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
@@ -1,7 +1,71 @@
1
1
  import * as React from 'react';
2
- import type { PlassColor, PlassSize } from '../../types.js';
3
- /** How the picture is fitted to the box. `object-fit`'s own words. */
4
- export type PlImageFit = 'cover' | 'contain' | 'fill' | 'none';
2
+ import type { PlassImageFlip } from '../../internal/image.js';
3
+ import type { PlassColor, PlassSide, PlassSize } from '../../types.js';
4
+ import type { PlassWatermarkOptions, PlassWatermarkPlacement } from '../../internal/watermark.js';
5
+ /** Where a watermark sits on the picture. */
6
+ export type PlImageWatermarkPlacement = PlassWatermarkPlacement;
7
+ /** A mark laid over the picture. A bare string is the text, in the usual corner. */
8
+ export type PlImageWatermark = PlassWatermarkOptions;
9
+ /**
10
+ * How the picture is fitted to the box. `object-fit`'s own words, and the same
11
+ * five `PlAspectRatio` takes: `scale-down` is `contain` that never enlarges a
12
+ * file smaller than the box.
13
+ */
14
+ export type PlImageFit = 'cover' | 'contain' | 'fill' | 'none' | 'scale-down';
15
+ /**
16
+ * How far the picture is turned, clockwise, in degrees.
17
+ *
18
+ * Quarter turns and nothing between them. A picture turned by any other angle
19
+ * no longer covers its own box, and filling the corners that leaves means
20
+ * enlarging it by an amount a caller would then want to tune, which is a photo
21
+ * editor's job rather than a component's.
22
+ */
23
+ export type PlImageRotation = 0 | 90 | 180 | 270;
24
+ /**
25
+ * Which way the picture is mirrored, along the axes it is shown on: `horizontal`
26
+ * swaps left and right on the screen whether or not the picture is turned.
27
+ */
28
+ export type PlImageFlip = PlassImageFlip;
29
+ /**
30
+ * Where the picture sits in its box, spelled the way `object-position` spells
31
+ * it: the centre, a side, a corner, or two percentages across and down.
32
+ *
33
+ * Physical rather than logical, on purpose. The subject of a photograph is on
34
+ * the same side of it in every language, so a crop that keeps it must not move
35
+ * to the other side on a right-to-left page.
36
+ */
37
+ export type PlImagePosition = 'center' | PlassSide | 'top left' | 'top right' | 'bottom left' | 'bottom right' | `${number}% ${number}%`;
38
+ /**
39
+ * What fills the part of the box a picture leaves empty.
40
+ *
41
+ * `blur` is the picture itself, covering the box and blurred behind it, the way
42
+ * a video player fills the sides of a portrait clip. Any other string is a CSS
43
+ * `background`.
44
+ */
45
+ export type PlImageLetterbox = 'none' | 'blur';
46
+ /**
47
+ * A picture to stand in while the file arrives, in place of the skeleton.
48
+ *
49
+ * It is drawn the way the picture will be, with the same `fit`, `position`,
50
+ * `rotate`, `flip` and `filter`, which is what it is for: a small copy of the
51
+ * same file, a few hundred bytes as a data URI or already in memory as a
52
+ * `Blob`, so the reader sees the picture's colours and shape before its detail.
53
+ */
54
+ export interface PlImagePlaceholder {
55
+ /**
56
+ * The stand-in: a URL, a data URI or a `Blob`. A `Blob` is given an object URL
57
+ * for as long as it is shown, and the URL is released when it is not.
58
+ */
59
+ src: string | Blob;
60
+ /**
61
+ * Blurs the stand-in, by this many pixels or by 20 for `true`. A copy
62
+ * stretched up from a few pixels is blocky without it.
63
+ * @default false
64
+ */
65
+ blur?: boolean | number;
66
+ }
67
+ /** The treatments that have a name. Anything else is written as CSS. */
68
+ export type PlImageFilter = 'none' | 'grayscale' | 'sepia' | 'saturate' | 'desaturate' | 'contrast' | 'dim';
5
69
  export interface PlImageProps extends Omit<React.ComponentPropsWithoutRef<'img'>, 'color' | 'onError' | 'onLoad'> {
6
70
  /**
7
71
  * The description a screen reader reads. **Required**, and `""` is a real
@@ -19,8 +83,85 @@ export interface PlImageProps extends Omit<React.ComponentPropsWithoutRef<'img'>
19
83
  * down the screen.
20
84
  */
21
85
  ratio?: number | string;
22
- /** @default 'cover' */
86
+ /**
87
+ * The file's own pixel dimensions, as an `<img>` takes them, or, given one at
88
+ * a time, the size of the box.
89
+ *
90
+ * Together they describe the file, and the box keeps their proportion before
91
+ * the file arrives, which is what they have always done on an `<img>`.
92
+ *
93
+ * One on its own is not a proportion, so it is read as the length it looks
94
+ * like. `height={200}` is a box 200 pixels tall across the width it is given,
95
+ * and `width={320}` is one 320 wide, never wider than its container, and as
96
+ * tall as the picture makes it. A number or a string of digits is pixels, and
97
+ * any other string is a CSS length. With a `ratio` as well, a lone `height`
98
+ * takes its width from the ratio. `fit` decides what the picture does inside.
99
+ *
100
+ * They reach the `<img>` either way.
101
+ */
102
+ width?: number | string;
103
+ height?: number | string;
104
+ /**
105
+ * How the picture fills its box.
106
+ * @default 'cover'
107
+ */
23
108
  fit?: PlImageFit;
109
+ /**
110
+ * Where the picture sits in its box: which part of it a `cover` crop keeps,
111
+ * and where `contain`, `none` and `scale-down` leave their empty space.
112
+ *
113
+ * Read on the picture as it is shown, so it holds through `rotate` and
114
+ * `flip`: `position="top"` keeps the top of what the reader sees rather than
115
+ * the top of the file. Anything else `object-position` accepts is passed
116
+ * through as written, without that conversion.
117
+ * @default 'center'
118
+ */
119
+ position?: PlImagePosition | (string & {});
120
+ /**
121
+ * What fills the box where `contain`, `none` or `scale-down` leave it empty:
122
+ * `blur` for the picture itself, blurred and covering the box behind it, or
123
+ * any CSS `background` — a colour, a token, a gradient.
124
+ *
125
+ * The blurred copy loads from exactly what the picture loads from, so it is
126
+ * the same request rather than a second one, and it is drawn only under a
127
+ * `fit` that can leave space. It is hidden from the accessibility tree and
128
+ * takes no pointer.
129
+ * @default 'none'
130
+ */
131
+ letterbox?: PlImageLetterbox | (string & {});
132
+ /**
133
+ * Turns the picture clockwise, a quarter at a time.
134
+ *
135
+ * A picture on its side is laid out on its side. `width` and `height` still
136
+ * describe the file, so `width={1200} height={800} rotate={90}` reserves a box
137
+ * two wide by three tall, and a picture with neither takes the turned shape
138
+ * once the file has said what it is. A `ratio` is the layout's and is kept,
139
+ * with `fit` deciding how the turned picture fills it.
140
+ *
141
+ * Drawn with CSS's own `rotate` property rather than a `transform`, which
142
+ * stays free for a hover effect or a class of your own.
143
+ * @default 0
144
+ */
145
+ rotate?: PlImageRotation;
146
+ /**
147
+ * Mirrors the picture, along the axes it is shown on.
148
+ *
149
+ * `horizontal` swaps left and right on the screen and `vertical` swaps top
150
+ * and bottom, whichever way `rotate` has turned the picture. Drawn with CSS's
151
+ * own `scale` property, so `transform` stays free.
152
+ * @default 'none'
153
+ */
154
+ flip?: PlImageFlip;
155
+ /**
156
+ * A treatment laid over the picture: one of the named ones, or any CSS
157
+ * `filter` chain of your own — `'blur(2px) hue-rotate(20deg)'` is as valid a
158
+ * value as `'sepia'`.
159
+ *
160
+ * It rides the same transition as the picture's own fade, so a caller who
161
+ * swaps the filter on hover gets a change that travels rather than one that
162
+ * snaps.
163
+ */
164
+ filter?: PlImageFilter | (string & {});
24
165
  /** Rounds the corners to the `size` step of the house ladder. @default false */
25
166
  rounded?: boolean;
26
167
  /** Which step of the radius ladder `rounded` uses. @default 'md' */
@@ -28,10 +169,16 @@ export interface PlImageProps extends Omit<React.ComponentPropsWithoutRef<'img'>
28
169
  /** The family the skeleton and the focus ring take. @default 'primary' */
29
170
  color?: PlassColor;
30
171
  /**
31
- * What is drawn while the picture is loading. A `PlSkeleton` by default;
32
- * `null` draws nothing and leaves the reserved box empty.
172
+ * What is drawn while the picture is loading. A `PlSkeleton` by default, a
173
+ * node of your own, `{ src }` for a picture to stand in, or `null` for nothing
174
+ * at all.
175
+ *
176
+ * A picture stand-in is a small copy of the same file, as a URL or a `Blob`.
177
+ * It is drawn under the picture and stays until the picture has finished
178
+ * fading in over it. Like the skeleton it fills the box, so it needs a box to
179
+ * fill: a `ratio`, or both `width` and `height`.
33
180
  */
34
- placeholder?: React.ReactNode;
181
+ placeholder?: React.ReactNode | PlImagePlaceholder;
35
182
  /**
36
183
  * What is drawn when the picture does not arrive — a wrong URL, a dead host,
37
184
  * a file that is not an image.
@@ -40,6 +187,30 @@ export interface PlImageProps extends Omit<React.ComponentPropsWithoutRef<'img'>
40
187
  * that is certainly available and certainly describes what is missing.
41
188
  */
42
189
  fallback?: React.ReactNode;
190
+ /**
191
+ * A mark laid over the picture — a bare string for one in the bottom corner,
192
+ * or an object to say where it goes, how visible it is, and at what angle.
193
+ *
194
+ * `placement: 'tile'` covers the whole picture instead, which is the one a
195
+ * proof or a preview wants: a mark in a corner is cropped off in a second.
196
+ *
197
+ * It is drawn only once the picture has arrived, and it is `aria-hidden` and
198
+ * takes no pointer. A watermark is a claim about the file, not something the
199
+ * page is telling a reader — `alt` is where a picture says what it is.
200
+ */
201
+ watermark?: string | PlImageWatermark;
202
+ /**
203
+ * Makes the picture awkward to take: no context menu, no drag out of the
204
+ * page, no text selection over it, and no long-press callout on iOS.
205
+ *
206
+ * **It is a deterrent and not a lock.** The file is still one request away —
207
+ * it is in the network tab, it is in the cache, and a screenshot needs none of
208
+ * that. What this stops is the casual right-click-and-save, which for most
209
+ * pictures is the whole of what was wanted. Anything that genuinely must not
210
+ * be copied does not belong on the page.
211
+ * @default false
212
+ */
213
+ protect?: boolean;
43
214
  /**
44
215
  * Opens the picture over the page when it is pressed.
45
216
  *
@@ -48,8 +219,24 @@ export interface PlImageProps extends Omit<React.ComponentPropsWithoutRef<'img'>
48
219
  * @default false
49
220
  */
50
221
  preview?: boolean;
51
- /** The accessible name of the preview overlay. @default 'Preview' */
222
+ /**
223
+ * The accessible name of the preview overlay. It also names the button that
224
+ * opens it: after `alt` and in lower case, "A portrait — preview", or on its
225
+ * own when `alt` is empty.
226
+ * @default 'Preview'
227
+ */
52
228
  previewLabel?: string;
229
+ /**
230
+ * Marks the picture a page is judged by — usually the largest thing above the
231
+ * fold, which is what Largest Contentful Paint measures — so it is fetched
232
+ * early rather than lazily: `loading="eager"` and a high fetch priority.
233
+ *
234
+ * Everything else about when a picture loads belongs to the `<img>` and
235
+ * passes straight through: `loading`, `decoding`, `fetchPriority`. An
236
+ * attribute written out wins over what this implies.
237
+ * @default false
238
+ */
239
+ priority?: boolean;
53
240
  /** Called when the picture has loaded, and when it has failed. */
54
241
  onStatusChange?: (status: PlImageStatus) => void;
55
242
  }
@@ -1 +1 @@
1
- "use client";import{jsx as e,Fragment as o,jsxs as a}from"react/jsx-runtime";import*as l from"react";import{useDefaults as s}from"../../internal/defaults.js";import{useLabels as t}from"../../internal/labels.js";import{PlOverlay as r}from"../overlay/PlOverlay.js";import{PlSkeleton as n}from"../skeleton/PlSkeleton.js";import{cx as i,focusRingClasses as c,radiusClasses as m,transitionClasses as d}from"../../internal/styles.js";const p={cover:"object-cover",contain:"object-contain",fill:"object-fill",none:"object-none"};export const PlImage=/* @__PURE__ */l.forwardRef(function PlImage({alt:f,src:u,ratio:b,fit:h="cover",rounded:g=!1,size:j,color:v,placeholder:y,fallback:x,preview:w=!1,previewLabel:N,onStatusChange:k,className:z,style:C,loading:P="lazy",...S},L){const E=s(),I=t(),O=N??I.preview,R=j??E.size??"md",$=v??E.color??"primary",[F,q]=l.useState("loading"),[A,B]=l.useState(!1);l.useEffect(()=>{q("loading")},[u]);const settle=e=>{q(e),k?.(e)},D=g?m[R]:"",G=e("img",{ref:L,src:u,alt:f,loading:P,onLoad:()=>settle("loaded"),onError:()=>settle("error"),className:i("block size-full",p[h],d,"loaded"===F?"opacity-100":"opacity-0","error"===F?"hidden":""),...S}),H=a(o,{children:[G,"loading"===F?e("span",{className:"absolute inset-0",children:void 0===y?e(n,{shape:"rect",color:$,size:R,width:"100%",height:"100%",className:D}):y}):null,"error"===F?e("span",{className:"absolute inset-0 flex items-center justify-center bg-(--plass-glass-press) p-3 text-center text-[0.8125rem] text-(--plass-muted-fg)",children:x??f}):null]}),J=i("relative block overflow-hidden",D,z),K={aspectRatio:b,...C};return w?a(o,{children:[e("button",{type:"button","aria-label":f?`${f} — ${O.toLowerCase()}`:O,onClick:()=>B(!0),disabled:"loaded"!==F,className:i(J,"cursor-zoom-in p-0",c),style:K,children:H}),e(r,{open:A,onOpenChange:B,tone:"glass",dismissible:!0,color:$,label:O,children:e("img",{src:u,alt:f,className:"max-h-[85vh] max-w-[90vw] object-contain"})})]}):e("span",{className:J,style:K,children:H})});
1
+ "use client";import{jsx as e,Fragment as t,jsxs as r}from"react/jsx-runtime";import*as l from"react";import{useDefaults as n}from"../../internal/defaults.js";import{useLabels as o}from"../../internal/labels.js";import{PlSkeleton as i}from"../skeleton/PlSkeleton.js";import{PlassWatermark as a}from"../../internal/watermark.js";import{isSideways as s,layerStyle as u,objectPosition as c,poseStyle as d,quartersOf as f}from"../../internal/image.js";import{cx as p,focusRingClasses as h,radiusClasses as b,transitionClasses as m}from"../../internal/styles.js";function boxLength(e){return"number"==typeof e||/^\d+(\.\d+)?$/.test(e.trim())?`${Number(e)}px`:e}const g=Number.parseInt(l.version,10)>=19?"fetchPriority":"fetchpriority",v={none:"none",grayscale:"grayscale(1)",sepia:"sepia(0.72)",saturate:"saturate(1.35)",desaturate:"saturate(0.45)",contrast:"contrast(1.2)",dim:"brightness(0.82)"},y={draggable:!1,onDragStart:e=>e.preventDefault(),onContextMenu:e=>e.preventDefault()},w={cover:"object-cover",contain:"object-contain",fill:"object-fill",none:"object-none","scale-down":"object-scale-down"},j=/* @__PURE__ */l.lazy(()=>import("./PlImagePreview.js").then(e=>({default:e.PlImagePreview})));export const PlImage=/* @__PURE__ */l.forwardRef(function PlImage({alt:x,src:k,ratio:P,fit:S="cover",position:N,letterbox:z="none",rotate:L=0,flip:R="none",filter:$,watermark:C,protect:I=!1,rounded:W=!1,size:O,color:U,placeholder:E,fallback:D,preview:B=!1,previewLabel:T,onStatusChange:q,className:A,style:F,loading:H,priority:M=!1,width:V,height:G,...J},K){const Q=n(),X=o(),Y=T??X.preview,Z=O??Q.size??"md",_=U??Q.color??"primary",[ee,te]=l.useState({status:"loading",natural:null}),re=ee.status,[le,ne]=l.useState(!1),oe=H??(M?"eager":"lazy"),ie=J.fetchPriority??(M?"high":void 0),ae=void 0===ie?null:{[g]:ie},se=function isPicturePlaceholder(e){return"object"==typeof e&&null!==e&&!l.isValidElement(e)&&"src"in e}(E)?E:null,ue=function useStandInUrl(e){const[t,r]=l.useState(null);return l.useEffect(()=>{if("undefined"==typeof Blob||!(e instanceof Blob))return;const t=URL.createObjectURL(e);return r({blob:e,url:t}),()=>URL.revokeObjectURL(t)},[e]),"string"==typeof e?e:null!==t&&t.blob===e?t.url:void 0}(se?.src),ce=l.useRef(null),de=l.useCallback(e=>{ce.current=e,"function"==typeof K?K(e):K&&(K.current=e)},[K]),fe=l.useRef("loading"),pe=l.useRef(k),he=l.useRef(null),settle=(e,t)=>{const r="loaded"===e?function naturalSize(e){return null!==e&&e.naturalWidth>0?{width:e.naturalWidth,height:e.naturalHeight}:null}(t):null;te(t=>t.status===e&&t.natural?.width===r?.width&&t.natural?.height===r?.height?t:{status:e,natural:r}),fe.current!==e&&(fe.current=e,q?.(e))};l.useLayoutEffect(()=>{const e=ce.current;if(null!==e){if(pe.current!==k&&(pe.current=k,fe.current="loading"),e.getAttribute("src")&&e.complete)return e.naturalWidth>0&&(he.current={src:k,file:e.currentSrc}),void settle(e.naturalWidth>0?"loaded":"error",e);te(e=>"loading"===e.status?e:{status:"loading",natural:null})}},[k]);const be=W?b[Z]:"",me=void 0===$?void 0:v[$]??$,ge=f(L),ve=s(ge),ye=d(ge,R),we=void 0===N?void 0:c(N,ge,R),je=void 0===me&&null===ye&&void 0===we?void 0:{...void 0===me?null:{"--p-filter":me},objectPosition:we,...ye},xe="blur"===z&&"cover"!==S&&"fill"!==S,ke="none"===z||"blur"===z?void 0:z,Pe=void 0===me||"none"===me?"":`${me} `,Se=xe&&"error"!==re?e("img",{src:k,srcSet:J.srcSet,sizes:J.sizes,loading:oe,decoding:J.decoding,crossOrigin:J.crossOrigin,referrerPolicy:J.referrerPolicy,...ae,alt:"","aria-hidden":"true",draggable:!1,className:p("pointer-events-none block object-cover select-none",m,"loaded"===re?"opacity-100":"opacity-0"),style:{...u(ge,R,48),objectPosition:we,filter:`${Pe}blur(24px)`}}):null,Ne=null!==se&&se.blur?!0===se.blur?20:se.blur:0,ze=null===se||void 0===ue||"error"===re?null:e("img",{src:ue,alt:"","aria-hidden":"true",draggable:!1,className:p("pointer-events-none block select-none",w[S]),style:{...u(ge,R,2*Ne),objectPosition:we,filter:""===Pe&&0===Ne?void 0:`${Pe}blur(${Ne}px)`,..."loaded"===re?{opacity:0,transition:"opacity 0ms linear var(--plass-duration)"}:null}}),Le=e("img",{ref:de,src:k,alt:x,loading:oe,width:V,height:G,onLoad:e=>{const t=e.currentTarget,r=he.current;he.current=null,null!==r&&r.src!==k&&r.file===t.currentSrc||settle("loaded",t)},onError:()=>settle("error",null),style:je,className:p("block size-full",w[S],void 0===me?"":"[filter:var(--p-filter,none)]",m,xe||null!==ze?"relative":"","loaded"===re?"opacity-100":"opacity-0","error"===re?"hidden":"",I?"select-none [-webkit-touch-callout:none]":""),...ae,...J,...I?y:null}),Re=r(t,{children:[Se,ze,Le,"loading"===re&&null===se?e("span",{className:"absolute inset-0",children:void 0===E?e(i,{shape:"rect",color:_,size:Z,width:"100%",height:"100%",className:be}):E}):null,"error"===re?e("span",{className:"absolute inset-0 flex items-center justify-center bg-(--plass-glass-press) p-3 text-center text-[0.8125rem] text-(--plass-muted-fg)",children:D??x}):null,void 0!==C&&"loaded"===re?e(a,{watermark:C}):null]}),$e=function pixelSize(e,t){const r=Number(e),l=Number(t);return void 0!==e&&void 0!==t&&r>0&&l>0?{width:r,height:l}:null}(V,G)??ee.natural,Ce=void 0===G&&void 0!==V?boxLength(V):void 0,Ie=void 0===V&&void 0!==G?boxLength(G):void 0,We=void 0===P&&ve&&null!==$e&&void 0===Ie?`${$e.height} / ${$e.width}`:P,Oe=p("relative block overflow-hidden",be,A),Ue={...void 0===Ce?null:{width:Ce,maxWidth:"100%"},...void 0===Ie?null:{height:Ie,...void 0===P?null:{width:"auto",maxWidth:"100%"}},aspectRatio:We,background:ke,containerType:ve?"size":void 0,...F};return B?r(t,{children:[e("button",{type:"button","aria-label":x?`${x} — ${Y.toLowerCase()}`:Y,onClick:()=>ne(!0),disabled:"loaded"!==re,className:p(Oe,"w-full cursor-zoom-in p-0",h),style:Ue,children:Re}),e(l.Suspense,{fallback:null,children:e(j,{open:le,onOpenChange:ne,src:k,alt:x,label:Y,color:_,protect:I,watermark:C,quarters:ge,flip:R,file:$e})})]}):e("span",{className:Oe,style:Ue,children:Re})});
@@ -0,0 +1,58 @@
1
+ import * as React from 'react';
2
+ import type { PlassImageFlip, PlassQuarters } from '../../internal/image.js';
3
+ import type { PlassWatermarkOptions } from '../../internal/watermark.js';
4
+ import type { PlassColor } from '../../types.js';
5
+ export interface PlImagePreviewProps {
6
+ /** Whether the picture is open over the page. */
7
+ open: boolean;
8
+ onOpenChange: (open: boolean) => void;
9
+ /** The file to show, at whatever size it really is. */
10
+ src?: string;
11
+ /** The picture's description, carried over from the thumbnail. */
12
+ alt: string;
13
+ /** The accessible name of the overlay itself. */
14
+ label: string;
15
+ /** The family the overlay takes. */
16
+ color: PlassColor;
17
+ /**
18
+ * Carried in from the thumbnail. A mark or a refusal that comes off the
19
+ * moment the picture is opened large is not a mark or a refusal — and large
20
+ * is the copy somebody wanted in the first place.
21
+ */
22
+ protect?: boolean;
23
+ /**
24
+ * Carried in from the thumbnail, for the same reason `protect` is: a mark that
25
+ * comes off the moment the picture is opened large has marked the copy nobody
26
+ * wanted.
27
+ */
28
+ watermark?: string | PlassWatermarkOptions;
29
+ /**
30
+ * How many quarters the thumbnail is turned, carried in so the picture opens
31
+ * the way it was shown.
32
+ */
33
+ quarters?: PlassQuarters;
34
+ /** The thumbnail's mirror, carried in for the same reason as its turn. */
35
+ flip?: PlassImageFlip;
36
+ /**
37
+ * The file's own pixel size, where the thumbnail knows it. A picture on its
38
+ * side is opened in a box of the turned shape, and this is that shape.
39
+ */
40
+ file?: {
41
+ width: number;
42
+ height: number;
43
+ } | null;
44
+ }
45
+ /**
46
+ * A `PlImage` opened over the page.
47
+ *
48
+ * It is a separate module because it is a separate download. This is a whole
49
+ * overlay and the chrome around it — several times the weight of the picture
50
+ * component that opens it — and `preview` is off by default, so a page drawing
51
+ * a wall of thumbnails would otherwise be paying for a lightbox it never shows.
52
+ * Reached through `React.lazy`, the chunk arrives after the first paint on the
53
+ * pages that ask for one and is never fetched by the pages that do not.
54
+ *
55
+ * The same bargain `PlGallery` makes with `PlGalleryViewer`, for the same
56
+ * reason.
57
+ */
58
+ export declare function PlImagePreview({ open, onOpenChange, src, alt, label, color, protect, watermark, quarters, flip, file }: PlImagePreviewProps): React.JSX.Element;
@@ -0,0 +1 @@
1
+ "use client";import{jsx as e,jsxs as t}from"react/jsx-runtime";import{PlOverlay as n}from"../overlay/PlOverlay.js";import{cx as o}from"../../internal/styles.js";import{isSideways as r,poseStyle as a}from"../../internal/image.js";import{PlassWatermark as i}from"../../internal/watermark.js";const l="85vh",s="90vw";function turnedBox(e){return null===e?{aspectRatio:"1",width:`min(${s}, ${l})`,containerType:"size"}:{aspectRatio:`${e.height} / ${e.width}`,width:`min(${s}, ${e.height}px, calc(${l} * ${e.height/e.width}))`,containerType:"size"}}export function PlImagePreview({open:l,onOpenChange:s,src:c,alt:m,label:p,color:h,protect:u=!1,watermark:d,quarters:v=0,flip:g="none",file:w=null}){const f=r(v);return e(n,{open:l,onOpenChange:s,tone:"glass",dismissible:!0,color:h,label:p,children:t("span",{className:"relative block",style:f?turnedBox(w):void 0,children:[e("img",{src:c,alt:m,className:o("block object-contain",f?"":"max-h-[85vh] max-w-[90vw]",u?"select-none [-webkit-touch-callout:none]":""),style:a(v,g)??void 0,draggable:!u&&void 0,onDragStart:u?e=>e.preventDefault():void 0,onContextMenu:u?e=>e.preventDefault():void 0}),void 0===d?null:e(i,{watermark:d})]})})}
@@ -1,2 +1,2 @@
1
1
  export { PlImage } from './PlImage.js';
2
- export type { PlImageFit, PlImageProps, PlImageStatus } from './PlImage.js';
2
+ export type { PlImageFit, PlImageFlip, PlImageLetterbox, PlImagePlaceholder, PlImagePosition, PlImageProps, PlImageRotation, PlImageStatus } from './PlImage.js';
@@ -1 +1 @@
1
- "use client";import{jsx as e,jsxs as s,Fragment as l}from"react/jsx-runtime";import*as r from"react";import{useDefaults as t}from"../../internal/defaults.js";import{useRender as a}from"@base-ui/react/use-render";import{focusRingClasses as i,gapClasses as n,glassClasses as o,hasContent as d,iconClasses as c,metaTextClasses as p,paddingXClasses as m,radiusClasses as f,sheetBodyClasses as x,surfaceSlots as u,transitionClasses as h}from"../../internal/styles.js";const g=/* @__PURE__ */r.createContext({size:"md",density:"default",dividers:!1}),v={solid:/* @__PURE__ */[o,"text-(--plass-fg) bg-(--plass-glass-press)","[box-shadow:var(--p-elev),var(--plass-gloss-glass)]"].join(" "),glass:/* @__PURE__ */[o,"border text-(--plass-fg) bg-(--plass-glass)","[border-color:var(--plass-glass-line)]","[box-shadow:var(--p-elev),var(--plass-gloss-glass)]"].join(" "),ghost:"text-(--plass-fg) bg-transparent"},y={default:{xs:"py-1",sm:"py-1.5",md:"py-2",lg:"py-2.5",xl:"py-3"},compact:{xs:"py-0.5",sm:"py-0.5",md:"py-1",lg:"py-1.5",xl:"py-2"}},b=m,N={xs:f.xs,sm:f.xs,md:f.sm,lg:f.sm,xl:f.md};export const PlList=/* @__PURE__ */r.forwardRef(function PlList({variant:s="glass",size:l,color:i,density:n,elevation:o=0,dividers:d=!1,render:c,className:p,style:m,children:x,...y},b){const N=t(),j=l??N.size??"md",w=i??N.color??"primary",k=n??N.density??"default",z=r.useMemo(()=>({size:j,density:k,dividers:d}),[j,k,d]),C=["flex flex-col",f[j],v[s],h,d?"overflow-hidden [&>li+li]:border-t [&>li+li]:[border-color:var(--plass-divider)]":"p-1",p??""].filter(Boolean).join(" "),P=a({render:c,ref:b,props:{role:"list",className:C,style:{...u(w,o),...m},children:x,...y}});return e(g.Provider,{value:z,children:P})});export const PlListItem=/* @__PURE__ */r.forwardRef(function PlListItem({startIcon:t,endIcon:a,description:o,action:m,href:f,selected:u=!1,disabled:v=!1,className:j,children:w,onClick:k,...z},C){const{size:P,density:B,dividers:I}=r.useContext(g),L=Boolean(k||f)&&!v,$=b[B][P],R=["flex min-w-0 flex-1 items-center text-start",$,y[B][P],n[P],x[P],h,c,I?"":N[P],v?"cursor-not-allowed opacity-50 saturate-[0.35]":u?"bg-(--p-soft-press) font-medium text-(--p-accent)":"",L?`cursor-pointer ${i}`:"",L&&!u?"hover:bg-(--p-soft)":"",L&&u?"hover:bg-(--p-soft-press)":""].filter(Boolean).join(" "),F=s(l,{children:[d(t)?e("span",{className:"flex h-[1lh] shrink-0 items-center text-(--plass-muted-fg)",children:t}):null,s("span",{className:"flex min-w-0 flex-1 flex-col",children:[d(w)?e("span",{className:"truncate",children:w}):null,d(o)?e("span",{className:`truncate text-(--plass-muted-fg) ${p[P]}`,children:o}):null]}),d(a)?e("span",{className:"flex h-[1lh] shrink-0 items-center text-(--plass-muted-fg)",children:a}):null]});return s("li",{ref:C,className:["flex w-full items-center",j??""].filter(Boolean).join(" "),...z,children:[L&&f?e("a",{href:f,className:R,"aria-current":u?"page":void 0,onClick:k,children:F}):L?e("button",{type:"button",className:R,"aria-current":!!u||void 0,onClick:k,children:F}):e("div",{className:R,"aria-disabled":v||void 0,children:F}),d(m)?e("div",{className:`flex shrink-0 items-center ${$}`,children:m}):null]})});
1
+ "use client";import{jsx as e,jsxs as s,Fragment as l}from"react/jsx-runtime";import*as r from"react";import{useDefaults as t}from"../../internal/defaults.js";import{useRender as a}from"@base-ui/react/use-render";import{focusRingClasses as i,gapClasses as n,glassClasses as o,hasContent as d,iconClasses as c,metaTextClasses as p,paddingXClasses as m,radiusClasses as f,sheetBodyClasses as x,surfaceSlots as u,transitionClasses as h}from"../../internal/styles.js";const g=/* @__PURE__ */r.createContext({size:"md",density:"default",dividers:!1}),v={solid:/* @__PURE__ */[o,"text-(--plass-fg) bg-(--plass-glass-press)","[box-shadow:var(--p-elev),var(--plass-gloss-glass)]"].join(" "),glass:/* @__PURE__ */[o,"border text-(--plass-fg) bg-(--plass-glass)","[border-color:var(--plass-glass-line)]","[box-shadow:var(--p-elev),var(--plass-gloss-glass)]"].join(" "),ghost:"text-(--plass-fg) bg-transparent"},y={default:{xs:"py-1",sm:"py-1.5",md:"py-2",lg:"py-2.5",xl:"py-3"},compact:{xs:"py-0.5",sm:"py-0.5",md:"py-1",lg:"py-1.5",xl:"py-2"}},b=m,N={xs:f.xs,sm:f.xs,md:f.sm,lg:f.sm,xl:f.md};export const PlList=/* @__PURE__ */r.forwardRef(function PlList({variant:s="glass",size:l,color:i,density:n,elevation:o=0,dividers:d=!1,render:c,className:p,style:m,children:x,...y},b){const N=t(),j=l??N.size??"md",w=i??N.color??"primary",k=n??N.density??"default",z=r.useMemo(()=>({size:j,density:k,dividers:d}),[j,k,d]),C=["m-0 flex list-none flex-col",f[j],v[s],h,d?"overflow-hidden p-0 [&>li+li]:border-t [&>li+li]:[border-color:var(--plass-divider)]":"p-1",p??""].filter(Boolean).join(" "),P=a({render:c,ref:b,props:{role:"list",className:C,style:{...u(w,o),...m},children:x,...y}});return e(g.Provider,{value:z,children:P})});export const PlListItem=/* @__PURE__ */r.forwardRef(function PlListItem({startIcon:t,endIcon:a,description:o,action:m,href:f,selected:u=!1,disabled:v=!1,className:j,children:w,onClick:k,...z},C){const{size:P,density:B,dividers:I}=r.useContext(g),L=Boolean(k||f)&&!v,$=b[B][P],R=["flex min-w-0 flex-1 items-center text-start",$,y[B][P],n[P],x[P],h,c,I?"":N[P],v?"cursor-not-allowed opacity-50 saturate-[0.35]":u?"bg-(--p-soft-press) font-medium text-(--p-accent)":"",L?`cursor-pointer ${i}`:"",L&&!u?"hover:bg-(--p-soft)":"",L&&u?"hover:bg-(--p-soft-press)":""].filter(Boolean).join(" "),F=s(l,{children:[d(t)?e("span",{className:"flex h-[1lh] shrink-0 items-center text-(--plass-muted-fg)",children:t}):null,s("span",{className:"flex min-w-0 flex-1 flex-col",children:[d(w)?e("span",{className:"truncate",children:w}):null,d(o)?e("span",{className:`truncate text-(--plass-muted-fg) ${p[P]}`,children:o}):null]}),d(a)?e("span",{className:"flex h-[1lh] shrink-0 items-center text-(--plass-muted-fg)",children:a}):null]});return s("li",{ref:C,className:["flex w-full items-center",j??""].filter(Boolean).join(" "),...z,children:[L&&f?e("a",{href:f,className:R,"aria-current":u?"page":void 0,onClick:k,children:F}):L?e("button",{type:"button",className:R,"aria-current":!!u||void 0,onClick:k,children:F}):e("div",{className:R,"aria-disabled":v||void 0,children:F}),d(m)?e("div",{className:`flex shrink-0 items-center ${$}`,children:m}):null]})});
@@ -65,8 +65,14 @@ export interface PlMenuItemProps {
65
65
  onClick?: (event: React.MouseEvent<HTMLElement>) => void;
66
66
  /** Renders the row as a real `<a>`. A menu of links has to be links. */
67
67
  href?: string;
68
- /** Where the link opens — `_blank` and the rest. Ignored without `href`. */
68
+ /**
69
+ * Where the link opens — `_blank` and the rest. Ignored without `href`.
70
+ * Anything other than this tab also gets `noopener noreferrer` merged into
71
+ * its `rel`.
72
+ */
69
73
  target?: string;
74
+ /** The link's `rel`. Ignored without `href`. */
75
+ rel?: string;
70
76
  /** Content before the label — an icon, a swatch, a check. */
71
77
  startIcon?: React.ReactNode;
72
78
  /** Content after the label, before any `shortcut`. */
@@ -99,7 +105,10 @@ export interface PlMenuSubmenuProps {
99
105
  label?: React.ReactNode;
100
106
  startIcon?: React.ReactNode;
101
107
  disabled?: boolean;
102
- /** Which edge of the parent row it opens against. @default 'right' */
108
+ /**
109
+ * Which edge of the parent row it opens against. Left out, the end of the line:
110
+ * the right, or the left under RTL.
111
+ */
103
112
  side?: PlassSide;
104
113
  /** Distance from the parent menu, in pixels. @default 4 */
105
114
  sideOffset?: number;
@@ -115,7 +124,7 @@ export interface PlMenuGroupProps {
115
124
  className?: string;
116
125
  style?: React.CSSProperties;
117
126
  }
118
- export interface PlMenuCheckboxItemProps extends Omit<PlMenuItemProps, 'href' | 'target' | 'startIcon' | 'onClick'> {
127
+ export interface PlMenuCheckboxItemProps extends Omit<PlMenuItemProps, 'href' | 'target' | 'rel' | 'startIcon' | 'onClick'> {
119
128
  checked?: boolean;
120
129
  defaultChecked?: boolean;
121
130
  onCheckedChange?: (checked: boolean) => void;
@@ -136,7 +145,7 @@ export interface PlMenuRadioGroupProps {
136
145
  className?: string;
137
146
  style?: React.CSSProperties;
138
147
  }
139
- export interface PlMenuRadioItemProps extends Omit<PlMenuItemProps, 'href' | 'target' | 'startIcon' | 'onClick'> {
148
+ export interface PlMenuRadioItemProps extends Omit<PlMenuItemProps, 'href' | 'target' | 'rel' | 'startIcon' | 'onClick'> {
140
149
  /** What this row sets the group to. */
141
150
  value: string | number;
142
151
  /** @default false */
@@ -151,7 +160,7 @@ export type PlMenuSeparatorProps = React.ComponentPropsWithoutRef<'div'>;
151
160
  * links that are not links cannot be opened in a new tab, cannot be copied, and
152
161
  * tells a screen reader the wrong thing about every one of them.
153
162
  */
154
- export declare function PlMenuItem({ onClick, href, target, startIcon, endIcon, shortcut, description, color, closeOnClick, disabled, label, children, className, style }: PlMenuItemProps): React.JSX.Element;
163
+ export declare function PlMenuItem({ onClick, href, target, rel, startIcon, endIcon, shortcut, description, color, closeOnClick, disabled, label, children, className, style }: PlMenuItemProps): React.JSX.Element;
155
164
  /** A row that ticks. The tick lands in the same slot a `startIcon` would. */
156
165
  export declare function PlMenuCheckboxItem({ checked, defaultChecked, onCheckedChange, endIcon, shortcut, description, color, closeOnClick, disabled, label, children, className, style }: PlMenuCheckboxItemProps): React.JSX.Element;
157
166
  /** One choice out of a set. Wraps the rows that make up the set. */
@@ -1 +1 @@
1
- "use client";import{jsx as e,jsxs as s,Fragment as l}from"react/jsx-runtime";import*as n from"react";import{useDefaults as a}from"../../internal/defaults.js";import{Menu as t}from"@base-ui/react/menu";import{ContextMenu as o}from"@base-ui/react/context-menu";import{MenuContext as r}from"../../internal/menu.js";import{CheckIcon as i,ChevronIcon as c,DotIcon as d}from"../../internal/icons.js";import{controlTextLeadingClasses as p,cx as u,gapClasses as m,glassClasses as h,hasContent as x,iconClasses as f,metaTextClasses as y,radiusClasses as g,surfaceSlots as b,transitionClasses as C}from"../../internal/styles.js";const N=/* @__PURE__ */[h,"max-h-[min(24rem,var(--available-height))] min-w-40 overflow-y-auto overscroll-contain","border bg-(--plass-glass-press) p-1","[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)]","data-[starting-style]:opacity-0 data-[ending-style]:opacity-0"].join(" "),v={default:{xs:"px-1.5 py-0.5",sm:"px-2 py-1",md:"px-2.5 py-1.5",lg:"px-3 py-2",xl:"px-3.5 py-2.5"},compact:{xs:"px-1 py-0.5",sm:"px-1.5 py-0.5",md:"px-2 py-1",lg:"px-2.5 py-1",xl:"px-3 py-1.5"}},k={xs:g.xs,sm:g.xs,md:g.sm,lg:g.sm,xl:g.md};function rowClasses(e,s,l,n){return u("relative flex w-full cursor-pointer items-center select-none",l?"text-(--p-accent)":"text-(--plass-fg)",v[s][e],k[e],m[e],p[e],C,f,"data-[highlighted]:bg-(--p-soft-hover)","data-[popup-open]:bg-(--p-soft)","data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50","[outline:none]",n)}const w="flex h-[1lh] w-[1.2em] shrink-0 items-center justify-center";function shortcutClasses(e){return u("ms-2 shrink-0 text-(--plass-muted-fg) tabular-nums",y[e])}function RowBody({children:l,description:n,size:a}){return x(n)?s("span",{className:"flex min-w-0 flex-1 flex-col text-start",children:[e("span",{className:"truncate",children:l}),e("span",{className:u("truncate text-(--plass-muted-fg)",y[a]),children:n})]}):e("span",{className:"min-w-0 flex-1 truncate text-start",children:l})}export function PlMenuItem({onClick:a,href:o,target:i,startIcon:c,endIcon:d,shortcut:p,description:m,color:h,closeOnClick:f=!0,disabled:y=!1,label:g,children:C,className:N,style:v}){const{size:k,density:z}=n.useContext(r),O=s(l,{children:[x(c)?e("span",{className:u(w,"text-(--plass-muted-fg)"),children:c}):null,e(RowBody,{description:m,size:k,children:C}),x(d)?e("span",{className:u(w,"text-(--plass-muted-fg)"),children:d}):null,x(p)?e("span",{className:shortcutClasses(k),children:p}):null]}),P=h?b(h,0):void 0,I=P||v?{...P,...v}:void 0;return void 0!==o?e(t.LinkItem,{href:o,target:i,label:g,closeOnClick:f,onClick:a,className:rowClasses(k,z,Boolean(h),N),style:I,children:O}):e(t.Item,{disabled:y,label:g,closeOnClick:f,onClick:a,className:rowClasses(k,z,Boolean(h),N),style:I,children:O})}export function PlMenuCheckboxItem({checked:l,defaultChecked:a,onCheckedChange:o,endIcon:c,shortcut:d,description:p,color:m,closeOnClick:h=!1,disabled:f=!1,label:y,children:g,className:C,style:N}){const{size:v,density:k}=n.useContext(r),z=m?b(m,0):void 0;return s(t.CheckboxItem,{checked:l,defaultChecked:a,onCheckedChange:e=>o?.(e),disabled:f,label:y,closeOnClick:h,className:rowClasses(v,k,Boolean(m),C),style:z||N?{...z,...N}:void 0,children:[e("span",{className:u(w,"text-(--p-accent)"),children:e(t.CheckboxItemIndicator,{className:"flex items-center justify-center",children:e(i,{})})}),e(RowBody,{description:p,size:v,children:g}),x(c)?e("span",{className:u(w,"text-(--plass-muted-fg)"),children:c}):null,x(d)?e("span",{className:shortcutClasses(v),children:d}):null]})}export function PlMenuRadioGroup({value:s,defaultValue:l,onValueChange:n,disabled:a=!1,children:o,className:r,style:i}){return e(t.RadioGroup,{value:s,defaultValue:l,onValueChange:e=>n?.(e),disabled:a,className:r,style:i,children:o})}export function PlMenuRadioItem({value:l,endIcon:a,shortcut:o,description:i,color:c,closeOnClick:p=!1,disabled:m=!1,label:h,children:f,className:y,style:g}){const{size:C,density:N}=n.useContext(r),v=c?b(c,0):void 0;return s(t.RadioItem,{value:l,disabled:m,label:h,closeOnClick:p,className:rowClasses(C,N,Boolean(c),y),style:v||g?{...v,...g}:void 0,children:[e("span",{className:u(w,"text-(--p-accent)"),children:e(t.RadioItemIndicator,{className:"flex items-center justify-center",children:e(d,{})})}),e(RowBody,{description:i,size:C,children:f}),x(a)?e("span",{className:u(w,"text-(--plass-muted-fg)"),children:a}):null,x(o)?e("span",{className:shortcutClasses(C),children:o}):null]})}export function PlMenuGroup({label:l,children:a,className:o,style:i}){const{size:c,density:d}=n.useContext(r);return s(t.Group,{className:o,style:i,children:[x(l)?e(t.GroupLabel,{className:u(v[d][c],y[c],"font-semibold tracking-wide text-(--plass-muted-fg) uppercase"),children:l}):null,a]})}export function PlMenuSeparator({className:s,...l}){return e(t.Separator,{className:u("-mx-1 my-1 h-px bg-(--plass-divider)",s),...l})}export function PlMenuSubmenu({label:l,startIcon:a,disabled:o=!1,side:i="right",sideOffset:d=4,children:m,className:h,style:f}){const{size:y,density:C,color:v}=n.useContext(r);return s(t.SubmenuRoot,{children:[s(t.SubmenuTrigger,{disabled:o,className:rowClasses(y,C,!1),children:[x(a)?e("span",{className:u(w,"text-(--plass-muted-fg)"),children:a}):null,e("span",{className:"min-w-0 flex-1 truncate text-start",children:l}),e("span",{className:u(w,"text-(--plass-muted-fg) -rotate-90"),children:e(c,{})})]}),e(t.Portal,{children:e(t.Positioner,{className:"plass-portal z-(--plass-z-portal) [outline:none]",side:i,sideOffset:d,align:"start",children:e(t.Popup,{className:u(N,g[y],p[y],h),style:{...b(v,3),...f},children:m})})})]})}export function PlMenu({size:l,color:o,density:i,trigger:c,open:d,defaultOpen:m,onOpenChange:h,side:x="bottom",align:f="start",sideOffset:y=6,modal:C=!0,openOnHover:v=!1,loopFocus:k=!0,disabled:w=!1,className:z,style:O,children:P}){const I=a(),M=l??I.size??"md",R=o??I.color??"primary",j=i??I.density??"default",B=n.useMemo(()=>({size:M,color:R,density:j}),[M,R,j]);return e(r.Provider,{value:B,children:s(t.Root,{open:d,defaultOpen:m,onOpenChange:e=>h?.(e),modal:C,loopFocus:k,disabled:w,children:[c?e(t.Trigger,{render:c,openOnHover:v,disabled:w}):null,e(t.Portal,{children:e(t.Positioner,{className:"plass-portal z-(--plass-z-portal) [outline:none]",side:x,align:f,sideOffset:y,children:e(t.Popup,{className:u(N,g[M],p[M],z),style:{...b(R,3),...O},children:P})})})]})})}export function PlContextMenu({size:l,color:t,density:i,content:c,children:d,open:m,defaultOpen:h,onOpenChange:x,loopFocus:f=!0,disabled:y=!1,className:C,style:v}){const k=a(),w=l??k.size??"md",z=t??k.color??"primary",O=i??k.density??"default",P=n.useMemo(()=>({size:w,color:z,density:O}),[w,z,O]);return e(r.Provider,{value:P,children:s(o.Root,{open:m,defaultOpen:h,onOpenChange:e=>x?.(e),loopFocus:f,disabled:y,children:[e(o.Trigger,{children:d}),e(o.Portal,{children:e(o.Positioner,{className:"plass-portal z-(--plass-z-portal) [outline:none]",children:e(o.Popup,{className:u(N,g[w],p[w],C),style:{...b(z,3),...v},children:c})})})]})})}
1
+ "use client";import{jsx as e,jsxs as s,Fragment as l}from"react/jsx-runtime";import*as n from"react";import{useDefaults as t}from"../../internal/defaults.js";import{Menu as a}from"@base-ui/react/menu";import{ContextMenu as o}from"@base-ui/react/context-menu";import{safeRel as r}from"../../internal/link.js";import{MenuContext as i}from"../../internal/menu.js";import{CheckIcon as c,ChevronIcon as d,DotIcon as p}from"../../internal/icons.js";import{controlTextLeadingClasses as u,cx as m,forcedHighlightedClasses as h,gapClasses as f,glassClasses as x,hasContent as y,iconClasses as g,metaTextClasses as b,radiusClasses as C,surfaceSlots as N,transitionClasses as v}from"../../internal/styles.js";const k=/* @__PURE__ */[x,"max-h-[min(24rem,var(--available-height))] min-w-40 overflow-y-auto overscroll-contain","border bg-(--plass-glass-press) p-1","[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)]","data-[starting-style]:opacity-0 data-[ending-style]:opacity-0"].join(" "),w={default:{xs:"px-1.5 py-0.5",sm:"px-2 py-1",md:"px-2.5 py-1.5",lg:"px-3 py-2",xl:"px-3.5 py-2.5"},compact:{xs:"px-1 py-0.5",sm:"px-1.5 py-0.5",md:"px-2 py-1",lg:"px-2.5 py-1",xl:"px-3 py-1.5"}},z={xs:C.xs,sm:C.xs,md:C.sm,lg:C.sm,xl:C.md};function rowClasses(e,s,l,n){return m("relative flex w-full cursor-pointer items-center select-none",l?"text-(--p-accent)":"text-(--plass-fg)",w[s][e],z[e],f[e],u[e],v,g,"data-[highlighted]:bg-(--p-soft-hover)",h,"data-[popup-open]:bg-(--p-soft)","data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50","[outline:none]",n)}const O="flex h-[1lh] w-[1.2em] shrink-0 items-center justify-center";function shortcutClasses(e){return m("ms-2 shrink-0 text-(--plass-muted-fg) tabular-nums",b[e])}function RowBody({children:l,description:n,size:t}){return y(n)?s("span",{className:"flex min-w-0 flex-1 flex-col text-start",children:[e("span",{className:"truncate",children:l}),e("span",{className:m("truncate text-(--plass-muted-fg)",b[t]),children:n})]}):e("span",{className:"min-w-0 flex-1 truncate text-start",children:l})}export function PlMenuItem({onClick:t,href:o,target:c,rel:d,startIcon:p,endIcon:u,shortcut:h,description:f,color:x,closeOnClick:g=!0,disabled:b=!1,label:C,children:v,className:k,style:w}){const{size:z,density:P}=n.useContext(i),I=s(l,{children:[y(p)?e("span",{className:m(O,"text-(--plass-muted-fg)"),children:p}):null,e(RowBody,{description:f,size:z,children:v}),y(u)?e("span",{className:m(O,"text-(--plass-muted-fg)"),children:u}):null,y(h)?e("span",{className:shortcutClasses(z),children:h}):null]}),M=x?N(x,0):void 0,j=M||w?{...M,...w}:void 0;return void 0===o||b?e(a.Item,{disabled:b,label:C,closeOnClick:g,onClick:t,className:rowClasses(z,P,Boolean(x),k),style:j,children:I}):e(a.LinkItem,{href:o,target:c,rel:r(c,d),label:C,closeOnClick:g,onClick:t,className:rowClasses(z,P,Boolean(x),k),style:j,children:I})}export function PlMenuCheckboxItem({checked:l,defaultChecked:t,onCheckedChange:o,endIcon:r,shortcut:d,description:p,color:u,closeOnClick:h=!1,disabled:f=!1,label:x,children:g,className:b,style:C}){const{size:v,density:k}=n.useContext(i),w=u?N(u,0):void 0;return s(a.CheckboxItem,{checked:l,defaultChecked:t,onCheckedChange:e=>o?.(e),disabled:f,label:x,closeOnClick:h,className:rowClasses(v,k,Boolean(u),b),style:w||C?{...w,...C}:void 0,children:[e("span",{className:m(O,"text-(--p-accent)"),children:e(a.CheckboxItemIndicator,{className:"flex items-center justify-center",children:e(c,{})})}),e(RowBody,{description:p,size:v,children:g}),y(r)?e("span",{className:m(O,"text-(--plass-muted-fg)"),children:r}):null,y(d)?e("span",{className:shortcutClasses(v),children:d}):null]})}export function PlMenuRadioGroup({value:s,defaultValue:l,onValueChange:n,disabled:t=!1,children:o,className:r,style:i}){return e(a.RadioGroup,{value:s,defaultValue:l,onValueChange:e=>n?.(e),disabled:t,className:r,style:i,children:o})}export function PlMenuRadioItem({value:l,endIcon:t,shortcut:o,description:r,color:c,closeOnClick:d=!1,disabled:u=!1,label:h,children:f,className:x,style:g}){const{size:b,density:C}=n.useContext(i),v=c?N(c,0):void 0;return s(a.RadioItem,{value:l,disabled:u,label:h,closeOnClick:d,className:rowClasses(b,C,Boolean(c),x),style:v||g?{...v,...g}:void 0,children:[e("span",{className:m(O,"text-(--p-accent)"),children:e(a.RadioItemIndicator,{className:"flex items-center justify-center",children:e(p,{})})}),e(RowBody,{description:r,size:b,children:f}),y(t)?e("span",{className:m(O,"text-(--plass-muted-fg)"),children:t}):null,y(o)?e("span",{className:shortcutClasses(b),children:o}):null]})}export function PlMenuGroup({label:l,children:t,className:o,style:r}){const{size:c,density:d}=n.useContext(i);return s(a.Group,{className:o,style:r,children:[y(l)?e(a.GroupLabel,{className:m(w[d][c],b[c],"font-semibold tracking-wide text-(--plass-muted-fg) uppercase"),children:l}):null,t]})}export function PlMenuSeparator({className:s,...l}){return e(a.Separator,{className:m("-mx-1 my-1 h-px bg-(--plass-divider)",s),...l})}export function PlMenuSubmenu({label:l,startIcon:t,disabled:o=!1,side:r,sideOffset:c=4,children:p,className:h,style:f}){const{size:x,density:g,color:b}=n.useContext(i);return s(a.SubmenuRoot,{children:[s(a.SubmenuTrigger,{disabled:o,className:rowClasses(x,g,!1),children:[y(t)?e("span",{className:m(O,"text-(--plass-muted-fg)"),children:t}):null,e("span",{className:"min-w-0 flex-1 truncate text-start",children:l}),e("span",{className:m(O,"text-(--plass-muted-fg) -rotate-90 rtl:rotate-90"),children:e(d,{})})]}),e(a.Portal,{children:e(a.Positioner,{className:"plass-portal z-(--plass-z-portal) [outline:none]",side:r??"inline-end",sideOffset:c,align:"start",children:e(a.Popup,{className:m(k,C[x],u[x],h),style:{...N(b,3),...f},children:p})})})]})}export function PlMenu({size:l,color:o,density:r,trigger:c,open:d,defaultOpen:p,onOpenChange:h,side:f="bottom",align:x="start",sideOffset:y=6,modal:g=!0,openOnHover:b=!1,loopFocus:v=!0,disabled:w=!1,className:z,style:O,children:P}){const I=t(),M=l??I.size??"md",j=o??I.color??"primary",R=r??I.density??"default",B=n.useMemo(()=>({size:M,color:j,density:R}),[M,j,R]);return e(i.Provider,{value:B,children:s(a.Root,{open:d,defaultOpen:p,onOpenChange:e=>h?.(e),modal:g,loopFocus:v,disabled:w,children:[c?e(a.Trigger,{render:c,openOnHover:b,disabled:w}):null,e(a.Portal,{children:e(a.Positioner,{className:"plass-portal z-(--plass-z-portal) [outline:none]",side:f,align:x,sideOffset:y,children:e(a.Popup,{className:m(k,C[M],u[M],z),style:{...N(j,3),...O},children:P})})})]})})}export function PlContextMenu({size:l,color:a,density:r,content:c,children:d,open:p,defaultOpen:h,onOpenChange:f,loopFocus:x=!0,disabled:y=!1,className:g,style:b}){const v=t(),w=l??v.size??"md",z=a??v.color??"primary",O=r??v.density??"default",P=n.useMemo(()=>({size:w,color:z,density:O}),[w,z,O]);return e(i.Provider,{value:P,children:s(o.Root,{open:p,defaultOpen:h,onOpenChange:e=>f?.(e),loopFocus:x,disabled:y,children:[e(o.Trigger,{children:d}),e(o.Portal,{children:e(o.Positioner,{className:"plass-portal z-(--plass-z-portal) [outline:none]",children:e(o.Popup,{className:m(k,C[w],u[w],g),style:{...N(z,3),...b},children:c})})})]})})}
@@ -1 +1 @@
1
- "use client";import{jsx as e,jsxs as l}from"react/jsx-runtime";import*as r from"react";import{Meter as a}from"@base-ui/react/meter";import{useDefaults as s}from"../../internal/defaults.js";import{barThicknessClasses as t,fillTransitionClasses as o,progressSlots as i,trackClasses as m}from"../../internal/progress.js";import{cx as n,metaTextClasses as c,stackGapClasses as f}from"../../internal/styles.js";import{bandColor as u}from"../../internal/threshold.js";export const PlMeter=/* @__PURE__ */r.forwardRef(function PlMeter({value:r,min:d=0,max:p=100,label:h,showValue:x=!1,format:j,thresholds:b,size:w,color:N,className:g,style:v,...y},k){const z=s(),M=w??z.size??"md",P=N??z.color??"primary";return l(a.Root,{ref:k,value:r,min:d,max:p,format:j,locale:z.locale,className:n("flex w-full flex-col",f[M],g),style:{...i(u(r,P,b)),...v},...y,children:[h||x?l("div",{className:n("flex items-baseline gap-2",h?"justify-between":"justify-end",c[M]),children:[h?e(a.Label,{className:"min-w-0 truncate text-(--plass-fg)",children:h}):null,x?e(a.Value,{className:"shrink-0 tabular-nums text-(--plass-muted-fg)"}):null]}):null,e(a.Track,{className:n("relative w-full overflow-hidden rounded-full",m,t[M]),children:e(a.Indicator,{className:n("rounded-full [background-image:var(--p-fill)]",o)})})]})});
1
+ "use client";import{jsx as e,jsxs as l}from"react/jsx-runtime";import*as r from"react";import{Meter as s}from"@base-ui/react/meter";import{useDefaults as a}from"../../internal/defaults.js";import{barThicknessClasses as t,fillClasses as o,fillTransitionClasses as m,progressSlots as n,trackClasses as i}from"../../internal/progress.js";import{cx as c,metaTextClasses as f,stackGapClasses as u}from"../../internal/styles.js";import{bandColor as d}from"../../internal/threshold.js";export const PlMeter=/* @__PURE__ */r.forwardRef(function PlMeter({value:r,min:p=0,max:h=100,label:x,showValue:j=!1,format:w,thresholds:N,size:b,color:y,className:v,style:g,...k},z){const M=a(),P=b??M.size??"md",R=y??M.color??"primary";return l(s.Root,{ref:z,value:r,min:p,max:h,format:w,locale:M.locale,className:c("flex w-full flex-col",u[P],v),style:{...n(d(r,R,N)),...g},...k,children:[x||j?l("div",{className:c("flex items-baseline gap-2",x?"justify-between":"justify-end",f[P]),children:[x?e(s.Label,{className:"min-w-0 truncate text-(--plass-fg)",children:x}):null,j?e(s.Value,{className:"shrink-0 tabular-nums text-(--plass-muted-fg)"}):null]}):null,e(s.Track,{className:c("relative w-full overflow-hidden rounded-full",i,t[P]),children:e(s.Indicator,{className:c("rounded-full",o,m)})})]})});
@@ -48,6 +48,12 @@ export interface PlNavigationMenuItemProps {
48
48
  value?: string;
49
49
  /** Unavailable. The word stays in the row and opens nothing. */
50
50
  disabled?: boolean;
51
+ /**
52
+ * The page the reader is on. A link item is marked `aria-current="page"` and
53
+ * drawn in the accent, so the row says where the reader is as well as where
54
+ * they can go. Ignored on an item that opens a panel.
55
+ */
56
+ active?: boolean;
51
57
  /** How many columns the panel lays its links out in. @default 1 */
52
58
  columns?: number;
53
59
  /** The panel's contents — usually `PlNavigationMenuLink`s. */
@@ -84,7 +90,7 @@ export declare const PlNavigationMenuLink: React.ForwardRefExoticComponent<PlNav
84
90
  * is a link, and the difference is not cosmetic — the second is announced as a
85
91
  * destination and the first as something that expands.
86
92
  */
87
- export declare function PlNavigationMenuItem({ label, href, target, rel, startIcon, value, disabled, columns, children, className, style }: PlNavigationMenuItemProps): React.ReactElement;
93
+ export declare function PlNavigationMenuItem({ label, href, target, rel, startIcon, value, disabled, active, columns, children, className, style }: PlNavigationMenuItemProps): React.ReactElement;
88
94
  /**
89
95
  * A site's navigation: a row of destinations, some of which open a panel of
90
96
  * more of them.
@@ -1 +1 @@
1
- "use client";import{jsx as e,jsxs as a,Fragment as s}from"react/jsx-runtime";import*as t from"react";import{useDefaults as n}from"../../internal/defaults.js";import{NavigationMenu as l}from"@base-ui/react/navigation-menu";import{ChevronIcon as r}from"../../internal/icons.js";import{safeRel as i}from"../../internal/link.js";import{controlHeightClasses as o,controlTextClasses as d,controlTextLeadingClasses as c,cx as p,focusRingClasses as u,focusRingInsetClasses as m,gapClasses as f,glassClasses as h,hasContent as g,iconClasses as v,metaTextClasses as x,paddingXClasses as y,radiusClasses as N,surfaceSlots as b,transitionClasses as w}from"../../internal/styles.js";const j=/* @__PURE__ */t.createContext({size:"md",density:"default"}),P=/* @__PURE__ */["inline-flex shrink-0 cursor-pointer select-none items-center justify-center","whitespace-nowrap font-medium leading-none no-underline","text-(--plass-fg) bg-transparent","[-webkit-tap-highlight-color:transparent] [touch-action:manipulation]",w,v,u,"hover:bg-(--p-soft)","data-[popup-open]:bg-(--p-soft-hover) data-[popup-open]:text-(--p-accent)","data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50","data-[disabled]:saturate-[0.35] data-[disabled]:hover:bg-transparent"].join(" "),z=/* @__PURE__ */[h,"relative 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] overflow-hidden","[transition:opacity_var(--plass-duration)_var(--plass-ease),width_var(--plass-duration)_var(--plass-ease),height_var(--plass-duration)_var(--plass-ease)]","data-[starting-style]:opacity-0 data-[ending-style]:opacity-0"].join(" "),k=/* @__PURE__ */["flex min-w-0 cursor-pointer items-start no-underline","text-(--plass-fg) bg-transparent",w,v,"hover:bg-(--p-soft)",m].join(" "),_={xs:"p-1",sm:"p-1.5",md:"p-2",lg:"p-2.5",xl:"p-3"};export const PlNavigationMenuLink=/* @__PURE__ */t.forwardRef(function PlNavigationMenuLink({href:s,title:n,description:r,startIcon:i,className:o,children:d,...u},m){const{size:h,density:v}=t.useContext(j);return a(l.Link,{ref:m,href:s,className:p(k,N[h],f[h],y[v][h],"py-2",o),...u,children:[g(i)?e("span",{className:"flex h-[1lh] shrink-0 items-center",children:i}):null,a("span",{className:"flex min-w-0 flex-col gap-0.5",children:[e("span",{className:p("font-medium",c[h]),children:n}),g(r)?e("span",{className:p("text-(--plass-muted-fg)",x[h]),children:r}):null,d]})]})});export function PlNavigationMenuItem({label:n,href:c,target:u,rel:m,startIcon:h,value:v,disabled:x=!1,columns:b=1,children:w,className:z,style:k}){const{size:C,density:M}=t.useContext(j),I=void 0!==c&&!g(w),L=p(P,o[C],d[C],f[C],y[M][C],N[C],z);return e(l.Item,{value:v,children:I?a(l.Link,{href:c,target:u,rel:i(u,m),className:L,style:k,children:[g(h)?h:null,n]}):a(s,{children:[a(l.Trigger,{disabled:x,className:L,style:k,children:[g(h)?h:null,n,e(l.Icon,{className:"flex items-center [transition:rotate_var(--plass-duration)_var(--plass-ease)] data-[popup-open]:rotate-180",children:e(r,{})})]}),e(l.Content,{className:p("grid gap-1",_[C]),style:b>1?{gridTemplateColumns:`repeat(${b}, minmax(0, 1fr))`}:void 0,children:w})]})})}export const PlNavigationMenu=/* @__PURE__ */t.forwardRef(function PlNavigationMenu({size:s,color:r,density:i,orientation:o="horizontal",value:d,defaultValue:c,onValueChange:u,delay:m,closeDelay:h,sideOffset:g=8,className:v,style:x,children:y,...w},P){const k=n(),_=s??k.size??"md",C=r??k.color??"primary",M=i??k.density??"default",I=t.useMemo(()=>({size:_,density:M}),[_,M]);return e(j.Provider,{value:I,children:a(l.Root,{ref:P,orientation:o,value:d,defaultValue:c,onValueChange:e=>u?.(e),delay:m,closeDelay:h,className:v,style:{...b(C,3),...x},...w,children:[e(l.List,{className:p("flex items-center","vertical"===o?"flex-col items-stretch":"flex-row",f[_]),children:y}),e(l.Portal,{children:e(l.Positioner,{className:"plass-portal z-(--plass-z-portal) [outline:none]",sideOffset:g,collisionPadding:12,children:e(l.Popup,{className:p(z,N[_]),children:e(l.Viewport,{})})})})]})})});
1
+ "use client";import{jsx as e,jsxs as a,Fragment as t}from"react/jsx-runtime";import*as s from"react";import{useDefaults as n}from"../../internal/defaults.js";import{NavigationMenu as r}from"@base-ui/react/navigation-menu";import{ChevronIcon as l}from"../../internal/icons.js";import{safeRel as i}from"../../internal/link.js";import{controlHeightClasses as o,controlTextClasses as c,controlTextLeadingClasses as d,cx as p,focusRingClasses as u,focusRingInsetClasses as m,gapClasses as f,glassClasses as h,hasContent as g,iconClasses as v,metaTextClasses as x,paddingXClasses as y,radiusClasses as N,surfaceSlots as b,transitionClasses as w}from"../../internal/styles.js";const j=/* @__PURE__ */s.createContext({size:"md",density:"default"}),P=/* @__PURE__ */["inline-flex shrink-0 cursor-pointer select-none items-center justify-center","whitespace-nowrap font-medium leading-none no-underline","text-(--plass-fg) bg-transparent","[-webkit-tap-highlight-color:transparent] [touch-action:manipulation]",w,v,u,"hover:bg-(--p-soft)","data-[popup-open]:bg-(--p-soft-hover) data-[popup-open]:text-(--p-accent)","aria-[current=page]:text-(--p-accent)","data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50","data-[disabled]:saturate-[0.35] data-[disabled]:hover:bg-transparent"].join(" "),z=/* @__PURE__ */[h,"relative 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] overflow-hidden","[transition:opacity_var(--plass-duration)_var(--plass-ease),width_var(--plass-duration)_var(--plass-ease),height_var(--plass-duration)_var(--plass-ease)]","data-[starting-style]:opacity-0 data-[ending-style]:opacity-0"].join(" "),k=/* @__PURE__ */["flex min-w-0 cursor-pointer items-start no-underline","text-(--plass-fg) bg-transparent",w,v,"hover:bg-(--p-soft)",m].join(" "),_={xs:"p-1",sm:"p-1.5",md:"p-2",lg:"p-2.5",xl:"p-3"};export const PlNavigationMenuLink=/* @__PURE__ */s.forwardRef(function PlNavigationMenuLink({href:t,title:n,description:l,startIcon:o,className:c,children:u,target:m,rel:h,...v},b){const{size:w,density:P}=s.useContext(j);return a(r.Link,{ref:b,href:t,target:m,rel:i(m,h),className:p(k,N[w],f[w],y[P][w],"py-2",c),...v,children:[g(o)?e("span",{className:"flex h-[1lh] shrink-0 items-center",children:o}):null,a("span",{className:"flex min-w-0 flex-col gap-0.5",children:[e("span",{className:p("font-medium",d[w]),children:n}),g(l)?e("span",{className:p("text-(--plass-muted-fg)",x[w]),children:l}):null,u]})]})});export function PlNavigationMenuItem({label:n,href:d,target:u,rel:m,startIcon:h,value:v,disabled:x=!1,active:b=!1,columns:w=1,children:z,className:k,style:C}){const{size:M,density:I}=s.useContext(j),L=void 0!==d&&!g(z),V=p(P,o[M],c[M],f[M],y[I][M],N[M],k);return e(r.Item,{value:v,children:L?a(r.Link,{href:d,target:u,rel:i(u,m),"aria-current":b?"page":void 0,className:V,style:C,children:[g(h)?h:null,n]}):a(t,{children:[a(r.Trigger,{disabled:x,className:V,style:C,children:[g(h)?h:null,n,e(r.Icon,{className:"flex items-center [transition:rotate_var(--plass-duration)_var(--plass-ease)] data-[popup-open]:rotate-180",children:e(l,{})})]}),e(r.Content,{className:p("grid gap-1",_[M]),style:w>1?{gridTemplateColumns:`repeat(${w}, minmax(0, 1fr))`}:void 0,children:z})]})})}export const PlNavigationMenu=/* @__PURE__ */s.forwardRef(function PlNavigationMenu({size:t,color:l,density:i,orientation:o="horizontal",value:c,defaultValue:d,onValueChange:u,delay:m,closeDelay:h,sideOffset:g=8,className:v,style:x,children:y,...w},P){const k=n(),_=t??k.size??"md",C=l??k.color??"primary",M=i??k.density??"default",I=s.useMemo(()=>({size:_,density:M}),[_,M]);return e(j.Provider,{value:I,children:a(r.Root,{ref:P,orientation:o,value:c,defaultValue:d,onValueChange:e=>u?.(e),delay:m,closeDelay:h,className:v,style:{...b(C,3),...x},...w,children:[e(r.List,{className:p("m-0 flex list-none items-center p-0","vertical"===o?"flex-col items-stretch":"flex-row",f[_]),children:y}),e(r.Portal,{children:e(r.Positioner,{className:"plass-portal z-(--plass-z-portal) [outline:none]",sideOffset:g,collisionPadding:12,children:e(r.Popup,{className:p(z,N[_]),children:e(r.Viewport,{})})})})]})})});
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import type { PlassElevation, PlassFieldClassNames, PlassHotKeys, PlassStyleProps } from '../../types.js';
2
+ import type { PlassElevation, PlassFieldClassNames, PlassHotKeys, PlassFieldLabelPlacement, PlassStyleProps } from '../../types.js';
3
3
  /**
4
4
  * Where the two steppers sit.
5
5
  *
@@ -98,10 +98,18 @@ export interface PlNumberFieldProps extends PlassStyleProps, Omit<React.Componen
98
98
  */
99
99
  decrementLabel?: string;
100
100
  /**
101
- * Label above the control, wired to it by Base UI's Field. There is no
102
- * floating variant on purpose: floating labels need a `transform`.
101
+ * The name of what the field holds, wired to the control by Base UI's Field.
102
+ * `labelPlacement` decides whether it sits above the box or in its top edge.
103
+ * There is still no floating variant on purpose: a floating label needs a
104
+ * `transform` on the thing being typed into, and the notch does not move.
103
105
  */
104
106
  label?: React.ReactNode;
107
+ /**
108
+ * Where the `label` goes — above the control, or in its top edge.
109
+ * Falls back to the nearest `PlassProvider`, then to `top`.
110
+ * @default 'top'
111
+ */
112
+ labelPlacement?: PlassFieldLabelPlacement;
105
113
  /** Helper text below the control. */
106
114
  description?: React.ReactNode;
107
115
  /** Error message below the control. Its presence also turns the field invalid. */
@@ -141,4 +149,4 @@ export interface PlNumberFieldProps extends PlassStyleProps, Omit<React.Componen
141
149
  * clamping, the press-and-hold repeat on the steppers, and the hidden input that
142
150
  * submits with a form.
143
151
  */
144
- export declare function PlNumberField({ variant, size: sizeProp, color: colorProp, density: densityProp, elevation, value, defaultValue, onValueChange, onValueCommitted, min, max, step, largeStep, smallStep, snapOnStep, allowWheelScrub, format, locale: localeProp, steppers, incrementLabel: incrementLabelProp, decrementLabel: decrementLabelProp, label, description, error, invalid, startIcon, endIcon, fullWidth, disabled, readOnly, required, name, placeholder, id, className, hotKeys, classNames, style, ...props }: PlNumberFieldProps): React.JSX.Element;
152
+ export declare function PlNumberField({ variant, size: sizeProp, color: colorProp, density: densityProp, elevation, value, defaultValue, onValueChange, onValueCommitted, min, max, step, largeStep, smallStep, snapOnStep, allowWheelScrub, format, locale: localeProp, steppers, incrementLabel: incrementLabelProp, decrementLabel: decrementLabelProp, label, labelPlacement: labelPlacementProp, description, error, invalid, startIcon, endIcon, fullWidth, disabled, readOnly, required, name, placeholder, id, className, hotKeys, classNames, style, ...props }: PlNumberFieldProps): React.JSX.Element;
@@ -1 +1 @@
1
- "use client";import{jsx as e,jsxs as l}from"react/jsx-runtime";import{useDefaults as a}from"../../internal/defaults.js";import{useLabels as t}from"../../internal/labels.js";import{NumberField as s}from"@base-ui/react/number-field";import{Field as n}from"@base-ui/react/field";import{MinusIcon as r,PlusIcon as i}from"../../internal/icons.js";import{hotKeyHandler as o}from"../../internal/keys.js";import{controlHeightClasses as c,controlTextLeadingClasses as d,cx as m,disabledClasses as p,fieldReadOnlyClasses as u,fieldRestClasses as f,focusRingClasses as h,focusWithinRingClasses as b,gapClasses as x,hasContent as g,iconClasses as v,metaTextClasses as N,paddingXClasses as y,radiusClasses as j,stackGapClasses as w,surfaceSlots as k,transitionClasses as S}from"../../internal/styles.js";const _=/* @__PURE__ */["group relative flex w-full cursor-text items-center","[-webkit-tap-highlight-color:transparent]",S,"focus-within:[transition-duration:0ms]",b,v].join(" "),V=/* @__PURE__ */["inline-flex size-[1.7em] shrink-0 cursor-pointer items-center justify-center","rounded-(--plass-radius-xs) text-(--plass-muted-fg) select-none","[&_svg]:size-[0.9em] [&_svg]:shrink-0","[-webkit-tap-highlight-color:transparent] [touch-action:manipulation]","[transition:background-color_var(--plass-duration)_var(--plass-ease),color_var(--plass-duration)_var(--plass-ease),opacity_var(--plass-duration)_var(--plass-ease)]","active:[transition-duration:0ms]","hover:bg-(--p-soft) hover:text-(--p-accent)","active:bg-(--p-soft-press)",h,"disabled:cursor-not-allowed disabled:bg-transparent disabled:opacity-40"].join(" ");export function PlNumberField({variant:h="glass",size:b,color:v,density:S,elevation:z=0,value:C,defaultValue:I,onValueChange:O,onValueCommitted:B,min:D,max:L,step:W,largeStep:q,smallStep:F,snapOnStep:K,allowWheelScrub:R=!1,format:E,locale:G,steppers:P="end",incrementLabel:$,decrementLabel:A,label:H,description:J,error:M,invalid:Q,startIcon:T,endIcon:U,fullWidth:X=!1,disabled:Y=!1,readOnly:Z=!1,required:ee=!1,name:le,placeholder:ae,id:te,className:se,hotKeys:ne,classNames:re,style:ie,...oe}){const ce=a(),de=t(),me=$??de.increase,pe=A??de.decrease,ue=G??ce.locale,fe=b??ce.size??"md",he=v??ce.color??"primary",be=S??ce.density??"default",xe=g(M),ge=Q??xe,ve=ge?"danger":he,Ne=y[be][fe],ye={end:`${Ne} pe-1`,split:"px-1",none:Ne},je=e(s.Decrement,{"aria-label":pe,className:V,children:e(r,{})}),we=e(s.Increment,{"aria-label":me,className:V,children:e(i,{})}),ke="none"!==P&&!Z;return l(n.Root,{disabled:Y,invalid:ge,className:["flex-col align-top",w[fe],X?"flex w-full":"inline-flex",se??""].filter(Boolean).join(" "),style:{...k(ve,z),...ie},...oe,children:[H?e(n.Label,{className:m(N[fe],"font-medium text-(--plass-fg)",Y?"opacity-50":"",re?.label),children:H}):null,e(s.Root,{id:te,name:le,className:"contents",value:C,defaultValue:I,onValueChange:e=>O?.(e),onValueCommitted:e=>B?.(e),min:D,max:L,step:W,largeStep:q,smallStep:F,snapOnStep:K,allowWheelScrub:R,format:E,locale:ue,disabled:Y,readOnly:Z,required:ee,children:l(s.Group,{className:[_,c[fe],d[fe],j[fe],x[fe],ke?ye[P]:Ne,Y?p[h]:Z?u[h]:f[h],re?.control].filter(Boolean).join(" "),children:[ke&&"split"===P?je:null,T?e("span",{className:"flex h-[1lh] shrink-0 items-center text-(--plass-muted-fg)",children:T}):null,e(s.Input,{placeholder:ae,onKeyDown:o(ne,void 0),className:["min-w-0 flex-1 self-stretch bg-transparent [font:inherit] text-inherit","[outline:none]","tabular-nums","split"===P&&ke?"text-center":"","placeholder:text-(--plass-muted-fg)","caret-(--p-accent) selection:bg-(--p-soft-press)","disabled:cursor-not-allowed"].filter(Boolean).join(" ")}),U?e("span",{className:"flex h-[1lh] shrink-0 items-center text-(--plass-muted-fg)",children:U}):null,ke&&"end"===P?l("span",{className:"flex shrink-0 items-center gap-0.5",children:[je,we]}):null,ke&&"split"===P?we:null]})}),J?e(n.Description,{className:m(N[fe],"text-(--plass-muted-fg)",re?.description),children:J}):null,e(n.Error,xe?{match:!0,className:m(N[fe],"text-(--p-accent)",re?.error),children:M}:{className:m(N[fe],"text-(--p-accent)",re?.error)})]})}
1
+ "use client";import{jsx as e,jsxs as l}from"react/jsx-runtime";import{useDefaults as a}from"../../internal/defaults.js";import{useLabels as t}from"../../internal/labels.js";import{NumberField as s}from"@base-ui/react/number-field";import{Field as n}from"@base-ui/react/field";import{MinusIcon as r,PlusIcon as i}from"../../internal/icons.js";import{hotKeyHandler as o}from"../../internal/keys.js";import{glowPointerMove as c}from"../../internal/glow.js";import{FieldNotch as d,notchShellStyle as m}from"../../internal/notch.js";import{controlHeightClasses as p,controlTextLeadingClasses as u,cx as f,disabledClasses as h,fieldReadOnlyClasses as b,fieldRestClasses as g,focusRingClasses as x,focusWithinRingClasses as v,gapClasses as y,hasContent as N,iconClasses as j,metaTextClasses as w,paddingXClasses as k,radiusClasses as S,stackGapClasses as _,surfaceSlots as V,transitionClasses as z}from"../../internal/styles.js";const O=/* @__PURE__ */["group relative flex w-full cursor-text items-center","[-webkit-tap-highlight-color:transparent]",z,"focus-within:[transition-duration:0ms]",j].join(" "),C=v,I=/* @__PURE__ */["inline-flex size-[1.7em] shrink-0 cursor-pointer items-center justify-center","rounded-(--plass-radius-xs) text-(--plass-muted-fg) select-none","[&_svg]:size-[0.9em] [&_svg]:shrink-0","[-webkit-tap-highlight-color:transparent] [touch-action:manipulation]","[transition:background-color_var(--plass-duration)_var(--plass-ease),color_var(--plass-duration)_var(--plass-ease),opacity_var(--plass-duration)_var(--plass-ease)]","active:[transition-duration:0ms]","hover:bg-(--p-soft) hover:text-(--p-accent)","active:bg-(--p-soft-press)",x,"disabled:cursor-not-allowed disabled:bg-transparent disabled:opacity-40"].join(" ");export function PlNumberField({variant:x="glass",size:v,color:j,density:z,elevation:P=0,value:B,defaultValue:D,onValueChange:L,onValueCommitted:W,min:q,max:F,step:K,largeStep:R,smallStep:E,snapOnStep:G,allowWheelScrub:M=!1,format:$,locale:A,steppers:H="end",incrementLabel:J,decrementLabel:Q,label:T,labelPlacement:U,description:X,error:Y,invalid:Z,startIcon:ee,endIcon:le,fullWidth:ae=!1,disabled:te=!1,readOnly:se=!1,required:ne=!1,name:re,placeholder:ie,id:oe,className:ce,hotKeys:de,classNames:me,style:pe,...ue}){const fe=a(),he=t(),be=J??he.increase,ge=Q??he.decrease,xe=A??fe.locale,ve=v??fe.size??"md",ye=j??fe.color??"primary",Ne=z??fe.density??"default",je="notch"===(U??fe.labelPlacement??"top")&&N(T),we=N(Y),ke=Z??we,Se=ke?"danger":ye,_e=!te&&!se,Ve=k[Ne][ve],ze={end:`${Ve} pe-1`,split:"px-1",none:Ve},Oe=e(s.Decrement,{"aria-label":ge,className:I,children:e(r,{})}),Ce=e(s.Increment,{"aria-label":be,className:I,children:e(i,{})}),Ie="none"!==H&&!se,Pe=e(n.Label,{className:f(w[ve],"font-semibold",te?"text-(--plass-muted-fg)":"text-(--plass-fg)",me?.label),children:T});return l(n.Root,{disabled:te,invalid:ke,className:["flex-col align-top",_[ve],ae?"flex w-full":"inline-flex",ce??""].filter(Boolean).join(" "),style:{...V(Se,P),...pe},...ue,children:[N(T)&&!je?Pe:null,e(s.Root,{id:oe,name:re,className:"contents",value:B,defaultValue:D,onValueChange:e=>L?.(e),onValueCommitted:e=>W?.(e),min:q,max:F,step:K,largeStep:R,smallStep:E,snapOnStep:G,allowWheelScrub:M,format:$,locale:xe,disabled:te,readOnly:se,required:ne,children:e(d,{notched:je,size:ve,density:Ne,variant:x,disabled:te,readOnly:se,label:Pe,children:l(s.Group,{style:je?m:void 0,onPointerMove:c(_e),className:[O,je?"":C,p[ve],u[ve],S[ve],y[ve],Ie?ze[H]:Ve,te?h[x]:se?b[x]:g[x],_e?"plass-glow":"",me?.control].filter(Boolean).join(" "),children:[Ie&&"split"===H?Oe:null,ee?e("span",{className:"flex h-[1lh] shrink-0 items-center text-(--plass-muted-fg)",children:ee}):null,e(s.Input,{placeholder:ie,onKeyDown:o(de,void 0),className:["min-w-0 flex-1 self-stretch bg-transparent [font:inherit] text-inherit","[outline:none]","tabular-nums","split"===H&&Ie?"text-center":"","placeholder:text-(--plass-muted-fg)","caret-(--p-accent) selection:bg-(--p-soft-press)","disabled:cursor-not-allowed"].filter(Boolean).join(" ")}),le?e("span",{className:"flex h-[1lh] shrink-0 items-center text-(--plass-muted-fg)",children:le}):null,Ie&&"end"===H?l("span",{className:"flex shrink-0 items-center gap-0.5",children:[Oe,Ce]}):null,Ie&&"split"===H?Ce:null]})})}),X?e(n.Description,{className:f("m-0",w[ve],"text-(--plass-muted-fg)",me?.description),children:X}):null,e(n.Error,we?{match:!0,className:f(w[ve],"text-(--p-accent)",me?.error),children:Y}:{className:f(w[ve],"text-(--p-accent)",me?.error)})]})}