@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.
Files changed (281) hide show
  1. package/dist/content/fonts/roboto-mono/LICENSE +93 -0
  2. package/dist/content/fonts/roboto-mono/RobotoMono.css +43 -0
  3. package/dist/content/fonts/roboto-mono/files/roboto-mono-latin-ext-wght-italic.woff2 +0 -0
  4. package/dist/content/fonts/roboto-mono/files/roboto-mono-latin-ext-wght-normal.woff2 +0 -0
  5. package/dist/content/fonts/roboto-mono/files/roboto-mono-latin-wght-italic.woff2 +0 -0
  6. package/dist/content/fonts/roboto-mono/files/roboto-mono-latin-wght-normal.woff2 +0 -0
  7. package/dist/content/icons/new-cw-icons/NewCwIcons.json +1 -1
  8. package/dist/content/icons/new-cw-icons/css/new-cw-icons.css +260 -824
  9. package/dist/content/icons/new-cw-icons/fonts/NewCwIcons.woff +0 -0
  10. package/dist/deprecated/components/MultiSelect_deprecated_.d.ts +24 -0
  11. package/dist/deprecated/components/MultiSelect_deprecated_.d.ts.map +1 -0
  12. package/dist/deprecated/components/dropdown/CwDropdownContainer.d.ts +17 -0
  13. package/dist/deprecated/components/dropdown/CwDropdownContainer.d.ts.map +1 -0
  14. package/dist/deprecated/components/multiselect/CwHeadFilter.d.ts +17 -0
  15. package/dist/deprecated/components/multiselect/CwHeadFilter.d.ts.map +1 -0
  16. package/dist/deprecated/components/multiselect/CwMultiselect.d.ts +13 -0
  17. package/dist/deprecated/components/multiselect/CwMultiselect.d.ts.map +1 -0
  18. package/dist/deprecated/components/multiselect/CwOptionList.d.ts +14 -0
  19. package/dist/deprecated/components/multiselect/CwOptionList.d.ts.map +1 -0
  20. package/dist/deprecated/components/tag/CwTag.d.ts +15 -0
  21. package/dist/deprecated/components/tag/CwTag.d.ts.map +1 -0
  22. package/dist/index.cjs.js +514 -213
  23. package/dist/index.css +2 -2
  24. package/dist/index.d.ts +226 -51
  25. package/dist/index.es.js +508 -212
  26. package/dist/playground/main.d.ts +4 -0
  27. package/dist/playground/main.d.ts.map +1 -0
  28. package/dist/src/components/control/action/button/CwPopoverButton.d.ts +33 -0
  29. package/dist/src/components/control/action/button/CwPopoverButton.d.ts.map +1 -0
  30. package/dist/src/components/control/action/contextual-menu/CwContextualMenu.d.ts +29 -0
  31. package/dist/src/components/control/action/contextual-menu/CwContextualMenu.d.ts.map +1 -0
  32. package/dist/src/components/control/action/search/CwAsyncSearch.d.ts +102 -0
  33. package/dist/src/components/control/action/search/CwAsyncSearch.d.ts.map +1 -0
  34. package/dist/src/components/control/action/search/CwSearch.d.ts +2 -0
  35. package/dist/src/components/control/action/search/CwSearch.d.ts.map +1 -1
  36. package/dist/src/components/control/action/search/searchKeyboardNavigation.d.ts +35 -0
  37. package/dist/src/components/control/action/search/searchKeyboardNavigation.d.ts.map +1 -0
  38. package/dist/src/components/control/action/tooltip-dialog/CwTooltipDialog.d.ts +19 -0
  39. package/dist/src/components/control/action/tooltip-dialog/CwTooltipDialog.d.ts.map +1 -0
  40. package/dist/src/components/control/choice/deprecated/CwDropdown.d.ts +19 -0
  41. package/dist/src/components/control/choice/deprecated/CwDropdown.d.ts.map +1 -0
  42. package/dist/src/components/control/choice/deprecated/CwDropdownNavigation.d.ts +21 -0
  43. package/dist/src/components/control/choice/deprecated/CwDropdownNavigation.d.ts.map +1 -0
  44. package/dist/src/components/control/choice/deprecated/MultiSelect_deprecated_.d.ts +24 -0
  45. package/dist/src/components/control/choice/deprecated/MultiSelect_deprecated_.d.ts.map +1 -0
  46. package/dist/src/components/control/choice/dropdown/CwDropdown.d.ts +19 -0
  47. package/dist/src/components/control/choice/dropdown/CwDropdown.d.ts.map +1 -0
  48. package/dist/src/components/control/choice/dropdown/CwDropdownContainer.d.ts +17 -0
  49. package/dist/src/components/control/choice/dropdown/CwDropdownContainer.d.ts.map +1 -0
  50. package/dist/src/components/control/choice/dropdown/CwDropdownNavigation.d.ts +21 -0
  51. package/dist/src/components/control/choice/dropdown/CwDropdownNavigation.d.ts.map +1 -0
  52. package/dist/src/components/control/choice/multiselect/CwHeadFilter.d.ts +17 -0
  53. package/dist/src/components/control/choice/multiselect/CwHeadFilter.d.ts.map +1 -0
  54. package/dist/src/components/control/choice/multiselect/CwMultiselect.d.ts +13 -0
  55. package/dist/src/components/control/choice/multiselect/CwMultiselect.d.ts.map +1 -0
  56. package/dist/src/components/control/choice/multiselect/CwOptionList.d.ts +14 -0
  57. package/dist/src/components/control/choice/multiselect/CwOptionList.d.ts.map +1 -0
  58. package/dist/src/components/control/choice/nav-menu/CwNavMenu.d.ts +78 -0
  59. package/dist/src/components/control/choice/nav-menu/CwNavMenu.d.ts.map +1 -0
  60. package/dist/src/components/control/choice/nav-menu/filterNavItems.d.ts +9 -0
  61. package/dist/src/components/control/choice/nav-menu/filterNavItems.d.ts.map +1 -0
  62. package/dist/src/components/control/choice/nav-menu/sortNavItems.d.ts +9 -0
  63. package/dist/src/components/control/choice/nav-menu/sortNavItems.d.ts.map +1 -0
  64. package/dist/src/components/control/input/file/CwFileUploadMultiple.d.ts +12 -0
  65. package/dist/src/components/control/input/file/CwFileUploadMultiple.d.ts.map +1 -1
  66. package/dist/src/components/control/input/image/CwInputImage.d.ts +17 -2
  67. package/dist/src/components/control/input/image/CwInputImage.d.ts.map +1 -1
  68. package/dist/src/components/control/input/new-dates/CwDateTimePicker2.d.ts +47 -0
  69. package/dist/src/components/control/input/new-dates/CwDateTimePicker2.d.ts.map +1 -0
  70. package/dist/src/components/custom/scheduler-temporal/CwSchedulerComp2.d.ts +24 -0
  71. package/dist/src/components/custom/scheduler-temporal/CwSchedulerComp2.d.ts.map +1 -0
  72. package/dist/src/components/custom/scheduler-temporal/CwSuperSchedulerComp.d.ts +86 -0
  73. package/dist/src/components/custom/scheduler-temporal/CwSuperSchedulerComp.d.ts.map +1 -0
  74. package/dist/src/components/custom/scheduler-temporal/components/EventRender.d.ts +10 -0
  75. package/dist/src/components/custom/scheduler-temporal/components/EventRender.d.ts.map +1 -0
  76. package/dist/src/components/custom/scheduler-temporal/components/ResourceListRender.d.ts +20 -0
  77. package/dist/src/components/custom/scheduler-temporal/components/ResourceListRender.d.ts.map +1 -0
  78. package/dist/src/components/custom/scheduler-temporal/components/ResourceRender.d.ts +14 -0
  79. package/dist/src/components/custom/scheduler-temporal/components/ResourceRender.d.ts.map +1 -0
  80. package/dist/src/components/custom/scheduler-temporal/components/day_headers/DayHeader.d.ts +11 -0
  81. package/dist/src/components/custom/scheduler-temporal/components/day_headers/DayHeader.d.ts.map +1 -0
  82. package/dist/src/components/custom/scheduler-temporal/components/day_headers/MonthHeader.d.ts +11 -0
  83. package/dist/src/components/custom/scheduler-temporal/components/day_headers/MonthHeader.d.ts.map +1 -0
  84. package/dist/src/components/custom/scheduler-temporal/components/day_headers/MyDaysHeader.d.ts +13 -0
  85. package/dist/src/components/custom/scheduler-temporal/components/day_headers/MyDaysHeader.d.ts.map +1 -0
  86. package/dist/src/components/custom/scheduler-temporal/components/day_headers/WeekHeader.d.ts +11 -0
  87. package/dist/src/components/custom/scheduler-temporal/components/day_headers/WeekHeader.d.ts.map +1 -0
  88. package/dist/src/components/custom/scheduler-temporal/components/resources_title_list/ResourcesTitleList.d.ts +14 -0
  89. package/dist/src/components/custom/scheduler-temporal/components/resources_title_list/ResourcesTitleList.d.ts.map +1 -0
  90. package/dist/src/components/custom/scheduler-temporal/components/scheduler_content_area/SchedulerContentArea.d.ts +23 -0
  91. package/dist/src/components/custom/scheduler-temporal/components/scheduler_content_area/SchedulerContentArea.d.ts.map +1 -0
  92. package/dist/src/components/custom/scheduler-temporal/components/scheduler_header/SchedulerHeader.d.ts +8 -0
  93. package/dist/src/components/custom/scheduler-temporal/components/scheduler_header/SchedulerHeader.d.ts.map +1 -0
  94. package/dist/src/components/custom/scheduler-temporal/components/scheduler_timeline/SchedulerTimeLine.d.ts +12 -0
  95. package/dist/src/components/custom/scheduler-temporal/components/scheduler_timeline/SchedulerTimeLine.d.ts.map +1 -0
  96. package/dist/src/components/custom/scheduler-temporal/components/time_headers/TimeHeader.d.ts +12 -0
  97. package/dist/src/components/custom/scheduler-temporal/components/time_headers/TimeHeader.d.ts.map +1 -0
  98. package/dist/src/components/custom/scheduler-temporal/components/time_headers/TimeHeaderRow.d.ts +10 -0
  99. package/dist/src/components/custom/scheduler-temporal/components/time_headers/TimeHeaderRow.d.ts.map +1 -0
  100. package/dist/src/components/custom/scheduler-temporal/components/time_line/TimeLine.d.ts +12 -0
  101. package/dist/src/components/custom/scheduler-temporal/components/time_line/TimeLine.d.ts.map +1 -0
  102. package/dist/src/components/custom/scheduler-temporal/logic/dates/addMinutesToDateFromPx.d.ts +2 -0
  103. package/dist/src/components/custom/scheduler-temporal/logic/dates/addMinutesToDateFromPx.d.ts.map +1 -0
  104. package/dist/src/components/custom/scheduler-temporal/logic/dates/daysBetweenTwoDates.d.ts +2 -0
  105. package/dist/src/components/custom/scheduler-temporal/logic/dates/daysBetweenTwoDates.d.ts.map +1 -0
  106. package/dist/src/components/custom/scheduler-temporal/logic/dates/daysBetweenTwoDatesWithoutCeil.d.ts +2 -0
  107. package/dist/src/components/custom/scheduler-temporal/logic/dates/daysBetweenTwoDatesWithoutCeil.d.ts.map +1 -0
  108. package/dist/src/components/custom/scheduler-temporal/logic/dates/getFormatedTimeForHeader.d.ts +7 -0
  109. package/dist/src/components/custom/scheduler-temporal/logic/dates/getFormatedTimeForHeader.d.ts.map +1 -0
  110. package/dist/src/components/custom/scheduler-temporal/logic/dates/getMonthHeaderData.d.ts +10 -0
  111. package/dist/src/components/custom/scheduler-temporal/logic/dates/getMonthHeaderData.d.ts.map +1 -0
  112. package/dist/src/components/custom/scheduler-temporal/logic/dates/getUtcToday.d.ts +2 -0
  113. package/dist/src/components/custom/scheduler-temporal/logic/dates/getUtcToday.d.ts.map +1 -0
  114. package/dist/src/components/custom/scheduler-temporal/logic/dates/getWeekHeaderDataFromWeekRange.d.ts +7 -0
  115. package/dist/src/components/custom/scheduler-temporal/logic/dates/getWeekHeaderDataFromWeekRange.d.ts.map +1 -0
  116. package/dist/src/components/custom/scheduler-temporal/logic/dates/listOfDatesToWeeks.d.ts +8 -0
  117. package/dist/src/components/custom/scheduler-temporal/logic/dates/listOfDatesToWeeks.d.ts.map +1 -0
  118. package/dist/src/components/custom/scheduler-temporal/logic/divisions/calculateDivisionType.d.ts +2 -0
  119. package/dist/src/components/custom/scheduler-temporal/logic/divisions/calculateDivisionType.d.ts.map +1 -0
  120. package/dist/src/components/custom/scheduler-temporal/logic/divisions/calculateDivisions.d.ts +2 -0
  121. package/dist/src/components/custom/scheduler-temporal/logic/divisions/calculateDivisions.d.ts.map +1 -0
  122. package/dist/src/components/custom/scheduler-temporal/logic/filtering/filterAndProcessResources.d.ts +4 -0
  123. package/dist/src/components/custom/scheduler-temporal/logic/filtering/filterAndProcessResources.d.ts.map +1 -0
  124. package/dist/src/components/custom/scheduler-temporal/logic/filtering/filterEvents.d.ts +3 -0
  125. package/dist/src/components/custom/scheduler-temporal/logic/filtering/filterEvents.d.ts.map +1 -0
  126. package/dist/src/components/custom/scheduler-temporal/logic/filtering/filterResources.d.ts +3 -0
  127. package/dist/src/components/custom/scheduler-temporal/logic/filtering/filterResources.d.ts.map +1 -0
  128. package/dist/src/components/custom/scheduler-temporal/logic/filtering/hasSameProperties.d.ts +3 -0
  129. package/dist/src/components/custom/scheduler-temporal/logic/filtering/hasSameProperties.d.ts.map +1 -0
  130. package/dist/src/components/custom/scheduler-temporal/logic/onDrop/OnDrop.d.ts +13 -0
  131. package/dist/src/components/custom/scheduler-temporal/logic/onDrop/OnDrop.d.ts.map +1 -0
  132. package/dist/src/components/custom/scheduler-temporal/logic/pixels/getHeightLineScheduler.d.ts +2 -0
  133. package/dist/src/components/custom/scheduler-temporal/logic/pixels/getHeightLineScheduler.d.ts.map +1 -0
  134. package/dist/src/components/custom/scheduler-temporal/logic/pixels/getPixelsForEvent.d.ts +7 -0
  135. package/dist/src/components/custom/scheduler-temporal/logic/pixels/getPixelsForEvent.d.ts.map +1 -0
  136. package/dist/src/components/custom/scheduler-temporal/logic/pixels/heightScheduler.d.ts +3 -0
  137. package/dist/src/components/custom/scheduler-temporal/logic/pixels/heightScheduler.d.ts.map +1 -0
  138. package/dist/src/components/custom/scheduler-temporal/logic/pixels/heightSchedulerPinned.d.ts +2 -0
  139. package/dist/src/components/custom/scheduler-temporal/logic/pixels/heightSchedulerPinned.d.ts.map +1 -0
  140. package/dist/src/components/custom/scheduler-temporal/logic/state_handle/doubleClickOnResource.d.ts +4 -0
  141. package/dist/src/components/custom/scheduler-temporal/logic/state_handle/doubleClickOnResource.d.ts.map +1 -0
  142. package/dist/src/components/custom/scheduler-temporal/logic/state_handle/handlePropChanges.d.ts +6 -0
  143. package/dist/src/components/custom/scheduler-temporal/logic/state_handle/handlePropChanges.d.ts.map +1 -0
  144. package/dist/src/components/custom/scheduler-temporal/logic/state_handle/handleResourceChange.d.ts +5 -0
  145. package/dist/src/components/custom/scheduler-temporal/logic/state_handle/handleResourceChange.d.ts.map +1 -0
  146. package/dist/src/components/custom/scheduler-temporal/logic/state_handle/onDragOver.d.ts +2 -0
  147. package/dist/src/components/custom/scheduler-temporal/logic/state_handle/onDragOver.d.ts.map +1 -0
  148. package/dist/src/components/custom/scheduler-temporal/logic/state_handle/onDropEventToResource.d.ts +5 -0
  149. package/dist/src/components/custom/scheduler-temporal/logic/state_handle/onDropEventToResource.d.ts.map +1 -0
  150. package/dist/src/components/custom/scheduler-temporal/logic/state_handle/onResizeEvent.d.ts +4 -0
  151. package/dist/src/components/custom/scheduler-temporal/logic/state_handle/onResizeEvent.d.ts.map +1 -0
  152. package/dist/src/components/custom/scheduler-temporal/logic/strings/compareStrings.d.ts +2 -0
  153. package/dist/src/components/custom/scheduler-temporal/logic/strings/compareStrings.d.ts.map +1 -0
  154. package/dist/src/components/custom/scheduler-temporal/logic/strings/getGUID.d.ts +2 -0
  155. package/dist/src/components/custom/scheduler-temporal/logic/strings/getGUID.d.ts.map +1 -0
  156. package/dist/src/components/custom/scheduler-temporal/logic/ui/checkIfSlotAvailable.d.ts +3 -0
  157. package/dist/src/components/custom/scheduler-temporal/logic/ui/checkIfSlotAvailable.d.ts.map +1 -0
  158. package/dist/src/components/custom/scheduler-temporal/logic/ui/getEventsOfResource.d.ts +6 -0
  159. package/dist/src/components/custom/scheduler-temporal/logic/ui/getEventsOfResource.d.ts.map +1 -0
  160. package/dist/src/components/custom/scheduler-temporal/logic/ui/getHasPropsChanged.d.ts +4 -0
  161. package/dist/src/components/custom/scheduler-temporal/logic/ui/getHasPropsChanged.d.ts.map +1 -0
  162. package/dist/src/components/custom/scheduler-temporal/logic/ui/getTimeHeaders.d.ts +2 -0
  163. package/dist/src/components/custom/scheduler-temporal/logic/ui/getTimeHeaders.d.ts.map +1 -0
  164. package/dist/src/components/custom/scheduler-temporal/logic/ui/isAllowedToMove.d.ts +3 -0
  165. package/dist/src/components/custom/scheduler-temporal/logic/ui/isAllowedToMove.d.ts.map +1 -0
  166. package/dist/src/components/custom/scheduler-temporal/logic/ui/shouldTriggerScroll.d.ts +4 -0
  167. package/dist/src/components/custom/scheduler-temporal/logic/ui/shouldTriggerScroll.d.ts.map +1 -0
  168. package/dist/src/components/custom/scheduler-temporal/logic/ui/updateResourceVisibility.d.ts +3 -0
  169. package/dist/src/components/custom/scheduler-temporal/logic/ui/updateResourceVisibility.d.ts.map +1 -0
  170. package/dist/src/components/custom/scheduler-temporal/state/CblDragAndDrop.d.ts +11 -0
  171. package/dist/src/components/custom/scheduler-temporal/state/CblDragAndDrop.d.ts.map +1 -0
  172. package/dist/src/components/custom/scheduler-temporal/state/CwSchedulerProps.d.ts +43 -0
  173. package/dist/src/components/custom/scheduler-temporal/state/CwSchedulerProps.d.ts.map +1 -0
  174. package/dist/src/components/custom/scheduler-temporal/state/Resource.d.ts +14 -0
  175. package/dist/src/components/custom/scheduler-temporal/state/Resource.d.ts.map +1 -0
  176. package/dist/src/components/custom/scheduler-temporal/state/State.d.ts +25 -0
  177. package/dist/src/components/custom/scheduler-temporal/state/State.d.ts.map +1 -0
  178. package/dist/src/components/custom/scheduler-temporal/state/cblEvent.d.ts +18 -0
  179. package/dist/src/components/custom/scheduler-temporal/state/cblEvent.d.ts.map +1 -0
  180. package/dist/src/components/custom/scheduler-temporal/state/cblEventCompProps.d.ts +7 -0
  181. package/dist/src/components/custom/scheduler-temporal/state/cblEventCompProps.d.ts.map +1 -0
  182. package/dist/src/components/custom/scheduler-temporal/state/resourceCompProps2.d.ts +6 -0
  183. package/dist/src/components/custom/scheduler-temporal/state/resourceCompProps2.d.ts.map +1 -0
  184. package/dist/src/components/display/data/table/CwTable.d.ts +4 -1
  185. package/dist/src/components/display/data/table/CwTable.d.ts.map +1 -1
  186. package/dist/src/components/display/data/table-serverside/CwTableServerSide.d.ts +4 -1
  187. package/dist/src/components/display/data/table-serverside/CwTableServerSide.d.ts.map +1 -1
  188. package/dist/src/components/display/data/table_sortable/CwSortableTable.d.ts +4 -2
  189. package/dist/src/components/display/data/table_sortable/CwSortableTable.d.ts.map +1 -1
  190. package/dist/src/components/display/graphics/icon/CwIcon.d.ts +1 -1
  191. package/dist/src/components/display/graphics/icon/CwIcon.d.ts.map +1 -1
  192. package/dist/src/components/display/graphics/loading/CwLoading.d.ts +3 -14
  193. package/dist/src/components/display/graphics/loading/CwLoading.d.ts.map +1 -1
  194. package/dist/src/components/display/graphics/loading/loadingConfig.d.ts +16 -0
  195. package/dist/src/components/display/graphics/loading/loadingConfig.d.ts.map +1 -0
  196. package/dist/src/components/display/graphics/progress/CwProgress.d.ts +36 -0
  197. package/dist/src/components/display/graphics/progress/CwProgress.d.ts.map +1 -0
  198. package/dist/src/components/display/graphics/skeleton/CwSkeleton.d.ts +31 -0
  199. package/dist/src/components/display/graphics/skeleton/CwSkeleton.d.ts.map +1 -0
  200. package/dist/src/components/display/graphics/skeleton/CwSkeletonCard.d.ts +21 -0
  201. package/dist/src/components/display/graphics/skeleton/CwSkeletonCard.d.ts.map +1 -0
  202. package/dist/src/components/display/graphics/skeleton/normalizeSkeletonCount.d.ts +8 -0
  203. package/dist/src/components/display/graphics/skeleton/normalizeSkeletonCount.d.ts.map +1 -0
  204. package/dist/src/components/display/graphics/skeleton/skeletonCellWidth.d.ts +8 -0
  205. package/dist/src/components/display/graphics/skeleton/skeletonCellWidth.d.ts.map +1 -0
  206. package/dist/src/components/display/text/tag/CwTag.d.ts +15 -0
  207. package/dist/src/components/display/text/tag/CwTag.d.ts.map +1 -0
  208. package/dist/src/components/display/text/tooltip/CwTooltip.d.ts +11 -0
  209. package/dist/src/components/display/text/tooltip/CwTooltip.d.ts.map +1 -0
  210. package/dist/src/components/layout/card/CwCard.d.ts +3 -1
  211. package/dist/src/components/layout/card/CwCard.d.ts.map +1 -1
  212. package/dist/src/components/layout/card/CwCardList.d.ts +4 -2
  213. package/dist/src/components/layout/card/CwCardList.d.ts.map +1 -1
  214. package/dist/src/components/layout/list/key-value/CwKeyValueList.d.ts +4 -0
  215. package/dist/src/components/layout/list/key-value/CwKeyValueList.d.ts.map +1 -1
  216. package/dist/src/components/layout/master-detail/CwMasterDetail.d.ts +4 -0
  217. package/dist/src/components/layout/master-detail/CwMasterDetail.d.ts.map +1 -1
  218. package/dist/src/components/layout/modal/legacy/cw_modal_confirm.d.ts +16 -0
  219. package/dist/src/components/layout/modal/legacy/cw_modal_confirm.d.ts.map +1 -0
  220. package/dist/src/components/layout/modal/legacy/cw_modal_iframe.d.ts +21 -0
  221. package/dist/src/components/layout/modal/legacy/cw_modal_iframe.d.ts.map +1 -0
  222. package/dist/src/components/layout/tabs/CwTabs.d.ts +7 -0
  223. package/dist/src/components/layout/tabs/CwTabs.d.ts.map +1 -1
  224. package/dist/src/index.d.ts +6 -2
  225. package/dist/src/index.d.ts.map +1 -1
  226. package/dist/src/playground/PlaygroundApp.d.ts.map +1 -1
  227. package/dist/src/playground/pages/CwFileUploadMultiplePage.d.ts +3 -0
  228. package/dist/src/playground/pages/CwFileUploadMultiplePage.d.ts.map +1 -0
  229. package/dist/src/playground/pages/CwInputImagePage.d.ts.map +1 -1
  230. package/dist/src/playground/pages/CwNavMenuPage.d.ts +3 -0
  231. package/dist/src/playground/pages/CwNavMenuPage.d.ts.map +1 -0
  232. package/dist/src/playground/pages/IconLibraryPage.d.ts +3 -0
  233. package/dist/src/playground/pages/IconLibraryPage.d.ts.map +1 -0
  234. package/dist/src/playground/pages/LoadingPage.d.ts +3 -0
  235. package/dist/src/playground/pages/LoadingPage.d.ts.map +1 -0
  236. package/dist/src/playground/pages/ProgressPage.d.ts +3 -0
  237. package/dist/src/playground/pages/ProgressPage.d.ts.map +1 -0
  238. package/dist/src/playground/pages/SelectorsPage.d.ts.map +1 -1
  239. package/dist/src/playground/pages/SkeletonPage.d.ts +3 -0
  240. package/dist/src/playground/pages/SkeletonPage.d.ts.map +1 -0
  241. package/dist/test/components/control/action/search/searchKeyboardNavigation.test.d.ts +2 -0
  242. package/dist/test/components/control/action/search/searchKeyboardNavigation.test.d.ts.map +1 -0
  243. package/dist/test/components/control/choice/nav-menu/CwNavMenu.test.d.ts +2 -0
  244. package/dist/test/components/control/choice/nav-menu/CwNavMenu.test.d.ts.map +1 -0
  245. package/dist/test/components/control/choice/nav-menu/filterNavItems.test.d.ts +2 -0
  246. package/dist/test/components/control/choice/nav-menu/filterNavItems.test.d.ts.map +1 -0
  247. package/dist/test/components/control/choice/nav-menu/sortNavItems.test.d.ts +2 -0
  248. package/dist/test/components/control/choice/nav-menu/sortNavItems.test.d.ts.map +1 -0
  249. package/dist/test/components/control/input/file/fileMatchesAccept.test.d.ts +2 -0
  250. package/dist/test/components/control/input/file/fileMatchesAccept.test.d.ts.map +1 -0
  251. package/dist/test/components/control/input/image/readImageFileAsDataUrl.test.d.ts +2 -0
  252. package/dist/test/components/control/input/image/readImageFileAsDataUrl.test.d.ts.map +1 -0
  253. package/dist/test/components/display/data/table/CwTable.test.d.ts +2 -0
  254. package/dist/test/components/display/data/table/CwTable.test.d.ts.map +1 -0
  255. package/dist/test/components/display/data/table-serverside/CwTableServerSide.test.d.ts +2 -0
  256. package/dist/test/components/display/data/table-serverside/CwTableServerSide.test.d.ts.map +1 -0
  257. package/dist/test/components/display/data/table_sortable/CwSortableTable.test.d.ts +2 -0
  258. package/dist/test/components/display/data/table_sortable/CwSortableTable.test.d.ts.map +1 -0
  259. package/dist/test/components/display/graphics/loading/CwLoading.test.d.ts +2 -0
  260. package/dist/test/components/display/graphics/loading/CwLoading.test.d.ts.map +1 -0
  261. package/dist/test/components/display/graphics/progress/CwProgress.test.d.ts +2 -0
  262. package/dist/test/components/display/graphics/progress/CwProgress.test.d.ts.map +1 -0
  263. package/dist/test/components/display/graphics/skeleton/CwSkeleton.test.d.ts +2 -0
  264. package/dist/test/components/display/graphics/skeleton/CwSkeleton.test.d.ts.map +1 -0
  265. package/dist/test/components/display/graphics/skeleton/CwSkeletonCard.test.d.ts +2 -0
  266. package/dist/test/components/display/graphics/skeleton/CwSkeletonCard.test.d.ts.map +1 -0
  267. package/dist/test/components/display/graphics/skeleton/normalizeSkeletonCount.test.d.ts +2 -0
  268. package/dist/test/components/display/graphics/skeleton/normalizeSkeletonCount.test.d.ts.map +1 -0
  269. package/dist/test/components/display/graphics/skeleton/skeletonCellWidth.test.d.ts +2 -0
  270. package/dist/test/components/display/graphics/skeleton/skeletonCellWidth.test.d.ts.map +1 -0
  271. package/dist/test/components/layout/card/CwCard.test.d.ts +2 -0
  272. package/dist/test/components/layout/card/CwCard.test.d.ts.map +1 -0
  273. package/dist/test/components/layout/card/CwCardList.test.d.ts +2 -0
  274. package/dist/test/components/layout/card/CwCardList.test.d.ts.map +1 -0
  275. package/dist/test/components/layout/list/key-value/CwKeyValueList.test.d.ts +2 -0
  276. package/dist/test/components/layout/list/key-value/CwKeyValueList.test.d.ts.map +1 -0
  277. package/dist/test/components/layout/master-detail/CwMasterDetail.test.d.ts +2 -0
  278. package/dist/test/components/layout/master-detail/CwMasterDetail.test.d.ts.map +1 -0
  279. package/dist/test/jest.setup.d.ts +2 -0
  280. package/dist/test/jest.setup.d.ts.map +1 -0
  281. package/package.json +1 -2
package/dist/index.es.js CHANGED
@@ -161,12 +161,7 @@ function getContrastColor(color) {
161
161
  return `hsl(${hsl.h}, ${contrastS}%, ${targetL}%)`;
162
162
  }
163
163
 
164
- const SVG_ICONS = {
165
- 'sortable-asc': (jsxs("svg", { width: "16", height: "16", viewBox: "0 0 128 128", fill: "currentColor", children: [jsx("path", { d: "M93.1675 73.1739C94.5691 74.5758 94.7323 76.7924 93.5515 78.3846L93.1675 78.8326L63.6741 108.326L34.1755 78.8326C32.6908 77.3518 32.6014 74.9761 33.9708 73.3881C35.3401 71.8001 37.7033 71.5391 39.3861 72.7899L39.8341 73.1739L63.6741 97.0137L87.5088 73.1739C88.9104 71.7726 91.1274 71.6092 92.7194 72.7899L93.1674 73.1739H93.1675Z", opacity: "0.3" }), jsx("path", { d: "M34.1714 55.1518C32.7697 53.7499 32.6066 51.5333 33.7874 49.9411L34.1714 49.4931L63.6647 20L93.1634 49.4931C94.6481 50.9739 94.7375 53.3496 93.3681 54.9376C91.9987 56.5256 89.6356 56.7866 87.9527 55.5358L87.5047 55.1517L63.6647 31.312L39.8301 55.1518C38.4285 56.5531 36.2115 56.7165 34.6195 55.5358L34.1715 55.1518L34.1714 55.1518Z", opacity: "1" })] })),
166
- 'sortable-desc': (jsxs("svg", { width: "16", height: "16", viewBox: "0 0 128 128", fill: "currentColor", children: [jsx("path", { d: "M93.1675 73.1739C94.5691 74.5758 94.7323 76.7924 93.5515 78.3846L93.1675 78.8326L63.6741 108.326L34.1755 78.8326C32.6908 77.3518 32.6014 74.9761 33.9708 73.3881C35.3401 71.8001 37.7033 71.5391 39.3861 72.7899L39.8341 73.1739L63.6741 97.0137L87.5088 73.1739C88.9104 71.7726 91.1274 71.6092 92.7194 72.7899L93.1674 73.1739H93.1675Z", opacity: "1" }), jsx("path", { d: "M34.1714 55.1518C32.7697 53.7499 32.6066 51.5333 33.7874 49.9411L34.1714 49.4931L63.6647 20L93.1634 49.4931C94.6481 50.9739 94.7375 53.3496 93.3681 54.9376C91.9987 56.5256 89.6356 56.7866 87.9527 55.5358L87.5047 55.1517L63.6647 31.312L39.8301 55.1518C38.4285 56.5531 36.2115 56.7165 34.6195 55.5358L34.1715 55.1518L34.1714 55.1518Z", opacity: "0.3" })] })),
167
- };
168
-
169
- var styles$u = {"cw-tooltip-content":"cw-tooltip-module__cw-tooltip-content__RZczd","cw-tooltip":"cw-tooltip-module__cw-tooltip__1KYig"};
164
+ var styles$x = {"cw-tooltip-content":"cw-tooltip-module__cw-tooltip-content__RZczd","cw-tooltip":"cw-tooltip-module__cw-tooltip__1KYig"};
170
165
 
171
166
  // Constants
172
167
  const margin$1 = 16;
@@ -456,7 +451,7 @@ const CwTooltipManager = () => {
456
451
  if (!state.isVisible || !state.content) {
457
452
  return null;
458
453
  }
459
- return createPortal(jsx("div", { ref: tooltipRef, className: styles$u["cw-tooltip-content"], "data-position": actualPosition, "data-visible": state.isVisible, "data-inline": state.displayInline, style: {
454
+ return createPortal(jsx("div", { ref: tooltipRef, className: styles$x["cw-tooltip-content"], "data-position": actualPosition, "data-visible": state.isVisible, "data-inline": state.displayInline, style: {
460
455
  top: `${tooltipPosition.top}px`,
461
456
  left: `${tooltipPosition.left}px`,
462
457
  opacity: (isPositioned && !isMeasuring) ? 1 : 0,
@@ -537,16 +532,22 @@ const CwTooltipNew = ({ children, content = null, position = "right", dissapears
537
532
  useEffect(() => {
538
533
  ensureTooltipManager();
539
534
  }, []);
540
- return (jsx("div", { ref: containerRef, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, style: overlayStyle, "data-inline": displayInline, className: styles$u["cw-tooltip"], children: children }));
535
+ return (jsx("div", { ref: containerRef, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, style: overlayStyle, "data-inline": displayInline, className: styles$x["cw-tooltip"], children: children }));
536
+ };
537
+
538
+ const SVG_ICONS = {
539
+ 'sortable-asc': (jsxs("svg", { width: "16", height: "16", viewBox: "0 0 128 128", fill: "currentColor", children: [jsx("path", { d: "M93.1675 73.1739C94.5691 74.5758 94.7323 76.7924 93.5515 78.3846L93.1675 78.8326L63.6741 108.326L34.1755 78.8326C32.6908 77.3518 32.6014 74.9761 33.9708 73.3881C35.3401 71.8001 37.7033 71.5391 39.3861 72.7899L39.8341 73.1739L63.6741 97.0137L87.5088 73.1739C88.9104 71.7726 91.1274 71.6092 92.7194 72.7899L93.1674 73.1739H93.1675Z", opacity: "0.3" }), jsx("path", { d: "M34.1714 55.1518C32.7697 53.7499 32.6066 51.5333 33.7874 49.9411L34.1714 49.4931L63.6647 20L93.1634 49.4931C94.6481 50.9739 94.7375 53.3496 93.3681 54.9376C91.9987 56.5256 89.6356 56.7866 87.9527 55.5358L87.5047 55.1517L63.6647 31.312L39.8301 55.1518C38.4285 56.5531 36.2115 56.7165 34.6195 55.5358L34.1715 55.1518L34.1714 55.1518Z", opacity: "1" })] })),
540
+ 'sortable-desc': (jsxs("svg", { width: "16", height: "16", viewBox: "0 0 128 128", fill: "currentColor", children: [jsx("path", { d: "M93.1675 73.1739C94.5691 74.5758 94.7323 76.7924 93.5515 78.3846L93.1675 78.8326L63.6741 108.326L34.1755 78.8326C32.6908 77.3518 32.6014 74.9761 33.9708 73.3881C35.3401 71.8001 37.7033 71.5391 39.3861 72.7899L39.8341 73.1739L63.6741 97.0137L87.5088 73.1739C88.9104 71.7726 91.1274 71.6092 92.7194 72.7899L93.1674 73.1739H93.1675Z", opacity: "1" }), jsx("path", { d: "M34.1714 55.1518C32.7697 53.7499 32.6066 51.5333 33.7874 49.9411L34.1714 49.4931L63.6647 20L93.1634 49.4931C94.6481 50.9739 94.7375 53.3496 93.3681 54.9376C91.9987 56.5256 89.6356 56.7866 87.9527 55.5358L87.5047 55.1517L63.6647 31.312L39.8301 55.1518C38.4285 56.5531 36.2115 56.7165 34.6195 55.5358L34.1715 55.1518L34.1714 55.1518Z", opacity: "0.3" })] })),
541
541
  };
542
542
 
543
543
  function CwIcon(props) {
544
- const { iconId, color, size, title, tooltipPosition = 'bottom', ...iconProps } = props;
544
+ const { iconId, color, size, className, title, tooltipPosition = 'bottom', ...iconProps } = props;
545
545
  const getClassName = (baseClass) => {
546
546
  return [
547
547
  baseClass,
548
548
  color && `cw-color-${color}`,
549
- size && `cw-font-size-${size}`
549
+ size && `cw-font-size-${size}`,
550
+ className
550
551
  ].filter(Boolean).join(' ');
551
552
  };
552
553
  let iconElement;
@@ -958,49 +959,128 @@ function CwImageZoom(image) {
958
959
  } }), jsx("div", { style: { color: "#fff", fontSize: "1rem", textAlign: "center" }, children: selectedImage.filename && jsx("div", { children: selectedImage.filename }) })] }))] }));
959
960
  }
960
961
 
962
+ let defaults = {};
963
+ /**
964
+ * Register global CwLoading defaults. Call once at app init, before the first render.
965
+ * Merges into any previously configured defaults.
966
+ */
967
+ function configureCwLoading(next) {
968
+ defaults = { ...defaults, ...next };
969
+ }
970
+ /** Read the currently configured CwLoading defaults. */
971
+ function getCwLoadingDefaults() {
972
+ return defaults;
973
+ }
974
+
961
975
  /**
962
- * CwLoading
976
+ * CwLoading — a spinner with optional text that dims the wrapped content while loading.
963
977
  *
964
- * A versatile loading component that shows a spinner with optional text
965
- * and disables the wrapped content while in loading state.
978
+ * Icon resolves as `iconName` prop → `getCwLoadingDefaults().icon` → none (neutral ring).
966
979
  *
967
980
  * @example
968
- * // Basic usage
969
981
  * <CwLoading isLoading={isSubmitting}>
970
982
  * <form>...</form>
971
983
  * </CwLoading>
972
- *
973
- * // With custom text and size
974
- * <CwLoading
975
- * isLoading={isLoading}
976
- * text="Please wait..."
977
- * size="large"
978
- * >
979
- * <UserProfile />
980
- * </CwLoading>
981
984
  */
982
- function CwLoading({ isLoading = false, text = '', size = 'regular', iconPosition = 'outside', iconName = 'cwi-plane-solid', animation = 'spin', children }) {
983
- const iconClasses = `cwi-icons ${iconName || ''}`;
984
- return (jsxs("div", { "aria-busy": isLoading, className: isLoading ? 'cw-loading-container' : '', "data-children": !!children, children: [isLoading && (jsxs("div", { className: "cw-loading-content", "data-size": size, "data-animation": animation, children: [jsx("div", { className: "cw-loading", "data-icon-position": iconPosition, children: jsx("span", { className: iconClasses }) }), text && (jsx("p", { children: text }))] })), jsx("div", { className: isLoading ? 'cw-loading-disabled-content' : '', children: children })] }));
985
+ function CwLoading({ isLoading = false, text = '', size = 'regular', iconPosition = 'outside', iconName, animation = 'spin', children }) {
986
+ let overlay = null;
987
+ if (isLoading) {
988
+ const resolvedIcon = iconName ?? getCwLoadingDefaults().icon;
989
+ overlay = (jsxs("div", { className: "cw-loading-content", "data-size": size, "data-animation": animation, role: "status", "aria-label": text || 'Loading', children: [jsx("div", { className: "cw-loading", "data-icon-position": iconPosition, "data-has-icon": !!resolvedIcon, children: resolvedIcon && jsx("span", { className: `cwi-icons ${resolvedIcon}` }) }), text && (jsx("p", { children: text }))] }));
990
+ }
991
+ return (jsxs("div", { "aria-busy": isLoading, className: "cw-loading-container", "data-children": !!children, children: [overlay, jsx("div", { className: "cw-loading-disabled-content", children: children })] }));
985
992
  }
986
993
 
994
+ var styles$w = {"skeleton":"cw-skeleton-module__skeleton__Jvx2x","group":"cw-skeleton-module__group__Cm8AU"};
995
+
996
+ /*
997
+ * Internal helper for skeleton allocations (CwSkeleton, tables, cards).
998
+ * Not exported from the library barrel - not a public API.
999
+ */
1000
+ /** Upper bound so a pathological count cannot allocate an unbounded number of nodes. */
1001
+ const MAX_SKELETON_COUNT = 100;
987
1002
  /**
988
- * @deprecated since may 2025. Use <CwLoading size="small"> instead.
1003
+ * Normalizes a skeleton count to a finite, floored, non-negative integer capped at
1004
+ * MAX_SKELETON_COUNT. Falls back to `fallback` for undefined, NaN, non-finite or
1005
+ * non-positive input, so valid inputs keep the public default behaviour and only
1006
+ * pathological ones are bounded.
1007
+ */
1008
+ function normalizeSkeletonCount(value, fallback) {
1009
+ if (value === undefined || !Number.isFinite(value) || value < 1) {
1010
+ return fallback;
1011
+ }
1012
+ return Math.min(Math.floor(value), MAX_SKELETON_COUNT);
1013
+ }
1014
+
1015
+ /**
1016
+ * CwSkeleton - a shimmering placeholder that reserves the shape of content while it loads.
989
1017
  *
990
- * This component will be removed in a future release.
1018
+ * Renders inline <span> elements so it can sit inside text-level contexts. Sizing flows
1019
+ * through component-scoped custom properties; only the props the caller provides are set
1020
+ * inline, so the CSS defaults per variant (and the 60% last-line rule) stay in charge.
991
1021
  *
992
1022
  * @example
993
- * // Instead of:
994
- * <CwLoadingSmall />
995
- *
996
- * // Use:
997
- * <CwLoading size="small" />
1023
+ * <CwSkeleton count={3} />
1024
+ * <CwSkeleton variant="circle" />
1025
+ * <CwSkeleton variant="rect" height="10rem" />
998
1026
  */
999
- function CwLoadingSmall(CwelltLoadingAppointements) {
1000
- return (jsx("div", { children: CwelltLoadingAppointements.isLoading === true ? (jsx("div", { className: "cw-loading-container", children: jsx("div", { className: "cw-loading" }) })) : (jsx("div", {})) }));
1027
+ function CwSkeleton({ variant = 'text', width, height, count = 1, radius, gap }) {
1028
+ // Only forward the custom properties the caller actually set; CSS declares the defaults.
1029
+ const style = {
1030
+ ...(width !== undefined && { '--skeleton-width': width }),
1031
+ ...(height !== undefined && { '--skeleton-height': height }),
1032
+ ...(radius !== undefined && { '--skeleton-radius': radius })
1033
+ };
1034
+ // The un-hashed cw-skeleton / cw-skeleton-group classes carry no styles in the
1035
+ // library - they are stable public hooks for exceptional external overrides.
1036
+ const skeletonClassName = ['cw-skeleton', styles$w.skeleton].filter(Boolean).join(' ');
1037
+ const groupClassName = ['cw-skeleton-group', styles$w.group].filter(Boolean).join(' ');
1038
+ const lineCount = normalizeSkeletonCount(count, 1);
1039
+ if (lineCount <= 1) {
1040
+ return (jsx("span", { className: skeletonClassName, "data-variant": variant, "aria-hidden": "true", style: style }));
1041
+ }
1042
+ const skeletonElements = Array.from({ length: lineCount }, (_, index) => (jsx("span", { className: skeletonClassName, "data-variant": variant, style: style }, index)));
1043
+ const groupStyle = {
1044
+ ...(gap !== undefined && { '--skeleton-gap': gap })
1045
+ };
1046
+ return (jsx("span", { className: groupClassName, "aria-hidden": "true", style: groupStyle, children: skeletonElements }));
1001
1047
  }
1002
1048
 
1003
- var styles$t = {"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"};
1049
+ 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"};
1050
+
1051
+ /**
1052
+ * CwProgress - a determinate or indeterminate progress bar.
1053
+ *
1054
+ * Use it for measurable operations (imports, uploads, batch jobs). For short
1055
+ * unmeasurable waits use CwLoading; for initial layout loads use CwSkeleton.
1056
+ *
1057
+ * @example
1058
+ * <CwProgress value={62} label="Import" color="success" />
1059
+ * <CwProgress indeterminate label="Uploading" />
1060
+ */
1061
+ function CwProgress({ value, indeterminate = false, label, rightLabel, size = 'regular', layout = 'row', color = 'primary', monoValue = false, prominent = false }) {
1062
+ const labelId = React__default.useId();
1063
+ // Determinate: a missing or non-finite value is treated as 0 (never NaN), then
1064
+ // clamped to [0,100] for aria-valuenow and the fill width. Indeterminate has no value.
1065
+ const clamped = indeterminate
1066
+ ? undefined
1067
+ : Math.min(Math.max(Number.isFinite(value) ? value : 0, 0), 100);
1068
+ const percent = clamped !== undefined ? Math.round(clamped) : undefined;
1069
+ const showValue = rightLabel !== undefined || (!indeterminate && percent !== undefined);
1070
+ const valueText = rightLabel ?? (percent !== undefined ? `${percent}%` : '');
1071
+ // The un-hashed cw-progress class carries no styles in the library - a stable
1072
+ // public hook for exceptional external overrides only.
1073
+ const rootClassName = ['cw-progress', styles$v.progress].filter(Boolean).join(' ');
1074
+ const labelSpan = label ? jsx("span", { className: styles$v.label, id: labelId, children: label }) : null;
1075
+ const valueLabel = showValue ? (jsx("span", { className: styles$v.value, "data-mono": monoValue || undefined, children: valueText })) : null;
1076
+ return (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) && (jsxs("header", { className: styles$v.header, children: [labelSpan, valueLabel] })), layout === 'row' && labelSpan, jsx("div", { className: styles$v.track, role: "progressbar", ...(label && { 'aria-labelledby': labelId }), ...(!indeterminate && percent !== undefined && {
1077
+ 'aria-valuenow': percent,
1078
+ 'aria-valuemin': 0,
1079
+ 'aria-valuemax': 100
1080
+ }), children: jsx("div", { className: styles$v.fill, style: !indeterminate && clamped !== undefined ? { width: `${clamped}%` } : undefined }) }), layout === 'row' && valueLabel] }));
1081
+ }
1082
+
1083
+ var styles$u = {"cw-generic-tooltip-content":"cw-generic-tooltip-module__cw-generic-tooltip-content__la-Si","cw-generic-tooltip":"cw-generic-tooltip-module__cw-generic-tooltip__Ij76M"};
1004
1084
 
1005
1085
  // Constants moved outside to prevent recreation
1006
1086
  const margin = 16;
@@ -1123,12 +1203,12 @@ const CwGenericTooltip = ({ children, content = null, position = defaultPosition
1123
1203
  const { setTooltipTimeout, clearTooltipTimeout } = useTooltipDelay(() => {
1124
1204
  setIsVisible(true);
1125
1205
  }, showDelay);
1126
- const { position: tooltipPosition, actualPosition } = useTooltipPosition(isVisible, containerRef, position, styles$t["cw-generic-tooltip-content"]);
1206
+ const { position: tooltipPosition, actualPosition } = useTooltipPosition(isVisible, containerRef, position, styles$u["cw-generic-tooltip-content"]);
1127
1207
  // Memoize tooltip content creation
1128
1208
  const tooltipContent = useMemo(() => {
1129
1209
  if (hide || !isVisible || !content)
1130
1210
  return null;
1131
- return createPortal(jsx("div", { className: styles$t["cw-generic-tooltip-content"], "data-position": actualPosition, "data-visible": isVisible, "data-inline": displayInline, style: {
1211
+ return createPortal(jsx("div", { className: styles$u["cw-generic-tooltip-content"], "data-position": actualPosition, "data-visible": isVisible, "data-inline": displayInline, style: {
1132
1212
  position: 'fixed',
1133
1213
  top: `${tooltipPosition.top}px`,
1134
1214
  left: `${tooltipPosition.left}px`,
@@ -1143,7 +1223,7 @@ const CwGenericTooltip = ({ children, content = null, position = defaultPosition
1143
1223
  clearTooltipTimeout();
1144
1224
  setIsVisible(false);
1145
1225
  }, [clearTooltipTimeout]);
1146
- return (jsxs("div", { ref: containerRef, className: styles$t["cw-generic-tooltip"], onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, style: overlayStyle, "data-inline": displayInline, children: [tooltipContent, children] }));
1226
+ return (jsxs("div", { ref: containerRef, className: styles$u["cw-generic-tooltip"], onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, style: overlayStyle, "data-inline": displayInline, children: [tooltipContent, children] }));
1147
1227
  };
1148
1228
 
1149
1229
  const CwButton = React__default.forwardRef(function CwButton({ text, variant = 'solid', color = 'primary', size = 'medium', iconPosition = 'left', pressed, className = '', icon = "", title, tooltipPosition = "bottom", children, ...buttonProps }, ref) {
@@ -1205,7 +1285,7 @@ function CwModal(custModalProps) {
1205
1285
  return (jsx("div", { children: custModalProps.modalState && (jsxs("div", { className: custModalProps.classNameModalOverlay + " cwelltModalOverlay", children: [jsx("div", { className: "cwelltModalOverlayBg", onClick: custModalProps.onCloseModal }), jsx(Draggable, { disabled: isModalDisabled, axis: "both", nodeRef: draggableRef, children: jsxs("div", { className: custModalProps.classNameModal + " cwelltContainerModal", ref: draggableRef, style: widthModalDef !== "40em" ? modalStyle.widthCustomStyle : modalStyle.widthDefStyle, children: [jsxs("div", { className: "cwelltModalHeader", onMouseOver: cwelltOnMouseOverModal, onMouseOut: cwelltOnMouseOutModal, children: [jsx("div", { className: "cwelltModalTitle", children: custModalProps.titleModal }), jsx("button", { className: "cwelltBtnCloseModal", onClick: custModalProps.onCloseModal, children: jsx("span", { className: "cwelltCloseIcon" }) })] }), jsx("div", { className: "cwelltModalBody", children: jsx("div", { className: "cwelltContainerModalBody", style: { position: "relative" }, children: custModalProps.children }) }), isHide === false ? (jsx("footer", { className: "legacy-modal-footer", onMouseOver: cwelltOnMouseOverModal, onMouseOut: cwelltOnMouseOutModal, children: jsx(CwButton, { variant: "icon", icon: "save", title: "Save", onClick: custModalProps.onSaveModal, form: custModalProps.formSaveModal, hidden: custModalProps.HideBtnModal, type: custModalProps.HtmlSubmitModal }) })) : (jsx("div", { style: { display: "none" } }))] }) })] })) }));
1206
1286
  }
1207
1287
 
1208
- var styles$s = {"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"};
1288
+ var styles$t = {"overlayPositioned":"CwConfirmationPopup-module__overlayPositioned__11qYB","popup":"CwConfirmationPopup-module__popup__ahPjM","message":"CwConfirmationPopup-module__message__MnNL4","buttons":"CwConfirmationPopup-module__buttons__fGYYE","button":"CwConfirmationPopup-module__button__ugYQE","confirmButton":"CwConfirmationPopup-module__confirmButton__rTP4S","cancelButton":"CwConfirmationPopup-module__cancelButton__Ry694"};
1209
1289
 
1210
1290
  function CwConfirmationPopup(props) {
1211
1291
  const { isOpen, onConfirm, onCancel, message = "Are you sure you want to proceed?", confirmText = "Confirm", cancelText = "Cancel", placement = 'bottom', children } = props;
@@ -1269,15 +1349,15 @@ function CwConfirmationPopup(props) {
1269
1349
  onCancel();
1270
1350
  }
1271
1351
  };
1272
- return (jsxs(Fragment, { children: [renderChildren(), isOpen && (jsx("div", { className: styles$s.overlayPositioned, onClick: handleOverlayClick, children: jsxs("div", { ref: popupRef, className: styles$s.popup, style: {
1352
+ return (jsxs(Fragment, { children: [renderChildren(), isOpen && (jsx("div", { className: styles$t.overlayPositioned, onClick: handleOverlayClick, children: jsxs("div", { ref: popupRef, className: styles$t.popup, style: {
1273
1353
  position: 'absolute',
1274
1354
  top: `${position.top}px`,
1275
1355
  left: `${position.left}px`,
1276
1356
  transform: 'none'
1277
- }, children: [jsx("p", { className: styles$s.message, children: message }), jsxs("div", { className: styles$s.buttons, children: [jsx("button", { className: `${styles$s.button} ${styles$s.confirmButton}`, onClick: onConfirm, children: confirmText }), jsx("button", { className: `${styles$s.button} ${styles$s.cancelButton}`, onClick: onCancel, children: cancelText })] })] }) }))] }));
1357
+ }, children: [jsx("p", { className: styles$t.message, children: message }), jsxs("div", { className: styles$t.buttons, children: [jsx("button", { className: `${styles$t.button} ${styles$t.confirmButton}`, onClick: onConfirm, children: confirmText }), jsx("button", { className: `${styles$t.button} ${styles$t.cancelButton}`, onClick: onCancel, children: cancelText })] })] }) }))] }));
1278
1358
  }
1279
1359
 
1280
- var styles$r = {"cw-dialog-main":"cw-dialog-module__cw-dialog-main__cHxHt","cw-dialog-button-close":"cw-dialog-module__cw-dialog-button-close__9GRd8"};
1360
+ var styles$s = {"cw-dialog-main":"cw-dialog-module__cw-dialog-main__cHxHt","cw-dialog-button-close":"cw-dialog-module__cw-dialog-button-close__9GRd8"};
1281
1361
 
1282
1362
  // Helper function to parse size values
1283
1363
  const parseSize = (size) => {
@@ -1550,7 +1630,7 @@ const CwDialog = props => {
1550
1630
  }
1551
1631
  }
1552
1632
  }, [open]);
1553
- const header = useMemo(() => (jsxs("header", { onMouseDown: handleMouseDown, children: [jsx("span", { children: headline }), customHeader || (jsx("button", { className: styles$r["cw-dialog-button-close"], onClick: onClose }))] })), [handleMouseDown, headline, customHeader, onClose]);
1633
+ const header = useMemo(() => (jsxs("header", { onMouseDown: handleMouseDown, children: [jsx("span", { children: headline }), customHeader || (jsx("button", { className: styles$s["cw-dialog-button-close"], onClick: onClose }))] })), [handleMouseDown, headline, customHeader, onClose]);
1554
1634
  const content = useMemo(() => (jsx("section", { children: children })), [children]);
1555
1635
  const footer = useMemo(() => (jsx("footer", { children: customFooter || (jsx(CwButton, { variant: "icon", icon: "save", title: "Save", onClick: onSave, tooltipPosition: "top", disabled: disableSave, "data-testid": "cw-dialog-save" })) })), [customFooter, onSave, disableSave]);
1556
1636
  const resizeHandles = useMemo(() => size.autoHeight
@@ -1577,7 +1657,7 @@ const CwDialog = props => {
1577
1657
  : `${convertFromPx(size.height, size.heightUnit)}${size.heightUnit}`;
1578
1658
  return { displayWidth, displayHeight };
1579
1659
  }, [size.width, size.height, size.widthUnit, size.heightUnit, size.autoHeight]);
1580
- const dialogContent = (jsx("div", { "data-has-scrim": hasScrim, className: styles$r["cw-dialog-main"], onMouseDown: handleScrimMouseDown, onMouseUp: handleScrimMouseUpOrLeave, onMouseLeave: handleScrimMouseUpOrLeave, "data-pressing": isPressingScrim, children: jsxs("dialog", { ...domProps, ref: dialogRef, style: {
1660
+ const dialogContent = (jsx("div", { "data-has-scrim": hasScrim, className: styles$s["cw-dialog-main"], onMouseDown: handleScrimMouseDown, onMouseUp: handleScrimMouseUpOrLeave, onMouseLeave: handleScrimMouseUpOrLeave, "data-pressing": isPressingScrim, children: jsxs("dialog", { ...domProps, ref: dialogRef, style: {
1581
1661
  left: `${position.x}px`,
1582
1662
  top: `${position.y}px`,
1583
1663
  width: displayDimensions.displayWidth,
@@ -1738,7 +1818,7 @@ function CwAlign(props) {
1738
1818
  }, children: props.children }));
1739
1819
  }
1740
1820
 
1741
- var styles$q = {"card":"cw-card-module__card__HJUT0","clickable":"cw-card-module__clickable__Y-V3X","disabled":"cw-card-module__disabled__0wHh1","loading":"cw-card-module__loading__-fzlx","content":"cw-card-module__content__ma9qy","headerContent":"cw-card-module__headerContent__x4Jfl","footerTags":"cw-card-module__footerTags__80sSW","loadingOverlay":"cw-card-module__loadingOverlay__8-zVV"};
1821
+ 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"};
1742
1822
 
1743
1823
  /**
1744
1824
  * CwCard - A simple card component for displaying content in a contained format
@@ -1758,17 +1838,16 @@ var styles$q = {"card":"cw-card-module__card__HJUT0","clickable":"cw-card-module
1758
1838
  * <p>This is the main content of the card.</p>
1759
1839
  * </CwCard>
1760
1840
  **/
1761
- 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, }) => {
1841
+ 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, }) => {
1762
1842
  const resolvedDirection = layout?.direction ?? direction;
1763
1843
  const resolvedAlign = layout?.align ?? (alignment === 'left' ? 'start' : 'center');
1764
1844
  // Construct class names using CSS modules
1765
1845
  const cardClassNames = [
1766
1846
  'cw-card',
1767
- styles$q.card,
1847
+ styles$r.card,
1768
1848
  className,
1769
- clickable ? styles$q.clickable : '',
1770
- disabled ? styles$q.disabled : '',
1771
- isLoading ? styles$q.loading : '',
1849
+ clickable ? styles$r.clickable : '',
1850
+ disabled ? styles$r.disabled : '',
1772
1851
  ].filter(Boolean).join(' ');
1773
1852
  // Handle click event when card is clickable
1774
1853
  const handleClick = () => {
@@ -1784,16 +1863,17 @@ const CwCard = ({ id, title, subtitle, alignment = 'center', children, footer, o
1784
1863
  const hasChips = chips.length > 0;
1785
1864
  // Determine if footer should be rendered
1786
1865
  const hasFooter = hasChips || footer || (hasActions && resolvedDirection === "row");
1787
- // Actions component to reuse
1788
- const ActionsComponent = hasActions && !disabled ? (jsxs("div", { className: styles$q.actions, children: [extraActions ?? null, onEdit && jsx(CwButton, { variant: "icon", icon: "edit", onClick: onEdit }), onDelete && jsx(CwButton, { variant: "icon", icon: "delete", color: "danger", onClick: onDelete })] })) : null;
1789
- return (jsxs("div", { ...(id && { id }), className: cardClassNames, ...(style && { style }), ...(clickable && {
1866
+ // Actions component to reuse. While loading, each provided action renders a circular
1867
+ // ghost sized to the CwButton icon footprint (2rem) - no interactive buttons.
1868
+ const ActionsComponent = hasActions && !disabled ? (jsx("div", { className: styles$r.actions, children: isLoading ? (jsxs(Fragment, { children: [extraActions && jsx(CwSkeleton, { variant: "circle", height: "2rem" }), onEdit && jsx(CwSkeleton, { variant: "circle", height: "2rem" }), onDelete && jsx(CwSkeleton, { variant: "circle", height: "2rem" })] })) : (jsxs(Fragment, { children: [extraActions ?? null, onEdit && jsx(CwButton, { variant: "icon", icon: "edit", onClick: onEdit }), onDelete && jsx(CwButton, { variant: "icon", icon: "delete", color: "danger", onClick: onDelete })] })) })) : null;
1869
+ return (jsxs("div", { ...(id && { id }), className: cardClassNames, ...(style && { style }), ...(clickable && !isLoading && {
1790
1870
  role: 'button',
1791
1871
  tabIndex: 0,
1792
1872
  onClick: handleClick,
1793
- }), "data-variant": variant, "data-direction": resolvedDirection, children: [hasHeader && (jsxs("header", { children: [(title || subtitle) && (jsxs("div", { className: styles$q.headerContent, "data-align": resolvedAlign, children: [title && jsx("h5", { children: title }), subtitle && jsx("strong", { children: subtitle })] })), resolvedDirection === "column" && ActionsComponent] })), jsx("div", { className: styles$q.content, children: children }), hasFooter && (jsxs("footer", { children: [hasChips && (jsx("div", { className: styles$q.footerTags, children: chips.map((chip, index) => (jsx(CwChip, { label: chip.label, colorScheme: chip.colorScheme, className: styles$q.chip, ...(chip.customColor && { customColor: chip.customColor }), ...(chip.variant && { variant: chip.variant }), ...(chip.icon && { icon: chip.icon }) }, index))) })), footer && (jsx("div", { className: styles$q.footerContent, children: footer }))] })), resolvedDirection === "row" && ActionsComponent, isLoading && (jsx("div", { className: styles$q.loadingOverlay, children: jsx(CwLoading, { isLoading: isLoading, size: "small" }) }))] }));
1873
+ }), "data-variant": variant, "data-direction": resolvedDirection, "aria-busy": isLoading || undefined, children: [isLoading ? (jsxs("header", { children: [jsx("div", { className: styles$r.headerContent, "data-align": resolvedAlign, children: jsx(CwSkeleton, { width: "8rem", height: "1.5em" }) }), resolvedDirection === "column" && ActionsComponent] })) : (hasHeader && (jsxs("header", { children: [(title || subtitle) && (jsxs("div", { className: styles$r.headerContent, "data-align": resolvedAlign, children: [title && jsx("h5", { children: title }), subtitle && jsx("strong", { children: subtitle })] })), resolvedDirection === "column" && ActionsComponent] }))), jsx("div", { className: styles$r.content, children: isLoading ? jsx(CwSkeleton, { count: normalizeSkeletonCount(skeletonLines, 3) }) : children }), hasFooter && (isLoading ? (jsx("footer", { children: jsx("div", { className: styles$r.footerTags, children: jsx(CwSkeleton, { variant: "rect", width: "4rem", height: "1.5em", radius: "1rem" }) }) })) : (jsxs("footer", { children: [hasChips && (jsx("div", { className: styles$r.footerTags, children: chips.map((chip, index) => (jsx(CwChip, { label: chip.label, colorScheme: chip.colorScheme, className: styles$r.chip, ...(chip.customColor && { customColor: chip.customColor }), ...(chip.variant && { variant: chip.variant }), ...(chip.icon && { icon: chip.icon }) }, index))) })), footer && (jsx("div", { className: styles$r.footerContent, children: footer }))] }))), resolvedDirection === "row" && ActionsComponent] }));
1794
1874
  };
1795
1875
 
1796
- var styles$p = {"cardContainer":"cw-card-list-module__cardContainer__l3YEh","pagination":"cw-card-list-module__pagination__5Ay78","pageInfo":"cw-card-list-module__pageInfo__uiMel","loading":"cw-card-list-module__loading__cYpND","emptyState":"cw-card-list-module__emptyState__RlqiS"};
1876
+ 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"};
1797
1877
 
1798
1878
  /**
1799
1879
  * Option to display in the CwSelect
@@ -1851,7 +1931,7 @@ function CwSelect(props) {
1851
1931
  : selectProps.onChange, children: [placeholder && jsx(CwOption, { value: "", children: placeholder }), children] }), buttonProps && jsx(CwButton, { ...buttonProps })] })] }), feedbackMessages.map((feedbackItem, index) => (jsx("p", { className: "cw-input-info", "data-color": feedbackItem.type, children: feedbackItem.message }, index)))] }));
1852
1932
  }
1853
1933
 
1854
- function CwCardList({ items, renderCard, pageSize = 10, layout = 'grid', defaultCardWidth = 320, cardGap = 16, isLoading = false, emptyState, sortOptions = [], defaultSortKey, keyExtractor, ...htmlProps }) {
1934
+ function CwCardList({ items, renderCard, pageSize = 10, layout = 'grid', defaultCardWidth = 320, cardGap = 16, isLoading = false, skeletonCards = 6, emptyState, sortOptions = [], defaultSortKey, keyExtractor, ...htmlProps }) {
1855
1935
  const [currentPage, setCurrentPage] = useState(1);
1856
1936
  const [sortKey, setSortKey] = useState(defaultSortKey || sortOptions[0]?.key || '');
1857
1937
  const [sortDirection, setSortDirection] = useState('asc');
@@ -1888,10 +1968,10 @@ function CwCardList({ items, renderCard, pageSize = 10, layout = 'grid', default
1888
1968
  icon: sortDirection === 'asc' ? 'arrow-up' : 'arrow-down',
1889
1969
  onClick: () => setSortDirection(prev => prev === 'asc' ? 'desc' : 'asc'),
1890
1970
  title: `Sort ${sortDirection === 'asc' ? 'descending' : 'ascending'}`,
1891
- }, value: sortKey, onChange: (e) => handleSortChange(e.target.value), children: sortOptions.map(option => (jsx(CwOption, { value: option.key, children: option.label }, option.key))) }) })), isLoading ? (jsx("div", { className: styles$p.loading, children: jsx(CwLoading, { isLoading: isLoading }) })) : sortedItems.length === 0 ? (jsx("div", { className: styles$p.emptyState, children: emptyState || jsx("p", { children: "No items to display" }) })) : (jsxs(Fragment, { children: [jsx("div", { className: `${styles$p.cardContainer}`, "data-layout": layout, style: gridStyle, children: visibleItems.map((item, index) => (jsx(React__default.Fragment, { children: renderCard(item, index) }, keyExtractor ? keyExtractor(item, index) : index))) }), totalPages > 1 && (jsxs("div", { className: styles$p.pagination, children: [jsx(CwButton, { variant: "icon", icon: "chevron-left", disabled: currentPage === 1, onClick: () => setCurrentPage(p => Math.max(1, p - 1)) }), jsxs("span", { className: styles$p.pageInfo, children: [currentPage, " / ", totalPages] }), jsx(CwButton, { variant: "icon", icon: "chevron-right", disabled: currentPage === totalPages, onClick: () => setCurrentPage(p => Math.min(totalPages, p + 1)) })] }))] }))] }));
1971
+ }, value: sortKey, onChange: (e) => handleSortChange(e.target.value), children: sortOptions.map(option => (jsx(CwOption, { value: option.key, children: option.label }, option.key))) }) })), isLoading ? (jsx("div", { className: `${styles$q.cardContainer}`, "data-layout": layout, style: gridStyle, "aria-busy": true, children: Array.from({ length: normalizeSkeletonCount(skeletonCards, 6) }, (_, index) => (jsx(CwCard, { isLoading: true, children: null }, `skeleton_${index}`))) })) : sortedItems.length === 0 ? (jsx("div", { className: styles$q.emptyState, children: emptyState || jsx("p", { children: "No items to display" }) })) : (jsxs(Fragment, { children: [jsx("div", { className: `${styles$q.cardContainer}`, "data-layout": layout, style: gridStyle, children: visibleItems.map((item, index) => (jsx(React__default.Fragment, { children: renderCard(item, index) }, keyExtractor ? keyExtractor(item, index) : index))) }), totalPages > 1 && (jsxs("div", { className: styles$q.pagination, children: [jsx(CwButton, { variant: "icon", icon: "chevron-left", disabled: currentPage === 1, onClick: () => setCurrentPage(p => Math.max(1, p - 1)) }), jsxs("span", { className: styles$q.pageInfo, children: [currentPage, " / ", totalPages] }), jsx(CwButton, { variant: "icon", icon: "chevron-right", disabled: currentPage === totalPages, onClick: () => setCurrentPage(p => Math.min(totalPages, p + 1)) })] }))] }))] }));
1892
1972
  }
1893
1973
 
1894
- var styles$o = {"cw-accordion":"cw-accordion-module__cw-accordion__ErvlW","cw-accordion-body":"cw-accordion-module__cw-accordion-body__xlI8b"};
1974
+ var styles$p = {"cw-accordion":"cw-accordion-module__cw-accordion__ErvlW","cw-accordion-body":"cw-accordion-module__cw-accordion-body__xlI8b"};
1895
1975
 
1896
1976
  /**
1897
1977
  *
@@ -1908,7 +1988,22 @@ function CwAccordionContainer(CwelltAccordionContainerProps) {
1908
1988
  setVisible_accordionBody(!isVisible_accordionBody);
1909
1989
  };
1910
1990
  // #endregion
1911
- return (jsxs("div", { className: styles$o["cw-accordion"], style: CwelltAccordionContainerProps.style, "data-open": isVisible_accordionBody, children: [jsxs("header", { onClick: () => showAccordionBody(), children: [jsx("div", { children: CwelltAccordionContainerProps.desc_text }), jsx("button", { className: "cw-button-icon" })] }), jsx("div", { className: styles$o["cw-accordion-body"], children: CwelltAccordionContainerProps.children })] }));
1991
+ return (jsxs("div", { className: styles$p["cw-accordion"], style: CwelltAccordionContainerProps.style, "data-open": isVisible_accordionBody, children: [jsxs("header", { onClick: () => showAccordionBody(), children: [jsx("div", { children: CwelltAccordionContainerProps.desc_text }), jsx("button", { className: "cw-button-icon" })] }), jsx("div", { className: styles$p["cw-accordion-body"], children: CwelltAccordionContainerProps.children })] }));
1992
+ }
1993
+
1994
+ /*
1995
+ * Internal helper for table loading ghosts (CwTable, CwSortableTable).
1996
+ * Not exported from the library barrel - not a public API.
1997
+ */
1998
+ const SKELETON_CELL_WIDTHS = ['85%', '60%', '95%', '70%', '80%', '65%'];
1999
+ /**
2000
+ * Deterministic width for a table ghost cell so skeleton rows look like real,
2001
+ * unevenly sized content. Derived purely from indices - stable across re-renders
2002
+ * (no reshuffling) - and offset by the column count so the pattern does not
2003
+ * repeat identically per row or per column.
2004
+ */
2005
+ function getSkeletonCellWidth(rowIndex, columnIndex, columnCount) {
2006
+ return SKELETON_CELL_WIDTHS[(rowIndex * columnCount + columnIndex) % SKELETON_CELL_WIDTHS.length];
1912
2007
  }
1913
2008
 
1914
2009
  /**
@@ -1980,7 +2075,7 @@ function CwAccordionContainer(CwelltAccordionContainerProps) {
1980
2075
  *
1981
2076
  * @returns React component
1982
2077
  */
1983
- 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 }) {
2078
+ 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 }) {
1984
2079
  const [currentPage, setCurrentPage] = useState(1);
1985
2080
  const [expandedRowKey, setExpandedRowKey] = useState(null);
1986
2081
  const [sortConfig, setSortConfig] = useState({
@@ -2118,7 +2213,9 @@ function CwTable({ columns, data, pagination = false, pageSizeOptions = [5, 10,
2118
2213
  };
2119
2214
  const renderTableBody = () => {
2120
2215
  if (loading) {
2121
- return (jsx("tr", { children: jsx("td", { colSpan: getColSpan(), children: jsx("div", { children: "Loading data..." }) }) }));
2216
+ // Ghost rows: rendered outside the data/selection/expand code paths, so they
2217
+ // cannot trigger row click, selection or expansion.
2218
+ return Array.from({ length: normalizeSkeletonCount(skeletonRows, 5) }, (_, rowIndex) => (jsxs("tr", { children: [expandedRowRender && jsx("td", { className: "cw-table-col-action" }), columns.map((col, columnIndex) => (jsx("td", { className: col.className ?? "", children: jsx(CwSkeleton, { variant: "text", width: getSkeletonCellWidth(rowIndex, columnIndex, columns.length) }) }, col.key)))] }, `skeleton_${rowIndex}`)));
2122
2219
  }
2123
2220
  if (!paginatedData || paginatedData.length === 0) {
2124
2221
  return (jsx("tr", { children: jsx("td", { colSpan: getColSpan(), className: "cw-table-cell-empty", style: { textAlign: "center" }, children: textNoData }) }));
@@ -2140,7 +2237,7 @@ function CwTable({ columns, data, pagination = false, pageSizeOptions = [5, 10,
2140
2237
  : "cwi-chevron-right"}` }) })), columns.map(col => (jsx("td", { className: col.className ?? "", children: col.render ? col.render(item) : col.dataIndex ? String(item[col.dataIndex] ?? "") : "" }, `${itemKey}_${col.key}`)))] }), expandedRowRender && expandedRowKey === itemKey && (jsx("tr", { className: "cw-table-row-expanded", children: jsx("td", { colSpan: getColSpan(), children: expandedRowRender(item) }) }))] }, String(itemKey)));
2141
2238
  });
2142
2239
  };
2143
- return (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: [jsxs("table", { className: `cw-table ${className ?? ""}`, style: { width: "100%" }, children: [jsx("thead", { children: jsxs("tr", { children: [expandedRowRender && jsx("th", {}), columns.map(col => (jsxs("th", { onClick: () => col.sortable && col.dataIndex && handleSort(col.dataIndex), className: `${col.className ?? ""} ${sortConfig.key === col.dataIndex
2240
+ return (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: [jsxs("table", { className: `cw-table ${className ?? ""}`, style: { width: "100%" }, children: [jsx("thead", { children: jsxs("tr", { children: [expandedRowRender && jsx("th", {}), columns.map(col => (jsxs("th", { onClick: () => col.sortable && col.dataIndex && handleSort(col.dataIndex), className: `${col.className ?? ""} ${sortConfig.key === col.dataIndex
2144
2241
  ? sortConfig.direction
2145
2242
  : ""}`.trim(), style: {
2146
2243
  cursor: col.sortable ? "pointer" : "default",
@@ -2166,7 +2263,7 @@ function CwTable({ columns, data, pagination = false, pageSizeOptions = [5, 10,
2166
2263
  }, min: 1, max: totalPages }), jsx("span", { children: "/" }), jsx("span", { children: totalPages }), jsx(CwButton, { onClick: () => handlePageChange(currentPage + 1), disabled: currentPage === totalPages || totalPages <= 1, variant: "icon", icon: "chevron-right" }), jsx(CwButton, { onClick: () => handlePageChange(totalPages), disabled: currentPage === totalPages || totalPages <= 1, variant: "icon", icon: "chevron-right-double" })] })] }))] }));
2167
2264
  }
2168
2265
 
2169
- var styles$n = {"dropIndicator":"cw-sortable-table-module__dropIndicator__ov-Jz","dragging":"cw-sortable-table-module__dragging__MrLrz","skeletonRow":"cw-sortable-table-module__skeletonRow__vyD0M","skeleton":"cw-sortable-table-module__skeleton__QGXAD","saveBar":"cw-sortable-table-module__saveBar__3OdoZ cw-flex-row cw-align-center-center cw-gap-small"};
2266
+ 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"};
2170
2267
 
2171
2268
  /**
2172
2269
  * Hook that provides state management for CwSortableTable.
@@ -2229,9 +2326,14 @@ function useSortableTable(initialItems) {
2229
2326
  }
2230
2327
 
2231
2328
  // ─── Drop indicator row ───────────────────────────────────────────────────────
2232
- const DropIndicatorRow = ({ colSpan }) => (jsx("tr", { className: styles$n.dropIndicator, "aria-hidden": true, children: jsx("td", { colSpan: colSpan, children: jsx("div", {}) }) }));
2329
+ const DropIndicatorRow = ({ colSpan }) => (jsx("tr", { className: styles$o.dropIndicator, "aria-hidden": true, children: jsx("td", { colSpan: colSpan, children: jsx("div", {}) }) }));
2233
2330
  // ─── Loading skeleton ─────────────────────────────────────────────────────────
2234
- const LoadingRows = ({ colSpan }) => (jsx(Fragment, { children: Array.from({ length: 4 }).map((_, i) => (jsx("tr", { className: styles$n.skeletonRow, children: jsx("td", { colSpan: colSpan, children: jsx("div", { className: styles$n.skeleton }) }) }, i))) }));
2331
+ // Plain td cells (no local class): the ghost cells get the same global cw-table
2332
+ // padding as real body cells, so row heights match the loaded rows exactly.
2333
+ // One cell per real column, so column classNames/widths apply to the ghost too.
2334
+ function LoadingRows({ columns, showHandle, skeletonRows }) {
2335
+ return (jsx(Fragment, { children: Array.from({ length: skeletonRows }).map((_, rowIndex) => (jsxs("tr", { children: [showHandle && jsx("td", { className: "cw-table-col-action" }), columns.map((col, columnIndex) => (jsx("td", { className: col.className ?? "", style: col.width ? { width: col.width } : undefined, children: jsx(CwSkeleton, { variant: "text", width: getSkeletonCellWidth(rowIndex, columnIndex, columns.length) }) }, col.key)))] }, rowIndex))) }));
2336
+ }
2235
2337
  // ─── Component ────────────────────────────────────────────────────────────────
2236
2338
  /**
2237
2339
  * CwSortableTable
@@ -2248,7 +2350,7 @@ const LoadingRows = ({ colSpan }) => (jsx(Fragment, { children: Array.from({ len
2248
2350
  * - Reorder is calculated in onDragEnd using lastValidDropIndex
2249
2351
  * - draggedItem is tracked in state, not via dataTransfer
2250
2352
  */
2251
- function CwSortableTable({ columns, data, rowKey = "key", onReorder, loading = false, textNoData = "No data available", className, tableClassName, maxHeight, showHandle = true, style, saveLabel = "Save order", discardLabel = "Discard", }) {
2353
+ 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", }) {
2252
2354
  const { items, hasChanges, handleReorder, handleSave, handleDiscard, } = useSortableTable(data);
2253
2355
  // Drag state lives in the component, same as CwSortableList
2254
2356
  const [draggedItem, setDraggedItem] = useState(null);
@@ -2267,11 +2369,15 @@ function CwSortableTable({ columns, data, rowKey = "key", onReorder, loading = f
2267
2369
  setLastValidDropIndex(null);
2268
2370
  };
2269
2371
  const handleDragStart = (e, item) => {
2372
+ if (loading)
2373
+ return;
2270
2374
  setDraggedItem(item);
2271
2375
  setLastValidDropIndex(null);
2272
2376
  e.dataTransfer.effectAllowed = "move";
2273
2377
  };
2274
2378
  const handleDragOver = (e, index) => {
2379
+ if (loading)
2380
+ return;
2275
2381
  e.preventDefault();
2276
2382
  if (!draggedItem)
2277
2383
  return;
@@ -2284,6 +2390,11 @@ function CwSortableTable({ columns, data, rowKey = "key", onReorder, loading = f
2284
2390
  }
2285
2391
  };
2286
2392
  const handleDragEnd = () => {
2393
+ // Never persist a reorder computed against stale/ghost data while loading.
2394
+ if (loading) {
2395
+ cleanupDragState();
2396
+ return;
2397
+ }
2287
2398
  if (draggedItem && lastValidDropIndex !== null) {
2288
2399
  const dragIndex = items.findIndex(item => item[rowKey] === draggedItem[rowKey]);
2289
2400
  if (dragIndex !== lastValidDropIndex && dragIndex !== lastValidDropIndex - 1) {
@@ -2310,7 +2421,7 @@ function CwSortableTable({ columns, data, rowKey = "key", onReorder, loading = f
2310
2421
  };
2311
2422
  const renderBody = () => {
2312
2423
  if (loading) {
2313
- return jsx(LoadingRows, { colSpan: totalCols });
2424
+ return jsx(LoadingRows, { columns: columns, showHandle: showHandle, skeletonRows: normalizeSkeletonCount(skeletonRows, 5) });
2314
2425
  }
2315
2426
  if (!items || items.length === 0) {
2316
2427
  return (jsx("tr", { children: jsx("td", { colSpan: totalCols, className: "cw-table-cell-empty", style: { textAlign: "center" }, children: textNoData }) }));
@@ -2318,11 +2429,11 @@ function CwSortableTable({ columns, data, rowKey = "key", onReorder, loading = f
2318
2429
  return items.map((item, index) => {
2319
2430
  const key = item[rowKey];
2320
2431
  const isDragging = draggedItem?.[rowKey] === key;
2321
- return (jsxs(React__default.Fragment, { children: [dropIndicatorIndex === index && (jsx(DropIndicatorRow, { colSpan: totalCols })), jsxs("tr", { draggable: true, onDragStart: (e) => handleDragStart(e, item), onDragOver: (e) => handleDragOver(e, index), onDragEnd: handleDragEnd, className: isDragging ? styles$n.dragging : "", children: [showHandle && (jsx("td", { className: "cw-table-col-action", children: jsx(CwIcon, { iconId: "grip-dots", color: "neutral", style: { opacity: 0.75 } }) })), columns.map(col => (jsx("td", { className: col.className ?? "", style: col.width ? { width: col.width } : undefined, children: renderCell(item, col) }, `${String(key)}_${col.key}`)))] }), index === items.length - 1 && dropIndicatorIndex === items.length && (jsx(DropIndicatorRow, { colSpan: totalCols }))] }, String(key)));
2432
+ return (jsxs(React__default.Fragment, { children: [dropIndicatorIndex === index && (jsx(DropIndicatorRow, { colSpan: totalCols })), jsxs("tr", { draggable: true, onDragStart: (e) => handleDragStart(e, item), onDragOver: (e) => handleDragOver(e, index), onDragEnd: handleDragEnd, className: isDragging ? styles$o.dragging : "", children: [showHandle && (jsx("td", { className: "cw-table-col-action", children: jsx(CwIcon, { iconId: "grip-dots", color: "neutral", style: { opacity: 0.75 } }) })), columns.map(col => (jsx("td", { className: col.className ?? "", style: col.width ? { width: col.width } : undefined, children: renderCell(item, col) }, `${String(key)}_${col.key}`)))] }), index === items.length - 1 && dropIndicatorIndex === items.length && (jsx(DropIndicatorRow, { colSpan: totalCols }))] }, String(key)));
2322
2433
  });
2323
2434
  };
2324
2435
  // ── Render ──────────────────────────────────────────────────────────────
2325
- return (jsxs("div", { className: `cw-table-container ${className ?? ""}`, style: containerStyle, children: [jsxs("table", { className: `cw-table cw-sortable-table ${tableClassName ?? ""}`, style: { width: "100%" }, children: [jsx("thead", { children: jsxs("tr", { children: [showHandle && jsx("th", { className: "cw-table-col-action" }), columns.map(col => (jsx("th", { className: col.className ?? "", style: col.width ? { width: col.width, minWidth: 50 } : undefined, children: col.title }, col.key)))] }) }), jsx("tbody", { children: renderBody() })] }), hasChanges && (jsxs("footer", { className: styles$n.saveBar, children: [jsx(CwButton, { variant: "outline", color: "neutral", icon: "undo", text: discardLabel, onClick: handleDiscard }), jsx(CwButton, { variant: "solid", color: "primary", icon: "save", text: saveLabel, onClick: () => handleSave(onReorder) })] }))] }));
2436
+ return (jsxs("div", { className: `cw-table-container ${className ?? ""}`, style: containerStyle, "aria-busy": loading || undefined, children: [jsxs("table", { className: `cw-table cw-sortable-table ${tableClassName ?? ""}`, style: { width: "100%" }, children: [jsx("thead", { children: jsxs("tr", { children: [showHandle && jsx("th", { className: "cw-table-col-action" }), columns.map(col => (jsx("th", { className: col.className ?? "", style: col.width ? { width: col.width, minWidth: 50 } : undefined, children: col.title }, col.key)))] }) }), jsx("tbody", { children: renderBody() })] }), !loading && hasChanges && (jsxs("footer", { className: styles$o.saveBar, children: [jsx(CwButton, { variant: "outline", color: "neutral", icon: "undo", text: discardLabel, onClick: handleDiscard }), jsx(CwButton, { variant: "solid", color: "primary", icon: "save", text: saveLabel, onClick: () => handleSave(onReorder) })] }))] }));
2326
2437
  }
2327
2438
 
2328
2439
  /**
@@ -2378,7 +2489,7 @@ function CwSortableTable({ columns, data, rowKey = "key", onReorder, loading = f
2378
2489
  *
2379
2490
  * @returns React component
2380
2491
  */
2381
- 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, }) {
2492
+ 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, }) {
2382
2493
  const [internalState, setInternalState] = useState({
2383
2494
  page: 1,
2384
2495
  pageSize: pageSizeOptions[0],
@@ -2479,7 +2590,9 @@ function CwTableServerSide({ columns, data, totalItems, pagination = false, page
2479
2590
  };
2480
2591
  const renderTableBody = () => {
2481
2592
  if (loading) {
2482
- return (jsx("tr", { children: jsx("td", { colSpan: getColSpan(), children: jsx("div", { children: "Loading data..." }) }) }));
2593
+ // Ghost rows: rendered outside the data/selection/expand code paths, so they
2594
+ // cannot trigger row click, selection or expansion.
2595
+ return Array.from({ length: normalizeSkeletonCount(skeletonRows, 5) }, (_, rowIndex) => (jsxs("tr", { children: [expandedRowRender && jsx("td", { className: "cw-table-col-action" }), columns.map((col, columnIndex) => (jsx("td", { className: col.className ?? "", children: jsx(CwSkeleton, { variant: "text", width: getSkeletonCellWidth(rowIndex, columnIndex, columns.length) }) }, col.key)))] }, `skeleton_${rowIndex}`)));
2483
2596
  }
2484
2597
  if (!data || data.length === 0) {
2485
2598
  return (jsx("tr", { children: jsx("td", { colSpan: getColSpan(), className: "cw-table-cell-empty", style: { textAlign: "center" }, children: textNoData }) }));
@@ -2497,7 +2610,7 @@ function CwTableServerSide({ columns, data, totalItems, pagination = false, page
2497
2610
  }, children: [expandedRowRender && (jsx("td", { className: "cw-table-col-action cw-table-col-expand", children: jsx("button", { onClick: () => handleRowExpand(item), className: `cw-button-icon ${expandedRowKey === itemKey ? "cwi-chevron-down" : "cwi-chevron-right"}` }) })), columns.map((col) => (jsx("td", { className: col.className ?? "", children: col.render ? col.render(item) : col.dataIndex ? String(item[col.dataIndex] ?? "") : "" }, `${itemKey}_${col.key}`)))] }), expandedRowRender && expandedRowKey === itemKey && (jsx("tr", { className: "cw-table-row-expanded", children: jsx("td", { colSpan: getColSpan(), children: expandedRowRender(item) }) }))] }, String(itemKey)));
2498
2611
  });
2499
2612
  };
2500
- return (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: [jsxs("table", { className: `cw-table ${className ?? ""}`, style: { width: "100%" }, children: [jsx("thead", { children: jsxs("tr", { children: [expandedRowRender && jsx("th", {}), columns.map((col) => (jsxs("th", { onClick: () => col.sortable && col.dataIndex && handleSort(col.dataIndex), className: `${col.className ?? ""} ${state.sortKey === col.dataIndex ? state.sortDirection : ""}`.trim(), style: {
2613
+ return (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: [jsxs("table", { className: `cw-table ${className ?? ""}`, style: { width: "100%" }, children: [jsx("thead", { children: jsxs("tr", { children: [expandedRowRender && jsx("th", {}), columns.map((col) => (jsxs("th", { onClick: () => col.sortable && col.dataIndex && handleSort(col.dataIndex), className: `${col.className ?? ""} ${state.sortKey === col.dataIndex ? state.sortDirection : ""}`.trim(), style: {
2501
2614
  cursor: col.sortable ? "pointer" : "default",
2502
2615
  userSelect: "none",
2503
2616
  width: columnWidths[col.key] ?? col.width,
@@ -2521,7 +2634,7 @@ function CwTableServerSide({ columns, data, totalItems, pagination = false, page
2521
2634
  }, min: 1, max: totalPages }), jsx("span", { children: "/" }), jsx("span", { children: totalPages }), jsx(CwButton, { onClick: () => handlePageChange(state.page + 1), disabled: state.page === totalPages || totalPages <= 1, variant: "icon", icon: "chevron-right" }), jsx(CwButton, { onClick: () => handlePageChange(totalPages), disabled: state.page === totalPages || totalPages <= 1, variant: "icon", icon: "chevron-right-double" })] })] }))] }));
2522
2635
  }
2523
2636
 
2524
- var styles$m = {"cw-tabs":"cw-tabs-module__cw-tabs__1pmji","badge":"cw-tabs-module__badge__AmVxW","cw-tabs-content":"cw-tabs-module__cw-tabs-content__HTp8d"};
2637
+ var styles$n = {"cw-tabs":"cw-tabs-module__cw-tabs__1pmji","badge":"cw-tabs-module__badge__AmVxW","cw-tabs-content":"cw-tabs-module__cw-tabs-content__HTp8d"};
2525
2638
 
2526
2639
  const TabIcon = ({ icon }) => {
2527
2640
  if (!icon)
@@ -2571,7 +2684,7 @@ function CwTabs(CwTabsProps) {
2571
2684
  const tabsListStyle = position === 'left' && CwTabsProps.tabsListWidth
2572
2685
  ? { minWidth: CwTabsProps.tabsListWidth }
2573
2686
  : undefined;
2574
- return (jsxs("div", { id: CwTabsProps.id, "data-testid": CwTabsProps.testId, className: styles$m['cw-tabs'] + (CwTabsProps.className ? ` ${CwTabsProps.className}` : "") + "", style: CwTabsProps.style, "data-tabs-position": position, children: [jsx("ul", { style: tabsListStyle, children: CwTabsProps.tabs.map(tab => (jsxs("li", { className: `${tab.key === activeTab ? "cw-tab-active" : ""}`, onClick: () => handleTabClick(tab), "data-active": tab.key === activeTab, "data-tab-key": tab.key, children: [jsx(TabIcon, { icon: tab.icon }), tab.title, (tab.badge !== undefined || tab.badgeColor) && (jsx("span", { className: styles$m['badge'], style: tab.badgeColor ? { backgroundColor: tab.badgeColor, color: getContrastColor(tab.badgeColor) } : undefined, children: tab.badge }))] }, tab.key))) }), jsx("div", { className: styles$m['cw-tabs-content'], "data-active-tab-key": activeTab ?? undefined, children: activeTab !== null && CwTabsProps.tabs.find(tab => tab.key === activeTab)?.content })] }));
2687
+ return (jsxs("div", { id: CwTabsProps.id, "data-testid": CwTabsProps.testId, className: styles$n['cw-tabs'] + (CwTabsProps.className ? ` ${CwTabsProps.className}` : "") + "", style: CwTabsProps.style, "data-tabs-position": position, children: [jsx("ul", { style: tabsListStyle, children: CwTabsProps.tabs.map(tab => (jsxs("li", { className: `${tab.key === activeTab ? "cw-tab-active" : ""}`, onClick: () => handleTabClick(tab), "data-active": tab.key === activeTab, "data-tab-key": tab.key, children: [jsx(TabIcon, { icon: tab.icon }), tab.title, (tab.badge !== undefined || tab.badgeColor) && (jsx("span", { className: styles$n['badge'], style: tab.badgeColor ? { backgroundColor: tab.badgeColor, color: getContrastColor(tab.badgeColor) } : undefined, children: tab.badge }))] }, tab.key))) }), jsx("div", { className: styles$n['cw-tabs-content'], "data-active-tab-key": activeTab ?? undefined, style: CwTabsProps.contentHeight ? { '--tabs-height': CwTabsProps.contentHeight } : undefined, children: activeTab !== null && CwTabsProps.tabs.find(tab => tab.key === activeTab)?.content })] }));
2575
2688
  }
2576
2689
 
2577
2690
  /**
@@ -2598,9 +2711,17 @@ const CwExpandable = ({ briefing, onToggle, onOpen, onClose, children, ...detail
2598
2711
  return (jsxs("details", { ref: myRef, ...detailsProps, className: "cw-expandable", children: [jsx("summary", { children: briefing }), children && jsx("section", { children: children })] }));
2599
2712
  };
2600
2713
 
2601
- var styles$l = {"cw-master-detail":"cw-master-detail-module__cw-master-detail__O8-FA","resizer":"cw-master-detail-module__resizer__hvGhL","detail":"cw-master-detail-module__detail__BG4Dm","detail-empty":"cw-master-detail-module__detail-empty__KFScK"};
2714
+ 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"};
2602
2715
 
2603
- 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, }) => {
2716
+ /*
2717
+ * Fixed rem widths for the ghosts: the master rows and detail panel size their
2718
+ * content freely, so a percentage-width skeleton would resolve to 100% of ~0 and
2719
+ * collapse to nothing. Fixed widths render regardless of layout. Cycled so rows do
2720
+ * not all look identical.
2721
+ */
2722
+ const MASTER_TITLE_WIDTHS = ['9rem', '11rem', '8rem', '10rem'];
2723
+ const MASTER_SUBTITLE_WIDTH = '5rem';
2724
+ 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, }) => {
2604
2725
  const [masterWidth, setMasterWidth] = useState(initialWidth);
2605
2726
  const [isResizing, setIsResizing] = useState(false);
2606
2727
  const containerRef = useRef(null);
@@ -2634,12 +2755,22 @@ const CwMasterDetail = ({ id, className, style, items, selectedKey, onSelect, de
2634
2755
  document.body.style.userSelect = '';
2635
2756
  };
2636
2757
  }, [isResizing, minMasterWidth, maxMasterWidth]);
2637
- const rootClassName = [styles$l['cw-master-detail'], className].filter(Boolean).join(' ');
2638
- return (jsxs("div", { id: id, ref: containerRef, className: rootClassName, style: style, children: [jsxs("aside", { style: { width: masterWidth, minWidth: masterWidth }, children: [showSearch && (jsx("search", { children: jsx("input", { type: "text", placeholder: searchPlaceholder, onChange: (e) => onSearch?.(e.target.value) }) })), masterHeader && (jsx("header", { children: masterHeader })), jsx("ul", { children: items.map((item) => (jsx("li", { "data-master-key": item.key, "data-selected": item.key === selectedKey, "data-disabled": item.disabled, onClick: () => onSelect?.(item.key), children: item.content }, item.key))) }), masterFooter && (jsx("footer", { children: masterFooter }))] }), resizable && (jsx("div", { className: styles$l.resizer, "data-resizing": isResizing, onMouseDown: handleMouseDown })), jsx("section", { className: styles$l.detail, children: selectedKey && detailContent
2758
+ const rootClassName = [styles$m['cw-master-detail'], className].filter(Boolean).join(' ');
2759
+ return (jsxs("div", { id: id, ref: containerRef, className: rootClassName, style: style, "aria-busy": loading || undefined, children: [jsxs("aside", { style: { width: masterWidth, minWidth: masterWidth }, children: [showSearch && (jsx("search", { children: jsx("input", { type: "text", placeholder: searchPlaceholder, onChange: (e) => onSearch?.(e.target.value) }) })), masterHeader && (jsx("header", { children: masterHeader })), jsx("ul", { children: loading
2760
+ ? Array.from({ length: skeletonRows }, (_unused, rowIndex) => (jsxs("li", { "aria-hidden": "true", children: [jsx(CwSkeleton, { variant: "circle", height: "2rem" }), jsxs("div", { className: styles$m.skeletonRow, children: [jsx(CwSkeleton, { variant: "text", width: MASTER_TITLE_WIDTHS[rowIndex % MASTER_TITLE_WIDTHS.length] }), jsx(CwSkeleton, { variant: "text", width: MASTER_SUBTITLE_WIDTH })] })] }, `skeleton_${rowIndex}`)))
2761
+ : items.map((item) => (jsx("li", { "data-master-key": item.key, "data-selected": item.key === selectedKey, "data-disabled": item.disabled, onClick: () => onSelect?.(item.key), children: item.content }, item.key))) }), masterFooter && (jsx("footer", { children: masterFooter }))] }), resizable && (jsx("div", { className: styles$m.resizer, "data-resizing": isResizing, onMouseDown: handleMouseDown })), jsx("section", { className: styles$m.detail, children: loading ? (jsxs("div", { className: styles$m.detailSkeleton, "aria-hidden": "true", children: [jsx(CwSkeleton, { variant: "text", width: "14rem", height: "1.5em" }), jsx(CwSkeleton, { variant: "text", width: "22rem" }), jsx(CwSkeleton, { variant: "text", width: "18rem" }), jsx(CwSkeleton, { variant: "text", width: "20rem" })] })) : selectedKey && detailContent
2639
2762
  ? detailContent
2640
- : (jsx("div", { className: styles$l['detail-empty'], children: emptyDetail ?? 'Select an item to view details' })) })] }));
2763
+ : (jsx("div", { className: styles$m['detail-empty'], children: emptyDetail ?? 'Select an item to view details' })) })] }));
2641
2764
  };
2642
2765
 
2766
+ /*
2767
+ * Fixed rem widths (not percentages): dt and dd size to their content in the list
2768
+ * item, so a percentage-width skeleton would resolve to 100% of ~0 and collapse to
2769
+ * nothing. Fixed widths are visible in both row (dt beside dd) and column (dt above
2770
+ * dd) item layouts. Cycled by row so keys and values do not all look identical.
2771
+ */
2772
+ const SKELETON_KEY_WIDTHS = ["5rem", "6.5rem", "4.5rem", "6rem"];
2773
+ const SKELETON_VALUE_WIDTHS = ["8rem", "6rem", "9rem", "7rem"];
2643
2774
  /**
2644
2775
  * A component for displaying key-value pairs in a definition list format
2645
2776
  * Used for read-only display of structured data
@@ -2653,16 +2784,23 @@ const CwMasterDetail = ({ id, className, style, items, selectedKey, onSelect, de
2653
2784
  * emptyValue="N/A"
2654
2785
  * />
2655
2786
  */
2656
- const CwKeyValueList = ({ items, className = "", emptyValue = "-", direction = "row", groupLayout, itemLayout, ...htmlProps }) => {
2787
+ const CwKeyValueList = ({ items, className = "", emptyValue = "-", direction = "row", loading = false, skeletonRows = 4, groupLayout, itemLayout, ...htmlProps }) => {
2657
2788
  const itemDirection = itemLayout?.direction ?? direction;
2658
- return (jsx("dl", { className: `cw-keyvalue-list ${className}`, "data-direction": groupLayout?.direction, "data-align": groupLayout?.align, "data-justify": groupLayout?.justify, "data-gap": groupLayout?.gap, ...htmlProps, children: items.map(item => (jsxs("div", { className: `cw-keyvalue-list-item cw-flex-${itemDirection}`, "data-align": itemLayout?.align, "data-justify": itemLayout?.justify, "data-gap": itemLayout?.gap, children: [jsx("dt", { children: item.label }), jsx("dd", { children: item.value !== undefined && item.value !== null && item.value !== ""
2789
+ const renderItems = () => {
2790
+ if (loading) {
2791
+ // The whole list comes from one data load, so both key and value ghost.
2792
+ return Array.from({ length: skeletonRows }, (_unused, rowIndex) => (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: [jsx("dt", { children: jsx(CwSkeleton, { variant: "text", width: SKELETON_KEY_WIDTHS[rowIndex % SKELETON_KEY_WIDTHS.length] }) }), jsx("dd", { children: jsx(CwSkeleton, { variant: "text", width: SKELETON_VALUE_WIDTHS[rowIndex % SKELETON_VALUE_WIDTHS.length] }) })] }, `skeleton_${rowIndex}`)));
2793
+ }
2794
+ return items.map(item => (jsxs("div", { className: `cw-keyvalue-list-item cw-flex-${itemDirection}`, "data-align": itemLayout?.align, "data-justify": itemLayout?.justify, "data-gap": itemLayout?.gap, children: [jsx("dt", { children: item.label }), jsx("dd", { children: item.value !== undefined && item.value !== null && item.value !== ""
2659
2795
  ? (React__default.isValidElement(item.value)
2660
2796
  ? item.value
2661
2797
  : `${item.value}${item.suffix ? ` ${item.suffix}` : ''}`)
2662
- : emptyValue })] }, item.key))) }));
2798
+ : emptyValue })] }, item.key)));
2799
+ };
2800
+ return (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() }));
2663
2801
  };
2664
2802
 
2665
- var styles$k = {"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"};
2803
+ var styles$l = {"sortableList":"cw-sortable-list-module__sortableList__PyLO-","sortableItem":"cw-sortable-list-module__sortableItem__FAnn2","readOnly":"cw-sortable-list-module__readOnly__r7GcH","dragging":"cw-sortable-list-module__dragging__MD715","moved":"cw-sortable-list-module__moved__sE6-N","expandedContent":"cw-sortable-list-module__expandedContent__Kocna","sortableHandle":"cw-sortable-list-module__sortableHandle__HvYBK","sortableContent":"cw-sortable-list-module__sortableContent__C6JhR","sortableTitle":"cw-sortable-list-module__sortableTitle__EgWXr","sortableExtraContent":"cw-sortable-list-module__sortableExtraContent__s4LSv","sortableActions":"cw-sortable-list-module__sortableActions__gwQOU","dropIndicator":"cw-sortable-list-module__dropIndicator__MNSF-","emptyMessage":"cw-sortable-list-module__emptyMessage__gMpaL"};
2666
2804
 
2667
2805
  function CwSortableList({ items, onReorder, renderItem, className = '', movedItems = new Set(), emptyMessage = "No elements to show", readOnly = false, maxHeight = "300px", }) {
2668
2806
  const [draggedItem, setDraggedItem] = useState(null);
@@ -2725,15 +2863,15 @@ function CwSortableList({ items, onReorder, renderItem, className = '', movedIte
2725
2863
  }
2726
2864
  };
2727
2865
  if (items.length === 0) {
2728
- return (jsx("div", { className: `${styles$k.sortableList} ${styles$k.emptyState} ${className}`, children: jsx("div", { className: styles$k.emptyMessage, children: emptyMessage }) }));
2866
+ return (jsx("div", { className: `${styles$l.sortableList} ${styles$l.emptyState} ${className}`, children: jsx("div", { className: styles$l.emptyMessage, children: emptyMessage }) }));
2729
2867
  }
2730
- return (jsx("div", { className: `${styles$k.sortableList} ${className}`, style: { maxHeight }, children: items.map((item, index) => {
2868
+ return (jsx("div", { className: `${styles$l.sortableList} ${className}`, style: { maxHeight }, children: items.map((item, index) => {
2731
2869
  const { title, extraContent, actions, showHandle = true, expandedContent } = renderItem(item);
2732
2870
  const isDragging = draggedItem?.id === item.id;
2733
2871
  const isMoved = movedItems.has(item.id);
2734
2872
  const canExpand = Boolean(expandedContent);
2735
2873
  const isExpanded = expandedItems.has(item.id);
2736
- return (jsxs(React__default.Fragment, { children: [dropIndicatorIndex === index && jsx("div", { className: styles$k.dropIndicator }), jsxs("div", { className: `${styles$k.sortableItem} ${isDragging ? styles$k.dragging : ''} ${isMoved ? styles$k.moved : ''} ${readOnly ? styles$k.readOnly : ''}`, draggable: !readOnly, onDragStart: (e) => handleDragStart(e, item), onDragOver: (e) => handleDragOver(e, index), onDragEnd: handleDragEnd, children: [jsxs("header", { children: [canExpand ? (jsx(CwButton, { variant: "icon", onClick: () => toggleExpanded(item.id), type: "button", title: isExpanded ? "Collapse" : "Expand", icon: isExpanded ? "chevron-up" : "chevron-down" })) : showHandle ? (jsx("div", { className: styles$k.sortableHandle, children: jsx(CwIcon, { iconId: "grip-dots" }) })) : null, jsxs("div", { className: styles$k.sortableContent, children: [jsx("div", { className: styles$k.sortableTitle, children: title }), extraContent && jsx("div", { className: styles$k.sortableExtraContent, children: extraContent })] }), jsx("div", { className: styles$k.sortableActions, children: actions })] }), isExpanded && expandedContent && (jsx("div", { className: styles$k.expandedContent, children: expandedContent }))] }), !readOnly && dropIndicatorIndex === items.length && index === items.length - 1 && (jsx("div", { className: styles$k.dropIndicator }))] }, item.id));
2874
+ return (jsxs(React__default.Fragment, { children: [dropIndicatorIndex === index && jsx("div", { className: styles$l.dropIndicator }), jsxs("div", { className: `${styles$l.sortableItem} ${isDragging ? styles$l.dragging : ''} ${isMoved ? styles$l.moved : ''} ${readOnly ? styles$l.readOnly : ''}`, draggable: !readOnly, onDragStart: (e) => handleDragStart(e, item), onDragOver: (e) => handleDragOver(e, index), onDragEnd: handleDragEnd, children: [jsxs("header", { children: [canExpand ? (jsx(CwButton, { variant: "icon", onClick: () => toggleExpanded(item.id), type: "button", title: isExpanded ? "Collapse" : "Expand", icon: isExpanded ? "chevron-up" : "chevron-down" })) : showHandle ? (jsx("div", { className: styles$l.sortableHandle, children: jsx(CwIcon, { iconId: "grip-dots" }) })) : null, jsxs("div", { className: styles$l.sortableContent, children: [jsx("div", { className: styles$l.sortableTitle, children: title }), extraContent && jsx("div", { className: styles$l.sortableExtraContent, children: extraContent })] }), jsx("div", { className: styles$l.sortableActions, children: actions })] }), isExpanded && expandedContent && (jsx("div", { className: styles$l.expandedContent, children: expandedContent }))] }), !readOnly && dropIndicatorIndex === items.length && index === items.length - 1 && (jsx("div", { className: styles$l.dropIndicator }))] }, item.id));
2737
2875
  }) }));
2738
2876
  }
2739
2877
 
@@ -2859,60 +2997,9 @@ const CwTableGrouped = props => {
2859
2997
  group.rows.map((child, j) => (jsx("tr", { "data-row": true, "data-row-last-of-group": j == group.rows.length - 1, children: child.cells.map((cell, k) => (jsx("td", { children: cell.content }, k))) }, j)))] }, i))) }), jsx("tfoot", {})] }) }));
2860
2998
  };
2861
2999
 
2862
- function CwFileUpload(fileUploadProps) {
2863
- const [previewURL, setPreviewURL] = useState("");
2864
- const [error, setError] = useState(null);
2865
- const [_selectedFileName, setSelectedFileName] = useState("");
2866
- const [_currentHexContent, setCurrentHexContent] = useState("");
2867
- useEffect(() => {
2868
- // If there is hexadecimal preview content, set the Preview URL
2869
- if (fileUploadProps.file?.Bindata) {
2870
- setPreviewURL(`data:image/png;base64,${fileUploadProps.file.Bindata}`);
2871
- }
2872
- }, [fileUploadProps.file?.Bindata]);
2873
- const handleFileChange = (event) => {
2874
- const file = event.target.files?.[0];
2875
- setSelectedFileName(file?.name ?? "");
2876
- if (file) {
2877
- const allowedExts = fileUploadProps.accept.split(',').map(ext => ext.trim().replace('.', '').toLowerCase());
2878
- const fileExt = file.name.split('.').pop()?.toLowerCase() ?? "";
2879
- if (!allowedExts.includes(fileExt)) {
2880
- setError(`Invalid file type. Only ${fileUploadProps.acceptString} files are allowed.`);
2881
- setPreviewURL("");
2882
- return;
2883
- }
2884
- setError(null);
2885
- const reader = new FileReader();
2886
- reader.onloadend = () => {
2887
- if (typeof reader.result === "string") {
2888
- const hexContent = arrayBufferToHex(reader.result);
2889
- setCurrentHexContent(hexContent);
2890
- setPreviewURL(reader.result);
2891
- setCurrentHexContent(arrayBufferToHex(reader.result));
2892
- // Call function to store hexadecimal content
2893
- fileUploadProps.onSaveHexContent(arrayBufferToHex(reader.result));
2894
- }
2895
- };
2896
- reader.readAsDataURL(file);
2897
- }
2898
- };
2899
- // Function to convert the image buffer into hexadecimal content
2900
- const arrayBufferToHex = (dataUrl) => {
2901
- // Decodes the base64 of the URL data
2902
- const base64 = dataUrl.split(",")[1];
2903
- const binary = atob(base64);
2904
- let hex = "";
2905
- for (let i = 0; i < binary.length; i++) {
2906
- hex += binary.charCodeAt(i).toString(16).padStart(2, "0");
2907
- }
2908
- return hex;
2909
- };
2910
- return (jsxs("div", { children: [jsxs("div", { className: "row", children: [jsx("input", { className: "cw-button", type: "file", accept: fileUploadProps.accept, readOnly: true, placeholder: "No file selected...", onChange: handleFileChange }), previewURL && (jsx("div", { className: "row", children: jsx("img", { src: previewURL, alt: "Preview", style: { maxWidth: "200px", maxHeight: "200px" } }) }))] }), error && jsx("div", { className: "row error", children: error }), jsx("div", { className: "row", children: jsxs("label", { children: ["Please note: File/image has to be in ", fileUploadProps.acceptString, " format", fileUploadProps.sizeString && `, ${fileUploadProps.sizeString}`] }) })] }));
2911
- }
2912
-
2913
- var styles$j = {"fileUploadContainer":"cw-file-upload-multiple-module__fileUploadContainer__liEc1","hiddenInput":"cw-file-upload-multiple-module__hiddenInput__TZBBI","uploadArea":"cw-file-upload-multiple-module__uploadArea__DdOhs","uploadAreaDisabled":"cw-file-upload-multiple-module__uploadAreaDisabled__VWeFX","uploadTitle":"cw-file-upload-multiple-module__uploadTitle__gjRk8","uploadSubtitle":"cw-file-upload-multiple-module__uploadSubtitle__Z0S5t","filesContainer":"cw-file-upload-multiple-module__filesContainer__g44PY","fileItem":"cw-file-upload-multiple-module__fileItem__w27Dg","fileIcon":"cw-file-upload-multiple-module__fileIcon__iJJUX","fileExtension":"cw-file-upload-multiple-module__fileExtension__vOuHv","fileInfo":"cw-file-upload-multiple-module__fileInfo__R5ZTv","fileName":"cw-file-upload-multiple-module__fileName__DjepK","fileSize":"cw-file-upload-multiple-module__fileSize__b8GSm","smallButton":"cw-file-upload-multiple-module__smallButton__siUAh"};
3000
+ var styles$k = {"fileUploadContainer":"cw-file-upload-multiple-module__fileUploadContainer__liEc1","hiddenInput":"cw-file-upload-multiple-module__hiddenInput__TZBBI","uploadArea":"cw-file-upload-multiple-module__uploadArea__DdOhs","uploadAreaDisabled":"cw-file-upload-multiple-module__uploadAreaDisabled__VWeFX","uploadTitle":"cw-file-upload-multiple-module__uploadTitle__gjRk8","uploadSubtitle":"cw-file-upload-multiple-module__uploadSubtitle__Z0S5t","filesContainer":"cw-file-upload-multiple-module__filesContainer__g44PY","fileItem":"cw-file-upload-multiple-module__fileItem__w27Dg","fileIcon":"cw-file-upload-multiple-module__fileIcon__iJJUX","fileExtension":"cw-file-upload-multiple-module__fileExtension__vOuHv","fileInfo":"cw-file-upload-multiple-module__fileInfo__R5ZTv","fileName":"cw-file-upload-multiple-module__fileName__DjepK","fileSize":"cw-file-upload-multiple-module__fileSize__b8GSm","smallButton":"cw-file-upload-multiple-module__smallButton__siUAh"};
2914
3001
 
2915
- const DEFAULT_LABELS = {
3002
+ const DEFAULT_LABELS$1 = {
2916
3003
  uploadDisabled: 'Upload disabled',
2917
3004
  clickToUpload: 'Click to upload or drag and drop',
2918
3005
  acceptedFiles: (accept) => `Accepted files: ${accept}`,
@@ -2920,6 +3007,7 @@ const DEFAULT_LABELS = {
2920
3007
  allTypesAccepted: 'All file types accepted',
2921
3008
  changeFile: 'Change File',
2922
3009
  clearAll: 'Clear all',
3010
+ upload: 'Upload',
2923
3011
  addMoreFiles: 'Add More Files',
2924
3012
  filesSelected: (count) => `${count} file${count !== 1 ? 's' : ''} selected`,
2925
3013
  fileTooLarge: (name, maxSize) => `File "${name}" is too large. Maximum size allowed is ${maxSize}MB.`,
@@ -2927,11 +3015,38 @@ const DEFAULT_LABELS = {
2927
3015
  invalidMimeType: (name, types) => `File "${name}" has an invalid MIME type. Allowed types: ${types}`,
2928
3016
  alreadySelected: (name) => `File "${name}" is already selected.`,
2929
3017
  };
3018
+ /**
3019
+ * Checks a file against an `accept` string (comma-separated tokens). A token can be a dotted
3020
+ * extension (".pdf"), an exact MIME type ("application/pdf"), a wildcard MIME ("image" + slash + "star"),
3021
+ * or a bare "star" / "star-slash-star" for anything. Returns true if the file matches ANY token
3022
+ * (or if `accept` is empty).
3023
+ */
3024
+ function fileMatchesAccept(fileName, fileType, accept) {
3025
+ const tokens = accept.split(',').map(token => token.trim().toLowerCase()).filter(Boolean);
3026
+ if (tokens.length === 0) {
3027
+ return true;
3028
+ }
3029
+ const fileExtension = '.' + (fileName.split('.').pop()?.toLowerCase() ?? '');
3030
+ const mimeType = fileType.toLowerCase();
3031
+ return tokens.some(token => {
3032
+ if (token === '*' || token === '*/*') {
3033
+ return true;
3034
+ }
3035
+ if (token.startsWith('.')) {
3036
+ return token === fileExtension;
3037
+ }
3038
+ if (token.endsWith('/*')) {
3039
+ const prefix = token.slice(0, token.indexOf('/') + 1);
3040
+ return mimeType.startsWith(prefix);
3041
+ }
3042
+ return token === mimeType;
3043
+ });
3044
+ }
2930
3045
  function CwFileUploadMultiple(fileUploadProps) {
2931
3046
  const fileInputRef = useRef(null);
2932
3047
  const [selectedFiles, setSelectedFiles] = useState([]);
2933
3048
  const [existingFile, setExistingFile] = useState(fileUploadProps.initialFileName);
2934
- const labels = { ...DEFAULT_LABELS, ...fileUploadProps.labels };
3049
+ const labels = { ...DEFAULT_LABELS$1, ...fileUploadProps.labels };
2935
3050
  React__default.useEffect(() => {
2936
3051
  setExistingFile(fileUploadProps.initialFileName);
2937
3052
  }, [fileUploadProps.initialFileName]);
@@ -2949,17 +3064,9 @@ function CwFileUploadMultiple(fileUploadProps) {
2949
3064
  };
2950
3065
  }
2951
3066
  }
2952
- // Validate file type by extension (based in accept)
3067
+ // Validate file type against accept (dotted extensions, exact MIME, wildcard MIME, or *)
2953
3068
  if (fileUploadProps.accept) {
2954
- const acceptedExtensions = fileUploadProps.accept.split(',').map(ext => ext.trim().toLowerCase());
2955
- const fileExtension = '.' + file.name.split('.').pop()?.toLowerCase();
2956
- const isExtensionValid = acceptedExtensions.some(ext => {
2957
- if (ext.startsWith('.')) {
2958
- return ext === fileExtension;
2959
- }
2960
- return false;
2961
- });
2962
- if (!isExtensionValid) {
3069
+ if (!fileMatchesAccept(file.name, file.type, fileUploadProps.accept)) {
2963
3070
  return {
2964
3071
  isValid: false,
2965
3072
  error: labels.invalidFormat(file.name, fileUploadProps.accept)
@@ -2984,7 +3091,7 @@ function CwFileUploadMultiple(fileUploadProps) {
2984
3091
  const errors = [];
2985
3092
  for (const file of fileArray) {
2986
3093
  // Check if the file already exists (by name and size)
2987
- const isDuplicate = existingFiles.some(existingFile => existingFile.name === file.name && existingFile.size === file.size);
3094
+ const isDuplicate = validFiles.some(existingFile => existingFile.name === file.name && existingFile.size === file.size);
2988
3095
  if (isDuplicate) {
2989
3096
  errors.push(labels.alreadySelected(file.name));
2990
3097
  continue;
@@ -3002,8 +3109,7 @@ function CwFileUploadMultiple(fileUploadProps) {
3002
3109
  fileUploadProps.onError(errors.join('\n'));
3003
3110
  }
3004
3111
  else {
3005
- console.error(errors.join('\n'));
3006
- alert(errors.join('\n')); // Fallback if there is no onError
3112
+ CwDisplayMessage(errors.join('\n'), CwMessageType.ERROR);
3007
3113
  }
3008
3114
  }
3009
3115
  // If not multiple, only take the first valid file (replace)
@@ -3077,12 +3183,20 @@ function CwFileUploadMultiple(fileUploadProps) {
3077
3183
  }
3078
3184
  }
3079
3185
  };
3080
- return (jsxs("div", { className: `${styles$j.fileUploadContainer} ${fileUploadProps.className}`, children: [jsx("input", { ref: fileInputRef, type: "file", name: fileUploadProps.name, accept: fileUploadProps.accept, multiple: fileUploadProps.multiple, onChange: handleFileSelectInternal, disabled: fileUploadProps.disabled, "aria-label": "files", className: styles$j.hiddenInput }), selectedFiles.length === 0 && !existingFile ? (jsxs("div", { className: `${styles$j.uploadArea} ${fileUploadProps.disabled ? styles$j.uploadAreaDisabled : ''}`, onDragOver: handleDragOver, onDrop: handleDrop, onClick: !fileUploadProps.disabled ? handleButtonClick : undefined, children: [jsx(CwIcon, { iconId: "upload" }), jsx("p", { className: `${styles$j.uploadTitle}`, children: fileUploadProps.disabled ? labels.uploadDisabled : labels.clickToUpload }), jsxs("p", { className: `${styles$j.uploadSubtitle}`, children: [fileUploadProps.accept ? labels.acceptedFiles(fileUploadProps.accept) : labels.allTypesAccepted, !fileUploadProps.multiple && ` ${labels.singleFileOnly}`] })] })) : selectedFiles.length === 0 && existingFile ? (jsxs("div", { className: styles$j.filesContainer, children: [jsxs("div", { className: styles$j.fileItem, children: [jsxs("div", { className: styles$j.fileIcon, children: [jsx(CwIcon, { iconId: "page" }), jsx("span", { className: styles$j.fileExtension, children: getFileExtension(existingFile) })] }), jsx("div", { className: styles$j.fileInfo, children: jsx("p", { className: styles$j.fileName, children: existingFile }) }), jsx(CwButton, { variant: "icon", icon: "close", color: "neutral", onClick: () => {
3186
+ return (jsxs("div", { className: `${styles$k.fileUploadContainer} ${fileUploadProps.className}`, children: [jsx("input", { ref: fileInputRef, type: "file", name: fileUploadProps.name, accept: fileUploadProps.accept, multiple: fileUploadProps.multiple, onChange: handleFileSelectInternal, disabled: fileUploadProps.disabled, "aria-label": "files", className: styles$k.hiddenInput }), selectedFiles.length === 0 && !existingFile ? (jsxs("div", { className: `${styles$k.uploadArea} ${fileUploadProps.disabled ? styles$k.uploadAreaDisabled : ''}`, onDragOver: handleDragOver, onDrop: handleDrop, onClick: !fileUploadProps.disabled ? handleButtonClick : undefined, children: [jsx(CwIcon, { iconId: "upload" }), jsx("p", { className: `${styles$k.uploadTitle}`, children: fileUploadProps.disabled ? labels.uploadDisabled : labels.clickToUpload }), jsxs("p", { className: `${styles$k.uploadSubtitle}`, children: [fileUploadProps.accept ? labels.acceptedFiles(fileUploadProps.accept) : labels.allTypesAccepted, !fileUploadProps.multiple && ` ${labels.singleFileOnly}`] })] })) : selectedFiles.length === 0 && existingFile ? (jsxs("div", { className: styles$k.filesContainer, children: [jsxs("div", { className: styles$k.fileItem, children: [jsxs("div", { className: styles$k.fileIcon, children: [jsx(CwIcon, { iconId: "page" }), jsx("span", { className: styles$k.fileExtension, children: getFileExtension(existingFile) })] }), jsx("div", { className: styles$k.fileInfo, children: jsx("p", { className: styles$k.fileName, children: existingFile }) }), jsx(CwButton, { variant: "icon", icon: "close", color: "neutral", onClick: () => {
3081
3187
  setExistingFile(undefined);
3082
3188
  if (fileUploadProps.onSelect) {
3083
3189
  fileUploadProps.onSelect(null);
3084
3190
  }
3085
- }, disabled: fileUploadProps.disabled, className: styles$j.smallButton })] }), jsx(CwButton, { text: labels.changeFile, icon: "refresh", onClick: handleButtonClick, disabled: fileUploadProps.disabled })] })) : (jsxs("div", { className: styles$j.filesContainer, children: [jsxs("div", { className: "cw-flex-row cw-align-between-center", children: [jsx("small", { className: styles$j.filesCount, children: labels.filesSelected(selectedFiles.length) }), !fileUploadProps.hideClearAll && (jsx(CwButton, { onClick: removeAllFiles, disabled: fileUploadProps.disabled, color: "danger", variant: "outline", icon: "delete", text: labels.clearAll }))] }), selectedFiles.map((file, index) => (jsxs("div", { className: styles$j.fileItem, children: [jsxs("div", { className: styles$j.fileIcon, children: [jsx(CwIcon, { iconId: "page" }), jsx("span", { className: styles$j.fileExtension, children: getFileExtension(file.name) })] }), jsxs("div", { className: styles$j.fileInfo, children: [jsx("p", { className: styles$j.fileName, children: file.name }), jsxs("p", { className: styles$j.fileSize, children: [(file.size / 1024).toFixed(1), " KB"] })] }), jsx(CwButton, { variant: "icon", icon: "close", color: "neutral", onClick: () => removeFile(index), className: styles$j.smallButton })] }, index))), fileUploadProps.multiple && (jsx(CwButton, { text: labels.addMoreFiles, icon: "plus", variant: "outline", onClick: handleButtonClick, disabled: fileUploadProps.disabled })), !fileUploadProps.multiple && (jsx(CwButton, { text: labels.changeFile, icon: "refresh", onClick: handleButtonClick, disabled: fileUploadProps.disabled }))] }))] }));
3191
+ }, disabled: fileUploadProps.disabled, className: styles$k.smallButton })] }), jsx(CwButton, { text: labels.changeFile, icon: "refresh", onClick: handleButtonClick, disabled: fileUploadProps.disabled })] })) : (jsxs("div", { className: styles$k.filesContainer, children: [jsxs("header", { className: "cw-flex-row cw-align-between-center cw-flex-wrap", children: [jsx("small", { className: styles$k.filesCount, children: fileUploadProps.statusText ?? labels.filesSelected(selectedFiles.length) }), jsxs("div", { className: "cw-flex-row", children: [fileUploadProps.onConfirm && selectedFiles.length > 0 && (jsx(CwButton, { onClick: () => {
3192
+ let files = fileInputRef.current?.files ?? null;
3193
+ if (!files) {
3194
+ const dataTransfer = new DataTransfer();
3195
+ selectedFiles.forEach(file => dataTransfer.items.add(file));
3196
+ files = dataTransfer.files;
3197
+ }
3198
+ fileUploadProps.onConfirm?.(files);
3199
+ }, disabled: fileUploadProps.disabled || fileUploadProps.confirmDisabled, icon: "upload", text: fileUploadProps.confirmLabel ?? labels.upload })), !fileUploadProps.hideClearAll && (jsx(CwButton, { onClick: removeAllFiles, disabled: fileUploadProps.disabled, color: "danger", variant: "outline", icon: "delete", text: labels.clearAll }))] })] }), selectedFiles.map((file, index) => (jsxs("div", { className: styles$k.fileItem, children: [jsxs("div", { className: styles$k.fileIcon, children: [jsx(CwIcon, { iconId: "page" }), jsx("span", { className: styles$k.fileExtension, children: getFileExtension(file.name) })] }), jsxs("div", { className: styles$k.fileInfo, children: [jsx("p", { className: styles$k.fileName, children: file.name }), jsxs("p", { className: styles$k.fileSize, children: [(file.size / 1024).toFixed(1), " KB"] })] }), jsx(CwButton, { variant: "icon", icon: "close", color: "neutral", onClick: () => removeFile(index), className: styles$k.smallButton })] }, `${file.name}-${file.size}`))), fileUploadProps.multiple && (jsx(CwButton, { text: labels.addMoreFiles, icon: "plus", variant: "outline", onClick: handleButtonClick, disabled: fileUploadProps.disabled })), !fileUploadProps.multiple && (jsx(CwButton, { text: labels.changeFile, icon: "refresh", onClick: handleButtonClick, disabled: fileUploadProps.disabled }))] }))] }));
3086
3200
  }
3087
3201
 
3088
3202
  function CwInput(CwInputProps) {
@@ -3123,7 +3237,7 @@ function CwDigit(props) {
3123
3237
  return (jsx("div", { className: "cw-input-text", children: jsxs(CwAlign, { ...alignProps, itemProp: inputProps.required === true ? "required" : "", children: [labelProps && (jsxs(CwLabel, { ...labelProps, children: [iconProps && jsx(CwIcon, { ...iconProps }), labelProps.text] })), jsx("input", { type: "number", ...inputProps }), buttonProps && jsx(CwButton, { ...buttonProps })] }) }));
3124
3238
  }
3125
3239
 
3126
- var styles$i = {"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"};
3240
+ var styles$j = {"colorPreview":"cw-color-picker-module__colorPreview__ylJcD","hueBar":"cw-color-picker-module__hueBar__bFhyC","hueBarSlider":"cw-color-picker-module__hueBarSlider__D53IV","colorPickerInteractiveArea":"cw-color-picker-module__colorPickerInteractiveArea__KZFR1","colorArea":"cw-color-picker-module__colorArea__xgpSE","colorAreaOverlay":"cw-color-picker-module__colorAreaOverlay__pmgOc","hueBackground":"cw-color-picker-module__hueBackground__Mks78","whiteGradient":"cw-color-picker-module__whiteGradient__Bt-fU","blackGradient":"cw-color-picker-module__blackGradient__VnEKJ","colorAreaCursor":"cw-color-picker-module__colorAreaCursor__lotg3"};
3127
3241
 
3128
3242
  const CwColorPicker = ({ initialColor, onChange, previewText = "Color preview" }) => {
3129
3243
  const [rgb, setRgb] = useState({ r: 255, g: 255, b: 255 });
@@ -3326,13 +3440,13 @@ const CwColorPicker = ({ initialColor, onChange, previewText = "Color preview" }
3326
3440
  // Calculate background color for the main area based on current hue
3327
3441
  const hueColor = hsvToRgb(hsv.h, 100, 100);
3328
3442
  const hueHex = rgbToHex(hueColor.r, hueColor.g, hueColor.b);
3329
- return (jsxs("div", { className: "cw-flex-column cw-gap-small", children: [jsxs("div", { className: "cw-flex-row cw-align-between-center cw-gap-small", children: [jsx("div", { className: styles$i.colorPreview, style: { backgroundColor: hexColor, color: getContrastColor(hexColor) }, children: previewText }), jsx("button", { type: "button", className: "cw-button", onClick: toggleInputMode, style: { minWidth: "3ch" }, children: inputMode === 'hex' ? 'RGB' : 'HEX' })] }), jsx("div", { className: "color-inputs-row", children: inputMode === 'hex' ? (jsx("input", { type: "text", value: hexColor, onChange: handleHexChange })) : (jsxs("div", { className: "cw-grid-base-3 cw-gap-small", children: [jsxs("div", { children: [jsx("label", { children: "R:" }), jsx("input", { type: "number", name: "r", min: "0", max: "255", value: rgb.r, onChange: handleRgbChange })] }), jsxs("div", { children: [jsx("label", { children: "G:" }), jsx("input", { type: "number", name: "g", min: "0", max: "255", value: rgb.g, onChange: handleRgbChange })] }), jsxs("div", { children: [jsx("label", { children: "B:" }), jsx("input", { type: "number", name: "b", min: "0", max: "255", value: rgb.b, onChange: handleRgbChange })] })] })) }), jsxs("div", { className: styles$i.colorPickerInteractiveArea, children: [jsx("div", { className: styles$i.hueBar, ref: hueBarRef, onClick: handleHueBarClick, children: jsx("div", { className: styles$i.hueBarSlider, style: { top: `${(360 - hsv.h) / 360 * 100}%` } }) }), jsxs("div", { className: styles$i.colorArea, ref: colorAreaRef, onClick: handleColorAreaClick, children: [jsxs("div", { className: styles$i.colorAreaOverlay, children: [jsx("div", { className: styles$i.hueBackground, style: { backgroundColor: hueHex } }), jsx("div", { className: styles$i.whiteGradient }), jsx("div", { className: styles$i.blackGradient })] }), jsx("div", { className: styles$i.colorAreaCursor, style: {
3443
+ return (jsxs("div", { className: "cw-flex-column cw-gap-small", children: [jsxs("div", { className: "cw-flex-row cw-align-between-center cw-gap-small", children: [jsx("div", { className: styles$j.colorPreview, style: { backgroundColor: hexColor, color: getContrastColor(hexColor) }, children: previewText }), jsx("button", { type: "button", className: "cw-button", onClick: toggleInputMode, style: { minWidth: "3ch" }, children: inputMode === 'hex' ? 'RGB' : 'HEX' })] }), jsx("div", { className: "color-inputs-row", children: inputMode === 'hex' ? (jsx("input", { type: "text", value: hexColor, onChange: handleHexChange })) : (jsxs("div", { className: "cw-grid-base-3 cw-gap-small", children: [jsxs("div", { children: [jsx("label", { children: "R:" }), jsx("input", { type: "number", name: "r", min: "0", max: "255", value: rgb.r, onChange: handleRgbChange })] }), jsxs("div", { children: [jsx("label", { children: "G:" }), jsx("input", { type: "number", name: "g", min: "0", max: "255", value: rgb.g, onChange: handleRgbChange })] }), jsxs("div", { children: [jsx("label", { children: "B:" }), jsx("input", { type: "number", name: "b", min: "0", max: "255", value: rgb.b, onChange: handleRgbChange })] })] })) }), jsxs("div", { className: styles$j.colorPickerInteractiveArea, children: [jsx("div", { className: styles$j.hueBar, ref: hueBarRef, onClick: handleHueBarClick, children: jsx("div", { className: styles$j.hueBarSlider, style: { top: `${(360 - hsv.h) / 360 * 100}%` } }) }), jsxs("div", { className: styles$j.colorArea, ref: colorAreaRef, onClick: handleColorAreaClick, children: [jsxs("div", { className: styles$j.colorAreaOverlay, children: [jsx("div", { className: styles$j.hueBackground, style: { backgroundColor: hueHex } }), jsx("div", { className: styles$j.whiteGradient }), jsx("div", { className: styles$j.blackGradient })] }), jsx("div", { className: styles$j.colorAreaCursor, style: {
3330
3444
  left: `${hsv.s}%`,
3331
3445
  top: `${100 - hsv.v}%`
3332
3446
  } })] })] })] }));
3333
3447
  };
3334
3448
 
3335
- var styles$h = {"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"};
3449
+ var styles$i = {"container":"cw-input-color-module__container__x7gpk","selectColor":"cw-input-color-module__selectColor__DTo3V","disabled":"cw-input-color-module__disabled__O1fK5","readOnly":"cw-input-color-module__readOnly__HL-Bz","colorDropdown":"cw-input-color-module__colorDropdown__pX2bc"};
3336
3450
 
3337
3451
  const CwInputColor = ({ value, onChange, previewText = "Color preview", disabled = false, readOnly = false, width = '4rem', height = '2rem', labelProps, layoutProps, }) => {
3338
3452
  const [isOpen, setIsOpen] = useState(false);
@@ -3465,11 +3579,11 @@ const CwInputColor = ({ value, onChange, previewText = "Color preview", disabled
3465
3579
  break;
3466
3580
  }
3467
3581
  };
3468
- return (jsxs("div", { className: `cw-input-color ${styles$h.container}`, "data-direction": layoutProps?.direction ?? "row", "data-align": layoutProps?.align, children: [labelProps && (jsx(CwLabel, { ...labelProps })), jsx("div", { ref: containerRef, onClick: handleToggle, className: `${styles$h.selectColor} ${disabled ? styles$h.disabled : ''} ${readOnly ? styles$h.readOnly : ''}`, style: {
3582
+ return (jsxs("div", { className: `cw-input-color ${styles$i.container}`, "data-direction": layoutProps?.direction ?? "row", "data-align": layoutProps?.align, children: [labelProps && (jsx(CwLabel, { ...labelProps })), jsx("div", { ref: containerRef, onClick: handleToggle, className: `${styles$i.selectColor} ${disabled ? styles$i.disabled : ''} ${readOnly ? styles$i.readOnly : ''}`, style: {
3469
3583
  width,
3470
3584
  height,
3471
3585
  backgroundColor: value,
3472
- }, "aria-label": "Open color picker", "aria-expanded": isOpen, "aria-haspopup": "dialog", "aria-readonly": readOnly, role: "button", tabIndex: disabled ? -1 : 0, onKeyDown: handleKeyDown }), isOpen && createPortal(jsx("div", { ref: dropdownRef, className: styles$h.colorDropdown, style: dropdownStyle, role: "dialog", "aria-modal": "true", "aria-label": "Color picker", children: jsx(CwColorPicker, { initialColor: value, onChange: handleColorChange, previewText: previewText }) }), document.body)] }));
3586
+ }, "aria-label": "Open color picker", "aria-expanded": isOpen, "aria-haspopup": "dialog", "aria-readonly": readOnly, role: "button", tabIndex: disabled ? -1 : 0, onKeyDown: handleKeyDown }), isOpen && createPortal(jsx("div", { ref: dropdownRef, className: styles$i.colorDropdown, style: dropdownStyle, role: "dialog", "aria-modal": "true", "aria-label": "Color picker", children: jsx(CwColorPicker, { initialColor: value, onChange: handleColorChange, previewText: previewText }) }), document.body)] }));
3473
3587
  };
3474
3588
 
3475
3589
  /**
@@ -3719,31 +3833,63 @@ function CwInputDateText(props) {
3719
3833
  return (jsx("div", { className: "cw-input-date-text", children: jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxs(CwLabel, { ...labelProps, children: [iconProps && jsx(CwIcon, { ...iconProps }), labelProps.text] })), jsxs("div", { children: [jsx("input", { type: "text", disabled: disabled, maxLength: 10, onChange: onChangeInputText, pattern: "^$ --|[.0-9\\/\\-]{10}", placeholder: format.toLowerCase(), readOnly: readOnly, ref: textInputRef, required: required, size: width, tabIndex: tabIndex, value: displayedDate }), jsxs("span", { children: [jsx(CwIcon, { iconId: "calendar" }), jsx("input", { type: "date", disabled: disabled, onChange: onChangeInputDate, readOnly: readOnly, ref: dateInputRef, tabIndex: -1, value: date, ...inputProps })] })] }), buttonProps && jsx(CwButton, { ...buttonProps })] }) }));
3720
3834
  }
3721
3835
 
3722
- var styles$g = {"dropZone":"cw-input-image-module__dropZone__ygrGu"};
3836
+ var styles$h = {"hiddenInput":"cw-input-image-module__hiddenInput__pS7hb","dropZone":"cw-input-image-module__dropZone__ygrGu","title":"cw-input-image-module__title__Rji5M","subtitle":"cw-input-image-module__subtitle__djYYu","container":"cw-input-image-module__container__qh7Tm"};
3723
3837
 
3838
+ const DEFAULT_LABELS = {
3839
+ dropImageHere: "Drop image here",
3840
+ paste: "Paste",
3841
+ browse: "Browse",
3842
+ acceptedFormats: (formats) => `(${formats})`,
3843
+ clipboardError: "Failed to read from clipboard. Ensure the app has permission to access the clipboard.",
3844
+ invalidType: (formats) => `Unsupported file type. Allowed: ${formats}`,
3845
+ readError: "Could not read the image file.",
3846
+ };
3847
+ /** Reads a file/blob into a base64 data URL (persistable, no blob URL to revoke). */
3848
+ function readImageFileAsDataUrl(file) {
3849
+ return new Promise((resolve, reject) => {
3850
+ const reader = new FileReader();
3851
+ reader.onload = () => resolve(reader.result);
3852
+ reader.onerror = () => reject(reader.error ?? new Error("Failed to read file"));
3853
+ reader.readAsDataURL(file);
3854
+ });
3855
+ }
3724
3856
  function CwInputImage(props) {
3725
3857
  const [_uploadedImage, setUploadedImage] = useState(null);
3726
3858
  const inputRef = useRef(null);
3727
- const { allowedImageFormats, onChange, ...inputProps } = props;
3859
+ const { allowedImageFormats, onChange, onError, labels: labelsProp, size, ...inputProps } = props;
3728
3860
  const allowedFormats = allowedImageFormats || ["image/jpeg", "image/png", "image/gif"];
3861
+ const labels = { ...DEFAULT_LABELS, ...labelsProp };
3729
3862
  const isValidFileType = (type) => allowedFormats.includes(type);
3730
- const handleFile = (file) => {
3731
- if (file && isValidFileType(file.type)) {
3732
- const imgURL = URL.createObjectURL(file);
3733
- setUploadedImage(imgURL);
3734
- if (onChange)
3735
- onChange(imgURL);
3863
+ const reportError = (message) => {
3864
+ if (onError)
3865
+ onError(message);
3866
+ else
3867
+ CwDisplayMessage(message, CwMessageType.ERROR);
3868
+ };
3869
+ const handleFile = async (file) => {
3870
+ if (!file) {
3871
+ onChange?.(null);
3872
+ return;
3736
3873
  }
3737
- else {
3738
- // Optionally handle unsupported file types
3739
- if (onChange)
3740
- onChange(null);
3874
+ if (!isValidFileType(file.type)) {
3875
+ reportError(labels.invalidType(allowedFormats.join(", ").replace(/image\//g, "")));
3876
+ onChange?.(null);
3877
+ return;
3878
+ }
3879
+ try {
3880
+ const dataUrl = await readImageFileAsDataUrl(file);
3881
+ setUploadedImage(dataUrl);
3882
+ onChange?.(dataUrl, file);
3883
+ }
3884
+ catch {
3885
+ reportError(labels.readError);
3886
+ onChange?.(null);
3741
3887
  }
3742
3888
  };
3743
3889
  const handleDrop = (e) => {
3744
3890
  e.preventDefault();
3745
3891
  const file = e.dataTransfer.files[0];
3746
- handleFile(file);
3892
+ void handleFile(file ?? null);
3747
3893
  };
3748
3894
  const onPasteButtonClick = async () => {
3749
3895
  try {
@@ -3753,21 +3899,20 @@ function CwInputImage(props) {
3753
3899
  for (const type of clipboardItem.types) {
3754
3900
  if (type.startsWith("image/")) {
3755
3901
  const blob = await clipboardItem.getType(type);
3756
- handleFile(blob);
3902
+ await handleFile(blob);
3757
3903
  }
3758
3904
  }
3759
3905
  }
3760
3906
  }
3761
- catch (err) {
3762
- console.error("Failed to read clipboard:", err);
3763
- alert("Failed to read from clipboard. Ensure the app has permission to access clipboard.");
3907
+ catch {
3908
+ reportError(labels.clipboardError);
3764
3909
  }
3765
3910
  };
3766
3911
  const handleFileChange = (e) => {
3767
- const file = e.target.files?.[0];
3768
- handleFile(file ?? null);
3912
+ const file = e.currentTarget.files?.[0];
3913
+ void handleFile(file ?? null);
3769
3914
  };
3770
- return (jsxs("div", { className: "cw-input-image", children: [jsxs("div", { onDragOver: (e) => e.preventDefault(), onDrop: handleDrop, className: styles$g.dropZone, children: [jsx("p", { children: "Drop image here" }), jsxs("small", { children: ["(", allowedFormats.join(", ").replace(/image\//g, ""), ")"] })] }), jsxs("div", { className: "cw-flex-row cw-align-center-center cw-gap-small", children: [jsx(CwButton, { onClick: onPasteButtonClick, icon: "paste", text: "Paste" }), jsx(CwButton, { onClick: () => inputRef.current?.click(), icon: "folder-open", text: "Browse" })] }), jsx("input", { ref: inputRef, type: "file", accept: allowedFormats.join(","), onChange: handleFileChange, style: { display: "none" }, ...inputProps })] }));
3915
+ return (jsxs("div", { className: `cw-input-image ${styles$h.container}`, "data-size": size, children: [jsxs("div", { onDragOver: (e) => e.preventDefault(), onDrop: handleDrop, className: styles$h.dropZone, children: [jsx(CwIcon, { iconId: "upload" }), jsxs("div", { className: "cw-flex-column cw-gap-tiny", children: [jsx("p", { className: styles$h.title, children: labels.dropImageHere }), jsx("p", { className: styles$h.subtitle, children: labels.acceptedFormats(allowedFormats.join(", ").replace(/image\//g, "")) })] })] }), jsxs("div", { className: "cw-flex-row cw-align-center-center cw-gap-small", children: [jsx(CwButton, { onClick: onPasteButtonClick, icon: "paste", text: labels.paste, size: size }), jsx(CwButton, { onClick: () => inputRef.current?.click(), icon: "folder-open", text: labels.browse, size: size })] }), jsx("input", { ref: inputRef, type: "file", accept: allowedFormats.join(","), onChange: handleFileChange, className: styles$h.hiddenInput, ...inputProps })] }));
3771
3916
  }
3772
3917
 
3773
3918
  /**
@@ -3899,7 +4044,7 @@ const CwImageArea = forwardRef((props, ref) => {
3899
4044
  });
3900
4045
  CwImageArea.displayName = "CwImageArea";
3901
4046
 
3902
- var styles$f = {"cw-weekday-selector":"cw-weekday-selector-module__cw-weekday-selector__Iz4GZ"};
4047
+ var styles$g = {"cw-weekday-selector":"cw-weekday-selector-module__cw-weekday-selector__Iz4GZ"};
3903
4048
 
3904
4049
  /**
3905
4050
  * This class represents a week where days can be selected or unselected
@@ -4039,16 +4184,16 @@ const CwWeekdaySelector = ({ value = "", onChange, disabled = false }) => {
4039
4184
  setSelectedDays(newWeekdays);
4040
4185
  onChange?.(newWeekdays.toString());
4041
4186
  };
4042
- return (jsx("div", { className: styles$f["cw-weekday-selector"], children: Weekdays.getFullWeek().map(day => (jsx("input", { type: "checkbox", "data-day": day, checked: selectedDays.toArray().includes(day), onChange: (e) => handleChange(day, e.target.checked), disabled: disabled }, day))) }));
4187
+ return (jsx("div", { className: styles$g["cw-weekday-selector"], children: Weekdays.getFullWeek().map(day => (jsx("input", { type: "checkbox", "data-day": day, checked: selectedDays.toArray().includes(day), onChange: (e) => handleChange(day, e.target.checked), disabled: disabled }, day))) }));
4043
4188
  };
4044
4189
 
4045
- var styles$e = {"check-container":"cw-check-module__check-container__4nscZ","group":"cw-check-module__group__6JCQo","options":"cw-check-module__options__-g9LF"};
4190
+ var styles$f = {"check-container":"cw-check-module__check-container__4nscZ","group":"cw-check-module__group__6JCQo","options":"cw-check-module__options__-g9LF"};
4046
4191
 
4047
4192
  function CwCheck(props) {
4048
4193
  const { labelProps, labelText, direction, alignment, className, ...inputProps } = props;
4049
4194
  const resolvedDirection = direction ?? alignment ?? "row";
4050
4195
  const displayText = labelProps?.text ?? labelText;
4051
- return (jsx("div", { className: `cw-check ${styles$e["check-container"]}${className ? ` ${className}` : ''}`, children: jsxs("label", { "data-direction": resolvedDirection, children: [jsx("input", { type: "checkbox", ...inputProps }), displayText && (jsx("span", { className: "cw-icon-text", children: displayText }))] }) }));
4196
+ return (jsx("div", { className: `cw-check ${styles$f["check-container"]}${className ? ` ${className}` : ''}`, children: jsxs("label", { "data-direction": resolvedDirection, children: [jsx("input", { type: "checkbox", ...inputProps }), displayText && (jsx("span", { className: "cw-icon-text", children: displayText }))] }) }));
4052
4197
  }
4053
4198
 
4054
4199
  function CwCheckbox(CwCheckboxProps) {
@@ -4099,14 +4244,14 @@ function CwCheckboxGroup({ options, value = [], onChange, labelProps, groupLayou
4099
4244
  ?? (optionsAlignment === "column" ? "row" : "column");
4100
4245
  // Each checkbox's box-to-text layout is the opposite of the options flow, mirroring CwRadioGroup.
4101
4246
  const checkDirection = itemDirection === "row" ? "column" : "row";
4102
- return (jsxs("div", { className: `cw-checkbox-group ${styles$e.group}${className ? ` ${className}` : ""}`, "data-testid": dataTestId, "data-direction": labelProps ? groupDirection : "column", "data-align": groupLayout?.align, "data-gap": groupLayout?.gap, children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsx("div", { className: styles$e.options, role: "group", "aria-label": labelProps?.text, "aria-required": required || undefined, "data-direction": itemDirection, "data-gap": itemLayout?.gap, children: options.map((option) => (jsx(CwCheck, { labelProps: { text: option.label }, checked: value.includes(option.value), disabled: disabled || option.disabled, direction: checkDirection, onChange: (e) => handleChange(option.value, e.currentTarget.checked) }, option.value))) }), feedbackMessages.map((feedbackItem, index) => (jsx("p", { className: "cw-input-info", "data-color": feedbackItem.type, children: feedbackItem.message }, index)))] }));
4247
+ return (jsxs("div", { className: `cw-checkbox-group ${styles$f.group}${className ? ` ${className}` : ""}`, "data-testid": dataTestId, "data-direction": labelProps ? groupDirection : "column", "data-align": groupLayout?.align, "data-gap": groupLayout?.gap, children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsx("div", { className: styles$f.options, role: "group", "aria-label": labelProps?.text, "aria-required": required || undefined, "data-direction": itemDirection, "data-gap": itemLayout?.gap, children: options.map((option) => (jsx(CwCheck, { labelProps: { text: option.label }, checked: value.includes(option.value), disabled: disabled || option.disabled, direction: checkDirection, onChange: (e) => handleChange(option.value, e.currentTarget.checked) }, option.value))) }), feedbackMessages.map((feedbackItem, index) => (jsx("p", { className: "cw-input-info", "data-color": feedbackItem.type, children: feedbackItem.message }, index)))] }));
4103
4248
  }
4104
4249
 
4105
- var styles$d = {"radio":"cw-radio-module__radio__5sh7a","group":"cw-radio-module__group__br-HM","options":"cw-radio-module__options__LSw7M"};
4250
+ var styles$e = {"radio":"cw-radio-module__radio__5sh7a","group":"cw-radio-module__group__br-HM","options":"cw-radio-module__options__LSw7M"};
4106
4251
 
4107
4252
  /** Single native radio input. Building block for CwRadioGroup. */
4108
4253
  function CwRadio({ label, direction = "row", className, ...inputProps }) {
4109
- return (jsxs("label", { className: `cw-radio ${styles$d.radio}${className ? ` ${className}` : ""}`, "data-direction": direction, children: [jsx("input", { type: "radio", ...inputProps }), label && jsx("span", { children: label })] }));
4254
+ return (jsxs("label", { className: `cw-radio ${styles$e.radio}${className ? ` ${className}` : ""}`, "data-direction": direction, children: [jsx("input", { type: "radio", ...inputProps }), label && jsx("span", { children: label })] }));
4110
4255
  }
4111
4256
 
4112
4257
  /**
@@ -4130,7 +4275,7 @@ function CwRadioGroup({ options, value, onChange, labelProps, groupLayout, itemL
4130
4275
  // (itemLayout column) reads best with the circle beside the text; a side-by-side row reads
4131
4276
  // best with the circle above the text.
4132
4277
  const radioDirection = itemLayout?.direction === "row" ? "column" : "row";
4133
- return (jsxs("div", { className: `cw-radio-group ${styles$d.group}${className ? ` ${className}` : ""}`, "data-testid": dataTestId, "data-direction": labelProps ? (groupLayout?.direction ?? "column") : "column", "data-align": groupLayout?.align, "data-gap": groupLayout?.gap, children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsx("div", { className: styles$d.options, role: "radiogroup", "aria-labelledby": ariaLabelledby, "aria-label": ariaLabelledby ? undefined : (ariaLabel ?? labelProps?.text), "aria-required": required || undefined, "data-direction": itemLayout?.direction ?? "column", "data-gap": itemLayout?.gap, children: options.map((option) => (jsx(CwRadio, { name: groupName, label: option.label, direction: radioDirection, checked: value === option.value, required: required, disabled: disabled || option.disabled, onChange: () => onChange(option.value) }, option.value))) }), feedbackMessages.map((feedbackItem, index) => (jsx("p", { className: "cw-input-info", "data-color": feedbackItem.type, children: feedbackItem.message }, index)))] }));
4278
+ return (jsxs("div", { className: `cw-radio-group ${styles$e.group}${className ? ` ${className}` : ""}`, "data-testid": dataTestId, "data-direction": labelProps ? (groupLayout?.direction ?? "column") : "column", "data-align": groupLayout?.align, "data-gap": groupLayout?.gap, children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsx("div", { className: styles$e.options, role: "radiogroup", "aria-labelledby": ariaLabelledby, "aria-label": ariaLabelledby ? undefined : (ariaLabel ?? labelProps?.text), "aria-required": required || undefined, "data-direction": itemLayout?.direction ?? "column", "data-gap": itemLayout?.gap, children: options.map((option) => (jsx(CwRadio, { name: groupName, label: option.label, direction: radioDirection, checked: value === option.value, required: required, disabled: disabled || option.disabled, onChange: () => onChange(option.value) }, option.value))) }), feedbackMessages.map((feedbackItem, index) => (jsx("p", { className: "cw-input-info", "data-color": feedbackItem.type, children: feedbackItem.message }, index)))] }));
4134
4279
  }
4135
4280
 
4136
4281
  function CwToggle(props) {
@@ -4396,7 +4541,7 @@ function CwDropdownFilter(props) {
4396
4541
  return (jsxs("div", { id: props.IdContent, className: containerClassName, children: [props.children, isVisible && (jsx("nav", { className: "cw-dropdown-menu", style: inlineStyles, onMouseLeave: props.onMouseLeave, id: props.idDropDownFilter, role: "menu", children: jsx("ul", { role: "none", children: props.DataSourceDropDownItem?.map((item) => (jsx("li", { id: item.IdDropDown_filter, role: "menuitem", children: item.dropDownFilter_desc }, item.IdDropDown_filter))) }) }))] }));
4397
4542
  }
4398
4543
 
4399
- var styles$c = {"container":"cw-popover-button-module__container__YSWQU","panel":"cw-popover-button-module__panel__C-BTn"};
4544
+ var styles$d = {"container":"cw-popover-button-module__container__YSWQU","panel":"cw-popover-button-module__panel__C-BTn"};
4400
4545
 
4401
4546
  /**
4402
4547
  * Button that toggles a floating panel with arbitrary children.
@@ -4475,7 +4620,7 @@ function CwPopoverButton({ children, panelWidth = "auto", placement = "bottom-st
4475
4620
  }
4476
4621
  panel.showPopover();
4477
4622
  }, [placement]);
4478
- return (jsxs("div", { ref: containerRef, className: styles$c.container, children: [jsx(CwButton, { ...buttonProps, onClick: handleClick }), jsx("div", { ref: panelCallbackRef, className: `${styles$c.panel}${panelClassName ? ` ${panelClassName}` : ""}`, style: { width: panelWidth }, children: children })] }));
4623
+ return (jsxs("div", { ref: containerRef, className: styles$d.container, children: [jsx(CwButton, { ...buttonProps, onClick: handleClick }), jsx("div", { ref: panelCallbackRef, className: `${styles$d.panel}${panelClassName ? ` ${panelClassName}` : ""}`, style: { width: panelWidth }, children: children })] }));
4479
4624
  }
4480
4625
 
4481
4626
  function itemsToMultiFilterTags(items, nameKey, valueKey, category, primaryColor, onPrimaryColor) {
@@ -4493,13 +4638,13 @@ function itemsToMultiFilterTags(items, nameKey, valueKey, category, primaryColor
4493
4638
  return result;
4494
4639
  }
4495
4640
 
4496
- var styles$b = {"cw-multifilter-tag":"cw-multi-filter-tag-module__cw-multifilter-tag__Epda-"};
4641
+ var styles$c = {"cw-multifilter-tag":"cw-multi-filter-tag-module__cw-multifilter-tag__Epda-"};
4497
4642
 
4498
4643
  const CwMultiFilterTag = props => {
4499
4644
  const { ID, Name, Value, Category, Removable, PrimaryColor, Selectable, Selected } = props;
4500
4645
  const backgroundColor = `rgb(${PrimaryColor.r},${PrimaryColor.g},${PrimaryColor.b})`;
4501
4646
  const isOutlineMode = Selected && !Removable;
4502
- return (jsx("li", { className: styles$b["cw-multifilter-tag"], id: ID, "data-value": Value, "data-category": Category, "data-selected": !!Selected, title: props.tooltip ?? Name, onClick: () => {
4647
+ return (jsx("li", { className: styles$c["cw-multifilter-tag"], id: ID, "data-value": Value, "data-category": Category, "data-selected": !!Selected, title: props.tooltip ?? Name, onClick: () => {
4503
4648
  if (Selectable)
4504
4649
  props.OnSelect?.(props);
4505
4650
  }, children: jsx(CwChip, { label: Name, colorScheme: "custom", customColor: backgroundColor, variant: isOutlineMode ? "outline" : "soft", closable: Removable, onClose: () => props.OnRemove?.(props),
@@ -4509,7 +4654,7 @@ const CwMultiFilterTag = props => {
4509
4654
  } : undefined }) }));
4510
4655
  };
4511
4656
 
4512
- var styles$a = {"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"};
4657
+ var styles$b = {"cw-multi-filter-catalog-container":"cw-multi-filter-module__cw-multi-filter-catalog-container__S3nsq","cw-multi-filter":"cw-multi-filter-module__cw-multi-filter__zipBK","category-selected":"cw-multi-filter-module__category-selected__eYbes","cw-multi-filter-search":"cw-multi-filter-module__cw-multi-filter-search__eyHr0 cw-choice-input-box-module__inputBox__gHY9d"};
4513
4658
 
4514
4659
  /**
4515
4660
  * A multiple filter selector, a MULTI-SELECT even. Allows users to select and filter items based on tags.
@@ -4736,9 +4881,9 @@ const CwMultiFilter = ({ allTags, id, onChangeSelectedTags, selectedTags, placeh
4736
4881
  inputRef.current?.focus();
4737
4882
  }
4738
4883
  };
4739
- return (jsxs("form", { ref: componentRef, id: id, className: `${styles$a["cw-multi-filter"]}${className ? ` ${className}` : ""}`, style: style, onSubmit: (e) => {
4884
+ return (jsxs("form", { ref: componentRef, id: id, className: `${styles$b["cw-multi-filter"]}${className ? ` ${className}` : ""}`, style: style, onSubmit: (e) => {
4740
4885
  e.preventDefault();
4741
- }, children: [jsxs("div", { onClick: handleDivClick, ref: wrapperRef, className: styles$a["cw-multi-filter-search"], style: isPanelOpen ? { outline: "1px solid var(--cw-color-outline-variant)" } : {}, children: [jsxs("ul", { id: id + "_selected_filters", children: [Array.from(selectedTags).map(tag => (createElement(CwMultiFilterTag, { ...tag, key: tag.ID, Selectable: false, Removable: true, OnRemove: () => removeTag(tag.ID) }))), jsx("input", { type: "text", id: id + "_input", ref: inputRef, value: inputTextValue, spellCheck: false, onFocus: () => setIsPanelOpen(true), onChange: e => handleInputText(e.currentTarget.value), autoComplete: "off", placeholder: selectedTags.size === 0 ? placeholder : "", onKeyDown: e => {
4886
+ }, children: [jsxs("div", { onClick: handleDivClick, ref: wrapperRef, className: styles$b["cw-multi-filter-search"], style: isPanelOpen ? { outline: "1px solid var(--cw-color-outline-variant)" } : {}, children: [jsxs("ul", { id: id + "_selected_filters", children: [Array.from(selectedTags).map(tag => (createElement(CwMultiFilterTag, { ...tag, key: tag.ID, Selectable: false, Removable: true, OnRemove: () => removeTag(tag.ID) }))), jsx("input", { type: "text", id: id + "_input", ref: inputRef, value: inputTextValue, spellCheck: false, onFocus: () => setIsPanelOpen(true), onChange: e => handleInputText(e.currentTarget.value), autoComplete: "off", placeholder: selectedTags.size === 0 ? placeholder : "", onKeyDown: e => {
4742
4887
  switch (e.key) {
4743
4888
  case "Enter":
4744
4889
  case "Tab": {
@@ -4765,7 +4910,7 @@ const CwMultiFilter = ({ allTags, id, onChangeSelectedTags, selectedTags, placeh
4765
4910
  break;
4766
4911
  }
4767
4912
  }
4768
- } })] }), selectedTags.size > 0 && (jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onMouseDown: e => e.preventDefault(), onClick: (e) => { e.stopPropagation(); onChangeSelectedTags(new Set()); setIsPanelOpen(false); }, tabIndex: -1, "aria-label": "Clear all" }))] }), renderPanel(jsxs("section", { ref: panelRef, className: styles$a["cw-multi-filter-catalog-container"], style: panelStyle, children: [jsxs("nav", { children: [jsx("button", { className: selectedCategory === "All" ? styles$a["category-selected"] : undefined, onClick: () => handleClickCategory("All"), children: allCategoriesLabel }), Array.from(categoriesMappedToTags().keys()).map(category => (jsx("button", { className: selectedCategory === category ? styles$a["category-selected"] : undefined, style: {
4913
+ } })] }), selectedTags.size > 0 && (jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onMouseDown: e => e.preventDefault(), onClick: (e) => { e.stopPropagation(); onChangeSelectedTags(new Set()); setIsPanelOpen(false); }, tabIndex: -1, "aria-label": "Clear all" }))] }), renderPanel(jsxs("section", { ref: panelRef, className: styles$b["cw-multi-filter-catalog-container"], style: panelStyle, children: [jsxs("nav", { children: [jsx("button", { className: selectedCategory === "All" ? styles$b["category-selected"] : undefined, onClick: () => handleClickCategory("All"), children: allCategoriesLabel }), Array.from(categoriesMappedToTags().keys()).map(category => (jsx("button", { className: selectedCategory === category ? styles$b["category-selected"] : undefined, style: {
4769
4914
  backgroundColor: getColor(category).primary,
4770
4915
  color: getColor(category).onPrimary,
4771
4916
  }, onClick: () => handleClickCategory(category), children: category }, category)))] }), jsx("ul", { children: displayTags
@@ -4791,7 +4936,7 @@ const CwMultiFilter = ({ allTags, id, onChangeSelectedTags, selectedTags, placeh
4791
4936
  } }, props.ID))) })] }))] }));
4792
4937
  };
4793
4938
 
4794
- var styles$9 = {"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"};
4939
+ var styles$a = {"container":"cw-tag-selector-module__container__-do8i","inputBox":"cw-tag-selector-module__inputBox__3NGz9 cw-choice-input-box-module__inputBox__gHY9d","disabled":"cw-tag-selector-module__disabled__vbud9 cw-choice-input-box-module__disabled__TFAnC","dropdown":"cw-tag-selector-module__dropdown__X6Dob cw-choice-dropdown-module__dropdown__P0b4j","option":"cw-tag-selector-module__option__2UQ7g cw-choice-dropdown-module__option__uR-ro","optionFocused":"cw-tag-selector-module__optionFocused__8-lv8 cw-choice-dropdown-module__optionFocused__BYMxj","optionDot":"cw-tag-selector-module__optionDot__CdFlG cw-choice-dropdown-module__colorCircle__x7mI9","selectAll":"cw-tag-selector-module__selectAll__HyvMA"};
4795
4940
 
4796
4941
  /**
4797
4942
  * Multi-select input with chip tags and searchable dropdown.
@@ -4926,11 +5071,11 @@ function CwTagSelector({ id, options, value, onChange, labelProps, iconProps, al
4926
5071
  // Keeping containerRef for any other potential use
4927
5072
  const direction = alignProps?.flexDirection ?? "row";
4928
5073
  const feedbackMessages = feedback ? (Array.isArray(feedback) ? feedback : [feedback]) : [];
4929
- return (jsxs("div", { ref: containerRef, className: `${styles$9.container}${className ? ` ${className}` : ""}`, style: style, id: id, "data-direction": direction, children: [jsxs(CwAlign, { ...alignProps, children: [labelProps && (jsxs(CwLabel, { ...labelProps, children: [iconProps && jsx(CwIcon, { ...iconProps }), labelProps.text] })), jsxs("div", { className: `${styles$9.inputBox}${disabled ? ` ${styles$9.disabled}` : ""}`, ref: inputBoxRef, onClick: () => { if (!disabled)
4930
- inputRef.current?.focus(); }, children: [selectedOptions.map(opt => (jsx(CwChip, { label: opt.label, colorScheme: opt.color ? "custom" : "info", customColor: opt.color, closable: !disabled, onClose: () => handleRemove(opt.value) }, opt.value))), jsx("input", { ref: inputRef, type: "text", value: search, onChange: handleInputChange, onFocus: handleInputFocus, onKeyDown: handleKeyDown, placeholder: selectedOptions.length === 0 ? placeholder : "", disabled: disabled, autoComplete: "off" }), value.length > 0 && !disabled && (jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onMouseDown: (e) => e.preventDefault(), onClick: (e) => { e.stopPropagation(); onChange([]); setSearch(""); setOpen(false); }, tabIndex: -1, "aria-label": "Clear all" }))] })] }), feedbackMessages.map((fb, i) => (jsx("p", { className: "cw-input-info", "data-color": fb.type, children: fb.message }, i))), renderPanel((showSelectAll || filtered.length > 0) ? (jsxs("div", { ref: panelRef, className: styles$9.dropdown, style: panelStyle, children: [showSelectAll && !search && (jsxs("div", { className: styles$9.selectAll, onMouseDown: (e) => e.preventDefault(), onClick: handleToggleAll, children: [jsx("input", { type: "checkbox", checked: allSelected, readOnly: true, tabIndex: -1 }), allSelected ? "Deselect all" : "Select all"] })), jsx("ul", { ref: listRef, children: filtered.map((opt, idx) => (jsxs("li", { className: `${styles$9.option}${idx === focusedIndex ? ` ${styles$9.optionFocused}` : ""}`, onMouseDown: (e) => e.preventDefault(), onClick: () => handleSelect(opt.value), onMouseEnter: () => setFocusedIndex(idx), title: opt.tooltip, children: [opt.color && jsx("span", { className: styles$9.optionDot, style: { backgroundColor: opt.color } }), opt.label] }, opt.value))) })] })) : null)] }));
5074
+ return (jsxs("div", { ref: containerRef, className: `${styles$a.container}${className ? ` ${className}` : ""}`, style: style, id: id, "data-direction": direction, children: [jsxs(CwAlign, { ...alignProps, children: [labelProps && (jsxs(CwLabel, { ...labelProps, children: [iconProps && jsx(CwIcon, { ...iconProps }), labelProps.text] })), jsxs("div", { className: `${styles$a.inputBox}${disabled ? ` ${styles$a.disabled}` : ""}`, ref: inputBoxRef, onClick: () => { if (!disabled)
5075
+ inputRef.current?.focus(); }, children: [selectedOptions.map(opt => (jsx(CwChip, { label: opt.label, colorScheme: opt.color ? "custom" : "info", customColor: opt.color, closable: !disabled, onClose: () => handleRemove(opt.value) }, opt.value))), jsx("input", { ref: inputRef, type: "text", value: search, onChange: handleInputChange, onFocus: handleInputFocus, onKeyDown: handleKeyDown, placeholder: selectedOptions.length === 0 ? placeholder : "", disabled: disabled, autoComplete: "off" }), value.length > 0 && !disabled && (jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onMouseDown: (e) => e.preventDefault(), onClick: (e) => { e.stopPropagation(); onChange([]); setSearch(""); setOpen(false); }, tabIndex: -1, "aria-label": "Clear all" }))] })] }), feedbackMessages.map((fb, i) => (jsx("p", { className: "cw-input-info", "data-color": fb.type, children: fb.message }, i))), renderPanel((showSelectAll || filtered.length > 0) ? (jsxs("div", { ref: panelRef, className: styles$a.dropdown, style: panelStyle, children: [showSelectAll && !search && (jsxs("div", { className: styles$a.selectAll, onMouseDown: (e) => e.preventDefault(), onClick: handleToggleAll, children: [jsx("input", { type: "checkbox", checked: allSelected, readOnly: true, tabIndex: -1 }), allSelected ? "Deselect all" : "Select all"] })), jsx("ul", { ref: listRef, children: filtered.map((opt, idx) => (jsxs("li", { className: `${styles$a.option}${idx === focusedIndex ? ` ${styles$a.optionFocused}` : ""}`, onMouseDown: (e) => e.preventDefault(), onClick: () => handleSelect(opt.value), onMouseEnter: () => setFocusedIndex(idx), title: opt.tooltip, children: [opt.color && jsx("span", { className: styles$a.optionDot, style: { backgroundColor: opt.color } }), opt.label] }, opt.value))) })] })) : null)] }));
4931
5076
  }
4932
5077
 
4933
- var styles$8 = {"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"};
5078
+ var styles$9 = {"tree-container":"cw-tree-view-module__tree-container__NN-HJ","tree-wrapper":"cw-tree-view-module__tree-wrapper__keBZI","tree-item":"cw-tree-view-module__tree-item__prE9N","tree-node":"cw-tree-view-module__tree-node__wfro9","selected":"cw-tree-view-module__selected__XJQ0w","non-selectable":"cw-tree-view-module__non-selectable__YuPSx","tree-children":"cw-tree-view-module__tree-children__ji8CZ","empty-state":"cw-tree-view-module__empty-state__yvRjo","tree-label":"cw-tree-view-module__tree-label__ss3Nf","tree-spacer":"cw-tree-view-module__tree-spacer__E9Ud2"};
4934
5079
 
4935
5080
  function CwTreeView({ data, onSelect, allowParentSelection = false, selectedId: initialSelectedId = null }) {
4936
5081
  const [expanded, setExpanded] = useState(new Set());
@@ -4997,10 +5142,10 @@ function CwTreeView({ data, onSelect, allowParentSelection = false, selectedId:
4997
5142
  const isLeaf = !hasChildren;
4998
5143
  const isSelected = selectedId?.toString().toLowerCase() === node.id.toString().toLowerCase();
4999
5144
  const selectable = allowParentSelection || isLeaf;
5000
- return (jsxs("div", { className: styles$8["tree-item"], children: [jsxs("div", { className: [
5001
- styles$8["tree-node"],
5002
- isSelected && styles$8["selected"],
5003
- !selectable && styles$8["non-selectable"]
5145
+ return (jsxs("div", { className: styles$9["tree-item"], children: [jsxs("div", { className: [
5146
+ styles$9["tree-node"],
5147
+ isSelected && styles$9["selected"],
5148
+ !selectable && styles$9["non-selectable"]
5004
5149
  ].filter(Boolean).join(' '), style: { paddingLeft: `${depth * 24 + 8}px` }, onClick: () => {
5005
5150
  if (selectable) {
5006
5151
  setSelectedId(node.id);
@@ -5009,7 +5154,7 @@ function CwTreeView({ data, onSelect, allowParentSelection = false, selectedId:
5009
5154
  else {
5010
5155
  toggleExpand(node.id);
5011
5156
  }
5012
- }, children: [hasChildren && (jsx(CwIcon, { size: "large", iconId: isExpanded ? "chevron-down" : "chevron-right" })), jsx("div", { className: `${styles$8["tree-label"]} ${!hasChildren ? styles$8["tree-spacer"] : ''}`, children: node.label })] }), hasChildren && isExpanded && (jsx("div", { className: styles$8["tree-children"], children: node.children.map((child) => renderNode(child, depth + 1)) }))] }, node.id));
5157
+ }, children: [hasChildren && (jsx(CwIcon, { size: "large", iconId: isExpanded ? "chevron-down" : "chevron-right" })), jsx("div", { className: `${styles$9["tree-label"]} ${!hasChildren ? styles$9["tree-spacer"] : ''}`, children: node.label })] }), hasChildren && isExpanded && (jsx("div", { className: styles$9["tree-children"], children: node.children.map((child) => renderNode(child, depth + 1)) }))] }, node.id));
5013
5158
  };
5014
5159
  // Function to search for nodes that match the search term
5015
5160
  const searchInTree = (nodes, searchTerm) => {
@@ -5033,7 +5178,129 @@ function CwTreeView({ data, onSelect, allowParentSelection = false, selectedId:
5033
5178
  return results;
5034
5179
  };
5035
5180
  const filteredData = searchInTree(data, search);
5036
- return (jsxs("div", { className: `cw-tree-view ${styles$8["tree-container"]}`, children: [jsxs("header", { children: [jsx("input", { type: "text", placeholder: "Search in tree...", value: search, onChange: (e) => setSearch(e.target.value) }), search && (jsx(CwButton, { onClick: () => setSearch(""), type: "button", icon: "close", variant: "icon", color: "neutral" }))] }), jsx("div", { className: styles$8["tree-wrapper"], children: filteredData.length > 0 ? (filteredData.map((node) => renderNode(node))) : (jsxs("div", { className: styles$8["empty-state"], children: [jsx(CwIcon, { iconId: "comment" }), search ? "No results found" : "There are no items"] })) })] }));
5181
+ return (jsxs("div", { className: `cw-tree-view ${styles$9["tree-container"]}`, children: [jsxs("header", { children: [jsx("input", { type: "text", placeholder: "Search in tree...", value: search, onChange: (e) => setSearch(e.target.value) }), search && (jsx(CwButton, { onClick: () => setSearch(""), type: "button", icon: "close", variant: "icon", color: "neutral" }))] }), jsx("div", { className: styles$9["tree-wrapper"], children: filteredData.length > 0 ? (filteredData.map((node) => renderNode(node))) : (jsxs("div", { className: styles$9["empty-state"], children: [jsx(CwIcon, { iconId: "comment" }), search ? "No results found" : "There are no items"] })) })] }));
5182
+ }
5183
+
5184
+ const EXACT_PHRASE = /"([^"]+)"/g;
5185
+ /**
5186
+ * Quoted phrases are matched against the label only; loose words against label + description + href.
5187
+ * Parsed once instead of per node.
5188
+ */
5189
+ function parseSearch(search) {
5190
+ const phrases = Array.from(search.matchAll(EXACT_PHRASE), match => match[1].toLowerCase());
5191
+ const words = search
5192
+ .replace(EXACT_PHRASE, "")
5193
+ .trim()
5194
+ .toLowerCase()
5195
+ .split(/\s+/)
5196
+ .filter(Boolean);
5197
+ return { phrases, words };
5198
+ }
5199
+ /**
5200
+ * Filters a nav tree by a search string, keeping a group whose descendants match.
5201
+ *
5202
+ * Supports `"quoted phrases"` (must appear in the label) alongside loose words (any field) — this is
5203
+ * behaviour users are told about, so don't simplify it.
5204
+ */
5205
+ function filterNavItems(items, search) {
5206
+ if (!search?.trim())
5207
+ return items;
5208
+ const { phrases, words } = parseSearch(search);
5209
+ if (phrases.length === 0 && words.length === 0)
5210
+ return items;
5211
+ const keep = (item, parentMatchedPhrases) => {
5212
+ const label = item.label.toLowerCase();
5213
+ const haystack = [item.label, item.description, item.href].filter(Boolean).join(" ").toLowerCase();
5214
+ const matchesPhrases = phrases.every(phrase => label.includes(phrase));
5215
+ const matchesWords = words.every(word => haystack.includes(word));
5216
+ const selfMatches = (phrases.length === 0 || matchesPhrases || parentMatchedPhrases) && matchesWords;
5217
+ if (!item.children?.length)
5218
+ return selfMatches ? item : null;
5219
+ let children = item.children
5220
+ .map(child => keep(child, matchesPhrases || parentMatchedPhrases))
5221
+ .filter((child) => child !== null);
5222
+ // A phrase-only search narrows the survivors further: each must carry the phrase itself.
5223
+ if (phrases.length > 0 && words.length === 0 && matchesPhrases) {
5224
+ children = children.filter(child => phrases.every(phrase => child.label.toLowerCase().includes(phrase)));
5225
+ }
5226
+ if (children.length > 0)
5227
+ return { ...item, children };
5228
+ // The group matched but nothing under it did. Returning `children: []` would make it a leaf —
5229
+ // and a leaf with no href — so keep the subtree instead of emptying it.
5230
+ return selfMatches ? item : null;
5231
+ };
5232
+ return items
5233
+ .map(item => keep(item, false))
5234
+ .filter((item) => item !== null);
5235
+ }
5236
+
5237
+ /**
5238
+ * Sorts the top level alphabetically, leaving every nested list in the order the consumer gave.
5239
+ *
5240
+ * Deliberately level 1 only: this exists because a long list of modules is hard to scan, while the
5241
+ * pages inside a module are ordered on purpose. Returns the input untouched when not sorting.
5242
+ */
5243
+ function sortNavItems(items, alphabetically) {
5244
+ if (!alphabetically)
5245
+ return items;
5246
+ return [...items].sort((first, second) => first.label.localeCompare(second.label));
5247
+ }
5248
+
5249
+ 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"};
5250
+
5251
+ const SKELETON_ROW_COUNT = 5;
5252
+ const defaultRenderLink = (item, children) => (jsx("a", { href: item.href, children: children }));
5253
+ /** Sizes only its own icons — content injected via `renderLink` is styled by the consumer. */
5254
+ function CwNavMenu({ items, loading = false, isActive, renderLink = defaultRenderLink, showExpandIndicator = false, search, emptyMessage, sortAlphabetically = false, favoritesSlot, favoritesLabel = "Favorites", favoritesProps, isFavorite, beforeTreeSlot, className, ...navProps }) {
5255
+ const visibleItems = sortNavItems(filterNavItems(items, search), sortAlphabetically);
5256
+ const showEmptyMessage = !loading && Boolean(emptyMessage) && Boolean(search?.trim()) && visibleItems.length === 0;
5257
+ const hasActiveDescendant = (node) => node.children?.some(child => isActive?.(child) || hasActiveDescendant(child)) ?? false;
5258
+ const renderItem = (item, level) => {
5259
+ const children = item.children;
5260
+ if (children && children.length > 0) {
5261
+ return (jsx("li", { children: jsxs("details", { "data-level": level, open: hasActiveDescendant(item) || undefined, children: [jsxs("summary", { children: [item.icon && jsx(CwIcon, { iconId: item.icon, size: level >= 2 ? "small" : "medium" }), item.label, (showExpandIndicator || level >= 2) && (jsx(CwIcon, { iconId: "chevron-down", size: "small", className: styles$8.expandIndicator }))] }), jsx("ul", { children: children.map(child => renderItem(child, level + 1)) })] }) }, item.id));
5262
+ }
5263
+ return (jsx("li", { "data-active": isActive?.(item) ? "true" : undefined, children: renderLink(item, jsxs(Fragment, { children: [item.icon && jsx(CwIcon, { iconId: item.icon, size: "medium" }), item.label, isFavorite?.(item) && jsx(CwIcon, { iconId: "star", size: "small", className: styles$8.favoriteStar })] })) }, item.id));
5264
+ };
5265
+ return (jsxs("nav", { ...navProps, className: [styles$8.menu, className].filter(Boolean).join(" "), "aria-busy": loading || undefined, children: [favoritesSlot && (jsxs("details", { open: true, ...favoritesProps, className: [styles$8.favorites, favoritesProps?.className].filter(Boolean).join(" "), children: [jsxs("summary", { children: [jsx(CwIcon, { iconId: "star", size: "medium" }), favoritesLabel] }), jsx("div", { className: styles$8.favoritesContent, children: favoritesSlot })] })), beforeTreeSlot, jsx("ul", { children: loading
5266
+ ? Array.from({ length: SKELETON_ROW_COUNT }, (_unused, index) => (jsx("li", { className: styles$8.skeleton, children: jsx(CwSkeleton, { height: "var(--cw-size-small)", radius: "var(--cw-border-radius-small)" }) }, index)))
5267
+ : visibleItems.map(item => renderItem(item, 1)) }), showEmptyMessage && jsx("p", { className: styles$8.emptyMessage, children: emptyMessage })] }));
5268
+ }
5269
+
5270
+ /**
5271
+ * Pure keyboard-navigation resolver shared by the `CwSearchInput` combobox.
5272
+ * Kept side-effect-free so the arrow/home/end/enter/escape behaviour can be unit
5273
+ * tested without a DOM (the library's vitest runs with `environment: "node"`).
5274
+ */
5275
+ /**
5276
+ * Resolves a key press against the current highlight into a {@link SearchKeyAction}.
5277
+ * Arrow navigation wraps around; `Enter` selects only when a valid row is highlighted.
5278
+ *
5279
+ * @param key `KeyboardEvent.key` value.
5280
+ * @param currentIndex Currently highlighted option index (`-1` = none).
5281
+ * @param optionsLength Number of options currently in the dropdown.
5282
+ */
5283
+ function resolveSearchKeyAction(key, currentIndex, optionsLength) {
5284
+ if (optionsLength <= 0)
5285
+ return { type: "none" };
5286
+ switch (key) {
5287
+ case "ArrowDown":
5288
+ return { type: "move", index: currentIndex < optionsLength - 1 ? currentIndex + 1 : 0 };
5289
+ case "ArrowUp":
5290
+ return { type: "move", index: currentIndex > 0 ? currentIndex - 1 : optionsLength - 1 };
5291
+ case "Home":
5292
+ return { type: "move", index: 0 };
5293
+ case "End":
5294
+ return { type: "move", index: optionsLength - 1 };
5295
+ case "Enter":
5296
+ return currentIndex >= 0 && currentIndex < optionsLength
5297
+ ? { type: "select", index: currentIndex }
5298
+ : { type: "none" };
5299
+ case "Escape":
5300
+ return { type: "close" };
5301
+ default:
5302
+ return { type: "none" };
5303
+ }
5037
5304
  }
5038
5305
 
5039
5306
  /**
@@ -5054,14 +5321,19 @@ function CwSearchInput(optionsProps) {
5054
5321
  const [_selectedOption, setSelectedOption] = useState(null);
5055
5322
  const [showDropdown, setShowDropdown] = useState(false);
5056
5323
  const [isLoading, setIsLoading] = useState(false);
5324
+ const [highlightedIndex, setHighlightedIndex] = useState(-1);
5057
5325
  const wrapperRef = useRef(null);
5326
+ const inputRef = useRef(null);
5327
+ // Stable ids wiring the combobox input to its listbox popup for assistive tech.
5328
+ const listboxId = useId();
5329
+ const optionId = (index) => `${listboxId}-opt-${index}`;
5058
5330
  const { panelRef, panelStyle, renderPanel } = useDropdownPortal({
5059
5331
  anchorRef: wrapperRef,
5060
5332
  isOpen: showDropdown && filteredOptions.length > 0,
5061
- onClose: () => setShowDropdown(false),
5333
+ onClose: () => { setShowDropdown(false); setHighlightedIndex(-1); },
5062
5334
  });
5063
5335
  // Extract props
5064
- const { labelProps, iconProps, alignProps, selectList, handleChange, placeholder = "Search…", disabled, renderOption, style, id, className, defaultValue, ...otherProps } = optionsProps;
5336
+ const { labelProps, iconProps, alignProps, selectList, handleChange, placeholder = "Search…", disabled, renderOption, style, id, className, defaultValue, autoFocus, ...otherProps } = optionsProps;
5065
5337
  // Get direction for data attribute
5066
5338
  const direction = alignProps?.flexDirection || "row";
5067
5339
  // Make default value selection when loading the component
@@ -5080,9 +5352,10 @@ function CwSearchInput(optionsProps) {
5080
5352
  }
5081
5353
  }, [defaultValue, selectList]);
5082
5354
  const handleInputChange = (event) => {
5083
- const text = event.target.value;
5355
+ const text = event.currentTarget.value;
5084
5356
  setSearchText(text);
5085
5357
  setShowDropdown(true);
5358
+ setHighlightedIndex(-1);
5086
5359
  if (text === "") {
5087
5360
  setFilteredOptions(selectList);
5088
5361
  setSelectedOption(null);
@@ -5105,10 +5378,30 @@ function CwSearchInput(optionsProps) {
5105
5378
  };
5106
5379
  const handleInputFocus = () => {
5107
5380
  setShowDropdown(true);
5381
+ setHighlightedIndex(-1);
5108
5382
  if (searchText === "") {
5109
5383
  setFilteredOptions(selectList);
5110
5384
  }
5111
5385
  };
5386
+ const handleKeyDown = (event) => {
5387
+ if (!(showDropdown && filteredOptions.length > 0))
5388
+ return;
5389
+ const action = resolveSearchKeyAction(event.key, highlightedIndex, filteredOptions.length);
5390
+ switch (action.type) {
5391
+ case "move":
5392
+ event.preventDefault();
5393
+ setHighlightedIndex(action.index);
5394
+ break;
5395
+ case "select":
5396
+ event.preventDefault();
5397
+ handleOptionSelect(filteredOptions[action.index]);
5398
+ break;
5399
+ case "close":
5400
+ setShowDropdown(false);
5401
+ setHighlightedIndex(-1);
5402
+ break;
5403
+ }
5404
+ };
5112
5405
  const handleInputBlur = () => {
5113
5406
  // Dropdown is closed by useDropdownPortal's outside-click handler.
5114
5407
  // Blur alone must not close it — clicking an option would lose focus before the click fires.
@@ -5120,16 +5413,19 @@ function CwSearchInput(optionsProps) {
5120
5413
  handleChange(option.id);
5121
5414
  }
5122
5415
  setFilteredOptions([]);
5416
+ setHighlightedIndex(-1);
5123
5417
  };
5124
5418
  const handleClearClick = () => {
5125
5419
  setSearchText("");
5126
5420
  setFilteredOptions([]);
5127
5421
  setSelectedOption(null);
5422
+ setHighlightedIndex(-1);
5128
5423
  if (handleChange) {
5129
5424
  handleChange("");
5130
5425
  }
5426
+ inputRef.current?.focus();
5131
5427
  };
5132
- return (jsxs("div", { className: `cw-search-input ${className || ""}`, style: style, id: id, ...otherProps, "data-direction": direction, children: [jsxs(CwAlign, { ...alignProps, children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxs("div", { className: "cw-search-input-wrapper", ref: wrapperRef, children: [jsx("input", { type: "text", value: searchText, onChange: handleInputChange, onFocus: handleInputFocus, onBlur: handleInputBlur, placeholder: placeholder, className: "cw-input-search", disabled: disabled }), isLoading && (jsx("div", { className: "cw-search-input-loading", children: jsx(CwIcon, { iconId: "spinner" }) })), jsx("div", { className: "cw-search-input-icons", children: searchText && !disabled && !isLoading ? (jsx(CwButton, { type: "button", onClick: handleClearClick, "aria-label": "Clear search", variant: "icon", icon: "close", color: "neutral" })) : (iconProps ? jsx(CwIcon, { ...iconProps }) : jsx(CwIcon, { iconId: "search" })) })] })] }), renderPanel(jsx("div", { ref: panelRef, className: dropdownStyles.dropdown, style: panelStyle, children: jsx("ul", { children: filteredOptions.map((option) => (jsx("li", { className: dropdownStyles.option, onClick: () => handleOptionSelect(option), onMouseDown: (e) => e.preventDefault(), children: renderOption ? renderOption(option) : option.description }, option.id))) }) }))] }));
5428
+ return (jsxs("div", { className: `cw-search-input ${className || ""}`, style: style, ...otherProps, "data-direction": direction, children: [jsxs(CwAlign, { ...alignProps, children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxs("div", { className: "cw-search-input-wrapper", ref: wrapperRef, children: [jsx("input", { ref: inputRef, id: id, type: "text", value: searchText, onChange: handleInputChange, onKeyDown: handleKeyDown, onFocus: handleInputFocus, onBlur: handleInputBlur, placeholder: placeholder, className: "cw-input-search", disabled: disabled, autoFocus: autoFocus, autoComplete: "off", role: "combobox", "aria-haspopup": "listbox", "aria-expanded": showDropdown && filteredOptions.length > 0, "aria-controls": listboxId, "aria-activedescendant": highlightedIndex >= 0 ? optionId(highlightedIndex) : undefined }), isLoading && (jsx("div", { className: "cw-search-input-loading", children: jsx(CwIcon, { iconId: "spinner" }) })), jsx("div", { className: "cw-search-input-icons", children: searchText && !disabled && !isLoading ? (jsx(CwButton, { type: "button", onClick: handleClearClick, "aria-label": "Clear search", variant: "icon", icon: "close", color: "neutral" })) : (iconProps ? jsx(CwIcon, { ...iconProps }) : jsx(CwIcon, { iconId: "search" })) })] })] }), renderPanel(jsx("div", { ref: panelRef, id: listboxId, className: dropdownStyles.dropdown, style: panelStyle, role: "listbox", children: jsx("ul", { children: filteredOptions.map((option, index) => (jsx("li", { id: optionId(index), className: `${dropdownStyles.option}${index === highlightedIndex ? ` ${dropdownStyles.optionFocused}` : ""}`, onClick: () => handleOptionSelect(option), onMouseDown: (e) => e.preventDefault(), onMouseEnter: () => setHighlightedIndex(index), role: "option", "aria-selected": index === highlightedIndex, children: renderOption ? renderOption(option) : option.description }, option.id))) }) }))] }));
5133
5429
  }
5134
5430
 
5135
5431
  /**
@@ -11292,4 +11588,4 @@ const CwFindCrewmember = ({ handleChange, placeHolder = "Search crew…", requir
11292
11588
  }, "data-direction": direction, children: [jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxs("div", { className: "cw-search-input-wrapper", ref: wrapperRef, children: [jsx("input", { ref: inputRef, type: "text", value: inputValue, onChange: handleInputChange, onKeyDown: handleKeyDown, onFocus: handleInputFocus, placeholder: isInitialLoading ? "Loading…" : placeHolder, disabled: disabled, required: required, autoComplete: "off", "aria-expanded": showDropdown, "aria-haspopup": "listbox", role: "combobox", title: tooltipText }), (isLoading || isInitialLoading) && (jsx("div", { className: "cw-search-input-loading", children: jsx(CwIcon, { iconId: "spinner" }) })), jsx("div", { className: "cw-search-input-icons", children: inputValue && !disabled && !isInitialLoading ? (jsx(CwButton, { type: "button", onClick: handleClear, "aria-label": "Clear selected crewmember", variant: "icon", icon: "close", color: "neutral" })) : (jsx(CwIcon, { iconId: "person" })) })] })] }), renderPanel(jsx("div", { ref: panelRef, className: dropdownStyles.dropdown, style: panelStyle, role: "listbox", children: jsx("ul", { children: options.map((option, index) => (jsx("li", { className: `${dropdownStyles.option}${index === highlightedIndex ? ` ${dropdownStyles.optionFocused}` : ""}`, onClick: () => handleOptionSelect(option.value), onMouseDown: (e) => e.preventDefault(), onMouseEnter: () => setHighlightedIndex(index), role: "option", "aria-selected": index === highlightedIndex, children: option.text }, option.value))) }) }))] }));
11293
11589
  };
11294
11590
 
11295
- export { CblDragAndDrop, CwAccordionContainer, CwAlign, CwAnchoredMenu, CwBtnApprove, CwBtnCancel, CwBtnDelete, CwBtnEdit, CwBtnSave, CwButton, CwButtonSplit, CwButtonSwitch, CwCard, CwCardList, CwCheck, CwCheckbox, CwCheckboxGroup, CwChip, CwColorPicker, CwConfirmationPopup, CwContextMenu, CwDatePicker, CwDatePickerTemporal, CwDateRangePicker, CwDateRangePickerTemporal, CwDateTimePicker, CwDateTimePickerCompact, CwDateTimePickerTemporal, CwDialog, CwDigit, CwDisplayMessage, CwDropdown, CwDropdownFilter, CwExpandable, CwFileUpload, CwFileUploadMultiple, CwFindAirport, CwFindCrewmember, CwGenericTooltip, CwHeadingMain, CwHeadingSecond, CwIcon, CwImageArea, CwImageGallery, CwImageZoom, CwInput, CwInputColor, CwInputDateText, CwInputDatetime, CwInputImage, CwInputNumber, CwInputPhone, CwInputText, CwKeyValueList, CwLabel, CwLoading, CwLoadingSmall, CwMasterDetail, CwMessage, CwMessageManager, CwMessageType, CwModal, CwModalHover, CwModalReportFunctional, CwMultiFilter, CwMultiFilterTag, CwNote, CwOption, CwPopoverButton, CwRadioGroup, CwReportModal, CwScheduler, CwSearchAsync, CwSearchInput, CwSelect, CwSelectList, CwSelectListItems, CwSortableList, CwSortableTable, CwSuperScheduler, CwTable, CwTableGrouped, CwTableServerSide, CwTabs, CwTagSelector, CwTextArea, CwTime, CwTimePicker, CwToggle, CwTooltipManager, CwTooltipNew, CwTreeView, CwWeekdaySelector, DefaultRowHeader, OnClearPinned, OnClickContextMenu, OnClickEvent, OnClickRowEvent, OnClickRowHeader, OnClickUtc, OnDoubleClickEvent, OnDoubleClickRowEvent, OnDragEvent, OnDropCtrlEvent, OnDropEvent, OnEndClickHeaderEvent, OnLeftDragStart, OnMultiClickEvent, OnPinRow, OnRangeClickEvent, OnRightClickEvent, OnRightClickRow, OnRightDragStart, OnStartClickHeaderEvent, OnUnpinRow, PRESET_LIBRARY_TEMPORAL, PinRowHeader, Resource, Scheduler, SchedulerEvent, SuperScheduler, TooltipConstraintContext, UiEvent, Weekdays, cblEvent, eventIsVisible, filterVisibleEvents, getDefaultDivisions, getEventSizes, getPresetsByKeysTemporal, itemsToMultiFilterTags, useCwMessage, useSortableList, useSortableTable, useTooltipConstraint };
11591
+ export { CblDragAndDrop, CwAccordionContainer, CwAlign, CwAnchoredMenu, CwBtnApprove, CwBtnCancel, CwBtnDelete, CwBtnEdit, CwBtnSave, CwButton, CwButtonSplit, CwButtonSwitch, CwCard, CwCardList, CwCheck, CwCheckbox, CwCheckboxGroup, CwChip, CwColorPicker, CwConfirmationPopup, CwContextMenu, CwDatePicker, CwDatePickerTemporal, CwDateRangePicker, CwDateRangePickerTemporal, CwDateTimePicker, CwDateTimePickerCompact, CwDateTimePickerTemporal, CwDialog, CwDigit, CwDisplayMessage, CwDropdown, CwDropdownFilter, CwExpandable, CwFileUploadMultiple, CwFindAirport, CwFindCrewmember, CwGenericTooltip, CwHeadingMain, CwHeadingSecond, CwIcon, CwImageArea, CwImageGallery, CwImageZoom, CwInput, CwInputColor, CwInputDateText, CwInputDatetime, CwInputImage, CwInputNumber, CwInputPhone, CwInputText, CwKeyValueList, CwLabel, CwLoading, CwMasterDetail, CwMessage, CwMessageManager, CwMessageType, CwModal, CwModalHover, CwModalReportFunctional, CwMultiFilter, CwMultiFilterTag, CwNavMenu, CwNote, CwOption, CwPopoverButton, CwProgress, CwRadioGroup, CwReportModal, CwScheduler, CwSearchAsync, CwSearchInput, CwSelect, CwSelectList, CwSelectListItems, CwSkeleton, CwSortableList, CwSortableTable, CwSuperScheduler, CwTable, CwTableGrouped, CwTableServerSide, CwTabs, CwTagSelector, CwTextArea, CwTime, CwTimePicker, CwToggle, CwTooltipManager, CwTooltipNew, CwTreeView, CwWeekdaySelector, DefaultRowHeader, OnClearPinned, OnClickContextMenu, OnClickEvent, OnClickRowEvent, OnClickRowHeader, OnClickUtc, OnDoubleClickEvent, OnDoubleClickRowEvent, OnDragEvent, OnDropCtrlEvent, OnDropEvent, OnEndClickHeaderEvent, OnLeftDragStart, OnMultiClickEvent, OnPinRow, OnRangeClickEvent, OnRightClickEvent, OnRightClickRow, OnRightDragStart, OnStartClickHeaderEvent, OnUnpinRow, PRESET_LIBRARY_TEMPORAL, PinRowHeader, Resource, Scheduler, SchedulerEvent, SuperScheduler, TooltipConstraintContext, UiEvent, Weekdays, cblEvent, configureCwLoading, eventIsVisible, filterNavItems, filterVisibleEvents, getCwLoadingDefaults, getDefaultDivisions, getEventSizes, getPresetsByKeysTemporal, itemsToMultiFilterTags, sortNavItems, useCwMessage, useSortableList, useSortableTable, useTooltipConstraint };