@fristil/designsystem 0.3.0 → 0.5.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 (116) hide show
  1. package/CHANGELOG.md +121 -0
  2. package/README.md +22 -9
  3. package/dist/components/frittstaende/connection-status/connection-status.d.ts +28 -0
  4. package/dist/components/frittstaende/connection-status/connection-status.d.ts.map +1 -0
  5. package/dist/components/frittstaende/connection-status/connection-status.js +22 -0
  6. package/dist/components/frittstaende/connection-status/connection-status.js.map +1 -0
  7. package/dist/components/frittstaende/connection-status/fs-connection-status.d.ts +54 -0
  8. package/dist/components/frittstaende/connection-status/fs-connection-status.d.ts.map +1 -0
  9. package/dist/components/frittstaende/connection-status/fs-connection-status.js +123 -0
  10. package/dist/components/frittstaende/connection-status/fs-connection-status.js.map +1 -0
  11. package/dist/components/frittstaende/session-timeout/fs-session-timeout.d.ts +56 -0
  12. package/dist/components/frittstaende/session-timeout/fs-session-timeout.d.ts.map +1 -0
  13. package/dist/components/frittstaende/session-timeout/fs-session-timeout.js +179 -0
  14. package/dist/components/frittstaende/session-timeout/fs-session-timeout.js.map +1 -0
  15. package/dist/components/frittstaende/session-timeout/session-timeout.d.ts +28 -0
  16. package/dist/components/frittstaende/session-timeout/session-timeout.d.ts.map +1 -0
  17. package/dist/components/frittstaende/session-timeout/session-timeout.js +22 -0
  18. package/dist/components/frittstaende/session-timeout/session-timeout.js.map +1 -0
  19. package/dist/components/frittstaende/toast/fs-toast.d.ts +16 -22
  20. package/dist/components/frittstaende/toast/fs-toast.d.ts.map +1 -1
  21. package/dist/components/frittstaende/toast/fs-toast.js +38 -27
  22. package/dist/components/frittstaende/toast/fs-toast.js.map +1 -1
  23. package/dist/components/frittstaende/toast/toast.d.ts +34 -0
  24. package/dist/components/frittstaende/toast/toast.d.ts.map +1 -0
  25. package/dist/components/frittstaende/toast/toast.js +26 -0
  26. package/dist/components/frittstaende/toast/toast.js.map +1 -0
  27. package/dist/components/ramme/error-summary/error-summary.d.ts +39 -0
  28. package/dist/components/ramme/error-summary/error-summary.d.ts.map +1 -0
  29. package/dist/components/ramme/error-summary/error-summary.js +31 -0
  30. package/dist/components/ramme/error-summary/error-summary.js.map +1 -0
  31. package/dist/components/ramme/error-summary/fs-error-summary.d.ts +16 -42
  32. package/dist/components/ramme/error-summary/fs-error-summary.d.ts.map +1 -1
  33. package/dist/components/ramme/error-summary/fs-error-summary.js +57 -92
  34. package/dist/components/ramme/error-summary/fs-error-summary.js.map +1 -1
  35. package/dist/components/ramme/field/field-core.d.ts +31 -0
  36. package/dist/components/ramme/field/field-core.d.ts.map +1 -1
  37. package/dist/components/ramme/field/field-core.js +31 -0
  38. package/dist/components/ramme/field/field-core.js.map +1 -1
  39. package/dist/components/ramme/field/fs-field.d.ts +38 -40
  40. package/dist/components/ramme/field/fs-field.d.ts.map +1 -1
  41. package/dist/components/ramme/field/fs-field.js +127 -54
  42. package/dist/components/ramme/field/fs-field.js.map +1 -1
  43. package/dist/components/ramme/popover/fs-popover.d.ts +20 -27
  44. package/dist/components/ramme/popover/fs-popover.d.ts.map +1 -1
  45. package/dist/components/ramme/popover/fs-popover.js +68 -54
  46. package/dist/components/ramme/popover/fs-popover.js.map +1 -1
  47. package/dist/components/ramme/popover/popover.d.ts +43 -0
  48. package/dist/components/ramme/popover/popover.d.ts.map +1 -0
  49. package/dist/components/ramme/popover/popover.js +49 -0
  50. package/dist/components/ramme/popover/popover.js.map +1 -0
  51. package/dist/components/ramme/suggestion/fs-suggestion.d.ts +75 -0
  52. package/dist/components/ramme/suggestion/fs-suggestion.d.ts.map +1 -0
  53. package/dist/components/ramme/suggestion/fs-suggestion.js +232 -0
  54. package/dist/components/ramme/suggestion/fs-suggestion.js.map +1 -0
  55. package/dist/components/ramme/suggestion/suggestion.d.ts +97 -0
  56. package/dist/components/ramme/suggestion/suggestion.d.ts.map +1 -0
  57. package/dist/components/ramme/suggestion/suggestion.js +79 -0
  58. package/dist/components/ramme/suggestion/suggestion.js.map +1 -0
  59. package/dist/components/ramme/tabs/fs-tabs.d.ts +31 -36
  60. package/dist/components/ramme/tabs/fs-tabs.d.ts.map +1 -1
  61. package/dist/components/ramme/tabs/fs-tabs.js +62 -84
  62. package/dist/components/ramme/tabs/fs-tabs.js.map +1 -1
  63. package/dist/components/ramme/tabs/tabs.d.ts +50 -0
  64. package/dist/components/ramme/tabs/tabs.d.ts.map +1 -0
  65. package/dist/components/ramme/tabs/tabs.js +54 -0
  66. package/dist/components/ramme/tabs/tabs.js.map +1 -0
  67. package/dist/fs.d.ts +94 -0
  68. package/dist/fs.d.ts.map +1 -1
  69. package/dist/fs.js +42 -0
  70. package/dist/fs.js.map +1 -1
  71. package/dist/index.d.ts +10 -3
  72. package/dist/index.d.ts.map +1 -1
  73. package/dist/index.js +10 -3
  74. package/dist/index.js.map +1 -1
  75. package/dist/jsx/react.d.ts +35 -50
  76. package/dist/jsx/react.d.ts.map +1 -1
  77. package/dist/react.d.ts +142 -1
  78. package/dist/react.d.ts.map +1 -1
  79. package/dist/react.js +71 -2
  80. package/dist/react.js.map +1 -1
  81. package/package.json +16 -25
  82. package/src/components/frittstaende/connection-status/connection-status.css +33 -0
  83. package/src/components/frittstaende/connection-status/connection-status.ts +41 -0
  84. package/src/components/frittstaende/connection-status/fs-connection-status.ts +144 -0
  85. package/src/components/frittstaende/session-timeout/fs-session-timeout.ts +212 -0
  86. package/src/components/frittstaende/session-timeout/session-timeout.css +43 -0
  87. package/src/components/frittstaende/session-timeout/session-timeout.ts +42 -0
  88. package/src/components/frittstaende/toast/fs-toast.ts +39 -30
  89. package/src/components/frittstaende/toast/toast.ts +45 -0
  90. package/src/components/ramme/error-summary/error-summary.ts +55 -0
  91. package/src/components/ramme/error-summary/fs-error-summary.ts +62 -119
  92. package/src/components/ramme/field/field-core.ts +32 -0
  93. package/src/components/ramme/field/fs-field.ts +144 -61
  94. package/src/components/ramme/popover/fs-popover.ts +78 -72
  95. package/src/components/ramme/popover/popover.ts +79 -0
  96. package/src/components/ramme/suggestion/fs-suggestion.ts +265 -0
  97. package/src/components/ramme/suggestion/suggestion.ts +105 -0
  98. package/src/components/ramme/tabs/fs-tabs.ts +67 -98
  99. package/src/components/ramme/tabs/tabs.ts +104 -0
  100. package/dist/components/frittstaende/calendar/fs-calendar.d.ts +0 -52
  101. package/dist/components/frittstaende/calendar/fs-calendar.d.ts.map +0 -1
  102. package/dist/components/frittstaende/calendar/fs-calendar.js +0 -462
  103. package/dist/components/frittstaende/calendar/fs-calendar.js.map +0 -1
  104. package/dist/components/frittstaende/date-field/fs-date-field.d.ts +0 -110
  105. package/dist/components/frittstaende/date-field/fs-date-field.d.ts.map +0 -1
  106. package/dist/components/frittstaende/date-field/fs-date-field.js +0 -264
  107. package/dist/components/frittstaende/date-field/fs-date-field.js.map +0 -1
  108. package/dist/components/frittstaende/suggestion/fs-suggestion.d.ts +0 -133
  109. package/dist/components/frittstaende/suggestion/fs-suggestion.d.ts.map +0 -1
  110. package/dist/components/frittstaende/suggestion/fs-suggestion.js +0 -280
  111. package/dist/components/frittstaende/suggestion/fs-suggestion.js.map +0 -1
  112. package/src/components/frittstaende/calendar/fs-calendar.ts +0 -525
  113. package/src/components/frittstaende/date-field/date-field.css +0 -54
  114. package/src/components/frittstaende/date-field/fs-date-field.ts +0 -309
  115. package/src/components/frittstaende/suggestion/fs-suggestion.ts +0 -333
  116. /package/src/components/{frittstaende → ramme}/suggestion/suggestion.css +0 -0
@@ -0,0 +1,232 @@
1
+ import { SUGGESTION_EMPTY_CLASS, SUGGESTION_OPTION_CLASS, } from "./suggestion.js";
2
+ export const FS_SUGGESTION_TAG = "fs-suggestion";
3
+ /**
4
+ * Tastaturet og filtreringen i et felt med forslagsliste.
5
+ *
6
+ * Serveren skriver feltet og lista med `fs.suggestion()`. Komponenten rendrer
7
+ * ingenting. Den lagde tidligere hele feltet selv, og da fantes det verken
8
+ * ledetekst eller inndatafelt før skriptet hadde kjørt, og ingenting ble med
9
+ * i innsendingen.
10
+ *
11
+ * Det komponenten gjør er det nettleseren ikke gjør: filtrerer alternativene
12
+ * mens brukeren skriver, flytter markeringen med piltastene, og holder
13
+ * `aria-activedescendant` i synk slik at skjermleseren leser opp alternativet
14
+ * uten at fokus forlater feltet.
15
+ *
16
+ * Patcher serveren lista selv, som i en Datastar-app, slår filtreringen seg
17
+ * av: da er det serveren som bestemmer hva som vises.
18
+ *
19
+ * ```html
20
+ * <fs-suggestion>
21
+ * <label class="fs-label" for="kommune">Kommune</label>
22
+ * <div class="fs-suggestion__field">
23
+ * <input class="fs-input" id="kommune" role="combobox" aria-controls="kommune-list"
24
+ * aria-expanded="false" data-preserve-attr="aria-expanded aria-activedescendant">
25
+ * <ul class="fs-suggestion__list" id="kommune-list" role="listbox" hidden
26
+ * data-preserve-attr="hidden">
27
+ * <li class="fs-suggestion__option" id="kommune-option-0" role="option">Bergen</li>
28
+ * </ul>
29
+ * </div>
30
+ * </fs-suggestion>
31
+ * ```
32
+ */
33
+ export class FsSuggestion extends HTMLElement {
34
+ constructor() {
35
+ super(...arguments);
36
+ this.activeIndex = -1;
37
+ /** Alternativene som alt har fått lytteren sin. */
38
+ this.bundne = new WeakSet();
39
+ /** Sant mens komponenten selv sender hendelser, så den ikke svarer seg selv. */
40
+ this.choosing = false;
41
+ this.handleInput = () => {
42
+ if (this.choosing)
43
+ return;
44
+ this.filter();
45
+ this.setOpen(true);
46
+ };
47
+ this.handleFocus = () => {
48
+ this.filter();
49
+ this.setOpen(true);
50
+ };
51
+ this.handleKeydown = (event) => {
52
+ const åpen = this.listElement?.hidden === false;
53
+ if (event.key === "ArrowDown") {
54
+ event.preventDefault();
55
+ if (!åpen) {
56
+ this.filter();
57
+ this.setOpen(true);
58
+ }
59
+ this.markActive(this.activeIndex + 1);
60
+ }
61
+ else if (event.key === "ArrowUp") {
62
+ event.preventDefault();
63
+ this.markActive(this.activeIndex - 1);
64
+ }
65
+ else if (event.key === "Enter" && åpen && this.activeIndex >= 0) {
66
+ event.preventDefault();
67
+ const valgt = this.visible[this.activeIndex];
68
+ if (valgt)
69
+ this.choose(valgt);
70
+ }
71
+ else if (event.key === "Escape" && åpen) {
72
+ event.preventDefault();
73
+ this.setOpen(false);
74
+ }
75
+ };
76
+ this.handleOptionMouseDown = (event) => {
77
+ // mousedown og ikke click: feltet mister ellers fokus før valget rekker
78
+ // å skje, og lista lukker seg først.
79
+ event.preventDefault();
80
+ this.choose(event.currentTarget);
81
+ };
82
+ this.handleOutsideClick = (event) => {
83
+ if (this.contains(event.target))
84
+ return;
85
+ this.setOpen(false);
86
+ };
87
+ }
88
+ connectedCallback() {
89
+ this.observer = new MutationObserver(() => this.bind());
90
+ this.observer.observe(this, { childList: true, subtree: true });
91
+ this.bind();
92
+ document.addEventListener("click", this.handleOutsideClick, true);
93
+ }
94
+ disconnectedCallback() {
95
+ document.removeEventListener("click", this.handleOutsideClick, true);
96
+ this.observer?.disconnect();
97
+ this.observer = undefined;
98
+ this.unbind();
99
+ }
100
+ /** Slår av filtreringen på klienten. Da er det serveren som bestemmer. */
101
+ get serverFiltered() {
102
+ return this.hasAttribute("server-filtered");
103
+ }
104
+ get listElement() {
105
+ return this.querySelector("[role='listbox']");
106
+ }
107
+ get options() {
108
+ return [
109
+ ...this.querySelectorAll(`.${SUGGESTION_OPTION_CLASS}`),
110
+ ];
111
+ }
112
+ /** Alternativene som er synlige nå. */
113
+ get visible() {
114
+ return this.options.filter((option) => !option.hidden);
115
+ }
116
+ unbind() {
117
+ const control = this.control;
118
+ if (!control)
119
+ return;
120
+ control.removeEventListener("input", this.handleInput);
121
+ control.removeEventListener("keydown", this.handleKeydown);
122
+ control.removeEventListener("focus", this.handleFocus);
123
+ this.control = undefined;
124
+ }
125
+ bind() {
126
+ const control = this.querySelector("[role='combobox']");
127
+ if (!control)
128
+ return;
129
+ if (control !== this.control) {
130
+ this.unbind();
131
+ control.addEventListener("input", this.handleInput);
132
+ control.addEventListener("keydown", this.handleKeydown);
133
+ control.addEventListener("focus", this.handleFocus);
134
+ this.control = control;
135
+ }
136
+ // Alternativene byttes ut uavhengig av feltet: i en Datastar-app sender
137
+ // serveren en ny liste mens brukeren skriver. Lå dette bak sjekken over,
138
+ // fikk de nye alternativene aldri lytteren sin, og valg med mus sluttet
139
+ // å virke etter første oppdatering.
140
+ for (const option of this.options) {
141
+ if (this.bundne.has(option))
142
+ continue;
143
+ option.addEventListener("mousedown", this.handleOptionMouseDown);
144
+ this.bundne.add(option);
145
+ }
146
+ }
147
+ setOpen(open) {
148
+ const list = this.listElement;
149
+ if (!list || !this.control)
150
+ return;
151
+ list.hidden = !open;
152
+ this.control.setAttribute("aria-expanded", String(open));
153
+ if (!open) {
154
+ this.activeIndex = -1;
155
+ this.control.removeAttribute("aria-activedescendant");
156
+ for (const option of this.options) {
157
+ option.setAttribute("aria-selected", "false");
158
+ }
159
+ }
160
+ }
161
+ filter() {
162
+ if (this.serverFiltered)
163
+ return;
164
+ const query = (this.control?.value ?? "").trim().toLowerCase();
165
+ for (const option of this.options) {
166
+ const label = (option.textContent ?? "").trim().toLowerCase();
167
+ option.hidden = query !== "" && !label.includes(query);
168
+ }
169
+ const treff = this.visible.length;
170
+ const empty = this.querySelector(`.${SUGGESTION_EMPTY_CLASS}`);
171
+ if (empty)
172
+ empty.hidden = treff > 0;
173
+ this.announce(treff);
174
+ }
175
+ /**
176
+ * Melder antall treff.
177
+ *
178
+ * Uten dette får den som ikke ser skjermen ingen beskjed om at lista
179
+ * snevret seg inn mens hun skrev. Teksten er klientgenerert, så elementet
180
+ * har `data-ignore-morph` fra byggeren.
181
+ */
182
+ announce(treff) {
183
+ const status = this.querySelector("[role='status']");
184
+ if (!status)
185
+ return;
186
+ const tekst = treff === 0 ? "Ingen treff" : treff === 1 ? "Ett treff" : `${treff} treff`;
187
+ if (status.textContent !== tekst)
188
+ status.textContent = tekst;
189
+ }
190
+ markActive(index) {
191
+ const synlige = this.visible;
192
+ if (synlige.length === 0 || !this.control)
193
+ return;
194
+ const neste = (index + synlige.length) % synlige.length;
195
+ this.activeIndex = neste;
196
+ for (const option of this.options) {
197
+ option.setAttribute("aria-selected", "false");
198
+ }
199
+ const aktiv = synlige[neste];
200
+ aktiv.setAttribute("aria-selected", "true");
201
+ // aria-activedescendant flytter skjermleserens lesepunkt uten at fokus
202
+ // forlater feltet. Uten den leses alternativet aldri opp.
203
+ this.control.setAttribute("aria-activedescendant", aktiv.id);
204
+ aktiv.scrollIntoView({ block: "nearest" });
205
+ }
206
+ choose(option) {
207
+ if (!this.control)
208
+ return;
209
+ const value = option.getAttribute("data-value") ?? (option.textContent ?? "").trim();
210
+ this.control.value = value;
211
+ // Flagget må stå før hendelsene sendes. `input` er den samme hendelsen
212
+ // komponenten selv lytter på, så uten dette åpner lista seg igjen i det
213
+ // øyeblikket brukeren har valgt noe.
214
+ this.choosing = true;
215
+ this.control.dispatchEvent(new Event("input", { bubbles: true }));
216
+ this.control.dispatchEvent(new Event("change", { bubbles: true }));
217
+ this.choosing = false;
218
+ this.setOpen(false);
219
+ this.dispatchEvent(new CustomEvent("suggestion-select", {
220
+ detail: { value },
221
+ bubbles: true,
222
+ composed: true,
223
+ }));
224
+ }
225
+ }
226
+ FsSuggestion.observedAttributes = ["server-filtered"];
227
+ export function defineFsSuggestion(tagName = FS_SUGGESTION_TAG) {
228
+ if (!customElements.get(tagName)) {
229
+ customElements.define(tagName, FsSuggestion);
230
+ }
231
+ }
232
+ //# sourceMappingURL=fs-suggestion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs-suggestion.js","sourceRoot":"","sources":["../../../../src/components/ramme/suggestion/fs-suggestion.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,97 @@
1
+ import { type FieldOptions } from "../field/field-core.js";
2
+ export declare const SUGGESTION_CLASS: "fs-suggestion";
3
+ export declare const SUGGESTION_FIELD_CLASS: "fs-suggestion__field";
4
+ export declare const SUGGESTION_LIST_CLASS: "fs-suggestion__list";
5
+ export declare const SUGGESTION_OPTION_CLASS: "fs-suggestion__option";
6
+ export declare const SUGGESTION_EMPTY_CLASS: "fs-suggestion__empty";
7
+ export declare const SUGGESTION_STATUS_CLASS: "fs-sr-only";
8
+ export type SuggestionOptions = Omit<FieldOptions, "id"> & {
9
+ /** Felles id-stamme. Kontrollen blir `${id}`, lista `${id}-list`. */
10
+ id: string;
11
+ /** Antall alternativer serveren sender med. Standard: 0. */
12
+ count?: number;
13
+ /** Alternativet som er markert med piltastene. Standard: ingen. */
14
+ activeIndex?: number;
15
+ /** Lista er åpen. Standard: lukket. */
16
+ open?: boolean;
17
+ };
18
+ /**
19
+ * Attributtene for et felt med forslagsliste.
20
+ *
21
+ * Serveren skriver både feltet og lista. Komponenten filtrerer, tar
22
+ * piltastene og holder `aria-activedescendant` i synk. Den rendrer ingenting:
23
+ * tidligere lagde den hele feltet selv, og da fantes det ikke noe å fylle ut
24
+ * før skriptet hadde kjørt.
25
+ *
26
+ * Attributtene som endrer seg mens brukeren skriver står i
27
+ * `data-preserve-attr`, ellers river Datastars morfing dem bort.
28
+ */
29
+ export declare const suggestion: ({ id, count, activeIndex, open, ...field }: SuggestionOptions) => {
30
+ label: {
31
+ class: "fs-label";
32
+ for: string;
33
+ "data-required"?: import("../../css/shared.js").RequiredMarker;
34
+ "data-optional"?: "";
35
+ "aria-disabled"?: "true";
36
+ };
37
+ field: {
38
+ class: "fs-suggestion__field";
39
+ };
40
+ control: {
41
+ class: "fs-input";
42
+ type: "text";
43
+ role: "combobox";
44
+ autocomplete: "off";
45
+ "aria-expanded": "true" | "false";
46
+ "aria-controls": string;
47
+ "aria-describedby": string;
48
+ "aria-autocomplete": "list";
49
+ "aria-activedescendant": string | undefined;
50
+ "data-preserve-attr": "aria-expanded aria-activedescendant";
51
+ id: string;
52
+ "aria-invalid"?: "true";
53
+ "data-state"?: "invalid";
54
+ disabled?: true;
55
+ };
56
+ list: {
57
+ class: "fs-suggestion__list";
58
+ id: string;
59
+ role: "listbox";
60
+ hidden: true | undefined;
61
+ "data-preserve-attr": "hidden";
62
+ };
63
+ options: {
64
+ class: "fs-suggestion__option";
65
+ id: string;
66
+ role: "option";
67
+ "aria-selected": "true" | "false";
68
+ "data-preserve-attr": "aria-selected hidden";
69
+ }[];
70
+ empty: {
71
+ class: "fs-suggestion__empty";
72
+ };
73
+ /**
74
+ * Området som melder antall treff til skjermlesere.
75
+ *
76
+ * Teksten skrives av komponenten mens brukeren taster, så den finnes ikke
77
+ * i serverens utgave. `data-ignore-morph` hindrer at neste patch tømmer
78
+ * den. Elementet må likevel stå i markupen serveren sender, ellers finnes
79
+ * det ikke noe å melde i før skriptet har kjørt.
80
+ */
81
+ status: {
82
+ class: "fs-sr-only";
83
+ id: string;
84
+ role: "status";
85
+ "aria-live": "polite";
86
+ "data-ignore-morph": "";
87
+ };
88
+ help: {
89
+ id: string;
90
+ };
91
+ error: {
92
+ id: string;
93
+ hidden?: true;
94
+ };
95
+ state: "default" | "success" | "invalid";
96
+ };
97
+ //# sourceMappingURL=suggestion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"suggestion.d.ts","sourceRoot":"","sources":["../../../../src/components/ramme/suggestion/suggestion.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,YAAY,EAClB,MAAM,wBAAwB,CAAA;AAE/B,eAAO,MAAM,gBAAgB,EAAG,eAAwB,CAAA;AACxD,eAAO,MAAM,sBAAsB,EAAG,sBAA+B,CAAA;AACrE,eAAO,MAAM,qBAAqB,EAAG,qBAA8B,CAAA;AACnE,eAAO,MAAM,uBAAuB,EAAG,uBAAgC,CAAA;AACvE,eAAO,MAAM,sBAAsB,EAAG,sBAA+B,CAAA;AACrE,eAAO,MAAM,uBAAuB,EAAG,YAAqB,CAAA;AAE5D,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,GAAG;IACzD,qEAAqE;IACrE,EAAE,EAAE,MAAM,CAAA;IACV,4DAA4D;IAC5D,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,mEAAmE;IACnE,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,uCAAuC;IACvC,IAAI,CAAC,EAAE,OAAO,CAAA;CACf,CAAA;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,UAAU,GAAI,4CAMxB,iBAAiB;;;;;;;;;;;;;;;;yBAgBgC,MAAM,GAAG,OAAO;;;;;;;;;;;;;;;;;;;;;;yBAsBxD,MAAM,GACN,OAAO;;;;;;IAKf;;;;;;;OAOG;;;;;;;;;;;;;;;;CAYN,CAAA"}
@@ -0,0 +1,79 @@
1
+ import { attributes } from "../../css/shared.js";
2
+ import { computeFieldAttributes, } from "../field/field-core.js";
3
+ export const SUGGESTION_CLASS = "fs-suggestion";
4
+ export const SUGGESTION_FIELD_CLASS = "fs-suggestion__field";
5
+ export const SUGGESTION_LIST_CLASS = "fs-suggestion__list";
6
+ export const SUGGESTION_OPTION_CLASS = "fs-suggestion__option";
7
+ export const SUGGESTION_EMPTY_CLASS = "fs-suggestion__empty";
8
+ export const SUGGESTION_STATUS_CLASS = "fs-sr-only";
9
+ /**
10
+ * Attributtene for et felt med forslagsliste.
11
+ *
12
+ * Serveren skriver både feltet og lista. Komponenten filtrerer, tar
13
+ * piltastene og holder `aria-activedescendant` i synk. Den rendrer ingenting:
14
+ * tidligere lagde den hele feltet selv, og da fantes det ikke noe å fylle ut
15
+ * før skriptet hadde kjørt.
16
+ *
17
+ * Attributtene som endrer seg mens brukeren skriver står i
18
+ * `data-preserve-attr`, ellers river Datastars morfing dem bort.
19
+ */
20
+ export const suggestion = ({ id, count = 0, activeIndex = -1, open = false, ...field }) => {
21
+ const computed = computeFieldAttributes({ ...field, id });
22
+ const listId = `${id}-list`;
23
+ const statusId = `${id}-status`;
24
+ const optionId = (index) => `${id}-option-${index}`;
25
+ const aktiv = open && activeIndex >= 0 && activeIndex < count;
26
+ return {
27
+ label: computed.label,
28
+ field: { class: SUGGESTION_FIELD_CLASS },
29
+ control: attributes({
30
+ ...computed.control,
31
+ class: "fs-input",
32
+ type: "text",
33
+ role: "combobox",
34
+ autocomplete: "off",
35
+ "aria-expanded": (open ? "true" : "false"),
36
+ "aria-controls": listId,
37
+ "aria-describedby": [computed.control["aria-describedby"], statusId]
38
+ .filter(Boolean)
39
+ .join(" "),
40
+ "aria-autocomplete": "list",
41
+ "aria-activedescendant": aktiv ? optionId(activeIndex) : undefined,
42
+ "data-preserve-attr": "aria-expanded aria-activedescendant",
43
+ }),
44
+ list: attributes({
45
+ class: SUGGESTION_LIST_CLASS,
46
+ id: listId,
47
+ role: "listbox",
48
+ hidden: open ? undefined : true,
49
+ "data-preserve-attr": "hidden",
50
+ }),
51
+ options: Array.from({ length: count }, (_, index) => attributes({
52
+ class: SUGGESTION_OPTION_CLASS,
53
+ id: optionId(index),
54
+ role: "option",
55
+ "aria-selected": (index === activeIndex ? "true" : "false"),
56
+ "data-preserve-attr": "aria-selected hidden",
57
+ })),
58
+ empty: { class: SUGGESTION_EMPTY_CLASS },
59
+ /**
60
+ * Området som melder antall treff til skjermlesere.
61
+ *
62
+ * Teksten skrives av komponenten mens brukeren taster, så den finnes ikke
63
+ * i serverens utgave. `data-ignore-morph` hindrer at neste patch tømmer
64
+ * den. Elementet må likevel stå i markupen serveren sender, ellers finnes
65
+ * det ikke noe å melde i før skriptet har kjørt.
66
+ */
67
+ status: {
68
+ class: SUGGESTION_STATUS_CLASS,
69
+ id: statusId,
70
+ role: "status",
71
+ "aria-live": "polite",
72
+ "data-ignore-morph": "",
73
+ },
74
+ help: computed.help,
75
+ error: computed.error,
76
+ state: computed.state,
77
+ };
78
+ };
79
+ //# sourceMappingURL=suggestion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"suggestion.js","sourceRoot":"","sources":["../../../../src/components/ramme/suggestion/suggestion.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAChD,OAAO,EACL,sBAAsB,GAEvB,MAAM,wBAAwB,CAAA;AAE/B,MAAM,CAAC,MAAM,gBAAgB,GAAG,eAAwB,CAAA;AACxD,MAAM,CAAC,MAAM,sBAAsB,GAAG,sBAA+B,CAAA;AACrE,MAAM,CAAC,MAAM,qBAAqB,GAAG,qBAA8B,CAAA;AACnE,MAAM,CAAC,MAAM,uBAAuB,GAAG,uBAAgC,CAAA;AACvE,MAAM,CAAC,MAAM,sBAAsB,GAAG,sBAA+B,CAAA;AACrE,MAAM,CAAC,MAAM,uBAAuB,GAAG,YAAqB,CAAA;AAa5D;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,EACzB,EAAE,EACF,KAAK,GAAG,CAAC,EACT,WAAW,GAAG,CAAC,CAAC,EAChB,IAAI,GAAG,KAAK,EACZ,GAAG,KAAK,EACU,EAAE,EAAE;IACtB,MAAM,QAAQ,GAAG,sBAAsB,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,EAAE,CAAC,CAAA;IACzD,MAAM,MAAM,GAAG,GAAG,EAAE,OAAO,CAAA;IAC3B,MAAM,QAAQ,GAAG,GAAG,EAAE,SAAS,CAAA;IAC/B,MAAM,QAAQ,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,EAAE,CAAA;IAC3D,MAAM,KAAK,GAAG,IAAI,IAAI,WAAW,IAAI,CAAC,IAAI,WAAW,GAAG,KAAK,CAAA;IAE7D,OAAO;QACL,KAAK,EAAE,QAAQ,CAAC,KAAK;QACrB,KAAK,EAAE,EAAE,KAAK,EAAE,sBAAsB,EAAE;QACxC,OAAO,EAAE,UAAU,CAAC;YAClB,GAAG,QAAQ,CAAC,OAAO;YACnB,KAAK,EAAE,UAAmB;YAC1B,IAAI,EAAE,MAAe;YACrB,IAAI,EAAE,UAAmB;YACzB,YAAY,EAAE,KAAc;YAC5B,eAAe,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAqB;YAC9D,eAAe,EAAE,MAAM;YACvB,kBAAkB,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE,QAAQ,CAAC;iBACjE,MAAM,CAAC,OAAO,CAAC;iBACf,IAAI,CAAC,GAAG,CAAC;YACZ,mBAAmB,EAAE,MAAe;YACpC,uBAAuB,EAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS;YAClE,oBAAoB,EAAE,qCAA8C;SACrE,CAAC;QACF,IAAI,EAAE,UAAU,CAAC;YACf,KAAK,EAAE,qBAAqB;YAC5B,EAAE,EAAE,MAAM;YACV,IAAI,EAAE,SAAkB;YACxB,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAE,IAAc;YAC1C,oBAAoB,EAAE,QAAiB;SACxC,CAAC;QACF,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAClD,UAAU,CAAC;YACT,KAAK,EAAE,uBAAuB;YAC9B,EAAE,EAAE,QAAQ,CAAC,KAAK,CAAC;YACnB,IAAI,EAAE,QAAiB;YACvB,eAAe,EAAE,CAAC,KAAK,KAAK,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAE/C;YACX,oBAAoB,EAAE,sBAA+B;SACtD,CAAC,CACH;QACD,KAAK,EAAE,EAAE,KAAK,EAAE,sBAAsB,EAAE;QACxC;;;;;;;WAOG;QACH,MAAM,EAAE;YACN,KAAK,EAAE,uBAAuB;YAC9B,EAAE,EAAE,QAAQ;YACZ,IAAI,EAAE,QAAiB;YACvB,WAAW,EAAE,QAAiB;YAC9B,mBAAmB,EAAE,EAAW;SACjC;QACD,IAAI,EAAE,QAAQ,CAAC,IAAI;QACnB,KAAK,EAAE,QAAQ,CAAC,KAAK;QACrB,KAAK,EAAE,QAAQ,CAAC,KAAK;KACtB,CAAA;AACH,CAAC,CAAA"}
@@ -1,52 +1,47 @@
1
- import { LitElement } from "lit";
2
1
  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
2
  /**
6
- * Kobler en rad med knapper til panelene de hører til.
3
+ * Tastaturet i en fanerad.
7
4
  *
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.
5
+ * Serveren skriver rollene, `aria-controls` og `hidden` med `fs.tabs()`.
6
+ * Gjorde komponenten det, ville alle panelene vises til skriptet hadde kjørt,
7
+ * og innholdet hoppe når panelene skjulte seg selv. I en Datastar-app ville
8
+ * de dessuten komme tilbake ved hver patch.
11
9
  *
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».
10
+ * Det komponenten gjør er det nettleseren ikke gjør selv: Tab hopper forbi
11
+ * hele raden og inn i panelet, mens piltastene flytter mellom fanene. Et sett
12
+ * knapper uten dette gir én tabbestopp per fane, og skjermleseren sier
13
+ * «knapp» der den skulle sagt «fane, 2 av 3, valgt».
14
+ *
15
+ * Attributtene som endrer seg når brukeren velger, altså `aria-selected`,
16
+ * `tabindex` og `hidden`, står i `data-preserve-attr` fra byggeren.
16
17
  *
17
18
  * ```html
18
19
  * <fs-tabs>
19
- * <div class="fs-tabs__list">
20
- * <button>Søknaden</button>
21
- * <button>Vedlegg</button>
20
+ * <div class="fs-tabs__list" role="tablist">
21
+ * <button id="sak-tab-0" role="tab" aria-selected="true" aria-controls="sak-panel-0"
22
+ * tabindex="0" data-preserve-attr="aria-selected tabindex">Søknaden</button>
22
23
  * </div>
23
- * <div class="fs-tabs__panel">…</div>
24
- * <div class="fs-tabs__panel">…</div>
24
+ * <div id="sak-panel-0" class="fs-tabs__panel" role="tabpanel"
25
+ * aria-labelledby="sak-tab-0" tabindex="0" data-preserve-attr="hidden">…</div>
25
26
  * </fs-tabs>
26
27
  * ```
27
28
  */
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;
29
+ export declare class FsTabs extends HTMLElement {
30
+ /**
31
+ * Ingen attributter. Hvilken fane som er valgt står i markupen serveren
32
+ * sendte, som `aria-selected` på fanen og `hidden` på panelene, og leses
33
+ * derfra. Et eget `selected` ville vært en parallell utgave av det samme.
34
+ */
35
+ static observedAttributes: string[];
36
+ private readonly bound;
37
+ private observer?;
38
+ connectedCallback(): void;
39
+ disconnectedCallback(): void;
47
40
  private get tabs();
48
41
  private get panels();
49
- private sync;
42
+ /** Indeksen på fanen serveren har markert som valgt. */
43
+ get selected(): number;
44
+ private bind;
50
45
  private handleClick;
51
46
  private handleKeydown;
52
47
  /** Velger en fane og melder fra. */
@@ -1 +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"}
1
+ {"version":3,"file":"fs-tabs.d.ts","sourceRoot":"","sources":["../../../../src/components/ramme/tabs/fs-tabs.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,WAAW,EAAG,SAAkB,CAAA;AAE7C;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBAAa,MAAO,SAAQ,WAAW;IACrC;;;;OAIG;IACH,MAAM,CAAC,kBAAkB,EAAE,MAAM,EAAE,CAAK;IAExC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA+B;IACrD,OAAO,CAAC,QAAQ,CAAC,CAAkB;IAEnC,iBAAiB,IAAI,IAAI;IAMzB,oBAAoB,IAAI,IAAI;IAU5B,OAAO,KAAK,IAAI,GAEf;IAED,OAAO,KAAK,MAAM,GAEjB;IAED,wDAAwD;IACxD,IAAI,QAAQ,IAAI,MAAM,CAKrB;IAED,OAAO,CAAC,IAAI;IASZ,OAAO,CAAC,WAAW,CAGlB;IAED,OAAO,CAAC,aAAa,CA2BpB;IAED,oCAAoC;IACpC,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;CAsB5B;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,SAAS,EAAE,MAAM,CAAA;KAClB;CACF;AAED,wBAAgB,YAAY,CAAC,OAAO,YAAc,GAAG,IAAI,CAIxD"}