@adobe-commerce/elsie 1.5.0-alpha100 → 1.5.0-alpha2
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/package.json
CHANGED
|
@@ -8,12 +8,13 @@
|
|
|
8
8
|
*******************************************************************/
|
|
9
9
|
|
|
10
10
|
import { Icon } from '@adobe-commerce/elsie/components';
|
|
11
|
-
import '@adobe-commerce/elsie/components/Picker/Picker.css';
|
|
12
11
|
import { ChevronDown } from '@adobe-commerce/elsie/icons';
|
|
13
12
|
import { classes } from '@adobe-commerce/elsie/lib';
|
|
14
13
|
import { FunctionComponent, VNode } from 'preact';
|
|
15
14
|
import { HTMLAttributes, useEffect, useState } from 'preact/compat';
|
|
16
15
|
|
|
16
|
+
import '@adobe-commerce/elsie/components/Picker/Picker.css';
|
|
17
|
+
|
|
17
18
|
type PickerValue = string | null;
|
|
18
19
|
|
|
19
20
|
export interface PickerOption {
|
|
@@ -68,9 +69,10 @@ export const Picker: FunctionComponent<PickerProps> = ({
|
|
|
68
69
|
defaultOption,
|
|
69
70
|
icon,
|
|
70
71
|
className,
|
|
72
|
+
id,
|
|
71
73
|
...props
|
|
72
74
|
}) => {
|
|
73
|
-
const
|
|
75
|
+
const uniqueId = id ?? name ?? `dropin-picker-${Math.random().toString(36)}`;
|
|
74
76
|
const isRequired = !!props?.required;
|
|
75
77
|
|
|
76
78
|
// find the first option that is not disabled
|
|
@@ -154,7 +156,7 @@ export const Picker: FunctionComponent<PickerProps> = ({
|
|
|
154
156
|
)}
|
|
155
157
|
|
|
156
158
|
<select
|
|
157
|
-
id={
|
|
159
|
+
id={uniqueId}
|
|
158
160
|
className={classes([
|
|
159
161
|
'dropin-picker__select',
|
|
160
162
|
`dropin-picker__select--${variant}`,
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
useEffect,
|
|
15
15
|
useRef,
|
|
16
16
|
useCallback,
|
|
17
|
+
useMemo,
|
|
17
18
|
} from 'preact/compat';
|
|
18
19
|
import { classes } from '@adobe-commerce/elsie/lib';
|
|
19
20
|
import '@adobe-commerce/elsie/components/TextSwatch/TextSwatch.css';
|
|
@@ -93,6 +94,8 @@ export const TextSwatch: FunctionComponent<TextSwatchProps> = ({
|
|
|
93
94
|
}
|
|
94
95
|
}, [label]);
|
|
95
96
|
|
|
97
|
+
const uniqueId = useMemo(() => id ?? `${name}_${id}_${Math.random().toString(36)}`, [name, id]);
|
|
98
|
+
|
|
96
99
|
return (
|
|
97
100
|
<div
|
|
98
101
|
className="dropin-text-swatch__container"
|
|
@@ -101,7 +104,7 @@ export const TextSwatch: FunctionComponent<TextSwatchProps> = ({
|
|
|
101
104
|
<input
|
|
102
105
|
type={multi ? 'checkbox' : 'radio'}
|
|
103
106
|
name={name}
|
|
104
|
-
id={
|
|
107
|
+
id={uniqueId}
|
|
105
108
|
value={value}
|
|
106
109
|
aria-label={handleAriaLabel()}
|
|
107
110
|
checked={selected}
|
|
@@ -116,7 +119,7 @@ export const TextSwatch: FunctionComponent<TextSwatchProps> = ({
|
|
|
116
119
|
])}
|
|
117
120
|
/>
|
|
118
121
|
<label
|
|
119
|
-
htmlFor={
|
|
122
|
+
htmlFor={uniqueId}
|
|
120
123
|
ref={spanRef}
|
|
121
124
|
className={classes([
|
|
122
125
|
'dropin-text-swatch__label',
|
package/src/docs/API/render.mdx
CHANGED
|
@@ -121,5 +121,21 @@ button.addEventListener('click', () => {
|
|
|
121
121
|
});
|
|
122
122
|
```
|
|
123
123
|
|
|
124
|
+
### Unmounting components without instance access
|
|
125
|
+
|
|
126
|
+
The `Render.unmount` static method provides a way to unmount components from the DOM when you don't have direct access to the component instance.
|
|
127
|
+
This is particularly useful in scenarios where components are rendered inside modals, dialogs, or other temporary containers that need to be cleaned up.
|
|
128
|
+
|
|
129
|
+
#### Example
|
|
130
|
+
|
|
131
|
+
```js
|
|
132
|
+
// Close the dialog
|
|
133
|
+
dialog.close();
|
|
134
|
+
|
|
135
|
+
// Unmount any dropin containers rendered in the modal
|
|
136
|
+
dialog.querySelectorAll('[data-dropin-container]').forEach(Render.unmount);
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
This approach ensures that all dropin components are properly cleaned up when their container elements are removed from the DOM, preventing memory leaks and maintaining application performance.
|
|
124
140
|
</Unstyled>
|
|
125
141
|
|
package/src/lib/aem/configs.ts
CHANGED
|
@@ -40,7 +40,7 @@ function resetConfig() {
|
|
|
40
40
|
* @param {Object} [configObj=config] - The config object.
|
|
41
41
|
* @returns {string} - The root path.
|
|
42
42
|
*/
|
|
43
|
-
function getRootPath(configObj: Config | null = config
|
|
43
|
+
function getRootPath(configObj: Config | null = config): string {
|
|
44
44
|
if (!configObj) {
|
|
45
45
|
console.warn('No config found. Please call initializeConfig() first.');
|
|
46
46
|
return '/';
|
|
@@ -56,7 +56,7 @@ function getRootPath(configObj: Config | null = config, options: { match?: (key:
|
|
|
56
56
|
.find(
|
|
57
57
|
(key) =>
|
|
58
58
|
window.location.pathname === key ||
|
|
59
|
-
|
|
59
|
+
window.location.pathname.startsWith(key)
|
|
60
60
|
);
|
|
61
61
|
|
|
62
62
|
return value ?? '/';
|
|
@@ -126,14 +126,11 @@ function applyConfigOverrides(
|
|
|
126
126
|
|
|
127
127
|
/**
|
|
128
128
|
* Initializes the configuration system.
|
|
129
|
-
* @param {Object} configObj - The config object.
|
|
130
|
-
* @param {Object} [options] - The options object.
|
|
131
|
-
* @param {Function} [options.match] - The function to match the path to the config.
|
|
132
129
|
* @returns {Object} The initialized root configuration
|
|
133
130
|
*/
|
|
134
|
-
function initializeConfig(configObj: Config
|
|
131
|
+
function initializeConfig(configObj: Config): ConfigRoot {
|
|
135
132
|
config = configObj;
|
|
136
|
-
rootPath = getRootPath(config
|
|
133
|
+
rootPath = getRootPath(config);
|
|
137
134
|
rootConfig = applyConfigOverrides(config, rootPath);
|
|
138
135
|
return rootConfig;
|
|
139
136
|
}
|
package/src/lib/render.tsx
CHANGED
|
@@ -71,17 +71,21 @@ export class Render {
|
|
|
71
71
|
rootElement.innerHTML = '';
|
|
72
72
|
|
|
73
73
|
// clone the root element to initialize rendering on the background
|
|
74
|
-
const
|
|
74
|
+
const root = document.createElement('div');
|
|
75
75
|
|
|
76
76
|
// apply base design tokens and global styles to the root element
|
|
77
77
|
rootElement.classList.add('dropin-design');
|
|
78
|
+
rootElement.setAttribute('data-dropin-container', Component.name);
|
|
78
79
|
|
|
79
|
-
|
|
80
|
+
// store the virtual root element
|
|
81
|
+
(rootElement as any).__rootElement = root;
|
|
82
|
+
|
|
83
|
+
render(<Root next={state} />, root);
|
|
80
84
|
|
|
81
85
|
// API object to control the rendered component
|
|
82
86
|
const API: RenderAPI = {
|
|
83
87
|
remove: () => {
|
|
84
|
-
render(null,
|
|
88
|
+
render(null, root);
|
|
85
89
|
},
|
|
86
90
|
setProps: (cb: (prev: T) => T) => {
|
|
87
91
|
const next = cb(state.peek());
|
|
@@ -97,7 +101,7 @@ export class Render {
|
|
|
97
101
|
rootElement.classList.add('dropin-design');
|
|
98
102
|
|
|
99
103
|
// append the rendered component to the DOM only when all slots are resolved
|
|
100
|
-
rootElement.appendChild(
|
|
104
|
+
rootElement.appendChild(root.firstChild ?? root);
|
|
101
105
|
|
|
102
106
|
return resolve(API);
|
|
103
107
|
}
|
|
@@ -106,14 +110,24 @@ export class Render {
|
|
|
106
110
|
};
|
|
107
111
|
}
|
|
108
112
|
|
|
113
|
+
/**
|
|
114
|
+
* Unmounts a container from a root element.
|
|
115
|
+
* @param rootElement - The root element to unmount the container from.
|
|
116
|
+
*/
|
|
117
|
+
static unmount(rootElement: HTMLElement) {
|
|
118
|
+
const root = (rootElement as any)?.__rootElement;
|
|
119
|
+
if (!root) throw new Error('Root element is not defined');
|
|
120
|
+
render(null, root);
|
|
121
|
+
}
|
|
122
|
+
|
|
109
123
|
/**
|
|
110
124
|
* UnRenders a component from a root element.
|
|
111
125
|
* @param rootElement - The root element to unmount the component from.
|
|
112
|
-
* @deprecated Use `remove` method from the returned object of the `mount` method instead.
|
|
126
|
+
* @deprecated Use `remove` method from the returned object of the `mount` method instead or `unmount` method from the `Render` class.
|
|
113
127
|
*/
|
|
114
128
|
unmount(rootElement: HTMLElement) {
|
|
115
129
|
if (!rootElement) throw new Error('Root element is not defined');
|
|
116
|
-
rootElement.firstChild?.remove();
|
|
130
|
+
rootElement.firstChild?.remove();
|
|
117
131
|
}
|
|
118
132
|
|
|
119
133
|
/**
|
|
@@ -135,4 +149,4 @@ export class Render {
|
|
|
135
149
|
{ ...options }
|
|
136
150
|
);
|
|
137
151
|
}
|
|
138
|
-
}
|
|
152
|
+
}
|