@helpwave/hightide 0.1.21 → 0.1.22

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 (193) hide show
  1. package/dist/components/date/DatePicker.js +11 -1
  2. package/dist/components/date/DatePicker.js.map +1 -1
  3. package/dist/components/date/DatePicker.mjs +11 -1
  4. package/dist/components/date/DatePicker.mjs.map +1 -1
  5. package/dist/components/date/DayPicker.js.map +1 -1
  6. package/dist/components/date/DayPicker.mjs.map +1 -1
  7. package/dist/components/date/TimeDisplay.js.map +1 -1
  8. package/dist/components/date/TimeDisplay.mjs.map +1 -1
  9. package/dist/components/date/YearMonthPicker.js +1 -0
  10. package/dist/components/date/YearMonthPicker.js.map +1 -1
  11. package/dist/components/date/YearMonthPicker.mjs +1 -0
  12. package/dist/components/date/YearMonthPicker.mjs.map +1 -1
  13. package/dist/components/dialogs/ConfirmDialog.js +2 -1
  14. package/dist/components/dialogs/ConfirmDialog.js.map +1 -1
  15. package/dist/components/dialogs/ConfirmDialog.mjs +2 -1
  16. package/dist/components/dialogs/ConfirmDialog.mjs.map +1 -1
  17. package/dist/components/icons-and-geometry/Avatar.d.mts +17 -7
  18. package/dist/components/icons-and-geometry/Avatar.d.ts +17 -7
  19. package/dist/components/icons-and-geometry/Avatar.js +103 -42
  20. package/dist/components/icons-and-geometry/Avatar.js.map +1 -1
  21. package/dist/components/icons-and-geometry/Avatar.mjs +102 -40
  22. package/dist/components/icons-and-geometry/Avatar.mjs.map +1 -1
  23. package/dist/components/layout-and-navigation/Carousel.js +1 -0
  24. package/dist/components/layout-and-navigation/Carousel.js.map +1 -1
  25. package/dist/components/layout-and-navigation/Carousel.mjs +1 -0
  26. package/dist/components/layout-and-navigation/Carousel.mjs.map +1 -1
  27. package/dist/components/layout-and-navigation/Chip.d.mts +6 -2
  28. package/dist/components/layout-and-navigation/Chip.d.ts +6 -2
  29. package/dist/components/layout-and-navigation/Chip.js +8 -2
  30. package/dist/components/layout-and-navigation/Chip.js.map +1 -1
  31. package/dist/components/layout-and-navigation/Chip.mjs +6 -1
  32. package/dist/components/layout-and-navigation/Chip.mjs.map +1 -1
  33. package/dist/components/layout-and-navigation/Overlay.js +3 -2
  34. package/dist/components/layout-and-navigation/Overlay.js.map +1 -1
  35. package/dist/components/layout-and-navigation/Overlay.mjs +3 -2
  36. package/dist/components/layout-and-navigation/Overlay.mjs.map +1 -1
  37. package/dist/components/layout-and-navigation/Pagination.js +3 -2
  38. package/dist/components/layout-and-navigation/Pagination.js.map +1 -1
  39. package/dist/components/layout-and-navigation/Pagination.mjs +3 -2
  40. package/dist/components/layout-and-navigation/Pagination.mjs.map +1 -1
  41. package/dist/components/layout-and-navigation/SearchableList.js +2 -1
  42. package/dist/components/layout-and-navigation/SearchableList.js.map +1 -1
  43. package/dist/components/layout-and-navigation/SearchableList.mjs +2 -1
  44. package/dist/components/layout-and-navigation/SearchableList.mjs.map +1 -1
  45. package/dist/components/layout-and-navigation/StepperBar.js +1 -0
  46. package/dist/components/layout-and-navigation/StepperBar.js.map +1 -1
  47. package/dist/components/layout-and-navigation/StepperBar.mjs +1 -0
  48. package/dist/components/layout-and-navigation/StepperBar.mjs.map +1 -1
  49. package/dist/components/layout-and-navigation/TextImage.js.map +1 -1
  50. package/dist/components/layout-and-navigation/TextImage.mjs.map +1 -1
  51. package/dist/components/loading-states/ErrorComponent.js.map +1 -1
  52. package/dist/components/loading-states/ErrorComponent.mjs.map +1 -1
  53. package/dist/components/loading-states/LoadingAnimation.js.map +1 -1
  54. package/dist/components/loading-states/LoadingAnimation.mjs.map +1 -1
  55. package/dist/components/loading-states/LoadingButton.js +1 -0
  56. package/dist/components/loading-states/LoadingButton.js.map +1 -1
  57. package/dist/components/loading-states/LoadingButton.mjs +1 -0
  58. package/dist/components/loading-states/LoadingButton.mjs.map +1 -1
  59. package/dist/components/modals/ConfirmModal.js +2 -1
  60. package/dist/components/modals/ConfirmModal.js.map +1 -1
  61. package/dist/components/modals/ConfirmModal.mjs +2 -1
  62. package/dist/components/modals/ConfirmModal.mjs.map +1 -1
  63. package/dist/components/modals/DiscardChangesModal.js +2 -1
  64. package/dist/components/modals/DiscardChangesModal.js.map +1 -1
  65. package/dist/components/modals/DiscardChangesModal.mjs +2 -1
  66. package/dist/components/modals/DiscardChangesModal.mjs.map +1 -1
  67. package/dist/components/modals/InputModal.js +3 -2
  68. package/dist/components/modals/InputModal.js.map +1 -1
  69. package/dist/components/modals/InputModal.mjs +3 -2
  70. package/dist/components/modals/InputModal.mjs.map +1 -1
  71. package/dist/components/modals/LanguageModal.js +5 -4
  72. package/dist/components/modals/LanguageModal.js.map +1 -1
  73. package/dist/components/modals/LanguageModal.mjs +6 -9
  74. package/dist/components/modals/LanguageModal.mjs.map +1 -1
  75. package/dist/components/modals/ThemeModal.js +11 -7
  76. package/dist/components/modals/ThemeModal.js.map +1 -1
  77. package/dist/components/modals/ThemeModal.mjs +10 -10
  78. package/dist/components/modals/ThemeModal.mjs.map +1 -1
  79. package/dist/components/properties/CheckboxProperty.js +13 -3
  80. package/dist/components/properties/CheckboxProperty.js.map +1 -1
  81. package/dist/components/properties/CheckboxProperty.mjs +13 -3
  82. package/dist/components/properties/CheckboxProperty.mjs.map +1 -1
  83. package/dist/components/properties/DateProperty.js +13 -3
  84. package/dist/components/properties/DateProperty.js.map +1 -1
  85. package/dist/components/properties/DateProperty.mjs +13 -3
  86. package/dist/components/properties/DateProperty.mjs.map +1 -1
  87. package/dist/components/properties/MultiSelectProperty.js +18 -8
  88. package/dist/components/properties/MultiSelectProperty.js.map +1 -1
  89. package/dist/components/properties/MultiSelectProperty.mjs +19 -13
  90. package/dist/components/properties/MultiSelectProperty.mjs.map +1 -1
  91. package/dist/components/properties/NumberProperty.js +13 -3
  92. package/dist/components/properties/NumberProperty.js.map +1 -1
  93. package/dist/components/properties/NumberProperty.mjs +13 -3
  94. package/dist/components/properties/NumberProperty.mjs.map +1 -1
  95. package/dist/components/properties/PropertyBase.js +12 -2
  96. package/dist/components/properties/PropertyBase.js.map +1 -1
  97. package/dist/components/properties/PropertyBase.mjs +12 -2
  98. package/dist/components/properties/PropertyBase.mjs.map +1 -1
  99. package/dist/components/properties/SelectProperty.js +15 -5
  100. package/dist/components/properties/SelectProperty.js.map +1 -1
  101. package/dist/components/properties/SelectProperty.mjs +16 -10
  102. package/dist/components/properties/SelectProperty.mjs.map +1 -1
  103. package/dist/components/properties/TextProperty.js +15 -5
  104. package/dist/components/properties/TextProperty.js.map +1 -1
  105. package/dist/components/properties/TextProperty.mjs +15 -5
  106. package/dist/components/properties/TextProperty.mjs.map +1 -1
  107. package/dist/components/table/Table.js +6 -5
  108. package/dist/components/table/Table.js.map +1 -1
  109. package/dist/components/table/Table.mjs +7 -10
  110. package/dist/components/table/Table.mjs.map +1 -1
  111. package/dist/components/table/TableFilterButton.js +3 -2
  112. package/dist/components/table/TableFilterButton.js.map +1 -1
  113. package/dist/components/table/TableFilterButton.mjs +4 -7
  114. package/dist/components/table/TableFilterButton.mjs.map +1 -1
  115. package/dist/components/table/TableSortButton.js +1 -0
  116. package/dist/components/table/TableSortButton.js.map +1 -1
  117. package/dist/components/table/TableSortButton.mjs +1 -0
  118. package/dist/components/table/TableSortButton.mjs.map +1 -1
  119. package/dist/components/user-action/Button.d.mts +2 -1
  120. package/dist/components/user-action/Button.d.ts +2 -1
  121. package/dist/components/user-action/Button.js +12 -1
  122. package/dist/components/user-action/Button.js.map +1 -1
  123. package/dist/components/user-action/Button.mjs +12 -1
  124. package/dist/components/user-action/Button.mjs.map +1 -1
  125. package/dist/components/user-action/Checkbox.js +1 -1
  126. package/dist/components/user-action/Checkbox.js.map +1 -1
  127. package/dist/components/user-action/Checkbox.mjs +1 -1
  128. package/dist/components/user-action/Checkbox.mjs.map +1 -1
  129. package/dist/components/user-action/CopyToClipboardWrapper.js.map +1 -1
  130. package/dist/components/user-action/CopyToClipboardWrapper.mjs.map +1 -1
  131. package/dist/components/user-action/DateAndTimePicker.js +11 -1
  132. package/dist/components/user-action/DateAndTimePicker.js.map +1 -1
  133. package/dist/components/user-action/DateAndTimePicker.mjs +11 -1
  134. package/dist/components/user-action/DateAndTimePicker.mjs.map +1 -1
  135. package/dist/components/user-action/Input.js +1 -1
  136. package/dist/components/user-action/Input.js.map +1 -1
  137. package/dist/components/user-action/Input.mjs +1 -1
  138. package/dist/components/user-action/Input.mjs.map +1 -1
  139. package/dist/components/user-action/Menu.js +2 -2
  140. package/dist/components/user-action/Menu.js.map +1 -1
  141. package/dist/components/user-action/Menu.mjs +3 -7
  142. package/dist/components/user-action/Menu.mjs.map +1 -1
  143. package/dist/components/user-action/MultiSelect.js +7 -6
  144. package/dist/components/user-action/MultiSelect.js.map +1 -1
  145. package/dist/components/user-action/MultiSelect.mjs +8 -11
  146. package/dist/components/user-action/MultiSelect.mjs.map +1 -1
  147. package/dist/components/user-action/SearchBar.js +2 -1
  148. package/dist/components/user-action/SearchBar.js.map +1 -1
  149. package/dist/components/user-action/SearchBar.mjs +2 -1
  150. package/dist/components/user-action/SearchBar.mjs.map +1 -1
  151. package/dist/components/user-action/Select.js +4 -3
  152. package/dist/components/user-action/Select.js.map +1 -1
  153. package/dist/components/user-action/Select.mjs +5 -8
  154. package/dist/components/user-action/Select.mjs.map +1 -1
  155. package/dist/components/user-action/Textarea.js +3 -3
  156. package/dist/components/user-action/Textarea.js.map +1 -1
  157. package/dist/components/user-action/Textarea.mjs +3 -3
  158. package/dist/components/user-action/Textarea.mjs.map +1 -1
  159. package/dist/css/globals.css +270 -47
  160. package/dist/css/uncompiled/globals.css +2 -2
  161. package/dist/css/uncompiled/theme/colors-basic.css +1 -1
  162. package/dist/css/uncompiled/theme/colors-component.css +9 -13
  163. package/dist/css/uncompiled/theme/colors-semantic.css +8 -3
  164. package/dist/css/uncompiled/utitlity/shadow.css +45 -16
  165. package/dist/hooks/useLocalStorage.js +8 -3
  166. package/dist/hooks/useLocalStorage.js.map +1 -1
  167. package/dist/hooks/useLocalStorage.mjs +8 -3
  168. package/dist/hooks/useLocalStorage.mjs.map +1 -1
  169. package/dist/hooks/useLogOnce.d.mts +8 -0
  170. package/dist/hooks/useLogOnce.d.ts +8 -0
  171. package/dist/hooks/useLogOnce.js +53 -0
  172. package/dist/hooks/useLogOnce.js.map +1 -0
  173. package/dist/hooks/useLogOnce.mjs +29 -0
  174. package/dist/hooks/useLogOnce.mjs.map +1 -0
  175. package/dist/index.d.mts +3 -2
  176. package/dist/index.d.ts +3 -2
  177. package/dist/index.js +285 -206
  178. package/dist/index.js.map +1 -1
  179. package/dist/index.mjs +249 -175
  180. package/dist/index.mjs.map +1 -1
  181. package/dist/localization/LanguageProvider.js +8 -3
  182. package/dist/localization/LanguageProvider.js.map +1 -1
  183. package/dist/localization/LanguageProvider.mjs +8 -3
  184. package/dist/localization/LanguageProvider.mjs.map +1 -1
  185. package/dist/localization/useTranslation.js.map +1 -1
  186. package/dist/localization/useTranslation.mjs.map +1 -1
  187. package/dist/theming/useTheme.d.mts +2 -2
  188. package/dist/theming/useTheme.d.ts +2 -2
  189. package/dist/theming/useTheme.js +26 -22
  190. package/dist/theming/useTheme.js.map +1 -1
  191. package/dist/theming/useTheme.mjs +21 -17
  192. package/dist/theming/useTheme.mjs.map +1 -1
  193. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/user-action/Input.tsx","../../../src/hooks/useDelay.ts","../../../src/util/noop.ts","../../../src/components/user-action/Label.tsx","../../../src/hooks/useFocusManagement.ts","../../../src/hooks/useFocusOnceVisible.ts"],"sourcesContent":["import React, { forwardRef, type InputHTMLAttributes, useEffect, useImperativeHandle, useRef, useState } from 'react'\nimport clsx from 'clsx'\nimport type { UseDelayOptionsResolved } from '../../hooks/useDelay'\nimport { useDelay } from '../../hooks/useDelay'\nimport { noop } from '../../util/noop'\nimport type { LabelProps } from './Label'\nimport { Label } from './Label'\nimport { useFocusManagement } from '../../hooks/useFocusManagement'\nimport { useFocusOnceVisible } from '../../hooks/useFocusOnceVisible'\n\ntype GetInputClassNameProps = {\n disabled?: boolean,\n hasError?: boolean,\n}\nconst getInputClassName = ({ disabled = false, hasError = false }: GetInputClassNameProps) => {\n return clsx(\n 'px-2 py-1.5 rounded-md border-2',\n {\n 'bg-surface text-on-surface hover:border-primary focus:border-primary': !disabled && !hasError,\n 'bg-on-negative text-negative border-negative-border hover:border-negative-border-hover': !disabled && hasError,\n 'bg-disabled-background text-disabled-text border-disabled-border': disabled,\n }\n )\n}\n\nexport type EditCompleteOptionsResolved = {\n onBlur: boolean,\n afterDelay: boolean,\n} & Omit<UseDelayOptionsResolved, 'disabled'>\n\nexport type EditCompleteOptions = Partial<EditCompleteOptionsResolved>\n\nconst defaultEditCompleteOptions: EditCompleteOptionsResolved = {\n onBlur: true,\n afterDelay: true,\n delay: 2500\n}\n\nexport type InputProps = {\n /**\n * used for the label's `for` attribute\n */\n label?: Omit<LabelProps, 'id'>,\n /**\n * Callback for when the input's value changes\n * This is pretty much required but made optional for the rare cases where it actually isn't need such as when used with disabled\n * That could be enforced through a union type but that seems a bit overkill\n * @default noop\n */\n onChangeText?: (text: string) => void,\n className?: string,\n onEditCompleted?: (text: string) => void,\n allowEnterComplete?: boolean,\n expanded?: boolean,\n containerClassName?: string,\n editCompleteOptions?: EditCompleteOptions,\n} & Omit<InputHTMLAttributes<HTMLInputElement>, 'label'>\n\n/**\n * A Component for inputting text or other information\n *\n * Its state is managed must be managed by the parent\n */\nconst Input = forwardRef<HTMLInputElement, InputProps>(function Input({\n id,\n type = 'text',\n value,\n label,\n onChange = noop,\n onChangeText = noop,\n onEditCompleted,\n className = '',\n allowEnterComplete = true,\n expanded = true,\n autoFocus = false,\n onBlur,\n editCompleteOptions,\n containerClassName,\n disabled,\n ...restProps\n }, forwardedRef) {\n const { onBlur: allowEditCompleteOnBlur, afterDelay, delay } = { ...defaultEditCompleteOptions, ...editCompleteOptions }\n\n const {\n restartTimer,\n clearTimer\n } = useDelay({ delay, disabled: !afterDelay })\n\n const innerRef = useRef<HTMLInputElement>(null)\n const { focusNext } = useFocusManagement()\n\n useFocusOnceVisible(innerRef, !autoFocus)\n useImperativeHandle(forwardedRef, () => innerRef.current)\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault()\n innerRef.current?.blur()\n focusNext()\n }\n }\n\n return (\n <div className={clsx({ 'w-full': expanded }, containerClassName)}>\n {label && <Label {...label} htmlFor={id} className={clsx('mb-1', label.className)} />}\n <input\n {...restProps}\n ref={innerRef}\n value={value}\n id={id}\n type={type}\n disabled={disabled}\n className={clsx(getInputClassName({ disabled }), className)}\n onKeyDown={allowEnterComplete ? handleKeyDown : undefined}\n onBlur={event => {\n onBlur?.(event)\n if (onEditCompleted && allowEditCompleteOnBlur) {\n onEditCompleted(event.target.value)\n clearTimer()\n }\n }}\n onChange={e => {\n const value = e.target.value\n if (onEditCompleted) {\n restartTimer(() => {\n if(innerRef.current){\n innerRef.current.blur()\n if(!allowEditCompleteOnBlur) {\n onEditCompleted(value)\n }\n } else {\n onEditCompleted(value)\n }\n })\n }\n onChange(e)\n onChangeText(value)\n }}\n />\n </div>\n )\n})\n\n\n/**\n * A Component for inputting text or other information\n *\n * Its state is managed by the component itself\n */\nconst InputUncontrolled = ({\n value = '',\n onChangeText = noop,\n ...props\n }: InputProps) => {\n const [usedValue, setUsedValue] = useState(value)\n\n useEffect(() => {\n setUsedValue(value)\n }, [value])\n\n return (\n <Input\n {...props}\n value={usedValue}\n onChangeText={text => {\n setUsedValue(text)\n onChangeText(text)\n }}\n />\n )\n}\n\nexport type FormInputProps = InputHTMLAttributes<HTMLInputElement> & {\n id: string,\n labelText?: string,\n errorText?: string,\n labelClassName?: string,\n errorClassName?: string,\n containerClassName?: string,\n}\n\nconst FormInput = forwardRef<HTMLInputElement, FormInputProps>(function FormInput({\n id,\n labelText,\n errorText,\n className,\n labelClassName,\n errorClassName,\n containerClassName,\n required,\n disabled,\n ...restProps\n }, ref) {\n const input = (\n <input\n {...restProps}\n ref={ref}\n id={id}\n disabled={disabled}\n className={clsx(\n getInputClassName({ disabled, hasError: !!errorText }),\n className\n )}\n />\n )\n\n return (\n <div className={clsx('flex flex-col gap-y-1', containerClassName)}>\n {labelText && (\n <label htmlFor={id} className={clsx('textstyle-label-md', labelClassName)}>\n {labelText}\n {required && <span className=\"text-primary font-bold\">*</span>}\n </label>\n )}\n {input}\n {errorText && <label htmlFor={id} className={clsx('text-negative', errorClassName)}>{errorText}</label>}\n </div>\n )\n})\n\nexport {\n InputUncontrolled,\n Input,\n FormInput\n}\n","import { useEffect, useState } from 'react'\n\nexport type UseDelayOptionsResolved = {\n delay: number,\n disabled: boolean,\n}\n\nexport type UseDelayOptions = Partial<UseDelayOptionsResolved>\n\nconst defaultOptions: UseDelayOptionsResolved = {\n delay: 3000,\n disabled: false,\n}\n\nexport function useDelay(options?: UseDelayOptions) {\n const [timer, setTimer] = useState<NodeJS.Timeout | undefined>(undefined)\n const { delay, disabled }: UseDelayOptionsResolved = {\n ...defaultOptions,\n ...options\n }\n\n const clearTimer = () => {\n clearTimeout(timer)\n setTimer(undefined)\n }\n\n const restartTimer = (onDelayFinish: () => void) => {\n if(disabled) {\n return\n }\n clearTimeout(timer)\n setTimer(setTimeout(() => {\n onDelayFinish()\n setTimer(undefined)\n }, delay))\n }\n\n useEffect(() => {\n return () => {\n clearTimeout(timer)\n }\n }, [timer])\n\n useEffect(() => {\n if(disabled){\n clearTimeout(timer)\n setTimer(undefined)\n }\n }, [disabled, timer])\n\n return { restartTimer, clearTimer, hasActiveTimer: !!timer }\n}","export const noop = () => undefined\n","import type { LabelHTMLAttributes } from 'react'\nimport clsx from 'clsx'\n\nexport type LabelType = 'labelSmall' | 'labelMedium' | 'labelBig'\n\nconst styleMapping: Record<LabelType, string> = {\n labelSmall: 'textstyle-label-sm',\n labelMedium: 'textstyle-label-md',\n labelBig: 'textstyle-label-lg',\n}\n\nexport type LabelProps = {\n /** The text for the label */\n name?: string,\n /** The styling for the label */\n labelType?: LabelType,\n} & LabelHTMLAttributes<HTMLLabelElement>\n\n/**\n * A Label component\n */\nexport const Label = ({\n children,\n name,\n labelType = 'labelSmall',\n className,\n ...props\n }: LabelProps) => {\n return (\n <label {...props} className={clsx(styleMapping[labelType], className)}>\n {children ? children : name}\n </label>\n )\n}\n","import { useCallback } from 'react'\n\nexport function useFocusManagement() {\n const getFocusableElements = useCallback((): HTMLElement[] => {\n return Array.from(\n document.querySelectorAll(\n 'input, button, select, textarea, a[href], [tabindex]:not([tabindex=\"-1\"])'\n )\n ).filter(\n (el): el is HTMLElement =>\n el instanceof HTMLElement &&\n !el.hasAttribute('disabled') &&\n !el.hasAttribute('hidden') &&\n el.tabIndex !== -1\n )\n }, [])\n\n const getNextFocusElement = useCallback((): HTMLElement | undefined => {\n const elements = getFocusableElements()\n if(elements.length === 0) {\n return undefined\n }\n let nextElement = elements[0]\n if(document.activeElement instanceof HTMLElement) {\n const currentIndex = elements.indexOf(document.activeElement)\n nextElement = elements[(currentIndex + 1) % elements.length]\n }\n return nextElement\n }, [getFocusableElements])\n\n const focusNext = useCallback(() => {\n const nextElement = getNextFocusElement()\n nextElement?.focus()\n }, [getNextFocusElement])\n\n const getPreviousFocusElement = useCallback((): HTMLElement | undefined => {\n const elements = getFocusableElements()\n if(elements.length === 0) {\n return undefined\n }\n let previousElement = elements[0]\n if(document.activeElement instanceof HTMLElement) {\n const currentIndex = elements.indexOf(document.activeElement)\n if(currentIndex === 0) {\n previousElement = elements[elements.length - 1]\n } else {\n previousElement = elements[currentIndex - 1]\n }\n }\n return previousElement\n }, [getFocusableElements])\n\n const focusPrevious = useCallback(() => {\n const previousElement = getPreviousFocusElement()\n if (previousElement) previousElement.focus()\n }, [getPreviousFocusElement])\n\n return {\n getFocusableElements,\n getNextFocusElement,\n getPreviousFocusElement,\n focusNext,\n focusPrevious,\n }\n}","import type { MutableRefObject } from 'react'\nimport React, { useEffect } from 'react'\n\nexport const useFocusOnceVisible = (\n ref: MutableRefObject<HTMLElement>,\n disable: boolean = false\n) => {\n const [hasUsedFocus, setHasUsedFocus] = React.useState(false)\n\n useEffect(() => {\n if (disable || hasUsedFocus) {\n return\n }\n const observer = new IntersectionObserver(([entry]) => {\n if (entry.isIntersecting && !hasUsedFocus) {\n ref.current?.focus()\n setHasUsedFocus(hasUsedFocus)\n }\n }, {\n threshold: 0.1,\n })\n\n if (ref.current) {\n observer.observe(ref.current)\n }\n\n return () => observer.disconnect()\n }, [disable, hasUsedFocus, ref])\n}"],"mappings":"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","names":["useEffect","useState","clsx","useEffect","jsx","clsx","Input","value","useState","useEffect","FormInput"]}
1
+ {"version":3,"sources":["../../../src/components/user-action/Input.tsx","../../../src/hooks/useDelay.ts","../../../src/util/noop.ts","../../../src/components/user-action/Label.tsx","../../../src/hooks/useFocusManagement.ts","../../../src/hooks/useFocusOnceVisible.ts"],"sourcesContent":["import React, { forwardRef, type InputHTMLAttributes, useEffect, useImperativeHandle, useRef, useState } from 'react'\nimport clsx from 'clsx'\nimport type { UseDelayOptionsResolved } from '../../hooks/useDelay'\nimport { useDelay } from '../../hooks/useDelay'\nimport { noop } from '../../util/noop'\nimport type { LabelProps } from './Label'\nimport { Label } from './Label'\nimport { useFocusManagement } from '../../hooks/useFocusManagement'\nimport { useFocusOnceVisible } from '../../hooks/useFocusOnceVisible'\n\ntype GetInputClassNameProps = {\n disabled?: boolean,\n hasError?: boolean,\n}\nconst getInputClassName = ({ disabled = false, hasError = false }: GetInputClassNameProps) => {\n return clsx(\n 'px-2 py-1.5 rounded-md border-2',\n {\n 'bg-input-background text-input-text hover:border-primary focus:border-primary': !disabled && !hasError,\n 'bg-on-negative text-negative border-negative-border hover:border-negative-border-hover': !disabled && hasError,\n 'bg-disabled-background text-disabled-text border-disabled-border': disabled,\n }\n )\n}\n\nexport type EditCompleteOptionsResolved = {\n onBlur: boolean,\n afterDelay: boolean,\n} & Omit<UseDelayOptionsResolved, 'disabled'>\n\nexport type EditCompleteOptions = Partial<EditCompleteOptionsResolved>\n\nconst defaultEditCompleteOptions: EditCompleteOptionsResolved = {\n onBlur: true,\n afterDelay: true,\n delay: 2500\n}\n\nexport type InputProps = {\n /**\n * used for the label's `for` attribute\n */\n label?: Omit<LabelProps, 'id'>,\n /**\n * Callback for when the input's value changes\n * This is pretty much required but made optional for the rare cases where it actually isn't need such as when used with disabled\n * That could be enforced through a union type but that seems a bit overkill\n * @default noop\n */\n onChangeText?: (text: string) => void,\n className?: string,\n onEditCompleted?: (text: string) => void,\n allowEnterComplete?: boolean,\n expanded?: boolean,\n containerClassName?: string,\n editCompleteOptions?: EditCompleteOptions,\n} & Omit<InputHTMLAttributes<HTMLInputElement>, 'label'>\n\n/**\n * A Component for inputting text or other information\n *\n * Its state is managed must be managed by the parent\n */\nconst Input = forwardRef<HTMLInputElement, InputProps>(function Input({\n id,\n type = 'text',\n value,\n label,\n onChange = noop,\n onChangeText = noop,\n onEditCompleted,\n className = '',\n allowEnterComplete = true,\n expanded = true,\n autoFocus = false,\n onBlur,\n editCompleteOptions,\n containerClassName,\n disabled,\n ...restProps\n }, forwardedRef) {\n const { onBlur: allowEditCompleteOnBlur, afterDelay, delay } = { ...defaultEditCompleteOptions, ...editCompleteOptions }\n\n const {\n restartTimer,\n clearTimer\n } = useDelay({ delay, disabled: !afterDelay })\n\n const innerRef = useRef<HTMLInputElement>(null)\n const { focusNext } = useFocusManagement()\n\n useFocusOnceVisible(innerRef, !autoFocus)\n useImperativeHandle(forwardedRef, () => innerRef.current)\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault()\n innerRef.current?.blur()\n focusNext()\n }\n }\n\n return (\n <div className={clsx({ 'w-full': expanded }, containerClassName)}>\n {label && <Label {...label} htmlFor={id} className={clsx('mb-1', label.className)} />}\n <input\n {...restProps}\n ref={innerRef}\n value={value}\n id={id}\n type={type}\n disabled={disabled}\n className={clsx(getInputClassName({ disabled }), className)}\n onKeyDown={allowEnterComplete ? handleKeyDown : undefined}\n onBlur={event => {\n onBlur?.(event)\n if (onEditCompleted && allowEditCompleteOnBlur) {\n onEditCompleted(event.target.value)\n clearTimer()\n }\n }}\n onChange={e => {\n const value = e.target.value\n if (onEditCompleted) {\n restartTimer(() => {\n if(innerRef.current){\n innerRef.current.blur()\n if(!allowEditCompleteOnBlur) {\n onEditCompleted(value)\n }\n } else {\n onEditCompleted(value)\n }\n })\n }\n onChange(e)\n onChangeText(value)\n }}\n />\n </div>\n )\n})\n\n\n/**\n * A Component for inputting text or other information\n *\n * Its state is managed by the component itself\n */\nconst InputUncontrolled = ({\n value = '',\n onChangeText = noop,\n ...props\n }: InputProps) => {\n const [usedValue, setUsedValue] = useState(value)\n\n useEffect(() => {\n setUsedValue(value)\n }, [value])\n\n return (\n <Input\n {...props}\n value={usedValue}\n onChangeText={text => {\n setUsedValue(text)\n onChangeText(text)\n }}\n />\n )\n}\n\nexport type FormInputProps = InputHTMLAttributes<HTMLInputElement> & {\n id: string,\n labelText?: string,\n errorText?: string,\n labelClassName?: string,\n errorClassName?: string,\n containerClassName?: string,\n}\n\nconst FormInput = forwardRef<HTMLInputElement, FormInputProps>(function FormInput({\n id,\n labelText,\n errorText,\n className,\n labelClassName,\n errorClassName,\n containerClassName,\n required,\n disabled,\n ...restProps\n }, ref) {\n const input = (\n <input\n {...restProps}\n ref={ref}\n id={id}\n disabled={disabled}\n className={clsx(\n getInputClassName({ disabled, hasError: !!errorText }),\n className\n )}\n />\n )\n\n return (\n <div className={clsx('flex flex-col gap-y-1', containerClassName)}>\n {labelText && (\n <label htmlFor={id} className={clsx('textstyle-label-md', labelClassName)}>\n {labelText}\n {required && <span className=\"text-primary font-bold\">*</span>}\n </label>\n )}\n {input}\n {errorText && <label htmlFor={id} className={clsx('text-negative', errorClassName)}>{errorText}</label>}\n </div>\n )\n})\n\nexport {\n InputUncontrolled,\n Input,\n FormInput\n}\n","import { useEffect, useState } from 'react'\n\nexport type UseDelayOptionsResolved = {\n delay: number,\n disabled: boolean,\n}\n\nexport type UseDelayOptions = Partial<UseDelayOptionsResolved>\n\nconst defaultOptions: UseDelayOptionsResolved = {\n delay: 3000,\n disabled: false,\n}\n\nexport function useDelay(options?: UseDelayOptions) {\n const [timer, setTimer] = useState<NodeJS.Timeout | undefined>(undefined)\n const { delay, disabled }: UseDelayOptionsResolved = {\n ...defaultOptions,\n ...options\n }\n\n const clearTimer = () => {\n clearTimeout(timer)\n setTimer(undefined)\n }\n\n const restartTimer = (onDelayFinish: () => void) => {\n if(disabled) {\n return\n }\n clearTimeout(timer)\n setTimer(setTimeout(() => {\n onDelayFinish()\n setTimer(undefined)\n }, delay))\n }\n\n useEffect(() => {\n return () => {\n clearTimeout(timer)\n }\n }, [timer])\n\n useEffect(() => {\n if(disabled){\n clearTimeout(timer)\n setTimer(undefined)\n }\n }, [disabled, timer])\n\n return { restartTimer, clearTimer, hasActiveTimer: !!timer }\n}","export const noop = () => undefined\n","import type { LabelHTMLAttributes } from 'react'\nimport clsx from 'clsx'\n\nexport type LabelType = 'labelSmall' | 'labelMedium' | 'labelBig'\n\nconst styleMapping: Record<LabelType, string> = {\n labelSmall: 'textstyle-label-sm',\n labelMedium: 'textstyle-label-md',\n labelBig: 'textstyle-label-lg',\n}\n\nexport type LabelProps = {\n /** The text for the label */\n name?: string,\n /** The styling for the label */\n labelType?: LabelType,\n} & LabelHTMLAttributes<HTMLLabelElement>\n\n/**\n * A Label component\n */\nexport const Label = ({\n children,\n name,\n labelType = 'labelSmall',\n className,\n ...props\n }: LabelProps) => {\n return (\n <label {...props} className={clsx(styleMapping[labelType], className)}>\n {children ? children : name}\n </label>\n )\n}\n","import { useCallback } from 'react'\n\nexport function useFocusManagement() {\n const getFocusableElements = useCallback((): HTMLElement[] => {\n return Array.from(\n document.querySelectorAll(\n 'input, button, select, textarea, a[href], [tabindex]:not([tabindex=\"-1\"])'\n )\n ).filter(\n (el): el is HTMLElement =>\n el instanceof HTMLElement &&\n !el.hasAttribute('disabled') &&\n !el.hasAttribute('hidden') &&\n el.tabIndex !== -1\n )\n }, [])\n\n const getNextFocusElement = useCallback((): HTMLElement | undefined => {\n const elements = getFocusableElements()\n if(elements.length === 0) {\n return undefined\n }\n let nextElement = elements[0]\n if(document.activeElement instanceof HTMLElement) {\n const currentIndex = elements.indexOf(document.activeElement)\n nextElement = elements[(currentIndex + 1) % elements.length]\n }\n return nextElement\n }, [getFocusableElements])\n\n const focusNext = useCallback(() => {\n const nextElement = getNextFocusElement()\n nextElement?.focus()\n }, [getNextFocusElement])\n\n const getPreviousFocusElement = useCallback((): HTMLElement | undefined => {\n const elements = getFocusableElements()\n if(elements.length === 0) {\n return undefined\n }\n let previousElement = elements[0]\n if(document.activeElement instanceof HTMLElement) {\n const currentIndex = elements.indexOf(document.activeElement)\n if(currentIndex === 0) {\n previousElement = elements[elements.length - 1]\n } else {\n previousElement = elements[currentIndex - 1]\n }\n }\n return previousElement\n }, [getFocusableElements])\n\n const focusPrevious = useCallback(() => {\n const previousElement = getPreviousFocusElement()\n if (previousElement) previousElement.focus()\n }, [getPreviousFocusElement])\n\n return {\n getFocusableElements,\n getNextFocusElement,\n getPreviousFocusElement,\n focusNext,\n focusPrevious,\n }\n}","import type { MutableRefObject } from 'react'\nimport React, { useEffect } from 'react'\n\nexport const useFocusOnceVisible = (\n ref: MutableRefObject<HTMLElement>,\n disable: boolean = false\n) => {\n const [hasUsedFocus, setHasUsedFocus] = React.useState(false)\n\n useEffect(() => {\n if (disable || hasUsedFocus) {\n return\n }\n const observer = new IntersectionObserver(([entry]) => {\n if (entry.isIntersecting && !hasUsedFocus) {\n ref.current?.focus()\n setHasUsedFocus(hasUsedFocus)\n }\n }, {\n threshold: 0.1,\n })\n\n if (ref.current) {\n observer.observe(ref.current)\n }\n\n return () => observer.disconnect()\n }, [disable, hasUsedFocus, ref])\n}"],"mappings":"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","names":["useEffect","useState","clsx","useEffect","jsx","clsx","Input","value","useState","useEffect","FormInput"]}
@@ -177,7 +177,7 @@ var MenuItem = ({
177
177
  }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
178
178
  "div",
179
179
  {
180
- className: (0, import_clsx.default)("block px-3 py-1.5 first:rounded-t-md last:rounded-b-md text-sm font-semibold", {
180
+ className: (0, import_clsx.default)("block px-3 py-1.5 first:rounded-t-md last:rounded-b-md text-sm font-semibold text-nowrap", {
181
181
  "text-right": alignment === "right",
182
182
  "text-left": alignment === "left",
183
183
  "text-disabled-text cursor-not-allowed": isDisabled,
@@ -251,7 +251,7 @@ var Menu = ({
251
251
  ref: menuRef,
252
252
  onClick: (e) => e.stopPropagation(),
253
253
  className: (0, import_clsx.default)(
254
- "absolute rounded-md bg-menu-background text-menu-text shadow-around-lg z-[300]",
254
+ "absolute rounded-md bg-menu-background text-menu-text shadow-around-lg shadow-strong z-[300]",
255
255
  {
256
256
  "animate-pop-in": isOpen,
257
257
  "animate-pop-out": !isOpen,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/user-action/Menu.tsx","../../../src/hooks/useOutsideClick.ts","../../../src/hooks/useHoverState.ts","../../../src/util/PropsWithFunctionChildren.ts","../../../src/hooks/usePopoverPosition.ts"],"sourcesContent":["import {\n type PropsWithChildren,\n type ReactNode,\n type RefObject,\n useEffect,\n useRef, useState\n} from 'react'\nimport clsx from 'clsx'\nimport { useOutsideClick } from '../../hooks/useOutsideClick'\nimport { useHoverState } from '../../hooks/useHoverState'\nimport type { PropsWithBagFunctionOrChildren } from '../../util/PropsWithFunctionChildren'\nimport { BagFunctionUtil } from '../../util/PropsWithFunctionChildren'\nimport type { PopoverHorizontalAlignment, PopoverVerticalAlignment } from '../../hooks/usePopoverPosition'\nimport { usePopoverPosition } from '../../hooks/usePopoverPosition'\nimport { createPortal } from 'react-dom'\n\nexport type MenuItemProps = {\n onClick?: () => void,\n alignment?: 'left' | 'right',\n isDisabled?: boolean,\n className?: string,\n}\nexport const MenuItem = ({\n children,\n onClick,\n alignment = 'left',\n isDisabled = false,\n className\n }: PropsWithChildren<MenuItemProps>) => (\n <div\n className={clsx('block px-3 py-1.5 first:rounded-t-md last:rounded-b-md text-sm font-semibold', {\n 'text-right': alignment === 'right',\n 'text-left': alignment === 'left',\n 'text-disabled-text cursor-not-allowed': isDisabled,\n 'text-menu-text hover:bg-primary/20': !isDisabled,\n 'cursor-pointer': !!onClick,\n }, className)}\n onClick={onClick}\n >\n {children}\n </div>\n)\n\nfunction getScrollableParents(element) {\n const scrollables = []\n let parent = element.parentElement\n while (parent) {\n scrollables.push(parent)\n parent = parent.parentElement\n }\n return scrollables\n}\n\nexport type MenuBag = {\n isOpen: boolean,\n disabled: boolean,\n toggleOpen: () => void,\n close: () => void,\n}\n\nexport type MenuProps<T> = PropsWithBagFunctionOrChildren<MenuBag> & {\n trigger: (bag: MenuBag, ref: RefObject<T>) => ReactNode,\n /**\n * @default 'l'\n */\n alignmentHorizontal?: PopoverHorizontalAlignment,\n alignmentVertical?: PopoverVerticalAlignment,\n showOnHover?: boolean,\n menuClassName?: string,\n disabled?: boolean,\n}\n\n/**\n * A Menu Component to allow the user to see different functions\n */\nexport const Menu = <T extends HTMLElement>({\n trigger,\n children,\n alignmentHorizontal = 'leftInside',\n alignmentVertical = 'bottomOutside',\n showOnHover = false,\n disabled = false,\n menuClassName = '',\n }: MenuProps<T>) => {\n const { isHovered: isOpen, setIsHovered: setIsOpen } = useHoverState({ isDisabled: !showOnHover || disabled })\n const triggerRef = useRef<T>(null)\n const menuRef = useRef<HTMLDivElement>(null)\n useOutsideClick([triggerRef, menuRef], () => setIsOpen(false))\n\n const [isHidden, setIsHidden] = useState<boolean>(true)\n const bag: MenuBag = {\n isOpen,\n close: () => setIsOpen(false),\n toggleOpen: () => setIsOpen(prevState => !prevState),\n disabled,\n }\n\n const menuPosition = usePopoverPosition(\n triggerRef.current?.getBoundingClientRect(),\n { verticalAlignment: alignmentVertical, horizontalAlignment: alignmentHorizontal, disabled }\n )\n\n useEffect(() => {\n if (!isOpen) return\n\n const triggerEl = triggerRef.current\n if (!triggerEl) return\n\n const scrollableParents = getScrollableParents(triggerEl)\n\n const close = () => setIsOpen(false)\n scrollableParents.forEach((parent) => {\n parent.addEventListener('scroll', close)\n })\n window.addEventListener('resize', close)\n\n return () => {\n scrollableParents.forEach((parent) => {\n parent.removeEventListener('scroll', close)\n })\n window.removeEventListener('resize', close)\n }\n }, [isOpen, setIsOpen])\n\n useEffect(() => {\n if (isOpen) {\n setIsHidden(false)\n }\n }, [isOpen])\n\n return (\n <>\n {trigger(bag, triggerRef)}\n {createPortal((<div\n ref={menuRef}\n onClick={e => e.stopPropagation()}\n className={clsx(\n 'absolute rounded-md bg-menu-background text-menu-text shadow-around-lg z-[300]',\n {\n 'animate-pop-in': isOpen,\n 'animate-pop-out': !isOpen,\n 'hidden': isHidden,\n },\n menuClassName\n )}\n onAnimationEnd={() => {\n if (!isOpen) {\n setIsHidden(true)\n }\n }}\n style={{\n ...menuPosition\n }}\n >\n {BagFunctionUtil.resolve<MenuBag>(children, bag)}\n </div>), document.body)}\n </>\n )\n}\n\n","import type { RefObject } from 'react'\nimport { useEffect } from 'react'\n\nexport const useOutsideClick = <Ts extends RefObject<HTMLElement>[]>(refs: Ts, handler: () => void) => {\n useEffect(() => {\n const listener = (event: MouseEvent | TouchEvent) => {\n // returning means not \"not clicking outside\"\n\n // if no target exists, return\n if (event.target === null) return\n // if the target is a ref's element or descendent thereof, return\n if (refs.some((ref) => !ref.current || ref.current.contains(event.target as Node))) {\n return\n }\n\n handler()\n }\n document.addEventListener('mousedown', listener)\n document.addEventListener('touchstart', listener)\n return () => {\n document.removeEventListener('mousedown', listener)\n document.removeEventListener('touchstart', listener)\n }\n }, [refs, handler])\n}\n","import type { Dispatch, SetStateAction } from 'react'\nimport { useEffect, useState } from 'react'\n\ntype UseHoverStateProps = {\n /**\n * The delay after which the menu is closed in milliseconds\n *\n * default: 200ms\n */\n closingDelay: number,\n /**\n * Whether the hover state management should be disabled\n *\n * default: false\n */\n isDisabled: boolean,\n}\n\ntype UseHoverStateReturnType = {\n /**\n * Whether the element is hovered\n */\n isHovered: boolean,\n /**\n * Function to change the current hover status\n */\n setIsHovered: Dispatch<SetStateAction<boolean>>,\n /**\n * Handlers to pass on to the component that should be hovered\n */\n handlers: {\n onMouseEnter: () => void,\n onMouseLeave: () => void,\n },\n}\n\nconst defaultUseHoverStateProps: UseHoverStateProps = {\n closingDelay: 200,\n isDisabled: false,\n}\n\n/**\n * @param props See UseHoverStateProps\n *\n * A react hook for managing the hover state of a component. The handlers provided should be\n * forwarded to the component which should be hovered over\n */\nexport const useHoverState = (props: Partial<UseHoverStateProps> | undefined = undefined): UseHoverStateReturnType => {\n const { closingDelay, isDisabled } = { ...defaultUseHoverStateProps, ...props }\n\n const [isHovered, setIsHovered] = useState(false)\n const [timer, setTimer] = useState<NodeJS.Timeout>()\n\n const onMouseEnter = () => {\n if (isDisabled) {\n return\n }\n clearTimeout(timer)\n setIsHovered(true)\n }\n\n const onMouseLeave = () => {\n if (isDisabled) {\n return\n }\n setTimer(setTimeout(() => {\n setIsHovered(false)\n }, closingDelay))\n }\n\n useEffect(() => {\n if (timer) {\n return () => {\n clearTimeout(timer)\n }\n }\n })\n\n useEffect(() => {\n if (timer) {\n clearTimeout(timer)\n }\n }, [isDisabled]) // eslint-disable-line react-hooks/exhaustive-deps\n\n return {\n isHovered, setIsHovered, handlers: { onMouseEnter, onMouseLeave }\n }\n}\n","import type { ReactNode } from 'react'\n\nexport type BagFunction<T> = (bag: T) => ReactNode\n\nexport type PropsWithBagFunction<T, P = unknown> = P & { children?: BagFunction<T> }\n\nexport type PropsWithBagFunctionOrChildren<T, P = unknown> = P & { children?: BagFunction<T> | ReactNode }\n\nconst resolve = <T>(children: BagFunction<T> | ReactNode, bag: T): ReactNode => {\n if (typeof children === 'function') {\n return (children as BagFunction<T>)(bag)\n }\n\n return children ?? undefined\n}\n\nexport const BagFunctionUtil = {\n resolve\n}","import type { CSSProperties } from 'react'\n\nexport type PopoverHorizontalAlignment = 'leftOutside' | 'leftInside' | 'rightOutside' | 'rightInside' | 'center'\nexport type PopoverVerticalAlignment = 'topOutside' | 'topInside' | 'bottomOutside' | 'bottomInside' | 'center'\n\ntype PopoverPositionOptionsResolved = {\n edgePadding: number,\n outerGap: number,\n verticalAlignment: PopoverVerticalAlignment,\n horizontalAlignment: PopoverHorizontalAlignment,\n disabled: boolean,\n}\n\ntype PopoverPositionOptions = Partial<PopoverPositionOptionsResolved>\n\nconst defaultPopoverPositionOptions: PopoverPositionOptionsResolved = {\n edgePadding: 16,\n outerGap: 4,\n horizontalAlignment: 'leftInside',\n verticalAlignment: 'bottomOutside',\n disabled: false,\n}\n\nexport const usePopoverPosition = (trigger?: DOMRect, options?: PopoverPositionOptions): CSSProperties => {\n const {\n edgePadding,\n outerGap,\n verticalAlignment,\n horizontalAlignment,\n disabled\n }: PopoverPositionOptionsResolved = { ...defaultPopoverPositionOptions, ...options }\n\n if (disabled || !trigger) {\n return {}\n }\n\n const left: number = {\n leftOutside: trigger.left - outerGap,\n leftInside: trigger.left,\n rightOutside: trigger.right + outerGap,\n rightInside: trigger.right,\n center: trigger.left + trigger.width / 2,\n }[horizontalAlignment]\n\n const top: number = {\n topOutside: trigger.top - outerGap,\n topInside: trigger.top,\n bottomOutside: trigger.bottom + outerGap,\n bottomInside: trigger.bottom,\n center: trigger.top + trigger.height / 2,\n }[verticalAlignment]\n\n const translateX: string | undefined = {\n leftOutside: '-100%',\n leftInside: undefined,\n rightOutside: undefined,\n rightInside: '-100%',\n center: '-50%',\n }[horizontalAlignment]\n\n const translateY: string | undefined = {\n topOutside: '-100%',\n topInside: undefined,\n bottomOutside: undefined,\n bottomInside: '-100%',\n center: '-50%',\n }[verticalAlignment]\n\n return {\n left: Math.max(left, edgePadding),\n top: Math.max(top, edgePadding),\n translate: [translateX ?? '0', translateY ?? '0'].join(' ')\n }\n}"],"mappings":"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","names":["import_react","import_react","clsx"]}
1
+ {"version":3,"sources":["../../../src/components/user-action/Menu.tsx","../../../src/hooks/useOutsideClick.ts","../../../src/hooks/useHoverState.ts","../../../src/util/PropsWithFunctionChildren.ts","../../../src/hooks/usePopoverPosition.ts"],"sourcesContent":["import { type PropsWithChildren, type ReactNode, type RefObject, useEffect, useRef, useState } from 'react'\nimport clsx from 'clsx'\nimport { useOutsideClick } from '../../hooks/useOutsideClick'\nimport { useHoverState } from '../../hooks/useHoverState'\nimport type { PropsWithBagFunctionOrChildren } from '../../util/PropsWithFunctionChildren'\nimport { BagFunctionUtil } from '../../util/PropsWithFunctionChildren'\nimport type { PopoverHorizontalAlignment, PopoverVerticalAlignment } from '../../hooks/usePopoverPosition'\nimport { usePopoverPosition } from '../../hooks/usePopoverPosition'\nimport { createPortal } from 'react-dom'\n\nexport type MenuItemProps = {\n onClick?: () => void,\n alignment?: 'left' | 'right',\n isDisabled?: boolean,\n className?: string,\n}\nexport const MenuItem = ({\n children,\n onClick,\n alignment = 'left',\n isDisabled = false,\n className\n }: PropsWithChildren<MenuItemProps>) => (\n <div\n className={clsx('block px-3 py-1.5 first:rounded-t-md last:rounded-b-md text-sm font-semibold text-nowrap', {\n 'text-right': alignment === 'right',\n 'text-left': alignment === 'left',\n 'text-disabled-text cursor-not-allowed': isDisabled,\n 'text-menu-text hover:bg-primary/20': !isDisabled,\n 'cursor-pointer': !!onClick,\n }, className)}\n onClick={onClick}\n >\n {children}\n </div>\n)\n\nfunction getScrollableParents(element) {\n const scrollables = []\n let parent = element.parentElement\n while (parent) {\n scrollables.push(parent)\n parent = parent.parentElement\n }\n return scrollables\n}\n\nexport type MenuBag = {\n isOpen: boolean,\n disabled: boolean,\n toggleOpen: () => void,\n close: () => void,\n}\n\nexport type MenuProps<T> = PropsWithBagFunctionOrChildren<MenuBag> & {\n trigger: (bag: MenuBag, ref: RefObject<T>) => ReactNode,\n /**\n * @default 'l'\n */\n alignmentHorizontal?: PopoverHorizontalAlignment,\n alignmentVertical?: PopoverVerticalAlignment,\n showOnHover?: boolean,\n menuClassName?: string,\n disabled?: boolean,\n}\n\n/**\n * A Menu Component to allow the user to see different functions\n */\nexport const Menu = <T extends HTMLElement>({\n trigger,\n children,\n alignmentHorizontal = 'leftInside',\n alignmentVertical = 'bottomOutside',\n showOnHover = false,\n disabled = false,\n menuClassName = '',\n }: MenuProps<T>) => {\n const { isHovered: isOpen, setIsHovered: setIsOpen } = useHoverState({ isDisabled: !showOnHover || disabled })\n const triggerRef = useRef<T>(null)\n const menuRef = useRef<HTMLDivElement>(null)\n useOutsideClick([triggerRef, menuRef], () => setIsOpen(false))\n\n const [isHidden, setIsHidden] = useState<boolean>(true)\n const bag: MenuBag = {\n isOpen,\n close: () => setIsOpen(false),\n toggleOpen: () => setIsOpen(prevState => !prevState),\n disabled,\n }\n\n const menuPosition = usePopoverPosition(\n triggerRef.current?.getBoundingClientRect(),\n { verticalAlignment: alignmentVertical, horizontalAlignment: alignmentHorizontal, disabled }\n )\n\n useEffect(() => {\n if (!isOpen) return\n\n const triggerEl = triggerRef.current\n if (!triggerEl) return\n\n const scrollableParents = getScrollableParents(triggerEl)\n\n const close = () => setIsOpen(false)\n scrollableParents.forEach((parent) => {\n parent.addEventListener('scroll', close)\n })\n window.addEventListener('resize', close)\n\n return () => {\n scrollableParents.forEach((parent) => {\n parent.removeEventListener('scroll', close)\n })\n window.removeEventListener('resize', close)\n }\n }, [isOpen, setIsOpen])\n\n useEffect(() => {\n if (isOpen) {\n setIsHidden(false)\n }\n }, [isOpen])\n\n return (\n <>\n {trigger(bag, triggerRef)}\n {createPortal((\n <div\n ref={menuRef}\n onClick={e => e.stopPropagation()}\n className={clsx(\n 'absolute rounded-md bg-menu-background text-menu-text shadow-around-lg shadow-strong z-[300]',\n {\n 'animate-pop-in': isOpen,\n 'animate-pop-out': !isOpen,\n 'hidden': isHidden,\n },\n menuClassName\n )}\n onAnimationEnd={() => {\n if (!isOpen) {\n setIsHidden(true)\n }\n }}\n style={{\n ...menuPosition\n }}\n >\n {BagFunctionUtil.resolve<MenuBag>(children, bag)}\n </div>\n ), document.body)}\n </>\n )\n}\n\n","import type { RefObject } from 'react'\nimport { useEffect } from 'react'\n\nexport const useOutsideClick = <Ts extends RefObject<HTMLElement>[]>(refs: Ts, handler: () => void) => {\n useEffect(() => {\n const listener = (event: MouseEvent | TouchEvent) => {\n // returning means not \"not clicking outside\"\n\n // if no target exists, return\n if (event.target === null) return\n // if the target is a ref's element or descendent thereof, return\n if (refs.some((ref) => !ref.current || ref.current.contains(event.target as Node))) {\n return\n }\n\n handler()\n }\n document.addEventListener('mousedown', listener)\n document.addEventListener('touchstart', listener)\n return () => {\n document.removeEventListener('mousedown', listener)\n document.removeEventListener('touchstart', listener)\n }\n }, [refs, handler])\n}\n","import type { Dispatch, SetStateAction } from 'react'\nimport { useEffect, useState } from 'react'\n\ntype UseHoverStateProps = {\n /**\n * The delay after which the menu is closed in milliseconds\n *\n * default: 200ms\n */\n closingDelay: number,\n /**\n * Whether the hover state management should be disabled\n *\n * default: false\n */\n isDisabled: boolean,\n}\n\ntype UseHoverStateReturnType = {\n /**\n * Whether the element is hovered\n */\n isHovered: boolean,\n /**\n * Function to change the current hover status\n */\n setIsHovered: Dispatch<SetStateAction<boolean>>,\n /**\n * Handlers to pass on to the component that should be hovered\n */\n handlers: {\n onMouseEnter: () => void,\n onMouseLeave: () => void,\n },\n}\n\nconst defaultUseHoverStateProps: UseHoverStateProps = {\n closingDelay: 200,\n isDisabled: false,\n}\n\n/**\n * @param props See UseHoverStateProps\n *\n * A react hook for managing the hover state of a component. The handlers provided should be\n * forwarded to the component which should be hovered over\n */\nexport const useHoverState = (props: Partial<UseHoverStateProps> | undefined = undefined): UseHoverStateReturnType => {\n const { closingDelay, isDisabled } = { ...defaultUseHoverStateProps, ...props }\n\n const [isHovered, setIsHovered] = useState(false)\n const [timer, setTimer] = useState<NodeJS.Timeout>()\n\n const onMouseEnter = () => {\n if (isDisabled) {\n return\n }\n clearTimeout(timer)\n setIsHovered(true)\n }\n\n const onMouseLeave = () => {\n if (isDisabled) {\n return\n }\n setTimer(setTimeout(() => {\n setIsHovered(false)\n }, closingDelay))\n }\n\n useEffect(() => {\n if (timer) {\n return () => {\n clearTimeout(timer)\n }\n }\n })\n\n useEffect(() => {\n if (timer) {\n clearTimeout(timer)\n }\n }, [isDisabled]) // eslint-disable-line react-hooks/exhaustive-deps\n\n return {\n isHovered, setIsHovered, handlers: { onMouseEnter, onMouseLeave }\n }\n}\n","import type { ReactNode } from 'react'\n\nexport type BagFunction<T> = (bag: T) => ReactNode\n\nexport type PropsWithBagFunction<T, P = unknown> = P & { children?: BagFunction<T> }\n\nexport type PropsWithBagFunctionOrChildren<T, P = unknown> = P & { children?: BagFunction<T> | ReactNode }\n\nconst resolve = <T>(children: BagFunction<T> | ReactNode, bag: T): ReactNode => {\n if (typeof children === 'function') {\n return (children as BagFunction<T>)(bag)\n }\n\n return children ?? undefined\n}\n\nexport const BagFunctionUtil = {\n resolve\n}","import type { CSSProperties } from 'react'\n\nexport type PopoverHorizontalAlignment = 'leftOutside' | 'leftInside' | 'rightOutside' | 'rightInside' | 'center'\nexport type PopoverVerticalAlignment = 'topOutside' | 'topInside' | 'bottomOutside' | 'bottomInside' | 'center'\n\ntype PopoverPositionOptionsResolved = {\n edgePadding: number,\n outerGap: number,\n verticalAlignment: PopoverVerticalAlignment,\n horizontalAlignment: PopoverHorizontalAlignment,\n disabled: boolean,\n}\n\ntype PopoverPositionOptions = Partial<PopoverPositionOptionsResolved>\n\nconst defaultPopoverPositionOptions: PopoverPositionOptionsResolved = {\n edgePadding: 16,\n outerGap: 4,\n horizontalAlignment: 'leftInside',\n verticalAlignment: 'bottomOutside',\n disabled: false,\n}\n\nexport const usePopoverPosition = (trigger?: DOMRect, options?: PopoverPositionOptions): CSSProperties => {\n const {\n edgePadding,\n outerGap,\n verticalAlignment,\n horizontalAlignment,\n disabled\n }: PopoverPositionOptionsResolved = { ...defaultPopoverPositionOptions, ...options }\n\n if (disabled || !trigger) {\n return {}\n }\n\n const left: number = {\n leftOutside: trigger.left - outerGap,\n leftInside: trigger.left,\n rightOutside: trigger.right + outerGap,\n rightInside: trigger.right,\n center: trigger.left + trigger.width / 2,\n }[horizontalAlignment]\n\n const top: number = {\n topOutside: trigger.top - outerGap,\n topInside: trigger.top,\n bottomOutside: trigger.bottom + outerGap,\n bottomInside: trigger.bottom,\n center: trigger.top + trigger.height / 2,\n }[verticalAlignment]\n\n const translateX: string | undefined = {\n leftOutside: '-100%',\n leftInside: undefined,\n rightOutside: undefined,\n rightInside: '-100%',\n center: '-50%',\n }[horizontalAlignment]\n\n const translateY: string | undefined = {\n topOutside: '-100%',\n topInside: undefined,\n bottomOutside: undefined,\n bottomInside: '-100%',\n center: '-50%',\n }[verticalAlignment]\n\n return {\n left: Math.max(left, edgePadding),\n top: Math.max(top, edgePadding),\n translate: [translateX ?? '0', translateY ?? '0'].join(' ')\n }\n}"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAAA,gBAAoG;AACpG,kBAAiB;;;ACAjB,mBAA0B;AAEnB,IAAM,kBAAkB,CAAsC,MAAU,YAAwB;AACrG,8BAAU,MAAM;AACd,UAAM,WAAW,CAAC,UAAmC;AAInD,UAAI,MAAM,WAAW,KAAM;AAE3B,UAAI,KAAK,KAAK,CAAC,QAAQ,CAAC,IAAI,WAAW,IAAI,QAAQ,SAAS,MAAM,MAAc,CAAC,GAAG;AAClF;AAAA,MACF;AAEA,cAAQ;AAAA,IACV;AACA,aAAS,iBAAiB,aAAa,QAAQ;AAC/C,aAAS,iBAAiB,cAAc,QAAQ;AAChD,WAAO,MAAM;AACX,eAAS,oBAAoB,aAAa,QAAQ;AAClD,eAAS,oBAAoB,cAAc,QAAQ;AAAA,IACrD;AAAA,EACF,GAAG,CAAC,MAAM,OAAO,CAAC;AACpB;;;ACvBA,IAAAC,gBAAoC;AAmCpC,IAAM,4BAAgD;AAAA,EACpD,cAAc;AAAA,EACd,YAAY;AACd;AAQO,IAAM,gBAAgB,CAAC,QAAiD,WAAuC;AACpH,QAAM,EAAE,cAAc,WAAW,IAAI,EAAE,GAAG,2BAA2B,GAAG,MAAM;AAE9E,QAAM,CAAC,WAAW,YAAY,QAAI,wBAAS,KAAK;AAChD,QAAM,CAAC,OAAO,QAAQ,QAAI,wBAAyB;AAEnD,QAAM,eAAe,MAAM;AACzB,QAAI,YAAY;AACd;AAAA,IACF;AACA,iBAAa,KAAK;AAClB,iBAAa,IAAI;AAAA,EACnB;AAEA,QAAM,eAAe,MAAM;AACzB,QAAI,YAAY;AACd;AAAA,IACF;AACA,aAAS,WAAW,MAAM;AACxB,mBAAa,KAAK;AAAA,IACpB,GAAG,YAAY,CAAC;AAAA,EAClB;AAEA,+BAAU,MAAM;AACd,QAAI,OAAO;AACT,aAAO,MAAM;AACX,qBAAa,KAAK;AAAA,MACpB;AAAA,IACF;AAAA,EACF,CAAC;AAED,+BAAU,MAAM;AACd,QAAI,OAAO;AACT,mBAAa,KAAK;AAAA,IACpB;AAAA,EACF,GAAG,CAAC,UAAU,CAAC;AAEf,SAAO;AAAA,IACL;AAAA,IAAW;AAAA,IAAc,UAAU,EAAE,cAAc,aAAa;AAAA,EAClE;AACF;;;AC/EA,IAAM,UAAU,CAAI,UAAsC,QAAsB;AAC9E,MAAI,OAAO,aAAa,YAAY;AAClC,WAAQ,SAA4B,GAAG;AAAA,EACzC;AAEA,SAAO,YAAY;AACrB;AAEO,IAAM,kBAAkB;AAAA,EAC7B;AACF;;;ACHA,IAAM,gCAAgE;AAAA,EACpE,aAAa;AAAA,EACb,UAAU;AAAA,EACV,qBAAqB;AAAA,EACrB,mBAAmB;AAAA,EACnB,UAAU;AACZ;AAEO,IAAM,qBAAqB,CAAC,SAAmB,YAAoD;AACxG,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAoC,EAAE,GAAG,+BAA+B,GAAG,QAAQ;AAEnF,MAAI,YAAY,CAAC,SAAS;AACxB,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,OAAe;AAAA,IACnB,aAAa,QAAQ,OAAO;AAAA,IAC5B,YAAY,QAAQ;AAAA,IACpB,cAAc,QAAQ,QAAQ;AAAA,IAC9B,aAAa,QAAQ;AAAA,IACrB,QAAQ,QAAQ,OAAO,QAAQ,QAAQ;AAAA,EACzC,EAAE,mBAAmB;AAErB,QAAM,MAAc;AAAA,IAClB,YAAY,QAAQ,MAAM;AAAA,IAC1B,WAAW,QAAQ;AAAA,IACnB,eAAe,QAAQ,SAAS;AAAA,IAChC,cAAc,QAAQ;AAAA,IACtB,QAAQ,QAAQ,MAAM,QAAQ,SAAS;AAAA,EACzC,EAAE,iBAAiB;AAEnB,QAAM,aAAiC;AAAA,IACrC,aAAa;AAAA,IACb,YAAY;AAAA,IACZ,cAAc;AAAA,IACd,aAAa;AAAA,IACb,QAAQ;AAAA,EACV,EAAE,mBAAmB;AAErB,QAAM,aAAiC;AAAA,IACrC,YAAY;AAAA,IACZ,WAAW;AAAA,IACX,eAAe;AAAA,IACf,cAAc;AAAA,IACd,QAAQ;AAAA,EACV,EAAE,iBAAiB;AAEnB,SAAO;AAAA,IACL,MAAM,KAAK,IAAI,MAAM,WAAW;AAAA,IAChC,KAAK,KAAK,IAAI,KAAK,WAAW;AAAA,IAC9B,WAAW,CAAC,cAAc,KAAK,cAAc,GAAG,EAAE,KAAK,GAAG;AAAA,EAC5D;AACF;;;AJjEA,uBAA6B;AAe3B;AAPK,IAAM,WAAW,CAAC;AAAA,EACE;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ,aAAa;AAAA,EACb;AACF,MACvB;AAAA,EAAC;AAAA;AAAA,IACC,eAAW,YAAAC,SAAK,4FAA4F;AAAA,MAC1G,cAAc,cAAc;AAAA,MAC5B,aAAa,cAAc;AAAA,MAC3B,yCAAyC;AAAA,MACzC,sCAAsC,CAAC;AAAA,MACvC,kBAAkB,CAAC,CAAC;AAAA,IACtB,GAAG,SAAS;AAAA,IACZ;AAAA,IAEC;AAAA;AACH;AAGF,SAAS,qBAAqB,SAAS;AACrC,QAAM,cAAc,CAAC;AACrB,MAAI,SAAS,QAAQ;AACrB,SAAO,QAAQ;AACb,gBAAY,KAAK,MAAM;AACvB,aAAS,OAAO;AAAA,EAClB;AACA,SAAO;AACT;AAwBO,IAAM,OAAO,CAAwB;AAAA,EACE;AAAA,EACA;AAAA,EACA,sBAAsB;AAAA,EACtB,oBAAoB;AAAA,EACpB,cAAc;AAAA,EACd,WAAW;AAAA,EACX,gBAAgB;AAClB,MAAoB;AAC9D,QAAM,EAAE,WAAW,QAAQ,cAAc,UAAU,IAAI,cAAc,EAAE,YAAY,CAAC,eAAe,SAAS,CAAC;AAC7G,QAAM,iBAAa,sBAAU,IAAI;AACjC,QAAM,cAAU,sBAAuB,IAAI;AAC3C,kBAAgB,CAAC,YAAY,OAAO,GAAG,MAAM,UAAU,KAAK,CAAC;AAE7D,QAAM,CAAC,UAAU,WAAW,QAAI,wBAAkB,IAAI;AACtD,QAAM,MAAe;AAAA,IACnB;AAAA,IACA,OAAO,MAAM,UAAU,KAAK;AAAA,IAC5B,YAAY,MAAM,UAAU,eAAa,CAAC,SAAS;AAAA,IACnD;AAAA,EACF;AAEA,QAAM,eAAe;AAAA,IACnB,WAAW,SAAS,sBAAsB;AAAA,IAC1C,EAAE,mBAAmB,mBAAmB,qBAAqB,qBAAqB,SAAS;AAAA,EAC7F;AAEA,+BAAU,MAAM;AACd,QAAI,CAAC,OAAQ;AAEb,UAAM,YAAY,WAAW;AAC7B,QAAI,CAAC,UAAW;AAEhB,UAAM,oBAAoB,qBAAqB,SAAS;AAExD,UAAM,QAAQ,MAAM,UAAU,KAAK;AACnC,sBAAkB,QAAQ,CAAC,WAAW;AACpC,aAAO,iBAAiB,UAAU,KAAK;AAAA,IACzC,CAAC;AACD,WAAO,iBAAiB,UAAU,KAAK;AAEvC,WAAO,MAAM;AACX,wBAAkB,QAAQ,CAAC,WAAW;AACpC,eAAO,oBAAoB,UAAU,KAAK;AAAA,MAC5C,CAAC;AACD,aAAO,oBAAoB,UAAU,KAAK;AAAA,IAC5C;AAAA,EACF,GAAG,CAAC,QAAQ,SAAS,CAAC;AAEtB,+BAAU,MAAM;AACd,QAAI,QAAQ;AACV,kBAAY,KAAK;AAAA,IACnB;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAEX,SACE,4EACG;AAAA,YAAQ,KAAK,UAAU;AAAA,QACvB,+BACC;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,SAAS,OAAK,EAAE,gBAAgB;AAAA,QAChC,eAAW,YAAAA;AAAA,UACT;AAAA,UACA;AAAA,YACE,kBAAkB;AAAA,YAClB,mBAAmB,CAAC;AAAA,YACpB,UAAU;AAAA,UACZ;AAAA,UACA;AAAA,QACF;AAAA,QACA,gBAAgB,MAAM;AACpB,cAAI,CAAC,QAAQ;AACX,wBAAY,IAAI;AAAA,UAClB;AAAA,QACF;AAAA,QACA,OAAO;AAAA,UACL,GAAG;AAAA,QACL;AAAA,QAEC,0BAAgB,QAAiB,UAAU,GAAG;AAAA;AAAA,IACjD,GACC,SAAS,IAAI;AAAA,KAClB;AAEJ;","names":["import_react","import_react","clsx"]}
@@ -1,9 +1,5 @@
1
1
  // src/components/user-action/Menu.tsx
2
- import {
3
- useEffect as useEffect3,
4
- useRef,
5
- useState as useState2
6
- } from "react";
2
+ import { useEffect as useEffect3, useRef, useState as useState2 } from "react";
7
3
  import clsx from "clsx";
8
4
 
9
5
  // src/hooks/useOutsideClick.ts
@@ -147,7 +143,7 @@ var MenuItem = ({
147
143
  }) => /* @__PURE__ */ jsx(
148
144
  "div",
149
145
  {
150
- className: clsx("block px-3 py-1.5 first:rounded-t-md last:rounded-b-md text-sm font-semibold", {
146
+ className: clsx("block px-3 py-1.5 first:rounded-t-md last:rounded-b-md text-sm font-semibold text-nowrap", {
151
147
  "text-right": alignment === "right",
152
148
  "text-left": alignment === "left",
153
149
  "text-disabled-text cursor-not-allowed": isDisabled,
@@ -221,7 +217,7 @@ var Menu = ({
221
217
  ref: menuRef,
222
218
  onClick: (e) => e.stopPropagation(),
223
219
  className: clsx(
224
- "absolute rounded-md bg-menu-background text-menu-text shadow-around-lg z-[300]",
220
+ "absolute rounded-md bg-menu-background text-menu-text shadow-around-lg shadow-strong z-[300]",
225
221
  {
226
222
  "animate-pop-in": isOpen,
227
223
  "animate-pop-out": !isOpen,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/user-action/Menu.tsx","../../../src/hooks/useOutsideClick.ts","../../../src/hooks/useHoverState.ts","../../../src/util/PropsWithFunctionChildren.ts","../../../src/hooks/usePopoverPosition.ts"],"sourcesContent":["import {\n type PropsWithChildren,\n type ReactNode,\n type RefObject,\n useEffect,\n useRef, useState\n} from 'react'\nimport clsx from 'clsx'\nimport { useOutsideClick } from '../../hooks/useOutsideClick'\nimport { useHoverState } from '../../hooks/useHoverState'\nimport type { PropsWithBagFunctionOrChildren } from '../../util/PropsWithFunctionChildren'\nimport { BagFunctionUtil } from '../../util/PropsWithFunctionChildren'\nimport type { PopoverHorizontalAlignment, PopoverVerticalAlignment } from '../../hooks/usePopoverPosition'\nimport { usePopoverPosition } from '../../hooks/usePopoverPosition'\nimport { createPortal } from 'react-dom'\n\nexport type MenuItemProps = {\n onClick?: () => void,\n alignment?: 'left' | 'right',\n isDisabled?: boolean,\n className?: string,\n}\nexport const MenuItem = ({\n children,\n onClick,\n alignment = 'left',\n isDisabled = false,\n className\n }: PropsWithChildren<MenuItemProps>) => (\n <div\n className={clsx('block px-3 py-1.5 first:rounded-t-md last:rounded-b-md text-sm font-semibold', {\n 'text-right': alignment === 'right',\n 'text-left': alignment === 'left',\n 'text-disabled-text cursor-not-allowed': isDisabled,\n 'text-menu-text hover:bg-primary/20': !isDisabled,\n 'cursor-pointer': !!onClick,\n }, className)}\n onClick={onClick}\n >\n {children}\n </div>\n)\n\nfunction getScrollableParents(element) {\n const scrollables = []\n let parent = element.parentElement\n while (parent) {\n scrollables.push(parent)\n parent = parent.parentElement\n }\n return scrollables\n}\n\nexport type MenuBag = {\n isOpen: boolean,\n disabled: boolean,\n toggleOpen: () => void,\n close: () => void,\n}\n\nexport type MenuProps<T> = PropsWithBagFunctionOrChildren<MenuBag> & {\n trigger: (bag: MenuBag, ref: RefObject<T>) => ReactNode,\n /**\n * @default 'l'\n */\n alignmentHorizontal?: PopoverHorizontalAlignment,\n alignmentVertical?: PopoverVerticalAlignment,\n showOnHover?: boolean,\n menuClassName?: string,\n disabled?: boolean,\n}\n\n/**\n * A Menu Component to allow the user to see different functions\n */\nexport const Menu = <T extends HTMLElement>({\n trigger,\n children,\n alignmentHorizontal = 'leftInside',\n alignmentVertical = 'bottomOutside',\n showOnHover = false,\n disabled = false,\n menuClassName = '',\n }: MenuProps<T>) => {\n const { isHovered: isOpen, setIsHovered: setIsOpen } = useHoverState({ isDisabled: !showOnHover || disabled })\n const triggerRef = useRef<T>(null)\n const menuRef = useRef<HTMLDivElement>(null)\n useOutsideClick([triggerRef, menuRef], () => setIsOpen(false))\n\n const [isHidden, setIsHidden] = useState<boolean>(true)\n const bag: MenuBag = {\n isOpen,\n close: () => setIsOpen(false),\n toggleOpen: () => setIsOpen(prevState => !prevState),\n disabled,\n }\n\n const menuPosition = usePopoverPosition(\n triggerRef.current?.getBoundingClientRect(),\n { verticalAlignment: alignmentVertical, horizontalAlignment: alignmentHorizontal, disabled }\n )\n\n useEffect(() => {\n if (!isOpen) return\n\n const triggerEl = triggerRef.current\n if (!triggerEl) return\n\n const scrollableParents = getScrollableParents(triggerEl)\n\n const close = () => setIsOpen(false)\n scrollableParents.forEach((parent) => {\n parent.addEventListener('scroll', close)\n })\n window.addEventListener('resize', close)\n\n return () => {\n scrollableParents.forEach((parent) => {\n parent.removeEventListener('scroll', close)\n })\n window.removeEventListener('resize', close)\n }\n }, [isOpen, setIsOpen])\n\n useEffect(() => {\n if (isOpen) {\n setIsHidden(false)\n }\n }, [isOpen])\n\n return (\n <>\n {trigger(bag, triggerRef)}\n {createPortal((<div\n ref={menuRef}\n onClick={e => e.stopPropagation()}\n className={clsx(\n 'absolute rounded-md bg-menu-background text-menu-text shadow-around-lg z-[300]',\n {\n 'animate-pop-in': isOpen,\n 'animate-pop-out': !isOpen,\n 'hidden': isHidden,\n },\n menuClassName\n )}\n onAnimationEnd={() => {\n if (!isOpen) {\n setIsHidden(true)\n }\n }}\n style={{\n ...menuPosition\n }}\n >\n {BagFunctionUtil.resolve<MenuBag>(children, bag)}\n </div>), document.body)}\n </>\n )\n}\n\n","import type { RefObject } from 'react'\nimport { useEffect } from 'react'\n\nexport const useOutsideClick = <Ts extends RefObject<HTMLElement>[]>(refs: Ts, handler: () => void) => {\n useEffect(() => {\n const listener = (event: MouseEvent | TouchEvent) => {\n // returning means not \"not clicking outside\"\n\n // if no target exists, return\n if (event.target === null) return\n // if the target is a ref's element or descendent thereof, return\n if (refs.some((ref) => !ref.current || ref.current.contains(event.target as Node))) {\n return\n }\n\n handler()\n }\n document.addEventListener('mousedown', listener)\n document.addEventListener('touchstart', listener)\n return () => {\n document.removeEventListener('mousedown', listener)\n document.removeEventListener('touchstart', listener)\n }\n }, [refs, handler])\n}\n","import type { Dispatch, SetStateAction } from 'react'\nimport { useEffect, useState } from 'react'\n\ntype UseHoverStateProps = {\n /**\n * The delay after which the menu is closed in milliseconds\n *\n * default: 200ms\n */\n closingDelay: number,\n /**\n * Whether the hover state management should be disabled\n *\n * default: false\n */\n isDisabled: boolean,\n}\n\ntype UseHoverStateReturnType = {\n /**\n * Whether the element is hovered\n */\n isHovered: boolean,\n /**\n * Function to change the current hover status\n */\n setIsHovered: Dispatch<SetStateAction<boolean>>,\n /**\n * Handlers to pass on to the component that should be hovered\n */\n handlers: {\n onMouseEnter: () => void,\n onMouseLeave: () => void,\n },\n}\n\nconst defaultUseHoverStateProps: UseHoverStateProps = {\n closingDelay: 200,\n isDisabled: false,\n}\n\n/**\n * @param props See UseHoverStateProps\n *\n * A react hook for managing the hover state of a component. The handlers provided should be\n * forwarded to the component which should be hovered over\n */\nexport const useHoverState = (props: Partial<UseHoverStateProps> | undefined = undefined): UseHoverStateReturnType => {\n const { closingDelay, isDisabled } = { ...defaultUseHoverStateProps, ...props }\n\n const [isHovered, setIsHovered] = useState(false)\n const [timer, setTimer] = useState<NodeJS.Timeout>()\n\n const onMouseEnter = () => {\n if (isDisabled) {\n return\n }\n clearTimeout(timer)\n setIsHovered(true)\n }\n\n const onMouseLeave = () => {\n if (isDisabled) {\n return\n }\n setTimer(setTimeout(() => {\n setIsHovered(false)\n }, closingDelay))\n }\n\n useEffect(() => {\n if (timer) {\n return () => {\n clearTimeout(timer)\n }\n }\n })\n\n useEffect(() => {\n if (timer) {\n clearTimeout(timer)\n }\n }, [isDisabled]) // eslint-disable-line react-hooks/exhaustive-deps\n\n return {\n isHovered, setIsHovered, handlers: { onMouseEnter, onMouseLeave }\n }\n}\n","import type { ReactNode } from 'react'\n\nexport type BagFunction<T> = (bag: T) => ReactNode\n\nexport type PropsWithBagFunction<T, P = unknown> = P & { children?: BagFunction<T> }\n\nexport type PropsWithBagFunctionOrChildren<T, P = unknown> = P & { children?: BagFunction<T> | ReactNode }\n\nconst resolve = <T>(children: BagFunction<T> | ReactNode, bag: T): ReactNode => {\n if (typeof children === 'function') {\n return (children as BagFunction<T>)(bag)\n }\n\n return children ?? undefined\n}\n\nexport const BagFunctionUtil = {\n resolve\n}","import type { CSSProperties } from 'react'\n\nexport type PopoverHorizontalAlignment = 'leftOutside' | 'leftInside' | 'rightOutside' | 'rightInside' | 'center'\nexport type PopoverVerticalAlignment = 'topOutside' | 'topInside' | 'bottomOutside' | 'bottomInside' | 'center'\n\ntype PopoverPositionOptionsResolved = {\n edgePadding: number,\n outerGap: number,\n verticalAlignment: PopoverVerticalAlignment,\n horizontalAlignment: PopoverHorizontalAlignment,\n disabled: boolean,\n}\n\ntype PopoverPositionOptions = Partial<PopoverPositionOptionsResolved>\n\nconst defaultPopoverPositionOptions: PopoverPositionOptionsResolved = {\n edgePadding: 16,\n outerGap: 4,\n horizontalAlignment: 'leftInside',\n verticalAlignment: 'bottomOutside',\n disabled: false,\n}\n\nexport const usePopoverPosition = (trigger?: DOMRect, options?: PopoverPositionOptions): CSSProperties => {\n const {\n edgePadding,\n outerGap,\n verticalAlignment,\n horizontalAlignment,\n disabled\n }: PopoverPositionOptionsResolved = { ...defaultPopoverPositionOptions, ...options }\n\n if (disabled || !trigger) {\n return {}\n }\n\n const left: number = {\n leftOutside: trigger.left - outerGap,\n leftInside: trigger.left,\n rightOutside: trigger.right + outerGap,\n rightInside: trigger.right,\n center: trigger.left + trigger.width / 2,\n }[horizontalAlignment]\n\n const top: number = {\n topOutside: trigger.top - outerGap,\n topInside: trigger.top,\n bottomOutside: trigger.bottom + outerGap,\n bottomInside: trigger.bottom,\n center: trigger.top + trigger.height / 2,\n }[verticalAlignment]\n\n const translateX: string | undefined = {\n leftOutside: '-100%',\n leftInside: undefined,\n rightOutside: undefined,\n rightInside: '-100%',\n center: '-50%',\n }[horizontalAlignment]\n\n const translateY: string | undefined = {\n topOutside: '-100%',\n topInside: undefined,\n bottomOutside: undefined,\n bottomInside: '-100%',\n center: '-50%',\n }[verticalAlignment]\n\n return {\n left: Math.max(left, edgePadding),\n top: Math.max(top, edgePadding),\n translate: [translateX ?? '0', translateY ?? '0'].join(' ')\n }\n}"],"mappings":"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","names":["useEffect","useState","useEffect","useState","useEffect"]}
1
+ {"version":3,"sources":["../../../src/components/user-action/Menu.tsx","../../../src/hooks/useOutsideClick.ts","../../../src/hooks/useHoverState.ts","../../../src/util/PropsWithFunctionChildren.ts","../../../src/hooks/usePopoverPosition.ts"],"sourcesContent":["import { type PropsWithChildren, type ReactNode, type RefObject, useEffect, useRef, useState } from 'react'\nimport clsx from 'clsx'\nimport { useOutsideClick } from '../../hooks/useOutsideClick'\nimport { useHoverState } from '../../hooks/useHoverState'\nimport type { PropsWithBagFunctionOrChildren } from '../../util/PropsWithFunctionChildren'\nimport { BagFunctionUtil } from '../../util/PropsWithFunctionChildren'\nimport type { PopoverHorizontalAlignment, PopoverVerticalAlignment } from '../../hooks/usePopoverPosition'\nimport { usePopoverPosition } from '../../hooks/usePopoverPosition'\nimport { createPortal } from 'react-dom'\n\nexport type MenuItemProps = {\n onClick?: () => void,\n alignment?: 'left' | 'right',\n isDisabled?: boolean,\n className?: string,\n}\nexport const MenuItem = ({\n children,\n onClick,\n alignment = 'left',\n isDisabled = false,\n className\n }: PropsWithChildren<MenuItemProps>) => (\n <div\n className={clsx('block px-3 py-1.5 first:rounded-t-md last:rounded-b-md text-sm font-semibold text-nowrap', {\n 'text-right': alignment === 'right',\n 'text-left': alignment === 'left',\n 'text-disabled-text cursor-not-allowed': isDisabled,\n 'text-menu-text hover:bg-primary/20': !isDisabled,\n 'cursor-pointer': !!onClick,\n }, className)}\n onClick={onClick}\n >\n {children}\n </div>\n)\n\nfunction getScrollableParents(element) {\n const scrollables = []\n let parent = element.parentElement\n while (parent) {\n scrollables.push(parent)\n parent = parent.parentElement\n }\n return scrollables\n}\n\nexport type MenuBag = {\n isOpen: boolean,\n disabled: boolean,\n toggleOpen: () => void,\n close: () => void,\n}\n\nexport type MenuProps<T> = PropsWithBagFunctionOrChildren<MenuBag> & {\n trigger: (bag: MenuBag, ref: RefObject<T>) => ReactNode,\n /**\n * @default 'l'\n */\n alignmentHorizontal?: PopoverHorizontalAlignment,\n alignmentVertical?: PopoverVerticalAlignment,\n showOnHover?: boolean,\n menuClassName?: string,\n disabled?: boolean,\n}\n\n/**\n * A Menu Component to allow the user to see different functions\n */\nexport const Menu = <T extends HTMLElement>({\n trigger,\n children,\n alignmentHorizontal = 'leftInside',\n alignmentVertical = 'bottomOutside',\n showOnHover = false,\n disabled = false,\n menuClassName = '',\n }: MenuProps<T>) => {\n const { isHovered: isOpen, setIsHovered: setIsOpen } = useHoverState({ isDisabled: !showOnHover || disabled })\n const triggerRef = useRef<T>(null)\n const menuRef = useRef<HTMLDivElement>(null)\n useOutsideClick([triggerRef, menuRef], () => setIsOpen(false))\n\n const [isHidden, setIsHidden] = useState<boolean>(true)\n const bag: MenuBag = {\n isOpen,\n close: () => setIsOpen(false),\n toggleOpen: () => setIsOpen(prevState => !prevState),\n disabled,\n }\n\n const menuPosition = usePopoverPosition(\n triggerRef.current?.getBoundingClientRect(),\n { verticalAlignment: alignmentVertical, horizontalAlignment: alignmentHorizontal, disabled }\n )\n\n useEffect(() => {\n if (!isOpen) return\n\n const triggerEl = triggerRef.current\n if (!triggerEl) return\n\n const scrollableParents = getScrollableParents(triggerEl)\n\n const close = () => setIsOpen(false)\n scrollableParents.forEach((parent) => {\n parent.addEventListener('scroll', close)\n })\n window.addEventListener('resize', close)\n\n return () => {\n scrollableParents.forEach((parent) => {\n parent.removeEventListener('scroll', close)\n })\n window.removeEventListener('resize', close)\n }\n }, [isOpen, setIsOpen])\n\n useEffect(() => {\n if (isOpen) {\n setIsHidden(false)\n }\n }, [isOpen])\n\n return (\n <>\n {trigger(bag, triggerRef)}\n {createPortal((\n <div\n ref={menuRef}\n onClick={e => e.stopPropagation()}\n className={clsx(\n 'absolute rounded-md bg-menu-background text-menu-text shadow-around-lg shadow-strong z-[300]',\n {\n 'animate-pop-in': isOpen,\n 'animate-pop-out': !isOpen,\n 'hidden': isHidden,\n },\n menuClassName\n )}\n onAnimationEnd={() => {\n if (!isOpen) {\n setIsHidden(true)\n }\n }}\n style={{\n ...menuPosition\n }}\n >\n {BagFunctionUtil.resolve<MenuBag>(children, bag)}\n </div>\n ), document.body)}\n </>\n )\n}\n\n","import type { RefObject } from 'react'\nimport { useEffect } from 'react'\n\nexport const useOutsideClick = <Ts extends RefObject<HTMLElement>[]>(refs: Ts, handler: () => void) => {\n useEffect(() => {\n const listener = (event: MouseEvent | TouchEvent) => {\n // returning means not \"not clicking outside\"\n\n // if no target exists, return\n if (event.target === null) return\n // if the target is a ref's element or descendent thereof, return\n if (refs.some((ref) => !ref.current || ref.current.contains(event.target as Node))) {\n return\n }\n\n handler()\n }\n document.addEventListener('mousedown', listener)\n document.addEventListener('touchstart', listener)\n return () => {\n document.removeEventListener('mousedown', listener)\n document.removeEventListener('touchstart', listener)\n }\n }, [refs, handler])\n}\n","import type { Dispatch, SetStateAction } from 'react'\nimport { useEffect, useState } from 'react'\n\ntype UseHoverStateProps = {\n /**\n * The delay after which the menu is closed in milliseconds\n *\n * default: 200ms\n */\n closingDelay: number,\n /**\n * Whether the hover state management should be disabled\n *\n * default: false\n */\n isDisabled: boolean,\n}\n\ntype UseHoverStateReturnType = {\n /**\n * Whether the element is hovered\n */\n isHovered: boolean,\n /**\n * Function to change the current hover status\n */\n setIsHovered: Dispatch<SetStateAction<boolean>>,\n /**\n * Handlers to pass on to the component that should be hovered\n */\n handlers: {\n onMouseEnter: () => void,\n onMouseLeave: () => void,\n },\n}\n\nconst defaultUseHoverStateProps: UseHoverStateProps = {\n closingDelay: 200,\n isDisabled: false,\n}\n\n/**\n * @param props See UseHoverStateProps\n *\n * A react hook for managing the hover state of a component. The handlers provided should be\n * forwarded to the component which should be hovered over\n */\nexport const useHoverState = (props: Partial<UseHoverStateProps> | undefined = undefined): UseHoverStateReturnType => {\n const { closingDelay, isDisabled } = { ...defaultUseHoverStateProps, ...props }\n\n const [isHovered, setIsHovered] = useState(false)\n const [timer, setTimer] = useState<NodeJS.Timeout>()\n\n const onMouseEnter = () => {\n if (isDisabled) {\n return\n }\n clearTimeout(timer)\n setIsHovered(true)\n }\n\n const onMouseLeave = () => {\n if (isDisabled) {\n return\n }\n setTimer(setTimeout(() => {\n setIsHovered(false)\n }, closingDelay))\n }\n\n useEffect(() => {\n if (timer) {\n return () => {\n clearTimeout(timer)\n }\n }\n })\n\n useEffect(() => {\n if (timer) {\n clearTimeout(timer)\n }\n }, [isDisabled]) // eslint-disable-line react-hooks/exhaustive-deps\n\n return {\n isHovered, setIsHovered, handlers: { onMouseEnter, onMouseLeave }\n }\n}\n","import type { ReactNode } from 'react'\n\nexport type BagFunction<T> = (bag: T) => ReactNode\n\nexport type PropsWithBagFunction<T, P = unknown> = P & { children?: BagFunction<T> }\n\nexport type PropsWithBagFunctionOrChildren<T, P = unknown> = P & { children?: BagFunction<T> | ReactNode }\n\nconst resolve = <T>(children: BagFunction<T> | ReactNode, bag: T): ReactNode => {\n if (typeof children === 'function') {\n return (children as BagFunction<T>)(bag)\n }\n\n return children ?? undefined\n}\n\nexport const BagFunctionUtil = {\n resolve\n}","import type { CSSProperties } from 'react'\n\nexport type PopoverHorizontalAlignment = 'leftOutside' | 'leftInside' | 'rightOutside' | 'rightInside' | 'center'\nexport type PopoverVerticalAlignment = 'topOutside' | 'topInside' | 'bottomOutside' | 'bottomInside' | 'center'\n\ntype PopoverPositionOptionsResolved = {\n edgePadding: number,\n outerGap: number,\n verticalAlignment: PopoverVerticalAlignment,\n horizontalAlignment: PopoverHorizontalAlignment,\n disabled: boolean,\n}\n\ntype PopoverPositionOptions = Partial<PopoverPositionOptionsResolved>\n\nconst defaultPopoverPositionOptions: PopoverPositionOptionsResolved = {\n edgePadding: 16,\n outerGap: 4,\n horizontalAlignment: 'leftInside',\n verticalAlignment: 'bottomOutside',\n disabled: false,\n}\n\nexport const usePopoverPosition = (trigger?: DOMRect, options?: PopoverPositionOptions): CSSProperties => {\n const {\n edgePadding,\n outerGap,\n verticalAlignment,\n horizontalAlignment,\n disabled\n }: PopoverPositionOptionsResolved = { ...defaultPopoverPositionOptions, ...options }\n\n if (disabled || !trigger) {\n return {}\n }\n\n const left: number = {\n leftOutside: trigger.left - outerGap,\n leftInside: trigger.left,\n rightOutside: trigger.right + outerGap,\n rightInside: trigger.right,\n center: trigger.left + trigger.width / 2,\n }[horizontalAlignment]\n\n const top: number = {\n topOutside: trigger.top - outerGap,\n topInside: trigger.top,\n bottomOutside: trigger.bottom + outerGap,\n bottomInside: trigger.bottom,\n center: trigger.top + trigger.height / 2,\n }[verticalAlignment]\n\n const translateX: string | undefined = {\n leftOutside: '-100%',\n leftInside: undefined,\n rightOutside: undefined,\n rightInside: '-100%',\n center: '-50%',\n }[horizontalAlignment]\n\n const translateY: string | undefined = {\n topOutside: '-100%',\n topInside: undefined,\n bottomOutside: undefined,\n bottomInside: '-100%',\n center: '-50%',\n }[verticalAlignment]\n\n return {\n left: Math.max(left, edgePadding),\n top: Math.max(top, edgePadding),\n translate: [translateX ?? '0', translateY ?? '0'].join(' ')\n }\n}"],"mappings":"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","names":["useEffect","useState","useEffect","useState","useEffect"]}
@@ -494,7 +494,7 @@ var Menu = ({
494
494
  ref: menuRef,
495
495
  onClick: (e) => e.stopPropagation(),
496
496
  className: (0, import_clsx4.default)(
497
- "absolute rounded-md bg-menu-background text-menu-text shadow-around-lg z-[300]",
497
+ "absolute rounded-md bg-menu-background text-menu-text shadow-around-lg shadow-strong z-[300]",
498
498
  {
499
499
  "animate-pop-in": isOpen,
500
500
  "animate-pop-out": !isOpen,
@@ -646,7 +646,7 @@ var getInputClassName = ({ disabled = false, hasError = false }) => {
646
646
  return (0, import_clsx5.default)(
647
647
  "px-2 py-1.5 rounded-md border-2",
648
648
  {
649
- "bg-surface text-on-surface hover:border-primary focus:border-primary": !disabled && !hasError,
649
+ "bg-input-background text-input-text hover:border-primary focus:border-primary": !disabled && !hasError,
650
650
  "bg-on-negative text-negative border-negative-border hover:border-negative-border-hover": !disabled && hasError,
651
651
  "bg-disabled-background text-disabled-text border-disabled-border": disabled
652
652
  }
@@ -946,6 +946,7 @@ var SolidButton = (0, import_react11.forwardRef)(function SolidButton2({
946
946
  onClick,
947
947
  disabled,
948
948
  className: (0, import_clsx6.default)(
949
+ "font-semibold",
949
950
  {
950
951
  "text-disabled-text bg-disabled-background cursor-not-allowed": disabled,
951
952
  [(0, import_clsx6.default)(colorClasses, "hover:brightness-90")]: !disabled
@@ -1246,7 +1247,7 @@ var Checkbox = ({
1246
1247
  className: (0, import_clsx10.default)(usedSizeClass, `items-center border-2 rounded outline-none `, {
1247
1248
  "text-disabled-text border-disabled-outline bg-disabled-background cursor-not-allowed": disabled,
1248
1249
  "focus:border-primary group-hover:border-primary ": !disabled,
1249
- "bg-surface": !disabled && !checked,
1250
+ "bg-input-background": !disabled && !checked,
1250
1251
  "bg-primary/30 border-primary text-primary": !disabled && checked === true || checked === "indeterminate"
1251
1252
  }, className),
1252
1253
  children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(CheckboxPrimitive.Indicator, { children: [
@@ -1312,17 +1313,17 @@ var MultiSelect = ({
1312
1313
  {
1313
1314
  ref,
1314
1315
  className: (0, import_clsx11.default)(
1315
- "btn-md justify-between w-full border-2 h-auto",
1316
+ "group btn-md justify-between w-full border-2 h-auto",
1316
1317
  {
1317
1318
  "min-h-14": useChipDisplay,
1318
- "bg-menu-background text-menu-text border-menu-border hover:border-primary": !disabled,
1319
+ "bg-input-background text-input-text hover:border-primary": !disabled,
1319
1320
  "bg-disabled-background text-disabled-text border-disabled-background cursor-not-allowed": disabled
1320
1321
  },
1321
1322
  triggerClassName
1322
1323
  ),
1323
1324
  onClick: toggleOpen,
1324
1325
  disabled,
1325
- children: useChipDisplay ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_jsx_runtime12.Fragment, { children: isShowingHint ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconButton, { disabled, size: "small", color: "neutral", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react5.Plus, {}) }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ChipList, { list: selectedItems.map((value) => ({ children: value.label })) }) }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
1326
+ children: useChipDisplay ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_jsx_runtime12.Fragment, { children: isShowingHint ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "icon-btn-sm bg-button-solid-neutral-background text-button-solid-neutral-text hover:brightness-90 group-hover:brightness-90", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react5.Plus, {}) }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ChipList, { list: selectedItems.map((value) => ({ children: value.label })) }) }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
1326
1327
  !isShowingHint && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "font-semibold", children: selectedDisplayOverwrite ?? translation("selected", { replacements: { amount: selectedItems.length.toString() } }) }),
1327
1328
  isShowingHint && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: (0, import_clsx11.default)("textstyle-description", hintTextClassName), children: hintText ?? translation("select") }),
1328
1329
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ExpansionIcon, { isExpanded: isOpen })