@pnx-mixtape/mxds 0.1.0-rc.0 → 0.1.0-rc.2

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 (204) hide show
  1. package/.storybook/decorators.ts +15 -0
  2. package/.storybook/preview.ts +4 -1
  3. package/.storybook/themes/campus-vibrant.css +181 -0
  4. package/.storybook/themes/civic-formal.css +246 -0
  5. package/.storybook/{theme-demo.css → themes/demo.css} +14 -7
  6. package/.storybook/themes/health-services.css +255 -0
  7. package/.storybook/themes/research-faculty.css +169 -0
  8. package/dist/build/accordion.css +1 -1
  9. package/dist/build/base.css +1 -1
  10. package/dist/build/button.css +1 -1
  11. package/dist/build/chunks/DropMenu-1baQc8Yc.js +1 -0
  12. package/dist/build/chunks/InPageNavigation-CVieEl9u.js +1 -0
  13. package/dist/build/chunks/Popover-Cxg-s5Jn.js +1 -0
  14. package/dist/build/chunks/Sticky-cWUVSOXN.js +1 -0
  15. package/dist/build/chunks/{Tabs-Dm8g301e.js → Tabs-DA_Ez8pv.js} +2 -2
  16. package/dist/build/chunks/polyfills-C7pRt54M.js +1 -0
  17. package/dist/build/constants.css +1 -1
  18. package/dist/build/drop-menu.css +1 -1
  19. package/dist/build/drop-menu.entry.js +1 -1
  20. package/dist/build/elements.js +1 -1
  21. package/dist/build/form.css +1 -1
  22. package/dist/build/grid.css +1 -1
  23. package/dist/build/header.css +1 -1
  24. package/dist/build/icon.css +1 -1
  25. package/dist/build/in-page-alert.css +1 -1
  26. package/dist/build/in-page-navigation.entry.js +1 -1
  27. package/dist/build/navigation.css +1 -1
  28. package/dist/build/pagination.css +1 -1
  29. package/dist/build/popover.entry.js +1 -1
  30. package/dist/build/print.css +1 -1
  31. package/dist/build/progress-indicator.css +1 -0
  32. package/dist/build/react.js +1 -1
  33. package/dist/build/side-navigation.css +1 -1
  34. package/dist/build/sidebar.css +1 -1
  35. package/dist/build/steps.css +1 -1
  36. package/dist/build/sticky.entry.js +1 -1
  37. package/dist/build/tabs.entry.js +1 -1
  38. package/dist/build/tag.css +1 -1
  39. package/dist/build/utilities.css +1 -1
  40. package/dist/types/Atom/DefinitionList/DefinitionList.d.ts +3 -2
  41. package/dist/types/Atom/DefinitionList/DefinitionList.d.ts.map +1 -1
  42. package/dist/types/Atom/Heading/Heading.d.ts.map +1 -1
  43. package/dist/types/Atom/List/List.d.ts +10 -0
  44. package/dist/types/Atom/List/List.d.ts.map +1 -0
  45. package/dist/types/Component/DropMenu/Elements/DropMenu.d.ts.map +1 -1
  46. package/dist/types/Component/InPageNavigation/Elements/InPageNavigation.d.ts +2 -2
  47. package/dist/types/Component/InPageNavigation/Elements/InPageNavigation.d.ts.map +1 -1
  48. package/dist/types/Component/InPageNavigation/Hooks/useInPageNavigation.d.ts.map +1 -1
  49. package/dist/types/Component/ProgressIndicator/ProgressIndicator.d.ts +9 -0
  50. package/dist/types/Component/ProgressIndicator/ProgressIndicator.d.ts.map +1 -0
  51. package/dist/types/Component/Tabs/Elements/Tabs.d.ts.map +1 -1
  52. package/dist/types/Component/Tag/Tag.d.ts +4 -2
  53. package/dist/types/Component/Tag/Tag.d.ts.map +1 -1
  54. package/dist/types/Form/Autocomplete/Autocomplete.d.ts.map +1 -1
  55. package/dist/types/Form/Checkbox/FormCheckbox.d.ts.map +1 -1
  56. package/dist/types/Form/CheckboxCard/CheckboxCard.d.ts +23 -0
  57. package/dist/types/Form/CheckboxCard/CheckboxCard.d.ts.map +1 -0
  58. package/dist/types/Form/Radio/FormRadio.d.ts.map +1 -1
  59. package/dist/types/Form/RadioCard/RadioCard.d.ts +16 -0
  60. package/dist/types/Form/RadioCard/RadioCard.d.ts.map +1 -0
  61. package/dist/types/Form/Select/FormSelect.d.ts.map +1 -1
  62. package/dist/types/Form/TextInput/FormText.d.ts.map +1 -1
  63. package/dist/types/Form/Textarea/FormTextarea.d.ts.map +1 -1
  64. package/dist/types/enums.d.ts +15 -0
  65. package/dist/types/enums.d.ts.map +1 -1
  66. package/dist/types/react.d.ts +4 -0
  67. package/dist/types/react.d.ts.map +1 -1
  68. package/package.json +7 -8
  69. package/src/Atom/Background/_background.css +2 -2
  70. package/src/Atom/Blockquote/_blockquote.css +9 -2
  71. package/src/Atom/Button/README.md +1 -0
  72. package/src/Atom/Button/_buttons-styles.css +6 -6
  73. package/src/Atom/Button/_buttons.css +6 -3
  74. package/src/Atom/DefinitionList/DefinitionList.stories.ts +39 -2
  75. package/src/Atom/DefinitionList/DefinitionList.stories.tsx +36 -0
  76. package/src/Atom/DefinitionList/DefinitionList.tsx +4 -1
  77. package/src/Atom/DefinitionList/DefinitionListItem.stories.ts +1 -1
  78. package/src/Atom/DefinitionList/README.md +43 -0
  79. package/src/Atom/DefinitionList/__snapshots__/DefinitionList.stories.ts.snap +37 -3
  80. package/src/Atom/DefinitionList/__snapshots__/DefinitionList.stories.tsx.snap +2 -0
  81. package/src/Atom/DefinitionList/__snapshots__/DefinitionListItem.stories.ts.snap +3 -3
  82. package/src/Atom/DefinitionList/definition-list-item.twig +1 -0
  83. package/src/Atom/DefinitionList/definition-list.twig +6 -1
  84. package/src/Atom/Heading/Heading.tsx +6 -0
  85. package/src/Atom/Heading/_headings.css +2 -1
  86. package/src/Atom/Icon/_extended-set.css +30 -30
  87. package/src/Atom/Icon/_icon.css +37 -36
  88. package/src/Atom/Image/README.md +2 -2
  89. package/src/Atom/Image/_image.css +12 -6
  90. package/src/Atom/List/List.stories.ts +102 -0
  91. package/src/Atom/List/List.stories.tsx +103 -0
  92. package/src/Atom/List/List.tsx +22 -0
  93. package/src/Atom/List/README.md +150 -0
  94. package/src/Atom/List/__snapshots__/List.stories.ts.snap +43 -0
  95. package/src/Atom/List/__snapshots__/List.stories.tsx.snap +13 -0
  96. package/src/Atom/List/_list.css +123 -0
  97. package/src/Atom/List/list.twig +5 -0
  98. package/src/Atom/Media/Media.stories.ts +1 -1
  99. package/src/Atom/Media/__snapshots__/Media.stories.ts.snap +2 -2
  100. package/src/Atom/Spacing/_spacing.css +24 -24
  101. package/src/Atom/Table/__snapshots__/Table.stories.ts.snap +24 -4
  102. package/src/Atom/Table/_table.css +15 -3
  103. package/src/Atom/Table/table.twig +6 -1
  104. package/src/Atom/Text/__snapshots__/Text.stories.ts.snap +3 -2
  105. package/src/Atom/Text/_text-styles.css +21 -1
  106. package/src/Atom/Text/twig/text-styles-example.twig +3 -2
  107. package/src/Atom/_base.css +6 -0
  108. package/src/Atom/_flow.css +1 -1
  109. package/src/Atom/_generic.css +18 -11
  110. package/src/Component/Accordion/accordion.css +2 -0
  111. package/src/Component/Card/__snapshots__/Card.stories.ts.snap +2 -2
  112. package/src/Component/Card/card.twig +1 -1
  113. package/src/Component/Carousel/Carousel.stories.ts +46 -23
  114. package/src/Component/DropMenu/Elements/DropMenu.ts +10 -1
  115. package/src/Component/InPageAlert/in-page-alert.css +2 -1
  116. package/src/Component/InPageNavigation/Elements/InPageNavigation.ts +10 -5
  117. package/src/Component/InPageNavigation/Hooks/useInPageNavigation.ts +10 -5
  118. package/src/Component/InPageNavigation/InPageNavigation.stories.ts +33 -0
  119. package/src/Component/InPageNavigation/InPageNavigation.stories.tsx +52 -0
  120. package/src/Component/InPageNavigation/__snapshots__/InPageNavigation.stories.ts.snap +26 -0
  121. package/src/Component/InPageNavigation/__snapshots__/InPageNavigation.stories.tsx.snap +2 -0
  122. package/src/Component/InPageNavigation/twig/content-example-duplicate-headings.twig +20 -0
  123. package/src/Component/InPageNavigation/twig/in-page-navigation-story-duplicate-headings.twig +2 -0
  124. package/src/Component/ListItem/__snapshots__/ListItem.stories.ts.snap +4 -4
  125. package/src/Component/ListItem/list-item.twig +2 -2
  126. package/src/Component/Navigation/_navigation.css +1 -1
  127. package/src/Component/Pagination/Pagination.stories.ts +8 -4
  128. package/src/Component/Pagination/pagination.css +3 -3
  129. package/src/Component/ProgressIndicator/ProgressIndicator.stories.ts +36 -0
  130. package/src/Component/ProgressIndicator/ProgressIndicator.stories.tsx +30 -0
  131. package/src/Component/ProgressIndicator/ProgressIndicator.tsx +60 -0
  132. package/src/Component/ProgressIndicator/README.md +111 -0
  133. package/src/Component/ProgressIndicator/__snapshots__/ProgressIndicator.stories.ts.snap +67 -0
  134. package/src/Component/ProgressIndicator/__snapshots__/ProgressIndicator.stories.tsx.snap +7 -0
  135. package/src/Component/ProgressIndicator/progress-indicator.css +59 -0
  136. package/src/Component/ProgressIndicator/progress-indicator.twig +22 -0
  137. package/src/Component/Sticky/Elements/Sticky.ts +1 -1
  138. package/src/Component/Sticky/sticky.css +3 -3
  139. package/src/Component/Tabs/Elements/Tabs.ts +3 -1
  140. package/src/Component/Tabs/Tabs.stories.ts +55 -21
  141. package/src/Component/Tabs/__snapshots__/Tabs.stories.ts.snap +2 -2
  142. package/src/Component/Tag/README.md +52 -26
  143. package/src/Component/Tag/Tag.stories.tsx +24 -0
  144. package/src/Component/Tag/Tag.tsx +12 -2
  145. package/src/Component/Tag/TagItem.stories.ts +25 -0
  146. package/src/Component/Tag/__snapshots__/Tag.stories.ts.snap +2 -2
  147. package/src/Component/Tag/__snapshots__/Tag.stories.tsx.snap +2 -0
  148. package/src/Component/Tag/tag-item.twig +2 -2
  149. package/src/Component/Tag/tag.css +76 -2
  150. package/src/Form/Autocomplete/Autocomplete.stories.ts +8 -3
  151. package/src/Form/Autocomplete/Autocomplete.tsx +1 -4
  152. package/src/Form/Autocomplete/README.md +26 -26
  153. package/src/Form/Autocomplete/__snapshots__/Autocomplete.stories.ts.snap +1 -1
  154. package/src/Form/Autocomplete/__snapshots__/Autocomplete.stories.tsx.snap +1 -1
  155. package/src/Form/Autocomplete/autocomplete.twig +0 -2
  156. package/src/Form/Checkbox/FormCheckbox.tsx +2 -8
  157. package/src/Form/Checkbox/README.md +23 -18
  158. package/src/Form/Checkbox/input-checkbox.twig +0 -2
  159. package/src/Form/CheckboxCard/CheckboxCard.stories.ts +90 -0
  160. package/src/Form/CheckboxCard/CheckboxCard.stories.tsx +43 -0
  161. package/src/Form/CheckboxCard/CheckboxCard.tsx +102 -0
  162. package/src/Form/CheckboxCard/README.md +163 -0
  163. package/src/Form/CheckboxCard/__snapshots__/CheckboxCard.stories.ts.snap +63 -0
  164. package/src/Form/CheckboxCard/__snapshots__/CheckboxCard.stories.tsx.snap +7 -0
  165. package/src/Form/CheckboxCard/checkbox-card.twig +29 -0
  166. package/src/Form/FormItem/__snapshots__/FormItem.stories.ts.snap +2 -2
  167. package/src/Form/README.md +65 -13
  168. package/src/Form/Radio/FormRadio.tsx +1 -4
  169. package/src/Form/Radio/input-radio.twig +0 -2
  170. package/src/Form/RadioCard/README.md +146 -0
  171. package/src/Form/RadioCard/RadioCard.stories.ts +95 -0
  172. package/src/Form/RadioCard/RadioCard.stories.tsx +26 -0
  173. package/src/Form/RadioCard/RadioCard.tsx +59 -0
  174. package/src/Form/RadioCard/__snapshots__/RadioCard.stories.ts.snap +69 -0
  175. package/src/Form/RadioCard/__snapshots__/RadioCard.stories.tsx.snap +3 -0
  176. package/src/Form/RadioCard/radio-card.twig +20 -0
  177. package/src/Form/Select/FormSelect.tsx +1 -4
  178. package/src/Form/Select/input-select.twig +0 -2
  179. package/src/Form/TextInput/FormText.stories.tsx +14 -0
  180. package/src/Form/TextInput/FormText.tsx +1 -4
  181. package/src/Form/TextInput/__snapshots__/FormText.stories.tsx.snap +2 -0
  182. package/src/Form/TextInput/input-text.twig +0 -2
  183. package/src/Form/Textarea/FormTextarea.tsx +1 -4
  184. package/src/Form/Textarea/input-textarea.twig +0 -2
  185. package/src/Form/Validation.stories.ts +153 -0
  186. package/src/Form/__snapshots__/Validation.stories.ts.snap +130 -0
  187. package/src/Form/form.css +155 -28
  188. package/src/Layout/Grid/grid.css +4 -4
  189. package/src/Layout/Sidebar/__snapshots__/Sidebar.stories.ts.snap +5 -5
  190. package/src/Layout/Sidebar/sidebar.css +1 -0
  191. package/src/Layout/Sidebar/sidebar.twig +1 -1
  192. package/src/Utility/_layout-utils.css +8 -0
  193. package/src/Utility/print.css +50 -28
  194. package/src/Utility/utilities.css +2 -2
  195. package/src/constants.css +12 -2
  196. package/src/enums.ts +17 -0
  197. package/src/react.ts +4 -0
  198. package/tools/lib/extract-classnames.mjs +0 -0
  199. package/tools/lint-classnames.mjs +1 -1
  200. package/dist/build/chunks/DropMenu-Co9jZZ4S.js +0 -1
  201. package/dist/build/chunks/InPageNavigation-CzR_KZaz.js +0 -1
  202. package/dist/build/chunks/Popover-De_CQqcd.js +0 -1
  203. package/dist/build/chunks/Sticky-Kyjykb36.js +0 -1
  204. package/dist/build/chunks/polyfills-Dokbkxxk.js +0 -1
@@ -0,0 +1,123 @@
1
+ /**
2
+ * List
3
+ */
4
+
5
+ @layer design-system.atoms {
6
+ .mx-list {
7
+ list-style: none;
8
+ margin-block: 0;
9
+ padding-inline-start: 0;
10
+ display: grid;
11
+ gap: var(--spacing-xxxs);
12
+ counter-reset: fn;
13
+
14
+ & li {
15
+ counter-increment: fn;
16
+ max-inline-size: var(--prose-measure, 70ch);
17
+ }
18
+ }
19
+
20
+ .mx-list--notes li {
21
+ position: relative;
22
+ padding-inline-start: var(--gap-l);
23
+ font-size: var(--list-font-size, var(--font-size-s));
24
+
25
+ &::before {
26
+ content: counter(fn) ".";
27
+ position: absolute;
28
+ inset-inline-start: 0;
29
+ inset-block-start: 2px;
30
+ font-family: var(--font-family-ui, var(--font-family));
31
+ font-size: var(--font-size-ui, var(--font-size-xs));
32
+ line-height: var(--line-height-ui, var(--line-height-h));
33
+ color: var(--colour-foreground-alt);
34
+ font-variant-numeric: tabular-nums lining-nums;
35
+ }
36
+ }
37
+
38
+ .mx-list--refs li {
39
+ padding-inline-start: var(--gap-l);
40
+ text-indent: calc(var(--gap-l) * -1);
41
+ font-size: var(--list-font-size, var(--font-size-s));
42
+ }
43
+
44
+ .mx-list--stats {
45
+ /* @public --stat-font-size --stat-font-weight --grid-repeat --grid-min --grid-gap --large-grid-gap */
46
+ --font-size: var(--stat-font-size, var(--font-size-xxl));
47
+
48
+ grid-template-columns: repeat(
49
+ var(--grid-repeat, auto-fit),
50
+ minmax(min(100%, var(--grid-min, 20ch)), 1fr)
51
+ );
52
+ grid-template-rows: 1fr;
53
+ gap: var(--grid-gap, var(--gap));
54
+ font-size: var(--list-font-size, var(--font-size-s));
55
+ text-wrap: balance;
56
+
57
+ @media (--large-up) {
58
+ --grid-gap: var(--large-grid-gap, var(--gap-l));
59
+ }
60
+
61
+ & :is(b, strong) {
62
+ font-family: var(--font-family-display, var(--font-family));
63
+ font-size: var(--font-size);
64
+ font-weight: var(--stat-font-weight, var(--font-weight-bold));
65
+ font-variant-numeric: tabular-nums lining-nums;
66
+ line-height: 1;
67
+ display: block;
68
+
69
+ @supports (font-size: 1cqi) {
70
+ --font-min: calc(var(--font-size) - var(--font-size) * var(--font-size-diff, 0.3));
71
+
72
+ font-size: clamp(
73
+ max(var(--font-size-xs), var(--font-min)),
74
+ var(--font-min) + 1cqi,
75
+ var(--font-size)
76
+ );
77
+ }
78
+ }
79
+ }
80
+
81
+ .mx-list--columns {
82
+ /* @public --grid-repeat --grid-min --grid-gap --large-grid-gap */
83
+ grid-template-columns: repeat(
84
+ var(--grid-repeat, auto-fit),
85
+ minmax(min(100%, var(--grid-min, 20ch)), 1fr)
86
+ );
87
+ gap: var(--grid-gap, var(--gap));
88
+
89
+ @media (--large-up) {
90
+ --grid-gap: var(--large-grid-gap, var(--gap-l));
91
+ }
92
+ }
93
+
94
+ .mx-list--summary {
95
+ /* @public --grid-min */
96
+ grid-template-columns: min(100%, var(--grid-min, 20ch)) 1fr auto;
97
+
98
+ & > div {
99
+ grid-template-columns: subgrid;
100
+ grid-column: span 3;
101
+ padding-block: var(--spacing-xs);
102
+ border-block-end: 1px solid var(--colour-border);
103
+
104
+ &:first-child {
105
+ border-block-start: 2px solid var(--colour-foreground);
106
+ }
107
+
108
+ @container (max-width: 60ch) {
109
+ grid-template-columns: 1fr auto;
110
+ grid-column: 1 / -1;
111
+
112
+ & > dt {
113
+ grid-column: 1 / -1;
114
+ }
115
+ }
116
+ }
117
+
118
+ & .mx-list__action {
119
+ text-align: end;
120
+ font-weight: var(--font-weight-bold);
121
+ }
122
+ }
123
+ }
@@ -0,0 +1,5 @@
1
+ {% set as = ordered ? 'ol' : 'ul' %}
2
+ {% set attributes = (attributes ?? create_attribute()).addClass(['mx-list', modifier]) %}
3
+ <{{ as }}{{ attributes }}>
4
+ {{ items }}
5
+ </{{ as }}>
@@ -16,7 +16,7 @@ const meta: Meta<MediaType> = {
16
16
  src: "https://picsum.photos/id/56/558/418?grayscale",
17
17
  alt: "Some blurry bubble image",
18
18
  }),
19
- caption: "A picsum image",
19
+ caption: "<b>Figure 1.</b> A picsum image",
20
20
  type: "image",
21
21
  },
22
22
  argTypes: {
@@ -7,7 +7,7 @@ exports[`Attribution 1`] = `
7
7
  <img src="https://picsum.photos/id/56/558/418?grayscale" alt="Some blurry bubble image">
8
8
  </picture>
9
9
 
10
- <figcaption>A picsum image
10
+ <figcaption><b>Figure 1.</b> A picsum image
11
11
  - Jane Doe </figcaption>
12
12
  </figure>"
13
13
  `;
@@ -19,7 +19,7 @@ exports[`Media 1`] = `
19
19
  <img src="https://picsum.photos/id/56/558/418?grayscale" alt="Some blurry bubble image">
20
20
  </picture>
21
21
 
22
- <figcaption>A picsum image </figcaption>
22
+ <figcaption><b>Figure 1.</b> A picsum image </figcaption>
23
23
  </figure>"
24
24
  `;
25
25
 
@@ -21,18 +21,18 @@
21
21
  padding-inline-end: 0 !important;
22
22
  }
23
23
 
24
- @mixin spacing xxs;
25
- @mixin spacing xs;
26
- @mixin spacing s;
27
- @mixin spacing m;
28
- @mixin spacing l;
29
- @mixin spacing xl;
30
- @mixin spacing xxl;
31
- @mixin spacing xxxl;
32
- @mixin spacing xxxxl;
33
- @mixin spacing ul;
34
- @mixin spacing uul;
35
- @mixin spacing uuul;
24
+ @add-mixin spacing xxs;
25
+ @add-mixin spacing xs;
26
+ @add-mixin spacing s;
27
+ @add-mixin spacing m;
28
+ @add-mixin spacing l;
29
+ @add-mixin spacing xl;
30
+ @add-mixin spacing xxl;
31
+ @add-mixin spacing xxxl;
32
+ @add-mixin spacing xxxxl;
33
+ @add-mixin spacing ul;
34
+ @add-mixin spacing uul;
35
+ @add-mixin spacing uuul;
36
36
 
37
37
  .mx-margin--reset {
38
38
  margin: 0 !important;
@@ -54,16 +54,16 @@
54
54
  margin-inline-end: 0 !important;
55
55
  }
56
56
 
57
- @mixin margin xxs;
58
- @mixin margin xs;
59
- @mixin margin s;
60
- @mixin margin m;
61
- @mixin margin l;
62
- @mixin margin xl;
63
- @mixin margin xxl;
64
- @mixin margin xxxl;
65
- @mixin margin xxxxl;
66
- @mixin margin ul;
67
- @mixin margin uul;
68
- @mixin margin uuul;
57
+ @add-mixin margin xxs;
58
+ @add-mixin margin xs;
59
+ @add-mixin margin s;
60
+ @add-mixin margin m;
61
+ @add-mixin margin l;
62
+ @add-mixin margin xl;
63
+ @add-mixin margin xxl;
64
+ @add-mixin margin xxxl;
65
+ @add-mixin margin xxxxl;
66
+ @add-mixin margin ul;
67
+ @add-mixin margin uul;
68
+ @add-mixin margin uuul;
69
69
  }
@@ -31,7 +31,12 @@ exports[`Bordered 1`] = `
31
31
  <td>~500px</td>
32
32
  </tr>
33
33
  </tbody>
34
- <caption>Description of table</caption>
34
+ <tfoot>
35
+ <tr>
36
+ <td colspan="5">Footnote for table</td>
37
+ </tr>
38
+ </tfoot>
39
+ <caption>Table 1. Description of table</caption>
35
40
  </table>
36
41
  "
37
42
  `;
@@ -67,7 +72,12 @@ exports[`Striped 1`] = `
67
72
  <td>~500px</td>
68
73
  </tr>
69
74
  </tbody>
70
- <caption>Description of table</caption>
75
+ <tfoot>
76
+ <tr>
77
+ <td colspan="5">Footnote for table</td>
78
+ </tr>
79
+ </tfoot>
80
+ <caption>Table 1. Description of table</caption>
71
81
  </table>
72
82
  "
73
83
  `;
@@ -103,7 +113,12 @@ exports[`Striped And Bordered 1`] = `
103
113
  <td>~500px</td>
104
114
  </tr>
105
115
  </tbody>
106
- <caption>Description of table</caption>
116
+ <tfoot>
117
+ <tr>
118
+ <td colspan="5">Footnote for table</td>
119
+ </tr>
120
+ </tfoot>
121
+ <caption>Table 1. Description of table</caption>
107
122
  </table>
108
123
  "
109
124
  `;
@@ -139,7 +154,12 @@ exports[`Table 1`] = `
139
154
  <td>~500px</td>
140
155
  </tr>
141
156
  </tbody>
142
- <caption>Description of table</caption>
157
+ <tfoot>
158
+ <tr>
159
+ <td colspan="5">Footnote for table</td>
160
+ </tr>
161
+ </tfoot>
162
+ <caption>Table 1. Description of table</caption>
143
163
  </table>
144
164
  "
145
165
  `;
@@ -1,7 +1,9 @@
1
1
  @layer design-system.defaults {
2
2
  table {
3
+ font-size: var(--font-size-s);
3
4
  inline-size: 100%;
4
5
  border-collapse: collapse;
6
+ font-variant-numeric: tabular-nums lining-nums;
5
7
  margin: 0;
6
8
 
7
9
  & th {
@@ -12,20 +14,30 @@
12
14
  & :is(td, th) {
13
15
  padding: var(--spacing-xxs);
14
16
  border-block-end: var(--line-width, 1px) solid var(--line-colour, var(--colour-border));
17
+ font-family: var(--font-family-ui, var(--font-family));
15
18
  vertical-align: top;
16
19
  }
17
20
 
18
21
  & thead :is(td, th) {
19
- border-block-end-color: currentcolor;
22
+ border-block-end: var(--line-width, 1.5px) solid currentcolor;
20
23
  }
21
24
 
22
25
  & caption {
23
26
  padding: var(--spacing-xxs);
24
27
  text-align: start;
25
- font-size: var(--caption-font-size, var(--font-size-xs));
26
- line-height: var(--caption-line-height, var(--line-height-h));
28
+ font-family: var(--font-family-ui, var(--font-family));
29
+ font-size: var(--font-size-ui, var(--font-size-xs));
30
+ line-height: var(--line-height-ui, var(--line-height-h));
31
+ color: var(--colour-foreground-alt);
27
32
  caption-side: bottom;
28
33
  }
34
+
35
+ & tfoot :is(td, th) {
36
+ border-block-start: var(--line-width, 1.5px) solid currentcolor;
37
+ font-family: var(--font-family-ui, var(--font-family));
38
+ font-size: var(--font-size-ui, var(--font-size-xs));
39
+ line-height: var(--line-height-ui, var(--line-height-h));
40
+ }
29
41
  }
30
42
 
31
43
  .mx-table--flush {
@@ -34,5 +34,10 @@
34
34
  <td>~500px</td>
35
35
  </tr>
36
36
  </tbody>
37
- <caption>Description of table</caption>
37
+ <tfoot>
38
+ <tr>
39
+ <td colspan="5">Footnote for table</td>
40
+ </tr>
41
+ </tfoot>
42
+ <caption>Table 1. Description of table</caption>
38
43
  </table>
@@ -10,6 +10,7 @@ exports[`Center 1`] = `
10
10
  exports[`Example 1`] = `
11
11
  "<div class="mx-rich-text mx-vertical-flow"><p class="mx-text--eyebrow mx-text--embellished">Embellished eyebrow</p>
12
12
  <p class="mx-text--eyebrow">Normal eyebrow</p>
13
+ <p class="mx-text--meta">Meta text</p>
13
14
 
14
15
  <p class="mx-text--xxxl">Text xxxl: Headliner size</p>
15
16
  <p class="mx-text--xxl">Text xxl: Heading 1 size</p>
@@ -26,9 +27,9 @@ exports[`Example 1`] = `
26
27
  <p class="mx-text--m mx-background--alt"><span>Background colours can be added combined with the text classes (and a span) to have inline backgrounds on text. <br>The background should wrap with the text when it folds instead of creating a rectangle.</span></p>
27
28
  <p class="mx-text--accent mx-background--reverse"><span>Text accent: Some colours need different backgrounds to ensure sufficient contrast.</span></p>
28
29
 
29
- <blockquote class="mx-vertical-flow-flex">
30
+ <blockquote>
30
31
  <q class="mx-text--xxl mx-background--alt"><span>Blockquotes can be styled however <u>you</u> like</span></q>
31
- <cite class="mx-text--s">Source: Rikki's infinite wisdom</cite>
32
+ <cite>Source: Rikki's infinite wisdom</cite>
32
33
  </blockquote>
33
34
  </div>"
34
35
  `;
@@ -4,6 +4,7 @@
4
4
  .mx-text--section-headline,
5
5
  .mx-text--embellished-headline,
6
6
  .mx-text--lede,
7
+ .mx-text--meta,
7
8
  .mx-text--xs,
8
9
  .mx-text--s,
9
10
  .mx-text--m,
@@ -21,6 +22,7 @@
21
22
  .mx-text--eyebrow,
22
23
  .mx-text--section-headline,
23
24
  .mx-text--embellished-headline,
25
+ .mx-text--meta,
24
26
  .mx-text--xs,
25
27
  .mx-text--s,
26
28
  .mx-text--lede,
@@ -47,7 +49,8 @@
47
49
 
48
50
  text-transform: var(--heading-transform, uppercase);
49
51
  font-weight: var(--heading-font-weight, var(--font-weight-bold));
50
- font-family: var(--heading-font-family);
52
+ font-family: var(--font-family-ui, var(--font-family));
53
+ letter-spacing: var(--heading-letter-spacing, 0);
51
54
  line-height: var(--line-height-h);
52
55
  text-wrap: balance;
53
56
  }
@@ -130,6 +133,15 @@
130
133
  --font-size: var(--font-size-xs);
131
134
  }
132
135
 
136
+ .mx-text--meta {
137
+ --font-size: var(--font-size-xs);
138
+ --foreground: var(--foreground-alt, var(--colour-foreground-alt));
139
+
140
+ color: var(--foreground);
141
+ display: grid;
142
+ gap: 0.2rem;
143
+ }
144
+
133
145
  .mx-text--alt {
134
146
  --foreground: var(--foreground-alt, var(--colour-foreground-alt));
135
147
 
@@ -162,4 +174,12 @@
162
174
  color-scheme: var(--scheme, var(--colour-scheme));
163
175
  }
164
176
  }
177
+
178
+ .mx-rich-text {
179
+ font-family: var(--font-family-prose, var(--font-family));
180
+
181
+ & :is(p, li) {
182
+ max-inline-size: var(--prose-measure, var(--container-max-width));
183
+ }
184
+ }
165
185
  }
@@ -1,5 +1,6 @@
1
1
  <p class="mx-text--eyebrow mx-text--embellished">Embellished eyebrow</p>
2
2
  <p class="mx-text--eyebrow">Normal eyebrow</p>
3
+ <p class="mx-text--meta">Meta text</p>
3
4
 
4
5
  <p class="mx-text--xxxl">Text xxxl: Headliner size</p>
5
6
  <p class="mx-text--xxl">Text xxl: Heading 1 size</p>
@@ -16,7 +17,7 @@
16
17
  <p class="mx-text--m mx-background--alt"><span>Background colours can be added combined with the text classes (and a span) to have inline backgrounds on text. <br />The background should wrap with the text when it folds instead of creating a rectangle.</span></p>
17
18
  <p class="mx-text--accent mx-background--reverse"><span>Text accent: Some colours need different backgrounds to ensure sufficient contrast.</span></p>
18
19
 
19
- <blockquote class="mx-vertical-flow-flex">
20
+ <blockquote>
20
21
  <q class="mx-text--xxl mx-background--alt"><span>Blockquotes can be styled however <u>you</u> like</span></q>
21
- <cite class="mx-text--s">Source: Rikki's infinite wisdom</cite>
22
+ <cite>Source: Rikki's infinite wisdom</cite>
22
23
  </blockquote>
@@ -54,3 +54,9 @@
54
54
  */
55
55
 
56
56
  @import "./Table/_table.css";
57
+
58
+ /**
59
+ * List
60
+ */
61
+
62
+ @import "./List/_list.css";
@@ -1,4 +1,4 @@
1
- @layer design-system.utilities {
1
+ @layer design-system.defaults {
2
2
  .mx-vertical-flow {
3
3
  /* Default vertical flow. */
4
4
 
@@ -82,9 +82,9 @@
82
82
 
83
83
  dl {
84
84
  display: grid;
85
- grid-template-columns: min(100%, var(--grid-min, 20ch)) 1fr;
86
85
  grid-template-rows: 1fr;
87
86
  gap: var(--spacing-xs);
87
+ inline-size: 100%;
88
88
 
89
89
  &:has(> div) {
90
90
  container-type: inline-size;
@@ -92,21 +92,28 @@
92
92
 
93
93
  & div {
94
94
  display: grid;
95
- grid-template-columns: subgrid;
96
- grid-column: span 2;
97
-
98
- @container (max-width: 60ch) {
99
- gap: var(--spacing-xxxs);
100
-
101
- & > :is(dt, dd) {
102
- grid-column: span 2;
103
- }
104
- }
95
+ gap: var(--spacing-xxxs);
96
+ align-content: start;
105
97
  }
106
98
 
107
99
  & dt {
108
100
  font-weight: var(--font-weight-bold);
109
101
  }
102
+
103
+ &:where(:not(.mx-list--columns)) {
104
+ grid-template-columns: min(100%, var(--grid-min, 20ch)) 1fr;
105
+
106
+ & div {
107
+ grid-template-columns: subgrid;
108
+ grid-column: span 2;
109
+
110
+ @container (max-width: 60ch) {
111
+ & > :is(dt, dd) {
112
+ grid-column: span 2;
113
+ }
114
+ }
115
+ }
116
+ }
110
117
  }
111
118
 
112
119
  p {
@@ -93,6 +93,8 @@
93
93
  justify-content: space-between;
94
94
  align-items: center;
95
95
  gap: var(--spacing-xxs);
96
+ font-size: var(--font-size);
97
+ font-weight: var(--font-weight-normal);
96
98
 
97
99
  & .mx-icon {
98
100
  margin-inline-start: auto;
@@ -66,7 +66,7 @@ exports[`Collapse 1`] = `
66
66
  <article class="mx-card mx-card--collapse">
67
67
  <div class="mx-card__content mx-vertical-flow-flex">
68
68
 
69
- <div class="mx-text--s">25 May 2025</div>
69
+ <div class="mx-text--meta">25 May 2025</div>
70
70
 
71
71
  <h3>Card title</h3>
72
72
 
@@ -97,7 +97,7 @@ exports[`Date 1`] = `
97
97
  <article class="mx-card">
98
98
  <div class="mx-card__content mx-vertical-flow-flex">
99
99
 
100
- <div class="mx-text--s">25 May 2025</div>
100
+ <div class="mx-text--meta">25 May 2025</div>
101
101
 
102
102
  <h3>Card title</h3>
103
103
 
@@ -30,7 +30,7 @@
30
30
  <div class="mx-card__content mx-vertical-flow-flex">
31
31
  {{ tags }}
32
32
  {% if date is not empty %}
33
- <div class="mx-text--s">{{ date }}</div>
33
+ <div class="mx-text--meta">{{ date }}</div>
34
34
  {% endif %}
35
35
  {{ title }}
36
36
  {% if content is not empty %}
@@ -236,6 +236,7 @@ type Story = StoryObj<CarouselType>
236
236
 
237
237
  export const Carousel: Story = {
238
238
  play: async ({ canvas, canvasElement, userEvent, step }) => {
239
+ const isMobile = matchMedia("(max-width: 767px)").matches
239
240
  const back = await canvas.findByRole("button", { name: "previous page" }, { timeout: 2000 })
240
241
  const next = await canvas.findByRole("button", { name: "next page" }, { timeout: 2000 })
241
242
  // The custom element's IntersectionObserver populates its internal item
@@ -259,18 +260,22 @@ export const Carousel: Story = {
259
260
  },
260
261
  { timeout: 2000 },
261
262
  )
262
- await userEvent.click(next)
263
- await waitFor(
264
- () => {
265
- expect(back).not.toHaveAttribute("disabled")
266
- expect(next).toHaveAttribute("disabled")
267
- },
268
- { timeout: 2000 },
269
- )
263
+ if (!isMobile) {
264
+ await userEvent.click(next)
265
+ await waitFor(
266
+ () => {
267
+ expect(back).not.toHaveAttribute("disabled")
268
+ expect(next).toHaveAttribute("disabled")
269
+ },
270
+ { timeout: 2000 },
271
+ )
272
+ }
270
273
  })
271
274
  await step("Navigates back", async () => {
272
275
  await userEvent.click(back)
273
- await userEvent.click(back)
276
+ if (!isMobile) {
277
+ await userEvent.click(back)
278
+ }
274
279
  await waitFor(
275
280
  () => {
276
281
  expect(back).toHaveAttribute("disabled")
@@ -390,6 +395,7 @@ export const Loop: Story = {
390
395
  loop: true,
391
396
  },
392
397
  play: async ({ canvas, canvasElement, userEvent, step }) => {
398
+ const isMobile = matchMedia("(max-width: 767px)").matches
393
399
  const back = await canvas.findByRole("button", { name: "previous page" }, { timeout: 2000 })
394
400
  const next = await canvas.findByRole("button", { name: "next page" }, { timeout: 2000 })
395
401
  // The custom element's IntersectionObserver populates its internal item
@@ -421,22 +427,39 @@ export const Loop: Story = {
421
427
  },
422
428
  { timeout: 2000 },
423
429
  )
424
- // With `loop`, `next` is never `disabled` at the end - the custom
425
- // element instead marks it `data-restart` once its debounced scroll
426
- // handler has confirmed the end was reached. Wait for that marker
427
- // before the "Loops back" step's click, or it can race the debounce
428
- // and request an out-of-range page.
429
- await waitFor(() => expect(next).toHaveAttribute("data-restart"), { timeout: 2000 })
430
+ if (!isMobile) {
431
+ // With `loop`, `next` is never `disabled` at the end - the custom
432
+ // element instead marks it `data-restart` once its debounced scroll
433
+ // handler has confirmed the end was reached. Wait for that marker
434
+ // before the "Loops back" step's click, or it can race the debounce
435
+ // and request an out-of-range page.
436
+ await waitFor(() => expect(next).toHaveAttribute("data-restart"), { timeout: 2000 })
437
+ }
430
438
  })
431
439
  await step("Loops back", async () => {
432
- await userEvent.click(next)
433
- await waitFor(
434
- () => {
435
- expect(back).toHaveAttribute("disabled")
436
- expect(next).not.toHaveAttribute("disabled")
437
- },
438
- { timeout: 2000 },
439
- )
440
+ if (!isMobile) {
441
+ await userEvent.click(next)
442
+ await waitFor(
443
+ () => {
444
+ expect(back).toHaveAttribute("disabled")
445
+ expect(next).not.toHaveAttribute("disabled")
446
+ },
447
+ { timeout: 2000 },
448
+ )
449
+ } else {
450
+ // On mobile there's too many pages to click through to so we just
451
+ // click back instead to restore the initial state. The desktop
452
+ // test covers the loop functionality and the behaviour is the same.
453
+ await userEvent.click(back)
454
+ await userEvent.click(back)
455
+ await waitFor(
456
+ () => {
457
+ expect(back).toHaveAttribute("disabled")
458
+ expect(next).not.toHaveAttribute("disabled")
459
+ },
460
+ { timeout: 2000 },
461
+ )
462
+ }
440
463
  // Remove focus
441
464
  await userEvent.click(canvasElement)
442
465
  })
@@ -52,9 +52,10 @@ export default class DropMenu extends Popover {
52
52
  "keydown",
53
53
  (event: KeyboardEvent): void => {
54
54
  const { target, key } = event
55
+ const items = [...this.items]
55
56
  if (
56
57
  (target as HTMLElement) !== this.container &&
57
- ![...this.items].includes(target as HTMLButtonElement | HTMLAnchorElement)
58
+ !items.includes(target as HTMLButtonElement | HTMLAnchorElement)
58
59
  )
59
60
  return
60
61
 
@@ -73,6 +74,14 @@ export default class DropMenu extends Popover {
73
74
  event.preventDefault()
74
75
  this.moveFocus(target as HTMLButtonElement | HTMLAnchorElement, -1)
75
76
  break
77
+ case "Home":
78
+ event.preventDefault()
79
+ items[0].focus()
80
+ break
81
+ case "End":
82
+ event.preventDefault()
83
+ items.at(-1).focus()
84
+ break
76
85
  default:
77
86
  // Let every other key (Tab, Escape, Space, ...) through - this
78
87
  // used to preventDefault unconditionally, which suppressed Tab
@@ -14,11 +14,12 @@
14
14
  gap: var(--gap-s);
15
15
  padding-block: var(--spacing-xxs);
16
16
  padding-inline: var(--spacing-s);
17
- border: 1px solid;
17
+ border: var(--line-width, 1px) solid;
18
18
  background-color: var(--background, var(--colour-background-alt));
19
19
  color: var(--foreground, var(--colour-foreground));
20
20
  color-scheme: var(--alert-scheme, light);
21
21
  border-radius: var(--border-radius);
22
+ align-items: start;
22
23
 
23
24
  &:has(.mx-icon--close) {
24
25
  grid-template-columns: auto min-content;