@blakesteve/roster 5.9.0 → 5.10.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 +41 -22
- package/dist/components/atoms/Button/button-variants.js +1 -1
- package/dist/components/atoms/Eyebrow/eyebrow-variants.d.ts +2 -2
- package/dist/components/atoms/Input/input-variants.js +1 -1
- package/dist/components/atoms/Skeleton/Skeleton.cjs +1 -1
- package/dist/components/atoms/Skeleton/Skeleton.d.ts +19 -3
- package/dist/components/atoms/Skeleton/Skeleton.js +38 -33
- package/dist/components/atoms/ThemeToggle/ThemeToggle.d.ts +1 -1
- package/dist/components/molecules/CheckboxGroup/CheckboxGroup.d.ts +1 -1
- package/dist/components/molecules/CheckboxGroup/checkbox-group-variants.d.ts +1 -1
- package/dist/components/molecules/SkeletonPresets/SkeletonPresets.cjs +1 -1
- package/dist/components/molecules/SkeletonPresets/SkeletonPresets.d.ts +13 -4
- package/dist/components/molecules/SkeletonPresets/SkeletonPresets.js +35 -35
- package/dist/components/molecules/Toast/Toaster.d.ts +1 -1
- package/dist/components/organisms/Navbar/Navbar.cjs +1 -1
- package/dist/components/organisms/Navbar/Navbar.js +37 -37
- package/dist/lib/utils.cjs +1 -1
- package/dist/lib/utils.js +4 -1
- package/dist/meta.json +3 -3
- package/dist/roster.css +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -269,7 +269,7 @@ changes nothing.
|
|
|
269
269
|
| ----- | ------- | -------- |
|
|
270
270
|
| `--roster-radius-sm` | `0.25rem` | `Button` `xs`, `Checkbox` `sm` and `md`, `InlineCode`, `Link`, `MultiSelect`'s chip dismiss, the dismiss and reveal buttons in `Alert`, `Toast` and `PasswordInput` |
|
|
271
271
|
| `--roster-radius-md` | `0.375rem` | `Button`, `Input`, `Textarea`, `Select`, `MultiSelect`, `Badge`, `Avatar` and its popover, `Checkbox` `lg`, `CheckboxGroup`'s panel, `Disclosure`, `Dialog`'s and `Sheet`'s close buttons, `Navbar`'s links and menu, popup panels, `Table` |
|
|
272
|
-
| `--roster-radius-lg` | `0.5rem` | `Alert`, `Toast`, `Tooltip`, `CallToAction`, `EmptyState`, `ErrorState`, `LiquidTabs`, `MatchupCard`, `Navbar`'s mobile panel |
|
|
272
|
+
| `--roster-radius-lg` | `0.5rem` | `Alert`, `Toast`, `Tooltip`, `CallToAction`, `EmptyState`, `ErrorState`, `LiquidTabs`, `MatchupCard`, `Navbar`'s mobile panel, `Skeleton` blocks (unless `--roster-skeleton-radius` is set) |
|
|
273
273
|
| `--roster-radius-xl` | `0.75rem` | `Card`, `LiquidTabs`' `pill` strip |
|
|
274
274
|
| `--roster-radius-2xl` | `1rem` | `Dialog`, the top of `Sheet` |
|
|
275
275
|
| `--roster-radius-3xl` | `1.5rem` | nothing yet; wired for the first component that uses it |
|
|
@@ -607,10 +607,14 @@ its `label` (default "loading") says so.
|
|
|
607
607
|
The loading system has its own: `--roster-skeleton` and
|
|
608
608
|
`--roster-skeleton-highlight` are the skeleton's fill and the light that
|
|
609
609
|
crosses it, and the empty part of every progress bar (gray-200 and gray-100,
|
|
610
|
-
gray-700 and gray-600 in dark).
|
|
611
|
-
pace: `--roster-skeleton-duration` (1.8s),
|
|
612
|
-
|
|
613
|
-
|
|
610
|
+
gray-700 and gray-600 in dark). Four durations, unset by default, change the
|
|
611
|
+
pace: `--roster-skeleton-duration` (1.8s, the shimmer),
|
|
612
|
+
`--roster-skeleton-pulse-duration` (2s, the pulse),
|
|
613
|
+
`--roster-progress-travel-duration` (1.4s, the indeterminate pill) and
|
|
614
|
+
`--roster-dots-duration` (1.2s). `--roster-skeleton-pulse-opacity` (0.5) is
|
|
615
|
+
how far a pulse fades. Under reduced motion all of them stop on a resting
|
|
616
|
+
frame. `--roster-skeleton-radius` rounds skeleton blocks without touching the
|
|
617
|
+
shared radius scale (see Skeleton below).
|
|
614
618
|
|
|
615
619
|
### Scrollbars
|
|
616
620
|
|
|
@@ -1039,7 +1043,7 @@ rather than vanishing from a field that still reports it.
|
|
|
1039
1043
|
|
|
1040
1044
|
#### CheckboxGroup
|
|
1041
1045
|
|
|
1042
|
-
Three things it adds over the version
|
|
1046
|
+
Three things it adds over the version one app's form hand-rolled:
|
|
1043
1047
|
|
|
1044
1048
|
- **Each option is a Headless UI `Field`**, so its label is wired to its own
|
|
1045
1049
|
checkbox and clicking the text toggles it. The pointer cursor sits on the
|
|
@@ -1109,8 +1113,8 @@ silently drops any selected value whose option has not loaded yet.
|
|
|
1109
1113
|
|
|
1110
1114
|
`CheckboxGroup` exists instead of a multi-select `Select`, and the reason is
|
|
1111
1115
|
that neither multi-selection UI in the portfolio was ever a dropdown.
|
|
1112
|
-
|
|
1113
|
-
category headings;
|
|
1116
|
+
One app's form picks sports from a grouped, scrollable checklist with
|
|
1117
|
+
category headings; another's share form picks tags from a flat row of
|
|
1114
1118
|
toggles. Collapsing either into a menu would have hidden the options behind a
|
|
1115
1119
|
click to save vertical space neither screen was short of, so the component
|
|
1116
1120
|
follows the shape that already worked. A multi-select dropdown is still the
|
|
@@ -1205,7 +1209,7 @@ rather than a rewrite.
|
|
|
1205
1209
|
|
|
1206
1210
|
```tsx
|
|
1207
1211
|
<RadioGroup
|
|
1208
|
-
label="Who can see this
|
|
1212
|
+
label="Who can see this group"
|
|
1209
1213
|
helperText="You can change this at any time."
|
|
1210
1214
|
value={visibility}
|
|
1211
1215
|
onChange={setVisibility}
|
|
@@ -1459,7 +1463,21 @@ import { SkeletonRegion, SkeletonCard } from "@blakesteve/roster";
|
|
|
1459
1463
|
- The fill is `--roster-skeleton` (gray-200, gray-700 in dark), with
|
|
1460
1464
|
`--roster-skeleton-highlight` crossing it. Neutral rather than the brand
|
|
1461
1465
|
shimmer Countdown uses, and its own pair, so retinting one never recolors the
|
|
1462
|
-
other.
|
|
1466
|
+
other.
|
|
1467
|
+
- `animation` picks how it moves: `"shimmer"` (the default, a band of light
|
|
1468
|
+
crossing the fill), `"pulse"` (the fill fading and returning, nothing
|
|
1469
|
+
moving: quieter on a dense page) or `"none"`. Under reduced motion both
|
|
1470
|
+
movements stop on the flat fill, and in forced colors every shape keeps its
|
|
1471
|
+
outline (a pulse stops there, so the outline never fades). Pass it to
|
|
1472
|
+
`SkeletonRegion` and every skeleton inside takes it, presets included; a
|
|
1473
|
+
preset or a skeleton that names its own keeps it. A pulse runs
|
|
1474
|
+
`--roster-skeleton-pulse-duration` (2s) and fades to
|
|
1475
|
+
`--roster-skeleton-pulse-opacity` (0.5).
|
|
1476
|
+
- A block's corners are `--roster-skeleton-radius`, the `lg` step unless
|
|
1477
|
+
set. Set it on `:root` or on a wrapper (`14px`, say) and skeleton blocks
|
|
1478
|
+
follow, and nothing else does: the shared scale and every other component
|
|
1479
|
+
stay as they are. A block's `radius` prop still wins, a line keeps its
|
|
1480
|
+
small step, and a circle stays round.
|
|
1463
1481
|
|
|
1464
1482
|
**Progress and ProgressField.** `ProgressField` is the form to reach for: the
|
|
1465
1483
|
label and value on one baseline above the bar, an optional detail line below.
|
|
@@ -1833,7 +1851,7 @@ function App() {
|
|
|
1833
1851
|
| `CollapsibleSection` | Clamps any content (prose, chips, image grids) to a fixed height with a fade and expand/collapse toggle |
|
|
1834
1852
|
| `Select` | Dropdown selector, on the same size scale as `Button` and `Input` |
|
|
1835
1853
|
| `SegmentBar` | Proportional horizontal bar divided into colored segments with optional legend (a split, not progress) |
|
|
1836
|
-
| `Skeleton` | Line, block or circle placeholder at the content's exact size; `SkeletonRegion` sets `aria-busy`
|
|
1854
|
+
| `Skeleton` | Line, block or circle placeholder at the content's exact size, shimmering, pulsing or still; `SkeletonRegion` sets `aria-busy` |
|
|
1837
1855
|
| `Progress` | Continuous or segmented progress bar: determinate, indeterminate or busy; per-segment state |
|
|
1838
1856
|
| `LoadingDots` | Three dots for a model generating before its first token; replaced by the text |
|
|
1839
1857
|
| `Stat` | A figure with its label and, optionally, its source; a valid `<dl>` group, or `semantics="standalone"` |
|
|
@@ -2037,14 +2055,15 @@ anything new. It also fails when a listed class starts emitting, so a fix cannot
|
|
|
2037
2055
|
leave a stale entry behind. Run it with `--verbose` to print the list.
|
|
2038
2056
|
|
|
2039
2057
|
Story tests that need the user's own input, a wheel, a mouse drag or a pointer
|
|
2040
|
-
resting on something, get it
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2058
|
+
resting on something, get it from `.storybook/real-input.ts`: Vitest browser
|
|
2059
|
+
commands that drive Playwright's mouse, whose events are trusted. They run in
|
|
2060
|
+
Chromium and in WebKit, where pointer and scroll events differ: WebKit sends a
|
|
2061
|
+
pointermove when content scrolls under a resting pointer, and Chromium doesn't.
|
|
2062
|
+
A synthetic wheel or pointer event never scrolls anything, so "a vertical wheel
|
|
2063
|
+
scrolls the page, not the row" can't be tested without them. The commands fail
|
|
2064
|
+
loudly when the pointer isn't over their target, rather than letting a wheel
|
|
2065
|
+
land on the page and a test pass for the wrong reason. Storybook's own UI has
|
|
2066
|
+
no such input, so those steps are skipped there.
|
|
2048
2067
|
|
|
2049
2068
|
`src/lib/utils.test.ts` pins `cn`. `tailwind-merge` has to be configured with the
|
|
2050
2069
|
prefix or it stops recognising Roster's classes as utilities and silently
|
|
@@ -2073,9 +2092,9 @@ Output in `dist/`:
|
|
|
2073
2092
|
|
|
2074
2093
|
### What `meta.json` is for
|
|
2075
2094
|
|
|
2076
|
-
Consumers read this package to describe it.
|
|
2077
|
-
version from `package.json` and counts components by parsing the exports
|
|
2078
|
-
`dist/*.d.ts`, so both stay correct on their own.
|
|
2095
|
+
Consumers read this package to describe it. A portfolio site's case study takes
|
|
2096
|
+
the version from `package.json` and counts components by parsing the exports
|
|
2097
|
+
out of `dist/*.d.ts`, so both stay correct on their own.
|
|
2079
2098
|
|
|
2080
2099
|
The test count has no such source. `files` is `["dist"]`, so the suite never
|
|
2081
2100
|
leaves this repo, and the number on that page was a hand-typed literal that
|
|
@@ -65,7 +65,7 @@ const e = /* @__PURE__ */ r(
|
|
|
65
65
|
// Translucent rather than a solid tint step. A ghost button sits directly
|
|
66
66
|
// on the host's own background, and a solid `bg-*-50` silently disappears
|
|
67
67
|
// wherever that background happens to equal the step it names — which is
|
|
68
|
-
// exactly what happened to
|
|
68
|
+
// exactly what happened to one app, whose paper is the same value it
|
|
69
69
|
// maps `--roster-gray-100` to. An alpha wash darkens or lightens whatever
|
|
70
70
|
// is actually behind it, so it reads on any surface.
|
|
71
71
|
{ 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" },
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The small uppercase label that sits above a heading, beside a rule, or as a
|
|
3
|
-
* column head. Extracted from
|
|
4
|
-
* class and used 26 times before anyone noticed it was a component.
|
|
3
|
+
* column head. Extracted from a portfolio site, where it was hand-rolled as a
|
|
4
|
+
* CSS class and used 26 times before anyone noticed it was a component.
|
|
5
5
|
*
|
|
6
6
|
* Monospace on purpose: at this size, tracked-out uppercase reads as chrome
|
|
7
7
|
* rather than prose, which is the whole job.
|
|
@@ -49,7 +49,7 @@ const s = /* @__PURE__ */ r(
|
|
|
49
49
|
},
|
|
50
50
|
/* Deliberately the same three heights as Button: h-9 / h-10 / h-11.
|
|
51
51
|
Input was a fixed 42px, which agreed with Button at no size at all, so
|
|
52
|
-
a field beside a submit button never lined up.
|
|
52
|
+
a field beside a submit button never lined up. One app gave up and
|
|
53
53
|
kept a raw <input> pinned to h-11. */
|
|
54
54
|
size: {
|
|
55
55
|
sm: "rst:h-9 rst:px-3",
|
|
@@ -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"),d=require("react"),i=require("../../../lib/utils.cjs"),b={sm:"rst:text-xs",md:"rst:text-sm",lg:"rst:text-base",inherit:""},j={xs:"rst:h-6 rst:w-6",sm:"rst:h-8 rst:w-8",md:"rst:h-10 rst:w-10",lg:"rst:h-12 rst:w-12",xl:"rst:h-16 rst:w-16"},p={sm:"rst:rounded-sm",md:"rst:rounded-md",lg:"rst:rounded-lg",xl:"rst:rounded-xl",full:"rst:rounded-full"},v="rst:rounded-skeleton",y={shimmer:"rst:animate-skeleton rst:forced-colors:outline-solid rst:forced-colors:outline-1",pulse:"rst:animate-skeleton-pulse rst:forced-colors:outline-solid rst:forced-colors:outline-1 rst:forced-colors:animate-none",none:"rst:skeleton-fill rst:forced-colors:outline-solid rst:forced-colors:outline-1"},S=d.createContext(void 0);function C({shape:e="line",size:s,lines:a=1,width:r,height:h,radius:n,animation:x,className:o}){const f=d.useContext(S),l=y[x??f??"shimmer"];if(e==="circle"){const c=s&&s in j?s:"md";return t.jsx("span",{"aria-hidden":"true",className:i.cn("rst:block rst:shrink-0 rst:rounded-full rst:border rst:border-transparent",j[c],l,o),"data-skeleton":"circle"})}if(e==="block")return t.jsx("span",{"aria-hidden":"true",className:i.cn("rst:block rst:w-full",n?p[n]:v,l,o),style:{height:h??"8rem",width:r},"data-skeleton":"block"});const k=s&&s in b?s:"md",u=Math.max(1,Math.floor(a)),g=c=>{const m=c===u-1;return t.jsxs("span",{className:i.cn("rst:relative rst:block",u>1&&!m&&"rst:w-full"),style:{width:u>1?m?r??"60%":void 0:r},children:[" ",t.jsx("span",{className:i.cn("rst:absolute rst:inset-x-0 rst:top-1/2 rst:h-[0.7em] rst:-translate-y-1/2",p[n??"sm"],l)})]},c)};return t.jsx("span",{"aria-hidden":"true",className:i.cn("rst:block",b[k],o),"data-skeleton":"line",children:Array.from({length:u},(c,m)=>g(m))})}function I({loading:e,skeleton:s,label:a="Loading",announce:r=!0,animation:h,children:n,className:x}){const o=d.useContext(S),[f,l]=d.useState("");return d.useEffect(()=>{const k=setTimeout(()=>l(e&&r?a:""),e?50:0);return()=>clearTimeout(k)},[e,a,r]),t.jsxs(t.Fragment,{children:[t.jsx("span",{role:"status",className:"rst:sr-only","data-skeleton-status":"",children:f}),t.jsx("div",{"aria-busy":e||void 0,className:x,"data-skeleton-region":e?"loading":"ready",children:e?t.jsx(S.Provider,{value:h??o,children:t.jsx("div",{"aria-hidden":"true",children:s})}):n})]})}exports.Skeleton=C;exports.SkeletonRegion=I;
|
|
@@ -24,6 +24,8 @@ declare const RADIUS: {
|
|
|
24
24
|
readonly xl: "rst:rounded-xl";
|
|
25
25
|
readonly full: "rst:rounded-full";
|
|
26
26
|
};
|
|
27
|
+
/** How a skeleton moves while it waits. */
|
|
28
|
+
export type SkeletonAnimation = "shimmer" | "pulse" | "none";
|
|
27
29
|
export interface SkeletonProps {
|
|
28
30
|
/**
|
|
29
31
|
* - `"line"`: a line of text, one line box tall at its `size`.
|
|
@@ -42,8 +44,20 @@ export interface SkeletonProps {
|
|
|
42
44
|
width?: CSSProperties["width"];
|
|
43
45
|
/** A block's height. */
|
|
44
46
|
height?: CSSProperties["height"];
|
|
45
|
-
/**
|
|
47
|
+
/**
|
|
48
|
+
* A block's corners, from the radius scale. Without it a block reads
|
|
49
|
+
* `--roster-skeleton-radius`, which defaults to `lg`. A line's corners are
|
|
50
|
+
* `sm` unless this says otherwise; a circle is always round.
|
|
51
|
+
*/
|
|
46
52
|
radius?: keyof typeof RADIUS;
|
|
53
|
+
/**
|
|
54
|
+
* `"shimmer"` (the default): a highlight sweeps across the fill. `"pulse"`:
|
|
55
|
+
* the fill fades and returns, at `--roster-skeleton-pulse-duration` and down
|
|
56
|
+
* to `--roster-skeleton-pulse-opacity`. `"none"`: the fill holds still.
|
|
57
|
+
* Under reduced motion both movements stop. Inside a `SkeletonRegion`, it
|
|
58
|
+
* defaults to the region's.
|
|
59
|
+
*/
|
|
60
|
+
animation?: SkeletonAnimation;
|
|
47
61
|
className?: string;
|
|
48
62
|
}
|
|
49
63
|
/**
|
|
@@ -53,7 +67,7 @@ export interface SkeletonProps {
|
|
|
53
67
|
* isn't there yet. The region it stands in for says it's busy; use
|
|
54
68
|
* `SkeletonRegion`, which does that, or set `aria-busy` on it yourself.
|
|
55
69
|
*/
|
|
56
|
-
declare function Skeleton({ shape, size, lines, width, height, radius, className }: SkeletonProps): import("react/jsx-runtime").JSX.Element;
|
|
70
|
+
declare function Skeleton({ shape, size, lines, width, height, radius, animation, className }: SkeletonProps): import("react/jsx-runtime").JSX.Element;
|
|
57
71
|
export interface SkeletonRegionProps {
|
|
58
72
|
/** While true, the skeleton shows and the region says it's busy. */
|
|
59
73
|
loading: boolean;
|
|
@@ -66,6 +80,8 @@ export interface SkeletonRegionProps {
|
|
|
66
80
|
* together, a grid of cards say, or wrap them in one region instead.
|
|
67
81
|
*/
|
|
68
82
|
announce?: boolean;
|
|
83
|
+
/** How the skeletons inside move, unless one says otherwise: see `Skeleton`. */
|
|
84
|
+
animation?: SkeletonAnimation;
|
|
69
85
|
children?: ReactNode;
|
|
70
86
|
className?: string;
|
|
71
87
|
}
|
|
@@ -75,5 +91,5 @@ export interface SkeletonRegionProps {
|
|
|
75
91
|
* When `loading` turns false the content replaces the skeleton in the same
|
|
76
92
|
* box, so a skeleton drawn at the content's size means nothing moves.
|
|
77
93
|
*/
|
|
78
|
-
declare function SkeletonRegion({ loading, skeleton, label, announce, children, className }: SkeletonRegionProps): import("react/jsx-runtime").JSX.Element;
|
|
94
|
+
declare function SkeletonRegion({ loading, skeleton, label, announce, animation, children, className }: SkeletonRegionProps): import("react/jsx-runtime").JSX.Element;
|
|
79
95
|
export { Skeleton, SkeletonRegion };
|
|
@@ -1,80 +1,85 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx as
|
|
3
|
-
import {
|
|
4
|
-
import { cn as
|
|
5
|
-
const
|
|
2
|
+
import { jsx as e, jsxs as v, Fragment as g } from "react/jsx-runtime";
|
|
3
|
+
import { useContext as y, useState as w, useEffect as C, createContext as L } from "react";
|
|
4
|
+
import { cn as c } from "../../../lib/utils.js";
|
|
5
|
+
const p = {
|
|
6
6
|
sm: "rst:text-xs",
|
|
7
7
|
md: "rst:text-sm",
|
|
8
8
|
lg: "rst:text-base",
|
|
9
9
|
inherit: ""
|
|
10
|
-
},
|
|
10
|
+
}, b = {
|
|
11
11
|
xs: "rst:h-6 rst:w-6",
|
|
12
12
|
sm: "rst:h-8 rst:w-8",
|
|
13
13
|
md: "rst:h-10 rst:w-10",
|
|
14
14
|
lg: "rst:h-12 rst:w-12",
|
|
15
15
|
xl: "rst:h-16 rst:w-16"
|
|
16
|
-
},
|
|
16
|
+
}, S = {
|
|
17
17
|
sm: "rst:rounded-sm",
|
|
18
18
|
md: "rst:rounded-md",
|
|
19
19
|
lg: "rst:rounded-lg",
|
|
20
20
|
xl: "rst:rounded-xl",
|
|
21
21
|
full: "rst:rounded-full"
|
|
22
|
-
},
|
|
23
|
-
|
|
22
|
+
}, E = "rst:rounded-skeleton", N = {
|
|
23
|
+
shimmer: "rst:animate-skeleton rst:forced-colors:outline-solid rst:forced-colors:outline-1",
|
|
24
|
+
pulse: "rst:animate-skeleton-pulse rst:forced-colors:outline-solid rst:forced-colors:outline-1 rst:forced-colors:animate-none",
|
|
25
|
+
none: "rst:skeleton-fill rst:forced-colors:outline-solid rst:forced-colors:outline-1"
|
|
26
|
+
}, x = L(void 0);
|
|
27
|
+
function j({ shape: t = "line", size: r, lines: d = 1, width: s, height: m, radius: o, animation: h, className: n }) {
|
|
28
|
+
const f = y(x), l = N[h ?? f ?? "shimmer"];
|
|
24
29
|
if (t === "circle") {
|
|
25
|
-
const
|
|
26
|
-
return /* @__PURE__ */
|
|
30
|
+
const i = r && r in b ? r : "md";
|
|
31
|
+
return /* @__PURE__ */ e(
|
|
27
32
|
"span",
|
|
28
33
|
{
|
|
29
34
|
"aria-hidden": "true",
|
|
30
|
-
className:
|
|
35
|
+
className: c("rst:block rst:shrink-0 rst:rounded-full rst:border rst:border-transparent", b[i], l, n),
|
|
31
36
|
"data-skeleton": "circle"
|
|
32
37
|
}
|
|
33
38
|
);
|
|
34
39
|
}
|
|
35
40
|
if (t === "block")
|
|
36
|
-
return /* @__PURE__ */
|
|
41
|
+
return /* @__PURE__ */ e(
|
|
37
42
|
"span",
|
|
38
43
|
{
|
|
39
44
|
"aria-hidden": "true",
|
|
40
|
-
className:
|
|
41
|
-
style: { height:
|
|
45
|
+
className: c("rst:block rst:w-full", o ? S[o] : E, l, n),
|
|
46
|
+
style: { height: m ?? "8rem", width: s },
|
|
42
47
|
"data-skeleton": "block"
|
|
43
48
|
}
|
|
44
49
|
);
|
|
45
|
-
const
|
|
46
|
-
const
|
|
47
|
-
return /* @__PURE__ */
|
|
50
|
+
const k = r && r in p ? r : "md", a = Math.max(1, Math.floor(d)), I = (i) => {
|
|
51
|
+
const u = i === a - 1;
|
|
52
|
+
return /* @__PURE__ */ v(
|
|
48
53
|
"span",
|
|
49
54
|
{
|
|
50
|
-
className:
|
|
51
|
-
style: { width:
|
|
55
|
+
className: c("rst:relative rst:block", a > 1 && !u && "rst:w-full"),
|
|
56
|
+
style: { width: a > 1 ? u ? s ?? "60%" : void 0 : s },
|
|
52
57
|
children: [
|
|
53
58
|
" ",
|
|
54
|
-
/* @__PURE__ */
|
|
59
|
+
/* @__PURE__ */ e(
|
|
55
60
|
"span",
|
|
56
61
|
{
|
|
57
|
-
className:
|
|
62
|
+
className: c("rst:absolute rst:inset-x-0 rst:top-1/2 rst:h-[0.7em] rst:-translate-y-1/2", S[o ?? "sm"], l)
|
|
58
63
|
}
|
|
59
64
|
)
|
|
60
65
|
]
|
|
61
66
|
},
|
|
62
|
-
|
|
67
|
+
i
|
|
63
68
|
);
|
|
64
69
|
};
|
|
65
|
-
return /* @__PURE__ */
|
|
70
|
+
return /* @__PURE__ */ e("span", { "aria-hidden": "true", className: c("rst:block", p[k], n), "data-skeleton": "line", children: Array.from({ length: a }, (i, u) => I(u)) });
|
|
66
71
|
}
|
|
67
|
-
function
|
|
68
|
-
const [
|
|
69
|
-
return
|
|
70
|
-
const
|
|
71
|
-
return () => clearTimeout(
|
|
72
|
-
}, [t, d,
|
|
73
|
-
/* @__PURE__ */
|
|
74
|
-
/* @__PURE__ */
|
|
72
|
+
function D({ loading: t, skeleton: r, label: d = "Loading", announce: s = !0, animation: m, children: o, className: h }) {
|
|
73
|
+
const n = y(x), [f, l] = w("");
|
|
74
|
+
return C(() => {
|
|
75
|
+
const k = setTimeout(() => l(t && s ? d : ""), t ? 50 : 0);
|
|
76
|
+
return () => clearTimeout(k);
|
|
77
|
+
}, [t, d, s]), /* @__PURE__ */ v(g, { children: [
|
|
78
|
+
/* @__PURE__ */ e("span", { role: "status", className: "rst:sr-only", "data-skeleton-status": "", children: f }),
|
|
79
|
+
/* @__PURE__ */ e("div", { "aria-busy": t || void 0, className: h, "data-skeleton-region": t ? "loading" : "ready", children: t ? /* @__PURE__ */ e(x.Provider, { value: m ?? n, children: /* @__PURE__ */ e("div", { "aria-hidden": "true", children: r }) }) : o })
|
|
75
80
|
] });
|
|
76
81
|
}
|
|
77
82
|
export {
|
|
78
|
-
|
|
79
|
-
|
|
83
|
+
j as Skeleton,
|
|
84
|
+
D as SkeletonRegion
|
|
80
85
|
};
|
|
@@ -13,7 +13,7 @@ export interface ThemeToggleProps extends Omit<ButtonProps, "onClick" | "childre
|
|
|
13
13
|
* opposite, because a button's name should say what pressing it does.
|
|
14
14
|
*
|
|
15
15
|
* Both take nodes, so a product with its own vocabulary for the two states
|
|
16
|
-
* ("
|
|
16
|
+
* ("Paper" / "Chalkboard", "Day" / "Night") can say so.
|
|
17
17
|
*/
|
|
18
18
|
lightLabel?: React.ReactNode;
|
|
19
19
|
/** Visible text when the page is dark, if `showLabel` is set. */
|
|
@@ -45,7 +45,7 @@ export interface CheckboxGroupProps extends Omit<React.HTMLAttributes<HTMLFieldS
|
|
|
45
45
|
* Caps the options' height and scrolls past it. A number is pixels.
|
|
46
46
|
*
|
|
47
47
|
* Applied inline rather than as a class because the useful values here are
|
|
48
|
-
* arbitrary — `240` is
|
|
48
|
+
* arbitrary — `240` is one app's, yours will differ — and an arbitrary
|
|
49
49
|
* Tailwind value built from a prop is a class that does not exist at build
|
|
50
50
|
* time, which is exactly what `check-classes-emit` fails the build over.
|
|
51
51
|
*/
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* short list of three options wants to sit on the form the way a Select's
|
|
6
6
|
* label and trigger do, with no chrome of its own.
|
|
7
7
|
*
|
|
8
|
-
* `panel` is the long-list case — the grouped, scrollable list
|
|
8
|
+
* `panel` is the long-list case — the grouped, scrollable list one app
|
|
9
9
|
* hand-rolled for its sports picker. It deliberately does NOT read
|
|
10
10
|
* `--roster-popover-*`: that family is documented as "a panel that floats over
|
|
11
11
|
* the page", and this one is in the flow.
|
|
@@ -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"),c=require("../../../lib/utils.cjs"),j=require("../../atoms/Card/Card.cjs"),S=require("../../atoms/Eyebrow/Eyebrow.cjs"),d=require("../../atoms/Stat/stat-variants.cjs"),u=require("../../organisms/Table/Table.cjs"),s=require("../../atoms/Skeleton/Skeleton.cjs");function k({media:a,lines:n=3,variant:r,padding:t,animation:i,className:l}){return e.jsxs(j.Card,{variant:r,padding:t,className:l,"aria-hidden":"true","data-skeleton":"card",children:[a!==void 0&&e.jsx(s.Skeleton,{shape:"block",height:a,animation:i,className:"rst:mb-4"}),e.jsx(s.Skeleton,{size:"lg",width:"45%",animation:i}),n>0&&e.jsx(s.Skeleton,{size:"md",lines:n,animation:i,className:"rst:mt-2"})]})}function m({columns:a,animation:n,className:r}){const t=["70%","50%","60%","40%"];return e.jsx(u.TableRow,{"aria-hidden":"true",className:r,"data-skeleton":"table-row",children:Array.from({length:Math.max(1,a)},(i,l)=>e.jsx(u.TableCell,{children:e.jsx(s.Skeleton,{size:"inherit",width:t[l%t.length],animation:n})},l))})}function w({size:a="md",withName:n=!1,animation:r,className:t}){return n?e.jsxs("span",{"aria-hidden":"true",className:c.cn("rst:flex rst:items-center rst:gap-3",t),"data-skeleton":"avatar",children:[e.jsx(s.Skeleton,{shape:"circle",size:a,animation:r}),e.jsx(s.Skeleton,{size:"md",width:"8rem",animation:r})]}):e.jsx(s.Skeleton,{shape:"circle",size:a,animation:r,className:t})}function p({size:a="md",semantics:n="definition",source:r=!1,animation:t,className:i}){const l=d.statValueVariants({size:a,colorScheme:"neutral"}),o=e.jsx(s.Skeleton,{size:"inherit",width:"2.5em",animation:t}),h=e.jsx(S.Eyebrow,{size:"xs",children:e.jsx(s.Skeleton,{size:"inherit",width:"9em",animation:t})}),x=e.jsx("span",{className:d.statSourceClass,children:e.jsx(s.Skeleton,{size:"inherit",width:"12em",animation:t})});return n==="standalone"?e.jsxs("span",{"aria-hidden":"true",className:c.cn("rst:flex rst:flex-col rst:gap-[3px]",i),"data-skeleton":"stat",children:[e.jsx("span",{className:l,children:o}),h,r&&x]}):e.jsxs("div",{"aria-hidden":"true",className:c.cn("rst:grid rst:content-start rst:gap-[3px]",i),"data-skeleton":"stat",children:[e.jsx("dt",{className:"rst:relative rst:col-start-1 rst:row-start-2 rst:flex",children:h}),r?e.jsxs("dd",{className:c.cn("rst:m-0",l,"rst:col-start-1 rst:row-span-3 rst:row-start-1 rst:grid rst:grid-rows-subgrid"),children:[e.jsx("span",{className:"rst:row-start-1",children:o}),e.jsx("span",{className:c.cn(d.statSourceClass,"rst:row-start-3"),children:e.jsx(s.Skeleton,{size:"inherit",width:"12em",animation:t})})]}):e.jsx("dd",{className:c.cn("rst:m-0 rst:col-start-1 rst:row-start-1",l),children:o})]})}exports.SkeletonAvatar=w;exports.SkeletonCard=k;exports.SkeletonStat=p;exports.SkeletonTableRow=m;
|
|
@@ -1,20 +1,25 @@
|
|
|
1
1
|
import { CSSProperties } from 'react';
|
|
2
2
|
import { CardProps } from '../../atoms/Card/Card';
|
|
3
|
+
import { SkeletonAnimation } from '../../atoms/Skeleton/Skeleton';
|
|
3
4
|
export interface SkeletonCardProps extends Pick<CardProps, "variant" | "padding"> {
|
|
4
5
|
/** A media block above the text, at this height (an image, a chart). */
|
|
5
6
|
media?: CSSProperties["height"];
|
|
6
7
|
/** Body lines under the title. */
|
|
7
8
|
lines?: number;
|
|
9
|
+
/** How its skeletons move: see `Skeleton`. Inside a `SkeletonRegion`, the region's. */
|
|
10
|
+
animation?: SkeletonAnimation;
|
|
8
11
|
className?: string;
|
|
9
12
|
}
|
|
10
13
|
/**
|
|
11
14
|
* A Card loading. Stands in for a Card holding an optional media block (with
|
|
12
15
|
* 16px below it), a `text-base` title, and `text-sm` body lines 8px under it.
|
|
13
16
|
*/
|
|
14
|
-
declare function SkeletonCard({ media, lines, variant, padding, className }: SkeletonCardProps): import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
declare function SkeletonCard({ media, lines, variant, padding, animation, className }: SkeletonCardProps): import("react/jsx-runtime").JSX.Element;
|
|
15
18
|
export interface SkeletonTableRowProps {
|
|
16
19
|
/** How many cells. */
|
|
17
20
|
columns: number;
|
|
21
|
+
/** How its skeletons move: see `Skeleton`. Inside a `SkeletonRegion`, the region's. */
|
|
22
|
+
animation?: SkeletonAnimation;
|
|
18
23
|
className?: string;
|
|
19
24
|
}
|
|
20
25
|
/**
|
|
@@ -22,16 +27,18 @@ export interface SkeletonTableRowProps {
|
|
|
22
27
|
* size, each holding one line in the cell's text size. Stands in for a row of
|
|
23
28
|
* one-line cells.
|
|
24
29
|
*/
|
|
25
|
-
declare function SkeletonTableRow({ columns, className }: SkeletonTableRowProps): import("react/jsx-runtime").JSX.Element;
|
|
30
|
+
declare function SkeletonTableRow({ columns, animation, className }: SkeletonTableRowProps): import("react/jsx-runtime").JSX.Element;
|
|
26
31
|
export interface SkeletonAvatarProps {
|
|
27
32
|
/** Avatar's sizes. */
|
|
28
33
|
size?: "xs" | "sm" | "md" | "lg" | "xl";
|
|
29
34
|
/** A name line beside it, in `text-sm`. */
|
|
30
35
|
withName?: boolean;
|
|
36
|
+
/** How its skeletons move: see `Skeleton`. Inside a `SkeletonRegion`, the region's. */
|
|
37
|
+
animation?: SkeletonAnimation;
|
|
31
38
|
className?: string;
|
|
32
39
|
}
|
|
33
40
|
/** An Avatar loading, and optionally the name beside it. */
|
|
34
|
-
declare function SkeletonAvatar({ size, withName, className }: SkeletonAvatarProps): import("react/jsx-runtime").JSX.Element;
|
|
41
|
+
declare function SkeletonAvatar({ size, withName, animation, className }: SkeletonAvatarProps): import("react/jsx-runtime").JSX.Element;
|
|
35
42
|
export interface SkeletonStatProps {
|
|
36
43
|
/** Stat's sizes. */
|
|
37
44
|
size?: "sm" | "md" | "lg";
|
|
@@ -43,6 +50,8 @@ export interface SkeletonStatProps {
|
|
|
43
50
|
semantics?: "definition" | "standalone";
|
|
44
51
|
/** A source line under the figure, as a Stat with `source` has. */
|
|
45
52
|
source?: boolean;
|
|
53
|
+
/** How its skeletons move: see `Skeleton`. Inside a `SkeletonRegion`, the region's. */
|
|
54
|
+
animation?: SkeletonAnimation;
|
|
46
55
|
className?: string;
|
|
47
56
|
}
|
|
48
57
|
/**
|
|
@@ -51,5 +60,5 @@ export interface SkeletonStatProps {
|
|
|
51
60
|
* the label is the real Eyebrow, a flex item where Stat's is, so it makes the
|
|
52
61
|
* same line.
|
|
53
62
|
*/
|
|
54
|
-
declare function SkeletonStat({ size, semantics, source, className }: SkeletonStatProps): import("react/jsx-runtime").JSX.Element;
|
|
63
|
+
declare function SkeletonStat({ size, semantics, source, animation, className }: SkeletonStatProps): import("react/jsx-runtime").JSX.Element;
|
|
55
64
|
export { SkeletonCard, SkeletonTableRow, SkeletonAvatar, SkeletonStat };
|
|
@@ -1,45 +1,45 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as t, jsxs as o } from "react/jsx-runtime";
|
|
3
|
-
import { cn as
|
|
4
|
-
import { Card as
|
|
5
|
-
import { Eyebrow as
|
|
6
|
-
import { statValueVariants as
|
|
7
|
-
import { TableRow as
|
|
8
|
-
import { Skeleton as
|
|
9
|
-
function
|
|
10
|
-
return /* @__PURE__ */ o(
|
|
11
|
-
|
|
12
|
-
/* @__PURE__ */ t(
|
|
13
|
-
|
|
3
|
+
import { cn as d } from "../../../lib/utils.js";
|
|
4
|
+
import { Card as u } from "../../atoms/Card/Card.js";
|
|
5
|
+
import { Eyebrow as f } from "../../atoms/Eyebrow/Eyebrow.js";
|
|
6
|
+
import { statValueVariants as w, statSourceClass as m } from "../../atoms/Stat/stat-variants.js";
|
|
7
|
+
import { TableRow as g, TableCell as k } from "../../organisms/Table/Table.js";
|
|
8
|
+
import { Skeleton as e } from "../../atoms/Skeleton/Skeleton.js";
|
|
9
|
+
function T({ media: a, lines: l = 3, variant: s, padding: r, animation: n, className: i }) {
|
|
10
|
+
return /* @__PURE__ */ o(u, { variant: s, padding: r, className: i, "aria-hidden": "true", "data-skeleton": "card", children: [
|
|
11
|
+
a !== void 0 && /* @__PURE__ */ t(e, { shape: "block", height: a, animation: n, className: "rst:mb-4" }),
|
|
12
|
+
/* @__PURE__ */ t(e, { size: "lg", width: "45%", animation: n }),
|
|
13
|
+
l > 0 && /* @__PURE__ */ t(e, { size: "md", lines: l, animation: n, className: "rst:mt-2" })
|
|
14
14
|
] });
|
|
15
15
|
}
|
|
16
|
-
function
|
|
17
|
-
const
|
|
18
|
-
return /* @__PURE__ */ t(
|
|
16
|
+
function j({ columns: a, animation: l, className: s }) {
|
|
17
|
+
const r = ["70%", "50%", "60%", "40%"];
|
|
18
|
+
return /* @__PURE__ */ t(g, { "aria-hidden": "true", className: s, "data-skeleton": "table-row", children: Array.from({ length: Math.max(1, a) }, (n, i) => /* @__PURE__ */ t(k, { children: /* @__PURE__ */ t(e, { size: "inherit", width: r[i % r.length], animation: l }) }, i)) });
|
|
19
19
|
}
|
|
20
|
-
function
|
|
21
|
-
return
|
|
22
|
-
/* @__PURE__ */ t(
|
|
23
|
-
/* @__PURE__ */ t(
|
|
24
|
-
] }) : /* @__PURE__ */ t(
|
|
20
|
+
function y({ size: a = "md", withName: l = !1, animation: s, className: r }) {
|
|
21
|
+
return l ? /* @__PURE__ */ o("span", { "aria-hidden": "true", className: d("rst:flex rst:items-center rst:gap-3", r), "data-skeleton": "avatar", children: [
|
|
22
|
+
/* @__PURE__ */ t(e, { shape: "circle", size: a, animation: s }),
|
|
23
|
+
/* @__PURE__ */ t(e, { size: "md", width: "8rem", animation: s })
|
|
24
|
+
] }) : /* @__PURE__ */ t(e, { shape: "circle", size: a, animation: s, className: r });
|
|
25
25
|
}
|
|
26
|
-
function
|
|
27
|
-
const i =
|
|
28
|
-
return
|
|
29
|
-
/* @__PURE__ */ t("span", { className: i, children:
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
] }) : /* @__PURE__ */ o("div", { "aria-hidden": "true", className:
|
|
33
|
-
/* @__PURE__ */ t("dt", { className: "rst:relative rst:col-start-1 rst:row-start-2 rst:flex", children:
|
|
34
|
-
|
|
35
|
-
/* @__PURE__ */ t("span", { className: "rst:row-start-1", children:
|
|
36
|
-
/* @__PURE__ */ t("span", { className:
|
|
37
|
-
] }) : /* @__PURE__ */ t("dd", { className:
|
|
26
|
+
function A({ size: a = "md", semantics: l = "definition", source: s = !1, animation: r, className: n }) {
|
|
27
|
+
const i = w({ size: a, colorScheme: "neutral" }), c = /* @__PURE__ */ t(e, { size: "inherit", width: "2.5em", animation: r }), h = /* @__PURE__ */ t(f, { size: "xs", children: /* @__PURE__ */ t(e, { size: "inherit", width: "9em", animation: r }) }), p = /* @__PURE__ */ t("span", { className: m, children: /* @__PURE__ */ t(e, { size: "inherit", width: "12em", animation: r }) });
|
|
28
|
+
return l === "standalone" ? /* @__PURE__ */ o("span", { "aria-hidden": "true", className: d("rst:flex rst:flex-col rst:gap-[3px]", n), "data-skeleton": "stat", children: [
|
|
29
|
+
/* @__PURE__ */ t("span", { className: i, children: c }),
|
|
30
|
+
h,
|
|
31
|
+
s && p
|
|
32
|
+
] }) : /* @__PURE__ */ o("div", { "aria-hidden": "true", className: d("rst:grid rst:content-start rst:gap-[3px]", n), "data-skeleton": "stat", children: [
|
|
33
|
+
/* @__PURE__ */ t("dt", { className: "rst:relative rst:col-start-1 rst:row-start-2 rst:flex", children: h }),
|
|
34
|
+
s ? /* @__PURE__ */ o("dd", { className: d("rst:m-0", i, "rst:col-start-1 rst:row-span-3 rst:row-start-1 rst:grid rst:grid-rows-subgrid"), children: [
|
|
35
|
+
/* @__PURE__ */ t("span", { className: "rst:row-start-1", children: c }),
|
|
36
|
+
/* @__PURE__ */ t("span", { className: d(m, "rst:row-start-3"), children: /* @__PURE__ */ t(e, { size: "inherit", width: "12em", animation: r }) })
|
|
37
|
+
] }) : /* @__PURE__ */ t("dd", { className: d("rst:m-0 rst:col-start-1 rst:row-start-1", i), children: c })
|
|
38
38
|
] });
|
|
39
39
|
}
|
|
40
40
|
export {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
y as SkeletonAvatar,
|
|
42
|
+
T as SkeletonCard,
|
|
43
|
+
A as SkeletonStat,
|
|
44
|
+
j as SkeletonTableRow
|
|
45
45
|
};
|
|
@@ -21,7 +21,7 @@ export interface ToasterProps extends Pick<HotToasterProps, "position" | "gutter
|
|
|
21
21
|
* already depend on it at the same version and already write
|
|
22
22
|
* `toast.success(...)`. Wrapping means their call sites do not move; what
|
|
23
23
|
* changes is that the toast stops being styled with hardcoded hex in each app
|
|
24
|
-
* —
|
|
24
|
+
* — one app pinned `#1a1f2e` and `#10b981`, the other `#413f3c` and
|
|
25
25
|
* `#f3eee3`, neither of which is in either app's palette any more.
|
|
26
26
|
*
|
|
27
27
|
* The `children` render prop is used rather than `toastOptions`, so the body
|