qc-trousse-sdg 1.3.2 → 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.
- package/README.md +5 -1
- package/dist/js/qc-sdg.min.js +1 -1
- package/package.json +3 -3
- package/public/index.html +375 -296
- package/public/js/qc-doc-sdg.js +5043 -1580
- package/public/js/qc-sdg.js +8111 -3685
- package/rollup.config.js +1 -0
- package/src/doc/components/Code.svelte +10 -15
- package/src/doc/components/Exemple.svelte +18 -15
- package/src/doc/components/Switch.svelte +7 -6
- package/src/doc/components/TopNav.svelte +6 -3
- package/src/doc/components/color-doc.svelte +2 -2
- package/src/doc/qc-doc-sdg.js +4 -1
- package/src/sdg/_components.js +10 -9
- package/src/sdg/components/Alert/Alert.svelte +69 -0
- package/src/sdg/components/Alert/AlertWC.svelte +24 -0
- package/src/sdg/components/ExternalLink/ExternalLink.svelte +96 -0
- package/src/sdg/components/ExternalLink/ExternalLinkWC.svelte +15 -0
- package/src/sdg/components/Icon/Icon.svelte +26 -0
- package/src/sdg/components/Icon/IconWC.svelte +20 -0
- package/src/sdg/components/IconButton/IconButton.svelte +30 -0
- package/src/sdg/components/IconButton/IconButtonWC.svelte +19 -0
- package/src/sdg/components/Notice/Notice.svelte +83 -0
- package/src/sdg/components/Notice/NoticeWC.svelte +25 -0
- package/src/sdg/components/PivFooter/PivFooter.svelte +51 -0
- package/src/sdg/components/PivFooter/PivFooterWC.svelte +52 -0
- package/src/sdg/components/PivFooter/_defaultCopyright.svelte +11 -0
- package/src/sdg/components/PivHeader/PivHeader.svelte +144 -0
- package/src/sdg/components/PivHeader/PivHeaderWC.svelte +68 -0
- package/src/sdg/components/PivHeader/_defaultLinks.svelte +24 -0
- package/src/sdg/components/SearchBar/SearchBar.svelte +67 -0
- package/src/sdg/components/SearchBar/SearchBarWC.svelte +17 -0
- package/src/sdg/components/SearchInput/SearchInput.svelte +17 -26
- package/src/sdg/components/SearchInput/SearchInputWC.svelte +16 -0
- package/src/sdg/components/{toTop.svelte → ToTop/ToTop.svelte} +31 -38
- package/src/sdg/components/ToTop/ToTopWC.svelte +16 -0
- package/src/sdg/components/utils.js +1 -1
- package/src/sdg/components/Button/IconButton.svelte +0 -29
- package/src/sdg/components/Icon.svelte +0 -39
- package/src/sdg/components/PivHeader/pivHeader.svelte +0 -158
- package/src/sdg/components/SearchBar/searchBar.svelte +0 -87
- package/src/sdg/components/alert.svelte +0 -88
- package/src/sdg/components/componentWrapper.js +0 -24
- package/src/sdg/components/externalLink.svelte +0 -92
- package/src/sdg/components/notice.svelte +0 -83
- package/src/sdg/components/pivFooter.svelte +0 -65
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
<svelte:options customElement="{{
|
|
2
|
+
tag: 'qc-piv-footer'
|
|
3
|
+
, props: {
|
|
4
|
+
logoUrl : {attribute: 'logo-url'}
|
|
5
|
+
, logoSrc : {attribute: 'logo-src'}
|
|
6
|
+
, logoSrcDarkTheme: {attribute: 'logo-src-dark-theme'}
|
|
7
|
+
, logoAlt : {attribute: 'logo-alt'}
|
|
8
|
+
, logoWidth: {attribute: 'logo-width'}
|
|
9
|
+
, logoHeight: {attribute: 'logo-height'}
|
|
10
|
+
, copyrightText : {attribute: 'copyright-text'}
|
|
11
|
+
, copyrightUrl : {attribute: 'copyright-url'}
|
|
12
|
+
|
|
13
|
+
},
|
|
14
|
+
extend: (customElementConstructor) => {
|
|
15
|
+
return class extends customElementConstructor {
|
|
16
|
+
static self;
|
|
17
|
+
|
|
18
|
+
constructor() {
|
|
19
|
+
super();
|
|
20
|
+
this.self = this;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}}" />
|
|
25
|
+
|
|
26
|
+
<script>
|
|
27
|
+
import { Utils } from "../utils";
|
|
28
|
+
import PivFooter from "./PivFooter.svelte";
|
|
29
|
+
import DefaultCopyright from "./_defaultCopyright.svelte";
|
|
30
|
+
|
|
31
|
+
const lang = Utils.getPageLanguage();
|
|
32
|
+
|
|
33
|
+
let {
|
|
34
|
+
copyrightText,
|
|
35
|
+
copyrightUrl,
|
|
36
|
+
self,
|
|
37
|
+
slots,
|
|
38
|
+
defaultSlot,
|
|
39
|
+
...props
|
|
40
|
+
} = $props();
|
|
41
|
+
$inspect(self,slots,defaultSlot);
|
|
42
|
+
</script>
|
|
43
|
+
<PivFooter {...props} >
|
|
44
|
+
{#snippet mainSlot()}
|
|
45
|
+
<slot />
|
|
46
|
+
{/snippet}
|
|
47
|
+
{#snippet copyrightSlot()}
|
|
48
|
+
<slot name="copyright">
|
|
49
|
+
<DefaultCopyright {copyrightText} {copyrightUrl} />
|
|
50
|
+
</slot>
|
|
51
|
+
{/snippet}
|
|
52
|
+
</PivFooter>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import {Utils} from "../utils";
|
|
3
|
+
const lang = Utils.getPageLanguage();
|
|
4
|
+
const {
|
|
5
|
+
copyrightUrl = lang === 'fr' ? 'https://www.quebec.ca/droit-auteur' : 'https://www.quebec.ca/en/copyright',
|
|
6
|
+
copyrightText = '© Gouvernement du Québec, ' + (new Date()).getFullYear()
|
|
7
|
+
} = $props()
|
|
8
|
+
</script>
|
|
9
|
+
<a href="{copyrightUrl}">
|
|
10
|
+
{copyrightText}
|
|
11
|
+
</a>
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import { onMount, tick } from "svelte";
|
|
3
|
+
import { Utils } from "../utils"
|
|
4
|
+
import DefaultLinks from "./_defaultLinks.svelte"
|
|
5
|
+
|
|
6
|
+
const lang = Utils.getPageLanguage();
|
|
7
|
+
|
|
8
|
+
let {
|
|
9
|
+
self,
|
|
10
|
+
logoUrl = '/',
|
|
11
|
+
fullWidth = 'false',
|
|
12
|
+
logoSrc = Utils.imagesRelativePath + 'QUEBEC_blanc.svg',
|
|
13
|
+
logoAlt = lang === 'fr' ? 'Logo du gouvernement du Québec' : 'Logo of government of Québec',
|
|
14
|
+
titleUrl = '/',
|
|
15
|
+
titleText = '',
|
|
16
|
+
linksLabel,
|
|
17
|
+
altLanguageText,
|
|
18
|
+
altLanguageUrl,
|
|
19
|
+
joinUsText,
|
|
20
|
+
joinUsUrl,
|
|
21
|
+
goToContent = 'true',
|
|
22
|
+
goToContentAnchor = '#main',
|
|
23
|
+
goToContentText = lang === 'fr' ? 'Passer au contenu' : 'Skip to content',
|
|
24
|
+
displaySearchText = lang === 'fr' ? 'Cliquer pour faire une recherche' : 'Click to search',
|
|
25
|
+
hideSearchText = lang === 'fr' ? 'Masquer la barre de recherche' : 'Hide search bar',
|
|
26
|
+
enableSearch = 'false',
|
|
27
|
+
showSearch = 'false',
|
|
28
|
+
links,
|
|
29
|
+
search
|
|
30
|
+
} = $props()
|
|
31
|
+
console.log('PivHeader self', self);
|
|
32
|
+
let containerClass = $state('qc-container')
|
|
33
|
+
, searchZone = $state(null)
|
|
34
|
+
, displaySearchForm = $state(false);
|
|
35
|
+
|
|
36
|
+
// $effect(_ => {
|
|
37
|
+
// if (displaySearchForm) {
|
|
38
|
+
// let input = self
|
|
39
|
+
// ? self.querySelector('[slot="search-zone"] input')
|
|
40
|
+
// : searchZone.querySelector('input')
|
|
41
|
+
// ;
|
|
42
|
+
// input?.focus();
|
|
43
|
+
// }
|
|
44
|
+
// })
|
|
45
|
+
$inspect(self)
|
|
46
|
+
|
|
47
|
+
function focusOnSearchInput() {
|
|
48
|
+
|
|
49
|
+
if (displaySearchForm) {
|
|
50
|
+
|
|
51
|
+
let input = self
|
|
52
|
+
? self.querySelector('[slot="search-zone"] input')
|
|
53
|
+
: searchZone.querySelector('input')
|
|
54
|
+
;
|
|
55
|
+
console.log('focusOnSearchInput', self, searchZone, input );
|
|
56
|
+
input?.focus();
|
|
57
|
+
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
onMount(() => {
|
|
62
|
+
containerClass += fullWidth === 'true' ? '-fluid' : '';
|
|
63
|
+
if (showSearch === 'true') {
|
|
64
|
+
enableSearch = 'true'
|
|
65
|
+
displaySearchForm = true;
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
</script>
|
|
69
|
+
|
|
70
|
+
<div role="banner"
|
|
71
|
+
class="qc-piv-header qc-component"
|
|
72
|
+
style="--logo-src:url({logoSrc})"
|
|
73
|
+
>
|
|
74
|
+
<div class="{containerClass}">
|
|
75
|
+
{#if goToContent === 'true'}
|
|
76
|
+
<div class="go-to-content">
|
|
77
|
+
<a href="{goToContentAnchor}">
|
|
78
|
+
{goToContentText}
|
|
79
|
+
</a>
|
|
80
|
+
</div>
|
|
81
|
+
{/if}
|
|
82
|
+
|
|
83
|
+
<div class="piv-top">
|
|
84
|
+
<div class="signature-group">
|
|
85
|
+
<a href="{logoUrl}"
|
|
86
|
+
class="logo"
|
|
87
|
+
rel="noreferrer"
|
|
88
|
+
aria-label="{logoAlt}"
|
|
89
|
+
>
|
|
90
|
+
<div role="img"></div>
|
|
91
|
+
</a>
|
|
92
|
+
|
|
93
|
+
{#if titleText}
|
|
94
|
+
<div class="title">
|
|
95
|
+
<a href="{titleUrl}"
|
|
96
|
+
class="title">
|
|
97
|
+
{titleText}
|
|
98
|
+
</a>
|
|
99
|
+
</div>
|
|
100
|
+
|
|
101
|
+
{/if}
|
|
102
|
+
</div>
|
|
103
|
+
|
|
104
|
+
<div class="right-section">
|
|
105
|
+
{#if Utils.isTruthy(enableSearch)}
|
|
106
|
+
<a class="qc-search"
|
|
107
|
+
href="/"
|
|
108
|
+
role="button"
|
|
109
|
+
onclick = {(evt) => {
|
|
110
|
+
evt.preventDefault();
|
|
111
|
+
displaySearchForm = !displaySearchForm;
|
|
112
|
+
tick().then(() => {
|
|
113
|
+
focusOnSearchInput()
|
|
114
|
+
});
|
|
115
|
+
}}
|
|
116
|
+
>
|
|
117
|
+
<span>{displaySearchForm ? hideSearchText : displaySearchText}</span>
|
|
118
|
+
</a>
|
|
119
|
+
{/if}
|
|
120
|
+
<div class="links">
|
|
121
|
+
{#if links}
|
|
122
|
+
{@render links()}
|
|
123
|
+
<!-- Le bloc else est present uniquement pour le cas ou PivHeader est utilise sans le wrapper PivHeaderWC.svelte -->
|
|
124
|
+
{:else}
|
|
125
|
+
<DefaultLinks {joinUsUrl}
|
|
126
|
+
{joinUsText}
|
|
127
|
+
{altLanguageUrl}
|
|
128
|
+
{altLanguageText}
|
|
129
|
+
{linksLabel}/>
|
|
130
|
+
{/if}
|
|
131
|
+
</div>
|
|
132
|
+
</div>
|
|
133
|
+
</div>
|
|
134
|
+
|
|
135
|
+
<div class="piv-bottom">
|
|
136
|
+
{#if displaySearchForm}
|
|
137
|
+
<div class="search-zone" bind:this={searchZone}>
|
|
138
|
+
{@render search?.()}
|
|
139
|
+
</div>
|
|
140
|
+
{/if}
|
|
141
|
+
</div>
|
|
142
|
+
</div>
|
|
143
|
+
</div>
|
|
144
|
+
<link rel='stylesheet' href='{Utils.cssPath}'>
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
<svelte:options customElement="{{
|
|
2
|
+
tag: 'qc-piv-header'
|
|
3
|
+
, props: {
|
|
4
|
+
logoUrl : {attribute: 'logo-url'}
|
|
5
|
+
, fullWidth : {attribute: 'full-width'}
|
|
6
|
+
, logoSrc : {attribute: 'logo-src'}
|
|
7
|
+
, logoAlt : {attribute: 'logo-alt'}
|
|
8
|
+
, titleUrl : {attribute: 'title-url'}
|
|
9
|
+
, titleText: {attribute: 'title-text'}
|
|
10
|
+
, linksLabel: {attribute: 'links-label'}
|
|
11
|
+
, altLanguageText: {attribute: 'alt-language-text'}
|
|
12
|
+
, altLanguageUrl: {attribute: 'alt-language-url'}
|
|
13
|
+
, joinUsText: {attribute: 'join-us-text'}
|
|
14
|
+
, joinUsUrl: {attribute: 'join-us-url'}
|
|
15
|
+
, goToContent: {attribute: 'go-to-content'}
|
|
16
|
+
, goToContentAnchor : {attribute: 'go-to-content-anchor'}
|
|
17
|
+
, goToContentText: {attribute: 'go-to-content-text'}
|
|
18
|
+
, displaySearchText : {attribute: 'display-search-text'}
|
|
19
|
+
, hideSearchText : {attribute: 'hide-search-text'}
|
|
20
|
+
, enableSearch : {attribute: 'enable-search'}
|
|
21
|
+
, showSearch : {attribute: 'show-search'}
|
|
22
|
+
},
|
|
23
|
+
extend: (customElementConstructor) => {
|
|
24
|
+
return class extends customElementConstructor {
|
|
25
|
+
static self;
|
|
26
|
+
|
|
27
|
+
constructor() {
|
|
28
|
+
super();
|
|
29
|
+
this.self = this;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}}" />
|
|
34
|
+
|
|
35
|
+
<script>
|
|
36
|
+
import { Utils } from "../utils";
|
|
37
|
+
import PivHeader from "./PivHeader.svelte";
|
|
38
|
+
import DefaultLinks from "./_defaultLinks.svelte";
|
|
39
|
+
|
|
40
|
+
const lang = Utils.getPageLanguage();
|
|
41
|
+
|
|
42
|
+
let {
|
|
43
|
+
self,
|
|
44
|
+
joinUsText,
|
|
45
|
+
joinUsUrl,
|
|
46
|
+
altLanguageText,
|
|
47
|
+
altLanguageUrl,
|
|
48
|
+
linksLabel,
|
|
49
|
+
...props
|
|
50
|
+
} = $props()
|
|
51
|
+
|
|
52
|
+
</script>
|
|
53
|
+
|
|
54
|
+
<PivHeader {self} {...props}>
|
|
55
|
+
{#snippet links()}
|
|
56
|
+
<slot name="links">
|
|
57
|
+
<DefaultLinks {joinUsUrl}
|
|
58
|
+
{joinUsText}
|
|
59
|
+
{altLanguageUrl}
|
|
60
|
+
{altLanguageText}
|
|
61
|
+
{linksLabel}/>
|
|
62
|
+
</slot>
|
|
63
|
+
{/snippet}
|
|
64
|
+
|
|
65
|
+
{#snippet search()}
|
|
66
|
+
<slot name="search-zone" />
|
|
67
|
+
{/snippet}
|
|
68
|
+
</PivHeader>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import {Utils} from "../utils";
|
|
3
|
+
const lang = Utils.getPageLanguage();
|
|
4
|
+
|
|
5
|
+
const {
|
|
6
|
+
joinUsText = lang === 'fr' ? 'Nous joindre' : 'Contact us',
|
|
7
|
+
joinUsUrl = '',
|
|
8
|
+
altLanguageText = lang === 'fr' ? 'English' : 'Français',
|
|
9
|
+
altLanguageUrl = '',
|
|
10
|
+
linksLabel = lang === 'fr' ? 'Navigation PIV' : 'PIV navigation',
|
|
11
|
+
} = $props()
|
|
12
|
+
</script>
|
|
13
|
+
{#if joinUsUrl || altLanguageUrl}
|
|
14
|
+
<nav aria-label="{linksLabel}">
|
|
15
|
+
<ul>
|
|
16
|
+
{#if altLanguageUrl}
|
|
17
|
+
<li><a href="{altLanguageUrl}">{altLanguageText}</a></li>
|
|
18
|
+
{/if}
|
|
19
|
+
{#if joinUsUrl}
|
|
20
|
+
<li><a href="{joinUsUrl}">{joinUsText}</a></li>
|
|
21
|
+
{/if}
|
|
22
|
+
</ul>
|
|
23
|
+
</nav>
|
|
24
|
+
{/if}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import {Utils} from "../utils";
|
|
3
|
+
import SearchInput from "../SearchInput/SearchInput.svelte";
|
|
4
|
+
import IconButton from "../IconButton/IconButton.svelte";
|
|
5
|
+
|
|
6
|
+
const lang = Utils.getPageLanguage();
|
|
7
|
+
|
|
8
|
+
let {
|
|
9
|
+
value = $bindable(''),
|
|
10
|
+
name = 'q',
|
|
11
|
+
pivBackground = false,
|
|
12
|
+
...rest
|
|
13
|
+
} = $props();
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
let defaultsAttributes = {
|
|
17
|
+
input: {
|
|
18
|
+
"placeholder": lang === "fr" ? "Rechercher…" : "Search",
|
|
19
|
+
"aria-label": lang === "fr" ? "Rechercher…" : "Search"
|
|
20
|
+
},
|
|
21
|
+
submit: {
|
|
22
|
+
"aria-label": lang === "fr" ? "Lancer la recherche" : "Submit search"
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
let inputProps = $state({});
|
|
27
|
+
let submitProps = $state({});
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
$effect(() => {
|
|
31
|
+
const [inputAttrs, submitAttrs] = computeFieldsAttributes(rest);
|
|
32
|
+
inputProps = {
|
|
33
|
+
...inputAttrs,
|
|
34
|
+
name,
|
|
35
|
+
};
|
|
36
|
+
submitProps = submitAttrs;
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @param {{[p: string]: T}} restProps
|
|
41
|
+
*/
|
|
42
|
+
function computeFieldsAttributes(restProps) {
|
|
43
|
+
return ["input","submit"].map(control => {
|
|
44
|
+
const prefix = `${control}-`;
|
|
45
|
+
return {
|
|
46
|
+
...defaultsAttributes[control],
|
|
47
|
+
...Object.fromEntries(
|
|
48
|
+
Object.entries(restProps)
|
|
49
|
+
.map(([k,v]) => k.startsWith(prefix) ? [k.replace(prefix, ''),v] : null)
|
|
50
|
+
.filter(Boolean) // élimine les éléments null
|
|
51
|
+
)
|
|
52
|
+
};
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
</script>
|
|
58
|
+
<div class="qc-search-bar" class:piv-background={pivBackground}>
|
|
59
|
+
<SearchInput bind:value {...inputProps}/>
|
|
60
|
+
<IconButton
|
|
61
|
+
type="submit"
|
|
62
|
+
iconColor={pivBackground ? 'blue-piv' : 'background'}
|
|
63
|
+
icon="loupe-piv-fine"
|
|
64
|
+
iconSize="md"
|
|
65
|
+
{...submitProps}
|
|
66
|
+
/>
|
|
67
|
+
</div>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<svelte:options customElement="{{
|
|
2
|
+
tag: 'qc-search-bar',
|
|
3
|
+
shadow: 'none',
|
|
4
|
+
props: {
|
|
5
|
+
value: {attribute: 'input-value', type:'String'},
|
|
6
|
+
name: {attribute: 'input-name', type:'String'},
|
|
7
|
+
pivBackground: {attribute: 'piv-background', type:'Boolean'},
|
|
8
|
+
}
|
|
9
|
+
}}" />
|
|
10
|
+
|
|
11
|
+
<script>
|
|
12
|
+
import SearchBar from "./SearchBar.svelte";
|
|
13
|
+
|
|
14
|
+
const props = $props();
|
|
15
|
+
</script>
|
|
16
|
+
|
|
17
|
+
<SearchBar {...props} />
|
|
@@ -1,36 +1,27 @@
|
|
|
1
|
-
<svelte:options customElement="{{
|
|
2
|
-
tag: 'qc-search-input',
|
|
3
|
-
shadow: 'none',
|
|
4
|
-
props: {
|
|
5
|
-
ariaLabel: {attribute:'aria-label'},
|
|
6
|
-
clearAriaLabel: {attribute: 'clear-aria-label'}
|
|
7
|
-
}
|
|
8
|
-
}}" />
|
|
9
1
|
<script>
|
|
10
|
-
import IconButton from "../
|
|
2
|
+
import IconButton from "../IconButton/IconButton.svelte";
|
|
11
3
|
import {Utils} from "../utils";
|
|
12
|
-
const
|
|
13
|
-
lang = Utils.getPageLanguage();
|
|
14
4
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
;
|
|
24
|
-
let searchInput;
|
|
5
|
+
const lang = Utils.getPageLanguage();
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
let {
|
|
9
|
+
value = $bindable(''),
|
|
10
|
+
ariaLabel = lang === "fr" ? "Rechercher…" : "Search_",
|
|
11
|
+
clearAriaLabel = lang === "fr" ? "Effacer le texte" : "Clear text",
|
|
12
|
+
...rest
|
|
13
|
+
} = $props();
|
|
25
14
|
|
|
15
|
+
let searchInput;
|
|
26
16
|
</script>
|
|
17
|
+
|
|
27
18
|
<div class="qc-search-input">
|
|
28
19
|
<input bind:this={searchInput}
|
|
29
|
-
bind:value
|
|
20
|
+
bind:value={value}
|
|
30
21
|
type="search"
|
|
31
22
|
autocomplete="off"
|
|
32
|
-
|
|
33
|
-
{
|
|
23
|
+
aria-label={ariaLabel}
|
|
24
|
+
{...rest}
|
|
34
25
|
/>
|
|
35
26
|
{#if value}
|
|
36
27
|
<IconButton type="button"
|
|
@@ -38,10 +29,10 @@
|
|
|
38
29
|
iconColor="blue-piv"
|
|
39
30
|
iconSize="sm"
|
|
40
31
|
aria-label={clearAriaLabel}
|
|
41
|
-
|
|
32
|
+
onclick={(e) => {
|
|
42
33
|
e.preventDefault();
|
|
43
34
|
value = "";
|
|
44
|
-
searchInput
|
|
35
|
+
searchInput?.focus();
|
|
45
36
|
}}
|
|
46
37
|
/>
|
|
47
38
|
{/if}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<svelte:options customElement="{{
|
|
2
|
+
tag: 'qc-search-input',
|
|
3
|
+
shadow: 'none',
|
|
4
|
+
props: {
|
|
5
|
+
ariaLabel: {attribute:'aria-label'},
|
|
6
|
+
clearAriaLabel: {attribute: 'clear-aria-label'}
|
|
7
|
+
}
|
|
8
|
+
}}" />
|
|
9
|
+
|
|
10
|
+
<script>
|
|
11
|
+
import SearchInput from "./SearchInput.svelte";
|
|
12
|
+
|
|
13
|
+
const props = $props();
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<SearchInput {...props} />
|
|
@@ -1,44 +1,32 @@
|
|
|
1
|
-
<svelte:options customElement="{{
|
|
2
|
-
tag: 'qc-to-top',
|
|
3
|
-
shadow: 'none',
|
|
4
|
-
props: {
|
|
5
|
-
text: {attribute: 'text', type:'String'},
|
|
6
|
-
}
|
|
7
|
-
}}" />
|
|
8
|
-
|
|
9
|
-
|
|
10
1
|
<script>
|
|
11
|
-
import { Utils } from "
|
|
12
|
-
import Icon from "
|
|
2
|
+
import { Utils } from "../utils";
|
|
3
|
+
import Icon from "../Icon/Icon.svelte";
|
|
4
|
+
import {setContext} from "svelte";
|
|
13
5
|
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
: "Back to top"
|
|
20
|
-
, demo = 'false'
|
|
21
|
-
;
|
|
22
|
-
let
|
|
23
|
-
minimumScrollHeight = 0
|
|
24
|
-
, src = `${Utils.imagesRelativePath}arrow-up-white.svg`
|
|
25
|
-
, lastScrollY = 0
|
|
26
|
-
, visible = demo === 'true'
|
|
27
|
-
, lastVisible = visible
|
|
28
|
-
, toTopElement
|
|
29
|
-
;
|
|
6
|
+
const lang = Utils.getPageLanguage();
|
|
7
|
+
const {
|
|
8
|
+
text = lang === 'fr' ? "Retour en haut" : "Back to top",
|
|
9
|
+
demo = 'false'
|
|
10
|
+
} = $props();
|
|
30
11
|
|
|
12
|
+
let visible = $state(demo === 'true');
|
|
13
|
+
let lastVisible = setContext('visible', () => visible);
|
|
14
|
+
let lastScrollY = 0;
|
|
15
|
+
let minimumScrollHeight = 0;
|
|
16
|
+
let toTopElement;
|
|
31
17
|
|
|
18
|
+
const src = `${Utils.imagesRelativePath}arrow-up-white.svg`;
|
|
32
19
|
|
|
33
20
|
function handleScrollUpButton() {
|
|
34
|
-
if (demo
|
|
35
|
-
return
|
|
21
|
+
if (Utils.isTruthy(demo)) {
|
|
22
|
+
return;
|
|
36
23
|
}
|
|
37
|
-
|
|
24
|
+
|
|
25
|
+
const pageBottom =
|
|
38
26
|
( window.innerHeight + window.scrollY )
|
|
39
27
|
>=
|
|
40
|
-
( document.body.offsetHeight - 1 )
|
|
41
|
-
|
|
28
|
+
( document.body.offsetHeight - 1 );
|
|
29
|
+
|
|
42
30
|
visible =
|
|
43
31
|
lastScrollY > window.scrollY
|
|
44
32
|
&& ( document.body.scrollTop > minimumScrollHeight
|
|
@@ -53,11 +41,12 @@
|
|
|
53
41
|
lastScrollY = window.scrollY;
|
|
54
42
|
}
|
|
55
43
|
|
|
56
|
-
function scrollToTop() {
|
|
57
|
-
|
|
44
|
+
function scrollToTop(e) {
|
|
45
|
+
e.preventDefault()
|
|
46
|
+
window.scrollTo({
|
|
58
47
|
top: 0,
|
|
59
48
|
behavior: 'smooth'
|
|
60
|
-
|
|
49
|
+
});
|
|
61
50
|
}
|
|
62
51
|
|
|
63
52
|
function handleEnterAndSpace(e) {
|
|
@@ -69,16 +58,20 @@
|
|
|
69
58
|
}
|
|
70
59
|
}
|
|
71
60
|
|
|
61
|
+
$effect(() => {
|
|
62
|
+
lastScrollY = window.scrollY;
|
|
63
|
+
});
|
|
64
|
+
|
|
72
65
|
</script>
|
|
73
66
|
|
|
74
67
|
<svelte:window on:scroll = {handleScrollUpButton} />
|
|
75
68
|
|
|
76
|
-
<a href="
|
|
69
|
+
<a href="#top"
|
|
77
70
|
bind:this={toTopElement}
|
|
78
71
|
class="qc-to-top"
|
|
79
72
|
class:visible
|
|
80
|
-
|
|
81
|
-
|
|
73
|
+
onclick={(e) => scrollToTop(e)}
|
|
74
|
+
onkeydown={handleEnterAndSpace}
|
|
82
75
|
tabindex={visible ? 0 : -1}
|
|
83
76
|
{demo}
|
|
84
77
|
>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<svelte:options customElement={{
|
|
2
|
+
tag: 'qc-to-top',
|
|
3
|
+
shadow: 'none',
|
|
4
|
+
props: {
|
|
5
|
+
text: { attribute: 'text', type: 'String' },
|
|
6
|
+
demo: { attribute: 'demo', type: 'String' }
|
|
7
|
+
}
|
|
8
|
+
}} />
|
|
9
|
+
|
|
10
|
+
<script>
|
|
11
|
+
import ToTop from "./ToTop.svelte";
|
|
12
|
+
|
|
13
|
+
const props = $props();
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<ToTop {...props} />
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import Icon from "../Icon.svelte";
|
|
3
|
-
|
|
4
|
-
export let
|
|
5
|
-
size = 'xl',
|
|
6
|
-
label,
|
|
7
|
-
icon,
|
|
8
|
-
iconSize,
|
|
9
|
-
iconColor
|
|
10
|
-
;
|
|
11
|
-
|
|
12
|
-
</script>
|
|
13
|
-
|
|
14
|
-
<button on:click
|
|
15
|
-
data-button-size={size}
|
|
16
|
-
{...$$restProps}
|
|
17
|
-
class="qc-icon-button {$$restProps.class ?? ''}"
|
|
18
|
-
|
|
19
|
-
>
|
|
20
|
-
{#if icon}
|
|
21
|
-
<Icon type="{icon}"
|
|
22
|
-
size={iconSize}
|
|
23
|
-
color={iconColor}
|
|
24
|
-
aria-hidden="true"
|
|
25
|
-
label={label}
|
|
26
|
-
/>
|
|
27
|
-
{/if}
|
|
28
|
-
</button>
|
|
29
|
-
|
|
@@ -1,39 +0,0 @@
|
|
|
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
|
-
<script>
|
|
14
|
-
export let
|
|
15
|
-
type,
|
|
16
|
-
label,
|
|
17
|
-
size='md',
|
|
18
|
-
color = 'text-primary',
|
|
19
|
-
width='auto',
|
|
20
|
-
height='auto'
|
|
21
|
-
;
|
|
22
|
-
$: attributes = width === "auto"
|
|
23
|
-
? {
|
|
24
|
-
"data-img-size":size,
|
|
25
|
-
}
|
|
26
|
-
: {}
|
|
27
|
-
</script>
|
|
28
|
-
<div role="img"
|
|
29
|
-
class="qc-icon"
|
|
30
|
-
aria-label={label}
|
|
31
|
-
style="--img-color:var(--qc-color-{color});
|
|
32
|
-
--img-width:{width};
|
|
33
|
-
--img-height:{height};
|
|
34
|
-
"
|
|
35
|
-
data-img-type={type}
|
|
36
|
-
{...attributes}
|
|
37
|
-
{...$$restProps}
|
|
38
|
-
>
|
|
39
|
-
</div>
|