@sonic-equipment/ui 212.0.0 → 214.0.0
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/dist/authentication/authenticated-container.d.ts +9 -0
- package/dist/authentication/authenticated-container.js +21 -0
- package/dist/collapsables/accordion/accordion-item.js +1 -1
- package/dist/collapsables/show-all/show-all.js +1 -1
- package/dist/exports.d.ts +1 -0
- package/dist/header/buttons/account/connected-account-button.js +1 -1
- package/dist/index.js +1 -0
- package/dist/navigation/account-icon/account-icon.js +1 -1
- package/dist/pages/my-sonic/pages/order-history/order-history.js +8 -5
- package/dist/pages/my-sonic/widgets/connected-address-book-widget.js +10 -6
- package/dist/sidebar/sidebar.js +1 -1
- package/dist/styles.css +18 -10
- package/dist/table/data-table.d.ts +8 -1
- package/dist/table/data-table.js +6 -6
- package/dist/table/elements/table-sort-button.js +1 -1
- package/dist/table/elements/td.d.ts +1 -0
- package/dist/table/elements/td.js +1 -1
- package/dist/table/elements/tr.d.ts +1 -1
- package/dist/table/elements/tr.js +2 -2
- package/dist/table/elements/types.d.ts +1 -0
- package/package.json +2 -5
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
export declare function AuthenticatedContainer({ children, onUnauthenticated, views, }: {
|
|
3
|
+
children: React.ReactNode;
|
|
4
|
+
onUnauthenticated?: () => void;
|
|
5
|
+
views?: {
|
|
6
|
+
unauthenticated?: ReactNode;
|
|
7
|
+
undetermined?: ReactNode;
|
|
8
|
+
};
|
|
9
|
+
}): string | number | boolean | import("react/jsx-runtime").JSX.Element | Iterable<ReactNode> | null;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, Fragment } from 'react/jsx-runtime';
|
|
3
|
+
import { useRef, useEffect } from 'react';
|
|
4
|
+
import { useIsAuthenticated } from '../shared/api/storefront/hooks/authentication/use-is-authenticated.js';
|
|
5
|
+
|
|
6
|
+
function AuthenticatedContainer({ children, onUnauthenticated, views, }) {
|
|
7
|
+
const isAuthenticated = useIsAuthenticated();
|
|
8
|
+
const wasAuthenticated = useRef(Boolean(isAuthenticated));
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
if (wasAuthenticated.current === true && isAuthenticated === false)
|
|
11
|
+
onUnauthenticated?.();
|
|
12
|
+
wasAuthenticated.current = isAuthenticated || false;
|
|
13
|
+
}, [isAuthenticated, onUnauthenticated]);
|
|
14
|
+
if (isAuthenticated === false)
|
|
15
|
+
return views?.unauthenticated ?? null;
|
|
16
|
+
if (isAuthenticated === undefined)
|
|
17
|
+
return views?.undetermined ?? null;
|
|
18
|
+
return jsx(Fragment, { children: children });
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export { AuthenticatedContainer };
|
|
@@ -29,7 +29,7 @@ function AccordionItem({ _pseudo = 'none', allowCollapse = true, allowToggle = t
|
|
|
29
29
|
}), disabled: isDisabled, id: id, onClick: () => {
|
|
30
30
|
if (allowToggle && allowCollapse)
|
|
31
31
|
toggle();
|
|
32
|
-
}, tabIndex: allowToggle ? 0 : -1, type: "button", children: [title, jsx("span", { className: styles.icon, children: size === 'lg' ? (jsx(GlyphsChevronsBoldDownIcon, {})) : (jsx(GlyphsChevronsSlimDownIcon, {})) })] }) }), jsx("div", { "aria-hidden": !isOpen, "aria-labelledby": id, className: styles.panel, id: panelId, inert: isOpen ? undefined :
|
|
32
|
+
}, tabIndex: allowToggle ? 0 : -1, type: "button", children: [title, jsx("span", { className: styles.icon, children: size === 'lg' ? (jsx(GlyphsChevronsBoldDownIcon, {})) : (jsx(GlyphsChevronsSlimDownIcon, {})) })] }) }), jsx("div", { "aria-hidden": !isOpen, "aria-labelledby": id, className: styles.panel, id: panelId, inert: isOpen ? undefined : true, role: "region", children: children })] }));
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
export { AccordionItem };
|
|
@@ -23,7 +23,7 @@ function ShowAll({ children, hasTransparency = true, initialHeight = 0, initialI
|
|
|
23
23
|
[styles['is-open']]: isReallyOpen,
|
|
24
24
|
}), style: contentFits ? undefined : { '--initial-height': `${initialHeight}px` }, children: [jsx("div", { className: styles.panel, children: jsx("div", { className: clsx(styles.content, {
|
|
25
25
|
[styles['has-transparency']]: !contentFits && hasTransparency,
|
|
26
|
-
}), children: jsx("div", { ref: ref, "aria-hidden": !isReallyOpen, inert: isReallyOpen ? undefined :
|
|
26
|
+
}), children: jsx("div", { ref: ref, "aria-hidden": !isReallyOpen, inert: isReallyOpen ? undefined : true, children: children }) }) }), !contentFits && (jsxs(Link, { className: styles.button, color: "secondary", onClick: () => {
|
|
27
27
|
if (isControlled)
|
|
28
28
|
return onToggle(!isControlled);
|
|
29
29
|
toggle();
|
package/dist/exports.d.ts
CHANGED
|
@@ -26,6 +26,7 @@ export * from './algolia/use-algolia-insights';
|
|
|
26
26
|
export * from './algolia/use-algolia-insights-provider-global-state';
|
|
27
27
|
export * from './algolia/use-algolia-instant-search-state';
|
|
28
28
|
export * from './algolia/use-algolia-search';
|
|
29
|
+
export * from './authentication/authenticated-container';
|
|
29
30
|
export * from './background-overlay/background-overlay';
|
|
30
31
|
export * from './background-overlay/background-overlay-manager';
|
|
31
32
|
export * from './badges/badge/badge';
|
|
@@ -14,7 +14,7 @@ function ConnectedAccountButton({ className, 'data-test-selector': dataTestSelec
|
|
|
14
14
|
const { href } = useLocation();
|
|
15
15
|
return (jsx(IconButton, { className: className, "data-authenticated": isAuthenticated ? true : false, "data-test-selector": dataTestSelector, href: isAuthenticated
|
|
16
16
|
? paths.ACCOUNT
|
|
17
|
-
: `${paths.SIGN_IN}${href ? `?returnUrl=${encodeURIComponent(href)}` : ''}`, onClick: onClick, children: jsx(AccountIcon, { "aria-label": isAuthenticated ? t('My Sonic') : t('Sign in or create account'), isAuthenticated: isAuthenticated }) }));
|
|
17
|
+
: `${paths.SIGN_IN}${href ? `?returnUrl=${encodeURIComponent(href)}` : ''}`, isDisabled: isAuthenticated === undefined, onClick: onClick, children: jsx(AccountIcon, { "aria-label": isAuthenticated ? t('My Sonic') : t('Sign in or create account'), isAuthenticated: isAuthenticated }) }));
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
export { ConnectedAccountButton };
|
package/dist/index.js
CHANGED
|
@@ -31,6 +31,7 @@ export { useAlgoliaInsights } from './algolia/use-algolia-insights.js';
|
|
|
31
31
|
export { useAlgoliaInsightsGlobalState } from './algolia/use-algolia-insights-provider-global-state.js';
|
|
32
32
|
export { useAlgoliaInstantSearchState, useAlgoliaInstantSearchStateIndex, useAlgoliaInstantSearchStateOnline, useAlgoliaInstantSearchStateQueryId, useAlgoliaInstantSearchStateStatus } from './algolia/use-algolia-instant-search-state.js';
|
|
33
33
|
export { useAlgoliaSearch } from './algolia/use-algolia-search.js';
|
|
34
|
+
export { AuthenticatedContainer } from './authentication/authenticated-container.js';
|
|
34
35
|
export { BackgroundOverlay } from './background-overlay/background-overlay.js';
|
|
35
36
|
export { BackgroundOverlayManager } from './background-overlay/background-overlay-manager.js';
|
|
36
37
|
export { Badge } from './badges/badge/badge.js';
|
|
@@ -7,7 +7,7 @@ import { useFormattedMessage } from '../../intl/use-formatted-message.js';
|
|
|
7
7
|
|
|
8
8
|
function AccountIcon({ 'aria-label': ariaLabel, isAuthenticated, }) {
|
|
9
9
|
const t = useFormattedMessage();
|
|
10
|
-
return (jsx(IconWithBadge, { "aria-label": ariaLabel, badge: isAuthenticated ? (jsx(Badge, { "aria-label": `(${t('Signed in')})`, variant: "green" })) : (jsx(Badge, { "aria-label": `(${t('Signed out')})`, variant: "red" })), icon: jsx(SolidLoginIcon, { role: "presentation" }) }));
|
|
10
|
+
return (jsx(IconWithBadge, { "aria-label": ariaLabel, badge: isAuthenticated === undefined ? null : isAuthenticated ? (jsx(Badge, { "aria-label": `(${t('Signed in')})`, variant: "green" })) : (jsx(Badge, { "aria-label": `(${t('Signed out')})`, variant: "red" })), icon: jsx(SolidLoginIcon, { role: "presentation" }) }));
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
export { AccountIcon };
|
|
@@ -66,9 +66,10 @@ function OrderHistory() {
|
|
|
66
66
|
...options,
|
|
67
67
|
[status]: t(`orderStatus.${status}`),
|
|
68
68
|
}), { any: t('orderStatus.Any') });
|
|
69
|
-
return (jsx(Fragment, { children: jsxs("section", { ref: orderHistoryRef, className: styles['order-history'], children: [jsx("div", { className: styles['search'], children: jsx(SearchField, { isDebounced: true, label: t('Search orders'), onChange: searchOrders, placeholder: t('Search orders'), showLabel: false, variant: "outline" }) }), jsx("div", { className: styles['filter'], children: jsx(SelectField, { label: t('Filter order status'), onChange: filterOrders, options: filterOptions, selectedOption: status, showLabel: false }) }), jsx("div", { "aria-label": t('Results'), "aria-live": "polite", className: styles['results'], children: jsx(DynamicLoadingOverlay, { isLoading: isFetching, children: orders && orders.length > 0 ? (jsx(DataTable, { actions: [
|
|
69
|
+
return (jsx(Fragment, { children: jsxs("section", { ref: orderHistoryRef, className: styles['order-history'], "data-test-selector": "order-history", children: [jsx("div", { className: styles['search'], children: jsx(SearchField, { isDebounced: true, "data-test-selector": "order-history-search", label: t('Search orders'), onChange: searchOrders, placeholder: t('Search orders'), showLabel: false, variant: "outline" }) }), jsx("div", { className: styles['filter'], children: jsx(SelectField, { "data-test-selector": "order-history-filter", label: t('Filter order status'), onChange: filterOrders, options: filterOptions, selectedOption: status, showLabel: false }) }), jsx("div", { "aria-label": t('Results'), "aria-live": "polite", className: styles['results'], children: jsx(DynamicLoadingOverlay, { isLoading: isFetching, children: orders && orders.length > 0 ? (jsx(DataTable, { actions: [
|
|
70
70
|
{
|
|
71
|
-
|
|
71
|
+
'data-test-selector': 'order-history-reorder',
|
|
72
|
+
isPrimary: false,
|
|
72
73
|
key: 'reorder',
|
|
73
74
|
label: 'Reorder',
|
|
74
75
|
onAction: order => window?.alert(`Reorder ${order.id}`),
|
|
@@ -80,13 +81,13 @@ function OrderHistory() {
|
|
|
80
81
|
},
|
|
81
82
|
key: 'webOrderNumber',
|
|
82
83
|
props: {
|
|
83
|
-
cssColumn: 'minmax(
|
|
84
|
+
cssColumn: 'minmax(15ch, min-content)',
|
|
84
85
|
nowrap: true,
|
|
85
86
|
sticky: true,
|
|
86
87
|
},
|
|
87
88
|
sort: { direction: 'DESC', isEnabled: true },
|
|
88
89
|
value: {
|
|
89
|
-
render: order => (jsx(Link, { hasUnderline: true, color: "secondary", href: `/my-sonic/order-history/${order.id}`, onClick: () => window?.alert(`open ${order.id}`), children: order.webOrderNumber })),
|
|
90
|
+
render: order => (jsx(Link, { hasUnderline: true, color: "secondary", "data-test-selector": "order-history-order-link", href: `/my-sonic/order-history/${order.id}`, onClick: () => window?.alert(`open ${order.id}`), children: order.webOrderNumber })),
|
|
90
91
|
},
|
|
91
92
|
},
|
|
92
93
|
{
|
|
@@ -163,7 +164,9 @@ function OrderHistory() {
|
|
|
163
164
|
name: key,
|
|
164
165
|
order: direction,
|
|
165
166
|
});
|
|
166
|
-
}
|
|
167
|
+
}, row: {
|
|
168
|
+
'data-test-selector': (order, _) => `order-${order.id}`,
|
|
169
|
+
} })) : (!isFetching && (jsx("p", { className: styles['no-results'], children: t('No orders found.') }))) }) }), orders && orders.length > 0 && (jsx("nav", { className: styles['paging'], children: jsx(Pagination, { currentPage: pagination?.currentPage || 1, "data-test-selector": "order-history-pagination", onChange: page => setPage(page), totalPages: pagination?.numberOfPages || 1 }) })), jsx("div", { className: styles['sticky-bar'], role: "presentation" })] }) }));
|
|
167
170
|
}
|
|
168
171
|
|
|
169
172
|
export { OrderHistory };
|
|
@@ -49,11 +49,12 @@ function ConnectedAddressBookWidget() {
|
|
|
49
49
|
}
|
|
50
50
|
};
|
|
51
51
|
return (jsx(TableCard, { stickyHeader: true, actions: [
|
|
52
|
-
jsx(SearchField, { isDebounced: true, className: styles['search-field'], label: t('Search'), onChange: searchAddresses, placeholder: t('Search'), showLabel: false, size: "md", variant: "outline" }, "searchAddresses"),
|
|
53
|
-
jsx(Button, { color: "secondary", href: `${paths.ACCOUNT_EDIT_BILL_TO_ADDRESS}/current${paths.ACCOUNT_EDIT_SHIP_TO_ADDRESS}/new?returnUrl=${encodeURIComponent(`${href}#${addressBookId}`)}`, size: "sm", variant: "outline", children: t('Add address') }, "addAddress"),
|
|
54
|
-
], className: styles['address-book-widget'], "data-test-selector": "address-book
|
|
52
|
+
jsx(SearchField, { isDebounced: true, className: styles['search-field'], "data-test-selector": "address-book-search", label: t('Search'), onChange: searchAddresses, placeholder: t('Search'), showLabel: false, size: "md", variant: "outline" }, "searchAddresses"),
|
|
53
|
+
jsx(Button, { color: "secondary", "data-test-selector": "address-book-add-address", href: `${paths.ACCOUNT_EDIT_BILL_TO_ADDRESS}/current${paths.ACCOUNT_EDIT_SHIP_TO_ADDRESS}/new?returnUrl=${encodeURIComponent(`${href}#${addressBookId}`)}`, size: "sm", variant: "outline", children: t('Add address') }, "addAddress"),
|
|
54
|
+
], className: styles['address-book-widget'], "data-test-selector": "address-book", id: addressBookId, isLoading: isFetching, paging: addresses &&
|
|
55
55
|
addresses.length > 0 && (jsx("nav", { className: styles['paging'], children: jsx(Pagination, { currentPage: pagination?.currentPage || 1, onChange: page => setPage(page), totalPages: pagination?.numberOfPages || 1 }) })), results: addresses ? addresses.length : 0, showError: error, title: "Address book", children: jsx("div", { ref: addressBookRef, "aria-label": "Results", "aria-live": "polite", className: styles['results'], children: jsx(DynamicLoadingOverlay, { isLoading: isFetching, children: jsx(DataTable, { actions: [
|
|
56
56
|
{
|
|
57
|
+
'data-test-selector': 'edit-address',
|
|
57
58
|
href: address => `${paths.ACCOUNT_EDIT_BILL_TO_ADDRESS}/current${paths.ACCOUNT_EDIT_SHIP_TO_ADDRESS}/${address.id}?returnUrl=${encodeURIComponent(`${href}#${addressBookId}`)}`,
|
|
58
59
|
key: 'edit',
|
|
59
60
|
label: 'Edit',
|
|
@@ -71,7 +72,7 @@ function ConnectedAddressBookWidget() {
|
|
|
71
72
|
},
|
|
72
73
|
value: {
|
|
73
74
|
render: address => {
|
|
74
|
-
return (address.isDefault && (jsx(SolidRatingIcon, { "aria-label": `(${t('addressProperty.Default')})`, className: styles['default-icon'] })));
|
|
75
|
+
return (address.isDefault && (jsx(SolidRatingIcon, { "aria-label": `(${t('addressProperty.Default')})`, className: styles['default-icon'], "data-test-selector": "default-address" })));
|
|
75
76
|
},
|
|
76
77
|
},
|
|
77
78
|
},
|
|
@@ -132,8 +133,8 @@ function ConnectedAddressBookWidget() {
|
|
|
132
133
|
header: { label: 'addressProperty.Country' },
|
|
133
134
|
key: 'country.name',
|
|
134
135
|
props: {
|
|
135
|
-
cssColumn: 'minmax(
|
|
136
|
-
|
|
136
|
+
cssColumn: 'minmax(15ch, min-content)',
|
|
137
|
+
truncated: 2,
|
|
137
138
|
},
|
|
138
139
|
sort: {
|
|
139
140
|
isEnabled: true,
|
|
@@ -162,6 +163,9 @@ function ConnectedAddressBookWidget() {
|
|
|
162
163
|
name: key,
|
|
163
164
|
order: direction,
|
|
164
165
|
});
|
|
166
|
+
}, row: {
|
|
167
|
+
'data-test-selector': (address, _) => `address-${address.id}`,
|
|
168
|
+
selected: (address, _) => address.isDefault,
|
|
165
169
|
} }) }) }) }));
|
|
166
170
|
}
|
|
167
171
|
|
package/dist/sidebar/sidebar.js
CHANGED
|
@@ -14,7 +14,7 @@ function Sidebar({ children, className }) {
|
|
|
14
14
|
[styles['is-closed']]: !isOpen,
|
|
15
15
|
[styles['is-docked']]: isDocked,
|
|
16
16
|
[styles['is-not-docked']]: !isDocked,
|
|
17
|
-
}, className), inert: isOpen ? undefined :
|
|
17
|
+
}, className), inert: isOpen ? undefined : true, children: [jsx(IconButton, { className: styles.close, color: "secondary", onClick: toggle, children: jsx(StrokeCloseboxIcon, {}) }), jsx("div", { className: styles['content'], children: children })] }));
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
export { Sidebar };
|
package/dist/styles.css
CHANGED
|
@@ -454,6 +454,7 @@ html {
|
|
|
454
454
|
|
|
455
455
|
.accordion-module-9WvAH .accordion-module-lf9d-.accordion-module-kYmoe .accordion-module-KZjMo {
|
|
456
456
|
block-size: 0;
|
|
457
|
+
visibility: hidden;
|
|
457
458
|
}
|
|
458
459
|
|
|
459
460
|
/* open state */
|
|
@@ -485,6 +486,7 @@ html {
|
|
|
485
486
|
background-color: var(--color-brand-light-gray);
|
|
486
487
|
font-size: var(--font-size-16);
|
|
487
488
|
font-weight: var(--font-weight-normal);
|
|
489
|
+
transition: border-radius 0s var(--transition-duration-short);
|
|
488
490
|
}
|
|
489
491
|
|
|
490
492
|
.accordion-module-9WvAH.accordion-module-SAbiG .accordion-module-lf9d- .accordion-module--Rwpb svg {
|
|
@@ -499,19 +501,24 @@ html {
|
|
|
499
501
|
}
|
|
500
502
|
|
|
501
503
|
.accordion-module-9WvAH.accordion-module-SAbiG .accordion-module-lf9d- .accordion-module-KZjMo {
|
|
502
|
-
|
|
504
|
+
display: grid;
|
|
505
|
+
padding: 0;
|
|
506
|
+
border: 1px solid var(--color-brand-medium-gray);
|
|
507
|
+
margin: 0;
|
|
508
|
+
border-bottom-left-radius: var(--border-radius-8);
|
|
509
|
+
border-bottom-right-radius: var(--border-radius-8);
|
|
510
|
+
grid-template-rows: var(--space-16) auto var(--space-16);
|
|
511
|
+
padding-inline: var(--space-16);
|
|
503
512
|
}
|
|
504
513
|
|
|
514
|
+
.accordion-module-9WvAH.accordion-module-SAbiG .accordion-module-lf9d- .accordion-module-KZjMo::before {
|
|
515
|
+
content: '';
|
|
516
|
+
}
|
|
517
|
+
|
|
505
518
|
.accordion-module-9WvAH.accordion-module-SAbiG .accordion-module-lf9d-.accordion-module-W0F1z .accordion-module--Rwpb {
|
|
506
519
|
border-bottom-left-radius: 0;
|
|
507
520
|
border-bottom-right-radius: 0;
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
.accordion-module-9WvAH.accordion-module-SAbiG .accordion-module-lf9d-.accordion-module-W0F1z .accordion-module-KZjMo {
|
|
511
|
-
border: 1px solid var(--color-brand-medium-gray);
|
|
512
|
-
border-bottom-left-radius: var(--border-radius-8);
|
|
513
|
-
border-bottom-right-radius: var(--border-radius-8);
|
|
514
|
-
padding-block: 1rem;
|
|
521
|
+
transition: border-radius 0s 0s;
|
|
515
522
|
}
|
|
516
523
|
|
|
517
524
|
.heading-module-pMC65 {
|
|
@@ -1766,7 +1773,7 @@ html {
|
|
|
1766
1773
|
'label .'
|
|
1767
1774
|
'field info'
|
|
1768
1775
|
'error .';
|
|
1769
|
-
grid-template-columns: auto;
|
|
1776
|
+
grid-template-columns: 1fr auto;
|
|
1770
1777
|
grid-template-rows: repeat(3, min-content);
|
|
1771
1778
|
}
|
|
1772
1779
|
|
|
@@ -4880,7 +4887,7 @@ button.swiper-pagination-bullet {
|
|
|
4880
4887
|
cursor: pointer;
|
|
4881
4888
|
gap: var(--space-2);
|
|
4882
4889
|
grid-template-areas: 'icon label .';
|
|
4883
|
-
grid-template-columns: (--space-24) 1fr var(--space-24);
|
|
4890
|
+
grid-template-columns: var(--space-24) 1fr var(--space-24);
|
|
4884
4891
|
grid-template-rows: minmax(24px, min-content);
|
|
4885
4892
|
line-height: 1;
|
|
4886
4893
|
outline: none;
|
|
@@ -8447,6 +8454,7 @@ button.swiper-pagination-bullet {
|
|
|
8447
8454
|
background-color: var(--bgcolor-row-selected);
|
|
8448
8455
|
content: '';
|
|
8449
8456
|
grid-column: 1 / -1;
|
|
8457
|
+
margin-block-end: 1px;
|
|
8450
8458
|
opacity: 1;
|
|
8451
8459
|
pointer-events: none;
|
|
8452
8460
|
}
|
|
@@ -2,6 +2,7 @@ import { FunctionComponent, ReactNode } from 'react';
|
|
|
2
2
|
import { TranslationId } from '../intl/translation-id';
|
|
3
3
|
import { SortDirection, SortHanlder, SortOptions, TableColumnProperties } from './elements/types';
|
|
4
4
|
export interface Column<T extends object> {
|
|
5
|
+
'data-test-selector'?: (column: Column<T>, item: T) => string;
|
|
5
6
|
header: {
|
|
6
7
|
isHidden?: boolean;
|
|
7
8
|
isNarrow?: boolean;
|
|
@@ -25,6 +26,7 @@ export interface Column<T extends object> {
|
|
|
25
26
|
};
|
|
26
27
|
}
|
|
27
28
|
export interface Action<T extends object> {
|
|
29
|
+
'data-test-selector'?: string;
|
|
28
30
|
href?: (item: T) => string;
|
|
29
31
|
icon?: ReactNode;
|
|
30
32
|
isEnabled?: (item: T) => boolean;
|
|
@@ -38,6 +40,11 @@ export interface DataTableProps<T extends object> {
|
|
|
38
40
|
columns?: Column<T>[];
|
|
39
41
|
data: T[];
|
|
40
42
|
onSort?: SortHanlder;
|
|
43
|
+
row?: {
|
|
44
|
+
'data-test-selector'?: (item: T, index: number) => string;
|
|
45
|
+
onClick?: (item: T) => void;
|
|
46
|
+
selected?: (item: T, index: number) => boolean;
|
|
47
|
+
};
|
|
41
48
|
}
|
|
42
49
|
export declare function SortWrapper<T extends object>({ children, column, direction, onSort, }: {
|
|
43
50
|
children: ReactNode;
|
|
@@ -45,4 +52,4 @@ export declare function SortWrapper<T extends object>({ children, column, direct
|
|
|
45
52
|
direction?: SortDirection;
|
|
46
53
|
onSort: SortHanlder;
|
|
47
54
|
}): import("react/jsx-runtime").JSX.Element;
|
|
48
|
-
export declare function DataTable<T extends object>({ actions, columns: _columns, data, onSort: _onSort, }: DataTableProps<T>): import("react/jsx-runtime").JSX.Element | null;
|
|
55
|
+
export declare function DataTable<T extends object>({ actions, columns: _columns, data, onSort: _onSort, row: _row, }: DataTableProps<T>): import("react/jsx-runtime").JSX.Element | null;
|
package/dist/table/data-table.js
CHANGED
|
@@ -19,7 +19,7 @@ function SortWrapper({ children, column, direction, onSort, }) {
|
|
|
19
19
|
return jsx(Fragment, { children: children });
|
|
20
20
|
return (jsx(TableSortButton, { columnName: column.header.label, direction: direction, onSort: onSort, sortKey: column.sort.columnName || column.key, children: children }));
|
|
21
21
|
}
|
|
22
|
-
function DataTable({ actions, columns: _columns, data, onSort: _onSort, }) {
|
|
22
|
+
function DataTable({ actions, columns: _columns, data, onSort: _onSort, row: _row, }) {
|
|
23
23
|
const isXl = useIsBreakpoint('lg');
|
|
24
24
|
const t = useFormattedMessage();
|
|
25
25
|
const [sortInfo, setSortInfo] = useState(() => {
|
|
@@ -70,20 +70,20 @@ function DataTable({ actions, columns: _columns, data, onSort: _onSort, }) {
|
|
|
70
70
|
? sortInfo?.direction
|
|
71
71
|
: 'NONE', onSort: onSort, children: 'render' in column.header && column.header.render
|
|
72
72
|
? column.header.render(column, data)
|
|
73
|
-
: t(column.header.label) }))) }, column.key))) }), children: data.map((item, index) => (
|
|
73
|
+
: t(column.header.label) }))) }, column.key))) }), children: data.map((item, index) => (jsx(TR
|
|
74
74
|
// eslint-disable-next-line @eslint-react/no-array-index-key
|
|
75
|
-
|
|
75
|
+
, { "data-test-selector": _row?.['data-test-selector']?.(item, index), onClick: _row?.onClick ? () => _row.onClick?.(item) : undefined, selected: _row?.selected ? _row.selected(item, index) : false, children: columns.map(column => {
|
|
76
76
|
const actionKey = 'action' in column.value ? column.value.action : undefined;
|
|
77
77
|
const action = actionKey
|
|
78
78
|
? actions?.find(action => action.key === actionKey)
|
|
79
79
|
: undefined;
|
|
80
80
|
if (actionKey && !action)
|
|
81
81
|
throw new Error(`Action "${actionKey}" not found`);
|
|
82
|
-
return 'render' in column.value ? (jsx(TD, { children: column.value.render(item, column, data) }, column.key)) : 'propertyName' in column.value ? (jsx(TD, { children: String(item[column.value.propertyName]) }, column.key)) : 'action' in column.value ? (jsx(TD, { children: action && (jsx(Link, { hasUnderline: true, color: "secondary", href: action.href?.(item), isDisabled: action.isEnabled ? !action.isEnabled(item) : false, onClick: () => action.onAction?.(item), children: t(action.label) })) }, column.key)) : null;
|
|
82
|
+
return 'render' in column.value ? (jsx(TD, { "data-key": column.key, children: column.value.render(item, column, data) }, column.key)) : 'propertyName' in column.value ? (jsx(TD, { "data-key": column.key, children: String(item[column.value.propertyName]) }, column.key)) : 'action' in column.value ? (jsx(TD, { "data-key": column.key, children: action && (jsx(Link, { hasUnderline: true, color: "secondary", "data-test-selector": action['data-test-selector'], href: action.href?.(item), isDisabled: action.isEnabled ? !action.isEnabled(item) : false, onClick: () => action.onAction?.(item), children: t(action.label) })) }, column.key)) : null;
|
|
83
83
|
}) }, index))) }) }));
|
|
84
84
|
return (jsx("div", { className: styles['data-card-list'], children: data.map((item, index) => (jsx(DataCard
|
|
85
85
|
// eslint-disable-next-line @eslint-react/no-array-index-key
|
|
86
|
-
, { actions: actions?.map(action => (jsx(Button, { color: action.isPrimary ? 'primary' : 'secondary', href: action.href?.(item), isDisabled: action.isEnabled ? !action.isEnabled(item) : false, onClick: () => action.onAction?.(item), size: "sm", variant: action.isPrimary ? undefined : 'outline', children: t(action.label) }, action.key))), data: columns
|
|
86
|
+
, { actions: actions?.map(action => (jsx(Button, { color: action.isPrimary ? 'primary' : 'secondary', "data-test-selector": action['data-test-selector'], href: action.href?.(item), isDisabled: action.isEnabled ? !action.isEnabled(item) : false, onClick: () => action.onAction?.(item), size: "sm", variant: action.isPrimary ? undefined : 'outline', children: t(action.label) }, action.key))), data: columns
|
|
87
87
|
.map(column => 'render' in column.value
|
|
88
88
|
? {
|
|
89
89
|
key: column.key,
|
|
@@ -97,7 +97,7 @@ function DataTable({ actions, columns: _columns, data, onSort: _onSort, }) {
|
|
|
97
97
|
value: item[column.value.propertyName],
|
|
98
98
|
}
|
|
99
99
|
: null)
|
|
100
|
-
.filter(Boolean) }, index))) }));
|
|
100
|
+
.filter(Boolean), "data-test-selector": _row?.['data-test-selector']?.(item, index) }, index))) }));
|
|
101
101
|
}
|
|
102
102
|
|
|
103
103
|
export { DataTable, SortWrapper };
|
|
@@ -13,7 +13,7 @@ function TableSortButton({ align = 'start', children, columnName, direction = 'N
|
|
|
13
13
|
${t(columnName)}
|
|
14
14
|
${isActive && `(${t('active')}, ${t(`sort.${direction}`)})`}
|
|
15
15
|
`;
|
|
16
|
-
return (jsxs("button", { "aria-label": ariaLabel, className: clsx(styles['table-sort-button'], isActive && styles['active'], styles[direction.toLowerCase()], styles[align]), onClick: () => onSort(sortKey, direction), type: "button", children: [jsx("span", { className: styles['label'], children: children }), isActive && (jsx(GlyphsChevronsBoldUpIcon, { "aria-label": t(direction), className: styles['icon'] }))] }));
|
|
16
|
+
return (jsxs("button", { "aria-label": ariaLabel, className: clsx(styles['table-sort-button'], isActive && styles['active'], styles[direction.toLowerCase()], styles[align]), "data-sort-direction": direction, onClick: () => onSort(sortKey, direction), type: "button", children: [jsx("span", { className: styles['label'], children: children }), isActive && (jsx(GlyphsChevronsBoldUpIcon, { "aria-label": t(direction), className: styles['icon'] }))] }));
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export { TableSortButton };
|
|
@@ -2,5 +2,6 @@ import { TableColumnProperties } from './types';
|
|
|
2
2
|
export interface TDProps extends TableColumnProperties {
|
|
3
3
|
children: React.ReactNode;
|
|
4
4
|
className?: string;
|
|
5
|
+
'data-key'?: string;
|
|
5
6
|
}
|
|
6
7
|
export declare function TD(props: TDProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -7,7 +7,7 @@ import styles from './table.module.css.js';
|
|
|
7
7
|
|
|
8
8
|
function TD(props) {
|
|
9
9
|
const { align = 'start', children, className, colSpan, isNarrow, nowrap, rowSpan, sticky, truncated, } = useTD(props);
|
|
10
|
-
return (jsx("td", { className: clsx(styles['td'], styles[align], nowrap && styles['nowrap'], sticky && styles['sticky'], isNarrow && styles['narrow'], className), colSpan: colSpan, rowSpan: rowSpan, children: truncated ? (jsx(Truncated, { lines: typeof truncated === 'number' ? truncated : undefined, children: children })) : (children) }));
|
|
10
|
+
return (jsx("td", { className: clsx(styles['td'], styles[align], nowrap && styles['nowrap'], sticky && styles['sticky'], isNarrow && styles['narrow'], className), colSpan: colSpan, "data-key": props['data-key'], rowSpan: rowSpan, children: truncated ? (jsx(Truncated, { lines: typeof truncated === 'number' ? truncated : undefined, children: children })) : (children) }));
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
export { TD };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { TRProps } from './types';
|
|
2
|
-
export declare function TR({ children, className, onClick, selected }: TRProps): import("react/jsx-runtime").JSX.Element;
|
|
2
|
+
export declare function TR({ children, className, 'data-test-selector': dataTestSelector, onClick, selected, }: TRProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -4,8 +4,8 @@ import clsx from 'clsx';
|
|
|
4
4
|
import { TableRowProvider } from './table-row-provider.js';
|
|
5
5
|
import styles from './table.module.css.js';
|
|
6
6
|
|
|
7
|
-
function TR({ children, className, onClick, selected }) {
|
|
8
|
-
return (jsx(TableRowProvider, { children: jsx("tr", { "aria-selected": selected, className: clsx(styles['tr'], selected && styles['selected'], Boolean(onClick) && styles['clickable'], className), onClick: onClick, children: children }) }));
|
|
7
|
+
function TR({ children, className, 'data-test-selector': dataTestSelector, onClick, selected, }) {
|
|
8
|
+
return (jsx(TableRowProvider, { children: jsx("tr", { "aria-selected": selected, className: clsx(styles['tr'], selected && styles['selected'], Boolean(onClick) && styles['clickable'], className), "data-test-selector": dataTestSelector, onClick: onClick, children: children }) }));
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
export { TR };
|
|
@@ -32,6 +32,7 @@ export interface THProps extends TableColumnProperties {
|
|
|
32
32
|
export interface TRProps {
|
|
33
33
|
children: ReactNode;
|
|
34
34
|
className?: string;
|
|
35
|
+
'data-test-selector'?: string;
|
|
35
36
|
onClick?: (event: React.MouseEvent<HTMLTableRowElement>) => void;
|
|
36
37
|
selected?: boolean;
|
|
37
38
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sonic-equipment/ui",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "214.0.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"engines": {
|
|
@@ -15,10 +15,7 @@
|
|
|
15
15
|
"default": "./dist/index.js"
|
|
16
16
|
}
|
|
17
17
|
},
|
|
18
|
-
"files": [
|
|
19
|
-
"dist",
|
|
20
|
-
"README.md"
|
|
21
|
-
],
|
|
18
|
+
"files": ["dist", "README.md"],
|
|
22
19
|
"main": "dist/index.js",
|
|
23
20
|
"types": "./dist/index.d.ts",
|
|
24
21
|
"scripts": {
|