@adobe-commerce/elsie 1.7.0-beta2 → 1.7.0-beta4
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 +1 -1
- package/src/components/CartItem/CartItem.css +3 -15
- package/src/components/Field/Field.css +3 -3
- package/src/components/Field/Field.stories.tsx +3 -45
- package/src/components/Field/Field.tsx +20 -22
- package/src/components/Input/Input.css +3 -3
- package/src/components/Input/Input.stories.tsx +3 -42
- package/src/components/Input/Input.tsx +6 -14
- package/src/components/Picker/Picker.css +3 -3
- package/src/components/Picker/Picker.stories.tsx +0 -53
- package/src/components/Picker/Picker.tsx +2 -2
- package/src/components/TextArea/TextArea.css +4 -4
- package/src/components/TextArea/TextArea.stories.tsx +7 -54
- package/src/components/TextArea/TextArea.tsx +5 -5
- package/src/components/UIProvider/normalize.css +3 -8
- package/src/lib/index.ts +0 -1
- package/src/lib/wrap-required-asterisk.tsx +0 -70
package/package.json
CHANGED
|
@@ -45,16 +45,6 @@
|
|
|
45
45
|
height: auto;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
.dropin-cart-item__image:is(a),
|
|
49
|
-
.dropin-cart-item__image a {
|
|
50
|
-
display: inline-block;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
.dropin-cart-item__image:is(a) img,
|
|
54
|
-
.dropin-cart-item__image a img {
|
|
55
|
-
display: block;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
48
|
.dropin-cart-item__title {
|
|
59
49
|
font: var(--type-body-1-default-font);
|
|
60
50
|
letter-spacing: var(--type-body-1-default-letter-spacing);
|
|
@@ -300,8 +290,7 @@
|
|
|
300
290
|
}
|
|
301
291
|
|
|
302
292
|
/* Smallish / Medium */
|
|
303
|
-
@container cart-item (width >=400px) and (width < 737px) {
|
|
304
|
-
|
|
293
|
+
@container cart-item (width >= 400px) and (width < 737px) {
|
|
305
294
|
.dropin-cart-item__title,
|
|
306
295
|
.dropin-cart-item__sku,
|
|
307
296
|
.dropin-cart-item__attributes,
|
|
@@ -331,8 +320,7 @@
|
|
|
331
320
|
}
|
|
332
321
|
|
|
333
322
|
/* Large */
|
|
334
|
-
@container cart-item (width >=737px) and (width < 1192px) {
|
|
335
|
-
|
|
323
|
+
@container cart-item (width >= 737px) and (width < 1192px) {
|
|
336
324
|
/* Grid */
|
|
337
325
|
.dropin-cart-item__wrapper {
|
|
338
326
|
grid-template-columns: repeat(12, 1fr);
|
|
@@ -410,7 +398,7 @@
|
|
|
410
398
|
}
|
|
411
399
|
|
|
412
400
|
/* Extra Large */
|
|
413
|
-
@container cart-item (width >=1192px) {
|
|
401
|
+
@container cart-item (width >= 1192px) {
|
|
414
402
|
.dropin-cart-item {
|
|
415
403
|
--item-group-spacing: var(--spacing-xxsmall);
|
|
416
404
|
--group-spacing: var(--spacing-small);
|
|
@@ -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://cssguidelin.es/#bem-like-naming */
|
|
@@ -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
|
|
@@ -230,48 +230,6 @@ export const CheckboxField: Story = {
|
|
|
230
230
|
},
|
|
231
231
|
};
|
|
232
232
|
|
|
233
|
-
/**
|
|
234
|
-
* Field with a label that includes a required asterisk.
|
|
235
|
-
* The asterisk is automatically wrapped in a `<span class="dropin-label-required">` for consistent styling.
|
|
236
|
-
*
|
|
237
|
-
* ```ts
|
|
238
|
-
* import { Field } from '@adobe-commerce/elsie/components/Field';
|
|
239
|
-
* import { Input } from '@adobe-commerce/elsie/components/Input';
|
|
240
|
-
* ```
|
|
241
|
-
*
|
|
242
|
-
* This example demonstrates:
|
|
243
|
-
* - Automatic asterisk wrapping in field labels
|
|
244
|
-
* - The asterisk can be styled independently using `.dropin-label-required`
|
|
245
|
-
* - Works with any child component (Input, Picker, etc.)
|
|
246
|
-
*/
|
|
247
|
-
export const WithRequiredAsterisk: Story = {
|
|
248
|
-
render: (args) => (
|
|
249
|
-
<Field {...args}>
|
|
250
|
-
<Input name="requiredField" placeholder="Enter your email" />
|
|
251
|
-
</Field>
|
|
252
|
-
),
|
|
253
|
-
args: {
|
|
254
|
-
label: 'Email Address',
|
|
255
|
-
hint: 'We will never share your email',
|
|
256
|
-
required: true,
|
|
257
|
-
error: '',
|
|
258
|
-
success: '',
|
|
259
|
-
size: 'medium',
|
|
260
|
-
disabled: false,
|
|
261
|
-
},
|
|
262
|
-
play: async ({ canvasElement }) => {
|
|
263
|
-
// Verify the label is rendered
|
|
264
|
-
const label = canvasElement.querySelector('.dropin-field__label');
|
|
265
|
-
await expect(label).toBeTruthy();
|
|
266
|
-
await expect(label?.textContent).toBe('Email Address *');
|
|
267
|
-
|
|
268
|
-
// Verify the asterisk is wrapped in a span with required class
|
|
269
|
-
const asteriskSpan = label?.querySelector('.dropin-label-required');
|
|
270
|
-
await expect(asteriskSpan).toBeTruthy();
|
|
271
|
-
await expect(asteriskSpan?.textContent).toBe('*');
|
|
272
|
-
},
|
|
273
|
-
};
|
|
274
|
-
|
|
275
233
|
/**
|
|
276
234
|
* ```ts
|
|
277
235
|
* import { Field } from '@adobe-commerce/elsie/components/Field';
|
|
@@ -2,17 +2,13 @@
|
|
|
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 '@adobe-commerce/elsie/components/Field/Field.css';
|
|
11
|
-
import {
|
|
12
|
-
classes,
|
|
13
|
-
VComponent,
|
|
14
|
-
wrapRequiredAsterisk,
|
|
15
|
-
} from '@adobe-commerce/elsie/lib';
|
|
11
|
+
import { classes, VComponent } from '@adobe-commerce/elsie/lib';
|
|
16
12
|
import { FunctionComponent, VNode } from 'preact';
|
|
17
13
|
import { HTMLAttributes } from 'preact/compat';
|
|
18
14
|
|
|
@@ -36,7 +32,6 @@ export const Field: FunctionComponent<FieldProps> = ({
|
|
|
36
32
|
size = 'medium',
|
|
37
33
|
disabled = false,
|
|
38
34
|
children,
|
|
39
|
-
required,
|
|
40
35
|
...props
|
|
41
36
|
}) => {
|
|
42
37
|
const id =
|
|
@@ -45,19 +40,20 @@ export const Field: FunctionComponent<FieldProps> = ({
|
|
|
45
40
|
let fieldContent: VNode | string | null = null;
|
|
46
41
|
|
|
47
42
|
if (children && typeof children !== 'string') {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
43
|
+
fieldContent = (
|
|
44
|
+
<VComponent
|
|
45
|
+
node={children}
|
|
46
|
+
id={id}
|
|
47
|
+
key={children.key}
|
|
48
|
+
disabled={disabled}
|
|
49
|
+
size={size}
|
|
50
|
+
error={!!error}
|
|
51
|
+
success={!!success && !error}
|
|
52
|
+
/>
|
|
53
|
+
);
|
|
59
54
|
}
|
|
60
55
|
|
|
56
|
+
|
|
61
57
|
return (
|
|
62
58
|
<div {...props} className={classes(['dropin-field', className])}>
|
|
63
59
|
{label && (
|
|
@@ -69,11 +65,13 @@ export const Field: FunctionComponent<FieldProps> = ({
|
|
|
69
65
|
])}
|
|
70
66
|
htmlFor={id}
|
|
71
67
|
>
|
|
72
|
-
{
|
|
68
|
+
{label}
|
|
73
69
|
</label>
|
|
74
70
|
)}
|
|
75
71
|
|
|
76
|
-
<div className={classes(['dropin-field__content'])}>
|
|
72
|
+
<div className={classes(['dropin-field__content'])}>
|
|
73
|
+
{fieldContent}
|
|
74
|
+
</div>
|
|
77
75
|
|
|
78
76
|
<div
|
|
79
77
|
className={classes([
|
|
@@ -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://cssguidelin.es/#bem-like-naming */
|
|
@@ -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
|
|
@@ -153,42 +153,3 @@ export const Secondary: Story = {
|
|
|
153
153
|
await expect(await canvas.findByDisplayValue('')).toBeTruthy();
|
|
154
154
|
},
|
|
155
155
|
};
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* Input with a floating label that includes a required asterisk.
|
|
159
|
-
* The asterisk is automatically wrapped in a `<span class="dropin-label-required">` for consistent styling.
|
|
160
|
-
*
|
|
161
|
-
* ```ts
|
|
162
|
-
* import { Input } from '@adobe-commerce/elsie/components/Input';
|
|
163
|
-
* ```
|
|
164
|
-
*
|
|
165
|
-
* This example demonstrates:
|
|
166
|
-
* - Automatic asterisk wrapping in floating labels
|
|
167
|
-
* - The asterisk can be styled independently using `.dropin-label-required`
|
|
168
|
-
* - The label floats above the input when it has a value
|
|
169
|
-
*/
|
|
170
|
-
export const WithRequiredAsterisk: Story = {
|
|
171
|
-
args: {
|
|
172
|
-
name: 'emailField',
|
|
173
|
-
value: 'user@example.com',
|
|
174
|
-
variant: 'primary',
|
|
175
|
-
size: 'medium',
|
|
176
|
-
floatingLabel: 'Email Address',
|
|
177
|
-
required: true,
|
|
178
|
-
disabled: false,
|
|
179
|
-
error: false,
|
|
180
|
-
success: false,
|
|
181
|
-
onValue: action('onValue'),
|
|
182
|
-
},
|
|
183
|
-
play: async ({ canvasElement }) => {
|
|
184
|
-
// Verify the floating label is rendered
|
|
185
|
-
const label = canvasElement.querySelector('.dropin-input__label--floating');
|
|
186
|
-
await expect(label).toBeTruthy();
|
|
187
|
-
await expect(label?.textContent).toBe('Email Address *');
|
|
188
|
-
|
|
189
|
-
// Verify the asterisk is wrapped in a span with required class
|
|
190
|
-
const asteriskSpan = label?.querySelector('.dropin-label-required');
|
|
191
|
-
await expect(asteriskSpan).toBeTruthy();
|
|
192
|
-
await expect(asteriskSpan?.textContent).toBe('*');
|
|
193
|
-
},
|
|
194
|
-
};
|
|
@@ -2,23 +2,15 @@
|
|
|
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 } from '@adobe-commerce/elsie/components/Icon';
|
|
11
11
|
import '@adobe-commerce/elsie/components/Input/Input.css';
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
WarningWithCircle,
|
|
15
|
-
} from '@adobe-commerce/elsie/icons';
|
|
16
|
-
import {
|
|
17
|
-
VComponent,
|
|
18
|
-
classes,
|
|
19
|
-
debounce,
|
|
20
|
-
wrapRequiredAsterisk,
|
|
21
|
-
} from '@adobe-commerce/elsie/lib';
|
|
12
|
+
import { CheckWithCircle, WarningWithCircle } from '@adobe-commerce/elsie/icons';
|
|
13
|
+
import { VComponent, classes, debounce } from '@adobe-commerce/elsie/lib';
|
|
22
14
|
import { FunctionComponent, VNode } from 'preact';
|
|
23
15
|
import { HTMLAttributes } from 'preact/compat';
|
|
24
16
|
import { useCallback } from 'preact/hooks';
|
|
@@ -131,7 +123,7 @@ export const Input: FunctionComponent<InputProps> = ({
|
|
|
131
123
|
[`dropin-input__label--floating--error`, !!error],
|
|
132
124
|
])}
|
|
133
125
|
>
|
|
134
|
-
{
|
|
126
|
+
{floatingLabel}
|
|
135
127
|
</label>
|
|
136
128
|
)}
|
|
137
129
|
</div>
|
|
@@ -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://cssguidelin.es/#bem-like-naming */
|
|
@@ -334,56 +334,3 @@ export const SingleOption: Story = {
|
|
|
334
334
|
],
|
|
335
335
|
},
|
|
336
336
|
};
|
|
337
|
-
|
|
338
|
-
/**
|
|
339
|
-
* Picker with a floating label that includes a required asterisk.
|
|
340
|
-
* The asterisk is automatically wrapped in a `<span class="dropin-label-required">` for consistent styling.
|
|
341
|
-
*
|
|
342
|
-
* ```ts
|
|
343
|
-
* import { Picker } from '@adobe-commerce/elsie/components/Picker';
|
|
344
|
-
* ```
|
|
345
|
-
*
|
|
346
|
-
* This example demonstrates:
|
|
347
|
-
* - Automatic asterisk wrapping in floating labels
|
|
348
|
-
* - The asterisk can be styled independently using `.dropin-label-required`
|
|
349
|
-
* - The label floats above the picker when an option is selected
|
|
350
|
-
*/
|
|
351
|
-
export const WithRequiredAsterisk: Story = {
|
|
352
|
-
name: 'With required asterisk',
|
|
353
|
-
args: {
|
|
354
|
-
name: 'countryPicker',
|
|
355
|
-
variant: 'primary',
|
|
356
|
-
floatingLabel: 'Country',
|
|
357
|
-
required: true,
|
|
358
|
-
value: 'us',
|
|
359
|
-
options: [
|
|
360
|
-
{
|
|
361
|
-
value: 'us',
|
|
362
|
-
text: 'United States',
|
|
363
|
-
},
|
|
364
|
-
{
|
|
365
|
-
value: 'ca',
|
|
366
|
-
text: 'Canada',
|
|
367
|
-
},
|
|
368
|
-
{
|
|
369
|
-
value: 'mx',
|
|
370
|
-
text: 'Mexico',
|
|
371
|
-
},
|
|
372
|
-
{
|
|
373
|
-
value: 'uk',
|
|
374
|
-
text: 'United Kingdom',
|
|
375
|
-
},
|
|
376
|
-
],
|
|
377
|
-
},
|
|
378
|
-
play: async ({ canvasElement }) => {
|
|
379
|
-
// Verify the floating label is rendered
|
|
380
|
-
const label = canvasElement.querySelector('.dropin-picker__floatingLabel');
|
|
381
|
-
await expect(label).toBeTruthy();
|
|
382
|
-
await expect(label?.textContent).toBe('Country *');
|
|
383
|
-
|
|
384
|
-
// Verify the asterisk is wrapped in a span with required class
|
|
385
|
-
const asteriskSpan = label?.querySelector('.dropin-label-required');
|
|
386
|
-
await expect(asteriskSpan).toBeTruthy();
|
|
387
|
-
await expect(asteriskSpan?.textContent).toBe('*');
|
|
388
|
-
},
|
|
389
|
-
};
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
import { Icon } from '@adobe-commerce/elsie/components';
|
|
11
11
|
import { ChevronDown } from '@adobe-commerce/elsie/icons';
|
|
12
|
-
import { classes
|
|
12
|
+
import { classes } from '@adobe-commerce/elsie/lib';
|
|
13
13
|
import { FunctionComponent, VNode } from 'preact';
|
|
14
14
|
import { HTMLAttributes, useEffect, useState } from 'preact/compat';
|
|
15
15
|
|
|
@@ -198,7 +198,7 @@ export const Picker: FunctionComponent<PickerProps> = ({
|
|
|
198
198
|
htmlFor={id}
|
|
199
199
|
className={classes(['dropin-picker__floatingLabel', !!floatingLabel])}
|
|
200
200
|
>
|
|
201
|
-
{
|
|
201
|
+
{floatingLabel}
|
|
202
202
|
</label>
|
|
203
203
|
)}
|
|
204
204
|
</div>
|
|
@@ -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
|
.dropin-textarea-container {
|
|
@@ -135,6 +135,6 @@
|
|
|
135
135
|
.dropin-textarea__label--floating--error {
|
|
136
136
|
font: var(--type-details-caption-1-font);
|
|
137
137
|
letter-spacing: var(--type-details-caption-1-letter-spacing);
|
|
138
|
-
color: var(--color-alert-
|
|
138
|
+
color: var(--color-alert-800);
|
|
139
139
|
padding-top: var(--spacing-xsmall);
|
|
140
140
|
}
|
|
@@ -2,17 +2,14 @@
|
|
|
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
|
|
11
11
|
import type { Meta, StoryObj } from '@storybook/preact';
|
|
12
|
-
import {
|
|
13
|
-
TextArea,
|
|
14
|
-
TextAreaProps,
|
|
15
|
-
} from '@adobe-commerce/elsie/components/TextArea';
|
|
12
|
+
import { TextArea, TextAreaProps } from '@adobe-commerce/elsie/components/TextArea';
|
|
16
13
|
import { expect, userEvent, within } from '@storybook/test';
|
|
17
14
|
import { useState, useCallback } from 'preact/hooks';
|
|
18
15
|
|
|
@@ -78,7 +75,7 @@ const Template: StoryObj<TextAreaProps> = {
|
|
|
78
75
|
render: (args) => {
|
|
79
76
|
const [value, setValue] = useState(args.value);
|
|
80
77
|
|
|
81
|
-
const setTextAreaValue = useCallback((event
|
|
78
|
+
const setTextAreaValue = useCallback((event) => {
|
|
82
79
|
setValue(event.target.value);
|
|
83
80
|
}, []);
|
|
84
81
|
|
|
@@ -86,7 +83,7 @@ const Template: StoryObj<TextAreaProps> = {
|
|
|
86
83
|
},
|
|
87
84
|
};
|
|
88
85
|
|
|
89
|
-
export const DefaultWithValue
|
|
86
|
+
export const DefaultWithValue = {
|
|
90
87
|
...Template,
|
|
91
88
|
parameters: {
|
|
92
89
|
layout: 'centered',
|
|
@@ -115,7 +112,7 @@ export const DefaultWithValue: StoryObj<TextAreaProps> = {
|
|
|
115
112
|
},
|
|
116
113
|
};
|
|
117
114
|
|
|
118
|
-
export const WithError
|
|
115
|
+
export const WithError = {
|
|
119
116
|
...Template,
|
|
120
117
|
parameters: {
|
|
121
118
|
layout: 'centered',
|
|
@@ -131,47 +128,3 @@ export const WithError: StoryObj<TextAreaProps> = {
|
|
|
131
128
|
errorMessage: 'Message cannot be empty',
|
|
132
129
|
},
|
|
133
130
|
};
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* TextArea with a label that includes a required asterisk.
|
|
137
|
-
* The asterisk is automatically wrapped in a `<span class="dropin-label-required">` for consistent styling.
|
|
138
|
-
*
|
|
139
|
-
* ```ts
|
|
140
|
-
* import { TextArea } from '@adobe-commerce/elsie/components/TextArea';
|
|
141
|
-
* ```
|
|
142
|
-
*
|
|
143
|
-
* This example demonstrates:
|
|
144
|
-
* - Automatic asterisk wrapping in textarea labels
|
|
145
|
-
* - The asterisk can be styled independently using `.dropin-label-required`
|
|
146
|
-
* - The label floats above the textarea when it has content
|
|
147
|
-
*/
|
|
148
|
-
export const WithRequiredAsterisk: StoryObj<TextAreaProps> = {
|
|
149
|
-
...Template,
|
|
150
|
-
parameters: {
|
|
151
|
-
layout: 'centered',
|
|
152
|
-
a11y: {
|
|
153
|
-
config: {
|
|
154
|
-
rules: [{ id: 'color-contrast', enabled: false }],
|
|
155
|
-
},
|
|
156
|
-
},
|
|
157
|
-
},
|
|
158
|
-
args: {
|
|
159
|
-
label: 'Comments',
|
|
160
|
-
name: 'comments',
|
|
161
|
-
required: true,
|
|
162
|
-
value: 'Please provide additional details about your request.',
|
|
163
|
-
},
|
|
164
|
-
play: async ({ canvasElement }) => {
|
|
165
|
-
// Verify the floating label is rendered
|
|
166
|
-
const label = canvasElement.querySelector(
|
|
167
|
-
'.dropin-textarea__label--floating'
|
|
168
|
-
);
|
|
169
|
-
await expect(label).toBeTruthy();
|
|
170
|
-
await expect(label?.textContent).toBe('Comments *');
|
|
171
|
-
|
|
172
|
-
// Verify the asterisk is wrapped in a span with required class
|
|
173
|
-
const asteriskSpan = label?.querySelector('.dropin-label-required');
|
|
174
|
-
await expect(asteriskSpan).toBeTruthy();
|
|
175
|
-
await expect(asteriskSpan?.textContent).toBe('*');
|
|
176
|
-
},
|
|
177
|
-
};
|
|
@@ -2,13 +2,13 @@
|
|
|
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';
|
|
11
|
-
import { classes
|
|
11
|
+
import { classes } from '@adobe-commerce/elsie/lib';
|
|
12
12
|
import { HTMLAttributes } from 'preact/compat';
|
|
13
13
|
import '@adobe-commerce/elsie/components/TextArea/TextArea.css';
|
|
14
14
|
import { useRef, useEffect, useId } from 'preact/hooks';
|
|
@@ -72,7 +72,7 @@ export const TextArea: FunctionComponent<TextAreaProps> = ({
|
|
|
72
72
|
[`dropin-textarea__label--floating--error`, error],
|
|
73
73
|
])}
|
|
74
74
|
>
|
|
75
|
-
{
|
|
75
|
+
{label}
|
|
76
76
|
</label>
|
|
77
77
|
{error ? (
|
|
78
78
|
<div
|
|
@@ -2,15 +2,14 @@
|
|
|
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
|
.dropin-design a {
|
|
11
11
|
--textColor: var(--color-brand-500);
|
|
12
12
|
color: var(--textColor);
|
|
13
|
-
border: var(--shape-border-width-1) solid transparent;
|
|
14
13
|
text-decoration: none;
|
|
15
14
|
}
|
|
16
15
|
|
|
@@ -25,7 +24,3 @@
|
|
|
25
24
|
border: var(--shape-border-width-1) solid var(--color-neutral-800);
|
|
26
25
|
border-radius: var(--shape-border-radius-1);
|
|
27
26
|
}
|
|
28
|
-
|
|
29
|
-
.dropin-design .dropin-label-required {
|
|
30
|
-
color: var(--color-alert-500);
|
|
31
|
-
}
|
package/src/lib/index.ts
CHANGED
|
@@ -26,4 +26,3 @@ export * from '@adobe-commerce/elsie/lib/deviceUtils';
|
|
|
26
26
|
export * from '@adobe-commerce/elsie/lib/get-path-value';
|
|
27
27
|
export * from '@adobe-commerce/elsie/lib/get-cookie';
|
|
28
28
|
export * from '@adobe-commerce/elsie/lib/get-price-formatter';
|
|
29
|
-
export * from '@adobe-commerce/elsie/lib/wrap-required-asterisk';
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
/********************************************************************
|
|
2
|
-
* ADOBE CONFIDENTIAL
|
|
3
|
-
* __________________
|
|
4
|
-
*
|
|
5
|
-
* Copyright 2025 Adobe
|
|
6
|
-
* All Rights Reserved.
|
|
7
|
-
*
|
|
8
|
-
* NOTICE: All information contained herein is, and remains
|
|
9
|
-
* the property of Adobe and its suppliers, if any. The intellectual
|
|
10
|
-
* and technical concepts contained herein are proprietary to Adobe
|
|
11
|
-
* and its suppliers and are protected by all applicable intellectual
|
|
12
|
-
* property laws, including trade secret and copyright laws.
|
|
13
|
-
* Dissemination of this information or reproduction of this material
|
|
14
|
-
* is strictly forbidden unless prior written permission is obtained
|
|
15
|
-
* from Adobe.
|
|
16
|
-
*******************************************************************/
|
|
17
|
-
|
|
18
|
-
import { VNode } from 'preact';
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Wraps trailing asterisk(s) in a span element for consistent styling.
|
|
22
|
-
* If the text ends with one or more asterisks (preceded by optional space),
|
|
23
|
-
* the asterisk(s) will be wrapped in a <span className="dropin-label-required">.
|
|
24
|
-
* If required is true and no asterisk exists, one will be added automatically.
|
|
25
|
-
*
|
|
26
|
-
* @param text - The label text that may contain asterisk(s)
|
|
27
|
-
* @param required - Whether the field is required
|
|
28
|
-
* @returns A VNode with the text and wrapped asterisk, or the original text
|
|
29
|
-
*
|
|
30
|
-
* @example
|
|
31
|
-
* wrapRequiredAsterisk('Email *', true) // Returns: <>Email <span className="dropin-label-required">*</span></>
|
|
32
|
-
* wrapRequiredAsterisk('Email', true) // Returns: <>Email <span className="dropin-label-required">*</span></>
|
|
33
|
-
* wrapRequiredAsterisk('Email *', false) // Returns: <>Email <span>*</span></>
|
|
34
|
-
* wrapRequiredAsterisk('Email', false) // Returns: 'Email'
|
|
35
|
-
*/
|
|
36
|
-
export const wrapRequiredAsterisk = (
|
|
37
|
-
text: string | undefined,
|
|
38
|
-
required?: boolean
|
|
39
|
-
): string | VNode | undefined => {
|
|
40
|
-
if (!text) return text;
|
|
41
|
-
|
|
42
|
-
// Match optional space followed by one or more asterisks at the end of the string
|
|
43
|
-
const asteriskPattern = /^(.+?)(\s*)(\*+)$/;
|
|
44
|
-
const match = text.match(asteriskPattern);
|
|
45
|
-
|
|
46
|
-
if (match) {
|
|
47
|
-
const [, textPart, space, asterisks] = match;
|
|
48
|
-
return (
|
|
49
|
-
<>
|
|
50
|
-
{textPart}
|
|
51
|
-
{space}
|
|
52
|
-
<span className={required ? 'dropin-label-required' : undefined}>
|
|
53
|
-
{asterisks}
|
|
54
|
-
</span>
|
|
55
|
-
</>
|
|
56
|
-
);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// If required is true and no asterisk exists, add it
|
|
60
|
-
if (required) {
|
|
61
|
-
return (
|
|
62
|
-
<>
|
|
63
|
-
{text}{' '}
|
|
64
|
-
<span className="dropin-label-required">*</span>
|
|
65
|
-
</>
|
|
66
|
-
);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
return text;
|
|
70
|
-
};
|