@gouvfr/dsfr-roller 1.0.32 → 1.0.34

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.
Files changed (29) hide show
  1. package/package.json +2 -2
  2. package/src/component/components/display-modal.js +1 -0
  3. package/src/component/components/sidemenu.js +4 -2
  4. package/src/node/directive/components/table/table-container-directive.js +2 -2
  5. package/src/node/directive/doc/guidance/guideline-container-directive.js +2 -2
  6. package/src/node/directive/home/hp-showcase-card-container-directive.js +3 -4
  7. package/src/node/directive/home/hp-slice-video-container-directive.js +1 -2
  8. package/src/node/generic/image-node.js +1 -1
  9. package/src/page/body/edit.js +59 -0
  10. package/src/page/body/toc.js +3 -0
  11. package/src/page/head/share.js +2 -0
  12. package/src/script/main/cmp/index.js +2 -2
  13. package/src/script/main/cmp/tarteaucitron/tarteaucitron.js +5 -5
  14. package/src/script/main/elements/storybook.js +1 -1
  15. package/src/style/home/_showcase.scss +23 -7
  16. package/src/style/main/components/{_dsfr-doc-storybook.scss → _dsfr-doc-storybook-leaf.scss} +1 -1
  17. package/src/style/main/components/_index.scss +1 -1
  18. package/src/style/main/utility/_global.scss +52 -19
  19. package/src/template/templates/editorial-template.js +13 -10
  20. package/static/file/Note_SIG_d_application_du_DSFR_et_gouv_fr_13_07_2023.docx +0 -0
  21. package/static/html/v1.14/palette/accent.html +3447 -0
  22. package/static/html/v1.14/palette/neutre.html +546 -0
  23. package/static/html/v1.14/palette/primaire.html +658 -0
  24. package/static/html/v1.14/palette/systeme.html +1029 -0
  25. package/src/component/components/edit.js +0 -20
  26. package/src/component/ejs/edit/edit.ejs +0 -32
  27. /package/static/{pdf/1_Circulaire_n_6411_SG_sites_Internet_de_l_Etat_et_demarches_numeriques_07_07_2023_14df00e6c2.pdf → file/Circulaire_n_6411_SG_sites_Internet_de_l_Etat_et_demarches_numeriques_07_07_2023.pdf} +0 -0
  28. /package/static/{pdf/3_Note_DINUM_qualite_des_services_numeriques_17_07_2023_9bd158313d.pdf → file/Note_DINUM_qualite_des_services_numeriques_17_07_2023.pdf} +0 -0
  29. /package/static/{pdf/2_Note_SIG_d_application_du_DSFR_et_gouv_fr_13_07_2023_e4824418a3.pdf → file/Note_SIG_d_application_du_DSFR_et_gouv_fr_13_07_2023.pdf} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gouvfr/dsfr-roller",
3
- "version": "1.0.32",
3
+ "version": "1.0.34",
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.32",
59
+ "@gouvfr/dsfr-forge": "=1.0.34",
60
60
  "@gouvfr/dsfr-publisher": "npm:@gouvfr/dsfr@1.13.2",
61
61
  "deepmerge": "^4.3.1",
62
62
  "ejs": "^3.1.10",
@@ -18,6 +18,7 @@ class DisplayModal extends Component {
18
18
  id: 'display-modal',
19
19
  title: this.data.resource.display.title,
20
20
  size: 'sm',
21
+ titleMarkup: 'p',
21
22
  closeButton: {
22
23
  label: this.data.fragments.button.close,
23
24
  },
@@ -34,7 +34,8 @@ class Sidemenu extends Component {
34
34
  collapseId: this.uniqueId(),
35
35
  buttonLabel: this.data.buttonLabel,
36
36
  titleId: this.uniqueId(),
37
- title: this.data.text,
37
+ title: this.data.titleLabel,
38
+ modifier: 'sticky-full-height',
38
39
  items: this.data?.items?.map(item => this._formatItem(item)).filter(item => item)
39
40
  };
40
41
  }
@@ -50,8 +51,9 @@ class Sidemenu extends Component {
50
51
  }
51
52
 
52
53
  _formatLink (link) {
54
+ const text = link.titleId ? `${link.text} (<span lang="en">${link.titleId}</span>)` : link.text;
53
55
  const badge = link.badge ? this._formatBadge(link.badge) : '';
54
- const label = link.badge ? link.text + badge : link.text;
56
+ const label = link.badge ? text + badge : text;
55
57
  return {
56
58
  ...formatLink(link),
57
59
  active: link.isCurrent,
@@ -30,8 +30,8 @@ class TableContainerDirective extends Node {
30
30
  const table = this.findDescendantsByType('table')[0];
31
31
  if (!table) return;
32
32
 
33
- if (properties.scroll === 'false') table.attributes.addClass('fr-table--no-scroll');
34
- if (properties.caption === 'false') table.attributes.addClass('fr-table--no-caption');
33
+ if (properties.scroll === false) table.attributes.addClass('fr-table--no-scroll');
34
+ if (properties.caption === false) table.attributes.addClass('fr-table--no-caption');
35
35
 
36
36
  const cellCount = table.children[0].children.length;
37
37
 
@@ -12,6 +12,7 @@ class GuidelineContainerDirective extends Node {
12
12
 
13
13
  const valid = data.properties.valid === true;
14
14
  const col = data.properties.col || '12';
15
+ const title = valid ? data.fragments.do : data.fragments.dont;
15
16
  const description = data.children.filter(child => {
16
17
  switch (true) {
17
18
  case child?.data?.directiveLabel === true:
@@ -22,7 +23,6 @@ class GuidelineContainerDirective extends Node {
22
23
  return true;
23
24
  }
24
25
  });
25
- const title = valid ? data.fragments.do : data.fragments.dont;
26
26
 
27
27
  return super.structure({
28
28
  type: 'htmlContainer',
@@ -39,7 +39,7 @@ class GuidelineContainerDirective extends Node {
39
39
  classes: ['dsfr-doc-guideline__img'],
40
40
  attributes: {
41
41
  src: image.url,
42
- alt: title
42
+ alt: image.alt,
43
43
  }
44
44
  },
45
45
  {
@@ -18,10 +18,9 @@ class HpShowcaseCardContainerDirective extends Node {
18
18
  classes: ['dsfr-doc-hp-showcase-card'],
19
19
  children: [
20
20
  {
21
- type: 'link',
21
+ type: 'htmlContainer',
22
+ tagName: 'div',
22
23
  classes: ['dsfr-doc-hp-showcase-card__img'],
23
- url: this._links[0].url,
24
- title: this._links[0].title || this._links[0].children[0].value || this._image.alt,
25
24
  children: [
26
25
  {
27
26
  classes: ['fr-responsive-img', data.imgDarkUrl ? 'dsfr-doc-hp-showcase-card__img--light' : ''],
@@ -51,7 +50,7 @@ class HpShowcaseCardContainerDirective extends Node {
51
50
  get structureLinks() {
52
51
  let structureLinks = {
53
52
  ...this._links[0],
54
- classes: ['dsfr-doc-hp-showcase-card__link', 'fr-link'],
53
+ classes: ['dsfr-doc-hp-showcase-card__link', 'dsfr-doc-hp-showcase-card__link--extended', 'fr-link'],
55
54
  };
56
55
  if (this._links.length > 1) {
57
56
  structureLinks = {
@@ -193,8 +193,7 @@ class HpSliceVideoContainerDirective extends Node {
193
193
  classes: ['fr-modal__content'],
194
194
  children: [
195
195
  {
196
- type: 'htmlContainer',
197
- tagName: 'h3',
196
+ type: 'paragraph',
198
197
  classes: ['fr-modal__title'],
199
198
  attributes: {
200
199
  id: modalId + '-title'
@@ -4,7 +4,7 @@ class ImageNode extends Node {
4
4
  constructor(data) {
5
5
  super(data, 'img', true);
6
6
  this.attributes.setAttribute('src', this.data.url);
7
- if (this.data.alt) this.attributes.setAttribute('alt', this.data.alt);
7
+ this.attributes.setAttribute('alt', this.data.alt ?? '');
8
8
  if (this.data.title) this.attributes.setAttribute('title', this.data.title);
9
9
  }
10
10
  }
@@ -0,0 +1,59 @@
1
+ class Edit {
2
+ constructor(data) {
3
+ this._node = {
4
+ type: 'htmlContainer',
5
+ tagName: 'div',
6
+ classes: ['dsfr-doc-edit', 'fr-background-alt--blue-france', `fr-icon-${data.icon ?? 'edit-fill'}`],
7
+ children: [
8
+ {
9
+ type: 'heading',
10
+ classes: ['dsfr-doc-edit__title', 'fr-h5'],
11
+ depth: data.depth ?? 5,
12
+ children: [
13
+ {
14
+ type: 'text',
15
+ value: data.title
16
+ }
17
+ ]
18
+ },
19
+ {
20
+ type: 'paragraph',
21
+ classes: ['dsfr-doc-edit__description'],
22
+ children: [
23
+ {
24
+ type: 'text',
25
+ value: data.description
26
+ }
27
+ ]
28
+ },
29
+ {
30
+ type: 'paragraph',
31
+ classes: ['dsfr-doc-edit__link'],
32
+ children: [
33
+ {
34
+ type: 'link',
35
+ classes: ['fr-link'],
36
+ attributes: {
37
+ href: data.editUrl,
38
+ target: '_blank',
39
+ title: `${data.link} - ${data.blankLabel}`
40
+ },
41
+ children: [
42
+ {
43
+ type: 'text',
44
+ value: data.link
45
+ }
46
+ ]
47
+ }
48
+ ]
49
+ }
50
+ ]
51
+ }
52
+ }
53
+
54
+ get node () {
55
+ return this._node;
56
+ }
57
+ }
58
+
59
+ export { Edit };
@@ -83,6 +83,9 @@ class TOC extends Renderable {
83
83
  depths = this._data.toc.split(',').map(depth => parseInt(depth.trim(), 10)).filter(depth => !isNaN(depth));
84
84
  mainList = filterHeadings(mainList, depths);
85
85
  break;
86
+ case 'number':
87
+ mainList = filterHeadings(mainList, [this._data.toc]);
88
+ break;
86
89
  }
87
90
 
88
91
  const summary = new Summary({ title: this.data?.fragments?.summary?.title, list: mainList });
@@ -13,6 +13,8 @@ class Share extends Renderable {
13
13
 
14
14
  async render() {
15
15
  return `
16
+ <meta name="description" content="${this._description}">
17
+
16
18
  <meta property="og:title" content="${this._title}">
17
19
  <meta property="og:description" content="${this._description}">
18
20
  <meta property="og:image" content="${this._cover}">
@@ -5,7 +5,7 @@ import tacLang from './tarteaucitron/lang';
5
5
 
6
6
  import {
7
7
  vimeo,
8
- // youtube,
8
+ youtube,
9
9
  // dailymotion,
10
10
  // twitterembed,
11
11
  // instagram,
@@ -19,7 +19,7 @@ class ConsentManagementPlatform {
19
19
  getCurrentRepo() + this._data?.tarteaucitron?.legalNoticeLink;
20
20
  this._services = [
21
21
  vimeo,
22
- // youtube,
22
+ youtube,
23
23
  // dailymotion,
24
24
  // twitterembed,
25
25
  // instagram,
@@ -436,9 +436,9 @@ export var tarteaucitron = {
436
436
  </button>
437
437
  </div>
438
438
  <div class="fr-modal__content">
439
- <h2 class="fr-modal__title fr-h3" id="fr-consent-modal-title">
439
+ <p class="fr-modal__title fr-h3" id="fr-consent-modal-title">
440
440
  ${tarteaucitron.lang.title}
441
- </h2>
441
+ </p>
442
442
  <div class="fr-consent-manager">
443
443
  <div class="fr-consent-service fr-consent-manager__header">
444
444
  <fieldset class="fr-fieldset fr-fieldset--inline">
@@ -666,14 +666,14 @@ export var tarteaucitron = {
666
666
  !tarteaucitron.parameters.AcceptAllCta
667
667
  ) {
668
668
  html += `<div tabindex="-1" id="tarteaucitronAlertBig" class="fr-consent-banner" ${modalAttrs}>`;
669
- html += `<h2 class="fr-h6">${tarteaucitron.lang.alertBigPrivacy.title}</h2>`;
669
+ html += `<p class="fr-h6">${tarteaucitron.lang.alertBigPrivacy.title}</p>`;
670
670
  html += `<div id="tarteaucitronDisclaimerAlert" class="fr-consent-banner__content"><p class="fr-text--sm">${tarteaucitron.lang.alertBigPrivacy.content}</p></div>`;
671
671
  html += `<ul class="fr-consent-banner__buttons fr-btns-group fr-btns-group--right fr-btns-group--inline-reverse fr-btns-group--inline-sm">`;
672
672
  html += `<li><button class="fr-btn fr-btn--secondary" data-fr-opened="false" aria-controls="consent-modal" aria-label="${tarteaucitron.lang.personalize} ${tarteaucitron.lang.modalWindow}" title="${tarteaucitron.lang.personalize} ${tarteaucitron.lang.modalWindow}" type="button" id="tarteaucitronPersonalize">${tarteaucitron.lang.personalize}</button></li>`;
673
673
  html += '</ul></div>';
674
674
  } else {
675
675
  html += `<div tabindex="-1" id="tarteaucitronAlertBig" class="fr-consent-banner" ${modalAttrs}>`;
676
- html += `<h2 class="fr-h6">${tarteaucitron.lang.alertBigPrivacy.title}</h2>`;
676
+ html += `<p class="fr-h6">${tarteaucitron.lang.alertBigPrivacy.title}</p>`;
677
677
  html += `<div id="tarteaucitronDisclaimerAlert" class="fr-consent-banner__content"><p class="fr-text--sm">${
678
678
  tarteaucitron.parameters.highPrivacy
679
679
  ? tarteaucitron.lang.alertBigPrivacy.content
@@ -925,7 +925,7 @@ export var tarteaucitron = {
925
925
  // The setimeout at 1500 ms will prevent the location.reload event to be properly binded...
926
926
  if (tarteaucitronNoAdBlocker === false) {
927
927
  html = `<div id="tarteaucitronAlertBig" class="fr-consent-banner tarteaucitronAlertBig tarteaucitron-display-block" role="alert" aria-live="polite">`;
928
- html += `<h2 class="fr-h6">${tarteaucitron.lang.adblock}</h2>`;
928
+ html += `<p class="fr-h6">${tarteaucitron.lang.adblock}</p>`;
929
929
  html += `<div id="tarteaucitronDisclaimerAlert" class="fr-consent-banner__content"><p class="fr-text--sm">${tarteaucitron.lang.adblock_call}</p></div>`;
930
930
  html += `<ul class="fr-consent-banner__buttons fr-btns-group fr-btns-group--right fr-btns-group--inline-reverse fr-btns-group--inline-sm">`;
931
931
  html += `<li><button class="fr-btn tarteaucitronCTAButton" aria-label="${tarteaucitron.lang.reload}" title="${tarteaucitron.lang.reload}" type="button" id="tarteaucitronCTAButton">${tarteaucitron.lang.reload}</button></li>`;
@@ -12,7 +12,7 @@ class Storybook extends Element {
12
12
  }
13
13
 
14
14
  handleMessage(event) {
15
- if (event.data?.type === 'storybook-height-change') {
15
+ if (event.data?.type === 'storybook-height-change' && this.iframe.id === event.data.iframeId) {
16
16
  this.setIframeHeight(event.data.height);
17
17
  }
18
18
  }
@@ -24,6 +24,7 @@
24
24
  }
25
25
 
26
26
  &-card {
27
+ position: relative;
27
28
  width: 100%;
28
29
  padding: 0;
29
30
 
@@ -42,6 +43,13 @@
42
43
  display: none;
43
44
  }
44
45
 
46
+ &:has(+ .dsfr-doc-hp-showcase-card__link--extended:hover) {
47
+ img,
48
+ svg {
49
+ transform: scale(1.05);
50
+ }
51
+ }
52
+
45
53
  img,
46
54
  svg {
47
55
  transition: transform 0.3s ease-out;
@@ -49,13 +57,6 @@
49
57
  width: 100%;
50
58
  height: auto;
51
59
  }
52
-
53
- &:hover {
54
- img,
55
- svg {
56
- transform: scale(1.05);
57
- }
58
- }
59
60
  }
60
61
 
61
62
  &__links-group {
@@ -71,6 +72,17 @@
71
72
  }
72
73
  }
73
74
  }
75
+
76
+ &__link--extended {
77
+ &::before {
78
+ content: '';
79
+ position: absolute;
80
+ top: 0;
81
+ left: 0;
82
+ width: 100%;
83
+ height: calc(100% - 2.25rem);
84
+ }
85
+ }
74
86
  }
75
87
 
76
88
  @media (min-width: 36em) {
@@ -108,6 +120,10 @@
108
120
  }
109
121
  }
110
122
  }
123
+
124
+ &__link--extended::before {
125
+ height: calc(100% - 2.5rem);
126
+ }
111
127
  }
112
128
 
113
129
  &__title {
@@ -1,5 +1,5 @@
1
1
  .dsfr-doc-storybook-leaf {
2
- iframe {
2
+ .dsfr-iframe-storybook-root {
3
3
  border: 1px solid var(--border-default-grey);
4
4
  }
5
5
  }
@@ -7,4 +7,4 @@
7
7
  @use 'dsfr-doc-searchbar';
8
8
  @use 'dsfr-doc-pagination';
9
9
  @use 'dsfr-doc-edit';
10
- @use 'dsfr-doc-storybook';
10
+ @use 'dsfr-doc-storybook-leaf';
@@ -8,7 +8,9 @@
8
8
  margin-bottom: 2rem;
9
9
  }
10
10
 
11
- #content-editorial {
11
+ .content-editorial {
12
+ margin-bottom: var(--block-spacing);
13
+
12
14
  img {
13
15
  max-width: 100%;
14
16
  height: auto;
@@ -26,6 +28,10 @@
26
28
  }
27
29
  }
28
30
 
31
+ .fr-breadcrumb__list {
32
+ margin-bottom: 0;
33
+ }
34
+
29
35
  :not(.fr-callout) > p {
30
36
  & + {
31
37
  dl,
@@ -44,27 +50,54 @@
44
50
  }
45
51
  }
46
52
 
47
- // .fr-sr-only attributes
48
- .fr-sidemenu {
49
- &__title {
50
- clip: rect(0, 0, 0, 0);
51
- height: 1px;
52
- margin: -1px;
53
- overflow: hidden;
54
- padding: 0;
55
- position: absolute;
56
- white-space: nowrap;
57
- width: 1px;
58
- border: 0;
59
- display: block;
60
- }
61
- }
62
-
63
53
  pre code.hljs {
64
54
  border-radius: 0;
65
55
  }
66
56
  }
67
57
 
68
- .fr-footer {
69
- margin-top: var(--block-spacing);
58
+ .fr-summary ol {
59
+ margin-bottom: 0;
60
+ }
61
+
62
+ .fr-breadcrumb {
63
+ margin-top: 0;
64
+ @media (min-width: 48em) {
65
+ margin-top: 1rem;
66
+ }
67
+ }
68
+
69
+ .fr-sidemenu {
70
+
71
+ &__title {
72
+ clip: rect(0, 0, 0, 0);
73
+ height: 1px;
74
+ margin: -1px;
75
+ overflow: hidden;
76
+ padding: 0;
77
+ position: absolute;
78
+ white-space: nowrap;
79
+ width: 1px;
80
+ border: 0;
81
+ display: block;
82
+ }
83
+
84
+ .fr-sidemenu__inner {
85
+ @media (min-width: 48em) {
86
+ padding-top: 1.5rem;
87
+ }
88
+ }
89
+
90
+ div:not(.fr-collapse) {
91
+ .fr-sidemenu__list {
92
+ .fr-sidemenu__item {
93
+ &::before {
94
+ box-shadow: inset 0 -1px 0 0 var(--border-default-grey);
95
+ }
96
+
97
+ &:last-child::before {
98
+ box-shadow: none;
99
+ }
100
+ }
101
+ }
102
+ }
70
103
  }
@@ -2,45 +2,48 @@ import { Template } from '../template.js';
2
2
  import { Sidemenu } from '../../component/components/sidemenu.js';
3
3
  import { Breadcrumb } from '../../component/components/breadcrumb.js';
4
4
  import { TOC } from '../../page/body/toc.js';
5
- import { Edit } from '../../component/components/edit.js';
5
+ import { Edit } from '../../page/body/edit.js';
6
6
 
7
7
  class EditorialTemplate extends Template {
8
8
  constructor (data) {
9
9
  super(data);
10
10
 
11
11
  this._hasSidemenu = data?.resource?.navigation?.sidemenu !== undefined;
12
-
13
- this._hasEditUrl = data?.editUrl !== undefined;
14
-
15
12
  if (this._hasSidemenu) this._sidemenu = new Sidemenu(data.resource.navigation.sidemenu, data.resource.badge);
16
13
 
17
- if (this._hasEditUrl) this._edit = new Edit({...data.resource.edit, editUrl: data.editUrl, blankLabel: this.data.fragments.blank});
18
-
19
14
  this._breadcrumb = new Breadcrumb(data.breadcrumb);
20
15
 
21
16
  this._toc = new TOC(data, this.content.nodes);
22
17
  }
23
18
 
19
+ structure (data) {
20
+ this._hasEditUrl = data?.editUrl != null;
21
+ if (this._hasEditUrl) {
22
+ const edit = new Edit({...data.resource.edit, editUrl: data.editUrl, blankLabel: data.fragments.blank});
23
+ data.nodes.push(edit.node);
24
+ }
25
+
26
+ return super.structure(data);
27
+ }
28
+
24
29
  async render () {
25
30
  const cols = [];
26
31
  if (this._hasSidemenu) {
27
32
  cols.push(`
28
- <div class="fr-col-12 fr-col-md-4 fr-pt-12v">
33
+ <div class="fr-col-12 fr-col-md-4">
29
34
  ${await this._sidemenu.render()}
30
35
  </div>
31
36
  `);
32
37
  }
33
38
 
34
39
  cols.push(`
35
- <div class="fr-col-12 fr-col-md-8" id="content-editorial">
40
+ <div class="content-editorial fr-col-12 fr-col-md-8">
36
41
  ${await this._breadcrumb.render()}
37
42
  ${await this._toc.render()}
38
43
  ${await super.render()}
39
- ${await this._edit.render()}
40
44
  </div>
41
45
  `);
42
46
 
43
-
44
47
  return `
45
48
  <div class="fr-container">
46
49
  <div class="fr-grid-row fr-grid-row--gutters fr-grid-row--center">