@gouvfr/dsfr-roller 1.0.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/LICENSE.md +21 -0
- package/README.md +11 -0
- package/index.js +5 -0
- package/package.json +65 -0
- package/src/component/component.js +50 -0
- package/src/component/components/action.js +28 -0
- package/src/component/components/breadcrumb.js +33 -0
- package/src/component/components/button.js +37 -0
- package/src/component/components/display-body.js +41 -0
- package/src/component/components/display-modal.js +29 -0
- package/src/component/components/footer.js +85 -0
- package/src/component/components/header.js +96 -0
- package/src/component/components/navigation.js +72 -0
- package/src/component/components/sidemenu.js +58 -0
- package/src/component/components/skiplink.js +49 -0
- package/src/component/components/translate.js +32 -0
- package/src/component/components/version.js +21 -0
- package/src/component/ejs/version/version.ejs +46 -0
- package/src/component/ejs/version/versions.ejs +31 -0
- package/src/component/ejs-pkg.js +6 -0
- package/src/component/render.js +19 -0
- package/src/constants.js +7 -0
- package/src/core/format-html.js +16 -0
- package/src/core/format-link.js +8 -0
- package/src/core/html-renderable.js +10 -0
- package/src/core/renderable.js +20 -0
- package/src/integration/bundler.js +47 -0
- package/src/integration/indexing/indexer.js +23 -0
- package/src/integration/indexing/sitemap.js +44 -0
- package/src/integration/redirect/redirection-type.js +4 -0
- package/src/integration/redirect/redirection.js +77 -0
- package/src/node/custom/html-container-node.js +7 -0
- package/src/node/directive/doc/accordion-container-directive.js +59 -0
- package/src/node/directive/doc/accordions-group-container-directive.js +12 -0
- package/src/node/directive/doc/anatomy-container-directive.js +61 -0
- package/src/node/directive/doc/button-leaf-directive.js +37 -0
- package/src/node/directive/doc/changelog-leaf-directive.js +238 -0
- package/src/node/directive/doc/figma-leaf-directive.js +21 -0
- package/src/node/directive/doc/guideline-container-directive.js +71 -0
- package/src/node/directive/doc/guidelines-container-directive.js +13 -0
- package/src/node/directive/doc/image-text-directive.js +13 -0
- package/src/node/directive/doc/pin-leaf-directive.js +46 -0
- package/src/node/directive/doc/storybook-leaf-directive.js +18 -0
- package/src/node/directive/doc/tab-container-directive.js +22 -0
- package/src/node/directive/doc/tab-navigation-container-directive.js +49 -0
- package/src/node/directive/doc/table-container-directive.js +56 -0
- package/src/node/directive/doc/tabs-container-directive.js +71 -0
- package/src/node/generic/blockquote-node.js +26 -0
- package/src/node/generic/break-node.js +11 -0
- package/src/node/generic/code-node.js +37 -0
- package/src/node/generic/definition-node.js +13 -0
- package/src/node/generic/emphasis-node.js +11 -0
- package/src/node/generic/heading-node.js +56 -0
- package/src/node/generic/html-node.js +11 -0
- package/src/node/generic/image-node.js +14 -0
- package/src/node/generic/image-reference-node.js +14 -0
- package/src/node/generic/inline-code-node.js +21 -0
- package/src/node/generic/link-node.js +26 -0
- package/src/node/generic/link-reference-node.js +14 -0
- package/src/node/generic/list-item-node.js +11 -0
- package/src/node/generic/list-node.js +15 -0
- package/src/node/generic/paragraph-node.js +11 -0
- package/src/node/generic/strong-node.js +11 -0
- package/src/node/generic/text-node.js +15 -0
- package/src/node/generic/thematic-break-node.js +12 -0
- package/src/node/gfm/table-body-node.js +11 -0
- package/src/node/gfm/table-cell-node.js +17 -0
- package/src/node/gfm/table-head-node.js +11 -0
- package/src/node/gfm/table-header-node.js +16 -0
- package/src/node/gfm/table-node.js +91 -0
- package/src/node/gfm/table-row-node.js +11 -0
- package/src/node/node-factory.js +128 -0
- package/src/node/node-root.js +25 -0
- package/src/node/node.js +106 -0
- package/src/page/body/custom-header.js +40 -0
- package/src/page/body/main.js +23 -0
- package/src/page/body/scheme.js +9 -0
- package/src/page/head/canonical.js +16 -0
- package/src/page/head/favicon.js +14 -0
- package/src/page/head/head.js +35 -0
- package/src/page/head/share.js +14 -0
- package/src/page/head/stylesheets.js +48 -0
- package/src/page/head/title.js +9 -0
- package/src/page/html.js +46 -0
- package/src/page/page.js +39 -0
- package/src/page/scripts/highlight.js +53 -0
- package/src/page/scripts/scripts.js +57 -0
- package/src/script/main/core/element.js +29 -0
- package/src/script/main/elements/copy-snippet.js +35 -0
- package/src/script/main/elements/searchbar.js +18 -0
- package/src/script/main/elements/storybook.js +20 -0
- package/src/script/main/index.js +10 -0
- package/src/script/search/index.js +0 -0
- package/src/style/main/components/_dsfr-doc-anatomy.scss +54 -0
- package/src/style/main/components/_dsfr-doc-code-snippet.scss +9 -0
- package/src/style/main/components/_dsfr-doc-figma-leaf.scss +6 -0
- package/src/style/main/components/_dsfr-doc-guideline.scss +58 -0
- package/src/style/main/components/_dsfr-doc-tab-navigation.scss +99 -0
- package/src/style/main/components/_dsfr-doc-version.scss +154 -0
- package/src/style/main/components/_index.scss +6 -0
- package/src/style/main/index.scss +3 -0
- package/src/style/main/third-party/_highlight.scss +227 -0
- package/src/style/main/third-party/_index.scss +1 -0
- package/src/style/main/utility/_dsfr-doc-code.scss +9 -0
- package/src/style/main/utility/_font.scss +31 -0
- package/src/style/main/utility/_icon.scss +4 -0
- package/src/style/main/utility/_index.scss +3 -0
- package/src/style/search/index.scss +0 -0
- package/src/template/template-factory.js +16 -0
- package/src/template/template.js +27 -0
- package/src/template/templates/editorial-template.js +45 -0
- package/src/template/templates/home-template.js +18 -0
- package/src/template/templates/search-template.js +20 -0
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import { Node } from '../../node.js'
|
|
2
|
+
import { convertHTMLEntities, gitmoji, log } from '@gouvfr/dsfr-forge'
|
|
3
|
+
|
|
4
|
+
class ChangelogLeafDirective extends Node {
|
|
5
|
+
structure (data) {
|
|
6
|
+
if (!data.changelog) {
|
|
7
|
+
log.warn('ChangelogLeafDirective: missing "changelog"');
|
|
8
|
+
return data;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
return super.structure({
|
|
12
|
+
type: 'htmlContainer',
|
|
13
|
+
tagName: 'div',
|
|
14
|
+
classes: ['dsfr-doc-changelog'],
|
|
15
|
+
children: data.changelog.map(version => this.structureVersion(version, data.dateFormat))
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
structureVersion (version, dateFormat) {
|
|
20
|
+
const date = new Intl.DateTimeFormat(dateFormat, {
|
|
21
|
+
year: "numeric",
|
|
22
|
+
month: "long",
|
|
23
|
+
day: "numeric"
|
|
24
|
+
}).format(new Date(version.date));
|
|
25
|
+
|
|
26
|
+
return {
|
|
27
|
+
type: 'htmlContainer',
|
|
28
|
+
tagName: 'div',
|
|
29
|
+
classes: ['dsfr-doc-changelog__version', 'fr-mb-12v'],
|
|
30
|
+
children: [
|
|
31
|
+
{
|
|
32
|
+
type: 'heading',
|
|
33
|
+
depth: 4,
|
|
34
|
+
children: [
|
|
35
|
+
{
|
|
36
|
+
type: 'link',
|
|
37
|
+
url: version.url,
|
|
38
|
+
children: [
|
|
39
|
+
{
|
|
40
|
+
type: 'text',
|
|
41
|
+
value: version.id
|
|
42
|
+
}
|
|
43
|
+
]
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
type: 'text',
|
|
47
|
+
value: ` - ${date}`
|
|
48
|
+
}
|
|
49
|
+
]
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
type: 'htmlContainer',
|
|
53
|
+
tagName: 'div',
|
|
54
|
+
classes: ['fr-grid-row', 'fr-grid-row--gutters'],
|
|
55
|
+
children: version.commits.map(commit => this.structureCommit(commit))
|
|
56
|
+
}
|
|
57
|
+
]
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
structureCommit (commit) {
|
|
62
|
+
const contentChildren = [
|
|
63
|
+
{
|
|
64
|
+
type: 'heading',
|
|
65
|
+
depth: 5,
|
|
66
|
+
data: { isSemantic: true },
|
|
67
|
+
classes: ['fr-tile__title'],
|
|
68
|
+
children: [
|
|
69
|
+
{
|
|
70
|
+
type: 'link',
|
|
71
|
+
url: commit.pull,
|
|
72
|
+
children: [
|
|
73
|
+
{
|
|
74
|
+
type: 'text',
|
|
75
|
+
value: convertHTMLEntities(commit.title)
|
|
76
|
+
}
|
|
77
|
+
]
|
|
78
|
+
}
|
|
79
|
+
]
|
|
80
|
+
}
|
|
81
|
+
];
|
|
82
|
+
|
|
83
|
+
if (commit.description) {
|
|
84
|
+
commit.description.forEach(node => {
|
|
85
|
+
node.classes = (node.classes ?? []).concat(['fr-tile__desc']);
|
|
86
|
+
});
|
|
87
|
+
contentChildren.push(...commit.description);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (commit.change) {
|
|
91
|
+
contentChildren.push({
|
|
92
|
+
type: 'paragraph',
|
|
93
|
+
classes: ['fr-tile__desc'],
|
|
94
|
+
children: [
|
|
95
|
+
{
|
|
96
|
+
type: 'text',
|
|
97
|
+
value: 'Breaking change:'
|
|
98
|
+
}
|
|
99
|
+
]
|
|
100
|
+
});
|
|
101
|
+
commit.change.forEach(node => {
|
|
102
|
+
node.classes = (node.classes ?? []).concat(['fr-tile__desc']);
|
|
103
|
+
});
|
|
104
|
+
contentChildren.push(...commit.change);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
let badgeClasses = ['fr-badge'];
|
|
108
|
+
|
|
109
|
+
switch (commit.type) {
|
|
110
|
+
case 'feat':
|
|
111
|
+
badgeClasses.push('fr-badge--success', 'fr-badge--no-icon');
|
|
112
|
+
break;
|
|
113
|
+
case 'fix':
|
|
114
|
+
badgeClasses.push('fr-badge--warning', 'fr-badge--no-icon');
|
|
115
|
+
break;
|
|
116
|
+
case 'refactor':
|
|
117
|
+
badgeClasses.push('fr-badge--info', 'fr-badge--no-icon');
|
|
118
|
+
break;
|
|
119
|
+
case 'docs':
|
|
120
|
+
case 'doc':
|
|
121
|
+
badgeClasses.push('fr-badge--info', 'fr-badge--no-icon');
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const badges = [
|
|
126
|
+
{
|
|
127
|
+
type: 'htmlContainer',
|
|
128
|
+
tagName: 'p',
|
|
129
|
+
classes: badgeClasses,
|
|
130
|
+
children: [
|
|
131
|
+
{
|
|
132
|
+
type: 'text',
|
|
133
|
+
value: (commit.gitmojis?.length ? `${commit.gitmojis.join('')} ` : '') + commit.type
|
|
134
|
+
}
|
|
135
|
+
]
|
|
136
|
+
}
|
|
137
|
+
]
|
|
138
|
+
|
|
139
|
+
if (commit.isBreaking) {
|
|
140
|
+
badges.push({
|
|
141
|
+
type: 'htmlContainer',
|
|
142
|
+
tagName: 'p',
|
|
143
|
+
classes: ['fr-badge', 'fr-badge--error', 'fr-badge--no-icon'],
|
|
144
|
+
children: [
|
|
145
|
+
{
|
|
146
|
+
type: 'text',
|
|
147
|
+
value: `${gitmoji(':boom:')} Breaking change`
|
|
148
|
+
}
|
|
149
|
+
]
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const badgesGroup = badges.length === 1 ? badges : [
|
|
154
|
+
{
|
|
155
|
+
type: 'htmlContainer',
|
|
156
|
+
tagName: 'div',
|
|
157
|
+
classes: ['fr-badges-group'],
|
|
158
|
+
children: badges
|
|
159
|
+
}
|
|
160
|
+
]
|
|
161
|
+
|
|
162
|
+
contentChildren.push({
|
|
163
|
+
type: 'htmlContainer',
|
|
164
|
+
tagName: 'div',
|
|
165
|
+
classes: ['fr-tile__start'],
|
|
166
|
+
children: badgesGroup
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
switch (true) {
|
|
170
|
+
case !commit.scopes?.length:
|
|
171
|
+
case commit.scopes.length === 1 && commit.scopes[0] === '*':
|
|
172
|
+
break;
|
|
173
|
+
|
|
174
|
+
default:
|
|
175
|
+
contentChildren.push({
|
|
176
|
+
type: 'htmlContainer',
|
|
177
|
+
tagName: 'div',
|
|
178
|
+
classes: ['fr-tile__start'],
|
|
179
|
+
children: [
|
|
180
|
+
{
|
|
181
|
+
type: 'htmlContainer',
|
|
182
|
+
tagName: 'div',
|
|
183
|
+
classes: ['fr-tags-group'],
|
|
184
|
+
children: commit.scopes.map(scope => ({
|
|
185
|
+
type: 'htmlContainer',
|
|
186
|
+
tagName: 'p',
|
|
187
|
+
classes: ['fr-tag'],
|
|
188
|
+
children: [{ type: 'text', value: scope }]
|
|
189
|
+
}))
|
|
190
|
+
}
|
|
191
|
+
]
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
contentChildren.push({
|
|
196
|
+
type: 'paragraph',
|
|
197
|
+
classes: ['fr-tile__detail'],
|
|
198
|
+
children: [
|
|
199
|
+
{
|
|
200
|
+
type: 'text',
|
|
201
|
+
value: `#${commit.id}`
|
|
202
|
+
}
|
|
203
|
+
]
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
return {
|
|
207
|
+
type: 'htmlContainer',
|
|
208
|
+
tagName: 'div',
|
|
209
|
+
classes: ['fr-col-12', 'fr-col-md-8'],
|
|
210
|
+
children: [
|
|
211
|
+
{
|
|
212
|
+
type: 'htmlContainer',
|
|
213
|
+
tagName: 'div',
|
|
214
|
+
classes: ['fr-tile', 'fr-tile--sm', 'fr-enlarge-link', 'fr-tile--horizontal'],
|
|
215
|
+
children: [
|
|
216
|
+
{
|
|
217
|
+
type: 'htmlContainer',
|
|
218
|
+
tagName: 'div',
|
|
219
|
+
classes: ['fr-tile__body'],
|
|
220
|
+
children: [
|
|
221
|
+
{
|
|
222
|
+
type: 'htmlContainer',
|
|
223
|
+
tagName: 'div',
|
|
224
|
+
classes: ['fr-tile__content'],
|
|
225
|
+
children: contentChildren
|
|
226
|
+
}
|
|
227
|
+
]
|
|
228
|
+
}
|
|
229
|
+
]
|
|
230
|
+
}
|
|
231
|
+
]
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
ChangelogLeafDirective.NAME = 'dsfr-doc-changelog';
|
|
237
|
+
|
|
238
|
+
export { ChangelogLeafDirective };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Node } from '../../node.js';
|
|
2
|
+
|
|
3
|
+
class FigmaLeafDirective extends Node {
|
|
4
|
+
constructor (data) {
|
|
5
|
+
super(data, 'iframe');
|
|
6
|
+
if (!this.attributes.hasAttribute('width')) this.attributes.setAttribute('width', '100%');
|
|
7
|
+
if (!this.attributes.hasAttribute('height')) this.attributes.setAttribute('height', '100%');
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
async render() {
|
|
11
|
+
return `
|
|
12
|
+
<div class="dsfr-doc-figma-leaf">
|
|
13
|
+
${await super.render()}
|
|
14
|
+
</div>
|
|
15
|
+
`;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
FigmaLeafDirective.NAME = 'dsfr-doc-figma';
|
|
20
|
+
|
|
21
|
+
export { FigmaLeafDirective };
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { Node } from '../../node.js'
|
|
2
|
+
import { log } from '@gouvfr/dsfr-forge';
|
|
3
|
+
|
|
4
|
+
class GuidelineContainerDirective extends Node {
|
|
5
|
+
structure (data) {
|
|
6
|
+
const image = Node.getImageChild(data);
|
|
7
|
+
|
|
8
|
+
if (!image) {
|
|
9
|
+
log.warn('GuidelineContainerDirective: missing image');
|
|
10
|
+
return data;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const valid = data.attributes.valid.toLowerCase() === 'true';
|
|
14
|
+
const col = data.attributes.col || '12';
|
|
15
|
+
const description = data.children.filter(child => {
|
|
16
|
+
switch (true) {
|
|
17
|
+
case child?.data?.directiveLabel === true:
|
|
18
|
+
return false;
|
|
19
|
+
case Node.getImageChild(child) !== null:
|
|
20
|
+
return false;
|
|
21
|
+
default:
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
const title = valid ? data.fragments.do : data.fragments.dont;
|
|
26
|
+
|
|
27
|
+
return super.structure({
|
|
28
|
+
type: 'htmlContainer',
|
|
29
|
+
tagName: 'div',
|
|
30
|
+
classes: ['fr-col-12', `fr-col-md-${col}`],
|
|
31
|
+
children: [
|
|
32
|
+
{
|
|
33
|
+
type: 'htmlContainer',
|
|
34
|
+
tagName: 'div',
|
|
35
|
+
classes: ['dsfr-doc-guideline', `dsfr-doc-guideline--${valid ? 'do' : 'dont'}`],
|
|
36
|
+
children: [
|
|
37
|
+
{
|
|
38
|
+
type: 'image',
|
|
39
|
+
classes: ['dsfr-doc-guideline__img'],
|
|
40
|
+
attributes: {
|
|
41
|
+
src: image.url,
|
|
42
|
+
alt: title
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
type: 'htmlContainer',
|
|
47
|
+
tagName: 'div',
|
|
48
|
+
classes: ['dsfr-doc-guideline__content'],
|
|
49
|
+
children: [
|
|
50
|
+
{
|
|
51
|
+
type: 'paragraph',
|
|
52
|
+
classes: ['dsfr-doc-guideline__title'],
|
|
53
|
+
children: [
|
|
54
|
+
{
|
|
55
|
+
type: 'text',
|
|
56
|
+
value: title
|
|
57
|
+
}
|
|
58
|
+
]
|
|
59
|
+
},
|
|
60
|
+
].concat(description)
|
|
61
|
+
}
|
|
62
|
+
]
|
|
63
|
+
}
|
|
64
|
+
]
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
GuidelineContainerDirective.NAME = 'dsfr-doc-guideline';
|
|
70
|
+
|
|
71
|
+
export { GuidelineContainerDirective };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Node } from '../../node.js'
|
|
2
|
+
|
|
3
|
+
class GuidelinesContainerDirective extends Node {
|
|
4
|
+
constructor (data) {
|
|
5
|
+
super(data, 'div');
|
|
6
|
+
this.attributes.addClass('fr-grid-row');
|
|
7
|
+
this.attributes.addClass('fr-grid-row--gutters');
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
GuidelinesContainerDirective.NAME = 'dsfr-doc-guidelines';
|
|
12
|
+
|
|
13
|
+
export { GuidelinesContainerDirective };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Node } from '../../node.js'
|
|
2
|
+
|
|
3
|
+
class ImageTextDirective extends Node {
|
|
4
|
+
constructor (data) {
|
|
5
|
+
super(data);
|
|
6
|
+
this._image = this.findDescendantsByType('image')[0];
|
|
7
|
+
if (this.attributes.hasAttribute('responsive') && this._image) this._image.attributes.addClass('fr-responsive-img');
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
ImageTextDirective.NAME = 'dsfr-doc-image';
|
|
12
|
+
|
|
13
|
+
export { ImageTextDirective };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Node } from '../../node.js';
|
|
2
|
+
|
|
3
|
+
class PinLeafDirective extends Node {
|
|
4
|
+
structure (data) {
|
|
5
|
+
const required = data?.attributes?.required;
|
|
6
|
+
const add = data?.attributes?.add;
|
|
7
|
+
const titleChildren = data?.children[0];
|
|
8
|
+
const requiredFragment = data.fragments?.anatomy?.required;
|
|
9
|
+
const optionalFragment = data.fragments?.anatomy?.optional;
|
|
10
|
+
let descriptionValue = `${required === 'true' ? requiredFragment : optionalFragment}`;
|
|
11
|
+
if (add) descriptionValue += ` ${add}`;
|
|
12
|
+
|
|
13
|
+
if (!titleChildren) {
|
|
14
|
+
log.warn(`PinLeafDirective: missing label on pin`);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return {
|
|
18
|
+
type: 'htmlContainer',
|
|
19
|
+
tagName: 'li',
|
|
20
|
+
classes: ['dsfr-doc-anatomy__pin', required === 'true' ? 'dsfr-doc-anatomy__pin--required' : ''],
|
|
21
|
+
children: [
|
|
22
|
+
{
|
|
23
|
+
type: 'htmlContainer',
|
|
24
|
+
tagName: 'span',
|
|
25
|
+
classes: ['dsfr-doc-anatomy__title'],
|
|
26
|
+
children: [titleChildren]
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
type: 'htmlContainer',
|
|
30
|
+
tagName: 'span',
|
|
31
|
+
classes: ['dsfr-doc-anatomy__description'],
|
|
32
|
+
children: [
|
|
33
|
+
{
|
|
34
|
+
type: 'text',
|
|
35
|
+
value: descriptionValue
|
|
36
|
+
}
|
|
37
|
+
]
|
|
38
|
+
}
|
|
39
|
+
]
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
PinLeafDirective.NAME = 'dsfr-doc-pin';
|
|
45
|
+
|
|
46
|
+
export { PinLeafDirective };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Node } from '../../node.js';
|
|
2
|
+
|
|
3
|
+
class StorybookLeafDirective extends Node {
|
|
4
|
+
|
|
5
|
+
// TODO:
|
|
6
|
+
// - script externe pour le resize de l'iframe
|
|
7
|
+
// - apossibilité de multiple storybook (baser sur id de la story ?)
|
|
8
|
+
// - bug resize down
|
|
9
|
+
// - bouton communication avec iframe pour changer le theme exemple
|
|
10
|
+
// - changement theme iframe en fonction theme parent
|
|
11
|
+
async render() {
|
|
12
|
+
return `<div class="storybook-leaf"><iframe ${this.renderAttributes()}></iframe></div>`;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
StorybookLeafDirective.NAME = 'dsfr-doc-storybook';
|
|
17
|
+
|
|
18
|
+
export { StorybookLeafDirective };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Node } from '../../node.js';
|
|
2
|
+
|
|
3
|
+
class TabContainerDirective extends Node {
|
|
4
|
+
structure (data) {
|
|
5
|
+
const tabId = data?.attributes?.id;
|
|
6
|
+
return super.structure({
|
|
7
|
+
type: 'htmlContainer',
|
|
8
|
+
tagName: 'div',
|
|
9
|
+
attributes: {
|
|
10
|
+
id: `${tabId}-panel`,
|
|
11
|
+
role: 'tabpanel',
|
|
12
|
+
'aria-labelledby': tabId
|
|
13
|
+
},
|
|
14
|
+
classes: ['fr-tabs__panel'],
|
|
15
|
+
children: data.children
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
TabContainerDirective.NAME = 'fr-tab';
|
|
21
|
+
|
|
22
|
+
export { TabContainerDirective };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Node } from '../../node.js';
|
|
2
|
+
import { HtmlNode } from '../../generic/html-node.js';
|
|
3
|
+
|
|
4
|
+
class TabNavigationContainerDirective extends Node {
|
|
5
|
+
constructor(data) {
|
|
6
|
+
super(data);
|
|
7
|
+
this._id = data.attributes.id || 'dsfr-doc-tab-navigation--collapse';
|
|
8
|
+
const list = this.findDescendantsByType('list')[0];
|
|
9
|
+
list.attributes.setAttribute('role', 'tablist');
|
|
10
|
+
const items = list.findDescendantsByType('listItem');
|
|
11
|
+
for (const item of items) {
|
|
12
|
+
item.attributes.setAttribute('role', 'presentation');
|
|
13
|
+
let node;
|
|
14
|
+
let isSelected = false;
|
|
15
|
+
const link = item.findDescendantsByType('link')[0];
|
|
16
|
+
if (link) {
|
|
17
|
+
node = link;
|
|
18
|
+
} else {
|
|
19
|
+
this._currentNode = item._children[0];
|
|
20
|
+
|
|
21
|
+
node = new HtmlNode({ type: 'html', value: '<div>' });
|
|
22
|
+
const close = new HtmlNode({ type: 'html', value: '</div>' });
|
|
23
|
+
item._children = [node, ...item._children, close];
|
|
24
|
+
isSelected = true;
|
|
25
|
+
}
|
|
26
|
+
node.attributes.setAttribute('role', 'tab');
|
|
27
|
+
node.attributes.setAttribute('aria-selected', isSelected);
|
|
28
|
+
node.attributes.addClass('dsfr-doc-tab-navigation__tab');
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
async render() {
|
|
32
|
+
this.attributes.setAttribute('role', 'navigation');
|
|
33
|
+
this.attributes.addClass('dsfr-doc-tab-navigation');
|
|
34
|
+
return `<nav ${this.renderAttributes()}>
|
|
35
|
+
<div class="fr-sidemenu">
|
|
36
|
+
<div class="fr-sidemenu__inner">
|
|
37
|
+
<button aria-expanded="false" aria-controls="${this._id}" type="button" class="fr-sidemenu__btn">${await this._currentNode.render()}</button>
|
|
38
|
+
<div class="fr-collapse" id="${this._id}">
|
|
39
|
+
${await super.render()}
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
</nav>`;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
TabNavigationContainerDirective.NAME = 'dsfr-doc-tab-navigation';
|
|
48
|
+
|
|
49
|
+
export { TabNavigationContainerDirective };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { Node } from '../../node.js';
|
|
2
|
+
import { log } from '@gouvfr/dsfr-forge';
|
|
3
|
+
|
|
4
|
+
const VALIGN = new Map([
|
|
5
|
+
['top', 'fr-cell--top'],
|
|
6
|
+
['bottom', 'fr-cell--bottom']
|
|
7
|
+
]);
|
|
8
|
+
|
|
9
|
+
class TableContainerDirective extends Node {
|
|
10
|
+
constructor (data) {
|
|
11
|
+
super(data);
|
|
12
|
+
this.applyAttributes(data.attributes);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
structure (data) {
|
|
16
|
+
const directiveLabel = data.children?.[0];
|
|
17
|
+
if (!directiveLabel.data?.directiveLabel) {
|
|
18
|
+
log.warn('TableContainerDirective: missing caption');
|
|
19
|
+
return data;
|
|
20
|
+
}
|
|
21
|
+
data.children.shift();
|
|
22
|
+
const table = data.children?.find(child => child.type === 'table');
|
|
23
|
+
if (table ) {
|
|
24
|
+
table.caption = directiveLabel.children?.[0]?.value;
|
|
25
|
+
}
|
|
26
|
+
return data;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
applyAttributes (attributes) {
|
|
30
|
+
const table = this.findDescendantsByType('table')[0];
|
|
31
|
+
if (!table) return;
|
|
32
|
+
|
|
33
|
+
if (attributes.scroll === 'false') table.attributes.addClass('fr-table--no-scroll');
|
|
34
|
+
if (attributes.caption === 'false') table.attributes.addClass('fr-table--no-caption');
|
|
35
|
+
|
|
36
|
+
const cellCount = table.children[0].children.length;
|
|
37
|
+
|
|
38
|
+
const valign = attributes.valign ? attributes.valign.split(',') : null;
|
|
39
|
+
if (valign?.length === 1 && VALIGN.has(valign[0])) {
|
|
40
|
+
valign.length = cellCount;
|
|
41
|
+
valign.fill(valign[0]);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
table.children.forEach((row, index) => {
|
|
45
|
+
row.children.forEach((cell, cellIndex) => {
|
|
46
|
+
if (valign && valign[cellIndex] && VALIGN.has(valign[cellIndex])) {
|
|
47
|
+
cell.attributes.addClass(VALIGN.get(valign[cellIndex]));
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
TableContainerDirective.NAME = 'dsfr-doc-table';
|
|
55
|
+
|
|
56
|
+
export { TableContainerDirective };
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { Node } from '../../node.js';
|
|
2
|
+
import { log } from '@gouvfr/dsfr-forge';
|
|
3
|
+
import { TabContainerDirective } from './tab-container-directive.js';
|
|
4
|
+
|
|
5
|
+
class TabsContainerDirective extends Node {
|
|
6
|
+
structure (data) {
|
|
7
|
+
const label = data.children.filter(child => child?.data?.directiveLabel)?.[0]?.children?.[0]?.value;
|
|
8
|
+
const contentChildren = data.children.filter(child => !child?.data?.directiveLabel);
|
|
9
|
+
const tabs = contentChildren
|
|
10
|
+
.filter(child => child.type === 'containerDirective' && child.name === TabContainerDirective.NAME)
|
|
11
|
+
.map(this.structureTab);
|
|
12
|
+
|
|
13
|
+
const listAttributes = {
|
|
14
|
+
role: 'tablist'
|
|
15
|
+
};
|
|
16
|
+
if (label) {
|
|
17
|
+
listAttributes['aria-label'] = label;
|
|
18
|
+
}
|
|
19
|
+
else log.warn('TabsContainerDirective: missing label on fr-tabs');
|
|
20
|
+
|
|
21
|
+
return super.structure({
|
|
22
|
+
type: 'htmlContainer',
|
|
23
|
+
tagName: 'div',
|
|
24
|
+
classes: ['fr-tabs'],
|
|
25
|
+
children: [
|
|
26
|
+
{
|
|
27
|
+
type: 'htmlContainer',
|
|
28
|
+
tagName: 'ul',
|
|
29
|
+
classes: ['fr-tabs__list'],
|
|
30
|
+
attributes: listAttributes,
|
|
31
|
+
children: tabs
|
|
32
|
+
},
|
|
33
|
+
...contentChildren
|
|
34
|
+
]
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
structureTab (data, index) {
|
|
39
|
+
const tabId = data?.attributes?.id;
|
|
40
|
+
const tabTitleChildren = data.children.filter(child => child?.data?.directiveLabel)?.[0]?.children;
|
|
41
|
+
|
|
42
|
+
if (!tabTitleChildren) {
|
|
43
|
+
log.warn(`TabsContainerDirective: missing label on fr-tab ${index + 1}`);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
type: 'htmlContainer',
|
|
48
|
+
tagName: 'li',
|
|
49
|
+
attributes: {
|
|
50
|
+
role: 'presentation'
|
|
51
|
+
},
|
|
52
|
+
children: [
|
|
53
|
+
{
|
|
54
|
+
type: 'htmlContainer',
|
|
55
|
+
tagName: 'button',
|
|
56
|
+
classes: ['fr-tabs__tab'],
|
|
57
|
+
attributes: {
|
|
58
|
+
role: 'tab',
|
|
59
|
+
'aria-controls': `${tabId}-panel`,
|
|
60
|
+
'aria-selected': index === 0
|
|
61
|
+
},
|
|
62
|
+
children: tabTitleChildren
|
|
63
|
+
}
|
|
64
|
+
]
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
TabsContainerDirective.NAME = 'fr-tabs';
|
|
70
|
+
|
|
71
|
+
export { TabsContainerDirective };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Node } from '../node.js';
|
|
2
|
+
|
|
3
|
+
const LEVELS = new Map([
|
|
4
|
+
['note', { icon: 'information-line', color: 'blue-cumulus' }],
|
|
5
|
+
['tip', { icon: 'lightbulb-line', color: 'green-emeraude' }],
|
|
6
|
+
['important', { icon: 'feedback-line', color: 'purple-glycine' }],
|
|
7
|
+
['warning', { icon: 'alert-line', color: 'yellow-moutarde' }],
|
|
8
|
+
['caution', { icon: 'spam-2-line', color: 'pink-tuile' }]
|
|
9
|
+
]);
|
|
10
|
+
|
|
11
|
+
class BlockquoteNode extends Node {
|
|
12
|
+
constructor (data) {
|
|
13
|
+
if (data?.children?.[0]?.type === 'heading') data.children[0].attributes = { class: 'fr-callout__title' };
|
|
14
|
+
super(data, 'div');
|
|
15
|
+
this.attributes.addClass('fr-callout fr-mb-6v');
|
|
16
|
+
|
|
17
|
+
if (data?.level && LEVELS.has(data.level)) {
|
|
18
|
+
const level = LEVELS.get(data.level);
|
|
19
|
+
this.attributes.addClasses(`fr-icon-${level.icon}`, `fr-callout--${level.color}`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
BlockquoteNode.TYPE = 'blockquote';
|
|
25
|
+
|
|
26
|
+
export { BlockquoteNode };
|