plass-ui 1.4.0 → 1.6.0

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 (268) hide show
  1. package/CHANGELOG.md +432 -0
  2. package/README.md +45 -23
  3. package/dist/components/accordion/PlAccordion.d.ts +1 -1
  4. package/dist/components/alert/PlAlert.js +1 -1
  5. package/dist/components/anchor/PlAnchor.d.ts +14 -1
  6. package/dist/components/anchor/PlAnchor.js +1 -1
  7. package/dist/components/animate-appear/PlAnimateAppear.js +1 -1
  8. package/dist/components/animate-blink/PlAnimateBlink.js +1 -1
  9. package/dist/components/animate-counter/PlAnimateCounter.js +1 -1
  10. package/dist/components/animate-fade/PlAnimateFade.js +1 -1
  11. package/dist/components/animate-float/PlAnimateFloat.js +1 -1
  12. package/dist/components/animate-grow/PlAnimateGrow.js +1 -1
  13. package/dist/components/animate-headline/PlAnimateHeadline.js +1 -1
  14. package/dist/components/animate-lighting/PlAnimateLighting.js +1 -1
  15. package/dist/components/animate-marquee/PlAnimateMarquee.d.ts +16 -4
  16. package/dist/components/animate-marquee/PlAnimateMarquee.js +1 -1
  17. package/dist/components/animate-reveal/PlAnimateReveal.js +1 -1
  18. package/dist/components/animate-rotate/PlAnimateRotate.js +1 -1
  19. package/dist/components/animate-scramble/PlAnimateScramble.js +1 -1
  20. package/dist/components/animate-shake/PlAnimateShake.js +1 -1
  21. package/dist/components/animate-slide/PlAnimateSlide.js +1 -1
  22. package/dist/components/animate-split/PlAnimateSplit.d.ts +7 -4
  23. package/dist/components/animate-split/PlAnimateSplit.js +1 -1
  24. package/dist/components/animate-typing/PlAnimateTyping.d.ts +3 -2
  25. package/dist/components/animate-typing/PlAnimateTyping.js +1 -1
  26. package/dist/components/animate-zoom/PlAnimateZoom.js +1 -1
  27. package/dist/components/app-logo/PlAppLogo.js +1 -1
  28. package/dist/components/area-chart/PlAreaChart.d.ts +1 -1
  29. package/dist/components/area-chart/PlAreaChart.js +1 -1
  30. package/dist/components/aspect-ratio/PlAspectRatio.d.ts +2 -1
  31. package/dist/components/aspect-ratio/PlAspectRatio.js +1 -1
  32. package/dist/components/avatar/PlAvatar.js +1 -1
  33. package/dist/components/back-top/PlBackTop.d.ts +8 -1
  34. package/dist/components/back-top/PlBackTop.js +1 -1
  35. package/dist/components/badge/PlBadge.js +1 -1
  36. package/dist/components/bar-chart/PlBarChart.d.ts +1 -1
  37. package/dist/components/bar-chart/PlBarChart.js +1 -1
  38. package/dist/components/blockquote/PlBlockquote.js +1 -1
  39. package/dist/components/bottom-navigation/PlBottomNavigation.d.ts +3 -0
  40. package/dist/components/breadcrumb/PlBreadcrumb.js +1 -1
  41. package/dist/components/button/PlButton.d.ts +8 -0
  42. package/dist/components/button/PlButton.js +1 -1
  43. package/dist/components/calendar/PlCalendar.js +1 -1
  44. package/dist/components/card/PlCard.js +1 -1
  45. package/dist/components/carousel/PlCarousel.d.ts +1 -1
  46. package/dist/components/carousel/PlCarousel.js +1 -1
  47. package/dist/components/chat-bubble/PlChatBubble.d.ts +4 -1
  48. package/dist/components/chat-bubble/PlChatBubble.js +1 -1
  49. package/dist/components/checkbox/PlCheckbox.js +1 -1
  50. package/dist/components/chip/PlChip.d.ts +6 -2
  51. package/dist/components/chip/PlChip.js +1 -1
  52. package/dist/components/code-block/PlCodeBlock.d.ts +19 -2
  53. package/dist/components/code-block/PlCodeBlock.js +1 -1
  54. package/dist/components/color-picker/PlColorPicker.d.ts +19 -2
  55. package/dist/components/color-picker/PlColorPicker.js +1 -1
  56. package/dist/components/combobox/PlCombobox.d.ts +14 -7
  57. package/dist/components/combobox/PlCombobox.js +1 -1
  58. package/dist/components/command-palette/PlCommandPalette.d.ts +6 -2
  59. package/dist/components/command-palette/PlCommandPalette.js +1 -1
  60. package/dist/components/confirm/PlConfirmProvider.js +1 -1
  61. package/dist/components/container/PlContainer.js +1 -1
  62. package/dist/components/data-table/PlDataTable.d.ts +20 -6
  63. package/dist/components/data-table/PlDataTable.js +1 -1
  64. package/dist/components/date-picker/PlDatePicker.js +1 -1
  65. package/dist/components/date-range-picker/PlDateRangePicker.js +1 -1
  66. package/dist/components/date-time-picker/PlDateTimePicker.js +1 -1
  67. package/dist/components/drawer/PlDrawer.js +1 -1
  68. package/dist/components/empty/PlEmpty.js +1 -1
  69. package/dist/components/file-picker/PlFilePicker.d.ts +22 -3
  70. package/dist/components/file-picker/PlFilePicker.js +1 -1
  71. package/dist/components/floating-bottom-navigation/PlFloatingBottomNavigation.d.ts +3 -0
  72. package/dist/components/floating-bottom-navigation/PlFloatingBottomNavigation.js +1 -1
  73. package/dist/components/form/PlForm.js +1 -1
  74. package/dist/components/gallery/PlGallery.d.ts +40 -2
  75. package/dist/components/gallery/PlGallery.js +1 -1
  76. package/dist/components/gallery/PlGalleryViewer.js +1 -1
  77. package/dist/components/gauge-chart/PlGaugeChart.js +1 -1
  78. package/dist/components/heatmap-chart/PlHeatmapChart.js +1 -1
  79. package/dist/components/highlight/PlHighlight.d.ts +10 -3
  80. package/dist/components/highlight/PlHighlight.js +1 -1
  81. package/dist/components/hot-keys/PlHotKeys.js +1 -1
  82. package/dist/components/hover-card/PlHoverCard.d.ts +5 -3
  83. package/dist/components/hover-card/PlHoverCard.js +1 -1
  84. package/dist/components/how-to-steps/PlHowToSteps.js +1 -1
  85. package/dist/components/image/PlImage.d.ts +195 -8
  86. package/dist/components/image/PlImage.js +1 -1
  87. package/dist/components/image/PlImagePreview.d.ts +58 -0
  88. package/dist/components/image/PlImagePreview.js +1 -0
  89. package/dist/components/image/index.d.ts +1 -1
  90. package/dist/components/list/PlList.js +1 -1
  91. package/dist/components/menu/PlMenu.d.ts +14 -5
  92. package/dist/components/menu/PlMenu.js +1 -1
  93. package/dist/components/meter/PlMeter.js +1 -1
  94. package/dist/components/navigation-menu/PlNavigationMenu.d.ts +7 -1
  95. package/dist/components/navigation-menu/PlNavigationMenu.js +1 -1
  96. package/dist/components/number-field/PlNumberField.d.ts +12 -4
  97. package/dist/components/number-field/PlNumberField.js +1 -1
  98. package/dist/components/otp-field/PlOtpField.d.ts +15 -1
  99. package/dist/components/otp-field/PlOtpField.js +1 -1
  100. package/dist/components/page-layout/PlPageLayout.js +1 -1
  101. package/dist/components/pagination/PlPagination.d.ts +12 -9
  102. package/dist/components/pagination/PlPagination.js +1 -1
  103. package/dist/components/panes/PlPanes.d.ts +5 -0
  104. package/dist/components/panes/PlPanes.js +1 -1
  105. package/dist/components/pie-chart/PlPieChart.js +1 -1
  106. package/dist/components/pill/PlPill.js +1 -1
  107. package/dist/components/popover/PlPopover.d.ts +5 -5
  108. package/dist/components/popover/PlPopover.js +1 -1
  109. package/dist/components/progress-box/PlProgressBox.js +1 -1
  110. package/dist/components/progress-circular/PlProgressCircular.js +1 -1
  111. package/dist/components/progress-linear/PlProgressLinear.js +1 -1
  112. package/dist/components/radio-group/PlRadioGroup.js +1 -1
  113. package/dist/components/rating/PlRating.d.ts +1 -1
  114. package/dist/components/rating/PlRating.js +1 -1
  115. package/dist/components/scatter-chart/PlScatterChart.js +1 -1
  116. package/dist/components/scroll-area/PlScrollArea.js +1 -1
  117. package/dist/components/scroll-zone/PlScrollZone.d.ts +19 -6
  118. package/dist/components/scroll-zone/PlScrollZone.js +1 -1
  119. package/dist/components/segmented-button/PlSegmentedButton.js +1 -1
  120. package/dist/components/select/PlSelect.d.ts +8 -2
  121. package/dist/components/select/PlSelect.js +1 -1
  122. package/dist/components/show/PlShow.d.ts +16 -0
  123. package/dist/components/show/PlShow.js +1 -1
  124. package/dist/components/sidebar/PlSidebar.js +1 -1
  125. package/dist/components/sidebar/PlSidebarTrigger.js +1 -1
  126. package/dist/components/skeleton/PlSkeleton.js +1 -1
  127. package/dist/components/slider/PlSlider.d.ts +13 -1
  128. package/dist/components/slider/PlSlider.js +1 -1
  129. package/dist/components/sparkline/PlSparkline.js +1 -1
  130. package/dist/components/spoiler/PlSpoiler.d.ts +15 -8
  131. package/dist/components/spoiler/PlSpoiler.js +1 -1
  132. package/dist/components/stat/PlStat.d.ts +4 -0
  133. package/dist/components/stat/PlStat.js +1 -1
  134. package/dist/components/stepper/PlStepper.d.ts +1 -1
  135. package/dist/components/stepper/PlStepper.js +1 -1
  136. package/dist/components/switch/PlSwitch.js +1 -1
  137. package/dist/components/table/PlTable.d.ts +5 -5
  138. package/dist/components/tabs/PlTabs.d.ts +26 -1
  139. package/dist/components/tabs/PlTabs.js +1 -1
  140. package/dist/components/text-field/PlTextField.d.ts +15 -5
  141. package/dist/components/text-field/PlTextField.js +1 -1
  142. package/dist/components/text-link/PlTextLink.js +1 -1
  143. package/dist/components/time-picker/PlTimePicker.js +1 -1
  144. package/dist/components/timeline/PlTimeline.js +1 -1
  145. package/dist/components/timeline-chart/PlTimelineChart.js +1 -1
  146. package/dist/components/toast/PlToast.js +1 -1
  147. package/dist/components/toggle/PlToggle.js +1 -1
  148. package/dist/components/tooltip/PlTooltip.js +1 -1
  149. package/dist/components/tour/PlTour.js +1 -1
  150. package/dist/components/transfer/PlTransfer.d.ts +10 -1
  151. package/dist/components/transfer/PlTransfer.js +1 -1
  152. package/dist/components/tree/PlTree.js +1 -1
  153. package/dist/components/tree-select/PlTreeSelect.js +1 -1
  154. package/dist/components/typography/PlTypography.js +1 -1
  155. package/dist/components/window-pane/PlWindowPane.d.ts +3 -3
  156. package/dist/components/window-pane/PlWindowPane.js +1 -1
  157. package/dist/css/area-chart.css +1 -0
  158. package/dist/css/back-top.css +2 -0
  159. package/dist/css/bar-chart.css +1 -0
  160. package/dist/css/calendar.css +1 -0
  161. package/dist/css/carousel.css +2 -0
  162. package/dist/css/color-picker.css +1 -0
  163. package/dist/css/combobox.css +1 -0
  164. package/dist/css/command-palette.css +1 -0
  165. package/dist/css/confirm.css +2 -0
  166. package/dist/css/data-table.css +5 -0
  167. package/dist/css/date-picker.css +1 -0
  168. package/dist/css/date-range-picker.css +1 -0
  169. package/dist/css/date-time-picker.css +1 -0
  170. package/dist/css/floating-action-button.css +2 -0
  171. package/dist/css/gallery.css +5 -0
  172. package/dist/css/gauge-chart.css +1 -0
  173. package/dist/css/heatmap-chart.css +1 -0
  174. package/dist/css/icon-button.css +1 -0
  175. package/dist/css/image.css +2 -0
  176. package/dist/css/line-chart.css +1 -0
  177. package/dist/css/menubar.css +1 -0
  178. package/dist/css/pagination.css +1 -0
  179. package/dist/css/pie-chart.css +1 -0
  180. package/dist/css/popconfirm.css +2 -0
  181. package/dist/css/scatter-chart.css +1 -0
  182. package/dist/css/scroll-zone.css +2 -0
  183. package/dist/css/sidebar.css +3 -0
  184. package/dist/css/sparkline.css +1 -0
  185. package/dist/css/spoiler.css +1 -0
  186. package/dist/css/stat.css +1 -0
  187. package/dist/css/time-picker.css +1 -0
  188. package/dist/css/timeline-chart.css +1 -0
  189. package/dist/css/tour.css +1 -0
  190. package/dist/css/transfer.css +4 -0
  191. package/dist/css/tree-select.css +2 -0
  192. package/dist/hooks/usePlElementSize.d.ts +4 -1
  193. package/dist/hooks/usePlElementSize.js +1 -1
  194. package/dist/hooks/usePlHotKeys.d.ts +5 -1
  195. package/dist/hooks/usePlHotKeys.js +1 -1
  196. package/dist/hooks/usePlOnScreen.d.ts +4 -0
  197. package/dist/hooks/usePlOnScreen.js +1 -1
  198. package/dist/internal/animate.d.ts +24 -21
  199. package/dist/internal/animate.js +1 -1
  200. package/dist/internal/calendar.js +1 -1
  201. package/dist/internal/chart-frame.d.ts +3 -14
  202. package/dist/internal/chart-frame.js +1 -1
  203. package/dist/internal/chart-line.js +1 -1
  204. package/dist/internal/chart.d.ts +90 -3
  205. package/dist/internal/chart.js +1 -1
  206. package/dist/internal/color-scheme.js +1 -1
  207. package/dist/internal/data-table.d.ts +5 -4
  208. package/dist/internal/data-table.js +1 -1
  209. package/dist/internal/date.d.ts +10 -0
  210. package/dist/internal/date.js +1 -1
  211. package/dist/internal/defaults.d.ts +14 -1
  212. package/dist/internal/drag.d.ts +16 -0
  213. package/dist/internal/drag.js +1 -1
  214. package/dist/internal/focusable.d.ts +8 -0
  215. package/dist/internal/focusable.js +1 -0
  216. package/dist/internal/form.d.ts +61 -0
  217. package/dist/internal/form.js +1 -0
  218. package/dist/internal/gallery.d.ts +60 -14
  219. package/dist/internal/gallery.js +1 -1
  220. package/dist/internal/glow.d.ts +32 -0
  221. package/dist/internal/glow.js +1 -0
  222. package/dist/internal/highlight.js +1 -1
  223. package/dist/internal/image.d.ts +94 -0
  224. package/dist/internal/image.js +1 -0
  225. package/dist/internal/inert.d.ts +19 -0
  226. package/dist/internal/inert.js +1 -0
  227. package/dist/internal/keys.d.ts +19 -0
  228. package/dist/internal/keys.js +1 -1
  229. package/dist/internal/labels.d.ts +58 -1
  230. package/dist/internal/labels.js +1 -1
  231. package/dist/internal/link.d.ts +17 -0
  232. package/dist/internal/link.js +1 -1
  233. package/dist/internal/notch.d.ts +83 -0
  234. package/dist/internal/notch.js +1 -0
  235. package/dist/internal/page-layout.d.ts +14 -7
  236. package/dist/internal/page-layout.js +1 -1
  237. package/dist/internal/picker.d.ts +51 -8
  238. package/dist/internal/picker.js +1 -1
  239. package/dist/internal/progress.d.ts +16 -8
  240. package/dist/internal/progress.js +1 -1
  241. package/dist/internal/scramble.d.ts +4 -0
  242. package/dist/internal/scramble.js +1 -1
  243. package/dist/internal/scroll-target.d.ts +5 -0
  244. package/dist/internal/scroll-target.js +1 -0
  245. package/dist/internal/steps.js +1 -1
  246. package/dist/internal/styles.d.ts +87 -0
  247. package/dist/internal/styles.js +1 -1
  248. package/dist/internal/text.d.ts +39 -0
  249. package/dist/internal/text.js +1 -0
  250. package/dist/internal/watermark.d.ts +44 -0
  251. package/dist/internal/watermark.js +1 -0
  252. package/dist/internal/wheel.d.ts +52 -0
  253. package/dist/internal/wheel.js +1 -0
  254. package/dist/internal/window.js +1 -1
  255. package/dist/locales/de.js +1 -1
  256. package/dist/locales/es.js +1 -1
  257. package/dist/locales/fr.js +1 -1
  258. package/dist/locales/ja.js +1 -1
  259. package/dist/locales/ko.js +1 -1
  260. package/dist/locales/zh-Hans.js +1 -1
  261. package/dist/provider/PlColorSchemeScript.js +1 -1
  262. package/dist/provider/PlassProvider.d.ts +4 -3
  263. package/dist/provider/PlassProvider.js +1 -1
  264. package/dist/styles.css +1 -1
  265. package/dist/tailwind.css +313 -15
  266. package/dist/tokens.css +313 -15
  267. package/dist/types.d.ts +71 -29
  268. package/package.json +15 -15
package/dist/tokens.css CHANGED
@@ -56,8 +56,11 @@
56
56
  * surface rather than looked at.
57
57
  *
58
58
  * Three values are hand-picked per family and everything else is derived with
59
- * `color-mix()`, so **adding a colour family is two edits**: one entry in
60
- * `PlassColor` and three lines here (plus its `accent` in each theme).
59
+ * `color-mix()`. Adding a family is still five places, though: one entry in
60
+ * `PlassColor`, those three lines here, an `accent` in each of the three theme
61
+ * blocks below, the eight derived declarations, which are written out per
62
+ * family rather than generated, and the Flutter package's own enum and
63
+ * families.
61
64
  *
62
65
  * `solid` and `solid-to` are the two ends of the gradient, at 135° — the
63
66
  * top-left corner and the bottom-right one. They are a **hue sweep at one
@@ -567,11 +570,21 @@
567
570
  * resolves its `var()`s on the element that declares it — declaring these only
568
571
  * on `:root` would freeze `--plass-*-tint` to the light theme's
569
572
  * `--plass-tint-strength` inside a `.dark` subtree.
573
+ *
574
+ * `.plass-theme` is the same reasoning applied to a *colour* override. Setting
575
+ * `--plass-primary-solid` on a `<div>` changes the base and nothing else,
576
+ * because every value derived from it was computed further up, where the old
577
+ * colour still is. The class re-runs the whole block on that element, so the
578
+ * gradient, the tint, the hairline and the ring follow the base that was just
579
+ * written beside them. It is the one hook here that does not force a theme:
580
+ * `--plass-tint-strength` and the rest inherit from whichever theme root is
581
+ * above, so a scoped family works the same in light and in dark.
570
582
  * ------------------------------------------------------------------------- */
571
583
 
572
584
  :root,
573
585
  .dark,
574
586
  .light,
587
+ .plass-theme,
575
588
  [data-theme='dark'],
576
589
  [data-theme='light'] {
577
590
  /* The elevation ladder. Neutral, wide and faint — it climbs by *blur* far
@@ -611,7 +624,11 @@
611
624
  --plass-primary-soft-press: color-mix(in srgb, var(--plass-primary-accent) 26%, transparent);
612
625
  --plass-primary-line: color-mix(in srgb, var(--plass-primary-accent) 30%, transparent);
613
626
  --plass-primary-line-hover: color-mix(in srgb, var(--plass-primary-accent) 48%, transparent);
614
- --plass-primary-ring: color-mix(in srgb, var(--plass-primary-solid) 55%, transparent);
627
+ /* The focus ring is the accent at full strength, because it is read against
628
+ the page rather than looked at: the ring has to clear 3:1 against the
629
+ sheet round a control in both themes, and only the per-theme accent does.
630
+ `solid` is one colour for both, and amber on white cannot reach it. */
631
+ --plass-primary-ring: var(--plass-primary-accent);
615
632
 
616
633
  --plass-secondary-fill: linear-gradient(
617
634
  135deg,
@@ -628,7 +645,7 @@
628
645
  --plass-secondary-soft-press: color-mix(in srgb, var(--plass-secondary-accent) 26%, transparent);
629
646
  --plass-secondary-line: color-mix(in srgb, var(--plass-secondary-accent) 30%, transparent);
630
647
  --plass-secondary-line-hover: color-mix(in srgb, var(--plass-secondary-accent) 48%, transparent);
631
- --plass-secondary-ring: color-mix(in srgb, var(--plass-secondary-solid) 55%, transparent);
648
+ --plass-secondary-ring: var(--plass-secondary-accent);
632
649
 
633
650
  --plass-success-fill: linear-gradient(
634
651
  135deg,
@@ -645,7 +662,7 @@
645
662
  --plass-success-soft-press: color-mix(in srgb, var(--plass-success-accent) 26%, transparent);
646
663
  --plass-success-line: color-mix(in srgb, var(--plass-success-accent) 30%, transparent);
647
664
  --plass-success-line-hover: color-mix(in srgb, var(--plass-success-accent) 48%, transparent);
648
- --plass-success-ring: color-mix(in srgb, var(--plass-success-solid) 55%, transparent);
665
+ --plass-success-ring: var(--plass-success-accent);
649
666
 
650
667
  --plass-warning-fill: linear-gradient(
651
668
  135deg,
@@ -662,7 +679,7 @@
662
679
  --plass-warning-soft-press: color-mix(in srgb, var(--plass-warning-accent) 28%, transparent);
663
680
  --plass-warning-line: color-mix(in srgb, var(--plass-warning-accent) 34%, transparent);
664
681
  --plass-warning-line-hover: color-mix(in srgb, var(--plass-warning-accent) 52%, transparent);
665
- --plass-warning-ring: color-mix(in srgb, var(--plass-warning-solid) 55%, transparent);
682
+ --plass-warning-ring: var(--plass-warning-accent);
666
683
 
667
684
  --plass-danger-fill: linear-gradient(
668
685
  135deg,
@@ -679,7 +696,7 @@
679
696
  --plass-danger-soft-press: color-mix(in srgb, var(--plass-danger-accent) 26%, transparent);
680
697
  --plass-danger-line: color-mix(in srgb, var(--plass-danger-accent) 30%, transparent);
681
698
  --plass-danger-line-hover: color-mix(in srgb, var(--plass-danger-accent) 48%, transparent);
682
- --plass-danger-ring: color-mix(in srgb, var(--plass-danger-solid) 55%, transparent);
699
+ --plass-danger-ring: var(--plass-danger-accent);
683
700
 
684
701
  --plass-info-fill: linear-gradient(
685
702
  135deg,
@@ -696,7 +713,7 @@
696
713
  --plass-info-soft-press: color-mix(in srgb, var(--plass-info-accent) 26%, transparent);
697
714
  --plass-info-line: color-mix(in srgb, var(--plass-info-accent) 30%, transparent);
698
715
  --plass-info-line-hover: color-mix(in srgb, var(--plass-info-accent) 48%, transparent);
699
- --plass-info-ring: color-mix(in srgb, var(--plass-info-solid) 55%, transparent);
716
+ --plass-info-ring: var(--plass-info-accent);
700
717
  /* The three greys a chart draws its frame with, derived so a project that
701
718
  re-tones its border moves the grid with it.
702
719
 
@@ -792,6 +809,17 @@
792
809
  * never re-renders — the component writes the two custom properties directly.
793
810
  * ------------------------------------------------------------------------- */
794
811
 
812
+ /*
813
+ * A stacking context of the surface's own, which is what lets the bloom below
814
+ * sit at a negative depth without falling through the surface it belongs to.
815
+ * `isolation` rather than a `z-index`, because a z-index is a position in a
816
+ * stack somebody else owns and this is only a statement that the two layers are
817
+ * the surface's business.
818
+ */
819
+ .plass-glow {
820
+ isolation: isolate;
821
+ }
822
+
795
823
  .plass-glow::before,
796
824
  .plass-glow::after {
797
825
  content: '';
@@ -802,8 +830,20 @@
802
830
  opacity: 0;
803
831
  }
804
832
 
805
- /* The bloom trailing the pointer across the surface. */
833
+ /*
834
+ * The bloom trailing the pointer across the surface.
835
+ *
836
+ * **Under the label, and over the fill.** A positioned pseudo-element otherwise
837
+ * paints above every in-flow thing in the box, so the bloom was laid over the
838
+ * words on a key and over the value in a field — faint enough to miss on a
839
+ * white label and not on dark ink. `z-index: -1` puts it where a stacking
840
+ * context paints a negative layer, which is after the element's own background
841
+ * and before its content: over the gradient, under what is written on it. The
842
+ * flash below stays where it is, over everything, which is the pair the Flutter
843
+ * build draws as two separate widgets on either side of the label.
844
+ */
806
845
  .plass-glow::before {
846
+ z-index: -1;
807
847
  background: radial-gradient(
808
848
  6rem circle at var(--p-mx, 50%) var(--p-my, 50%),
809
849
  var(--p-glow, transparent),
@@ -1194,6 +1234,190 @@
1194
1234
  * drift.
1195
1235
  * ------------------------------------------------------------------------- */
1196
1236
 
1237
+ /*
1238
+ * The per-breakpoint slots do not inherit. Each one is written inline on the
1239
+ * element that reads it, and a custom property is inherited by default, so a
1240
+ * `PlFlex` nested in another took every rung its parent named and it did not:
1241
+ * a vertical flex inside `{ xs: 'vertical', md: 'horizontal' }` turned
1242
+ * horizontal at `md`, and a `PlGridItem` with no `span` inside a cell of eight
1243
+ * was eight columns wide. The slots they resolve into (`--p-cols`, `--p-gap-x`)
1244
+ * still inherit, which is how a grid item reads its grid.
1245
+ */
1246
+ @property --p-gap-x-xs {
1247
+ syntax: '*';
1248
+ inherits: false;
1249
+ }
1250
+
1251
+ @property --p-gap-x-sm {
1252
+ syntax: '*';
1253
+ inherits: false;
1254
+ }
1255
+
1256
+ @property --p-gap-x-md {
1257
+ syntax: '*';
1258
+ inherits: false;
1259
+ }
1260
+
1261
+ @property --p-gap-x-lg {
1262
+ syntax: '*';
1263
+ inherits: false;
1264
+ }
1265
+
1266
+ @property --p-gap-x-xl {
1267
+ syntax: '*';
1268
+ inherits: false;
1269
+ }
1270
+
1271
+ @property --p-gap-y-xs {
1272
+ syntax: '*';
1273
+ inherits: false;
1274
+ }
1275
+
1276
+ @property --p-gap-y-sm {
1277
+ syntax: '*';
1278
+ inherits: false;
1279
+ }
1280
+
1281
+ @property --p-gap-y-md {
1282
+ syntax: '*';
1283
+ inherits: false;
1284
+ }
1285
+
1286
+ @property --p-gap-y-lg {
1287
+ syntax: '*';
1288
+ inherits: false;
1289
+ }
1290
+
1291
+ @property --p-gap-y-xl {
1292
+ syntax: '*';
1293
+ inherits: false;
1294
+ }
1295
+
1296
+ @property --p-cols-xs {
1297
+ syntax: '*';
1298
+ inherits: false;
1299
+ }
1300
+
1301
+ @property --p-cols-sm {
1302
+ syntax: '*';
1303
+ inherits: false;
1304
+ }
1305
+
1306
+ @property --p-cols-md {
1307
+ syntax: '*';
1308
+ inherits: false;
1309
+ }
1310
+
1311
+ @property --p-cols-lg {
1312
+ syntax: '*';
1313
+ inherits: false;
1314
+ }
1315
+
1316
+ @property --p-cols-xl {
1317
+ syntax: '*';
1318
+ inherits: false;
1319
+ }
1320
+
1321
+ @property --p-dir-xs {
1322
+ syntax: '*';
1323
+ inherits: false;
1324
+ }
1325
+
1326
+ @property --p-dir-sm {
1327
+ syntax: '*';
1328
+ inherits: false;
1329
+ }
1330
+
1331
+ @property --p-dir-md {
1332
+ syntax: '*';
1333
+ inherits: false;
1334
+ }
1335
+
1336
+ @property --p-dir-lg {
1337
+ syntax: '*';
1338
+ inherits: false;
1339
+ }
1340
+
1341
+ @property --p-dir-xl {
1342
+ syntax: '*';
1343
+ inherits: false;
1344
+ }
1345
+
1346
+ @property --p-span-xs {
1347
+ syntax: '*';
1348
+ inherits: false;
1349
+ }
1350
+
1351
+ @property --p-span-sm {
1352
+ syntax: '*';
1353
+ inherits: false;
1354
+ }
1355
+
1356
+ @property --p-span-md {
1357
+ syntax: '*';
1358
+ inherits: false;
1359
+ }
1360
+
1361
+ @property --p-span-lg {
1362
+ syntax: '*';
1363
+ inherits: false;
1364
+ }
1365
+
1366
+ @property --p-span-xl {
1367
+ syntax: '*';
1368
+ inherits: false;
1369
+ }
1370
+
1371
+ @property --p-offset-xs {
1372
+ syntax: '*';
1373
+ inherits: false;
1374
+ }
1375
+
1376
+ @property --p-offset-sm {
1377
+ syntax: '*';
1378
+ inherits: false;
1379
+ }
1380
+
1381
+ @property --p-offset-md {
1382
+ syntax: '*';
1383
+ inherits: false;
1384
+ }
1385
+
1386
+ @property --p-offset-lg {
1387
+ syntax: '*';
1388
+ inherits: false;
1389
+ }
1390
+
1391
+ @property --p-offset-xl {
1392
+ syntax: '*';
1393
+ inherits: false;
1394
+ }
1395
+
1396
+ @property --p-maxw-xs {
1397
+ syntax: '*';
1398
+ inherits: false;
1399
+ }
1400
+
1401
+ @property --p-maxw-sm {
1402
+ syntax: '*';
1403
+ inherits: false;
1404
+ }
1405
+
1406
+ @property --p-maxw-md {
1407
+ syntax: '*';
1408
+ inherits: false;
1409
+ }
1410
+
1411
+ @property --p-maxw-lg {
1412
+ syntax: '*';
1413
+ inherits: false;
1414
+ }
1415
+
1416
+ @property --p-maxw-xl {
1417
+ syntax: '*';
1418
+ inherits: false;
1419
+ }
1420
+
1197
1421
  .plass-grid,
1198
1422
  .plass-flex {
1199
1423
  --p-gap-x: var(--p-gap-x-xs, 0px);
@@ -1681,13 +1905,28 @@
1681
1905
  animation-name: plass-anim-lighting;
1682
1906
  animation-duration: var(--p-anim-duration, 3s);
1683
1907
  animation-delay: var(--p-anim-delay, 0ms);
1684
- animation-timing-function: linear;
1908
+ /* Linear unless a caller says otherwise, which is what `curve` does in the
1909
+ Flutter build: an arc that eases at both ends of a turn that has no ends
1910
+ reads as a stutter, and that is a default rather than a rule. */
1911
+ animation-timing-function: var(--p-anim-ease, linear);
1685
1912
  animation-iteration-count: var(--p-anim-repeat, infinite);
1686
1913
  animation-direction: var(--p-anim-direction, normal);
1687
1914
  animation-fill-mode: both;
1688
1915
  animation-play-state: var(--p-anim-state, running);
1689
1916
  }
1690
1917
 
1918
+ /*
1919
+ * The rewind, for the one effect that runs on a pseudo-element.
1920
+ *
1921
+ * Restarting a CSS animation means clearing its name, forcing the style to
1922
+ * settle and putting the name back, and an inline style cannot reach a
1923
+ * `::before`. So the root carries `data-plass-rewind` for the length of that
1924
+ * read, and this is what answers it. Nothing is painted in between.
1925
+ */
1926
+ .plass-anim-lighting[data-plass-rewind]::before {
1927
+ animation-name: none;
1928
+ }
1929
+
1691
1930
  /*
1692
1931
  * Marquee: two identical copies, both moving by exactly one copy plus the gap.
1693
1932
  *
@@ -1725,6 +1964,12 @@
1725
1964
  flex-direction: column;
1726
1965
  }
1727
1966
 
1967
+ /* Inset, so a box inside something that clips does not lose its ring. */
1968
+ .plass-marquee:focus-visible {
1969
+ outline: 2px solid var(--plass-primary-ring);
1970
+ outline-offset: -2px;
1971
+ }
1972
+
1728
1973
  .plass-marquee-track {
1729
1974
  display: flex;
1730
1975
  flex: 0 0 auto;
@@ -1930,8 +2175,13 @@
1930
2175
  --p-code-del: oklch(75% 0.15 25);
1931
2176
  }
1932
2177
 
2178
+ /* Both ways of forcing light are named, the same pair the token block above
2179
+ answers to. `auto` means "whatever the page is", so a page that has said it
2180
+ is light with `.light` and one that has said it with `[data-theme='light']`
2181
+ have to leave the block light alike — otherwise the page is white and the
2182
+ code on it is the one dark rectangle nobody asked for. */
1933
2183
  @media (prefers-color-scheme: dark) {
1934
- :root:not([data-theme='light']) .plass-code[data-code-theme='auto'] {
2184
+ :root:not(.light):not([data-theme='light']) .plass-code[data-code-theme='auto'] {
1935
2185
  --p-code-bg: oklch(19.5% 0.014 262);
1936
2186
  --p-code-fg: oklch(90% 0.012 262);
1937
2187
 
@@ -2323,10 +2573,11 @@
2323
2573
  * arrangement that still reads as a set.
2324
2574
  *
2325
2575
  * The three lines below are what the slot is *for*. A grid and a quilt lay out
2326
- * in CSS Grid off `--p-cols`; a masonry deals its items into that many lanes in
2327
- * JavaScript, because which lane an item lands in changes the DOM and no
2328
- * stylesheet can do that; and a justified row is flexbox, which needs no count
2329
- * at all — it fills to the edge with whatever fits.
2576
+ * in CSS Grid off `--p-cols`; a masonry deals its items into lanes in JavaScript
2577
+ * and writes the count and the rows inline, because which lane an item lands in
2578
+ * depends on the heights of the items before it and no stylesheet can work that
2579
+ * out; and a justified row is flexbox, which needs no count at all — it fills
2580
+ * to the edge with whatever fits.
2330
2581
  * ------------------------------------------------------------------------- */
2331
2582
 
2332
2583
  .plass-gallery-grid,
@@ -2334,6 +2585,32 @@
2334
2585
  grid-template-columns: repeat(var(--p-cols, 2), minmax(0, 1fr));
2335
2586
  }
2336
2587
 
2588
+ /*
2589
+ * What holds a justified gallery's last row down.
2590
+ *
2591
+ * Every tile is grown in proportion to its own width, which is what makes a row
2592
+ * come out one height once it has been stretched to the edge. The last row is
2593
+ * the exception: it has fewer tiles and the same width to share, so they stretch
2594
+ * further than any row above them — one leftover photograph ends up filling the
2595
+ * whole width and standing two or three times as tall as the gallery it belongs
2596
+ * to.
2597
+ *
2598
+ * An empty `::after` with an absurd `flex-grow` eats the leftover width instead,
2599
+ * so the real tiles keep their basis and the row lands at the height it was
2600
+ * aiming for. It has to be a pseudo-element rather than a filler item: the list
2601
+ * is a `<ul>` with `role="list"`, and an extra `<li>` would be an extra item in
2602
+ * it — a photograph that is not there, counted by every screen reader that
2603
+ * announces how many there are.
2604
+ *
2605
+ * It costs a row of nothing when the last row happens to be full, which is why
2606
+ * the flex-basis is zero.
2607
+ */
2608
+ .plass-gallery-justified::after {
2609
+ content: '';
2610
+ flex-grow: 1000000;
2611
+ flex-basis: 0;
2612
+ }
2613
+
2337
2614
  /* ---------------------------------------------------------------------------
2338
2615
  * Reduced motion
2339
2616
  *
@@ -2405,6 +2682,27 @@
2405
2682
  animation: none;
2406
2683
  }
2407
2684
 
2685
+ /*
2686
+ * A marquee that stops would leave everything past the edge of its box out
2687
+ * of sight for good. One copy is drawn, and the box scrolls along it instead
2688
+ * of clipping it, so the strip stays one line rather than wrapping down the
2689
+ * page; a platform that draws a permanent scrollbar adds only the bar. The
2690
+ * component makes the box a tab stop while it scrolls.
2691
+ */
2692
+ .plass-marquee {
2693
+ overflow-x: auto;
2694
+ overflow-y: hidden;
2695
+ }
2696
+
2697
+ .plass-marquee-vertical {
2698
+ overflow-x: hidden;
2699
+ overflow-y: auto;
2700
+ }
2701
+
2702
+ .plass-marquee-track + .plass-marquee-track {
2703
+ display: none;
2704
+ }
2705
+
2408
2706
  /* The arc stops travelling and becomes an even glow. The same trade the
2409
2707
  skeleton makes: the decoration survives, the motion does not. */
2410
2708
  .plass-anim-lighting::before {
package/dist/types.d.ts CHANGED
@@ -107,6 +107,21 @@ export type PlassAlignSelf = 'auto' | 'start' | 'center' | 'end' | 'stretch' | '
107
107
  * as a `<div>`.
108
108
  */
109
109
  export type PlassPosition = 'static' | 'sticky' | 'fixed';
110
+ /**
111
+ * What a scroller does with a gesture it has run out of room for, spelled the
112
+ * way CSS spells it.
113
+ *
114
+ * - `contain` — keeps it. The pointer being inside the strip is the reader
115
+ * saying which of the two things under it they meant to move, and that answer
116
+ * does not change the moment the strip reaches its end. A shelf that fits its
117
+ * box is not a scroller and never holds anything back, so what this contains
118
+ * is only a gesture that was moving *something*.
119
+ * - `auto` — hands it back to the page, which is what a nested scroller does
120
+ * left alone. Even here the strip keeps the wheel while the gesture that was
121
+ * scrolling it is still running: a page that jumps out from under a flick is
122
+ * the thing chaining was supposed to be sparing the reader.
123
+ */
124
+ export type PlassOverscroll = 'auto' | 'contain';
110
125
  /**
111
126
  * Which corner of a box something is pinned to. `PlBadge` reads this.
112
127
  *
@@ -116,6 +131,52 @@ export type PlassPosition = 'static' | 'sticky' | 'fixed';
116
131
  * a caller spell `{ vertical: 'left' }`.
117
132
  */
118
133
  export type PlassCorner = 'top-start' | 'top-end' | 'bottom-start' | 'bottom-end';
134
+ /**
135
+ * Where a **field-shaped** control puts the name of what it holds.
136
+ *
137
+ * The placements a box has to offer, which are not the placements a tick has:
138
+ * a PlCheckbox, a PlRadio and a PlSwitch put their label beside themselves and
139
+ * take `labelPlacement` out of `PlassAlign` instead — same question, same prop
140
+ * name, the answers each shape actually has. See `PlSwitchLabelPlacement`.
141
+ *
142
+ * - `top` — above the control, on its own line. The default, and the one that
143
+ * is always safe: the label is a block of text in the layout, it can wrap, it
144
+ * can be as long as it needs to be, and nothing about the control's edge has
145
+ * to make room for it.
146
+ * - `notch` — in the control's own top edge, with the hairline cut away behind
147
+ * it. The label stops being a line of the form and becomes part of the field,
148
+ * which buys back a row of vertical space and ties the name to the box rather
149
+ * than to whatever is above it.
150
+ *
151
+ * The cut is a real one — a `<legend>` in a `<fieldset>`, which is the only way
152
+ * to take a segment out of a border without knowing what is behind it. Nothing
153
+ * here paints over the line with the page's colour, because a library that does
154
+ * not paint the page cannot know what colour that is, and a Plass field is
155
+ * translucent besides.
156
+ *
157
+ * Two things follow from the label sitting on the edge, and both are deliberate:
158
+ *
159
+ * - **Focus is the edge thickening rather than a ring.** An outline is a
160
+ * rectangle and would run straight through the label. The edge that is
161
+ * already there goes to 2px and takes the family's colour instead, which is
162
+ * what the flush ring was drawn to look like anyway.
163
+ * - **The label no longer widens the control.** It is out of the flow, so a
164
+ * label longer than a narrow field runs past its end. Give the field
165
+ * `fullWidth`, or keep the word short — a notch is a place for "Email", not
166
+ * for a sentence.
167
+ *
168
+ * Only `glass` has a hairline to cut. On `solid` and `ghost` the label sits in
169
+ * the same place and there is simply nothing there to take out, so a form that
170
+ * mixes the three keeps one baseline for its labels.
171
+ *
172
+ * **`PlOtpField` is the one labelled field that does not take this**, and the
173
+ * reason is the same one that decides everything above: a notch is a segment
174
+ * taken out of one continuous edge, and a row of separate boxes with gaps
175
+ * between them has no such edge. Cutting only the first box leaves the word
176
+ * lying across the two after it, which is worse than the label above the row
177
+ * that it keeps.
178
+ */
179
+ export type PlassFieldLabelPlacement = 'top' | 'notch';
119
180
  /**
120
181
  * What a surface is made of. This is the library's own name, and the two
121
182
  * materials in it are the whole design language.
@@ -516,9 +577,18 @@ export interface PlassChartSeries {
516
577
  * @default false
517
578
  */
518
579
  hidden?: boolean;
580
+ /**
581
+ * Draws the line dashed — a forecast, a target, a last year.
582
+ *
583
+ * Only a line has a line to dash, so it does nothing on a bar, and nothing on
584
+ * a stacked area either, where the band's fill *is* the mark and there is no
585
+ * stroke along its top.
586
+ * @default false
587
+ */
588
+ dashed?: boolean;
519
589
  }
520
590
  /**
521
- * One span on a [PlTimelineChart] — a stretch of time with two ends.
591
+ * One span on a `PlTimelineChart` — a stretch of time with two ends.
522
592
  *
523
593
  * Its own type rather than a `z2` or an `x2` bolted onto `PlassChartPoint`,
524
594
  * because a second position on the axis is a field the other six charts would
@@ -540,34 +610,6 @@ export interface PlassTimelinePoint {
540
610
  /** Overrides its row's colour for this one span. */
541
611
  color?: PlassColor | (string & {});
542
612
  }
543
- /**
544
- * One row of a PlTimelineChart, and everything on it.
545
- *
546
- * A row is a series — one entity, one name, one colour — but its data are
547
- * spans rather than values, so it cannot be a `PlassChartSeries`. There is no
548
- * `hidden` here and no legend to pair it with: a Gantt's rows *are* its
549
- * category axis, already named down the side, and a twenty-entry legend
550
- * restating them is not a filter anyone wants.
551
- */
552
- export interface PlassTimelineSeries {
553
- /** Its name on the axis, in the tooltip and in the table. */
554
- name?: string;
555
- /** The spans on this row. Overlapping ones are drawn over each other. */
556
- data: readonly PlassTimelinePoint[];
557
- /** Overrides the palette slot this row would otherwise take. */
558
- color?: PlassColor | (string & {});
559
- }
560
- /** One stretch of time on a row of a `PlTimelineChart`. */
561
- export interface PlassTimelinePoint {
562
- /** When it begins. A `Date`, or a number of milliseconds. */
563
- start: PlassChartCategory;
564
- /** And when it is done. A span that ends before it starts is drawn either way round. */
565
- end: PlassChartCategory;
566
- /** What the span is called, in the tooltip and the table. */
567
- label?: React.ReactNode;
568
- /** Overrides its row's colour for this one span. */
569
- color?: PlassColor | (string & {});
570
- }
571
613
  /**
572
614
  * One row of a `PlTimelineChart`, and everything on it.
573
615
  *
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "plass-ui",
3
- "version": "1.4.0",
3
+ "version": "1.6.0",
4
4
  "description": "A React UI component library made of glass and gradients — smooth tinted surfaces, shadows in their own colour, and light that follows the pointer. Accessible and themeable, ESM only, types included, dark mode built in.",
5
5
  "type": "module",
6
6
  "types": "dist/index.d.ts",
7
7
  "sideEffects": [
8
8
  "**/*.css"
9
9
  ],
10
- "author": "CDGet <jooy2.contact@gmail.com>",
10
+ "author": "CDGet (https://cdget.com)",
11
11
  "license": "MIT",
12
12
  "homepage": "https://plass.cdget.com",
13
13
  "repository": {
@@ -128,22 +128,22 @@
128
128
  "devDependencies": {
129
129
  "@eslint/js": "^9.39.1",
130
130
  "@tailwindcss/postcss": "^4.3.3",
131
- "@types/node": "^26.4.0",
131
+ "@types/node": "^26.4.1",
132
132
  "@types/react": "^19.2.18",
133
- "@types/react-dom": "^19.2.5",
134
- "@typescript-eslint/parser": "^8.68.0",
133
+ "@types/react-dom": "^19.2.7",
134
+ "@typescript-eslint/parser": "^8.69.0",
135
135
  "@vitejs/plugin-react": "^6.1.1",
136
- "@vitest/browser": "^4.1.11",
137
- "@vitest/browser-playwright": "^4.1.11",
136
+ "@vitest/browser": "^5.0.0",
137
+ "@vitest/browser-playwright": "^5.0.0",
138
138
  "esbuild": "^0.28.2",
139
139
  "eslint": "^9.39.1",
140
140
  "eslint-config-prettier": "^10.1.8",
141
141
  "eslint-plugin-n": "^18.3.0",
142
142
  "eslint-plugin-react-hooks": "^7.1.1",
143
- "globals": "^17.11.0",
143
+ "globals": "^17.12.0",
144
144
  "jiti": "^2.7.0",
145
- "playwright": "^1.62.1",
146
- "postcss": "^8.5.26",
145
+ "playwright": "^1.63.0",
146
+ "postcss": "^8.5.28",
147
147
  "prettier": "^3.9.6",
148
148
  "prettier-plugin-tailwindcss": "^0.8.1",
149
149
  "react": "^19.2.8",
@@ -151,14 +151,14 @@
151
151
  "tailwindcss": "^4.3.3",
152
152
  "terser": "^5.51.2",
153
153
  "typescript": "^6.0.3",
154
- "typescript-eslint": "^8.68.0",
154
+ "typescript-eslint": "^8.69.0",
155
155
  "vite": "^8.2.2",
156
- "vitest": "^4.1.11",
157
- "vitest-browser-react": "^2.2.0"
156
+ "vitest": "^5.0.0",
157
+ "vitest-browser-react": "^2.3.0"
158
158
  },
159
159
  "dependencies": {
160
- "@base-ui/react": "^1.7.0",
161
- "highlight.js": "^11.11.1"
160
+ "@base-ui/react": "^1.8.0",
161
+ "highlight.js": "^11.12.0"
162
162
  },
163
163
  "peerDependencies": {
164
164
  "@types/react": "^18.0.0 || ^19.0.0",