vanilla-framework 4.44.0 → 4.45.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/package.json
CHANGED
|
@@ -97,6 +97,18 @@
|
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
+
%vf-pseudo-border--left {
|
|
101
|
+
position: relative;
|
|
102
|
+
|
|
103
|
+
&::before {
|
|
104
|
+
@extend %vf-pseudo-border;
|
|
105
|
+
bottom: 0;
|
|
106
|
+
height: auto;
|
|
107
|
+
top: 0;
|
|
108
|
+
width: 1px;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
100
112
|
%hr {
|
|
101
113
|
background: $colors--theme--border-default;
|
|
102
114
|
border: 0;
|
|
@@ -0,0 +1,440 @@
|
|
|
1
|
+
@import 'settings';
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
@classreference
|
|
5
|
+
in-page-navigation:
|
|
6
|
+
Root element:
|
|
7
|
+
.p-in-page-navigation:
|
|
8
|
+
in-page navigation in default variant.
|
|
9
|
+
"&.is-sticky":
|
|
10
|
+
Sticky version of in-page navigation.
|
|
11
|
+
|
|
12
|
+
Dropdown toggle:
|
|
13
|
+
.p-in-page-navigation__dropdown-toggle:
|
|
14
|
+
Button to toggle between horizontal and vertical dropdown navigation on small/medium screens.
|
|
15
|
+
.p-in-page-navigation__dropdown-toggle-icon:
|
|
16
|
+
Chevron icon inside the dropdown toggle button.
|
|
17
|
+
|
|
18
|
+
Items list heading:
|
|
19
|
+
.p-in-page-navigation__heading:
|
|
20
|
+
Heading for in-page navigation items group (text only).
|
|
21
|
+
|
|
22
|
+
Items list:
|
|
23
|
+
.p-in-page-navigation__list:
|
|
24
|
+
Group of in-page navigation items (usually a `<ul>` element).
|
|
25
|
+
|
|
26
|
+
Item element:
|
|
27
|
+
.p-in-page-navigation__item:
|
|
28
|
+
Single item in in-page navigation (usually a `<li>` element). May contain nested items lists.
|
|
29
|
+
|
|
30
|
+
Item link:
|
|
31
|
+
.p-in-page-navigation__link:
|
|
32
|
+
Single link in the in-page navigation.
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
// Shared text styles mixin
|
|
36
|
+
@mixin vf-in-page-navigation-text {
|
|
37
|
+
@include vf-in-page-navigation-spacing-left;
|
|
38
|
+
|
|
39
|
+
padding-bottom: $spv--x-small;
|
|
40
|
+
padding-right: 0;
|
|
41
|
+
padding-top: $spv--x-small;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Shared link styles for large screens and expanded dropdown
|
|
45
|
+
@mixin vf-in-page-navigation-link-vertical {
|
|
46
|
+
-webkit-box-orient: vertical;
|
|
47
|
+
display: -webkit-box;
|
|
48
|
+
-webkit-line-clamp: 2;
|
|
49
|
+
line-clamp: 2;
|
|
50
|
+
overflow: hidden;
|
|
51
|
+
text-overflow: ellipsis;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
@mixin vf-p-in-page-navigation {
|
|
55
|
+
// Use a consistent border width for left-highlight and list border
|
|
56
|
+
$in-page-navigation-border-width: 3px;
|
|
57
|
+
|
|
58
|
+
// Scroll margins for headings within the parent grid section
|
|
59
|
+
.grid-row:has(.p-in-page-navigation) {
|
|
60
|
+
/* stylelint-disable selector-max-type */
|
|
61
|
+
h2,
|
|
62
|
+
h3,
|
|
63
|
+
h4 {
|
|
64
|
+
/* stylelint-enable selector-max-type */
|
|
65
|
+
scroll-margin-top: 72px;
|
|
66
|
+
|
|
67
|
+
@media screen and (width >= $threshold-4-8-col) {
|
|
68
|
+
scroll-margin-top: 24px;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// When the page has a sticky main navigation, increase scroll margin
|
|
72
|
+
// to account for the fixed header height. This prevents headings from
|
|
73
|
+
// being hidden behind the navigation when scrolling to anchors.
|
|
74
|
+
@at-root body:has(.p-navigation.is-sticky) &,
|
|
75
|
+
body:has(.p-navigation--sliding.is-sticky) & {
|
|
76
|
+
scroll-margin-top: 120px;
|
|
77
|
+
|
|
78
|
+
@media screen and (width >= $threshold-4-8-col) {
|
|
79
|
+
scroll-margin-top: 80px;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Sticky styles for large screens
|
|
86
|
+
.p-in-page-navigation {
|
|
87
|
+
margin-bottom: $spv--strip-regular;
|
|
88
|
+
max-height: 100vh;
|
|
89
|
+
overflow-y: auto;
|
|
90
|
+
position: sticky;
|
|
91
|
+
top: $spv--strip-shallow;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// We re-enable scrolling when the dropdown is expanded on small/medium screens
|
|
95
|
+
// `is-expanded` class is toggled via JS
|
|
96
|
+
.p-in-page-navigation.is-expanded {
|
|
97
|
+
overflow-y: auto;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Custom tooltip styles for scrollable navigation
|
|
101
|
+
// We dynamically calculate the position using JS
|
|
102
|
+
.p-in-page-navigation .p-tooltip--right {
|
|
103
|
+
position: relative;
|
|
104
|
+
|
|
105
|
+
.p-tooltip__message {
|
|
106
|
+
// Position will be set via JS using CSS custom properties
|
|
107
|
+
left: var(--tooltip-left, auto);
|
|
108
|
+
// Use fixed positioning to escape overflow clipping
|
|
109
|
+
position: fixed;
|
|
110
|
+
top: var(--tooltip-top, auto);
|
|
111
|
+
z-index: 100;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Left hand border
|
|
116
|
+
.p-in-page-navigation__container > .p-in-page-navigation__list {
|
|
117
|
+
@extend %vf-pseudo-border--left;
|
|
118
|
+
|
|
119
|
+
&::before {
|
|
120
|
+
background-color: $colors--theme--border-low-contrast;
|
|
121
|
+
width: $in-page-navigation-border-width;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.p-in-page-navigation__list {
|
|
126
|
+
@extend %vf-list;
|
|
127
|
+
color: $colors--theme--text-inactive;
|
|
128
|
+
|
|
129
|
+
&:last-of-type::after {
|
|
130
|
+
content: none;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.p-in-page-navigation__heading {
|
|
135
|
+
@extend %common-default-text-properties;
|
|
136
|
+
@extend %small-caps-text;
|
|
137
|
+
|
|
138
|
+
display: block;
|
|
139
|
+
font-size: map-get($base-font-sizes, base);
|
|
140
|
+
font-weight: $font-weight-bold;
|
|
141
|
+
margin: 0;
|
|
142
|
+
max-width: none;
|
|
143
|
+
padding: $spv--x-small 0 $spv--small;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.p-in-page-navigation__link {
|
|
147
|
+
@include vf-in-page-navigation-text;
|
|
148
|
+
@include vf-in-page-navigation-link-vertical;
|
|
149
|
+
@include vf-focus-themed;
|
|
150
|
+
|
|
151
|
+
color: $colors--theme--text-muted;
|
|
152
|
+
|
|
153
|
+
&:visited {
|
|
154
|
+
color: $colors--theme--text-muted;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
&:hover {
|
|
158
|
+
color: $colors--theme--text-default;
|
|
159
|
+
text-decoration: none;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// vf-highlight-bar is rendered above focus outline
|
|
163
|
+
// so we need to hide it on focus
|
|
164
|
+
&:focus::before {
|
|
165
|
+
display: none;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Display the highlight when focussing in modern browsers that support
|
|
169
|
+
// focus-visible.
|
|
170
|
+
&:focus:not(:focus-visible)::before {
|
|
171
|
+
display: block;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Active state for current navigation item
|
|
175
|
+
&.is-active,
|
|
176
|
+
&[aria-current='true'] {
|
|
177
|
+
@extend %vf-pseudo-border--left;
|
|
178
|
+
|
|
179
|
+
color: $colors--theme--text-default;
|
|
180
|
+
cursor: default;
|
|
181
|
+
|
|
182
|
+
&::before {
|
|
183
|
+
background-color: $colors--theme--text-default;
|
|
184
|
+
width: $in-page-navigation-border-width;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Dropdown toggle button
|
|
190
|
+
.p-in-page-navigation__dropdown-toggle {
|
|
191
|
+
background-color: $colors--theme--background-default;
|
|
192
|
+
border: 0;
|
|
193
|
+
display: none;
|
|
194
|
+
line-height: map-get($icon-sizes, default);
|
|
195
|
+
margin: 0;
|
|
196
|
+
padding: $spv--large $sph--x-large;
|
|
197
|
+
|
|
198
|
+
&:focus {
|
|
199
|
+
@include vf-focus;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
&:hover {
|
|
203
|
+
background: $colors--theme--background-default;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
.p-in-page-navigation__dropdown-toggle-icon {
|
|
207
|
+
height: map-get($icon-sizes, default);
|
|
208
|
+
width: map-get($icon-sizes, default);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
.p-in-page-navigation__container {
|
|
213
|
+
position: relative;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// Nested 2nd level of navigation indentation
|
|
217
|
+
.p-in-page-navigation__item .p-in-page-navigation__list .p-in-page-navigation__link {
|
|
218
|
+
// @media screen and (width >= $threshold-4-8-col) {
|
|
219
|
+
@include vf-in-page-navigation-spacing-left($multiplier: 2);
|
|
220
|
+
// }
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Small/medium screens
|
|
224
|
+
@media screen and (width < $threshold-4-8-col) {
|
|
225
|
+
.p-in-page-navigation {
|
|
226
|
+
background-color: $colors--theme--background-default;
|
|
227
|
+
margin-bottom: $spv--strip-shallow;
|
|
228
|
+
margin-left: (-$spv--x-large);
|
|
229
|
+
margin-right: (-$spv--x-large);
|
|
230
|
+
overflow-y: unset;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Sticky styles for parent column
|
|
234
|
+
// IMPORTANT: Pattern requires a grid-col as a parent
|
|
235
|
+
[class^='grid-col']:has(> .p-in-page-navigation) {
|
|
236
|
+
position: sticky;
|
|
237
|
+
top: 0;
|
|
238
|
+
z-index: 1;
|
|
239
|
+
|
|
240
|
+
> .p-in-page-navigation {
|
|
241
|
+
position: static;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// Top level navigation list
|
|
246
|
+
.p-in-page-navigation__container > .p-in-page-navigation__list {
|
|
247
|
+
background-color: $colors--theme--background-default;
|
|
248
|
+
padding-left: $spv--large;
|
|
249
|
+
|
|
250
|
+
&::before {
|
|
251
|
+
left: $spv--large;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
> .p-in-page-navigation__item {
|
|
255
|
+
scroll-margin-left: $spv--large;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// Hide heading unless dropdown is expanded
|
|
260
|
+
.p-in-page-navigation__heading {
|
|
261
|
+
display: none;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// Link styles for horizontal layout
|
|
265
|
+
.p-in-page-navigation__link {
|
|
266
|
+
display: inline-block;
|
|
267
|
+
line-height: $spv--x-large;
|
|
268
|
+
max-width: 33.33vw; // Limit link width to 1/3 viewport
|
|
269
|
+
overflow: hidden;
|
|
270
|
+
padding: $spv--medium $spv--large;
|
|
271
|
+
text-overflow: ellipsis;
|
|
272
|
+
vertical-align: middle;
|
|
273
|
+
|
|
274
|
+
// Adjust active state pseudo-border for horizontal layout
|
|
275
|
+
&.is-active,
|
|
276
|
+
&[aria-current='true'] {
|
|
277
|
+
&::before {
|
|
278
|
+
height: 50%;
|
|
279
|
+
top: 25%;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// Nested link indentation when expanded
|
|
285
|
+
.p-in-page-navigation.is-expanded .p-in-page-navigation__item .p-in-page-navigation__list .p-in-page-navigation__link {
|
|
286
|
+
@include vf-in-page-navigation-spacing-left($multiplier: 2);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// Container styles for horizontal layout
|
|
290
|
+
.p-in-page-navigation__container {
|
|
291
|
+
align-items: center;
|
|
292
|
+
background-color: $colors--theme--background-default;
|
|
293
|
+
display: grid;
|
|
294
|
+
grid-template-columns: 1fr auto;
|
|
295
|
+
|
|
296
|
+
// Full-width bottom border
|
|
297
|
+
&::after {
|
|
298
|
+
background-color: $colors--theme--border-low-contrast;
|
|
299
|
+
bottom: 0;
|
|
300
|
+
content: '';
|
|
301
|
+
height: 1px;
|
|
302
|
+
left: 50%;
|
|
303
|
+
position: absolute;
|
|
304
|
+
transform: translateX(-50%);
|
|
305
|
+
width: 100%;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
.p-in-page-navigation__dropdown-toggle {
|
|
310
|
+
display: block;
|
|
311
|
+
grid-column: 2;
|
|
312
|
+
justify-self: end;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// Collapsed dropdown styles
|
|
316
|
+
.p-in-page-navigation:not(.is-expanded) .p-in-page-navigation__container {
|
|
317
|
+
.p-in-page-navigation__list {
|
|
318
|
+
grid-column: 1;
|
|
319
|
+
margin-bottom: 0;
|
|
320
|
+
min-width: 0;
|
|
321
|
+
overflow-x: auto;
|
|
322
|
+
overflow-y: hidden;
|
|
323
|
+
scroll-behavior: smooth;
|
|
324
|
+
scrollbar-width: none; // Firefox
|
|
325
|
+
white-space: nowrap;
|
|
326
|
+
|
|
327
|
+
&::-webkit-scrollbar {
|
|
328
|
+
display: none; // Chrome/Safari/Opera
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// Remove left side border
|
|
332
|
+
&::before {
|
|
333
|
+
content: none;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
.p-in-page-navigation__item {
|
|
337
|
+
display: inline-block;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// Hide nested lists
|
|
342
|
+
.p-in-page-navigation__item .p-in-page-navigation__list {
|
|
343
|
+
display: none;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// Expanded dropdown styles
|
|
348
|
+
// Grid layout: [list content | toggle button]
|
|
349
|
+
// Row 1: heading * | toggle
|
|
350
|
+
// Row 2: nav list |
|
|
351
|
+
// * If present, otherwise nav list is in row 1
|
|
352
|
+
.p-in-page-navigation.is-expanded .p-in-page-navigation__container {
|
|
353
|
+
align-items: start;
|
|
354
|
+
background-color: $colors--theme--background-alt;
|
|
355
|
+
display: grid;
|
|
356
|
+
grid-template-columns: 1fr auto;
|
|
357
|
+
|
|
358
|
+
> .p-in-page-navigation__list {
|
|
359
|
+
background-color: $colors--theme--background-alt;
|
|
360
|
+
grid-column: 1 / 2;
|
|
361
|
+
grid-row: 2;
|
|
362
|
+
margin-bottom: $spv--large;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
.p-in-page-navigation__item .p-in-page-navigation__list {
|
|
366
|
+
display: block;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
.p-in-page-navigation__heading {
|
|
370
|
+
display: block;
|
|
371
|
+
grid-column: 1 / 2;
|
|
372
|
+
grid-row: 1;
|
|
373
|
+
padding: $spv--medium $spv--large;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// Override for when there is no heading
|
|
377
|
+
&:not(:has(> .p-in-page-navigation__heading)) > .p-in-page-navigation__list {
|
|
378
|
+
grid-row: 1;
|
|
379
|
+
margin-top: $spv--medium;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
.p-in-page-navigation__dropdown-toggle {
|
|
383
|
+
background-color: $colors--theme--background-alt;
|
|
384
|
+
display: block;
|
|
385
|
+
grid-column: 2 / 3;
|
|
386
|
+
grid-row: 1;
|
|
387
|
+
justify-self: end;
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
.p-in-page-navigation.is-expanded .p-in-page-navigation__link {
|
|
392
|
+
@include vf-in-page-navigation-text;
|
|
393
|
+
@include vf-in-page-navigation-link-vertical;
|
|
394
|
+
|
|
395
|
+
max-width: unset;
|
|
396
|
+
padding-right: $spv--large;
|
|
397
|
+
|
|
398
|
+
&.is-active,
|
|
399
|
+
&[aria-current='true'] {
|
|
400
|
+
&::before {
|
|
401
|
+
height: auto;
|
|
402
|
+
top: 0;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
// Small screens only
|
|
409
|
+
@media screen and (width < $threshold-4-small-4-med-col) {
|
|
410
|
+
.p-in-page-navigation {
|
|
411
|
+
margin-left: (-$spv--large);
|
|
412
|
+
margin-right: (-$spv--large);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
.p-in-page-navigation__link {
|
|
416
|
+
max-width: 50vw; // Limit link width to 1/2 viewport
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
.p-in-page-navigation__dropdown-toggle {
|
|
420
|
+
padding: $spv--large;
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
// Helper
|
|
426
|
+
|
|
427
|
+
// elements in side nav should be aligned from left based on grid margin for given screen size
|
|
428
|
+
// additional offset is added when icons are used or for nested navigation levels
|
|
429
|
+
@mixin vf-in-page-navigation-spacing-left(
|
|
430
|
+
// property to adjust spacing, defaults to `padding-left`
|
|
431
|
+
$prop: padding-left,
|
|
432
|
+
// how many times grid margin width should be multiplied (for nested navigation levels)
|
|
433
|
+
$multiplier: 1
|
|
434
|
+
) {
|
|
435
|
+
#{$prop}: $multiplier * map-get($grid-margin-widths, small);
|
|
436
|
+
|
|
437
|
+
@media screen and (width >= $threshold-4-small-4-med-col) {
|
|
438
|
+
#{$prop}: $multiplier * map-get($grid-margin-widths, default);
|
|
439
|
+
}
|
|
440
|
+
}
|
|
@@ -15,7 +15,7 @@ $tooltip-overlay-top-border-radius: 0% 0% 100% 100%;
|
|
|
15
15
|
|
|
16
16
|
&:focus,
|
|
17
17
|
&:hover {
|
|
18
|
-
.p-tooltip__message {
|
|
18
|
+
> .p-tooltip__message:first-of-type {
|
|
19
19
|
display: inline;
|
|
20
20
|
text-decoration: initial;
|
|
21
21
|
}
|
|
@@ -105,7 +105,7 @@ $tooltip-overlay-top-border-radius: 0% 0% 100% 100%;
|
|
|
105
105
|
.p-tooltip--btm-center {
|
|
106
106
|
@extend %tooltip;
|
|
107
107
|
|
|
108
|
-
.p-tooltip__message {
|
|
108
|
+
> .p-tooltip__message {
|
|
109
109
|
bottom: inherit;
|
|
110
110
|
left: 50%;
|
|
111
111
|
top: 100%;
|
package/scss/_vanilla.scss
CHANGED
|
@@ -54,6 +54,7 @@
|
|
|
54
54
|
@import 'patterns_separator';
|
|
55
55
|
@import 'patterns_side-navigation-expandable';
|
|
56
56
|
@import 'patterns_side-navigation';
|
|
57
|
+
@import 'patterns_in-page-navigation';
|
|
57
58
|
@import 'patterns_slider';
|
|
58
59
|
@import 'patterns_status-label';
|
|
59
60
|
@import 'patterns_strip';
|
|
@@ -156,6 +157,7 @@
|
|
|
156
157
|
@include vf-p-separator;
|
|
157
158
|
@include vf-p-side-navigation;
|
|
158
159
|
@include vf-p-side-navigation-expandable;
|
|
160
|
+
@include vf-p-in-page-navigation;
|
|
159
161
|
@include vf-p-slider;
|
|
160
162
|
@include vf-p-status-label;
|
|
161
163
|
@include vf-p-strip;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
{#
|
|
2
|
+
Parameters:
|
|
3
|
+
- title (string) (optional): The text to be displayed as the title. Defauts to None and doesn"t render.
|
|
4
|
+
- navigation_items (list<object>) (optional): A list of navigation items to be included in the in-page navigation. Each item is an object with the following properties:
|
|
5
|
+
- id (string) (required): The ID of the section to link to.
|
|
6
|
+
- text (string) (required): The text to be displayed for the navigation item.
|
|
7
|
+
- scope (string) (optional): Rendering mode for navigation items.
|
|
8
|
+
- "manual" (default): Render from `navigation_items`.
|
|
9
|
+
- "full-page": Autogenerate from headings via JS.
|
|
10
|
+
- primary_heading (string) (optional, requires scope="full-page"): The heading level to treat as primary. Accepts "h2" or "h3".
|
|
11
|
+
- secondary_heading (string) (optional, requires primary_heading): The heading level to treat as secondary. Accepts "h3" or "h4"
|
|
12
|
+
- excludes (list<string>) (optional): A list of exclusions for headings (only applies when scope="full-page").
|
|
13
|
+
Supports two formats:
|
|
14
|
+
- CSS selector (e.g. "#some-id", ".some-class"): excludes headings matching the selector.
|
|
15
|
+
- Text match (e.g. "text:Newsletter signup"): excludes headings whose text content matches (case-insensitive).
|
|
16
|
+
#}
|
|
17
|
+
|
|
18
|
+
{%- macro vf_in_page_navigation(title=None, navigation_items=[], scope="full-page", primary_heading="h2", secondary_heading=None, excludes=[]) -%}
|
|
19
|
+
{%- set nav_id = "in-page-navigation-list" -%}
|
|
20
|
+
{%- set valid_primary_headings = ["h2", "h3"] %}
|
|
21
|
+
{%- set valid_secondary_headings = ["h3", "h4"] %}
|
|
22
|
+
{%- set valid_scopes = ["full-page", "manual"] %}
|
|
23
|
+
{%- if scope not in valid_scopes -%}
|
|
24
|
+
{%- set scope = "full-page" -%}
|
|
25
|
+
{%- endif -%}
|
|
26
|
+
{%- set excludes_queries = excludes | join(",") + ",.p-in-page-navigation__heading" -%}
|
|
27
|
+
|
|
28
|
+
<div class="p-in-page-navigation"
|
|
29
|
+
data-in-page-navigation-scope="{{ scope }}"
|
|
30
|
+
{%- if primary_heading and primary_heading in valid_primary_headings -%} data-in-page-navigation-primary="{{ primary_heading }}" {%- if secondary_heading and secondary_heading in valid_secondary_headings -%} data-in-page-navigation-secondary="{{ secondary_heading }}" {%- endif -%} {%- else -%} data-in-page-navigation-primary="h2" {% endif %}
|
|
31
|
+
data-in-page-navigation-excludes="{{ excludes_queries }}">
|
|
32
|
+
|
|
33
|
+
<nav class="p-in-page-navigation__container"
|
|
34
|
+
aria-label="{% if title %}{{ title }}{% else %}In-page navigation{% endif %}">
|
|
35
|
+
|
|
36
|
+
{%- if title -%}
|
|
37
|
+
<h3 class="p-in-page-navigation__heading">{{ title | safe }}</h3>
|
|
38
|
+
{%- endif -%}
|
|
39
|
+
<ul class="p-in-page-navigation__list js-in-page-nav-list"
|
|
40
|
+
id="{{ nav_id }}"
|
|
41
|
+
aria-expanded="false">
|
|
42
|
+
{%- if scope != "full-page" -%}
|
|
43
|
+
{%- for item in navigation_items -%}
|
|
44
|
+
<li class="p-in-page-navigation__item p-tooltip--right"
|
|
45
|
+
aria-describedby="{{ item.id }}-tooltip">
|
|
46
|
+
<a class="p-in-page-navigation__link{% if loop.first %} is-active{% endif %}"
|
|
47
|
+
href="#{{ item.id }}">{{ item.text }}</a>
|
|
48
|
+
<span class="p-tooltip__message u-hide"
|
|
49
|
+
role="tooltip"
|
|
50
|
+
id="{{ item.id }}-tooltip">{{ item.text }}</span>
|
|
51
|
+
{%- if item.children -%}
|
|
52
|
+
<ul class="p-in-page-navigation__list">
|
|
53
|
+
{%- for child in item.children -%}
|
|
54
|
+
<li class="p-in-page-navigation__item p-tooltip--right"
|
|
55
|
+
aria-describedby="{{ child.id }}-tooltip">
|
|
56
|
+
<a class="p-in-page-navigation__link" href="#{{ child.id }}">{{ child.text }}</a>
|
|
57
|
+
<span class="p-tooltip__message u-hide"
|
|
58
|
+
role="tooltip"
|
|
59
|
+
id="{{ child.id }}-tooltip">{{ child.text }}</span>
|
|
60
|
+
</li>
|
|
61
|
+
{%- endfor -%}
|
|
62
|
+
</ul>
|
|
63
|
+
{%- endif -%}
|
|
64
|
+
</li>
|
|
65
|
+
{%- endfor -%}
|
|
66
|
+
{%- endif -%}
|
|
67
|
+
</ul>
|
|
68
|
+
|
|
69
|
+
<button class="p-in-page-navigation__dropdown-toggle"
|
|
70
|
+
aria-expanded="false"
|
|
71
|
+
aria-controls="{{ nav_id }}">
|
|
72
|
+
<i class="p-icon--chevron-down p-in-page-navigation__dropdown-toggle-icon"></i>
|
|
73
|
+
<i class="p-icon--chevron-up p-in-page-navigation__dropdown-toggle-icon u-hide"></i>
|
|
74
|
+
</button>
|
|
75
|
+
|
|
76
|
+
</nav>
|
|
77
|
+
</div>
|
|
78
|
+
|
|
79
|
+
{# Templates for JS auto-generation (used when scope="full-page") #}
|
|
80
|
+
{%- if scope == "full-page" -%}
|
|
81
|
+
<template class="js-in-page-nav-template-item">
|
|
82
|
+
<li class="p-in-page-navigation__item p-tooltip--right"
|
|
83
|
+
aria-describedby="#">
|
|
84
|
+
<a class="p-in-page-navigation__link" href="#"></a>
|
|
85
|
+
<span class="p-tooltip__message u-hide" role="tooltip" id="#"></span>
|
|
86
|
+
</li>
|
|
87
|
+
</template>
|
|
88
|
+
<template class="js-in-page-nav-template-sublist">
|
|
89
|
+
<ul class="p-in-page-navigation__list">
|
|
90
|
+
</ul>
|
|
91
|
+
</template>
|
|
92
|
+
{%- endif -%}
|
|
93
|
+
{%- endmacro -%}
|