@cwellt_software/cwellt-reactjs-lib 1.4.15 → 1.5.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/content/icons/new-cw-icons/NewCwIcons.json +1 -1
- package/dist/content/icons/new-cw-icons/css/new-cw-icons.css +260 -824
- package/dist/content/icons/new-cw-icons/fonts/NewCwIcons.woff +0 -0
- package/dist/index.cjs.js +355 -203
- package/dist/index.css +2 -2
- package/dist/index.d.ts +133 -48
- package/dist/index.es.js +351 -202
- package/dist/src/components/control/action/search/CwSearch.d.ts +2 -0
- package/dist/src/components/control/action/search/CwSearch.d.ts.map +1 -1
- package/dist/src/components/control/action/search/searchKeyboardNavigation.d.ts +35 -0
- package/dist/src/components/control/action/search/searchKeyboardNavigation.d.ts.map +1 -0
- package/dist/src/components/control/choice/nav-menu/CwNavMenu.d.ts +78 -0
- package/dist/src/components/control/choice/nav-menu/CwNavMenu.d.ts.map +1 -0
- package/dist/src/components/control/choice/nav-menu/filterNavItems.d.ts +9 -0
- package/dist/src/components/control/choice/nav-menu/filterNavItems.d.ts.map +1 -0
- package/dist/src/components/control/choice/nav-menu/sortNavItems.d.ts +9 -0
- package/dist/src/components/control/choice/nav-menu/sortNavItems.d.ts.map +1 -0
- package/dist/src/components/control/input/file/CwFileUploadMultiple.d.ts +12 -0
- package/dist/src/components/control/input/file/CwFileUploadMultiple.d.ts.map +1 -1
- package/dist/src/components/control/input/image/CwInputImage.d.ts +17 -2
- package/dist/src/components/control/input/image/CwInputImage.d.ts.map +1 -1
- package/dist/src/components/display/graphics/icon/CwIcon.d.ts +1 -1
- package/dist/src/components/display/graphics/icon/CwIcon.d.ts.map +1 -1
- package/dist/src/components/display/graphics/loading/CwLoading.d.ts +3 -14
- package/dist/src/components/display/graphics/loading/CwLoading.d.ts.map +1 -1
- package/dist/src/components/display/graphics/loading/loadingConfig.d.ts +16 -0
- package/dist/src/components/display/graphics/loading/loadingConfig.d.ts.map +1 -0
- package/dist/src/index.d.ts +4 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/playground/PlaygroundApp.d.ts.map +1 -1
- package/dist/src/playground/pages/CwFileUploadMultiplePage.d.ts +3 -0
- package/dist/src/playground/pages/CwFileUploadMultiplePage.d.ts.map +1 -0
- package/dist/src/playground/pages/CwInputImagePage.d.ts.map +1 -1
- package/dist/src/playground/pages/CwNavMenuPage.d.ts +3 -0
- package/dist/src/playground/pages/CwNavMenuPage.d.ts.map +1 -0
- package/dist/src/playground/pages/IconLibraryPage.d.ts +3 -0
- package/dist/src/playground/pages/IconLibraryPage.d.ts.map +1 -0
- package/dist/src/playground/pages/LoadingPage.d.ts +3 -0
- package/dist/src/playground/pages/LoadingPage.d.ts.map +1 -0
- package/dist/src/playground/pages/SelectorsPage.d.ts.map +1 -1
- package/dist/test/components/control/action/search/searchKeyboardNavigation.test.d.ts +2 -0
- package/dist/test/components/control/action/search/searchKeyboardNavigation.test.d.ts.map +1 -0
- package/dist/test/components/control/choice/nav-menu/filterNavItems.test.d.ts +2 -0
- package/dist/test/components/control/choice/nav-menu/filterNavItems.test.d.ts.map +1 -0
- package/dist/test/components/control/choice/nav-menu/sortNavItems.test.d.ts +2 -0
- package/dist/test/components/control/choice/nav-menu/sortNavItems.test.d.ts.map +1 -0
- package/dist/test/components/control/input/file/fileMatchesAccept.test.d.ts +2 -0
- package/dist/test/components/control/input/file/fileMatchesAccept.test.d.ts.map +1 -0
- package/dist/test/components/control/input/image/readImageFileAsDataUrl.test.d.ts +2 -0
- package/dist/test/components/control/input/image/readImageFileAsDataUrl.test.d.ts.map +1 -0
- package/dist/test/components/display/graphics/loading/CwLoading.test.d.ts +2 -0
- package/dist/test/components/display/graphics/loading/CwLoading.test.d.ts.map +1 -0
- package/package.json +1 -2
package/dist/index.es.js
CHANGED
|
@@ -161,12 +161,7 @@ function getContrastColor(color) {
|
|
|
161
161
|
return `hsl(${hsl.h}, ${contrastS}%, ${targetL}%)`;
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
-
|
|
165
|
-
'sortable-asc': (jsxs("svg", { width: "16", height: "16", viewBox: "0 0 128 128", fill: "currentColor", children: [jsx("path", { d: "M93.1675 73.1739C94.5691 74.5758 94.7323 76.7924 93.5515 78.3846L93.1675 78.8326L63.6741 108.326L34.1755 78.8326C32.6908 77.3518 32.6014 74.9761 33.9708 73.3881C35.3401 71.8001 37.7033 71.5391 39.3861 72.7899L39.8341 73.1739L63.6741 97.0137L87.5088 73.1739C88.9104 71.7726 91.1274 71.6092 92.7194 72.7899L93.1674 73.1739H93.1675Z", opacity: "0.3" }), jsx("path", { d: "M34.1714 55.1518C32.7697 53.7499 32.6066 51.5333 33.7874 49.9411L34.1714 49.4931L63.6647 20L93.1634 49.4931C94.6481 50.9739 94.7375 53.3496 93.3681 54.9376C91.9987 56.5256 89.6356 56.7866 87.9527 55.5358L87.5047 55.1517L63.6647 31.312L39.8301 55.1518C38.4285 56.5531 36.2115 56.7165 34.6195 55.5358L34.1715 55.1518L34.1714 55.1518Z", opacity: "1" })] })),
|
|
166
|
-
'sortable-desc': (jsxs("svg", { width: "16", height: "16", viewBox: "0 0 128 128", fill: "currentColor", children: [jsx("path", { d: "M93.1675 73.1739C94.5691 74.5758 94.7323 76.7924 93.5515 78.3846L93.1675 78.8326L63.6741 108.326L34.1755 78.8326C32.6908 77.3518 32.6014 74.9761 33.9708 73.3881C35.3401 71.8001 37.7033 71.5391 39.3861 72.7899L39.8341 73.1739L63.6741 97.0137L87.5088 73.1739C88.9104 71.7726 91.1274 71.6092 92.7194 72.7899L93.1674 73.1739H93.1675Z", opacity: "1" }), jsx("path", { d: "M34.1714 55.1518C32.7697 53.7499 32.6066 51.5333 33.7874 49.9411L34.1714 49.4931L63.6647 20L93.1634 49.4931C94.6481 50.9739 94.7375 53.3496 93.3681 54.9376C91.9987 56.5256 89.6356 56.7866 87.9527 55.5358L87.5047 55.1517L63.6647 31.312L39.8301 55.1518C38.4285 56.5531 36.2115 56.7165 34.6195 55.5358L34.1715 55.1518L34.1714 55.1518Z", opacity: "0.3" })] })),
|
|
167
|
-
};
|
|
168
|
-
|
|
169
|
-
var styles$u = {"cw-tooltip-content":"cw-tooltip-module__cw-tooltip-content__RZczd","cw-tooltip":"cw-tooltip-module__cw-tooltip__1KYig"};
|
|
164
|
+
var styles$v = {"cw-tooltip-content":"cw-tooltip-module__cw-tooltip-content__RZczd","cw-tooltip":"cw-tooltip-module__cw-tooltip__1KYig"};
|
|
170
165
|
|
|
171
166
|
// Constants
|
|
172
167
|
const margin$1 = 16;
|
|
@@ -456,7 +451,7 @@ const CwTooltipManager = () => {
|
|
|
456
451
|
if (!state.isVisible || !state.content) {
|
|
457
452
|
return null;
|
|
458
453
|
}
|
|
459
|
-
return createPortal(jsx("div", { ref: tooltipRef, className: styles$
|
|
454
|
+
return createPortal(jsx("div", { ref: tooltipRef, className: styles$v["cw-tooltip-content"], "data-position": actualPosition, "data-visible": state.isVisible, "data-inline": state.displayInline, style: {
|
|
460
455
|
top: `${tooltipPosition.top}px`,
|
|
461
456
|
left: `${tooltipPosition.left}px`,
|
|
462
457
|
opacity: (isPositioned && !isMeasuring) ? 1 : 0,
|
|
@@ -537,16 +532,22 @@ const CwTooltipNew = ({ children, content = null, position = "right", dissapears
|
|
|
537
532
|
useEffect(() => {
|
|
538
533
|
ensureTooltipManager();
|
|
539
534
|
}, []);
|
|
540
|
-
return (jsx("div", { ref: containerRef, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, style: overlayStyle, "data-inline": displayInline, className: styles$
|
|
535
|
+
return (jsx("div", { ref: containerRef, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, style: overlayStyle, "data-inline": displayInline, className: styles$v["cw-tooltip"], children: children }));
|
|
536
|
+
};
|
|
537
|
+
|
|
538
|
+
const SVG_ICONS = {
|
|
539
|
+
'sortable-asc': (jsxs("svg", { width: "16", height: "16", viewBox: "0 0 128 128", fill: "currentColor", children: [jsx("path", { d: "M93.1675 73.1739C94.5691 74.5758 94.7323 76.7924 93.5515 78.3846L93.1675 78.8326L63.6741 108.326L34.1755 78.8326C32.6908 77.3518 32.6014 74.9761 33.9708 73.3881C35.3401 71.8001 37.7033 71.5391 39.3861 72.7899L39.8341 73.1739L63.6741 97.0137L87.5088 73.1739C88.9104 71.7726 91.1274 71.6092 92.7194 72.7899L93.1674 73.1739H93.1675Z", opacity: "0.3" }), jsx("path", { d: "M34.1714 55.1518C32.7697 53.7499 32.6066 51.5333 33.7874 49.9411L34.1714 49.4931L63.6647 20L93.1634 49.4931C94.6481 50.9739 94.7375 53.3496 93.3681 54.9376C91.9987 56.5256 89.6356 56.7866 87.9527 55.5358L87.5047 55.1517L63.6647 31.312L39.8301 55.1518C38.4285 56.5531 36.2115 56.7165 34.6195 55.5358L34.1715 55.1518L34.1714 55.1518Z", opacity: "1" })] })),
|
|
540
|
+
'sortable-desc': (jsxs("svg", { width: "16", height: "16", viewBox: "0 0 128 128", fill: "currentColor", children: [jsx("path", { d: "M93.1675 73.1739C94.5691 74.5758 94.7323 76.7924 93.5515 78.3846L93.1675 78.8326L63.6741 108.326L34.1755 78.8326C32.6908 77.3518 32.6014 74.9761 33.9708 73.3881C35.3401 71.8001 37.7033 71.5391 39.3861 72.7899L39.8341 73.1739L63.6741 97.0137L87.5088 73.1739C88.9104 71.7726 91.1274 71.6092 92.7194 72.7899L93.1674 73.1739H93.1675Z", opacity: "1" }), jsx("path", { d: "M34.1714 55.1518C32.7697 53.7499 32.6066 51.5333 33.7874 49.9411L34.1714 49.4931L63.6647 20L93.1634 49.4931C94.6481 50.9739 94.7375 53.3496 93.3681 54.9376C91.9987 56.5256 89.6356 56.7866 87.9527 55.5358L87.5047 55.1517L63.6647 31.312L39.8301 55.1518C38.4285 56.5531 36.2115 56.7165 34.6195 55.5358L34.1715 55.1518L34.1714 55.1518Z", opacity: "0.3" })] })),
|
|
541
541
|
};
|
|
542
542
|
|
|
543
543
|
function CwIcon(props) {
|
|
544
|
-
const { iconId, color, size, title, tooltipPosition = 'bottom', ...iconProps } = props;
|
|
544
|
+
const { iconId, color, size, className, title, tooltipPosition = 'bottom', ...iconProps } = props;
|
|
545
545
|
const getClassName = (baseClass) => {
|
|
546
546
|
return [
|
|
547
547
|
baseClass,
|
|
548
548
|
color && `cw-color-${color}`,
|
|
549
|
-
size && `cw-font-size-${size}
|
|
549
|
+
size && `cw-font-size-${size}`,
|
|
550
|
+
className
|
|
550
551
|
].filter(Boolean).join(' ');
|
|
551
552
|
};
|
|
552
553
|
let iconElement;
|
|
@@ -958,49 +959,39 @@ function CwImageZoom(image) {
|
|
|
958
959
|
} }), jsx("div", { style: { color: "#fff", fontSize: "1rem", textAlign: "center" }, children: selectedImage.filename && jsx("div", { children: selectedImage.filename }) })] }))] }));
|
|
959
960
|
}
|
|
960
961
|
|
|
962
|
+
let defaults = {};
|
|
961
963
|
/**
|
|
962
|
-
* CwLoading
|
|
963
|
-
*
|
|
964
|
-
* A versatile loading component that shows a spinner with optional text
|
|
965
|
-
* and disables the wrapped content while in loading state.
|
|
966
|
-
*
|
|
967
|
-
* @example
|
|
968
|
-
* // Basic usage
|
|
969
|
-
* <CwLoading isLoading={isSubmitting}>
|
|
970
|
-
* <form>...</form>
|
|
971
|
-
* </CwLoading>
|
|
972
|
-
*
|
|
973
|
-
* // With custom text and size
|
|
974
|
-
* <CwLoading
|
|
975
|
-
* isLoading={isLoading}
|
|
976
|
-
* text="Please wait..."
|
|
977
|
-
* size="large"
|
|
978
|
-
* >
|
|
979
|
-
* <UserProfile />
|
|
980
|
-
* </CwLoading>
|
|
964
|
+
* Register global CwLoading defaults. Call once at app init, before the first render.
|
|
965
|
+
* Merges into any previously configured defaults.
|
|
981
966
|
*/
|
|
982
|
-
function
|
|
983
|
-
|
|
984
|
-
|
|
967
|
+
function configureCwLoading(next) {
|
|
968
|
+
defaults = { ...defaults, ...next };
|
|
969
|
+
}
|
|
970
|
+
/** Read the currently configured CwLoading defaults. */
|
|
971
|
+
function getCwLoadingDefaults() {
|
|
972
|
+
return defaults;
|
|
985
973
|
}
|
|
986
974
|
|
|
987
975
|
/**
|
|
988
|
-
*
|
|
976
|
+
* CwLoading — a spinner with optional text that dims the wrapped content while loading.
|
|
989
977
|
*
|
|
990
|
-
*
|
|
978
|
+
* Icon resolves as `iconName` prop → `getCwLoadingDefaults().icon` → none (neutral ring).
|
|
991
979
|
*
|
|
992
980
|
* @example
|
|
993
|
-
*
|
|
994
|
-
*
|
|
995
|
-
*
|
|
996
|
-
* // Use:
|
|
997
|
-
* <CwLoading size="small" />
|
|
981
|
+
* <CwLoading isLoading={isSubmitting}>
|
|
982
|
+
* <form>...</form>
|
|
983
|
+
* </CwLoading>
|
|
998
984
|
*/
|
|
999
|
-
function
|
|
1000
|
-
|
|
985
|
+
function CwLoading({ isLoading = false, text = '', size = 'regular', iconPosition = 'outside', iconName, animation = 'spin', children }) {
|
|
986
|
+
let overlay = null;
|
|
987
|
+
if (isLoading) {
|
|
988
|
+
const resolvedIcon = iconName ?? getCwLoadingDefaults().icon;
|
|
989
|
+
overlay = (jsxs("div", { className: "cw-loading-content", "data-size": size, "data-animation": animation, role: "status", "aria-label": text || 'Loading', children: [jsx("div", { className: "cw-loading", "data-icon-position": iconPosition, "data-has-icon": !!resolvedIcon, children: resolvedIcon && jsx("span", { className: `cwi-icons ${resolvedIcon}` }) }), text && (jsx("p", { children: text }))] }));
|
|
990
|
+
}
|
|
991
|
+
return (jsxs("div", { "aria-busy": isLoading, className: "cw-loading-container", "data-children": !!children, children: [overlay, jsx("div", { className: "cw-loading-disabled-content", children: children })] }));
|
|
1001
992
|
}
|
|
1002
993
|
|
|
1003
|
-
var styles$
|
|
994
|
+
var styles$u = {"cw-generic-tooltip-content":"cw-generic-tooltip-module__cw-generic-tooltip-content__la-Si","cw-generic-tooltip":"cw-generic-tooltip-module__cw-generic-tooltip__Ij76M"};
|
|
1004
995
|
|
|
1005
996
|
// Constants moved outside to prevent recreation
|
|
1006
997
|
const margin = 16;
|
|
@@ -1123,12 +1114,12 @@ const CwGenericTooltip = ({ children, content = null, position = defaultPosition
|
|
|
1123
1114
|
const { setTooltipTimeout, clearTooltipTimeout } = useTooltipDelay(() => {
|
|
1124
1115
|
setIsVisible(true);
|
|
1125
1116
|
}, showDelay);
|
|
1126
|
-
const { position: tooltipPosition, actualPosition } = useTooltipPosition(isVisible, containerRef, position, styles$
|
|
1117
|
+
const { position: tooltipPosition, actualPosition } = useTooltipPosition(isVisible, containerRef, position, styles$u["cw-generic-tooltip-content"]);
|
|
1127
1118
|
// Memoize tooltip content creation
|
|
1128
1119
|
const tooltipContent = useMemo(() => {
|
|
1129
1120
|
if (hide || !isVisible || !content)
|
|
1130
1121
|
return null;
|
|
1131
|
-
return createPortal(jsx("div", { className: styles$
|
|
1122
|
+
return createPortal(jsx("div", { className: styles$u["cw-generic-tooltip-content"], "data-position": actualPosition, "data-visible": isVisible, "data-inline": displayInline, style: {
|
|
1132
1123
|
position: 'fixed',
|
|
1133
1124
|
top: `${tooltipPosition.top}px`,
|
|
1134
1125
|
left: `${tooltipPosition.left}px`,
|
|
@@ -1143,7 +1134,7 @@ const CwGenericTooltip = ({ children, content = null, position = defaultPosition
|
|
|
1143
1134
|
clearTooltipTimeout();
|
|
1144
1135
|
setIsVisible(false);
|
|
1145
1136
|
}, [clearTooltipTimeout]);
|
|
1146
|
-
return (jsxs("div", { ref: containerRef, className: styles$
|
|
1137
|
+
return (jsxs("div", { ref: containerRef, className: styles$u["cw-generic-tooltip"], onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, style: overlayStyle, "data-inline": displayInline, children: [tooltipContent, children] }));
|
|
1147
1138
|
};
|
|
1148
1139
|
|
|
1149
1140
|
const CwButton = React__default.forwardRef(function CwButton({ text, variant = 'solid', color = 'primary', size = 'medium', iconPosition = 'left', pressed, className = '', icon = "", title, tooltipPosition = "bottom", children, ...buttonProps }, ref) {
|
|
@@ -1205,7 +1196,7 @@ function CwModal(custModalProps) {
|
|
|
1205
1196
|
return (jsx("div", { children: custModalProps.modalState && (jsxs("div", { className: custModalProps.classNameModalOverlay + " cwelltModalOverlay", children: [jsx("div", { className: "cwelltModalOverlayBg", onClick: custModalProps.onCloseModal }), jsx(Draggable, { disabled: isModalDisabled, axis: "both", nodeRef: draggableRef, children: jsxs("div", { className: custModalProps.classNameModal + " cwelltContainerModal", ref: draggableRef, style: widthModalDef !== "40em" ? modalStyle.widthCustomStyle : modalStyle.widthDefStyle, children: [jsxs("div", { className: "cwelltModalHeader", onMouseOver: cwelltOnMouseOverModal, onMouseOut: cwelltOnMouseOutModal, children: [jsx("div", { className: "cwelltModalTitle", children: custModalProps.titleModal }), jsx("button", { className: "cwelltBtnCloseModal", onClick: custModalProps.onCloseModal, children: jsx("span", { className: "cwelltCloseIcon" }) })] }), jsx("div", { className: "cwelltModalBody", children: jsx("div", { className: "cwelltContainerModalBody", style: { position: "relative" }, children: custModalProps.children }) }), isHide === false ? (jsx("footer", { className: "legacy-modal-footer", onMouseOver: cwelltOnMouseOverModal, onMouseOut: cwelltOnMouseOutModal, children: jsx(CwButton, { variant: "icon", icon: "save", title: "Save", onClick: custModalProps.onSaveModal, form: custModalProps.formSaveModal, hidden: custModalProps.HideBtnModal, type: custModalProps.HtmlSubmitModal }) })) : (jsx("div", { style: { display: "none" } }))] }) })] })) }));
|
|
1206
1197
|
}
|
|
1207
1198
|
|
|
1208
|
-
var styles$
|
|
1199
|
+
var styles$t = {"overlayPositioned":"CwConfirmationPopup-module__overlayPositioned__11qYB","popup":"CwConfirmationPopup-module__popup__ahPjM","message":"CwConfirmationPopup-module__message__MnNL4","buttons":"CwConfirmationPopup-module__buttons__fGYYE","button":"CwConfirmationPopup-module__button__ugYQE","confirmButton":"CwConfirmationPopup-module__confirmButton__rTP4S","cancelButton":"CwConfirmationPopup-module__cancelButton__Ry694"};
|
|
1209
1200
|
|
|
1210
1201
|
function CwConfirmationPopup(props) {
|
|
1211
1202
|
const { isOpen, onConfirm, onCancel, message = "Are you sure you want to proceed?", confirmText = "Confirm", cancelText = "Cancel", placement = 'bottom', children } = props;
|
|
@@ -1269,15 +1260,15 @@ function CwConfirmationPopup(props) {
|
|
|
1269
1260
|
onCancel();
|
|
1270
1261
|
}
|
|
1271
1262
|
};
|
|
1272
|
-
return (jsxs(Fragment, { children: [renderChildren(), isOpen && (jsx("div", { className: styles$
|
|
1263
|
+
return (jsxs(Fragment, { children: [renderChildren(), isOpen && (jsx("div", { className: styles$t.overlayPositioned, onClick: handleOverlayClick, children: jsxs("div", { ref: popupRef, className: styles$t.popup, style: {
|
|
1273
1264
|
position: 'absolute',
|
|
1274
1265
|
top: `${position.top}px`,
|
|
1275
1266
|
left: `${position.left}px`,
|
|
1276
1267
|
transform: 'none'
|
|
1277
|
-
}, children: [jsx("p", { className: styles$
|
|
1268
|
+
}, children: [jsx("p", { className: styles$t.message, children: message }), jsxs("div", { className: styles$t.buttons, children: [jsx("button", { className: `${styles$t.button} ${styles$t.confirmButton}`, onClick: onConfirm, children: confirmText }), jsx("button", { className: `${styles$t.button} ${styles$t.cancelButton}`, onClick: onCancel, children: cancelText })] })] }) }))] }));
|
|
1278
1269
|
}
|
|
1279
1270
|
|
|
1280
|
-
var styles$
|
|
1271
|
+
var styles$s = {"cw-dialog-main":"cw-dialog-module__cw-dialog-main__cHxHt","cw-dialog-button-close":"cw-dialog-module__cw-dialog-button-close__9GRd8"};
|
|
1281
1272
|
|
|
1282
1273
|
// Helper function to parse size values
|
|
1283
1274
|
const parseSize = (size) => {
|
|
@@ -1550,7 +1541,7 @@ const CwDialog = props => {
|
|
|
1550
1541
|
}
|
|
1551
1542
|
}
|
|
1552
1543
|
}, [open]);
|
|
1553
|
-
const header = useMemo(() => (jsxs("header", { onMouseDown: handleMouseDown, children: [jsx("span", { children: headline }), customHeader || (jsx("button", { className: styles$
|
|
1544
|
+
const header = useMemo(() => (jsxs("header", { onMouseDown: handleMouseDown, children: [jsx("span", { children: headline }), customHeader || (jsx("button", { className: styles$s["cw-dialog-button-close"], onClick: onClose }))] })), [handleMouseDown, headline, customHeader, onClose]);
|
|
1554
1545
|
const content = useMemo(() => (jsx("section", { children: children })), [children]);
|
|
1555
1546
|
const footer = useMemo(() => (jsx("footer", { children: customFooter || (jsx(CwButton, { variant: "icon", icon: "save", title: "Save", onClick: onSave, tooltipPosition: "top", disabled: disableSave, "data-testid": "cw-dialog-save" })) })), [customFooter, onSave, disableSave]);
|
|
1556
1547
|
const resizeHandles = useMemo(() => size.autoHeight
|
|
@@ -1577,7 +1568,7 @@ const CwDialog = props => {
|
|
|
1577
1568
|
: `${convertFromPx(size.height, size.heightUnit)}${size.heightUnit}`;
|
|
1578
1569
|
return { displayWidth, displayHeight };
|
|
1579
1570
|
}, [size.width, size.height, size.widthUnit, size.heightUnit, size.autoHeight]);
|
|
1580
|
-
const dialogContent = (jsx("div", { "data-has-scrim": hasScrim, className: styles$
|
|
1571
|
+
const dialogContent = (jsx("div", { "data-has-scrim": hasScrim, className: styles$s["cw-dialog-main"], onMouseDown: handleScrimMouseDown, onMouseUp: handleScrimMouseUpOrLeave, onMouseLeave: handleScrimMouseUpOrLeave, "data-pressing": isPressingScrim, children: jsxs("dialog", { ...domProps, ref: dialogRef, style: {
|
|
1581
1572
|
left: `${position.x}px`,
|
|
1582
1573
|
top: `${position.y}px`,
|
|
1583
1574
|
width: displayDimensions.displayWidth,
|
|
@@ -1738,7 +1729,7 @@ function CwAlign(props) {
|
|
|
1738
1729
|
}, children: props.children }));
|
|
1739
1730
|
}
|
|
1740
1731
|
|
|
1741
|
-
var styles$
|
|
1732
|
+
var styles$r = {"card":"cw-card-module__card__HJUT0","clickable":"cw-card-module__clickable__Y-V3X","disabled":"cw-card-module__disabled__0wHh1","loading":"cw-card-module__loading__-fzlx","content":"cw-card-module__content__ma9qy","headerContent":"cw-card-module__headerContent__x4Jfl","footerTags":"cw-card-module__footerTags__80sSW","loadingOverlay":"cw-card-module__loadingOverlay__8-zVV"};
|
|
1742
1733
|
|
|
1743
1734
|
/**
|
|
1744
1735
|
* CwCard - A simple card component for displaying content in a contained format
|
|
@@ -1764,11 +1755,11 @@ const CwCard = ({ id, title, subtitle, alignment = 'center', children, footer, o
|
|
|
1764
1755
|
// Construct class names using CSS modules
|
|
1765
1756
|
const cardClassNames = [
|
|
1766
1757
|
'cw-card',
|
|
1767
|
-
styles$
|
|
1758
|
+
styles$r.card,
|
|
1768
1759
|
className,
|
|
1769
|
-
clickable ? styles$
|
|
1770
|
-
disabled ? styles$
|
|
1771
|
-
isLoading ? styles$
|
|
1760
|
+
clickable ? styles$r.clickable : '',
|
|
1761
|
+
disabled ? styles$r.disabled : '',
|
|
1762
|
+
isLoading ? styles$r.loading : '',
|
|
1772
1763
|
].filter(Boolean).join(' ');
|
|
1773
1764
|
// Handle click event when card is clickable
|
|
1774
1765
|
const handleClick = () => {
|
|
@@ -1785,15 +1776,15 @@ const CwCard = ({ id, title, subtitle, alignment = 'center', children, footer, o
|
|
|
1785
1776
|
// Determine if footer should be rendered
|
|
1786
1777
|
const hasFooter = hasChips || footer || (hasActions && resolvedDirection === "row");
|
|
1787
1778
|
// Actions component to reuse
|
|
1788
|
-
const ActionsComponent = hasActions && !disabled ? (jsxs("div", { className: styles$
|
|
1779
|
+
const ActionsComponent = hasActions && !disabled ? (jsxs("div", { className: styles$r.actions, children: [extraActions ?? null, onEdit && jsx(CwButton, { variant: "icon", icon: "edit", onClick: onEdit }), onDelete && jsx(CwButton, { variant: "icon", icon: "delete", color: "danger", onClick: onDelete })] })) : null;
|
|
1789
1780
|
return (jsxs("div", { ...(id && { id }), className: cardClassNames, ...(style && { style }), ...(clickable && {
|
|
1790
1781
|
role: 'button',
|
|
1791
1782
|
tabIndex: 0,
|
|
1792
1783
|
onClick: handleClick,
|
|
1793
|
-
}), "data-variant": variant, "data-direction": resolvedDirection, children: [hasHeader && (jsxs("header", { children: [(title || subtitle) && (jsxs("div", { className: styles$
|
|
1784
|
+
}), "data-variant": variant, "data-direction": resolvedDirection, children: [hasHeader && (jsxs("header", { children: [(title || subtitle) && (jsxs("div", { className: styles$r.headerContent, "data-align": resolvedAlign, children: [title && jsx("h5", { children: title }), subtitle && jsx("strong", { children: subtitle })] })), resolvedDirection === "column" && ActionsComponent] })), jsx("div", { className: styles$r.content, children: children }), hasFooter && (jsxs("footer", { children: [hasChips && (jsx("div", { className: styles$r.footerTags, children: chips.map((chip, index) => (jsx(CwChip, { label: chip.label, colorScheme: chip.colorScheme, className: styles$r.chip, ...(chip.customColor && { customColor: chip.customColor }), ...(chip.variant && { variant: chip.variant }), ...(chip.icon && { icon: chip.icon }) }, index))) })), footer && (jsx("div", { className: styles$r.footerContent, children: footer }))] })), resolvedDirection === "row" && ActionsComponent, isLoading && (jsx("div", { className: styles$r.loadingOverlay, children: jsx(CwLoading, { isLoading: isLoading, size: "small" }) }))] }));
|
|
1794
1785
|
};
|
|
1795
1786
|
|
|
1796
|
-
var styles$
|
|
1787
|
+
var styles$q = {"cardContainer":"cw-card-list-module__cardContainer__l3YEh","pagination":"cw-card-list-module__pagination__5Ay78","pageInfo":"cw-card-list-module__pageInfo__uiMel","loading":"cw-card-list-module__loading__cYpND","emptyState":"cw-card-list-module__emptyState__RlqiS"};
|
|
1797
1788
|
|
|
1798
1789
|
/**
|
|
1799
1790
|
* Option to display in the CwSelect
|
|
@@ -1888,10 +1879,10 @@ function CwCardList({ items, renderCard, pageSize = 10, layout = 'grid', default
|
|
|
1888
1879
|
icon: sortDirection === 'asc' ? 'arrow-up' : 'arrow-down',
|
|
1889
1880
|
onClick: () => setSortDirection(prev => prev === 'asc' ? 'desc' : 'asc'),
|
|
1890
1881
|
title: `Sort ${sortDirection === 'asc' ? 'descending' : 'ascending'}`,
|
|
1891
|
-
}, value: sortKey, onChange: (e) => handleSortChange(e.target.value), children: sortOptions.map(option => (jsx(CwOption, { value: option.key, children: option.label }, option.key))) }) })), isLoading ? (jsx("div", { className: styles$
|
|
1882
|
+
}, value: sortKey, onChange: (e) => handleSortChange(e.target.value), children: sortOptions.map(option => (jsx(CwOption, { value: option.key, children: option.label }, option.key))) }) })), isLoading ? (jsx("div", { className: styles$q.loading, children: jsx(CwLoading, { isLoading: isLoading }) })) : sortedItems.length === 0 ? (jsx("div", { className: styles$q.emptyState, children: emptyState || jsx("p", { children: "No items to display" }) })) : (jsxs(Fragment, { children: [jsx("div", { className: `${styles$q.cardContainer}`, "data-layout": layout, style: gridStyle, children: visibleItems.map((item, index) => (jsx(React__default.Fragment, { children: renderCard(item, index) }, keyExtractor ? keyExtractor(item, index) : index))) }), totalPages > 1 && (jsxs("div", { className: styles$q.pagination, children: [jsx(CwButton, { variant: "icon", icon: "chevron-left", disabled: currentPage === 1, onClick: () => setCurrentPage(p => Math.max(1, p - 1)) }), jsxs("span", { className: styles$q.pageInfo, children: [currentPage, " / ", totalPages] }), jsx(CwButton, { variant: "icon", icon: "chevron-right", disabled: currentPage === totalPages, onClick: () => setCurrentPage(p => Math.min(totalPages, p + 1)) })] }))] }))] }));
|
|
1892
1883
|
}
|
|
1893
1884
|
|
|
1894
|
-
var styles$
|
|
1885
|
+
var styles$p = {"cw-accordion":"cw-accordion-module__cw-accordion__ErvlW","cw-accordion-body":"cw-accordion-module__cw-accordion-body__xlI8b"};
|
|
1895
1886
|
|
|
1896
1887
|
/**
|
|
1897
1888
|
*
|
|
@@ -1908,7 +1899,7 @@ function CwAccordionContainer(CwelltAccordionContainerProps) {
|
|
|
1908
1899
|
setVisible_accordionBody(!isVisible_accordionBody);
|
|
1909
1900
|
};
|
|
1910
1901
|
// #endregion
|
|
1911
|
-
return (jsxs("div", { className: styles$
|
|
1902
|
+
return (jsxs("div", { className: styles$p["cw-accordion"], style: CwelltAccordionContainerProps.style, "data-open": isVisible_accordionBody, children: [jsxs("header", { onClick: () => showAccordionBody(), children: [jsx("div", { children: CwelltAccordionContainerProps.desc_text }), jsx("button", { className: "cw-button-icon" })] }), jsx("div", { className: styles$p["cw-accordion-body"], children: CwelltAccordionContainerProps.children })] }));
|
|
1912
1903
|
}
|
|
1913
1904
|
|
|
1914
1905
|
/**
|
|
@@ -2166,7 +2157,7 @@ function CwTable({ columns, data, pagination = false, pageSizeOptions = [5, 10,
|
|
|
2166
2157
|
}, min: 1, max: totalPages }), jsx("span", { children: "/" }), jsx("span", { children: totalPages }), jsx(CwButton, { onClick: () => handlePageChange(currentPage + 1), disabled: currentPage === totalPages || totalPages <= 1, variant: "icon", icon: "chevron-right" }), jsx(CwButton, { onClick: () => handlePageChange(totalPages), disabled: currentPage === totalPages || totalPages <= 1, variant: "icon", icon: "chevron-right-double" })] })] }))] }));
|
|
2167
2158
|
}
|
|
2168
2159
|
|
|
2169
|
-
var styles$
|
|
2160
|
+
var styles$o = {"dropIndicator":"cw-sortable-table-module__dropIndicator__ov-Jz","dragging":"cw-sortable-table-module__dragging__MrLrz","skeletonRow":"cw-sortable-table-module__skeletonRow__vyD0M","skeleton":"cw-sortable-table-module__skeleton__QGXAD","saveBar":"cw-sortable-table-module__saveBar__3OdoZ cw-flex-row cw-align-center-center cw-gap-small"};
|
|
2170
2161
|
|
|
2171
2162
|
/**
|
|
2172
2163
|
* Hook that provides state management for CwSortableTable.
|
|
@@ -2229,9 +2220,9 @@ function useSortableTable(initialItems) {
|
|
|
2229
2220
|
}
|
|
2230
2221
|
|
|
2231
2222
|
// ─── Drop indicator row ───────────────────────────────────────────────────────
|
|
2232
|
-
const DropIndicatorRow = ({ colSpan }) => (jsx("tr", { className: styles$
|
|
2223
|
+
const DropIndicatorRow = ({ colSpan }) => (jsx("tr", { className: styles$o.dropIndicator, "aria-hidden": true, children: jsx("td", { colSpan: colSpan, children: jsx("div", {}) }) }));
|
|
2233
2224
|
// ─── Loading skeleton ─────────────────────────────────────────────────────────
|
|
2234
|
-
const LoadingRows = ({ colSpan }) => (jsx(Fragment, { children: Array.from({ length: 4 }).map((_, i) => (jsx("tr", { className: styles$
|
|
2225
|
+
const LoadingRows = ({ colSpan }) => (jsx(Fragment, { children: Array.from({ length: 4 }).map((_, i) => (jsx("tr", { className: styles$o.skeletonRow, children: jsx("td", { colSpan: colSpan, children: jsx("div", { className: styles$o.skeleton }) }) }, i))) }));
|
|
2235
2226
|
// ─── Component ────────────────────────────────────────────────────────────────
|
|
2236
2227
|
/**
|
|
2237
2228
|
* CwSortableTable
|
|
@@ -2318,11 +2309,11 @@ function CwSortableTable({ columns, data, rowKey = "key", onReorder, loading = f
|
|
|
2318
2309
|
return items.map((item, index) => {
|
|
2319
2310
|
const key = item[rowKey];
|
|
2320
2311
|
const isDragging = draggedItem?.[rowKey] === key;
|
|
2321
|
-
return (jsxs(React__default.Fragment, { children: [dropIndicatorIndex === index && (jsx(DropIndicatorRow, { colSpan: totalCols })), jsxs("tr", { draggable: true, onDragStart: (e) => handleDragStart(e, item), onDragOver: (e) => handleDragOver(e, index), onDragEnd: handleDragEnd, className: isDragging ? styles$
|
|
2312
|
+
return (jsxs(React__default.Fragment, { children: [dropIndicatorIndex === index && (jsx(DropIndicatorRow, { colSpan: totalCols })), jsxs("tr", { draggable: true, onDragStart: (e) => handleDragStart(e, item), onDragOver: (e) => handleDragOver(e, index), onDragEnd: handleDragEnd, className: isDragging ? styles$o.dragging : "", children: [showHandle && (jsx("td", { className: "cw-table-col-action", children: jsx(CwIcon, { iconId: "grip-dots", color: "neutral", style: { opacity: 0.75 } }) })), columns.map(col => (jsx("td", { className: col.className ?? "", style: col.width ? { width: col.width } : undefined, children: renderCell(item, col) }, `${String(key)}_${col.key}`)))] }), index === items.length - 1 && dropIndicatorIndex === items.length && (jsx(DropIndicatorRow, { colSpan: totalCols }))] }, String(key)));
|
|
2322
2313
|
});
|
|
2323
2314
|
};
|
|
2324
2315
|
// ── Render ──────────────────────────────────────────────────────────────
|
|
2325
|
-
return (jsxs("div", { className: `cw-table-container ${className ?? ""}`, style: containerStyle, children: [jsxs("table", { className: `cw-table cw-sortable-table ${tableClassName ?? ""}`, style: { width: "100%" }, children: [jsx("thead", { children: jsxs("tr", { children: [showHandle && jsx("th", { className: "cw-table-col-action" }), columns.map(col => (jsx("th", { className: col.className ?? "", style: col.width ? { width: col.width, minWidth: 50 } : undefined, children: col.title }, col.key)))] }) }), jsx("tbody", { children: renderBody() })] }), hasChanges && (jsxs("footer", { className: styles$
|
|
2316
|
+
return (jsxs("div", { className: `cw-table-container ${className ?? ""}`, style: containerStyle, children: [jsxs("table", { className: `cw-table cw-sortable-table ${tableClassName ?? ""}`, style: { width: "100%" }, children: [jsx("thead", { children: jsxs("tr", { children: [showHandle && jsx("th", { className: "cw-table-col-action" }), columns.map(col => (jsx("th", { className: col.className ?? "", style: col.width ? { width: col.width, minWidth: 50 } : undefined, children: col.title }, col.key)))] }) }), jsx("tbody", { children: renderBody() })] }), hasChanges && (jsxs("footer", { className: styles$o.saveBar, children: [jsx(CwButton, { variant: "outline", color: "neutral", icon: "undo", text: discardLabel, onClick: handleDiscard }), jsx(CwButton, { variant: "solid", color: "primary", icon: "save", text: saveLabel, onClick: () => handleSave(onReorder) })] }))] }));
|
|
2326
2317
|
}
|
|
2327
2318
|
|
|
2328
2319
|
/**
|
|
@@ -2521,7 +2512,7 @@ function CwTableServerSide({ columns, data, totalItems, pagination = false, page
|
|
|
2521
2512
|
}, min: 1, max: totalPages }), jsx("span", { children: "/" }), jsx("span", { children: totalPages }), jsx(CwButton, { onClick: () => handlePageChange(state.page + 1), disabled: state.page === totalPages || totalPages <= 1, variant: "icon", icon: "chevron-right" }), jsx(CwButton, { onClick: () => handlePageChange(totalPages), disabled: state.page === totalPages || totalPages <= 1, variant: "icon", icon: "chevron-right-double" })] })] }))] }));
|
|
2522
2513
|
}
|
|
2523
2514
|
|
|
2524
|
-
var styles$
|
|
2515
|
+
var styles$n = {"cw-tabs":"cw-tabs-module__cw-tabs__1pmji","badge":"cw-tabs-module__badge__AmVxW","cw-tabs-content":"cw-tabs-module__cw-tabs-content__HTp8d"};
|
|
2525
2516
|
|
|
2526
2517
|
const TabIcon = ({ icon }) => {
|
|
2527
2518
|
if (!icon)
|
|
@@ -2571,7 +2562,7 @@ function CwTabs(CwTabsProps) {
|
|
|
2571
2562
|
const tabsListStyle = position === 'left' && CwTabsProps.tabsListWidth
|
|
2572
2563
|
? { minWidth: CwTabsProps.tabsListWidth }
|
|
2573
2564
|
: undefined;
|
|
2574
|
-
return (jsxs("div", { id: CwTabsProps.id, "data-testid": CwTabsProps.testId, className: styles$
|
|
2565
|
+
return (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: [jsx("ul", { style: tabsListStyle, children: CwTabsProps.tabs.map(tab => (jsxs("li", { className: `${tab.key === activeTab ? "cw-tab-active" : ""}`, onClick: () => handleTabClick(tab), "data-active": tab.key === activeTab, "data-tab-key": tab.key, children: [jsx(TabIcon, { icon: tab.icon }), tab.title, (tab.badge !== undefined || tab.badgeColor) && (jsx("span", { className: styles$n['badge'], style: tab.badgeColor ? { backgroundColor: tab.badgeColor, color: getContrastColor(tab.badgeColor) } : undefined, children: tab.badge }))] }, tab.key))) }), jsx("div", { className: styles$n['cw-tabs-content'], "data-active-tab-key": activeTab ?? undefined, children: activeTab !== null && CwTabsProps.tabs.find(tab => tab.key === activeTab)?.content })] }));
|
|
2575
2566
|
}
|
|
2576
2567
|
|
|
2577
2568
|
/**
|
|
@@ -2598,7 +2589,7 @@ const CwExpandable = ({ briefing, onToggle, onOpen, onClose, children, ...detail
|
|
|
2598
2589
|
return (jsxs("details", { ref: myRef, ...detailsProps, className: "cw-expandable", children: [jsx("summary", { children: briefing }), children && jsx("section", { children: children })] }));
|
|
2599
2590
|
};
|
|
2600
2591
|
|
|
2601
|
-
var styles$
|
|
2592
|
+
var styles$m = {"cw-master-detail":"cw-master-detail-module__cw-master-detail__O8-FA","resizer":"cw-master-detail-module__resizer__hvGhL","detail":"cw-master-detail-module__detail__BG4Dm","detail-empty":"cw-master-detail-module__detail-empty__KFScK"};
|
|
2602
2593
|
|
|
2603
2594
|
const CwMasterDetail = ({ id, className, style, items, selectedKey, onSelect, detailContent, emptyDetail, searchPlaceholder = 'Search...', onSearch, masterHeader, masterFooter, masterWidth: initialWidth = 320, minMasterWidth = 240, maxMasterWidth = 500, resizable = true, showSearch = true, }) => {
|
|
2604
2595
|
const [masterWidth, setMasterWidth] = useState(initialWidth);
|
|
@@ -2634,10 +2625,10 @@ const CwMasterDetail = ({ id, className, style, items, selectedKey, onSelect, de
|
|
|
2634
2625
|
document.body.style.userSelect = '';
|
|
2635
2626
|
};
|
|
2636
2627
|
}, [isResizing, minMasterWidth, maxMasterWidth]);
|
|
2637
|
-
const rootClassName = [styles$
|
|
2638
|
-
return (jsxs("div", { id: id, ref: containerRef, className: rootClassName, style: style, children: [jsxs("aside", { style: { width: masterWidth, minWidth: masterWidth }, children: [showSearch && (jsx("search", { children: jsx("input", { type: "text", placeholder: searchPlaceholder, onChange: (e) => onSearch?.(e.target.value) }) })), masterHeader && (jsx("header", { children: masterHeader })), jsx("ul", { children: items.map((item) => (jsx("li", { "data-master-key": item.key, "data-selected": item.key === selectedKey, "data-disabled": item.disabled, onClick: () => onSelect?.(item.key), children: item.content }, item.key))) }), masterFooter && (jsx("footer", { children: masterFooter }))] }), resizable && (jsx("div", { className: styles$
|
|
2628
|
+
const rootClassName = [styles$m['cw-master-detail'], className].filter(Boolean).join(' ');
|
|
2629
|
+
return (jsxs("div", { id: id, ref: containerRef, className: rootClassName, style: style, children: [jsxs("aside", { style: { width: masterWidth, minWidth: masterWidth }, children: [showSearch && (jsx("search", { children: jsx("input", { type: "text", placeholder: searchPlaceholder, onChange: (e) => onSearch?.(e.target.value) }) })), masterHeader && (jsx("header", { children: masterHeader })), jsx("ul", { children: items.map((item) => (jsx("li", { "data-master-key": item.key, "data-selected": item.key === selectedKey, "data-disabled": item.disabled, onClick: () => onSelect?.(item.key), children: item.content }, item.key))) }), masterFooter && (jsx("footer", { children: masterFooter }))] }), resizable && (jsx("div", { className: styles$m.resizer, "data-resizing": isResizing, onMouseDown: handleMouseDown })), jsx("section", { className: styles$m.detail, children: selectedKey && detailContent
|
|
2639
2630
|
? detailContent
|
|
2640
|
-
: (jsx("div", { className: styles$
|
|
2631
|
+
: (jsx("div", { className: styles$m['detail-empty'], children: emptyDetail ?? 'Select an item to view details' })) })] }));
|
|
2641
2632
|
};
|
|
2642
2633
|
|
|
2643
2634
|
/**
|
|
@@ -2662,7 +2653,7 @@ const CwKeyValueList = ({ items, className = "", emptyValue = "-", direction = "
|
|
|
2662
2653
|
: emptyValue })] }, item.key))) }));
|
|
2663
2654
|
};
|
|
2664
2655
|
|
|
2665
|
-
var styles$
|
|
2656
|
+
var styles$l = {"sortableList":"cw-sortable-list-module__sortableList__PyLO-","sortableItem":"cw-sortable-list-module__sortableItem__FAnn2","readOnly":"cw-sortable-list-module__readOnly__r7GcH","dragging":"cw-sortable-list-module__dragging__MD715","moved":"cw-sortable-list-module__moved__sE6-N","expandedContent":"cw-sortable-list-module__expandedContent__Kocna","sortableHandle":"cw-sortable-list-module__sortableHandle__HvYBK","sortableContent":"cw-sortable-list-module__sortableContent__C6JhR","sortableTitle":"cw-sortable-list-module__sortableTitle__EgWXr","sortableExtraContent":"cw-sortable-list-module__sortableExtraContent__s4LSv","sortableActions":"cw-sortable-list-module__sortableActions__gwQOU","dropIndicator":"cw-sortable-list-module__dropIndicator__MNSF-","emptyMessage":"cw-sortable-list-module__emptyMessage__gMpaL"};
|
|
2666
2657
|
|
|
2667
2658
|
function CwSortableList({ items, onReorder, renderItem, className = '', movedItems = new Set(), emptyMessage = "No elements to show", readOnly = false, maxHeight = "300px", }) {
|
|
2668
2659
|
const [draggedItem, setDraggedItem] = useState(null);
|
|
@@ -2725,15 +2716,15 @@ function CwSortableList({ items, onReorder, renderItem, className = '', movedIte
|
|
|
2725
2716
|
}
|
|
2726
2717
|
};
|
|
2727
2718
|
if (items.length === 0) {
|
|
2728
|
-
return (jsx("div", { className: `${styles$
|
|
2719
|
+
return (jsx("div", { className: `${styles$l.sortableList} ${styles$l.emptyState} ${className}`, children: jsx("div", { className: styles$l.emptyMessage, children: emptyMessage }) }));
|
|
2729
2720
|
}
|
|
2730
|
-
return (jsx("div", { className: `${styles$
|
|
2721
|
+
return (jsx("div", { className: `${styles$l.sortableList} ${className}`, style: { maxHeight }, children: items.map((item, index) => {
|
|
2731
2722
|
const { title, extraContent, actions, showHandle = true, expandedContent } = renderItem(item);
|
|
2732
2723
|
const isDragging = draggedItem?.id === item.id;
|
|
2733
2724
|
const isMoved = movedItems.has(item.id);
|
|
2734
2725
|
const canExpand = Boolean(expandedContent);
|
|
2735
2726
|
const isExpanded = expandedItems.has(item.id);
|
|
2736
|
-
return (jsxs(React__default.Fragment, { children: [dropIndicatorIndex === index && jsx("div", { className: styles$
|
|
2727
|
+
return (jsxs(React__default.Fragment, { children: [dropIndicatorIndex === index && jsx("div", { className: styles$l.dropIndicator }), jsxs("div", { className: `${styles$l.sortableItem} ${isDragging ? styles$l.dragging : ''} ${isMoved ? styles$l.moved : ''} ${readOnly ? styles$l.readOnly : ''}`, draggable: !readOnly, onDragStart: (e) => handleDragStart(e, item), onDragOver: (e) => handleDragOver(e, index), onDragEnd: handleDragEnd, children: [jsxs("header", { children: [canExpand ? (jsx(CwButton, { variant: "icon", onClick: () => toggleExpanded(item.id), type: "button", title: isExpanded ? "Collapse" : "Expand", icon: isExpanded ? "chevron-up" : "chevron-down" })) : showHandle ? (jsx("div", { className: styles$l.sortableHandle, children: jsx(CwIcon, { iconId: "grip-dots" }) })) : null, jsxs("div", { className: styles$l.sortableContent, children: [jsx("div", { className: styles$l.sortableTitle, children: title }), extraContent && jsx("div", { className: styles$l.sortableExtraContent, children: extraContent })] }), jsx("div", { className: styles$l.sortableActions, children: actions })] }), isExpanded && expandedContent && (jsx("div", { className: styles$l.expandedContent, children: expandedContent }))] }), !readOnly && dropIndicatorIndex === items.length && index === items.length - 1 && (jsx("div", { className: styles$l.dropIndicator }))] }, item.id));
|
|
2737
2728
|
}) }));
|
|
2738
2729
|
}
|
|
2739
2730
|
|
|
@@ -2859,60 +2850,9 @@ const CwTableGrouped = props => {
|
|
|
2859
2850
|
group.rows.map((child, j) => (jsx("tr", { "data-row": true, "data-row-last-of-group": j == group.rows.length - 1, children: child.cells.map((cell, k) => (jsx("td", { children: cell.content }, k))) }, j)))] }, i))) }), jsx("tfoot", {})] }) }));
|
|
2860
2851
|
};
|
|
2861
2852
|
|
|
2862
|
-
|
|
2863
|
-
const [previewURL, setPreviewURL] = useState("");
|
|
2864
|
-
const [error, setError] = useState(null);
|
|
2865
|
-
const [_selectedFileName, setSelectedFileName] = useState("");
|
|
2866
|
-
const [_currentHexContent, setCurrentHexContent] = useState("");
|
|
2867
|
-
useEffect(() => {
|
|
2868
|
-
// If there is hexadecimal preview content, set the Preview URL
|
|
2869
|
-
if (fileUploadProps.file?.Bindata) {
|
|
2870
|
-
setPreviewURL(`data:image/png;base64,${fileUploadProps.file.Bindata}`);
|
|
2871
|
-
}
|
|
2872
|
-
}, [fileUploadProps.file?.Bindata]);
|
|
2873
|
-
const handleFileChange = (event) => {
|
|
2874
|
-
const file = event.target.files?.[0];
|
|
2875
|
-
setSelectedFileName(file?.name ?? "");
|
|
2876
|
-
if (file) {
|
|
2877
|
-
const allowedExts = fileUploadProps.accept.split(',').map(ext => ext.trim().replace('.', '').toLowerCase());
|
|
2878
|
-
const fileExt = file.name.split('.').pop()?.toLowerCase() ?? "";
|
|
2879
|
-
if (!allowedExts.includes(fileExt)) {
|
|
2880
|
-
setError(`Invalid file type. Only ${fileUploadProps.acceptString} files are allowed.`);
|
|
2881
|
-
setPreviewURL("");
|
|
2882
|
-
return;
|
|
2883
|
-
}
|
|
2884
|
-
setError(null);
|
|
2885
|
-
const reader = new FileReader();
|
|
2886
|
-
reader.onloadend = () => {
|
|
2887
|
-
if (typeof reader.result === "string") {
|
|
2888
|
-
const hexContent = arrayBufferToHex(reader.result);
|
|
2889
|
-
setCurrentHexContent(hexContent);
|
|
2890
|
-
setPreviewURL(reader.result);
|
|
2891
|
-
setCurrentHexContent(arrayBufferToHex(reader.result));
|
|
2892
|
-
// Call function to store hexadecimal content
|
|
2893
|
-
fileUploadProps.onSaveHexContent(arrayBufferToHex(reader.result));
|
|
2894
|
-
}
|
|
2895
|
-
};
|
|
2896
|
-
reader.readAsDataURL(file);
|
|
2897
|
-
}
|
|
2898
|
-
};
|
|
2899
|
-
// Function to convert the image buffer into hexadecimal content
|
|
2900
|
-
const arrayBufferToHex = (dataUrl) => {
|
|
2901
|
-
// Decodes the base64 of the URL data
|
|
2902
|
-
const base64 = dataUrl.split(",")[1];
|
|
2903
|
-
const binary = atob(base64);
|
|
2904
|
-
let hex = "";
|
|
2905
|
-
for (let i = 0; i < binary.length; i++) {
|
|
2906
|
-
hex += binary.charCodeAt(i).toString(16).padStart(2, "0");
|
|
2907
|
-
}
|
|
2908
|
-
return hex;
|
|
2909
|
-
};
|
|
2910
|
-
return (jsxs("div", { children: [jsxs("div", { className: "row", children: [jsx("input", { className: "cw-button", type: "file", accept: fileUploadProps.accept, readOnly: true, placeholder: "No file selected...", onChange: handleFileChange }), previewURL && (jsx("div", { className: "row", children: jsx("img", { src: previewURL, alt: "Preview", style: { maxWidth: "200px", maxHeight: "200px" } }) }))] }), error && jsx("div", { className: "row error", children: error }), jsx("div", { className: "row", children: jsxs("label", { children: ["Please note: File/image has to be in ", fileUploadProps.acceptString, " format", fileUploadProps.sizeString && `, ${fileUploadProps.sizeString}`] }) })] }));
|
|
2911
|
-
}
|
|
2912
|
-
|
|
2913
|
-
var styles$j = {"fileUploadContainer":"cw-file-upload-multiple-module__fileUploadContainer__liEc1","hiddenInput":"cw-file-upload-multiple-module__hiddenInput__TZBBI","uploadArea":"cw-file-upload-multiple-module__uploadArea__DdOhs","uploadAreaDisabled":"cw-file-upload-multiple-module__uploadAreaDisabled__VWeFX","uploadTitle":"cw-file-upload-multiple-module__uploadTitle__gjRk8","uploadSubtitle":"cw-file-upload-multiple-module__uploadSubtitle__Z0S5t","filesContainer":"cw-file-upload-multiple-module__filesContainer__g44PY","fileItem":"cw-file-upload-multiple-module__fileItem__w27Dg","fileIcon":"cw-file-upload-multiple-module__fileIcon__iJJUX","fileExtension":"cw-file-upload-multiple-module__fileExtension__vOuHv","fileInfo":"cw-file-upload-multiple-module__fileInfo__R5ZTv","fileName":"cw-file-upload-multiple-module__fileName__DjepK","fileSize":"cw-file-upload-multiple-module__fileSize__b8GSm","smallButton":"cw-file-upload-multiple-module__smallButton__siUAh"};
|
|
2853
|
+
var styles$k = {"fileUploadContainer":"cw-file-upload-multiple-module__fileUploadContainer__liEc1","hiddenInput":"cw-file-upload-multiple-module__hiddenInput__TZBBI","uploadArea":"cw-file-upload-multiple-module__uploadArea__DdOhs","uploadAreaDisabled":"cw-file-upload-multiple-module__uploadAreaDisabled__VWeFX","uploadTitle":"cw-file-upload-multiple-module__uploadTitle__gjRk8","uploadSubtitle":"cw-file-upload-multiple-module__uploadSubtitle__Z0S5t","filesContainer":"cw-file-upload-multiple-module__filesContainer__g44PY","fileItem":"cw-file-upload-multiple-module__fileItem__w27Dg","fileIcon":"cw-file-upload-multiple-module__fileIcon__iJJUX","fileExtension":"cw-file-upload-multiple-module__fileExtension__vOuHv","fileInfo":"cw-file-upload-multiple-module__fileInfo__R5ZTv","fileName":"cw-file-upload-multiple-module__fileName__DjepK","fileSize":"cw-file-upload-multiple-module__fileSize__b8GSm","smallButton":"cw-file-upload-multiple-module__smallButton__siUAh"};
|
|
2914
2854
|
|
|
2915
|
-
const DEFAULT_LABELS = {
|
|
2855
|
+
const DEFAULT_LABELS$1 = {
|
|
2916
2856
|
uploadDisabled: 'Upload disabled',
|
|
2917
2857
|
clickToUpload: 'Click to upload or drag and drop',
|
|
2918
2858
|
acceptedFiles: (accept) => `Accepted files: ${accept}`,
|
|
@@ -2920,6 +2860,7 @@ const DEFAULT_LABELS = {
|
|
|
2920
2860
|
allTypesAccepted: 'All file types accepted',
|
|
2921
2861
|
changeFile: 'Change File',
|
|
2922
2862
|
clearAll: 'Clear all',
|
|
2863
|
+
upload: 'Upload',
|
|
2923
2864
|
addMoreFiles: 'Add More Files',
|
|
2924
2865
|
filesSelected: (count) => `${count} file${count !== 1 ? 's' : ''} selected`,
|
|
2925
2866
|
fileTooLarge: (name, maxSize) => `File "${name}" is too large. Maximum size allowed is ${maxSize}MB.`,
|
|
@@ -2927,11 +2868,38 @@ const DEFAULT_LABELS = {
|
|
|
2927
2868
|
invalidMimeType: (name, types) => `File "${name}" has an invalid MIME type. Allowed types: ${types}`,
|
|
2928
2869
|
alreadySelected: (name) => `File "${name}" is already selected.`,
|
|
2929
2870
|
};
|
|
2871
|
+
/**
|
|
2872
|
+
* Checks a file against an `accept` string (comma-separated tokens). A token can be a dotted
|
|
2873
|
+
* extension (".pdf"), an exact MIME type ("application/pdf"), a wildcard MIME ("image" + slash + "star"),
|
|
2874
|
+
* or a bare "star" / "star-slash-star" for anything. Returns true if the file matches ANY token
|
|
2875
|
+
* (or if `accept` is empty).
|
|
2876
|
+
*/
|
|
2877
|
+
function fileMatchesAccept(fileName, fileType, accept) {
|
|
2878
|
+
const tokens = accept.split(',').map(token => token.trim().toLowerCase()).filter(Boolean);
|
|
2879
|
+
if (tokens.length === 0) {
|
|
2880
|
+
return true;
|
|
2881
|
+
}
|
|
2882
|
+
const fileExtension = '.' + (fileName.split('.').pop()?.toLowerCase() ?? '');
|
|
2883
|
+
const mimeType = fileType.toLowerCase();
|
|
2884
|
+
return tokens.some(token => {
|
|
2885
|
+
if (token === '*' || token === '*/*') {
|
|
2886
|
+
return true;
|
|
2887
|
+
}
|
|
2888
|
+
if (token.startsWith('.')) {
|
|
2889
|
+
return token === fileExtension;
|
|
2890
|
+
}
|
|
2891
|
+
if (token.endsWith('/*')) {
|
|
2892
|
+
const prefix = token.slice(0, token.indexOf('/') + 1);
|
|
2893
|
+
return mimeType.startsWith(prefix);
|
|
2894
|
+
}
|
|
2895
|
+
return token === mimeType;
|
|
2896
|
+
});
|
|
2897
|
+
}
|
|
2930
2898
|
function CwFileUploadMultiple(fileUploadProps) {
|
|
2931
2899
|
const fileInputRef = useRef(null);
|
|
2932
2900
|
const [selectedFiles, setSelectedFiles] = useState([]);
|
|
2933
2901
|
const [existingFile, setExistingFile] = useState(fileUploadProps.initialFileName);
|
|
2934
|
-
const labels = { ...DEFAULT_LABELS, ...fileUploadProps.labels };
|
|
2902
|
+
const labels = { ...DEFAULT_LABELS$1, ...fileUploadProps.labels };
|
|
2935
2903
|
React__default.useEffect(() => {
|
|
2936
2904
|
setExistingFile(fileUploadProps.initialFileName);
|
|
2937
2905
|
}, [fileUploadProps.initialFileName]);
|
|
@@ -2949,17 +2917,9 @@ function CwFileUploadMultiple(fileUploadProps) {
|
|
|
2949
2917
|
};
|
|
2950
2918
|
}
|
|
2951
2919
|
}
|
|
2952
|
-
// Validate file type
|
|
2920
|
+
// Validate file type against accept (dotted extensions, exact MIME, wildcard MIME, or *)
|
|
2953
2921
|
if (fileUploadProps.accept) {
|
|
2954
|
-
|
|
2955
|
-
const fileExtension = '.' + file.name.split('.').pop()?.toLowerCase();
|
|
2956
|
-
const isExtensionValid = acceptedExtensions.some(ext => {
|
|
2957
|
-
if (ext.startsWith('.')) {
|
|
2958
|
-
return ext === fileExtension;
|
|
2959
|
-
}
|
|
2960
|
-
return false;
|
|
2961
|
-
});
|
|
2962
|
-
if (!isExtensionValid) {
|
|
2922
|
+
if (!fileMatchesAccept(file.name, file.type, fileUploadProps.accept)) {
|
|
2963
2923
|
return {
|
|
2964
2924
|
isValid: false,
|
|
2965
2925
|
error: labels.invalidFormat(file.name, fileUploadProps.accept)
|
|
@@ -2984,7 +2944,7 @@ function CwFileUploadMultiple(fileUploadProps) {
|
|
|
2984
2944
|
const errors = [];
|
|
2985
2945
|
for (const file of fileArray) {
|
|
2986
2946
|
// Check if the file already exists (by name and size)
|
|
2987
|
-
const isDuplicate =
|
|
2947
|
+
const isDuplicate = validFiles.some(existingFile => existingFile.name === file.name && existingFile.size === file.size);
|
|
2988
2948
|
if (isDuplicate) {
|
|
2989
2949
|
errors.push(labels.alreadySelected(file.name));
|
|
2990
2950
|
continue;
|
|
@@ -3002,8 +2962,7 @@ function CwFileUploadMultiple(fileUploadProps) {
|
|
|
3002
2962
|
fileUploadProps.onError(errors.join('\n'));
|
|
3003
2963
|
}
|
|
3004
2964
|
else {
|
|
3005
|
-
|
|
3006
|
-
alert(errors.join('\n')); // Fallback if there is no onError
|
|
2965
|
+
CwDisplayMessage(errors.join('\n'), CwMessageType.ERROR);
|
|
3007
2966
|
}
|
|
3008
2967
|
}
|
|
3009
2968
|
// If not multiple, only take the first valid file (replace)
|
|
@@ -3077,12 +3036,20 @@ function CwFileUploadMultiple(fileUploadProps) {
|
|
|
3077
3036
|
}
|
|
3078
3037
|
}
|
|
3079
3038
|
};
|
|
3080
|
-
return (jsxs("div", { className: `${styles$
|
|
3039
|
+
return (jsxs("div", { className: `${styles$k.fileUploadContainer} ${fileUploadProps.className}`, children: [jsx("input", { ref: fileInputRef, type: "file", name: fileUploadProps.name, accept: fileUploadProps.accept, multiple: fileUploadProps.multiple, onChange: handleFileSelectInternal, disabled: fileUploadProps.disabled, "aria-label": "files", className: styles$k.hiddenInput }), selectedFiles.length === 0 && !existingFile ? (jsxs("div", { className: `${styles$k.uploadArea} ${fileUploadProps.disabled ? styles$k.uploadAreaDisabled : ''}`, onDragOver: handleDragOver, onDrop: handleDrop, onClick: !fileUploadProps.disabled ? handleButtonClick : undefined, children: [jsx(CwIcon, { iconId: "upload" }), jsx("p", { className: `${styles$k.uploadTitle}`, children: fileUploadProps.disabled ? labels.uploadDisabled : labels.clickToUpload }), jsxs("p", { className: `${styles$k.uploadSubtitle}`, children: [fileUploadProps.accept ? labels.acceptedFiles(fileUploadProps.accept) : labels.allTypesAccepted, !fileUploadProps.multiple && ` ${labels.singleFileOnly}`] })] })) : selectedFiles.length === 0 && existingFile ? (jsxs("div", { className: styles$k.filesContainer, children: [jsxs("div", { className: styles$k.fileItem, children: [jsxs("div", { className: styles$k.fileIcon, children: [jsx(CwIcon, { iconId: "page" }), jsx("span", { className: styles$k.fileExtension, children: getFileExtension(existingFile) })] }), jsx("div", { className: styles$k.fileInfo, children: jsx("p", { className: styles$k.fileName, children: existingFile }) }), jsx(CwButton, { variant: "icon", icon: "close", color: "neutral", onClick: () => {
|
|
3081
3040
|
setExistingFile(undefined);
|
|
3082
3041
|
if (fileUploadProps.onSelect) {
|
|
3083
3042
|
fileUploadProps.onSelect(null);
|
|
3084
3043
|
}
|
|
3085
|
-
}, disabled: fileUploadProps.disabled, className: styles$
|
|
3044
|
+
}, disabled: fileUploadProps.disabled, className: styles$k.smallButton })] }), jsx(CwButton, { text: labels.changeFile, icon: "refresh", onClick: handleButtonClick, disabled: fileUploadProps.disabled })] })) : (jsxs("div", { className: styles$k.filesContainer, children: [jsxs("header", { className: "cw-flex-row cw-align-between-center cw-flex-wrap", children: [jsx("small", { className: styles$k.filesCount, children: fileUploadProps.statusText ?? labels.filesSelected(selectedFiles.length) }), jsxs("div", { className: "cw-flex-row", children: [fileUploadProps.onConfirm && selectedFiles.length > 0 && (jsx(CwButton, { onClick: () => {
|
|
3045
|
+
let files = fileInputRef.current?.files ?? null;
|
|
3046
|
+
if (!files) {
|
|
3047
|
+
const dataTransfer = new DataTransfer();
|
|
3048
|
+
selectedFiles.forEach(file => dataTransfer.items.add(file));
|
|
3049
|
+
files = dataTransfer.files;
|
|
3050
|
+
}
|
|
3051
|
+
fileUploadProps.onConfirm?.(files);
|
|
3052
|
+
}, disabled: fileUploadProps.disabled || fileUploadProps.confirmDisabled, icon: "upload", text: fileUploadProps.confirmLabel ?? labels.upload })), !fileUploadProps.hideClearAll && (jsx(CwButton, { onClick: removeAllFiles, disabled: fileUploadProps.disabled, color: "danger", variant: "outline", icon: "delete", text: labels.clearAll }))] })] }), selectedFiles.map((file, index) => (jsxs("div", { className: styles$k.fileItem, children: [jsxs("div", { className: styles$k.fileIcon, children: [jsx(CwIcon, { iconId: "page" }), jsx("span", { className: styles$k.fileExtension, children: getFileExtension(file.name) })] }), jsxs("div", { className: styles$k.fileInfo, children: [jsx("p", { className: styles$k.fileName, children: file.name }), jsxs("p", { className: styles$k.fileSize, children: [(file.size / 1024).toFixed(1), " KB"] })] }), jsx(CwButton, { variant: "icon", icon: "close", color: "neutral", onClick: () => removeFile(index), className: styles$k.smallButton })] }, `${file.name}-${file.size}`))), fileUploadProps.multiple && (jsx(CwButton, { text: labels.addMoreFiles, icon: "plus", variant: "outline", onClick: handleButtonClick, disabled: fileUploadProps.disabled })), !fileUploadProps.multiple && (jsx(CwButton, { text: labels.changeFile, icon: "refresh", onClick: handleButtonClick, disabled: fileUploadProps.disabled }))] }))] }));
|
|
3086
3053
|
}
|
|
3087
3054
|
|
|
3088
3055
|
function CwInput(CwInputProps) {
|
|
@@ -3123,7 +3090,7 @@ function CwDigit(props) {
|
|
|
3123
3090
|
return (jsx("div", { className: "cw-input-text", children: jsxs(CwAlign, { ...alignProps, itemProp: inputProps.required === true ? "required" : "", children: [labelProps && (jsxs(CwLabel, { ...labelProps, children: [iconProps && jsx(CwIcon, { ...iconProps }), labelProps.text] })), jsx("input", { type: "number", ...inputProps }), buttonProps && jsx(CwButton, { ...buttonProps })] }) }));
|
|
3124
3091
|
}
|
|
3125
3092
|
|
|
3126
|
-
var styles$
|
|
3093
|
+
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"};
|
|
3127
3094
|
|
|
3128
3095
|
const CwColorPicker = ({ initialColor, onChange, previewText = "Color preview" }) => {
|
|
3129
3096
|
const [rgb, setRgb] = useState({ r: 255, g: 255, b: 255 });
|
|
@@ -3326,13 +3293,13 @@ const CwColorPicker = ({ initialColor, onChange, previewText = "Color preview" }
|
|
|
3326
3293
|
// Calculate background color for the main area based on current hue
|
|
3327
3294
|
const hueColor = hsvToRgb(hsv.h, 100, 100);
|
|
3328
3295
|
const hueHex = rgbToHex(hueColor.r, hueColor.g, hueColor.b);
|
|
3329
|
-
return (jsxs("div", { className: "cw-flex-column cw-gap-small", children: [jsxs("div", { className: "cw-flex-row cw-align-between-center cw-gap-small", children: [jsx("div", { className: styles$
|
|
3296
|
+
return (jsxs("div", { className: "cw-flex-column cw-gap-small", children: [jsxs("div", { className: "cw-flex-row cw-align-between-center cw-gap-small", children: [jsx("div", { className: styles$j.colorPreview, style: { backgroundColor: hexColor, color: getContrastColor(hexColor) }, children: previewText }), jsx("button", { type: "button", className: "cw-button", onClick: toggleInputMode, style: { minWidth: "3ch" }, children: inputMode === 'hex' ? 'RGB' : 'HEX' })] }), jsx("div", { className: "color-inputs-row", children: inputMode === 'hex' ? (jsx("input", { type: "text", value: hexColor, onChange: handleHexChange })) : (jsxs("div", { className: "cw-grid-base-3 cw-gap-small", children: [jsxs("div", { children: [jsx("label", { children: "R:" }), jsx("input", { type: "number", name: "r", min: "0", max: "255", value: rgb.r, onChange: handleRgbChange })] }), jsxs("div", { children: [jsx("label", { children: "G:" }), jsx("input", { type: "number", name: "g", min: "0", max: "255", value: rgb.g, onChange: handleRgbChange })] }), jsxs("div", { children: [jsx("label", { children: "B:" }), jsx("input", { type: "number", name: "b", min: "0", max: "255", value: rgb.b, onChange: handleRgbChange })] })] })) }), jsxs("div", { className: styles$j.colorPickerInteractiveArea, children: [jsx("div", { className: styles$j.hueBar, ref: hueBarRef, onClick: handleHueBarClick, children: jsx("div", { className: styles$j.hueBarSlider, style: { top: `${(360 - hsv.h) / 360 * 100}%` } }) }), jsxs("div", { className: styles$j.colorArea, ref: colorAreaRef, onClick: handleColorAreaClick, children: [jsxs("div", { className: styles$j.colorAreaOverlay, children: [jsx("div", { className: styles$j.hueBackground, style: { backgroundColor: hueHex } }), jsx("div", { className: styles$j.whiteGradient }), jsx("div", { className: styles$j.blackGradient })] }), jsx("div", { className: styles$j.colorAreaCursor, style: {
|
|
3330
3297
|
left: `${hsv.s}%`,
|
|
3331
3298
|
top: `${100 - hsv.v}%`
|
|
3332
3299
|
} })] })] })] }));
|
|
3333
3300
|
};
|
|
3334
3301
|
|
|
3335
|
-
var styles$
|
|
3302
|
+
var styles$i = {"container":"cw-input-color-module__container__x7gpk","selectColor":"cw-input-color-module__selectColor__DTo3V","disabled":"cw-input-color-module__disabled__O1fK5","readOnly":"cw-input-color-module__readOnly__HL-Bz","colorDropdown":"cw-input-color-module__colorDropdown__pX2bc"};
|
|
3336
3303
|
|
|
3337
3304
|
const CwInputColor = ({ value, onChange, previewText = "Color preview", disabled = false, readOnly = false, width = '4rem', height = '2rem', labelProps, layoutProps, }) => {
|
|
3338
3305
|
const [isOpen, setIsOpen] = useState(false);
|
|
@@ -3465,11 +3432,11 @@ const CwInputColor = ({ value, onChange, previewText = "Color preview", disabled
|
|
|
3465
3432
|
break;
|
|
3466
3433
|
}
|
|
3467
3434
|
};
|
|
3468
|
-
return (jsxs("div", { className: `cw-input-color ${styles$
|
|
3435
|
+
return (jsxs("div", { className: `cw-input-color ${styles$i.container}`, "data-direction": layoutProps?.direction ?? "row", "data-align": layoutProps?.align, children: [labelProps && (jsx(CwLabel, { ...labelProps })), jsx("div", { ref: containerRef, onClick: handleToggle, className: `${styles$i.selectColor} ${disabled ? styles$i.disabled : ''} ${readOnly ? styles$i.readOnly : ''}`, style: {
|
|
3469
3436
|
width,
|
|
3470
3437
|
height,
|
|
3471
3438
|
backgroundColor: value,
|
|
3472
|
-
}, "aria-label": "Open color picker", "aria-expanded": isOpen, "aria-haspopup": "dialog", "aria-readonly": readOnly, role: "button", tabIndex: disabled ? -1 : 0, onKeyDown: handleKeyDown }), isOpen && createPortal(jsx("div", { ref: dropdownRef, className: styles$
|
|
3439
|
+
}, "aria-label": "Open color picker", "aria-expanded": isOpen, "aria-haspopup": "dialog", "aria-readonly": readOnly, role: "button", tabIndex: disabled ? -1 : 0, onKeyDown: handleKeyDown }), isOpen && createPortal(jsx("div", { ref: dropdownRef, className: styles$i.colorDropdown, style: dropdownStyle, role: "dialog", "aria-modal": "true", "aria-label": "Color picker", children: jsx(CwColorPicker, { initialColor: value, onChange: handleColorChange, previewText: previewText }) }), document.body)] }));
|
|
3473
3440
|
};
|
|
3474
3441
|
|
|
3475
3442
|
/**
|
|
@@ -3719,31 +3686,63 @@ function CwInputDateText(props) {
|
|
|
3719
3686
|
return (jsx("div", { className: "cw-input-date-text", children: jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxs(CwLabel, { ...labelProps, children: [iconProps && jsx(CwIcon, { ...iconProps }), labelProps.text] })), jsxs("div", { children: [jsx("input", { type: "text", disabled: disabled, maxLength: 10, onChange: onChangeInputText, pattern: "^$ --|[.0-9\\/\\-]{10}", placeholder: format.toLowerCase(), readOnly: readOnly, ref: textInputRef, required: required, size: width, tabIndex: tabIndex, value: displayedDate }), jsxs("span", { children: [jsx(CwIcon, { iconId: "calendar" }), jsx("input", { type: "date", disabled: disabled, onChange: onChangeInputDate, readOnly: readOnly, ref: dateInputRef, tabIndex: -1, value: date, ...inputProps })] })] }), buttonProps && jsx(CwButton, { ...buttonProps })] }) }));
|
|
3720
3687
|
}
|
|
3721
3688
|
|
|
3722
|
-
var styles$
|
|
3689
|
+
var styles$h = {"hiddenInput":"cw-input-image-module__hiddenInput__pS7hb","dropZone":"cw-input-image-module__dropZone__ygrGu","title":"cw-input-image-module__title__Rji5M","subtitle":"cw-input-image-module__subtitle__djYYu","container":"cw-input-image-module__container__qh7Tm"};
|
|
3723
3690
|
|
|
3691
|
+
const DEFAULT_LABELS = {
|
|
3692
|
+
dropImageHere: "Drop image here",
|
|
3693
|
+
paste: "Paste",
|
|
3694
|
+
browse: "Browse",
|
|
3695
|
+
acceptedFormats: (formats) => `(${formats})`,
|
|
3696
|
+
clipboardError: "Failed to read from clipboard. Ensure the app has permission to access the clipboard.",
|
|
3697
|
+
invalidType: (formats) => `Unsupported file type. Allowed: ${formats}`,
|
|
3698
|
+
readError: "Could not read the image file.",
|
|
3699
|
+
};
|
|
3700
|
+
/** Reads a file/blob into a base64 data URL (persistable, no blob URL to revoke). */
|
|
3701
|
+
function readImageFileAsDataUrl(file) {
|
|
3702
|
+
return new Promise((resolve, reject) => {
|
|
3703
|
+
const reader = new FileReader();
|
|
3704
|
+
reader.onload = () => resolve(reader.result);
|
|
3705
|
+
reader.onerror = () => reject(reader.error ?? new Error("Failed to read file"));
|
|
3706
|
+
reader.readAsDataURL(file);
|
|
3707
|
+
});
|
|
3708
|
+
}
|
|
3724
3709
|
function CwInputImage(props) {
|
|
3725
3710
|
const [_uploadedImage, setUploadedImage] = useState(null);
|
|
3726
3711
|
const inputRef = useRef(null);
|
|
3727
|
-
const { allowedImageFormats, onChange, ...inputProps } = props;
|
|
3712
|
+
const { allowedImageFormats, onChange, onError, labels: labelsProp, size, ...inputProps } = props;
|
|
3728
3713
|
const allowedFormats = allowedImageFormats || ["image/jpeg", "image/png", "image/gif"];
|
|
3714
|
+
const labels = { ...DEFAULT_LABELS, ...labelsProp };
|
|
3729
3715
|
const isValidFileType = (type) => allowedFormats.includes(type);
|
|
3730
|
-
const
|
|
3731
|
-
if (
|
|
3732
|
-
|
|
3733
|
-
|
|
3734
|
-
|
|
3735
|
-
|
|
3716
|
+
const reportError = (message) => {
|
|
3717
|
+
if (onError)
|
|
3718
|
+
onError(message);
|
|
3719
|
+
else
|
|
3720
|
+
CwDisplayMessage(message, CwMessageType.ERROR);
|
|
3721
|
+
};
|
|
3722
|
+
const handleFile = async (file) => {
|
|
3723
|
+
if (!file) {
|
|
3724
|
+
onChange?.(null);
|
|
3725
|
+
return;
|
|
3736
3726
|
}
|
|
3737
|
-
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
|
-
|
|
3727
|
+
if (!isValidFileType(file.type)) {
|
|
3728
|
+
reportError(labels.invalidType(allowedFormats.join(", ").replace(/image\//g, "")));
|
|
3729
|
+
onChange?.(null);
|
|
3730
|
+
return;
|
|
3731
|
+
}
|
|
3732
|
+
try {
|
|
3733
|
+
const dataUrl = await readImageFileAsDataUrl(file);
|
|
3734
|
+
setUploadedImage(dataUrl);
|
|
3735
|
+
onChange?.(dataUrl, file);
|
|
3736
|
+
}
|
|
3737
|
+
catch {
|
|
3738
|
+
reportError(labels.readError);
|
|
3739
|
+
onChange?.(null);
|
|
3741
3740
|
}
|
|
3742
3741
|
};
|
|
3743
3742
|
const handleDrop = (e) => {
|
|
3744
3743
|
e.preventDefault();
|
|
3745
3744
|
const file = e.dataTransfer.files[0];
|
|
3746
|
-
handleFile(file);
|
|
3745
|
+
void handleFile(file ?? null);
|
|
3747
3746
|
};
|
|
3748
3747
|
const onPasteButtonClick = async () => {
|
|
3749
3748
|
try {
|
|
@@ -3753,21 +3752,20 @@ function CwInputImage(props) {
|
|
|
3753
3752
|
for (const type of clipboardItem.types) {
|
|
3754
3753
|
if (type.startsWith("image/")) {
|
|
3755
3754
|
const blob = await clipboardItem.getType(type);
|
|
3756
|
-
handleFile(blob);
|
|
3755
|
+
await handleFile(blob);
|
|
3757
3756
|
}
|
|
3758
3757
|
}
|
|
3759
3758
|
}
|
|
3760
3759
|
}
|
|
3761
|
-
catch
|
|
3762
|
-
|
|
3763
|
-
alert("Failed to read from clipboard. Ensure the app has permission to access clipboard.");
|
|
3760
|
+
catch {
|
|
3761
|
+
reportError(labels.clipboardError);
|
|
3764
3762
|
}
|
|
3765
3763
|
};
|
|
3766
3764
|
const handleFileChange = (e) => {
|
|
3767
|
-
const file = e.
|
|
3768
|
-
handleFile(file ?? null);
|
|
3765
|
+
const file = e.currentTarget.files?.[0];
|
|
3766
|
+
void handleFile(file ?? null);
|
|
3769
3767
|
};
|
|
3770
|
-
return (jsxs("div", { className:
|
|
3768
|
+
return (jsxs("div", { className: `cw-input-image ${styles$h.container}`, "data-size": size, children: [jsxs("div", { onDragOver: (e) => e.preventDefault(), onDrop: handleDrop, className: styles$h.dropZone, children: [jsx(CwIcon, { iconId: "upload" }), jsxs("div", { className: "cw-flex-column cw-gap-tiny", children: [jsx("p", { className: styles$h.title, children: labels.dropImageHere }), jsx("p", { className: styles$h.subtitle, children: labels.acceptedFormats(allowedFormats.join(", ").replace(/image\//g, "")) })] })] }), jsxs("div", { className: "cw-flex-row cw-align-center-center cw-gap-small", children: [jsx(CwButton, { onClick: onPasteButtonClick, icon: "paste", text: labels.paste, size: size }), jsx(CwButton, { onClick: () => inputRef.current?.click(), icon: "folder-open", text: labels.browse, size: size })] }), jsx("input", { ref: inputRef, type: "file", accept: allowedFormats.join(","), onChange: handleFileChange, className: styles$h.hiddenInput, ...inputProps })] }));
|
|
3771
3769
|
}
|
|
3772
3770
|
|
|
3773
3771
|
/**
|
|
@@ -3899,7 +3897,7 @@ const CwImageArea = forwardRef((props, ref) => {
|
|
|
3899
3897
|
});
|
|
3900
3898
|
CwImageArea.displayName = "CwImageArea";
|
|
3901
3899
|
|
|
3902
|
-
var styles$
|
|
3900
|
+
var styles$g = {"cw-weekday-selector":"cw-weekday-selector-module__cw-weekday-selector__Iz4GZ"};
|
|
3903
3901
|
|
|
3904
3902
|
/**
|
|
3905
3903
|
* This class represents a week where days can be selected or unselected
|
|
@@ -4039,16 +4037,16 @@ const CwWeekdaySelector = ({ value = "", onChange, disabled = false }) => {
|
|
|
4039
4037
|
setSelectedDays(newWeekdays);
|
|
4040
4038
|
onChange?.(newWeekdays.toString());
|
|
4041
4039
|
};
|
|
4042
|
-
return (jsx("div", { className: styles$
|
|
4040
|
+
return (jsx("div", { className: styles$g["cw-weekday-selector"], children: Weekdays.getFullWeek().map(day => (jsx("input", { type: "checkbox", "data-day": day, checked: selectedDays.toArray().includes(day), onChange: (e) => handleChange(day, e.target.checked), disabled: disabled }, day))) }));
|
|
4043
4041
|
};
|
|
4044
4042
|
|
|
4045
|
-
var styles$
|
|
4043
|
+
var styles$f = {"check-container":"cw-check-module__check-container__4nscZ","group":"cw-check-module__group__6JCQo","options":"cw-check-module__options__-g9LF"};
|
|
4046
4044
|
|
|
4047
4045
|
function CwCheck(props) {
|
|
4048
4046
|
const { labelProps, labelText, direction, alignment, className, ...inputProps } = props;
|
|
4049
4047
|
const resolvedDirection = direction ?? alignment ?? "row";
|
|
4050
4048
|
const displayText = labelProps?.text ?? labelText;
|
|
4051
|
-
return (jsx("div", { className: `cw-check ${styles$
|
|
4049
|
+
return (jsx("div", { className: `cw-check ${styles$f["check-container"]}${className ? ` ${className}` : ''}`, children: jsxs("label", { "data-direction": resolvedDirection, children: [jsx("input", { type: "checkbox", ...inputProps }), displayText && (jsx("span", { className: "cw-icon-text", children: displayText }))] }) }));
|
|
4052
4050
|
}
|
|
4053
4051
|
|
|
4054
4052
|
function CwCheckbox(CwCheckboxProps) {
|
|
@@ -4099,14 +4097,14 @@ function CwCheckboxGroup({ options, value = [], onChange, labelProps, groupLayou
|
|
|
4099
4097
|
?? (optionsAlignment === "column" ? "row" : "column");
|
|
4100
4098
|
// Each checkbox's box-to-text layout is the opposite of the options flow, mirroring CwRadioGroup.
|
|
4101
4099
|
const checkDirection = itemDirection === "row" ? "column" : "row";
|
|
4102
|
-
return (jsxs("div", { className: `cw-checkbox-group ${styles$
|
|
4100
|
+
return (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 && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), 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) => (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) => (jsx("p", { className: "cw-input-info", "data-color": feedbackItem.type, children: feedbackItem.message }, index)))] }));
|
|
4103
4101
|
}
|
|
4104
4102
|
|
|
4105
|
-
var styles$
|
|
4103
|
+
var styles$e = {"radio":"cw-radio-module__radio__5sh7a","group":"cw-radio-module__group__br-HM","options":"cw-radio-module__options__LSw7M"};
|
|
4106
4104
|
|
|
4107
4105
|
/** Single native radio input. Building block for CwRadioGroup. */
|
|
4108
4106
|
function CwRadio({ label, direction = "row", className, ...inputProps }) {
|
|
4109
|
-
return (jsxs("label", { className: `cw-radio ${styles$
|
|
4107
|
+
return (jsxs("label", { className: `cw-radio ${styles$e.radio}${className ? ` ${className}` : ""}`, "data-direction": direction, children: [jsx("input", { type: "radio", ...inputProps }), label && jsx("span", { children: label })] }));
|
|
4110
4108
|
}
|
|
4111
4109
|
|
|
4112
4110
|
/**
|
|
@@ -4130,7 +4128,7 @@ function CwRadioGroup({ options, value, onChange, labelProps, groupLayout, itemL
|
|
|
4130
4128
|
// (itemLayout column) reads best with the circle beside the text; a side-by-side row reads
|
|
4131
4129
|
// best with the circle above the text.
|
|
4132
4130
|
const radioDirection = itemLayout?.direction === "row" ? "column" : "row";
|
|
4133
|
-
return (jsxs("div", { className: `cw-radio-group ${styles$
|
|
4131
|
+
return (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 && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), 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) => (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) => (jsx("p", { className: "cw-input-info", "data-color": feedbackItem.type, children: feedbackItem.message }, index)))] }));
|
|
4134
4132
|
}
|
|
4135
4133
|
|
|
4136
4134
|
function CwToggle(props) {
|
|
@@ -4396,7 +4394,7 @@ function CwDropdownFilter(props) {
|
|
|
4396
4394
|
return (jsxs("div", { id: props.IdContent, className: containerClassName, children: [props.children, isVisible && (jsx("nav", { className: "cw-dropdown-menu", style: inlineStyles, onMouseLeave: props.onMouseLeave, id: props.idDropDownFilter, role: "menu", children: jsx("ul", { role: "none", children: props.DataSourceDropDownItem?.map((item) => (jsx("li", { id: item.IdDropDown_filter, role: "menuitem", children: item.dropDownFilter_desc }, item.IdDropDown_filter))) }) }))] }));
|
|
4397
4395
|
}
|
|
4398
4396
|
|
|
4399
|
-
var styles$
|
|
4397
|
+
var styles$d = {"container":"cw-popover-button-module__container__YSWQU","panel":"cw-popover-button-module__panel__C-BTn"};
|
|
4400
4398
|
|
|
4401
4399
|
/**
|
|
4402
4400
|
* Button that toggles a floating panel with arbitrary children.
|
|
@@ -4475,7 +4473,7 @@ function CwPopoverButton({ children, panelWidth = "auto", placement = "bottom-st
|
|
|
4475
4473
|
}
|
|
4476
4474
|
panel.showPopover();
|
|
4477
4475
|
}, [placement]);
|
|
4478
|
-
return (jsxs("div", { ref: containerRef, className: styles$
|
|
4476
|
+
return (jsxs("div", { ref: containerRef, className: styles$d.container, children: [jsx(CwButton, { ...buttonProps, onClick: handleClick }), jsx("div", { ref: panelCallbackRef, className: `${styles$d.panel}${panelClassName ? ` ${panelClassName}` : ""}`, style: { width: panelWidth }, children: children })] }));
|
|
4479
4477
|
}
|
|
4480
4478
|
|
|
4481
4479
|
function itemsToMultiFilterTags(items, nameKey, valueKey, category, primaryColor, onPrimaryColor) {
|
|
@@ -4493,13 +4491,13 @@ function itemsToMultiFilterTags(items, nameKey, valueKey, category, primaryColor
|
|
|
4493
4491
|
return result;
|
|
4494
4492
|
}
|
|
4495
4493
|
|
|
4496
|
-
var styles$
|
|
4494
|
+
var styles$c = {"cw-multifilter-tag":"cw-multi-filter-tag-module__cw-multifilter-tag__Epda-"};
|
|
4497
4495
|
|
|
4498
4496
|
const CwMultiFilterTag = props => {
|
|
4499
4497
|
const { ID, Name, Value, Category, Removable, PrimaryColor, Selectable, Selected } = props;
|
|
4500
4498
|
const backgroundColor = `rgb(${PrimaryColor.r},${PrimaryColor.g},${PrimaryColor.b})`;
|
|
4501
4499
|
const isOutlineMode = Selected && !Removable;
|
|
4502
|
-
return (jsx("li", { className: styles$
|
|
4500
|
+
return (jsx("li", { className: styles$c["cw-multifilter-tag"], id: ID, "data-value": Value, "data-category": Category, "data-selected": !!Selected, title: props.tooltip ?? Name, onClick: () => {
|
|
4503
4501
|
if (Selectable)
|
|
4504
4502
|
props.OnSelect?.(props);
|
|
4505
4503
|
}, children: jsx(CwChip, { label: Name, colorScheme: "custom", customColor: backgroundColor, variant: isOutlineMode ? "outline" : "soft", closable: Removable, onClose: () => props.OnRemove?.(props),
|
|
@@ -4509,7 +4507,7 @@ const CwMultiFilterTag = props => {
|
|
|
4509
4507
|
} : undefined }) }));
|
|
4510
4508
|
};
|
|
4511
4509
|
|
|
4512
|
-
var styles$
|
|
4510
|
+
var styles$b = {"cw-multi-filter-catalog-container":"cw-multi-filter-module__cw-multi-filter-catalog-container__S3nsq","cw-multi-filter":"cw-multi-filter-module__cw-multi-filter__zipBK","category-selected":"cw-multi-filter-module__category-selected__eYbes","cw-multi-filter-search":"cw-multi-filter-module__cw-multi-filter-search__eyHr0 cw-choice-input-box-module__inputBox__gHY9d"};
|
|
4513
4511
|
|
|
4514
4512
|
/**
|
|
4515
4513
|
* A multiple filter selector, a MULTI-SELECT even. Allows users to select and filter items based on tags.
|
|
@@ -4736,9 +4734,9 @@ const CwMultiFilter = ({ allTags, id, onChangeSelectedTags, selectedTags, placeh
|
|
|
4736
4734
|
inputRef.current?.focus();
|
|
4737
4735
|
}
|
|
4738
4736
|
};
|
|
4739
|
-
return (jsxs("form", { ref: componentRef, id: id, className: `${styles$
|
|
4737
|
+
return (jsxs("form", { ref: componentRef, id: id, className: `${styles$b["cw-multi-filter"]}${className ? ` ${className}` : ""}`, style: style, onSubmit: (e) => {
|
|
4740
4738
|
e.preventDefault();
|
|
4741
|
-
}, children: [jsxs("div", { onClick: handleDivClick, ref: wrapperRef, className: styles$
|
|
4739
|
+
}, children: [jsxs("div", { onClick: handleDivClick, ref: wrapperRef, className: styles$b["cw-multi-filter-search"], style: isPanelOpen ? { outline: "1px solid var(--cw-color-outline-variant)" } : {}, children: [jsxs("ul", { id: id + "_selected_filters", children: [Array.from(selectedTags).map(tag => (createElement(CwMultiFilterTag, { ...tag, key: tag.ID, Selectable: false, Removable: true, OnRemove: () => removeTag(tag.ID) }))), 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 => {
|
|
4742
4740
|
switch (e.key) {
|
|
4743
4741
|
case "Enter":
|
|
4744
4742
|
case "Tab": {
|
|
@@ -4765,7 +4763,7 @@ const CwMultiFilter = ({ allTags, id, onChangeSelectedTags, selectedTags, placeh
|
|
|
4765
4763
|
break;
|
|
4766
4764
|
}
|
|
4767
4765
|
}
|
|
4768
|
-
} })] }), selectedTags.size > 0 && (jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onMouseDown: e => e.preventDefault(), onClick: (e) => { e.stopPropagation(); onChangeSelectedTags(new Set()); setIsPanelOpen(false); }, tabIndex: -1, "aria-label": "Clear all" }))] }), renderPanel(jsxs("section", { ref: panelRef, className: styles$
|
|
4766
|
+
} })] }), selectedTags.size > 0 && (jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onMouseDown: e => e.preventDefault(), onClick: (e) => { e.stopPropagation(); onChangeSelectedTags(new Set()); setIsPanelOpen(false); }, tabIndex: -1, "aria-label": "Clear all" }))] }), renderPanel(jsxs("section", { ref: panelRef, className: styles$b["cw-multi-filter-catalog-container"], style: panelStyle, children: [jsxs("nav", { children: [jsx("button", { className: selectedCategory === "All" ? styles$b["category-selected"] : undefined, onClick: () => handleClickCategory("All"), children: allCategoriesLabel }), Array.from(categoriesMappedToTags().keys()).map(category => (jsx("button", { className: selectedCategory === category ? styles$b["category-selected"] : undefined, style: {
|
|
4769
4767
|
backgroundColor: getColor(category).primary,
|
|
4770
4768
|
color: getColor(category).onPrimary,
|
|
4771
4769
|
}, onClick: () => handleClickCategory(category), children: category }, category)))] }), jsx("ul", { children: displayTags
|
|
@@ -4791,7 +4789,7 @@ const CwMultiFilter = ({ allTags, id, onChangeSelectedTags, selectedTags, placeh
|
|
|
4791
4789
|
} }, props.ID))) })] }))] }));
|
|
4792
4790
|
};
|
|
4793
4791
|
|
|
4794
|
-
var styles$
|
|
4792
|
+
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"};
|
|
4795
4793
|
|
|
4796
4794
|
/**
|
|
4797
4795
|
* Multi-select input with chip tags and searchable dropdown.
|
|
@@ -4926,11 +4924,11 @@ function CwTagSelector({ id, options, value, onChange, labelProps, iconProps, al
|
|
|
4926
4924
|
// Keeping containerRef for any other potential use
|
|
4927
4925
|
const direction = alignProps?.flexDirection ?? "row";
|
|
4928
4926
|
const feedbackMessages = feedback ? (Array.isArray(feedback) ? feedback : [feedback]) : [];
|
|
4929
|
-
return (jsxs("div", { ref: containerRef, className: `${styles$
|
|
4930
|
-
inputRef.current?.focus(); }, children: [selectedOptions.map(opt => (jsx(CwChip, { label: opt.label, colorScheme: opt.color ? "custom" : "info", customColor: opt.color, closable: !disabled, onClose: () => handleRemove(opt.value) }, opt.value))), jsx("input", { ref: inputRef, type: "text", value: search, onChange: handleInputChange, onFocus: handleInputFocus, onKeyDown: handleKeyDown, placeholder: selectedOptions.length === 0 ? placeholder : "", disabled: disabled, autoComplete: "off" }), value.length > 0 && !disabled && (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) => (jsx("p", { className: "cw-input-info", "data-color": fb.type, children: fb.message }, i))), renderPanel((showSelectAll || filtered.length > 0) ? (jsxs("div", { ref: panelRef, className: styles$
|
|
4927
|
+
return (jsxs("div", { ref: containerRef, className: `${styles$a.container}${className ? ` ${className}` : ""}`, style: style, id: id, "data-direction": direction, children: [jsxs(CwAlign, { ...alignProps, children: [labelProps && (jsxs(CwLabel, { ...labelProps, children: [iconProps && jsx(CwIcon, { ...iconProps }), labelProps.text] })), jsxs("div", { className: `${styles$a.inputBox}${disabled ? ` ${styles$a.disabled}` : ""}`, ref: inputBoxRef, onClick: () => { if (!disabled)
|
|
4928
|
+
inputRef.current?.focus(); }, children: [selectedOptions.map(opt => (jsx(CwChip, { label: opt.label, colorScheme: opt.color ? "custom" : "info", customColor: opt.color, closable: !disabled, onClose: () => handleRemove(opt.value) }, opt.value))), jsx("input", { ref: inputRef, type: "text", value: search, onChange: handleInputChange, onFocus: handleInputFocus, onKeyDown: handleKeyDown, placeholder: selectedOptions.length === 0 ? placeholder : "", disabled: disabled, autoComplete: "off" }), value.length > 0 && !disabled && (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) => (jsx("p", { className: "cw-input-info", "data-color": fb.type, children: fb.message }, i))), renderPanel((showSelectAll || filtered.length > 0) ? (jsxs("div", { ref: panelRef, className: styles$a.dropdown, style: panelStyle, children: [showSelectAll && !search && (jsxs("div", { className: styles$a.selectAll, onMouseDown: (e) => e.preventDefault(), onClick: handleToggleAll, children: [jsx("input", { type: "checkbox", checked: allSelected, readOnly: true, tabIndex: -1 }), allSelected ? "Deselect all" : "Select all"] })), jsx("ul", { ref: listRef, children: filtered.map((opt, idx) => (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 && jsx("span", { className: styles$a.optionDot, style: { backgroundColor: opt.color } }), opt.label] }, opt.value))) })] })) : null)] }));
|
|
4931
4929
|
}
|
|
4932
4930
|
|
|
4933
|
-
var styles$
|
|
4931
|
+
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"};
|
|
4934
4932
|
|
|
4935
4933
|
function CwTreeView({ data, onSelect, allowParentSelection = false, selectedId: initialSelectedId = null }) {
|
|
4936
4934
|
const [expanded, setExpanded] = useState(new Set());
|
|
@@ -4997,10 +4995,10 @@ function CwTreeView({ data, onSelect, allowParentSelection = false, selectedId:
|
|
|
4997
4995
|
const isLeaf = !hasChildren;
|
|
4998
4996
|
const isSelected = selectedId?.toString().toLowerCase() === node.id.toString().toLowerCase();
|
|
4999
4997
|
const selectable = allowParentSelection || isLeaf;
|
|
5000
|
-
return (jsxs("div", { className: styles$
|
|
5001
|
-
styles$
|
|
5002
|
-
isSelected && styles$
|
|
5003
|
-
!selectable && styles$
|
|
4998
|
+
return (jsxs("div", { className: styles$9["tree-item"], children: [jsxs("div", { className: [
|
|
4999
|
+
styles$9["tree-node"],
|
|
5000
|
+
isSelected && styles$9["selected"],
|
|
5001
|
+
!selectable && styles$9["non-selectable"]
|
|
5004
5002
|
].filter(Boolean).join(' '), style: { paddingLeft: `${depth * 24 + 8}px` }, onClick: () => {
|
|
5005
5003
|
if (selectable) {
|
|
5006
5004
|
setSelectedId(node.id);
|
|
@@ -5009,7 +5007,7 @@ function CwTreeView({ data, onSelect, allowParentSelection = false, selectedId:
|
|
|
5009
5007
|
else {
|
|
5010
5008
|
toggleExpand(node.id);
|
|
5011
5009
|
}
|
|
5012
|
-
}, children: [hasChildren && (jsx(CwIcon, { size: "large", iconId: isExpanded ? "chevron-down" : "chevron-right" })), jsx("div", { className: `${styles$
|
|
5010
|
+
}, children: [hasChildren && (jsx(CwIcon, { size: "large", iconId: isExpanded ? "chevron-down" : "chevron-right" })), jsx("div", { className: `${styles$9["tree-label"]} ${!hasChildren ? styles$9["tree-spacer"] : ''}`, children: node.label })] }), hasChildren && isExpanded && (jsx("div", { className: styles$9["tree-children"], children: node.children.map((child) => renderNode(child, depth + 1)) }))] }, node.id));
|
|
5013
5011
|
};
|
|
5014
5012
|
// Function to search for nodes that match the search term
|
|
5015
5013
|
const searchInTree = (nodes, searchTerm) => {
|
|
@@ -5033,7 +5031,129 @@ function CwTreeView({ data, onSelect, allowParentSelection = false, selectedId:
|
|
|
5033
5031
|
return results;
|
|
5034
5032
|
};
|
|
5035
5033
|
const filteredData = searchInTree(data, search);
|
|
5036
|
-
return (jsxs("div", { className: `cw-tree-view ${styles$
|
|
5034
|
+
return (jsxs("div", { className: `cw-tree-view ${styles$9["tree-container"]}`, children: [jsxs("header", { children: [jsx("input", { type: "text", placeholder: "Search in tree...", value: search, onChange: (e) => setSearch(e.target.value) }), search && (jsx(CwButton, { onClick: () => setSearch(""), type: "button", icon: "close", variant: "icon", color: "neutral" }))] }), jsx("div", { className: styles$9["tree-wrapper"], children: filteredData.length > 0 ? (filteredData.map((node) => renderNode(node))) : (jsxs("div", { className: styles$9["empty-state"], children: [jsx(CwIcon, { iconId: "comment" }), search ? "No results found" : "There are no items"] })) })] }));
|
|
5035
|
+
}
|
|
5036
|
+
|
|
5037
|
+
const EXACT_PHRASE = /"([^"]+)"/g;
|
|
5038
|
+
/**
|
|
5039
|
+
* Quoted phrases are matched against the label only; loose words against label + description + href.
|
|
5040
|
+
* Parsed once instead of per node.
|
|
5041
|
+
*/
|
|
5042
|
+
function parseSearch(search) {
|
|
5043
|
+
const phrases = Array.from(search.matchAll(EXACT_PHRASE), match => match[1].toLowerCase());
|
|
5044
|
+
const words = search
|
|
5045
|
+
.replace(EXACT_PHRASE, "")
|
|
5046
|
+
.trim()
|
|
5047
|
+
.toLowerCase()
|
|
5048
|
+
.split(/\s+/)
|
|
5049
|
+
.filter(Boolean);
|
|
5050
|
+
return { phrases, words };
|
|
5051
|
+
}
|
|
5052
|
+
/**
|
|
5053
|
+
* Filters a nav tree by a search string, keeping a group whose descendants match.
|
|
5054
|
+
*
|
|
5055
|
+
* Supports `"quoted phrases"` (must appear in the label) alongside loose words (any field) — this is
|
|
5056
|
+
* behaviour users are told about, so don't simplify it.
|
|
5057
|
+
*/
|
|
5058
|
+
function filterNavItems(items, search) {
|
|
5059
|
+
if (!search?.trim())
|
|
5060
|
+
return items;
|
|
5061
|
+
const { phrases, words } = parseSearch(search);
|
|
5062
|
+
if (phrases.length === 0 && words.length === 0)
|
|
5063
|
+
return items;
|
|
5064
|
+
const keep = (item, parentMatchedPhrases) => {
|
|
5065
|
+
const label = item.label.toLowerCase();
|
|
5066
|
+
const haystack = [item.label, item.description, item.href].filter(Boolean).join(" ").toLowerCase();
|
|
5067
|
+
const matchesPhrases = phrases.every(phrase => label.includes(phrase));
|
|
5068
|
+
const matchesWords = words.every(word => haystack.includes(word));
|
|
5069
|
+
const selfMatches = (phrases.length === 0 || matchesPhrases || parentMatchedPhrases) && matchesWords;
|
|
5070
|
+
if (!item.children?.length)
|
|
5071
|
+
return selfMatches ? item : null;
|
|
5072
|
+
let children = item.children
|
|
5073
|
+
.map(child => keep(child, matchesPhrases || parentMatchedPhrases))
|
|
5074
|
+
.filter((child) => child !== null);
|
|
5075
|
+
// A phrase-only search narrows the survivors further: each must carry the phrase itself.
|
|
5076
|
+
if (phrases.length > 0 && words.length === 0 && matchesPhrases) {
|
|
5077
|
+
children = children.filter(child => phrases.every(phrase => child.label.toLowerCase().includes(phrase)));
|
|
5078
|
+
}
|
|
5079
|
+
if (children.length > 0)
|
|
5080
|
+
return { ...item, children };
|
|
5081
|
+
// The group matched but nothing under it did. Returning `children: []` would make it a leaf —
|
|
5082
|
+
// and a leaf with no href — so keep the subtree instead of emptying it.
|
|
5083
|
+
return selfMatches ? item : null;
|
|
5084
|
+
};
|
|
5085
|
+
return items
|
|
5086
|
+
.map(item => keep(item, false))
|
|
5087
|
+
.filter((item) => item !== null);
|
|
5088
|
+
}
|
|
5089
|
+
|
|
5090
|
+
/**
|
|
5091
|
+
* Sorts the top level alphabetically, leaving every nested list in the order the consumer gave.
|
|
5092
|
+
*
|
|
5093
|
+
* Deliberately level 1 only: this exists because a long list of modules is hard to scan, while the
|
|
5094
|
+
* pages inside a module are ordered on purpose. Returns the input untouched when not sorting.
|
|
5095
|
+
*/
|
|
5096
|
+
function sortNavItems(items, alphabetically) {
|
|
5097
|
+
if (!alphabetically)
|
|
5098
|
+
return items;
|
|
5099
|
+
return [...items].sort((first, second) => first.label.localeCompare(second.label));
|
|
5100
|
+
}
|
|
5101
|
+
|
|
5102
|
+
var styles$8 = {"menu":"cw-nav-menu-module__menu__LmeQg","expandIndicator":"cw-nav-menu-module__expandIndicator__TBSdQ","favorites":"cw-nav-menu-module__favorites__Esaqd","favoritesContent":"cw-nav-menu-module__favoritesContent__l5DGG","favoriteStar":"cw-nav-menu-module__favoriteStar__J-jzg","emptyMessage":"cw-nav-menu-module__emptyMessage__-CQNd","skeleton":"cw-nav-menu-module__skeleton__INQqF"};
|
|
5103
|
+
|
|
5104
|
+
const SKELETON_ROW_COUNT = 5;
|
|
5105
|
+
const defaultRenderLink = (item, children) => (jsx("a", { href: item.href, children: children }));
|
|
5106
|
+
/** Sizes only its own icons — content injected via `renderLink` is styled by the consumer. */
|
|
5107
|
+
function CwNavMenu({ items, loading = false, isActive, renderLink = defaultRenderLink, showExpandIndicator = false, search, emptyMessage, sortAlphabetically = false, favoritesSlot, favoritesLabel = "Favorites", favoritesProps, isFavorite, beforeTreeSlot, className, ...navProps }) {
|
|
5108
|
+
const visibleItems = sortNavItems(filterNavItems(items, search), sortAlphabetically);
|
|
5109
|
+
const showEmptyMessage = !loading && Boolean(emptyMessage) && Boolean(search?.trim()) && visibleItems.length === 0;
|
|
5110
|
+
const hasActiveDescendant = (node) => node.children?.some(child => isActive?.(child) || hasActiveDescendant(child)) ?? false;
|
|
5111
|
+
const renderItem = (item, level) => {
|
|
5112
|
+
const children = item.children;
|
|
5113
|
+
if (children && children.length > 0) {
|
|
5114
|
+
return (jsx("li", { children: jsxs("details", { "data-level": level, open: hasActiveDescendant(item) || undefined, children: [jsxs("summary", { children: [item.icon && jsx(CwIcon, { iconId: item.icon, size: level >= 2 ? "small" : "medium" }), item.label, (showExpandIndicator || level >= 2) && (jsx(CwIcon, { iconId: "chevron-down", size: "small", className: styles$8.expandIndicator }))] }), jsx("ul", { children: children.map(child => renderItem(child, level + 1)) })] }) }, item.id));
|
|
5115
|
+
}
|
|
5116
|
+
return (jsx("li", { "data-active": isActive?.(item) ? "true" : undefined, children: renderLink(item, jsxs(Fragment, { children: [item.icon && jsx(CwIcon, { iconId: item.icon, size: "medium" }), item.label, isFavorite?.(item) && jsx(CwIcon, { iconId: "star", size: "small", className: styles$8.favoriteStar })] })) }, item.id));
|
|
5117
|
+
};
|
|
5118
|
+
return (jsxs("nav", { ...navProps, className: [styles$8.menu, className].filter(Boolean).join(" "), children: [favoritesSlot && (jsxs("details", { open: true, ...favoritesProps, className: [styles$8.favorites, favoritesProps?.className].filter(Boolean).join(" "), children: [jsxs("summary", { children: [jsx(CwIcon, { iconId: "star", size: "medium" }), favoritesLabel] }), jsx("div", { className: styles$8.favoritesContent, children: favoritesSlot })] })), beforeTreeSlot, jsx("ul", { children: loading
|
|
5119
|
+
? Array.from({ length: SKELETON_ROW_COUNT }, (_unused, index) => (jsx("li", { className: styles$8.skeleton }, index)))
|
|
5120
|
+
: visibleItems.map(item => renderItem(item, 1)) }), showEmptyMessage && jsx("p", { className: styles$8.emptyMessage, children: emptyMessage })] }));
|
|
5121
|
+
}
|
|
5122
|
+
|
|
5123
|
+
/**
|
|
5124
|
+
* Pure keyboard-navigation resolver shared by the `CwSearchInput` combobox.
|
|
5125
|
+
* Kept side-effect-free so the arrow/home/end/enter/escape behaviour can be unit
|
|
5126
|
+
* tested without a DOM (the library's vitest runs with `environment: "node"`).
|
|
5127
|
+
*/
|
|
5128
|
+
/**
|
|
5129
|
+
* Resolves a key press against the current highlight into a {@link SearchKeyAction}.
|
|
5130
|
+
* Arrow navigation wraps around; `Enter` selects only when a valid row is highlighted.
|
|
5131
|
+
*
|
|
5132
|
+
* @param key `KeyboardEvent.key` value.
|
|
5133
|
+
* @param currentIndex Currently highlighted option index (`-1` = none).
|
|
5134
|
+
* @param optionsLength Number of options currently in the dropdown.
|
|
5135
|
+
*/
|
|
5136
|
+
function resolveSearchKeyAction(key, currentIndex, optionsLength) {
|
|
5137
|
+
if (optionsLength <= 0)
|
|
5138
|
+
return { type: "none" };
|
|
5139
|
+
switch (key) {
|
|
5140
|
+
case "ArrowDown":
|
|
5141
|
+
return { type: "move", index: currentIndex < optionsLength - 1 ? currentIndex + 1 : 0 };
|
|
5142
|
+
case "ArrowUp":
|
|
5143
|
+
return { type: "move", index: currentIndex > 0 ? currentIndex - 1 : optionsLength - 1 };
|
|
5144
|
+
case "Home":
|
|
5145
|
+
return { type: "move", index: 0 };
|
|
5146
|
+
case "End":
|
|
5147
|
+
return { type: "move", index: optionsLength - 1 };
|
|
5148
|
+
case "Enter":
|
|
5149
|
+
return currentIndex >= 0 && currentIndex < optionsLength
|
|
5150
|
+
? { type: "select", index: currentIndex }
|
|
5151
|
+
: { type: "none" };
|
|
5152
|
+
case "Escape":
|
|
5153
|
+
return { type: "close" };
|
|
5154
|
+
default:
|
|
5155
|
+
return { type: "none" };
|
|
5156
|
+
}
|
|
5037
5157
|
}
|
|
5038
5158
|
|
|
5039
5159
|
/**
|
|
@@ -5054,14 +5174,19 @@ function CwSearchInput(optionsProps) {
|
|
|
5054
5174
|
const [_selectedOption, setSelectedOption] = useState(null);
|
|
5055
5175
|
const [showDropdown, setShowDropdown] = useState(false);
|
|
5056
5176
|
const [isLoading, setIsLoading] = useState(false);
|
|
5177
|
+
const [highlightedIndex, setHighlightedIndex] = useState(-1);
|
|
5057
5178
|
const wrapperRef = useRef(null);
|
|
5179
|
+
const inputRef = useRef(null);
|
|
5180
|
+
// Stable ids wiring the combobox input to its listbox popup for assistive tech.
|
|
5181
|
+
const listboxId = useId();
|
|
5182
|
+
const optionId = (index) => `${listboxId}-opt-${index}`;
|
|
5058
5183
|
const { panelRef, panelStyle, renderPanel } = useDropdownPortal({
|
|
5059
5184
|
anchorRef: wrapperRef,
|
|
5060
5185
|
isOpen: showDropdown && filteredOptions.length > 0,
|
|
5061
|
-
onClose: () => setShowDropdown(false),
|
|
5186
|
+
onClose: () => { setShowDropdown(false); setHighlightedIndex(-1); },
|
|
5062
5187
|
});
|
|
5063
5188
|
// Extract props
|
|
5064
|
-
const { labelProps, iconProps, alignProps, selectList, handleChange, placeholder = "Search…", disabled, renderOption, style, id, className, defaultValue, ...otherProps } = optionsProps;
|
|
5189
|
+
const { labelProps, iconProps, alignProps, selectList, handleChange, placeholder = "Search…", disabled, renderOption, style, id, className, defaultValue, autoFocus, ...otherProps } = optionsProps;
|
|
5065
5190
|
// Get direction for data attribute
|
|
5066
5191
|
const direction = alignProps?.flexDirection || "row";
|
|
5067
5192
|
// Make default value selection when loading the component
|
|
@@ -5080,9 +5205,10 @@ function CwSearchInput(optionsProps) {
|
|
|
5080
5205
|
}
|
|
5081
5206
|
}, [defaultValue, selectList]);
|
|
5082
5207
|
const handleInputChange = (event) => {
|
|
5083
|
-
const text = event.
|
|
5208
|
+
const text = event.currentTarget.value;
|
|
5084
5209
|
setSearchText(text);
|
|
5085
5210
|
setShowDropdown(true);
|
|
5211
|
+
setHighlightedIndex(-1);
|
|
5086
5212
|
if (text === "") {
|
|
5087
5213
|
setFilteredOptions(selectList);
|
|
5088
5214
|
setSelectedOption(null);
|
|
@@ -5105,10 +5231,30 @@ function CwSearchInput(optionsProps) {
|
|
|
5105
5231
|
};
|
|
5106
5232
|
const handleInputFocus = () => {
|
|
5107
5233
|
setShowDropdown(true);
|
|
5234
|
+
setHighlightedIndex(-1);
|
|
5108
5235
|
if (searchText === "") {
|
|
5109
5236
|
setFilteredOptions(selectList);
|
|
5110
5237
|
}
|
|
5111
5238
|
};
|
|
5239
|
+
const handleKeyDown = (event) => {
|
|
5240
|
+
if (!(showDropdown && filteredOptions.length > 0))
|
|
5241
|
+
return;
|
|
5242
|
+
const action = resolveSearchKeyAction(event.key, highlightedIndex, filteredOptions.length);
|
|
5243
|
+
switch (action.type) {
|
|
5244
|
+
case "move":
|
|
5245
|
+
event.preventDefault();
|
|
5246
|
+
setHighlightedIndex(action.index);
|
|
5247
|
+
break;
|
|
5248
|
+
case "select":
|
|
5249
|
+
event.preventDefault();
|
|
5250
|
+
handleOptionSelect(filteredOptions[action.index]);
|
|
5251
|
+
break;
|
|
5252
|
+
case "close":
|
|
5253
|
+
setShowDropdown(false);
|
|
5254
|
+
setHighlightedIndex(-1);
|
|
5255
|
+
break;
|
|
5256
|
+
}
|
|
5257
|
+
};
|
|
5112
5258
|
const handleInputBlur = () => {
|
|
5113
5259
|
// Dropdown is closed by useDropdownPortal's outside-click handler.
|
|
5114
5260
|
// Blur alone must not close it — clicking an option would lose focus before the click fires.
|
|
@@ -5120,16 +5266,19 @@ function CwSearchInput(optionsProps) {
|
|
|
5120
5266
|
handleChange(option.id);
|
|
5121
5267
|
}
|
|
5122
5268
|
setFilteredOptions([]);
|
|
5269
|
+
setHighlightedIndex(-1);
|
|
5123
5270
|
};
|
|
5124
5271
|
const handleClearClick = () => {
|
|
5125
5272
|
setSearchText("");
|
|
5126
5273
|
setFilteredOptions([]);
|
|
5127
5274
|
setSelectedOption(null);
|
|
5275
|
+
setHighlightedIndex(-1);
|
|
5128
5276
|
if (handleChange) {
|
|
5129
5277
|
handleChange("");
|
|
5130
5278
|
}
|
|
5279
|
+
inputRef.current?.focus();
|
|
5131
5280
|
};
|
|
5132
|
-
return (jsxs("div", { className: `cw-search-input ${className || ""}`, style: style,
|
|
5281
|
+
return (jsxs("div", { className: `cw-search-input ${className || ""}`, style: style, ...otherProps, "data-direction": direction, children: [jsxs(CwAlign, { ...alignProps, children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxs("div", { className: "cw-search-input-wrapper", ref: wrapperRef, children: [jsx("input", { ref: inputRef, id: id, type: "text", value: searchText, onChange: handleInputChange, onKeyDown: handleKeyDown, onFocus: handleInputFocus, onBlur: handleInputBlur, placeholder: placeholder, className: "cw-input-search", disabled: disabled, autoFocus: autoFocus, autoComplete: "off", role: "combobox", "aria-haspopup": "listbox", "aria-expanded": showDropdown && filteredOptions.length > 0, "aria-controls": listboxId, "aria-activedescendant": highlightedIndex >= 0 ? optionId(highlightedIndex) : undefined }), isLoading && (jsx("div", { className: "cw-search-input-loading", children: jsx(CwIcon, { iconId: "spinner" }) })), jsx("div", { className: "cw-search-input-icons", children: searchText && !disabled && !isLoading ? (jsx(CwButton, { type: "button", onClick: handleClearClick, "aria-label": "Clear search", variant: "icon", icon: "close", color: "neutral" })) : (iconProps ? jsx(CwIcon, { ...iconProps }) : jsx(CwIcon, { iconId: "search" })) })] })] }), renderPanel(jsx("div", { ref: panelRef, id: listboxId, className: dropdownStyles.dropdown, style: panelStyle, role: "listbox", children: jsx("ul", { children: filteredOptions.map((option, index) => (jsx("li", { id: optionId(index), className: `${dropdownStyles.option}${index === highlightedIndex ? ` ${dropdownStyles.optionFocused}` : ""}`, onClick: () => handleOptionSelect(option), onMouseDown: (e) => e.preventDefault(), onMouseEnter: () => setHighlightedIndex(index), role: "option", "aria-selected": index === highlightedIndex, children: renderOption ? renderOption(option) : option.description }, option.id))) }) }))] }));
|
|
5133
5282
|
}
|
|
5134
5283
|
|
|
5135
5284
|
/**
|
|
@@ -11292,4 +11441,4 @@ const CwFindCrewmember = ({ handleChange, placeHolder = "Search crew…", requir
|
|
|
11292
11441
|
}, "data-direction": direction, children: [jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxs("div", { className: "cw-search-input-wrapper", ref: wrapperRef, children: [jsx("input", { ref: inputRef, type: "text", value: inputValue, onChange: handleInputChange, onKeyDown: handleKeyDown, onFocus: handleInputFocus, placeholder: isInitialLoading ? "Loading…" : placeHolder, disabled: disabled, required: required, autoComplete: "off", "aria-expanded": showDropdown, "aria-haspopup": "listbox", role: "combobox", title: tooltipText }), (isLoading || isInitialLoading) && (jsx("div", { className: "cw-search-input-loading", children: jsx(CwIcon, { iconId: "spinner" }) })), jsx("div", { className: "cw-search-input-icons", children: inputValue && !disabled && !isInitialLoading ? (jsx(CwButton, { type: "button", onClick: handleClear, "aria-label": "Clear selected crewmember", variant: "icon", icon: "close", color: "neutral" })) : (jsx(CwIcon, { iconId: "person" })) })] })] }), renderPanel(jsx("div", { ref: panelRef, className: dropdownStyles.dropdown, style: panelStyle, role: "listbox", children: jsx("ul", { children: options.map((option, index) => (jsx("li", { className: `${dropdownStyles.option}${index === highlightedIndex ? ` ${dropdownStyles.optionFocused}` : ""}`, onClick: () => handleOptionSelect(option.value), onMouseDown: (e) => e.preventDefault(), onMouseEnter: () => setHighlightedIndex(index), role: "option", "aria-selected": index === highlightedIndex, children: option.text }, option.value))) }) }))] }));
|
|
11293
11442
|
};
|
|
11294
11443
|
|
|
11295
|
-
export { CblDragAndDrop, CwAccordionContainer, CwAlign, CwAnchoredMenu, CwBtnApprove, CwBtnCancel, CwBtnDelete, CwBtnEdit, CwBtnSave, CwButton, CwButtonSplit, CwButtonSwitch, CwCard, CwCardList, CwCheck, CwCheckbox, CwCheckboxGroup, CwChip, CwColorPicker, CwConfirmationPopup, CwContextMenu, CwDatePicker, CwDatePickerTemporal, CwDateRangePicker, CwDateRangePickerTemporal, CwDateTimePicker, CwDateTimePickerCompact, CwDateTimePickerTemporal, CwDialog, CwDigit, CwDisplayMessage, CwDropdown, CwDropdownFilter, CwExpandable,
|
|
11444
|
+
export { CblDragAndDrop, CwAccordionContainer, CwAlign, CwAnchoredMenu, CwBtnApprove, CwBtnCancel, CwBtnDelete, CwBtnEdit, CwBtnSave, CwButton, CwButtonSplit, CwButtonSwitch, CwCard, CwCardList, CwCheck, CwCheckbox, CwCheckboxGroup, CwChip, CwColorPicker, CwConfirmationPopup, CwContextMenu, CwDatePicker, CwDatePickerTemporal, CwDateRangePicker, CwDateRangePickerTemporal, CwDateTimePicker, CwDateTimePickerCompact, CwDateTimePickerTemporal, CwDialog, CwDigit, CwDisplayMessage, CwDropdown, CwDropdownFilter, CwExpandable, CwFileUploadMultiple, CwFindAirport, CwFindCrewmember, CwGenericTooltip, CwHeadingMain, CwHeadingSecond, CwIcon, CwImageArea, CwImageGallery, CwImageZoom, CwInput, CwInputColor, CwInputDateText, CwInputDatetime, CwInputImage, CwInputNumber, CwInputPhone, CwInputText, CwKeyValueList, CwLabel, CwLoading, CwMasterDetail, CwMessage, CwMessageManager, CwMessageType, CwModal, CwModalHover, CwModalReportFunctional, CwMultiFilter, CwMultiFilterTag, CwNavMenu, CwNote, CwOption, CwPopoverButton, CwRadioGroup, CwReportModal, CwScheduler, CwSearchAsync, CwSearchInput, CwSelect, CwSelectList, CwSelectListItems, CwSortableList, CwSortableTable, CwSuperScheduler, CwTable, CwTableGrouped, CwTableServerSide, CwTabs, CwTagSelector, CwTextArea, CwTime, CwTimePicker, CwToggle, CwTooltipManager, CwTooltipNew, CwTreeView, CwWeekdaySelector, DefaultRowHeader, OnClearPinned, OnClickContextMenu, OnClickEvent, OnClickRowEvent, OnClickRowHeader, OnClickUtc, OnDoubleClickEvent, OnDoubleClickRowEvent, OnDragEvent, OnDropCtrlEvent, OnDropEvent, OnEndClickHeaderEvent, OnLeftDragStart, OnMultiClickEvent, OnPinRow, OnRangeClickEvent, OnRightClickEvent, OnRightClickRow, OnRightDragStart, OnStartClickHeaderEvent, OnUnpinRow, PRESET_LIBRARY_TEMPORAL, PinRowHeader, Resource, Scheduler, SchedulerEvent, SuperScheduler, TooltipConstraintContext, UiEvent, Weekdays, cblEvent, configureCwLoading, eventIsVisible, filterNavItems, filterVisibleEvents, getCwLoadingDefaults, getDefaultDivisions, getEventSizes, getPresetsByKeysTemporal, itemsToMultiFilterTags, sortNavItems, useCwMessage, useSortableList, useSortableTable, useTooltipConstraint };
|