@cwellt_software/cwellt-reactjs-lib 1.5.2 → 1.5.4
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/content/icons/new-cw-icons/css/new-cw-icons.css +6 -0
- package/dist/index.cjs.js +278 -89
- package/dist/index.css +2 -2
- package/dist/index.d.ts +133 -16
- package/dist/index.es.js +278 -90
- package/dist/src/components/control/action/button/CwButton.d.ts +5 -0
- package/dist/src/components/control/action/button/CwButton.d.ts.map +1 -1
- package/dist/src/components/control/action/button/CwButton.stories.d.ts +28 -0
- package/dist/src/components/control/action/button/CwButton.stories.d.ts.map +1 -0
- package/dist/src/components/control/action/button/CwButtonBadge.d.ts +63 -0
- package/dist/src/components/control/action/button/CwButtonBadge.d.ts.map +1 -0
- package/dist/src/components/control/choice/checkbox/CwCheckboxGroup.d.ts.map +1 -1
- package/dist/src/components/control/choice/checkbox/CwRadioGroup.d.ts.map +1 -1
- package/dist/src/components/control/choice/multi-filter/CwMultiFilter.d.ts +11 -0
- package/dist/src/components/control/choice/multi-filter/CwMultiFilter.d.ts.map +1 -1
- package/dist/src/components/control/choice/select/CwDropdown.d.ts.map +1 -1
- package/dist/src/components/control/choice/tag-selector/CwTagSelector.d.ts.map +1 -1
- package/dist/src/components/control/input/digit/CwDigit.d.ts +6 -0
- package/dist/src/components/control/input/digit/CwDigit.d.ts.map +1 -1
- package/dist/src/components/control/input/new-dates/CwDatePicker.d.ts.map +1 -1
- package/dist/src/components/control/input/new-dates/CwDatePickerTemporal.d.ts.map +1 -1
- package/dist/src/components/control/input/new-dates/CwDateRangePicker.d.ts.map +1 -1
- package/dist/src/components/control/input/new-dates/CwDateRangePickerTemporal.d.ts.map +1 -1
- package/dist/src/components/control/input/new-dates/CwTimePicker.d.ts.map +1 -1
- package/dist/src/components/control/input/text/CwInputText.stories.d.ts +840 -0
- package/dist/src/components/control/input/text/CwInputText.stories.d.ts.map +1 -0
- package/dist/src/components/control/input/weekday/CwWeekdaySelector.d.ts +16 -44
- package/dist/src/components/control/input/weekday/CwWeekdaySelector.d.ts.map +1 -1
- package/dist/src/components/control/input/weekday/weekdayNames.d.ts +14 -0
- package/dist/src/components/control/input/weekday/weekdayNames.d.ts.map +1 -0
- package/dist/src/components/control/input/weekday/weekdays.d.ts +65 -0
- package/dist/src/components/control/input/weekday/weekdays.d.ts.map +1 -0
- package/dist/src/components/display/graphics/progress/CwProgress.d.ts +3 -1
- package/dist/src/components/display/graphics/progress/CwProgress.d.ts.map +1 -1
- package/dist/src/components/display/text/badge/CwBadge.d.ts +48 -0
- package/dist/src/components/display/text/badge/CwBadge.d.ts.map +1 -0
- package/dist/src/components/display/text/badge/badgeContent.d.ts +33 -0
- package/dist/src/components/display/text/badge/badgeContent.d.ts.map +1 -0
- package/dist/src/components/display/text/note/CwNote.stories.d.ts +51 -0
- package/dist/src/components/display/text/note/CwNote.stories.d.ts.map +1 -0
- package/dist/src/components/display/text/tag/CwChip.d.ts +16 -8
- package/dist/src/components/display/text/tag/CwChip.d.ts.map +1 -1
- package/dist/src/components/display/text/tag/CwChip.stories.d.ts +29 -0
- package/dist/src/components/display/text/tag/CwChip.stories.d.ts.map +1 -0
- package/dist/src/components/layout/tabs/CwTabs.d.ts +7 -1
- package/dist/src/components/layout/tabs/CwTabs.d.ts.map +1 -1
- package/dist/src/index.d.ts +3 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/playground/PlaygroundApp.d.ts.map +1 -1
- package/dist/src/playground/pages/CwBadgePage.d.ts +3 -0
- package/dist/src/playground/pages/CwBadgePage.d.ts.map +1 -0
- package/dist/src/playground/pages/CwChipPage.d.ts +3 -0
- package/dist/src/playground/pages/CwChipPage.d.ts.map +1 -0
- package/dist/src/playground/pages/CwDigitPage.d.ts +3 -0
- package/dist/src/playground/pages/CwDigitPage.d.ts.map +1 -0
- package/dist/src/playground/pages/CwWeekdaySelectorPage.d.ts +3 -0
- package/dist/src/playground/pages/CwWeekdaySelectorPage.d.ts.map +1 -0
- package/dist/src/playground/pages/FormControlLayoutsPage.d.ts +3 -0
- package/dist/src/playground/pages/FormControlLayoutsPage.d.ts.map +1 -0
- package/dist/src/playground/pages/ProgressPage.d.ts.map +1 -1
- package/dist/src/playground/pages/SelectorsPage.d.ts.map +1 -1
- package/dist/src/storybook/inputStoryArgs.d.ts +68 -0
- package/dist/src/storybook/inputStoryArgs.d.ts.map +1 -0
- package/dist/src/storybook/layoutStoryArgs.d.ts +60 -0
- package/dist/src/storybook/layoutStoryArgs.d.ts.map +1 -0
- package/dist/src/storybook/storySource.d.ts +22 -0
- package/dist/src/storybook/storySource.d.ts.map +1 -0
- package/dist/test/components/control/input/weekday/weekdayNames.test.d.ts +2 -0
- package/dist/test/components/control/input/weekday/weekdayNames.test.d.ts.map +1 -0
- package/dist/test/components/control/input/weekday/weekdays.test.d.ts +2 -0
- package/dist/test/components/control/input/weekday/weekdays.test.d.ts.map +1 -0
- package/dist/test/components/display/text/badge/badgeContent.test.d.ts +2 -0
- package/dist/test/components/display/text/badge/badgeContent.test.d.ts.map +1 -0
- package/dist/test/storybook/inputStoryArgs.test.d.ts +2 -0
- package/dist/test/storybook/inputStoryArgs.test.d.ts.map +1 -0
- package/dist/test/storybook/layoutStoryArgs.test.d.ts +2 -0
- package/dist/test/storybook/layoutStoryArgs.test.d.ts.map +1 -0
- package/package.json +1 -1
package/dist/index.cjs.js
CHANGED
|
@@ -181,7 +181,7 @@ function getContrastColor(color) {
|
|
|
181
181
|
return `hsl(${hsl.h}, ${contrastS}%, ${targetL}%)`;
|
|
182
182
|
}
|
|
183
183
|
|
|
184
|
-
var styles$
|
|
184
|
+
var styles$y = {"cw-tooltip-content":"cw-tooltip-module__cw-tooltip-content__RZczd","cw-tooltip":"cw-tooltip-module__cw-tooltip__1KYig"};
|
|
185
185
|
|
|
186
186
|
// Constants
|
|
187
187
|
const margin$1 = 16;
|
|
@@ -471,7 +471,7 @@ const CwTooltipManager = () => {
|
|
|
471
471
|
if (!state.isVisible || !state.content) {
|
|
472
472
|
return null;
|
|
473
473
|
}
|
|
474
|
-
return reactDom.createPortal(jsxRuntime.jsx("div", { ref: tooltipRef, className: styles$
|
|
474
|
+
return reactDom.createPortal(jsxRuntime.jsx("div", { ref: tooltipRef, className: styles$y["cw-tooltip-content"], "data-position": actualPosition, "data-visible": state.isVisible, "data-inline": state.displayInline, style: {
|
|
475
475
|
top: `${tooltipPosition.top}px`,
|
|
476
476
|
left: `${tooltipPosition.left}px`,
|
|
477
477
|
opacity: (isPositioned && !isMeasuring) ? 1 : 0,
|
|
@@ -552,7 +552,7 @@ const CwTooltipNew = ({ children, content = null, position = "right", dissapears
|
|
|
552
552
|
React.useEffect(() => {
|
|
553
553
|
ensureTooltipManager();
|
|
554
554
|
}, []);
|
|
555
|
-
return (jsxRuntime.jsx("div", { ref: containerRef, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, style: overlayStyle, "data-inline": displayInline, className: styles$
|
|
555
|
+
return (jsxRuntime.jsx("div", { ref: containerRef, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, style: overlayStyle, "data-inline": displayInline, className: styles$y["cw-tooltip"], children: children }));
|
|
556
556
|
};
|
|
557
557
|
|
|
558
558
|
const SVG_ICONS = {
|
|
@@ -587,25 +587,31 @@ function CwIcon(props) {
|
|
|
587
587
|
/**
|
|
588
588
|
* CwChip - A simple chip/tag component for displaying labels or categories
|
|
589
589
|
*
|
|
590
|
+
* The colour comes from `color`; the older `colorScheme` spelling is deprecated but still
|
|
591
|
+
* honoured, and `color` wins when both are passed.
|
|
592
|
+
*
|
|
590
593
|
* @example
|
|
591
|
-
* <CwChip label="Active"
|
|
592
|
-
* <CwChip label="High Priority"
|
|
593
|
-
* <CwChip label="Custom"
|
|
594
|
-
* <CwChip label="Outlined"
|
|
594
|
+
* <CwChip label="Active" color="success" />
|
|
595
|
+
* <CwChip label="High Priority" color="danger" variant="solid" />
|
|
596
|
+
* <CwChip label="Custom" color="custom" customColor="#8a2be2" />
|
|
597
|
+
* <CwChip label="Outlined" color="info" variant="outline" />
|
|
595
598
|
* <CwChip label="Removable" closable onClose={() => console.log('closed')} />
|
|
596
599
|
**/
|
|
597
|
-
const CwChip = ({ label, colorScheme
|
|
600
|
+
const CwChip = ({ label, color, colorScheme, customColor, variant = 'soft', className = '', closable = false, onClose, icon, style = {}, }) => {
|
|
601
|
+
const resolvedColor = color ?? colorScheme ?? 'info';
|
|
598
602
|
// Basic validation
|
|
599
603
|
if (closable && !onClose) {
|
|
600
604
|
console.warn('CwChip: onClose prop is required when closable is true');
|
|
601
605
|
}
|
|
602
|
-
//
|
|
606
|
+
// One arbitrary colour can only fill two of the four roles, so soft and solid look alike here.
|
|
603
607
|
const chipStyle = React.useMemo(() => {
|
|
604
608
|
if (customColor) {
|
|
605
|
-
|
|
609
|
+
const contrast = getContrastColor(customColor);
|
|
606
610
|
return {
|
|
607
|
-
'--
|
|
608
|
-
'--
|
|
611
|
+
'--accent-light': customColor,
|
|
612
|
+
'--accent-main': customColor,
|
|
613
|
+
'--accent-dark': contrast,
|
|
614
|
+
'--accent-on-main': contrast,
|
|
609
615
|
...style
|
|
610
616
|
};
|
|
611
617
|
}
|
|
@@ -624,7 +630,79 @@ const CwChip = ({ label, colorScheme = 'info', customColor, variant = 'soft', cl
|
|
|
624
630
|
className,
|
|
625
631
|
closable ? 'cw-chip-closable' : '',
|
|
626
632
|
].filter(Boolean).join(' ');
|
|
627
|
-
return (jsxRuntime.jsxs("span", { className: chipClassNames, "data-color
|
|
633
|
+
return (jsxRuntime.jsxs("span", { className: chipClassNames, "data-color": resolvedColor, "data-variant": variant, "data-icon-only": (Boolean(icon) && !label) || undefined, style: chipStyle, children: [icon && jsxRuntime.jsx(CwIcon, { iconId: icon }), label && jsxRuntime.jsx("span", { children: label }), closable && (jsxRuntime.jsx("button", { className: "cw-chip-close-button", onClick: handleClose, "aria-label": "Remove", type: "button", children: jsxRuntime.jsx("span", { className: "cwi-icons cwi-close" }) }))] }));
|
|
634
|
+
};
|
|
635
|
+
|
|
636
|
+
/**
|
|
637
|
+
* Normalises a raw count into the integer the badge represents: a non-negative whole number.
|
|
638
|
+
* Both the display string and the `showZero` decision derive from this.
|
|
639
|
+
*/
|
|
640
|
+
function normalizeBadgeCount(count) {
|
|
641
|
+
return Number.isFinite(count) ? Math.max(0, Math.trunc(count)) : 0;
|
|
642
|
+
}
|
|
643
|
+
/**
|
|
644
|
+
* Formats a badge count into its display string. Both arguments are normalised, `max` with a
|
|
645
|
+
* floor of 1 - below that every non-zero count would overflow.
|
|
646
|
+
*
|
|
647
|
+
* @param count Raw count to display.
|
|
648
|
+
* @param max Highest value shown as a number; anything above renders `"{max}+"`.
|
|
649
|
+
*
|
|
650
|
+
* @example
|
|
651
|
+
* formatBadgeCount(7, 99); // "7"
|
|
652
|
+
* formatBadgeCount(100, 99); // "99+"
|
|
653
|
+
* formatBadgeCount(12, 9); // "9+"
|
|
654
|
+
*/
|
|
655
|
+
function formatBadgeCount(count, max) {
|
|
656
|
+
const safeCount = normalizeBadgeCount(count);
|
|
657
|
+
const safeMax = Number.isFinite(max) ? Math.max(1, Math.trunc(max)) : 1;
|
|
658
|
+
return safeCount > safeMax ? `${safeMax}+` : `${safeCount}`;
|
|
659
|
+
}
|
|
660
|
+
/**
|
|
661
|
+
* Resolves the badge's accessibility attributes. A text-less badge with no label is hidden rather
|
|
662
|
+
* than announced as an empty element; the button or tab around it usually names the thing.
|
|
663
|
+
*
|
|
664
|
+
* @param label Caller-supplied accessible name.
|
|
665
|
+
* @param loading Whether the badge is showing its spinner.
|
|
666
|
+
* @param hasText Whether the badge renders a count or content.
|
|
667
|
+
*/
|
|
668
|
+
function resolveBadgeAria(label, loading, hasText) {
|
|
669
|
+
if (label) {
|
|
670
|
+
return { role: loading ? 'status' : 'img', 'aria-label': label };
|
|
671
|
+
}
|
|
672
|
+
return hasText ? {} : { 'aria-hidden': 'true' };
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
var styles$x = {"badge":"cw-badge-module__badge__PKlak"};
|
|
676
|
+
|
|
677
|
+
/**
|
|
678
|
+
* CwBadge - the small coloured circle with a number, used for alert and notification counts.
|
|
679
|
+
*
|
|
680
|
+
* Always **in flow** (`inline-flex`); it never positions itself, so overlaying it on an icon
|
|
681
|
+
* button is the caller's job. One digit stays a circle, wider content such as `"99+"` grows into
|
|
682
|
+
* a pill. With neither `count` nor `content` it renders as a dot.
|
|
683
|
+
*
|
|
684
|
+
* Precedence: `loading` > `content` > `count` > dot. While loading the badge renders regardless
|
|
685
|
+
* of `showZero`, and the spinner replaces it - circle, background and padding come off.
|
|
686
|
+
*
|
|
687
|
+
* @example
|
|
688
|
+
* <CwBadge count={3} color="danger" />
|
|
689
|
+
* <CwBadge count={0} showZero={false} />
|
|
690
|
+
* <CwBadge count={128} max={99} color="warning" variant="soft" />
|
|
691
|
+
* <CwBadge color="warning" label="Unresolved findings" />
|
|
692
|
+
* <CwBadge count={0} loading />
|
|
693
|
+
*/
|
|
694
|
+
const CwBadge = ({ count, content, color = 'info', variant = 'solid', size = 'small', showZero = true, loading = false, max = 99, label, className = '', style, }) => {
|
|
695
|
+
// null counts as absent, so `content={null}` still renders a dot rather than an empty pill.
|
|
696
|
+
const hasContent = content !== undefined && content !== null;
|
|
697
|
+
if (!loading && !hasContent && count !== undefined && !showZero && normalizeBadgeCount(count) === 0) {
|
|
698
|
+
return null;
|
|
699
|
+
}
|
|
700
|
+
const countText = !hasContent && count !== undefined
|
|
701
|
+
? formatBadgeCount(count, max)
|
|
702
|
+
: undefined;
|
|
703
|
+
const isDot = !loading && !hasContent && count === undefined;
|
|
704
|
+
const badgeClassNames = ['cw-badge', styles$x.badge, className].filter(Boolean).join(' ');
|
|
705
|
+
return (jsxRuntime.jsx("span", { className: badgeClassNames, "data-color": color, "data-variant": variant, "data-size": size, "data-loading": loading ? 'true' : undefined, "data-dot": isDot ? 'true' : undefined, ...resolveBadgeAria(label, loading, !loading && (hasContent || countText !== undefined)), style: style, children: loading ? jsxRuntime.jsx(CwIcon, { iconId: "spinner", size: "small" }) : hasContent ? content : countText }));
|
|
628
706
|
};
|
|
629
707
|
|
|
630
708
|
const CW_DEFAULT_MESSAGE_DURATION = 2000;
|
|
@@ -1078,7 +1156,7 @@ var styles$v = {"progress":"cw-progress-module__progress__d-g2-","value":"cw-pro
|
|
|
1078
1156
|
* <CwProgress value={62} label="Import" color="success" />
|
|
1079
1157
|
* <CwProgress indeterminate label="Uploading" />
|
|
1080
1158
|
*/
|
|
1081
|
-
function CwProgress({ value, indeterminate = false, label, rightLabel, size = 'regular', layout = 'row', color = 'primary', monoValue = false, prominent = false }) {
|
|
1159
|
+
function CwProgress({ value, indeterminate = false, label, rightLabel, size = 'regular', layout = 'row', color = 'primary', monoValue = false, prominent = false, className }) {
|
|
1082
1160
|
const labelId = React.useId();
|
|
1083
1161
|
// Determinate: a missing or non-finite value is treated as 0 (never NaN), then
|
|
1084
1162
|
// clamped to [0,100] for aria-valuenow and the fill width. Indeterminate has no value.
|
|
@@ -1090,7 +1168,7 @@ function CwProgress({ value, indeterminate = false, label, rightLabel, size = 'r
|
|
|
1090
1168
|
const valueText = rightLabel ?? (percent !== undefined ? `${percent}%` : '');
|
|
1091
1169
|
// The un-hashed cw-progress class carries no styles in the library - a stable
|
|
1092
1170
|
// public hook for exceptional external overrides only.
|
|
1093
|
-
const rootClassName = ['cw-progress', styles$v.progress].filter(Boolean).join(' ');
|
|
1171
|
+
const rootClassName = ['cw-progress', styles$v.progress, className].filter(Boolean).join(' ');
|
|
1094
1172
|
const labelSpan = label ? jsxRuntime.jsx("span", { className: styles$v.label, id: labelId, children: label }) : null;
|
|
1095
1173
|
const valueLabel = showValue ? (jsxRuntime.jsx("span", { className: styles$v.value, "data-mono": monoValue || undefined, children: valueText })) : null;
|
|
1096
1174
|
return (jsxRuntime.jsxs("div", { className: rootClassName, "data-layout": layout, "data-size": size, "data-color": color, "data-prominent": prominent || undefined, "data-indeterminate": indeterminate || undefined, children: [layout === 'column' && (labelSpan || valueLabel) && (jsxRuntime.jsxs("header", { className: styles$v.header, children: [labelSpan, valueLabel] })), layout === 'row' && labelSpan, jsxRuntime.jsx("div", { className: styles$v.track, role: "progressbar", ...(label && { 'aria-labelledby': labelId }), ...(!indeterminate && percent !== undefined && {
|
|
@@ -1246,7 +1324,7 @@ const CwGenericTooltip = ({ children, content = null, position = defaultPosition
|
|
|
1246
1324
|
return (jsxRuntime.jsxs("div", { ref: containerRef, className: styles$u["cw-generic-tooltip"], onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, style: overlayStyle, "data-inline": displayInline, children: [tooltipContent, children] }));
|
|
1247
1325
|
};
|
|
1248
1326
|
|
|
1249
|
-
const CwButton = React.forwardRef(function CwButton({ text, variant = 'solid', color = 'primary', size = 'medium', iconPosition = 'left', pressed, className = '', icon = "", title, tooltipPosition = "bottom", children, ...buttonProps }, ref) {
|
|
1327
|
+
const CwButton = React.forwardRef(function CwButton({ text, variant = 'solid', color = 'primary', size = 'medium', iconPosition = 'left', pressed, className = '', icon = "", title, tooltipPosition = "bottom", badge, children, ...buttonProps }, ref) {
|
|
1250
1328
|
// Build CSS classes based on variant and props
|
|
1251
1329
|
let buttonClass = `cw-button-${variant}`;
|
|
1252
1330
|
// Add icon class only for icon variant without children
|
|
@@ -1259,13 +1337,19 @@ const CwButton = React.forwardRef(function CwButton({ text, variant = 'solid', c
|
|
|
1259
1337
|
const tooltipContent = title || (variant === 'icon' && text ? text : undefined);
|
|
1260
1338
|
const iconElement = icon ? jsxRuntime.jsx(CwIcon, { iconId: icon }) : null;
|
|
1261
1339
|
const textElement = text ? jsxRuntime.jsx("strong", { children: text }) : null;
|
|
1340
|
+
// Overlaid, not content: the `cwi-` condition above deliberately ignores it, so a badge
|
|
1341
|
+
// never suppresses the button's own icon. Size defaulted explicitly, not by spread order,
|
|
1342
|
+
// so `size: undefined` in the object cannot clobber it.
|
|
1343
|
+
const badgeElement = badge
|
|
1344
|
+
? jsxRuntime.jsx(CwBadge, { ...badge, size: badge.size ?? (variant === 'icon' ? 'small' : size) })
|
|
1345
|
+
: null;
|
|
1262
1346
|
// Only emit toggle attributes when `pressed` is defined; otherwise output stays identical to a normal button.
|
|
1263
1347
|
const pressedProps = pressed !== undefined
|
|
1264
1348
|
? { "aria-pressed": pressed, "data-pressed": pressed ? "true" : undefined }
|
|
1265
1349
|
: {};
|
|
1266
|
-
const buttonElement = (jsxRuntime.jsx("button", { ref: ref, type: "button", className: buttonClass, ...buttonProps, "data-color": color, "data-size": size, ...pressedProps, "aria-label":
|
|
1267
|
-
|
|
1268
|
-
|
|
1350
|
+
const buttonElement = (jsxRuntime.jsx("button", { ref: ref, type: "button", className: buttonClass, ...buttonProps, "data-color": color, "data-size": size, "data-has-badge": badge ? "true" : undefined, ...pressedProps, "aria-label": buttonProps["aria-label"] ?? tooltipContent, children: variant === 'icon' ? badgeElement : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [children ?? (iconPosition === 'right'
|
|
1351
|
+
? jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [textElement, iconElement] })
|
|
1352
|
+
: jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [iconElement, textElement] })), badgeElement] })) }));
|
|
1269
1353
|
return tooltipContent ? (jsxRuntime.jsx(CwTooltipNew, { content: tooltipContent, position: tooltipPosition, displayInline: true, children: buttonElement })) : (buttonElement);
|
|
1270
1354
|
});
|
|
1271
1355
|
CwButton.displayName = "CwButton";
|
|
@@ -2654,8 +2738,12 @@ function CwTableServerSide({ columns, data, totalItems, pagination = false, page
|
|
|
2654
2738
|
}, min: 1, max: totalPages }), jsxRuntime.jsx("span", { children: "/" }), jsxRuntime.jsx("span", { children: totalPages }), jsxRuntime.jsx(CwButton, { onClick: () => handlePageChange(state.page + 1), disabled: state.page === totalPages || totalPages <= 1, variant: "icon", icon: "chevron-right" }), jsxRuntime.jsx(CwButton, { onClick: () => handlePageChange(totalPages), disabled: state.page === totalPages || totalPages <= 1, variant: "icon", icon: "chevron-right-double" })] })] }))] }));
|
|
2655
2739
|
}
|
|
2656
2740
|
|
|
2657
|
-
var styles$n = {"cw-tabs":"cw-tabs-module__cw-tabs__1pmji","
|
|
2741
|
+
var styles$n = {"cw-tabs":"cw-tabs-module__cw-tabs__1pmji","cw-tabs-content":"cw-tabs-module__cw-tabs-content__HTp8d"};
|
|
2658
2742
|
|
|
2743
|
+
const BADGE_COLOR_SCHEMES = ['primary', 'danger', 'warning', 'success', 'info', 'neutral'];
|
|
2744
|
+
function isBadgeColorScheme(value) {
|
|
2745
|
+
return BADGE_COLOR_SCHEMES.includes(value);
|
|
2746
|
+
}
|
|
2659
2747
|
const TabIcon = ({ icon }) => {
|
|
2660
2748
|
if (!icon)
|
|
2661
2749
|
return null;
|
|
@@ -2704,7 +2792,11 @@ function CwTabs(CwTabsProps) {
|
|
|
2704
2792
|
const tabsListStyle = position === 'left' && CwTabsProps.tabsListWidth
|
|
2705
2793
|
? { minWidth: CwTabsProps.tabsListWidth }
|
|
2706
2794
|
: undefined;
|
|
2707
|
-
return (jsxRuntime.jsxs("div", { id: CwTabsProps.id, "data-testid": CwTabsProps.testId, className: styles$n['cw-tabs'] + (CwTabsProps.className ? ` ${CwTabsProps.className}` : "") + "", style: CwTabsProps.style, "data-tabs-position": position, children: [jsxRuntime.jsx("ul", { style: tabsListStyle, children: CwTabsProps.tabs.map(tab =>
|
|
2795
|
+
return (jsxRuntime.jsxs("div", { id: CwTabsProps.id, "data-testid": CwTabsProps.testId, className: styles$n['cw-tabs'] + (CwTabsProps.className ? ` ${CwTabsProps.className}` : "") + "", style: CwTabsProps.style, "data-tabs-position": position, children: [jsxRuntime.jsx("ul", { style: tabsListStyle, children: CwTabsProps.tabs.map(tab => {
|
|
2796
|
+
const badgeScheme = tab.badgeColor && isBadgeColorScheme(tab.badgeColor) ? tab.badgeColor : undefined;
|
|
2797
|
+
const rawBadgeColor = tab.badgeColor && !badgeScheme ? tab.badgeColor : undefined;
|
|
2798
|
+
return (jsxRuntime.jsxs("li", { className: `${tab.key === activeTab ? "cw-tab-active" : ""}`, onClick: () => handleTabClick(tab), "data-active": tab.key === activeTab, "data-tab-key": tab.key, "data-badge-themed": tab.badgeColor ? "true" : undefined, children: [jsxRuntime.jsx(TabIcon, { icon: tab.icon }), tab.title, (tab.badge !== undefined || tab.badgeColor) && (jsxRuntime.jsx(CwBadge, { count: typeof tab.badge === 'number' ? tab.badge : undefined, content: typeof tab.badge === 'string' ? tab.badge : undefined, size: "medium", color: badgeScheme ?? 'primary', variant: badgeScheme ? 'solid' : 'soft', style: rawBadgeColor ? { backgroundColor: rawBadgeColor, color: getContrastColor(rawBadgeColor) } : undefined }))] }, tab.key));
|
|
2799
|
+
}) }), jsxRuntime.jsx("div", { className: styles$n['cw-tabs-content'], "data-active-tab-key": activeTab ?? undefined, style: CwTabsProps.contentHeight ? { '--tabs-height': CwTabsProps.contentHeight } : undefined, children: activeTab !== null && CwTabsProps.tabs.find(tab => tab.key === activeTab)?.content })] }));
|
|
2708
2800
|
}
|
|
2709
2801
|
|
|
2710
2802
|
/**
|
|
@@ -3253,14 +3345,16 @@ function CwInput(CwInputProps) {
|
|
|
3253
3345
|
* ```
|
|
3254
3346
|
*/
|
|
3255
3347
|
function CwDigit(props) {
|
|
3256
|
-
const { alignProps, buttonProps, iconProps, labelProps, feedback, ...inputProps } = props;
|
|
3348
|
+
const { alignProps, buttonProps, iconProps, labelProps, feedback, feedbackPosition, ...inputProps } = props;
|
|
3257
3349
|
const feedbackMessages = feedback
|
|
3258
3350
|
? Array.isArray(feedback) ? feedback : [feedback]
|
|
3259
3351
|
: [];
|
|
3260
3352
|
const feedbackId = React.useId();
|
|
3261
3353
|
const feedbackIds = feedbackMessages.map((_, index) => `${feedbackId}-${index}`);
|
|
3262
3354
|
const describedBy = [inputProps["aria-describedby"], ...feedbackIds].filter(Boolean).join(" ") || undefined;
|
|
3263
|
-
|
|
3355
|
+
// data-direction drives the feedback indent, which only makes sense under a label column.
|
|
3356
|
+
const flexDirection = alignProps?.flexDirection ?? "row";
|
|
3357
|
+
return (jsxRuntime.jsxs("div", { className: "cw-input-text", "data-direction": labelProps ? flexDirection : "column", "data-feedback-position": feedbackPosition, children: [jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: inputProps.required === true ? "required" : "", children: [labelProps && (jsxRuntime.jsxs(CwLabel, { ...labelProps, children: [iconProps && jsxRuntime.jsx(CwIcon, { ...iconProps }), labelProps.text] })), jsxRuntime.jsxs("div", { className: "cw-input-button", children: [jsxRuntime.jsx("input", { type: "number", ...inputProps, "aria-describedby": describedBy }), buttonProps && jsxRuntime.jsx(CwButton, { ...buttonProps })] })] }), feedbackMessages.map((feedbackItem, index) => (jsxRuntime.jsx("p", { id: feedbackIds[index], className: "cw-input-info", "data-color": feedbackItem.type, "aria-live": "polite", children: feedbackItem.message }, index)))] }));
|
|
3264
3358
|
}
|
|
3265
3359
|
|
|
3266
3360
|
var styles$j = {"colorPreview":"cw-color-picker-module__colorPreview__ylJcD","hueBar":"cw-color-picker-module__hueBar__bFhyC","hueBarSlider":"cw-color-picker-module__hueBarSlider__D53IV","colorPickerInteractiveArea":"cw-color-picker-module__colorPickerInteractiveArea__KZFR1","colorArea":"cw-color-picker-module__colorArea__xgpSE","colorAreaOverlay":"cw-color-picker-module__colorAreaOverlay__pmgOc","hueBackground":"cw-color-picker-module__hueBackground__Mks78","whiteGradient":"cw-color-picker-module__whiteGradient__Bt-fU","blackGradient":"cw-color-picker-module__blackGradient__VnEKJ","colorAreaCursor":"cw-color-picker-module__colorAreaCursor__lotg3"};
|
|
@@ -4070,15 +4164,37 @@ const CwImageArea = React.forwardRef((props, ref) => {
|
|
|
4070
4164
|
});
|
|
4071
4165
|
CwImageArea.displayName = "CwImageArea";
|
|
4072
4166
|
|
|
4073
|
-
var styles$g = {"cw-weekday-selector":"cw-weekday-selector-
|
|
4167
|
+
var styles$g = {"container":"cw-weekday-selector-module__container__pwcvx","days":"cw-weekday-selector-module__days__Dd3RH"};
|
|
4168
|
+
|
|
4169
|
+
/* 2024-01-01 was a Monday. Formatted in UTC so a negative browser offset cannot shift a day. */
|
|
4170
|
+
const MONDAY_UTC = Date.UTC(2024, 0, 1);
|
|
4171
|
+
const DAY_IN_MS = 86_400_000;
|
|
4172
|
+
const DAY_CODES = ["M", "T", "W", "R", "F", "S", "U"];
|
|
4173
|
+
/**
|
|
4174
|
+
* Day names in the fixed MTWRFSU order the selector renders, resolved through Intl so every
|
|
4175
|
+
* locale gets its own letters (es -> LMXJVSD, de -> MDMDFSS) with no table to maintain.
|
|
4176
|
+
*
|
|
4177
|
+
* @param localeCode BCP-47 tag, e.g. "en-GB" | "es" | "de"
|
|
4178
|
+
*/
|
|
4179
|
+
function getWeekdayNames(localeCode) {
|
|
4180
|
+
const narrow = new Intl.DateTimeFormat(localeCode, { weekday: "narrow", timeZone: "UTC" });
|
|
4181
|
+
const full = new Intl.DateTimeFormat(localeCode, { weekday: "long", timeZone: "UTC" });
|
|
4182
|
+
const names = {};
|
|
4183
|
+
DAY_CODES.forEach((code, index) => {
|
|
4184
|
+
const date = new Date(MONDAY_UTC + index * DAY_IN_MS);
|
|
4185
|
+
names[code] = { letter: narrow.format(date), full: full.format(date) };
|
|
4186
|
+
});
|
|
4187
|
+
return names;
|
|
4188
|
+
}
|
|
4074
4189
|
|
|
4190
|
+
/* The week model behind CwWeekdaySelector, kept apart from the rendering. */
|
|
4075
4191
|
/**
|
|
4076
4192
|
* This class represents a week where days can be selected or unselected
|
|
4077
4193
|
* @remark Selected days are in UPPERCASE, unselected days are in lowercase
|
|
4078
4194
|
* ```
|
|
4079
4195
|
* Monday = "M" | "m"
|
|
4080
4196
|
* Tuesday = "T" | "t"
|
|
4081
|
-
*
|
|
4197
|
+
* Wednesday = "W" | "w"
|
|
4082
4198
|
* thuRsday = "R" | "r"
|
|
4083
4199
|
* Friday = "F" | "f"
|
|
4084
4200
|
* Saturday = "S" | "s"
|
|
@@ -4090,15 +4206,6 @@ class Weekdays {
|
|
|
4090
4206
|
static WEEKDAYS_STANDARD_ARRAY_EMPTY = ["m", "t", "w", "r", "f", "s", "u"];
|
|
4091
4207
|
static WEEKDAYS_STANDARD_STRING_FULL = "MTWRFSU";
|
|
4092
4208
|
static WEEKDAYS_STANDARD_STRING_EMPTY = "mtwrfsu";
|
|
4093
|
-
static WEEKDAYS_TO_USA_LETTER_FORMAT = new Map([
|
|
4094
|
-
["M", "M"],
|
|
4095
|
-
["T", "T"],
|
|
4096
|
-
["W", "W"],
|
|
4097
|
-
["R", "T"],
|
|
4098
|
-
["F", "F"],
|
|
4099
|
-
["S", "S"],
|
|
4100
|
-
["U", "S"]
|
|
4101
|
-
]);
|
|
4102
4209
|
static WEEKDAYS_TO_USA_SHORT_FORMAT = new Map([
|
|
4103
4210
|
["M", "Mon"],
|
|
4104
4211
|
["T", "Tue"],
|
|
@@ -4117,6 +4224,7 @@ class Weekdays {
|
|
|
4117
4224
|
5: "F",
|
|
4118
4225
|
6: "S"
|
|
4119
4226
|
};
|
|
4227
|
+
static DAY_NUMBER_BY_CODE = Object.fromEntries(Object.entries(Weekdays.WEEKDAY_MAP).map(([dayNumber, code]) => [code, Number(dayNumber)]));
|
|
4120
4228
|
days;
|
|
4121
4229
|
constructor(days = Weekdays.WEEKDAYS_STANDARD_ARRAY_FULL) {
|
|
4122
4230
|
if (typeof days === "string")
|
|
@@ -4160,11 +4268,11 @@ class Weekdays {
|
|
|
4160
4268
|
toString() {
|
|
4161
4269
|
return this.days.join("").trim();
|
|
4162
4270
|
}
|
|
4163
|
-
toStringFormatted(limiters = { startExistingDay: "{",
|
|
4271
|
+
toStringFormatted(limiters = { startExistingDay: "{", endExistingDay: "}", startMissingDay: "(", endMissingDay: ")", separator: " " }, format = Weekdays.WEEKDAYS_TO_USA_SHORT_FORMAT) {
|
|
4164
4272
|
const result = new Array();
|
|
4165
4273
|
[...this.days].forEach((letter, index) => {
|
|
4166
4274
|
if (letter === letter.toUpperCase()) {
|
|
4167
|
-
result.push(limiters.startExistingDay + format.get(letter) + limiters.
|
|
4275
|
+
result.push(limiters.startExistingDay + format.get(letter) + limiters.endExistingDay);
|
|
4168
4276
|
}
|
|
4169
4277
|
else if (letter === letter.toLowerCase()) {
|
|
4170
4278
|
result.push(limiters.startMissingDay +
|
|
@@ -4184,33 +4292,77 @@ class Weekdays {
|
|
|
4184
4292
|
return this.toString() === Weekdays.WEEKDAYS_STANDARD_STRING_FULL;
|
|
4185
4293
|
}
|
|
4186
4294
|
static getFullWeek() {
|
|
4187
|
-
return Weekdays.WEEKDAYS_STANDARD_ARRAY_FULL;
|
|
4295
|
+
return [...Weekdays.WEEKDAYS_STANDARD_ARRAY_FULL];
|
|
4188
4296
|
}
|
|
4189
4297
|
static getEmptyWeek() {
|
|
4190
|
-
return Weekdays.WEEKDAYS_STANDARD_ARRAY_EMPTY;
|
|
4298
|
+
return [...Weekdays.WEEKDAYS_STANDARD_ARRAY_EMPTY];
|
|
4191
4299
|
}
|
|
4192
|
-
|
|
4193
|
-
|
|
4194
|
-
|
|
4195
|
-
|
|
4196
|
-
|
|
4197
|
-
|
|
4198
|
-
|
|
4199
|
-
|
|
4200
|
-
|
|
4201
|
-
if (
|
|
4202
|
-
|
|
4203
|
-
|
|
4300
|
+
/** A week with nothing selected. */
|
|
4301
|
+
static empty() {
|
|
4302
|
+
return new Weekdays(Weekdays.WEEKDAYS_STANDARD_ARRAY_EMPTY);
|
|
4303
|
+
}
|
|
4304
|
+
/**
|
|
4305
|
+
* Like {@link fromString}, but yields an empty week instead of throwing on anything invalid.
|
|
4306
|
+
* For UI fed straight from a backend field that can arrive null, empty or partial.
|
|
4307
|
+
*/
|
|
4308
|
+
static tryFromString(value) {
|
|
4309
|
+
if (!value)
|
|
4310
|
+
return Weekdays.empty();
|
|
4311
|
+
try {
|
|
4312
|
+
return Weekdays.fromString(value);
|
|
4204
4313
|
}
|
|
4205
|
-
|
|
4206
|
-
|
|
4207
|
-
updated.push(day.toLowerCase());
|
|
4314
|
+
catch {
|
|
4315
|
+
return Weekdays.empty();
|
|
4208
4316
|
}
|
|
4209
|
-
|
|
4210
|
-
|
|
4211
|
-
|
|
4317
|
+
}
|
|
4318
|
+
/** Selected flags in MTWRFSU order (Monday first). */
|
|
4319
|
+
toBooleans() {
|
|
4320
|
+
return this.days.map(day => day === day.toUpperCase());
|
|
4321
|
+
}
|
|
4322
|
+
/** @param flags selected flags in MTWRFSU order; missing entries count as unselected */
|
|
4323
|
+
static fromBooleans(flags) {
|
|
4324
|
+
return new Weekdays(Weekdays.WEEKDAYS_STANDARD_ARRAY_FULL.map((day, index) => flags[index] ? day : day.toLowerCase()));
|
|
4325
|
+
}
|
|
4326
|
+
/** 7-character mask in MTWRFSU order where "1" means selected, e.g. "1100100". */
|
|
4327
|
+
toMask() {
|
|
4328
|
+
return this.toBooleans().map(selected => (selected ? "1" : "0")).join("");
|
|
4329
|
+
}
|
|
4330
|
+
/** @param mask 7-character mask in MTWRFSU order where "1" means selected; a shorter, empty or
|
|
4331
|
+
* missing mask counts the absent days as unselected */
|
|
4332
|
+
static fromMask(mask) {
|
|
4333
|
+
return Weekdays.fromBooleans(Weekdays.WEEKDAYS_STANDARD_ARRAY_FULL.map((_, index) => mask?.[index] === "1"));
|
|
4334
|
+
}
|
|
4335
|
+
/** Selected days as Date.getDay() numbers (0 = Sunday), in MTWRFSU order. */
|
|
4336
|
+
toDayNumbers() {
|
|
4337
|
+
return this.days
|
|
4338
|
+
.filter(day => day === day.toUpperCase())
|
|
4339
|
+
.map(day => Weekdays.DAY_NUMBER_BY_CODE[day]);
|
|
4340
|
+
}
|
|
4341
|
+
/** @param days Date.getDay() numbers (0 = Sunday) */
|
|
4342
|
+
static fromDayNumbers(days) {
|
|
4343
|
+
const selected = new Set(days);
|
|
4344
|
+
return Weekdays.fromBooleans(Weekdays.WEEKDAYS_STANDARD_ARRAY_FULL.map(day => selected.has(Weekdays.DAY_NUMBER_BY_CODE[day])));
|
|
4345
|
+
}
|
|
4346
|
+
}
|
|
4347
|
+
|
|
4348
|
+
const CwWeekdaySelector = ({ value = "mtwrfsu", onChange, disabled = false, labelProps, layout, feedback, locale = "en-GB", className }) => {
|
|
4349
|
+
const selectedDays = Weekdays.tryFromString(value).toArray();
|
|
4350
|
+
const dayNames = React.useMemo(() => getWeekdayNames(locale), [locale]);
|
|
4351
|
+
const handleChange = (day, checked) => {
|
|
4352
|
+
const updated = selectedDays.filter(d => d !== day && d !== day.toLowerCase());
|
|
4353
|
+
updated.push(checked ? day : day.toLowerCase());
|
|
4354
|
+
onChange?.(new Weekdays(updated).toString());
|
|
4212
4355
|
};
|
|
4213
|
-
|
|
4356
|
+
const feedbackMessages = feedback
|
|
4357
|
+
? Array.isArray(feedback) ? feedback : [feedback]
|
|
4358
|
+
: [];
|
|
4359
|
+
const feedbackId = React.useId();
|
|
4360
|
+
const feedbackIds = feedbackMessages.map((_, index) => `${feedbackId}-${index}`);
|
|
4361
|
+
const describedBy = feedbackIds.join(" ") || undefined;
|
|
4362
|
+
// Points at the label element rather than copying its text, which also covers a labelProps that
|
|
4363
|
+
// carries children instead of `text`.
|
|
4364
|
+
const labelId = labelProps?.id ?? `${feedbackId}-label`;
|
|
4365
|
+
return (jsxRuntime.jsxs("div", { className: `cw-weekday-selector ${styles$g.container}${className ? ` ${className}` : ""}`, "data-direction": labelProps ? layout?.direction ?? "row" : "column", "data-align": layout?.align, "data-gap": layout?.gap, children: [labelProps && jsxRuntime.jsx(CwLabel, { id: labelId, ...labelProps }), jsxRuntime.jsx("div", { role: "group", className: styles$g.days, "aria-labelledby": labelProps ? labelId : undefined, "aria-describedby": describedBy, children: Weekdays.getFullWeek().map(day => (jsxRuntime.jsx("input", { type: "checkbox", "data-day": day, "data-letter": dayNames[day].letter, "aria-label": dayNames[day].full, title: dayNames[day].full, checked: selectedDays.includes(day), onChange: (e) => handleChange(day, e.target.checked), disabled: disabled }, day))) }), feedbackMessages.map((feedbackItem, index) => (jsxRuntime.jsx("p", { id: feedbackIds[index], className: "cw-input-feedback", "data-color": feedbackItem.type, "aria-live": "polite", children: feedbackItem.message }, index)))] }));
|
|
4214
4366
|
};
|
|
4215
4367
|
|
|
4216
4368
|
var styles$f = {"check-container":"cw-check-module__check-container__4nscZ","group":"cw-check-module__group__6JCQo","options":"cw-check-module__options__-g9LF"};
|
|
@@ -4258,6 +4410,9 @@ function CwCheckboxGroup({ options, value = [], onChange, labelProps, groupLayou
|
|
|
4258
4410
|
const feedbackMessages = feedback
|
|
4259
4411
|
? Array.isArray(feedback) ? feedback : [feedback]
|
|
4260
4412
|
: [];
|
|
4413
|
+
const feedbackId = React.useId();
|
|
4414
|
+
const feedbackIds = feedbackMessages.map((_, index) => `${feedbackId}-${index}`);
|
|
4415
|
+
const describedBy = feedbackIds.join(" ") || undefined;
|
|
4261
4416
|
// Effective layout — precedence: new `groupLayout`/`itemLayout` > legacy-derived > default.
|
|
4262
4417
|
// Legacy `alignProps.flexDirection` drove the label-vs-options axis (default "row" = label
|
|
4263
4418
|
// beside the options); map it to `groupLayout.direction`.
|
|
@@ -4270,7 +4425,7 @@ function CwCheckboxGroup({ options, value = [], onChange, labelProps, groupLayou
|
|
|
4270
4425
|
?? (optionsAlignment === "column" ? "row" : "column");
|
|
4271
4426
|
// Each checkbox's box-to-text layout is the opposite of the options flow, mirroring CwRadioGroup.
|
|
4272
4427
|
const checkDirection = itemDirection === "row" ? "column" : "row";
|
|
4273
|
-
return (jsxRuntime.jsxs("div", { className: `cw-checkbox-group ${styles$f.group}${className ? ` ${className}` : ""}`, "data-testid": dataTestId, "data-direction": labelProps ? groupDirection : "column", "data-align": groupLayout?.align, "data-gap": groupLayout?.gap, children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsx("div", { className: styles$f.options, role: "group", "aria-label": labelProps?.text, "aria-required": required || undefined, "data-direction": itemDirection, "data-gap": itemLayout?.gap, children: options.map((option) => (jsxRuntime.jsx(CwCheck, { labelProps: { text: option.label }, checked: value.includes(option.value), disabled: disabled || option.disabled, direction: checkDirection, onChange: (e) => handleChange(option.value, e.currentTarget.checked) }, option.value))) }), feedbackMessages.map((feedbackItem, index) => (jsxRuntime.jsx("p", { className: "cw-input-
|
|
4428
|
+
return (jsxRuntime.jsxs("div", { className: `cw-checkbox-group ${styles$f.group}${className ? ` ${className}` : ""}`, "data-testid": dataTestId, "data-direction": labelProps ? groupDirection : "column", "data-align": groupLayout?.align, "data-gap": groupLayout?.gap, children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsx("div", { className: styles$f.options, role: "group", "aria-label": labelProps?.text, "aria-describedby": describedBy, "aria-required": required || undefined, "data-direction": itemDirection, "data-gap": itemLayout?.gap, children: options.map((option) => (jsxRuntime.jsx(CwCheck, { labelProps: { text: option.label }, checked: value.includes(option.value), disabled: disabled || option.disabled, direction: checkDirection, onChange: (e) => handleChange(option.value, e.currentTarget.checked) }, option.value))) }), feedbackMessages.map((feedbackItem, index) => (jsxRuntime.jsx("p", { id: feedbackIds[index], className: "cw-input-feedback", "data-color": feedbackItem.type, "aria-live": "polite", children: feedbackItem.message }, index)))] }));
|
|
4274
4429
|
}
|
|
4275
4430
|
|
|
4276
4431
|
var styles$e = {"radio":"cw-radio-module__radio__5sh7a","group":"cw-radio-module__group__br-HM","options":"cw-radio-module__options__LSw7M"};
|
|
@@ -4297,11 +4452,14 @@ function CwRadioGroup({ options, value, onChange, labelProps, groupLayout, itemL
|
|
|
4297
4452
|
const feedbackMessages = feedback
|
|
4298
4453
|
? Array.isArray(feedback) ? feedback : [feedback]
|
|
4299
4454
|
: [];
|
|
4455
|
+
const feedbackId = React.useId();
|
|
4456
|
+
const feedbackIds = feedbackMessages.map((_, index) => `${feedbackId}-${index}`);
|
|
4457
|
+
const describedBy = feedbackIds.join(" ") || undefined;
|
|
4300
4458
|
// Each radio's circle-to-text layout is the opposite of the options flow: a stacked list
|
|
4301
4459
|
// (itemLayout column) reads best with the circle beside the text; a side-by-side row reads
|
|
4302
4460
|
// best with the circle above the text.
|
|
4303
4461
|
const radioDirection = itemLayout?.direction === "row" ? "column" : "row";
|
|
4304
|
-
return (jsxRuntime.jsxs("div", { className: `cw-radio-group ${styles$e.group}${className ? ` ${className}` : ""}`, "data-testid": dataTestId, "data-direction": labelProps ? (groupLayout?.direction ?? "column") : "column", "data-align": groupLayout?.align, "data-gap": groupLayout?.gap, children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsx("div", { className: styles$e.options, role: "radiogroup", "aria-labelledby": ariaLabelledby, "aria-label": ariaLabelledby ? undefined : (ariaLabel ?? labelProps?.text), "aria-required": required || undefined, "data-direction": itemLayout?.direction ?? "column", "data-gap": itemLayout?.gap, children: options.map((option) => (jsxRuntime.jsx(CwRadio, { name: groupName, label: option.label, direction: radioDirection, checked: value === option.value, required: required, disabled: disabled || option.disabled, onChange: () => onChange(option.value) }, option.value))) }), feedbackMessages.map((feedbackItem, index) => (jsxRuntime.jsx("p", { className: "cw-input-
|
|
4462
|
+
return (jsxRuntime.jsxs("div", { className: `cw-radio-group ${styles$e.group}${className ? ` ${className}` : ""}`, "data-testid": dataTestId, "data-direction": labelProps ? (groupLayout?.direction ?? "column") : "column", "data-align": groupLayout?.align, "data-gap": groupLayout?.gap, children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsx("div", { className: styles$e.options, role: "radiogroup", "aria-describedby": describedBy, "aria-labelledby": ariaLabelledby, "aria-label": ariaLabelledby ? undefined : (ariaLabel ?? labelProps?.text), "aria-required": required || undefined, "data-direction": itemLayout?.direction ?? "column", "data-gap": itemLayout?.gap, children: options.map((option) => (jsxRuntime.jsx(CwRadio, { name: groupName, label: option.label, direction: radioDirection, checked: value === option.value, required: required, disabled: disabled || option.disabled, onChange: () => onChange(option.value) }, option.value))) }), feedbackMessages.map((feedbackItem, index) => (jsxRuntime.jsx("p", { id: feedbackIds[index], className: "cw-input-feedback", "data-color": feedbackItem.type, "aria-live": "polite", children: feedbackItem.message }, index)))] }));
|
|
4305
4463
|
}
|
|
4306
4464
|
|
|
4307
4465
|
function CwToggle(props) {
|
|
@@ -4481,6 +4639,13 @@ function CwDropdown({ options, value, onChange, labelProps, alignProps, placehol
|
|
|
4481
4639
|
const feedbackMessages = feedback
|
|
4482
4640
|
? Array.isArray(feedback) ? feedback : [feedback]
|
|
4483
4641
|
: [];
|
|
4642
|
+
const feedbackId = React.useId();
|
|
4643
|
+
const feedbackIds = feedbackMessages.map((_, index) => `${feedbackId}-${index}`);
|
|
4644
|
+
const describedBy = feedbackIds.join(" ") || undefined;
|
|
4645
|
+
// The trigger is named by reference - the label for the field, the content for the current
|
|
4646
|
+
// value - so neither has to be copied into a string.
|
|
4647
|
+
const labelId = labelProps?.id ?? `${feedbackId}-label`;
|
|
4648
|
+
const valueId = `${feedbackId}-value`;
|
|
4484
4649
|
// Scroll highlighted item into view
|
|
4485
4650
|
React.useEffect(() => {
|
|
4486
4651
|
if (isOpen && highlightedItemRef.current) {
|
|
@@ -4549,12 +4714,12 @@ function CwDropdown({ options, value, onChange, labelProps, alignProps, placehol
|
|
|
4549
4714
|
}
|
|
4550
4715
|
}, [isOpen, highlightedIndex, filteredOptions, handleOptionSelect]);
|
|
4551
4716
|
const flexDirection = alignProps?.flexDirection ?? "row";
|
|
4552
|
-
return (jsxRuntime.
|
|
4553
|
-
|
|
4554
|
-
|
|
4555
|
-
|
|
4556
|
-
|
|
4557
|
-
|
|
4717
|
+
return (jsxRuntime.jsx("div", { ref: containerRef, className: `cw-dropdown${className ? ` ${className}` : ""}`, "data-direction": flexDirection, style: style, ...otherProps, children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && jsxRuntime.jsx(CwLabel, { id: labelId, ...labelProps }), jsxRuntime.jsxs("div", { className: dropdownStyles.value, children: [jsxRuntime.jsxs("div", { className: "cw-dropdown-wrapper", ref: wrapperRef, children: [jsxRuntime.jsxs("button", { type: "button", className: "cw-dropdown-trigger", onClick: handleTriggerClick, onKeyDown: handleKeyDown, disabled: disabled, "aria-haspopup": "listbox", "aria-expanded": isOpen, "aria-labelledby": labelProps ? `${labelId} ${valueId}` : undefined, "aria-label": labelProps ? undefined : (selectedOption?.label || placeholder), "aria-describedby": describedBy, children: [jsxRuntime.jsx("div", { className: "cw-dropdown-trigger-content", id: valueId, children: selectedOption ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [selectedOption.color && (jsxRuntime.jsx("span", { className: dropdownStyles.colorCircle, style: { backgroundColor: selectedOption.color } })), jsxRuntime.jsx("span", { children: selectedOption.label })] })) : (jsxRuntime.jsx("span", { className: "cw-dropdown-placeholder", children: placeholder })) }), jsxRuntime.jsx(CwIcon, { iconId: "chevron-down", size: "small" })] }), renderPanel(jsxRuntime.jsxs("div", { ref: panelRef, className: dropdownStyles.dropdown, style: panelStyle, role: "listbox", onKeyDown: handleKeyDown, children: [allowSearch && (jsxRuntime.jsx("div", { className: dropdownStyles.searchBox, children: jsxRuntime.jsx("input", { ref: inputRef, type: "text", placeholder: "Search...", value: searchText, onChange: handleSearchChange, onKeyDown: handleKeyDown, className: dropdownStyles.searchInput, autoComplete: "off" }) })), jsxRuntime.jsx("ul", { children: filteredOptions.length > 0 ? (filteredOptions.map((option, index) => (jsxRuntime.jsxs("li", { ref: highlightedIndex === index ? highlightedItemRef : null, className: [
|
|
4718
|
+
dropdownStyles.option,
|
|
4719
|
+
value === option.value ? dropdownStyles.optionSelected : "",
|
|
4720
|
+
highlightedIndex === index ? dropdownStyles.optionFocused : "",
|
|
4721
|
+
option.disabled ? dropdownStyles.optionDisabled : "",
|
|
4722
|
+
].filter(Boolean).join(" "), onClick: () => !option.disabled && handleOptionSelect(option.value), onMouseEnter: () => setHighlightedIndex(index), role: "option", "aria-selected": value === option.value, "aria-disabled": option.disabled, children: [option.color && (jsxRuntime.jsx("span", { className: dropdownStyles.colorCircle, style: { backgroundColor: option.color } })), jsxRuntime.jsx("span", { children: option.label })] }, option.value)))) : (jsxRuntime.jsx("li", { className: dropdownStyles.emptyState, children: "No options available" })) })] }))] }), feedbackMessages.map((item, index) => (jsxRuntime.jsx("p", { id: feedbackIds[index], className: "cw-input-feedback", "data-color": item.type, "aria-live": "polite", children: item.message }, index)))] })] }) }));
|
|
4558
4723
|
}
|
|
4559
4724
|
|
|
4560
4725
|
function CwDropdownFilter(props) {
|
|
@@ -4821,21 +4986,29 @@ var styles$b = {"cw-multi-filter-catalog-container":"cw-multi-filter-module__cw-
|
|
|
4821
4986
|
* @param {CwMultiFilterProps} props
|
|
4822
4987
|
* @returns Set the `onChange` callback to a function to check for changes in the selected filters
|
|
4823
4988
|
*/
|
|
4824
|
-
const CwMultiFilter = ({ allTags, id, onChangeSelectedTags, selectedTags, placeholder = "Write to filter", allCategoriesLabel = "ALL CATEGORIES", className, style }) => {
|
|
4989
|
+
const CwMultiFilter = ({ allTags, id, onChangeSelectedTags, selectedTags, placeholder = "Write to filter", allCategoriesLabel = "ALL CATEGORIES", className, style, testId, initialTagVisibility = "all" }) => {
|
|
4825
4990
|
const [inputTextValue, setInputTextValue] = React.useState("");
|
|
4826
4991
|
const [isPanelOpen, setIsPanelOpen] = React.useState(false);
|
|
4827
4992
|
const [selectedCategory, setSelectedCategory] = React.useState("All");
|
|
4993
|
+
// True once the user touches the current opening (any category click or a search); gates the cascade.
|
|
4994
|
+
const [hasInteracted, setHasInteracted] = React.useState(false);
|
|
4828
4995
|
const componentRef = React.useRef(null);
|
|
4829
4996
|
const inputRef = React.useRef(null);
|
|
4830
4997
|
const wrapperRef = React.useRef(null);
|
|
4831
4998
|
const { panelRef, panelStyle, renderPanel } = useDropdownPortal({
|
|
4832
4999
|
anchorRef: wrapperRef,
|
|
4833
5000
|
isOpen: isPanelOpen,
|
|
4834
|
-
onClose: () =>
|
|
5001
|
+
onClose: () => setIsPanelOpen(false),
|
|
4835
5002
|
});
|
|
5003
|
+
// Single reset point for all transient panel state on close, whatever closed it - the clear-all
|
|
5004
|
+
// button closes the panel directly and bypasses onClose, so resetting here covers every path.
|
|
4836
5005
|
React.useEffect(() => {
|
|
4837
|
-
|
|
4838
|
-
|
|
5006
|
+
if (!isPanelOpen) {
|
|
5007
|
+
setHasInteracted(false);
|
|
5008
|
+
setSelectedCategory("All");
|
|
5009
|
+
setInputTextValue("");
|
|
5010
|
+
}
|
|
5011
|
+
}, [isPanelOpen]);
|
|
4839
5012
|
const categoriesMappedToTags = () => {
|
|
4840
5013
|
const categoriesMap = new Map();
|
|
4841
5014
|
allTags.forEach(tag => {
|
|
@@ -4846,6 +5019,9 @@ const CwMultiFilter = ({ allTags, id, onChangeSelectedTags, selectedTags, placeh
|
|
|
4846
5019
|
return categoriesMap;
|
|
4847
5020
|
};
|
|
4848
5021
|
const displayTags = React.useMemo(() => {
|
|
5022
|
+
if (initialTagVisibility === "afterCategoryOrSearch" && !hasInteracted) {
|
|
5023
|
+
return [];
|
|
5024
|
+
}
|
|
4849
5025
|
let tags = Array.from(allTags);
|
|
4850
5026
|
if (selectedCategory !== "All") {
|
|
4851
5027
|
tags = tags.filter(t => t.Category === selectedCategory);
|
|
@@ -4855,8 +5031,9 @@ const CwMultiFilter = ({ allTags, id, onChangeSelectedTags, selectedTags, placeh
|
|
|
4855
5031
|
tags = tags.filter(t => t.Name.replaceAll(" ", "").toLowerCase().includes(input));
|
|
4856
5032
|
}
|
|
4857
5033
|
return tags;
|
|
4858
|
-
}, [allTags, selectedCategory, inputTextValue]);
|
|
5034
|
+
}, [allTags, selectedCategory, inputTextValue, initialTagVisibility, hasInteracted]);
|
|
4859
5035
|
const handleClickCategory = (category) => {
|
|
5036
|
+
setHasInteracted(true);
|
|
4860
5037
|
setSelectedCategory(category);
|
|
4861
5038
|
};
|
|
4862
5039
|
const rgbAString = (r, g, b) => {
|
|
@@ -4881,6 +5058,8 @@ const CwMultiFilter = ({ allTags, id, onChangeSelectedTags, selectedTags, placeh
|
|
|
4881
5058
|
const handleInputText = (input) => {
|
|
4882
5059
|
if (selectedCategory !== "All")
|
|
4883
5060
|
setSelectedCategory("All");
|
|
5061
|
+
if (input.trim() !== "")
|
|
5062
|
+
setHasInteracted(true);
|
|
4884
5063
|
setInputTextValue(input.trimStart());
|
|
4885
5064
|
};
|
|
4886
5065
|
const addTag = (newTag) => {
|
|
@@ -4907,7 +5086,7 @@ const CwMultiFilter = ({ allTags, id, onChangeSelectedTags, selectedTags, placeh
|
|
|
4907
5086
|
inputRef.current?.focus();
|
|
4908
5087
|
}
|
|
4909
5088
|
};
|
|
4910
|
-
return (jsxRuntime.jsxs("form", { ref: componentRef, id: id, className: `${styles$b["cw-multi-filter"]}${className ? ` ${className}` : ""}`, style: style, onSubmit: (e) => {
|
|
5089
|
+
return (jsxRuntime.jsxs("form", { ref: componentRef, id: id, "data-testid": testId, className: `${styles$b["cw-multi-filter"]}${className ? ` ${className}` : ""}`, style: style, onSubmit: (e) => {
|
|
4911
5090
|
e.preventDefault();
|
|
4912
5091
|
}, children: [jsxRuntime.jsxs("div", { onClick: handleDivClick, ref: wrapperRef, className: styles$b["cw-multi-filter-search"], style: isPanelOpen ? { outline: "1px solid var(--cw-color-outline-variant)" } : {}, children: [jsxRuntime.jsxs("ul", { id: id + "_selected_filters", children: [Array.from(selectedTags).map(tag => (React.createElement(CwMultiFilterTag, { ...tag, key: tag.ID, Selectable: false, Removable: true, OnRemove: () => removeTag(tag.ID) }))), jsxRuntime.jsx("input", { type: "text", id: id + "_input", ref: inputRef, value: inputTextValue, spellCheck: false, onFocus: () => setIsPanelOpen(true), onChange: e => handleInputText(e.currentTarget.value), autoComplete: "off", placeholder: selectedTags.size === 0 ? placeholder : "", onKeyDown: e => {
|
|
4913
5092
|
switch (e.key) {
|
|
@@ -4962,7 +5141,7 @@ const CwMultiFilter = ({ allTags, id, onChangeSelectedTags, selectedTags, placeh
|
|
|
4962
5141
|
} }, props.ID))) })] }))] }));
|
|
4963
5142
|
};
|
|
4964
5143
|
|
|
4965
|
-
var styles$a = {"container":"cw-tag-selector-module__container__-do8i","inputBox":"cw-tag-selector-module__inputBox__3NGz9 cw-choice-input-box-module__inputBox__gHY9d","disabled":"cw-tag-selector-module__disabled__vbud9 cw-choice-input-box-module__disabled__TFAnC","dropdown":"cw-tag-selector-module__dropdown__X6Dob cw-choice-dropdown-module__dropdown__P0b4j","option":"cw-tag-selector-module__option__2UQ7g cw-choice-dropdown-module__option__uR-ro","optionFocused":"cw-tag-selector-module__optionFocused__8-lv8 cw-choice-dropdown-module__optionFocused__BYMxj","optionDot":"cw-tag-selector-module__optionDot__CdFlG cw-choice-dropdown-module__colorCircle__x7mI9","selectAll":"cw-tag-selector-module__selectAll__HyvMA"};
|
|
5144
|
+
var styles$a = {"container":"cw-tag-selector-module__container__-do8i","value":"cw-tag-selector-module__value__TDAy3","inputBox":"cw-tag-selector-module__inputBox__3NGz9 cw-choice-input-box-module__inputBox__gHY9d","disabled":"cw-tag-selector-module__disabled__vbud9 cw-choice-input-box-module__disabled__TFAnC","dropdown":"cw-tag-selector-module__dropdown__X6Dob cw-choice-dropdown-module__dropdown__P0b4j","option":"cw-tag-selector-module__option__2UQ7g cw-choice-dropdown-module__option__uR-ro","optionFocused":"cw-tag-selector-module__optionFocused__8-lv8 cw-choice-dropdown-module__optionFocused__BYMxj","optionDot":"cw-tag-selector-module__optionDot__CdFlG cw-choice-dropdown-module__colorCircle__x7mI9","selectAll":"cw-tag-selector-module__selectAll__HyvMA"};
|
|
4966
5145
|
|
|
4967
5146
|
/**
|
|
4968
5147
|
* Multi-select input with chip tags and searchable dropdown.
|
|
@@ -5097,8 +5276,11 @@ function CwTagSelector({ id, options, value, onChange, labelProps, iconProps, al
|
|
|
5097
5276
|
// Keeping containerRef for any other potential use
|
|
5098
5277
|
const direction = alignProps?.flexDirection ?? "row";
|
|
5099
5278
|
const feedbackMessages = feedback ? (Array.isArray(feedback) ? feedback : [feedback]) : [];
|
|
5100
|
-
|
|
5101
|
-
|
|
5279
|
+
const feedbackId = React.useId();
|
|
5280
|
+
const feedbackIds = feedbackMessages.map((_, index) => `${feedbackId}-${index}`);
|
|
5281
|
+
const describedBy = feedbackIds.join(" ") || undefined;
|
|
5282
|
+
return (jsxRuntime.jsxs("div", { ref: containerRef, className: `${styles$a.container}${className ? ` ${className}` : ""}`, style: style, id: id, "data-direction": direction, children: [jsxRuntime.jsxs(CwAlign, { ...alignProps, children: [labelProps && (jsxRuntime.jsxs(CwLabel, { ...labelProps, children: [iconProps && jsxRuntime.jsx(CwIcon, { ...iconProps }), labelProps.text] })), jsxRuntime.jsxs("div", { className: styles$a.value, children: [jsxRuntime.jsxs("div", { className: `${styles$a.inputBox}${disabled ? ` ${styles$a.disabled}` : ""}`, ref: inputBoxRef, onClick: () => { if (!disabled)
|
|
5283
|
+
inputRef.current?.focus(); }, children: [selectedOptions.map(opt => (jsxRuntime.jsx(CwChip, { label: opt.label, colorScheme: opt.color ? "custom" : "info", customColor: opt.color, closable: !disabled, onClose: () => handleRemove(opt.value) }, opt.value))), jsxRuntime.jsx("input", { ref: inputRef, type: "text", value: search, onChange: handleInputChange, onFocus: handleInputFocus, onKeyDown: handleKeyDown, placeholder: selectedOptions.length === 0 ? placeholder : "", disabled: disabled, autoComplete: "off", "aria-describedby": describedBy }), value.length > 0 && !disabled && (jsxRuntime.jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onMouseDown: (e) => e.preventDefault(), onClick: (e) => { e.stopPropagation(); onChange([]); setSearch(""); setOpen(false); }, tabIndex: -1, "aria-label": "Clear all" }))] }), feedbackMessages.map((fb, i) => (jsxRuntime.jsx("p", { id: feedbackIds[i], className: "cw-input-feedback", "data-color": fb.type, "aria-live": "polite", children: fb.message }, i)))] })] }), renderPanel((showSelectAll || filtered.length > 0) ? (jsxRuntime.jsxs("div", { ref: panelRef, className: styles$a.dropdown, style: panelStyle, children: [showSelectAll && !search && (jsxRuntime.jsxs("div", { className: styles$a.selectAll, onMouseDown: (e) => e.preventDefault(), onClick: handleToggleAll, children: [jsxRuntime.jsx("input", { type: "checkbox", checked: allSelected, readOnly: true, tabIndex: -1 }), allSelected ? "Deselect all" : "Select all"] })), jsxRuntime.jsx("ul", { ref: listRef, children: filtered.map((opt, idx) => (jsxRuntime.jsxs("li", { className: `${styles$a.option}${idx === focusedIndex ? ` ${styles$a.optionFocused}` : ""}`, onMouseDown: (e) => e.preventDefault(), onClick: () => handleSelect(opt.value), onMouseEnter: () => setFocusedIndex(idx), title: opt.tooltip, children: [opt.color && jsxRuntime.jsx("span", { className: styles$a.optionDot, style: { backgroundColor: opt.color } }), opt.label] }, opt.value))) })] })) : null)] }));
|
|
5102
5284
|
}
|
|
5103
5285
|
|
|
5104
5286
|
var styles$9 = {"tree-container":"cw-tree-view-module__tree-container__NN-HJ","tree-wrapper":"cw-tree-view-module__tree-wrapper__keBZI","tree-item":"cw-tree-view-module__tree-item__prE9N","tree-node":"cw-tree-view-module__tree-node__wfro9","selected":"cw-tree-view-module__selected__XJQ0w","non-selectable":"cw-tree-view-module__non-selectable__YuPSx","tree-children":"cw-tree-view-module__tree-children__ji8CZ","empty-state":"cw-tree-view-module__empty-state__yvRjo","tree-label":"cw-tree-view-module__tree-label__ss3Nf","tree-spacer":"cw-tree-view-module__tree-spacer__E9Ud2"};
|
|
@@ -6109,7 +6291,7 @@ function CwBtnCancel({ cw_btnOnclick, cw_btn_disabled, onClick, disabled, ...res
|
|
|
6109
6291
|
return (jsxRuntime.jsx(CwButton, { ...rest, variant: "icon", icon: "cancel", color: "danger", onClick: onClick ?? cw_btnOnclick, disabled: disabled ?? cw_btn_disabled, title: "Cancel" }));
|
|
6110
6292
|
}
|
|
6111
6293
|
|
|
6112
|
-
var styles$4 = {"pickerWrapper":"cw-pickers-base-module__pickerWrapper__Fb9Zo","pickerIcons":"cw-pickers-base-module__pickerIcons__dyd2-","pickerPopup":"cw-pickers-base-module__pickerPopup__dkxJo"};
|
|
6294
|
+
var styles$4 = {"value":"cw-pickers-base-module__value__BR67P","pickerWrapper":"cw-pickers-base-module__pickerWrapper__Fb9Zo","pickerIcons":"cw-pickers-base-module__pickerIcons__dyd2-","pickerPopup":"cw-pickers-base-module__pickerPopup__dkxJo"};
|
|
6113
6295
|
|
|
6114
6296
|
/**
|
|
6115
6297
|
* Renders a picker popup in a portal so it escapes overflow containers.
|
|
@@ -6166,6 +6348,9 @@ function CwDatePicker({ value, onChange, minDate, maxDate, disabledDates, disabl
|
|
|
6166
6348
|
const feedbackMessages = feedback
|
|
6167
6349
|
? Array.isArray(feedback) ? feedback : [feedback]
|
|
6168
6350
|
: [];
|
|
6351
|
+
const feedbackId = React.useId();
|
|
6352
|
+
const feedbackIds = feedbackMessages.map((_, index) => `${feedbackId}-${index}`);
|
|
6353
|
+
const describedBy = feedbackIds.join(" ") || undefined;
|
|
6169
6354
|
const wrapperRef = React.useRef(null);
|
|
6170
6355
|
const inputRef = React.useRef(null);
|
|
6171
6356
|
const prevValueRef = React.useRef(undefined);
|
|
@@ -6346,11 +6531,11 @@ function CwDatePicker({ value, onChange, minDate, maxDate, disabledDates, disabl
|
|
|
6346
6531
|
...(maxDate ? [{ after: maxDate }] : []),
|
|
6347
6532
|
...(disabledMatcher ? [disabledMatcher] : []),
|
|
6348
6533
|
], [disabledDates, minDate, maxDate, disabledMatcher]);
|
|
6349
|
-
return (jsxRuntime.
|
|
6350
|
-
|
|
6351
|
-
|
|
6352
|
-
|
|
6353
|
-
|
|
6534
|
+
return (jsxRuntime.jsx("div", { ref: containerRef, className: `cw-datepicker ${className || ""}`, children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsxs("div", { className: styles$4.value, children: [jsxRuntime.jsxs("div", { ref: wrapperRef, className: styles$4.pickerWrapper, children: [jsxRuntime.jsx("input", { ref: inputRef, type: "text", value: inputValue, placeholder: placeholder, onChange: handleInputChange, onBlur: handleInputBlur, onClick: handleInputClick, onKeyDown: handleInputKeyDown, disabled: disabled, "aria-describedby": describedBy, required: required, size: displayFormat.length }), jsxRuntime.jsx("div", { className: styles$4.pickerIcons, children: showClear && value && !disabled ? (jsxRuntime.jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClear, tabIndex: -1, "aria-label": "Clear date" })) : (jsxRuntime.jsx(CwIcon, { iconId: "calendar" })) }), renderPopup(jsxRuntime.jsxs("div", { ref: popupRef, className: styles$4.pickerPopup, style: popupStyle, children: [jsxRuntime.jsx(reactDayPicker.DayPicker, { mode: "single", selected: value || undefined, defaultMonth: defaultMonth || value || undefined, onSelect: handleDaySelect, disabled: disabledDays, numberOfMonths: numberOfMonths, locale: locale$1, captionLayout: "dropdown", startMonth: dropdownStartMonth, endMonth: dropdownEndMonth, modifiers: {
|
|
6535
|
+
today: new Date(),
|
|
6536
|
+
}, modifiersClassNames: {
|
|
6537
|
+
today: "rdp-day-today",
|
|
6538
|
+
} }), showTodayButton && (jsxRuntime.jsx("footer", { className: "cw-flex-row cw-align-right-center", children: jsxRuntime.jsx(CwButton, { type: "button", variant: "outline", onClick: handleTodayClick, text: todayLabel }) }))] }))] }), feedbackMessages.map((feedbackItem, index) => (jsxRuntime.jsx("p", { id: feedbackIds[index], className: "cw-input-feedback", "data-color": feedbackItem.type, "aria-live": "polite", children: feedbackItem.message }, index)))] })] }) }));
|
|
6354
6539
|
}
|
|
6355
6540
|
|
|
6356
6541
|
var rangeStyles = {"rangeWrapper":"cw-range-picker-module__rangeWrapper__1nIVs","rangePopup":"cw-range-picker-module__rangePopup__E5jd1","rangeCalendarRow":"cw-range-picker-module__rangeCalendarRow__VTxi0","presetList":"cw-range-picker-module__presetList__INiLo","rangeError":"cw-range-picker-module__rangeError__qHMdi"};
|
|
@@ -6989,14 +7174,14 @@ function CwDateRangePicker({ value, onChange, minDate, maxDate, disabledDates, d
|
|
|
6989
7174
|
}
|
|
6990
7175
|
return undefined;
|
|
6991
7176
|
}, [value]);
|
|
6992
|
-
return (jsxRuntime.jsx("div", { ref: containerRef, className: `cw-rangepicker ${className || ""}`, children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsxs("div", { ref: wrapperRef, className: rangeStyles.rangeWrapper, children: [jsxRuntime.jsxs("div", { className: styles$4.pickerWrapper, children: [jsxRuntime.jsx("input", { ref: inputFromRef, type: "text", value: inputFromValue, placeholder: placeholderFrom, onChange: handleInputFromChange, onBlur: () => handleInputBlur('from'), onClick: handleInputFromClick, onKeyDown: (e) => handleInputKeyDown(e, 'from'), disabled: disabled, required: required, "data-focused": focusedInput === 'from' }), jsxRuntime.jsx("div", { className: styles$4.pickerIcons, children: showClear && value?.from && !disabled ? (jsxRuntime.jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClearFrom, tabIndex: -1, "aria-label": "Clear from date" })) : (jsxRuntime.jsx(CwIcon, { iconId: "calendar" })) })] }), jsxRuntime.jsx(CwIcon, { iconId: "arrow-right", size: "medium" }), jsxRuntime.jsxs("div", { className: styles$4.pickerWrapper, children: [jsxRuntime.jsx("input", { ref: inputToRef, type: "text", value: inputToValue, placeholder: placeholderTo, onChange: handleInputToChange, onBlur: () => handleInputBlur('to'), onClick: handleInputToClick, onKeyDown: (e) => handleInputKeyDown(e, 'to'), disabled: disabled, required: required, "data-focused": focusedInput === 'to' }), jsxRuntime.jsx("div", { className: styles$4.pickerIcons, children: showClear && value?.to && !disabled ? (jsxRuntime.jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClearTo, tabIndex: -1, "aria-label": "Clear to date" })) : (jsxRuntime.jsx(CwIcon, { iconId: "calendar" })) })] }), renderPopup(jsxRuntime.jsxs("div", { ref: popupRef, className: `${styles$4.pickerPopup} ${rangeStyles.rangePopup}`, style: popupStyle, children: [jsxRuntime.jsxs("div", { className: rangeStyles.rangeCalendarRow, children: [showPresets && presetsToRender.length > 0 && (jsxRuntime.jsx("div", { className: rangeStyles.presetList, children: presetsToRender.map((preset) => (jsxRuntime.jsx("button", { type: "button", onClick: (e) => handlePresetClick(preset, e), children: preset.label }, preset.key))) })), jsxRuntime.jsx(reactDayPicker.DayPicker, { mode: "range", selected: selectedRange, onSelect: handleRangeSelect, disabled: disabledDays, numberOfMonths: numberOfMonths, defaultMonth: defaultMonth || value?.from || undefined, modifiers: {
|
|
7177
|
+
return (jsxRuntime.jsx("div", { ref: containerRef, className: `cw-rangepicker ${className || ""}`, children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsxs("div", { ref: wrapperRef, className: rangeStyles.rangeWrapper, children: [jsxRuntime.jsxs("div", { className: styles$4.pickerWrapper, children: [jsxRuntime.jsx("input", { ref: inputFromRef, type: "text", value: inputFromValue, placeholder: placeholderFrom, onChange: handleInputFromChange, onBlur: () => handleInputBlur('from'), onClick: handleInputFromClick, onKeyDown: (e) => handleInputKeyDown(e, 'from'), disabled: disabled, required: required, size: displayFormat.length, "data-focused": focusedInput === 'from' }), jsxRuntime.jsx("div", { className: styles$4.pickerIcons, children: showClear && value?.from && !disabled ? (jsxRuntime.jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClearFrom, tabIndex: -1, "aria-label": "Clear from date" })) : (jsxRuntime.jsx(CwIcon, { iconId: "calendar" })) })] }), jsxRuntime.jsx(CwIcon, { iconId: "arrow-right", size: "medium" }), jsxRuntime.jsxs("div", { className: styles$4.pickerWrapper, children: [jsxRuntime.jsx("input", { ref: inputToRef, type: "text", value: inputToValue, placeholder: placeholderTo, onChange: handleInputToChange, onBlur: () => handleInputBlur('to'), onClick: handleInputToClick, onKeyDown: (e) => handleInputKeyDown(e, 'to'), disabled: disabled, required: required, size: displayFormat.length, "data-focused": focusedInput === 'to' }), jsxRuntime.jsx("div", { className: styles$4.pickerIcons, children: showClear && value?.to && !disabled ? (jsxRuntime.jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClearTo, tabIndex: -1, "aria-label": "Clear to date" })) : (jsxRuntime.jsx(CwIcon, { iconId: "calendar" })) })] }), renderPopup(jsxRuntime.jsxs("div", { ref: popupRef, className: `${styles$4.pickerPopup} ${rangeStyles.rangePopup}`, style: popupStyle, children: [jsxRuntime.jsxs("div", { className: rangeStyles.rangeCalendarRow, children: [showPresets && presetsToRender.length > 0 && (jsxRuntime.jsx("div", { className: rangeStyles.presetList, children: presetsToRender.map((preset) => (jsxRuntime.jsx("button", { type: "button", onClick: (e) => handlePresetClick(preset, e), children: preset.label }, preset.key))) })), jsxRuntime.jsx(reactDayPicker.DayPicker, { mode: "range", selected: selectedRange, onSelect: handleRangeSelect, disabled: disabledDays, numberOfMonths: numberOfMonths, defaultMonth: defaultMonth || value?.from || undefined, modifiers: {
|
|
6993
7178
|
today: new Date(),
|
|
6994
7179
|
}, modifiersClassNames: {
|
|
6995
7180
|
today: "rdp-day-today",
|
|
6996
7181
|
} })] }), jsxRuntime.jsx("div", { role: "alert", "aria-live": "polite", className: rangeStyles.rangeError, children: rangeErrorMessage })] }))] })] }) }));
|
|
6997
7182
|
}
|
|
6998
7183
|
|
|
6999
|
-
var timeStyles = {"timePickerPopup":"cw-time-picker-module__timePickerPopup__BN63t","timePickerList":"cw-time-picker-module__timePickerList__E88pr","selected":"cw-time-picker-module__selected__qVnfL","
|
|
7184
|
+
var timeStyles = {"timePickerPopup":"cw-time-picker-module__timePickerPopup__BN63t","timePickerList":"cw-time-picker-module__timePickerList__E88pr","selected":"cw-time-picker-module__selected__qVnfL","field":"cw-time-picker-module__field__kPvGN","narrow":"cw-time-picker-module__narrow__Z7lCI"};
|
|
7000
7185
|
|
|
7001
7186
|
const isMobileDevice = () => {
|
|
7002
7187
|
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
|
|
@@ -7158,7 +7343,7 @@ function CwTimePicker({ value, onChange, interval = 15, minTime, maxTime, labelP
|
|
|
7158
7343
|
return (jsxRuntime.jsx("div", { className: `cw-timepicker cw-timepicker-native ${className || ""}`, children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsx("div", { className: styles$4.pickerWrapper, children: jsxRuntime.jsx("input", { type: "time", value: displayValue, onChange: handleNativeChange, min: minTime, max: maxTime, step: interval * 60, disabled: disabled, required: required, placeholder: placeholder, className: "cw-timepicker-native" }) })] }) }));
|
|
7159
7344
|
}
|
|
7160
7345
|
// Custom time picker
|
|
7161
|
-
return (jsxRuntime.jsx("div", { ref: containerRef, className: `cw-timepicker ${className || ""}`, children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsxs("div", { ref: wrapperRef, className: styles$4.pickerWrapper
|
|
7346
|
+
return (jsxRuntime.jsx("div", { ref: containerRef, className: `cw-timepicker ${className || ""}`, children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsxs("div", { ref: wrapperRef, className: `${styles$4.pickerWrapper} ${timeStyles.field}${showClear ? "" : ` ${timeStyles.narrow}`}`, children: [jsxRuntime.jsx("input", { ref: inputRef, type: "text", value: inputValue, placeholder: placeholder, onChange: handleInputChange, onBlur: handleInputBlur, onClick: handleInputClick, onKeyDown: handleInputKeyDown, disabled: disabled, required: required, maxLength: 5 }), showClear && (jsxRuntime.jsx("div", { className: styles$4.pickerIcons, children: value && !disabled ? (jsxRuntime.jsx(CwButton, { type: "button", variant: "icon", icon: "close", color: "neutral", onClick: handleClear, tabIndex: -1, "aria-label": "Clear time" })) : (jsxRuntime.jsx(CwIcon, { iconId: "clock" })) })), renderPopup(jsxRuntime.jsx("div", { ref: popupRef, className: `${styles$4.pickerPopup} ${timeStyles.timePickerPopup}`, style: popupStyle, children: jsxRuntime.jsx("div", { className: timeStyles.timePickerList, children: timeOptions.map((time) => {
|
|
7162
7347
|
const isSelected = time === value;
|
|
7163
7348
|
return (jsxRuntime.jsx("button", { ref: isSelected ? selectedItemRef : null, type: "button", className: isSelected ? timeStyles.selected : "", onClick: () => handleTimeSelect(time), children: time }, time));
|
|
7164
7349
|
}) }) }))] })] }) }));
|
|
@@ -7824,6 +8009,9 @@ function CwDatePickerTemporal({ value, onChange, minDate, maxDate, disabledDates
|
|
|
7824
8009
|
const feedbackMessages = feedback
|
|
7825
8010
|
? Array.isArray(feedback) ? feedback : [feedback]
|
|
7826
8011
|
: [];
|
|
8012
|
+
const feedbackId = React.useId();
|
|
8013
|
+
const feedbackIds = feedbackMessages.map((_, index) => `${feedbackId}-${index}`);
|
|
8014
|
+
const describedBy = feedbackIds.join(" ") || undefined;
|
|
7827
8015
|
const wrapperRef = React.useRef(null);
|
|
7828
8016
|
const inputRef = React.useRef(null);
|
|
7829
8017
|
const prevValueRef = React.useRef(undefined);
|
|
@@ -7930,11 +8118,11 @@ function CwDatePickerTemporal({ value, onChange, minDate, maxDate, disabledDates
|
|
|
7930
8118
|
const defaultMonthJsDate = defaultMonth
|
|
7931
8119
|
? new Date(defaultMonth.year, defaultMonth.month - 1, 1)
|
|
7932
8120
|
: selectedJsDate;
|
|
7933
|
-
return (jsxRuntime.
|
|
7934
|
-
|
|
7935
|
-
|
|
7936
|
-
|
|
7937
|
-
|
|
8121
|
+
return (jsxRuntime.jsx("div", { ref: containerRef, className: `cw-datepicker ${className || ""}`, children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsxs("div", { className: styles$4.value, children: [jsxRuntime.jsxs("div", { ref: wrapperRef, className: styles$4.pickerWrapper, children: [jsxRuntime.jsx("input", { ref: inputRef, type: "text", value: inputValue, placeholder: placeholder, onChange: handleInputChange, onBlur: handleInputBlur, onClick: handleInputClick, onKeyDown: handleInputKeyDown, disabled: disabled, "aria-describedby": describedBy, required: required, size: displayFormat.length }), jsxRuntime.jsx("div", { className: styles$4.pickerIcons, children: showClear && value && !disabled ? (jsxRuntime.jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClear, tabIndex: -1, "aria-label": "Clear date" })) : (jsxRuntime.jsx(CwIcon, { iconId: "calendar" })) }), renderPopup(jsxRuntime.jsxs("div", { ref: popupRef, className: styles$4.pickerPopup, style: popupStyle, children: [jsxRuntime.jsx(reactDayPicker.DayPicker, { mode: "single", selected: selectedJsDate, defaultMonth: defaultMonthJsDate, onSelect: handleDaySelect, disabled: disabledDays, numberOfMonths: numberOfMonths, locale: locale$1, captionLayout: "dropdown", startMonth: dropdownStartMonth, endMonth: dropdownEndMonth, modifiers: {
|
|
8122
|
+
today: new Date(),
|
|
8123
|
+
}, modifiersClassNames: {
|
|
8124
|
+
today: "rdp-day-today",
|
|
8125
|
+
} }), showTodayButton && (jsxRuntime.jsx("footer", { className: "cw-flex-row cw-align-right-center", children: jsxRuntime.jsx(CwButton, { type: "button", variant: "outline", onClick: handleTodayClick, text: todayLabel }) }))] }))] }), feedbackMessages.map((feedbackItem, index) => (jsxRuntime.jsx("p", { id: feedbackIds[index], className: "cw-input-feedback", "data-color": feedbackItem.type, "aria-live": "polite", children: feedbackItem.message }, index)))] })] }) }));
|
|
7938
8126
|
}
|
|
7939
8127
|
|
|
7940
8128
|
// DateTimePickerState - immutable domain model for the Temporal date-time picker.
|
|
@@ -8672,7 +8860,7 @@ function CwDateRangePickerTemporal({ value, onChange, minDate, maxDate, disabled
|
|
|
8672
8860
|
const defaultMonthJsDate = defaultMonth
|
|
8673
8861
|
? new Date(defaultMonth.year, defaultMonth.month - 1, 1)
|
|
8674
8862
|
: (value?.from ? plainDateToJsDate(value.from) : undefined);
|
|
8675
|
-
return (jsxRuntime.jsx("div", { ref: containerRef, className: `cw-rangepicker ${className || ""}`, children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsxs("div", { ref: wrapperRef, className: rangeStyles.rangeWrapper, children: [jsxRuntime.jsxs("div", { className: styles$4.pickerWrapper, children: [jsxRuntime.jsx("input", { ref: inputFromRef, type: "text", value: inputFromValue, placeholder: placeholderFrom, onChange: handleInputFromChange, onBlur: () => handleInputBlur('from'), onClick: handleInputFromClick, onKeyDown: (e) => handleInputKeyDown(e, 'from'), disabled: disabled, required: required, "data-focused": focusedInput === 'from' }), jsxRuntime.jsx("div", { className: styles$4.pickerIcons, children: showClear && value?.from && !disabled ? (jsxRuntime.jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClearFrom, tabIndex: -1, "aria-label": "Clear from date" })) : (jsxRuntime.jsx(CwIcon, { iconId: "calendar" })) })] }), jsxRuntime.jsx(CwIcon, { iconId: "arrow-right", size: "medium" }), jsxRuntime.jsxs("div", { className: styles$4.pickerWrapper, children: [jsxRuntime.jsx("input", { ref: inputToRef, type: "text", value: inputToValue, placeholder: placeholderTo, onChange: handleInputToChange, onBlur: () => handleInputBlur('to'), onClick: handleInputToClick, onKeyDown: (e) => handleInputKeyDown(e, 'to'), disabled: disabled, required: required, "data-focused": focusedInput === 'to' }), jsxRuntime.jsx("div", { className: styles$4.pickerIcons, children: showClear && value?.to && !disabled ? (jsxRuntime.jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClearTo, tabIndex: -1, "aria-label": "Clear to date" })) : (jsxRuntime.jsx(CwIcon, { iconId: "calendar" })) })] }), renderPopup(jsxRuntime.jsxs("div", { ref: popupRef, className: `${styles$4.pickerPopup} ${rangeStyles.rangePopup}`, style: popupStyle, children: [jsxRuntime.jsxs("div", { className: rangeStyles.rangeCalendarRow, children: [showPresets && presetsToRender.length > 0 && (jsxRuntime.jsx("div", { className: rangeStyles.presetList, children: presetsToRender.map((preset) => (jsxRuntime.jsx("button", { type: "button", onClick: (e) => handlePresetClick(preset, e), children: preset.label }, preset.key))) })), jsxRuntime.jsx(reactDayPicker.DayPicker, { mode: "range", selected: selectedRange, onSelect: handleRangeSelect, disabled: disabledDays, numberOfMonths: numberOfMonths, defaultMonth: defaultMonthJsDate, locale: locale$1, captionLayout: "dropdown", startMonth: dropdownStartMonth, endMonth: dropdownEndMonth, modifiers: {
|
|
8863
|
+
return (jsxRuntime.jsx("div", { ref: containerRef, className: `cw-rangepicker ${className || ""}`, children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsxs("div", { ref: wrapperRef, className: rangeStyles.rangeWrapper, children: [jsxRuntime.jsxs("div", { className: styles$4.pickerWrapper, children: [jsxRuntime.jsx("input", { ref: inputFromRef, type: "text", value: inputFromValue, placeholder: placeholderFrom, onChange: handleInputFromChange, onBlur: () => handleInputBlur('from'), onClick: handleInputFromClick, onKeyDown: (e) => handleInputKeyDown(e, 'from'), disabled: disabled, required: required, size: displayFormat.length, "data-focused": focusedInput === 'from' }), jsxRuntime.jsx("div", { className: styles$4.pickerIcons, children: showClear && value?.from && !disabled ? (jsxRuntime.jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClearFrom, tabIndex: -1, "aria-label": "Clear from date" })) : (jsxRuntime.jsx(CwIcon, { iconId: "calendar" })) })] }), jsxRuntime.jsx(CwIcon, { iconId: "arrow-right", size: "medium" }), jsxRuntime.jsxs("div", { className: styles$4.pickerWrapper, children: [jsxRuntime.jsx("input", { ref: inputToRef, type: "text", value: inputToValue, placeholder: placeholderTo, onChange: handleInputToChange, onBlur: () => handleInputBlur('to'), onClick: handleInputToClick, onKeyDown: (e) => handleInputKeyDown(e, 'to'), disabled: disabled, required: required, size: displayFormat.length, "data-focused": focusedInput === 'to' }), jsxRuntime.jsx("div", { className: styles$4.pickerIcons, children: showClear && value?.to && !disabled ? (jsxRuntime.jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClearTo, tabIndex: -1, "aria-label": "Clear to date" })) : (jsxRuntime.jsx(CwIcon, { iconId: "calendar" })) })] }), renderPopup(jsxRuntime.jsxs("div", { ref: popupRef, className: `${styles$4.pickerPopup} ${rangeStyles.rangePopup}`, style: popupStyle, children: [jsxRuntime.jsxs("div", { className: rangeStyles.rangeCalendarRow, children: [showPresets && presetsToRender.length > 0 && (jsxRuntime.jsx("div", { className: rangeStyles.presetList, children: presetsToRender.map((preset) => (jsxRuntime.jsx("button", { type: "button", onClick: (e) => handlePresetClick(preset, e), children: preset.label }, preset.key))) })), jsxRuntime.jsx(reactDayPicker.DayPicker, { mode: "range", selected: selectedRange, onSelect: handleRangeSelect, disabled: disabledDays, numberOfMonths: numberOfMonths, defaultMonth: defaultMonthJsDate, locale: locale$1, captionLayout: "dropdown", startMonth: dropdownStartMonth, endMonth: dropdownEndMonth, modifiers: {
|
|
8676
8864
|
today: new Date(),
|
|
8677
8865
|
}, modifiersClassNames: {
|
|
8678
8866
|
today: "rdp-day-today",
|
|
@@ -10238,6 +10426,7 @@ const CwFindCrewmember = ({ handleChange, placeHolder = "Search crew…", requir
|
|
|
10238
10426
|
exports.CwAccordionContainer = CwAccordionContainer;
|
|
10239
10427
|
exports.CwAlign = CwAlign;
|
|
10240
10428
|
exports.CwAnchoredMenu = CwAnchoredMenu;
|
|
10429
|
+
exports.CwBadge = CwBadge;
|
|
10241
10430
|
exports.CwBtnApprove = CwBtnApprove;
|
|
10242
10431
|
exports.CwBtnCancel = CwBtnCancel;
|
|
10243
10432
|
exports.CwBtnDelete = CwBtnDelete;
|