@blakesteve/roster 5.11.0 → 5.13.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 (59) hide show
  1. package/README.md +137 -16
  2. package/dist/components/atoms/Chip/chip-variants.cjs +1 -1
  3. package/dist/components/atoms/Chip/chip-variants.js +8 -2
  4. package/dist/components/atoms/Combobox/Combobox.cjs +1 -1
  5. package/dist/components/atoms/Combobox/Combobox.js +20 -18
  6. package/dist/components/atoms/MultiSelect/MultiSelect.cjs +1 -1
  7. package/dist/components/atoms/MultiSelect/MultiSelect.js +22 -20
  8. package/dist/components/atoms/Select/Select.cjs +1 -1
  9. package/dist/components/atoms/Select/Select.js +19 -17
  10. package/dist/components/molecules/Carousel/Carousel.cjs +1 -1
  11. package/dist/components/molecules/Carousel/Carousel.js +31 -29
  12. package/dist/components/molecules/FileUpload/FileUpload.cjs +1 -1
  13. package/dist/components/molecules/FileUpload/FileUpload.js +21 -19
  14. package/dist/components/molecules/LiquidTabs/LiquidCount.cjs +1 -0
  15. package/dist/components/molecules/LiquidTabs/LiquidCount.d.ts +29 -0
  16. package/dist/components/molecules/LiquidTabs/LiquidCount.js +21 -0
  17. package/dist/components/molecules/LiquidTabs/LiquidNav.cjs +1 -1
  18. package/dist/components/molecules/LiquidTabs/LiquidNav.d.ts +12 -1
  19. package/dist/components/molecules/LiquidTabs/LiquidNav.js +50 -44
  20. package/dist/components/molecules/LiquidTabs/LiquidTabPanel.cjs +1 -0
  21. package/dist/components/molecules/LiquidTabs/LiquidTabPanel.d.ts +52 -0
  22. package/dist/components/molecules/LiquidTabs/LiquidTabPanel.js +32 -0
  23. package/dist/components/molecules/LiquidTabs/LiquidTabs.cjs +1 -1
  24. package/dist/components/molecules/LiquidTabs/LiquidTabs.d.ts +20 -1
  25. package/dist/components/molecules/LiquidTabs/LiquidTabs.js +59 -52
  26. package/dist/components/molecules/LiquidTabs/liquid-count.cjs +1 -0
  27. package/dist/components/molecules/LiquidTabs/liquid-count.d.ts +37 -0
  28. package/dist/components/molecules/LiquidTabs/liquid-count.js +9 -0
  29. package/dist/components/molecules/Menu/Menu.cjs +1 -1
  30. package/dist/components/molecules/Menu/Menu.js +104 -102
  31. package/dist/components/molecules/RadioGroup/RadioGroup.cjs +1 -1
  32. package/dist/components/molecules/RadioGroup/RadioGroup.js +23 -21
  33. package/dist/components/molecules/RangeSlider/RangeSlider.cjs +1 -1
  34. package/dist/components/molecules/RangeSlider/RangeSlider.d.ts +8 -3
  35. package/dist/components/molecules/RangeSlider/RangeSlider.js +38 -36
  36. package/dist/components/molecules/Slider/Slider.cjs +1 -1
  37. package/dist/components/molecules/Slider/Slider.d.ts +7 -3
  38. package/dist/components/molecules/Slider/Slider.js +30 -28
  39. package/dist/components/molecules/Slider/track-parts.d.ts +2 -1
  40. package/dist/components/organisms/Dialog/Dialog.cjs +1 -1
  41. package/dist/components/organisms/Dialog/Dialog.js +19 -17
  42. package/dist/components/organisms/ModerationQueue/ModerationQueue.cjs +1 -1
  43. package/dist/components/organisms/ModerationQueue/ModerationQueue.js +230 -207
  44. package/dist/components/organisms/Navbar/Navbar.cjs +1 -1
  45. package/dist/components/organisms/Navbar/Navbar.js +24 -22
  46. package/dist/components/organisms/Sheet/Sheet.cjs +1 -1
  47. package/dist/components/organisms/Sheet/Sheet.js +25 -23
  48. package/dist/index.d.ts +2 -0
  49. package/dist/internal/key-focus.cjs +1 -0
  50. package/dist/internal/key-focus.d.ts +32 -0
  51. package/dist/internal/key-focus.js +60 -0
  52. package/dist/internal/popup.cjs +1 -1
  53. package/dist/internal/popup.d.ts +15 -1
  54. package/dist/internal/popup.js +17 -12
  55. package/dist/meta.json +3 -3
  56. package/dist/roster.cjs +1 -1
  57. package/dist/roster.css +1 -1
  58. package/dist/roster.js +150 -145
  59. package/package.json +2 -2
package/README.md CHANGED
@@ -555,6 +555,44 @@ the ring with it. In `Menu` the ring shows for keyboard focus only, because the
555
555
  pointer moves focus there too. Headless UI's popups mark the keys' row and the
556
556
  pointer's alike, so in theirs it shows on hover as well.
557
557
 
558
+ **Keyboard focus shows in Safari too.** Every ring is drawn on Roster's
559
+ `focus-visible` variant, which matches the engine's own `:focus-visible` or an
560
+ element marked `data-key-focus`. WebKit doesn't match `:focus-visible` on an
561
+ element a script focuses in answer to a key once the page has been clicked.
562
+ Escape handing focus back to a menu's or a select's trigger, or to a dialog's
563
+ opener, and a radio group's or tabs' arrows all drew no ring in Safari after
564
+ a click. A small tracker marks those elements: keyboard mode starts on a navigation key (Tab, Option+Tab, the
565
+ arrows, Escape, Enter, Space, Home, End, PageUp, PageDown) and ends on pointer
566
+ input, and it marks only what Chromium's own `:focus-visible` already matches,
567
+ so Chromium's rings are unchanged. It runs while a component that moves focus
568
+ is mounted (Menu, the select family, Dialog, Sheet, RadioGroup, LiquidTabs,
569
+ Slider and the rest), on one set of document listeners.
570
+
571
+ Your own components' rings come from your Tailwind, not Roster's, so they
572
+ don't follow the mark on their own. To have them do the same, redefine the
573
+ variant in your stylesheet as Roster does:
574
+
575
+ ```css
576
+ @custom-variant focus-visible (&:is(:focus-visible, [data-key-focus]));
577
+ ```
578
+
579
+ The variant is enough for your rings on a page where one of Roster's
580
+ components has the tracker running. A control of your own that moves focus by
581
+ script in answer to a key, arrows around a hand-drawn wheel or a grid that
582
+ roves its own focus, shouldn't count on one: call `useKeyFocus()` in it, and
583
+ the tracker runs while it's mounted. The listeners are shared, so it costs
584
+ nothing beside Roster's own components. `KEY_FOCUS` is the attribute's name,
585
+ for a selector or a test.
586
+
587
+ ```tsx
588
+ import { useKeyFocus } from "@blakesteve/roster";
589
+
590
+ function Wheel() {
591
+ useKeyFocus();
592
+ // arrows move focus between the stops with stop.focus(); rings on focus-visible:
593
+ }
594
+ ```
595
+
558
596
  ### Motion
559
597
 
560
598
  Two hand-rolled utilities, both of which stop for `prefers-reduced-motion`.
@@ -744,11 +782,10 @@ opens are also legitimately different surfaces in plenty of palettes.
744
782
  **Set these at `:root`, not on a container.** The menu and the tooltip bubble
745
783
  are portaled to `<body>`, so they are not descendants of whatever you rendered
746
784
  the component inside: properties set on a wrapper reach the trigger and stop
747
- there. Any ancestor of `<body>` works — `:root` is simply the one that always
748
- is, which is also why the `.dark` block below reaches a menu whose `.dark`
749
- scope `Select` copies across the portal. The result is a themed trigger opening an unthemed panel, which is the
750
- exact problem this family exists to fix. Set them in both scopes too, for the
751
- same reason the control family needs both.
785
+ there, and the result is a themed trigger opening an unthemed panel, which is
786
+ the exact problem this family exists to fix. Any ancestor of `<body>` works:
787
+ `:root`, `html.dark`, or inline on `<html>` all reach every panel. Set them in
788
+ both scopes too, for the same reason the control family needs both.
752
789
 
753
790
  Where each component takes them, and why not everywhere:
754
791
 
@@ -939,9 +976,12 @@ look like oversights until you know why:
939
976
  variable that inline rule reads:
940
977
  `optionsClassName="rst:[--anchor-max-height:20rem]"`.
941
978
  - **The panel is portaled to `<body>`**, so a `.dark` scoped to part of your
942
- page does not reach it. All three components copy the nearest `.dark` onto
943
- the panel to fix that. Custom properties are not carried the same way — set
944
- `--roster-popover-*` at `:root`.
979
+ page does not reach it. The panel carries `.dark` itself in that case, and
980
+ only then: when `.dark` is on `<html>` or `<body>` the panel is already
981
+ inside it, and carrying the class would re-declare Roster's palette on the
982
+ panel over your own. Every portaled surface does the same (`Menu`, `Sheet`
983
+ and the toasts too). Custom properties are not carried: set
984
+ `--roster-popover-*` on an ancestor of `<body>`.
945
985
  - **A row is a click target, and focus is a ring.** Every option row shows
946
986
  the pointer cursor, as `Menu`'s items do (a disabled one, `not-allowed`).
947
987
  A focused row keeps its tint and adds an inset `--roster-ring`, which is
@@ -1329,6 +1369,10 @@ What it promises:
1329
1369
  item's decision.
1330
1370
  - **Steps take focus and give it back.** Escape or Cancel returns focus to the
1331
1371
  button that opened the step.
1372
+ - **A blocked step says why, plainly.** A step that can't be submitted yet (a
1373
+ reason not picked, an edit with nothing changed) says why in plain text,
1374
+ and its submit is described by it. A submit tried anyway decides nothing
1375
+ and turns the reason into an error.
1332
1376
  - **An item that disappears** (another reviewer, a reload) with its step open
1333
1377
  closes the step without deciding, and is announced once as decided
1334
1378
  elsewhere. Without a step, it moves focus only if focus was inside it.
@@ -1337,10 +1381,11 @@ What it promises:
1337
1381
  - **Phones.** Every button is 44px tall at every width, and nothing scrolls
1338
1382
  sideways at 320px. Nothing animates as an item leaves.
1339
1383
 
1340
- Counts for a tab badge need no API: the app holds the items, so it's
1341
- `items.length`. `MediaPreview` is the thumbnail to use in an item: when the
1342
- image can't render (an expired link, a format the browser can't draw), it
1343
- falls back to a link to the original in the same footprint.
1384
+ Counts for a tab need no API: the app holds the items, so it's
1385
+ `items.length`, passed as a `LiquidTabs` tab's `count`. `MediaPreview` is the
1386
+ thumbnail to use in an item: when the image can't render (an expired link, a
1387
+ format the browser can't draw), it falls back to a link to the original in the
1388
+ same footprint.
1344
1389
 
1345
1390
  ### FileUpload
1346
1391
 
@@ -1650,6 +1695,10 @@ import { Slider } from "@blakesteve/roster";
1650
1695
  still lands anywhere between them. A chip shows as pressed (solid rather
1651
1696
  than outline) while the value is exactly its value, and pressing it again
1652
1697
  leaves it there. A point outside `min` to `max` is left out.
1698
+ - **The label** is a string or a node, so it can carry markup; the slider is
1699
+ named by reference to it, so what's read is its text. A consumer's own
1700
+ `aria-labelledby` names it instead, as when the visible label is shared and
1701
+ each slider needs its own name.
1653
1702
  - **The number** shows beside the label (`formatValue` writes it). A screen
1654
1703
  reader hears it with the nearest snap point's name, "72%, Likely", and
1655
1704
  "Not set" while there's no value, never a number. Every string is in
@@ -1724,6 +1773,8 @@ import { RangeSlider } from "@blakesteve/roster";
1724
1773
  - **Snap points** put a bead on the rail and a `Chip` under it, which does
1725
1774
  what a tap on its mark does: moves the nearer thumb there (halfway, the
1726
1775
  low one). A chip shows as pressed while either thumb is on it.
1776
+ - **The label** takes a node too, and names the group and each thumb by
1777
+ reference; a consumer's `aria-labelledby` names them instead.
1727
1778
  - **The number** beside the label shows both, "$120 – $340"
1728
1779
  (`labels.range`). Each thumb says its own value with the nearest snap
1729
1780
  point's name.
@@ -1849,6 +1900,71 @@ contained. Under reduced motion every scroll the component makes is instant.
1849
1900
  `showPosition` shows "2 of 5", which is also each item's name and is announced
1850
1901
  politely when it changes.
1851
1902
 
1903
+ ### LiquidTabs
1904
+
1905
+ A tab strip with a sliding pill, on the WAI tabs pattern: one tab stop, arrows
1906
+ that wrap, Home and End, and `activation="manual"` for tabs that are costly to
1907
+ switch. `LiquidNav` is the same strip as a `nav` of links.
1908
+
1909
+ **Counts.** A tab or a nav link takes `count`, shown in a small mark after its
1910
+ label:
1911
+
1912
+ ```tsx
1913
+ <LiquidTabs tabs={[{ id: "queue", label: "Queue", count: queue.length }, …]} … />
1914
+ ```
1915
+
1916
+ The count is part of the name, "Queue, 12 items" rather than "Queue12" or
1917
+ "Queue (12)", and its words come from `labels`, English by default with a
1918
+ plural. Name your own noun, and use `Intl.PluralRules` for a language with
1919
+ more than two forms:
1920
+
1921
+ ```tsx
1922
+ labels={{ count: (n) => (n === 1 ? "1 game" : `${n.toLocaleString()} games`) }}
1923
+ ```
1924
+
1925
+ - **Zero shows,** as "0" and "Queue, 0 items": an empty queue is worth
1926
+ saying. To show no count, pass `undefined`.
1927
+ - **A count that isn't a whole number from zero** (negative, a fraction,
1928
+ `NaN`) shows nothing, as if there were none, rather than being rounded or
1929
+ clamped into a number nobody passed.
1930
+ - **Large counts are written whole,** "12,345", in the mark and the name. To
1931
+ shorten the mark, pass `labels.countMark` (`(n) => "12K"`); the name stays
1932
+ whole, since a screen reader has no width to save.
1933
+ - **The mark is drawn from the tab's own text color:** its number in that
1934
+ color on a 12% tint of it. So it follows the tab through every state, both
1935
+ variants and both themes, and through any palette set on the
1936
+ `--roster-lt-*` tokens, and its number clears 4.5:1 in every state on
1937
+ Roster's own (4.88:1 at the least). `Badge` and `Pill` each draw from a fixed
1938
+ palette, which on the selected tab would be a second chip sitting on the
1939
+ pill.
1940
+ - **The pill follows,** re-measuring when a count widens its tab or one
1941
+ before it.
1942
+
1943
+ **The panel.** `LiquidTabPanel` is the `role="tabpanel"` a tab controls, paired
1944
+ with it by construction: its `id` is the tab's `panelId`, and its
1945
+ `aria-labelledby` points at the tab through `liquidTabId`, so the panel takes
1946
+ the tab's name, count included. Give the `LiquidTabs` an `id` to pair it with.
1947
+ One panel that swaps its content, or a panel per tab:
1948
+
1949
+ ```tsx
1950
+ // One panel: every tab carries the same panelId, and `tab` is the selected one.
1951
+ <LiquidTabs id="lists" tabs={tabs.map((t) => ({ ...t, panelId: "lists-panel" }))} activeTab={list} onChange={setList} />
1952
+ <LiquidTabPanel tabsId="lists" id="lists-panel" tab={list}>…</LiquidTabPanel>
1953
+
1954
+ // A panel per tab: each its own panelId, and every panel gets activeTab.
1955
+ <LiquidTabPanel tabsId="views" id="views-board" tab="board" activeTab={view}>…</LiquidTabPanel>
1956
+ <LiquidTabPanel tabsId="views" id="views-list" tab="list" activeTab={view} keepMounted>…</LiquidTabPanel>
1957
+ ```
1958
+
1959
+ Per tab, a panel that isn't selected stays in the page, hidden, so every tab's
1960
+ `aria-controls` points at something, and renders no content. `keepMounted`
1961
+ keeps its content mounted, so a half-filled form or a scroll position survives
1962
+ a switch away and back. A panel with nothing inside it to Tab to is itself in
1963
+ the tab order (`tabIndex={0}`), as the WAI pattern asks, so a keyboard user
1964
+ can reach what they just selected; it leaves the tab order once its content
1965
+ holds a link, a button or a field, rechecked as the content changes. Pass
1966
+ `tabIndex` to decide it yourself.
1967
+
1852
1968
  ### Components that render links
1853
1969
 
1854
1970
  `Breadcrumbs` renders a plain `<a>` by default, which is right for a static
@@ -1870,8 +1986,10 @@ once, and the pages that use the wrapper stay server-rendered.
1870
1986
  `LiquidNav` takes a `linkComponent` too, with a wider contract: each link
1871
1987
  receives `href` and `to` with the same value, so React Router's `Link` works as
1872
1988
  well as `next/link`, plus `className`, `children`, `aria-current`, `onClick` and
1873
- `data-tab-id`, which it must forward to the DOM. The props type is exported as
1874
- `LiquidNavLinkProps`. The same client-component rule applies.
1989
+ `data-tab-id`, which it must forward to the DOM, and `aria-label` when the
1990
+ link has a count (forward it too; a component that doesn't still gets a name
1991
+ with the count in it). The props type is exported as `LiquidNavLinkProps`. The
1992
+ same client-component rule applies.
1875
1993
 
1876
1994
  `Eyebrow` takes the other approach: `as` accepts any element and the props
1877
1995
  follow it, so `<Eyebrow as="a" href="/work">` works, as does `as={NextLink}`.
@@ -1897,7 +2015,8 @@ Dialog or Sheet), alongside `Pagination`, the loading system and DataTable's
1897
2015
  instead, and 5.8.0 adds the ones that were missing: MultiSelect's
1898
2016
  `countLabel`, DataTable's `emptyMessage` and MediaPreview's `newTabLabel`, next
1899
2017
  to the existing `dismissLabel`, `placeholder`, `removeLabel`, `prevLabel` and
1900
- the like. Words that take a number or a name are functions, so a language
2018
+ the like. `LiquidTabs` and `LiquidNav` take `labels` for the words a count
2019
+ says. Words that take a number or a name are functions, so a language
1901
2020
  whose word changes with the count can say so. An entry passed as `undefined`
1902
2021
  (a catalog missing a key) keeps its English rather than leaving a control
1903
2022
  unnamed.
@@ -2009,7 +2128,8 @@ function App() {
2009
2128
  | `EmptyState` | Zero-data placeholder with icon and action slot; `headingLevel` sets its title's `h1` to `h6` |
2010
2129
  | `ErrorState` | Error display with retry action |
2011
2130
  | `LiquidNav` | `LiquidTabs`' strip as a `nav` of links; takes a router's link component |
2012
- | `LiquidTabs` | Tab strip with a sliding pill; arrow keys, roving focus, 44px `lg` size |
2131
+ | `LiquidTabs` | Tab strip with a sliding pill; arrow keys, roving focus, counts, 44px `lg` size (see [LiquidTabs](#liquidtabs)) |
2132
+ | `LiquidTabPanel` | The panel a `LiquidTabs` tab controls, named for its tab by construction; one swapping panel or one per tab |
2013
2133
  | `MatchupCard` | Head-to-head comparison card |
2014
2134
  | `MediaPreview` | Thumbnail that falls back to "Preview unavailable, open original" when it can't render |
2015
2135
  | `Menu` | A button's menu of actions: icons, shortcuts, checkbox and radio items, links, groups, submenus; the full keyboard pattern, 44px targets (see [Menu](#menu)) |
@@ -2096,6 +2216,7 @@ the one that can not be affected by a future change to the barrel.
2096
2216
  | Hook | Description |
2097
2217
  | ---------------- | ------------------------------------------------------------------------------- |
2098
2218
  | `useCountdown` | Countdown timer logic without the UI; `days` counts the whole remaining total |
2219
+ | `useKeyFocus` | Keeps keyboard focus ringed in Safari for your own control that moves focus by script (see [Focus](#focus)). Ships `KEY_FOCUS` |
2099
2220
  | `useKeySequence` | Fires a callback when a sequence of keys is typed in order. Ships `KONAMI_CODE` |
2100
2221
 
2101
2222
  ## Authoring components: the `rst:` prefix
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("../../../node_modules/class-variance-authority/dist/index.cjs"),t=r.cva("rst:font-ui rst:inline-flex rst:items-center rst:rounded-full rst:font-medium rst:whitespace-nowrap rst:align-middle rst:transition-colors",{variants:{colorScheme:{primary:"",success:"",error:"",amber:"",info:"",neutral:""},variant:{soft:"",outline:"rst:bg-transparent rst:border",solid:""},size:{sm:"rst:text-xs rst:px-2.5 rst:py-0.5 rst:gap-1.5",md:"rst:text-sm rst:px-3 rst:py-1 rst:gap-2"},disabled:{true:"rst:opacity-50 rst:cursor-not-allowed",false:""}},compoundVariants:[{variant:"soft",colorScheme:"primary",className:"rst:bg-primary-50 rst:text-primary-700 rst:dark:bg-primary-500/15 rst:dark:text-primary-300"},{variant:"soft",colorScheme:"success",className:"rst:bg-success-50 rst:text-success-700 rst:dark:bg-success-500/15 rst:dark:text-success-300"},{variant:"soft",colorScheme:"error",className:"rst:bg-error-50 rst:text-error-700 rst:dark:bg-error-500/15 rst:dark:text-error-300"},{variant:"soft",colorScheme:"amber",className:"rst:bg-amber-50 rst:text-amber-800 rst:dark:bg-amber-500/15 rst:dark:text-amber-300"},{variant:"soft",colorScheme:"info",className:"rst:bg-info-50 rst:text-info-700 rst:dark:bg-info-500/15 rst:dark:text-info-300"},{variant:"soft",colorScheme:"neutral",className:"rst:bg-gray-100 rst:text-gray-700 rst:dark:bg-gray-500/15 rst:dark:text-gray-300"},{variant:"outline",colorScheme:"primary",className:"rst:border-primary-600 rst:text-primary-700 rst:dark:border-primary-400 rst:dark:text-primary-300"},{variant:"outline",colorScheme:"success",className:"rst:border-success-600 rst:text-success-700 rst:dark:border-success-400 rst:dark:text-success-300"},{variant:"outline",colorScheme:"error",className:"rst:border-error-600 rst:text-error-700 rst:dark:border-error-400 rst:dark:text-error-300"},{variant:"outline",colorScheme:"amber",className:"rst:border-amber-600 rst:text-amber-800 rst:dark:border-amber-400 rst:dark:text-amber-300"},{variant:"outline",colorScheme:"info",className:"rst:border-info-600 rst:text-info-700 rst:dark:border-info-400 rst:dark:text-info-300"},{variant:"outline",colorScheme:"neutral",className:"rst:border-gray-600 rst:text-gray-700 rst:dark:border-gray-400 rst:dark:text-gray-300"},{variant:"solid",colorScheme:"primary",className:"rst:bg-primary-500 rst:text-primary-500-ink"},{variant:"solid",colorScheme:"success",className:"rst:bg-success-500 rst:text-success-500-ink"},{variant:"solid",colorScheme:"error",className:"rst:bg-error-500 rst:text-error-500-ink"},{variant:"solid",colorScheme:"amber",className:"rst:bg-amber-500 rst:text-amber-500-ink"},{variant:"solid",colorScheme:"info",className:"rst:bg-info-500 rst:text-info-500-ink"},{variant:"solid",colorScheme:"neutral",className:"rst:bg-gray-600 rst:dark:bg-gray-500 rst:text-gray-600-ink rst:dark:text-gray-500-ink"}],defaultVariants:{colorScheme:"neutral",variant:"soft",size:"md",disabled:!1}});exports.chipVariants=t;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("../../../node_modules/class-variance-authority/dist/index.cjs"),t=r.cva("rst:font-ui rst:inline-flex rst:items-center rst:rounded-full rst:border rst:border-transparent rst:font-medium rst:whitespace-nowrap rst:align-middle rst:transition-colors",{variants:{colorScheme:{primary:"",success:"",error:"",amber:"",info:"",neutral:""},variant:{soft:"",outline:"rst:bg-transparent",solid:""},size:{sm:"rst:text-xs rst:px-2.5 rst:py-0.5 rst:gap-1.5",md:"rst:text-sm rst:px-3 rst:py-1 rst:gap-2"},disabled:{true:"rst:opacity-50 rst:cursor-not-allowed",false:""}},compoundVariants:[{variant:"soft",colorScheme:"primary",className:"rst:bg-primary-50 rst:text-primary-700 rst:dark:bg-primary-500/15 rst:dark:text-primary-300"},{variant:"soft",colorScheme:"success",className:"rst:bg-success-50 rst:text-success-700 rst:dark:bg-success-500/15 rst:dark:text-success-300"},{variant:"soft",colorScheme:"error",className:"rst:bg-error-50 rst:text-error-700 rst:dark:bg-error-500/15 rst:dark:text-error-300"},{variant:"soft",colorScheme:"amber",className:"rst:bg-amber-50 rst:text-amber-800 rst:dark:bg-amber-500/15 rst:dark:text-amber-300"},{variant:"soft",colorScheme:"info",className:"rst:bg-info-50 rst:text-info-700 rst:dark:bg-info-500/15 rst:dark:text-info-300"},{variant:"soft",colorScheme:"neutral",className:"rst:bg-gray-100 rst:text-gray-700 rst:dark:bg-gray-500/15 rst:dark:text-gray-300"},{variant:"outline",colorScheme:"primary",className:"rst:border-primary-600 rst:text-primary-700 rst:dark:border-primary-400 rst:dark:text-primary-300"},{variant:"outline",colorScheme:"success",className:"rst:border-success-600 rst:text-success-700 rst:dark:border-success-400 rst:dark:text-success-300"},{variant:"outline",colorScheme:"error",className:"rst:border-error-600 rst:text-error-700 rst:dark:border-error-400 rst:dark:text-error-300"},{variant:"outline",colorScheme:"amber",className:"rst:border-amber-600 rst:text-amber-800 rst:dark:border-amber-400 rst:dark:text-amber-300"},{variant:"outline",colorScheme:"info",className:"rst:border-info-600 rst:text-info-700 rst:dark:border-info-400 rst:dark:text-info-300"},{variant:"outline",colorScheme:"neutral",className:"rst:border-gray-600 rst:text-gray-700 rst:dark:border-gray-400 rst:dark:text-gray-300"},{variant:"solid",colorScheme:"primary",className:"rst:bg-primary-500 rst:text-primary-500-ink"},{variant:"solid",colorScheme:"success",className:"rst:bg-success-500 rst:text-success-500-ink"},{variant:"solid",colorScheme:"error",className:"rst:bg-error-500 rst:text-error-500-ink"},{variant:"solid",colorScheme:"amber",className:"rst:bg-amber-500 rst:text-amber-500-ink"},{variant:"solid",colorScheme:"info",className:"rst:bg-info-500 rst:text-info-500-ink"},{variant:"solid",colorScheme:"neutral",className:"rst:bg-gray-600 rst:dark:bg-gray-500 rst:text-gray-600-ink rst:dark:text-gray-500-ink"}],defaultVariants:{colorScheme:"neutral",variant:"soft",size:"md",disabled:!1}});exports.chipVariants=t;
@@ -1,6 +1,12 @@
1
1
  import { cva as r } from "../../../node_modules/class-variance-authority/dist/index.js";
2
2
  const s = /* @__PURE__ */ r(
3
- "rst:font-ui rst:inline-flex rst:items-center rst:rounded-full rst:font-medium rst:whitespace-nowrap rst:align-middle rst:transition-colors",
3
+ /* A border on every variant, transparent where the variant draws none, so
4
+ every variant is one size. Only `outline` had one, so a chip that swaps
5
+ `outline` for `solid` when selected, as a filter row and a slider's snap
6
+ chips do, lost the border's width on both sides at the press and the row
7
+ jumped. A transparent border costs nothing to see: the fill paints under
8
+ it. Its width is `--roster-border-width`, like every edge. */
9
+ "rst:font-ui rst:inline-flex rst:items-center rst:rounded-full rst:border rst:border-transparent rst:font-medium rst:whitespace-nowrap rst:align-middle rst:transition-colors",
4
10
  {
5
11
  variants: {
6
12
  colorScheme: {
@@ -13,7 +19,7 @@ const s = /* @__PURE__ */ r(
13
19
  },
14
20
  variant: {
15
21
  soft: "",
16
- outline: "rst:bg-transparent rst:border",
22
+ outline: "rst:bg-transparent",
17
23
  solid: ""
18
24
  },
19
25
  size: {
@@ -1 +1 @@
1
- "use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),y=require("react"),a=require("../../../node_modules/@headlessui/react/dist/components/combobox/combobox.cjs"),F=require("../../../node_modules/@headlessui/react/dist/components/description/description.cjs"),L=require("../../../node_modules/@headlessui/react/dist/components/field/field.cjs"),R=require("../../../node_modules/@headlessui/react/dist/components/label/label.cjs"),T=require("../../../node_modules/@headlessui/react/dist/components/transition/transition.cjs"),U=require("../../../node_modules/@fortawesome/react-fontawesome/dist/index.cjs"),A=require("../../../node_modules/@fortawesome/free-solid-svg-icons/index.cjs"),i=require("../../../lib/utils.cjs"),j=require("../../../internal/field-invalid.cjs"),V=require("../Input/input-variants.cjs"),E=require("../../../internal/PopupOption.cjs"),l=require("../../../internal/popup.cjs");function H(t){const s=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(t){for(const r in t)if(r!=="default"){const o=Object.getOwnPropertyDescriptor(t,r);Object.defineProperty(s,r,o.get?o:{enumerable:!0,get:()=>t[r]})}}return s.default=t,Object.freeze(s)}const B=H(y),Q=(t,s)=>{const r=s.trim().toLowerCase();return r?t.filter(o=>o.label.toLowerCase().includes(r)):t},W=({options:t,value:s,onChange:r,placeholder:o="Search...",disabled:x=!1,variant:m,size:c,error:P,label:p,helperText:b,errorMessage:u,className:q,inputClassName:O,optionsClassName:g,emptyMessage:N="No matches",filter:C=Q,...f})=>{const[k,v]=B.useState(""),{ref:w,inDarkScope:D}=l.useDarkScope(),d=!!u||P,I=j.isFieldInvalid(d,f),S=j.withoutInvalidProps(f),h=C(t,k),_=t.find(n=>n.value===s)??null;return e.jsxs(L.Field,{disabled:x,className:i.cn("rst:flex rst:flex-col rst:gap-1.5",q),...S,children:[p&&e.jsx(R.Label,{className:"rst:block rst:text-sm rst:font-medium rst:text-[var(--roster-control-text)] rst:text-left",children:p}),e.jsx(a.Combobox,{value:s??null,onChange:r,disabled:x,children:e.jsxs("div",{ref:w,className:"rst:relative",children:[e.jsx(a.ComboboxInput,{"aria-invalid":I||void 0,className:i.cn(V.inputVariants({variant:m,size:c,error:d}),O,"rst:pr-9"),placeholder:o,displayValue:()=>_?.label??"",onChange:n=>v(n.target.value)}),e.jsx(a.ComboboxButton,{className:i.cn("rst:absolute rst:inset-y-0 rst:right-0 rst:flex rst:w-11 rst:cursor-pointer rst:items-center rst:justify-end",c==="sm"?"rst:pr-2.5":"rst:pr-3"),children:e.jsx(U.FontAwesomeIcon,{icon:A.faChevronDown,className:"rst:h-3.5 rst:w-3.5 rst:text-gray-400 rst:dark:text-gray-500","aria-hidden":"true"})}),e.jsx(T.Transition,{as:y.Fragment,leave:"rst:transition rst:ease-in rst:duration-100",leaveFrom:"rst:opacity-100",leaveTo:"rst:opacity-0",afterLeave:()=>v(""),children:e.jsx(a.ComboboxOptions,{anchor:l.POPUP_ANCHOR,className:i.cn(l.popupInDarkPalette(D,m)&&"dark",l.POPUP_PANEL,l.POPUP_WIDTH_OF_INPUT,g),children:h.length===0?e.jsx(a.ComboboxOption,{value:"",disabled:!0,className:i.cn("rst:px-4 rst:py-2.5 rst:text-sm rst:opacity-70",c==="sm"&&"rst:px-3 rst:py-2"),children:N}):h.map(n=>e.jsx(E.PopupOption,{as:a.ComboboxOption,value:n.value,disabled:n.disabled,size:c,children:n.label},n.value))})})]})}),(b||u)&&e.jsx(F.Description,{className:i.cn("rst:text-xs rst:text-left",d?"rst:text-error-600 rst:dark:text-error-400 rst:font-medium":"rst:text-gray-500 rst:dark:text-gray-400"),children:u||b})]})};exports.Combobox=W;
1
+ "use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),j=require("react"),a=require("../../../node_modules/@headlessui/react/dist/components/combobox/combobox.cjs"),_=require("../../../node_modules/@headlessui/react/dist/components/description/description.cjs"),L=require("../../../node_modules/@headlessui/react/dist/components/field/field.cjs"),R=require("../../../node_modules/@headlessui/react/dist/components/label/label.cjs"),T=require("../../../node_modules/@headlessui/react/dist/components/transition/transition.cjs"),U=require("../../../node_modules/@fortawesome/react-fontawesome/dist/index.cjs"),A=require("../../../node_modules/@fortawesome/free-solid-svg-icons/index.cjs"),i=require("../../../lib/utils.cjs"),h=require("../../../internal/field-invalid.cjs"),V=require("../Input/input-variants.cjs"),E=require("../../../internal/PopupOption.cjs"),c=require("../../../internal/popup.cjs"),H=require("../../../internal/key-focus.cjs");function B(t){const s=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(t){for(const r in t)if(r!=="default"){const n=Object.getOwnPropertyDescriptor(t,r);Object.defineProperty(s,r,n.get?n:{enumerable:!0,get:()=>t[r]})}}return s.default=t,Object.freeze(s)}const K=B(j),Q=(t,s)=>{const r=s.trim().toLowerCase();return r?t.filter(n=>n.label.toLowerCase().includes(r)):t},W=({options:t,value:s,onChange:r,placeholder:n="Search...",disabled:x=!1,variant:m,size:l,error:P,label:p,helperText:b,errorMessage:u,className:q,inputClassName:O,optionsClassName:g,emptyMessage:N="No matches",filter:C=Q,...f})=>{H.useKeyFocus();const[k,v]=K.useState(""),{ref:F,inDarkScope:w}=c.useDarkScope(),d=!!u||P,D=h.isFieldInvalid(d,f),I=h.withoutInvalidProps(f),y=C(t,k),S=t.find(o=>o.value===s)??null;return e.jsxs(L.Field,{disabled:x,className:i.cn("rst:flex rst:flex-col rst:gap-1.5",q),...I,children:[p&&e.jsx(R.Label,{className:"rst:block rst:text-sm rst:font-medium rst:text-[var(--roster-control-text)] rst:text-left",children:p}),e.jsx(a.Combobox,{value:s??null,onChange:r,disabled:x,children:e.jsxs("div",{ref:F,className:"rst:relative",children:[e.jsx(a.ComboboxInput,{"aria-invalid":D||void 0,className:i.cn(V.inputVariants({variant:m,size:l,error:d}),O,"rst:pr-9"),placeholder:n,displayValue:()=>S?.label??"",onChange:o=>v(o.target.value)}),e.jsx(a.ComboboxButton,{className:i.cn("rst:absolute rst:inset-y-0 rst:right-0 rst:flex rst:w-11 rst:cursor-pointer rst:items-center rst:justify-end",l==="sm"?"rst:pr-2.5":"rst:pr-3"),children:e.jsx(U.FontAwesomeIcon,{icon:A.faChevronDown,className:"rst:h-3.5 rst:w-3.5 rst:text-gray-400 rst:dark:text-gray-500","aria-hidden":"true"})}),e.jsx(T.Transition,{as:j.Fragment,leave:"rst:transition rst:ease-in rst:duration-100",leaveFrom:"rst:opacity-100",leaveTo:"rst:opacity-0",afterLeave:()=>v(""),children:e.jsx(a.ComboboxOptions,{anchor:c.POPUP_ANCHOR,className:i.cn(c.popupInDarkPalette(w,m)&&"dark",c.POPUP_PANEL,c.POPUP_WIDTH_OF_INPUT,g),children:y.length===0?e.jsx(a.ComboboxOption,{value:"",disabled:!0,className:i.cn("rst:px-4 rst:py-2.5 rst:text-sm rst:opacity-70",l==="sm"&&"rst:px-3 rst:py-2"),children:N}):y.map(o=>e.jsx(E.PopupOption,{as:a.ComboboxOption,value:o.value,disabled:o.disabled,size:l,children:o.label},o.value))})})]})}),(b||u)&&e.jsx(_.Description,{className:i.cn("rst:text-xs rst:text-left",d?"rst:text-error-600 rst:dark:text-error-400 rst:font-medium":"rst:text-gray-500 rst:dark:text-gray-400"),children:u||b})]})};exports.Combobox=W;
@@ -8,16 +8,17 @@ import { Field as T } from "../../../node_modules/@headlessui/react/dist/compone
8
8
  import { Label as q } from "../../../node_modules/@headlessui/react/dist/components/label/label.js";
9
9
  import { Transition as B } from "../../../node_modules/@headlessui/react/dist/components/transition/transition.js";
10
10
  import { FontAwesomeIcon as E } from "../../../node_modules/@fortawesome/react-fontawesome/dist/index.js";
11
- import { faChevronDown as V } from "../../../node_modules/@fortawesome/free-solid-svg-icons/index.js";
11
+ import { faChevronDown as K } from "../../../node_modules/@fortawesome/free-solid-svg-icons/index.js";
12
12
  import { cn as e } from "../../../lib/utils.js";
13
- import { isFieldInvalid as W, withoutInvalidProps as K } from "../../../internal/field-invalid.js";
13
+ import { isFieldInvalid as V, withoutInvalidProps as W } from "../../../internal/field-invalid.js";
14
14
  import { inputVariants as Q } from "../Input/input-variants.js";
15
15
  import { PopupOption as Z } from "../../../internal/PopupOption.js";
16
16
  import { useDarkScope as G, POPUP_ANCHOR as J, POPUP_WIDTH_OF_INPUT as X, POPUP_PANEL as Y, popupInDarkPalette as $ } from "../../../internal/popup.js";
17
- const M = (s, o) => {
17
+ import { useKeyFocus as M } from "../../../internal/key-focus.js";
18
+ const z = (s, o) => {
18
19
  const a = o.trim().toLowerCase();
19
20
  return a ? s.filter((l) => l.label.toLowerCase().includes(a)) : s;
20
- }, ft = ({
21
+ }, xt = ({
21
22
  options: s,
22
23
  value: o,
23
24
  onChange: a,
@@ -25,23 +26,24 @@ const M = (s, o) => {
25
26
  disabled: c = !1,
26
27
  variant: d,
27
28
  size: i,
28
- error: P,
29
+ error: y,
29
30
  label: p,
30
31
  helperText: f,
31
- errorMessage: n,
32
- className: y,
32
+ errorMessage: m,
33
+ className: P,
33
34
  inputClassName: N,
34
35
  optionsClassName: C,
35
36
  emptyMessage: k = "No matches",
36
- filter: g = M,
37
+ filter: g = z,
37
38
  ...u
38
39
  }) => {
39
- const [O, x] = U.useState(""), { ref: w, inDarkScope: F } = G(), m = !!n || P, I = W(m, u), D = K(u), h = g(s, O), L = s.find((r) => r.value === o) ?? null;
40
+ M();
41
+ const [F, x] = U.useState(""), { ref: O, inDarkScope: w } = G(), n = !!m || y, I = V(n, u), D = W(u), h = g(s, F), L = s.find((r) => r.value === o) ?? null;
40
42
  return /* @__PURE__ */ b(
41
43
  T,
42
44
  {
43
45
  disabled: c,
44
- className: e("rst:flex rst:flex-col rst:gap-1.5", y),
46
+ className: e("rst:flex rst:flex-col rst:gap-1.5", P),
45
47
  ...D,
46
48
  children: [
47
49
  p && /* @__PURE__ */ t(q, { className: "rst:block rst:text-sm rst:font-medium rst:text-[var(--roster-control-text)] rst:text-left", children: p }),
@@ -51,13 +53,13 @@ const M = (s, o) => {
51
53
  value: o ?? null,
52
54
  onChange: a,
53
55
  disabled: c,
54
- children: /* @__PURE__ */ b("div", { ref: w, className: "rst:relative", children: [
56
+ children: /* @__PURE__ */ b("div", { ref: O, className: "rst:relative", children: [
55
57
  /* @__PURE__ */ t(
56
58
  S,
57
59
  {
58
60
  "aria-invalid": I || void 0,
59
61
  className: e(
60
- Q({ variant: d, size: i, error: m }),
62
+ Q({ variant: d, size: i, error: n }),
61
63
  N,
62
64
  "rst:pr-9"
63
65
  ),
@@ -76,7 +78,7 @@ const M = (s, o) => {
76
78
  children: /* @__PURE__ */ t(
77
79
  E,
78
80
  {
79
- icon: V,
81
+ icon: K,
80
82
  className: "rst:h-3.5 rst:w-3.5 rst:text-gray-400 rst:dark:text-gray-500",
81
83
  "aria-hidden": "true"
82
84
  }
@@ -96,7 +98,7 @@ const M = (s, o) => {
96
98
  {
97
99
  anchor: J,
98
100
  className: e(
99
- $(F, d) && "dark",
101
+ $(w, d) && "dark",
100
102
  Y,
101
103
  /* `--input-width`, not `--button-width`: the button here is
102
104
  the chevron, so matching it renders a 20px sliver. */
@@ -132,14 +134,14 @@ const M = (s, o) => {
132
134
  ] })
133
135
  }
134
136
  ),
135
- (f || n) && /* @__PURE__ */ t(
137
+ (f || m) && /* @__PURE__ */ t(
136
138
  R,
137
139
  {
138
140
  className: e(
139
141
  "rst:text-xs rst:text-left",
140
- m ? "rst:text-error-600 rst:dark:text-error-400 rst:font-medium" : "rst:text-gray-500 rst:dark:text-gray-400"
142
+ n ? "rst:text-error-600 rst:dark:text-error-400 rst:font-medium" : "rst:text-gray-500 rst:dark:text-gray-400"
141
143
  ),
142
- children: n || f
144
+ children: m || f
143
145
  }
144
146
  )
145
147
  ]
@@ -147,5 +149,5 @@ const M = (s, o) => {
147
149
  );
148
150
  };
149
151
  export {
150
- ft as Combobox
152
+ xt as Combobox
151
153
  };
@@ -1 +1 @@
1
- "use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime"),T=require("react"),W=require("../../../node_modules/@headlessui/react/dist/components/description/description.cjs"),X=require("../../../node_modules/@headlessui/react/dist/components/field/field.cjs"),G=require("../../../node_modules/@headlessui/react/dist/components/label/label.cjs"),h=require("../../../node_modules/@headlessui/react/dist/components/listbox/listbox.cjs"),J=require("../../../node_modules/@headlessui/react/dist/components/transition/transition.cjs"),F=require("../../../node_modules/@fortawesome/react-fontawesome/dist/index.cjs"),R=require("../../../node_modules/@fortawesome/free-solid-svg-icons/index.cjs"),n=require("../../../lib/utils.cjs"),_=require("../../../internal/field-invalid.cjs"),K=require("../Select/select-variants.cjs"),D=require("../Chip/Chip.cjs"),Q=require("../../../internal/PopupOption.cjs"),c=require("../../../internal/popup.cjs"),Z=({options:x,value:i,onChange:m,placeholder:v="Select options",disabled:l=!1,variant:f,size:o,error:L,className:A,triggerClassName:E,optionsClassName:U,helperText:b,errorMessage:p,label:g,display:u="chips",maxChips:N,clearable:j=!1,chipColorScheme:w="neutral",chipVariant:k="outline",clearLabel:$="Clear selection",removeLabel:C=e=>`Remove ${e}`,countLabel:I=e=>`${e} selected`,...P})=>{const e=!!p||L,V=_.isFieldInvalid(e,P),B=_.withoutInvalidProps(P),a=i.length>0,y=new Map(x.map((r,s)=>[r.value,s])),d=i.map(r=>({value:r,label:x.find(s=>s.value===r)?.label??String(r)})).sort((r,s)=>(y.get(r.value)??Number.POSITIVE_INFINITY)-(y.get(s.value)??Number.POSITIVE_INFINITY)),q=N===void 0?d:d.slice(0,N),O=d.length-q.length,{ref:H,inDarkScope:M}=c.useDarkScope(),S=T.useRef(null);return t.jsxs(X.Field,{disabled:l,className:n.cn("rst:flex rst:flex-col rst:gap-1.5",A),...B,children:[g&&t.jsx(G.Label,{className:"rst:block rst:text-sm rst:font-medium rst:text-[var(--roster-control-text)] rst:text-left",children:g}),t.jsx(h.Listbox,{value:i,onChange:m,disabled:l,multiple:!0,children:t.jsxs("div",{ref:H,className:"rst:relative",children:[t.jsxs("div",{className:n.cn(K.selectTriggerVariants({variant:f,size:o,error:e}),"rst:h-auto rst:flex-wrap rst:items-center rst:gap-1.5 rst:py-1.5",o==="sm"?"rst:min-h-9":o==="lg"?"rst:min-h-11":"rst:min-h-10",j&&a&&"rst:pr-16","rst:focus-within:ring-[length:calc(var(--roster-border-width,1px)+1px)] rst:focus-within:ring-ring",l&&"rst:opacity-50 rst:cursor-not-allowed",E),children:[t.jsx(h.ListboxButton,{ref:S,"aria-invalid":V||void 0,className:"rst:absolute rst:inset-0 rst:h-full rst:w-full rst:cursor-pointer rst:rounded-md rst:focus:outline-hidden rst:disabled:cursor-not-allowed",children:t.jsx("span",{className:"rst:sr-only",children:a?u==="count"?I(i.length):d.map(r=>r.label).join(", "):v})}),!a&&t.jsx("span",{"aria-hidden":"true",className:"rst:pointer-events-none rst:relative rst:block rst:truncate rst:text-gray-500 rst:dark:text-gray-400",children:v}),a&&u==="count"&&t.jsx("span",{"aria-hidden":"true",className:"rst:pointer-events-none rst:relative rst:block rst:truncate",children:I(i.length)}),a&&u==="chips"&&q.map((r,s)=>t.jsx(D.Chip,{size:"sm",variant:k,colorScheme:w,disabled:l,onRemove:()=>m(i.filter(Y=>Y!==r.value)),removeLabel:C(r.label),className:n.cn("rst:relative rst:max-w-[12rem] rst:pointer-events-none","rst:[&_button]:pointer-events-auto","rst:text-inherit rst:border-current/70 rst:dark:text-inherit rst:dark:border-current/70"),children:t.jsx("span",{className:"rst:block rst:truncate",children:r.label})},`${s}-${String(r.value)}`)),O>0&&u==="chips"&&t.jsxs(D.Chip,{size:"sm",variant:k,colorScheme:w,"aria-hidden":"true",className:"rst:pointer-events-none rst:relative rst:text-inherit rst:border-current/70 rst:dark:text-inherit rst:dark:border-current/70",children:["+",O]}),t.jsx("span",{className:n.cn("rst:pointer-events-none rst:absolute rst:inset-y-0 rst:right-0 rst:flex rst:items-center",o==="sm"?"rst:pr-2.5":"rst:pr-3"),children:t.jsx(F.FontAwesomeIcon,{icon:R.faChevronDown,className:"rst:h-3.5 rst:w-3.5 rst:text-gray-400 rst:dark:text-gray-500","aria-hidden":"true"})}),j&&a&&t.jsx("button",{type:"button",disabled:l,onClick:()=>{m([]),S.current?.focus()},"aria-label":$,className:n.cn("rst:absolute rst:inset-y-0 rst:flex rst:w-6 rst:items-center rst:justify-center","rst:cursor-pointer rst:disabled:cursor-not-allowed","rst:text-current rst:opacity-70 rst:hover:opacity-100 rst:disabled:opacity-40","rst:focus:outline-hidden rst:focus-visible:ring-2 rst:focus-visible:ring-ring rst:rounded-sm",o==="sm"?"rst:right-7":"rst:right-8"),children:t.jsx(F.FontAwesomeIcon,{icon:R.faXmark,className:"rst:h-3.5 rst:w-3.5","aria-hidden":"true"})})]}),t.jsx(J.Transition,{as:T.Fragment,leave:"rst:transition rst:ease-in rst:duration-100",leaveFrom:"rst:opacity-100",leaveTo:"rst:opacity-0",children:t.jsx(h.ListboxOptions,{anchor:c.POPUP_ANCHOR,className:n.cn(c.popupInDarkPalette(M,f)&&"dark",c.POPUP_PANEL,c.POPUP_WIDTH_OF_BUTTON,U),children:x.map(r=>t.jsx(Q.PopupOption,{as:h.ListboxOption,value:r.value,disabled:r.disabled,size:o,children:r.label},r.value))})})]})}),(b||p)&&t.jsx(W.Description,{className:n.cn("rst:text-xs rst:text-left",e?"rst:text-error-600 rst:dark:text-error-400 rst:font-medium":"rst:text-gray-500 rst:dark:text-gray-400"),children:p||b})]})};exports.MultiSelect=Z;
1
+ "use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime"),F=require("react"),K=require("../../../node_modules/@headlessui/react/dist/components/description/description.cjs"),W=require("../../../node_modules/@headlessui/react/dist/components/field/field.cjs"),X=require("../../../node_modules/@headlessui/react/dist/components/label/label.cjs"),h=require("../../../node_modules/@headlessui/react/dist/components/listbox/listbox.cjs"),G=require("../../../node_modules/@headlessui/react/dist/components/transition/transition.cjs"),T=require("../../../node_modules/@fortawesome/react-fontawesome/dist/index.cjs"),R=require("../../../node_modules/@fortawesome/free-solid-svg-icons/index.cjs"),n=require("../../../lib/utils.cjs"),_=require("../../../internal/field-invalid.cjs"),J=require("../Select/select-variants.cjs"),D=require("../Chip/Chip.cjs"),Q=require("../../../internal/PopupOption.cjs"),c=require("../../../internal/popup.cjs"),Z=require("../../../internal/key-focus.cjs"),z=({options:x,value:i,onChange:m,placeholder:v="Select options",disabled:l=!1,variant:f,size:o,error:L,className:A,triggerClassName:E,optionsClassName:U,helperText:b,errorMessage:p,label:g,display:u="chips",maxChips:N,clearable:j=!1,chipColorScheme:k="neutral",chipVariant:w="outline",clearLabel:$="Clear selection",removeLabel:C=e=>`Remove ${e}`,countLabel:y=e=>`${e} selected`,...I})=>{Z.useKeyFocus();const e=!!p||L,V=_.isFieldInvalid(e,I),B=_.withoutInvalidProps(I),a=i.length>0,P=new Map(x.map((r,s)=>[r.value,s])),d=i.map(r=>({value:r,label:x.find(s=>s.value===r)?.label??String(r)})).sort((r,s)=>(P.get(r.value)??Number.POSITIVE_INFINITY)-(P.get(s.value)??Number.POSITIVE_INFINITY)),q=N===void 0?d:d.slice(0,N),O=d.length-q.length,{ref:H,inDarkScope:M}=c.useDarkScope(),S=F.useRef(null);return t.jsxs(W.Field,{disabled:l,className:n.cn("rst:flex rst:flex-col rst:gap-1.5",A),...B,children:[g&&t.jsx(X.Label,{className:"rst:block rst:text-sm rst:font-medium rst:text-[var(--roster-control-text)] rst:text-left",children:g}),t.jsx(h.Listbox,{value:i,onChange:m,disabled:l,multiple:!0,children:t.jsxs("div",{ref:H,className:"rst:relative",children:[t.jsxs("div",{className:n.cn(J.selectTriggerVariants({variant:f,size:o,error:e}),"rst:h-auto rst:flex-wrap rst:items-center rst:gap-1.5 rst:py-1.5",o==="sm"?"rst:min-h-9":o==="lg"?"rst:min-h-11":"rst:min-h-10",j&&a&&"rst:pr-16","rst:focus-within:ring-[length:calc(var(--roster-border-width,1px)+1px)] rst:focus-within:ring-ring",l&&"rst:opacity-50 rst:cursor-not-allowed",E),children:[t.jsx(h.ListboxButton,{ref:S,"aria-invalid":V||void 0,className:"rst:absolute rst:inset-0 rst:h-full rst:w-full rst:cursor-pointer rst:rounded-md rst:focus:outline-hidden rst:disabled:cursor-not-allowed",children:t.jsx("span",{className:"rst:sr-only",children:a?u==="count"?y(i.length):d.map(r=>r.label).join(", "):v})}),!a&&t.jsx("span",{"aria-hidden":"true",className:"rst:pointer-events-none rst:relative rst:block rst:truncate rst:text-gray-500 rst:dark:text-gray-400",children:v}),a&&u==="count"&&t.jsx("span",{"aria-hidden":"true",className:"rst:pointer-events-none rst:relative rst:block rst:truncate",children:y(i.length)}),a&&u==="chips"&&q.map((r,s)=>t.jsx(D.Chip,{size:"sm",variant:w,colorScheme:k,disabled:l,onRemove:()=>m(i.filter(Y=>Y!==r.value)),removeLabel:C(r.label),className:n.cn("rst:relative rst:max-w-[12rem] rst:pointer-events-none","rst:[&_button]:pointer-events-auto","rst:text-inherit rst:border-current/70 rst:dark:text-inherit rst:dark:border-current/70"),children:t.jsx("span",{className:"rst:block rst:truncate",children:r.label})},`${s}-${String(r.value)}`)),O>0&&u==="chips"&&t.jsxs(D.Chip,{size:"sm",variant:w,colorScheme:k,"aria-hidden":"true",className:"rst:pointer-events-none rst:relative rst:text-inherit rst:border-current/70 rst:dark:text-inherit rst:dark:border-current/70",children:["+",O]}),t.jsx("span",{className:n.cn("rst:pointer-events-none rst:absolute rst:inset-y-0 rst:right-0 rst:flex rst:items-center",o==="sm"?"rst:pr-2.5":"rst:pr-3"),children:t.jsx(T.FontAwesomeIcon,{icon:R.faChevronDown,className:"rst:h-3.5 rst:w-3.5 rst:text-gray-400 rst:dark:text-gray-500","aria-hidden":"true"})}),j&&a&&t.jsx("button",{type:"button",disabled:l,onClick:()=>{m([]),S.current?.focus()},"aria-label":$,className:n.cn("rst:absolute rst:inset-y-0 rst:flex rst:w-6 rst:items-center rst:justify-center","rst:cursor-pointer rst:disabled:cursor-not-allowed","rst:text-current rst:opacity-70 rst:hover:opacity-100 rst:disabled:opacity-40","rst:focus:outline-hidden rst:focus-visible:ring-2 rst:focus-visible:ring-ring rst:rounded-sm",o==="sm"?"rst:right-7":"rst:right-8"),children:t.jsx(T.FontAwesomeIcon,{icon:R.faXmark,className:"rst:h-3.5 rst:w-3.5","aria-hidden":"true"})})]}),t.jsx(G.Transition,{as:F.Fragment,leave:"rst:transition rst:ease-in rst:duration-100",leaveFrom:"rst:opacity-100",leaveTo:"rst:opacity-0",children:t.jsx(h.ListboxOptions,{anchor:c.POPUP_ANCHOR,className:n.cn(c.popupInDarkPalette(M,f)&&"dark",c.POPUP_PANEL,c.POPUP_WIDTH_OF_BUTTON,U),children:x.map(r=>t.jsx(Q.PopupOption,{as:h.ListboxOption,value:r.value,disabled:r.disabled,size:o,children:r.label},r.value))})})]})}),(b||p)&&t.jsx(K.Description,{className:n.cn("rst:text-xs rst:text-left",e?"rst:text-error-600 rst:dark:text-error-400 rst:font-medium":"rst:text-gray-500 rst:dark:text-gray-400"),children:p||b})]})};exports.MultiSelect=z;
@@ -1,20 +1,21 @@
1
1
  "use client";
2
2
  import { jsxs as d, jsx as r } from "react/jsx-runtime";
3
- import V, { Fragment as W } from "react";
4
- import { Description as Y } from "../../../node_modules/@headlessui/react/dist/components/description/description.js";
5
- import { Field as C } from "../../../node_modules/@headlessui/react/dist/components/field/field.js";
6
- import { Label as K } from "../../../node_modules/@headlessui/react/dist/components/label/label.js";
3
+ import K, { Fragment as V } from "react";
4
+ import { Description as W } from "../../../node_modules/@headlessui/react/dist/components/description/description.js";
5
+ import { Field as Y } from "../../../node_modules/@headlessui/react/dist/components/field/field.js";
6
+ import { Label as C } from "../../../node_modules/@headlessui/react/dist/components/label/label.js";
7
7
  import { Listbox as X, ListboxButton as Z, ListboxOptions as q, ListboxOption as G } from "../../../node_modules/@headlessui/react/dist/components/listbox/listbox.js";
8
8
  import { Transition as J } from "../../../node_modules/@headlessui/react/dist/components/transition/transition.js";
9
- import { FontAwesomeIcon as T } from "../../../node_modules/@fortawesome/react-fontawesome/dist/index.js";
9
+ import { FontAwesomeIcon as F } from "../../../node_modules/@fortawesome/react-fontawesome/dist/index.js";
10
10
  import { faChevronDown as Q, faXmark as z } from "../../../node_modules/@fortawesome/free-solid-svg-icons/index.js";
11
11
  import { cn as n } from "../../../lib/utils.js";
12
12
  import { isFieldInvalid as tt, withoutInvalidProps as rt } from "../../../internal/field-invalid.js";
13
13
  import { selectTriggerVariants as et } from "../Select/select-variants.js";
14
- import { Chip as F } from "../Chip/Chip.js";
14
+ import { Chip as T } from "../Chip/Chip.js";
15
15
  import { PopupOption as st } from "../../../internal/PopupOption.js";
16
16
  import { useDarkScope as nt, POPUP_ANCHOR as ot, POPUP_WIDTH_OF_BUTTON as it, POPUP_PANEL as at, popupInDarkPalette as lt } from "../../../internal/popup.js";
17
- const Pt = ({
17
+ import { useKeyFocus as ct } from "../../../internal/key-focus.js";
18
+ const Ot = ({
18
19
  options: u,
19
20
  value: o,
20
21
  onChange: p,
@@ -37,22 +38,23 @@ const Pt = ({
37
38
  clearLabel: E = "Clear selection",
38
39
  removeLabel: U = (e) => `Remove ${e}`,
39
40
  countLabel: I = (e) => `${e} selected`,
40
- ...P
41
+ ...y
41
42
  }) => {
42
- const e = !!h || R, $ = tt(e, P), A = rt(P), a = o.length > 0, y = new Map(u.map((t, s) => [t.value, s])), m = o.map((t) => ({
43
+ ct();
44
+ const e = !!h || R, $ = tt(e, y), A = rt(y), a = o.length > 0, P = new Map(u.map((t, s) => [t.value, s])), m = o.map((t) => ({
43
45
  value: t,
44
46
  label: u.find((s) => s.value === t)?.label ?? String(t)
45
47
  })).sort(
46
- (t, s) => (y.get(t.value) ?? Number.POSITIVE_INFINITY) - (y.get(s.value) ?? Number.POSITIVE_INFINITY)
47
- ), O = g === void 0 ? m : m.slice(0, g), S = m.length - O.length, { ref: B, inDarkScope: M } = nt(), _ = V.useRef(null);
48
+ (t, s) => (P.get(t.value) ?? Number.POSITIVE_INFINITY) - (P.get(s.value) ?? Number.POSITIVE_INFINITY)
49
+ ), O = g === void 0 ? m : m.slice(0, g), S = m.length - O.length, { ref: B, inDarkScope: M } = nt(), _ = K.useRef(null);
48
50
  return /* @__PURE__ */ d(
49
- C,
51
+ Y,
50
52
  {
51
53
  disabled: l,
52
54
  className: n("rst:flex rst:flex-col rst:gap-1.5", D),
53
55
  ...A,
54
56
  children: [
55
- b && /* @__PURE__ */ r(K, { className: "rst:block rst:text-sm rst:font-medium rst:text-[var(--roster-control-text)] rst:text-left", children: b }),
57
+ b && /* @__PURE__ */ r(C, { className: "rst:block rst:text-sm rst:font-medium rst:text-[var(--roster-control-text)] rst:text-left", children: b }),
56
58
  /* @__PURE__ */ r(X, { value: o, onChange: p, disabled: l, multiple: !0, children: /* @__PURE__ */ d("div", { ref: B, className: "rst:relative", children: [
57
59
  /* @__PURE__ */ d(
58
60
  "div",
@@ -98,7 +100,7 @@ const Pt = ({
98
100
  }
99
101
  ),
100
102
  a && c === "chips" && O.map((t, s) => /* @__PURE__ */ r(
101
- F,
103
+ T,
102
104
  {
103
105
  size: "sm",
104
106
  variant: w,
@@ -116,7 +118,7 @@ const Pt = ({
116
118
  `${s}-${String(t.value)}`
117
119
  )),
118
120
  S > 0 && c === "chips" && /* @__PURE__ */ d(
119
- F,
121
+ T,
120
122
  {
121
123
  size: "sm",
122
124
  variant: w,
@@ -137,7 +139,7 @@ const Pt = ({
137
139
  i === "sm" ? "rst:pr-2.5" : "rst:pr-3"
138
140
  ),
139
141
  children: /* @__PURE__ */ r(
140
- T,
142
+ F,
141
143
  {
142
144
  icon: Q,
143
145
  className: "rst:h-3.5 rst:w-3.5 rst:text-gray-400 rst:dark:text-gray-500",
@@ -167,7 +169,7 @@ const Pt = ({
167
169
  i === "sm" ? "rst:right-7" : "rst:right-8"
168
170
  ),
169
171
  children: /* @__PURE__ */ r(
170
- T,
172
+ F,
171
173
  {
172
174
  icon: z,
173
175
  className: "rst:h-3.5 rst:w-3.5",
@@ -182,7 +184,7 @@ const Pt = ({
182
184
  /* @__PURE__ */ r(
183
185
  J,
184
186
  {
185
- as: W,
187
+ as: V,
186
188
  leave: "rst:transition rst:ease-in rst:duration-100",
187
189
  leaveFrom: "rst:opacity-100",
188
190
  leaveTo: "rst:opacity-0",
@@ -213,7 +215,7 @@ const Pt = ({
213
215
  )
214
216
  ] }) }),
215
217
  (x || h) && /* @__PURE__ */ r(
216
- Y,
218
+ W,
217
219
  {
218
220
  className: n(
219
221
  "rst:text-xs rst:text-left",
@@ -227,5 +229,5 @@ const Pt = ({
227
229
  );
228
230
  };
229
231
  export {
230
- Pt as MultiSelect
232
+ Ot as MultiSelect
231
233
  };
@@ -1 +1 @@
1
- "use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime"),S=require("react"),D=require("../../../node_modules/@headlessui/react/dist/components/description/description.cjs"),F=require("../../../node_modules/@headlessui/react/dist/components/field/field.cjs"),I=require("../../../node_modules/@headlessui/react/dist/components/label/label.cjs"),n=require("../../../node_modules/@headlessui/react/dist/components/listbox/listbox.cjs"),L=require("../../../node_modules/@headlessui/react/dist/components/transition/transition.cjs"),T=require("../../../node_modules/@fortawesome/react-fontawesome/dist/index.cjs"),_=require("../../../node_modules/@fortawesome/free-solid-svg-icons/index.cjs"),r=require("../../../lib/utils.cjs"),f=require("../../../internal/field-invalid.cjs"),w=require("./select-variants.cjs"),R=require("../../../internal/PopupOption.cjs"),s=require("../../../internal/popup.cjs"),U=({options:o,value:d,onChange:h,placeholder:P="Select an option",disabled:u=!1,variant:x,size:i,error:b,className:j,triggerClassName:q,optionsClassName:N,helperText:p,errorMessage:a,label:m,...v})=>{const c=o.find(e=>e.value===d),l=!!a||b,O=f.isFieldInvalid(l,v),g=f.withoutInvalidProps(v),{ref:y,inDarkScope:k}=s.useDarkScope();return t.jsxs(F.Field,{disabled:u,className:r.cn("rst:flex rst:flex-col rst:gap-1.5",j),...g,children:[m&&t.jsx(I.Label,{className:"rst:block rst:text-sm rst:font-medium rst:text-[var(--roster-control-text)] rst:text-left",children:m}),t.jsx(n.Listbox,{value:d??void 0,onChange:h,disabled:u,children:t.jsxs("div",{ref:y,className:"rst:relative",children:[t.jsxs(n.ListboxButton,{"aria-invalid":O||void 0,className:r.cn(w.selectTriggerVariants({variant:x,size:i,error:l}),q),children:[t.jsx("span",{className:r.cn("rst:block rst:truncate",!c&&"rst:text-gray-500 rst:dark:text-gray-400"),children:c?c.label:P}),t.jsx("span",{className:r.cn("rst:pointer-events-none rst:absolute rst:inset-y-0 rst:right-0 rst:flex rst:items-center",i==="sm"?"rst:pr-2.5":"rst:pr-3"),children:t.jsx(T.FontAwesomeIcon,{icon:_.faChevronDown,className:"rst:h-3.5 rst:w-3.5 rst:text-gray-400 rst:dark:text-gray-500","aria-hidden":"true"})})]}),t.jsx(L.Transition,{as:S.Fragment,leave:"rst:transition rst:ease-in rst:duration-100",leaveFrom:"rst:opacity-100",leaveTo:"rst:opacity-0",children:t.jsx(n.ListboxOptions,{anchor:s.POPUP_ANCHOR,className:r.cn(s.popupInDarkPalette(k,x)&&"dark",s.POPUP_PANEL,s.POPUP_WIDTH_OF_BUTTON,N),children:o.map(e=>t.jsx(R.PopupOption,{as:n.ListboxOption,value:e.value,disabled:e.disabled,size:i,children:e.label},e.value))})})]})}),(p||a)&&t.jsx(D.Description,{className:r.cn("rst:text-xs rst:text-left",l?"rst:text-error-600 rst:dark:text-error-400 rst:font-medium":"rst:text-gray-500 rst:dark:text-gray-400"),children:a||p})]})};exports.Select=U;
1
+ "use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),F=require("react"),S=require("../../../node_modules/@headlessui/react/dist/components/description/description.cjs"),D=require("../../../node_modules/@headlessui/react/dist/components/field/field.cjs"),I=require("../../../node_modules/@headlessui/react/dist/components/label/label.cjs"),n=require("../../../node_modules/@headlessui/react/dist/components/listbox/listbox.cjs"),L=require("../../../node_modules/@headlessui/react/dist/components/transition/transition.cjs"),T=require("../../../node_modules/@fortawesome/react-fontawesome/dist/index.cjs"),_=require("../../../node_modules/@fortawesome/free-solid-svg-icons/index.cjs"),r=require("../../../lib/utils.cjs"),f=require("../../../internal/field-invalid.cjs"),w=require("./select-variants.cjs"),R=require("../../../internal/PopupOption.cjs"),s=require("../../../internal/popup.cjs"),U=require("../../../internal/key-focus.cjs"),A=({options:l,value:d,onChange:h,placeholder:P="Select an option",disabled:u=!1,variant:x,size:i,error:b,className:q,triggerClassName:j,optionsClassName:y,helperText:p,errorMessage:a,label:m,...v})=>{U.useKeyFocus();const c=l.find(t=>t.value===d),o=!!a||b,N=f.isFieldInvalid(o,v),O=f.withoutInvalidProps(v),{ref:g,inDarkScope:k}=s.useDarkScope();return e.jsxs(D.Field,{disabled:u,className:r.cn("rst:flex rst:flex-col rst:gap-1.5",q),...O,children:[m&&e.jsx(I.Label,{className:"rst:block rst:text-sm rst:font-medium rst:text-[var(--roster-control-text)] rst:text-left",children:m}),e.jsx(n.Listbox,{value:d??void 0,onChange:h,disabled:u,children:e.jsxs("div",{ref:g,className:"rst:relative",children:[e.jsxs(n.ListboxButton,{"aria-invalid":N||void 0,className:r.cn(w.selectTriggerVariants({variant:x,size:i,error:o}),j),children:[e.jsx("span",{className:r.cn("rst:block rst:truncate",!c&&"rst:text-gray-500 rst:dark:text-gray-400"),children:c?c.label:P}),e.jsx("span",{className:r.cn("rst:pointer-events-none rst:absolute rst:inset-y-0 rst:right-0 rst:flex rst:items-center",i==="sm"?"rst:pr-2.5":"rst:pr-3"),children:e.jsx(T.FontAwesomeIcon,{icon:_.faChevronDown,className:"rst:h-3.5 rst:w-3.5 rst:text-gray-400 rst:dark:text-gray-500","aria-hidden":"true"})})]}),e.jsx(L.Transition,{as:F.Fragment,leave:"rst:transition rst:ease-in rst:duration-100",leaveFrom:"rst:opacity-100",leaveTo:"rst:opacity-0",children:e.jsx(n.ListboxOptions,{anchor:s.POPUP_ANCHOR,className:r.cn(s.popupInDarkPalette(k,x)&&"dark",s.POPUP_PANEL,s.POPUP_WIDTH_OF_BUTTON,y),children:l.map(t=>e.jsx(R.PopupOption,{as:n.ListboxOption,value:t.value,disabled:t.disabled,size:i,children:t.label},t.value))})})]})}),(p||a)&&e.jsx(S.Description,{className:r.cn("rst:text-xs rst:text-left",o?"rst:text-error-600 rst:dark:text-error-400 rst:font-medium":"rst:text-gray-500 rst:dark:text-gray-400"),children:a||p})]})};exports.Select=A;