qc-trousse-sdg 1.4.0-develop.0 → 1.4.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 (292) hide show
  1. package/README.md +22 -5
  2. package/dist/css/qc-sdg-design-tokens.min.css +1 -1
  3. package/dist/css/qc-sdg-no-grid.min.css +1 -1
  4. package/dist/css/qc-sdg.min.css +1 -1
  5. package/dist/fonts/open-sans-v43-latin-500.woff2 +0 -0
  6. package/dist/fonts/open-sans-v43-latin-500italic.woff2 +0 -0
  7. package/dist/fonts/open-sans-v43-latin-600.woff2 +0 -0
  8. package/dist/fonts/open-sans-v43-latin-600italic.woff2 +0 -0
  9. package/dist/fonts/open-sans-v43-latin-700.woff2 +0 -0
  10. package/dist/fonts/open-sans-v43-latin-700italic.woff2 +0 -0
  11. package/dist/fonts/open-sans-v43-latin-italic.woff2 +0 -0
  12. package/dist/fonts/open-sans-v43-latin-regular.woff2 +0 -0
  13. package/dist/fonts/roboto-mono-v30-latin-500.woff2 +0 -0
  14. package/dist/fonts/roboto-mono-v30-latin-500italic.woff2 +0 -0
  15. package/dist/fonts/roboto-mono-v30-latin-600.woff2 +0 -0
  16. package/dist/fonts/roboto-mono-v30-latin-600italic.woff2 +0 -0
  17. package/dist/fonts/roboto-mono-v30-latin-700.woff2 +0 -0
  18. package/dist/fonts/roboto-mono-v30-latin-700italic.woff2 +0 -0
  19. package/dist/fonts/roboto-mono-v30-latin-italic.woff2 +0 -0
  20. package/dist/fonts/roboto-mono-v30-latin-regular.woff2 +0 -0
  21. package/dist/fonts/roboto-v48-latin-500.woff2 +0 -0
  22. package/dist/fonts/roboto-v48-latin-500italic.woff2 +0 -0
  23. package/dist/fonts/roboto-v48-latin-600.woff2 +0 -0
  24. package/dist/fonts/roboto-v48-latin-600italic.woff2 +0 -0
  25. package/dist/fonts/roboto-v48-latin-700.woff2 +0 -0
  26. package/dist/fonts/roboto-v48-latin-700italic.woff2 +0 -0
  27. package/dist/fonts/roboto-v48-latin-italic.woff2 +0 -0
  28. package/dist/fonts/roboto-v48-latin-regular.woff2 +0 -0
  29. package/dist/img/icon/adresse.svg +4 -0
  30. package/dist/img/icon/arrow-up.svg +3 -0
  31. package/dist/img/icon/calendar.svg +1 -0
  32. package/dist/img/icon/checkmark.svg +3 -0
  33. package/dist/img/icon/chevron-up-thin.svg +5 -0
  34. package/dist/img/{chevron-white.svg → icon/chevron-up.svg} +1 -1
  35. package/{public/img → dist/img/icon}/clipboard.svg +3 -3
  36. package/dist/img/icon/clock.svg +1 -0
  37. package/dist/img/icon/email.svg +1 -0
  38. package/dist/img/icon/error.svg +1 -0
  39. package/{public/img/exclamation-white.svg → dist/img/icon/exclamation.svg} +2 -2
  40. package/{public/img → dist/img/icon}/external-link.svg +2 -2
  41. package/dist/img/icon/information.svg +1 -0
  42. package/dist/img/icon/ligth-bulb.svg +1 -0
  43. package/{public/img → dist/img/icon}/minus.svg +1 -1
  44. package/dist/img/icon/note.svg +1 -0
  45. package/dist/img/icon/phone.svg +1 -0
  46. package/dist/img/{plus.svg → icon/plus.svg} +1 -1
  47. package/{public/img → dist/img/icon}/question-mark.svg +2 -2
  48. package/dist/img/icon/search-thin.svg +10 -0
  49. package/dist/img/icon/search.svg +1 -0
  50. package/dist/img/icon/success.svg +1 -0
  51. package/dist/img/icon/user.svg +6 -0
  52. package/dist/img/icon/warning.svg +1 -0
  53. package/dist/img/icon/website.svg +1 -0
  54. package/dist/img/icon/xclose.svg +1 -0
  55. package/dist/js/qc-sdg.min.js +1 -1
  56. package/package.json +11 -3
  57. package/playwright.config.ts +79 -0
  58. package/plugins/buildDevDoc.js +36 -0
  59. package/plugins/buildHtmlDoc.js +43 -0
  60. package/plugins/buildTestFixtures.js +37 -0
  61. package/public/css/qc-doc-sdg.css +4 -67
  62. package/public/css/qc-sdg-design-tokens.css +17 -0
  63. package/public/css/qc-sdg-no-grid.css +2001 -1108
  64. package/public/css/qc-sdg.css +1999 -1106
  65. package/public/img/checkmark.svg +3 -0
  66. package/public/img/question.svg +10 -0
  67. package/public/index.html +3104 -1387
  68. package/public/js/qc-doc-sdg.js +5705 -285
  69. package/public/js/qc-sdg.js +5660 -1415
  70. package/rollup.config.js +67 -41
  71. package/scripts/buildImagesMap.js +85 -0
  72. package/scripts/check-release-note.sh +11 -0
  73. package/scripts/compile-doc.sh +4 -0
  74. package/src/doc/_index.html +100 -0
  75. package/src/doc/_nav.html +53 -0
  76. package/src/doc/_test.html +32 -0
  77. package/src/doc/components/Code.svelte +6 -2
  78. package/src/doc/components/TopNav.svelte +8 -9
  79. package/src/doc/components/color-doc.svelte +1 -1
  80. package/src/doc/ejs/layout/index.ejs +129 -0
  81. package/src/doc/qc-doc-sdg.js +1 -2
  82. package/src/doc/scss/components/_code.scss +1 -1
  83. package/src/doc/scss/jQueryUI/_jquery-ui.autocomplete.scss +1 -0
  84. package/src/doc/scss/qc-doc-sdg.scss +1 -1
  85. package/src/doc/scss/settings/_base.scss +4 -0
  86. package/src/sdg/_components.js +9 -2
  87. package/src/sdg/{components → bases}/Icon/Icon.svelte +13 -6
  88. package/src/sdg/bases/Icon/IconDoc.ejs +129 -0
  89. package/src/sdg/{components → bases}/Icon/IconWC.svelte +3 -1
  90. package/src/sdg/bases/Icon/Test/IconEmbeddedTest.html +1 -0
  91. package/src/sdg/bases/Icon/Test/IconEmbeddedTest.svelte +168 -0
  92. package/src/sdg/bases/Icon/Test/iconTest.html +156 -0
  93. package/src/sdg/bases/Icon/_icon.html +254 -0
  94. package/src/sdg/bases/Icon/_icons.scss +47 -0
  95. package/src/sdg/{scss/base → bases/accessibility}/_accessibility.scss +1 -1
  96. package/src/sdg/bases/colors/_colors.html +112 -0
  97. package/src/sdg/bases/figures/_figure.html +16 -0
  98. package/src/sdg/{scss/base → bases/form}/_form.scss +10 -3
  99. package/src/sdg/bases/grid/_grid.html +118 -0
  100. package/src/sdg/bases/headings/_headings.html +18 -0
  101. package/src/sdg/bases/headings/_headings.scss +25 -0
  102. package/src/sdg/{scss/base → bases/layout}/_layout.scss +1 -4
  103. package/src/sdg/bases/links/_links.html +104 -0
  104. package/src/sdg/bases/links/_links.scss +51 -0
  105. package/src/sdg/bases/lists/_lists.html +27 -0
  106. package/src/sdg/bases/separator/_separator.html +7 -0
  107. package/src/sdg/bases/separator/_separator.scss +5 -0
  108. package/src/sdg/bases/shadings/_shadings.html +14 -0
  109. package/src/sdg/{scss/base → bases/shadings}/_shadings.scss +1 -1
  110. package/src/sdg/bases/typography/_font.html +45 -0
  111. package/src/sdg/bases/typography/_fonts.scss +162 -0
  112. package/src/sdg/bases/typography/_paragraph.html +17 -0
  113. package/src/sdg/bases/typography/_paragraph.scss +33 -0
  114. package/src/sdg/components/Alert/Alert.svelte +2 -5
  115. package/src/sdg/components/Alert/AlertWC.svelte +3 -2
  116. package/src/sdg/components/Alert/_alert.html +110 -0
  117. package/src/sdg/{scss/components → components/Alert}/_alert.scss +1 -1
  118. package/src/sdg/components/Button/Button.svelte +50 -0
  119. package/src/sdg/components/Button/ButtonWC.svelte +36 -0
  120. package/src/sdg/components/Button/Test/buttonTest.html +349 -0
  121. package/src/sdg/components/Button/_button.html +186 -0
  122. package/src/sdg/components/Button/_button.scss +202 -0
  123. package/src/sdg/components/CharCount/_charCount.html +7 -0
  124. package/src/sdg/components/Checkbox/Checkbox.svelte +77 -0
  125. package/src/sdg/components/Checkbox/CheckboxWC.svelte +49 -0
  126. package/src/sdg/components/Checkbox/_checkbox.html +86 -0
  127. package/src/sdg/components/Checkbox/_checkbox.scss +70 -0
  128. package/src/sdg/components/Checkbox/updateInput.svelte.js +23 -0
  129. package/src/sdg/components/ChoiceGroup/ChoiceGroup.svelte +56 -0
  130. package/src/sdg/components/ChoiceGroup/ChoiceGroupWC.svelte +47 -0
  131. package/src/sdg/components/ChoiceGroup/Test/ChoiceGroupeEmbededTest.svelte +261 -0
  132. package/src/sdg/components/ChoiceGroup/Test/checkboxEmbeddedTest.html +1 -0
  133. package/src/sdg/components/ChoiceGroup/Test/checkboxTest.html +253 -0
  134. package/src/sdg/components/ChoiceGroup/Test/radiosEmbeddedTest.html +1 -0
  135. package/src/sdg/components/ChoiceGroup/Test/radiosTest.html +185 -0
  136. package/src/sdg/components/ChoiceGroup/ToggleSwitchGroupWC.svelte +56 -0
  137. package/src/sdg/components/ChoiceGroup/_choiceGroup.html +285 -0
  138. package/src/sdg/components/ChoiceGroup/_choiceGroup.scss +32 -0
  139. package/src/sdg/components/ChoiceGroup/_selectionButton.scss +53 -0
  140. package/src/sdg/components/ChoiceGroup/_selectionButtons.html +130 -0
  141. package/src/sdg/components/DropdownList/DropdownList.svelte +394 -0
  142. package/src/sdg/components/DropdownList/DropdownListButton/DropdownListButton.svelte +43 -0
  143. package/src/sdg/components/DropdownList/DropdownListButton/_dropdownListButton.scss +65 -0
  144. package/src/sdg/components/DropdownList/DropdownListItems/DropdownListItems.svelte +110 -0
  145. package/src/sdg/components/DropdownList/DropdownListItems/DropdownListItemsMultiple/DropdownListItemsMultiple.svelte +185 -0
  146. package/src/sdg/components/DropdownList/DropdownListItems/DropdownListItemsMultiple/_dropdownListItemsMultiple.scss +19 -0
  147. package/src/sdg/components/DropdownList/DropdownListItems/DropdownListItemsSingle/DropdownListItemsSingle.svelte +136 -0
  148. package/src/sdg/components/DropdownList/DropdownListItems/DropdownListItemsSingle/_dropdownListItemsSingle.scss +11 -0
  149. package/src/sdg/components/DropdownList/DropdownListItems/_dropdownListItems.scss +67 -0
  150. package/src/sdg/components/DropdownList/SelectWC.svelte +158 -0
  151. package/src/sdg/components/DropdownList/Test/DropdownListEmbeddedTest.svelte +89 -0
  152. package/src/sdg/components/DropdownList/Test/dropdownListEmbeddedTest.html +1 -0
  153. package/src/sdg/components/DropdownList/Test/dropdownListTest.html +194 -0
  154. package/src/sdg/components/DropdownList/Test/dropdownListTestUtils.js +113 -0
  155. package/src/sdg/components/DropdownList/_dropdownList.scss +73 -0
  156. package/src/sdg/components/DropdownList/_select.html +212 -0
  157. package/src/sdg/components/ExternalLink/ExternalLink.svelte +1 -1
  158. package/src/sdg/components/Fieldset/Fieldset.svelte +73 -0
  159. package/src/sdg/components/Fieldset/_fieldset.scss +95 -0
  160. package/src/sdg/components/FormError/FormError.svelte +51 -0
  161. package/src/sdg/components/FormError/_formError.scss +21 -0
  162. package/src/sdg/components/FormfieldRow/_formfieldRow.html +108 -0
  163. package/src/sdg/components/IconButton/IconButton.svelte +1 -1
  164. package/src/sdg/components/IconButton/_iconButton.scss +14 -0
  165. package/src/sdg/components/Label/Label.svelte +28 -0
  166. package/src/sdg/components/Label/LabelText.svelte +4 -0
  167. package/src/sdg/components/Label/_label.scss +19 -0
  168. package/src/sdg/components/Notice/Notice.svelte +1 -2
  169. package/src/sdg/components/Notice/NoticeWC.svelte +3 -0
  170. package/src/sdg/components/Notice/_notice.html +141 -0
  171. package/src/sdg/{scss/components → components/Notice}/_notice.scss +1 -1
  172. package/src/sdg/components/PivFooter/PivFooter.svelte +8 -9
  173. package/src/sdg/components/PivFooter/PivFooterWC.svelte +6 -14
  174. package/src/sdg/components/PivFooter/_pivFooter.html +153 -0
  175. package/src/sdg/{scss/components → components/PivFooter}/_pivFooter.scss +1 -1
  176. package/src/sdg/components/PivHeader/PivHeader.svelte +47 -53
  177. package/src/sdg/components/PivHeader/PivHeaderWC.svelte +9 -20
  178. package/src/sdg/components/PivHeader/Test/pivHeaderEmbeddedTest.html +1 -0
  179. package/src/sdg/components/PivHeader/Test/pivHeaderEmbeddedTest.svelte +28 -0
  180. package/src/sdg/components/PivHeader/Test/pivHeaderTest.html +43 -0
  181. package/src/sdg/components/PivHeader/_pivHeader.html +221 -0
  182. package/src/sdg/{scss/components → components/PivHeader}/_pivHeader.scss +55 -77
  183. package/src/sdg/components/RadioButton/_radioButton.html +24 -0
  184. package/src/sdg/components/RadioButton/_radioButton.scss +29 -0
  185. package/src/sdg/components/SearchBar/SearchBar.svelte +12 -32
  186. package/src/sdg/components/SearchBar/_searchBar.html +125 -0
  187. package/src/sdg/{scss/components → components/SearchBar}/_searchBar.scss +3 -3
  188. package/src/sdg/components/SearchInput/SearchInput.svelte +26 -4
  189. package/src/sdg/components/SearchInput/SearchInputWC.svelte +3 -1
  190. package/src/sdg/components/SearchInput/_searchInput.html +85 -0
  191. package/src/sdg/{scss/components → components/SearchInput}/_searchInput.scss +27 -2
  192. package/src/sdg/components/TextField/Doc/TextFieldDemo.svelte +143 -0
  193. package/src/sdg/components/TextField/Test/TextFieldEmbededTest.svelte +129 -0
  194. package/src/sdg/components/TextField/Test/textFieldEmbeddedTest.html +1 -0
  195. package/src/sdg/components/TextField/Test/textFieldTest.html +121 -0
  196. package/src/sdg/components/TextField/TextField.svelte +171 -0
  197. package/src/sdg/components/TextField/TextFieldWC.svelte +90 -0
  198. package/src/sdg/components/TextField/_textField.html +218 -0
  199. package/src/sdg/components/TextField/_textField.scss +110 -0
  200. package/src/sdg/components/TextField/textFieldUtils.js +19 -0
  201. package/src/sdg/components/ToTop/ToTop.svelte +2 -4
  202. package/src/sdg/components/ToTop/_toTop.html +45 -0
  203. package/src/sdg/{scss/components → components/ToTop}/_toTop.scss +2 -2
  204. package/src/sdg/components/ToggleSwitch/Test/ToggleSwitchEmbeddedTest.svelte +46 -0
  205. package/src/sdg/components/ToggleSwitch/Test/toggleSwitchEmbeddedTest.html +1 -0
  206. package/src/sdg/components/ToggleSwitch/Test/toggleSwitchTest.html +34 -0
  207. package/src/sdg/components/ToggleSwitch/ToggleSwitch.svelte +34 -0
  208. package/src/sdg/components/ToggleSwitch/ToggleSwitchWC.svelte +66 -0
  209. package/src/sdg/components/ToggleSwitch/_toggleSwitch.html +160 -0
  210. package/src/sdg/components/ToggleSwitch/_toggleSwitch.scss +97 -0
  211. package/src/sdg/components/utils.js +81 -1
  212. package/src/sdg/qc-sdg-test.js +6 -0
  213. package/src/sdg/scss/lib/_functions.scss +10 -2
  214. package/src/sdg/scss/lib/_mixins.scss +63 -26
  215. package/src/sdg/scss/qc-sdg.scss +1 -1
  216. package/src/sdg/scss/qc-sgd-no-grid.scss +30 -18
  217. package/src/sdg/scss/settings/_base.scss +5 -33
  218. package/src/sdg/scss/settings/_images.scss +30 -0
  219. package/src/sdg/scss/settings/_tokens.scss +23 -0
  220. package/src/sdg/scss/utilities/_display.scss +1 -1
  221. package/src/sdg/scss/utilities/_states.scss +13 -0
  222. package/tests/button.spec.ts +11 -0
  223. package/tests/choice-group.spec.ts +36 -0
  224. package/tests/dropdown-list.spec.ts +529 -0
  225. package/tests/icon.spec.ts +19 -0
  226. package/tests/pivHeader.spec.ts +22 -0
  227. package/tests/textfield.spec.ts +21 -0
  228. package/tests/toggle-switch.spec.ts +20 -0
  229. package/dist/img/arrow-up-white.svg +0 -3
  230. package/dist/img/chevron-blue.svg +0 -3
  231. package/dist/img/clipboard.svg +0 -8
  232. package/dist/img/error-white.svg +0 -1
  233. package/dist/img/error.svg +0 -1
  234. package/dist/img/exclamation-white.svg +0 -37
  235. package/dist/img/external-link-white.svg +0 -18
  236. package/dist/img/external-link.svg +0 -10
  237. package/dist/img/facebook.svg +0 -6
  238. package/dist/img/information-white.svg +0 -1
  239. package/dist/img/information.svg +0 -1
  240. package/dist/img/linkedin.svg +0 -5
  241. package/dist/img/loupe-piv-fonce.svg +0 -1
  242. package/dist/img/minus.svg +0 -6
  243. package/dist/img/qc-sprite.svg +0 -1
  244. package/dist/img/question-mark.svg +0 -47
  245. package/dist/img/success-white.svg +0 -1
  246. package/dist/img/success.svg +0 -1
  247. package/dist/img/twitter.svg +0 -8
  248. package/dist/img/warning.svg +0 -1
  249. package/dist/img/xclose-blue.svg +0 -6
  250. package/dist/img/xclose-white.svg +0 -1
  251. package/dist/img/youtube.svg +0 -3
  252. package/public/img/ampoule.svg +0 -1
  253. package/public/img/arrow-up-white.svg +0 -3
  254. package/public/img/chevron-blue.svg +0 -3
  255. package/public/img/chevron-white.svg +0 -3
  256. package/public/img/error-white.svg +0 -1
  257. package/public/img/error.svg +0 -1
  258. package/public/img/external-link-white.svg +0 -18
  259. package/public/img/facebook.svg +0 -6
  260. package/public/img/information-white.svg +0 -1
  261. package/public/img/information.svg +0 -1
  262. package/public/img/linkedin.svg +0 -5
  263. package/public/img/logo-piv-footer-mess.png +0 -0
  264. package/public/img/loupe-piv-droite.svg +0 -1
  265. package/public/img/loupe-piv-fonce.svg +0 -1
  266. package/public/img/note.svg +0 -1
  267. package/public/img/piv-bas-MCE-theme-clair.png +0 -0
  268. package/public/img/piv-bas-MCE-theme-sombre.png +0 -0
  269. package/public/img/piv-logo-pied-de-page.svg +0 -37
  270. package/public/img/plus.svg +0 -6
  271. package/public/img/qc-sprite.svg +0 -1
  272. package/public/img/quebec-logo.svg +0 -13
  273. package/public/img/success-white.svg +0 -1
  274. package/public/img/success.svg +0 -1
  275. package/public/img/twitter.svg +0 -8
  276. package/public/img/warning.svg +0 -1
  277. package/public/img/xclose-blue.svg +0 -6
  278. package/public/img/xclose-white.svg +0 -1
  279. package/public/img/youtube.svg +0 -3
  280. package/src/doc/scss/components/_button.scss +0 -61
  281. package/src/sdg/components/PivFooter/_defaultCopyright.svelte +0 -11
  282. package/src/sdg/components/PivHeader/_defaultLinks.svelte +0 -24
  283. package/src/sdg/scss/base/_fonts.scss +0 -29
  284. package/src/sdg/scss/base/_typography.scss +0 -94
  285. package/src/sdg/scss/components/_icons.scss +0 -169
  286. package/src/sdg/scss/components/_separator.scss +0 -5
  287. /package/dist/img/{loupe-piv-droite.svg → piv-search.svg} +0 -0
  288. /package/src/sdg/{scss/base → bases/colors}/_colors.scss +0 -0
  289. /package/src/sdg/{scss/base → bases/figures}/_figure.scss +0 -0
  290. /package/src/sdg/{scss → bases}/grid/_grid-lib.scss +0 -0
  291. /package/src/sdg/{scss → bases}/grid/_grid.scss +0 -0
  292. /package/src/sdg/{scss/base → bases/lists}/_lists.scss +0 -0
@@ -0,0 +1,130 @@
1
+ <h4 id="selection-button">Boutons de sélection</h4>
2
+
3
+ <h5>Exemples</h5>
4
+ <qc-doc-exemple caption="Exemple de boutons radio sous forme de boutons de sélection avec différents états.">
5
+ <qc-choice-group legend="Sélectionnez une option :"
6
+ name="ex-radio-select"
7
+ selection-button
8
+ column-count="2"
9
+ >
10
+ <label>
11
+ <input type="radio"
12
+ value="1"
13
+ checked
14
+ />
15
+ <span class="qc-tile">
16
+ <span class="qc-tile-text">Option 1</span>
17
+ <span class="qc-tile-description">Ceci est une <b>longue</b> description servant à montrer l'affichage des boutons de sélection.</span>
18
+ </span>
19
+ </label>
20
+
21
+ <label>
22
+ <input type="radio"
23
+ value="2"
24
+ />
25
+ <span class="qc-tile">
26
+ <span class="qc-tile-text">Option 2</span>
27
+ </span>
28
+ </label>
29
+ <label>
30
+ <input type="radio"
31
+ value="3"
32
+ disabled
33
+ />
34
+ <span class="qc-tile">
35
+ <span class="qc-tile-text">Option 3 (désactivée)</span>
36
+ </span>
37
+ </label>
38
+ </qc-choice-group>
39
+ </qc-doc-exemple>
40
+
41
+ <qc-doc-exemple
42
+ caption="Exemple d’un groupe de cases à cocher sous forme de boutons de sélection avec différents états."
43
+ >
44
+ <qc-choice-group
45
+ name="exemple-checkbox-select"
46
+ legend="Sélectionnez vos options"
47
+ selection-button
48
+ column-count="2">
49
+ <label>
50
+ <input type="checkbox"
51
+ value="1"
52
+ checked
53
+ />
54
+ <span class="qc-tile">
55
+ <span class="qc-tile-text">Option 1</span>
56
+ <span class="qc-tile-description">Ceci est une <b>longue</b> description servant à montrer l'affichage des boutons de sélection.</span>
57
+ </span>
58
+ </label>
59
+
60
+ <label>
61
+ <input type="checkbox"
62
+ value="2"
63
+ />
64
+ <span class="qc-tile">
65
+ <span class="qc-tile-text">Option 2</span>
66
+ </span>
67
+ </label>
68
+ <label>
69
+ <input type="checkbox"
70
+ value="3"
71
+ disabled
72
+ />
73
+ <span class="qc-tile">
74
+ <span class="qc-tile-text">Option 3 (désactivée)</span>
75
+ </span>
76
+ </label>
77
+ </qc-choice-group>
78
+ </qc-doc-exemple>
79
+
80
+ <qc-doc-exemple caption="Exemple de boutons radio sous forme de boutons de sélection sur une rangée.">
81
+ <qc-choice-group legend="Choisissez une option :"
82
+ name="ex-radio-select-inline"
83
+ selection-button
84
+ inline
85
+ >
86
+ <label>
87
+ <input type="radio"
88
+ value="1"
89
+ checked
90
+ />
91
+ <span>1</span>
92
+ </label>
93
+ <label>
94
+ <input type="radio"
95
+ value="2"
96
+ />
97
+ <span>2</span>
98
+ </label>
99
+ <label>
100
+ <input type="radio"
101
+ value="3"
102
+ />
103
+ <span>3</span>
104
+ </label>
105
+ <label>
106
+ <input type="radio"
107
+ value="4"
108
+ />
109
+ <span>4</span>
110
+ </label>
111
+ <label>
112
+ <input type="radio"
113
+ value="5"
114
+ />
115
+ <span>5</span>
116
+ </label>
117
+ <label>
118
+ <input type="radio"
119
+ value="6"
120
+ disabled
121
+ />
122
+ <span>6</span>
123
+ </label>
124
+
125
+ </qc-choice-group>
126
+ </qc-doc-exemple>
127
+
128
+ <h5>Documentation technique</h5>
129
+ <p>Voir <a href="#choice-group-doc">la documentation technique du composant qc-choice-group</a>.</p>
130
+
@@ -0,0 +1,394 @@
1
+ <script>
2
+ import {Utils} from "../utils";
3
+ import SearchInput from "../SearchInput/SearchInput.svelte";
4
+ import FormError from "../FormError/FormError.svelte";
5
+ import DropdownListItems from "./DropdownListItems/DropdownListItems.svelte";
6
+ import DropdownListButton from "./DropdownListButton/DropdownListButton.svelte";
7
+ import Label from "../Label/Label.svelte";
8
+
9
+ const lang = Utils.getPageLanguage();
10
+
11
+ let {
12
+ id = Math.random().toString(36).substring(2, 15),
13
+ label = "",
14
+ ariaLabel = "",
15
+ width = "md",
16
+ items = [],
17
+ value = $bindable([]),
18
+ placeholder,
19
+ noOptionsMessage = lang === "fr" ? "Aucun élément" : "No item",
20
+ enableSearch = false,
21
+ required = false,
22
+ disabled = false,
23
+ invalid = $bindable(false),
24
+ invalidText,
25
+ searchPlaceholder = "",
26
+ multiple = false,
27
+ rootElement = $bindable(),
28
+ errorElement = $bindable(),
29
+ webComponentMode = false,
30
+ webComponentParentRow,
31
+ } = $props();
32
+
33
+ const
34
+ defaultPlaceholder = lang === "fr" ? "Faire une sélection" : "Select an option",
35
+ inputId = `${id}-input`,
36
+ popupId = `${id}-popup`,
37
+ itemsId = `${id}-items`,
38
+ labelId = `${id}-label`,
39
+ errorId = `${id}-error`,
40
+ availableWidths = ["xs", "sm", "md", "lg", "xl"]
41
+ ;
42
+
43
+ let
44
+ instance = $state(),
45
+ parentRow = $derived(instance?.closest(".qc-formfield-row")),
46
+ button = $state(),
47
+ searchInput = $state(),
48
+ dropdownItems = $state(),
49
+ selectedItems = $derived(items.filter((item) => item.checked) ?? []),
50
+ selectedOptionsText = $derived.by(() => {
51
+ if (selectedItems.length >= 3) {
52
+ if (lang === "fr") {
53
+ return `${selectedItems.length} options sélectionnées`;
54
+ }
55
+ return `${selectedItems.length} selected options`;
56
+ }
57
+
58
+ if (selectedItems.length > 0 && value.length > 0) {
59
+ if (multiple) {
60
+ return selectedItems.map((item) => item.label).join(", ");
61
+ }
62
+ return selectedItems[0].label;
63
+ }
64
+
65
+ return "";
66
+ }),
67
+ previousValue = $state(value),
68
+ expanded = $state(false),
69
+ searchText = $state(""),
70
+ hiddenSearchText = $state(""),
71
+ displayedItems = $state(items),
72
+ itemsForSearch = $derived(items.map((item) => {
73
+ return {
74
+ label: Utils.cleanupSearchPrompt(item.label),
75
+ value: item.value,
76
+ disabled: item.disabled,
77
+ checked: item.checked,
78
+ }
79
+ })),
80
+ widthClass = $derived.by(() => {
81
+ const keyword = webComponentMode ? "container" : "root";
82
+
83
+ if (availableWidths.includes(width)) {
84
+ return `qc-dropdown-list-${keyword}-${width}`;
85
+ }
86
+ return `qc-dropdown-list-${keyword}-md`;
87
+ }),
88
+ srItemsCountText = $derived.by(() => {
89
+ const s = displayedItems.length > 1 ? "s" : "";
90
+ if (displayedItems.length > 0) {
91
+ return lang === "fr" ?
92
+ `${displayedItems.length} résultat${s} disponible${s}. Utilisez les flèches directionnelles haut et bas pour vous déplacer dans la liste.`
93
+ : `${displayedItems.length} result${s} available. Use up and down arrow keys to navigate through the list.`;
94
+ }
95
+
96
+ return "";
97
+ })
98
+ ;
99
+
100
+ function focusOnSelectedOption(value) {
101
+ if (displayedItems.length > 0) {
102
+ if (value && value.length > 0) {
103
+ dropdownItems?.focusOnFirstMatchingElement($state.snapshot(value)?.sort()[0]);
104
+ } else {
105
+ dropdownItems?.focus();
106
+ }
107
+ }
108
+ }
109
+
110
+ function handleDropdownButtonClick(event) {
111
+ event.preventDefault();
112
+ expanded = !expanded;
113
+ }
114
+
115
+ function handleOuterEvent() {
116
+ if (!Utils.componentIsActive(instance)) {
117
+ expanded = false;
118
+ }
119
+ }
120
+
121
+ function handleTab(event) {
122
+ // Le changement de focus a lieu après le lancement de l'événement clavier.
123
+ // Il faut donc faire un court sleep pour avoir le nouvel élément en focus.
124
+ Utils.sleep(5).then(() => {
125
+ if (event.key === "Tab" && !Utils.componentIsActive(instance)) {
126
+ expanded = false;
127
+ }
128
+ }).catch(console.error);
129
+ }
130
+
131
+ function handleEscape(event) {
132
+ if (event.key === "Escape") {
133
+ expanded = false;
134
+ }
135
+ }
136
+
137
+ function handleArrowUp(event, targetComponent) {
138
+ if (event.key === "ArrowUp" && targetComponent) {
139
+ event.preventDefault();
140
+ targetComponent.focus();
141
+ }
142
+ }
143
+
144
+ function handleArrowDown(event, targetComponent) {
145
+ if (event.key === "ArrowDown" && targetComponent) {
146
+ event.preventDefault();
147
+ expanded = true;
148
+ targetComponent.focus();
149
+ }
150
+ }
151
+
152
+ function handleButtonComboKey(event, targetComponent) {
153
+ handleEscape(event);
154
+ handleTab(event);
155
+
156
+ if (event.key === "ArrowDown") {
157
+ event.preventDefault();
158
+ if (expanded) {
159
+ targetComponent.focus();
160
+ } else {
161
+ expanded = true;
162
+ focusOnSelectedOption(value);
163
+ }
164
+ }
165
+
166
+ if (event.key === "ArrowUp") {
167
+ event.preventDefault();
168
+ if (expanded) {
169
+ dropdownItems?.focusOnLastElement();
170
+ }
171
+ }
172
+ }
173
+
174
+ function handlePrintableCharacter(event) {
175
+ if (enableSearch) {
176
+ searchInput?.focus();
177
+ } else {
178
+ hiddenSearchText += event.key;
179
+ if (hiddenSearchText.length > 0 && expanded) {
180
+ dropdownItems?.focusOnFirstMatchingElement(hiddenSearchText);
181
+ }
182
+ }
183
+ }
184
+
185
+ function handleButtonKeyDown(event, targetComponent) {
186
+ if (event.key.match(/^\w$/i)) {
187
+ handlePrintableCharacter(event);
188
+ } else {
189
+ handleButtonComboKey(event, targetComponent);
190
+ }
191
+ }
192
+
193
+ function closeDropdown(key) {
194
+ expanded = false;
195
+ hiddenSearchText = "";
196
+ if (key === "Escape" && button) {
197
+ button.focus();
198
+ }
199
+ }
200
+
201
+ $effect(() => {
202
+ if (searchText.length > 0) {
203
+ let newDisplayedItems = [];
204
+ for (let i = 0; i < items.length; i++) {
205
+ if (itemsForSearch[i].label.includes(Utils.cleanupSearchPrompt(searchText))) {
206
+ newDisplayedItems.push(items[i]);
207
+ }
208
+ }
209
+
210
+ displayedItems = newDisplayedItems;
211
+ } else {
212
+ displayedItems = items;
213
+ }
214
+ });
215
+
216
+ $effect(() => {
217
+ if (previousValue?.toString() !== value?.toString()) {
218
+ invalid = false;
219
+ }
220
+ });
221
+
222
+ $effect(() => {
223
+ if (!expanded) {
224
+ hiddenSearchText = "";
225
+ searchText = "";
226
+ }
227
+ });
228
+
229
+ $effect(() => {
230
+ const tempValue = selectedItems?.map(item => item.value);
231
+ if (tempValue?.toString() !== "") {
232
+ value = tempValue;
233
+ } else {
234
+ value = [];
235
+ }
236
+ });
237
+
238
+ $effect(() => {
239
+ items.forEach((item) => {
240
+ if (!item.id) {
241
+ item.id = `${id}-${item.label.toString().replace(/(\(|\))/gmi, "").replace(/\s+/, "-")}-${item.value?.toString().replace(/(\(|\))/gmi, "").replace(/\s+/, "-")}`;
242
+ }
243
+ });
244
+ });
245
+
246
+ $effect(() => {
247
+ if (parentRow && errorElement && !webComponentMode) {
248
+ parentRow.appendChild($state.snapshot(errorElement));
249
+ }
250
+ });
251
+
252
+ $effect(() => {
253
+ if (placeholder) return;
254
+ const optionWithEmptyValue = findOptionWithEmptyValue();
255
+ if (!optionWithEmptyValue) return;
256
+ placeholder =
257
+ optionWithEmptyValue.label !== ""
258
+ ? optionWithEmptyValue.label
259
+ : defaultPlaceholder
260
+ ;
261
+ })
262
+
263
+
264
+ function findOptionWithEmptyValue() {
265
+ return items?.find(
266
+ item => item.value === ""
267
+ || item.value === null
268
+ || item.value === undefined
269
+ );
270
+ }
271
+ </script>
272
+
273
+ <svelte:body onclick={handleOuterEvent} onkeydown={handleTab}/>
274
+ <div
275
+ class={[
276
+ "qc-dropdown-list-root",
277
+ !webComponentMode && widthClass,
278
+ !(parentRow || webComponentParentRow) && "qc-dropdown-list-margin"
279
+ ]} bind:this={rootElement}
280
+ >
281
+ <div class={[
282
+ "qc-dropdown-list-container",
283
+ webComponentMode && widthClass
284
+ ]}>
285
+ <!-- svelte-ignore a11y_click_events_have_key_events -->
286
+ <!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
287
+ {#if label}
288
+ <Label
289
+ {required}
290
+ {disabled}
291
+ text={label}
292
+ forId={inputId}
293
+ onclick={(e) => {
294
+ e.preventDefault();
295
+ button.focus();
296
+ }}
297
+ bold={true}
298
+ id={labelId}
299
+ />
300
+ {/if}
301
+ <div
302
+ class={[
303
+ `qc-dropdown-list`,
304
+ invalid && "qc-dropdown-list-invalid",
305
+ ]}
306
+ tabindex="-1"
307
+ bind:this={instance}
308
+ >
309
+ <DropdownListButton
310
+ {inputId}
311
+ {disabled}
312
+ {expanded}
313
+ aria-labelledby={labelId}
314
+ aria-required={required}
315
+ aria-expanded={expanded}
316
+ aria-haspopup="listbox"
317
+ aria-controls={itemsId}
318
+ aria-invalid={invalid}
319
+ {selectedOptionsText}
320
+ {placeholder}
321
+ onclick={handleDropdownButtonClick}
322
+ onkeydown={(e) => {
323
+ handleButtonKeyDown(e, enableSearch ? searchInput : dropdownItems);
324
+ }}
325
+ bind:this={button}
326
+ />
327
+
328
+ <div
329
+ id={popupId}
330
+ class="qc-dropdown-list-expanded"
331
+ tabindex="-1"
332
+ hidden={!expanded}
333
+ role="listbox"
334
+ >
335
+
336
+ {#if enableSearch}
337
+ <div class="qc-dropdown-list-search">
338
+ <SearchInput
339
+ id="{id}-search"
340
+ bind:value={searchText}
341
+ placeholder={searchPlaceholder}
342
+ ariaLabel={searchPlaceholder ? searchPlaceholder : undefined}
343
+ leftIcon="true"
344
+ bind:this={searchInput}
345
+ onkeydown={(e) => {
346
+ handleArrowDown(e, dropdownItems);
347
+ handleArrowUp(e, button);
348
+ if (e.key === "Enter") {
349
+ e.preventDefault();
350
+ }
351
+ }}
352
+ />
353
+ </div>
354
+ {/if}
355
+
356
+ <DropdownListItems
357
+ id={itemsId}
358
+ {enableSearch}
359
+ {placeholder}
360
+ {multiple}
361
+ {items}
362
+ {displayedItems}
363
+ {noOptionsMessage}
364
+ selectionCallbackSingle={() => {
365
+ closeDropdown("");
366
+ button?.focus();
367
+ }}
368
+ handleExitSingle={(key) => closeDropdown(key)}
369
+ handleExitMultiple={(key) => closeDropdown(key)}
370
+ focusOnOuterElement={() => enableSearch ? searchInput?.focus() : button?.focus()}
371
+ handlePrintableCharacter={handlePrintableCharacter}
372
+ bind:this={dropdownItems}
373
+ bind:value={value}
374
+ />
375
+
376
+ <!-- Pour les lecteurs d'écran: lit le nombre de résultats -->
377
+ <div role="status" class="qc-sr-only">
378
+ {#key searchText}
379
+ <span>{srItemsCountText}</span>
380
+ {/key}
381
+ </div>
382
+ </div>
383
+ </div>
384
+
385
+ </div>
386
+
387
+ <FormError id={errorId}
388
+ bind:rootElement={errorElement}
389
+ {invalid}
390
+ {invalidText}
391
+ extraClasses={["qc-xs-mt"]}
392
+ label={label ?? ariaLabel}
393
+ />
394
+ </div>
@@ -0,0 +1,43 @@
1
+ <script>
2
+ import Icon from "../../../bases/Icon/Icon.svelte";
3
+
4
+ let {
5
+ inputId,
6
+ expanded,
7
+ disabled,
8
+ selectedOptionsText = "",
9
+ placeholder,
10
+ ...rest
11
+ } = $props()
12
+
13
+ let button;
14
+ export function focus() {
15
+ button?.focus();
16
+ }
17
+ </script>
18
+
19
+ <button
20
+ type="button"
21
+ id={inputId}
22
+ {disabled}
23
+ class="qc-dropdown-button"
24
+ role="combobox"
25
+ bind:this={button}
26
+ {...rest}
27
+ >
28
+ <span class="qc-dropdown-text">
29
+ {#if selectedOptionsText.length > 0}
30
+ <span class="qc-dropdown-choice">{@html selectedOptionsText}</span>
31
+ {:else}
32
+ <span class="qc-dropdown-placeholder">{@html placeholder}</span>
33
+ {/if}
34
+ </span>
35
+
36
+ <span class={["qc-dropdown-button-icon", expanded && "qc-dropdown-button-icon-expanded"]}>
37
+ <Icon
38
+ type="chevron-up-thin"
39
+ color={disabled ? "grey-regular" : "blue-piv"}
40
+ size="sm"
41
+ />
42
+ </span>
43
+ </button>
@@ -0,0 +1,65 @@
1
+ @use "../../../scss/qc-sdg-lib" as *;
2
+
3
+ $min-height: 40;
4
+
5
+ .qc-dropdown-button {
6
+ display: flex;
7
+ width: 100%;
8
+ justify-content: space-between;
9
+ height: rem($min-height);
10
+ align-items: center;
11
+ background-color: token-value(color, background);
12
+ border: none;
13
+ padding-left: token-value(spacer, xs);
14
+ padding-right: token-value(spacer, xs);
15
+ gap: token-value(spacer, xs);
16
+
17
+ @include qc-formcontrol-box();
18
+ @include content-font(md);
19
+
20
+ &:hover {
21
+ cursor: pointer;
22
+ }
23
+
24
+ &:disabled {
25
+ cursor: not-allowed;
26
+
27
+ &::before {
28
+ background-color: token-value(color, grey, pale);
29
+ }
30
+ }
31
+ }
32
+
33
+ .qc-dropdown-text {
34
+ display: flex;
35
+ justify-items: start;
36
+ overflow: hidden;
37
+ }
38
+
39
+ %dropdown-placeholder-text {
40
+ display: block;
41
+ justify-content: start;
42
+ min-width: 0;
43
+ overflow: hidden;
44
+ white-space: nowrap;
45
+ text-overflow: ellipsis;
46
+ }
47
+
48
+ .qc-dropdown-placeholder {
49
+ @extend %dropdown-placeholder-text;
50
+ color: token-value(color, grey, medium);
51
+ }
52
+
53
+ .qc-dropdown-choice {
54
+ @extend %dropdown-placeholder-text;
55
+ color: token-value(color, blue, dark);
56
+ }
57
+
58
+ .qc-dropdown-button-icon {
59
+ align-items: center;
60
+ rotate: 180deg;
61
+ }
62
+
63
+ .qc-dropdown-button-icon-expanded {
64
+ transform: rotate(180deg);
65
+ }