@folkehelseinstituttet/designsystem 0.43.4 → 0.44.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/fhi-checkbox.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { a as e, d as t, o as n, s as r, t as i, u as a } from "./decorate-DFXIek-k.js";
2
2
  import { t as o } from "./if-defined-Dl-W5B5_.js";
3
+ import "./fhi-body.js";
3
4
  //#region src/components/fhi-checkbox/fhi-checkbox.component.ts
4
5
  var s = "fhi-checkbox", c = class extends r {
5
6
  static {
@@ -11,6 +12,9 @@ var s = "fhi-checkbox", c = class extends r {
11
12
  connectedCallback() {
12
13
  super.connectedCallback(), this._updateFormValue();
13
14
  }
15
+ updated(e) {
16
+ (e.has("helpText") || e.has("label")) && !this.label && this.helpText && console.error("The \"help-text\" property is set, but the \"label\" property is not. It is required to provide a label when using help text.");
17
+ }
14
18
  _handleChange(e) {
15
19
  this.checked = e.target.checked, this._updateFormValue(), e.stopPropagation(), this._dispatchChangeEvent();
16
20
  }
@@ -34,9 +38,10 @@ var s = "fhi-checkbox", c = class extends r {
34
38
  }
35
39
  render() {
36
40
  return a`
37
- <label>
41
+ <div class="checkbox-wrapper">
38
42
  <input
39
43
  type="checkbox"
44
+ id="checkbox-element"
40
45
  name="${o(this.name)}"
41
46
  value="${o(this.value)}"
42
47
  ?disabled=${this.disabled}
@@ -55,9 +60,11 @@ var s = "fhi-checkbox", c = class extends r {
55
60
  d="M12.043 6.04295C12.4335 5.65243 13.0666 5.65243 13.4571 6.04295C13.8476 6.43348 13.8476 7.06649 13.4571 7.45702L8.95708 11.957C8.56655 12.3475 7.93354 12.3475 7.54302 11.957L5.29302 9.70702C4.90249 9.31649 4.90249 8.68348 5.29302 8.29295C5.65913 7.92684 6.23813 7.90424 6.63091 8.22459L6.70708 8.29295L8.25005 9.83592L12.043 6.04295Z"
56
61
  />
57
62
  </svg>
58
-
59
- ${this.label}
60
- </label>
63
+ </div>
64
+ ${this.label && a`<label for="checkbox-element">${this.label}</label>`}
65
+ ${this.helpText ? a`<fhi-body size="small" class="help-text"
66
+ >${this.helpText}</fhi-body
67
+ >` : ""}
61
68
  `;
62
69
  }
63
70
  static {
@@ -67,26 +74,33 @@ var s = "fhi-checkbox", c = class extends r {
67
74
  }
68
75
 
69
76
  :host {
70
- display: flex;
71
- align-items: center;
77
+ display: grid;
72
78
  width: max-content;
79
+ height: fit-content;
80
+ color: var(--fhi-checkbox-color);
73
81
 
74
- label {
75
- align-items: center;
76
- display: flex;
82
+ .checkbox-wrapper {
77
83
  position: relative;
78
- color: var(--fhi-checkbox-color);
84
+ height: fit-content;
85
+ }
86
+
87
+ label {
79
88
  font-family: var(--fhi-font-family-default);
80
89
  -webkit-font-smoothing: antialiased;
81
90
  font-size: var(--fhi-typography-body-medium-font-size);
82
91
  font-weight: var(--fhi-typography-body-medium-font-weight);
83
92
  line-height: var(--fhi-typography-body-medium-line-height);
84
93
  letter-spacing: var(--fhi-typography-body-medium-letter-spacing);
85
- gap: var(--fhi-spacing-050);
94
+ }
95
+
96
+ label,
97
+ fhi-body {
98
+ grid-column: 2;
99
+ padding-left: 7px;
86
100
  }
87
101
 
88
102
  input[type='checkbox'] {
89
- margin: 3px;
103
+ margin: 3px 0 0 3px;
90
104
  appearance: none;
91
105
  width: 1.125rem;
92
106
  height: 1.125rem;
@@ -94,8 +108,11 @@ var s = "fhi-checkbox", c = class extends r {
94
108
  border: var(--fhi-dimension-border-width) solid
95
109
  var(--fhi-color-neutral-border-default);
96
110
  border-radius: var(--fhi-border-radius-050);
97
- transition: var(--fhi-motion-ease-default)
111
+ transition: all var(--fhi-motion-ease-default)
98
112
  var(--fhi-motion-duration-quick);
113
+ &:not(:focus-visible) {
114
+ outline-color: var(--fhi-color-accent-surface-hover);
115
+ }
99
116
 
100
117
  &:hover {
101
118
  background-color: var(--fhi-color-accent-background-subtle);
@@ -134,16 +151,21 @@ var s = "fhi-checkbox", c = class extends r {
134
151
  transition: opacity var(--fhi-motion-ease-default)
135
152
  var(--fhi-motion-duration-quick);
136
153
  position: absolute;
154
+ top: 3px;
155
+ left: 3px;
137
156
  height: 1.125rem;
138
157
  width: 1.125rem;
139
- margin-left: 3px;
158
+ pointer-events: none;
159
+ }
160
+
161
+ .help-text {
162
+ color: var(--fhi-color-neutral-text-subtle);
140
163
  }
141
164
  }
142
165
 
143
166
  :host([disabled]) {
144
167
  opacity: var(--fhi-opacity-disabled);
145
- label,
146
- input {
168
+ * {
147
169
  cursor: not-allowed;
148
170
  }
149
171
 
@@ -175,6 +197,9 @@ var s = "fhi-checkbox", c = class extends r {
175
197
  input[type='checkbox'] {
176
198
  background-color: var(--fhi-color-danger-background-default);
177
199
  border-color: var(--fhi-color-danger-border-default);
200
+ &:not(:focus-visible) {
201
+ outline-color: var(--fhi-color-danger-surface-hover);
202
+ }
178
203
 
179
204
  &:hover {
180
205
  background-color: var(--fhi-color-danger-background-subtle);
@@ -183,8 +208,8 @@ var s = "fhi-checkbox", c = class extends r {
183
208
 
184
209
  &:active {
185
210
  background-color: var(--fhi-color-danger-surface-default);
186
- outline: solid 5px var(--fhi-color-danger-surface-hover);
187
211
  border-color: var(--fhi-color-danger-border-strong);
212
+ outline-color: var(--fhi-color-danger-surface-hover);
188
213
  }
189
214
 
190
215
  &:checked {
@@ -206,6 +231,9 @@ var s = "fhi-checkbox", c = class extends r {
206
231
  }
207
232
  };
208
233
  i([e({ type: String })], c.prototype, "label", void 0), i([e({ type: String })], c.prototype, "name", void 0), i([e({ type: String })], c.prototype, "value", void 0), i([e({
234
+ type: String,
235
+ attribute: "help-text"
236
+ })], c.prototype, "helpText", void 0), i([e({
209
237
  type: String,
210
238
  reflect: !0
211
239
  })], c.prototype, "status", void 0), i([e({ type: Boolean })], c.prototype, "checked", void 0), i([e({
@@ -1 +1 @@
1
- {"version":3,"file":"fhi-checkbox.js","names":[],"sources":["../../src/components/fhi-checkbox/fhi-checkbox.component.ts"],"sourcesContent":["import { html, css, LitElement } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\n\nexport const FhiCheckboxSelector = 'fhi-checkbox';\n\n/**\n * ## FHI Checkbox\n *\n * {@link https://designsystem.fhi.no/?path=/docs/komponenter-checkbox--docs}\n *\n * The `<fhi-checkbox>` component represents a checkbox input element styled and implemented according to the FHI Design System guidelines.\n * It allows users to make binary choices, such as selecting or deselecting an option.\n *\n * @tag fhi-checkbox\n * @element fhi-checkbox\n */\n@customElement(FhiCheckboxSelector)\nexport class FhiCheckbox extends LitElement {\n /** @internal */\n static readonly formAssociated = true;\n\n /**\n * The text label assigned to and displayed next to the checkbox.\n * You should always provide a label.\n * @type {string}\n */\n @property({ type: String }) label?: string = undefined;\n\n /**\n * The name of the checkbox. This is submitted with the form data as a `key` when the checkbox is checked.\n * @type {string}\n */\n @property({ type: String }) name?: string = undefined;\n\n /**\n * The value of the checkbox. This is submitted with the form data as a `value` when the checkbox is checked.\n * @type {string}\n */\n @property({ type: String }) value: string = 'on';\n\n /**\n * Sets the visual status of the checkbox. There is currently only one status available: `error`.\n * The `error` status is used to indicate that there is an issue with the checkbox, such as a required checkbox not being checked.\n * @reflect\n * @type {'error' | undefined}\n */\n @property({ type: String, reflect: true }) status?: 'error' | undefined;\n\n /**\n * Whether the checkbox is checked or not.\n * @type {boolean}\n */\n @property({ type: Boolean }) checked? = false;\n\n /**\n * Disables the checkbox. This changes its appearance and makes it non-interactive.\n * @reflect\n * @type {boolean}\n */\n @property({ type: Boolean, reflect: true }) disabled? = false;\n\n private _internals: ElementInternals;\n\n constructor() {\n super();\n this._internals = this.attachInternals();\n }\n\n connectedCallback(): void {\n super.connectedCallback();\n this._updateFormValue();\n }\n\n private _handleChange(event: Event): void {\n this.checked = (event.target as HTMLInputElement).checked;\n this._updateFormValue();\n\n event.stopPropagation();\n this._dispatchChangeEvent();\n }\n\n private _handleInput(event: Event): void {\n event.stopPropagation();\n this._dispatchInputEvent();\n }\n\n private _updateFormValue() {\n this._internals.setFormValue(this.checked ? this.value : null);\n }\n\n private _dispatchChangeEvent(): void {\n /**\n * @type {Event} - Standard DOM event with the type `change`.\n * This event is dispatched when the checkbox is checked or unchecked.\n */\n this.dispatchEvent(new Event('change', { bubbles: true }));\n }\n\n private _dispatchInputEvent(): void {\n /**\n * @type {Event} - Standard DOM event with the type `input`.\n * This event is dispatched when the checkbox is checked or unchecked.\n */\n this.dispatchEvent(new Event('input', { bubbles: true, composed: true }));\n }\n\n public formResetCallback() {\n this.checked = false;\n this._updateFormValue();\n }\n\n render() {\n return html`\n <label>\n <input\n type=\"checkbox\"\n name=\"${ifDefined(this.name)}\"\n value=\"${ifDefined(this.value)}\"\n ?disabled=${this.disabled}\n ?checked=${this.checked}\n @change=${this._handleChange}\n @input=${this._handleInput}\n />\n <svg\n class=\"checkmark\"\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 18 18\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M12.043 6.04295C12.4335 5.65243 13.0666 5.65243 13.4571 6.04295C13.8476 6.43348 13.8476 7.06649 13.4571 7.45702L8.95708 11.957C8.56655 12.3475 7.93354 12.3475 7.54302 11.957L5.29302 9.70702C4.90249 9.31649 4.90249 8.68348 5.29302 8.29295C5.65913 7.92684 6.23813 7.90424 6.63091 8.22459L6.70708 8.29295L8.25005 9.83592L12.043 6.04295Z\"\n />\n </svg>\n\n ${this.label}\n </label>\n `;\n }\n\n static styles = css`\n :host {\n --fhi-checkbox-color: currentcolor;\n }\n\n :host {\n display: flex;\n align-items: center;\n width: max-content;\n\n label {\n align-items: center;\n display: flex;\n position: relative;\n color: var(--fhi-checkbox-color);\n font-family: var(--fhi-font-family-default);\n -webkit-font-smoothing: antialiased;\n font-size: var(--fhi-typography-body-medium-font-size);\n font-weight: var(--fhi-typography-body-medium-font-weight);\n line-height: var(--fhi-typography-body-medium-line-height);\n letter-spacing: var(--fhi-typography-body-medium-letter-spacing);\n gap: var(--fhi-spacing-050);\n }\n\n input[type='checkbox'] {\n margin: 3px;\n appearance: none;\n width: 1.125rem;\n height: 1.125rem;\n background-color: var(--fhi-color-neutral-background-default);\n border: var(--fhi-dimension-border-width) solid\n var(--fhi-color-neutral-border-default);\n border-radius: var(--fhi-border-radius-050);\n transition: var(--fhi-motion-ease-default)\n var(--fhi-motion-duration-quick);\n\n &:hover {\n background-color: var(--fhi-color-accent-background-subtle);\n border-color: var(--fhi-color-accent-border-strong);\n }\n\n &:active {\n background-color: var(--fhi-color-accent-surface-default);\n outline: solid 5px var(--fhi-color-accent-surface-hover);\n border-color: var(--fhi-color-accent-border-strong);\n }\n\n &:checked {\n background-color: var(--fhi-color-neutral-base-default);\n border-color: var(--fhi-color-neutral-base-default);\n ~ .checkmark {\n fill: var(--fhi-color-neutral-text-inverted);\n visibility: visible;\n opacity: 1;\n }\n\n &:hover {\n background-color: var(--fhi-color-accent-base-hover);\n border-color: var(--fhi-color-accent-base-hover);\n }\n &:active {\n background-color: var(--fhi-color-accent-base-active);\n border-color: var(--fhi-color-accent-base-active);\n }\n }\n }\n\n .checkmark {\n visibility: hidden;\n opacity: 0;\n transition: opacity var(--fhi-motion-ease-default)\n var(--fhi-motion-duration-quick);\n position: absolute;\n height: 1.125rem;\n width: 1.125rem;\n margin-left: 3px;\n }\n }\n\n :host([disabled]) {\n opacity: var(--fhi-opacity-disabled);\n label,\n input {\n cursor: not-allowed;\n }\n\n input {\n &:hover {\n background-color: var(--fhi-color-neutral-background-default);\n border-color: var(--fhi-color-neutral-border-default);\n }\n\n &:active {\n outline: none;\n background-color: var(--fhi-color-neutral-background-default);\n border-color: var(--fhi-color-neutral-border-default);\n }\n\n &:checked:hover {\n background-color: var(--fhi-color-neutral-base-default);\n border-color: var(--fhi-color-neutral-base-default);\n }\n\n &:checked:active {\n background-color: var(--fhi-color-neutral-base-default);\n border-color: var(--fhi-color-neutral-base-default);\n }\n }\n }\n\n :host([status='error']:not([disabled])) {\n input[type='checkbox'] {\n background-color: var(--fhi-color-danger-background-default);\n border-color: var(--fhi-color-danger-border-default);\n\n &:hover {\n background-color: var(--fhi-color-danger-background-subtle);\n border-color: var(--fhi-color-danger-border-strong);\n }\n\n &:active {\n background-color: var(--fhi-color-danger-surface-default);\n outline: solid 5px var(--fhi-color-danger-surface-hover);\n border-color: var(--fhi-color-danger-border-strong);\n }\n\n &:checked {\n background-color: var(--fhi-color-danger-base-default);\n border-color: var(--fhi-color-danger-base-default);\n &:hover {\n background-color: var(--fhi-color-danger-base-hover);\n border-color: var(--fhi-color-danger-base-hover);\n }\n\n &:active {\n background-color: var(--fhi-color-danger-base-active);\n border-color: var(--fhi-color-danger-base-active);\n }\n }\n }\n }\n `;\n}\n"],"mappings":";;;AAIA,IAAa,IAAsB,gBAc5B,IAAA,cAA0B,EAAW;;wBAET;;CA4CjC,cAAc;EAEZ,AADA,MAAM,gBAtCqC,KAAA,eAMD,KAAA,gBAMA,qBAcJ,oBAOgB,IAMtD,KAAK,aAAa,KAAK,gBAAgB;CACzC;CAEA,oBAA0B;EAExB,AADA,MAAM,kBAAkB,GACxB,KAAK,iBAAiB;CACxB;CAEA,cAAsB,GAAoB;EAKxC,AAJA,KAAK,UAAW,EAAM,OAA4B,SAClD,KAAK,iBAAiB,GAEtB,EAAM,gBAAgB,GACtB,KAAK,qBAAqB;CAC5B;CAEA,aAAqB,GAAoB;EAEvC,AADA,EAAM,gBAAgB,GACtB,KAAK,oBAAoB;CAC3B;CAEA,mBAA2B;EACzB,KAAK,WAAW,aAAa,KAAK,UAAU,KAAK,QAAQ,IAAI;CAC/D;CAEA,uBAAqC;EAKnC,KAAK,cAAc,IAAI,MAAM,UAAU,EAAE,SAAS,GAAK,CAAC,CAAC;CAC3D;CAEA,sBAAoC;EAKlC,KAAK,cAAc,IAAI,MAAM,SAAS;GAAE,SAAS;GAAM,UAAU;EAAK,CAAC,CAAC;CAC1E;CAEA,oBAA2B;EAEzB,AADA,KAAK,UAAU,IACf,KAAK,iBAAiB;CACxB;CAEA,SAAS;EACP,OAAO,CAAI;;;;kBAIG,EAAU,KAAK,IAAI,EAAE;mBACpB,EAAU,KAAK,KAAK,EAAE;sBACnB,KAAK,SAAS;qBACf,KAAK,QAAQ;oBACd,KAAK,cAAc;mBACpB,KAAK,aAAa;;;;;;;;;;;;;;UAc3B,KAAK,MAAM;;;CAGnB;;gBAEgB,CAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8IrB;GAhQG,EAAS,EAAE,MAAM,OAAO,CAAC,CAAA,GAAA,EAAA,WAAA,SAAA,KAAA,CAAA,MAMzB,EAAS,EAAE,MAAM,OAAO,CAAC,CAAA,GAAA,EAAA,WAAA,QAAA,KAAA,CAAA,MAMzB,EAAS,EAAE,MAAM,OAAO,CAAC,CAAA,GAAA,EAAA,WAAA,SAAA,KAAA,CAAA,MAQzB,EAAS;CAAE,MAAM;CAAQ,SAAS;AAAK,CAAC,CAAA,GAAA,EAAA,WAAA,UAAA,KAAA,CAAA,MAMxC,EAAS,EAAE,MAAM,QAAQ,CAAC,CAAA,GAAA,EAAA,WAAA,WAAA,KAAA,CAAA,MAO1B,EAAS;CAAE,MAAM;CAAS,SAAS;AAAK,CAAC,CAAA,GAAA,EAAA,WAAA,YAAA,KAAA,CAAA,UA3C3C,EAAc,CAAmB,CAAA,GAAA,CAAA"}
1
+ {"version":3,"file":"fhi-checkbox.js","names":[],"sources":["../../src/components/fhi-checkbox/fhi-checkbox.component.ts"],"sourcesContent":["import { html, css, LitElement, PropertyValues } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\n\nimport '../typography/fhi-body/fhi-body.component';\n\nexport const FhiCheckboxSelector = 'fhi-checkbox';\n\n/**\n * ## FHI Checkbox\n *\n * {@link https://designsystem.fhi.no/?path=/docs/komponenter-checkbox--docs}\n *\n * The `<fhi-checkbox>` component represents a checkbox input element styled and implemented according to the FHI Design System guidelines.\n * It allows users to make binary choices, such as selecting or deselecting an option.\n *\n * @tag fhi-checkbox\n * @element fhi-checkbox\n */\n@customElement(FhiCheckboxSelector)\nexport class FhiCheckbox extends LitElement {\n /** @internal */\n static readonly formAssociated = true;\n\n /**\n * The text label assigned to and displayed next to the checkbox.\n * You should always provide a label.\n * @type {string}\n */\n @property({ type: String }) label?: string = undefined;\n\n /**\n * The name of the checkbox. This is submitted with the form data as a `key` when the checkbox is checked.\n * @type {string}\n */\n @property({ type: String }) name?: string = undefined;\n\n /**\n * The value of the checkbox. This is submitted with the form data as a `value` when the checkbox is checked.\n * @type {string}\n */\n @property({ type: String }) value: string = 'on';\n\n /**\n * The help text shown below the label.\n * This is used to provide additional information or descriptions to the user.\n * @type {string}\n */\n @property({ type: String, attribute: 'help-text' }) helpText?: string;\n\n /**\n * Sets the visual status of the checkbox. There is currently only one status available: `error`.\n * The `error` status is used to indicate that there is an issue with the checkbox, such as a required checkbox not being checked.\n * @reflect\n * @type {'error' | undefined}\n */\n @property({ type: String, reflect: true }) status?: 'error' | undefined;\n\n /**\n * Whether the checkbox is checked or not.\n * @type {boolean}\n */\n @property({ type: Boolean }) checked? = false;\n\n /**\n * Disables the checkbox. This changes its appearance and makes it non-interactive.\n * @reflect\n * @type {boolean}\n */\n @property({ type: Boolean, reflect: true }) disabled? = false;\n\n private _internals: ElementInternals;\n\n constructor() {\n super();\n this._internals = this.attachInternals();\n }\n\n connectedCallback(): void {\n super.connectedCallback();\n this._updateFormValue();\n }\n\n protected updated(_changedProperties: PropertyValues<FhiCheckbox>): void {\n if (_changedProperties.has('helpText') || _changedProperties.has('label')) {\n if (!this.label && this.helpText) {\n console.error(\n 'The \"help-text\" property is set, but the \"label\" property is not. It is required to provide a label when using help text.',\n );\n }\n }\n }\n\n private _handleChange(event: Event): void {\n this.checked = (event.target as HTMLInputElement).checked;\n this._updateFormValue();\n\n event.stopPropagation();\n this._dispatchChangeEvent();\n }\n\n private _handleInput(event: Event): void {\n event.stopPropagation();\n this._dispatchInputEvent();\n }\n\n private _updateFormValue() {\n this._internals.setFormValue(this.checked ? this.value : null);\n }\n\n private _dispatchChangeEvent(): void {\n /**\n * @type {Event} - Standard DOM event with the type `change`.\n * This event is dispatched when the checkbox is checked or unchecked.\n */\n this.dispatchEvent(new Event('change', { bubbles: true }));\n }\n\n private _dispatchInputEvent(): void {\n /**\n * @type {Event} - Standard DOM event with the type `input`.\n * This event is dispatched when the checkbox is checked or unchecked.\n */\n this.dispatchEvent(new Event('input', { bubbles: true, composed: true }));\n }\n\n public formResetCallback() {\n this.checked = false;\n this._updateFormValue();\n }\n\n render() {\n return html`\n <div class=\"checkbox-wrapper\">\n <input\n type=\"checkbox\"\n id=\"checkbox-element\"\n name=\"${ifDefined(this.name)}\"\n value=\"${ifDefined(this.value)}\"\n ?disabled=${this.disabled}\n ?checked=${this.checked}\n @change=${this._handleChange}\n @input=${this._handleInput}\n />\n <svg\n class=\"checkmark\"\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 18 18\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M12.043 6.04295C12.4335 5.65243 13.0666 5.65243 13.4571 6.04295C13.8476 6.43348 13.8476 7.06649 13.4571 7.45702L8.95708 11.957C8.56655 12.3475 7.93354 12.3475 7.54302 11.957L5.29302 9.70702C4.90249 9.31649 4.90249 8.68348 5.29302 8.29295C5.65913 7.92684 6.23813 7.90424 6.63091 8.22459L6.70708 8.29295L8.25005 9.83592L12.043 6.04295Z\"\n />\n </svg>\n </div>\n ${this.label && html`<label for=\"checkbox-element\">${this.label}</label>`}\n ${this.helpText\n ? html`<fhi-body size=\"small\" class=\"help-text\"\n >${this.helpText}</fhi-body\n >`\n : ''}\n `;\n }\n\n static styles = css`\n :host {\n --fhi-checkbox-color: currentcolor;\n }\n\n :host {\n display: grid;\n width: max-content;\n height: fit-content;\n color: var(--fhi-checkbox-color);\n\n .checkbox-wrapper {\n position: relative;\n height: fit-content;\n }\n\n label {\n font-family: var(--fhi-font-family-default);\n -webkit-font-smoothing: antialiased;\n font-size: var(--fhi-typography-body-medium-font-size);\n font-weight: var(--fhi-typography-body-medium-font-weight);\n line-height: var(--fhi-typography-body-medium-line-height);\n letter-spacing: var(--fhi-typography-body-medium-letter-spacing);\n }\n\n label,\n fhi-body {\n grid-column: 2;\n padding-left: 7px;\n }\n\n input[type='checkbox'] {\n margin: 3px 0 0 3px;\n appearance: none;\n width: 1.125rem;\n height: 1.125rem;\n background-color: var(--fhi-color-neutral-background-default);\n border: var(--fhi-dimension-border-width) solid\n var(--fhi-color-neutral-border-default);\n border-radius: var(--fhi-border-radius-050);\n transition: all var(--fhi-motion-ease-default)\n var(--fhi-motion-duration-quick);\n &:not(:focus-visible) {\n outline-color: var(--fhi-color-accent-surface-hover);\n }\n\n &:hover {\n background-color: var(--fhi-color-accent-background-subtle);\n border-color: var(--fhi-color-accent-border-strong);\n }\n\n &:active {\n background-color: var(--fhi-color-accent-surface-default);\n outline: solid 5px var(--fhi-color-accent-surface-hover);\n border-color: var(--fhi-color-accent-border-strong);\n }\n\n &:checked {\n background-color: var(--fhi-color-neutral-base-default);\n border-color: var(--fhi-color-neutral-base-default);\n ~ .checkmark {\n fill: var(--fhi-color-neutral-text-inverted);\n visibility: visible;\n opacity: 1;\n }\n\n &:hover {\n background-color: var(--fhi-color-accent-base-hover);\n border-color: var(--fhi-color-accent-base-hover);\n }\n &:active {\n background-color: var(--fhi-color-accent-base-active);\n border-color: var(--fhi-color-accent-base-active);\n }\n }\n }\n\n .checkmark {\n visibility: hidden;\n opacity: 0;\n transition: opacity var(--fhi-motion-ease-default)\n var(--fhi-motion-duration-quick);\n position: absolute;\n top: 3px;\n left: 3px;\n height: 1.125rem;\n width: 1.125rem;\n pointer-events: none;\n }\n\n .help-text {\n color: var(--fhi-color-neutral-text-subtle);\n }\n }\n\n :host([disabled]) {\n opacity: var(--fhi-opacity-disabled);\n * {\n cursor: not-allowed;\n }\n\n input {\n &:hover {\n background-color: var(--fhi-color-neutral-background-default);\n border-color: var(--fhi-color-neutral-border-default);\n }\n\n &:active {\n outline: none;\n background-color: var(--fhi-color-neutral-background-default);\n border-color: var(--fhi-color-neutral-border-default);\n }\n\n &:checked:hover {\n background-color: var(--fhi-color-neutral-base-default);\n border-color: var(--fhi-color-neutral-base-default);\n }\n\n &:checked:active {\n background-color: var(--fhi-color-neutral-base-default);\n border-color: var(--fhi-color-neutral-base-default);\n }\n }\n }\n\n :host([status='error']:not([disabled])) {\n input[type='checkbox'] {\n background-color: var(--fhi-color-danger-background-default);\n border-color: var(--fhi-color-danger-border-default);\n &:not(:focus-visible) {\n outline-color: var(--fhi-color-danger-surface-hover);\n }\n\n &:hover {\n background-color: var(--fhi-color-danger-background-subtle);\n border-color: var(--fhi-color-danger-border-strong);\n }\n\n &:active {\n background-color: var(--fhi-color-danger-surface-default);\n border-color: var(--fhi-color-danger-border-strong);\n outline-color: var(--fhi-color-danger-surface-hover);\n }\n\n &:checked {\n background-color: var(--fhi-color-danger-base-default);\n border-color: var(--fhi-color-danger-base-default);\n &:hover {\n background-color: var(--fhi-color-danger-base-hover);\n border-color: var(--fhi-color-danger-base-hover);\n }\n\n &:active {\n background-color: var(--fhi-color-danger-base-active);\n border-color: var(--fhi-color-danger-base-active);\n }\n }\n }\n }\n `;\n}\n"],"mappings":";;;;AAMA,IAAa,IAAsB,gBAc5B,IAAA,cAA0B,EAAW;;wBAET;;CAmDjC,cAAc;EAEZ,AADA,MAAM,gBA7CqC,KAAA,eAMD,KAAA,gBAMA,qBAqBJ,oBAOgB,IAMtD,KAAK,aAAa,KAAK,gBAAgB;CACzC;CAEA,oBAA0B;EAExB,AADA,MAAM,kBAAkB,GACxB,KAAK,iBAAiB;CACxB;CAEA,QAAkB,GAAuD;EACvE,CAAI,EAAmB,IAAI,UAAU,KAAK,EAAmB,IAAI,OAAO,MAClE,CAAC,KAAK,SAAS,KAAK,YACtB,QAAQ,MACN,+HACF;CAGN;CAEA,cAAsB,GAAoB;EAKxC,AAJA,KAAK,UAAW,EAAM,OAA4B,SAClD,KAAK,iBAAiB,GAEtB,EAAM,gBAAgB,GACtB,KAAK,qBAAqB;CAC5B;CAEA,aAAqB,GAAoB;EAEvC,AADA,EAAM,gBAAgB,GACtB,KAAK,oBAAoB;CAC3B;CAEA,mBAA2B;EACzB,KAAK,WAAW,aAAa,KAAK,UAAU,KAAK,QAAQ,IAAI;CAC/D;CAEA,uBAAqC;EAKnC,KAAK,cAAc,IAAI,MAAM,UAAU,EAAE,SAAS,GAAK,CAAC,CAAC;CAC3D;CAEA,sBAAoC;EAKlC,KAAK,cAAc,IAAI,MAAM,SAAS;GAAE,SAAS;GAAM,UAAU;EAAK,CAAC,CAAC;CAC1E;CAEA,oBAA2B;EAEzB,AADA,KAAK,UAAU,IACf,KAAK,iBAAiB;CACxB;CAEA,SAAS;EACP,OAAO,CAAI;;;;;kBAKG,EAAU,KAAK,IAAI,EAAE;mBACpB,EAAU,KAAK,KAAK,EAAE;sBACnB,KAAK,SAAS;qBACf,KAAK,QAAQ;oBACd,KAAK,cAAc;mBACpB,KAAK,aAAa;;;;;;;;;;;;;;QAc7B,KAAK,SAAS,CAAI,iCAAiC,KAAK,MAAM,UAAU;QACxE,KAAK,WACH,CAAI;eACC,KAAK,SAAS;eAEnB,GAAG;;CAEX;;gBAEgB,CAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgKrB;GAxSG,EAAS,EAAE,MAAM,OAAO,CAAC,CAAA,GAAA,EAAA,WAAA,SAAA,KAAA,CAAA,MAMzB,EAAS,EAAE,MAAM,OAAO,CAAC,CAAA,GAAA,EAAA,WAAA,QAAA,KAAA,CAAA,MAMzB,EAAS,EAAE,MAAM,OAAO,CAAC,CAAA,GAAA,EAAA,WAAA,SAAA,KAAA,CAAA,MAOzB,EAAS;CAAE,MAAM;CAAQ,WAAW;AAAY,CAAC,CAAA,GAAA,EAAA,WAAA,YAAA,KAAA,CAAA,MAQjD,EAAS;CAAE,MAAM;CAAQ,SAAS;AAAK,CAAC,CAAA,GAAA,EAAA,WAAA,UAAA,KAAA,CAAA,MAMxC,EAAS,EAAE,MAAM,QAAQ,CAAC,CAAA,GAAA,EAAA,WAAA,WAAA,KAAA,CAAA,MAO1B,EAAS;CAAE,MAAM;CAAS,SAAS;AAAK,CAAC,CAAA,GAAA,EAAA,WAAA,YAAA,KAAA,CAAA,UAlD3C,EAAc,CAAmB,CAAA,GAAA,CAAA"}
@@ -1 +1 @@
1
- {"kind":"javascript-module","path":"src/components/fhi-checkbox/fhi-checkbox.component.ts","declarations":[{"kind":"class","description":"## FHI Checkbox\n\nhttps://designsystem.fhi.no/?path=/docs/komponenter-checkbox--docs\n\nThe `<fhi-checkbox>` component represents a checkbox input element styled and implemented according to the FHI Design System guidelines.\nIt allows users to make binary choices, such as selecting or deselecting an option.","name":"FhiCheckbox","members":[{"kind":"method","name":"_dispatchChangeEvent","privacy":"private","return":{"type":{"text":"void"}}},{"kind":"method","name":"_dispatchInputEvent","privacy":"private","return":{"type":{"text":"void"}}},{"kind":"method","name":"_handleChange","privacy":"private","return":{"type":{"text":"void"}},"parameters":[{"name":"event","type":{"text":"Event"}}]},{"kind":"method","name":"_handleInput","privacy":"private","return":{"type":{"text":"void"}},"parameters":[{"name":"event","type":{"text":"Event"}}]},{"kind":"field","name":"_internals","type":{"text":"ElementInternals"},"privacy":"private"},{"kind":"method","name":"_updateFormValue","privacy":"private"},{"kind":"field","name":"checked","type":{"text":"boolean"},"default":"false","description":"Whether the checkbox is checked or not.","attribute":"checked"},{"kind":"field","name":"disabled","type":{"text":"boolean"},"default":"false","description":"Disables the checkbox. This changes its appearance and makes it non-interactive.","reflects":true,"attribute":"disabled"},{"kind":"method","name":"formResetCallback","privacy":"public"},{"kind":"field","name":"label","type":{"text":"string"},"default":"undefined","description":"The text label assigned to and displayed next to the checkbox.\nYou should always provide a label.","attribute":"label"},{"kind":"field","name":"name","type":{"text":"string"},"default":"undefined","description":"The name of the checkbox. This is submitted with the form data as a `key` when the checkbox is checked.","attribute":"name"},{"kind":"field","name":"status","type":{"text":"'error' | undefined"},"description":"Sets the visual status of the checkbox. There is currently only one status available: `error`.\nThe `error` status is used to indicate that there is an issue with the checkbox, such as a required checkbox not being checked.","reflects":true,"attribute":"status"},{"kind":"field","name":"value","type":{"text":"string"},"default":"'on'","description":"The value of the checkbox. This is submitted with the form data as a `value` when the checkbox is checked.","attribute":"value"}],"events":[{"name":"change","type":{"text":"Event"},"description":"Standard DOM event with the type `change`.\nThis event is dispatched when the checkbox is checked or unchecked."},{"name":"input","type":{"text":"Event"},"description":"Standard DOM event with the type `input`.\nThis event is dispatched when the checkbox is checked or unchecked."}],"attributes":[{"name":"checked","type":{"text":"boolean"},"default":"false","description":"Whether the checkbox is checked or not.","fieldName":"checked"},{"name":"disabled","type":{"text":"boolean"},"default":"false","description":"Disables the checkbox. This changes its appearance and makes it non-interactive.","fieldName":"disabled"},{"name":"label","type":{"text":"string"},"default":"undefined","description":"The text label assigned to and displayed next to the checkbox.\nYou should always provide a label.","fieldName":"label"},{"name":"name","type":{"text":"string"},"default":"undefined","description":"The name of the checkbox. This is submitted with the form data as a `key` when the checkbox is checked.","fieldName":"name"},{"name":"status","type":{"text":"'error' | undefined"},"description":"Sets the visual status of the checkbox. There is currently only one status available: `error`.\nThe `error` status is used to indicate that there is an issue with the checkbox, such as a required checkbox not being checked.","fieldName":"status"},{"name":"value","type":{"text":"string"},"default":"'on'","description":"The value of the checkbox. This is submitted with the form data as a `value` when the checkbox is checked.","fieldName":"value"}],"superclass":{"name":"LitElement","package":"lit"},"tagName":"fhi-checkbox","customElement":true},{"kind":"variable","name":"FhiCheckboxSelector","type":{"text":"string"},"default":"'fhi-checkbox'"}]}
1
+ {"kind":"javascript-module","path":"src/components/fhi-checkbox/fhi-checkbox.component.ts","declarations":[{"kind":"class","description":"## FHI Checkbox\n\nhttps://designsystem.fhi.no/?path=/docs/komponenter-checkbox--docs\n\nThe `<fhi-checkbox>` component represents a checkbox input element styled and implemented according to the FHI Design System guidelines.\nIt allows users to make binary choices, such as selecting or deselecting an option.","name":"FhiCheckbox","members":[{"kind":"method","name":"_dispatchChangeEvent","privacy":"private","return":{"type":{"text":"void"}}},{"kind":"method","name":"_dispatchInputEvent","privacy":"private","return":{"type":{"text":"void"}}},{"kind":"method","name":"_handleChange","privacy":"private","return":{"type":{"text":"void"}},"parameters":[{"name":"event","type":{"text":"Event"}}]},{"kind":"method","name":"_handleInput","privacy":"private","return":{"type":{"text":"void"}},"parameters":[{"name":"event","type":{"text":"Event"}}]},{"kind":"field","name":"_internals","type":{"text":"ElementInternals"},"privacy":"private"},{"kind":"method","name":"_updateFormValue","privacy":"private"},{"kind":"field","name":"checked","type":{"text":"boolean"},"default":"false","description":"Whether the checkbox is checked or not.","attribute":"checked"},{"kind":"field","name":"disabled","type":{"text":"boolean"},"default":"false","description":"Disables the checkbox. This changes its appearance and makes it non-interactive.","reflects":true,"attribute":"disabled"},{"kind":"method","name":"formResetCallback","privacy":"public"},{"kind":"field","name":"helpText","type":{"text":"string"},"description":"The help text shown below the label.\nThis is used to provide additional information or descriptions to the user.","attribute":"help-text"},{"kind":"field","name":"label","type":{"text":"string"},"default":"undefined","description":"The text label assigned to and displayed next to the checkbox.\nYou should always provide a label.","attribute":"label"},{"kind":"field","name":"name","type":{"text":"string"},"default":"undefined","description":"The name of the checkbox. This is submitted with the form data as a `key` when the checkbox is checked.","attribute":"name"},{"kind":"field","name":"status","type":{"text":"'error' | undefined"},"description":"Sets the visual status of the checkbox. There is currently only one status available: `error`.\nThe `error` status is used to indicate that there is an issue with the checkbox, such as a required checkbox not being checked.","reflects":true,"attribute":"status"},{"kind":"field","name":"value","type":{"text":"string"},"default":"'on'","description":"The value of the checkbox. This is submitted with the form data as a `value` when the checkbox is checked.","attribute":"value"}],"events":[{"name":"change","type":{"text":"Event"},"description":"Standard DOM event with the type `change`.\nThis event is dispatched when the checkbox is checked or unchecked."},{"name":"input","type":{"text":"Event"},"description":"Standard DOM event with the type `input`.\nThis event is dispatched when the checkbox is checked or unchecked."}],"attributes":[{"name":"checked","type":{"text":"boolean"},"default":"false","description":"Whether the checkbox is checked or not.","fieldName":"checked"},{"name":"disabled","type":{"text":"boolean"},"default":"false","description":"Disables the checkbox. This changes its appearance and makes it non-interactive.","fieldName":"disabled"},{"name":"help-text","type":{"text":"string"},"description":"The help text shown below the label.\nThis is used to provide additional information or descriptions to the user.","fieldName":"helpText"},{"name":"label","type":{"text":"string"},"default":"undefined","description":"The text label assigned to and displayed next to the checkbox.\nYou should always provide a label.","fieldName":"label"},{"name":"name","type":{"text":"string"},"default":"undefined","description":"The name of the checkbox. This is submitted with the form data as a `key` when the checkbox is checked.","fieldName":"name"},{"name":"status","type":{"text":"'error' | undefined"},"description":"Sets the visual status of the checkbox. There is currently only one status available: `error`.\nThe `error` status is used to indicate that there is an issue with the checkbox, such as a required checkbox not being checked.","fieldName":"status"},{"name":"value","type":{"text":"string"},"default":"'on'","description":"The value of the checkbox. This is submitted with the form data as a `value` when the checkbox is checked.","fieldName":"value"}],"superclass":{"name":"LitElement","package":"lit"},"tagName":"fhi-checkbox","customElement":true},{"kind":"variable","name":"FhiCheckboxSelector","type":{"text":"string"},"default":"'fhi-checkbox'"}]}
package/fhi-radio.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { a as e, d as t, o as n, r, s as i, t as a, u as o } from "./decorate-DFXIek-k.js";
2
2
  import { t as s } from "./if-defined-Dl-W5B5_.js";
3
+ import "./fhi-body.js";
3
4
  //#region src/components/fhi-radio/fhi-radio.component.ts
4
5
  var c = "fhi-radio", l = class extends i {
5
6
  static {
@@ -27,7 +28,7 @@ var c = "fhi-radio", l = class extends i {
27
28
  }), !e.some((e) => e.checked) && e.length > 0 && (e[0].tabIndex = 0);
28
29
  }
29
30
  updated(e) {
30
- super.updated(e), e.has("checked") && (this._input.checked = !!this.checked, this._updateFormValue(), this.checked && this.uncheckGroupMembers()), (e.has("value") || e.has("name")) && this._input.checked && this._updateFormValue();
31
+ super.updated(e), e.has("checked") && (this._input.checked = !!this.checked, this._updateFormValue(), this.checked && this.uncheckGroupMembers()), (e.has("value") || e.has("name")) && this._input.checked && this._updateFormValue(), (e.has("helpText") || e.has("label")) && !this.label && this.helpText && console.error("The \"help-text\" property is set, but the \"label\" property is not. It is required to provide a label when using help text.");
31
32
  }
32
33
  formResetCallback() {
33
34
  this._getRadioGroup().filter((e) => typeof e.getAttribute("checked") == "string").pop() === this && (this.checked = !0), this._updateFormValue();
@@ -70,28 +71,29 @@ var c = "fhi-radio", l = class extends i {
70
71
  }
71
72
  render() {
72
73
  return o`
73
- <label>
74
- <div class="radio-container">
75
- <input
76
- type="radio"
77
- id="input-element"
78
- name="${s(this.name)}"
79
- value="${this.value}"
80
- ?checked=${this.checked}
81
- ?disabled=${this.disabled}
82
- @change=${this._handleChange}
83
- @input=${this._handleInput}
84
- />
85
- <svg
86
- class="radio-dot"
87
- viewBox="0 0 18 18"
88
- xmlns="http://www.w3.org/2000/svg"
89
- >
90
- <circle r="6" cx="9" cy="9" />
91
- </svg>
92
- </div>
93
- ${this.label}
94
- </label>
74
+ <div class="radio-wrapper">
75
+ <input
76
+ type="radio"
77
+ id="input-element"
78
+ name="${s(this.name)}"
79
+ value="${this.value}"
80
+ ?checked=${this.checked}
81
+ ?disabled=${this.disabled}
82
+ @change=${this._handleChange}
83
+ @input=${this._handleInput}
84
+ />
85
+ <svg
86
+ class="radio-dot"
87
+ viewBox="0 0 18 18"
88
+ xmlns="http://www.w3.org/2000/svg"
89
+ >
90
+ <circle r="6" cx="9" cy="9" />
91
+ </svg>
92
+ </div>
93
+ ${this.label && o`<label for="input-element">${this.label}</label>`}
94
+ ${this.helpText ? o`<fhi-body size="small" class="help-text"
95
+ >${this.helpText}</fhi-body
96
+ >` : ""}
95
97
  `;
96
98
  }
97
99
  static {
@@ -101,15 +103,20 @@ var c = "fhi-radio", l = class extends i {
101
103
  }
102
104
 
103
105
  :host {
104
- display: flex;
105
- align-items: center;
106
+ display: grid;
106
107
  width: max-content;
108
+ height: fit-content;
109
+ grid-template-columns: auto auto;
110
+ color: var(--fhi-radio-color);
111
+ padding-left: 0.125rem;
107
112
 
108
- label {
113
+ .radio-wrapper {
109
114
  display: flex;
110
115
  position: relative;
111
- gap: var(--fhi-spacing-050);
112
- color: var(--fhi-radio-color);
116
+ height: fit-content;
117
+ }
118
+
119
+ label {
113
120
  font-family: var(--fhi-font-family-default);
114
121
  -webkit-font-smoothing: antialiased;
115
122
  font-size: var(--fhi-typography-body-medium-font-size);
@@ -118,14 +125,15 @@ var c = "fhi-radio", l = class extends i {
118
125
  letter-spacing: var(--fhi-typography-body-medium-letter-spacing);
119
126
  }
120
127
 
121
- .radio-container {
122
- display: flex;
123
- position: relative;
128
+ label,
129
+ fhi-body {
130
+ grid-column: 2;
131
+ padding-left: 6px;
124
132
  }
125
133
 
126
134
  input {
135
+ margin: 0.125rem 0 0.125rem 0;
127
136
  appearance: none;
128
- margin: 0.125rem;
129
137
  width: var(--fhi-spacing-250);
130
138
  height: var(--fhi-spacing-250);
131
139
  background-color: var(--fhi-color-neutral-background-default);
@@ -134,6 +142,9 @@ var c = "fhi-radio", l = class extends i {
134
142
  border-radius: var(--fhi-border-radius-full);
135
143
  transition: all var(--fhi-motion-ease-default)
136
144
  var(--fhi-motion-duration-quick);
145
+ &:not(:focus-visible) {
146
+ outline-color: var(--fhi-color-accent-surface-hover);
147
+ }
137
148
  }
138
149
 
139
150
  .radio-dot {
@@ -145,7 +156,6 @@ var c = "fhi-radio", l = class extends i {
145
156
  top: 50%;
146
157
  left: 50%;
147
158
  transform: translate(-50%, -50%);
148
- height: 1.125rem;
149
159
  width: 1.125rem;
150
160
  }
151
161
 
@@ -159,12 +169,15 @@ var c = "fhi-radio", l = class extends i {
159
169
  opacity: 1;
160
170
  }
161
171
  }
172
+
173
+ .help-text {
174
+ color: var(--fhi-color-neutral-text-subtle);
175
+ }
162
176
  }
163
177
 
164
178
  :host([disabled]) {
165
179
  opacity: var(--fhi-opacity-disabled);
166
- label,
167
- input {
180
+ * {
168
181
  cursor: not-allowed;
169
182
  }
170
183
  }
@@ -186,6 +199,9 @@ var c = "fhi-radio", l = class extends i {
186
199
  input {
187
200
  border-color: var(--fhi-color-danger-border-default);
188
201
  background-color: var(--fhi-color-danger-background-default);
202
+ &:not(:focus-visible) {
203
+ outline-color: var(--fhi-color-danger-surface-hover);
204
+ }
189
205
  }
190
206
 
191
207
  input:checked {
@@ -220,7 +236,10 @@ a([e({ type: String })], l.prototype, "label", void 0), a([e({
220
236
  })], l.prototype, "status", void 0), a([e({
221
237
  type: Boolean,
222
238
  reflect: !0
223
- })], l.prototype, "disabled", void 0), a([e({ type: Boolean })], l.prototype, "checked", void 0), a([e({ type: String })], l.prototype, "value", void 0), a([r("#input-element")], l.prototype, "_input", void 0), l = a([n(c)], l);
239
+ })], l.prototype, "disabled", void 0), a([e({ type: Boolean })], l.prototype, "checked", void 0), a([e({ type: String })], l.prototype, "value", void 0), a([e({
240
+ type: String,
241
+ attribute: "help-text"
242
+ })], l.prototype, "helpText", void 0), a([r("#input-element")], l.prototype, "_input", void 0), l = a([n(c)], l);
224
243
  //#endregion
225
244
  export { l as FhiRadio, c as FhiRadioSelector };
226
245
 
package/fhi-radio.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"fhi-radio.js","names":[],"sources":["../../src/components/fhi-radio/fhi-radio.component.ts"],"sourcesContent":["import { html, css, LitElement } from 'lit';\nimport { customElement, property, query } from 'lit/decorators.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\n\nexport const FhiRadioSelector = 'fhi-radio';\n\n/**\n * ## FHI Radio\n *\n * {@link https://designsystem.fhi.no/?path=/docs/komponenter-radio--docs}\n *\n * The `<fhi-radio>` component represents a single radio button.\n * It should be used within a group of options, allowing users to select one option from a set.\n *\n * @tag fhi-radio\n * @element fhi-radio\n */\n@customElement(FhiRadioSelector)\nexport class FhiRadio extends LitElement {\n static readonly formAssociated = true;\n\n /**\n * The text label assigned to and displayed next to the radio.\n * You should always provide a label.\n * @type {string}\n */\n @property({ type: String }) label?: string = undefined;\n\n /**\n * The name of the radio. This is submitted with the form data as a `key` when the checkbox is checked.\n * All `<fhi-radio>` components with the same name belong to the same group.\n * @reflect\n * @type {string}\n */\n @property({ type: String, reflect: true }) name?: string = undefined;\n\n /**\n * Sets the visual status of the radio. There is currently only one status available: `error`.\n * The `error` status is used to indicate that there is an issue with the radio, such as a required radio not being checked.\n * @reflect\n * @type {'error' | undefined}\n */\n @property({ type: String, reflect: true }) status?: 'error' = undefined;\n\n /**\n * Disables the radio. This changes its appearance and makes it non-interactive.\n * @reflect\n * @type {boolean}\n */\n @property({ type: Boolean, reflect: true }) disabled? = false;\n\n /**\n * Whether the radio button is checked or not.\n * @type {boolean}\n */\n @property({ type: Boolean }) checked? = false;\n\n /**\n * The value of the radio. This is submitted with the form data as a `value` when the radio is checked.\n * @type {string}\n */\n @property({ type: String }) value: string = 'on';\n\n @query('#input-element')\n private _input!: HTMLInputElement;\n\n private _groupRoot: Document | HTMLFormElement;\n private _internals: ElementInternals;\n\n /**\n * Indicates if the radio button is part of a form.\n * @internal\n */\n public isFormElement = false;\n\n constructor() {\n super();\n this._internals = this.attachInternals();\n this._groupRoot = document;\n }\n\n public connectedCallback(): void {\n super.connectedCallback();\n\n this.addEventListener('focus', this._setFocusOnInput);\n\n this.isFormElement = !!this._internals.form;\n\n if (this.isFormElement) {\n this._updateFormValue();\n this._groupRoot = this._internals.form!;\n }\n\n // If the radio has a name then it is part of a group and needs keyboard navigation\n if (this.name) {\n this.addEventListener('keydown', this._handleKeyDown);\n this._SetTabbableRadios();\n }\n }\n\n public disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener('keydown', this._handleKeyDown);\n this.removeEventListener('focus', this._setFocusOnInput);\n }\n\n private _setFocusOnInput() {\n this._input.focus();\n }\n\n private _getRadioGroup() {\n return Array.from(\n this._groupRoot.querySelectorAll<FhiRadio>(\n `${FhiRadioSelector}[name=\"${this.name}\"]`,\n ),\n );\n }\n\n private _SetTabbableRadios() {\n const radios = this._getRadioGroup();\n\n radios.forEach(radio => {\n // Only the checked radio should be tabbable\n radio.tabIndex = radio.checked ? 0 : -1;\n });\n\n // If none of the radios are checked, make the first one tabbable\n if (!radios.some(radio => radio.checked) && radios.length > 0) {\n radios[0].tabIndex = 0;\n }\n }\n\n public updated(changedProperties: Map<string, unknown>) {\n super.updated(changedProperties);\n\n // make sure the radio input can be programmatically toggeled. e.g by a form reset\n if (changedProperties.has('checked')) {\n this._input.checked = !!this.checked;\n this._updateFormValue();\n\n if (this.checked) {\n this.uncheckGroupMembers();\n }\n }\n\n // update the form value when the value or name input changes and the radio is already checked\n if (changedProperties.has('value') || changedProperties.has('name')) {\n if (this._input.checked) {\n this._updateFormValue();\n }\n }\n }\n\n public formResetCallback(): void {\n const radiosCheckedByDefault = this._getRadioGroup().filter(\n radio => typeof radio.getAttribute('checked') === 'string',\n );\n\n if (radiosCheckedByDefault.pop() === this) {\n this.checked = true;\n }\n\n this._updateFormValue();\n }\n\n private uncheckGroupMembers(): void {\n const radios = this._getRadioGroup();\n\n radios.forEach(radio => {\n if (radio === this) {\n return;\n }\n\n if (radio.isFormElement && this._groupRoot === document) {\n return;\n }\n\n radio.checked = false;\n });\n }\n\n private _updateFormValue(): void {\n if (!this.isFormElement) {\n return;\n }\n\n this._internals.setFormValue(this.checked ? this.value : null);\n }\n\n private _handleChange(event: Event): void {\n this.checked = (event.target as HTMLInputElement).checked;\n\n this.uncheckGroupMembers();\n\n this._updateFormValue();\n\n event.stopPropagation();\n this._dispatchChangeEvent();\n }\n private _handleInput(event: Event): void {\n event.stopPropagation();\n this._dispatchInputEvent();\n }\n\n private _dispatchChangeEvent(): void {\n /**\n * @type {Event} - Standard DOM event with the type `change`.\n * This event is dispatched when the radio is checked or unchecked.\n */\n this.dispatchEvent(new Event('change', { bubbles: true }));\n }\n\n private _dispatchInputEvent(): void {\n /**\n * @type {Event} - Standard DOM event with the type `input`.\n * This event is dispatched when the radio is checked or unchecked.\n */\n this.dispatchEvent(new Event('input', { bubbles: true, composed: true }));\n }\n\n private _handleKeyDown(event: KeyboardEvent): void {\n const arrows = ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'];\n\n if (!arrows.includes(event.key)) {\n return;\n }\n\n event.preventDefault();\n\n const radios = this._getRadioGroup();\n\n if (radios.length < 2) {\n return;\n }\n\n const currentIndex = radios.indexOf(this);\n\n const nextIndex = currentIndex;\n let nextRadio: FhiRadio;\n\n if (event.key === 'ArrowUp' || event.key === 'ArrowLeft') {\n nextRadio = radios[nextIndex === 0 ? radios.length - 1 : nextIndex - 1];\n } else {\n nextRadio = radios[nextIndex === radios.length - 1 ? 0 : nextIndex + 1];\n }\n\n nextRadio.focus();\n this.checked = false;\n nextRadio.checked = true;\n this._SetTabbableRadios();\n }\n\n render() {\n return html`\n <label>\n <div class=\"radio-container\">\n <input\n type=\"radio\"\n id=\"input-element\"\n name=\"${ifDefined(this.name)}\"\n value=\"${this.value}\"\n ?checked=${this.checked}\n ?disabled=${this.disabled}\n @change=${this._handleChange}\n @input=${this._handleInput}\n />\n <svg\n class=\"radio-dot\"\n viewBox=\"0 0 18 18\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <circle r=\"6\" cx=\"9\" cy=\"9\" />\n </svg>\n </div>\n ${this.label}\n </label>\n `;\n }\n\n static styles = css`\n :host {\n --fhi-radio-color: currentcolor;\n }\n\n :host {\n display: flex;\n align-items: center;\n width: max-content;\n\n label {\n display: flex;\n position: relative;\n gap: var(--fhi-spacing-050);\n color: var(--fhi-radio-color);\n font-family: var(--fhi-font-family-default);\n -webkit-font-smoothing: antialiased;\n font-size: var(--fhi-typography-body-medium-font-size);\n font-weight: var(--fhi-typography-body-medium-font-weight);\n line-height: var(--fhi-typography-body-medium-line-height);\n letter-spacing: var(--fhi-typography-body-medium-letter-spacing);\n }\n\n .radio-container {\n display: flex;\n position: relative;\n }\n\n input {\n appearance: none;\n margin: 0.125rem;\n width: var(--fhi-spacing-250);\n height: var(--fhi-spacing-250);\n background-color: var(--fhi-color-neutral-background-default);\n border: var(--fhi-dimension-border-width) solid\n var(--fhi-color-neutral-border-default);\n border-radius: var(--fhi-border-radius-full);\n transition: all var(--fhi-motion-ease-default)\n var(--fhi-motion-duration-quick);\n }\n\n .radio-dot {\n visibility: hidden;\n opacity: 0;\n transition: opacity var(--fhi-motion-ease-default)\n var(--fhi-motion-duration-quick);\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n height: 1.125rem;\n width: 1.125rem;\n }\n\n input:checked {\n border-width: var(--fhi-dimension-border-width-active);\n ~ .radio-dot {\n circle {\n fill: var(--fhi-color-neutral-border-default);\n }\n visibility: visible;\n opacity: 1;\n }\n }\n }\n\n :host([disabled]) {\n opacity: var(--fhi-opacity-disabled);\n label,\n input {\n cursor: not-allowed;\n }\n }\n\n :host(:not(:disabled)) {\n input:hover:not(:checked) {\n border-color: var(--fhi-color-accent-border-strong);\n background-color: var(--fhi-color-accent-background-subtle);\n }\n\n input:active:not(:checked) {\n border-color: var(--fhi-color-accent-border-strong);\n background-color: var(--fhi-color-accent-surface-default);\n outline: var(--fhi-dimension-border-width-focus) solid\n var(--fhi-color-accent-surface-hover);\n }\n\n &:host([status='error']) {\n input {\n border-color: var(--fhi-color-danger-border-default);\n background-color: var(--fhi-color-danger-background-default);\n }\n\n input:checked {\n ~ .radio-dot {\n circle {\n fill: var(--fhi-color-danger-border-default);\n }\n }\n }\n\n input:hover:not(:checked) {\n border-color: var(--fhi-color-danger-border-strong);\n background-color: var(--fhi-color-danger-background-subtle);\n }\n\n input:active:not(:checked) {\n border-color: var(--fhi-color-danger-border-strong);\n background-color: var(--fhi-color-danger-surface-default);\n outline-color: var(--fhi-color-danger-surface-hover);\n }\n }\n }\n `;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"fhi-radio.js","names":[],"sources":["../../src/components/fhi-radio/fhi-radio.component.ts"],"sourcesContent":["import { html, css, LitElement } from 'lit';\nimport { customElement, property, query } from 'lit/decorators.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\n\nimport '../typography/fhi-body/fhi-body.component';\n\nexport const FhiRadioSelector = 'fhi-radio';\n\n/**\n * ## FHI Radio\n *\n * {@link https://designsystem.fhi.no/?path=/docs/komponenter-radio--docs}\n *\n * The `<fhi-radio>` component represents a single radio button.\n * It should be used within a group of options, allowing users to select one option from a set.\n *\n * @tag fhi-radio\n * @element fhi-radio\n */\n@customElement(FhiRadioSelector)\nexport class FhiRadio extends LitElement {\n static readonly formAssociated = true;\n\n /**\n * The text label assigned to and displayed next to the radio.\n * You should always provide a label.\n * @type {string}\n */\n @property({ type: String }) label?: string = undefined;\n\n /**\n * The name of the radio. This is submitted with the form data as a `key` when the checkbox is checked.\n * All `<fhi-radio>` components with the same name belong to the same group.\n * @reflect\n * @type {string}\n */\n @property({ type: String, reflect: true }) name?: string = undefined;\n\n /**\n * Sets the visual status of the radio. There is currently only one status available: `error`.\n * The `error` status is used to indicate that there is an issue with the radio, such as a required radio not being checked.\n * @reflect\n * @type {'error' | undefined}\n */\n @property({ type: String, reflect: true }) status?: 'error' = undefined;\n\n /**\n * Disables the radio. This changes its appearance and makes it non-interactive.\n * @reflect\n * @type {boolean}\n */\n @property({ type: Boolean, reflect: true }) disabled? = false;\n\n /**\n * Whether the radio button is checked or not.\n * @type {boolean}\n */\n @property({ type: Boolean }) checked? = false;\n\n /**\n * The value of the radio. This is submitted with the form data as a `value` when the radio is checked.\n * @type {string}\n */\n @property({ type: String }) value: string = 'on';\n\n /**\n * The help text shown below the label.\n * This is used to provide additional information or descriptions to the user.\n * @type {string}\n */\n @property({ type: String, attribute: 'help-text' }) helpText?: string;\n\n @query('#input-element')\n private _input!: HTMLInputElement;\n\n private _groupRoot: Document | HTMLFormElement;\n private _internals: ElementInternals;\n\n /**\n * Indicates if the radio button is part of a form.\n * @internal\n */\n public isFormElement = false;\n\n constructor() {\n super();\n this._internals = this.attachInternals();\n this._groupRoot = document;\n }\n\n public connectedCallback(): void {\n super.connectedCallback();\n\n this.addEventListener('focus', this._setFocusOnInput);\n\n this.isFormElement = !!this._internals.form;\n\n if (this.isFormElement) {\n this._updateFormValue();\n this._groupRoot = this._internals.form!;\n }\n\n // If the radio has a name then it is part of a group and needs keyboard navigation\n if (this.name) {\n this.addEventListener('keydown', this._handleKeyDown);\n this._SetTabbableRadios();\n }\n }\n\n public disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener('keydown', this._handleKeyDown);\n this.removeEventListener('focus', this._setFocusOnInput);\n }\n\n private _setFocusOnInput() {\n this._input.focus();\n }\n\n private _getRadioGroup() {\n return Array.from(\n this._groupRoot.querySelectorAll<FhiRadio>(\n `${FhiRadioSelector}[name=\"${this.name}\"]`,\n ),\n );\n }\n\n private _SetTabbableRadios() {\n const radios = this._getRadioGroup();\n\n radios.forEach(radio => {\n // Only the checked radio should be tabbable\n radio.tabIndex = radio.checked ? 0 : -1;\n });\n\n // If none of the radios are checked, make the first one tabbable\n if (!radios.some(radio => radio.checked) && radios.length > 0) {\n radios[0].tabIndex = 0;\n }\n }\n\n public updated(changedProperties: Map<string, unknown>) {\n super.updated(changedProperties);\n\n // make sure the radio input can be programmatically toggeled. e.g by a form reset\n if (changedProperties.has('checked')) {\n this._input.checked = !!this.checked;\n this._updateFormValue();\n\n if (this.checked) {\n this.uncheckGroupMembers();\n }\n }\n\n // update the form value when the value or name input changes and the radio is already checked\n if (changedProperties.has('value') || changedProperties.has('name')) {\n if (this._input.checked) {\n this._updateFormValue();\n }\n }\n\n if (changedProperties.has('helpText') || changedProperties.has('label')) {\n if (!this.label && this.helpText) {\n console.error(\n 'The \"help-text\" property is set, but the \"label\" property is not. It is required to provide a label when using help text.',\n );\n }\n }\n }\n\n public formResetCallback(): void {\n const radiosCheckedByDefault = this._getRadioGroup().filter(\n radio => typeof radio.getAttribute('checked') === 'string',\n );\n\n if (radiosCheckedByDefault.pop() === this) {\n this.checked = true;\n }\n\n this._updateFormValue();\n }\n\n private uncheckGroupMembers(): void {\n const radios = this._getRadioGroup();\n\n radios.forEach(radio => {\n if (radio === this) {\n return;\n }\n\n if (radio.isFormElement && this._groupRoot === document) {\n return;\n }\n\n radio.checked = false;\n });\n }\n\n private _updateFormValue(): void {\n if (!this.isFormElement) {\n return;\n }\n\n this._internals.setFormValue(this.checked ? this.value : null);\n }\n\n private _handleChange(event: Event): void {\n this.checked = (event.target as HTMLInputElement).checked;\n\n this.uncheckGroupMembers();\n\n this._updateFormValue();\n\n event.stopPropagation();\n this._dispatchChangeEvent();\n }\n private _handleInput(event: Event): void {\n event.stopPropagation();\n this._dispatchInputEvent();\n }\n\n private _dispatchChangeEvent(): void {\n /**\n * @type {Event} - Standard DOM event with the type `change`.\n * This event is dispatched when the radio is checked or unchecked.\n */\n this.dispatchEvent(new Event('change', { bubbles: true }));\n }\n\n private _dispatchInputEvent(): void {\n /**\n * @type {Event} - Standard DOM event with the type `input`.\n * This event is dispatched when the radio is checked or unchecked.\n */\n this.dispatchEvent(new Event('input', { bubbles: true, composed: true }));\n }\n\n private _handleKeyDown(event: KeyboardEvent): void {\n const arrows = ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'];\n\n if (!arrows.includes(event.key)) {\n return;\n }\n\n event.preventDefault();\n\n const radios = this._getRadioGroup();\n\n if (radios.length < 2) {\n return;\n }\n\n const currentIndex = radios.indexOf(this);\n\n const nextIndex = currentIndex;\n let nextRadio: FhiRadio;\n\n if (event.key === 'ArrowUp' || event.key === 'ArrowLeft') {\n nextRadio = radios[nextIndex === 0 ? radios.length - 1 : nextIndex - 1];\n } else {\n nextRadio = radios[nextIndex === radios.length - 1 ? 0 : nextIndex + 1];\n }\n\n nextRadio.focus();\n this.checked = false;\n nextRadio.checked = true;\n this._SetTabbableRadios();\n }\n\n render() {\n return html`\n <div class=\"radio-wrapper\">\n <input\n type=\"radio\"\n id=\"input-element\"\n name=\"${ifDefined(this.name)}\"\n value=\"${this.value}\"\n ?checked=${this.checked}\n ?disabled=${this.disabled}\n @change=${this._handleChange}\n @input=${this._handleInput}\n />\n <svg\n class=\"radio-dot\"\n viewBox=\"0 0 18 18\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <circle r=\"6\" cx=\"9\" cy=\"9\" />\n </svg>\n </div>\n ${this.label && html`<label for=\"input-element\">${this.label}</label>`}\n ${this.helpText\n ? html`<fhi-body size=\"small\" class=\"help-text\"\n >${this.helpText}</fhi-body\n >`\n : ''}\n `;\n }\n\n static styles = css`\n :host {\n --fhi-radio-color: currentcolor;\n }\n\n :host {\n display: grid;\n width: max-content;\n height: fit-content;\n grid-template-columns: auto auto;\n color: var(--fhi-radio-color);\n padding-left: 0.125rem;\n\n .radio-wrapper {\n display: flex;\n position: relative;\n height: fit-content;\n }\n\n label {\n font-family: var(--fhi-font-family-default);\n -webkit-font-smoothing: antialiased;\n font-size: var(--fhi-typography-body-medium-font-size);\n font-weight: var(--fhi-typography-body-medium-font-weight);\n line-height: var(--fhi-typography-body-medium-line-height);\n letter-spacing: var(--fhi-typography-body-medium-letter-spacing);\n }\n\n label,\n fhi-body {\n grid-column: 2;\n padding-left: 6px;\n }\n\n input {\n margin: 0.125rem 0 0.125rem 0;\n appearance: none;\n width: var(--fhi-spacing-250);\n height: var(--fhi-spacing-250);\n background-color: var(--fhi-color-neutral-background-default);\n border: var(--fhi-dimension-border-width) solid\n var(--fhi-color-neutral-border-default);\n border-radius: var(--fhi-border-radius-full);\n transition: all var(--fhi-motion-ease-default)\n var(--fhi-motion-duration-quick);\n &:not(:focus-visible) {\n outline-color: var(--fhi-color-accent-surface-hover);\n }\n }\n\n .radio-dot {\n visibility: hidden;\n opacity: 0;\n transition: opacity var(--fhi-motion-ease-default)\n var(--fhi-motion-duration-quick);\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 1.125rem;\n }\n\n input:checked {\n border-width: var(--fhi-dimension-border-width-active);\n ~ .radio-dot {\n circle {\n fill: var(--fhi-color-neutral-border-default);\n }\n visibility: visible;\n opacity: 1;\n }\n }\n\n .help-text {\n color: var(--fhi-color-neutral-text-subtle);\n }\n }\n\n :host([disabled]) {\n opacity: var(--fhi-opacity-disabled);\n * {\n cursor: not-allowed;\n }\n }\n\n :host(:not(:disabled)) {\n input:hover:not(:checked) {\n border-color: var(--fhi-color-accent-border-strong);\n background-color: var(--fhi-color-accent-background-subtle);\n }\n\n input:active:not(:checked) {\n border-color: var(--fhi-color-accent-border-strong);\n background-color: var(--fhi-color-accent-surface-default);\n outline: var(--fhi-dimension-border-width-focus) solid\n var(--fhi-color-accent-surface-hover);\n }\n\n &:host([status='error']) {\n input {\n border-color: var(--fhi-color-danger-border-default);\n background-color: var(--fhi-color-danger-background-default);\n &:not(:focus-visible) {\n outline-color: var(--fhi-color-danger-surface-hover);\n }\n }\n\n input:checked {\n ~ .radio-dot {\n circle {\n fill: var(--fhi-color-danger-border-default);\n }\n }\n }\n\n input:hover:not(:checked) {\n border-color: var(--fhi-color-danger-border-strong);\n background-color: var(--fhi-color-danger-background-subtle);\n }\n\n input:active:not(:checked) {\n border-color: var(--fhi-color-danger-border-strong);\n background-color: var(--fhi-color-danger-surface-default);\n outline-color: var(--fhi-color-danger-surface-hover);\n }\n }\n }\n `;\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"kind":"javascript-module","path":"src/components/fhi-radio/fhi-radio.component.ts","declarations":[{"kind":"class","description":"## FHI Radio\n\nhttps://designsystem.fhi.no/?path=/docs/komponenter-radio--docs\n\nThe `<fhi-radio>` component represents a single radio button.\nIt should be used within a group of options, allowing users to select one option from a set.","name":"FhiRadio","members":[{"kind":"method","name":"_dispatchChangeEvent","privacy":"private","return":{"type":{"text":"void"}}},{"kind":"method","name":"_dispatchInputEvent","privacy":"private","return":{"type":{"text":"void"}}},{"kind":"method","name":"_getRadioGroup","privacy":"private"},{"kind":"field","name":"_groupRoot","type":{"text":"Document | HTMLFormElement"},"privacy":"private","default":"document"},{"kind":"method","name":"_handleChange","privacy":"private","return":{"type":{"text":"void"}},"parameters":[{"name":"event","type":{"text":"Event"}}]},{"kind":"method","name":"_handleInput","privacy":"private","return":{"type":{"text":"void"}},"parameters":[{"name":"event","type":{"text":"Event"}}]},{"kind":"method","name":"_handleKeyDown","privacy":"private","return":{"type":{"text":"void"}},"parameters":[{"name":"event","type":{"text":"KeyboardEvent"}}]},{"kind":"field","name":"_input","type":{"text":"HTMLInputElement"},"privacy":"private"},{"kind":"field","name":"_internals","type":{"text":"ElementInternals"},"privacy":"private"},{"kind":"method","name":"_setFocusOnInput","privacy":"private"},{"kind":"method","name":"_SetTabbableRadios","privacy":"private"},{"kind":"method","name":"_updateFormValue","privacy":"private","return":{"type":{"text":"void"}}},{"kind":"field","name":"checked","type":{"text":"boolean"},"default":"false","description":"Whether the radio button is checked or not.","attribute":"checked"},{"kind":"field","name":"disabled","type":{"text":"boolean"},"default":"false","description":"Disables the radio. This changes its appearance and makes it non-interactive.","reflects":true,"attribute":"disabled"},{"kind":"field","name":"formAssociated","type":{"text":"boolean"},"static":true,"readonly":true,"default":"true"},{"kind":"method","name":"formResetCallback","privacy":"public","return":{"type":{"text":"void"}}},{"kind":"field","name":"label","type":{"text":"string"},"default":"undefined","description":"The text label assigned to and displayed next to the radio.\nYou should always provide a label.","attribute":"label"},{"kind":"field","name":"name","type":{"text":"string"},"default":"undefined","description":"The name of the radio. This is submitted with the form data as a `key` when the checkbox is checked.\nAll `<fhi-radio>` components with the same name belong to the same group.","reflects":true,"attribute":"name"},{"kind":"field","name":"status","type":{"text":"'error' | undefined"},"default":"undefined","description":"Sets the visual status of the radio. There is currently only one status available: `error`.\nThe `error` status is used to indicate that there is an issue with the radio, such as a required radio not being checked.","reflects":true,"attribute":"status"},{"kind":"method","name":"uncheckGroupMembers","privacy":"private","return":{"type":{"text":"void"}}},{"kind":"field","name":"value","type":{"text":"string"},"default":"'on'","description":"The value of the radio. This is submitted with the form data as a `value` when the radio is checked.","attribute":"value"}],"events":[{"name":"change","type":{"text":"Event"},"description":"Standard DOM event with the type `change`.\nThis event is dispatched when the radio is checked or unchecked."},{"name":"input","type":{"text":"Event"},"description":"Standard DOM event with the type `input`.\nThis event is dispatched when the radio is checked or unchecked."}],"attributes":[{"name":"checked","type":{"text":"boolean"},"default":"false","description":"Whether the radio button is checked or not.","fieldName":"checked"},{"name":"disabled","type":{"text":"boolean"},"default":"false","description":"Disables the radio. This changes its appearance and makes it non-interactive.","fieldName":"disabled"},{"name":"label","type":{"text":"string"},"default":"undefined","description":"The text label assigned to and displayed next to the radio.\nYou should always provide a label.","fieldName":"label"},{"name":"name","type":{"text":"string"},"default":"undefined","description":"The name of the radio. This is submitted with the form data as a `key` when the checkbox is checked.\nAll `<fhi-radio>` components with the same name belong to the same group.","fieldName":"name"},{"name":"status","type":{"text":"'error' | undefined"},"default":"undefined","description":"Sets the visual status of the radio. There is currently only one status available: `error`.\nThe `error` status is used to indicate that there is an issue with the radio, such as a required radio not being checked.","fieldName":"status"},{"name":"value","type":{"text":"string"},"default":"'on'","description":"The value of the radio. This is submitted with the form data as a `value` when the radio is checked.","fieldName":"value"}],"superclass":{"name":"LitElement","package":"lit"},"tagName":"fhi-radio","customElement":true},{"kind":"variable","name":"FhiRadioSelector","type":{"text":"string"},"default":"'fhi-radio'"}]}
1
+ {"kind":"javascript-module","path":"src/components/fhi-radio/fhi-radio.component.ts","declarations":[{"kind":"class","description":"## FHI Radio\n\nhttps://designsystem.fhi.no/?path=/docs/komponenter-radio--docs\n\nThe `<fhi-radio>` component represents a single radio button.\nIt should be used within a group of options, allowing users to select one option from a set.","name":"FhiRadio","members":[{"kind":"method","name":"_dispatchChangeEvent","privacy":"private","return":{"type":{"text":"void"}}},{"kind":"method","name":"_dispatchInputEvent","privacy":"private","return":{"type":{"text":"void"}}},{"kind":"method","name":"_getRadioGroup","privacy":"private"},{"kind":"field","name":"_groupRoot","type":{"text":"Document | HTMLFormElement"},"privacy":"private","default":"document"},{"kind":"method","name":"_handleChange","privacy":"private","return":{"type":{"text":"void"}},"parameters":[{"name":"event","type":{"text":"Event"}}]},{"kind":"method","name":"_handleInput","privacy":"private","return":{"type":{"text":"void"}},"parameters":[{"name":"event","type":{"text":"Event"}}]},{"kind":"method","name":"_handleKeyDown","privacy":"private","return":{"type":{"text":"void"}},"parameters":[{"name":"event","type":{"text":"KeyboardEvent"}}]},{"kind":"field","name":"_input","type":{"text":"HTMLInputElement"},"privacy":"private"},{"kind":"field","name":"_internals","type":{"text":"ElementInternals"},"privacy":"private"},{"kind":"method","name":"_setFocusOnInput","privacy":"private"},{"kind":"method","name":"_SetTabbableRadios","privacy":"private"},{"kind":"method","name":"_updateFormValue","privacy":"private","return":{"type":{"text":"void"}}},{"kind":"field","name":"checked","type":{"text":"boolean"},"default":"false","description":"Whether the radio button is checked or not.","attribute":"checked"},{"kind":"field","name":"disabled","type":{"text":"boolean"},"default":"false","description":"Disables the radio. This changes its appearance and makes it non-interactive.","reflects":true,"attribute":"disabled"},{"kind":"field","name":"formAssociated","type":{"text":"boolean"},"static":true,"readonly":true,"default":"true"},{"kind":"method","name":"formResetCallback","privacy":"public","return":{"type":{"text":"void"}}},{"kind":"field","name":"helpText","type":{"text":"string"},"description":"The help text shown below the label.\nThis is used to provide additional information or descriptions to the user.","attribute":"help-text"},{"kind":"field","name":"label","type":{"text":"string"},"default":"undefined","description":"The text label assigned to and displayed next to the radio.\nYou should always provide a label.","attribute":"label"},{"kind":"field","name":"name","type":{"text":"string"},"default":"undefined","description":"The name of the radio. This is submitted with the form data as a `key` when the checkbox is checked.\nAll `<fhi-radio>` components with the same name belong to the same group.","reflects":true,"attribute":"name"},{"kind":"field","name":"status","type":{"text":"'error' | undefined"},"default":"undefined","description":"Sets the visual status of the radio. There is currently only one status available: `error`.\nThe `error` status is used to indicate that there is an issue with the radio, such as a required radio not being checked.","reflects":true,"attribute":"status"},{"kind":"method","name":"uncheckGroupMembers","privacy":"private","return":{"type":{"text":"void"}}},{"kind":"field","name":"value","type":{"text":"string"},"default":"'on'","description":"The value of the radio. This is submitted with the form data as a `value` when the radio is checked.","attribute":"value"}],"events":[{"name":"change","type":{"text":"Event"},"description":"Standard DOM event with the type `change`.\nThis event is dispatched when the radio is checked or unchecked."},{"name":"input","type":{"text":"Event"},"description":"Standard DOM event with the type `input`.\nThis event is dispatched when the radio is checked or unchecked."}],"attributes":[{"name":"checked","type":{"text":"boolean"},"default":"false","description":"Whether the radio button is checked or not.","fieldName":"checked"},{"name":"disabled","type":{"text":"boolean"},"default":"false","description":"Disables the radio. This changes its appearance and makes it non-interactive.","fieldName":"disabled"},{"name":"help-text","type":{"text":"string"},"description":"The help text shown below the label.\nThis is used to provide additional information or descriptions to the user.","fieldName":"helpText"},{"name":"label","type":{"text":"string"},"default":"undefined","description":"The text label assigned to and displayed next to the radio.\nYou should always provide a label.","fieldName":"label"},{"name":"name","type":{"text":"string"},"default":"undefined","description":"The name of the radio. This is submitted with the form data as a `key` when the checkbox is checked.\nAll `<fhi-radio>` components with the same name belong to the same group.","fieldName":"name"},{"name":"status","type":{"text":"'error' | undefined"},"default":"undefined","description":"Sets the visual status of the radio. There is currently only one status available: `error`.\nThe `error` status is used to indicate that there is an issue with the radio, such as a required radio not being checked.","fieldName":"status"},{"name":"value","type":{"text":"string"},"default":"'on'","description":"The value of the radio. This is submitted with the form data as a `value` when the radio is checked.","fieldName":"value"}],"superclass":{"name":"LitElement","package":"lit"},"tagName":"fhi-radio","customElement":true},{"kind":"variable","name":"FhiRadioSelector","type":{"text":"string"},"default":"'fhi-radio'"}]}