@charcuterie/ui 2.0.0 → 2.1.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.
@@ -1,7 +1,13 @@
1
1
  import type { ReactNode } from "react";
2
2
  export type DialogSize = "full" | "lg" | "md" | "sm" | "xl";
3
3
  export type DialogProps = {
4
- children: ReactNode;
4
+ /**
5
+ * The scrolling body. Optional: a confirm dialog whose question is
6
+ * its `heading` and whose answers are its `footer` has no body, and
7
+ * the old chrome `Modal` (which extended `<dialog>`'s DOM props)
8
+ * allowed that — `Dialog` keeps it.
9
+ */
10
+ children?: ReactNode;
5
11
  className?: string;
6
12
  /** The footer row. Buttons, usually. */
7
13
  footer?: ReactNode;
@@ -1 +1 @@
1
- {"version":3,"file":"Dialog.d.ts","sourceRoot":"","sources":["../../src/Dialog/Dialog.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAMtC,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;AAE3D,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,EAAE,SAAS,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,wCAAwC;IACxC,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IACxB;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,SAAS,EAAE,OAAO,CAAA;IAClB;;;OAGG;IACH,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,IAAI,CAAC,EAAE,UAAU,CAAA;CAClB,CAAA;AAqBD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,MAAM,GAAI,kGAUpB,WAAW,KAAG,SA4ChB,CAAA"}
1
+ {"version":3,"file":"Dialog.d.ts","sourceRoot":"","sources":["../../src/Dialog/Dialog.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAMtC,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;AAE3D,MAAM,MAAM,WAAW,GAAG;IACxB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,wCAAwC;IACxC,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IACxB;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,SAAS,EAAE,OAAO,CAAA;IAClB;;;OAGG;IACH,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,IAAI,CAAC,EAAE,UAAU,CAAA;CAClB,CAAA;AAqBD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,MAAM,GAAI,kGAUpB,WAAW,KAAG,SA4ChB,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"Dialog.js","sourceRoot":"","sources":["../../src/Dialog/Dialog.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAGhD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAsB,CAAA;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAoB,CAAA;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAyB/C;;;;GAIG;AACH,MAAM,UAAU,GAA+B;IAC7C,EAAE,EAAE,+BAA+B;IACnC,EAAE,EAAE,+BAA+B;IACnC,EAAE,EAAE,gCAAgC;IACpC,iEAAiE;IACjE,8DAA8D;IAC9D,6DAA6D;IAC7D,kEAAkE;IAClE,+DAA+D;IAC/D,+DAA+D;IAC/D,EAAE,EAAE,gCAAgC;IACpC,IAAI,EAAE,0DAA0D;CACjE,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,EACrB,QAAQ,EACR,SAAS,EACT,MAAM,EACN,OAAO,EACP,YAAY,GAAG,CAAC,EAChB,aAAa,GAAG,IAAI,EACpB,SAAS,EACT,OAAO,EACP,IAAI,GAAG,IAAI,GACC,EAAa,EAAE;IAC3B,MAAM,SAAS,GAAG,WAAW,EAAE,CAAA;IAE/B,MAAM,OAAO,GAAG,IAAI,YAAY,EAAW,CAAA;IAE3C,OAAO,CACL,MAAC,KAAK,uBACa,SAAS,EAC1B,SAAS,EAAE,WAAW,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,EACnD,aAAa,EAAE,aAAa,EAC5B,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,OAAO,aAEhB,kBAAQ,SAAS,EAAC,mFAAmF,aACnG,KAAC,OAAO,IACN,SAAS,EAAC,qCAAqC,EAC/C,EAAE,EAAE,SAAS,YAEZ,OAAO,GACA,EAET,aAAa,CAAC,CAAC,CAAC,CACf,KAAC,MAAM,IACL,UAAU,EAAC,OAAO,EAClB,MAAM,EAAC,SAAS,EAChB,OAAO,EAAE,OAAO,EAChB,IAAI,EAAC,IAAI,sBAGF,CACV,CAAC,CAAC,CAAC,IAAI,IACD,EAET,cAAK,SAAS,EAAC,kCAAkC,YAC9C,QAAQ,GACL,EAEL,MAAM,CAAC,CAAC,CAAC,CACR,iBAAQ,SAAS,EAAC,6EAA6E,YAC5F,MAAM,GACA,CACV,CAAC,CAAC,CAAC,IAAI,IACF,CACT,CAAA;AACH,CAAC,CAAA"}
1
+ {"version":3,"file":"Dialog.js","sourceRoot":"","sources":["../../src/Dialog/Dialog.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAGhD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAsB,CAAA;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAoB,CAAA;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AA+B/C;;;;GAIG;AACH,MAAM,UAAU,GAA+B;IAC7C,EAAE,EAAE,+BAA+B;IACnC,EAAE,EAAE,+BAA+B;IACnC,EAAE,EAAE,gCAAgC;IACpC,iEAAiE;IACjE,8DAA8D;IAC9D,6DAA6D;IAC7D,kEAAkE;IAClE,+DAA+D;IAC/D,+DAA+D;IAC/D,EAAE,EAAE,gCAAgC;IACpC,IAAI,EAAE,0DAA0D;CACjE,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,EACrB,QAAQ,EACR,SAAS,EACT,MAAM,EACN,OAAO,EACP,YAAY,GAAG,CAAC,EAChB,aAAa,GAAG,IAAI,EACpB,SAAS,EACT,OAAO,EACP,IAAI,GAAG,IAAI,GACC,EAAa,EAAE;IAC3B,MAAM,SAAS,GAAG,WAAW,EAAE,CAAA;IAE/B,MAAM,OAAO,GAAG,IAAI,YAAY,EAAW,CAAA;IAE3C,OAAO,CACL,MAAC,KAAK,uBACa,SAAS,EAC1B,SAAS,EAAE,WAAW,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,EACnD,aAAa,EAAE,aAAa,EAC5B,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,OAAO,aAEhB,kBAAQ,SAAS,EAAC,mFAAmF,aACnG,KAAC,OAAO,IACN,SAAS,EAAC,qCAAqC,EAC/C,EAAE,EAAE,SAAS,YAEZ,OAAO,GACA,EAET,aAAa,CAAC,CAAC,CAAC,CACf,KAAC,MAAM,IACL,UAAU,EAAC,OAAO,EAClB,MAAM,EAAC,SAAS,EAChB,OAAO,EAAE,OAAO,EAChB,IAAI,EAAC,IAAI,sBAGF,CACV,CAAC,CAAC,CAAC,IAAI,IACD,EAET,cAAK,SAAS,EAAC,kCAAkC,YAC9C,QAAQ,GACL,EAEL,MAAM,CAAC,CAAC,CAAC,CACR,iBAAQ,SAAS,EAAC,6EAA6E,YAC5F,MAAM,GACA,CACV,CAAC,CAAC,CAAC,IAAI,IACF,CACT,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,83 @@
1
+ import type { ComponentPropsWithRef, ReactNode } from "react";
2
+ export type SwatchAppearance = "outline" | "solid";
3
+ export type SwatchSize = keyof typeof SWATCH_SIZE_CLASS;
4
+ export type SwatchProps = Omit<ComponentPropsWithRef<"span">, "children" | "color"> & {
5
+ /**
6
+ * `outline` keeps the hue and drops the fill — for a swatch whose
7
+ * subject is present but inactive. It is the one visual state a
8
+ * status colour cannot borrow from `intent`, because the colour is
9
+ * not an intent.
10
+ */
11
+ appearance?: SwatchAppearance;
12
+ /**
13
+ * Any CSS colour, and this is the whole reason the component
14
+ * exists: it is a **value from data** — a physical sticker, an
15
+ * album's extracted accent, a user-chosen tag — not a token. A
16
+ * design system owns `intent.danger`; it does not own the colour
17
+ * of the dot somebody stuck on a game controller, and re-theming
18
+ * that would be re-theming the hardware. So it is a prop and lands
19
+ * in an inline `style`, the one sanctioned escape hatch for a
20
+ * runtime value.
21
+ */
22
+ color: string;
23
+ isLabelVisible?: boolean;
24
+ /**
25
+ * Required, and it is the point. A colour is not a name: a screen
26
+ * reader gets nothing at all from a `background-color`, and
27
+ * `getByRole("img", { name })` — the query an agent writes — has
28
+ * nothing to match. So the type asks for the name and there is no
29
+ * way to render the component without one.
30
+ */
31
+ label: string;
32
+ size?: SwatchSize;
33
+ };
34
+ /**
35
+ * The scale is the component's own, and deliberately larger than
36
+ * `DOT_SIZE_CLASS`.
37
+ *
38
+ * That map tops out at 10px, which is right for a status dot beside
39
+ * a line of text and far too small for a swatch that is the primary
40
+ * way a user tells one row from another across a room. A swatch is
41
+ * content, not punctuation.
42
+ */
43
+ declare const SWATCH_SIZE_CLASS: {
44
+ readonly sm: "size-4";
45
+ readonly md: "size-6";
46
+ readonly lg: "size-9";
47
+ };
48
+ /**
49
+ * A colour presented **as content**, with a name attached.
50
+ *
51
+ * It is not `LiveStatusIndicator`'s dot and not a `Badge`. Both of
52
+ * those take an `intent`, because both show a *state* whose colour
53
+ * the design system owns and can name in English. This shows a
54
+ * colour the system does **not** own and **cannot** name — the red
55
+ * sticker on a controller, red because someone put a red sticker on
56
+ * it; the accent castkit pulls off an album; a user's tag colour.
57
+ * `DOT_SIZE_CLASS` is exported precisely so an app can hand-roll one
58
+ * of these, and three of them across the fleet did, each without a
59
+ * name a screen reader could read.
60
+ *
61
+ * ### `role="img"`, and the name is required
62
+ *
63
+ * A swatch is a graphic that carries meaning, so it is an image with
64
+ * an accessible name — which makes it findable by
65
+ * `getByRole("img", { name })` in **both** the dot-only and
66
+ * labelled forms, one stable handle regardless of whether the text
67
+ * is on screen. The dot and any visible label are inside it and go
68
+ * `aria-hidden` by virtue of the name on the wrapper, exactly as an
69
+ * inline SVG with a caption would.
70
+ *
71
+ * ### The ring is not a token
72
+ *
73
+ * `solid` sits a translucent white ring inside the fill so a white
74
+ * or near-white swatch stays visible against `surface-raised` in
75
+ * both schemes; a hairline border alone disappears on one of the
76
+ * two. `outline` drops the fill to a faint tint of the same hue and
77
+ * draws the ring in the colour itself — via an inline `box-shadow`,
78
+ * because the ring colour has to come from the data and
79
+ * `--tw-ring-color` is not something `CSSProperties` will type.
80
+ */
81
+ export declare const Swatch: ({ appearance, className, color, isLabelVisible, label, size, ...spanProps }: SwatchProps) => ReactNode;
82
+ export {};
83
+ //# sourceMappingURL=Swatch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Swatch.d.ts","sourceRoot":"","sources":["../../src/Swatch/Swatch.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,qBAAqB,EACrB,SAAS,EACV,MAAM,OAAO,CAAA;AAId,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,OAAO,CAAA;AAElD,MAAM,MAAM,UAAU,GAAG,MAAM,OAAO,iBAAiB,CAAA;AAEvD,MAAM,MAAM,WAAW,GAAG,IAAI,CAC5B,qBAAqB,CAAC,MAAM,CAAC,EAC7B,UAAU,GAAG,OAAO,CACrB,GAAG;IACF;;;;;OAKG;IACH,UAAU,CAAC,EAAE,gBAAgB,CAAA;IAC7B;;;;;;;;;OASG;IACH,KAAK,EAAE,MAAM,CAAA;IACb,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB;;;;;;OAMG;IACH,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,UAAU,CAAA;CAClB,CAAA;AAED;;;;;;;;GAQG;AACH,QAAA,MAAM,iBAAiB;;;;CAIb,CAAA;AAEV;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,eAAO,MAAM,MAAM,GAAI,6EAQpB,WAAW,KAAG,SAqChB,CAAA"}
@@ -0,0 +1,57 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { toClassName } from "../toClassName.js";
3
+ /**
4
+ * The scale is the component's own, and deliberately larger than
5
+ * `DOT_SIZE_CLASS`.
6
+ *
7
+ * That map tops out at 10px, which is right for a status dot beside
8
+ * a line of text and far too small for a swatch that is the primary
9
+ * way a user tells one row from another across a room. A swatch is
10
+ * content, not punctuation.
11
+ */
12
+ const SWATCH_SIZE_CLASS = {
13
+ sm: "size-4",
14
+ md: "size-6",
15
+ lg: "size-9",
16
+ };
17
+ /**
18
+ * A colour presented **as content**, with a name attached.
19
+ *
20
+ * It is not `LiveStatusIndicator`'s dot and not a `Badge`. Both of
21
+ * those take an `intent`, because both show a *state* whose colour
22
+ * the design system owns and can name in English. This shows a
23
+ * colour the system does **not** own and **cannot** name — the red
24
+ * sticker on a controller, red because someone put a red sticker on
25
+ * it; the accent castkit pulls off an album; a user's tag colour.
26
+ * `DOT_SIZE_CLASS` is exported precisely so an app can hand-roll one
27
+ * of these, and three of them across the fleet did, each without a
28
+ * name a screen reader could read.
29
+ *
30
+ * ### `role="img"`, and the name is required
31
+ *
32
+ * A swatch is a graphic that carries meaning, so it is an image with
33
+ * an accessible name — which makes it findable by
34
+ * `getByRole("img", { name })` in **both** the dot-only and
35
+ * labelled forms, one stable handle regardless of whether the text
36
+ * is on screen. The dot and any visible label are inside it and go
37
+ * `aria-hidden` by virtue of the name on the wrapper, exactly as an
38
+ * inline SVG with a caption would.
39
+ *
40
+ * ### The ring is not a token
41
+ *
42
+ * `solid` sits a translucent white ring inside the fill so a white
43
+ * or near-white swatch stays visible against `surface-raised` in
44
+ * both schemes; a hairline border alone disappears on one of the
45
+ * two. `outline` drops the fill to a faint tint of the same hue and
46
+ * draws the ring in the colour itself — via an inline `box-shadow`,
47
+ * because the ring colour has to come from the data and
48
+ * `--tw-ring-color` is not something `CSSProperties` will type.
49
+ */
50
+ export const Swatch = ({ appearance = "solid", className, color, isLabelVisible = false, label, size = "md", ...spanProps }) => (_jsxs("span", { ...spanProps, "aria-label": label, className: toClassName("inline-flex items-center gap-2 align-middle", className), role: "img", children: [_jsx("span", { "aria-hidden": "true", className: toClassName("inline-block shrink-0 rounded-full", SWATCH_SIZE_CLASS[size], appearance === "solid" &&
51
+ "shadow-low ring-2 ring-white/25 ring-inset"), style: appearance === "solid"
52
+ ? { backgroundColor: color }
53
+ : {
54
+ backgroundColor: `color-mix(in srgb, ${color} 12%, transparent)`,
55
+ boxShadow: `inset 0 0 0 3px ${color}`,
56
+ } }), isLabelVisible ? (_jsx("span", { "aria-hidden": "true", className: "text-content-primary text-sm", children: label })) : null] }));
57
+ //# sourceMappingURL=Swatch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Swatch.js","sourceRoot":"","sources":["../../src/Swatch/Swatch.tsx"],"names":[],"mappings":";AAKA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAwC/C;;;;;;;;GAQG;AACH,MAAM,iBAAiB,GAAG;IACxB,EAAE,EAAE,QAAQ;IACZ,EAAE,EAAE,QAAQ;IACZ,EAAE,EAAE,QAAQ;CACJ,CAAA;AAEV;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,EACrB,UAAU,GAAG,OAAO,EACpB,SAAS,EACT,KAAK,EACL,cAAc,GAAG,KAAK,EACtB,KAAK,EACL,IAAI,GAAG,IAAI,EACX,GAAG,SAAS,EACA,EAAa,EAAE,CAAC,CAC5B,mBACM,SAAS,gBACD,KAAK,EACjB,SAAS,EAAE,WAAW,CACpB,6CAA6C,EAC7C,SAAS,CACV,EACD,IAAI,EAAC,KAAK,aAEV,8BACc,MAAM,EAClB,SAAS,EAAE,WAAW,CACpB,oCAAoC,EACpC,iBAAiB,CAAC,IAAI,CAAC,EACvB,UAAU,KAAK,OAAO;gBACpB,4CAA4C,CAC/C,EACD,KAAK,EACH,UAAU,KAAK,OAAO;gBACpB,CAAC,CAAC,EAAE,eAAe,EAAE,KAAK,EAAE;gBAC5B,CAAC,CAAC;oBACE,eAAe,EAAE,sBAAsB,KAAK,oBAAoB;oBAChE,SAAS,EAAE,mBAAmB,KAAK,EAAE;iBACtC,GAEP,EAED,cAAc,CAAC,CAAC,CAAC,CAChB,8BACc,MAAM,EAClB,SAAS,EAAC,8BAA8B,YAEvC,KAAK,GACD,CACR,CAAC,CAAC,CAAC,IAAI,IACH,CACR,CAAA"}
package/dist/index.d.ts CHANGED
@@ -94,6 +94,8 @@ export type { SortableTableHeaderProps, SortDirection, } from "./SortableTableHe
94
94
  export { SortableTableHeader } from "./SortableTableHeader/SortableTableHeader.tsx";
95
95
  export type { SpinnerProps } from "./Spinner/Spinner.tsx";
96
96
  export { Spinner } from "./Spinner/Spinner.tsx";
97
+ export type { SwatchAppearance, SwatchProps, SwatchSize, } from "./Swatch/Swatch.tsx";
98
+ export { Swatch } from "./Swatch/Swatch.tsx";
97
99
  export type { SlotProps } from "./slotProps.ts";
98
100
  export { mergeSlotProps } from "./slotProps.ts";
99
101
  export { getAsyncIntent, getAsyncLabel, getConnectionIntent, getConnectionLabel, getIsConnectionBusy, } from "./statusIntent.ts";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,YAAY,EACV,qBAAqB,EACrB,aAAa,EACb,cAAc,GACf,MAAM,2BAA2B,CAAA;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AACrD,YAAY,EACV,UAAU,EACV,SAAS,GACV,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AACzC,YAAY,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AACnD,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AACzC,YAAY,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAC5C,YAAY,EACV,WAAW,EACX,SAAS,EACT,WAAW,GACZ,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAA;AACtC,YAAY,EAAE,wBAAwB,EAAE,MAAM,+CAA+C,CAAA;AAC7F,OAAO,EAAE,mBAAmB,EAAE,MAAM,+CAA+C,CAAA;AACnF,YAAY,EACV,gBAAgB,EAChB,sBAAsB,GACvB,MAAM,2CAA2C,CAAA;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2CAA2C,CAAA;AAC7E,YAAY,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAA;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAClD,YAAY,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AACnD,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,EACd,uBAAuB,EACvB,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,oBAAoB,CAAA;AAC3B,YAAY,EACV,WAAW,EACX,UAAU,GACX,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAC5C,YAAY,EACV,eAAe,EACf,cAAc,GACf,MAAM,6BAA6B,CAAA;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAA;AACxD,YAAY,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AACnD,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AACzC,YAAY,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AACnD,YAAY,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAA;AACxE,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAA;AAC9D,YAAY,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAA;AAClE,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAA;AACxD,YAAY,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACzD,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,uBAAuB,EACvB,oBAAoB,EACpB,kBAAkB,EAClB,uBAAuB,GACxB,MAAM,mBAAmB,CAAA;AAC1B,YAAY,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAA;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAClD,YAAY,EACV,WAAW,EACX,YAAY,GACb,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAA;AAC/C,YAAY,EACV,wBAAwB,EACxB,uBAAuB,GACxB,MAAM,+CAA+C,CAAA;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,+CAA+C,CAAA;AACnF,YAAY,EACV,OAAO,EACP,cAAc,GACf,MAAM,2BAA2B,CAAA;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AACrD,YAAY,EACV,cAAc,EACd,cAAc,GACf,MAAM,2BAA2B,CAAA;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AACrD,YAAY,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAA;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAA;AAC7D,YAAY,EACV,QAAQ,EACR,SAAS,GACV,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAA;AACtC,YAAY,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AACnD,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AACzC,YAAY,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACzD,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAA;AAC/C,YAAY,EACV,gBAAgB,EAChB,eAAe,GAChB,MAAM,+BAA+B,CAAA;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAA;AAC3D,YAAY,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AACvE,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,GAChB,MAAM,gCAAgC,CAAA;AACvC,YAAY,EACV,qBAAqB,EACrB,aAAa,GACd,MAAM,yCAAyC,CAAA;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAA;AAC1E,YAAY,EACV,UAAU,EACV,YAAY,EACZ,iBAAiB,EACjB,WAAW,GACZ,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAC5C,YAAY,EACV,aAAa,EACb,aAAa,GACd,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAClD,YAAY,EACV,wBAAwB,EACxB,aAAa,GACd,MAAM,+CAA+C,CAAA;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,+CAA+C,CAAA;AACnF,YAAY,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACzD,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAA;AAC/C,YAAY,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAC/C,OAAO,EACL,cAAc,EACd,aAAa,EACb,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,mBAAmB,CAAA;AAC1B,YAAY,EACV,OAAO,EACP,cAAc,EACd,eAAe,EACf,SAAS,GACV,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAA;AACtC,YAAY,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AACnD,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AACzC,YAAY,EACV,WAAW,EACX,gBAAgB,GACjB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AACrD,YAAY,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAA;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AAC5D,YAAY,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACzD,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAA;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,YAAY,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAA;AAC9E,OAAO,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -62,6 +62,7 @@ export { Select } from "./Select/Select.js";
62
62
  export { Skeleton } from "./Skeleton/Skeleton.js";
63
63
  export { SortableTableHeader } from "./SortableTableHeader/SortableTableHeader.js";
64
64
  export { Spinner } from "./Spinner/Spinner.js";
65
+ export { Swatch } from "./Swatch/Swatch.js";
65
66
  export { mergeSlotProps } from "./slotProps.js";
66
67
  export { getAsyncIntent, getAsyncLabel, getConnectionIntent, getConnectionLabel, getIsConnectionBusy, } from "./statusIntent.js";
67
68
  export { Tabs } from "./Tabs/Tabs.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@charcuterie/ui",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "The Charcuterie components. Tokens for look, @charcuterie/logic for state, ARIA that agents can actually drive.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -44,7 +44,7 @@
44
44
  },
45
45
  "dependencies": {
46
46
  "@charcuterie/logic": "1.1.0",
47
- "@charcuterie/tokens": "1.1.0",
47
+ "@charcuterie/tokens": "1.1.1",
48
48
  "@floating-ui/react": "^0.27.20",
49
49
  "@tanstack/react-virtual": "^3.13.12"
50
50
  },
@@ -316,6 +316,56 @@ export const Responsive: Story = {
316
316
  * unlike the old native `<dialog>`, a synthetic `userEvent.keyboard`
317
317
  * can now press for real.
318
318
  */
319
+ /**
320
+ * A confirm dialog with **no body**: the question is the `heading`
321
+ * (which is the dialog's accessible name) and the answers are the
322
+ * `footer`. `children` is optional precisely for this shape — the old
323
+ * chrome `Modal` extended `<dialog>`'s DOM props, so it allowed it,
324
+ * and image-viewer's delete-confirm renders exactly this.
325
+ */
326
+ const NoBodyDemo = (): ReactNode => {
327
+ const { hide, isVisible, show } = useVisibility()
328
+
329
+ return (
330
+ <>
331
+ <Button appearance="soft" onClick={show} size="sm">
332
+ Delete the file
333
+ </Button>
334
+
335
+ <Dialog
336
+ footer={
337
+ <>
338
+ <Button
339
+ appearance="soft"
340
+ intent="neutral"
341
+ onClick={hide}
342
+ size="sm"
343
+ >
344
+ Keep it
345
+ </Button>
346
+
347
+ <Button intent="danger" size="sm">
348
+ Delete
349
+ </Button>
350
+ </>
351
+ }
352
+ heading="Delete this file? This cannot be undone."
353
+ isVisible={isVisible}
354
+ onClose={hide}
355
+ />
356
+ </>
357
+ )
358
+ }
359
+
360
+ export const NoBody: Story = {
361
+ args: {
362
+ heading: "Delete this file? This cannot be undone.",
363
+ isVisible: false,
364
+ onClose: () => {},
365
+ },
366
+ render: () => <NoBodyDemo />,
367
+ }
368
+
319
369
  export const Interactive: Story = {
320
370
  args: {
321
371
  heading: "Bay 3",
@@ -15,10 +15,38 @@ const {
15
15
  AllVariants,
16
16
  Default,
17
17
  Interactive,
18
+ NoBody,
18
19
  Responsive,
19
20
  Stacked,
20
21
  } = composeStories(stories)
21
22
 
23
+ test("a dialog with no body renders from heading and footer alone", async () => {
24
+ const { body, canvas } = await mountStory(NoBody)
25
+
26
+ await userEvent.click(
27
+ expectAgentDrivable(canvas, {
28
+ name: "Delete the file",
29
+ role: "button",
30
+ }),
31
+ )
32
+
33
+ // `children` is optional: the question is the accessible name and
34
+ // the answers are the footer, with nothing in between.
35
+ const dialog = expectAgentDrivable(body, {
36
+ name: "Delete this file? This cannot be undone.",
37
+ role: "dialog",
38
+ })
39
+
40
+ await expect(
41
+ expectAgentDrivable(body, {
42
+ name: "Delete",
43
+ role: "button",
44
+ }),
45
+ ).toBeInTheDocument()
46
+
47
+ await expectNoAxeViolations(dialog)
48
+ })
49
+
22
50
  test("the dialog is reachable from a body-scoped query", async () => {
23
51
  const { body, canvas } = await mountStory(Default)
24
52
 
@@ -8,7 +8,13 @@ import { toClassName } from "../toClassName.ts"
8
8
  export type DialogSize = "full" | "lg" | "md" | "sm" | "xl"
9
9
 
10
10
  export type DialogProps = {
11
- children: ReactNode
11
+ /**
12
+ * The scrolling body. Optional: a confirm dialog whose question is
13
+ * its `heading` and whose answers are its `footer` has no body, and
14
+ * the old chrome `Modal` (which extended `<dialog>`'s DOM props)
15
+ * allowed that — `Dialog` keeps it.
16
+ */
17
+ children?: ReactNode
12
18
  className?: string
13
19
  /** The footer row. Buttons, usually. */
14
20
  footer?: ReactNode
@@ -0,0 +1,50 @@
1
+ import { Canvas, Controls, Meta } from "@storybook/addon-docs/blocks";
2
+
3
+ import * as SwatchStories from "./Swatch.stories";
4
+
5
+ <Meta of={SwatchStories} />
6
+
7
+ # Swatch
8
+
9
+ A colour presented **as content**, with a name attached. It is the one colour the design
10
+ system does not own: the red sticker on a game controller, the accent castkit pulls off an
11
+ album, a user's tag colour. Not a token — a value from data.
12
+
13
+ <Canvas of={SwatchStories.Default} />
14
+
15
+ ## Props
16
+
17
+ <Controls />
18
+
19
+ ## Why it is not a `Badge` or a status dot
20
+
21
+ `Badge` and `LiveStatusIndicator` both take an `intent`, because both show a *state* whose
22
+ colour the system owns and can name — `danger` is red and is called "danger". A swatch
23
+ shows a colour the system cannot name, so the colour is a `color` prop that lands in an
24
+ inline `style`, and the meaning travels in a **required** `label`. A `background-color` is
25
+ nothing to a screen reader and nothing to `getByRole`, so the type asks for the name and
26
+ there is no way to render one without it.
27
+
28
+ `DOT_SIZE_CLASS` is exported so an app *can* hand-roll one of these — and three across the
29
+ fleet did, each without a name. This is that dot, named, and sized as content rather than
30
+ punctuation.
31
+
32
+ ## `outline` — present but inactive
33
+
34
+ <Canvas of={SwatchStories.AllVariants} />
35
+
36
+ `outline` keeps the hue and drops the fill. It is the one visual state a status colour
37
+ cannot borrow from `intent`: a subject that is there but not active — a powered-off
38
+ controller beside its live siblings. The ring is drawn in the colour itself, so it survives
39
+ where a token could not follow.
40
+
41
+ ## Findable, and white stays visible
42
+
43
+ <Canvas of={SwatchStories.AllStates} />
44
+
45
+ It is a `role="img"` with an accessible name, so `getByRole("img", { name })` resolves in
46
+ both the dot-only and labelled forms — one stable handle whether or not the text is on
47
+ screen. The translucent inset ring on `solid` is what keeps a white or near-white swatch
48
+ from vanishing against `surface-raised` in one of the two schemes.
49
+
50
+ <Canvas of={SwatchStories.InAList} />
@@ -0,0 +1,177 @@
1
+ import type { Meta, StoryObj } from "@storybook/react"
2
+
3
+ import {
4
+ StoryCell,
5
+ StoryGrid,
6
+ StoryRow,
7
+ StorySection,
8
+ } from "../board.storyHelpers.tsx"
9
+ import { Card } from "../Card/Card.tsx"
10
+ import { Swatch } from "./Swatch.tsx"
11
+
12
+ /**
13
+ * Colours that are **data**, not tokens — the whole reason the
14
+ * component exists. These stand in for stickers on a controller, and
15
+ * a design system re-theming them would be re-theming the hardware.
16
+ */
17
+ const STICKERS = [
18
+ { color: "#E5484D", label: "Red" },
19
+ { color: "#3B82F6", label: "Blue" },
20
+ { color: "#35D07F", label: "Green" },
21
+ { color: "#F5C518", label: "Yellow" },
22
+ ] as const
23
+
24
+ const meta = {
25
+ title: "Components/Swatch",
26
+ component: Swatch,
27
+ parameters: { layout: "padded" },
28
+ argTypes: { color: { control: "color" } },
29
+ args: {
30
+ appearance: "solid",
31
+ color: "#E5484D",
32
+ isLabelVisible: true,
33
+ label: "Red",
34
+ size: "md",
35
+ },
36
+ } satisfies Meta<typeof Swatch>
37
+
38
+ export default meta
39
+
40
+ type Story = StoryObj<typeof meta>
41
+
42
+ /**
43
+ * A named graphic — `getByRole("img", { name: "Red" })` resolves,
44
+ * because a colour a screen reader cannot see needs a name it can
45
+ * read.
46
+ */
47
+ export const Default: Story = {}
48
+
49
+ /**
50
+ * `solid` fills; `outline` keeps the hue and drops the fill. The
51
+ * second is the one state a status colour cannot borrow from
52
+ * `intent` — "this thing is present but inactive" — which is what a
53
+ * powered-off controller looks like beside its live siblings.
54
+ */
55
+ export const AllVariants: Story = {
56
+ render: (swatchProps) => (
57
+ <StorySection title="`outline` is the same colour with the fill taken away — for a subject that is there but not active.">
58
+ <StoryGrid columns={2}>
59
+ <StoryCell label="solid">
60
+ <StoryRow>
61
+ {STICKERS.map((sticker) => (
62
+ <Swatch
63
+ {...swatchProps}
64
+ appearance="solid"
65
+ color={sticker.color}
66
+ isLabelVisible={false}
67
+ key={sticker.label}
68
+ label={sticker.label}
69
+ />
70
+ ))}
71
+ </StoryRow>
72
+ </StoryCell>
73
+
74
+ <StoryCell label="outline">
75
+ <StoryRow>
76
+ {STICKERS.map((sticker) => (
77
+ <Swatch
78
+ {...swatchProps}
79
+ appearance="outline"
80
+ color={sticker.color}
81
+ isLabelVisible={false}
82
+ key={sticker.label}
83
+ label={sticker.label}
84
+ />
85
+ ))}
86
+ </StoryRow>
87
+ </StoryCell>
88
+ </StoryGrid>
89
+ </StorySection>
90
+ ),
91
+ }
92
+
93
+ export const AllStates: Story = {
94
+ render: (swatchProps) => (
95
+ <StoryGrid columns={2}>
96
+ <StoryCell label="dot only — name still read">
97
+ <Swatch {...swatchProps} isLabelVisible={false} />
98
+ </StoryCell>
99
+
100
+ <StoryCell label="label visible">
101
+ <Swatch {...swatchProps} isLabelVisible />
102
+ </StoryCell>
103
+
104
+ <StoryCell label="sizes">
105
+ <StoryRow>
106
+ <Swatch
107
+ {...swatchProps}
108
+ isLabelVisible={false}
109
+ size="sm"
110
+ />
111
+
112
+ <Swatch
113
+ {...swatchProps}
114
+ isLabelVisible={false}
115
+ size="md"
116
+ />
117
+
118
+ <Swatch
119
+ {...swatchProps}
120
+ isLabelVisible={false}
121
+ size="lg"
122
+ />
123
+ </StoryRow>
124
+ </StoryCell>
125
+
126
+ <StoryCell label="white stays visible in both schemes">
127
+ <StoryRow>
128
+ <Swatch
129
+ {...swatchProps}
130
+ color="#FFFFFF"
131
+ isLabelVisible={false}
132
+ label="White"
133
+ />
134
+
135
+ <Swatch
136
+ {...swatchProps}
137
+ appearance="outline"
138
+ color="#FFFFFF"
139
+ isLabelVisible={false}
140
+ label="White"
141
+ />
142
+ </StoryRow>
143
+ </StoryCell>
144
+ </StoryGrid>
145
+ ),
146
+ }
147
+
148
+ /**
149
+ * The real placement: a row per item, the swatch answering "which
150
+ * one" before the words do. This is castkit's album accent and
151
+ * plex-channels' channel colours as much as it is a controller
152
+ * sticker.
153
+ */
154
+ export const InAList: Story = {
155
+ render: () => (
156
+ <Card heading="Controllers">
157
+ <ul className="flex list-none flex-col gap-2 p-0">
158
+ {STICKERS.map((sticker) => (
159
+ <li
160
+ className="flex items-center gap-3"
161
+ key={sticker.label}
162
+ >
163
+ <Swatch
164
+ color={sticker.color}
165
+ label={`${sticker.label} sticker`}
166
+ size="sm"
167
+ />
168
+
169
+ <span className="text-content-secondary text-sm">
170
+ {sticker.label} controller
171
+ </span>
172
+ </li>
173
+ ))}
174
+ </ul>
175
+ </Card>
176
+ ),
177
+ }
@@ -0,0 +1,57 @@
1
+ import { composeStories } from "@storybook/react"
2
+ import { expect } from "storybook/test"
3
+ import { test } from "vitest"
4
+
5
+ import { mountStory } from "../mountStory.testHelpers.ts"
6
+ import { expectAgentDrivable } from "../testing/index.ts"
7
+ import * as stories from "./Swatch.stories.tsx"
8
+
9
+ const { Default, InAList } = composeStories(stories)
10
+
11
+ test("a colour is findable by the name a screen reader can read", async () => {
12
+ const { canvas } = await mountStory(Default)
13
+
14
+ // The whole contract: a `background-color` is nothing to an agent
15
+ // or a screen reader, so the swatch is an `img` with a name.
16
+ const swatch = expectAgentDrivable(canvas, {
17
+ name: "Red",
18
+ role: "img",
19
+ })
20
+
21
+ // The name comes from `aria-label`, not the dot, which carries no
22
+ // information of its own.
23
+ await expect(swatch.firstElementChild).toHaveAttribute(
24
+ "aria-hidden",
25
+ "true",
26
+ )
27
+ })
28
+
29
+ test("the name survives with no visible label", async () => {
30
+ // `InAList` renders the dot-only form — `isLabelVisible` defaults
31
+ // false — with a distinct name per row, which is the placement
32
+ // that has to stay drivable: the swatch answers "which one" before
33
+ // any text does.
34
+ const { canvas } = await mountStory(InAList)
35
+
36
+ for (const name of [
37
+ "Red sticker",
38
+ "Blue sticker",
39
+ "Green sticker",
40
+ "Yellow sticker",
41
+ ]) {
42
+ expectAgentDrivable(canvas, { name, role: "img" })
43
+ }
44
+ })
45
+
46
+ test("solid rings its fill; the ring is what keeps white visible", async () => {
47
+ const { canvas } = await mountStory(Default)
48
+
49
+ const dot = canvas.getByRole("img", {
50
+ name: "Red",
51
+ }).firstElementChild
52
+
53
+ // Not decoration: a hairline border on a white swatch disappears
54
+ // against `surface-raised` in one of the two schemes, and the
55
+ // inset ring is what stops that.
56
+ await expect(dot).toHaveClass("ring-inset")
57
+ })
@@ -0,0 +1,139 @@
1
+ import type {
2
+ ComponentPropsWithRef,
3
+ ReactNode,
4
+ } from "react"
5
+
6
+ import { toClassName } from "../toClassName.ts"
7
+
8
+ export type SwatchAppearance = "outline" | "solid"
9
+
10
+ export type SwatchSize = keyof typeof SWATCH_SIZE_CLASS
11
+
12
+ export type SwatchProps = Omit<
13
+ ComponentPropsWithRef<"span">,
14
+ "children" | "color"
15
+ > & {
16
+ /**
17
+ * `outline` keeps the hue and drops the fill — for a swatch whose
18
+ * subject is present but inactive. It is the one visual state a
19
+ * status colour cannot borrow from `intent`, because the colour is
20
+ * not an intent.
21
+ */
22
+ appearance?: SwatchAppearance
23
+ /**
24
+ * Any CSS colour, and this is the whole reason the component
25
+ * exists: it is a **value from data** — a physical sticker, an
26
+ * album's extracted accent, a user-chosen tag — not a token. A
27
+ * design system owns `intent.danger`; it does not own the colour
28
+ * of the dot somebody stuck on a game controller, and re-theming
29
+ * that would be re-theming the hardware. So it is a prop and lands
30
+ * in an inline `style`, the one sanctioned escape hatch for a
31
+ * runtime value.
32
+ */
33
+ color: string
34
+ isLabelVisible?: boolean
35
+ /**
36
+ * Required, and it is the point. A colour is not a name: a screen
37
+ * reader gets nothing at all from a `background-color`, and
38
+ * `getByRole("img", { name })` — the query an agent writes — has
39
+ * nothing to match. So the type asks for the name and there is no
40
+ * way to render the component without one.
41
+ */
42
+ label: string
43
+ size?: SwatchSize
44
+ }
45
+
46
+ /**
47
+ * The scale is the component's own, and deliberately larger than
48
+ * `DOT_SIZE_CLASS`.
49
+ *
50
+ * That map tops out at 10px, which is right for a status dot beside
51
+ * a line of text and far too small for a swatch that is the primary
52
+ * way a user tells one row from another across a room. A swatch is
53
+ * content, not punctuation.
54
+ */
55
+ const SWATCH_SIZE_CLASS = {
56
+ sm: "size-4",
57
+ md: "size-6",
58
+ lg: "size-9",
59
+ } as const
60
+
61
+ /**
62
+ * A colour presented **as content**, with a name attached.
63
+ *
64
+ * It is not `LiveStatusIndicator`'s dot and not a `Badge`. Both of
65
+ * those take an `intent`, because both show a *state* whose colour
66
+ * the design system owns and can name in English. This shows a
67
+ * colour the system does **not** own and **cannot** name — the red
68
+ * sticker on a controller, red because someone put a red sticker on
69
+ * it; the accent castkit pulls off an album; a user's tag colour.
70
+ * `DOT_SIZE_CLASS` is exported precisely so an app can hand-roll one
71
+ * of these, and three of them across the fleet did, each without a
72
+ * name a screen reader could read.
73
+ *
74
+ * ### `role="img"`, and the name is required
75
+ *
76
+ * A swatch is a graphic that carries meaning, so it is an image with
77
+ * an accessible name — which makes it findable by
78
+ * `getByRole("img", { name })` in **both** the dot-only and
79
+ * labelled forms, one stable handle regardless of whether the text
80
+ * is on screen. The dot and any visible label are inside it and go
81
+ * `aria-hidden` by virtue of the name on the wrapper, exactly as an
82
+ * inline SVG with a caption would.
83
+ *
84
+ * ### The ring is not a token
85
+ *
86
+ * `solid` sits a translucent white ring inside the fill so a white
87
+ * or near-white swatch stays visible against `surface-raised` in
88
+ * both schemes; a hairline border alone disappears on one of the
89
+ * two. `outline` drops the fill to a faint tint of the same hue and
90
+ * draws the ring in the colour itself — via an inline `box-shadow`,
91
+ * because the ring colour has to come from the data and
92
+ * `--tw-ring-color` is not something `CSSProperties` will type.
93
+ */
94
+ export const Swatch = ({
95
+ appearance = "solid",
96
+ className,
97
+ color,
98
+ isLabelVisible = false,
99
+ label,
100
+ size = "md",
101
+ ...spanProps
102
+ }: SwatchProps): ReactNode => (
103
+ <span
104
+ {...spanProps}
105
+ aria-label={label}
106
+ className={toClassName(
107
+ "inline-flex items-center gap-2 align-middle",
108
+ className,
109
+ )}
110
+ role="img"
111
+ >
112
+ <span
113
+ aria-hidden="true"
114
+ className={toClassName(
115
+ "inline-block shrink-0 rounded-full",
116
+ SWATCH_SIZE_CLASS[size],
117
+ appearance === "solid" &&
118
+ "shadow-low ring-2 ring-white/25 ring-inset",
119
+ )}
120
+ style={
121
+ appearance === "solid"
122
+ ? { backgroundColor: color }
123
+ : {
124
+ backgroundColor: `color-mix(in srgb, ${color} 12%, transparent)`,
125
+ boxShadow: `inset 0 0 0 3px ${color}`,
126
+ }
127
+ }
128
+ />
129
+
130
+ {isLabelVisible ? (
131
+ <span
132
+ aria-hidden="true"
133
+ className="text-content-primary text-sm"
134
+ >
135
+ {label}
136
+ </span>
137
+ ) : null}
138
+ </span>
139
+ )
package/src/index.ts CHANGED
@@ -165,6 +165,12 @@ export type {
165
165
  export { SortableTableHeader } from "./SortableTableHeader/SortableTableHeader.tsx"
166
166
  export type { SpinnerProps } from "./Spinner/Spinner.tsx"
167
167
  export { Spinner } from "./Spinner/Spinner.tsx"
168
+ export type {
169
+ SwatchAppearance,
170
+ SwatchProps,
171
+ SwatchSize,
172
+ } from "./Swatch/Swatch.tsx"
173
+ export { Swatch } from "./Swatch/Swatch.tsx"
168
174
  export type { SlotProps } from "./slotProps.ts"
169
175
  export { mergeSlotProps } from "./slotProps.ts"
170
176
  export {
@@ -300,7 +300,10 @@ test("the barrel is the only place components are re-exported", async () => {
300
300
  // `Dialog` and reintroduces `Modal` as the base layer, so both are
301
301
  // components: +1 → 29. The picker family adds `Listbox` (single-select)
302
302
  // and `Combobox` (searchable/virtualized): +2 → 31.
303
- expect(componentNames.length).toBe(31)
303
+ // `Swatch` — a colour as content with a required name, the one
304
+ // colour the system does not own — comes out of `portly-controllers`,
305
+ // the fleet's newest consumer: +1 -> 32.
306
+ expect(componentNames.length).toBe(32)
304
307
 
305
308
  for (const name of componentNames) {
306
309
  expect(barrel).toContain(`export { ${name} }`)