@charcuterie/ui 3.10.0 → 3.11.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 CHANGED
@@ -146,6 +146,7 @@ an hour of confusion.
146
146
  | Type | `text-sm`/`text-md`/`text-lg`, which are **ours**: `theme.css` bridges `--text-*` onto the density-scaled `--font-size-*` |
147
147
  | Motion | `styles.css`, at `--duration-loop-*`, switched off under `prefers-reduced-motion` |
148
148
  | Scrollbar | `styles.css` — add `charcuterie-scrollbar` to any scrolling element for a token-tinted bar (rounded thumb on Chromium/Safari; thin standard match on Firefox) that flips with `[data-scheme]` |
149
+ | Accent edge | `Card/cardAccentEdge.ts` — `<Card accentEdge={{ categorical }} \| {{ color }}>` draws a bar down the leading edge from a pseudo-element that **inherits the card's radius**. A border cannot follow a corner, which is why three apps had a square bar on a round card |
149
150
  | State | `@charcuterie/logic` — `useUniqueId` for label wiring, `useStatus` for `MediaTile`'s three image states |
150
151
 
151
152
  **Class names are never interpolated.** `` `bg-intent-${intent}-solid` `` generates nothing
@@ -1,8 +1,19 @@
1
1
  import type { ElevationStep, SurfaceRole } from "@charcuterie/tokens";
2
2
  import type { ComponentPropsWithRef, ReactNode } from "react";
3
+ import type { CardAccentEdge } from "./cardAccentEdge.ts";
3
4
  export type CardSurface = Extract<SurfaceRole, "base" | "raised" | "sunken">;
4
5
  export type CardPadding = "lg" | "md" | "none" | "sm";
5
6
  export type CardProps = ComponentPropsWithRef<"section"> & {
7
+ /**
8
+ * A coloured bar down the leading edge, following the card's own
9
+ * corners.
10
+ *
11
+ * `{ categorical: 3 }` for a colour a user picked; `{ color }`
12
+ * for one an app computed — a hue hashed from a repo's name, say,
13
+ * where ten indices are not enough. See `cardAccentEdge.ts` for
14
+ * why it is a pseudo-element and not a border.
15
+ */
16
+ accentEdge?: CardAccentEdge;
6
17
  /** Buttons or a badge, laid out beside the heading. */
7
18
  actions?: ReactNode;
8
19
  elevation?: ElevationStep;
@@ -40,5 +51,5 @@ export declare const ELEVATION_CLASS: Record<ElevationStep, string>;
40
51
  * because a card wrapping a poster grid genuinely has none, which is
41
52
  * a layout fact rather than a density one.
42
53
  */
43
- export declare const Card: ({ actions, children, className, elevation, footer, heading, headingLevel, padding, surface, ...sectionProps }: CardProps) => ReactNode;
54
+ export declare const Card: ({ accentEdge, actions, children, className, elevation, footer, heading, headingLevel, padding, style, surface, ...sectionProps }: CardProps) => ReactNode;
44
55
  //# sourceMappingURL=Card.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Card.d.ts","sourceRoot":"","sources":["../../src/Card/Card.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,aAAa,EACb,WAAW,EACZ,MAAM,qBAAqB,CAAA;AAC5B,OAAO,KAAK,EACV,qBAAqB,EACrB,SAAS,EACV,MAAM,OAAO,CAAA;AAId,MAAM,MAAM,WAAW,GAAG,OAAO,CAC/B,WAAW,EACX,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAC7B,CAAA;AAED,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAAA;AAErD,MAAM,MAAM,SAAS,GAAG,qBAAqB,CAAC,SAAS,CAAC,GAAG;IACzD,uDAAuD;IACvD,OAAO,CAAC,EAAE,SAAS,CAAA;IACnB,SAAS,CAAC,EAAE,aAAa,CAAA;IACzB,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IACxB,OAAO,CAAC,EAAE,WAAW,CAAA;IACrB,OAAO,CAAC,EAAE,WAAW,CAAA;CACtB,CAAA;AAQD;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,EAAE,MAAM,CAClC,aAAa,EACb,MAAM,CAMP,CAAA;AASD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,IAAI,GAAI,+GAWlB,SAAS,KAAG,SAkDd,CAAA"}
1
+ {"version":3,"file":"Card.d.ts","sourceRoot":"","sources":["../../src/Card/Card.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,aAAa,EACb,WAAW,EACZ,MAAM,qBAAqB,CAAA;AAC5B,OAAO,KAAK,EACV,qBAAqB,EACrB,SAAS,EACV,MAAM,OAAO,CAAA;AAGd,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAMzD,MAAM,MAAM,WAAW,GAAG,OAAO,CAC/B,WAAW,EACX,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAC7B,CAAA;AAED,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAAA;AAErD,MAAM,MAAM,SAAS,GAAG,qBAAqB,CAAC,SAAS,CAAC,GAAG;IACzD;;;;;;;;OAQG;IACH,UAAU,CAAC,EAAE,cAAc,CAAA;IAC3B,uDAAuD;IACvD,OAAO,CAAC,EAAE,SAAS,CAAA;IACnB,SAAS,CAAC,EAAE,aAAa,CAAA;IACzB,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IACxB,OAAO,CAAC,EAAE,WAAW,CAAA;IACrB,OAAO,CAAC,EAAE,WAAW,CAAA;CACtB,CAAA;AAQD;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,EAAE,MAAM,CAClC,aAAa,EACb,MAAM,CAMP,CAAA;AASD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,IAAI,GAAI,kIAalB,SAAS,KAAG,SAmEd,CAAA"}
package/dist/Card/Card.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useUniqueId } from "@charcuterie/logic";
3
3
  import { toClassName } from "../toClassName.js";
4
+ import { getAccentEdgeClassName, getAccentEdgeStyle, } from "./cardAccentEdge.js";
4
5
  const SURFACE_CLASS = {
5
6
  base: "bg-surface-base",
6
7
  raised: "bg-surface-raised",
@@ -45,8 +46,17 @@ const PADDING_CLASS = {
45
46
  * because a card wrapping a poster grid genuinely has none, which is
46
47
  * a layout fact rather than a density one.
47
48
  */
48
- export const Card = ({ actions, children, className, elevation = "low", footer, heading, headingLevel = 2, padding = "md", surface = "raised", ...sectionProps }) => {
49
+ export const Card = ({ accentEdge, actions, children, className, elevation = "low", footer, heading, headingLevel = 2, padding = "md", style, surface = "raised", ...sectionProps }) => {
49
50
  const headingId = useUniqueId();
51
+ // The caller's own `style` wins. An accent colour is one custom
52
+ // property, and silently dropping whatever else the call site set
53
+ // would be a worse trade than letting it override this one.
54
+ const accentEdgeStyle = accentEdge == null
55
+ ? undefined
56
+ : getAccentEdgeStyle(accentEdge);
57
+ const mergedStyle = accentEdgeStyle == null
58
+ ? style
59
+ : { ...accentEdgeStyle, ...style };
50
60
  const Heading = `h${headingLevel}`;
51
61
  return (_jsxs("section", { ...sectionProps, "aria-labelledby": heading ? headingId : undefined, className: toClassName(
52
62
  // `@container` here, not on a wrapper, is what lets the
@@ -54,6 +64,8 @@ export const Card = ({ actions, children, className, elevation = "low", footer,
54
64
  // a card in a sidebar and the same card full-bleed are the
55
65
  // case a media query cannot tell apart, and the fleet's
56
66
  // poster grids get it wrong at intermediate widths today.
57
- "@container flex flex-col gap-3 rounded-lg border border-border-subtle text-content-primary", SURFACE_CLASS[surface], ELEVATION_CLASS[elevation], PADDING_CLASS[padding], className), children: [heading || actions ? (_jsxs("header", { className: "flex flex-col gap-2 cq-sm:flex-row cq-sm:items-start cq-sm:justify-between", children: [heading ? (_jsx(Heading, { className: "font-semibold text-md leading-tight", id: headingId, children: heading })) : null, actions ? (_jsx("div", { className: "flex shrink-0 items-center gap-1", children: actions })) : null] })) : null, children, footer ? (_jsx("footer", { className: "border-t border-border-subtle pt-3 text-content-secondary text-sm", children: footer })) : null] }));
67
+ "@container flex flex-col gap-3 rounded-lg border border-border-subtle text-content-primary", SURFACE_CLASS[surface], ELEVATION_CLASS[elevation], PADDING_CLASS[padding], accentEdge == null
68
+ ? undefined
69
+ : getAccentEdgeClassName(accentEdge), className), style: mergedStyle, children: [heading || actions ? (_jsxs("header", { className: "flex flex-col gap-2 cq-sm:flex-row cq-sm:items-start cq-sm:justify-between", children: [heading ? (_jsx(Heading, { className: "font-semibold text-md leading-tight", id: headingId, children: heading })) : null, actions ? (_jsx("div", { className: "flex shrink-0 items-center gap-1", children: actions })) : null] })) : null, children, footer ? (_jsx("footer", { className: "border-t border-border-subtle pt-3 text-content-secondary text-sm", children: footer })) : null] }));
58
70
  };
59
71
  //# sourceMappingURL=Card.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Card.js","sourceRoot":"","sources":["../../src/Card/Card.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAUhD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAoB/C,MAAM,aAAa,GAAgC;IACjD,IAAI,EAAE,iBAAiB;IACvB,MAAM,EAAE,mBAAmB;IAC3B,MAAM,EAAE,mBAAmB;CAC5B,CAAA;AAED;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,eAAe,GAGxB;IACF,IAAI,EAAE,aAAa;IACnB,GAAG,EAAE,YAAY;IACjB,MAAM,EAAE,eAAe;IACvB,IAAI,EAAE,aAAa;CACpB,CAAA;AAED,MAAM,aAAa,GAAgC;IACjD,IAAI,EAAE,KAAK;IACX,EAAE,EAAE,KAAK;IACT,EAAE,EAAE,KAAK;IACT,EAAE,EAAE,KAAK;CACV,CAAA;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,EACnB,OAAO,EACP,QAAQ,EACR,SAAS,EACT,SAAS,GAAG,KAAK,EACjB,MAAM,EACN,OAAO,EACP,YAAY,GAAG,CAAC,EAChB,OAAO,GAAG,IAAI,EACd,OAAO,GAAG,QAAQ,EAClB,GAAG,YAAY,EACL,EAAa,EAAE;IACzB,MAAM,SAAS,GAAG,WAAW,EAAE,CAAA;IAE/B,MAAM,OAAO,GAAG,IAAI,YAAY,EAAW,CAAA;IAE3C,OAAO,CACL,sBACM,YAAY,qBACC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,EAChD,SAAS,EAAE,WAAW;QACpB,wDAAwD;QACxD,2DAA2D;QAC3D,2DAA2D;QAC3D,wDAAwD;QACxD,0DAA0D;QAC1D,4FAA4F,EAC5F,aAAa,CAAC,OAAO,CAAC,EACtB,eAAe,CAAC,SAAS,CAAC,EAC1B,aAAa,CAAC,OAAO,CAAC,EACtB,SAAS,CACV,aAEA,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,CACpB,kBAAQ,SAAS,EAAC,4EAA4E,aAC3F,OAAO,CAAC,CAAC,CAAC,CACT,KAAC,OAAO,IACN,SAAS,EAAC,qCAAqC,EAC/C,EAAE,EAAE,SAAS,YAEZ,OAAO,GACA,CACX,CAAC,CAAC,CAAC,IAAI,EAEP,OAAO,CAAC,CAAC,CAAC,CACT,cAAK,SAAS,EAAC,kCAAkC,YAC9C,OAAO,GACJ,CACP,CAAC,CAAC,CAAC,IAAI,IACD,CACV,CAAC,CAAC,CAAC,IAAI,EAEP,QAAQ,EAER,MAAM,CAAC,CAAC,CAAC,CACR,iBAAQ,SAAS,EAAC,mEAAmE,YAClF,MAAM,GACA,CACV,CAAC,CAAC,CAAC,IAAI,IACA,CACX,CAAA;AACH,CAAC,CAAA"}
1
+ {"version":3,"file":"Card.js","sourceRoot":"","sources":["../../src/Card/Card.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAUhD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAE/C,OAAO,EACL,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,qBAAqB,CAAA;AA8B5B,MAAM,aAAa,GAAgC;IACjD,IAAI,EAAE,iBAAiB;IACvB,MAAM,EAAE,mBAAmB;IAC3B,MAAM,EAAE,mBAAmB;CAC5B,CAAA;AAED;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,eAAe,GAGxB;IACF,IAAI,EAAE,aAAa;IACnB,GAAG,EAAE,YAAY;IACjB,MAAM,EAAE,eAAe;IACvB,IAAI,EAAE,aAAa;CACpB,CAAA;AAED,MAAM,aAAa,GAAgC;IACjD,IAAI,EAAE,KAAK;IACX,EAAE,EAAE,KAAK;IACT,EAAE,EAAE,KAAK;IACT,EAAE,EAAE,KAAK;CACV,CAAA;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,EACnB,UAAU,EACV,OAAO,EACP,QAAQ,EACR,SAAS,EACT,SAAS,GAAG,KAAK,EACjB,MAAM,EACN,OAAO,EACP,YAAY,GAAG,CAAC,EAChB,OAAO,GAAG,IAAI,EACd,KAAK,EACL,OAAO,GAAG,QAAQ,EAClB,GAAG,YAAY,EACL,EAAa,EAAE;IACzB,MAAM,SAAS,GAAG,WAAW,EAAE,CAAA;IAE/B,gEAAgE;IAChE,kEAAkE;IAClE,4DAA4D;IAC5D,MAAM,eAAe,GACnB,UAAU,IAAI,IAAI;QAChB,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAA;IAEpC,MAAM,WAAW,GACf,eAAe,IAAI,IAAI;QACrB,CAAC,CAAC,KAAK;QACP,CAAC,CAAC,EAAE,GAAG,eAAe,EAAE,GAAG,KAAK,EAAE,CAAA;IAEtC,MAAM,OAAO,GAAG,IAAI,YAAY,EAAW,CAAA;IAE3C,OAAO,CACL,sBACM,YAAY,qBACC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,EAChD,SAAS,EAAE,WAAW;QACpB,wDAAwD;QACxD,2DAA2D;QAC3D,2DAA2D;QAC3D,wDAAwD;QACxD,0DAA0D;QAC1D,4FAA4F,EAC5F,aAAa,CAAC,OAAO,CAAC,EACtB,eAAe,CAAC,SAAS,CAAC,EAC1B,aAAa,CAAC,OAAO,CAAC,EACtB,UAAU,IAAI,IAAI;YAChB,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,sBAAsB,CAAC,UAAU,CAAC,EACtC,SAAS,CACV,EACD,KAAK,EAAE,WAAW,aAEjB,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,CACpB,kBAAQ,SAAS,EAAC,4EAA4E,aAC3F,OAAO,CAAC,CAAC,CAAC,CACT,KAAC,OAAO,IACN,SAAS,EAAC,qCAAqC,EAC/C,EAAE,EAAE,SAAS,YAEZ,OAAO,GACA,CACX,CAAC,CAAC,CAAC,IAAI,EAEP,OAAO,CAAC,CAAC,CAAC,CACT,cAAK,SAAS,EAAC,kCAAkC,YAC9C,OAAO,GACJ,CACP,CAAC,CAAC,CAAC,IAAI,IACD,CACV,CAAC,CAAC,CAAC,IAAI,EAEP,QAAQ,EAER,MAAM,CAAC,CAAC,CAAC,CACR,iBAAQ,SAAS,EAAC,mEAAmE,YAClF,MAAM,GACA,CACV,CAAC,CAAC,CAAC,IAAI,IACA,CACX,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,101 @@
1
+ /**
2
+ * A coloured bar down a card's leading edge — and the reason it is
3
+ * a pseudo-element rather than a border.
4
+ *
5
+ * Three apps had grown this shape independently and all three drew
6
+ * it as a straight border beside a rounded box, so the bar ran past
7
+ * the curve and stopped square while the card it belonged to was
8
+ * round. Folio put `border-inline-start` on a WRAPPER around the
9
+ * card; mail-sifter puts `borderInlineStartWidth: 4` on a
10
+ * `rounded-xl` anchor; spoolbuddy writes `rounded-lg border-l-3`.
11
+ * A border is painted on the border box, so none of them can follow
12
+ * a corner — the notch is not a bug in any one app, it is what that
13
+ * technique does.
14
+ *
15
+ * A pseudo-element overlays the card and takes
16
+ * `border-radius: inherit`, so the bar follows whatever radius the
17
+ * card already has and nobody states a radius twice.
18
+ *
19
+ * ⚠️ **The shadow goes on the pseudo-element, never on the card.**
20
+ * `Card` carries `shadow-low` from the elevation scale, and an app
21
+ * stylesheet is unlayered while Tailwind's utilities sit in
22
+ * `@layer utilities` — so a `box-shadow` written at the call site
23
+ * outranks the utility and takes the card's elevation away with it.
24
+ * That is not hypothetical; it is the version of this fix that was
25
+ * written first.
26
+ *
27
+ * ⚠️ **Not a 3px-wide pseudo-element with a rounded leading edge.**
28
+ * A `border-radius` of `0.5rem` on a 3px-wide box is clamped by the
29
+ * browser to fit, so it caps the bar instead of following the
30
+ * card's curve.
31
+ *
32
+ * ⚠️ **`box-shadow` has no logical form**, so the offset is
33
+ * physical and the `rtl:` variant is what carries the bar to the
34
+ * other side. A single `inset 3px` would put it on the left of an
35
+ * Arabic page, which is the trailing edge there.
36
+ */
37
+ import type { CategoricalIndex } from "@charcuterie/tokens";
38
+ /**
39
+ * Which colour the bar takes.
40
+ *
41
+ * Two arms, because the fleet has two answers and neither is wrong.
42
+ * Docket picks a **categorical index** — a colour a user chose for
43
+ * a project, from the ten-wide contrast-audited family. Folio and
44
+ * mail-sifter derive a **hue from a name hash**, so a repo added
45
+ * tomorrow already has a colour and nobody maintains a palette;
46
+ * that is 360 answers, not ten, and it cannot be an index.
47
+ *
48
+ * `intent` is deliberately absent. An intent is a claim the design
49
+ * system makes — `danger` says what happens if you press the thing
50
+ * — and no card in this fleet wants its edge to make one. When one
51
+ * does, that is a third arm and a decision record, not a guess
52
+ * made here.
53
+ */
54
+ export type CardAccentEdge = {
55
+ categorical: CategoricalIndex;
56
+ color?: never;
57
+ } | {
58
+ categorical?: never;
59
+ color: string;
60
+ };
61
+ /**
62
+ * The custom property an explicit colour is threaded through.
63
+ *
64
+ * A property rather than an inline `box-shadow`, because the shadow
65
+ * string has to stay a COMPLETE literal in the source for Tailwind
66
+ * to generate it at all. One literal reading one variable covers
67
+ * every colour an app can compute; interpolating the colour into
68
+ * the class name would generate nothing, paint nothing, and report
69
+ * nothing.
70
+ */
71
+ export declare const ACCENT_EDGE_COLOR_PROPERTY = "--charcuterie-accent-edge";
72
+ /**
73
+ * The overlay itself. Colour arrives separately.
74
+ *
75
+ * `pointer-events: none` is load-bearing rather than tidy: this box
76
+ * covers the whole card, including every link and button in it.
77
+ */
78
+ export declare const ACCENT_EDGE_BASE_CLASS = "relative before:pointer-events-none before:absolute before:inset-0 before:rounded-[inherit] before:content-['']";
79
+ /**
80
+ * Ten indices, written out in full, for the reason
81
+ * `categoricalStyles.ts` opens with: Tailwind scans source text for
82
+ * COMPLETE class strings, so a template literal generates nothing
83
+ * at all and the bar renders invisible with no error and no failing
84
+ * test. `tailwindCandidates.test.ts` compiles every literal in this
85
+ * package through the real Tailwind, which is the something that
86
+ * checks.
87
+ */
88
+ export declare const ACCENT_EDGE_CATEGORICAL_CLASS: Record<CategoricalIndex, string>;
89
+ /** The same bar, reading the caller's own colour. */
90
+ export declare const ACCENT_EDGE_COLOR_CLASS = "before:shadow-[inset_3px_0_0_var(--charcuterie-accent-edge)] rtl:before:shadow-[inset_-3px_0_0_var(--charcuterie-accent-edge)]";
91
+ export declare const getAccentEdgeClassName: (accentEdge: CardAccentEdge) => string;
92
+ /**
93
+ * The inline style an explicit colour needs, and nothing when the
94
+ * colour came from an index.
95
+ *
96
+ * Returns `undefined` rather than `{}` so a card with a categorical
97
+ * edge and no `style` of its own renders no `style` attribute at
98
+ * all.
99
+ */
100
+ export declare const getAccentEdgeStyle: (accentEdge: CardAccentEdge) => Record<string, string> | undefined;
101
+ //# sourceMappingURL=cardAccentEdge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cardAccentEdge.d.ts","sourceRoot":"","sources":["../../src/Card/cardAccentEdge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AAE3D;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,cAAc,GACtB;IAAE,WAAW,EAAE,gBAAgB,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAA;CAAE,GAChD;IAAE,WAAW,CAAC,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAA;AAE1C;;;;;;;;;GASG;AACH,eAAO,MAAM,0BAA0B,8BACV,CAAA;AAE7B;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,oHACgF,CAAA;AAEnH;;;;;;;;GAQG;AACH,eAAO,MAAM,6BAA6B,EAAE,MAAM,CAChD,gBAAgB,EAChB,MAAM,CAYP,CAAA;AAED,qDAAqD;AACrD,eAAO,MAAM,uBAAuB,mIAC8F,CAAA;AAElI,eAAO,MAAM,sBAAsB,GACjC,YAAY,cAAc,KACzB,MAOC,CAAA;AAEJ;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,GAC7B,YAAY,cAAc,KACzB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAG4B,CAAA"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * A coloured bar down a card's leading edge — and the reason it is
3
+ * a pseudo-element rather than a border.
4
+ *
5
+ * Three apps had grown this shape independently and all three drew
6
+ * it as a straight border beside a rounded box, so the bar ran past
7
+ * the curve and stopped square while the card it belonged to was
8
+ * round. Folio put `border-inline-start` on a WRAPPER around the
9
+ * card; mail-sifter puts `borderInlineStartWidth: 4` on a
10
+ * `rounded-xl` anchor; spoolbuddy writes `rounded-lg border-l-3`.
11
+ * A border is painted on the border box, so none of them can follow
12
+ * a corner — the notch is not a bug in any one app, it is what that
13
+ * technique does.
14
+ *
15
+ * A pseudo-element overlays the card and takes
16
+ * `border-radius: inherit`, so the bar follows whatever radius the
17
+ * card already has and nobody states a radius twice.
18
+ *
19
+ * ⚠️ **The shadow goes on the pseudo-element, never on the card.**
20
+ * `Card` carries `shadow-low` from the elevation scale, and an app
21
+ * stylesheet is unlayered while Tailwind's utilities sit in
22
+ * `@layer utilities` — so a `box-shadow` written at the call site
23
+ * outranks the utility and takes the card's elevation away with it.
24
+ * That is not hypothetical; it is the version of this fix that was
25
+ * written first.
26
+ *
27
+ * ⚠️ **Not a 3px-wide pseudo-element with a rounded leading edge.**
28
+ * A `border-radius` of `0.5rem` on a 3px-wide box is clamped by the
29
+ * browser to fit, so it caps the bar instead of following the
30
+ * card's curve.
31
+ *
32
+ * ⚠️ **`box-shadow` has no logical form**, so the offset is
33
+ * physical and the `rtl:` variant is what carries the bar to the
34
+ * other side. A single `inset 3px` would put it on the left of an
35
+ * Arabic page, which is the trailing edge there.
36
+ */
37
+ /**
38
+ * The custom property an explicit colour is threaded through.
39
+ *
40
+ * A property rather than an inline `box-shadow`, because the shadow
41
+ * string has to stay a COMPLETE literal in the source for Tailwind
42
+ * to generate it at all. One literal reading one variable covers
43
+ * every colour an app can compute; interpolating the colour into
44
+ * the class name would generate nothing, paint nothing, and report
45
+ * nothing.
46
+ */
47
+ export const ACCENT_EDGE_COLOR_PROPERTY = "--charcuterie-accent-edge";
48
+ /**
49
+ * The overlay itself. Colour arrives separately.
50
+ *
51
+ * `pointer-events: none` is load-bearing rather than tidy: this box
52
+ * covers the whole card, including every link and button in it.
53
+ */
54
+ export const ACCENT_EDGE_BASE_CLASS = "relative before:pointer-events-none before:absolute before:inset-0 before:rounded-[inherit] before:content-['']";
55
+ /**
56
+ * Ten indices, written out in full, for the reason
57
+ * `categoricalStyles.ts` opens with: Tailwind scans source text for
58
+ * COMPLETE class strings, so a template literal generates nothing
59
+ * at all and the bar renders invisible with no error and no failing
60
+ * test. `tailwindCandidates.test.ts` compiles every literal in this
61
+ * package through the real Tailwind, which is the something that
62
+ * checks.
63
+ */
64
+ export const ACCENT_EDGE_CATEGORICAL_CLASS = {
65
+ 1: "before:shadow-[inset_3px_0_0_var(--color-categorical-1-solid)] rtl:before:shadow-[inset_-3px_0_0_var(--color-categorical-1-solid)]",
66
+ 2: "before:shadow-[inset_3px_0_0_var(--color-categorical-2-solid)] rtl:before:shadow-[inset_-3px_0_0_var(--color-categorical-2-solid)]",
67
+ 3: "before:shadow-[inset_3px_0_0_var(--color-categorical-3-solid)] rtl:before:shadow-[inset_-3px_0_0_var(--color-categorical-3-solid)]",
68
+ 4: "before:shadow-[inset_3px_0_0_var(--color-categorical-4-solid)] rtl:before:shadow-[inset_-3px_0_0_var(--color-categorical-4-solid)]",
69
+ 5: "before:shadow-[inset_3px_0_0_var(--color-categorical-5-solid)] rtl:before:shadow-[inset_-3px_0_0_var(--color-categorical-5-solid)]",
70
+ 6: "before:shadow-[inset_3px_0_0_var(--color-categorical-6-solid)] rtl:before:shadow-[inset_-3px_0_0_var(--color-categorical-6-solid)]",
71
+ 7: "before:shadow-[inset_3px_0_0_var(--color-categorical-7-solid)] rtl:before:shadow-[inset_-3px_0_0_var(--color-categorical-7-solid)]",
72
+ 8: "before:shadow-[inset_3px_0_0_var(--color-categorical-8-solid)] rtl:before:shadow-[inset_-3px_0_0_var(--color-categorical-8-solid)]",
73
+ 9: "before:shadow-[inset_3px_0_0_var(--color-categorical-9-solid)] rtl:before:shadow-[inset_-3px_0_0_var(--color-categorical-9-solid)]",
74
+ 10: "before:shadow-[inset_3px_0_0_var(--color-categorical-10-solid)] rtl:before:shadow-[inset_-3px_0_0_var(--color-categorical-10-solid)]",
75
+ };
76
+ /** The same bar, reading the caller's own colour. */
77
+ export const ACCENT_EDGE_COLOR_CLASS = "before:shadow-[inset_3px_0_0_var(--charcuterie-accent-edge)] rtl:before:shadow-[inset_-3px_0_0_var(--charcuterie-accent-edge)]";
78
+ export const getAccentEdgeClassName = (accentEdge) => `${ACCENT_EDGE_BASE_CLASS} ${accentEdge.categorical == null
79
+ ? ACCENT_EDGE_COLOR_CLASS
80
+ : ACCENT_EDGE_CATEGORICAL_CLASS[accentEdge.categorical]}`;
81
+ /**
82
+ * The inline style an explicit colour needs, and nothing when the
83
+ * colour came from an index.
84
+ *
85
+ * Returns `undefined` rather than `{}` so a card with a categorical
86
+ * edge and no `style` of its own renders no `style` attribute at
87
+ * all.
88
+ */
89
+ export const getAccentEdgeStyle = (accentEdge) => accentEdge.color == null
90
+ ? undefined
91
+ : { [ACCENT_EDGE_COLOR_PROPERTY]: accentEdge.color };
92
+ //# sourceMappingURL=cardAccentEdge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cardAccentEdge.js","sourceRoot":"","sources":["../../src/Card/cardAccentEdge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAwBH;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,0BAA0B,GACrC,2BAA2B,CAAA;AAE7B;;;;;GAKG;AACH,MAAM,CAAC,MAAM,sBAAsB,GACjC,iHAAiH,CAAA;AAEnH;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAGtC;IACF,CAAC,EAAE,oIAAoI;IACvI,CAAC,EAAE,oIAAoI;IACvI,CAAC,EAAE,oIAAoI;IACvI,CAAC,EAAE,oIAAoI;IACvI,CAAC,EAAE,oIAAoI;IACvI,CAAC,EAAE,oIAAoI;IACvI,CAAC,EAAE,oIAAoI;IACvI,CAAC,EAAE,oIAAoI;IACvI,CAAC,EAAE,oIAAoI;IACvI,EAAE,EAAE,sIAAsI;CAC3I,CAAA;AAED,qDAAqD;AACrD,MAAM,CAAC,MAAM,uBAAuB,GAClC,gIAAgI,CAAA;AAElI,MAAM,CAAC,MAAM,sBAAsB,GAAG,CACpC,UAA0B,EAClB,EAAE,CACV,GAAG,sBAAsB,IACvB,UAAU,CAAC,WAAW,IAAI,IAAI;IAC5B,CAAC,CAAC,uBAAuB;IACzB,CAAC,CAAC,6BAA6B,CAC3B,UAAU,CAAC,WAAW,CAE9B,EAAE,CAAA;AAEJ;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,UAA0B,EACU,EAAE,CACtC,UAAU,CAAC,KAAK,IAAI,IAAI;IACtB,CAAC,CAAC,SAAS;IACX,CAAC,CAAC,EAAE,CAAC,0BAA0B,CAAC,EAAE,UAAU,CAAC,KAAK,EAAE,CAAA"}
package/dist/index.d.ts CHANGED
@@ -57,6 +57,7 @@ export type { ButtonLinkProps } from "./ButtonLink/ButtonLink.tsx";
57
57
  export { ButtonLink } from "./ButtonLink/ButtonLink.tsx";
58
58
  export type { CardPadding, CardProps, CardSurface, } from "./Card/Card.tsx";
59
59
  export { Card } from "./Card/Card.tsx";
60
+ export type { CardAccentEdge } from "./Card/cardAccentEdge.ts";
60
61
  export type { CheckboxProps } from "./Checkbox/Checkbox.tsx";
61
62
  export { Checkbox } from "./Checkbox/Checkbox.tsx";
62
63
  export type { ColorSchemeSwitcherProps } from "./ColorSchemeSwitcher/ColorSchemeSwitcher.tsx";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAOH,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA2B,CAAA;AAErD,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAiC,CAAA;AAE9D,OAAO,EACL,aAAa,EACb,wBAAwB,EACxB,0BAA0B,EAC1B,iCAAiC,EACjC,gBAAgB,EAChB,uBAAuB,GACxB,MAAM,iCAAiC,CAAA;AAKxC,OAAO,EACL,6BAA6B,EAC7B,gBAAgB,EAChB,kBAAkB,EAClB,yBAAyB,GAC1B,MAAM,sCAAsC,CAAA;AAK7C,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAmB,CAAA;AAEzC,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAmB,CAAA;AAGzC,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA+B,CAAA;AAK3D,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAmB,CAAA;AASzC,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,mBAAmB,EACnB,cAAc,GACf,MAAM,sBAAsB,CAAA;AAE7B,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAqB,CAAA;AAE5C,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA6B,CAAA;AAMxD,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAiB,CAAA;AAEtC,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAyB,CAAA;AAElD,OAAO,EAAE,mBAAmB,EAAE,MAAM,8CAA+C,CAAA;AAKnF,OAAO,EAAE,iBAAiB,EAAE,MAAM,0CAA2C,CAAA;AAE7E,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAyB,CAAA;AAClD,OAAO,EACL,4BAA4B,EAC5B,yBAAyB,EACzB,uBAAuB,EACvB,4BAA4B,GAC7B,MAAM,wBAAwB,CAAA;AAE/B,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAClB,cAAc,EACd,mBAAmB,EACnB,uBAAuB,EACvB,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,oBAAoB,CAAA;AAO3B,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA2B,CAAA;AAErD,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA6B,CAAA;AAExD,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAA;AAMlE,OAAO,EACL,2BAA2B,EAC3B,cAAc,GACf,MAAM,gCAAgC,CAAA;AAMvC,OAAO,EACL,OAAO,EACP,SAAS,EACT,cAAc,EACd,iBAAiB,EACjB,eAAe,EACf,YAAY,EACZ,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,aAAa,EACb,YAAY,EACZ,mBAAmB,EACnB,gBAAgB,EAChB,iBAAiB,EACjB,aAAa,EACb,yBAAyB,EACzB,UAAU,EACV,eAAe,EACf,YAAY,EACZ,SAAS,GACV,MAAM,2BAA2B,CAAA;AAKlC,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAqB,CAAA;AAK5C,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA6B,CAAA;AAExD,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAmB,CAAA;AAEzC,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAwB,CAAA;AAEnD,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAiC,CAAA;AAE9D,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAqB,CAAA;AAE5C,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA6B,CAAA;AAExD,OAAO,EACL,mBAAmB,EACnB,cAAc,EACd,gBAAgB,EAChB,uBAAuB,EACvB,oBAAoB,EACpB,kBAAkB,EAClB,uBAAuB,GACxB,MAAM,mBAAmB,CAAA;AAE1B,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAyB,CAAA;AAKlD,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAuB,CAAA;AAK/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,8CAA+C,CAAA;AAKnF,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA2B,CAAA;AAErD,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAiB,CAAA;AAKtC,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAqC,CAAA;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAA;AAOtE,OAAO,EACL,WAAW,EACX,eAAe,GAChB,MAAM,mCAAmC,CAAA;AAK1C,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA2B,CAAA;AAErD,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAA;AAK7D,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAiB,CAAA;AAEtC,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAmB,CAAA;AAKzC,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAqB,CAAA;AAE5C,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAuB,CAAA;AAK/C,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA+B,CAAA;AAE3D,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,GAChB,MAAM,gCAAgC,CAAA;AAKvC,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAiC,CAAA;AAK9D,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA6B,CAAA;AAMxD,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAiB,CAAA;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA6B,CAAA;AACxD,OAAO,EACL,kBAAkB,EAClB,aAAa,GACd,MAAM,oCAAqC,CAAA;AAK5C,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAA;AAK5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wCAAyC,CAAA;AAY1E,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAqB,CAAA;AAM5C,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAmB,CAAA;AAKzC,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAyB,CAAA;AAKlD,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAqB,CAAA;AAK5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,8CAA+C,CAAA;AAEnF,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAuB,CAAA;AAO/C,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAuB,CAAA;AAM/C,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAqB,CAAA;AAE5C,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAqB,CAAA;AAE5C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAC/C,OAAO,EACL,cAAc,EACd,aAAa,EACb,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,mBAAmB,CAAA;AAO1B,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAiB,CAAA;AAKtC,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAyB,CAAA;AAElD,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAmB,CAAA;AAKzC,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAyB,CAAA;AAErD,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAA;AAOpE,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAuB,CAAA;AAE/C,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAuB,CAAA;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAA;AAElE,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAuC,CAAA;AAEvE,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAqC,CAAA"}
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": "3.10.0",
3
+ "version": "3.11.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",
package/src/Card/Card.mdx CHANGED
@@ -51,3 +51,24 @@ The header stacks below `--cq-sm` and sits on one row above it, and the containe
51
51
  cannot tell apart, and it is where the fleet's poster grids look wrong today.
52
52
 
53
53
  <Canvas of={CardStories.Responsive} />
54
+
55
+ ## The accent edge follows the corner
56
+
57
+ `accentEdge` draws a coloured bar down the leading edge. `{ categorical: 3 }` is a colour a
58
+ user picked, from the ten-wide contrast-audited family; `{ color }` is one the app computed,
59
+ for the case where ten indices are not enough — Folio hashes a repo's name so a repo added
60
+ tomorrow already has a hue and nobody maintains a palette.
61
+
62
+ > **It is a pseudo-element, not a border, and that is the whole point.** Three apps grew this
63
+ > shape independently and all three drew a straight border beside a rounded box, so the bar
64
+ > ran past the curve and stopped square while the card was round. A border is painted on the
65
+ > border box; it cannot follow a corner. The overlay here takes `border-radius: inherit`, so
66
+ > the bar reads the radius off whatever card it is on and nobody states one twice.
67
+
68
+ Two shapes this deliberately is not. **Not `box-shadow: inset` on the card itself** — `Card`
69
+ carries `shadow-low` from the elevation scale, and a `box-shadow` at the call site outranks
70
+ that utility and takes the elevation with it. **Not a 3px-wide pseudo-element with a rounded
71
+ leading edge** — a `0.5rem` radius on a 3px box is clamped to fit, so it caps the bar instead
72
+ of following the curve.
73
+
74
+ <Canvas of={CardStories.AccentEdge} />
@@ -13,12 +13,18 @@ import { IconButton } from "../IconButton/IconButton.tsx"
13
13
  import { SettingsIcon } from "../icons.storyHelpers.tsx"
14
14
  import { ProgressBar } from "../ProgressBar/ProgressBar.tsx"
15
15
  import { Card, ELEVATION_CLASS } from "./Card.tsx"
16
+ import { ACCENT_EDGE_CATEGORICAL_CLASS } from "./cardAccentEdge.ts"
16
17
 
17
18
  const meta = {
18
19
  title: "Components/Layout/Card",
19
20
  component: Card,
20
21
  parameters: { layout: "padded" },
21
22
  argTypes: {
23
+ // An object union, so an object control is the right one — but
24
+ // it is stated rather than inferred, because docgen's fallback
25
+ // for a type it cannot read is also an object control and the
26
+ // two are indistinguishable in the panel.
27
+ accentEdge: { control: "object" },
22
28
  elevation: toStoryChoice(
23
29
  Object.keys(
24
30
  ELEVATION_CLASS,
@@ -205,3 +211,88 @@ export const Interactive: Story = {
205
211
  </div>
206
212
  ),
207
213
  }
214
+
215
+ /**
216
+ * The leading edge, and the two answers the fleet has for what
217
+ * colour it is.
218
+ *
219
+ * A **categorical index** is a colour a user picked — Docket's
220
+ * project colours come from this ten-wide family, and every pair in
221
+ * it is contrast-audited. An explicit **colour** is one the app
222
+ * computed: Folio hashes a repo's name so a repo added tomorrow
223
+ * already has a hue and nobody maintains a palette, which is 360
224
+ * answers rather than ten.
225
+ *
226
+ * Both bars follow the card's own corner, because the treatment
227
+ * inherits its radius instead of naming one. Every app that grew
228
+ * this shape by hand drew it as a straight border beside a rounded
229
+ * box, and a border cannot follow a curve.
230
+ */
231
+ export const AccentEdge: Story = {
232
+ args: { children: "Content" },
233
+ render: () => (
234
+ <StorySection title="A categorical index, and an app's own colour. Both take the card's radius.">
235
+ <StoryGrid columns={3}>
236
+ {(
237
+ Object.keys(
238
+ ACCENT_EDGE_CATEGORICAL_CLASS,
239
+ ) as unknown as (keyof typeof ACCENT_EDGE_CATEGORICAL_CLASS)[]
240
+ ).map((index) => (
241
+ <StoryCell
242
+ align="stretch"
243
+ key={index}
244
+ label={`categorical ${index}`}
245
+ >
246
+ <Card
247
+ accentEdge={{
248
+ categorical: Number(index) as 1,
249
+ }}
250
+ heading={`Project ${index}`}
251
+ >
252
+ <p className="text-content-secondary text-sm">
253
+ A colour the user picked.
254
+ </p>
255
+ </Card>
256
+ </StoryCell>
257
+ ))}
258
+
259
+ <StoryCell align="stretch" label="a hashed hue">
260
+ <Card
261
+ accentEdge={{ color: "hsl(287 55% 52%)" }}
262
+ heading="home-assistant"
263
+ >
264
+ <p className="text-content-secondary text-sm">
265
+ A hue hashed from the name, not an index.
266
+ </p>
267
+ </Card>
268
+ </StoryCell>
269
+
270
+ <StoryCell
271
+ align="stretch"
272
+ label="a rounder card, same rule"
273
+ >
274
+ <Card
275
+ accentEdge={{ color: "hsl(24 55% 52%)" }}
276
+ className="rounded-3xl"
277
+ heading="A wider radius"
278
+ >
279
+ <p className="text-content-secondary text-sm">
280
+ The bar reads the radius off the card rather
281
+ than naming one, so an override still lines
282
+ up.
283
+ </p>
284
+ </Card>
285
+ </StoryCell>
286
+
287
+ <StoryCell align="stretch" label="a link inside it">
288
+ <Card
289
+ accentEdge={{ categorical: 4 }}
290
+ heading="Still clickable"
291
+ >
292
+ <Button size="sm">Open</Button>
293
+ </Card>
294
+ </StoryCell>
295
+ </StoryGrid>
296
+ </StorySection>
297
+ ),
298
+ }
@@ -6,7 +6,7 @@ import { mountStory } from "../mountStory.testHelpers.ts"
6
6
  import { expectAgentDrivable } from "../testing/index.ts"
7
7
  import * as stories from "./Card.stories.tsx"
8
8
 
9
- const { AllStates, Default, Interactive } =
9
+ const { AccentEdge, AllStates, Default, Interactive } =
10
10
  composeStories(stories)
11
11
 
12
12
  test("a heading turns the card into a named landmark", async () => {
@@ -54,3 +54,94 @@ test("region scoping disambiguates two identical buttons", async () => {
54
54
  }),
55
55
  ).toHaveAttribute("aria-valuenow", "40")
56
56
  })
57
+
58
+ /**
59
+ * The bar overlays the entire card, links and buttons included, so
60
+ * `pointer-events: none` on it is the difference between a card you
61
+ * can use and one that swallows every click. Driven, not asserted
62
+ * off a class name — the class is what the fix looks like, and this
63
+ * is what it is for.
64
+ */
65
+ test("the accent edge does not swallow a click", async () => {
66
+ const { canvas } = await mountStory(AccentEdge)
67
+
68
+ const open = expectAgentDrivable(canvas, {
69
+ name: "Open",
70
+ role: "button",
71
+ })
72
+
73
+ let isClicked = false
74
+
75
+ open.addEventListener("click", () => {
76
+ isClicked = true
77
+ })
78
+
79
+ open.click()
80
+
81
+ await expect(isClicked).toBe(true)
82
+ })
83
+
84
+ const readRadius = (card: Element, isBar: boolean) =>
85
+ globalThis.getComputedStyle(
86
+ card,
87
+ isBar ? "::before" : undefined,
88
+ ).borderTopLeftRadius
89
+
90
+ /**
91
+ * The radius is INHERITED rather than restated, which is what lets
92
+ * one treatment sit on `rounded-lg`, on `rounded-3xl`, and on
93
+ * whatever an app overrides it to. Computed styles, because a class
94
+ * name is the thing that can be right while the paint is wrong.
95
+ */
96
+ test("the bar takes the card's own radius, whatever it is", async () => {
97
+ const { canvas } = await mountStory(AccentEdge)
98
+
99
+ const wider = expectAgentDrivable(canvas, {
100
+ name: "A wider radius",
101
+ role: "region",
102
+ })
103
+
104
+ const stock = expectAgentDrivable(canvas, {
105
+ name: "Project 1",
106
+ role: "region",
107
+ })
108
+
109
+ await expect(readRadius(wider, true)).toBe(
110
+ readRadius(wider, false),
111
+ )
112
+ await expect(readRadius(stock, true)).toBe(
113
+ readRadius(stock, false),
114
+ )
115
+
116
+ // And the two cards genuinely differ, or the assertions above
117
+ // would pass on a component that hardcoded one radius.
118
+ await expect(readRadius(wider, false)).not.toBe(
119
+ readRadius(stock, false),
120
+ )
121
+ })
122
+
123
+ /**
124
+ * `Card` carries `shadow-low`. The accent edge is a second shadow,
125
+ * and the first version of this fix wrote it onto the card itself —
126
+ * where an unlayered rule outranks the utility and the elevation
127
+ * silently goes away.
128
+ */
129
+ test("the accent edge leaves the card's elevation alone", async () => {
130
+ const { canvas } = await mountStory(AccentEdge)
131
+
132
+ const card = expectAgentDrivable(canvas, {
133
+ name: "Project 1",
134
+ role: "region",
135
+ })
136
+
137
+ const cardShadow =
138
+ globalThis.getComputedStyle(card).boxShadow
139
+ const barShadow = globalThis.getComputedStyle(
140
+ card,
141
+ "::before",
142
+ ).boxShadow
143
+
144
+ await expect(cardShadow).not.toBe("none")
145
+ await expect(cardShadow).not.toContain("inset")
146
+ await expect(barShadow).toContain("inset")
147
+ })
package/src/Card/Card.tsx CHANGED
@@ -9,6 +9,11 @@ import type {
9
9
  } from "react"
10
10
 
11
11
  import { toClassName } from "../toClassName.ts"
12
+ import type { CardAccentEdge } from "./cardAccentEdge.ts"
13
+ import {
14
+ getAccentEdgeClassName,
15
+ getAccentEdgeStyle,
16
+ } from "./cardAccentEdge.ts"
12
17
 
13
18
  export type CardSurface = Extract<
14
19
  SurfaceRole,
@@ -18,6 +23,16 @@ export type CardSurface = Extract<
18
23
  export type CardPadding = "lg" | "md" | "none" | "sm"
19
24
 
20
25
  export type CardProps = ComponentPropsWithRef<"section"> & {
26
+ /**
27
+ * A coloured bar down the leading edge, following the card's own
28
+ * corners.
29
+ *
30
+ * `{ categorical: 3 }` for a colour a user picked; `{ color }`
31
+ * for one an app computed — a hue hashed from a repo's name, say,
32
+ * where ten indices are not enough. See `cardAccentEdge.ts` for
33
+ * why it is a pseudo-element and not a border.
34
+ */
35
+ accentEdge?: CardAccentEdge
21
36
  /** Buttons or a badge, laid out beside the heading. */
22
37
  actions?: ReactNode
23
38
  elevation?: ElevationStep
@@ -79,6 +94,7 @@ const PADDING_CLASS: Record<CardPadding, string> = {
79
94
  * a layout fact rather than a density one.
80
95
  */
81
96
  export const Card = ({
97
+ accentEdge,
82
98
  actions,
83
99
  children,
84
100
  className,
@@ -87,11 +103,25 @@ export const Card = ({
87
103
  heading,
88
104
  headingLevel = 2,
89
105
  padding = "md",
106
+ style,
90
107
  surface = "raised",
91
108
  ...sectionProps
92
109
  }: CardProps): ReactNode => {
93
110
  const headingId = useUniqueId()
94
111
 
112
+ // The caller's own `style` wins. An accent colour is one custom
113
+ // property, and silently dropping whatever else the call site set
114
+ // would be a worse trade than letting it override this one.
115
+ const accentEdgeStyle =
116
+ accentEdge == null
117
+ ? undefined
118
+ : getAccentEdgeStyle(accentEdge)
119
+
120
+ const mergedStyle =
121
+ accentEdgeStyle == null
122
+ ? style
123
+ : { ...accentEdgeStyle, ...style }
124
+
95
125
  const Heading = `h${headingLevel}` as const
96
126
 
97
127
  return (
@@ -108,8 +138,12 @@ export const Card = ({
108
138
  SURFACE_CLASS[surface],
109
139
  ELEVATION_CLASS[elevation],
110
140
  PADDING_CLASS[padding],
141
+ accentEdge == null
142
+ ? undefined
143
+ : getAccentEdgeClassName(accentEdge),
111
144
  className,
112
145
  )}
146
+ style={mergedStyle}
113
147
  >
114
148
  {heading || actions ? (
115
149
  <header className="flex flex-col gap-2 cq-sm:flex-row cq-sm:items-start cq-sm:justify-between">
@@ -0,0 +1,105 @@
1
+ import { describe, expect, test } from "vitest"
2
+
3
+ import {
4
+ ACCENT_EDGE_BASE_CLASS,
5
+ ACCENT_EDGE_CATEGORICAL_CLASS,
6
+ ACCENT_EDGE_COLOR_CLASS,
7
+ ACCENT_EDGE_COLOR_PROPERTY,
8
+ getAccentEdgeClassName,
9
+ getAccentEdgeStyle,
10
+ } from "./cardAccentEdge.ts"
11
+
12
+ describe("getAccentEdgeClassName", () => {
13
+ test("reads a categorical index off the ten-wide family", () => {
14
+ const className = getAccentEdgeClassName({
15
+ categorical: 3,
16
+ })
17
+
18
+ expect(className).toContain(ACCENT_EDGE_BASE_CLASS)
19
+ expect(className).toContain(
20
+ ACCENT_EDGE_CATEGORICAL_CLASS[3],
21
+ )
22
+ })
23
+
24
+ test("threads an app's own colour through one literal", () => {
25
+ const className = getAccentEdgeClassName({
26
+ color: "hsl(210 55% 52%)",
27
+ })
28
+
29
+ expect(className).toContain(ACCENT_EDGE_BASE_CLASS)
30
+ expect(className).toContain(ACCENT_EDGE_COLOR_CLASS)
31
+ })
32
+
33
+ /**
34
+ * The bar overlays the whole card, links and buttons included, so
35
+ * this is the difference between a card you can click and one you
36
+ * cannot.
37
+ */
38
+ test("never eats a pointer", () => {
39
+ expect(
40
+ getAccentEdgeClassName({ categorical: 1 }),
41
+ ).toContain("before:pointer-events-none")
42
+ })
43
+
44
+ /**
45
+ * The card already has a radius; the bar must not restate it.
46
+ * `inherit` is what makes one component work on `rounded-lg`,
47
+ * `rounded-xl` and whatever an app overrides it to.
48
+ */
49
+ test("takes the card's own radius rather than naming one", () => {
50
+ expect(
51
+ getAccentEdgeClassName({ categorical: 1 }),
52
+ ).toContain("before:rounded-[inherit]")
53
+ })
54
+
55
+ /**
56
+ * `box-shadow` has no logical form. Without the `rtl:` twin the
57
+ * bar sits on the left of an Arabic page, which is the trailing
58
+ * edge there.
59
+ */
60
+ test("carries the bar to the other side under rtl", () => {
61
+ for (const className of [
62
+ ...Object.values(ACCENT_EDGE_CATEGORICAL_CLASS),
63
+ ACCENT_EDGE_COLOR_CLASS,
64
+ ]) {
65
+ expect(className).toContain("rtl:before:shadow-")
66
+ expect(className).toContain("inset_-3px")
67
+ }
68
+ })
69
+
70
+ /**
71
+ * Tailwind scans source text for COMPLETE class strings, so an
72
+ * interpolated index generates nothing, paints nothing and
73
+ * reports nothing. This is the cheap half of that guarantee;
74
+ * `tailwindCandidates.test.ts` is the half that compiles them.
75
+ */
76
+ test("names every categorical index in full", () => {
77
+ for (const [index, className] of Object.entries(
78
+ ACCENT_EDGE_CATEGORICAL_CLASS,
79
+ )) {
80
+ expect(className).toContain(
81
+ `var(--color-categorical-${index}-solid)`,
82
+ )
83
+ }
84
+ })
85
+ })
86
+
87
+ describe("getAccentEdgeStyle", () => {
88
+ test("writes one custom property for an app's own colour", () => {
89
+ expect(
90
+ getAccentEdgeStyle({ color: "hsl(210 55% 52%)" }),
91
+ ).toStrictEqual({
92
+ [ACCENT_EDGE_COLOR_PROPERTY]: "hsl(210 55% 52%)",
93
+ })
94
+ })
95
+
96
+ /**
97
+ * `undefined`, not `{}`, so a categorical card renders no `style`
98
+ * attribute at all.
99
+ */
100
+ test("writes nothing when the colour came from an index", () => {
101
+ expect(
102
+ getAccentEdgeStyle({ categorical: 7 }),
103
+ ).toBeUndefined()
104
+ })
105
+ })
@@ -0,0 +1,135 @@
1
+ /**
2
+ * A coloured bar down a card's leading edge — and the reason it is
3
+ * a pseudo-element rather than a border.
4
+ *
5
+ * Three apps had grown this shape independently and all three drew
6
+ * it as a straight border beside a rounded box, so the bar ran past
7
+ * the curve and stopped square while the card it belonged to was
8
+ * round. Folio put `border-inline-start` on a WRAPPER around the
9
+ * card; mail-sifter puts `borderInlineStartWidth: 4` on a
10
+ * `rounded-xl` anchor; spoolbuddy writes `rounded-lg border-l-3`.
11
+ * A border is painted on the border box, so none of them can follow
12
+ * a corner — the notch is not a bug in any one app, it is what that
13
+ * technique does.
14
+ *
15
+ * A pseudo-element overlays the card and takes
16
+ * `border-radius: inherit`, so the bar follows whatever radius the
17
+ * card already has and nobody states a radius twice.
18
+ *
19
+ * ⚠️ **The shadow goes on the pseudo-element, never on the card.**
20
+ * `Card` carries `shadow-low` from the elevation scale, and an app
21
+ * stylesheet is unlayered while Tailwind's utilities sit in
22
+ * `@layer utilities` — so a `box-shadow` written at the call site
23
+ * outranks the utility and takes the card's elevation away with it.
24
+ * That is not hypothetical; it is the version of this fix that was
25
+ * written first.
26
+ *
27
+ * ⚠️ **Not a 3px-wide pseudo-element with a rounded leading edge.**
28
+ * A `border-radius` of `0.5rem` on a 3px-wide box is clamped by the
29
+ * browser to fit, so it caps the bar instead of following the
30
+ * card's curve.
31
+ *
32
+ * ⚠️ **`box-shadow` has no logical form**, so the offset is
33
+ * physical and the `rtl:` variant is what carries the bar to the
34
+ * other side. A single `inset 3px` would put it on the left of an
35
+ * Arabic page, which is the trailing edge there.
36
+ */
37
+
38
+ import type { CategoricalIndex } from "@charcuterie/tokens"
39
+
40
+ /**
41
+ * Which colour the bar takes.
42
+ *
43
+ * Two arms, because the fleet has two answers and neither is wrong.
44
+ * Docket picks a **categorical index** — a colour a user chose for
45
+ * a project, from the ten-wide contrast-audited family. Folio and
46
+ * mail-sifter derive a **hue from a name hash**, so a repo added
47
+ * tomorrow already has a colour and nobody maintains a palette;
48
+ * that is 360 answers, not ten, and it cannot be an index.
49
+ *
50
+ * `intent` is deliberately absent. An intent is a claim the design
51
+ * system makes — `danger` says what happens if you press the thing
52
+ * — and no card in this fleet wants its edge to make one. When one
53
+ * does, that is a third arm and a decision record, not a guess
54
+ * made here.
55
+ */
56
+ export type CardAccentEdge =
57
+ | { categorical: CategoricalIndex; color?: never }
58
+ | { categorical?: never; color: string }
59
+
60
+ /**
61
+ * The custom property an explicit colour is threaded through.
62
+ *
63
+ * A property rather than an inline `box-shadow`, because the shadow
64
+ * string has to stay a COMPLETE literal in the source for Tailwind
65
+ * to generate it at all. One literal reading one variable covers
66
+ * every colour an app can compute; interpolating the colour into
67
+ * the class name would generate nothing, paint nothing, and report
68
+ * nothing.
69
+ */
70
+ export const ACCENT_EDGE_COLOR_PROPERTY =
71
+ "--charcuterie-accent-edge"
72
+
73
+ /**
74
+ * The overlay itself. Colour arrives separately.
75
+ *
76
+ * `pointer-events: none` is load-bearing rather than tidy: this box
77
+ * covers the whole card, including every link and button in it.
78
+ */
79
+ export const ACCENT_EDGE_BASE_CLASS =
80
+ "relative before:pointer-events-none before:absolute before:inset-0 before:rounded-[inherit] before:content-['']"
81
+
82
+ /**
83
+ * Ten indices, written out in full, for the reason
84
+ * `categoricalStyles.ts` opens with: Tailwind scans source text for
85
+ * COMPLETE class strings, so a template literal generates nothing
86
+ * at all and the bar renders invisible with no error and no failing
87
+ * test. `tailwindCandidates.test.ts` compiles every literal in this
88
+ * package through the real Tailwind, which is the something that
89
+ * checks.
90
+ */
91
+ export const ACCENT_EDGE_CATEGORICAL_CLASS: Record<
92
+ CategoricalIndex,
93
+ string
94
+ > = {
95
+ 1: "before:shadow-[inset_3px_0_0_var(--color-categorical-1-solid)] rtl:before:shadow-[inset_-3px_0_0_var(--color-categorical-1-solid)]",
96
+ 2: "before:shadow-[inset_3px_0_0_var(--color-categorical-2-solid)] rtl:before:shadow-[inset_-3px_0_0_var(--color-categorical-2-solid)]",
97
+ 3: "before:shadow-[inset_3px_0_0_var(--color-categorical-3-solid)] rtl:before:shadow-[inset_-3px_0_0_var(--color-categorical-3-solid)]",
98
+ 4: "before:shadow-[inset_3px_0_0_var(--color-categorical-4-solid)] rtl:before:shadow-[inset_-3px_0_0_var(--color-categorical-4-solid)]",
99
+ 5: "before:shadow-[inset_3px_0_0_var(--color-categorical-5-solid)] rtl:before:shadow-[inset_-3px_0_0_var(--color-categorical-5-solid)]",
100
+ 6: "before:shadow-[inset_3px_0_0_var(--color-categorical-6-solid)] rtl:before:shadow-[inset_-3px_0_0_var(--color-categorical-6-solid)]",
101
+ 7: "before:shadow-[inset_3px_0_0_var(--color-categorical-7-solid)] rtl:before:shadow-[inset_-3px_0_0_var(--color-categorical-7-solid)]",
102
+ 8: "before:shadow-[inset_3px_0_0_var(--color-categorical-8-solid)] rtl:before:shadow-[inset_-3px_0_0_var(--color-categorical-8-solid)]",
103
+ 9: "before:shadow-[inset_3px_0_0_var(--color-categorical-9-solid)] rtl:before:shadow-[inset_-3px_0_0_var(--color-categorical-9-solid)]",
104
+ 10: "before:shadow-[inset_3px_0_0_var(--color-categorical-10-solid)] rtl:before:shadow-[inset_-3px_0_0_var(--color-categorical-10-solid)]",
105
+ }
106
+
107
+ /** The same bar, reading the caller's own colour. */
108
+ export const ACCENT_EDGE_COLOR_CLASS =
109
+ "before:shadow-[inset_3px_0_0_var(--charcuterie-accent-edge)] rtl:before:shadow-[inset_-3px_0_0_var(--charcuterie-accent-edge)]"
110
+
111
+ export const getAccentEdgeClassName = (
112
+ accentEdge: CardAccentEdge,
113
+ ): string =>
114
+ `${ACCENT_EDGE_BASE_CLASS} ${
115
+ accentEdge.categorical == null
116
+ ? ACCENT_EDGE_COLOR_CLASS
117
+ : ACCENT_EDGE_CATEGORICAL_CLASS[
118
+ accentEdge.categorical
119
+ ]
120
+ }`
121
+
122
+ /**
123
+ * The inline style an explicit colour needs, and nothing when the
124
+ * colour came from an index.
125
+ *
126
+ * Returns `undefined` rather than `{}` so a card with a categorical
127
+ * edge and no `style` of its own renders no `style` attribute at
128
+ * all.
129
+ */
130
+ export const getAccentEdgeStyle = (
131
+ accentEdge: CardAccentEdge,
132
+ ): Record<string, string> | undefined =>
133
+ accentEdge.color == null
134
+ ? undefined
135
+ : { [ACCENT_EDGE_COLOR_PROPERTY]: accentEdge.color }
package/src/index.ts CHANGED
@@ -98,6 +98,7 @@ export type {
98
98
  CardSurface,
99
99
  } from "./Card/Card.tsx"
100
100
  export { Card } from "./Card/Card.tsx"
101
+ export type { CardAccentEdge } from "./Card/cardAccentEdge.ts"
101
102
  export type { CheckboxProps } from "./Checkbox/Checkbox.tsx"
102
103
  export { Checkbox } from "./Checkbox/Checkbox.tsx"
103
104
  export type { ColorSchemeSwitcherProps } from "./ColorSchemeSwitcher/ColorSchemeSwitcher.tsx"