@adobe-commerce/elsie 1.6.0-alpha2 → 1.6.0-alpha23
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
|
@@ -2,14 +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
|
import { FunctionComponent } from 'preact';
|
|
11
11
|
import { HTMLAttributes, useMemo } from 'preact/compat';
|
|
12
|
-
import { classes,
|
|
12
|
+
import { classes, getPriceFormatter } from '@adobe-commerce/elsie/lib';
|
|
13
13
|
import '@adobe-commerce/elsie/components/Price/Price.css';
|
|
14
14
|
|
|
15
15
|
export interface PriceProps
|
|
@@ -39,43 +39,10 @@ export const Price: FunctionComponent<PriceProps> = ({
|
|
|
39
39
|
size = 'small',
|
|
40
40
|
...props
|
|
41
41
|
}) => {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
const globalLocale = getGlobalLocale();
|
|
48
|
-
if (globalLocale) {
|
|
49
|
-
return globalLocale;
|
|
50
|
-
}
|
|
51
|
-
// Fallback to browser locale or default
|
|
52
|
-
return process.env.LOCALE && process.env.LOCALE !== 'undefined' ? process.env.LOCALE : 'en-US';
|
|
53
|
-
}, [locale]);
|
|
54
|
-
|
|
55
|
-
const formatter = useMemo(
|
|
56
|
-
() => {
|
|
57
|
-
const params: Intl.NumberFormatOptions = {
|
|
58
|
-
style: 'currency',
|
|
59
|
-
currency: currency || 'USD',
|
|
60
|
-
// These options are needed to round to whole numbers if that's what you want.
|
|
61
|
-
minimumFractionDigits: 2, // (this suffices for whole numbers, but will print 2500.10 as $2,500.1)
|
|
62
|
-
maximumFractionDigits: 2, // (causes 2500.99 to be printed as $2,501)
|
|
63
|
-
...formatOptions,
|
|
64
|
-
}
|
|
65
|
-
try {
|
|
66
|
-
return new Intl.NumberFormat(effectiveLocale, params);
|
|
67
|
-
} catch (error) {
|
|
68
|
-
console.error(`Error creating Intl.NumberFormat instance for locale ${effectiveLocale}. Falling back to en-US.`, error);
|
|
69
|
-
return new Intl.NumberFormat('en-US', params);
|
|
70
|
-
}
|
|
71
|
-
},
|
|
72
|
-
[effectiveLocale, currency, formatOptions]
|
|
73
|
-
);
|
|
74
|
-
|
|
75
|
-
const formattedAmount = useMemo(
|
|
76
|
-
() => formatter.format(amount),
|
|
77
|
-
[amount, formatter]
|
|
78
|
-
);
|
|
42
|
+
const formattedAmount = useMemo(() => {
|
|
43
|
+
const formatter = getPriceFormatter({ currency, locale, formatOptions });
|
|
44
|
+
return formatter.format(amount);
|
|
45
|
+
}, [amount, currency, locale, formatOptions]);
|
|
79
46
|
|
|
80
47
|
return (
|
|
81
48
|
<span
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
.dropin-table__table {
|
|
20
|
+
border: var(--shape-border-width-1) solid var(--color-neutral-400);
|
|
20
21
|
border-collapse: collapse;
|
|
21
22
|
width: 100%;
|
|
22
23
|
}
|
|
@@ -34,9 +35,8 @@
|
|
|
34
35
|
letter-spacing: var(--type-body-1-strong-letter-spacing);
|
|
35
36
|
}
|
|
36
37
|
|
|
37
|
-
.dropin-table__header__cell
|
|
38
|
-
|
|
39
|
-
padding: var(--spacing-xsmall);
|
|
38
|
+
.dropin-table__header__cell {
|
|
39
|
+
color: var(--color-neutral-800);
|
|
40
40
|
text-align: left;
|
|
41
41
|
white-space: nowrap;
|
|
42
42
|
}
|
|
@@ -46,15 +46,26 @@
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
.dropin-table__header__row {
|
|
49
|
-
border-bottom:
|
|
49
|
+
border-bottom: var(--shape-border-width-1) solid var(--color-neutral-400);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.dropin-table__header__row th {
|
|
53
|
+
padding: var(--spacing-small) var(--spacing-medium);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.dropin-table__body__row:nth-child(even) {
|
|
57
|
+
background-color: var(--color-neutral-100);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.dropin-table__body__row.dropin-table__body__row--expanded {
|
|
61
|
+
background-color: var(--color-neutral-200);
|
|
50
62
|
}
|
|
51
63
|
|
|
52
|
-
.dropin-
|
|
53
|
-
|
|
64
|
+
.dropin-table__body__cell {
|
|
65
|
+
padding: var(--spacing-small) var(--spacing-medium);
|
|
54
66
|
}
|
|
55
67
|
|
|
56
68
|
.dropin-table__header__sort-button {
|
|
57
|
-
margin-left: var(--spacing-xsmall);
|
|
58
69
|
vertical-align: middle;
|
|
59
70
|
}
|
|
60
71
|
|
|
@@ -67,10 +78,29 @@
|
|
|
67
78
|
}
|
|
68
79
|
|
|
69
80
|
.dropin-table__row-details__cell {
|
|
70
|
-
padding: var(--spacing-small);
|
|
71
|
-
background-color: var(--color-neutral-
|
|
72
|
-
|
|
73
|
-
|
|
81
|
+
padding: var(--spacing-small) var(--spacing-medium);
|
|
82
|
+
background-color: var(--color-neutral-200);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.dropin-table__row-details--expanded .dropin-table__row-details__cell > *:last-child {
|
|
86
|
+
margin: 0;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.dropin-table__row-details__cell h1,
|
|
90
|
+
.dropin-table__row-details__cell h2,
|
|
91
|
+
.dropin-table__row-details__cell h3,
|
|
92
|
+
.dropin-table__row-details__cell h4,
|
|
93
|
+
.dropin-table__row-details__cell h5,
|
|
94
|
+
.dropin-table__row-details__cell h6 {
|
|
95
|
+
font: var(--type-body-1-strong-font);
|
|
96
|
+
letter-spacing: var(--type-body-1-strong-letter-spacing);
|
|
97
|
+
margin: 0;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.dropin-table__row-details__cell p,
|
|
101
|
+
.dropin-table__row-details__cell span {
|
|
102
|
+
font: var(--type-body-1-default-font);
|
|
103
|
+
letter-spacing: var(--type-body-1-default-letter-spacing);
|
|
74
104
|
}
|
|
75
105
|
|
|
76
106
|
/* Container query for mobile layout */
|
|
@@ -80,20 +110,63 @@
|
|
|
80
110
|
display: none;
|
|
81
111
|
}
|
|
82
112
|
|
|
113
|
+
.dropin-table--mobile-layout-stacked .dropin-table__body__row {
|
|
114
|
+
padding: var(--spacing-medium);
|
|
115
|
+
display: block;
|
|
116
|
+
}
|
|
117
|
+
|
|
83
118
|
.dropin-table--mobile-layout-stacked .dropin-table__body__cell {
|
|
84
119
|
display: block;
|
|
120
|
+
font: var(--type-body-2-default-font);
|
|
121
|
+
letter-spacing: var(--type-body-2-default-letter-spacing);
|
|
122
|
+
padding: var(--spacing-xsmall) 0;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.dropin-table--mobile-layout-stacked .dropin-table__body__cell:first-child {
|
|
126
|
+
padding-top: 0;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.dropin-table--mobile-layout-stacked .dropin-table__body__cell:last-child {
|
|
130
|
+
padding-bottom: 0;
|
|
85
131
|
}
|
|
86
132
|
|
|
87
133
|
.dropin-table--mobile-layout-stacked .dropin-table__body__cell::before {
|
|
88
134
|
content: attr(data-label);
|
|
89
|
-
font
|
|
135
|
+
font: var(--type-body-2-strong-font);
|
|
136
|
+
letter-spacing: var(--type-body-2-strong-letter-spacing);
|
|
90
137
|
display: block;
|
|
91
138
|
margin-bottom: var(--spacing-xxsmall);
|
|
92
139
|
}
|
|
93
140
|
|
|
94
141
|
.dropin-table--mobile-layout-stacked .dropin-table__row-details__cell {
|
|
95
142
|
display: block;
|
|
96
|
-
padding: var(--spacing-
|
|
143
|
+
padding: var(--spacing-medium);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.dropin-table--mobile-layout-stacked .dropin-table__row-details__cell > *:first-child {
|
|
147
|
+
border-top: var(--shape-border-width-1) solid var(--color-neutral-400);
|
|
148
|
+
padding-top: var(--spacing-medium);
|
|
149
|
+
margin-top: calc(var(--spacing-medium) * -1);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.dropin-table--mobile-layout-stacked .dropin-table__row-details--expanded .dropin-table__row-details__cell > *:last-child {
|
|
153
|
+
margin: 0;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
.dropin-table--mobile-layout-stacked .dropin-table__row-details__cell h1,
|
|
157
|
+
.dropin-table--mobile-layout-stacked .dropin-table__row-details__cell h2,
|
|
158
|
+
.dropin-table--mobile-layout-stacked .dropin-table__row-details__cell h3,
|
|
159
|
+
.dropin-table--mobile-layout-stacked .dropin-table__row-details__cell h4,
|
|
160
|
+
.dropin-table--mobile-layout-stacked .dropin-table__row-details__cell h5,
|
|
161
|
+
.dropin-table--mobile-layout-stacked .dropin-table__row-details__cell h6 {
|
|
162
|
+
font: var(--type-body-2-strong-font);
|
|
163
|
+
letter-spacing: var(--type-body-2-strong-letter-spacing);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
.dropin-table--mobile-layout-stacked .dropin-table__row-details__cell p,
|
|
167
|
+
.dropin-table--mobile-layout-stacked .dropin-table__row-details__cell span {
|
|
168
|
+
font: var(--type-body-2-default-font);
|
|
169
|
+
letter-spacing: var(--type-body-2-default-letter-spacing);
|
|
97
170
|
}
|
|
98
171
|
}
|
|
99
172
|
|
|
@@ -11,6 +11,10 @@
|
|
|
11
11
|
import type { Meta, StoryObj } from '@storybook/preact';
|
|
12
12
|
import { useState } from 'preact/hooks';
|
|
13
13
|
import { Table as TableComponent, TableProps } from '@adobe-commerce/elsie/components/Table';
|
|
14
|
+
import { ActionButton } from '@adobe-commerce/elsie/components/ActionButton';
|
|
15
|
+
import { ActionButtonGroup } from '@adobe-commerce/elsie/components/ActionButtonGroup';
|
|
16
|
+
import { Pagination } from '@adobe-commerce/elsie/components/Pagination';
|
|
17
|
+
import { Picker, type PickerOption } from '@adobe-commerce/elsie/components/Picker';
|
|
14
18
|
|
|
15
19
|
/**
|
|
16
20
|
* Use the `Table` component to render data in a structured table.
|
|
@@ -175,10 +179,10 @@ export const Table: Story = {
|
|
|
175
179
|
{ key: 'actions', label: 'Actions' },
|
|
176
180
|
],
|
|
177
181
|
rowData: [
|
|
178
|
-
{ name: 'John', email: 'john@example.com', age: 20, actions: <
|
|
179
|
-
{ name: 'Jane', email: 'jane@example.com', age: 21, actions: <
|
|
180
|
-
{ name: 'Jim', email: 'jim@example.com', age: 22, actions: <
|
|
181
|
-
{ name: 'Jill', email: 'jill@example.com', age: 23, actions: <
|
|
182
|
+
{ name: 'John', email: 'john@example.com', age: 20, actions: <ActionButton>Edit</ActionButton> },
|
|
183
|
+
{ name: 'Jane', email: 'jane@example.com', age: 21, actions: <ActionButton>Edit</ActionButton> },
|
|
184
|
+
{ name: 'Jim', email: 'jim@example.com', age: 22, actions: <ActionButton>Edit</ActionButton> },
|
|
185
|
+
{ name: 'Jill', email: 'jill@example.com', age: 23, actions: <ActionButton>Edit</ActionButton> },
|
|
182
186
|
],
|
|
183
187
|
},
|
|
184
188
|
};
|
|
@@ -212,11 +216,11 @@ export const AllSortable: Story = {
|
|
|
212
216
|
{ key: 'actions', label: 'Actions' },
|
|
213
217
|
],
|
|
214
218
|
rowData: [
|
|
215
|
-
{ name: 'John', email: 'john@example.com', age: 20, actions: <
|
|
216
|
-
{ name: 'Jane', email: 'jane@example.com', age: 21, actions: <
|
|
217
|
-
{ name: 'Jim', email: 'jim@example.com', age: 22, actions: <
|
|
218
|
-
{ name: 'Jill', email: 'jill@example.com', age: 23, actions: <
|
|
219
|
-
{ name: 'Jack', email: 'jack@example.com', age: 24, actions: <
|
|
219
|
+
{ name: 'John', email: 'john@example.com', age: 20, actions: <ActionButton>Edit</ActionButton> },
|
|
220
|
+
{ name: 'Jane', email: 'jane@example.com', age: 21, actions: <ActionButton>Edit</ActionButton> },
|
|
221
|
+
{ name: 'Jim', email: 'jim@example.com', age: 22, actions: <ActionButton>Edit</ActionButton> },
|
|
222
|
+
{ name: 'Jill', email: 'jill@example.com', age: 23, actions: <ActionButton>Edit</ActionButton> },
|
|
223
|
+
{ name: 'Jack', email: 'jack@example.com', age: 24, actions: <ActionButton>Edit</ActionButton> },
|
|
220
224
|
],
|
|
221
225
|
},
|
|
222
226
|
};
|
|
@@ -240,7 +244,7 @@ export const AllSortable: Story = {
|
|
|
240
244
|
* { key: 'actions', label: 'Actions' }
|
|
241
245
|
* ]}
|
|
242
246
|
* rowData={[
|
|
243
|
-
* { id: 1, name: 'John Doe', email: 'john@company.com', phone: '+1-555-0123', department: 'Engineering', position: 'Senior Developer', salary: '$95,000', startDate: '2022-01-15', status: 'Active', actions: <
|
|
247
|
+
* { id: 1, name: 'John Doe', email: 'john@company.com', phone: '+1-555-0123', department: 'Engineering', position: 'Senior Developer', salary: '$95,000', startDate: '2022-01-15', status: 'Active', actions: <ActionButton>Edit</ActionButton> }
|
|
244
248
|
* ]}
|
|
245
249
|
* />
|
|
246
250
|
* ```
|
|
@@ -270,7 +274,7 @@ export const WideTable: Story = {
|
|
|
270
274
|
salary: '$95,000',
|
|
271
275
|
startDate: '2022-01-15',
|
|
272
276
|
status: 'Active',
|
|
273
|
-
actions: <
|
|
277
|
+
actions: <ActionButton>Edit</ActionButton>
|
|
274
278
|
},
|
|
275
279
|
{
|
|
276
280
|
id: 2,
|
|
@@ -282,7 +286,7 @@ export const WideTable: Story = {
|
|
|
282
286
|
salary: '$78,000',
|
|
283
287
|
startDate: '2021-06-20',
|
|
284
288
|
status: 'Active',
|
|
285
|
-
actions: <
|
|
289
|
+
actions: <ActionButton>Edit</ActionButton>
|
|
286
290
|
},
|
|
287
291
|
{
|
|
288
292
|
id: 3,
|
|
@@ -294,7 +298,7 @@ export const WideTable: Story = {
|
|
|
294
298
|
salary: '$110,000',
|
|
295
299
|
startDate: '2020-03-10',
|
|
296
300
|
status: 'Active',
|
|
297
|
-
actions: <
|
|
301
|
+
actions: <ActionButton>Edit</ActionButton>
|
|
298
302
|
},
|
|
299
303
|
{
|
|
300
304
|
id: 4,
|
|
@@ -306,7 +310,7 @@ export const WideTable: Story = {
|
|
|
306
310
|
salary: '$65,000',
|
|
307
311
|
startDate: '2023-02-28',
|
|
308
312
|
status: 'Pending',
|
|
309
|
-
actions: <
|
|
313
|
+
actions: <ActionButton>Edit</ActionButton>
|
|
310
314
|
},
|
|
311
315
|
{
|
|
312
316
|
id: 5,
|
|
@@ -318,7 +322,7 @@ export const WideTable: Story = {
|
|
|
318
322
|
salary: '$72,000',
|
|
319
323
|
startDate: '2022-09-12',
|
|
320
324
|
status: 'Active',
|
|
321
|
-
actions: <
|
|
325
|
+
actions: <ActionButton>Edit</ActionButton>
|
|
322
326
|
},
|
|
323
327
|
],
|
|
324
328
|
},
|
|
@@ -341,7 +345,7 @@ export const WideTable: Story = {
|
|
|
341
345
|
* user: <div><strong>John Doe</strong><br/>john@example.com<br/>Senior Developer</div>,
|
|
342
346
|
* description: <div>Lead developer for the<br/>e-commerce platform<br/>with 5+ years experience</div>,
|
|
343
347
|
* status: <span>Active</span>,
|
|
344
|
-
* actions: <div><
|
|
348
|
+
* actions: <div><ActionButton>Edit</ActionButton><br/><ActionButton>Delete</ActionButton><br/><ActionButton>View</ActionButton></div>
|
|
345
349
|
* }
|
|
346
350
|
* ]}
|
|
347
351
|
* />
|
|
@@ -375,11 +379,11 @@ export const ComplexCells: Story = {
|
|
|
375
379
|
<span>Active</span>
|
|
376
380
|
),
|
|
377
381
|
actions: (
|
|
378
|
-
<
|
|
379
|
-
<
|
|
380
|
-
<
|
|
381
|
-
<
|
|
382
|
-
</
|
|
382
|
+
<ActionButtonGroup>
|
|
383
|
+
<ActionButton value="edit">Edit</ActionButton>
|
|
384
|
+
<ActionButton value="delete">Delete</ActionButton>
|
|
385
|
+
<ActionButton value="view">View</ActionButton>
|
|
386
|
+
</ActionButtonGroup>
|
|
383
387
|
),
|
|
384
388
|
},
|
|
385
389
|
{
|
|
@@ -401,11 +405,11 @@ export const ComplexCells: Story = {
|
|
|
401
405
|
<span>Pending</span>
|
|
402
406
|
),
|
|
403
407
|
actions: (
|
|
404
|
-
<
|
|
405
|
-
<
|
|
406
|
-
<
|
|
407
|
-
<
|
|
408
|
-
</
|
|
408
|
+
<ActionButtonGroup>
|
|
409
|
+
<ActionButton value="edit">Edit</ActionButton>
|
|
410
|
+
<ActionButton value="approve">Approve</ActionButton>
|
|
411
|
+
<ActionButton value="reject">Reject</ActionButton>
|
|
412
|
+
</ActionButtonGroup>
|
|
409
413
|
),
|
|
410
414
|
},
|
|
411
415
|
{
|
|
@@ -427,11 +431,11 @@ export const ComplexCells: Story = {
|
|
|
427
431
|
<span>Inactive</span>
|
|
428
432
|
),
|
|
429
433
|
actions: (
|
|
430
|
-
<
|
|
431
|
-
<
|
|
432
|
-
<
|
|
433
|
-
<
|
|
434
|
-
</
|
|
434
|
+
<ActionButtonGroup>
|
|
435
|
+
<ActionButton value="edit">Edit</ActionButton>
|
|
436
|
+
<ActionButton value="activate">Activate</ActionButton>
|
|
437
|
+
<ActionButton value="archive">Archive</ActionButton>
|
|
438
|
+
</ActionButtonGroup>
|
|
435
439
|
),
|
|
436
440
|
},
|
|
437
441
|
],
|
|
@@ -476,10 +480,10 @@ export const StackedMobileLayout: Story = {
|
|
|
476
480
|
{ key: 'actions', label: 'Actions' },
|
|
477
481
|
],
|
|
478
482
|
rowData: [
|
|
479
|
-
{ name: 'John Doe', email: 'john.doe@example.com', age: 28, status: 'Active', actions: <
|
|
480
|
-
{ name: 'Jane Smith', email: 'jane.smith@example.com', age: 32, status: 'Inactive', actions: <
|
|
481
|
-
{ name: 'Bob Johnson', email: 'bob.johnson@example.com', age: 45, status: 'Active', actions: <
|
|
482
|
-
{ name: 'Alice Brown', email: 'alice.brown@example.com', age: 29, status: 'Pending', actions: <
|
|
483
|
+
{ name: 'John Doe', email: 'john.doe@example.com', age: 28, status: 'Active', actions: <ActionButton>Edit</ActionButton> },
|
|
484
|
+
{ name: 'Jane Smith', email: 'jane.smith@example.com', age: 32, status: 'Inactive', actions: <ActionButton>Edit</ActionButton> },
|
|
485
|
+
{ name: 'Bob Johnson', email: 'bob.johnson@example.com', age: 45, status: 'Active', actions: <ActionButton>Edit</ActionButton> },
|
|
486
|
+
{ name: 'Alice Brown', email: 'alice.brown@example.com', age: 29, status: 'Pending', actions: <ActionButton>Edit</ActionButton> },
|
|
483
487
|
],
|
|
484
488
|
},
|
|
485
489
|
};
|
|
@@ -520,7 +524,7 @@ export const StackedMobileLayout: Story = {
|
|
|
520
524
|
* {
|
|
521
525
|
* name: 'John',
|
|
522
526
|
* email: 'john@example.com',
|
|
523
|
-
* actions: <
|
|
527
|
+
* actions: <ActionButton onClick={() => toggleRow(0)}>Toggle Details</ActionButton>,
|
|
524
528
|
* _rowDetails: <div>Additional information...</div>
|
|
525
529
|
* }
|
|
526
530
|
* ]}
|
|
@@ -550,22 +554,22 @@ export const RowDetails: Story = {
|
|
|
550
554
|
email: 'john.doe@company.com',
|
|
551
555
|
status: 'Active',
|
|
552
556
|
actions: (
|
|
553
|
-
<
|
|
557
|
+
<ActionButton onClick={() => toggleRow(0)}>
|
|
554
558
|
{expandedRows.has(0) ? 'Hide' : 'Show'}
|
|
555
|
-
</
|
|
559
|
+
</ActionButton>
|
|
556
560
|
),
|
|
557
561
|
_rowDetails: (
|
|
558
|
-
|
|
562
|
+
<>
|
|
559
563
|
<h3>Employee Details</h3>
|
|
560
564
|
<p><strong>Department:</strong> Engineering</p>
|
|
561
565
|
<p><strong>Position:</strong> Senior Developer</p>
|
|
562
566
|
<p><strong>Start Date:</strong> January 15, 2022</p>
|
|
563
567
|
<p><strong>Notes:</strong> Excellent performance, leads the frontend team.</p>
|
|
564
568
|
<div style={{ marginTop: '12px' }}>
|
|
565
|
-
<
|
|
566
|
-
<
|
|
569
|
+
<ActionButton style={{ marginRight: '8px' }}>Update Details</ActionButton>
|
|
570
|
+
<ActionButton>View Full Profile</ActionButton>
|
|
567
571
|
</div>
|
|
568
|
-
|
|
572
|
+
</>
|
|
569
573
|
)
|
|
570
574
|
},
|
|
571
575
|
{
|
|
@@ -573,22 +577,22 @@ export const RowDetails: Story = {
|
|
|
573
577
|
email: 'jane.smith@company.com',
|
|
574
578
|
status: 'Pending',
|
|
575
579
|
actions: (
|
|
576
|
-
<
|
|
580
|
+
<ActionButton onClick={() => toggleRow(1)}>
|
|
577
581
|
{expandedRows.has(1) ? 'Hide' : 'Show'}
|
|
578
|
-
</
|
|
582
|
+
</ActionButton>
|
|
579
583
|
),
|
|
580
584
|
_rowDetails: (
|
|
581
|
-
|
|
585
|
+
<>
|
|
582
586
|
<h3>Pending Approval</h3>
|
|
583
587
|
<p><strong>Department:</strong> Marketing</p>
|
|
584
588
|
<p><strong>Position:</strong> Marketing Manager</p>
|
|
585
589
|
<p><strong>Application Date:</strong> December 1, 2024</p>
|
|
586
590
|
<p><strong>Status:</strong> Awaiting HR approval</p>
|
|
587
591
|
<div style={{ marginTop: '12px' }}>
|
|
588
|
-
<
|
|
589
|
-
<
|
|
592
|
+
<ActionButton style={{ marginRight: '8px', backgroundColor: '#22c55e', color: 'white', border: 'none', padding: '6px 12px', borderRadius: '4px' }}>Approve</ActionButton>
|
|
593
|
+
<ActionButton style={{ backgroundColor: '#ef4444', color: 'white', border: 'none', padding: '6px 12px', borderRadius: '4px' }}>Reject</ActionButton>
|
|
590
594
|
</div>
|
|
591
|
-
|
|
595
|
+
</>
|
|
592
596
|
)
|
|
593
597
|
},
|
|
594
598
|
{
|
|
@@ -596,22 +600,22 @@ export const RowDetails: Story = {
|
|
|
596
600
|
email: 'bob.johnson@company.com',
|
|
597
601
|
status: 'Inactive',
|
|
598
602
|
actions: (
|
|
599
|
-
<
|
|
603
|
+
<ActionButton onClick={() => toggleRow(2)}>
|
|
600
604
|
{expandedRows.has(2) ? 'Hide' : 'Show'}
|
|
601
|
-
</
|
|
605
|
+
</ActionButton>
|
|
602
606
|
),
|
|
603
607
|
_rowDetails: (
|
|
604
|
-
|
|
608
|
+
<>
|
|
605
609
|
<h3>Account Information</h3>
|
|
606
610
|
<p><strong>Department:</strong> Sales</p>
|
|
607
611
|
<p><strong>Position:</strong> Sales Director</p>
|
|
608
612
|
<p><strong>Last Active:</strong> November 20, 2024</p>
|
|
609
613
|
<p><strong>Reason:</strong> On extended leave</p>
|
|
610
614
|
<div style={{ marginTop: '12px' }}>
|
|
611
|
-
<
|
|
612
|
-
<
|
|
615
|
+
<ActionButton style={{ marginRight: '8px' }}>Reactivate Account</ActionButton>
|
|
616
|
+
<ActionButton>Contact Employee</ActionButton>
|
|
613
617
|
</div>
|
|
614
|
-
|
|
618
|
+
</>
|
|
615
619
|
)
|
|
616
620
|
},
|
|
617
621
|
];
|
|
@@ -704,14 +708,17 @@ export const VNodeLabels: Story = {
|
|
|
704
708
|
<strong>👤 User Name</strong>
|
|
705
709
|
</span>
|
|
706
710
|
),
|
|
711
|
+
ariaLabel: 'User Name',
|
|
707
712
|
},
|
|
708
713
|
{
|
|
709
714
|
key: 'email',
|
|
710
715
|
label: <span style={{ color: '#0066cc' }}>📧 Email Address</span>,
|
|
716
|
+
ariaLabel: 'Email Address',
|
|
711
717
|
},
|
|
712
718
|
{
|
|
713
719
|
key: 'role',
|
|
714
720
|
label: <em style={{ color: '#666' }}>Role & Department</em>,
|
|
721
|
+
ariaLabel: 'Role & Department',
|
|
715
722
|
},
|
|
716
723
|
{
|
|
717
724
|
key: 'status',
|
|
@@ -727,10 +734,12 @@ export const VNodeLabels: Story = {
|
|
|
727
734
|
📊 Status
|
|
728
735
|
</span>
|
|
729
736
|
),
|
|
737
|
+
ariaLabel: 'Status',
|
|
730
738
|
},
|
|
731
739
|
{
|
|
732
740
|
key: 'actions',
|
|
733
741
|
label: <span>⚙️ Actions</span>,
|
|
742
|
+
ariaLabel: 'Actions',
|
|
734
743
|
},
|
|
735
744
|
],
|
|
736
745
|
rowData: [
|
|
@@ -739,23 +748,277 @@ export const VNodeLabels: Story = {
|
|
|
739
748
|
email: 'john.doe@company.com',
|
|
740
749
|
role: 'Senior Developer',
|
|
741
750
|
status: 'Active',
|
|
742
|
-
actions: <
|
|
751
|
+
actions: <ActionButton>Edit</ActionButton>,
|
|
743
752
|
},
|
|
744
753
|
{
|
|
745
754
|
name: 'Jane Smith',
|
|
746
755
|
email: 'jane.smith@company.com',
|
|
747
756
|
role: 'Product Manager',
|
|
748
757
|
status: 'Active',
|
|
749
|
-
actions: <
|
|
758
|
+
actions: <ActionButton>Edit</ActionButton>,
|
|
750
759
|
},
|
|
751
760
|
{
|
|
752
761
|
name: 'Bob Johnson',
|
|
753
762
|
email: 'bob.johnson@company.com',
|
|
754
763
|
role: 'UX Designer',
|
|
755
764
|
status: 'Inactive',
|
|
756
|
-
actions: <
|
|
765
|
+
actions: <ActionButton>Edit</ActionButton>,
|
|
757
766
|
},
|
|
758
767
|
],
|
|
759
768
|
},
|
|
760
769
|
};
|
|
761
770
|
|
|
771
|
+
/**
|
|
772
|
+
* Table with pagination to navigate through multiple pages of data.
|
|
773
|
+
* This demonstrates how to integrate the Pagination component with the Table component.
|
|
774
|
+
*
|
|
775
|
+
* **Features**:
|
|
776
|
+
* - Pagination controls below the table
|
|
777
|
+
* - Page state management with useState
|
|
778
|
+
* - Dynamic row data based on current page
|
|
779
|
+
* - Items per page configuration
|
|
780
|
+
*
|
|
781
|
+
* ```tsx
|
|
782
|
+
* const [currentPage, setCurrentPage] = useState(1);
|
|
783
|
+
* const itemsPerPage = 5;
|
|
784
|
+
* const totalItems = 50;
|
|
785
|
+
* const totalPages = Math.ceil(totalItems / itemsPerPage);
|
|
786
|
+
*
|
|
787
|
+
* const paginatedData = allData.slice(
|
|
788
|
+
* (currentPage - 1) * itemsPerPage,
|
|
789
|
+
* currentPage * itemsPerPage
|
|
790
|
+
* );
|
|
791
|
+
*
|
|
792
|
+
* <div>
|
|
793
|
+
* <Table
|
|
794
|
+
* columns={columns}
|
|
795
|
+
* rowData={paginatedData}
|
|
796
|
+
* />
|
|
797
|
+
* <Pagination
|
|
798
|
+
* currentPage={currentPage}
|
|
799
|
+
* totalPages={totalPages}
|
|
800
|
+
* onChange={setCurrentPage}
|
|
801
|
+
* />
|
|
802
|
+
* </div>
|
|
803
|
+
* ```
|
|
804
|
+
*/
|
|
805
|
+
export const WithPagination: Story = {
|
|
806
|
+
render: (args) => {
|
|
807
|
+
const [currentPage, setCurrentPage] = useState(1);
|
|
808
|
+
const [pageSize, setPageSize] = useState(5);
|
|
809
|
+
|
|
810
|
+
// Page size options
|
|
811
|
+
const pageSizeOptions: PickerOption[] = [
|
|
812
|
+
{ value: '5', text: '5' },
|
|
813
|
+
{ value: '10', text: '10' },
|
|
814
|
+
{ value: '15', text: '15' },
|
|
815
|
+
];
|
|
816
|
+
|
|
817
|
+
// Generate sample data (287 items to match screenshot)
|
|
818
|
+
const allData = Array.from({ length: 287 }, (_, index) => ({
|
|
819
|
+
id: index + 1,
|
|
820
|
+
name: `User ${index + 1}`,
|
|
821
|
+
email: `user${index + 1}@example.com`,
|
|
822
|
+
department: ['Engineering', 'Marketing', 'Sales', 'HR', 'Finance'][index % 5],
|
|
823
|
+
status: ['Active', 'Inactive', 'Pending'][index % 3],
|
|
824
|
+
actions: <ActionButton>Edit</ActionButton>,
|
|
825
|
+
}));
|
|
826
|
+
|
|
827
|
+
const totalPages = Math.ceil(allData.length / pageSize);
|
|
828
|
+
|
|
829
|
+
// Calculate item range
|
|
830
|
+
const startItem = (currentPage - 1) * pageSize + 1;
|
|
831
|
+
const endItem = Math.min(currentPage * pageSize, allData.length);
|
|
832
|
+
const totalItems = allData.length;
|
|
833
|
+
|
|
834
|
+
// Get current page data
|
|
835
|
+
const paginatedData = allData.slice(
|
|
836
|
+
(currentPage - 1) * pageSize,
|
|
837
|
+
currentPage * pageSize
|
|
838
|
+
);
|
|
839
|
+
|
|
840
|
+
// Handle page size change
|
|
841
|
+
const handlePageSizeChange = (event: Event) => {
|
|
842
|
+
const target = event.target as HTMLSelectElement;
|
|
843
|
+
const newPageSize = Number(target.value);
|
|
844
|
+
setPageSize(newPageSize);
|
|
845
|
+
setCurrentPage(1); // Reset to first page when page size changes
|
|
846
|
+
};
|
|
847
|
+
|
|
848
|
+
return (
|
|
849
|
+
<div>
|
|
850
|
+
<TableComponent
|
|
851
|
+
{...args}
|
|
852
|
+
columns={[
|
|
853
|
+
{ key: 'id', label: 'ID' },
|
|
854
|
+
{ key: 'name', label: 'Name' },
|
|
855
|
+
{ key: 'email', label: 'Email' },
|
|
856
|
+
{ key: 'department', label: 'Department' },
|
|
857
|
+
{ key: 'status', label: 'Status' },
|
|
858
|
+
{ key: 'actions', label: 'Actions' },
|
|
859
|
+
]}
|
|
860
|
+
rowData={paginatedData}
|
|
861
|
+
/>
|
|
862
|
+
<div style={{ marginTop: 'var(--spacing-small)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
|
863
|
+
<span style={{
|
|
864
|
+
font: 'var(--type-body-1-default-font)',
|
|
865
|
+
letterSpacing: 'var(--type-body-1-default-letter-spacing)',
|
|
866
|
+
color: 'var(--color-neutral-800)'
|
|
867
|
+
}}>
|
|
868
|
+
Items {startItem} to {endItem} of {totalItems} total
|
|
869
|
+
</span>
|
|
870
|
+
<Pagination
|
|
871
|
+
currentPage={currentPage}
|
|
872
|
+
totalPages={totalPages}
|
|
873
|
+
onChange={setCurrentPage}
|
|
874
|
+
/>
|
|
875
|
+
<div style={{
|
|
876
|
+
display: 'flex',
|
|
877
|
+
alignItems: 'center',
|
|
878
|
+
gap: 'var(--spacing-xsmall)',
|
|
879
|
+
font: 'var(--type-body-1-default-font)',
|
|
880
|
+
letterSpacing: 'var(--type-body-1-default-letter-spacing)',
|
|
881
|
+
color: 'var(--color-neutral-800)'
|
|
882
|
+
}}>
|
|
883
|
+
<span>Show</span>
|
|
884
|
+
<Picker
|
|
885
|
+
variant="primary"
|
|
886
|
+
size="medium"
|
|
887
|
+
value={String(pageSize)}
|
|
888
|
+
options={pageSizeOptions}
|
|
889
|
+
handleSelect={handlePageSizeChange}
|
|
890
|
+
aria-label="Items per page"
|
|
891
|
+
/>
|
|
892
|
+
</div>
|
|
893
|
+
</div>
|
|
894
|
+
</div>
|
|
895
|
+
);
|
|
896
|
+
},
|
|
897
|
+
};
|
|
898
|
+
|
|
899
|
+
/**
|
|
900
|
+
* Table with expandable row details and stacked mobile layout.
|
|
901
|
+
* Combines the expandable rows feature with responsive mobile behavior using container queries.
|
|
902
|
+
*
|
|
903
|
+
* **Features**:
|
|
904
|
+
* - Expandable rows with toggle buttons
|
|
905
|
+
* - Stacked mobile layout when container width ≤ 600px
|
|
906
|
+
* - Row details expand in both desktop and mobile views
|
|
907
|
+
* - Mobile view shows labels above each cell value
|
|
908
|
+
*
|
|
909
|
+
* ```tsx
|
|
910
|
+
* const [expandedRows, setExpandedRows] = useState(new Set());
|
|
911
|
+
*
|
|
912
|
+
* const toggleRow = (rowIndex: number) => {
|
|
913
|
+
* setExpandedRows(prev => {
|
|
914
|
+
* const newSet = new Set(prev);
|
|
915
|
+
* if (newSet.has(rowIndex)) {
|
|
916
|
+
* newSet.delete(rowIndex);
|
|
917
|
+
* } else {
|
|
918
|
+
* newSet.add(rowIndex);
|
|
919
|
+
* }
|
|
920
|
+
* return newSet;
|
|
921
|
+
* });
|
|
922
|
+
* };
|
|
923
|
+
*
|
|
924
|
+
* <Table
|
|
925
|
+
* mobileLayout="stacked"
|
|
926
|
+
* columns={columns}
|
|
927
|
+
* rowData={rowDataWithDetails}
|
|
928
|
+
* expandedRows={expandedRows}
|
|
929
|
+
* />
|
|
930
|
+
* ```
|
|
931
|
+
*/
|
|
932
|
+
export const ExpandableRowsWithMobileLayout: Story = {
|
|
933
|
+
render: (args) => {
|
|
934
|
+
const [expandedRows, setExpandedRows] = useState(new Set<number>());
|
|
935
|
+
|
|
936
|
+
const toggleRow = (rowIndex: number) => {
|
|
937
|
+
setExpandedRows((prev) => {
|
|
938
|
+
const newSet = new Set(prev);
|
|
939
|
+
if (newSet.has(rowIndex)) {
|
|
940
|
+
newSet.delete(rowIndex);
|
|
941
|
+
} else {
|
|
942
|
+
newSet.add(rowIndex);
|
|
943
|
+
}
|
|
944
|
+
return newSet;
|
|
945
|
+
});
|
|
946
|
+
};
|
|
947
|
+
|
|
948
|
+
const rowData = [
|
|
949
|
+
{
|
|
950
|
+
name: 'John Doe',
|
|
951
|
+
email: 'john.doe@company.com',
|
|
952
|
+
status: 'Active',
|
|
953
|
+
actions: (
|
|
954
|
+
<ActionButton onClick={() => toggleRow(0)}>
|
|
955
|
+
{expandedRows.has(0) ? 'Hide' : 'Show'}
|
|
956
|
+
</ActionButton>
|
|
957
|
+
),
|
|
958
|
+
_rowDetails: (
|
|
959
|
+
<>
|
|
960
|
+
<h3>Employee Details</h3>
|
|
961
|
+
<p><strong>Department:</strong> Engineering</p>
|
|
962
|
+
<p><strong>Position:</strong> Senior Developer</p>
|
|
963
|
+
<p><strong>Start Date:</strong> January 15, 2022</p>
|
|
964
|
+
<p><strong>Notes:</strong> Excellent performance, leads the frontend team.</p>
|
|
965
|
+
</>
|
|
966
|
+
)
|
|
967
|
+
},
|
|
968
|
+
{
|
|
969
|
+
name: 'Jane Smith',
|
|
970
|
+
email: 'jane.smith@company.com',
|
|
971
|
+
status: 'Pending',
|
|
972
|
+
actions: (
|
|
973
|
+
<ActionButton onClick={() => toggleRow(1)}>
|
|
974
|
+
{expandedRows.has(1) ? 'Hide' : 'Show'}
|
|
975
|
+
</ActionButton>
|
|
976
|
+
),
|
|
977
|
+
_rowDetails: (
|
|
978
|
+
<>
|
|
979
|
+
<h3>Pending Approval</h3>
|
|
980
|
+
<p><strong>Department:</strong> Marketing</p>
|
|
981
|
+
<p><strong>Position:</strong> Marketing Manager</p>
|
|
982
|
+
<p><strong>Application Date:</strong> December 1, 2024</p>
|
|
983
|
+
<p><strong>Status:</strong> Awaiting HR approval</p>
|
|
984
|
+
</>
|
|
985
|
+
)
|
|
986
|
+
},
|
|
987
|
+
{
|
|
988
|
+
name: 'Bob Johnson',
|
|
989
|
+
email: 'bob.johnson@company.com',
|
|
990
|
+
status: 'Inactive',
|
|
991
|
+
actions: (
|
|
992
|
+
<ActionButton onClick={() => toggleRow(2)}>
|
|
993
|
+
{expandedRows.has(2) ? 'Hide' : 'Show'}
|
|
994
|
+
</ActionButton>
|
|
995
|
+
),
|
|
996
|
+
_rowDetails: (
|
|
997
|
+
<>
|
|
998
|
+
<h3>Account Information</h3>
|
|
999
|
+
<p><strong>Department:</strong> Sales</p>
|
|
1000
|
+
<p><strong>Position:</strong> Sales Director</p>
|
|
1001
|
+
<p><strong>Last Active:</strong> November 20, 2024</p>
|
|
1002
|
+
<p><strong>Reason:</strong> On extended leave</p>
|
|
1003
|
+
</>
|
|
1004
|
+
)
|
|
1005
|
+
},
|
|
1006
|
+
];
|
|
1007
|
+
|
|
1008
|
+
return (
|
|
1009
|
+
<TableComponent
|
|
1010
|
+
{...args}
|
|
1011
|
+
mobileLayout="stacked"
|
|
1012
|
+
columns={[
|
|
1013
|
+
{ key: 'name', label: 'Name', ariaLabel: 'Name' },
|
|
1014
|
+
{ key: 'email', label: 'Email', ariaLabel: 'Email' },
|
|
1015
|
+
{ key: 'status', label: 'Status', ariaLabel: 'Status' },
|
|
1016
|
+
{ key: 'actions', label: 'Actions', ariaLabel: 'Actions' },
|
|
1017
|
+
]}
|
|
1018
|
+
rowData={rowData}
|
|
1019
|
+
expandedRows={expandedRows}
|
|
1020
|
+
/>
|
|
1021
|
+
);
|
|
1022
|
+
},
|
|
1023
|
+
};
|
|
1024
|
+
|
|
@@ -97,7 +97,8 @@ export const Table: FunctionComponent<TableProps> = ({
|
|
|
97
97
|
iconSource = 'ChevronDown';
|
|
98
98
|
ariaLabel = translations.sortedDescending.replace('{label}', label);
|
|
99
99
|
} else {
|
|
100
|
-
|
|
100
|
+
// Show chevron down when sortable but not sorted
|
|
101
|
+
iconSource = 'ChevronDown';
|
|
101
102
|
ariaLabel = translations.sortBy.replace('{label}', label);
|
|
102
103
|
}
|
|
103
104
|
|
|
@@ -138,7 +139,10 @@ export const Table: FunctionComponent<TableProps> = ({
|
|
|
138
139
|
|
|
139
140
|
return (
|
|
140
141
|
<Fragment key={rowIndex}>
|
|
141
|
-
<tr className=
|
|
142
|
+
<tr className={classes([
|
|
143
|
+
'dropin-table__body__row',
|
|
144
|
+
['dropin-table__body__row--expanded', isExpanded && hasDetails],
|
|
145
|
+
])}>
|
|
142
146
|
{columns.map((column) => {
|
|
143
147
|
const cell = row[column.key];
|
|
144
148
|
const label = column.ariaLabel ?? column.label;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/********************************************************************
|
|
2
|
+
* Copyright 2025 Adobe
|
|
3
|
+
* All Rights Reserved.
|
|
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.
|
|
8
|
+
*******************************************************************/
|
|
9
|
+
|
|
10
|
+
import { getGlobalLocale } from '@adobe-commerce/elsie/lib';
|
|
11
|
+
|
|
12
|
+
export interface PriceFormatterOptions {
|
|
13
|
+
currency?: string | null;
|
|
14
|
+
locale?: string;
|
|
15
|
+
formatOptions?: Intl.NumberFormatOptions;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Determines the effective locale to use for price formatting
|
|
20
|
+
* Priority: prop locale > global locale > browser locale > default 'en-US'
|
|
21
|
+
*/
|
|
22
|
+
export function getEffectiveLocale(locale?: string): string {
|
|
23
|
+
if (locale) {
|
|
24
|
+
return locale;
|
|
25
|
+
}
|
|
26
|
+
const globalLocale = getGlobalLocale();
|
|
27
|
+
if (globalLocale) {
|
|
28
|
+
return globalLocale;
|
|
29
|
+
}
|
|
30
|
+
// Fallback to browser locale or default
|
|
31
|
+
return process.env.LOCALE && process.env.LOCALE !== 'undefined' ? process.env.LOCALE : 'en-US';
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Gets an Intl.NumberFormat instance for price formatting
|
|
36
|
+
* Uses getEffectiveLocale internally to determine the best locale
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* // Single price formatting
|
|
40
|
+
* const formatter = getPriceFormatter({ currency: 'USD', locale: 'en-US' });
|
|
41
|
+
* const price = formatter.format(10.99); // "$10.99"
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* // Bulk price formatting (more efficient)
|
|
45
|
+
* const formatter = getPriceFormatter({ currency: 'EUR', locale: 'fr-FR' });
|
|
46
|
+
* const prices = [10.99, 25.50, 99.99].map(amount => formatter.format(amount));
|
|
47
|
+
*/
|
|
48
|
+
export function getPriceFormatter(
|
|
49
|
+
options: PriceFormatterOptions = {}
|
|
50
|
+
): Intl.NumberFormat {
|
|
51
|
+
const { currency, locale, formatOptions = {} } = options;
|
|
52
|
+
const effectiveLocale = getEffectiveLocale(locale);
|
|
53
|
+
|
|
54
|
+
const params: Intl.NumberFormatOptions = {
|
|
55
|
+
style: 'currency',
|
|
56
|
+
currency: currency || 'USD',
|
|
57
|
+
// These options are needed to round to whole numbers if that's what you want.
|
|
58
|
+
minimumFractionDigits: 2, // (this suffices for whole numbers, but will print 2500.10 as $2,500.1)
|
|
59
|
+
maximumFractionDigits: 2, // (causes 2500.99 to be printed as $2,501)
|
|
60
|
+
...formatOptions,
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
try {
|
|
64
|
+
return new Intl.NumberFormat(effectiveLocale, params);
|
|
65
|
+
} catch (error) {
|
|
66
|
+
console.error(`Error creating Intl.NumberFormat instance for locale ${effectiveLocale}. Falling back to en-US.`, error);
|
|
67
|
+
return new Intl.NumberFormat('en-US', params);
|
|
68
|
+
}
|
|
69
|
+
}
|
package/src/lib/index.ts
CHANGED
|
@@ -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/lib/form-values';
|
|
@@ -25,3 +25,4 @@ export * from '@adobe-commerce/elsie/lib/is-number';
|
|
|
25
25
|
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
|
+
export * from '@adobe-commerce/elsie/lib/get-price-formatter';
|