@juwel-development/design-system 3.4.0 → 3.6.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.
Files changed (38) hide show
  1. package/README.md +28 -0
  2. package/dist/design-system.js +370 -193
  3. package/dist/index.css +1 -1
  4. package/dist/types/Display/Typography/Eyebrow/Eyebrow.d.ts +5 -2
  5. package/dist/types/Display/Typography/H1/H1.d.ts +5 -2
  6. package/dist/types/Display/Typography/H2/H2.d.ts +5 -2
  7. package/dist/types/Display/Typography/H3/H3.d.ts +5 -2
  8. package/dist/types/Display/Typography/H4/H4.d.ts +5 -2
  9. package/dist/types/Display/Typography/H5/H5.d.ts +5 -2
  10. package/dist/types/Display/Typography/H6/H6.d.ts +5 -2
  11. package/dist/types/Display/Typography/Note/Note.d.ts +5 -2
  12. package/dist/types/Display/Typography/P/P.d.ts +5 -2
  13. package/dist/types/Display/Typography/Prose/Prose.d.ts +6 -3
  14. package/dist/types/Layout/Dialog/Dialog.d.ts +104 -0
  15. package/dist/types/Layout/Dialog/DialogCompositionError.d.ts +3 -0
  16. package/dist/types/Layout/Dialog/DialogNamingError.d.ts +3 -0
  17. package/dist/types/Theme/Palette.d.ts +19 -2
  18. package/dist/types/index.d.ts +1 -0
  19. package/package.json +1 -1
  20. package/src/Display/Typography/Eyebrow/Eyebrow.tsx +12 -2
  21. package/src/Display/Typography/H1/H1.tsx +12 -2
  22. package/src/Display/Typography/H2/H2.tsx +12 -2
  23. package/src/Display/Typography/H3/H3.tsx +12 -2
  24. package/src/Display/Typography/H4/H4.tsx +12 -2
  25. package/src/Display/Typography/H5/H5.tsx +12 -2
  26. package/src/Display/Typography/H6/H6.tsx +12 -2
  27. package/src/Display/Typography/Note/Note.tsx +12 -2
  28. package/src/Display/Typography/P/P.tsx +12 -2
  29. package/src/Display/Typography/Prose/Prose.tsx +13 -3
  30. package/src/Layout/Dialog/Dialog.tsx +478 -0
  31. package/src/Layout/Dialog/DialogCompositionError.ts +6 -0
  32. package/src/Layout/Dialog/DialogNamingError.ts +8 -0
  33. package/src/Theme/Palette.ts +27 -5
  34. package/src/Theme/renderTokens.ts +31 -3
  35. package/src/index.ts +1 -0
  36. package/src/tokens.css +23 -3
  37. package/src/tokens.dark.css +19 -0
  38. package/src/tokens.light.css +22 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@juwel-development/design-system",
3
- "version": "3.4.0",
3
+ "version": "3.6.0",
4
4
  "type": "module",
5
5
  "description": "Shared design system: tokens and components.",
6
6
  "license": "MIT",
@@ -10,7 +10,14 @@ import type { FunctionComponent, ReactNode } from 'react';
10
10
  // semantic token re-pointed by `.dark`, so no variant carries a `dark:` class.
11
11
  const eyebrow = cva('font-secondary text-label tracking-label font-medium', {
12
12
  variants: {
13
- color: { foreground: 'text-foreground', muted: 'text-muted' },
13
+ color: {
14
+ foreground: 'text-foreground',
15
+ muted: 'text-muted',
16
+ success: 'text-success',
17
+ warning: 'text-warning',
18
+ error: 'text-error',
19
+ info: 'text-info',
20
+ },
14
21
  },
15
22
  defaultVariants: { color: 'muted' },
16
23
  });
@@ -28,12 +35,15 @@ interface IEyebrowProps extends VariantProps<typeof eyebrow> {
28
35
  * @Guarantees — enforced on every render
29
36
  * - Renders a `p`, reading `--font-secondary`, sized by `--text-label` and tracked by
30
37
  * `--tracking-label`, at weight 500.
31
- * - `color` selects the `muted` (default) or `foreground` role; nothing else paints text.
38
+ * - `color` selects `muted` (default), `foreground`, `success`, `warning`, `error` or `info`;
39
+ * nothing else paints text. A status tone changes colour only and adds no announcement semantics.
32
40
  * - Sets neither `font-variant-caps` nor `font-variant-numeric` under any prop.
33
41
  *
34
42
  * @CallerMustEnsure — the component cannot see these and does not check them
35
43
  * - This is **not a form label**: it renders no `htmlFor` and labels no control. A labelled control
36
44
  * uses `Input`/`TextArea`, which label themselves.
45
+ * - Status-toned content communicates its status without relying on colour. The caller owns any
46
+ * announcement behavior required when that status changes.
37
47
  */
38
48
  export const Eyebrow: FunctionComponent<IEyebrowProps> = ({
39
49
  children,
@@ -12,7 +12,14 @@ const h1 = cva(
12
12
  'font-primary text-display leading-display tracking-optical max-w-[var(--measure-display)]',
13
13
  {
14
14
  variants: {
15
- color: { foreground: 'text-foreground', muted: 'text-muted' },
15
+ color: {
16
+ foreground: 'text-foreground',
17
+ muted: 'text-muted',
18
+ success: 'text-success',
19
+ warning: 'text-warning',
20
+ error: 'text-error',
21
+ info: 'text-info',
22
+ },
16
23
  },
17
24
  defaultVariants: { color: 'foreground' },
18
25
  },
@@ -34,7 +41,8 @@ interface IH1Props extends VariantProps<typeof h1> {
34
41
  * because bigger type wants fewer characters per line (docs/adr/0004). The bound is the recipe's,
35
42
  * not a caller's: the level fixes the role and the role fixes the measure, so there is no `measure`
36
43
  * prop to select between roles (docs/adr/0008). It holds under every `color`.
37
- * - `color` selects the `foreground` or `muted` role; nothing else paints text.
44
+ * - `color` selects `foreground`, `muted`, `success`, `warning`, `error` or `info`; nothing else
45
+ * paints text. A status tone changes colour only and adds no announcement semantics.
38
46
  *
39
47
  * @CallerMustEnsure — the component cannot see these and does not check them
40
48
  * - This is an ordinary page title, and it is also a hero's lead - `display` is the hero role, so a
@@ -44,6 +52,8 @@ interface IH1Props extends VariantProps<typeof h1> {
44
52
  * - A subpage head is the exception: `PageHead` renders its own `h1` at the `title` role, the one
45
53
  * sanctioned escape valve from level-fixes-role (docs/adr/0005). Reach for it where it fits.
46
54
  * - Heading levels descend without skipping — an `h1` is followed by an `h2`, never an `h3`.
55
+ * - Status-toned content communicates its status without relying on colour. The caller owns any
56
+ * announcement behavior required when that status changes.
47
57
  */
48
58
  export const H1: FunctionComponent<IH1Props> = ({
49
59
  children,
@@ -9,7 +9,14 @@ import type { FunctionComponent, ReactNode } from 'react';
9
9
  // Colour is a semantic token re-pointed by `.dark`, so no variant carries a `dark:` class.
10
10
  const h2 = cva('font-primary text-title leading-title tracking-optical', {
11
11
  variants: {
12
- color: { foreground: 'text-foreground', muted: 'text-muted' },
12
+ color: {
13
+ foreground: 'text-foreground',
14
+ muted: 'text-muted',
15
+ success: 'text-success',
16
+ warning: 'text-warning',
17
+ error: 'text-error',
18
+ info: 'text-info',
19
+ },
13
20
  },
14
21
  defaultVariants: { color: 'foreground' },
15
22
  });
@@ -27,10 +34,13 @@ interface IH2Props extends VariantProps<typeof h2> {
27
34
  * - Reads `--font-primary`, sized by `--text-title`, led by `--leading-title` and optically corrected
28
35
  * by `--tracking-optical` — the title role is the smallest role that carries it, so `H3` and below
29
36
  * take none.
30
- * - `color` selects the `foreground` or `muted` role; nothing else paints text.
37
+ * - `color` selects `foreground`, `muted`, `success`, `warning`, `error` or `info`; nothing else
38
+ * paints text. A status tone changes colour only and adds no announcement semantics.
31
39
  *
32
40
  * @CallerMustEnsure — the component cannot see these and does not check them
33
41
  * - Heading levels descend without skipping — an `h2` sits under an `h1`, not under an `h3`.
42
+ * - Status-toned content communicates its status without relying on colour. The caller owns any
43
+ * announcement behavior required when that status changes.
34
44
  */
35
45
  export const H2: FunctionComponent<IH2Props> = ({
36
46
  children,
@@ -8,7 +8,14 @@ import type { FunctionComponent, ReactNode } from 'react';
8
8
  // class.
9
9
  const h3 = cva('font-primary text-subtitle leading-subtitle', {
10
10
  variants: {
11
- color: { foreground: 'text-foreground', muted: 'text-muted' },
11
+ color: {
12
+ foreground: 'text-foreground',
13
+ muted: 'text-muted',
14
+ success: 'text-success',
15
+ warning: 'text-warning',
16
+ error: 'text-error',
17
+ info: 'text-info',
18
+ },
12
19
  },
13
20
  defaultVariants: { color: 'foreground' },
14
21
  });
@@ -25,10 +32,13 @@ interface IH3Props extends VariantProps<typeof h3> {
25
32
  * @Guarantees — enforced on every render
26
33
  * - Renders an `h3`; its outline level and the subtitle role are one choice, not two (docs/adr/0005).
27
34
  * - Reads `--font-primary`, sized by `--text-subtitle` and led by `--leading-subtitle`.
28
- * - `color` selects the `foreground` or `muted` role; nothing else paints text.
35
+ * - `color` selects `foreground`, `muted`, `success`, `warning`, `error` or `info`; nothing else
36
+ * paints text. A status tone changes colour only and adds no announcement semantics.
29
37
  *
30
38
  * @CallerMustEnsure — the component cannot see these and does not check them
31
39
  * - Heading levels descend without skipping — an `h3` sits under an `h2`, not under an `h1`.
40
+ * - Status-toned content communicates its status without relying on colour. The caller owns any
41
+ * announcement behavior required when that status changes.
32
42
  */
33
43
  export const H3: FunctionComponent<IH3Props> = ({
34
44
  children,
@@ -8,7 +8,14 @@ import type { FunctionComponent, ReactNode } from 'react';
8
8
  // token re-pointed by `.dark`, so no variant carries a `dark:` class.
9
9
  const h4 = cva('font-primary text-body leading-body font-bold', {
10
10
  variants: {
11
- color: { foreground: 'text-foreground', muted: 'text-muted' },
11
+ color: {
12
+ foreground: 'text-foreground',
13
+ muted: 'text-muted',
14
+ success: 'text-success',
15
+ warning: 'text-warning',
16
+ error: 'text-error',
17
+ info: 'text-info',
18
+ },
12
19
  },
13
20
  defaultVariants: { color: 'foreground' },
14
21
  });
@@ -24,10 +31,13 @@ interface IH4Props extends VariantProps<typeof h4> {
24
31
  * @Guarantees — enforced on every render
25
32
  * - Renders an `h4`; its outline level and the body role are one choice, not two (docs/adr/0005).
26
33
  * - Reads `--font-primary`, sized by `--text-body`, and is bold so it stands apart from a paragraph.
27
- * - `color` selects the `foreground` or `muted` role; nothing else paints text.
34
+ * - `color` selects `foreground`, `muted`, `success`, `warning`, `error` or `info`; nothing else
35
+ * paints text. A status tone changes colour only and adds no announcement semantics.
28
36
  *
29
37
  * @CallerMustEnsure — the component cannot see these and does not check them
30
38
  * - Heading levels descend without skipping — an `h4` sits under an `h3`, not under an `h2`.
39
+ * - Status-toned content communicates its status without relying on colour. The caller owns any
40
+ * announcement behavior required when that status changes.
31
41
  */
32
42
  export const H4: FunctionComponent<IH4Props> = ({
33
43
  children,
@@ -8,7 +8,14 @@ import type { FunctionComponent, ReactNode } from 'react';
8
8
  // token re-pointed by `.dark`, so no variant carries a `dark:` class.
9
9
  const h5 = cva('font-primary text-body leading-body font-semibold', {
10
10
  variants: {
11
- color: { foreground: 'text-foreground', muted: 'text-muted' },
11
+ color: {
12
+ foreground: 'text-foreground',
13
+ muted: 'text-muted',
14
+ success: 'text-success',
15
+ warning: 'text-warning',
16
+ error: 'text-error',
17
+ info: 'text-info',
18
+ },
12
19
  },
13
20
  defaultVariants: { color: 'foreground' },
14
21
  });
@@ -25,10 +32,13 @@ interface IH5Props extends VariantProps<typeof h5> {
25
32
  * @Guarantees — enforced on every render
26
33
  * - Renders an `h5`; its outline level and the body role are one choice, not two (docs/adr/0005).
27
34
  * - Reads `--font-primary`, sized by `--text-body`, semibold so it stands apart from a paragraph.
28
- * - `color` selects the `foreground` or `muted` role; nothing else paints text.
35
+ * - `color` selects `foreground`, `muted`, `success`, `warning`, `error` or `info`; nothing else
36
+ * paints text. A status tone changes colour only and adds no announcement semantics.
29
37
  *
30
38
  * @CallerMustEnsure — the component cannot see these and does not check them
31
39
  * - Heading levels descend without skipping — an `h5` sits under an `h4`, not under an `h3`.
40
+ * - Status-toned content communicates its status without relying on colour. The caller owns any
41
+ * announcement behavior required when that status changes.
32
42
  */
33
43
  export const H5: FunctionComponent<IH5Props> = ({
34
44
  children,
@@ -8,7 +8,14 @@ import type { FunctionComponent, ReactNode } from 'react';
8
8
  // token re-pointed by `.dark`, so no variant carries a `dark:` class.
9
9
  const h6 = cva('font-primary text-body leading-body font-medium', {
10
10
  variants: {
11
- color: { foreground: 'text-foreground', muted: 'text-muted' },
11
+ color: {
12
+ foreground: 'text-foreground',
13
+ muted: 'text-muted',
14
+ success: 'text-success',
15
+ warning: 'text-warning',
16
+ error: 'text-error',
17
+ info: 'text-info',
18
+ },
12
19
  },
13
20
  defaultVariants: { color: 'foreground' },
14
21
  });
@@ -25,10 +32,13 @@ interface IH6Props extends VariantProps<typeof h6> {
25
32
  * @Guarantees — enforced on every render
26
33
  * - Renders an `h6`; its outline level and the body role are one choice, not two (docs/adr/0005).
27
34
  * - Reads `--font-primary`, sized by `--text-body`, medium so it stands apart from a paragraph.
28
- * - `color` selects the `foreground` or `muted` role; nothing else paints text.
35
+ * - `color` selects `foreground`, `muted`, `success`, `warning`, `error` or `info`; nothing else
36
+ * paints text. A status tone changes colour only and adds no announcement semantics.
29
37
  *
30
38
  * @CallerMustEnsure — the component cannot see these and does not check them
31
39
  * - Heading levels descend without skipping — an `h6` sits under an `h5`, not under an `h4`.
40
+ * - Status-toned content communicates its status without relying on colour. The caller owns any
41
+ * announcement behavior required when that status changes.
32
42
  */
33
43
  export const H6: FunctionComponent<IH6Props> = ({
34
44
  children,
@@ -11,7 +11,14 @@ import type { FunctionComponent, ReactNode } from 'react';
11
11
  // the page owns the rhythm around it. Colour is re-pointed by `.dark`, so no variant carries `dark:`.
12
12
  const note = cva('font-secondary text-small', {
13
13
  variants: {
14
- color: { foreground: 'text-foreground', muted: 'text-muted' },
14
+ color: {
15
+ foreground: 'text-foreground',
16
+ muted: 'text-muted',
17
+ success: 'text-success',
18
+ warning: 'text-warning',
19
+ error: 'text-error',
20
+ info: 'text-info',
21
+ },
15
22
  },
16
23
  defaultVariants: { color: 'foreground' },
17
24
  });
@@ -30,7 +37,8 @@ export interface INoteProps extends VariantProps<typeof note> {
30
37
  *
31
38
  * @Guarantees — enforced on every render
32
39
  * - Renders a `p`, reading `--font-secondary` and sized by `--text-small`.
33
- * - `color` selects the `foreground` (default) or `muted` role; nothing else paints text.
40
+ * - `color` selects `foreground` (default), `muted`, `success`, `warning`, `error` or `info`;
41
+ * nothing else paints text. A status tone changes colour only.
34
42
  * - Emits no tracking, no font-weight, no measure and no margin under any prop.
35
43
  * - Carries no ARIA role and no live region under any prop.
36
44
  *
@@ -44,6 +52,8 @@ export interface INoteProps extends VariantProps<typeof note> {
44
52
  * architecture standard's one-way dependency rule is why `Prose` restates `P`'s utilities.
45
53
  * - Where the annotation is a form's status message, `Form` owns `role="status"`/`role="alert"` by
46
54
  * state; a `Note` announces nothing.
55
+ * - Status-toned content communicates its status without relying on colour. The caller owns any
56
+ * announcement behavior required when that status changes.
47
57
  */
48
58
  export const Note: FunctionComponent<INoteProps> = ({
49
59
  children,
@@ -7,7 +7,14 @@ import type { FunctionComponent, ReactNode } from 'react';
7
7
  // P owns no reading measure - that belongs to whatever owns the reading column (Prose #21).
8
8
  const p = cva('font-primary text-body leading-body', {
9
9
  variants: {
10
- color: { foreground: 'text-foreground', muted: 'text-muted' },
10
+ color: {
11
+ foreground: 'text-foreground',
12
+ muted: 'text-muted',
13
+ success: 'text-success',
14
+ warning: 'text-warning',
15
+ error: 'text-error',
16
+ info: 'text-info',
17
+ },
11
18
  },
12
19
  defaultVariants: { color: 'foreground' },
13
20
  });
@@ -23,13 +30,16 @@ interface IPProps extends VariantProps<typeof p> {
23
30
  *
24
31
  * @Guarantees — enforced on every render
25
32
  * - Renders a `p`, reading `--font-primary`, sized by `--text-body` and led by `--leading-body`.
26
- * - `color` selects the `foreground` or `muted` role; nothing else paints text.
33
+ * - `color` selects `foreground`, `muted`, `success`, `warning`, `error` or `info`; nothing else
34
+ * paints text. A status tone changes colour only and adds no announcement semantics.
27
35
  *
28
36
  * @CallerMustEnsure — the component cannot see these and does not check them
29
37
  * - Where line length matters, place the paragraph inside whatever bounds the reading measure; `P`
30
38
  * does not constrain its own width.
31
39
  * - For a paragraph inside a reading column, reach for `Prose.Body`, which is measure-bounded by its
32
40
  * `Prose.Root`; `P` is for a paragraph with no reading column around it.
41
+ * - Status-toned content communicates its status without relying on colour. If a change needs to be
42
+ * announced, the caller owns that behavior; selecting a tone does not create a status event.
33
43
  */
34
44
  export const P: FunctionComponent<IPProps> = ({ children, color, testId }) => (
35
45
  <p className={p({ color })} data-testid={testId}>
@@ -20,7 +20,14 @@ const proseLede = cva('font-primary text-lede leading-lede text-foreground');
20
20
  // semantic token re-pointed by `.dark`, so no variant carries a `dark:` class.
21
21
  const proseBody = cva('font-primary text-body leading-body', {
22
22
  variants: {
23
- color: { foreground: 'text-foreground', muted: 'text-muted' },
23
+ color: {
24
+ foreground: 'text-foreground',
25
+ muted: 'text-muted',
26
+ success: 'text-success',
27
+ warning: 'text-warning',
28
+ error: 'text-error',
29
+ info: 'text-info',
30
+ },
24
31
  },
25
32
  defaultVariants: { color: 'foreground' },
26
33
  });
@@ -76,12 +83,15 @@ const ProseTail: FunctionComponent<IProseTailProps> = ({ children }) => (
76
83
  * `--measure`, setting no font-size so the `ch` measure resolves against inherited body type.
77
84
  * - `Root` stacks its children on `--space-stack` and takes no outer margin: the page owns the
78
85
  * rhythm around the block, and the air the block wants is at its edges and inside the type.
79
- * - `Lede` renders a `p` at the lede role; `Body` at the body role with a `foreground`/`muted`
80
- * `color`; `Tail` at the small role, muted. No drop cap or other invented device.
86
+ * - `Lede` renders a fixed-foreground `p` at the lede role; `Body` at the body role with a
87
+ * `foreground`, `muted`, `success`, `warning`, `error` or `info` `color`; `Tail` at the small
88
+ * role, always muted. A status tone changes colour only and adds no announcement semantics.
81
89
  *
82
90
  * @CallerMustEnsure — the component cannot see these and does not check them
83
91
  * - Use `Prose.Body` for a paragraph inside this reading column; for a paragraph with no reading
84
92
  * column around it - in a form, a card, a table cell - use `P` instead.
93
+ * - Status-toned content communicates its status without relying on colour. The caller owns any
94
+ * announcement behavior required when that status changes.
85
95
  */
86
96
  export const Prose = {
87
97
  Root: ProseRoot,