@cwellt_software/cwellt-reactjs-lib 1.4.15 → 1.5.1
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/fonts/roboto-mono/LICENSE +93 -0
- package/dist/content/fonts/roboto-mono/RobotoMono.css +43 -0
- package/dist/content/fonts/roboto-mono/files/roboto-mono-latin-ext-wght-italic.woff2 +0 -0
- package/dist/content/fonts/roboto-mono/files/roboto-mono-latin-ext-wght-normal.woff2 +0 -0
- package/dist/content/fonts/roboto-mono/files/roboto-mono-latin-wght-italic.woff2 +0 -0
- package/dist/content/fonts/roboto-mono/files/roboto-mono-latin-wght-normal.woff2 +0 -0
- 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/deprecated/components/MultiSelect_deprecated_.d.ts +24 -0
- package/dist/deprecated/components/MultiSelect_deprecated_.d.ts.map +1 -0
- package/dist/deprecated/components/dropdown/CwDropdownContainer.d.ts +17 -0
- package/dist/deprecated/components/dropdown/CwDropdownContainer.d.ts.map +1 -0
- package/dist/deprecated/components/multiselect/CwHeadFilter.d.ts +17 -0
- package/dist/deprecated/components/multiselect/CwHeadFilter.d.ts.map +1 -0
- package/dist/deprecated/components/multiselect/CwMultiselect.d.ts +13 -0
- package/dist/deprecated/components/multiselect/CwMultiselect.d.ts.map +1 -0
- package/dist/deprecated/components/multiselect/CwOptionList.d.ts +14 -0
- package/dist/deprecated/components/multiselect/CwOptionList.d.ts.map +1 -0
- package/dist/deprecated/components/tag/CwTag.d.ts +15 -0
- package/dist/deprecated/components/tag/CwTag.d.ts.map +1 -0
- package/dist/index.cjs.js +514 -213
- package/dist/index.css +2 -2
- package/dist/index.d.ts +226 -51
- package/dist/index.es.js +508 -212
- package/dist/playground/main.d.ts +4 -0
- package/dist/playground/main.d.ts.map +1 -0
- package/dist/src/components/control/action/button/CwPopoverButton.d.ts +33 -0
- package/dist/src/components/control/action/button/CwPopoverButton.d.ts.map +1 -0
- package/dist/src/components/control/action/contextual-menu/CwContextualMenu.d.ts +29 -0
- package/dist/src/components/control/action/contextual-menu/CwContextualMenu.d.ts.map +1 -0
- package/dist/src/components/control/action/search/CwAsyncSearch.d.ts +102 -0
- package/dist/src/components/control/action/search/CwAsyncSearch.d.ts.map +1 -0
- 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/action/tooltip-dialog/CwTooltipDialog.d.ts +19 -0
- package/dist/src/components/control/action/tooltip-dialog/CwTooltipDialog.d.ts.map +1 -0
- package/dist/src/components/control/choice/deprecated/CwDropdown.d.ts +19 -0
- package/dist/src/components/control/choice/deprecated/CwDropdown.d.ts.map +1 -0
- package/dist/src/components/control/choice/deprecated/CwDropdownNavigation.d.ts +21 -0
- package/dist/src/components/control/choice/deprecated/CwDropdownNavigation.d.ts.map +1 -0
- package/dist/src/components/control/choice/deprecated/MultiSelect_deprecated_.d.ts +24 -0
- package/dist/src/components/control/choice/deprecated/MultiSelect_deprecated_.d.ts.map +1 -0
- package/dist/src/components/control/choice/dropdown/CwDropdown.d.ts +19 -0
- package/dist/src/components/control/choice/dropdown/CwDropdown.d.ts.map +1 -0
- package/dist/src/components/control/choice/dropdown/CwDropdownContainer.d.ts +17 -0
- package/dist/src/components/control/choice/dropdown/CwDropdownContainer.d.ts.map +1 -0
- package/dist/src/components/control/choice/dropdown/CwDropdownNavigation.d.ts +21 -0
- package/dist/src/components/control/choice/dropdown/CwDropdownNavigation.d.ts.map +1 -0
- package/dist/src/components/control/choice/multiselect/CwHeadFilter.d.ts +17 -0
- package/dist/src/components/control/choice/multiselect/CwHeadFilter.d.ts.map +1 -0
- package/dist/src/components/control/choice/multiselect/CwMultiselect.d.ts +13 -0
- package/dist/src/components/control/choice/multiselect/CwMultiselect.d.ts.map +1 -0
- package/dist/src/components/control/choice/multiselect/CwOptionList.d.ts +14 -0
- package/dist/src/components/control/choice/multiselect/CwOptionList.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/control/input/new-dates/CwDateTimePicker2.d.ts +47 -0
- package/dist/src/components/control/input/new-dates/CwDateTimePicker2.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/CwSchedulerComp2.d.ts +24 -0
- package/dist/src/components/custom/scheduler-temporal/CwSchedulerComp2.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/CwSuperSchedulerComp.d.ts +86 -0
- package/dist/src/components/custom/scheduler-temporal/CwSuperSchedulerComp.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/components/EventRender.d.ts +10 -0
- package/dist/src/components/custom/scheduler-temporal/components/EventRender.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/components/ResourceListRender.d.ts +20 -0
- package/dist/src/components/custom/scheduler-temporal/components/ResourceListRender.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/components/ResourceRender.d.ts +14 -0
- package/dist/src/components/custom/scheduler-temporal/components/ResourceRender.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/components/day_headers/DayHeader.d.ts +11 -0
- package/dist/src/components/custom/scheduler-temporal/components/day_headers/DayHeader.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/components/day_headers/MonthHeader.d.ts +11 -0
- package/dist/src/components/custom/scheduler-temporal/components/day_headers/MonthHeader.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/components/day_headers/MyDaysHeader.d.ts +13 -0
- package/dist/src/components/custom/scheduler-temporal/components/day_headers/MyDaysHeader.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/components/day_headers/WeekHeader.d.ts +11 -0
- package/dist/src/components/custom/scheduler-temporal/components/day_headers/WeekHeader.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/components/resources_title_list/ResourcesTitleList.d.ts +14 -0
- package/dist/src/components/custom/scheduler-temporal/components/resources_title_list/ResourcesTitleList.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/components/scheduler_content_area/SchedulerContentArea.d.ts +23 -0
- package/dist/src/components/custom/scheduler-temporal/components/scheduler_content_area/SchedulerContentArea.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/components/scheduler_header/SchedulerHeader.d.ts +8 -0
- package/dist/src/components/custom/scheduler-temporal/components/scheduler_header/SchedulerHeader.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/components/scheduler_timeline/SchedulerTimeLine.d.ts +12 -0
- package/dist/src/components/custom/scheduler-temporal/components/scheduler_timeline/SchedulerTimeLine.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/components/time_headers/TimeHeader.d.ts +12 -0
- package/dist/src/components/custom/scheduler-temporal/components/time_headers/TimeHeader.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/components/time_headers/TimeHeaderRow.d.ts +10 -0
- package/dist/src/components/custom/scheduler-temporal/components/time_headers/TimeHeaderRow.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/components/time_line/TimeLine.d.ts +12 -0
- package/dist/src/components/custom/scheduler-temporal/components/time_line/TimeLine.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/logic/dates/addMinutesToDateFromPx.d.ts +2 -0
- package/dist/src/components/custom/scheduler-temporal/logic/dates/addMinutesToDateFromPx.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/logic/dates/daysBetweenTwoDates.d.ts +2 -0
- package/dist/src/components/custom/scheduler-temporal/logic/dates/daysBetweenTwoDates.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/logic/dates/daysBetweenTwoDatesWithoutCeil.d.ts +2 -0
- package/dist/src/components/custom/scheduler-temporal/logic/dates/daysBetweenTwoDatesWithoutCeil.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/logic/dates/getFormatedTimeForHeader.d.ts +7 -0
- package/dist/src/components/custom/scheduler-temporal/logic/dates/getFormatedTimeForHeader.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/logic/dates/getMonthHeaderData.d.ts +10 -0
- package/dist/src/components/custom/scheduler-temporal/logic/dates/getMonthHeaderData.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/logic/dates/getUtcToday.d.ts +2 -0
- package/dist/src/components/custom/scheduler-temporal/logic/dates/getUtcToday.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/logic/dates/getWeekHeaderDataFromWeekRange.d.ts +7 -0
- package/dist/src/components/custom/scheduler-temporal/logic/dates/getWeekHeaderDataFromWeekRange.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/logic/dates/listOfDatesToWeeks.d.ts +8 -0
- package/dist/src/components/custom/scheduler-temporal/logic/dates/listOfDatesToWeeks.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/logic/divisions/calculateDivisionType.d.ts +2 -0
- package/dist/src/components/custom/scheduler-temporal/logic/divisions/calculateDivisionType.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/logic/divisions/calculateDivisions.d.ts +2 -0
- package/dist/src/components/custom/scheduler-temporal/logic/divisions/calculateDivisions.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/logic/filtering/filterAndProcessResources.d.ts +4 -0
- package/dist/src/components/custom/scheduler-temporal/logic/filtering/filterAndProcessResources.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/logic/filtering/filterEvents.d.ts +3 -0
- package/dist/src/components/custom/scheduler-temporal/logic/filtering/filterEvents.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/logic/filtering/filterResources.d.ts +3 -0
- package/dist/src/components/custom/scheduler-temporal/logic/filtering/filterResources.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/logic/filtering/hasSameProperties.d.ts +3 -0
- package/dist/src/components/custom/scheduler-temporal/logic/filtering/hasSameProperties.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/logic/onDrop/OnDrop.d.ts +13 -0
- package/dist/src/components/custom/scheduler-temporal/logic/onDrop/OnDrop.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/logic/pixels/getHeightLineScheduler.d.ts +2 -0
- package/dist/src/components/custom/scheduler-temporal/logic/pixels/getHeightLineScheduler.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/logic/pixels/getPixelsForEvent.d.ts +7 -0
- package/dist/src/components/custom/scheduler-temporal/logic/pixels/getPixelsForEvent.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/logic/pixels/heightScheduler.d.ts +3 -0
- package/dist/src/components/custom/scheduler-temporal/logic/pixels/heightScheduler.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/logic/pixels/heightSchedulerPinned.d.ts +2 -0
- package/dist/src/components/custom/scheduler-temporal/logic/pixels/heightSchedulerPinned.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/logic/state_handle/doubleClickOnResource.d.ts +4 -0
- package/dist/src/components/custom/scheduler-temporal/logic/state_handle/doubleClickOnResource.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/logic/state_handle/handlePropChanges.d.ts +6 -0
- package/dist/src/components/custom/scheduler-temporal/logic/state_handle/handlePropChanges.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/logic/state_handle/handleResourceChange.d.ts +5 -0
- package/dist/src/components/custom/scheduler-temporal/logic/state_handle/handleResourceChange.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/logic/state_handle/onDragOver.d.ts +2 -0
- package/dist/src/components/custom/scheduler-temporal/logic/state_handle/onDragOver.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/logic/state_handle/onDropEventToResource.d.ts +5 -0
- package/dist/src/components/custom/scheduler-temporal/logic/state_handle/onDropEventToResource.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/logic/state_handle/onResizeEvent.d.ts +4 -0
- package/dist/src/components/custom/scheduler-temporal/logic/state_handle/onResizeEvent.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/logic/strings/compareStrings.d.ts +2 -0
- package/dist/src/components/custom/scheduler-temporal/logic/strings/compareStrings.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/logic/strings/getGUID.d.ts +2 -0
- package/dist/src/components/custom/scheduler-temporal/logic/strings/getGUID.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/logic/ui/checkIfSlotAvailable.d.ts +3 -0
- package/dist/src/components/custom/scheduler-temporal/logic/ui/checkIfSlotAvailable.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/logic/ui/getEventsOfResource.d.ts +6 -0
- package/dist/src/components/custom/scheduler-temporal/logic/ui/getEventsOfResource.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/logic/ui/getHasPropsChanged.d.ts +4 -0
- package/dist/src/components/custom/scheduler-temporal/logic/ui/getHasPropsChanged.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/logic/ui/getTimeHeaders.d.ts +2 -0
- package/dist/src/components/custom/scheduler-temporal/logic/ui/getTimeHeaders.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/logic/ui/isAllowedToMove.d.ts +3 -0
- package/dist/src/components/custom/scheduler-temporal/logic/ui/isAllowedToMove.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/logic/ui/shouldTriggerScroll.d.ts +4 -0
- package/dist/src/components/custom/scheduler-temporal/logic/ui/shouldTriggerScroll.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/logic/ui/updateResourceVisibility.d.ts +3 -0
- package/dist/src/components/custom/scheduler-temporal/logic/ui/updateResourceVisibility.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/state/CblDragAndDrop.d.ts +11 -0
- package/dist/src/components/custom/scheduler-temporal/state/CblDragAndDrop.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/state/CwSchedulerProps.d.ts +43 -0
- package/dist/src/components/custom/scheduler-temporal/state/CwSchedulerProps.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/state/Resource.d.ts +14 -0
- package/dist/src/components/custom/scheduler-temporal/state/Resource.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/state/State.d.ts +25 -0
- package/dist/src/components/custom/scheduler-temporal/state/State.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/state/cblEvent.d.ts +18 -0
- package/dist/src/components/custom/scheduler-temporal/state/cblEvent.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/state/cblEventCompProps.d.ts +7 -0
- package/dist/src/components/custom/scheduler-temporal/state/cblEventCompProps.d.ts.map +1 -0
- package/dist/src/components/custom/scheduler-temporal/state/resourceCompProps2.d.ts +6 -0
- package/dist/src/components/custom/scheduler-temporal/state/resourceCompProps2.d.ts.map +1 -0
- package/dist/src/components/display/data/table/CwTable.d.ts +4 -1
- package/dist/src/components/display/data/table/CwTable.d.ts.map +1 -1
- package/dist/src/components/display/data/table-serverside/CwTableServerSide.d.ts +4 -1
- package/dist/src/components/display/data/table-serverside/CwTableServerSide.d.ts.map +1 -1
- package/dist/src/components/display/data/table_sortable/CwSortableTable.d.ts +4 -2
- package/dist/src/components/display/data/table_sortable/CwSortableTable.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/components/display/graphics/progress/CwProgress.d.ts +36 -0
- package/dist/src/components/display/graphics/progress/CwProgress.d.ts.map +1 -0
- package/dist/src/components/display/graphics/skeleton/CwSkeleton.d.ts +31 -0
- package/dist/src/components/display/graphics/skeleton/CwSkeleton.d.ts.map +1 -0
- package/dist/src/components/display/graphics/skeleton/CwSkeletonCard.d.ts +21 -0
- package/dist/src/components/display/graphics/skeleton/CwSkeletonCard.d.ts.map +1 -0
- package/dist/src/components/display/graphics/skeleton/normalizeSkeletonCount.d.ts +8 -0
- package/dist/src/components/display/graphics/skeleton/normalizeSkeletonCount.d.ts.map +1 -0
- package/dist/src/components/display/graphics/skeleton/skeletonCellWidth.d.ts +8 -0
- package/dist/src/components/display/graphics/skeleton/skeletonCellWidth.d.ts.map +1 -0
- package/dist/src/components/display/text/tag/CwTag.d.ts +15 -0
- package/dist/src/components/display/text/tag/CwTag.d.ts.map +1 -0
- package/dist/src/components/display/text/tooltip/CwTooltip.d.ts +11 -0
- package/dist/src/components/display/text/tooltip/CwTooltip.d.ts.map +1 -0
- package/dist/src/components/layout/card/CwCard.d.ts +3 -1
- package/dist/src/components/layout/card/CwCard.d.ts.map +1 -1
- package/dist/src/components/layout/card/CwCardList.d.ts +4 -2
- package/dist/src/components/layout/card/CwCardList.d.ts.map +1 -1
- package/dist/src/components/layout/list/key-value/CwKeyValueList.d.ts +4 -0
- package/dist/src/components/layout/list/key-value/CwKeyValueList.d.ts.map +1 -1
- package/dist/src/components/layout/master-detail/CwMasterDetail.d.ts +4 -0
- package/dist/src/components/layout/master-detail/CwMasterDetail.d.ts.map +1 -1
- package/dist/src/components/layout/modal/legacy/cw_modal_confirm.d.ts +16 -0
- package/dist/src/components/layout/modal/legacy/cw_modal_confirm.d.ts.map +1 -0
- package/dist/src/components/layout/modal/legacy/cw_modal_iframe.d.ts +21 -0
- package/dist/src/components/layout/modal/legacy/cw_modal_iframe.d.ts.map +1 -0
- package/dist/src/components/layout/tabs/CwTabs.d.ts +7 -0
- package/dist/src/components/layout/tabs/CwTabs.d.ts.map +1 -1
- package/dist/src/index.d.ts +6 -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/ProgressPage.d.ts +3 -0
- package/dist/src/playground/pages/ProgressPage.d.ts.map +1 -0
- package/dist/src/playground/pages/SelectorsPage.d.ts.map +1 -1
- package/dist/src/playground/pages/SkeletonPage.d.ts +3 -0
- package/dist/src/playground/pages/SkeletonPage.d.ts.map +1 -0
- 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/CwNavMenu.test.d.ts +2 -0
- package/dist/test/components/control/choice/nav-menu/CwNavMenu.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/data/table/CwTable.test.d.ts +2 -0
- package/dist/test/components/display/data/table/CwTable.test.d.ts.map +1 -0
- package/dist/test/components/display/data/table-serverside/CwTableServerSide.test.d.ts +2 -0
- package/dist/test/components/display/data/table-serverside/CwTableServerSide.test.d.ts.map +1 -0
- package/dist/test/components/display/data/table_sortable/CwSortableTable.test.d.ts +2 -0
- package/dist/test/components/display/data/table_sortable/CwSortableTable.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/dist/test/components/display/graphics/progress/CwProgress.test.d.ts +2 -0
- package/dist/test/components/display/graphics/progress/CwProgress.test.d.ts.map +1 -0
- package/dist/test/components/display/graphics/skeleton/CwSkeleton.test.d.ts +2 -0
- package/dist/test/components/display/graphics/skeleton/CwSkeleton.test.d.ts.map +1 -0
- package/dist/test/components/display/graphics/skeleton/CwSkeletonCard.test.d.ts +2 -0
- package/dist/test/components/display/graphics/skeleton/CwSkeletonCard.test.d.ts.map +1 -0
- package/dist/test/components/display/graphics/skeleton/normalizeSkeletonCount.test.d.ts +2 -0
- package/dist/test/components/display/graphics/skeleton/normalizeSkeletonCount.test.d.ts.map +1 -0
- package/dist/test/components/display/graphics/skeleton/skeletonCellWidth.test.d.ts +2 -0
- package/dist/test/components/display/graphics/skeleton/skeletonCellWidth.test.d.ts.map +1 -0
- package/dist/test/components/layout/card/CwCard.test.d.ts +2 -0
- package/dist/test/components/layout/card/CwCard.test.d.ts.map +1 -0
- package/dist/test/components/layout/card/CwCardList.test.d.ts +2 -0
- package/dist/test/components/layout/card/CwCardList.test.d.ts.map +1 -0
- package/dist/test/components/layout/list/key-value/CwKeyValueList.test.d.ts +2 -0
- package/dist/test/components/layout/list/key-value/CwKeyValueList.test.d.ts.map +1 -0
- package/dist/test/components/layout/master-detail/CwMasterDetail.test.d.ts +2 -0
- package/dist/test/components/layout/master-detail/CwMasterDetail.test.d.ts.map +1 -0
- package/dist/test/jest.setup.d.ts +2 -0
- package/dist/test/jest.setup.d.ts.map +1 -0
- package/package.json +1 -2
package/dist/index.cjs.js
CHANGED
|
@@ -181,12 +181,7 @@ function getContrastColor(color) {
|
|
|
181
181
|
return `hsl(${hsl.h}, ${contrastS}%, ${targetL}%)`;
|
|
182
182
|
}
|
|
183
183
|
|
|
184
|
-
|
|
185
|
-
'sortable-asc': (jsxRuntime.jsxs("svg", { width: "16", height: "16", viewBox: "0 0 128 128", fill: "currentColor", children: [jsxRuntime.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" }), jsxRuntime.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" })] })),
|
|
186
|
-
'sortable-desc': (jsxRuntime.jsxs("svg", { width: "16", height: "16", viewBox: "0 0 128 128", fill: "currentColor", children: [jsxRuntime.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" }), jsxRuntime.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" })] })),
|
|
187
|
-
};
|
|
188
|
-
|
|
189
|
-
var styles$u = {"cw-tooltip-content":"cw-tooltip-module__cw-tooltip-content__RZczd","cw-tooltip":"cw-tooltip-module__cw-tooltip__1KYig"};
|
|
184
|
+
var styles$x = {"cw-tooltip-content":"cw-tooltip-module__cw-tooltip-content__RZczd","cw-tooltip":"cw-tooltip-module__cw-tooltip__1KYig"};
|
|
190
185
|
|
|
191
186
|
// Constants
|
|
192
187
|
const margin$1 = 16;
|
|
@@ -476,7 +471,7 @@ const CwTooltipManager = () => {
|
|
|
476
471
|
if (!state.isVisible || !state.content) {
|
|
477
472
|
return null;
|
|
478
473
|
}
|
|
479
|
-
return reactDom.createPortal(jsxRuntime.jsx("div", { ref: tooltipRef, className: styles$
|
|
474
|
+
return reactDom.createPortal(jsxRuntime.jsx("div", { ref: tooltipRef, className: styles$x["cw-tooltip-content"], "data-position": actualPosition, "data-visible": state.isVisible, "data-inline": state.displayInline, style: {
|
|
480
475
|
top: `${tooltipPosition.top}px`,
|
|
481
476
|
left: `${tooltipPosition.left}px`,
|
|
482
477
|
opacity: (isPositioned && !isMeasuring) ? 1 : 0,
|
|
@@ -557,16 +552,22 @@ const CwTooltipNew = ({ children, content = null, position = "right", dissapears
|
|
|
557
552
|
React.useEffect(() => {
|
|
558
553
|
ensureTooltipManager();
|
|
559
554
|
}, []);
|
|
560
|
-
return (jsxRuntime.jsx("div", { ref: containerRef, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, style: overlayStyle, "data-inline": displayInline, className: styles$
|
|
555
|
+
return (jsxRuntime.jsx("div", { ref: containerRef, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, style: overlayStyle, "data-inline": displayInline, className: styles$x["cw-tooltip"], children: children }));
|
|
556
|
+
};
|
|
557
|
+
|
|
558
|
+
const SVG_ICONS = {
|
|
559
|
+
'sortable-asc': (jsxRuntime.jsxs("svg", { width: "16", height: "16", viewBox: "0 0 128 128", fill: "currentColor", children: [jsxRuntime.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" }), jsxRuntime.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" })] })),
|
|
560
|
+
'sortable-desc': (jsxRuntime.jsxs("svg", { width: "16", height: "16", viewBox: "0 0 128 128", fill: "currentColor", children: [jsxRuntime.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" }), jsxRuntime.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" })] })),
|
|
561
561
|
};
|
|
562
562
|
|
|
563
563
|
function CwIcon(props) {
|
|
564
|
-
const { iconId, color, size, title, tooltipPosition = 'bottom', ...iconProps } = props;
|
|
564
|
+
const { iconId, color, size, className, title, tooltipPosition = 'bottom', ...iconProps } = props;
|
|
565
565
|
const getClassName = (baseClass) => {
|
|
566
566
|
return [
|
|
567
567
|
baseClass,
|
|
568
568
|
color && `cw-color-${color}`,
|
|
569
|
-
size && `cw-font-size-${size}
|
|
569
|
+
size && `cw-font-size-${size}`,
|
|
570
|
+
className
|
|
570
571
|
].filter(Boolean).join(' ');
|
|
571
572
|
};
|
|
572
573
|
let iconElement;
|
|
@@ -978,49 +979,128 @@ function CwImageZoom(image) {
|
|
|
978
979
|
} }), jsxRuntime.jsx("div", { style: { color: "#fff", fontSize: "1rem", textAlign: "center" }, children: selectedImage.filename && jsxRuntime.jsx("div", { children: selectedImage.filename }) })] }))] }));
|
|
979
980
|
}
|
|
980
981
|
|
|
982
|
+
let defaults = {};
|
|
983
|
+
/**
|
|
984
|
+
* Register global CwLoading defaults. Call once at app init, before the first render.
|
|
985
|
+
* Merges into any previously configured defaults.
|
|
986
|
+
*/
|
|
987
|
+
function configureCwLoading(next) {
|
|
988
|
+
defaults = { ...defaults, ...next };
|
|
989
|
+
}
|
|
990
|
+
/** Read the currently configured CwLoading defaults. */
|
|
991
|
+
function getCwLoadingDefaults() {
|
|
992
|
+
return defaults;
|
|
993
|
+
}
|
|
994
|
+
|
|
981
995
|
/**
|
|
982
|
-
* CwLoading
|
|
996
|
+
* CwLoading — a spinner with optional text that dims the wrapped content while loading.
|
|
983
997
|
*
|
|
984
|
-
*
|
|
985
|
-
* and disables the wrapped content while in loading state.
|
|
998
|
+
* Icon resolves as `iconName` prop → `getCwLoadingDefaults().icon` → none (neutral ring).
|
|
986
999
|
*
|
|
987
1000
|
* @example
|
|
988
|
-
* // Basic usage
|
|
989
1001
|
* <CwLoading isLoading={isSubmitting}>
|
|
990
1002
|
* <form>...</form>
|
|
991
1003
|
* </CwLoading>
|
|
992
|
-
*
|
|
993
|
-
* // With custom text and size
|
|
994
|
-
* <CwLoading
|
|
995
|
-
* isLoading={isLoading}
|
|
996
|
-
* text="Please wait..."
|
|
997
|
-
* size="large"
|
|
998
|
-
* >
|
|
999
|
-
* <UserProfile />
|
|
1000
|
-
* </CwLoading>
|
|
1001
1004
|
*/
|
|
1002
|
-
function CwLoading({ isLoading = false, text = '', size = 'regular', iconPosition = 'outside', iconName
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
+
function CwLoading({ isLoading = false, text = '', size = 'regular', iconPosition = 'outside', iconName, animation = 'spin', children }) {
|
|
1006
|
+
let overlay = null;
|
|
1007
|
+
if (isLoading) {
|
|
1008
|
+
const resolvedIcon = iconName ?? getCwLoadingDefaults().icon;
|
|
1009
|
+
overlay = (jsxRuntime.jsxs("div", { className: "cw-loading-content", "data-size": size, "data-animation": animation, role: "status", "aria-label": text || 'Loading', children: [jsxRuntime.jsx("div", { className: "cw-loading", "data-icon-position": iconPosition, "data-has-icon": !!resolvedIcon, children: resolvedIcon && jsxRuntime.jsx("span", { className: `cwi-icons ${resolvedIcon}` }) }), text && (jsxRuntime.jsx("p", { children: text }))] }));
|
|
1010
|
+
}
|
|
1011
|
+
return (jsxRuntime.jsxs("div", { "aria-busy": isLoading, className: "cw-loading-container", "data-children": !!children, children: [overlay, jsxRuntime.jsx("div", { className: "cw-loading-disabled-content", children: children })] }));
|
|
1005
1012
|
}
|
|
1006
1013
|
|
|
1014
|
+
var styles$w = {"skeleton":"cw-skeleton-module__skeleton__Jvx2x","group":"cw-skeleton-module__group__Cm8AU"};
|
|
1015
|
+
|
|
1016
|
+
/*
|
|
1017
|
+
* Internal helper for skeleton allocations (CwSkeleton, tables, cards).
|
|
1018
|
+
* Not exported from the library barrel - not a public API.
|
|
1019
|
+
*/
|
|
1020
|
+
/** Upper bound so a pathological count cannot allocate an unbounded number of nodes. */
|
|
1021
|
+
const MAX_SKELETON_COUNT = 100;
|
|
1007
1022
|
/**
|
|
1008
|
-
*
|
|
1023
|
+
* Normalizes a skeleton count to a finite, floored, non-negative integer capped at
|
|
1024
|
+
* MAX_SKELETON_COUNT. Falls back to `fallback` for undefined, NaN, non-finite or
|
|
1025
|
+
* non-positive input, so valid inputs keep the public default behaviour and only
|
|
1026
|
+
* pathological ones are bounded.
|
|
1027
|
+
*/
|
|
1028
|
+
function normalizeSkeletonCount(value, fallback) {
|
|
1029
|
+
if (value === undefined || !Number.isFinite(value) || value < 1) {
|
|
1030
|
+
return fallback;
|
|
1031
|
+
}
|
|
1032
|
+
return Math.min(Math.floor(value), MAX_SKELETON_COUNT);
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1035
|
+
/**
|
|
1036
|
+
* CwSkeleton - a shimmering placeholder that reserves the shape of content while it loads.
|
|
1009
1037
|
*
|
|
1010
|
-
*
|
|
1038
|
+
* Renders inline <span> elements so it can sit inside text-level contexts. Sizing flows
|
|
1039
|
+
* through component-scoped custom properties; only the props the caller provides are set
|
|
1040
|
+
* inline, so the CSS defaults per variant (and the 60% last-line rule) stay in charge.
|
|
1011
1041
|
*
|
|
1012
1042
|
* @example
|
|
1013
|
-
*
|
|
1014
|
-
* <
|
|
1015
|
-
*
|
|
1016
|
-
* // Use:
|
|
1017
|
-
* <CwLoading size="small" />
|
|
1043
|
+
* <CwSkeleton count={3} />
|
|
1044
|
+
* <CwSkeleton variant="circle" />
|
|
1045
|
+
* <CwSkeleton variant="rect" height="10rem" />
|
|
1018
1046
|
*/
|
|
1019
|
-
function
|
|
1020
|
-
|
|
1047
|
+
function CwSkeleton({ variant = 'text', width, height, count = 1, radius, gap }) {
|
|
1048
|
+
// Only forward the custom properties the caller actually set; CSS declares the defaults.
|
|
1049
|
+
const style = {
|
|
1050
|
+
...(width !== undefined && { '--skeleton-width': width }),
|
|
1051
|
+
...(height !== undefined && { '--skeleton-height': height }),
|
|
1052
|
+
...(radius !== undefined && { '--skeleton-radius': radius })
|
|
1053
|
+
};
|
|
1054
|
+
// The un-hashed cw-skeleton / cw-skeleton-group classes carry no styles in the
|
|
1055
|
+
// library - they are stable public hooks for exceptional external overrides.
|
|
1056
|
+
const skeletonClassName = ['cw-skeleton', styles$w.skeleton].filter(Boolean).join(' ');
|
|
1057
|
+
const groupClassName = ['cw-skeleton-group', styles$w.group].filter(Boolean).join(' ');
|
|
1058
|
+
const lineCount = normalizeSkeletonCount(count, 1);
|
|
1059
|
+
if (lineCount <= 1) {
|
|
1060
|
+
return (jsxRuntime.jsx("span", { className: skeletonClassName, "data-variant": variant, "aria-hidden": "true", style: style }));
|
|
1061
|
+
}
|
|
1062
|
+
const skeletonElements = Array.from({ length: lineCount }, (_, index) => (jsxRuntime.jsx("span", { className: skeletonClassName, "data-variant": variant, style: style }, index)));
|
|
1063
|
+
const groupStyle = {
|
|
1064
|
+
...(gap !== undefined && { '--skeleton-gap': gap })
|
|
1065
|
+
};
|
|
1066
|
+
return (jsxRuntime.jsx("span", { className: groupClassName, "aria-hidden": "true", style: groupStyle, children: skeletonElements }));
|
|
1021
1067
|
}
|
|
1022
1068
|
|
|
1023
|
-
var styles$
|
|
1069
|
+
var styles$v = {"progress":"cw-progress-module__progress__d-g2-","value":"cw-progress-module__value__Q-DrH","header":"cw-progress-module__header__mv5ct","label":"cw-progress-module__label__jwOWp","track":"cw-progress-module__track__572-3","fill":"cw-progress-module__fill__fX1UA"};
|
|
1070
|
+
|
|
1071
|
+
/**
|
|
1072
|
+
* CwProgress - a determinate or indeterminate progress bar.
|
|
1073
|
+
*
|
|
1074
|
+
* Use it for measurable operations (imports, uploads, batch jobs). For short
|
|
1075
|
+
* unmeasurable waits use CwLoading; for initial layout loads use CwSkeleton.
|
|
1076
|
+
*
|
|
1077
|
+
* @example
|
|
1078
|
+
* <CwProgress value={62} label="Import" color="success" />
|
|
1079
|
+
* <CwProgress indeterminate label="Uploading" />
|
|
1080
|
+
*/
|
|
1081
|
+
function CwProgress({ value, indeterminate = false, label, rightLabel, size = 'regular', layout = 'row', color = 'primary', monoValue = false, prominent = false }) {
|
|
1082
|
+
const labelId = React.useId();
|
|
1083
|
+
// Determinate: a missing or non-finite value is treated as 0 (never NaN), then
|
|
1084
|
+
// clamped to [0,100] for aria-valuenow and the fill width. Indeterminate has no value.
|
|
1085
|
+
const clamped = indeterminate
|
|
1086
|
+
? undefined
|
|
1087
|
+
: Math.min(Math.max(Number.isFinite(value) ? value : 0, 0), 100);
|
|
1088
|
+
const percent = clamped !== undefined ? Math.round(clamped) : undefined;
|
|
1089
|
+
const showValue = rightLabel !== undefined || (!indeterminate && percent !== undefined);
|
|
1090
|
+
const valueText = rightLabel ?? (percent !== undefined ? `${percent}%` : '');
|
|
1091
|
+
// The un-hashed cw-progress class carries no styles in the library - a stable
|
|
1092
|
+
// public hook for exceptional external overrides only.
|
|
1093
|
+
const rootClassName = ['cw-progress', styles$v.progress].filter(Boolean).join(' ');
|
|
1094
|
+
const labelSpan = label ? jsxRuntime.jsx("span", { className: styles$v.label, id: labelId, children: label }) : null;
|
|
1095
|
+
const valueLabel = showValue ? (jsxRuntime.jsx("span", { className: styles$v.value, "data-mono": monoValue || undefined, children: valueText })) : null;
|
|
1096
|
+
return (jsxRuntime.jsxs("div", { className: rootClassName, "data-layout": layout, "data-size": size, "data-color": color, "data-prominent": prominent || undefined, "data-indeterminate": indeterminate || undefined, children: [layout === 'column' && (labelSpan || valueLabel) && (jsxRuntime.jsxs("header", { className: styles$v.header, children: [labelSpan, valueLabel] })), layout === 'row' && labelSpan, jsxRuntime.jsx("div", { className: styles$v.track, role: "progressbar", ...(label && { 'aria-labelledby': labelId }), ...(!indeterminate && percent !== undefined && {
|
|
1097
|
+
'aria-valuenow': percent,
|
|
1098
|
+
'aria-valuemin': 0,
|
|
1099
|
+
'aria-valuemax': 100
|
|
1100
|
+
}), children: jsxRuntime.jsx("div", { className: styles$v.fill, style: !indeterminate && clamped !== undefined ? { width: `${clamped}%` } : undefined }) }), layout === 'row' && valueLabel] }));
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
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"};
|
|
1024
1104
|
|
|
1025
1105
|
// Constants moved outside to prevent recreation
|
|
1026
1106
|
const margin = 16;
|
|
@@ -1143,12 +1223,12 @@ const CwGenericTooltip = ({ children, content = null, position = defaultPosition
|
|
|
1143
1223
|
const { setTooltipTimeout, clearTooltipTimeout } = useTooltipDelay(() => {
|
|
1144
1224
|
setIsVisible(true);
|
|
1145
1225
|
}, showDelay);
|
|
1146
|
-
const { position: tooltipPosition, actualPosition } = useTooltipPosition(isVisible, containerRef, position, styles$
|
|
1226
|
+
const { position: tooltipPosition, actualPosition } = useTooltipPosition(isVisible, containerRef, position, styles$u["cw-generic-tooltip-content"]);
|
|
1147
1227
|
// Memoize tooltip content creation
|
|
1148
1228
|
const tooltipContent = React.useMemo(() => {
|
|
1149
1229
|
if (hide || !isVisible || !content)
|
|
1150
1230
|
return null;
|
|
1151
|
-
return reactDom.createPortal(jsxRuntime.jsx("div", { className: styles$
|
|
1231
|
+
return reactDom.createPortal(jsxRuntime.jsx("div", { className: styles$u["cw-generic-tooltip-content"], "data-position": actualPosition, "data-visible": isVisible, "data-inline": displayInline, style: {
|
|
1152
1232
|
position: 'fixed',
|
|
1153
1233
|
top: `${tooltipPosition.top}px`,
|
|
1154
1234
|
left: `${tooltipPosition.left}px`,
|
|
@@ -1163,7 +1243,7 @@ const CwGenericTooltip = ({ children, content = null, position = defaultPosition
|
|
|
1163
1243
|
clearTooltipTimeout();
|
|
1164
1244
|
setIsVisible(false);
|
|
1165
1245
|
}, [clearTooltipTimeout]);
|
|
1166
|
-
return (jsxRuntime.jsxs("div", { ref: containerRef, className: styles$
|
|
1246
|
+
return (jsxRuntime.jsxs("div", { ref: containerRef, className: styles$u["cw-generic-tooltip"], onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, style: overlayStyle, "data-inline": displayInline, children: [tooltipContent, children] }));
|
|
1167
1247
|
};
|
|
1168
1248
|
|
|
1169
1249
|
const CwButton = React.forwardRef(function CwButton({ text, variant = 'solid', color = 'primary', size = 'medium', iconPosition = 'left', pressed, className = '', icon = "", title, tooltipPosition = "bottom", children, ...buttonProps }, ref) {
|
|
@@ -1225,7 +1305,7 @@ function CwModal(custModalProps) {
|
|
|
1225
1305
|
return (jsxRuntime.jsx("div", { children: custModalProps.modalState && (jsxRuntime.jsxs("div", { className: custModalProps.classNameModalOverlay + " cwelltModalOverlay", children: [jsxRuntime.jsx("div", { className: "cwelltModalOverlayBg", onClick: custModalProps.onCloseModal }), jsxRuntime.jsx(Draggable, { disabled: isModalDisabled, axis: "both", nodeRef: draggableRef, children: jsxRuntime.jsxs("div", { className: custModalProps.classNameModal + " cwelltContainerModal", ref: draggableRef, style: widthModalDef !== "40em" ? modalStyle.widthCustomStyle : modalStyle.widthDefStyle, children: [jsxRuntime.jsxs("div", { className: "cwelltModalHeader", onMouseOver: cwelltOnMouseOverModal, onMouseOut: cwelltOnMouseOutModal, children: [jsxRuntime.jsx("div", { className: "cwelltModalTitle", children: custModalProps.titleModal }), jsxRuntime.jsx("button", { className: "cwelltBtnCloseModal", onClick: custModalProps.onCloseModal, children: jsxRuntime.jsx("span", { className: "cwelltCloseIcon" }) })] }), jsxRuntime.jsx("div", { className: "cwelltModalBody", children: jsxRuntime.jsx("div", { className: "cwelltContainerModalBody", style: { position: "relative" }, children: custModalProps.children }) }), isHide === false ? (jsxRuntime.jsx("footer", { className: "legacy-modal-footer", onMouseOver: cwelltOnMouseOverModal, onMouseOut: cwelltOnMouseOutModal, children: jsxRuntime.jsx(CwButton, { variant: "icon", icon: "save", title: "Save", onClick: custModalProps.onSaveModal, form: custModalProps.formSaveModal, hidden: custModalProps.HideBtnModal, type: custModalProps.HtmlSubmitModal }) })) : (jsxRuntime.jsx("div", { style: { display: "none" } }))] }) })] })) }));
|
|
1226
1306
|
}
|
|
1227
1307
|
|
|
1228
|
-
var styles$
|
|
1308
|
+
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"};
|
|
1229
1309
|
|
|
1230
1310
|
function CwConfirmationPopup(props) {
|
|
1231
1311
|
const { isOpen, onConfirm, onCancel, message = "Are you sure you want to proceed?", confirmText = "Confirm", cancelText = "Cancel", placement = 'bottom', children } = props;
|
|
@@ -1289,15 +1369,15 @@ function CwConfirmationPopup(props) {
|
|
|
1289
1369
|
onCancel();
|
|
1290
1370
|
}
|
|
1291
1371
|
};
|
|
1292
|
-
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [renderChildren(), isOpen && (jsxRuntime.jsx("div", { className: styles$
|
|
1372
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [renderChildren(), isOpen && (jsxRuntime.jsx("div", { className: styles$t.overlayPositioned, onClick: handleOverlayClick, children: jsxRuntime.jsxs("div", { ref: popupRef, className: styles$t.popup, style: {
|
|
1293
1373
|
position: 'absolute',
|
|
1294
1374
|
top: `${position.top}px`,
|
|
1295
1375
|
left: `${position.left}px`,
|
|
1296
1376
|
transform: 'none'
|
|
1297
|
-
}, children: [jsxRuntime.jsx("p", { className: styles$
|
|
1377
|
+
}, children: [jsxRuntime.jsx("p", { className: styles$t.message, children: message }), jsxRuntime.jsxs("div", { className: styles$t.buttons, children: [jsxRuntime.jsx("button", { className: `${styles$t.button} ${styles$t.confirmButton}`, onClick: onConfirm, children: confirmText }), jsxRuntime.jsx("button", { className: `${styles$t.button} ${styles$t.cancelButton}`, onClick: onCancel, children: cancelText })] })] }) }))] }));
|
|
1298
1378
|
}
|
|
1299
1379
|
|
|
1300
|
-
var styles$
|
|
1380
|
+
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"};
|
|
1301
1381
|
|
|
1302
1382
|
// Helper function to parse size values
|
|
1303
1383
|
const parseSize = (size) => {
|
|
@@ -1570,7 +1650,7 @@ const CwDialog = props => {
|
|
|
1570
1650
|
}
|
|
1571
1651
|
}
|
|
1572
1652
|
}, [open]);
|
|
1573
|
-
const header = React.useMemo(() => (jsxRuntime.jsxs("header", { onMouseDown: handleMouseDown, children: [jsxRuntime.jsx("span", { children: headline }), customHeader || (jsxRuntime.jsx("button", { className: styles$
|
|
1653
|
+
const header = React.useMemo(() => (jsxRuntime.jsxs("header", { onMouseDown: handleMouseDown, children: [jsxRuntime.jsx("span", { children: headline }), customHeader || (jsxRuntime.jsx("button", { className: styles$s["cw-dialog-button-close"], onClick: onClose }))] })), [handleMouseDown, headline, customHeader, onClose]);
|
|
1574
1654
|
const content = React.useMemo(() => (jsxRuntime.jsx("section", { children: children })), [children]);
|
|
1575
1655
|
const footer = React.useMemo(() => (jsxRuntime.jsx("footer", { children: customFooter || (jsxRuntime.jsx(CwButton, { variant: "icon", icon: "save", title: "Save", onClick: onSave, tooltipPosition: "top", disabled: disableSave, "data-testid": "cw-dialog-save" })) })), [customFooter, onSave, disableSave]);
|
|
1576
1656
|
const resizeHandles = React.useMemo(() => size.autoHeight
|
|
@@ -1597,7 +1677,7 @@ const CwDialog = props => {
|
|
|
1597
1677
|
: `${convertFromPx(size.height, size.heightUnit)}${size.heightUnit}`;
|
|
1598
1678
|
return { displayWidth, displayHeight };
|
|
1599
1679
|
}, [size.width, size.height, size.widthUnit, size.heightUnit, size.autoHeight]);
|
|
1600
|
-
const dialogContent = (jsxRuntime.jsx("div", { "data-has-scrim": hasScrim, className: styles$
|
|
1680
|
+
const dialogContent = (jsxRuntime.jsx("div", { "data-has-scrim": hasScrim, className: styles$s["cw-dialog-main"], onMouseDown: handleScrimMouseDown, onMouseUp: handleScrimMouseUpOrLeave, onMouseLeave: handleScrimMouseUpOrLeave, "data-pressing": isPressingScrim, children: jsxRuntime.jsxs("dialog", { ...domProps, ref: dialogRef, style: {
|
|
1601
1681
|
left: `${position.x}px`,
|
|
1602
1682
|
top: `${position.y}px`,
|
|
1603
1683
|
width: displayDimensions.displayWidth,
|
|
@@ -1758,7 +1838,7 @@ function CwAlign(props) {
|
|
|
1758
1838
|
}, children: props.children }));
|
|
1759
1839
|
}
|
|
1760
1840
|
|
|
1761
|
-
var styles$
|
|
1841
|
+
var styles$r = {"card":"cw-card-module__card__HJUT0","clickable":"cw-card-module__clickable__Y-V3X","disabled":"cw-card-module__disabled__0wHh1","content":"cw-card-module__content__ma9qy","headerContent":"cw-card-module__headerContent__x4Jfl","footerTags":"cw-card-module__footerTags__80sSW"};
|
|
1762
1842
|
|
|
1763
1843
|
/**
|
|
1764
1844
|
* CwCard - A simple card component for displaying content in a contained format
|
|
@@ -1778,17 +1858,16 @@ var styles$q = {"card":"cw-card-module__card__HJUT0","clickable":"cw-card-module
|
|
|
1778
1858
|
* <p>This is the main content of the card.</p>
|
|
1779
1859
|
* </CwCard>
|
|
1780
1860
|
**/
|
|
1781
|
-
const CwCard = ({ id, title, subtitle, alignment = 'center', children, footer, onEdit, onDelete, extraActions, className = '', clickable = false, onClick, isLoading = false, disabled = false, style, chips = [], variant = "border", direction = "column", layout, }) => {
|
|
1861
|
+
const CwCard = ({ id, title, subtitle, alignment = 'center', children, footer, onEdit, onDelete, extraActions, className = '', clickable = false, onClick, isLoading = false, skeletonLines = 3, disabled = false, style, chips = [], variant = "border", direction = "column", layout, }) => {
|
|
1782
1862
|
const resolvedDirection = layout?.direction ?? direction;
|
|
1783
1863
|
const resolvedAlign = layout?.align ?? (alignment === 'left' ? 'start' : 'center');
|
|
1784
1864
|
// Construct class names using CSS modules
|
|
1785
1865
|
const cardClassNames = [
|
|
1786
1866
|
'cw-card',
|
|
1787
|
-
styles$
|
|
1867
|
+
styles$r.card,
|
|
1788
1868
|
className,
|
|
1789
|
-
clickable ? styles$
|
|
1790
|
-
disabled ? styles$
|
|
1791
|
-
isLoading ? styles$q.loading : '',
|
|
1869
|
+
clickable ? styles$r.clickable : '',
|
|
1870
|
+
disabled ? styles$r.disabled : '',
|
|
1792
1871
|
].filter(Boolean).join(' ');
|
|
1793
1872
|
// Handle click event when card is clickable
|
|
1794
1873
|
const handleClick = () => {
|
|
@@ -1804,16 +1883,17 @@ const CwCard = ({ id, title, subtitle, alignment = 'center', children, footer, o
|
|
|
1804
1883
|
const hasChips = chips.length > 0;
|
|
1805
1884
|
// Determine if footer should be rendered
|
|
1806
1885
|
const hasFooter = hasChips || footer || (hasActions && resolvedDirection === "row");
|
|
1807
|
-
// Actions component to reuse
|
|
1808
|
-
|
|
1809
|
-
|
|
1886
|
+
// Actions component to reuse. While loading, each provided action renders a circular
|
|
1887
|
+
// ghost sized to the CwButton icon footprint (2rem) - no interactive buttons.
|
|
1888
|
+
const ActionsComponent = hasActions && !disabled ? (jsxRuntime.jsx("div", { className: styles$r.actions, children: isLoading ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [extraActions && jsxRuntime.jsx(CwSkeleton, { variant: "circle", height: "2rem" }), onEdit && jsxRuntime.jsx(CwSkeleton, { variant: "circle", height: "2rem" }), onDelete && jsxRuntime.jsx(CwSkeleton, { variant: "circle", height: "2rem" })] })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [extraActions ?? null, onEdit && jsxRuntime.jsx(CwButton, { variant: "icon", icon: "edit", onClick: onEdit }), onDelete && jsxRuntime.jsx(CwButton, { variant: "icon", icon: "delete", color: "danger", onClick: onDelete })] })) })) : null;
|
|
1889
|
+
return (jsxRuntime.jsxs("div", { ...(id && { id }), className: cardClassNames, ...(style && { style }), ...(clickable && !isLoading && {
|
|
1810
1890
|
role: 'button',
|
|
1811
1891
|
tabIndex: 0,
|
|
1812
1892
|
onClick: handleClick,
|
|
1813
|
-
}), "data-variant": variant, "data-direction": resolvedDirection, children: [hasHeader && (jsxRuntime.jsxs("header", { children: [(title || subtitle) && (jsxRuntime.jsxs("div", { className: styles$
|
|
1893
|
+
}), "data-variant": variant, "data-direction": resolvedDirection, "aria-busy": isLoading || undefined, children: [isLoading ? (jsxRuntime.jsxs("header", { children: [jsxRuntime.jsx("div", { className: styles$r.headerContent, "data-align": resolvedAlign, children: jsxRuntime.jsx(CwSkeleton, { width: "8rem", height: "1.5em" }) }), resolvedDirection === "column" && ActionsComponent] })) : (hasHeader && (jsxRuntime.jsxs("header", { children: [(title || subtitle) && (jsxRuntime.jsxs("div", { className: styles$r.headerContent, "data-align": resolvedAlign, children: [title && jsxRuntime.jsx("h5", { children: title }), subtitle && jsxRuntime.jsx("strong", { children: subtitle })] })), resolvedDirection === "column" && ActionsComponent] }))), jsxRuntime.jsx("div", { className: styles$r.content, children: isLoading ? jsxRuntime.jsx(CwSkeleton, { count: normalizeSkeletonCount(skeletonLines, 3) }) : children }), hasFooter && (isLoading ? (jsxRuntime.jsx("footer", { children: jsxRuntime.jsx("div", { className: styles$r.footerTags, children: jsxRuntime.jsx(CwSkeleton, { variant: "rect", width: "4rem", height: "1.5em", radius: "1rem" }) }) })) : (jsxRuntime.jsxs("footer", { children: [hasChips && (jsxRuntime.jsx("div", { className: styles$r.footerTags, children: chips.map((chip, index) => (jsxRuntime.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 && (jsxRuntime.jsx("div", { className: styles$r.footerContent, children: footer }))] }))), resolvedDirection === "row" && ActionsComponent] }));
|
|
1814
1894
|
};
|
|
1815
1895
|
|
|
1816
|
-
var styles$
|
|
1896
|
+
var styles$q = {"cardContainer":"cw-card-list-module__cardContainer__l3YEh","pagination":"cw-card-list-module__pagination__5Ay78","pageInfo":"cw-card-list-module__pageInfo__uiMel","emptyState":"cw-card-list-module__emptyState__RlqiS"};
|
|
1817
1897
|
|
|
1818
1898
|
/**
|
|
1819
1899
|
* Option to display in the CwSelect
|
|
@@ -1871,7 +1951,7 @@ function CwSelect(props) {
|
|
|
1871
1951
|
: selectProps.onChange, children: [placeholder && jsxRuntime.jsx(CwOption, { value: "", children: placeholder }), children] }), buttonProps && jsxRuntime.jsx(CwButton, { ...buttonProps })] })] }), feedbackMessages.map((feedbackItem, index) => (jsxRuntime.jsx("p", { className: "cw-input-info", "data-color": feedbackItem.type, children: feedbackItem.message }, index)))] }));
|
|
1872
1952
|
}
|
|
1873
1953
|
|
|
1874
|
-
function CwCardList({ items, renderCard, pageSize = 10, layout = 'grid', defaultCardWidth = 320, cardGap = 16, isLoading = false, emptyState, sortOptions = [], defaultSortKey, keyExtractor, ...htmlProps }) {
|
|
1954
|
+
function CwCardList({ items, renderCard, pageSize = 10, layout = 'grid', defaultCardWidth = 320, cardGap = 16, isLoading = false, skeletonCards = 6, emptyState, sortOptions = [], defaultSortKey, keyExtractor, ...htmlProps }) {
|
|
1875
1955
|
const [currentPage, setCurrentPage] = React.useState(1);
|
|
1876
1956
|
const [sortKey, setSortKey] = React.useState(defaultSortKey || sortOptions[0]?.key || '');
|
|
1877
1957
|
const [sortDirection, setSortDirection] = React.useState('asc');
|
|
@@ -1908,10 +1988,10 @@ function CwCardList({ items, renderCard, pageSize = 10, layout = 'grid', default
|
|
|
1908
1988
|
icon: sortDirection === 'asc' ? 'arrow-up' : 'arrow-down',
|
|
1909
1989
|
onClick: () => setSortDirection(prev => prev === 'asc' ? 'desc' : 'asc'),
|
|
1910
1990
|
title: `Sort ${sortDirection === 'asc' ? 'descending' : 'ascending'}`,
|
|
1911
|
-
}, value: sortKey, onChange: (e) => handleSortChange(e.target.value), children: sortOptions.map(option => (jsxRuntime.jsx(CwOption, { value: option.key, children: option.label }, option.key))) }) })), isLoading ? (jsxRuntime.jsx("div", { className: styles$
|
|
1991
|
+
}, value: sortKey, onChange: (e) => handleSortChange(e.target.value), children: sortOptions.map(option => (jsxRuntime.jsx(CwOption, { value: option.key, children: option.label }, option.key))) }) })), isLoading ? (jsxRuntime.jsx("div", { className: `${styles$q.cardContainer}`, "data-layout": layout, style: gridStyle, "aria-busy": true, children: Array.from({ length: normalizeSkeletonCount(skeletonCards, 6) }, (_, index) => (jsxRuntime.jsx(CwCard, { isLoading: true, children: null }, `skeleton_${index}`))) })) : sortedItems.length === 0 ? (jsxRuntime.jsx("div", { className: styles$q.emptyState, children: emptyState || jsxRuntime.jsx("p", { children: "No items to display" }) })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { className: `${styles$q.cardContainer}`, "data-layout": layout, style: gridStyle, children: visibleItems.map((item, index) => (jsxRuntime.jsx(React.Fragment, { children: renderCard(item, index) }, keyExtractor ? keyExtractor(item, index) : index))) }), totalPages > 1 && (jsxRuntime.jsxs("div", { className: styles$q.pagination, children: [jsxRuntime.jsx(CwButton, { variant: "icon", icon: "chevron-left", disabled: currentPage === 1, onClick: () => setCurrentPage(p => Math.max(1, p - 1)) }), jsxRuntime.jsxs("span", { className: styles$q.pageInfo, children: [currentPage, " / ", totalPages] }), jsxRuntime.jsx(CwButton, { variant: "icon", icon: "chevron-right", disabled: currentPage === totalPages, onClick: () => setCurrentPage(p => Math.min(totalPages, p + 1)) })] }))] }))] }));
|
|
1912
1992
|
}
|
|
1913
1993
|
|
|
1914
|
-
var styles$
|
|
1994
|
+
var styles$p = {"cw-accordion":"cw-accordion-module__cw-accordion__ErvlW","cw-accordion-body":"cw-accordion-module__cw-accordion-body__xlI8b"};
|
|
1915
1995
|
|
|
1916
1996
|
/**
|
|
1917
1997
|
*
|
|
@@ -1928,7 +2008,22 @@ function CwAccordionContainer(CwelltAccordionContainerProps) {
|
|
|
1928
2008
|
setVisible_accordionBody(!isVisible_accordionBody);
|
|
1929
2009
|
};
|
|
1930
2010
|
// #endregion
|
|
1931
|
-
return (jsxRuntime.jsxs("div", { className: styles$
|
|
2011
|
+
return (jsxRuntime.jsxs("div", { className: styles$p["cw-accordion"], style: CwelltAccordionContainerProps.style, "data-open": isVisible_accordionBody, children: [jsxRuntime.jsxs("header", { onClick: () => showAccordionBody(), children: [jsxRuntime.jsx("div", { children: CwelltAccordionContainerProps.desc_text }), jsxRuntime.jsx("button", { className: "cw-button-icon" })] }), jsxRuntime.jsx("div", { className: styles$p["cw-accordion-body"], children: CwelltAccordionContainerProps.children })] }));
|
|
2012
|
+
}
|
|
2013
|
+
|
|
2014
|
+
/*
|
|
2015
|
+
* Internal helper for table loading ghosts (CwTable, CwSortableTable).
|
|
2016
|
+
* Not exported from the library barrel - not a public API.
|
|
2017
|
+
*/
|
|
2018
|
+
const SKELETON_CELL_WIDTHS = ['85%', '60%', '95%', '70%', '80%', '65%'];
|
|
2019
|
+
/**
|
|
2020
|
+
* Deterministic width for a table ghost cell so skeleton rows look like real,
|
|
2021
|
+
* unevenly sized content. Derived purely from indices - stable across re-renders
|
|
2022
|
+
* (no reshuffling) - and offset by the column count so the pattern does not
|
|
2023
|
+
* repeat identically per row or per column.
|
|
2024
|
+
*/
|
|
2025
|
+
function getSkeletonCellWidth(rowIndex, columnIndex, columnCount) {
|
|
2026
|
+
return SKELETON_CELL_WIDTHS[(rowIndex * columnCount + columnIndex) % SKELETON_CELL_WIDTHS.length];
|
|
1932
2027
|
}
|
|
1933
2028
|
|
|
1934
2029
|
/**
|
|
@@ -2000,7 +2095,7 @@ function CwAccordionContainer(CwelltAccordionContainerProps) {
|
|
|
2000
2095
|
*
|
|
2001
2096
|
* @returns React component
|
|
2002
2097
|
*/
|
|
2003
|
-
function CwTable({ columns, data, pagination = false, pageSizeOptions = [5, 10, 20, 50], expandedRowRender, onExpand, className, classNameRow, style, classNameContainer, id, testId, textNoData = "No data available at the moment", rowKey = "key", loading = false, scrollHeight, stickyHeader = false, pageLabel = "page", rowSelection }) {
|
|
2098
|
+
function CwTable({ columns, data, pagination = false, pageSizeOptions = [5, 10, 20, 50], expandedRowRender, onExpand, className, classNameRow, style, classNameContainer, id, testId, textNoData = "No data available at the moment", rowKey = "key", loading = false, skeletonRows = 5, scrollHeight, stickyHeader = false, pageLabel = "page", rowSelection }) {
|
|
2004
2099
|
const [currentPage, setCurrentPage] = React.useState(1);
|
|
2005
2100
|
const [expandedRowKey, setExpandedRowKey] = React.useState(null);
|
|
2006
2101
|
const [sortConfig, setSortConfig] = React.useState({
|
|
@@ -2138,7 +2233,9 @@ function CwTable({ columns, data, pagination = false, pageSizeOptions = [5, 10,
|
|
|
2138
2233
|
};
|
|
2139
2234
|
const renderTableBody = () => {
|
|
2140
2235
|
if (loading) {
|
|
2141
|
-
|
|
2236
|
+
// Ghost rows: rendered outside the data/selection/expand code paths, so they
|
|
2237
|
+
// cannot trigger row click, selection or expansion.
|
|
2238
|
+
return Array.from({ length: normalizeSkeletonCount(skeletonRows, 5) }, (_, rowIndex) => (jsxRuntime.jsxs("tr", { children: [expandedRowRender && jsxRuntime.jsx("td", { className: "cw-table-col-action" }), columns.map((col, columnIndex) => (jsxRuntime.jsx("td", { className: col.className ?? "", children: jsxRuntime.jsx(CwSkeleton, { variant: "text", width: getSkeletonCellWidth(rowIndex, columnIndex, columns.length) }) }, col.key)))] }, `skeleton_${rowIndex}`)));
|
|
2142
2239
|
}
|
|
2143
2240
|
if (!paginatedData || paginatedData.length === 0) {
|
|
2144
2241
|
return (jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { colSpan: getColSpan(), className: "cw-table-cell-empty", style: { textAlign: "center" }, children: textNoData }) }));
|
|
@@ -2160,7 +2257,7 @@ function CwTable({ columns, data, pagination = false, pageSizeOptions = [5, 10,
|
|
|
2160
2257
|
: "cwi-chevron-right"}` }) })), columns.map(col => (jsxRuntime.jsx("td", { className: col.className ?? "", children: col.render ? col.render(item) : col.dataIndex ? String(item[col.dataIndex] ?? "") : "" }, `${itemKey}_${col.key}`)))] }), expandedRowRender && expandedRowKey === itemKey && (jsxRuntime.jsx("tr", { className: "cw-table-row-expanded", children: jsxRuntime.jsx("td", { colSpan: getColSpan(), children: expandedRowRender(item) }) }))] }, String(itemKey)));
|
|
2161
2258
|
});
|
|
2162
2259
|
};
|
|
2163
|
-
return (jsxRuntime.jsxs("div", { id: id, "data-testid": testId, className: `cw-table-container${stickyHeader || scrollHeight ? " cw-table-scroll" : ""} ${classNameContainer ?? ""}`, style: { ...(scrollHeight ? { "--table-height": typeof scrollHeight === "number" ? `${scrollHeight}px` : scrollHeight } : {}), ...style }, children: [jsxRuntime.jsxs("table", { className: `cw-table ${className ?? ""}`, style: { width: "100%" }, children: [jsxRuntime.jsx("thead", { children: jsxRuntime.jsxs("tr", { children: [expandedRowRender && jsxRuntime.jsx("th", {}), columns.map(col => (jsxRuntime.jsxs("th", { onClick: () => col.sortable && col.dataIndex && handleSort(col.dataIndex), className: `${col.className ?? ""} ${sortConfig.key === col.dataIndex
|
|
2260
|
+
return (jsxRuntime.jsxs("div", { id: id, "data-testid": testId, className: `cw-table-container${stickyHeader || scrollHeight ? " cw-table-scroll" : ""} ${classNameContainer ?? ""}`, style: { ...(scrollHeight ? { "--table-height": typeof scrollHeight === "number" ? `${scrollHeight}px` : scrollHeight } : {}), ...style }, "aria-busy": loading || undefined, children: [jsxRuntime.jsxs("table", { className: `cw-table ${className ?? ""}`, style: { width: "100%" }, children: [jsxRuntime.jsx("thead", { children: jsxRuntime.jsxs("tr", { children: [expandedRowRender && jsxRuntime.jsx("th", {}), columns.map(col => (jsxRuntime.jsxs("th", { onClick: () => col.sortable && col.dataIndex && handleSort(col.dataIndex), className: `${col.className ?? ""} ${sortConfig.key === col.dataIndex
|
|
2164
2261
|
? sortConfig.direction
|
|
2165
2262
|
: ""}`.trim(), style: {
|
|
2166
2263
|
cursor: col.sortable ? "pointer" : "default",
|
|
@@ -2186,7 +2283,7 @@ function CwTable({ columns, data, pagination = false, pageSizeOptions = [5, 10,
|
|
|
2186
2283
|
}, min: 1, max: totalPages }), jsxRuntime.jsx("span", { children: "/" }), jsxRuntime.jsx("span", { children: totalPages }), jsxRuntime.jsx(CwButton, { onClick: () => handlePageChange(currentPage + 1), disabled: currentPage === totalPages || totalPages <= 1, variant: "icon", icon: "chevron-right" }), jsxRuntime.jsx(CwButton, { onClick: () => handlePageChange(totalPages), disabled: currentPage === totalPages || totalPages <= 1, variant: "icon", icon: "chevron-right-double" })] })] }))] }));
|
|
2187
2284
|
}
|
|
2188
2285
|
|
|
2189
|
-
var styles$
|
|
2286
|
+
var styles$o = {"dropIndicator":"cw-sortable-table-module__dropIndicator__ov-Jz","dragging":"cw-sortable-table-module__dragging__MrLrz","saveBar":"cw-sortable-table-module__saveBar__3OdoZ cw-flex-row cw-align-center-center cw-gap-small"};
|
|
2190
2287
|
|
|
2191
2288
|
/**
|
|
2192
2289
|
* Hook that provides state management for CwSortableTable.
|
|
@@ -2249,9 +2346,14 @@ function useSortableTable(initialItems) {
|
|
|
2249
2346
|
}
|
|
2250
2347
|
|
|
2251
2348
|
// ─── Drop indicator row ───────────────────────────────────────────────────────
|
|
2252
|
-
const DropIndicatorRow = ({ colSpan }) => (jsxRuntime.jsx("tr", { className: styles$
|
|
2349
|
+
const DropIndicatorRow = ({ colSpan }) => (jsxRuntime.jsx("tr", { className: styles$o.dropIndicator, "aria-hidden": true, children: jsxRuntime.jsx("td", { colSpan: colSpan, children: jsxRuntime.jsx("div", {}) }) }));
|
|
2253
2350
|
// ─── Loading skeleton ─────────────────────────────────────────────────────────
|
|
2254
|
-
|
|
2351
|
+
// Plain td cells (no local class): the ghost cells get the same global cw-table
|
|
2352
|
+
// padding as real body cells, so row heights match the loaded rows exactly.
|
|
2353
|
+
// One cell per real column, so column classNames/widths apply to the ghost too.
|
|
2354
|
+
function LoadingRows({ columns, showHandle, skeletonRows }) {
|
|
2355
|
+
return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: Array.from({ length: skeletonRows }).map((_, rowIndex) => (jsxRuntime.jsxs("tr", { children: [showHandle && jsxRuntime.jsx("td", { className: "cw-table-col-action" }), columns.map((col, columnIndex) => (jsxRuntime.jsx("td", { className: col.className ?? "", style: col.width ? { width: col.width } : undefined, children: jsxRuntime.jsx(CwSkeleton, { variant: "text", width: getSkeletonCellWidth(rowIndex, columnIndex, columns.length) }) }, col.key)))] }, rowIndex))) }));
|
|
2356
|
+
}
|
|
2255
2357
|
// ─── Component ────────────────────────────────────────────────────────────────
|
|
2256
2358
|
/**
|
|
2257
2359
|
* CwSortableTable
|
|
@@ -2268,7 +2370,7 @@ const LoadingRows = ({ colSpan }) => (jsxRuntime.jsx(jsxRuntime.Fragment, { chil
|
|
|
2268
2370
|
* - Reorder is calculated in onDragEnd using lastValidDropIndex
|
|
2269
2371
|
* - draggedItem is tracked in state, not via dataTransfer
|
|
2270
2372
|
*/
|
|
2271
|
-
function CwSortableTable({ columns, data, rowKey = "key", onReorder, loading = false, textNoData = "No data available", className, tableClassName, maxHeight, showHandle = true, style, saveLabel = "Save order", discardLabel = "Discard", }) {
|
|
2373
|
+
function CwSortableTable({ columns, data, rowKey = "key", onReorder, loading = false, skeletonRows = 5, textNoData = "No data available", className, tableClassName, maxHeight, showHandle = true, style, saveLabel = "Save order", discardLabel = "Discard", }) {
|
|
2272
2374
|
const { items, hasChanges, handleReorder, handleSave, handleDiscard, } = useSortableTable(data);
|
|
2273
2375
|
// Drag state lives in the component, same as CwSortableList
|
|
2274
2376
|
const [draggedItem, setDraggedItem] = React.useState(null);
|
|
@@ -2287,11 +2389,15 @@ function CwSortableTable({ columns, data, rowKey = "key", onReorder, loading = f
|
|
|
2287
2389
|
setLastValidDropIndex(null);
|
|
2288
2390
|
};
|
|
2289
2391
|
const handleDragStart = (e, item) => {
|
|
2392
|
+
if (loading)
|
|
2393
|
+
return;
|
|
2290
2394
|
setDraggedItem(item);
|
|
2291
2395
|
setLastValidDropIndex(null);
|
|
2292
2396
|
e.dataTransfer.effectAllowed = "move";
|
|
2293
2397
|
};
|
|
2294
2398
|
const handleDragOver = (e, index) => {
|
|
2399
|
+
if (loading)
|
|
2400
|
+
return;
|
|
2295
2401
|
e.preventDefault();
|
|
2296
2402
|
if (!draggedItem)
|
|
2297
2403
|
return;
|
|
@@ -2304,6 +2410,11 @@ function CwSortableTable({ columns, data, rowKey = "key", onReorder, loading = f
|
|
|
2304
2410
|
}
|
|
2305
2411
|
};
|
|
2306
2412
|
const handleDragEnd = () => {
|
|
2413
|
+
// Never persist a reorder computed against stale/ghost data while loading.
|
|
2414
|
+
if (loading) {
|
|
2415
|
+
cleanupDragState();
|
|
2416
|
+
return;
|
|
2417
|
+
}
|
|
2307
2418
|
if (draggedItem && lastValidDropIndex !== null) {
|
|
2308
2419
|
const dragIndex = items.findIndex(item => item[rowKey] === draggedItem[rowKey]);
|
|
2309
2420
|
if (dragIndex !== lastValidDropIndex && dragIndex !== lastValidDropIndex - 1) {
|
|
@@ -2330,7 +2441,7 @@ function CwSortableTable({ columns, data, rowKey = "key", onReorder, loading = f
|
|
|
2330
2441
|
};
|
|
2331
2442
|
const renderBody = () => {
|
|
2332
2443
|
if (loading) {
|
|
2333
|
-
return jsxRuntime.jsx(LoadingRows, {
|
|
2444
|
+
return jsxRuntime.jsx(LoadingRows, { columns: columns, showHandle: showHandle, skeletonRows: normalizeSkeletonCount(skeletonRows, 5) });
|
|
2334
2445
|
}
|
|
2335
2446
|
if (!items || items.length === 0) {
|
|
2336
2447
|
return (jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { colSpan: totalCols, className: "cw-table-cell-empty", style: { textAlign: "center" }, children: textNoData }) }));
|
|
@@ -2338,11 +2449,11 @@ function CwSortableTable({ columns, data, rowKey = "key", onReorder, loading = f
|
|
|
2338
2449
|
return items.map((item, index) => {
|
|
2339
2450
|
const key = item[rowKey];
|
|
2340
2451
|
const isDragging = draggedItem?.[rowKey] === key;
|
|
2341
|
-
return (jsxRuntime.jsxs(React.Fragment, { children: [dropIndicatorIndex === index && (jsxRuntime.jsx(DropIndicatorRow, { colSpan: totalCols })), jsxRuntime.jsxs("tr", { draggable: true, onDragStart: (e) => handleDragStart(e, item), onDragOver: (e) => handleDragOver(e, index), onDragEnd: handleDragEnd, className: isDragging ? styles$
|
|
2452
|
+
return (jsxRuntime.jsxs(React.Fragment, { children: [dropIndicatorIndex === index && (jsxRuntime.jsx(DropIndicatorRow, { colSpan: totalCols })), jsxRuntime.jsxs("tr", { draggable: true, onDragStart: (e) => handleDragStart(e, item), onDragOver: (e) => handleDragOver(e, index), onDragEnd: handleDragEnd, className: isDragging ? styles$o.dragging : "", children: [showHandle && (jsxRuntime.jsx("td", { className: "cw-table-col-action", children: jsxRuntime.jsx(CwIcon, { iconId: "grip-dots", color: "neutral", style: { opacity: 0.75 } }) })), columns.map(col => (jsxRuntime.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 && (jsxRuntime.jsx(DropIndicatorRow, { colSpan: totalCols }))] }, String(key)));
|
|
2342
2453
|
});
|
|
2343
2454
|
};
|
|
2344
2455
|
// ── Render ──────────────────────────────────────────────────────────────
|
|
2345
|
-
return (jsxRuntime.jsxs("div", { className: `cw-table-container ${className ?? ""}`, style: containerStyle, children: [jsxRuntime.jsxs("table", { className: `cw-table cw-sortable-table ${tableClassName ?? ""}`, style: { width: "100%" }, children: [jsxRuntime.jsx("thead", { children: jsxRuntime.jsxs("tr", { children: [showHandle && jsxRuntime.jsx("th", { className: "cw-table-col-action" }), columns.map(col => (jsxRuntime.jsx("th", { className: col.className ?? "", style: col.width ? { width: col.width, minWidth: 50 } : undefined, children: col.title }, col.key)))] }) }), jsxRuntime.jsx("tbody", { children: renderBody() })] }), hasChanges && (jsxRuntime.jsxs("footer", { className: styles$
|
|
2456
|
+
return (jsxRuntime.jsxs("div", { className: `cw-table-container ${className ?? ""}`, style: containerStyle, "aria-busy": loading || undefined, children: [jsxRuntime.jsxs("table", { className: `cw-table cw-sortable-table ${tableClassName ?? ""}`, style: { width: "100%" }, children: [jsxRuntime.jsx("thead", { children: jsxRuntime.jsxs("tr", { children: [showHandle && jsxRuntime.jsx("th", { className: "cw-table-col-action" }), columns.map(col => (jsxRuntime.jsx("th", { className: col.className ?? "", style: col.width ? { width: col.width, minWidth: 50 } : undefined, children: col.title }, col.key)))] }) }), jsxRuntime.jsx("tbody", { children: renderBody() })] }), !loading && hasChanges && (jsxRuntime.jsxs("footer", { className: styles$o.saveBar, children: [jsxRuntime.jsx(CwButton, { variant: "outline", color: "neutral", icon: "undo", text: discardLabel, onClick: handleDiscard }), jsxRuntime.jsx(CwButton, { variant: "solid", color: "primary", icon: "save", text: saveLabel, onClick: () => handleSave(onReorder) })] }))] }));
|
|
2346
2457
|
}
|
|
2347
2458
|
|
|
2348
2459
|
/**
|
|
@@ -2398,7 +2509,7 @@ function CwSortableTable({ columns, data, rowKey = "key", onReorder, loading = f
|
|
|
2398
2509
|
*
|
|
2399
2510
|
* @returns React component
|
|
2400
2511
|
*/
|
|
2401
|
-
function CwTableServerSide({ columns, data, totalItems, pagination = false, pageSizeOptions = [5, 10, 20, 50], pageLabel = "page", expandedRowRender, onExpand, className, classNameRow, style, classNameContainer, id, testId, textNoData = "No data available at the moment", rowKey = "key", loading = false, scrollHeight, stickyHeader = false, rowSelection, onChange, serverState, }) {
|
|
2512
|
+
function CwTableServerSide({ columns, data, totalItems, pagination = false, pageSizeOptions = [5, 10, 20, 50], pageLabel = "page", expandedRowRender, onExpand, className, classNameRow, style, classNameContainer, id, testId, textNoData = "No data available at the moment", rowKey = "key", loading = false, skeletonRows = 5, scrollHeight, stickyHeader = false, rowSelection, onChange, serverState, }) {
|
|
2402
2513
|
const [internalState, setInternalState] = React.useState({
|
|
2403
2514
|
page: 1,
|
|
2404
2515
|
pageSize: pageSizeOptions[0],
|
|
@@ -2499,7 +2610,9 @@ function CwTableServerSide({ columns, data, totalItems, pagination = false, page
|
|
|
2499
2610
|
};
|
|
2500
2611
|
const renderTableBody = () => {
|
|
2501
2612
|
if (loading) {
|
|
2502
|
-
|
|
2613
|
+
// Ghost rows: rendered outside the data/selection/expand code paths, so they
|
|
2614
|
+
// cannot trigger row click, selection or expansion.
|
|
2615
|
+
return Array.from({ length: normalizeSkeletonCount(skeletonRows, 5) }, (_, rowIndex) => (jsxRuntime.jsxs("tr", { children: [expandedRowRender && jsxRuntime.jsx("td", { className: "cw-table-col-action" }), columns.map((col, columnIndex) => (jsxRuntime.jsx("td", { className: col.className ?? "", children: jsxRuntime.jsx(CwSkeleton, { variant: "text", width: getSkeletonCellWidth(rowIndex, columnIndex, columns.length) }) }, col.key)))] }, `skeleton_${rowIndex}`)));
|
|
2503
2616
|
}
|
|
2504
2617
|
if (!data || data.length === 0) {
|
|
2505
2618
|
return (jsxRuntime.jsx("tr", { children: jsxRuntime.jsx("td", { colSpan: getColSpan(), className: "cw-table-cell-empty", style: { textAlign: "center" }, children: textNoData }) }));
|
|
@@ -2517,7 +2630,7 @@ function CwTableServerSide({ columns, data, totalItems, pagination = false, page
|
|
|
2517
2630
|
}, children: [expandedRowRender && (jsxRuntime.jsx("td", { className: "cw-table-col-action cw-table-col-expand", children: jsxRuntime.jsx("button", { onClick: () => handleRowExpand(item), className: `cw-button-icon ${expandedRowKey === itemKey ? "cwi-chevron-down" : "cwi-chevron-right"}` }) })), columns.map((col) => (jsxRuntime.jsx("td", { className: col.className ?? "", children: col.render ? col.render(item) : col.dataIndex ? String(item[col.dataIndex] ?? "") : "" }, `${itemKey}_${col.key}`)))] }), expandedRowRender && expandedRowKey === itemKey && (jsxRuntime.jsx("tr", { className: "cw-table-row-expanded", children: jsxRuntime.jsx("td", { colSpan: getColSpan(), children: expandedRowRender(item) }) }))] }, String(itemKey)));
|
|
2518
2631
|
});
|
|
2519
2632
|
};
|
|
2520
|
-
return (jsxRuntime.jsxs("div", { id: id, "data-testid": testId, className: `cw-table-container${stickyHeader || scrollHeight ? " cw-table-scroll" : ""} ${classNameContainer ?? ""}`, style: { ...(scrollHeight ? { "--table-height": typeof scrollHeight === "number" ? `${scrollHeight}px` : scrollHeight } : {}), ...style }, children: [jsxRuntime.jsxs("table", { className: `cw-table ${className ?? ""}`, style: { width: "100%" }, children: [jsxRuntime.jsx("thead", { children: jsxRuntime.jsxs("tr", { children: [expandedRowRender && jsxRuntime.jsx("th", {}), columns.map((col) => (jsxRuntime.jsxs("th", { onClick: () => col.sortable && col.dataIndex && handleSort(col.dataIndex), className: `${col.className ?? ""} ${state.sortKey === col.dataIndex ? state.sortDirection : ""}`.trim(), style: {
|
|
2633
|
+
return (jsxRuntime.jsxs("div", { id: id, "data-testid": testId, className: `cw-table-container${stickyHeader || scrollHeight ? " cw-table-scroll" : ""} ${classNameContainer ?? ""}`, style: { ...(scrollHeight ? { "--table-height": typeof scrollHeight === "number" ? `${scrollHeight}px` : scrollHeight } : {}), ...style }, "aria-busy": loading || undefined, children: [jsxRuntime.jsxs("table", { className: `cw-table ${className ?? ""}`, style: { width: "100%" }, children: [jsxRuntime.jsx("thead", { children: jsxRuntime.jsxs("tr", { children: [expandedRowRender && jsxRuntime.jsx("th", {}), columns.map((col) => (jsxRuntime.jsxs("th", { onClick: () => col.sortable && col.dataIndex && handleSort(col.dataIndex), className: `${col.className ?? ""} ${state.sortKey === col.dataIndex ? state.sortDirection : ""}`.trim(), style: {
|
|
2521
2634
|
cursor: col.sortable ? "pointer" : "default",
|
|
2522
2635
|
userSelect: "none",
|
|
2523
2636
|
width: columnWidths[col.key] ?? col.width,
|
|
@@ -2541,7 +2654,7 @@ function CwTableServerSide({ columns, data, totalItems, pagination = false, page
|
|
|
2541
2654
|
}, min: 1, max: totalPages }), jsxRuntime.jsx("span", { children: "/" }), jsxRuntime.jsx("span", { children: totalPages }), jsxRuntime.jsx(CwButton, { onClick: () => handlePageChange(state.page + 1), disabled: state.page === totalPages || totalPages <= 1, variant: "icon", icon: "chevron-right" }), jsxRuntime.jsx(CwButton, { onClick: () => handlePageChange(totalPages), disabled: state.page === totalPages || totalPages <= 1, variant: "icon", icon: "chevron-right-double" })] })] }))] }));
|
|
2542
2655
|
}
|
|
2543
2656
|
|
|
2544
|
-
var styles$
|
|
2657
|
+
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"};
|
|
2545
2658
|
|
|
2546
2659
|
const TabIcon = ({ icon }) => {
|
|
2547
2660
|
if (!icon)
|
|
@@ -2591,7 +2704,7 @@ function CwTabs(CwTabsProps) {
|
|
|
2591
2704
|
const tabsListStyle = position === 'left' && CwTabsProps.tabsListWidth
|
|
2592
2705
|
? { minWidth: CwTabsProps.tabsListWidth }
|
|
2593
2706
|
: undefined;
|
|
2594
|
-
return (jsxRuntime.jsxs("div", { id: CwTabsProps.id, "data-testid": CwTabsProps.testId, className: styles$
|
|
2707
|
+
return (jsxRuntime.jsxs("div", { id: CwTabsProps.id, "data-testid": CwTabsProps.testId, className: styles$n['cw-tabs'] + (CwTabsProps.className ? ` ${CwTabsProps.className}` : "") + "", style: CwTabsProps.style, "data-tabs-position": position, children: [jsxRuntime.jsx("ul", { style: tabsListStyle, children: CwTabsProps.tabs.map(tab => (jsxRuntime.jsxs("li", { className: `${tab.key === activeTab ? "cw-tab-active" : ""}`, onClick: () => handleTabClick(tab), "data-active": tab.key === activeTab, "data-tab-key": tab.key, children: [jsxRuntime.jsx(TabIcon, { icon: tab.icon }), tab.title, (tab.badge !== undefined || tab.badgeColor) && (jsxRuntime.jsx("span", { className: styles$n['badge'], style: tab.badgeColor ? { backgroundColor: tab.badgeColor, color: getContrastColor(tab.badgeColor) } : undefined, children: tab.badge }))] }, tab.key))) }), jsxRuntime.jsx("div", { className: styles$n['cw-tabs-content'], "data-active-tab-key": activeTab ?? undefined, style: CwTabsProps.contentHeight ? { '--tabs-height': CwTabsProps.contentHeight } : undefined, children: activeTab !== null && CwTabsProps.tabs.find(tab => tab.key === activeTab)?.content })] }));
|
|
2595
2708
|
}
|
|
2596
2709
|
|
|
2597
2710
|
/**
|
|
@@ -2618,9 +2731,17 @@ const CwExpandable = ({ briefing, onToggle, onOpen, onClose, children, ...detail
|
|
|
2618
2731
|
return (jsxRuntime.jsxs("details", { ref: myRef, ...detailsProps, className: "cw-expandable", children: [jsxRuntime.jsx("summary", { children: briefing }), children && jsxRuntime.jsx("section", { children: children })] }));
|
|
2619
2732
|
};
|
|
2620
2733
|
|
|
2621
|
-
var styles$
|
|
2734
|
+
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","skeletonRow":"cw-master-detail-module__skeletonRow__6BUgt","detailSkeleton":"cw-master-detail-module__detailSkeleton__GcDS4","detail-empty":"cw-master-detail-module__detail-empty__KFScK"};
|
|
2622
2735
|
|
|
2623
|
-
|
|
2736
|
+
/*
|
|
2737
|
+
* Fixed rem widths for the ghosts: the master rows and detail panel size their
|
|
2738
|
+
* content freely, so a percentage-width skeleton would resolve to 100% of ~0 and
|
|
2739
|
+
* collapse to nothing. Fixed widths render regardless of layout. Cycled so rows do
|
|
2740
|
+
* not all look identical.
|
|
2741
|
+
*/
|
|
2742
|
+
const MASTER_TITLE_WIDTHS = ['9rem', '11rem', '8rem', '10rem'];
|
|
2743
|
+
const MASTER_SUBTITLE_WIDTH = '5rem';
|
|
2744
|
+
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, loading = false, skeletonRows = 5, }) => {
|
|
2624
2745
|
const [masterWidth, setMasterWidth] = React.useState(initialWidth);
|
|
2625
2746
|
const [isResizing, setIsResizing] = React.useState(false);
|
|
2626
2747
|
const containerRef = React.useRef(null);
|
|
@@ -2654,12 +2775,22 @@ const CwMasterDetail = ({ id, className, style, items, selectedKey, onSelect, de
|
|
|
2654
2775
|
document.body.style.userSelect = '';
|
|
2655
2776
|
};
|
|
2656
2777
|
}, [isResizing, minMasterWidth, maxMasterWidth]);
|
|
2657
|
-
const rootClassName = [styles$
|
|
2658
|
-
return (jsxRuntime.jsxs("div", { id: id, ref: containerRef, className: rootClassName, style: style, children: [jsxRuntime.jsxs("aside", { style: { width: masterWidth, minWidth: masterWidth }, children: [showSearch && (jsxRuntime.jsx("search", { children: jsxRuntime.jsx("input", { type: "text", placeholder: searchPlaceholder, onChange: (e) => onSearch?.(e.target.value) }) })), masterHeader && (jsxRuntime.jsx("header", { children: masterHeader })), jsxRuntime.jsx("ul", { children:
|
|
2778
|
+
const rootClassName = [styles$m['cw-master-detail'], className].filter(Boolean).join(' ');
|
|
2779
|
+
return (jsxRuntime.jsxs("div", { id: id, ref: containerRef, className: rootClassName, style: style, "aria-busy": loading || undefined, children: [jsxRuntime.jsxs("aside", { style: { width: masterWidth, minWidth: masterWidth }, children: [showSearch && (jsxRuntime.jsx("search", { children: jsxRuntime.jsx("input", { type: "text", placeholder: searchPlaceholder, onChange: (e) => onSearch?.(e.target.value) }) })), masterHeader && (jsxRuntime.jsx("header", { children: masterHeader })), jsxRuntime.jsx("ul", { children: loading
|
|
2780
|
+
? Array.from({ length: skeletonRows }, (_unused, rowIndex) => (jsxRuntime.jsxs("li", { "aria-hidden": "true", children: [jsxRuntime.jsx(CwSkeleton, { variant: "circle", height: "2rem" }), jsxRuntime.jsxs("div", { className: styles$m.skeletonRow, children: [jsxRuntime.jsx(CwSkeleton, { variant: "text", width: MASTER_TITLE_WIDTHS[rowIndex % MASTER_TITLE_WIDTHS.length] }), jsxRuntime.jsx(CwSkeleton, { variant: "text", width: MASTER_SUBTITLE_WIDTH })] })] }, `skeleton_${rowIndex}`)))
|
|
2781
|
+
: items.map((item) => (jsxRuntime.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 && (jsxRuntime.jsx("footer", { children: masterFooter }))] }), resizable && (jsxRuntime.jsx("div", { className: styles$m.resizer, "data-resizing": isResizing, onMouseDown: handleMouseDown })), jsxRuntime.jsx("section", { className: styles$m.detail, children: loading ? (jsxRuntime.jsxs("div", { className: styles$m.detailSkeleton, "aria-hidden": "true", children: [jsxRuntime.jsx(CwSkeleton, { variant: "text", width: "14rem", height: "1.5em" }), jsxRuntime.jsx(CwSkeleton, { variant: "text", width: "22rem" }), jsxRuntime.jsx(CwSkeleton, { variant: "text", width: "18rem" }), jsxRuntime.jsx(CwSkeleton, { variant: "text", width: "20rem" })] })) : selectedKey && detailContent
|
|
2659
2782
|
? detailContent
|
|
2660
|
-
: (jsxRuntime.jsx("div", { className: styles$
|
|
2783
|
+
: (jsxRuntime.jsx("div", { className: styles$m['detail-empty'], children: emptyDetail ?? 'Select an item to view details' })) })] }));
|
|
2661
2784
|
};
|
|
2662
2785
|
|
|
2786
|
+
/*
|
|
2787
|
+
* Fixed rem widths (not percentages): dt and dd size to their content in the list
|
|
2788
|
+
* item, so a percentage-width skeleton would resolve to 100% of ~0 and collapse to
|
|
2789
|
+
* nothing. Fixed widths are visible in both row (dt beside dd) and column (dt above
|
|
2790
|
+
* dd) item layouts. Cycled by row so keys and values do not all look identical.
|
|
2791
|
+
*/
|
|
2792
|
+
const SKELETON_KEY_WIDTHS = ["5rem", "6.5rem", "4.5rem", "6rem"];
|
|
2793
|
+
const SKELETON_VALUE_WIDTHS = ["8rem", "6rem", "9rem", "7rem"];
|
|
2663
2794
|
/**
|
|
2664
2795
|
* A component for displaying key-value pairs in a definition list format
|
|
2665
2796
|
* Used for read-only display of structured data
|
|
@@ -2673,16 +2804,23 @@ const CwMasterDetail = ({ id, className, style, items, selectedKey, onSelect, de
|
|
|
2673
2804
|
* emptyValue="N/A"
|
|
2674
2805
|
* />
|
|
2675
2806
|
*/
|
|
2676
|
-
const CwKeyValueList = ({ items, className = "", emptyValue = "-", direction = "row", groupLayout, itemLayout, ...htmlProps }) => {
|
|
2807
|
+
const CwKeyValueList = ({ items, className = "", emptyValue = "-", direction = "row", loading = false, skeletonRows = 4, groupLayout, itemLayout, ...htmlProps }) => {
|
|
2677
2808
|
const itemDirection = itemLayout?.direction ?? direction;
|
|
2678
|
-
|
|
2809
|
+
const renderItems = () => {
|
|
2810
|
+
if (loading) {
|
|
2811
|
+
// The whole list comes from one data load, so both key and value ghost.
|
|
2812
|
+
return Array.from({ length: skeletonRows }, (_unused, rowIndex) => (jsxRuntime.jsxs("div", { className: `cw-keyvalue-list-item cw-flex-${itemDirection}`, "data-align": itemLayout?.align, "data-justify": itemLayout?.justify, "data-gap": itemLayout?.gap, "aria-hidden": "true", children: [jsxRuntime.jsx("dt", { children: jsxRuntime.jsx(CwSkeleton, { variant: "text", width: SKELETON_KEY_WIDTHS[rowIndex % SKELETON_KEY_WIDTHS.length] }) }), jsxRuntime.jsx("dd", { children: jsxRuntime.jsx(CwSkeleton, { variant: "text", width: SKELETON_VALUE_WIDTHS[rowIndex % SKELETON_VALUE_WIDTHS.length] }) })] }, `skeleton_${rowIndex}`)));
|
|
2813
|
+
}
|
|
2814
|
+
return items.map(item => (jsxRuntime.jsxs("div", { className: `cw-keyvalue-list-item cw-flex-${itemDirection}`, "data-align": itemLayout?.align, "data-justify": itemLayout?.justify, "data-gap": itemLayout?.gap, children: [jsxRuntime.jsx("dt", { children: item.label }), jsxRuntime.jsx("dd", { children: item.value !== undefined && item.value !== null && item.value !== ""
|
|
2679
2815
|
? (React.isValidElement(item.value)
|
|
2680
2816
|
? item.value
|
|
2681
2817
|
: `${item.value}${item.suffix ? ` ${item.suffix}` : ''}`)
|
|
2682
|
-
: emptyValue })] }, item.key)))
|
|
2818
|
+
: emptyValue })] }, item.key)));
|
|
2819
|
+
};
|
|
2820
|
+
return (jsxRuntime.jsx("dl", { className: `cw-keyvalue-list ${className}`, "data-direction": groupLayout?.direction, "data-align": groupLayout?.align, "data-justify": groupLayout?.justify, "data-gap": groupLayout?.gap, "aria-busy": loading || undefined, ...htmlProps, children: renderItems() }));
|
|
2683
2821
|
};
|
|
2684
2822
|
|
|
2685
|
-
var styles$
|
|
2823
|
+
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"};
|
|
2686
2824
|
|
|
2687
2825
|
function CwSortableList({ items, onReorder, renderItem, className = '', movedItems = new Set(), emptyMessage = "No elements to show", readOnly = false, maxHeight = "300px", }) {
|
|
2688
2826
|
const [draggedItem, setDraggedItem] = React.useState(null);
|
|
@@ -2745,15 +2883,15 @@ function CwSortableList({ items, onReorder, renderItem, className = '', movedIte
|
|
|
2745
2883
|
}
|
|
2746
2884
|
};
|
|
2747
2885
|
if (items.length === 0) {
|
|
2748
|
-
return (jsxRuntime.jsx("div", { className: `${styles$
|
|
2886
|
+
return (jsxRuntime.jsx("div", { className: `${styles$l.sortableList} ${styles$l.emptyState} ${className}`, children: jsxRuntime.jsx("div", { className: styles$l.emptyMessage, children: emptyMessage }) }));
|
|
2749
2887
|
}
|
|
2750
|
-
return (jsxRuntime.jsx("div", { className: `${styles$
|
|
2888
|
+
return (jsxRuntime.jsx("div", { className: `${styles$l.sortableList} ${className}`, style: { maxHeight }, children: items.map((item, index) => {
|
|
2751
2889
|
const { title, extraContent, actions, showHandle = true, expandedContent } = renderItem(item);
|
|
2752
2890
|
const isDragging = draggedItem?.id === item.id;
|
|
2753
2891
|
const isMoved = movedItems.has(item.id);
|
|
2754
2892
|
const canExpand = Boolean(expandedContent);
|
|
2755
2893
|
const isExpanded = expandedItems.has(item.id);
|
|
2756
|
-
return (jsxRuntime.jsxs(React.Fragment, { children: [dropIndicatorIndex === index && jsxRuntime.jsx("div", { className: styles$
|
|
2894
|
+
return (jsxRuntime.jsxs(React.Fragment, { children: [dropIndicatorIndex === index && jsxRuntime.jsx("div", { className: styles$l.dropIndicator }), jsxRuntime.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: [jsxRuntime.jsxs("header", { children: [canExpand ? (jsxRuntime.jsx(CwButton, { variant: "icon", onClick: () => toggleExpanded(item.id), type: "button", title: isExpanded ? "Collapse" : "Expand", icon: isExpanded ? "chevron-up" : "chevron-down" })) : showHandle ? (jsxRuntime.jsx("div", { className: styles$l.sortableHandle, children: jsxRuntime.jsx(CwIcon, { iconId: "grip-dots" }) })) : null, jsxRuntime.jsxs("div", { className: styles$l.sortableContent, children: [jsxRuntime.jsx("div", { className: styles$l.sortableTitle, children: title }), extraContent && jsxRuntime.jsx("div", { className: styles$l.sortableExtraContent, children: extraContent })] }), jsxRuntime.jsx("div", { className: styles$l.sortableActions, children: actions })] }), isExpanded && expandedContent && (jsxRuntime.jsx("div", { className: styles$l.expandedContent, children: expandedContent }))] }), !readOnly && dropIndicatorIndex === items.length && index === items.length - 1 && (jsxRuntime.jsx("div", { className: styles$l.dropIndicator }))] }, item.id));
|
|
2757
2895
|
}) }));
|
|
2758
2896
|
}
|
|
2759
2897
|
|
|
@@ -2879,60 +3017,9 @@ const CwTableGrouped = props => {
|
|
|
2879
3017
|
group.rows.map((child, j) => (jsxRuntime.jsx("tr", { "data-row": true, "data-row-last-of-group": j == group.rows.length - 1, children: child.cells.map((cell, k) => (jsxRuntime.jsx("td", { children: cell.content }, k))) }, j)))] }, i))) }), jsxRuntime.jsx("tfoot", {})] }) }));
|
|
2880
3018
|
};
|
|
2881
3019
|
|
|
2882
|
-
|
|
2883
|
-
const [previewURL, setPreviewURL] = React.useState("");
|
|
2884
|
-
const [error, setError] = React.useState(null);
|
|
2885
|
-
const [_selectedFileName, setSelectedFileName] = React.useState("");
|
|
2886
|
-
const [_currentHexContent, setCurrentHexContent] = React.useState("");
|
|
2887
|
-
React.useEffect(() => {
|
|
2888
|
-
// If there is hexadecimal preview content, set the Preview URL
|
|
2889
|
-
if (fileUploadProps.file?.Bindata) {
|
|
2890
|
-
setPreviewURL(`data:image/png;base64,${fileUploadProps.file.Bindata}`);
|
|
2891
|
-
}
|
|
2892
|
-
}, [fileUploadProps.file?.Bindata]);
|
|
2893
|
-
const handleFileChange = (event) => {
|
|
2894
|
-
const file = event.target.files?.[0];
|
|
2895
|
-
setSelectedFileName(file?.name ?? "");
|
|
2896
|
-
if (file) {
|
|
2897
|
-
const allowedExts = fileUploadProps.accept.split(',').map(ext => ext.trim().replace('.', '').toLowerCase());
|
|
2898
|
-
const fileExt = file.name.split('.').pop()?.toLowerCase() ?? "";
|
|
2899
|
-
if (!allowedExts.includes(fileExt)) {
|
|
2900
|
-
setError(`Invalid file type. Only ${fileUploadProps.acceptString} files are allowed.`);
|
|
2901
|
-
setPreviewURL("");
|
|
2902
|
-
return;
|
|
2903
|
-
}
|
|
2904
|
-
setError(null);
|
|
2905
|
-
const reader = new FileReader();
|
|
2906
|
-
reader.onloadend = () => {
|
|
2907
|
-
if (typeof reader.result === "string") {
|
|
2908
|
-
const hexContent = arrayBufferToHex(reader.result);
|
|
2909
|
-
setCurrentHexContent(hexContent);
|
|
2910
|
-
setPreviewURL(reader.result);
|
|
2911
|
-
setCurrentHexContent(arrayBufferToHex(reader.result));
|
|
2912
|
-
// Call function to store hexadecimal content
|
|
2913
|
-
fileUploadProps.onSaveHexContent(arrayBufferToHex(reader.result));
|
|
2914
|
-
}
|
|
2915
|
-
};
|
|
2916
|
-
reader.readAsDataURL(file);
|
|
2917
|
-
}
|
|
2918
|
-
};
|
|
2919
|
-
// Function to convert the image buffer into hexadecimal content
|
|
2920
|
-
const arrayBufferToHex = (dataUrl) => {
|
|
2921
|
-
// Decodes the base64 of the URL data
|
|
2922
|
-
const base64 = dataUrl.split(",")[1];
|
|
2923
|
-
const binary = atob(base64);
|
|
2924
|
-
let hex = "";
|
|
2925
|
-
for (let i = 0; i < binary.length; i++) {
|
|
2926
|
-
hex += binary.charCodeAt(i).toString(16).padStart(2, "0");
|
|
2927
|
-
}
|
|
2928
|
-
return hex;
|
|
2929
|
-
};
|
|
2930
|
-
return (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsxs("div", { className: "row", children: [jsxRuntime.jsx("input", { className: "cw-button", type: "file", accept: fileUploadProps.accept, readOnly: true, placeholder: "No file selected...", onChange: handleFileChange }), previewURL && (jsxRuntime.jsx("div", { className: "row", children: jsxRuntime.jsx("img", { src: previewURL, alt: "Preview", style: { maxWidth: "200px", maxHeight: "200px" } }) }))] }), error && jsxRuntime.jsx("div", { className: "row error", children: error }), jsxRuntime.jsx("div", { className: "row", children: jsxRuntime.jsxs("label", { children: ["Please note: File/image has to be in ", fileUploadProps.acceptString, " format", fileUploadProps.sizeString && `, ${fileUploadProps.sizeString}`] }) })] }));
|
|
2931
|
-
}
|
|
2932
|
-
|
|
2933
|
-
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"};
|
|
3020
|
+
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"};
|
|
2934
3021
|
|
|
2935
|
-
const DEFAULT_LABELS = {
|
|
3022
|
+
const DEFAULT_LABELS$1 = {
|
|
2936
3023
|
uploadDisabled: 'Upload disabled',
|
|
2937
3024
|
clickToUpload: 'Click to upload or drag and drop',
|
|
2938
3025
|
acceptedFiles: (accept) => `Accepted files: ${accept}`,
|
|
@@ -2940,6 +3027,7 @@ const DEFAULT_LABELS = {
|
|
|
2940
3027
|
allTypesAccepted: 'All file types accepted',
|
|
2941
3028
|
changeFile: 'Change File',
|
|
2942
3029
|
clearAll: 'Clear all',
|
|
3030
|
+
upload: 'Upload',
|
|
2943
3031
|
addMoreFiles: 'Add More Files',
|
|
2944
3032
|
filesSelected: (count) => `${count} file${count !== 1 ? 's' : ''} selected`,
|
|
2945
3033
|
fileTooLarge: (name, maxSize) => `File "${name}" is too large. Maximum size allowed is ${maxSize}MB.`,
|
|
@@ -2947,11 +3035,38 @@ const DEFAULT_LABELS = {
|
|
|
2947
3035
|
invalidMimeType: (name, types) => `File "${name}" has an invalid MIME type. Allowed types: ${types}`,
|
|
2948
3036
|
alreadySelected: (name) => `File "${name}" is already selected.`,
|
|
2949
3037
|
};
|
|
3038
|
+
/**
|
|
3039
|
+
* Checks a file against an `accept` string (comma-separated tokens). A token can be a dotted
|
|
3040
|
+
* extension (".pdf"), an exact MIME type ("application/pdf"), a wildcard MIME ("image" + slash + "star"),
|
|
3041
|
+
* or a bare "star" / "star-slash-star" for anything. Returns true if the file matches ANY token
|
|
3042
|
+
* (or if `accept` is empty).
|
|
3043
|
+
*/
|
|
3044
|
+
function fileMatchesAccept(fileName, fileType, accept) {
|
|
3045
|
+
const tokens = accept.split(',').map(token => token.trim().toLowerCase()).filter(Boolean);
|
|
3046
|
+
if (tokens.length === 0) {
|
|
3047
|
+
return true;
|
|
3048
|
+
}
|
|
3049
|
+
const fileExtension = '.' + (fileName.split('.').pop()?.toLowerCase() ?? '');
|
|
3050
|
+
const mimeType = fileType.toLowerCase();
|
|
3051
|
+
return tokens.some(token => {
|
|
3052
|
+
if (token === '*' || token === '*/*') {
|
|
3053
|
+
return true;
|
|
3054
|
+
}
|
|
3055
|
+
if (token.startsWith('.')) {
|
|
3056
|
+
return token === fileExtension;
|
|
3057
|
+
}
|
|
3058
|
+
if (token.endsWith('/*')) {
|
|
3059
|
+
const prefix = token.slice(0, token.indexOf('/') + 1);
|
|
3060
|
+
return mimeType.startsWith(prefix);
|
|
3061
|
+
}
|
|
3062
|
+
return token === mimeType;
|
|
3063
|
+
});
|
|
3064
|
+
}
|
|
2950
3065
|
function CwFileUploadMultiple(fileUploadProps) {
|
|
2951
3066
|
const fileInputRef = React.useRef(null);
|
|
2952
3067
|
const [selectedFiles, setSelectedFiles] = React.useState([]);
|
|
2953
3068
|
const [existingFile, setExistingFile] = React.useState(fileUploadProps.initialFileName);
|
|
2954
|
-
const labels = { ...DEFAULT_LABELS, ...fileUploadProps.labels };
|
|
3069
|
+
const labels = { ...DEFAULT_LABELS$1, ...fileUploadProps.labels };
|
|
2955
3070
|
React.useEffect(() => {
|
|
2956
3071
|
setExistingFile(fileUploadProps.initialFileName);
|
|
2957
3072
|
}, [fileUploadProps.initialFileName]);
|
|
@@ -2969,17 +3084,9 @@ function CwFileUploadMultiple(fileUploadProps) {
|
|
|
2969
3084
|
};
|
|
2970
3085
|
}
|
|
2971
3086
|
}
|
|
2972
|
-
// Validate file type
|
|
3087
|
+
// Validate file type against accept (dotted extensions, exact MIME, wildcard MIME, or *)
|
|
2973
3088
|
if (fileUploadProps.accept) {
|
|
2974
|
-
|
|
2975
|
-
const fileExtension = '.' + file.name.split('.').pop()?.toLowerCase();
|
|
2976
|
-
const isExtensionValid = acceptedExtensions.some(ext => {
|
|
2977
|
-
if (ext.startsWith('.')) {
|
|
2978
|
-
return ext === fileExtension;
|
|
2979
|
-
}
|
|
2980
|
-
return false;
|
|
2981
|
-
});
|
|
2982
|
-
if (!isExtensionValid) {
|
|
3089
|
+
if (!fileMatchesAccept(file.name, file.type, fileUploadProps.accept)) {
|
|
2983
3090
|
return {
|
|
2984
3091
|
isValid: false,
|
|
2985
3092
|
error: labels.invalidFormat(file.name, fileUploadProps.accept)
|
|
@@ -3004,7 +3111,7 @@ function CwFileUploadMultiple(fileUploadProps) {
|
|
|
3004
3111
|
const errors = [];
|
|
3005
3112
|
for (const file of fileArray) {
|
|
3006
3113
|
// Check if the file already exists (by name and size)
|
|
3007
|
-
const isDuplicate =
|
|
3114
|
+
const isDuplicate = validFiles.some(existingFile => existingFile.name === file.name && existingFile.size === file.size);
|
|
3008
3115
|
if (isDuplicate) {
|
|
3009
3116
|
errors.push(labels.alreadySelected(file.name));
|
|
3010
3117
|
continue;
|
|
@@ -3022,8 +3129,7 @@ function CwFileUploadMultiple(fileUploadProps) {
|
|
|
3022
3129
|
fileUploadProps.onError(errors.join('\n'));
|
|
3023
3130
|
}
|
|
3024
3131
|
else {
|
|
3025
|
-
|
|
3026
|
-
alert(errors.join('\n')); // Fallback if there is no onError
|
|
3132
|
+
CwDisplayMessage(errors.join('\n'), exports.CwMessageType.ERROR);
|
|
3027
3133
|
}
|
|
3028
3134
|
}
|
|
3029
3135
|
// If not multiple, only take the first valid file (replace)
|
|
@@ -3097,12 +3203,20 @@ function CwFileUploadMultiple(fileUploadProps) {
|
|
|
3097
3203
|
}
|
|
3098
3204
|
}
|
|
3099
3205
|
};
|
|
3100
|
-
return (jsxRuntime.jsxs("div", { className: `${styles$
|
|
3206
|
+
return (jsxRuntime.jsxs("div", { className: `${styles$k.fileUploadContainer} ${fileUploadProps.className}`, children: [jsxRuntime.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 ? (jsxRuntime.jsxs("div", { className: `${styles$k.uploadArea} ${fileUploadProps.disabled ? styles$k.uploadAreaDisabled : ''}`, onDragOver: handleDragOver, onDrop: handleDrop, onClick: !fileUploadProps.disabled ? handleButtonClick : undefined, children: [jsxRuntime.jsx(CwIcon, { iconId: "upload" }), jsxRuntime.jsx("p", { className: `${styles$k.uploadTitle}`, children: fileUploadProps.disabled ? labels.uploadDisabled : labels.clickToUpload }), jsxRuntime.jsxs("p", { className: `${styles$k.uploadSubtitle}`, children: [fileUploadProps.accept ? labels.acceptedFiles(fileUploadProps.accept) : labels.allTypesAccepted, !fileUploadProps.multiple && ` ${labels.singleFileOnly}`] })] })) : selectedFiles.length === 0 && existingFile ? (jsxRuntime.jsxs("div", { className: styles$k.filesContainer, children: [jsxRuntime.jsxs("div", { className: styles$k.fileItem, children: [jsxRuntime.jsxs("div", { className: styles$k.fileIcon, children: [jsxRuntime.jsx(CwIcon, { iconId: "page" }), jsxRuntime.jsx("span", { className: styles$k.fileExtension, children: getFileExtension(existingFile) })] }), jsxRuntime.jsx("div", { className: styles$k.fileInfo, children: jsxRuntime.jsx("p", { className: styles$k.fileName, children: existingFile }) }), jsxRuntime.jsx(CwButton, { variant: "icon", icon: "close", color: "neutral", onClick: () => {
|
|
3101
3207
|
setExistingFile(undefined);
|
|
3102
3208
|
if (fileUploadProps.onSelect) {
|
|
3103
3209
|
fileUploadProps.onSelect(null);
|
|
3104
3210
|
}
|
|
3105
|
-
}, disabled: fileUploadProps.disabled, className: styles$
|
|
3211
|
+
}, disabled: fileUploadProps.disabled, className: styles$k.smallButton })] }), jsxRuntime.jsx(CwButton, { text: labels.changeFile, icon: "refresh", onClick: handleButtonClick, disabled: fileUploadProps.disabled })] })) : (jsxRuntime.jsxs("div", { className: styles$k.filesContainer, children: [jsxRuntime.jsxs("header", { className: "cw-flex-row cw-align-between-center cw-flex-wrap", children: [jsxRuntime.jsx("small", { className: styles$k.filesCount, children: fileUploadProps.statusText ?? labels.filesSelected(selectedFiles.length) }), jsxRuntime.jsxs("div", { className: "cw-flex-row", children: [fileUploadProps.onConfirm && selectedFiles.length > 0 && (jsxRuntime.jsx(CwButton, { onClick: () => {
|
|
3212
|
+
let files = fileInputRef.current?.files ?? null;
|
|
3213
|
+
if (!files) {
|
|
3214
|
+
const dataTransfer = new DataTransfer();
|
|
3215
|
+
selectedFiles.forEach(file => dataTransfer.items.add(file));
|
|
3216
|
+
files = dataTransfer.files;
|
|
3217
|
+
}
|
|
3218
|
+
fileUploadProps.onConfirm?.(files);
|
|
3219
|
+
}, disabled: fileUploadProps.disabled || fileUploadProps.confirmDisabled, icon: "upload", text: fileUploadProps.confirmLabel ?? labels.upload })), !fileUploadProps.hideClearAll && (jsxRuntime.jsx(CwButton, { onClick: removeAllFiles, disabled: fileUploadProps.disabled, color: "danger", variant: "outline", icon: "delete", text: labels.clearAll }))] })] }), selectedFiles.map((file, index) => (jsxRuntime.jsxs("div", { className: styles$k.fileItem, children: [jsxRuntime.jsxs("div", { className: styles$k.fileIcon, children: [jsxRuntime.jsx(CwIcon, { iconId: "page" }), jsxRuntime.jsx("span", { className: styles$k.fileExtension, children: getFileExtension(file.name) })] }), jsxRuntime.jsxs("div", { className: styles$k.fileInfo, children: [jsxRuntime.jsx("p", { className: styles$k.fileName, children: file.name }), jsxRuntime.jsxs("p", { className: styles$k.fileSize, children: [(file.size / 1024).toFixed(1), " KB"] })] }), jsxRuntime.jsx(CwButton, { variant: "icon", icon: "close", color: "neutral", onClick: () => removeFile(index), className: styles$k.smallButton })] }, `${file.name}-${file.size}`))), fileUploadProps.multiple && (jsxRuntime.jsx(CwButton, { text: labels.addMoreFiles, icon: "plus", variant: "outline", onClick: handleButtonClick, disabled: fileUploadProps.disabled })), !fileUploadProps.multiple && (jsxRuntime.jsx(CwButton, { text: labels.changeFile, icon: "refresh", onClick: handleButtonClick, disabled: fileUploadProps.disabled }))] }))] }));
|
|
3106
3220
|
}
|
|
3107
3221
|
|
|
3108
3222
|
function CwInput(CwInputProps) {
|
|
@@ -3143,7 +3257,7 @@ function CwDigit(props) {
|
|
|
3143
3257
|
return (jsxRuntime.jsx("div", { className: "cw-input-text", children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: inputProps.required === true ? "required" : "", children: [labelProps && (jsxRuntime.jsxs(CwLabel, { ...labelProps, children: [iconProps && jsxRuntime.jsx(CwIcon, { ...iconProps }), labelProps.text] })), jsxRuntime.jsx("input", { type: "number", ...inputProps }), buttonProps && jsxRuntime.jsx(CwButton, { ...buttonProps })] }) }));
|
|
3144
3258
|
}
|
|
3145
3259
|
|
|
3146
|
-
var styles$
|
|
3260
|
+
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"};
|
|
3147
3261
|
|
|
3148
3262
|
const CwColorPicker = ({ initialColor, onChange, previewText = "Color preview" }) => {
|
|
3149
3263
|
const [rgb, setRgb] = React.useState({ r: 255, g: 255, b: 255 });
|
|
@@ -3346,13 +3460,13 @@ const CwColorPicker = ({ initialColor, onChange, previewText = "Color preview" }
|
|
|
3346
3460
|
// Calculate background color for the main area based on current hue
|
|
3347
3461
|
const hueColor = hsvToRgb(hsv.h, 100, 100);
|
|
3348
3462
|
const hueHex = rgbToHex(hueColor.r, hueColor.g, hueColor.b);
|
|
3349
|
-
return (jsxRuntime.jsxs("div", { className: "cw-flex-column cw-gap-small", children: [jsxRuntime.jsxs("div", { className: "cw-flex-row cw-align-between-center cw-gap-small", children: [jsxRuntime.jsx("div", { className: styles$
|
|
3463
|
+
return (jsxRuntime.jsxs("div", { className: "cw-flex-column cw-gap-small", children: [jsxRuntime.jsxs("div", { className: "cw-flex-row cw-align-between-center cw-gap-small", children: [jsxRuntime.jsx("div", { className: styles$j.colorPreview, style: { backgroundColor: hexColor, color: getContrastColor(hexColor) }, children: previewText }), jsxRuntime.jsx("button", { type: "button", className: "cw-button", onClick: toggleInputMode, style: { minWidth: "3ch" }, children: inputMode === 'hex' ? 'RGB' : 'HEX' })] }), jsxRuntime.jsx("div", { className: "color-inputs-row", children: inputMode === 'hex' ? (jsxRuntime.jsx("input", { type: "text", value: hexColor, onChange: handleHexChange })) : (jsxRuntime.jsxs("div", { className: "cw-grid-base-3 cw-gap-small", children: [jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("label", { children: "R:" }), jsxRuntime.jsx("input", { type: "number", name: "r", min: "0", max: "255", value: rgb.r, onChange: handleRgbChange })] }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("label", { children: "G:" }), jsxRuntime.jsx("input", { type: "number", name: "g", min: "0", max: "255", value: rgb.g, onChange: handleRgbChange })] }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("label", { children: "B:" }), jsxRuntime.jsx("input", { type: "number", name: "b", min: "0", max: "255", value: rgb.b, onChange: handleRgbChange })] })] })) }), jsxRuntime.jsxs("div", { className: styles$j.colorPickerInteractiveArea, children: [jsxRuntime.jsx("div", { className: styles$j.hueBar, ref: hueBarRef, onClick: handleHueBarClick, children: jsxRuntime.jsx("div", { className: styles$j.hueBarSlider, style: { top: `${(360 - hsv.h) / 360 * 100}%` } }) }), jsxRuntime.jsxs("div", { className: styles$j.colorArea, ref: colorAreaRef, onClick: handleColorAreaClick, children: [jsxRuntime.jsxs("div", { className: styles$j.colorAreaOverlay, children: [jsxRuntime.jsx("div", { className: styles$j.hueBackground, style: { backgroundColor: hueHex } }), jsxRuntime.jsx("div", { className: styles$j.whiteGradient }), jsxRuntime.jsx("div", { className: styles$j.blackGradient })] }), jsxRuntime.jsx("div", { className: styles$j.colorAreaCursor, style: {
|
|
3350
3464
|
left: `${hsv.s}%`,
|
|
3351
3465
|
top: `${100 - hsv.v}%`
|
|
3352
3466
|
} })] })] })] }));
|
|
3353
3467
|
};
|
|
3354
3468
|
|
|
3355
|
-
var styles$
|
|
3469
|
+
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"};
|
|
3356
3470
|
|
|
3357
3471
|
const CwInputColor = ({ value, onChange, previewText = "Color preview", disabled = false, readOnly = false, width = '4rem', height = '2rem', labelProps, layoutProps, }) => {
|
|
3358
3472
|
const [isOpen, setIsOpen] = React.useState(false);
|
|
@@ -3485,11 +3599,11 @@ const CwInputColor = ({ value, onChange, previewText = "Color preview", disabled
|
|
|
3485
3599
|
break;
|
|
3486
3600
|
}
|
|
3487
3601
|
};
|
|
3488
|
-
return (jsxRuntime.jsxs("div", { className: `cw-input-color ${styles$
|
|
3602
|
+
return (jsxRuntime.jsxs("div", { className: `cw-input-color ${styles$i.container}`, "data-direction": layoutProps?.direction ?? "row", "data-align": layoutProps?.align, children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps })), jsxRuntime.jsx("div", { ref: containerRef, onClick: handleToggle, className: `${styles$i.selectColor} ${disabled ? styles$i.disabled : ''} ${readOnly ? styles$i.readOnly : ''}`, style: {
|
|
3489
3603
|
width,
|
|
3490
3604
|
height,
|
|
3491
3605
|
backgroundColor: value,
|
|
3492
|
-
}, "aria-label": "Open color picker", "aria-expanded": isOpen, "aria-haspopup": "dialog", "aria-readonly": readOnly, role: "button", tabIndex: disabled ? -1 : 0, onKeyDown: handleKeyDown }), isOpen && reactDom.createPortal(jsxRuntime.jsx("div", { ref: dropdownRef, className: styles$
|
|
3606
|
+
}, "aria-label": "Open color picker", "aria-expanded": isOpen, "aria-haspopup": "dialog", "aria-readonly": readOnly, role: "button", tabIndex: disabled ? -1 : 0, onKeyDown: handleKeyDown }), isOpen && reactDom.createPortal(jsxRuntime.jsx("div", { ref: dropdownRef, className: styles$i.colorDropdown, style: dropdownStyle, role: "dialog", "aria-modal": "true", "aria-label": "Color picker", children: jsxRuntime.jsx(CwColorPicker, { initialColor: value, onChange: handleColorChange, previewText: previewText }) }), document.body)] }));
|
|
3493
3607
|
};
|
|
3494
3608
|
|
|
3495
3609
|
/**
|
|
@@ -3739,31 +3853,63 @@ function CwInputDateText(props) {
|
|
|
3739
3853
|
return (jsxRuntime.jsx("div", { className: "cw-input-date-text", children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxRuntime.jsxs(CwLabel, { ...labelProps, children: [iconProps && jsxRuntime.jsx(CwIcon, { ...iconProps }), labelProps.text] })), jsxRuntime.jsxs("div", { children: [jsxRuntime.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 }), jsxRuntime.jsxs("span", { children: [jsxRuntime.jsx(CwIcon, { iconId: "calendar" }), jsxRuntime.jsx("input", { type: "date", disabled: disabled, onChange: onChangeInputDate, readOnly: readOnly, ref: dateInputRef, tabIndex: -1, value: date, ...inputProps })] })] }), buttonProps && jsxRuntime.jsx(CwButton, { ...buttonProps })] }) }));
|
|
3740
3854
|
}
|
|
3741
3855
|
|
|
3742
|
-
var styles$
|
|
3856
|
+
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"};
|
|
3743
3857
|
|
|
3858
|
+
const DEFAULT_LABELS = {
|
|
3859
|
+
dropImageHere: "Drop image here",
|
|
3860
|
+
paste: "Paste",
|
|
3861
|
+
browse: "Browse",
|
|
3862
|
+
acceptedFormats: (formats) => `(${formats})`,
|
|
3863
|
+
clipboardError: "Failed to read from clipboard. Ensure the app has permission to access the clipboard.",
|
|
3864
|
+
invalidType: (formats) => `Unsupported file type. Allowed: ${formats}`,
|
|
3865
|
+
readError: "Could not read the image file.",
|
|
3866
|
+
};
|
|
3867
|
+
/** Reads a file/blob into a base64 data URL (persistable, no blob URL to revoke). */
|
|
3868
|
+
function readImageFileAsDataUrl(file) {
|
|
3869
|
+
return new Promise((resolve, reject) => {
|
|
3870
|
+
const reader = new FileReader();
|
|
3871
|
+
reader.onload = () => resolve(reader.result);
|
|
3872
|
+
reader.onerror = () => reject(reader.error ?? new Error("Failed to read file"));
|
|
3873
|
+
reader.readAsDataURL(file);
|
|
3874
|
+
});
|
|
3875
|
+
}
|
|
3744
3876
|
function CwInputImage(props) {
|
|
3745
3877
|
const [_uploadedImage, setUploadedImage] = React.useState(null);
|
|
3746
3878
|
const inputRef = React.useRef(null);
|
|
3747
|
-
const { allowedImageFormats, onChange, ...inputProps } = props;
|
|
3879
|
+
const { allowedImageFormats, onChange, onError, labels: labelsProp, size, ...inputProps } = props;
|
|
3748
3880
|
const allowedFormats = allowedImageFormats || ["image/jpeg", "image/png", "image/gif"];
|
|
3881
|
+
const labels = { ...DEFAULT_LABELS, ...labelsProp };
|
|
3749
3882
|
const isValidFileType = (type) => allowedFormats.includes(type);
|
|
3750
|
-
const
|
|
3751
|
-
if (
|
|
3752
|
-
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
|
|
3883
|
+
const reportError = (message) => {
|
|
3884
|
+
if (onError)
|
|
3885
|
+
onError(message);
|
|
3886
|
+
else
|
|
3887
|
+
CwDisplayMessage(message, exports.CwMessageType.ERROR);
|
|
3888
|
+
};
|
|
3889
|
+
const handleFile = async (file) => {
|
|
3890
|
+
if (!file) {
|
|
3891
|
+
onChange?.(null);
|
|
3892
|
+
return;
|
|
3756
3893
|
}
|
|
3757
|
-
|
|
3758
|
-
|
|
3759
|
-
|
|
3760
|
-
|
|
3894
|
+
if (!isValidFileType(file.type)) {
|
|
3895
|
+
reportError(labels.invalidType(allowedFormats.join(", ").replace(/image\//g, "")));
|
|
3896
|
+
onChange?.(null);
|
|
3897
|
+
return;
|
|
3898
|
+
}
|
|
3899
|
+
try {
|
|
3900
|
+
const dataUrl = await readImageFileAsDataUrl(file);
|
|
3901
|
+
setUploadedImage(dataUrl);
|
|
3902
|
+
onChange?.(dataUrl, file);
|
|
3903
|
+
}
|
|
3904
|
+
catch {
|
|
3905
|
+
reportError(labels.readError);
|
|
3906
|
+
onChange?.(null);
|
|
3761
3907
|
}
|
|
3762
3908
|
};
|
|
3763
3909
|
const handleDrop = (e) => {
|
|
3764
3910
|
e.preventDefault();
|
|
3765
3911
|
const file = e.dataTransfer.files[0];
|
|
3766
|
-
handleFile(file);
|
|
3912
|
+
void handleFile(file ?? null);
|
|
3767
3913
|
};
|
|
3768
3914
|
const onPasteButtonClick = async () => {
|
|
3769
3915
|
try {
|
|
@@ -3773,21 +3919,20 @@ function CwInputImage(props) {
|
|
|
3773
3919
|
for (const type of clipboardItem.types) {
|
|
3774
3920
|
if (type.startsWith("image/")) {
|
|
3775
3921
|
const blob = await clipboardItem.getType(type);
|
|
3776
|
-
handleFile(blob);
|
|
3922
|
+
await handleFile(blob);
|
|
3777
3923
|
}
|
|
3778
3924
|
}
|
|
3779
3925
|
}
|
|
3780
3926
|
}
|
|
3781
|
-
catch
|
|
3782
|
-
|
|
3783
|
-
alert("Failed to read from clipboard. Ensure the app has permission to access clipboard.");
|
|
3927
|
+
catch {
|
|
3928
|
+
reportError(labels.clipboardError);
|
|
3784
3929
|
}
|
|
3785
3930
|
};
|
|
3786
3931
|
const handleFileChange = (e) => {
|
|
3787
|
-
const file = e.
|
|
3788
|
-
handleFile(file ?? null);
|
|
3932
|
+
const file = e.currentTarget.files?.[0];
|
|
3933
|
+
void handleFile(file ?? null);
|
|
3789
3934
|
};
|
|
3790
|
-
return (jsxRuntime.jsxs("div", { className:
|
|
3935
|
+
return (jsxRuntime.jsxs("div", { className: `cw-input-image ${styles$h.container}`, "data-size": size, children: [jsxRuntime.jsxs("div", { onDragOver: (e) => e.preventDefault(), onDrop: handleDrop, className: styles$h.dropZone, children: [jsxRuntime.jsx(CwIcon, { iconId: "upload" }), jsxRuntime.jsxs("div", { className: "cw-flex-column cw-gap-tiny", children: [jsxRuntime.jsx("p", { className: styles$h.title, children: labels.dropImageHere }), jsxRuntime.jsx("p", { className: styles$h.subtitle, children: labels.acceptedFormats(allowedFormats.join(", ").replace(/image\//g, "")) })] })] }), jsxRuntime.jsxs("div", { className: "cw-flex-row cw-align-center-center cw-gap-small", children: [jsxRuntime.jsx(CwButton, { onClick: onPasteButtonClick, icon: "paste", text: labels.paste, size: size }), jsxRuntime.jsx(CwButton, { onClick: () => inputRef.current?.click(), icon: "folder-open", text: labels.browse, size: size })] }), jsxRuntime.jsx("input", { ref: inputRef, type: "file", accept: allowedFormats.join(","), onChange: handleFileChange, className: styles$h.hiddenInput, ...inputProps })] }));
|
|
3791
3936
|
}
|
|
3792
3937
|
|
|
3793
3938
|
/**
|
|
@@ -3919,7 +4064,7 @@ const CwImageArea = React.forwardRef((props, ref) => {
|
|
|
3919
4064
|
});
|
|
3920
4065
|
CwImageArea.displayName = "CwImageArea";
|
|
3921
4066
|
|
|
3922
|
-
var styles$
|
|
4067
|
+
var styles$g = {"cw-weekday-selector":"cw-weekday-selector-module__cw-weekday-selector__Iz4GZ"};
|
|
3923
4068
|
|
|
3924
4069
|
/**
|
|
3925
4070
|
* This class represents a week where days can be selected or unselected
|
|
@@ -4059,16 +4204,16 @@ const CwWeekdaySelector = ({ value = "", onChange, disabled = false }) => {
|
|
|
4059
4204
|
setSelectedDays(newWeekdays);
|
|
4060
4205
|
onChange?.(newWeekdays.toString());
|
|
4061
4206
|
};
|
|
4062
|
-
return (jsxRuntime.jsx("div", { className: styles$
|
|
4207
|
+
return (jsxRuntime.jsx("div", { className: styles$g["cw-weekday-selector"], children: Weekdays.getFullWeek().map(day => (jsxRuntime.jsx("input", { type: "checkbox", "data-day": day, checked: selectedDays.toArray().includes(day), onChange: (e) => handleChange(day, e.target.checked), disabled: disabled }, day))) }));
|
|
4063
4208
|
};
|
|
4064
4209
|
|
|
4065
|
-
var styles$
|
|
4210
|
+
var styles$f = {"check-container":"cw-check-module__check-container__4nscZ","group":"cw-check-module__group__6JCQo","options":"cw-check-module__options__-g9LF"};
|
|
4066
4211
|
|
|
4067
4212
|
function CwCheck(props) {
|
|
4068
4213
|
const { labelProps, labelText, direction, alignment, className, ...inputProps } = props;
|
|
4069
4214
|
const resolvedDirection = direction ?? alignment ?? "row";
|
|
4070
4215
|
const displayText = labelProps?.text ?? labelText;
|
|
4071
|
-
return (jsxRuntime.jsx("div", { className: `cw-check ${styles$
|
|
4216
|
+
return (jsxRuntime.jsx("div", { className: `cw-check ${styles$f["check-container"]}${className ? ` ${className}` : ''}`, children: jsxRuntime.jsxs("label", { "data-direction": resolvedDirection, children: [jsxRuntime.jsx("input", { type: "checkbox", ...inputProps }), displayText && (jsxRuntime.jsx("span", { className: "cw-icon-text", children: displayText }))] }) }));
|
|
4072
4217
|
}
|
|
4073
4218
|
|
|
4074
4219
|
function CwCheckbox(CwCheckboxProps) {
|
|
@@ -4119,14 +4264,14 @@ function CwCheckboxGroup({ options, value = [], onChange, labelProps, groupLayou
|
|
|
4119
4264
|
?? (optionsAlignment === "column" ? "row" : "column");
|
|
4120
4265
|
// Each checkbox's box-to-text layout is the opposite of the options flow, mirroring CwRadioGroup.
|
|
4121
4266
|
const checkDirection = itemDirection === "row" ? "column" : "row";
|
|
4122
|
-
return (jsxRuntime.jsxs("div", { className: `cw-checkbox-group ${styles$
|
|
4267
|
+
return (jsxRuntime.jsxs("div", { className: `cw-checkbox-group ${styles$f.group}${className ? ` ${className}` : ""}`, "data-testid": dataTestId, "data-direction": labelProps ? groupDirection : "column", "data-align": groupLayout?.align, "data-gap": groupLayout?.gap, children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsx("div", { className: styles$f.options, role: "group", "aria-label": labelProps?.text, "aria-required": required || undefined, "data-direction": itemDirection, "data-gap": itemLayout?.gap, children: options.map((option) => (jsxRuntime.jsx(CwCheck, { labelProps: { text: option.label }, checked: value.includes(option.value), disabled: disabled || option.disabled, direction: checkDirection, onChange: (e) => handleChange(option.value, e.currentTarget.checked) }, option.value))) }), feedbackMessages.map((feedbackItem, index) => (jsxRuntime.jsx("p", { className: "cw-input-info", "data-color": feedbackItem.type, children: feedbackItem.message }, index)))] }));
|
|
4123
4268
|
}
|
|
4124
4269
|
|
|
4125
|
-
var styles$
|
|
4270
|
+
var styles$e = {"radio":"cw-radio-module__radio__5sh7a","group":"cw-radio-module__group__br-HM","options":"cw-radio-module__options__LSw7M"};
|
|
4126
4271
|
|
|
4127
4272
|
/** Single native radio input. Building block for CwRadioGroup. */
|
|
4128
4273
|
function CwRadio({ label, direction = "row", className, ...inputProps }) {
|
|
4129
|
-
return (jsxRuntime.jsxs("label", { className: `cw-radio ${styles$
|
|
4274
|
+
return (jsxRuntime.jsxs("label", { className: `cw-radio ${styles$e.radio}${className ? ` ${className}` : ""}`, "data-direction": direction, children: [jsxRuntime.jsx("input", { type: "radio", ...inputProps }), label && jsxRuntime.jsx("span", { children: label })] }));
|
|
4130
4275
|
}
|
|
4131
4276
|
|
|
4132
4277
|
/**
|
|
@@ -4150,7 +4295,7 @@ function CwRadioGroup({ options, value, onChange, labelProps, groupLayout, itemL
|
|
|
4150
4295
|
// (itemLayout column) reads best with the circle beside the text; a side-by-side row reads
|
|
4151
4296
|
// best with the circle above the text.
|
|
4152
4297
|
const radioDirection = itemLayout?.direction === "row" ? "column" : "row";
|
|
4153
|
-
return (jsxRuntime.jsxs("div", { className: `cw-radio-group ${styles$
|
|
4298
|
+
return (jsxRuntime.jsxs("div", { className: `cw-radio-group ${styles$e.group}${className ? ` ${className}` : ""}`, "data-testid": dataTestId, "data-direction": labelProps ? (groupLayout?.direction ?? "column") : "column", "data-align": groupLayout?.align, "data-gap": groupLayout?.gap, children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsx("div", { className: styles$e.options, role: "radiogroup", "aria-labelledby": ariaLabelledby, "aria-label": ariaLabelledby ? undefined : (ariaLabel ?? labelProps?.text), "aria-required": required || undefined, "data-direction": itemLayout?.direction ?? "column", "data-gap": itemLayout?.gap, children: options.map((option) => (jsxRuntime.jsx(CwRadio, { name: groupName, label: option.label, direction: radioDirection, checked: value === option.value, required: required, disabled: disabled || option.disabled, onChange: () => onChange(option.value) }, option.value))) }), feedbackMessages.map((feedbackItem, index) => (jsxRuntime.jsx("p", { className: "cw-input-info", "data-color": feedbackItem.type, children: feedbackItem.message }, index)))] }));
|
|
4154
4299
|
}
|
|
4155
4300
|
|
|
4156
4301
|
function CwToggle(props) {
|
|
@@ -4416,7 +4561,7 @@ function CwDropdownFilter(props) {
|
|
|
4416
4561
|
return (jsxRuntime.jsxs("div", { id: props.IdContent, className: containerClassName, children: [props.children, isVisible && (jsxRuntime.jsx("nav", { className: "cw-dropdown-menu", style: inlineStyles, onMouseLeave: props.onMouseLeave, id: props.idDropDownFilter, role: "menu", children: jsxRuntime.jsx("ul", { role: "none", children: props.DataSourceDropDownItem?.map((item) => (jsxRuntime.jsx("li", { id: item.IdDropDown_filter, role: "menuitem", children: item.dropDownFilter_desc }, item.IdDropDown_filter))) }) }))] }));
|
|
4417
4562
|
}
|
|
4418
4563
|
|
|
4419
|
-
var styles$
|
|
4564
|
+
var styles$d = {"container":"cw-popover-button-module__container__YSWQU","panel":"cw-popover-button-module__panel__C-BTn"};
|
|
4420
4565
|
|
|
4421
4566
|
/**
|
|
4422
4567
|
* Button that toggles a floating panel with arbitrary children.
|
|
@@ -4495,7 +4640,7 @@ function CwPopoverButton({ children, panelWidth = "auto", placement = "bottom-st
|
|
|
4495
4640
|
}
|
|
4496
4641
|
panel.showPopover();
|
|
4497
4642
|
}, [placement]);
|
|
4498
|
-
return (jsxRuntime.jsxs("div", { ref: containerRef, className: styles$
|
|
4643
|
+
return (jsxRuntime.jsxs("div", { ref: containerRef, className: styles$d.container, children: [jsxRuntime.jsx(CwButton, { ...buttonProps, onClick: handleClick }), jsxRuntime.jsx("div", { ref: panelCallbackRef, className: `${styles$d.panel}${panelClassName ? ` ${panelClassName}` : ""}`, style: { width: panelWidth }, children: children })] }));
|
|
4499
4644
|
}
|
|
4500
4645
|
|
|
4501
4646
|
function itemsToMultiFilterTags(items, nameKey, valueKey, category, primaryColor, onPrimaryColor) {
|
|
@@ -4513,13 +4658,13 @@ function itemsToMultiFilterTags(items, nameKey, valueKey, category, primaryColor
|
|
|
4513
4658
|
return result;
|
|
4514
4659
|
}
|
|
4515
4660
|
|
|
4516
|
-
var styles$
|
|
4661
|
+
var styles$c = {"cw-multifilter-tag":"cw-multi-filter-tag-module__cw-multifilter-tag__Epda-"};
|
|
4517
4662
|
|
|
4518
4663
|
const CwMultiFilterTag = props => {
|
|
4519
4664
|
const { ID, Name, Value, Category, Removable, PrimaryColor, Selectable, Selected } = props;
|
|
4520
4665
|
const backgroundColor = `rgb(${PrimaryColor.r},${PrimaryColor.g},${PrimaryColor.b})`;
|
|
4521
4666
|
const isOutlineMode = Selected && !Removable;
|
|
4522
|
-
return (jsxRuntime.jsx("li", { className: styles$
|
|
4667
|
+
return (jsxRuntime.jsx("li", { className: styles$c["cw-multifilter-tag"], id: ID, "data-value": Value, "data-category": Category, "data-selected": !!Selected, title: props.tooltip ?? Name, onClick: () => {
|
|
4523
4668
|
if (Selectable)
|
|
4524
4669
|
props.OnSelect?.(props);
|
|
4525
4670
|
}, children: jsxRuntime.jsx(CwChip, { label: Name, colorScheme: "custom", customColor: backgroundColor, variant: isOutlineMode ? "outline" : "soft", closable: Removable, onClose: () => props.OnRemove?.(props),
|
|
@@ -4529,7 +4674,7 @@ const CwMultiFilterTag = props => {
|
|
|
4529
4674
|
} : undefined }) }));
|
|
4530
4675
|
};
|
|
4531
4676
|
|
|
4532
|
-
var styles$
|
|
4677
|
+
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"};
|
|
4533
4678
|
|
|
4534
4679
|
/**
|
|
4535
4680
|
* A multiple filter selector, a MULTI-SELECT even. Allows users to select and filter items based on tags.
|
|
@@ -4756,9 +4901,9 @@ const CwMultiFilter = ({ allTags, id, onChangeSelectedTags, selectedTags, placeh
|
|
|
4756
4901
|
inputRef.current?.focus();
|
|
4757
4902
|
}
|
|
4758
4903
|
};
|
|
4759
|
-
return (jsxRuntime.jsxs("form", { ref: componentRef, id: id, className: `${styles$
|
|
4904
|
+
return (jsxRuntime.jsxs("form", { ref: componentRef, id: id, className: `${styles$b["cw-multi-filter"]}${className ? ` ${className}` : ""}`, style: style, onSubmit: (e) => {
|
|
4760
4905
|
e.preventDefault();
|
|
4761
|
-
}, children: [jsxRuntime.jsxs("div", { onClick: handleDivClick, ref: wrapperRef, className: styles$
|
|
4906
|
+
}, children: [jsxRuntime.jsxs("div", { onClick: handleDivClick, ref: wrapperRef, className: styles$b["cw-multi-filter-search"], style: isPanelOpen ? { outline: "1px solid var(--cw-color-outline-variant)" } : {}, children: [jsxRuntime.jsxs("ul", { id: id + "_selected_filters", children: [Array.from(selectedTags).map(tag => (React.createElement(CwMultiFilterTag, { ...tag, key: tag.ID, Selectable: false, Removable: true, OnRemove: () => removeTag(tag.ID) }))), jsxRuntime.jsx("input", { type: "text", id: id + "_input", ref: inputRef, value: inputTextValue, spellCheck: false, onFocus: () => setIsPanelOpen(true), onChange: e => handleInputText(e.currentTarget.value), autoComplete: "off", placeholder: selectedTags.size === 0 ? placeholder : "", onKeyDown: e => {
|
|
4762
4907
|
switch (e.key) {
|
|
4763
4908
|
case "Enter":
|
|
4764
4909
|
case "Tab": {
|
|
@@ -4785,7 +4930,7 @@ const CwMultiFilter = ({ allTags, id, onChangeSelectedTags, selectedTags, placeh
|
|
|
4785
4930
|
break;
|
|
4786
4931
|
}
|
|
4787
4932
|
}
|
|
4788
|
-
} })] }), selectedTags.size > 0 && (jsxRuntime.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(jsxRuntime.jsxs("section", { ref: panelRef, className: styles$
|
|
4933
|
+
} })] }), selectedTags.size > 0 && (jsxRuntime.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(jsxRuntime.jsxs("section", { ref: panelRef, className: styles$b["cw-multi-filter-catalog-container"], style: panelStyle, children: [jsxRuntime.jsxs("nav", { children: [jsxRuntime.jsx("button", { className: selectedCategory === "All" ? styles$b["category-selected"] : undefined, onClick: () => handleClickCategory("All"), children: allCategoriesLabel }), Array.from(categoriesMappedToTags().keys()).map(category => (jsxRuntime.jsx("button", { className: selectedCategory === category ? styles$b["category-selected"] : undefined, style: {
|
|
4789
4934
|
backgroundColor: getColor(category).primary,
|
|
4790
4935
|
color: getColor(category).onPrimary,
|
|
4791
4936
|
}, onClick: () => handleClickCategory(category), children: category }, category)))] }), jsxRuntime.jsx("ul", { children: displayTags
|
|
@@ -4811,7 +4956,7 @@ const CwMultiFilter = ({ allTags, id, onChangeSelectedTags, selectedTags, placeh
|
|
|
4811
4956
|
} }, props.ID))) })] }))] }));
|
|
4812
4957
|
};
|
|
4813
4958
|
|
|
4814
|
-
var styles$
|
|
4959
|
+
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"};
|
|
4815
4960
|
|
|
4816
4961
|
/**
|
|
4817
4962
|
* Multi-select input with chip tags and searchable dropdown.
|
|
@@ -4946,11 +5091,11 @@ function CwTagSelector({ id, options, value, onChange, labelProps, iconProps, al
|
|
|
4946
5091
|
// Keeping containerRef for any other potential use
|
|
4947
5092
|
const direction = alignProps?.flexDirection ?? "row";
|
|
4948
5093
|
const feedbackMessages = feedback ? (Array.isArray(feedback) ? feedback : [feedback]) : [];
|
|
4949
|
-
return (jsxRuntime.jsxs("div", { ref: containerRef, className: `${styles$
|
|
4950
|
-
inputRef.current?.focus(); }, children: [selectedOptions.map(opt => (jsxRuntime.jsx(CwChip, { label: opt.label, colorScheme: opt.color ? "custom" : "info", customColor: opt.color, closable: !disabled, onClose: () => handleRemove(opt.value) }, opt.value))), jsxRuntime.jsx("input", { ref: inputRef, type: "text", value: search, onChange: handleInputChange, onFocus: handleInputFocus, onKeyDown: handleKeyDown, placeholder: selectedOptions.length === 0 ? placeholder : "", disabled: disabled, autoComplete: "off" }), value.length > 0 && !disabled && (jsxRuntime.jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onMouseDown: (e) => e.preventDefault(), onClick: (e) => { e.stopPropagation(); onChange([]); setSearch(""); setOpen(false); }, tabIndex: -1, "aria-label": "Clear all" }))] })] }), feedbackMessages.map((fb, i) => (jsxRuntime.jsx("p", { className: "cw-input-info", "data-color": fb.type, children: fb.message }, i))), renderPanel((showSelectAll || filtered.length > 0) ? (jsxRuntime.jsxs("div", { ref: panelRef, className: styles$
|
|
5094
|
+
return (jsxRuntime.jsxs("div", { ref: containerRef, className: `${styles$a.container}${className ? ` ${className}` : ""}`, style: style, id: id, "data-direction": direction, children: [jsxRuntime.jsxs(CwAlign, { ...alignProps, children: [labelProps && (jsxRuntime.jsxs(CwLabel, { ...labelProps, children: [iconProps && jsxRuntime.jsx(CwIcon, { ...iconProps }), labelProps.text] })), jsxRuntime.jsxs("div", { className: `${styles$a.inputBox}${disabled ? ` ${styles$a.disabled}` : ""}`, ref: inputBoxRef, onClick: () => { if (!disabled)
|
|
5095
|
+
inputRef.current?.focus(); }, children: [selectedOptions.map(opt => (jsxRuntime.jsx(CwChip, { label: opt.label, colorScheme: opt.color ? "custom" : "info", customColor: opt.color, closable: !disabled, onClose: () => handleRemove(opt.value) }, opt.value))), jsxRuntime.jsx("input", { ref: inputRef, type: "text", value: search, onChange: handleInputChange, onFocus: handleInputFocus, onKeyDown: handleKeyDown, placeholder: selectedOptions.length === 0 ? placeholder : "", disabled: disabled, autoComplete: "off" }), value.length > 0 && !disabled && (jsxRuntime.jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onMouseDown: (e) => e.preventDefault(), onClick: (e) => { e.stopPropagation(); onChange([]); setSearch(""); setOpen(false); }, tabIndex: -1, "aria-label": "Clear all" }))] })] }), feedbackMessages.map((fb, i) => (jsxRuntime.jsx("p", { className: "cw-input-info", "data-color": fb.type, children: fb.message }, i))), renderPanel((showSelectAll || filtered.length > 0) ? (jsxRuntime.jsxs("div", { ref: panelRef, className: styles$a.dropdown, style: panelStyle, children: [showSelectAll && !search && (jsxRuntime.jsxs("div", { className: styles$a.selectAll, onMouseDown: (e) => e.preventDefault(), onClick: handleToggleAll, children: [jsxRuntime.jsx("input", { type: "checkbox", checked: allSelected, readOnly: true, tabIndex: -1 }), allSelected ? "Deselect all" : "Select all"] })), jsxRuntime.jsx("ul", { ref: listRef, children: filtered.map((opt, idx) => (jsxRuntime.jsxs("li", { className: `${styles$a.option}${idx === focusedIndex ? ` ${styles$a.optionFocused}` : ""}`, onMouseDown: (e) => e.preventDefault(), onClick: () => handleSelect(opt.value), onMouseEnter: () => setFocusedIndex(idx), title: opt.tooltip, children: [opt.color && jsxRuntime.jsx("span", { className: styles$a.optionDot, style: { backgroundColor: opt.color } }), opt.label] }, opt.value))) })] })) : null)] }));
|
|
4951
5096
|
}
|
|
4952
5097
|
|
|
4953
|
-
var styles$
|
|
5098
|
+
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"};
|
|
4954
5099
|
|
|
4955
5100
|
function CwTreeView({ data, onSelect, allowParentSelection = false, selectedId: initialSelectedId = null }) {
|
|
4956
5101
|
const [expanded, setExpanded] = React.useState(new Set());
|
|
@@ -5017,10 +5162,10 @@ function CwTreeView({ data, onSelect, allowParentSelection = false, selectedId:
|
|
|
5017
5162
|
const isLeaf = !hasChildren;
|
|
5018
5163
|
const isSelected = selectedId?.toString().toLowerCase() === node.id.toString().toLowerCase();
|
|
5019
5164
|
const selectable = allowParentSelection || isLeaf;
|
|
5020
|
-
return (jsxRuntime.jsxs("div", { className: styles$
|
|
5021
|
-
styles$
|
|
5022
|
-
isSelected && styles$
|
|
5023
|
-
!selectable && styles$
|
|
5165
|
+
return (jsxRuntime.jsxs("div", { className: styles$9["tree-item"], children: [jsxRuntime.jsxs("div", { className: [
|
|
5166
|
+
styles$9["tree-node"],
|
|
5167
|
+
isSelected && styles$9["selected"],
|
|
5168
|
+
!selectable && styles$9["non-selectable"]
|
|
5024
5169
|
].filter(Boolean).join(' '), style: { paddingLeft: `${depth * 24 + 8}px` }, onClick: () => {
|
|
5025
5170
|
if (selectable) {
|
|
5026
5171
|
setSelectedId(node.id);
|
|
@@ -5029,7 +5174,7 @@ function CwTreeView({ data, onSelect, allowParentSelection = false, selectedId:
|
|
|
5029
5174
|
else {
|
|
5030
5175
|
toggleExpand(node.id);
|
|
5031
5176
|
}
|
|
5032
|
-
}, children: [hasChildren && (jsxRuntime.jsx(CwIcon, { size: "large", iconId: isExpanded ? "chevron-down" : "chevron-right" })), jsxRuntime.jsx("div", { className: `${styles$
|
|
5177
|
+
}, children: [hasChildren && (jsxRuntime.jsx(CwIcon, { size: "large", iconId: isExpanded ? "chevron-down" : "chevron-right" })), jsxRuntime.jsx("div", { className: `${styles$9["tree-label"]} ${!hasChildren ? styles$9["tree-spacer"] : ''}`, children: node.label })] }), hasChildren && isExpanded && (jsxRuntime.jsx("div", { className: styles$9["tree-children"], children: node.children.map((child) => renderNode(child, depth + 1)) }))] }, node.id));
|
|
5033
5178
|
};
|
|
5034
5179
|
// Function to search for nodes that match the search term
|
|
5035
5180
|
const searchInTree = (nodes, searchTerm) => {
|
|
@@ -5053,7 +5198,129 @@ function CwTreeView({ data, onSelect, allowParentSelection = false, selectedId:
|
|
|
5053
5198
|
return results;
|
|
5054
5199
|
};
|
|
5055
5200
|
const filteredData = searchInTree(data, search);
|
|
5056
|
-
return (jsxRuntime.jsxs("div", { className: `cw-tree-view ${styles$
|
|
5201
|
+
return (jsxRuntime.jsxs("div", { className: `cw-tree-view ${styles$9["tree-container"]}`, children: [jsxRuntime.jsxs("header", { children: [jsxRuntime.jsx("input", { type: "text", placeholder: "Search in tree...", value: search, onChange: (e) => setSearch(e.target.value) }), search && (jsxRuntime.jsx(CwButton, { onClick: () => setSearch(""), type: "button", icon: "close", variant: "icon", color: "neutral" }))] }), jsxRuntime.jsx("div", { className: styles$9["tree-wrapper"], children: filteredData.length > 0 ? (filteredData.map((node) => renderNode(node))) : (jsxRuntime.jsxs("div", { className: styles$9["empty-state"], children: [jsxRuntime.jsx(CwIcon, { iconId: "comment" }), search ? "No results found" : "There are no items"] })) })] }));
|
|
5202
|
+
}
|
|
5203
|
+
|
|
5204
|
+
const EXACT_PHRASE = /"([^"]+)"/g;
|
|
5205
|
+
/**
|
|
5206
|
+
* Quoted phrases are matched against the label only; loose words against label + description + href.
|
|
5207
|
+
* Parsed once instead of per node.
|
|
5208
|
+
*/
|
|
5209
|
+
function parseSearch(search) {
|
|
5210
|
+
const phrases = Array.from(search.matchAll(EXACT_PHRASE), match => match[1].toLowerCase());
|
|
5211
|
+
const words = search
|
|
5212
|
+
.replace(EXACT_PHRASE, "")
|
|
5213
|
+
.trim()
|
|
5214
|
+
.toLowerCase()
|
|
5215
|
+
.split(/\s+/)
|
|
5216
|
+
.filter(Boolean);
|
|
5217
|
+
return { phrases, words };
|
|
5218
|
+
}
|
|
5219
|
+
/**
|
|
5220
|
+
* Filters a nav tree by a search string, keeping a group whose descendants match.
|
|
5221
|
+
*
|
|
5222
|
+
* Supports `"quoted phrases"` (must appear in the label) alongside loose words (any field) — this is
|
|
5223
|
+
* behaviour users are told about, so don't simplify it.
|
|
5224
|
+
*/
|
|
5225
|
+
function filterNavItems(items, search) {
|
|
5226
|
+
if (!search?.trim())
|
|
5227
|
+
return items;
|
|
5228
|
+
const { phrases, words } = parseSearch(search);
|
|
5229
|
+
if (phrases.length === 0 && words.length === 0)
|
|
5230
|
+
return items;
|
|
5231
|
+
const keep = (item, parentMatchedPhrases) => {
|
|
5232
|
+
const label = item.label.toLowerCase();
|
|
5233
|
+
const haystack = [item.label, item.description, item.href].filter(Boolean).join(" ").toLowerCase();
|
|
5234
|
+
const matchesPhrases = phrases.every(phrase => label.includes(phrase));
|
|
5235
|
+
const matchesWords = words.every(word => haystack.includes(word));
|
|
5236
|
+
const selfMatches = (phrases.length === 0 || matchesPhrases || parentMatchedPhrases) && matchesWords;
|
|
5237
|
+
if (!item.children?.length)
|
|
5238
|
+
return selfMatches ? item : null;
|
|
5239
|
+
let children = item.children
|
|
5240
|
+
.map(child => keep(child, matchesPhrases || parentMatchedPhrases))
|
|
5241
|
+
.filter((child) => child !== null);
|
|
5242
|
+
// A phrase-only search narrows the survivors further: each must carry the phrase itself.
|
|
5243
|
+
if (phrases.length > 0 && words.length === 0 && matchesPhrases) {
|
|
5244
|
+
children = children.filter(child => phrases.every(phrase => child.label.toLowerCase().includes(phrase)));
|
|
5245
|
+
}
|
|
5246
|
+
if (children.length > 0)
|
|
5247
|
+
return { ...item, children };
|
|
5248
|
+
// The group matched but nothing under it did. Returning `children: []` would make it a leaf —
|
|
5249
|
+
// and a leaf with no href — so keep the subtree instead of emptying it.
|
|
5250
|
+
return selfMatches ? item : null;
|
|
5251
|
+
};
|
|
5252
|
+
return items
|
|
5253
|
+
.map(item => keep(item, false))
|
|
5254
|
+
.filter((item) => item !== null);
|
|
5255
|
+
}
|
|
5256
|
+
|
|
5257
|
+
/**
|
|
5258
|
+
* Sorts the top level alphabetically, leaving every nested list in the order the consumer gave.
|
|
5259
|
+
*
|
|
5260
|
+
* Deliberately level 1 only: this exists because a long list of modules is hard to scan, while the
|
|
5261
|
+
* pages inside a module are ordered on purpose. Returns the input untouched when not sorting.
|
|
5262
|
+
*/
|
|
5263
|
+
function sortNavItems(items, alphabetically) {
|
|
5264
|
+
if (!alphabetically)
|
|
5265
|
+
return items;
|
|
5266
|
+
return [...items].sort((first, second) => first.label.localeCompare(second.label));
|
|
5267
|
+
}
|
|
5268
|
+
|
|
5269
|
+
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"};
|
|
5270
|
+
|
|
5271
|
+
const SKELETON_ROW_COUNT = 5;
|
|
5272
|
+
const defaultRenderLink = (item, children) => (jsxRuntime.jsx("a", { href: item.href, children: children }));
|
|
5273
|
+
/** Sizes only its own icons — content injected via `renderLink` is styled by the consumer. */
|
|
5274
|
+
function CwNavMenu({ items, loading = false, isActive, renderLink = defaultRenderLink, showExpandIndicator = false, search, emptyMessage, sortAlphabetically = false, favoritesSlot, favoritesLabel = "Favorites", favoritesProps, isFavorite, beforeTreeSlot, className, ...navProps }) {
|
|
5275
|
+
const visibleItems = sortNavItems(filterNavItems(items, search), sortAlphabetically);
|
|
5276
|
+
const showEmptyMessage = !loading && Boolean(emptyMessage) && Boolean(search?.trim()) && visibleItems.length === 0;
|
|
5277
|
+
const hasActiveDescendant = (node) => node.children?.some(child => isActive?.(child) || hasActiveDescendant(child)) ?? false;
|
|
5278
|
+
const renderItem = (item, level) => {
|
|
5279
|
+
const children = item.children;
|
|
5280
|
+
if (children && children.length > 0) {
|
|
5281
|
+
return (jsxRuntime.jsx("li", { children: jsxRuntime.jsxs("details", { "data-level": level, open: hasActiveDescendant(item) || undefined, children: [jsxRuntime.jsxs("summary", { children: [item.icon && jsxRuntime.jsx(CwIcon, { iconId: item.icon, size: level >= 2 ? "small" : "medium" }), item.label, (showExpandIndicator || level >= 2) && (jsxRuntime.jsx(CwIcon, { iconId: "chevron-down", size: "small", className: styles$8.expandIndicator }))] }), jsxRuntime.jsx("ul", { children: children.map(child => renderItem(child, level + 1)) })] }) }, item.id));
|
|
5282
|
+
}
|
|
5283
|
+
return (jsxRuntime.jsx("li", { "data-active": isActive?.(item) ? "true" : undefined, children: renderLink(item, jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [item.icon && jsxRuntime.jsx(CwIcon, { iconId: item.icon, size: "medium" }), item.label, isFavorite?.(item) && jsxRuntime.jsx(CwIcon, { iconId: "star", size: "small", className: styles$8.favoriteStar })] })) }, item.id));
|
|
5284
|
+
};
|
|
5285
|
+
return (jsxRuntime.jsxs("nav", { ...navProps, className: [styles$8.menu, className].filter(Boolean).join(" "), "aria-busy": loading || undefined, children: [favoritesSlot && (jsxRuntime.jsxs("details", { open: true, ...favoritesProps, className: [styles$8.favorites, favoritesProps?.className].filter(Boolean).join(" "), children: [jsxRuntime.jsxs("summary", { children: [jsxRuntime.jsx(CwIcon, { iconId: "star", size: "medium" }), favoritesLabel] }), jsxRuntime.jsx("div", { className: styles$8.favoritesContent, children: favoritesSlot })] })), beforeTreeSlot, jsxRuntime.jsx("ul", { children: loading
|
|
5286
|
+
? Array.from({ length: SKELETON_ROW_COUNT }, (_unused, index) => (jsxRuntime.jsx("li", { className: styles$8.skeleton, children: jsxRuntime.jsx(CwSkeleton, { height: "var(--cw-size-small)", radius: "var(--cw-border-radius-small)" }) }, index)))
|
|
5287
|
+
: visibleItems.map(item => renderItem(item, 1)) }), showEmptyMessage && jsxRuntime.jsx("p", { className: styles$8.emptyMessage, children: emptyMessage })] }));
|
|
5288
|
+
}
|
|
5289
|
+
|
|
5290
|
+
/**
|
|
5291
|
+
* Pure keyboard-navigation resolver shared by the `CwSearchInput` combobox.
|
|
5292
|
+
* Kept side-effect-free so the arrow/home/end/enter/escape behaviour can be unit
|
|
5293
|
+
* tested without a DOM (the library's vitest runs with `environment: "node"`).
|
|
5294
|
+
*/
|
|
5295
|
+
/**
|
|
5296
|
+
* Resolves a key press against the current highlight into a {@link SearchKeyAction}.
|
|
5297
|
+
* Arrow navigation wraps around; `Enter` selects only when a valid row is highlighted.
|
|
5298
|
+
*
|
|
5299
|
+
* @param key `KeyboardEvent.key` value.
|
|
5300
|
+
* @param currentIndex Currently highlighted option index (`-1` = none).
|
|
5301
|
+
* @param optionsLength Number of options currently in the dropdown.
|
|
5302
|
+
*/
|
|
5303
|
+
function resolveSearchKeyAction(key, currentIndex, optionsLength) {
|
|
5304
|
+
if (optionsLength <= 0)
|
|
5305
|
+
return { type: "none" };
|
|
5306
|
+
switch (key) {
|
|
5307
|
+
case "ArrowDown":
|
|
5308
|
+
return { type: "move", index: currentIndex < optionsLength - 1 ? currentIndex + 1 : 0 };
|
|
5309
|
+
case "ArrowUp":
|
|
5310
|
+
return { type: "move", index: currentIndex > 0 ? currentIndex - 1 : optionsLength - 1 };
|
|
5311
|
+
case "Home":
|
|
5312
|
+
return { type: "move", index: 0 };
|
|
5313
|
+
case "End":
|
|
5314
|
+
return { type: "move", index: optionsLength - 1 };
|
|
5315
|
+
case "Enter":
|
|
5316
|
+
return currentIndex >= 0 && currentIndex < optionsLength
|
|
5317
|
+
? { type: "select", index: currentIndex }
|
|
5318
|
+
: { type: "none" };
|
|
5319
|
+
case "Escape":
|
|
5320
|
+
return { type: "close" };
|
|
5321
|
+
default:
|
|
5322
|
+
return { type: "none" };
|
|
5323
|
+
}
|
|
5057
5324
|
}
|
|
5058
5325
|
|
|
5059
5326
|
/**
|
|
@@ -5074,14 +5341,19 @@ function CwSearchInput(optionsProps) {
|
|
|
5074
5341
|
const [_selectedOption, setSelectedOption] = React.useState(null);
|
|
5075
5342
|
const [showDropdown, setShowDropdown] = React.useState(false);
|
|
5076
5343
|
const [isLoading, setIsLoading] = React.useState(false);
|
|
5344
|
+
const [highlightedIndex, setHighlightedIndex] = React.useState(-1);
|
|
5077
5345
|
const wrapperRef = React.useRef(null);
|
|
5346
|
+
const inputRef = React.useRef(null);
|
|
5347
|
+
// Stable ids wiring the combobox input to its listbox popup for assistive tech.
|
|
5348
|
+
const listboxId = React.useId();
|
|
5349
|
+
const optionId = (index) => `${listboxId}-opt-${index}`;
|
|
5078
5350
|
const { panelRef, panelStyle, renderPanel } = useDropdownPortal({
|
|
5079
5351
|
anchorRef: wrapperRef,
|
|
5080
5352
|
isOpen: showDropdown && filteredOptions.length > 0,
|
|
5081
|
-
onClose: () => setShowDropdown(false),
|
|
5353
|
+
onClose: () => { setShowDropdown(false); setHighlightedIndex(-1); },
|
|
5082
5354
|
});
|
|
5083
5355
|
// Extract props
|
|
5084
|
-
const { labelProps, iconProps, alignProps, selectList, handleChange, placeholder = "Search…", disabled, renderOption, style, id, className, defaultValue, ...otherProps } = optionsProps;
|
|
5356
|
+
const { labelProps, iconProps, alignProps, selectList, handleChange, placeholder = "Search…", disabled, renderOption, style, id, className, defaultValue, autoFocus, ...otherProps } = optionsProps;
|
|
5085
5357
|
// Get direction for data attribute
|
|
5086
5358
|
const direction = alignProps?.flexDirection || "row";
|
|
5087
5359
|
// Make default value selection when loading the component
|
|
@@ -5100,9 +5372,10 @@ function CwSearchInput(optionsProps) {
|
|
|
5100
5372
|
}
|
|
5101
5373
|
}, [defaultValue, selectList]);
|
|
5102
5374
|
const handleInputChange = (event) => {
|
|
5103
|
-
const text = event.
|
|
5375
|
+
const text = event.currentTarget.value;
|
|
5104
5376
|
setSearchText(text);
|
|
5105
5377
|
setShowDropdown(true);
|
|
5378
|
+
setHighlightedIndex(-1);
|
|
5106
5379
|
if (text === "") {
|
|
5107
5380
|
setFilteredOptions(selectList);
|
|
5108
5381
|
setSelectedOption(null);
|
|
@@ -5125,10 +5398,30 @@ function CwSearchInput(optionsProps) {
|
|
|
5125
5398
|
};
|
|
5126
5399
|
const handleInputFocus = () => {
|
|
5127
5400
|
setShowDropdown(true);
|
|
5401
|
+
setHighlightedIndex(-1);
|
|
5128
5402
|
if (searchText === "") {
|
|
5129
5403
|
setFilteredOptions(selectList);
|
|
5130
5404
|
}
|
|
5131
5405
|
};
|
|
5406
|
+
const handleKeyDown = (event) => {
|
|
5407
|
+
if (!(showDropdown && filteredOptions.length > 0))
|
|
5408
|
+
return;
|
|
5409
|
+
const action = resolveSearchKeyAction(event.key, highlightedIndex, filteredOptions.length);
|
|
5410
|
+
switch (action.type) {
|
|
5411
|
+
case "move":
|
|
5412
|
+
event.preventDefault();
|
|
5413
|
+
setHighlightedIndex(action.index);
|
|
5414
|
+
break;
|
|
5415
|
+
case "select":
|
|
5416
|
+
event.preventDefault();
|
|
5417
|
+
handleOptionSelect(filteredOptions[action.index]);
|
|
5418
|
+
break;
|
|
5419
|
+
case "close":
|
|
5420
|
+
setShowDropdown(false);
|
|
5421
|
+
setHighlightedIndex(-1);
|
|
5422
|
+
break;
|
|
5423
|
+
}
|
|
5424
|
+
};
|
|
5132
5425
|
const handleInputBlur = () => {
|
|
5133
5426
|
// Dropdown is closed by useDropdownPortal's outside-click handler.
|
|
5134
5427
|
// Blur alone must not close it — clicking an option would lose focus before the click fires.
|
|
@@ -5140,16 +5433,19 @@ function CwSearchInput(optionsProps) {
|
|
|
5140
5433
|
handleChange(option.id);
|
|
5141
5434
|
}
|
|
5142
5435
|
setFilteredOptions([]);
|
|
5436
|
+
setHighlightedIndex(-1);
|
|
5143
5437
|
};
|
|
5144
5438
|
const handleClearClick = () => {
|
|
5145
5439
|
setSearchText("");
|
|
5146
5440
|
setFilteredOptions([]);
|
|
5147
5441
|
setSelectedOption(null);
|
|
5442
|
+
setHighlightedIndex(-1);
|
|
5148
5443
|
if (handleChange) {
|
|
5149
5444
|
handleChange("");
|
|
5150
5445
|
}
|
|
5446
|
+
inputRef.current?.focus();
|
|
5151
5447
|
};
|
|
5152
|
-
return (jsxRuntime.jsxs("div", { className: `cw-search-input ${className || ""}`, style: style,
|
|
5448
|
+
return (jsxRuntime.jsxs("div", { className: `cw-search-input ${className || ""}`, style: style, ...otherProps, "data-direction": direction, children: [jsxRuntime.jsxs(CwAlign, { ...alignProps, children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsxs("div", { className: "cw-search-input-wrapper", ref: wrapperRef, children: [jsxRuntime.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 && (jsxRuntime.jsx("div", { className: "cw-search-input-loading", children: jsxRuntime.jsx(CwIcon, { iconId: "spinner" }) })), jsxRuntime.jsx("div", { className: "cw-search-input-icons", children: searchText && !disabled && !isLoading ? (jsxRuntime.jsx(CwButton, { type: "button", onClick: handleClearClick, "aria-label": "Clear search", variant: "icon", icon: "close", color: "neutral" })) : (iconProps ? jsxRuntime.jsx(CwIcon, { ...iconProps }) : jsxRuntime.jsx(CwIcon, { iconId: "search" })) })] })] }), renderPanel(jsxRuntime.jsx("div", { ref: panelRef, id: listboxId, className: dropdownStyles.dropdown, style: panelStyle, role: "listbox", children: jsxRuntime.jsx("ul", { children: filteredOptions.map((option, index) => (jsxRuntime.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))) }) }))] }));
|
|
5153
5449
|
}
|
|
5154
5450
|
|
|
5155
5451
|
/**
|
|
@@ -11346,7 +11642,6 @@ exports.CwDisplayMessage = CwDisplayMessage;
|
|
|
11346
11642
|
exports.CwDropdown = CwDropdown;
|
|
11347
11643
|
exports.CwDropdownFilter = CwDropdownFilter;
|
|
11348
11644
|
exports.CwExpandable = CwExpandable;
|
|
11349
|
-
exports.CwFileUpload = CwFileUpload;
|
|
11350
11645
|
exports.CwFileUploadMultiple = CwFileUploadMultiple;
|
|
11351
11646
|
exports.CwFindAirport = CwFindAirport;
|
|
11352
11647
|
exports.CwFindCrewmember = CwFindCrewmember;
|
|
@@ -11368,7 +11663,6 @@ exports.CwInputText = CwInputText;
|
|
|
11368
11663
|
exports.CwKeyValueList = CwKeyValueList;
|
|
11369
11664
|
exports.CwLabel = CwLabel;
|
|
11370
11665
|
exports.CwLoading = CwLoading;
|
|
11371
|
-
exports.CwLoadingSmall = CwLoadingSmall;
|
|
11372
11666
|
exports.CwMasterDetail = CwMasterDetail;
|
|
11373
11667
|
exports.CwMessage = CwMessage;
|
|
11374
11668
|
exports.CwMessageManager = CwMessageManager;
|
|
@@ -11377,9 +11671,11 @@ exports.CwModalHover = CwModalHover;
|
|
|
11377
11671
|
exports.CwModalReportFunctional = CwModalReportFunctional;
|
|
11378
11672
|
exports.CwMultiFilter = CwMultiFilter;
|
|
11379
11673
|
exports.CwMultiFilterTag = CwMultiFilterTag;
|
|
11674
|
+
exports.CwNavMenu = CwNavMenu;
|
|
11380
11675
|
exports.CwNote = CwNote;
|
|
11381
11676
|
exports.CwOption = CwOption;
|
|
11382
11677
|
exports.CwPopoverButton = CwPopoverButton;
|
|
11678
|
+
exports.CwProgress = CwProgress;
|
|
11383
11679
|
exports.CwRadioGroup = CwRadioGroup;
|
|
11384
11680
|
exports.CwReportModal = CwReportModal;
|
|
11385
11681
|
exports.CwScheduler = CwScheduler;
|
|
@@ -11388,6 +11684,7 @@ exports.CwSearchInput = CwSearchInput;
|
|
|
11388
11684
|
exports.CwSelect = CwSelect;
|
|
11389
11685
|
exports.CwSelectList = CwSelectList;
|
|
11390
11686
|
exports.CwSelectListItems = CwSelectListItems;
|
|
11687
|
+
exports.CwSkeleton = CwSkeleton;
|
|
11391
11688
|
exports.CwSortableList = CwSortableList;
|
|
11392
11689
|
exports.CwSortableTable = CwSortableTable;
|
|
11393
11690
|
exports.CwSuperScheduler = CwSuperScheduler;
|
|
@@ -11436,12 +11733,16 @@ exports.TooltipConstraintContext = TooltipConstraintContext;
|
|
|
11436
11733
|
exports.UiEvent = UiEvent;
|
|
11437
11734
|
exports.Weekdays = Weekdays;
|
|
11438
11735
|
exports.cblEvent = cblEvent;
|
|
11736
|
+
exports.configureCwLoading = configureCwLoading;
|
|
11439
11737
|
exports.eventIsVisible = eventIsVisible;
|
|
11738
|
+
exports.filterNavItems = filterNavItems;
|
|
11440
11739
|
exports.filterVisibleEvents = filterVisibleEvents;
|
|
11740
|
+
exports.getCwLoadingDefaults = getCwLoadingDefaults;
|
|
11441
11741
|
exports.getDefaultDivisions = getDefaultDivisions;
|
|
11442
11742
|
exports.getEventSizes = getEventSizes;
|
|
11443
11743
|
exports.getPresetsByKeysTemporal = getPresetsByKeysTemporal;
|
|
11444
11744
|
exports.itemsToMultiFilterTags = itemsToMultiFilterTags;
|
|
11745
|
+
exports.sortNavItems = sortNavItems;
|
|
11445
11746
|
exports.useCwMessage = useCwMessage;
|
|
11446
11747
|
exports.useSortableList = useSortableList;
|
|
11447
11748
|
exports.useSortableTable = useSortableTable;
|