@dropins/tools 2.0.0-beta.1 → 2.0.1-alpha-20260728135101

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/CHANGELOG.md CHANGED
@@ -1,10 +1,254 @@
1
1
  # @adobe-commerce/elsie
2
2
 
3
+ ## 2.0.1-alpha-20260728135101
4
+
5
+ ### Patch Changes
6
+
7
+ - 7e84f40: chore: migrate build tooling from Yarn to pnpm
8
+
9
+ The monorepo now uses pnpm instead of Yarn v1. As part of this, elsie's CLI
10
+ (`lint`/`test`/`storybook`/`changeset`/`types`) no longer shells out to bare
11
+ command names — each tool is resolved and spawned directly, fixing a latent
12
+ path-with-spaces bug and command-injection surface.
13
+
14
+ - a920177: fix(Incrementer): prevent quantity input flicker during in-progress
15
+ typing, and prevent double onValue call when debounce fires before blur
16
+
17
+ ## 2.0.0
18
+
19
+ ### Major Changes
20
+
21
+ - ea02d5f: Upgrade Jest to 30.4.2 and Storybook to 10.4.0
22
+
23
+ Updated testing and component development tools to latest stable versions.
24
+ Jest 30.4.2 provides enhanced snapshot handling and improved test performance.
25
+ Storybook 10.4.0 includes updated addon ecosystem, improved Preact Vite
26
+ integration, and enhanced accessibility features with addon-a11y and
27
+ addon-coverage support.
28
+
29
+ - 9cd299b: Upgrade TypeScript to 6.0 and ESLint to 9 (flat config)
30
+
31
+ ## What changed
32
+
33
+ ### TypeScript 4.7 → 6.0
34
+ - `tsconfig-base.json` updated with correct TS 6 defaults. Two new-default
35
+ opt-outs are deferred as tech debt: `exactOptionalPropertyTypes` and
36
+ `verbatimModuleSyntax`.
37
+ - `moduleResolution` changed from `"nodenext"` to `"bundler"` across all
38
+ packages — the correct pairing for `module: "esnext"` in a Vite monorepo.
39
+ Only `packages/elsie` keeps `"NodeNext"` (paired with `module: "NodeNext"`
40
+ for its dual CJS/ESM output).
41
+ - `baseUrl` removed from all tsconfigs (deprecated in TS 6; `paths` resolves
42
+ relative to the tsconfig file directly).
43
+ - `rootDir` added explicitly to `build-tools`, `event-bus`, `fetch-graphql`,
44
+ and `recaptcha` tsconfigs (implicit `rootDir` deprecated in TS 6).
45
+ - `types: []` set in `tsconfig-base.json` to prevent ambient test types from
46
+ leaking into declaration output. Each package's own `tsconfig.json` declares
47
+ its `types` explicitly (`jest`, `node`, `vite/client`, etc.).
48
+ - `babel-plugin-tsconfig-paths` removed — it was a no-op in every package that
49
+ listed it.
50
+ - `noUncheckedIndexedAccess` enabled — violations were few enough to fix in
51
+ source.
52
+
53
+ ### ESLint 8 → 9 (flat config)
54
+ - `@typescript-eslint/parser` and `@typescript-eslint/eslint-plugin` (v5)
55
+ removed; replaced by the unified `typescript-eslint` v8 package.
56
+ - `eslint-config-preact` bumped to `^2.0.0` (ESLint 9 support).
57
+ - `eslint-config-prettier` bumped to `^10.0.0`.
58
+ - `eslint-plugin-mdx` bumped to `^3.8.1`. **ESLint 10 is not supported** —
59
+ `eslint-plugin-mdx` vendors an internal ESLint API removed in v10; ESLint 9
60
+ is pinned until a fix is released.
61
+ - `globals` added (`^15.0.0`) for `languageOptions.globals` in flat config.
62
+ - Shared config (`packages/elsie/config/eslint.mjs`) rewritten as a
63
+ flat-config array export.
64
+ - Per-package `.eslintrc.js` files deleted; replaced with `eslint.config.js`
65
+ (ESM flat config).
66
+ - Several `typescript-eslint` v8 rules disabled to preserve prior behavior:
67
+ `no-explicit-any`, `ban-ts-comment`, `no-unused-expressions`,
68
+ `no-unsafe-function-type`, `no-require-imports`, `no-empty-object-type`.
69
+ Tracked as tech debt.
70
+ - `reportUnusedDisableDirectives` disabled to avoid sweeping pre-existing
71
+ inline disable comments.
72
+
73
+ ### `vite-plugin-dts` removed; replaced with custom `dtsPlugin`
74
+
75
+ `vite-plugin-dts@3.9.1` declared a `typescript <5.0` peer range and its v5
76
+ successor was incompatible with this monorepo's layout (cross-package sources,
77
+ workspace symlinks, multi-`outDir`). It was removed and replaced with a thin
78
+ custom Vite plugin at `packages/elsie/config/plugins/dts.mjs` (`dtsPlugin`)
79
+ that runs `tsc` directly. The resulting `dist/` layout is identical to what
80
+ v3.9 produced (147 `.d.ts` files, 12 top-level entry shims).
81
+
82
+ ### Module format standardization
83
+
84
+ All tooling config files now follow a consistent format:
85
+
86
+ - **ESLint / Jest / Vite configs** — ESM (`.js` in `"type":"module"` packages;
87
+ `.mjs` in elsie).
88
+ - **Prettier** — JSON only (`@adobe-commerce/elsie/config/prettier.json`
89
+ referenced via each package's `"prettier"` key). `prettier.config.*` files
90
+ deleted from all packages.
91
+ - **elsie CLI** (`bin/**`) — intentionally stays CommonJS.
92
+
93
+ See `architecture/decisions/009-module-format.md` for the full convention.
94
+
95
+ ### `.elsie.js` → `.elsie.cjs`
96
+
97
+ The consumer project config file is renamed from `.elsie.js` to `.elsie.cjs`.
98
+ With `"type":"module"` now required in consumer packages, a plain `.js` file
99
+ is treated as ES module — making `module.exports` a SyntaxError and making
100
+ `require()` in the elsie CLI fail with `ERR_REQUIRE_ESM`. The `.cjs` extension
101
+ forces CommonJS regardless of the package's `"type"` field.
102
+
103
+ - `elsie generate config` now writes `.elsie.cjs`.
104
+ - The CLI (`bin/lib/config.js`) and `config/vite.mjs` both prefer `.elsie.cjs`
105
+ and fall back to `.elsie.js` for packages not yet migrated.
106
+ - `.elsie.cjs` added to `.npmignore` in all consumer packages.
107
+
108
+ ## Consumer migration
109
+
110
+ See `docs/elsie-v2-migration.md` for the full step-by-step guide. Key actions:
111
+
112
+ 1. Add `"type": "module"` to `package.json`.
113
+ 2. Replace `.eslintrc.js` with `eslint.config.js` (ESM flat config importing
114
+ from `@adobe-commerce/elsie/config/eslint.mjs`).
115
+ 3. Rename `.elsie.js` → `.elsie.cjs` (keep `module.exports` content as-is).
116
+ 4. Add `"prettier": "@adobe-commerce/elsie/config/prettier.json"` to
117
+ `package.json`; delete `prettier.config.js`.
118
+ 5. Update `tsconfig.json`: remove `baseUrl`, add explicit `rootDir` and
119
+ `types`.
120
+ 6. Add `tsconfig.build.json` for declaration emit (required by `dtsPlugin`).
121
+ 7. Convert `.elsie.js` imports in `.storybook/main.js` and
122
+ `storybook-stories.js` to reference `.elsie.cjs`.
123
+
124
+ ### Minor Changes
125
+
126
+ - c21a378: Add optional `cypress` export to shared ESLint config
127
+
128
+ `cypress` is a new named export from `@adobe-commerce/elsie/config/eslint.mjs`
129
+ that provides a pre-configured ESLint flat config for Cypress test files
130
+ (`cypress/**/*.js`). It applies `eslint-plugin-cypress`'s recommended rules
131
+ with `jest/expect-expect` turned off.
132
+
133
+ The plugin is declared as an optional peer dependency — `cypress` resolves to
134
+ an empty array when `eslint-plugin-cypress` is not installed, so projects that
135
+ don't use Cypress are unaffected.
136
+
137
+ ## Usage
138
+
139
+ Install the peer dependency in your project:
140
+
141
+ ```sh
142
+ yarn add -D eslint-plugin-cypress
143
+ ```
144
+
145
+ Then spread `cypress` into your ESLint config:
146
+
147
+ ```js
148
+ import base, {
149
+ sourceImportRestrictions,
150
+ cypress,
151
+ } from '@adobe-commerce/elsie/config/eslint.mjs';
152
+
153
+ export default [...base, ...cypress, ...sourceImportRestrictions];
154
+ ```
155
+
156
+ - 9d558ed: Adds `window.DROPINS.showOverlays(state)` — a developer utility that
157
+ visually outlines all dropin containers and slots on the page with labeled
158
+ overlays, making it easier to understand how the storefront is composed at
159
+ runtime.
160
+
161
+ `DROPINS.showSlots()` is deprecated in favor of `showOverlays()` and will log
162
+ a console warning when called.
163
+
164
+ - c25a5d7: feat(elsie): add `changeset` builder command
165
+
166
+ Adds `elsie changeset` as a first-class CLI command, wrapping
167
+ `@changesets/cli`. All subcommands pass through transparently (`status`,
168
+ `version`, `publish`, `--snapshot`, etc.). `@changesets/cli` is now a
169
+ dependency of elsie, so consumers no longer need to install it separately.
170
+
171
+ - 005edc7: Adds validation to the Incrementer component when the field is
172
+ changed to "empty".
173
+
174
+ ### Patch Changes
175
+
176
+ - bf352d2: Fix InputDate showing wrong format after selecting a date from the
177
+ calendar
178
+ - 4c3d82d: fix(field): associate error messages with inputs via aria-describedby
179
+ (WCAG 3.3.1)
180
+ - 36354d9: Add disableWhenSingle prop to Picker; defaults to true (preserves
181
+ existing behavior). Pass false to keep the picker interactive when only one
182
+ option is available.
183
+ - 09c2100: Declare `preact` as a runtime dependency. It previously sat in
184
+ `devDependencies` (unlike `@preact/signals` and `preact-i18n`), so standalone
185
+ consumers of `@adobe-commerce/elsie` had an unmet `preact` — also the unmet
186
+ peer of `@preact/preset-vite`, `@storybook/preact-vite` and
187
+ `@testing-library/preact`. It now resolves to the same `~10.22.1` bundled into
188
+ `@dropins/tools`. The emitted bundle is unchanged.
189
+ - 4641ab0: Fix `Field` and `InLineAlert` status/error messages not being
190
+ announced by screen readers. `Field`'s description/hint element now always
191
+ carries `role="status"` and `aria-live="polite"`, instead of only adding
192
+ `aria-live` once an error appeared, so assistive technology reliably announces
193
+ validation and success messages (WCAG 4.1.3). `InLineAlert` now sets
194
+ `role="alert"`/`aria-live="assertive"` for `type="error"` and
195
+ `role="status"`/`aria-live="polite"` for `success`/`warning`, since it
196
+ previously had no live-region semantics at all.
197
+ - ccada8c: Reset default margin on Header and CartItem titles to support
198
+ rendering them as semantic headings
199
+ - cb6eb81: Fix `InLineAlert` additional-action buttons announcing the same
200
+ accessible name across multiple alerts. Each entry in `additionalActions` may
201
+ now include an optional `'aria-label'` that is applied to the rendered button
202
+ (falling back to `label` when omitted), so consumers can give visually
203
+ identical "Undo"/"Dismiss" style buttons unique, descriptive names for
204
+ assistive technology.
205
+ - ab5cf32: Fix `Modal` accessibility: the dialog now exposes `role="dialog"`,
206
+ `aria-modal="true"`, and an `aria-labelledby` linked to its title. Focus moves
207
+ into the modal when it opens (falling back to the dialog body when there are
208
+ no focusable elements), Tab/Shift+Tab now cycles between the first and last
209
+ focusable elements instead of escaping the modal, and focus returns to the
210
+ previously focused element when the modal closes.
211
+ - 58da630: Fix `Picker` accessible name and label association. The `<select>`
212
+ now falls back to `floatingLabel` or `placeholder` for its `aria-label` when
213
+ no `name` is provided, and the floating `<label>` is now correctly associated
214
+ with the rendered `<select>` via its generated id instead of the raw `id`
215
+ prop.
216
+ - 450c408: fix(Picker): auto-select and emit the sole option when the control
217
+ auto-disables, so single-option narrowing on configurable PDPs no longer
218
+ leaves the value unselected and Add to Cart permanently disabled
219
+ - 33ebe8a: Add accessible labels to password validation and input status icons
220
+ (WCAG 1.1.1)
221
+ - 2ad7316: Fix `ToggleButton`'s underlying radio input announcing the shared
222
+ radio-group `name` (e.g. "payment-method") as its accessible name for every
223
+ option instead of the option's own visible label, which violates WCAG 2.4.6
224
+ (Headings and Labels) and 2.5.3 (Label in Name). The radio input's accessible
225
+ name now defaults to `aria-labelledby` pointing at the option's own visible
226
+ label content (e.g. "Check / Money order"), which works correctly whether
227
+ `label` is a string or a `VNode`. An optional `ariaLabel` prop is still
228
+ available for consumers who need to set an explicit accessible name via
229
+ `aria-label` instead.
230
+ - 256007e: Fix ToggleButton generating invalid HTML ids when value prop contains
231
+ spaces, breaking aria-labelledby label association
232
+ - 016a558: Fix low-contrast field label text in `Input` when a field is in an
233
+ error state. The floating label color now meets WCAG AA contrast requirements
234
+ for normal-size text against light backgrounds, matching the color already
235
+ used for error text elsewhere (helper text, alerts).
236
+ - 51fcb35: fix(a11y): darken low-contrast focus indicators to meet WCAG 1.4.11
237
+ (3:1 non-text contrast)
238
+
239
+ The default keyboard focus indicator across Button, IconButton, Checkbox,
240
+ RadioButton, ActionButton, ActionButtonGroup, ToggleButton, TextSwatch,
241
+ ColorSwatch, ImageSwatch, and links used `--color-neutral-400` (#d6d6d6,
242
+ ~1.45:1 against white), below the 3:1 minimum required by WCAG 1.4.11. These
243
+ focus indicators now use `--color-neutral-600` (#8f8f8f, ~3.2:1), so keyboard
244
+ users can reliably see which control is focused.
245
+
3
246
  ## 2.0.0-beta.1
4
247
 
5
248
  ### Patch Changes
6
249
 
7
- - 256007e: Fix ToggleButton generating invalid HTML ids when value prop contains spaces, breaking aria-labelledby label association
250
+ - 256007e: Fix ToggleButton generating invalid HTML ids when value prop contains
251
+ spaces, breaking aria-labelledby label association
8
252
 
9
253
  ## 2.0.0-beta.0
10
254
 
@@ -12,54 +256,89 @@
12
256
 
13
257
  - ea02d5f: Upgrade Jest to 30.4.2 and Storybook to 10.4.0
14
258
 
15
- Updated testing and component development tools to latest stable versions. Jest 30.4.2 provides enhanced snapshot handling and improved test performance. Storybook 10.4.0 includes updated addon ecosystem, improved Preact Vite integration, and enhanced accessibility features with addon-a11y and addon-coverage support.
259
+ Updated testing and component development tools to latest stable versions.
260
+ Jest 30.4.2 provides enhanced snapshot handling and improved test performance.
261
+ Storybook 10.4.0 includes updated addon ecosystem, improved Preact Vite
262
+ integration, and enhanced accessibility features with addon-a11y and
263
+ addon-coverage support.
16
264
 
17
265
  - 9cd299b: Upgrade TypeScript to 6.0 and ESLint to 9 (flat config)
18
266
 
19
267
  ## What changed
20
268
 
21
269
  ### TypeScript 4.7 → 6.0
22
-
23
- - `tsconfig-base.json` updated with correct TS 6 defaults. Two new-default opt-outs are deferred as tech debt: `exactOptionalPropertyTypes` and `verbatimModuleSyntax`.
24
- - `moduleResolution` changed from `"nodenext"` to `"bundler"` across all packages — the correct pairing for `module: "esnext"` in a Vite monorepo. Only `packages/elsie` keeps `"NodeNext"` (paired with `module: "NodeNext"` for its dual CJS/ESM output).
25
- - `baseUrl` removed from all tsconfigs (deprecated in TS 6; `paths` resolves relative to the tsconfig file directly).
26
- - `rootDir` added explicitly to `build-tools`, `event-bus`, `fetch-graphql`, and `recaptcha` tsconfigs (implicit `rootDir` deprecated in TS 6).
27
- - `types: []` set in `tsconfig-base.json` to prevent ambient test types from leaking into declaration output. Each package's own `tsconfig.json` declares its `types` explicitly (`jest`, `node`, `vite/client`, etc.).
28
- - `babel-plugin-tsconfig-paths` removed it was a no-op in every package that listed it.
29
- - `noUncheckedIndexedAccess` enabled violations were few enough to fix in source.
270
+ - `tsconfig-base.json` updated with correct TS 6 defaults. Two new-default
271
+ opt-outs are deferred as tech debt: `exactOptionalPropertyTypes` and
272
+ `verbatimModuleSyntax`.
273
+ - `moduleResolution` changed from `"nodenext"` to `"bundler"` across all
274
+ packages the correct pairing for `module: "esnext"` in a Vite monorepo.
275
+ Only `packages/elsie` keeps `"NodeNext"` (paired with `module: "NodeNext"`
276
+ for its dual CJS/ESM output).
277
+ - `baseUrl` removed from all tsconfigs (deprecated in TS 6; `paths` resolves
278
+ relative to the tsconfig file directly).
279
+ - `rootDir` added explicitly to `build-tools`, `event-bus`, `fetch-graphql`,
280
+ and `recaptcha` tsconfigs (implicit `rootDir` deprecated in TS 6).
281
+ - `types: []` set in `tsconfig-base.json` to prevent ambient test types from
282
+ leaking into declaration output. Each package's own `tsconfig.json` declares
283
+ its `types` explicitly (`jest`, `node`, `vite/client`, etc.).
284
+ - `babel-plugin-tsconfig-paths` removed — it was a no-op in every package that
285
+ listed it.
286
+ - `noUncheckedIndexedAccess` enabled — violations were few enough to fix in
287
+ source.
30
288
 
31
289
  ### ESLint 8 → 9 (flat config)
32
-
33
- - `@typescript-eslint/parser` and `@typescript-eslint/eslint-plugin` (v5) removed; replaced by the unified `typescript-eslint` v8 package.
290
+ - `@typescript-eslint/parser` and `@typescript-eslint/eslint-plugin` (v5)
291
+ removed; replaced by the unified `typescript-eslint` v8 package.
34
292
  - `eslint-config-preact` bumped to `^2.0.0` (ESLint 9 support).
35
293
  - `eslint-config-prettier` bumped to `^10.0.0`.
36
- - `eslint-plugin-mdx` bumped to `^3.8.1`. **ESLint 10 is not supported** — `eslint-plugin-mdx` vendors an internal ESLint API removed in v10; ESLint 9 is pinned until a fix is released.
294
+ - `eslint-plugin-mdx` bumped to `^3.8.1`. **ESLint 10 is not supported** —
295
+ `eslint-plugin-mdx` vendors an internal ESLint API removed in v10; ESLint 9
296
+ is pinned until a fix is released.
37
297
  - `globals` added (`^15.0.0`) for `languageOptions.globals` in flat config.
38
- - Shared config (`packages/elsie/config/eslint.mjs`) rewritten as a flat-config array export.
39
- - Per-package `.eslintrc.js` files deleted; replaced with `eslint.config.js` (ESM flat config).
40
- - Several `typescript-eslint` v8 rules disabled to preserve prior behavior: `no-explicit-any`, `ban-ts-comment`, `no-unused-expressions`, `no-unsafe-function-type`, `no-require-imports`, `no-empty-object-type`. Tracked as tech debt.
41
- - `reportUnusedDisableDirectives` disabled to avoid sweeping pre-existing inline disable comments.
298
+ - Shared config (`packages/elsie/config/eslint.mjs`) rewritten as a
299
+ flat-config array export.
300
+ - Per-package `.eslintrc.js` files deleted; replaced with `eslint.config.js`
301
+ (ESM flat config).
302
+ - Several `typescript-eslint` v8 rules disabled to preserve prior behavior:
303
+ `no-explicit-any`, `ban-ts-comment`, `no-unused-expressions`,
304
+ `no-unsafe-function-type`, `no-require-imports`, `no-empty-object-type`.
305
+ Tracked as tech debt.
306
+ - `reportUnusedDisableDirectives` disabled to avoid sweeping pre-existing
307
+ inline disable comments.
42
308
 
43
309
  ### `vite-plugin-dts` removed; replaced with custom `dtsPlugin`
44
310
 
45
- `vite-plugin-dts@3.9.1` declared a `typescript <5.0` peer range and its v5 successor was incompatible with this monorepo's layout (cross-package sources, workspace symlinks, multi-`outDir`). It was removed and replaced with a thin custom Vite plugin at `packages/elsie/config/plugins/dts.mjs` (`dtsPlugin`) that runs `tsc` directly. The resulting `dist/` layout is identical to what v3.9 produced (147 `.d.ts` files, 12 top-level entry shims).
311
+ `vite-plugin-dts@3.9.1` declared a `typescript <5.0` peer range and its v5
312
+ successor was incompatible with this monorepo's layout (cross-package sources,
313
+ workspace symlinks, multi-`outDir`). It was removed and replaced with a thin
314
+ custom Vite plugin at `packages/elsie/config/plugins/dts.mjs` (`dtsPlugin`)
315
+ that runs `tsc` directly. The resulting `dist/` layout is identical to what
316
+ v3.9 produced (147 `.d.ts` files, 12 top-level entry shims).
46
317
 
47
318
  ### Module format standardization
48
319
 
49
320
  All tooling config files now follow a consistent format:
50
321
 
51
- - **ESLint / Jest / Vite configs** — ESM (`.js` in `"type":"module"` packages; `.mjs` in elsie).
52
- - **Prettier** — JSON only (`@adobe-commerce/elsie/config/prettier.json` referenced via each package's `"prettier"` key). `prettier.config.*` files deleted from all packages.
322
+ - **ESLint / Jest / Vite configs** — ESM (`.js` in `"type":"module"` packages;
323
+ `.mjs` in elsie).
324
+ - **Prettier** — JSON only (`@adobe-commerce/elsie/config/prettier.json`
325
+ referenced via each package's `"prettier"` key). `prettier.config.*` files
326
+ deleted from all packages.
53
327
  - **elsie CLI** (`bin/**`) — intentionally stays CommonJS.
54
328
 
55
329
  See `architecture/decisions/009-module-format.md` for the full convention.
56
330
 
57
331
  ### `.elsie.js` → `.elsie.cjs`
58
332
 
59
- The consumer project config file is renamed from `.elsie.js` to `.elsie.cjs`. With `"type":"module"` now required in consumer packages, a plain `.js` file is treated as ES module — making `module.exports` a SyntaxError and making `require()` in the elsie CLI fail with `ERR_REQUIRE_ESM`. The `.cjs` extension forces CommonJS regardless of the package's `"type"` field.
333
+ The consumer project config file is renamed from `.elsie.js` to `.elsie.cjs`.
334
+ With `"type":"module"` now required in consumer packages, a plain `.js` file
335
+ is treated as ES module — making `module.exports` a SyntaxError and making
336
+ `require()` in the elsie CLI fail with `ERR_REQUIRE_ESM`. The `.cjs` extension
337
+ forces CommonJS regardless of the package's `"type"` field.
60
338
 
61
339
  - `elsie generate config` now writes `.elsie.cjs`.
62
- - The CLI (`bin/lib/config.js`) and `config/vite.mjs` both prefer `.elsie.cjs` and fall back to `.elsie.js` for packages not yet migrated.
340
+ - The CLI (`bin/lib/config.js`) and `config/vite.mjs` both prefer `.elsie.cjs`
341
+ and fall back to `.elsie.js` for packages not yet migrated.
63
342
  - `.elsie.cjs` added to `.npmignore` in all consumer packages.
64
343
 
65
344
  ## Consumer migration
@@ -67,20 +346,29 @@
67
346
  See `docs/elsie-v2-migration.md` for the full step-by-step guide. Key actions:
68
347
 
69
348
  1. Add `"type": "module"` to `package.json`.
70
- 2. Replace `.eslintrc.js` with `eslint.config.js` (ESM flat config importing from `@adobe-commerce/elsie/config/eslint.mjs`).
349
+ 2. Replace `.eslintrc.js` with `eslint.config.js` (ESM flat config importing
350
+ from `@adobe-commerce/elsie/config/eslint.mjs`).
71
351
  3. Rename `.elsie.js` → `.elsie.cjs` (keep `module.exports` content as-is).
72
- 4. Add `"prettier": "@adobe-commerce/elsie/config/prettier.json"` to `package.json`; delete `prettier.config.js`.
73
- 5. Update `tsconfig.json`: remove `baseUrl`, add explicit `rootDir` and `types`.
352
+ 4. Add `"prettier": "@adobe-commerce/elsie/config/prettier.json"` to
353
+ `package.json`; delete `prettier.config.js`.
354
+ 5. Update `tsconfig.json`: remove `baseUrl`, add explicit `rootDir` and
355
+ `types`.
74
356
  6. Add `tsconfig.build.json` for declaration emit (required by `dtsPlugin`).
75
- 7. Convert `.elsie.js` imports in `.storybook/main.js` and `storybook-stories.js` to reference `.elsie.cjs`.
357
+ 7. Convert `.elsie.js` imports in `.storybook/main.js` and
358
+ `storybook-stories.js` to reference `.elsie.cjs`.
76
359
 
77
360
  ### Minor Changes
78
361
 
79
362
  - c21a378: Add optional `cypress` export to shared ESLint config
80
363
 
81
- `cypress` is a new named export from `@adobe-commerce/elsie/config/eslint.mjs` that provides a pre-configured ESLint flat config for Cypress test files (`cypress/**/*.js`). It applies `eslint-plugin-cypress`'s recommended rules with `jest/expect-expect` turned off.
364
+ `cypress` is a new named export from `@adobe-commerce/elsie/config/eslint.mjs`
365
+ that provides a pre-configured ESLint flat config for Cypress test files
366
+ (`cypress/**/*.js`). It applies `eslint-plugin-cypress`'s recommended rules
367
+ with `jest/expect-expect` turned off.
82
368
 
83
- The plugin is declared as an optional peer dependency — `cypress` resolves to an empty array when `eslint-plugin-cypress` is not installed, so projects that don't use Cypress are unaffected.
369
+ The plugin is declared as an optional peer dependency — `cypress` resolves to
370
+ an empty array when `eslint-plugin-cypress` is not installed, so projects that
371
+ don't use Cypress are unaffected.
84
372
 
85
373
  ## Usage
86
374
 
@@ -101,34 +389,93 @@
101
389
  export default [...base, ...cypress, ...sourceImportRestrictions];
102
390
  ```
103
391
 
104
- - 9d558ed: Adds `window.DROPINS.showOverlays(state)` — a developer utility that visually outlines all dropin containers and slots on the page with labeled overlays, making it easier to understand how the storefront is composed at runtime.
392
+ - 9d558ed: Adds `window.DROPINS.showOverlays(state)` — a developer utility that
393
+ visually outlines all dropin containers and slots on the page with labeled
394
+ overlays, making it easier to understand how the storefront is composed at
395
+ runtime.
105
396
 
106
- `DROPINS.showSlots()` is deprecated in favor of `showOverlays()` and will log a console warning when called.
397
+ `DROPINS.showSlots()` is deprecated in favor of `showOverlays()` and will log
398
+ a console warning when called.
107
399
 
108
400
  - c25a5d7: feat(elsie): add `changeset` builder command
109
401
 
110
- Adds `elsie changeset` as a first-class CLI command, wrapping `@changesets/cli`. All subcommands pass through transparently (`status`, `version`, `publish`, `--snapshot`, etc.). `@changesets/cli` is now a dependency of elsie, so consumers no longer need to install it separately.
402
+ Adds `elsie changeset` as a first-class CLI command, wrapping
403
+ `@changesets/cli`. All subcommands pass through transparently (`status`,
404
+ `version`, `publish`, `--snapshot`, etc.). `@changesets/cli` is now a
405
+ dependency of elsie, so consumers no longer need to install it separately.
111
406
 
112
- - 005edc7: Adds validation to the Incrementer component when the field is changed to "empty".
407
+ - 005edc7: Adds validation to the Incrementer component when the field is
408
+ changed to "empty".
113
409
 
114
410
  ### Patch Changes
115
411
 
116
- - bf352d2: Fix InputDate showing wrong format after selecting a date from the calendar
117
- - 4c3d82d: fix(field): associate error messages with inputs via aria-describedby (WCAG 3.3.1)
118
- - 36354d9: Add disableWhenSingle prop to Picker; defaults to true (preserves existing behavior). Pass false to keep the picker interactive when only one option is available.
119
- - 09c2100: Declare `preact` as a runtime dependency. It previously sat in `devDependencies` (unlike `@preact/signals` and `preact-i18n`), so standalone consumers of `@adobe-commerce/elsie` had an unmet `preact` — also the unmet peer of `@preact/preset-vite`, `@storybook/preact-vite` and `@testing-library/preact`. It now resolves to the same `~10.22.1` bundled into `@dropins/tools`. The emitted bundle is unchanged.
120
- - 4641ab0: Fix `Field` and `InLineAlert` status/error messages not being announced by screen readers. `Field`'s description/hint element now always carries `role="status"` and `aria-live="polite"`, instead of only adding `aria-live` once an error appeared, so assistive technology reliably announces validation and success messages (WCAG 4.1.3). `InLineAlert` now sets `role="alert"`/`aria-live="assertive"` for `type="error"` and `role="status"`/`aria-live="polite"` for `success`/`warning`, since it previously had no live-region semantics at all.
121
- - ccada8c: Reset default margin on Header and CartItem titles to support rendering them as semantic headings
122
- - cb6eb81: Fix `InLineAlert` additional-action buttons announcing the same accessible name across multiple alerts. Each entry in `additionalActions` may now include an optional `'aria-label'` that is applied to the rendered button (falling back to `label` when omitted), so consumers can give visually identical "Undo"/"Dismiss" style buttons unique, descriptive names for assistive technology.
123
- - ab5cf32: Fix `Modal` accessibility: the dialog now exposes `role="dialog"`, `aria-modal="true"`, and an `aria-labelledby` linked to its title. Focus moves into the modal when it opens (falling back to the dialog body when there are no focusable elements), Tab/Shift+Tab now cycles between the first and last focusable elements instead of escaping the modal, and focus returns to the previously focused element when the modal closes.
124
- - 58da630: Fix `Picker` accessible name and label association. The `<select>` now falls back to `floatingLabel` or `placeholder` for its `aria-label` when no `name` is provided, and the floating `<label>` is now correctly associated with the rendered `<select>` via its generated id instead of the raw `id` prop.
125
- - 450c408: fix(Picker): auto-select and emit the sole option when the control auto-disables, so single-option narrowing on configurable PDPs no longer leaves the value unselected and Add to Cart permanently disabled
126
- - 33ebe8a: Add accessible labels to password validation and input status icons (WCAG 1.1.1)
127
- - 2ad7316: Fix `ToggleButton`'s underlying radio input announcing the shared radio-group `name` (e.g. "payment-method") as its accessible name for every option instead of the option's own visible label, which violates WCAG 2.4.6 (Headings and Labels) and 2.5.3 (Label in Name). The radio input's accessible name now defaults to `aria-labelledby` pointing at the option's own visible label content (e.g. "Check / Money order"), which works correctly whether `label` is a string or a `VNode`. An optional `ariaLabel` prop is still available for consumers who need to set an explicit accessible name via `aria-label` instead.
128
- - 016a558: Fix low-contrast field label text in `Input` when a field is in an error state. The floating label color now meets WCAG AA contrast requirements for normal-size text against light backgrounds, matching the color already used for error text elsewhere (helper text, alerts).
129
- - 51fcb35: fix(a11y): darken low-contrast focus indicators to meet WCAG 1.4.11 (3:1 non-text contrast)
130
-
131
- The default keyboard focus indicator across Button, IconButton, Checkbox, RadioButton, ActionButton, ActionButtonGroup, ToggleButton, TextSwatch, ColorSwatch, ImageSwatch, and links used `--color-neutral-400` (#d6d6d6, ~1.45:1 against white), below the 3:1 minimum required by WCAG 1.4.11. These focus indicators now use `--color-neutral-600` (#8f8f8f, ~3.2:1), so keyboard users can reliably see which control is focused.
412
+ - bf352d2: Fix InputDate showing wrong format after selecting a date from the
413
+ calendar
414
+ - 4c3d82d: fix(field): associate error messages with inputs via aria-describedby
415
+ (WCAG 3.3.1)
416
+ - 36354d9: Add disableWhenSingle prop to Picker; defaults to true (preserves
417
+ existing behavior). Pass false to keep the picker interactive when only one
418
+ option is available.
419
+ - 09c2100: Declare `preact` as a runtime dependency. It previously sat in
420
+ `devDependencies` (unlike `@preact/signals` and `preact-i18n`), so standalone
421
+ consumers of `@adobe-commerce/elsie` had an unmet `preact` also the unmet
422
+ peer of `@preact/preset-vite`, `@storybook/preact-vite` and
423
+ `@testing-library/preact`. It now resolves to the same `~10.22.1` bundled into
424
+ `@dropins/tools`. The emitted bundle is unchanged.
425
+ - 4641ab0: Fix `Field` and `InLineAlert` status/error messages not being
426
+ announced by screen readers. `Field`'s description/hint element now always
427
+ carries `role="status"` and `aria-live="polite"`, instead of only adding
428
+ `aria-live` once an error appeared, so assistive technology reliably announces
429
+ validation and success messages (WCAG 4.1.3). `InLineAlert` now sets
430
+ `role="alert"`/`aria-live="assertive"` for `type="error"` and
431
+ `role="status"`/`aria-live="polite"` for `success`/`warning`, since it
432
+ previously had no live-region semantics at all.
433
+ - ccada8c: Reset default margin on Header and CartItem titles to support
434
+ rendering them as semantic headings
435
+ - cb6eb81: Fix `InLineAlert` additional-action buttons announcing the same
436
+ accessible name across multiple alerts. Each entry in `additionalActions` may
437
+ now include an optional `'aria-label'` that is applied to the rendered button
438
+ (falling back to `label` when omitted), so consumers can give visually
439
+ identical "Undo"/"Dismiss" style buttons unique, descriptive names for
440
+ assistive technology.
441
+ - ab5cf32: Fix `Modal` accessibility: the dialog now exposes `role="dialog"`,
442
+ `aria-modal="true"`, and an `aria-labelledby` linked to its title. Focus moves
443
+ into the modal when it opens (falling back to the dialog body when there are
444
+ no focusable elements), Tab/Shift+Tab now cycles between the first and last
445
+ focusable elements instead of escaping the modal, and focus returns to the
446
+ previously focused element when the modal closes.
447
+ - 58da630: Fix `Picker` accessible name and label association. The `<select>`
448
+ now falls back to `floatingLabel` or `placeholder` for its `aria-label` when
449
+ no `name` is provided, and the floating `<label>` is now correctly associated
450
+ with the rendered `<select>` via its generated id instead of the raw `id`
451
+ prop.
452
+ - 450c408: fix(Picker): auto-select and emit the sole option when the control
453
+ auto-disables, so single-option narrowing on configurable PDPs no longer
454
+ leaves the value unselected and Add to Cart permanently disabled
455
+ - 33ebe8a: Add accessible labels to password validation and input status icons
456
+ (WCAG 1.1.1)
457
+ - 2ad7316: Fix `ToggleButton`'s underlying radio input announcing the shared
458
+ radio-group `name` (e.g. "payment-method") as its accessible name for every
459
+ option instead of the option's own visible label, which violates WCAG 2.4.6
460
+ (Headings and Labels) and 2.5.3 (Label in Name). The radio input's accessible
461
+ name now defaults to `aria-labelledby` pointing at the option's own visible
462
+ label content (e.g. "Check / Money order"), which works correctly whether
463
+ `label` is a string or a `VNode`. An optional `ariaLabel` prop is still
464
+ available for consumers who need to set an explicit accessible name via
465
+ `aria-label` instead.
466
+ - 016a558: Fix low-contrast field label text in `Input` when a field is in an
467
+ error state. The floating label color now meets WCAG AA contrast requirements
468
+ for normal-size text against light backgrounds, matching the color already
469
+ used for error text elsewhere (helper text, alerts).
470
+ - 51fcb35: fix(a11y): darken low-contrast focus indicators to meet WCAG 1.4.11
471
+ (3:1 non-text contrast)
472
+
473
+ The default keyboard focus indicator across Button, IconButton, Checkbox,
474
+ RadioButton, ActionButton, ActionButtonGroup, ToggleButton, TextSwatch,
475
+ ColorSwatch, ImageSwatch, and links used `--color-neutral-400` (#d6d6d6,
476
+ ~1.45:1 against white), below the 3:1 minimum required by WCAG 1.4.11. These
477
+ focus indicators now use `--color-neutral-600` (#8f8f8f, ~3.2:1), so keyboard
478
+ users can reliably see which control is focused.
132
479
 
133
480
  ## 1.9.0
134
481
 
@@ -136,28 +483,59 @@
136
483
 
137
484
  - af62897: Update minimum Node.js requirement to 22 LTS
138
485
 
139
- Packages are now built with Node.js 22. `elsie` requires `>=22`; browser-only packages (`fetch-graphql`, `event-bus`, `recaptcha`, `storefront-design`, `build-tools`) do not declare an `engines` field as they do not run in Node.js.
486
+ Packages are now built with Node.js 22. `elsie` requires `>=22`; browser-only
487
+ packages (`fetch-graphql`, `event-bus`, `recaptcha`, `storefront-design`,
488
+ `build-tools`) do not declare an `engines` field as they do not run in
489
+ Node.js.
140
490
 
141
- - 62adf1c: Reduce HTTP requests on page load through three bundling optimizations. The preact runtime is isolated in its own vendor chunk so it no longer co-locates into other chunks. Dropin API and internal component modules are consolidated into `chunks/api.js` and `chunks/components.js` respectively, replacing the previous pattern of one chunk file per function or component. All SVG icons are consolidated into a single `chunks/icons.js` chunk instead of one chunk per icon.
491
+ - 62adf1c: Reduce HTTP requests on page load through three bundling
492
+ optimizations. The preact runtime is isolated in its own vendor chunk so it no
493
+ longer co-locates into other chunks. Dropin API and internal component modules
494
+ are consolidated into `chunks/api.js` and `chunks/components.js` respectively,
495
+ replacing the previous pattern of one chunk file per function or component.
496
+ All SVG icons are consolidated into a single `chunks/icons.js` chunk instead
497
+ of one chunk per icon.
142
498
 
143
- Drop-ins must be rebuilt against this release to get the reduced request footprint. No source changes are required.
499
+ Drop-ins must be rebuilt against this release to get the reduced request
500
+ footprint. No source changes are required.
144
501
 
145
502
  ### Patch Changes
146
503
 
147
- - d2aacc7: Fix: GraphQL fragment source files are no longer incorrectly bundled into `chunks/api.js`. The `manualChunks` function now walks the full importer graph (with cycle protection) to determine whether an api-directory module is owned by the fragments barrel, so fragment files stay in the fragments output chunk even when accessed through intermediate sub-barrels.
148
- - 5c64620: Implement a new `fragment-import-redirect` build plugin that automatically detects and redirects any dropin source file that directly imports a fragment source file (bypassing the barrel). The import is silently redirected to the fragments barrel at build time and a warning is emitted identifying the file so it can be corrected in source. This ensures fragment constants always appear as local declarations in `fragments.js` regardless of how dropin source code references them.
504
+ - d2aacc7: Fix: GraphQL fragment source files are no longer incorrectly bundled
505
+ into `chunks/api.js`. The `manualChunks` function now walks the full importer
506
+ graph (with cycle protection) to determine whether an api-directory module is
507
+ owned by the fragments barrel, so fragment files stay in the fragments output
508
+ chunk even when accessed through intermediate sub-barrels.
509
+ - 5c64620: Implement a new `fragment-import-redirect` build plugin that
510
+ automatically detects and redirects any dropin source file that directly
511
+ imports a fragment source file (bypassing the barrel). The import is silently
512
+ redirected to the fragments barrel at build time and a warning is emitted
513
+ identifying the file so it can be corrected in source. This ensures fragment
514
+ constants always appear as local declarations in `fragments.js` regardless of
515
+ how dropin source code references them.
149
516
 
150
517
  ## 1.9.0-beta.3
151
518
 
152
519
  ### Patch Changes
153
520
 
154
- - 5c64620: Implement a new `fragment-import-redirect` build plugin that automatically detects and redirects any dropin source file that directly imports a fragment source file (bypassing the barrel). The import is silently redirected to the fragments barrel at build time and a warning is emitted identifying the file so it can be corrected in source. This ensures fragment constants always appear as local declarations in `fragments.js` regardless of how dropin source code references them.
521
+ - 5c64620: Implement a new `fragment-import-redirect` build plugin that
522
+ automatically detects and redirects any dropin source file that directly
523
+ imports a fragment source file (bypassing the barrel). The import is silently
524
+ redirected to the fragments barrel at build time and a warning is emitted
525
+ identifying the file so it can be corrected in source. This ensures fragment
526
+ constants always appear as local declarations in `fragments.js` regardless of
527
+ how dropin source code references them.
155
528
 
156
529
  ## 1.9.0-beta.2
157
530
 
158
531
  ### Patch Changes
159
532
 
160
- - d2aacc7: Fix: GraphQL fragment source files are no longer incorrectly bundled into `chunks/api.js`. The `manualChunks` function now walks the full importer graph (with cycle protection) to determine whether an api-directory module is owned by the fragments barrel, so fragment files stay in the fragments output chunk even when accessed through intermediate sub-barrels. Boilerplate GraphQL overrides work correctly in all dropin barrel structures.
533
+ - d2aacc7: Fix: GraphQL fragment source files are no longer incorrectly bundled
534
+ into `chunks/api.js`. The `manualChunks` function now walks the full importer
535
+ graph (with cycle protection) to determine whether an api-directory module is
536
+ owned by the fragments barrel, so fragment files stay in the fragments output
537
+ chunk even when accessed through intermediate sub-barrels. Boilerplate GraphQL
538
+ overrides work correctly in all dropin barrel structures.
161
539
 
162
540
  ## 1.9.0-beta.1
163
541
 
@@ -165,35 +543,53 @@
165
543
 
166
544
  - af62897: Update minimum Node.js requirement to 22 LTS
167
545
 
168
- Packages are now built with Node.js 22. `elsie` requires `>=22`; browser-only packages (`fetch-graphql`, `event-bus`, `recaptcha`, `storefront-design`, `build-tools`) do not declare an `engines` field as they do not run in Node.js.
546
+ Packages are now built with Node.js 22. `elsie` requires `>=22`; browser-only
547
+ packages (`fetch-graphql`, `event-bus`, `recaptcha`, `storefront-design`,
548
+ `build-tools`) do not declare an `engines` field as they do not run in
549
+ Node.js.
169
550
 
170
551
  ## 1.9.0-beta.0
171
552
 
172
553
  ### Minor Changes
173
554
 
174
- - 62adf1c: Reduce HTTP requests on page load through three bundling optimizations. The preact runtime is isolated in its own vendor chunk so it no longer co-locates into other chunks. Dropin API and internal component modules are consolidated into `chunks/api.js` and `chunks/components.js` respectively, replacing the previous pattern of one chunk file per function or component. All SVG icons are consolidated into a single `chunks/icons.js` chunk instead of one chunk per icon.
555
+ - 62adf1c: Reduce HTTP requests on page load through three bundling
556
+ optimizations. The preact runtime is isolated in its own vendor chunk so it no
557
+ longer co-locates into other chunks. Dropin API and internal component modules
558
+ are consolidated into `chunks/api.js` and `chunks/components.js` respectively,
559
+ replacing the previous pattern of one chunk file per function or component.
560
+ All SVG icons are consolidated into a single `chunks/icons.js` chunk instead
561
+ of one chunk per icon.
175
562
 
176
- Drop-ins must be rebuilt against this release to get the reduced request footprint. No source changes are required.
563
+ Drop-ins must be rebuilt against this release to get the reduced request
564
+ footprint. No source changes are required.
177
565
 
178
566
  ## 1.8.1
179
567
 
180
568
  ### Patch Changes
181
569
 
182
- - e44f618: Fixed `srcset w` descriptors to use actual image widths instead of viewport breakpoints, preventing blurry product images.
183
- - 46d57ca: Add optional `sizes` prop to the `Image` component so dropins can provide layout-aware sizing hints for more accurate srcset image source selection.
570
+ - e44f618: Fixed `srcset w` descriptors to use actual image widths instead of
571
+ viewport breakpoints, preventing blurry product images.
572
+ - 46d57ca: Add optional `sizes` prop to the `Image` component so dropins can
573
+ provide layout-aware sizing hints for more accurate srcset image source
574
+ selection.
184
575
 
185
576
  ## 1.8.1-beta.0
186
577
 
187
578
  ### Patch Changes
188
579
 
189
- - e44f618: Fixed `srcset w` descriptors to use actual image widths instead of viewport breakpoints, preventing blurry product images.
190
- - 46d57ca: Add optional `sizes` prop to the `Image` component so dropins can provide layout-aware sizing hints for more accurate srcset image source selection.
580
+ - e44f618: Fixed `srcset w` descriptors to use actual image widths instead of
581
+ viewport breakpoints, preventing blurry product images.
582
+ - 46d57ca: Add optional `sizes` prop to the `Image` component so dropins can
583
+ provide layout-aware sizing hints for more accurate srcset image source
584
+ selection.
191
585
 
192
586
  ## 1.8.0
193
587
 
194
588
  ### Minor Changes
195
589
 
196
- - c4da094: Enhance the Vite build process to automatically generate a package.json file and include both the LICENSE and CHANGELOG files in the dist directory.
590
+ - c4da094: Enhance the Vite build process to automatically generate a
591
+ package.json file and include both the LICENSE and CHANGELOG files in the dist
592
+ directory.
197
593
 
198
594
  ### Patch Changes
199
595
 
@@ -209,4 +605,6 @@
209
605
 
210
606
  ### Minor Changes
211
607
 
212
- - c4da094: Enhance the Vite build process to automatically generate a package.json file and include both the LICENSE and CHANGELOG files in the dist directory.
608
+ - c4da094: Enhance the Vite build process to automatically generate a
609
+ package.json file and include both the LICENSE and CHANGELOG files in the dist
610
+ directory.