plass-ui 1.1.0 → 1.3.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 (190) hide show
  1. package/CHANGELOG.md +98 -0
  2. package/dist/components/accordion/PlAccordion.js +1 -1
  3. package/dist/components/alert/PlAlert.js +1 -1
  4. package/dist/components/animate-headline/PlAnimateHeadline.js +1 -1
  5. package/dist/components/animate-lighting/PlAnimateLighting.js +1 -1
  6. package/dist/components/animate-typing/PlAnimateTyping.js +1 -1
  7. package/dist/components/aspect-ratio/PlAspectRatio.js +1 -1
  8. package/dist/components/avatar/PlAvatar.js +1 -1
  9. package/dist/components/avatar-group/PlAvatarGroup.js +1 -1
  10. package/dist/components/back-top/PlBackTop.d.ts +55 -0
  11. package/dist/components/back-top/PlBackTop.js +1 -0
  12. package/dist/components/back-top/index.d.ts +2 -0
  13. package/dist/components/back-top/index.js +1 -0
  14. package/dist/components/badge/PlBadge.js +1 -1
  15. package/dist/components/blockquote/PlBlockquote.js +1 -1
  16. package/dist/components/bottom-navigation/PlBottomNavigation.js +1 -1
  17. package/dist/components/box/PlBox.js +1 -1
  18. package/dist/components/breadcrumb/PlBreadcrumb.js +1 -1
  19. package/dist/components/button/PlButton.js +1 -1
  20. package/dist/components/calendar/PlCalendar.d.ts +104 -0
  21. package/dist/components/calendar/PlCalendar.js +1 -0
  22. package/dist/components/calendar/index.d.ts +2 -0
  23. package/dist/components/calendar/index.js +1 -0
  24. package/dist/components/card/PlCard.js +1 -1
  25. package/dist/components/carousel/PlCarousel.js +1 -1
  26. package/dist/components/chat-bubble/PlChatBubble.js +1 -1
  27. package/dist/components/checkbox/PlCheckbox.d.ts +3 -1
  28. package/dist/components/checkbox/PlCheckbox.js +1 -1
  29. package/dist/components/chip/PlChip.js +1 -1
  30. package/dist/components/collapsible/PlCollapsible.js +1 -1
  31. package/dist/components/color-picker/PlColorPicker.js +1 -1
  32. package/dist/components/combobox/PlCombobox.d.ts +13 -2
  33. package/dist/components/combobox/PlCombobox.js +1 -1
  34. package/dist/components/command-palette/PlCommandPalette.d.ts +8 -2
  35. package/dist/components/command-palette/PlCommandPalette.js +1 -1
  36. package/dist/components/confirm/PlConfirmProvider.d.ts +100 -0
  37. package/dist/components/confirm/PlConfirmProvider.js +1 -0
  38. package/dist/components/confirm/index.d.ts +2 -0
  39. package/dist/components/confirm/index.js +1 -0
  40. package/dist/components/container/PlContainer.js +1 -1
  41. package/dist/components/date-picker/PlDatePicker.d.ts +41 -2
  42. package/dist/components/date-picker/PlDatePicker.js +1 -1
  43. package/dist/components/date-range-picker/PlDateRangePicker.js +1 -1
  44. package/dist/components/date-time-picker/PlDateTimePicker.js +1 -1
  45. package/dist/components/divider/PlDivider.js +1 -1
  46. package/dist/components/drawer/PlDrawer.d.ts +4 -2
  47. package/dist/components/drawer/PlDrawer.js +1 -1
  48. package/dist/components/empty/PlEmpty.d.ts +47 -0
  49. package/dist/components/empty/PlEmpty.js +1 -0
  50. package/dist/components/empty/index.d.ts +2 -0
  51. package/dist/components/empty/index.js +1 -0
  52. package/dist/components/file-picker/PlFilePicker.js +1 -1
  53. package/dist/components/floating-bottom-navigation/PlFloatingBottomNavigation.js +1 -1
  54. package/dist/components/footer/PlFooter.js +1 -1
  55. package/dist/components/header/PlHeader.js +1 -1
  56. package/dist/components/highlight/PlHighlight.js +1 -1
  57. package/dist/components/hot-keys/PlHotKeys.js +1 -1
  58. package/dist/components/image/PlImage.d.ts +72 -0
  59. package/dist/components/image/PlImage.js +1 -0
  60. package/dist/components/image/index.d.ts +2 -0
  61. package/dist/components/image/index.js +1 -0
  62. package/dist/components/list/PlList.js +1 -1
  63. package/dist/components/menu/PlMenu.d.ts +6 -4
  64. package/dist/components/menu/PlMenu.js +1 -1
  65. package/dist/components/menubar/PlMenubar.d.ts +5 -1
  66. package/dist/components/menubar/PlMenubar.js +1 -1
  67. package/dist/components/modal/PlModal.d.ts +4 -2
  68. package/dist/components/modal/PlModal.js +1 -1
  69. package/dist/components/navigation-menu/PlNavigationMenu.d.ts +5 -1
  70. package/dist/components/navigation-menu/PlNavigationMenu.js +1 -1
  71. package/dist/components/number-field/PlNumberField.d.ts +13 -2
  72. package/dist/components/number-field/PlNumberField.js +1 -1
  73. package/dist/components/otp-field/PlOtpField.d.ts +12 -1
  74. package/dist/components/otp-field/PlOtpField.js +1 -1
  75. package/dist/components/overlay/PlOverlay.d.ts +4 -2
  76. package/dist/components/overlay/PlOverlay.js +1 -1
  77. package/dist/components/page-layout/PlPageLayout.js +1 -1
  78. package/dist/components/pagination/PlPagination.js +1 -1
  79. package/dist/components/panes/PlPanes.js +1 -1
  80. package/dist/components/pill/PlPill.js +1 -1
  81. package/dist/components/popconfirm/PlPopconfirm.d.ts +61 -0
  82. package/dist/components/popconfirm/PlPopconfirm.js +1 -0
  83. package/dist/components/popconfirm/index.d.ts +2 -0
  84. package/dist/components/popconfirm/index.js +1 -0
  85. package/dist/components/popover/PlPopover.d.ts +1 -1
  86. package/dist/components/popover/PlPopover.js +1 -1
  87. package/dist/components/progress-box/PlProgressBox.js +1 -1
  88. package/dist/components/progress-circular/PlProgressCircular.js +1 -1
  89. package/dist/components/progress-linear/PlProgressLinear.js +1 -1
  90. package/dist/components/radio-group/PlRadioGroup.d.ts +3 -1
  91. package/dist/components/radio-group/PlRadioGroup.js +1 -1
  92. package/dist/components/rating/PlRating.js +1 -1
  93. package/dist/components/scroll-zone/PlScrollZone.js +1 -1
  94. package/dist/components/segmented-button/PlSegmentedButton.js +1 -1
  95. package/dist/components/select/PlSelect.d.ts +12 -1
  96. package/dist/components/select/PlSelect.js +1 -1
  97. package/dist/components/sidebar/PlSidebar.js +1 -1
  98. package/dist/components/skeleton/PlSkeleton.js +1 -1
  99. package/dist/components/slider/PlSlider.js +1 -1
  100. package/dist/components/spoiler/PlSpoiler.js +1 -1
  101. package/dist/components/stat/PlStat.d.ts +66 -0
  102. package/dist/components/stat/PlStat.js +1 -0
  103. package/dist/components/stat/index.d.ts +2 -0
  104. package/dist/components/stat/index.js +1 -0
  105. package/dist/components/stepper/PlStepper.d.ts +86 -0
  106. package/dist/components/stepper/PlStepper.js +1 -0
  107. package/dist/components/stepper/index.d.ts +2 -0
  108. package/dist/components/stepper/index.js +1 -0
  109. package/dist/components/switch/PlSwitch.d.ts +3 -1
  110. package/dist/components/switch/PlSwitch.js +1 -1
  111. package/dist/components/tabs/PlTabs.js +1 -1
  112. package/dist/components/text-field/PlTextField.d.ts +12 -1
  113. package/dist/components/text-field/PlTextField.js +1 -1
  114. package/dist/components/time-picker/PlTimePicker.js +1 -1
  115. package/dist/components/timeline/PlTimeline.d.ts +5 -8
  116. package/dist/components/timeline/PlTimeline.js +1 -1
  117. package/dist/components/toast/PlToast.d.ts +11 -1
  118. package/dist/components/toast/PlToast.js +1 -1
  119. package/dist/components/toggle/PlToggle.js +1 -1
  120. package/dist/components/toolbar/PlToolbar.js +1 -1
  121. package/dist/components/tooltip/PlTooltip.d.ts +1 -1
  122. package/dist/components/tooltip/PlTooltip.js +1 -1
  123. package/dist/components/transfer/PlTransfer.js +1 -1
  124. package/dist/components/tree/PlTree.d.ts +67 -0
  125. package/dist/components/tree/PlTree.js +1 -0
  126. package/dist/components/tree/index.d.ts +2 -0
  127. package/dist/components/tree/index.js +1 -0
  128. package/dist/components/visually-hidden/PlVisuallyHidden.d.ts +46 -0
  129. package/dist/components/visually-hidden/PlVisuallyHidden.js +1 -0
  130. package/dist/components/visually-hidden/index.d.ts +2 -0
  131. package/dist/components/visually-hidden/index.js +1 -0
  132. package/dist/css/back-top.css +2 -0
  133. package/dist/css/calendar.css +2 -0
  134. package/dist/css/confirm.css +2 -0
  135. package/dist/css/empty.css +2 -0
  136. package/dist/css/image.css +2 -0
  137. package/dist/css/popconfirm.css +2 -0
  138. package/dist/css/stat.css +2 -0
  139. package/dist/css/stepper.css +2 -0
  140. package/dist/css/tree.css +2 -0
  141. package/dist/css/visually-hidden.css +2 -0
  142. package/dist/hooks/index.d.ts +7 -0
  143. package/dist/hooks/index.js +1 -0
  144. package/dist/hooks/usePlBreakpoint.d.ts +38 -0
  145. package/dist/hooks/usePlBreakpoint.js +1 -0
  146. package/dist/hooks/usePlColorScheme.d.ts +66 -0
  147. package/dist/hooks/usePlColorScheme.js +1 -0
  148. package/dist/hooks/usePlHotKeys.d.ts +81 -0
  149. package/dist/hooks/usePlHotKeys.js +1 -0
  150. package/dist/hooks/usePlMediaQuery.d.ts +22 -0
  151. package/dist/hooks/usePlMediaQuery.js +1 -0
  152. package/dist/hooks/usePlReducedMotion.d.ts +22 -0
  153. package/dist/hooks/usePlReducedMotion.js +1 -0
  154. package/dist/index.d.ts +12 -0
  155. package/dist/index.js +1 -1
  156. package/dist/internal/animate.d.ts +0 -1
  157. package/dist/internal/animate.js +1 -1
  158. package/dist/internal/calendar.d.ts +25 -3
  159. package/dist/internal/calendar.js +1 -1
  160. package/dist/internal/color-scheme.d.ts +23 -0
  161. package/dist/internal/color-scheme.js +1 -0
  162. package/dist/internal/date.d.ts +21 -0
  163. package/dist/internal/date.js +1 -1
  164. package/dist/internal/defaults.d.ts +69 -0
  165. package/dist/internal/defaults.js +1 -0
  166. package/dist/internal/direction.d.ts +4 -0
  167. package/dist/internal/direction.js +1 -0
  168. package/dist/internal/grid.d.ts +2 -0
  169. package/dist/internal/grid.js +1 -1
  170. package/dist/internal/keys.d.ts +93 -0
  171. package/dist/internal/keys.js +1 -0
  172. package/dist/internal/media.d.ts +26 -0
  173. package/dist/internal/media.js +1 -0
  174. package/dist/internal/page-layout.d.ts +6 -6
  175. package/dist/internal/page-layout.js +1 -1
  176. package/dist/internal/picker.d.ts +4 -2
  177. package/dist/internal/picker.js +1 -1
  178. package/dist/internal/steps.d.ts +76 -0
  179. package/dist/internal/steps.js +1 -0
  180. package/dist/provider/PlColorSchemeScript.d.ts +40 -0
  181. package/dist/provider/PlColorSchemeScript.js +1 -0
  182. package/dist/provider/PlassProvider.d.ts +39 -0
  183. package/dist/provider/PlassProvider.js +1 -0
  184. package/dist/provider/index.d.ts +5 -0
  185. package/dist/provider/index.js +1 -0
  186. package/dist/styles.css +1 -1
  187. package/dist/tailwind.css +29 -1
  188. package/dist/tokens.css +29 -1
  189. package/dist/types.d.ts +89 -0
  190. package/package.json +17 -1
package/CHANGELOG.md CHANGED
@@ -2,6 +2,104 @@
2
2
 
3
3
  > This package's history. The Flutter package keeps its own at [`packages/flutter/CHANGELOG.md`](https://github.com/jooy2/plass-ui/blob/main/packages/flutter/CHANGELOG.md), because the two version independently.
4
4
 
5
+ ## 1.3.0 (2026-08-31)
6
+
7
+ ### Added
8
+
9
+ - **Five fields take a `hotKeys` map.** `PlTextField`, `PlNumberField`, `PlOtpField`, `PlCombobox` and `PlSelect` now bind chords — `hotKeys` takes `{ 'Mod+Enter': save, Escape: cancel }`. What makes it worth a prop rather than an `onKeyDown` — which those five already took and still take — is that the chord is spelled **the way a key cap is spelled**, in the vocabulary [`PlHotKeys`](https://plass.cdget.com/components/display/hot-keys) draws: `Mod` resolves per platform, and `Esc`, `Return`, `Cmd` and `Option` fold onto the same keys their caps do. A shortcut a component displays and a shortcut it binds are now one string rather than two that can drift, which is the argument `PlCommandPalette` made when it bound its own opener — it carried a private copy of the matcher to make it, and that copy is now `internal/keys.ts` with `PlHotKeys` reading its alias table and its platform out of the same file. Three rules hold everywhere: the map sits on the **control** rather than on the stack around it, so a chord is answered by the thing that has the focus; a modifier is checked in **both** directions, so `Enter` does not fire on `Shift+Enter`; and a chord that matches is **consumed** — not reaching the form, the dialog above it, or the browser. Which is why these are chords rather than letters: a field with `{ a: … }` cannot type an `a`. A caller's own `onKeyDown` still runs first and can overrule the map by calling `preventDefault()`. The vocabulary also grew one alias, `NumpadEnter`, so the long spelling reaches the same key its cap does.
10
+
11
+ - **A `PlDatePicker` can stop at a month or a year.** `precision` is `'day'`, `'month'` or `'year'`, and it is a _floor_: the calendar opens on the grid for that unit and pressing a cell in it answers, so a `month` picker's month grid is the last grid and there is no day grid under it at all. That last part is the point rather than a side effect — a card's expiry is a month, and a control that makes someone answer _which day of December 2027_ is a control that will be answered wrongly. The value stays a `Date`, normalised to the start of what was chosen: the 1st of the month, or the 1st of January, never whichever day or month the cursor happened to be resting on when the year was pressed. Three things follow it without being asked for — the trigger's default `format`, the hidden input's spelling (`YYYY-MM-DD`, then `YYYY-MM` and `YYYY`, which is what a native `<input type="month">` submits), and the footer's shortcut, which reads "This month" or "This year" rather than "Today" and brings two new `labels` entries with it. `minDate` and `maxDate` are then read **at the same precision**: a `minDate` of 15 July leaves July pickable on a `month` picker and hands back 1 July, because a bound on a control that returns a month is a bound on months. `shouldDisableDate` is day-granular and is not consulted at all.
12
+
13
+ - **`PlVisuallyHidden`.** Content for a screen reader and for nobody else — the rule the library already applies inside a dozen of its own components, spelled once for the caller's own markup. The two obvious ways to hide something are both wrong in the same place: `hidden` and `display: none` take the text off the accessibility tree along with the screen, which is the one thing this exists to avoid, and `opacity: 0` leaves a clickable ghost the size of the words. A one-pixel clipped box is the only form that is absent to a sighted reader and present to every other kind. The ordinary use is naming a control whose whole label is a glyph — mark the glyph `aria-hidden`, or the control ends up with two names — and the other is a live region, which is a `<div>` with an `aria-live` and nothing to draw. `focusable` puts the box back in the flow while anything inside it holds the focus: that is the skip link, and it is the one variation a caller cannot add from outside, because the clip is `position: absolute` and revealing it means making the element `static` again. It answers `:focus-within` rather than `:focus`, since what is tabbed to is almost always the link _inside_ the box rather than the box itself. It is **React-only**, and deliberately: what it works around is a DOM problem, and Flutter's answer is `Semantics` with an `ExcludeSemantics` under it rather than a widget of ours.
14
+
15
+ - **The media query machinery is public.** `usePlMediaQuery`, `usePlBreakpoint` and `usePlBreakpointValue` are the store a `PlSidebar` has always used to find out that it has become a drawer, given names — new surface rather than new code, which is why they arrive together. `usePlMediaQuery` takes any query and returns a boolean that re-renders when the answer changes; the other two are the same store asked about the ladder, and `usePlBreakpointValue` resolves the **same map shape** a responsive prop on `PlGrid` takes, with the same rule — a bare value applies everywhere, a map applies each entry from its own breakpoint up, and it is `undefined` below every rung the map named rather than a guess at one the caller did not write. The widths are Tailwind's own, and they are asked as media queries rather than measured off `innerWidth`: the ladder is written in `rem`, so a reader who has enlarged their default font size would otherwise get a rung that disagrees with the stylesheet beside it. **The first answer in a browser is the server's answer** — `false`, and `xs` — because `useSyncExternalStore` renders its server snapshot through hydration, which is exactly why the library's own components pair the hook with a CSS class rather than replacing one with the other. Anything that must be right in the first frame belongs in a Tailwind variant; these are for the decisions CSS cannot make, like whether a component is mounted at all. One `MediaQueryList` is now shared per query string across the whole page, where `useCollapsed` used to open one per component. They are exported from the barrel and from a new **`plass-ui/hooks`** subpath, and the documentation has a `Hooks` section to put them in.
16
+
17
+ - **`usePlReducedMotion`.** The preference the library has always answered on its own behalf, given a name. `prefers-reduced-motion: reduce` is easy to typo and the mistake is silent, which is most of the argument for a hook over a query string. The other part is what the documentation can now say in one place: **"reduced" is not "none"**, and the library's own components disagree with each other on purpose — an entrance is dropped entirely, because an animation that never played has still delivered everything it was carrying, while a `PlProgressCircular` is _slowed_ rather than stopped, because a spinner that stopped would be lying about whether anything is still happening. The store moved with it: `internal/animate.ts` no longer keeps a `matchMedia` of its own, and the query is one more subscription shared through `internal/media.ts` like every other.
18
+
19
+ - **`usePlHotKeys` binds a chord outside any one control.** The `hotKeys` prop added in this cycle put the vocabulary on a field; this puts it on the page, which is where an application's own shortcuts live and which `PlCommandPalette` has needed since it existed — it carried a private window listener to bind its opener, and now calls the hook like anybody else. The three rules come with it: a modifier is checked in **both** directions, a chord that matches is **consumed**, and — new, and true of the prop as well — an event that is _already_ consumed is left alone, so a field's binding wins over a page's. The interesting default is `whileTyping: false`, and it is narrower than the name suggests: a chord carrying `Mod`, `Ctrl`, `Meta` or `Alt` is answered in a field anyway, because none of them can appear in its value, and so is a key that does nothing to text — `Escape` above all, since a panel that closes on Escape has to close from inside its own form. What is held back is a printable character or one of the keys that edits or moves through text, which is exactly the case worth holding back: a global `/` must not eat the slash out of a URL somebody is typing. Handlers are read fresh on every keystroke, so the map may be written inline and a handler closing over current state is never stale; what re-attaches the listener is the **set of chords** rather than the object's identity. `target` scopes the binding to an element or a ref, and `enabled: false` removes the listener rather than muting the handler — a shortcut that is off should not consume the key from whatever else wanted it.
20
+
21
+ - **`PlCalendar`.** The grid a `PlDatePicker` opens, on the page. It is not a new calendar — it is the same `internal/calendar.tsx` the four pickers already share, with the trigger and the popup taken away, which is why it arrives with the three views, the roving tab stop and the arrow keys that step the month when they run off an edge already finished. The reason to have both is what each one _is_: a picker is a **field** that happens to open a calendar and belongs in a form beside other fields, and this is a calendar that is not standing in for a field — a booking page, an availability view, a date rail — where the grid is the interface rather than a way of filling one in. So it has no `label`, `description` or `error`, and it keeps `name`, so a plain form can still submit what it holds. `precision` is the same **floor** the picker's is, and the value is normalised to the start of what was chosen. Two props are deliberately absent: there is no `density`, because padding on a grid of forty-two squares is what stops them being squares, and no `readOnly`, because a read-only field still shows a value a reader can select and copy while a calendar has nothing to copy — a grid whose every cell is inert _is_ the disabled one, and `disabled` draws it with the `inert` attribute rather than with a `disabled` on forty-two cells. `autoFocus` is **off**, the opposite of the picker's: a popup has just been opened by somebody who wants to be in it, and a calendar in a page has not.
22
+
23
+ - **`PlassProvider` sets the defaults once.** Sixty-six components resolved `size`, `color` and `density` from a literal in their own destructuring, which meant an application whose controls are `sm` said so at every call site — not a design decision, transcription. They now resolve from the nearest provider instead, in four layers and in the order a reader would guess: **the component's own prop, then whatever set it is in, then the provider, then the component's own default**. So a `size="lg"` on one button still wins inside a `PlButtonGroup` inside a compact application. Providers nest and **merge**, so a section that says only `density` keeps the `locale` from the one above it. The date vocabulary comes with it — `locale`, `weekStartsOn` and `labels` reach all five date components and `PlNumberField`, and `labels` merges _under_ each component's own so an application can translate the set once and one picker can still say something different.
24
+
25
+ **`variant` and `elevation` are deliberately not in it**, and the absence is the load-bearing part. `variant` names what a surface is made of, and a `PlButton` is `solid` while a `PlCard` is `glass` because that is the arrangement rather than an unset default; `elevation` is per-component semantics for the same reason, a control resting **on** the sheet at `1` and a field cut **into** it at `0`. One value for either would not be a default, it would be a flattening. `usePlassDefaults()` reads what is in scope, for a caller's own component that has to line up with the ones around it.
26
+
27
+ **`PlTable` is the one component that does not read it**, and stays the one exception it already was: reading a React context would make it a client component, and it is kept out of that graph on purpose, because every one of its columns is a `render` callback and a server component cannot hand a function across the boundary. A new package test asserts the contract from both ends — that a provider produces byte-identical markup to writing the prop, on fourteen components, and that no component takes a style axis without reading the defaults.
28
+
29
+ **What it costs**, measured with `npm run size` — a real esbuild bundle of `dist/`, gzipped, React external: **+0.1 kB on a five-component form and +1.9 kB on the whole library**. That is one `useContext` per component plus the resolution lines, and it is paid whether or not a provider is ever rendered, because the read is unconditional. A single `PlButton` is unchanged to the tenth of a kilobyte.
30
+
31
+ - **`usePlColorScheme` and `PlColorSchemeScript`.** Dark mode already worked — the tokens answer `prefers-color-scheme` and can be forced with `.dark` or `[data-theme]` on any ancestor — and what was missing was everything around a **choice**: somewhere to keep it, something to write it onto `<html>`, and a way to paint it before the first frame. The hook is the first two. `system` is deliberately the absence of a choice rather than a third theme: it removes the attribute and hands the question back to the platform, so a reader who picks it goes back to following their computer rather than being pinned to whatever their computer said at that moment. `toggle` flips from what is **painted**, so the first press on a system-dark page gives light, which is what pressing a toggle means. It writes the attribute **and** the class, and that is not belt and braces: the attribute is what this library's tokens read, and the class is what a consumer's own Tailwind `dark:` utilities read when they are configured against a class — a toggle that moved one and not the other would leave a page half switched. Two toggles on one page share one store and agree with each other, and a second tab that changes the scheme changes this one, because the choice is one the reader made about themselves rather than about a window.
32
+
33
+ `PlColorSchemeScript` is the third, and it is the one that has to be a **server component**: React runs after the document is parsed, so a theme applied from an effect is applied one paint too late and the reader has already seen white. It goes in `<head>`, renders nothing but an inline `<script>`, calls no hook and reads no context — a client component here would arrive with the bundle and be too late by definition. `suppressHydrationWarning` on `<html>` is the other half and is not a workaround: the script's whole job is to change that element before React hydrates.
34
+
35
+ The stylesheet gained one declaration with them: **`color-scheme`**, stated per theme block. Scrollbars, the caret, a native `<select>` popup and a date input's own calendar are the browser's to paint and none of them is ours to style — they were white on a page forced to dark, which reads as broken rather than themed.
36
+
37
+ - **`PlConfirmProvider` and `usePlConfirm`.** `await confirm({ title: 'Delete this project?', color: 'danger' })` resolves with the answer, so the branch after a question stays in the handler that asked it. The argument for a hook rather than a component is the same one `PlToastProvider` made: what a caller has at the moment a question is warranted is a **click handler**, not a place in the tree — and without this, adding a confirmation to one button means a piece of state, a `<PlModal>` kept mounted beside it, and the work after the answer torn in half across a callback, repeated at every button that needs one. `alert` is the one-button form and resolves when it has been acknowledged, which is what makes it awaitable in the middle of a sequence.
38
+
39
+ Three decisions worth stating. **Cancel holds the focus by default**: a confirm dialog exists to make somebody stop, and an Enter key that lands on the destructive action defeats the whole thing — `initialFocus: 'confirm'` moves it for a question whose yes is the harmless answer. **Questions asked while one is open are queued**, in order, with the sheet's content changing rather than the dialog closing and reopening; the alternative is a promise nobody ever resolves, which is a hung button rather than a visible bug, and a provider that unmounts with questions outstanding resolves them all `false` for the same reason. And **`usePlConfirm` throws outside a provider** rather than answering `false`, because a silent `false` is a delete button that quietly does nothing, which is worse than a missing provider that says so on the first press.
40
+
41
+ - **`PlStepper` and `PlStep`.** A process the reader is moving through, and where they are in it. It draws the same rail a `PlTimeline` does — and _shares_ it: the bullet ladder, the three states, the connector and the status arithmetic moved into a new `internal/steps.ts` that both components read, because a haloed bullet must not mean two things and two copies of twelve lines are two copies that drift. What differs is what each one is for, which is also the whole of when to reach for which: a timeline **reports** a sequence that already happened and nothing on it can be pressed; a stepper **is** the sequence, its steps are buttons and the current one owns a panel.
42
+
43
+ `active` is an **index** rather than a value, exactly as a timeline's is, because a stepper has no selection. `linear` is on by default — the third step of a sign-up cannot be filled in before the second — while a step _behind_ the reader is always reachable, since going back to correct an answer is the whole reason a stepper is not a wizard with one door. Horizontal puts the panel under the rail and **vertical puts each panel inside its own step**, which is the reason to lay one out vertically at all. `status` overrides where the sequence says a step is, for the one that failed validation while the reader was three steps on. And it is deliberately **not** a `role="tablist"`: a tab list owes a keyboard reader one tab stop and arrow keys, and claiming the role without the behaviour is worse than never claiming it — each reachable step is its own tab stop, and a step nobody has reached yet is not a button at all rather than a disabled one.
44
+
45
+ - **`PlTree`.** A hierarchy opened one branch at a time. It takes its nodes as **data** rather than as children — the opposite of most of this library, and the right way round here for one reason: a tree is recursive, and recursion written in JSX is a component every caller has to write for themselves. `PlTable` takes its columns the same way and for the same reason.
46
+
47
+ `expanded` and `selected` are separate arrays and separate questions, because opening a folder is not choosing it. `selection` is `single` by default, `multiple` says so with `aria-multiselectable`, and `none` makes the tree a **browser** rather than a chooser — rows still expand and a click still reports, but nothing stays lit. **`children: []` and `children: undefined` are different things**, visibly: the first is a branch that opens and shows nothing, the second is a leaf with no twisty at all, which is what makes a lazily-loaded tree possible. The keyboard is the ARIA tree pattern and is most of what makes this a tree rather than a nested list — **one tab stop** for the whole thing, following the focus rather than leading it; ↓/↑ walking the rows that are actually visible; → opening a branch and _then_ stepping into it, two presses rather than one, so a reader can open a branch without leaving the row that told them it was there; ← closing it or stepping out to the parent.
48
+
49
+ - **`PlImage`.** An `<img>` is one tag and it works, so this says what it adds rather than assuming it. Three things: the space is **reserved** before the picture arrives, so the paragraph under it does not move when it does — that is `ratio`, and it is the prop worth reaching for every time, because without it there is nothing to reserve; a failure is **drawn** rather than left as the browser's broken-image glyph and the alt text in a serif nobody chose; and the two are **one state machine**, so a placeholder is never still sitting behind a picture that has loaded, and a changed `src` starts again rather than inheriting the last one's success. The `<img>` stays in the document the whole time, because an `<img>` that is not in the document never loads. `alt` is required and `""` is a real answer rather than a missing one. `preview` opens the picture over the page in a `PlOverlay` and is off by default — a picture that grows when you click it is a promise that there is more of it to see, and most pictures on a page are not making it. There is no gallery component and no next/previous inside the preview, deliberately: a gallery is a list with a state of its own, and it composes out of what is already here.
50
+
51
+ - **`PlEmpty`.** An empty list, a search that found nothing, a request that failed and a flow that has finished are the **same arrangement** — a mark, a line, a sentence, a way out — which is why they are one component and not four, and why `color` is what tells them apart: `secondary` is "nothing here yet", `danger` is "something went wrong", and `success` is "you are done", which makes the order-confirmed screen without a second component. It draws **no surface**: an empty state is always inside a card, a table or a panel, and a sheet inside a sheet is two sheets — `PlTable`'s `empty` prop takes a node, and this is the node it was waiting for. The part worth getting right is the way out, and it is the reason `actions` is a slot rather than an afterthought: a screen that says "No projects" and stops is a dead end, and the same screen with a "New project" button is the best moment in the whole flow to offer one. It has **no role of its own**, deliberately — `role="status"` belongs on it when the emptiness is the _result_ of something the reader just did, and not on a list that was already empty when the page loaded and has therefore already been read.
52
+
53
+ - **`PlPopconfirm`.** A question asked where it was raised. The difference from `PlConfirmProvider` is not the words, it is **how much it interrupts** — a modal takes the page away and is right for the question that deserves that, and this appears against the row's own delete button, leaves the rest of the table readable, and puts a reader who changes their mind back exactly where they were. The rule of thumb is what happens if they answer by accident: if they can undo it, this is the one. `color` defaults to `danger` here and to `primary` on a `PlButton`, and that is not an inconsistency — nobody reaches for a popconfirm to ask whether to save.
54
+
55
+ `onConfirm` may return a **promise**: the button shows its loading state until it settles, the popup closes only if it _resolves_, and Escape is ignored while it runs, because a request in flight is not something to abandon halfway. A rejection is caught and goes no further, and that is a decision rather than an omission — keeping the question on screen is the whole of what this component owes a failure, and what the failure _means_ belongs to the caller who returned the promise and has the context to raise a toast about it. The focus lands on the **confirming** button, the other way round from the modal and deliberately: a popconfirm is opened _by_ the button it is asking about, so the reader has already said what they want once.
56
+
57
+ - **`PlBackTop`.** The way back up, once there is a way back up to want. It is **hidden until it is useful**, and that is the whole design rather than a nicety: a button pinned to the corner of every page from the first paint is one more thing covering the content, and on a page short enough not to scroll it is a control that does nothing. While it is out of reach it is `aria-hidden` and out of the tab order rather than merely faded — a control a reader can tab to and cannot see is worse than one that is not there. `target` takes a ref, so a panel that scrolls inside the page gets one of its own, and `floating={false}` keeps the appearing and the scrolling while giving up the corner. The scroll is smooth and **not** under `prefers-reduced-motion`: a page that flies past a reader who asked for less movement is the exact case that setting exists for, so it jumps instead and arrives in the same place. The position is read once on mount as well as on every scroll, so a page restored halfway down — a back navigation, an anchor in the URL — has the button already there.
58
+
59
+ - **`PlStat`.** One figure, and what has happened to it. A row of these is the top of every dashboard, and the whole of what makes them worth a component rather than three `<div>`s is the **change**: a number on its own says what things are, and a number with a movement beside it says whether that is going anywhere.
60
+
61
+ The colour of that movement is decided by `improvesWhen` and **not by the sign**, which is the one thing a naive version of this gets wrong — churn going up is not good news, and a green arrow on it is a dashboard lying to somebody. `value` takes a **node** rather than a number, deliberately: how a figure is written — the currency, the grouping, the decimals, the locale — is the page's decision and `Intl.NumberFormat` already makes it, so a component that took a number would have to guess at all four. The arrow is `aria-hidden` and the sign is in the text, so colour is never the only thing carrying the direction.
62
+
63
+ - **A `PlPopconfirm`'s two buttons wrap.** They sat in a row that could not break, so a pair of labels translated into anything longer than "Confirm" and "Cancel" ran off the 280px sheet. Found while porting the component to Flutter, where the same arrangement is a layout error rather than a quiet overflow.
64
+
65
+ ### Fixed
66
+
67
+ - **`dir="rtl"` turned the layout over and left the behaviour behind.** Base UI reads the writing direction from a **React context** and from nowhere else: with no `DirectionProvider` in the tree its `useDirection()` answers `ltr` however the document is written. That decides a `PlSlider`'s arrow keys, the way ←/→ walk a `PlTabs`, a `PlMenubar` or a `PlRadioGroup`, and which physical edge a popup's logical `align` resolves to — so a right-to-left page that set the attribute and stopped **looked** right and **behaved** left to right. Proved with a test before it was believed: `ArrowRight` on a slider at 40 answered 45 in both directions.
68
+
69
+ `PlassProvider` now renders that context, and takes the answer **off the document** rather than from a prop — `getComputedStyle(document.documentElement).direction`, watched with one `MutationObserver` for the whole page. A second place to declare the direction is a second place to get it wrong, and the page has already said it. The new `direction` prop is only for the case the document cannot answer: a subtree that runs the other way round from the page it is in, or a server that knows before there is a document to ask. It merges through nested providers like every other default.
70
+
71
+ The cost is **+0.3 kB gzipped** on the everything-imported scenario and nothing at all on the four narrower ones, because the provider is only ever reached through the barrel.
72
+
73
+ - **A `PlAnimateMarquee` delivered its words backwards under RTL.** The strip's flex track had already reversed on its own, and the animation had not — there is no logical `translate`, so the keyframe was still travelling towards the physical left and running the content off the wrong edge. The sign is now a custom property that `[dir='rtl']` flips, which makes it the one right-to-left rule in the library that lives in the stylesheet; the test for it loads the shipped sheet, because no component test loads CSS.
74
+
75
+ - **Three components ran the wrong way under RTL.** The library has always been written in logical properties, and that turned out to be the easy half — what nobody had was a test, so the three places the rule had been broken had been broken quietly. A **`PlPanes`** handle nudged with the arrow keys moved the boundary _away_ from the key it was pressed with: the drag path read the writing direction and the keyboard path did not, which made the component page's own claim that "the arrow keys follow the writing direction, exactly as a drag does" false. A **`PlSwitch`**'s thumb travelled on `left`, so under RTL it sat at the wrong end of its track and moved the wrong way — every platform's own switch puts off at the inline start, which is the right-hand end. And a **`PlCard`**'s `headerAction` was pushed out with `ml-auto`, landing it on the left of a right-to-left header. `PlDivider`'s vertical rule moved to `border-inline-start` with them; it drew identically either way, and now it is spelled the way everything else is.
76
+
77
+ The test that found them is `test/package/rtl.test.tsx`, and it is a contract test rather than a component one for the reason the contract is: RTL is not a feature any component has, it is a rule every component follows, and it breaks one component at a time in a class name nobody looked at twice. It drives a real `dir="rtl"` document for the parts that are decided in JavaScript, and reads every component's source for a physical direction utility that is not on a short list of deliberate exceptions — each of which is a place where the **thing being measured** is physical too (`offsetLeft` for a moving indicator, Base UI's own `data-side` for a tooltip arrow, `PlassSide` for a drawer's edge). Pairing a logical property with a physical measurement is what would actually break the direction.
78
+
79
+ ### Documentation
80
+
81
+ - **[Right to left](https://plass.cdget.com/design/rtl) is a page.** The support was there and undocumented, which is nearly the same as not having it: a reader evaluating the library had no way to find out. It says what the one-attribute setup is, what flips and what deliberately does not, and names the three places the direction is read in JavaScript and why each one has to be.
82
+
83
+ ## 1.2.0 (2026-08-30)
84
+
85
+ ### Added
86
+
87
+ - **Every component that draws something now takes a `className` and a `style`.** Six did not, and each for its own reason rather than by decision: `PlCommandPalette`'s prop type is closed because it renders a portalled dialog rather than an element in the caller's tree, `PlMenubarMenu` and `PlNavigationMenuItem` describe a row that their parent draws, `PlMenuGroup` and `PlMenuRadioGroup` had the class and not the style, and a toast has no element to put either on — it is raised from a click handler. The first four take both on the element a reader would point at: the palette's sheet, the word on the bar, the word in the row. A toast takes them in the same `data` its colour and its variant already travel in, so `toast.add({ title, className })` reaches the one message rather than every message the provider will ever show. In all six the class **joins** the component's own rather than replacing them, and the style is applied **over** the custom properties the component wrote, which is the arrangement the rest of the library already had.
88
+
89
+ - **The `--plass-*` tokens are a typed channel.** Every one of them was already settable in an inline `style` — they are ordinary custom properties, and an inline declaration beats every class there is — but a `'--plass-radius-md'` written into a `style` object was a TypeScript error before it was anything else, because React's `CSSProperties` has no index signature. Importing the package now widens it to accept any `--plass-*` key and nothing else, so a typo in some other custom property is still a typo. This is the channel that matters most, and not as a convenience: the library writes its edge, its shadow, its focus ring and its fill as Tailwind _arbitrary properties_, Tailwind sorts those **last** in the generated stylesheet, and an ordinary utility appended after one loses on order whatever it says — while the token underneath it does not. It also cascades, which a `className` cannot: one declaration on a wrapping `<div>` and every Plass component inside it answers. `PlassToken` names all 108 of them and `PlassTokens` is the stricter form for a set of overrides written once, where a name that is not a token fails to compile. A new package test reads `styles.css` and the type as text and fails if either grows a token the other does not have.
90
+
91
+ - **A field's four parts are reachable.** Twelve labelled controls — `PlTextField`, `PlSelect`, `PlCombobox`, `PlNumberField`, `PlOtpField`, `PlCheckbox`, `PlSwitch`, `PlRadioGroup` and the four pickers — put a `className` on the _stack_: the wrapper holding the label, the control and the two lines of text under it. That is the right element to position and size a field with, and the wrong one for everything else a caller reaches for, which until now had nowhere to go. `classNames` names the four parts inside it: `label`, `control`, `description` and `error`.
92
+
93
+ **`control` is the one that matters.** It is the box a `PlTextField` is typed into, the button a `PlSelect` opens, the tick, the track, the run of radios, the trigger a picker's calendar hangs off — the part a reader acts on, and the part almost every override was aimed at. The other three are named because a field that has a label at all has three pieces of text with three different jobs, and "the red one under the box" is not addressable any other way. A `PlRadio` inside a group is deliberately not in the list: it is a row rather than a field, and its own `className` already lands on it.
94
+
95
+ - **A portalled surface's backdrop is reachable.** `PlModal`, `PlDrawer`, `PlOverlay` and `PlCommandPalette` each draw two elements into the portal, and a `className` could only ever land on one of them — the sheet, the panel, the popup, which is what a reader points at and calls the component. The scrim behind it had nothing at all. `classNames.backdrop` is that second element, and it is a **second prop rather than a second meaning for the first**: a component's own surface keeps one way of being addressed, so there is never a question of which of the two wins. An inline `PlDrawer` draws no scrim and simply has nowhere for the class to go, which is the one case where passing it does nothing.
96
+
97
+ ### Documentation
98
+
99
+ - **The styling contract is written down.** [Prop conventions](https://plass.cdget.com/design/prop-conventions#styling-a-component-from-outside) now has the four channels in the order to reach for them, and — the part that was not documented anywhere — **where a plain `className` loses**. The order of two classes in an attribute means nothing; what decides is their order in the generated stylesheet, and Tailwind sorts by _name_, numeric scales ascending and everything else alphabetically. So `text-lg` loses to a `size="sm"` field's `text-sm`, `bg-red-500` loses to a `ghost` button's `bg-transparent`, `w-auto` loses to `fullWidth`, and nothing at all beats an arbitrary property. The page says so with the measured table rather than with advice, and gives the two ways out: a token, or the `!` modifier, which always works because the library carries no `!important` of its own. Which stylesheet was imported changes the answer too, and that is a table as well.
100
+
101
+ - **`Getting started` overpromised what Tailwind's sort decides.** On the `plass-ui/tailwind.css` path it said that a `className` passed to a component "sorts correctly against the component's own classes", which reads as _the caller's class wins_ — and it does not. Tailwind sorts utilities by name, so a `text-lg` is emitted **before** a `size="sm"` field's `text-sm` and loses to it on order. The line now says what the sort actually settles, and points at the table that spells out the rest.
102
+
5
103
  ## 1.1.0 (2026-08-30)
6
104
 
7
105
  ### Added
@@ -1 +1 @@
1
- "use client";import{jsx as e,jsxs as t}from"react/jsx-runtime";import*as l from"react";import{Accordion as s}from"@base-ui/react/accordion";import{ChevronIcon as a}from"../../internal/icons.js";import{focusRingClasses as n,focusRingInsetClasses as i,gapClasses as r,hasContent as d,iconClasses as o,metaTextClasses as c,radiusClasses as m,sheetBodyClasses as p,sheetHeaderGapClasses as f,sheetPaddingXClasses as u,sheetPaddingYClasses as x,sheetRestClasses as h,sheetTitleClasses as v,surfaceSlots as b,transitionClasses as g}from"../../internal/styles.js";const N=/* @__PURE__ */l.createContext({size:"md",density:"default",dividers:!0}),j={xs:m.xs,sm:m.xs,md:m.sm,lg:m.sm,xl:m.md},y={default:{xs:"pt-1.5",sm:"pt-2",md:"pt-3",lg:"pt-3.5",xl:"pt-4"},compact:{xs:"pt-1",sm:"pt-1.5",md:"pt-2",lg:"pt-2.5",xl:"pt-3"}},w={default:{xs:"pb-2.5",sm:"pb-3",md:"pb-5",lg:"pb-6",xl:"pb-7"},compact:{xs:"pb-2",sm:"pb-2.5",md:"pb-3.5",lg:"pb-4",xl:"pb-5"}};export const PlAccordion=/* @__PURE__ */l.forwardRef(function PlAccordion({variant:t="glass",size:a="md",color:n="primary",density:i="default",elevation:r=0,multiple:d=!1,value:o,defaultValue:c,onValueChange:p,dividers:f=!0,disabled:u=!1,hiddenUntilFound:x=!1,keepMounted:v=!1,className:j,style:y,children:w,...$},P){const k=l.useMemo(()=>({size:a,density:i,dividers:f}),[a,i,f]),A=["flex flex-col",m[a],h[t],g,f?"overflow-hidden [&>div+div]:border-t [&>div+div]:[border-color:var(--plass-divider)]":"p-1",j??""].filter(Boolean).join(" ");return e(N.Provider,{value:k,children:e(s.Root,{ref:P,multiple:d,value:o,defaultValue:c,onValueChange:e=>p?.(e),disabled:u,hiddenUntilFound:x,keepMounted:v,className:A,style:{...b(n,r),...y},...$,children:w})})});export const PlAccordionItem=/* @__PURE__ */l.forwardRef(function PlAccordionItem({value:m,title:h,subtitle:b,startIcon:$,action:P,truncate:k=!1,disabled:A=!1,className:z,children:C,...I},V){const{size:_,density:B,dividers:M}=l.useContext(N),R=u[B][_],F=x[B][_],U=k?"truncate":"";return t(s.Item,{ref:V,value:m,disabled:A,className:["flex flex-col",z??""].filter(Boolean).join(" "),...I,children:[t(s.Header,{className:"m-0 flex w-full items-center [font:inherit]",children:[t(s.Trigger,{className:["flex min-w-0 flex-1 cursor-pointer items-center text-start",R,F,r[_],g,o,M?i:`${n} ${j[_]}`,"hover:bg-(--p-soft)","data-[panel-open]:bg-(--p-soft) data-[panel-open]:text-(--p-accent)","disabled:cursor-not-allowed disabled:bg-transparent disabled:opacity-50"].filter(Boolean).join(" "),children:[d($)?e("span",{className:"flex h-[1lh] shrink-0 items-center text-(--plass-muted-fg)",children:$}):null,t("span",{className:`flex min-w-0 flex-1 flex-col ${f[_]}`,children:[d(h)?e("span",{className:`plass-title font-semibold ${U} ${v[_]}`.trim(),children:h}):null,d(b)?e("span",{className:`text-(--plass-muted-fg) ${U} ${c[_]}`.trim(),children:b}):null]}),e("span",{className:["flex h-[1lh] shrink-0 items-center text-(--plass-muted-fg)","[transition:rotate_var(--plass-duration)_var(--plass-ease)]","data-[panel-open]:rotate-180"].join(" "),children:e(a,{})})]}),d(P)?e("span",{className:`flex shrink-0 items-center ${R}`,children:P}):null]}),e(s.Panel,{className:["h-(--accordion-panel-height) overflow-hidden","[transition:height_var(--plass-duration-slow)_var(--plass-ease)]","data-[starting-style]:h-0 data-[ending-style]:h-0"].join(" "),children:e("div",{className:["text-(--plass-muted-fg)",p[_],R,y[B][_],w[B][_]].join(" "),children:C})})]})});
1
+ "use client";import{jsx as e,jsxs as t}from"react/jsx-runtime";import*as l from"react";import{useDefaults as s}from"../../internal/defaults.js";import{Accordion as a}from"@base-ui/react/accordion";import{ChevronIcon as n}from"../../internal/icons.js";import{focusRingClasses as i,focusRingInsetClasses as r,gapClasses as o,hasContent as d,iconClasses as c,metaTextClasses as m,radiusClasses as p,sheetBodyClasses as f,sheetHeaderGapClasses as u,sheetPaddingXClasses as x,sheetPaddingYClasses as h,sheetRestClasses as v,sheetTitleClasses as b,surfaceSlots as g,transitionClasses as N}from"../../internal/styles.js";const j=/* @__PURE__ */l.createContext({size:"md",density:"default",dividers:!0}),y={xs:p.xs,sm:p.xs,md:p.sm,lg:p.sm,xl:p.md},w={default:{xs:"pt-1.5",sm:"pt-2",md:"pt-3",lg:"pt-3.5",xl:"pt-4"},compact:{xs:"pt-1",sm:"pt-1.5",md:"pt-2",lg:"pt-2.5",xl:"pt-3"}},$={default:{xs:"pb-2.5",sm:"pb-3",md:"pb-5",lg:"pb-6",xl:"pb-7"},compact:{xs:"pb-2",sm:"pb-2.5",md:"pb-3.5",lg:"pb-4",xl:"pb-5"}};export const PlAccordion=/* @__PURE__ */l.forwardRef(function PlAccordion({variant:t="glass",size:n,color:i,density:r,elevation:o=0,multiple:d=!1,value:c,defaultValue:m,onValueChange:f,dividers:u=!0,disabled:x=!1,hiddenUntilFound:h=!1,keepMounted:b=!1,className:y,style:w,children:$,...P},k){const z=s(),A=n??z.size??"md",C=i??z.color??"primary",I=r??z.density??"default",V=l.useMemo(()=>({size:A,density:I,dividers:u}),[A,I,u]),_=["flex flex-col",p[A],v[t],N,u?"overflow-hidden [&>div+div]:border-t [&>div+div]:[border-color:var(--plass-divider)]":"p-1",y??""].filter(Boolean).join(" ");return e(j.Provider,{value:V,children:e(a.Root,{ref:k,multiple:d,value:c,defaultValue:m,onValueChange:e=>f?.(e),disabled:x,hiddenUntilFound:h,keepMounted:b,className:_,style:{...g(C,o),...w},...P,children:$})})});export const PlAccordionItem=/* @__PURE__ */l.forwardRef(function PlAccordionItem({value:s,title:p,subtitle:v,startIcon:g,action:P,truncate:k=!1,disabled:z=!1,className:A,children:C,...I},V){const{size:_,density:B,dividers:M}=l.useContext(j),R=x[B][_],F=h[B][_],U=k?"truncate":"";return t(a.Item,{ref:V,value:s,disabled:z,className:["flex flex-col",A??""].filter(Boolean).join(" "),...I,children:[t(a.Header,{className:"m-0 flex w-full items-center [font:inherit]",children:[t(a.Trigger,{className:["flex min-w-0 flex-1 cursor-pointer items-center text-start",R,F,o[_],N,c,M?r:`${i} ${y[_]}`,"hover:bg-(--p-soft)","data-[panel-open]:bg-(--p-soft) data-[panel-open]:text-(--p-accent)","disabled:cursor-not-allowed disabled:bg-transparent disabled:opacity-50"].filter(Boolean).join(" "),children:[d(g)?e("span",{className:"flex h-[1lh] shrink-0 items-center text-(--plass-muted-fg)",children:g}):null,t("span",{className:`flex min-w-0 flex-1 flex-col ${u[_]}`,children:[d(p)?e("span",{className:`plass-title font-semibold ${U} ${b[_]}`.trim(),children:p}):null,d(v)?e("span",{className:`text-(--plass-muted-fg) ${U} ${m[_]}`.trim(),children:v}):null]}),e("span",{className:["flex h-[1lh] shrink-0 items-center text-(--plass-muted-fg)","[transition:rotate_var(--plass-duration)_var(--plass-ease)]","data-[panel-open]:rotate-180"].join(" "),children:e(n,{})})]}),d(P)?e("span",{className:`flex shrink-0 items-center ${R}`,children:P}):null]}),e(a.Panel,{className:["h-(--accordion-panel-height) overflow-hidden","[transition:height_var(--plass-duration-slow)_var(--plass-ease)]","data-[starting-style]:h-0 data-[ending-style]:h-0"].join(" "),children:e("div",{className:["text-(--plass-muted-fg)",f[_],R,w[B][_],$[B][_]].join(" "),children:C})})]})});
@@ -1 +1 @@
1
- "use client";import{jsx as s,jsxs as e}from"react/jsx-runtime";import*as l from"react";import{CloseIcon as t,severityIcon as a}from"../../internal/icons.js";import{controlSlots as i,focusRingClasses as r,glassClasses as n,hasContent as o,iconClasses as c,radiusClasses as d,sheetBodyClasses as f,sheetHeaderGapClasses as m,sheetPaddingXClasses as p,sheetPaddingYClasses as u,sheetSectionGapClasses as h,sheetTitleClasses as v,transitionClasses as x}from"../../internal/styles.js";const g={solid:/* @__PURE__ */["text-(--p-on-solid) [background-image:var(--p-fill)]","[box-shadow:var(--p-elev),var(--p-lift)]"].join(" "),glass:/* @__PURE__ */[n,"border text-(--plass-fg) bg-(--plass-glass)","[border-color:var(--p-line)]","[box-shadow:var(--p-elev),var(--plass-gloss-glass)]"].join(" "),ghost:"text-(--plass-fg) bg-(--p-soft)"},b={solid:"",glass:"text-(--p-accent)",ghost:"text-(--p-accent)"},y={solid:"",glass:"text-(--plass-muted-fg)",ghost:"text-(--plass-muted-fg)"},j={primary:"status",secondary:"status",info:"status",success:"status",warning:"alert",danger:"alert"};export const PlAlert=/* @__PURE__ */l.forwardRef(function PlAlert({variant:l="glass",size:n="md",color:N="info",density:w="default",elevation:k=0,title:$,icon:z,action:A,onClose:C,closeLabel:P="Dismiss",className:_,style:B,children:D,...L},R){const q=void 0===z?a(N):z,E=b[l],F=o($);return e("div",{ref:R,role:j[N],className:["flex w-full items-start",p[w][n],u[w][n],d[n],h[n],f[n],x,g[l],c,_??""].filter(Boolean).join(" "),style:{...i(N,k,l),...B},...L,children:[o(q)?s("span",{className:`flex h-[1lh] shrink-0 items-center ${E}`,children:q}):null,e("div",{className:`flex min-w-0 flex-1 flex-col ${m[n]}`,children:[F?s("div",{className:`plass-title font-semibold ${v[n]} ${E}`,children:$}):null,o(D)?s("div",{className:F?y[l]:void 0,children:D}):null]}),o(A)?s("div",{className:"flex h-[1lh] shrink-0 items-center",children:A}):null,C?s("span",{className:"flex h-[1lh] shrink-0 items-center",children:s("button",{type:"button","aria-label":P,onClick:C,className:["inline-flex size-[1.15em] cursor-pointer items-center justify-center rounded-full","opacity-70 [transition:opacity_var(--plass-duration)_var(--plass-ease)]","hover:opacity-100 focus-visible:opacity-100",r].join(" "),children:s(t,{})})}):null]})});
1
+ "use client";import{jsx as s,jsxs as e}from"react/jsx-runtime";import*as l from"react";import{useDefaults as t}from"../../internal/defaults.js";import{CloseIcon as a,severityIcon as i}from"../../internal/icons.js";import{controlSlots as r,focusRingClasses as o,glassClasses as n,hasContent as c,iconClasses as d,radiusClasses as f,sheetBodyClasses as m,sheetHeaderGapClasses as p,sheetPaddingXClasses as u,sheetPaddingYClasses as h,sheetSectionGapClasses as v,sheetTitleClasses as x,transitionClasses as g}from"../../internal/styles.js";const b={solid:/* @__PURE__ */["text-(--p-on-solid) [background-image:var(--p-fill)]","[box-shadow:var(--p-elev),var(--p-lift)]"].join(" "),glass:/* @__PURE__ */[n,"border text-(--plass-fg) bg-(--plass-glass)","[border-color:var(--p-line)]","[box-shadow:var(--p-elev),var(--plass-gloss-glass)]"].join(" "),ghost:"text-(--plass-fg) bg-(--p-soft)"},y={solid:"",glass:"text-(--p-accent)",ghost:"text-(--p-accent)"},j={solid:"",glass:"text-(--plass-muted-fg)",ghost:"text-(--plass-muted-fg)"},N={primary:"status",secondary:"status",info:"status",success:"status",warning:"alert",danger:"alert"};export const PlAlert=/* @__PURE__ */l.forwardRef(function PlAlert({variant:l="glass",size:n,color:w,density:k,elevation:$=0,title:z,icon:A,action:C,onClose:P,closeLabel:_="Dismiss",className:B,style:D,children:L,...R},q){const E=t(),F=n??E.size??"md",G=w??E.color??"info",H=k??E.density??"default",I=void 0===A?i(G):A,J=y[l],K=c(z);return e("div",{ref:q,role:N[G],className:["flex w-full items-start",u[H][F],h[H][F],f[F],v[F],m[F],g,b[l],d,B??""].filter(Boolean).join(" "),style:{...r(G,$,l),...D},...R,children:[c(I)?s("span",{className:`flex h-[1lh] shrink-0 items-center ${J}`,children:I}):null,e("div",{className:`flex min-w-0 flex-1 flex-col ${p[F]}`,children:[K?s("div",{className:`plass-title font-semibold ${x[F]} ${J}`,children:z}):null,c(L)?s("div",{className:K?j[l]:void 0,children:L}):null]}),c(C)?s("div",{className:"flex h-[1lh] shrink-0 items-center",children:C}):null,P?s("span",{className:"flex h-[1lh] shrink-0 items-center",children:s("button",{type:"button","aria-label":_,onClick:P,className:["inline-flex size-[1.15em] cursor-pointer items-center justify-center rounded-full","opacity-70 [transition:opacity_var(--plass-duration)_var(--plass-ease)]","hover:opacity-100 focus-visible:opacity-100",o].join(" "),children:s(a,{})})}):null]})});
@@ -1 +1 @@
1
- "use client";import{jsx as e}from"react/jsx-runtime";import*as t from"react";import{isInfinite as n,lengthValue as a,useAnimationRun as r,usePrefersReducedMotion as i}from"../../internal/animate.js";import{cx as s}from"../../internal/styles.js";export const PlAnimateHeadline=/* @__PURE__ */t.forwardRef(function PlAnimateHeadline({duration:l=460,delay:o=0,easing:u,repeat:c="infinite",paused:m,trigger:d="mount",play:f,once:p=!0,threshold:h=.2,interval:g=2600,index:v,defaultIndex:y=0,onIndexChange:x,loop:E=!0,rise:N="100%",className:j,style:T,children:A,...C},R){const k=r({trigger:d,play:f,once:p,threshold:h,paused:m,infinite:n(c)}),H=i(),I=t.Children.toArray(A),M=I.length,[P,S]=t.useState(y),b=Math.min(v??P,Math.max(M-1,0)),[w,V]=t.useState(null),$=t.useRef(b);t.useEffect(()=>{$.current!==b&&(V($.current),$.current=b)},[b]),t.useEffect(()=>{if(null===w)return;const e=setTimeout(()=>V(null),l);return()=>clearTimeout(e)},[w,l]);const q=t.useCallback(()=>{const e=b+1;if(e>=M){if(!E)return;return void 0===v&&S(0),void x?.(0)}void 0===v&&S(e),x?.(e)},[b,M,E,v,x]),z=t.useRef(!1);return t.useEffect(()=>{if(void 0!==v||M<2||"running"!==k.state)return;if(!E&&b===M-1)return;const e=setTimeout(()=>{z.current=!0,q()},g+(z.current?0:o));return()=>clearTimeout(e)},[v,M,k.state,g,o,q,E,b]),e("div",{ref:e=>{k.ref(e),"function"==typeof R?R(e):R&&(R.current=e)},className:s("plass-headline",j),style:{"--p-anim-duration":`${l}ms`,"--p-anim-rise":a(N),...u?{"--p-anim-ease":u}:{},"--p-anim-state":k.state,...T},"data-plass-animation":"headline","data-state":k.state,...k.handlers,...C,children:I.map((n,a)=>{const r=a===b?"active":a!==w||H?void 0:"leaving";if(!t.isValidElement(n))return e("span",{className:"plass-headline-item","data-state":r,children:n},a);const i=n.props;return t.cloneElement(n,{key:a,className:s("plass-headline-item",i.className),"data-state":r})})})});
1
+ "use client";import{jsx as e}from"react/jsx-runtime";import*as t from"react";import{isInfinite as n,lengthValue as a,useAnimationRun as r}from"../../internal/animate.js";import{usePrefersReducedMotion as i}from"../../internal/media.js";import{cx as s}from"../../internal/styles.js";export const PlAnimateHeadline=/* @__PURE__ */t.forwardRef(function PlAnimateHeadline({duration:l=460,delay:o=0,easing:u,repeat:m="infinite",paused:c,trigger:d="mount",play:f,once:p=!0,threshold:h=.2,interval:g=2600,index:v,defaultIndex:y=0,onIndexChange:x,loop:j=!0,rise:E="100%",className:N,style:T,children:A,...C},R){const k=r({trigger:d,play:f,once:p,threshold:h,paused:c,infinite:n(m)}),H=i(),I=t.Children.toArray(A),M=I.length,[P,S]=t.useState(y),b=Math.min(v??P,Math.max(M-1,0)),[w,V]=t.useState(null),$=t.useRef(b);t.useEffect(()=>{$.current!==b&&(V($.current),$.current=b)},[b]),t.useEffect(()=>{if(null===w)return;const e=setTimeout(()=>V(null),l);return()=>clearTimeout(e)},[w,l]);const q=t.useCallback(()=>{const e=b+1;if(e>=M){if(!j)return;return void 0===v&&S(0),void x?.(0)}void 0===v&&S(e),x?.(e)},[b,M,j,v,x]),z=t.useRef(!1);return t.useEffect(()=>{if(void 0!==v||M<2||"running"!==k.state)return;if(!j&&b===M-1)return;const e=setTimeout(()=>{z.current=!0,q()},g+(z.current?0:o));return()=>clearTimeout(e)},[v,M,k.state,g,o,q,j,b]),e("div",{ref:e=>{k.ref(e),"function"==typeof R?R(e):R&&(R.current=e)},className:s("plass-headline",N),style:{"--p-anim-duration":`${l}ms`,"--p-anim-rise":a(E),...u?{"--p-anim-ease":u}:{},"--p-anim-state":k.state,...T},"data-plass-animation":"headline","data-state":k.state,...k.handlers,...C,children:I.map((n,a)=>{const r=a===b?"active":a!==w||H?void 0:"leaving";if(!t.isValidElement(n))return e("span",{className:"plass-headline-item","data-state":r,children:n},a);const i=n.props;return t.cloneElement(n,{key:a,className:s("plass-headline-item",i.className),"data-state":r})})})});
@@ -1 +1 @@
1
- "use client";import*as e from"react";import{useRender as r}from"@base-ui/react/use-render";import{isInfinite as a,useAnimateElement as i}from"../../internal/animate.js";import{cx as t,radiusClasses as n}from"../../internal/styles.js";export const PlAnimateLighting=/* @__PURE__ */e.forwardRef(function PlAnimateLighting({duration:e=3e3,delay:l=0,easing:o,repeat:s="infinite",alternate:p,paused:m,trigger:d="mount",play:g,once:c=!0,threshold:f=.2,color:u="primary",glow:h,size:y="md",spread:w=3,arc:$=50,blur:b=5,reverse:v=!1,render:x,className:j,style:A,children:L,...N},P){const z=i({effect:null,duration:e,delay:l,easing:o,repeat:s,alternate:p,mode:v?"out":"in",trigger:d,play:g,once:c,threshold:f,paused:m,infinite:a(s)});return r({render:x,ref:[P,z.ref],props:{...N,className:t("plass-anim-lighting",n[y],j),style:{...z.style,"--p-anim-glow-from":h??`var(--plass-${u}-solid)`,"--p-anim-glow-to":h??`var(--plass-${u}-solid-to)`,"--p-anim-glow-width":`${w}px`,"--p-anim-glow-arc":`${$}deg`,"--p-anim-glow-blur":`${b}px`,...A},...z.props,"data-plass-animation":"lighting",children:L}})});
1
+ "use client";import*as e from"react";import{useDefaults as r}from"../../internal/defaults.js";import{useRender as a}from"@base-ui/react/use-render";import{isInfinite as i,useAnimateElement as t}from"../../internal/animate.js";import{cx as n,radiusClasses as l}from"../../internal/styles.js";export const PlAnimateLighting=/* @__PURE__ */e.forwardRef(function PlAnimateLighting({duration:e=3e3,delay:o=0,easing:s,repeat:p="infinite",alternate:m,paused:d,trigger:g="mount",play:c,once:f=!0,threshold:u=.2,color:h,glow:y,size:w,spread:$=3,arc:b=50,blur:j=5,reverse:v=!1,render:x,className:z,style:A,children:L,...N},P){const R=r(),k=h??R.color??"primary",q=w??R.size??"md",B=t({effect:null,duration:e,delay:o,easing:s,repeat:p,alternate:m,mode:v?"out":"in",trigger:g,play:c,once:f,threshold:u,paused:d,infinite:i(p)});return a({render:x,ref:[P,B.ref],props:{...N,className:n("plass-anim-lighting",l[q],z),style:{...B.style,"--p-anim-glow-from":y??`var(--plass-${k}-solid)`,"--p-anim-glow-to":y??`var(--plass-${k}-solid-to)`,"--p-anim-glow-width":`${$}px`,"--p-anim-glow-arc":`${b}deg`,"--p-anim-glow-blur":`${j}px`,...A},...B.props,"data-plass-animation":"lighting",children:L}})});
@@ -1 +1 @@
1
- "use client";import{jsx as e,jsxs as t}from"react/jsx-runtime";import*as r from"react";import{isInfinite as n,useAnimationRun as a,usePrefersReducedMotion as i}from"../../internal/animate.js";import{srOnlyClasses as s}from"../../internal/styles.js";function textOf(e){return"string"==typeof e||"number"==typeof e?String(e):Array.isArray(e)?e.map(textOf).join(""):""}export const PlAnimateTyping=/* @__PURE__ */r.forwardRef(function PlAnimateTyping({text:o,speed:u=24,hold:m=1400,erase:c=!1,eraseSpeed:l,caret:f=!0,caretChar:p="|",duration:d,delay:h=0,repeat:g=1,paused:y,trigger:x="mount",play:T,once:j=!0,threshold:v=.2,className:N,style:S,children:w,...A},M){const O=a({trigger:x,play:T,once:j,threshold:v,paused:y,infinite:n(g)}),I=i(),E=o??textOf(w),P=r.useMemo(()=>function graphemesOf(e,t){return"undefined"!=typeof Intl&&"Segmenter"in Intl?[...new Intl.Segmenter(t,{granularity:"grapheme"}).segment(e)].map(e=>e.segment):[...e]}(E),[E]),R=P.length,[b,C]=r.useState(0),k=r.useRef(0),q=d&&R>0?d/R:1e3/Math.max(u,1),z=1e3/Math.max(l??2*u,1);return r.useEffect(()=>{k.current=0},[R]),r.useEffect(()=>{if(I||0===R)return void C(R);if(!O.started)return k.current=0,void C(0);if(y)return;let e,t=!1,r=k.current,n=1,a=!1;const i="infinite"===g?1/0:Math.max(1,g);if(r>=R&&1===i)return;const step=()=>{if(!t){if(a)return r-=1,k.current=r,C(r),r<=0&&(a=!1,n+=1),void(e=setTimeout(step,a?z:q));if(r+=1,k.current=r,C(r),r<R)e=setTimeout(step,q);else if(!(n>=i)){if(c)return a=!0,void(e=setTimeout(step,m));n+=1,e=setTimeout(()=>{t||(r=0,k.current=0,C(0),e=setTimeout(step,q))},m)}}};return C(r),e=setTimeout(step,0===r?h:q),()=>{t=!0,clearTimeout(e)}},[O.started,y,I,R,q,z,h,m,c,g]),t("div",{ref:e=>{O.ref(e),"function"==typeof M?M(e):M&&(M.current=e)},className:N,style:S,"data-plass-animation":"typing","data-state":O.state,...O.handlers,...A,children:[e("span",{className:s,children:E}),t("span",{"aria-hidden":"true",className:"whitespace-pre-wrap",children:[P.slice(0,b).join(""),f?e("span",{className:"plass-caret",children:p}):null]})]})});
1
+ "use client";import{jsx as e,jsxs as t}from"react/jsx-runtime";import*as r from"react";import{isInfinite as n,useAnimationRun as a}from"../../internal/animate.js";import{usePrefersReducedMotion as i}from"../../internal/media.js";import{srOnlyClasses as s}from"../../internal/styles.js";function textOf(e){return"string"==typeof e||"number"==typeof e?String(e):Array.isArray(e)?e.map(textOf).join(""):""}export const PlAnimateTyping=/* @__PURE__ */r.forwardRef(function PlAnimateTyping({text:o,speed:u=24,hold:m=1400,erase:l=!1,eraseSpeed:c,caret:f=!0,caretChar:p="|",duration:d,delay:h=0,repeat:g=1,paused:y,trigger:x="mount",play:T,once:j=!0,threshold:v=.2,className:N,style:S,children:w,...A},M){const O=a({trigger:x,play:T,once:j,threshold:v,paused:y,infinite:n(g)}),I=i(),E=o??textOf(w),P=r.useMemo(()=>function graphemesOf(e,t){return"undefined"!=typeof Intl&&"Segmenter"in Intl?[...new Intl.Segmenter(t,{granularity:"grapheme"}).segment(e)].map(e=>e.segment):[...e]}(E),[E]),R=P.length,[b,C]=r.useState(0),k=r.useRef(0),q=d&&R>0?d/R:1e3/Math.max(u,1),z=1e3/Math.max(c??2*u,1);return r.useEffect(()=>{k.current=0},[R]),r.useEffect(()=>{if(I||0===R)return void C(R);if(!O.started)return k.current=0,void C(0);if(y)return;let e,t=!1,r=k.current,n=1,a=!1;const i="infinite"===g?1/0:Math.max(1,g);if(r>=R&&1===i)return;const step=()=>{if(!t){if(a)return r-=1,k.current=r,C(r),r<=0&&(a=!1,n+=1),void(e=setTimeout(step,a?z:q));if(r+=1,k.current=r,C(r),r<R)e=setTimeout(step,q);else if(!(n>=i)){if(l)return a=!0,void(e=setTimeout(step,m));n+=1,e=setTimeout(()=>{t||(r=0,k.current=0,C(0),e=setTimeout(step,q))},m)}}};return C(r),e=setTimeout(step,0===r?h:q),()=>{t=!0,clearTimeout(e)}},[O.started,y,I,R,q,z,h,m,l,g]),t("div",{ref:e=>{O.ref(e),"function"==typeof M?M(e):M&&(M.current=e)},className:N,style:S,"data-plass-animation":"typing","data-state":O.state,...O.handlers,...A,children:[e("span",{className:s,children:E}),t("span",{"aria-hidden":"true",className:"whitespace-pre-wrap",children:[P.slice(0,b).join(""),f?e("span",{className:"plass-caret",children:p}):null]})]})});
@@ -1 +1 @@
1
- "use client";import*as e from"react";import{useRender as i}from"@base-ui/react/use-render";import{cx as o,radiusClasses as t}from"../../internal/styles.js";const c=/* @__PURE__ */["[&>img]:size-full","[&>video]:size-full","[&>canvas]:size-full","[&>svg]:size-full","[&>iframe]:size-full","[&>picture]:size-full","[&>picture>img]:size-full"].join(" "),r={cover:"[&>img]:object-cover [&>video]:object-cover [&>picture>img]:object-cover",contain:"[&>img]:object-contain [&>video]:object-contain [&>picture>img]:object-contain",fill:"[&>img]:object-fill [&>video]:object-fill [&>picture>img]:object-fill",none:"[&>img]:object-none [&>video]:object-none [&>picture>img]:object-none"};export const PlAspectRatio=/* @__PURE__ */e.forwardRef(function PlAspectRatio({ratio:e=1,fit:l="cover",rounded:n=!1,size:s="md",render:a,className:f,style:m,children:u,...d},p){const b=o("relative block w-full overflow-hidden",c,r[l],n?t[s]:"",f);return i({render:a,ref:p,props:{className:b,style:{aspectRatio:e,...m},children:u,...d}})});
1
+ "use client";import*as e from"react";import{useDefaults as i}from"../../internal/defaults.js";import{useRender as o}from"@base-ui/react/use-render";import{cx as t,radiusClasses as c}from"../../internal/styles.js";const r=/* @__PURE__ */["[&>img]:size-full","[&>video]:size-full","[&>canvas]:size-full","[&>svg]:size-full","[&>iframe]:size-full","[&>picture]:size-full","[&>picture>img]:size-full"].join(" "),l={cover:"[&>img]:object-cover [&>video]:object-cover [&>picture>img]:object-cover",contain:"[&>img]:object-contain [&>video]:object-contain [&>picture>img]:object-contain",fill:"[&>img]:object-fill [&>video]:object-fill [&>picture>img]:object-fill",none:"[&>img]:object-none [&>video]:object-none [&>picture>img]:object-none"};export const PlAspectRatio=/* @__PURE__ */e.forwardRef(function PlAspectRatio({ratio:e=1,fit:n="cover",rounded:s=!1,size:a,render:f,className:m,style:u,children:d,...p},j){const b=i(),v=a??b.size??"md",g=t("relative block w-full overflow-hidden",r,l[n],s?c[v]:"",m);return o({render:f,ref:j,props:{className:g,style:{aspectRatio:e,...u},children:d,...p}})});
@@ -1 +1 @@
1
- "use client";import{jsx as e,jsxs as a}from"react/jsx-runtime";import*as r from"react";import{Avatar as t}from"@base-ui/react/avatar";import{AvatarGroupContext as s}from"../../internal/avatar-group.js";import{controlHeightClasses as o,controlSlots as n,controlSquareClasses as l,glassClasses as i,hasContent as c,radiusClasses as d,srOnlyClasses as m,transitionClasses as p}from"../../internal/styles.js";const f={xs:"text-[0.5625rem]",sm:"text-[0.6875rem]",md:"text-[0.8125rem]",lg:"text-[1rem]",xl:"text-[1.1875rem]"},v={solid:/* @__PURE__ */["text-(--p-on-solid) [background-image:var(--p-fill)]","[box-shadow:var(--p-elev),var(--p-lift)]"].join(" "),glass:/* @__PURE__ */[i,"border text-(--p-accent) bg-(--plass-glass)","[border-color:var(--plass-border)]","[box-shadow:var(--p-elev),var(--plass-gloss-glass)]"].join(" "),ghost:"text-(--p-accent) bg-(--p-soft-press) [box-shadow:var(--p-elev)]"},g=/* @__PURE__ */["relative inline-flex shrink-0 select-none items-center justify-center overflow-hidden","align-middle leading-none font-semibold tracking-wide whitespace-nowrap","[&_svg]:pointer-events-none [&_svg]:size-[55%]",p].join(" ");function PersonIcon(){return a("svg",{viewBox:"0 0 24 24",fill:"currentColor","aria-hidden":"true",children:[e("path",{d:"M12 12a4.5 4.5 0 1 0 0-9 4.5 4.5 0 0 0 0 9Z"}),e("path",{d:"M12 14.25c-4.28 0-7.75 2.42-7.75 5.4 0 .75.6 1.35 1.35 1.35h12.8c.75 0 1.35-.6 1.35-1.35 0-2.98-3.47-5.4-7.75-5.4Z"})]})}export const PlAvatar=/* @__PURE__ */r.forwardRef(function PlAvatar({src:i,srcSet:p,alt:h,name:u,initials:x,shape:b,variant:j,size:y,color:w,elevation:N,delay:z,imageProps:C,onLoadingStatusChange:A,className:P,style:k,children:B,...S},I){const L=r.useContext(s),F=b??L?.shape??"circle",M=j??L?.variant??"ghost",R=y??L?.size??"md",Z=w??L?.color??"primary",_=N??L?.elevation??0,O=u?function initialsOf(e){const a=e.normalize("NFC").trim().split(/\s+/).filter(Boolean);return 0===a.length?"":((Array.from(a[0])[0]??"")+(a.length>1?Array.from(a[a.length-1])[0]??"":"")).toLocaleUpperCase()}(u):"",U=h??u,q=c(B)?B:(x??O)||e(PersonIcon,{}),D=c(B)||Boolean(x??O),E=[g,o[R],l[R],f[R],"circle"===F?"rounded-full":d[R],v[M],P??""].filter(Boolean).join(" ");return a(t.Root,{ref:I,className:E,style:{...n(Z,_,M),...k},...S,children:[i?e(t.Image,{src:i,srcSet:p,alt:U??"",className:"size-full object-cover",onLoadingStatusChange:A,...C}):null,a(t.Fallback,{delay:i?z:void 0,className:"flex size-full items-center justify-center",children:[U&&D?e("span",{className:m,children:U}):null,e("span",{"aria-hidden":!(!U||!D)||void 0,className:"contents",children:q})]})]})});
1
+ "use client";import{jsx as e,jsxs as r}from"react/jsx-runtime";import*as a from"react";import{useDefaults as t}from"../../internal/defaults.js";import{Avatar as s}from"@base-ui/react/avatar";import{AvatarGroupContext as o}from"../../internal/avatar-group.js";import{controlHeightClasses as n,controlSlots as l,controlSquareClasses as i,glassClasses as c,hasContent as d,radiusClasses as m,srOnlyClasses as p,transitionClasses as f}from"../../internal/styles.js";const v={xs:"text-[0.5625rem]",sm:"text-[0.6875rem]",md:"text-[0.8125rem]",lg:"text-[1rem]",xl:"text-[1.1875rem]"},g={solid:/* @__PURE__ */["text-(--p-on-solid) [background-image:var(--p-fill)]","[box-shadow:var(--p-elev),var(--p-lift)]"].join(" "),glass:/* @__PURE__ */[c,"border text-(--p-accent) bg-(--plass-glass)","[border-color:var(--plass-border)]","[box-shadow:var(--p-elev),var(--plass-gloss-glass)]"].join(" "),ghost:"text-(--p-accent) bg-(--p-soft-press) [box-shadow:var(--p-elev)]"},h=/* @__PURE__ */["relative inline-flex shrink-0 select-none items-center justify-center overflow-hidden","align-middle leading-none font-semibold tracking-wide whitespace-nowrap","[&_svg]:pointer-events-none [&_svg]:size-[55%]",f].join(" ");function PersonIcon(){return r("svg",{viewBox:"0 0 24 24",fill:"currentColor","aria-hidden":"true",children:[e("path",{d:"M12 12a4.5 4.5 0 1 0 0-9 4.5 4.5 0 0 0 0 9Z"}),e("path",{d:"M12 14.25c-4.28 0-7.75 2.42-7.75 5.4 0 .75.6 1.35 1.35 1.35h12.8c.75 0 1.35-.6 1.35-1.35 0-2.98-3.47-5.4-7.75-5.4Z"})]})}export const PlAvatar=/* @__PURE__ */a.forwardRef(function PlAvatar({src:c,srcSet:f,alt:u,name:x,initials:b,shape:j,variant:y,size:w,color:z,elevation:N,delay:C,imageProps:A,onLoadingStatusChange:P,className:k,style:B,children:S,...I},L){const F=t(),M=a.useContext(o),R=j??M?.shape??"circle",Z=y??M?.variant??"ghost",_=w??M?.size??F.size??"md",O=z??M?.color??F.color??"primary",U=N??M?.elevation??0,q=x?function initialsOf(e){const r=e.normalize("NFC").trim().split(/\s+/).filter(Boolean);return 0===r.length?"":((Array.from(r[0])[0]??"")+(r.length>1?Array.from(r[r.length-1])[0]??"":"")).toLocaleUpperCase()}(x):"",D=u??x,E=d(S)?S:(b??q)||e(PersonIcon,{}),G=d(S)||Boolean(b??q),H=[h,n[_],i[_],v[_],"circle"===R?"rounded-full":m[_],g[Z],k??""].filter(Boolean).join(" ");return r(s.Root,{ref:L,className:H,style:{...l(O,U,Z),...B},...I,children:[c?e(s.Image,{src:c,srcSet:f,alt:D??"",className:"size-full object-cover",onLoadingStatusChange:P,...A}):null,r(s.Fallback,{delay:c?C:void 0,className:"flex size-full items-center justify-center",children:[D&&G?e("span",{className:p,children:D}):null,e("span",{"aria-hidden":!(!D||!G)||void 0,className:"contents",children:E})]})]})});
@@ -1 +1 @@
1
- "use client";import{jsx as r,jsxs as a}from"react/jsx-runtime";import*as e from"react";import{PlAvatar as t}from"../avatar/PlAvatar.js";import{AvatarGroupContext as i}from"../../internal/avatar-group.js";import{cx as l,toLength as s}from"../../internal/styles.js";const o={xs:"0.5rem",sm:"0.625rem",md:"0.875rem",lg:"1rem",xl:"1.25rem"};export const PlAvatarGroup=/* @__PURE__ */e.forwardRef(function PlAvatarGroup({max:n,total:m,overlap:c,size:p="md",shape:v="circle",variant:d="ghost",color:f="primary",elevation:h=0,className:u,style:x,children:g,...j},y){const A=e.useMemo(()=>({size:p,shape:v,variant:d,color:f,elevation:h}),[p,v,d,f,h]),P=e.Children.toArray(g),M=void 0===n?P:P.slice(0,Math.max(0,n)),z=m??P.length,G=Math.max(0,z-M.length);return r(i.Provider,{value:A,children:a("div",{ref:y,className:l("isolate inline-flex items-center","[&>*:not(:first-child)]:[margin-inline-start:calc(var(--p-overlap)*-1)]","[&>*]:ring-2 [&>*]:ring-(--plass-surface)",u??""),style:{"--p-overlap":void 0===c?o[p]:s(c),...x},...j,children:[M,G>0?r(t,{initials:`+${G}`}):null]})})});
1
+ "use client";import{jsx as r,jsxs as e}from"react/jsx-runtime";import*as a from"react";import{useDefaults as t}from"../../internal/defaults.js";import{PlAvatar as i}from"../avatar/PlAvatar.js";import{AvatarGroupContext as l}from"../../internal/avatar-group.js";import{cx as s,toLength as o}from"../../internal/styles.js";const n={xs:"0.5rem",sm:"0.625rem",md:"0.875rem",lg:"1rem",xl:"1.25rem"};export const PlAvatarGroup=/* @__PURE__ */a.forwardRef(function PlAvatarGroup({max:m,total:c,overlap:p,size:v,shape:f="circle",variant:d="ghost",color:h,elevation:u=0,className:x,style:g,children:j,...y},A){const P=t(),z=v??P.size??"md",M=h??P.color??"primary",G=a.useMemo(()=>({size:z,shape:f,variant:d,color:M,elevation:u}),[z,f,d,M,u]),N=a.Children.toArray(j),w=void 0===m?N:N.slice(0,Math.max(0,m)),C=c??N.length,R=Math.max(0,C-w.length);return r(l.Provider,{value:G,children:e("div",{ref:A,className:s("isolate inline-flex items-center","[&>*:not(:first-child)]:[margin-inline-start:calc(var(--p-overlap)*-1)]","[&>*]:ring-2 [&>*]:ring-(--plass-surface)",x??""),style:{"--p-overlap":void 0===p?n[z]:o(p),...g},...y,children:[w,R>0?r(i,{initials:`+${R}`}):null]})})});
@@ -0,0 +1,55 @@
1
+ import * as React from 'react';
2
+ import type { PlassColor, PlassElevation, PlassSize, PlassVariant } from '../../types.js';
3
+ /** What is scrolled, and what is watched. */
4
+ export type PlBackTopTarget = Window | HTMLElement | React.RefObject<HTMLElement | null> | (() => Window | HTMLElement | null);
5
+ export interface PlBackTopProps extends Omit<React.ComponentPropsWithoutRef<'button'>, 'color'> {
6
+ /**
7
+ * What is scrolled. The window by default; a ref or an element for a panel
8
+ * that scrolls inside the page.
9
+ */
10
+ target?: PlBackTopTarget;
11
+ /**
12
+ * How far down the reader has to be before it appears, in pixels.
13
+ *
14
+ * 400 is roughly one screen on a laptop, which is the point at which "go
15
+ * back to the top" stops being a thing they could just do by scrolling.
16
+ * @default 400
17
+ */
18
+ visibilityHeight?: number;
19
+ /** What it does, in words, and its accessible name. @default 'Back to top' */
20
+ label?: string;
21
+ /** The glyph. An upward chevron by default. */
22
+ icon?: React.ReactNode;
23
+ /**
24
+ * Whether it pins itself to the bottom corner of the window.
25
+ *
26
+ * On by default, because that is what this component is. Turn it off to put
27
+ * the button somewhere of your own — the end of an article, a toolbar — and
28
+ * keep the appearing and the scrolling.
29
+ * @default true
30
+ */
31
+ floating?: boolean;
32
+ /** @default 'glass' */
33
+ variant?: PlassVariant;
34
+ /** @default 'md' */
35
+ size?: PlassSize;
36
+ /** @default 'primary' */
37
+ color?: PlassColor;
38
+ /** @default 2 */
39
+ elevation?: PlassElevation;
40
+ }
41
+ /**
42
+ * The way back up, once there is a way back up to want.
43
+ *
44
+ * It is **hidden until it is useful** and that is the whole design: a button
45
+ * pinned to the corner of every page from the first paint is one more thing
46
+ * covering the content, and on a page short enough not to scroll it is a
47
+ * control that does nothing. It appears when the reader is a screen or so down,
48
+ * which is the point at which scrolling back stops being something they would
49
+ * just do.
50
+ *
51
+ * The scroll is smooth, and **not** under `prefers-reduced-motion` — a page
52
+ * that flies past a reader who asked for less movement is the exact case that
53
+ * setting exists for. It jumps instead, which arrives at the same place.
54
+ */
55
+ export declare const PlBackTop: React.ForwardRefExoticComponent<PlBackTopProps & React.RefAttributes<HTMLButtonElement>>;
@@ -0,0 +1 @@
1
+ "use client";import{jsx as o}from"react/jsx-runtime";import*as e from"react";import{PlIconButton as t}from"../icon-button/PlIconButton.js";import{useDefaults as n}from"../../internal/defaults.js";import{usePrefersReducedMotion as r}from"../../internal/media.js";import{cx as i,transitionClasses as s}from"../../internal/styles.js";function ChevronUp(){return o("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:o("path",{d:"M4.5 9.5 8 6l3.5 3.5",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})}function resolve(o){return void 0===o?"undefined"==typeof window?null:window:"function"==typeof o?o():"current"in o?o.current:o}export const PlBackTop=/* @__PURE__ */e.forwardRef(function PlBackTop({target:l,visibilityHeight:a=400,label:c="Back to top",icon:d,floating:u=!0,variant:f="glass",size:p,color:v,elevation:m=2,className:h,onClick:k,...b},j){const w=n(),y=p??w.size??"md",x=v??w.color??"primary",g=r(),[B,C]=e.useState(!1);return e.useEffect(()=>{const o=resolve(l);if(!o)return;const read=()=>C(function scrollTopOf(o){return o instanceof Window?o.scrollY:o.scrollTop}(o)>a);return read(),o.addEventListener("scroll",read,{passive:!0}),()=>o.removeEventListener("scroll",read)},[l,a]),o(t,{ref:j,label:c,icon:d??o(ChevronUp,{}),variant:f,size:y,color:x,elevation:m,onClick:o=>{k?.(o),o.defaultPrevented||resolve(l)?.scrollTo({top:0,behavior:g?"auto":"smooth"})},"aria-hidden":!B||void 0,tabIndex:B?void 0:-1,className:i(u?"fixed end-6 bottom-6 z-30":"",s,B?"opacity-100":"pointer-events-none opacity-0",h),...b})});
@@ -0,0 +1,2 @@
1
+ export { PlBackTop } from './PlBackTop.js';
2
+ export type { PlBackTopProps, PlBackTopTarget } from './PlBackTop.js';
@@ -0,0 +1 @@
1
+ export{PlBackTop}from"./PlBackTop.js";
@@ -1 +1 @@
1
- "use client";import{jsx as e,Fragment as t,jsxs as s}from"react/jsx-runtime";import*as m from"react";import{controlSlots as o,glassClasses as a,hasContent as l,srOnlyClasses as n,transitionClasses as r}from"../../internal/styles.js";const i={xs:"h-3.5 min-w-3.5",sm:"h-4 min-w-4",md:"h-4.5 min-w-4.5",lg:"h-5 min-w-5",xl:"h-6 min-w-6"},d={xs:"size-1.5",sm:"size-2",md:"size-2.5",lg:"size-2.5",xl:"size-3"},p={xs:"text-[0.5625rem]",sm:"text-[0.625rem]",md:"text-[0.6875rem]",lg:"text-[0.75rem]",xl:"text-[0.8125rem]"},b={default:{xs:"px-1",sm:"px-1",md:"px-1.5",lg:"px-1.5",xl:"px-2"},compact:{xs:"px-0.5",sm:"px-0.5",md:"px-1",lg:"px-1",xl:"px-1.5"}},x="rounded-full",c={xs:{badge:"-mt-1.5 -mb-1.5 -ms-1.5 -me-1.5",dot:"-mt-0.5 -mb-0.5 -ms-0.5 -me-0.5"},sm:{badge:"-mt-2 -mb-2 -ms-2 -me-2",dot:"-mt-1 -mb-1 -ms-1 -me-1"},md:{badge:"-mt-2 -mb-2 -ms-2 -me-2",dot:"-mt-1 -mb-1 -ms-1 -me-1"},lg:{badge:"-mt-2.5 -mb-2.5 -ms-2.5 -me-2.5",dot:"-mt-1 -mb-1 -ms-1 -me-1"},xl:{badge:"-mt-3 -mb-3 -ms-3 -me-3",dot:"-mt-1.5 -mb-1.5 -ms-1.5 -me-1.5"}},g={"top-start":"top-0 start-0","top-end":"top-0 end-0","bottom-start":"bottom-0 start-0","bottom-end":"bottom-0 end-0"},f={"top-start":"mt-[7%] ms-[7%]","top-end":"mt-[7%] me-[7%]","bottom-start":"mb-[7%] ms-[7%]","bottom-end":"mb-[7%] me-[7%]"},h={solid:/* @__PURE__ */["text-(--p-on-solid) [background-image:var(--p-fill)]","[box-shadow:var(--p-elev),var(--p-lift)]"].join(" "),glass:/* @__PURE__ */[a,"border text-(--p-accent) bg-(--plass-glass)","[border-color:var(--plass-border)]","[box-shadow:var(--p-elev),var(--plass-gloss-glass)]"].join(" "),ghost:"text-(--p-accent) bg-(--p-soft-press)"};export const PlBadge=/* @__PURE__ */m.forwardRef(function PlBadge({variant:m="solid",size:a="md",color:u="primary",density:v="default",elevation:w=0,content:j,max:y=99,dot:z=!1,showZero:N=!1,invisible:k=!1,placement:B="top-end",overlap:P="square",label:$,className:q,style:C,children:F,...R},Z){const A=l(F),D=!l(j)||0===j&&!N,E=z||D,G=k||D&&!z,H=["pointer-events-none z-10 inline-flex shrink-0 items-center justify-center","font-semibold tabular-nums whitespace-nowrap",x,r,h[m],E?d[a]:[i[a],p[a],b[v][a]].join(" "),A?`absolute ${g[B]}`:"relative align-middle",A?E?c[a].dot:c[a].badge:"",A&&"circle"===P?f[B]:"",G?"invisible":"",q??""].filter(Boolean).join(" "),I=function capContent(e,t){return"number"==typeof e&&e>t?`${t}+`:e}(j,y),J=e("span",{ref:Z,className:H,style:{...o(u,w,m),...C},"aria-hidden":!!G||void 0,...R,children:G?null:s(t,{children:[E||$?e("span",{className:n,children:$??I}):null,E?null:e("span",{"aria-hidden":!!$||void 0,children:I})]})});return A?s("span",{className:"relative inline-flex shrink-0 align-middle",children:[F,J]}):J});
1
+ "use client";import{jsx as e,Fragment as t,jsxs as s}from"react/jsx-runtime";import*as m from"react";import{useDefaults as o}from"../../internal/defaults.js";import{controlSlots as a,glassClasses as l,hasContent as n,srOnlyClasses as r,transitionClasses as i}from"../../internal/styles.js";const d={xs:"h-3.5 min-w-3.5",sm:"h-4 min-w-4",md:"h-4.5 min-w-4.5",lg:"h-5 min-w-5",xl:"h-6 min-w-6"},p={xs:"size-1.5",sm:"size-2",md:"size-2.5",lg:"size-2.5",xl:"size-3"},b={xs:"text-[0.5625rem]",sm:"text-[0.625rem]",md:"text-[0.6875rem]",lg:"text-[0.75rem]",xl:"text-[0.8125rem]"},x={default:{xs:"px-1",sm:"px-1",md:"px-1.5",lg:"px-1.5",xl:"px-2"},compact:{xs:"px-0.5",sm:"px-0.5",md:"px-1",lg:"px-1",xl:"px-1.5"}},c="rounded-full",g={xs:{badge:"-mt-1.5 -mb-1.5 -ms-1.5 -me-1.5",dot:"-mt-0.5 -mb-0.5 -ms-0.5 -me-0.5"},sm:{badge:"-mt-2 -mb-2 -ms-2 -me-2",dot:"-mt-1 -mb-1 -ms-1 -me-1"},md:{badge:"-mt-2 -mb-2 -ms-2 -me-2",dot:"-mt-1 -mb-1 -ms-1 -me-1"},lg:{badge:"-mt-2.5 -mb-2.5 -ms-2.5 -me-2.5",dot:"-mt-1 -mb-1 -ms-1 -me-1"},xl:{badge:"-mt-3 -mb-3 -ms-3 -me-3",dot:"-mt-1.5 -mb-1.5 -ms-1.5 -me-1.5"}},f={"top-start":"top-0 start-0","top-end":"top-0 end-0","bottom-start":"bottom-0 start-0","bottom-end":"bottom-0 end-0"},u={"top-start":"mt-[7%] ms-[7%]","top-end":"mt-[7%] me-[7%]","bottom-start":"mb-[7%] ms-[7%]","bottom-end":"mb-[7%] me-[7%]"},h={solid:/* @__PURE__ */["text-(--p-on-solid) [background-image:var(--p-fill)]","[box-shadow:var(--p-elev),var(--p-lift)]"].join(" "),glass:/* @__PURE__ */[l,"border text-(--p-accent) bg-(--plass-glass)","[border-color:var(--plass-border)]","[box-shadow:var(--p-elev),var(--plass-gloss-glass)]"].join(" "),ghost:"text-(--p-accent) bg-(--p-soft-press)"};export const PlBadge=/* @__PURE__ */m.forwardRef(function PlBadge({variant:m="solid",size:l,color:v,density:w,elevation:j=0,content:y,max:z=99,dot:N=!1,showZero:k=!1,invisible:B=!1,placement:P="top-end",overlap:$="square",label:q,className:C,style:F,children:R,...Z},A){const D=o(),E=l??D.size??"md",G=v??D.color??"primary",H=w??D.density??"default",I=n(R),J=!n(y)||0===y&&!k,K=N||J,L=B||J&&!N,M=["pointer-events-none z-10 inline-flex shrink-0 items-center justify-center","font-semibold tabular-nums whitespace-nowrap",c,i,h[m],K?p[E]:[d[E],b[E],x[H][E]].join(" "),I?`absolute ${f[P]}`:"relative align-middle",I?K?g[E].dot:g[E].badge:"",I&&"circle"===$?u[P]:"",L?"invisible":"",C??""].filter(Boolean).join(" "),O=function capContent(e,t){return"number"==typeof e&&e>t?`${t}+`:e}(y,z),Q=e("span",{ref:A,className:M,style:{...a(G,j,m),...F},"aria-hidden":!!L||void 0,...Z,children:L?null:s(t,{children:[K||q?e("span",{className:r,children:q??O}):null,K?null:e("span",{"aria-hidden":!!q||void 0,children:O})]})});return I?s("span",{className:"relative inline-flex shrink-0 align-middle",children:[R,Q]}):Q});
@@ -1 +1 @@
1
- "use client";import{jsx as e,jsxs as s}from"react/jsx-runtime";import*as r from"react";import{glassClasses as l,hasContent as a,metaTextClasses as t,radiusClasses as o,sheetPaddingXClasses as n,sheetPaddingYClasses as i,surfaceSlots as c,transitionClasses as d}from"../../internal/styles.js";const m={xs:"text-[0.75rem]/[1.25rem]",sm:"text-[0.8125rem]/[1.375rem]",md:"text-[0.9375rem]/[1.625rem]",lg:"text-[1.0625rem]/[1.875rem]",xl:"text-[1.25rem]/[2.125rem]"},p="border-s-2 [border-inline-start-color:var(--p-accent)]",u={solid:/* @__PURE__ */[l,"bg-(--plass-glass-press)","[box-shadow:var(--p-elev),var(--plass-gloss-glass)]"].join(" "),glass:/* @__PURE__ */[l,"border border-s-2 bg-(--plass-glass)","[border-color:var(--plass-glass-line)]","[box-shadow:var(--p-elev),var(--plass-gloss-glass)]"].join(" "),ghost:"bg-transparent"};function QuoteMarkIcon(){return e("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:e("path",{d:"M6.4 3.6c-2.3.9-3.7 2.8-3.7 5.1 0 2 1.2 3.3 2.8 3.3 1.4 0 2.5-1 2.5-2.4 0-1.3-.9-2.2-2.1-2.2-.2 0-.4 0-.6.1.3-1 1.1-1.8 2.2-2.3l-1.1-1.6ZM13.3 3.6c-2.3.9-3.7 2.8-3.7 5.1 0 2 1.2 3.3 2.8 3.3 1.4 0 2.5-1 2.5-2.4 0-1.3-.9-2.2-2.1-2.2-.2 0-.4 0-.6.1.3-1 1.1-1.8 2.2-2.3l-1.1-1.6Z",fill:"currentColor"})})}export const PlBlockquote=/* @__PURE__ */r.forwardRef(function PlBlockquote({variant:r="ghost",size:l="md",color:f="primary",density:g="default",elevation:x=0,author:h,source:v,cite:b,icon:j,className:N,style:k,children:y,...w},B){const M=a(h)||a(v),q=void 0===j?e(QuoteMarkIcon,{}):j,z=["flex flex-col text-(--plass-fg)",p,"ghost"===r?"":`${o[l]} rounded-s-none`,u[r],n[g][l],i[g][l],d,N??""].filter(Boolean).join(" "),I=s("blockquote",{cite:b,className:m[l],children:[a(q)?e("span",{"aria-hidden":"true",className:"mb-1 block size-[2em] text-(--p-soft-press) [&>svg]:size-full",children:q}):null,y]}),P={...c(f,x),...k};return M?s("figure",{ref:B,className:z,style:P,...w,children:[I,s("figcaption",{className:["mt-2 flex flex-wrap items-baseline gap-x-1.5 text-(--plass-muted-fg)",t[l]].join(" "),children:[a(h)?s("span",{className:"font-medium text-(--plass-fg)",children:[e("span",{"aria-hidden":"true",children:"— "}),h]}):null,a(v)?e("cite",{className:"not-italic",children:v}):null]})]}):e("div",{ref:B,className:z,style:P,...w,children:I})});
1
+ "use client";import{jsx as e,jsxs as s}from"react/jsx-runtime";import*as r from"react";import{useDefaults as l}from"../../internal/defaults.js";import{glassClasses as t,hasContent as a,metaTextClasses as o,radiusClasses as n,sheetPaddingXClasses as i,sheetPaddingYClasses as c,surfaceSlots as d,transitionClasses as m}from"../../internal/styles.js";const p={xs:"text-[0.75rem]/[1.25rem]",sm:"text-[0.8125rem]/[1.375rem]",md:"text-[0.9375rem]/[1.625rem]",lg:"text-[1.0625rem]/[1.875rem]",xl:"text-[1.25rem]/[2.125rem]"},f="border-s-2 [border-inline-start-color:var(--p-accent)]",u={solid:/* @__PURE__ */[t,"bg-(--plass-glass-press)","[box-shadow:var(--p-elev),var(--plass-gloss-glass)]"].join(" "),glass:/* @__PURE__ */[t,"border border-s-2 bg-(--plass-glass)","[border-color:var(--plass-glass-line)]","[box-shadow:var(--p-elev),var(--plass-gloss-glass)]"].join(" "),ghost:"bg-transparent"};function QuoteMarkIcon(){return e("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:e("path",{d:"M6.4 3.6c-2.3.9-3.7 2.8-3.7 5.1 0 2 1.2 3.3 2.8 3.3 1.4 0 2.5-1 2.5-2.4 0-1.3-.9-2.2-2.1-2.2-.2 0-.4 0-.6.1.3-1 1.1-1.8 2.2-2.3l-1.1-1.6ZM13.3 3.6c-2.3.9-3.7 2.8-3.7 5.1 0 2 1.2 3.3 2.8 3.3 1.4 0 2.5-1 2.5-2.4 0-1.3-.9-2.2-2.1-2.2-.2 0-.4 0-.6.1.3-1 1.1-1.8 2.2-2.3l-1.1-1.6Z",fill:"currentColor"})})}export const PlBlockquote=/* @__PURE__ */r.forwardRef(function PlBlockquote({variant:r="ghost",size:t,color:g,density:x,elevation:h=0,author:v,source:b,cite:j,icon:N,className:y,style:k,children:w,...z},B){const M=l(),q=t??M.size??"md",I=g??M.color??"primary",P=x??M.density??"default",Q=a(v)||a(b),Z=void 0===N?e(QuoteMarkIcon,{}):N,C=["flex flex-col text-(--plass-fg)",f,"ghost"===r?"":`${n[q]} rounded-s-none`,u[r],i[P][q],c[P][q],m,y??""].filter(Boolean).join(" "),R=s("blockquote",{cite:j,className:p[q],children:[a(Z)?e("span",{"aria-hidden":"true",className:"mb-1 block size-[2em] text-(--p-soft-press) [&>svg]:size-full",children:Z}):null,w]}),$={...d(I,h),...k};return Q?s("figure",{ref:B,className:C,style:$,...z,children:[R,s("figcaption",{className:["mt-2 flex flex-wrap items-baseline gap-x-1.5 text-(--plass-muted-fg)",o[q]].join(" "),children:[a(v)?s("span",{className:"font-medium text-(--plass-fg)",children:[e("span",{"aria-hidden":"true",children:"— "}),v]}):null,a(b)?e("cite",{className:"not-italic",children:b}):null]})]}):e("div",{ref:B,className:C,style:$,...z,children:R})});
@@ -1 +1 @@
1
- "use client";import{jsx as e,Fragment as a,jsxs as t}from"react/jsx-runtime";import*as l from"react";import{useRender as s}from"@base-ui/react/use-render";import{cx as i,focusRingInsetClasses as n,hasContent as r,iconSizeClasses as o,metaTextClasses as c,radiusClasses as d,sheetLineClasses as m,sheetRestClasses as u,srOnlyClasses as p,surfaceSlots as f,transitionClasses as g}from"../../internal/styles.js";const h=/* @__PURE__ */l.createContext({value:null,change:()=>{},size:"md",density:"default",labels:"all",disabled:!1}),x={static:"",sticky:"sticky bottom-0 z-20",fixed:"fixed inset-x-0 bottom-0 z-30"},v={xs:"min-h-10",sm:"min-h-12",md:"min-h-14",lg:"min-h-16",xl:"min-h-18"},b={default:{xs:"p-1",sm:"p-1",md:"p-1.5",lg:"p-2",xl:"p-2.5"},compact:{xs:"p-0.5",sm:"p-0.5",md:"p-1",lg:"p-1",xl:"p-1.5"}},y={xs:"gap-0.5",sm:"gap-0.5",md:"gap-1",lg:"gap-1",xl:"gap-1.5"};export const PlBottomNavigation=/* @__PURE__ */l.forwardRef(function PlBottomNavigation({variant:a="glass",size:t="md",color:n="primary",density:r="default",elevation:o=0,value:c,defaultValue:p=null,onValueChange:y,position:N="fixed",labels:w="all",divider:z=!0,safeArea:k=!0,disabled:C=!1,label:j,render:P,className:B,style:I,children:R,...V},A){const[D,F]=l.useState(p),M=void 0!==c,S=M?c:D,q=l.useCallback(e=>{M||F(e),y?.(e)},[M,y]),E=l.useMemo(()=>({value:S??null,change:q,size:t,density:r,labels:w,disabled:C}),[S,q,t,r,w,C]),G=i("w-full min-w-0","static"===N?d[t]:"",u[a],"glass"===a&&"static"!==N?"border-0":"",z?m:"",x[N],k?"pb-[env(safe-area-inset-bottom)]":"",g,B);return s({render:P??e("nav",{}),ref:A,props:{"aria-label":j,className:G,style:{...f(n,o),...I},children:e(h.Provider,{value:E,children:e("div",{className:i("flex w-full items-stretch",v[t],b[r][t]),children:R})}),...V}})});export const PlBottomNavigationItem=/* @__PURE__ */l.forwardRef(function PlBottomNavigationItem({value:s,icon:m,href:u,disabled:f=!1,className:x,children:v,onClick:b,...N},w){const z=l.useContext(h),k=f||z.disabled,C=null!==z.value&&z.value===s,j="all"===z.labels||"selected"===z.labels&&C,P=i("flex min-w-0 flex-1 flex-col items-center justify-center px-1 py-1.5",y[z.size],d[z.size],"[-webkit-tap-highlight-color:transparent] [touch-action:manipulation]",g,n,k?"cursor-not-allowed opacity-50 saturate-[0.35] text-(--plass-muted-fg)":C?"cursor-pointer font-medium text-(--p-accent) bg-(--p-soft) hover:bg-(--p-soft-hover)":"cursor-pointer text-(--plass-muted-fg) hover:text-(--plass-fg) hover:bg-(--plass-glass-hover)",x),B=t(a,{children:[r(m)?e("span",{className:i("flex shrink-0 items-center justify-center",o[z.size]),children:m}):null,r(v)?e("span",{className:j?i("max-w-full truncate leading-tight",c[z.size]):p,children:v}):null]}),press=e=>{k?e.preventDefault():(z.change(s),b?.(e))};return u?e("a",{ref:w,href:k?void 0:u,"aria-current":C?"page":void 0,"aria-disabled":k||void 0,className:P,onClick:press,...N,children:B}):e("button",{ref:w,type:"button",disabled:k,"aria-current":C?"page":void 0,className:P,onClick:press,...N,children:B})});
1
+ "use client";import{jsx as e,Fragment as a,jsxs as t}from"react/jsx-runtime";import*as l from"react";import{useDefaults as s}from"../../internal/defaults.js";import{useRender as i}from"@base-ui/react/use-render";import{cx as r,focusRingInsetClasses as n,hasContent as o,iconSizeClasses as c,metaTextClasses as d,radiusClasses as m,sheetLineClasses as u,sheetRestClasses as p,srOnlyClasses as f,surfaceSlots as g,transitionClasses as h}from"../../internal/styles.js";const x=/* @__PURE__ */l.createContext({value:null,change:()=>{},size:"md",density:"default",labels:"all",disabled:!1}),v={static:"",sticky:"sticky bottom-0 z-20",fixed:"fixed inset-x-0 bottom-0 z-30"},b={xs:"min-h-10",sm:"min-h-12",md:"min-h-14",lg:"min-h-16",xl:"min-h-18"},y={default:{xs:"p-1",sm:"p-1",md:"p-1.5",lg:"p-2",xl:"p-2.5"},compact:{xs:"p-0.5",sm:"p-0.5",md:"p-1",lg:"p-1",xl:"p-1.5"}},N={xs:"gap-0.5",sm:"gap-0.5",md:"gap-1",lg:"gap-1",xl:"gap-1.5"};export const PlBottomNavigation=/* @__PURE__ */l.forwardRef(function PlBottomNavigation({variant:a="glass",size:t,color:n,density:o,elevation:c=0,value:d,defaultValue:f=null,onValueChange:N,position:z="fixed",labels:w="all",divider:k=!0,safeArea:j=!0,disabled:C=!1,label:P,render:B,className:I,style:R,children:V,...A},D){const F=s(),M=t??F.size??"md",S=n??F.color??"primary",q=o??F.density??"default",[E,G]=l.useState(f),H=void 0!==d,J=H?d:E,K=l.useCallback(e=>{H||G(e),N?.(e)},[H,N]),L=l.useMemo(()=>({value:J??null,change:K,size:M,density:q,labels:w,disabled:C}),[J,K,M,q,w,C]),O=r("w-full min-w-0","static"===z?m[M]:"",p[a],"glass"===a&&"static"!==z?"border-0":"",k?u:"",v[z],j?"pb-[env(safe-area-inset-bottom)]":"",h,I);return i({render:B??e("nav",{}),ref:D,props:{"aria-label":P,className:O,style:{...g(S,c),...R},children:e(x.Provider,{value:L,children:e("div",{className:r("flex w-full items-stretch",b[M],y[q][M]),children:V})}),...A}})});export const PlBottomNavigationItem=/* @__PURE__ */l.forwardRef(function PlBottomNavigationItem({value:s,icon:i,href:u,disabled:p=!1,className:g,children:v,onClick:b,...y},z){const w=l.useContext(x),k=p||w.disabled,j=null!==w.value&&w.value===s,C="all"===w.labels||"selected"===w.labels&&j,P=r("flex min-w-0 flex-1 flex-col items-center justify-center px-1 py-1.5",N[w.size],m[w.size],"[-webkit-tap-highlight-color:transparent] [touch-action:manipulation]",h,n,k?"cursor-not-allowed opacity-50 saturate-[0.35] text-(--plass-muted-fg)":j?"cursor-pointer font-medium text-(--p-accent) bg-(--p-soft) hover:bg-(--p-soft-hover)":"cursor-pointer text-(--plass-muted-fg) hover:text-(--plass-fg) hover:bg-(--plass-glass-hover)",g),B=t(a,{children:[o(i)?e("span",{className:r("flex shrink-0 items-center justify-center",c[w.size]),children:i}):null,o(v)?e("span",{className:C?r("max-w-full truncate leading-tight",d[w.size]):f,children:v}):null]}),press=e=>{k?e.preventDefault():(w.change(s),b?.(e))};return u?e("a",{ref:z,href:k?void 0:u,"aria-current":j?"page":void 0,"aria-disabled":k||void 0,className:P,onClick:press,...y,children:B}):e("button",{ref:z,type:"button",disabled:k,"aria-current":j?"page":void 0,className:P,onClick:press,...y,children:B})});
@@ -1 +1 @@
1
- "use client";import{jsx as e}from"react/jsx-runtime";import*as r from"react";import{useRender as s}from"@base-ui/react/use-render";import{cx as t,radiusClasses as o,sheetPaddingXClasses as a,sheetPaddingYClasses as i,sheetRestClasses as n,surfaceSlots as l,transitionClasses as c}from"../../internal/styles.js";export const PlBox=/* @__PURE__ */r.forwardRef(function PlBox({variant:r="glass",size:d="md",color:m="primary",density:f="default",elevation:p=0,padded:u=!0,render:x,className:y,style:j,children:v,...b},h){const B=t("block",o[d],u?`${a[f][d]} ${i[f][d]}`:"",n[r],c,y);return s({render:x??e("div",{}),ref:h,props:{className:B,style:{...l(m,p),...j},children:v,...b}})});
1
+ "use client";import{jsx as e}from"react/jsx-runtime";import*as r from"react";import{useDefaults as s}from"../../internal/defaults.js";import{useRender as t}from"@base-ui/react/use-render";import{cx as o,radiusClasses as a,sheetPaddingXClasses as i,sheetPaddingYClasses as n,sheetRestClasses as l,surfaceSlots as d,transitionClasses as m}from"../../internal/styles.js";export const PlBox=/* @__PURE__ */r.forwardRef(function PlBox({variant:r="glass",size:c,color:f,density:p,elevation:u=0,padded:y=!0,render:x,className:j,style:v,children:b,...h},z){const B=s(),N=c??B.size??"md",P=f??B.color??"primary",$=p??B.density??"default",g=o("block",a[N],y?`${i[$][N]} ${n[$][N]}`:"",l[r],m,j);return t({render:x??e("div",{}),ref:z,props:{className:g,style:{...d(P,u),...v},children:b,...h}})});
@@ -1 +1 @@
1
- "use client";import{jsx as e,jsxs as t,Fragment as r}from"react/jsx-runtime";import*as a from"react";import{ArrowRightIcon as s,ChevronIcon as n,EllipsisIcon as l}from"../../internal/icons.js";import{controlTextClasses as i,cx as c,focusRingClasses as o,gapClasses as m,hasContent as p,iconClasses as d,radiusClasses as u,transitionClasses as f}from"../../internal/styles.js";const h=/* @__PURE__ */a.createContext({size:"md",last:!1}),x={default:{xs:"gap-1",sm:"gap-1.5",md:"gap-2",lg:"gap-2.5",xl:"gap-3"},compact:{xs:"gap-0.5",sm:"gap-1",md:"gap-1",lg:"gap-1.5",xl:"gap-2"}},g={xs:u.xs,sm:u.xs,md:u.xs,lg:u.sm,xl:u.sm},b=["chevron","arrow","slash","dot"];function textOf(e){return"string"==typeof e||"number"==typeof e?String(e):Array.isArray(e)?e.map(textOf).join(""):a.isValidElement(e)?textOf(e.props.children):""}function absoluteHref(e,t){if(!t)return e;try{return new URL(e,t).href}catch{return e}}function breadcrumbListData(e,t){const r=e.map((e,r)=>{const{href:a,children:s}=e.props;return{"@type":"ListItem",position:r+1,name:textOf(s),...a?{item:absoluteHref(a,t)}:null}});return JSON.stringify({"@context":"https://schema.org","@type":"BreadcrumbList",itemListElement:r}).replace(/</g,"\\u003c")}export const PlBreadcrumb=/* @__PURE__ */a.forwardRef(function PlBreadcrumb({size:r="md",color:m="primary",density:p="default",separator:u="chevron",maxItems:g,itemsBeforeCollapse:y=1,itemsAfterCollapse:N=1,expandable:v=!0,label:w="Breadcrumb",expandLabel:k="Show the hidden steps",structuredData:C=!1,baseUrl:B,className:L,style:j,children:I,...S},M){const[O,P]=a.useState(!1),z=a.Children.toArray(I).filter(a.isValidElement),A=z.length,D=z.some(e=>!0===e.props.current),E=!O&&void 0!==g&&A>Math.max(g,1)&&A-y-N>1?[...z.slice(0,Math.max(0,y)),null,...z.slice(A-Math.max(0,N))]:z,H=function isSeparatorName(e){return"string"==typeof e&&b.includes(e)}(u)?function separatorMark(t){switch(t){case"chevron":return e("span",{className:"flex -rotate-90 items-center rtl:rotate-90",children:e(n,{})});case"arrow":return e("span",{className:"flex items-center rtl:rotate-180",children:e(s,{})});case"slash":return e("span",{className:"opacity-70",children:"/"});case"dot":return e("span",{className:"opacity-70",children:"·"});default:return null}}(u):u,R=c("inline-flex items-center rounded-(--plass-radius-xs) px-0.5","text-(--plass-muted-fg)",f,d,v?c("cursor-pointer hover:bg-(--p-soft) hover:text-(--p-accent)",o):"");return t("nav",{ref:M,"aria-label":w,className:c("flex",i[r],d,L),style:{"--p-accent":`var(--plass-${m}-accent)`,"--p-soft":`var(--plass-${m}-soft)`,"--p-ring":`var(--plass-${m}-ring)`,...j},...S,children:[C&&A>0?e("script",{type:"application/ld+json",dangerouslySetInnerHTML:{__html:breadcrumbListData(z,B)}}):null,e("ol",{role:"list",className:c("flex list-none flex-wrap items-center p-0",x[p][r]),children:E.map((s,n)=>t(a.Fragment,{children:[n>0?e("li",{"aria-hidden":"true",className:"flex shrink-0 items-center text-(--plass-muted-fg) select-none",children:H}):null,s?e(h.Provider,{value:{size:r,last:!D&&n===E.length-1},children:s}):e("li",{className:"flex shrink-0 items-center",children:v?e("button",{type:"button",className:R,"aria-label":k,onClick:()=>P(!0),children:e(l,{})}):e("span",{className:R,"aria-hidden":"true",children:e(l,{})})})]},s?s.key??n:"fold"))})]})});export const PlBreadcrumbItem=/* @__PURE__ */a.forwardRef(function PlBreadcrumbItem({href:s,onClick:n,startIcon:l,endIcon:i,current:d,disabled:u=!1,className:x,children:b,...y},N){const{size:v,last:w}=a.useContext(h),k=d??w,C=Boolean(s||n)&&!k&&!u,B=c("inline-flex min-w-0 items-center px-1",m[v],g[v],f,u?"cursor-not-allowed text-(--plass-muted-fg) opacity-50":k?"font-medium text-(--plass-fg)":C?c("cursor-pointer text-(--plass-muted-fg)","hover:bg-(--p-soft) hover:text-(--p-accent)",o):"text-(--plass-muted-fg)"),L=t(r,{children:[p(l)?e("span",{className:"flex h-[1lh] shrink-0 items-center",children:l}):null,e("span",{className:"truncate",children:b}),p(i)?e("span",{className:"flex h-[1lh] shrink-0 items-center",children:i}):null]});return e("li",{ref:N,className:c("flex min-w-0 items-center",x),...y,children:C&&s?e("a",{href:s,className:B,onClick:n,children:L}):C?e("button",{type:"button",className:B,onClick:n,children:L}):e("span",{className:B,"aria-current":k?"page":void 0,"aria-disabled":u||void 0,children:L})})});
1
+ "use client";import{jsx as e,jsxs as t,Fragment as r}from"react/jsx-runtime";import*as a from"react";import{useDefaults as s}from"../../internal/defaults.js";import{ArrowRightIcon as n,ChevronIcon as l,EllipsisIcon as i}from"../../internal/icons.js";import{controlTextClasses as c,cx as o,focusRingClasses as m,gapClasses as p,hasContent as d,iconClasses as u,radiusClasses as f,transitionClasses as h}from"../../internal/styles.js";const x=/* @__PURE__ */a.createContext({size:"md",last:!1}),g={default:{xs:"gap-1",sm:"gap-1.5",md:"gap-2",lg:"gap-2.5",xl:"gap-3"},compact:{xs:"gap-0.5",sm:"gap-1",md:"gap-1",lg:"gap-1.5",xl:"gap-2"}},b={xs:f.xs,sm:f.xs,md:f.xs,lg:f.sm,xl:f.sm},y=["chevron","arrow","slash","dot"];function textOf(e){return"string"==typeof e||"number"==typeof e?String(e):Array.isArray(e)?e.map(textOf).join(""):a.isValidElement(e)?textOf(e.props.children):""}function absoluteHref(e,t){if(!t)return e;try{return new URL(e,t).href}catch{return e}}function breadcrumbListData(e,t){const r=e.map((e,r)=>{const{href:a,children:s}=e.props;return{"@type":"ListItem",position:r+1,name:textOf(s),...a?{item:absoluteHref(a,t)}:null}});return JSON.stringify({"@context":"https://schema.org","@type":"BreadcrumbList",itemListElement:r}).replace(/</g,"\\u003c")}export const PlBreadcrumb=/* @__PURE__ */a.forwardRef(function PlBreadcrumb({size:r,color:p,density:d,separator:f="chevron",maxItems:b,itemsBeforeCollapse:N=1,itemsAfterCollapse:v=1,expandable:w=!0,label:k="Breadcrumb",expandLabel:C="Show the hidden steps",structuredData:j=!1,baseUrl:B,className:L,style:I,children:S,...z},M){const O=s(),P=r??O.size??"md",A=p??O.color??"primary",D=d??O.density??"default",[E,H]=a.useState(!1),R=a.Children.toArray(S).filter(a.isValidElement),$=R.length,F=R.some(e=>!0===e.props.current),U=!E&&void 0!==b&&$>Math.max(b,1)&&$-N-v>1?[...R.slice(0,Math.max(0,N)),null,...R.slice($-Math.max(0,v))]:R,V=function isSeparatorName(e){return"string"==typeof e&&y.includes(e)}(f)?function separatorMark(t){switch(t){case"chevron":return e("span",{className:"flex -rotate-90 items-center rtl:rotate-90",children:e(l,{})});case"arrow":return e("span",{className:"flex items-center rtl:rotate-180",children:e(n,{})});case"slash":return e("span",{className:"opacity-70",children:"/"});case"dot":return e("span",{className:"opacity-70",children:"·"});default:return null}}(f):f,_=o("inline-flex items-center rounded-(--plass-radius-xs) px-0.5","text-(--plass-muted-fg)",h,u,w?o("cursor-pointer hover:bg-(--p-soft) hover:text-(--p-accent)",m):"");return t("nav",{ref:M,"aria-label":k,className:o("flex",c[P],u,L),style:{"--p-accent":`var(--plass-${A}-accent)`,"--p-soft":`var(--plass-${A}-soft)`,"--p-ring":`var(--plass-${A}-ring)`,...I},...z,children:[j&&$>0?e("script",{type:"application/ld+json",dangerouslySetInnerHTML:{__html:breadcrumbListData(R,B)}}):null,e("ol",{role:"list",className:o("flex list-none flex-wrap items-center p-0",g[D][P]),children:U.map((r,s)=>t(a.Fragment,{children:[s>0?e("li",{"aria-hidden":"true",className:"flex shrink-0 items-center text-(--plass-muted-fg) select-none",children:V}):null,r?e(x.Provider,{value:{size:P,last:!F&&s===U.length-1},children:r}):e("li",{className:"flex shrink-0 items-center",children:w?e("button",{type:"button",className:_,"aria-label":C,onClick:()=>H(!0),children:e(i,{})}):e("span",{className:_,"aria-hidden":"true",children:e(i,{})})})]},r?r.key??s:"fold"))})]})});export const PlBreadcrumbItem=/* @__PURE__ */a.forwardRef(function PlBreadcrumbItem({href:s,onClick:n,startIcon:l,endIcon:i,current:c,disabled:u=!1,className:f,children:g,...y},N){const{size:v,last:w}=a.useContext(x),k=c??w,C=Boolean(s||n)&&!k&&!u,j=o("inline-flex min-w-0 items-center px-1",p[v],b[v],h,u?"cursor-not-allowed text-(--plass-muted-fg) opacity-50":k?"font-medium text-(--plass-fg)":C?o("cursor-pointer text-(--plass-muted-fg)","hover:bg-(--p-soft) hover:text-(--p-accent)",m):"text-(--plass-muted-fg)"),B=t(r,{children:[d(l)?e("span",{className:"flex h-[1lh] shrink-0 items-center",children:l}):null,e("span",{className:"truncate",children:g}),d(i)?e("span",{className:"flex h-[1lh] shrink-0 items-center",children:i}):null]});return e("li",{ref:N,className:o("flex min-w-0 items-center",f),...y,children:C&&s?e("a",{href:s,className:j,onClick:n,children:B}):C?e("button",{type:"button",className:j,onClick:n,children:B}):e("span",{className:j,"aria-current":k?"page":void 0,"aria-disabled":u||void 0,children:B})})});
@@ -1 +1 @@
1
- "use client";import{jsx as s,Fragment as e,jsxs as o}from"react/jsx-runtime";import*as r from"react";import{Button as a}from"@base-ui/react/button";import{useRender as t}from"@base-ui/react/use-render";import{ButtonGroupContext as l}from"../../internal/button-group.js";import{Spinner as n}from"../../internal/icons.js";import{controlHeightClasses as i,controlSlots as p,controlSquareClasses as d,controlTextClasses as v,disabledClasses as c,focusRingClasses as g,gapClasses as m,glassClasses as x,hasContent as b,iconClasses as f,paddingXClasses as h,radiusClasses as u,readOnlyFilterClasses as $,transitionClasses as j}from"../../internal/styles.js";const y={xs:`${i.xs} ${m.xs} ${u.xs} ${v.xs}`,sm:`${i.sm} ${m.sm} ${u.sm} ${v.sm}`,md:`${i.md} ${m.md} ${u.md} ${v.md}`,lg:`${i.lg} ${m.lg} ${u.lg} ${v.lg}`,xl:`${i.xl} ${m.xl} ${u.xl} ${v.xl}`},w={xs:`${d.xs} px-0`,sm:`${d.sm} px-0`,md:`${d.md} px-0`,lg:`${d.lg} px-0`,xl:`${d.xl} px-0`},P=/* @__PURE__ */["relative inline-flex shrink-0 select-none items-center justify-center","whitespace-nowrap align-middle font-semibold leading-none","[-webkit-tap-highlight-color:transparent] [touch-action:manipulation]",j,g,f].join(" "),k={solid:/* @__PURE__ */["text-(--p-on-solid) [background-image:var(--p-fill)]","[box-shadow:var(--p-elev),var(--p-lift)]"].join(" "),glass:/* @__PURE__ */[x,"border text-(--p-accent) bg-(--plass-glass)","[border-color:var(--plass-glass-line)]","[box-shadow:var(--p-elev),var(--plass-gloss-glass)]"].join(" "),ghost:"text-(--p-accent) bg-transparent"},B={solid:/* @__PURE__ */["hover:brightness-105","hover:[box-shadow:var(--p-elev-hover),var(--p-lift-hover)]","active:brightness-95","active:[box-shadow:var(--p-elev-press),var(--p-lift-press)]"].join(" "),glass:/* @__PURE__ */["hover:bg-(--plass-glass-hover) hover:[border-color:var(--p-line)]","hover:[box-shadow:var(--p-elev-hover),var(--plass-gloss-glass)]","active:bg-(--plass-glass-press)","active:[box-shadow:var(--p-elev-press),var(--plass-gloss-glass)]"].join(" "),ghost:"hover:bg-(--p-soft) active:bg-(--p-soft-hover)"},C={solid:/* @__PURE__ */["cursor-default text-(--p-on-solid) [background-image:var(--p-fill)]",`shadow-none ${$}`].join(" "),glass:/* @__PURE__ */[x,"cursor-default border text-(--p-accent) bg-(--plass-glass)","[border-color:var(--plass-glass-line)]",`[box-shadow:var(--plass-gloss-glass)] ${$}`].join(" "),ghost:`cursor-default text-(--p-accent) bg-transparent ${$}`};export const PlButton=/* @__PURE__ */r.forwardRef(function PlButton({variant:i,size:d,color:v,density:g,elevation:m,startIcon:x,endIcon:f,loading:u=!1,readOnly:$=!1,fullWidth:j=!1,disabled:z,render:E,className:I,style:M,children:N,onClick:D,onPointerMove:F,...O},R){const T=r.useContext(l),W=i??T?.variant??"solid",X=d??T?.size??"md",Y=v??T?.color??"primary",q=g??T?.density??"default",A=m??T?.elevation??1,G=z??T?.disabled??!1,H=!b(N),J=u||$,K=!G&&!J,L=[P,y[X],H?w[X]:h[q][X],G?c[W]:$?C[W]:k[W],K?`${B[W]} cursor-pointer`:"",K?"plass-glow":"",u?"cursor-progress":"",j?"w-full":"",I??""].filter(Boolean).join(" ");return t({render:E??s(a,{disabled:G}),ref:R,props:{className:L,style:{...p(Y,A,W),...M},"aria-disabled":J||void 0,"aria-busy":u||void 0,"data-loading":u||void 0,"data-readonly":$||void 0,onClick:s=>{if(J)return s.preventDefault(),void s.stopPropagation();D?.(s)},onPointerMove:s=>{const e=s.currentTarget;e.style.setProperty("--p-mx",`${s.nativeEvent.offsetX}px`),e.style.setProperty("--p-my",`${s.nativeEvent.offsetY}px`),F?.(s)},...O,children:o(e,{children:[u?s(n,{}):x,N,f]})}})});
1
+ "use client";import{jsx as s,Fragment as e,jsxs as o}from"react/jsx-runtime";import*as r from"react";import{useDefaults as a}from"../../internal/defaults.js";import{Button as t}from"@base-ui/react/button";import{useRender as l}from"@base-ui/react/use-render";import{ButtonGroupContext as n}from"../../internal/button-group.js";import{Spinner as i}from"../../internal/icons.js";import{controlHeightClasses as p,controlSlots as d,controlSquareClasses as v,controlTextClasses as c,disabledClasses as g,focusRingClasses as m,gapClasses as x,glassClasses as f,hasContent as b,iconClasses as u,paddingXClasses as h,radiusClasses as $,readOnlyFilterClasses as j,transitionClasses as y}from"../../internal/styles.js";const w={xs:`${p.xs} ${x.xs} ${$.xs} ${c.xs}`,sm:`${p.sm} ${x.sm} ${$.sm} ${c.sm}`,md:`${p.md} ${x.md} ${$.md} ${c.md}`,lg:`${p.lg} ${x.lg} ${$.lg} ${c.lg}`,xl:`${p.xl} ${x.xl} ${$.xl} ${c.xl}`},P={xs:`${v.xs} px-0`,sm:`${v.sm} px-0`,md:`${v.md} px-0`,lg:`${v.lg} px-0`,xl:`${v.xl} px-0`},k=/* @__PURE__ */["relative inline-flex shrink-0 select-none items-center justify-center","whitespace-nowrap align-middle font-semibold leading-none","[-webkit-tap-highlight-color:transparent] [touch-action:manipulation]",y,m,u].join(" "),B={solid:/* @__PURE__ */["text-(--p-on-solid) [background-image:var(--p-fill)]","[box-shadow:var(--p-elev),var(--p-lift)]"].join(" "),glass:/* @__PURE__ */[f,"border text-(--p-accent) bg-(--plass-glass)","[border-color:var(--plass-glass-line)]","[box-shadow:var(--p-elev),var(--plass-gloss-glass)]"].join(" "),ghost:"text-(--p-accent) bg-transparent"},z={solid:/* @__PURE__ */["hover:brightness-105","hover:[box-shadow:var(--p-elev-hover),var(--p-lift-hover)]","active:brightness-95","active:[box-shadow:var(--p-elev-press),var(--p-lift-press)]"].join(" "),glass:/* @__PURE__ */["hover:bg-(--plass-glass-hover) hover:[border-color:var(--p-line)]","hover:[box-shadow:var(--p-elev-hover),var(--plass-gloss-glass)]","active:bg-(--plass-glass-press)","active:[box-shadow:var(--p-elev-press),var(--plass-gloss-glass)]"].join(" "),ghost:"hover:bg-(--p-soft) active:bg-(--p-soft-hover)"},C={solid:/* @__PURE__ */["cursor-default text-(--p-on-solid) [background-image:var(--p-fill)]",`shadow-none ${j}`].join(" "),glass:/* @__PURE__ */[f,"cursor-default border text-(--p-accent) bg-(--plass-glass)","[border-color:var(--plass-glass-line)]",`[box-shadow:var(--plass-gloss-glass)] ${j}`].join(" "),ghost:`cursor-default text-(--p-accent) bg-transparent ${j}`};export const PlButton=/* @__PURE__ */r.forwardRef(function PlButton({variant:p,size:v,color:c,density:m,elevation:x,startIcon:f,endIcon:u,loading:$=!1,readOnly:j=!1,fullWidth:y=!1,disabled:E,render:I,className:M,style:N,children:D,onClick:F,onPointerMove:O,...R},T){const W=a(),X=r.useContext(n),Y=p??X?.variant??"solid",q=v??X?.size??W.size??"md",A=c??X?.color??W.color??"primary",G=m??X?.density??W.density??"default",H=x??X?.elevation??1,J=E??X?.disabled??!1,K=!b(D),L=$||j,Q=!J&&!L,S=[k,w[q],K?P[q]:h[G][q],J?g[Y]:j?C[Y]:B[Y],Q?`${z[Y]} cursor-pointer`:"",Q?"plass-glow":"",$?"cursor-progress":"",y?"w-full":"",M??""].filter(Boolean).join(" ");return l({render:I??s(t,{disabled:J}),ref:T,props:{className:S,style:{...d(A,H,Y),...N},"aria-disabled":L||void 0,"aria-busy":$||void 0,"data-loading":$||void 0,"data-readonly":j||void 0,onClick:s=>{if(L)return s.preventDefault(),void s.stopPropagation();F?.(s)},onPointerMove:s=>{const e=s.currentTarget;e.style.setProperty("--p-mx",`${s.nativeEvent.offsetX}px`),e.style.setProperty("--p-my",`${s.nativeEvent.offsetY}px`),O?.(s)},...R,children:o(e,{children:[$?s(i,{}):f,D,u]})}})});