@blakesteve/roster 4.8.1 → 4.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.
@@ -0,0 +1,75 @@
1
+ import { default as React } from 'react';
2
+ import { VariantProps } from 'class-variance-authority';
3
+ import { selectTriggerVariants } from '../Select/select-variants';
4
+ import { SelectOption } from '../Select/Select';
5
+ import { Chip } from '../Chip/Chip';
6
+ export type MultiSelectValue = string | number;
7
+ export interface MultiSelectProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "onChange" | "defaultValue">, VariantProps<typeof selectTriggerVariants> {
8
+ /** Same option shape as `Select`. */
9
+ options: SelectOption[];
10
+ value: MultiSelectValue[];
11
+ onChange: (value: MultiSelectValue[]) => void;
12
+ placeholder?: string;
13
+ disabled?: boolean;
14
+ className?: string;
15
+ label?: string;
16
+ /** Classes for the trigger button itself. Mirrors `Select`. */
17
+ triggerClassName?: string;
18
+ /** Classes for the popup panel. Mirrors `Select`. */
19
+ optionsClassName?: string;
20
+ /** Supporting text under the trigger. */
21
+ helperText?: string;
22
+ /**
23
+ * The message for an invalid selection. Implies `error`, so a caller cannot
24
+ * set the red ring and forget to say why. Mirrors `Select`.
25
+ */
26
+ errorMessage?: string;
27
+ /**
28
+ * How the selection reads in the closed trigger.
29
+ *
30
+ * `chips` names every selection, which is the point of the component when
31
+ * the list is short. `count` is the escape hatch for a field that would
32
+ * otherwise grow to five rows on a narrow screen — `maxChips` handles the
33
+ * middle ground.
34
+ */
35
+ display?: "chips" | "count";
36
+ /**
37
+ * Chips to show before the rest collapse into a `+N` chip. `undefined` shows
38
+ * all of them.
39
+ */
40
+ maxChips?: number;
41
+ /** Adds a control that clears the whole selection. */
42
+ clearable?: boolean;
43
+ /** Color scheme for the selection chips. */
44
+ chipColorScheme?: React.ComponentProps<typeof Chip>["colorScheme"];
45
+ /**
46
+ * Fill for the selection chips. `outline` by default, and deliberately.
47
+ *
48
+ * The trigger's own default variant paints `--roster-control-bg`, which is
49
+ * `transparent` — so a chip sits on whatever the page is, not on a surface
50
+ * this component controls. A `soft neutral` chip is `gray-100`, which on the
51
+ * library's own `gray-50` page is a 1.04:1 rectangle: the chips rendered,
52
+ * measured correct, and could not be seen. `outline` is the one fill whose
53
+ * identity is a border rather than a background.
54
+ *
55
+ * Chip's own outline palette is not enough on its own, though, and that is
56
+ * why the chips below take `text-inherit` and `border-current`. Chip holds
57
+ * its border to 3:1 against a PAGE; this component can be told to paint its
58
+ * own surface, and `variant="slate"` paints `gray-700` — byte-identical to
59
+ * the neutral chip's own `gray-700` label. That rendered chip-shaped holes
60
+ * with no readable text at 1.00:1. Inheriting means the chip cannot disagree
61
+ * with the surface it was just placed on.
62
+ */
63
+ chipVariant?: React.ComponentProps<typeof Chip>["variant"];
64
+ /** Accessible name for the clear control. */
65
+ clearLabel?: string;
66
+ /**
67
+ * Builds the accessible name for a chip's dismiss control.
68
+ *
69
+ * A row of buttons all named "Remove" is a row a screen reader user cannot
70
+ * tell apart, so this takes the label rather than being a constant.
71
+ */
72
+ removeLabel?: (label: string) => string;
73
+ }
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;
75
+ export { MultiSelect };
@@ -0,0 +1,58 @@
1
+ import { default as React } from 'react';
2
+ import { VariantProps } from 'class-variance-authority';
3
+ import { Checkbox } from '../../atoms/Checkbox/Checkbox';
4
+ import { checkboxGroupOptionsVariants, checkboxGroupPanelVariants } from './checkbox-group-variants';
5
+ export type CheckboxGroupOption = {
6
+ value: string;
7
+ label: string;
8
+ disabled?: boolean;
9
+ /** Supporting text under the option's label. */
10
+ description?: string;
11
+ };
12
+ export type CheckboxGroupCategory = {
13
+ /** Heading for this run of options. Rendered as an `Eyebrow`. */
14
+ category: string;
15
+ options: CheckboxGroupOption[];
16
+ };
17
+ type CheckboxGroupOptions = CheckboxGroupOption[] | CheckboxGroupCategory[];
18
+ export interface CheckboxGroupProps extends Omit<React.HTMLAttributes<HTMLFieldSetElement>, "onChange" | "defaultValue">, Omit<VariantProps<typeof checkboxGroupPanelVariants>, "error">, Pick<VariantProps<typeof checkboxGroupOptionsVariants>, "columns"> {
19
+ /**
20
+ * A flat list, or a list of `{ category, options }` groups. Mixing the two
21
+ * is not supported: the first entry decides how the whole array is read.
22
+ */
23
+ options: CheckboxGroupOptions;
24
+ /** The selected values. Unknown values are preserved, not dropped. */
25
+ value: string[];
26
+ onChange: (value: string[]) => void;
27
+ /** The group's name. Becomes the fieldset's accessible name. */
28
+ label?: string;
29
+ /** Supporting text under the options. */
30
+ helperText?: string;
31
+ /**
32
+ * The message for an invalid selection. Implies the error state, so a caller
33
+ * cannot color the text red and forget to say why.
34
+ *
35
+ * What it repaints depends on `variant`, and the difference is worth
36
+ * knowing: `panel` gets an error border, `plain` has no boundary to repaint
37
+ * and so the message *is* the whole error state. Narrower than `Input`'s or
38
+ * `Select`'s, which both ring the control itself — a checkbox is not the
39
+ * thing that is invalid here, the selection is.
40
+ */
41
+ errorMessage?: string;
42
+ /**
43
+ * Caps the options' height and scrolls past it. A number is pixels.
44
+ *
45
+ * Applied inline rather than as a class because the useful values here are
46
+ * arbitrary — `240` is mega-squad's, yours will differ — and an arbitrary
47
+ * Tailwind value built from a prop is a class that does not exist at build
48
+ * time, which is exactly what `check-classes-emit` fails the build over.
49
+ */
50
+ maxHeight?: number | string;
51
+ /** Disables every option, and dims the label and helper text with them. */
52
+ disabled?: boolean;
53
+ colorScheme?: React.ComponentProps<typeof Checkbox>["colorScheme"];
54
+ /** Classes for the options' container. `className` lands on the fieldset. */
55
+ panelClassName?: string;
56
+ }
57
+ declare const CheckboxGroup: ({ options, value, onChange, label, helperText, errorMessage, maxHeight, disabled, variant, size, columns, colorScheme, className, panelClassName, "aria-describedby": ariaDescribedBy, "aria-invalid": ariaInvalid, ...props }: CheckboxGroupProps) => import("react/jsx-runtime").JSX.Element;
58
+ export { CheckboxGroup };
@@ -0,0 +1,34 @@
1
+ /**
2
+ * The container the options sit in.
3
+ *
4
+ * `plain` is the default because a checkbox group is not inherently a box: a
5
+ * short list of three options wants to sit on the form the way a Select's
6
+ * label and trigger do, with no chrome of its own.
7
+ *
8
+ * `panel` is the long-list case — the grouped, scrollable list mega-squad
9
+ * hand-rolled for its sports picker. It deliberately does NOT read
10
+ * `--roster-popover-*`: that family is documented as "a panel that floats over
11
+ * the page", and this one is in the flow.
12
+ *
13
+ * Its fill is `Card`'s `soft` exactly. Its border is deliberately two ramp
14
+ * steps heavier than that card's — `gray-200` against the card's `gray-100`,
15
+ * and no `/50` in dark. A card's hairline separates one block of content from
16
+ * the page; this one has to read as the wall a scroll region ends at, and at
17
+ * `gray-100` it did not.
18
+ */
19
+ export declare const checkboxGroupPanelVariants: (props?: ({
20
+ variant?: "plain" | "panel" | null | undefined;
21
+ size?: "sm" | "md" | "lg" | null | undefined;
22
+ error?: boolean | null | undefined;
23
+ } & import('class-variance-authority/types').ClassProp) | undefined) => string;
24
+ /**
25
+ * The options themselves.
26
+ *
27
+ * Every column count starts at one and widens at a breakpoint. A two-column
28
+ * checkbox list on a 320px screen is two columns of truncated labels, which is
29
+ * the layout this exists to avoid.
30
+ */
31
+ export declare const checkboxGroupOptionsVariants: (props?: ({
32
+ columns?: 1 | 2 | 3 | null | undefined;
33
+ size?: "sm" | "md" | "lg" | null | undefined;
34
+ } & import('class-variance-authority/types').ClassProp) | undefined) => string;
@@ -0,0 +1,30 @@
1
+ import { VariantProps } from 'class-variance-authority';
2
+ import { toastVariants } from './toast-variants';
3
+ import * as React from "react";
4
+ export interface ToastProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "title">, VariantProps<typeof toastVariants> {
5
+ /** The message itself. */
6
+ children: React.ReactNode;
7
+ /** Optional bolded first line above the message, as on `Alert`. */
8
+ title?: React.ReactNode;
9
+ /** Replaces the icon chosen for the color scheme. Pass `null` for none. */
10
+ icon?: React.ReactNode;
11
+ /** Presence adds a dismiss control. */
12
+ onDismiss?: () => void;
13
+ /** Accessible name for the dismiss control. */
14
+ dismissLabel?: string;
15
+ }
16
+ /**
17
+ * The body of a toast: icon, message, optional dismiss.
18
+ *
19
+ * Presentational and controlled. It does not queue, position or time itself —
20
+ * `Toaster` does that, and this stays renderable on its own so it can be
21
+ * tested and viewed without a running queue.
22
+ *
23
+ * `role` is deliberately not set here. A toast's urgency depends on what it is
24
+ * saying, not on how it looks, and the same body is used for all of them.
25
+ * `Toaster` decides: `alert` / `assertive` for errors, and react-hot-toast's
26
+ * `status` / `polite` for the rest. Rendered on its own, this sets no role at
27
+ * all, which is correct for a component that does not know why it exists.
28
+ */
29
+ declare const Toast: React.ForwardRefExoticComponent<ToastProps & React.RefAttributes<HTMLDivElement>>;
30
+ export { Toast };
@@ -0,0 +1,33 @@
1
+ import { ToasterProps as HotToasterProps } from 'react-hot-toast';
2
+ import { ToastProps } from './Toast';
3
+ export interface ToasterProps extends Pick<HotToasterProps, "position" | "gutter" | "reverseOrder" | "containerClassName"> {
4
+ /** Milliseconds a toast stays up. */
5
+ duration?: number;
6
+ /** Adds a dismiss control to every toast. */
7
+ dismissible?: boolean;
8
+ /**
9
+ * Fill treatment for every toast in the queue.
10
+ *
11
+ * `soft` is the default and is quiet enough that a stack does not shout.
12
+ * Reach for `solid` when toasts land over photography, video or any surface
13
+ * the app does not control, where a tint is a gamble.
14
+ */
15
+ variant?: ToastProps["variant"];
16
+ }
17
+ /**
18
+ * Mount once, near the root. Everything else goes through `toast`.
19
+ *
20
+ * This wraps react-hot-toast rather than replacing it, because both consumers
21
+ * already depend on it at the same version and already write
22
+ * `toast.success(...)`. Wrapping means their call sites do not move; what
23
+ * changes is that the toast stops being styled with hardcoded hex in each app
24
+ * — game-verdict pinned `#1a1f2e` and `#10b981`, mega-squad `#413f3c` and
25
+ * `#f3eee3`, neither of which is in either app's palette any more.
26
+ *
27
+ * The `children` render prop is used rather than `toastOptions`, so the body
28
+ * is a real Roster component instead of a set of inline styles handed to
29
+ * someone else's markup. That is what lets `Toast` be tested and viewed on its
30
+ * own, and what lets a toast carry a title, a dismiss control and the popover
31
+ * tokens.
32
+ */
33
+ export declare function Toaster({ position, duration, dismissible, variant, gutter, reverseOrder, containerClassName, }: ToasterProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,38 @@
1
+ import { Renderable, Toast, ToastOptions, ValueOrFunction } from 'react-hot-toast';
2
+ /** Everything react-hot-toast accepts as a message, including a render fn. */
3
+ type Message = ValueOrFunction<Renderable, Toast>;
4
+ /**
5
+ * The imperative handle: `toast.success("Saved")` from anywhere.
6
+ *
7
+ * A thin re-export of react-hot-toast's, with the gaps filled. Both consumers
8
+ * had already written this wrapper themselves — `gameToast` and `megaToast` —
9
+ * which is the usual sign it belongs in the library.
10
+ *
11
+ * The file is `toast-api.ts` rather than `toast.ts` because `Toast.tsx` sits
12
+ * beside it and the two collide on a case-insensitive filesystem. The export
13
+ * is still `toast`.
14
+ *
15
+ * `info` and `warning` are the additions, and they are not cosmetic.
16
+ * react-hot-toast ships `success`, `error`, `loading` and `blank` only, so an
17
+ * app wanting an informational toast has to improvise. One improvised by
18
+ * calling `toast.error`, so every informational message in that app rendered
19
+ * as an error — a bug that survived because the wrapper was three lines long
20
+ * and nobody re-read it.
21
+ */
22
+ export declare const toast: ((message: Message, options?: ToastOptions) => string) & {
23
+ success: (message: Message, options?: ToastOptions) => string;
24
+ error: (message: Message, options?: ToastOptions) => string;
25
+ info: (message: Message, options?: ToastOptions) => string;
26
+ warning: (message: Message, options?: ToastOptions) => string;
27
+ loading: (message: Message, options?: ToastOptions) => string;
28
+ custom: (message: Renderable | import('react-hot-toast').ValueFunction<Renderable, Toast>, options?: ToastOptions) => string;
29
+ dismiss: (toastId?: string, toasterId?: string) => void;
30
+ remove: (toastId?: string, toasterId?: string) => void;
31
+ promise: <T>(promise: Promise<T> | (() => Promise<T>), msgs: {
32
+ loading: Renderable;
33
+ success?: ValueOrFunction<Renderable, T>;
34
+ error?: ValueOrFunction<Renderable, any>;
35
+ }, opts?: import('react-hot-toast').DefaultToastOptions) => Promise<T>;
36
+ };
37
+ export declare const TONE_PREFIX = "rst-toast-tone-";
38
+ export {};
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Toast vs Alert.
3
+ *
4
+ * Alert is an inline notice strip: it sits in the flow of a page or a form,
5
+ * stays as long as the condition does, and the reader finds it by looking at
6
+ * the thing it is about. Toast is transient chrome floating over everything,
7
+ * announced rather than found, and gone in a few seconds.
8
+ *
9
+ * They share a color language on purpose — the same six schemes and the same
10
+ * icons — because "this failed" should not be two different reds depending on
11
+ * where it is said. What Toast adds is elevation and an opaque surface: it is
12
+ * drawn over arbitrary page content, so a tint that reads correctly inside a
13
+ * form can disappear over an image.
14
+ *
15
+ * The left stripe is Alert's. Toast borders on all sides instead, because a
16
+ * floating object needs a complete edge to read as detached from the page
17
+ * rather than as something that fell out of the layout.
18
+ */
19
+ export declare const toastVariants: (props?: ({
20
+ colorScheme?: "primary" | "amber" | "success" | "error" | "neutral" | "info" | null | undefined;
21
+ variant?: "soft" | "solid" | "glass" | null | undefined;
22
+ } & import('class-variance-authority/types').ClassProp) | undefined) => string;
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { j as e, T as C, a as S, b as l, c as P, F as a, f as w, d as y, e as v, g as c, B as n, h as N, i as R, k as T, l as k } from "./Table--O-sD53L.js";
2
+ import { j as e, T as C, a as S, b as l, c as P, F as a, f as w, d as y, e as v, g as c, B as n, h as N, i as R, k as T, l as k } from "./Table-C1JbdA7q.js";
3
3
  import { useState as F } from "react";
4
4
  import { tableFeatures as I, sortFns as A, rowPaginationFeature as M, rowSortingFeature as z, createPaginatedRowModel as D, createSortedRowModel as G, useTable as H, flexRender as g } from "@tanstack/react-table";
5
5
  import { c as o } from "./utils-hNxf9HpA.js";
package/dist/index.d.ts CHANGED
@@ -15,6 +15,9 @@ export * from './components/atoms/Input/input-variants';
15
15
  export * from './components/atoms/Link/Link';
16
16
  export * from './components/atoms/Link/link-variants';
17
17
  export * from './components/atoms/PasswordInput/PasswordInput';
18
+ export * from './components/atoms/Combobox/Combobox';
19
+ export * from './components/atoms/Chip/Chip';
20
+ export * from './components/atoms/Chip/chip-variants';
18
21
  export * from './components/atoms/Pill/Pill';
19
22
  export * from './components/atoms/Pill/pill-variants';
20
23
  export * from './components/atoms/Eyebrow/Eyebrow';
@@ -25,6 +28,7 @@ export * from './components/atoms/LabeledDivider/LabeledDivider';
25
28
  export * from './components/atoms/Stat/Stat';
26
29
  export * from './components/atoms/Stat/stat-variants';
27
30
  export * from './components/atoms/ThemeToggle/ThemeToggle';
31
+ export * from './components/atoms/MultiSelect/MultiSelect';
28
32
  export * from './components/atoms/Select/Select';
29
33
  export * from './components/atoms/Select/select-variants';
30
34
  export * from './components/atoms/Spinner/Spinner';
@@ -37,6 +41,10 @@ export * from './components/atoms/LiquidTabs/LiquidTabs';
37
41
  export * from './components/atoms/Tooltip/Tooltip';
38
42
  export * from './components/atoms/CollapsibleSection/CollapsibleSection';
39
43
  export * from './components/atoms/SegmentBar/SegmentBar';
44
+ export * from './components/molecules/Toast/Toast';
45
+ export * from './components/molecules/Toast/toast-variants';
46
+ export * from './components/molecules/Toast/Toaster';
47
+ export * from './components/molecules/Toast/toast-api';
40
48
  export * from './components/molecules/Alert/Alert';
41
49
  export * from './components/molecules/Alert/alert-variants';
42
50
  export * from './components/molecules/Accordion/Accordion';
@@ -44,6 +52,8 @@ export * from './components/molecules/DescriptionList/DescriptionList';
44
52
  export * from './components/molecules/DescriptionList/description-list-variants';
45
53
  export * from './components/molecules/Pullquote/Pullquote';
46
54
  export * from './components/molecules/Pullquote/pullquote-variants';
55
+ export * from './components/molecules/CheckboxGroup/CheckboxGroup';
56
+ export * from './components/molecules/CheckboxGroup/checkbox-group-variants';
47
57
  export * from './components/molecules/Breadcrumbs/Breadcrumbs';
48
58
  export * from './components/molecules/Breadcrumbs/breadcrumb-variants';
49
59
  export * from './components/molecules/CallToAction/CallToAction';
@@ -0,0 +1,21 @@
1
+ import * as React from "react";
2
+ /**
3
+ * One row in an anchored popup: the label, truncated, and the check mark that
4
+ * marks it selected.
5
+ *
6
+ * Extracted because it was copy-pasted between `Select` and `Combobox` and the
7
+ * rendered markup was byte-identical — which is the definition of the thing
8
+ * this module exists to hold. The README claimed the option rows were already
9
+ * shared before they were; this is that claim becoming true.
10
+ *
11
+ * It takes the Headless UI option component rather than importing one, because
12
+ * `ListboxOption` and `ComboboxOption` are different components with the same
13
+ * shape, and the alternative is this module knowing which caller it has.
14
+ */
15
+ export declare function PopupOption({ as: Option, value, disabled, size, children, }: {
16
+ as: React.ElementType;
17
+ value: string | number;
18
+ disabled?: boolean;
19
+ size?: "sm" | "default" | "lg" | null;
20
+ children: React.ReactNode;
21
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,103 @@
1
+ import * as React from "react";
2
+ /**
3
+ * The presentation shared by every anchored popup Roster opens off a control:
4
+ * `Select`'s menu, `Combobox`'s and `MultiSelect`'s, and whatever anchored
5
+ * popup comes next.
6
+ *
7
+ * Internal, and not exported from the package. Its contract is with those
8
+ * components, not with consumers — the escape hatch a consumer reaches for is
9
+ * `optionsClassName` on the component itself.
10
+ *
11
+ * It exists because the alternative is copying two subtle things into each
12
+ * one. Both have already been got wrong in a real app:
13
+ *
14
+ * - the `.dark` carry below, which is why a consumer's menu once rendered in
15
+ * Roster's grays while the trigger above it took their palette
16
+ * - the absence of a height utility in `POPUP_PANEL`, which reads like an
17
+ * oversight until you know Headless UI writes `max-height` inline
18
+ */
19
+ /**
20
+ * Carries a subtree-scoped `.dark` across the portal.
21
+ *
22
+ * Headless UI attaches an anchored panel to `<body>`, so it leaves whatever
23
+ * `.dark` subtree the trigger sits in. That is fine when `.dark` is on
24
+ * `<html>` — the portal is still a descendant — and wrong when a page scopes
25
+ * dark mode to part of itself, which Roster's README explicitly permits: the
26
+ * panel renders light against a dark page.
27
+ *
28
+ * `closest` finds the NEAREST `.dark`, which is exactly what
29
+ * `@custom-variant dark (&:where(.dark, .dark *))` matches, so this reproduces
30
+ * the cascade rather than second-guessing it. Applying the class to the panel
31
+ * covers the panel itself through the `&:where(.dark, …)` half, and its
32
+ * options through `.dark *`. Idempotent when `.dark` is already on the root.
33
+ *
34
+ * Read once, on mount. A theme TOGGLE does not need this at all: it flips
35
+ * `.dark` on `<html>`, and the portal is already a descendant of `<html>`. The
36
+ * only case this covers is a scoped `.dark`, which is part of a page's
37
+ * structure rather than something that changes at runtime.
38
+ */
39
+ export declare function useDarkScope<T extends HTMLElement>(): {
40
+ ref: React.RefObject<T | null>;
41
+ inDarkScope: boolean;
42
+ };
43
+ /**
44
+ * The panel's own classes, minus anything a caller should decide.
45
+ *
46
+ * Deliberately no `max-h-*` and no `overflow-*`. Headless UI's `size`
47
+ * middleware writes both INLINE on this element whenever `anchor` is set:
48
+ *
49
+ * Object.assign(floating.style, {
50
+ * overflow: "auto",
51
+ * maxHeight: `min(var(--anchor-max-height, 100vh), Npx)`,
52
+ * })
53
+ *
54
+ * so the panel has always been capped at the space between the trigger and the
55
+ * viewport edge, and has always scrolled. A utility here would lose to that
56
+ * inline rule anyway. `--anchor-max-height` is READ by that expression and
57
+ * never set by Headless UI — it is an author hook like `--anchor-gap` — so a
58
+ * consumer wanting a shorter menu sets the variable, not a height:
59
+ * `optionsClassName="rst:[--anchor-max-height:20rem]"`.
60
+ *
61
+ * The surface comes from `--roster-popover-*`, so a consumer who repaints the
62
+ * trigger with `--roster-control-*` does not open a hardcoded white sheet
63
+ * under it.
64
+ */
65
+ export declare const POPUP_PANEL: string;
66
+ /**
67
+ * Matching the panel's width to the control it opens from — and WHICH control
68
+ * that is depends on the component, which is why this is not folded into
69
+ * `POPUP_PANEL`.
70
+ *
71
+ * Headless UI writes both variables inline on the panel. For a `Listbox` the
72
+ * button IS the whole trigger, so `--button-width` is right. For a `Combobox`
73
+ * the trigger is the text input and the button is the little chevron beside
74
+ * it, so `--button-width` is about 20px and the panel renders as an
75
+ * unreadable sliver. Use `--input-width` there.
76
+ */
77
+ /**
78
+ * Whether the panel should render on the dark palette.
79
+ *
80
+ * Two reasons it might, and they are unrelated:
81
+ *
82
+ * - the control sits inside a `.dark` subtree, which the portaled panel does
83
+ * not inherit — that is `inDarkScope`, above.
84
+ * - the control's own variant NAMES a dark surface. `slate` paints `gray-700`
85
+ * in light mode, and its panel was rendering white: a dark trigger opening a
86
+ * white sheet, which is the exact mismatch `--roster-popover-*` was
87
+ * introduced to stop. The token family only ever covered the variant that
88
+ * reads tokens; the ones that name a surface were left behind.
89
+ *
90
+ * The fix reuses the dark palette rather than inventing a slate one, because
91
+ * every state in that palette already exists and has already been measured —
92
+ * `dark:data-focus:bg-primary-900/30` and `dark:data-selected:bg-gray-700/50`
93
+ * are designed for a dark sheet. Painting a bespoke slate panel would have
94
+ * meant a third set of option states with no contrast pass behind them.
95
+ *
96
+ * Shared here rather than repeated in three components, for the same reason
97
+ * everything else in this module is.
98
+ */
99
+ export declare function popupInDarkPalette(inDarkScope: boolean, variant: string | null | undefined): boolean;
100
+ export declare const POPUP_WIDTH_OF_BUTTON = "rst:w-(--button-width)";
101
+ export declare const POPUP_WIDTH_OF_INPUT = "rst:w-(--input-width)";
102
+ /** Where an anchored panel opens, and the only value Roster uses. */
103
+ export declare const POPUP_ANCHOR: "bottom start";
package/dist/meta.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "4.8.1",
3
- "tests": 1117,
4
- "testFiles": 93
2
+ "version": "4.9.0",
3
+ "tests": 1318,
4
+ "testFiles": 106
5
5
  }