@fristil/designsystem 0.2.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 (314) hide show
  1. package/CHANGELOG.md +85 -0
  2. package/LICENSE +21 -0
  3. package/README.md +101 -0
  4. package/dist/cli.d.ts +31 -0
  5. package/dist/cli.d.ts.map +1 -0
  6. package/dist/cli.js +261 -0
  7. package/dist/cli.js.map +1 -0
  8. package/dist/components/css/accordion/accordion.d.ts +37 -0
  9. package/dist/components/css/accordion/accordion.d.ts.map +1 -0
  10. package/dist/components/css/accordion/accordion.js +31 -0
  11. package/dist/components/css/accordion/accordion.js.map +1 -0
  12. package/dist/components/css/alert/alert.d.ts +35 -0
  13. package/dist/components/css/alert/alert.d.ts.map +1 -0
  14. package/dist/components/css/alert/alert.js +29 -0
  15. package/dist/components/css/alert/alert.js.map +1 -0
  16. package/dist/components/css/avatar/avatar.d.ts +40 -0
  17. package/dist/components/css/avatar/avatar.d.ts.map +1 -0
  18. package/dist/components/css/avatar/avatar.js +30 -0
  19. package/dist/components/css/avatar/avatar.js.map +1 -0
  20. package/dist/components/css/badge/badge.d.ts +24 -0
  21. package/dist/components/css/badge/badge.d.ts.map +1 -0
  22. package/dist/components/css/badge/badge.js +24 -0
  23. package/dist/components/css/badge/badge.js.map +1 -0
  24. package/dist/components/css/breadcrumbs/breadcrumbs.d.ts +25 -0
  25. package/dist/components/css/breadcrumbs/breadcrumbs.d.ts.map +1 -0
  26. package/dist/components/css/breadcrumbs/breadcrumbs.js +23 -0
  27. package/dist/components/css/breadcrumbs/breadcrumbs.js.map +1 -0
  28. package/dist/components/css/button/button.d.ts +26 -0
  29. package/dist/components/css/button/button.d.ts.map +1 -0
  30. package/dist/components/css/button/button.js +25 -0
  31. package/dist/components/css/button/button.js.map +1 -0
  32. package/dist/components/css/card/card.d.ts +36 -0
  33. package/dist/components/css/card/card.d.ts.map +1 -0
  34. package/dist/components/css/card/card.js +28 -0
  35. package/dist/components/css/card/card.js.map +1 -0
  36. package/dist/components/css/checkbox/checkbox.d.ts +32 -0
  37. package/dist/components/css/checkbox/checkbox.d.ts.map +1 -0
  38. package/dist/components/css/checkbox/checkbox.js +27 -0
  39. package/dist/components/css/checkbox/checkbox.js.map +1 -0
  40. package/dist/components/css/dialog/dialog.d.ts +30 -0
  41. package/dist/components/css/dialog/dialog.d.ts.map +1 -0
  42. package/dist/components/css/dialog/dialog.js +28 -0
  43. package/dist/components/css/dialog/dialog.js.map +1 -0
  44. package/dist/components/css/divider/divider.d.ts +28 -0
  45. package/dist/components/css/divider/divider.d.ts.map +1 -0
  46. package/dist/components/css/divider/divider.js +22 -0
  47. package/dist/components/css/divider/divider.js.map +1 -0
  48. package/dist/components/css/error-text/error-text.d.ts +24 -0
  49. package/dist/components/css/error-text/error-text.d.ts.map +1 -0
  50. package/dist/components/css/error-text/error-text.js +18 -0
  51. package/dist/components/css/error-text/error-text.js.map +1 -0
  52. package/dist/components/css/fieldset/fieldset.d.ts +55 -0
  53. package/dist/components/css/fieldset/fieldset.d.ts.map +1 -0
  54. package/dist/components/css/fieldset/fieldset.js +39 -0
  55. package/dist/components/css/fieldset/fieldset.js.map +1 -0
  56. package/dist/components/css/file-upload/file-upload.d.ts +41 -0
  57. package/dist/components/css/file-upload/file-upload.d.ts.map +1 -0
  58. package/dist/components/css/file-upload/file-upload.js +32 -0
  59. package/dist/components/css/file-upload/file-upload.js.map +1 -0
  60. package/dist/components/css/heading/heading.d.ts +29 -0
  61. package/dist/components/css/heading/heading.d.ts.map +1 -0
  62. package/dist/components/css/heading/heading.js +23 -0
  63. package/dist/components/css/heading/heading.js.map +1 -0
  64. package/dist/components/css/help-text/help-text.d.ts +24 -0
  65. package/dist/components/css/help-text/help-text.d.ts.map +1 -0
  66. package/dist/components/css/help-text/help-text.js +23 -0
  67. package/dist/components/css/help-text/help-text.js.map +1 -0
  68. package/dist/components/css/input/input.d.ts +39 -0
  69. package/dist/components/css/input/input.d.ts.map +1 -0
  70. package/dist/components/css/input/input.js +44 -0
  71. package/dist/components/css/input/input.js.map +1 -0
  72. package/dist/components/css/label/label.d.ts +33 -0
  73. package/dist/components/css/label/label.d.ts.map +1 -0
  74. package/dist/components/css/label/label.js +23 -0
  75. package/dist/components/css/label/label.js.map +1 -0
  76. package/dist/components/css/link/link.d.ts +21 -0
  77. package/dist/components/css/link/link.d.ts.map +1 -0
  78. package/dist/components/css/link/link.js +14 -0
  79. package/dist/components/css/link/link.js.map +1 -0
  80. package/dist/components/css/list/list.d.ts +29 -0
  81. package/dist/components/css/list/list.d.ts.map +1 -0
  82. package/dist/components/css/list/list.js +23 -0
  83. package/dist/components/css/list/list.js.map +1 -0
  84. package/dist/components/css/pagination/pagination.d.ts +27 -0
  85. package/dist/components/css/pagination/pagination.d.ts.map +1 -0
  86. package/dist/components/css/pagination/pagination.js +25 -0
  87. package/dist/components/css/pagination/pagination.js.map +1 -0
  88. package/dist/components/css/paragraph/paragraph.d.ts +36 -0
  89. package/dist/components/css/paragraph/paragraph.d.ts.map +1 -0
  90. package/dist/components/css/paragraph/paragraph.js +26 -0
  91. package/dist/components/css/paragraph/paragraph.js.map +1 -0
  92. package/dist/components/css/radio/radio.d.ts +32 -0
  93. package/dist/components/css/radio/radio.d.ts.map +1 -0
  94. package/dist/components/css/radio/radio.js +27 -0
  95. package/dist/components/css/radio/radio.js.map +1 -0
  96. package/dist/components/css/search/search.d.ts +33 -0
  97. package/dist/components/css/search/search.d.ts.map +1 -0
  98. package/dist/components/css/search/search.js +31 -0
  99. package/dist/components/css/search/search.js.map +1 -0
  100. package/dist/components/css/select/select.d.ts +23 -0
  101. package/dist/components/css/select/select.d.ts.map +1 -0
  102. package/dist/components/css/select/select.js +18 -0
  103. package/dist/components/css/select/select.js.map +1 -0
  104. package/dist/components/css/shared.d.ts +26 -0
  105. package/dist/components/css/shared.d.ts.map +1 -0
  106. package/dist/components/css/shared.js +34 -0
  107. package/dist/components/css/shared.js.map +1 -0
  108. package/dist/components/css/skeleton/skeleton.d.ts +29 -0
  109. package/dist/components/css/skeleton/skeleton.d.ts.map +1 -0
  110. package/dist/components/css/skeleton/skeleton.js +23 -0
  111. package/dist/components/css/skeleton/skeleton.js.map +1 -0
  112. package/dist/components/css/skip-link/skip-link.d.ts +18 -0
  113. package/dist/components/css/skip-link/skip-link.d.ts.map +1 -0
  114. package/dist/components/css/skip-link/skip-link.js +16 -0
  115. package/dist/components/css/skip-link/skip-link.js.map +1 -0
  116. package/dist/components/css/spinner/spinner.d.ts +33 -0
  117. package/dist/components/css/spinner/spinner.d.ts.map +1 -0
  118. package/dist/components/css/spinner/spinner.js +25 -0
  119. package/dist/components/css/spinner/spinner.js.map +1 -0
  120. package/dist/components/css/sr-only/sr-only.d.ts +17 -0
  121. package/dist/components/css/sr-only/sr-only.d.ts.map +1 -0
  122. package/dist/components/css/sr-only/sr-only.js +14 -0
  123. package/dist/components/css/sr-only/sr-only.js.map +1 -0
  124. package/dist/components/css/switch/switch.d.ts +33 -0
  125. package/dist/components/css/switch/switch.d.ts.map +1 -0
  126. package/dist/components/css/switch/switch.js +29 -0
  127. package/dist/components/css/switch/switch.js.map +1 -0
  128. package/dist/components/css/table/table.d.ts +36 -0
  129. package/dist/components/css/table/table.d.ts.map +1 -0
  130. package/dist/components/css/table/table.js +28 -0
  131. package/dist/components/css/table/table.js.map +1 -0
  132. package/dist/components/css/tag/tag.d.ts +35 -0
  133. package/dist/components/css/tag/tag.d.ts.map +1 -0
  134. package/dist/components/css/tag/tag.js +27 -0
  135. package/dist/components/css/tag/tag.js.map +1 -0
  136. package/dist/components/css/textarea/textarea.d.ts +23 -0
  137. package/dist/components/css/textarea/textarea.d.ts.map +1 -0
  138. package/dist/components/css/textarea/textarea.js +18 -0
  139. package/dist/components/css/textarea/textarea.js.map +1 -0
  140. package/dist/components/css/toggle-group/toggle-group.d.ts +31 -0
  141. package/dist/components/css/toggle-group/toggle-group.d.ts.map +1 -0
  142. package/dist/components/css/toggle-group/toggle-group.js +29 -0
  143. package/dist/components/css/toggle-group/toggle-group.js.map +1 -0
  144. package/dist/components/css/tooltip/tooltip.d.ts +30 -0
  145. package/dist/components/css/tooltip/tooltip.d.ts.map +1 -0
  146. package/dist/components/css/tooltip/tooltip.js +28 -0
  147. package/dist/components/css/tooltip/tooltip.js.map +1 -0
  148. package/dist/components/frittstaende/calendar/fs-calendar.d.ts +52 -0
  149. package/dist/components/frittstaende/calendar/fs-calendar.d.ts.map +1 -0
  150. package/dist/components/frittstaende/calendar/fs-calendar.js +462 -0
  151. package/dist/components/frittstaende/calendar/fs-calendar.js.map +1 -0
  152. package/dist/components/frittstaende/date-field/fs-date-field.d.ts +110 -0
  153. package/dist/components/frittstaende/date-field/fs-date-field.d.ts.map +1 -0
  154. package/dist/components/frittstaende/date-field/fs-date-field.js +264 -0
  155. package/dist/components/frittstaende/date-field/fs-date-field.js.map +1 -0
  156. package/dist/components/frittstaende/suggestion/fs-suggestion.d.ts +133 -0
  157. package/dist/components/frittstaende/suggestion/fs-suggestion.d.ts.map +1 -0
  158. package/dist/components/frittstaende/suggestion/fs-suggestion.js +280 -0
  159. package/dist/components/frittstaende/suggestion/fs-suggestion.js.map +1 -0
  160. package/dist/components/frittstaende/toast/fs-toast.d.ts +67 -0
  161. package/dist/components/frittstaende/toast/fs-toast.d.ts.map +1 -0
  162. package/dist/components/frittstaende/toast/fs-toast.js +108 -0
  163. package/dist/components/frittstaende/toast/fs-toast.js.map +1 -0
  164. package/dist/components/ramme/error-summary/fs-error-summary.d.ts +70 -0
  165. package/dist/components/ramme/error-summary/fs-error-summary.d.ts.map +1 -0
  166. package/dist/components/ramme/error-summary/fs-error-summary.js +155 -0
  167. package/dist/components/ramme/error-summary/fs-error-summary.js.map +1 -0
  168. package/dist/components/ramme/field/field-core.d.ts +70 -0
  169. package/dist/components/ramme/field/field-core.d.ts.map +1 -0
  170. package/dist/components/ramme/field/field-core.js +60 -0
  171. package/dist/components/ramme/field/field-core.js.map +1 -0
  172. package/dist/components/ramme/field/fs-field.d.ts +49 -0
  173. package/dist/components/ramme/field/fs-field.d.ts.map +1 -0
  174. package/dist/components/ramme/field/fs-field.js +118 -0
  175. package/dist/components/ramme/field/fs-field.js.map +1 -0
  176. package/dist/components/ramme/popover/fs-popover.d.ts +68 -0
  177. package/dist/components/ramme/popover/fs-popover.d.ts.map +1 -0
  178. package/dist/components/ramme/popover/fs-popover.js +167 -0
  179. package/dist/components/ramme/popover/fs-popover.js.map +1 -0
  180. package/dist/components/ramme/tabs/fs-tabs.d.ts +61 -0
  181. package/dist/components/ramme/tabs/fs-tabs.d.ts.map +1 -0
  182. package/dist/components/ramme/tabs/fs-tabs.js +156 -0
  183. package/dist/components/ramme/tabs/fs-tabs.js.map +1 -0
  184. package/dist/dom.d.ts +33 -0
  185. package/dist/dom.d.ts.map +1 -0
  186. package/dist/dom.js +77 -0
  187. package/dist/dom.js.map +1 -0
  188. package/dist/fs.d.ts +199 -0
  189. package/dist/fs.d.ts.map +1 -0
  190. package/dist/fs.js +128 -0
  191. package/dist/fs.js.map +1 -0
  192. package/dist/index.d.ts +84 -0
  193. package/dist/index.d.ts.map +1 -0
  194. package/dist/index.js +48 -0
  195. package/dist/index.js.map +1 -0
  196. package/dist/jsx/react.d.ts +127 -0
  197. package/dist/jsx/react.d.ts.map +1 -0
  198. package/dist/jsx/react.js +2 -0
  199. package/dist/jsx/react.js.map +1 -0
  200. package/dist/react.d.ts +207 -0
  201. package/dist/react.d.ts.map +1 -0
  202. package/dist/react.js +109 -0
  203. package/dist/react.js.map +1 -0
  204. package/dist/tailwind/preset.d.ts +120 -0
  205. package/dist/tailwind/preset.d.ts.map +1 -0
  206. package/dist/tailwind/preset.js +107 -0
  207. package/dist/tailwind/preset.js.map +1 -0
  208. package/dist/takeover.d.ts +79 -0
  209. package/dist/takeover.d.ts.map +1 -0
  210. package/dist/takeover.js +119 -0
  211. package/dist/takeover.js.map +1 -0
  212. package/dist/tokens/color.d.ts +85 -0
  213. package/dist/tokens/color.d.ts.map +1 -0
  214. package/dist/tokens/color.js +212 -0
  215. package/dist/tokens/color.js.map +1 -0
  216. package/dist/tokens/theme.d.ts +52 -0
  217. package/dist/tokens/theme.d.ts.map +1 -0
  218. package/dist/tokens/theme.js +197 -0
  219. package/dist/tokens/theme.js.map +1 -0
  220. package/dist/tokens/tokens.d.ts +210 -0
  221. package/dist/tokens/tokens.d.ts.map +1 -0
  222. package/dist/tokens/tokens.js +238 -0
  223. package/dist/tokens/tokens.js.map +1 -0
  224. package/package.json +334 -0
  225. package/src/components/css/accordion/accordion.css +74 -0
  226. package/src/components/css/accordion/accordion.ts +50 -0
  227. package/src/components/css/alert/alert.css +50 -0
  228. package/src/components/css/alert/alert.ts +48 -0
  229. package/src/components/css/avatar/avatar.css +64 -0
  230. package/src/components/css/avatar/avatar.ts +57 -0
  231. package/src/components/css/badge/badge.css +42 -0
  232. package/src/components/css/badge/badge.ts +43 -0
  233. package/src/components/css/breadcrumbs/breadcrumbs.css +50 -0
  234. package/src/components/css/breadcrumbs/breadcrumbs.ts +29 -0
  235. package/src/components/css/button/button.css +101 -0
  236. package/src/components/css/button/button.ts +44 -0
  237. package/src/components/css/card/card.css +48 -0
  238. package/src/components/css/card/card.ts +50 -0
  239. package/src/components/css/checkbox/checkbox.css +96 -0
  240. package/src/components/css/checkbox/checkbox.ts +50 -0
  241. package/src/components/css/dialog/dialog.css +50 -0
  242. package/src/components/css/dialog/dialog.ts +36 -0
  243. package/src/components/css/divider/divider.css +18 -0
  244. package/src/components/css/divider/divider.ts +41 -0
  245. package/src/components/css/error-text/error-text.css +21 -0
  246. package/src/components/css/error-text/error-text.ts +37 -0
  247. package/src/components/css/fieldset/fieldset.css +57 -0
  248. package/src/components/css/fieldset/fieldset.ts +87 -0
  249. package/src/components/css/file-upload/file-upload.css +92 -0
  250. package/src/components/css/file-upload/file-upload.ts +65 -0
  251. package/src/components/css/heading/heading.css +33 -0
  252. package/src/components/css/heading/heading.ts +42 -0
  253. package/src/components/css/help-text/help-text.css +24 -0
  254. package/src/components/css/help-text/help-text.ts +42 -0
  255. package/src/components/css/input/input.css +131 -0
  256. package/src/components/css/input/input.ts +76 -0
  257. package/src/components/css/label/label.css +34 -0
  258. package/src/components/css/label/label.ts +51 -0
  259. package/src/components/css/link/link.css +36 -0
  260. package/src/components/css/link/link.ts +29 -0
  261. package/src/components/css/list/list.css +40 -0
  262. package/src/components/css/list/list.ts +42 -0
  263. package/src/components/css/pagination/pagination.css +77 -0
  264. package/src/components/css/pagination/pagination.ts +33 -0
  265. package/src/components/css/paragraph/paragraph.css +31 -0
  266. package/src/components/css/paragraph/paragraph.ts +53 -0
  267. package/src/components/css/radio/radio.css +76 -0
  268. package/src/components/css/radio/radio.ts +50 -0
  269. package/src/components/css/search/search.css +49 -0
  270. package/src/components/css/search/search.ts +52 -0
  271. package/src/components/css/select/select.css +95 -0
  272. package/src/components/css/select/select.ts +40 -0
  273. package/src/components/css/shared.ts +40 -0
  274. package/src/components/css/skeleton/skeleton.css +49 -0
  275. package/src/components/css/skeleton/skeleton.ts +43 -0
  276. package/src/components/css/skip-link/skip-link.css +36 -0
  277. package/src/components/css/skip-link/skip-link.ts +22 -0
  278. package/src/components/css/spinner/spinner.css +48 -0
  279. package/src/components/css/spinner/spinner.ts +48 -0
  280. package/src/components/css/sr-only/sr-only.css +16 -0
  281. package/src/components/css/sr-only/sr-only.ts +18 -0
  282. package/src/components/css/switch/switch.css +101 -0
  283. package/src/components/css/switch/switch.ts +46 -0
  284. package/src/components/css/table/table.css +63 -0
  285. package/src/components/css/table/table.ts +50 -0
  286. package/src/components/css/tag/tag.css +58 -0
  287. package/src/components/css/tag/tag.ts +49 -0
  288. package/src/components/css/textarea/textarea.css +71 -0
  289. package/src/components/css/textarea/textarea.ts +40 -0
  290. package/src/components/css/toggle-group/toggle-group.css +82 -0
  291. package/src/components/css/toggle-group/toggle-group.ts +37 -0
  292. package/src/components/css/tooltip/tooltip.css +47 -0
  293. package/src/components/css/tooltip/tooltip.ts +36 -0
  294. package/src/components/frittstaende/calendar/fs-calendar.ts +525 -0
  295. package/src/components/frittstaende/date-field/date-field.css +54 -0
  296. package/src/components/frittstaende/date-field/fs-date-field.ts +309 -0
  297. package/src/components/frittstaende/suggestion/fs-suggestion.ts +333 -0
  298. package/src/components/frittstaende/suggestion/suggestion.css +63 -0
  299. package/src/components/frittstaende/toast/fs-toast.ts +146 -0
  300. package/src/components/frittstaende/toast/toast.css +71 -0
  301. package/src/components/ramme/error-summary/error-summary.css +45 -0
  302. package/src/components/ramme/error-summary/fs-error-summary.ts +197 -0
  303. package/src/components/ramme/field/field-core.ts +132 -0
  304. package/src/components/ramme/field/field.css +6 -0
  305. package/src/components/ramme/field/fs-field.ts +154 -0
  306. package/src/components/ramme/popover/fs-popover.ts +205 -0
  307. package/src/components/ramme/popover/popover.css +34 -0
  308. package/src/components/ramme/tabs/fs-tabs.ts +182 -0
  309. package/src/components/ramme/tabs/tabs.css +68 -0
  310. package/src/tailwind/tailwind.css +134 -0
  311. package/src/tokens/color.ts +267 -0
  312. package/src/tokens/theme.ts +350 -0
  313. package/src/tokens/tokens.css +214 -0
  314. package/src/tokens/tokens.ts +293 -0
@@ -0,0 +1,167 @@
1
+ import { html, LitElement } from "lit";
2
+ export const FS_POPOVER_TAG = "fs-popover";
3
+ export const POPOVER_CLASS = "fs-popover";
4
+ /**
5
+ * Et panel som henger under en knapp, og som lukker seg selv.
6
+ *
7
+ * Panelet bruker nettleserens egen `popover`, så det havner i topplaget. Det
8
+ * løser tre ting som ellers krever kode: panelet legger seg over alt annet
9
+ * uten `z-index`, Escape lukker det, og et klikk utenfor lukker det.
10
+ *
11
+ * Det topplaget gjør ikke er å plassere panelet. `position-anchor` finnes
12
+ * ennå ikke i alle nettlesere, så posisjonen regnes ut her, mot knappens
13
+ * plass på skjermen.
14
+ *
15
+ * Du skriver knappen og innholdet selv, og komponenten kobler dem sammen:
16
+ *
17
+ * ```html
18
+ * <fs-popover placement="bottom-end">
19
+ * <button slot="trigger" class="fs-button">Handlinger</button>
20
+ * <ul class="fs-list" data-variant="plain">…</ul>
21
+ * </fs-popover>
22
+ * ```
23
+ */
24
+ export class FsPopover extends LitElement {
25
+ constructor() {
26
+ super(...arguments);
27
+ /** Om panelet er åpent. Speiles, så CSS kan treffe tilstanden. */
28
+ this.open = false;
29
+ /** Hvilken kant panelet henger fra. Standard: `bottom-start`. */
30
+ this.placement = "bottom-start";
31
+ this.handleSlotChange = () => {
32
+ this.sync();
33
+ };
34
+ this.handleTriggerClick = () => {
35
+ this.toggle();
36
+ };
37
+ this.handleOutsideClick = (event) => {
38
+ const target = event.target;
39
+ if (this.contains(target) || this.panel?.contains(target))
40
+ return;
41
+ this.hide();
42
+ };
43
+ this.handleKeydown = (event) => {
44
+ if (event.key !== "Escape")
45
+ return;
46
+ this.hide();
47
+ // Fokus tilbake til knappen. Uten dette står fokus på et panel som ikke
48
+ // lenger finnes, og neste tastetrykk starter på toppen av siden.
49
+ this.triggerElement?.focus();
50
+ };
51
+ /** Regner ut hvor panelet skal stå, mot knappens plass på skjermen. */
52
+ this.reposition = () => {
53
+ if (!this.open || !this.panel || !this.triggerElement)
54
+ return;
55
+ const anchor = this.triggerElement.getBoundingClientRect();
56
+ const panel = this.panel.getBoundingClientRect();
57
+ const space = 4;
58
+ const below = this.placement.startsWith("bottom");
59
+ const alignEnd = this.placement.endsWith("end");
60
+ let top = below ? anchor.bottom + space : anchor.top - panel.height - space;
61
+ let left = alignEnd ? anchor.right - panel.width : anchor.left;
62
+ // Panelet skal ikke havne utenfor skjermen. Går det ut på siden, flyttes
63
+ // det inn; er det ikke plass under, legges det over knappen i stedet.
64
+ left = Math.max(space, Math.min(left, window.innerWidth - panel.width - space));
65
+ if (below && top + panel.height > window.innerHeight) {
66
+ top = Math.max(space, anchor.top - panel.height - space);
67
+ }
68
+ this.panel.style.setProperty("--fs-popover-top", `${Math.round(top)}px`);
69
+ this.panel.style.setProperty("--fs-popover-left", `${Math.round(left)}px`);
70
+ };
71
+ }
72
+ createRenderRoot() {
73
+ return this;
74
+ }
75
+ render() {
76
+ return html `<slot @slotchange=${this.handleSlotChange}></slot>`;
77
+ }
78
+ connectedCallback() {
79
+ super.connectedCallback();
80
+ window.addEventListener("resize", this.reposition);
81
+ window.addEventListener("scroll", this.reposition, true);
82
+ }
83
+ disconnectedCallback() {
84
+ window.removeEventListener("resize", this.reposition);
85
+ window.removeEventListener("scroll", this.reposition, true);
86
+ super.disconnectedCallback();
87
+ }
88
+ firstUpdated() {
89
+ this.sync();
90
+ }
91
+ updated() {
92
+ this.sync();
93
+ }
94
+ sync() {
95
+ const trigger = this.querySelector("[slot='trigger']");
96
+ const panel = [...this.children].find((child) => child instanceof HTMLElement &&
97
+ child.getAttribute("slot") !== "trigger" &&
98
+ child.tagName !== "SLOT");
99
+ if (!trigger || !panel)
100
+ return;
101
+ this.triggerElement = trigger;
102
+ this.panel = panel;
103
+ if (!panel.id) {
104
+ panel.id = `fs-popover-${Math.random().toString(36).slice(2, 9)}`;
105
+ }
106
+ panel.classList.add(POPOVER_CLASS);
107
+ // `manual` og ikke `auto`: vi lukker selv, slik at knappen kan brukes til
108
+ // å lukke igjen uten at nettleseren rekker å lukke først.
109
+ panel.setAttribute("popover", "manual");
110
+ trigger.setAttribute("aria-expanded", String(this.open));
111
+ trigger.setAttribute("aria-controls", panel.id);
112
+ trigger.removeEventListener("click", this.handleTriggerClick);
113
+ trigger.addEventListener("click", this.handleTriggerClick);
114
+ if (this.open) {
115
+ if (!panel.matches(":popover-open"))
116
+ panel.showPopover();
117
+ this.reposition();
118
+ document.addEventListener("click", this.handleOutsideClick, true);
119
+ document.addEventListener("keydown", this.handleKeydown);
120
+ }
121
+ else {
122
+ if (panel.matches(":popover-open"))
123
+ panel.hidePopover();
124
+ document.removeEventListener("click", this.handleOutsideClick, true);
125
+ document.removeEventListener("keydown", this.handleKeydown);
126
+ }
127
+ }
128
+ /** Åpner panelet. */
129
+ show() {
130
+ if (this.open)
131
+ return;
132
+ this.open = true;
133
+ this.dispatchEvent(new CustomEvent("popover-toggle", {
134
+ detail: { open: true },
135
+ bubbles: true,
136
+ composed: true,
137
+ }));
138
+ }
139
+ /** Lukker panelet. */
140
+ hide() {
141
+ if (!this.open)
142
+ return;
143
+ this.open = false;
144
+ this.dispatchEvent(new CustomEvent("popover-toggle", {
145
+ detail: { open: false },
146
+ bubbles: true,
147
+ composed: true,
148
+ }));
149
+ }
150
+ /** Åpner eller lukker. */
151
+ toggle() {
152
+ if (this.open)
153
+ this.hide();
154
+ else
155
+ this.show();
156
+ }
157
+ }
158
+ FsPopover.properties = {
159
+ open: { type: Boolean, reflect: true },
160
+ placement: { type: String },
161
+ };
162
+ export function defineFsPopover(tagName = FS_POPOVER_TAG) {
163
+ if (!customElements.get(tagName)) {
164
+ customElements.define(tagName, FsPopover);
165
+ }
166
+ }
167
+ //# sourceMappingURL=fs-popover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs-popover.js","sourceRoot":"","sources":["../../../../src/components/ramme/popover/fs-popover.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ import { LitElement } from "lit";
2
+ export declare const FS_TABS_TAG: "fs-tabs";
3
+ export declare const TABS_LIST_CLASS: "fs-tabs__list";
4
+ export declare const TABS_PANEL_CLASS: "fs-tabs__panel";
5
+ /**
6
+ * Kobler en rad med knapper til panelene de hører til.
7
+ *
8
+ * Du skriver knappene og panelene selv. Komponenten setter rollene, holder
9
+ * `aria-selected` og `aria-controls` i synk, skjuler panelene som ikke er
10
+ * valgt, og tar piltastene.
11
+ *
12
+ * Tastaturet er hele grunnen til at komponenten finnes. I en faneliste skal
13
+ * Tab hoppe forbi hele raden og inn i panelet, mens piltastene flytter mellom
14
+ * fanene. Et sett knapper uten denne koblingen gir én tabbestopp per fane, og
15
+ * skjermleseren sier «knapp» der den skulle sagt «fane, 2 av 3, valgt».
16
+ *
17
+ * ```html
18
+ * <fs-tabs>
19
+ * <div class="fs-tabs__list">
20
+ * <button>Søknaden</button>
21
+ * <button>Vedlegg</button>
22
+ * </div>
23
+ * <div class="fs-tabs__panel">…</div>
24
+ * <div class="fs-tabs__panel">…</div>
25
+ * </fs-tabs>
26
+ * ```
27
+ */
28
+ export declare class FsTabs extends LitElement {
29
+ static properties: {
30
+ selected: {
31
+ type: NumberConstructor;
32
+ reflect: boolean;
33
+ };
34
+ label: {
35
+ type: StringConstructor;
36
+ };
37
+ };
38
+ /** Indeksen på fanen som er valgt. */
39
+ selected: number;
40
+ /** Tekst som sier hva fanene velger mellom. Blir `aria-label` på raden. */
41
+ label?: string;
42
+ createRenderRoot(): this;
43
+ render(): import("lit").TemplateResult<1>;
44
+ firstUpdated(): void;
45
+ updated(): void;
46
+ private handleSlotChange;
47
+ private get tabs();
48
+ private get panels();
49
+ private sync;
50
+ private handleClick;
51
+ private handleKeydown;
52
+ /** Velger en fane og melder fra. */
53
+ select(index: number): void;
54
+ }
55
+ declare global {
56
+ interface HTMLElementTagNameMap {
57
+ "fs-tabs": FsTabs;
58
+ }
59
+ }
60
+ export declare function defineFsTabs(tagName?: "fs-tabs"): void;
61
+ //# sourceMappingURL=fs-tabs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs-tabs.d.ts","sourceRoot":"","sources":["../../../../src/components/ramme/tabs/fs-tabs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,UAAU,EAAE,MAAM,KAAK,CAAA;AAEtC,eAAO,MAAM,WAAW,EAAG,SAAkB,CAAA;AAE7C,eAAO,MAAM,eAAe,EAAG,eAAwB,CAAA;AACvD,eAAO,MAAM,gBAAgB,EAAG,gBAAyB,CAAA;AAMzD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,MAAO,SAAQ,UAAU;IACpC,MAAM,CAAC,UAAU;;;;;;;;MAGhB;IAED,sCAAsC;IACtC,QAAQ,SAAI;IACZ,2EAA2E;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAA;IAEd,gBAAgB;IAIhB,MAAM;IAIN,YAAY;IAIZ,OAAO;IAIP,OAAO,CAAC,gBAAgB,CAEvB;IAED,OAAO,KAAK,IAAI,GAGf;IAED,OAAO,KAAK,MAAM,GAEjB;IAED,OAAO,CAAC,IAAI;IA8CZ,OAAO,CAAC,WAAW,CAGlB;IAED,OAAO,CAAC,aAAa,CA2BpB;IAED,oCAAoC;IACpC,MAAM,CAAC,KAAK,EAAE,MAAM;CAcrB;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,SAAS,EAAE,MAAM,CAAA;KAClB;CACF;AAED,wBAAgB,YAAY,CAAC,OAAO,YAAc,GAAG,IAAI,CAIxD"}
@@ -0,0 +1,156 @@
1
+ import { html, LitElement } from "lit";
2
+ export const FS_TABS_TAG = "fs-tabs";
3
+ export const TABS_LIST_CLASS = "fs-tabs__list";
4
+ export const TABS_PANEL_CLASS = "fs-tabs__panel";
5
+ function uniqueId(prefix) {
6
+ return `${prefix}-${Math.random().toString(36).slice(2, 9)}`;
7
+ }
8
+ /**
9
+ * Kobler en rad med knapper til panelene de hører til.
10
+ *
11
+ * Du skriver knappene og panelene selv. Komponenten setter rollene, holder
12
+ * `aria-selected` og `aria-controls` i synk, skjuler panelene som ikke er
13
+ * valgt, og tar piltastene.
14
+ *
15
+ * Tastaturet er hele grunnen til at komponenten finnes. I en faneliste skal
16
+ * Tab hoppe forbi hele raden og inn i panelet, mens piltastene flytter mellom
17
+ * fanene. Et sett knapper uten denne koblingen gir én tabbestopp per fane, og
18
+ * skjermleseren sier «knapp» der den skulle sagt «fane, 2 av 3, valgt».
19
+ *
20
+ * ```html
21
+ * <fs-tabs>
22
+ * <div class="fs-tabs__list">
23
+ * <button>Søknaden</button>
24
+ * <button>Vedlegg</button>
25
+ * </div>
26
+ * <div class="fs-tabs__panel">…</div>
27
+ * <div class="fs-tabs__panel">…</div>
28
+ * </fs-tabs>
29
+ * ```
30
+ */
31
+ export class FsTabs extends LitElement {
32
+ constructor() {
33
+ super(...arguments);
34
+ /** Indeksen på fanen som er valgt. */
35
+ this.selected = 0;
36
+ this.handleSlotChange = () => {
37
+ this.sync();
38
+ };
39
+ this.handleClick = (event) => {
40
+ const index = this.tabs.indexOf(event.currentTarget);
41
+ if (index >= 0)
42
+ this.select(index);
43
+ };
44
+ this.handleKeydown = (event) => {
45
+ const tabs = this.tabs;
46
+ const current = tabs.indexOf(event.currentTarget);
47
+ if (current < 0)
48
+ return;
49
+ const steps = {
50
+ ArrowRight: 1,
51
+ ArrowLeft: -1,
52
+ ArrowDown: 1,
53
+ ArrowUp: -1,
54
+ };
55
+ let next;
56
+ if (event.key in steps) {
57
+ next = (current + steps[event.key] + tabs.length) % tabs.length;
58
+ }
59
+ else if (event.key === "Home") {
60
+ next = 0;
61
+ }
62
+ else if (event.key === "End") {
63
+ next = tabs.length - 1;
64
+ }
65
+ if (next === undefined)
66
+ return;
67
+ event.preventDefault();
68
+ this.select(next);
69
+ tabs[next].focus();
70
+ };
71
+ }
72
+ createRenderRoot() {
73
+ return this;
74
+ }
75
+ render() {
76
+ return html `<slot @slotchange=${this.handleSlotChange}></slot>`;
77
+ }
78
+ firstUpdated() {
79
+ this.sync();
80
+ }
81
+ updated() {
82
+ this.sync();
83
+ }
84
+ get tabs() {
85
+ const list = this.querySelector(`.${TABS_LIST_CLASS}`);
86
+ return list ? [...list.querySelectorAll("button")] : [];
87
+ }
88
+ get panels() {
89
+ return [...this.querySelectorAll(`.${TABS_PANEL_CLASS}`)];
90
+ }
91
+ sync() {
92
+ const list = this.querySelector(`.${TABS_LIST_CLASS}`);
93
+ const tabs = this.tabs;
94
+ const panels = this.panels;
95
+ if (!list || tabs.length === 0)
96
+ return;
97
+ list.setAttribute("role", "tablist");
98
+ if (this.label)
99
+ list.setAttribute("aria-label", this.label);
100
+ // Er `selected` satt utenfor rekkevidde, rettes den her. Ellers ville
101
+ // attributtet sagt noe annet enn det brukeren ser.
102
+ const valid = Math.min(Math.max(this.selected, 0), tabs.length - 1);
103
+ if (valid !== this.selected)
104
+ this.selected = valid;
105
+ tabs.forEach((tab, index) => {
106
+ const panel = panels[index];
107
+ if (!tab.id)
108
+ tab.id = uniqueId("fs-tab");
109
+ if (panel && !panel.id)
110
+ panel.id = uniqueId("fs-tabpanel");
111
+ const isSelected = index === valid;
112
+ tab.setAttribute("role", "tab");
113
+ tab.setAttribute("type", "button");
114
+ tab.setAttribute("aria-selected", String(isSelected));
115
+ // Roving tabindex: bare den valgte fanen er en tabbestopp, så Tab går
116
+ // fra raden og rett inn i panelet.
117
+ tab.tabIndex = isSelected ? 0 : -1;
118
+ if (panel)
119
+ tab.setAttribute("aria-controls", panel.id);
120
+ tab.removeEventListener("click", this.handleClick);
121
+ tab.addEventListener("click", this.handleClick);
122
+ tab.removeEventListener("keydown", this.handleKeydown);
123
+ tab.addEventListener("keydown", this.handleKeydown);
124
+ if (panel) {
125
+ panel.setAttribute("role", "tabpanel");
126
+ panel.setAttribute("aria-labelledby", tab.id);
127
+ panel.hidden = !isSelected;
128
+ // Panelet får fokus når det ikke har noe å fokusere på selv, ellers
129
+ // hopper Tab rett forbi innholdet som nettopp ble vist.
130
+ panel.tabIndex = 0;
131
+ }
132
+ });
133
+ }
134
+ /** Velger en fane og melder fra. */
135
+ select(index) {
136
+ if (index === this.selected)
137
+ return;
138
+ this.selected = index;
139
+ this.sync();
140
+ this.dispatchEvent(new CustomEvent("tab-select", {
141
+ detail: { index },
142
+ bubbles: true,
143
+ composed: true,
144
+ }));
145
+ }
146
+ }
147
+ FsTabs.properties = {
148
+ selected: { type: Number, reflect: true },
149
+ label: { type: String },
150
+ };
151
+ export function defineFsTabs(tagName = FS_TABS_TAG) {
152
+ if (!customElements.get(tagName)) {
153
+ customElements.define(tagName, FsTabs);
154
+ }
155
+ }
156
+ //# sourceMappingURL=fs-tabs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs-tabs.js","sourceRoot":"","sources":["../../../../src/components/ramme/tabs/fs-tabs.ts"],"names":[],"mappings":"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"}
package/dist/dom.d.ts ADDED
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Å bruke attributtene på et element i vanlig DOM.
3
+ *
4
+ * I JSX sprer du objektet rett inn i elementet. Uten JSX måtte du løkke
5
+ * gjennom det selv, og passe på å fjerne attributter fra forrige tilstand.
6
+ * Går et felt fra ugyldig til gyldig, utelater byggeren `data-state`, og et
7
+ * `setAttribute` alene ville latt den gamle verdien bli stående.
8
+ */
9
+ /**
10
+ * Verdiene en byggefunksjon kan sende ut.
11
+ *
12
+ * `true` og `false` er med fordi flere av dem er boolske HTML-attributter:
13
+ * `disabled` på en bryter, `multiple` på et filfelt, `hidden` på en
14
+ * feilmelding. I HTML er et slikt attributt sant så lenge det finnes, uansett
15
+ * verdi, så `true` settes som tom streng og `false` fjerner det.
16
+ */
17
+ export type Attributes = Record<string, string | boolean | undefined>;
18
+ /**
19
+ * Setter attributtene fra en `fs`-funksjon på et element.
20
+ *
21
+ * ```ts
22
+ * import { fs } from "@fristil/designsystem"
23
+ *
24
+ * const felt = document.querySelector("input")
25
+ * fs.setAttributes(felt, fs.input({ type: "email", state: "invalid" }))
26
+ * ```
27
+ *
28
+ * Kall den på nytt for å endre tilstand. Attributter fra forrige kall som
29
+ * ikke er med i det nye settet, fjernes, men bare systemets egne, og bare
30
+ * `fs-`-klassene. Alt annet på elementet står som det står.
31
+ */
32
+ export declare function setAttributes(element: Element, attributes: Attributes): void;
33
+ //# sourceMappingURL=dom.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dom.d.ts","sourceRoot":"","sources":["../src/dom.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AA2BH;;;;;;;GAOG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,CAAA;AAErE;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,GAAG,IAAI,CAwB5E"}
package/dist/dom.js ADDED
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Å bruke attributtene på et element i vanlig DOM.
3
+ *
4
+ * I JSX sprer du objektet rett inn i elementet. Uten JSX måtte du løkke
5
+ * gjennom det selv, og passe på å fjerne attributter fra forrige tilstand.
6
+ * Går et felt fra ugyldig til gyldig, utelater byggeren `data-state`, og et
7
+ * `setAttribute` alene ville latt den gamle verdien bli stående.
8
+ */
9
+ /**
10
+ * Attributtene byggerne kan sende ut.
11
+ *
12
+ * Lista er lukket, og `setAttributes` rydder bare i disse. Konsumentens egne
13
+ * attributter, som `data-testid` og hva det måtte være, røres ikke.
14
+ */
15
+ const SYSTEM_ATTRIBUTES = [
16
+ "type",
17
+ "data-variant",
18
+ "data-state",
19
+ "data-color",
20
+ "data-required",
21
+ "data-optional",
22
+ "aria-invalid",
23
+ "aria-disabled",
24
+ "aria-describedby",
25
+ "disabled",
26
+ "multiple",
27
+ "accept",
28
+ "hidden",
29
+ ];
30
+ /** Klassene systemet eier. Konsumentens egne klasser beholdes. */
31
+ const IS_SYSTEM_CLASS = /^fs-/;
32
+ /**
33
+ * Setter attributtene fra en `fs`-funksjon på et element.
34
+ *
35
+ * ```ts
36
+ * import { fs } from "@fristil/designsystem"
37
+ *
38
+ * const felt = document.querySelector("input")
39
+ * fs.setAttributes(felt, fs.input({ type: "email", state: "invalid" }))
40
+ * ```
41
+ *
42
+ * Kall den på nytt for å endre tilstand. Attributter fra forrige kall som
43
+ * ikke er med i det nye settet, fjernes, men bare systemets egne, og bare
44
+ * `fs-`-klassene. Alt annet på elementet står som det står.
45
+ */
46
+ export function setAttributes(element, attributes) {
47
+ const newClass = attributes.class;
48
+ if (typeof newClass === "string") {
49
+ const ownClasses = [...element.classList].filter((klasse) => !IS_SYSTEM_CLASS.test(klasse));
50
+ element.className = [...new Set([...newClass.split(/\s+/), ...ownClasses])]
51
+ .filter(Boolean)
52
+ .join(" ");
53
+ }
54
+ for (const name of SYSTEM_ATTRIBUTES) {
55
+ setOrRemove(element, name, attributes[name]);
56
+ }
57
+ // Attributter utenfor den lukkede lista settes, men ryddes aldri bort.
58
+ // Systemet kan ikke vite om de er dets egne.
59
+ for (const [name, value] of Object.entries(attributes)) {
60
+ if (name === "class")
61
+ continue;
62
+ if (SYSTEM_ATTRIBUTES.includes(name))
63
+ continue;
64
+ if (value === undefined || value === false)
65
+ continue;
66
+ element.setAttribute(name, value === true ? "" : value);
67
+ }
68
+ }
69
+ function setOrRemove(element, name, value) {
70
+ if (value === undefined || value === false) {
71
+ element.removeAttribute(name);
72
+ }
73
+ else {
74
+ element.setAttribute(name, value === true ? "" : value);
75
+ }
76
+ }
77
+ //# sourceMappingURL=dom.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dom.js","sourceRoot":"","sources":["../src/dom.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;;GAKG;AACH,MAAM,iBAAiB,GAAG;IACxB,MAAM;IACN,cAAc;IACd,YAAY;IACZ,YAAY;IACZ,eAAe;IACf,eAAe;IACf,cAAc;IACd,eAAe;IACf,kBAAkB;IAClB,UAAU;IACV,UAAU;IACV,QAAQ;IACR,QAAQ;CACA,CAAA;AAEV,kEAAkE;AAClE,MAAM,eAAe,GAAG,MAAM,CAAA;AAY9B;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,aAAa,CAAC,OAAgB,EAAE,UAAsB;IACpE,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAA;IAEjC,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjC,MAAM,UAAU,GAAG,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,MAAM,CAC9C,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAC1C,CAAA;QACD,OAAO,CAAC,SAAS,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,GAAG,UAAU,CAAC,CAAC,CAAC;aACxE,MAAM,CAAC,OAAO,CAAC;aACf,IAAI,CAAC,GAAG,CAAC,CAAA;IACd,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,iBAAiB,EAAE,CAAC;QACrC,WAAW,CAAC,OAAO,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,CAAA;IAC9C,CAAC;IAED,uEAAuE;IACvE,6CAA6C;IAC7C,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QACvD,IAAI,IAAI,KAAK,OAAO;YAAE,SAAQ;QAC9B,IAAK,iBAAuC,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,SAAQ;QACrE,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,KAAK;YAAE,SAAQ;QACpD,OAAO,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;IACzD,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAClB,OAAgB,EAChB,IAAY,EACZ,KAAmC;IAEnC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,KAAK,EAAE,CAAC;QAC3C,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,CAAA;IAC/B,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;IACzD,CAAC;AACH,CAAC"}