@fristil/designsystem 0.4.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 +112 -0
  2. package/README.md +22 -7
  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 +15 -18
  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
@@ -1,53 +1,51 @@
1
- import { html, LitElement } from "lit";
2
1
  export const FS_ERROR_SUMMARY_TAG = "fs-error-summary";
3
- export const ERROR_SUMMARY_CLASS = "fs-error-summary";
4
- export const ERROR_SUMMARY_TITLE_CLASS = "fs-error-summary__title";
5
2
  /**
6
- * Samler feilene i et skjema og sender brukeren til feltet som feilet.
3
+ * Sender brukeren fra en feil i oppsummeringen til feltet som feilet.
7
4
  *
8
- * Du skriver lista med feil selv, som lenker til id-en på hvert felt.
9
- * Komponenten gjør tre ting som er lette å glemme, og som avgjør om
10
- * oppsummeringen er til nytte:
5
+ * Serveren skriver hele boksen med `fs.errorSummary()`: klassen, `role`,
6
+ * `tabindex`, overskriften og lista. Komponenten lager ingenting. Den gjorde
7
+ * det før, og da forsvant både klassen og overskriften ved første morfing i
8
+ * Datastar, uten å komme tilbake.
11
9
  *
12
- * 1. Flytter fokus til boksen når den kommer til syne, så den som hører siden
10
+ * Det som er igjen er to ting nettleseren ikke gjør selv:
11
+ *
12
+ * 1. Fokus flyttes til boksen når den kommer til syne, så den som hører siden
13
13
  * får vite at innsendingen stoppet.
14
- * 2. Gir fokus til selve kontrollen når en lenke følges. En vanlig ankerlenke
14
+ * 2. Fokus gis til selve kontrollen når en lenke følges. En vanlig ankerlenke
15
15
  * ruller bare dit, og neste tastetrykk fortsetter der fokus sto før.
16
- * 3. Holder boksen skjult mens lista er tom, så en tom overskrift ikke blir
17
- * stående i skjemaet.
18
16
  *
19
17
  * ```html
20
- * <fs-error-summary heading="Skjemaet har to feil">
18
+ * <fs-error-summary class="fs-error-summary" role="alert" tabindex="-1">
19
+ * <h2 class="fs-error-summary__title">Skjemaet har to feil</h2>
21
20
  * <ul class="fs-list">
22
21
  * <li><a href="#epost">Skriv en gyldig e-postadresse</a></li>
23
22
  * </ul>
24
23
  * </fs-error-summary>
25
24
  * ```
26
25
  */
27
- export class FsErrorSummary extends LitElement {
26
+ export class FsErrorSummary extends HTMLElement {
28
27
  constructor() {
29
28
  super(...arguments);
30
- /** Overskriften over lista. */
31
- this.heading = "Skjemaet har feil";
32
- /** Flytt fokus hit når boksen kommer til syne. Standard: på. */
33
- this.autofocus = true;
34
29
  this.hasFocused = false;
35
- this.syncing = false;
36
- this.handleSlotChange = () => {
37
- this.sync();
38
- };
30
+ this.links = new Set();
39
31
  this.handleLinkClick = (event) => {
40
32
  const link = event.currentTarget;
41
33
  const id = link.getAttribute("href")?.slice(1);
42
34
  if (!id)
43
35
  return;
44
- const target = document.getElementById(id);
36
+ // Oppslaget går mot rota komponenten selv står i, ikke mot `document`.
37
+ // Ligger skjemaet i en skyggerot, som i en forhåndsvisning eller inne i
38
+ // en annen komponent, finner `document.getElementById` ingenting, og
39
+ // lenken blir en vanlig ankerlenke uten fokusflytting.
40
+ const rot = this.getRootNode();
41
+ const target = rot.getElementById?.(id) ?? document.getElementById(id);
45
42
  if (!target)
46
43
  return;
47
44
  event.preventDefault();
48
45
  // Er lenken til en ledetekst, skal fokus til kontrollen den peker på.
49
46
  const control = target instanceof HTMLLabelElement && target.htmlFor
50
- ? document.getElementById(target.htmlFor)
47
+ ? (rot.getElementById?.(target.htmlFor) ??
48
+ document.getElementById(target.htmlFor))
51
49
  : target;
52
50
  const focusable = control ?? target;
53
51
  if (!focusable.hasAttribute("tabindex") && !isFocusable(focusable)) {
@@ -57,89 +55,56 @@ export class FsErrorSummary extends LitElement {
57
55
  focusable.scrollIntoView({ block: "center", behavior: "smooth" });
58
56
  };
59
57
  }
60
- createRenderRoot() {
61
- return this;
62
- }
63
- render() {
64
- return html `<slot @slotchange=${this.handleSlotChange}></slot>`;
65
- }
66
58
  connectedCallback() {
67
- super.connectedCallback();
68
- this.observer = new MutationObserver(() => {
69
- if (!this.syncing)
70
- this.sync();
71
- });
59
+ // Feilene kommer og går mens brukeren retter, og `slotchange` melder ikke
60
+ // fra i vanlig DOM. Bare childList: komponenten setter ingen attributter
61
+ // på barna, så observatøren kan ikke utløse seg selv.
62
+ this.observer = new MutationObserver(() => this.sync());
72
63
  this.observer.observe(this, { childList: true, subtree: true });
64
+ this.sync();
65
+ }
66
+ attributeChangedCallback() {
67
+ // Serveren kan sende boksen skjult og senere bare ta bort `hidden` på
68
+ // den samme noden. Uten dette får en oppsummering som nettopp ble synlig
69
+ // aldri fokus, og det er hele grunnen til at komponenten finnes.
70
+ if (this.isConnected)
71
+ this.sync();
73
72
  }
74
73
  disconnectedCallback() {
75
74
  this.observer?.disconnect();
76
75
  this.observer = undefined;
77
- super.disconnectedCallback();
78
- }
79
- firstUpdated() {
80
- this.sync();
81
- }
82
- updated() {
83
- this.sync();
76
+ for (const link of this.links) {
77
+ link.removeEventListener("click", this.handleLinkClick);
78
+ }
79
+ this.links.clear();
84
80
  }
85
- get items() {
86
- return [...this.querySelectorAll("li a[href^='#']")];
81
+ get shouldFocus() {
82
+ const value = this.getAttribute("autofocus");
83
+ return value !== "false";
87
84
  }
88
85
  sync() {
89
- if (this.syncing)
86
+ const links = [
87
+ ...this.querySelectorAll("li a[href^='#']"),
88
+ ];
89
+ if (links.length === 0) {
90
+ this.hasFocused = false;
90
91
  return;
91
- this.syncing = true;
92
- try {
93
- const links = this.items;
94
- const empty = links.length === 0;
95
- this.hidden = empty;
96
- if (empty) {
97
- this.hasFocused = false;
98
- return;
99
- }
100
- // Boksen er selve elementet. Vi flytter ikke konsumentens markup inn i
101
- // et omslag: da ville Lit-delen vår og innholdet byttet plass i DOM-en.
102
- this.classList.add(ERROR_SUMMARY_CLASS);
103
- this.setAttribute("role", "alert");
104
- this.tabIndex = -1;
105
- let title = this.querySelector(`.${ERROR_SUMMARY_TITLE_CLASS}`);
106
- if (!title) {
107
- title = document.createElement("h2");
108
- title.className = ERROR_SUMMARY_TITLE_CLASS;
109
- this.prepend(title);
110
- this.ownTitle = title;
111
- }
112
- // Overskriften følger `heading` så lenge det er vi som har laget den.
113
- // Antallet feil endrer seg mens brukeren retter, og en overskrift som
114
- // ble stående på det første tallet er verre enn ingen: den som hører
115
- // siden får vite at det er to feil igjen når det er én.
116
- // Har konsumenten skrevet tittelen selv, er den deres.
117
- //
118
- // Sammenligningen er ikke pynt: å skrive den samme teksten på nytt
119
- // teller som en endring for MutationObserver, og da kaller den sync()
120
- // igjen i det uendelige.
121
- const skalSkrive = title === this.ownTitle || !title.textContent?.trim();
122
- if (skalSkrive && title.textContent !== this.heading) {
123
- title.textContent = this.heading;
124
- }
125
- for (const link of links) {
126
- link.removeEventListener("click", this.handleLinkClick);
127
- link.addEventListener("click", this.handleLinkClick);
128
- }
129
- if (this.autofocus && !this.hasFocused) {
130
- this.hasFocused = true;
131
- this.focus();
132
- }
133
92
  }
134
- finally {
135
- this.syncing = false;
93
+ for (const link of links) {
94
+ if (this.links.has(link))
95
+ continue;
96
+ link.addEventListener("click", this.handleLinkClick);
97
+ this.links.add(link);
98
+ }
99
+ // Boksen er skjult av serveren når lista er tom. Er den synlig nå, og vi
100
+ // ikke har flyttet fokus hit ennå, er det denne innsendingen som feilet.
101
+ if (this.shouldFocus && !this.hasFocused && !this.hidden) {
102
+ this.hasFocused = true;
103
+ this.focus();
136
104
  }
137
105
  }
138
106
  }
139
- FsErrorSummary.properties = {
140
- heading: { type: String },
141
- autofocus: { type: Boolean, reflect: true },
142
- };
107
+ FsErrorSummary.observedAttributes = ["autofocus", "hidden"];
143
108
  function isFocusable(element) {
144
109
  return (element instanceof HTMLInputElement ||
145
110
  element instanceof HTMLSelectElement ||
@@ -1 +1 @@
1
- {"version":3,"file":"fs-error-summary.js","sourceRoot":"","sources":["../../../../src/components/ramme/error-summary/fs-error-summary.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fs-error-summary.js","sourceRoot":"","sources":["../../../../src/components/ramme/error-summary/fs-error-summary.ts"],"names":[],"mappings":"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"}
@@ -67,4 +67,35 @@ export declare function createFieldId(): string;
67
67
  */
68
68
  export declare function joinDescribedBy(ids: Array<string | undefined | false>): string | undefined;
69
69
  export declare function computeFieldAttributes(options?: FieldOptions): FieldAttributes;
70
+ /**
71
+ * Attributtene `<fs-field>` setter, per element den rører.
72
+ *
73
+ * Kjører serveren JavaScript, skal den kalle `computeFieldAttributes` og
74
+ * skrive dem selv. Da trengs verken komponenten eller denne lista. Kjører den
75
+ * noe annet, altså Go, PHP eller .NET, gjør komponenten koblingen på klienten,
76
+ * og da må serveren skrive lista som `data-preserve-attr` på hvert av de tre
77
+ * elementene. Datastars morfing leser lista fra serverens node, per element,
78
+ * så komponenten kan ikke beskytte seg selv.
79
+ *
80
+ * Det holder ikke å beskytte kontrollen alene. Komponenten legger også
81
+ * `fs-label` og markeringene på ledeteksten, og skjuler feilmeldingen. Uten
82
+ * lister på de to andre forsvinner klassen og feilmeldingen ved neste
83
+ * morfing, som er nøyaktig den feilen kontrakten skal hindre.
84
+ *
85
+ * ```html
86
+ * <label class="fs-label" for="epost"
87
+ * data-preserve-attr="class data-required data-optional aria-disabled">E-post</label>
88
+ * <input class="fs-input" id="epost"
89
+ * data-preserve-attr="id aria-describedby aria-invalid data-state disabled aria-disabled">
90
+ * <p class="fs-error-text" hidden data-preserve-attr="hidden">Skriv en gyldig adresse.</p>
91
+ * ```
92
+ */
93
+ export declare const FIELD_PRESERVED_ATTRIBUTES: {
94
+ /** På ledeteksten. */
95
+ readonly label: "class data-required data-optional aria-disabled";
96
+ /** På selve kontrollen. */
97
+ readonly control: "id aria-describedby aria-invalid data-state disabled aria-disabled";
98
+ /** På feilmeldingen. */
99
+ readonly error: "hidden";
100
+ };
70
101
  //# sourceMappingURL=field-core.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"field-core.d.ts","sourceRoot":"","sources":["../../../../src/components/ramme/field/field-core.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAGrE;;;;;;;;GAQG;AAEH,MAAM,MAAM,YAAY,GAAG;IACzB,4DAA4D;IAC5D,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,wEAAwE;IACxE,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,oEAAoE;IACpE,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,oEAAoE;IACpE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,oEAAoE;IACpE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,sCAAsC;IACtC,QAAQ,CAAC,EAAE,cAAc,CAAA;IACzB,sCAAsC;IACtC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,uEAAuE;IACvE,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,sDAAsD;IACtD,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;CACvB,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE;QACL,KAAK,EAAE,UAAU,CAAA;QACjB,GAAG,EAAE,MAAM,CAAA;QACX,eAAe,CAAC,EAAE,cAAc,CAAA;QAChC,eAAe,CAAC,EAAE,EAAE,CAAA;QACpB,eAAe,CAAC,EAAE,MAAM,CAAA;KACzB,CAAA;IACD,OAAO,EAAE;QACP,EAAE,EAAE,MAAM,CAAA;QACV,kBAAkB,CAAC,EAAE,MAAM,CAAA;QAC3B,cAAc,CAAC,EAAE,MAAM,CAAA;QACvB,YAAY,CAAC,EAAE,SAAS,CAAA;QACxB,QAAQ,CAAC,EAAE,IAAI,CAAA;KAChB,CAAA;IACD,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAA;IACpB,KAAK,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,IAAI,CAAA;KAAE,CAAA;IACpC,gFAAgF;IAChF,KAAK,EAAE,UAAU,CAAA;CAClB,CAAA;AAID,mDAAmD;AACnD,wBAAgB,aAAa,IAAI,MAAM,CAGtC;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,KAAK,CAAC,MAAM,GAAG,SAAS,GAAG,KAAK,CAAC,GACrC,MAAM,GAAG,SAAS,CASpB;AAED,wBAAgB,sBAAsB,CACpC,OAAO,GAAE,YAAiB,GACzB,eAAe,CA2CjB"}
1
+ {"version":3,"file":"field-core.d.ts","sourceRoot":"","sources":["../../../../src/components/ramme/field/field-core.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAGrE;;;;;;;;GAQG;AAEH,MAAM,MAAM,YAAY,GAAG;IACzB,4DAA4D;IAC5D,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,wEAAwE;IACxE,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,oEAAoE;IACpE,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,oEAAoE;IACpE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,oEAAoE;IACpE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,sCAAsC;IACtC,QAAQ,CAAC,EAAE,cAAc,CAAA;IACzB,sCAAsC;IACtC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,uEAAuE;IACvE,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,sDAAsD;IACtD,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;CACvB,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE;QACL,KAAK,EAAE,UAAU,CAAA;QACjB,GAAG,EAAE,MAAM,CAAA;QACX,eAAe,CAAC,EAAE,cAAc,CAAA;QAChC,eAAe,CAAC,EAAE,EAAE,CAAA;QACpB,eAAe,CAAC,EAAE,MAAM,CAAA;KACzB,CAAA;IACD,OAAO,EAAE;QACP,EAAE,EAAE,MAAM,CAAA;QACV,kBAAkB,CAAC,EAAE,MAAM,CAAA;QAC3B,cAAc,CAAC,EAAE,MAAM,CAAA;QACvB,YAAY,CAAC,EAAE,SAAS,CAAA;QACxB,QAAQ,CAAC,EAAE,IAAI,CAAA;KAChB,CAAA;IACD,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAA;IACpB,KAAK,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,IAAI,CAAA;KAAE,CAAA;IACpC,gFAAgF;IAChF,KAAK,EAAE,UAAU,CAAA;CAClB,CAAA;AAID,mDAAmD;AACnD,wBAAgB,aAAa,IAAI,MAAM,CAGtC;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,KAAK,CAAC,MAAM,GAAG,SAAS,GAAG,KAAK,CAAC,GACrC,MAAM,GAAG,SAAS,CASpB;AAED,wBAAgB,sBAAsB,CACpC,OAAO,GAAE,YAAiB,GACzB,eAAe,CA2CjB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,0BAA0B;IACrC,sBAAsB;;IAEtB,2BAA2B;;IAE3B,wBAAwB;;CAEhB,CAAA"}
@@ -57,4 +57,35 @@ export function computeFieldAttributes(options = {}) {
57
57
  state: invalid ? "invalid" : "default",
58
58
  };
59
59
  }
60
+ /**
61
+ * Attributtene `<fs-field>` setter, per element den rører.
62
+ *
63
+ * Kjører serveren JavaScript, skal den kalle `computeFieldAttributes` og
64
+ * skrive dem selv. Da trengs verken komponenten eller denne lista. Kjører den
65
+ * noe annet, altså Go, PHP eller .NET, gjør komponenten koblingen på klienten,
66
+ * og da må serveren skrive lista som `data-preserve-attr` på hvert av de tre
67
+ * elementene. Datastars morfing leser lista fra serverens node, per element,
68
+ * så komponenten kan ikke beskytte seg selv.
69
+ *
70
+ * Det holder ikke å beskytte kontrollen alene. Komponenten legger også
71
+ * `fs-label` og markeringene på ledeteksten, og skjuler feilmeldingen. Uten
72
+ * lister på de to andre forsvinner klassen og feilmeldingen ved neste
73
+ * morfing, som er nøyaktig den feilen kontrakten skal hindre.
74
+ *
75
+ * ```html
76
+ * <label class="fs-label" for="epost"
77
+ * data-preserve-attr="class data-required data-optional aria-disabled">E-post</label>
78
+ * <input class="fs-input" id="epost"
79
+ * data-preserve-attr="id aria-describedby aria-invalid data-state disabled aria-disabled">
80
+ * <p class="fs-error-text" hidden data-preserve-attr="hidden">Skriv en gyldig adresse.</p>
81
+ * ```
82
+ */
83
+ export const FIELD_PRESERVED_ATTRIBUTES = {
84
+ /** På ledeteksten. */
85
+ label: "class data-required data-optional aria-disabled",
86
+ /** På selve kontrollen. */
87
+ control: "id aria-describedby aria-invalid data-state disabled aria-disabled",
88
+ /** På feilmeldingen. */
89
+ error: "hidden",
90
+ };
60
91
  //# sourceMappingURL=field-core.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"field-core.js","sourceRoot":"","sources":["../../../../src/components/ramme/field/field-core.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAwDhD,IAAI,OAAO,GAAG,CAAC,CAAA;AAEf,mDAAmD;AACnD,MAAM,UAAU,aAAa;IAC3B,OAAO,IAAI,CAAC,CAAA;IACZ,OAAO,YAAY,OAAO,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAA;AACxE,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAC7B,GAAsC;IAEtC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAA;IAChC,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;QACrB,IAAI,CAAC,EAAE;YAAE,SAAQ;QACjB,KAAK,MAAM,IAAI,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YACnC,IAAI,IAAI;gBAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QAC5B,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;AAC5D,CAAC;AAED,MAAM,UAAU,sBAAsB,CACpC,UAAwB,EAAE;IAE1B,MAAM,EACJ,EAAE,GAAG,aAAa,EAAE,EACpB,IAAI,GAAG,KAAK,EACZ,KAAK,GAAG,KAAK,EACb,QAAQ,EACR,QAAQ,EACR,OAAO,GAAG,KAAK,EACf,QAAQ,GAAG,KAAK,EAChB,WAAW,GAAG,EAAE,EAChB,MAAM,GAAG,GAAG,EAAE,OAAO,EACrB,OAAO,GAAG,GAAG,EAAE,QAAQ,GACxB,GAAG,OAAO,CAAA;IAEX,OAAO;QACL,KAAK,EAAE,UAAU,CAAC;YAChB,KAAK,EAAE,UAAmB;YAC1B,GAAG,EAAE,EAAE;YACP,eAAe,EAAE,QAAQ;YACzB,eAAe,EAAE,QAAQ,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAE,EAAY,CAAC,CAAC,CAAC,SAAS;YAClE,eAAe,EAAE,QAAQ,CAAC,CAAC,CAAE,MAAgB,CAAC,CAAC,CAAC,SAAS;SAC1D,CAAC;QACF,OAAO,EAAE,UAAU,CAAC;YAClB,EAAE;YACF,kBAAkB,EAAE,eAAe,CAAC;gBAClC,IAAI,IAAI,MAAM;gBACd,OAAO,IAAI,KAAK,IAAI,OAAO;gBAC3B,GAAG,WAAW;aACf,CAAC;YACF,cAAc,EAAE,OAAO,CAAC,CAAC,CAAE,MAAgB,CAAC,CAAC,CAAC,SAAS;YACvD,sEAAsE;YACtE,wEAAwE;YACxE,8DAA8D;YAC9D,YAAY,EAAE,OAAO,CAAC,CAAC,CAAE,SAAmB,CAAC,CAAC,CAAC,SAAS;YACxD,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAE,IAAc,CAAC,CAAC,CAAC,SAAS;SACjD,CAAC;QACF,IAAI,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE;QACpB,KAAK,EAAE,UAAU,CAAC;YAChB,EAAE,EAAE,OAAO;YACX,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAE,IAAc;SAC9C,CAAC;QACF,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;KACvC,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"field-core.js","sourceRoot":"","sources":["../../../../src/components/ramme/field/field-core.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAwDhD,IAAI,OAAO,GAAG,CAAC,CAAA;AAEf,mDAAmD;AACnD,MAAM,UAAU,aAAa;IAC3B,OAAO,IAAI,CAAC,CAAA;IACZ,OAAO,YAAY,OAAO,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAA;AACxE,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAC7B,GAAsC;IAEtC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAA;IAChC,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;QACrB,IAAI,CAAC,EAAE;YAAE,SAAQ;QACjB,KAAK,MAAM,IAAI,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YACnC,IAAI,IAAI;gBAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QAC5B,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;AAC5D,CAAC;AAED,MAAM,UAAU,sBAAsB,CACpC,UAAwB,EAAE;IAE1B,MAAM,EACJ,EAAE,GAAG,aAAa,EAAE,EACpB,IAAI,GAAG,KAAK,EACZ,KAAK,GAAG,KAAK,EACb,QAAQ,EACR,QAAQ,EACR,OAAO,GAAG,KAAK,EACf,QAAQ,GAAG,KAAK,EAChB,WAAW,GAAG,EAAE,EAChB,MAAM,GAAG,GAAG,EAAE,OAAO,EACrB,OAAO,GAAG,GAAG,EAAE,QAAQ,GACxB,GAAG,OAAO,CAAA;IAEX,OAAO;QACL,KAAK,EAAE,UAAU,CAAC;YAChB,KAAK,EAAE,UAAmB;YAC1B,GAAG,EAAE,EAAE;YACP,eAAe,EAAE,QAAQ;YACzB,eAAe,EAAE,QAAQ,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAE,EAAY,CAAC,CAAC,CAAC,SAAS;YAClE,eAAe,EAAE,QAAQ,CAAC,CAAC,CAAE,MAAgB,CAAC,CAAC,CAAC,SAAS;SAC1D,CAAC;QACF,OAAO,EAAE,UAAU,CAAC;YAClB,EAAE;YACF,kBAAkB,EAAE,eAAe,CAAC;gBAClC,IAAI,IAAI,MAAM;gBACd,OAAO,IAAI,KAAK,IAAI,OAAO;gBAC3B,GAAG,WAAW;aACf,CAAC;YACF,cAAc,EAAE,OAAO,CAAC,CAAC,CAAE,MAAgB,CAAC,CAAC,CAAC,SAAS;YACvD,sEAAsE;YACtE,wEAAwE;YACxE,8DAA8D;YAC9D,YAAY,EAAE,OAAO,CAAC,CAAC,CAAE,SAAmB,CAAC,CAAC,CAAC,SAAS;YACxD,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAE,IAAc,CAAC,CAAC,CAAC,SAAS;SACjD,CAAC;QACF,IAAI,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE;QACpB,KAAK,EAAE,UAAU,CAAC;YAChB,EAAE,EAAE,OAAO;YACX,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAE,IAAc;SAC9C,CAAC;QACF,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;KACvC,CAAA;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG;IACxC,sBAAsB;IACtB,KAAK,EAAE,iDAAiD;IACxD,2BAA2B;IAC3B,OAAO,EAAE,oEAAoE;IAC7E,wBAAwB;IACxB,KAAK,EAAE,QAAQ;CACP,CAAA"}
@@ -1,44 +1,42 @@
1
- import { LitElement } from "lit";
2
1
  export declare const FS_FIELD_TAG: "fs-field";
3
- export declare class FsField extends LitElement {
4
- static properties: {
5
- invalid: {
6
- type: BooleanConstructor;
7
- reflect: boolean;
8
- };
9
- disabled: {
10
- type: BooleanConstructor;
11
- reflect: boolean;
12
- };
13
- optional: {
14
- type: BooleanConstructor;
15
- reflect: boolean;
16
- };
17
- requiredMarker: {
18
- type: StringConstructor;
19
- attribute: string;
20
- };
21
- controlId: {
22
- type: StringConstructor;
23
- attribute: string;
24
- };
25
- describedBy: {
26
- type: StringConstructor;
27
- attribute: string;
28
- };
29
- };
30
- invalid: boolean;
31
- disabled: boolean;
32
- optional: boolean;
33
- requiredMarker: "none" | "symbol" | "text";
34
- controlId?: string;
35
- describedBy?: string;
36
- createRenderRoot(): this;
37
- render(): import("lit").TemplateResult<1>;
38
- firstUpdated(): void;
39
- updated(): void;
40
- private handleSlotChange;
41
- private syncA11y;
2
+ /**
3
+ * Kobler ledetekst, kontroll, hjelpetekst og feilmelding i vanlig DOM.
4
+ *
5
+ * Komponenten er for servere som ikke kan kalle `fs.field()`, altså alt som
6
+ * ikke kjører JavaScript. Kan serveren kalle byggeren, skal den skrive
7
+ * attributtene selv, og da trengs ikke dette elementet.
8
+ *
9
+ * Komponenten rendrer ingenting. Den satte tidligere et `<slot>`-element inn i
10
+ * vanlig DOM, og siden serveren ikke visste om det, fjernet Datastars morfing
11
+ * det ved hver patch. Se `FIELD_PRESERVED_ATTRIBUTES` for hva serveren må
12
+ * skrive for at koblingen skal overleve en morfing.
13
+ */
14
+ export declare class FsField extends HTMLElement {
15
+ static observedAttributes: string[];
16
+ private observer?;
17
+ /**
18
+ * Egenskapene speiler attributtene.
19
+ *
20
+ * Tilstanden bor i attributtet og ikke i et felt på klassen, slik at det
21
+ * serveren sendte og det komponenten mener alltid er det samme. En egen
22
+ * `invalid`-variabel ville kunne si noe annet enn markupen etter en morfing.
23
+ */
24
+ get invalid(): boolean;
25
+ set invalid(value: boolean);
26
+ get disabled(): boolean;
27
+ set disabled(value: boolean);
28
+ get optional(): boolean;
29
+ set optional(value: boolean);
30
+ get requiredMarker(): "none" | "symbol" | "text";
31
+ set requiredMarker(value: "none" | "symbol" | "text");
32
+ get controlId(): string | undefined;
33
+ set controlId(value: string | undefined);
34
+ get describedBy(): string | undefined;
35
+ set describedBy(value: string | undefined);
36
+ connectedCallback(): void;
37
+ disconnectedCallback(): void;
38
+ attributeChangedCallback(): void;
39
+ private sync;
42
40
  }
43
41
  declare global {
44
42
  interface HTMLElementTagNameMap {
@@ -1 +1 @@
1
- {"version":3,"file":"fs-field.d.ts","sourceRoot":"","sources":["../../../../src/components/ramme/field/fs-field.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,UAAU,EAAE,MAAM,KAAK,CAAA;AAItC,eAAO,MAAM,YAAY,EAAG,UAAmB,CAAA;AAM/C,qBAAa,OAAQ,SAAQ,UAAU;IACrC,MAAM,CAAC,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;MAOhB;IAED,OAAO,UAAQ;IACf,QAAQ,UAAQ;IAChB,QAAQ,UAAQ;IAChB,cAAc,EAAE,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAS;IACnD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;IAEpB,gBAAgB;IAIhB,MAAM;IAIN,YAAY;IAIZ,OAAO;IAIP,OAAO,CAAC,gBAAgB,CAEvB;IAED,OAAO,CAAC,QAAQ;CAkFjB;AAcD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,UAAU,EAAE,OAAO,CAAA;KACpB;CACF;AAED,wBAAgB,aAAa,CAAC,OAAO,aAAe,GAAG,IAAI,CAI1D"}
1
+ {"version":3,"file":"fs-field.d.ts","sourceRoot":"","sources":["../../../../src/components/ramme/field/fs-field.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,YAAY,EAAG,UAAmB,CAAA;AAkB/C;;;;;;;;;;;GAWG;AACH,qBAAa,OAAQ,SAAQ,WAAW;IACtC,MAAM,CAAC,kBAAkB,WAOxB;IAED,OAAO,CAAC,QAAQ,CAAC,CAAkB;IAEnC;;;;;;OAMG;IACH,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAEzB;IAED,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED,IAAI,QAAQ,CAAC,KAAK,EAAE,OAAO,EAE1B;IAED,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED,IAAI,QAAQ,CAAC,KAAK,EAAE,OAAO,EAE1B;IAED,IAAI,cAAc,IAAI,MAAM,GAAG,QAAQ,GAAG,MAAM,CAG/C;IAED,IAAI,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,GAAG,MAAM,EAGnD;IAED,IAAI,SAAS,IAAI,MAAM,GAAG,SAAS,CAElC;IAED,IAAI,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAGtC;IAED,IAAI,WAAW,IAAI,MAAM,GAAG,SAAS,CAEpC;IAED,IAAI,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAGxC;IAED,iBAAiB,IAAI,IAAI;IASzB,oBAAoB,IAAI,IAAI;IAK5B,wBAAwB,IAAI,IAAI;IAIhC,OAAO,CAAC,IAAI;CAuGb;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,UAAU,EAAE,OAAO,CAAA;KACpB;CACF;AAED,wBAAgB,aAAa,CAAC,OAAO,aAAe,GAAG,IAAI,CAI1D"}
@@ -1,33 +1,99 @@
1
- import { html, LitElement } from "lit";
2
1
  import { computeFieldAttributes } from "./field-core.js";
3
2
  export const FS_FIELD_TAG = "fs-field";
4
3
  function uniqueId(prefix) {
5
4
  return `${prefix}-${Math.random().toString(36).slice(2, 9)}`;
6
5
  }
7
- export class FsField extends LitElement {
8
- constructor() {
9
- super(...arguments);
10
- this.invalid = false;
11
- this.disabled = false;
12
- this.optional = false;
13
- this.requiredMarker = "none";
14
- this.handleSlotChange = () => {
15
- this.syncA11y();
16
- };
17
- }
18
- createRenderRoot() {
19
- return this;
20
- }
21
- render() {
22
- return html `<slot @slotchange=${this.handleSlotChange}></slot>`;
23
- }
24
- firstUpdated() {
25
- this.syncA11y();
26
- }
27
- updated() {
28
- this.syncA11y();
29
- }
30
- syncA11y() {
6
+ function setOrRemove(element, name, value) {
7
+ if (value === undefined) {
8
+ element.removeAttribute(name);
9
+ }
10
+ else if (element.getAttribute(name) !== value) {
11
+ element.setAttribute(name, value);
12
+ }
13
+ }
14
+ /**
15
+ * Kobler ledetekst, kontroll, hjelpetekst og feilmelding i vanlig DOM.
16
+ *
17
+ * Komponenten er for servere som ikke kan kalle `fs.field()`, altså alt som
18
+ * ikke kjører JavaScript. Kan serveren kalle byggeren, skal den skrive
19
+ * attributtene selv, og da trengs ikke dette elementet.
20
+ *
21
+ * Komponenten rendrer ingenting. Den satte tidligere et `<slot>`-element inn i
22
+ * vanlig DOM, og siden serveren ikke visste om det, fjernet Datastars morfing
23
+ * det ved hver patch. Se `FIELD_PRESERVED_ATTRIBUTES` for hva serveren må
24
+ * skrive for at koblingen skal overleve en morfing.
25
+ */
26
+ export class FsField extends HTMLElement {
27
+ /**
28
+ * Egenskapene speiler attributtene.
29
+ *
30
+ * Tilstanden bor i attributtet og ikke i et felt på klassen, slik at det
31
+ * serveren sendte og det komponenten mener alltid er det samme. En egen
32
+ * `invalid`-variabel ville kunne si noe annet enn markupen etter en morfing.
33
+ */
34
+ get invalid() {
35
+ return this.hasAttribute("invalid");
36
+ }
37
+ set invalid(value) {
38
+ this.toggleAttribute("invalid", value);
39
+ }
40
+ get disabled() {
41
+ return this.hasAttribute("disabled");
42
+ }
43
+ set disabled(value) {
44
+ this.toggleAttribute("disabled", value);
45
+ }
46
+ get optional() {
47
+ return this.hasAttribute("optional");
48
+ }
49
+ set optional(value) {
50
+ this.toggleAttribute("optional", value);
51
+ }
52
+ get requiredMarker() {
53
+ const value = this.getAttribute("required-marker");
54
+ return value === "symbol" || value === "text" ? value : "none";
55
+ }
56
+ set requiredMarker(value) {
57
+ if (value === "none")
58
+ this.removeAttribute("required-marker");
59
+ else
60
+ this.setAttribute("required-marker", value);
61
+ }
62
+ get controlId() {
63
+ return this.getAttribute("control-id") ?? undefined;
64
+ }
65
+ set controlId(value) {
66
+ if (value === undefined)
67
+ this.removeAttribute("control-id");
68
+ else
69
+ this.setAttribute("control-id", value);
70
+ }
71
+ get describedBy() {
72
+ return this.getAttribute("described-by") ?? undefined;
73
+ }
74
+ set describedBy(value) {
75
+ if (value === undefined)
76
+ this.removeAttribute("described-by");
77
+ else
78
+ this.setAttribute("described-by", value);
79
+ }
80
+ connectedCallback() {
81
+ // `slotchange` melder ikke fra i vanlig DOM, og innholdet byttes ut mens
82
+ // brukeren fyller ut skjemaet. Bare childList: å sette et attributt på et
83
+ // barn utløser da ingen ny runde, så observatøren kan ikke gå i ring.
84
+ this.observer = new MutationObserver(() => this.sync());
85
+ this.observer.observe(this, { childList: true, subtree: true });
86
+ this.sync();
87
+ }
88
+ disconnectedCallback() {
89
+ this.observer?.disconnect();
90
+ this.observer = undefined;
91
+ }
92
+ attributeChangedCallback() {
93
+ if (this.isConnected)
94
+ this.sync();
95
+ }
96
+ sync() {
31
97
  const label = this.querySelector("label");
32
98
  const control = this.querySelector("input:not([type='hidden']), textarea, select");
33
99
  const help = this.querySelector(".fs-help-text, [data-role='help']");
@@ -38,24 +104,37 @@ export class FsField extends LitElement {
38
104
  help.id = uniqueId("fs-field-help");
39
105
  if (error && !error.id)
40
106
  error.id = uniqueId("fs-field-error");
41
- // Selve kontrakten regnes ut av den delte kjernen, som fs.field() også
42
- // bruker. Denne komponenten gjør bare én ting utover det: å sette
43
- // resultatet elementer som allerede står i DOM-en.
107
+ // Markeringene leses også fra markupen. Skrev serveren dem med
108
+ // `fs.field()`, står de ledeteksten, og en komponent som bare så på
109
+ // sine egne attributter ville fjernet dem igjen. I React ga det en
110
+ // hydreringsfeil: serveren sendte `data-required="symbol"`, komponenten
111
+ // tok det bort, og så mente React at HTML-en ikke stemte.
112
+ const marker = this.getAttribute("required-marker") ??
113
+ label?.getAttribute("data-required") ??
114
+ null;
115
+ const disabled = this.hasAttribute("disabled") || control.hasAttribute("disabled");
116
+ // Tilstanden leses fra markupen, ikke bare fra et attributt på verten.
117
+ // Skrev serveren feltet med `fs.field()`, står svaret allerede på
118
+ // kontrollen, og en komponent som regnet ut sitt eget ville fjernet det
119
+ // igjen. Da kranglet de to halvdelene av API-et med hverandre.
120
+ const invalid = this.hasAttribute("invalid") ||
121
+ control.getAttribute("aria-invalid") === "true";
44
122
  const computed = computeFieldAttributes({
45
- id: this.controlId || control.id || uniqueId("fs-field-control"),
123
+ id: this.getAttribute("control-id") ||
124
+ control.id ||
125
+ uniqueId("fs-field-control"),
46
126
  help: Boolean(help),
47
127
  error: Boolean(error),
48
128
  helpId: help?.id,
49
129
  errorId: error?.id,
50
- required: this.requiredMarker === "symbol" || this.requiredMarker === "text"
51
- ? this.requiredMarker
52
- : undefined,
53
- optional: this.optional,
54
- invalid: this.invalid,
55
- disabled: this.disabled,
130
+ required: marker === "symbol" || marker === "text" ? marker : undefined,
131
+ optional: this.hasAttribute("optional") ||
132
+ label?.hasAttribute("data-optional") === true,
133
+ invalid,
134
+ disabled,
56
135
  describedBy: [
57
136
  control.getAttribute("aria-describedby") ?? "",
58
- this.describedBy ?? "",
137
+ this.getAttribute("described-by") ?? "",
59
138
  ].filter(Boolean),
60
139
  });
61
140
  control.id = computed.control.id;
@@ -68,12 +147,14 @@ export class FsField extends LitElement {
68
147
  setOrRemove(label, "aria-disabled", computed.label["aria-disabled"]);
69
148
  }
70
149
  if (error) {
150
+ // Bare `hidden`. Et skjult element er allerede ute av
151
+ // tilgjengelighetstreet, så `aria-hidden` var overflødig, og ga en
152
+ // hydreringsfeil i React fordi serveren ikke skriver det.
71
153
  error.hidden = Boolean(computed.error.hidden);
72
- error.setAttribute("aria-hidden", String(Boolean(computed.error.hidden)));
73
154
  }
74
155
  setOrRemove(control, "aria-describedby", computed.control["aria-describedby"]);
75
156
  setOrRemove(control, "aria-invalid", computed.control["aria-invalid"]);
76
- if (this.disabled) {
157
+ if (disabled) {
77
158
  control.setAttribute("disabled", "");
78
159
  control.setAttribute("aria-disabled", "true");
79
160
  }
@@ -94,22 +175,14 @@ export class FsField extends LitElement {
94
175
  }
95
176
  }
96
177
  }
97
- FsField.properties = {
98
- invalid: { type: Boolean, reflect: true },
99
- disabled: { type: Boolean, reflect: true },
100
- optional: { type: Boolean, reflect: true },
101
- requiredMarker: { type: String, attribute: "required-marker" },
102
- controlId: { type: String, attribute: "control-id" },
103
- describedBy: { type: String, attribute: "described-by" },
104
- };
105
- function setOrRemove(element, name, value) {
106
- if (value === undefined) {
107
- element.removeAttribute(name);
108
- }
109
- else {
110
- element.setAttribute(name, value);
111
- }
112
- }
178
+ FsField.observedAttributes = [
179
+ "invalid",
180
+ "disabled",
181
+ "optional",
182
+ "required-marker",
183
+ "control-id",
184
+ "described-by",
185
+ ];
113
186
  export function defineFsField(tagName = FS_FIELD_TAG) {
114
187
  if (!customElements.get(tagName)) {
115
188
  customElements.define(tagName, FsField);