@payloadcms/ui 4.0.0-canary.16 → 4.0.0-canary.18

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 (153) hide show
  1. package/dist/css/app.css +121 -0
  2. package/dist/css/forms.css +0 -6
  3. package/dist/css/spacing.css +10 -3
  4. package/dist/css/z-index.css +1 -0
  5. package/dist/elements/AddNewRelation/index.css +0 -1
  6. package/dist/elements/AppHeader/index.css +0 -3
  7. package/dist/elements/AppHeader/index.d.ts.map +1 -1
  8. package/dist/elements/AppHeader/index.js +5 -1
  9. package/dist/elements/AppHeader/index.js.map +1 -1
  10. package/dist/elements/BulkUpload/EditMany/DrawerContent.js +2 -2
  11. package/dist/elements/BulkUpload/EditMany/DrawerContent.js.map +1 -1
  12. package/dist/elements/CodeEditor/index.css +0 -5
  13. package/dist/elements/CommandPalette/index.css +0 -7
  14. package/dist/elements/DatePicker/DatePicker.d.ts.map +1 -1
  15. package/dist/elements/DatePicker/DatePicker.js +1 -0
  16. package/dist/elements/DatePicker/DatePicker.js.map +1 -1
  17. package/dist/elements/DatePicker/index.css +1 -1
  18. package/dist/elements/DeleteDocument/index.d.ts.map +1 -1
  19. package/dist/elements/DeleteDocument/index.js +16 -1
  20. package/dist/elements/DeleteDocument/index.js.map +1 -1
  21. package/dist/elements/EditMany/DrawerContent.js +2 -2
  22. package/dist/elements/EditMany/DrawerContent.js.map +1 -1
  23. package/dist/elements/FileDetails/StaticFileDetails/index.css +8 -9
  24. package/dist/elements/FileManager/index.js +1 -0
  25. package/dist/elements/FileManager/index.js.map +1 -1
  26. package/dist/elements/Hierarchy/ColumnBrowser/ColumnItem/index.css +0 -1
  27. package/dist/elements/Hierarchy/Tree/TreeNode/index.css +0 -1
  28. package/dist/elements/InputStepper/index.css +0 -1
  29. package/dist/elements/Locked/index.css +0 -8
  30. package/dist/elements/Locked/index.d.ts.map +1 -1
  31. package/dist/elements/Locked/index.js +70 -64
  32. package/dist/elements/Locked/index.js.map +1 -1
  33. package/dist/elements/Nav/SidebarTabs/index.css +0 -5
  34. package/dist/elements/NavGroup/index.css +0 -1
  35. package/dist/elements/PreviewButton/index.d.ts +1 -2
  36. package/dist/elements/PreviewButton/index.d.ts.map +1 -1
  37. package/dist/elements/PreviewButton/index.js +11 -5
  38. package/dist/elements/PreviewButton/index.js.map +1 -1
  39. package/dist/elements/PreviewSizes/index.css +8 -9
  40. package/dist/elements/ReactSelect/ClearIndicator/index.css +0 -1
  41. package/dist/elements/ReactSelect/MultiValue/index.css +0 -1
  42. package/dist/elements/ReactSelect/index.css +0 -3
  43. package/dist/elements/RelationshipTable/index.d.ts.map +1 -1
  44. package/dist/elements/RelationshipTable/index.js +32 -0
  45. package/dist/elements/RelationshipTable/index.js.map +1 -1
  46. package/dist/elements/SelectRow/index.d.ts +4 -3
  47. package/dist/elements/SelectRow/index.d.ts.map +1 -1
  48. package/dist/elements/SelectRow/index.js +10 -7
  49. package/dist/elements/SelectRow/index.js.map +1 -1
  50. package/dist/elements/SidebarToggle/index.css +0 -17
  51. package/dist/elements/SortColumn/index.d.ts.map +1 -1
  52. package/dist/elements/SortColumn/index.js +42 -38
  53. package/dist/elements/SortColumn/index.js.map +1 -1
  54. package/dist/elements/Tooltip/index.css +15 -34
  55. package/dist/elements/Tooltip/index.d.ts +11 -3
  56. package/dist/elements/Tooltip/index.d.ts.map +1 -1
  57. package/dist/elements/Tooltip/index.js +151 -85
  58. package/dist/elements/Tooltip/index.js.map +1 -1
  59. package/dist/elements/Upload/index.css +0 -5
  60. package/dist/exports/client/index.d.ts +3 -0
  61. package/dist/exports/client/index.d.ts.map +1 -1
  62. package/dist/exports/client/index.js +1 -1
  63. package/dist/exports/client/index.js.map +3 -3
  64. package/dist/fields/Checkbox/Input.d.ts +2 -0
  65. package/dist/fields/Checkbox/Input.d.ts.map +1 -1
  66. package/dist/fields/Checkbox/Input.js +32 -26
  67. package/dist/fields/Checkbox/Input.js.map +1 -1
  68. package/dist/fields/Checkbox/index.css +37 -73
  69. package/dist/fields/FieldError/index.css +0 -9
  70. package/dist/fields/FieldError/index.d.ts.map +1 -1
  71. package/dist/fields/FieldError/index.js +19 -9
  72. package/dist/fields/FieldError/index.js.map +1 -1
  73. package/dist/fields/RadioGroup/index.css +0 -7
  74. package/dist/fields/Relationship/Input.d.ts.map +1 -1
  75. package/dist/fields/Relationship/Input.js +32 -14
  76. package/dist/fields/Relationship/Input.js.map +1 -1
  77. package/dist/fields/Slug/index.css +0 -1
  78. package/dist/fields/Slug/index.d.ts.map +1 -1
  79. package/dist/fields/Slug/index.js +80 -125
  80. package/dist/fields/Slug/index.js.map +1 -1
  81. package/dist/forms/Form/fieldReducer.d.ts.map +1 -1
  82. package/dist/forms/Form/fieldReducer.js +3 -1
  83. package/dist/forms/Form/fieldReducer.js.map +1 -1
  84. package/dist/forms/Form/index.d.ts.map +1 -1
  85. package/dist/forms/Form/index.js +6 -1
  86. package/dist/forms/Form/index.js.map +1 -1
  87. package/dist/forms/Form/types.d.ts +1 -1
  88. package/dist/forms/Form/types.d.ts.map +1 -1
  89. package/dist/forms/Form/types.js.map +1 -1
  90. package/dist/forms/WatchChildErrors/index.d.ts.map +1 -1
  91. package/dist/forms/WatchChildErrors/index.js +2 -2
  92. package/dist/forms/WatchChildErrors/index.js.map +1 -1
  93. package/dist/forms/fieldSchemasToFormState/addFieldStatePromise.js +1 -1
  94. package/dist/forms/fieldSchemasToFormState/addFieldStatePromise.js.map +1 -1
  95. package/dist/forms/fieldSchemasToFormState/renderField.d.ts.map +1 -1
  96. package/dist/forms/fieldSchemasToFormState/renderField.js +1 -3
  97. package/dist/forms/fieldSchemasToFormState/renderField.js.map +1 -1
  98. package/dist/layouts/Root/index.d.ts +1 -1
  99. package/dist/layouts/Root/index.d.ts.map +1 -1
  100. package/dist/layouts/Root/index.js +8 -2
  101. package/dist/layouts/Root/index.js.map +1 -1
  102. package/dist/providers/Embed/index.d.ts +24 -0
  103. package/dist/providers/Embed/index.d.ts.map +1 -0
  104. package/dist/providers/Embed/index.js +105 -0
  105. package/dist/providers/Embed/index.js.map +1 -0
  106. package/dist/providers/FormErrorHandler/index.d.ts +20 -0
  107. package/dist/providers/FormErrorHandler/index.d.ts.map +1 -0
  108. package/dist/providers/FormErrorHandler/index.js +6 -0
  109. package/dist/providers/FormErrorHandler/index.js.map +1 -0
  110. package/dist/providers/Root/index.d.ts +1 -0
  111. package/dist/providers/Root/index.d.ts.map +1 -1
  112. package/dist/providers/Root/index.js +33 -27
  113. package/dist/providers/Root/index.js.map +1 -1
  114. package/dist/providers/Theme/index.d.ts +3 -0
  115. package/dist/providers/Theme/index.d.ts.map +1 -1
  116. package/dist/providers/Theme/index.js +107 -95
  117. package/dist/providers/Theme/index.js.map +1 -1
  118. package/dist/styles.css +12 -10
  119. package/dist/utilities/combineFieldLabel.d.ts.map +1 -1
  120. package/dist/utilities/combineFieldLabel.js +5 -1
  121. package/dist/utilities/combineFieldLabel.js.map +1 -1
  122. package/dist/utilities/generateFieldID.d.ts +1 -1
  123. package/dist/utilities/generateFieldID.d.ts.map +1 -1
  124. package/dist/utilities/generateFieldID.js +2 -2
  125. package/dist/utilities/generateFieldID.js.map +1 -1
  126. package/dist/utilities/getRequestEmbed.d.ts +14 -0
  127. package/dist/utilities/getRequestEmbed.d.ts.map +1 -0
  128. package/dist/utilities/getRequestEmbed.js +10 -0
  129. package/dist/utilities/getRequestEmbed.js.map +1 -0
  130. package/dist/utilities/renderTable.d.ts.map +1 -1
  131. package/dist/utilities/renderTable.js +18 -2
  132. package/dist/utilities/renderTable.js.map +1 -1
  133. package/dist/utilities/slugify.d.ts.map +1 -1
  134. package/dist/utilities/slugify.js +49 -6
  135. package/dist/utilities/slugify.js.map +1 -1
  136. package/dist/views/Dashboard/Default/ModularDashboard/index.css +0 -8
  137. package/dist/views/Dashboard/Default/ModularDashboard/renderWidget/RenderWidget.js +4 -4
  138. package/dist/views/Dashboard/Default/ModularDashboard/renderWidget/RenderWidget.js.map +1 -1
  139. package/dist/views/Dashboard/Default/ModularDashboard/renderWidget/renderWidgetServerFn.js +10 -10
  140. package/dist/views/Dashboard/Default/ModularDashboard/renderWidget/renderWidgetServerFn.js.map +1 -1
  141. package/dist/views/List/index.d.ts.map +1 -1
  142. package/dist/views/List/index.js +4 -0
  143. package/dist/views/List/index.js.map +1 -1
  144. package/package.json +5 -10
  145. package/dist/scss/app.scss +0 -183
  146. package/dist/scss/colors.scss +0 -191
  147. package/dist/scss/custom.css +0 -1
  148. package/dist/scss/queries.scss +0 -27
  149. package/dist/scss/styles.scss +0 -9
  150. package/dist/scss/svg.scss +0 -10
  151. package/dist/scss/toastify.scss +0 -61
  152. package/dist/scss/vars.scss +0 -192
  153. package/dist/scss/z-index.scss +0 -9
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["c","_c","React","FieldLabel","ChevronIcon","useListQuery","useTranslation","baseClass","SortColumn","props","$","name","appearance","disable","t0","Label","label","undefined","handleSortChange","query","t","sort","desc","asc","ascClasses","push","descClasses","isSorted","t1","t2","t3","filter","Boolean","t4","join","t5","_jsxs","className","children","_jsx","hideLocale","unstyled","direction","onClick","type","size"],"sources":["../../../src/elements/SortColumn/index.tsx"],"sourcesContent":["'use client'\nimport type { StaticLabel } from 'payload'\n\nimport React from 'react'\n\nimport { FieldLabel } from '../../fields/FieldLabel/index.js'\nimport { ChevronIcon } from '../../icons/Chevron/index.js'\nimport { useListQuery } from '../../providers/ListQuery/index.js'\nimport { useTranslation } from '../../providers/Translation/index.js'\nimport './index.css'\n\nexport type SortColumnProps = {\n readonly appearance?: 'condensed' | 'default'\n readonly disable?: boolean\n readonly Label: React.ReactNode\n readonly label?: StaticLabel\n readonly name: string\n}\n\nconst baseClass = 'sort-column'\n\nexport const SortColumn: React.FC<SortColumnProps> = (props) => {\n const { name, appearance, disable = false, Label, label } = props\n const { handleSortChange, query } = useListQuery()\n const { t } = useTranslation()\n\n const { sort } = query\n\n const desc = `-${name}`\n const asc = name\n\n const ascClasses = [`${baseClass}__asc`]\n if (sort === asc) {\n ascClasses.push(`${baseClass}--active`)\n }\n\n const descClasses = [`${baseClass}__desc`]\n if (sort === desc) {\n descClasses.push(`${baseClass}--active`)\n }\n\n const isSorted = sort === asc || sort === desc\n\n return (\n <div\n className={[\n baseClass,\n appearance && `${baseClass}--appearance-${appearance}`,\n isSorted && `${baseClass}--sorted`,\n ]\n .filter(Boolean)\n .join(' ')}\n >\n <span className={`${baseClass}__label`}>\n {Label ?? <FieldLabel hideLocale label={label} unstyled />}\n </span>\n {!disable && (\n <div className={`${baseClass}__buttons`}>\n <button\n aria-label={t('general:sortByLabelDirection', {\n direction: t('general:descending'),\n label,\n })}\n className={[...descClasses, `${baseClass}__button`].filter(Boolean).join(' ')}\n onClick={() => void handleSortChange(desc)}\n type=\"button\"\n >\n <ChevronIcon size={16} />\n </button>\n <button\n aria-label={t('general:sortByLabelDirection', {\n direction: t('general:ascending'),\n label,\n })}\n className={[...ascClasses, `${baseClass}__button`].filter(Boolean).join(' ')}\n onClick={() => void handleSortChange(asc)}\n type=\"button\"\n >\n <ChevronIcon direction=\"up\" size={16} />\n </button>\n </div>\n )}\n </div>\n )\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"index.js","names":["c","_c","React","FieldLabel","ChevronIcon","useListQuery","useTranslation","baseClass","SortColumn","props","$","name","appearance","disable","t0","Label","label","undefined","handleSortChange","query","t","sort","desc","asc","ascClasses","push","descClasses","isSorted","t1","descLabel","direction","ascLabel","t2","t3","t4","filter","Boolean","_jsxs","className","join","children","_jsx","hideLocale","unstyled","onClick","title","type","size"],"sources":["../../../src/elements/SortColumn/index.tsx"],"sourcesContent":["'use client'\nimport type { StaticLabel } from 'payload'\n\nimport React from 'react'\n\nimport { FieldLabel } from '../../fields/FieldLabel/index.js'\nimport { ChevronIcon } from '../../icons/Chevron/index.js'\nimport { useListQuery } from '../../providers/ListQuery/index.js'\nimport { useTranslation } from '../../providers/Translation/index.js'\nimport './index.css'\n\nexport type SortColumnProps = {\n readonly appearance?: 'condensed' | 'default'\n readonly disable?: boolean\n readonly Label: React.ReactNode\n readonly label?: StaticLabel\n readonly name: string\n}\n\nconst baseClass = 'sort-column'\n\nexport const SortColumn: React.FC<SortColumnProps> = (props) => {\n const { name, appearance, disable = false, Label, label } = props\n const { handleSortChange, query } = useListQuery()\n const { t } = useTranslation()\n\n const { sort } = query\n\n const desc = `-${name}`\n const asc = name\n\n const ascClasses = [`${baseClass}__asc`]\n if (sort === asc) {\n ascClasses.push(`${baseClass}--active`)\n }\n\n const descClasses = [`${baseClass}__desc`]\n if (sort === desc) {\n descClasses.push(`${baseClass}--active`)\n }\n\n const isSorted = sort === asc || sort === desc\n\n const descLabel = t('general:sortByLabelDirection', {\n direction: t('general:descending'),\n label,\n })\n const ascLabel = t('general:sortByLabelDirection', {\n direction: t('general:ascending'),\n label,\n })\n\n return (\n <div\n className={[\n baseClass,\n appearance && `${baseClass}--appearance-${appearance}`,\n isSorted && `${baseClass}--sorted`,\n ]\n .filter(Boolean)\n .join(' ')}\n >\n <span className={`${baseClass}__label`}>\n {Label ?? <FieldLabel hideLocale label={label} unstyled />}\n </span>\n {!disable && (\n <div className={`${baseClass}__buttons`}>\n <button\n aria-label={descLabel}\n className={[...descClasses, `${baseClass}__button`].filter(Boolean).join(' ')}\n onClick={() => void handleSortChange(desc)}\n title={descLabel}\n type=\"button\"\n >\n <ChevronIcon size={16} />\n </button>\n <button\n aria-label={ascLabel}\n className={[...ascClasses, `${baseClass}__button`].filter(Boolean).join(' ')}\n onClick={() => void handleSortChange(asc)}\n title={ascLabel}\n type=\"button\"\n >\n <ChevronIcon direction=\"up\" size={16} />\n </button>\n </div>\n )}\n </div>\n )\n}\n"],"mappings":"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","ignoreList":[]}
@@ -4,15 +4,18 @@
4
4
  --caret-height: 7px;
5
5
  --caret-offset: 4px;
6
6
  --caret-border-color: var(--color-border);
7
- --tooltip-x: -50%;
8
7
  --tooltip-caret-x: 0px;
8
+ --tooltip-caret-y: 0px;
9
9
  --tooltip-max-width: none;
10
10
 
11
+ position: fixed;
12
+ top: 0;
13
+ left: 0;
14
+ z-index: var(--z-portal-element);
15
+ pointer-events: none;
16
+
11
17
  opacity: 0;
12
18
  background-color: var(--color-bg-tooltip);
13
- position: absolute;
14
- z-index: 3;
15
- left: 50%;
16
19
  max-width: var(--tooltip-max-width);
17
20
  padding: var(--spacer-1);
18
21
  color: var(--color-text-ontooltip);
@@ -26,6 +29,11 @@
26
29
  box-shadow: var(--elevation-300-tooltip);
27
30
  visibility: hidden;
28
31
 
32
+ &[data-wrap] {
33
+ white-space: normal;
34
+ overflow-wrap: break-word;
35
+ }
36
+
29
37
  &.field-error {
30
38
  background-color: var(--color-bg-danger);
31
39
  color: var(--color-text-ondanger);
@@ -51,11 +59,6 @@
51
59
  }
52
60
  }
53
61
 
54
- .tooltip--wrap {
55
- white-space: normal;
56
- overflow-wrap: break-word;
57
- }
58
-
59
62
  .tooltip__caret {
60
63
  position: absolute;
61
64
  pointer-events: none;
@@ -76,7 +79,6 @@
76
79
  .tooltip--show {
77
80
  visibility: visible;
78
81
  opacity: 1;
79
- transition: opacity 0.2s ease-in-out;
80
82
  cursor: default;
81
83
  }
82
84
 
@@ -94,13 +96,6 @@
94
96
  }
95
97
 
96
98
  .tooltip--position-top {
97
- top: 0;
98
- transform: translate3d(
99
- var(--tooltip-x),
100
- calc(-100% - var(--caret-height) - var(--caret-offset) + 1px),
101
- 0
102
- );
103
-
104
99
  .tooltip__caret {
105
100
  --color-border: var(--ramp-grey-700);
106
101
  top: calc(100% - 0.5px);
@@ -112,13 +107,6 @@
112
107
  }
113
108
 
114
109
  .tooltip--position-bottom {
115
- top: 100%;
116
- transform: translate3d(
117
- var(--tooltip-x),
118
- calc(var(--caret-height) + var(--caret-offset) - 1px),
119
- 0
120
- );
121
-
122
110
  .tooltip__caret {
123
111
  bottom: calc(100% - 0.5px);
124
112
  transform: rotate(180deg);
@@ -134,28 +122,21 @@
134
122
  }
135
123
 
136
124
  .tooltip--position-left {
137
- top: 50%;
138
- left: 0;
139
- transform: translate3d(calc(-100% - var(--caret-height) - var(--caret-offset)), -50%, 0);
140
-
141
125
  .tooltip__caret {
142
126
  top: calc(50% + 0.5px);
143
127
  left: calc(100% - 0.5px);
144
- transform: translateY(calc(1 * var(--caret-width) / 2)) rotate(-90deg);
128
+ transform: translateY(calc(1 * var(--caret-width) / 2 + var(--tooltip-caret-y)))
129
+ rotate(-90deg);
145
130
  transform-origin: top left;
146
131
  }
147
132
  }
148
133
 
149
134
  .tooltip--position-right {
150
- top: 50%;
151
- left: 100%;
152
- transform: translate3d(calc(var(--caret-height) + var(--caret-offset)), -50%, 0);
153
-
154
135
  .tooltip__caret {
155
136
  top: calc(50% + 0.5px);
156
137
  left: unset;
157
138
  right: calc(100% - 0.5px);
158
- transform: translateY(calc(1 * var(--caret-width) / 2)) rotate(90deg);
139
+ transform: translateY(calc(1 * var(--caret-width) / 2 + var(--tooltip-caret-y))) rotate(90deg);
159
140
  transform-origin: top right;
160
141
  }
161
142
  }
@@ -1,17 +1,25 @@
1
1
  import React from 'react';
2
2
  import './index.css';
3
+ type Side = 'bottom' | 'left' | 'right' | 'top';
3
4
  export type Props = {
4
5
  alignCaret?: 'center' | 'left' | 'right';
5
- boundingRef?: React.RefObject<HTMLElement | null>;
6
6
  children: React.ReactNode;
7
7
  className?: string;
8
8
  delay?: number;
9
- position?: 'bottom' | 'left' | 'right' | 'top';
9
+ /**
10
+ * Applied to the portaled tooltip element, so it can be located independent of its
11
+ * position in the DOM (e.g. by tests).
12
+ */
13
+ id?: string;
14
+ position?: Side;
10
15
  show?: boolean;
11
16
  /**
12
- * If the tooltip position should not change depending on if the toolbar is outside the boundingRef. @default false
17
+ * Disables adaptive placement: the tooltip always renders on `position` (or its
18
+ * default) instead of flipping to whichever side has room. It does not affect
19
+ * portaling - every tooltip is portaled to `document.body` regardless. @default false
13
20
  */
14
21
  staticPositioning?: boolean;
15
22
  };
16
23
  export declare const Tooltip: React.FC<Props>;
24
+ export {};
17
25
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/elements/Tooltip/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAA4D,MAAM,OAAO,CAAA;AAGhF,OAAO,aAAa,CAAA;AAwBpB,MAAM,MAAM,KAAK,GAAG;IAClB,UAAU,CAAC,EAAE,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAA;IACxC,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAA;IACjD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,CAAA;IAC9C,IAAI,CAAC,EAAE,OAAO,CAAA;IACd;;OAEG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAA;CAC5B,CAAA;AAsBD,eAAO,MAAM,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CAsJnC,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/elements/Tooltip/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAoE,MAAM,OAAO,CAAA;AAGxF,OAAO,aAAa,CAAA;AAOpB,KAAK,IAAI,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,CAAA;AAE/C,MAAM,MAAM,KAAK,GAAG;IAClB,UAAU,CAAC,EAAE,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAA;IACxC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;;;OAGG;IACH,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,QAAQ,CAAC,EAAE,IAAI,CAAA;IACf,IAAI,CAAC,EAAE,OAAO,CAAA;IACd;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAA;CAC5B,CAAA;AAwCD,eAAO,MAAM,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CAyOnC,CAAA"}
@@ -2,24 +2,13 @@
2
2
 
3
3
  import { c as _c } from "react/compiler-runtime";
4
4
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
5
- import React, { useCallback, useEffect, useLayoutEffect, useState } from 'react';
6
- import { useIntersect } from '../../hooks/useIntersect.js';
5
+ import { autoUpdate, computePosition, flip, hide, offset, shift, size } from '@floating-ui/dom';
6
+ import React, { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';
7
+ import { createPortal } from 'react-dom';
7
8
  import './index.css';
8
- // Breathing room (px) between a shifted tooltip and its clipping edge. Maps to `--spacer-1`.
9
9
  const EDGE_GUTTER = 4;
10
- const getClipBoundary = el => {
11
- let current = el?.parentElement || null;
12
- while (current) {
13
- const {
14
- overflowX
15
- } = window.getComputedStyle(current);
16
- if (overflowX === 'auto' || overflowX === 'clip' || overflowX === 'hidden' || overflowX === 'scroll') {
17
- return current.getBoundingClientRect();
18
- }
19
- current = current.parentElement;
20
- }
21
- return null;
22
- };
10
+ const TOP_BOTTOM_OFFSET = 10;
11
+ const LEFT_RIGHT_OFFSET = 11;
23
12
  const TooltipCaret = () => {
24
13
  const $ = _c(2);
25
14
  const clipId = React.useId();
@@ -55,10 +44,24 @@ const TooltipCaret = () => {
55
44
  }
56
45
  return t0;
57
46
  };
47
+ const isTriggerHidden = element => {
48
+ if (typeof element.checkVisibility === 'function') {
49
+ return !element.checkVisibility();
50
+ }
51
+ // Fallback for browsers without `checkVisibility`: an element collapsed by a
52
+ // `display: none` ancestor has no client rects.
53
+ return element.getClientRects().length === 0;
54
+ };
55
+ const toPlacement = (side, alignCaret) => {
56
+ if (side === 'left' || side === 'right' || alignCaret === 'center') {
57
+ return side;
58
+ }
59
+ return `${side}-${alignCaret === 'left' ? 'start' : 'end'}`;
60
+ };
58
61
  export const Tooltip = props => {
59
62
  const {
63
+ id,
60
64
  alignCaret = 'center',
61
- boundingRef,
62
65
  children,
63
66
  className,
64
67
  delay = 500,
@@ -66,15 +69,16 @@ export const Tooltip = props => {
66
69
  show: showFromProps = true,
67
70
  staticPositioning = false
68
71
  } = props;
69
- const [show, setShow] = React.useState(showFromProps);
70
- const [position, setPosition] = React.useState('top');
71
- const [shiftX, setShiftX] = useState(0);
72
- const [maxWidth, setMaxWidth] = useState(null);
73
- const [ref, intersectionEntry, node] = useIntersect({
74
- root: boundingRef?.current || null,
75
- rootMargin: '-145px 0px 0px 100px',
76
- threshold: 0
77
- }, staticPositioning);
72
+ const generatedID = React.useId();
73
+ const tooltipID = id || generatedID;
74
+ const [show, setShow] = useState(showFromProps);
75
+ const [isMounted, setIsMounted] = useState(false);
76
+ const [placement, setPlacement] = useState(positionFromProps || 'top');
77
+ // A hidden marker rendered where the tooltip used to live in the DOM, so its
78
+ // parent element can be used as the floating-ui reference for the portaled tooltip.
79
+ const triggerMarkerRef = useRef(null);
80
+ const floatingRef = useRef(null);
81
+ const updateTokenRef = useRef(0);
78
82
  useEffect(() => {
79
83
  let timerID;
80
84
  // do not use the delay on transition-out
@@ -91,83 +95,145 @@ export const Tooltip = props => {
91
95
  }
92
96
  };
93
97
  }, [showFromProps, delay]);
98
+ // Keep the tooltip mounted for the duration of its fade-out transition so the
99
+ // portal doesn't disappear abruptly when `show` flips back to false.
94
100
  useEffect(() => {
95
- if (staticPositioning) {
101
+ if (show) {
102
+ setIsMounted(true);
96
103
  return;
97
104
  }
98
- setPosition(intersectionEntry?.isIntersecting ? 'top' : 'bottom');
99
- }, [intersectionEntry, staticPositioning]);
100
- // Keep a horizontally-centered tooltip (top/bottom) inside its boundary by
101
- // shifting it inward by exactly the amount it would overflow. The hidden
102
- // measuring aside (`node`) provides the natural, unshifted geometry.
103
- const computeShift = useCallback(() => {
104
- const usesHorizontalCenter = (positionFromProps || position) === 'top' || (positionFromProps || position) === 'bottom';
105
- if (staticPositioning || !node || !usesHorizontalCenter) {
106
- setShiftX(0);
107
- setMaxWidth(null);
105
+ // Matches the `.tooltip--show` opacity transition duration.
106
+ const timeoutID = setTimeout(() => setIsMounted(false), 200);
107
+ return () => {
108
+ clearTimeout(timeoutID);
109
+ };
110
+ }, [show]);
111
+ const updatePosition = useCallback(async () => {
112
+ const trigger = triggerMarkerRef.current?.parentElement;
113
+ const floatingElement = floatingRef.current;
114
+ if (!trigger || !floatingElement) {
108
115
  return;
109
116
  }
110
- const rect = node.getBoundingClientRect();
111
- const boundary = boundingRef?.current?.getBoundingClientRect() ?? getClipBoundary(node) ?? undefined;
112
- const leftEdge = (boundary?.left ?? 0) + EDGE_GUTTER;
113
- const rightEdge = (boundary?.right ?? window.innerWidth) - EDGE_GUTTER;
114
- const available = rightEdge - leftEdge;
115
- // When the tooltip can't fit even at full boundary width, cap it so it wraps.
116
- const nextMaxWidth = rect.width > available ? available : null;
117
- setMaxWidth(nextMaxWidth);
118
- // Compute the shift against the clamped box, kept centered on the anchor.
119
- const center = rect.left + rect.width / 2;
120
- const effectiveWidth = nextMaxWidth ?? rect.width;
121
- const effectiveLeft = center - effectiveWidth / 2;
122
- const effectiveRight = center + effectiveWidth / 2;
123
- let shift = 0;
124
- if (effectiveRight > rightEdge) {
125
- shift = rightEdge - effectiveRight;
126
- }
127
- if (effectiveLeft + shift < leftEdge) {
128
- shift = leftEdge - effectiveLeft;
117
+ const token = ++updateTokenRef.current;
118
+ const boundary = 'clippingAncestors';
119
+ const canFlip = !staticPositioning && !positionFromProps;
120
+ const {
121
+ middlewareData,
122
+ placement: resolvedPlacement,
123
+ x,
124
+ y
125
+ } = await computePosition(trigger, floatingElement, {
126
+ middleware: [offset(({
127
+ placement: currentPlacement
128
+ }) => currentPlacement.startsWith('left') || currentPlacement.startsWith('right') ? LEFT_RIGHT_OFFSET : TOP_BOTTOM_OFFSET), ...(canFlip ? [flip({
129
+ boundary,
130
+ padding: EDGE_GUTTER
131
+ })] : []), ...(staticPositioning ? [] : [shift({
132
+ boundary,
133
+ padding: EDGE_GUTTER
134
+ }), size({
135
+ apply({
136
+ availableWidth,
137
+ elements
138
+ }) {
139
+ const shouldWrap = elements.floating.scrollWidth > availableWidth;
140
+ elements.floating.toggleAttribute('data-wrap', shouldWrap);
141
+ elements.floating.style.setProperty('--tooltip-max-width', shouldWrap ? `${Math.floor(availableWidth)}px` : '');
142
+ },
143
+ boundary,
144
+ padding: EDGE_GUTTER
145
+ })]), hide({
146
+ boundary: 'clippingAncestors'
147
+ })],
148
+ placement: toPlacement(positionFromProps || 'top', alignCaret),
149
+ strategy: 'fixed'
150
+ });
151
+ // A newer call already applied a fresher position - discard this stale result.
152
+ if (token !== updateTokenRef.current) {
153
+ return;
129
154
  }
130
- setShiftX(shift);
131
- }, [boundingRef, node, position, positionFromProps, staticPositioning]);
155
+ const hidden = isTriggerHidden(trigger) || Boolean(middlewareData.hide?.referenceHidden);
156
+ Object.assign(floatingElement.style, {
157
+ left: `${x}px`,
158
+ top: `${y}px`,
159
+ visibility: hidden ? 'hidden' : ''
160
+ });
161
+ const resolvedSide = resolvedPlacement.split('-')[0];
162
+ const isHorizontalSide = resolvedSide === 'left' || resolvedSide === 'right';
163
+ const shiftX = !isHorizontalSide && alignCaret === 'center' ? middlewareData.shift?.x || 0 : 0;
164
+ const shiftY = isHorizontalSide ? middlewareData.shift?.y || 0 : 0;
165
+ floatingElement.style.setProperty('--tooltip-caret-x', shiftX ? `${-shiftX}px` : '0px');
166
+ floatingElement.style.setProperty('--tooltip-caret-y', shiftY ? `${-shiftY}px` : '0px');
167
+ setPlacement(resolvedSide);
168
+ }, [alignCaret, positionFromProps, staticPositioning]);
169
+ const setFloatingElement = useCallback(element => {
170
+ floatingRef.current = element;
171
+ void updatePosition();
172
+ }, [updatePosition]);
173
+ // While mounted, let floating-ui keep the portaled tooltip aligned to its trigger
174
+ // as the page scrolls, the trigger resizes or moves, or a hidden ancestor becomes
175
+ // visible again - instead of manually re-measuring on window scroll/resize alone.
132
176
  useLayoutEffect(() => {
133
- if (!show) {
177
+ const trigger_0 = triggerMarkerRef.current?.parentElement;
178
+ const floatingElement_0 = floatingRef.current;
179
+ if (!isMounted || !trigger_0 || !floatingElement_0) {
134
180
  return;
135
181
  }
136
- computeShift();
137
- window.addEventListener('resize', computeShift);
182
+ const cleanupAutoUpdate = autoUpdate(trigger_0, floatingElement_0, updatePosition, {
183
+ elementResize: 'ResizeObserver' in window
184
+ });
185
+ // autoUpdate's own layout-shift tracking gives up once the trigger's rect
186
+ // collapses to zero (e.g. behind a `display: none` ancestor), so it can't
187
+ // tell when the trigger becomes visible again. Watch for that separately.
188
+ const visibilityObserver = typeof IntersectionObserver === 'function' ? new IntersectionObserver(() => void updatePosition(), {
189
+ threshold: 0
190
+ }) : null;
191
+ visibilityObserver?.observe(trigger_0);
192
+ const visualViewport = window.visualViewport;
193
+ visualViewport?.addEventListener('resize', updatePosition);
194
+ visualViewport?.addEventListener('scroll', updatePosition);
195
+ return () => {
196
+ cleanupAutoUpdate();
197
+ visibilityObserver?.disconnect();
198
+ visualViewport?.removeEventListener('resize', updatePosition);
199
+ visualViewport?.removeEventListener('scroll', updatePosition);
200
+ };
201
+ }, [isMounted, updatePosition]);
202
+ useEffect(() => {
203
+ const trigger_1 = triggerMarkerRef.current?.parentElement;
204
+ if (!show || !trigger_1) {
205
+ return;
206
+ }
207
+ const describedByIDs = trigger_1.getAttribute('aria-describedby')?.split(' ') || [];
208
+ if (!describedByIDs.includes(tooltipID)) {
209
+ trigger_1.setAttribute('aria-describedby', [...describedByIDs, tooltipID].join(' '));
210
+ }
138
211
  return () => {
139
- window.removeEventListener('resize', computeShift);
212
+ const remainingIDs = (trigger_1.getAttribute('aria-describedby')?.split(' ') || []).filter(describedByID => describedByID !== tooltipID);
213
+ if (remainingIDs.length) {
214
+ trigger_1.setAttribute('aria-describedby', remainingIDs.join(' '));
215
+ } else {
216
+ trigger_1.removeAttribute('aria-describedby');
217
+ }
140
218
  };
141
- }, [show, computeShift]);
142
- // The first aside is always on top. The purpose of that is that it can reliably be used for the interaction observer (as it's not moving around), to calculate the position of the actual tooltip.
219
+ }, [show, tooltipID]);
143
220
  return /*#__PURE__*/_jsxs(React.Fragment, {
144
- children: [!staticPositioning && /*#__PURE__*/_jsxs("aside", {
221
+ children: [/*#__PURE__*/_jsx("span", {
145
222
  "aria-hidden": "true",
146
- className: ['tooltip', className, `tooltip--caret-${alignCaret}`, 'tooltip--position-top'].filter(Boolean).join(' '),
147
- ref: ref,
223
+ ref: triggerMarkerRef,
148
224
  style: {
149
- opacity: '0'
150
- },
151
- children: [/*#__PURE__*/_jsx(TooltipCaret, {}), /*#__PURE__*/_jsx("div", {
152
- className: "tooltip-content",
153
- children: children
154
- })]
155
- }), /*#__PURE__*/_jsxs("aside", {
156
- className: ['tooltip', className, show && 'tooltip--show', maxWidth && 'tooltip--wrap', `tooltip--caret-${alignCaret}`, `tooltip--position-${positionFromProps || position}`].filter(Boolean).join(' '),
157
- style: {
158
- ...(maxWidth ? {
159
- '--tooltip-max-width': `${maxWidth}px`
160
- } : {}),
161
- ...(shiftX ? {
162
- '--tooltip-caret-x': `${-shiftX}px`,
163
- '--tooltip-x': `calc(-50% + ${shiftX}px)`
164
- } : {})
165
- },
225
+ display: 'none'
226
+ }
227
+ }), isMounted && /*#__PURE__*/createPortal(/*#__PURE__*/_jsxs("aside", {
228
+ className: ['tooltip', className, show && 'tooltip--show', `tooltip--caret-${alignCaret}`, `tooltip--position-${placement}`].filter(Boolean).join(' '),
229
+ id: tooltipID,
230
+ ref: setFloatingElement,
231
+ role: "tooltip",
166
232
  children: [/*#__PURE__*/_jsx(TooltipCaret, {}), /*#__PURE__*/_jsx("div", {
167
233
  className: "tooltip-content",
168
234
  children: children
169
235
  })]
170
- })]
236
+ }), document.body)]
171
237
  });
172
238
  };
173
239
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["c","_c","React","useCallback","useEffect","useLayoutEffect","useState","useIntersect","EDGE_GUTTER","getClipBoundary","el","current","parentElement","overflowX","window","getComputedStyle","getBoundingClientRect","TooltipCaret","$","clipId","useId","t0","_jsxs","className","height","viewBox","width","children","_jsx","id","x","y","clipPath","d","Tooltip","props","alignCaret","boundingRef","delay","position","positionFromProps","show","showFromProps","staticPositioning","setShow","setPosition","shiftX","setShiftX","maxWidth","setMaxWidth","ref","intersectionEntry","node","root","rootMargin","threshold","timerID","setTimeout","clearTimeout","isIntersecting","computeShift","usesHorizontalCenter","rect","boundary","undefined","leftEdge","left","rightEdge","right","innerWidth","available","nextMaxWidth","center","effectiveWidth","effectiveLeft","effectiveRight","shift","addEventListener","removeEventListener","Fragment","filter","Boolean","join","style","opacity"],"sources":["../../../src/elements/Tooltip/index.tsx"],"sourcesContent":["'use client'\nimport React, { useCallback, useEffect, useLayoutEffect, useState } from 'react'\n\nimport { useIntersect } from '../../hooks/useIntersect.js'\nimport './index.css'\n\n// Breathing room (px) between a shifted tooltip and its clipping edge. Maps to `--spacer-1`.\nconst EDGE_GUTTER = 4\n\nconst getClipBoundary = (el: HTMLElement | null): DOMRect | null => {\n let current = el?.parentElement || null\n\n while (current) {\n const { overflowX } = window.getComputedStyle(current)\n if (\n overflowX === 'auto' ||\n overflowX === 'clip' ||\n overflowX === 'hidden' ||\n overflowX === 'scroll'\n ) {\n return current.getBoundingClientRect()\n }\n current = current.parentElement\n }\n\n return null\n}\n\nexport type Props = {\n alignCaret?: 'center' | 'left' | 'right'\n boundingRef?: React.RefObject<HTMLElement | null>\n children: React.ReactNode\n className?: string\n delay?: number\n position?: 'bottom' | 'left' | 'right' | 'top'\n show?: boolean\n /**\n * If the tooltip position should not change depending on if the toolbar is outside the boundingRef. @default false\n */\n staticPositioning?: boolean\n}\n\nconst TooltipCaret: React.FC = () => {\n const clipId = React.useId()\n\n return (\n <svg aria-hidden=\"true\" className=\"tooltip__caret\" height=\"14\" viewBox=\"0 0 14 14\" width=\"15\">\n <clipPath id={clipId}>\n <rect height=\"14\" width=\"15\" x=\"-0.5\" y=\"0.5\" />\n </clipPath>\n {/* Border stroke - clipped to hide top edge */}\n <path\n className=\"tooltip__caret-stroke\"\n clipPath={`url(#${clipId})`}\n d=\"M0,0 H14 L7.875,6.125 Q7,7 6.125,6.125 Z\"\n />\n {/* Fill path */}\n <path className=\"tooltip__caret-fill\" d=\"M0,0 H14 L7.875,6.125 Q7,7 6.125,6.125 Z\" />\n </svg>\n )\n}\n\nexport const Tooltip: React.FC<Props> = (props) => {\n const {\n alignCaret = 'center',\n boundingRef,\n children,\n className,\n delay = 500,\n position: positionFromProps,\n show: showFromProps = true,\n staticPositioning = false,\n } = props\n\n const [show, setShow] = React.useState(showFromProps)\n const [position, setPosition] = React.useState<'bottom' | 'left' | 'right' | 'top'>('top')\n const [shiftX, setShiftX] = useState(0)\n const [maxWidth, setMaxWidth] = useState<null | number>(null)\n\n const [ref, intersectionEntry, node] = useIntersect(\n {\n root: boundingRef?.current || null,\n rootMargin: '-145px 0px 0px 100px',\n threshold: 0,\n },\n staticPositioning,\n )\n\n useEffect(() => {\n let timerID: NodeJS.Timeout\n\n // do not use the delay on transition-out\n if (delay && showFromProps) {\n timerID = setTimeout(() => {\n setShow(showFromProps)\n }, delay)\n } else {\n setShow(showFromProps)\n }\n\n return () => {\n if (timerID) {\n clearTimeout(timerID)\n }\n }\n }, [showFromProps, delay])\n\n useEffect(() => {\n if (staticPositioning) {\n return\n }\n setPosition(intersectionEntry?.isIntersecting ? 'top' : 'bottom')\n }, [intersectionEntry, staticPositioning])\n\n // Keep a horizontally-centered tooltip (top/bottom) inside its boundary by\n // shifting it inward by exactly the amount it would overflow. The hidden\n // measuring aside (`node`) provides the natural, unshifted geometry.\n const computeShift = useCallback(() => {\n const usesHorizontalCenter =\n (positionFromProps || position) === 'top' || (positionFromProps || position) === 'bottom'\n\n if (staticPositioning || !node || !usesHorizontalCenter) {\n setShiftX(0)\n setMaxWidth(null)\n return\n }\n\n const rect = node.getBoundingClientRect()\n const boundary =\n boundingRef?.current?.getBoundingClientRect() ?? getClipBoundary(node) ?? undefined\n const leftEdge = (boundary?.left ?? 0) + EDGE_GUTTER\n const rightEdge = (boundary?.right ?? window.innerWidth) - EDGE_GUTTER\n const available = rightEdge - leftEdge\n\n // When the tooltip can't fit even at full boundary width, cap it so it wraps.\n const nextMaxWidth = rect.width > available ? available : null\n setMaxWidth(nextMaxWidth)\n\n // Compute the shift against the clamped box, kept centered on the anchor.\n const center = rect.left + rect.width / 2\n const effectiveWidth = nextMaxWidth ?? rect.width\n const effectiveLeft = center - effectiveWidth / 2\n const effectiveRight = center + effectiveWidth / 2\n\n let shift = 0\n if (effectiveRight > rightEdge) {\n shift = rightEdge - effectiveRight\n }\n if (effectiveLeft + shift < leftEdge) {\n shift = leftEdge - effectiveLeft\n }\n\n setShiftX(shift)\n }, [boundingRef, node, position, positionFromProps, staticPositioning])\n\n useLayoutEffect(() => {\n if (!show) {\n return\n }\n\n computeShift()\n window.addEventListener('resize', computeShift)\n\n return () => {\n window.removeEventListener('resize', computeShift)\n }\n }, [show, computeShift])\n\n // The first aside is always on top. The purpose of that is that it can reliably be used for the interaction observer (as it's not moving around), to calculate the position of the actual tooltip.\n return (\n <React.Fragment>\n {!staticPositioning && (\n <aside\n aria-hidden=\"true\"\n className={['tooltip', className, `tooltip--caret-${alignCaret}`, 'tooltip--position-top']\n .filter(Boolean)\n .join(' ')}\n ref={ref}\n style={{ opacity: '0' }}\n >\n <TooltipCaret />\n <div className=\"tooltip-content\">{children}</div>\n </aside>\n )}\n <aside\n className={[\n 'tooltip',\n className,\n show && 'tooltip--show',\n maxWidth && 'tooltip--wrap',\n `tooltip--caret-${alignCaret}`,\n `tooltip--position-${positionFromProps || position}`,\n ]\n .filter(Boolean)\n .join(' ')}\n style={\n {\n ...(maxWidth ? { '--tooltip-max-width': `${maxWidth}px` } : {}),\n ...(shiftX\n ? {\n '--tooltip-caret-x': `${-shiftX}px`,\n '--tooltip-x': `calc(-50% + ${shiftX}px)`,\n }\n : {}),\n } as React.CSSProperties\n }\n >\n <TooltipCaret />\n <div className=\"tooltip-content\">{children}</div>\n </aside>\n </React.Fragment>\n )\n}\n"],"mappings":"AAAA;;AAAA,SAAAA,CAAA,IAAAC,EAAA;;AACA,OAAOC,KAAA,IAASC,WAAW,EAAEC,SAAS,EAAEC,eAAe,EAAEC,QAAQ,QAAQ;AAEzE,SAASC,YAAY,QAAQ;AAC7B,OAAO;AAEP;AACA,MAAMC,WAAA,GAAc;AAEpB,MAAMC,eAAA,GAAmBC,EAAA;EACvB,IAAIC,OAAA,GAAUD,EAAA,EAAIE,aAAA,IAAiB;EAEnC,OAAOD,OAAA,EAAS;IACd,MAAM;MAAEE;IAAS,CAAE,GAAGC,MAAA,CAAOC,gBAAgB,CAACJ,OAAA;IAC9C,IACEE,SAAA,KAAc,UACdA,SAAA,KAAc,UACdA,SAAA,KAAc,YACdA,SAAA,KAAc,UACd;MACA,OAAOF,OAAA,CAAQK,qBAAqB;IACtC;IACAL,OAAA,GAAUA,OAAA,CAAQC,aAAa;EACjC;EAEA,OAAO;AACT;AAgBA,MAAMK,YAAA,GAAyBA,CAAA;EAAA,MAAAC,CAAA,GAAAjB,EAAA;EAC7B,MAAAkB,MAAA,GAAejB,KAAA,CAAAkB,KAAA,CAAW;EAAA,IAAAC,EAAA;EAAA,IAAAH,CAAA,QAAAC,MAAA;IAGxBE,EAAA,GAAAC,KAAA,CAAC;MAAA,eAAgB;MAAAC,SAAA,EAAiB;MAAAC,MAAA,EAAwB;MAAAC,OAAA,EAAa;MAAAC,KAAA,EAAkB;MAAAC,QAAA,GACvFC,IAAA,CAAC;QAAAC,EAAA,EAAaV,MAAA;QAAAQ,QAAA,EACZC,IAAA,CAAC;UAAAJ,MAAA,EAAY;UAAAE,KAAA,EAAW;UAAAI,CAAA,EAAO;UAAAC,CAAA,EAAS;QAAA,C;UAG1CH,IAAA,CAAC;QAAAL,SAAA,EACW;QAAAS,QAAA,EACA,QAAQb,MAAA,GAAS;QAAAc,CAAA,EACzB;MAAA,C,GAGJL,IAAA,CAAC;QAAAL,SAAA,EAAe;QAAAU,CAAA,EAAwB;MAAA,C;;;;;;;SAX1CZ,E;CAcJ;AAEA,OAAO,MAAMa,OAAA,GAA4BC,KAAA;EACvC,MAAM;IACJC,UAAA,GAAa,QAAQ;IACrBC,WAAW;IACXV,QAAQ;IACRJ,SAAS;IACTe,KAAA,GAAQ,GAAG;IACXC,QAAA,EAAUC,iBAAiB;IAC3BC,IAAA,EAAMC,aAAA,GAAgB,IAAI;IAC1BC,iBAAA,GAAoB;EAAK,CAC1B,GAAGR,KAAA;EAEJ,MAAM,CAACM,IAAA,EAAMG,OAAA,CAAQ,GAAG1C,KAAA,CAAMI,QAAQ,CAACoC,aAAA;EACvC,MAAM,CAACH,QAAA,EAAUM,WAAA,CAAY,GAAG3C,KAAA,CAAMI,QAAQ,CAAsC;EACpF,MAAM,CAACwC,MAAA,EAAQC,SAAA,CAAU,GAAGzC,QAAA,CAAS;EACrC,MAAM,CAAC0C,QAAA,EAAUC,WAAA,CAAY,GAAG3C,QAAA,CAAwB;EAExD,MAAM,CAAC4C,GAAA,EAAKC,iBAAA,EAAmBC,IAAA,CAAK,GAAG7C,YAAA,CACrC;IACE8C,IAAA,EAAMhB,WAAA,EAAa1B,OAAA,IAAW;IAC9B2C,UAAA,EAAY;IACZC,SAAA,EAAW;EACb,GACAZ,iBAAA;EAGFvC,SAAA,CAAU;IACR,IAAIoD,OAAA;IAEJ;IACA,IAAIlB,KAAA,IAASI,aAAA,EAAe;MAC1Bc,OAAA,GAAUC,UAAA,CAAW;QACnBb,OAAA,CAAQF,aAAA;MACV,GAAGJ,KAAA;IACL,OAAO;MACLM,OAAA,CAAQF,aAAA;IACV;IAEA,OAAO;MACL,IAAIc,OAAA,EAAS;QACXE,YAAA,CAAaF,OAAA;MACf;IACF;EACF,GAAG,CAACd,aAAA,EAAeJ,KAAA,CAAM;EAEzBlC,SAAA,CAAU;IACR,IAAIuC,iBAAA,EAAmB;MACrB;IACF;IACAE,WAAA,CAAYM,iBAAA,EAAmBQ,cAAA,GAAiB,QAAQ;EAC1D,GAAG,CAACR,iBAAA,EAAmBR,iBAAA,CAAkB;EAEzC;EACA;EACA;EACA,MAAMiB,YAAA,GAAezD,WAAA,CAAY;IAC/B,MAAM0D,oBAAA,GACJ,CAACrB,iBAAA,IAAqBD,QAAO,MAAO,SAAS,CAACC,iBAAA,IAAqBD,QAAO,MAAO;IAEnF,IAAII,iBAAA,IAAqB,CAACS,IAAA,IAAQ,CAACS,oBAAA,EAAsB;MACvDd,SAAA,CAAU;MACVE,WAAA,CAAY;MACZ;IACF;IAEA,MAAMa,IAAA,GAAOV,IAAA,CAAKpC,qBAAqB;IACvC,MAAM+C,QAAA,GACJ1B,WAAA,EAAa1B,OAAA,EAASK,qBAAA,MAA2BP,eAAA,CAAgB2C,IAAA,KAASY,SAAA;IAC5E,MAAMC,QAAA,GAAW,CAACF,QAAA,EAAUG,IAAA,IAAQ,KAAK1D,WAAA;IACzC,MAAM2D,SAAA,GAAY,CAACJ,QAAA,EAAUK,KAAA,IAAStD,MAAA,CAAOuD,UAAU,IAAI7D,WAAA;IAC3D,MAAM8D,SAAA,GAAYH,SAAA,GAAYF,QAAA;IAE9B;IACA,MAAMM,YAAA,GAAeT,IAAA,CAAKpC,KAAK,GAAG4C,SAAA,GAAYA,SAAA,GAAY;IAC1DrB,WAAA,CAAYsB,YAAA;IAEZ;IACA,MAAMC,MAAA,GAASV,IAAA,CAAKI,IAAI,GAAGJ,IAAA,CAAKpC,KAAK,GAAG;IACxC,MAAM+C,cAAA,GAAiBF,YAAA,IAAgBT,IAAA,CAAKpC,KAAK;IACjD,MAAMgD,aAAA,GAAgBF,MAAA,GAASC,cAAA,GAAiB;IAChD,MAAME,cAAA,GAAiBH,MAAA,GAASC,cAAA,GAAiB;IAEjD,IAAIG,KAAA,GAAQ;IACZ,IAAID,cAAA,GAAiBR,SAAA,EAAW;MAC9BS,KAAA,GAAQT,SAAA,GAAYQ,cAAA;IACtB;IACA,IAAID,aAAA,GAAgBE,KAAA,GAAQX,QAAA,EAAU;MACpCW,KAAA,GAAQX,QAAA,GAAWS,aAAA;IACrB;IAEA3B,SAAA,CAAU6B,KAAA;EACZ,GAAG,CAACvC,WAAA,EAAae,IAAA,EAAMb,QAAA,EAAUC,iBAAA,EAAmBG,iBAAA,CAAkB;EAEtEtC,eAAA,CAAgB;IACd,IAAI,CAACoC,IAAA,EAAM;MACT;IACF;IAEAmB,YAAA;IACA9C,MAAA,CAAO+D,gBAAgB,CAAC,UAAUjB,YAAA;IAElC,OAAO;MACL9C,MAAA,CAAOgE,mBAAmB,CAAC,UAAUlB,YAAA;IACvC;EACF,GAAG,CAACnB,IAAA,EAAMmB,YAAA,CAAa;EAEvB;EACA,oBACEtC,KAAA,CAACpB,KAAA,CAAM6E,QAAQ;eACZ,CAACpC,iBAAA,iBACArB,KAAA,CAAC;MACC,eAAY;MACZC,SAAA,EAAW,CAAC,WAAWA,SAAA,EAAW,kBAAkBa,UAAA,EAAY,EAAE,wBAAwB,CACvF4C,MAAM,CAACC,OAAA,EACPC,IAAI,CAAC;MACRhC,GAAA,EAAKA,GAAA;MACLiC,KAAA,EAAO;QAAEC,OAAA,EAAS;MAAI;8BAEtBxD,IAAA,CAACX,YAAA,O,aACDW,IAAA,CAAC;QAAIL,SAAA,EAAU;kBAAmBI;;qBAGtCL,KAAA,CAAC;MACCC,SAAA,EAAW,CACT,WACAA,SAAA,EACAkB,IAAA,IAAQ,iBACRO,QAAA,IAAY,iBACZ,kBAAkBZ,UAAA,EAAY,EAC9B,qBAAqBI,iBAAA,IAAqBD,QAAA,EAAU,CACrD,CACEyC,MAAM,CAACC,OAAA,EACPC,IAAI,CAAC;MACRC,KAAA,EACE;QACE,IAAInC,QAAA,GAAW;UAAE,uBAAuB,GAAGA,QAAA;QAAa,IAAI,CAAC,CAAC;QAC9D,IAAIF,MAAA,GACA;UACE,qBAAqB,GAAG,CAACA,MAAA,IAAU;UACnC,eAAe,eAAeA,MAAA;QAChC,IACA,CAAC,CAAC;MACR;8BAGFlB,IAAA,CAACX,YAAA,O,aACDW,IAAA,CAAC;QAAIL,SAAA,EAAU;kBAAmBI;;;;AAI1C","ignoreList":[]}
1
+ {"version":3,"file":"index.js","names":["c","_c","autoUpdate","computePosition","flip","hide","offset","shift","size","React","useCallback","useEffect","useLayoutEffect","useRef","useState","createPortal","EDGE_GUTTER","TOP_BOTTOM_OFFSET","LEFT_RIGHT_OFFSET","TooltipCaret","$","clipId","useId","t0","_jsxs","className","height","viewBox","width","children","_jsx","id","x","y","clipPath","d","isTriggerHidden","element","checkVisibility","getClientRects","length","toPlacement","side","alignCaret","Tooltip","props","delay","position","positionFromProps","show","showFromProps","staticPositioning","generatedID","tooltipID","setShow","isMounted","setIsMounted","placement","setPlacement","triggerMarkerRef","floatingRef","updateTokenRef","timerID","setTimeout","clearTimeout","timeoutID","updatePosition","trigger","current","parentElement","floatingElement","token","boundary","canFlip","middlewareData","resolvedPlacement","middleware","currentPlacement","startsWith","padding","apply","availableWidth","elements","shouldWrap","floating","scrollWidth","toggleAttribute","style","setProperty","Math","floor","strategy","hidden","Boolean","referenceHidden","Object","assign","left","top","visibility","resolvedSide","split","isHorizontalSide","shiftX","shiftY","setFloatingElement","cleanupAutoUpdate","elementResize","window","visibilityObserver","IntersectionObserver","threshold","observe","visualViewport","addEventListener","disconnect","removeEventListener","describedByIDs","getAttribute","includes","setAttribute","join","remainingIDs","filter","describedByID","removeAttribute","Fragment","ref","display","role","document","body"],"sources":["../../../src/elements/Tooltip/index.tsx"],"sourcesContent":["'use client'\nimport { autoUpdate, computePosition, flip, hide, offset, shift, size } from '@floating-ui/dom'\nimport React, { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react'\nimport { createPortal } from 'react-dom'\n\nimport './index.css'\n\nconst EDGE_GUTTER = 4\n\nconst TOP_BOTTOM_OFFSET = 10\nconst LEFT_RIGHT_OFFSET = 11\n\ntype Side = 'bottom' | 'left' | 'right' | 'top'\n\nexport type Props = {\n alignCaret?: 'center' | 'left' | 'right'\n children: React.ReactNode\n className?: string\n delay?: number\n /**\n * Applied to the portaled tooltip element, so it can be located independent of its\n * position in the DOM (e.g. by tests).\n */\n id?: string\n position?: Side\n show?: boolean\n /**\n * Disables adaptive placement: the tooltip always renders on `position` (or its\n * default) instead of flipping to whichever side has room. It does not affect\n * portaling - every tooltip is portaled to `document.body` regardless. @default false\n */\n staticPositioning?: boolean\n}\n\nconst TooltipCaret: React.FC = () => {\n const clipId = React.useId()\n\n return (\n <svg aria-hidden=\"true\" className=\"tooltip__caret\" height=\"14\" viewBox=\"0 0 14 14\" width=\"15\">\n <clipPath id={clipId}>\n <rect height=\"14\" width=\"15\" x=\"-0.5\" y=\"0.5\" />\n </clipPath>\n {/* Border stroke - clipped to hide top edge */}\n <path\n className=\"tooltip__caret-stroke\"\n clipPath={`url(#${clipId})`}\n d=\"M0,0 H14 L7.875,6.125 Q7,7 6.125,6.125 Z\"\n />\n {/* Fill path */}\n <path className=\"tooltip__caret-fill\" d=\"M0,0 H14 L7.875,6.125 Q7,7 6.125,6.125 Z\" />\n </svg>\n )\n}\n\nconst isTriggerHidden = (element: Element): boolean => {\n if (typeof element.checkVisibility === 'function') {\n return !element.checkVisibility()\n }\n\n // Fallback for browsers without `checkVisibility`: an element collapsed by a\n // `display: none` ancestor has no client rects.\n return element.getClientRects().length === 0\n}\n\nconst toPlacement = (side: Side, alignCaret: 'center' | 'left' | 'right') => {\n if (side === 'left' || side === 'right' || alignCaret === 'center') {\n return side\n }\n\n return `${side}-${alignCaret === 'left' ? 'start' : 'end'}` as const\n}\n\nexport const Tooltip: React.FC<Props> = (props) => {\n const {\n id,\n alignCaret = 'center',\n children,\n className,\n delay = 500,\n position: positionFromProps,\n show: showFromProps = true,\n staticPositioning = false,\n } = props\n\n const generatedID = React.useId()\n const tooltipID = id || generatedID\n\n const [show, setShow] = useState(showFromProps)\n const [isMounted, setIsMounted] = useState(false)\n const [placement, setPlacement] = useState<Side>(positionFromProps || 'top')\n\n // A hidden marker rendered where the tooltip used to live in the DOM, so its\n // parent element can be used as the floating-ui reference for the portaled tooltip.\n const triggerMarkerRef = useRef<HTMLSpanElement>(null)\n const floatingRef = useRef<HTMLDivElement | null>(null)\n\n const updateTokenRef = useRef(0)\n\n useEffect(() => {\n let timerID: NodeJS.Timeout\n\n // do not use the delay on transition-out\n if (delay && showFromProps) {\n timerID = setTimeout(() => {\n setShow(showFromProps)\n }, delay)\n } else {\n setShow(showFromProps)\n }\n\n return () => {\n if (timerID) {\n clearTimeout(timerID)\n }\n }\n }, [showFromProps, delay])\n\n // Keep the tooltip mounted for the duration of its fade-out transition so the\n // portal doesn't disappear abruptly when `show` flips back to false.\n useEffect(() => {\n if (show) {\n setIsMounted(true)\n return\n }\n\n // Matches the `.tooltip--show` opacity transition duration.\n const timeoutID = setTimeout(() => setIsMounted(false), 200)\n\n return () => {\n clearTimeout(timeoutID)\n }\n }, [show])\n\n const updatePosition = useCallback(async () => {\n const trigger = triggerMarkerRef.current?.parentElement\n const floatingElement = floatingRef.current\n\n if (!trigger || !floatingElement) {\n return\n }\n\n const token = ++updateTokenRef.current\n const boundary = 'clippingAncestors'\n const canFlip = !staticPositioning && !positionFromProps\n\n const {\n middlewareData,\n placement: resolvedPlacement,\n x,\n y,\n } = await computePosition(trigger, floatingElement, {\n middleware: [\n offset(({ placement: currentPlacement }) =>\n currentPlacement.startsWith('left') || currentPlacement.startsWith('right')\n ? LEFT_RIGHT_OFFSET\n : TOP_BOTTOM_OFFSET,\n ),\n ...(canFlip ? [flip({ boundary, padding: EDGE_GUTTER })] : []),\n ...(staticPositioning\n ? []\n : [\n shift({ boundary, padding: EDGE_GUTTER }),\n size({\n apply({ availableWidth, elements }) {\n const shouldWrap = elements.floating.scrollWidth > availableWidth\n\n elements.floating.toggleAttribute('data-wrap', shouldWrap)\n elements.floating.style.setProperty(\n '--tooltip-max-width',\n shouldWrap ? `${Math.floor(availableWidth)}px` : '',\n )\n },\n boundary,\n padding: EDGE_GUTTER,\n }),\n ]),\n hide({ boundary: 'clippingAncestors' }),\n ],\n placement: toPlacement(positionFromProps || 'top', alignCaret),\n strategy: 'fixed',\n })\n\n // A newer call already applied a fresher position - discard this stale result.\n if (token !== updateTokenRef.current) {\n return\n }\n\n const hidden = isTriggerHidden(trigger) || Boolean(middlewareData.hide?.referenceHidden)\n\n Object.assign(floatingElement.style, {\n left: `${x}px`,\n top: `${y}px`,\n visibility: hidden ? 'hidden' : '',\n })\n\n const resolvedSide = resolvedPlacement.split('-')[0] as Side\n const isHorizontalSide = resolvedSide === 'left' || resolvedSide === 'right'\n\n const shiftX = !isHorizontalSide && alignCaret === 'center' ? middlewareData.shift?.x || 0 : 0\n const shiftY = isHorizontalSide ? middlewareData.shift?.y || 0 : 0\n\n floatingElement.style.setProperty('--tooltip-caret-x', shiftX ? `${-shiftX}px` : '0px')\n floatingElement.style.setProperty('--tooltip-caret-y', shiftY ? `${-shiftY}px` : '0px')\n\n setPlacement(resolvedSide)\n }, [alignCaret, positionFromProps, staticPositioning])\n\n const setFloatingElement = useCallback(\n (element: HTMLDivElement | null) => {\n floatingRef.current = element\n void updatePosition()\n },\n [updatePosition],\n )\n\n // While mounted, let floating-ui keep the portaled tooltip aligned to its trigger\n // as the page scrolls, the trigger resizes or moves, or a hidden ancestor becomes\n // visible again - instead of manually re-measuring on window scroll/resize alone.\n useLayoutEffect(() => {\n const trigger = triggerMarkerRef.current?.parentElement\n const floatingElement = floatingRef.current\n\n if (!isMounted || !trigger || !floatingElement) {\n return\n }\n\n const cleanupAutoUpdate = autoUpdate(trigger, floatingElement, updatePosition, {\n elementResize: 'ResizeObserver' in window,\n })\n\n // autoUpdate's own layout-shift tracking gives up once the trigger's rect\n // collapses to zero (e.g. behind a `display: none` ancestor), so it can't\n // tell when the trigger becomes visible again. Watch for that separately.\n const visibilityObserver =\n typeof IntersectionObserver === 'function'\n ? new IntersectionObserver(() => void updatePosition(), { threshold: 0 })\n : null\n\n visibilityObserver?.observe(trigger)\n\n const visualViewport = window.visualViewport\n\n visualViewport?.addEventListener('resize', updatePosition)\n visualViewport?.addEventListener('scroll', updatePosition)\n\n return () => {\n cleanupAutoUpdate()\n visibilityObserver?.disconnect()\n visualViewport?.removeEventListener('resize', updatePosition)\n visualViewport?.removeEventListener('scroll', updatePosition)\n }\n }, [isMounted, updatePosition])\n\n useEffect(() => {\n const trigger = triggerMarkerRef.current?.parentElement\n\n if (!show || !trigger) {\n return\n }\n\n const describedByIDs = trigger.getAttribute('aria-describedby')?.split(' ') || []\n\n if (!describedByIDs.includes(tooltipID)) {\n trigger.setAttribute('aria-describedby', [...describedByIDs, tooltipID].join(' '))\n }\n\n return () => {\n const remainingIDs = (trigger.getAttribute('aria-describedby')?.split(' ') || []).filter(\n (describedByID) => describedByID !== tooltipID,\n )\n\n if (remainingIDs.length) {\n trigger.setAttribute('aria-describedby', remainingIDs.join(' '))\n } else {\n trigger.removeAttribute('aria-describedby')\n }\n }\n }, [show, tooltipID])\n\n return (\n <React.Fragment>\n <span aria-hidden=\"true\" ref={triggerMarkerRef} style={{ display: 'none' }} />\n {isMounted &&\n createPortal(\n <aside\n className={[\n 'tooltip',\n className,\n show && 'tooltip--show',\n `tooltip--caret-${alignCaret}`,\n `tooltip--position-${placement}`,\n ]\n .filter(Boolean)\n .join(' ')}\n id={tooltipID}\n ref={setFloatingElement}\n role=\"tooltip\"\n >\n <TooltipCaret />\n <div className=\"tooltip-content\">{children}</div>\n </aside>,\n document.body,\n )}\n </React.Fragment>\n )\n}\n"],"mappings":"AAAA;;AAAA,SAAAA,CAAA,IAAAC,EAAA;;AACA,SAASC,UAAU,EAAEC,eAAe,EAAEC,IAAI,EAAEC,IAAI,EAAEC,MAAM,EAAEC,KAAK,EAAEC,IAAI,QAAQ;AAC7E,OAAOC,KAAA,IAASC,WAAW,EAAEC,SAAS,EAAEC,eAAe,EAAEC,MAAM,EAAEC,QAAQ,QAAQ;AACjF,SAASC,YAAY,QAAQ;AAE7B,OAAO;AAEP,MAAMC,WAAA,GAAc;AAEpB,MAAMC,iBAAA,GAAoB;AAC1B,MAAMC,iBAAA,GAAoB;AAwB1B,MAAMC,YAAA,GAAyBA,CAAA;EAAA,MAAAC,CAAA,GAAAnB,EAAA;EAC7B,MAAAoB,MAAA,GAAeZ,KAAA,CAAAa,KAAA,CAAW;EAAA,IAAAC,EAAA;EAAA,IAAAH,CAAA,QAAAC,MAAA;IAGxBE,EAAA,GAAAC,KAAA,CAAC;MAAA,eAAgB;MAAAC,SAAA,EAAiB;MAAAC,MAAA,EAAwB;MAAAC,OAAA,EAAa;MAAAC,KAAA,EAAkB;MAAAC,QAAA,GACvFC,IAAA,CAAC;QAAAC,EAAA,EAAaV,MAAA;QAAAQ,QAAA,EACZC,IAAA,CAAC;UAAAJ,MAAA,EAAY;UAAAE,KAAA,EAAW;UAAAI,CAAA,EAAO;UAAAC,CAAA,EAAS;QAAA,C;UAG1CH,IAAA,CAAC;QAAAL,SAAA,EACW;QAAAS,QAAA,EACA,QAAQb,MAAA,GAAS;QAAAc,CAAA,EACzB;MAAA,C,GAGJL,IAAA,CAAC;QAAAL,SAAA,EAAe;QAAAU,CAAA,EAAwB;MAAA,C;;;;;;;SAX1CZ,E;CAcJ;AAEA,MAAMa,eAAA,GAAmBC,OAAA;EACvB,IAAI,OAAOA,OAAA,CAAQC,eAAe,KAAK,YAAY;IACjD,OAAO,CAACD,OAAA,CAAQC,eAAe;EACjC;EAEA;EACA;EACA,OAAOD,OAAA,CAAQE,cAAc,GAAGC,MAAM,KAAK;AAC7C;AAEA,MAAMC,WAAA,GAAcA,CAACC,IAAA,EAAYC,UAAA;EAC/B,IAAID,IAAA,KAAS,UAAUA,IAAA,KAAS,WAAWC,UAAA,KAAe,UAAU;IAClE,OAAOD,IAAA;EACT;EAEA,OAAO,GAAGA,IAAA,IAAQC,UAAA,KAAe,SAAS,UAAU,OAAO;AAC7D;AAEA,OAAO,MAAMC,OAAA,GAA4BC,KAAA;EACvC,MAAM;IACJd,EAAE;IACFY,UAAA,GAAa,QAAQ;IACrBd,QAAQ;IACRJ,SAAS;IACTqB,KAAA,GAAQ,GAAG;IACXC,QAAA,EAAUC,iBAAiB;IAC3BC,IAAA,EAAMC,aAAA,GAAgB,IAAI;IAC1BC,iBAAA,GAAoB;EAAK,CAC1B,GAAGN,KAAA;EAEJ,MAAMO,WAAA,GAAc3C,KAAA,CAAMa,KAAK;EAC/B,MAAM+B,SAAA,GAAYtB,EAAA,IAAMqB,WAAA;EAExB,MAAM,CAACH,IAAA,EAAMK,OAAA,CAAQ,GAAGxC,QAAA,CAASoC,aAAA;EACjC,MAAM,CAACK,SAAA,EAAWC,YAAA,CAAa,GAAG1C,QAAA,CAAS;EAC3C,MAAM,CAAC2C,SAAA,EAAWC,YAAA,CAAa,GAAG5C,QAAA,CAAekC,iBAAA,IAAqB;EAEtE;EACA;EACA,MAAMW,gBAAA,GAAmB9C,MAAA,CAAwB;EACjD,MAAM+C,WAAA,GAAc/C,MAAA,CAA8B;EAElD,MAAMgD,cAAA,GAAiBhD,MAAA,CAAO;EAE9BF,SAAA,CAAU;IACR,IAAImD,OAAA;IAEJ;IACA,IAAIhB,KAAA,IAASI,aAAA,EAAe;MAC1BY,OAAA,GAAUC,UAAA,CAAW;QACnBT,OAAA,CAAQJ,aAAA;MACV,GAAGJ,KAAA;IACL,OAAO;MACLQ,OAAA,CAAQJ,aAAA;IACV;IAEA,OAAO;MACL,IAAIY,OAAA,EAAS;QACXE,YAAA,CAAaF,OAAA;MACf;IACF;EACF,GAAG,CAACZ,aAAA,EAAeJ,KAAA,CAAM;EAEzB;EACA;EACAnC,SAAA,CAAU;IACR,IAAIsC,IAAA,EAAM;MACRO,YAAA,CAAa;MACb;IACF;IAEA;IACA,MAAMS,SAAA,GAAYF,UAAA,CAAW,MAAMP,YAAA,CAAa,QAAQ;IAExD,OAAO;MACLQ,YAAA,CAAaC,SAAA;IACf;EACF,GAAG,CAAChB,IAAA,CAAK;EAET,MAAMiB,cAAA,GAAiBxD,WAAA,CAAY;IACjC,MAAMyD,OAAA,GAAUR,gBAAA,CAAiBS,OAAO,EAAEC,aAAA;IAC1C,MAAMC,eAAA,GAAkBV,WAAA,CAAYQ,OAAO;IAE3C,IAAI,CAACD,OAAA,IAAW,CAACG,eAAA,EAAiB;MAChC;IACF;IAEA,MAAMC,KAAA,GAAQ,EAAEV,cAAA,CAAeO,OAAO;IACtC,MAAMI,QAAA,GAAW;IACjB,MAAMC,OAAA,GAAU,CAACtB,iBAAA,IAAqB,CAACH,iBAAA;IAEvC,MAAM;MACJ0B,cAAc;MACdjB,SAAA,EAAWkB,iBAAiB;MAC5B3C,CAAC;MACDC;IAAC,CACF,GAAG,MAAM9B,eAAA,CAAgBgE,OAAA,EAASG,eAAA,EAAiB;MAClDM,UAAA,EAAY,CACVtE,MAAA,CAAO,CAAC;QAAEmD,SAAA,EAAWoB;MAAgB,CAAE,KACrCA,gBAAA,CAAiBC,UAAU,CAAC,WAAWD,gBAAA,CAAiBC,UAAU,CAAC,WAC/D5D,iBAAA,GACAD,iBAAA,G,IAEFwD,OAAA,GAAU,CAACrE,IAAA,CAAK;QAAEoE,QAAA;QAAUO,OAAA,EAAS/D;MAAY,GAAG,GAAG,EAAE,G,IACzDmC,iBAAA,GACA,EAAE,GACF,CACE5C,KAAA,CAAM;QAAEiE,QAAA;QAAUO,OAAA,EAAS/D;MAAY,IACvCR,IAAA,CAAK;QACHwE,MAAM;UAAEC,cAAc;UAAEC;QAAQ,CAAE;UAChC,MAAMC,UAAA,GAAaD,QAAA,CAASE,QAAQ,CAACC,WAAW,GAAGJ,cAAA;UAEnDC,QAAA,CAASE,QAAQ,CAACE,eAAe,CAAC,aAAaH,UAAA;UAC/CD,QAAA,CAASE,QAAQ,CAACG,KAAK,CAACC,WAAW,CACjC,uBACAL,UAAA,GAAa,GAAGM,IAAA,CAAKC,KAAK,CAACT,cAAA,KAAmB,GAAG;QAErD;QACAT,QAAA;QACAO,OAAA,EAAS/D;MACX,GACD,GACLX,IAAA,CAAK;QAAEmE,QAAA,EAAU;MAAoB,GACtC;MACDf,SAAA,EAAWhB,WAAA,CAAYO,iBAAA,IAAqB,OAAOL,UAAA;MACnDgD,QAAA,EAAU;IACZ;IAEA;IACA,IAAIpB,KAAA,KAAUV,cAAA,CAAeO,OAAO,EAAE;MACpC;IACF;IAEA,MAAMwB,MAAA,GAASxD,eAAA,CAAgB+B,OAAA,KAAY0B,OAAA,CAAQnB,cAAA,CAAerE,IAAI,EAAEyF,eAAA;IAExEC,MAAA,CAAOC,MAAM,CAAC1B,eAAA,CAAgBiB,KAAK,EAAE;MACnCU,IAAA,EAAM,GAAGjE,CAAA,IAAK;MACdkE,GAAA,EAAK,GAAGjE,CAAA,IAAK;MACbkE,UAAA,EAAYP,MAAA,GAAS,WAAW;IAClC;IAEA,MAAMQ,YAAA,GAAezB,iBAAA,CAAkB0B,KAAK,CAAC,IAAI,CAAC,EAAE;IACpD,MAAMC,gBAAA,GAAmBF,YAAA,KAAiB,UAAUA,YAAA,KAAiB;IAErE,MAAMG,MAAA,GAAS,CAACD,gBAAA,IAAoB3D,UAAA,KAAe,WAAW+B,cAAA,CAAenE,KAAK,EAAEyB,CAAA,IAAK,IAAI;IAC7F,MAAMwE,MAAA,GAASF,gBAAA,GAAmB5B,cAAA,CAAenE,KAAK,EAAE0B,CAAA,IAAK,IAAI;IAEjEqC,eAAA,CAAgBiB,KAAK,CAACC,WAAW,CAAC,qBAAqBe,MAAA,GAAS,GAAG,CAACA,MAAA,IAAU,GAAG;IACjFjC,eAAA,CAAgBiB,KAAK,CAACC,WAAW,CAAC,qBAAqBgB,MAAA,GAAS,GAAG,CAACA,MAAA,IAAU,GAAG;IAEjF9C,YAAA,CAAa0C,YAAA;EACf,GAAG,CAACzD,UAAA,EAAYK,iBAAA,EAAmBG,iBAAA,CAAkB;EAErD,MAAMsD,kBAAA,GAAqB/F,WAAA,CACxB2B,OAAA;IACCuB,WAAA,CAAYQ,OAAO,GAAG/B,OAAA;IACtB,KAAK6B,cAAA;EACP,GACA,CAACA,cAAA,CAAe;EAGlB;EACA;EACA;EACAtD,eAAA,CAAgB;IACd,MAAMuD,SAAA,GAAUR,gBAAA,CAAiBS,OAAO,EAAEC,aAAA;IAC1C,MAAMC,iBAAA,GAAkBV,WAAA,CAAYQ,OAAO;IAE3C,IAAI,CAACb,SAAA,IAAa,CAACY,SAAA,IAAW,CAACG,iBAAA,EAAiB;MAC9C;IACF;IAEA,MAAMoC,iBAAA,GAAoBxG,UAAA,CAAWiE,SAAA,EAASG,iBAAA,EAAiBJ,cAAA,EAAgB;MAC7EyC,aAAA,EAAe,oBAAoBC;IACrC;IAEA;IACA;IACA;IACA,MAAMC,kBAAA,GACJ,OAAOC,oBAAA,KAAyB,aAC5B,IAAIA,oBAAA,CAAqB,MAAM,KAAK5C,cAAA,IAAkB;MAAE6C,SAAA,EAAW;IAAE,KACrE;IAENF,kBAAA,EAAoBG,OAAA,CAAQ7C,SAAA;IAE5B,MAAM8C,cAAA,GAAiBL,MAAA,CAAOK,cAAc;IAE5CA,cAAA,EAAgBC,gBAAA,CAAiB,UAAUhD,cAAA;IAC3C+C,cAAA,EAAgBC,gBAAA,CAAiB,UAAUhD,cAAA;IAE3C,OAAO;MACLwC,iBAAA;MACAG,kBAAA,EAAoBM,UAAA;MACpBF,cAAA,EAAgBG,mBAAA,CAAoB,UAAUlD,cAAA;MAC9C+C,cAAA,EAAgBG,mBAAA,CAAoB,UAAUlD,cAAA;IAChD;EACF,GAAG,CAACX,SAAA,EAAWW,cAAA,CAAe;EAE9BvD,SAAA,CAAU;IACR,MAAMwD,SAAA,GAAUR,gBAAA,CAAiBS,OAAO,EAAEC,aAAA;IAE1C,IAAI,CAACpB,IAAA,IAAQ,CAACkB,SAAA,EAAS;MACrB;IACF;IAEA,MAAMkD,cAAA,GAAiBlD,SAAA,CAAQmD,YAAY,CAAC,qBAAqBjB,KAAA,CAAM,QAAQ,EAAE;IAEjF,IAAI,CAACgB,cAAA,CAAeE,QAAQ,CAAClE,SAAA,GAAY;MACvCc,SAAA,CAAQqD,YAAY,CAAC,oBAAoB,C,GAAIH,cAAA,EAAgBhE,SAAA,CAAU,CAACoE,IAAI,CAAC;IAC/E;IAEA,OAAO;MACL,MAAMC,YAAA,GAAe,CAACvD,SAAA,CAAQmD,YAAY,CAAC,qBAAqBjB,KAAA,CAAM,QAAQ,EAAE,EAAEsB,MAAM,CACrFC,aAAA,IAAkBA,aAAA,KAAkBvE,SAAA;MAGvC,IAAIqE,YAAA,CAAalF,MAAM,EAAE;QACvB2B,SAAA,CAAQqD,YAAY,CAAC,oBAAoBE,YAAA,CAAaD,IAAI,CAAC;MAC7D,OAAO;QACLtD,SAAA,CAAQ0D,eAAe,CAAC;MAC1B;IACF;EACF,GAAG,CAAC5E,IAAA,EAAMI,SAAA,CAAU;EAEpB,oBACE7B,KAAA,CAACf,KAAA,CAAMqH,QAAQ;4BACbhG,IAAA,CAAC;MAAK,eAAY;MAAOiG,GAAA,EAAKpE,gBAAA;MAAkB4B,KAAA,EAAO;QAAEyC,OAAA,EAAS;MAAO;QACxEzE,SAAA,iBACCxC,YAAA,cACES,KAAA,CAAC;MACCC,SAAA,EAAW,CACT,WACAA,SAAA,EACAwB,IAAA,IAAQ,iBACR,kBAAkBN,UAAA,EAAY,EAC9B,qBAAqBc,SAAA,EAAW,CACjC,CACEkE,MAAM,CAAC9B,OAAA,EACP4B,IAAI,CAAC;MACR1F,EAAA,EAAIsB,SAAA;MACJ0E,GAAA,EAAKtB,kBAAA;MACLwB,IAAA,EAAK;8BAELnG,IAAA,CAACX,YAAA,O,aACDW,IAAA,CAAC;QAAIL,SAAA,EAAU;kBAAmBI;;QAEpCqG,QAAA,CAASC,IAAI;;AAIvB","ignoreList":[]}
@@ -11,11 +11,6 @@
11
11
  position: relative;
12
12
  }
13
13
 
14
- .file-field .tooltip.error-message {
15
- z-index: 3;
16
- bottom: calc(100% - var(--spacer-2));
17
- }
18
-
19
14
  .file-field__file-selected {
20
15
  display: flex;
21
16
  }
@@ -311,6 +311,7 @@ export { ProgressBar } from '../../providers/RouteTransition/ProgressBar/index.j
311
311
  export { RouteTransitionProvider, useRouteTransition, } from '../../providers/RouteTransition/index.js';
312
312
  export { ConfigProvider, PageConfigProvider, useConfig } from '../../providers/Config/index.js';
313
313
  export { DocumentEventsProvider, useDocumentEvents } from '../../providers/DocumentEvents/index.js';
314
+ export { FormErrorHandlerContext, useFormErrorHandler, } from '../../providers/FormErrorHandler/index.js';
314
315
  export { DocumentInfoProvider, useDocumentInfo } from '../../providers/DocumentInfo/index.js';
315
316
  export { useDocumentTitle } from '../../providers/DocumentTitle/index.js';
316
317
  export type { DocumentTitleContext } from '../../providers/DocumentTitle/index.js';
@@ -337,6 +338,8 @@ export type { AllowedCollection } from '../../providers/Hierarchy/types.js';
337
338
  export { UploadHandlersProvider, useUploadHandlers } from '../../providers/UploadHandlers/index.js';
338
339
  export type { UploadHandlersContext } from '../../providers/UploadHandlers/index.js';
339
340
  export { defaultTheme, type Theme, type ThemeContext, ThemeProvider, useTheme, } from '../../providers/Theme/index.js';
341
+ export { EmbedProvider, useEmbed } from '../../providers/Embed/index.js';
342
+ export type { EmbedContext } from '../../providers/Embed/index.js';
340
343
  export { TranslationProvider, useTranslation } from '../../providers/Translation/index.js';
341
344
  export { useWindowInfo, WindowInfoProvider } from '../../providers/WindowInfo/index.js';
342
345
  export { useControllableState } from '../../hooks/useControllableState.js';