Skip to content

Commit 578f5dd

Browse files
committed
chore(action-button): adds structure for s2 migration (#6339)
* chore(action-button): adds structure for s2 migration * chore: clean up base class and export types * chore(action-button): update migration plan * chore(action-button): address feedback
1 parent e082b3a commit 578f5dd

12 files changed

Lines changed: 388 additions & 29 deletions

File tree

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/**
2+
* Copyright 2026 Adobe. All rights reserved.
3+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License. You may obtain a copy
5+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software distributed under
8+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9+
* OF ANY KIND, either express or implied. See the License for the specific language
10+
* governing permissions and limitations under the License.
11+
*/
12+
13+
import type { ElementSize } from '@spectrum-web-components/core/mixins/index.js';
14+
15+
// ──────────────────
16+
// SHARED
17+
// ──────────────────
18+
19+
export const ACTION_BUTTON_VALID_SIZES = [
20+
'xs',
21+
's',
22+
'm',
23+
'l',
24+
'xl',
25+
] as const satisfies readonly ElementSize[];
26+
27+
export const ACTION_BUTTON_STATIC_COLORS = ['white', 'black'] as const;
28+
29+
// ──────────────────
30+
// TYPES
31+
// ──────────────────
32+
33+
export type ActionButtonSize = (typeof ACTION_BUTTON_VALID_SIZES)[number];
34+
export type ActionButtonStaticColor =
35+
(typeof ACTION_BUTTON_STATIC_COLORS)[number];
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/**
2+
* Copyright 2026 Adobe. All rights reserved.
3+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License. You may obtain a copy
5+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software distributed under
8+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9+
* OF ANY KIND, either express or implied. See the License for the specific language
10+
* governing permissions and limitations under the License.
11+
*/
12+
export * from './ActionButton.types.js';

2nd-gen/packages/core/package.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
},
1616
"type": "module",
1717
"exports": {
18+
"./components/action-button": {
19+
"types": "./dist/components/action-button/index.d.ts",
20+
"import": "./dist/components/action-button/index.js"
21+
},
1822
"./components/alert-banner": {
1923
"types": "./dist/components/alert-banner/index.d.ts",
2024
"import": "./dist/components/alert-banner/index.js"
@@ -165,6 +169,9 @@
165169
},
166170
"typesVersions": {
167171
"*": {
172+
"components/action-button": [
173+
"dist/components/action-button/index.d.ts"
174+
],
168175
"components/alert-banner": [
169176
"dist/components/alert-banner/index.d.ts"
170177
],
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
/**
2+
* Copyright 2026 Adobe. All rights reserved.
3+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License. You may obtain a copy
5+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software distributed under
8+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9+
* OF ANY KIND, either express or implied. See the License for the specific language
10+
* governing permissions and limitations under the License.
11+
*/
12+
13+
import { CSSResultArray, html, PropertyValues, TemplateResult } from 'lit';
14+
import { property } from 'lit/decorators.js';
15+
import { classMap } from 'lit/directives/class-map.js';
16+
import { ifDefined } from 'lit/directives/if-defined.js';
17+
18+
import {
19+
ACTION_BUTTON_VALID_SIZES,
20+
type ActionButtonSize,
21+
type ActionButtonStaticColor,
22+
} from '@spectrum-web-components/core/components/action-button';
23+
import { ButtonBase } from '@spectrum-web-components/core/components/button';
24+
25+
import styles from './action-button.css';
26+
27+
/**
28+
* A compact action button for toolbars, action groups, and icon-first chrome.
29+
*
30+
* @element swc-action-button
31+
* @since 0.0.1
32+
*
33+
* @slot - Visible button label.
34+
* @slot icon - Optional leading icon displayed before the label.
35+
*
36+
* @example
37+
* <swc-action-button>Edit</swc-action-button>
38+
*
39+
* @example
40+
* <swc-action-button quiet>
41+
* <sp-icon-edit slot="icon"></sp-icon-edit>
42+
* Edit
43+
* </swc-action-button>
44+
*/
45+
export class ActionButton extends ButtonBase {
46+
// ──────────────────────
47+
// API OVERRIDES
48+
// ──────────────────────
49+
50+
/** @internal */
51+
static override readonly VALID_SIZES: readonly ActionButtonSize[] =
52+
ACTION_BUTTON_VALID_SIZES;
53+
54+
/**
55+
* Size of the button. Supports the full `xs`–`xl` range; `xs` is an
56+
* action-button-specific addition not available on `swc-button`.
57+
*/
58+
@property({ type: String })
59+
public override get size(): ActionButtonSize {
60+
return this._size ?? 'm';
61+
}
62+
63+
public override set size(value: ActionButtonSize) {
64+
const normalized = (
65+
value ? (value as string).toLocaleLowerCase() : value
66+
) as ActionButtonSize;
67+
const validSize: ActionButtonSize = ACTION_BUTTON_VALID_SIZES.includes(
68+
normalized
69+
)
70+
? normalized
71+
: 'm';
72+
const oldSize = this._size ?? 'm';
73+
if (oldSize === validSize) {
74+
return;
75+
}
76+
this._size = validSize;
77+
this.setAttribute('size', validSize);
78+
this.requestUpdate('size', oldSize);
79+
}
80+
81+
private _size: ActionButtonSize | null = null;
82+
83+
// ───────────────────
84+
// API ADDITIONS
85+
// ───────────────────
86+
87+
/**
88+
* Applies the quiet (low-emphasis) visual treatment.
89+
*/
90+
@property({ type: Boolean, reflect: true })
91+
public quiet: boolean = false;
92+
93+
/**
94+
* Static color treatment for display over colored or image backgrounds.
95+
*/
96+
@property({ type: String, reflect: true, attribute: 'static-color' })
97+
public staticColor?: ActionButtonStaticColor;
98+
99+
// ──────────────────────────────
100+
// RENDERING & STYLING
101+
// ──────────────────────────────
102+
103+
public static override get styles(): CSSResultArray {
104+
return [styles];
105+
}
106+
107+
protected override render(): TemplateResult {
108+
return html`
109+
<button
110+
class=${classMap({
111+
'swc-ActionButton': true,
112+
'swc-ActionButton--hasIcon': this.hasIcon,
113+
'swc-ActionButton--iconOnly': this.hasIcon && !this.hasLabel,
114+
'swc-ActionButton--pendingActive': this.pendingActive,
115+
})}
116+
type="button"
117+
@click=${this.handleClick}
118+
?disabled=${this.disabled}
119+
aria-disabled=${ifDefined(
120+
this.pending && !this.disabled ? 'true' : undefined
121+
)}
122+
aria-label=${ifDefined(
123+
this.pending ? this.getPendingAccessibleName() : this.accessibleLabel
124+
)}
125+
>
126+
<slot name="icon"></slot>
127+
<span class="swc-ActionButton-label">
128+
<slot></slot>
129+
</span>
130+
</button>
131+
`;
132+
}
133+
134+
protected override update(changes: PropertyValues): void {
135+
super.update(changes);
136+
// Counteracts SizedMixin's auto-reflect of size="m" when no size was explicitly set.
137+
if (this._size === null) {
138+
this.removeAttribute('size');
139+
}
140+
}
141+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/**
2+
* Copyright 2026 Adobe. All rights reserved.
3+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License. You may obtain a copy
5+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software distributed under
8+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9+
* OF ANY KIND, either express or implied. See the License for the specific language
10+
* governing permissions and limitations under the License.
11+
*/
12+
13+
.swc-ActionButton {
14+
display: inline-flex;
15+
align-items: center;
16+
justify-content: center;
17+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/**
2+
* Copyright 2026 Adobe. All rights reserved.
3+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License. You may obtain a copy
5+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software distributed under
8+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9+
* OF ANY KIND, either express or implied. See the License for the specific language
10+
* governing permissions and limitations under the License.
11+
*/
12+
export * from './ActionButton.js';
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/**
2+
* Copyright 2026 Adobe. All rights reserved.
3+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License. You may obtain a copy
5+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software distributed under
8+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9+
* OF ANY KIND, either express or implied. See the License for the specific language
10+
* governing permissions and limitations under the License.
11+
*/
12+
13+
import type { Meta, StoryObj as Story } from '@storybook/web-components';
14+
import { getStorybookHelpers } from '@wc-toolkit/storybook-helpers';
15+
16+
import '@adobe/spectrum-wc/components/action-button/swc-action-button.js';
17+
18+
// ────────────────
19+
// METADATA
20+
// ────────────────
21+
22+
const { args, argTypes, template } = getStorybookHelpers('swc-action-button');
23+
24+
/**
25+
* A compact action button for toolbars, action groups, and icon-first chrome.
26+
*/
27+
const meta: Meta = {
28+
title: 'Action Button',
29+
component: 'swc-action-button',
30+
args,
31+
argTypes,
32+
render: (args) => template(args),
33+
parameters: {
34+
docs: {
35+
subtitle: 'Compact button for toolbars and action groups',
36+
},
37+
},
38+
tags: ['migrated'],
39+
};
40+
41+
export default meta;
42+
43+
// ────────────────────
44+
// AUTODOCS STORY
45+
// ────────────────────
46+
47+
export const Playground: Story = {
48+
args: {
49+
'default-slot': 'Edit',
50+
},
51+
tags: ['autodocs', 'dev'],
52+
};
53+
54+
// ──────────────────────────
55+
// OVERVIEW STORY
56+
// ──────────────────────────
57+
58+
export const Overview: Story = {
59+
args: {
60+
'default-slot': 'Edit',
61+
},
62+
tags: ['overview'],
63+
};
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
* Copyright 2026 Adobe. All rights reserved.
3+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License. You may obtain a copy
5+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software distributed under
8+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9+
* OF ANY KIND, either express or implied. See the License for the specific language
10+
* governing permissions and limitations under the License.
11+
*/
12+
import { defineElement } from '@spectrum-web-components/core/element/index.js';
13+
14+
import { ActionButton } from './ActionButton.js';
15+
16+
declare global {
17+
interface HTMLElementTagNameMap {
18+
'swc-action-button': ActionButton;
19+
}
20+
}
21+
22+
defineElement('swc-action-button', ActionButton);
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/**
2+
* Copyright 2026 Adobe. All rights reserved.
3+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License. You may obtain a copy
5+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software distributed under
8+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9+
* OF ANY KIND, either express or implied. See the License for the specific language
10+
* governing permissions and limitations under the License.
11+
*/
12+
13+
/**
14+
* Accessibility tests for ActionButton component (2nd generation).
15+
*
16+
* ARIA snapshot tests validate the accessibility tree structure.
17+
* aXe WCAG compliance and color contrast validation are run via
18+
* test-storybook (see .storybook/test-runner.ts). Both are included
19+
* in the `test:a11y` command.
20+
*/
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/**
2+
* Copyright 2026 Adobe. All rights reserved.
3+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License. You may obtain a copy
5+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software distributed under
8+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9+
* OF ANY KIND, either express or implied. See the License for the specific language
10+
* governing permissions and limitations under the License.
11+
*/
12+
13+
import type { Meta, StoryObj as Story } from '@storybook/web-components';
14+
15+
import meta, { Overview } from '../stories/action-button.stories.js';
16+
17+
export default {
18+
...meta,
19+
title: 'Action Button/Tests',
20+
parameters: {
21+
...meta.parameters,
22+
docs: { disable: true, page: null },
23+
},
24+
tags: ['!autodocs', 'dev'],
25+
} as Meta;
26+
27+
// Placeholder: play function with component-specific assertions is added in Phase 6.
28+
export const OverviewTest: Story = {
29+
...Overview,
30+
};

0 commit comments

Comments
 (0)