Skip to content

Commit a2a2bc9

Browse files
feat(accordion): add direct actions feature
- adds direct actions feature to storybook, template, and css
1 parent 84ca9cf commit a2a2bc9

File tree

5 files changed

+108
-2
lines changed

5 files changed

+108
-2
lines changed

components/accordion/dist/metadata.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
".spectrum-Accordion-item.is-open > .spectrum-Accordion-itemHeading .spectrum-Accordion-itemIndicator",
2323
".spectrum-Accordion-item:first-child",
2424
".spectrum-Accordion-itemContent",
25+
".spectrum-Accordion-itemDirectActions",
26+
".spectrum-Accordion-itemDirectActions .spectrum-ActionButton",
27+
".spectrum-Accordion-itemDirectActions .spectrum-Switch",
2528
".spectrum-Accordion-itemHeader",
2629
".spectrum-Accordion-itemHeader.spectrum-Accordion-itemHeader:active",
2730
".spectrum-Accordion-itemHeader:focus-visible",
@@ -44,6 +47,8 @@
4447
"--mod-accordion-background-color-key-focus",
4548
"--mod-accordion-content-padding-inline",
4649
"--mod-accordion-corner-radius",
50+
"--mod-accordion-direct-actions-height",
51+
"--mod-accordion-direct-actions-vertical-spacing",
4752
"--mod-accordion-disclosure-indicator-height",
4853
"--mod-accordion-disclosure-indicator-to-text-space",
4954
"--mod-accordion-divider-color",
@@ -60,6 +65,7 @@
6065
"--mod-accordion-item-content-font-style",
6166
"--mod-accordion-item-content-font-weight",
6267
"--mod-accordion-item-content-line-height",
68+
"--mod-accordion-item-direct-actions-spacing",
6369
"--mod-accordion-item-focus-indicator-color",
6470
"--mod-accordion-item-focus-indicator-gap",
6571
"--mod-accordion-item-focus-indicator-thickness",
@@ -107,6 +113,8 @@
107113
"--spectrum-accordion-content-area-top-to-content",
108114
"--spectrum-accordion-content-padding-inline",
109115
"--spectrum-accordion-corner-radius",
116+
"--spectrum-accordion-direct-actions-height",
117+
"--spectrum-accordion-direct-actions-vertical-spacing",
110118
"--spectrum-accordion-disclosure-indicator-height",
111119
"--spectrum-accordion-disclosure-indicator-to-text-extra-large",
112120
"--spectrum-accordion-disclosure-indicator-to-text-large",
@@ -131,6 +139,7 @@
131139
"--spectrum-accordion-item-content-font-style",
132140
"--spectrum-accordion-item-content-font-weight",
133141
"--spectrum-accordion-item-content-line-height",
142+
"--spectrum-accordion-item-direct-actions-spacing",
134143
"--spectrum-accordion-item-focus-indicator-color",
135144
"--spectrum-accordion-item-focus-indicator-gap",
136145
"--spectrum-accordion-item-focus-indicator-thickness",
@@ -227,6 +236,7 @@
227236
"--spectrum-neutral-content-color-hover",
228237
"--spectrum-neutral-content-color-key-focus",
229238
"--spectrum-sans-font-family-stack",
239+
"--spectrum-spacing-100",
230240
"--spectrum-transparent-black-100",
231241
"--spectrum-transparent-black-25",
232242
"--spectrum-transparent-black-300"

components/accordion/index.css

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
--spectrum-accordion-item-content-area-top-to-content: var(--spectrum-accordion-content-area-top-to-content);
3232
--spectrum-accordion-item-content-area-bottom-to-content: var(--spectrum-accordion-content-area-bottom-to-content);
3333
--spectrum-accordion-divider-thickness: var(--spectrum-divider-thickness-small);
34+
--spectrum-accordion-direct-actions-height: var(--spectrum-component-height-100);
3435

3536
/* Text header */
3637
--spectrum-accordion-item-header-font: var(--spectrum-sans-font-family-stack);
@@ -40,6 +41,7 @@
4041
--spectrum-accordion-item-header-line-height: var(--spectrum-line-height-100);
4142

4243
--spectrum-accordion-item-header-cursor: pointer;
44+
--spectrum-accordion-item-direct-actions-spacing: var(--spectrum-spacing-100);
4345
--spectrum-accordion-animation-duration: var(--spectrum-animation-duration-100);
4446

4547
/* Text body */
@@ -72,6 +74,12 @@
7274
var(--mod-accordion-item-header-top-to-text-space, var(--spectrum-accordion-item-header-top-to-text-space)) + var(--mod-accordion-item-header-bottom-to-text-space, var(--spectrum-accordion-item-header-bottom-to-text-space)) + (var(--mod-accordion-item-header-font-size, var(--spectrum-accordion-item-header-font-size)) * var(--mod-accordion-item-header-line-height, var(--spectrum-accordion-item-header-line-height)))
7375
);
7476

77+
/* Calculated vertical spacing for action button and switch to center them within the accordion item */
78+
--spectrum-accordion-direct-actions-vertical-spacing: calc(
79+
(var(--mod-accordion-item-min-block-size, var(--spectrum-accordion-item-min-block-size)) -
80+
var(--mod-accordion-direct-actions-height, var(--spectrum-accordion-direct-actions-height))) / 2
81+
);
82+
7583
/* Right-to-left adjustments for transforms */
7684
&:dir(rtl) {
7785
--spectrum-logical-rotation: matrix(-1, 0, 0, 1, 0, 0);
@@ -100,6 +108,7 @@
100108
--spectrum-accordion-item-header-top-to-text-space: var(--spectrum-accordion-top-to-text-small);
101109
--spectrum-accordion-item-header-bottom-to-text-space: var(--spectrum-accordion-bottom-to-text-small);
102110
--spectrum-accordion-top-to-disclosure-indicator: var(--spectrum-field-top-to-disclosure-icon-small);
111+
--spectrum-accordion-direct-actions-height: var(--spectrum-component-height-75); /* component height for switch and action button */
103112
}
104113

105114
.spectrum-Accordion--sizeL {
@@ -116,6 +125,7 @@
116125
--spectrum-accordion-item-header-top-to-text-space: var(--spectrum-accordion-top-to-text-large);
117126
--spectrum-accordion-item-header-bottom-to-text-space: var(--spectrum-accordion-bottom-to-text-large);
118127
--spectrum-accordion-top-to-disclosure-indicator: var(--spectrum-field-top-to-disclosure-icon-large);
128+
--spectrum-accordion-direct-actions-height: var(--spectrum-component-height-200);
119129
}
120130

121131
.spectrum-Accordion--sizeXL {
@@ -132,6 +142,7 @@
132142
--spectrum-accordion-item-header-top-to-text-space: var(--spectrum-accordion-top-to-text-extra-large);
133143
--spectrum-accordion-item-header-bottom-to-text-space: var(--spectrum-accordion-bottom-to-text-extra-large);
134144
--spectrum-accordion-top-to-disclosure-indicator: var(--spectrum-field-top-to-disclosure-icon-extra-large);
145+
--spectrum-accordion-direct-actions-height: var(--spectrum-component-height-300);
135146
}
136147

137148
.spectrum-Accordion--compact {
@@ -237,6 +248,7 @@
237248
margin: 0;
238249
position: relative;
239250
box-sizing: border-box;
251+
display: flex;
240252
}
241253

242254
.spectrum-Accordion-itemIndicator {
@@ -268,6 +280,9 @@
268280

269281
/* Focusable button that expands/collapses the accordion item. */
270282
.spectrum-Accordion-itemHeader {
283+
text-overflow: ellipsis;
284+
word-break: break-word;
285+
271286
box-sizing: border-box;
272287
position: relative;
273288

@@ -277,6 +292,7 @@
277292

278293
/* start spacing controlled by edge to disclosure icon spacing */
279294
padding-inline: 0 var(--mod-accordion-edge-to-content-area, var(--spectrum-accordion-edge-to-content-area));
295+
padding-block: 0; /* reset user-agent styles */
280296
line-height: var(--mod-accordion-item-header-line-height, var(--spectrum-accordion-item-header-line-height));
281297

282298
text-overflow: ellipsis;
@@ -315,6 +331,17 @@
315331
}
316332
}
317333

334+
.spectrum-Accordion-itemDirectActions {
335+
margin-inline-end: var(--mod-accordion-edge-to-content-area, var(--spectrum-accordion-edge-to-content-area));
336+
display: inline-flex;
337+
gap: var(--mod-accordion-item-direct-actions-spacing, var(--spectrum-accordion-item-direct-actions-spacing));
338+
339+
& .spectrum-ActionButton,
340+
& .spectrum-Switch {
341+
margin-block-start: var(--mod-accordion-direct-actions-vertical-spacing, var(--spectrum-accordion-direct-actions-vertical-spacing));
342+
}
343+
}
344+
318345
.spectrum-Accordion-item.is-open {
319346
> .spectrum-Accordion-itemHeading .spectrum-Accordion-itemIndicator {
320347
transform: var(--spectrum-logical-rotation,) rotate(90deg);

components/accordion/stories/accordion.stories.js

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { default as IconStories } from "@spectrum-css/icon/stories/icon.stories.js";
12
import { Sizes } from "@spectrum-css/preview/decorators";
23
import { disableDefaultModes } from "@spectrum-css/preview/modes";
34
import { isQuiet, size } from "@spectrum-css/preview/types";
@@ -60,7 +61,36 @@ export default {
6061
},
6162
control: { type: "boolean" },
6263
},
63-
isQuiet
64+
isQuiet,
65+
hasActionButtons: {
66+
name: "Has action buttons",
67+
description: "Adds an action button to each accordion item header, in the direct actions section.",
68+
type: { name: "boolean" },
69+
table: {
70+
type: { summary: "boolean" },
71+
category: "Direct actions",
72+
},
73+
control: { type: "boolean" },
74+
},
75+
actionButtonIconName: {
76+
name: "Action button icon",
77+
...(IconStories?.argTypes?.iconName ?? {}),
78+
if: { arg: "hasActionButtons", truthy: true },
79+
table: {
80+
type: { summary: "string" },
81+
category: "Direct actions",
82+
},
83+
},
84+
hasSwitches: {
85+
name: "Has switches",
86+
description: "Adds a switch to each accordion item header, in the direct actions section.",
87+
type: { name: "boolean" },
88+
table: {
89+
type: { summary: "boolean" },
90+
category: "Direct actions",
91+
},
92+
control: { type: "boolean" },
93+
},
6494
},
6595
args: {
6696
rootClass: "spectrum-Accordion",
@@ -70,6 +100,9 @@ export default {
70100
disableAll: false,
71101
isQuiet: false,
72102
hasNoInlinePadding: false,
103+
hasActionButtons: false,
104+
actionButtonIconName: "Circle",
105+
hasSwitches: false,
73106
},
74107
parameters: {
75108
actions: {

components/accordion/stories/accordion.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ export const testsContent = new Map([
5959
},
6060
],
6161
[
62-
"Landscape",
62+
"Landscape and longer text that wraps",
6363
{
6464
content: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec eleifend est mollis ligula lobortis, tempus ultricies sapien lacinia. Nulla ut turpis velit. Sed finibus dapibus diam et sollicitudin. Phasellus in ipsum nec ante elementum congue eget in leo. Morbi eleifend justo non rutrum venenatis. Fusce cursus et lectus eu facilisis. Ut laoreet felis in magna dignissim feugiat.",
6565
},

components/accordion/stories/template.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1+
import { Template as ActionButton } from "@spectrum-css/actionbutton/stories/template.js";
12
import { Template as Icon } from "@spectrum-css/icon/stories/template.js";
23
import { getRandomId } from "@spectrum-css/preview/decorators";
4+
import { Template as Switch } from "@spectrum-css/switch/stories/template.js";
35
import { html } from "lit";
46
import { classMap } from "lit/directives/class-map.js";
57
import { ifDefined } from "lit/directives/if-defined.js";
68
import { repeat } from "lit/directives/repeat.js";
79
import { styleMap } from "lit/directives/style-map.js";
10+
import { when } from "lit/directives/when.js";
811

912
import "../index.css";
1013

@@ -19,6 +22,10 @@ export const AccordionItem = ({
1922
isHovered = false,
2023
isActive = false,
2124
isFocused = false,
25+
hasActionButton = false,
26+
hasSwitch = false,
27+
actionButtonIconName = "",
28+
size = "m",
2229
iconSize = "m",
2330
customStyles = {},
2431
customClasses = [],
@@ -66,6 +73,28 @@ export const AccordionItem = ({
6673
}, context)}
6774
<span class="${rootClass}Title">${heading}</span>
6875
</button>
76+
${when(
77+
hasActionButton || hasSwitch,
78+
() =>
79+
html`
80+
<div class="${rootClass}DirectActions">
81+
${when(hasActionButton, () =>
82+
ActionButton({
83+
label: "", // icon-only
84+
isQuiet: true,
85+
customClasses: [`${rootClass}ActionButton`],
86+
iconName: actionButtonIconName,
87+
size,
88+
}, context)
89+
)}
90+
${when(hasSwitch, () =>
91+
Switch({
92+
label: "",
93+
customClasses: [`${rootClass}Switch`],
94+
size
95+
}, context))}
96+
</div>
97+
`)}
6998
</h3>
7099
<!-- WAI-ARIA 1.1: Item content uses a role of "region" -->
71100
<div
@@ -90,6 +119,9 @@ export const Template = ({
90119
id = getRandomId("accordion"),
91120
disableAll = false,
92121
collapseAll = false,
122+
hasActionButtons = false,
123+
actionButtonIconName = "",
124+
hasSwitches = false,
93125
customClasses = [],
94126
customStyles = {},
95127
} = {}, context = {}) => {
@@ -118,6 +150,10 @@ export const Template = ({
118150
rootClass: `${rootClass}-item`,
119151
heading,
120152
idx,
153+
size,
154+
hasActionButton: item.hasActionButton || hasActionButtons,
155+
actionButtonIconName: item.actionButtonIconName || actionButtonIconName,
156+
hasSwitch: item.hasSwitch || hasSwitches,
121157
iconSize: `${size}`,
122158
isDisabled: item.isDisabled || disableAll,
123159
isOpen: collapseAll === true ? false : item.isOpen,

0 commit comments

Comments
 (0)