diff --git a/2nd-gen/packages/core/AGENTS.md b/2nd-gen/packages/core/AGENTS.md index ccfd73779a7..878050717cf 100644 --- a/2nd-gen/packages/core/AGENTS.md +++ b/2nd-gen/packages/core/AGENTS.md @@ -8,7 +8,7 @@ core/ ├── element/ # SpectrumElement base class, defineElement, version tracking ├── mixins/ # SizedMixin, ObserveSlotPresence, ObserveSlotText -├── controllers/ # LanguageResolutionController +├── controllers/ # LanguageResolutionController, PendingController, … ├── utils/ # capitalize, getLabelFromSlot └── components/ # One folder per component └── badge/ diff --git a/2nd-gen/packages/core/components/button/Button.base.ts b/2nd-gen/packages/core/components/button/Button.base.ts index 783f7939c99..6495bc9aac1 100644 --- a/2nd-gen/packages/core/components/button/Button.base.ts +++ b/2nd-gen/packages/core/components/button/Button.base.ts @@ -11,7 +11,7 @@ */ import { PropertyValues } from 'lit'; -import { property, state } from 'lit/decorators.js'; +import { property } from 'lit/decorators.js'; import { SpectrumElement } from '@spectrum-web-components/core/element/index.js'; import { @@ -23,11 +23,10 @@ import { import { BUTTON_VALID_SIZES } from './Button.types.js'; /** - * Abstract base class for all button-like components. Owns shared semantic - * concerns: interaction state, sizing, slot-derived icon/label state, - * accessible-name resolution, and host-to-internal-button attribute forwarding. + * Abstract base for button-like components that share sizing, slots, disabled + * state, and accessible-name resolution. * - * Visual API specific to `sp-button` (`variant`, `fill-style`, `static-color`) + * Visual API specific to `swc-button` (`variant`, `fill-style`, `static-color`) * is intentionally absent so that ActionButton, ClearButton, CloseButton, * PickerButton, and InfieldButton can extend this base without inheriting * the `swc-button` visual surface. @@ -36,9 +35,6 @@ import { BUTTON_VALID_SIZES } from './Button.types.js'; * @slot icon - Optional leading icon. * * @attribute {ElementSize} size - The size of the button. - * - * @todo We currently have 3 levels of mixins on this class, but the mixin - * composition guide recommends a maximum of 2. Explore reducing after milestone 2. */ export abstract class ButtonBase extends SizedMixin( ObserveSlotText(ObserveSlotPresence(SpectrumElement, '[slot="icon"]'), ''), @@ -60,13 +56,6 @@ export abstract class ButtonBase extends SizedMixin( @property({ type: Boolean, reflect: true }) public disabled: boolean = false; - /** - * Whether the button is in a pending (busy) state. The button remains - * focusable but activation is suppressed. - */ - @property({ type: Boolean, reflect: true }) - public pending: boolean = false; - /** * Accessible label forwarded to the internal ` + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + 'demo-pending-host': DemoPendingHost; + } +} + +export default { + title: 'Pending controller/Tests', + parameters: { + docs: { disable: true, page: null }, + }, + tags: ['!autodocs', 'dev'], +} as Meta; + +export const SuppressesClickWhilePending: Story = { + render: () => html` + Save + `, + play: async ({ canvasElement, step }) => { + const host = canvasElement.querySelector('demo-pending-host'); + if (!(host instanceof DemoPendingHost)) { + throw new Error('demo-pending-host not found'); + } + await host.updateComplete; + + await step('suppresses click events while pending is true', async () => { + let clickCount = 0; + host.addEventListener('click', () => { + clickCount += 1; + }); + + host.shadowRoot?.querySelector('button')?.click(); + expect(clickCount, 'click is suppressed while pending').toBe(0); + }); + + await step('allows click events after pending is cleared', async () => { + let clickCount = 0; + host.addEventListener('click', () => { + clickCount += 1; + }); + + host.pending = false; + await host.updateComplete; + host.shadowRoot?.querySelector('button')?.click(); + expect(clickCount, 'click fires normally after pending is cleared').toBe( + 1 + ); + }); + }, +}; + +export const DerivesPendingAccessibleName: Story = { + render: () => html` + Save + `, + play: async ({ canvasElement, step }) => { + const host = canvasElement.querySelector('demo-pending-host'); + if (!(host instanceof DemoPendingHost)) { + throw new Error('demo-pending-host not found'); + } + await host.updateComplete; + + await step('derives busy suffix from visible label', async () => { + expect( + host.pendingController.getPendingAccessibleName(), + 'pending name includes busy suffix' + ).toBe('Save, busy'); + }); + }, +}; + +export const UsesExplicitPendingLabel: Story = { + render: () => html` + + Save + + `, + play: async ({ canvasElement, step }) => { + const host = canvasElement.querySelector('demo-pending-host'); + if (!(host instanceof DemoPendingHost)) { + throw new Error('demo-pending-host not found'); + } + await host.updateComplete; + + await step('prefers explicit pending-label', async () => { + expect( + host.pendingController.getPendingAccessibleName(), + 'explicit pendingLabel overrides derived busy name' + ).toBe('Processing your request'); + }); + }, +}; diff --git a/2nd-gen/packages/core/package.json b/2nd-gen/packages/core/package.json index f5ce52ab92c..cededcdc960 100644 --- a/2nd-gen/packages/core/package.json +++ b/2nd-gen/packages/core/package.json @@ -43,6 +43,10 @@ "types": "./dist/components/button/index.d.ts", "import": "./dist/components/button/index.js" }, + "./components/close-button": { + "types": "./dist/components/close-button/index.d.ts", + "import": "./dist/components/close-button/index.js" + }, "./components/divider": { "types": "./dist/components/divider/index.d.ts", "import": "./dist/components/divider/index.js" @@ -198,6 +202,9 @@ "components/button": [ "dist/components/button/index.d.ts" ], + "components/close-button": [ + "dist/components/close-button/index.d.ts" + ], "components/divider": [ "dist/components/divider/index.d.ts" ], diff --git a/2nd-gen/packages/swc/components/button/Button.ts b/2nd-gen/packages/swc/components/button/Button.ts index 01b5bcb1fcb..1ea17844b3a 100644 --- a/2nd-gen/packages/swc/components/button/Button.ts +++ b/2nd-gen/packages/swc/components/button/Button.ts @@ -29,6 +29,7 @@ import { type ButtonStaticColor, type ButtonVariant, } from '@spectrum-web-components/core/components/button'; +import { PendingController } from '@spectrum-web-components/core/controllers/pending-controller/index.js'; import styles from './button.css'; import baseStyles from './button-base.css'; @@ -42,6 +43,9 @@ import baseStyles from './button-base.css'; * @slot - Visible button label. * @slot icon - Leading icon displayed before the label. * + * @attribute {boolean} pending - Whether the button is in a pending state. + * @attribute {string} pending-label - Custom accessible label during pending. + * * @cssprop --swc-button-min-block-size - Minimum block size of the button. * @cssprop --swc-button-border-radius - Corner radius. Defaults to half the height (pill shape). * @cssprop --swc-button-padding-vertical - Block padding (adjusted for border width). @@ -77,10 +81,27 @@ import baseStyles from './button-base.css'; * Cancel */ export class Button extends ButtonBase { + private readonly pendingController = new PendingController(this); + // ─────────────────── // API ADDITIONS // ─────────────────── + /** + * Whether the button is in a pending state. The button remains + * focusable but activation is suppressed. + */ + @property({ type: Boolean, reflect: true }) + public pending: boolean = false; + + /** + * Custom accessible label used during the pending state. When omitted, + * the pending label is derived from the resolved non-busy accessible name + * plus a busy suffix (e.g. "Save, busy"). + */ + @property({ type: String, attribute: 'pending-label' }) + public pendingLabel?: string; + /** * The visual variant of the button. * @@ -127,6 +148,25 @@ export class Button extends ButtonBase { return [baseStyles, styles]; } + protected get pendingActive(): boolean { + return this.pendingController.pendingActive; + } + + protected override handleActivationClick(event: Event): void { + if (this.disabled || this.pending) { + event.preventDefault(); + event.stopImmediatePropagation(); + } + } + + protected readonly handleClick = (event: Event): void => { + this.handleActivationClick(event); + }; + + protected getPendingAccessibleName(): string { + return this.pendingController.getPendingAccessibleName(); + } + // @todo SWC-2034: handle form-associated types reset / submit protected override render(): TemplateResult { return html` @@ -185,6 +225,7 @@ export class Button extends ButtonBase { } protected override update(changedProperties: PropertyValues): void { + this.pendingController.handleHostUpdate(changedProperties); super.update(changedProperties); if (window.__swc?.DEBUG) { if (!BUTTON_VARIANTS.includes(this.variant)) { diff --git a/2nd-gen/packages/swc/components/button/button.css b/2nd-gen/packages/swc/components/button/button.css index f8f16553657..737b62dfbbe 100644 --- a/2nd-gen/packages/swc/components/button/button.css +++ b/2nd-gen/packages/swc/components/button/button.css @@ -337,7 +337,7 @@ slot[name="icon"]::slotted(*) { /* ── Pending ──────────────────────────────────────── */ -/* @global-exclude: pending state requires JS runtime (ButtonBase.pendingActive) */ +/* @global-exclude: pending state requires JS runtime (PendingController.pendingActive) */ /* Cursor changes immediately on [pending]. Disabled colors, label/icon fade, and spinner appearance are deferred to .swc-Button--pendingActive, which is @@ -462,7 +462,7 @@ slot[name="icon"]::slotted(*) { /* @global-exclude-end */ } -/* @global-exclude: pending state requires JS runtime (ButtonBase.pendingActive) */ +/* @global-exclude: pending state requires JS runtime (PendingController.pendingActive) */ @media (forced-colors: active) { /* Pending-active button maps all interactive color states to system disabled colors so it visually matches native disabled controls in high-contrast diff --git a/2nd-gen/packages/swc/components/button/test/button.test.ts b/2nd-gen/packages/swc/components/button/test/button.test.ts index 00a8ada1f5c..268583e94d7 100644 --- a/2nd-gen/packages/swc/components/button/test/button.test.ts +++ b/2nd-gen/packages/swc/components/button/test/button.test.ts @@ -20,6 +20,7 @@ import { BUTTON_STATIC_COLORS, BUTTON_VALID_SIZES, BUTTON_VARIANTS, + ButtonBase, } from '@spectrum-web-components/core/components/button'; import '@adobe/spectrum-wc/components/button/swc-button.js'; @@ -684,6 +685,22 @@ export const AccessibilityTest: Story = { }, }; +export const ButtonBaseInstanceofTest: Story = { + render: () => html` + Save + `, + play: async ({ canvasElement, step }) => { + const button = await getComponent + `; + } +} diff --git a/2nd-gen/packages/swc/components/close-button/close-button.css b/2nd-gen/packages/swc/components/close-button/close-button.css new file mode 100644 index 00000000000..cd2d72c1f5f --- /dev/null +++ b/2nd-gen/packages/swc/components/close-button/close-button.css @@ -0,0 +1,79 @@ +/** + * Copyright 2026 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +:host { + display: inline-flex; +} + +.swc-CloseButton { + --_swc-close-button-block-size: token("component-height-100"); + --_swc-close-button-icon-size: token("cross-icon-size-300"); + + display: inline-flex; + align-items: center; + justify-content: center; + inline-size: var(--_swc-close-button-block-size); + block-size: var(--_swc-close-button-block-size); + padding: 0; + color: token("neutral-content-color-default"); + background: transparent; + border: none; + cursor: pointer; +} + +.swc-CloseButton:disabled { + cursor: default; +} + +:host([size="s"]) .swc-CloseButton { + --_swc-close-button-block-size: token("component-height-75"); + --_swc-close-button-icon-size: token("cross-icon-size-200"); +} + +:host([size="l"]) .swc-CloseButton { + --_swc-close-button-block-size: token("component-height-200"); + --_swc-close-button-icon-size: token("cross-icon-size-400"); +} + +:host([size="xl"]) .swc-CloseButton { + --_swc-close-button-block-size: token("component-height-300"); + --_swc-close-button-icon-size: token("cross-icon-size-500"); +} + +.swc-CloseButton-icon { + display: block; + flex-shrink: 0; + inline-size: var(--_swc-close-button-icon-size); + block-size: var(--_swc-close-button-icon-size); +} + +.swc-CloseButton-icon svg { + display: block; + inline-size: 100%; + block-size: 100%; +} + +.swc-CloseButton-icon svg path { + fill: currentcolor; +} + +.swc-CloseButton-label { + position: absolute; + inline-size: 1px; + block-size: 1px; + padding: 0; + margin: -1px; + white-space: nowrap; + border: 0; + overflow: hidden; + clip-path: inset(50%); +} diff --git a/2nd-gen/packages/swc/components/close-button/close-button.mdx b/2nd-gen/packages/swc/components/close-button/close-button.mdx new file mode 100644 index 00000000000..bb118076e55 --- /dev/null +++ b/2nd-gen/packages/swc/components/close-button/close-button.mdx @@ -0,0 +1,10 @@ +import { Meta } from '@storybook/addon-docs/blocks'; +import { DocsFooter, DocsHeader } from '../../.storybook/blocks'; + +import * as CloseButtonStories from './stories/close-button.stories'; + + + + + + diff --git a/2nd-gen/packages/swc/components/close-button/index.ts b/2nd-gen/packages/swc/components/close-button/index.ts new file mode 100644 index 00000000000..fc250839695 --- /dev/null +++ b/2nd-gen/packages/swc/components/close-button/index.ts @@ -0,0 +1,12 @@ +/** + * Copyright 2026 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +export * from './CloseButton.js'; diff --git a/2nd-gen/packages/swc/components/close-button/stories/close-button.stories.ts b/2nd-gen/packages/swc/components/close-button/stories/close-button.stories.ts new file mode 100644 index 00000000000..94b084b4279 --- /dev/null +++ b/2nd-gen/packages/swc/components/close-button/stories/close-button.stories.ts @@ -0,0 +1,88 @@ +/** + * Copyright 2026 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import type { Meta, StoryObj as Story } from '@storybook/web-components'; +import { getStorybookHelpers } from '@wc-toolkit/storybook-helpers'; + +import { + CLOSE_BUTTON_STATIC_COLORS, + CLOSE_BUTTON_VALID_SIZES, +} from '@spectrum-web-components/core/components/close-button'; + +import '@adobe/spectrum-wc/components/close-button/swc-close-button.js'; + +// ──────────────── +// METADATA +// ──────────────── + +const { args, argTypes, template } = getStorybookHelpers('swc-close-button'); + +argTypes.size = { + ...argTypes.size, + control: { type: 'select' }, + options: CLOSE_BUTTON_VALID_SIZES, +}; + +argTypes['static-color'] = { + ...argTypes['static-color'], + control: 'select', + options: ['', ...CLOSE_BUTTON_STATIC_COLORS], + table: { + ...argTypes['static-color']?.table, + category: 'attributes', + }, +}; + +args['accessible-label'] = 'Close'; + +/** + * Close buttons dismiss dialogs, banners, toasts, and similar surfaces. They + * are compact, icon-forward controls that require an accessible name describing + * the dismiss action. + */ +const meta: Meta = { + title: 'Close Button', + component: 'swc-close-button', + args, + argTypes, + render: (args) => template(args), + parameters: { + docs: { + subtitle: 'Compact dismiss control for overlays and chrome regions', + }, + }, + tags: ['migrated'], +}; + +export default meta; + +// ──────────────────── +// PLAYGROUND STORY +// ──────────────────── + +export const Playground: Story = { + args: { + 'accessible-label': 'Close', + }, + tags: ['dev'], +}; + +// ────────────────────────── +// OVERVIEW STORY +// ────────────────────────── + +export const Overview: Story = { + args: { + 'accessible-label': 'Close', + }, + tags: ['overview'], +}; diff --git a/2nd-gen/packages/swc/components/close-button/swc-close-button.ts b/2nd-gen/packages/swc/components/close-button/swc-close-button.ts new file mode 100644 index 00000000000..43239f19769 --- /dev/null +++ b/2nd-gen/packages/swc/components/close-button/swc-close-button.ts @@ -0,0 +1,22 @@ +/** + * Copyright 2026 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { defineElement } from '@spectrum-web-components/core/element/index.js'; + +import { CloseButton } from './CloseButton.js'; + +declare global { + interface HTMLElementTagNameMap { + 'swc-close-button': CloseButton; + } +} + +defineElement('swc-close-button', CloseButton); diff --git a/2nd-gen/packages/swc/components/close-button/test/close-button.a11y.spec.ts b/2nd-gen/packages/swc/components/close-button/test/close-button.a11y.spec.ts new file mode 100644 index 00000000000..ce808728ff0 --- /dev/null +++ b/2nd-gen/packages/swc/components/close-button/test/close-button.a11y.spec.ts @@ -0,0 +1,36 @@ +/** + * Copyright 2026 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { expect, test } from '@playwright/test'; + +import { gotoStory } from '../../../utils/a11y-helpers.js'; + +/** + * Accessibility tests for Close Button component (2nd Generation). + * + * Placeholder: ARIA snapshot coverage is added in Phase 6. + */ + +test.describe('Close Button - ARIA Snapshots', () => { + test('should expose a named dismiss button in the overview story', async ({ + page, + }) => { + const root = await gotoStory( + page, + 'components-close-button--overview', + 'swc-close-button' + ); + await expect(root).toMatchAriaSnapshot(` + - button "Close" + `); + }); +}); diff --git a/2nd-gen/packages/swc/components/close-button/test/close-button.test.ts b/2nd-gen/packages/swc/components/close-button/test/close-button.test.ts new file mode 100644 index 00000000000..1bfae4a4d1a --- /dev/null +++ b/2nd-gen/packages/swc/components/close-button/test/close-button.test.ts @@ -0,0 +1,57 @@ +/** + * Copyright 2026 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +import { expect } from '@storybook/test'; +import type { Meta, StoryObj as Story } from '@storybook/web-components'; + +import { CloseButton } from '@adobe/spectrum-wc/components/close-button'; +import { ButtonBase } from '@spectrum-web-components/core/components/button'; + +import '@adobe/spectrum-wc/components/close-button/swc-close-button.js'; + +import { getComponent } from '../../../utils/test-utils.js'; +import meta, { Overview } from '../stories/close-button.stories.js'; + +export default { + ...meta, + title: 'Close Button/Tests', + parameters: { + ...meta.parameters, + docs: { disable: true, page: null }, + }, + tags: ['!autodocs', 'dev'], +} as Meta; + +export const OverviewTest: Story = { + ...Overview, +}; + +export const ButtonBaseInstanceofTest: Story = { + ...Overview, + play: async ({ canvasElement, step }) => { + const closeButton = await getComponent( + canvasElement, + 'swc-close-button' + ); + + await step('is a ButtonBase without pending API', async () => { + expect( + closeButton instanceof ButtonBase, + 'swc-close-button instanceof ButtonBase' + ).toBe(true); + expect( + 'pending' in closeButton, + 'swc-close-button does not expose pending' + ).toBe(false); + }); + }, +}; diff --git a/2nd-gen/packages/swc/components/icon/elements/Cross400Icon.ts b/2nd-gen/packages/swc/components/icon/elements/Cross400Icon.ts new file mode 100644 index 00000000000..16416d159a3 --- /dev/null +++ b/2nd-gen/packages/swc/components/icon/elements/Cross400Icon.ts @@ -0,0 +1,22 @@ +/** + * Copyright 2026 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { html, TemplateResult } from 'lit'; + +export const Cross400Icon = (): TemplateResult => { + return html` + + + + `; +}; diff --git a/2nd-gen/packages/swc/components/icon/elements/Cross500Icon.ts b/2nd-gen/packages/swc/components/icon/elements/Cross500Icon.ts new file mode 100644 index 00000000000..a033816c826 --- /dev/null +++ b/2nd-gen/packages/swc/components/icon/elements/Cross500Icon.ts @@ -0,0 +1,22 @@ +/** + * Copyright 2026 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { html, TemplateResult } from 'lit'; + +export const Cross500Icon = (): TemplateResult => { + return html` + + + + `; +}; diff --git a/2nd-gen/packages/swc/components/icon/elements/index.ts b/2nd-gen/packages/swc/components/icon/elements/index.ts index b30f66ddd2c..b681852df39 100644 --- a/2nd-gen/packages/swc/components/icon/elements/index.ts +++ b/2nd-gen/packages/swc/components/icon/elements/index.ts @@ -25,6 +25,8 @@ export * from './Cross75Icon.js'; export * from './Cross100Icon.js'; export * from './Cross200Icon.js'; export * from './Cross300Icon.js'; +export * from './Cross400Icon.js'; +export * from './Cross500Icon.js'; export * from './Dash75Icon.js'; export * from './Dash100Icon.js'; export * from './Dash200Icon.js'; diff --git a/CONTRIBUTOR-DOCS/03_project-planning/02_workstreams/02_2nd-gen-component-migration/01_status.md b/CONTRIBUTOR-DOCS/03_project-planning/02_workstreams/02_2nd-gen-component-migration/01_status.md index 3303eb4a3a1..05856bbb9f6 100644 --- a/CONTRIBUTOR-DOCS/03_project-planning/02_workstreams/02_2nd-gen-component-migration/01_status.md +++ b/CONTRIBUTOR-DOCS/03_project-planning/02_workstreams/02_2nd-gen-component-migration/01_status.md @@ -36,7 +36,7 @@ | Card | | | | | | | | | Checkbox | ✓ | | | | | | | | Clear Button | | | | | | | | -| Close Button | | | | | | | | +| Close Button | ✓ | ✓ | ✓ | | ✓ | | | | Coachmark | | | | | | | | | Color Area | | | | | | | | | Color Field | ✓ | | | | | | | diff --git a/CONTRIBUTOR-DOCS/03_project-planning/03_components/close-button/migration-plan.md b/CONTRIBUTOR-DOCS/03_project-planning/03_components/close-button/migration-plan.md index edae099060f..cd55af17998 100644 --- a/CONTRIBUTOR-DOCS/03_project-planning/03_components/close-button/migration-plan.md +++ b/CONTRIBUTOR-DOCS/03_project-planning/03_components/close-button/migration-plan.md @@ -57,7 +57,7 @@ - `swc-close-button` should ship as a dedicated 2nd-gen component in both `core` and `swc` layers, not as an extension point buried inside `swc-button`. - API should align with modern button conventions: `accessible-label` (consumer-facing), `static-color`, and `size` (`s|m|l|xl`). -- Variant aliases from 1st-gen (`variant="white|black"`) should be deprecated in favor of `static-color`. +- 2nd-gen does not ship the 1st-gen `variant="white|black"` alias; use `static-color` only. Deprecation of `variant` is a 1st-gen (`sp-close-button`) concern. - Styling source of truth is Spectrum CSS `spectrum-two` `components/closebutton`; 2nd-gen should not re-expose the 1st-gen `--mod-closebutton-*` surface. - Accessibility is must-ship: real inner `