@ilo-org/twig 1.0.1 → 1.0.3
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/dist/components/accordion/accordion-item.twig +2 -2
- package/dist/components/accordion/accordion.behavior.js +1 -1
- package/dist/components/accordion/accordion.css +1 -1
- package/dist/components/breadcrumb/breadcrumb.behavior.js +1 -1
- package/dist/components/breadcrumb/breadcrumb.css +1 -1
- package/dist/components/breadcrumb/breadcrumb.twig +48 -36
- package/dist/components/breadcrumb/breadcrumb.wingsuit.yml +7 -8
- package/dist/components/contextmenu/contextmenu.css +1 -1
- package/dist/components/contextmenu/contextmenu.twig +9 -9
- package/dist/components/herocard/herocard.css +1 -1
- package/dist/components/logogrid/logogrid.wingsuit.yml +1 -1
- package/dist/components/navigation/navigation.css +1 -1
- package/dist/components/promocard/promocard.css +1 -1
- package/dist/components/richtext/richtext.css +1 -1
- package/dist/components/statcard/statcard.css +1 -1
- package/dist/components/tabs/tabs.css +1 -1
- package/dist/components/tabs/tabs.twig +4 -1
- package/dist/components/tabs/tabs.wingsuit.yml +3 -134
- package/dist/components/textcard/textcard.css +1 -1
- package/package.json +6 -6
- package/src/patterns/components/accordion/accordion-item.twig +2 -2
- package/src/patterns/components/accordion/accordion.js +3 -3
- package/src/patterns/components/breadcrumb/breadcrumb.js +176 -22
- package/src/patterns/components/breadcrumb/breadcrumb.twig +48 -36
- package/src/patterns/components/breadcrumb/breadcrumb.wingsuit.yml +7 -8
- package/src/patterns/components/contextmenu/contextmenu.twig +9 -9
- package/src/patterns/components/logogrid/logogrid.wingsuit.yml +1 -1
- package/src/patterns/components/tabs/tabs.twig +4 -1
- package/src/patterns/components/tabs/tabs.wingsuit.yml +3 -134
|
@@ -7,9 +7,10 @@ tabs:
|
|
|
7
7
|
items:
|
|
8
8
|
type: object
|
|
9
9
|
label: Items
|
|
10
|
-
description: The items and labels for each tab
|
|
10
|
+
description: The items and labels for each tab. Each item takes a `label` property which gives the tag a name, a `component` property which specifies the kind of component the tab should render, and the `componentdata` which contains the data that will be passed to that component. You can also include an optional `icon` component with the name of the icon to render next to the label.
|
|
11
11
|
preview:
|
|
12
12
|
- label: "Tab Label With A Really Really Lenghty Title Even Though We Do Not Recommend Such A Lengthy Title"
|
|
13
|
+
icon: "info"
|
|
13
14
|
component: "image"
|
|
14
15
|
componentdata:
|
|
15
16
|
alt: "My alt text"
|
|
@@ -33,137 +34,5 @@ tabs:
|
|
|
33
34
|
default:
|
|
34
35
|
label: Default
|
|
35
36
|
description: the default settings for the Tabs
|
|
36
|
-
|
|
37
|
-
label: With Icon
|
|
38
|
-
description: Tabs with Icons
|
|
39
|
-
fields:
|
|
40
|
-
items:
|
|
41
|
-
- label: "Tab One"
|
|
42
|
-
component: "image"
|
|
43
|
-
componentdata:
|
|
44
|
-
alt: "My alt text"
|
|
45
|
-
caption: "my image caption"
|
|
46
|
-
credit: "Photo: copyright 2022 Person S. Name"
|
|
47
|
-
url:
|
|
48
|
-
- breakpoint: 0
|
|
49
|
-
src: "https://place-hold.it/400x300?text=Tab One Image"
|
|
50
|
-
- breakpoint: 800
|
|
51
|
-
src: "https://place-hold.it/800x600?text=Tab One tImage"
|
|
52
|
-
- breakpoint: 1200
|
|
53
|
-
src: "https://place-hold.it/1200x900?text=Tab One Image"
|
|
54
|
-
- breakpoint: 1440
|
|
55
|
-
src: "https://place-hold.it/1600x1200?text=Tab One Image"
|
|
56
|
-
icon: error
|
|
57
|
-
- label: "Tab Two"
|
|
58
|
-
component: "image"
|
|
59
|
-
componentdata:
|
|
60
|
-
alt: "My alt text"
|
|
61
|
-
caption: "my image caption"
|
|
62
|
-
credit: "Photo: copyright 2022 Person S. Name"
|
|
63
|
-
url:
|
|
64
|
-
- breakpoint: 0
|
|
65
|
-
src: "https://place-hold.it/400x300?text=Tab Two Image"
|
|
66
|
-
- breakpoint: 800
|
|
67
|
-
src: "https://place-hold.it/800x600?text=Tab Two Image"
|
|
68
|
-
- breakpoint: 1200
|
|
69
|
-
src: "https://place-hold.it/1200x900?text=Tab Two Image"
|
|
70
|
-
- breakpoint: 1440
|
|
71
|
-
src: "https://place-hold.it/1600x1200?text=Tab Two Image"
|
|
72
|
-
icon: error
|
|
73
|
-
- label: "Tab Three"
|
|
74
|
-
component: "image"
|
|
75
|
-
componentdata:
|
|
76
|
-
alt: "My alt text"
|
|
77
|
-
caption: "my image caption"
|
|
78
|
-
credit: "Photo: copyright 2022 Person S. Name"
|
|
79
|
-
url:
|
|
80
|
-
- breakpoint: 0
|
|
81
|
-
src: "https://place-hold.it/400x300?text=Tab Three Image"
|
|
82
|
-
- breakpoint: 800
|
|
83
|
-
src: "https://place-hold.it/800x600?text=Tab Three Image"
|
|
84
|
-
- breakpoint: 1200
|
|
85
|
-
src: "https://place-hold.it/1200x900?text=Tab Three Image"
|
|
86
|
-
- breakpoint: 1440
|
|
87
|
-
src: "https://place-hold.it/1600x1200?text=Tab Three Image"
|
|
88
|
-
icon: error
|
|
89
|
-
fiveitems:
|
|
90
|
-
label: Five Items
|
|
91
|
-
description: Tab component with five items
|
|
92
|
-
fields:
|
|
93
|
-
items:
|
|
94
|
-
- label: "Tab One"
|
|
95
|
-
component: "image"
|
|
96
|
-
componentdata:
|
|
97
|
-
alt: "My alt text"
|
|
98
|
-
caption: "my image caption"
|
|
99
|
-
credit: "Photo: copyright 2022 Person S. Name"
|
|
100
|
-
url:
|
|
101
|
-
- breakpoint: 0
|
|
102
|
-
src: "https://place-hold.it/400x300?text=Tab One Image"
|
|
103
|
-
- breakpoint: 800
|
|
104
|
-
src: "https://place-hold.it/800x600?text=Tab One tImage"
|
|
105
|
-
- breakpoint: 1200
|
|
106
|
-
src: "https://place-hold.it/1200x900?text=Tab One Image"
|
|
107
|
-
- breakpoint: 1440
|
|
108
|
-
src: "https://place-hold.it/1600x1200?text=Tab One Image"
|
|
109
|
-
- label: "Tab Two"
|
|
110
|
-
component: "image"
|
|
111
|
-
componentdata:
|
|
112
|
-
alt: "My alt text"
|
|
113
|
-
caption: "my image caption"
|
|
114
|
-
credit: "Photo: copyright 2022 Person S. Name"
|
|
115
|
-
url:
|
|
116
|
-
- breakpoint: 0
|
|
117
|
-
src: "https://place-hold.it/400x300?text=Tab Two Image"
|
|
118
|
-
- breakpoint: 800
|
|
119
|
-
src: "https://place-hold.it/800x600?text=Tab Two Image"
|
|
120
|
-
- breakpoint: 1200
|
|
121
|
-
src: "https://place-hold.it/1200x900?text=Tab Two Image"
|
|
122
|
-
- breakpoint: 1440
|
|
123
|
-
src: "https://place-hold.it/1600x1200?text=Tab Two Image"
|
|
124
|
-
- label: "Tab Three"
|
|
125
|
-
component: "image"
|
|
126
|
-
componentdata:
|
|
127
|
-
alt: "My alt text"
|
|
128
|
-
caption: "my image caption"
|
|
129
|
-
credit: "Photo: copyright 2022 Person S. Name"
|
|
130
|
-
url:
|
|
131
|
-
- breakpoint: 0
|
|
132
|
-
src: "https://place-hold.it/400x300?text=Tab Three Image"
|
|
133
|
-
- breakpoint: 800
|
|
134
|
-
src: "https://place-hold.it/800x600?text=Tab Three Image"
|
|
135
|
-
- breakpoint: 1200
|
|
136
|
-
src: "https://place-hold.it/1200x900?text=Tab Three Image"
|
|
137
|
-
- breakpoint: 1440
|
|
138
|
-
src: "https://place-hold.it/1600x1200?text=Tab Three Image"
|
|
139
|
-
- label: "Tab Four Has A Really Lenghthy Title Which Might Get Truncated"
|
|
140
|
-
component: "image"
|
|
141
|
-
componentdata:
|
|
142
|
-
alt: "My alt text"
|
|
143
|
-
caption: "my image caption"
|
|
144
|
-
credit: "Photo: copyright 2022 Person S. Name"
|
|
145
|
-
url:
|
|
146
|
-
- breakpoint: 0
|
|
147
|
-
src: "https://place-hold.it/400x300?text=Tab Four Image"
|
|
148
|
-
- breakpoint: 800
|
|
149
|
-
src: "https://place-hold.it/800x600?text=Tab Four Image"
|
|
150
|
-
- breakpoint: 1200
|
|
151
|
-
src: "https://place-hold.it/1200x900?text=Tab Four Image"
|
|
152
|
-
- breakpoint: 1440
|
|
153
|
-
src: "https://place-hold.it/1600x1200?text=Tab Four Image"
|
|
154
|
-
- label: "Tab Five"
|
|
155
|
-
component: "image"
|
|
156
|
-
componentdata:
|
|
157
|
-
alt: "My alt text"
|
|
158
|
-
caption: "my image caption"
|
|
159
|
-
credit: "Photo: copyright 2022 Person S. Name"
|
|
160
|
-
url:
|
|
161
|
-
- breakpoint: 0
|
|
162
|
-
src: "https://place-hold.it/400x300?text=Tab Five Image"
|
|
163
|
-
- breakpoint: 800
|
|
164
|
-
src: "https://place-hold.it/800x600?text=Tab Five Image"
|
|
165
|
-
- breakpoint: 1200
|
|
166
|
-
src: "https://place-hold.it/1200x900?text=Tab Five Image"
|
|
167
|
-
- breakpoint: 1440
|
|
168
|
-
src: "https://place-hold.it/1600x1200?text=Tab Five Image"
|
|
37
|
+
|
|
169
38
|
visibility: storybook
|
|
@@ -1 +1 @@
|
|
|
1
|
-
.ilo--card__type__text{--max-width:16.1307609861rem;border-bottom:.1607717042rem solid #b8c4cc;padding:2.1436227224rem 1.2861736334rem 1.7148981779rem
|
|
1
|
+
.ilo--card__type__text{--max-width:16.1307609861rem;border-bottom:.1607717042rem solid #b8c4cc;padding:2.1436227224rem 1.2861736334rem 1.7148981779rem;clip-path:polygon(0 0,calc(100% - 72px) 0,100% 40px,100% 100%,0 100%)}[dir=rtl] .ilo--card__type__text{clip-path:polygon(72px 0,100% 0,100% 100%,0 100%,0 40px)}.ilo--card__type__text [class$=profile__theme__light] *{color:#2d2d2d}.ilo--card__type__text [class$=profile__theme__dark] *{color:#fff}.ilo--card__type__text:focus,.ilo--card__type__text:focus-within,.ilo--card__type__text:hover{filter:drop-shadow(0 -4px 16px rgba(30,45,190,.05)) drop-shadow(0 10px 20px rgba(30,45,190,.08)) drop-shadow(0 4px 8px rgba(30,45,190,.05)) drop-shadow(0 .8px 1.6px rgba(30,45,190,.04));transition-property:border-color;transition-duration:.15s;transition-timing-function:ease-out;border-color:#1e2dbe}.ilo--card__type__text:focus-within [class*=profile__theme] *,.ilo--card__type__text:focus [class*=profile__theme] *,.ilo--card__type__text:hover [class*=profile__theme] *{color:#1e2dbe}@media screen and (max-width:609px){.ilo--card__type__text{--max-width:100%}}.ilo--card__type__text.ilo--card__size__fluid,.ilo--card__type__text.ilo--card__size__wide{--max-width:28.0278670954rem;padding:2.1436227224rem 1.7148981779rem 1.7148981779rem}.ilo--card__type__text.ilo--card__size__narrow{--max-width:16.1307609861rem;padding:2.1436227224rem 1.2861736334rem 1.7148981779rem}@media screen and (max-width:609px){.ilo--card__type__text.ilo--card__size__narrow{--max-width:100%}}.ilo--card__type__text.ilo--card__size__narrow .ilo--card--title{font-size:18.66px;letter-spacing:-.035em;line-height:24.26px;margin-bottom:1.674953518rem}.ilo--card__type__text.ilo--card__dark{border-bottom:.1607717042rem solid #fa3c4b}.ilo--card__type__text .ilo--card--eyebrow{margin-bottom:1.0110920672rem}.ilo--card__type__text .ilo--card--title{font-size:18.66px;letter-spacing:-.035em;line-height:24.26px;margin-bottom:1.674953518rem}@media screen and (min-width:610px){.ilo--card__type__text .ilo--card--title{font-size:23.32px;letter-spacing:-.035em;line-height:29.15px;margin-bottom:1.5763397642rem}}.ilo--card__type__text .ilo--card--date{display:block;margin-bottom:1.4398166117rem}.ilo--card__type__text .ilo--card--content{display:flex;flex-direction:column;position:relative}.ilo--card__type__text .ilo--card--content>*{justify-self:flex-start}.ilo--card__type__text .ilo--card--content>:last-child{justify-self:flex-end;margin-bottom:0}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ilo-org/twig",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"description": "Twig components for the ILO's Design System",
|
|
6
6
|
"publishConfig": {
|
|
@@ -49,10 +49,10 @@
|
|
|
49
49
|
"video.js": "^7.21.2",
|
|
50
50
|
"videojs-youtube": "^3.0.1",
|
|
51
51
|
"@ilo-org/brand-assets": "0.5.1",
|
|
52
|
-
"@ilo-org/fonts": "0.2.
|
|
52
|
+
"@ilo-org/fonts": "0.2.2",
|
|
53
53
|
"@ilo-org/icons": "0.3.1",
|
|
54
|
-
"@ilo-org/styles": "1.0.
|
|
55
|
-
"@ilo-org/themes": "0.
|
|
54
|
+
"@ilo-org/styles": "1.0.3",
|
|
55
|
+
"@ilo-org/themes": "0.9.0",
|
|
56
56
|
"@ilo-org/utils": "0.1.1"
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
@@ -107,8 +107,8 @@
|
|
|
107
107
|
"webpack": "^4.46.0",
|
|
108
108
|
"yaml-loader": "0.6.0",
|
|
109
109
|
"yo": "^3.1.1",
|
|
110
|
-
"@ilo-org/eslint-config": "0.
|
|
111
|
-
"@ilo-org/prettier-config": "0.
|
|
110
|
+
"@ilo-org/eslint-config": "1.0.0",
|
|
111
|
+
"@ilo-org/prettier-config": "1.0.0"
|
|
112
112
|
},
|
|
113
113
|
"scripts": {
|
|
114
114
|
"storybook": "node importprefix.js && node importsvgs.js && start-storybook --config-dir apps/storybook",
|
|
@@ -5,12 +5,12 @@
|
|
|
5
5
|
{% set accordion_id = id ~ uid %}
|
|
6
6
|
{% set button_id = 'button-' ~ accordion_id %}
|
|
7
7
|
{% set panel_id = 'panel-' ~ accordion_id %}
|
|
8
|
-
{% set expanded_class = defaultExpanded ? prefix ~ '--accordion--
|
|
8
|
+
{% set expanded_class = defaultExpanded ? prefix ~ '--accordion--panel__open' : '' %}
|
|
9
9
|
{% set scroll_class = scroll ? prefix ~ '--accordion--panel__scroll' : '' %}
|
|
10
10
|
|
|
11
11
|
<li class="{{prefix}}--accordion--item" id="{{ accordion_id }}">
|
|
12
12
|
<div class="ilo--h3">
|
|
13
|
-
<button class="{{prefix}}--accordion--button {{prefix}}--accordion--
|
|
13
|
+
<button class="{{prefix}}--accordion--button {{prefix}}--accordion--button__{{ size|default('small') }}" aria-expanded="{{ defaultExpanded }}" aria-controls="{{ panel_id }}" id="{{ button_id }}">
|
|
14
14
|
{{label}}
|
|
15
15
|
</button>
|
|
16
16
|
</div>
|
|
@@ -130,7 +130,7 @@ export default class Accordion {
|
|
|
130
130
|
const panel = panelbutton
|
|
131
131
|
.closest(".ilo--accordion--item")
|
|
132
132
|
.querySelector(".ilo--accordion--panel");
|
|
133
|
-
const isopen = panel.classList.contains("ilo--accordion--
|
|
133
|
+
const isopen = panel.classList.contains("ilo--accordion--panel__open");
|
|
134
134
|
|
|
135
135
|
if (!this.multipleExpanded) {
|
|
136
136
|
this.accordionPanels.forEach((item) => {
|
|
@@ -158,7 +158,7 @@ export default class Accordion {
|
|
|
158
158
|
* @chainable
|
|
159
159
|
*/
|
|
160
160
|
collapseSection(element) {
|
|
161
|
-
element.classList.remove("ilo--accordion--
|
|
161
|
+
element.classList.remove("ilo--accordion--panel__open");
|
|
162
162
|
element.parentElement
|
|
163
163
|
.querySelector(".ilo--accordion--button")
|
|
164
164
|
.setAttribute(ARIA.EXPANDED, "false");
|
|
@@ -178,7 +178,7 @@ export default class Accordion {
|
|
|
178
178
|
.querySelector(".ilo--accordion--button")
|
|
179
179
|
.setAttribute(ARIA.EXPANDED, "true");
|
|
180
180
|
element.setAttribute(ARIA.HIDDEN, "false");
|
|
181
|
-
element.classList.add("ilo--accordion--
|
|
181
|
+
element.classList.add("ilo--accordion--panel__open");
|
|
182
182
|
this.handleTabIndex(element, "ADD");
|
|
183
183
|
}
|
|
184
184
|
|
|
@@ -45,12 +45,35 @@ export default class Breadcrumb {
|
|
|
45
45
|
* @chainable
|
|
46
46
|
*/
|
|
47
47
|
cacheDomReferences() {
|
|
48
|
-
|
|
49
|
-
this.
|
|
50
|
-
this.
|
|
51
|
-
|
|
48
|
+
// Store references to classnames
|
|
49
|
+
this.breadcrumbsId = `${this.prefix}--breadcrumb--container`;
|
|
50
|
+
this.contextAreaClass = `${this.prefix}--breadcrumb--context`;
|
|
51
|
+
this.contextMenuItemsClass = `${this.prefix}--context-menu`;
|
|
52
|
+
this.contextCollapseClass = `${this.contextAreaClass}__collapse`;
|
|
53
|
+
this.contextButtonClass = `${this.contextAreaClass}--button`;
|
|
54
|
+
this.contextMenuClass = `${this.contextAreaClass}--menu`;
|
|
55
|
+
this.contextMenuVisibleClass = `${this.contextMenuClass}__visible`;
|
|
56
|
+
|
|
57
|
+
// Store reference to DOM elements
|
|
58
|
+
this.breadcrumbs = this.element.querySelector(`#${this.breadcrumbsId}`);
|
|
59
|
+
this.contextArea = this.element.querySelector(`.${this.contextAreaClass}`);
|
|
60
|
+
this.contextMenu = this.element.querySelector(`.${this.contextMenuClass}`);
|
|
61
|
+
this.contextButton = this.element.querySelector(
|
|
62
|
+
`.${this.contextButtonClass}`
|
|
63
|
+
);
|
|
64
|
+
this.breadcrumbsLastLink = this.element.querySelector(
|
|
65
|
+
`#${this.breadcrumbsId} > li:last-child a`
|
|
66
|
+
);
|
|
67
|
+
this.contextMenuItems = this.element.querySelector(
|
|
68
|
+
`.${this.contextMenuItemsClass}`
|
|
52
69
|
);
|
|
53
|
-
this.
|
|
70
|
+
this.contextMenuItemFirstLink =
|
|
71
|
+
this.contextMenuItems.querySelector("li:first-child a");
|
|
72
|
+
this.contextMenuItemLastLink =
|
|
73
|
+
this.contextMenuItems.querySelector("li:last-child a");
|
|
74
|
+
|
|
75
|
+
// Store a reference to the breadcrumbs width so we know when to uncollapse them
|
|
76
|
+
this.breadcrumbsWidth = this.breadcrumbs.offsetWidth;
|
|
54
77
|
|
|
55
78
|
return this;
|
|
56
79
|
}
|
|
@@ -64,59 +87,190 @@ export default class Breadcrumb {
|
|
|
64
87
|
setupHandlers() {
|
|
65
88
|
this.onResize = this.onResize.bind(this);
|
|
66
89
|
this.onClick = this.onClick.bind(this);
|
|
90
|
+
this.contexMenuIsOpen = this.contexMenuIsOpen.bind(this);
|
|
91
|
+
this.openContextMenu = this.openContextMenu.bind(this);
|
|
92
|
+
this.closeContextMenu = this.closeContextMenu.bind(this);
|
|
93
|
+
this.focusBreadcrumbsLastLink = this.focusBreadcrumbsLastLink.bind(this);
|
|
94
|
+
this.focusContextMenuItemFirstLink =
|
|
95
|
+
this.focusContextMenuItemFirstLink.bind(this);
|
|
96
|
+
this.onKeydown = this.onKeydown.bind(this);
|
|
67
97
|
|
|
68
98
|
return this;
|
|
69
99
|
}
|
|
70
100
|
|
|
71
101
|
/**
|
|
72
|
-
*
|
|
102
|
+
* Adds event listeners to enable interaction with view
|
|
73
103
|
*
|
|
74
104
|
* @return {Object} Breadcrumb A reference to the instance of the class
|
|
75
105
|
* @chainable
|
|
76
106
|
*/
|
|
77
107
|
enable() {
|
|
108
|
+
// Handle resizing events
|
|
78
109
|
window.addEventListener(EVENTS.RESIZE, (e) => this.onResize(e));
|
|
79
|
-
|
|
80
|
-
|
|
110
|
+
|
|
111
|
+
if (this.contextButton) {
|
|
112
|
+
// When the context button gets clicked
|
|
113
|
+
this.contextButton.addEventListener(EVENTS.CLICK, (e) => this.onClick(e));
|
|
114
|
+
|
|
115
|
+
// We only need the keydown handler to manage tab navigation when the
|
|
116
|
+
// context menu is visible
|
|
117
|
+
this.element.addEventListener("keydown", (e) => this.onKeydown(e));
|
|
118
|
+
|
|
119
|
+
return this;
|
|
81
120
|
}
|
|
121
|
+
}
|
|
82
122
|
|
|
123
|
+
/**
|
|
124
|
+
* OnClick interaction with the ContextMenu button
|
|
125
|
+
*
|
|
126
|
+
* @return {Object} Breadcrumb A reference to the instance of the class
|
|
127
|
+
* @chainable
|
|
128
|
+
*/
|
|
129
|
+
onClick(e) {
|
|
130
|
+
e.stopPropagation();
|
|
131
|
+
if (this.contexMenuIsOpen()) {
|
|
132
|
+
this.closeContextMenu();
|
|
133
|
+
} else {
|
|
134
|
+
this.openContextMenu();
|
|
135
|
+
// Add an event listener to close the context menu if the user clicks outside of it
|
|
136
|
+
window.addEventListener("click", this.closeContextMenu, { once: true });
|
|
137
|
+
}
|
|
83
138
|
return this;
|
|
84
139
|
}
|
|
85
140
|
|
|
86
141
|
/**
|
|
87
|
-
* onResize interaction
|
|
142
|
+
* onResize interaction
|
|
88
143
|
*
|
|
89
144
|
* @return {Object} Breadcrumb A reference to the instance of the class
|
|
90
145
|
* @chainable
|
|
91
146
|
*/
|
|
92
147
|
onResize() {
|
|
93
|
-
if (this.
|
|
94
|
-
if (this.
|
|
95
|
-
this.
|
|
96
|
-
this.ContextMenu.classList.remove("open");
|
|
148
|
+
if (this.contextArea && this.breadcrumbsWidth) {
|
|
149
|
+
if (this.breadcrumbsWidth >= window.innerWidth / 1.5) {
|
|
150
|
+
this.contextArea.classList.add(this.contextCollapseClass);
|
|
97
151
|
} else {
|
|
98
|
-
this.
|
|
99
|
-
this.
|
|
152
|
+
this.contextArea.classList.remove(this.contextCollapseClass);
|
|
153
|
+
this.closeContextMenu();
|
|
100
154
|
}
|
|
101
155
|
}
|
|
102
156
|
return this;
|
|
103
157
|
}
|
|
104
158
|
|
|
105
159
|
/**
|
|
106
|
-
*
|
|
160
|
+
* onKeydown interaction for tab navigation
|
|
107
161
|
*
|
|
162
|
+
* @param {*} e keydown event
|
|
108
163
|
* @return {Object} Breadcrumb A reference to the instance of the class
|
|
109
164
|
* @chainable
|
|
110
165
|
*/
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
166
|
+
onKeydown(e) {
|
|
167
|
+
// Back navigation using the shift key
|
|
168
|
+
if (e.shiftKey) {
|
|
169
|
+
if (e.key.toLowerCase() === "tab") {
|
|
170
|
+
// If the first context menu item is selected, tabbing back
|
|
171
|
+
// should select the context button
|
|
172
|
+
if (document.activeElement === this.contextMenuItemFirstLink) {
|
|
173
|
+
e.preventDefault();
|
|
174
|
+
this.contextButton.focus();
|
|
175
|
+
}
|
|
117
176
|
}
|
|
177
|
+
return this;
|
|
118
178
|
}
|
|
119
179
|
|
|
180
|
+
// When using tab navigation
|
|
181
|
+
if (e.key.toLowerCase() === "tab") {
|
|
182
|
+
// If the context menu is open...
|
|
183
|
+
const contexMenuIsOpen = this.contexMenuIsOpen();
|
|
184
|
+
// If the context button is focused then the next focusable item
|
|
185
|
+
// should be the first item in the context menu
|
|
186
|
+
if (contexMenuIsOpen) {
|
|
187
|
+
if (document.activeElement === this.contextButton) {
|
|
188
|
+
e.preventDefault();
|
|
189
|
+
this.focusContextMenuItemFirstLink();
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// If the last context menu item is focused then the next focusable
|
|
193
|
+
// item should be the last breadcrumb item
|
|
194
|
+
if (document.activeElement === this.contextMenuItemLastLink) {
|
|
195
|
+
e.preventDefault();
|
|
196
|
+
this.focusBreadcrumbsLastLink();
|
|
197
|
+
this.closeContextMenu();
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
return this;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Position the context menu directly beneath the button
|
|
207
|
+
*
|
|
208
|
+
* @return {Object} Breadcrumb A reference to the instance of the class
|
|
209
|
+
* @chainable
|
|
210
|
+
*/
|
|
211
|
+
positionContextMenu() {
|
|
212
|
+
const buttonRect = this.contextButton.getBoundingClientRect();
|
|
213
|
+
const buttonCenterX = buttonRect.left + buttonRect.width / 2;
|
|
214
|
+
const contextMenuWidth = this.contextMenu.offsetWidth;
|
|
215
|
+
const navStart = buttonCenterX - contextMenuWidth / 2;
|
|
216
|
+
const navTop = buttonRect.bottom + 16;
|
|
217
|
+
this.contextMenu.style.left = navStart + "px";
|
|
218
|
+
this.contextMenu.style.top = navTop + "px";
|
|
219
|
+
return this;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Open the Context menu
|
|
224
|
+
*
|
|
225
|
+
* @return {Object} Breadcrumb A reference to the instance of the class
|
|
226
|
+
* @chainable
|
|
227
|
+
*/
|
|
228
|
+
openContextMenu() {
|
|
229
|
+
this.contextMenu.classList.add(this.contextMenuVisibleClass);
|
|
230
|
+
this.contextButton.setAttribute("aria-expanded", "true");
|
|
231
|
+
this.positionContextMenu();
|
|
232
|
+
return this;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Close the Context menu
|
|
237
|
+
*
|
|
238
|
+
* @return {Object} Breadcrumb A reference to the instance of the class
|
|
239
|
+
* @chainable
|
|
240
|
+
*/
|
|
241
|
+
closeContextMenu() {
|
|
242
|
+
this.contextMenu.classList.remove(this.contextMenuVisibleClass);
|
|
243
|
+
this.contextButton.setAttribute("aria-expanded", "false");
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Check to see whether the Context menu is open
|
|
248
|
+
*
|
|
249
|
+
* @returns boolean
|
|
250
|
+
*/
|
|
251
|
+
contexMenuIsOpen() {
|
|
252
|
+
return this.contextMenu.classList.contains(this.contextMenuVisibleClass);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Focuses first link in the Context Menu
|
|
257
|
+
*
|
|
258
|
+
* @return {Object} Breadcrumb A reference to the instance of the class
|
|
259
|
+
* @chainable
|
|
260
|
+
*/
|
|
261
|
+
focusContextMenuItemFirstLink() {
|
|
262
|
+
this.contextMenuItemFirstLink.focus();
|
|
263
|
+
return this;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Focuses last item of the Breadcrumbs
|
|
268
|
+
*
|
|
269
|
+
* @return {Object} Breadcrumb A reference to the instance of the class
|
|
270
|
+
* @chainable
|
|
271
|
+
*/
|
|
272
|
+
focusBreadcrumbsLastLink() {
|
|
273
|
+
this.breadcrumbsLastLink.focus();
|
|
120
274
|
return this;
|
|
121
275
|
}
|
|
122
276
|
}
|
|
@@ -1,43 +1,55 @@
|
|
|
1
|
-
{#
|
|
2
|
-
|
|
3
|
-
#}
|
|
1
|
+
{# breadcrumb.twig #}
|
|
2
|
+
|
|
3
|
+
{# If a home field is passed, it will be used as the first link #}
|
|
4
|
+
{# THE `HOME` FIELD WILL BE DEPRECATED IN FUTURE VERSIONS AND SHOULD NOT BE USED #}
|
|
5
|
+
{% if home %}
|
|
6
|
+
{% set firstlink = home %}
|
|
7
|
+
{% set contextLinks = links|slice(0, items|length - 1) %}
|
|
8
|
+
{% endif %}
|
|
9
|
+
|
|
10
|
+
{% if not home %}
|
|
11
|
+
{% set firstlink = links|first %}
|
|
12
|
+
{% set contextLinks = links|slice(1, items|length - 1) %}
|
|
13
|
+
{% endif %}
|
|
14
|
+
|
|
4
15
|
{% set lastlink = links|last %}
|
|
5
|
-
|
|
6
|
-
<nav class="{{prefix}}--breadcrumb{% if className %}
|
|
7
|
-
<
|
|
8
|
-
<
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
</li>
|
|
13
|
-
{% if links|length >= 2 %}
|
|
14
|
-
<li class="{{prefix}}--breadcrumb--item first">
|
|
15
|
-
<a class="{{prefix}}--breadcrumb--link" href="{{firstlink.url}}">
|
|
16
|
-
<span class="{{prefix}}--breadcrumb--link--label">{{firstlink.label}}</span>
|
|
17
|
-
</a>
|
|
16
|
+
|
|
17
|
+
<nav class="{{prefix}}--breadcrumb {% if className %}{{className}}{% endif %}" data-prefix="{{prefix}}" data-loadcomponent="Breadcrumb">
|
|
18
|
+
<div class="{{prefix}}--breadcrumb--inner">
|
|
19
|
+
<ol class="{{prefix}}--breadcrumb--items" id="{{prefix}}--breadcrumb--container">
|
|
20
|
+
{# Render the first link on its own as a custom icon #}
|
|
21
|
+
<li class="{{prefix}}--breadcrumb--item {{prefix}}--breadcrumb--item__first">
|
|
22
|
+
<a aria-label="{{firstlink.label}}" class="{{prefix}}--breadcrumb--link" href="{{firstlink.url}}}"></a>
|
|
18
23
|
</li>
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
{% if not loop.first and not loop.last %}
|
|
24
|
+
{# Render all but the first and last items in the context area #}
|
|
25
|
+
{% if contextLinks|length > 0 %}
|
|
26
|
+
<li class="{{prefix}}--breadcrumb--context">
|
|
27
|
+
<ol class="{{prefix}}--breadcrumb--items">
|
|
28
|
+
{% for link in contextLinks %}
|
|
25
29
|
<li class="{{prefix}}--breadcrumb--item">
|
|
26
30
|
<a href="{{link.url}}" class="{{prefix}}--breadcrumb--link">
|
|
27
|
-
<span class="{{prefix}}--breadcrumb--link--label
|
|
31
|
+
<span class="{{prefix}}--breadcrumb--link--label">{{link.label}}</span>
|
|
28
32
|
</a>
|
|
29
33
|
</li>
|
|
30
|
-
{%
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
<
|
|
38
|
-
<
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
34
|
+
{% endfor %}
|
|
35
|
+
</ol>
|
|
36
|
+
<button aria-label="{{buttonlabel|default('More links')}}" aria-expanded="false" controls="{{prefix}}--breadcrumb--menu" class="{{prefix}}--breadcrumb--context--button"></button>
|
|
37
|
+
</li>
|
|
38
|
+
{% endif %}
|
|
39
|
+
{# Render the last one outside the context area #}
|
|
40
|
+
{% if links|length > 1 %}
|
|
41
|
+
<li class="{{prefix}}--breadcrumb--item">
|
|
42
|
+
<a class="{{prefix}}--breadcrumb--link" href="{{lastlink.url}}">
|
|
43
|
+
<span class="{{prefix}}--breadcrumb--link--label">{{lastlink.label}}</span>
|
|
44
|
+
</a>
|
|
45
|
+
</li>
|
|
46
|
+
{% endif %}
|
|
47
|
+
</ol>
|
|
48
|
+
</div>
|
|
49
|
+
<div class="{{prefix}}--breadcrumb--context--menu" id="{{prefix}}--breadcrumb--menu">
|
|
50
|
+
{% include '@components/contextmenu/contextmenu.twig' with {
|
|
51
|
+
links: contextLinks,
|
|
52
|
+
prefix: prefix
|
|
53
|
+
} only %}
|
|
54
|
+
</div>
|
|
43
55
|
</nav>
|
|
@@ -4,14 +4,13 @@ breadcrumb:
|
|
|
4
4
|
label: Breadcrumb
|
|
5
5
|
description: A component for displaying links in a "breadcrumb" ux
|
|
6
6
|
fields:
|
|
7
|
-
|
|
8
|
-
type:
|
|
9
|
-
label:
|
|
10
|
-
description:
|
|
11
|
-
required:
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
url: "/"
|
|
7
|
+
buttonlabel:
|
|
8
|
+
type: string
|
|
9
|
+
label: buttonlabel
|
|
10
|
+
description: The `aria-label` value for the button that toggles the context menu when the Breadcrumbs are collapsed
|
|
11
|
+
required: false
|
|
12
|
+
default: "Toggle links"
|
|
13
|
+
preview: "Toggle links"
|
|
15
14
|
links:
|
|
16
15
|
type: object
|
|
17
16
|
label: Home
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{#
|
|
2
2
|
CONTEXT MENU COMPONENT
|
|
3
3
|
#}
|
|
4
|
-
<
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
</
|
|
4
|
+
<ol class="{{prefix}}--context-menu">
|
|
5
|
+
{% for link in links %}
|
|
6
|
+
<li class="{{prefix}}--context-menu--item{% if link.endsection == 'true' %} endsection{% endif %}">
|
|
7
|
+
<a href="{{link.url}}" class="{{prefix}}--context-menu--link">
|
|
8
|
+
<span class="{{prefix}}--context-menu--label">{{link.label}}</span>
|
|
9
|
+
</a>
|
|
10
|
+
</li>
|
|
11
|
+
{% endfor %}
|
|
12
|
+
</ol>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
logogrid:
|
|
2
|
-
namespace: Components/
|
|
2
|
+
namespace: Components/Media
|
|
3
3
|
use: "@components/logogrid/logogrid.twig"
|
|
4
4
|
label: Logo Grid
|
|
5
5
|
description: The Logo Grid component renders a series of logos representing a group of organizations. It can be shown on a light or dark background.
|
|
@@ -10,7 +10,10 @@
|
|
|
10
10
|
<a href="#tab--{{tabids[loop.index - 1]}}" class="{{prefix}}--tabs--selection--button{% if item.icon is defined %} icon{% endif %}" aria-controls="tab--{{tabids[loop.index - 1]}}" role="tab" tabindex="0" {% if loop.index == 1 %}aria-selected="true"{% else %}aria-selected="false"{% endif %} title="{{item.label}}">
|
|
11
11
|
<span class="{{prefix}}--tabs--selection--label">{{item.label}}</span>
|
|
12
12
|
{% if item.icon is defined %}
|
|
13
|
-
{% include '@components/icon/icon.twig' with {
|
|
13
|
+
{% include '@components/icon/icon.twig' with {
|
|
14
|
+
name: item.icon,
|
|
15
|
+
size: '24'
|
|
16
|
+
} %}
|
|
14
17
|
{% endif %}
|
|
15
18
|
</a>
|
|
16
19
|
</li>
|