qc-trousse-sdg 1.3.1 → 1.4.0-develop.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.
Files changed (51) hide show
  1. package/README.md +7 -1
  2. package/dist/css/qc-sdg-no-grid.min.css +1 -1
  3. package/dist/css/qc-sdg.min.css +1 -1
  4. package/dist/js/qc-sdg.min.js +1 -1
  5. package/package.json +3 -3
  6. package/public/css/qc-sdg-no-grid.css +1 -0
  7. package/public/css/qc-sdg.css +1 -0
  8. package/public/index.html +375 -296
  9. package/public/js/qc-doc-sdg.js +5043 -1580
  10. package/public/js/qc-sdg.js +8111 -3685
  11. package/rollup.config.js +1 -0
  12. package/src/doc/components/Code.svelte +10 -15
  13. package/src/doc/components/Exemple.svelte +18 -15
  14. package/src/doc/components/Switch.svelte +7 -6
  15. package/src/doc/components/TopNav.svelte +6 -3
  16. package/src/doc/components/color-doc.svelte +2 -2
  17. package/src/doc/qc-doc-sdg.js +4 -1
  18. package/src/sdg/_components.js +10 -9
  19. package/src/sdg/components/Alert/Alert.svelte +69 -0
  20. package/src/sdg/components/Alert/AlertWC.svelte +24 -0
  21. package/src/sdg/components/ExternalLink/ExternalLink.svelte +96 -0
  22. package/src/sdg/components/ExternalLink/ExternalLinkWC.svelte +15 -0
  23. package/src/sdg/components/Icon/Icon.svelte +26 -0
  24. package/src/sdg/components/Icon/IconWC.svelte +20 -0
  25. package/src/sdg/components/IconButton/IconButton.svelte +30 -0
  26. package/src/sdg/components/IconButton/IconButtonWC.svelte +19 -0
  27. package/src/sdg/components/Notice/Notice.svelte +83 -0
  28. package/src/sdg/components/Notice/NoticeWC.svelte +25 -0
  29. package/src/sdg/components/PivFooter/PivFooter.svelte +51 -0
  30. package/src/sdg/components/PivFooter/PivFooterWC.svelte +52 -0
  31. package/src/sdg/components/PivFooter/_defaultCopyright.svelte +11 -0
  32. package/src/sdg/components/PivHeader/PivHeader.svelte +144 -0
  33. package/src/sdg/components/PivHeader/PivHeaderWC.svelte +68 -0
  34. package/src/sdg/components/PivHeader/_defaultLinks.svelte +24 -0
  35. package/src/sdg/components/SearchBar/SearchBar.svelte +67 -0
  36. package/src/sdg/components/SearchBar/SearchBarWC.svelte +17 -0
  37. package/src/sdg/components/SearchInput/SearchInput.svelte +17 -26
  38. package/src/sdg/components/SearchInput/SearchInputWC.svelte +16 -0
  39. package/src/sdg/components/{toTop.svelte → ToTop/ToTop.svelte} +31 -38
  40. package/src/sdg/components/ToTop/ToTopWC.svelte +16 -0
  41. package/src/sdg/components/utils.js +1 -1
  42. package/src/sdg/scss/components/_pivHeader.scss +1 -0
  43. package/src/sdg/components/Button/IconButton.svelte +0 -29
  44. package/src/sdg/components/Icon.svelte +0 -39
  45. package/src/sdg/components/PivHeader/pivHeader.svelte +0 -158
  46. package/src/sdg/components/SearchBar/searchBar.svelte +0 -87
  47. package/src/sdg/components/alert.svelte +0 -88
  48. package/src/sdg/components/componentWrapper.js +0 -24
  49. package/src/sdg/components/externalLink.svelte +0 -92
  50. package/src/sdg/components/notice.svelte +0 -83
  51. package/src/sdg/components/pivFooter.svelte +0 -65
package/rollup.config.js CHANGED
@@ -89,6 +89,7 @@ let
89
89
  compilerOptions: {
90
90
  // enable run-time checks
91
91
  customElement: true,
92
+ dev: dev_process,
92
93
  cssHash: ({ hash, name, filename, css }) => {
93
94
  // replacement of default `svelte-${hash(css)}`
94
95
  return `qc-hash-${hash(css)}`;
@@ -11,22 +11,17 @@
11
11
  <script>
12
12
 
13
13
  import {HighlightJS} from "highlight.js"
14
- // import 'highlight.js/styles/default.css';
15
14
  import pretty from "pretty";
16
- import { onMount } from "svelte";
17
- import { Utils } from "../../sdg/components/utils"
18
15
 
19
- export let
20
- targetId = ''
21
- , rawCode = ''
22
- , language = 'html'
23
- , outerHTML = false
24
- ;
16
+ let {
17
+ targetId = '',
18
+ rawCode = '',
19
+ language = 'html',
20
+ outerHTML = false
21
+ } = $props();
25
22
 
26
- let
27
- hlCode
28
- , prettyCode
29
- ;
23
+ let hlCode = $state();
24
+ let prettyCode = $state();
30
25
 
31
26
  function copy() {
32
27
  navigator.clipboard.writeText(prettyCode);
@@ -48,14 +43,14 @@
48
43
  hlCode = HighlightJS.highlight(prettyCode, {language:language}).value;
49
44
  }
50
45
 
51
- $: updateHLCode(rawCode, targetId)
46
+ $effect(() => updateHLCode(rawCode, targetId));
52
47
 
53
48
  </script>
54
49
 
55
50
  <pre
56
51
  ><code class="hljs"
57
52
  ><button class="btn btn-sm btn-primary"
58
- on:click={copy}>
53
+ onclick={copy}>
59
54
  <span class="copy">copier</span>
60
55
  <span class="copied">copié !</span>
61
56
  </button
@@ -11,24 +11,27 @@
11
11
  <script>
12
12
  import Code from "./Code.svelte";
13
13
  import {onMount} from "svelte";
14
- export let
15
- caption = "SVP fournir une description"
16
- , codeTargetId
17
- , hideCode = false
18
- , rawCode
19
- ;
20
- let exempleCode,
21
- figure,
22
- rootElement,
23
- exempleArea,
24
- figCaption;
14
+
15
+ let {
16
+ caption = "SVP fournir une description",
17
+ codeTargetId,
18
+ hideCode = false,
19
+ rawCode,
20
+ ...restProps
21
+ } = $props();
22
+
23
+ let exempleCode = $state();
24
+ let figure = $state();
25
+ let rootElement = $state();
26
+ let exempleArea = $state();
27
+ let figCaption = $state();
28
+
25
29
  onMount(() => {
26
30
  rootElement.parentElement.childNodes.forEach(node => {
27
- if (node.nodeType == 3) {
31
+ if (node.nodeType === 3) {
28
32
  return;
29
33
  }
30
- if (node != rootElement) {
31
- // let detach = rootElement.removeChild(node)
34
+ if (node !== rootElement) {
32
35
  exempleArea.appendChild(node)
33
36
  }
34
37
  exempleCode = rawCode
@@ -42,7 +45,7 @@
42
45
  <div bind:this={rootElement}
43
46
  class="exemple-area"
44
47
  >
45
- <figure {...$$restProps}
48
+ <figure {...restProps}
46
49
  bind:this={figure}
47
50
  >
48
51
  <div bind:this={exempleArea}
@@ -3,15 +3,16 @@
3
3
  shadow:'none'
4
4
  }}" />
5
5
  <script>
6
- export let
7
- value=false,
8
- name='switch',
6
+ let {
7
+ value = $bindable(false),
8
+ name = 'switch',
9
9
  color = {
10
10
  unchecked: 'grey-light',
11
11
  checked: 'blue-regular',
12
12
  slider: 'background'
13
- }
14
- ;
13
+ },
14
+ ...rest
15
+ } = $props();
15
16
 
16
17
  </script>
17
18
  <div class="switch"
@@ -25,7 +26,7 @@
25
26
  {name}
26
27
  bind:checked={value}
27
28
  aria-checked={value}
28
- {...$$restProps}
29
+ {...rest}
29
30
  />
30
31
  <span class="slider round" ></span>
31
32
  </div>
@@ -7,11 +7,14 @@
7
7
  }}" />
8
8
  <script>
9
9
  import Switch from "./Switch.svelte";
10
- let value = localStorage.getItem('dark-theme') === "true";
10
+ let value = $state(localStorage.getItem('dark-theme') === "true");
11
11
 
12
- $: document.documentElement.classList.toggle('qc-dark-theme', value)
13
- $: localStorage.setItem('dark-theme', value)
12
+ $effect(() => {
13
+ document.documentElement.classList.toggle('qc-dark-theme', value);
14
+ localStorage.setItem('dark-theme', value);
15
+ });
14
16
  </script>
17
+
15
18
  <div role="complementary">
16
19
  <div class="qc-container top-nav">
17
20
  <div class="switch-control">
@@ -6,11 +6,11 @@
6
6
  }
7
7
  }}" />
8
8
  <script>
9
- export let
9
+ let {
10
10
  title,
11
11
  token,
12
12
  border = null
13
- ;
13
+ } = $props();
14
14
 
15
15
  </script>
16
16
  <div class="color-details">
@@ -22,7 +22,10 @@ if (displayAlertLink) {
22
22
  );
23
23
  document.addEventListener(
24
24
  'qc.alert.hide',
25
- () => displayAlertLink.hidden = false
25
+ () => {
26
+ maskableAlert.setAttribute('hide', 'true');
27
+ displayAlertLink.hidden = false;
28
+ }
26
29
  )
27
30
  }
28
31
 
@@ -1,9 +1,10 @@
1
- export * from './components/notice.svelte'
2
- export * from './components/PivHeader/pivHeader.svelte'
3
- export * from './components/pivFooter.svelte'
4
- export * from './components/alert.svelte'
5
- export * from './components/toTop.svelte'
6
- export * from './components/externalLink.svelte'
7
- export * from './components/SearchBar/searchBar.svelte'
8
- export * from './components/SearchInput/SearchInput.svelte'
9
- export * from './components/Icon.svelte'
1
+ export * from './components/Notice/NoticeWC.svelte'
2
+ export * from './components/PivHeader/PivHeaderWC.svelte'
3
+ export * from './components/PivFooter/PivFooterWC.svelte'
4
+ export * from './components/Alert/AlertWC.svelte'
5
+ export * from './components/ToTop/toTopWC.svelte'
6
+ export * from './components/ExternalLink/ExternalLinkWC.svelte'
7
+ export * from './components/SearchBar/SearchBarWC.svelte'
8
+ export * from './components/SearchInput/SearchInputWC.svelte'
9
+ export * from './components/Icon/IconWC.svelte'
10
+ export * from './components/IconButton/IconButtonWC.svelte'
@@ -0,0 +1,69 @@
1
+ <script>
2
+ import {Utils} from "../utils";
3
+ import Icon from "../Icon/Icon.svelte";
4
+ import IconButton from "../IconButton/IconButton.svelte";
5
+
6
+ let {
7
+ type = "general",
8
+ maskable = "",
9
+ content = "",
10
+ hide = "false",
11
+ fullWidth = "false",
12
+ slotContent,
13
+ } = $props();
14
+
15
+ const language = Utils.getPageLanguage();
16
+
17
+ const typeClass = (type !== "") ? type : 'general';
18
+ const closeLabel = language === 'fr' ? "Fermer l’alerte" : "Close l’alerte";
19
+ const warningLabel = language === 'fr' ? "Information d'importance élevée" : "Information of high importance";
20
+ const generalLabel = language === 'fr' ? "Information importante" : "Important information";
21
+
22
+ const label = type === 'general' ? generalLabel : warningLabel;
23
+
24
+ let rootElement = $state(null);
25
+
26
+ let containerClass = "qc-container" + (fullWidth === 'true' ? '-fluid' : '');
27
+
28
+ function hideAlert() {
29
+ hide = "true";
30
+ rootElement.dispatchEvent(
31
+ new CustomEvent('qc.alert.hide', {
32
+ bubbles: true,
33
+ composed: true
34
+ })
35
+ );
36
+ }
37
+ </script>
38
+
39
+ {#if !Utils.isTruthy(hide)}
40
+ <div bind:this={rootElement}
41
+ class="qc-general-alert {typeClass}"
42
+ role="alert">
43
+ <div class={containerClass}>
44
+ <div class="qc-general-alert-elements">
45
+ <Icon type={type === 'warning' ? 'warning' : 'information'}
46
+ color={type === 'general' ? 'blue-piv' : 'yellow-dark'}
47
+ size="nm"
48
+ label={label}
49
+ />
50
+ <div class="qc-alert-content">
51
+ {@html content}
52
+ {@html slotContent}
53
+ </div>
54
+ {#if Utils.isTruthy(maskable)}
55
+ <IconButton aria-label={closeLabel}
56
+ onclick={hideAlert}
57
+ size="nm"
58
+ icon="clear-input"
59
+ iconSize="sm"
60
+ iconColor="text-primary"
61
+ />
62
+ {/if}
63
+ </div>
64
+ </div>
65
+ </div>
66
+ {/if}
67
+
68
+ <link rel='stylesheet'
69
+ href='{Utils.cssPath}'>
@@ -0,0 +1,24 @@
1
+ <svelte:options customElement="{{
2
+ tag:'qc-alert',
3
+ reflect: true,
4
+ props: {
5
+ type : {attribute: 'type'},
6
+ maskable : {attribute: 'maskable'},
7
+ fullWidth : {attribute: 'full-width'},
8
+ content: {attribute: 'content'},
9
+ hide: {attribute: 'hide'},
10
+ }
11
+ }}"/>
12
+
13
+ <script>
14
+
15
+ import Alert from "./Alert.svelte";
16
+
17
+ const props = $props();
18
+
19
+ </script>
20
+
21
+ <Alert
22
+ {...props}
23
+ slotContent = {`<slot />`}
24
+ />
@@ -0,0 +1,96 @@
1
+ <script>
2
+ import {Utils} from "../utils";
3
+ import {onMount} from "svelte";
4
+
5
+ const {
6
+ externalIconAlt = Utils.getPageLanguage() === 'fr'
7
+ ? "Ce lien dirige vers un autre site."
8
+ : "This link directs to another site."
9
+ } = $props();
10
+
11
+ let imgElement = $state();
12
+
13
+ function createVisibleNodesTreeWalker() {
14
+ return document.createTreeWalker(
15
+ imgElement.parentElement,
16
+ NodeFilter.SHOW_ALL,
17
+ {
18
+ acceptNode: node => {
19
+ if (node instanceof Element) {
20
+ if (node.hasAttribute('hidden')) {
21
+ return NodeFilter.FILTER_REJECT;
22
+ }
23
+ const style = window.getComputedStyle(node);
24
+ // Si l'élément est masqué par CSS (display ou visibility), on l'ignore
25
+ if (style.display === 'none'
26
+ || style.visibility === 'hidden'
27
+ || style.position === 'absolute') {
28
+ return NodeFilter.FILTER_REJECT;
29
+ }
30
+ }
31
+ if (!node instanceof Text) {
32
+ return NodeFilter.FILTER_SKIP;
33
+ }
34
+
35
+ // Ignore les nœuds vides
36
+ if (!/\S/.test(node.textContent)) {
37
+ return NodeFilter.FILTER_SKIP;
38
+ }
39
+
40
+ return NodeFilter.FILTER_ACCEPT;
41
+ }
42
+ }
43
+ );
44
+ }
45
+
46
+ onMount(() => {
47
+ imgElement.parentElement.querySelectorAll('a').forEach(link => {
48
+
49
+ // Crée un TreeWalker pour parcourir uniquement les nœuds texte visibles
50
+ const walker = createVisibleNodesTreeWalker();
51
+
52
+ let lastTextNode = null;
53
+ while (walker.nextNode()) {
54
+ lastTextNode = walker.currentNode;
55
+ }
56
+ // S'il n'y a pas de nœud texte visible, on ne fait rien
57
+ if (!lastTextNode) {
58
+ return;
59
+ }
60
+
61
+ // Séparer le contenu du dernier nœud texte en deux parties :
62
+ // le préfixe (éventuel) et le dernier mot
63
+ const text = lastTextNode.textContent;
64
+ const match = text.match(/^([\s\S]*\s)?(\S+)\s*$/m);
65
+ if (!match) {
66
+ return;
67
+ }
68
+
69
+ const prefix = match[1] || "";
70
+ const lastWord = match[2];
71
+
72
+ // Crée un span avec white-space: nowrap pour empêcher le saut de ligne de l'image de lien externe
73
+ const span = document.createElement('span');
74
+ span.classList.add('img-wrap')
75
+ span.innerHTML = `${lastWord}`;
76
+ span.appendChild(imgElement)
77
+
78
+ // Met à jour le nœud texte : on garde le préfixe et on insère le span après
79
+ if (prefix) {
80
+ lastTextNode.textContent = prefix;
81
+ lastTextNode.parentNode.insertBefore(span, lastTextNode.nextSibling);
82
+ } else {
83
+ lastTextNode.parentNode.replaceChild(span, lastTextNode);
84
+ }
85
+ });
86
+ });
87
+ </script>
88
+
89
+ <span bind:this={imgElement}
90
+ role="img"
91
+ class="qc-ext-link-img"
92
+ aria-label={externalIconAlt}>
93
+ </span>
94
+
95
+
96
+
@@ -0,0 +1,15 @@
1
+ <svelte:options customElement={{
2
+ tag: 'qc-external-link',
3
+ shadow: 'none',
4
+ props: {
5
+ externalIconAlt: { attribute: 'img-alt' }
6
+ }
7
+ }} />
8
+
9
+ <script>
10
+ import ExternalLink from "./ExternalLink.svelte";
11
+
12
+ const props = $props();
13
+ </script>
14
+
15
+ <ExternalLink {...props} />
@@ -0,0 +1,26 @@
1
+ <script>
2
+ let {
3
+ type,
4
+ label,
5
+ size = 'md',
6
+ color = 'text-primary',
7
+ width='auto',
8
+ height='auto',
9
+ ...rest
10
+ } = $props();
11
+
12
+ let attributes = $derived(width === 'auto' ? { 'data-img-size': size } : {});
13
+ </script>
14
+
15
+ <div role="img"
16
+ class="qc-icon"
17
+ aria-label={label}
18
+ style="--img-color:var(--qc-color-{color});
19
+ --img-width:{width};
20
+ --img-height:{height};
21
+ "
22
+ data-img-type={type}
23
+ {...attributes}
24
+ {...rest}
25
+ >
26
+ </div>
@@ -0,0 +1,20 @@
1
+ <svelte:options customElement="{{
2
+ tag: 'qc-icon',
3
+ shadow: 'none',
4
+ props: {
5
+ type : {attribute: 'icon'},
6
+ label: {attribute: 'label'},
7
+ color: {attribute: 'color'},
8
+ size: {attribute: 'size'},
9
+ width: {attribute: 'width'},
10
+ height: {attribute: 'height'}
11
+ }
12
+ }}" />
13
+
14
+ <script>
15
+ import Icon from "./Icon.svelte";
16
+
17
+ const props = $props();
18
+ </script>
19
+
20
+ <Icon {...props} />
@@ -0,0 +1,30 @@
1
+ <script>
2
+ import Icon from "../Icon/Icon.svelte";
3
+
4
+ const {
5
+ size = 'xl',
6
+ label,
7
+ icon,
8
+ iconSize,
9
+ iconColor,
10
+ class: className = '',
11
+ ...rest
12
+ } = $props();
13
+
14
+ </script>
15
+
16
+ <button
17
+ data-button-size={size}
18
+ class={`qc-icon-button ${className}`}
19
+ {...rest}
20
+ >
21
+ {#if icon}
22
+ <Icon type={icon}
23
+ size={iconSize}
24
+ color={iconColor}
25
+ aria-hidden="true"
26
+ label={label}
27
+ />
28
+ {/if}
29
+ </button>
30
+
@@ -0,0 +1,19 @@
1
+ <svelte:options customElement={{
2
+ tag: 'qc-icon-button',
3
+ shadow: 'none',
4
+ props: {
5
+ size: { attribute: 'size' },
6
+ label: { attribute: 'label' },
7
+ icon: { attribute: 'icon' },
8
+ iconSize: { attribute: 'icon-size' },
9
+ iconColor: { attribute: 'icon-color' }
10
+ }
11
+ }} />
12
+
13
+ <script>
14
+ import IconButton from './IconButton.svelte';
15
+
16
+ const props = $props();
17
+ </script>
18
+
19
+ <IconButton {...props} />
@@ -0,0 +1,83 @@
1
+ <script>
2
+ import { Utils } from "../utils"
3
+ import Icon from "../Icon/Icon.svelte";
4
+
5
+ const isFr = Utils.getPageLanguage() === 'fr';
6
+ const defaultHeader = 'h2';
7
+ const defaultType = 'information';
8
+ const typesDescriptions = {
9
+ 'advice': isFr ? "Avis conseil" : "Advisory notice",
10
+ 'note': isFr ? "Avis explicatif" : "Explanatory notice",
11
+ 'information': isFr ? "Avis général" : "General notice",
12
+ 'warning': isFr ? "Avis d’avertissement" : "Warning notice",
13
+ 'success': isFr ? "Avis de réussite" : "Success notice",
14
+ 'error': isFr ? "Avis d’erreur" : "Error notice"
15
+ };
16
+
17
+ let {
18
+ title = "",
19
+ type = defaultType,
20
+ content = "",
21
+ header = defaultHeader,
22
+ icon,
23
+ slotContent
24
+ } = $props();
25
+
26
+ const types = Object.keys(typesDescriptions);
27
+
28
+ const usedType = types.includes(type) ? type : defaultType;
29
+ const usedHeader = header.match(/h[1-6]/) ? header : defaultHeader;
30
+ const role = usedType === "success" ? "status" : (usedType === "error" ? "alert" : null);
31
+
32
+ let noticeElement = $state(null);
33
+ $effect(() => {
34
+ if (role && noticeElement) {
35
+ const tempNodes = Array.from(noticeElement.childNodes);
36
+ noticeElement.innerHTML = "";
37
+
38
+ // Réinsère le contenu pour qu'il soit détecté par le lecteur d'écran.
39
+ tempNodes.forEach(node => noticeElement.appendChild(node));
40
+ }
41
+ });
42
+
43
+ const shouldUseIcon = usedType === "advice" || usedType === "note";
44
+
45
+ // Si le type est "advice" ou "note", on force "neutral" (le gris), sinon on garde le type normal
46
+ const computedType = shouldUseIcon ? "neutral" : usedType;
47
+ const iconType = shouldUseIcon ? (icon ?? "note") : usedType;
48
+ const iconLabel = typesDescriptions[type] ?? typesDescriptions['information'];
49
+ </script>
50
+
51
+ <!-- TODO Confirmer tabindex. On pense que c'est important de recevoir le focus (notamment dans les formulaires) en fait pour nous c'est très important, sinon en mode formulaire au lecteur écran (nav avec TAB, ce n'est jamais lu). -->
52
+ <!--Le warning `Svelte: noninteractive element cannot have nonnegative tabIndex value`
53
+ associe a tabindex="0" doit etre ignore pour qu'on puisse focus sur le composant sans
54
+ le denaturaliser.-->
55
+
56
+ <!-- svelte-ignore a11y_no_noninteractive_tabindex -->
57
+ <div class="qc-component qc-notice qc-{computedType}"
58
+ tabindex="0"
59
+ >
60
+ <div class="icon-container">
61
+ <div class="qc-icon">
62
+ <Icon type={iconType}
63
+ label={iconLabel}
64
+ size="nm"
65
+ />
66
+ </div>
67
+ </div>
68
+
69
+ <div class="content-container">
70
+ <div class="content" {role} bind:this={noticeElement}>
71
+ {#if title && title !== ""}
72
+ <svelte:element this={usedHeader}>
73
+ {@html title}
74
+ </svelte:element>
75
+ {/if}
76
+
77
+ {@html content}
78
+
79
+ {@render slotContent?.()}
80
+ </div>
81
+ </div>
82
+ </div>
83
+ <link rel='stylesheet' href='{Utils.cssPath}'>
@@ -0,0 +1,25 @@
1
+ <svelte:options customElement={{
2
+ tag: 'qc-notice',
3
+ props: {
4
+ title: { attribute: 'title', type: 'String' },
5
+ type: { attribute: 'type', type: 'String' },
6
+ content: { attribute: 'content', type: 'String' },
7
+ header: { attribute: 'header', type: 'String' },
8
+ icon: { attribute: 'icon', type: 'String' }
9
+ }
10
+ }} />
11
+
12
+ <script>
13
+ import Notice from './Notice.svelte';
14
+
15
+ const props = $props();
16
+ </script>
17
+
18
+
19
+ <Notice
20
+ {...props}
21
+ >
22
+ {#snippet slotContent()}
23
+ <slot />
24
+ {/snippet}
25
+ </Notice>
@@ -0,0 +1,51 @@
1
+ <script>
2
+ import { Utils } from "../utils"
3
+ import DefaultCopyright from "./_defaultCopyright.svelte";
4
+ const lang = Utils.getPageLanguage();
5
+
6
+ let {
7
+ logoUrl = '/',
8
+ logoSrc = Utils.imagesRelativePath + '/QUEBEC_couleur.svg',
9
+ logoSrcDarkTheme = Utils.imagesRelativePath + '/QUEBEC_blanc.svg',
10
+ logoAlt = lang === 'fr' ? 'Logo du gouvernement du Québec' : 'Logo of the Quebec government',
11
+ copyrightText,
12
+ logoWidth = 139,
13
+ logoHeight = 50,
14
+ copyrightUrl,
15
+ mainSlot,
16
+ copyrightSlot
17
+ } = $props();
18
+ </script>
19
+
20
+ <div class="qc-piv-footer qc-container-fluid">
21
+ {#if mainSlot}
22
+ {@render mainSlot()}
23
+ {/if}
24
+
25
+ <a href="{logoUrl}"
26
+ class="logo"
27
+ style:--logo-width={logoWidth}
28
+ style:--logo-height={logoHeight}
29
+ >
30
+ {#each [
31
+ ['light', logoSrc],
32
+ ['dark', logoSrcDarkTheme]]
33
+ as [theme, src]}
34
+ <img {src}
35
+ alt="{logoAlt}"
36
+ class="qc-{theme}-theme-show"
37
+ />
38
+ {/each}
39
+ </a>
40
+
41
+ <span class="copyright">
42
+ {#if copyrightSlot}
43
+ {@render copyrightSlot()}
44
+ {:else}
45
+ <DefaultCopyright {copyrightText} {copyrightUrl} />
46
+ {/if}
47
+ </span>
48
+ </div>
49
+
50
+ <link rel='stylesheet' href='{Utils.cssPath}'>
51
+