@adobe-commerce/elsie 2.0.0 → 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/.elsie.js +3 -3
- package/CHANGELOG.md +385 -112
- package/LICENSE.md +257 -157
- package/README.md +4 -2
- package/__mocks__/svg.js +3 -3
- package/bin/builders/build/index.js +2 -1
- package/bin/builders/changeset/index.js +1 -1
- package/bin/builders/concurrently/index.js +1 -1
- package/bin/builders/generate/api/index.js +7 -7
- package/bin/builders/generate/component/index.js +8 -8
- package/bin/builders/generate/config/index.js +5 -5
- package/bin/builders/generate/config/templates/elsie.js +1 -1
- package/bin/builders/generate/container/index.js +7 -7
- package/bin/builders/generate/index.js +36 -36
- package/bin/builders/gql/index.js +28 -28
- package/bin/builders/gql/validate.js +116 -105
- package/bin/builders/lint/index.js +1 -1
- package/bin/builders/serve/index.js +1 -1
- package/bin/builders/storybook/index.js +9 -1
- package/bin/builders/types/index.js +1 -2
- package/bin/builders/types/validate-tsconfig.js +5 -5
- package/bin/index.js +12 -6
- package/bin/lib/cli.js +9 -8
- package/bin/lib/resolve-bin.js +9 -0
- package/bin/lib/validate-typeof.js +3 -3
- package/bin/lib/write-file.js +3 -3
- package/bin/lib/write-parent-index.js +4 -4
- package/config/eslint.mjs +2 -1
- package/config/jest.mjs +7 -2
- package/config/plugins/dts-normalize-relative-replacer.cjs +1 -1
- package/config/plugins/dts.mjs +4 -3
- package/config/prettier.json +25 -3
- package/config/setEnvVars.mjs +2 -2
- package/config/storybook/addon.js +5 -5
- package/config/storybook/components/FileTree/FileTree.jsx +4 -4
- package/config/storybook/components/FileTree/index.js +4 -4
- package/config/storybook/components/Flex/Flex.jsx +3 -3
- package/config/storybook/components/Flex/index.js +3 -3
- package/config/storybook/components/OptionsTable/OptionsTable.jsx +3 -3
- package/config/storybook/components/OptionsTable/index.js +4 -4
- package/config/storybook/components/Panel/Panel.tsx +7 -7
- package/config/storybook/components/Panel/index.ts +3 -3
- package/config/storybook/components/Screenshot/Screenshot.jsx +3 -3
- package/config/storybook/components/Screenshot/index.js +4 -4
- package/config/storybook/components/Steps/Steps.jsx +3 -3
- package/config/storybook/components/Steps/index.js +4 -4
- package/config/storybook/components/StoryWrapper/StoryWrapper.jsx +3 -3
- package/config/storybook/components/StoryWrapper/index.js +3 -3
- package/config/storybook/components/Summary/Summary.jsx +3 -3
- package/config/storybook/components/Summary/index.js +3 -3
- package/config/storybook/components/Variants/Variants.jsx +11 -7
- package/config/storybook/components/Variants/index.js +3 -3
- package/config/storybook/manager.js +3 -3
- package/config/storybook/preview.jsx +3 -3
- package/config/storybook/theming/fonts.css +12 -4
- package/config/storybook/theming/preview.css +3 -1
- package/config/storybook/theming/theme.js +3 -3
- package/config/vite.mjs +53 -26
- package/package.json +36 -34
- package/src/components/Accordion/Accordion.css +1 -1
- package/src/components/Accordion/Accordion.stories.tsx +18 -18
- package/src/components/Accordion/Accordion.tsx +12 -8
- package/src/components/Accordion/index.ts +3 -3
- package/src/components/ActionButton/ActionButton.stories.tsx +8 -8
- package/src/components/ActionButton/ActionButton.tsx +7 -5
- package/src/components/ActionButton/index.ts +3 -3
- package/src/components/ActionButtonGroup/ActionButtonGroup.stories.tsx +3 -3
- package/src/components/ActionButtonGroup/ActionButtonGroup.tsx +2 -2
- package/src/components/ActionButtonGroup/index.ts +3 -3
- package/src/components/AlertBanner/AlertBanner.stories.tsx +6 -6
- package/src/components/AlertBanner/AlertBanner.tsx +12 -10
- package/src/components/AlertBanner/index.ts +3 -3
- package/src/components/Breadcrumbs/Breadcrumbs.stories.tsx +14 -14
- package/src/components/Breadcrumbs/Breadcrumbs.tsx +3 -3
- package/src/components/Breadcrumbs/index.ts +3 -3
- package/src/components/Button/Button.mdx +24 -11
- package/src/components/Button/Button.stories.tsx +6 -6
- package/src/components/Button/Button.tsx +7 -8
- package/src/components/Button/index.ts +3 -3
- package/src/components/Card/Card.stories.tsx +6 -6
- package/src/components/Card/Card.tsx +3 -3
- package/src/components/Card/index.ts +3 -3
- package/src/components/CartItem/CartItem.stories.tsx +12 -12
- package/src/components/CartItem/CartItem.tsx +4 -2
- package/src/components/CartItem/CartItemSkeleton.tsx +3 -3
- package/src/components/CartItem/index.ts +3 -3
- package/src/components/CartList/CartList.tsx +3 -3
- package/src/components/CartList/index.ts +3 -3
- package/src/components/Checkbox/Checkbox.stories.tsx +17 -14
- package/src/components/Checkbox/Checkbox.tsx +8 -6
- package/src/components/Checkbox/index.ts +3 -3
- package/src/components/ColorSwatch/ColorSwatch.css +8 -4
- package/src/components/ColorSwatch/ColorSwatch.stories.tsx +6 -6
- package/src/components/ColorSwatch/ColorSwatch.tsx +8 -6
- package/src/components/ColorSwatch/index.ts +3 -3
- package/src/components/ContentGrid/ContentGrid.css +15 -15
- package/src/components/ContentGrid/ContentGrid.stories.tsx +4 -4
- package/src/components/ContentGrid/ContentGrid.tsx +3 -3
- package/src/components/ContentGrid/index.ts +3 -3
- package/src/components/Divider/Divider.stories.tsx +7 -4
- package/src/components/Divider/Divider.tsx +3 -3
- package/src/components/Divider/index.ts +4 -4
- package/src/components/Field/Field.stories.tsx +7 -7
- package/src/components/Field/Field.tsx +4 -2
- package/src/components/Field/index.ts +3 -3
- package/src/components/Header/Header.stories.tsx +9 -10
- package/src/components/Header/Header.tsx +11 -7
- package/src/components/Header/index.ts +3 -3
- package/src/components/Icon/Icon.stories.helpers.jsx +4 -4
- package/src/components/Icon/Icon.stories.tsx +74 -60
- package/src/components/Icon/Icon.tsx +77 -44
- package/src/components/Icon/index.ts +3 -3
- package/src/components/IllustratedMessage/IllustratedMessage.stories.tsx +8 -8
- package/src/components/IllustratedMessage/IllustratedMessage.tsx +7 -5
- package/src/components/IllustratedMessage/index.ts +3 -3
- package/src/components/Image/Image.stories.tsx +3 -3
- package/src/components/Image/Image.tsx +4 -4
- package/src/components/Image/index.ts +3 -3
- package/src/components/ImageSwatch/ImageSwatch.css +8 -4
- package/src/components/ImageSwatch/ImageSwatch.stories.tsx +10 -10
- package/src/components/ImageSwatch/ImageSwatch.tsx +25 -23
- package/src/components/ImageSwatch/index.ts +3 -3
- package/src/components/InLineAlert/InLineAlert.stories.tsx +12 -7
- package/src/components/InLineAlert/InLineAlert.tsx +4 -2
- package/src/components/InLineAlert/index.ts +3 -3
- package/src/components/Incrementer/Incrementer.stories.tsx +9 -9
- package/src/components/Incrementer/Incrementer.tsx +75 -37
- package/src/components/Incrementer/index.ts +3 -3
- package/src/components/Input/Input.css +4 -1
- package/src/components/Input/Input.stories.tsx +5 -5
- package/src/components/Input/Input.tsx +5 -3
- package/src/components/Input/index.ts +3 -3
- package/src/components/InputDate/InputDate.tsx +3 -3
- package/src/components/InputDate/index.ts +3 -3
- package/src/components/InputFile/InputFile.css +16 -16
- package/src/components/InputFile/InputFile.stories.tsx +21 -16
- package/src/components/InputFile/InputFile.tsx +8 -6
- package/src/components/InputFile/index.ts +5 -5
- package/src/components/InputPassword/InputPassword.stories.tsx +4 -4
- package/src/components/InputPassword/InputPassword.tsx +5 -4
- package/src/components/InputPassword/PasswordStatusIndicator/PasswordStatusIndicator.tsx +1 -1
- package/src/components/InputPassword/PasswordStatusIndicator/index.ts +3 -3
- package/src/components/InputPassword/index.ts +3 -3
- package/src/components/Modal/Modal.stories.tsx +27 -16
- package/src/components/Modal/Modal.tsx +10 -11
- package/src/components/Modal/index.ts +3 -3
- package/src/components/MultiSelect/MultiSelect.stories.tsx +15 -15
- package/src/components/MultiSelect/MultiSelect.tsx +15 -15
- package/src/components/Pagination/Pagination.css +1 -1
- package/src/components/Pagination/Pagination.stories.tsx +0 -1
- package/src/components/Pagination/Pagination.tsx +17 -12
- package/src/components/Pagination/PaginationButton.tsx +2 -3
- package/src/components/Pagination/index.ts +3 -3
- package/src/components/Picker/Picker.css +3 -1
- package/src/components/Picker/Picker.stories.tsx +1 -1
- package/src/components/Picker/Picker.tsx +8 -6
- package/src/components/Picker/index.ts +3 -3
- package/src/components/Portal/Portal.stories.tsx +50 -44
- package/src/components/Portal/Portal.tsx +4 -4
- package/src/components/Price/Price.stories.tsx +3 -3
- package/src/components/Price/Price.tsx +4 -2
- package/src/components/Price/index.ts +3 -3
- package/src/components/PriceRange/PriceRange.stories.tsx +3 -3
- package/src/components/PriceRange/PriceRange.tsx +8 -6
- package/src/components/PriceRange/index.ts +3 -3
- package/src/components/ProductItemCard/ProductItemCard.tsx +4 -2
- package/src/components/ProductItemCard/ProductItemCardSkeleton.tsx +16 -16
- package/src/components/ProductItemCard/index.ts +4 -4
- package/src/components/ProgressSpinner/ProgressSpinner.stories.tsx +8 -8
- package/src/components/ProgressSpinner/ProgressSpinner.tsx +7 -5
- package/src/components/ProgressSpinner/index.ts +3 -3
- package/src/components/RadioButton/RadioButton.stories.tsx +1 -1
- package/src/components/RadioButton/RadioButton.tsx +4 -2
- package/src/components/Skeleton/Skeleton.stories.tsx +4 -4
- package/src/components/Skeleton/Skeleton.tsx +11 -7
- package/src/components/Skeleton/index.ts +3 -3
- package/src/components/Table/Table.css +106 -99
- package/src/components/Table/Table.stories.tsx +404 -227
- package/src/components/Table/Table.tsx +11 -7
- package/src/components/Table/index.ts +4 -4
- package/src/components/Tag/Tag.stories.tsx +6 -6
- package/src/components/Tag/Tag.tsx +7 -5
- package/src/components/Tag/index.ts +3 -3
- package/src/components/TextArea/TextArea.css +3 -1
- package/src/components/TextArea/TextArea.stories.tsx +9 -6
- package/src/components/TextArea/TextArea.tsx +3 -3
- package/src/components/TextArea/index.ts +3 -3
- package/src/components/TextSwatch/TextSwatch.css +4 -2
- package/src/components/TextSwatch/TextSwatch.stories.tsx +8 -8
- package/src/components/TextSwatch/TextSwatch.tsx +12 -7
- package/src/components/TextSwatch/index.ts +3 -3
- package/src/components/ToggleButton/ToggleButton.css +6 -2
- package/src/components/ToggleButton/ToggleButton.stories.tsx +10 -6
- package/src/components/ToggleButton/ToggleButton.tsx +8 -3
- package/src/components/ToggleButton/index.ts +3 -3
- package/src/components/UIProvider/UIProvider.css +3 -2
- package/src/components/UIProvider/UIProvider.tsx +11 -7
- package/src/components/UIProvider/debugger.css +5 -6
- package/src/components/UIProvider/index.ts +3 -3
- package/src/docs/API/event-bus.mdx +64 -37
- package/src/docs/API/graphql.mdx +69 -36
- package/src/docs/API/initializer.mdx +58 -35
- package/src/docs/API/render.mdx +45 -32
- package/src/docs/Design/colors.mdx +10 -12
- package/src/docs/Design/grid.mdx +41 -14
- package/src/docs/Design/overview.mdx +20 -4
- package/src/docs/Design/shapes.mdx +8 -7
- package/src/docs/Design/spacing.mdx +3 -1
- package/src/docs/Design/typography.mdx +3 -2
- package/src/docs/Utilities/VComponent.mdx +27 -10
- package/src/docs/Utilities/classList.mdx +7 -5
- package/src/docs/Utilities/debounce.mdx +6 -7
- package/src/docs/Utilities/getCookie.mdx +1 -2
- package/src/docs/Utilities/getFormErrors.mdx +1 -2
- package/src/docs/Utilities/getFormValues.mdx +1 -2
- package/src/docs/Utilities/getPathValue.mdx +2 -4
- package/src/docs/Utilities/links.mdx +16 -7
- package/src/docs/cli-usage.mdx +8 -3
- package/src/docs/components/overview.mdx +14 -4
- package/src/docs/quick-start.mdx +69 -22
- package/src/docs/slots.mdx +74 -37
- package/src/docs/welcome.mdx +13 -4
- package/src/i18n/index.ts +3 -3
- package/src/lib/aem/assets.ts +9 -9
- package/src/lib/aem/configs.ts +16 -8
- package/src/lib/classes.ts +4 -4
- package/src/lib/config.ts +3 -3
- package/src/lib/debounce.ts +3 -3
- package/src/lib/deepmerge.ts +6 -13
- package/src/lib/deviceUtils.ts +3 -3
- package/src/lib/form-values.ts +3 -3
- package/src/lib/get-price-formatter.ts +8 -3
- package/src/lib/i18n.ts +3 -3
- package/src/lib/image-params-keymap.ts +4 -5
- package/src/lib/initializer.ts +11 -12
- package/src/lib/is-number.ts +3 -3
- package/src/lib/locale-config.ts +4 -4
- package/src/lib/render.tsx +14 -8
- package/src/lib/resolve-image.ts +19 -16
- package/src/lib/signals.ts +4 -4
- package/src/lib/slot.tsx +34 -27
- package/src/lib/tests.tsx +6 -8
- package/src/lib/types.ts +3 -3
- package/src/lib/vcomponent.tsx +3 -3
- package/src/shims/importmap.js +3107 -20
- package/static/assets/images/index.ts +3 -3
- package/storybook-stories.js +3 -3
- package/tests/__mocks__/browserMocks.ts +3 -3
- package/tests/__mocks__/fileMocks.ts +3 -3
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
* Copyright 2024 Adobe
|
|
3
3
|
* All Rights Reserved.
|
|
4
4
|
*
|
|
5
|
-
* NOTICE: Adobe permits you to use, modify, and distribute this
|
|
6
|
-
* file in accordance with the terms of the Adobe license agreement
|
|
7
|
-
* accompanying it.
|
|
5
|
+
* NOTICE: Adobe permits you to use, modify, and distribute this
|
|
6
|
+
* file in accordance with the terms of the Adobe license agreement
|
|
7
|
+
* accompanying it.
|
|
8
8
|
*******************************************************************/
|
|
9
9
|
|
|
10
10
|
import { Icon, IconProps } from '@adobe-commerce/elsie/components/Icon';
|
|
@@ -14,7 +14,7 @@ import type { Meta, StoryObj } from '@storybook/preact-vite';
|
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* Use Icons as symbols or metaphors to communicate and enhance the user experience.
|
|
17
|
-
*
|
|
17
|
+
*
|
|
18
18
|
* The Icon component supports three source types:
|
|
19
19
|
* - Direct component imports
|
|
20
20
|
* - Icon names from the built-in icon set
|
|
@@ -36,7 +36,8 @@ const meta: Meta<StoryIconProps> = {
|
|
|
36
36
|
control: {
|
|
37
37
|
type: 'text',
|
|
38
38
|
},
|
|
39
|
-
description:
|
|
39
|
+
description:
|
|
40
|
+
'Or enter a URL to an external SVG (this takes priority over icon selection)',
|
|
40
41
|
},
|
|
41
42
|
size: {
|
|
42
43
|
control: 'select',
|
|
@@ -93,24 +94,24 @@ export const AllBuiltInIcons: Story = {
|
|
|
93
94
|
style: Object,
|
|
94
95
|
url: {
|
|
95
96
|
table: {
|
|
96
|
-
disable: true
|
|
97
|
-
}
|
|
97
|
+
disable: true,
|
|
98
|
+
},
|
|
98
99
|
},
|
|
99
100
|
source: {
|
|
100
101
|
table: {
|
|
101
|
-
disable: true
|
|
102
|
-
}
|
|
102
|
+
disable: true,
|
|
103
|
+
},
|
|
103
104
|
},
|
|
104
105
|
title: {
|
|
105
106
|
table: {
|
|
106
|
-
disable: true
|
|
107
|
-
}
|
|
108
|
-
}
|
|
107
|
+
disable: true,
|
|
108
|
+
},
|
|
109
|
+
},
|
|
109
110
|
},
|
|
110
111
|
args: {
|
|
111
112
|
style: {
|
|
112
|
-
color: 'blue'
|
|
113
|
-
}
|
|
113
|
+
color: 'blue',
|
|
114
|
+
},
|
|
114
115
|
},
|
|
115
116
|
render: (props) => (
|
|
116
117
|
<div
|
|
@@ -132,82 +133,95 @@ export const AllBuiltInIcons: Story = {
|
|
|
132
133
|
),
|
|
133
134
|
};
|
|
134
135
|
|
|
135
|
-
|
|
136
136
|
export const UrlExamples: Story = {
|
|
137
137
|
argTypes: {
|
|
138
138
|
source: {
|
|
139
139
|
table: {
|
|
140
|
-
disable: true
|
|
141
|
-
}
|
|
140
|
+
disable: true,
|
|
141
|
+
},
|
|
142
142
|
},
|
|
143
143
|
title: {
|
|
144
144
|
table: {
|
|
145
|
-
disable: true
|
|
146
|
-
}
|
|
147
|
-
}
|
|
145
|
+
disable: true,
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
148
|
},
|
|
149
149
|
render: ({ url, ...args }: StoryIconProps) => (
|
|
150
|
-
<div
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
150
|
+
<div
|
|
151
|
+
style={{
|
|
152
|
+
display: 'grid',
|
|
153
|
+
gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))',
|
|
154
|
+
gap: '2rem',
|
|
155
|
+
padding: '1rem',
|
|
156
|
+
}}
|
|
157
|
+
>
|
|
158
|
+
<div
|
|
159
|
+
style={{
|
|
160
|
+
border: '1px solid #e1e5e9',
|
|
161
|
+
borderRadius: '8px',
|
|
162
|
+
padding: '1.5rem',
|
|
163
|
+
textAlign: 'center',
|
|
164
|
+
backgroundColor: '#f8f9fa',
|
|
165
|
+
}}
|
|
166
|
+
>
|
|
163
167
|
<h3 style={{ margin: '0 0 1rem 0', color: '#2c3e50' }}>✅ Valid URL</h3>
|
|
164
|
-
<Icon
|
|
168
|
+
<Icon
|
|
165
169
|
source={url || `${window.location.origin}/favicon.svg`}
|
|
166
170
|
size="12"
|
|
167
171
|
title="logo icon from common domain"
|
|
168
172
|
aria-label="Star icon loaded from external URL"
|
|
169
173
|
{...args}
|
|
170
174
|
/>
|
|
171
|
-
<p
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
175
|
+
<p
|
|
176
|
+
style={{
|
|
177
|
+
fontSize: '12px',
|
|
178
|
+
color: '#495057',
|
|
179
|
+
margin: '0.5rem 0 0 0',
|
|
180
|
+
wordBreak: 'break-all',
|
|
181
|
+
}}
|
|
182
|
+
>
|
|
183
|
+
{url
|
|
184
|
+
? `Displays icon from: ${url}`
|
|
185
|
+
: `Displays icon from ${window.location.origin}/favicon.svg`}
|
|
178
186
|
</p>
|
|
179
187
|
</div>
|
|
180
|
-
|
|
181
|
-
<div
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
188
|
+
|
|
189
|
+
<div
|
|
190
|
+
style={{
|
|
191
|
+
border: '1px solid #f8d7da',
|
|
192
|
+
borderRadius: '8px',
|
|
193
|
+
padding: '1.5rem',
|
|
194
|
+
textAlign: 'center',
|
|
195
|
+
backgroundColor: '#f8d7da',
|
|
196
|
+
}}
|
|
197
|
+
>
|
|
198
|
+
<h3 style={{ margin: '0 0 1rem 0', color: '#721c24' }}>
|
|
199
|
+
❌ Invalid URL
|
|
200
|
+
</h3>
|
|
201
|
+
<Icon
|
|
202
|
+
source="https://invalid-url.com/icon.svg"
|
|
191
203
|
size="32"
|
|
192
204
|
title="Failed to load icon"
|
|
193
205
|
aria-label="Icon that failed to load"
|
|
194
206
|
/>
|
|
195
|
-
<p
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
207
|
+
<p
|
|
208
|
+
style={{
|
|
209
|
+
fontSize: '12px',
|
|
210
|
+
color: '#721c24',
|
|
211
|
+
margin: '0.5rem 0 0 0',
|
|
212
|
+
wordBreak: 'break-all',
|
|
213
|
+
}}
|
|
214
|
+
>
|
|
201
215
|
Shows empty SVG
|
|
202
216
|
</p>
|
|
203
217
|
</div>
|
|
204
|
-
|
|
205
218
|
</div>
|
|
206
219
|
),
|
|
207
220
|
parameters: {
|
|
208
221
|
docs: {
|
|
209
222
|
description: {
|
|
210
|
-
story:
|
|
223
|
+
story:
|
|
224
|
+
'Examples of different URL formats supported by the Icon component.',
|
|
211
225
|
},
|
|
212
226
|
},
|
|
213
227
|
},
|
|
@@ -18,16 +18,24 @@ export type IconType = keyof typeof import('@adobe-commerce/elsie/icons');
|
|
|
18
18
|
|
|
19
19
|
const lazyIcons = {
|
|
20
20
|
Add: lazy(() => import('@adobe-commerce/elsie/icons/Add.svg')),
|
|
21
|
-
AddressBook: lazy(
|
|
21
|
+
AddressBook: lazy(
|
|
22
|
+
() => import('@adobe-commerce/elsie/icons/AddressBook.svg'),
|
|
23
|
+
),
|
|
22
24
|
Bulk: lazy(() => import('@adobe-commerce/elsie/icons/Bulk.svg')),
|
|
23
25
|
Burger: lazy(() => import('@adobe-commerce/elsie/icons/Burger.svg')),
|
|
24
26
|
Business: lazy(() => import('@adobe-commerce/elsie/icons/Business.svg')),
|
|
25
27
|
Card: lazy(() => import('@adobe-commerce/elsie/icons/Card.svg')),
|
|
26
28
|
Cart: lazy(() => import('@adobe-commerce/elsie/icons/Cart.svg')),
|
|
27
29
|
Check: lazy(() => import('@adobe-commerce/elsie/icons/Check.svg')),
|
|
28
|
-
CheckWithCircle: lazy(
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
CheckWithCircle: lazy(
|
|
31
|
+
() => import('@adobe-commerce/elsie/icons/CheckWithCircle.svg'),
|
|
32
|
+
),
|
|
33
|
+
ChevronDown: lazy(
|
|
34
|
+
() => import('@adobe-commerce/elsie/icons/ChevronDown.svg'),
|
|
35
|
+
),
|
|
36
|
+
ChevronRight: lazy(
|
|
37
|
+
() => import('@adobe-commerce/elsie/icons/ChevronRight.svg'),
|
|
38
|
+
),
|
|
31
39
|
ChevronUp: lazy(() => import('@adobe-commerce/elsie/icons/ChevronUp.svg')),
|
|
32
40
|
Close: lazy(() => import('@adobe-commerce/elsie/icons/Close.svg')),
|
|
33
41
|
Coupon: lazy(() => import('@adobe-commerce/elsie/icons/Coupon.svg')),
|
|
@@ -40,23 +48,33 @@ const lazyIcons = {
|
|
|
40
48
|
Gift: lazy(() => import('@adobe-commerce/elsie/icons/Gift.svg')),
|
|
41
49
|
GiftCard: lazy(() => import('@adobe-commerce/elsie/icons/GiftCard.svg')),
|
|
42
50
|
Heart: lazy(() => import('@adobe-commerce/elsie/icons/Heart.svg')),
|
|
43
|
-
HeartFilled: lazy(
|
|
51
|
+
HeartFilled: lazy(
|
|
52
|
+
() => import('@adobe-commerce/elsie/icons/HeartFilled.svg'),
|
|
53
|
+
),
|
|
44
54
|
InfoFilled: lazy(() => import('@adobe-commerce/elsie/icons/InfoFilled.svg')),
|
|
45
55
|
List: lazy(() => import('@adobe-commerce/elsie/icons/List.svg')),
|
|
46
56
|
Locker: lazy(() => import('@adobe-commerce/elsie/icons/Locker.svg')),
|
|
47
57
|
Minus: lazy(() => import('@adobe-commerce/elsie/icons/Minus.svg')),
|
|
48
58
|
Order: lazy(() => import('@adobe-commerce/elsie/icons/Order.svg')),
|
|
49
59
|
OrderError: lazy(() => import('@adobe-commerce/elsie/icons/OrderError.svg')),
|
|
50
|
-
OrderSuccess: lazy(
|
|
51
|
-
|
|
52
|
-
|
|
60
|
+
OrderSuccess: lazy(
|
|
61
|
+
() => import('@adobe-commerce/elsie/icons/OrderSuccess.svg'),
|
|
62
|
+
),
|
|
63
|
+
PaymentError: lazy(
|
|
64
|
+
() => import('@adobe-commerce/elsie/icons/PaymentError.svg'),
|
|
65
|
+
),
|
|
66
|
+
Placeholder: lazy(
|
|
67
|
+
() => import('@adobe-commerce/elsie/icons/Placeholder.svg'),
|
|
68
|
+
),
|
|
53
69
|
PlaceholderFilled: lazy(
|
|
54
|
-
() => import('@adobe-commerce/elsie/icons/PlaceholderFilled.svg')
|
|
70
|
+
() => import('@adobe-commerce/elsie/icons/PlaceholderFilled.svg'),
|
|
55
71
|
),
|
|
56
72
|
Purchase: lazy(() => import('@adobe-commerce/elsie/icons/Purchase.svg')),
|
|
57
73
|
Quote: lazy(() => import('@adobe-commerce/elsie/icons/Quote.svg')),
|
|
58
74
|
Search: lazy(() => import('@adobe-commerce/elsie/icons/Search.svg')),
|
|
59
|
-
SearchFilled: lazy(
|
|
75
|
+
SearchFilled: lazy(
|
|
76
|
+
() => import('@adobe-commerce/elsie/icons/SearchFilled.svg'),
|
|
77
|
+
),
|
|
60
78
|
Sort: lazy(() => import('@adobe-commerce/elsie/icons/Sort.svg')),
|
|
61
79
|
Star: lazy(() => import('@adobe-commerce/elsie/icons/Star.svg')),
|
|
62
80
|
Structure: lazy(() => import('@adobe-commerce/elsie/icons/Structure.svg')),
|
|
@@ -66,17 +84,19 @@ const lazyIcons = {
|
|
|
66
84
|
View: lazy(() => import('@adobe-commerce/elsie/icons/View.svg')),
|
|
67
85
|
Wallet: lazy(() => import('@adobe-commerce/elsie/icons/Wallet.svg')),
|
|
68
86
|
Warning: lazy(() => import('@adobe-commerce/elsie/icons/Warning.svg')),
|
|
69
|
-
WarningFilled: lazy(
|
|
87
|
+
WarningFilled: lazy(
|
|
88
|
+
() => import('@adobe-commerce/elsie/icons/WarningFilled.svg'),
|
|
89
|
+
),
|
|
70
90
|
WarningWithCircle: lazy(
|
|
71
|
-
() => import('@adobe-commerce/elsie/icons/WarningWithCircle.svg')
|
|
91
|
+
() => import('@adobe-commerce/elsie/icons/WarningWithCircle.svg'),
|
|
72
92
|
),
|
|
73
93
|
};
|
|
74
94
|
|
|
75
95
|
export interface IconProps extends Omit<SVGProps<SVGSVGElement>, 'size'> {
|
|
76
96
|
source?:
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
97
|
+
| FunctionComponent<SVGProps<SVGSVGElement> & { title?: string }>
|
|
98
|
+
| IconType
|
|
99
|
+
| string;
|
|
80
100
|
size?: '12' | '16' | '24' | '32' | '64' | '80';
|
|
81
101
|
stroke?: '1' | '2' | '3' | '4';
|
|
82
102
|
className?: string;
|
|
@@ -87,26 +107,29 @@ export type IconNode = FunctionComponent<
|
|
|
87
107
|
SVGProps<SVGSVGElement> & { title?: string }
|
|
88
108
|
>;
|
|
89
109
|
|
|
90
|
-
function isValidUrl(source: string): boolean {
|
|
110
|
+
function isValidUrl(source: string): boolean {
|
|
111
|
+
// check for URL from same domain
|
|
91
112
|
try {
|
|
92
113
|
if (source.startsWith('//')) {
|
|
93
114
|
const absoluteUrl = `${window.location.protocol}${source}`;
|
|
94
115
|
const url = new URL(absoluteUrl);
|
|
95
116
|
if (url.hostname !== window.location.hostname) {
|
|
96
117
|
console.error(
|
|
97
|
-
`[Icon] External URL rejected for security: ${source} - Only same-domain URLs are allowed
|
|
118
|
+
`[Icon] External URL rejected for security: ${source} - Only same-domain URLs are allowed`,
|
|
98
119
|
);
|
|
99
120
|
return false;
|
|
100
121
|
}
|
|
101
122
|
return true;
|
|
102
123
|
}
|
|
103
124
|
const url = new URL(source);
|
|
104
|
-
|
|
125
|
+
|
|
105
126
|
if (url.hostname !== window.location.hostname) {
|
|
106
|
-
console.error(
|
|
127
|
+
console.error(
|
|
128
|
+
`[Icon] External URL rejected for security: ${source} - Only same-domain URLs are allowed`,
|
|
129
|
+
);
|
|
107
130
|
return false;
|
|
108
131
|
}
|
|
109
|
-
|
|
132
|
+
|
|
110
133
|
return true;
|
|
111
134
|
} catch {
|
|
112
135
|
console.error(`[Icon] Invalid URL format: ${source}`);
|
|
@@ -124,33 +147,40 @@ function UrlSvgLoader({
|
|
|
124
147
|
|
|
125
148
|
useEffect(() => {
|
|
126
149
|
fetch(url)
|
|
127
|
-
.then(response => {
|
|
150
|
+
.then((response) => {
|
|
128
151
|
if (!response.ok) {
|
|
129
|
-
console.error(
|
|
130
|
-
|
|
152
|
+
console.error(
|
|
153
|
+
`[Icon] Failed to fetch SVG: ${response.status} ${response.statusText}`,
|
|
154
|
+
);
|
|
155
|
+
throw new Error(
|
|
156
|
+
`Failed to fetch SVG: ${response.status} ${response.statusText}`,
|
|
157
|
+
);
|
|
131
158
|
}
|
|
132
159
|
return response.text();
|
|
133
160
|
})
|
|
134
|
-
.then(content => {
|
|
161
|
+
.then((content) => {
|
|
135
162
|
// Check if content is valid SVG
|
|
136
163
|
try {
|
|
137
164
|
const parser = new DOMParser();
|
|
138
|
-
const doc = parser.parseFromString(content,
|
|
165
|
+
const doc = parser.parseFromString(content, 'image/svg+xml');
|
|
139
166
|
const svg = doc.querySelector('svg');
|
|
140
167
|
if (!svg) {
|
|
141
|
-
throw new Error(
|
|
168
|
+
throw new Error('No <svg> element found');
|
|
142
169
|
}
|
|
143
170
|
// Success!
|
|
144
|
-
} catch(e: unknown) {
|
|
145
|
-
if (e instanceof Error
|
|
146
|
-
console.error(
|
|
171
|
+
} catch (e: unknown) {
|
|
172
|
+
if (e instanceof Error) {
|
|
173
|
+
console.error(
|
|
174
|
+
`[Icon] Invalid SVG content from ${url}: ${e.message}`,
|
|
175
|
+
);
|
|
147
176
|
} else {
|
|
148
|
-
console.error(
|
|
177
|
+
console.error(
|
|
178
|
+
`[Icon] Invalid SVG content from ${url}: ${String(e)}`,
|
|
179
|
+
);
|
|
149
180
|
}
|
|
150
181
|
setError(true);
|
|
151
182
|
setLoading(false);
|
|
152
183
|
}
|
|
153
|
-
|
|
154
184
|
|
|
155
185
|
// Process SVG content to ensure proper sizing and accessibility
|
|
156
186
|
let processedContent = content;
|
|
@@ -158,33 +188,36 @@ function UrlSvgLoader({
|
|
|
158
188
|
if (props.width) {
|
|
159
189
|
processedContent = processedContent.replace(
|
|
160
190
|
/<svg([^>]*)\s+width\s*=\s*["'][^"']*["']/gi,
|
|
161
|
-
'<svg$1'
|
|
191
|
+
'<svg$1',
|
|
162
192
|
);
|
|
163
193
|
processedContent = processedContent.replace(
|
|
164
194
|
/<svg/i,
|
|
165
|
-
`<svg width="${props.width}"
|
|
195
|
+
`<svg width="${props.width}"`,
|
|
166
196
|
);
|
|
167
197
|
}
|
|
168
198
|
|
|
169
199
|
if (props.height) {
|
|
170
200
|
processedContent = processedContent.replace(
|
|
171
201
|
/<svg([^>]*)\s+height\s*=\s*["'][^"']*["']/gi,
|
|
172
|
-
'<svg$1'
|
|
202
|
+
'<svg$1',
|
|
173
203
|
);
|
|
174
204
|
processedContent = processedContent.replace(
|
|
175
205
|
/<svg/i,
|
|
176
|
-
`<svg height="${props.height}"
|
|
206
|
+
`<svg height="${props.height}"`,
|
|
177
207
|
);
|
|
178
208
|
}
|
|
179
|
-
|
|
209
|
+
|
|
180
210
|
if (props.title) {
|
|
181
|
-
processedContent = processedContent.replace(
|
|
211
|
+
processedContent = processedContent.replace(
|
|
212
|
+
/<title[^>]*>.*?<\/title>/gi,
|
|
213
|
+
'',
|
|
214
|
+
);
|
|
182
215
|
processedContent = processedContent.replace(
|
|
183
216
|
/<svg([^>]*)>/i,
|
|
184
|
-
`<svg$1><title>${props.title}</title
|
|
217
|
+
`<svg$1><title>${props.title}</title>`,
|
|
185
218
|
);
|
|
186
219
|
}
|
|
187
|
-
|
|
220
|
+
|
|
188
221
|
setSvgContent(processedContent);
|
|
189
222
|
setLoading(false);
|
|
190
223
|
})
|
|
@@ -226,7 +259,6 @@ export function Icon({
|
|
|
226
259
|
className,
|
|
227
260
|
...props
|
|
228
261
|
}: IconProps) {
|
|
229
|
-
|
|
230
262
|
const defaultProps = {
|
|
231
263
|
className: classes([
|
|
232
264
|
'dropin-icon',
|
|
@@ -248,14 +280,15 @@ export function Icon({
|
|
|
248
280
|
if (isLikelyUrl && isValidUrl(Source)) {
|
|
249
281
|
return (
|
|
250
282
|
<Suspense fallback={<svg {...props} {...defaultProps} />}>
|
|
251
|
-
<UrlSvgLoader url={Source} {...props} {...defaultProps}/>
|
|
283
|
+
<UrlSvgLoader url={Source} {...props} {...defaultProps} />
|
|
252
284
|
</Suspense>
|
|
253
285
|
);
|
|
254
286
|
}
|
|
255
287
|
|
|
256
|
-
const LazyIcon =
|
|
257
|
-
|
|
258
|
-
|
|
288
|
+
const LazyIcon =
|
|
289
|
+
typeof Source === 'string' && Source in lazyIcons
|
|
290
|
+
? lazyIcons[Source as IconType]
|
|
291
|
+
: null;
|
|
259
292
|
|
|
260
293
|
const isRejectedUrl = isLikelyUrl && !isValidUrl(Source);
|
|
261
294
|
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
* Copyright 2024 Adobe
|
|
3
3
|
* All Rights Reserved.
|
|
4
4
|
*
|
|
5
|
-
* NOTICE: Adobe permits you to use, modify, and distribute this
|
|
6
|
-
* file in accordance with the terms of the Adobe license agreement
|
|
7
|
-
* accompanying it.
|
|
5
|
+
* NOTICE: Adobe permits you to use, modify, and distribute this
|
|
6
|
+
* file in accordance with the terms of the Adobe license agreement
|
|
7
|
+
* accompanying it.
|
|
8
8
|
*******************************************************************/
|
|
9
9
|
|
|
10
10
|
export * from '@adobe-commerce/elsie/components/Icon/Icon';
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
* Copyright 2024 Adobe
|
|
3
3
|
* All Rights Reserved.
|
|
4
4
|
*
|
|
5
|
-
* NOTICE: Adobe permits you to use, modify, and distribute this
|
|
6
|
-
* file in accordance with the terms of the Adobe license agreement
|
|
7
|
-
* accompanying it.
|
|
5
|
+
* NOTICE: Adobe permits you to use, modify, and distribute this
|
|
6
|
+
* file in accordance with the terms of the Adobe license agreement
|
|
7
|
+
* accompanying it.
|
|
8
8
|
*******************************************************************/
|
|
9
9
|
|
|
10
10
|
// https://storybook.js.org/docs/7.0/preact/writing-stories/introduction
|
|
@@ -98,28 +98,28 @@ export const IllustratedMessage: Story = {
|
|
|
98
98
|
},
|
|
99
99
|
play: async () => {
|
|
100
100
|
const illustratedMessage = document.querySelector(
|
|
101
|
-
'div[class*="dropin-illustrated-message"]'
|
|
101
|
+
'div[class*="dropin-illustrated-message"]',
|
|
102
102
|
) as HTMLElement;
|
|
103
103
|
|
|
104
104
|
await expect(illustratedMessage).toBeVisible();
|
|
105
105
|
|
|
106
106
|
const icon = illustratedMessage.querySelector(
|
|
107
|
-
'.dropin-illustrated-message__icon'
|
|
107
|
+
'.dropin-illustrated-message__icon',
|
|
108
108
|
);
|
|
109
109
|
await expect(icon).toBeVisible();
|
|
110
110
|
|
|
111
111
|
const heading = illustratedMessage.querySelector(
|
|
112
|
-
'.dropin-illustrated-message__heading'
|
|
112
|
+
'.dropin-illustrated-message__heading',
|
|
113
113
|
);
|
|
114
114
|
await expect(heading).toBeVisible();
|
|
115
115
|
|
|
116
116
|
const message = illustratedMessage.querySelector(
|
|
117
|
-
'.dropin-illustrated-message__message'
|
|
117
|
+
'.dropin-illustrated-message__message',
|
|
118
118
|
);
|
|
119
119
|
await expect(message).toBeVisible();
|
|
120
120
|
|
|
121
121
|
const action = illustratedMessage.querySelector(
|
|
122
|
-
'.dropin-illustrated-message__action'
|
|
122
|
+
'.dropin-illustrated-message__action',
|
|
123
123
|
);
|
|
124
124
|
await expect(action).toBeVisible();
|
|
125
125
|
},
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
* Copyright 2024 Adobe
|
|
3
3
|
* All Rights Reserved.
|
|
4
4
|
*
|
|
5
|
-
* NOTICE: Adobe permits you to use, modify, and distribute this
|
|
6
|
-
* file in accordance with the terms of the Adobe license agreement
|
|
7
|
-
* accompanying it.
|
|
5
|
+
* NOTICE: Adobe permits you to use, modify, and distribute this
|
|
6
|
+
* file in accordance with the terms of the Adobe license agreement
|
|
7
|
+
* accompanying it.
|
|
8
8
|
*******************************************************************/
|
|
9
9
|
|
|
10
10
|
import { FunctionComponent, VNode } from 'preact';
|
|
@@ -13,8 +13,10 @@ import { classes, VComponent } from '@adobe-commerce/elsie/lib';
|
|
|
13
13
|
import '@adobe-commerce/elsie/components/IllustratedMessage/IllustratedMessage.css';
|
|
14
14
|
import { Card } from '@adobe-commerce/elsie/components';
|
|
15
15
|
|
|
16
|
-
export interface IllustratedMessageProps
|
|
17
|
-
|
|
16
|
+
export interface IllustratedMessageProps extends Omit<
|
|
17
|
+
HTMLAttributes<HTMLDivElement>,
|
|
18
|
+
'icon' | 'action'
|
|
19
|
+
> {
|
|
18
20
|
icon?: VNode<HTMLAttributes<SVGSVGElement>>;
|
|
19
21
|
heading?: string;
|
|
20
22
|
headingLevel?: 1 | 2 | 3 | 4 | 5 | 6;
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
* Copyright 2024 Adobe
|
|
3
3
|
* All Rights Reserved.
|
|
4
4
|
*
|
|
5
|
-
* NOTICE: Adobe permits you to use, modify, and distribute this
|
|
6
|
-
* file in accordance with the terms of the Adobe license agreement
|
|
7
|
-
* accompanying it.
|
|
5
|
+
* NOTICE: Adobe permits you to use, modify, and distribute this
|
|
6
|
+
* file in accordance with the terms of the Adobe license agreement
|
|
7
|
+
* accompanying it.
|
|
8
8
|
*******************************************************************/
|
|
9
9
|
|
|
10
10
|
export * from '@adobe-commerce/elsie/components/IllustratedMessage/IllustratedMessage';
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
* Copyright 2024 Adobe
|
|
3
3
|
* All Rights Reserved.
|
|
4
4
|
*
|
|
5
|
-
* NOTICE: Adobe permits you to use, modify, and distribute this
|
|
6
|
-
* file in accordance with the terms of the Adobe license agreement
|
|
7
|
-
* accompanying it.
|
|
5
|
+
* NOTICE: Adobe permits you to use, modify, and distribute this
|
|
6
|
+
* file in accordance with the terms of the Adobe license agreement
|
|
7
|
+
* accompanying it.
|
|
8
8
|
*******************************************************************/
|
|
9
9
|
|
|
10
10
|
// https://storybook.js.org/docs/7.0/preact/writing-stories/introduction
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
* Copyright 2024 Adobe
|
|
3
3
|
* All Rights Reserved.
|
|
4
4
|
*
|
|
5
|
-
* NOTICE: Adobe permits you to use, modify, and distribute this
|
|
6
|
-
* file in accordance with the terms of the Adobe license agreement
|
|
7
|
-
* accompanying it.
|
|
5
|
+
* NOTICE: Adobe permits you to use, modify, and distribute this
|
|
6
|
+
* file in accordance with the terms of the Adobe license agreement
|
|
7
|
+
* accompanying it.
|
|
8
8
|
*******************************************************************/
|
|
9
9
|
|
|
10
10
|
import { FunctionComponent } from 'preact';
|
|
@@ -47,7 +47,7 @@ export const Image: FunctionComponent<ImageProps> = ({
|
|
|
47
47
|
|
|
48
48
|
// Add class at image onLoad
|
|
49
49
|
const onLoadHandler = (e: any) => {
|
|
50
|
-
setLoaded(true);
|
|
50
|
+
setLoaded(true);
|
|
51
51
|
onLoad?.(e);
|
|
52
52
|
};
|
|
53
53
|
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
* Copyright 2024 Adobe
|
|
3
3
|
* All Rights Reserved.
|
|
4
4
|
*
|
|
5
|
-
* NOTICE: Adobe permits you to use, modify, and distribute this
|
|
6
|
-
* file in accordance with the terms of the Adobe license agreement
|
|
7
|
-
* accompanying it.
|
|
5
|
+
* NOTICE: Adobe permits you to use, modify, and distribute this
|
|
6
|
+
* file in accordance with the terms of the Adobe license agreement
|
|
7
|
+
* accompanying it.
|
|
8
8
|
*******************************************************************/
|
|
9
9
|
|
|
10
10
|
export * from '@adobe-commerce/elsie/components/Image/Image';
|
|
@@ -51,7 +51,8 @@
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
.dropin-image-swatch__span:hover {
|
|
54
|
-
box-shadow:
|
|
54
|
+
box-shadow:
|
|
55
|
+
0 0 0 var(--shape-border-width-3) var(--color-neutral-50),
|
|
55
56
|
0 0 0 var(--shape-border-width-4) var(--color-neutral-500);
|
|
56
57
|
outline: none;
|
|
57
58
|
}
|
|
@@ -73,7 +74,8 @@
|
|
|
73
74
|
input[type='checkbox']:checked
|
|
74
75
|
~ .dropin-image-swatch__span,
|
|
75
76
|
.dropin-image-swatch--selected {
|
|
76
|
-
box-shadow:
|
|
77
|
+
box-shadow:
|
|
78
|
+
0 0 0 var(--shape-border-width-3) var(--color-neutral-50),
|
|
77
79
|
0 0 0 var(--shape-border-width-4) var(--color-neutral-800);
|
|
78
80
|
}
|
|
79
81
|
|
|
@@ -83,7 +85,8 @@
|
|
|
83
85
|
.dropin-image-swatch__container
|
|
84
86
|
input[type='checkbox']:checked:active
|
|
85
87
|
~ .dropin-image-swatch__span {
|
|
86
|
-
box-shadow:
|
|
88
|
+
box-shadow:
|
|
89
|
+
0 0 0 var(--shape-border-width-3) var(--color-neutral-50),
|
|
87
90
|
0 0 0 var(--shape-border-width-4) var(--color-neutral-600);
|
|
88
91
|
}
|
|
89
92
|
|
|
@@ -93,7 +96,8 @@
|
|
|
93
96
|
.dropin-image-swatch__container
|
|
94
97
|
input[type='checkbox']:focus-visible
|
|
95
98
|
+ .dropin-image-swatch__span {
|
|
96
|
-
box-shadow:
|
|
99
|
+
box-shadow:
|
|
100
|
+
0 0 0 var(--shape-border-width-3) var(--color-neutral-900),
|
|
97
101
|
0 0 0 6px var(--color-neutral-600);
|
|
98
102
|
}
|
|
99
103
|
|