@adobe-commerce/elsie 1.9.0-beta.3 → 1.9.1-alpha-20260702101934
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 +23 -4
- package/package.json +6 -6
- package/src/components/Picker/Picker.tsx +40 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# @adobe-commerce/elsie
|
|
2
2
|
|
|
3
|
+
## 1.9.1-alpha-20260702101934
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- fa16e7d: 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
|
|
8
|
+
|
|
9
|
+
## 1.9.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- af62897: Update minimum Node.js requirement to 22 LTS
|
|
14
|
+
|
|
15
|
+
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.
|
|
16
|
+
|
|
17
|
+
- 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.
|
|
18
|
+
|
|
19
|
+
Drop-ins must be rebuilt against this release to get the reduced request footprint. No source changes are required.
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- 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.
|
|
24
|
+
- 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.
|
|
25
|
+
|
|
3
26
|
## 1.9.0-beta.3
|
|
4
27
|
|
|
5
28
|
### Patch Changes
|
|
@@ -24,10 +47,6 @@
|
|
|
24
47
|
|
|
25
48
|
### Minor Changes
|
|
26
49
|
|
|
27
|
-
- f55a79c: Migrate to Node.js 24 LTS
|
|
28
|
-
|
|
29
|
-
Minimum required Node.js version is now 24. Updated `engines.node` from `>=16`/`>=18` to `>=24` across all packages. Regenerated lockfile under Node 24. Updated CI workflows to use `storefront-workflows@v6` with Node 24 support.
|
|
30
|
-
|
|
31
50
|
- 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.
|
|
32
51
|
|
|
33
52
|
Drop-ins must be rebuilt against this release to get the reduced request footprint. No source changes are required.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adobe-commerce/elsie",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.1-alpha-20260702101934",
|
|
4
4
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
5
5
|
"description": "Domain Package SDK",
|
|
6
6
|
"engines": {
|
|
@@ -28,11 +28,11 @@
|
|
|
28
28
|
"postpublish": "node ./scripts/publish-tools.mjs"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
|
-
"@adobe-commerce/event-bus": "~1.1.0
|
|
32
|
-
"@adobe-commerce/fetch-graphql": "~1.3.0
|
|
33
|
-
"@adobe-commerce/recaptcha": "1.2.0
|
|
34
|
-
"@adobe-commerce/storefront-design": "~1.1.0
|
|
35
|
-
"@dropins/build-tools": "~1.2.0
|
|
31
|
+
"@adobe-commerce/event-bus": "~1.1.0",
|
|
32
|
+
"@adobe-commerce/fetch-graphql": "~1.3.0",
|
|
33
|
+
"@adobe-commerce/recaptcha": "1.2.0",
|
|
34
|
+
"@adobe-commerce/storefront-design": "~1.1.0",
|
|
35
|
+
"@dropins/build-tools": "~1.2.0",
|
|
36
36
|
"preact": "~10.22.1",
|
|
37
37
|
"vite-plugin-banner": "^0.8.0"
|
|
38
38
|
},
|
|
@@ -11,7 +11,7 @@ import { Icon } from '@adobe-commerce/elsie/components';
|
|
|
11
11
|
import { ChevronDown } from '@adobe-commerce/elsie/icons';
|
|
12
12
|
import { classes } from '@adobe-commerce/elsie/lib';
|
|
13
13
|
import { FunctionComponent, VNode } from 'preact';
|
|
14
|
-
import { HTMLAttributes, useEffect, useState } from 'preact/compat';
|
|
14
|
+
import { HTMLAttributes, useEffect, useRef, useState } from 'preact/compat';
|
|
15
15
|
|
|
16
16
|
import '@adobe-commerce/elsie/components/Picker/Picker.css';
|
|
17
17
|
|
|
@@ -46,10 +46,13 @@ function findSelectedValue(
|
|
|
46
46
|
defaultOption?: PickerOption,
|
|
47
47
|
placeholder?: string,
|
|
48
48
|
floatingLabel?: string,
|
|
49
|
-
firstAvailableOption?: PickerOption
|
|
49
|
+
firstAvailableOption?: PickerOption,
|
|
50
|
+
singleOption?: PickerOption
|
|
50
51
|
) {
|
|
51
52
|
if (value) return value;
|
|
52
53
|
if (defaultOption) return defaultOption.value;
|
|
54
|
+
// sole option wins over the placeholder so it stays selected, not blank
|
|
55
|
+
if (singleOption) return singleOption.value;
|
|
53
56
|
if (placeholder || floatingLabel) return '';
|
|
54
57
|
if (firstAvailableOption) return firstAvailableOption.value;
|
|
55
58
|
return null;
|
|
@@ -75,17 +78,26 @@ export const Picker: FunctionComponent<PickerProps> = ({
|
|
|
75
78
|
const uniqueId = id ?? name ?? `dropin-picker-${Math.random().toString(36)}`;
|
|
76
79
|
const isRequired = !!props?.required;
|
|
77
80
|
const isDisabled = disabled || options?.length === 1;
|
|
81
|
+
const selectRef = useRef<HTMLSelectElement>(null);
|
|
78
82
|
|
|
79
83
|
// find the first option that is not disabled
|
|
80
84
|
const firstAvailableOption = options?.find((option) => !option.disabled);
|
|
81
85
|
|
|
86
|
+
// the only selectable option when the picker auto-disables; a disabled
|
|
87
|
+
// <select> never fires change, so we must emit it ourselves (see below)
|
|
88
|
+
const singleOption =
|
|
89
|
+
!disabled && options?.length === 1 && !options[0]?.disabled
|
|
90
|
+
? options[0]
|
|
91
|
+
: undefined;
|
|
92
|
+
|
|
82
93
|
const [selectedValue, setSelectedValue] = useState<PickerValue>(() => {
|
|
83
94
|
return findSelectedValue(
|
|
84
95
|
value,
|
|
85
96
|
defaultOption,
|
|
86
97
|
placeholder,
|
|
87
98
|
floatingLabel,
|
|
88
|
-
firstAvailableOption
|
|
99
|
+
firstAvailableOption,
|
|
100
|
+
singleOption
|
|
89
101
|
);
|
|
90
102
|
});
|
|
91
103
|
|
|
@@ -96,10 +108,32 @@ export const Picker: FunctionComponent<PickerProps> = ({
|
|
|
96
108
|
defaultOption,
|
|
97
109
|
placeholder,
|
|
98
110
|
floatingLabel,
|
|
99
|
-
firstAvailableOption
|
|
111
|
+
firstAvailableOption,
|
|
112
|
+
singleOption
|
|
100
113
|
)
|
|
101
114
|
);
|
|
102
|
-
}, [
|
|
115
|
+
}, [
|
|
116
|
+
value,
|
|
117
|
+
defaultOption,
|
|
118
|
+
placeholder,
|
|
119
|
+
floatingLabel,
|
|
120
|
+
firstAvailableOption,
|
|
121
|
+
singleOption,
|
|
122
|
+
]);
|
|
123
|
+
|
|
124
|
+
// commit the sole option to the consumer; skip once value has come back in.
|
|
125
|
+
// dispatch a real change event so handleOptionClick emits it: consumers get
|
|
126
|
+
// a genuine Event (some call preventDefault) identical to a user selection.
|
|
127
|
+
useEffect(() => {
|
|
128
|
+
if (!singleOption || value === singleOption.value) return;
|
|
129
|
+
|
|
130
|
+
const select = selectRef.current;
|
|
131
|
+
if (!select) return;
|
|
132
|
+
|
|
133
|
+
select.value = singleOption.value as string;
|
|
134
|
+
select.dispatchEvent(new Event('change', { bubbles: true }));
|
|
135
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
136
|
+
}, [singleOption?.value, value]);
|
|
103
137
|
|
|
104
138
|
const handleOptionClick = (event: Event) => {
|
|
105
139
|
const { options, value } = event.target as HTMLSelectElement;
|
|
@@ -157,6 +191,7 @@ export const Picker: FunctionComponent<PickerProps> = ({
|
|
|
157
191
|
)}
|
|
158
192
|
|
|
159
193
|
<select
|
|
194
|
+
ref={selectRef}
|
|
160
195
|
id={uniqueId}
|
|
161
196
|
className={classes([
|
|
162
197
|
'dropin-picker__select',
|