@lar-works/design-system 0.0.0-stage → 0.1.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 (555) hide show
  1. package/README.md +24 -2
  2. package/dist/actions/Button.d.ts +25 -0
  3. package/dist/actions/Button.js +55 -0
  4. package/dist/actions/Button.js.map +1 -0
  5. package/dist/actions/ButtonLink.d.ts +21 -0
  6. package/dist/actions/ButtonLink.js +40 -0
  7. package/dist/actions/ButtonLink.js.map +1 -0
  8. package/dist/actions/IconButton.d.ts +14 -0
  9. package/dist/actions/IconButton.js +29 -0
  10. package/dist/actions/IconButton.js.map +1 -0
  11. package/dist/actions/ThemeSwitch.d.ts +7 -0
  12. package/dist/actions/ThemeSwitch.js +42 -0
  13. package/dist/actions/ThemeSwitch.js.map +1 -0
  14. package/dist/actions/index.d.ts +5 -0
  15. package/dist/collections/CollectionSectionHeader.d.ts +5 -0
  16. package/dist/collections/CollectionSectionHeader.js +18 -0
  17. package/dist/collections/CollectionSectionHeader.js.map +1 -0
  18. package/dist/collections/CollectionState.d.ts +37 -0
  19. package/dist/collections/CollectionState.js +69 -0
  20. package/dist/collections/CollectionState.js.map +1 -0
  21. package/dist/collections/CollectionTokens.d.ts +16 -0
  22. package/dist/collections/CollectionTokens.js +19 -0
  23. package/dist/collections/CollectionTokens.js.map +1 -0
  24. package/dist/collections/CollectionViewport.js +36 -0
  25. package/dist/collections/CollectionViewport.js.map +1 -0
  26. package/dist/collections/DataRow.d.ts +23 -0
  27. package/dist/collections/DataRow.js +57 -0
  28. package/dist/collections/DataRow.js.map +1 -0
  29. package/dist/collections/ResultList.d.ts +29 -0
  30. package/dist/collections/ResultList.js +128 -0
  31. package/dist/collections/ResultList.js.map +1 -0
  32. package/dist/collections/ScrollRow.d.ts +23 -0
  33. package/dist/collections/ScrollRow.js +59 -0
  34. package/dist/collections/ScrollRow.js.map +1 -0
  35. package/dist/collections/VirtualGrid.d.ts +14 -0
  36. package/dist/collections/VirtualGrid.js +71 -0
  37. package/dist/collections/VirtualGrid.js.map +1 -0
  38. package/dist/collections/VirtualList.d.ts +34 -0
  39. package/dist/collections/VirtualList.js +128 -0
  40. package/dist/collections/VirtualList.js.map +1 -0
  41. package/dist/collections/index.d.ts +10 -0
  42. package/dist/collections/useCollectionMotion.d.ts +3 -0
  43. package/dist/collections/useCollectionMotion.js +34 -0
  44. package/dist/collections/useCollectionMotion.js.map +1 -0
  45. package/dist/collections/useScrollRow.d.ts +17 -0
  46. package/dist/collections/useScrollRow.js +63 -0
  47. package/dist/collections/useScrollRow.js.map +1 -0
  48. package/dist/display/ActivityCard.d.ts +17 -0
  49. package/dist/display/ActivityCard.js +58 -0
  50. package/dist/display/ActivityCard.js.map +1 -0
  51. package/dist/display/Artwork.d.ts +25 -0
  52. package/dist/display/Artwork.js +97 -0
  53. package/dist/display/Artwork.js.map +1 -0
  54. package/dist/display/Avatar.d.ts +5 -0
  55. package/dist/display/Avatar.js +13 -0
  56. package/dist/display/Avatar.js.map +1 -0
  57. package/dist/display/Badge.d.ts +10 -0
  58. package/dist/display/Badge.js +28 -0
  59. package/dist/display/Badge.js.map +1 -0
  60. package/dist/display/BadgeList.d.ts +11 -0
  61. package/dist/display/BadgeList.js +20 -0
  62. package/dist/display/BadgeList.js.map +1 -0
  63. package/dist/display/BrandMark.d.ts +21 -0
  64. package/dist/display/BrandMark.js +60 -0
  65. package/dist/display/BrandMark.js.map +1 -0
  66. package/dist/display/ChangeList.d.ts +16 -0
  67. package/dist/display/ChangeList.js +56 -0
  68. package/dist/display/ChangeList.js.map +1 -0
  69. package/dist/display/CheckList.d.ts +10 -0
  70. package/dist/display/CheckList.js +25 -0
  71. package/dist/display/CheckList.js.map +1 -0
  72. package/dist/display/CodeBlock.d.ts +6 -0
  73. package/dist/display/CodeBlock.js +12 -0
  74. package/dist/display/CodeBlock.js.map +1 -0
  75. package/dist/display/CopyButton.d.ts +9 -0
  76. package/dist/display/CopyButton.js +59 -0
  77. package/dist/display/CopyButton.js.map +1 -0
  78. package/dist/display/DataTable.d.ts +35 -0
  79. package/dist/display/DataTable.js +53 -0
  80. package/dist/display/DataTable.js.map +1 -0
  81. package/dist/display/DetailHero.d.ts +39 -0
  82. package/dist/display/DetailHero.js +146 -0
  83. package/dist/display/DetailHero.js.map +1 -0
  84. package/dist/display/DetailList.d.ts +15 -0
  85. package/dist/display/DetailList.js +53 -0
  86. package/dist/display/DetailList.js.map +1 -0
  87. package/dist/display/DeviceCard.d.ts +18 -0
  88. package/dist/display/DeviceCard.js +48 -0
  89. package/dist/display/DeviceCard.js.map +1 -0
  90. package/dist/display/Identity.d.ts +14 -0
  91. package/dist/display/Identity.js +54 -0
  92. package/dist/display/Identity.js.map +1 -0
  93. package/dist/display/ImageCard.d.ts +22 -0
  94. package/dist/display/ImageCard.js +63 -0
  95. package/dist/display/ImageCard.js.map +1 -0
  96. package/dist/display/ImagePicker.d.ts +30 -0
  97. package/dist/display/ImagePicker.js +108 -0
  98. package/dist/display/ImagePicker.js.map +1 -0
  99. package/dist/display/InfoBox.d.ts +15 -0
  100. package/dist/display/InfoBox.js +41 -0
  101. package/dist/display/InfoBox.js.map +1 -0
  102. package/dist/display/InsetPanel.d.ts +13 -0
  103. package/dist/display/InsetPanel.js +26 -0
  104. package/dist/display/InsetPanel.js.map +1 -0
  105. package/dist/display/ItemAction.d.ts +10 -0
  106. package/dist/display/ItemAction.js +35 -0
  107. package/dist/display/ItemAction.js.map +1 -0
  108. package/dist/display/Kbd.d.ts +6 -0
  109. package/dist/display/Kbd.js +12 -0
  110. package/dist/display/Kbd.js.map +1 -0
  111. package/dist/display/KindIcon.d.ts +8 -0
  112. package/dist/display/KindIcon.js +15 -0
  113. package/dist/display/KindIcon.js.map +1 -0
  114. package/dist/display/NoticeCard.d.ts +24 -0
  115. package/dist/display/NoticeCard.js +59 -0
  116. package/dist/display/NoticeCard.js.map +1 -0
  117. package/dist/display/PairingList.d.ts +19 -0
  118. package/dist/display/PairingList.js +53 -0
  119. package/dist/display/PairingList.js.map +1 -0
  120. package/dist/display/PathList.d.ts +9 -0
  121. package/dist/display/PathList.js +21 -0
  122. package/dist/display/PathList.js.map +1 -0
  123. package/dist/display/PeoplePreview.d.ts +16 -0
  124. package/dist/display/PeoplePreview.js +41 -0
  125. package/dist/display/PeoplePreview.js.map +1 -0
  126. package/dist/display/PropertySheet.d.ts +56 -0
  127. package/dist/display/PropertySheet.js +150 -0
  128. package/dist/display/PropertySheet.js.map +1 -0
  129. package/dist/display/QrCode.d.ts +6 -0
  130. package/dist/display/QrCode.js +47 -0
  131. package/dist/display/QrCode.js.map +1 -0
  132. package/dist/display/RadioChoice.d.ts +9 -0
  133. package/dist/display/RadioChoice.js +28 -0
  134. package/dist/display/RadioChoice.js.map +1 -0
  135. package/dist/display/RatingLink.d.ts +10 -0
  136. package/dist/display/RatingLink.js +80 -0
  137. package/dist/display/RatingLink.js.map +1 -0
  138. package/dist/display/ResourceCard.d.ts +20 -0
  139. package/dist/display/ResourceCard.js +200 -0
  140. package/dist/display/ResourceCard.js.map +1 -0
  141. package/dist/display/RowList.d.ts +28 -0
  142. package/dist/display/RowList.js +76 -0
  143. package/dist/display/RowList.js.map +1 -0
  144. package/dist/display/StackedMeter.d.ts +28 -0
  145. package/dist/display/StackedMeter.js +48 -0
  146. package/dist/display/StackedMeter.js.map +1 -0
  147. package/dist/display/StatTile.d.ts +13 -0
  148. package/dist/display/StatTile.js +35 -0
  149. package/dist/display/StatTile.js.map +1 -0
  150. package/dist/display/StepList.d.ts +5 -0
  151. package/dist/display/StepList.js +12 -0
  152. package/dist/display/StepList.js.map +1 -0
  153. package/dist/display/TextPreview.d.ts +14 -0
  154. package/dist/display/TextPreview.js +46 -0
  155. package/dist/display/TextPreview.js.map +1 -0
  156. package/dist/display/TimeSeriesChart.d.ts +19 -0
  157. package/dist/display/TimeSeriesChart.js +163 -0
  158. package/dist/display/TimeSeriesChart.js.map +1 -0
  159. package/dist/display/ToneTile.js +12 -0
  160. package/dist/display/ToneTile.js.map +1 -0
  161. package/dist/display/index.d.ts +38 -0
  162. package/dist/feedback/Alert.d.ts +15 -0
  163. package/dist/feedback/Alert.js +19 -0
  164. package/dist/feedback/Alert.js.map +1 -0
  165. package/dist/feedback/AsyncState.d.ts +16 -0
  166. package/dist/feedback/AsyncState.js +29 -0
  167. package/dist/feedback/AsyncState.js.map +1 -0
  168. package/dist/feedback/ErrorNotification.d.ts +8 -0
  169. package/dist/feedback/ErrorNotification.js +20 -0
  170. package/dist/feedback/ErrorNotification.js.map +1 -0
  171. package/dist/feedback/Notifications.d.ts +2 -0
  172. package/dist/feedback/Notifications.js +9 -0
  173. package/dist/feedback/Notifications.js.map +1 -0
  174. package/dist/feedback/ProgressStatusRow.d.ts +23 -0
  175. package/dist/feedback/ProgressStatusRow.js +74 -0
  176. package/dist/feedback/ProgressStatusRow.js.map +1 -0
  177. package/dist/feedback/SkeletonLoader.d.ts +19 -0
  178. package/dist/feedback/SkeletonLoader.js +59 -0
  179. package/dist/feedback/SkeletonLoader.js.map +1 -0
  180. package/dist/feedback/StatusIndicator.d.ts +9 -0
  181. package/dist/feedback/StatusIndicator.js +28 -0
  182. package/dist/feedback/StatusIndicator.js.map +1 -0
  183. package/dist/feedback/StatusPopoverContent.d.ts +13 -0
  184. package/dist/feedback/StatusPopoverContent.js +50 -0
  185. package/dist/feedback/StatusPopoverContent.js.map +1 -0
  186. package/dist/feedback/StatusRow.d.ts +16 -0
  187. package/dist/feedback/StatusRow.js +60 -0
  188. package/dist/feedback/StatusRow.js.map +1 -0
  189. package/dist/feedback/index.d.ts +11 -0
  190. package/dist/feedback/index.js +11 -0
  191. package/dist/forms/Checkbox.d.ts +10 -0
  192. package/dist/forms/Checkbox.js +48 -0
  193. package/dist/forms/Checkbox.js.map +1 -0
  194. package/dist/forms/Field.d.ts +5 -0
  195. package/dist/forms/Field.js +15 -0
  196. package/dist/forms/Field.js.map +1 -0
  197. package/dist/forms/FormControlStyles.js +14 -0
  198. package/dist/forms/FormControlStyles.js.map +1 -0
  199. package/dist/forms/FormSection.d.ts +48 -0
  200. package/dist/forms/FormSection.js +142 -0
  201. package/dist/forms/FormSection.js.map +1 -0
  202. package/dist/forms/InlineFields.d.ts +13 -0
  203. package/dist/forms/InlineFields.js +24 -0
  204. package/dist/forms/InlineFields.js.map +1 -0
  205. package/dist/forms/Input.d.ts +5 -0
  206. package/dist/forms/Input.js +18 -0
  207. package/dist/forms/Input.js.map +1 -0
  208. package/dist/forms/OptionSelect.d.ts +21 -0
  209. package/dist/forms/OptionSelect.js +28 -0
  210. package/dist/forms/OptionSelect.js.map +1 -0
  211. package/dist/forms/RadioGroup.d.ts +5 -0
  212. package/dist/forms/RadioGroup.js +35 -0
  213. package/dist/forms/RadioGroup.js.map +1 -0
  214. package/dist/forms/Select.d.ts +6 -0
  215. package/dist/forms/Select.js +36 -0
  216. package/dist/forms/Select.js.map +1 -0
  217. package/dist/forms/Switch.d.ts +4 -0
  218. package/dist/forms/Switch.js +16 -0
  219. package/dist/forms/Switch.js.map +1 -0
  220. package/dist/forms/TagInput.d.ts +19 -0
  221. package/dist/forms/TagInput.js +60 -0
  222. package/dist/forms/TagInput.js.map +1 -0
  223. package/dist/forms/Textarea.d.ts +4 -0
  224. package/dist/forms/Textarea.js +15 -0
  225. package/dist/forms/Textarea.js.map +1 -0
  226. package/dist/forms/index.d.ts +12 -0
  227. package/dist/foundations/DesignSystemProvider.d.ts +64 -0
  228. package/dist/foundations/DesignSystemProvider.js +66 -0
  229. package/dist/foundations/DesignSystemProvider.js.map +1 -0
  230. package/dist/foundations/KeyboardFocus.d.ts +9 -0
  231. package/dist/foundations/KeyboardFocus.js +10 -0
  232. package/dist/foundations/KeyboardFocus.js.map +1 -0
  233. package/dist/foundations/KeyboardShortcut.d.ts +5 -0
  234. package/dist/foundations/KeyboardShortcut.js +10 -0
  235. package/dist/foundations/KeyboardShortcut.js.map +1 -0
  236. package/dist/foundations/Theme.d.ts +14 -0
  237. package/dist/foundations/Theme.js +54 -0
  238. package/dist/foundations/Theme.js.map +1 -0
  239. package/dist/foundations/index.d.ts +5 -0
  240. package/dist/icons/BrandIcons.d.ts +3 -0
  241. package/dist/icons/BrandIcons.js +14 -0
  242. package/dist/icons/BrandIcons.js.map +1 -0
  243. package/dist/icons/index.d.ts +3 -0
  244. package/dist/icons/index.js +2 -0
  245. package/dist/icons.d.ts +4 -0
  246. package/dist/icons.js +2 -0
  247. package/dist/index.d.ts +133 -0
  248. package/dist/index.js +125 -0
  249. package/dist/layout/AppShell.d.ts +11 -0
  250. package/dist/layout/AppShell.js +46 -0
  251. package/dist/layout/AppShell.js.map +1 -0
  252. package/dist/layout/AuthLayout.d.ts +11 -0
  253. package/dist/layout/AuthLayout.js +48 -0
  254. package/dist/layout/AuthLayout.js.map +1 -0
  255. package/dist/layout/ContentContainer.d.ts +9 -0
  256. package/dist/layout/ContentContainer.js +15 -0
  257. package/dist/layout/ContentContainer.js.map +1 -0
  258. package/dist/layout/Flow.d.ts +26 -0
  259. package/dist/layout/Flow.js +65 -0
  260. package/dist/layout/Flow.js.map +1 -0
  261. package/dist/layout/PageLayout.d.ts +12 -0
  262. package/dist/layout/PageLayout.js +31 -0
  263. package/dist/layout/PageLayout.js.map +1 -0
  264. package/dist/layout/PageSection.d.ts +43 -0
  265. package/dist/layout/PageSection.js +63 -0
  266. package/dist/layout/PageSection.js.map +1 -0
  267. package/dist/layout/ScrollArea.d.ts +4 -0
  268. package/dist/layout/ScrollArea.js +11 -0
  269. package/dist/layout/ScrollArea.js.map +1 -0
  270. package/dist/layout/Section.d.ts +12 -0
  271. package/dist/layout/Section.js +36 -0
  272. package/dist/layout/Section.js.map +1 -0
  273. package/dist/layout/Site.d.ts +41 -0
  274. package/dist/layout/Site.js +157 -0
  275. package/dist/layout/Site.js.map +1 -0
  276. package/dist/layout/TitleBar.d.ts +28 -0
  277. package/dist/layout/TitleBar.js +83 -0
  278. package/dist/layout/TitleBar.js.map +1 -0
  279. package/dist/layout/WorkspaceActionsHeader.d.ts +8 -0
  280. package/dist/layout/WorkspaceActionsHeader.js +18 -0
  281. package/dist/layout/WorkspaceActionsHeader.js.map +1 -0
  282. package/dist/layout/index.d.ts +19 -0
  283. package/dist/layout/index.js +19 -0
  284. package/dist/layout/sidebar/SidebarNavigationItem.d.ts +10 -0
  285. package/dist/layout/sidebar/SidebarNavigationItem.js +36 -0
  286. package/dist/layout/sidebar/SidebarNavigationItem.js.map +1 -0
  287. package/dist/layout/sidebar/SidebarPane.d.ts +13 -0
  288. package/dist/layout/sidebar/SidebarPane.js +30 -0
  289. package/dist/layout/sidebar/SidebarPane.js.map +1 -0
  290. package/dist/layout/toolbar/CommandPaletteTrigger.d.ts +11 -0
  291. package/dist/layout/toolbar/CommandPaletteTrigger.js +46 -0
  292. package/dist/layout/toolbar/CommandPaletteTrigger.js.map +1 -0
  293. package/dist/layout/toolbar/ToolbarStatusGroup.d.ts +5 -0
  294. package/dist/layout/toolbar/ToolbarStatusGroup.js +14 -0
  295. package/dist/layout/toolbar/ToolbarStatusGroup.js.map +1 -0
  296. package/dist/layout/toolbar/ToolbarStatusItem.d.ts +9 -0
  297. package/dist/layout/toolbar/ToolbarStatusItem.js +18 -0
  298. package/dist/layout/toolbar/ToolbarStatusItem.js.map +1 -0
  299. package/dist/navigation/ArtworkTabs.d.ts +18 -0
  300. package/dist/navigation/ArtworkTabs.js +72 -0
  301. package/dist/navigation/ArtworkTabs.js.map +1 -0
  302. package/dist/navigation/Breadcrumbs.d.ts +13 -0
  303. package/dist/navigation/Breadcrumbs.js +32 -0
  304. package/dist/navigation/Breadcrumbs.js.map +1 -0
  305. package/dist/navigation/CollectionBrowseSelector.d.ts +22 -0
  306. package/dist/navigation/CollectionBrowseSelector.js +70 -0
  307. package/dist/navigation/CollectionBrowseSelector.js.map +1 -0
  308. package/dist/navigation/CollectionViewToggle.d.ts +12 -0
  309. package/dist/navigation/CollectionViewToggle.js +36 -0
  310. package/dist/navigation/CollectionViewToggle.js.map +1 -0
  311. package/dist/navigation/DrilldownBrowseSelector.d.ts +31 -0
  312. package/dist/navigation/DrilldownBrowseSelector.js +174 -0
  313. package/dist/navigation/DrilldownBrowseSelector.js.map +1 -0
  314. package/dist/navigation/FolderSelector.d.ts +24 -0
  315. package/dist/navigation/FolderSelector.js +142 -0
  316. package/dist/navigation/FolderSelector.js.map +1 -0
  317. package/dist/navigation/TabKeys.js +13 -0
  318. package/dist/navigation/TabKeys.js.map +1 -0
  319. package/dist/navigation/ViewTabs.d.ts +19 -0
  320. package/dist/navigation/ViewTabs.js +48 -0
  321. package/dist/navigation/ViewTabs.js.map +1 -0
  322. package/dist/navigation/index.d.ts +8 -0
  323. package/dist/overlays/ActionModal.d.ts +21 -0
  324. package/dist/overlays/ActionModal.js +48 -0
  325. package/dist/overlays/ActionModal.js.map +1 -0
  326. package/dist/overlays/CommandPalette.d.ts +43 -0
  327. package/dist/overlays/CommandPalette.js +163 -0
  328. package/dist/overlays/CommandPalette.js.map +1 -0
  329. package/dist/overlays/Drawer.d.ts +19 -0
  330. package/dist/overlays/Drawer.js +83 -0
  331. package/dist/overlays/Drawer.js.map +1 -0
  332. package/dist/overlays/DropdownMenu.d.ts +47 -0
  333. package/dist/overlays/DropdownMenu.js +58 -0
  334. package/dist/overlays/DropdownMenu.js.map +1 -0
  335. package/dist/overlays/ImageViewer.d.ts +21 -0
  336. package/dist/overlays/ImageViewer.js +82 -0
  337. package/dist/overlays/ImageViewer.js.map +1 -0
  338. package/dist/overlays/Modal.d.ts +36 -0
  339. package/dist/overlays/Modal.js +149 -0
  340. package/dist/overlays/Modal.js.map +1 -0
  341. package/dist/overlays/Popover.d.ts +19 -0
  342. package/dist/overlays/Popover.js +26 -0
  343. package/dist/overlays/Popover.js.map +1 -0
  344. package/dist/overlays/Tooltip.d.ts +12 -0
  345. package/dist/overlays/Tooltip.js +54 -0
  346. package/dist/overlays/Tooltip.js.map +1 -0
  347. package/dist/overlays/index.d.ts +9 -0
  348. package/dist/overlays/useModalAutoFocus.js +84 -0
  349. package/dist/overlays/useModalAutoFocus.js.map +1 -0
  350. package/dist/overlays/useScrollFade.js +43 -0
  351. package/dist/overlays/useScrollFade.js.map +1 -0
  352. package/dist/showcase/CallToAction.d.ts +11 -0
  353. package/dist/showcase/CallToAction.js +54 -0
  354. package/dist/showcase/CallToAction.js.map +1 -0
  355. package/dist/showcase/Cards.d.ts +34 -0
  356. package/dist/showcase/Cards.js +122 -0
  357. package/dist/showcase/Cards.js.map +1 -0
  358. package/dist/showcase/Devices.d.ts +72 -0
  359. package/dist/showcase/Devices.js +249 -0
  360. package/dist/showcase/Devices.js.map +1 -0
  361. package/dist/showcase/FeatureRow.d.ts +30 -0
  362. package/dist/showcase/FeatureRow.js +91 -0
  363. package/dist/showcase/FeatureRow.js.map +1 -0
  364. package/dist/showcase/Hero.d.ts +15 -0
  365. package/dist/showcase/Hero.js +73 -0
  366. package/dist/showcase/Hero.js.map +1 -0
  367. package/dist/showcase/PhotoSearchConcept.d.ts +14 -0
  368. package/dist/showcase/PhotoSearchConcept.js +43 -0
  369. package/dist/showcase/PhotoSearchConcept.js.map +1 -0
  370. package/dist/showcase/Platforms.d.ts +15 -0
  371. package/dist/showcase/Platforms.js +48 -0
  372. package/dist/showcase/Platforms.js.map +1 -0
  373. package/dist/showcase/ProductBand.d.ts +38 -0
  374. package/dist/showcase/ProductBand.js +120 -0
  375. package/dist/showcase/ProductBand.js.map +1 -0
  376. package/dist/showcase/Roadmap.d.ts +21 -0
  377. package/dist/showcase/Roadmap.js +111 -0
  378. package/dist/showcase/Roadmap.js.map +1 -0
  379. package/dist/showcase/RouteDiagram.d.ts +14 -0
  380. package/dist/showcase/RouteDiagram.js +57 -0
  381. package/dist/showcase/RouteDiagram.js.map +1 -0
  382. package/dist/showcase/ServerUnit.d.ts +50 -0
  383. package/dist/showcase/ServerUnit.js +175 -0
  384. package/dist/showcase/ServerUnit.js.map +1 -0
  385. package/dist/showcase/Stage.d.ts +46 -0
  386. package/dist/showcase/Stage.js +106 -0
  387. package/dist/showcase/Stage.js.map +1 -0
  388. package/dist/showcase/Status.d.ts +30 -0
  389. package/dist/showcase/Status.js +84 -0
  390. package/dist/showcase/Status.js.map +1 -0
  391. package/dist/showcase/StepFlow.d.ts +13 -0
  392. package/dist/showcase/StepFlow.js +47 -0
  393. package/dist/showcase/StepFlow.js.map +1 -0
  394. package/dist/showcase/index.d.ts +15 -0
  395. package/dist/testing.d.ts +5 -0
  396. package/dist/testing.js +43 -0
  397. package/dist/testing.js.map +1 -0
  398. package/dist/typography/Link.d.ts +21 -0
  399. package/dist/typography/Link.js +60 -0
  400. package/dist/typography/Link.js.map +1 -0
  401. package/dist/typography/Typography.d.ts +53 -0
  402. package/dist/typography/Typography.js +67 -0
  403. package/dist/typography/Typography.js.map +1 -0
  404. package/dist/typography/index.d.ts +4 -0
  405. package/dist/typography/index.js +4 -0
  406. package/package.json +80 -3
  407. package/src/actions/Button.tsx +68 -0
  408. package/src/actions/ButtonLink.tsx +75 -0
  409. package/src/actions/IconButton.tsx +55 -0
  410. package/src/actions/ThemeSwitch.tsx +46 -0
  411. package/src/actions/index.ts +4 -0
  412. package/src/collections/CollectionSectionHeader.tsx +13 -0
  413. package/src/collections/CollectionState.tsx +76 -0
  414. package/src/collections/CollectionTokens.ts +12 -0
  415. package/src/collections/CollectionViewport.ts +40 -0
  416. package/src/collections/DataRow.tsx +79 -0
  417. package/src/collections/ResultList.tsx +164 -0
  418. package/src/collections/ScrollRow.tsx +90 -0
  419. package/src/collections/VirtualGrid.tsx +92 -0
  420. package/src/collections/VirtualList.tsx +224 -0
  421. package/src/collections/index.ts +10 -0
  422. package/src/collections/useCollectionMotion.ts +42 -0
  423. package/src/collections/useScrollRow.ts +64 -0
  424. package/src/display/ActivityCard.tsx +76 -0
  425. package/src/display/Artwork.tsx +140 -0
  426. package/src/display/Avatar.tsx +7 -0
  427. package/src/display/Badge.tsx +33 -0
  428. package/src/display/BadgeList.tsx +25 -0
  429. package/src/display/BrandMark.tsx +72 -0
  430. package/src/display/ChangeList.tsx +41 -0
  431. package/src/display/CheckList.tsx +27 -0
  432. package/src/display/CodeBlock.tsx +12 -0
  433. package/src/display/CopyButton.tsx +77 -0
  434. package/src/display/DataTable.tsx +80 -0
  435. package/src/display/DetailHero.tsx +191 -0
  436. package/src/display/DetailList.tsx +74 -0
  437. package/src/display/DeviceCard.tsx +49 -0
  438. package/src/display/Identity.tsx +56 -0
  439. package/src/display/ImageCard.tsx +102 -0
  440. package/src/display/ImagePicker.tsx +149 -0
  441. package/src/display/InfoBox.tsx +48 -0
  442. package/src/display/InsetPanel.tsx +37 -0
  443. package/src/display/ItemAction.tsx +53 -0
  444. package/src/display/Kbd.tsx +6 -0
  445. package/src/display/KindIcon.tsx +15 -0
  446. package/src/display/NoticeCard.tsx +77 -0
  447. package/src/display/PairingList.tsx +55 -0
  448. package/src/display/PathList.tsx +16 -0
  449. package/src/display/PeoplePreview.tsx +66 -0
  450. package/src/display/PropertySheet.tsx +180 -0
  451. package/src/display/QrCode.tsx +47 -0
  452. package/src/display/RadioChoice.tsx +34 -0
  453. package/src/display/RatingLink.tsx +76 -0
  454. package/src/display/ResourceCard.tsx +201 -0
  455. package/src/display/RowList.tsx +110 -0
  456. package/src/display/StackedMeter.tsx +72 -0
  457. package/src/display/StatTile.tsx +39 -0
  458. package/src/display/StepList.tsx +10 -0
  459. package/src/display/TextPreview.tsx +66 -0
  460. package/src/display/TimeSeriesChart.tsx +191 -0
  461. package/src/display/ToneTile.ts +10 -0
  462. package/src/display/index.ts +37 -0
  463. package/src/feedback/Alert.tsx +35 -0
  464. package/src/feedback/AsyncState.tsx +56 -0
  465. package/src/feedback/ErrorNotification.ts +24 -0
  466. package/src/feedback/Notifications.tsx +5 -0
  467. package/src/feedback/ProgressStatusRow.tsx +104 -0
  468. package/src/feedback/SkeletonLoader.tsx +88 -0
  469. package/src/feedback/StatusIndicator.tsx +28 -0
  470. package/src/feedback/StatusPopoverContent.tsx +54 -0
  471. package/src/feedback/StatusRow.tsx +70 -0
  472. package/src/feedback/index.ts +15 -0
  473. package/src/forms/Checkbox.tsx +61 -0
  474. package/src/forms/Field.tsx +17 -0
  475. package/src/forms/FormControlStyles.ts +9 -0
  476. package/src/forms/FormSection.tsx +175 -0
  477. package/src/forms/InlineFields.tsx +22 -0
  478. package/src/forms/Input.tsx +22 -0
  479. package/src/forms/OptionSelect.tsx +49 -0
  480. package/src/forms/RadioGroup.tsx +48 -0
  481. package/src/forms/Select.tsx +46 -0
  482. package/src/forms/Switch.tsx +10 -0
  483. package/src/forms/TagInput.tsx +76 -0
  484. package/src/forms/Textarea.tsx +14 -0
  485. package/src/forms/index.ts +11 -0
  486. package/src/foundations/DesignSystemProvider.tsx +79 -0
  487. package/src/foundations/KeyboardFocus.ts +6 -0
  488. package/src/foundations/KeyboardShortcut.ts +12 -0
  489. package/src/foundations/Theme.ts +71 -0
  490. package/src/foundations/index.ts +10 -0
  491. package/src/foundations/theme.css +425 -0
  492. package/src/icons/BrandIcons.tsx +8 -0
  493. package/src/icons/index.ts +4 -0
  494. package/src/icons.ts +1 -0
  495. package/src/index.ts +13 -0
  496. package/src/layout/AppShell.tsx +63 -0
  497. package/src/layout/AuthLayout.tsx +40 -0
  498. package/src/layout/ContentContainer.tsx +16 -0
  499. package/src/layout/Flow.tsx +56 -0
  500. package/src/layout/PageLayout.tsx +35 -0
  501. package/src/layout/PageSection.tsx +103 -0
  502. package/src/layout/ScrollArea.tsx +7 -0
  503. package/src/layout/Section.tsx +36 -0
  504. package/src/layout/Site.tsx +205 -0
  505. package/src/layout/TitleBar.tsx +97 -0
  506. package/src/layout/WorkspaceActionsHeader.tsx +17 -0
  507. package/src/layout/index.ts +18 -0
  508. package/src/layout/sidebar/SidebarNavigationItem.tsx +45 -0
  509. package/src/layout/sidebar/SidebarPane.tsx +37 -0
  510. package/src/layout/toolbar/CommandPaletteTrigger.tsx +53 -0
  511. package/src/layout/toolbar/ToolbarStatusGroup.tsx +9 -0
  512. package/src/layout/toolbar/ToolbarStatusItem.tsx +18 -0
  513. package/src/navigation/ArtworkTabs.tsx +107 -0
  514. package/src/navigation/Breadcrumbs.tsx +31 -0
  515. package/src/navigation/CollectionBrowseSelector.tsx +90 -0
  516. package/src/navigation/CollectionViewToggle.tsx +52 -0
  517. package/src/navigation/DrilldownBrowseSelector.tsx +229 -0
  518. package/src/navigation/FolderSelector.tsx +172 -0
  519. package/src/navigation/TabKeys.ts +21 -0
  520. package/src/navigation/ViewTabs.tsx +85 -0
  521. package/src/navigation/index.ts +15 -0
  522. package/src/overlays/ActionModal.tsx +81 -0
  523. package/src/overlays/CommandPalette.tsx +199 -0
  524. package/src/overlays/Drawer.tsx +107 -0
  525. package/src/overlays/DropdownMenu.tsx +122 -0
  526. package/src/overlays/ImageViewer.tsx +96 -0
  527. package/src/overlays/Modal.tsx +234 -0
  528. package/src/overlays/Popover.tsx +40 -0
  529. package/src/overlays/Tooltip.tsx +56 -0
  530. package/src/overlays/index.ts +8 -0
  531. package/src/overlays/useModalAutoFocus.ts +119 -0
  532. package/src/overlays/useScrollFade.ts +49 -0
  533. package/src/showcase/CallToAction.tsx +46 -0
  534. package/src/showcase/Cards.tsx +133 -0
  535. package/src/showcase/Devices.tsx +259 -0
  536. package/src/showcase/FeatureRow.tsx +107 -0
  537. package/src/showcase/Hero.tsx +70 -0
  538. package/src/showcase/PhotoSearchConcept.tsx +50 -0
  539. package/src/showcase/Platforms.tsx +49 -0
  540. package/src/showcase/ProductBand.tsx +148 -0
  541. package/src/showcase/Roadmap.tsx +115 -0
  542. package/src/showcase/RouteDiagram.tsx +56 -0
  543. package/src/showcase/ServerUnit.tsx +191 -0
  544. package/src/showcase/Stage.tsx +160 -0
  545. package/src/showcase/Status.tsx +107 -0
  546. package/src/showcase/StepFlow.tsx +48 -0
  547. package/src/showcase/devices.css +441 -0
  548. package/src/showcase/index.ts +34 -0
  549. package/src/showcase/server-unit.css +258 -0
  550. package/src/showcase/stage.css +175 -0
  551. package/src/styles.css +5 -0
  552. package/src/testing.ts +34 -0
  553. package/src/typography/Link.tsx +105 -0
  554. package/src/typography/Typography.tsx +113 -0
  555. package/src/typography/index.ts +3 -0
@@ -0,0 +1,21 @@
1
+ interface ImageViewerProps {
2
+ alt: string;
3
+ caption?: string;
4
+ onClose: () => void;
5
+ open: boolean;
6
+ /** Pixel size to show beside the caption; omit when unknown rather than guessing. */
7
+ resolution?: {
8
+ height: number;
9
+ width: number;
10
+ };
11
+ /** Omit while the image is not ready yet (still loading, authenticating, and so on); shows the
12
+ * same loading indicator as a slow-loading image rather than a broken one. */
13
+ src?: string;
14
+ }
15
+ /**
16
+ * Shows one image at its natural size over the blurred modal backdrop, scaled down only when it would not fit.
17
+ * Clicking anywhere except the image, the close button, or Escape dismisses it.
18
+ */
19
+ export declare function ImageViewer({ alt, caption, onClose, open, resolution, src }: ImageViewerProps): import("react").JSX.Element;
20
+ export {};
21
+ //# sourceMappingURL=ImageViewer.d.ts.map
@@ -0,0 +1,82 @@
1
+ import { IconButton } from "../actions/IconButton.js";
2
+ import { useDesignSystemLabels } from "../foundations/DesignSystemProvider.js";
3
+ import { Text } from "../typography/Typography.js";
4
+ import { useModalAutoFocus } from "./useModalAutoFocus.js";
5
+ import { useId, useState } from "react";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ import { XIcon } from "lucide-react";
8
+ import { Loading } from "@ninna-ui/feedback";
9
+ import { Modal } from "@ninna-ui/overlays";
10
+ // src/overlays/ImageViewer.tsx
11
+ /**
12
+ * Shows one image at its natural size over the blurred modal backdrop, scaled down only when it would not fit.
13
+ * Clicking anywhere except the image, the close button, or Escape dismisses it.
14
+ */
15
+ function ImageViewer({ alt, caption, onClose, open, resolution, src }) {
16
+ const labels = useDesignSystemLabels();
17
+ const focusProps = useModalAutoFocus();
18
+ const captionId = useId();
19
+ const [loadedSource, setLoadedSource] = useState();
20
+ const loaded = Boolean(src) && loadedSource === src;
21
+ const size = resolution ? labels.imageSize(resolution.width, resolution.height) : void 0;
22
+ return /* @__PURE__ */ jsx(Modal, {
23
+ open,
24
+ onOpenChange: (next) => !next && onClose(),
25
+ children: /* @__PURE__ */ jsxs(Modal.Content, {
26
+ ...focusProps,
27
+ title: caption ?? alt,
28
+ size: "full",
29
+ className: "top-0 left-0 flex h-dvh max-h-none w-screen translate-x-0 translate-y-0 items-center justify-center overflow-hidden rounded-none border-0 bg-transparent p-4 shadow-none sm:top-0 sm:left-0 sm:h-dvh sm:w-screen sm:translate-x-0 sm:translate-y-0 sm:p-8",
30
+ onClick: (event) => event.target === event.currentTarget && onClose(),
31
+ children: [
32
+ /* @__PURE__ */ jsx("div", {
33
+ className: "absolute top-5 right-5 z-10 [--color-header-icon:#ffffff] sm:top-6 sm:right-6",
34
+ children: /* @__PURE__ */ jsx(Modal.Close, {
35
+ asChild: true,
36
+ children: /* @__PURE__ */ jsx(IconButton, {
37
+ "aria-label": labels.close,
38
+ icon: /* @__PURE__ */ jsx(XIcon, {}),
39
+ variant: "header"
40
+ })
41
+ })
42
+ }),
43
+ loaded ? null : /* @__PURE__ */ jsx("span", {
44
+ className: "pointer-events-none absolute inset-0 flex items-center justify-center text-white/80",
45
+ children: /* @__PURE__ */ jsx(Loading, { size: "lg" })
46
+ }),
47
+ /* @__PURE__ */ jsxs("figure", {
48
+ "aria-labelledby": caption ? captionId : void 0,
49
+ className: "pointer-events-none m-0 flex max-w-full flex-col items-center gap-3",
50
+ children: [src ? /* @__PURE__ */ jsx("img", {
51
+ alt,
52
+ src,
53
+ decoding: "async",
54
+ ref: (image) => {
55
+ if (image?.complete && image.naturalWidth > 0) setLoadedSource(src);
56
+ },
57
+ onLoad: () => setLoadedSource(src),
58
+ onError: () => setLoadedSource(src),
59
+ className: `pointer-events-auto max-h-[calc(100dvh-7rem)] max-w-full rounded-lg object-contain shadow-2xl transition-opacity duration-200 motion-reduce:transition-none sm:max-h-[calc(100dvh-9rem)] ${loaded ? "opacity-100" : "opacity-0"}`
60
+ }) : null, caption || size ? /* @__PURE__ */ jsxs("figcaption", {
61
+ className: "flex max-w-prose flex-wrap items-baseline justify-center gap-x-3 gap-y-1 text-center",
62
+ children: [caption ? /* @__PURE__ */ jsx(Text, {
63
+ id: captionId,
64
+ as: "span",
65
+ className: "wrap-break-word text-white/90",
66
+ variant: "label",
67
+ children: caption
68
+ }) : null, size ? /* @__PURE__ */ jsx(Text, {
69
+ as: "span",
70
+ className: "text-white/60 tabular-nums",
71
+ variant: "caption",
72
+ children: size
73
+ }) : null]
74
+ }) : null]
75
+ })
76
+ ]
77
+ })
78
+ });
79
+ }
80
+ export { ImageViewer };
81
+
82
+ //# sourceMappingURL=ImageViewer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ImageViewer.js","names":["NinnaModal"],"sources":["../../src/overlays/ImageViewer.tsx"],"sourcesContent":["import { Loading } from '@ninna-ui/feedback';\nimport { Modal as NinnaModal } from '@ninna-ui/overlays';\nimport { XIcon } from 'lucide-react';\nimport { useId, useState } from 'react';\n\nimport { IconButton } from '../actions/IconButton';\nimport { useDesignSystemLabels } from '../foundations/DesignSystemProvider';\nimport { Text } from '../typography/Typography';\nimport { useModalAutoFocus } from './useModalAutoFocus';\n\ninterface ImageViewerProps {\n alt: string;\n caption?: string;\n onClose: () => void;\n open: boolean;\n /** Pixel size to show beside the caption; omit when unknown rather than guessing. */\n resolution?: { height: number; width: number };\n /** Omit while the image is not ready yet (still loading, authenticating, and so on); shows the\n * same loading indicator as a slow-loading image rather than a broken one. */\n src?: string;\n}\n\n/**\n * Shows one image at its natural size over the blurred modal backdrop, scaled down only when it would not fit.\n * Clicking anywhere except the image, the close button, or Escape dismisses it.\n */\nexport function ImageViewer({ alt, caption, onClose, open, resolution, src }: ImageViewerProps) {\n const labels = useDesignSystemLabels();\n const focusProps = useModalAutoFocus();\n const captionId = useId();\n const [loadedSource, setLoadedSource] = useState<string>();\n const loaded = Boolean(src) && loadedSource === src;\n const size = resolution ? labels.imageSize(resolution.width, resolution.height) : undefined;\n\n return (\n <NinnaModal open={open} onOpenChange={(next) => !next && onClose()}>\n <NinnaModal.Content\n {...focusProps}\n title={caption ?? alt}\n size=\"full\"\n className=\"top-0 left-0 flex h-dvh max-h-none w-screen translate-x-0 translate-y-0 items-center justify-center overflow-hidden rounded-none border-0 bg-transparent p-4 shadow-none sm:top-0 sm:left-0 sm:h-dvh sm:w-screen sm:translate-x-0 sm:translate-y-0 sm:p-8\"\n onClick={(event) => event.target === event.currentTarget && onClose()}\n >\n {/* The standard header close button, lightened because it always sits on the dark backdrop. */}\n <div className=\"absolute top-5 right-5 z-10 [--color-header-icon:#ffffff] sm:top-6 sm:right-6\">\n <NinnaModal.Close asChild>\n <IconButton aria-label={labels.close} icon={<XIcon />} variant=\"header\" />\n </NinnaModal.Close>\n </div>\n {loaded ? null : (\n <span className=\"pointer-events-none absolute inset-0 flex items-center justify-center text-white/80\">\n <Loading size=\"lg\" />\n </span>\n )}\n {/* Only the image itself catches clicks; the space around it and the caption fall through to close. */}\n <figure\n aria-labelledby={caption ? captionId : undefined}\n className=\"pointer-events-none m-0 flex max-w-full flex-col items-center gap-3\"\n >\n {src ? (\n <img\n alt={alt}\n src={src}\n decoding=\"async\"\n ref={(image) => {\n if (image?.complete && image.naturalWidth > 0) setLoadedSource(src);\n }}\n onLoad={() => setLoadedSource(src)}\n onError={() => setLoadedSource(src)}\n className={`pointer-events-auto max-h-[calc(100dvh-7rem)] max-w-full rounded-lg object-contain shadow-2xl transition-opacity duration-200 motion-reduce:transition-none sm:max-h-[calc(100dvh-9rem)] ${loaded ? 'opacity-100' : 'opacity-0'}`}\n />\n ) : null}\n {caption || size ? (\n <figcaption className=\"flex max-w-prose flex-wrap items-baseline justify-center gap-x-3 gap-y-1 text-center\">\n {caption ? (\n <Text\n id={captionId}\n as=\"span\"\n className=\"wrap-break-word text-white/90\"\n variant=\"label\"\n >\n {caption}\n </Text>\n ) : null}\n {size ? (\n <Text as=\"span\" className=\"text-white/60 tabular-nums\" variant=\"caption\">\n {size}\n </Text>\n ) : null}\n </figcaption>\n ) : null}\n </figure>\n </NinnaModal.Content>\n </NinnaModal>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;AA0BA,SAAgB,YAAY,EAAE,KAAK,SAAS,SAAS,MAAM,YAAY,OAAyB;CAC5F,MAAM,SAAS,sBAAsB;CACrC,MAAM,aAAa,kBAAkB;CACrC,MAAM,YAAY,MAAM;CACxB,MAAM,CAAC,cAAc,mBAAmB,SAAiB;CACzD,MAAM,SAAS,QAAQ,GAAG,KAAK,iBAAiB;CAChD,MAAM,OAAO,aAAa,OAAO,UAAU,WAAW,OAAO,WAAW,MAAM,IAAI,KAAA;CAElF,OACI,oBAACA,OAAD;EAAkB;EAAM,eAAe,SAAS,CAAC,QAAQ,QAAQ;EAC7D,UAAA,qBAACA,MAAW,SAAZ;GACI,GAAI;GACJ,OAAO,WAAW;GAClB,MAAK;GACL,WAAU;GACV,UAAU,UAAU,MAAM,WAAW,MAAM,iBAAiB,QAAQ;GALxE,UAAA;IAQI,oBAAC,OAAD;KAAK,WAAU;KACX,UAAA,oBAACA,MAAW,OAAZ;MAAkB,SAAA;MACd,UAAA,oBAAC,YAAD;OAAY,cAAY,OAAO;OAAO,MAAM,oBAAC,OAAD,CAAQ,CAAA;OAAG,SAAQ;MAAU,CAAA;KAC3D,CAAA;IACjB,CAAA;IACJ,SAAS,OACN,oBAAC,QAAD;KAAM,WAAU;KACZ,UAAA,oBAAC,SAAD,EAAS,MAAK,KAAM,CAAA;IAClB,CAAA;IAGV,qBAAC,UAAD;KACI,mBAAiB,UAAU,YAAY,KAAA;KACvC,WAAU;KAFd,UAAA,CAIK,MACG,oBAAC,OAAD;MACS;MACA;MACL,UAAS;MACT,MAAM,UAAU;OACZ,IAAI,OAAO,YAAY,MAAM,eAAe,GAAG,gBAAgB,GAAG;MACtE;MACA,cAAc,gBAAgB,GAAG;MACjC,eAAe,gBAAgB,GAAG;MAClC,WAAW,4LAA4L,SAAS,gBAAgB;KACnO,CAAA,IACD,MACH,WAAW,OACR,qBAAC,cAAD;MAAY,WAAU;MAAtB,UAAA,CACK,UACG,oBAAC,MAAD;OACI,IAAI;OACJ,IAAG;OACH,WAAU;OACV,SAAQ;OAEP,UAAA;MACC,CAAA,IACN,MACH,OACG,oBAAC,MAAD;OAAM,IAAG;OAAO,WAAU;OAA6B,SAAQ;OAC1D,UAAA;MACC,CAAA,IACN,IACI;KACZ,CAAA,IAAA,IACA;;GACQ;;CACZ,CAAA;AAEpB"}
@@ -0,0 +1,36 @@
1
+ import { ComponentProps, ReactNode } from "react";
2
+ import { ModalBodyProps, ModalContentProps, ModalFooterProps } from "@ninna-ui/overlays";
3
+ interface ModalContentPolicyProps extends Omit<ModalContentProps, 'className' | 'size' | 'title'> {
4
+ accessibleTitle?: string;
5
+ /** Whether opening focuses the first editable field; off while the caller focuses something else. */
6
+ focusFirstField?: boolean;
7
+ headerActions?: ReactNode;
8
+ sidebar?: ReactNode;
9
+ /** The dialog's size; a dialog with a sidebar is `paned` unless it says otherwise. */
10
+ presentation?: 'default' | 'paned' | 'workspace';
11
+ title: string;
12
+ }
13
+ declare function ModalForm(props: Omit<ComponentProps<'form'>, 'className'>): import("react").JSX.Element;
14
+ declare function ModalPane({ active, children }: {
15
+ active: boolean;
16
+ children: ReactNode;
17
+ }): import("react").JSX.Element;
18
+ interface ModalRootPolicyProps {
19
+ children: ReactNode;
20
+ loading?: boolean;
21
+ onClose: () => void;
22
+ }
23
+ declare function ModalRoot({ children, loading, onClose }: ModalRootPolicyProps): import("react").JSX.Element;
24
+ declare const Modal$1: typeof ModalRoot & {
25
+ Body: import("react").ForwardRefExoticComponent<Omit<ModalBodyProps, "className"> & {
26
+ layout?: 'scroll' | 'fill';
27
+ } & import("react").RefAttributes<HTMLDivElement>>;
28
+ Form: typeof ModalForm;
29
+ Pane: typeof ModalPane;
30
+ Content: import("react").ForwardRefExoticComponent<ModalContentPolicyProps & import("react").RefAttributes<HTMLDivElement>>;
31
+ Footer: import("react").ForwardRefExoticComponent<Omit<ModalFooterProps, "className"> & {
32
+ leading?: ReactNode;
33
+ } & import("react").RefAttributes<HTMLDivElement>>;
34
+ };
35
+ export { Modal$1 as Modal };
36
+ //# sourceMappingURL=Modal.d.ts.map
@@ -0,0 +1,149 @@
1
+ import { IconButton } from "../actions/IconButton.js";
2
+ import { useDesignSystemLabels } from "../foundations/DesignSystemProvider.js";
3
+ import { Heading, Text } from "../typography/Typography.js";
4
+ import { useModalAutoFocus } from "./useModalAutoFocus.js";
5
+ import { useScrollFade } from "./useScrollFade.js";
6
+ import { createContext, forwardRef, useCallback, useContext } from "react";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ import { XIcon } from "lucide-react";
9
+ import { Modal } from "@ninna-ui/overlays";
10
+ // src/overlays/Modal.tsx
11
+ const ModalLoadingContext = createContext(false);
12
+ const ModalContent = forwardRef(({ accessibleTitle, children, closeOnEscape, closeOnOverlayClick, description, focusFirstField, headerActions, onPointerDownOutside, sidebar, presentation = sidebar ? "paned" : "default", title, ...props }, ref) => {
13
+ const loading = useContext(ModalLoadingContext);
14
+ const focusProps = useModalAutoFocus(focusFirstField);
15
+ return /* @__PURE__ */ jsxs(Modal.Content, {
16
+ ref,
17
+ ...props,
18
+ ...focusProps,
19
+ title: accessibleTitle ?? title,
20
+ description,
21
+ closeOnEscape: loading ? false : closeOnEscape,
22
+ closeOnOverlayClick: loading ? false : closeOnOverlayClick,
23
+ onPointerDownOutside: (event) => {
24
+ if (event.target instanceof Element && event.target.closest("[data-slot=\"toaster\"]")) event.preventDefault();
25
+ onPointerDownOutside?.(event);
26
+ },
27
+ size: presentation === "workspace" ? "full" : void 0,
28
+ className: `flex max-h-[calc(100dvh-1rem)] w-[calc(100vw-1rem)] flex-col overflow-hidden sm:max-h-[calc(100dvh-2rem)] sm:w-[calc(100vw-2rem)] ${sidebar ? "md:grid md:grid-cols-[14rem_minmax(0,1fr)] md:grid-rows-[auto_minmax(0,1fr)]" : ""} ${presentation === "workspace" ? "h-[calc(100dvh-1rem)] max-w-6xl sm:h-[calc(100dvh-2rem)] sm:max-w-6xl" : presentation === "paned" ? "h-[calc(100dvh-1rem)] max-w-4xl sm:h-[min(44rem,calc(100dvh-2rem))] sm:max-w-4xl" : "max-w-160 sm:max-w-160"}`,
29
+ children: [
30
+ /* @__PURE__ */ jsx("header", {
31
+ "data-slot": "modal-header",
32
+ className: `@container min-w-0 shrink-0 px-5 pt-5 sm:px-6 sm:pt-6 ${description ? sidebar ? "pb-4 md:pb-0" : "" : "pb-4"} ${sidebar ? "md:col-start-2 md:row-start-1" : ""}`,
33
+ children: /* @__PURE__ */ jsxs("div", {
34
+ className: "flex min-w-0 flex-wrap items-center justify-between gap-x-4 gap-y-3",
35
+ children: [
36
+ /* @__PURE__ */ jsx(Heading, {
37
+ as: "h2",
38
+ className: "min-w-0 flex-1 wrap-break-word",
39
+ variant: "section",
40
+ children: title
41
+ }),
42
+ headerActions ? /* @__PURE__ */ jsx("div", {
43
+ className: "order-3 flex basis-full items-center justify-end gap-2 @min-[32rem]:order-0 @min-[32rem]:ml-auto @min-[32rem]:basis-auto",
44
+ children: headerActions
45
+ }) : null,
46
+ /* @__PURE__ */ jsx("div", {
47
+ className: "shrink-0",
48
+ children: /* @__PURE__ */ jsx(ModalClose, {})
49
+ })
50
+ ]
51
+ })
52
+ }),
53
+ sidebar ? /* @__PURE__ */ jsx("div", {
54
+ className: "min-h-0 min-w-0 shrink-0 md:col-start-1 md:row-span-2 md:row-start-1",
55
+ children: sidebar
56
+ }) : null,
57
+ /* @__PURE__ */ jsxs("div", {
58
+ className: `flex min-h-0 min-w-0 flex-1 flex-col ${sidebar ? "md:col-start-2 md:row-start-2" : ""}`,
59
+ children: [description ? /* @__PURE__ */ jsx(Text, {
60
+ className: `shrink-0 px-5 pb-4 sm:px-6 ${sidebar ? "pt-4 md:pt-2" : "pt-2"}`,
61
+ tone: "muted",
62
+ children: description
63
+ }) : null, children]
64
+ })
65
+ ]
66
+ });
67
+ });
68
+ ModalContent.displayName = "Modal.Content";
69
+ const ModalBody = forwardRef(({ layout = "scroll", children, ...props }, ref) => {
70
+ const { setViewport, setContent, className } = useScrollFade();
71
+ const bodyRef = useCallback((element) => {
72
+ setViewport(element);
73
+ const cleanup = typeof ref === "function" ? ref(element) : void 0;
74
+ if (ref && typeof ref !== "function") ref.current = element;
75
+ return () => {
76
+ setViewport(null);
77
+ if (typeof cleanup === "function") cleanup();
78
+ else if (typeof ref === "function") ref(null);
79
+ else if (ref) ref.current = null;
80
+ };
81
+ }, [ref, setViewport]);
82
+ return /* @__PURE__ */ jsx(Modal.Body, {
83
+ ref: bodyRef,
84
+ ...props,
85
+ className: `min-h-0 flex-1 overflow-y-auto overscroll-contain px-5 pt-2 pb-6 sm:px-6 ${layout === "fill" ? "flex flex-col" : ""} ${className}`,
86
+ children: /* @__PURE__ */ jsx("div", {
87
+ ref: setContent,
88
+ className: layout === "fill" ? "flex min-h-0 flex-1 flex-col gap-3" : "flow-root",
89
+ children
90
+ })
91
+ });
92
+ });
93
+ ModalBody.displayName = "Modal.Body";
94
+ function ModalForm(props) {
95
+ return /* @__PURE__ */ jsx("form", {
96
+ ...props,
97
+ className: "flex min-h-0 flex-1 flex-col"
98
+ });
99
+ }
100
+ function ModalPane({ active, children }) {
101
+ return /* @__PURE__ */ jsx("div", {
102
+ hidden: !active,
103
+ className: active ? "flex min-h-0 flex-1 flex-col" : "hidden",
104
+ children
105
+ });
106
+ }
107
+ const ModalFooter = forwardRef(({ leading, children, ...props }, ref) => /* @__PURE__ */ jsxs(Modal.Footer, {
108
+ ref,
109
+ ...props,
110
+ className: "border-base-300 bg-base-50/60 shrink-0 border-t px-5 py-4 sm:px-6 sm:pb-4",
111
+ children: [leading ? /* @__PURE__ */ jsx("div", {
112
+ className: "mr-auto min-w-0 basis-full pb-2 sm:basis-auto sm:pb-0",
113
+ children: leading
114
+ }) : null, children]
115
+ }));
116
+ ModalFooter.displayName = "Modal.Footer";
117
+ function ModalClose() {
118
+ const labels = useDesignSystemLabels();
119
+ const loading = useContext(ModalLoadingContext);
120
+ return /* @__PURE__ */ jsx(Modal.Close, {
121
+ asChild: true,
122
+ children: /* @__PURE__ */ jsx(IconButton, {
123
+ "aria-label": labels.close,
124
+ disabled: loading,
125
+ icon: /* @__PURE__ */ jsx(XIcon, {}),
126
+ variant: "header"
127
+ })
128
+ });
129
+ }
130
+ function ModalRoot({ children, loading = false, onClose }) {
131
+ return /* @__PURE__ */ jsx(ModalLoadingContext.Provider, {
132
+ value: loading,
133
+ children: /* @__PURE__ */ jsx(Modal, {
134
+ open: true,
135
+ onOpenChange: (open) => !open && !loading && onClose(),
136
+ children
137
+ })
138
+ });
139
+ }
140
+ const Modal$1 = Object.assign(ModalRoot, {
141
+ Body: ModalBody,
142
+ Form: ModalForm,
143
+ Pane: ModalPane,
144
+ Content: ModalContent,
145
+ Footer: ModalFooter
146
+ });
147
+ export { Modal$1 as Modal };
148
+
149
+ //# sourceMappingURL=Modal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Modal.js","names":["NinnaModal","Modal"],"sources":["../../src/overlays/Modal.tsx"],"sourcesContent":["/* oxlint-disable react/only-export-components -- Compound members are exported through Modal. */\n\nimport {\n Modal as NinnaModal,\n type ModalBodyProps,\n type ModalContentProps,\n type ModalFooterProps,\n} from '@ninna-ui/overlays';\nimport { XIcon } from 'lucide-react';\nimport {\n type ComponentProps,\n createContext,\n forwardRef,\n type ReactNode,\n type Ref,\n useCallback,\n useContext,\n} from 'react';\n\nimport { IconButton } from '../actions/IconButton';\nimport { useDesignSystemLabels } from '../foundations/DesignSystemProvider';\nimport { Heading, Text } from '../typography/Typography';\nimport { useModalAutoFocus } from './useModalAutoFocus';\nimport { useScrollFade } from './useScrollFade';\n\nconst ModalLoadingContext = createContext(false);\n\ninterface ModalContentPolicyProps extends Omit<ModalContentProps, 'className' | 'size' | 'title'> {\n accessibleTitle?: string;\n /** Whether opening focuses the first editable field; off while the caller focuses something else. */\n focusFirstField?: boolean;\n headerActions?: ReactNode;\n sidebar?: ReactNode;\n /** The dialog's size; a dialog with a sidebar is `paned` unless it says otherwise. */\n presentation?: 'default' | 'paned' | 'workspace';\n title: string;\n}\n\nconst ModalContent = forwardRef<HTMLDivElement, ModalContentPolicyProps>(\n (\n {\n accessibleTitle,\n children,\n closeOnEscape,\n closeOnOverlayClick,\n description,\n focusFirstField,\n headerActions,\n onPointerDownOutside,\n sidebar,\n presentation = sidebar ? 'paned' : 'default',\n title,\n ...props\n },\n ref,\n ) => {\n const loading = useContext(ModalLoadingContext);\n const focusProps = useModalAutoFocus(focusFirstField);\n\n return (\n <NinnaModal.Content\n ref={ref}\n {...props}\n {...focusProps}\n title={accessibleTitle ?? title}\n description={description}\n closeOnEscape={loading ? false : closeOnEscape}\n closeOnOverlayClick={loading ? false : closeOnOverlayClick}\n onPointerDownOutside={(event) => {\n if (event.target instanceof Element && event.target.closest('[data-slot=\"toaster\"]')) {\n event.preventDefault();\n }\n\n onPointerDownOutside?.(event);\n }}\n size={presentation === 'workspace' ? 'full' : undefined}\n className={`flex max-h-[calc(100dvh-1rem)] w-[calc(100vw-1rem)] flex-col overflow-hidden sm:max-h-[calc(100dvh-2rem)] sm:w-[calc(100vw-2rem)] ${\n sidebar ? 'md:grid md:grid-cols-[14rem_minmax(0,1fr)] md:grid-rows-[auto_minmax(0,1fr)]' : ''\n } ${\n presentation === 'workspace'\n ? 'h-[calc(100dvh-1rem)] max-w-6xl sm:h-[calc(100dvh-2rem)] sm:max-w-6xl'\n : presentation === 'paned'\n ? // Paned dialogs keep one height across panes; the body scrolls instead of the dialog resizing.\n 'h-[calc(100dvh-1rem)] max-w-4xl sm:h-[min(44rem,calc(100dvh-2rem))] sm:max-w-4xl'\n : 'max-w-160 sm:max-w-160'\n }`}\n >\n <header\n data-slot=\"modal-header\"\n className={`@container min-w-0 shrink-0 px-5 pt-5 sm:px-6 sm:pt-6 ${\n description ? (sidebar ? 'pb-4 md:pb-0' : '') : 'pb-4'\n } ${sidebar ? 'md:col-start-2 md:row-start-1' : ''}`}\n >\n <div className=\"flex min-w-0 flex-wrap items-center justify-between gap-x-4 gap-y-3\">\n <Heading as=\"h2\" className=\"min-w-0 flex-1 wrap-break-word\" variant=\"section\">\n {title}\n </Heading>\n {headerActions ? (\n <div className=\"order-3 flex basis-full items-center justify-end gap-2 @min-[32rem]:order-0 @min-[32rem]:ml-auto @min-[32rem]:basis-auto\">\n {headerActions}\n </div>\n ) : null}\n <div className=\"shrink-0\">\n <ModalClose />\n </div>\n </div>\n </header>\n {sidebar ? (\n <div className=\"min-h-0 min-w-0 shrink-0 md:col-start-1 md:row-span-2 md:row-start-1\">\n {sidebar}\n </div>\n ) : null}\n <div\n className={`flex min-h-0 min-w-0 flex-1 flex-col ${sidebar ? 'md:col-start-2 md:row-start-2' : ''}`}\n >\n {description ? (\n <Text\n className={`shrink-0 px-5 pb-4 sm:px-6 ${sidebar ? 'pt-4 md:pt-2' : 'pt-2'}`}\n tone=\"muted\"\n >\n {description}\n </Text>\n ) : null}\n {children}\n </div>\n </NinnaModal.Content>\n );\n },\n);\n\nModalContent.displayName = 'Modal.Content';\n\nconst ModalBody = forwardRef<HTMLDivElement, Omit<ModalBodyProps, 'className'> & { layout?: 'scroll' | 'fill' }>(\n ({ layout = 'scroll', children, ...props }, ref: Ref<HTMLDivElement>) => {\n const { setViewport, setContent, className } = useScrollFade();\n const bodyRef = useCallback(\n (element: HTMLDivElement) => {\n setViewport(element);\n\n const cleanup = typeof ref === 'function' ? ref(element) : undefined;\n\n if (ref && typeof ref !== 'function') ref.current = element;\n\n return () => {\n setViewport(null);\n\n if (typeof cleanup === 'function') cleanup();\n else if (typeof ref === 'function') ref(null);\n else if (ref) ref.current = null;\n };\n },\n [ref, setViewport],\n );\n\n return (\n <NinnaModal.Body\n ref={bodyRef}\n {...props}\n className={`min-h-0 flex-1 overflow-y-auto overscroll-contain px-5 pt-2 pb-6 sm:px-6 ${layout === 'fill' ? 'flex flex-col' : ''} ${className}`}\n >\n <div\n ref={setContent}\n className={layout === 'fill' ? 'flex min-h-0 flex-1 flex-col gap-3' : 'flow-root'}\n >\n {children}\n </div>\n </NinnaModal.Body>\n );\n },\n);\n\nModalBody.displayName = 'Modal.Body';\n\nfunction ModalForm(props: Omit<ComponentProps<'form'>, 'className'>) {\n return <form {...props} className=\"flex min-h-0 flex-1 flex-col\" />;\n}\n\nfunction ModalPane({ active, children }: { active: boolean; children: ReactNode }) {\n return (\n <div hidden={!active} className={active ? 'flex min-h-0 flex-1 flex-col' : 'hidden'}>\n {children}\n </div>\n );\n}\n\nconst ModalFooter = forwardRef<HTMLDivElement, Omit<ModalFooterProps, 'className'> & { leading?: ReactNode }>(\n ({ leading, children, ...props }, ref) => (\n <NinnaModal.Footer\n ref={ref}\n {...props}\n className=\"border-base-300 bg-base-50/60 shrink-0 border-t px-5 py-4 sm:px-6 sm:pb-4\"\n >\n {leading ? <div className=\"mr-auto min-w-0 basis-full pb-2 sm:basis-auto sm:pb-0\">{leading}</div> : null}\n {children}\n </NinnaModal.Footer>\n ),\n);\n\nModalFooter.displayName = 'Modal.Footer';\n\nfunction ModalClose() {\n const labels = useDesignSystemLabels();\n const loading = useContext(ModalLoadingContext);\n\n return (\n <NinnaModal.Close asChild>\n <IconButton aria-label={labels.close} disabled={loading} icon={<XIcon />} variant=\"header\" />\n </NinnaModal.Close>\n );\n}\n\ninterface ModalRootPolicyProps {\n children: ReactNode;\n loading?: boolean;\n onClose: () => void;\n}\n\nfunction ModalRoot({ children, loading = false, onClose }: ModalRootPolicyProps) {\n return (\n <ModalLoadingContext.Provider value={loading}>\n <NinnaModal open onOpenChange={(open) => !open && !loading && onClose()}>\n {children}\n </NinnaModal>\n </ModalLoadingContext.Provider>\n );\n}\n\nexport const Modal = Object.assign(ModalRoot, {\n Body: ModalBody,\n Form: ModalForm,\n Pane: ModalPane,\n Content: ModalContent,\n Footer: ModalFooter,\n});\n"],"mappings":";;;;;;;;;;AAyBA,MAAM,sBAAsB,cAAc,KAAK;AAa/C,MAAM,eAAe,YAEb,EACI,iBACA,UACA,eACA,qBACA,aACA,iBACA,eACA,sBACA,SACA,eAAe,UAAU,UAAU,WACnC,OACA,GAAG,SAEP,QACC;CACD,MAAM,UAAU,WAAW,mBAAmB;CAC9C,MAAM,aAAa,kBAAkB,eAAe;CAEpD,OACI,qBAACA,MAAW,SAAZ;EACS;EACL,GAAI;EACJ,GAAI;EACJ,OAAO,mBAAmB;EACb;EACb,eAAe,UAAU,QAAQ;EACjC,qBAAqB,UAAU,QAAQ;EACvC,uBAAuB,UAAU;GAC7B,IAAI,MAAM,kBAAkB,WAAW,MAAM,OAAO,QAAQ,yBAAuB,GAC/E,MAAM,eAAe;GAGzB,uBAAuB,KAAK;EAChC;EACA,MAAM,iBAAiB,cAAc,SAAS,KAAA;EAC9C,WAAW,qIACP,UAAU,iFAAiF,GAC9F,GACG,iBAAiB,cACX,0EACA,iBAAiB,UAEf,qFACA;EAxBhB,UAAA;GA2BI,oBAAC,UAAD;IACI,aAAU;IACV,WAAW,yDACP,cAAe,UAAU,iBAAiB,KAAM,OACnD,GAAG,UAAU,kCAAkC;IAEhD,UAAA,qBAAC,OAAD;KAAK,WAAU;KAAf,UAAA;MACI,oBAAC,SAAD;OAAS,IAAG;OAAK,WAAU;OAAiC,SAAQ;OAC/D,UAAA;MACI,CAAA;MACR,gBACG,oBAAC,OAAD;OAAK,WAAU;OACV,UAAA;MACA,CAAA,IACL;MACJ,oBAAC,OAAD;OAAK,WAAU;OACX,UAAA,oBAAC,YAAD,CAAa,CAAA;MACZ,CAAA;KACJ;;GACD,CAAA;GACP,UACG,oBAAC,OAAD;IAAK,WAAU;IACV,UAAA;GACA,CAAA,IACL;GACJ,qBAAC,OAAD;IACI,WAAW,wCAAwC,UAAU,kCAAkC;IADnG,UAAA,CAGK,cACG,oBAAC,MAAD;KACI,WAAW,8BAA8B,UAAU,iBAAiB;KACpE,MAAK;KAEJ,UAAA;IACC,CAAA,IACN,MACH,QACA;;EACW;;AAE5B,CACJ;AAEA,aAAa,cAAc;AAE3B,MAAM,YAAY,YACb,EAAE,SAAS,UAAU,UAAU,GAAG,SAAS,QAA6B;CACrE,MAAM,EAAE,aAAa,YAAY,cAAc,cAAc;CAC7D,MAAM,UAAU,aACX,YAA4B;EACzB,YAAY,OAAO;EAEnB,MAAM,UAAU,OAAO,QAAQ,aAAa,IAAI,OAAO,IAAI,KAAA;EAE3D,IAAI,OAAO,OAAO,QAAQ,YAAY,IAAI,UAAU;EAEpD,aAAa;GACT,YAAY,IAAI;GAEhB,IAAI,OAAO,YAAY,YAAY,QAAQ;QACtC,IAAI,OAAO,QAAQ,YAAY,IAAI,IAAI;QACvC,IAAI,KAAK,IAAI,UAAU;EAChC;CACJ,GACA,CAAC,KAAK,WAAW,CACrB;CAEA,OACI,oBAACA,MAAW,MAAZ;EACI,KAAK;EACL,GAAI;EACJ,WAAW,4EAA4E,WAAW,SAAS,kBAAkB,GAAG,GAAG;EAEnI,UAAA,oBAAC,OAAD;GACI,KAAK;GACL,WAAW,WAAW,SAAS,uCAAuC;GAErE;EACA,CAAA;CACQ,CAAA;AAEzB,CACJ;AAEA,UAAU,cAAc;AAExB,SAAS,UAAU,OAAkD;CACjE,OAAO,oBAAC,QAAD;EAAM,GAAI;EAAO,WAAU;CAAgC,CAAA;AACtE;AAEA,SAAS,UAAU,EAAE,QAAQ,YAAsD;CAC/E,OACI,oBAAC,OAAD;EAAK,QAAQ,CAAC;EAAQ,WAAW,SAAS,iCAAiC;EACtE;CACA,CAAA;AAEb;AAEA,MAAM,cAAc,YACf,EAAE,SAAS,UAAU,GAAG,SAAS,QAC9B,qBAACA,MAAW,QAAZ;CACS;CACL,GAAI;CACJ,WAAU;CAHd,UAAA,CAKK,UAAU,oBAAC,OAAD;EAAK,WAAU;EAAyD,UAAA;CAAa,CAAA,IAAI,MACnG,QACc;AAE3B,CAAA,CAAA;AAEA,YAAY,cAAc;AAE1B,SAAS,aAAa;CAClB,MAAM,SAAS,sBAAsB;CACrC,MAAM,UAAU,WAAW,mBAAmB;CAE9C,OACI,oBAACA,MAAW,OAAZ;EAAkB,SAAA;EACd,UAAA,oBAAC,YAAD;GAAY,cAAY,OAAO;GAAO,UAAU;GAAS,MAAM,oBAAC,OAAD,CAAQ,CAAA;GAAG,SAAQ;EAAU,CAAA;CAC9E,CAAA;AAE1B;AAQA,SAAS,UAAU,EAAE,UAAU,UAAU,OAAO,WAAiC;CAC7E,OACI,oBAAC,oBAAoB,UAArB;EAA8B,OAAO;EACjC,UAAA,oBAACA,OAAD;GAAY,MAAA;GAAK,eAAe,SAAS,CAAC,QAAQ,CAAC,WAAW,QAAQ;GACjE;EACO,CAAA;CACc,CAAA;AAEtC;AAEA,MAAaC,UAAQ,OAAO,OAAO,WAAW;CAC1C,MAAM;CACN,MAAM;CACN,MAAM;CACN,SAAS;CACT,QAAQ;AACZ,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { ComponentProps } from "react";
2
+ import { Popover, PopoverContentProps } from "@ninna-ui/overlays";
3
+ interface PopoverContentPolicyProps extends Omit<PopoverContentProps, 'className'> {
4
+ layout?: 'fill' | 'scroll';
5
+ onOpenAutoFocus?: (event: Event) => void;
6
+ onCloseAutoFocus?: (event: Event) => void;
7
+ presentation?: 'default' | 'menu';
8
+ width?: 'content' | 'sm' | 'trigger';
9
+ }
10
+ declare function PopoverRoot(props: ComponentProps<typeof Popover>): import("react").JSX.Element;
11
+ declare const Popover$1: typeof PopoverRoot & {
12
+ displayName: string;
13
+ Trigger: import("react").ForwardRefExoticComponent<import("@ninna-ui/overlays").PopoverTriggerProps & import("react").RefAttributes<HTMLButtonElement>>;
14
+ Arrow: import("react").ForwardRefExoticComponent<import("@ninna-ui/overlays").PopoverArrowProps & import("react").RefAttributes<SVGSVGElement>>;
15
+ Close: import("react").ForwardRefExoticComponent<import("@ninna-ui/overlays").PopoverCloseProps & import("react").RefAttributes<HTMLButtonElement>>;
16
+ Content: import("react").ForwardRefExoticComponent<PopoverContentPolicyProps & import("react").RefAttributes<HTMLDivElement>>;
17
+ };
18
+ export { Popover$1 as Popover };
19
+ //# sourceMappingURL=Popover.d.ts.map
@@ -0,0 +1,26 @@
1
+ import { forwardRef } from "react";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { Popover } from "@ninna-ui/overlays";
4
+ // src/overlays/Popover.tsx
5
+ const popoverWidthClasses = {
6
+ content: void 0,
7
+ sm: "w-64",
8
+ trigger: "w-(--radix-popover-trigger-width)"
9
+ };
10
+ const PopoverContent = forwardRef(({ layout = "scroll", presentation = "default", width = "content", ...props }, ref) => /* @__PURE__ */ jsx(Popover.Content, {
11
+ ref,
12
+ ...props,
13
+ "data-layout": layout,
14
+ className: `${popoverWidthClasses[width] ?? ""} ${presentation === "menu" ? "p-1" : ""}`
15
+ }));
16
+ PopoverContent.displayName = "Popover.Content";
17
+ function PopoverRoot(props) {
18
+ return /* @__PURE__ */ jsx(Popover, { ...props });
19
+ }
20
+ const Popover$1 = Object.assign(PopoverRoot, {
21
+ ...Popover,
22
+ Content: PopoverContent
23
+ });
24
+ export { Popover$1 as Popover };
25
+
26
+ //# sourceMappingURL=Popover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Popover.js","names":["NinnaPopover","Popover"],"sources":["../../src/overlays/Popover.tsx"],"sourcesContent":["/* oxlint-disable react/only-export-components -- Compound members are exported through Popover. */\n\nimport { Popover as NinnaPopover, type PopoverContentProps } from '@ninna-ui/overlays';\nimport { type ComponentProps, forwardRef } from 'react';\n\ninterface PopoverContentPolicyProps extends Omit<PopoverContentProps, 'className'> {\n layout?: 'fill' | 'scroll';\n onOpenAutoFocus?: (event: Event) => void;\n onCloseAutoFocus?: (event: Event) => void;\n presentation?: 'default' | 'menu';\n width?: 'content' | 'sm' | 'trigger';\n}\n\nconst popoverWidthClasses: Record<NonNullable<PopoverContentPolicyProps['width']>, string | undefined> = {\n content: undefined,\n sm: 'w-64',\n trigger: 'w-(--radix-popover-trigger-width)',\n};\n\nconst PopoverContent = forwardRef<HTMLDivElement, PopoverContentPolicyProps>(\n ({ layout = 'scroll', presentation = 'default', width = 'content', ...props }, ref) => (\n <NinnaPopover.Content\n ref={ref}\n {...props}\n data-layout={layout}\n className={`${popoverWidthClasses[width] ?? ''} ${presentation === 'menu' ? 'p-1' : ''}`}\n />\n ),\n);\n\nPopoverContent.displayName = 'Popover.Content';\n\nfunction PopoverRoot(props: ComponentProps<typeof NinnaPopover>) {\n return <NinnaPopover {...props} />;\n}\n\nexport const Popover = Object.assign(PopoverRoot, {\n ...NinnaPopover,\n Content: PopoverContent,\n});\n"],"mappings":";;;;AAaA,MAAM,sBAAmG;CACrG,SAAS,KAAA;CACT,IAAI;CACJ,SAAS;AACb;AAEA,MAAM,iBAAiB,YAClB,EAAE,SAAS,UAAU,eAAe,WAAW,QAAQ,WAAW,GAAG,SAAS,QAC3E,oBAACA,QAAa,SAAd;CACS;CACL,GAAI;CACJ,eAAa;CACb,WAAW,GAAG,oBAAoB,UAAU,GAAG,GAAG,iBAAiB,SAAS,QAAQ;AACvF,CAAA,CAET;AAEA,eAAe,cAAc;AAE7B,SAAS,YAAY,OAA4C;CAC7D,OAAO,oBAACA,SAAD,EAAc,GAAI,MAAQ,CAAA;AACrC;AAEA,MAAaC,YAAU,OAAO,OAAO,aAAa;CAC9C,GAAGD;CACH,SAAS;AACb,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { ComponentProps } from "react";
2
+ import { TooltipContentProps, TooltipTriggerProps } from "@ninna-ui/overlays";
3
+ import { TooltipEngine } from "@ninna-ui/react-internal";
4
+ /** Shares one open delay across the tooltips inside it. */
5
+ export declare function TooltipProvider(props: ComponentProps<typeof TooltipEngine.Provider>): import("react").JSX.Element;
6
+ declare function Tooltip$1({ disabled, ...props }: ComponentProps<typeof TooltipEngine.Root> & {
7
+ disabled?: boolean;
8
+ }): import("react").JSX.Element;
9
+ export declare const TooltipTrigger: import("react").ForwardRefExoticComponent<TooltipTriggerProps & import("react").RefAttributes<HTMLButtonElement>>;
10
+ export declare const TooltipPopup: import("react").ForwardRefExoticComponent<Omit<TooltipContentProps, "color" | "hasArrow"> & import("react").RefAttributes<HTMLDivElement>>;
11
+ export { Tooltip$1 as Tooltip };
12
+ //# sourceMappingURL=Tooltip.d.ts.map
@@ -0,0 +1,54 @@
1
+ import { forwardRef, isValidElement } from "react";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { Tooltip } from "@ninna-ui/overlays";
4
+ import { Slot, TooltipEngine } from "@ninna-ui/react-internal";
5
+ // src/overlays/Tooltip.tsx
6
+ /** Shares one open delay across the tooltips inside it. */
7
+ function TooltipProvider(props) {
8
+ return /* @__PURE__ */ jsx(TooltipEngine.Provider, { ...props });
9
+ }
10
+ function Tooltip$1({ disabled, ...props }) {
11
+ return /* @__PURE__ */ jsx(TooltipEngine.Root, {
12
+ ...props,
13
+ open: disabled ? false : props.open
14
+ });
15
+ }
16
+ const TooltipTrigger = forwardRef(({ asChild, children, ...props }, ref) => {
17
+ const childProps = asChild && isValidElement(children) ? children.props : void 0;
18
+ if (props.disabled || childProps?.disabled) {
19
+ const Trigger = asChild ? Slot : "button";
20
+ return /* @__PURE__ */ jsx(Tooltip.Trigger, {
21
+ asChild: true,
22
+ children: /* @__PURE__ */ jsx("span", {
23
+ tabIndex: 0,
24
+ role: "button",
25
+ "aria-disabled": "true",
26
+ "aria-label": props["aria-label"] ?? childProps?.["aria-label"],
27
+ "aria-labelledby": props["aria-labelledby"] ?? childProps?.["aria-labelledby"],
28
+ className: "inline-flex [&>*]:pointer-events-none",
29
+ children: /* @__PURE__ */ jsx(Trigger, {
30
+ type: "button",
31
+ ...props,
32
+ ref,
33
+ children
34
+ })
35
+ })
36
+ });
37
+ }
38
+ return /* @__PURE__ */ jsx(Tooltip.Trigger, {
39
+ ...props,
40
+ ref,
41
+ asChild,
42
+ children
43
+ });
44
+ });
45
+ TooltipTrigger.displayName = "TooltipTrigger";
46
+ const TooltipPopup = forwardRef((props, ref) => /* @__PURE__ */ jsx(Tooltip.Content, {
47
+ ...props,
48
+ ref,
49
+ role: void 0
50
+ }));
51
+ TooltipPopup.displayName = "TooltipPopup";
52
+ export { Tooltip$1 as Tooltip, TooltipPopup, TooltipProvider, TooltipTrigger };
53
+
54
+ //# sourceMappingURL=Tooltip.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Tooltip.js","names":["Tooltip","NinnaTooltip"],"sources":["../../src/overlays/Tooltip.tsx"],"sourcesContent":["import { Tooltip as NinnaTooltip, type TooltipContentProps, type TooltipTriggerProps } from '@ninna-ui/overlays';\nimport { Slot, TooltipEngine } from '@ninna-ui/react-internal';\nimport { type ComponentProps, forwardRef, isValidElement } from 'react';\n\n/** Shares one open delay across the tooltips inside it. */\nexport function TooltipProvider(props: ComponentProps<typeof TooltipEngine.Provider>) {\n return <TooltipEngine.Provider {...props} />;\n}\n\nexport function Tooltip({ disabled, ...props }: ComponentProps<typeof TooltipEngine.Root> & { disabled?: boolean }) {\n return <TooltipEngine.Root {...props} open={disabled ? false : props.open} />;\n}\n\nexport const TooltipTrigger = forwardRef<HTMLButtonElement, TooltipTriggerProps>(\n ({ asChild, children, ...props }, ref) => {\n const childProps = asChild && isValidElement<TooltipTriggerProps>(children) ? children.props : undefined;\n\n if (props.disabled || childProps?.disabled) {\n const Trigger = asChild ? Slot : 'button';\n\n return (\n <NinnaTooltip.Trigger asChild>\n <span\n tabIndex={0}\n role=\"button\"\n aria-disabled=\"true\"\n aria-label={props['aria-label'] ?? childProps?.['aria-label']}\n aria-labelledby={props['aria-labelledby'] ?? childProps?.['aria-labelledby']}\n className=\"inline-flex [&>*]:pointer-events-none\"\n >\n <Trigger type=\"button\" {...props} ref={ref}>\n {children}\n </Trigger>\n </span>\n </NinnaTooltip.Trigger>\n );\n }\n\n return (\n <NinnaTooltip.Trigger {...props} ref={ref} asChild={asChild}>\n {children}\n </NinnaTooltip.Trigger>\n );\n },\n);\n\nTooltipTrigger.displayName = 'TooltipTrigger';\n\nexport const TooltipPopup = forwardRef<HTMLDivElement, Omit<TooltipContentProps, 'color' | 'hasArrow'>>(\n (props, ref) => (\n // Radix supplies the tooltip role on its visually hidden accessible description.\n <NinnaTooltip.Content {...props} ref={ref} role={undefined} />\n ),\n);\n\nTooltipPopup.displayName = 'TooltipPopup';\n"],"mappings":";;;;;;AAKA,SAAgB,gBAAgB,OAAsD;CAClF,OAAO,oBAAC,cAAc,UAAf,EAAwB,GAAI,MAAQ,CAAA;AAC/C;AAEA,SAAgBA,UAAQ,EAAE,UAAU,GAAG,SAA6E;CAChH,OAAO,oBAAC,cAAc,MAAf;EAAoB,GAAI;EAAO,MAAM,WAAW,QAAQ,MAAM;CAAO,CAAA;AAChF;AAEA,MAAa,iBAAiB,YACzB,EAAE,SAAS,UAAU,GAAG,SAAS,QAAQ;CACtC,MAAM,aAAa,WAAW,eAAoC,QAAQ,IAAI,SAAS,QAAQ,KAAA;CAE/F,IAAI,MAAM,YAAY,YAAY,UAAU;EACxC,MAAM,UAAU,UAAU,OAAO;EAEjC,OACI,oBAACC,QAAa,SAAd;GAAsB,SAAA;GAClB,UAAA,oBAAC,QAAD;IACI,UAAU;IACV,MAAK;IACL,iBAAc;IACd,cAAY,MAAM,iBAAiB,aAAa;IAChD,mBAAiB,MAAM,sBAAsB,aAAa;IAC1D,WAAU;IAEV,UAAA,oBAAC,SAAD;KAAS,MAAK;KAAS,GAAI;KAAY;KAClC;IACI,CAAA;GACP,CAAA;EACY,CAAA;CAE9B;CAEA,OACI,oBAACA,QAAa,SAAd;EAAsB,GAAI;EAAY;EAAc;EAC/C;CACiB,CAAA;AAE9B,CACJ;AAEA,eAAe,cAAc;AAE7B,MAAa,eAAe,YACvB,OAAO,QAEJ,oBAACA,QAAa,SAAd;CAAsB,GAAI;CAAY;CAAK,MAAM,KAAA;AAAY,CAAA,CAErE;AAEA,aAAa,cAAc"}
@@ -0,0 +1,9 @@
1
+ import { ActionModal } from "./ActionModal.js";
2
+ import { CommandPalette, CommandPaletteGroup, useCommandPaletteOption } from "./CommandPalette.js";
3
+ import { Drawer } from "./Drawer.js";
4
+ import { DropdownMenu } from "./DropdownMenu.js";
5
+ import { ImageViewer } from "./ImageViewer.js";
6
+ import { Modal } from "./Modal.js";
7
+ import { Popover } from "./Popover.js";
8
+ import { Tooltip, TooltipPopup, TooltipProvider, TooltipTrigger } from "./Tooltip.js";
9
+ export { ActionModal, CommandPalette, CommandPaletteGroup, Drawer, DropdownMenu, ImageViewer, Modal, Popover, Tooltip, TooltipPopup, TooltipProvider, TooltipTrigger, useCommandPaletteOption };
@@ -0,0 +1,84 @@
1
+ import { useEffect, useRef } from "react";
2
+ // src/overlays/useModalAutoFocus.ts
3
+ /** Focuses a dialog's first editable field when it opens, or once one appears, unless `focusFirstField` is
4
+ * false, such as while the caller focuses something else; turning it off stops a pending wait. */
5
+ function useModalAutoFocus(focusFirstField = true) {
6
+ const cleanup = useRef(void 0);
7
+ const returnFocus = useRef(null);
8
+ useEffect(() => () => cleanup.current?.(), []);
9
+ useEffect(() => {
10
+ if (!focusFirstField) cleanup.current?.();
11
+ }, [focusFirstField]);
12
+ const onOpenAutoFocus = (event) => {
13
+ cleanup.current?.();
14
+ const dialog = event.target;
15
+ if (!(dialog instanceof HTMLElement)) return;
16
+ returnFocus.current = document.activeElement instanceof HTMLElement ? document.activeElement : null;
17
+ if (!focusFirstField) return;
18
+ if (focusFirstEditable(dialog)) {
19
+ event.preventDefault();
20
+ return;
21
+ }
22
+ const observer = new MutationObserver(() => {
23
+ if (focusFirstEditable(dialog)) stop();
24
+ });
25
+ const stop = () => {
26
+ observer.disconnect();
27
+ dialog.removeEventListener("pointerdown", stop, true);
28
+ dialog.removeEventListener("keydown", stop, true);
29
+ cleanup.current = void 0;
30
+ };
31
+ cleanup.current = stop;
32
+ observer.observe(dialog, {
33
+ childList: true,
34
+ subtree: true,
35
+ attributes: true,
36
+ attributeFilter: [
37
+ "disabled",
38
+ "readonly",
39
+ "hidden",
40
+ "inert",
41
+ "class",
42
+ "style",
43
+ "aria-disabled",
44
+ "aria-readonly",
45
+ "aria-hidden"
46
+ ]
47
+ });
48
+ dialog.addEventListener("pointerdown", stop, true);
49
+ dialog.addEventListener("keydown", stop, true);
50
+ };
51
+ const onCloseAutoFocus = (event) => {
52
+ cleanup.current?.();
53
+ if (returnFocus.current?.isConnected) {
54
+ event.preventDefault();
55
+ returnFocus.current.focus({ preventScroll: true });
56
+ }
57
+ };
58
+ return {
59
+ onOpenAutoFocus,
60
+ onCloseAutoFocus
61
+ };
62
+ }
63
+ function focusFirstEditable(dialog) {
64
+ const candidates = dialog.querySelectorAll("input, textarea, select, [role=\"combobox\"], [role=\"switch\"], [role=\"checkbox\"], [role=\"radio\"], [contenteditable=\"true\"], [data-slot=\"field\"] button[aria-haspopup=\"dialog\"]");
65
+ for (const field of candidates) {
66
+ if (field.tabIndex < 0 || field.matches(":disabled, [readonly], [aria-disabled=\"true\"], [aria-readonly=\"true\"], input[type=\"hidden\"], input[type=\"button\"], input[type=\"submit\"], input[type=\"reset\"], input[type=\"image\"]") || field.closest("[hidden], [inert], [aria-hidden=\"true\"], details:not([open])") || field.closest("[role=\"dialog\"]") !== dialog || !isVisible(field, dialog)) continue;
67
+ field.focus({ preventScroll: true });
68
+ if (document.activeElement !== field) continue;
69
+ if (field instanceof HTMLTextAreaElement || field instanceof HTMLInputElement && field.selectionStart !== null) field.select();
70
+ return true;
71
+ }
72
+ return false;
73
+ }
74
+ function isVisible(field, dialog) {
75
+ if (getComputedStyle(field).visibility !== "visible") return false;
76
+ for (let element = field; element; element = element.parentElement) {
77
+ if (getComputedStyle(element).display === "none") return false;
78
+ if (element === dialog) return true;
79
+ }
80
+ return false;
81
+ }
82
+ export { useModalAutoFocus };
83
+
84
+ //# sourceMappingURL=useModalAutoFocus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useModalAutoFocus.js","names":[],"sources":["../../src/overlays/useModalAutoFocus.ts"],"sourcesContent":["import { useEffect, useRef } from 'react';\n\n/** Focuses a dialog's first editable field when it opens, or once one appears, unless `focusFirstField` is\n * false, such as while the caller focuses something else; turning it off stops a pending wait. */\nexport function useModalAutoFocus(focusFirstField = true) {\n const cleanup = useRef<(() => void) | undefined>(undefined);\n const returnFocus = useRef<HTMLElement | null>(null);\n\n useEffect(() => () => cleanup.current?.(), []);\n useEffect(() => {\n if (!focusFirstField) cleanup.current?.();\n }, [focusFirstField]);\n\n const onOpenAutoFocus = (event: Event) => {\n cleanup.current?.();\n\n const dialog = event.target;\n\n if (!(dialog instanceof HTMLElement)) return;\n\n returnFocus.current = document.activeElement instanceof HTMLElement ? document.activeElement : null;\n\n if (!focusFirstField) return;\n\n if (focusFirstEditable(dialog)) {\n event.preventDefault();\n\n return;\n }\n\n const observer = new MutationObserver(() => {\n if (focusFirstEditable(dialog)) stop();\n });\n\n const stop = () => {\n observer.disconnect();\n dialog.removeEventListener('pointerdown', stop, true);\n dialog.removeEventListener('keydown', stop, true);\n cleanup.current = undefined;\n };\n\n cleanup.current = stop;\n observer.observe(dialog, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: [\n 'disabled',\n 'readonly',\n 'hidden',\n 'inert',\n 'class',\n 'style',\n 'aria-disabled',\n 'aria-readonly',\n 'aria-hidden',\n ],\n });\n dialog.addEventListener('pointerdown', stop, true);\n dialog.addEventListener('keydown', stop, true);\n };\n\n const onCloseAutoFocus = (event: Event) => {\n cleanup.current?.();\n\n if (returnFocus.current?.isConnected) {\n event.preventDefault();\n returnFocus.current.focus({ preventScroll: true });\n }\n };\n\n return { onOpenAutoFocus, onCloseAutoFocus };\n}\n\nfunction focusFirstEditable(dialog: HTMLElement): boolean {\n const candidates = dialog.querySelectorAll<HTMLElement>(\n 'input, textarea, select, [role=\"combobox\"], [role=\"switch\"], [role=\"checkbox\"], [role=\"radio\"], [contenteditable=\"true\"], [data-slot=\"field\"] button[aria-haspopup=\"dialog\"]',\n );\n\n for (const field of candidates) {\n if (\n field.tabIndex < 0 ||\n field.matches(\n ':disabled, [readonly], [aria-disabled=\"true\"], [aria-readonly=\"true\"], input[type=\"hidden\"], input[type=\"button\"], input[type=\"submit\"], input[type=\"reset\"], input[type=\"image\"]',\n ) ||\n field.closest('[hidden], [inert], [aria-hidden=\"true\"], details:not([open])') ||\n field.closest('[role=\"dialog\"]') !== dialog ||\n !isVisible(field, dialog)\n )\n continue;\n\n field.focus({ preventScroll: true });\n\n if (document.activeElement !== field) continue;\n\n if (\n field instanceof HTMLTextAreaElement ||\n (field instanceof HTMLInputElement && field.selectionStart !== null)\n ) {\n field.select();\n }\n\n return true;\n }\n\n return false;\n}\n\nfunction isVisible(field: HTMLElement, dialog: HTMLElement): boolean {\n if (getComputedStyle(field).visibility !== 'visible') return false;\n\n for (let element: HTMLElement | null = field; element; element = element.parentElement) {\n if (getComputedStyle(element).display === 'none') return false;\n\n if (element === dialog) return true;\n }\n\n return false;\n}\n"],"mappings":";;;;AAIA,SAAgB,kBAAkB,kBAAkB,MAAM;CACtD,MAAM,UAAU,OAAiC,KAAA,CAAS;CAC1D,MAAM,cAAc,OAA2B,IAAI;CAEnD,sBAAsB,QAAQ,UAAU,GAAG,CAAC,CAAC;CAC7C,gBAAgB;EACZ,IAAI,CAAC,iBAAiB,QAAQ,UAAU;CAC5C,GAAG,CAAC,eAAe,CAAC;CAEpB,MAAM,mBAAmB,UAAiB;EACtC,QAAQ,UAAU;EAElB,MAAM,SAAS,MAAM;EAErB,IAAI,EAAE,kBAAkB,cAAc;EAEtC,YAAY,UAAU,SAAS,yBAAyB,cAAc,SAAS,gBAAgB;EAE/F,IAAI,CAAC,iBAAiB;EAEtB,IAAI,mBAAmB,MAAM,GAAG;GAC5B,MAAM,eAAe;GAErB;EACJ;EAEA,MAAM,WAAW,IAAI,uBAAuB;GACxC,IAAI,mBAAmB,MAAM,GAAG,KAAK;EACzC,CAAC;EAED,MAAM,aAAa;GACf,SAAS,WAAW;GACpB,OAAO,oBAAoB,eAAe,MAAM,IAAI;GACpD,OAAO,oBAAoB,WAAW,MAAM,IAAI;GAChD,QAAQ,UAAU,KAAA;EACtB;EAEA,QAAQ,UAAU;EAClB,SAAS,QAAQ,QAAQ;GACrB,WAAW;GACX,SAAS;GACT,YAAY;GACZ,iBAAiB;IACb;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;GACJ;EACJ,CAAC;EACD,OAAO,iBAAiB,eAAe,MAAM,IAAI;EACjD,OAAO,iBAAiB,WAAW,MAAM,IAAI;CACjD;CAEA,MAAM,oBAAoB,UAAiB;EACvC,QAAQ,UAAU;EAElB,IAAI,YAAY,SAAS,aAAa;GAClC,MAAM,eAAe;GACrB,YAAY,QAAQ,MAAM,EAAE,eAAe,KAAK,CAAC;EACrD;CACJ;CAEA,OAAO;EAAE;EAAiB;CAAiB;AAC/C;AAEA,SAAS,mBAAmB,QAA8B;CACtD,MAAM,aAAa,OAAO,iBACtB,4LACJ;CAEA,KAAK,MAAM,SAAS,YAAY;EAC5B,IACI,MAAM,WAAW,KACjB,MAAM,QACF,iMACJ,KACA,MAAM,QAAQ,gEAA8D,KAC5E,MAAM,QAAQ,mBAAiB,MAAM,UACrC,CAAC,UAAU,OAAO,MAAM,GAExB;EAEJ,MAAM,MAAM,EAAE,eAAe,KAAK,CAAC;EAEnC,IAAI,SAAS,kBAAkB,OAAO;EAEtC,IACI,iBAAiB,uBAChB,iBAAiB,oBAAoB,MAAM,mBAAmB,MAE/D,MAAM,OAAO;EAGjB,OAAO;CACX;CAEA,OAAO;AACX;AAEA,SAAS,UAAU,OAAoB,QAA8B;CACjE,IAAI,iBAAiB,KAAK,CAAC,CAAC,eAAe,WAAW,OAAO;CAE7D,KAAK,IAAI,UAA8B,OAAO,SAAS,UAAU,QAAQ,eAAe;EACpF,IAAI,iBAAiB,OAAO,CAAC,CAAC,YAAY,QAAQ,OAAO;EAEzD,IAAI,YAAY,QAAQ,OAAO;CACnC;CAEA,OAAO;AACX"}
@@ -0,0 +1,43 @@
1
+ import { useLayoutEffect, useState } from "react";
2
+ // src/overlays/useScrollFade.ts
3
+ /** Attach to the scroll owner and its content so async content and viewport changes update the mask. */
4
+ function useScrollFade() {
5
+ const [viewport, setViewport] = useState(null);
6
+ const [content, setContent] = useState(null);
7
+ useLayoutEffect(() => {
8
+ if (!viewport || !content) return;
9
+ const measure = () => {
10
+ const { scrollTop, scrollHeight, clientHeight } = viewport;
11
+ viewport.style.setProperty("--scroll-fade-top", `${Math.max(0, scrollTop)}px`);
12
+ viewport.style.setProperty("--scroll-fade-bottom", `${Math.max(0, scrollHeight - clientHeight - scrollTop)}px`);
13
+ };
14
+ const observer = new ResizeObserver(measure);
15
+ const observeContent = () => {
16
+ observer.disconnect();
17
+ observer.observe(viewport);
18
+ observer.observe(content);
19
+ content.querySelectorAll("*").forEach((element) => observer.observe(element));
20
+ measure();
21
+ };
22
+ const mutations = new MutationObserver(observeContent);
23
+ mutations.observe(content, {
24
+ childList: true,
25
+ subtree: true
26
+ });
27
+ viewport.addEventListener("scroll", measure, { passive: true });
28
+ observeContent();
29
+ return () => {
30
+ mutations.disconnect();
31
+ observer.disconnect();
32
+ viewport.removeEventListener("scroll", measure);
33
+ };
34
+ }, [viewport, content]);
35
+ return {
36
+ setViewport,
37
+ setContent,
38
+ className: "[mask-image:linear-gradient(to_bottom,transparent,black_min(1.5rem,var(--scroll-fade-top,0px)),black_calc(100%_-_min(1.5rem,var(--scroll-fade-bottom,0px))),transparent)] focus-visible:[mask-image:none] has-[:focus-visible]:[mask-image:none]"
39
+ };
40
+ }
41
+ export { useScrollFade };
42
+
43
+ //# sourceMappingURL=useScrollFade.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useScrollFade.js","names":[],"sources":["../../src/overlays/useScrollFade.ts"],"sourcesContent":["import { useLayoutEffect, useState } from 'react';\n\n/** Attach to the scroll owner and its content so async content and viewport changes update the mask. */\nexport function useScrollFade() {\n const [viewport, setViewport] = useState<HTMLDivElement | null>(null);\n const [content, setContent] = useState<HTMLDivElement | null>(null);\n\n useLayoutEffect(() => {\n if (!viewport || !content) return;\n\n const measure = () => {\n const { scrollTop, scrollHeight, clientHeight } = viewport;\n\n viewport.style.setProperty('--scroll-fade-top', `${Math.max(0, scrollTop)}px`);\n viewport.style.setProperty(\n '--scroll-fade-bottom',\n `${Math.max(0, scrollHeight - clientHeight - scrollTop)}px`,\n );\n };\n const observer = new ResizeObserver(measure);\n\n const observeContent = () => {\n observer.disconnect();\n observer.observe(viewport);\n observer.observe(content);\n // Fill layouts can keep ancestors fixed while descendants change the scroll extent.\n content.querySelectorAll('*').forEach((element) => observer.observe(element));\n measure();\n };\n const mutations = new MutationObserver(observeContent);\n\n mutations.observe(content, { childList: true, subtree: true });\n viewport.addEventListener('scroll', measure, { passive: true });\n observeContent();\n\n return () => {\n mutations.disconnect();\n observer.disconnect();\n viewport.removeEventListener('scroll', measure);\n };\n }, [viewport, content]);\n\n return {\n setViewport,\n setContent,\n className:\n '[mask-image:linear-gradient(to_bottom,transparent,black_min(1.5rem,var(--scroll-fade-top,0px)),black_calc(100%_-_min(1.5rem,var(--scroll-fade-bottom,0px))),transparent)] focus-visible:[mask-image:none] has-[:focus-visible]:[mask-image:none]',\n };\n}\n"],"mappings":";;;AAGA,SAAgB,gBAAgB;CAC5B,MAAM,CAAC,UAAU,eAAe,SAAgC,IAAI;CACpE,MAAM,CAAC,SAAS,cAAc,SAAgC,IAAI;CAElE,sBAAsB;EAClB,IAAI,CAAC,YAAY,CAAC,SAAS;EAE3B,MAAM,gBAAgB;GAClB,MAAM,EAAE,WAAW,cAAc,iBAAiB;GAElD,SAAS,MAAM,YAAY,qBAAqB,GAAG,KAAK,IAAI,GAAG,SAAS,EAAE,GAAG;GAC7E,SAAS,MAAM,YACX,wBACA,GAAG,KAAK,IAAI,GAAG,eAAe,eAAe,SAAS,EAAE,GAC5D;EACJ;EACA,MAAM,WAAW,IAAI,eAAe,OAAO;EAE3C,MAAM,uBAAuB;GACzB,SAAS,WAAW;GACpB,SAAS,QAAQ,QAAQ;GACzB,SAAS,QAAQ,OAAO;GAExB,QAAQ,iBAAiB,GAAG,CAAC,CAAC,SAAS,YAAY,SAAS,QAAQ,OAAO,CAAC;GAC5E,QAAQ;EACZ;EACA,MAAM,YAAY,IAAI,iBAAiB,cAAc;EAErD,UAAU,QAAQ,SAAS;GAAE,WAAW;GAAM,SAAS;EAAK,CAAC;EAC7D,SAAS,iBAAiB,UAAU,SAAS,EAAE,SAAS,KAAK,CAAC;EAC9D,eAAe;EAEf,aAAa;GACT,UAAU,WAAW;GACrB,SAAS,WAAW;GACpB,SAAS,oBAAoB,UAAU,OAAO;EAClD;CACJ,GAAG,CAAC,UAAU,OAAO,CAAC;CAEtB,OAAO;EACH;EACA;EACA,WACI;CACR;AACJ"}