mirror of
https://github.com/podman-desktop/podman-desktop
synced 2026-04-21 09:37:22 +00:00
docs(storybook): update Spinner stories with a11y documentation (#16454)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
7b5195d651
commit
862cd8e788
1 changed files with 97 additions and 1 deletions
|
|
@ -5,7 +5,16 @@ import { defineMeta } from '@storybook/addon-svelte-csf';
|
|||
|
||||
/**
|
||||
* These are the stories for the `Spinner` component.
|
||||
* Displays indeterminate progress through a circle/spinner.
|
||||
* An SVG-based indeterminate loading spinner for ongoing processes with unknown duration.
|
||||
*
|
||||
* **Accessibility**: The wrapper element uses `role="status"` with `aria-live="polite"` so screen readers
|
||||
* announce loading state changes. The SVG graphic is marked `aria-hidden="true"`. The `label` prop sets
|
||||
* `aria-label` on the wrapper (default: `"Loading"`).
|
||||
*
|
||||
* **Color**: The spinner stroke uses `currentColor`, so it inherits the text color of its container.
|
||||
*
|
||||
* **Motion**: Support for `prefers-reduced-motion` is planned in
|
||||
* [#15806](https://github.com/podman-desktop/podman-desktop/issues/15806).
|
||||
*/
|
||||
const { Story } = defineMeta({
|
||||
component: Spinner,
|
||||
|
|
@ -13,6 +22,24 @@ const { Story } = defineMeta({
|
|||
title: 'Progress/Spinner',
|
||||
tags: ['autodocs'],
|
||||
argTypes: {
|
||||
size: {
|
||||
control: 'text',
|
||||
description: 'CSS size value for SVG width and height',
|
||||
defaultValue: '2em',
|
||||
},
|
||||
class: {
|
||||
control: 'text',
|
||||
description: 'Additional CSS classes on the wrapper element',
|
||||
},
|
||||
style: {
|
||||
control: 'text',
|
||||
description: 'Inline CSS styles on the wrapper element',
|
||||
},
|
||||
label: {
|
||||
control: 'text',
|
||||
description: 'Accessible label for screen readers via aria-label',
|
||||
defaultValue: 'Loading',
|
||||
},
|
||||
kind: {
|
||||
table: { disable: true },
|
||||
},
|
||||
|
|
@ -28,6 +55,46 @@ const sizeVariants: { label: string; size?: string }[] = [
|
|||
{ label: '12px', size: '12px' },
|
||||
{ label: '16px', size: '16px' },
|
||||
];
|
||||
|
||||
const accessibilityVariants: { heading: string; label?: string; containerClass?: string; aria: string }[] = [
|
||||
{
|
||||
heading: 'Default label',
|
||||
aria: 'role="status" aria-label="Loading" aria-live="polite"',
|
||||
},
|
||||
{
|
||||
heading: 'Custom label: Pulling image',
|
||||
label: 'Pulling image',
|
||||
aria: 'role="status" aria-label="Pulling image" aria-live="polite"',
|
||||
},
|
||||
{
|
||||
heading: 'Custom label: Checking prerequisites',
|
||||
label: 'Checking prerequisites',
|
||||
aria: 'role="status" aria-label="Checking prerequisites" aria-live="polite"',
|
||||
},
|
||||
{
|
||||
heading: 'Custom label: Building container',
|
||||
label: 'Building container',
|
||||
aria: 'role="status" aria-label="Building container" aria-live="polite"',
|
||||
},
|
||||
{
|
||||
heading: 'Color inheritance: Info',
|
||||
label: 'Loading info',
|
||||
containerClass: 'text-(--pd-state-info)',
|
||||
aria: 'Inherits currentColor from info context',
|
||||
},
|
||||
{
|
||||
heading: 'Color inheritance: Warning',
|
||||
label: 'Loading warning',
|
||||
containerClass: 'text-(--pd-state-warning)',
|
||||
aria: 'Inherits currentColor from warning context',
|
||||
},
|
||||
{
|
||||
heading: 'Color inheritance: Muted',
|
||||
label: 'Loading muted',
|
||||
containerClass: 'text-(--pd-content-invert-text)',
|
||||
aria: 'Inherits currentColor from muted context',
|
||||
},
|
||||
];
|
||||
</script>
|
||||
|
||||
{#snippet template({ _children, ...args })}
|
||||
|
|
@ -51,6 +118,30 @@ const sizeVariants: { label: string; size?: string }[] = [
|
|||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
{:else if args.kind === 'accessibility'}
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="text-sm text-(--pd-content-text)">
|
||||
Accessibility features: ARIA attributes and color inheritance via <code>currentColor</code>.
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-2 gap-4 sm:grid-cols-3">
|
||||
{#each accessibilityVariants as variant (variant.heading)}
|
||||
<div class="flex flex-col gap-2 rounded border border-(--pd-content-divider) p-3">
|
||||
<div class="text-xs font-semibold text-(--pd-content-header)">{variant.heading}</div>
|
||||
|
||||
<div class="flex items-center justify-center py-2 {variant.containerClass ?? ''}">
|
||||
{#if variant.label}
|
||||
<Spinner label={variant.label} />
|
||||
{:else}
|
||||
<Spinner />
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<code class="text-[10px] text-(--pd-content-text) break-all">{variant.aria}</code>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
{:else if args.kind === 'contexts'}
|
||||
<div class="flex flex-col gap-6 text-(--pd-content-text)">
|
||||
<div class="flex flex-col gap-2">
|
||||
|
|
@ -128,6 +219,11 @@ const sizeVariants: { label: string; size?: string }[] = [
|
|||
args={{
|
||||
kind: 'sizes',
|
||||
}} />
|
||||
<Story
|
||||
name="Accessibility"
|
||||
args={{
|
||||
kind: 'accessibility',
|
||||
}} />
|
||||
<Story
|
||||
name="Contexts"
|
||||
args={{
|
||||
|
|
|
|||
Loading…
Reference in a new issue