plass-ui 1.7.0 → 1.8.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 (335) hide show
  1. package/CHANGELOG.md +229 -0
  2. package/README.md +3 -3
  3. package/dist/components/accordion/PlAccordion.d.ts +11 -4
  4. package/dist/components/accordion/PlAccordion.js +1 -1
  5. package/dist/components/alert/PlAlert.d.ts +2 -0
  6. package/dist/components/alert/PlAlert.js +1 -1
  7. package/dist/components/anchor/PlAnchor.js +1 -1
  8. package/dist/components/animate-appear/PlAnimateAppear.js +1 -1
  9. package/dist/components/animate-counter/PlAnimateCounter.d.ts +5 -2
  10. package/dist/components/animate-counter/PlAnimateCounter.js +1 -1
  11. package/dist/components/animate-float/PlAnimateFloat.js +1 -1
  12. package/dist/components/animate-headline/PlAnimateHeadline.js +1 -1
  13. package/dist/components/animate-lighting/PlAnimateLighting.js +1 -1
  14. package/dist/components/animate-marquee/PlAnimateMarquee.js +1 -1
  15. package/dist/components/animate-scramble/PlAnimateScramble.js +1 -1
  16. package/dist/components/animate-shake/PlAnimateShake.js +1 -1
  17. package/dist/components/animate-split/PlAnimateSplit.js +1 -1
  18. package/dist/components/animate-typing/PlAnimateTyping.js +1 -1
  19. package/dist/components/app-logo/PlAppLogo.d.ts +51 -15
  20. package/dist/components/area-chart/PlAreaChart.js +1 -1
  21. package/dist/components/avatar/PlAvatar.js +1 -1
  22. package/dist/components/badge/PlBadge.d.ts +2 -0
  23. package/dist/components/bar-chart/PlBarChart.js +1 -1
  24. package/dist/components/blockquote/PlBlockquote.d.ts +2 -0
  25. package/dist/components/bottom-navigation/PlBottomNavigation.d.ts +17 -5
  26. package/dist/components/bottom-navigation/PlBottomNavigation.js +1 -1
  27. package/dist/components/box/PlBox.d.ts +2 -0
  28. package/dist/components/breadcrumb/PlBreadcrumb.d.ts +16 -3
  29. package/dist/components/breadcrumb/PlBreadcrumb.js +1 -1
  30. package/dist/components/button/PlButton.d.ts +2 -0
  31. package/dist/components/button/PlButton.js +1 -1
  32. package/dist/components/button-group/PlButtonGroup.d.ts +2 -0
  33. package/dist/components/calendar/PlCalendar.js +1 -1
  34. package/dist/components/card/PlCard.d.ts +4 -1
  35. package/dist/components/card/PlCard.js +1 -1
  36. package/dist/components/carousel/PlCarousel.d.ts +2 -0
  37. package/dist/components/carousel/PlCarousel.js +1 -1
  38. package/dist/components/checkbox/PlCheckbox.js +1 -1
  39. package/dist/components/chip/PlChip.d.ts +2 -0
  40. package/dist/components/chip/PlChip.js +1 -1
  41. package/dist/components/code-block/PlCodeBlock.js +1 -1
  42. package/dist/components/collapsible/PlCollapsible.d.ts +2 -0
  43. package/dist/components/collapsible/PlCollapsible.js +1 -1
  44. package/dist/components/color-picker/PlColorPicker.d.ts +2 -0
  45. package/dist/components/color-picker/PlColorPicker.js +1 -1
  46. package/dist/components/combobox/PlCombobox.d.ts +3 -1
  47. package/dist/components/combobox/PlCombobox.js +1 -1
  48. package/dist/components/command-palette/PlCommandPalette.js +1 -1
  49. package/dist/components/confirm/PlConfirmProvider.js +1 -1
  50. package/dist/components/data-table/PlDataTable.d.ts +2 -0
  51. package/dist/components/data-table/PlDataTable.js +1 -1
  52. package/dist/components/date-picker/PlDatePicker.js +1 -1
  53. package/dist/components/date-range-picker/PlDateRangePicker.js +1 -1
  54. package/dist/components/date-time-picker/PlDateTimePicker.js +1 -1
  55. package/dist/components/drawer/PlDrawer.d.ts +27 -2
  56. package/dist/components/drawer/PlDrawer.js +1 -1
  57. package/dist/components/empty/PlEmpty.d.ts +4 -1
  58. package/dist/components/empty/PlEmpty.js +1 -1
  59. package/dist/components/file-picker/PlFilePicker.d.ts +31 -0
  60. package/dist/components/file-picker/PlFilePicker.js +1 -1
  61. package/dist/components/file-picker/index.d.ts +1 -1
  62. package/dist/components/floating-bottom-navigation/PlFloatingBottomNavigation.d.ts +10 -0
  63. package/dist/components/floating-bottom-navigation/PlFloatingBottomNavigation.js +1 -1
  64. package/dist/components/footer/PlFooter.js +1 -1
  65. package/dist/components/gallery/PlGallery.js +1 -1
  66. package/dist/components/gauge-chart/PlGaugeChart.d.ts +11 -2
  67. package/dist/components/gauge-chart/PlGaugeChart.js +1 -1
  68. package/dist/components/header/PlHeader.js +1 -1
  69. package/dist/components/heatmap-chart/PlHeatmapChart.d.ts +1 -1
  70. package/dist/components/heatmap-chart/PlHeatmapChart.js +1 -1
  71. package/dist/components/hot-keys/PlHotKeys.d.ts +4 -0
  72. package/dist/components/image/PlImage.js +1 -1
  73. package/dist/components/image/PlImagePreview.d.ts +3 -2
  74. package/dist/components/list/PlList.d.ts +18 -5
  75. package/dist/components/list/PlList.js +1 -1
  76. package/dist/components/menu/PlMenu.d.ts +19 -7
  77. package/dist/components/menu/PlMenu.js +1 -1
  78. package/dist/components/menubar/PlMenubar.js +1 -1
  79. package/dist/components/meter/PlMeter.js +1 -1
  80. package/dist/components/mockup/PlMockup.d.ts +4 -3
  81. package/dist/components/mockup/PlMockup.js +1 -1
  82. package/dist/components/modal/PlModal.js +1 -1
  83. package/dist/components/navigation-menu/PlNavigationMenu.d.ts +52 -8
  84. package/dist/components/navigation-menu/PlNavigationMenu.js +1 -1
  85. package/dist/components/number-field/PlNumberField.d.ts +3 -1
  86. package/dist/components/number-field/PlNumberField.js +1 -1
  87. package/dist/components/otp-field/PlOtpField.d.ts +2 -0
  88. package/dist/components/otp-field/PlOtpField.js +1 -1
  89. package/dist/components/overlay/PlOverlay.js +1 -1
  90. package/dist/components/page-layout/PlPageLayout.js +1 -1
  91. package/dist/components/pagination/PlPagination.d.ts +2 -0
  92. package/dist/components/panes/PlPanes.d.ts +4 -1
  93. package/dist/components/panes/PlPanes.js +1 -1
  94. package/dist/components/pie-chart/PlPieChart.d.ts +1 -1
  95. package/dist/components/pie-chart/PlPieChart.js +1 -1
  96. package/dist/components/pill/PlPill.d.ts +2 -0
  97. package/dist/components/pill/PlPill.js +1 -1
  98. package/dist/components/popover/PlPopover.js +1 -1
  99. package/dist/components/progress-box/PlProgressBox.js +1 -1
  100. package/dist/components/progress-circular/PlProgressCircular.d.ts +11 -1
  101. package/dist/components/progress-circular/PlProgressCircular.js +1 -1
  102. package/dist/components/progress-linear/PlProgressLinear.js +1 -1
  103. package/dist/components/radio-group/PlRadioGroup.js +1 -1
  104. package/dist/components/scatter-chart/PlScatterChart.js +1 -1
  105. package/dist/components/scroll-zone/PlScrollZone.d.ts +2 -0
  106. package/dist/components/scroll-zone/PlScrollZone.js +1 -1
  107. package/dist/components/segmented-button/PlSegmentedButton.d.ts +6 -1
  108. package/dist/components/segmented-button/PlSegmentedButton.js +1 -1
  109. package/dist/components/select/PlSelect.d.ts +2 -0
  110. package/dist/components/select/PlSelect.js +1 -1
  111. package/dist/components/sidebar/PlSidebar.d.ts +12 -0
  112. package/dist/components/sidebar/PlSidebar.js +1 -1
  113. package/dist/components/sidebar/PlSidebarTrigger.d.ts +2 -0
  114. package/dist/components/slider/PlSlider.d.ts +2 -1
  115. package/dist/components/slider/PlSlider.js +1 -1
  116. package/dist/components/sparkline/PlSparkline.d.ts +15 -3
  117. package/dist/components/sparkline/PlSparkline.js +1 -1
  118. package/dist/components/stepper/PlStepper.d.ts +11 -0
  119. package/dist/components/stepper/PlStepper.js +1 -1
  120. package/dist/components/switch/PlSwitch.js +1 -1
  121. package/dist/components/table/PlTable.d.ts +2 -0
  122. package/dist/components/tabs/PlTabs.js +1 -1
  123. package/dist/components/text-field/PlTextField.d.ts +2 -0
  124. package/dist/components/text-field/PlTextField.js +1 -1
  125. package/dist/components/text-link/PlTextLink.js +1 -1
  126. package/dist/components/time-picker/PlTimePicker.js +1 -1
  127. package/dist/components/timeline-chart/PlTimelineChart.js +1 -1
  128. package/dist/components/toast/PlToast.d.ts +2 -0
  129. package/dist/components/toast/PlToast.js +1 -1
  130. package/dist/components/toggle/PlToggle.js +1 -1
  131. package/dist/components/toolbar/PlToolbar.d.ts +2 -0
  132. package/dist/components/tour/PlTour.js +1 -1
  133. package/dist/components/transfer/PlTransfer.d.ts +2 -0
  134. package/dist/components/transfer/PlTransfer.js +1 -1
  135. package/dist/components/tree/PlTree.d.ts +12 -0
  136. package/dist/components/tree/PlTree.js +1 -1
  137. package/dist/components/tree-select/PlTreeSelect.js +1 -1
  138. package/dist/components/typography/PlTypography.d.ts +20 -7
  139. package/dist/components/typography/PlTypography.js +1 -1
  140. package/dist/components/visually-hidden/PlVisuallyHidden.d.ts +12 -3
  141. package/dist/components/visually-hidden/PlVisuallyHidden.js +1 -1
  142. package/dist/components/window-pane/PlWindowPane.d.ts +3 -0
  143. package/dist/components/window-pane/PlWindowPane.js +1 -1
  144. package/dist/css/accordion.css +4 -0
  145. package/dist/css/alert.css +5 -0
  146. package/dist/css/anchor.css +6 -0
  147. package/dist/css/animate-appear.css +3 -0
  148. package/dist/css/animate-blink.css +3 -0
  149. package/dist/css/animate-counter.css +4 -0
  150. package/dist/css/animate-fade.css +3 -0
  151. package/dist/css/animate-float.css +3 -0
  152. package/dist/css/animate-grow.css +3 -0
  153. package/dist/css/animate-headline.css +3 -0
  154. package/dist/css/animate-lighting.css +4 -0
  155. package/dist/css/animate-marquee.css +4 -0
  156. package/dist/css/animate-reveal.css +3 -0
  157. package/dist/css/animate-rotate.css +3 -0
  158. package/dist/css/animate-scramble.css +5 -0
  159. package/dist/css/animate-shake.css +3 -0
  160. package/dist/css/animate-slide.css +3 -0
  161. package/dist/css/animate-split.css +4 -0
  162. package/dist/css/animate-typing.css +4 -0
  163. package/dist/css/animate-zoom.css +3 -0
  164. package/dist/css/app-logo.css +2 -0
  165. package/dist/css/area-chart.css +12 -0
  166. package/dist/css/aspect-ratio.css +2 -0
  167. package/dist/css/avatar.css +2 -0
  168. package/dist/css/back-top.css +11 -0
  169. package/dist/css/badge.css +2 -0
  170. package/dist/css/bar-chart.css +10 -0
  171. package/dist/css/base.css +2 -3
  172. package/dist/css/blockquote.css +2 -0
  173. package/dist/css/bottom-navigation.css +4 -0
  174. package/dist/css/box.css +2 -0
  175. package/dist/css/breadcrumb.css +6 -0
  176. package/dist/css/button-group.css +2 -0
  177. package/dist/css/button.css +7 -0
  178. package/dist/css/calendar.css +17 -0
  179. package/dist/css/card.css +2 -0
  180. package/dist/css/carousel.css +10 -0
  181. package/dist/css/chat-bubble.css +6 -0
  182. package/dist/css/checkbox.css +3 -0
  183. package/dist/css/chip.css +8 -0
  184. package/dist/css/code-block.css +6 -0
  185. package/dist/css/collapsible.css +3 -0
  186. package/dist/css/color-picker.css +17 -0
  187. package/dist/css/combobox.css +10 -0
  188. package/dist/css/command-palette.css +7 -0
  189. package/dist/css/confirm.css +9 -0
  190. package/dist/css/container.css +5 -0
  191. package/dist/css/data-list.css +2 -0
  192. package/dist/css/data-table.css +15 -0
  193. package/dist/css/date-picker.css +16 -0
  194. package/dist/css/date-range-picker.css +16 -0
  195. package/dist/css/date-time-picker.css +16 -0
  196. package/dist/css/divider.css +2 -0
  197. package/dist/css/drawer.css +6 -0
  198. package/dist/css/empty.css +2 -0
  199. package/dist/css/fieldset.css +2 -0
  200. package/dist/css/file-picker.css +8 -0
  201. package/dist/css/flex.css +5 -0
  202. package/dist/css/floating-action-button.css +7 -0
  203. package/dist/css/floating-bottom-navigation.css +5 -0
  204. package/dist/css/footer.css +6 -0
  205. package/dist/css/form.css +2 -0
  206. package/dist/css/gallery.css +15 -0
  207. package/dist/css/gauge-chart.css +11 -0
  208. package/dist/css/grid.css +5 -0
  209. package/dist/css/header.css +6 -0
  210. package/dist/css/heatmap-chart.css +10 -0
  211. package/dist/css/highlight.css +2 -0
  212. package/dist/css/hot-keys.css +3 -0
  213. package/dist/css/hover-card.css +9 -0
  214. package/dist/css/how-to-steps.css +3 -0
  215. package/dist/css/icon-button.css +7 -0
  216. package/dist/css/icon.css +1 -0
  217. package/dist/css/image.css +7 -0
  218. package/dist/css/line-chart.css +12 -0
  219. package/dist/css/list.css +2 -0
  220. package/dist/css/menu.css +5 -0
  221. package/dist/css/menubar.css +5 -0
  222. package/dist/css/meter.css +6 -0
  223. package/dist/css/mockup.css +4 -0
  224. package/dist/css/modal.css +5 -0
  225. package/dist/css/navigation-menu.css +4 -0
  226. package/dist/css/number-field.css +10 -0
  227. package/dist/css/otp-field.css +6 -0
  228. package/dist/css/overlay.css +4 -0
  229. package/dist/css/page-layout.css +7 -0
  230. package/dist/css/pagination.css +8 -0
  231. package/dist/css/panes.css +7 -0
  232. package/dist/css/pie-chart.css +10 -0
  233. package/dist/css/pill.css +4 -0
  234. package/dist/css/popconfirm.css +12 -0
  235. package/dist/css/popover.css +11 -0
  236. package/dist/css/portal.css +1 -0
  237. package/dist/css/progress-box.css +5 -0
  238. package/dist/css/progress-circular.css +5 -0
  239. package/dist/css/progress-linear.css +5 -0
  240. package/dist/css/radio-group.css +3 -0
  241. package/dist/css/rating.css +6 -0
  242. package/dist/css/scatter-chart.css +10 -0
  243. package/dist/css/scroll-area.css +2 -0
  244. package/dist/css/scroll-zone.css +15 -0
  245. package/dist/css/segmented-button.css +5 -0
  246. package/dist/css/select.css +9 -0
  247. package/dist/css/show.css +1 -0
  248. package/dist/css/sidebar.css +16 -0
  249. package/dist/css/skeleton.css +2 -0
  250. package/dist/css/slider.css +3 -0
  251. package/dist/css/sparkline.css +10 -0
  252. package/dist/css/spoiler.css +10 -0
  253. package/dist/css/stack.css +5 -0
  254. package/dist/css/stat.css +2 -0
  255. package/dist/css/stepper.css +8 -0
  256. package/dist/css/switch.css +3 -0
  257. package/dist/css/table.css +3 -0
  258. package/dist/css/tabs.css +7 -0
  259. package/dist/css/text-field.css +8 -0
  260. package/dist/css/text-link.css +6 -0
  261. package/dist/css/time-picker.css +16 -0
  262. package/dist/css/timeline-chart.css +10 -0
  263. package/dist/css/timeline.css +6 -0
  264. package/dist/css/toast.css +5 -0
  265. package/dist/css/toggle.css +5 -0
  266. package/dist/css/toolbar.css +2 -0
  267. package/dist/css/tooltip.css +9 -0
  268. package/dist/css/tour.css +10 -0
  269. package/dist/css/transfer.css +13 -0
  270. package/dist/css/tree-select.css +14 -0
  271. package/dist/css/tree.css +3 -0
  272. package/dist/css/visually-hidden.css +2 -0
  273. package/dist/css/window-pane.css +9 -0
  274. package/dist/internal/animate.d.ts +59 -4
  275. package/dist/internal/animate.js +1 -1
  276. package/dist/internal/bottom-bar.js +1 -1
  277. package/dist/internal/calendar.js +1 -1
  278. package/dist/internal/chart-frame.d.ts +132 -11
  279. package/dist/internal/chart-frame.js +1 -1
  280. package/dist/internal/commit-change.d.ts +38 -0
  281. package/dist/internal/commit-change.js +1 -0
  282. package/dist/internal/data-table.d.ts +2 -2
  283. package/dist/internal/data-table.js +1 -1
  284. package/dist/internal/date.d.ts +9 -0
  285. package/dist/internal/date.js +1 -1
  286. package/dist/internal/defaults.d.ts +34 -1
  287. package/dist/internal/defaults.js +1 -1
  288. package/dist/internal/direction.d.ts +8 -2
  289. package/dist/internal/direction.js +1 -1
  290. package/dist/internal/form.d.ts +43 -0
  291. package/dist/internal/form.js +1 -1
  292. package/dist/internal/format.d.ts +4 -1
  293. package/dist/internal/format.js +1 -1
  294. package/dist/internal/gallery.d.ts +28 -0
  295. package/dist/internal/gallery.js +1 -1
  296. package/dist/internal/glow.d.ts +7 -2
  297. package/dist/internal/glow.js +1 -1
  298. package/dist/internal/heading.d.ts +11 -0
  299. package/dist/internal/heading.js +1 -0
  300. package/dist/internal/highlight.d.ts +4 -2
  301. package/dist/internal/highlight.js +1 -1
  302. package/dist/internal/labels.d.ts +5 -0
  303. package/dist/internal/labels.js +1 -1
  304. package/dist/internal/layout-box.d.ts +35 -0
  305. package/dist/internal/layout-box.js +1 -0
  306. package/dist/internal/lazy.d.ts +37 -0
  307. package/dist/internal/lazy.js +1 -0
  308. package/dist/internal/media.d.ts +6 -0
  309. package/dist/internal/media.js +1 -1
  310. package/dist/internal/page-layout.d.ts +24 -13
  311. package/dist/internal/page-layout.js +1 -1
  312. package/dist/internal/picker.d.ts +1 -1
  313. package/dist/internal/picker.js +1 -1
  314. package/dist/internal/progress.d.ts +24 -0
  315. package/dist/internal/progress.js +1 -1
  316. package/dist/internal/search.d.ts +12 -0
  317. package/dist/internal/search.js +1 -1
  318. package/dist/internal/sizer.d.ts +15 -8
  319. package/dist/internal/sizer.js +1 -1
  320. package/dist/internal/styles.d.ts +22 -6
  321. package/dist/internal/styles.js +1 -1
  322. package/dist/internal/wheel.d.ts +13 -1
  323. package/dist/internal/wheel.js +1 -1
  324. package/dist/internal/window.js +1 -1
  325. package/dist/locales/de.js +1 -1
  326. package/dist/locales/es.js +1 -1
  327. package/dist/locales/fr.js +1 -1
  328. package/dist/locales/ja.js +1 -1
  329. package/dist/locales/ko.js +1 -1
  330. package/dist/locales/zh-Hans.js +1 -1
  331. package/dist/styles.css +1 -1
  332. package/dist/tailwind.css +758 -40
  333. package/dist/tokens.css +758 -40
  334. package/dist/types.d.ts +14 -2
  335. package/package.json +19 -18
@@ -1,3 +1,4 @@
1
+ import type { PlassResponsive } from '../types.js';
1
2
  /**
2
3
  * A tile's proportion as the number the layouts do arithmetic on.
3
4
  *
@@ -78,3 +79,30 @@ export declare function masonryRows(ratios: readonly number[], columns: number,
78
79
  tracks: PlassMasonryTrack[];
79
80
  tiles: PlassMasonryTile[];
80
81
  };
82
+ /**
83
+ * A column count as a gallery uses it: a whole number of lanes, and at least
84
+ * one. The column slot and the masonry deal both read it through here, so the
85
+ * columns the stylesheet draws are the columns the tiles were dealt into.
86
+ */
87
+ export declare function laneCount(value: number): number;
88
+ /**
89
+ * A masonry dealt at every rung of the breakpoint ladder, as the slots the
90
+ * stylesheet switches between.
91
+ *
92
+ * Which lane a tile lands in depends on the heights of the tiles before it, so
93
+ * a stylesheet cannot work it out — but it can choose between answers worked
94
+ * out ahead of time. The deal is made once per lane count the columns name,
95
+ * and the rung it starts at is written as slots: the list's rows as
96
+ * `--p-lane-rows-{rung}`, and each tile's place and the number of rows it spans
97
+ * as `--p-lane-area-{rung}` and `--p-lane-span-{rung}`. A rung that changes
98
+ * nothing is left out, and the stylesheet carries the rung below up through it,
99
+ * so a server's markup is laid out right at every width before any script has
100
+ * run, and a resize redraws without React hearing about it.
101
+ *
102
+ * `track` writes one row track as CSS, because the gap and the caption rows
103
+ * are lengths only the gallery knows.
104
+ */
105
+ export declare function masonrySlots(ratios: readonly number[], columns: PlassResponsive<number>, captions: boolean, track: (track: PlassMasonryTrack) => string): {
106
+ list: Record<string, string>;
107
+ tiles: Array<Record<string, string>>;
108
+ };
@@ -1 +1 @@
1
- import{isSideways as t,quartersOf as r}from"./image.js";export function ratioOf(t,r){if(void 0===t)return r;if("number"==typeof t)return t>0?t:r;const[n,o]=t.split("/"),e=void 0===o?Number(n):Number(n)/Number(o);return Number.isFinite(e)&&e>0?e:r}export function isTurned(n){return void 0!==n&&t(r(n))}export function shownRatio(t,r){return isTurned(r)?1/t:t}export function dealColumns(t,r){const n=Array.from({length:r},()=>[]),o=new Array(r).fill(0);return t.forEach((t,e)=>{let s=0;for(let t=1;t<r;t+=1)o[t]<o[s]&&(s=t);n[s].push(e),o[s]+=1/t}),n}export function masonryRows(t,r,n){const o=dealColumns(t,r),e=[],s=[],u=[];o.forEach((r,n)=>{let o=0;r.forEach((i,a)=>{o+=1/t[i],e[i]=n,s[i]=o,u[i]=0===a?-1:r[a-1]})});const i=[],a=[];for(const r of t.map((t,r)=>r).sort((t,r)=>s[t]-s[r]))(0===i.length||s[r]-i[i.length-1]>.001)&&i.push(s[r]),a[r]=i.length-1;const f=new Set(u.filter(t=>-1!==t).map(t=>a[t])),c=[],l=[],p=[];i.forEach((t,r)=>{c.push(t-(0===r?0:i[r-1])),n&&c.push("caption"),l[r]=c.length+1,f.has(r)&&c.push("gap"),p[r]=c.length+1});const h=t.map((t,r)=>({column:e[r]+1,start:-1===u[r]?1:p[a[u[r]]],end:l[a[r]]}));return{tracks:c,tiles:h}}
1
+ import{isSideways as t,quartersOf as n}from"./image.js";import{breakpoints as o,resolveAt as r}from"./responsive.js";export function ratioOf(t,n){if(void 0===t)return n;if("number"==typeof t)return t>0?t:n;const[o,r]=t.split("/"),e=void 0===r?Number(o):Number(o)/Number(r);return Number.isFinite(e)&&e>0?e:n}export function isTurned(o){return void 0!==o&&t(n(o))}export function shownRatio(t,n){return isTurned(n)?1/t:t}export function dealColumns(t,n){const o=Array.from({length:n},()=>[]),r=new Array(n).fill(0);return t.forEach((t,e)=>{let s=0;for(let t=1;t<n;t+=1)r[t]<r[s]&&(s=t);o[s].push(e),r[s]+=1/t}),o}export function masonryRows(t,n,o){const r=dealColumns(t,n),e=[],s=[],a=[];r.forEach((n,o)=>{let r=0;n.forEach((u,i)=>{r+=1/t[u],e[u]=o,s[u]=r,a[u]=0===i?-1:n[i-1]})});const u=[],i=[];for(const n of t.map((t,n)=>n).sort((t,n)=>s[t]-s[n]))(0===u.length||s[n]-u[u.length-1]>.001)&&u.push(s[n]),i[n]=u.length-1;const c=new Set(a.filter(t=>-1!==t).map(t=>i[t])),l=[],p=[],f=[];u.forEach((t,n)=>{l.push(t-(0===n?0:u[n-1])),o&&l.push("caption"),p[n]=l.length+1,c.has(n)&&l.push("gap"),f[n]=l.length+1});const m=t.map((t,n)=>({column:e[n]+1,start:-1===a[n]?1:f[i[a[n]]],end:p[i[n]]}));return{tracks:l,tiles:m}}export function laneCount(t){return Math.max(1,Math.round(t))}export function masonrySlots(t,n,e,s){const a={},u=t.map(()=>({})),i=[],c=[];let l,p;for(const f of o){const o=laneCount(r(n,f)??2);if(o===p)continue;p=o;const m=masonryRows(t,o,e),h=m.tracks.map(s).join(" ");h!==l&&(a[`--p-lane-rows-${f}`]=h,l=h),m.tiles.forEach(({column:t,start:n,end:o},r)=>{const e=`${n} / ${t} / ${o}`,s=String(o-n);e!==i[r]&&(u[r][`--p-lane-area-${f}`]=e,i[r]=e),s!==c[r]&&(u[r][`--p-lane-span-${f}`]=s,c[r]=s)})}return{list:a,tiles:u}}
@@ -11,8 +11,13 @@ import * as React from 'react';
11
11
  * `offsetX` and `offsetY` cost nothing, but they are measured from whatever the
12
12
  * pointer is over. On a surface whose own element is under the pointer — a
13
13
  * button, whose icons ignore the pointer — that is the surface, and they are
14
- * used as they are. On one that holds other elements the pointer can land on,
15
- * the position is read against the surface's own box instead.
14
+ * used as they are: every browser counts them in the surface's own pixels from
15
+ * inside its border, through any `transform` above it. On one that holds other
16
+ * elements the pointer can land on, the position is read against the surface's
17
+ * box on the screen instead, and turned into those same pixels from inside the
18
+ * border, which is where the two layers are laid out. The screen and the
19
+ * surface differ inside a scaled ancestor, a field in a scaled `PlMockup` for
20
+ * one. `offsetWidth` is read after the box, so it costs no second layout.
16
21
  */
17
22
  export declare function followPointer(event: React.PointerEvent<HTMLElement>): void;
18
23
  /**
@@ -1 +1 @@
1
- import*as t from"react";export function followPointer(t){const e=t.currentTarget;let o=t.nativeEvent.offsetX,n=t.nativeEvent.offsetY;if(t.target!==e){const r=e.getBoundingClientRect();o=t.clientX-r.left,n=t.clientY-r.top}e.style.setProperty("--p-mx",`${o}px`),e.style.setProperty("--p-my",`${n}px`)}export function glowPointerMove(t,e){return t?t=>{followPointer(t),e?.(t)}:e}const e=/* @__PURE__ */new Set(["Tab","Escape","Shift","Control","Alt","Meta","CapsLock"]);export function useFieldLight(o){const[n,r]=t.useState(!1),l=t.useRef(!1),i=t.useCallback(t=>{l.current!==t&&(l.current=t,r(t))},[]),a=t.useCallback(t=>{followPointer(t),i(!1)},[i]),s=t.useCallback(t=>{e.has(t.key)||i(!0)},[i]);return o?{"data-quiet":n?"":void 0,onPointerMove:a,onKeyDown:s}:{}}
1
+ import*as t from"react";export function followPointer(t){const e=t.currentTarget;let o=t.nativeEvent.offsetX,n=t.nativeEvent.offsetY;if(t.target!==e){const i=e.getBoundingClientRect(),r=i.width?e.offsetWidth/i.width:1,l=i.height?e.offsetHeight/i.height:1;o=(t.clientX-i.left)*r-e.clientLeft,n=(t.clientY-i.top)*l-e.clientTop}e.style.setProperty("--p-mx",`${o}px`),e.style.setProperty("--p-my",`${n}px`)}export function glowPointerMove(t,e){return t?t=>{followPointer(t),e?.(t)}:e}const e=/* @__PURE__ */new Set(["Tab","Escape","Shift","Control","Alt","Meta","CapsLock"]);export function useFieldLight(o){const[n,i]=t.useState(!1),r=t.useRef(!1),l=t.useCallback(t=>{r.current!==t&&(r.current=t,i(t))},[]),s=t.useCallback(t=>{followPointer(t),l(!1)},[l]),c=t.useCallback(t=>{e.has(t.key)||l(!0)},[l]);return o?{"data-quiet":n?"":void 0,onPointerMove:s,onKeyDown:c}:{}}
@@ -0,0 +1,11 @@
1
+ import type { PlassHeadingLevel } from '../types.js';
2
+ /**
3
+ * The heading level a caller asked for, or `undefined` when what arrived is
4
+ * not one.
5
+ *
6
+ * The type keeps a TypeScript caller inside the six; this keeps a JavaScript
7
+ * one there too, where a `7` would have written an `<h7>`, which is no heading
8
+ * at all. Every component that takes a `headingLevel` reads it through here,
9
+ * so they cannot come to disagree about what a level is.
10
+ */
11
+ export declare function headingLevelOf(value: unknown): PlassHeadingLevel | undefined;
@@ -0,0 +1 @@
1
+ export function headingLevelOf(e){return"number"==typeof e&&Number.isInteger(e)&&e>=1&&e<=6?e:void 0}
@@ -76,9 +76,11 @@ export declare function canonicalLanguage(language: string | undefined): string
76
76
  * Highlighting the block as a whole and splitting afterwards, never line by
77
77
  * line: a block comment, a template literal and a heredoc all span lines, and a
78
78
  * highlighter handed one line at a time sees the second line of a comment as
79
- * code.
79
+ * code. A block is coloured in its own turn, after the blocks that asked before
80
+ * it, with the browser given the main thread in between, and `signal` takes a
81
+ * block that has gone away by then out of the queue.
80
82
  */
81
- export declare function highlight(code: string, language: string): Promise<PlCodeLine[] | null>;
83
+ export declare function highlight(code: string, language: string, signal?: AbortSignal): Promise<PlCodeLine[] | null>;
82
84
  /**
83
85
  * highlight.js's own markup, as lines of coloured runs.
84
86
  *
@@ -1 +1 @@
1
- const i={bash:()=>import("highlight.js/lib/languages/bash"),c:()=>import("highlight.js/lib/languages/c"),cpp:()=>import("highlight.js/lib/languages/cpp"),csharp:()=>import("highlight.js/lib/languages/csharp"),css:()=>import("highlight.js/lib/languages/css"),dart:()=>import("highlight.js/lib/languages/dart"),diff:()=>import("highlight.js/lib/languages/diff"),dockerfile:()=>import("highlight.js/lib/languages/dockerfile"),go:()=>import("highlight.js/lib/languages/go"),graphql:()=>import("highlight.js/lib/languages/graphql"),ini:()=>import("highlight.js/lib/languages/ini"),java:()=>import("highlight.js/lib/languages/java"),javascript:()=>import("highlight.js/lib/languages/javascript"),json:()=>import("highlight.js/lib/languages/json"),kotlin:()=>import("highlight.js/lib/languages/kotlin"),less:()=>import("highlight.js/lib/languages/less"),lua:()=>import("highlight.js/lib/languages/lua"),makefile:()=>import("highlight.js/lib/languages/makefile"),markdown:()=>import("highlight.js/lib/languages/markdown"),objectivec:()=>import("highlight.js/lib/languages/objectivec"),perl:()=>import("highlight.js/lib/languages/perl"),php:()=>import("highlight.js/lib/languages/php"),plaintext:()=>import("highlight.js/lib/languages/plaintext"),powershell:()=>import("highlight.js/lib/languages/powershell"),python:()=>import("highlight.js/lib/languages/python"),r:()=>import("highlight.js/lib/languages/r"),ruby:()=>import("highlight.js/lib/languages/ruby"),rust:()=>import("highlight.js/lib/languages/rust"),scss:()=>import("highlight.js/lib/languages/scss"),shell:()=>import("highlight.js/lib/languages/shell"),sql:()=>import("highlight.js/lib/languages/sql"),swift:()=>import("highlight.js/lib/languages/swift"),typescript:()=>import("highlight.js/lib/languages/typescript"),xml:()=>import("highlight.js/lib/languages/xml"),yaml:()=>import("highlight.js/lib/languages/yaml")},t={"c++":"cpp",cc:"cpp",cjs:"javascript",console:"bash",cs:"csharp",cts:"typescript",docker:"dockerfile",gql:"graphql",golang:"go",h:"cpp",hpp:"cpp",htm:"xml",html:"xml",js:"javascript",jsx:"javascript",kt:"kotlin",kts:"kotlin",md:"markdown",mdx:"markdown",mjs:"javascript",mm:"objectivec",mts:"typescript",mysql:"sql",node:"javascript",none:"plaintext",objc:"objectivec",plain:"plaintext",posh:"powershell",ps1:"powershell",psql:"sql",py:"python",rb:"ruby",rs:"rust",sh:"bash",svelte:"xml",svg:"xml",text:"plaintext",toml:"ini",ts:"typescript",tsx:"typescript",txt:"plaintext",vue:"xml",yml:"yaml",zsh:"bash"},l=new Map;export function registerLanguage(i,t){const g=i.toLowerCase();l.set(g,t),s.delete(g)}let g=null;const s=new Map;export function canonicalLanguage(i){if(!i)return null;const g=i.trim().toLowerCase();return g?l.has(g)?g:t[g]??g:null}export async function highlight(t,a){let e=s.get(a);e||(e=async function prepare(t){const s=l.get(t),a=s?void 0:i[t];if(!s&&!a)return null;g??=import("highlight.js/lib/core").then(i=>i.default);const e=await g;return s?e.registerLanguage(t,s):e.getLanguage(t)||e.registerLanguage(t,(await a()).default),t}(a).catch(i=>{throw s.delete(a),i}),s.set(a,e));const h=await e;return h&&g?tokenize((await g).highlight(t,{language:h,ignoreIllegals:!0}).value):null}const a={"&amp;":"&","&lt;":"<","&gt;":">","&quot;":'"',"&#x27;":"'"};export function tokenize(i){const t=[[]],l=[],g=/<span class="([^"]*)">|<\/span>/g;let s=0;const push=i=>{if(!i)return;const g=l[l.length-1];i.replace(/&(?:amp|lt|gt|quot|#x27);/g,i=>a[i]).split("\n").forEach((i,l)=>{l>0&&t.push([]),i&&t[t.length-1].push(g?{text:i,token:g}:{text:i})})};for(const t of i.matchAll(g))push(i.slice(s,t.index)),s=t.index+t[0].length,void 0===t[1]?l.pop():l.push(t[1]);return push(i.slice(s)),t}export function plainLines(i){return i.split("\n").map(i=>i?[{text:i}]:[])}
1
+ const i={bash:()=>import("highlight.js/lib/languages/bash"),c:()=>import("highlight.js/lib/languages/c"),cpp:()=>import("highlight.js/lib/languages/cpp"),csharp:()=>import("highlight.js/lib/languages/csharp"),css:()=>import("highlight.js/lib/languages/css"),dart:()=>import("highlight.js/lib/languages/dart"),diff:()=>import("highlight.js/lib/languages/diff"),dockerfile:()=>import("highlight.js/lib/languages/dockerfile"),go:()=>import("highlight.js/lib/languages/go"),graphql:()=>import("highlight.js/lib/languages/graphql"),ini:()=>import("highlight.js/lib/languages/ini"),java:()=>import("highlight.js/lib/languages/java"),javascript:()=>import("highlight.js/lib/languages/javascript"),json:()=>import("highlight.js/lib/languages/json"),kotlin:()=>import("highlight.js/lib/languages/kotlin"),less:()=>import("highlight.js/lib/languages/less"),lua:()=>import("highlight.js/lib/languages/lua"),makefile:()=>import("highlight.js/lib/languages/makefile"),markdown:()=>import("highlight.js/lib/languages/markdown"),objectivec:()=>import("highlight.js/lib/languages/objectivec"),perl:()=>import("highlight.js/lib/languages/perl"),php:()=>import("highlight.js/lib/languages/php"),plaintext:()=>import("highlight.js/lib/languages/plaintext"),powershell:()=>import("highlight.js/lib/languages/powershell"),python:()=>import("highlight.js/lib/languages/python"),r:()=>import("highlight.js/lib/languages/r"),ruby:()=>import("highlight.js/lib/languages/ruby"),rust:()=>import("highlight.js/lib/languages/rust"),scss:()=>import("highlight.js/lib/languages/scss"),shell:()=>import("highlight.js/lib/languages/shell"),sql:()=>import("highlight.js/lib/languages/sql"),swift:()=>import("highlight.js/lib/languages/swift"),typescript:()=>import("highlight.js/lib/languages/typescript"),xml:()=>import("highlight.js/lib/languages/xml"),yaml:()=>import("highlight.js/lib/languages/yaml")},t={"c++":"cpp",cc:"cpp",cjs:"javascript",console:"bash",cs:"csharp",cts:"typescript",docker:"dockerfile",gql:"graphql",golang:"go",h:"cpp",hpp:"cpp",htm:"xml",html:"xml",js:"javascript",jsx:"javascript",kt:"kotlin",kts:"kotlin",md:"markdown",mdx:"markdown",mjs:"javascript",mm:"objectivec",mts:"typescript",mysql:"sql",node:"javascript",none:"plaintext",objc:"objectivec",plain:"plaintext",posh:"powershell",ps1:"powershell",psql:"sql",py:"python",rb:"ruby",rs:"rust",sh:"bash",svelte:"xml",svg:"xml",text:"plaintext",toml:"ini",ts:"typescript",tsx:"typescript",txt:"plaintext",vue:"xml",yml:"yaml",zsh:"bash"},l=new Map;export function registerLanguage(i,t){const s=i.toLowerCase();l.set(s,t),e.delete(s)}let s=null;const e=new Map;export function canonicalLanguage(i){if(!i)return null;const s=i.trim().toLowerCase();return s?l.has(s)?s:t[s]??s:null}function yieldToBrowser(){const{scheduler:i}=globalThis;return"function"==typeof i?.yield?i.yield():new Promise(i=>{const t=new MessageChannel;t.port1.onmessage=()=>{t.port1.close(),i()},t.port2.postMessage(null)})}let g=Promise.resolve();export async function highlight(t,a,h){let n=e.get(a);n||(n=async function prepare(t){const e=l.get(t),g=e?void 0:i[t];if(!e&&!g)return null;if(!s){const i=import("highlight.js/lib/core").then(i=>i.default);i.catch(()=>{s===i&&(s=null)}),s=i}const[a,h]=await Promise.all([s,e??g().then(i=>i.default)]);return!e&&a.getLanguage(t)||a.registerLanguage(t,h),t}(a).catch(i=>{throw e.delete(a),i}),e.set(a,n));const o=await n;if(!o||!s)return null;const r=await s;return await function nextTurn(){return g=g.then(yieldToBrowser),g}(),h?.aborted?null:tokenize(r.highlight(t,{language:o,ignoreIllegals:!0}).value)}const a={"&amp;":"&","&lt;":"<","&gt;":">","&quot;":'"',"&#x27;":"'"};export function tokenize(i){const t=[[]],l=[],s=/<span class="([^"]*)">|<\/span>/g;let e=0;const push=i=>{if(!i)return;const s=l[l.length-1];i.replace(/&(?:amp|lt|gt|quot|#x27);/g,i=>a[i]).split("\n").forEach((i,l)=>{l>0&&t.push([]),i&&t[t.length-1].push(s?{text:i,token:s}:{text:i})})};for(const t of i.matchAll(s))push(i.slice(e,t.index)),e=t.index+t[0].length,void 0===t[1]?l.pop():l.push(t[1]);return push(i.slice(e)),t}export function plainLines(i){return i.split("\n").map(i=>i?[{text:i}]:[])}
@@ -72,6 +72,11 @@ export interface PlassLabels {
72
72
  chartMore: (count: number) => string;
73
73
  /** And the way back, once they are all showing. */
74
74
  chartFewer: string;
75
+ /**
76
+ * The head of the column a chart's table names each mark in, for marks that
77
+ * carry a name of their own: a timeline's spans.
78
+ */
79
+ name: string;
75
80
  minimize: string;
76
81
  maximize: string;
77
82
  restore: string;
@@ -1 +1 @@
1
- "use client";import*as e from"react";import{useDefaults as a}from"./defaults.js";import{loadingLabel as o}from"./loading.js";export const defaultLabels={close:"Close",cancel:"Cancel",confirm:"Confirm",acknowledge:"OK",clear:"Clear",done:"Done",skip:"Skip",search:"Search",selectAll:"Select all",selectRow:"Select row",remove:"Remove",dismiss:"Dismiss",open:"Open",previous:"Previous",next:"Next",reveal:"Reveal",hide:"Hide",increase:"Increase",decrease:"Decrease",preview:"Preview",empty:"Nothing here",optional:"Optional",loading:o,breadcrumb:"Breadcrumb",breadcrumbExpand:"Show the hidden steps",carousel:"Carousel",carouselPrevious:"Previous slide",carouselNext:"Next slide",carouselPlay:"Start slide show",carouselStop:"Stop slide show",slide:"slide",commandPalette:"Command palette",commandPalettePlaceholder:"Search commands",gallery:"Gallery",chart:"Chart",chartOther:"Other",chartMore:e=>`${e} more`,chartFewer:"Show fewer",minimize:"Minimize",maximize:"Maximize",restore:"Restore",resizeWindow:"Resize window",moveWindow:"Move window",overlay:"Overlay",notifications:"Notifications",pagination:"Pagination",paginationPrevious:"Previous page",paginationNext:"Next page",paginationFirst:"First page",paginationLast:"Last page",rating:"Rating",sidebar:"Sidebar",sidebarOpen:"Open sidebar",sidebarClose:"Close sidebar",sidebarResize:"Resize sidebar",skipToContent:"Skip to content",backToTop:"Back to top",onThisPage:"On this page",typing:"Typing…",messageSending:"Sending",messageSent:"Sent",messageDelivered:"Delivered",messageRead:"Read",messageFailed:"Not delivered",spoilerWarning:"This may contain spoilers",filePickerTitle:"Drop files here, or click to browse",newTab:"(opens in a new tab)",transferAvailable:"Available",transferSelected:"Selected",transferToSelected:"Move to selected",transferToAvailable:"Move to available",copy:"Copy",copied:"Copied",copyFailed:"Could not copy",raw:"Raw",code:"Code",previousMonth:"Previous month",nextMonth:"Next month",previousYear:"Previous year",nextYear:"Next year",previousYears:"Previous years",nextYears:"Next years",chooseMonth:"Choose a month",chooseYear:"Choose a year",today:"Today",thisMonth:"This month",thisYear:"This year",now:"Now",hour:"Hour",minute:"Minute",second:"Second",meridiem:"AM/PM",start:"Start",end:"End",paginationPage:e=>`Page ${e}`,paginationStatus:(e,a)=>`Page ${e} of ${a}`,ratingValue:(e,a)=>`${e.toLocaleString("en")} out of ${a}`,ratingNone:"No rating",carouselSlide:(e,a)=>`Slide ${e} of ${a}`,galleryItem:(e,a)=>`${e} of ${a}`,removeItem:e=>`Remove ${e}`,addCustom:e=>`Add “${e}”`,otpSlot:(e,a)=>`Character ${e} of ${a}`,transferSelectAll:e=>`Select all in ${e}`,transferMoved:(e,a)=>`${e} ${1===e?"item":"items"} moved to ${a}`,filesRejectedType:e=>`${e} ${1===e?"file is":"files are"} not an accepted type`,filesRejectedSize:e=>`${e} ${1===e?"file is":"files are"} too large`,filesRejectedCount:e=>`${e} ${1===e?"file":"files"} did not fit`};export function useLabels(){const{labels:o}=a();return e.useMemo(()=>o?{...defaultLabels,...o}:defaultLabels,[o])}
1
+ "use client";import*as e from"react";import{useDefaults as a}from"./defaults.js";import{loadingLabel as o}from"./loading.js";export const defaultLabels={close:"Close",cancel:"Cancel",confirm:"Confirm",acknowledge:"OK",clear:"Clear",done:"Done",skip:"Skip",search:"Search",selectAll:"Select all",selectRow:"Select row",remove:"Remove",dismiss:"Dismiss",open:"Open",previous:"Previous",next:"Next",reveal:"Reveal",hide:"Hide",increase:"Increase",decrease:"Decrease",preview:"Preview",empty:"Nothing here",optional:"Optional",loading:o,breadcrumb:"Breadcrumb",breadcrumbExpand:"Show the hidden steps",carousel:"Carousel",carouselPrevious:"Previous slide",carouselNext:"Next slide",carouselPlay:"Start slide show",carouselStop:"Stop slide show",slide:"slide",commandPalette:"Command palette",commandPalettePlaceholder:"Search commands",gallery:"Gallery",chart:"Chart",chartOther:"Other",chartMore:e=>`${e} more`,chartFewer:"Show fewer",name:"Name",minimize:"Minimize",maximize:"Maximize",restore:"Restore",resizeWindow:"Resize window",moveWindow:"Move window",overlay:"Overlay",notifications:"Notifications",pagination:"Pagination",paginationPrevious:"Previous page",paginationNext:"Next page",paginationFirst:"First page",paginationLast:"Last page",rating:"Rating",sidebar:"Sidebar",sidebarOpen:"Open sidebar",sidebarClose:"Close sidebar",sidebarResize:"Resize sidebar",skipToContent:"Skip to content",backToTop:"Back to top",onThisPage:"On this page",typing:"Typing…",messageSending:"Sending",messageSent:"Sent",messageDelivered:"Delivered",messageRead:"Read",messageFailed:"Not delivered",spoilerWarning:"This may contain spoilers",filePickerTitle:"Drop files here, or click to browse",newTab:"(opens in a new tab)",transferAvailable:"Available",transferSelected:"Selected",transferToSelected:"Move to selected",transferToAvailable:"Move to available",copy:"Copy",copied:"Copied",copyFailed:"Could not copy",raw:"Raw",code:"Code",previousMonth:"Previous month",nextMonth:"Next month",previousYear:"Previous year",nextYear:"Next year",previousYears:"Previous years",nextYears:"Next years",chooseMonth:"Choose a month",chooseYear:"Choose a year",today:"Today",thisMonth:"This month",thisYear:"This year",now:"Now",hour:"Hour",minute:"Minute",second:"Second",meridiem:"AM/PM",start:"Start",end:"End",paginationPage:e=>`Page ${e}`,paginationStatus:(e,a)=>`Page ${e} of ${a}`,ratingValue:(e,a)=>`${e.toLocaleString("en")} out of ${a}`,ratingNone:"No rating",carouselSlide:(e,a)=>`Slide ${e} of ${a}`,galleryItem:(e,a)=>`${e} of ${a}`,removeItem:e=>`Remove ${e}`,addCustom:e=>`Add “${e}”`,otpSlot:(e,a)=>`Character ${e} of ${a}`,transferSelectAll:e=>`Select all in ${e}`,transferMoved:(e,a)=>`${e} ${1===e?"item":"items"} moved to ${a}`,filesRejectedType:e=>`${e} ${1===e?"file is":"files are"} not an accepted type`,filesRejectedSize:e=>`${e} ${1===e?"file is":"files are"} too large`,filesRejectedCount:e=>`${e} ${1===e?"file":"files"} did not fit`};export function useLabels(){const{labels:o}=a();return e.useMemo(()=>o?{...defaultLabels,...o}:defaultLabels,[o])}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * An element's length along one axis as it is laid out, which is not always
3
+ * the length it is drawn at.
4
+ *
5
+ * The two differ under a `transform` on an ancestor, a component inside a
6
+ * scaled `PlMockup` for one. `getBoundingClientRect` measures the box on the
7
+ * screen, which is the drawn size there, while a `width`, a `flex-basis`
8
+ * percentage and a `scrollLeft` are all counted in the element's own pixels.
9
+ * So the laid-out size is read off the computed style, which a transform does
10
+ * not reach, and the box on the screen is kept for what is measured on the
11
+ * screen: a pointer's movement, and the distance between two boxes.
12
+ */
13
+ export interface LayoutBox {
14
+ /**
15
+ * The used `width` or `height`, which is the border box or the content box
16
+ * as `box-sizing` says: the length a declaration of either sets.
17
+ */
18
+ size: number;
19
+ /**
20
+ * The content box, inside the padding and the border: what a child's
21
+ * percentage is a percentage of.
22
+ */
23
+ content: number;
24
+ /**
25
+ * How many of the element's own pixels one pixel on the screen is. `1`
26
+ * unless an ancestor scales it.
27
+ */
28
+ perPixel: number;
29
+ }
30
+ /**
31
+ * Measures `element` across when `horizontal` and down otherwise. An element
32
+ * that is not laid out, inside a closed `PlAccordion` for example, measures
33
+ * nothing.
34
+ */
35
+ export declare function layoutBox(element: HTMLElement, horizontal: boolean): LayoutBox;
@@ -0,0 +1 @@
1
+ export function layoutBox(t,e){const n=t.getBoundingClientRect(),d=e?n.width:n.height;if(!(d>0))return{size:0,content:0,perPixel:1};const i=getComputedStyle(t),r=(e?[i.paddingInlineStart,i.paddingInlineEnd,i.borderInlineStartWidth,i.borderInlineEndWidth]:[i.paddingBlockStart,i.paddingBlockEnd,i.borderBlockStartWidth,i.borderBlockEndWidth]).reduce((t,e)=>t+(parseFloat(e)||0),0),o=parseFloat(e?i.width:i.height)||0,l="border-box"===i.boxSizing?o:o+r;return{size:o,content:l-r,perPixel:l>0?l/d:1}}
@@ -0,0 +1,37 @@
1
+ import * as React from 'react';
2
+ /**
3
+ * A part of a component that is a download of its own, and that steps back
4
+ * rather than throwing when the download fails.
5
+ *
6
+ * Four components keep a piece most pages never show behind an `import()`:
7
+ * `PlConfirmProvider` its dialog, `PlSidebar` the drawer it becomes on a narrow
8
+ * window, `PlImage` its preview and `PlGallery` its viewer. `React.lazy` on its
9
+ * own throws to the nearest error boundary when that chunk cannot be fetched —
10
+ * a connection that dropped, or a deploy that replaced the chunk under a page
11
+ * that was already open — and the boundary takes down everything it holds over
12
+ * a part the reader may only have pointed at.
13
+ *
14
+ * So the import is tried a second time, and if that fails as well the part
15
+ * renders nothing and says so once through `onUnavailable`, which is where the
16
+ * component that asked for it steps back: closes what it was opening, answers
17
+ * what it was asking. A failed attempt is forgotten, so the next mount tries
18
+ * again. Chromium keeps a module whose fetch failed for the life of the page,
19
+ * so there a second try, now or later, fails at once without a request; Firefox
20
+ * and WebKit fetch it again.
21
+ */
22
+ /** A part's own props, and the one it adds. */
23
+ export type LazyPartProps<P> = P & {
24
+ /** Called once, after the second try has failed. The part then renders nothing. */
25
+ onUnavailable?: () => void;
26
+ };
27
+ export interface LazyPart<P> {
28
+ (props: LazyPartProps<P>): React.ReactElement;
29
+ /** Starts the download without rendering anything. A failure is kept quiet. */
30
+ preload: () => void;
31
+ }
32
+ /**
33
+ * `React.lazy` with one retry and a quiet failure. Render the result inside a
34
+ * `Suspense` as a lazy component would be, and unmount it when it reports
35
+ * `onUnavailable`, so that the next mount is the next attempt.
36
+ */
37
+ export declare function lazyPart<P extends object>(load: () => Promise<React.ComponentType<P>>): LazyPart<P>;
@@ -0,0 +1 @@
1
+ "use client";import{jsx as n}from"react/jsx-runtime";import*as t from"react";function Unavailable({onUnavailable:n}){const a=t.useRef(!1);return t.useLayoutEffect(()=>{a.current||(a.current=!0,n?.())}),null}export function lazyPart(a){let e=null;const download=()=>(e??=a().catch(()=>a()).catch(()=>(e=null,null)),e),attempt=()=>{const a=t.lazy(async()=>{const t=await download();if(!t){const retire=()=>{r===a&&(r=attempt())};function Failed({onUnavailable:t}){return n(Unavailable,{onUnavailable:()=>{retire(),t?.()}})}return{default:Failed}}const e=t;return{default:function Ready({onUnavailable:t,...a}){return n(e,{...a})}}});return a};let r=attempt();function Part(a){const[e]=t.useState(()=>r);return n(e,{...a})}return Part.preload=()=>{download()},Part}
@@ -24,3 +24,9 @@ export declare function useMediaQuery(query: string | null): boolean;
24
24
  * — before any of these animations has had a frame to run in.
25
25
  */
26
26
  export declare function usePrefersReducedMotion(): boolean;
27
+ /**
28
+ * The same answer, read at the moment it is asked rather than on the render
29
+ * after it changes: for an event handler that has to act before the next frame
30
+ * is drawn.
31
+ */
32
+ export declare function prefersReducedMotion(): boolean;
@@ -1 +1 @@
1
- "use client";import*as e from"react";const n=new Map;function listFor(e){if("undefined"==typeof window||!window.matchMedia)return null;let r=n.get(e);return r||(r=window.matchMedia(e),n.set(e,r)),r}function onServer(){return!1}export const reducedMotionQuery="(prefers-reduced-motion: reduce)";export function useMediaQuery(n){const r=e.useCallback(e=>{const r=null===n?null:listFor(n);return r?(r.addEventListener("change",e),()=>r.removeEventListener("change",e)):()=>{}},[n]),t=e.useCallback(()=>null!==n&&(listFor(n)?.matches??!1),[n]);return e.useSyncExternalStore(r,t,onServer)}export function usePrefersReducedMotion(){return useMediaQuery(reducedMotionQuery)}
1
+ "use client";import*as e from"react";const r=new Map;function listFor(e){if("undefined"==typeof window||!window.matchMedia)return null;let n=r.get(e);return n||(n=window.matchMedia(e),r.set(e,n)),n}function onServer(){return!1}export const reducedMotionQuery="(prefers-reduced-motion: reduce)";export function useMediaQuery(r){const n=e.useCallback(e=>{const n=null===r?null:listFor(r);return n?(n.addEventListener("change",e),()=>n.removeEventListener("change",e)):()=>{}},[r]),t=e.useCallback(()=>null!==r&&(listFor(r)?.matches??!1),[r]);return e.useSyncExternalStore(n,t,onServer)}export function usePrefersReducedMotion(){return useMediaQuery(reducedMotionQuery)}export function prefersReducedMotion(){return listFor(reducedMotionQuery)?.matches??!1}
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import type { PlassDirection } from './direction.js';
3
- import type { PlassBreakpoint, PlassSide } from '../types.js';
3
+ import type { PlassBreakpoint, PlassPosition, PlassSide } from '../types.js';
4
4
  /**
5
5
  * The vocabulary a page's structure is written in, and the context the four
6
6
  * components that build one share.
@@ -75,6 +75,12 @@ export interface PlPageLayoutContextValue {
75
75
  * reliably as one that is not.
76
76
  */
77
77
  register: (slot: PlPageLayoutSlot, node: HTMLElement | null) => void;
78
+ /**
79
+ * Measures the registered bars again, for the one change to a bar that
80
+ * neither its ref nor the layout's `ResizeObserver` reports: its `position`,
81
+ * which decides what its height is reserved for. See `useSlotPosition`.
82
+ */
83
+ remeasure: () => void;
78
84
  /** Where the sidebars stop being columns. */
79
85
  collapseBelow: PlPageLayoutCollapse;
80
86
  /** Whether each sidebar's drawer is open. Only meaningful while it is collapsed. */
@@ -84,6 +90,16 @@ export interface PlPageLayoutContextValue {
84
90
  scroll: PlPageLayoutScroll;
85
91
  }
86
92
  export declare const PlPageLayoutContext: React.Context<PlPageLayoutContextValue>;
93
+ /**
94
+ * Tells the layout around a bar that the bar's `position` changed.
95
+ *
96
+ * A bar that turns from `static` to `fixed` keeps its element, so its ref is
97
+ * not handed over again, and usually its size, so the layout's observer has
98
+ * nothing to report either — and the layout went on reserving nothing for a
99
+ * bar that had left the flow, until something else happened to resize it. Not
100
+ * on the first commit, which the layout measures on its own.
101
+ */
102
+ export declare function useSlotPosition(position: PlassPosition): void;
87
103
  /**
88
104
  * Which end of the band the sidebar being rendered right now takes.
89
105
  *
@@ -132,16 +148,11 @@ export declare function useCollapsed(breakpoint: PlPageLayoutCollapse): boolean;
132
148
  * a tooltip above a button is above it in every writing direction — so the two
133
149
  * have to be translated.
134
150
  *
135
- * `direction` is what the nearest `PlassProvider` was told, and it wins for the
136
- * reason it wins there: a provider given a direction is describing a subtree
137
- * that runs the other way from the page, and a drawer is portalled out of that
138
- * subtree, so the document is the one place that cannot say which way it runs.
139
- * Without one, the document's own direction is the answer, as it is for the
140
- * provider.
141
- *
142
- * The document is read during render rather than in an effect, which is safe
143
- * here for a narrower reason than it looks: the only caller is a sidebar that
144
- * has already collapsed, and collapsing is a client-side answer. There is no
145
- * server render of this to disagree with.
151
+ * `direction` is the caller's to resolve: what the nearest `PlassProvider` was
152
+ * told, which wins for the reason it wins there — a provider given a direction
153
+ * is describing a subtree that runs the other way from the page, and a drawer
154
+ * is portalled out of that subtree, so the document is the one place that
155
+ * cannot say which way it runs — and without one, the document's own
156
+ * direction, as it is for the provider.
146
157
  */
147
- export declare function drawerSide(side: PlassSidebarSide, direction?: PlassDirection): PlassSide;
158
+ export declare function drawerSide(side: PlassSidebarSide, direction: PlassDirection): PlassSide;
@@ -1 +1 @@
1
- "use client";import*as e from"react";import{belowQuery as t}from"./breakpoints.js";import{useMediaQuery as n}from"./media.js";export const PlPageLayoutContext=/* @__PURE__ */e.createContext({present:!1,register:()=>{},collapseBelow:"none",open:{start:!1,end:!1},setOpen:()=>{},scroll:"page"});export const PlassSidebarSideContext=/* @__PURE__ */e.createContext(null);export const collapsedOnlyClasses={none:"hidden",xs:"hidden",sm:"sm:hidden",md:"md:hidden",lg:"lg:hidden",xl:"xl:hidden"};export const expandedOnlyClasses={none:"",xs:"",sm:"max-sm:hidden",md:"max-md:hidden",lg:"max-lg:hidden",xl:"max-xl:hidden"};export function useCollapsed(e){return n("none"===e?null:function collapseQuery(e){return"xs"===e?null:t(e)}(e))}export function drawerSide(e,t){const n=t?"rtl"===t:"undefined"!=typeof document&&"rtl"===getComputedStyle(document.documentElement).direction;return"start"===e?n?"right":"left":n?"left":"right"}
1
+ "use client";import*as e from"react";import{belowQuery as t}from"./breakpoints.js";import{useMediaQuery as n}from"./media.js";export const PlPageLayoutContext=/* @__PURE__ */e.createContext({present:!1,register:()=>{},remeasure:()=>{},collapseBelow:"none",open:{start:!1,end:!1},setOpen:()=>{},scroll:"page"});export function useSlotPosition(t){const{remeasure:n}=e.useContext(PlPageLayoutContext),o=e.useRef(t);e.useLayoutEffect(()=>{o.current!==t&&(o.current=t,n())},[t,n])}export const PlassSidebarSideContext=/* @__PURE__ */e.createContext(null);export const collapsedOnlyClasses={none:"hidden",xs:"hidden",sm:"sm:hidden",md:"md:hidden",lg:"lg:hidden",xl:"xl:hidden"};export const expandedOnlyClasses={none:"",xs:"",sm:"max-sm:hidden",md:"max-md:hidden",lg:"max-lg:hidden",xl:"max-xl:hidden"};export function useCollapsed(e){return n("none"===e?null:function collapseQuery(e){return"xs"===e?null:t(e)}(e))}export function drawerSide(e,t){const n="rtl"===t;return"start"===e?n?"right":"left":n?"left":"right"}
@@ -153,7 +153,7 @@ interface InternalShellProps extends PlassPickerShellProps {
153
153
  * and the way `invalid` re-points the whole colour family at `danger` so the
154
154
  * edge, the ring and the message turn over together.
155
155
  */
156
- export declare function PickerShell({ variant, size, color, density, elevation, label, labelPlacement: labelPlacementProp, description, error, invalid, startIcon, fullWidth, disabled: disabledProp, readOnly, required, id, className, classNames, style, display, samples, empty, clearable, onClear, open, onOpenChange, labels, name, formValue, children, triggerRef, ...props }: InternalShellProps): React.JSX.Element;
156
+ export declare function PickerShell({ variant, size, color, density, elevation, label, labelPlacement: labelPlacementProp, description, error, invalid, startIcon, fullWidth, disabled: disabledProp, readOnly, required, id, className, classNames, style, display, samples, empty, clearable, onClear, open, onOpenChange, labels, name, formValue, children, triggerRef, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, ...props }: InternalShellProps): React.JSX.Element;
157
157
  /**
158
158
  * The row of shortcuts under a picker's panel.
159
159
  *
@@ -1 +1 @@
1
- import{jsx as e,jsxs as t}from"react/jsx-runtime";import*as l from"react";import{Field as s}from"@base-ui/react/field";import{Popover as a}from"@base-ui/react/popover";import{FormControl as r,leaveFormControl as i,useDisabled as o,useFieldsetDisabled as n}from"./form.js";import{glowPointerMove as d}from"./glow.js";import{CloseIcon as p}from"./icons.js";import{WidthSizer as c}from"./sizer.js";import{textOf as m}from"./text.js";import{FieldNotch as u,floatPlaceholderClassName as f,notchShellStyle as h,resolveNotch as g}from"./notch.js";import{useDefaults as x}from"./defaults.js";import{chipRemoveClasses as b,controlHeightClasses as v,controlTextLeadingClasses as y,cx as N,disabledClasses as w,fieldDescriptionClasses as j,fieldReadOnlyClasses as P,fieldRestClasses as k,fieldSlots as $,focusWithinRingClasses as z,gapClasses as C,glassClasses as B,hasContent as D,iconClasses as E,metaTextClasses as I,paddingXClasses as O,radiusClasses as R,stackGapClasses as S,surfaceSlots as q,transitionClasses as F}from"./styles.js";export function popupSlots(e,t){return{...q(e,t),"--p-fill":`var(--plass-${e}-fill)`,"--p-on-solid":`var(--plass-${e}-on-solid)`}}const M=/* @__PURE__ */["relative flex w-full items-center select-none","[-webkit-tap-highlight-color:transparent] [touch-action:manipulation]",F,E].join(" "),L=z;export const pickerPopupClasses=/* @__PURE__ */[B,"border text-(--plass-fg) bg-(--plass-glass-press)","[border-color:var(--plass-glass-line)]","[box-shadow:var(--plass-shadow-3),var(--plass-gloss-glass)]","[outline:none]","[transition:opacity_var(--plass-duration)_var(--plass-ease)]","motion-reduce:[transition-duration:0ms]","data-[starting-style]:opacity-0 data-[ending-style]:opacity-0"].join(" ");export const popupPaddingClasses={xs:"p-1.5",sm:"p-2",md:"p-2.5",lg:"p-3",xl:"p-3.5"};const T=/* @__PURE__ */["data-[side=top]:bottom-[-1px]","data-[side=bottom]:top-[-1px] data-[side=bottom]:rotate-180","data-[side=left]:right-[-1px] data-[side=left]:-rotate-90","data-[side=right]:left-[-1px] data-[side=right]:rotate-90"].join(" ");export function PopupArrow({as:l,size:s}){return e(l,{className:T,children:t("svg",{width:s,height:s/2,viewBox:"0 0 10 5","aria-hidden":"true",className:"block",children:[e("path",{d:"M0 0h10L5 5z",fill:"var(--plass-glass-press)"}),e("path",{d:"M0 0 5 5 10 0",fill:"none",stroke:"var(--plass-glass-line)",strokeWidth:"1",vectorEffect:"non-scaling-stroke"})]})})}export function PickerShell({variant:z="glass",size:B="md",color:E="primary",density:q="default",elevation:F=0,label:T,labelPlacement:V,description:W,error:_,invalid:A,startIcon:G,fullWidth:H=!1,disabled:J=!1,readOnly:K=!1,required:Q=!1,id:U,className:X,classNames:Y,style:Z,display:ee,samples:te,empty:le,clearable:se=!1,onClear:ae,open:re,onOpenChange:ie,labels:oe,name:ne,formValue:de,children:pe,triggerRef:ce,...me}){const ue=l.useId(),fe=U??`${ue}-trigger`,he=`${ue}-label`,ge=`${ue}-value`,xe=`${ue}-description`,be=`${ue}-error`,ve=x(),ye=V??ve.labelPlacement??"top",{notched:Ne,float:we}=g(ye,T,D(G)),je=null!=_&&!1!==_&&""!==_,Pe=A??je,ke=Pe?"danger":E,[$e,ze]=l.useState(null),Ce=n($e),Be=o(J)||Ce,De=!Be&&!K,Ee=Be||K,Ie=l.useRef(null),Oe=e(s.Label,{id:he,htmlFor:fe,className:N(I[B],"font-semibold",Be?"text-(--plass-muted-fg)":"text-(--plass-fg)",Y?.label),children:T});return t(s.Root,{ref:ze,disabled:Be,invalid:Pe,className:N("flex-col align-top",S[B],H?"flex w-full":"inline-flex",X),style:{...$(ke,F),...Z},...me,children:[D(T)&&!Ne?Oe:null,t(a.Root,{open:re,onOpenChange:e=>ie(e),children:[e(u,{notched:Ne,size:B,density:q,variant:z,disabled:Be,readOnly:K,float:we,empty:le,label:Oe,children:t("span",{style:Ne?h:void 0,onPointerMove:d(De),className:N(M,Ne?"":L,v[B],y[B],R[B],C[B],O[q][B],Be?w[z]:K?P[z]:k[z],De?"plass-glow":"",Y?.control),children:[e(s.Validity,{children:({validity:l})=>{const s=!1===l.valid,r=[W?xe:null,je||s&&!Be&&!0!==A?be:null].filter(Boolean).join(" ")||void 0;return t(a.Trigger,{id:fe,ref:ce,disabled:Be,"aria-labelledby":T?`${he} ${ge}`:void 0,"aria-describedby":r,"aria-required":Q||void 0,"aria-invalid":Pe||s||void 0,onBlur:()=>{re||i(Ie.current)},className:N("flex min-w-0 flex-1 items-center bg-transparent text-start [font:inherit] text-inherit",C[B],"[outline:none]",Ee?"cursor-default":"cursor-pointer"),children:[G?e("span",{className:"flex h-[1lh] shrink-0 items-center text-(--plass-muted-fg)",children:G}):null,t("span",{className:"flex min-w-0 flex-1 flex-col",children:[e("span",{id:ge,className:N("w-full truncate",le?"text-(--plass-muted-fg)":"text-(--plass-fg)",we&&f),children:ee}),H?null:e(c,{samples:we?[...te??[],m(T)].filter(Boolean):te??[]})]})]})}}),!se||le||Ee?null:e("button",{type:"button","aria-label":oe.clear,className:N(b,"text-(--plass-muted-fg)"),onClick:e=>{e.stopPropagation();const t=e.currentTarget,l=t.ownerDocument.activeElement===t;ae(),l&&t.ownerDocument.getElementById(fe)?.focus()},children:e(p,{})})]})}),e(a.Portal,{children:e(a.Positioner,{className:"plass-portal z-(--plass-z-portal) [outline:none]",sideOffset:6,align:"start",children:e(a.Popup,{initialFocus:!1,className:N(pickerPopupClasses,R[B],popupPaddingClasses[B],y[B]),style:popupSlots(ke,3),children:pe})})})]}),W?e(s.Description,{id:xe,className:N(j(B),Y?.description),children:W}):null,e(s.Error,je?{id:be,match:!0,className:N(I[B],"text-(--p-accent)",Y?.error),children:_}:{id:be,className:N(I[B],"text-(--p-accent)",Y?.error)}),e(r,{ref:Ie,name:ne,value:de,required:Q&&!K,disabled:Be,standIn:()=>Ie.current?.ownerDocument.getElementById(fe)})]})}export function PickerFooter({size:t,children:l}){return e("div",{className:N("flex items-center justify-end border-t pt-1.5","[border-color:var(--plass-divider)]",C[t]),children:l})}export function PickerDivider(){return e("div",{"aria-hidden":"true",className:"w-px self-stretch bg-(--plass-divider)"})}
1
+ import{jsx as e,jsxs as t}from"react/jsx-runtime";import*as l from"react";import{Field as a}from"@base-ui/react/field";import{Popover as s}from"@base-ui/react/popover";import{FormControl as r,leaveFormControl as i,useDisabled as o,useFieldsetDisabled as n}from"./form.js";import{glowPointerMove as d}from"./glow.js";import{CloseIcon as p}from"./icons.js";import{WidthSizer as c}from"./sizer.js";import{textOf as m}from"./text.js";import{FieldNotch as u,floatPlaceholderClassName as f,notchShellStyle as h,resolveNotch as g}from"./notch.js";import{useDefaults as x}from"./defaults.js";import{chipRemoveClasses as b,controlHeightClasses as v,controlTextLeadingClasses as y,cx as N,disabledClasses as w,fieldDescriptionClasses as j,fieldReadOnlyClasses as P,fieldRestClasses as k,fieldSlots as $,focusWithinRingClasses as z,gapClasses as C,glassClasses as B,hasContent as D,iconClasses as E,metaTextClasses as I,paddingXClasses as O,radiusClasses as R,stackGapClasses as S,surfaceSlots as q,transitionClasses as F}from"./styles.js";export function popupSlots(e,t){return{...q(e,t),"--p-fill":`var(--plass-${e}-fill)`,"--p-on-solid":`var(--plass-${e}-on-solid)`}}const M=/* @__PURE__ */["relative flex w-full items-center select-none","[-webkit-tap-highlight-color:transparent] [touch-action:manipulation]",F,E].join(" "),L=z;export const pickerPopupClasses=/* @__PURE__ */[B,"border text-(--plass-fg) bg-(--plass-glass-press)","[border-color:var(--plass-glass-line)]","[box-shadow:var(--plass-shadow-3),var(--plass-gloss-glass)]","[outline:none]","[transition:opacity_var(--plass-duration)_var(--plass-ease)]","motion-reduce:[transition-duration:0ms]","data-[starting-style]:opacity-0 data-[ending-style]:opacity-0"].join(" ");export const popupPaddingClasses={xs:"p-1.5",sm:"p-2",md:"p-2.5",lg:"p-3",xl:"p-3.5"};const T=/* @__PURE__ */["data-[side=top]:bottom-[-1px]","data-[side=bottom]:top-[-1px] data-[side=bottom]:rotate-180","data-[side=left]:right-[-1px] data-[side=left]:-rotate-90","data-[side=right]:left-[-1px] data-[side=right]:rotate-90"].join(" ");export function PopupArrow({as:l,size:a}){return e(l,{className:T,children:t("svg",{width:a,height:a/2,viewBox:"0 0 10 5","aria-hidden":"true",className:"block",children:[e("path",{d:"M0 0h10L5 5z",fill:"var(--plass-glass-press)"}),e("path",{d:"M0 0 5 5 10 0",fill:"none",stroke:"var(--plass-glass-line)",strokeWidth:"1",vectorEffect:"non-scaling-stroke"})]})})}export function PickerShell({variant:z="glass",size:B="md",color:E="primary",density:q="default",elevation:F=0,label:T,labelPlacement:V,description:W,error:_,invalid:A,startIcon:G,fullWidth:H=!1,disabled:J=!1,readOnly:K=!1,required:Q=!1,id:U,className:X,classNames:Y,style:Z,display:ee,samples:te,empty:le,clearable:ae=!1,onClear:se,open:re,onOpenChange:ie,labels:oe,name:ne,formValue:de,children:pe,triggerRef:ce,"aria-label":me,"aria-labelledby":ue,...fe}){const he=l.useId(),ge=U??`${he}-trigger`,xe=`${he}-label`,be=`${he}-value`,ve=`${he}-description`,ye=`${he}-error`,Ne=ue??(me?ge:T?xe:void 0),we=x(),je=V??we.labelPlacement??"top",{notched:Pe,float:ke}=g(je,T,D(G)),$e=null!=_&&!1!==_&&""!==_,ze=A??$e,Ce=ze?"danger":E,[Be,De]=l.useState(null),Ee=n(Be),Ie=o(J)||Ee,Oe=!Ie&&!K,Re=Ie||K,Se=l.useRef(null),qe=e(a.Label,{id:xe,htmlFor:ge,className:N(I[B],"font-semibold",Ie?"text-(--plass-muted-fg)":"text-(--plass-fg)",Y?.label),children:T});return t(a.Root,{ref:De,disabled:Ie,invalid:ze,className:N("flex-col align-top",S[B],H?"flex w-full":"inline-flex",X),style:{...$(Ce,F),...Z},...fe,children:[D(T)&&!Pe?qe:null,t(s.Root,{open:re,onOpenChange:e=>ie(e),children:[e(u,{notched:Pe,size:B,density:q,variant:z,disabled:Ie,readOnly:K,float:ke,empty:le,label:qe,children:t("span",{style:Pe?h:void 0,onPointerMove:d(Oe),className:N(M,Pe?"":L,v[B],y[B],R[B],C[B],O[q][B],Ie?w[z]:K?P[z]:k[z],Oe?"plass-glow":"",Y?.control),children:[e(a.Validity,{children:({validity:l})=>{const a=!1===l.valid,r=[W?ve:null,$e||a&&!Ie&&!0!==A?ye:null].filter(Boolean).join(" ")||void 0;return t(s.Trigger,{id:ge,ref:ce,disabled:Ie,"aria-label":me,"aria-labelledby":Ne?`${Ne} ${be}`:void 0,"aria-describedby":r,"aria-required":Q||void 0,"aria-invalid":ze||a||void 0,onBlur:()=>{re||i(Se.current)},className:N("flex min-w-0 flex-1 items-center bg-transparent p-0 text-start [font:inherit] text-inherit",C[B],"[outline:none]",Re?"cursor-default":"cursor-pointer"),children:[G?e("span",{className:"flex h-[1lh] shrink-0 items-center text-(--plass-muted-fg)",children:G}):null,t("span",{className:"flex min-w-0 flex-1 flex-col",children:[e("span",{id:be,className:N("w-full truncate",le?"text-(--plass-muted-fg)":"text-(--plass-fg)",ke&&f),children:ee}),H?null:e(c,{samples:ke?[...te??[],m(T)].filter(Boolean):te??[]})]})]})}}),!ae||le||Re?null:e("button",{type:"button","aria-label":oe.clear,className:N(b,"text-(--plass-muted-fg)"),onClick:e=>{e.stopPropagation();const t=e.currentTarget,l=t.ownerDocument.activeElement===t;se(),l&&t.ownerDocument.getElementById(ge)?.focus()},children:e(p,{})})]})}),e(s.Portal,{children:e(s.Positioner,{className:"plass-portal z-(--plass-z-portal) [outline:none]",sideOffset:6,align:"start",children:e(s.Popup,{initialFocus:!1,className:N(pickerPopupClasses,R[B],popupPaddingClasses[B],y[B]),style:popupSlots(Ce,3),children:pe})})})]}),W?e(a.Description,{id:ve,className:N(j(B),Y?.description),children:W}):null,e(a.Error,$e?{id:ye,match:!0,className:N(I[B],"text-(--p-accent)",Y?.error),children:_}:{id:ye,className:N(I[B],"text-(--p-accent)",Y?.error)}),e(r,{ref:Se,name:ne,value:de,required:Q&&!K,disabled:Ie,standIn:()=>Se.current?.ownerDocument.getElementById(ge)})]})}export function PickerFooter({size:t,children:l}){return e("div",{className:N("flex items-center justify-end border-t pt-1.5","[border-color:var(--plass-divider)]",C[t]),children:l})}export function PickerDivider(){return e("div",{"aria-hidden":"true",className:"w-px self-stretch bg-(--plass-divider)"})}
@@ -98,6 +98,30 @@ export declare const barThicknessClasses: Record<PlassSize, string>;
98
98
  export declare const ringDiameters: Record<PlassSize, number>;
99
99
  /** The ring's stroke, thickening with the ring so the hole stays in proportion. */
100
100
  export declare const ringStrokes: Record<PlassSize, number>;
101
+ /**
102
+ * The stroke of a ring `diameter` pixels across, read off the ladder rather
103
+ * than given a proportion of its own.
104
+ *
105
+ * Between two rungs it is the straight line between their strokes, so a
106
+ * diameter that lands on a rung draws exactly that rung's ring. Past either end
107
+ * it keeps that end's proportion: `xl`'s, a little under a tenth of the
108
+ * diameter, which keeps the hole in proportion on a ring the size of a loading
109
+ * screen, and `xs`'s below it. So the stroke is always a fraction of the
110
+ * diameter, and the radius it leaves stays above zero however small the ring.
111
+ */
112
+ export declare function ringStrokeFor(diameter: number): number;
113
+ /**
114
+ * The diameter and the stroke a ring is drawn at: `size`'s rung, or `diameter`
115
+ * when it is a length a ring can be drawn at.
116
+ *
117
+ * Anything but a finite number above zero is ignored rather than drawn, so a
118
+ * `NaN` that arrived from a division somewhere draws the rung. The Dart build
119
+ * resolves the two numbers with the same arithmetic.
120
+ */
121
+ export declare function ringMetrics(size: PlassSize, diameter: number | undefined): {
122
+ diameter: number;
123
+ stroke: number;
124
+ };
101
125
  /**
102
126
  * One plate of a `PlProgressBox`, on the tick ladder — an indicator beside a
103
127
  * label, not a control you can put one inside.
@@ -1 +1 @@
1
- import{numberFormatter as s}from"./format.js";import{forcedFieldEdgeClasses as r,forcedFillClasses as t}from"./styles.js";export function progressSlots(s){return{"--p-fill":`var(--plass-${s}-fill)`,"--p-solid":`var(--plass-${s}-solid)`,"--p-solid-to":`var(--plass-${s}-solid-to)`,"--p-accent":`var(--plass-${s}-accent)`,"--p-soft":`var(--plass-${s}-soft)`,"--p-soft-press":`var(--plass-${s}-soft-press)`}}export const barThicknessClasses={xs:"h-1",sm:"h-1.5",md:"h-1.5",lg:"h-2",xl:"h-2.5"};export const ringDiameters={xs:14,sm:16,md:20,lg:26,xl:32};export const ringStrokes={xs:1.5,sm:1.75,md:2,lg:2.5,xl:3};export const plateSizeClasses={xs:"size-2",sm:"size-2.5",md:"size-3",lg:"size-4",xl:"size-5"};export const plateRadiusClasses={xs:"rounded-[0.1875rem]",sm:"rounded-[0.25rem]",md:"rounded-[0.28125rem]",lg:"rounded-[0.375rem]",xl:"rounded-[0.4375rem]"};export const plateGapClasses={xs:"gap-1",sm:"gap-1",md:"gap-1.5",lg:"gap-1.5",xl:"gap-2"};export const trackClasses=`bg-(--plass-track) ${r}`;export const fillClasses=`[background-image:var(--p-fill)] ${t}`;export const fillTransitionClasses="[transition:width_var(--plass-duration-slow)_var(--plass-ease)] motion-reduce:[transition-duration:0ms]";export function progressFraction(s,r,t){return null==s||Number.isNaN(s)||t<=r?null:Math.min(1,Math.max(0,(s-r)/(t-r)))}export function progressValue(s,r,t){return null==s||null===progressFraction(s,r,t)?null:Math.min(t,Math.max(r,s))}const e={style:"percent"};export function progressText(r,t,o,l){return null===r?null:o?t:s(l,e).format(r)}export function progressAriaText(s,r,t){if(null!==s)return e=>progressText(s,e,r,t)??""}
1
+ import{numberFormatter as r}from"./format.js";import{forcedFieldEdgeClasses as s,forcedFillClasses as e}from"./styles.js";export function progressSlots(r){return{"--p-fill":`var(--plass-${r}-fill)`,"--p-solid":`var(--plass-${r}-solid)`,"--p-solid-to":`var(--plass-${r}-solid-to)`,"--p-accent":`var(--plass-${r}-accent)`,"--p-soft":`var(--plass-${r}-soft)`,"--p-soft-press":`var(--plass-${r}-soft-press)`}}export const barThicknessClasses={xs:"h-1",sm:"h-1.5",md:"h-1.5",lg:"h-2",xl:"h-2.5"};export const ringDiameters={xs:14,sm:16,md:20,lg:26,xl:32};export const ringStrokes={xs:1.5,sm:1.75,md:2,lg:2.5,xl:3};const t=["xs","sm","md","lg","xl"];export function ringStrokeFor(r){if(r<=ringDiameters.xs)return r*ringStrokes.xs/ringDiameters.xs;if(r>=ringDiameters.xl)return r*ringStrokes.xl/ringDiameters.xl;const s=t.findIndex(s=>ringDiameters[s]>=r),e=t[s-1],n=t[s];return ringStrokes[e]+(r-ringDiameters[e])/(ringDiameters[n]-ringDiameters[e])*(ringStrokes[n]-ringStrokes[e])}export function ringMetrics(r,s){return void 0===s||!Number.isFinite(s)||s<=0?{diameter:ringDiameters[r],stroke:ringStrokes[r]}:{diameter:s,stroke:ringStrokeFor(s)}}export const plateSizeClasses={xs:"size-2",sm:"size-2.5",md:"size-3",lg:"size-4",xl:"size-5"};export const plateRadiusClasses={xs:"rounded-[0.1875rem]",sm:"rounded-[0.25rem]",md:"rounded-[0.28125rem]",lg:"rounded-[0.375rem]",xl:"rounded-[0.4375rem]"};export const plateGapClasses={xs:"gap-1",sm:"gap-1",md:"gap-1.5",lg:"gap-1.5",xl:"gap-2"};export const trackClasses=`bg-(--plass-track) ${s}`;export const fillClasses=`[background-image:var(--p-fill)] ${e}`;export const fillTransitionClasses="[transition:width_var(--plass-duration-slow)_var(--plass-ease)] motion-reduce:[transition-duration:0ms]";export function progressFraction(r,s,e){return null==r||Number.isNaN(r)||e<=s?null:Math.min(1,Math.max(0,(r-s)/(e-s)))}export function progressValue(r,s,e){return null==r||null===progressFraction(r,s,e)?null:Math.min(e,Math.max(s,r))}const n={style:"percent"};export function progressText(s,e,t,o){return null===s?null:t?e:r(o,n).format(s)}export function progressAriaText(r,s,e){if(null!==r)return t=>progressText(r,t,s,e)??""}
@@ -29,3 +29,15 @@
29
29
  export declare function searchText(value: unknown): string;
30
30
  /** Every string a row can be found by, folded once and joined into one haystack. */
31
31
  export declare function searchHaystack(values: readonly unknown[]): string;
32
+ /**
33
+ * `searchText` of what `read` finds on an item, remembered per item.
34
+ *
35
+ * Only the needle changes from one keystroke to the next, so a filter that
36
+ * folds its items as it goes folds every one of them again for every character
37
+ * typed. This folds an item the first time a query reaches it and hands the
38
+ * same text back after that, for as long as `read` finds the same value on it —
39
+ * an item whose text changed is folded again, so nothing it answers is stale.
40
+ * Kept by the item itself, weakly, so an item nobody holds any more takes its
41
+ * text with it.
42
+ */
43
+ export declare function cachedSearchText<Item extends object>(read: (item: Item) => unknown): (item: Item) => string;
@@ -1 +1 @@
1
- const e=/[\u0300-\u036f]/g;export function searchText(t){return null==t||"object"==typeof t?"":String(t).normalize("NFD").replace(e,"").toLowerCase()}export function searchHaystack(e){return e.map(searchText).join("\0")}
1
+ const e=/[\u0300-\u036f]/g;export function searchText(t){return null==t||"object"==typeof t?"":String(t).normalize("NFD").replace(e,"").toLowerCase()}export function searchHaystack(e){return e.map(searchText).join("\0")}export function cachedSearchText(e){const t=new WeakMap;return r=>{const n=e(r),c=t.get(r);if(c&&Object.is(c.value,n))return c.text;const a=searchText(n);return t.set(r,{value:n,text:a}),a}}
@@ -7,9 +7,15 @@
7
7
  * `Washington DC`. Either way the field moves under the pointer that just used
8
8
  * it, and the whole row of controls beside it shuffles along.
9
9
  *
10
- * So the alternatives are laid out too, stacked in a box clipped to no height.
11
- * The control's intrinsic width becomes the widest of them and stops depending
12
- * on the value.
10
+ * So the alternatives are laid out too, one to a line in a box clipped to no
11
+ * height. The control's intrinsic width becomes the widest line and stops
12
+ * depending on the value.
13
+ *
14
+ * The lines are one element. Every sample goes into one attribute, a newline
15
+ * between each two, and `white-space: pre` breaks the line there and nowhere
16
+ * else, so the box is as wide as its widest line. An element per sample drew
17
+ * the same box and cost a select of 250 countries 250 elements, each with a
18
+ * generated box of its own to style and lay out.
13
19
  *
14
20
  * Three things it deliberately is not:
15
21
  *
@@ -17,11 +23,12 @@
17
23
  * and a box that is not laid out reserves nothing.
18
24
  * - **Not read out.** `aria-hidden`, or a screen reader would announce every
19
25
  * value the control might hold before the one it does.
20
- * - **Not text.** A sample is drawn as generated content off a data attribute
21
- * rather than as a text node. `content: attr(…)` lays out exactly like text,
22
- * so it reserves the same width — but it leaves nothing for `getByText` or a
23
- * screen reader's find-in-page to trip over, and a caller's test asking for
24
- * the option they selected keeps finding one element rather than two.
26
+ * - **Not text.** The samples are drawn as generated content off a data
27
+ * attribute rather than as a text node. `content: attr(…)` lays out exactly
28
+ * like text, so it reserves the same width — but it leaves nothing for
29
+ * `getByText` or a screen reader's find-in-page to trip over, and a caller's
30
+ * test asking for the option they selected keeps finding one element rather
31
+ * than two.
25
32
  *
26
33
  * Which is why a sample is a string and never a node. A label that is a node
27
34
  * reaches here as its text, through `textOf`: laid out for real, a list of
@@ -1 +1 @@
1
- import{jsx as e}from"react/jsx-runtime";export function WidthSizer({samples:a}){return 0===a.length?null:e("span",{"aria-hidden":"true",className:"invisible h-0 min-h-0 overflow-hidden",children:a.map((a,n)=>e("span",{"data-sample":a,className:"block whitespace-nowrap before:content-[attr(data-sample)]"},`${n}:${a}`))})}
1
+ import{jsx as e}from"react/jsx-runtime";export function WidthSizer({samples:n}){return 0===n.length?null:e("span",{"aria-hidden":"true","data-sample":n.map(oneLine).join("\n"),className:"invisible block h-0 min-h-0 overflow-hidden whitespace-pre before:content-[attr(data-sample)]"})}function oneLine(e){return e.replace(/[ \t\n\r]+/g," ").replace(/^ | $/g,"")}
@@ -212,6 +212,10 @@ export declare const sheetHeaderGapClasses: Record<PlassSize, string>;
212
212
  *
213
213
  * `-webkit-backdrop-filter` is written alongside the standard property because
214
214
  * Safari still needs it, and Tailwind will not add it for an arbitrary value.
215
+ *
216
+ * For a reader who has asked for less transparency `--plass-blur` is `none` and
217
+ * the glass tokens are opaque (`styles.css`), so a surface that pairs these with
218
+ * a `--plass-glass*` fill needs nothing of its own for that reader.
215
219
  */
216
220
  export declare const glassClasses = "[backdrop-filter:var(--plass-blur)] [-webkit-backdrop-filter:var(--plass-blur)]";
217
221
  /**
@@ -321,6 +325,10 @@ export declare const safeInlineClasses: Record<'Start' | 'End', string>;
321
325
  * or the trigger in the markup and is positioned, so where the square reaches
322
326
  * over one of them the × has the press, and the neighbour keeps everything
323
327
  * outside the square.
328
+ *
329
+ * `p-0` because a browser pads a button on every side, and
330
+ * `plass-ui/styles.css` does not reset that padding: WebKit's is a pixel deeper
331
+ * below than above, which would sit the × half a pixel high.
324
332
  */
325
333
  export declare const chipRemoveClasses: string;
326
334
  /** Icons track their label rather than carrying a size of their own. */
@@ -349,17 +357,25 @@ export declare const pictureSlotClasses: string;
349
357
  * text off the accessibility tree along with the screen, and the third leaves a
350
358
  * clickable ghost the size of the words. A 1px clipped box is the one form that
351
359
  * is invisible to a sighted reader and present to every other kind.
360
+ *
361
+ * The text effects put their line in one of these and draw what a sighted
362
+ * reader sees as generated content beside it, so this copy is the only text
363
+ * there is: the one a crawler indexes and the one a selection copies.
352
364
  */
353
365
  export declare const srOnlyClasses = "absolute size-px overflow-hidden whitespace-nowrap [clip-path:inset(50%)]";
354
366
  /**
355
- * The same clipped box, for a copy of text that is also drawn.
367
+ * The drawn copy of a text effect whose line changes while it runs, holding the
368
+ * room of the line it arrives at.
356
369
  *
357
- * A text effect draws its line and puts a second copy of it beside it for a
358
- * screen reader, so a selection across the pair used to hand back the line
359
- * twice. This one is left out of the selection: the drawn copy is the one a
360
- * sighted reader can see, and the one they mean when they copy it.
370
+ * Two pieces of generated content in one grid cell: `data-text`, the frame
371
+ * being drawn, and `data-sample`, the finished line, laid out and not drawn.
372
+ * The cell is as wide as the wider of the two, so the box has the finished
373
+ * line's width from the first paint, and a frame that is narrower — a count
374
+ * still short of its figure — no longer moves the text around it as it grows.
375
+ * The frame is the first of the two, so it is the one the grid takes its
376
+ * baseline from, and it sits on the line of the text around it.
361
377
  */
362
- export declare const srOnlyCopyClasses = "absolute size-px overflow-hidden whitespace-nowrap [clip-path:inset(50%)] select-none";
378
+ export declare const drawnCopyClasses: string;
363
379
  /**
364
380
  * Every slot a control reads.
365
381
  *