@boostdev/design-system-components 2.16.0 → 2.18.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 (97) hide show
  1. package/AGENTS.md +5 -2
  2. package/dist/client.cjs +57 -57
  3. package/dist/client.css +641 -631
  4. package/dist/client.js +57 -57
  5. package/dist/index.cjs +57 -57
  6. package/dist/index.css +641 -631
  7. package/dist/index.js +57 -57
  8. package/dist/web-components/{chunk-XI2U6U26.js → chunk-2FNCV46J.js} +4 -5
  9. package/dist/web-components/{chunk-SYNLFKD3.js → chunk-3LQKFSMR.js} +6 -0
  10. package/dist/web-components/{chunk-RZH5IVB5.js → chunk-5ATTKUCP.js} +2 -2
  11. package/dist/web-components/{chunk-XJU7KITO.js → chunk-5QA7JOC3.js} +4 -5
  12. package/dist/web-components/{chunk-EYCW7TKB.js → chunk-7GEAT2TY.js} +4 -5
  13. package/dist/web-components/chunk-FYTISJN3.js +18 -0
  14. package/dist/web-components/{chunk-LHFUXZ52.js → chunk-ISV56UWR.js} +4 -8
  15. package/dist/web-components/{chunk-YLDQOESI.js → chunk-K3VK6VEL.js} +6 -5
  16. package/dist/web-components/{chunk-GQNQBEYR.js → chunk-QZMFNJSN.js} +4 -5
  17. package/dist/web-components/{chunk-BPYKZVDK.js → chunk-SJLMW2VR.js} +2 -2
  18. package/dist/web-components/{chunk-GPJWLAKU.js → chunk-VGPJ5L6N.js} +6 -5
  19. package/dist/web-components/{chunk-AGI6YQRC.js → chunk-WOFGYU6E.js} +4 -5
  20. package/dist/web-components/{chunk-2MJTO2IW.js → chunk-WWWJCSXN.js} +2 -2
  21. package/dist/web-components/index.js +13 -12
  22. package/dist/web-components/interaction/form/bds-checkbox-group.js +1 -1
  23. package/dist/web-components/interaction/form/bds-combobox.js +2 -1
  24. package/dist/web-components/interaction/form/bds-form-input.js +2 -1
  25. package/dist/web-components/interaction/form/bds-number-input.js +2 -1
  26. package/dist/web-components/interaction/form/bds-radio-group.js +1 -1
  27. package/dist/web-components/interaction/form/bds-select.js +2 -1
  28. package/dist/web-components/interaction/form/bds-slider.js +2 -1
  29. package/dist/web-components/interaction/form/bds-textarea.js +2 -1
  30. package/dist/web-components/ui/bds-alert.js +1 -1
  31. package/dist/web-components/ui/bds-badge.js +1 -1
  32. package/dist/web-components/ui/bds-notification-banner.js +1 -1
  33. package/dist/web-components/ui/bds-rating.js +1 -1
  34. package/package.json +1 -1
  35. package/src/components/interaction/Rating/Rating.mdx +4 -1
  36. package/src/components/interaction/Rating/Rating.module.css +9 -0
  37. package/src/components/interaction/Rating/Rating.spec.tsx +9 -0
  38. package/src/components/interaction/form/Checkbox/Checkbox.tsx +1 -1
  39. package/src/components/interaction/form/CheckboxGroup/CheckboxGroup.mdx +1 -1
  40. package/src/components/interaction/form/CheckboxGroup/CheckboxGroup.spec.tsx +5 -0
  41. package/src/components/interaction/form/Combobox/Combobox.mdx +2 -0
  42. package/src/components/interaction/form/FormInput/FormInput.mdx +4 -0
  43. package/src/components/interaction/form/NumberInput/NumberInput.mdx +2 -0
  44. package/src/components/interaction/form/Radio/Radio.tsx +1 -1
  45. package/src/components/interaction/form/RadioGroup/RadioGroup.mdx +1 -1
  46. package/src/components/interaction/form/RadioGroup/RadioGroup.spec.tsx +5 -0
  47. package/src/components/interaction/form/Select/Select.mdx +2 -0
  48. package/src/components/interaction/form/Slider/Slider.mdx +2 -0
  49. package/src/components/interaction/form/Switch/Switch.tsx +1 -1
  50. package/src/components/interaction/form/Textarea/Textarea.mdx +2 -0
  51. package/src/components/interaction/form/atoms/Label.module.css +10 -0
  52. package/src/components/interaction/form/atoms/Label.spec.tsx +48 -0
  53. package/src/components/interaction/form/atoms/Label.stories.tsx +3 -0
  54. package/src/components/interaction/form/atoms/Label.tsx +4 -2
  55. package/src/components/ui/Alert/Alert.mdx +1 -1
  56. package/src/components/ui/Alert/Alert.module.css +2 -2
  57. package/src/components/ui/Alert/Alert.spec.tsx +6 -0
  58. package/src/components/ui/Badge/Badge.mdx +1 -1
  59. package/src/components/ui/Badge/Badge.module.css +2 -2
  60. package/src/components/ui/Badge/Badge.spec.tsx +8 -0
  61. package/src/components/ui/NotificationBanner/NotificationBanner.mdx +13 -1
  62. package/src/components/ui/NotificationBanner/NotificationBanner.module.css +2 -2
  63. package/src/components/ui/NotificationBanner/NotificationBanner.spec.tsx +6 -0
  64. package/src/test/token-contract.spec.ts +1 -0
  65. package/src/web-components/interaction/form/BdsCheckboxGroup.mdx +14 -0
  66. package/src/web-components/interaction/form/BdsCombobox.mdx +4 -0
  67. package/src/web-components/interaction/form/BdsFormInput.mdx +4 -0
  68. package/src/web-components/interaction/form/BdsNumberInput.mdx +4 -0
  69. package/src/web-components/interaction/form/BdsRadioGroup.mdx +11 -1
  70. package/src/web-components/interaction/form/BdsSelect.mdx +4 -0
  71. package/src/web-components/interaction/form/BdsSlider.mdx +4 -0
  72. package/src/web-components/interaction/form/BdsTextarea.mdx +4 -0
  73. package/src/web-components/interaction/form/bds-checkbox-group.spec.ts +11 -1
  74. package/src/web-components/interaction/form/bds-checkbox-group.ts +6 -5
  75. package/src/web-components/interaction/form/bds-combobox.ts +2 -5
  76. package/src/web-components/interaction/form/bds-form-input.ts +2 -5
  77. package/src/web-components/interaction/form/bds-number-input.ts +2 -5
  78. package/src/web-components/interaction/form/bds-radio-group.spec.ts +11 -1
  79. package/src/web-components/interaction/form/bds-radio-group.ts +6 -5
  80. package/src/web-components/interaction/form/bds-select.ts +2 -5
  81. package/src/web-components/interaction/form/bds-slider.ts +2 -8
  82. package/src/web-components/interaction/form/bds-textarea.ts +2 -5
  83. package/src/web-components/interaction/form/field-label.spec.ts +42 -0
  84. package/src/web-components/interaction/form/field-label.ts +20 -0
  85. package/src/web-components/test/helpers.ts +20 -0
  86. package/src/web-components/ui/BdsAlert.mdx +1 -0
  87. package/src/web-components/ui/BdsBadge.mdx +1 -0
  88. package/src/web-components/ui/BdsNotificationBanner.mdx +1 -1
  89. package/src/web-components/ui/BdsRating.mdx +4 -1
  90. package/src/web-components/ui/bds-alert.spec.ts +7 -0
  91. package/src/web-components/ui/bds-alert.ts +2 -2
  92. package/src/web-components/ui/bds-badge.spec.ts +6 -0
  93. package/src/web-components/ui/bds-badge.ts +2 -2
  94. package/src/web-components/ui/bds-notification-banner.spec.ts +7 -0
  95. package/src/web-components/ui/bds-notification-banner.ts +2 -2
  96. package/src/web-components/ui/bds-rating.spec.ts +7 -0
  97. package/src/web-components/ui/bds-rating.ts +6 -0
@@ -0,0 +1,20 @@
1
+ import { css } from 'lit';
2
+
3
+ /**
4
+ * Shared look for the label above a form control. Every `bds-*` field with a
5
+ * `label` attribute spreads `fieldLabelStyles` into its own styles, so the
6
+ * controls cannot drift. The React `Label` atom (field variant) reads the same
7
+ * hooks with the same defaults.
8
+ *
9
+ * Hooks: --formLabel_font-family, --formLabel_font-size, --formLabel_font-weight,
10
+ * --formLabel_color.
11
+ */
12
+ export const fieldLabelStyles = css`
13
+ .label {
14
+ display: block;
15
+ font-family: var(--formLabel_font-family, var(--bds-font_family--body));
16
+ font-size: var(--formLabel_font-size, var(--bds-font_size--body--s));
17
+ font-weight: var(--formLabel_font-weight, var(--bds-font_weight--semibold));
18
+ color: var(--formLabel_color, var(--bds-color_on-bg));
19
+ }
20
+ `;
@@ -1,3 +1,6 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { resolve } from 'node:path';
3
+
1
4
  /** Render an HTML string, upgrade the custom element, and await first paint. */
2
5
  export async function fixture(html: string): Promise<HTMLElement> {
3
6
  const template = document.createElement('template');
@@ -20,3 +23,20 @@ export function makeCommandEvent(command: string): Event {
20
23
  Object.defineProperty(event, 'source', { value: null, configurable: true });
21
24
  return event;
22
25
  }
26
+
27
+ /**
28
+ * Declarations of the first `selector { ... }` rule in a stylesheet, keyed by property.
29
+ * Used to compare a web component's styles with its React counterpart's CSS module.
30
+ */
31
+ export function ruleDeclarations(css: string, selector: string): Record<string, string> {
32
+ const escaped = selector.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
33
+ const body = css.match(new RegExp(`(?:^|[\\s,}])${escaped}\\s*\\{([^}]*)\\}`))?.[1] ?? '';
34
+ return Object.fromEntries(
35
+ [...body.matchAll(/([\w-]+)\s*:\s*([^;]+);/g)].map(([, prop, value]) => [prop, value.replace(/\s+/g, ' ').trim()]),
36
+ );
37
+ }
38
+
39
+ /** Reads a source file relative to the repo root. */
40
+ export function readSource(path: string): string {
41
+ return readFileSync(resolve(process.cwd(), path), 'utf8');
42
+ }
@@ -67,6 +67,7 @@ import '@boostdev/design-system-components/web-components';
67
67
  | Property | Default | Description |
68
68
  |----------|---------|-------------|
69
69
  | `--alert_bg` / `--alert_text` / `--alert_border` | per variant | Colours for all variants. Per-variant forms: `--alert_bg--info`, `--alert_text--info`, `--alert_border--info` (and `success`, `warning`, `error`). |
70
+ | `--alert_bg--error` / `--alert_text--error` / `--alert_border--error` | `var(--bds-color_error--subtle)` / `var(--bds-color_on-error--subtle)` / `var(--bds-color_error)` | Error variant colours, the subtle pair like the other variants |
70
71
  | `--alert_border-width` | `var(--bds-space_s)` (`3px` with `appearance="gradient"`) | Width of the inline-start accent line |
71
72
  | `--alert_gradient` | `linear-gradient(100deg, transparent 35%, var(--bds-color_bg--strong, var(--bds-color_bg)) 100%)` | Gradient over the variant background, `appearance="gradient"` only |
72
73
  | `--alert_shadow` | `var(--bds-shadow_s)` | Box shadow, `appearance="gradient"` only |
@@ -57,6 +57,7 @@ import '@boostdev/design-system-components/web-components';
57
57
  |----------|-------------|
58
58
  | `--badge_bg` | Badge background colour |
59
59
  | `--badge_text` | Badge text colour |
60
+ | `--badge_bg--secondary` / `--badge_text--secondary` | `secondary` variant colours (defaults `--bds-color_grey`, `--bds-color_on-grey`). The other variants have the same pair: `--badge_bg--{variant}` / `--badge_text--{variant}`. |
60
61
  | `--badge_font-size` | Font size |
61
62
  | `--badge_radius` | Border radius |
62
63
 
@@ -78,7 +78,7 @@ import '@boostdev/design-system-components/web-components';
78
78
  | `--banner_bg--info` / `--banner_text--info` / `--banner_border--info` | Info variant colours |
79
79
  | `--banner_bg--success` / `--banner_text--success` / `--banner_border--success` | Success variant colours |
80
80
  | `--banner_bg--warning` / `--banner_text--warning` / `--banner_border--warning` | Warning variant colours |
81
- | `--banner_bg--error` / `--banner_text--error` / `--banner_border--error` | Error variant colours |
81
+ | `--banner_bg--error` / `--banner_text--error` / `--banner_border--error` | Error variant colours (defaults `--bds-color_error--subtle`, `--bds-color_on-error--subtle`, `--bds-color_error`) |
82
82
  | `--banner_border-width` | Width of the block-end accent line (default `3px`) |
83
83
  | `--banner_gradient` | Gradient over the variant background, `appearance="gradient"` only (default `linear-gradient(100deg, transparent 35%, var(--bds-color_bg--strong, var(--bds-color_bg)) 100%)`) |
84
84
  | `--banner_shadow` | Box shadow, `appearance="gradient"` only (default `var(--bds-shadow_s)`) |
@@ -59,8 +59,11 @@ import '@boostdev/design-system-components/web-components';
59
59
 
60
60
  | Variable | Default | Description |
61
61
  |----------|---------|--------------|
62
- | `--rating_color` | `var(--bds-color_bg)` | Colour of unfilled stars |
62
+ | `--rating_color` | `var(--bds-color_bg)` | Fill of unfilled stars |
63
63
  | `--rating_color--filled` | `var(--bds-color_warning)` | Colour of filled stars |
64
+ | `--rating_stroke-color` | `var(--bds-color_on-bg--as-surface)` | Outline of unfilled stars, a non-text mark (falls back to `--bds-color_on-bg--border`, then `--bds-color_on-bg`, on foundations before 2.3.0) |
65
+ | `--rating_stroke-color--filled` | `currentcolor` | Outline of filled stars, the filled colour by default so both kinds keep the same size |
66
+ | `--rating_stroke-width` | `var(--bdc-outline_width)` | Outline width, in the star's 24-unit viewBox |
64
67
 
65
68
  ## Accessibility
66
69
 
@@ -148,4 +148,11 @@ describe('bds-alert', () => {
148
148
  expect(styles).toContain(`--alert_accent--${v}`);
149
149
  });
150
150
  });
151
+
152
+ it('paints the error variant with the error subtle pair, matching the React counterpart', () => {
153
+ const styles = String(BdsAlert.styles);
154
+ expect(styles).toMatch(/--alert_bg--variant:\s*var\(--alert_bg--error,\s*var\(--bds-color_error--subtle\)\)/);
155
+ expect(styles).toMatch(/--alert_text--variant:\s*var\(--alert_text--error,\s*var\(--bds-color_on-error--subtle\)\)/);
156
+ expect(styles).not.toContain('rgb(from var(--bds-color_error)');
157
+ });
151
158
  });
@@ -91,8 +91,8 @@ export class BdsAlert extends LitElement {
91
91
  }
92
92
 
93
93
  :host([variant='error']) .alert {
94
- --alert_bg--variant: var(--alert_bg--error, rgb(from var(--bds-color_error) r g b / 12%));
95
- --alert_text--variant: var(--alert_text--error, var(--bds-color_on-bg));
94
+ --alert_bg--variant: var(--alert_bg--error, var(--bds-color_error--subtle));
95
+ --alert_text--variant: var(--alert_text--error, var(--bds-color_on-error--subtle));
96
96
  --alert_border--variant: var(--alert_border--error, var(--bds-color_error));
97
97
  }
98
98
 
@@ -53,4 +53,10 @@ describe('bds-badge', () => {
53
53
  const cssText = BdsBadge.styles.cssText;
54
54
  expect(cssText).toMatch(/border-radius:\s*var\(--badge_radius,\s*var\(--bds-border_radius--full\)\)/);
55
55
  });
56
+
57
+ it('gives the secondary variant a solid neutral surface, matching the React counterpart', () => {
58
+ const cssText = BdsBadge.styles.cssText;
59
+ expect(cssText).toMatch(/:host\(\[variant='secondary'\]\) \.badge \{[^}]*--badge_bg--variant:\s*var\(--badge_bg--secondary,\s*var\(--bds-color_grey\)\)/);
60
+ expect(cssText).toMatch(/:host\(\[variant='secondary'\]\) \.badge \{[^}]*--badge_text--variant:\s*var\(--badge_text--secondary,\s*var\(--bds-color_on-grey\)\)/);
61
+ });
56
62
  });
@@ -54,8 +54,8 @@ export class BdsBadge extends LitElement {
54
54
  }
55
55
 
56
56
  :host([variant='secondary']) .badge {
57
- --badge_bg--variant: var(--badge_bg--secondary, var(--bds-color_bg));
58
- --badge_text--variant: var(--badge_text--secondary, var(--bds-color_on-bg));
57
+ --badge_bg--variant: var(--badge_bg--secondary, var(--bds-color_grey));
58
+ --badge_text--variant: var(--badge_text--secondary, var(--bds-color_on-grey));
59
59
  }
60
60
 
61
61
  :host([variant='success']) .badge {
@@ -137,4 +137,11 @@ describe('bds-notification-banner', () => {
137
137
  expect(plain.shadowRoot!.querySelector('.icon')!.classList.contains('has-content')).toBe(false);
138
138
  cleanup(plain);
139
139
  });
140
+
141
+ it('paints the error variant with the error subtle pair, matching the React counterpart', () => {
142
+ const styles = String(BdsNotificationBanner.styles);
143
+ expect(styles).toMatch(/--banner_bg--variant:\s*var\(--banner_bg--error,\s*var\(--bds-color_error--subtle\)\)/);
144
+ expect(styles).toMatch(/--banner_text--variant:\s*var\(--banner_text--error,\s*var\(--bds-color_on-error--subtle\)\)/);
145
+ expect(styles).not.toContain('rgb(from var(--bds-color_error)');
146
+ });
140
147
  });
@@ -75,8 +75,8 @@ export class BdsNotificationBanner extends LitElement {
75
75
  }
76
76
 
77
77
  :host([variant='error']) .banner {
78
- --banner_bg--variant: var(--banner_bg--error, rgb(from var(--bds-color_error) r g b / 12%));
79
- --banner_text--variant: var(--banner_text--error, var(--bds-color_on-bg));
78
+ --banner_bg--variant: var(--banner_bg--error, var(--bds-color_error--subtle));
79
+ --banner_text--variant: var(--banner_text--error, var(--bds-color_on-error--subtle));
80
80
  --banner_border--variant: var(--banner_border--error, var(--bds-color_error));
81
81
  }
82
82
 
@@ -73,4 +73,11 @@ describe('bds-rating', () => {
73
73
  expect(cssText).toMatch(/color:\s*var\(--rating_color,\s*var\(--bds-color_bg\)\)/);
74
74
  expect(cssText).toMatch(/color:\s*var\(--rating_color--filled,\s*var\(--bds-color_warning\)\)/);
75
75
  });
76
+
77
+ it('outlines empty stars through the same stroke hooks as the React counterpart', () => {
78
+ const cssText = BdsRating.styles.cssText;
79
+ expect(cssText).toMatch(/\.star \{[^}]*stroke:\s*var\(--rating_stroke-color,\s*var\(--bds-color_on-bg--as-surface,\s*var\(--bds-color_on-bg--border,\s*var\(--bds-color_on-bg\)\)\)\)/);
80
+ expect(cssText).toMatch(/\.star \{[^}]*stroke-width:\s*var\(--rating_stroke-width,\s*var\(--bdc-outline_width\)\)/);
81
+ expect(cssText).toMatch(/\.star\.--filled \{[^}]*stroke:\s*var\(--rating_stroke-color--filled,\s*currentcolor\)/);
82
+ });
76
83
  });
@@ -35,13 +35,19 @@ export class BdsRating extends LitElement {
35
35
  color: var(--rating_color, var(--bds-color_bg));
36
36
  }
37
37
 
38
+ /* Empty stars are outlined, filled stars solid, matching the React
39
+ counterpart: shape tells them apart, not only hue. */
38
40
  .star {
39
41
  inline-size: 1.5em;
40
42
  block-size: 1.5em;
43
+ stroke: var(--rating_stroke-color, var(--bds-color_on-bg--as-surface, var(--bds-color_on-bg--border, var(--bds-color_on-bg))));
44
+ stroke-width: var(--rating_stroke-width, var(--bdc-outline_width));
45
+ stroke-linejoin: round;
41
46
  }
42
47
 
43
48
  .star.--filled {
44
49
  color: var(--rating_color--filled, var(--bds-color_warning));
50
+ stroke: var(--rating_stroke-color--filled, currentcolor);
45
51
  }
46
52
  `;
47
53