@gouvfr/dsfr-roller 1.0.17 → 1.0.18
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/env/local/env.json +4 -1
- package/env/prod/env.json +4 -1
- package/env/staging/env.json +4 -1
- package/package.json +2 -2
- package/src/component/components/breadcrumb.js +1 -0
- package/src/component/components/header.js +1 -0
- package/src/component/components/translate.js +1 -1
- package/src/component/ejs/version/version.ejs +1 -0
- package/src/core/format-link.js +2 -0
- package/src/node/directive/doc/page-item-card-container-directive.js +13 -4
- package/src/node/directive/doc/page-item-heading-container-directive.js +47 -0
- package/src/node/directive/doc/page-item-list-leaf-directive.js +22 -12
- package/src/node/node-factory.js +2 -0
- package/src/node/node.js +13 -1
- package/src/page/head/analytics-config.js +29 -0
- package/src/page/head/head.js +3 -0
- package/src/page/html.js +1 -1
- package/src/page/scripts/scripts.js +1 -0
package/env/local/env.json
CHANGED
package/env/prod/env.json
CHANGED
package/env/staging/env.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gouvfr/dsfr-roller",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.18",
|
|
4
4
|
"description": "Le module `dsfr-roller` permet de publier le site de documentation du Système de Design de l’État - DSFR",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Système de Design de l'État",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
],
|
|
57
57
|
"main": "./index.js",
|
|
58
58
|
"dependencies": {
|
|
59
|
-
"@gouvfr/dsfr-forge": "=1.0.
|
|
59
|
+
"@gouvfr/dsfr-forge": "=1.0.18",
|
|
60
60
|
"@gouvfr/dsfr-publisher": "npm:@gouvfr/dsfr@1.13.1",
|
|
61
61
|
"deepmerge": "^4.3.1",
|
|
62
62
|
"ejs": "^3.1.10",
|
|
@@ -20,6 +20,7 @@ class Header extends Component {
|
|
|
20
20
|
const search = {
|
|
21
21
|
id: 'search',
|
|
22
22
|
modalId: 'search-modal',
|
|
23
|
+
btnId: 'search-modal-button',
|
|
23
24
|
input: { placeholder: this.data.search.label, label: this.data.search.label },
|
|
24
25
|
button: { id: 'search-button', label: this.data.search.label, title: this.data.search.title ?? this.data.search.label, markup: 'a', href: this.data.search.url, attributes: { 'data-href': this.data.search.url } }
|
|
25
26
|
};
|
|
@@ -11,7 +11,7 @@ class Translate extends Component {
|
|
|
11
11
|
async format () {
|
|
12
12
|
return {
|
|
13
13
|
id: 'translate',
|
|
14
|
-
button: { title: this.data.button, kind: 3 },
|
|
14
|
+
button: { title: this.data.button, kind: 3, id: 'header__tools--translate' },
|
|
15
15
|
collapseId: 'translate-collapse',
|
|
16
16
|
languages: this._formatLanguages(this.data.languages)
|
|
17
17
|
};
|
|
@@ -31,6 +31,7 @@ const collapseId = version.collapseId || uniqueId('version');
|
|
|
31
31
|
'aria-expanded': false,
|
|
32
32
|
title: versionBtn.title
|
|
33
33
|
};
|
|
34
|
+
versionBtn.id = 'header__tools--version';
|
|
34
35
|
versionBtn.classes = versionBtn.classes !== undefined ? versionBtn.classes.concat(minBtnClasses) : minBtnClasses;
|
|
35
36
|
versionBtn.attributes = versionBtn.attributes !== undefined ? {...minBtnAttrs, ...versionBtn.attributes} : minBtnAttrs;
|
|
36
37
|
|
package/src/core/format-link.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export const formatLink = (link) => {
|
|
2
2
|
if (!link) return undefined;
|
|
3
3
|
const url = link.url ?? link.href;
|
|
4
|
+
const segments = url && url.split('/');
|
|
5
|
+
if (segments) link.id = link.id ?? `link-${segments.join('-')}`;
|
|
4
6
|
if (/^(https:|http:|www\.)\S*$/.test(url)) link.blank = true;
|
|
5
7
|
link.href = url;
|
|
6
8
|
link.label = link.label ?? link.text;
|
|
@@ -2,9 +2,20 @@ import { CardContainerDirective } from '../components/card/card-container-direct
|
|
|
2
2
|
|
|
3
3
|
class PageItemCardContainerDirective extends CardContainerDirective {
|
|
4
4
|
structure (data) {
|
|
5
|
+
const cols = {
|
|
6
|
+
col: data.properties?.col || 12,
|
|
7
|
+
colSm: data.properties?.colSm,
|
|
8
|
+
colMd: data.properties?.colMd,
|
|
9
|
+
colLg: data.properties?.colLg
|
|
10
|
+
}
|
|
11
|
+
if (!data.horizontal) {
|
|
12
|
+
cols.colSm = cols.colSm || 6;
|
|
13
|
+
cols.colLg = cols.colLg || 4;
|
|
14
|
+
}
|
|
5
15
|
data.properties = {
|
|
6
|
-
horizontal: false,
|
|
7
|
-
download: false,
|
|
16
|
+
horizontal: data.horizontal || false,
|
|
17
|
+
download: data.download || false,
|
|
18
|
+
...cols,
|
|
8
19
|
...data.properties,
|
|
9
20
|
};
|
|
10
21
|
|
|
@@ -42,10 +53,8 @@ class PageItemCardContainerDirective extends CardContainerDirective {
|
|
|
42
53
|
],
|
|
43
54
|
});
|
|
44
55
|
}
|
|
45
|
-
|
|
46
56
|
return super.structure(data);
|
|
47
57
|
}
|
|
48
|
-
|
|
49
58
|
}
|
|
50
59
|
|
|
51
60
|
PageItemCardContainerDirective.NAME = 'dsfr-doc-page-item-card';
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Node } from '../../node.js'
|
|
2
|
+
|
|
3
|
+
class PageItemHeadingContainerDirective extends Node {
|
|
4
|
+
structure (data) {
|
|
5
|
+
const children = [
|
|
6
|
+
{
|
|
7
|
+
type: 'heading',
|
|
8
|
+
depth: 3,
|
|
9
|
+
children: [
|
|
10
|
+
{
|
|
11
|
+
type: 'link',
|
|
12
|
+
url: data.url,
|
|
13
|
+
children: [
|
|
14
|
+
{
|
|
15
|
+
type: 'text',
|
|
16
|
+
value: data.text
|
|
17
|
+
},
|
|
18
|
+
],
|
|
19
|
+
},
|
|
20
|
+
],
|
|
21
|
+
}
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
if (data.shortDescription || data.excerpt) {
|
|
25
|
+
children.push({
|
|
26
|
+
type: 'paragraph',
|
|
27
|
+
children: [
|
|
28
|
+
{
|
|
29
|
+
type: 'text',
|
|
30
|
+
value: data.shortDescription || data.excerpt,
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return super.structure({
|
|
37
|
+
type: 'htmlContainer',
|
|
38
|
+
tagName: 'div',
|
|
39
|
+
classes: ['fr-col-12'],
|
|
40
|
+
children: children,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
PageItemHeadingContainerDirective.NAME = 'dsfr-doc-page-item-heading';
|
|
46
|
+
|
|
47
|
+
export { PageItemHeadingContainerDirective };
|
|
@@ -1,19 +1,29 @@
|
|
|
1
1
|
import { Node } from '../../node.js';
|
|
2
2
|
|
|
3
|
+
const mapItem = (item) => {
|
|
4
|
+
const nodes = [
|
|
5
|
+
{
|
|
6
|
+
...item,
|
|
7
|
+
type: 'containerDirective',
|
|
8
|
+
name: item.name ?? 'dsfr-doc-page-item-card',
|
|
9
|
+
}
|
|
10
|
+
];
|
|
11
|
+
|
|
12
|
+
if (item.items) {
|
|
13
|
+
for (const childItem of item.items) {
|
|
14
|
+
nodes.push(...mapItem(childItem));
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return nodes
|
|
19
|
+
};
|
|
20
|
+
|
|
3
21
|
class PageItemListLeafDirective extends Node {
|
|
4
22
|
structure (data) {
|
|
5
|
-
const children =
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
children: [
|
|
10
|
-
{
|
|
11
|
-
...item,
|
|
12
|
-
type: 'containerDirective',
|
|
13
|
-
name: data.itemDirectiveName ?? 'dsfr-doc-page-item-card'
|
|
14
|
-
}
|
|
15
|
-
]
|
|
16
|
-
}));
|
|
23
|
+
const children = [];
|
|
24
|
+
for (const item of data.items) {
|
|
25
|
+
children.push(...mapItem(item));
|
|
26
|
+
}
|
|
17
27
|
|
|
18
28
|
return super.structure({
|
|
19
29
|
type: 'htmlContainer',
|
package/src/node/node-factory.js
CHANGED
|
@@ -54,6 +54,7 @@ import { TabNavigationContainerDirective } from './directive/doc/tab-navigation-
|
|
|
54
54
|
import { StorybookLeafDirective } from './directive/doc/storybook-leaf-directive.js';
|
|
55
55
|
import { FigmaLeafDirective } from './directive/doc/figma-leaf-directive.js';
|
|
56
56
|
import { PageItemListLeafDirective } from './directive/doc/page-item-list-leaf-directive.js';
|
|
57
|
+
import { PageItemHeadingContainerDirective } from './directive/doc/page-item-heading-container-directive.js';
|
|
57
58
|
import { PageItemCardContainerDirective } from './directive/doc/page-item-card-container-directive.js';
|
|
58
59
|
import { VideoLeafDirective } from './directive/doc/video-leaf-directive.js';
|
|
59
60
|
import { ImageTextDirective } from './directive/doc/image-text-directive.js'
|
|
@@ -107,6 +108,7 @@ const DIRECTIVE_CONTAINERS = [
|
|
|
107
108
|
AccordionsGroupContainerDirective,
|
|
108
109
|
CardContainerDirective,
|
|
109
110
|
PageItemCardContainerDirective,
|
|
111
|
+
PageItemHeadingContainerDirective,
|
|
110
112
|
TileContainerDirective,
|
|
111
113
|
GuidelineContainerDirective,
|
|
112
114
|
GuidelinesContainerDirective,
|
package/src/node/node.js
CHANGED
|
@@ -11,7 +11,19 @@ class Node extends Renderable {
|
|
|
11
11
|
this._children = Array.isArray(this.data.children) ? this.data.children.map(childData => nodeFactory.create(childData)) : [];
|
|
12
12
|
if (typeof this.data?.attributes === 'object' && Object.keys(this.data.attributes).length > 0) {
|
|
13
13
|
Object.entries(this.data.attributes).forEach(([key, value]) => {
|
|
14
|
-
|
|
14
|
+
switch (key) {
|
|
15
|
+
case 'classes':
|
|
16
|
+
if (typeof value === 'string') {
|
|
17
|
+
this.attributes.setClasses(value.split(' '));
|
|
18
|
+
} else if (Array.isArray(value)) {
|
|
19
|
+
this.attributes.setClasses(value);
|
|
20
|
+
}
|
|
21
|
+
break;
|
|
22
|
+
|
|
23
|
+
default:
|
|
24
|
+
this.attributes.setAttribute(key, value);
|
|
25
|
+
}
|
|
26
|
+
|
|
15
27
|
});
|
|
16
28
|
}
|
|
17
29
|
if (typeof this.data?.classes === 'object' && Array.isArray(this.data.classes)) {
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Renderable } from '../../core/renderable.js';
|
|
2
|
+
|
|
3
|
+
class AnalyticsConfig extends Renderable {
|
|
4
|
+
constructor (data) {
|
|
5
|
+
super(data, 'analyticsConfig');
|
|
6
|
+
this._analytics = data.analytics;
|
|
7
|
+
this._analytics.domain = '$(1)';
|
|
8
|
+
this._analytics.site.environment = '$(2)';
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
async render () {
|
|
12
|
+
return `
|
|
13
|
+
<script>
|
|
14
|
+
const xhr = new XMLHttpRequest();
|
|
15
|
+
xhr.open('GET', '/env.json', false);
|
|
16
|
+
xhr.send(null);
|
|
17
|
+
|
|
18
|
+
if (xhr.status === 200) {
|
|
19
|
+
const env = JSON.parse(xhr.responseText);
|
|
20
|
+
const analytics = ${JSON.stringify(this._analytics).replace('"$(1)"', 'env.domain').replace('"$(2)"', 'env.env')};
|
|
21
|
+
window.dsfr = { analytics };
|
|
22
|
+
} else {
|
|
23
|
+
console.error('Failed to load JSON:', xhr.status, xhr.statusText);
|
|
24
|
+
}
|
|
25
|
+
</script>`;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export { AnalyticsConfig };
|
package/src/page/head/head.js
CHANGED
|
@@ -5,6 +5,7 @@ import { Renderable } from '../../core/renderable.js';
|
|
|
5
5
|
import { Favicon } from './favicon.js';
|
|
6
6
|
import { Resource } from './resource.js';
|
|
7
7
|
import { Share } from './share.js';
|
|
8
|
+
import { AnalyticsConfig } from './analytics-config.js';
|
|
8
9
|
|
|
9
10
|
class Head extends Renderable {
|
|
10
11
|
|
|
@@ -16,6 +17,7 @@ class Head extends Renderable {
|
|
|
16
17
|
this._resource = new Resource(data);
|
|
17
18
|
this._share = new Share(data);
|
|
18
19
|
this._stylesheets = new Stylesheets(data);
|
|
20
|
+
this._analyticsConfig = new AnalyticsConfig(data);
|
|
19
21
|
}
|
|
20
22
|
|
|
21
23
|
async render () {
|
|
@@ -30,6 +32,7 @@ class Head extends Renderable {
|
|
|
30
32
|
${await this._share.render()}
|
|
31
33
|
${await this._stylesheets.render()}
|
|
32
34
|
${await this._resource.render()}
|
|
35
|
+
${await this._analyticsConfig.render()}
|
|
33
36
|
</head>
|
|
34
37
|
`;
|
|
35
38
|
}
|
package/src/page/html.js
CHANGED