@ogds/elements 1.0.0-alpha.6 → 1.0.0-alpha.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.storybook/{UswdsTheme.js → OgdsTheme.js} +1 -1
- package/.storybook/manager.js +2 -2
- package/.storybook/preview.js +2 -2
- package/.storybook/worker.js +5 -0
- package/README.md +39 -136
- package/dist/components/frameworks/react/{UsaLink.d.ts → OGDSAlert.d.ts} +15 -14
- package/dist/components/frameworks/react/OGDSAlert.js +23 -0
- package/dist/components/frameworks/react/OgdsAccordionToggle.d.ts +4 -6
- package/dist/components/frameworks/react/OgdsAccordionToggle.js +1 -3
- package/dist/components/frameworks/react/{UsaBanner.d.ts → OgdsBanner.d.ts} +9 -9
- package/dist/components/frameworks/react/{UsaBanner.js → OgdsBanner.js} +3 -3
- package/dist/components/frameworks/react/OgdsTaskList.d.ts +48 -0
- package/dist/components/frameworks/react/{UsaLink.js → OgdsTaskList.js} +4 -7
- package/dist/components/frameworks/react/index.d.ts +3 -2
- package/dist/components/frameworks/react/index.js +3 -2
- package/dist/components/index.cjs +15 -1
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.d.ts +4 -3
- package/dist/components/index.js +162 -4
- package/dist/components/index.js.map +1 -1
- package/dist/components/ogds-accordion/index.d.ts +36 -0
- package/dist/components/ogds-accordion/ogds-accordion.spec.d.ts +1 -0
- package/dist/components/ogds-accordion-toggle/index.d.ts +25 -0
- package/dist/components/ogds-accordion-toggle/ogds-accordion-toggle.spec.d.ts +1 -0
- package/dist/components/ogds-alert/index.d.ts +21 -0
- package/dist/components/{usa-banner → ogds-banner}/index.d.ts +7 -7
- package/dist/components/ogds-banner.cjs +1 -0
- package/dist/components/ogds-banner.cjs.map +1 -0
- package/dist/components/ogds-banner.js +7 -0
- package/dist/components/ogds-banner.js.map +1 -0
- package/dist/components/task-list/index.d.ts +21 -0
- package/dist/core/token-styles.d.ts +1 -0
- package/dist/index-CC1QRihN.cjs +95 -0
- package/dist/index-CC1QRihN.cjs.map +1 -0
- package/dist/{components/usa-banner.js → index-DDf2o6Dk.js} +34 -28
- package/dist/index-DDf2o6Dk.js.map +1 -0
- package/dist/types/custom-element-jsx.d.ts +32 -22
- package/dist/types/custom-element-solidjs.d.ts +39 -27
- package/dist/types/custom-element-svelte.d.ts +32 -22
- package/dist/types/custom-element-vuejs.d.ts +32 -22
- package/package.json +44 -29
- package/src/Globals.d.ts +3 -0
- package/src/components/index.ts +3 -3
- package/src/components/ogds-accordion/docs.mdx +31 -20
- package/src/components/ogds-accordion/ogds-accordion.stories.ts +12 -0
- package/src/components/ogds-accordion-toggle/docs.mdx +54 -0
- package/src/components/ogds-accordion-toggle/index.ts +38 -11
- package/src/components/ogds-accordion-toggle/ogds-accordion-toggle.css +31 -0
- package/src/components/ogds-accordion-toggle/ogds-accordion-toggle.spec.ts +227 -0
- package/src/components/ogds-accordion-toggle/ogds-accordion-toggle.stories.ts +95 -0
- package/src/components/ogds-alert/base-variables.css +496 -0
- package/src/components/ogds-alert/index.ts +78 -0
- package/src/components/ogds-alert/ogds-alert.css +119 -0
- package/src/components/ogds-alert/ogds-alert.stories.ts +75 -0
- package/src/components/{usa-banner → ogds-banner}/docs.mdx +1 -10
- package/src/components/{usa-banner → ogds-banner}/index.ts +17 -15
- package/src/components/{usa-banner/usa-banner.spec.ts → ogds-banner/ogds-banner.spec.ts} +5 -5
- package/src/components/{usa-banner/usa-banner.stories.ts → ogds-banner/ogds-banner.stories.ts} +2 -2
- package/src/components/task-list/docs.mdx +23 -0
- package/src/components/task-list/index.ts +65 -0
- package/src/components/task-list/ogds-task-list.css +34 -0
- package/src/components/task-list/ogds-task-list.stories.ts +46 -0
- package/src/core/token-styles.ts +2 -0
- package/src/declaration.d.ts +5 -0
- package/storybook/contributing.mdx +1 -110
- package/storybook/framework-guidance.mdx +5 -5
- package/storybook/readme.mdx +1 -1
- package/dist/components/usa-banner/usa-banner.stories.d.ts +0 -95
- package/dist/components/usa-banner.cjs +0 -95
- package/dist/components/usa-banner.cjs.map +0 -1
- package/dist/components/usa-banner.js.map +0 -1
- package/dist/components/usa-header/index.d.ts +0 -6
- package/dist/components/usa-link/index.d.ts +0 -30
- package/dist/components/usa-link/usa-link.spec.d.ts +0 -0
- package/dist/components/usa-link.cjs +0 -5
- package/dist/components/usa-link.cjs.map +0 -1
- package/dist/components/usa-link.js +0 -32
- package/dist/components/usa-link.js.map +0 -1
- package/dist/core/OgdsElement.d.ts +0 -3
- package/dist/index-7kIMQwBw.cjs +0 -1
- package/dist/index-7kIMQwBw.cjs.map +0 -1
- package/dist/index-BrHk1-6T.js +0 -10
- package/dist/index-BrHk1-6T.js.map +0 -1
- package/src/components/ogds-accordion/.claude/settings.local.json +0 -7
- package/src/components/usa-header/index.ts +0 -50
- package/src/components/usa-header/usa-header.css +0 -1
- package/src/components/usa-link/index.ts +0 -66
- package/src/components/usa-link/usa-link.css +0 -24
- package/src/components/usa-link/usa-link.spec.ts +0 -50
- /package/dist/components/{usa-banner/usa-banner.spec.d.ts → ogds-banner/ogds-banner.spec.d.ts} +0 -0
- /package/src/components/{usa-banner/usa-banner.css → ogds-banner/ogds-banner.css} +0 -0
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
|
2
|
+
|
|
3
|
+
vi.mock("./ogds-accordion-toggle.css", () => ({ default: { cssText: "" } }));
|
|
4
|
+
vi.mock("../../core/token-styles", () => ({ adoptTokenStyles: vi.fn() }));
|
|
5
|
+
|
|
6
|
+
import { OgdsAccordionToggle } from "./index";
|
|
7
|
+
|
|
8
|
+
function mountPair({
|
|
9
|
+
accordionId = "test-accordion",
|
|
10
|
+
openItems = false,
|
|
11
|
+
expandLabel,
|
|
12
|
+
collapseLabel,
|
|
13
|
+
}: {
|
|
14
|
+
accordionId?: string;
|
|
15
|
+
openItems?: boolean;
|
|
16
|
+
expandLabel?: string;
|
|
17
|
+
collapseLabel?: string;
|
|
18
|
+
} = {}): OgdsAccordionToggle {
|
|
19
|
+
const accordion = document.createElement("div");
|
|
20
|
+
accordion.id = accordionId;
|
|
21
|
+
accordion.innerHTML = `
|
|
22
|
+
<details${openItems ? " open" : ""}><summary>One</summary></details>
|
|
23
|
+
<details${openItems ? " open" : ""}><summary>Two</summary></details>
|
|
24
|
+
`;
|
|
25
|
+
document.body.appendChild(accordion);
|
|
26
|
+
|
|
27
|
+
const toggle = document.createElement(
|
|
28
|
+
"ogds-accordion-toggle",
|
|
29
|
+
) as OgdsAccordionToggle;
|
|
30
|
+
toggle.setAttribute("controls", accordionId);
|
|
31
|
+
if (expandLabel) {
|
|
32
|
+
const span = document.createElement("span");
|
|
33
|
+
span.slot = "expand-label";
|
|
34
|
+
span.textContent = expandLabel;
|
|
35
|
+
toggle.appendChild(span);
|
|
36
|
+
}
|
|
37
|
+
if (collapseLabel) {
|
|
38
|
+
const span = document.createElement("span");
|
|
39
|
+
span.slot = "collapse-label";
|
|
40
|
+
span.textContent = collapseLabel;
|
|
41
|
+
toggle.appendChild(span);
|
|
42
|
+
}
|
|
43
|
+
document.body.appendChild(toggle);
|
|
44
|
+
return toggle;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function getButton(toggle: OgdsAccordionToggle): HTMLButtonElement {
|
|
48
|
+
return toggle.shadowRoot!.querySelector("button") as HTMLButtonElement;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
beforeEach(() => {
|
|
52
|
+
document.adoptedStyleSheets = [];
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
afterEach(() => {
|
|
56
|
+
document.body.innerHTML = "";
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
function getExpandSlot(toggle: OgdsAccordionToggle): HTMLSlotElement {
|
|
60
|
+
return toggle.shadowRoot!.querySelector(
|
|
61
|
+
'slot[name="expand-label"]',
|
|
62
|
+
) as HTMLSlotElement;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function getCollapseSlot(toggle: OgdsAccordionToggle): HTMLSlotElement {
|
|
66
|
+
return toggle.shadowRoot!.querySelector(
|
|
67
|
+
'slot[name="collapse-label"]',
|
|
68
|
+
) as HTMLSlotElement;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
describe("rendering", () => {
|
|
72
|
+
it("renders with the expand slot visible and fallback text 'Expand All' by default", async () => {
|
|
73
|
+
const toggle = mountPair();
|
|
74
|
+
await toggle.updateComplete;
|
|
75
|
+
expect(getExpandSlot(toggle).hasAttribute("hidden")).toBe(false);
|
|
76
|
+
expect(getExpandSlot(toggle).textContent?.trim()).toBe("Expand All");
|
|
77
|
+
expect(getCollapseSlot(toggle).hasAttribute("hidden")).toBe(true);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it("renders with custom slotted expand label content", async () => {
|
|
81
|
+
const toggle = mountPair({
|
|
82
|
+
expandLabel: "Open All",
|
|
83
|
+
collapseLabel: "Close All",
|
|
84
|
+
});
|
|
85
|
+
await toggle.updateComplete;
|
|
86
|
+
expect(toggle.querySelector('[slot="expand-label"]')?.textContent).toBe(
|
|
87
|
+
"Open All",
|
|
88
|
+
);
|
|
89
|
+
expect(toggle.querySelector('[slot="collapse-label"]')?.textContent).toBe(
|
|
90
|
+
"Close All",
|
|
91
|
+
);
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
describe("MutationObserver sync", () => {
|
|
96
|
+
it("switches to collapse slot when a panel is opened manually", async () => {
|
|
97
|
+
const toggle = mountPair();
|
|
98
|
+
await toggle.updateComplete;
|
|
99
|
+
expect(getExpandSlot(toggle).hasAttribute("hidden")).toBe(false);
|
|
100
|
+
|
|
101
|
+
const details = document.querySelector("details")!;
|
|
102
|
+
details.setAttribute("open", "");
|
|
103
|
+
await Promise.resolve(); // flush MutationObserver callback
|
|
104
|
+
await toggle.updateComplete;
|
|
105
|
+
|
|
106
|
+
expect(getCollapseSlot(toggle).hasAttribute("hidden")).toBe(false);
|
|
107
|
+
expect(getExpandSlot(toggle).hasAttribute("hidden")).toBe(true);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it("switches to expand slot when all panels are closed manually", async () => {
|
|
111
|
+
const toggle = mountPair({ openItems: true });
|
|
112
|
+
await toggle.updateComplete;
|
|
113
|
+
expect(getCollapseSlot(toggle).hasAttribute("hidden")).toBe(false);
|
|
114
|
+
|
|
115
|
+
document
|
|
116
|
+
.querySelectorAll("details")
|
|
117
|
+
.forEach((d) => d.removeAttribute("open"));
|
|
118
|
+
await Promise.resolve(); // flush MutationObserver callback
|
|
119
|
+
await toggle.updateComplete;
|
|
120
|
+
|
|
121
|
+
expect(getExpandSlot(toggle).hasAttribute("hidden")).toBe(false);
|
|
122
|
+
expect(getCollapseSlot(toggle).hasAttribute("hidden")).toBe(true);
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
describe("toggleAll", () => {
|
|
127
|
+
it("opens all details when none are open", async () => {
|
|
128
|
+
const toggle = mountPair();
|
|
129
|
+
await toggle.updateComplete;
|
|
130
|
+
getButton(toggle).click();
|
|
131
|
+
await toggle.updateComplete;
|
|
132
|
+
document.querySelectorAll("details").forEach((d) => {
|
|
133
|
+
expect(d.hasAttribute("open")).toBe(true);
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
it("shows the collapse slot and hides the expand slot after expanding all", async () => {
|
|
138
|
+
const toggle = mountPair();
|
|
139
|
+
await toggle.updateComplete;
|
|
140
|
+
getButton(toggle).click();
|
|
141
|
+
await toggle.updateComplete;
|
|
142
|
+
expect(getCollapseSlot(toggle).hasAttribute("hidden")).toBe(false);
|
|
143
|
+
expect(getExpandSlot(toggle).hasAttribute("hidden")).toBe(true);
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
it("closes all details when all are open", async () => {
|
|
147
|
+
const toggle = mountPair();
|
|
148
|
+
await toggle.updateComplete;
|
|
149
|
+
getButton(toggle).click();
|
|
150
|
+
await toggle.updateComplete;
|
|
151
|
+
getButton(toggle).click();
|
|
152
|
+
await toggle.updateComplete;
|
|
153
|
+
document.querySelectorAll("details").forEach((d) => {
|
|
154
|
+
expect(d.hasAttribute("open")).toBe(false);
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
it("shows the expand slot and hides the collapse slot after collapsing all", async () => {
|
|
159
|
+
const toggle = mountPair();
|
|
160
|
+
await toggle.updateComplete;
|
|
161
|
+
getButton(toggle).click();
|
|
162
|
+
await toggle.updateComplete;
|
|
163
|
+
getButton(toggle).click();
|
|
164
|
+
await toggle.updateComplete;
|
|
165
|
+
expect(getExpandSlot(toggle).hasAttribute("hidden")).toBe(false);
|
|
166
|
+
expect(getCollapseSlot(toggle).hasAttribute("hidden")).toBe(true);
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
it("logs an error when the target accordion is not found", async () => {
|
|
170
|
+
const errorSpy = vi.spyOn(console, "error").mockImplementation(() => {});
|
|
171
|
+
document.body.innerHTML = `<ogds-accordion-toggle controls="nonexistent"></ogds-accordion-toggle>`;
|
|
172
|
+
const toggle = document.body.querySelector(
|
|
173
|
+
"ogds-accordion-toggle",
|
|
174
|
+
) as OgdsAccordionToggle;
|
|
175
|
+
await toggle.updateComplete;
|
|
176
|
+
toggle.toggleAll();
|
|
177
|
+
expect(errorSpy).toHaveBeenCalledOnce();
|
|
178
|
+
errorSpy.mockRestore();
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
describe("checkOpen", () => {
|
|
183
|
+
it("returns false when no details are open", async () => {
|
|
184
|
+
const toggle = mountPair();
|
|
185
|
+
await toggle.updateComplete;
|
|
186
|
+
expect(toggle.checkOpen()).toBe(false);
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
it("returns true when at least one details is open", async () => {
|
|
190
|
+
const toggle = mountPair({ openItems: true });
|
|
191
|
+
await toggle.updateComplete;
|
|
192
|
+
expect(toggle.checkOpen()).toBe(true);
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
describe("missing controls attribute", () => {
|
|
197
|
+
it("logs a console error when controls is not set", async () => {
|
|
198
|
+
const errorSpy = vi.spyOn(console, "error").mockImplementation(() => {});
|
|
199
|
+
document.body.innerHTML = `<ogds-accordion-toggle></ogds-accordion-toggle>`;
|
|
200
|
+
const toggle = document.body.querySelector(
|
|
201
|
+
"ogds-accordion-toggle",
|
|
202
|
+
) as OgdsAccordionToggle;
|
|
203
|
+
await toggle.updateComplete;
|
|
204
|
+
expect(errorSpy).toHaveBeenCalledOnce();
|
|
205
|
+
errorSpy.mockRestore();
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
describe("stylesheet adoption", () => {
|
|
210
|
+
beforeEach(() => {
|
|
211
|
+
(OgdsAccordionToggle as any)._sheet = null;
|
|
212
|
+
document.adoptedStyleSheets = [];
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
it("adds a stylesheet to document.adoptedStyleSheets on first mount", async () => {
|
|
216
|
+
const toggle = mountPair();
|
|
217
|
+
await toggle.updateComplete;
|
|
218
|
+
expect(document.adoptedStyleSheets).toHaveLength(1);
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
it("does not add the stylesheet more than once when multiple toggles are mounted", async () => {
|
|
222
|
+
const toggle1 = mountPair({ accordionId: "acc1" });
|
|
223
|
+
const toggle2 = mountPair({ accordionId: "acc2" });
|
|
224
|
+
await Promise.all([toggle1.updateComplete, toggle2.updateComplete]);
|
|
225
|
+
expect(document.adoptedStyleSheets).toHaveLength(1);
|
|
226
|
+
});
|
|
227
|
+
});
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { html } from "lit";
|
|
2
|
+
import "./index";
|
|
3
|
+
import "../ogds-accordion/index";
|
|
4
|
+
import ComponentDocs from "./docs.mdx";
|
|
5
|
+
import { expect, userEvent, waitFor } from "storybook/test";
|
|
6
|
+
import { within } from "shadow-dom-testing-library";
|
|
7
|
+
|
|
8
|
+
const items = html`
|
|
9
|
+
<details>
|
|
10
|
+
<summary>First Amendment</summary>
|
|
11
|
+
<p>
|
|
12
|
+
Congress shall make no law respecting an establishment of religion, or
|
|
13
|
+
prohibiting the free exercise thereof; or abridging the freedom of speech,
|
|
14
|
+
or of the press; or the right of the people peaceably to assemble, and to
|
|
15
|
+
petition the Government for a redress of grievances.
|
|
16
|
+
</p>
|
|
17
|
+
</details>
|
|
18
|
+
<details>
|
|
19
|
+
<summary>Second Amendment</summary>
|
|
20
|
+
<p>
|
|
21
|
+
A well regulated Militia, being necessary to the security of a free State,
|
|
22
|
+
the right of the people to keep and bear Arms, shall not be infringed.
|
|
23
|
+
</p>
|
|
24
|
+
</details>
|
|
25
|
+
<details>
|
|
26
|
+
<summary>Third Amendment</summary>
|
|
27
|
+
<p>
|
|
28
|
+
No Soldier shall, in time of peace be quartered in any house, without the
|
|
29
|
+
consent of the Owner, nor in time of war, but in a manner to be prescribed
|
|
30
|
+
by law.
|
|
31
|
+
</p>
|
|
32
|
+
</details>
|
|
33
|
+
`;
|
|
34
|
+
|
|
35
|
+
export default {
|
|
36
|
+
title: "Components/Accordion Toggle",
|
|
37
|
+
component: "ogds-accordion-toggle",
|
|
38
|
+
tags: ["alpha"],
|
|
39
|
+
parameters: {
|
|
40
|
+
docs: {
|
|
41
|
+
page: ComponentDocs,
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export const Default = {
|
|
47
|
+
render: () => html`
|
|
48
|
+
<ogds-accordion-toggle
|
|
49
|
+
controls="accordion-toggle-default"
|
|
50
|
+
></ogds-accordion-toggle>
|
|
51
|
+
<ogds-accordion id="accordion-toggle-default">${items}</ogds-accordion>
|
|
52
|
+
`,
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export const CustomLabels = {
|
|
56
|
+
render: () => html`
|
|
57
|
+
<ogds-accordion-toggle controls="accordion-toggle-custom">
|
|
58
|
+
<span slot="expand-label">Show All</span>
|
|
59
|
+
<span slot="collapse-label">Hide All</span>
|
|
60
|
+
</ogds-accordion-toggle>
|
|
61
|
+
<ogds-accordion id="accordion-toggle-custom">${items}</ogds-accordion>
|
|
62
|
+
`,
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
export const ToggleTest = {
|
|
66
|
+
parameters: {
|
|
67
|
+
docs: {
|
|
68
|
+
disable: true,
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
render: () => html`
|
|
72
|
+
<ogds-accordion-toggle
|
|
73
|
+
controls="accordion-toggle-test"
|
|
74
|
+
></ogds-accordion-toggle>
|
|
75
|
+
<ogds-accordion id="accordion-toggle-test">${items}</ogds-accordion>
|
|
76
|
+
`,
|
|
77
|
+
play: async ({ canvasElement }: { canvasElement: HTMLElement }) => {
|
|
78
|
+
const canvas = within(canvasElement);
|
|
79
|
+
const button = canvas.getByShadowRole("button");
|
|
80
|
+
|
|
81
|
+
await userEvent.click(button);
|
|
82
|
+
await waitFor(() => {
|
|
83
|
+
canvasElement.querySelectorAll("details").forEach((d) => {
|
|
84
|
+
expect(d).toHaveAttribute("open");
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
await userEvent.click(button);
|
|
89
|
+
await waitFor(() => {
|
|
90
|
+
canvasElement.querySelectorAll("details").forEach((d) => {
|
|
91
|
+
expect(d).not.toHaveAttribute("open");
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
},
|
|
95
|
+
};
|