@blakesteve/roster 5.7.0 → 5.9.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 (106) hide show
  1. package/README.md +169 -5
  2. package/dist/components/atoms/Avatar/Avatar.cjs +1 -1
  3. package/dist/components/atoms/Avatar/Avatar.d.ts +4 -0
  4. package/dist/components/atoms/Avatar/Avatar.js +1 -1
  5. package/dist/components/atoms/AvatarStrip/AvatarStrip.cjs +1 -1
  6. package/dist/components/atoms/AvatarStrip/AvatarStrip.d.ts +10 -1
  7. package/dist/components/atoms/AvatarStrip/AvatarStrip.js +34 -30
  8. package/dist/components/atoms/Button/button-variants.cjs +1 -1
  9. package/dist/components/atoms/Button/button-variants.js +5 -3
  10. package/dist/components/atoms/Eyebrow/eyebrow-variants.cjs +1 -1
  11. package/dist/components/atoms/Eyebrow/eyebrow-variants.js +8 -4
  12. package/dist/components/atoms/MultiSelect/MultiSelect.cjs +1 -1
  13. package/dist/components/atoms/MultiSelect/MultiSelect.d.ts +3 -1
  14. package/dist/components/atoms/MultiSelect/MultiSelect.js +87 -89
  15. package/dist/components/atoms/Progress/Progress.cjs +1 -1
  16. package/dist/components/atoms/Progress/Progress.d.ts +1 -0
  17. package/dist/components/atoms/Progress/Progress.js +28 -27
  18. package/dist/components/atoms/Stat/Stat.cjs +1 -1
  19. package/dist/components/atoms/Stat/Stat.js +5 -5
  20. package/dist/components/atoms/Stat/stat-variants.cjs +1 -1
  21. package/dist/components/atoms/Stat/stat-variants.js +10 -8
  22. package/dist/components/molecules/Breadcrumbs/Breadcrumbs.cjs +1 -1
  23. package/dist/components/molecules/Breadcrumbs/Breadcrumbs.d.ts +10 -1
  24. package/dist/components/molecules/Breadcrumbs/Breadcrumbs.js +31 -29
  25. package/dist/components/molecules/CallToAction/CallToAction.cjs +1 -1
  26. package/dist/components/molecules/CallToAction/CallToAction.d.ts +8 -1
  27. package/dist/components/molecules/CallToAction/CallToAction.js +34 -29
  28. package/dist/components/molecules/Carousel/Carousel.cjs +1 -1
  29. package/dist/components/molecules/Carousel/Carousel.d.ts +7 -0
  30. package/dist/components/molecules/Carousel/Carousel.js +155 -155
  31. package/dist/components/molecules/ErrorState/ErrorState.cjs +1 -1
  32. package/dist/components/molecules/ErrorState/ErrorState.d.ts +8 -1
  33. package/dist/components/molecules/ErrorState/ErrorState.js +44 -39
  34. package/dist/components/molecules/FileUpload/FileUpload.cjs +1 -1
  35. package/dist/components/molecules/FileUpload/FileUpload.js +23 -22
  36. package/dist/components/molecules/MediaPreview/MediaPreview.cjs +1 -1
  37. package/dist/components/molecules/MediaPreview/MediaPreview.d.ts +3 -1
  38. package/dist/components/molecules/MediaPreview/MediaPreview.js +13 -12
  39. package/dist/components/molecules/Menu/Menu.cjs +1 -0
  40. package/dist/components/molecules/Menu/Menu.d.ts +169 -0
  41. package/dist/components/molecules/Menu/Menu.js +577 -0
  42. package/dist/components/molecules/Menu/menu-typeahead.cjs +1 -0
  43. package/dist/components/molecules/Menu/menu-typeahead.d.ts +7 -0
  44. package/dist/components/molecules/Menu/menu-typeahead.js +13 -0
  45. package/dist/components/molecules/Pagination/Pagination.cjs +1 -1
  46. package/dist/components/molecules/Pagination/Pagination.d.ts +1 -0
  47. package/dist/components/molecules/Pagination/Pagination.js +47 -46
  48. package/dist/components/molecules/ProgressField/ProgressField.d.ts +1 -0
  49. package/dist/components/molecules/SkeletonPresets/SkeletonPresets.cjs +1 -1
  50. package/dist/components/molecules/SkeletonPresets/SkeletonPresets.d.ts +2 -2
  51. package/dist/components/molecules/SkeletonPresets/SkeletonPresets.js +17 -17
  52. package/dist/components/molecules/StepProgress/StepProgress.cjs +1 -1
  53. package/dist/components/molecules/StepProgress/StepProgress.d.ts +1 -0
  54. package/dist/components/molecules/StepProgress/StepProgress.js +9 -8
  55. package/dist/components/organisms/Countdown/Countdown.cjs +1 -1
  56. package/dist/components/organisms/Countdown/Countdown.d.ts +13 -0
  57. package/dist/components/organisms/Countdown/Countdown.js +54 -47
  58. package/dist/components/organisms/DataTable/DataTable.cjs +1 -1
  59. package/dist/components/organisms/DataTable/DataTable.d.ts +5 -3
  60. package/dist/components/organisms/DataTable/DataTable.js +27 -26
  61. package/dist/components/organisms/Dialog/Dialog.cjs +1 -1
  62. package/dist/components/organisms/Dialog/Dialog.d.ts +8 -1
  63. package/dist/components/organisms/Dialog/Dialog.js +25 -23
  64. package/dist/components/organisms/Footer/Footer.cjs +1 -1
  65. package/dist/components/organisms/Footer/Footer.d.ts +9 -0
  66. package/dist/components/organisms/Footer/Footer.js +21 -23
  67. package/dist/components/organisms/ModerationQueue/ModerationQueue.cjs +1 -1
  68. package/dist/components/organisms/ModerationQueue/ModerationQueue.d.ts +40 -1
  69. package/dist/components/organisms/ModerationQueue/ModerationQueue.js +262 -237
  70. package/dist/components/organisms/ModerationQueue/QueueEditDialog.cjs +1 -1
  71. package/dist/components/organisms/ModerationQueue/QueueEditDialog.d.ts +1 -1
  72. package/dist/components/organisms/ModerationQueue/QueueEditDialog.js +23 -21
  73. package/dist/components/organisms/ModerationQueue/QueueEditSheet.cjs +1 -1
  74. package/dist/components/organisms/ModerationQueue/QueueEditSheet.d.ts +1 -1
  75. package/dist/components/organisms/ModerationQueue/QueueEditSheet.js +22 -20
  76. package/dist/components/organisms/ModerationQueue/queue-actions.d.ts +29 -10
  77. package/dist/components/organisms/Navbar/Navbar.cjs +1 -1
  78. package/dist/components/organisms/Navbar/Navbar.d.ts +39 -4
  79. package/dist/components/organisms/Navbar/Navbar.js +297 -301
  80. package/dist/components/organisms/Navbar/navbar-variants.cjs +1 -1
  81. package/dist/components/organisms/Navbar/navbar-variants.js +4 -2
  82. package/dist/components/organisms/Sheet/Sheet.cjs +1 -1
  83. package/dist/components/organisms/Sheet/Sheet.d.ts +8 -1
  84. package/dist/components/organisms/Sheet/Sheet.js +65 -63
  85. package/dist/index.d.ts +1 -0
  86. package/dist/lib/labels.cjs +1 -0
  87. package/dist/lib/labels.d.ts +7 -0
  88. package/dist/lib/labels.js +12 -0
  89. package/dist/meta.json +3 -3
  90. package/dist/node_modules/@floating-ui/core/dist/floating-ui.core.js +7 -7
  91. package/dist/node_modules/@floating-ui/dom/dist/floating-ui.dom.js +2 -2
  92. package/dist/node_modules/@floating-ui/react-dom/dist/floating-ui.react-dom.js +5 -5
  93. package/dist/node_modules/@headlessui/react/dist/components/portal/portal.js +6 -6
  94. package/dist/node_modules/@headlessui/react/dist/utils/focus-management.cjs +1 -1
  95. package/dist/node_modules/@headlessui/react/dist/utils/focus-management.js +52 -61
  96. package/dist/node_modules/@radix-ui/react-popper/dist/index.js +6 -6
  97. package/dist/roster.cjs +1 -1
  98. package/dist/roster.css +1 -1
  99. package/dist/roster.js +127 -116
  100. package/package.json +2 -1
  101. package/dist/node_modules/@headlessui/react/dist/components/menu/menu-machine-glue.cjs +0 -1
  102. package/dist/node_modules/@headlessui/react/dist/components/menu/menu-machine-glue.js +0 -21
  103. package/dist/node_modules/@headlessui/react/dist/components/menu/menu-machine.cjs +0 -1
  104. package/dist/node_modules/@headlessui/react/dist/components/menu/menu-machine.js +0 -120
  105. package/dist/node_modules/@headlessui/react/dist/components/menu/menu.cjs +0 -1
  106. package/dist/node_modules/@headlessui/react/dist/components/menu/menu.js +0 -197
package/README.md CHANGED
@@ -113,6 +113,12 @@ import "@blakesteve/roster/style.css";
113
113
  Skip it and components render against browser defaults: serif type, bulleted
114
114
  lists, and `content-box` sizing.
115
115
 
116
+ One default Roster does undo itself: a `<button>`'s own border. A `link` or
117
+ `soft` Button sets its border to zero (`soft` since 5.8.0). In an app without a
118
+ reset, `link` drew the browser's 2px border, and `soft` kept it, transparent,
119
+ which took 4px of extra room and showed in forced colors. Zero is what an app
120
+ with Tailwind's reset already had, so no layout moves.
121
+
116
122
  ### Dark mode
117
123
 
118
124
  Every component reads a `.dark` class on an ancestor, so dark mode is whatever
@@ -452,8 +458,15 @@ the supported way now.
452
458
  rule stops matching.** Solid Button, Badge, Pill and Checkbox no longer carry
453
459
  `rst:text-white` or `rst:text-gray-950`, so a selector naming either matches
454
460
  nothing. It fails silently, and it fails *partially*: those classes are still on
455
- `Card`, `Navbar`, `Dialog`, `ActionBar`, `Avatar` and `Breadcrumbs`, so a
456
- themed foreground keeps working there while reverting on every solid control.
461
+ `ActionBar`, `Avatar` and `Breadcrumbs`, so a themed foreground keeps working
462
+ there while reverting on every solid control. The `primary` fills of `Card`,
463
+ `Dialog` and, since 5.8.0, `Navbar` read their ink token too: Navbar's bar,
464
+ brand and active link take `--roster-primary-700-ink`, and its other links and
465
+ menu button the same ink at 80%. Each keeps white in dark mode, where its fill
466
+ is a dark step the ink doesn't describe. A primary Navbar looks different even
467
+ with no ink set: its links were `gray-300` and its active link `primary-400`,
468
+ which was 4.04:1 on Roster's own primary, under the 4.5 text needs. Now they
469
+ are white at 80% and white, the active one still semibold.
457
470
  Replace the rule with the token:
458
471
 
459
472
  ```css
@@ -911,6 +924,10 @@ look like oversights until you know why:
911
924
  page does not reach it. All three components copy the nearest `.dark` onto
912
925
  the panel to fix that. Custom properties are not carried the same way — set
913
926
  `--roster-popover-*` at `:root`.
927
+ - **`Menu` shares the panel, not the anchoring.** Its panel takes the same
928
+ surface, tokens and dark carry, but `Menu` places itself (see
929
+ [Menu](#menu)), writing its own inline `max-height`. It reads the same
930
+ `--anchor-max-height`, so the hatch above works on `MenuItems` too.
914
931
  - **`variant="slate"` opens on the dark palette**, in light mode too. That
915
932
  variant paints a dark trigger, and its panel was rendering white: a dark
916
933
  control opening a white sheet, which is the mismatch `--roster-popover-*`
@@ -1258,6 +1275,12 @@ app supplies, inline by default or in a Dialog or Sheet (`QueueEditDialog`,
1258
1275
  `QueueEditSheet`, separate exports so a queue that doesn't use them doesn't
1259
1276
  ship them).
1260
1277
 
1278
+ **A reason outranks a confirm.** An action with both asks the reason's
1279
+ question, and its submit button is the confirmation. A `required` reason asks
1280
+ for one of its `options`, so the types refuse `required` without them: a
1281
+ reason that is only a note is `note: "required"`. That makes `QueueReasonStep`
1282
+ a type rather than an interface (5.8.0), so extend it with `&`, not `extends`.
1283
+
1261
1284
  **Drafts are typed.** An edit's draft is whatever its `initial` returns, and
1262
1285
  `validate`, the form and `run` all get that type. Inside JSX, pass `actions` as
1263
1286
  a function and write edits with the `edit` it's handed, as above; outside it,
@@ -1480,6 +1503,84 @@ shown beside it.
1480
1503
 
1481
1504
  Every string in all five is a prop with an English default.
1482
1505
 
1506
+ ### Menu
1507
+
1508
+ A button that opens a panel of actions: the menu button pattern. Compose it:
1509
+
1510
+ ```tsx
1511
+ import { Menu, MenuButton, MenuItems, MenuItem, MenuSeparator } from "@blakesteve/roster";
1512
+
1513
+ <Menu>
1514
+ <MenuButton variant="ghost" size="icon" aria-label="More for Banded agate">⋯</MenuButton>
1515
+ <MenuItems align="end">
1516
+ <MenuItem icon={<EditIcon />} shortcut="⌘E" onSelect={edit}>Edit</MenuItem>
1517
+ <MenuItem href="/rocks/agate/share">Share</MenuItem>
1518
+ <MenuSeparator />
1519
+ <MenuItem destructive onSelect={confirmDelete}>Delete</MenuItem>
1520
+ </MenuItems>
1521
+ </Menu>;
1522
+ ```
1523
+
1524
+ - **Items.** `MenuItem` is an action, or a link with `href` (rendered through
1525
+ the menu's `linkComponent`; pass `next/link` from a client component, as with
1526
+ Breadcrumbs). Each takes a leading `icon`, a `shortcut` to show (display
1527
+ only: your app handles the keys; `keyshortcuts` tells assistive technology),
1528
+ a `description` line, a trailing `badge`, `destructive` and `disabled`.
1529
+ `MenuCheckboxItem` is an on/off choice, `MenuRadioGroup` with
1530
+ `MenuRadioItem` one of several, `MenuGroup` puts items under an optional
1531
+ label, `MenuSeparator` draws a rule, and `MenuSubmenu` opens a menu beside
1532
+ its item. Submenus nest.
1533
+ - **Keyboard.** Enter, Space or Down open it on the first item and Up on the
1534
+ last; a click opens it on the panel. The arrows move, Home and End jump, and
1535
+ typing jumps to the next item starting with what's typed, a space included
1536
+ ("save a"). Escape closes it and returns focus to the button; Tab closes it
1537
+ and moves on from the button, to what the browser's own Tab would reach. A
1538
+ submenu opens with the arrow away from its parent, Enter, Space, a click or
1539
+ the pointer resting on it, and closes with the arrow back or Escape. A click
1540
+ only ever opens it.
1541
+ - **Choosing.** A click or Enter chooses and closes, with focus back on the
1542
+ button, so a choice that opens a Dialog hands focus to it and gets it back.
1543
+ Space on a checkbox or radio item chooses and keeps the menu open, so
1544
+ several can be set in one visit. `closeOnSelect={false}` keeps it open on
1545
+ any choice. A disabled item can be reached, so it can be read, but not
1546
+ chosen. A press outside closes it without moving the page, and focus stays
1547
+ where the press put it.
1548
+ - **Events.** Keys inside the panel stay there: the panel is portaled, and
1549
+ React would otherwise carry them to the components around the menu, so
1550
+ Enter on Delete would also open the row whose overflow menu it is. A key
1551
+ with Ctrl, Meta or Alt goes on, for the app's shortcuts. Clicks go on to the
1552
+ page, where analytics listen, and so React carries an item's click to that
1553
+ row too: a row with its own `onClick` checks that the click landed inside
1554
+ it (`event.currentTarget.contains(event.target as Node)`). The button is
1555
+ in your markup, and its keys and clicks reach the row like any other.
1556
+ - **Placement.** Below the button, lined up with its start (`align="end"` for
1557
+ the other edge); flipped above when there's more room there, shifted to stay
1558
+ on screen, and capped at the room there is. A taller menu scrolls with
1559
+ Roster's scrollbar and a shadow at whichever edge has more. Under
1560
+ `dir="rtl"` it lines up with the right edge and submenus open to the left.
1561
+ It takes its button's direction, not the page's.
1562
+ - **Inside other layers.** The panel opens in a portal, so nothing it sits in
1563
+ clips it, a card with `overflow: hidden` included. A `Dialog`, a `Sheet` or
1564
+ Navbar's mobile panel counts it as inside: choosing from it leaves them
1565
+ open.
1566
+ - **Styling.** `className` on `MenuItems` and on each item merges last, so a
1567
+ fill such as `bg-gray-100` takes; the scroll shadows are drawn over it. Its
1568
+ ring and separators follow `--roster-border-width`. Items show the pointer
1569
+ cursor, a disabled one `not-allowed`. In forced colors the focused item gets
1570
+ an outline, since its fill is dropped.
1571
+ - **Targets.** Every item is at least 44px tall, and `MenuButton` at least 44
1572
+ by 44 whatever its size. `MenuButton plain` renders a bare `<button>` for a
1573
+ trigger drawn its own way; keep its target at least 44 by 44 with a hit
1574
+ area, as Navbar's avatar does.
1575
+
1576
+ Built on Roster's own popup panel and on Floating UI for placement, which
1577
+ Roster already ships through its other popups, rather than on Headless UI's
1578
+ `Menu`: that has no submenus, and no checkbox or radio items. Navbar's user
1579
+ menu is built on it since 5.9.0. It looks as it did, in every state, except
1580
+ that its rows are 44px tall rather than 36, and that with neither an inbox nor
1581
+ a theme row it no longer draws an empty band and rule at the top. It keeps its
1582
+ own white fill, whatever `--roster-popover-bg` says.
1583
+
1483
1584
  ### Pagination
1484
1585
 
1485
1586
  Moves through pages of a list, built for a long list browsed on a phone.
@@ -1623,6 +1724,65 @@ well as `next/link`, plus `className`, `children`, `aria-current`, `onClick` and
1623
1724
  `Eyebrow` takes the other approach: `as` accepts any element and the props
1624
1725
  follow it, so `<Eyebrow as="a" href="/work">` works, as does `as={NextLink}`.
1625
1726
 
1727
+ ### Every built-in word is replaceable
1728
+
1729
+ Where a component writes words of its own (a close button's name, a menu
1730
+ button's, "Log In", a sentence a screen reader hears), each can be replaced
1731
+ and defaults to English. Most components take a `labels` prop; pass any entry
1732
+ and the rest stay:
1733
+
1734
+ ```tsx
1735
+ <Navbar labels={{ openMainMenu: t("nav.open"), closeMainMenu: t("nav.close") }} … />
1736
+ <Sheet labels={{ close: t("common.close") }} … />
1737
+ <Countdown labels={{ days: (n) => t("units.days", { count: n }) }} … />
1738
+ ```
1739
+
1740
+ Since 5.8.0 that covers `Navbar`, `Sheet`, `Dialog`, `Breadcrumbs`, `Footer`,
1741
+ `CallToAction`, `AvatarStrip`, `ErrorState`, `Countdown`, `Carousel` and
1742
+ `ModerationQueue` (whose `labels.close` names the close button of its edit
1743
+ Dialog or Sheet), alongside `Pagination`, the loading system and DataTable's
1744
+ `paginationLabels`. A few components name their words with single props
1745
+ instead, and 5.8.0 adds the ones that were missing: MultiSelect's
1746
+ `countLabel`, DataTable's `emptyMessage` and MediaPreview's `newTabLabel`, next
1747
+ to the existing `dismissLabel`, `placeholder`, `removeLabel`, `prevLabel` and
1748
+ the like. Words that take a number or a name are functions, so a language
1749
+ whose word changes with the count can say so. An entry passed as `undefined`
1750
+ (a catalog missing a key) keeps its English rather than leaving a control
1751
+ unnamed.
1752
+
1753
+ `src/labels.test.tsx` renders each of these, in the states where its words
1754
+ appear, with every word pseudo-localized, and fails on any English left. A
1755
+ default it can't reach: `Avatar`'s alt is "Avatar" unless you pass one (`""`
1756
+ marks it decorative, since 5.8.0), and a team without a name in
1757
+ `MatchupCard` is "Team" and its id.
1758
+
1759
+ **From a server component, pass only strings.** Every component is a client
1760
+ component, and functions can't cross the React Server Component boundary, so a
1761
+ function label (Footer's `copyright`, Countdown's units) has to be passed from
1762
+ a `"use client"` wrapper, as `linkComponent` does above.
1763
+
1764
+ ### Eyebrow and Stat line height
1765
+
1766
+ An `Eyebrow`'s line is as tall as its letters, and so is a `Stat`'s figure and
1767
+ its label. Through 5.7.0 neither was: `leading-none` sat before the font size
1768
+ in their variant tables, and `cn()`'s tailwind-merge drops a line height that
1769
+ comes before a size. An Eyebrow drew a line 1.5 times its size (15px for the
1770
+ default `xs`, not 10), and a Stat's figure and label drew lines taller than
1771
+ their type.
1772
+
1773
+ **Upgrading to 5.8.0 moves layouts.** An Eyebrow that makes its own line, as
1774
+ a flex or grid item or rendered as a block (`as="p"`, `as="h2"`), is a third
1775
+ shorter: 10px for `xs`, not 15. One inline in running text sits on its
1776
+ parent's line and doesn't change. A Stat in its default markup loses more:
1777
+ its figure's line was the size's own (28px for `sm`'s 20px figure) or the
1778
+ page's 1.5 (`md`, `lg`), and its label sat on the page's line (24px on a 16px,
1779
+ 1.5 body). So a `sm` Stat goes from 55px tall to 33, and an `lg` one at 48px
1780
+ from 99 to 61. In the `standalone` markup only the label moves, 15px to 10.
1781
+ `LabeledDivider` sets its label in an Eyebrow of its own, so every rule is 5px
1782
+ shorter whatever label it's given. An Eyebrow that wraps now sets solid, its
1783
+ lines as close as its size. Spacing an app tuned against the old lines (a
1784
+ margin that cleared them) may want retuning.
1785
+
1626
1786
  ## Quick start
1627
1787
 
1628
1788
  ```tsx
@@ -1700,6 +1860,7 @@ function App() {
1700
1860
  | `LiquidTabs` | Tab strip with a sliding pill; arrow keys, roving focus, 44px `lg` size |
1701
1861
  | `MatchupCard` | Head-to-head comparison card |
1702
1862
  | `MediaPreview` | Thumbnail that falls back to "Preview unavailable, open original" when it can't render |
1863
+ | `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)) |
1703
1864
  | `FileUpload` | Picks files and uploads each through the app's `upload`, with per-file progress, retry and rules |
1704
1865
  | `Pagination` | Page numbers with gaps, or a compact page picker on narrow screens; buttons or real links, 44px targets |
1705
1866
  | `SkeletonCard`, `SkeletonTableRow`, `SkeletonAvatar`, `SkeletonStat` | Skeleton presets in the real component's box |
@@ -1715,11 +1876,13 @@ function App() {
1715
1876
  | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
1716
1877
  | `ActionBar` | Sticky bottom action strip |
1717
1878
  | `Countdown` | Live countdown timer |
1718
- | `DataTable` | Full-featured table with sorting and pagination via TanStack Table v9; its pager is `Pagination`'s arrows, worded through `paginationLabels`. Imported from `@blakesteve/roster/data-table` (see [DataTable columns](#datatable-columns)) |
1879
+ | `DataTable` | Table with sorting and paging via TanStack Table v9. Its pager is built on `Pagination` (since 5.6.0, the arrows layout), worded through `paginationLabels`; the page size is fixed at 10, with no prop to change it yet. Imported from `@blakesteve/roster/data-table` (see [DataTable columns](#datatable-columns)) |
1719
1880
  | `Dialog` | Modal dialog; `onAfterClose` runs once it has finished closing |
1720
1881
  | `Footer` | Site footer |
1721
1882
  | `ModerationQueue` | Items waiting for a decision: busy per action, confirm, reason and edit steps, focus after an item leaves, a live region. Never fetches (see [ModerationQueue](#moderationqueue)) |
1722
- | `Navbar` | Responsive navigation bar with mobile slide-out |
1883
+ | `QueueEditDialog` | A ModerationQueue edit step in a Dialog: pass it as an edit's `surface`. A separate export, so a queue that never uses it doesn't ship it |
1884
+ | `QueueEditSheet` | A ModerationQueue edit step in a Sheet, for a long form: pass it as an edit's `surface`. A separate export, like `QueueEditDialog` |
1885
+ | `Navbar` | Responsive navigation bar with mobile slide-out; its user menu is a `Menu`. A wide logo keeps its own proportions through `logoHeight` and `logoWidth`; its built-in words are in `labels` |
1723
1886
  | `Sheet` | Bottom sheet: drag, Escape or backdrop to dismiss; only its content scrolls; returns focus, even from a deep link; the title may be a node |
1724
1887
  | `Table` | Static data table |
1725
1888
 
@@ -1873,7 +2036,8 @@ reason and the build goes green on the state it inherited while still failing on
1873
2036
  anything new. It also fails when a listed class starts emitting, so a fix cannot
1874
2037
  leave a stale entry behind. Run it with `--verbose` to print the list.
1875
2038
 
1876
- Story tests that need the user's own input, a wheel or a mouse drag, get it
2039
+ Story tests that need the user's own input, a wheel, a mouse drag or a pointer
2040
+ resting on something, get it
1877
2041
  from `.storybook/real-input.ts`: Vitest browser commands that drive
1878
2042
  Playwright's mouse, whose events are trusted. A synthetic wheel or pointer
1879
2043
  event never scrolls anything, so "a vertical wheel scrolls the page, not the
@@ -1 +1 @@
1
- "use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("react/jsx-runtime"),n=require("react"),o=require("../../../lib/utils.cjs"),h=require("./avatar-variants.cjs"),t=require("../../../node_modules/@headlessui/react/dist/components/popover/popover.cjs"),i=n.forwardRef(({className:c,size:l,colorScheme:u,shape:d,initials:g,src:s,alt:v,title:e,...m},f)=>{const[p,b]=n.useState(!1),x=s&&!p,a=r.jsx("div",{ref:f,className:o.cn(h.avatarVariants({size:l,colorScheme:u,shape:d}),c),...m,children:x?r.jsx("img",{src:s,alt:v||"Avatar",className:"rst:h-full rst:w-full rst:object-cover",onError:()=>b(!0)}):r.jsx("span",{className:"rst:leading-none rst:uppercase",children:g?.slice(0,2)})});return e?r.jsxs(t.Popover,{className:"rst:relative rst:inline-flex",children:[r.jsx(t.PopoverButton,{as:"div",className:"rst:cursor-pointer rst:focus-visible:outline-hidden rst:focus-visible:ring-2 rst:focus-visible:ring-ring rst:focus-visible:ring-offset-2 rst:ring-offset-background rst:rounded-full",children:a}),r.jsx(t.PopoverPanel,{anchor:"bottom",className:o.cn("rst:z-50 rst:mt-2 rst:rounded-md rst:px-3 rst:py-1.5 rst:text-xs rst:font-medium rst:elevation-anchored rst:backdrop-blur-md rst:ring","rst:bg-gray-900/95 rst:text-white rst:ring-black/5 rst:dark:bg-gray-100/95 rst:dark:text-gray-900 rst:dark:ring-white/20","rst:transition rst:duration-200 rst:ease-in-out rst:data-closed:opacity-0 rst:data-closed:translate-y-1"),children:e})]}):a});i.displayName="Avatar";exports.Avatar=i;
1
+ "use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("react/jsx-runtime"),n=require("react"),o=require("../../../lib/utils.cjs"),h=require("./avatar-variants.cjs"),t=require("../../../node_modules/@headlessui/react/dist/components/popover/popover.cjs"),i=n.forwardRef(({className:c,size:l,colorScheme:u,shape:d,initials:g,src:s,alt:v,title:e,...m},f)=>{const[p,b]=n.useState(!1),x=s&&!p,a=r.jsx("div",{ref:f,className:o.cn(h.avatarVariants({size:l,colorScheme:u,shape:d}),c),...m,children:x?r.jsx("img",{src:s,alt:v??"Avatar",className:"rst:h-full rst:w-full rst:object-cover",onError:()=>b(!0)}):r.jsx("span",{className:"rst:leading-none rst:uppercase",children:g?.slice(0,2)})});return e?r.jsxs(t.Popover,{className:"rst:relative rst:inline-flex",children:[r.jsx(t.PopoverButton,{as:"div",className:"rst:cursor-pointer rst:focus-visible:outline-hidden rst:focus-visible:ring-2 rst:focus-visible:ring-ring rst:focus-visible:ring-offset-2 rst:ring-offset-background rst:rounded-full",children:a}),r.jsx(t.PopoverPanel,{anchor:"bottom",className:o.cn("rst:z-50 rst:mt-2 rst:rounded-md rst:px-3 rst:py-1.5 rst:text-xs rst:font-medium rst:elevation-anchored rst:backdrop-blur-md rst:ring","rst:bg-gray-900/95 rst:text-white rst:ring-black/5 rst:dark:bg-gray-100/95 rst:dark:text-gray-900 rst:dark:ring-white/20","rst:transition rst:duration-200 rst:ease-in-out rst:data-closed:opacity-0 rst:data-closed:translate-y-1"),children:e})]}):a});i.displayName="Avatar";exports.Avatar=i;
@@ -4,6 +4,10 @@ import { avatarVariants } from './avatar-variants';
4
4
  export interface AvatarProps extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof avatarVariants> {
5
5
  initials?: string;
6
6
  src?: string;
7
+ /**
8
+ * The photo's text alternative. Defaults to "Avatar"; pass the person's
9
+ * name, or `""` where the avatar sits beside a name that already says who.
10
+ */
7
11
  alt?: string;
8
12
  title?: string;
9
13
  }
@@ -26,7 +26,7 @@ const w = b.forwardRef(
26
26
  "img",
27
27
  {
28
28
  src: t,
29
- alt: d || "Avatar",
29
+ alt: d ?? "Avatar",
30
30
  className: "rst:h-full rst:w-full rst:object-cover",
31
31
  onError: () => g(!0)
32
32
  }
@@ -1 +1 @@
1
- "use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("react/jsx-runtime"),a=require("../../../lib/utils.cjs"),f=require("../Avatar/Avatar.cjs");function g({items:i,maxDisplay:l=5,totalCount:n,excludeKey:c,onDismiss:o,trailingSlot:d,label:v,ringClass:h="rst:ring-white rst:dark:ring-gray-900",className:p}){const s=i.filter(t=>t.key!==c).slice(0,l),e=n!==void 0?Math.max(0,n-s.length):Math.max(0,i.filter(t=>t.key!==c).length-l);return s.length===0&&!d?null:r.jsxs("div",{"data-testid":"avatar-strip",className:a.cn("rst:font-ui rst:flex rst:items-center rst:gap-3",p),children:[o&&r.jsx("button",{type:"button",onClick:o,"aria-label":"Dismiss","data-testid":"avatar-strip-dismiss",className:"rst:shrink-0 rst:text-gray-400/50 rst:dark:text-gray-500/50 rst:hover:text-gray-400 rst:dark:hover:text-gray-500 rst:transition-colors rst:cursor-pointer",children:"✕"}),r.jsxs("div",{"data-testid":"avatar-strip-stack",className:"rst:flex rst:items-center rst:-space-x-2",children:[s.map(t=>{const x=r.jsx(f.Avatar,{initials:t.label[0].toUpperCase(),src:t.src,colorScheme:t.colorScheme??"neutral",size:"xs"}),u=a.cn("rst:relative rst:inline-flex rst:h-6 rst:w-6 rst:rounded-full rst:ring-2 rst:transition-transform rst:hover:z-10 rst:hover:scale-110",h);return t.href?r.jsx("a",{href:t.href,title:t.label,"data-testid":`avatar-strip-item-${t.key}`,className:u,children:x},t.key):r.jsx("span",{title:t.label,"data-testid":`avatar-strip-item-${t.key}`,className:u,children:x},t.key)}),e>0&&r.jsx("div",{title:`${e} more`,"data-testid":"avatar-strip-overflow",className:a.cn("rst:relative rst:flex rst:h-6 rst:w-6 rst:items-center rst:justify-center rst:rounded-full rst:bg-gray-500/10 rst:ring-2",h),children:r.jsxs("span",{className:"rst:text-[9px] rst:font-bold rst:text-gray-500 rst:dark:text-gray-400 rst:select-none",children:["+",e]})}),d]}),v&&r.jsx("div",{"data-testid":"avatar-strip-label",children:v})]})}exports.AvatarStrip=g;
1
+ "use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("react/jsx-runtime"),i=require("../../../lib/utils.cjs"),y=require("../../../lib/labels.cjs"),b=require("../Avatar/Avatar.cjs"),k={dismiss:"Dismiss",more:s=>`${s} more`};function m({items:s,maxDisplay:l=5,totalCount:n,excludeKey:c,onDismiss:o,trailingSlot:d,label:h,ringClass:v="rst:ring-white rst:dark:ring-gray-900",labels:f,className:g}){const x=y.withLabels(k,f),e=s.filter(t=>t.key!==c).slice(0,l),a=n!==void 0?Math.max(0,n-e.length):Math.max(0,s.filter(t=>t.key!==c).length-l);return e.length===0&&!d?null:r.jsxs("div",{"data-testid":"avatar-strip",className:i.cn("rst:font-ui rst:flex rst:items-center rst:gap-3",g),children:[o&&r.jsx("button",{type:"button",onClick:o,"aria-label":x.dismiss,"data-testid":"avatar-strip-dismiss",className:"rst:shrink-0 rst:text-gray-400/50 rst:dark:text-gray-500/50 rst:hover:text-gray-400 rst:dark:hover:text-gray-500 rst:transition-colors rst:cursor-pointer",children:"✕"}),r.jsxs("div",{"data-testid":"avatar-strip-stack",className:"rst:flex rst:items-center rst:-space-x-2",children:[e.map(t=>{const u=r.jsx(b.Avatar,{initials:t.label[0].toUpperCase(),src:t.src,alt:t.label,colorScheme:t.colorScheme??"neutral",size:"xs"}),p=i.cn("rst:relative rst:inline-flex rst:h-6 rst:w-6 rst:rounded-full rst:ring-2 rst:transition-transform rst:hover:z-10 rst:hover:scale-110",v);return t.href?r.jsx("a",{href:t.href,title:t.label,"data-testid":`avatar-strip-item-${t.key}`,className:p,children:u},t.key):r.jsx("span",{title:t.label,"data-testid":`avatar-strip-item-${t.key}`,className:p,children:u},t.key)}),a>0&&r.jsx("div",{title:x.more(a),"data-testid":"avatar-strip-overflow",className:i.cn("rst:relative rst:flex rst:h-6 rst:w-6 rst:items-center rst:justify-center rst:rounded-full rst:bg-gray-500/10 rst:ring-2",v),children:r.jsxs("span",{className:"rst:text-[9px] rst:font-bold rst:text-gray-500 rst:dark:text-gray-400 rst:select-none",children:["+",a]})}),d]}),h&&r.jsx("div",{"data-testid":"avatar-strip-label",children:h})]})}exports.AvatarStrip=m;
@@ -12,6 +12,13 @@ export interface AvatarStripItem {
12
12
  /** When provided, the avatar is wrapped in an `<a>` tag with this href. */
13
13
  href?: string;
14
14
  }
15
+ /** Every word AvatarStrip says of its own. Pass any of them in `labels` to replace it. */
16
+ export interface AvatarStripLabels {
17
+ /** The dismiss button's name, with `onDismiss`. */
18
+ dismiss: string;
19
+ /** The overflow chip's title: how many more there are. */
20
+ more: (count: number) => string;
21
+ }
15
22
  export interface AvatarStripProps {
16
23
  /** Ordered list of avatar items. */
17
24
  items: AvatarStripItem[];
@@ -35,6 +42,8 @@ export interface AvatarStripProps {
35
42
  trailingSlot?: ReactNode;
36
43
  /** Rendered to the right of the avatar stack. Accepts any React node. */
37
44
  label?: ReactNode;
45
+ /** The component's own words, replaced; any left out stay English. */
46
+ labels?: Partial<AvatarStripLabels>;
38
47
  /**
39
48
  * Tailwind class that sets the ring color around each avatar and the overflow chip.
40
49
  * Should match the background the strip is rendered on to produce the cutout stack effect.
@@ -56,4 +65,4 @@ export interface AvatarStripProps {
56
65
  *
57
66
  * Returns `null` when there are no visible items and no `trailingSlot`.
58
67
  */
59
- export declare function AvatarStrip({ items, maxDisplay, totalCount, excludeKey, onDismiss, trailingSlot, label, ringClass, className, }: AvatarStripProps): import("react/jsx-runtime").JSX.Element | null;
68
+ export declare function AvatarStrip({ items, maxDisplay, totalCount, excludeKey, onDismiss, trailingSlot, label, ringClass, labels, className, }: AvatarStripProps): import("react/jsx-runtime").JSX.Element | null;
@@ -1,54 +1,58 @@
1
1
  "use client";
2
- import { jsxs as a, jsx as r } from "react/jsx-runtime";
3
- import { cn as i } from "../../../lib/utils.js";
4
- import { Avatar as m } from "../Avatar/Avatar.js";
5
- function b({
6
- items: l,
2
+ import { jsxs as i, jsx as r } from "react/jsx-runtime";
3
+ import { cn as l } from "../../../lib/utils.js";
4
+ import { withLabels as y } from "../../../lib/labels.js";
5
+ import { Avatar as k } from "../Avatar/Avatar.js";
6
+ const b = { dismiss: "Dismiss", more: (s) => `${s} more` };
7
+ function L({
8
+ items: s,
7
9
  maxDisplay: n = 5,
8
- totalCount: c,
9
- excludeKey: o,
10
+ totalCount: o,
11
+ excludeKey: c,
10
12
  onDismiss: d,
11
13
  trailingSlot: h,
12
- label: v,
13
- ringClass: p = "rst:ring-white rst:dark:ring-gray-900",
14
- className: g
14
+ label: p,
15
+ ringClass: v = "rst:ring-white rst:dark:ring-gray-900",
16
+ labels: g,
17
+ className: u
15
18
  }) {
16
- const s = l.filter((t) => t.key !== o).slice(0, n), e = c !== void 0 ? Math.max(0, c - s.length) : Math.max(0, l.filter((t) => t.key !== o).length - n);
17
- return s.length === 0 && !h ? null : /* @__PURE__ */ a(
19
+ const f = y(b, g), e = s.filter((t) => t.key !== c).slice(0, n), a = o !== void 0 ? Math.max(0, o - e.length) : Math.max(0, s.filter((t) => t.key !== c).length - n);
20
+ return e.length === 0 && !h ? null : /* @__PURE__ */ i(
18
21
  "div",
19
22
  {
20
23
  "data-testid": "avatar-strip",
21
- className: i("rst:font-ui rst:flex rst:items-center rst:gap-3", g),
24
+ className: l("rst:font-ui rst:flex rst:items-center rst:gap-3", u),
22
25
  children: [
23
26
  d && /* @__PURE__ */ r(
24
27
  "button",
25
28
  {
26
29
  type: "button",
27
30
  onClick: d,
28
- "aria-label": "Dismiss",
31
+ "aria-label": f.dismiss,
29
32
  "data-testid": "avatar-strip-dismiss",
30
33
  className: "rst:shrink-0 rst:text-gray-400/50 rst:dark:text-gray-500/50 rst:hover:text-gray-400 rst:dark:hover:text-gray-500 rst:transition-colors rst:cursor-pointer",
31
34
  children: "✕"
32
35
  }
33
36
  ),
34
- /* @__PURE__ */ a(
37
+ /* @__PURE__ */ i(
35
38
  "div",
36
39
  {
37
40
  "data-testid": "avatar-strip-stack",
38
41
  className: "rst:flex rst:items-center rst:-space-x-2",
39
42
  children: [
40
- s.map((t) => {
41
- const f = /* @__PURE__ */ r(
42
- m,
43
+ e.map((t) => {
44
+ const m = /* @__PURE__ */ r(
45
+ k,
43
46
  {
44
47
  initials: t.label[0].toUpperCase(),
45
48
  src: t.src,
49
+ alt: t.label,
46
50
  colorScheme: t.colorScheme ?? "neutral",
47
51
  size: "xs"
48
52
  }
49
- ), x = i(
53
+ ), x = l(
50
54
  "rst:relative rst:inline-flex rst:h-6 rst:w-6 rst:rounded-full rst:ring-2 rst:transition-transform rst:hover:z-10 rst:hover:scale-110",
51
- p
55
+ v
52
56
  );
53
57
  return t.href ? /* @__PURE__ */ r(
54
58
  "a",
@@ -57,7 +61,7 @@ function b({
57
61
  title: t.label,
58
62
  "data-testid": `avatar-strip-item-${t.key}`,
59
63
  className: x,
60
- children: f
64
+ children: m
61
65
  },
62
66
  t.key
63
67
  ) : /* @__PURE__ */ r(
@@ -66,23 +70,23 @@ function b({
66
70
  title: t.label,
67
71
  "data-testid": `avatar-strip-item-${t.key}`,
68
72
  className: x,
69
- children: f
73
+ children: m
70
74
  },
71
75
  t.key
72
76
  );
73
77
  }),
74
- e > 0 && /* @__PURE__ */ r(
78
+ a > 0 && /* @__PURE__ */ r(
75
79
  "div",
76
80
  {
77
- title: `${e} more`,
81
+ title: f.more(a),
78
82
  "data-testid": "avatar-strip-overflow",
79
- className: i(
83
+ className: l(
80
84
  "rst:relative rst:flex rst:h-6 rst:w-6 rst:items-center rst:justify-center rst:rounded-full rst:bg-gray-500/10 rst:ring-2",
81
- p
85
+ v
82
86
  ),
83
- children: /* @__PURE__ */ a("span", { className: "rst:text-[9px] rst:font-bold rst:text-gray-500 rst:dark:text-gray-400 rst:select-none", children: [
87
+ children: /* @__PURE__ */ i("span", { className: "rst:text-[9px] rst:font-bold rst:text-gray-500 rst:dark:text-gray-400 rst:select-none", children: [
84
88
  "+",
85
- e
89
+ a
86
90
  ] })
87
91
  }
88
92
  ),
@@ -90,11 +94,11 @@ function b({
90
94
  ]
91
95
  }
92
96
  ),
93
- v && /* @__PURE__ */ r("div", { "data-testid": "avatar-strip-label", children: v })
97
+ p && /* @__PURE__ */ r("div", { "data-testid": "avatar-strip-label", children: p })
94
98
  ]
95
99
  }
96
100
  );
97
101
  }
98
102
  export {
99
- b as AvatarStrip
103
+ L as AvatarStrip
100
104
  };
@@ -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:justify-center rst:cursor-pointer rst:whitespace-nowrap rst:rounded-md rst:text-sm rst:font-medium rst:ring-offset-background rst:transition-colors rst:focus-visible:outline-hidden rst:focus-visible:ring-2 rst:focus-visible:ring-ring rst:focus-visible:ring-offset-2 rst:disabled:pointer-events-none rst:disabled:opacity-50",{variants:{variant:{solid:"rst:border rst:border-transparent rst:elevation-control",soft:"rst:border-transparent rst:shadow-none",outline:"rst:border rst:bg-transparent rst:elevation-control",ghost:"rst:border rst:border-transparent rst:bg-transparent",link:"rst:border-0 rst:bg-transparent rst:underline-offset-4 rst:hover:underline"},colorScheme:{primary:"",orange:"",teal:"",purple:"",amber:"",success:"",error:"",neutral:""},size:{xs:"rst:h-7 rst:rounded-sm rst:px-2 rst:text-xs",sm:"rst:h-9 rst:rounded-md rst:px-3",default:"rst:h-10 rst:px-4 rst:py-2",lg:"rst:h-11 rst:rounded-md rst:px-8",icon:"rst:h-10 rst:w-10"}},compoundVariants:[{variant:"solid",colorScheme:"primary",className:"rst:bg-primary-600 rst:hover:bg-primary-700 rst:dark:bg-primary-600 rst:dark:hover:bg-primary-500 rst:text-primary-600-ink rst:hover:text-primary-700-ink rst:dark:hover:text-primary-500-ink"},{variant:"solid",colorScheme:"orange",className:"rst:bg-orange-600 rst:hover:bg-orange-700 rst:dark:bg-orange-600 rst:dark:hover:bg-orange-700 rst:text-orange-600-ink rst:hover:text-orange-700-ink rst:dark:hover:text-orange-700-ink"},{variant:"solid",colorScheme:"teal",className:"rst:bg-teal-600 rst:hover:bg-teal-500 rst:dark:bg-teal-600 rst:dark:hover:bg-teal-500 rst:text-teal-600-ink rst:hover:text-teal-500-ink rst:dark:hover:text-teal-500-ink"},{variant:"solid",colorScheme:"purple",className:"rst:bg-purple-600 rst:hover:bg-purple-700 rst:dark:bg-purple-600 rst:dark:hover:bg-purple-700 rst:text-purple-600-ink rst:hover:text-purple-700-ink rst:dark:hover:text-purple-700-ink"},{variant:"solid",colorScheme:"amber",className:"rst:bg-amber-400 rst:hover:bg-amber-500 rst:dark:bg-amber-500 rst:dark:hover:bg-amber-400 rst:text-amber-400-ink rst:hover:text-amber-500-ink rst:dark:text-amber-500-ink rst:dark:hover:text-amber-400-ink"},{variant:"solid",colorScheme:"success",className:"rst:bg-success-600 rst:hover:bg-success-700 rst:dark:bg-success-600 rst:dark:hover:bg-success-700 rst:text-success-600-ink rst:hover:text-success-700-ink rst:dark:hover:text-success-700-ink"},{variant:"solid",colorScheme:"error",className:"rst:bg-error-600 rst:hover:bg-error-700 rst:dark:bg-error-600 rst:dark:hover:bg-error-500 rst:text-error-600-ink rst:hover:text-error-700-ink rst:dark:hover:text-error-500-ink"},{variant:"solid",colorScheme:"neutral",className:"rst:bg-gray-600 rst:hover:bg-gray-700 rst:dark:bg-gray-600 rst:dark:hover:bg-gray-500 rst:text-gray-600-ink rst:hover:text-gray-700-ink rst:dark:hover:text-gray-500-ink"},{variant:"soft",colorScheme:"primary",className:"rst:bg-primary-50 rst:text-primary-700 rst:hover:bg-primary-100 rst:dark:bg-primary-900/40 rst:dark:text-primary-300 rst:dark:hover:bg-primary-900/60"},{variant:"soft",colorScheme:"orange",className:"rst:bg-orange-50 rst:text-orange-700 rst:hover:bg-orange-100 rst:dark:bg-orange-900/30 rst:dark:text-orange-300 rst:dark:hover:bg-orange-900/50"},{variant:"soft",colorScheme:"teal",className:"rst:bg-teal-100 rst:text-teal-800 rst:hover:bg-teal-200 rst:dark:bg-teal-900/30 rst:dark:text-teal-300 rst:dark:hover:bg-teal-900/50"},{variant:"soft",colorScheme:"purple",className:"rst:bg-purple-50 rst:text-purple-700 rst:hover:bg-purple-100 rst:dark:bg-purple-900/30 rst:dark:text-purple-300 rst:dark:hover:bg-purple-900/50"},{variant:"soft",colorScheme:"amber",className:"rst:bg-amber-50 rst:text-amber-800 rst:hover:bg-amber-100 rst:dark:bg-amber-900/30 rst:dark:text-amber-300 rst:dark:hover:bg-amber-900/50"},{variant:"soft",colorScheme:"success",className:"rst:bg-success-50 rst:text-success-700 rst:hover:bg-success-100 rst:dark:bg-success-900/30 rst:dark:text-success-300 rst:dark:hover:bg-success-900/50"},{variant:"soft",colorScheme:"error",className:"rst:bg-error-50 rst:text-error-700 rst:hover:bg-error-100 rst:dark:bg-error-900/30 rst:dark:text-error-300 rst:dark:hover:bg-error-900/50"},{variant:"soft",colorScheme:"neutral",className:"rst:bg-gray-100 rst:text-gray-700 rst:hover:bg-gray-200 rst:dark:bg-gray-800/50 rst:dark:text-gray-300 rst:dark:hover:bg-gray-800"},{variant:"outline",colorScheme:"primary",className:"rst:border-primary-600 rst:text-primary-600 rst:hover:bg-primary-50 rst:dark:border-primary-500 rst:dark:text-primary-400 rst:dark:hover:bg-primary-500/10"},{variant:"outline",colorScheme:"orange",className:"rst:border-orange-600 rst:text-orange-600 rst:hover:bg-orange-50 rst:dark:border-orange-500 rst:dark:text-orange-400 rst:dark:hover:bg-orange-500/10"},{variant:"outline",colorScheme:"teal",className:"rst:border-teal-600 rst:text-teal-600 rst:hover:bg-teal-50 rst:dark:border-teal-500 rst:dark:text-teal-400 rst:dark:hover:bg-teal-500/10"},{variant:"outline",colorScheme:"purple",className:"rst:border-purple-600 rst:text-purple-600 rst:hover:bg-purple-50 rst:dark:border-purple-500 rst:dark:text-purple-400 rst:dark:hover:bg-purple-500/10"},{variant:"outline",colorScheme:"amber",className:"rst:border-amber-600 rst:text-amber-600 rst:hover:bg-amber-50 rst:dark:border-amber-500 rst:dark:text-amber-400 rst:dark:hover:bg-amber-500/10"},{variant:"outline",colorScheme:"success",className:"rst:border-success-600 rst:text-success-600 rst:hover:bg-success-50 rst:dark:border-success-500 rst:dark:text-success-400 rst:dark:hover:bg-success-500/10"},{variant:"outline",colorScheme:"error",className:"rst:border-error-600 rst:text-error-600 rst:hover:bg-error-50 rst:dark:border-error-500 rst:dark:text-error-400 rst:dark:hover:bg-error-500/10"},{variant:"outline",colorScheme:"neutral",className:"rst:border-gray-300 rst:text-gray-700 rst:hover:bg-gray-50 rst:dark:border-gray-600 rst:dark:text-gray-300 rst:dark:hover:bg-gray-800/50"},{variant:"ghost",colorScheme:"primary",className:"rst:text-primary-600 rst:hover:bg-primary-500/10 rst:dark:text-primary-400 rst:dark:hover:bg-primary-400/15"},{variant:"ghost",colorScheme:"orange",className:"rst:text-orange-600 rst:hover:bg-orange-500/10 rst:dark:text-orange-400 rst:dark:hover:bg-orange-400/15"},{variant:"ghost",colorScheme:"teal",className:"rst:text-teal-600 rst:hover:bg-teal-500/10 rst:dark:text-teal-400 rst:dark:hover:bg-teal-400/15"},{variant:"ghost",colorScheme:"purple",className:"rst:text-purple-600 rst:hover:bg-purple-500/10 rst:dark:text-purple-400 rst:dark:hover:bg-purple-400/15"},{variant:"ghost",colorScheme:"amber",className:"rst:text-amber-600 rst:hover:bg-amber-500/10 rst:dark:text-amber-400 rst:dark:hover:bg-amber-400/15"},{variant:"ghost",colorScheme:"success",className:"rst:text-success-600 rst:hover:bg-success-500/10 rst:dark:text-success-400 rst:dark:hover:bg-success-400/15"},{variant:"ghost",colorScheme:"error",className:"rst:text-error-600 rst:hover:bg-error-500/10 rst:dark:text-error-400 rst:dark:hover:bg-error-400/15"},{variant:"ghost",colorScheme:"neutral",className:"rst:text-gray-600 rst:hover:bg-gray-500/10 rst:dark:text-gray-400 rst:dark:hover:bg-gray-400/15"},{variant:"link",colorScheme:"primary",className:"rst:text-primary-600 rst:hover:text-primary-700 rst:dark:text-primary-400 rst:dark:hover:text-primary-300"},{variant:"link",colorScheme:"orange",className:"rst:text-orange-600 rst:hover:text-orange-700 rst:dark:text-orange-400 rst:dark:hover:text-orange-300"},{variant:"link",colorScheme:"teal",className:"rst:text-teal-600 rst:hover:text-teal-700 rst:dark:text-teal-400 rst:dark:hover:text-teal-300"},{variant:"link",colorScheme:"purple",className:"rst:text-purple-600 rst:hover:text-purple-700 rst:dark:text-purple-400 rst:dark:hover:text-purple-300"},{variant:"link",colorScheme:"amber",className:"rst:text-amber-600 rst:hover:text-amber-700 rst:dark:text-amber-400 rst:dark:hover:text-amber-300"},{variant:"link",colorScheme:"success",className:"rst:text-success-600 rst:hover:text-success-700 rst:dark:text-success-400 rst:dark:hover:text-success-300"},{variant:"link",colorScheme:"error",className:"rst:text-error-600 rst:hover:text-error-700 rst:dark:text-error-400 rst:dark:hover:text-error-300"},{variant:"link",colorScheme:"neutral",className:"rst:text-gray-600 rst:hover:text-gray-900 rst:dark:text-gray-400 rst:dark:hover:text-gray-100"}],defaultVariants:{colorScheme:"primary",variant:"solid",size:"default"}});exports.buttonVariants=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:justify-center rst:cursor-pointer rst:whitespace-nowrap rst:rounded-md rst:text-sm rst:font-medium rst:ring-offset-background rst:transition-colors rst:focus-visible:outline-hidden rst:focus-visible:ring-2 rst:focus-visible:ring-ring rst:focus-visible:ring-offset-2 rst:disabled:pointer-events-none rst:disabled:opacity-50",{variants:{variant:{solid:"rst:border rst:border-transparent rst:elevation-control",soft:"rst:border-0 rst:shadow-none",outline:"rst:border rst:bg-transparent rst:elevation-control",ghost:"rst:border rst:border-transparent rst:bg-transparent",link:"rst:border-0 rst:bg-transparent rst:underline-offset-4 rst:hover:underline"},colorScheme:{primary:"",orange:"",teal:"",purple:"",amber:"",success:"",error:"",neutral:""},size:{xs:"rst:h-7 rst:rounded-sm rst:px-2 rst:text-xs",sm:"rst:h-9 rst:rounded-md rst:px-3",default:"rst:h-10 rst:px-4 rst:py-2",lg:"rst:h-11 rst:rounded-md rst:px-8",icon:"rst:h-10 rst:w-10"}},compoundVariants:[{variant:"solid",colorScheme:"primary",className:"rst:bg-primary-600 rst:hover:bg-primary-700 rst:dark:bg-primary-600 rst:dark:hover:bg-primary-500 rst:text-primary-600-ink rst:hover:text-primary-700-ink rst:dark:hover:text-primary-500-ink"},{variant:"solid",colorScheme:"orange",className:"rst:bg-orange-600 rst:hover:bg-orange-700 rst:dark:bg-orange-600 rst:dark:hover:bg-orange-700 rst:text-orange-600-ink rst:hover:text-orange-700-ink rst:dark:hover:text-orange-700-ink"},{variant:"solid",colorScheme:"teal",className:"rst:bg-teal-600 rst:hover:bg-teal-500 rst:dark:bg-teal-600 rst:dark:hover:bg-teal-500 rst:text-teal-600-ink rst:hover:text-teal-500-ink rst:dark:hover:text-teal-500-ink"},{variant:"solid",colorScheme:"purple",className:"rst:bg-purple-600 rst:hover:bg-purple-700 rst:dark:bg-purple-600 rst:dark:hover:bg-purple-700 rst:text-purple-600-ink rst:hover:text-purple-700-ink rst:dark:hover:text-purple-700-ink"},{variant:"solid",colorScheme:"amber",className:"rst:bg-amber-400 rst:hover:bg-amber-500 rst:dark:bg-amber-500 rst:dark:hover:bg-amber-400 rst:text-amber-400-ink rst:hover:text-amber-500-ink rst:dark:text-amber-500-ink rst:dark:hover:text-amber-400-ink"},{variant:"solid",colorScheme:"success",className:"rst:bg-success-600 rst:hover:bg-success-700 rst:dark:bg-success-600 rst:dark:hover:bg-success-700 rst:text-success-600-ink rst:hover:text-success-700-ink rst:dark:hover:text-success-700-ink"},{variant:"solid",colorScheme:"error",className:"rst:bg-error-600 rst:hover:bg-error-700 rst:dark:bg-error-600 rst:dark:hover:bg-error-500 rst:text-error-600-ink rst:hover:text-error-700-ink rst:dark:hover:text-error-500-ink"},{variant:"solid",colorScheme:"neutral",className:"rst:bg-gray-600 rst:hover:bg-gray-700 rst:dark:bg-gray-600 rst:dark:hover:bg-gray-500 rst:text-gray-600-ink rst:hover:text-gray-700-ink rst:dark:hover:text-gray-500-ink"},{variant:"soft",colorScheme:"primary",className:"rst:bg-primary-50 rst:text-primary-700 rst:hover:bg-primary-100 rst:dark:bg-primary-900/40 rst:dark:text-primary-300 rst:dark:hover:bg-primary-900/60"},{variant:"soft",colorScheme:"orange",className:"rst:bg-orange-50 rst:text-orange-700 rst:hover:bg-orange-100 rst:dark:bg-orange-900/30 rst:dark:text-orange-300 rst:dark:hover:bg-orange-900/50"},{variant:"soft",colorScheme:"teal",className:"rst:bg-teal-100 rst:text-teal-800 rst:hover:bg-teal-200 rst:dark:bg-teal-900/30 rst:dark:text-teal-300 rst:dark:hover:bg-teal-900/50"},{variant:"soft",colorScheme:"purple",className:"rst:bg-purple-50 rst:text-purple-700 rst:hover:bg-purple-100 rst:dark:bg-purple-900/30 rst:dark:text-purple-300 rst:dark:hover:bg-purple-900/50"},{variant:"soft",colorScheme:"amber",className:"rst:bg-amber-50 rst:text-amber-800 rst:hover:bg-amber-100 rst:dark:bg-amber-900/30 rst:dark:text-amber-300 rst:dark:hover:bg-amber-900/50"},{variant:"soft",colorScheme:"success",className:"rst:bg-success-50 rst:text-success-700 rst:hover:bg-success-100 rst:dark:bg-success-900/30 rst:dark:text-success-300 rst:dark:hover:bg-success-900/50"},{variant:"soft",colorScheme:"error",className:"rst:bg-error-50 rst:text-error-700 rst:hover:bg-error-100 rst:dark:bg-error-900/30 rst:dark:text-error-300 rst:dark:hover:bg-error-900/50"},{variant:"soft",colorScheme:"neutral",className:"rst:bg-gray-100 rst:text-gray-700 rst:hover:bg-gray-200 rst:dark:bg-gray-800/50 rst:dark:text-gray-300 rst:dark:hover:bg-gray-800"},{variant:"outline",colorScheme:"primary",className:"rst:border-primary-600 rst:text-primary-600 rst:hover:bg-primary-50 rst:dark:border-primary-500 rst:dark:text-primary-400 rst:dark:hover:bg-primary-500/10"},{variant:"outline",colorScheme:"orange",className:"rst:border-orange-600 rst:text-orange-600 rst:hover:bg-orange-50 rst:dark:border-orange-500 rst:dark:text-orange-400 rst:dark:hover:bg-orange-500/10"},{variant:"outline",colorScheme:"teal",className:"rst:border-teal-600 rst:text-teal-600 rst:hover:bg-teal-50 rst:dark:border-teal-500 rst:dark:text-teal-400 rst:dark:hover:bg-teal-500/10"},{variant:"outline",colorScheme:"purple",className:"rst:border-purple-600 rst:text-purple-600 rst:hover:bg-purple-50 rst:dark:border-purple-500 rst:dark:text-purple-400 rst:dark:hover:bg-purple-500/10"},{variant:"outline",colorScheme:"amber",className:"rst:border-amber-600 rst:text-amber-600 rst:hover:bg-amber-50 rst:dark:border-amber-500 rst:dark:text-amber-400 rst:dark:hover:bg-amber-500/10"},{variant:"outline",colorScheme:"success",className:"rst:border-success-600 rst:text-success-600 rst:hover:bg-success-50 rst:dark:border-success-500 rst:dark:text-success-400 rst:dark:hover:bg-success-500/10"},{variant:"outline",colorScheme:"error",className:"rst:border-error-600 rst:text-error-600 rst:hover:bg-error-50 rst:dark:border-error-500 rst:dark:text-error-400 rst:dark:hover:bg-error-500/10"},{variant:"outline",colorScheme:"neutral",className:"rst:border-gray-300 rst:text-gray-700 rst:hover:bg-gray-50 rst:dark:border-gray-600 rst:dark:text-gray-300 rst:dark:hover:bg-gray-800/50"},{variant:"ghost",colorScheme:"primary",className:"rst:text-primary-600 rst:hover:bg-primary-500/10 rst:dark:text-primary-400 rst:dark:hover:bg-primary-400/15"},{variant:"ghost",colorScheme:"orange",className:"rst:text-orange-600 rst:hover:bg-orange-500/10 rst:dark:text-orange-400 rst:dark:hover:bg-orange-400/15"},{variant:"ghost",colorScheme:"teal",className:"rst:text-teal-600 rst:hover:bg-teal-500/10 rst:dark:text-teal-400 rst:dark:hover:bg-teal-400/15"},{variant:"ghost",colorScheme:"purple",className:"rst:text-purple-600 rst:hover:bg-purple-500/10 rst:dark:text-purple-400 rst:dark:hover:bg-purple-400/15"},{variant:"ghost",colorScheme:"amber",className:"rst:text-amber-600 rst:hover:bg-amber-500/10 rst:dark:text-amber-400 rst:dark:hover:bg-amber-400/15"},{variant:"ghost",colorScheme:"success",className:"rst:text-success-600 rst:hover:bg-success-500/10 rst:dark:text-success-400 rst:dark:hover:bg-success-400/15"},{variant:"ghost",colorScheme:"error",className:"rst:text-error-600 rst:hover:bg-error-500/10 rst:dark:text-error-400 rst:dark:hover:bg-error-400/15"},{variant:"ghost",colorScheme:"neutral",className:"rst:text-gray-600 rst:hover:bg-gray-500/10 rst:dark:text-gray-400 rst:dark:hover:bg-gray-400/15"},{variant:"link",colorScheme:"primary",className:"rst:text-primary-600 rst:hover:text-primary-700 rst:dark:text-primary-400 rst:dark:hover:text-primary-300"},{variant:"link",colorScheme:"orange",className:"rst:text-orange-600 rst:hover:text-orange-700 rst:dark:text-orange-400 rst:dark:hover:text-orange-300"},{variant:"link",colorScheme:"teal",className:"rst:text-teal-600 rst:hover:text-teal-700 rst:dark:text-teal-400 rst:dark:hover:text-teal-300"},{variant:"link",colorScheme:"purple",className:"rst:text-purple-600 rst:hover:text-purple-700 rst:dark:text-purple-400 rst:dark:hover:text-purple-300"},{variant:"link",colorScheme:"amber",className:"rst:text-amber-600 rst:hover:text-amber-700 rst:dark:text-amber-400 rst:dark:hover:text-amber-300"},{variant:"link",colorScheme:"success",className:"rst:text-success-600 rst:hover:text-success-700 rst:dark:text-success-400 rst:dark:hover:text-success-300"},{variant:"link",colorScheme:"error",className:"rst:text-error-600 rst:hover:text-error-700 rst:dark:text-error-400 rst:dark:hover:text-error-300"},{variant:"link",colorScheme:"neutral",className:"rst:text-gray-600 rst:hover:text-gray-900 rst:dark:text-gray-400 rst:dark:hover:text-gray-100"}],defaultVariants:{colorScheme:"primary",variant:"solid",size:"default"}});exports.buttonVariants=t;
@@ -6,11 +6,13 @@ const e = /* @__PURE__ */ r(
6
6
  variants: {
7
7
  variant: {
8
8
  solid: "rst:border rst:border-transparent rst:elevation-control",
9
- soft: "rst:border-transparent rst:shadow-none",
9
+ // `border-0`, here and on `link`: a <button> draws the browser's own
10
+ // border unless told otherwise, and an app without a reset would see
11
+ // it. Zero rather than the 1px the others have, because zero is what
12
+ // every app with a reset already draws: none of them moves.
13
+ soft: "rst:border-0 rst:shadow-none",
10
14
  outline: "rst:border rst:bg-transparent rst:elevation-control",
11
15
  ghost: "rst:border rst:border-transparent rst:bg-transparent",
12
- // `border-0`: a <button> draws the browser's own border unless told
13
- // otherwise, and an app without a reset would see it round a link.
14
16
  link: "rst:border-0 rst:bg-transparent rst:underline-offset-4 rst:hover:underline"
15
17
  },
16
18
  colorScheme: {
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("../../../node_modules/class-variance-authority/dist/index.cjs"),r=t.cva("rst:font-mono rst:uppercase rst:leading-none",{variants:{size:{xs:"rst:text-[0.625rem] rst:tracking-[0.16em]",sm:"rst:text-[0.6875rem] rst:tracking-[0.14em]",md:"rst:text-xs rst:tracking-[0.12em]"},tone:{faint:"rst:text-gray-500 rst:dark:text-gray-400",default:"rst:text-gray-700 rst:dark:text-gray-300",strong:"rst:text-gray-900 rst:dark:text-gray-100",primary:"rst:text-primary-600 rst:dark:text-primary-400"},weight:{normal:"rst:font-normal",medium:"rst:font-medium",semibold:"rst:font-semibold"}},defaultVariants:{size:"xs",tone:"faint",weight:"normal"}});exports.eyebrowVariants=r;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("../../../node_modules/class-variance-authority/dist/index.cjs"),r=t.cva("rst:font-mono rst:uppercase",{variants:{size:{xs:"rst:text-[0.625rem] rst:leading-none rst:tracking-[0.16em]",sm:"rst:text-[0.6875rem] rst:leading-none rst:tracking-[0.14em]",md:"rst:text-xs rst:leading-none rst:tracking-[0.12em]"},tone:{faint:"rst:text-gray-500 rst:dark:text-gray-400",default:"rst:text-gray-700 rst:dark:text-gray-300",strong:"rst:text-gray-900 rst:dark:text-gray-100",primary:"rst:text-primary-600 rst:dark:text-primary-400"},weight:{normal:"rst:font-normal",medium:"rst:font-medium",semibold:"rst:font-semibold"}},defaultVariants:{size:"xs",tone:"faint",weight:"normal"}});exports.eyebrowVariants=r;
@@ -1,12 +1,16 @@
1
1
  import { cva as t } from "../../../node_modules/class-variance-authority/dist/index.js";
2
2
  const e = /* @__PURE__ */ t(
3
- "rst:font-mono rst:uppercase rst:leading-none",
3
+ "rst:font-mono rst:uppercase",
4
4
  {
5
5
  variants: {
6
+ /* `leading-none` after each size, never before it: tailwind-merge
7
+ drops a line height that comes before a font size, because a size
8
+ can carry its own. Placed first, it was lost, and the line was 1.5
9
+ times the size instead of 1. */
6
10
  size: {
7
- xs: "rst:text-[0.625rem] rst:tracking-[0.16em]",
8
- sm: "rst:text-[0.6875rem] rst:tracking-[0.14em]",
9
- md: "rst:text-xs rst:tracking-[0.12em]"
11
+ xs: "rst:text-[0.625rem] rst:leading-none rst:tracking-[0.16em]",
12
+ sm: "rst:text-[0.6875rem] rst:leading-none rst:tracking-[0.14em]",
13
+ md: "rst:text-xs rst:leading-none rst:tracking-[0.12em]"
10
14
  },
11
15
  tone: {
12
16
  faint: "rst:text-gray-500 rst:dark:text-gray-400",
@@ -1 +1 @@
1
- "use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime"),S=require("react"),Y=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"),F=require("../../../node_modules/@fortawesome/free-solid-svg-icons/index.cjs"),s=require("../../../lib/utils.cjs"),R=require("../../../internal/field-invalid.cjs"),J=require("../Select/select-variants.cjs"),_=require("../Chip/Chip.cjs"),K=require("../../../internal/PopupOption.cjs"),c=require("../../../internal/popup.cjs"),Q=({options:x,value:n,onChange:m,placeholder:v="Select options",disabled:a=!1,variant:f,size:i,error:L,className:D,triggerClassName:A,optionsClassName:E,helperText:b,errorMessage:p,label:g,display:u="chips",maxChips:N,clearable:j=!1,chipColorScheme:w="neutral",chipVariant:k="outline",clearLabel:U="Clear selection",removeLabel:$=l=>`Remove ${l}`,...I})=>{const l=!!p||L,C=R.isFieldInvalid(l,I),V=R.withoutInvalidProps(I),o=n.length>0,P=new Map(x.map((r,e)=>[r.value,e])),d=n.map(r=>({value:r,label:x.find(e=>e.value===r)?.label??String(r)})).sort((r,e)=>(P.get(r.value)??Number.POSITIVE_INFINITY)-(P.get(e.value)??Number.POSITIVE_INFINITY)),y=N===void 0?d:d.slice(0,N),q=d.length-y.length,{ref:B,inDarkScope:H}=c.useDarkScope(),O=S.useRef(null);return t.jsxs(W.Field,{disabled:a,className:s.cn("rst:flex rst:flex-col rst:gap-1.5",D),...V,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:n,onChange:m,disabled:a,multiple:!0,children:t.jsxs("div",{ref:B,className:"rst:relative",children:[t.jsxs("div",{className:s.cn(J.selectTriggerVariants({variant:f,size:i,error:l}),"rst:h-auto rst:flex-wrap rst:items-center rst:gap-1.5 rst:py-1.5",i==="sm"?"rst:min-h-9":i==="lg"?"rst:min-h-11":"rst:min-h-10",j&&o&&"rst:pr-16","rst:focus-within:ring-[length:calc(var(--roster-border-width,1px)+1px)] rst:focus-within:ring-ring",a&&"rst:opacity-50 rst:cursor-not-allowed",A),children:[t.jsx(h.ListboxButton,{ref:O,"aria-invalid":C||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:o?u==="count"?`${n.length} selected`:d.map(r=>r.label).join(", "):v})}),!o&&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}),o&&u==="count"&&t.jsxs("span",{"aria-hidden":"true",className:"rst:pointer-events-none rst:relative rst:block rst:truncate",children:[n.length," selected"]}),o&&u==="chips"&&y.map((r,e)=>t.jsx(_.Chip,{size:"sm",variant:k,colorScheme:w,disabled:a,onRemove:()=>m(n.filter(M=>M!==r.value)),removeLabel:$(r.label),className:s.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})},`${e}-${String(r.value)}`)),q>0&&u==="chips"&&t.jsxs(_.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:["+",q]}),t.jsx("span",{className:s.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:F.faChevronDown,className:"rst:h-3.5 rst:w-3.5 rst:text-gray-400 rst:dark:text-gray-500","aria-hidden":"true"})}),j&&o&&t.jsx("button",{type:"button",disabled:a,onClick:()=>{m([]),O.current?.focus()},"aria-label":U,className:s.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",i==="sm"?"rst:right-7":"rst:right-8"),children:t.jsx(T.FontAwesomeIcon,{icon:F.faXmark,className:"rst:h-3.5 rst:w-3.5","aria-hidden":"true"})})]}),t.jsx(G.Transition,{as:S.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:s.cn(c.popupInDarkPalette(H,f)&&"dark",c.POPUP_PANEL,c.POPUP_WIDTH_OF_BUTTON,E),children:x.map(r=>t.jsx(K.PopupOption,{as:h.ListboxOption,value:r.value,disabled:r.disabled,size:i,children:r.label},r.value))})})]})}),(b||p)&&t.jsx(Y.Description,{className:s.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:p||b})]})};exports.MultiSelect=Q;
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;
@@ -70,6 +70,8 @@ export interface MultiSelectProps extends Omit<React.HTMLAttributes<HTMLDivEleme
70
70
  * tell apart, so this takes the label rather than being a constant.
71
71
  */
72
72
  removeLabel?: (label: string) => string;
73
+ /** With `display="count"`, how many are chosen: "3 selected". Shown, and said. */
74
+ countLabel?: (count: number) => string;
73
75
  }
74
- declare const MultiSelect: ({ options, value, onChange, placeholder, disabled, variant, size, error, className, triggerClassName, optionsClassName, helperText, errorMessage, label, display, maxChips, clearable, chipColorScheme, chipVariant, clearLabel, removeLabel, ...props }: MultiSelectProps) => import("react/jsx-runtime").JSX.Element;
76
+ declare const MultiSelect: ({ options, value, onChange, placeholder, disabled, variant, size, error, className, triggerClassName, optionsClassName, helperText, errorMessage, label, display, maxChips, clearable, chipColorScheme, chipVariant, clearLabel, removeLabel, countLabel, ...props }: MultiSelectProps) => import("react/jsx-runtime").JSX.Element;
75
77
  export { MultiSelect };