@danxbot/ui 15.33.4 → 15.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,62 @@
1
+ /**
2
+ * The vocabulary of the document-level display preferences, and the one way a
3
+ * value is written onto `<html>`.
4
+ *
5
+ * DX-4075: REACT-FREE ON PURPOSE. `preferences.ts` holds the hooks, so it imports
6
+ * React; `@danxbot/ui/pure` may not reach React (`pure-entry.test.ts`). The framed
7
+ * side of `SandboxedFrame` (`designFrameClient`) has to apply the host's
8
+ * appearance with the very same write the host used and accept exactly the same
9
+ * values, so the unions, the value lists and `applyPreference` live here, imported
10
+ * by both. Two copies would be two chances for the host and the frame to drift.
11
+ */
12
+ /**
13
+ * Writes one preference onto `<html>` with document-wide motion suspended for
14
+ * the duration of the change.
15
+ *
16
+ * WHY THIS IS NOT JUST `setAttribute`. Colour transitions are a foundation in
17
+ * this system: every element has one. That is right for an interaction — a
18
+ * control easing as you hover it — and wrong for a preference, because
19
+ * switching theme changes the computed colour of EVERY element at once.
20
+ * Measured on this demo: 2,360 transitions started simultaneously and the page
21
+ * took **957ms** to settle, 1,560ms on the chat route, for a token whose
22
+ * duration is 110ms. A theme switch should be a cut, not a dissolve; what it
23
+ * actually looked like was the whole document struggling.
24
+ *
25
+ * `--motion-scale: 0` is how it is suspended, rather than a blanket
26
+ * `transition: none !important`. Every duration in the system is already
27
+ * pre-multiplied by that scalar, so zeroing it turns them all off through the
28
+ * layer that exists for the purpose, overrides nothing a component declared,
29
+ * and cannot be forgotten by a component author.
30
+ *
31
+ * THE FORCED READ IS LOAD-BEARING. Style is normally recalculated once, after
32
+ * this function has returned — by which time the attribute is gone and the
33
+ * durations are back. Reading a computed value flushes the recalculation
34
+ * synchronously, so the new colours are committed WHILE durations are still
35
+ * zero, and no transition is ever started. Delete that line and the suspension
36
+ * silently does nothing at all, which is why `audit:motion` measures the settle
37
+ * time rather than the presence of the attribute.
38
+ */
39
+ export declare function applyPreference(attribute: string, value: string): void;
40
+ export type Theme = "light" | "dark";
41
+ export declare const THEMES: readonly ["light", "dark"];
42
+ export type UiScale = "sm" | "md" | "lg";
43
+ export declare const SCALES: readonly ["sm", "md", "lg"];
44
+ /**
45
+ * `design` is the palette as drawn; `aa` raises every token to the 4.5:1 floor.
46
+ *
47
+ * Opt-IN, not enforced, because enforcing the floor everywhere flattens the
48
+ * hierarchy for everyone: de-emphasised text stops being de-emphasised, and in
49
+ * this palette light-theme tertiary collapsed onto the same ramp step as
50
+ * secondary. A floor is a floor — reachable in one click by anyone who needs
51
+ * it, not a target that drags the whole design up to meet it.
52
+ */
53
+ export type ContrastPreference = "design" | "aa";
54
+ export declare const CONTRAST: readonly ["design", "aa"];
55
+ /**
56
+ * `system` is a real third state, not a synonym for "full": it means defer to
57
+ * the OS, which is what most people want and what the OS-level preference
58
+ * exists to express. Collapsing it into a boolean would make an app-level
59
+ * control that says "full" override a user who set reduced motion system-wide.
60
+ */
61
+ export type MotionPreference = "system" | "full" | "reduced";
62
+ export declare const MOTION: readonly ["system", "full", "reduced"];
@@ -1,78 +1,19 @@
1
- /**
2
- * Document-level display preferences.
3
- *
4
- * All three of theme, size scale and motion work the same way: a value lives on
5
- * `<html data-*>`, CSS reads it, and localStorage remembers it. Writing that
6
- * three times would be three chances to diverge — so it is written once and
7
- * specialised below.
8
- *
9
- * WHY `<html>` AND NOT REACT CONTEXT: the value has to reach plain CSS, not
10
- * just components. Portalled content (dialogs, popovers, toasts) renders
11
- * outside the React tree that would hold the context, and a preference that
12
- * fails on exactly the overlay layers is worse than no preference at all.
13
- */
14
- /**
15
- * Writes one preference onto `<html>` with document-wide motion suspended for
16
- * the duration of the change.
17
- *
18
- * WHY THIS IS NOT JUST `setAttribute`. Colour transitions are a foundation in
19
- * this system: every element has one. That is right for an interaction — a
20
- * control easing as you hover it — and wrong for a preference, because
21
- * switching theme changes the computed colour of EVERY element at once.
22
- * Measured on this demo: 2,360 transitions started simultaneously and the page
23
- * took **957ms** to settle, 1,560ms on the chat route, for a token whose
24
- * duration is 110ms. A theme switch should be a cut, not a dissolve; what it
25
- * actually looked like was the whole document struggling.
26
- *
27
- * `--motion-scale: 0` is how it is suspended, rather than a blanket
28
- * `transition: none !important`. Every duration in the system is already
29
- * pre-multiplied by that scalar, so zeroing it turns them all off through the
30
- * layer that exists for the purpose, overrides nothing a component declared,
31
- * and cannot be forgotten by a component author.
32
- *
33
- * THE FORCED READ IS LOAD-BEARING. Style is normally recalculated once, after
34
- * this function has returned — by which time the attribute is gone and the
35
- * durations are back. Reading a computed value flushes the recalculation
36
- * synchronously, so the new colours are committed WHILE durations are still
37
- * zero, and no transition is ever started. Delete that line and the suspension
38
- * silently does nothing at all, which is why `audit:motion` measures the settle
39
- * time rather than the presence of the attribute.
40
- */
41
- export declare function applyPreference(attribute: string, value: string): void;
42
- export type Theme = "light" | "dark";
1
+ import { type ContrastPreference, type MotionPreference, type Theme, type UiScale } from "./preference-values";
43
2
  export declare function useTheme(): {
44
3
  theme: Theme;
45
4
  setTheme: import("react").Dispatch<import("react").SetStateAction<Theme>>;
46
5
  toggle: () => void;
47
6
  };
48
- export type UiScale = "sm" | "md" | "lg";
49
7
  export declare function useUiScale(): {
50
8
  scale: UiScale;
51
9
  setScale: import("react").Dispatch<import("react").SetStateAction<UiScale>>;
52
10
  cycle: () => void;
53
11
  };
54
- /**
55
- * `design` is the palette as drawn; `aa` raises every token to the 4.5:1 floor.
56
- *
57
- * Opt-IN, not enforced, because enforcing the floor everywhere flattens the
58
- * hierarchy for everyone: de-emphasised text stops being de-emphasised, and in
59
- * this palette light-theme tertiary collapsed onto the same ramp step as
60
- * secondary. A floor is a floor — reachable in one click by anyone who needs
61
- * it, not a target that drags the whole design up to meet it.
62
- */
63
- export type ContrastPreference = "design" | "aa";
64
12
  export declare function useContrast(): {
65
13
  contrast: ContrastPreference;
66
14
  setContrast: import("react").Dispatch<import("react").SetStateAction<ContrastPreference>>;
67
15
  toggle: () => void;
68
16
  };
69
- /**
70
- * `system` is a real third state, not a synonym for "full": it means defer to
71
- * the OS, which is what most people want and what the OS-level preference
72
- * exists to express. Collapsing it into a boolean would make an app-level
73
- * control that says "full" override a user who set reduced motion system-wide.
74
- */
75
- export type MotionPreference = "system" | "full" | "reduced";
76
17
  export declare function useMotionPreference(): {
77
18
  motion: MotionPreference;
78
19
  setMotion: import("react").Dispatch<import("react").SetStateAction<MotionPreference>>;
@@ -43,3 +43,5 @@ export { formatDate, parseDate, formatDateTime, parseDateTime, type FormatDateTi
43
43
  export { confidenceLevel, CONFIDENCE_LEVEL_LABELS, type ConfidenceLevel } from "./lib/confidence";
44
44
  export { CHART_SERIES_COUNT, CHART_SERIES_TOKENS, CHART_SEQUENTIAL_TOKEN, CHART_SEQUENTIAL_COLOR, chartSeriesColor, } from "./lib/chart-palette";
45
45
  export type { LegalBlock, LegalDocumentValue, LegalSection } from "./lib/legal-document";
46
+ export { designFrameClient } from "./lib/design-frame/client";
47
+ export { DESIGN_FRAME_APPEARANCE, DESIGN_FRAME_READY, DESIGN_FRAME_ERROR, DESIGN_FRAME_ERROR_MAX_LENGTH, type DesignFrameAppearance, type DesignFrameAppearanceMessage, type DesignFrameReadyMessage, type DesignFrameErrorMessage, type DesignFrameInboundMessage, } from "./lib/design-frame/protocol";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danxbot/ui",
3
- "version": "15.33.4",
3
+ "version": "15.35.0",
4
4
  "type": "module",
5
5
  "description": "Danxbot — a domain-agnostic React design system with motion as a first-class primitive.",
6
6
  "license": "MIT",