@tcn/ui 0.2.0 → 0.3.1

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 (341) hide show
  1. package/dist/Color-ASIRERSW-B4GaVKuQ.js +990 -0
  2. package/dist/Color-ASIRERSW-B4GaVKuQ.js.map +1 -0
  3. package/dist/WithTooltip-IO6J4KBT-B1oq93K5.js +1485 -0
  4. package/dist/WithTooltip-IO6J4KBT-B1oq93K5.js.map +1 -0
  5. package/dist/actions/__docs__/components/gallery.d.ts +8 -0
  6. package/dist/actions/__docs__/components/gallery.d.ts.map +1 -0
  7. package/dist/actions/__docs__/components/gallery.js +20 -0
  8. package/dist/actions/__docs__/components/gallery.js.map +1 -0
  9. package/dist/actions/__docs__/components/showcase.d.ts +27 -0
  10. package/dist/actions/__docs__/components/showcase.d.ts.map +1 -0
  11. package/dist/actions/__docs__/components/showcase.js +15 -0
  12. package/dist/actions/__docs__/components/showcase.js.map +1 -0
  13. package/dist/actions/button/base_button/base_button.d.ts +2 -0
  14. package/dist/actions/button/base_button/base_button.d.ts.map +1 -1
  15. package/dist/actions/button/base_button/base_button.js +18 -16
  16. package/dist/actions/button/base_button/base_button.js.map +1 -1
  17. package/dist/actions/button/button/button.js +6 -6
  18. package/dist/actions/button/button_group/button_group.js +1 -1
  19. package/dist/actions/button/select_group/select_group.js +13 -13
  20. package/dist/actions/button/select_group/single_select_group.js +6 -6
  21. package/dist/actions/button/slim_button/slim_button.js +2 -2
  22. package/dist/actions/types.d.ts +2 -0
  23. package/dist/actions/types.d.ts.map +1 -0
  24. package/dist/actions/types.js +2 -0
  25. package/dist/actions/types.js.map +1 -0
  26. package/dist/divider.module-FptFV0PX.js +5 -0
  27. package/dist/divider.module-FptFV0PX.js.map +1 -0
  28. package/dist/feedback/loading/loading.js +12 -12
  29. package/dist/feedback/loading/loading.js.map +1 -1
  30. package/dist/feedback/progress/progress_bar.js +1 -1
  31. package/dist/form/field/common/field_control/field_control.js +8 -8
  32. package/dist/form/field/common/status_input/status_input.js +6 -6
  33. package/dist/form/field/field.js +6 -6
  34. package/dist/form/field/h_field/h_field.js +11 -11
  35. package/dist/form/field/v_field/v_field.js +10 -10
  36. package/dist/form/field_set/field_set.js +3 -3
  37. package/dist/formatter-QJ4M4OGQ-DaIl2Wi_.js +6 -0
  38. package/dist/formatter-QJ4M4OGQ-DaIl2Wi_.js.map +1 -0
  39. package/dist/frame.css +1 -0
  40. package/dist/gallery.css +1 -0
  41. package/dist/inputs/checkbox/checkbox.js +11 -11
  42. package/dist/inputs/color_input/color_input.js +1 -1
  43. package/dist/inputs/color_input/color_input.js.map +1 -1
  44. package/dist/inputs/color_input/color_picker.js +6 -6
  45. package/dist/inputs/combo_box/combo_box.js +17 -17
  46. package/dist/inputs/date_picker/date_picker.js +19 -19
  47. package/dist/inputs/date_picker/date_picker_body.js +2 -2
  48. package/dist/inputs/date_picker/date_picker_input.js +20 -20
  49. package/dist/inputs/date_picker/date_picker_input.js.map +1 -1
  50. package/dist/inputs/date_picker/date_picker_year_input.js +1 -1
  51. package/dist/inputs/date_picker/date_picker_year_input.js.map +1 -1
  52. package/dist/inputs/date_picker/date_picker_year_selector.js +1 -1
  53. package/dist/inputs/input/input.js +5 -5
  54. package/dist/inputs/mask_input/key_capture_input.js +8 -8
  55. package/dist/inputs/mask_input/mask_input.js +5 -5
  56. package/dist/inputs/multi_combo_box/multi_combo_box.js +17 -17
  57. package/dist/inputs/multiselect/multiselect.js +14 -14
  58. package/dist/inputs/multiselect/multiselect_row.js +8 -8
  59. package/dist/inputs/phone_number_input/phone_number_input.js +12 -12
  60. package/dist/inputs/radio/radio.js +10 -10
  61. package/dist/inputs/radio/radio_row.js +3 -3
  62. package/dist/inputs/select/select.js +15 -15
  63. package/dist/inputs/slider/slider.js +11 -11
  64. package/dist/inputs/suggestions/suggestion_list.js +2 -2
  65. package/dist/inputs/suggestions/suggestion_list.js.map +1 -1
  66. package/dist/inputs/switch/switch.js +5 -5
  67. package/dist/inputs/textarea/textarea.js +7 -7
  68. package/dist/inputs/unit_input/unit_input.js +5 -5
  69. package/dist/layouts/body/h_body.js +7 -7
  70. package/dist/layouts/body/v_body.js +6 -6
  71. package/dist/layouts/column/column.js +17 -17
  72. package/dist/layouts/divider/divider.js +24 -23
  73. package/dist/layouts/divider/divider.js.map +1 -1
  74. package/dist/layouts/footer/footer.js +7 -7
  75. package/dist/layouts/grid/grid.js +24 -24
  76. package/dist/layouts/header/header.js +2 -2
  77. package/dist/layouts/index.d.ts +6 -5
  78. package/dist/layouts/index.d.ts.map +1 -1
  79. package/dist/layouts/index.js +28 -26
  80. package/dist/layouts/index.js.map +1 -1
  81. package/dist/layouts/list/item.js +2 -2
  82. package/dist/layouts/list/list.js +7 -7
  83. package/dist/layouts/list/section_header.js +6 -6
  84. package/dist/layouts/scaffold/scaffold.d.ts +9 -0
  85. package/dist/layouts/scaffold/scaffold.d.ts.map +1 -0
  86. package/dist/layouts/scaffold/scaffold.js +55 -0
  87. package/dist/layouts/scaffold/scaffold.js.map +1 -0
  88. package/dist/layouts/sidebar_end/sidebar_end.js +14 -14
  89. package/dist/layouts/sidebar_start/sidebar_start.js +10 -10
  90. package/dist/layouts/utility_bar/utility_bar.js +10 -10
  91. package/dist/modal.css +1 -1
  92. package/dist/overlay/frame/frame.d.ts.map +1 -1
  93. package/dist/overlay/frame/frame.js +22 -5
  94. package/dist/overlay/frame/frame.js.map +1 -1
  95. package/dist/overlay/index.d.ts +9 -2
  96. package/dist/overlay/index.d.ts.map +1 -1
  97. package/dist/overlay/index.js +22 -10
  98. package/dist/overlay/index.js.map +1 -1
  99. package/dist/overlay/menu/menu.d.ts +1 -1
  100. package/dist/overlay/menu/menu.d.ts.map +1 -1
  101. package/dist/overlay/menu/menu.js +36 -36
  102. package/dist/overlay/menu/menu.js.map +1 -1
  103. package/dist/overlay/popper/base/base_popper.d.ts +11 -0
  104. package/dist/overlay/popper/base/base_popper.d.ts.map +1 -0
  105. package/dist/overlay/popper/base/base_popper.js +27 -0
  106. package/dist/overlay/popper/base/base_popper.js.map +1 -0
  107. package/dist/overlay/popper/base/dismissal_decorator.d.ts +16 -0
  108. package/dist/overlay/popper/base/dismissal_decorator.d.ts.map +1 -0
  109. package/dist/overlay/popper/base/dismissal_decorator.js +69 -0
  110. package/dist/overlay/popper/base/dismissal_decorator.js.map +1 -0
  111. package/dist/overlay/popper/context_popper.d.ts +11 -0
  112. package/dist/overlay/popper/context_popper.d.ts.map +1 -0
  113. package/dist/overlay/popper/context_popper.js +33 -0
  114. package/dist/overlay/popper/context_popper.js.map +1 -0
  115. package/dist/overlay/popper/element_popper.d.ts +7 -0
  116. package/dist/overlay/popper/element_popper.d.ts.map +1 -0
  117. package/dist/overlay/popper/element_popper.js +33 -0
  118. package/dist/overlay/popper/element_popper.js.map +1 -0
  119. package/dist/overlay/popper/hooks/use_context_trigger.d.ts +7 -0
  120. package/dist/overlay/popper/hooks/use_context_trigger.d.ts.map +1 -0
  121. package/dist/overlay/popper/hooks/use_context_trigger.js +31 -0
  122. package/dist/overlay/popper/hooks/use_context_trigger.js.map +1 -0
  123. package/dist/overlay/popper/hooks/use_hover_trigger.d.ts +6 -0
  124. package/dist/overlay/popper/hooks/use_hover_trigger.d.ts.map +1 -0
  125. package/dist/overlay/popper/hooks/use_hover_trigger.js +17 -0
  126. package/dist/overlay/popper/hooks/use_hover_trigger.js.map +1 -0
  127. package/dist/overlay/popper/hooks/use_restore_focus.d.ts +2 -0
  128. package/dist/overlay/popper/hooks/use_restore_focus.d.ts.map +1 -0
  129. package/dist/overlay/popper/hooks/use_restore_focus.js +18 -0
  130. package/dist/overlay/popper/hooks/use_restore_focus.js.map +1 -0
  131. package/dist/overlay/popper/legacy/popper.d.ts.map +1 -0
  132. package/dist/overlay/popper/{popper.js → legacy/popper.js} +6 -6
  133. package/dist/overlay/popper/legacy/popper.js.map +1 -0
  134. package/dist/overlay/popper/preview_popper.d.ts +7 -0
  135. package/dist/overlay/popper/preview_popper.d.ts.map +1 -0
  136. package/dist/overlay/popper/preview_popper.js +46 -0
  137. package/dist/overlay/popper/preview_popper.js.map +1 -0
  138. package/dist/overlay/portal/portal_platform_context.js +4 -4
  139. package/dist/overlay/tethered/element_tethered.d.ts +8 -0
  140. package/dist/overlay/tethered/element_tethered.d.ts.map +1 -0
  141. package/dist/overlay/tethered/element_tethered.js +33 -0
  142. package/dist/overlay/tethered/element_tethered.js.map +1 -0
  143. package/dist/overlay/tethered/hooks/calculate_position.d.ts +19 -0
  144. package/dist/overlay/tethered/hooks/calculate_position.d.ts.map +1 -0
  145. package/dist/overlay/tethered/hooks/calculate_position.js +43 -0
  146. package/dist/overlay/tethered/hooks/calculate_position.js.map +1 -0
  147. package/dist/overlay/tethered/hooks/useTether.d.ts +19 -0
  148. package/dist/overlay/tethered/hooks/useTether.d.ts.map +1 -0
  149. package/dist/overlay/tethered/hooks/useTether.js +61 -0
  150. package/dist/overlay/tethered/hooks/useTether.js.map +1 -0
  151. package/dist/overlay/tethered/tethered.d.ts +20 -0
  152. package/dist/overlay/tethered/tethered.d.ts.map +1 -0
  153. package/dist/overlay/tethered/tethered.js +59 -0
  154. package/dist/overlay/tethered/tethered.js.map +1 -0
  155. package/dist/overlay/tethered/types.d.ts +3 -0
  156. package/dist/overlay/tethered/types.d.ts.map +1 -0
  157. package/dist/overlay/tethered/types.js +2 -0
  158. package/dist/overlay/tethered/types.js.map +1 -0
  159. package/dist/popper.css +1 -1
  160. package/dist/scaffold.css +1 -0
  161. package/dist/showcase-WfP6kBEb.js +58401 -0
  162. package/dist/showcase-WfP6kBEb.js.map +1 -0
  163. package/dist/showcase.css +1 -0
  164. package/dist/stacks/box/box.js +24 -24
  165. package/dist/stacks/h_collapsible_box.js +3 -3
  166. package/dist/stacks/h_stack.js +41 -41
  167. package/dist/stacks/spacer.js +11 -11
  168. package/dist/stacks/story_components/circle.js +10 -10
  169. package/dist/stacks/story_components/picture_placeholder.js +9 -9
  170. package/dist/stacks/story_components/rect.js +7 -7
  171. package/dist/stacks/story_components/style_box.js +4 -4
  172. package/dist/stacks/utils/use_is_collapsed.js +6 -6
  173. package/dist/stacks/v_collapsible_box.js +3 -3
  174. package/dist/stacks/v_stack.js +42 -42
  175. package/dist/stacks/z_stack.js +39 -39
  176. package/dist/surfaces/alert/alert.js +4 -4
  177. package/dist/surfaces/card/card.d.ts +2 -2
  178. package/dist/surfaces/card/card.d.ts.map +1 -1
  179. package/dist/surfaces/card/card.js +7 -7
  180. package/dist/surfaces/card/card.js.map +1 -1
  181. package/dist/surfaces/confirm/confirm.js +9 -9
  182. package/dist/surfaces/drawers/drawer_start/drawer_start.js +2 -2
  183. package/dist/surfaces/drawers/drawer_top/drawer_top.js +2 -2
  184. package/dist/surfaces/index.d.ts +2 -0
  185. package/dist/surfaces/index.d.ts.map +1 -1
  186. package/dist/surfaces/index.js +22 -18
  187. package/dist/surfaces/index.js.map +1 -1
  188. package/dist/surfaces/modal/modal.d.ts +3 -3
  189. package/dist/surfaces/modal/modal.d.ts.map +1 -1
  190. package/dist/surfaces/modal/modal.js +14 -14
  191. package/dist/surfaces/modal/modal.js.map +1 -1
  192. package/dist/surfaces/page/h_page.js +7 -7
  193. package/dist/surfaces/page/v_page.js +5 -5
  194. package/dist/surfaces/panel/h_panel.js +29 -30
  195. package/dist/surfaces/panel/h_panel.js.map +1 -1
  196. package/dist/surfaces/panel/v_panel.d.ts +3 -7
  197. package/dist/surfaces/panel/v_panel.d.ts.map +1 -1
  198. package/dist/surfaces/panel/v_panel.js +12 -54
  199. package/dist/surfaces/panel/v_panel.js.map +1 -1
  200. package/dist/surfaces/pop_confirm/pop_confirm.d.ts +5 -0
  201. package/dist/surfaces/pop_confirm/pop_confirm.d.ts.map +1 -0
  202. package/dist/surfaces/pop_confirm/pop_confirm.js +37 -0
  203. package/dist/surfaces/pop_confirm/pop_confirm.js.map +1 -0
  204. package/dist/surfaces/popconfirm/pop_confirm.d.ts +5 -0
  205. package/dist/surfaces/popconfirm/pop_confirm.d.ts.map +1 -0
  206. package/dist/surfaces/popconfirm/pop_confirm.js +13 -0
  207. package/dist/surfaces/popconfirm/pop_confirm.js.map +1 -0
  208. package/dist/surfaces/popover/popover.d.ts +1 -1
  209. package/dist/surfaces/popover/popover.d.ts.map +1 -1
  210. package/dist/surfaces/popover/popover.js +1 -1
  211. package/dist/surfaces/popover/popover.js.map +1 -1
  212. package/dist/surfaces/tooltip/tooltip.d.ts +10 -0
  213. package/dist/surfaces/tooltip/tooltip.d.ts.map +1 -0
  214. package/dist/surfaces/tooltip/tooltip.js +38 -0
  215. package/dist/surfaces/tooltip/tooltip.js.map +1 -0
  216. package/dist/surfaces/window/window.d.ts +3 -3
  217. package/dist/surfaces/window/window.d.ts.map +1 -1
  218. package/dist/surfaces/window/window.js +15 -13
  219. package/dist/surfaces/window/window.js.map +1 -1
  220. package/dist/syntaxhighlighter-IQDEPFLK-BX_eF8__.js +3777 -0
  221. package/dist/syntaxhighlighter-IQDEPFLK-BX_eF8__.js.map +1 -0
  222. package/dist/tethered.css +1 -0
  223. package/dist/themes/themes/ergo/ergo_theme.js +177 -206
  224. package/dist/themes/themes/ergo/ergo_theme.js.map +1 -1
  225. package/dist/tokens/badge/badge.js +9 -9
  226. package/dist/tokens/bubble/bubble.js +8 -8
  227. package/dist/tokens/chip/chip.js +3 -3
  228. package/dist/tooltip.css +1 -1
  229. package/dist/utility_bar.css +1 -1
  230. package/dist/utils/click_away_listener.d.ts +1 -0
  231. package/dist/utils/click_away_listener.d.ts.map +1 -1
  232. package/dist/utils/click_away_listener.js +12 -11
  233. package/dist/utils/click_away_listener.js.map +1 -1
  234. package/dist/utils/dnd/draggable/draggable.js +4 -4
  235. package/dist/utils/dnd/handle.js +8 -8
  236. package/dist/utils/focus_redirect.js +5 -5
  237. package/dist/utils/hooks/make_context_hook.js +4 -4
  238. package/dist/utils/hooks/use_media_query.js +2 -2
  239. package/dist/utils/hooks/use_media_query.js.map +1 -1
  240. package/dist/utils/index.d.ts +6 -5
  241. package/dist/utils/index.d.ts.map +1 -1
  242. package/dist/utils/index.js +26 -23
  243. package/dist/utils/index.js.map +1 -1
  244. package/dist/utils/mouse_leave_region.d.ts +8 -0
  245. package/dist/utils/mouse_leave_region.d.ts.map +1 -0
  246. package/dist/utils/mouse_leave_region.js +26 -0
  247. package/dist/utils/mouse_leave_region.js.map +1 -0
  248. package/dist/utils/types/dimensions.d.ts +11 -1
  249. package/dist/utils/types/dimensions.d.ts.map +1 -1
  250. package/package.json +3 -3
  251. package/src/actions/__docs__/actions.mdx +131 -0
  252. package/src/actions/__docs__/actions.stories.tsx +309 -0
  253. package/src/actions/__docs__/components/gallery.module.css +6 -0
  254. package/src/actions/__docs__/components/gallery.tsx +28 -0
  255. package/src/actions/__docs__/components/showcase.module.css +55 -0
  256. package/src/actions/__docs__/components/showcase.tsx +121 -0
  257. package/src/actions/button/base_button/base_button.tsx +5 -1
  258. package/src/actions/types.ts +6 -0
  259. package/src/inputs/color_input/color_input.tsx +1 -1
  260. package/src/inputs/date_picker/date_picker_input.tsx +1 -1
  261. package/src/inputs/date_picker/date_picker_year_input.tsx +1 -1
  262. package/src/inputs/suggestions/suggestion_list.tsx +1 -1
  263. package/src/layouts/index.ts +7 -5
  264. package/src/layouts/scaffold/scaffold.module.css +5 -0
  265. package/src/layouts/scaffold/scaffold.tsx +60 -0
  266. package/src/layouts/utility_bar/utility_bar.module.css +0 -3
  267. package/src/overlay/frame/frame.module.css +5 -0
  268. package/src/overlay/frame/frame.stories.tsx +1 -1
  269. package/src/overlay/frame/frame.tsx +19 -3
  270. package/src/overlay/index.ts +29 -2
  271. package/src/overlay/menu/menu.tsx +1 -1
  272. package/src/overlay/popper/__stories__/base_args.ts +75 -0
  273. package/src/overlay/popper/__stories__/context_popper.stories.tsx +77 -0
  274. package/src/overlay/popper/__stories__/element_popper.stories.tsx +80 -0
  275. package/src/overlay/popper/__stories__/preview_popper.stories.tsx +73 -0
  276. package/src/overlay/popper/base/base_popper.tsx +55 -0
  277. package/src/overlay/popper/base/dismissal_decorator.tsx +80 -0
  278. package/src/overlay/popper/context_popper.tsx +43 -0
  279. package/src/overlay/popper/element_popper.tsx +42 -0
  280. package/src/overlay/popper/hooks/use_context_trigger.ts +50 -0
  281. package/src/overlay/popper/hooks/use_hover_trigger.ts +24 -0
  282. package/src/overlay/popper/hooks/use_restore_focus.ts +16 -0
  283. package/src/overlay/popper/{popper.stories.tsx → legacy/popper.stories.tsx} +11 -5
  284. package/src/overlay/popper/{popper.tsx → legacy/popper.tsx} +3 -2
  285. package/src/overlay/popper/preview_popper.tsx +54 -0
  286. package/src/overlay/tethered/__stories__/element/element_tethered.stories.tsx +57 -0
  287. package/src/overlay/tethered/__stories__/element/element_tethered_stories.module.css +14 -0
  288. package/src/overlay/tethered/__stories__/shared/base_story_config.ts +52 -0
  289. package/src/overlay/tethered/__stories__/shared/components/sb_point.module.css +20 -0
  290. package/src/overlay/tethered/__stories__/shared/components/sb_point.tsx +34 -0
  291. package/src/overlay/tethered/__stories__/shared/components/sb_reference_points.tsx +54 -0
  292. package/src/overlay/tethered/__stories__/tethered/tethered.stories.tsx +90 -0
  293. package/src/overlay/tethered/__stories__/tethered/tethered_stories.module.css +25 -0
  294. package/src/overlay/tethered/element_tethered.tsx +62 -0
  295. package/src/overlay/tethered/hooks/calculate_position.ts +110 -0
  296. package/src/overlay/tethered/hooks/useTether.ts +85 -0
  297. package/src/overlay/tethered/tethered.module.css +8 -0
  298. package/src/overlay/tethered/tethered.tsx +72 -0
  299. package/src/overlay/tethered/types.ts +2 -0
  300. package/src/stacks/h_stack.stories.tsx +2 -2
  301. package/src/stacks/v_stack.stories.tsx +2 -2
  302. package/src/surfaces/card/card.stories.tsx +64 -0
  303. package/src/surfaces/card/card.tsx +4 -4
  304. package/src/surfaces/card/card_stories.module.css +13 -0
  305. package/src/surfaces/index.ts +2 -0
  306. package/src/surfaces/modal/__stories__/modal.stories.tsx +12 -1
  307. package/src/surfaces/modal/modal.module.css +2 -2
  308. package/src/surfaces/modal/modal.tsx +14 -12
  309. package/src/surfaces/panel/__stories__/panel.stories.tsx +1 -1
  310. package/src/surfaces/panel/v_panel.tsx +8 -53
  311. package/src/surfaces/pop_confirm/pop_confirm.stories.tsx +70 -0
  312. package/src/surfaces/pop_confirm/pop_confirm.tsx +30 -0
  313. package/src/surfaces/popconfirm/pop_confirm.tsx +18 -0
  314. package/src/surfaces/popover/popover.tsx +1 -1
  315. package/src/surfaces/tooltip/tooltip.stories.tsx +54 -0
  316. package/src/surfaces/tooltip/tooltip.tsx +59 -0
  317. package/src/surfaces/window/window.stories.tsx +15 -1
  318. package/src/surfaces/window/window.tsx +16 -12
  319. package/src/themes/themes/ergo/__stories__/components/tone_picker/sb_tone_picker.tsx +7 -9
  320. package/src/themes/themes/ergo/__stories__/material.stories.tsx +2 -6
  321. package/src/themes/themes/ergo/__stories__/sb_materials.module.css +29 -21
  322. package/src/themes/themes/ergo/ergo_theme.css +177 -206
  323. package/src/utils/click_away_listener.tsx +1 -1
  324. package/src/utils/index.ts +7 -5
  325. package/src/utils/mouse_leave_region.tsx +38 -0
  326. package/src/utils/types/dimensions.ts +13 -1
  327. package/tsconfig.json +3 -0
  328. package/dist/overlay/popper/popper.d.ts.map +0 -1
  329. package/dist/overlay/popper/popper.js.map +0 -1
  330. package/dist/overlay/tooltip/tooltip.d.ts +0 -7
  331. package/dist/overlay/tooltip/tooltip.d.ts.map +0 -1
  332. package/dist/overlay/tooltip/tooltip.js +0 -20
  333. package/dist/overlay/tooltip/tooltip.js.map +0 -1
  334. package/dist/panel.module-DwGKncon.js +0 -5
  335. package/dist/panel.module-DwGKncon.js.map +0 -1
  336. package/src/overlay/tooltip/tooltip.stories.tsx +0 -22
  337. package/src/overlay/tooltip/tooltip.tsx +0 -24
  338. /package/dist/{panel.css → h_panel.css} +0 -0
  339. /package/dist/overlay/popper/{popper.d.ts → legacy/popper.d.ts} +0 -0
  340. /package/src/overlay/popper/{popper.module.css → legacy/popper.module.css} +0 -0
  341. /package/src/{overlay → surfaces}/tooltip/tooltip.module.css +0 -0
@@ -0,0 +1,50 @@
1
+ import { useCallback, useLayoutEffect, useState } from 'react';
2
+ import type { Rectangle } from '../../../utils/types/dimensions.js';
3
+
4
+ function getContextMenuRectangle(
5
+ element: HTMLElement | null,
6
+ mouseEvent: MouseEvent
7
+ ): Rectangle | null {
8
+ if (!element) return null;
9
+
10
+ const position = { x: mouseEvent.clientX, y: mouseEvent.clientY };
11
+
12
+ return {
13
+ position,
14
+ dimensions: {
15
+ width: 8,
16
+ height: 8,
17
+ },
18
+ };
19
+ }
20
+
21
+ export function useContextTrigger(anchorElement: React.RefObject<HTMLElement>) {
22
+ const [isOpen, setIsOpen] = useState(false);
23
+ const [rectangle, setRectangle] = useState<Rectangle | null>(null);
24
+
25
+ const close = useCallback(() => {
26
+ setIsOpen(false);
27
+ }, []);
28
+
29
+ const handleContextMenu = useCallback(
30
+ (e: MouseEvent) => {
31
+ e.preventDefault();
32
+ setRectangle(getContextMenuRectangle(anchorElement.current, e));
33
+ setIsOpen(true);
34
+ },
35
+ [anchorElement]
36
+ );
37
+
38
+ useLayoutEffect(() => {
39
+ const element = anchorElement.current;
40
+ if (!element) return;
41
+
42
+ element.addEventListener('contextmenu', handleContextMenu);
43
+
44
+ return () => {
45
+ element.removeEventListener('contextmenu', handleContextMenu);
46
+ };
47
+ }, [anchorElement, handleContextMenu]);
48
+
49
+ return { isOpen, close, rectangle };
50
+ }
@@ -0,0 +1,24 @@
1
+ import { useCallback, useLayoutEffect, useState } from 'react';
2
+
3
+ export function usePreviewElement(anchorElement: React.RefObject<HTMLElement>) {
4
+ const [isOpen, setIsOpen] = useState(false);
5
+ const close = useCallback(() => {
6
+ setIsOpen(false);
7
+ }, []);
8
+
9
+ const open = useCallback(() => setIsOpen(true), []);
10
+
11
+ // Open on hover on the anchor element
12
+ useLayoutEffect(() => {
13
+ const anchor = anchorElement.current;
14
+ if (!anchor) return;
15
+
16
+ anchor.addEventListener('mouseenter', open);
17
+
18
+ return () => {
19
+ anchor.removeEventListener('mouseenter', open);
20
+ };
21
+ }, [anchorElement, open]);
22
+
23
+ return { isOpen, close, open };
24
+ }
@@ -0,0 +1,16 @@
1
+ import { useLayoutEffect, useRef } from 'react';
2
+
3
+ export function useRestoreFocus(open: boolean, restoreFocus: boolean) {
4
+ const activeElementRef = useRef<HTMLElement | null>(null);
5
+
6
+ useLayoutEffect(() => {
7
+ if (open) {
8
+ activeElementRef.current = window.document.activeElement as HTMLElement;
9
+ } else {
10
+ const restoreToElement = activeElementRef.current;
11
+ requestAnimationFrame(() => {
12
+ restoreFocus && restoreToElement?.focus();
13
+ });
14
+ }
15
+ }, [open, restoreFocus]);
16
+ }
@@ -1,11 +1,11 @@
1
1
  import { Meta } from '@storybook/react-vite';
2
- import { BodyText } from '../../typography/index.js';
2
+ import { BodyText } from '../../../typography/index.js';
3
3
  import React, { useLayoutEffect, useRef, useState } from 'react';
4
4
  import { Popper as PopperComponent, PopperProps } from './popper.js';
5
- import { HStack } from '../../stacks/h_stack.js';
6
- import { StyleBox } from '../../stacks/story_components/style_box.js';
7
- import { VStack } from '../../stacks/v_stack.js';
8
- import { ZStack } from '../../stacks/z_stack.js';
5
+ import { HStack } from '../../../stacks/h_stack.js';
6
+ import { StyleBox } from '../../../stacks/story_components/style_box.js';
7
+ import { VStack } from '../../../stacks/v_stack.js';
8
+ import { ZStack } from '../../../stacks/z_stack.js';
9
9
 
10
10
  type PopoverStoryProps = Omit<PopperProps, 'anchorElement' | 'open' | 'onClose'> & {
11
11
  clickAwayRefs?: React.RefObject<HTMLElement | null>[];
@@ -72,6 +72,11 @@ const meta: Meta<typeof PopperComponent> = {
72
72
  defaultValue: false,
73
73
  description: 'Whether to display a veil when the popper is open.',
74
74
  },
75
+ isScrollAwayException: {
76
+ control: { type: 'boolean' },
77
+ defaultValue: false,
78
+ description: 'Whether to scroll away the popper when the scroll area is scrolled.',
79
+ },
75
80
  },
76
81
  };
77
82
 
@@ -106,6 +111,7 @@ export function Popper(props: PopoverStoryProps) {
106
111
  horizontalOffset={props.horizontalOffset}
107
112
  restoreFocus={props.restoreFocus}
108
113
  veil={props.veil}
114
+ isScrollAwayException={props.isScrollAwayException}
109
115
  >
110
116
  <StyleBox
111
117
  className="surface-primary"
@@ -1,6 +1,6 @@
1
- import { ClickAwayListener, ScrollAwayListener } from '../../utils/index.js';
1
+ import { ClickAwayListener, ScrollAwayListener } from '../../../utils/index.js';
2
2
  import React, { useLayoutEffect, useRef, useState } from 'react';
3
- import { Portal } from '../portal/portal.js';
3
+ import { Portal } from '../../portal/portal.js';
4
4
  import styles from './popper.module.css';
5
5
 
6
6
  export interface PopperProps {
@@ -23,6 +23,7 @@ export interface PopperProps {
23
23
  disableClickAway?: boolean;
24
24
  }
25
25
 
26
+ // This component is being phased out in favor of ElementPopper - need to ensure parity beforehand.
26
27
  export function Popper({
27
28
  anchorElement,
28
29
  verticalAnchor = 'bottom',
@@ -0,0 +1,54 @@
1
+ import { forwardRef, useRef, type PropsWithChildren } from 'react';
2
+ import { BasePopper, type BasePopperProps } from './base/base_popper.js';
3
+ import { useForkRef } from '../../utils/index.js';
4
+ import {
5
+ ElementTethered,
6
+ type ElementTetheredProps,
7
+ } from '../tethered/element_tethered.js';
8
+ import { usePreviewElement } from './hooks/use_hover_trigger.js';
9
+ import { PopperDismissal } from './base/dismissal_decorator.js';
10
+
11
+ export type PreviewPopperProps = Omit<BasePopperProps, 'open' | 'onDismissal'> &
12
+ ElementTetheredProps;
13
+
14
+ export const PreviewPopper = forwardRef<
15
+ HTMLElement,
16
+ PropsWithChildren<PreviewPopperProps>
17
+ >(function PreviewPopper(
18
+ {
19
+ anchorElement,
20
+ restoreFocus,
21
+ children,
22
+ acceptedRefs = [],
23
+ isException,
24
+ dismissals = [PopperDismissal.MOUSE_LEAVE],
25
+ ...elementTetheredProps
26
+ },
27
+ ref
28
+ ) {
29
+ const popperRef = useRef<HTMLElement>(null);
30
+ const merged = useForkRef(ref, popperRef);
31
+
32
+ const { isOpen, close } = usePreviewElement(anchorElement);
33
+
34
+ return (
35
+ <>
36
+ <BasePopper
37
+ restoreFocus={restoreFocus}
38
+ open={isOpen}
39
+ onDismissal={close}
40
+ isException={isException}
41
+ dismissals={dismissals}
42
+ acceptedRefs={[popperRef, ...acceptedRefs]}
43
+ >
44
+ <ElementTethered
45
+ ref={merged}
46
+ anchorElement={anchorElement}
47
+ {...elementTetheredProps}
48
+ >
49
+ {children}
50
+ </ElementTethered>
51
+ </BasePopper>
52
+ </>
53
+ );
54
+ });
@@ -0,0 +1,57 @@
1
+ import { useRef } from 'react';
2
+ import { HStack, VStack } from '../../../../stacks/index.js';
3
+ import { ElementTethered, type ElementTetheredProps } from '../../element_tethered.js';
4
+ import { tetheredArgTypes, tetheredArgs } from '../shared/base_story_config.js';
5
+
6
+ import styles from './element_tethered_stories.module.css';
7
+
8
+ export default {
9
+ title: 'Overlays/Element Tethered',
10
+ component: ElementTethered,
11
+ tags: ['autodocs'],
12
+ argTypes: tetheredArgTypes,
13
+ args: tetheredArgs,
14
+ };
15
+
16
+ type ElementTetheredStoryProps = Omit<ElementTetheredProps, 'anchorElement'>;
17
+
18
+ export const Default = (args: ElementTetheredStoryProps) => {
19
+ const anchorElement = useRef<HTMLDivElement>(null);
20
+
21
+ return (
22
+ <VStack height="100%" width="100%" hAlign="center" vAlign="center">
23
+ <VStack
24
+ className={styles.container}
25
+ hAlign="center"
26
+ vAlign="center"
27
+ height="500px"
28
+ width="500px"
29
+ >
30
+ <HStack
31
+ padding="16px"
32
+ width="auto"
33
+ height="auto"
34
+ ref={anchorElement}
35
+ className={styles.anchor}
36
+ hAlign="center"
37
+ vAlign="center"
38
+ >
39
+ Anchor Element
40
+ </HStack>
41
+
42
+ <ElementTethered anchorElement={anchorElement} {...args}>
43
+ <HStack
44
+ className={styles.tethered}
45
+ width="auto"
46
+ height="auto"
47
+ padding="16px"
48
+ hAlign="center"
49
+ vAlign="center"
50
+ >
51
+ Tethered to Anchor Element
52
+ </HStack>
53
+ </ElementTethered>
54
+ </VStack>
55
+ </VStack>
56
+ );
57
+ };
@@ -0,0 +1,14 @@
1
+ .container {
2
+ background-color: #f0eee7; /* eggshell */
3
+ }
4
+
5
+ .anchor {
6
+ background: white;
7
+ border-radius: 8px;
8
+ }
9
+
10
+ .tethered {
11
+ background: white;
12
+ border-radius: 8px;
13
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
14
+ }
@@ -0,0 +1,52 @@
1
+ import type { ArgTypes } from '@storybook/react-vite';
2
+ import type { TetheredProps } from '../../tethered.js';
3
+
4
+ type TetheredStoryArgs = Pick<
5
+ TetheredProps,
6
+ | 'verticalAnchor'
7
+ | 'horizontalAnchor'
8
+ | 'verticalOrigin'
9
+ | 'horizontalOrigin'
10
+ | 'verticalOffset'
11
+ | 'horizontalOffset'
12
+ >;
13
+
14
+ export const tetheredArgTypes: ArgTypes<TetheredStoryArgs> = {
15
+ verticalAnchor: {
16
+ options: ['top', 'center', 'bottom'],
17
+ control: { type: 'radio' },
18
+ description: 'The anchor to position the popper vertically.',
19
+ },
20
+ horizontalAnchor: {
21
+ options: ['start', 'center', 'end'],
22
+ control: { type: 'radio' },
23
+ description: 'The anchor to position the popper horizontally.',
24
+ },
25
+ verticalOrigin: {
26
+ options: ['top', 'center', 'bottom'],
27
+ control: { type: 'radio' },
28
+ description: 'The origin to position the popper vertically.',
29
+ },
30
+ horizontalOrigin: {
31
+ options: ['start', 'center', 'end'],
32
+ control: { type: 'radio' },
33
+ description: 'The origin to position the popper horizontally.',
34
+ },
35
+ verticalOffset: {
36
+ control: { type: 'number' },
37
+ description: 'The offset to position the popper vertically.',
38
+ },
39
+ horizontalOffset: {
40
+ control: { type: 'number' },
41
+ description: 'The offset to position the popper horizontally.',
42
+ },
43
+ };
44
+
45
+ export const tetheredArgs: TetheredStoryArgs = {
46
+ verticalAnchor: 'top',
47
+ horizontalAnchor: 'center',
48
+ verticalOrigin: 'bottom',
49
+ horizontalOrigin: 'center',
50
+ verticalOffset: 0,
51
+ horizontalOffset: 0,
52
+ };
@@ -0,0 +1,20 @@
1
+ .point {
2
+ position: absolute;
3
+ left: var(--point-x);
4
+ top: var(--point-y);
5
+ border-radius: 50%;
6
+ background: black;
7
+ pointer-events: none;
8
+ opacity: 0.5;
9
+ translate: -50% -50%;
10
+ width: var(--point-size);
11
+ height: var(--point-size);
12
+ }
13
+
14
+ .point[data-selected="true"] {
15
+ width: calc(var(--point-size) * 1.5);
16
+ height: calc(var(--point-size) * 1.5);
17
+ opacity: 1;
18
+ background: var(--accent-color);
19
+ border: 1px solid white;
20
+ }
@@ -0,0 +1,34 @@
1
+ import { Box, type BoxProps } from '../../../../../stacks/index.js';
2
+ import type { Position } from '../../../../../utils/index.js';
3
+
4
+ import styles from './sb_point.module.css';
5
+
6
+ export interface SB_TetheredPointProps extends BoxProps {
7
+ point: Position;
8
+ isSelected: boolean;
9
+ size?: number;
10
+ }
11
+
12
+ export const SB_TetheredPoint: React.FC<SB_TetheredPointProps> = ({
13
+ point,
14
+ isSelected,
15
+ style,
16
+ size = 8,
17
+ ...rest
18
+ }) => {
19
+ return (
20
+ <Box
21
+ className={styles.point}
22
+ data-selected={isSelected}
23
+ style={
24
+ {
25
+ ...style,
26
+ '--point-size': `${size}px`,
27
+ '--point-x': `${point.x}px`,
28
+ '--point-y': `${point.y}px`,
29
+ } as React.CSSProperties
30
+ }
31
+ {...rest}
32
+ />
33
+ );
34
+ };
@@ -0,0 +1,54 @@
1
+ import type { Dimensions } from '../../../../../utils/index.js';
2
+ import type { VerticalTether, HorizontalTether } from '../../../types.js';
3
+ import { SB_TetheredPoint } from './sb_point.js';
4
+
5
+ type PointValue = `${VerticalTether}-${HorizontalTether}`;
6
+
7
+ type SBReferencePoint = {
8
+ x: number;
9
+ y: number;
10
+ value: PointValue;
11
+ };
12
+
13
+ const mid = (value: number) => value / 2;
14
+
15
+ const getPoints = (dimensions: Dimensions): SBReferencePoint[] => {
16
+ const mWidth = mid(dimensions.width);
17
+ const mHeight = mid(dimensions.height);
18
+ const { width, height } = dimensions;
19
+ return [
20
+ { x: 0, y: 0, value: 'top-start' },
21
+ { x: mWidth, y: 0, value: 'top-center' },
22
+ { x: width, y: 0, value: 'top-end' },
23
+ { x: 0, y: mHeight, value: 'center-start' },
24
+ { x: mWidth, y: mHeight, value: 'center-center' },
25
+ { x: width, y: mHeight, value: 'center-end' },
26
+ { x: 0, y: height, value: 'bottom-start' },
27
+ { x: mWidth, y: height, value: 'bottom-center' },
28
+ { x: width, y: height, value: 'bottom-end' },
29
+ ];
30
+ };
31
+
32
+ const getAnchorValue = (
33
+ verticalAnchor: VerticalTether,
34
+ horizontalAnchor: HorizontalTether
35
+ ): PointValue => {
36
+ return `${verticalAnchor}-${horizontalAnchor}`;
37
+ };
38
+
39
+ export const SBReferencePoints: React.FC<{
40
+ dimensions: Dimensions;
41
+ vertical: VerticalTether;
42
+ horizontal: HorizontalTether;
43
+ }> = ({ dimensions, vertical, horizontal }) => {
44
+ const anchorPoints = getPoints(dimensions);
45
+ return (
46
+ <>
47
+ {anchorPoints.map((point, index) => {
48
+ const value = getAnchorValue(vertical, horizontal);
49
+ const isSelected = value === point.value;
50
+ return <SB_TetheredPoint key={index} point={point} isSelected={isSelected} />;
51
+ })}
52
+ </>
53
+ );
54
+ };
@@ -0,0 +1,90 @@
1
+ import { Box, VStack } from '../../../../stacks/index.js';
2
+ import type { Rectangle } from '../../../../utils/index.js';
3
+ import { Portal } from '../../../portal/portal.js';
4
+ import { Tethered, type TetheredProps } from '../../tethered.js';
5
+ import { tetheredArgTypes, tetheredArgs } from '../shared/base_story_config.js';
6
+ import { SBReferencePoints } from '../shared/components/sb_reference_points.js';
7
+
8
+ import styles from './tethered_stories.module.css';
9
+
10
+ export default {
11
+ title: 'Overlays/Tethered',
12
+ component: Tethered,
13
+ tags: ['autodocs'],
14
+ argTypes: tetheredArgTypes,
15
+ args: tetheredArgs,
16
+ };
17
+
18
+ type TetheredStoryProps = Omit<TetheredProps, 'anchor'>;
19
+
20
+ export const Default = (args: TetheredStoryProps) => {
21
+ const anchorRect: Rectangle = {
22
+ dimensions: {
23
+ width: 150,
24
+ height: 75,
25
+ },
26
+ position: {
27
+ x: 150,
28
+ y: 200,
29
+ },
30
+ };
31
+
32
+ const tetherRect = {
33
+ dimensions: {
34
+ width: 200,
35
+ height: 50,
36
+ },
37
+ position: {
38
+ x: 100,
39
+ y: 100,
40
+ },
41
+ };
42
+
43
+ return (
44
+ <VStack height="100%" width="100%" hAlign="center" vAlign="center">
45
+ <VStack
46
+ className={styles.container}
47
+ hAlign="center"
48
+ vAlign="center"
49
+ height="500px"
50
+ width="500px"
51
+ >
52
+ <Portal>
53
+ <Box
54
+ className={styles.anchor}
55
+ height={anchorRect.dimensions.height}
56
+ width={anchorRect.dimensions.width}
57
+ style={
58
+ {
59
+ '--anchor-top': `${anchorRect.position.y}px`,
60
+ '--anchor-left': `${anchorRect.position.x}px`,
61
+ } as React.CSSProperties
62
+ }
63
+ >
64
+ Anchor Rectangle
65
+ <SBReferencePoints
66
+ dimensions={anchorRect.dimensions}
67
+ vertical={args.verticalAnchor || 'top'}
68
+ horizontal={args.horizontalAnchor || 'start'}
69
+ />
70
+ </Box>
71
+ </Portal>
72
+
73
+ <Tethered anchor={anchorRect} {...args}>
74
+ <Box
75
+ className={styles.tether}
76
+ height={tetherRect.dimensions.height}
77
+ width={tetherRect.dimensions.width}
78
+ >
79
+ Tether to Anchor Rectangle
80
+ <SBReferencePoints
81
+ dimensions={tetherRect.dimensions}
82
+ vertical={args.verticalOrigin || 'top'}
83
+ horizontal={args.horizontalOrigin || 'start'}
84
+ />
85
+ </Box>
86
+ </Tethered>
87
+ </VStack>
88
+ </VStack>
89
+ );
90
+ };
@@ -0,0 +1,25 @@
1
+ .container {
2
+ background-color: grey;
3
+ position: relative;
4
+ }
5
+
6
+ .anchor {
7
+ background-color: blue;
8
+ display: flex;
9
+ flex-direction: column;
10
+ align-items: center;
11
+ justify-content: center;
12
+ color: white;
13
+ position: absolute;
14
+ top: var(--anchor-top);
15
+ left: var(--anchor-left);
16
+ }
17
+
18
+ .tether {
19
+ background-color: green;
20
+ display: flex;
21
+ flex-direction: column;
22
+ align-items: center;
23
+ justify-content: center;
24
+ color: white;
25
+ }
@@ -0,0 +1,62 @@
1
+ import { forwardRef, useLayoutEffect, useState, type PropsWithChildren } from 'react';
2
+ import { type Rectangle } from '../../utils/index.js';
3
+ import { Tethered, type TetheredProps } from './tethered.js';
4
+
5
+ export interface ElementTetheredProps extends Omit<TetheredProps, 'anchor'> {
6
+ anchorElement: React.RefObject<HTMLElement>;
7
+ }
8
+
9
+ function getElementRect(element: HTMLElement | null): Rectangle | null {
10
+ if (!element) return null;
11
+
12
+ const clientRect = element.getBoundingClientRect();
13
+
14
+ return {
15
+ position: { x: clientRect.left, y: clientRect.top },
16
+ dimensions: {
17
+ width: clientRect.width,
18
+ height: clientRect.height,
19
+ },
20
+ };
21
+ }
22
+
23
+ export const ElementTethered = forwardRef<
24
+ HTMLElement,
25
+ PropsWithChildren<ElementTetheredProps>
26
+ >(function ElementTether({ anchorElement, children, ...rest }, ref) {
27
+ const [rectangle, setRectangle] = useState<Rectangle | null>(null);
28
+
29
+ useLayoutEffect(() => {
30
+ const element = anchorElement.current;
31
+ if (!element) return;
32
+
33
+ const update = () => {
34
+ setRectangle(getElementRect(element));
35
+ };
36
+
37
+ update();
38
+
39
+ // Track size/position changes of the anchor element via ResizeObserver
40
+ const resizeObserver = new ResizeObserver(update);
41
+ resizeObserver.observe(element);
42
+
43
+ // Track scroll-induced position changes
44
+ // TODO: might need to bypass react state here (setRectangle on scroll event) - to an OV or setting css variables/attributes directly
45
+ // This is a slight lag - not a huge deal, but could be improved.
46
+ window.addEventListener('scroll', update, true);
47
+ // Track window resize-induced position changes
48
+ window.addEventListener('resize', update);
49
+
50
+ return () => {
51
+ resizeObserver.disconnect();
52
+ window.removeEventListener('scroll', update, true);
53
+ window.removeEventListener('resize', update);
54
+ };
55
+ }, [anchorElement]);
56
+
57
+ return (
58
+ <Tethered ref={ref} anchor={rectangle} {...rest}>
59
+ {children}
60
+ </Tethered>
61
+ );
62
+ });