Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .ai/skills/vrt-authoring/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ This skill is the quick reference. The authoritative guide is `CONTRIBUTOR-DOCS/
- Put VRT stories in `2nd-gen/packages/swc/components/<component>/test/vrt/*.vrt.ts` or `2nd-gen/packages/swc/patterns/<pattern>/test/vrt/*.vrt.ts`.
- Keep docs stories for examples; keep `.vrt.ts` stories for dense visual coverage.
- Aim for maximum meaningful coverage: include every size, variant, state, anatomy, theme, static-color, global-style, custom-property, and component-specific visual axis that can produce a useful visual difference. Cover CJK language rendering explicitly when text metrics can change, e.g. `lang="ja"` / `lang="ko"` / `lang="zh"` line-height, wrapping, or truncation. Skip only impossible, unsupported, or truly redundant combinations.
- Don't cover a visual axis your component only forwards to a slotted or composed child with no CSS of its own for it (e.g. a layout component passing `static-color` through to its children); that's already covered by the child's own VRT file. Only cover it here if this component's own CSS does something with that state.
- Use shared helpers from `.storybook/helpers`: `createPermutations`, `groupPermutationsBy`, `row`, `theme`, `staticColorBackground`, `forcePseudoStates` (and `forcePseudoState` for forcing state on individual slotted elements), `vrtParameters`, and `forcedColorsVrtParameters`.
- Keep unit files data-driven: local case lists and renderers only. Move reusable mechanics to `.storybook/helpers`.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
gap: var(--swc-action-button-gap, token("base-gap-medium"));
align-items: center;
justify-content: center;
inline-size: 100%;
min-block-size: var(--_swc-action-button-min-block-size);
padding-inline: calc(var(--swc-action-button-edge-to-text, token("base-padding-horizontal-medium")) - var(--_swc-action-button-border-width));
margin: 0;
Expand All @@ -60,6 +59,14 @@
transition-property: border-color, color, background-color, transform;
}

/* @global-exclude: fills a shadow-DOM host stretched by an ancestor flex layout (e.g. vertical swc-action-group); plain elements via global classes already stretch natively */
/* stylelint-disable-next-line no-duplicate-selectors -- re-opens .swc-ActionButton so the @global-exclude fence (see vite-global-elements-css) can strip just this declaration from the generated global stylesheet without excluding the rest of the class's rules */
.swc-ActionButton {
inline-size: 100%;
}

/* @global-exclude-end */

Comment on lines +62 to +69

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@5t3ph I started looking at Chromatic and realized that while <swc-action-button> isn't affected by applying inline-size: 100% (for vertical action group alignment), the global action button is. I'm excluding this style, and I committed the changes to the global stylesheet. I'm not 100% that's how this is supposed to be handled though so would appreciate some eyes on this piece.

/* ── States ───────────────────────────────────────── */

.swc-ActionButton:hover {
Expand Down

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Compact action groups need to be able to modify the action button corner radii, this adds VRT testing for those

Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,22 @@ type ModPropertyCase = CustomPropertyCase<`--swc-action-button-${string}`> & {
const MOD_PROPERTY_CASES: readonly ModPropertyCase[] = [
{ property: '--swc-action-button-min-block-size', value: '80px' },
{ property: '--swc-action-button-border-radius', value: '0px' },
{
property: '--swc-action-button-border-start-start-radius',
value: '20px',
},
{
property: '--swc-action-button-border-start-end-radius',
value: '20px',
},
{
property: '--swc-action-button-border-end-start-radius',
value: '20px',
},
{
property: '--swc-action-button-border-end-end-radius',
value: '20px',
},
{ property: '--swc-action-button-font-size', value: '24px' },
{ property: '--swc-action-button-gap', value: '40px', withIcon: true },
{ property: '--swc-action-button-edge-to-text', value: '40px' },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -372,4 +372,32 @@ export const Justified: Story = {
// ACCESSIBILITY STORIES
// ────────────────────────────────

// Outer `role="toolbar"` landmark wrapping two named `role="group"` clusters,
// per the APG toolbar example and the migration plan's accessibility
// section. `swc-action-group` never sets `role="toolbar"` itself; that role
// belongs on this wrapper only, since the host role is fixed to `"group"`
// and not author-overridable. Backs the `ToolbarComposition` ARIA-snapshot
// assertion in `action-group.a11y.spec.ts`.
export const ToolbarComposition: Story = {
render: () => html`
<div
role="toolbar"
aria-label="Document actions"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use of aria-orientation becomes important when role="toolbar" is applied. Maybe a note that when you do the a11y docs that you include a vertical example to show applying aria-orientation="vertical" since the default for toolbar is horizontal?

style="display: flex; gap: var(--swc-spacing-400);"
>
<swc-action-group accessible-label="Edit actions">
<swc-action-button>Cut</swc-action-button>
<swc-action-button>Copy</swc-action-button>
<swc-action-button>Paste</swc-action-button>
</swc-action-group>
<swc-action-group accessible-label="View actions">
<swc-action-button>Zoom in</swc-action-button>
<swc-action-button>Zoom out</swc-action-button>
</swc-action-group>
</div>
`,
tags: ['a11y'],
};
ToolbarComposition.storyName = 'Toolbar wrapper composition';

// TODO: will complete in separate documentation pass of phase 7
Loading
Loading