@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.
- package/README.md +137 -16
- package/dist/components/atoms/Chip/chip-variants.cjs +1 -1
- package/dist/components/atoms/Chip/chip-variants.js +8 -2
- package/dist/components/atoms/Combobox/Combobox.cjs +1 -1
- package/dist/components/atoms/Combobox/Combobox.js +20 -18
- package/dist/components/atoms/MultiSelect/MultiSelect.cjs +1 -1
- package/dist/components/atoms/MultiSelect/MultiSelect.js +22 -20
- package/dist/components/atoms/Select/Select.cjs +1 -1
- package/dist/components/atoms/Select/Select.js +19 -17
- package/dist/components/molecules/Carousel/Carousel.cjs +1 -1
- package/dist/components/molecules/Carousel/Carousel.js +31 -29
- package/dist/components/molecules/FileUpload/FileUpload.cjs +1 -1
- package/dist/components/molecules/FileUpload/FileUpload.js +21 -19
- package/dist/components/molecules/LiquidTabs/LiquidCount.cjs +1 -0
- package/dist/components/molecules/LiquidTabs/LiquidCount.d.ts +29 -0
- package/dist/components/molecules/LiquidTabs/LiquidCount.js +21 -0
- package/dist/components/molecules/LiquidTabs/LiquidNav.cjs +1 -1
- package/dist/components/molecules/LiquidTabs/LiquidNav.d.ts +12 -1
- package/dist/components/molecules/LiquidTabs/LiquidNav.js +50 -44
- package/dist/components/molecules/LiquidTabs/LiquidTabPanel.cjs +1 -0
- package/dist/components/molecules/LiquidTabs/LiquidTabPanel.d.ts +52 -0
- package/dist/components/molecules/LiquidTabs/LiquidTabPanel.js +32 -0
- package/dist/components/molecules/LiquidTabs/LiquidTabs.cjs +1 -1
- package/dist/components/molecules/LiquidTabs/LiquidTabs.d.ts +20 -1
- package/dist/components/molecules/LiquidTabs/LiquidTabs.js +59 -52
- package/dist/components/molecules/LiquidTabs/liquid-count.cjs +1 -0
- package/dist/components/molecules/LiquidTabs/liquid-count.d.ts +37 -0
- package/dist/components/molecules/LiquidTabs/liquid-count.js +9 -0
- package/dist/components/molecules/Menu/Menu.cjs +1 -1
- package/dist/components/molecules/Menu/Menu.js +104 -102
- package/dist/components/molecules/RadioGroup/RadioGroup.cjs +1 -1
- package/dist/components/molecules/RadioGroup/RadioGroup.js +23 -21
- package/dist/components/molecules/RangeSlider/RangeSlider.cjs +1 -1
- package/dist/components/molecules/RangeSlider/RangeSlider.d.ts +8 -3
- package/dist/components/molecules/RangeSlider/RangeSlider.js +38 -36
- package/dist/components/molecules/Slider/Slider.cjs +1 -1
- package/dist/components/molecules/Slider/Slider.d.ts +7 -3
- package/dist/components/molecules/Slider/Slider.js +30 -28
- package/dist/components/molecules/Slider/track-parts.d.ts +2 -1
- package/dist/components/organisms/Dialog/Dialog.cjs +1 -1
- package/dist/components/organisms/Dialog/Dialog.js +19 -17
- package/dist/components/organisms/ModerationQueue/ModerationQueue.cjs +1 -1
- package/dist/components/organisms/ModerationQueue/ModerationQueue.js +230 -207
- package/dist/components/organisms/Navbar/Navbar.cjs +1 -1
- package/dist/components/organisms/Navbar/Navbar.js +24 -22
- package/dist/components/organisms/Sheet/Sheet.cjs +1 -1
- package/dist/components/organisms/Sheet/Sheet.js +25 -23
- package/dist/index.d.ts +2 -0
- package/dist/internal/key-focus.cjs +1 -0
- package/dist/internal/key-focus.d.ts +32 -0
- package/dist/internal/key-focus.js +60 -0
- package/dist/internal/popup.cjs +1 -1
- package/dist/internal/popup.d.ts +15 -1
- package/dist/internal/popup.js +17 -12
- package/dist/meta.json +3 -3
- package/dist/roster.cjs +1 -1
- package/dist/roster.css +1 -1
- package/dist/roster.js +150 -145
- 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
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
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.
|
|
943
|
-
|
|
944
|
-
|
|
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
|
|
1341
|
-
`items.length
|
|
1342
|
-
image can't render (an expired link, a
|
|
1343
|
-
falls back to a link to the original in the
|
|
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
|
|
1874
|
-
|
|
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.
|
|
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
|
|
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
|
-
|
|
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
|
|
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"),
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
},
|
|
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:
|
|
29
|
+
error: y,
|
|
29
30
|
label: p,
|
|
30
31
|
helperText: f,
|
|
31
|
-
errorMessage:
|
|
32
|
-
className:
|
|
32
|
+
errorMessage: m,
|
|
33
|
+
className: P,
|
|
33
34
|
inputClassName: N,
|
|
34
35
|
optionsClassName: C,
|
|
35
36
|
emptyMessage: k = "No matches",
|
|
36
|
-
filter: g =
|
|
37
|
+
filter: g = z,
|
|
37
38
|
...u
|
|
38
39
|
}) => {
|
|
39
|
-
|
|
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",
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
-
$(
|
|
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 ||
|
|
137
|
+
(f || m) && /* @__PURE__ */ t(
|
|
136
138
|
R,
|
|
137
139
|
{
|
|
138
140
|
className: e(
|
|
139
141
|
"rst:text-xs rst:text-left",
|
|
140
|
-
|
|
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:
|
|
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
|
-
|
|
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"),
|
|
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
|
|
4
|
-
import { Description as
|
|
5
|
-
import { Field as
|
|
6
|
-
import { Label as
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
...
|
|
41
|
+
...y
|
|
41
42
|
}) => {
|
|
42
|
-
|
|
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) => (
|
|
47
|
-
), O = g === void 0 ? m : m.slice(0, g), S = m.length - O.length, { ref: B, inDarkScope: M } = nt(), _ =
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
232
|
+
Ot as MultiSelect
|
|
231
233
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
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;
|