cx 26.2.1 → 26.2.3

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 (324) hide show
  1. package/build/charts/Chart.d.ts.map +1 -1
  2. package/build/charts/Chart.js +5 -4
  3. package/build/charts/ColumnBarBase.d.ts +3 -3
  4. package/build/charts/ColumnBarBase.d.ts.map +1 -1
  5. package/build/charts/ColumnBarBase.js +1 -1
  6. package/build/charts/Legend.d.ts.map +1 -1
  7. package/build/charts/Legend.js +11 -4
  8. package/build/charts/Marker.d.ts +3 -3
  9. package/build/charts/Marker.d.ts.map +1 -1
  10. package/build/charts/MarkerLine.d.ts +7 -7
  11. package/build/charts/MarkerLine.d.ts.map +1 -1
  12. package/build/charts/MarkerLine.js +14 -10
  13. package/build/charts/PieChart.d.ts +4 -4
  14. package/build/charts/PieChart.d.ts.map +1 -1
  15. package/build/charts/PieChart.js +36 -14
  16. package/build/charts/PieLabel.d.ts.map +1 -1
  17. package/build/charts/PieLabel.js +2 -1
  18. package/build/charts/RangeMarker.d.ts +3 -3
  19. package/build/charts/RangeMarker.d.ts.map +1 -1
  20. package/build/charts/RangeMarker.js +1 -1
  21. package/build/charts/axis/TimeAxis.d.ts +3 -3
  22. package/build/charts/axis/TimeAxis.d.ts.map +1 -1
  23. package/build/charts/axis/TimeAxis.js +70 -21
  24. package/build/charts/helpers/ValueAtFinder.d.ts +1 -1
  25. package/build/charts/helpers/ValueAtFinder.d.ts.map +1 -1
  26. package/build/charts/helpers/ValueAtFinder.js +5 -2
  27. package/build/data/StructuredSelector.js +3 -4
  28. package/build/data/createAccessorModelProxy.d.ts +6 -11
  29. package/build/data/createAccessorModelProxy.d.ts.map +1 -1
  30. package/build/data/createAccessorModelProxy.js +1 -3
  31. package/build/svg/Ellipse.d.ts +5 -4
  32. package/build/svg/Ellipse.d.ts.map +1 -1
  33. package/build/svg/Ellipse.js +9 -6
  34. package/build/svg/Line.d.ts +1 -0
  35. package/build/svg/Line.d.ts.map +1 -1
  36. package/build/svg/Line.js +4 -1
  37. package/build/svg/Text.d.ts +12 -6
  38. package/build/svg/Text.d.ts.map +1 -1
  39. package/build/svg/Text.js +12 -4
  40. package/build/ui/Controller.d.ts +2 -0
  41. package/build/ui/Controller.d.ts.map +1 -1
  42. package/build/ui/Controller.js +3 -0
  43. package/build/ui/HoverSync.d.ts.map +1 -1
  44. package/build/ui/HoverSync.js +7 -2
  45. package/build/ui/Prop.d.ts +1 -1
  46. package/build/ui/Prop.d.ts.map +1 -1
  47. package/build/ui/Text.d.ts +3 -3
  48. package/build/ui/Text.d.ts.map +1 -1
  49. package/build/ui/Text.js +5 -5
  50. package/build/ui/adapter/GroupAdapter.d.ts.map +1 -1
  51. package/build/ui/adapter/GroupAdapter.js +20 -10
  52. package/build/ui/app/History.js +1 -1
  53. package/build/widgets/List.d.ts.map +1 -1
  54. package/build/widgets/List.js +6 -7
  55. package/build/widgets/drag-drop/DropZone.d.ts +3 -3
  56. package/build/widgets/drag-drop/DropZone.d.ts.map +1 -1
  57. package/build/widgets/form/Calendar.d.ts.map +1 -1
  58. package/build/widgets/form/Calendar.js +30 -11
  59. package/build/widgets/form/ColorField.d.ts.map +1 -1
  60. package/build/widgets/form/ColorField.js +16 -7
  61. package/build/widgets/form/DateTimeField.d.ts.map +1 -1
  62. package/build/widgets/form/DateTimeField.js +23 -10
  63. package/build/widgets/form/Field.d.ts +2 -0
  64. package/build/widgets/form/Field.d.ts.map +1 -1
  65. package/build/widgets/form/Field.js +11 -5
  66. package/build/widgets/form/LookupField.d.ts +1 -1
  67. package/build/widgets/form/LookupField.d.ts.map +1 -1
  68. package/build/widgets/form/LookupField.js +6 -6
  69. package/build/widgets/form/MonthField.d.ts.map +1 -1
  70. package/build/widgets/form/MonthField.js +15 -7
  71. package/build/widgets/form/MonthPicker.d.ts +1 -2
  72. package/build/widgets/form/MonthPicker.d.ts.map +1 -1
  73. package/build/widgets/form/MonthPicker.js +84 -41
  74. package/build/widgets/form/NumberField.d.ts +2 -0
  75. package/build/widgets/form/NumberField.d.ts.map +1 -1
  76. package/build/widgets/form/NumberField.js +45 -15
  77. package/build/widgets/form/TextField.d.ts +1 -9
  78. package/build/widgets/form/TextField.d.ts.map +1 -1
  79. package/build/widgets/form/TextField.js +1 -1
  80. package/build/widgets/grid/Grid.d.ts +2 -2
  81. package/build/widgets/grid/Grid.d.ts.map +1 -1
  82. package/build/widgets/grid/Grid.js +9 -4
  83. package/build/widgets/grid/Pagination.d.ts.map +1 -1
  84. package/build/widgets/grid/Pagination.js +4 -4
  85. package/build/widgets/grid/TreeNode.d.ts.map +1 -1
  86. package/build/widgets/grid/TreeNode.js +10 -2
  87. package/build/widgets/icons/folder.d.ts.map +1 -1
  88. package/build/widgets/icons/folder.js +1 -0
  89. package/build/widgets/icons/forward.d.ts.map +1 -1
  90. package/build/widgets/icons/forward.js +4 -3
  91. package/build/widgets/icons/loading.d.ts.map +1 -1
  92. package/build/widgets/icons/loading.js +6 -5
  93. package/build/widgets/icons/square.d.ts.map +1 -1
  94. package/build/widgets/icons/square.js +3 -3
  95. package/build/widgets/index.d.ts +3 -1
  96. package/build/widgets/index.d.ts.map +1 -1
  97. package/build/widgets/index.js +3 -1
  98. package/build/widgets/overlay/ContextMenu.d.ts.map +1 -1
  99. package/build/widgets/overlay/ContextMenu.js +2 -0
  100. package/build/widgets/overlay/Dropdown.d.ts +2 -1
  101. package/build/widgets/overlay/Dropdown.d.ts.map +1 -1
  102. package/build/widgets/overlay/Dropdown.js +75 -20
  103. package/build/widgets/overlay/MsgBox.d.ts +1 -0
  104. package/build/widgets/overlay/MsgBox.d.ts.map +1 -1
  105. package/build/widgets/overlay/MsgBox.js +2 -2
  106. package/build/widgets/overlay/Overlay.d.ts +32 -2
  107. package/build/widgets/overlay/Overlay.d.ts.map +1 -1
  108. package/build/widgets/overlay/Overlay.js +47 -16
  109. package/build/widgets/overlay/Toast.d.ts +1 -1
  110. package/build/widgets/overlay/Toast.d.ts.map +1 -1
  111. package/build/widgets/overlay/Toast.js +4 -1
  112. package/build/widgets/overlay/Tooltip.d.ts +6 -0
  113. package/build/widgets/overlay/Tooltip.d.ts.map +1 -1
  114. package/build/widgets/overlay/Tooltip.js +24 -9
  115. package/build/widgets/overlay/Window.d.ts.map +1 -1
  116. package/build/widgets/overlay/Window.js +24 -9
  117. package/dist/charts.css +325 -272
  118. package/dist/charts.js +11 -5
  119. package/dist/data.js +2 -2
  120. package/dist/manifest.js +892 -880
  121. package/dist/svg.css +14 -8
  122. package/dist/svg.js +9 -1
  123. package/dist/ui.js +29 -16
  124. package/dist/widgets.css +997 -294
  125. package/dist/widgets.js +317 -121
  126. package/package.json +1 -1
  127. package/src/charts/Bar.scss +13 -10
  128. package/src/charts/BarGraph.scss +31 -29
  129. package/src/charts/BubbleGraph.scss +11 -8
  130. package/src/charts/Chart.ts +5 -3
  131. package/src/charts/Column.scss +13 -10
  132. package/src/charts/ColumnBarBase.tsx +255 -230
  133. package/src/charts/ColumnGraph.scss +13 -11
  134. package/src/charts/Gridlines.scss +10 -8
  135. package/src/charts/Legend.scss +57 -50
  136. package/src/charts/Legend.tsx +257 -213
  137. package/src/charts/LegendEntry.scss +35 -29
  138. package/src/charts/LineGraph.scss +28 -25
  139. package/src/charts/Marker.scss +12 -10
  140. package/src/charts/Marker.tsx +3 -2
  141. package/src/charts/MarkerLine.scss +11 -8
  142. package/src/charts/MarkerLine.tsx +196 -177
  143. package/src/charts/PieChart.scss +12 -9
  144. package/src/charts/PieChart.tsx +717 -591
  145. package/src/charts/PieLabel.tsx +99 -81
  146. package/src/charts/Range.scss +11 -8
  147. package/src/charts/RangeMarker.tsx +204 -187
  148. package/src/charts/ScatterGraph.scss +12 -9
  149. package/src/charts/axis/Axis.scss +6 -5
  150. package/src/charts/axis/CategoryAxis.scss +10 -8
  151. package/src/charts/axis/NumericAxis.scss +9 -6
  152. package/src/charts/axis/TimeAxis.scss +9 -6
  153. package/src/charts/axis/TimeAxis.tsx +753 -637
  154. package/src/charts/axis/index.scss +4 -5
  155. package/src/charts/axis/variables.scss +4 -2
  156. package/src/charts/helpers/ValueAtFinder.ts +19 -5
  157. package/src/charts/index.scss +16 -19
  158. package/src/charts/maps.scss +0 -0
  159. package/src/charts/palette.scss +11 -31
  160. package/src/charts/palette.variables.scss +23 -0
  161. package/src/charts/variables.scss +35 -3
  162. package/src/data/StructuredSelector.ts +2 -2
  163. package/src/data/createAccessorModelProxy.ts +66 -74
  164. package/src/index.scss +5 -6
  165. package/src/maps.scss +5 -0
  166. package/src/svg/Ellipse.tsx +62 -55
  167. package/src/svg/Line.tsx +57 -42
  168. package/src/svg/Svg.scss +6 -6
  169. package/src/svg/Text.scss +19 -0
  170. package/src/svg/Text.tsx +172 -116
  171. package/src/svg/index.scss +3 -2
  172. package/src/svg/maps.scss +0 -0
  173. package/src/svg/variables.scss +0 -0
  174. package/src/ui/Container.spec.ts +59 -0
  175. package/src/ui/Controller.spec.tsx +30 -0
  176. package/src/ui/Controller.ts +5 -0
  177. package/src/ui/HoverSync.tsx +179 -147
  178. package/src/ui/Prop.ts +1 -1
  179. package/src/ui/Text.ts +12 -9
  180. package/src/ui/adapter/GroupAdapter.spec.ts +42 -0
  181. package/src/ui/adapter/GroupAdapter.ts +25 -14
  182. package/src/ui/app/History.ts +1 -1
  183. package/src/ui/index.scss +1 -1
  184. package/src/ui/layout/LabelsLeftLayout.scss +5 -7
  185. package/src/ui/layout/LabelsTopLayout.scss +4 -6
  186. package/src/ui/layout/index.scss +2 -3
  187. package/src/ui/maps.scss +0 -0
  188. package/src/ui/variables.scss +1 -2
  189. package/src/util/index.scss +4 -2
  190. package/src/util/maps.scss +1 -0
  191. package/src/util/scss/besm.scss +15 -0
  192. package/src/util/scss/calc.scss +103 -11
  193. package/src/util/scss/defaults.scss +24 -0
  194. package/src/util/scss/elements.scss +78 -0
  195. package/src/util/scss/global.scss +15 -0
  196. package/src/util/scss/include.scss +17 -9
  197. package/src/util/scss/index.scss +1 -9
  198. package/src/util/scss/maps.scss +2 -0
  199. package/src/util/scss/pad-size.scss +9 -0
  200. package/src/util/scss/padding.scss +6 -0
  201. package/src/util/scss/screen-size.scss +5 -0
  202. package/src/util/scss/variables.scss +6 -0
  203. package/src/util/variables.scss +1 -0
  204. package/src/variables.scss +5 -217
  205. package/src/widgets/Button.maps.scss +103 -0
  206. package/src/widgets/Button.scss +33 -9
  207. package/src/widgets/Button.variables.scss +8 -104
  208. package/src/widgets/CxCredit.scss +2 -0
  209. package/src/widgets/FlexBox.scss +16 -11
  210. package/src/widgets/Heading.scss +6 -0
  211. package/src/widgets/HighlightedSearchText.scss +8 -1
  212. package/src/widgets/Icon.scss +6 -0
  213. package/src/widgets/List.scss +7 -0
  214. package/src/widgets/List.tsx +6 -7
  215. package/src/widgets/ProgressBar.scss +9 -0
  216. package/src/widgets/Resizer.scss +9 -7
  217. package/src/widgets/Section.scss +53 -56
  218. package/src/widgets/animations.scss +4 -2
  219. package/src/widgets/box.scss +47 -0
  220. package/src/widgets/drag-drop/DragClone.scss +12 -4
  221. package/src/widgets/drag-drop/DragHandle.scss +12 -6
  222. package/src/widgets/drag-drop/DragSource.scss +12 -6
  223. package/src/widgets/drag-drop/DropZone.scss +9 -0
  224. package/src/widgets/drag-drop/DropZone.tsx +3 -3
  225. package/src/widgets/drag-drop/index.scss +4 -4
  226. package/src/widgets/drag-drop/maps.scss +7 -0
  227. package/src/widgets/drag-drop/variables.scss +8 -5
  228. package/src/widgets/form/Calendar.maps.scss +54 -0
  229. package/src/widgets/form/Calendar.scss +49 -11
  230. package/src/widgets/form/Calendar.tsx +755 -653
  231. package/src/widgets/form/Calendar.variables.scss +3 -46
  232. package/src/widgets/form/Checkbox.maps.scss +34 -0
  233. package/src/widgets/form/Checkbox.scss +14 -3
  234. package/src/widgets/form/Checkbox.variables.scss +4 -36
  235. package/src/widgets/form/ColorField.scss +21 -2
  236. package/src/widgets/form/ColorField.tsx +485 -431
  237. package/src/widgets/form/ColorPicker.maps.scss +21 -0
  238. package/src/widgets/form/ColorPicker.scss +26 -9
  239. package/src/widgets/form/ColorPicker.variables.scss +3 -16
  240. package/src/widgets/form/DateTimeField.scss +54 -21
  241. package/src/widgets/form/DateTimeField.tsx +697 -615
  242. package/src/widgets/form/DateTimePicker.scss +14 -4
  243. package/src/widgets/form/Field.maps.scss +122 -0
  244. package/src/widgets/form/Field.scss +54 -18
  245. package/src/widgets/form/Field.tsx +611 -504
  246. package/src/widgets/form/Field.variables.scss +46 -0
  247. package/src/widgets/form/HelpText.scss +8 -5
  248. package/src/widgets/form/Label.scss +10 -3
  249. package/src/widgets/form/LookupField.maps.scss +26 -0
  250. package/src/widgets/form/LookupField.scss +54 -24
  251. package/src/widgets/form/LookupField.tsx +25 -21
  252. package/src/widgets/form/MonthField.scss +48 -26
  253. package/src/widgets/form/MonthField.tsx +645 -567
  254. package/src/widgets/form/MonthPicker.maps.scss +50 -0
  255. package/src/widgets/form/MonthPicker.scss +44 -35
  256. package/src/widgets/form/MonthPicker.tsx +954 -724
  257. package/src/widgets/form/MonthPicker.variables.scss +24 -0
  258. package/src/widgets/form/NumberField.scss +19 -2
  259. package/src/widgets/form/NumberField.tsx +576 -466
  260. package/src/widgets/form/Radio.maps.scss +36 -0
  261. package/src/widgets/form/Radio.scss +12 -2
  262. package/src/widgets/form/Radio.variables.scss +3 -42
  263. package/src/widgets/form/Select.scss +25 -9
  264. package/src/widgets/form/Slider.scss +23 -14
  265. package/src/widgets/form/Switch.scss +18 -8
  266. package/src/widgets/form/TextArea.scss +14 -1
  267. package/src/widgets/form/TextField.scss +24 -3
  268. package/src/widgets/form/TextField.tsx +9 -21
  269. package/src/widgets/form/UploadButton.scss +14 -6
  270. package/src/widgets/form/ValidationError.scss +10 -6
  271. package/src/widgets/form/Wheel.scss +14 -4
  272. package/src/widgets/form/index.scss +22 -24
  273. package/src/widgets/form/maps.scss +81 -0
  274. package/src/widgets/form/variables.scss +111 -355
  275. package/src/widgets/grid/Grid.scss +19 -2
  276. package/src/widgets/grid/Grid.spec.ts +42 -0
  277. package/src/widgets/grid/Grid.tsx +15 -7
  278. package/src/widgets/grid/Pagination.scss +11 -2
  279. package/src/widgets/grid/Pagination.tsx +110 -102
  280. package/src/widgets/grid/TreeNode.scss +25 -8
  281. package/src/widgets/grid/TreeNode.tsx +127 -116
  282. package/src/widgets/grid/index.scss +3 -4
  283. package/src/widgets/grid/maps.scss +110 -0
  284. package/src/widgets/grid/variables.scss +48 -137
  285. package/src/widgets/icons/folder.tsx +1 -2
  286. package/src/widgets/icons/forward.tsx +23 -20
  287. package/src/widgets/icons/loading.tsx +22 -19
  288. package/src/widgets/icons/square.tsx +20 -17
  289. package/src/widgets/index.scss +16 -16
  290. package/src/widgets/index.ts +63 -58
  291. package/src/widgets/lists.scss +42 -0
  292. package/src/widgets/maps.scss +139 -0
  293. package/src/widgets/nav/Link.scss +14 -1
  294. package/src/widgets/nav/Menu.scss +13 -7
  295. package/src/widgets/nav/Menu.variables.scss +1 -12
  296. package/src/widgets/nav/MenuItem.scss +21 -6
  297. package/src/widgets/nav/Scroller.scss +11 -2
  298. package/src/widgets/nav/Tab.maps.scss +78 -0
  299. package/src/widgets/nav/Tab.scss +12 -6
  300. package/src/widgets/nav/Tab.variables.scss +7 -76
  301. package/src/widgets/nav/cover.scss +6 -4
  302. package/src/widgets/nav/index.scss +6 -6
  303. package/src/widgets/nav/maps.scss +32 -0
  304. package/src/widgets/nav/variables.scss +4 -11
  305. package/src/widgets/overlay/ContextMenu.ts +3 -0
  306. package/src/widgets/overlay/Dropdown.scss +47 -16
  307. package/src/widgets/overlay/Dropdown.tsx +851 -676
  308. package/src/widgets/overlay/MsgBox.tsx +125 -111
  309. package/src/widgets/overlay/Overlay.scss +60 -40
  310. package/src/widgets/overlay/Overlay.tsx +948 -800
  311. package/src/widgets/overlay/Toast.scss +42 -34
  312. package/src/widgets/overlay/Toast.ts +11 -1
  313. package/src/widgets/overlay/Tooltip.scss +27 -96
  314. package/src/widgets/overlay/Tooltip.tsx +376 -309
  315. package/src/widgets/overlay/Window.maps.scss +51 -0
  316. package/src/widgets/overlay/Window.scss +17 -17
  317. package/src/widgets/overlay/Window.tsx +291 -236
  318. package/src/widgets/overlay/Window.variables.scss +2 -43
  319. package/src/widgets/overlay/index.d.ts +11 -11
  320. package/src/widgets/overlay/index.scss +6 -15
  321. package/src/widgets/overlay/maps.scss +44 -0
  322. package/src/widgets/overlay/variables.scss +11 -42
  323. package/src/widgets/variables.scss +33 -117
  324. package/src/global.scss +0 -14
@@ -33,335 +33,425 @@ import { captureMouseOrTouch, getCursorPos } from "./captureMouse";
33
33
  */
34
34
 
35
35
  export interface OverlayConfig extends StyledContainerConfig {
36
- /** Set to `true` to enable resizing. */
37
- resizable?: BooleanProp;
36
+ /** Set to `true` to enable resizing. */
37
+ resizable?: BooleanProp;
38
38
 
39
- /** Set to `true` to enable dragging the overlay. */
40
- draggable?: BooleanProp;
39
+ /** Set to `true` to enable dragging the overlay. */
40
+ draggable?: BooleanProp;
41
41
 
42
- /** Base CSS class to be applied to the field. Defaults to `overlay`. */
43
- baseClass?: string;
42
+ /** Base CSS class to be applied to the field. Defaults to `overlay`. */
43
+ baseClass?: string;
44
44
 
45
- /** Width of resize handle area. */
46
- resizeWidth?: number;
45
+ /** Width of resize handle area. */
46
+ resizeWidth?: number;
47
47
 
48
- /** Set to `true` to initially place the overlay in the center of the page. */
49
- center?: boolean;
48
+ /** Set to `true` to initially place the overlay in the center of the page. */
49
+ center?: boolean;
50
50
 
51
- /** Set to `true` to initially place the overlay in the center of the page horizontally. */
52
- centerX?: boolean;
51
+ /** Set to `true` to initially place the overlay in the center of the page horizontally. */
52
+ centerX?: boolean;
53
53
 
54
- /** Set to `true` to initially place the overlay in the center of the page vertically. */
55
- centerY?: boolean;
54
+ /** Set to `true` to initially place the overlay in the center of the page vertically. */
55
+ centerY?: boolean;
56
56
 
57
- /** Set to `true` to add a modal backdrop which masks mouse events for the rest of the page. */
58
- modal?: boolean;
57
+ /** Set to `true` to add a modal backdrop which masks mouse events for the rest of the page. */
58
+ modal?: boolean;
59
59
 
60
- /** Set to `true` to add a modal backdrop which will dismiss the window when clicked. */
61
- backdrop?: boolean;
60
+ /** Set to `true` to add a modal backdrop which will dismiss the window when clicked. */
61
+ backdrop?: boolean;
62
62
 
63
- /** Set to `true` to force the element to be rendered inline, instead of being appended to the body element.
64
- * Inline overlays have z-index set to a very high value, to ensure they are displayed on top of the other content. */
65
- inline?: boolean;
63
+ /** Set to `true` to force the element to be rendered inline, instead of being appended to the body element.
64
+ * Inline overlays have z-index set to a very high value, to ensure they are displayed on top of the other content. */
65
+ inline?: boolean;
66
66
 
67
- /** Set to `true` to automatically focus the top level overlay element. */
68
- autoFocus?: boolean;
67
+ /** Set to `true` to automatically focus the top level overlay element. */
68
+ autoFocus?: boolean;
69
69
 
70
- /** Set to `true` to automatically focus the first focusable child in the overlay. */
71
- autoFocusFirstChild?: boolean;
70
+ /** Set to `true` to automatically focus the first focusable child in the overlay. */
71
+ autoFocusFirstChild?: boolean;
72
72
 
73
- /** Set to `true` to append the set animate state after the initial render. Appended CSS class may be used to add show/hide animations. */
74
- animate?: boolean;
73
+ /** Set to `true` to append the set animate state after the initial render. Appended CSS class may be used to add show/hide animations. */
74
+ animate?: boolean;
75
75
 
76
- /** Number of milliseconds to wait, before removing the element from the DOM. Used in combination with the animate property. */
77
- destroyDelay?: number;
76
+ /** Number of milliseconds to wait, before removing the element from the DOM. Used in combination with the animate property. */
77
+ destroyDelay?: number;
78
78
 
79
- /** Automatically dismiss overlay if it loses focus. */
80
- dismissOnFocusOut?: boolean;
79
+ /** Automatically dismiss overlay if it loses focus. */
80
+ dismissOnFocusOut?: boolean;
81
81
 
82
- /** Set to true to make the top level overlay element focusable. */
83
- focusable?: boolean;
82
+ /** Set to true to make the top level overlay element focusable. */
83
+ focusable?: boolean;
84
84
 
85
- /** Set to `true` to dismiss the window if the user presses the back button in the browser. */
86
- dismissOnPopState?: boolean;
85
+ /** Set to `true` to dismiss the window if the user presses the back button in the browser. */
86
+ dismissOnPopState?: boolean;
87
87
 
88
- /** A callback function which fires while the overlay is being moved around. */
89
- onMove?: string | ((e: Event, instance: Instance, component: any) => void);
88
+ /** A callback function which fires while the overlay is being moved around. */
89
+ onMove?: string | ((e: Event, instance: Instance, component: any) => void);
90
90
 
91
- /** A callback function which fires while the overlay is being resized. */
92
- onResize?: string | ((e: Event, instance: Instance, component: any) => void);
91
+ /** A callback function which fires while the overlay is being resized. */
92
+ onResize?: string | ((e: Event, instance: Instance, component: any) => void);
93
93
 
94
- /** zIndex */
95
- zIndex?: NumberProp;
94
+ /** zIndex */
95
+ zIndex?: NumberProp;
96
96
 
97
- /** Set to `true` to make the window automatically close if Esc is pressed on the keyboard. Default value is false.*/
98
- closeOnEscape?: boolean;
97
+ /** Set to `true` to make the window automatically close if Esc is pressed on the keyboard. Default value is false.*/
98
+ closeOnEscape?: boolean;
99
99
 
100
- /** Custom CSS styling for the container element. */
101
- containerStyle?: string;
100
+ /** Custom CSS styling for the container element. */
101
+ containerStyle?: string;
102
102
 
103
- /** Callback for focus out event. */
104
- onFocusOut?: string;
103
+ /** Callback for focus out event. */
104
+ onFocusOut?: string;
105
105
 
106
- /** Callback for mouse enter event. */
107
- onMouseEnter?: string;
106
+ /** Callback for mouse enter event. */
107
+ onMouseEnter?: string;
108
108
 
109
- /** Callback for mouse leave event. */
110
- onMouseLeave?: string;
109
+ /** Callback for mouse leave event. */
110
+ onMouseLeave?: string;
111
111
 
112
- /** Callback for backdrop click. */
113
- onBackdropClick?: string;
112
+ /** Callback for backdrop click. */
113
+ onBackdropClick?: string;
114
114
 
115
- /** Callback for mouse down event. */
116
- onMouseDown?: string;
115
+ /** Callback for mouse down event. */
116
+ onMouseDown?: string;
117
117
 
118
- /** Callback for key down event. */
119
- onKeyDown?: string;
118
+ /** Callback for key down event. */
119
+ onKeyDown?: string;
120
120
 
121
- /** Callback fired before dismiss. */
122
- onBeforeDismiss?: string | (() => boolean);
121
+ /** Callback fired before dismiss. */
122
+ onBeforeDismiss?: string | (() => boolean);
123
123
 
124
- /** Callback fired when overlay will dismiss. */
125
- overlayWillDismiss?: (instance: Instance, component: any) => boolean;
124
+ /** Callback fired when overlay will dismiss. */
125
+ overlayWillDismiss?: (instance: Instance, component: any) => boolean;
126
126
 
127
- /** Callback for click event. */
128
- onClick?: string;
127
+ /** Callback for click event. */
128
+ onClick?: string;
129
129
  }
130
130
 
131
- export class OverlayInstance<WidgetType extends OverlayBase<any, any> = Overlay> extends Instance<WidgetType> {
132
- declare positionChangeSubscribers: SubscriberList;
133
- declare dismiss?: () => void;
134
- onBeforeDismiss?: () => boolean;
131
+ export interface OverlayOpenOptions {
132
+ initiatingEvent?: React.SyntheticEvent;
133
+ name?: string;
134
+ dismiss?: () => void;
135
+ parentEl?: Element;
136
+ subscribeToBeforeDismiss?: (callback: () => boolean) => void;
137
+ destroyDelay?: number;
138
+ removeParentDOMElement?: boolean;
139
+ }
140
+
141
+ export interface ConfigureOverlayContainerContext {
142
+ relatedElement?: HTMLElement | null;
143
+ initiatingEvent?: React.SyntheticEvent;
144
+ }
145
+
146
+ export class OverlayInstance<
147
+ WidgetType extends OverlayBase<any, any> = Overlay,
148
+ > extends Instance<WidgetType> {
149
+ declare positionChangeSubscribers: SubscriberList;
150
+ declare dismiss?: () => void;
151
+ onBeforeDismiss?: () => boolean;
152
+ declare beaconEl?: HTMLElement | null;
135
153
  }
136
154
 
137
155
  export class OverlayBase<
138
- Config extends OverlayConfig = OverlayConfig,
139
- InstanceType extends OverlayInstance<any> = OverlayInstance<any>,
156
+ Config extends OverlayConfig = OverlayConfig,
157
+ InstanceType extends OverlayInstance<any> = OverlayInstance<any>,
140
158
  > extends ContainerBase<Config, InstanceType> {
141
- // Properties declared here to support prototype assignments
142
- declare styled: true;
143
- declare baseClass: string;
144
- declare resizable?: BooleanProp;
145
- declare resizeWidth: number;
146
- declare center?: boolean;
147
- declare centerX?: boolean;
148
- declare centerY?: boolean;
149
- declare modal?: boolean;
150
- declare backdrop?: boolean;
151
- declare inline?: boolean;
152
- declare autoFocus?: boolean;
153
- declare autoFocusFirstChild?: boolean;
154
- declare animate?: boolean;
155
- declare draggable?: BooleanProp;
156
- declare destroyDelay?: number;
157
- declare dismissOnFocusOut?: boolean;
158
- declare focusable?: boolean;
159
- declare containerStyle?: string;
160
- declare dismissOnPopState?: boolean;
161
- declare closeOnEscape?: boolean;
162
- declare onFocusOut?: string;
163
- declare onMouseLeave?: string;
164
- declare onMouseEnter?: string;
165
- declare onKeyDown?: string;
166
- declare onMove?: string | ((e: Event, instance: Instance, component: any) => void);
167
- declare onResize?: string | ((e: Event, instance: Instance, component: any) => void);
168
- declare onClick?: string;
169
- declare onMouseDown?: string;
170
- declare onBackdropClick?: string;
171
- declare overlayWillDismiss?: (instance: Instance, component: any) => boolean;
172
- declare style?: any;
173
- declare pad?: boolean;
174
-
175
- init() {
176
- if (this.center) this.centerX = this.centerY = this.center;
177
-
178
- super.init();
179
- }
180
-
181
- declareData(...args: any[]) {
182
- super.declareData(...args, {
183
- shadowStyle: {
184
- structured: true,
185
- },
186
- resizable: undefined,
187
- draggable: undefined,
188
- zIndex: undefined,
189
- });
190
- }
191
-
192
- prepareData(context: RenderingContext, instance: InstanceType): void {
193
- let { data } = instance;
194
- data.stateMods = {
195
- ...data.stateMods,
196
- inline: this.inline,
197
- modal: this.modal,
198
- pad: this.pad,
199
- resizable: data.resizable,
200
- draggable: data.draggable,
201
- animate: this.animate,
202
- shadow: this.modal || this.backdrop,
203
- };
204
-
205
- super.prepareData(context, instance);
206
- }
207
-
208
- initInstance(context: RenderingContext, instance: InstanceType): void {
209
- instance.positionChangeSubscribers = new SubscriberList();
210
- super.initInstance(context, instance);
211
- }
212
-
213
- explore(context: RenderingContext, instance: InstanceType): void {
214
- if (isBinding(this.visible)) {
215
- if (!instance.dismiss) {
216
- instance.dismiss = () => {
217
- if (instance.onBeforeDismiss && instance.onBeforeDismiss() === false) return;
218
- instance.set("visible", false);
219
- };
220
- }
221
- } else if (context.options.dismiss) instance.dismiss = context.options.dismiss;
222
-
223
- if (instance.dismiss) {
224
- context.push("parentOptions", {
225
- ...context.parentOptions,
226
- dismiss: instance.dismiss,
227
- });
159
+ static configureOverlayContainer?: (
160
+ containerEl: HTMLElement,
161
+ context: ConfigureOverlayContainerContext,
162
+ ) => void;
163
+
164
+ // Properties declared here to support prototype assignments
165
+ declare styled: true;
166
+ declare baseClass: string;
167
+ declare resizable?: BooleanProp;
168
+ declare resizeWidth: number;
169
+ declare center?: boolean;
170
+ declare centerX?: boolean;
171
+ declare centerY?: boolean;
172
+ declare modal?: boolean;
173
+ declare backdrop?: boolean;
174
+ declare inline?: boolean;
175
+ declare autoFocus?: boolean;
176
+ declare autoFocusFirstChild?: boolean;
177
+ declare animate?: boolean;
178
+ declare draggable?: BooleanProp;
179
+ declare destroyDelay?: number;
180
+ declare dismissOnFocusOut?: boolean;
181
+ declare focusable?: boolean;
182
+ declare containerStyle?: string;
183
+ declare dismissOnPopState?: boolean;
184
+ declare closeOnEscape?: boolean;
185
+ declare onFocusOut?: string;
186
+ declare onMouseLeave?: string;
187
+ declare onMouseEnter?: string;
188
+ declare onKeyDown?: string;
189
+ declare onMove?:
190
+ | string
191
+ | ((e: Event, instance: Instance, component: any) => void);
192
+ declare onResize?:
193
+ | string
194
+ | ((e: Event, instance: Instance, component: any) => void);
195
+ declare onClick?: string;
196
+ declare onMouseDown?: string;
197
+ declare onBackdropClick?: string;
198
+ declare overlayWillDismiss?: (instance: Instance, component: any) => boolean;
199
+ declare style?: any;
200
+ declare pad?: boolean;
201
+ declare needsBeacon: boolean;
202
+
203
+ init() {
204
+ if (this.center) this.centerX = this.centerY = this.center;
205
+
206
+ super.init();
207
+ }
208
+
209
+ declareData(...args: any[]) {
210
+ super.declareData(...args, {
211
+ shadowStyle: {
212
+ structured: true,
213
+ },
214
+ resizable: undefined,
215
+ draggable: undefined,
216
+ zIndex: undefined,
217
+ });
218
+ }
219
+
220
+ prepareData(context: RenderingContext, instance: InstanceType): void {
221
+ let { data } = instance;
222
+ data.stateMods = {
223
+ ...data.stateMods,
224
+ inline: this.inline,
225
+ modal: this.modal,
226
+ pad: this.pad,
227
+ resizable: data.resizable,
228
+ draggable: data.draggable,
229
+ animate: this.animate,
230
+ shadow: this.modal || this.backdrop,
231
+ };
232
+
233
+ super.prepareData(context, instance);
234
+ }
235
+
236
+ initInstance(context: RenderingContext, instance: InstanceType): void {
237
+ instance.positionChangeSubscribers = new SubscriberList();
238
+ super.initInstance(context, instance);
239
+ }
240
+
241
+ explore(context: RenderingContext, instance: InstanceType): void {
242
+ if (isBinding(this.visible)) {
243
+ if (!instance.dismiss) {
244
+ instance.dismiss = () => {
245
+ if (instance.onBeforeDismiss && instance.onBeforeDismiss() === false)
246
+ return;
247
+ instance.set("visible", false);
248
+ };
228
249
  }
250
+ } else if (context.options.dismiss)
251
+ instance.dismiss = context.options.dismiss;
252
+
253
+ if (instance.dismiss) {
254
+ context.push("parentOptions", {
255
+ ...context.parentOptions,
256
+ dismiss: instance.dismiss,
257
+ });
258
+ }
229
259
 
230
- if (instance.cache("dismiss", instance.dismiss)) instance.markShouldUpdate(context);
260
+ if (instance.cache("dismiss", instance.dismiss))
261
+ instance.markShouldUpdate(context);
231
262
 
232
- context.push("parentPositionChangeEvent", instance.positionChangeSubscribers);
263
+ context.push(
264
+ "parentPositionChangeEvent",
265
+ instance.positionChangeSubscribers,
266
+ );
233
267
 
234
- super.explore(context, instance);
235
- }
268
+ super.explore(context, instance);
269
+ }
236
270
 
237
- exploreCleanup(context: RenderingContext, instance: InstanceType): void {
238
- if (instance.dismiss) context.pop("parentOptions");
239
- context.pop("parentPositionChangeEvent");
240
- }
271
+ exploreCleanup(context: RenderingContext, instance: InstanceType): void {
272
+ if (instance.dismiss) context.pop("parentOptions");
273
+ context.pop("parentPositionChangeEvent");
274
+ }
241
275
 
242
- render(context: RenderingContext, instance: InstanceType, key: string): any {
276
+ render(context: RenderingContext, instance: InstanceType, key: string): any {
277
+ if (this.needsBeacon)
243
278
  return (
244
- <OverlayComponent
245
- key={key}
246
- instance={instance}
247
- subscribeToBeforeDismiss={context.options.subscribeToBeforeDismiss}
248
- parentEl={context.options.parentEl}
249
- >
250
- {this.renderContents(context, instance)}
251
- </OverlayComponent>
279
+ <OverlayBeacon
280
+ key={key}
281
+ childrenFactory={(beaconEl) => (
282
+ <OverlayComponent
283
+ beaconEl={beaconEl}
284
+ instance={instance}
285
+ subscribeToBeforeDismiss={
286
+ context.options.subscribeToBeforeDismiss
287
+ }
288
+ parentEl={context.options.parentEl}
289
+ >
290
+ {this.renderContents(context, instance)}
291
+ </OverlayComponent>
292
+ )}
293
+ />
252
294
  );
253
- }
254
-
255
- renderContents(context: RenderingContext, instance: InstanceType): any {
256
- return this.renderChildren(context, instance);
257
- }
258
-
259
- overlayDidMount(instance: InstanceType, component: any): void {
260
- let { el } = component;
261
- if (this.centerX) if (!el.style.left) el.style.left = `${(window.innerWidth - el.offsetWidth) / 2}px`;
262
- if (this.centerY)
263
- if (!el.style.top) el.style.top = `${Math.max(0, (window.innerHeight - el.offsetHeight) / 2)}px`;
264
- }
265
-
266
- overlayDidUpdate(instance: InstanceType, component: any): void {}
267
-
268
- overlayWillUnmount(instance: InstanceType, component: any): void {}
269
-
270
- handleFocusOut(instance: InstanceType, component: any): void {
271
- if (this.onFocusOut) instance.invoke("onFocusOut", instance, component);
272
-
273
- if (this.dismissOnFocusOut && instance.dismiss) instance.dismiss();
274
- }
275
295
 
276
- handleKeyDown(e: any, instance: InstanceType, component?: any): void | false {
277
- if (this.onKeyDown && instance.invoke("onKeyDown", e, instance, component) === false) return false;
278
-
279
- if (this.closeOnEscape && e.keyCode == KeyCode.esc && instance.dismiss) {
280
- instance.dismiss();
281
- e.stopPropagation();
282
- }
283
- }
284
-
285
- handleMouseLeave(instance: InstanceType, component: any): void {
286
- if (this.onMouseLeave) instance.invoke("onMouseLeave", instance, component);
287
- }
288
-
289
- handleMouseEnter(instance: InstanceType, component: any): void {
290
- if (this.onMouseEnter) instance.invoke("onMouseEnter", instance, component);
291
- }
292
-
293
- getOverlayContainer(): HTMLElement {
294
- return document.body;
295
- }
296
-
297
- containerFactory(): HTMLElement {
298
- let el = document.createElement("div");
299
- let container = this.getOverlayContainer();
300
- container.appendChild(el);
301
- el.style.position = "absolute";
302
- if (this.containerStyle) Object.assign(el.style, parseStyle(this.containerStyle));
303
- return el;
304
- }
305
-
306
- open(storeOrInstance?: View | Instance, options?: any): () => void {
307
- if (!this.initialized) this.init();
308
-
309
- let el = this.containerFactory();
310
- el.style.display = "hidden";
311
-
312
- let beforeDismiss: (() => boolean) | null = null;
313
- let stop: any;
314
-
315
- options = {
316
- destroyDelay: this.destroyDelay,
317
- removeParentDOMElement: true,
318
- ...options,
319
- parentEl: el,
320
- dismiss: () => {
321
- if (beforeDismiss && beforeDismiss() === false) return;
322
- stop();
323
- beforeDismiss = null;
324
- },
325
- subscribeToBeforeDismiss: (cb: () => boolean) => {
326
- beforeDismiss = cb;
327
- },
328
- };
329
- options.name = options.name || "overlay";
330
- stop = startAppLoop(el, storeOrInstance, this, options);
331
- return options.dismiss;
332
- }
333
-
334
- handleMove(e: any, instance: InstanceType, component: any): void {
335
- let { widget } = instance;
336
- if (!widget.onMove || instance.invoke("onMove", e, instance, component) !== false) {
337
- instance.store.silently(() => {
338
- if (isDataRecord(this.style) && isBindingObject(this.style.top)) {
339
- instance.store.set(this.style.top.bind, component.el.style.top);
340
- }
341
-
342
- if (isDataRecord(this.style) && isBindingObject(this.style.left)) {
343
- instance.store.set(this.style.left.bind, component.el.style.left);
344
- }
345
- });
346
- }
347
- instance.positionChangeSubscribers.notify();
348
- }
349
-
350
- handleResize(e: any, instance: InstanceType, component: any): void {
351
- let { widget } = instance;
352
- if (!widget.onResize || instance.invoke("onResize", e, instance, component) !== false) {
353
- instance.store.silently(() => {
354
- if (isDataRecord(this.style) && isBindingObject(this.style.width)) {
355
- instance.store.set(this.style.width.bind, component.el.style.width);
356
- }
296
+ return (
297
+ <OverlayComponent
298
+ beaconEl={null}
299
+ instance={instance}
300
+ subscribeToBeforeDismiss={context.options.subscribeToBeforeDismiss}
301
+ parentEl={context.options.parentEl}
302
+ >
303
+ {this.renderContents(context, instance)}
304
+ </OverlayComponent>
305
+ );
306
+ }
307
+
308
+ renderContents(context: RenderingContext, instance: InstanceType): any {
309
+ return this.renderChildren(context, instance);
310
+ }
311
+
312
+ getConfigureOverlayContainerContext(
313
+ instance?: InstanceType,
314
+ initiatingEvent?: React.SyntheticEvent,
315
+ ): ConfigureOverlayContainerContext {
316
+ return {
317
+ initiatingEvent,
318
+ relatedElement: instance?.beaconEl,
319
+ };
320
+ }
321
+
322
+ overlayDidMount(instance: InstanceType, component: any): void {
323
+ let { el } = component;
324
+ if (this.centerX)
325
+ if (!el.style.left)
326
+ el.style.left = `${(window.innerWidth - el.offsetWidth) / 2}px`;
327
+ if (this.centerY)
328
+ if (!el.style.top)
329
+ el.style.top = `${Math.max(0, (window.innerHeight - el.offsetHeight) / 2)}px`;
330
+ }
331
+
332
+ overlayDidUpdate(instance: InstanceType, component: any): void {}
333
+
334
+ overlayWillUnmount(instance: InstanceType, component: any): void {}
335
+
336
+ handleFocusOut(instance: InstanceType, component: any): void {
337
+ if (this.onFocusOut) instance.invoke("onFocusOut", instance, component);
338
+
339
+ if (this.dismissOnFocusOut && instance.dismiss) instance.dismiss();
340
+ }
341
+
342
+ handleKeyDown(e: any, instance: InstanceType, component?: any): void | false {
343
+ if (
344
+ this.onKeyDown &&
345
+ instance.invoke("onKeyDown", e, instance, component) === false
346
+ )
347
+ return false;
348
+
349
+ if (this.closeOnEscape && e.keyCode == KeyCode.esc && instance.dismiss) {
350
+ instance.dismiss();
351
+ e.stopPropagation();
352
+ }
353
+ }
354
+
355
+ handleMouseLeave(instance: InstanceType, component: any): void {
356
+ if (this.onMouseLeave) instance.invoke("onMouseLeave", instance, component);
357
+ }
358
+
359
+ handleMouseEnter(instance: InstanceType, component: any): void {
360
+ if (this.onMouseEnter) instance.invoke("onMouseEnter", instance, component);
361
+ }
362
+
363
+ getOverlayContainer(): HTMLElement {
364
+ return document.body;
365
+ }
366
+
367
+ containerFactory(
368
+ instance?: InstanceType,
369
+ initiatingEvent?: React.SyntheticEvent,
370
+ ): HTMLElement {
371
+ let el = document.createElement("div");
372
+ let container = this.getOverlayContainer();
373
+ container.appendChild(el);
374
+ el.style.position = "absolute";
375
+ if (this.containerStyle)
376
+ Object.assign(el.style, parseStyle(this.containerStyle));
377
+
378
+ if (OverlayBase.configureOverlayContainer)
379
+ OverlayBase.configureOverlayContainer(
380
+ el,
381
+ this.getConfigureOverlayContainerContext(instance, initiatingEvent),
382
+ );
357
383
 
358
- if (isDataRecord(this.style) && isBindingObject(this.style.height)) {
359
- instance.store.set(this.style.height.bind, component.el.style.height);
360
- }
361
- });
362
- }
363
- instance.positionChangeSubscribers.notify();
364
- }
384
+ return el;
385
+ }
386
+
387
+ open(
388
+ storeOrInstance?: View | Instance,
389
+ options?: OverlayOpenOptions,
390
+ ): () => void {
391
+ if (!this.initialized) this.init();
392
+
393
+ let el = this.containerFactory(undefined, options?.initiatingEvent);
394
+ el.style.display = "hidden";
395
+
396
+ let beforeDismiss: (() => boolean) | null = null;
397
+ let stop: any;
398
+
399
+ options = {
400
+ destroyDelay: this.destroyDelay,
401
+ removeParentDOMElement: true,
402
+ ...options,
403
+ parentEl: el,
404
+ dismiss: () => {
405
+ if (beforeDismiss && beforeDismiss() === false) return;
406
+ stop();
407
+ beforeDismiss = null;
408
+ },
409
+ subscribeToBeforeDismiss: (cb: () => boolean) => {
410
+ beforeDismiss = cb;
411
+ },
412
+ };
413
+ options.name = options.name || "overlay";
414
+ stop = startAppLoop(el, storeOrInstance, this, options);
415
+ return options.dismiss!;
416
+ }
417
+
418
+ handleMove(e: any, instance: InstanceType, component: any): void {
419
+ let { widget } = instance;
420
+ if (
421
+ !widget.onMove ||
422
+ instance.invoke("onMove", e, instance, component) !== false
423
+ ) {
424
+ instance.store.silently(() => {
425
+ if (isDataRecord(this.style) && isBindingObject(this.style.top)) {
426
+ instance.store.set(this.style.top.bind, component.el.style.top);
427
+ }
428
+
429
+ if (isDataRecord(this.style) && isBindingObject(this.style.left)) {
430
+ instance.store.set(this.style.left.bind, component.el.style.left);
431
+ }
432
+ });
433
+ }
434
+ instance.positionChangeSubscribers.notify();
435
+ }
436
+
437
+ handleResize(e: any, instance: InstanceType, component: any): void {
438
+ let { widget } = instance;
439
+ if (
440
+ !widget.onResize ||
441
+ instance.invoke("onResize", e, instance, component) !== false
442
+ ) {
443
+ instance.store.silently(() => {
444
+ if (isDataRecord(this.style) && isBindingObject(this.style.width)) {
445
+ instance.store.set(this.style.width.bind, component.el.style.width);
446
+ }
447
+
448
+ if (isDataRecord(this.style) && isBindingObject(this.style.height)) {
449
+ instance.store.set(this.style.height.bind, component.el.style.height);
450
+ }
451
+ });
452
+ }
453
+ instance.positionChangeSubscribers.notify();
454
+ }
365
455
  }
366
456
 
367
457
  OverlayBase.prototype.styled = true;
@@ -384,565 +474,623 @@ OverlayBase.prototype.focusable = false;
384
474
  OverlayBase.prototype.containerStyle = undefined;
385
475
  OverlayBase.prototype.dismissOnPopState = false;
386
476
  OverlayBase.prototype.closeOnEscape = false;
477
+ OverlayBase.prototype.needsBeacon = false;
387
478
 
388
479
  export class Overlay extends OverlayBase<OverlayConfig, OverlayInstance> {}
389
480
 
390
481
  Widget.alias("overlay", Overlay);
391
482
 
392
483
  interface OverlayContentProps {
393
- onRef: (el: HTMLDivElement | null) => void;
394
- className: string;
395
- style: any;
396
- tabIndex: number | undefined;
397
- onFocus: () => void;
398
- onBlur: () => void;
399
- onKeyDown: (e: any) => void;
400
- onMouseMove: (e: any, captureData?: any) => void;
401
- onMouseUp: (e: any) => void;
402
- onMouseDown: (e: any) => void;
403
- onTouchStart: (e: any) => void;
404
- onTouchEnd: (e: any) => void;
405
- onTouchMove: (e: any, captureData?: any) => void;
406
- onMouseEnter: (e: any) => void;
407
- onMouseLeave: (e: any) => void;
408
- onClick: (e: any) => void;
409
- onDidUpdate: () => void;
410
- focusableOverlayContainer?: boolean;
411
- children: any;
484
+ onRef: (el: HTMLDivElement | null) => void;
485
+ className: string;
486
+ style: any;
487
+ tabIndex: number | undefined;
488
+ onFocus: () => void;
489
+ onBlur: () => void;
490
+ onKeyDown: (e: any) => void;
491
+ onMouseMove: (e: any, captureData?: any) => void;
492
+ onMouseUp: (e: any) => void;
493
+ onMouseDown: (e: any) => void;
494
+ onTouchStart: (e: any) => void;
495
+ onTouchEnd: (e: any) => void;
496
+ onTouchMove: (e: any, captureData?: any) => void;
497
+ onMouseEnter: (e: any) => void;
498
+ onMouseLeave: (e: any) => void;
499
+ onClick: (e: any) => void;
500
+ onDidUpdate: () => void;
501
+ focusableOverlayContainer?: boolean;
502
+ children: any;
412
503
  }
413
504
 
414
505
  //TODO: all el related logic should be moved here
415
506
  class OverlayContent extends VDOM.Component<OverlayContentProps, {}> {
416
- render() {
417
- return (
418
- <div
419
- ref={this.props.onRef}
420
- className={this.props.className}
421
- style={this.props.style}
422
- tabIndex={this.props.tabIndex}
423
- onFocus={this.props.onFocus}
424
- onBlur={this.props.onBlur}
425
- onKeyDown={this.props.onKeyDown}
426
- onMouseMove={this.props.onMouseMove}
427
- onMouseUp={this.props.onMouseUp}
428
- onMouseDown={this.props.onMouseDown}
429
- onTouchStart={this.props.onTouchStart}
430
- onTouchEnd={this.props.onTouchEnd}
431
- onTouchMove={this.props.onTouchMove}
432
- onMouseEnter={this.props.onMouseEnter}
433
- onMouseLeave={this.props.onMouseLeave}
434
- onClick={this.props.onClick}
435
- data-focusable-overlay-container={this.props.focusableOverlayContainer}
436
- >
437
- {this.props.children}
438
- </div>
439
- );
440
- }
441
-
442
- componentDidUpdate() {
443
- this.props.onDidUpdate();
444
- }
507
+ render() {
508
+ return (
509
+ <div
510
+ ref={this.props.onRef}
511
+ className={this.props.className}
512
+ style={this.props.style}
513
+ tabIndex={this.props.tabIndex}
514
+ onFocus={this.props.onFocus}
515
+ onBlur={this.props.onBlur}
516
+ onKeyDown={this.props.onKeyDown}
517
+ onMouseMove={this.props.onMouseMove}
518
+ onMouseUp={this.props.onMouseUp}
519
+ onMouseDown={this.props.onMouseDown}
520
+ onTouchStart={this.props.onTouchStart}
521
+ onTouchEnd={this.props.onTouchEnd}
522
+ onTouchMove={this.props.onTouchMove}
523
+ onMouseEnter={this.props.onMouseEnter}
524
+ onMouseLeave={this.props.onMouseLeave}
525
+ onClick={this.props.onClick}
526
+ data-focusable-overlay-container={this.props.focusableOverlayContainer}
527
+ >
528
+ {this.props.children}
529
+ </div>
530
+ );
531
+ }
532
+
533
+ componentDidUpdate() {
534
+ this.props.onDidUpdate();
535
+ }
445
536
  }
446
537
 
447
538
  export interface OverlayComponentProps {
448
- instance: OverlayInstance;
449
- parentEl?: HTMLElement;
450
- subscribeToBeforeDismiss?: (cb: () => boolean) => void;
451
- children: any;
539
+ instance: OverlayInstance;
540
+ parentEl?: HTMLElement;
541
+ subscribeToBeforeDismiss?: (cb: () => boolean) => void;
542
+ children: any;
543
+ beaconEl: HTMLElement | null;
452
544
  }
453
545
 
454
546
  export interface OverlayComponentState {
455
- animated?: boolean;
456
- mods?: Record<string, boolean>;
547
+ animated?: boolean;
548
+ mods?: Record<string, boolean>;
457
549
  }
458
550
 
459
551
  //TODO: This should be called OverlayPortal
460
552
  export class OverlayComponent<
461
- Props extends OverlayComponentProps = OverlayComponentProps,
462
- State extends OverlayComponentState = OverlayComponentState,
553
+ Props extends OverlayComponentProps = OverlayComponentProps,
554
+ State extends OverlayComponentState = OverlayComponentState,
463
555
  > extends VDOM.Component<Props, State> {
464
- declare el?: HTMLElement | null;
465
- declare containerEl?: HTMLElement | null;
466
- declare ownedEl?: HTMLElement | null;
467
- onOverlayRef?: (el: HTMLElement | null) => void;
468
- declare shadowEl?: HTMLElement | null;
469
- declare dismissed?: boolean;
470
- declare unmounting?: boolean;
471
- onPopState?: () => void;
472
- unsubscribeWheelBlock?: () => void;
473
- declare customStyle: any;
474
- declare root: Root;
475
-
476
- constructor(props: Props) {
477
- super(props);
478
- this.state = {} as State;
479
- this.customStyle = {};
480
- }
481
-
482
- render() {
483
- let { instance, parentEl } = this.props;
484
- let { widget } = instance;
485
-
486
- if (widget.inline || parentEl) return this.renderOverlay();
487
-
488
- if (!this.containerEl) {
489
- this.ownedEl = widget.containerFactory();
490
- this.ownedEl.style.display = "hidden";
491
- this.containerEl = this.ownedEl;
492
- }
493
-
494
- if (VDOM.DOM.createPortal) return VDOM.DOM.createPortal(this.renderOverlay(), this.containerEl);
495
-
496
- //rendered in componentDidUpdate if portals are not supported
497
- return null;
498
- }
499
-
500
- renderOverlay() {
501
- let { widget, data } = this.props.instance;
502
- let { CSS, baseClass } = widget;
556
+ declare el?: HTMLElement | null;
557
+ declare containerEl?: HTMLElement | null;
558
+ declare ownedEl?: HTMLElement | null;
559
+ onOverlayRef?: (el: HTMLElement | null) => void;
560
+ declare shadowEl?: HTMLElement | null;
561
+ declare dismissed?: boolean;
562
+ declare unmounting?: boolean;
563
+ onPopState?: () => void;
564
+ unsubscribeWheelBlock?: () => void;
565
+ declare customStyle: any;
566
+ declare root: Root;
567
+
568
+ constructor(props: Props) {
569
+ super(props);
570
+ this.state = {} as State;
571
+ this.customStyle = {};
572
+ }
573
+
574
+ render() {
575
+ let { instance, parentEl } = this.props;
576
+ let { widget } = instance;
577
+
578
+ if (widget.inline || parentEl) return this.renderOverlay();
579
+
580
+ if (!this.containerEl) {
581
+ instance.beaconEl = this.props.beaconEl;
582
+ this.ownedEl = widget.containerFactory(instance);
583
+ this.ownedEl.style.display = "hidden";
584
+ this.containerEl = this.ownedEl;
585
+ }
586
+
587
+ // content is rendered in componentDidUpdate if portals are not supported
588
+ return VDOM.DOM.createPortal
589
+ ? VDOM.DOM.createPortal!(this.renderOverlay(), this.containerEl)
590
+ : null;
591
+ }
592
+
593
+ renderOverlay() {
594
+ let { widget, data } = this.props.instance;
595
+ let { CSS, baseClass } = widget;
596
+
597
+ if (!this.onOverlayRef)
598
+ this.onOverlayRef = (el) => {
599
+ this.el = el;
600
+ };
503
601
 
504
- if (!this.onOverlayRef)
505
- this.onOverlayRef = (el) => {
506
- this.el = el;
507
- };
508
-
509
- let content = (
510
- <OverlayContent
511
- onRef={this.onOverlayRef}
512
- className={data.classNames}
513
- style={data.style}
514
- tabIndex={widget.focusable ? 0 : undefined}
515
- onFocus={this.onFocus.bind(this)}
516
- onBlur={this.onBlur.bind(this)}
517
- onKeyDown={this.onKeyDown.bind(this)}
518
- onMouseDown={this.onMouseDown.bind(this)}
519
- onMouseUp={this.onMouseUp.bind(this)}
520
- onMouseMove={this.onMouseMove.bind(this)}
521
- onTouchStart={this.onMouseDown.bind(this)}
522
- onTouchEnd={this.onMouseUp.bind(this)}
523
- onTouchMove={this.onMouseMove.bind(this)}
524
- onMouseLeave={this.onMouseLeave.bind(this)}
525
- onMouseEnter={this.onMouseEnter.bind(this)}
526
- onClick={this.onClick.bind(this)}
527
- onDidUpdate={this.overlayDidUpdate.bind(this)}
528
- focusableOverlayContainer={widget.dismissOnFocusOut}
529
- >
530
- {this.renderOverlayBody()}
531
- </OverlayContent>
602
+ let content = (
603
+ <OverlayContent
604
+ onRef={this.onOverlayRef}
605
+ className={data.classNames}
606
+ style={data.style}
607
+ tabIndex={widget.focusable ? 0 : undefined}
608
+ onFocus={this.onFocus.bind(this)}
609
+ onBlur={this.onBlur.bind(this)}
610
+ onKeyDown={this.onKeyDown.bind(this)}
611
+ onMouseDown={this.onMouseDown.bind(this)}
612
+ onMouseUp={this.onMouseUp.bind(this)}
613
+ onMouseMove={this.onMouseMove.bind(this)}
614
+ onTouchStart={this.onMouseDown.bind(this)}
615
+ onTouchEnd={this.onMouseUp.bind(this)}
616
+ onTouchMove={this.onMouseMove.bind(this)}
617
+ onMouseLeave={this.onMouseLeave.bind(this)}
618
+ onMouseEnter={this.onMouseEnter.bind(this)}
619
+ onClick={this.onClick.bind(this)}
620
+ onDidUpdate={this.overlayDidUpdate.bind(this)}
621
+ focusableOverlayContainer={widget.dismissOnFocusOut}
622
+ >
623
+ {this.renderOverlayBody()}
624
+ </OverlayContent>
625
+ );
626
+
627
+ let result = content;
628
+
629
+ if (widget.modal || widget.backdrop) {
630
+ result = (
631
+ <div
632
+ key="shadow"
633
+ ref={(el) => {
634
+ this.shadowEl = el;
635
+ }}
636
+ className={CSS.element(baseClass, "shadow", {
637
+ animated: this.state.animated,
638
+ "animate-enter": this.state.animated && !this.dismissed,
639
+ animate: widget.animate,
640
+ })}
641
+ style={parseStyle(data.shadowStyle)}
642
+ >
643
+ <div
644
+ key="backdrop"
645
+ className={CSS.element("overlay", "modal-backdrop")}
646
+ onClick={this.onBackdropClick.bind(this)}
647
+ />
648
+ {content}
649
+ </div>
532
650
  );
533
-
534
- let result = content;
535
-
536
- if (widget.modal || widget.backdrop) {
537
- result = (
538
- <div
539
- key="shadow"
540
- ref={(el) => {
541
- this.shadowEl = el;
542
- }}
543
- className={CSS.element(baseClass, "shadow", {
544
- animated: this.state.animated,
545
- "animate-enter": this.state.animated && !this.dismissed,
546
- animate: widget.animate,
547
- })}
548
- style={parseStyle(data.shadowStyle)}
549
- >
550
- <div
551
- key="backdrop"
552
- className={CSS.element("overlay", "modal-backdrop")}
553
- onClick={this.onBackdropClick.bind(this)}
554
- />
555
- {content}
556
- </div>
557
- );
558
- }
559
-
560
- return result;
561
- }
562
-
563
- renderOverlayBody() {
564
- return this.props.children;
565
- }
566
-
567
- onFocus() {
568
- FocusManager.nudge();
569
- this.onFocusIn();
570
- if (this.el) oneFocusOut(this, this.el, this.onFocusOut.bind(this));
571
- }
572
-
573
- onBlur() {
574
- FocusManager.nudge();
575
- }
576
-
577
- onFocusIn() {}
578
-
579
- onFocusOut() {
580
- let { widget } = this.props.instance;
581
- widget.handleFocusOut(this.props.instance, this);
582
- }
583
-
584
- onMouseEnter(e: React.MouseEvent) {
585
- let { widget } = this.props.instance;
586
- widget.handleMouseEnter(this.props.instance, this);
587
- }
588
-
589
- onMouseLeave(e: React.MouseEvent) {
590
- let { widget } = this.props.instance;
591
- widget.handleMouseLeave(this.props.instance, this);
592
- }
593
-
594
- onClick(e: React.MouseEvent) {
595
- let { instance } = this.props;
596
- let { widget } = instance;
597
- if (widget.onClick) instance.invoke("onClick", e, instance, this);
598
- }
599
-
600
- onKeyDown(e: React.KeyboardEvent) {
601
- let { widget } = this.props.instance;
602
- widget.handleKeyDown(e, this.props.instance, this);
603
- }
604
-
605
- getResizePrefix(e: MouseEvent | React.MouseEvent | React.TouchEvent) {
606
- let { widget, data } = this.props.instance;
607
- if (!data.resizable) return "";
651
+ }
652
+
653
+ return result;
654
+ }
655
+
656
+ renderOverlayBody() {
657
+ return this.props.children;
658
+ }
659
+
660
+ onFocus() {
661
+ FocusManager.nudge();
662
+ this.onFocusIn();
663
+ if (this.el) oneFocusOut(this, this.el, this.onFocusOut.bind(this));
664
+ }
665
+
666
+ onBlur() {
667
+ FocusManager.nudge();
668
+ }
669
+
670
+ onFocusIn() {}
671
+
672
+ onFocusOut() {
673
+ let { widget } = this.props.instance;
674
+ widget.handleFocusOut(this.props.instance, this);
675
+ }
676
+
677
+ onMouseEnter(e: React.MouseEvent) {
678
+ let { widget } = this.props.instance;
679
+ widget.handleMouseEnter(this.props.instance, this);
680
+ }
681
+
682
+ onMouseLeave(e: React.MouseEvent) {
683
+ let { widget } = this.props.instance;
684
+ widget.handleMouseLeave(this.props.instance, this);
685
+ }
686
+
687
+ onClick(e: React.MouseEvent) {
688
+ let { instance } = this.props;
689
+ let { widget } = instance;
690
+ if (widget.onClick) instance.invoke("onClick", e, instance, this);
691
+ }
692
+
693
+ onKeyDown(e: React.KeyboardEvent) {
694
+ let { widget } = this.props.instance;
695
+ widget.handleKeyDown(e, this.props.instance, this);
696
+ }
697
+
698
+ getResizePrefix(e: MouseEvent | React.MouseEvent | React.TouchEvent) {
699
+ let { widget, data } = this.props.instance;
700
+ if (!data.resizable) return "";
701
+ let cursor = getCursorPos(e);
702
+ let bounds = getTopLevelBoundingClientRect(this.el!);
703
+ let leftMargin = cursor.clientX - bounds.left;
704
+ let rightMargin = bounds.right - cursor.clientX;
705
+ let topMargin = cursor.clientY - bounds.top;
706
+ let bottomMargin = bounds.bottom - cursor.clientY;
707
+ let prefix = "";
708
+
709
+ if (topMargin >= 0 && topMargin < widget.resizeWidth) prefix += "n";
710
+ else if (bottomMargin >= 0 && bottomMargin < widget.resizeWidth)
711
+ prefix += "s";
712
+
713
+ if (leftMargin >= 0 && leftMargin < widget.resizeWidth) prefix += "w";
714
+ else if (rightMargin >= 0 && rightMargin < widget.resizeWidth)
715
+ prefix += "e";
716
+ return prefix;
717
+ }
718
+
719
+ onMouseDown(e: React.MouseEvent | React.TouchEvent) {
720
+ let { instance } = this.props;
721
+ let { widget, data } = instance;
722
+
723
+ if (
724
+ widget.onMouseDown &&
725
+ instance.invoke("onMouseDown", e, instance) === false
726
+ )
727
+ return;
728
+
729
+ let prefix = this.getResizePrefix(e);
730
+ if (prefix) {
731
+ //e.preventDefault();
732
+ let rect = getTopLevelBoundingClientRect(this.el!);
733
+ let cursor = getCursorPos(e);
734
+ let captureData = {
735
+ prefix: prefix,
736
+ dl: cursor.clientX - rect.left,
737
+ dt: cursor.clientY - rect.top,
738
+ dr: cursor.clientX - rect.right,
739
+ db: cursor.clientY - rect.bottom,
740
+ rect: rect,
741
+ };
742
+ captureMouseOrTouch(
743
+ e,
744
+ this.onMouseMove.bind(this),
745
+ undefined,
746
+ captureData,
747
+ prefix + "-resize",
748
+ );
749
+ } else if (data.draggable) {
750
+ ddMouseDown(e);
751
+ }
752
+ //e.stopPropagation();
753
+ }
754
+
755
+ onBackdropClick(e: React.MouseEvent) {
756
+ e.stopPropagation();
757
+ let { instance } = this.props;
758
+ let { widget } = instance;
759
+
760
+ if (widget.onBackdropClick) instance.invoke("onBackdropClick", e, instance);
761
+
762
+ if (widget.backdrop) {
763
+ if (instance.dismiss) instance.dismiss();
764
+ } else if (widget.modal) {
765
+ FocusManager.focus(this.el!);
766
+ }
767
+ }
768
+
769
+ onMouseUp(e: React.MouseEvent | React.TouchEvent) {
770
+ ddMouseUp();
771
+ e.stopPropagation();
772
+ }
773
+
774
+ onMouseMove(e: MouseEvent, captureData: any) {
775
+ // handle dragging
776
+ let { instance } = this.props;
777
+ let { data, widget } = instance;
778
+ let detect = ddDetect(e);
779
+ if (data.draggable && detect) {
780
+ this.startMoveOperation(e);
781
+ return;
782
+ }
783
+
784
+ if (captureData && captureData.prefix) {
785
+ let { prefix, rect, dl, dt, dr, db } = captureData;
608
786
  let cursor = getCursorPos(e);
609
- let bounds = getTopLevelBoundingClientRect(this.el!);
610
- let leftMargin = cursor.clientX - bounds.left;
611
- let rightMargin = bounds.right - cursor.clientX;
612
- let topMargin = cursor.clientY - bounds.top;
613
- let bottomMargin = bounds.bottom - cursor.clientY;
614
- let prefix = "";
615
-
616
- if (topMargin >= 0 && topMargin < widget.resizeWidth) prefix += "n";
617
- else if (bottomMargin >= 0 && bottomMargin < widget.resizeWidth) prefix += "s";
618
-
619
- if (leftMargin >= 0 && leftMargin < widget.resizeWidth) prefix += "w";
620
- else if (rightMargin >= 0 && rightMargin < widget.resizeWidth) prefix += "e";
621
- return prefix;
622
- }
623
-
624
- onMouseDown(e: React.MouseEvent | React.TouchEvent) {
625
- let { instance } = this.props;
626
- let { widget, data } = instance;
627
-
628
- if (widget.onMouseDown && instance.invoke("onMouseDown", e, instance) === false) return;
629
787
 
788
+ if (prefix.indexOf("w") != -1)
789
+ this.setCustomStyle({
790
+ left: cursor.clientX - dl + "px",
791
+ width: rect.right - cursor.clientX + dl + "px",
792
+ right: "auto",
793
+ });
794
+
795
+ if (prefix.indexOf("n") != -1)
796
+ this.setCustomStyle({
797
+ top: cursor.clientY - dt + "px",
798
+ height: rect.bottom - cursor.clientY + dt + "px",
799
+ bottom: "auto",
800
+ });
801
+
802
+ if (prefix.indexOf("e") != -1)
803
+ this.setCustomStyle({
804
+ width: cursor.clientX - dr - rect.left + "px",
805
+ left: `${rect.left}px`,
806
+ right: "auto",
807
+ });
808
+
809
+ if (prefix.indexOf("s") != -1)
810
+ this.setCustomStyle({
811
+ height: cursor.clientY - db - rect.top + "px",
812
+ top: `${rect.top}px`,
813
+ bottom: "auto",
814
+ });
815
+
816
+ if (prefix.indexOf("w") >= 0 || prefix.indexOf("n") >= 0)
817
+ widget.handleMove(e, instance, this);
818
+
819
+ widget.handleResize(e, instance, this);
820
+ } else {
630
821
  let prefix = this.getResizePrefix(e);
631
- if (prefix) {
632
- //e.preventDefault();
633
- let rect = getTopLevelBoundingClientRect(this.el!);
634
- let cursor = getCursorPos(e);
635
- let captureData = {
636
- prefix: prefix,
637
- dl: cursor.clientX - rect.left,
638
- dt: cursor.clientY - rect.top,
639
- dr: cursor.clientX - rect.right,
640
- db: cursor.clientY - rect.bottom,
641
- rect: rect,
642
- };
643
- captureMouseOrTouch(e, this.onMouseMove.bind(this), undefined, captureData, prefix + "-resize");
644
- } else if (data.draggable) {
645
- ddMouseDown(e);
646
- }
647
- //e.stopPropagation();
648
- }
649
-
650
- onBackdropClick(e: React.MouseEvent) {
651
- e.stopPropagation();
652
- let { instance } = this.props;
653
- let { widget } = instance;
654
-
655
- if (widget.onBackdropClick) instance.invoke("onBackdropClick", e, instance);
656
-
657
- if (widget.backdrop) {
658
- if (instance.dismiss) instance.dismiss();
659
- } else if (widget.modal) {
660
- FocusManager.focus(this.el!);
661
- }
662
- }
822
+ this.setCustomStyle({
823
+ cursor: prefix ? prefix + "-resize" : undefined,
824
+ });
825
+ }
826
+ }
663
827
 
664
- onMouseUp(e: React.MouseEvent | React.TouchEvent) {
665
- ddMouseUp();
828
+ startMoveOperation(e: MouseEvent | React.MouseEvent | React.TouchEvent) {
829
+ if (this.el && !this.getResizePrefix(e)) {
666
830
  e.stopPropagation();
667
- }
831
+ let rect = getTopLevelBoundingClientRect(this.el);
832
+ let cursor = getCursorPos(e);
833
+ let data = {
834
+ dx: cursor.clientX - rect.left,
835
+ dy: cursor.clientY - rect.top,
836
+ };
668
837
 
669
- onMouseMove(e: MouseEvent, captureData: any) {
670
- // handle dragging
671
- let { instance } = this.props;
672
- let { data, widget } = instance;
673
- let detect = ddDetect(e);
674
- if (data.draggable && detect) {
675
- this.startMoveOperation(e);
676
- return;
677
- }
838
+ captureMouseOrTouch(
839
+ e,
840
+ this.onMove.bind(this),
841
+ undefined,
842
+ data,
843
+ getComputedStyle(e.target as HTMLElement).cursor,
844
+ );
845
+ }
846
+ }
678
847
 
679
- if (captureData && captureData.prefix) {
680
- let { prefix, rect, dl, dt, dr, db } = captureData;
681
- let cursor = getCursorPos(e);
682
-
683
- if (prefix.indexOf("w") != -1)
684
- this.setCustomStyle({
685
- left: cursor.clientX - dl + "px",
686
- width: rect.right - cursor.clientX + dl + "px",
687
- right: "auto",
688
- });
689
-
690
- if (prefix.indexOf("n") != -1)
691
- this.setCustomStyle({
692
- top: cursor.clientY - dt + "px",
693
- height: rect.bottom - cursor.clientY + dt + "px",
694
- bottom: "auto",
695
- });
696
-
697
- if (prefix.indexOf("e") != -1)
698
- this.setCustomStyle({
699
- width: cursor.clientX - dr - rect.left + "px",
700
- left: `${rect.left}px`,
701
- right: "auto",
702
- });
703
-
704
- if (prefix.indexOf("s") != -1)
705
- this.setCustomStyle({
706
- height: cursor.clientY - db - rect.top + "px",
707
- top: `${rect.top}px`,
708
- bottom: "auto",
709
- });
710
-
711
- if (prefix.indexOf("w") >= 0 || prefix.indexOf("n") >= 0) widget.handleMove(e, instance, this);
712
-
713
- widget.handleResize(e, instance, this);
714
- } else {
715
- let prefix = this.getResizePrefix(e);
716
- this.setCustomStyle({
717
- cursor: prefix ? prefix + "-resize" : undefined,
718
- });
719
- }
720
- }
721
-
722
- startMoveOperation(e: MouseEvent | React.MouseEvent | React.TouchEvent) {
723
- if (this.el && !this.getResizePrefix(e)) {
724
- e.stopPropagation();
725
- let rect = getTopLevelBoundingClientRect(this.el);
726
- let cursor = getCursorPos(e);
727
- let data = {
728
- dx: cursor.clientX - rect.left,
729
- dy: cursor.clientY - rect.top,
730
- };
731
-
732
- captureMouseOrTouch(
733
- e,
734
- this.onMove.bind(this),
735
- undefined,
736
- data,
737
- getComputedStyle(e.target as HTMLElement).cursor,
738
- );
739
- }
740
- }
741
-
742
- onMove(e: MouseEvent, data: any) {
743
- if (data) {
744
- let cursor = getCursorPos(e);
745
- e.preventDefault();
746
- this.setCustomStyle({
747
- left: cursor.clientX - data.dx + "px",
748
- top: cursor.clientY - data.dy + "px",
749
- right: "auto",
750
- bottom: "auto",
751
- });
752
-
753
- let { instance } = this.props;
754
- let { widget } = instance;
755
- widget.handleMove(e, instance, this);
756
- }
757
- }
848
+ onMove(e: MouseEvent, data: any) {
849
+ if (data) {
850
+ let cursor = getCursorPos(e);
851
+ e.preventDefault();
852
+ this.setCustomStyle({
853
+ left: cursor.clientX - data.dx + "px",
854
+ top: cursor.clientY - data.dy + "px",
855
+ right: "auto",
856
+ bottom: "auto",
857
+ });
758
858
 
759
- onBeforeDismiss() {
760
859
  let { instance } = this.props;
761
860
  let { widget } = instance;
861
+ widget.handleMove(e, instance, this);
862
+ }
863
+ }
864
+
865
+ onBeforeDismiss() {
866
+ let { instance } = this.props;
867
+ let { widget } = instance;
868
+
869
+ if (
870
+ widget.overlayWillDismiss &&
871
+ widget.overlayWillDismiss(instance, this) === false
872
+ )
873
+ return false;
874
+
875
+ this.dismissed = true;
876
+
877
+ //this.el might be null if visible is set to false
878
+ if (this.el) {
879
+ this.el.className = this.getOverlayCssClass();
880
+
881
+ // if (widget.animate)
882
+ // this.setState({
883
+ // animated: false
884
+ // });
885
+ }
886
+ return true;
887
+ }
888
+
889
+ componentDidMount() {
890
+ let { instance, subscribeToBeforeDismiss, parentEl } = this.props;
891
+ let { widget, data } = instance;
892
+
893
+ this.setZIndex(isNumber(data.zIndex) ? data.zIndex : ZIndexManager.next());
894
+
895
+ this.componentDidUpdate();
896
+ widget.overlayDidMount(instance, this);
897
+
898
+ if (this.containerEl) this.containerEl.style.removeProperty("display");
899
+ else if (parentEl) parentEl.style.removeProperty("display");
900
+
901
+ let childHasFocus = isSelfOrDescendant(this.el!, getActiveElement());
902
+
903
+ if (childHasFocus) oneFocusOut(this, this.el, this.onFocusOut.bind(this));
904
+ else {
905
+ if (
906
+ !widget.autoFocusFirstChild ||
907
+ !FocusManager.focusFirstChild(this.el!)
908
+ )
909
+ if (widget.focusable && widget.autoFocus) FocusManager.focus(this.el!);
910
+ }
911
+
912
+ instance.onBeforeDismiss = this.onBeforeDismiss.bind(this);
913
+
914
+ if (subscribeToBeforeDismiss) {
915
+ subscribeToBeforeDismiss(instance.onBeforeDismiss);
916
+ }
917
+
918
+ if (widget.animate) {
919
+ setTimeout(() => {
920
+ if (!this.unmounting)
921
+ this.setState({
922
+ animated: true,
923
+ });
924
+ }, 0);
925
+ }
926
+
927
+ if (widget.dismissOnPopState) {
928
+ this.onPopState = () => {
929
+ this.props.instance.dismiss?.();
930
+ };
931
+ window.addEventListener("popstate", this.onPopState);
932
+ }
933
+
934
+ if (this.shadowEl)
935
+ this.unsubscribeWheelBlock = addEventListenerWithOptions(
936
+ this.shadowEl,
937
+ "wheel",
938
+ (e) => {
939
+ if (e.shiftKey || e.ctrlKey) return;
940
+ //check if there is a scrollable element within the shadow or overlay contents
941
+ //such that its scrollbar is not at the very end
942
+ let scrollAllowed = false;
943
+ closest(e.target as Element, (el) => {
944
+ if (
945
+ (e.deltaY > 0 &&
946
+ el.scrollTop < el.scrollHeight - el.clientHeight) ||
947
+ (e.deltaY < 0 && el.scrollTop > 0)
948
+ ) {
949
+ scrollAllowed = true;
950
+ return true;
951
+ }
952
+ return el == e.currentTarget;
953
+ });
954
+ if (!scrollAllowed) e.preventDefault();
955
+ },
956
+ { passive: false },
957
+ );
958
+ }
762
959
 
763
- if (widget.overlayWillDismiss && widget.overlayWillDismiss(instance, this) === false) return false;
764
-
765
- this.dismissed = true;
766
-
767
- //this.el might be null if visible is set to false
768
- if (this.el) {
769
- this.el.className = this.getOverlayCssClass();
770
-
771
- // if (widget.animate)
772
- // this.setState({
773
- // animated: false
774
- // });
775
- }
776
- return true;
777
- }
778
-
779
- componentDidMount() {
780
- let { instance, subscribeToBeforeDismiss, parentEl } = this.props;
781
- let { widget, data } = instance;
782
-
783
- this.setZIndex(isNumber(data.zIndex) ? data.zIndex : ZIndexManager.next());
784
-
785
- this.componentDidUpdate();
786
- widget.overlayDidMount(instance, this);
787
-
788
- if (this.containerEl) this.containerEl.style.removeProperty("display");
789
- else if (parentEl) parentEl.style.removeProperty("display");
790
-
791
- let childHasFocus = isSelfOrDescendant(this.el!, getActiveElement());
792
-
793
- if (childHasFocus) oneFocusOut(this, this.el, this.onFocusOut.bind(this));
794
- else {
795
- if (!widget.autoFocusFirstChild || !FocusManager.focusFirstChild(this.el!))
796
- if (widget.focusable && widget.autoFocus) FocusManager.focus(this.el!);
797
- }
798
-
799
- instance.onBeforeDismiss = this.onBeforeDismiss.bind(this);
960
+ componentWillUnmount() {
961
+ if (this.onPopState)
962
+ window.removeEventListener("popstate", this.onPopState);
800
963
 
801
- if (subscribeToBeforeDismiss) {
802
- subscribeToBeforeDismiss(instance.onBeforeDismiss);
803
- }
964
+ if (this.unsubscribeWheelBlock) this.unsubscribeWheelBlock();
804
965
 
805
- if (widget.animate) {
806
- setTimeout(() => {
807
- if (!this.unmounting)
808
- this.setState({
809
- animated: true,
810
- });
811
- }, 0);
812
- }
966
+ offFocusOut(this);
967
+ this.unmounting = true;
813
968
 
814
- if (widget.dismissOnPopState) {
815
- this.onPopState = () => {
816
- this.props.instance.dismiss?.();
817
- };
818
- window.addEventListener("popstate", this.onPopState);
819
- }
969
+ let { widget } = this.props.instance;
970
+ let { baseClass, CSS } = widget;
820
971
 
972
+ // //we didn't have a chance to call onBeforeDismiss
973
+ if (this.state.animated && this.el) {
974
+ this.el.className = this.getOverlayCssClass();
821
975
  if (this.shadowEl)
822
- this.unsubscribeWheelBlock = addEventListenerWithOptions(
823
- this.shadowEl,
824
- "wheel",
825
- (e) => {
826
- if (e.shiftKey || e.ctrlKey) return;
827
- //check if there is a scrollable element within the shadow or overlay contents
828
- //such that its scrollbar is not at the very end
829
- let scrollAllowed = false;
830
- closest(e.target as Element, (el) => {
831
- if (
832
- (e.deltaY > 0 && el.scrollTop < el.scrollHeight - el.clientHeight) ||
833
- (e.deltaY < 0 && el.scrollTop > 0)
834
- ) {
835
- scrollAllowed = true;
836
- return true;
837
- }
838
- return el == e.currentTarget;
839
- });
840
- if (!scrollAllowed) e.preventDefault();
841
- },
842
- { passive: false },
843
- );
844
- }
845
-
846
- componentWillUnmount() {
847
- if (this.onPopState) window.removeEventListener("popstate", this.onPopState);
848
-
849
- if (this.unsubscribeWheelBlock) this.unsubscribeWheelBlock();
850
-
851
- offFocusOut(this);
852
- this.unmounting = true;
853
-
854
- let { widget } = this.props.instance;
855
- let { baseClass, CSS } = widget;
856
-
857
- // //we didn't have a chance to call onBeforeDismiss
858
- if (this.state.animated && this.el) {
859
- this.el.className = this.getOverlayCssClass();
860
- if (this.shadowEl)
861
- this.shadowEl.className = CSS.element(baseClass, "shadow", {
862
- animate: widget.animate,
863
- "animate-leave": true,
864
- });
976
+ this.shadowEl.className = CSS.element(baseClass, "shadow", {
977
+ animate: widget.animate,
978
+ "animate-leave": true,
979
+ });
980
+ }
981
+
982
+ widget.overlayWillUnmount(this.props.instance, this);
983
+
984
+ if (this.ownedEl) {
985
+ setTimeout(() => {
986
+ this.root?.unmount();
987
+ if (this.ownedEl?.parentNode)
988
+ this.ownedEl.parentNode.removeChild(this.ownedEl);
989
+ this.ownedEl = null;
990
+ }, widget.destroyDelay);
991
+ }
992
+
993
+ delete this.containerEl;
994
+ }
995
+
996
+ setZIndex(zIndex: number) {
997
+ if (this.shadowEl) this.shadowEl.style.zIndex = zIndex.toString();
998
+ this.setCustomStyle({
999
+ zIndex: zIndex.toString(),
1000
+ });
1001
+ }
1002
+
1003
+ setCustomStyle(style: Partial<CSSStyleDeclaration>) {
1004
+ Object.assign(this.customStyle, style);
1005
+ if (this.el) Object.assign(this.el.style, this.customStyle);
1006
+ }
1007
+
1008
+ getOverlayStyle() {
1009
+ let { data } = this.props.instance;
1010
+ return {
1011
+ ...data.style,
1012
+ ...this.customStyle,
1013
+ };
1014
+ }
1015
+
1016
+ setCSSState(mods: Record<string, boolean>) {
1017
+ let m: Record<string, boolean> = { ...this.state.mods };
1018
+ let changed = false;
1019
+ for (let k in mods)
1020
+ if (m[k] !== mods[k]) {
1021
+ m[k] = mods[k];
1022
+ changed = true;
865
1023
  }
866
1024
 
867
- widget.overlayWillUnmount(this.props.instance, this);
868
-
869
- if (this.ownedEl) {
870
- setTimeout(() => {
871
- this.root?.unmount();
872
- if (this.ownedEl?.parentNode) this.ownedEl.parentNode.removeChild(this.ownedEl);
873
- this.ownedEl = null;
874
- }, widget.destroyDelay);
875
- }
876
-
877
- delete this.containerEl;
878
- }
879
-
880
- setZIndex(zIndex: number) {
881
- if (this.shadowEl) this.shadowEl.style.zIndex = zIndex.toString();
882
- this.setCustomStyle({
883
- zIndex: zIndex.toString(),
1025
+ if (changed)
1026
+ this.setState({
1027
+ mods: mods,
884
1028
  });
885
- }
886
-
887
- setCustomStyle(style: Partial<CSSStyleDeclaration>) {
888
- Object.assign(this.customStyle, style);
889
- if (this.el) Object.assign(this.el.style, this.customStyle);
890
- }
891
-
892
- getOverlayStyle() {
893
- let { data } = this.props.instance;
894
- return {
895
- ...data.style,
896
- ...this.customStyle,
897
- };
898
- }
899
-
900
- setCSSState(mods: Record<string, boolean>) {
901
- let m: Record<string, boolean> = { ...this.state.mods };
902
- let changed = false;
903
- for (let k in mods)
904
- if (m[k] !== mods[k]) {
905
- m[k] = mods[k];
906
- changed = true;
907
- }
908
-
909
- if (changed)
910
- this.setState({
911
- mods: mods,
912
- });
913
- }
914
-
915
- getOverlayCssClass() {
916
- let { data, widget } = this.props.instance;
917
- let { CSS } = widget;
1029
+ }
1030
+
1031
+ getOverlayCssClass() {
1032
+ let { data, widget } = this.props.instance;
1033
+ let { CSS } = widget;
1034
+
1035
+ return (
1036
+ CSS.expand(
1037
+ data.classNames,
1038
+ CSS.state({
1039
+ ...this.state.mods,
1040
+ animated: this.state.animated && !this.unmounting && !this.dismissed,
1041
+ "animate-enter": this.state.animated && !this.dismissed,
1042
+ "animate-leave": widget.animate && this.dismissed,
1043
+ }),
1044
+ ) ?? ""
1045
+ );
1046
+ }
1047
+
1048
+ overlayDidUpdate() {
1049
+ if (this.el && !this.dismissed) {
1050
+ let { widget } = this.props.instance;
1051
+ widget.overlayDidUpdate(this.props.instance, this);
1052
+ this.el.className = this.getOverlayCssClass();
1053
+ Object.assign(this.el.style, this.getOverlayStyle());
1054
+ }
1055
+ }
1056
+
1057
+ componentDidUpdate() {
1058
+ if (this.containerEl && !VDOM.DOM.createPortal) {
1059
+ this.root = VDOM.DOM.createRoot(this.containerEl);
1060
+ this.root.render(this.renderOverlay());
1061
+ }
1062
+ this.overlayDidUpdate();
1063
+ }
1064
+ }
918
1065
 
919
- return (
920
- CSS.expand(
921
- data.classNames,
922
- CSS.state({
923
- ...this.state.mods,
924
- animated: this.state.animated && !this.unmounting && !this.dismissed,
925
- "animate-enter": this.state.animated && !this.dismissed,
926
- "animate-leave": widget.animate && this.dismissed,
927
- }),
928
- ) ?? ""
929
- );
930
- }
931
-
932
- overlayDidUpdate() {
933
- if (this.el && !this.dismissed) {
934
- let { widget } = this.props.instance;
935
- widget.overlayDidUpdate(this.props.instance, this);
936
- this.el.className = this.getOverlayCssClass();
937
- Object.assign(this.el.style, this.getOverlayStyle());
938
- }
939
- }
1066
+ interface OverlayBeaconProps {
1067
+ childrenFactory: (beacon: HTMLElement) => React.ReactNode;
1068
+ }
940
1069
 
941
- componentDidUpdate() {
942
- if (this.containerEl && !VDOM.DOM.createPortal) {
943
- this.root = VDOM.DOM.createRoot(this.containerEl);
944
- this.root.render(this.renderOverlay());
945
- }
946
- this.overlayDidUpdate();
947
- }
1070
+ export interface OverlayBeaconState {
1071
+ children?: React.ReactNode;
1072
+ }
1073
+
1074
+ export class OverlayBeacon extends VDOM.Component<
1075
+ OverlayBeaconProps,
1076
+ OverlayBeaconState
1077
+ > {
1078
+ el: HTMLElement | null;
1079
+ render() {
1080
+ return (
1081
+ <>
1082
+ <div
1083
+ ref={(el) => {
1084
+ this.el = el;
1085
+ }}
1086
+ style={{ position: "absolute", display: "none" }}
1087
+ />
1088
+ {this.state?.children}
1089
+ </>
1090
+ );
1091
+ }
1092
+
1093
+ componentDidMount(): void {
1094
+ this.setState({ children: this.props.childrenFactory(this.el!) });
1095
+ }
948
1096
  }