@mittwald/flow-react-components 1.3.0-next.9 → 1.3.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 (186) hide show
  1. package/AGENTS.md +42 -1
  2. package/USAGE.md +14 -6
  3. package/dist/assets/component-index.json +1 -1
  4. package/dist/assets/doc-properties.json +1 -1
  5. package/dist/css/all-layered.css +1 -1
  6. package/dist/css/all.css +1 -1
  7. package/dist/js/_virtual/_28.locale.mjs +10 -0
  8. package/dist/js/default.mjs +1 -2
  9. package/dist/js/flr-universal.mjs +1 -2
  10. package/dist/js/packages/components/src/components/Accordion/Accordion.mjs +26 -15
  11. package/dist/js/packages/components/src/components/Accordion/Accordion.mjs.map +1 -1
  12. package/dist/js/packages/components/src/components/Accordion/Accordion.module.mjs.map +1 -1
  13. package/dist/js/packages/components/src/components/Action/models/ActionModel.mjs +8 -25
  14. package/dist/js/packages/components/src/components/Action/models/ActionModel.mjs.map +1 -1
  15. package/dist/js/packages/components/src/components/Avatar/Avatar.module.mjs.map +1 -1
  16. package/dist/js/packages/components/src/components/Button/Button.module.mjs +1 -0
  17. package/dist/js/packages/components/src/components/Button/Button.module.mjs.map +1 -1
  18. package/dist/js/packages/components/src/components/Calendar/Calendar.module.mjs +3 -1
  19. package/dist/js/packages/components/src/components/Calendar/Calendar.module.mjs.map +1 -1
  20. package/dist/js/packages/components/src/components/Calendar/components/CalendarHeader/CalendarHeader.mjs +19 -15
  21. package/dist/js/packages/components/src/components/Calendar/components/CalendarHeader/CalendarHeader.mjs.map +1 -1
  22. package/dist/js/packages/components/src/components/CartesianChart/CartesianChart.module.mjs.map +1 -1
  23. package/dist/js/packages/components/src/components/CartesianChart/components/Area/Area.mjs +4 -1
  24. package/dist/js/packages/components/src/components/CartesianChart/components/Area/Area.mjs.map +1 -1
  25. package/dist/js/packages/components/src/components/CartesianChart/components/Bar/Bar.mjs +4 -1
  26. package/dist/js/packages/components/src/components/CartesianChart/components/Bar/Bar.mjs.map +1 -1
  27. package/dist/js/packages/components/src/components/CartesianChart/components/Line/Line.mjs +4 -1
  28. package/dist/js/packages/components/src/components/CartesianChart/components/Line/Line.mjs.map +1 -1
  29. package/dist/js/packages/components/src/components/CartesianChart/hooks/useChartAnimation.mjs +27 -0
  30. package/dist/js/packages/components/src/components/CartesianChart/hooks/useChartAnimation.mjs.map +1 -0
  31. package/dist/js/packages/components/src/components/Chat/Chat.module.mjs.map +1 -1
  32. package/dist/js/packages/components/src/components/Checkbox/Checkbox.module.mjs +2 -1
  33. package/dist/js/packages/components/src/components/Checkbox/Checkbox.module.mjs.map +1 -1
  34. package/dist/js/packages/components/src/components/CheckboxGroup/CheckboxGroup.module.mjs.map +1 -1
  35. package/dist/js/packages/components/src/components/CodeBlock/CodeBlock.mjs +31 -5
  36. package/dist/js/packages/components/src/components/CodeBlock/CodeBlock.mjs.map +1 -1
  37. package/dist/js/packages/components/src/components/CodeBlock/CodeBlock.module.mjs +6 -4
  38. package/dist/js/packages/components/src/components/CodeBlock/CodeBlock.module.mjs.map +1 -1
  39. package/dist/js/packages/components/src/components/Combine/Combine.module.mjs.map +1 -1
  40. package/dist/js/packages/components/src/components/ComboBox/ComboBox.module.mjs.map +1 -1
  41. package/dist/js/packages/components/src/components/ContextMenu/ContextMenu.mjs +2 -2
  42. package/dist/js/packages/components/src/components/ContextMenu/ContextMenu.mjs.map +1 -1
  43. package/dist/js/packages/components/src/components/ContextMenu/ContextMenu.module.mjs.map +1 -1
  44. package/dist/js/packages/components/src/components/ContextMenu/components/ContextMenuSection/ContextMenuSection.mjs +2 -2
  45. package/dist/js/packages/components/src/components/ContextMenu/components/ContextMenuSection/ContextMenuSection.mjs.map +1 -1
  46. package/dist/js/packages/components/src/components/ContextMenu/lib.mjs +3 -7
  47. package/dist/js/packages/components/src/components/ContextMenu/lib.mjs.map +1 -1
  48. package/dist/js/packages/components/src/components/DateRangePicker/components/DateRangeInput/DateRangeInput.mjs +14 -11
  49. package/dist/js/packages/components/src/components/DateRangePicker/components/DateRangeInput/DateRangeInput.mjs.map +1 -1
  50. package/dist/js/packages/components/src/components/DateRangePicker/components/DateRangeInput/DateRangeInput.module.mjs +4 -2
  51. package/dist/js/packages/components/src/components/DateRangePicker/components/DateRangeInput/DateRangeInput.module.mjs.map +1 -1
  52. package/dist/js/packages/components/src/components/DonutChart/DonutChart.module.mjs +6 -3
  53. package/dist/js/packages/components/src/components/DonutChart/DonutChart.module.mjs.map +1 -1
  54. package/dist/js/packages/components/src/components/DonutChart/components/DonutChartFill.mjs +13 -2
  55. package/dist/js/packages/components/src/components/DonutChart/components/DonutChartFill.mjs.map +1 -1
  56. package/dist/js/packages/components/src/components/FileDropZone/FileDropZone.mjs +2 -2
  57. package/dist/js/packages/components/src/components/FileDropZone/FileDropZone.mjs.map +1 -1
  58. package/dist/js/packages/components/src/components/HeaderNavigation/HeaderNavigation.mjs +9 -6
  59. package/dist/js/packages/components/src/components/HeaderNavigation/HeaderNavigation.mjs.map +1 -1
  60. package/dist/js/packages/components/src/components/HeaderNavigation/HeaderNavigation.module.mjs +5 -1
  61. package/dist/js/packages/components/src/components/HeaderNavigation/HeaderNavigation.module.mjs.map +1 -1
  62. package/dist/js/packages/components/src/components/Heading/Heading.mjs +1 -1
  63. package/dist/js/packages/components/src/components/Heading/Heading.mjs.map +1 -1
  64. package/dist/js/packages/components/src/components/Heading/Heading.module.mjs.map +1 -1
  65. package/dist/js/packages/components/src/components/LayoutCard/LayoutCard.module.mjs.map +1 -1
  66. package/dist/js/packages/components/src/components/LightBox/LightBox.module.mjs.map +1 -1
  67. package/dist/js/packages/components/src/components/LightBox/components/LightBoxGallery/Controls.mjs +1 -1
  68. package/dist/js/packages/components/src/components/LightBox/components/LightBoxGallery/Controls.mjs.map +1 -1
  69. package/dist/js/packages/components/src/components/Link/Link.module.mjs.map +1 -1
  70. package/dist/js/packages/components/src/components/List/List.module.mjs.map +1 -1
  71. package/dist/js/packages/components/src/components/List/components/Header/components/SearchField/SearchField.module.mjs.map +1 -1
  72. package/dist/js/packages/components/src/components/List/components/Items/Items.mjs +3 -6
  73. package/dist/js/packages/components/src/components/List/components/Items/Items.mjs.map +1 -1
  74. package/dist/js/packages/components/src/components/List/components/Items/components/Item/Item.module.mjs.map +1 -1
  75. package/dist/js/packages/components/src/components/List/components/ListItemView/ListItemView.module.mjs.map +1 -1
  76. package/dist/js/packages/components/src/components/List/components/Table/Table.mjs +6 -2
  77. package/dist/js/packages/components/src/components/List/components/Table/Table.mjs.map +1 -1
  78. package/dist/js/packages/components/src/components/List/{components/Items/hooks → hooks}/useInfiniteScrollTrigger.mjs +11 -12
  79. package/dist/js/packages/components/src/components/List/hooks/useInfiniteScrollTrigger.mjs.map +1 -0
  80. package/dist/js/packages/components/src/components/Markdown/Markdown.module.mjs.map +1 -1
  81. package/dist/js/packages/components/src/components/MarkdownEditor/MarkdownEditor.module.mjs.map +1 -1
  82. package/dist/js/packages/components/src/components/MessageThread/MessageThread.module.mjs.map +1 -1
  83. package/dist/js/packages/components/src/components/Modal/Modal.mjs +4 -6
  84. package/dist/js/packages/components/src/components/Modal/Modal.mjs.map +1 -1
  85. package/dist/js/packages/components/src/components/Modal/Modal.module.mjs.map +1 -1
  86. package/dist/js/packages/components/src/components/Navigation/Navigation.module.mjs +3 -1
  87. package/dist/js/packages/components/src/components/Navigation/Navigation.module.mjs.map +1 -1
  88. package/dist/js/packages/components/src/components/Navigation/components/LinkListTunnelExit/LinkListTunnelExit.mjs +5 -1
  89. package/dist/js/packages/components/src/components/Navigation/components/LinkListTunnelExit/LinkListTunnelExit.mjs.map +1 -1
  90. package/dist/js/packages/components/src/components/Navigation/components/NavigationGroup/NavigationGroup.module.mjs.map +1 -1
  91. package/dist/js/packages/components/src/components/NumberField/NumberField.module.mjs.map +1 -1
  92. package/dist/js/packages/components/src/components/Overlay/Overlay.module.mjs +3 -1
  93. package/dist/js/packages/components/src/components/Overlay/Overlay.module.mjs.map +1 -1
  94. package/dist/js/packages/components/src/components/Overlay/components/OverlayContent.mjs +47 -9
  95. package/dist/js/packages/components/src/components/Overlay/components/OverlayContent.mjs.map +1 -1
  96. package/dist/js/packages/components/src/components/OverlayTrigger/OverlayTrigger.mjs +0 -1
  97. package/dist/js/packages/components/src/components/OverlayTrigger/OverlayTrigger.mjs.map +1 -1
  98. package/dist/js/packages/components/src/components/PasswordCreationField/PasswordCreationField.mjs +8 -1
  99. package/dist/js/packages/components/src/components/PasswordCreationField/PasswordCreationField.mjs.map +1 -1
  100. package/dist/js/packages/components/src/components/PasswordCreationField/components/PasswordGenerateButton/PasswordGenerateButton.mjs +2 -0
  101. package/dist/js/packages/components/src/components/PasswordCreationField/components/PasswordGenerateButton/PasswordGenerateButton.mjs.map +1 -1
  102. package/dist/js/packages/components/src/components/PasswordCreationField/components/ValidationResultButton/ValidationResultButton.mjs +13 -7
  103. package/dist/js/packages/components/src/components/PasswordCreationField/components/ValidationResultButton/ValidationResultButton.mjs.map +1 -1
  104. package/dist/js/packages/components/src/components/PasswordCreationField/components/ValidationResultButton/ValidationResultButton.module.mjs +9 -0
  105. package/dist/js/packages/components/src/components/PasswordCreationField/components/ValidationResultButton/ValidationResultButton.module.mjs.map +1 -0
  106. package/dist/js/packages/components/src/components/PasswordCreationField/components/ValidationResultEntry/ValidationResultEntry.mjs +12 -4
  107. package/dist/js/packages/components/src/components/PasswordCreationField/components/ValidationResultEntry/ValidationResultEntry.mjs.map +1 -1
  108. package/dist/js/packages/components/src/components/PasswordCreationField/lib/ariaAnnounce.mjs +52 -0
  109. package/dist/js/packages/components/src/components/PasswordCreationField/lib/ariaAnnounce.mjs.map +1 -0
  110. package/dist/js/packages/components/src/components/PasswordCreationField/lib/generateValidationTranslation.mjs +1 -0
  111. package/dist/js/packages/components/src/components/PasswordCreationField/lib/generateValidationTranslation.mjs.map +1 -1
  112. package/dist/js/packages/components/src/components/PasswordCreationField/lib/getStatusFromPolicyValidationResult.mjs +1 -0
  113. package/dist/js/packages/components/src/components/PasswordCreationField/lib/getStatusFromPolicyValidationResult.mjs.map +1 -1
  114. package/dist/js/packages/components/src/components/PasswordCreationField/lib/usePolicyValidationResult.mjs +1 -0
  115. package/dist/js/packages/components/src/components/PasswordCreationField/lib/usePolicyValidationResult.mjs.map +1 -1
  116. package/dist/js/packages/components/src/components/Popover/Popover.module.mjs +3 -1
  117. package/dist/js/packages/components/src/components/Popover/Popover.module.mjs.map +1 -1
  118. package/dist/js/packages/components/src/components/Popover/components/NonModalPopoverContent/NonModalPopoverContent.mjs +2 -6
  119. package/dist/js/packages/components/src/components/Popover/components/NonModalPopoverContent/NonModalPopoverContent.mjs.map +1 -1
  120. package/dist/js/packages/components/src/components/Popover/components/PopoverContent/PopoverContent.mjs +2 -6
  121. package/dist/js/packages/components/src/components/Popover/components/PopoverContent/PopoverContent.mjs.map +1 -1
  122. package/dist/js/packages/components/src/components/Popover/components/PopoverTip/PopoverTip.mjs +17 -0
  123. package/dist/js/packages/components/src/components/Popover/components/PopoverTip/PopoverTip.mjs.map +1 -0
  124. package/dist/js/packages/components/src/components/ProgressBar/ProgressBar.module.mjs +1 -0
  125. package/dist/js/packages/components/src/components/ProgressBar/ProgressBar.module.mjs.map +1 -1
  126. package/dist/js/packages/components/src/components/RadioGroup/components/Radio/Radio.module.mjs +2 -1
  127. package/dist/js/packages/components/src/components/RadioGroup/components/Radio/Radio.module.mjs.map +1 -1
  128. package/dist/js/packages/components/src/components/SearchField/SearchField.module.mjs +3 -3
  129. package/dist/js/packages/components/src/components/SearchField/SearchField.module.mjs.map +1 -1
  130. package/dist/js/packages/components/src/components/Section/Section.module.mjs.map +1 -1
  131. package/dist/js/packages/components/src/components/Section/components/SectionHeader/SectionHeader.module.mjs.map +1 -1
  132. package/dist/js/packages/components/src/components/Slider/Slider.module.mjs.map +1 -1
  133. package/dist/js/packages/components/src/components/Switch/Switch.module.mjs.map +1 -1
  134. package/dist/js/packages/components/src/components/TabNavigation/TabNavigation.mjs +2 -1
  135. package/dist/js/packages/components/src/components/TabNavigation/TabNavigation.mjs.map +1 -1
  136. package/dist/js/packages/components/src/components/TabNavigation/TabNavigation.module.mjs +5 -1
  137. package/dist/js/packages/components/src/components/TabNavigation/TabNavigation.module.mjs.map +1 -1
  138. package/dist/js/packages/components/src/components/Table/Table.module.mjs.map +1 -1
  139. package/dist/js/packages/components/src/components/Tabs/components/TabTitle/TabTitle.module.mjs.map +1 -1
  140. package/dist/js/packages/components/src/components/Text/Text.module.mjs.map +1 -1
  141. package/dist/js/packages/components/src/components/TextArea/TextArea.mjs +14 -13
  142. package/dist/js/packages/components/src/components/TextArea/TextArea.mjs.map +1 -1
  143. package/dist/js/packages/components/src/components/Tooltip/Tooltip.mjs +1 -0
  144. package/dist/js/packages/components/src/components/Tooltip/Tooltip.mjs.map +1 -1
  145. package/dist/js/packages/components/src/components/Tooltip/Tooltip.module.mjs +3 -1
  146. package/dist/js/packages/components/src/components/Tooltip/Tooltip.module.mjs.map +1 -1
  147. package/dist/js/packages/components/src/lib/controller/overlay/OverlayContextProvider.mjs +3 -6
  148. package/dist/js/packages/components/src/lib/controller/overlay/OverlayContextProvider.mjs.map +1 -1
  149. package/dist/js/packages/components/src/lib/controller/overlay/OverlayController.mjs.map +1 -1
  150. package/dist/js/packages/components/src/lib/controller/overlay/context.mjs +1 -1
  151. package/dist/js/packages/components/src/lib/controller/overlay/context.mjs.map +1 -1
  152. package/dist/js/packages/components/src/lib/controller/overlay/useOverlayController.mjs +1 -1
  153. package/dist/js/packages/components/src/lib/controller/overlay/useOverlayController.mjs.map +1 -1
  154. package/dist/js/packages/components/src/lib/files/acceptedFiles.mjs +34 -0
  155. package/dist/js/packages/components/src/lib/files/acceptedFiles.mjs.map +1 -0
  156. package/dist/js/packages/components/src/lib/hooks/dom/useKeepBrowserExtensionsInteractive.mjs +1 -1
  157. package/dist/js/packages/components/src/lib/hooks/dom/useKeepBrowserExtensionsInteractive.mjs.map +1 -1
  158. package/dist/js/packages/design-tokens/dist/json-runtime/all-dark.mjs +12 -0
  159. package/dist/js/packages/design-tokens/dist/json-runtime/all-dark.mjs.map +1 -1
  160. package/dist/js/packages/design-tokens/dist/json-runtime/all-light.mjs +12 -0
  161. package/dist/js/packages/design-tokens/dist/json-runtime/all-light.mjs.map +1 -1
  162. package/dist/types/components/Action/models/ActionModel.d.ts +4 -12
  163. package/dist/types/components/Action/types.d.ts +2 -9
  164. package/dist/types/components/CartesianChart/hooks/useChartAnimation.d.ts +1 -0
  165. package/dist/types/components/ContextMenu/lib.d.ts +1 -5
  166. package/dist/types/components/Icon/components/icons/index.d.ts +0 -1
  167. package/dist/types/components/List/hooks/useInfiniteScrollTrigger.d.ts +17 -0
  168. package/dist/types/components/PasswordCreationField/components/PasswordGenerateButton/PasswordGenerateButton.d.ts +0 -7
  169. package/dist/types/components/PasswordCreationField/components/ValidationResultButton/ValidationResultButton.d.ts +0 -9
  170. package/dist/types/components/PasswordCreationField/lib/ariaAnnounce.d.ts +1 -0
  171. package/dist/types/components/PasswordCreationField/lib/generateValidationTranslation.d.ts +0 -2
  172. package/dist/types/components/PasswordCreationField/lib/getStatusFromPolicyValidationResult.d.ts +0 -3
  173. package/dist/types/components/PasswordCreationField/lib/usePolicyValidationResult.d.ts +1 -7
  174. package/dist/types/components/Popover/components/PopoverTip/PopoverTip.d.ts +1 -2
  175. package/dist/types/lib/controller/overlay/OverlayContextProvider.d.ts +0 -9
  176. package/dist/types/lib/controller/overlay/OverlayController.d.ts +1 -11
  177. package/dist/types/lib/controller/overlay/context.d.ts +2 -19
  178. package/dist/types/lib/files/acceptedFiles.d.ts +1 -0
  179. package/dist/types/lib/hooks/dom/useKeepBrowserExtensionsInteractive.d.ts +1 -0
  180. package/dist/types/lib/theming/hooks/useDesignTokens.d.ts +14 -0
  181. package/package.json +10 -10
  182. package/dist/js/packages/components/src/components/Icon/components/icons/IconAIHosting.mjs +0 -19
  183. package/dist/js/packages/components/src/components/Icon/components/icons/IconAIHosting.mjs.map +0 -1
  184. package/dist/js/packages/components/src/components/List/components/Items/hooks/useInfiniteScrollTrigger.mjs.map +0 -1
  185. package/dist/types/components/Icon/components/icons/IconAIHosting.d.ts +0 -4
  186. package/dist/types/components/List/components/Items/hooks/useInfiniteScrollTrigger.d.ts +0 -3
@@ -1 +1 @@
1
- {"version":3,"file":"Text.module.mjs","names":[],"sources":["../../../../../../../src/components/Text/Text.module.scss"],"sourcesContent":[".text {\n color: inherit;\n text-wrap-style: pretty;\n\n /* Alpha Colors */\n @mixin color($color) {\n &:where(.#{$color}) {\n color: var(--text--color--#{$color});\n }\n }\n\n @include color(dark);\n @include color(light);\n @include color(dark-static);\n @include color(light-static);\n\n ul,\n ol {\n padding-inline-start: var(--text--list-padding);\n }\n\n ul {\n li {\n list-style: initial;\n }\n }\n\n small {\n font-size: var(--font-size-text--s);\n }\n\n blockquote {\n border-inline-start: var(--text--blockquote-border-width)\n var(--text--blockquote-border-style) var(--text--blockquote-border-color);\n padding-inline-start: var(--text--blockquote-padding);\n }\n\n .icon {\n vertical-align: text-bottom;\n }\n\n small {\n .icon {\n width: var(--line-height-s);\n height: var(--line-height-s);\n }\n }\n\n &:where(.align-start) {\n text-align: start;\n }\n\n &:where(.align-center) {\n text-align: center;\n }\n\n &:where(.align-end) {\n text-align: end;\n }\n\n &:where(.wrap-wrap) {\n text-wrap: wrap;\n }\n\n &:where(.wrap-balance) {\n text-wrap: balance;\n }\n\n &:where(.wrap-pretty) {\n text-wrap: pretty;\n }\n\n &:where(.no-ligatures) {\n font-variant-ligatures: none;\n }\n}\n"],"mappings":""}
1
+ {"version":3,"file":"Text.module.mjs","names":[],"sources":["../../../../../../../src/components/Text/Text.module.scss"],"sourcesContent":[".text {\n color: inherit;\n text-wrap-style: pretty;\n\n /* Alpha Colors */\n @mixin color($color) {\n &:where(.#{$color}) {\n color: var(--text--color--#{$color});\n }\n }\n\n @include color(dark);\n @include color(light);\n @include color(dark-static);\n @include color(light-static);\n\n /* `Text` styles raw HTML that its children bring along — `Markdown` nests\n bare `<ul>`/`<ol>`/`<blockquote>` inside a `Text`, and consumers write the\n same markup by hand. None of it is authored here, so none of it is classed. */\n // stylelint-disable selector-max-type -- children's raw HTML, see above\n ul,\n ol {\n padding-inline-start: var(--text--list-padding);\n }\n\n ul {\n li {\n list-style: initial;\n }\n }\n\n small {\n font-size: var(--font-size-text--s);\n }\n\n blockquote {\n border-inline-start: var(--text--blockquote-border-width)\n var(--text--blockquote-border-style) var(--text--blockquote-border-color);\n padding-inline-start: var(--text--blockquote-padding);\n }\n\n .icon {\n vertical-align: text-bottom;\n }\n\n small {\n .icon {\n width: var(--line-height-s);\n height: var(--line-height-s);\n }\n }\n // stylelint-enable selector-max-type\n\n &:where(.align-start) {\n text-align: start;\n }\n\n &:where(.align-center) {\n text-align: center;\n }\n\n &:where(.align-end) {\n text-align: end;\n }\n\n &:where(.wrap-wrap) {\n text-wrap: wrap;\n }\n\n &:where(.wrap-balance) {\n text-wrap: balance;\n }\n\n &:where(.wrap-pretty) {\n text-wrap: pretty;\n }\n\n &:where(.no-ligatures) {\n font-variant-ligatures: none;\n }\n}\n"],"mappings":""}
@@ -10,7 +10,7 @@ import { FieldDescription } from "../FieldDescription/FieldDescription.mjs";
10
10
  import TextArea_module_default from "./TextArea.module.mjs";
11
11
  import __locale_default from "../../../../../_virtual/_23.locale.mjs";
12
12
  import clsx from "clsx";
13
- import { useEffect, useState } from "react";
13
+ import { useEffect, useLayoutEffect, useState } from "react";
14
14
  import { jsx, jsxs } from "react/jsx-runtime";
15
15
  import { useObjectRef } from "@react-aria/utils";
16
16
  import * as Aria from "react-aria-components";
@@ -18,8 +18,7 @@ import * as Aria from "react-aria-components";
18
18
  /** @flr-generate all */
19
19
  var TextArea = flowComponent("TextArea", (props) => {
20
20
  const warnDeprecation = useWarnDeprecation();
21
- const { children, placeholder, rows = 5, autoResizeMaxRows = rows, ref, allowVerticalResize, allowHorizontalResize, showCharacterCount, className, onChange, isReadOnly, ...rest } = useControlledHostValueProps(props, "");
22
- const [charactersCount, setCharactersCount] = useState(props.defaultValue?.length ?? props.value?.length ?? 0);
21
+ const { children, placeholder, rows = 5, autoResizeMaxRows = rows, ref, allowVerticalResize, allowHorizontalResize, showCharacterCount, className, onChange, isReadOnly, value, ...rest } = useControlledHostValueProps(props, "");
23
22
  if (allowHorizontalResize !== void 0) warnDeprecation("The 'allowHorizontalResize' prop is deprecated and will be removed in a future release. Use 'allowResize' instead.");
24
23
  if (allowVerticalResize !== void 0) warnDeprecation("The 'allowVerticalResize' prop is deprecated and will be removed in a future release. Use 'allowResize' instead.");
25
24
  const { FieldErrorView, FieldErrorCaptureContext, fieldPropsContext, fieldProps } = useFieldComponent(props, "TextArea");
@@ -30,11 +29,10 @@ var TextArea = flowComponent("TextArea", (props) => {
30
29
  const inputClassName = clsx(TextArea_module_default.input, typeof allowResize === "boolean" && allowResize ? TextArea_module_default.resize : null, allowResize === "horizontal" ? TextArea_module_default.horizontalResize : allowResize === "vertical" ? TextArea_module_default.verticalResize : null);
31
30
  const handleChange = (v) => {
32
31
  if (isReadOnly) return;
33
- if (showCharacterCount) setCharactersCount(v.length);
34
32
  if (onChange) onChange(v);
35
33
  };
36
34
  const charactersCountDescription = useLocalizedStringFormatter(__locale_default, "TextArea").format("characters", {
37
- count: charactersCount,
35
+ count: value.length,
38
36
  maxCount: props.maxLength ?? 0
39
37
  });
40
38
  const localRef = useObjectRef(ref);
@@ -71,16 +69,20 @@ var TextArea = flowComponent("TextArea", (props) => {
71
69
  window.removeEventListener("mouseup", handleMouseUp);
72
70
  };
73
71
  }, [resized]);
74
- const updateHeight = () => {
75
- if (localRef.current && autoResizable && !verticallyResizable) {
76
- localRef.current.style.height = "0px";
77
- const scrollHeight = localRef.current.scrollHeight;
78
- localRef.current.style.height = scrollHeight + 2 + "px";
79
- }
80
- };
72
+ useLayoutEffect(() => {
73
+ const textArea = localRef.current;
74
+ if (!textArea || !autoResizable || verticallyResizable) return;
75
+ textArea.style.height = "0px";
76
+ textArea.style.height = `${textArea.scrollHeight + 2}px`;
77
+ }, [
78
+ value,
79
+ autoResizable,
80
+ verticallyResizable
81
+ ]);
81
82
  return /* @__PURE__ */ jsx(Aria.TextField, {
82
83
  ...rest,
83
84
  ...fieldProps,
85
+ value,
84
86
  className: rootClassName,
85
87
  onChange: handleChange,
86
88
  children: /* @__PURE__ */ jsxs(PropsContextProvider, {
@@ -95,7 +97,6 @@ var TextArea = flowComponent("TextArea", (props) => {
95
97
  placeholder,
96
98
  className: inputClassName,
97
99
  ref: localRef,
98
- onChange: updateHeight,
99
100
  style: {
100
101
  caretColor: isReadOnly ? "transparent" : void 0,
101
102
  minHeight: getHeight(rows),
@@ -1 +1 @@
1
- {"version":3,"file":"TextArea.mjs","names":[],"sources":["../../../../../../../src/components/TextArea/TextArea.tsx"],"sourcesContent":["import * as Aria from \"react-aria-components\";\nimport styles from \"./TextArea.module.scss\";\nimport type { FlowComponentProps } from \"@/lib/componentFactory/flowComponent\";\nimport { flowComponent } from \"@/lib/componentFactory/flowComponent\";\nimport { useObjectRef } from \"@react-aria/utils\";\nimport { useFieldComponent } from \"@/lib/hooks/useFieldComponent\";\nimport { PropsContextProvider } from \"@/lib/propsContext\";\nimport clsx from \"clsx\";\nimport { type PropsWithChildren, useEffect, useState } from \"react\";\nimport { useControlledHostValueProps } from \"@/lib/remote/useControlledHostValueProps\";\nimport { useLocalizedStringFormatter } from \"@/components/TranslationProvider/useLocalizedStringFormatter\";\nimport locales from \"./locales/*.locale.json\";\nimport { FieldDescription } from \"@/components/FieldDescription\";\nimport { useWarnDeprecation } from \"@/components/DeprecationWarningProvider\";\n\nexport interface TextAreaProps\n extends\n PropsWithChildren<Omit<Aria.TextFieldProps, \"children\">>,\n Pick<Aria.TextAreaProps, \"placeholder\" | \"rows\" | \"aria-hidden\">,\n FlowComponentProps<HTMLTextAreaElement> {\n /** Whether a character count should be displayed inside the field description. */\n showCharacterCount?: boolean;\n /**\n * Whether the text area should grow if its content gets longer than its\n * initial height.\n */\n autoResizeMaxRows?: number;\n /** Allows the user to manually resize the textArea horizontally. */\n allowResize?: boolean | \"horizontal\" | \"vertical\";\n /** @deprecated Use `allowResize` instead. */\n allowHorizontalResize?: boolean;\n /** @deprecated Use `allowResize` instead. */\n allowVerticalResize?: boolean;\n}\n\n/** @flr-generate all */\nexport const TextArea = flowComponent(\"TextArea\", (props) => {\n const warnDeprecation = useWarnDeprecation();\n const {\n children,\n placeholder,\n rows = 5,\n autoResizeMaxRows = rows,\n ref,\n allowVerticalResize,\n allowHorizontalResize,\n showCharacterCount,\n className,\n onChange,\n isReadOnly,\n ...rest\n } = useControlledHostValueProps(props, \"\");\n\n const [charactersCount, setCharactersCount] = useState(\n props.defaultValue?.length ?? props.value?.length ?? 0,\n );\n\n if (allowHorizontalResize !== undefined) {\n warnDeprecation(\n \"The 'allowHorizontalResize' prop is deprecated and will be removed in a future release. Use 'allowResize' instead.\",\n );\n }\n if (allowVerticalResize !== undefined) {\n warnDeprecation(\n \"The 'allowVerticalResize' prop is deprecated and will be removed in a future release. Use 'allowResize' instead.\",\n );\n }\n\n const {\n FieldErrorView,\n FieldErrorCaptureContext,\n fieldPropsContext,\n fieldProps,\n } = useFieldComponent(props, \"TextArea\");\n\n let { allowResize } = props;\n if (allowVerticalResize) {\n allowResize = \"vertical\";\n } else if (allowHorizontalResize) {\n allowResize = \"horizontal\";\n }\n\n const rootClassName = clsx(fieldProps.className, className);\n\n const inputClassName = clsx(\n styles.input,\n typeof allowResize === \"boolean\" && allowResize ? styles.resize : null,\n allowResize === \"horizontal\"\n ? styles.horizontalResize\n : allowResize === \"vertical\"\n ? styles.verticalResize\n : null,\n );\n\n const handleChange = (v: string) => {\n if (isReadOnly) {\n return;\n }\n\n if (showCharacterCount) {\n setCharactersCount(v.length);\n }\n if (onChange) {\n onChange(v);\n }\n };\n\n const translation = useLocalizedStringFormatter(locales, \"TextArea\");\n\n const charactersCountDescription = translation.format(\"characters\", {\n count: charactersCount,\n maxCount: props.maxLength ?? 0,\n });\n\n const localRef = useObjectRef(ref);\n\n const getHeight = (rows: number) => {\n return `calc(var(--line-height-m) * ${rows} + (var(--form-control--padding-y) * 2))`;\n };\n\n const [resized, setResized] = useState(false);\n\n const autoResizable = rows !== autoResizeMaxRows;\n\n const verticallyResizable =\n allowResize && (!autoResizable || (autoResizable && resized));\n\n useEffect(() => {\n const textarea = localRef.current;\n if (!textarea) return;\n\n const startHeight = textarea.offsetHeight;\n let tracking = false;\n\n const handleMouseDown = () => {\n tracking = true;\n };\n\n const handleMouseMove = () => {\n if (!tracking || resized) return;\n\n const currentHeight = textarea.offsetHeight;\n\n if (currentHeight !== startHeight) {\n setResized(true);\n tracking = false;\n }\n };\n\n const handleMouseUp = () => {\n tracking = false;\n };\n\n window.addEventListener(\"mousedown\", handleMouseDown);\n window.addEventListener(\"mousemove\", handleMouseMove);\n window.addEventListener(\"mouseup\", handleMouseUp);\n\n return () => {\n window.removeEventListener(\"mousedown\", handleMouseDown);\n window.removeEventListener(\"mousemove\", handleMouseMove);\n window.removeEventListener(\"mouseup\", handleMouseUp);\n };\n }, [resized]);\n\n const updateHeight = () => {\n if (localRef.current && autoResizable && !verticallyResizable) {\n // https://stackoverflow.com/a/60795884\n localRef.current.style.height = \"0px\";\n const scrollHeight = localRef.current.scrollHeight;\n // + 2 to add border height\n localRef.current.style.height = scrollHeight + 2 + \"px\";\n }\n };\n\n return (\n <Aria.TextField\n {...rest}\n {...fieldProps}\n className={rootClassName}\n onChange={handleChange}\n >\n <PropsContextProvider props={fieldPropsContext}>\n <FieldErrorCaptureContext>{children}</FieldErrorCaptureContext>\n <Aria.TextArea\n rows={rows}\n {...(isReadOnly ? { \"data-readonly\": true } : {})}\n aria-readonly={isReadOnly}\n aria-hidden={props[\"aria-hidden\"]}\n placeholder={placeholder}\n className={inputClassName}\n ref={localRef}\n onChange={updateHeight}\n style={{\n caretColor: isReadOnly ? \"transparent\" : undefined,\n minHeight: getHeight(rows),\n maxHeight: verticallyResizable\n ? undefined\n : getHeight(autoResizeMaxRows),\n }}\n />\n {showCharacterCount && (\n <FieldDescription>{charactersCountDescription}</FieldDescription>\n )}\n <FieldErrorView />\n </PropsContextProvider>\n </Aria.TextField>\n );\n});\n\nexport default TextArea;\n"],"mappings":"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"}
1
+ {"version":3,"file":"TextArea.mjs","names":[],"sources":["../../../../../../../src/components/TextArea/TextArea.tsx"],"sourcesContent":["import * as Aria from \"react-aria-components\";\nimport styles from \"./TextArea.module.scss\";\nimport type { FlowComponentProps } from \"@/lib/componentFactory/flowComponent\";\nimport { flowComponent } from \"@/lib/componentFactory/flowComponent\";\nimport { useObjectRef } from \"@react-aria/utils\";\nimport { useFieldComponent } from \"@/lib/hooks/useFieldComponent\";\nimport { PropsContextProvider } from \"@/lib/propsContext\";\nimport clsx from \"clsx\";\nimport {\n type PropsWithChildren,\n useEffect,\n useLayoutEffect,\n useState,\n} from \"react\";\nimport { useControlledHostValueProps } from \"@/lib/remote/useControlledHostValueProps\";\nimport { useLocalizedStringFormatter } from \"@/components/TranslationProvider/useLocalizedStringFormatter\";\nimport locales from \"./locales/*.locale.json\";\nimport { FieldDescription } from \"@/components/FieldDescription\";\nimport { useWarnDeprecation } from \"@/components/DeprecationWarningProvider\";\n\nexport interface TextAreaProps\n extends\n PropsWithChildren<Omit<Aria.TextFieldProps, \"children\">>,\n Pick<Aria.TextAreaProps, \"placeholder\" | \"rows\" | \"aria-hidden\">,\n FlowComponentProps<HTMLTextAreaElement> {\n /** Whether a character count should be displayed inside the field description. */\n showCharacterCount?: boolean;\n /**\n * Whether the text area should grow if its content gets longer than its\n * initial height.\n */\n autoResizeMaxRows?: number;\n /** Allows the user to manually resize the textArea horizontally. */\n allowResize?: boolean | \"horizontal\" | \"vertical\";\n /** @deprecated Use `allowResize` instead. */\n allowHorizontalResize?: boolean;\n /** @deprecated Use `allowResize` instead. */\n allowVerticalResize?: boolean;\n}\n\n/** @flr-generate all */\nexport const TextArea = flowComponent(\"TextArea\", (props) => {\n const warnDeprecation = useWarnDeprecation();\n const {\n children,\n placeholder,\n rows = 5,\n autoResizeMaxRows = rows,\n ref,\n allowVerticalResize,\n allowHorizontalResize,\n showCharacterCount,\n className,\n onChange,\n isReadOnly,\n value,\n ...rest\n } = useControlledHostValueProps(props, \"\");\n\n if (allowHorizontalResize !== undefined) {\n warnDeprecation(\n \"The 'allowHorizontalResize' prop is deprecated and will be removed in a future release. Use 'allowResize' instead.\",\n );\n }\n if (allowVerticalResize !== undefined) {\n warnDeprecation(\n \"The 'allowVerticalResize' prop is deprecated and will be removed in a future release. Use 'allowResize' instead.\",\n );\n }\n\n const {\n FieldErrorView,\n FieldErrorCaptureContext,\n fieldPropsContext,\n fieldProps,\n } = useFieldComponent(props, \"TextArea\");\n\n let { allowResize } = props;\n if (allowVerticalResize) {\n allowResize = \"vertical\";\n } else if (allowHorizontalResize) {\n allowResize = \"horizontal\";\n }\n\n const rootClassName = clsx(fieldProps.className, className);\n\n const inputClassName = clsx(\n styles.input,\n typeof allowResize === \"boolean\" && allowResize ? styles.resize : null,\n allowResize === \"horizontal\"\n ? styles.horizontalResize\n : allowResize === \"vertical\"\n ? styles.verticalResize\n : null,\n );\n\n const handleChange = (v: string) => {\n if (isReadOnly) {\n return;\n }\n\n if (onChange) {\n onChange(v);\n }\n };\n\n const translation = useLocalizedStringFormatter(locales, \"TextArea\");\n\n // Derived, so that a value the field never saw typed is counted as well.\n const charactersCountDescription = translation.format(\"characters\", {\n count: value.length,\n maxCount: props.maxLength ?? 0,\n });\n\n const localRef = useObjectRef(ref);\n\n const getHeight = (rows: number) => {\n return `calc(var(--line-height-m) * ${rows} + (var(--form-control--padding-y) * 2))`;\n };\n\n const [resized, setResized] = useState(false);\n\n const autoResizable = rows !== autoResizeMaxRows;\n\n const verticallyResizable =\n allowResize && (!autoResizable || (autoResizable && resized));\n\n useEffect(() => {\n const textarea = localRef.current;\n if (!textarea) return;\n\n const startHeight = textarea.offsetHeight;\n let tracking = false;\n\n const handleMouseDown = () => {\n tracking = true;\n };\n\n const handleMouseMove = () => {\n if (!tracking || resized) return;\n\n const currentHeight = textarea.offsetHeight;\n\n if (currentHeight !== startHeight) {\n setResized(true);\n tracking = false;\n }\n };\n\n const handleMouseUp = () => {\n tracking = false;\n };\n\n window.addEventListener(\"mousedown\", handleMouseDown);\n window.addEventListener(\"mousemove\", handleMouseMove);\n window.addEventListener(\"mouseup\", handleMouseUp);\n\n return () => {\n window.removeEventListener(\"mousedown\", handleMouseDown);\n window.removeEventListener(\"mousemove\", handleMouseMove);\n window.removeEventListener(\"mouseup\", handleMouseUp);\n };\n }, [resized]);\n\n /*\n * The height depends on the rendered content, so it cannot be a style. It is\n * synced to the value instead of to the `change` event, because a value the\n * field never saw typed — an initial value, or a draft loaded into a\n * controlled field — has to resize it just the same.\n */\n useLayoutEffect(() => {\n const textArea = localRef.current;\n if (!textArea || !autoResizable || verticallyResizable) {\n return;\n }\n // https://stackoverflow.com/a/60795884\n textArea.style.height = \"0px\";\n // + 2 to add border height\n textArea.style.height = `${textArea.scrollHeight + 2}px`;\n }, [value, autoResizable, verticallyResizable]);\n\n return (\n <Aria.TextField\n {...rest}\n {...fieldProps}\n value={value}\n className={rootClassName}\n onChange={handleChange}\n >\n <PropsContextProvider props={fieldPropsContext}>\n <FieldErrorCaptureContext>{children}</FieldErrorCaptureContext>\n <Aria.TextArea\n rows={rows}\n {...(isReadOnly ? { \"data-readonly\": true } : {})}\n aria-readonly={isReadOnly}\n aria-hidden={props[\"aria-hidden\"]}\n placeholder={placeholder}\n className={inputClassName}\n ref={localRef}\n style={{\n caretColor: isReadOnly ? \"transparent\" : undefined,\n minHeight: getHeight(rows),\n maxHeight: verticallyResizable\n ? undefined\n : getHeight(autoResizeMaxRows),\n }}\n />\n {showCharacterCount && (\n <FieldDescription>{charactersCountDescription}</FieldDescription>\n )}\n <FieldErrorView />\n </PropsContextProvider>\n </Aria.TextField>\n );\n});\n\nexport default TextArea;\n"],"mappings":"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"}
@@ -19,6 +19,7 @@ var Tooltip = (props) => {
19
19
  children: [/* @__PURE__ */ jsx(Aria.OverlayArrow, {
20
20
  className: Tooltip_module_default.tip,
21
21
  children: /* @__PURE__ */ jsx("svg", {
22
+ className: Tooltip_module_default.tipIcon,
22
23
  viewBox: "0 0 8 8",
23
24
  children: /* @__PURE__ */ jsx("path", { d: "M0 0 L4 4 L8 0" })
24
25
  })
@@ -1 +1 @@
1
- {"version":3,"file":"Tooltip.mjs","names":[],"sources":["../../../../../../../src/components/Tooltip/Tooltip.tsx"],"sourcesContent":["import * as Aria from \"react-aria-components\";\nimport type { FC, PropsWithChildren } from \"react\";\nimport styles from \"./Tooltip.module.scss\";\nimport clsx from \"clsx\";\nimport { ClearPropsContext } from \"@/components/ClearPropsContext\";\nimport { useIsActivityActive } from \"@/components/Activity/context\";\n\nexport type TooltipProps = PropsWithChildren<\n Omit<Aria.TooltipProps, \"children\">\n>;\n\n/** @flr-generate all */\nexport const Tooltip: FC<TooltipProps> = (props) => {\n const { children, className, ...rest } = props;\n\n const isActivityActive = useIsActivityActive();\n\n const rootClassName = clsx(styles.tooltip, className);\n\n if (!isActivityActive) {\n return null;\n }\n\n return (\n <ClearPropsContext>\n <Aria.Tooltip {...rest} className={rootClassName}>\n <Aria.OverlayArrow className={styles.tip}>\n <svg viewBox=\"0 0 8 8\">\n <path d=\"M0 0 L4 4 L8 0\" />\n </svg>\n </Aria.OverlayArrow>\n {children}\n </Aria.Tooltip>\n </ClearPropsContext>\n );\n};\n\nexport default Tooltip;\n"],"mappings":";;;;;;;;;;AAYA,IAAa,WAA6B,UAAU;CAClD,MAAM,EAAE,UAAU,WAAW,GAAG,SAAS;CAEzC,MAAM,mBAAmB,oBAAoB;CAE7C,MAAM,gBAAgB,KAAK,uBAAO,SAAS,SAAS;CAEpD,IAAI,CAAC,kBACH,OAAO;CAGT,OACE,oBAAC,mBAAD,EAAA,UACE,qBAAC,KAAK,SAAN;EAAc,GAAI;EAAM,WAAW;EAAnC,UAAA,CACE,oBAAC,KAAK,cAAN;GAAmB,WAAW,uBAAO;GACnC,UAAA,oBAAC,OAAD;IAAK,SAAQ;IACX,UAAA,oBAAC,QAAD,EAAM,GAAE,iBAAkB,CAAA;GACvB,CAAA;EACY,CAAA,GAClB,QACW;CACG,CAAA,EAAA,CAAA;AAEvB"}
1
+ {"version":3,"file":"Tooltip.mjs","names":[],"sources":["../../../../../../../src/components/Tooltip/Tooltip.tsx"],"sourcesContent":["import * as Aria from \"react-aria-components\";\nimport type { FC, PropsWithChildren } from \"react\";\nimport styles from \"./Tooltip.module.scss\";\nimport clsx from \"clsx\";\nimport { ClearPropsContext } from \"@/components/ClearPropsContext\";\nimport { useIsActivityActive } from \"@/components/Activity/context\";\n\nexport type TooltipProps = PropsWithChildren<\n Omit<Aria.TooltipProps, \"children\">\n>;\n\n/** @flr-generate all */\nexport const Tooltip: FC<TooltipProps> = (props) => {\n const { children, className, ...rest } = props;\n\n const isActivityActive = useIsActivityActive();\n\n const rootClassName = clsx(styles.tooltip, className);\n\n if (!isActivityActive) {\n return null;\n }\n\n return (\n <ClearPropsContext>\n <Aria.Tooltip {...rest} className={rootClassName}>\n <Aria.OverlayArrow className={styles.tip}>\n <svg className={styles.tipIcon} viewBox=\"0 0 8 8\">\n <path d=\"M0 0 L4 4 L8 0\" />\n </svg>\n </Aria.OverlayArrow>\n {children}\n </Aria.Tooltip>\n </ClearPropsContext>\n );\n};\n\nexport default Tooltip;\n"],"mappings":";;;;;;;;;;AAYA,IAAa,WAA6B,UAAU;CAClD,MAAM,EAAE,UAAU,WAAW,GAAG,SAAS;CAEzC,MAAM,mBAAmB,oBAAoB;CAE7C,MAAM,gBAAgB,KAAK,uBAAO,SAAS,SAAS;CAEpD,IAAI,CAAC,kBACH,OAAO;CAGT,OACE,oBAAC,mBAAD,EAAA,UACE,qBAAC,KAAK,SAAN;EAAc,GAAI;EAAM,WAAW;EAAnC,UAAA,CACE,oBAAC,KAAK,cAAN;GAAmB,WAAW,uBAAO;GACnC,UAAA,oBAAC,OAAD;IAAK,WAAW,uBAAO;IAAS,SAAQ;IACtC,UAAA,oBAAC,QAAD,EAAM,GAAE,iBAAkB,CAAA;GACvB,CAAA;EACY,CAAA,GAClB,QACW;CACG,CAAA,EAAA,CAAA;AAEvB"}
@@ -3,13 +3,15 @@
3
3
  //#region src/components/Tooltip/Tooltip.module.scss
4
4
  var tooltip = "flow--tooltip";
5
5
  var tip = "flow--tooltip--tip";
6
+ var tipIcon = "flow--tooltip--tip-icon";
6
7
  var slide = "flow--tooltip--slide";
7
8
  var Tooltip_module_default = {
8
9
  tooltip,
9
10
  tip,
11
+ tipIcon,
10
12
  slide
11
13
  };
12
14
  //#endregion
13
- export { Tooltip_module_default as default, slide, tip, tooltip };
15
+ export { Tooltip_module_default as default, slide, tip, tipIcon, tooltip };
14
16
 
15
17
  //# sourceMappingURL=Tooltip.module.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Tooltip.module.mjs","names":[],"sources":["../../../../../../../src/components/Tooltip/Tooltip.module.scss"],"sourcesContent":[".tooltip {\n border-radius: var(--tooltip--corner-radius);\n background-color: var(--tooltip--background-color);\n color: var(--tooltip--color);\n font-size: var(--tooltip--font-size);\n padding-block: var(--tooltip--padding-y);\n padding-inline: var(--tooltip--padding-x);\n max-width: var(--tooltip--max-width);\n transform: translate3d(0, 0, 0);\n box-shadow: var(--tooltip--box-shadow);\n\n --translate-origin-length: var(--tooltip--tooltip-to-trigger-spacing) / 2;\n\n /**\n * React Aria sets `data-placement` once it has computed a position, and\n * renders the overlay at `top: 0; left: 0` of the viewport until then. It\n * skips computing one when the tooltip mounts for its exit animation alone –\n * swapping quickly between neighbouring triggers does that – and never\n * retries afterwards, so such a tooltip stays parked in the corner for its\n * whole lifetime. Keep it out of sight instead. `visibility` rather than\n * `display`, so the overlay stays measurable for the positioning pass.\n */\n &:not([data-placement]) {\n visibility: hidden;\n }\n\n /* Placement */\n &[data-placement=\"top\"] {\n margin-bottom: var(--tooltip--tooltip-to-trigger-spacing);\n\n --translate-origin: translateY(var(--translate-origin-length));\n }\n\n &[data-placement=\"bottom\"] {\n margin-top: var(--tooltip--tooltip-to-trigger-spacing);\n\n --translate-origin: translateY(var(--translate-origin-length) * -1);\n\n .tip svg {\n transform: rotate(180deg);\n }\n }\n\n &[data-placement=\"right\"] {\n margin-inline-start: var(--tooltip--tooltip-to-trigger-spacing);\n\n --translate-origin: translateX(var(--translate-origin-length) * -1);\n\n .tip svg {\n transform: rotate(90deg);\n }\n }\n\n &[data-placement=\"left\"] {\n margin-inline-end: var(--tooltip--tooltip-to-trigger-spacing);\n\n --translate-origin: translateX(var(--translate-origin-length));\n\n .tip svg {\n transform: rotate(-90deg);\n }\n }\n\n /* Animation */\n\n &[data-entering] {\n animation: slide 200ms;\n }\n\n &[data-exiting] {\n animation: slide 200ms reverse ease-in;\n }\n\n .tip {\n width: var(--tooltip--tip-size);\n height: var(--tooltip--tip-size);\n\n svg {\n display: block;\n fill: var(--tooltip--background-color);\n }\n }\n}\n\n@keyframes slide {\n from {\n transform: var(--translate-origin);\n opacity: 0;\n }\n\n to {\n transform: translateY(0);\n opacity: 1;\n }\n}\n"],"mappings":""}
1
+ {"version":3,"file":"Tooltip.module.mjs","names":[],"sources":["../../../../../../../src/components/Tooltip/Tooltip.module.scss"],"sourcesContent":[".tooltip {\n border-radius: var(--tooltip--corner-radius);\n background-color: var(--tooltip--background-color);\n color: var(--tooltip--color);\n font-size: var(--tooltip--font-size);\n padding-block: var(--tooltip--padding-y);\n padding-inline: var(--tooltip--padding-x);\n max-width: var(--tooltip--max-width);\n transform: translate3d(0, 0, 0);\n box-shadow: var(--tooltip--box-shadow);\n\n --translate-origin-length: var(--tooltip--tooltip-to-trigger-spacing) / 2;\n\n /**\n * React Aria sets `data-placement` once it has computed a position, and\n * renders the overlay at `top: 0; left: 0` of the viewport until then. It\n * skips computing one when the tooltip mounts for its exit animation alone –\n * swapping quickly between neighbouring triggers does that – and never\n * retries afterwards, so such a tooltip stays parked in the corner for its\n * whole lifetime. Keep it out of sight instead. `visibility` rather than\n * `display`, so the overlay stays measurable for the positioning pass.\n */\n &:not([data-placement]) {\n visibility: hidden;\n }\n\n /* Placement */\n &[data-placement=\"top\"] {\n margin-bottom: var(--tooltip--tooltip-to-trigger-spacing);\n\n --translate-origin: translateY(var(--translate-origin-length));\n }\n\n &[data-placement=\"bottom\"] {\n margin-top: var(--tooltip--tooltip-to-trigger-spacing);\n\n --translate-origin: translateY(var(--translate-origin-length) * -1);\n\n .tip .tipIcon {\n transform: rotate(180deg);\n }\n }\n\n &[data-placement=\"right\"] {\n margin-inline-start: var(--tooltip--tooltip-to-trigger-spacing);\n\n --translate-origin: translateX(var(--translate-origin-length) * -1);\n\n .tip .tipIcon {\n transform: rotate(90deg);\n }\n }\n\n &[data-placement=\"left\"] {\n margin-inline-end: var(--tooltip--tooltip-to-trigger-spacing);\n\n --translate-origin: translateX(var(--translate-origin-length));\n\n .tip .tipIcon {\n transform: rotate(-90deg);\n }\n }\n\n /* Animation */\n\n &[data-entering] {\n animation: slide 200ms;\n }\n\n &[data-exiting] {\n animation: slide 200ms reverse ease-in;\n }\n\n .tip {\n width: var(--tooltip--tip-size);\n height: var(--tooltip--tip-size);\n\n .tipIcon {\n display: block;\n fill: var(--tooltip--background-color);\n }\n }\n}\n\n@keyframes slide {\n from {\n transform: var(--translate-origin);\n opacity: 0;\n }\n\n to {\n transform: translateY(0);\n opacity: 1;\n }\n}\n"],"mappings":""}
@@ -4,15 +4,12 @@ import { overlayContext, useOverlayContext } from "./context.mjs";
4
4
  import { jsx } from "react/jsx-runtime";
5
5
  //#region src/lib/controller/overlay/OverlayContextProvider.tsx
6
6
  var OverlayContextProvider = (props) => {
7
- const { type, controller, isOverlayContent = true, children } = props;
7
+ const { type, controller, children } = props;
8
8
  const parentContext = useOverlayContext();
9
9
  return /* @__PURE__ */ jsx(overlayContext.Provider, {
10
10
  value: {
11
- byType: {
12
- ...parentContext.byType,
13
- [type]: controller
14
- },
15
- nearest: isOverlayContent ? controller : parentContext.nearest
11
+ ...parentContext,
12
+ [type]: controller
16
13
  },
17
14
  children
18
15
  });
@@ -1 +1 @@
1
- {"version":3,"file":"OverlayContextProvider.mjs","names":[],"sources":["../../../../../../../../src/lib/controller/overlay/OverlayContextProvider.tsx"],"sourcesContent":["import type { FC, PropsWithChildren } from \"react\";\nimport {\n overlayContext,\n useOverlayContext,\n} from \"@/lib/controller/overlay/context\";\nimport type { FlowComponentName } from \"@/components/propTypes\";\nimport type { OverlayController } from \"@/lib/controller\";\n\ninterface Props extends PropsWithChildren {\n type: FlowComponentName;\n controller: OverlayController;\n /**\n * Whether the children are the overlay's content. Content also registers the\n * controller as the _nearest_ overlay, which is what `closeOverlay` without a\n * name resolves to. Set `false` where the subtree is not inside the overlay –\n * `OverlayTrigger` wraps the trigger too.\n *\n * @default true\n */\n isOverlayContent?: boolean;\n}\n\nexport const OverlayContextProvider: FC<Props> = (props) => {\n const { type, controller, isOverlayContent = true, children } = props;\n const parentContext = useOverlayContext();\n\n return (\n <overlayContext.Provider\n value={{\n byType: {\n ...parentContext.byType,\n [type]: controller,\n },\n nearest: isOverlayContent ? controller : parentContext.nearest,\n }}\n >\n {children}\n </overlayContext.Provider>\n );\n};\n\nexport default OverlayContextProvider;\n"],"mappings":";;;;;AAsBA,IAAa,0BAAqC,UAAU;CAC1D,MAAM,EAAE,MAAM,YAAY,mBAAmB,MAAM,aAAa;CAChE,MAAM,gBAAgB,kBAAkB;CAExC,OACE,oBAAC,eAAe,UAAhB;EACE,OAAO;GACL,QAAQ;IACN,GAAG,cAAc;KAChB,OAAO;GACV;GACA,SAAS,mBAAmB,aAAa,cAAc;EACzD;EAEC;CACsB,CAAA;AAE7B"}
1
+ {"version":3,"file":"OverlayContextProvider.mjs","names":[],"sources":["../../../../../../../../src/lib/controller/overlay/OverlayContextProvider.tsx"],"sourcesContent":["import type { FC, PropsWithChildren } from \"react\";\nimport {\n overlayContext,\n useOverlayContext,\n} from \"@/lib/controller/overlay/context\";\nimport type { FlowComponentName } from \"@/components/propTypes\";\nimport type { OverlayController } from \"@/lib/controller\";\n\ninterface Props extends PropsWithChildren {\n type: FlowComponentName;\n controller: OverlayController;\n}\n\nexport const OverlayContextProvider: FC<Props> = (props) => {\n const { type, controller, children } = props;\n const parentContext = useOverlayContext();\n\n return (\n <overlayContext.Provider\n value={{\n ...parentContext,\n [type]: controller,\n }}\n >\n {children}\n </overlayContext.Provider>\n );\n};\n\nexport default OverlayContextProvider;\n"],"mappings":";;;;;AAaA,IAAa,0BAAqC,UAAU;CAC1D,MAAM,EAAE,MAAM,YAAY,aAAa;CACvC,MAAM,gBAAgB,kBAAkB;CAExC,OACE,oBAAC,eAAe,UAAhB;EACE,OAAO;GACL,GAAG;IACF,OAAO;EACV;EAEC;CACsB,CAAA;AAE7B"}
@@ -1 +1 @@
1
- {"version":3,"file":"OverlayController.mjs","names":[],"sources":["../../../../../../../../src/lib/controller/overlay/OverlayController.ts"],"sourcesContent":["import {\n action,\n computed,\n makeObservable,\n observable,\n runInAction,\n} from \"mobx\";\nimport useSelector from \"@/lib/mobx/useSelector\";\nimport { useStatic } from \"@/lib/hooks/useStatic\";\nimport { useEffect, useRef, type DependencyList } from \"react\";\nimport { useCloseOverlayConfirmationController } from \"@/lib/controller/overlay/useCloseOverlayConfirmationController\";\nimport type { FlowComponentName } from \"@/components/propTypes\";\n\nexport type OverlayOpenHandler = () => unknown;\nexport type OverlayCloseHandler = () => unknown;\nexport type OverlayOpenStateHandler = (isOpen: boolean) => unknown;\ntype AnyOverlayOpenStateHandler =\n OverlayOpenHandler | OverlayCloseHandler | OverlayOpenStateHandler;\n\ntype DisposerFn = () => void;\n\nexport interface CloseOverlayOptions {\n /**\n * The overlay to close. Omitted, the nearest enclosing overlay is closed –\n * the same thing `closeOverlay={true}` means.\n */\n overlay?: FlowComponentName | OverlayController;\n bypassConfirmation?: boolean;\n}\n\nexport interface OnOverlayClosedOptions {\n dependencies?: DependencyList;\n}\n\nexport type CloseModalOptions = Omit<CloseOverlayOptions, \"overlay\">;\n\n/**\n * Every way an action can point at an overlay: by the Flow component name it\n * registers under, by controller, by options, or with `true` – the nearest\n * enclosing overlay, whatever its name.\n */\nexport type OverlayReference =\n FlowComponentName | OverlayController | CloseOverlayOptions | true;\n\ntype CloseOptions = CloseOverlayOptions | CloseModalOptions;\n\nexport interface OverlayControllerOptions {\n isDefaultOpen?: boolean;\n onOpen?: OverlayOpenHandler;\n onClose?: OverlayCloseHandler;\n onOpenChange?: OverlayOpenStateHandler;\n /**\n * Whether closing the overlay must be confirmed. `undefined` means \"no\n * opinion\": the value is not contributed at all, so other sources (e.g. a\n * `Modal`'s `confirmOnClose` prop or a dirty `Form`) still decide.\n */\n confirmOnClose?: boolean;\n}\n\ntype ConstructorOptions = Pick<\n OverlayControllerOptions,\n \"isDefaultOpen\" | \"confirmOnClose\"\n>;\n\nexport class OverlayController {\n public isOpen = false;\n public isContentSuspended = false;\n private onOpenHandlers = new Set<OverlayOpenHandler>();\n private onCloseHandlers = new Set<OverlayCloseHandler>();\n private onOpenChangeHandlers = new Set<OverlayOpenStateHandler>();\n\n public showConfirmationModal = false;\n public closeIsConfirmed = false;\n private readonly confirmOnCloseFromOptions: boolean;\n /**\n * Every mounted component that has an opinion on close confirmation\n * contributes one entry here – e.g. a `Modal` with a `confirmOnClose` prop\n * and a `Form` tracking its dirty state. Combining them instead of assigning\n * a single flag keeps them from overwriting each other.\n */\n private confirmOnCloseSources = observable.map<object, boolean>();\n /**\n * Active grants that allow closing without a confirmation. Each entry is\n * scoped to an ongoing operation that legitimately closes the overlay – e.g.\n * a `Form` submit – and is dropped again when that operation has finished, so\n * an operation that does _not_ close the overlay leaves the confirmation\n * armed.\n */\n private closeWithoutConfirmationGrants = new Set<object>();\n /**\n * The open state a `setOpen` call is currently applying. Handlers run before\n * `isOpen` is assigned, so a handler that calls `setOpen` again would not be\n * caught by the equality check at the top and would recurse.\n */\n private openStateInFlight: boolean | undefined;\n\n public constructor(options: ConstructorOptions = {}) {\n makeObservable(this, {\n isOpen: observable,\n isContentSuspended: observable,\n showConfirmationModal: observable,\n confirmOnCloseEnabled: computed,\n open: action.bound,\n close: action.bound,\n toggle: action.bound,\n setOpen: action.bound,\n syncOpen: action.bound,\n setIsContentSuspended: action.bound,\n confirmClose: action.bound,\n cancelConfirmation: action.bound,\n });\n const { isDefaultOpen = false, confirmOnClose = false } = options;\n this.isOpen = isDefaultOpen;\n this.confirmOnCloseFromOptions = confirmOnClose;\n }\n\n /** Whether closing this overlay currently requires a confirmation. */\n public get confirmOnCloseEnabled(): boolean {\n if (this.confirmOnCloseSources.size === 0) {\n return this.confirmOnCloseFromOptions;\n }\n return Array.from(this.confirmOnCloseSources.values()).some(Boolean);\n }\n\n public useUpdateOptions(options: OverlayControllerOptions = {}): void {\n const { onOpen, onClose, onOpenChange, confirmOnClose } = options;\n\n this.useOnHandler(onOpen, (h) =>\n this.addOpenStateHandler(h, this.onOpenHandlers),\n );\n this.useOnHandler(onClose, (h) =>\n this.addOpenStateHandler(h, this.onCloseHandlers),\n );\n this.useOnHandler(onOpenChange, (h) =>\n this.addOpenStateHandler(h, this.onOpenChangeHandlers),\n );\n\n this.useConfirmOnCloseSource(confirmOnClose);\n }\n\n /**\n * Registers the calling component as a close confirmation source for as long\n * as it is mounted. `undefined` contributes nothing at all.\n */\n private useConfirmOnCloseSource(confirmOnClose: boolean | undefined): void {\n const source = useStatic((): object => ({}));\n\n useEffect(() => {\n if (confirmOnClose === undefined) {\n this.removeConfirmOnCloseSource(source);\n return;\n }\n this.setConfirmOnCloseSource(source, confirmOnClose);\n return () => this.removeConfirmOnCloseSource(source);\n }, [this, source, confirmOnClose]);\n }\n\n private setConfirmOnCloseSource(source: object, confirmOnClose: boolean) {\n runInAction(() => this.confirmOnCloseSources.set(source, confirmOnClose));\n }\n\n private removeConfirmOnCloseSource(source: object) {\n runInAction(() => this.confirmOnCloseSources.delete(source));\n }\n\n /**\n * Can be used to execute a callback when the Overlay has unmounted – means\n * after any closing animation.\n *\n * NOTICE: This hook only works inside the corresponding Overlay!\n */\n public useOnClosed(\n callback: () => unknown,\n options: OnOverlayClosedOptions = {},\n ) {\n const { dependencies = [] } = options;\n const isOpen = this.useIsOpen();\n const wasOpen = useRef(this.isOpen);\n\n this.useUpdateOptions({\n onOpen: () => {\n wasOpen.current = true;\n },\n });\n\n useEffect(() => {\n return () => {\n if (!isOpen && wasOpen.current) {\n wasOpen.current = false;\n callback();\n }\n };\n }, [isOpen, ...dependencies]);\n }\n\n public static useNew(\n options: OverlayControllerOptions = {},\n ): OverlayController {\n const controller = useStatic(() => new OverlayController(options));\n controller.useUpdateOptions(options);\n return controller;\n }\n\n private addOpenStateHandler<T extends AnyOverlayOpenStateHandler>(\n handler: T,\n handlersSet: Set<T>,\n ): DisposerFn {\n handlersSet.add(handler);\n return () => {\n handlersSet.delete(handler);\n };\n }\n\n private useOnHandler<T extends AnyOverlayOpenStateHandler>(\n handler: T | undefined,\n addHandlerFn: (handler: T) => DisposerFn,\n ) {\n useEffect(\n () => (handler ? addHandlerFn(handler) : undefined),\n [handler, this],\n );\n }\n\n private executeHandlers(\n isOpen: boolean,\n handlers: Set<\n OverlayOpenHandler | OverlayCloseHandler | OverlayOpenStateHandler\n >,\n ): boolean {\n const handlerResult = Array.from(handlers).map((handler) =>\n handler(isOpen),\n );\n return handlerResult.some((result) => result === false);\n }\n\n private executeOnClose(): boolean {\n return this.executeHandlers(false, this.onCloseHandlers);\n }\n\n private executeOnOpen(): boolean {\n return this.executeHandlers(true, this.onOpenHandlers);\n }\n\n private executeOnOpenChange(isOpen: boolean): boolean {\n return this.executeHandlers(isOpen, this.onOpenChangeHandlers);\n }\n\n public addOnClose(handler: OverlayCloseHandler) {\n return this.addOpenStateHandler(handler, this.onCloseHandlers);\n }\n\n public addOnOpen(handler: OverlayOpenHandler) {\n return this.addOpenStateHandler(handler, this.onOpenHandlers);\n }\n\n public addOnOpenChange(handler: OverlayOpenStateHandler) {\n return this.addOpenStateHandler(handler, this.onOpenChangeHandlers);\n }\n\n public open(): void {\n this.setOpen(true);\n }\n\n public close(options?: CloseOptions): void {\n this.setOpen(false, options);\n }\n\n public toggle(): void {\n this.setOpen(!this.isOpen);\n }\n\n public setOpen(toOpen: boolean, options: CloseOptions = {}): void {\n if (this.isOpen === toOpen || this.openStateInFlight === toOpen) {\n return;\n }\n\n this.openStateInFlight = toOpen;\n try {\n this.applyOpenState(toOpen, options);\n } finally {\n this.openStateInFlight = undefined;\n }\n }\n\n /**\n * Sets the open state without running any handler. Use it to mirror a\n * controlled `isOpen` prop, whose change comes from the consumer – notifying\n * them of their own state would echo it back.\n */\n public syncOpen(toOpen: boolean): void {\n this.isOpen = toOpen;\n }\n\n private applyOpenState(toOpen: boolean, options: CloseOptions): void {\n const { bypassConfirmation = false } = options;\n\n if (toOpen === false) {\n // The confirmation is a one-shot permission for exactly this close\n // attempt – consume it here instead of only when a close succeeds, so it\n // cannot survive an aborted close and disarm later attempts.\n const closeIsConfirmed = this.closeIsConfirmed;\n this.closeIsConfirmed = false;\n\n if (\n this.confirmOnCloseEnabled &&\n !closeIsConfirmed &&\n this.closeWithoutConfirmationGrants.size === 0 &&\n !bypassConfirmation\n ) {\n this.showConfirmationModal = true;\n return;\n }\n }\n\n let aborted: boolean;\n if (toOpen) {\n aborted = this.executeOnOpen();\n } else {\n aborted = this.executeOnClose();\n }\n if (!aborted) {\n aborted = this.executeOnOpenChange(toOpen);\n }\n\n if (!aborted) {\n this.isOpen = toOpen;\n }\n }\n\n public setIsContentSuspended(to: boolean): void {\n this.isContentSuspended = to;\n }\n\n public useIsOpen() {\n return useSelector(() => this.isOpen);\n }\n\n public useIsContentSuspended() {\n return useSelector(() => this.isContentSuspended);\n }\n\n public useShowConfirmationModal() {\n return useSelector(() => this.showConfirmationModal);\n }\n\n public useConfirmOnCloseEnabled() {\n return useSelector(() => this.confirmOnCloseEnabled);\n }\n\n public useConfirmationController() {\n return useCloseOverlayConfirmationController(this);\n }\n\n /**\n * Allows closing this overlay without a confirmation until the returned\n * disposer is called. Use it around an operation that may legitimately close\n * the overlay – e.g. a `Form` submit, where a \"discard unsaved changes?\"\n * prompt would be nonsense – and dispose it as soon as that operation has\n * finished. An operation that ends without closing the overlay therefore\n * leaves the confirmation armed (#2775).\n */\n public grantCloseWithoutConfirmation(): DisposerFn {\n const grant = {};\n this.closeWithoutConfirmationGrants.add(grant);\n return () => {\n this.closeWithoutConfirmationGrants.delete(grant);\n };\n }\n\n public confirmClose(): void {\n this.closeIsConfirmed = true;\n this.showConfirmationModal = false;\n }\n\n public cancelConfirmation(): void {\n this.showConfirmationModal = false;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"OverlayController.mjs","names":[],"sources":["../../../../../../../../src/lib/controller/overlay/OverlayController.ts"],"sourcesContent":["import {\n action,\n computed,\n makeObservable,\n observable,\n runInAction,\n} from \"mobx\";\nimport useSelector from \"@/lib/mobx/useSelector\";\nimport { useStatic } from \"@/lib/hooks/useStatic\";\nimport { useEffect, useRef, type DependencyList } from \"react\";\nimport { useCloseOverlayConfirmationController } from \"@/lib/controller/overlay/useCloseOverlayConfirmationController\";\nimport type { FlowComponentName } from \"@/components/propTypes\";\n\nexport type OverlayOpenHandler = () => unknown;\nexport type OverlayCloseHandler = () => unknown;\nexport type OverlayOpenStateHandler = (isOpen: boolean) => unknown;\ntype AnyOverlayOpenStateHandler =\n OverlayOpenHandler | OverlayCloseHandler | OverlayOpenStateHandler;\n\ntype DisposerFn = () => void;\n\nexport interface CloseOverlayOptions {\n overlay: FlowComponentName | OverlayController;\n bypassConfirmation?: boolean;\n}\n\nexport interface OnOverlayClosedOptions {\n dependencies?: DependencyList;\n}\n\nexport type CloseModalOptions = Omit<CloseOverlayOptions, \"overlay\">;\n\ntype CloseOptions = CloseOverlayOptions | CloseModalOptions;\n\nexport interface OverlayControllerOptions {\n isDefaultOpen?: boolean;\n onOpen?: OverlayOpenHandler;\n onClose?: OverlayCloseHandler;\n onOpenChange?: OverlayOpenStateHandler;\n /**\n * Whether closing the overlay must be confirmed. `undefined` means \"no\n * opinion\": the value is not contributed at all, so other sources (e.g. a\n * `Modal`'s `confirmOnClose` prop or a dirty `Form`) still decide.\n */\n confirmOnClose?: boolean;\n}\n\ntype ConstructorOptions = Pick<\n OverlayControllerOptions,\n \"isDefaultOpen\" | \"confirmOnClose\"\n>;\n\nexport class OverlayController {\n public isOpen = false;\n public isContentSuspended = false;\n private onOpenHandlers = new Set<OverlayOpenHandler>();\n private onCloseHandlers = new Set<OverlayCloseHandler>();\n private onOpenChangeHandlers = new Set<OverlayOpenStateHandler>();\n\n public showConfirmationModal = false;\n public closeIsConfirmed = false;\n private readonly confirmOnCloseFromOptions: boolean;\n /**\n * Every mounted component that has an opinion on close confirmation\n * contributes one entry here – e.g. a `Modal` with a `confirmOnClose` prop\n * and a `Form` tracking its dirty state. Combining them instead of assigning\n * a single flag keeps them from overwriting each other.\n */\n private confirmOnCloseSources = observable.map<object, boolean>();\n /**\n * Active grants that allow closing without a confirmation. Each entry is\n * scoped to an ongoing operation that legitimately closes the overlay – e.g.\n * a `Form` submit – and is dropped again when that operation has finished, so\n * an operation that does _not_ close the overlay leaves the confirmation\n * armed.\n */\n private closeWithoutConfirmationGrants = new Set<object>();\n /**\n * The open state a `setOpen` call is currently applying. Handlers run before\n * `isOpen` is assigned, so a handler that calls `setOpen` again would not be\n * caught by the equality check at the top and would recurse.\n */\n private openStateInFlight: boolean | undefined;\n\n public constructor(options: ConstructorOptions = {}) {\n makeObservable(this, {\n isOpen: observable,\n isContentSuspended: observable,\n showConfirmationModal: observable,\n confirmOnCloseEnabled: computed,\n open: action.bound,\n close: action.bound,\n toggle: action.bound,\n setOpen: action.bound,\n syncOpen: action.bound,\n setIsContentSuspended: action.bound,\n confirmClose: action.bound,\n cancelConfirmation: action.bound,\n });\n const { isDefaultOpen = false, confirmOnClose = false } = options;\n this.isOpen = isDefaultOpen;\n this.confirmOnCloseFromOptions = confirmOnClose;\n }\n\n /** Whether closing this overlay currently requires a confirmation. */\n public get confirmOnCloseEnabled(): boolean {\n if (this.confirmOnCloseSources.size === 0) {\n return this.confirmOnCloseFromOptions;\n }\n return Array.from(this.confirmOnCloseSources.values()).some(Boolean);\n }\n\n public useUpdateOptions(options: OverlayControllerOptions = {}): void {\n const { onOpen, onClose, onOpenChange, confirmOnClose } = options;\n\n this.useOnHandler(onOpen, (h) =>\n this.addOpenStateHandler(h, this.onOpenHandlers),\n );\n this.useOnHandler(onClose, (h) =>\n this.addOpenStateHandler(h, this.onCloseHandlers),\n );\n this.useOnHandler(onOpenChange, (h) =>\n this.addOpenStateHandler(h, this.onOpenChangeHandlers),\n );\n\n this.useConfirmOnCloseSource(confirmOnClose);\n }\n\n /**\n * Registers the calling component as a close confirmation source for as long\n * as it is mounted. `undefined` contributes nothing at all.\n */\n private useConfirmOnCloseSource(confirmOnClose: boolean | undefined): void {\n const source = useStatic((): object => ({}));\n\n useEffect(() => {\n if (confirmOnClose === undefined) {\n this.removeConfirmOnCloseSource(source);\n return;\n }\n this.setConfirmOnCloseSource(source, confirmOnClose);\n return () => this.removeConfirmOnCloseSource(source);\n }, [this, source, confirmOnClose]);\n }\n\n private setConfirmOnCloseSource(source: object, confirmOnClose: boolean) {\n runInAction(() => this.confirmOnCloseSources.set(source, confirmOnClose));\n }\n\n private removeConfirmOnCloseSource(source: object) {\n runInAction(() => this.confirmOnCloseSources.delete(source));\n }\n\n /**\n * Can be used to execute a callback when the Overlay has unmounted – means\n * after any closing animation.\n *\n * NOTICE: This hook only works inside the corresponding Overlay!\n */\n public useOnClosed(\n callback: () => unknown,\n options: OnOverlayClosedOptions = {},\n ) {\n const { dependencies = [] } = options;\n const isOpen = this.useIsOpen();\n const wasOpen = useRef(this.isOpen);\n\n this.useUpdateOptions({\n onOpen: () => {\n wasOpen.current = true;\n },\n });\n\n useEffect(() => {\n return () => {\n if (!isOpen && wasOpen.current) {\n wasOpen.current = false;\n callback();\n }\n };\n }, [isOpen, ...dependencies]);\n }\n\n public static useNew(\n options: OverlayControllerOptions = {},\n ): OverlayController {\n const controller = useStatic(() => new OverlayController(options));\n controller.useUpdateOptions(options);\n return controller;\n }\n\n private addOpenStateHandler<T extends AnyOverlayOpenStateHandler>(\n handler: T,\n handlersSet: Set<T>,\n ): DisposerFn {\n handlersSet.add(handler);\n return () => {\n handlersSet.delete(handler);\n };\n }\n\n private useOnHandler<T extends AnyOverlayOpenStateHandler>(\n handler: T | undefined,\n addHandlerFn: (handler: T) => DisposerFn,\n ) {\n useEffect(\n () => (handler ? addHandlerFn(handler) : undefined),\n [handler, this],\n );\n }\n\n private executeHandlers(\n isOpen: boolean,\n handlers: Set<\n OverlayOpenHandler | OverlayCloseHandler | OverlayOpenStateHandler\n >,\n ): boolean {\n const handlerResult = Array.from(handlers).map((handler) =>\n handler(isOpen),\n );\n return handlerResult.some((result) => result === false);\n }\n\n private executeOnClose(): boolean {\n return this.executeHandlers(false, this.onCloseHandlers);\n }\n\n private executeOnOpen(): boolean {\n return this.executeHandlers(true, this.onOpenHandlers);\n }\n\n private executeOnOpenChange(isOpen: boolean): boolean {\n return this.executeHandlers(isOpen, this.onOpenChangeHandlers);\n }\n\n public addOnClose(handler: OverlayCloseHandler) {\n return this.addOpenStateHandler(handler, this.onCloseHandlers);\n }\n\n public addOnOpen(handler: OverlayOpenHandler) {\n return this.addOpenStateHandler(handler, this.onOpenHandlers);\n }\n\n public addOnOpenChange(handler: OverlayOpenStateHandler) {\n return this.addOpenStateHandler(handler, this.onOpenChangeHandlers);\n }\n\n public open(): void {\n this.setOpen(true);\n }\n\n public close(options?: CloseOptions): void {\n this.setOpen(false, options);\n }\n\n public toggle(): void {\n this.setOpen(!this.isOpen);\n }\n\n public setOpen(toOpen: boolean, options: CloseOptions = {}): void {\n if (this.isOpen === toOpen || this.openStateInFlight === toOpen) {\n return;\n }\n\n this.openStateInFlight = toOpen;\n try {\n this.applyOpenState(toOpen, options);\n } finally {\n this.openStateInFlight = undefined;\n }\n }\n\n /**\n * Sets the open state without running any handler. Use it to mirror a\n * controlled `isOpen` prop, whose change comes from the consumer – notifying\n * them of their own state would echo it back.\n */\n public syncOpen(toOpen: boolean): void {\n this.isOpen = toOpen;\n }\n\n private applyOpenState(toOpen: boolean, options: CloseOptions): void {\n const { bypassConfirmation = false } = options;\n\n if (toOpen === false) {\n // The confirmation is a one-shot permission for exactly this close\n // attempt – consume it here instead of only when a close succeeds, so it\n // cannot survive an aborted close and disarm later attempts.\n const closeIsConfirmed = this.closeIsConfirmed;\n this.closeIsConfirmed = false;\n\n if (\n this.confirmOnCloseEnabled &&\n !closeIsConfirmed &&\n this.closeWithoutConfirmationGrants.size === 0 &&\n !bypassConfirmation\n ) {\n this.showConfirmationModal = true;\n return;\n }\n }\n\n let aborted: boolean;\n if (toOpen) {\n aborted = this.executeOnOpen();\n } else {\n aborted = this.executeOnClose();\n }\n if (!aborted) {\n aborted = this.executeOnOpenChange(toOpen);\n }\n\n if (!aborted) {\n this.isOpen = toOpen;\n }\n }\n\n public setIsContentSuspended(to: boolean): void {\n this.isContentSuspended = to;\n }\n\n public useIsOpen() {\n return useSelector(() => this.isOpen);\n }\n\n public useIsContentSuspended() {\n return useSelector(() => this.isContentSuspended);\n }\n\n public useShowConfirmationModal() {\n return useSelector(() => this.showConfirmationModal);\n }\n\n public useConfirmOnCloseEnabled() {\n return useSelector(() => this.confirmOnCloseEnabled);\n }\n\n public useConfirmationController() {\n return useCloseOverlayConfirmationController(this);\n }\n\n /**\n * Allows closing this overlay without a confirmation until the returned\n * disposer is called. Use it around an operation that may legitimately close\n * the overlay – e.g. a `Form` submit, where a \"discard unsaved changes?\"\n * prompt would be nonsense – and dispose it as soon as that operation has\n * finished. An operation that ends without closing the overlay therefore\n * leaves the confirmation armed (#2775).\n */\n public grantCloseWithoutConfirmation(): DisposerFn {\n const grant = {};\n this.closeWithoutConfirmationGrants.add(grant);\n return () => {\n this.closeWithoutConfirmationGrants.delete(grant);\n };\n }\n\n public confirmClose(): void {\n this.closeIsConfirmed = true;\n this.showConfirmationModal = false;\n }\n\n public cancelConfirmation(): void {\n this.showConfirmationModal = false;\n }\n}\n"],"mappings":"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"}
@@ -2,7 +2,7 @@
2
2
  /* */
3
3
  import { createContext, useContext } from "react";
4
4
  //#region src/lib/controller/overlay/context.ts
5
- var overlayContext = createContext({ byType: {} });
5
+ var overlayContext = createContext({});
6
6
  var useOverlayContext = () => useContext(overlayContext);
7
7
  //#endregion
8
8
  export { overlayContext, useOverlayContext };
@@ -1 +1 @@
1
- {"version":3,"file":"context.mjs","names":[],"sources":["../../../../../../../../src/lib/controller/overlay/context.ts"],"sourcesContent":["import { createContext, useContext } from \"react\";\nimport type { OverlayController } from \"@/lib/controller/overlay/OverlayController\";\nimport type { FlowComponentName } from \"@/components/propTypes\";\n\nexport interface OverlayContext {\n /**\n * The enclosing overlays' controllers, keyed by the Flow component name the\n * providing overlay registers itself under. Innermost wins per name – a\n * `Modal` inside a `Modal` overwrites the `Modal` entry – but the map does\n * not record which of two differently named overlays is the inner one.\n */\n byType: Partial<Record<FlowComponentName, OverlayController | undefined>>;\n /**\n * The controller of the innermost overlay this subtree is the _content_ of,\n * whatever its component name. `undefined` outside any overlay content.\n *\n * Only providers that wrap overlay content set it. `OverlayTrigger` wraps the\n * trigger as well, so it contributes to `byType` only – an `Action` in the\n * trigger button is not inside the overlay it opens.\n */\n nearest?: OverlayController;\n}\n\nexport const overlayContext = createContext<OverlayContext>({ byType: {} });\n\nexport const useOverlayContext = (): OverlayContext =>\n useContext(overlayContext);\n"],"mappings":";;;;AAuBA,IAAa,iBAAiB,cAA8B,EAAE,QAAQ,CAAC,EAAE,CAAC;AAE1E,IAAa,0BACX,WAAW,cAAc"}
1
+ {"version":3,"file":"context.mjs","names":[],"sources":["../../../../../../../../src/lib/controller/overlay/context.ts"],"sourcesContent":["import { createContext, useContext } from \"react\";\nimport type { OverlayController } from \"@/lib/controller/overlay/OverlayController\";\nimport type { FlowComponentName } from \"@/components/propTypes\";\n\nexport type OverlayContext = Partial<\n Record<FlowComponentName, OverlayController | undefined>\n>;\n\nexport const overlayContext = createContext<OverlayContext>({});\n\nexport const useOverlayContext = (): OverlayContext =>\n useContext(overlayContext);\n"],"mappings":";;;;AAQA,IAAa,iBAAiB,cAA8B,CAAC,CAAC;AAE9D,IAAa,0BACX,WAAW,cAAc"}
@@ -6,7 +6,7 @@ import { useOverlayContext } from "./context.mjs";
6
6
  var useOverlayController = (overlayType, options = {}) => {
7
7
  const { reuseControllerFromContext = true, ...restControllerOptions } = options;
8
8
  const newController = OverlayController.useNew(restControllerOptions);
9
- const controllerFromContext = useOverlayContext().byType[overlayType];
9
+ const controllerFromContext = useOverlayContext()[overlayType];
10
10
  const controller = reuseControllerFromContext && controllerFromContext ? controllerFromContext : newController;
11
11
  if (controller === controllerFromContext) controller.useUpdateOptions(restControllerOptions);
12
12
  return controller;
@@ -1 +1 @@
1
- {"version":3,"file":"useOverlayController.mjs","names":[],"sources":["../../../../../../../../src/lib/controller/overlay/useOverlayController.ts"],"sourcesContent":["import { useOverlayContext } from \"@/lib/controller/overlay/context\";\nimport type { OverlayControllerOptions } from \"@/lib/controller/overlay/OverlayController\";\nimport { OverlayController } from \"@/lib/controller/overlay/OverlayController\";\nimport type { FlowComponentName } from \"@/components/propTypes\";\n\nexport interface UseOverlayControllerOptions extends OverlayControllerOptions {\n reuseControllerFromContext?: boolean;\n}\n\nexport const useOverlayController = (\n overlayType: FlowComponentName,\n options: UseOverlayControllerOptions = {},\n): OverlayController => {\n const { reuseControllerFromContext = true, ...restControllerOptions } =\n options;\n\n const newController = OverlayController.useNew(restControllerOptions);\n const controllerFromContext = useOverlayContext().byType[overlayType];\n\n const controller =\n reuseControllerFromContext && controllerFromContext\n ? controllerFromContext\n : newController;\n\n if (controller === controllerFromContext) {\n controller.useUpdateOptions(restControllerOptions);\n }\n\n return controller;\n};\n"],"mappings":";;;;;AASA,IAAa,wBACX,aACA,UAAuC,CAAC,MAClB;CACtB,MAAM,EAAE,6BAA6B,MAAM,GAAG,0BAC5C;CAEF,MAAM,gBAAgB,kBAAkB,OAAO,qBAAqB;CACpE,MAAM,wBAAwB,kBAAkB,CAAC,CAAC,OAAO;CAEzD,MAAM,aACJ,8BAA8B,wBAC1B,wBACA;CAEN,IAAI,eAAe,uBACjB,WAAW,iBAAiB,qBAAqB;CAGnD,OAAO;AACT"}
1
+ {"version":3,"file":"useOverlayController.mjs","names":[],"sources":["../../../../../../../../src/lib/controller/overlay/useOverlayController.ts"],"sourcesContent":["import { useOverlayContext } from \"@/lib/controller/overlay/context\";\nimport type { OverlayControllerOptions } from \"@/lib/controller/overlay/OverlayController\";\nimport { OverlayController } from \"@/lib/controller/overlay/OverlayController\";\nimport type { FlowComponentName } from \"@/components/propTypes\";\n\nexport interface UseOverlayControllerOptions extends OverlayControllerOptions {\n reuseControllerFromContext?: boolean;\n}\n\nexport const useOverlayController = (\n overlayType: FlowComponentName,\n options: UseOverlayControllerOptions = {},\n): OverlayController => {\n const { reuseControllerFromContext = true, ...restControllerOptions } =\n options;\n\n const newController = OverlayController.useNew(restControllerOptions);\n const controllerFromContext = useOverlayContext()[overlayType];\n\n const controller =\n reuseControllerFromContext && controllerFromContext\n ? controllerFromContext\n : newController;\n\n if (controller === controllerFromContext) {\n controller.useUpdateOptions(restControllerOptions);\n }\n\n return controller;\n};\n"],"mappings":";;;;;AASA,IAAa,wBACX,aACA,UAAuC,CAAC,MAClB;CACtB,MAAM,EAAE,6BAA6B,MAAM,GAAG,0BAC5C;CAEF,MAAM,gBAAgB,kBAAkB,OAAO,qBAAqB;CACpE,MAAM,wBAAwB,kBAAkB,CAAC,CAAC;CAElD,MAAM,aACJ,8BAA8B,wBAC1B,wBACA;CAEN,IAAI,eAAe,uBACjB,WAAW,iBAAiB,qBAAqB;CAGnD,OAAO;AACT"}
@@ -0,0 +1,34 @@
1
+ "use client"
2
+ /* */
3
+ //#region src/lib/files/acceptedFiles.ts
4
+ /**
5
+ * Whether a file matches an `accept` attribute value — a comma separated list
6
+ * of MIME types (`image/png`), MIME wildcards (`image/*`) and file extensions
7
+ * (`.png`). A missing or empty list matches everything, the way the attribute
8
+ * itself does.
9
+ *
10
+ * @internal
11
+ */
12
+ var matchesAccept = (file, accept) => {
13
+ const tokens = accept?.split(",").map((token) => token.trim().toLowerCase()).filter(Boolean) ?? [];
14
+ if (tokens.length === 0) return true;
15
+ const type = file.type.toLowerCase();
16
+ const name = file.name.toLowerCase();
17
+ return tokens.some((token) => {
18
+ if (token.startsWith(".")) return name.endsWith(token);
19
+ if (token.endsWith("/*")) return type.startsWith(token.slice(0, -1));
20
+ return type === token;
21
+ });
22
+ };
23
+ /**
24
+ * The files of a drop event that match `accept`. Non-file items (dragged text,
25
+ * directories) are skipped, and the filter runs on the drop item — so a file
26
+ * `accept` rejects is never read from disk.
27
+ *
28
+ * @internal
29
+ */
30
+ var getAcceptedFiles = async (items, accept) => await Promise.all(items.filter((item) => item.kind === "file").filter((item) => matchesAccept(item, accept)).map(async (item) => await item.getFile()));
31
+ //#endregion
32
+ export { getAcceptedFiles, matchesAccept };
33
+
34
+ //# sourceMappingURL=acceptedFiles.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acceptedFiles.mjs","names":[],"sources":["../../../../../../../src/lib/files/acceptedFiles.ts"],"sourcesContent":["import type { DropItem } from \"@react-types/shared\";\n\n/**\n * Whether a file matches an `accept` attribute value — a comma separated list\n * of MIME types (`image/png`), MIME wildcards (`image/*`) and file extensions\n * (`.png`). A missing or empty list matches everything, the way the attribute\n * itself does.\n *\n * @internal\n */\nexport const matchesAccept = (\n file: Pick<File, \"name\" | \"type\">,\n accept?: string,\n): boolean => {\n const tokens =\n accept\n ?.split(\",\")\n .map((token) => token.trim().toLowerCase())\n .filter(Boolean) ?? [];\n\n if (tokens.length === 0) {\n return true;\n }\n\n const type = file.type.toLowerCase();\n const name = file.name.toLowerCase();\n\n return tokens.some((token) => {\n if (token.startsWith(\".\")) {\n return name.endsWith(token);\n }\n if (token.endsWith(\"/*\")) {\n return type.startsWith(token.slice(0, -1));\n }\n return type === token;\n });\n};\n\n/**\n * The files of a drop event that match `accept`. Non-file items (dragged text,\n * directories) are skipped, and the filter runs on the drop item — so a file\n * `accept` rejects is never read from disk.\n *\n * @internal\n */\nexport const getAcceptedFiles = async (\n items: readonly DropItem[],\n accept?: string,\n): Promise<File[]> =>\n await Promise.all(\n items\n .filter((item) => item.kind === \"file\")\n .filter((item) => matchesAccept(item, accept))\n .map(async (item) => await item.getFile()),\n );\n"],"mappings":";;;;;;;;;;;AAUA,IAAa,iBACX,MACA,WACY;CACZ,MAAM,SACJ,QACI,MAAM,GAAG,CAAC,CACX,KAAK,UAAU,MAAM,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAC1C,OAAO,OAAO,KAAK,CAAC;CAEzB,IAAI,OAAO,WAAW,GACpB,OAAO;CAGT,MAAM,OAAO,KAAK,KAAK,YAAY;CACnC,MAAM,OAAO,KAAK,KAAK,YAAY;CAEnC,OAAO,OAAO,MAAM,UAAU;EAC5B,IAAI,MAAM,WAAW,GAAG,GACtB,OAAO,KAAK,SAAS,KAAK;EAE5B,IAAI,MAAM,SAAS,IAAI,GACrB,OAAO,KAAK,WAAW,MAAM,MAAM,GAAG,EAAE,CAAC;EAE3C,OAAO,SAAS;CAClB,CAAC;AACH;;;;;;;;AASA,IAAa,mBAAmB,OAC9B,OACA,WAEA,MAAM,QAAQ,IACZ,MACG,QAAQ,SAAS,KAAK,SAAS,MAAM,CAAC,CACtC,QAAQ,SAAS,cAAc,MAAM,MAAM,CAAC,CAAC,CAC7C,IAAI,OAAO,SAAS,MAAM,KAAK,QAAQ,CAAC,CAC7C"}
@@ -59,6 +59,6 @@ var useKeepBrowserExtensionsInteractive = (isActive) => {
59
59
  }, [isActive]);
60
60
  };
61
61
  //#endregion
62
- export { useKeepBrowserExtensionsInteractive as default, useKeepBrowserExtensionsInteractive };
62
+ export { useKeepBrowserExtensionsInteractive as default, useKeepBrowserExtensionsInteractive, isBrowserExtensionNode };
63
63
 
64
64
  //# sourceMappingURL=useKeepBrowserExtensionsInteractive.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"useKeepBrowserExtensionsInteractive.mjs","names":[],"sources":["../../../../../../../../src/lib/hooks/dom/useKeepBrowserExtensionsInteractive.ts"],"sourcesContent":["import { useEffect } from \"react\";\n\n/**\n * Attribute react-aria checks to keep a node out of the `inert` / `aria-hidden`\n * isolation it applies to everything outside an open modal overlay.\n *\n * @see `isAlwaysVisibleNode` in `@react-aria/overlays` (`ariaHideOutside`)\n */\nconst keepInteractiveAttribute = \"data-react-aria-top-layer\";\n\nconst extensionUrlSchemes = [\n \"chrome-extension:\",\n \"moz-extension:\",\n \"safari-web-extension:\",\n \"safari-extension:\",\n];\n\nconst isBrowserExtensionNode = (element: Element): boolean => {\n if (element.tagName.includes(\"-\")) {\n return true;\n }\n if (element.shadowRoot !== null) {\n return true;\n }\n if (element instanceof HTMLIFrameElement) {\n const source = element.getAttribute(\"src\") ?? \"\";\n return extensionUrlSchemes.some((scheme) => source.startsWith(scheme));\n }\n return false;\n};\n\nconst keepInteractive = (element: Element): void => {\n if (!element.hasAttribute(keepInteractiveAttribute)) {\n element.setAttribute(keepInteractiveAttribute, \"\");\n }\n if (element instanceof HTMLElement && element.inert) {\n element.inert = false;\n }\n if (element.getAttribute(\"aria-hidden\") === \"true\") {\n element.removeAttribute(\"aria-hidden\");\n }\n};\n\n/**\n * While a modal overlay is open, react-aria isolates the rest of the document\n * by setting `inert` on every sibling of the modal (see `ariaHideOutside`) —\n * and it keeps doing so for nodes that appear afterwards via a\n * `MutationObserver`. That also catches UI a browser extension injects while\n * the modal is open, e.g. a password manager's autofill dropdown on a field, or\n * its \"save credentials\" popover. An `inert` node stays visible but cannot be\n * clicked, so the user sees the extension UI but cannot interact with it.\n *\n * This hook watches the document while `isActive` and re-enables such\n * extension-injected, document-level nodes, so browser extensions keep working\n * on top of modals. It targets the structural fingerprint of extension UI (see\n * {@link isBrowserExtensionNode}) rather than a fixed list of vendors.\n */\nexport const useKeepBrowserExtensionsInteractive = (\n isActive: boolean,\n): void => {\n useEffect(() => {\n if (!isActive || typeof MutationObserver === \"undefined\") {\n return;\n }\n\n const root = document.body;\n\n const process = (node: Node): void => {\n if (node instanceof Element && isBrowserExtensionNode(node)) {\n keepInteractive(node);\n }\n };\n\n for (const child of Array.from(root.children)) {\n process(child);\n }\n\n const observer = new MutationObserver((mutations) => {\n for (const mutation of mutations) {\n for (const node of Array.from(mutation.addedNodes)) {\n process(node);\n }\n }\n });\n observer.observe(root, { childList: true });\n\n return () => observer.disconnect();\n }, [isActive]);\n};\n\nexport default useKeepBrowserExtensionsInteractive;\n"],"mappings":";;;;;;;;;;AAQA,IAAM,2BAA2B;AAEjC,IAAM,sBAAsB;CAC1B;CACA;CACA;CACA;AACF;AAEA,IAAM,0BAA0B,YAA8B;CAC5D,IAAI,QAAQ,QAAQ,SAAS,GAAG,GAC9B,OAAO;CAET,IAAI,QAAQ,eAAe,MACzB,OAAO;CAET,IAAI,mBAAmB,mBAAmB;EACxC,MAAM,SAAS,QAAQ,aAAa,KAAK,KAAK;EAC9C,OAAO,oBAAoB,MAAM,WAAW,OAAO,WAAW,MAAM,CAAC;CACvE;CACA,OAAO;AACT;AAEA,IAAM,mBAAmB,YAA2B;CAClD,IAAI,CAAC,QAAQ,aAAa,wBAAwB,GAChD,QAAQ,aAAa,0BAA0B,EAAE;CAEnD,IAAI,mBAAmB,eAAe,QAAQ,OAC5C,QAAQ,QAAQ;CAElB,IAAI,QAAQ,aAAa,aAAa,MAAM,QAC1C,QAAQ,gBAAgB,aAAa;AAEzC;;;;;;;;;;;;;;;AAgBA,IAAa,uCACX,aACS;CACT,gBAAgB;EACd,IAAI,CAAC,YAAY,OAAO,qBAAqB,aAC3C;EAGF,MAAM,OAAO,SAAS;EAEtB,MAAM,WAAW,SAAqB;GACpC,IAAI,gBAAgB,WAAW,uBAAuB,IAAI,GACxD,gBAAgB,IAAI;EAExB;EAEA,KAAK,MAAM,SAAS,MAAM,KAAK,KAAK,QAAQ,GAC1C,QAAQ,KAAK;EAGf,MAAM,WAAW,IAAI,kBAAkB,cAAc;GACnD,KAAK,MAAM,YAAY,WACrB,KAAK,MAAM,QAAQ,MAAM,KAAK,SAAS,UAAU,GAC/C,QAAQ,IAAI;EAGlB,CAAC;EACD,SAAS,QAAQ,MAAM,EAAE,WAAW,KAAK,CAAC;EAE1C,aAAa,SAAS,WAAW;CACnC,GAAG,CAAC,QAAQ,CAAC;AACf"}
1
+ {"version":3,"file":"useKeepBrowserExtensionsInteractive.mjs","names":[],"sources":["../../../../../../../../src/lib/hooks/dom/useKeepBrowserExtensionsInteractive.ts"],"sourcesContent":["import { useEffect } from \"react\";\n\n/**\n * Attribute react-aria checks to keep a node out of the `inert` / `aria-hidden`\n * isolation it applies to everything outside an open modal overlay.\n *\n * @see `isAlwaysVisibleNode` in `@react-aria/overlays` (`ariaHideOutside`)\n */\nconst keepInteractiveAttribute = \"data-react-aria-top-layer\";\n\nconst extensionUrlSchemes = [\n \"chrome-extension:\",\n \"moz-extension:\",\n \"safari-web-extension:\",\n \"safari-extension:\",\n];\n\nexport const isBrowserExtensionNode = (element: Element): boolean => {\n if (element.tagName.includes(\"-\")) {\n return true;\n }\n if (element.shadowRoot !== null) {\n return true;\n }\n if (element instanceof HTMLIFrameElement) {\n const source = element.getAttribute(\"src\") ?? \"\";\n return extensionUrlSchemes.some((scheme) => source.startsWith(scheme));\n }\n return false;\n};\n\nconst keepInteractive = (element: Element): void => {\n if (!element.hasAttribute(keepInteractiveAttribute)) {\n element.setAttribute(keepInteractiveAttribute, \"\");\n }\n if (element instanceof HTMLElement && element.inert) {\n element.inert = false;\n }\n if (element.getAttribute(\"aria-hidden\") === \"true\") {\n element.removeAttribute(\"aria-hidden\");\n }\n};\n\n/**\n * While a modal overlay is open, react-aria isolates the rest of the document\n * by setting `inert` on every sibling of the modal (see `ariaHideOutside`) —\n * and it keeps doing so for nodes that appear afterwards via a\n * `MutationObserver`. That also catches UI a browser extension injects while\n * the modal is open, e.g. a password manager's autofill dropdown on a field, or\n * its \"save credentials\" popover. An `inert` node stays visible but cannot be\n * clicked, so the user sees the extension UI but cannot interact with it.\n *\n * This hook watches the document while `isActive` and re-enables such\n * extension-injected, document-level nodes, so browser extensions keep working\n * on top of modals. It targets the structural fingerprint of extension UI (see\n * {@link isBrowserExtensionNode}) rather than a fixed list of vendors.\n */\nexport const useKeepBrowserExtensionsInteractive = (\n isActive: boolean,\n): void => {\n useEffect(() => {\n if (!isActive || typeof MutationObserver === \"undefined\") {\n return;\n }\n\n const root = document.body;\n\n const process = (node: Node): void => {\n if (node instanceof Element && isBrowserExtensionNode(node)) {\n keepInteractive(node);\n }\n };\n\n for (const child of Array.from(root.children)) {\n process(child);\n }\n\n const observer = new MutationObserver((mutations) => {\n for (const mutation of mutations) {\n for (const node of Array.from(mutation.addedNodes)) {\n process(node);\n }\n }\n });\n observer.observe(root, { childList: true });\n\n return () => observer.disconnect();\n }, [isActive]);\n};\n\nexport default useKeepBrowserExtensionsInteractive;\n"],"mappings":";;;;;;;;;;AAQA,IAAM,2BAA2B;AAEjC,IAAM,sBAAsB;CAC1B;CACA;CACA;CACA;AACF;AAEA,IAAa,0BAA0B,YAA8B;CACnE,IAAI,QAAQ,QAAQ,SAAS,GAAG,GAC9B,OAAO;CAET,IAAI,QAAQ,eAAe,MACzB,OAAO;CAET,IAAI,mBAAmB,mBAAmB;EACxC,MAAM,SAAS,QAAQ,aAAa,KAAK,KAAK;EAC9C,OAAO,oBAAoB,MAAM,WAAW,OAAO,WAAW,MAAM,CAAC;CACvE;CACA,OAAO;AACT;AAEA,IAAM,mBAAmB,YAA2B;CAClD,IAAI,CAAC,QAAQ,aAAa,wBAAwB,GAChD,QAAQ,aAAa,0BAA0B,EAAE;CAEnD,IAAI,mBAAmB,eAAe,QAAQ,OAC5C,QAAQ,QAAQ;CAElB,IAAI,QAAQ,aAAa,aAAa,MAAM,QAC1C,QAAQ,gBAAgB,aAAa;AAEzC;;;;;;;;;;;;;;;AAgBA,IAAa,uCACX,aACS;CACT,gBAAgB;EACd,IAAI,CAAC,YAAY,OAAO,qBAAqB,aAC3C;EAGF,MAAM,OAAO,SAAS;EAEtB,MAAM,WAAW,SAAqB;GACpC,IAAI,gBAAgB,WAAW,uBAAuB,IAAI,GACxD,gBAAgB,IAAI;EAExB;EAEA,KAAK,MAAM,SAAS,MAAM,KAAK,KAAK,QAAQ,GAC1C,QAAQ,KAAK;EAGf,MAAM,WAAW,IAAI,kBAAkB,cAAc;GACnD,KAAK,MAAM,YAAY,WACrB,KAAK,MAAM,QAAQ,MAAM,KAAK,SAAS,UAAU,GAC/C,QAAQ,IAAI;EAGlB,CAAC;EACD,SAAS,QAAQ,MAAM,EAAE,WAAW,KAAK,CAAC;EAE1C,aAAa,SAAS,WAAW;CACnC,GAAG,CAAC,QAAQ,CAAC;AACf"}
@@ -4326,6 +4326,10 @@ var all_dark_default = {
4326
4326
  "path": ["big-number", "font-weight"]
4327
4327
  }
4328
4328
  },
4329
+ "cartesian-chart": { "transition-duration": {
4330
+ "value": "800ms",
4331
+ "path": ["cartesian-chart", "transition-duration"]
4332
+ } },
4329
4333
  "cartesian-grid": {
4330
4334
  "color": {
4331
4335
  "value": "#E5EFF8",
@@ -4341,6 +4345,10 @@ var all_dark_default = {
4341
4345
  "path": ["chart-tooltip", "spacing"]
4342
4346
  } },
4343
4347
  "donut-chart": {
4348
+ "transition-duration": {
4349
+ "value": "800ms",
4350
+ "path": ["donut-chart", "transition-duration"]
4351
+ },
4344
4352
  "border-color": {
4345
4353
  "value": "#DCE9F7",
4346
4354
  "path": ["donut-chart", "border-color"]
@@ -5302,6 +5310,10 @@ var all_dark_default = {
5302
5310
  "path": ["password-creation-field", "rule-to-rule-spacing"]
5303
5311
  } },
5304
5312
  "progress-bar": {
5313
+ "transition-duration": {
5314
+ "value": "800ms",
5315
+ "path": ["progress-bar", "transition-duration"]
5316
+ },
5305
5317
  "font-size": {
5306
5318
  "value": "1rem",
5307
5319
  "path": ["progress-bar", "font-size"]