@rio-cloud/rio-uikit 2.0.1 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (202) hide show
  1. package/components/actionBarItem/ActionBarItem.d.ts +2 -2
  2. package/components/actionBarItem/ActionBarItem.js.map +1 -1
  3. package/components/applicationHeader/ApplicationHeader.d.ts +6 -7
  4. package/components/applicationHeader/ApplicationHeader.js.map +1 -1
  5. package/components/applicationLayout/SubNavigation.d.ts +7 -0
  6. package/components/applicationLayout/SubNavigation.js.map +1 -1
  7. package/components/assetTree/AssetTree.d.ts +7 -0
  8. package/components/assetTree/AssetTree.js.map +1 -1
  9. package/components/assetTree/Tree.d.ts +15 -0
  10. package/components/assetTree/Tree.js.map +1 -1
  11. package/components/assetTree/TreeIcon.d.ts +30 -0
  12. package/components/assetTree/TreeIcon.js +16 -0
  13. package/components/assetTree/TreeIcon.js.map +1 -0
  14. package/components/assetTree/TreeLeaf.js +22 -22
  15. package/components/assetTree/TreeLeaf.js.map +1 -1
  16. package/components/assetTree/TreeNode.js +25 -25
  17. package/components/assetTree/TreeNode.js.map +1 -1
  18. package/components/assetTree/TreeSearch.d.ts +2 -0
  19. package/components/assetTree/TreeSearch.js.map +1 -1
  20. package/components/barList/BarList.d.ts +26 -0
  21. package/components/barList/BarList.js.map +1 -1
  22. package/components/bottomSheet/BottomSheet.d.ts +17 -3
  23. package/components/bottomSheet/BottomSheet.js.map +1 -1
  24. package/components/bottomSheet/TimedBottomSheet.d.ts +10 -0
  25. package/components/bottomSheet/TimedBottomSheet.js.map +1 -1
  26. package/components/calendarStripe/CalendarStripe.d.ts +1 -1
  27. package/components/calendarStripe/CalendarStripe.js +34 -36
  28. package/components/calendarStripe/CalendarStripe.js.map +1 -1
  29. package/components/charts/Area.d.ts +2 -2
  30. package/components/charts/Area.js.map +1 -1
  31. package/components/charts/Line.d.ts +2 -2
  32. package/components/charts/Line.js.map +1 -1
  33. package/components/checkbox/Checkbox.d.ts +0 -3
  34. package/components/checkbox/Checkbox.js.map +1 -1
  35. package/components/clearableInput/ClearableInput.d.ts +21 -20
  36. package/components/clearableInput/ClearableInput.js.map +1 -1
  37. package/components/collapse/Collapse.d.ts +3 -0
  38. package/components/collapse/Collapse.js +12 -12
  39. package/components/collapse/Collapse.js.map +1 -1
  40. package/components/contentLoader/ContentLoader.d.ts +10 -2
  41. package/components/contentLoader/ContentLoader.js.map +1 -1
  42. package/components/dataTabs/DataTabs.d.ts +6 -0
  43. package/components/dataTabs/DataTabs.js.map +1 -1
  44. package/components/dialog/ConfirmationDialog.d.ts +22 -0
  45. package/components/dialog/ConfirmationDialog.js.map +1 -1
  46. package/components/dialog/Dialog.d.ts +13 -1
  47. package/components/dialog/Dialog.js.map +1 -1
  48. package/components/dialog/ReleaseNotesDialog.d.ts +3 -3
  49. package/components/dialog/ReleaseNotesDialog.js.map +1 -1
  50. package/components/dropdown/ButtonDropdown.d.ts +4 -0
  51. package/components/dropdown/ButtonDropdown.js +51 -51
  52. package/components/dropdown/ButtonDropdown.js.map +1 -1
  53. package/components/dropdown/DropdownSubmenu.d.ts +4 -0
  54. package/components/dropdown/DropdownSubmenu.js.map +1 -1
  55. package/components/editableContent/EditableContent.d.ts +6 -0
  56. package/components/editableContent/EditableContent.js.map +1 -1
  57. package/components/expander/ExpanderList.d.ts +3 -0
  58. package/components/expander/ExpanderList.js.map +1 -1
  59. package/components/expander/ExpanderPanel.d.ts +14 -4
  60. package/components/expander/ExpanderPanel.js.map +1 -1
  61. package/components/fade/Fade.d.ts +1 -1
  62. package/components/fade/Fade.js.map +1 -1
  63. package/components/filepicker/FilePicker.d.ts +0 -2
  64. package/components/filepicker/FilePicker.js.map +1 -1
  65. package/components/groupedItemList/GroupedItemList.d.ts +10 -7
  66. package/components/groupedItemList/GroupedItemList.js.map +1 -1
  67. package/components/listMenu/ListMenu.js.map +1 -1
  68. package/components/listMenu/ListMenuGroup.d.ts +2 -1
  69. package/components/listMenu/ListMenuGroup.js.map +1 -1
  70. package/components/map/components/Map.js.map +1 -1
  71. package/components/map/components/constants.js.map +1 -1
  72. package/components/map/components/features/ContextMenuItem.d.ts +1 -1
  73. package/components/map/components/features/ContextMenuItem.js +2 -17
  74. package/components/map/components/features/ContextMenuItem.js.map +1 -1
  75. package/components/map/components/features/basics/Polyline.d.ts +4 -1
  76. package/components/map/components/features/basics/Polyline.js +1 -1
  77. package/components/map/components/features/basics/Polyline.js.map +1 -1
  78. package/components/map/components/features/layers/MarkerLayer.d.ts +3 -1
  79. package/components/map/components/features/layers/MarkerLayer.js.map +1 -1
  80. package/components/map/components/features/layers/clustering/ClusterLayer.js +1 -1
  81. package/components/map/components/features/layers/clustering/ClusterLayer.js.map +1 -1
  82. package/components/map/components/features/layers/clustering/SimpleClusterLayer.d.ts +3 -2
  83. package/components/map/components/features/layers/clustering/SimpleClusterLayer.js.map +1 -1
  84. package/components/map/components/features/layers/overlayLayers/RoadRestrictionLayer.js +7 -7
  85. package/components/map/components/features/layers/overlayLayers/RoadRestrictionLayer.js.map +1 -1
  86. package/components/map/components/features/layers/overlayLayers/TrafficLayer.js +4 -4
  87. package/components/map/components/features/layers/overlayLayers/TrafficLayer.js.map +1 -1
  88. package/components/map/utils/clustering.d.ts +6 -1
  89. package/components/map/utils/clustering.js +25 -19
  90. package/components/map/utils/clustering.js.map +1 -1
  91. package/components/map/utils/rendering.d.ts +1 -1
  92. package/components/map/utils/rendering.js +23 -23
  93. package/components/map/utils/rendering.js.map +1 -1
  94. package/components/menuItems/MenuItem.d.ts +23 -0
  95. package/components/menuItems/MenuItem.js.map +1 -1
  96. package/components/notification/Notification.js +4 -4
  97. package/components/notification/Notification.js.map +1 -1
  98. package/components/onboarding/OnboardingTip.d.ts +18 -12
  99. package/components/onboarding/OnboardingTip.js.map +1 -1
  100. package/components/overlay/OverlayTrigger.d.ts +43 -1
  101. package/components/overlay/OverlayTrigger.js.map +1 -1
  102. package/components/pager/Pager.d.ts +3 -0
  103. package/components/pager/Pager.js.map +1 -1
  104. package/components/popover/Popover.d.ts +1 -0
  105. package/components/popover/Popover.js.map +1 -1
  106. package/components/preloader/ImagePreloader.d.ts +1 -1
  107. package/components/preloader/ImagePreloader.js.map +1 -1
  108. package/components/radiobutton/RadioButton.d.ts +9 -5
  109. package/components/radiobutton/RadioButton.js.map +1 -1
  110. package/components/releaseNotes/ReleaseNotes.d.ts +0 -3
  111. package/components/releaseNotes/ReleaseNotes.js.map +1 -1
  112. package/components/resizer/Resizer.d.ts +17 -3
  113. package/components/resizer/Resizer.js.map +1 -1
  114. package/components/rioglyph/Rioglyph.d.ts +20 -8
  115. package/components/rioglyph/Rioglyph.js.map +1 -1
  116. package/components/rules/RulesWrapper.js +1 -1
  117. package/components/rules/RulesWrapper.js.map +1 -1
  118. package/components/saveableInput/SaveableDateInput.d.ts +20 -2
  119. package/components/saveableInput/SaveableDateInput.js.map +1 -1
  120. package/components/saveableInput/SaveableInput.d.ts +10 -2
  121. package/components/saveableInput/SaveableInput.js.map +1 -1
  122. package/components/selects/BaseSelectDropdown.js +90 -79
  123. package/components/selects/BaseSelectDropdown.js.map +1 -1
  124. package/components/selects/Select.d.ts +5 -0
  125. package/components/selects/Select.js +94 -94
  126. package/components/selects/Select.js.map +1 -1
  127. package/components/sidebars/Sidebar.d.ts +19 -3
  128. package/components/sidebars/Sidebar.js.map +1 -1
  129. package/components/slider/RangeSlider.d.ts +15 -0
  130. package/components/slider/RangeSlider.js.map +1 -1
  131. package/components/slider/Slider.d.ts +9 -0
  132. package/components/slider/Slider.js.map +1 -1
  133. package/components/smoothScrollbars/SmoothScrollbars.d.ts +44 -0
  134. package/components/smoothScrollbars/SmoothScrollbars.js.map +1 -1
  135. package/components/spinner/Spinner.d.ts +3 -3
  136. package/components/spinner/Spinner.js.map +1 -1
  137. package/components/states/BaseStateProps.d.ts +6 -2
  138. package/components/states/StateIcon.d.ts +14 -1
  139. package/components/states/StateIcon.js.map +1 -1
  140. package/components/statsWidget/StatsWidget.d.ts +2 -0
  141. package/components/statsWidget/StatsWidget.js.map +1 -1
  142. package/components/statsWidget/StatsWidgetBody.d.ts +1 -0
  143. package/components/statsWidget/StatsWidgetBody.js.map +1 -1
  144. package/components/statsWidget/StatsWidgetNumber.d.ts +2 -0
  145. package/components/statsWidget/StatsWidgetNumber.js.map +1 -1
  146. package/components/statusBar/StatusBar.d.ts +2 -31
  147. package/components/statusBar/StatusBar.js.map +1 -1
  148. package/components/statusBar/StatusBarIcon.d.ts +2 -2
  149. package/components/statusBar/StatusBarIcon.js.map +1 -1
  150. package/components/statusBar/StatusBarLabel.d.ts +2 -2
  151. package/components/statusBar/StatusBarLabel.js.map +1 -1
  152. package/components/statusBar/StatusBarProgressBar.d.ts +1 -1
  153. package/components/statusBar/StatusBarProgressBar.js.map +1 -1
  154. package/components/statusBar/{StatusBar.types.d.ts → StatusBarProps.d.ts} +44 -2
  155. package/components/steppedProgressBar/SteppedProgressBar.d.ts +1 -1
  156. package/components/steppedProgressBar/SteppedProgressBar.js.map +1 -1
  157. package/components/switch/Switch.d.ts +13 -1
  158. package/components/switch/Switch.js.map +1 -1
  159. package/components/table/SortArrowDown.d.ts +1 -1
  160. package/components/table/SortArrowDown.js.map +1 -1
  161. package/components/table/SortArrowUp.d.ts +1 -1
  162. package/components/table/SortArrowUp.js.map +1 -1
  163. package/components/table/TableSettingsDialog.d.ts +5 -0
  164. package/components/table/TableSettingsDialog.js +119 -109
  165. package/components/table/TableSettingsDialog.js.map +1 -1
  166. package/components/table/TableSettingsDialogFooter.js +9 -9
  167. package/components/table/TableSettingsDialogFooter.js.map +1 -1
  168. package/components/table/TableViewToggles.d.ts +21 -1
  169. package/components/table/TableViewToggles.js.map +1 -1
  170. package/components/tag/Tag.d.ts +7 -2
  171. package/components/tag/Tag.js.map +1 -1
  172. package/components/tagManager/TagManager.d.ts +15 -0
  173. package/components/tagManager/TagManager.js.map +1 -1
  174. package/components/tagManager/TagManagerTag.d.ts +9 -0
  175. package/components/teaser/Teaser.d.ts +57 -55
  176. package/components/teaser/Teaser.js.map +1 -1
  177. package/components/teaser/TeaserContainer.d.ts +1 -1
  178. package/components/teaser/TeaserContainer.js.map +1 -1
  179. package/components/tooltip/SimpleTooltip.d.ts +22 -4
  180. package/components/tooltip/SimpleTooltip.js.map +1 -1
  181. package/components/tooltip/Tooltip.d.ts +22 -2
  182. package/components/tooltip/Tooltip.js.map +1 -1
  183. package/components/video/ResponsiveVideo.d.ts +8 -3
  184. package/components/video/ResponsiveVideo.js.map +1 -1
  185. package/hooks/useKey.d.ts +1 -1
  186. package/hooks/useKey.js.map +1 -1
  187. package/hooks/useOnboarding.d.ts +86 -80
  188. package/hooks/useOnboarding.js.map +1 -1
  189. package/hooks/useTableExport.js.map +1 -1
  190. package/hooks/useUncontrollable.d.ts +1 -1
  191. package/hooks/useUncontrollable.js.map +1 -1
  192. package/package.json +12 -14
  193. package/utils/colorScheme.js +14 -13
  194. package/utils/colorScheme.js.map +1 -1
  195. package/utils/cssuseragent.js.map +1 -1
  196. package/utils/scrollItemIntoView.js +12 -11
  197. package/utils/scrollItemIntoView.js.map +1 -1
  198. package/utils/urlFeatureToggles.js +19 -20
  199. package/utils/urlFeatureToggles.js.map +1 -1
  200. package/version.d.ts +1 -1
  201. package/version.js +1 -1
  202. package/version.js.map +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"Dialog.js","sources":["../../../src/components/dialog/Dialog.tsx"],"sourcesContent":["import React, { useState, useRef, type PropsWithChildren } from 'react';\nimport ReactDOM from 'react-dom';\nimport classNames from 'classnames';\nimport { noop } from 'es-toolkit/function';\nimport { AnimatePresence, type AnimationDefinition, motion, type Transition, useReducedMotion } from 'motion/react';\n\nimport { getOrCreatePortalRoot } from '../../utils/portalRoot';\nimport useEsc from '../../hooks/useEsc';\nimport DialogHeader from './DialogHeader';\nimport DialogBody from './DialogBody';\nimport DialogFooter from './DialogFooter';\nimport useFocusTrap from '../../hooks/useFocusTrap';\nimport { DialogContextProvider } from './dialogContext';\n\nconst MODAL_DIALOG_CLASS = 'modal-dialog';\nconst MODAL_OPEN_CLASS = 'modal-open';\n\nexport type DialogSize =\n | 'xs'\n | 'sm'\n | 'md'\n | 'lg'\n | 'xl'\n | 'full'\n | 'fullwidth'\n | 'fullheight'\n | 'fullheight-lg'\n | 'fullheight-xl'\n | 'fullscreen';\n\nexport type BaseDialogProps = {\n /**\n * Opens the dialog when set to `true`.\n *\n * @default false\n */\n show: boolean;\n\n /**\n * The dialog title (can also be a FormattedMessage component).\n */\n title?: React.ReactNode;\n\n /**\n * The dialog header subtitle content.\n */\n subtitle?: React.ReactNode;\n\n /**\n * Shows a close button when set to `true`.\n *\n * @default true\n */\n showCloseButton?: boolean;\n\n /**\n * A callback function invoked when the dialog closes.\n */\n onClose?: () => void;\n\n /**\n * Defined how large the dialog will be rendered.\n *\n * By default, the dialog has a medium size, and thus it can be omitted.\n *\n * Possible values are: `xs`, `sm`, `lg` `xl` `fullwidth` `fullheight` 'fullheight-lg' 'fullheight-xl' `fullscreen`\n *\n * @default 'md'\n */\n bsSize?: DialogSize;\n\n /**\n * Enables or disabled closing the dialog via esc key.\n *\n * @default false\n */\n disableEsc?: boolean;\n\n /**\n * Enables the modal body to overflow and use inline scrolling if needed.\n *\n * @default false\n */\n useOverflow?: boolean;\n\n /**\n * Show Header and Footer Borders for the \"xs\" dialog\n *\n * @default false\n */\n showXsDialogBorders?: boolean;\n\n /**\n * Additional classes for the modal element.\n */\n className?: string;\n};\n\nexport type DialogProps = BaseDialogProps & {\n /**\n * The dialog body content.\n */\n body?: React.ReactNode;\n\n /**\n * The dialog body content.\n */\n footer?: React.ReactNode;\n\n /**\n * Additional classes for the modal-body element.\n */\n bodyClassName?: string;\n\n /**\n * Additional classes for the modal-footer element.\n */\n footerClassName?: string;\n\n /**\n * Allows to add additional buttons to the dialog header.\n */\n headerButtons?: React.ReactNode;\n\n /**\n * A callback fired when esc key is pressed and the dialog is about to close.\n */\n onEsc?: VoidFunction;\n\n /**\n * A callback function to be executed before closing the dialog.\n *\n * If the function returns `false`, the dialog will not be closed\n */\n onCloseValidation?: () => boolean;\n};\n\nconst Dialog = (props: PropsWithChildren<DialogProps>) => {\n const {\n title,\n subtitle,\n body,\n footer,\n headerButtons,\n className = '',\n bodyClassName,\n footerClassName,\n showXsDialogBorders = false,\n showCloseButton = true,\n useOverflow = false,\n bsSize,\n show = false,\n onClose: onCloseCallback = noop,\n disableEsc = false,\n onEsc = noop,\n onCloseValidation = () => true,\n children,\n ...remainingProps\n } = props;\n\n const [open, setOpen] = useState(show);\n const dialogWrapperRef = useRef<HTMLDivElement>(null);\n\n const modalRoot = getOrCreatePortalRoot();\n\n const shouldReduceMotion = useReducedMotion();\n\n // Use a setter function for the focus trap as it would not re-render\n // and fails to set the focus listener\n const [focusTrapRef, setFocusTrapRef] = useState<HTMLDivElement>();\n useFocusTrap(focusTrapRef);\n\n const toggleBodyClass = (add: boolean) => {\n // We need to set a body class to fix the -webkit-overflow-scrolling on safari and iOS\n\n // Remove \"modal-open\" from body only when there is no other dialog in the DOM\n // in order to support multiple dialogs\n const hasOtherDialogs = modalRoot.getElementsByClassName(MODAL_DIALOG_CLASS).length > 1;\n\n if (add) {\n document.body.classList.add(MODAL_OPEN_CLASS);\n } else if (!add && !hasOtherDialogs) {\n document.body.classList.remove(MODAL_OPEN_CLASS);\n }\n };\n\n const handleCloseButton = () => closeDialog(true);\n\n const closeDialog = (usedEscapeKey: boolean) => {\n if (onCloseValidation()) {\n setOpen(false);\n onCloseCallback();\n\n usedEscapeKey && onEsc();\n }\n };\n\n const [previousShow, setPreviousShow] = useState(show);\n if (show !== previousShow) {\n setOpen(show);\n toggleBodyClass(show);\n setPreviousShow(show);\n }\n\n useEsc(() => {\n if (!dialogWrapperRef || !dialogWrapperRef.current) {\n return;\n }\n\n const dialogElement = dialogWrapperRef.current;\n const currentActiveElement = document.activeElement;\n\n // Only allow to close the dialog when the focus is inside the dialog\n if (!disableEsc && dialogElement.contains(currentActiveElement)) {\n closeDialog(true);\n }\n });\n\n const handleAnimationComplete = (definition: AnimationDefinition) => {\n // The animation complete callback is invoked too when closing the dialog.\n // For that we check the animation props like the \"opacity\" to skip focusing\n // on the way out when closing the dialog.\n // @ts-ignore\n if (definition.opacity === 0) {\n return;\n }\n\n const dialogElement = dialogWrapperRef.current;\n const currentActiveElement = document.activeElement;\n\n // Set the focus to the dialog if no element inside has focus already. Otherwise, focused\n // elements like inputs would lose their focus to the dialog.\n // Note that in order to focus the dialog itself, the tabindex has to be set on that element\n // IMPORTANT: make sure the dialog has a tabIndex prop\n if (!dialogElement?.contains(currentActiveElement)) {\n dialogWrapperRef?.current?.focus();\n }\n };\n\n const modalClasses = classNames('modal', 'show', className);\n\n const isSmallestDialog = bsSize === 'xs';\n\n const hasChildren = !!children;\n\n const modalDialogClasses = classNames(\n MODAL_DIALOG_CLASS,\n useOverflow && 'modal-overflow',\n bsSize === 'xs' && 'modal-xs',\n bsSize === 'sm' && 'modal-sm',\n bsSize === 'lg' && 'modal-lg',\n bsSize === 'xl' && 'modal-xl',\n bsSize === 'full' && 'modal-full-width',\n bsSize === 'fullwidth' && 'modal-full-width',\n bsSize === 'fullheight' && 'modal-full-height',\n bsSize === 'fullheight-lg' && 'modal-full-height modal-lg',\n bsSize === 'fullheight-xl' && 'modal-full-height modal-xl',\n bsSize === 'fullscreen' && 'modal-fullscreen'\n );\n\n const spring: Transition = {\n type: 'spring',\n damping: 33,\n stiffness: 500,\n };\n\n const springXs: Transition = {\n type: 'spring',\n damping: 25,\n stiffness: 400,\n };\n\n return ReactDOM.createPortal(\n <DialogContextProvider\n value={{ onClose: handleCloseButton, isSmallestDialog, showXsDialogBorders, showCloseButton }}\n >\n {/* @ts-ignore-next-line */}\n <AnimatePresence\n // Disable any initial animations on children that\n // are present when the component is first rendered\n initial={false}\n // Only render one component at a time.\n // The exiting component will finish its exit\n // animation before entering component is rendered\n mode='wait'\n >\n {open && (\n <div\n {...remainingProps}\n className={modalClasses}\n role='dialog'\n ref={dialogWrapperRef}\n aria-label='dialog'\n // Make sure it has a tabIndex to focus the dialog so the close on esc works.\n // biome-ignore lint/a11y/noNoninteractiveTabindex: <explanation>\n tabIndex={0}\n >\n <motion.div\n initial={shouldReduceMotion ? false : { opacity: 0, y: '-50%' }}\n animate={\n shouldReduceMotion\n ? { opacity: 1 }\n : { opacity: 1, y: 0, transition: isSmallestDialog ? springXs : spring }\n }\n exit={shouldReduceMotion ? undefined : { opacity: 0, y: '-150%' }}\n transition={\n shouldReduceMotion\n ? { duration: 0 }\n : {\n opacity: { duration: 0.2 },\n y: { duration: 0.3 },\n }\n }\n onAnimationComplete={handleAnimationComplete}\n // @ts-ignore\n ref={setFocusTrapRef}\n className={modalDialogClasses}\n role='document'\n >\n <div className='modal-content'>\n {hasChildren && children}\n {!hasChildren && (\n <>\n {title && (\n <DialogHeader\n title={title}\n subtitle={subtitle}\n headerButtons={headerButtons}\n />\n )}\n {body && <DialogBody className={bodyClassName}>{body}</DialogBody>}\n {footer && <DialogFooter className={footerClassName}>{footer}</DialogFooter>}\n </>\n )}\n </div>\n </motion.div>\n <motion.div\n initial={shouldReduceMotion ? false : { opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={shouldReduceMotion ? undefined : { opacity: 0 }}\n transition={shouldReduceMotion ? { duration: 0 } : { duration: 0.1 }}\n className='modal-backdrop'\n />\n </div>\n )}\n </AnimatePresence>\n </DialogContextProvider>,\n modalRoot\n );\n};\n\nDialog.Title = DialogHeader;\nDialog.Body = DialogBody;\nDialog.Footer = DialogFooter;\n\nDialog.SIZE_XS = 'xs' as const;\nDialog.SIZE_SM = 'sm' as const;\nDialog.SIZE_MD = 'md' as const; // default\nDialog.SIZE_LG = 'lg' as const;\nDialog.SIZE_XL = 'xl' as const;\nDialog.SIZE_FULL = 'full' as const;\nDialog.SIZE_FULL_WIDTH = 'fullwidth' as const;\nDialog.SIZE_FULL_HEIGHT = 'fullheight' as const;\nDialog.SIZE_FULL_HEIGHT_LG = 'fullheight-lg' as const;\nDialog.SIZE_FULL_HEIGHT_XL = 'fullheight-xl' as const;\nDialog.SIZE_FULL_SCREEN = 'fullscreen' as const;\n\nexport default Dialog;\n"],"names":["MODAL_DIALOG_CLASS","MODAL_OPEN_CLASS","Dialog","props","title","subtitle","body","footer","headerButtons","className","bodyClassName","footerClassName","showXsDialogBorders","showCloseButton","useOverflow","bsSize","show","onCloseCallback","noop","disableEsc","onEsc","onCloseValidation","children","remainingProps","open","setOpen","useState","dialogWrapperRef","useRef","modalRoot","getOrCreatePortalRoot","shouldReduceMotion","useReducedMotion","focusTrapRef","setFocusTrapRef","useFocusTrap","toggleBodyClass","add","hasOtherDialogs","handleCloseButton","closeDialog","usedEscapeKey","previousShow","setPreviousShow","useEsc","dialogElement","currentActiveElement","handleAnimationComplete","definition","modalClasses","classNames","isSmallestDialog","hasChildren","modalDialogClasses","spring","springXs","ReactDOM","jsx","DialogContextProvider","AnimatePresence","jsxs","motion","Fragment","DialogHeader","DialogBody","DialogFooter"],"mappings":"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"}
1
+ {"version":3,"file":"Dialog.js","sources":["../../../src/components/dialog/Dialog.tsx"],"sourcesContent":["import React, { useState, useRef, type PropsWithChildren } from 'react';\nimport ReactDOM from 'react-dom';\nimport classNames from 'classnames';\nimport { noop } from 'es-toolkit/function';\nimport { AnimatePresence, type AnimationDefinition, motion, type Transition, useReducedMotion } from 'motion/react';\n\nimport { getOrCreatePortalRoot } from '../../utils/portalRoot';\nimport useEsc from '../../hooks/useEsc';\nimport DialogHeader from './DialogHeader';\nimport DialogBody from './DialogBody';\nimport DialogFooter from './DialogFooter';\nimport useFocusTrap from '../../hooks/useFocusTrap';\nimport { DialogContextProvider } from './dialogContext';\n\nconst MODAL_DIALOG_CLASS = 'modal-dialog';\nconst MODAL_OPEN_CLASS = 'modal-open';\n\nexport type DialogSize =\n | 'xs'\n | 'sm'\n | 'md'\n | 'lg'\n | 'xl'\n | 'full'\n | 'fullwidth'\n | 'fullheight'\n | 'fullheight-lg'\n | 'fullheight-xl'\n | 'fullscreen';\n\nexport type BaseDialogProps = {\n /**\n * Opens the dialog when set to `true`.\n *\n * @default false\n */\n show: boolean;\n\n /**\n * The dialog title (can also be a FormattedMessage component).\n */\n title?: React.ReactNode;\n\n /**\n * The dialog header subtitle content.\n */\n subtitle?: React.ReactNode;\n\n /**\n * Shows a close button when set to `true`.\n *\n * @default true\n */\n showCloseButton?: boolean;\n\n /**\n * A callback function invoked when the dialog closes.\n */\n onClose?: () => void;\n\n /**\n * Defined how large the dialog will be rendered.\n *\n * By default, the dialog has a medium size, and thus it can be omitted.\n *\n * Possible values are:\n *\n * - `'xs'`\n * - `'sm'`\n * - `'lg'`\n * - `'xl'`\n * - `'fullwidth'`\n * - `'fullheight'`\n * - `'fullheight-lg'`\n * - `'fullheight-xl'`\n * - `'fullscreen'`\n *\n * @default 'md'\n */\n bsSize?: DialogSize;\n\n /**\n * Enables or disabled closing the dialog via esc key.\n *\n * @default false\n */\n disableEsc?: boolean;\n\n /**\n * Enables the modal body to overflow and use inline scrolling if needed.\n *\n * @default false\n */\n useOverflow?: boolean;\n\n /**\n * Show Header and Footer Borders for the \"xs\" dialog\n *\n * @default false\n */\n showXsDialogBorders?: boolean;\n\n /**\n * Additional classes for the modal element.\n */\n className?: string;\n};\n\nexport type DialogProps = BaseDialogProps & {\n /**\n * The dialog body content.\n */\n body?: React.ReactNode;\n\n /**\n * The dialog body content.\n */\n footer?: React.ReactNode;\n\n /**\n * Additional classes for the modal-body element.\n */\n bodyClassName?: string;\n\n /**\n * Additional classes for the modal-footer element.\n */\n footerClassName?: string;\n\n /**\n * Allows to add additional buttons to the dialog header.\n */\n headerButtons?: React.ReactNode;\n\n /**\n * A callback fired when esc key is pressed and the dialog is about to close.\n */\n onEsc?: VoidFunction;\n\n /**\n * A callback function to be executed before closing the dialog.\n *\n * If the function returns `false`, the dialog will not be closed\n *\n * @default () => true\n */\n onCloseValidation?: () => boolean;\n};\n\nconst Dialog = (props: PropsWithChildren<DialogProps>) => {\n const {\n title,\n subtitle,\n body,\n footer,\n headerButtons,\n className = '',\n bodyClassName,\n footerClassName,\n showXsDialogBorders = false,\n showCloseButton = true,\n useOverflow = false,\n bsSize,\n show = false,\n onClose: onCloseCallback = noop,\n disableEsc = false,\n onEsc = noop,\n onCloseValidation = () => true,\n children,\n ...remainingProps\n } = props;\n\n const [open, setOpen] = useState(show);\n const dialogWrapperRef = useRef<HTMLDivElement>(null);\n\n const modalRoot = getOrCreatePortalRoot();\n\n const shouldReduceMotion = useReducedMotion();\n\n // Use a setter function for the focus trap as it would not re-render\n // and fails to set the focus listener\n const [focusTrapRef, setFocusTrapRef] = useState<HTMLDivElement>();\n useFocusTrap(focusTrapRef);\n\n const toggleBodyClass = (add: boolean) => {\n // We need to set a body class to fix the -webkit-overflow-scrolling on safari and iOS\n\n // Remove \"modal-open\" from body only when there is no other dialog in the DOM\n // in order to support multiple dialogs\n const hasOtherDialogs = modalRoot.getElementsByClassName(MODAL_DIALOG_CLASS).length > 1;\n\n if (add) {\n document.body.classList.add(MODAL_OPEN_CLASS);\n } else if (!add && !hasOtherDialogs) {\n document.body.classList.remove(MODAL_OPEN_CLASS);\n }\n };\n\n const handleCloseButton = () => closeDialog(true);\n\n const closeDialog = (usedEscapeKey: boolean) => {\n if (onCloseValidation()) {\n setOpen(false);\n onCloseCallback();\n\n usedEscapeKey && onEsc();\n }\n };\n\n const [previousShow, setPreviousShow] = useState(show);\n if (show !== previousShow) {\n setOpen(show);\n toggleBodyClass(show);\n setPreviousShow(show);\n }\n\n useEsc(() => {\n if (!dialogWrapperRef || !dialogWrapperRef.current) {\n return;\n }\n\n const dialogElement = dialogWrapperRef.current;\n const currentActiveElement = document.activeElement;\n\n // Only allow to close the dialog when the focus is inside the dialog\n if (!disableEsc && dialogElement.contains(currentActiveElement)) {\n closeDialog(true);\n }\n });\n\n const handleAnimationComplete = (definition: AnimationDefinition) => {\n // The animation complete callback is invoked too when closing the dialog.\n // For that we check the animation props like the \"opacity\" to skip focusing\n // on the way out when closing the dialog.\n // @ts-ignore\n if (definition.opacity === 0) {\n return;\n }\n\n const dialogElement = dialogWrapperRef.current;\n const currentActiveElement = document.activeElement;\n\n // Set the focus to the dialog if no element inside has focus already. Otherwise, focused\n // elements like inputs would lose their focus to the dialog.\n // Note that in order to focus the dialog itself, the tabindex has to be set on that element\n // IMPORTANT: make sure the dialog has a tabIndex prop\n if (!dialogElement?.contains(currentActiveElement)) {\n dialogWrapperRef?.current?.focus();\n }\n };\n\n const modalClasses = classNames('modal', 'show', className);\n\n const isSmallestDialog = bsSize === 'xs';\n\n const hasChildren = !!children;\n\n const modalDialogClasses = classNames(\n MODAL_DIALOG_CLASS,\n useOverflow && 'modal-overflow',\n bsSize === 'xs' && 'modal-xs',\n bsSize === 'sm' && 'modal-sm',\n bsSize === 'lg' && 'modal-lg',\n bsSize === 'xl' && 'modal-xl',\n bsSize === 'full' && 'modal-full-width',\n bsSize === 'fullwidth' && 'modal-full-width',\n bsSize === 'fullheight' && 'modal-full-height',\n bsSize === 'fullheight-lg' && 'modal-full-height modal-lg',\n bsSize === 'fullheight-xl' && 'modal-full-height modal-xl',\n bsSize === 'fullscreen' && 'modal-fullscreen'\n );\n\n const spring: Transition = {\n type: 'spring',\n damping: 33,\n stiffness: 500,\n };\n\n const springXs: Transition = {\n type: 'spring',\n damping: 25,\n stiffness: 400,\n };\n\n return ReactDOM.createPortal(\n <DialogContextProvider\n value={{ onClose: handleCloseButton, isSmallestDialog, showXsDialogBorders, showCloseButton }}\n >\n {/* @ts-ignore-next-line */}\n <AnimatePresence\n // Disable any initial animations on children that\n // are present when the component is first rendered\n initial={false}\n // Only render one component at a time.\n // The exiting component will finish its exit\n // animation before entering component is rendered\n mode='wait'\n >\n {open && (\n <div\n {...remainingProps}\n className={modalClasses}\n role='dialog'\n ref={dialogWrapperRef}\n aria-label='dialog'\n // Make sure it has a tabIndex to focus the dialog so the close on esc works.\n // biome-ignore lint/a11y/noNoninteractiveTabindex: <explanation>\n tabIndex={0}\n >\n <motion.div\n initial={shouldReduceMotion ? false : { opacity: 0, y: '-50%' }}\n animate={\n shouldReduceMotion\n ? { opacity: 1 }\n : { opacity: 1, y: 0, transition: isSmallestDialog ? springXs : spring }\n }\n exit={shouldReduceMotion ? undefined : { opacity: 0, y: '-150%' }}\n transition={\n shouldReduceMotion\n ? { duration: 0 }\n : {\n opacity: { duration: 0.2 },\n y: { duration: 0.3 },\n }\n }\n onAnimationComplete={handleAnimationComplete}\n // @ts-ignore\n ref={setFocusTrapRef}\n className={modalDialogClasses}\n role='document'\n >\n <div className='modal-content'>\n {hasChildren && children}\n {!hasChildren && (\n <>\n {title && (\n <DialogHeader\n title={title}\n subtitle={subtitle}\n headerButtons={headerButtons}\n />\n )}\n {body && <DialogBody className={bodyClassName}>{body}</DialogBody>}\n {footer && <DialogFooter className={footerClassName}>{footer}</DialogFooter>}\n </>\n )}\n </div>\n </motion.div>\n <motion.div\n initial={shouldReduceMotion ? false : { opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={shouldReduceMotion ? undefined : { opacity: 0 }}\n transition={shouldReduceMotion ? { duration: 0 } : { duration: 0.1 }}\n className='modal-backdrop'\n />\n </div>\n )}\n </AnimatePresence>\n </DialogContextProvider>,\n modalRoot\n );\n};\n\nDialog.Title = DialogHeader;\nDialog.Body = DialogBody;\nDialog.Footer = DialogFooter;\n\nDialog.SIZE_XS = 'xs' as const;\nDialog.SIZE_SM = 'sm' as const;\nDialog.SIZE_MD = 'md' as const; // default\nDialog.SIZE_LG = 'lg' as const;\nDialog.SIZE_XL = 'xl' as const;\nDialog.SIZE_FULL = 'full' as const;\nDialog.SIZE_FULL_WIDTH = 'fullwidth' as const;\nDialog.SIZE_FULL_HEIGHT = 'fullheight' as const;\nDialog.SIZE_FULL_HEIGHT_LG = 'fullheight-lg' as const;\nDialog.SIZE_FULL_HEIGHT_XL = 'fullheight-xl' as const;\nDialog.SIZE_FULL_SCREEN = 'fullscreen' as const;\n\nexport default Dialog;\n"],"names":["MODAL_DIALOG_CLASS","MODAL_OPEN_CLASS","Dialog","props","title","subtitle","body","footer","headerButtons","className","bodyClassName","footerClassName","showXsDialogBorders","showCloseButton","useOverflow","bsSize","show","onCloseCallback","noop","disableEsc","onEsc","onCloseValidation","children","remainingProps","open","setOpen","useState","dialogWrapperRef","useRef","modalRoot","getOrCreatePortalRoot","shouldReduceMotion","useReducedMotion","focusTrapRef","setFocusTrapRef","useFocusTrap","toggleBodyClass","add","hasOtherDialogs","handleCloseButton","closeDialog","usedEscapeKey","previousShow","setPreviousShow","useEsc","dialogElement","currentActiveElement","handleAnimationComplete","definition","modalClasses","classNames","isSmallestDialog","hasChildren","modalDialogClasses","spring","springXs","ReactDOM","jsx","DialogContextProvider","AnimatePresence","jsxs","motion","Fragment","DialogHeader","DialogBody","DialogFooter"],"mappings":"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"}
@@ -6,6 +6,7 @@ export type ReleaseNotesDialogProps = {
6
6
  showReleaseNotes: boolean;
7
7
  /**
8
8
  * Callback set showReleaseNotes state
9
+ *
9
10
  * @param show
10
11
  * @returns
11
12
  */
@@ -26,8 +27,6 @@ export type ReleaseNotesDialogProps = {
26
27
  * Translated release notes.
27
28
  *
28
29
  * @example
29
- *
30
- * ```tsx
31
30
  * {
32
31
  * "0.1.2": {
33
32
  * date: '20.10.2023',
@@ -40,7 +39,6 @@ export type ReleaseNotesDialogProps = {
40
39
  * ),
41
40
  * }
42
41
  * }
43
- * ```
44
42
  */
45
43
  translatedReleaseNotes: ReleaseNotesData;
46
44
  /**
@@ -54,6 +52,8 @@ export type ReleaseNotesDialogProps = {
54
52
  /**
55
53
  * Enables the content of the dialog to scroll when it overflows.
56
54
  * This means the dialog body scrolls instead of the entire dialog.
55
+ *
56
+ * @default true
57
57
  */
58
58
  useOverflow?: boolean;
59
59
  };
@@ -1 +1 @@
1
- {"version":3,"file":"ReleaseNotesDialog.js","sources":["../../../src/components/dialog/ReleaseNotesDialog.tsx"],"sourcesContent":["import ReleaseNotes, { type ReleaseNotesData } from '../releaseNotes/ReleaseNotes';\n\nimport Button from '../button/Button';\nimport Dialog from './Dialog';\n\nconst setReleaseNotesItem = (props: ReleaseNotesDialogProps) => {\n window.localStorage.setItem(props.RELEASE_NOTES_ITEM, props.currentVersion);\n props.setShowReleaseNotes(false);\n};\n\nconst getModuleName = (moduleName: string | undefined, whatsNew: string | undefined) => (\n <span>{moduleName ? moduleName : whatsNew}</span>\n);\n\nexport type ReleaseNotesDialogProps = {\n /**\n * Decides if the dialog is opened.\n */\n showReleaseNotes: boolean;\n\n /**\n * Callback set showReleaseNotes state\n * @param show\n * @returns\n */\n setShowReleaseNotes: (show: boolean) => void;\n\n /**\n * Translated text for \"What`s new?\"\n */\n whatsNewTitle?: string;\n\n /**\n * The translated modulename.\n */\n moduleName?: string;\n\n /**\n * Translated text for the close button.\n */\n closeButtonText?: string;\n\n /**\n * Translated release notes.\n *\n * @example\n *\n * ```tsx\n * {\n * \"0.1.2\": {\n * date: '20.10.2023',\n * content: (\n * <div className='padding-left-15'>\n * Summary\n * • Feature 1\n * • Feature 2\n * </div>\n * ),\n * }\n * }\n * ```\n */\n translatedReleaseNotes: ReleaseNotesData;\n\n /**\n * Specifies the current module version.\n */\n currentVersion: string;\n\n /**\n * Specifies the item in the localStorage that is used to save the last read module version.\n */\n RELEASE_NOTES_ITEM: string;\n\n /**\n * Enables the content of the dialog to scroll when it overflows.\n * This means the dialog body scrolls instead of the entire dialog.\n */\n useOverflow?: boolean;\n};\n\nconst ReleaseNotesDialog = (props: ReleaseNotesDialogProps) => {\n const { moduleName, whatsNewTitle, closeButtonText, translatedReleaseNotes, useOverflow = true } = props;\n\n return (\n <Dialog\n show={props.showReleaseNotes}\n useOverflow={useOverflow}\n title={getModuleName(moduleName, whatsNewTitle)}\n subtitle={moduleName && whatsNewTitle}\n body={<ReleaseNotes releaseNotes={translatedReleaseNotes} />}\n footer={<Button onClick={() => setReleaseNotesItem(props)}>{closeButtonText || 'Close'}</Button>}\n onClose={() => setReleaseNotesItem(props)}\n />\n );\n};\n\nexport default ReleaseNotesDialog;\n"],"names":["setReleaseNotesItem","props","getModuleName","moduleName","whatsNew","ReleaseNotesDialog","whatsNewTitle","closeButtonText","translatedReleaseNotes","useOverflow","jsx","Dialog","ReleaseNotes","Button"],"mappings":";;;;AAKA,MAAMA,IAAsB,CAACC,MAAmC;AAC5D,SAAO,aAAa,QAAQA,EAAM,oBAAoBA,EAAM,cAAc,GAC1EA,EAAM,oBAAoB,EAAK;AACnC,GAEMC,IAAgB,CAACC,GAAgCC,wBAClD,QAAA,EAAM,UAAAD,KAA0BC,GAAS,GAsExCC,IAAqB,CAACJ,MAAmC;AAC3D,QAAM,EAAE,YAAAE,GAAY,eAAAG,GAAe,iBAAAC,GAAiB,wBAAAC,GAAwB,aAAAC,IAAc,OAASR;AAEnG,SACI,gBAAAS;AAAA,IAACC;AAAA,IAAA;AAAA,MACG,MAAMV,EAAM;AAAA,MACZ,aAAAQ;AAAA,MACA,OAAOP,EAAcC,GAAYG,CAAa;AAAA,MAC9C,UAAUH,KAAcG;AAAA,MACxB,MAAM,gBAAAI,EAACE,GAAA,EAAa,cAAcJ,EAAA,CAAwB;AAAA,MAC1D,0BAASK,GAAA,EAAO,SAAS,MAAMb,EAAoBC,CAAK,GAAI,UAAAM,KAAmB,QAAA,CAAQ;AAAA,MACvF,SAAS,MAAMP,EAAoBC,CAAK;AAAA,IAAA;AAAA,EAAA;AAGpD;"}
1
+ {"version":3,"file":"ReleaseNotesDialog.js","sources":["../../../src/components/dialog/ReleaseNotesDialog.tsx"],"sourcesContent":["import ReleaseNotes, { type ReleaseNotesData } from '../releaseNotes/ReleaseNotes';\n\nimport Button from '../button/Button';\nimport Dialog from './Dialog';\n\nconst setReleaseNotesItem = (props: ReleaseNotesDialogProps) => {\n window.localStorage.setItem(props.RELEASE_NOTES_ITEM, props.currentVersion);\n props.setShowReleaseNotes(false);\n};\n\nconst getModuleName = (moduleName: string | undefined, whatsNew: string | undefined) => (\n <span>{moduleName ? moduleName : whatsNew}</span>\n);\n\nexport type ReleaseNotesDialogProps = {\n /**\n * Decides if the dialog is opened.\n */\n showReleaseNotes: boolean;\n\n /**\n * Callback set showReleaseNotes state\n *\n * @param show\n * @returns\n */\n setShowReleaseNotes: (show: boolean) => void;\n\n /**\n * Translated text for \"What`s new?\"\n */\n whatsNewTitle?: string;\n\n /**\n * The translated modulename.\n */\n moduleName?: string;\n\n /**\n * Translated text for the close button.\n */\n closeButtonText?: string;\n\n /**\n * Translated release notes.\n *\n * @example\n * {\n * \"0.1.2\": {\n * date: '20.10.2023',\n * content: (\n * <div className='padding-left-15'>\n * Summary\n * • Feature 1\n * • Feature 2\n * </div>\n * ),\n * }\n * }\n */\n translatedReleaseNotes: ReleaseNotesData;\n\n /**\n * Specifies the current module version.\n */\n currentVersion: string;\n\n /**\n * Specifies the item in the localStorage that is used to save the last read module version.\n */\n RELEASE_NOTES_ITEM: string;\n\n /**\n * Enables the content of the dialog to scroll when it overflows.\n * This means the dialog body scrolls instead of the entire dialog.\n *\n * @default true\n */\n useOverflow?: boolean;\n};\n\nconst ReleaseNotesDialog = (props: ReleaseNotesDialogProps) => {\n const { moduleName, whatsNewTitle, closeButtonText, translatedReleaseNotes, useOverflow = true } = props;\n\n return (\n <Dialog\n show={props.showReleaseNotes}\n useOverflow={useOverflow}\n title={getModuleName(moduleName, whatsNewTitle)}\n subtitle={moduleName && whatsNewTitle}\n body={<ReleaseNotes releaseNotes={translatedReleaseNotes} />}\n footer={<Button onClick={() => setReleaseNotesItem(props)}>{closeButtonText || 'Close'}</Button>}\n onClose={() => setReleaseNotesItem(props)}\n />\n );\n};\n\nexport default ReleaseNotesDialog;\n"],"names":["setReleaseNotesItem","props","getModuleName","moduleName","whatsNew","ReleaseNotesDialog","whatsNewTitle","closeButtonText","translatedReleaseNotes","useOverflow","jsx","Dialog","ReleaseNotes","Button"],"mappings":";;;;AAKA,MAAMA,IAAsB,CAACC,MAAmC;AAC5D,SAAO,aAAa,QAAQA,EAAM,oBAAoBA,EAAM,cAAc,GAC1EA,EAAM,oBAAoB,EAAK;AACnC,GAEMC,IAAgB,CAACC,GAAgCC,wBAClD,QAAA,EAAM,UAAAD,KAA0BC,GAAS,GAsExCC,IAAqB,CAACJ,MAAmC;AAC3D,QAAM,EAAE,YAAAE,GAAY,eAAAG,GAAe,iBAAAC,GAAiB,wBAAAC,GAAwB,aAAAC,IAAc,OAASR;AAEnG,SACI,gBAAAS;AAAA,IAACC;AAAA,IAAA;AAAA,MACG,MAAMV,EAAM;AAAA,MACZ,aAAAQ;AAAA,MACA,OAAOP,EAAcC,GAAYG,CAAa;AAAA,MAC9C,UAAUH,KAAcG;AAAA,MACxB,MAAM,gBAAAI,EAACE,GAAA,EAAa,cAAcJ,EAAA,CAAwB;AAAA,MAC1D,0BAASK,GAAA,EAAO,SAAS,MAAMb,EAAoBC,CAAK,GAAI,UAAAM,KAAmB,QAAA,CAAQ;AAAA,MACvF,SAAS,MAAMP,EAAoBC,CAAK;AAAA,IAAA;AAAA,EAAA;AAGpD;"}
@@ -33,12 +33,16 @@ export type ButtonDropdownProps<T extends DropdownToggleButtonType = 'button'> =
33
33
  * Defines how large the button will be rendered.
34
34
  *
35
35
  * Possible values are: `xs`, `sm`, `md`, `lg`
36
+ *
37
+ * @default 'md'
36
38
  */
37
39
  bsSize?: BUTTON_SIZE;
38
40
  /**
39
41
  * Defines the button color.
40
42
  *
41
43
  * Possible values are: `default`, `primary`, `secondary`, `info`, `warning`, `danger`, `success`, `muted`
44
+ *
45
+ * @default 'default'
42
46
  */
43
47
  bsStyle?: BUTTON_STYLE;
44
48
  /**
@@ -1,18 +1,18 @@
1
- import { jsx as l, jsxs as N, Fragment as ro } from "react/jsx-runtime";
2
- import { forwardRef as so, useState as c, useEffect as lo } from "react";
3
- import po from "react-dom";
4
- import { usePopper as ao } from "react-popper";
1
+ import { jsx as i, jsxs as h } from "react/jsx-runtime";
2
+ import { forwardRef as ro, useState as f, useEffect as so } from "react";
3
+ import lo from "react-dom";
4
+ import { usePopper as po } from "react-popper";
5
5
  import P from "classnames";
6
6
  import { noop as u } from "es-toolkit/function";
7
- import { isNil as io } from "es-toolkit/predicate";
8
- import { getOrCreatePortalRoot as co } from "../../utils/portalRoot.js";
9
- import fo, { DEFAULT_EVENT_TYPES as mo } from "../../hooks/useClickOutside.js";
10
- import uo from "../menuItems/MenuItems.js";
11
- import go from "../menuItems/MenuItemList.js";
12
- import wo from "./DropdownToggleButton.js";
13
- import Co from "./SplitCaretButton.js";
14
- import Bo from "./Caret.js";
15
- const Do = (r, s) => r && s ? "top-end" : !r && s ? "top-start" : r && !s ? "bottom-end" : "bottom-start", Oo = () => so((r, s) => {
7
+ import { isNil as ao } from "es-toolkit/predicate";
8
+ import { getOrCreatePortalRoot as io } from "../../utils/portalRoot.js";
9
+ import fo, { DEFAULT_EVENT_TYPES as co } from "../../hooks/useClickOutside.js";
10
+ import mo from "../menuItems/MenuItems.js";
11
+ import uo from "../menuItems/MenuItemList.js";
12
+ import go from "./DropdownToggleButton.js";
13
+ import wo from "./SplitCaretButton.js";
14
+ import Co from "./Caret.js";
15
+ const Bo = (r, s) => r && s ? "top-end" : !r && s ? "top-start" : r && !s ? "bottom-end" : "bottom-start", Do = () => ro((r, s) => {
16
16
  const {
17
17
  id: g = Math.random().toString(36).slice(2, 16),
18
18
  items: R = [],
@@ -26,61 +26,61 @@ const Do = (r, s) => r && s ? "top-end" : !r && s ? "top-start" : r && !s ? "bot
26
26
  customDropdown: O,
27
27
  open: e,
28
28
  dropup: y = !1,
29
- pullRight: f = !1,
29
+ pullRight: c = !1,
30
30
  noCaret: E = !1,
31
31
  onOpen: L = u,
32
32
  onClose: x = u,
33
33
  onLabelButtonClick: I = u,
34
- usePortal: p = !1,
34
+ usePortal: l = !1,
35
35
  popperConfig: j,
36
- toggleButtonType: F = "button",
36
+ toggleButtonType: U = "button",
37
37
  toggleClassName: S = "",
38
- dropdownClassName: U,
39
- className: _ = "",
40
- ...v
41
- } = r, [b, m] = c(e), [z, A] = c(null), [h, V] = c(null), [Y, q] = c(null), G = {
42
- placement: Do(f, y),
38
+ dropdownClassName: _,
39
+ className: v = "",
40
+ ...z
41
+ } = r, [b, m] = f(e), [A, F] = f(null), [M, V] = f(null), [Y, q] = f(null), G = {
42
+ placement: Bo(c, y),
43
43
  modifiers: []
44
- }, H = t && f ? Y : z, { styles: J, attributes: K } = ao(H, h, j || G), n = io(e), a = n ? b : e, Q = fo(
44
+ }, H = t && c ? Y : A, { styles: J, attributes: K } = po(H, M, j || G), n = ao(e), p = n ? b : e, Q = fo(
45
45
  (o) => {
46
- p && h?.contains(o.target) || i();
46
+ l && M?.contains(o.target) || a();
47
47
  },
48
- mo,
49
- !!a
48
+ co,
49
+ !!p
50
50
  // only listen to clicks outside when the dropdown is open
51
- ), W = co(), X = !E && !t && !D;
52
- lo(() => {
51
+ ), W = io(), X = !E && !t && !D;
52
+ so(() => {
53
53
  n || m(e);
54
54
  }, [n, e]);
55
55
  const d = (o) => {
56
- (n ? b : e) ? i() : Z(o);
56
+ (n ? b : e) ? a() : Z(o);
57
57
  }, Z = (o) => {
58
58
  n && m(!0), o && L(o);
59
- }, i = () => {
59
+ }, a = () => {
60
60
  n && m(!1), x();
61
61
  }, $ = () => {
62
- i(), I();
62
+ a(), I();
63
63
  }, oo = (o) => {
64
64
  d(o);
65
65
  }, to = (o) => {
66
66
  t ? $() : d(o);
67
- }, eo = P("dropdown", "btn-group", a && "open", _), no = P(
68
- p && "dropdown-portal",
69
- t && f && "pull-right",
70
- U
71
- ), M = /* @__PURE__ */ l(
72
- go,
67
+ }, eo = P("dropdown", "btn-group", p && "open", v), no = P(
68
+ l && "dropdown-portal",
69
+ t && c && "pull-right",
70
+ _
71
+ ), N = /* @__PURE__ */ i(
72
+ uo,
73
73
  {
74
74
  className: no,
75
75
  ref: V,
76
76
  style: J.popper,
77
77
  ...K.popper,
78
- children: O || /* @__PURE__ */ l(uo, { items: R, closeMenu: d })
78
+ children: O || /* @__PURE__ */ i(mo, { items: R, closeMenu: d })
79
79
  }
80
80
  );
81
- return /* @__PURE__ */ N("div", { ...v, className: eo, ref: Q, children: [
82
- /* @__PURE__ */ l(
83
- wo,
81
+ return /* @__PURE__ */ h("div", { ...z, className: eo, ref: Q, children: [
82
+ /* @__PURE__ */ h(
83
+ go,
84
84
  {
85
85
  id: g,
86
86
  splitButton: t,
@@ -89,19 +89,19 @@ const Do = (r, s) => r && s ? "top-end" : !r && s ? "top-start" : r && !s ? "bot
89
89
  variant: T,
90
90
  iconOnly: D,
91
91
  disabled: B,
92
- ref: A,
92
+ ref: F,
93
93
  onClick: to,
94
94
  outerRef: s,
95
- toggleButtonType: F,
95
+ toggleButtonType: U,
96
96
  className: S,
97
- children: /* @__PURE__ */ N(ro, { children: [
97
+ children: [
98
98
  k,
99
- X && /* @__PURE__ */ l(Bo, {})
100
- ] })
99
+ X && /* @__PURE__ */ i(Co, {})
100
+ ]
101
101
  }
102
102
  ),
103
- t && /* @__PURE__ */ l(
104
- Co,
103
+ t && /* @__PURE__ */ i(
104
+ wo,
105
105
  {
106
106
  id: g,
107
107
  bsStyle: C,
@@ -112,11 +112,11 @@ const Do = (r, s) => r && s ? "top-end" : !r && s ? "top-start" : r && !s ? "bot
112
112
  ref: q
113
113
  }
114
114
  ),
115
- a && p && po.createPortal(M, W),
116
- a && !p && M
115
+ p && l && lo.createPortal(N, W),
116
+ p && !l && N
117
117
  ] });
118
- }), Fo = Oo();
118
+ }), jo = Do();
119
119
  export {
120
- Fo as default
120
+ jo as default
121
121
  };
122
122
  //# sourceMappingURL=ButtonDropdown.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ButtonDropdown.js","sources":["../../../src/components/dropdown/ButtonDropdown.tsx"],"sourcesContent":["// biome-ignore lint/style/useImportType: <explanation>\nimport React, { useState, useEffect, forwardRef, type PropsWithChildren } from 'react';\nimport ReactDOM from 'react-dom';\nimport { usePopper } from 'react-popper';\nimport classNames from 'classnames';\nimport { noop } from 'es-toolkit/function';\nimport { isNil } from 'es-toolkit/predicate';\n\nimport { getOrCreatePortalRoot } from '../../utils/portalRoot';\nimport useClickOutside, { DEFAULT_EVENT_TYPES } from '../../hooks/useClickOutside';\nimport MenuItems from '../menuItems/MenuItems';\nimport MenuItemList from '../menuItems/MenuItemList';\nimport DropdownToggleButton, { type DropdownToggleEvent, type DropdownToggleButtonType } from './DropdownToggleButton';\nimport SplitCaretButton from './SplitCaretButton';\nimport Caret from './Caret';\nimport type { MenuItemProps as MenuItem } from '../menuItems/MenuItem';\nimport type { BUTTON_SIZE, BUTTON_STYLE, BUTTON_VARIANT } from '../button/Button';\n\nconst getPlacement = (pullRight: boolean, dropup: boolean) => {\n if (pullRight && dropup) {\n return 'top-end';\n }\n if (!pullRight && dropup) {\n return 'top-start';\n }\n if (pullRight && !dropup) {\n return 'bottom-end';\n }\n return 'bottom-start';\n};\n\nexport type ButtonDropdownProps<T extends DropdownToggleButtonType = 'button'> = {\n /**\n * Unique button id. If not present a random id is generated.\n */\n id?: string;\n\n /**\n * The button title. This may be also a node, like a <span> or a <FormattedMessage>.\n */\n title: string | React.ReactNode;\n\n /**\n * Defined weather or not the menu is rendered.\n * Use this to control the component from the outside.\n *\n * @default undefined\n */\n open?: boolean;\n\n /**\n * Defines whether the dropdown opens above or below.\n * Set it to \"true\" additionally disables the automatic position feature.\n *\n * @default false\n */\n dropup?: boolean;\n\n /**\n * Defines whether the dropdown opens right aligned to the dropdown or not.\n */\n pullRight?: boolean;\n\n /**\n * Defines how large the button will be rendered.\n *\n * Possible values are: `xs`, `sm`, `md`, `lg`\n */\n bsSize?: BUTTON_SIZE;\n\n /**\n * Defines the button color.\n *\n * Possible values are: `default`, `primary`, `secondary`, `info`, `warning`, `danger`, `success`, `muted`\n */\n bsStyle?: BUTTON_STYLE;\n\n /**\n * Defines the variation of the button design.\n *\n * Possible values are: `link`, `link-inline`, `outline`, `action`\n */\n variant?: BUTTON_VARIANT;\n\n /**\n * Specify the toggle element type.\n * It supports the following types: \"button\" | \"tag\" | \"label\"\n *\n * @default 'button'\n */\n toggleButtonType?: DropdownToggleButtonType;\n\n /**\n * Optional prop to defines whether the dropdown title is icon only which\n * applies different padding so the button is a square.\n *\n * @default false\n */\n iconOnly?: boolean;\n\n /**\n * Defines whether the caret is shown or not.\n *\n * @default false\n */\n noCaret?: boolean;\n\n /**\n * Defines whether the dropdown-toggle (with caret) should be in a separate button.\n *\n * @default false\n */\n splitButton?: boolean;\n\n /**\n * Renders the dropdown into a dedicated react portal\n *\n * @default false\n */\n usePortal?: boolean;\n\n /**\n * Items to display in the dropdown menu. If you use a custom dropdown you can skip this prop.\n */\n items?: MenuItem[];\n\n /**\n * Disables the dropdown button.\n *\n * @default false\n */\n disabled?: boolean;\n\n /**\n * Callback for splitButton label button click.\n */\n onLabelButtonClick?: () => void;\n\n /**\n * Callback for when the toggle button was clicked to open it.\n * @param event\n * @returns\n */\n onOpen?: (event: DropdownToggleEvent<T>) => void;\n\n /**\n * Callback for when the toggle button was clicked to close it.\n * @returns\n */\n onClose?: () => void;\n\n /**\n * Allows to pass in custom dropdown menu content.\n */\n customDropdown?: React.ReactNode;\n\n /**\n * Define custom popper.js configuration for dropdown placement and modifiers.\n */\n popperConfig?: object;\n\n /**\n * Additional classes to be set on the dropdown-toggle button.\n */\n toggleClassName?: string;\n\n /**\n * Additional classes to be set on the dropdown.\n */\n dropdownClassName?: string;\n\n /**\n * Additional classes to be set to the wrapper element.\n */\n className?: string;\n};\n\nconst createButtonDropdown = <T extends DropdownToggleButtonType = 'button'>() => {\n return forwardRef<\n T extends 'button' ? HTMLButtonElement : HTMLDivElement,\n PropsWithChildren<ButtonDropdownProps<T>>\n >((props, ref) => {\n const {\n id = Math.random().toString(36).slice(2, 16),\n items = [],\n bsSize = 'md',\n bsStyle = 'default',\n variant,\n disabled = false,\n iconOnly = false,\n title,\n splitButton = false,\n customDropdown,\n open,\n dropup = false,\n pullRight = false,\n noCaret = false,\n onOpen = noop,\n onClose = noop,\n onLabelButtonClick = noop,\n usePortal = false,\n popperConfig,\n toggleButtonType = 'button',\n toggleClassName = '',\n dropdownClassName,\n className = '',\n ...remainingProps\n } = props;\n\n const [internalOpen, setInternalOpen] = useState(open);\n\n const [refDropdownToggle, setRefDropdownToggle] = useState<HTMLButtonElement | HTMLDivElement | null>(null);\n const [refDropdownMenu, setRefDropdownMenu] = useState<HTMLUListElement | null>(null);\n const [refSplitButtonToggle, setRefSplitButtonToggle] = useState<HTMLButtonElement | null>(null);\n\n const defaultPopperConfig = {\n placement: getPlacement(pullRight, dropup),\n modifiers: [],\n };\n\n const popperParentRef = splitButton && pullRight ? refSplitButtonToggle : refDropdownToggle;\n\n const { styles, attributes } = usePopper(popperParentRef, refDropdownMenu, popperConfig || defaultPopperConfig);\n\n const isUncontrolled = isNil(open);\n const isOpen = isUncontrolled ? internalOpen : open;\n\n const wrapperRef = useClickOutside(\n event => {\n if (usePortal) {\n // In case the dropdown is rendered via portal the clickOutside the toggle button element is\n // triggered since the dropdown is not a child of the wrapper element.\n // In this case we need to check if the event target is inside the dropdown-menu and prevent closing\n // the dropdown\n if (!refDropdownMenu?.contains(event.target as Node)) {\n closeMenu();\n }\n } else {\n closeMenu();\n }\n },\n DEFAULT_EVENT_TYPES,\n Boolean(isOpen) // only listen to clicks outside when the dropdown is open\n );\n\n const dropdownRoot = getOrCreatePortalRoot();\n\n const shouldShowCaret = !noCaret && !splitButton && !iconOnly;\n\n useEffect(() => {\n if (!isUncontrolled) {\n setInternalOpen(open);\n }\n }, [isUncontrolled, open]);\n\n const toggleOpen = (event?: DropdownToggleEvent<T>) => {\n const isDropdownOpen = isUncontrolled ? internalOpen : open;\n\n if (isDropdownOpen) {\n closeMenu();\n } else {\n openMenu(event);\n }\n };\n\n const openMenu = (event?: DropdownToggleEvent<T>) => {\n if (isUncontrolled) {\n setInternalOpen(true);\n }\n if (event) {\n onOpen(event);\n }\n };\n\n const closeMenu = () => {\n if (isUncontrolled) {\n setInternalOpen(false);\n }\n onClose();\n };\n\n const handleSplitLabelButtonClick = () => {\n closeMenu();\n onLabelButtonClick();\n };\n\n const handleSplitCaretButtonClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n toggleOpen(event as any);\n };\n\n const handleDropdownButtonClick = (event: React.MouseEvent<HTMLButtonElement | HTMLDivElement>) => {\n if (splitButton) {\n handleSplitLabelButtonClick();\n } else {\n toggleOpen(event as DropdownToggleEvent<T>);\n }\n };\n\n const wrapperClasses = classNames('dropdown', 'btn-group', isOpen && 'open', className);\n\n const dropdownClasses = classNames(\n usePortal && 'dropdown-portal',\n splitButton && pullRight && 'pull-right',\n dropdownClassName\n );\n\n const dropdownMenu = (\n <MenuItemList\n className={dropdownClasses}\n ref={setRefDropdownMenu}\n style={styles.popper}\n {...attributes.popper}\n >\n {customDropdown ? customDropdown : <MenuItems items={items} closeMenu={toggleOpen} />}\n </MenuItemList>\n );\n\n return (\n <div {...remainingProps} className={wrapperClasses} ref={wrapperRef}>\n <DropdownToggleButton\n id={id}\n splitButton={splitButton}\n bsStyle={bsStyle}\n bsSize={bsSize}\n variant={variant}\n iconOnly={iconOnly}\n disabled={disabled}\n ref={setRefDropdownToggle}\n onClick={handleDropdownButtonClick}\n outerRef={ref}\n toggleButtonType={toggleButtonType}\n className={toggleClassName}\n >\n <>\n {title}\n {shouldShowCaret && <Caret />}\n </>\n </DropdownToggleButton>\n {splitButton && (\n <SplitCaretButton\n id={id}\n bsStyle={bsStyle}\n bsSize={bsSize}\n disabled={disabled}\n className={toggleClassName}\n onClick={handleSplitCaretButtonClick}\n ref={setRefSplitButtonToggle}\n />\n )}\n {isOpen && usePortal && ReactDOM.createPortal(dropdownMenu, dropdownRoot)}\n {isOpen && !usePortal && dropdownMenu}\n </div>\n );\n });\n};\n\nconst ButtonDropdown = createButtonDropdown();\n\nexport default ButtonDropdown;\n"],"names":["getPlacement","pullRight","dropup","createButtonDropdown","forwardRef","props","ref","id","items","bsSize","bsStyle","variant","disabled","iconOnly","title","splitButton","customDropdown","open","noCaret","onOpen","noop","onClose","onLabelButtonClick","usePortal","popperConfig","toggleButtonType","toggleClassName","dropdownClassName","className","remainingProps","internalOpen","setInternalOpen","useState","refDropdownToggle","setRefDropdownToggle","refDropdownMenu","setRefDropdownMenu","refSplitButtonToggle","setRefSplitButtonToggle","defaultPopperConfig","popperParentRef","styles","attributes","usePopper","isUncontrolled","isNil","isOpen","wrapperRef","useClickOutside","event","closeMenu","DEFAULT_EVENT_TYPES","dropdownRoot","getOrCreatePortalRoot","shouldShowCaret","useEffect","toggleOpen","openMenu","handleSplitLabelButtonClick","handleSplitCaretButtonClick","handleDropdownButtonClick","wrapperClasses","classNames","dropdownClasses","dropdownMenu","jsx","MenuItemList","MenuItems","DropdownToggleButton","jsxs","Fragment","Caret","SplitCaretButton","ReactDOM","ButtonDropdown"],"mappings":"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"}
1
+ {"version":3,"file":"ButtonDropdown.js","sources":["../../../src/components/dropdown/ButtonDropdown.tsx"],"sourcesContent":["import React, { useState, useEffect, forwardRef, type PropsWithChildren } from 'react';\nimport ReactDOM from 'react-dom';\nimport { usePopper } from 'react-popper';\nimport classNames from 'classnames';\nimport { noop } from 'es-toolkit/function';\nimport { isNil } from 'es-toolkit/predicate';\n\nimport { getOrCreatePortalRoot } from '../../utils/portalRoot';\nimport useClickOutside, { DEFAULT_EVENT_TYPES } from '../../hooks/useClickOutside';\nimport MenuItems from '../menuItems/MenuItems';\nimport MenuItemList from '../menuItems/MenuItemList';\nimport DropdownToggleButton, { type DropdownToggleEvent, type DropdownToggleButtonType } from './DropdownToggleButton';\nimport SplitCaretButton from './SplitCaretButton';\nimport Caret from './Caret';\nimport type { MenuItemProps as MenuItem } from '../menuItems/MenuItem';\nimport type { BUTTON_SIZE, BUTTON_STYLE, BUTTON_VARIANT } from '../button/Button';\n\nconst getPlacement = (pullRight: boolean, dropup: boolean) => {\n if (pullRight && dropup) {\n return 'top-end';\n }\n if (!pullRight && dropup) {\n return 'top-start';\n }\n if (pullRight && !dropup) {\n return 'bottom-end';\n }\n return 'bottom-start';\n};\n\nexport type ButtonDropdownProps<T extends DropdownToggleButtonType = 'button'> = {\n /**\n * Unique button id. If not present a random id is generated.\n */\n id?: string;\n\n /**\n * The button title. This may be also a node, like a <span> or a <FormattedMessage>.\n */\n title: string | React.ReactNode;\n\n /**\n * Defined weather or not the menu is rendered.\n * Use this to control the component from the outside.\n *\n * @default undefined\n */\n open?: boolean;\n\n /**\n * Defines whether the dropdown opens above or below.\n * Set it to \"true\" additionally disables the automatic position feature.\n *\n * @default false\n */\n dropup?: boolean;\n\n /**\n * Defines whether the dropdown opens right aligned to the dropdown or not.\n */\n pullRight?: boolean;\n\n /**\n * Defines how large the button will be rendered.\n *\n * Possible values are: `xs`, `sm`, `md`, `lg`\n *\n * @default 'md'\n */\n bsSize?: BUTTON_SIZE;\n\n /**\n * Defines the button color.\n *\n * Possible values are: `default`, `primary`, `secondary`, `info`, `warning`, `danger`, `success`, `muted`\n *\n * @default 'default'\n */\n bsStyle?: BUTTON_STYLE;\n\n /**\n * Defines the variation of the button design.\n *\n * Possible values are: `link`, `link-inline`, `outline`, `action`\n */\n variant?: BUTTON_VARIANT;\n\n /**\n * Specify the toggle element type.\n * It supports the following types: \"button\" | \"tag\" | \"label\"\n *\n * @default 'button'\n */\n toggleButtonType?: DropdownToggleButtonType;\n\n /**\n * Optional prop to defines whether the dropdown title is icon only which\n * applies different padding so the button is a square.\n *\n * @default false\n */\n iconOnly?: boolean;\n\n /**\n * Defines whether the caret is shown or not.\n *\n * @default false\n */\n noCaret?: boolean;\n\n /**\n * Defines whether the dropdown-toggle (with caret) should be in a separate button.\n *\n * @default false\n */\n splitButton?: boolean;\n\n /**\n * Renders the dropdown into a dedicated react portal\n *\n * @default false\n */\n usePortal?: boolean;\n\n /**\n * Items to display in the dropdown menu. If you use a custom dropdown you can skip this prop.\n */\n items?: MenuItem[];\n\n /**\n * Disables the dropdown button.\n *\n * @default false\n */\n disabled?: boolean;\n\n /**\n * Callback for splitButton label button click.\n */\n onLabelButtonClick?: () => void;\n\n /**\n * Callback for when the toggle button was clicked to open it.\n * @param event\n * @returns\n */\n onOpen?: (event: DropdownToggleEvent<T>) => void;\n\n /**\n * Callback for when the toggle button was clicked to close it.\n * @returns\n */\n onClose?: () => void;\n\n /**\n * Allows to pass in custom dropdown menu content.\n */\n customDropdown?: React.ReactNode;\n\n /**\n * Define custom popper.js configuration for dropdown placement and modifiers.\n */\n popperConfig?: object;\n\n /**\n * Additional classes to be set on the dropdown-toggle button.\n */\n toggleClassName?: string;\n\n /**\n * Additional classes to be set on the dropdown.\n */\n dropdownClassName?: string;\n\n /**\n * Additional classes to be set to the wrapper element.\n */\n className?: string;\n};\n\nconst createButtonDropdown = <T extends DropdownToggleButtonType = 'button'>() => {\n return forwardRef<\n T extends 'button' ? HTMLButtonElement : HTMLDivElement,\n PropsWithChildren<ButtonDropdownProps<T>>\n >((props, ref) => {\n const {\n id = Math.random().toString(36).slice(2, 16),\n items = [],\n bsSize = 'md',\n bsStyle = 'default',\n variant,\n disabled = false,\n iconOnly = false,\n title,\n splitButton = false,\n customDropdown,\n open,\n dropup = false,\n pullRight = false,\n noCaret = false,\n onOpen = noop,\n onClose = noop,\n onLabelButtonClick = noop,\n usePortal = false,\n popperConfig,\n toggleButtonType = 'button',\n toggleClassName = '',\n dropdownClassName,\n className = '',\n ...remainingProps\n } = props;\n\n const [internalOpen, setInternalOpen] = useState(open);\n\n const [refDropdownToggle, setRefDropdownToggle] = useState<HTMLButtonElement | HTMLDivElement | null>(null);\n const [refDropdownMenu, setRefDropdownMenu] = useState<HTMLUListElement | null>(null);\n const [refSplitButtonToggle, setRefSplitButtonToggle] = useState<HTMLButtonElement | null>(null);\n\n const defaultPopperConfig = {\n placement: getPlacement(pullRight, dropup),\n modifiers: [],\n };\n\n const popperParentRef = splitButton && pullRight ? refSplitButtonToggle : refDropdownToggle;\n\n const { styles, attributes } = usePopper(popperParentRef, refDropdownMenu, popperConfig || defaultPopperConfig);\n\n const isUncontrolled = isNil(open);\n const isOpen = isUncontrolled ? internalOpen : open;\n\n const wrapperRef = useClickOutside(\n event => {\n if (usePortal) {\n // In case the dropdown is rendered via portal the clickOutside the toggle button element is\n // triggered since the dropdown is not a child of the wrapper element.\n // In this case we need to check if the event target is inside the dropdown-menu and prevent closing\n // the dropdown\n if (!refDropdownMenu?.contains(event.target as Node)) {\n closeMenu();\n }\n } else {\n closeMenu();\n }\n },\n DEFAULT_EVENT_TYPES,\n Boolean(isOpen) // only listen to clicks outside when the dropdown is open\n );\n\n const dropdownRoot = getOrCreatePortalRoot();\n\n const shouldShowCaret = !noCaret && !splitButton && !iconOnly;\n\n useEffect(() => {\n if (!isUncontrolled) {\n setInternalOpen(open);\n }\n }, [isUncontrolled, open]);\n\n const toggleOpen = (event?: DropdownToggleEvent<T>) => {\n const isDropdownOpen = isUncontrolled ? internalOpen : open;\n\n if (isDropdownOpen) {\n closeMenu();\n } else {\n openMenu(event);\n }\n };\n\n const openMenu = (event?: DropdownToggleEvent<T>) => {\n if (isUncontrolled) {\n setInternalOpen(true);\n }\n if (event) {\n onOpen(event);\n }\n };\n\n const closeMenu = () => {\n if (isUncontrolled) {\n setInternalOpen(false);\n }\n onClose();\n };\n\n const handleSplitLabelButtonClick = () => {\n closeMenu();\n onLabelButtonClick();\n };\n\n const handleSplitCaretButtonClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n toggleOpen(event as any);\n };\n\n const handleDropdownButtonClick = (event: React.MouseEvent<HTMLButtonElement | HTMLDivElement>) => {\n if (splitButton) {\n handleSplitLabelButtonClick();\n } else {\n toggleOpen(event as DropdownToggleEvent<T>);\n }\n };\n\n const wrapperClasses = classNames('dropdown', 'btn-group', isOpen && 'open', className);\n\n const dropdownClasses = classNames(\n usePortal && 'dropdown-portal',\n splitButton && pullRight && 'pull-right',\n dropdownClassName\n );\n\n const dropdownMenu = (\n <MenuItemList\n className={dropdownClasses}\n ref={setRefDropdownMenu}\n style={styles.popper}\n {...attributes.popper}\n >\n {customDropdown ? customDropdown : <MenuItems items={items} closeMenu={toggleOpen} />}\n </MenuItemList>\n );\n\n return (\n <div {...remainingProps} className={wrapperClasses} ref={wrapperRef}>\n <DropdownToggleButton\n id={id}\n splitButton={splitButton}\n bsStyle={bsStyle}\n bsSize={bsSize}\n variant={variant}\n iconOnly={iconOnly}\n disabled={disabled}\n ref={setRefDropdownToggle}\n onClick={handleDropdownButtonClick}\n outerRef={ref}\n toggleButtonType={toggleButtonType}\n className={toggleClassName}\n >\n {title}\n {shouldShowCaret && <Caret />}\n </DropdownToggleButton>\n {splitButton && (\n <SplitCaretButton\n id={id}\n bsStyle={bsStyle}\n bsSize={bsSize}\n disabled={disabled}\n className={toggleClassName}\n onClick={handleSplitCaretButtonClick}\n ref={setRefSplitButtonToggle}\n />\n )}\n {isOpen && usePortal && ReactDOM.createPortal(dropdownMenu, dropdownRoot)}\n {isOpen && !usePortal && dropdownMenu}\n </div>\n );\n });\n};\n\nconst ButtonDropdown = createButtonDropdown();\n\nexport default ButtonDropdown;\n"],"names":["getPlacement","pullRight","dropup","createButtonDropdown","forwardRef","props","ref","id","items","bsSize","bsStyle","variant","disabled","iconOnly","title","splitButton","customDropdown","open","noCaret","onOpen","noop","onClose","onLabelButtonClick","usePortal","popperConfig","toggleButtonType","toggleClassName","dropdownClassName","className","remainingProps","internalOpen","setInternalOpen","useState","refDropdownToggle","setRefDropdownToggle","refDropdownMenu","setRefDropdownMenu","refSplitButtonToggle","setRefSplitButtonToggle","defaultPopperConfig","popperParentRef","styles","attributes","usePopper","isUncontrolled","isNil","isOpen","wrapperRef","useClickOutside","event","closeMenu","DEFAULT_EVENT_TYPES","dropdownRoot","getOrCreatePortalRoot","shouldShowCaret","useEffect","toggleOpen","openMenu","handleSplitLabelButtonClick","handleSplitCaretButtonClick","handleDropdownButtonClick","wrapperClasses","classNames","dropdownClasses","dropdownMenu","jsx","MenuItemList","MenuItems","jsxs","DropdownToggleButton","Caret","SplitCaretButton","ReactDOM","ButtonDropdown"],"mappings":"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"}
@@ -3,6 +3,8 @@ import { MenuItemProps as MenuItem } from '../menuItems/MenuItem';
3
3
  export type DropdownSubmenuProps = {
4
4
  /**
5
5
  * Displayed button title.
6
+ *
7
+ * @default ''
6
8
  */
7
9
  title?: string | React.ReactNode;
8
10
  /**
@@ -11,6 +13,8 @@ export type DropdownSubmenuProps = {
11
13
  items?: MenuItem[];
12
14
  /**
13
15
  * Disables every entry on the title list item.
16
+ *
17
+ * @default false
14
18
  */
15
19
  disabled?: boolean;
16
20
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"DropdownSubmenu.js","sources":["../../../src/components/dropdown/DropdownSubmenu.tsx"],"sourcesContent":["import type React from 'react';\nimport { useState } from 'react';\nimport classNames from 'classnames';\nimport { usePopper } from 'react-popper';\n\nimport MenuItems from '../menuItems/MenuItems';\nimport MenuItemList from '../menuItems/MenuItemList';\nimport type { MenuItemProps as MenuItem } from '../menuItems/MenuItem';\n\nexport type DropdownSubmenuProps = {\n /**\n * Displayed button title.\n */\n title?: string | React.ReactNode;\n\n /**\n * Items to display in the dropdown sub menu.\n */\n items?: MenuItem[];\n\n /**\n * Disables every entry on the title list item.\n */\n disabled?: boolean;\n\n /**\n * Additional classes to be set on the dropdown-submenu element.\n */\n className?: string;\n};\n\nconst DropdownSubmenu = (props: DropdownSubmenuProps) => {\n const { title = '', items = [], disabled = false, className, ...remainingProps } = props;\n\n const classes = classNames('dropdown-submenu', disabled && 'disabled', className);\n\n const [refParentPopper, setRefParentPopper] = useState<HTMLLIElement | null>(null);\n const [refDropdownSubmenu, setRefDropdownSubmenu] = useState<HTMLUListElement | null>(null);\n\n // We have to use the workaround of checking the hover state as popper may render\n // the sub menu on an odd place and fixes it's position on the next render cycle\n const [isHover, setIsHover] = useState(false);\n const handleMouseEnter = () => setIsHover(true);\n const handleMouseLeave = () => setIsHover(false);\n\n const { styles, attributes } = usePopper(refParentPopper, refDropdownSubmenu, {\n placement: 'right-start',\n modifiers: [\n {\n name: 'offset',\n options: {\n offset: [-4, 0],\n },\n },\n ],\n });\n\n // return a list item that is also automatically the new toggle for the submenu\n return (\n <li\n ref={setRefParentPopper}\n {...remainingProps}\n className={classes}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n >\n {/* biome-ignore lint/a11y/useValidAnchor: <explanation> */}\n <a className='submenu-title' role='menuitem'>\n <span className='submenu-title-text'>{title}</span>\n <span className='rioglyph rioglyph-chevron-right' />\n </a>\n {/* The actual submenu items */}\n {isHover && !disabled && (\n <MenuItemList ref={setRefDropdownSubmenu} style={styles.popper} {...attributes.popper}>\n <MenuItems items={items} />\n </MenuItemList>\n )}\n </li>\n );\n};\n\nexport default DropdownSubmenu;\n"],"names":["DropdownSubmenu","props","title","items","disabled","className","remainingProps","classes","classNames","refParentPopper","setRefParentPopper","useState","refDropdownSubmenu","setRefDropdownSubmenu","isHover","setIsHover","handleMouseEnter","handleMouseLeave","styles","attributes","usePopper","jsxs","jsx","MenuItemList","MenuItems"],"mappings":";;;;;;AA+BA,MAAMA,IAAkB,CAACC,MAAgC;AACrD,QAAM,EAAE,OAAAC,IAAQ,IAAI,OAAAC,IAAQ,CAAA,GAAI,UAAAC,IAAW,IAAO,WAAAC,GAAW,GAAGC,EAAA,IAAmBL,GAE7EM,IAAUC,EAAW,oBAAoBJ,KAAY,YAAYC,CAAS,GAE1E,CAACI,GAAiBC,CAAkB,IAAIC,EAA+B,IAAI,GAC3E,CAACC,GAAoBC,CAAqB,IAAIF,EAAkC,IAAI,GAIpF,CAACG,GAASC,CAAU,IAAIJ,EAAS,EAAK,GACtCK,IAAmB,MAAMD,EAAW,EAAI,GACxCE,IAAmB,MAAMF,EAAW,EAAK,GAEzC,EAAE,QAAAG,GAAQ,YAAAC,EAAA,IAAeC,EAAUX,GAAiBG,GAAoB;AAAA,IAC1E,WAAW;AAAA,IACX,WAAW;AAAA,MACP;AAAA,QACI,MAAM;AAAA,QACN,SAAS;AAAA,UACL,QAAQ,CAAC,IAAI,CAAC;AAAA,QAAA;AAAA,MAClB;AAAA,IACJ;AAAA,EACJ,CACH;AAGD,SACI,gBAAAS;AAAA,IAAC;AAAA,IAAA;AAAA,MACG,KAAKX;AAAA,MACJ,GAAGJ;AAAA,MACJ,WAAWC;AAAA,MACX,cAAcS;AAAA,MACd,cAAcC;AAAA,MAGd,UAAA;AAAA,QAAA,gBAAAI,EAAC,KAAA,EAAE,WAAU,iBAAgB,MAAK,YAC9B,UAAA;AAAA,UAAA,gBAAAC,EAAC,QAAA,EAAK,WAAU,sBAAsB,UAAApB,GAAM;AAAA,UAC5C,gBAAAoB,EAAC,QAAA,EAAK,WAAU,kCAAA,CAAkC;AAAA,QAAA,GACtD;AAAA,QAECR,KAAW,CAACV,KACT,gBAAAkB,EAACC,GAAA,EAAa,KAAKV,GAAuB,OAAOK,EAAO,QAAS,GAAGC,EAAW,QAC3E,UAAA,gBAAAG,EAACE,GAAA,EAAU,OAAArB,GAAc,EAAA,CAC7B;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAIhB;"}
1
+ {"version":3,"file":"DropdownSubmenu.js","sources":["../../../src/components/dropdown/DropdownSubmenu.tsx"],"sourcesContent":["import type React from 'react';\nimport { useState } from 'react';\nimport classNames from 'classnames';\nimport { usePopper } from 'react-popper';\n\nimport MenuItems from '../menuItems/MenuItems';\nimport MenuItemList from '../menuItems/MenuItemList';\nimport type { MenuItemProps as MenuItem } from '../menuItems/MenuItem';\n\nexport type DropdownSubmenuProps = {\n /**\n * Displayed button title.\n *\n * @default ''\n */\n title?: string | React.ReactNode;\n\n /**\n * Items to display in the dropdown sub menu.\n */\n items?: MenuItem[];\n\n /**\n * Disables every entry on the title list item.\n *\n * @default false\n */\n disabled?: boolean;\n\n /**\n * Additional classes to be set on the dropdown-submenu element.\n */\n className?: string;\n};\n\nconst DropdownSubmenu = (props: DropdownSubmenuProps) => {\n const { title = '', items = [], disabled = false, className, ...remainingProps } = props;\n\n const classes = classNames('dropdown-submenu', disabled && 'disabled', className);\n\n const [refParentPopper, setRefParentPopper] = useState<HTMLLIElement | null>(null);\n const [refDropdownSubmenu, setRefDropdownSubmenu] = useState<HTMLUListElement | null>(null);\n\n // We have to use the workaround of checking the hover state as popper may render\n // the sub menu on an odd place and fixes it's position on the next render cycle\n const [isHover, setIsHover] = useState(false);\n const handleMouseEnter = () => setIsHover(true);\n const handleMouseLeave = () => setIsHover(false);\n\n const { styles, attributes } = usePopper(refParentPopper, refDropdownSubmenu, {\n placement: 'right-start',\n modifiers: [\n {\n name: 'offset',\n options: {\n offset: [-4, 0],\n },\n },\n ],\n });\n\n // return a list item that is also automatically the new toggle for the submenu\n return (\n <li\n ref={setRefParentPopper}\n {...remainingProps}\n className={classes}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n >\n {/* biome-ignore lint/a11y/useValidAnchor: <explanation> */}\n <a className='submenu-title' role='menuitem'>\n <span className='submenu-title-text'>{title}</span>\n <span className='rioglyph rioglyph-chevron-right' />\n </a>\n {/* The actual submenu items */}\n {isHover && !disabled && (\n <MenuItemList ref={setRefDropdownSubmenu} style={styles.popper} {...attributes.popper}>\n <MenuItems items={items} />\n </MenuItemList>\n )}\n </li>\n );\n};\n\nexport default DropdownSubmenu;\n"],"names":["DropdownSubmenu","props","title","items","disabled","className","remainingProps","classes","classNames","refParentPopper","setRefParentPopper","useState","refDropdownSubmenu","setRefDropdownSubmenu","isHover","setIsHover","handleMouseEnter","handleMouseLeave","styles","attributes","usePopper","jsxs","jsx","MenuItemList","MenuItems"],"mappings":";;;;;;AAmCA,MAAMA,IAAkB,CAACC,MAAgC;AACrD,QAAM,EAAE,OAAAC,IAAQ,IAAI,OAAAC,IAAQ,CAAA,GAAI,UAAAC,IAAW,IAAO,WAAAC,GAAW,GAAGC,EAAA,IAAmBL,GAE7EM,IAAUC,EAAW,oBAAoBJ,KAAY,YAAYC,CAAS,GAE1E,CAACI,GAAiBC,CAAkB,IAAIC,EAA+B,IAAI,GAC3E,CAACC,GAAoBC,CAAqB,IAAIF,EAAkC,IAAI,GAIpF,CAACG,GAASC,CAAU,IAAIJ,EAAS,EAAK,GACtCK,IAAmB,MAAMD,EAAW,EAAI,GACxCE,IAAmB,MAAMF,EAAW,EAAK,GAEzC,EAAE,QAAAG,GAAQ,YAAAC,EAAA,IAAeC,EAAUX,GAAiBG,GAAoB;AAAA,IAC1E,WAAW;AAAA,IACX,WAAW;AAAA,MACP;AAAA,QACI,MAAM;AAAA,QACN,SAAS;AAAA,UACL,QAAQ,CAAC,IAAI,CAAC;AAAA,QAAA;AAAA,MAClB;AAAA,IACJ;AAAA,EACJ,CACH;AAGD,SACI,gBAAAS;AAAA,IAAC;AAAA,IAAA;AAAA,MACG,KAAKX;AAAA,MACJ,GAAGJ;AAAA,MACJ,WAAWC;AAAA,MACX,cAAcS;AAAA,MACd,cAAcC;AAAA,MAGd,UAAA;AAAA,QAAA,gBAAAI,EAAC,KAAA,EAAE,WAAU,iBAAgB,MAAK,YAC9B,UAAA;AAAA,UAAA,gBAAAC,EAAC,QAAA,EAAK,WAAU,sBAAsB,UAAApB,GAAM;AAAA,UAC5C,gBAAAoB,EAAC,QAAA,EAAK,WAAU,kCAAA,CAAkC;AAAA,QAAA,GACtD;AAAA,QAECR,KAAW,CAACV,KACT,gBAAAkB,EAACC,GAAA,EAAa,KAAKV,GAAuB,OAAOK,EAAO,QAAS,GAAGC,EAAW,QAC3E,UAAA,gBAAAG,EAACE,GAAA,EAAU,OAAArB,GAAc,EAAA,CAC7B;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAIhB;"}
@@ -2,11 +2,13 @@ import { default as React, PropsWithChildren } from 'react';
2
2
  export type EditableContentProps = {
3
3
  /**
4
4
  * Visibility flag used to control edit mode from outside.
5
+ *
5
6
  * @default undefined
6
7
  */
7
8
  show?: boolean;
8
9
  /**
9
10
  * Callback function triggered when the save button is clicked.
11
+ *
10
12
  * @param value
11
13
  * @returns
12
14
  */
@@ -50,23 +52,27 @@ export type EditableContentProps = {
50
52
  /**
51
53
  * Offset value to control the vertical position for the editor in case the text element has
52
54
  * borders, spacings different text sizes.
55
+ *
53
56
  * @default 0
54
57
  */
55
58
  editorOffsetTop?: number;
56
59
  /**
57
60
  * Offset value to control the horizontal position for the editor in case the text element has
58
61
  * borders, spacings different text sizes.
62
+ *
59
63
  * @default 0
60
64
  */
61
65
  editorOffsetLeft?: number;
62
66
  /**
63
67
  * Defines the input and button size. Use 'lg' for headlines.
68
+ *
64
69
  * @default 'md'
65
70
  */
66
71
  size?: 'md' | 'lg';
67
72
  /**
68
73
  * Defines if the internal textarea is allowed to resize vertically.
69
74
  * This comes in handy for larger text and when using multiple input rows.
75
+ *
70
76
  * @default false
71
77
  */
72
78
  allowResize?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"EditableContent.js","sources":["../../../src/components/editableContent/EditableContent.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect, useMemo, type PropsWithChildren, type CSSProperties } from 'react';\nimport { noop } from 'es-toolkit/function';\nimport classNames from 'classnames';\nimport { usePopper } from 'react-popper';\nimport { createPortal } from 'react-dom';\nimport type { Options, Rect, StrictModifiers } from '@popperjs/core';\n\nimport { getOrCreatePortalRoot } from '../../utils/portalRoot';\nimport useEsc from '../../hooks/useEsc';\nimport useFocusTrap from '../../hooks/useFocusTrap';\n\n// Features\n// [x] Hide children with opacity 0\n// [x] Allow custom editor elements\n// [x] Use textarea for longer text\n// [x] Use focus trap\n// [x] Keyboard support mit esc and tab+enter to accept\n// [-] If space, get the width of the text to make the input larger - no nice solution\n// [x] Control edit mode from outside\n\n// This offset takes into account the padding of the overlay and the padding/border of the edit component (input).\n// This works best if the text is wrapped within a single <span> tag and has a dotted bottom border only.\n// External offset defined by the using component will be starting from 0 for easier understanding.\nconst POPOVER_OFFSET_TOP = -13;\nconst POPOVER_OFFSET_LEFT = -18;\n\nconst DEFAULT_TEXTAREA_ROWS = 1;\n\nexport type EditableContentProps = {\n /**\n * Visibility flag used to control edit mode from outside.\n * @default undefined\n */\n show?: boolean;\n\n /**\n * Callback function triggered when the save button is clicked.\n * @param value\n * @returns\n */\n onSave?: (value: string) => void;\n\n /**\n * Callback function triggered when the cancel button is clicked.\n */\n onCancel?: VoidFunction;\n\n /**\n * Callback function triggered when the input gets focused.\n */\n onFocus?: VoidFunction;\n\n /**\n * Callback function triggered when input looses it's focus.\n */\n onBlur?: VoidFunction;\n\n /**\n * Callback function triggered when entering the edit mode.\n */\n onEditMode?: VoidFunction;\n\n /**\n * Validation function to intercept saving and prevent save on error.\n */\n onSaveValidation?: (value: string) => boolean;\n\n /**\n * Controls the error message visibility from outside. This is useful when using a custom input\n * where the validation happens outside of this component.\n * @default true\n */\n isValid?: boolean;\n\n /**\n * The error message that shall be shown to the user in case the validation fails.\n */\n errorMessage?: React.ReactNode;\n\n /**\n * Use this prop to define a custom editor input component like Select, NumberInput, TimePicker or DatePicker.\n * Handling input state changes of a custom editor need to be handled outside of this component.\n * By default the EditableContent uses a built-in textarea to allow resizing for larger text.\n */\n customEditor?: React.ReactNode;\n\n /**\n * Offset value to control the vertical position for the editor in case the text element has\n * borders, spacings different text sizes.\n * @default 0\n */\n editorOffsetTop?: number;\n\n /**\n * Offset value to control the horizontal position for the editor in case the text element has\n * borders, spacings different text sizes.\n * @default 0\n */\n editorOffsetLeft?: number;\n\n /**\n * Defines the input and button size. Use 'lg' for headlines.\n * @default 'md'\n */\n size?: 'md' | 'lg';\n\n /**\n * Defines if the internal textarea is allowed to resize vertically.\n * This comes in handy for larger text and when using multiple input rows.\n * @default false\n */\n allowResize?: boolean;\n\n /**\n * Defines the number of rows to use by the internal textarea component.\n * When a single line is used, the input is saved on \"enter\" key.\n *\n * @default 1\n */\n inputRows?: number;\n\n /**\n * Additional classes to be set on the editor input itself.\n */\n inputClassName?: string;\n\n /**\n * Additional classes to be set on the editor wrapper element.\n */\n editorClassName?: string;\n\n /**\n * Additional classes to be set on the text wrapper element.\n */\n className?: string;\n};\n\nconst EditableContent = (props: PropsWithChildren<EditableContentProps>) => {\n const {\n show = undefined,\n onSave = noop,\n onCancel = noop,\n onFocus = noop,\n onBlur = noop,\n onEditMode = noop,\n onSaveValidation = () => true,\n isValid = true,\n errorMessage,\n allowResize = false,\n inputRows = DEFAULT_TEXTAREA_ROWS,\n editorOffsetTop = 0,\n editorOffsetLeft = 0,\n customEditor,\n size = 'md',\n className = '',\n inputClassName = '',\n editorClassName = '',\n children,\n ...remainingProps\n } = props;\n\n const [isEditMode, setIsEditMode] = useState(show);\n const [inputValue, setInputValue] = useState('');\n const [hasError, setHasError] = useState(!isValid);\n\n const [referenceElement, setReferenceElement] = useState<HTMLSpanElement | null>(null);\n const [popperElement, setPopperElement] = useState<HTMLDivElement | null>(null);\n\n const hasCustomControl = !!customEditor;\n\n // Close edit mode on \"esc\"\n useEsc(() => handleCloseEditMode());\n\n // Trap focus on the popper element\n useFocusTrap(popperElement);\n\n // Input ref used to focus inside when entering edit mode\n const inputRef = useRef<HTMLTextAreaElement>(null);\n\n useEffect(() => {\n if (inputRef.current && isEditMode) {\n inputRef.current?.focus();\n inputRef.current?.select();\n }\n }, [isEditMode, inputRef.current]);\n\n const customModifier = useMemo(\n () => ({\n name: 'offset',\n options: {\n offset: ({ reference }: { reference: Rect }) => {\n const leftOffset = POPOVER_OFFSET_LEFT + editorOffsetLeft;\n const topOffset = -(reference.height - (POPOVER_OFFSET_TOP + editorOffsetTop));\n return [leftOffset, topOffset];\n },\n },\n }),\n []\n );\n\n const popperConfig: Options = {\n placement: 'bottom-start',\n modifiers: [customModifier],\n strategy: 'absolute',\n };\n\n const { styles, attributes } = usePopper<StrictModifiers>(referenceElement, popperElement, popperConfig);\n\n const handleEditMode = () => {\n // In a controlled usage, the \"show\" property is set from the outside\n // and the edit mode is handled there\n if (show === undefined) {\n enterEditMode();\n }\n onEditMode();\n };\n\n const enterEditMode = () => {\n setIsEditMode(true);\n setInputValue(referenceElement?.textContent?.trimEnd() ?? '');\n setHasError(false);\n };\n\n const handleInputChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {\n setInputValue(event.target.value);\n };\n\n const handleKeyDown = (event: React.KeyboardEvent) => {\n // Prevent line breaks when textarea is a single line\n if (event.key === 'Enter' && inputRows === DEFAULT_TEXTAREA_ROWS) {\n event.preventDefault();\n\n // Save on \"enter\" when textarea has a single line\n handleSaveChanges();\n }\n };\n\n const handleCloseEditMode = () => {\n setIsEditMode(false);\n onCancel();\n };\n\n const handleSaveChanges = () => {\n const isInputValid = onSaveValidation(inputValue);\n setHasError(!isInputValid);\n\n if (isInputValid) {\n setIsEditMode(false);\n onSave(inputValue.trimEnd());\n }\n };\n\n // Control edit mode from outside for instance if text element got focus\n // and user used \"Enter\" key to enter edit mode.\n const [previousShow, setPreviousShow] = useState(show);\n if (show !== previousShow) {\n if (show) {\n enterEditMode();\n }\n if (!show) {\n setIsEditMode(false);\n }\n setPreviousShow(show);\n }\n\n // Control error message visibility from outside. This is useful when using a custom input\n // where the validation happens outside of this component.\n const [previousIsValid, setPreviousIsValid] = useState(isValid);\n if (isValid !== previousIsValid) {\n setHasError(!isValid);\n setPreviousIsValid(isValid);\n }\n\n const textWrapperClasses = classNames(className, isEditMode && 'opacity-0');\n\n const overlayWrapperClasses = classNames(\n 'EditableContentEditor',\n 'display-flex gap-5',\n 'padding-5',\n 'rounded',\n 'shadow-accent',\n 'z-index-max',\n 'bg-white',\n editorClassName\n );\n\n const inputWrapperClasses = classNames(\n 'display-flex flex-column gap-5',\n 'margin-0',\n 'form-group',\n hasError && 'has-feedback has-error'\n );\n\n const inputClasses = classNames('form-control', size === 'lg' && 'input-lg', inputClassName);\n\n const inputStyle: CSSProperties = {\n minWidth: '100px',\n resize: allowResize ? 'vertical' : 'none',\n };\n\n return (\n <>\n <span ref={setReferenceElement} onClick={handleEditMode} className={textWrapperClasses}>\n {children}\n </span>\n {isEditMode &&\n createPortal(\n <div\n className={overlayWrapperClasses}\n onClick={event => event.stopPropagation()}\n ref={setPopperElement}\n style={styles.popper}\n {...attributes.popper}\n {...remainingProps}\n >\n <div className={inputWrapperClasses}>\n {hasCustomControl && customEditor}\n {!hasCustomControl && (\n <textarea\n ref={inputRef}\n className={inputClasses}\n value={inputValue}\n onChange={handleInputChange}\n onFocus={onFocus}\n onBlur={onBlur}\n onKeyDown={handleKeyDown}\n style={inputStyle}\n rows={inputRows}\n />\n )}\n {hasError && <div className='help-block position-relative'>{errorMessage}</div>}\n </div>\n <div className='display-flex gap-5'>\n <button\n type='button'\n onClick={handleCloseEditMode}\n className={`EditableContentCancel btn btn-default btn-icon-only btn-${size}`}\n aria-label='EditableContent cancel button'\n data-testid='EditableContentCancel'\n >\n <span className='rioglyph rioglyph-remove' />\n </button>\n <button\n type='button'\n onClick={handleSaveChanges}\n className={`EditableContentSave btn btn-primary btn-icon-only btn-${size}`}\n aria-label='EditableContent save button'\n data-testid='EditableContentSave'\n >\n <span className='rioglyph rioglyph-ok' />\n </button>\n </div>\n </div>,\n getOrCreatePortalRoot()\n )}\n </>\n );\n};\n\nexport default EditableContent;\n"],"names":["POPOVER_OFFSET_TOP","POPOVER_OFFSET_LEFT","DEFAULT_TEXTAREA_ROWS","EditableContent","props","show","onSave","noop","onCancel","onFocus","onBlur","onEditMode","onSaveValidation","isValid","errorMessage","allowResize","inputRows","editorOffsetTop","editorOffsetLeft","customEditor","size","className","inputClassName","editorClassName","children","remainingProps","isEditMode","setIsEditMode","useState","inputValue","setInputValue","hasError","setHasError","referenceElement","setReferenceElement","popperElement","setPopperElement","hasCustomControl","useEsc","handleCloseEditMode","useFocusTrap","inputRef","useRef","useEffect","popperConfig","useMemo","reference","leftOffset","topOffset","styles","attributes","usePopper","handleEditMode","enterEditMode","handleInputChange","event","handleKeyDown","handleSaveChanges","isInputValid","previousShow","setPreviousShow","previousIsValid","setPreviousIsValid","textWrapperClasses","classNames","overlayWrapperClasses","inputWrapperClasses","inputClasses","inputStyle","jsxs","Fragment","jsx","createPortal","getOrCreatePortalRoot"],"mappings":"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"}
1
+ {"version":3,"file":"EditableContent.js","sources":["../../../src/components/editableContent/EditableContent.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect, useMemo, type PropsWithChildren, type CSSProperties } from 'react';\nimport { noop } from 'es-toolkit/function';\nimport classNames from 'classnames';\nimport { usePopper } from 'react-popper';\nimport { createPortal } from 'react-dom';\nimport type { Options, Rect, StrictModifiers } from '@popperjs/core';\n\nimport { getOrCreatePortalRoot } from '../../utils/portalRoot';\nimport useEsc from '../../hooks/useEsc';\nimport useFocusTrap from '../../hooks/useFocusTrap';\n\n// Features\n// [x] Hide children with opacity 0\n// [x] Allow custom editor elements\n// [x] Use textarea for longer text\n// [x] Use focus trap\n// [x] Keyboard support mit esc and tab+enter to accept\n// [-] If space, get the width of the text to make the input larger - no nice solution\n// [x] Control edit mode from outside\n\n// This offset takes into account the padding of the overlay and the padding/border of the edit component (input).\n// This works best if the text is wrapped within a single <span> tag and has a dotted bottom border only.\n// External offset defined by the using component will be starting from 0 for easier understanding.\nconst POPOVER_OFFSET_TOP = -13;\nconst POPOVER_OFFSET_LEFT = -18;\n\nconst DEFAULT_TEXTAREA_ROWS = 1;\n\nexport type EditableContentProps = {\n /**\n * Visibility flag used to control edit mode from outside.\n *\n * @default undefined\n */\n show?: boolean;\n\n /**\n * Callback function triggered when the save button is clicked.\n *\n * @param value\n * @returns\n */\n onSave?: (value: string) => void;\n\n /**\n * Callback function triggered when the cancel button is clicked.\n */\n onCancel?: VoidFunction;\n\n /**\n * Callback function triggered when the input gets focused.\n */\n onFocus?: VoidFunction;\n\n /**\n * Callback function triggered when input looses it's focus.\n */\n onBlur?: VoidFunction;\n\n /**\n * Callback function triggered when entering the edit mode.\n */\n onEditMode?: VoidFunction;\n\n /**\n * Validation function to intercept saving and prevent save on error.\n */\n onSaveValidation?: (value: string) => boolean;\n\n /**\n * Controls the error message visibility from outside. This is useful when using a custom input\n * where the validation happens outside of this component.\n * @default true\n */\n isValid?: boolean;\n\n /**\n * The error message that shall be shown to the user in case the validation fails.\n */\n errorMessage?: React.ReactNode;\n\n /**\n * Use this prop to define a custom editor input component like Select, NumberInput, TimePicker or DatePicker.\n * Handling input state changes of a custom editor need to be handled outside of this component.\n * By default the EditableContent uses a built-in textarea to allow resizing for larger text.\n */\n customEditor?: React.ReactNode;\n\n /**\n * Offset value to control the vertical position for the editor in case the text element has\n * borders, spacings different text sizes.\n *\n * @default 0\n */\n editorOffsetTop?: number;\n\n /**\n * Offset value to control the horizontal position for the editor in case the text element has\n * borders, spacings different text sizes.\n *\n * @default 0\n */\n editorOffsetLeft?: number;\n\n /**\n * Defines the input and button size. Use 'lg' for headlines.\n *\n * @default 'md'\n */\n size?: 'md' | 'lg';\n\n /**\n * Defines if the internal textarea is allowed to resize vertically.\n * This comes in handy for larger text and when using multiple input rows.\n *\n * @default false\n */\n allowResize?: boolean;\n\n /**\n * Defines the number of rows to use by the internal textarea component.\n * When a single line is used, the input is saved on \"enter\" key.\n *\n * @default 1\n */\n inputRows?: number;\n\n /**\n * Additional classes to be set on the editor input itself.\n */\n inputClassName?: string;\n\n /**\n * Additional classes to be set on the editor wrapper element.\n */\n editorClassName?: string;\n\n /**\n * Additional classes to be set on the text wrapper element.\n */\n className?: string;\n};\n\nconst EditableContent = (props: PropsWithChildren<EditableContentProps>) => {\n const {\n show = undefined,\n onSave = noop,\n onCancel = noop,\n onFocus = noop,\n onBlur = noop,\n onEditMode = noop,\n onSaveValidation = () => true,\n isValid = true,\n errorMessage,\n allowResize = false,\n inputRows = DEFAULT_TEXTAREA_ROWS,\n editorOffsetTop = 0,\n editorOffsetLeft = 0,\n customEditor,\n size = 'md',\n className = '',\n inputClassName = '',\n editorClassName = '',\n children,\n ...remainingProps\n } = props;\n\n const [isEditMode, setIsEditMode] = useState(show);\n const [inputValue, setInputValue] = useState('');\n const [hasError, setHasError] = useState(!isValid);\n\n const [referenceElement, setReferenceElement] = useState<HTMLSpanElement | null>(null);\n const [popperElement, setPopperElement] = useState<HTMLDivElement | null>(null);\n\n const hasCustomControl = !!customEditor;\n\n // Close edit mode on \"esc\"\n useEsc(() => handleCloseEditMode());\n\n // Trap focus on the popper element\n useFocusTrap(popperElement);\n\n // Input ref used to focus inside when entering edit mode\n const inputRef = useRef<HTMLTextAreaElement>(null);\n\n useEffect(() => {\n if (inputRef.current && isEditMode) {\n inputRef.current?.focus();\n inputRef.current?.select();\n }\n }, [isEditMode, inputRef.current]);\n\n const customModifier = useMemo(\n () => ({\n name: 'offset',\n options: {\n offset: ({ reference }: { reference: Rect }) => {\n const leftOffset = POPOVER_OFFSET_LEFT + editorOffsetLeft;\n const topOffset = -(reference.height - (POPOVER_OFFSET_TOP + editorOffsetTop));\n return [leftOffset, topOffset];\n },\n },\n }),\n []\n );\n\n const popperConfig: Options = {\n placement: 'bottom-start',\n modifiers: [customModifier],\n strategy: 'absolute',\n };\n\n const { styles, attributes } = usePopper<StrictModifiers>(referenceElement, popperElement, popperConfig);\n\n const handleEditMode = () => {\n // In a controlled usage, the \"show\" property is set from the outside\n // and the edit mode is handled there\n if (show === undefined) {\n enterEditMode();\n }\n onEditMode();\n };\n\n const enterEditMode = () => {\n setIsEditMode(true);\n setInputValue(referenceElement?.textContent?.trimEnd() ?? '');\n setHasError(false);\n };\n\n const handleInputChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {\n setInputValue(event.target.value);\n };\n\n const handleKeyDown = (event: React.KeyboardEvent) => {\n // Prevent line breaks when textarea is a single line\n if (event.key === 'Enter' && inputRows === DEFAULT_TEXTAREA_ROWS) {\n event.preventDefault();\n\n // Save on \"enter\" when textarea has a single line\n handleSaveChanges();\n }\n };\n\n const handleCloseEditMode = () => {\n setIsEditMode(false);\n onCancel();\n };\n\n const handleSaveChanges = () => {\n const isInputValid = onSaveValidation(inputValue);\n setHasError(!isInputValid);\n\n if (isInputValid) {\n setIsEditMode(false);\n onSave(inputValue.trimEnd());\n }\n };\n\n // Control edit mode from outside for instance if text element got focus\n // and user used \"Enter\" key to enter edit mode.\n const [previousShow, setPreviousShow] = useState(show);\n if (show !== previousShow) {\n if (show) {\n enterEditMode();\n }\n if (!show) {\n setIsEditMode(false);\n }\n setPreviousShow(show);\n }\n\n // Control error message visibility from outside. This is useful when using a custom input\n // where the validation happens outside of this component.\n const [previousIsValid, setPreviousIsValid] = useState(isValid);\n if (isValid !== previousIsValid) {\n setHasError(!isValid);\n setPreviousIsValid(isValid);\n }\n\n const textWrapperClasses = classNames(className, isEditMode && 'opacity-0');\n\n const overlayWrapperClasses = classNames(\n 'EditableContentEditor',\n 'display-flex gap-5',\n 'padding-5',\n 'rounded',\n 'shadow-accent',\n 'z-index-max',\n 'bg-white',\n editorClassName\n );\n\n const inputWrapperClasses = classNames(\n 'display-flex flex-column gap-5',\n 'margin-0',\n 'form-group',\n hasError && 'has-feedback has-error'\n );\n\n const inputClasses = classNames('form-control', size === 'lg' && 'input-lg', inputClassName);\n\n const inputStyle: CSSProperties = {\n minWidth: '100px',\n resize: allowResize ? 'vertical' : 'none',\n };\n\n return (\n <>\n <span ref={setReferenceElement} onClick={handleEditMode} className={textWrapperClasses}>\n {children}\n </span>\n {isEditMode &&\n createPortal(\n <div\n className={overlayWrapperClasses}\n onClick={event => event.stopPropagation()}\n ref={setPopperElement}\n style={styles.popper}\n {...attributes.popper}\n {...remainingProps}\n >\n <div className={inputWrapperClasses}>\n {hasCustomControl && customEditor}\n {!hasCustomControl && (\n <textarea\n ref={inputRef}\n className={inputClasses}\n value={inputValue}\n onChange={handleInputChange}\n onFocus={onFocus}\n onBlur={onBlur}\n onKeyDown={handleKeyDown}\n style={inputStyle}\n rows={inputRows}\n />\n )}\n {hasError && <div className='help-block position-relative'>{errorMessage}</div>}\n </div>\n <div className='display-flex gap-5'>\n <button\n type='button'\n onClick={handleCloseEditMode}\n className={`EditableContentCancel btn btn-default btn-icon-only btn-${size}`}\n aria-label='EditableContent cancel button'\n data-testid='EditableContentCancel'\n >\n <span className='rioglyph rioglyph-remove' />\n </button>\n <button\n type='button'\n onClick={handleSaveChanges}\n className={`EditableContentSave btn btn-primary btn-icon-only btn-${size}`}\n aria-label='EditableContent save button'\n data-testid='EditableContentSave'\n >\n <span className='rioglyph rioglyph-ok' />\n </button>\n </div>\n </div>,\n getOrCreatePortalRoot()\n )}\n </>\n );\n};\n\nexport default EditableContent;\n"],"names":["POPOVER_OFFSET_TOP","POPOVER_OFFSET_LEFT","DEFAULT_TEXTAREA_ROWS","EditableContent","props","show","onSave","noop","onCancel","onFocus","onBlur","onEditMode","onSaveValidation","isValid","errorMessage","allowResize","inputRows","editorOffsetTop","editorOffsetLeft","customEditor","size","className","inputClassName","editorClassName","children","remainingProps","isEditMode","setIsEditMode","useState","inputValue","setInputValue","hasError","setHasError","referenceElement","setReferenceElement","popperElement","setPopperElement","hasCustomControl","useEsc","handleCloseEditMode","useFocusTrap","inputRef","useRef","useEffect","popperConfig","useMemo","reference","leftOffset","topOffset","styles","attributes","usePopper","handleEditMode","enterEditMode","handleInputChange","event","handleKeyDown","handleSaveChanges","isInputValid","previousShow","setPreviousShow","previousIsValid","setPreviousIsValid","textWrapperClasses","classNames","overlayWrapperClasses","inputWrapperClasses","inputClasses","inputStyle","jsxs","Fragment","jsx","createPortal","getOrCreatePortalRoot"],"mappings":"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"}
@@ -46,17 +46,20 @@ export type ExpanderListProps = {
46
46
  items: ExpanderListItem[];
47
47
  /**
48
48
  * Defines whether the "expander-list-body" is rounded or not.
49
+ *
49
50
  * @default true
50
51
  */
51
52
  rounded?: boolean;
52
53
  /**
53
54
  * Defines whether the "expander-list-body" has a border or not.
55
+ *
54
56
  * @default true
55
57
  */
56
58
  bordered?: boolean;
57
59
  /**
58
60
  * It unmounts the body component (remove it from the DOM) when it is collapsed.
59
61
  * Set it to false to avoid the unmount.
62
+ *
60
63
  * @default true
61
64
  */
62
65
  unmountOnExit?: boolean;