@qhealth-design-system/core 1.22.2 → 1.23.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.
- package/.storybook/assets/image-position-demo-portrait.svg +54 -0
- package/.storybook/assets/image-position-demo.svg +55 -0
- package/.storybook/globals.js +9 -0
- package/.storybook/preview.js +8 -1
- package/CHANGELOG.md +2 -0
- package/README.md +0 -6
- package/package.json +13 -33
- package/src/assets/img/svg-icons.svg +154 -154
- package/src/component-loader.js +11 -2
- package/src/components/_global/css/admin/component.scss +1 -0
- package/src/components/_global/css/btn/component.scss +9 -0
- package/src/components/_global/css/img/image-position-utility-classes.scss +30 -0
- package/src/components/_global/css/img/image-ratio-utility-classes.scss +41 -0
- package/src/components/_global/css/img/images.scss +74 -5
- package/src/components/_global/css/modal/component.scss +1 -0
- package/src/components/_global/js/animate/global.js +272 -294
- package/src/components/_global/js/collapsible.js +3 -3
- package/src/components/_global/js/global.js +304 -316
- package/src/components/_global/js/legacyGlobal.js +63 -0
- package/src/components/_global/js/modal/global.js +218 -223
- package/src/components/_global/js/popover/controller.js +4 -4
- package/src/components/_global/js/tabs/global.js +264 -276
- package/src/components/a-z_listing/js/global.js +106 -92
- package/src/components/accordion/css/component.scss +24 -41
- package/src/components/accordion/html/component.hbs +23 -5
- package/src/components/accordion/js/global.js +5 -10
- package/src/components/basic_search/js/global.js +0 -7
- package/src/components/code/js/global.js +6 -12
- package/src/components/file_upload/js/global.js +1 -5
- package/src/components/internal_navigation/css/component.scss +2 -2
- package/src/components/internal_navigation/html/component.hbs +16 -1
- package/src/components/main_navigation/js/global.js +341 -335
- package/src/components/overflow_menu/css/component.scss +1 -0
- package/src/components/search_box/css/component.scss +0 -1
- package/src/components/tab/js/global.js +5 -10
- package/src/components/toggle_tip/js/global.js +0 -6
- package/src/components/tool_tip/js/global.js +0 -6
- package/src/components/video_player/css/component.scss +27 -9
- package/src/components/video_player/html/component.hbs +32 -6
- package/src/components/video_player/js/global.js +8 -1
- package/src/index.js +4 -0
- package/src/stories/Accordion/accordion.stories.js +1 -0
- package/src/stories/Banner/bannerContained.stories.js +123 -0
- package/src/stories/Flexbox/Flexbox.stories.js +316 -0
- package/src/stories/Image/Image.stories.js +182 -0
- package/src/stories/Templates/ContentPage.stories.js +101 -0
- package/src/stories/Templates/LandingPage.stories.js +193 -0
- package/src/stories/Templates/templateHelpers.js +102 -0
- package/src/stories/VideoPlayer/VideoPlayer.stories.js +16 -0
- package/src/styles/imports/utilities.scss +15 -25
- package/src/styles/imports/variables.scss +26 -0
- package/src/components/_global/html/head.html +0 -22
- package/src/components/_global/html/scripts.html +0 -28
- package/src/components/_global/js/_polyfills/global.js +0 -19
- package/src/components/_template/html/component-page.html +0 -75
- package/src/components/_template/js/global.js +0 -3
- package/src/components/accordion/html/accordion-group.html +0 -163
- package/src/components/accordion/html/default.html +0 -99
- package/src/components/banner_basic/js/global.js +0 -3
- package/src/components/loading_spinner/js/global.js +0 -3
- package/src/components/pagination/html/default.html +0 -39
- package/src/components/search_box/html/component.html +0 -26
- package/src/data/current.json +0 -400
- package/src/data/current_admin.json +0 -305
- package/src/data/model_component.js +0 -14
- package/src/data/site.json +0 -977
- package/src/externals/tinymce_classes.css +0 -62
- package/src/html/component-global-elements.html +0 -2857
- package/src/html/component-horizontal_rule.html +0 -647
- package/src/html/component-internal_navigation.html +0 -583
- package/src/html/component-left_hand_navigation.html +0 -57
- package/src/html/component-main_navigation.html +0 -583
- package/src/html/component-multi_column.html +0 -582
- package/src/html/components.html +0 -354
- package/src/html/home.html +0 -1898
- package/src/html/index.html +0 -129
- package/src/html/inner-with-nav.html +0 -605
- package/src/html/inner.html +0 -618
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
// Flexbox utility-class reference and Chromatic snapshot target.
|
|
2
|
+
//
|
|
3
|
+
// Same approach as Colours.stories.js / Typography.stories.js: a set of
|
|
4
|
+
// collapsible <details> accordions rendered as plain, deterministic HTML. Each
|
|
5
|
+
// card is a *live* demo — the qld__ flex classes are the real ones compiled into
|
|
6
|
+
// Storybook (via src/components/_global/css/flex/flexbox-utility-classes.scss),
|
|
7
|
+
// so what you see is exactly what the class does — paired with the class name in
|
|
8
|
+
// mono and a short description.
|
|
9
|
+
//
|
|
10
|
+
// Story chrome (cards, grid, accordions) uses inline styles that mirror
|
|
11
|
+
// Storybook's light docs theme; the demo containers/items use the real utility
|
|
12
|
+
// classes plus a little inline styling for visibility (gap, background).
|
|
13
|
+
|
|
14
|
+
const TEXT = "#2e3438";
|
|
15
|
+
const MUTED = "rgba(46, 52, 56, 0.7)";
|
|
16
|
+
const BORDER = "rgba(38, 85, 115, 0.15)";
|
|
17
|
+
const SANS =
|
|
18
|
+
"'Nunito Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif";
|
|
19
|
+
const MONO = "ui-monospace, Menlo, Monaco, Consolas, 'Courier New', monospace";
|
|
20
|
+
const ITEM_BG = "#0a5a8f";
|
|
21
|
+
const LINK = "#005eb8";
|
|
22
|
+
|
|
23
|
+
const DS_URL = "https://www.designsystem.qld.gov.au/styles/flex-box-utilities";
|
|
24
|
+
const SOURCE = "src/components/_global/css/flex/flexbox-utility-classes.scss";
|
|
25
|
+
|
|
26
|
+
// One flex item (the coloured boxes inside a demo container). `cls` puts a real
|
|
27
|
+
// utility class on the item itself (used by the grow/shrink/align-self demos);
|
|
28
|
+
// `style` adds inline chrome such as extra height for align-items demos.
|
|
29
|
+
const item = (label, { cls = "", style = "" } = {}) =>
|
|
30
|
+
`<div class="${cls}" style="background:${ITEM_BG};color:#fff;padding:10px 14px;border-radius:4px;font-size:13px;font-weight:600;white-space:nowrap;${style}">${label}</div>`;
|
|
31
|
+
|
|
32
|
+
// A live demo container: `cls` is the real class string applied to it (e.g.
|
|
33
|
+
// "qld__display-flex qld__justify-content-center"); the dashed border and grey
|
|
34
|
+
// fill are chrome so the container's bounds and free space are visible.
|
|
35
|
+
const container = (cls, inner, style = "") =>
|
|
36
|
+
`<div class="${cls}" style="gap:8px;border:1px dashed ${BORDER};background:#f6f8fa;padding:12px;border-radius:6px;${style}">${inner}</div>`;
|
|
37
|
+
|
|
38
|
+
// One card: the live demo above, the class name (mono) and a description below.
|
|
39
|
+
const card = (codeLabel, desc, demoHtml) => `
|
|
40
|
+
<div style="border:1px solid ${BORDER};border-radius:6px;overflow:hidden;background:#fff;display:flex;flex-direction:column;">
|
|
41
|
+
<div style="padding:14px;border-bottom:1px solid ${BORDER};">${demoHtml}</div>
|
|
42
|
+
<div style="padding:10px 12px;">
|
|
43
|
+
<div style="font-family:${MONO};font-size:12px;color:${TEXT};font-weight:600;word-break:break-word;">${codeLabel}</div>
|
|
44
|
+
${desc ? `<div style="font-size:12px;color:${MUTED};margin-top:4px;line-height:1.4;">${desc}</div>` : ""}
|
|
45
|
+
</div>
|
|
46
|
+
</div>`;
|
|
47
|
+
|
|
48
|
+
// A responsive grid of cards that wraps to fill the available width.
|
|
49
|
+
const grid = (cards) => `
|
|
50
|
+
<div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:16px;">
|
|
51
|
+
${cards.join("")}
|
|
52
|
+
</div>`;
|
|
53
|
+
|
|
54
|
+
// Each group is a native <details> accordion, open by default so every group is
|
|
55
|
+
// expanded for Chromatic and a developer can collapse the ones they don't need.
|
|
56
|
+
const section = (text, count, cards) => `
|
|
57
|
+
<details open style="margin-top:24px;">
|
|
58
|
+
<summary style="cursor:pointer;font-size:20px;font-weight:700;color:${TEXT};padding:12px 0 8px;border-bottom:1px solid ${BORDER};">${text} <span style="font-weight:400;color:${MUTED};font-size:14px;">(${count})</span></summary>
|
|
59
|
+
<div style="padding-top:16px;">${grid(cards)}</div>
|
|
60
|
+
</details>`;
|
|
61
|
+
|
|
62
|
+
const threeItems = item("1") + item("2") + item("3");
|
|
63
|
+
|
|
64
|
+
// display
|
|
65
|
+
const displayCards = [
|
|
66
|
+
{
|
|
67
|
+
cls: "qld__display-flex",
|
|
68
|
+
desc: "Block-level flex container (fills its own line).",
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
cls: "qld__display-inline-flex",
|
|
72
|
+
desc: "Inline-level flex container (sits inline with surrounding text).",
|
|
73
|
+
},
|
|
74
|
+
].map((d) => card(`.${d.cls}`, d.desc, container(d.cls, threeItems)));
|
|
75
|
+
|
|
76
|
+
// flex-direction (each demo is display-flex + the direction class)
|
|
77
|
+
const directionCards = [
|
|
78
|
+
["qld__flex-row", "Main axis left → right (the default)."],
|
|
79
|
+
["qld__flex-column", "Main axis top → bottom; items stack."],
|
|
80
|
+
["qld__flex-row-reverse", "Main axis right → left."],
|
|
81
|
+
["qld__flex-column-reverse", "Main axis bottom → top."],
|
|
82
|
+
].map(([cls, desc]) =>
|
|
83
|
+
card(`.${cls}`, desc, container(`qld__display-flex ${cls}`, threeItems)),
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
// justify-content — spacing along the main axis
|
|
87
|
+
const justifyCards = [
|
|
88
|
+
["qld__justify-content-start", "Pack items to the start."],
|
|
89
|
+
["qld__justify-content-end", "Pack items to the end."],
|
|
90
|
+
["qld__justify-content-center", "Centre items on the main axis."],
|
|
91
|
+
["qld__justify-content-between", "First/last flush; equal space between."],
|
|
92
|
+
["qld__justify-content-around", "Equal space around each item."],
|
|
93
|
+
["qld__justify-content-evenly", "Equal space between and at the ends."],
|
|
94
|
+
].map(([cls, desc]) =>
|
|
95
|
+
card(`.${cls}`, desc, container(`qld__display-flex ${cls}`, threeItems)),
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
// align-items — cross-axis alignment of items. Vary item heights + a tall
|
|
99
|
+
// container so the alignment is visible.
|
|
100
|
+
const alignItemsDemo = (cls) =>
|
|
101
|
+
container(
|
|
102
|
+
`qld__display-flex ${cls}`,
|
|
103
|
+
item("1", { style: "padding:6px 14px;" }) +
|
|
104
|
+
item("2", { style: "padding:24px 14px;" }) +
|
|
105
|
+
item("3", { style: "padding:14px 14px;" }),
|
|
106
|
+
"min-height:110px;",
|
|
107
|
+
);
|
|
108
|
+
const alignItemsCards = [
|
|
109
|
+
["qld__align-items-start", "Align items to the cross-start edge."],
|
|
110
|
+
["qld__align-items-end", "Align items to the cross-end edge."],
|
|
111
|
+
["qld__align-items-center", "Centre items on the cross axis."],
|
|
112
|
+
["qld__align-items-baseline", "Align item text baselines."],
|
|
113
|
+
["qld__align-items-stretch", "Stretch items to fill the cross axis."],
|
|
114
|
+
].map(([cls, desc]) =>
|
|
115
|
+
card(
|
|
116
|
+
`.${cls}`,
|
|
117
|
+
desc,
|
|
118
|
+
cls === "qld__align-items-stretch"
|
|
119
|
+
? // stretch only shows when items have no fixed height
|
|
120
|
+
container(
|
|
121
|
+
`qld__display-flex ${cls}`,
|
|
122
|
+
item("1") + item("2") + item("3"),
|
|
123
|
+
"min-height:110px;",
|
|
124
|
+
)
|
|
125
|
+
: alignItemsDemo(cls),
|
|
126
|
+
),
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
// flex-wrap — many items in a width-constrained container
|
|
130
|
+
const wrapDemo = (cls) =>
|
|
131
|
+
container(
|
|
132
|
+
`qld__display-flex ${cls}`,
|
|
133
|
+
[1, 2, 3, 4, 5, 6, 7, 8].map((n) => item(String(n))).join(""),
|
|
134
|
+
"max-width:260px;",
|
|
135
|
+
);
|
|
136
|
+
const wrapCards = [
|
|
137
|
+
["qld__flex-wrap", "Items wrap onto multiple lines as needed."],
|
|
138
|
+
["qld__flex-nowrap", "Items stay on one line (may overflow/shrink)."],
|
|
139
|
+
["qld__flex-wrap-reverse", "Items wrap onto multiple lines, reversed."],
|
|
140
|
+
].map(([cls, desc]) => card(`.${cls}`, desc, wrapDemo(cls)));
|
|
141
|
+
|
|
142
|
+
// align-content — spacing of wrapped lines on the cross axis. Needs wrap + a
|
|
143
|
+
// tall container + enough items to form multiple lines.
|
|
144
|
+
const alignContentDemo = (cls) =>
|
|
145
|
+
container(
|
|
146
|
+
`qld__display-flex qld__flex-wrap ${cls}`,
|
|
147
|
+
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map((n) => item(String(n))).join(""),
|
|
148
|
+
"min-height:170px;max-width:260px;",
|
|
149
|
+
);
|
|
150
|
+
const alignContentCards = [
|
|
151
|
+
["qld__align-content-start", "Pack lines to the cross-start."],
|
|
152
|
+
["qld__align-content-end", "Pack lines to the cross-end."],
|
|
153
|
+
["qld__align-content-center", "Centre the lines."],
|
|
154
|
+
["qld__align-content-between", "First/last lines flush; space between."],
|
|
155
|
+
["qld__align-content-around", "Equal space around each line."],
|
|
156
|
+
["qld__align-content-stretch", "Stretch lines to fill the cross axis."],
|
|
157
|
+
].map(([cls, desc]) => card(`.${cls}`, desc, alignContentDemo(cls)));
|
|
158
|
+
|
|
159
|
+
// flex grow / shrink / fill — classes applied to the items
|
|
160
|
+
const growShrinkCards = [
|
|
161
|
+
card(
|
|
162
|
+
".qld__flex-fill",
|
|
163
|
+
"Item grows and shrinks to take the available space (flex: 1 1 auto).",
|
|
164
|
+
container(
|
|
165
|
+
"qld__display-flex",
|
|
166
|
+
item("auto") +
|
|
167
|
+
item("qld__flex-fill", { cls: "qld__flex-fill" }) +
|
|
168
|
+
item("auto"),
|
|
169
|
+
),
|
|
170
|
+
),
|
|
171
|
+
card(
|
|
172
|
+
".qld__flex-grow-1",
|
|
173
|
+
"Item grows to absorb free space; siblings stay at their content size.",
|
|
174
|
+
container(
|
|
175
|
+
"qld__display-flex",
|
|
176
|
+
item("grow-1", { cls: "qld__flex-grow-1" }) + item("2") + item("3"),
|
|
177
|
+
),
|
|
178
|
+
),
|
|
179
|
+
card(
|
|
180
|
+
".qld__flex-grow-0",
|
|
181
|
+
"Item does not grow (the default) — stays at its content size.",
|
|
182
|
+
container(
|
|
183
|
+
"qld__display-flex",
|
|
184
|
+
item("grow-0", { cls: "qld__flex-grow-0" }) +
|
|
185
|
+
item("grow-1", { cls: "qld__flex-grow-1" }),
|
|
186
|
+
),
|
|
187
|
+
),
|
|
188
|
+
card(
|
|
189
|
+
".qld__flex-shrink-0",
|
|
190
|
+
"Item refuses to shrink below its content size when space is tight.",
|
|
191
|
+
container(
|
|
192
|
+
"qld__display-flex",
|
|
193
|
+
item("shrink-0 — a long, unshrinkable label", {
|
|
194
|
+
cls: "qld__flex-shrink-0",
|
|
195
|
+
}) + item("shrink-1", { cls: "qld__flex-shrink-1" }),
|
|
196
|
+
"max-width:260px;",
|
|
197
|
+
),
|
|
198
|
+
),
|
|
199
|
+
];
|
|
200
|
+
|
|
201
|
+
// align-self — override the container's align-items for a single item. Container
|
|
202
|
+
// is align-items-start; the highlighted item overrides it.
|
|
203
|
+
const alignSelfDemo = (cls) =>
|
|
204
|
+
container(
|
|
205
|
+
"qld__display-flex qld__align-items-start",
|
|
206
|
+
item("1") + item(cls.replace("qld__align-self-", ""), { cls }) + item("3"),
|
|
207
|
+
"min-height:110px;",
|
|
208
|
+
);
|
|
209
|
+
const alignSelfCards = [
|
|
210
|
+
["qld__align-self-start", "This item aligns to the cross-start."],
|
|
211
|
+
["qld__align-self-end", "This item aligns to the cross-end."],
|
|
212
|
+
["qld__align-self-center", "This item centres on the cross axis."],
|
|
213
|
+
["qld__align-self-stretch", "This item stretches to fill the cross axis."],
|
|
214
|
+
].map(([cls, desc]) => card(`.${cls}`, desc, alignSelfDemo(cls)));
|
|
215
|
+
|
|
216
|
+
// order — the two examples from the brief, rendered live.
|
|
217
|
+
const orderCards = [
|
|
218
|
+
card(
|
|
219
|
+
".qld__order-1 … .qld__order-5",
|
|
220
|
+
"Numeric order (0–5) reorders items regardless of source order.",
|
|
221
|
+
container(
|
|
222
|
+
"qld__display-flex",
|
|
223
|
+
item("item 1", { cls: "qld__order-3" }) +
|
|
224
|
+
item("item 2", { cls: "qld__order-2" }) +
|
|
225
|
+
item("item 3", { cls: "qld__order-1" }) +
|
|
226
|
+
item("item 4", { cls: "qld__order-5" }) +
|
|
227
|
+
item("item 5", { cls: "qld__order-4" }),
|
|
228
|
+
),
|
|
229
|
+
),
|
|
230
|
+
card(
|
|
231
|
+
".qld__order-first / .qld__order-last",
|
|
232
|
+
"order-first (order: -1) and order-last (order: 6) jump an item to the ends.",
|
|
233
|
+
container(
|
|
234
|
+
"qld__display-flex",
|
|
235
|
+
item("item 1", { cls: "qld__order-last" }) +
|
|
236
|
+
item("item 2") +
|
|
237
|
+
item("item 3", { cls: "qld__order-first" }),
|
|
238
|
+
),
|
|
239
|
+
),
|
|
240
|
+
];
|
|
241
|
+
|
|
242
|
+
// Responsive-variant note. Every utility has breakpoint variants that apply from
|
|
243
|
+
// the named breakpoint up; widths mirror the QLD-media breakpoints in globals.js.
|
|
244
|
+
const responsiveNote = `
|
|
245
|
+
<div style="margin-top:28px;padding:16px;border:1px solid ${BORDER};border-radius:6px;background:#f6f8fa;">
|
|
246
|
+
<div style="font-weight:700;font-size:15px;color:${TEXT};margin-bottom:6px;">Responsive variants</div>
|
|
247
|
+
<p style="font-size:13px;color:${MUTED};margin:0 0 8px;line-height:1.5;">
|
|
248
|
+
Every class above has <code>-sm</code>, <code>-md</code>,
|
|
249
|
+
<code>-lg</code> and <code>-xl</code> variants that take effect from
|
|
250
|
+
that breakpoint up — e.g. <code>.qld__flex-md-column</code>,
|
|
251
|
+
<code>.qld__justify-content-lg-between</code>,
|
|
252
|
+
<code>.qld__order-sm-first</code>.
|
|
253
|
+
</p>
|
|
254
|
+
<p style="font-size:13px;color:${MUTED};margin:0;line-height:1.5;">
|
|
255
|
+
Breakpoints — <strong>sm</strong> 400px · <strong>md</strong> 699px · <strong>lg</strong> 992px · <strong>xl</strong> 1312px.
|
|
256
|
+
</p>
|
|
257
|
+
</div>`;
|
|
258
|
+
|
|
259
|
+
// Page shell shared by both stories: a title, intro blurb, the section
|
|
260
|
+
// accordions, then the responsive-variant note and source line.
|
|
261
|
+
const page = (title, blurb, sections) => `
|
|
262
|
+
<div style="font-family:${SANS};color:${TEXT};padding:1rem;">
|
|
263
|
+
<h1 style="font-size:28px;font-weight:700;margin:0 0 8px;">${title}</h1>
|
|
264
|
+
<p style="color:${MUTED};margin:0 0 8px;max-width:72ch;line-height:1.5;">${blurb}</p>
|
|
265
|
+
<p style="margin:0 0 8px;font-size:13px;color:${MUTED};">
|
|
266
|
+
<strong>Resources:</strong>
|
|
267
|
+
<a href="${DS_URL}" target="_blank" rel="noopener noreferrer" style="color:${LINK};">QLD Design System ↗</a>
|
|
268
|
+
</p>
|
|
269
|
+
<p style="margin:0 0 8px;font-size:13px;color:${MUTED};">
|
|
270
|
+
Source: <code>${SOURCE}</code>
|
|
271
|
+
</p>
|
|
272
|
+
${sections}
|
|
273
|
+
${responsiveNote}
|
|
274
|
+
</div>`;
|
|
275
|
+
|
|
276
|
+
// Parent utilities go on the flex container itself.
|
|
277
|
+
const renderParent = () =>
|
|
278
|
+
page(
|
|
279
|
+
"Flexbox utilities — flex container (parent)",
|
|
280
|
+
`Classes that go on the flex <strong>container</strong>. Start with
|
|
281
|
+
<code>.qld__display-flex</code> to make an element a flex parent, then
|
|
282
|
+
control the flow of its children with direction, wrap, and the justify/align utilities.
|
|
283
|
+
Every demo below is live — it uses the real <code>qld__</code> classes
|
|
284
|
+
compiled into the design system.`,
|
|
285
|
+
`${section("Display", displayCards.length, displayCards)}
|
|
286
|
+
${section("Flex direction", directionCards.length, directionCards)}
|
|
287
|
+
${section("Justify content — main axis", justifyCards.length, justifyCards)}
|
|
288
|
+
${section("Align items — cross axis", alignItemsCards.length, alignItemsCards)}
|
|
289
|
+
${section("Flex wrap", wrapCards.length, wrapCards)}
|
|
290
|
+
${section("Align content — wrapped lines", alignContentCards.length, alignContentCards)}`,
|
|
291
|
+
);
|
|
292
|
+
|
|
293
|
+
// Child utilities go on the individual flex items.
|
|
294
|
+
const renderChildren = () =>
|
|
295
|
+
page(
|
|
296
|
+
"Flexbox utilities — flex items (children)",
|
|
297
|
+
`Classes that go on the individual flex <strong>items</strong> inside a
|
|
298
|
+
<code>.qld__display-flex</code> parent. Reorder items, control how they grow
|
|
299
|
+
and shrink to share space, and override the parent's cross-axis alignment for a single item.
|
|
300
|
+
Every demo below is live — it uses the real <code>qld__</code> classes
|
|
301
|
+
compiled into the design system.`,
|
|
302
|
+
`${section("Order", orderCards.length, orderCards)}
|
|
303
|
+
${section("Grow, shrink & fill", growShrinkCards.length, growShrinkCards)}
|
|
304
|
+
${section("Align self", alignSelfCards.length, alignSelfCards)}`,
|
|
305
|
+
);
|
|
306
|
+
|
|
307
|
+
export default {
|
|
308
|
+
title: "1. Core Styles/Flexbox utilities",
|
|
309
|
+
// This is a utility reference page, so opt out of the auto-generated docs page
|
|
310
|
+
// (autodocs is enabled globally in preview.js), matching Colours.stories.js.
|
|
311
|
+
tags: ["!autodocs"],
|
|
312
|
+
};
|
|
313
|
+
|
|
314
|
+
// Split by where the class is applied: container-level utilities vs item-level.
|
|
315
|
+
export const FlexContainerParent = { render: () => renderParent() };
|
|
316
|
+
export const FlexItemsChildren = { render: () => renderChildren() };
|
|
@@ -1,12 +1,30 @@
|
|
|
1
1
|
import {
|
|
2
2
|
dummyImageLink,
|
|
3
3
|
dummyText,
|
|
4
|
+
imagePositionDemoImage,
|
|
5
|
+
imagePositionDemoImagePortrait,
|
|
4
6
|
storyParams,
|
|
5
7
|
} from "../../../.storybook/globals";
|
|
6
8
|
|
|
9
|
+
const imageRatios = ["1x1", "3x2", "2x3", "4x3", "3x4", "16x9"];
|
|
10
|
+
|
|
11
|
+
const imagePositions = [
|
|
12
|
+
"center",
|
|
13
|
+
"left",
|
|
14
|
+
"right",
|
|
15
|
+
"top",
|
|
16
|
+
"bottom",
|
|
17
|
+
"left-top",
|
|
18
|
+
"right-top",
|
|
19
|
+
"left-bottom",
|
|
20
|
+
"right-bottom",
|
|
21
|
+
];
|
|
22
|
+
|
|
7
23
|
function render(args) {
|
|
8
24
|
const classes = [
|
|
9
25
|
args.responsiveMediaImg ? "qld__responsive-media-img" : "",
|
|
26
|
+
args.imageRatio ? `qld__image-ratio-${args.imageRatio}` : "",
|
|
27
|
+
args.imagePosition ? `qld__image-position--${args.imagePosition}` : "",
|
|
10
28
|
args.extraClasses,
|
|
11
29
|
]
|
|
12
30
|
.filter(Boolean)
|
|
@@ -57,6 +75,18 @@ const meta = {
|
|
|
57
75
|
description: "Applies responsive media image styling to the image.",
|
|
58
76
|
control: { type: "boolean" },
|
|
59
77
|
},
|
|
78
|
+
imageRatio: {
|
|
79
|
+
description:
|
|
80
|
+
"Crops the image to a fixed aspect ratio via the qld__image-ratio-* utility.",
|
|
81
|
+
control: { type: "select" },
|
|
82
|
+
options: ["", ...imageRatios],
|
|
83
|
+
},
|
|
84
|
+
imagePosition: {
|
|
85
|
+
description:
|
|
86
|
+
"Chooses which part of a cropped image stays in frame via the qld__image-position--* utility. Needs a crop to act on, such as an image ratio.",
|
|
87
|
+
control: { type: "select" },
|
|
88
|
+
options: ["", ...imagePositions],
|
|
89
|
+
},
|
|
60
90
|
extraClasses: {
|
|
61
91
|
description: "Any additional classes to apply to the image.",
|
|
62
92
|
control: { type: "text" },
|
|
@@ -71,6 +101,8 @@ const meta = {
|
|
|
71
101
|
"Supplied by Stephen Doggett, Department of Medical Entomology, NSW Health Pathology.",
|
|
72
102
|
rightAligned: false,
|
|
73
103
|
responsiveMediaImg: false,
|
|
104
|
+
imageRatio: "",
|
|
105
|
+
imagePosition: "",
|
|
74
106
|
extraClasses: "",
|
|
75
107
|
},
|
|
76
108
|
decorators: [
|
|
@@ -93,6 +125,156 @@ export const WithoutCaption = {
|
|
|
93
125
|
args: { caption: "" },
|
|
94
126
|
};
|
|
95
127
|
|
|
128
|
+
export const FixedRatio = {
|
|
129
|
+
args: { imageRatio: "1x1" },
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
export const RightAlignedFixedRatio = {
|
|
133
|
+
args: { rightAligned: true, imageRatio: "16x9" },
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Every `qld__image-ratio-*` utility applied directly to the `img`, sharing one
|
|
138
|
+
* source image so the difference is purely the crop.
|
|
139
|
+
*/
|
|
140
|
+
export const AllRatios = {
|
|
141
|
+
name: "All image ratios",
|
|
142
|
+
render: (args) =>
|
|
143
|
+
`<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 24px;">
|
|
144
|
+
${imageRatios
|
|
145
|
+
.map(
|
|
146
|
+
(ratio) => `<figure>
|
|
147
|
+
<img
|
|
148
|
+
loading="lazy"
|
|
149
|
+
src="${args.src}"
|
|
150
|
+
alt="${args.alt}"
|
|
151
|
+
width="${args.width}"
|
|
152
|
+
height="${args.height}"
|
|
153
|
+
class="qld__image-ratio-${ratio}"
|
|
154
|
+
/>
|
|
155
|
+
<figcaption>qld__image-ratio-${ratio}</figcaption>
|
|
156
|
+
</figure>`,
|
|
157
|
+
)
|
|
158
|
+
.join("\n ")}
|
|
159
|
+
</div>`,
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* The utility also works on a wrapper — put it on the `figure` (or any
|
|
164
|
+
* containing element) and the image inside is cropped to match.
|
|
165
|
+
*/
|
|
166
|
+
export const RatioOnWrapper = {
|
|
167
|
+
name: "Ratio on the wrapper",
|
|
168
|
+
render: (args) =>
|
|
169
|
+
`<figure class="qld__image-ratio-16x9" style="max-width: 480px;">
|
|
170
|
+
<img
|
|
171
|
+
loading="lazy"
|
|
172
|
+
src="${args.src}"
|
|
173
|
+
alt="${args.alt}"
|
|
174
|
+
width="${args.width}"
|
|
175
|
+
height="${args.height}"
|
|
176
|
+
/>
|
|
177
|
+
</figure>`,
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Every `qld__image-position--*` utility, over a test sheet that names the zone
|
|
182
|
+
* left in frame.
|
|
183
|
+
*
|
|
184
|
+
* `object-position` can only slide an image along the axis its crop overflows,
|
|
185
|
+
* so no single crop shows all nine utilities doing something. The first row
|
|
186
|
+
* crops a landscape sheet to a tall frame — spare width, so the `left`/`right`
|
|
187
|
+
* half of each name bites and the `top`/`bottom` half sits idle. The second row
|
|
188
|
+
* crops a portrait sheet to a wide frame, which is the other way round.
|
|
189
|
+
*/
|
|
190
|
+
export const AllPositions = {
|
|
191
|
+
name: "All image positions",
|
|
192
|
+
args: { alt: "Test sheet of nine labelled zones" },
|
|
193
|
+
render: (args) => {
|
|
194
|
+
const reference = (src) =>
|
|
195
|
+
`<figure style="max-width: 300px;">
|
|
196
|
+
<img loading="lazy" src="${src}" alt="${args.alt}" />
|
|
197
|
+
<figcaption>Uncropped source</figcaption>
|
|
198
|
+
</figure>`;
|
|
199
|
+
|
|
200
|
+
const grid = (src, ratio) =>
|
|
201
|
+
`<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 24px;">
|
|
202
|
+
${imagePositions
|
|
203
|
+
.map(
|
|
204
|
+
(position) => `<figure>
|
|
205
|
+
<img
|
|
206
|
+
loading="lazy"
|
|
207
|
+
src="${src}"
|
|
208
|
+
alt="${args.alt}"
|
|
209
|
+
class="qld__image-ratio-${ratio} qld__image-position--${position}"
|
|
210
|
+
/>
|
|
211
|
+
<figcaption>qld__image-position--${position}</figcaption>
|
|
212
|
+
</figure>`,
|
|
213
|
+
)
|
|
214
|
+
.join("\n ")}
|
|
215
|
+
</div>`;
|
|
216
|
+
|
|
217
|
+
return `<h3>Landscape image, tall crop — slides left and right</h3>
|
|
218
|
+
${reference(imagePositionDemoImage)}
|
|
219
|
+
${grid(imagePositionDemoImage, "2x3")}
|
|
220
|
+
<h3 class="qld__margin-t-component">Portrait image, wide crop — slides up and down</h3>
|
|
221
|
+
${reference(imagePositionDemoImagePortrait)}
|
|
222
|
+
${grid(imagePositionDemoImagePortrait, "16x9")}`;
|
|
223
|
+
},
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
const borderRadiusSizes = ["xs", "sm", "md", "lg"];
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* One figure per radius size, plus a final figure carrying the utility itself.
|
|
230
|
+
* `captioned` decides whether each figure gets a `figcaption`, which is what
|
|
231
|
+
* changes how the radius has to be applied.
|
|
232
|
+
*/
|
|
233
|
+
function renderRoundedGrid(args, captioned) {
|
|
234
|
+
const label = (text) => (captioned ? `<figcaption>${text}</figcaption>` : "");
|
|
235
|
+
|
|
236
|
+
const image = (classes) => `<img
|
|
237
|
+
loading="lazy"
|
|
238
|
+
src="${args.src}"
|
|
239
|
+
alt="${args.alt}"
|
|
240
|
+
class="qld__image-ratio-4x3${classes ? ` ${classes}` : ""}"
|
|
241
|
+
/>`;
|
|
242
|
+
|
|
243
|
+
return `<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 24px;">
|
|
244
|
+
${borderRadiusSizes
|
|
245
|
+
.map(
|
|
246
|
+
(size) => `<figure>
|
|
247
|
+
${image(`qld__border-radius--${size}`)}
|
|
248
|
+
${label(`img.qld__border-radius--${size}`)}
|
|
249
|
+
</figure>`,
|
|
250
|
+
)
|
|
251
|
+
.join("\n ")}
|
|
252
|
+
<figure class="qld__border-radius--md">
|
|
253
|
+
${image("")}
|
|
254
|
+
${label("figure.qld__border-radius--md")}
|
|
255
|
+
</figure>
|
|
256
|
+
</div>`;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* `qld__border-radius--*` on the image rounds the top corners and passes the
|
|
261
|
+
* matching radius to the caption, so the pair reads as one rounded block. Put
|
|
262
|
+
* the same utility on the `figure` instead and it clips its contents to shape.
|
|
263
|
+
*/
|
|
264
|
+
export const RoundedCorners = {
|
|
265
|
+
name: "Rounded corners",
|
|
266
|
+
render: (args) => renderRoundedGrid(args, true),
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Without a caption the image keeps all four corners, whether the utility sits
|
|
271
|
+
* on the `img` or on the `figure` around it.
|
|
272
|
+
*/
|
|
273
|
+
export const RoundedCornersWithoutCaption = {
|
|
274
|
+
name: "Rounded corners without caption",
|
|
275
|
+
render: (args) => renderRoundedGrid(args, false),
|
|
276
|
+
};
|
|
277
|
+
|
|
96
278
|
export const ResponsiveImage = {
|
|
97
279
|
args: { responsiveMediaImg: true },
|
|
98
280
|
decorators: [
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { initComponents } from "../../../.storybook/decorators";
|
|
2
|
+
import { initMegaMenu } from "../../components/mega_main_navigation/js/global";
|
|
3
|
+
import initCtaLinks from "../../components/_global/js/cta_links/global";
|
|
4
|
+
import { initAccordion } from "../../components/accordion/js/global";
|
|
5
|
+
import initInternalNavigation from "../../components/internal_navigation/js/global";
|
|
6
|
+
import initInPageNavigation from "../../components/in_page_navigation/js/global";
|
|
7
|
+
import initPromoPanel from "../../components/promo_panel/js/global";
|
|
8
|
+
import {
|
|
9
|
+
renderSiteHeader,
|
|
10
|
+
renderSiteFooter,
|
|
11
|
+
renderPrefooter,
|
|
12
|
+
renderBanner,
|
|
13
|
+
renderSideNav,
|
|
14
|
+
renderInPageNav,
|
|
15
|
+
renderPromoPanel,
|
|
16
|
+
contentBody,
|
|
17
|
+
} from "./templateHelpers.js";
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* A full content page: header + mega main nav, a banner with breadcrumbs, a
|
|
21
|
+
* side navigation beside the main content, an in-page ("On this page")
|
|
22
|
+
* navigation, body copy, a pre-footer and the footer.
|
|
23
|
+
*/
|
|
24
|
+
function renderContentPage(args) {
|
|
25
|
+
const { site } = args;
|
|
26
|
+
|
|
27
|
+
return `
|
|
28
|
+
${renderSiteHeader(site)}
|
|
29
|
+
<main class="main" role="main">
|
|
30
|
+
${renderBanner({
|
|
31
|
+
headingPrimary: "Applying for a health card",
|
|
32
|
+
abstract:
|
|
33
|
+
"Everything you need to know about eligibility, the application process and what happens next.",
|
|
34
|
+
backgroundColour: "dark",
|
|
35
|
+
backgroundType: "texture",
|
|
36
|
+
showBreadcrumbs: true,
|
|
37
|
+
})}
|
|
38
|
+
<div class="qld__body">
|
|
39
|
+
<div class="container-fluid">
|
|
40
|
+
<div class="row">
|
|
41
|
+
<div class="col-xs-12 col-md-4 col-lg-3">
|
|
42
|
+
${renderSideNav()}
|
|
43
|
+
</div>
|
|
44
|
+
<div class="col-xs-12 col-md-8 col-lg-9" id="content">
|
|
45
|
+
${renderInPageNav()}
|
|
46
|
+
${contentBody()}
|
|
47
|
+
</div>
|
|
48
|
+
</div>
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
${renderPromoPanel(site, {
|
|
52
|
+
title: "Need help with your application?",
|
|
53
|
+
abstract:
|
|
54
|
+
"Our team can guide you through eligibility, the application process and what happens next.",
|
|
55
|
+
imageAlignment: "qld__promo-panel--image-right",
|
|
56
|
+
bodyBackground: "qld__body--light",
|
|
57
|
+
promoPanelIcon: undefined,
|
|
58
|
+
})}
|
|
59
|
+
${renderPrefooter(site, { pageType: "content" })}
|
|
60
|
+
</main>
|
|
61
|
+
${renderSiteFooter(site)}
|
|
62
|
+
`;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export default {
|
|
66
|
+
title: "4. Templates/Content page",
|
|
67
|
+
render: renderContentPage,
|
|
68
|
+
parameters: {
|
|
69
|
+
layout: "fullscreen",
|
|
70
|
+
docs: {
|
|
71
|
+
description: {
|
|
72
|
+
component:
|
|
73
|
+
"A representative content page assembled from the design system's " +
|
|
74
|
+
"layout and component stories: header with the horizontal mega " +
|
|
75
|
+
"navigation, a banner carrying breadcrumbs, a side navigation, the " +
|
|
76
|
+
"main content column with an in-page navigation and body copy, then " +
|
|
77
|
+
"the pre-footer and footer.",
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
// All the interactive chrome a content page needs: the mega menu and its CTA
|
|
82
|
+
// links, the side nav (an accordion below its breakpoint), and the in-page
|
|
83
|
+
// navigation that builds its list from the headings inside `#content`.
|
|
84
|
+
decorators: [
|
|
85
|
+
initComponents([
|
|
86
|
+
initMegaMenu,
|
|
87
|
+
initCtaLinks,
|
|
88
|
+
initAccordion,
|
|
89
|
+
initInternalNavigation,
|
|
90
|
+
initInPageNavigation,
|
|
91
|
+
initPromoPanel,
|
|
92
|
+
]),
|
|
93
|
+
],
|
|
94
|
+
// The page supplies its own full-width layout, so opt out of controls that
|
|
95
|
+
// don't apply to a whole-page composition.
|
|
96
|
+
argTypes: {
|
|
97
|
+
site: { table: { disable: true } },
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
export const Default = {};
|