@dta-au/civictheme-twig 1.13.5 → 1.14.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 (73) hide show
  1. package/components/00-base/about-civictheme/about-civictheme.stories.js +1 -0
  2. package/components/00-base/collapsible/collapsible.stories.js +1 -0
  3. package/components/00-base/elevation/elevation.stories.js +1 -0
  4. package/components/00-base/layout/__snapshots__/layout.test.js.snap +22 -33
  5. package/components/00-base/layout/layout.twig +2 -2
  6. package/components/00-base/responsive/responsive.stories.js +1 -0
  7. package/components/00-base/scrollspy/scrollspy.stories.js +1 -0
  8. package/components/00-base/spacing/spacing.stories.js +1 -0
  9. package/components/00-base/typography/typography.stories.js +1 -0
  10. package/components/00-base/welcome/welcome.stories.js +1 -0
  11. package/components/01-atoms/iframe/iframe.mdx +56 -0
  12. package/components/01-atoms/summary-list/summary-list.mdx +9 -8
  13. package/components/01-atoms/summary-list/summary-list.scss +6 -0
  14. package/components/01-atoms/summary-list/summary-list.stories.js +37 -0
  15. package/components/01-atoms/summary-list/summary-list.twig +9 -1
  16. package/components/01-atoms/table/table.mdx +65 -0
  17. package/components/01-atoms/table-sort/table-sort.stories.js +7 -10
  18. package/components/01-atoms/tag/tag.mdx +51 -0
  19. package/components/02-molecules/accordion/accordion.mdx +70 -0
  20. package/components/02-molecules/attachment/attachment.mdx +40 -0
  21. package/components/02-molecules/basic-content/content.mdx +34 -0
  22. package/components/02-molecules/callout/callout.mdx +53 -0
  23. package/components/02-molecules/feature-link-list/feature-link-list.mdx +8 -7
  24. package/components/02-molecules/figure/figure.mdx +59 -0
  25. package/components/02-molecules/{link-list-card/__snapshots__/link-list-card.test.js.snap → link-card/__snapshots__/link-card.test.js.snap} +38 -38
  26. package/components/02-molecules/{link-list-card/link-list-card.scss → link-card/link-card.scss} +3 -3
  27. package/components/02-molecules/{link-list-card/link-list-card.stories.js → link-card/link-card.stories.js} +13 -11
  28. package/components/02-molecules/{link-list-card/link-list-card.test.js → link-card/link-card.test.js} +15 -15
  29. package/components/02-molecules/{link-list-card/link-list-card.twig → link-card/link-card.twig} +8 -8
  30. package/components/02-molecules/map/map.mdx +56 -0
  31. package/components/02-molecules/next-step/next-step.mdx +34 -0
  32. package/components/02-molecules/table-of-contents/table-of-contents.mdx +38 -0
  33. package/components/02-molecules/tabs/__snapshots__/tabs.test.js.snap +454 -15
  34. package/components/02-molecules/tabs/tabs.js +43 -0
  35. package/components/02-molecules/tabs/tabs.scss +86 -1
  36. package/components/02-molecules/tabs/tabs.stories.js +39 -0
  37. package/components/02-molecules/tabs/tabs.test.js +69 -0
  38. package/components/02-molecules/tabs/tabs.twig +38 -8
  39. package/components/03-organisms/banner/__snapshots__/banner.test.js.snap +0 -6
  40. package/components/03-organisms/banner/banner.mdx +33 -0
  41. package/components/03-organisms/banner/banner.twig +1 -1
  42. package/components/03-organisms/campaign/campaign.mdx +35 -0
  43. package/components/03-organisms/chart/chart.js +3 -5
  44. package/components/03-organisms/chart/chart.scss +22 -4
  45. package/components/03-organisms/filterable-table/filterable-table.js +59 -27
  46. package/components/03-organisms/filterable-table/filterable-table.stories.data.js +56 -0
  47. package/components/03-organisms/filterable-table/filterable-table.stories.js +34 -16
  48. package/components/03-organisms/filterable-table/filterable-table.twig +4 -1
  49. package/components/03-organisms/link-list/__snapshots__/link-list.test.js.snap +30 -30
  50. package/components/03-organisms/link-list/link-list.stories.js +3 -1
  51. package/components/03-organisms/link-list/link-list.test.js +4 -4
  52. package/components/03-organisms/link-list/link-list.twig +2 -2
  53. package/components/03-organisms/list/manual-list.mdx +35 -0
  54. package/components/03-organisms/message/message.mdx +45 -0
  55. package/components/03-organisms/promo/promo.mdx +36 -0
  56. package/components/03-organisms/side-navigation/sub-nav.mdx +39 -0
  57. package/components/03-organisms/slider/slider.mdx +62 -0
  58. package/components/03-organisms/webform/webform.mdx +56 -0
  59. package/components/04-templates/page/__snapshots__/page.test.js.snap +259 -204
  60. package/components/04-templates/page/page.twig +36 -35
  61. package/components/04-templates/search-results/__snapshots__/search-results.test.js.snap +1766 -1706
  62. package/components/04-templates/search-results/search-results.scss +10 -17
  63. package/components/04-templates/search-results/search-results.test.js +4 -2
  64. package/components/04-templates/search-results/search-results.twig +12 -10
  65. package/components/variables.components.scss +47 -10
  66. package/dist/civictheme.css +158 -62
  67. package/dist/civictheme.storybook.css +158 -62
  68. package/dist/civictheme.storybook.js +105 -65
  69. package/dist/civictheme.variables.css +27 -9
  70. package/dist/constants.json +27 -9
  71. package/package.json +2 -1
  72. package/components/04-templates/search-results/search-results.js +0 -30
  73. /package/components/02-molecules/{link-list-card/link-list-card.stories.data.js → link-card/link-card.stories.data.js} +0 -0
@@ -4,6 +4,7 @@ import Constants from '../../../dist/constants.json';
4
4
  const meta = {
5
5
  title: 'About CivicTheme',
6
6
  component: Component,
7
+ tags: ['!autodocs'],
7
8
  argTypes: {
8
9
  logos: {
9
10
  table: {
@@ -3,6 +3,7 @@ import Component from './collapsible.stories.twig';
3
3
  const meta = {
4
4
  title: 'Base/Utilities/Collapsible',
5
5
  component: Component,
6
+ tags: ['!autodocs'],
6
7
  };
7
8
 
8
9
  export default meta;
@@ -3,6 +3,7 @@ import Component from './elevation.stories.twig';
3
3
  const meta = {
4
4
  title: 'Base/Elevation',
5
5
  component: Component,
6
+ tags: ['!autodocs'],
6
7
  };
7
8
 
8
9
  export default meta;
@@ -9,9 +9,8 @@ exports[`Layout Component hides sidebars when specified - contained 1`] = `
9
9
 
10
10
 
11
11
 
12
- <main
12
+ <div
13
13
  class="ct-layout ct-layout--no-sidebar-left ct-layout--no-sidebar-right ct-layout--no-top-left ct-layout--no-top-right ct-layout--no-bottom-left ct-layout--no-bottom-right"
14
- role="main"
15
14
  >
16
15
 
17
16
 
@@ -36,7 +35,7 @@ exports[`Layout Component hides sidebars when specified - contained 1`] = `
36
35
 
37
36
 
38
37
 
39
- </main>
38
+ </div>
40
39
 
41
40
 
42
41
  </div>
@@ -51,9 +50,8 @@ exports[`Layout Component hides sidebars when specified 1`] = `
51
50
 
52
51
 
53
52
 
54
- <main
53
+ <div
55
54
  class="ct-layout ct-layout--no-sidebar-left ct-layout--no-sidebar-right ct-layout--no-top-left ct-layout--no-top-right ct-layout--no-bottom-left ct-layout--no-bottom-right"
56
- role="main"
57
55
  >
58
56
 
59
57
 
@@ -78,7 +76,7 @@ exports[`Layout Component hides sidebars when specified 1`] = `
78
76
 
79
77
 
80
78
 
81
- </main>
79
+ </div>
82
80
 
83
81
 
84
82
  </div>
@@ -93,9 +91,8 @@ exports[`Layout Component only main - contained 1`] = `
93
91
 
94
92
 
95
93
 
96
- <main
94
+ <div
97
95
  class="ct-layout ct-layout--no-top-left ct-layout--no-top-right ct-layout--no-bottom-left ct-layout--no-bottom-right"
98
- role="main"
99
96
  >
100
97
 
101
98
 
@@ -120,7 +117,7 @@ exports[`Layout Component only main - contained 1`] = `
120
117
 
121
118
 
122
119
 
123
- </main>
120
+ </div>
124
121
 
125
122
 
126
123
  </div>
@@ -135,9 +132,8 @@ exports[`Layout Component only main - not contained 1`] = `
135
132
 
136
133
 
137
134
 
138
- <main
135
+ <div
139
136
  class="ct-layout ct-layout--no-top-left ct-layout--no-top-right ct-layout--no-bottom-left ct-layout--no-bottom-right"
140
- role="main"
141
137
  >
142
138
 
143
139
 
@@ -162,7 +158,7 @@ exports[`Layout Component only main - not contained 1`] = `
162
158
 
163
159
 
164
160
 
165
- </main>
161
+ </div>
166
162
 
167
163
 
168
164
  </div>
@@ -177,9 +173,8 @@ exports[`Layout Component renders with all sidebars and content sections 1`] = `
177
173
 
178
174
 
179
175
 
180
- <main
176
+ <div
181
177
  class="ct-layout ct-vertical-spacing--top"
182
- role="main"
183
178
  >
184
179
 
185
180
  Top content
@@ -232,7 +227,7 @@ exports[`Layout Component renders with all sidebars and content sections 1`] = `
232
227
 
233
228
 
234
229
  Bottom content
235
- </main>
230
+ </div>
236
231
 
237
232
 
238
233
  </div>
@@ -247,10 +242,9 @@ exports[`Layout Component renders with custom attributes and classes 1`] = `
247
242
 
248
243
 
249
244
 
250
- <main
245
+ <div
251
246
  class="ct-layout ct-layout--no-top-left ct-layout--no-top-right ct-layout--no-bottom-left ct-layout--no-bottom-right custom-modifier"
252
247
  data-test="true"
253
- role="main"
254
248
  >
255
249
 
256
250
 
@@ -275,7 +269,7 @@ exports[`Layout Component renders with custom attributes and classes 1`] = `
275
269
 
276
270
 
277
271
 
278
- </main>
272
+ </div>
279
273
 
280
274
 
281
275
  </div>
@@ -290,9 +284,8 @@ exports[`Layout Component renders with default values 1`] = `
290
284
 
291
285
 
292
286
 
293
- <main
287
+ <div
294
288
  class="ct-layout ct-layout--no-top-left ct-layout--no-top-right ct-layout--no-bottom-left ct-layout--no-bottom-right"
295
- role="main"
296
289
  >
297
290
 
298
291
 
@@ -317,7 +310,7 @@ exports[`Layout Component renders with default values 1`] = `
317
310
 
318
311
 
319
312
 
320
- </main>
313
+ </div>
321
314
 
322
315
 
323
316
  </div>
@@ -332,9 +325,8 @@ exports[`Layout Component renders with sidebar bottom left 1`] = `
332
325
 
333
326
 
334
327
 
335
- <main
328
+ <div
336
329
  class="ct-layout ct-layout--no-top-left ct-layout--no-top-right ct-layout--no-bottom-right ct-vertical-spacing--top"
337
- role="main"
338
330
  >
339
331
 
340
332
 
@@ -366,7 +358,7 @@ exports[`Layout Component renders with sidebar bottom left 1`] = `
366
358
 
367
359
 
368
360
 
369
- </main>
361
+ </div>
370
362
 
371
363
 
372
364
  </div>
@@ -381,9 +373,8 @@ exports[`Layout Component renders with sidebar bottom right 1`] = `
381
373
 
382
374
 
383
375
 
384
- <main
376
+ <div
385
377
  class="ct-layout ct-layout--no-top-left ct-layout--no-top-right ct-layout--no-bottom-left ct-vertical-spacing--top"
386
- role="main"
387
378
  >
388
379
 
389
380
 
@@ -415,7 +406,7 @@ exports[`Layout Component renders with sidebar bottom right 1`] = `
415
406
 
416
407
 
417
408
 
418
- </main>
409
+ </div>
419
410
 
420
411
 
421
412
  </div>
@@ -430,9 +421,8 @@ exports[`Layout Component renders with sidebar top left 1`] = `
430
421
 
431
422
 
432
423
 
433
- <main
424
+ <div
434
425
  class="ct-layout ct-layout--no-top-right ct-layout--no-bottom-left ct-layout--no-bottom-right ct-vertical-spacing--top"
435
- role="main"
436
426
  >
437
427
 
438
428
 
@@ -464,7 +454,7 @@ exports[`Layout Component renders with sidebar top left 1`] = `
464
454
 
465
455
 
466
456
 
467
- </main>
457
+ </div>
468
458
 
469
459
 
470
460
  </div>
@@ -479,9 +469,8 @@ exports[`Layout Component renders with sidebar top right 1`] = `
479
469
 
480
470
 
481
471
 
482
- <main
472
+ <div
483
473
  class="ct-layout ct-layout--no-top-left ct-layout--no-bottom-left ct-layout--no-bottom-right ct-vertical-spacing--top"
484
- role="main"
485
474
  >
486
475
 
487
476
 
@@ -513,7 +502,7 @@ exports[`Layout Component renders with sidebar top right 1`] = `
513
502
 
514
503
 
515
504
 
516
- </main>
505
+ </div>
517
506
 
518
507
 
519
508
  </div>
@@ -57,7 +57,7 @@
57
57
  {% set modifier_class = modifier_class|trim %}
58
58
 
59
59
  {% if content %}
60
- <main class="ct-layout {{ modifier_class -}}" role="main" {% if attributes is defined and attributes is not null %}{{- attributes -}}{% endif %}>
60
+ <div class="ct-layout {{ modifier_class -}}" {% if attributes is defined and attributes is not null %}{{- attributes -}}{% endif %}>
61
61
  {% block content_top_block %}
62
62
  {% if content_top is not empty %}
63
63
  {{- content_top -}}
@@ -111,5 +111,5 @@
111
111
  {{- content_bottom -}}
112
112
  {% endif %}
113
113
  {% endblock %}
114
- </main>
114
+ </div>
115
115
  {% endif %}
@@ -3,6 +3,7 @@ import Component from './responsive.stories.twig';
3
3
  const meta = {
4
4
  title: 'Base/Utilities/Responsive',
5
5
  component: Component,
6
+ tags: ['!autodocs'],
6
7
  };
7
8
 
8
9
  export default meta;
@@ -3,6 +3,7 @@ import Component from './scrollspy.stories.twig';
3
3
  const meta = {
4
4
  title: 'Base/Utilities/Scrollspy',
5
5
  component: Component,
6
+ tags: ['!autodocs'],
6
7
  };
7
8
 
8
9
  export default meta;
@@ -3,6 +3,7 @@ import Component from './spacing.stories.twig';
3
3
  const meta = {
4
4
  title: 'Base/Spacing',
5
5
  component: Component,
6
+ tags: ['!autodocs'],
6
7
  };
7
8
 
8
9
  export default meta;
@@ -3,6 +3,7 @@ import Component from './typography.stories.twig';
3
3
  const meta = {
4
4
  title: 'Base/Typography',
5
5
  component: Component,
6
+ tags: ['!autodocs'],
6
7
  };
7
8
 
8
9
  export default meta;
@@ -4,6 +4,7 @@ import Constants from '../../../dist/constants.json';
4
4
  const meta = {
5
5
  title: 'Welcome',
6
6
  component: Component,
7
+ tags: ['!autodocs'],
7
8
  argTypes: {
8
9
  logos: {
9
10
  table: {
@@ -0,0 +1,56 @@
1
+ {/* Editorial guidance ported from the digital.gov.au design library (dga-dl /src/content). */}
2
+ {/* Internal /patterns and /templates links demoted to plain text – they do not resolve in Storybook. */}
3
+
4
+ import { Meta, Canvas, Controls } from '@storybook/addon-docs/blocks';
5
+ import * as Stories from './iframe.stories';
6
+
7
+ <Meta of={Stories} />
8
+
9
+ # iFrame
10
+
11
+ A callout draws attention to important or interesting information.
12
+
13
+ <Canvas of={Stories.Iframe} />
14
+
15
+ <Controls of={Stories.Iframe} />
16
+
17
+ <div style="box-sizing: border-box;
18
+ list-style: none;
19
+ margin: 0;
20
+ padding: 0;
21
+ border-width: 0;
22
+ border-left-width: 1px;
23
+ border-right-width: 1px;
24
+ border-top-width: 1px;
25
+ border-bottom-width: 1px;
26
+ border-color: var(--ct-color-light-border-light);
27
+ border-style: solid;
28
+ border-radius: 4px;">
29
+ <Canvas of={Stories.Iframe} />
30
+ </div>
31
+
32
+
33
+ Use callout to draw a user's attention to important snippets of static information.
34
+
35
+ ## Do
36
+
37
+ - use sparingly as they are intrusive
38
+ - use to help users quickly scan to find essential information in a long text page
39
+ - use to reiterate important content
40
+ - use to format content not included in the main text such as support and contact details, checklists, definitions and 'Did you know?' content.
41
+
42
+ ## Don't
43
+ - use for primary content, as it may be missed
44
+ - use for quotes in long-form content - use a **Quote** instead
45
+ - make them the focus of content; they are a supporting tool
46
+ - use for errors and alerts – use an alert or message instead
47
+ - embed form inputs in Callouts
48
+ - use in conditionally revealed checkbox or radio groups
49
+ - mix colour palettes.
50
+
51
+ ## Related components
52
+ - Global alert – Global alerts display prominent service or system wide messages at the top of the screen.
53
+ - Message – A message is a colour-coded, non-disruptive notification that provides Success, Error, Warning or Information messages within a page at relevant times during the user journey. They should not be confused with Callouts.
54
+
55
+ ## Related patterns
56
+ - Messaging – Messaging conveys contextual information to the user, provides information in relation to a service or interaction, and provides feedback in response to their actions or the current system status.
@@ -1,8 +1,7 @@
1
- {/* Generated by packages/sdc/scripts/import-dga-dl-docs.js re-run to refresh. */}
2
- {/* Source: digital.gov.au design library (dga-dl /src/content). */}
3
- {/* Cross-link rewrites deferred to beads ui-kit-dev-space-r0f — links may be broken. */}
1
+ {/* Editorial guidance ported from the digital.gov.au design library (dga-dl /src/content). */}
2
+ {/* Internal /patterns and /templates links demoted to plain text – they do not resolve in Storybook. */}
4
3
 
5
- import { Meta, Canvas } from '@storybook/addon-docs/blocks';
4
+ import { Meta, Canvas, Controls } from '@storybook/addon-docs/blocks';
6
5
  import * as Stories from './summary-list.stories';
7
6
 
8
7
  <Meta of={Stories} />
@@ -13,6 +12,8 @@ A structured list of name–value pairs for displaying record summaries and meta
13
12
 
14
13
  <Canvas of={Stories.Default} />
15
14
 
15
+ <Controls of={Stories.Default} />
16
+
16
17
  Use a summary list to display structured information as labelled name–value pairs. Typical uses include review and confirm screens before form submission, metadata panels on record or profile pages, and read-only summaries of collected data.
17
18
 
18
19
  The component renders as a styled `<dl>` element with `<dt>` (term) and `<dd>` (description) pairs.
@@ -27,11 +28,11 @@ The component renders as a styled `<dl>` element with `<dt>` (term) and `<dd>` (
27
28
  ## When not to use
28
29
 
29
30
  - for content that needs running prose – use a rich text body instead
30
- - when the data is tabular with multiple columns of comparable items – use a [Table](/components/table/) instead
31
- - for navigational lists – use [Manual list](/components/manual-list/) or [Feature link list](/components/feature-link-list/) instead
31
+ - when the data is tabular with multiple columns of comparable items – use a **Table** instead
32
+ - for navigational lists – use **Manual list** or **Feature link list** instead
32
33
  - when there are only one or two pairs – a simple paragraph is sufficient
33
34
 
34
35
  ## Related components
35
36
 
36
- - [Table](/components/table/) – use when data has multiple comparable rows and columns.
37
- - [Content](/components/content/) – use for free-form body text and formatted content.
37
+ - **Table** – use when data has multiple comparable rows and columns.
38
+ - **Content** – use for free-form body text and formatted content.
@@ -23,6 +23,12 @@
23
23
  flex-wrap: nowrap;
24
24
  gap: 0;
25
25
  }
26
+
27
+ // The display:flex above outranks the UA [hidden] rule, so a row the
28
+ // filterable-table behaviour hides would otherwise stay visible.
29
+ &[hidden] {
30
+ display: none;
31
+ }
26
32
  }
27
33
 
28
34
  &--no-border {
@@ -19,6 +19,9 @@ const meta = {
19
19
  no_border: {
20
20
  control: { type: 'boolean' },
21
21
  },
22
+ id: {
23
+ control: { type: 'text' },
24
+ },
22
25
  items: {
23
26
  control: { type: 'object' },
24
27
  },
@@ -87,3 +90,37 @@ export const WithActions = {
87
90
  ],
88
91
  },
89
92
  };
93
+
94
+ // Rows carry id + per-row filter_values, the contract the filterable-table
95
+ // behaviour (target_type: list) reads via data-filter-col-N. Glossary example
96
+ // (term -> definition) — the canonical <dl> use case; Category is a filter
97
+ // dimension not shown in the row. See the "Filterable Definition List" story
98
+ // under Content/Tables/Filterable table for the controls wired up. The <dl>
99
+ // alone is fully usable without JS.
100
+ export const Filterable = {
101
+ name: 'With filter attributes',
102
+ args: {
103
+ theme: 'light',
104
+ no_border: false,
105
+ modifier_class: '',
106
+ attributes: null,
107
+ id: 'digital-glossary',
108
+ items: [
109
+ {
110
+ key: 'Accessibility',
111
+ value: 'Designing services so everyone, including people with disability, can use them.',
112
+ filter_values: ['Accessibility', 'Inclusion'],
113
+ },
114
+ {
115
+ key: 'Design system',
116
+ value: 'A library of reusable components and standards for building consistent services.',
117
+ filter_values: ['Design system', 'Design'],
118
+ },
119
+ {
120
+ key: 'Open data',
121
+ value: 'Data published in a reusable, openly licensed, machine-readable format.',
122
+ filter_values: ['Open data', 'Data'],
123
+ },
124
+ ],
125
+ },
126
+ };
@@ -6,12 +6,16 @@
6
6
  * Props:
7
7
  * - theme: [string]
8
8
  * - no_border: [boolean]
9
+ * - id: [string] Optional id on the <dl>, e.g. so a filterable-table control set can target it.
9
10
  * - items: [array] :
10
11
  * Each item contains:
11
12
  * - key: [string]
12
13
  * - value: [string]
13
14
  * - action_url: [string]
14
15
  * - action_text: [string]
16
+ * - filter_values: [array] Optional per-column filterable values (order matches the filterable-table columns). When set, the row carries data-filter-row plus data-filter-col-N attributes.
17
+ * Each item contains:
18
+ * - items [string]
15
19
  * - modifier_class: [string]
16
20
  * - attributes: [Drupal\Core\Template\Attribute] Additional HTML attributes.
17
21
  */
@@ -26,11 +30,15 @@
26
30
  <dl
27
31
  class="ct-summary-list {{ modifier_class|trim }}"
28
32
  data-component-name="ct-summary-list"
33
+ {%- if id is not empty %} id="{{ id }}"{% endif %}
29
34
  {%- if attributes is defined and attributes is not null %} {{- attributes -}}{% endif %}
30
35
  >
31
36
  {% for item in items %}
32
37
  {% if item.key is not empty and item.value is not empty %}
33
- <div class="ct-summary-list__row">
38
+ <div
39
+ class="ct-summary-list__row"
40
+ {%- if item.filter_values is not empty %} data-filter-row{% for filter_value in item.filter_values %} data-filter-col-{{ loop.index0 }}="{{ filter_value }}"{% endfor %}{% endif %}
41
+ >
34
42
  <dt class="ct-summary-list__key">{{ item.key }}</dt>
35
43
  <dd class="ct-summary-list__value">{{ item.value }}</dd>
36
44
  {% if item.action_url is not empty %}
@@ -0,0 +1,65 @@
1
+ {/* Editorial guidance ported from the digital.gov.au design library (dga-dl /src/content). */}
2
+ {/* Internal /patterns and /templates links demoted to plain text – they do not resolve in Storybook. */}
3
+
4
+ import { Meta, Canvas, Controls } from '@storybook/addon-docs/blocks';
5
+ import * as Stories from './table.stories';
6
+
7
+ <Meta of={Stories} />
8
+
9
+ # Table
10
+
11
+ A structured display of data in rows and columns.
12
+
13
+ <Canvas of={Stories.Table} />
14
+
15
+ <Controls of={Stories.Table} />
16
+
17
+ Use tables to present data that users need to scan, compare, or look up. Tables work well when information has a clear row-and-column structure and relationships between cells matter.
18
+
19
+ ## When to use
20
+
21
+ - data has a meaningful row-and-column structure
22
+ - users need to compare values across rows or columns
23
+ - the data cannot be adequately expressed as a list or prose
24
+
25
+ ## When not to use
26
+
27
+ - for layout purposes – tables are for data, not for arranging page elements
28
+ - when the data has only one column – a list is more appropriate
29
+ - when all rows contain the same value in most columns – reconsider the data structure
30
+
31
+ ## Variants
32
+
33
+ ### Standard
34
+
35
+ A basic table with column headers, an optional caption, and optional zebra striping for readability.
36
+
37
+ ### Sortable
38
+
39
+ Column headers become interactive sort controls. Clicking a header sorts that column ascending; clicking again sorts descending. Only one column sorts at a time. Sort direction is indicated with an icon.
40
+
41
+ ### Filterable
42
+
43
+ Connects to the search-filters pattern. Three filter configurations apply depending on the number of filters:
44
+
45
+ - **Small (1–2 filters):** filters appear inline above the table; no applied filter tags are needed.
46
+ - **Medium (3–6 filters):** primary filters appear inline; remaining filters appear in an accordion triggered by 'Show filters'; applied filters are shown as dismissible tags.
47
+ - **Large (6+ filters):** primary filters appear inline; remaining filters appear in a drawer triggered by 'Show filters'; the drawer has Apply, Clear, Close, and Cancel actions; applied filters are shown as dismissible tags.
48
+
49
+ ### Wide tables
50
+
51
+ When table content overflows its container, a custom horizontal scrollbar renders at the bottom of the table. The scrollbar sticks to the bottom of the viewport when the bottom of the table is off-screen, so users can scroll horizontally from any row.
52
+
53
+ ### Spanning cells
54
+
55
+ Cells can span multiple columns (`colSpan`) or rows (`rowSpan`) to represent data with genuinely hierarchical relationships. Use spanning cells only when the data relationship is inherently multi-dimensional. Do not use them to create visual layout effects.
56
+
57
+ ## Related components
58
+
59
+ - **Filter sidebar** – use when filters should be persistently visible in a sidebar alongside the table.
60
+ - **Summary list** – use for structured name–value pairs rather than rows-and-columns data.
61
+
62
+ ## Related patterns
63
+
64
+ - Search filters – use to connect filter controls to a filterable table.
65
+ - Pagination – use to limit the number of rows displayed at once in large datasets.
@@ -8,19 +8,16 @@
8
8
  * Pre-sorted columns: add aria-sort="ascending|descending" to a <th>.
9
9
  * Custom sort values: add data-sort-value="..." to a <td>.
10
10
  *
11
- * CSS and JS are imported explicitly here because the sdc-plugin auto-discovers
12
- * assets via Twig imports this component has no Twig template, so they must
13
- * be declared manually.
11
+ * In the twig package, CSS is bundled globally via civictheme.storybook.css,
12
+ * so no per-component CSS imports are needed only the behaviour JS.
13
+ *
14
+ * @sync-ignore
15
+ * This file intentionally drifts from the SDC source: the SDC version imports
16
+ * per-component .css files so sdc-plugin can discover them; the twig Storybook
17
+ * build has no such files and resolves them globally.
14
18
  */
15
19
 
16
- import './table-sort.css';
17
20
  import './table-sort.js';
18
- // table.js sets data-title attrs on tbody cells so mobile pseudo-element labels
19
- // render; table.css carries the matching `content: attr(data-title)` rule. The
20
- // sdc-plugin only auto-loads sibling assets via Twig imports — this atom has no
21
- // Twig template, so the table assets must be pulled in explicitly.
22
- import '../table/table.js';
23
- import '../table/table.css';
24
21
 
25
22
  const meta = {
26
23
  title: 'Content/Tables/Table sort',
@@ -0,0 +1,51 @@
1
+ {/* Editorial guidance ported from the digital.gov.au design library (dga-dl /src/content). */}
2
+ {/* Internal /patterns and /templates links demoted to plain text – they do not resolve in Storybook. */}
3
+
4
+ import { Meta, Canvas, Controls } from '@storybook/addon-docs/blocks';
5
+ import * as Stories from './tag.stories';
6
+
7
+ <Meta of={Stories} />
8
+
9
+ # Tag
10
+
11
+ A short label that signals status, audience, document type, or another classification axis.
12
+
13
+ <Canvas of={Stories.Tag} />
14
+
15
+ <Controls of={Stories.Tag} />
16
+
17
+ A tag is a short label – usually one to three words – that classifies a page along an axis other than its title. Tags appear most often in page banners, where they signal status ('Mandatory', 'Draft'), audience or scope ('Whole-of-government'), document type ('Plan', 'Communique', 'Case study'), or a temporal horizon ('2025–2027').
18
+
19
+ Tags carry information that travels with screenshots and search-result snippets. A reader who sees only the banner of a rule page should still know whether the rule is mandatory.
20
+
21
+ ## When to use
22
+
23
+ Use a tag in a page banner when:
24
+
25
+ - the page is a rule and its mandatory status needs to be visible
26
+ - the page is one of a numbered set and its position in a second classification axis matters (for example, a statement's lifecycle stage)
27
+ - the page is a published artefact whose document type is not obvious from the title (a case study, a communique, a plan)
28
+ - the page is dated or versioned and that information is part of the page's identity
29
+
30
+ A single page may carry one tag or a tag-list of two to four. More than four tags in a banner is a sign that the page's identity is unclear and the tags are doing the work the title should do.
31
+
32
+ ## When not to use
33
+
34
+ Do not use a tag for:
35
+
36
+ - topical taxonomy ('AI', 'investment') – that belongs in the site's content tagging system, not the page banner
37
+ - the section the page lives in – breadcrumb covers that
38
+ - a call to action – that belongs in a **callout** or **next step**
39
+
40
+ Section landing pages do not typically carry banner tags – they are navigation surfaces, not classified artefacts.
41
+
42
+ ## Tag-list
43
+
44
+ A tag-list is a horizontal group of two or more tags shown together. Use a tag-list when a page sits at the intersection of two or more classification axes – for example, a statement that is both 'Mandatory' and 'Lifecycle: Design'.
45
+
46
+ Order the tags in the list from most general to most specific: status before audience before topic before date.
47
+
48
+ ## Related components
49
+
50
+ - **Callout** – for the page's most important sentence; not a substitute for a tag.
51
+ - **Banner** – the page header that hosts tags.