@solid-design-system/components 1.35.1 → 1.37.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 (154) hide show
  1. package/dist/components/es/checkbox-group.js +1 -1
  2. package/dist/components/es/checkbox.js +1 -1
  3. package/dist/components/es/form.js +1 -1
  4. package/dist/components/es/input.js +1 -1
  5. package/dist/components/es/option.js +1 -1
  6. package/dist/components/es/radio-button.js +1 -0
  7. package/dist/components/es/radio-group.js +1 -1
  8. package/dist/components/es/radio.js +1 -1
  9. package/dist/components/es/select.js +2 -2
  10. package/dist/components/es/solid-components2.js +1 -1
  11. package/dist/components/es/solid-element.js +1 -1
  12. package/dist/components/es/switch.js +1 -1
  13. package/dist/components/es/textarea.js +1 -1
  14. package/dist/components/umd/solid-components.js +19 -19
  15. package/dist/custom-elements.json +1 -1
  16. package/dist/package/components/checkbox/checkbox.d.ts +2 -0
  17. package/dist/package/components/checkbox/checkbox.js +23 -6
  18. package/dist/package/components/checkbox-group/checkbox-group.js +1 -1
  19. package/dist/package/components/input/input.d.ts +3 -0
  20. package/dist/package/components/input/input.js +20 -19
  21. package/dist/package/components/option/option.js +0 -2
  22. package/dist/package/components/radio/radio.js +3 -3
  23. package/dist/package/components/radio-button/radio-button.d.ts +25 -0
  24. package/dist/package/components/radio-button/radio-button.js +118 -0
  25. package/dist/package/components/radio-group/radio-group.d.ts +4 -3
  26. package/dist/package/components/radio-group/radio-group.js +26 -26
  27. package/dist/package/components/select/select.d.ts +3 -3
  28. package/dist/package/components/select/select.js +18 -23
  29. package/dist/package/components/switch/switch.d.ts +2 -0
  30. package/dist/package/components/switch/switch.js +15 -7
  31. package/dist/package/components/textarea/textarea.d.ts +3 -0
  32. package/dist/package/components/textarea/textarea.js +30 -24
  33. package/dist/package/internal/form.d.ts +3 -1
  34. package/dist/package/internal/form.js +38 -10
  35. package/dist/package/internal/solid-element.d.ts +2 -0
  36. package/dist/package/solid-components.d.ts +1 -0
  37. package/dist/package/solid-components.js +20 -18
  38. package/dist/package/styles/tailwind.css.js +1 -1
  39. package/dist/versioned-components/es/accordion-group.js +1 -1
  40. package/dist/versioned-components/es/accordion.js +1 -1
  41. package/dist/versioned-components/es/badge.js +1 -1
  42. package/dist/versioned-components/es/brandshape.js +1 -1
  43. package/dist/versioned-components/es/button.js +1 -1
  44. package/dist/versioned-components/es/carousel-item.js +1 -1
  45. package/dist/versioned-components/es/carousel.js +3 -3
  46. package/dist/versioned-components/es/checkbox-group.js +1 -1
  47. package/dist/versioned-components/es/checkbox.js +1 -1
  48. package/dist/versioned-components/es/divider.js +1 -1
  49. package/dist/versioned-components/es/drawer.js +1 -1
  50. package/dist/versioned-components/es/dropdown.js +1 -1
  51. package/dist/versioned-components/es/form.js +1 -1
  52. package/dist/versioned-components/es/header.js +1 -1
  53. package/dist/versioned-components/es/icon.js +1 -1
  54. package/dist/versioned-components/es/include.js +1 -1
  55. package/dist/versioned-components/es/input.js +1 -1
  56. package/dist/versioned-components/es/link.js +1 -1
  57. package/dist/versioned-components/es/navigation-item.js +1 -1
  58. package/dist/versioned-components/es/notification.js +1 -1
  59. package/dist/versioned-components/es/option.js +1 -1
  60. package/dist/versioned-components/es/popup.js +1 -1
  61. package/dist/versioned-components/es/radio-button.js +1 -0
  62. package/dist/versioned-components/es/radio-group.js +1 -1
  63. package/dist/versioned-components/es/radio.js +1 -1
  64. package/dist/versioned-components/es/select.js +2 -2
  65. package/dist/versioned-components/es/solid-components2.js +1 -1
  66. package/dist/versioned-components/es/solid-element.js +1 -1
  67. package/dist/versioned-components/es/spinner.js +1 -1
  68. package/dist/versioned-components/es/switch.js +1 -1
  69. package/dist/versioned-components/es/tag.js +1 -1
  70. package/dist/versioned-components/es/teaser.js +1 -1
  71. package/dist/versioned-components/es/textarea.js +1 -1
  72. package/dist/versioned-components/es/tooltip.js +2 -2
  73. package/dist/versioned-components/es/video.js +1 -1
  74. package/dist/versioned-package/_components/button-group/button-group.d.ts +1 -1
  75. package/dist/versioned-package/_components/button-group/button-group.js +11 -11
  76. package/dist/versioned-package/components/accordion/accordion.d.ts +1 -1
  77. package/dist/versioned-package/components/accordion/accordion.js +2 -2
  78. package/dist/versioned-package/components/accordion-group/accordion-group.d.ts +1 -1
  79. package/dist/versioned-package/components/accordion-group/accordion-group.js +3 -3
  80. package/dist/versioned-package/components/badge/badge.d.ts +1 -1
  81. package/dist/versioned-package/components/badge/badge.js +1 -1
  82. package/dist/versioned-package/components/brandshape/brandshape.d.ts +1 -1
  83. package/dist/versioned-package/components/brandshape/brandshape.js +1 -1
  84. package/dist/versioned-package/components/button/button.d.ts +1 -1
  85. package/dist/versioned-package/components/button/button.js +4 -4
  86. package/dist/versioned-package/components/carousel/carousel.d.ts +1 -1
  87. package/dist/versioned-package/components/carousel/carousel.js +6 -6
  88. package/dist/versioned-package/components/carousel-item/carousel-item.d.ts +1 -1
  89. package/dist/versioned-package/components/carousel-item/carousel-item.js +1 -1
  90. package/dist/versioned-package/components/checkbox/checkbox.d.ts +3 -1
  91. package/dist/versioned-package/components/checkbox/checkbox.js +27 -10
  92. package/dist/versioned-package/components/checkbox-group/checkbox-group.d.ts +1 -1
  93. package/dist/versioned-package/components/checkbox-group/checkbox-group.js +6 -6
  94. package/dist/versioned-package/components/divider/divider.d.ts +1 -1
  95. package/dist/versioned-package/components/divider/divider.js +2 -2
  96. package/dist/versioned-package/components/drawer/drawer.d.ts +1 -1
  97. package/dist/versioned-package/components/drawer/drawer.js +2 -2
  98. package/dist/versioned-package/components/dropdown/dropdown.d.ts +1 -1
  99. package/dist/versioned-package/components/dropdown/dropdown.js +8 -8
  100. package/dist/versioned-package/components/header/header.d.ts +1 -1
  101. package/dist/versioned-package/components/header/header.js +4 -4
  102. package/dist/versioned-package/components/icon/icon.d.ts +1 -1
  103. package/dist/versioned-package/components/icon/icon.js +1 -1
  104. package/dist/versioned-package/components/include/include.d.ts +1 -1
  105. package/dist/versioned-package/components/include/include.js +1 -1
  106. package/dist/versioned-package/components/input/input.d.ts +4 -1
  107. package/dist/versioned-package/components/input/input.js +23 -22
  108. package/dist/versioned-package/components/link/link.d.ts +1 -1
  109. package/dist/versioned-package/components/link/link.js +2 -2
  110. package/dist/versioned-package/components/navigation-item/navigation-item.d.ts +1 -1
  111. package/dist/versioned-package/components/navigation-item/navigation-item.js +3 -3
  112. package/dist/versioned-package/components/notification/notification.d.ts +1 -1
  113. package/dist/versioned-package/components/notification/notification.js +5 -5
  114. package/dist/versioned-package/components/option/option.d.ts +1 -1
  115. package/dist/versioned-package/components/option/option.js +2 -4
  116. package/dist/versioned-package/components/popup/popup.d.ts +1 -1
  117. package/dist/versioned-package/components/popup/popup.js +1 -1
  118. package/dist/versioned-package/components/radio/radio.d.ts +1 -1
  119. package/dist/versioned-package/components/radio/radio.js +5 -5
  120. package/dist/versioned-package/components/radio-button/radio-button.d.ts +25 -0
  121. package/dist/versioned-package/components/radio-button/radio-button.js +118 -0
  122. package/dist/versioned-package/components/radio-group/radio-group.d.ts +6 -5
  123. package/dist/versioned-package/components/radio-group/radio-group.js +39 -39
  124. package/dist/versioned-package/components/select/select.d.ts +7 -7
  125. package/dist/versioned-package/components/select/select.js +44 -49
  126. package/dist/versioned-package/components/spinner/spinner.d.ts +1 -1
  127. package/dist/versioned-package/components/spinner/spinner.js +1 -1
  128. package/dist/versioned-package/components/switch/switch.d.ts +3 -1
  129. package/dist/versioned-package/components/switch/switch.js +17 -9
  130. package/dist/versioned-package/components/tag/tag.d.ts +1 -1
  131. package/dist/versioned-package/components/tag/tag.js +2 -2
  132. package/dist/versioned-package/components/teaser/teaser.js +1 -1
  133. package/dist/versioned-package/components/textarea/textarea.d.ts +4 -1
  134. package/dist/versioned-package/components/textarea/textarea.js +32 -26
  135. package/dist/versioned-package/components/tooltip/tooltip.d.ts +1 -1
  136. package/dist/versioned-package/components/tooltip/tooltip.js +5 -5
  137. package/dist/versioned-package/components/video/video.d.ts +1 -1
  138. package/dist/versioned-package/components/video/video.js +2 -2
  139. package/dist/versioned-package/internal/form.d.ts +3 -1
  140. package/dist/versioned-package/internal/form.js +40 -12
  141. package/dist/versioned-package/internal/solid-element.d.ts +2 -0
  142. package/dist/versioned-package/solid-components.d.ts +1 -0
  143. package/dist/versioned-package/solid-components.js +20 -18
  144. package/dist/versioned-package/styles/tailwind.css.js +1 -1
  145. package/dist/versioned-styles/solid-styles.css +1 -1
  146. package/dist/vscode.html-custom-data.json +107 -33
  147. package/dist/web-types.json +177 -18
  148. package/package.json +5 -4
  149. package/dist/components/es/form-control.styles.js +0 -1
  150. package/dist/package/styles/form-control.styles.d.ts +0 -2
  151. package/dist/package/styles/form-control.styles.js +0 -5
  152. package/dist/versioned-components/es/form-control.styles.js +0 -1
  153. package/dist/versioned-package/styles/form-control.styles.d.ts +0 -2
  154. package/dist/versioned-package/styles/form-control.styles.js +0 -5
@@ -4,6 +4,7 @@ import type { SolidFormControl } from '../../internal/solid-element';
4
4
  export default class SdCheckbox extends SolidElement implements SolidFormControl {
5
5
  private readonly formControlController;
6
6
  input: HTMLInputElement;
7
+ invalidMessage: HTMLDivElement;
7
8
  title: string;
8
9
  name: string;
9
10
  value: string;
@@ -14,6 +15,7 @@ export default class SdCheckbox extends SolidElement implements SolidFormControl
14
15
  defaultChecked: boolean;
15
16
  form: string;
16
17
  required: boolean;
18
+ showInvalidStyle: boolean;
17
19
  get validity(): ValidityState;
18
20
  firstUpdated(): void;
19
21
  private handleClick;
@@ -5,7 +5,7 @@ import { defaultValue } from "../../internal/default-value.js";
5
5
  import { FormControlController } from "../../internal/form.js";
6
6
  import { ifDefined } from "lit/directives/if-defined.js";
7
7
  import { live } from "lit/directives/live.js";
8
- import { query, property } from "lit/decorators.js";
8
+ import { query, property, state } from "lit/decorators.js";
9
9
  import { watch } from "../../internal/watch.js";
10
10
  import cx from "classix";
11
11
  import SolidElement from "../../internal/solid-element.js";
@@ -37,6 +37,7 @@ let SdCheckbox = class extends SolidElement {
37
37
  this.defaultChecked = false;
38
38
  this.form = "";
39
39
  this.required = false;
40
+ this.showInvalidStyle = false;
40
41
  }
41
42
  /** Gets the validity state object */
42
43
  get validity() {
@@ -59,6 +60,7 @@ let SdCheckbox = class extends SolidElement {
59
60
  handleInvalid(event) {
60
61
  this.formControlController.setValidity(false);
61
62
  this.formControlController.emitInvalidEvent(event);
63
+ this.invalidMessage.textContent = event.target.validationMessage;
62
64
  }
63
65
  handleFocus() {
64
66
  this.emit("sd-focus");
@@ -105,6 +107,7 @@ let SdCheckbox = class extends SolidElement {
105
107
  this.formControlController.updateValidity();
106
108
  }
107
109
  render() {
110
+ const checkboxState = this.disabled && this.indeterminate ? "disabledIndeterminate" : this.disabled && this.checked ? "disabledChecked" : this.disabled ? "disabled" : this.showInvalidStyle && this.indeterminate ? "invalidIndeterminate" : this.showInvalidStyle ? "invalid" : this.checked || this.indeterminate ? "filled" : "default";
108
111
  return html`<label part="base" class="${cx(
109
112
  "sd-checkbox group flex items-start text-base leading-normal text-black cursor-pointer",
110
113
  this.disabled && "hover:cursor-not-allowed",
@@ -121,20 +124,31 @@ let SdCheckbox = class extends SolidElement {
121
124
  sm: "mt-[2px]",
122
125
  lg: "mt-[3px]"
123
126
  }[this.size],
124
- this.disabled && this.indeterminate && "border-neutral-500 bg-neutral-500" || this.disabled && this.checked && "border-neutral-500 bg-neutral-500" || this.disabled && "border-neutral-500" || (this.checked || this.indeterminate) && "border-accent hover:border-accent-550 group-hover:border-accent-550 bg-accent group-hover:bg-accent-550" || "border-neutral-800 hover:bg-neutral-200 group-hover:bg-neutral-200 bg-white"
127
+ {
128
+ disabledIndeterminate: "border-neutral-500 bg-neutral-500",
129
+ disabledChecked: "border-neutral-500 bg-neutral-500",
130
+ disabled: "border-neutral-500",
131
+ invalidIndeterminate: "border-error bg-error group-hover:bg-error-400",
132
+ invalid: "border-error group-hover:bg-neutral-200",
133
+ filled: "border-accent hover:border-accent-550 group-hover:border-accent-550 bg-accent group-hover:bg-accent-550",
134
+ default: "border-neutral-800 hover:bg-neutral-200 group-hover:bg-neutral-200 bg-white"
135
+ }[checkboxState]
125
136
  )}">${this.checked ? html`<sd-icon part="checked-icon" class="text-white w-3 h-3" library="system" name="status-hook"></sd-icon>` : ""} ${!this.checked && this.indeterminate ? html`<sd-icon part="indeterminate-icon" class="text-white w-3 h-3" library="system" name="status-minus"></sd-icon>` : ""} </span><span part="label" id="label" class="${cx(
126
- "select-none inline-block ml-2 text-black",
127
- this.disabled && "text-neutral-500" || "text-neutral-800"
128
- )}"><slot></slot></span></label>`;
137
+ "select-none inline-block ml-2",
138
+ this.disabled ? "text-neutral-500" : this.showInvalidStyle ? "text-error" : "text-black"
139
+ )}"><slot></slot></span></label> ${this.formControlController.renderInvalidMessage()}`;
129
140
  }
130
141
  };
131
142
  SdCheckbox.styles = [
132
143
  SolidElement.styles,
133
- css`:host{display:block}:host(:focus-visible){outline-width:0}:host([required]) #label::after{content:' *'}:host([data-user-invalid]) #label{color:rgb(var(--sd-color-error,204 25 55))}:host([data-user-invalid]) #control{border-color:rgb(var(--sd-color-error,204 25 55))}:host([data-user-invalid]):host([indeterminate]) #control{background-color:rgb(var(--sd-color-error,204 25 55))}`
144
+ css`:host{display:block}:host(:focus-visible){outline-width:0}:host([required]) #label::after{content:' *'}`
134
145
  ];
135
146
  __decorateClass([
136
147
  query('input[type="checkbox"]')
137
148
  ], SdCheckbox.prototype, "input", 2);
149
+ __decorateClass([
150
+ query("#invalid-message")
151
+ ], SdCheckbox.prototype, "invalidMessage", 2);
138
152
  __decorateClass([
139
153
  property()
140
154
  ], SdCheckbox.prototype, "title", 2);
@@ -165,6 +179,9 @@ __decorateClass([
165
179
  __decorateClass([
166
180
  property({ type: Boolean, reflect: true })
167
181
  ], SdCheckbox.prototype, "required", 2);
182
+ __decorateClass([
183
+ state()
184
+ ], SdCheckbox.prototype, "showInvalidStyle", 2);
168
185
  __decorateClass([
169
186
  watch("disabled", { waitUntilFirstUpdate: true })
170
187
  ], SdCheckbox.prototype, "handleDisabledChange", 1);
@@ -66,7 +66,7 @@ let SdCheckboxGroup = class extends SolidElement {
66
66
  sm: "text-sm",
67
67
  lg: "text-base"
68
68
  }[this.size]
69
- )}" role="group" aria-labelledby="label"><label part="form-control-label" id="label" class="${cx("mb-2 p-0 font-bold leading-normal text-black", hasLabel ? "flex" : "hidden")}" aria-hidden="${!hasLabel}"><slot name="label">${this.label}</slot></label><div part="form-control-input" class="${cx(
69
+ )}" role="group" aria-labelledby="label"><label part="form-control-label" id="label" class="${cx("mb-2 p-0 font-bold leading-normal text-black", hasLabel ? "flex" : "hidden")}" aria-hidden="${hasLabel ? "false" : "true"}"><slot name="label">${this.label}</slot></label><div part="form-control-input" class="${cx(
70
70
  {
71
71
  vertical: "flex flex-col",
72
72
  horizontal: "flex flex-row"
@@ -7,7 +7,10 @@ export default class SdInput extends SolidElement implements SolidFormControl {
7
7
  private readonly hasSlotController;
8
8
  private readonly localize;
9
9
  input: HTMLInputElement;
10
+ invalidMessage: HTMLDivElement;
10
11
  private hasFocus;
12
+ showValidStyle: boolean;
13
+ showInvalidStyle: boolean;
11
14
  type: 'date' | 'datetime-local' | 'email' | 'number' | 'password' | 'search' | 'tel' | 'text' | 'time' | 'url';
12
15
  size: 'lg' | 'md' | 'sm';
13
16
  inputmode: 'none' | 'text' | 'decimal' | 'numeric' | 'tel' | 'search' | 'email' | 'url';
@@ -12,7 +12,6 @@ import { query, state, property } from "lit/decorators.js";
12
12
  import { watch } from "../../internal/watch.js";
13
13
  import componentStyles from "../../styles/component.styles.js";
14
14
  import cx from "classix";
15
- import formControlStyles from "../../styles/form-control.styles.js";
16
15
  import SolidElement from "../../internal/solid-element.js";
17
16
  var __defProp = Object.defineProperty;
18
17
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -42,6 +41,8 @@ let SdInput = class extends SolidElement {
42
41
  );
43
42
  this.localize = new LocalizeController(this);
44
43
  this.hasFocus = false;
44
+ this.showValidStyle = false;
45
+ this.showInvalidStyle = false;
45
46
  this.type = "text";
46
47
  this.size = "lg";
47
48
  this.value = "";
@@ -115,8 +116,10 @@ let SdInput = class extends SolidElement {
115
116
  this.formControlController.updateValidity();
116
117
  this.emit("sd-input");
117
118
  }
118
- handleInvalid() {
119
+ handleInvalid(event) {
119
120
  this.formControlController.setValidity(false);
121
+ this.formControlController.emitInvalidEvent(event);
122
+ this.invalidMessage.textContent = event.target.validationMessage;
120
123
  }
121
124
  handleKeyDown(event) {
122
125
  const hasModifier = event.metaKey || event.ctrlKey || event.shiftKey || event.altKey;
@@ -210,10 +213,7 @@ let SdInput = class extends SolidElement {
210
213
  const hasLabel = this.label ? true : !!slots["label"];
211
214
  const hasHelpText = this.helpText ? true : !!slots["helpText"];
212
215
  const hasClearIcon = this.clearable && !this.readonly && (typeof this.value === "number" || this.value.length > 0);
213
- const hasValidationAttr = this.required || !!this.pattern || !!this.minlength || !!this.maxlength;
214
- const isInvalid = hasValidationAttr && !this.checkValidity();
215
- const isValid = hasValidationAttr && this.checkValidity();
216
- const inputState = this.disabled ? "disabled" : this.readonly ? "readonly" : this.hasFocus && isInvalid ? "activeInvalid" : this.hasFocus && isValid ? "activeValid" : this.hasFocus ? "active" : isInvalid ? "invalid" : isValid ? "valid" : "default";
216
+ const inputState = this.disabled ? "disabled" : this.readonly ? "readonly" : this.hasFocus && this.showInvalidStyle ? "activeInvalid" : this.hasFocus && this.showValidStyle ? "activeValid" : this.hasFocus ? "active" : this.showInvalidStyle ? "invalid" : this.showValidStyle ? "valid" : "default";
217
217
  const textSize = this.size === "sm" ? "text-sm" : "text-base";
218
218
  const textColor = {
219
219
  disabled: "text-neutral-500",
@@ -242,40 +242,41 @@ let SdInput = class extends SolidElement {
242
242
  md: "text-lg",
243
243
  lg: "text-xl"
244
244
  }[this.size];
245
- return html`<div part="form-control" class="${cx("form-control", hasLabel && "form-control--has-label", this.disabled && "pointer-events-none")}"><label part="form-control-label" id="label" class="${cx("form-control-label mb-2", hasLabel ? "has-label inline-block" : "hidden", textSize)}" for="input" aria-hidden="${hasLabel ? "false" : "true"}"><slot name="label">${this.label}</slot></label><div part="form-control-input" class="form-control-input relative w-full"><div part="border" class="${cx(
246
- "absolute w-full h-full pointer-events-none border rounded-default transition-all",
247
- borderColor
248
- )}"></div><div part="base" class="${cx(
249
- "px-4 flex flex-row items-center rounded-default transition-all",
245
+ return html`<div part="form-control" class="${cx(this.disabled && "pointer-events-none")}"><label part="form-control-label" id="label" class="${cx("mb-2", hasLabel ? "inline-block" : "hidden", textSize)}" for="input" aria-hidden="${hasLabel ? "false" : "true"}"><slot name="label">${this.label}</slot></label><div part="form-control-input" class="relative w-full"><div part="border" class="${cx("absolute w-full h-full pointer-events-none border rounded-default", borderColor)}"></div><div part="base" class="${cx(
246
+ "px-4 flex flex-row items-center rounded-default transition-all bg-white",
250
247
  // Vertical Padding
251
248
  this.size === "lg" ? "py-2" : "py-1",
252
249
  // States
253
250
  !this.disabled && !this.readonly ? "hover:bg-neutral-200" : "",
254
251
  this.readonly && "bg-neutral-100",
255
- isInvalid && "form-control-input--invalid",
256
- textColor,
257
- !this.value && "input--empty",
258
- this.noSpinButtons && "input--no-spin-buttons",
259
- isFirefox && "input--is-firefox"
252
+ textColor
260
253
  )}">${slots["left"] ? html`<slot name="left" part="left" class="${cx("inline-flex", this.size === "sm" ? "mr-1" : "mr-2", iconColor, iconSize)}"></slot>` : ""} <input part="input" id="input" class="${cx(
261
254
  "min-w-0 flex-grow focus:outline-none bg-transparent placeholder-neutral-700",
262
255
  this.size === "sm" ? "h-6" : "h-8",
263
256
  textSize
264
- )}" type="${this.type === "password" && this.passwordVisible ? "text" : this.type}" title="${this.title}" name="${ifDefined(this.name)}" ?disabled="${this.disabled}" ?readonly="${this.readonly}" ?required="${this.required}" placeholder="${ifDefined(this.placeholder)}" minlength="${ifDefined(this.minlength)}" maxlength="${ifDefined(this.maxlength)}" min="${ifDefined(this.min)}" max="${ifDefined(this.max)}" step="${ifDefined(this.step)}" .value="${live(this.value)}" autocapitalize="${ifDefined(this.type === "password" ? "off" : this.autocapitalize)}" autocomplete="${ifDefined(this.type === "password" ? "off" : this.autocomplete)}" autocorrect="${ifDefined(this.type === "password" ? "off" : this.autocorrect)}" ?autofocus="${this.autofocus}" spellcheck="${this.spellcheck}" pattern="${ifDefined(this.pattern)}" enterkeyhint="${ifDefined(this.enterkeyhint)}" inputmode="${ifDefined(this.inputmode)}" aria-describedby="help-text" @change="${this.handleChange}" @input="${this.handleInput}" @invalid="${this.handleInvalid}" @keydown="${this.handleKeyDown}" @focus="${this.handleFocus}" @blur="${this.handleBlur}"> ${hasClearIcon ? html`<button part="clear-button" class="${cx("flex justify-center ", iconMarginLeft)}" type="button" aria-label="${this.localize.term("clearEntry")}" @click="${this.handleClearClick}" tabindex="-1"><slot name="clear-icon"><sd-icon class="${cx("text-neutral-500", iconSize)}" library="system" name="closing-round"></sd-icon></slot></button>` : ""} ${this.passwordToggle && this.type === "password" ? html`<button aria-label="${this.localize.term(this.passwordVisible ? "hidePassword" : "showPassword")}" part="password-toggle-button" class="flex items-center" type="button" @click="${this.handlePasswordToggle}" tabindex="-1">${this.passwordVisible ? html`<slot name="show-password-icon"><sd-icon class="${cx(iconColor, iconMarginLeft, iconSize)}" library="system" name="eye"></sd-icon></slot>` : html`<slot name="hide-password-icon"><sd-icon class="${cx(iconColor, iconMarginLeft, iconSize)}" library="system" name="eye-crossed-out"></sd-icon></slot>`}</button>` : ""} ${(this.type === "date" || this.type === "datetime-local") && !isFirefox ? html`<sd-icon class="${cx(iconColor, iconMarginLeft, iconSize)}" library="system" name="calendar"></sd-icon>` : ""} ${this.type === "time" ? html`<sd-icon class="${cx(iconColor, iconMarginLeft, iconSize)}" library="system" name="clock"></sd-icon>` : ""} ${isInvalid ? html`<sd-icon class="${cx("text-error", iconMarginLeft, iconSize)}" library="system" name="risk"></sd-icon>` : ""} ${isValid ? html`<sd-icon class="${cx("text-success", iconMarginLeft, iconSize)}" library="system" name="confirm"></sd-icon>` : ""} ${slots["right"] ? html`<slot name="right" part="right" class="${cx("inline-flex", iconColor, iconMarginLeft, iconSize)}"></slot>` : ""}</div></div><slot name="help-text" part="form-control-help-text" id="help-text" class="${cx("text-sm text-neutral-700", hasHelpText ? "block" : "hidden")}" aria-hidden="${hasHelpText ? "false" : "true"}">${this.helpText}</slot></div>`;
257
+ )}" type="${this.type === "password" && this.passwordVisible ? "text" : this.type}" title="${this.title}" name="${ifDefined(this.name)}" ?disabled="${this.disabled}" ?readonly="${this.readonly}" ?required="${this.required}" placeholder="${ifDefined(this.placeholder)}" minlength="${ifDefined(this.minlength)}" maxlength="${ifDefined(this.maxlength)}" min="${ifDefined(this.min)}" max="${ifDefined(this.max)}" step="${ifDefined(this.step)}" .value="${live(this.value)}" autocapitalize="${ifDefined(this.type === "password" ? "off" : this.autocapitalize)}" autocomplete="${ifDefined(this.type === "password" ? "off" : this.autocomplete)}" autocorrect="${ifDefined(this.type === "password" ? "off" : this.autocorrect)}" ?autofocus="${this.autofocus}" spellcheck="${this.spellcheck}" pattern="${ifDefined(this.pattern)}" enterkeyhint="${ifDefined(this.enterkeyhint)}" inputmode="${ifDefined(this.inputmode)}" aria-describedby="help-text" @change="${this.handleChange}" @input="${this.handleInput}" @invalid="${this.handleInvalid}" @keydown="${this.handleKeyDown}" @focus="${this.handleFocus}" @blur="${this.handleBlur}"> ${hasClearIcon ? html`<button part="clear-button" class="${cx("flex justify-center ", iconMarginLeft)}" type="button" aria-label="${this.localize.term("clearEntry")}" @click="${this.handleClearClick}" tabindex="-1"><slot name="clear-icon"><sd-icon class="${cx("text-neutral-500", iconSize)}" library="system" name="closing-round"></sd-icon></slot></button>` : ""} ${this.passwordToggle && this.type === "password" ? html`<button aria-label="${this.localize.term(this.passwordVisible ? "hidePassword" : "showPassword")}" part="password-toggle-button" class="flex items-center" type="button" @click="${this.handlePasswordToggle}" tabindex="-1">${this.passwordVisible ? html`<slot name="show-password-icon"><sd-icon class="${cx(iconColor, iconMarginLeft, iconSize)}" library="system" name="eye"></sd-icon></slot>` : html`<slot name="hide-password-icon"><sd-icon class="${cx(iconColor, iconMarginLeft, iconSize)}" library="system" name="eye-crossed-out"></sd-icon></slot>`}</button>` : ""} ${(this.type === "date" || this.type === "datetime-local") && !isFirefox ? html`<sd-icon class="${cx(iconColor, iconMarginLeft, iconSize)}" library="system" name="calendar"></sd-icon>` : ""} ${this.type === "time" ? html`<sd-icon class="${cx(iconColor, iconMarginLeft, iconSize)}" library="system" name="clock"></sd-icon>` : ""} ${this.showInvalidStyle ? html`<sd-icon class="${cx("text-error", iconMarginLeft, iconSize)}" library="system" name="risk"></sd-icon>` : ""} ${this.showValidStyle ? html`<sd-icon class="${cx("text-success", iconMarginLeft, iconSize)}" library="system" name="confirm"></sd-icon>` : ""} ${slots["right"] ? html`<slot name="right" part="right" class="${cx("inline-flex", iconColor, iconMarginLeft, iconSize)}"></slot>` : ""}</div></div><slot name="help-text" part="form-control-help-text" id="help-text" class="${cx("text-sm text-neutral-700", hasHelpText ? "block" : "hidden")}" aria-hidden="${!hasHelpText}">${this.helpText}</slot></div>${this.formControlController.renderInvalidMessage()}`;
265
258
  }
266
259
  };
267
260
  SdInput.styles = [
268
261
  componentStyles,
269
- formControlStyles,
270
262
  SolidElement.styles,
271
- css`:host{position:relative;box-sizing:border-box;display:inline-block;width:100%;text-align:left}:host([vertical]){display:block}:host([required]) #label.has-label::after{content:'*';margin-left:var(--sd-spacing-0-5,.125rem)}input::-webkit-inner-spin-button,input::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}input[type=number]{-moz-appearance:textfield}input[type=time]::-webkit-calendar-picker-indicator{background:0 0}details summary::-webkit-details-marker,input[type=date]::-webkit-calendar-picker-indicator,input[type=datetime-local]::-webkit-calendar-picker-indicator,input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration,input[type=search]::-webkit-search-results-button,input[type=search]::-webkit-search-results-decoration{display:none}`
263
+ css`:host{position:relative;box-sizing:border-box;display:inline-block;width:100%;text-align:left}:host([vertical]){display:block}:host([required]) #label::after{content:' *'}details summary::-webkit-details-marker{display:none}input::-webkit-inner-spin-button,input::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}input[type=number]{-moz-appearance:textfield}input[type=time]::-webkit-calendar-picker-indicator{background:0 0}details summary::-webkit-details-marker,input[type=date]::-webkit-calendar-picker-indicator,input[type=datetime-local]::-webkit-calendar-picker-indicator,input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration,input[type=search]::-webkit-search-results-button,input[type=search]::-webkit-search-results-decoration{display:none}`
272
264
  ];
273
265
  __decorateClass([
274
266
  query("#input")
275
267
  ], SdInput.prototype, "input", 2);
268
+ __decorateClass([
269
+ query("#invalid-message")
270
+ ], SdInput.prototype, "invalidMessage", 2);
276
271
  __decorateClass([
277
272
  state()
278
273
  ], SdInput.prototype, "hasFocus", 2);
274
+ __decorateClass([
275
+ state()
276
+ ], SdInput.prototype, "showValidStyle", 2);
277
+ __decorateClass([
278
+ state()
279
+ ], SdInput.prototype, "showInvalidStyle", 2);
279
280
  __decorateClass([
280
281
  property({ reflect: true })
281
282
  ], SdInput.prototype, "type", 2);
@@ -7,7 +7,6 @@ import { query, state, property } from "lit/decorators.js";
7
7
  import { watch } from "../../internal/watch.js";
8
8
  import componentStyles from "../../styles/component.styles.js";
9
9
  import cx from "classix";
10
- import formControlStyles from "../../styles/form-control.styles.js";
11
10
  import SolidElement from "../../internal/solid-element.js";
12
11
  var __defProp = Object.defineProperty;
13
12
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -100,7 +99,6 @@ let SdOption = class extends SolidElement {
100
99
  };
101
100
  SdOption.styles = [
102
101
  componentStyles,
103
- formControlStyles,
104
102
  SolidElement.styles,
105
103
  css`:host{position:relative;display:block;width:100%;outline:2px solid transparent!important;outline-offset:2px!important}`
106
104
  ];
@@ -82,13 +82,13 @@ let SdRadio = class extends SolidElement {
82
82
  }[this.size]
83
83
  )}"><span part="${`${this.checked ? "control--checked" : "control--unchecked"}`}" class="${cx(
84
84
  "flex-initial shrink-0 relative inline-flex items-center justify-center border rounded-full bg-white h-4 w-4",
85
- this.disabled && "border-neutral-500" || this.invalid && "border-error hover:border-error-400 group-hover:border-error-400" || this.checked && "border-accent hover:border-accent-550 group-hover:border-accent-550" || "border-neutral-800 hover:bg-neutral-200 group-hover:bg-neutral-200"
85
+ this.disabled ? "border-neutral-500" : this.invalid ? "border-error hover:border-error-400 group-hover:border-error-400" : this.checked ? "border-accent hover:border-accent-550 group-hover:border-accent-550" : "border-neutral-800 hover:bg-neutral-200 group-hover:bg-neutral-200"
86
86
  )}">${this.checked ? html`<span part="checked" class="${cx(
87
87
  "rounded-full inline-flex text-white border bg-accent h-2.5 w-2.5",
88
- this.disabled && "bg-neutral-500" || this.invalid && "bg-error hover:bg-error-400 group-hover:bg-error-400" || this.checked && "bg-accent hover:bg-accent-550 group-hover:bg-accent-550" || "bg-neutral-800"
88
+ this.disabled ? "bg-neutral-500" : this.invalid ? "bg-error hover:bg-error-400 group-hover:bg-error-400" : this.checked ? "bg-accent hover:bg-accent-550 group-hover:bg-accent-550" : "bg-neutral-800"
89
89
  )}"></span>` : ""}</span><slot part="label" class="${cx(
90
90
  "ml-2 select-none inline-block",
91
- this.disabled && "text-neutral-500" || this.invalid && "text-error" || "text-black"
91
+ this.disabled ? "text-neutral-500" : this.invalid ? "text-error" : "text-black"
92
92
  )}"></slot></span>`;
93
93
  }
94
94
  };
@@ -0,0 +1,25 @@
1
+ import SolidElement from '../../internal/solid-element';
2
+ export default class SdRadioButton extends SolidElement {
3
+ private readonly hasSlotController;
4
+ input: HTMLInputElement;
5
+ hiddenInput: HTMLInputElement;
6
+ protected hasFocus: boolean;
7
+ checked: boolean;
8
+ value: string;
9
+ disabled: boolean;
10
+ size: 'lg' | 'md' | 'sm';
11
+ connectedCallback(): void;
12
+ private handleBlur;
13
+ private handleClick;
14
+ private handleFocus;
15
+ handleDisabledChange(): void;
16
+ focus(options?: FocusOptions): void;
17
+ blur(): void;
18
+ render(): import("lit-html").TemplateResult<1>;
19
+ static styles: import("lit").CSSResultGroup[];
20
+ }
21
+ declare global {
22
+ interface HTMLElementTagNameMap {
23
+ 'sd-radio-button': SdRadioButton;
24
+ }
25
+ }
@@ -0,0 +1,118 @@
1
+ import { css, html } from "lit";
2
+ import { customElement } from "../../internal/register-custom-element.js";
3
+ import { HasSlotController } from "../../internal/slot.js";
4
+ import { ifDefined } from "lit/directives/if-defined.js";
5
+ import { query, state, property } from "lit/decorators.js";
6
+ import { watch } from "../../internal/watch.js";
7
+ import componentStyles from "../../styles/component.styles.js";
8
+ import cx from "classix";
9
+ import SolidElement from "../../internal/solid-element.js";
10
+ var __defProp = Object.defineProperty;
11
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
12
+ var __decorateClass = (decorators, target, key, kind) => {
13
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
14
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
15
+ if (decorator = decorators[i])
16
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
17
+ if (kind && result)
18
+ __defProp(target, key, result);
19
+ return result;
20
+ };
21
+ let SdRadioButton = class extends SolidElement {
22
+ constructor() {
23
+ super(...arguments);
24
+ this.hasSlotController = new HasSlotController(this, "[default]", "icon");
25
+ this.hasFocus = false;
26
+ this.checked = false;
27
+ this.disabled = false;
28
+ this.size = "lg";
29
+ }
30
+ connectedCallback() {
31
+ super.connectedCallback();
32
+ this.setAttribute("role", "presentation");
33
+ }
34
+ handleBlur() {
35
+ this.hasFocus = false;
36
+ this.emit("sd-blur");
37
+ }
38
+ handleClick(e) {
39
+ if (this.disabled) {
40
+ e.preventDefault();
41
+ e.stopPropagation();
42
+ return;
43
+ }
44
+ this.checked = true;
45
+ }
46
+ handleFocus() {
47
+ this.hasFocus = true;
48
+ this.emit("sd-focus");
49
+ }
50
+ handleDisabledChange() {
51
+ this.setAttribute("aria-disabled", this.disabled ? "true" : "false");
52
+ }
53
+ /** Sets focus on the radio button. */
54
+ focus(options) {
55
+ this.input.focus(options);
56
+ }
57
+ /** Removes focus from the radio button. */
58
+ blur() {
59
+ this.input.blur();
60
+ }
61
+ render() {
62
+ const hasDefaultSlot = this.hasSlotController.test("[default]");
63
+ const hasIconSlot = this.hasSlotController.test("icon");
64
+ const buttonSizeClass = `${this.size}-${hasDefaultSlot ? "label" : "no-label"}`;
65
+ return html`<div part="base" role="presentation" class="relative"><button part="${`button${this.checked ? " button--checked" : ""}`}" role="radio" aria-checked="${this.checked}" class="${cx(
66
+ "relative text-center border rounded-default transition-all ease-in-out duration-100 items-center justify-center focus-visible:focus-outline",
67
+ this.size === "sm" ? "text-sm" : "text-base",
68
+ this.checked && !this.disabled ? "bg-primary border-primary text-white hover:bg-primary-500 hover:border-primary-500" : this.disabled && !this.checked ? "border-neutral-500 text-neutral-500 hover:cursor-not-allowed" : this.disabled && this.checked ? "bg-neutral-500 text-white hover:cursor-not-allowed" : "bg-transparent text-primary border-primary hover:bg-primary-100 hover:border-primary-500 hover:text-primary-500 cursor-pointer",
69
+ hasDefaultSlot && "px-4",
70
+ this.hasFocus && "focused-class",
71
+ hasDefaultSlot && "button--has-label",
72
+ hasIconSlot && "button--has-icon flex gap-2",
73
+ buttonSizeClass
74
+ )}" aria-disabled="${this.disabled}" type="button" value="${ifDefined(this.value)}" tabindex="${this.checked ? "0" : "-1"}" @blur="${this.handleBlur}" @focus="${this.handleFocus}" @click="${this.handleClick}"><slot name="icon" part="icon" class="${cx(
75
+ hasIconSlot && "inline-flex relative items-center",
76
+ {
77
+ sm: "text-base",
78
+ md: "text-lg",
79
+ lg: "text-xl"
80
+ }[this.size]
81
+ )}" ?hidden="${!hasIconSlot}"></slot>${hasDefaultSlot ? html`<slot part="label" class="button__label inline-flex relative items-center whitespace-nowrap"></slot>` : null}</button></div>`;
82
+ }
83
+ };
84
+ SdRadioButton.styles = [
85
+ SolidElement.styles,
86
+ componentStyles,
87
+ css`:host{display:block;width:-moz-min-content;width:min-content}.hidden-input{all:unset;position:absolute;inset:var(--sd-spacing-0,0);z-index:-10;opacity:var(--sd-opacity-0,0);outline-style:dotted;outline-width:1px;outline-color:rgb(var(--sd-color-error,204 25 55) / 1)}.lg-label{height:var(--sd-spacing-12,3rem)}.lg-no-label{height:var(--sd-spacing-12,3rem);width:var(--sd-spacing-12,3rem)}.md-label{height:var(--sd-spacing-10,2.5rem)}.md-no-label{height:var(--sd-spacing-10,2.5rem);width:var(--sd-spacing-10,2.5rem)}.sm-label{height:var(--sd-spacing-8,2rem)}.sm-no-label{height:var(--sd-spacing-8,2rem);width:var(--sd-spacing-8,2rem)}:host(.sd-button-group__button--first:not(.sd-button-group__button--last)) button{border-top-right-radius:var(--sd-border-radius-none,0);border-bottom-right-radius:var(--sd-border-radius-none,0)}:host(.sd-button-group__button--inner) button{border-radius:var(--sd-border-radius-none,0)}:host(.sd-button-group__button--last:not(.sd-button-group__button--first)) button{border-top-left-radius:var(--sd-border-radius-none,0);border-bottom-left-radius:var(--sd-border-radius-none,0)}:host(.sd-button-group__button:not(.sd-button-group__button--first)){margin-inline-start:-1px}:host(.sd-button-group__button--hover){z-index:10}:host(.sd-button-group__button--focus),:host(.sd-button-group__button[checked]){z-index:20}`
88
+ ];
89
+ __decorateClass([
90
+ query(".button")
91
+ ], SdRadioButton.prototype, "input", 2);
92
+ __decorateClass([
93
+ query(".hidden-input")
94
+ ], SdRadioButton.prototype, "hiddenInput", 2);
95
+ __decorateClass([
96
+ state()
97
+ ], SdRadioButton.prototype, "hasFocus", 2);
98
+ __decorateClass([
99
+ property({ type: Boolean, reflect: true })
100
+ ], SdRadioButton.prototype, "checked", 2);
101
+ __decorateClass([
102
+ property()
103
+ ], SdRadioButton.prototype, "value", 2);
104
+ __decorateClass([
105
+ property({ type: Boolean, reflect: true })
106
+ ], SdRadioButton.prototype, "disabled", 2);
107
+ __decorateClass([
108
+ property({ reflect: true })
109
+ ], SdRadioButton.prototype, "size", 2);
110
+ __decorateClass([
111
+ watch("disabled", { waitUntilFirstUpdate: true })
112
+ ], SdRadioButton.prototype, "handleDisabledChange", 1);
113
+ SdRadioButton = __decorateClass([
114
+ customElement("sd-radio-button")
115
+ ], SdRadioButton);
116
+ export {
117
+ SdRadioButton as default
118
+ };
@@ -12,11 +12,12 @@ export default class SdRadioGroup extends SolidElement implements SolidFormContr
12
12
  private validationTimeout;
13
13
  defaultSlot: HTMLSlotElement;
14
14
  validationInput: HTMLInputElement;
15
+ invalidMessage: HTMLDivElement;
15
16
  private hasButtonGroup;
16
17
  defaultValue: string;
17
- private invalid;
18
- private errorText;
18
+ showInvalidStyle: boolean;
19
19
  label: string;
20
+ boldLabel: boolean;
20
21
  name: string;
21
22
  value: string;
22
23
  size: 'lg' | 'sm';
@@ -30,7 +31,7 @@ export default class SdRadioGroup extends SolidElement implements SolidFormContr
30
31
  private getAllRadios;
31
32
  private handleRadioClick;
32
33
  private handleKeyDown;
33
- private handleLabelClick;
34
+ focus(): void;
34
35
  private handleInvalid;
35
36
  private syncRadioElements;
36
37
  private syncRadios;
@@ -7,6 +7,7 @@ import { watch } from "../../internal/watch.js";
7
7
  import componentStyles from "../../styles/component.styles.js";
8
8
  import cx from "classix";
9
9
  import SdButtonGroup from "../../_components/button-group/button-group.js";
10
+ import SdRadio from "../radio/radio.js";
10
11
  import SolidElement from "../../internal/solid-element.js";
11
12
  var __defProp = Object.defineProperty;
12
13
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -27,9 +28,9 @@ let SdRadioGroup = class extends SolidElement {
27
28
  this.customValidityMessage = "";
28
29
  this.hasButtonGroup = false;
29
30
  this.defaultValue = "";
30
- this.invalid = false;
31
- this.errorText = "";
31
+ this.showInvalidStyle = false;
32
32
  this.label = "";
33
+ this.boldLabel = false;
33
34
  this.name = "option";
34
35
  this.value = "";
35
36
  this.size = "lg";
@@ -42,13 +43,10 @@ let SdRadioGroup = class extends SolidElement {
42
43
  const isRequiredAndEmpty = this.required && !this.value;
43
44
  const hasCustomValidityMessage = this.customValidityMessage !== "";
44
45
  if (hasCustomValidityMessage) {
45
- this.invalid = true;
46
46
  return customErrorValidityState;
47
47
  } else if (isRequiredAndEmpty) {
48
- this.invalid = true;
49
48
  return valueMissingValidityState;
50
49
  }
51
- this.invalid = false;
52
50
  return validValidityState;
53
51
  }
54
52
  /** Gets the validation message */
@@ -56,10 +54,8 @@ let SdRadioGroup = class extends SolidElement {
56
54
  const isRequiredAndEmpty = this.required && !this.value;
57
55
  const hasCustomValidityMessage = this.customValidityMessage !== "";
58
56
  if (hasCustomValidityMessage) {
59
- console.log("this.customValidityMessage", this.customValidityMessage);
60
57
  return this.customValidityMessage;
61
58
  } else if (isRequiredAndEmpty) {
62
- console.log("this.validationInput.validationMessage", this.validationInput);
63
59
  return this.validationInput.validationMessage;
64
60
  }
65
61
  return "";
@@ -123,7 +119,8 @@ let SdRadioGroup = class extends SolidElement {
123
119
  }
124
120
  event.preventDefault();
125
121
  }
126
- handleLabelClick() {
122
+ /** Move focus to the checked radio (or the first one if none are checked) */
123
+ focus() {
127
124
  const radios = this.getAllRadios();
128
125
  const checked = radios.find((radio) => radio.checked);
129
126
  const radioToFocus = checked || radios[0];
@@ -134,6 +131,7 @@ let SdRadioGroup = class extends SolidElement {
134
131
  handleInvalid(event) {
135
132
  this.formControlController.setValidity(false);
136
133
  this.formControlController.emitInvalidEvent(event);
134
+ this.invalidMessage.textContent = event.target.validationMessage;
137
135
  }
138
136
  async syncRadioElements() {
139
137
  var _a, _b;
@@ -144,7 +142,9 @@ let SdRadioGroup = class extends SolidElement {
144
142
  await radio.updateComplete;
145
143
  radio.checked = radio.value === this.value;
146
144
  radio.size = this.size;
147
- radio.invalid = this.invalid;
145
+ if (radio instanceof SdRadio) {
146
+ radio.invalid = this.showInvalidStyle;
147
+ }
148
148
  })
149
149
  );
150
150
  this.hasButtonGroup = radios.some((radio) => radio.tagName.toLowerCase() === "sd-radio-button");
@@ -213,10 +213,8 @@ let SdRadioGroup = class extends SolidElement {
213
213
  return this.formControlController.getForm();
214
214
  }
215
215
  /** Checks for validity and shows the browser's validation message if the control is invalid. */
216
- // TODO: https://github.com/solid-design-system/solid/issues/501
217
216
  reportValidity() {
218
217
  const isValid = this.validity.valid;
219
- this.errorText = this.customValidityMessage || isValid ? "" : this.validationInput.validationMessage;
220
218
  this.formControlController.setValidity(isValid);
221
219
  this.validationInput.hidden = true;
222
220
  clearTimeout(this.validationTimeout);
@@ -230,39 +228,38 @@ let SdRadioGroup = class extends SolidElement {
230
228
  /** Sets a custom validation message. Pass an empty string to restore validity. */
231
229
  setCustomValidity(message = "") {
232
230
  this.customValidityMessage = message;
233
- this.errorText = message;
234
231
  this.validationInput.setCustomValidity(message);
235
232
  this.formControlController.updateValidity();
236
233
  }
237
234
  render() {
238
235
  const hasLabelSlot = this.hasSlotController.test("label");
239
- const hasErrorTextSlot = this.hasSlotController.test("error-text");
240
236
  const hasLabel = this.label ? true : !!hasLabelSlot;
241
- const hasErrorText = this.errorText ? true : !!hasErrorTextSlot;
242
237
  const defaultSlot = html`<slot @slotchange="${this.syncRadios}" @click="${this.handleRadioClick}" @keydown="${this.handleKeyDown}"></slot>`;
243
238
  return html`<fieldset part="form-control" class="${cx(
244
- "border-0 p-0 m-0",
245
- hasErrorText && "text-error",
239
+ "border-0 p-0 m-0 flex flex-col",
246
240
  {
247
241
  /* sizes, fonts */
248
242
  sm: "text-sm",
249
243
  lg: "text-base"
250
244
  }[this.size]
251
- )}" role="radiogroup" aria-labelledby="label" aria-errormessage="error-text"><label part="form-control-label" id="label" class="${cx("mb-2 p-0 font-bold leading-normal text-black", hasLabel ? "has-label flex" : "hidden")}" aria-hidden="${!hasLabel}" @click="${this.handleLabelClick}"><slot name="label">${this.label}</slot></label><div part="form-control-input" class="${cx(
252
- "form-control-input flex",
253
- this.invalid && "form-control-input--invalid text-error",
245
+ )}" role="radiogroup" aria-labelledby="label" aria-errormessage="error-text"><label part="form-control-label" id="label" class="${cx(
246
+ "mb-2 p-0 leading-normal text-black text-left",
247
+ !hasLabel && "hidden",
248
+ this.boldLabel && "font-bold"
249
+ )}" @click="${this.focus}" aria-hidden="${hasLabel ? "false" : "true"}"><slot name="label">${this.label}</slot></label><div part="form-control-input" class="${cx(
250
+ "flex",
254
251
  {
255
252
  vertical: "flex-col",
256
253
  horizontal: "flex-row"
257
254
  }[this.orientation]
258
- )}"><div class="sr-only"><div id="error-message" aria-live="assertive">${this.errorText}</div><label><input id="validation-input" type="text" ?required="${this.required}" tabindex="-1" hidden @invalid="${this.handleInvalid}"></label></div>${defaultSlot}</div></fieldset>`;
255
+ )}"><div class="sr-only"><label><input id="validation-input" type="text" ?required="${this.required}" tabindex="-1" hidden @invalid="${this.handleInvalid}"></label></div>${this.hasButtonGroup ? html`<sd-button-group part="button-group" exportparts="base:button-group__base" role="presentation">${defaultSlot}</sd-button-group>` : defaultSlot}</div></fieldset>${this.formControlController.renderInvalidMessage()}`;
259
256
  }
260
257
  };
261
258
  SdRadioGroup.dependencies = { "sd-button-group": SdButtonGroup };
262
259
  SdRadioGroup.styles = [
263
260
  componentStyles,
264
261
  SolidElement.styles,
265
- css`:host{display:block}:host([orientation=vertical]) ::slotted(sd-radio){margin-bottom:var(--sd-spacing-2,.5rem);display:flex}:host([orientation=vertical]) ::slotted(sd-radio:last-of-type){margin-bottom:var(--sd-spacing-0,0)}:host([orientation=horizontal]) ::slotted(sd-radio){margin-right:var(--sd-spacing-6,1.5rem)}:host([orientation=horizontal]) ::slotted(sd-radio:last-of-type){margin-right:var(--sd-spacing-0,0)}:host([orientation=horizontal]):host([size=sm]) ::slotted(sd-radio){margin-right:var(--sd-spacing-4,1rem)}:host([orientation=horizontal]):host([size=sm]) ::slotted(sd-radio:last-of-type){margin-right:var(--sd-spacing-0,0)}:host([required]) #label.has-label::after{content:'*';margin-left:var(--sd-spacing-0-5,.125rem)}`
262
+ css`:host{display:block}:host([orientation=vertical]) ::slotted(sd-radio){margin-bottom:var(--sd-spacing-2,.5rem);display:flex}:host([orientation=vertical]) ::slotted(sd-radio:last-of-type){margin-bottom:var(--sd-spacing-0,0)}:host([orientation=horizontal]) ::slotted(sd-radio){margin-right:var(--sd-spacing-6,1.5rem)}:host([orientation=horizontal]) ::slotted(sd-radio:last-of-type){margin-right:var(--sd-spacing-0,0)}:host([orientation=horizontal]):host([size=sm]) ::slotted(sd-radio){margin-right:var(--sd-spacing-4,1rem)}:host([orientation=horizontal]):host([size=sm]) ::slotted(sd-radio:last-of-type){margin-right:var(--sd-spacing-0,0)}:host([required]) #label::after{content:' *'}`
266
263
  ];
267
264
  __decorateClass([
268
265
  query("slot:not([name])")
@@ -270,6 +267,9 @@ __decorateClass([
270
267
  __decorateClass([
271
268
  query("#validation-input")
272
269
  ], SdRadioGroup.prototype, "validationInput", 2);
270
+ __decorateClass([
271
+ query("#invalid-message")
272
+ ], SdRadioGroup.prototype, "invalidMessage", 2);
273
273
  __decorateClass([
274
274
  state()
275
275
  ], SdRadioGroup.prototype, "hasButtonGroup", 2);
@@ -278,13 +278,13 @@ __decorateClass([
278
278
  ], SdRadioGroup.prototype, "defaultValue", 2);
279
279
  __decorateClass([
280
280
  state()
281
- ], SdRadioGroup.prototype, "invalid", 2);
282
- __decorateClass([
283
- state()
284
- ], SdRadioGroup.prototype, "errorText", 2);
281
+ ], SdRadioGroup.prototype, "showInvalidStyle", 2);
285
282
  __decorateClass([
286
283
  property()
287
284
  ], SdRadioGroup.prototype, "label", 2);
285
+ __decorateClass([
286
+ property({ type: Boolean, reflect: true })
287
+ ], SdRadioGroup.prototype, "boldLabel", 2);
288
288
  __decorateClass([
289
289
  property()
290
290
  ], SdRadioGroup.prototype, "name", 2);
@@ -307,7 +307,7 @@ __decorateClass([
307
307
  watch("size", { waitUntilFirstUpdate: true })
308
308
  ], SdRadioGroup.prototype, "handleSizeChange", 1);
309
309
  __decorateClass([
310
- watch("invalid", { waitUntilFirstUpdate: true })
310
+ watch("showInvalidStyle", { waitUntilFirstUpdate: true })
311
311
  ], SdRadioGroup.prototype, "handleInvalidChange", 1);
312
312
  __decorateClass([
313
313
  watch("value")
@@ -22,13 +22,14 @@ export default class SdSelect extends SolidElement implements SolidFormControl {
22
22
  displayInput: HTMLInputElement;
23
23
  valueInput: HTMLInputElement;
24
24
  listbox: HTMLSlotElement;
25
+ invalidMessage: HTMLDivElement;
25
26
  private hasFocus;
26
27
  hasHover: boolean;
27
28
  private displayLabel;
28
29
  private currentOption;
29
30
  private selectedOptions;
30
- private isValid;
31
- private isInvalid;
31
+ showValidStyle: boolean;
32
+ showInvalidStyle: boolean;
32
33
  defaultValue: string | string[];
33
34
  open: boolean;
34
35
  size: 'lg' | 'md' | 'sm';
@@ -51,7 +52,6 @@ export default class SdSelect extends SolidElement implements SolidFormControl {
51
52
  get validity(): ValidityState;
52
53
  get validationMessage(): string;
53
54
  connectedCallback(): void;
54
- updated(): void;
55
55
  private addOpenListeners;
56
56
  private removeOpenListeners;
57
57
  private handleFocus;