Skip to content

Commit 4639901

Browse files
authored
Merge branch 'main' into user-items
2 parents 489b01b + 4f930a0 commit 4639901

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+855
-22
lines changed

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,6 @@ To ensure your website gets the greatest exposure, add it both to [Awesome Volto
149149
- [Industrial Emissions portal for Europe](https://industry.eea.europa.eu) (Thematic website focusing on European industrial emissions, developed by [Eau de Web](https://eaudeweb.ro/), 2020)
150150
- [Interpretare.ro](https://www.interpretare.ro) (Romanian medical imaging interpretation service allowing patients to submit MRI, CT, and other diagnostic imaging for professional evaluation by medical specialists, 2022)
151151
- [iTlent - Basque Institute of Talent in VET](https://www.itlent.eus/en) (developed by [CodeSyntax](https://www.codesyntax.com/en), 2024)
152-
- [Jobfamilie MEDICE](https://jobfamilie.medice.de/de) (Career website for MEDICE Arzneimittel Pütter GmbH & Co. KG, developed by [Werkbank GmbH](https://werkbank.de/), 2020)
153152
- [Lanku](https://www.lanku.eus) (Website for Lanku Kultur Zerbitzuak, a company offering cultural services and improvised Basque verse singing sessions across the Basque Country, developed by [CodeSyntax](https://www.codesyntax.com/en), 2023)
154153
- [Leibniz Institute for Science and Mathematics Education (IPN)](https://www.leibniz-ipn.de/de) (Website of the IPN, a research institute dedicated to issues related to learning and teaching of science, mathematics and computer science in and outside of schools, developed by [Starzel](https://www.starzel.de), 2023)
155154
- [Nuova Voce Ecologista](https://nuovavoceecologista.it) (Website of Nuova Voce Ecologista, an Italian green Party, 2020)

docs/source/release-notes/index.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,28 @@ myst:
1717

1818
<!-- towncrier release notes start -->
1919

20+
## 19.0.0-alpha.26 (2026-02-20)
21+
22+
### Breaking
23+
24+
- Created a new `VideoEmbed` component for usage in a video block, helping to fix accessibility issues with the Semantic UI one. @jackahl @iRohitSingh [#6359](https://github.com/plone/volto/issues/6359)
25+
- Table block is now responsive and can scroll horizontally for non-fixed tables. @sneridagh [#7916](https://github.com/plone/volto/issues/7916)
26+
27+
### Feature
28+
29+
- Allow other sources, including Peertube instances, in the Video block via blocks configuration. @ionlizarazu [#6870](https://github.com/plone/volto/issues/6870)
30+
31+
### Bugfix
32+
33+
- Fix ContentTypeSchema error toast to display only error message instead of stringified JSON object. @Shyam-Raghuwanshi [#7692](https://github.com/plone/volto/issues/7692)
34+
- Fix missing i18n and a11y id for facet widget of Search block. @IFlameing
35+
36+
### Internal
37+
38+
- Added Vitest coverage for `.well-known` public asset handling and corrected a test import path in volto-razzle. @Kathrina-dev [#7868](https://github.com/plone/volto/issues/7868)
39+
- Use `getSlateEditorAndType` in `03-block-slate.js` to make the test more robust. @wesleybl [#7924](https://github.com/plone/volto/issues/7924)
40+
- Add CI check for volto-razzle changelog. @davisagli
41+
2042
## 19.0.0-alpha.25 (2026-02-13)
2143

2244
### Feature

packages/components/CHANGELOG.md

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,25 @@
88

99
<!-- towncrier release notes start -->
1010

11+
## 4.0.0-alpha.6 (2026-02-20)
12+
13+
### Feature
14+
15+
- Added Spinner component. @sneridagh [#7918](https://github.com/plone/volto/issues/7918)
16+
- Added width (layout) icon components (and related SVGs). @sneridagh
17+
18+
## 4.0.0-alpha.5 (2025-12-23)
19+
20+
### Feature
21+
22+
- Quanta, Tailwind styled `Toolbar` component. @sneridagh [#7549](https://github.com/plone/volto/issues/7549)
23+
24+
### Internal
25+
26+
- Include other *.md files in the repo root for link checking, fix redirecting links, and remove non-responsive server. @stevepiercy [#7712](https://github.com/plone/volto/issues/7712)
27+
- Add storybook for lots of items with custom separator. @iFlameing
28+
- Fixed update to RAC 1.14.0 DTS problems. @sneridagh
29+
1130
## 4.0.0-alpha.4 (2025-11-19)
1231

1332
### Bugfix
@@ -18,7 +37,7 @@
1837

1938
### Bugfix
2039

21-
- Fixed `Icon` component return type since it was breaking in some builds. @sneridagh
40+
- Fixed `Icon` component return type since it was breaking in some builds. @sneridagh
2241

2342
## 4.0.0-alpha.2 (2025-11-12)
2443

@@ -27,7 +46,7 @@
2746
- Added ESlint Tailwind plugin for prettifying and wrapping up the classNames in components.
2847
Amended components classNames by applying the plugin. @sneridagh [#7434](https://github.com/plone/volto/issues/7434)
2948
- Added `Radio` component to basic set of components, proxied from RAC. @sneridagh [#7555](https://github.com/plone/volto/issues/7555)
30-
- Added RSC compatibility. @pnicolli
49+
- Added RSC compatibility. @pnicolli
3150

3251
### Bugfix
3352

@@ -162,7 +181,7 @@
162181

163182
### Internal
164183

165-
- Improve packaging and bring back the export for `src` folder. @sneridagh
184+
- Improve packaging and bring back the export for `src` folder. @sneridagh
166185

167186
## 2.1.0 (2024-11-05)
168187

@@ -174,7 +193,7 @@
174193

175194
### Internal
176195

177-
- Release 2.0.0 @sneridagh
196+
- Release 2.0.0 @sneridagh
178197

179198
## 2.0.0-alpha.16 (2024-10-18)
180199

packages/components/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
[![Build Status](https://github.com/plone/components/actions/workflows/unit.yml/badge.svg)](https://github.com/plone/components/actions)
66
[![Build Status](https://app.readthedocs.org/projects/plone-components/badge/?version=latest)](https://plone-components.readthedocs.io/latest/)
77

8-
This package contains React components for using Plone as a headless CMS.
8+
This package contains ReactJS components for using Plone as a headless CMS.
99

1010
The purpose of this package is to provide an agnostic set of baseline components to build sites upon.
1111

packages/components/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
}
99
],
1010
"license": "MIT",
11-
"version": "4.0.0-alpha.4",
11+
"version": "4.0.0-alpha.6",
1212
"repository": {
1313
"type": "git",
1414
"url": "http://github.com/plone/volto.git",
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import React from 'react';
2+
import { Spinner } from './Spinner.quanta';
3+
import type { Meta, StoryObj } from '@storybook/react-vite';
4+
5+
const meta = {
6+
title: 'Quanta/Spinner',
7+
component: Spinner,
8+
parameters: {
9+
layout: 'centered',
10+
backgrounds: { disable: true },
11+
},
12+
tags: ['autodocs'],
13+
} satisfies Meta<typeof Spinner>;
14+
15+
export default meta;
16+
type Story = StoryObj<typeof meta>;
17+
18+
export const Default: Story = {
19+
args: {},
20+
};
21+
22+
export const WithLabel: Story = {
23+
args: {
24+
label: 'Loading content',
25+
},
26+
};
27+
28+
export const Sizes: Story = {
29+
render: () => (
30+
<div className="flex items-center gap-4" aria-label="Spinner sizes">
31+
<Spinner size="xs" />
32+
<Spinner size="sm" />
33+
<Spinner size="lg" />
34+
<Spinner size={40} />
35+
</div>
36+
),
37+
};
38+
39+
export const Decorative: Story = {
40+
args: {
41+
isDecorative: true,
42+
},
43+
};
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
import React from 'react';
2+
import clsx from 'clsx';
3+
import { tv } from 'tailwind-variants';
4+
5+
type SpinnerSize = 'xs' | 'sm' | 'lg';
6+
7+
export interface SpinnerProps extends React.HTMLAttributes<HTMLDivElement> {
8+
size?: SpinnerSize | number | string;
9+
label?: string | null;
10+
isDecorative?: boolean;
11+
}
12+
13+
const wrapperStyles = tv({
14+
base: 'inline-flex items-center gap-2 text-quanta-iron',
15+
});
16+
17+
const spinnerStyles = tv({
18+
base: `
19+
animate-spin
20+
motion-reduce:animate-none
21+
`,
22+
variants: {
23+
size: {
24+
xs: 'size-4',
25+
sm: 'size-6',
26+
lg: 'size-8',
27+
},
28+
},
29+
defaultVariants: {
30+
size: 'sm',
31+
},
32+
});
33+
34+
function isPresetSize(size: SpinnerProps['size']): size is SpinnerSize {
35+
return size === 'xs' || size === 'sm' || size === 'lg';
36+
}
37+
38+
function resolveCustomSize(size: SpinnerProps['size']) {
39+
if (typeof size === 'number') return `${size}px`;
40+
if (typeof size === 'string' && !isPresetSize(size)) {
41+
return size;
42+
}
43+
return undefined;
44+
}
45+
46+
export function Spinner({
47+
size = 'sm',
48+
label = null,
49+
isDecorative = false,
50+
className,
51+
style,
52+
'aria-label': ariaLabelProp,
53+
...props
54+
}: SpinnerProps) {
55+
const hasLabel =
56+
!isDecorative && typeof label === 'string' && label.length > 0;
57+
const ariaLabel = isDecorative
58+
? undefined
59+
: ariaLabelProp ??
60+
(typeof label === 'string' && label.length > 0 ? label : 'Loading');
61+
const customSize = resolveCustomSize(size);
62+
const presetSize = isPresetSize(size) ? size : 'sm';
63+
64+
return (
65+
<div
66+
{...props}
67+
className={wrapperStyles({ className: clsx(className) })}
68+
style={style}
69+
aria-label={ariaLabel}
70+
{...(isDecorative
71+
? { 'aria-hidden': true }
72+
: { role: 'status', 'aria-live': 'polite' })}
73+
>
74+
<svg
75+
className={spinnerStyles({ size: presetSize })}
76+
style={
77+
customSize
78+
? ({ width: customSize, height: customSize } as React.CSSProperties)
79+
: undefined
80+
}
81+
viewBox="0 0 24 24"
82+
fill="none"
83+
xmlns="http://www.w3.org/2000/svg"
84+
aria-hidden="true"
85+
>
86+
<circle
87+
cx="12"
88+
cy="12"
89+
r="9"
90+
stroke="currentColor"
91+
strokeWidth="3"
92+
opacity="0.2"
93+
/>
94+
<circle
95+
cx="12"
96+
cy="12"
97+
r="9"
98+
stroke="currentColor"
99+
strokeWidth="3"
100+
strokeLinecap="round"
101+
strokeDasharray="42 57"
102+
/>
103+
</svg>
104+
{hasLabel && <span className="text-sm">{label}</span>}
105+
</div>
106+
);
107+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import React from 'react';
2+
import { Spinner } from './Spinner';
3+
4+
import type { Meta, StoryObj } from '@storybook/react-vite';
5+
6+
const meta: Meta<typeof Spinner> = {
7+
title: 'Basic/Spinner',
8+
component: Spinner,
9+
parameters: {
10+
layout: 'centered',
11+
},
12+
tags: ['autodocs'],
13+
} satisfies Meta<typeof Spinner>;
14+
15+
export default meta;
16+
type Story = StoryObj<typeof meta>;
17+
18+
export const Default: Story = {
19+
args: {},
20+
};
21+
22+
export const WithLabel: Story = {
23+
args: {
24+
label: 'Loading content',
25+
},
26+
};
27+
28+
export const Sizes: Story = {
29+
render: () => (
30+
<div
31+
style={{ display: 'flex', alignItems: 'center', gap: '1rem' }}
32+
aria-label="Spinner sizes"
33+
>
34+
<Spinner size="xs" />
35+
<Spinner size="sm" />
36+
<Spinner size="lg" />
37+
<Spinner size={40} />
38+
</div>
39+
),
40+
};
41+
42+
export const Decorative: Story = {
43+
args: {
44+
isDecorative: true,
45+
},
46+
};
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import React from 'react';
2+
import { render, screen } from '@testing-library/react';
3+
import { axe, toHaveNoViolations } from 'jest-axe';
4+
import { Spinner } from './Spinner';
5+
6+
expect.extend(toHaveNoViolations);
7+
8+
it('Spinner basic a11y test', async () => {
9+
const { container } = render(<Spinner />);
10+
const results = await axe(container);
11+
expect(results).toHaveNoViolations();
12+
expect(screen.getByRole('status')).toBeInTheDocument();
13+
});
14+
15+
it('Spinner decorative mode is hidden from assistive tech', () => {
16+
render(<Spinner isDecorative data-testid="spinner" />);
17+
expect(screen.getByTestId('spinner')).toHaveAttribute('aria-hidden', 'true');
18+
});

0 commit comments

Comments
 (0)