@progressive-development/pd-forms 0.9.2 → 1.0.1

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 (164) hide show
  1. package/LICENSE +21 -2
  2. package/README.md +56 -62
  3. package/dist/base/pd-base-input-element.d.ts +10 -10
  4. package/dist/base/pd-base-input-element.d.ts.map +1 -1
  5. package/dist/base/pd-base-input-element.js +8 -1
  6. package/dist/base/pd-base-ui-input.d.ts +41 -16
  7. package/dist/base/pd-base-ui-input.d.ts.map +1 -1
  8. package/dist/base/pd-base-ui-input.js +25 -6
  9. package/dist/base/pd-base-ui.js +0 -18
  10. package/dist/generated/locales/be.d.ts +3 -0
  11. package/dist/generated/locales/be.d.ts.map +1 -1
  12. package/dist/generated/locales/de.d.ts +3 -0
  13. package/dist/generated/locales/de.d.ts.map +1 -1
  14. package/dist/generated/locales/en.d.ts +3 -0
  15. package/dist/generated/locales/en.d.ts.map +1 -1
  16. package/dist/index.d.ts +4 -1
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +6 -0
  19. package/dist/locales/be.js +4 -1
  20. package/dist/locales/de.js +4 -1
  21. package/dist/locales/en.js +4 -1
  22. package/dist/pd-button/PdButton.d.ts +172 -37
  23. package/dist/pd-button/PdButton.d.ts.map +1 -1
  24. package/dist/pd-button/PdButton.js +507 -71
  25. package/dist/pd-button/pd-button.stories.d.ts +82 -10
  26. package/dist/pd-button/pd-button.stories.d.ts.map +1 -1
  27. package/dist/pd-button-group/PdButtonGroup.d.ts +25 -0
  28. package/dist/pd-button-group/PdButtonGroup.d.ts.map +1 -1
  29. package/dist/pd-button-group/PdButtonGroup.js +52 -27
  30. package/dist/pd-button-group/pd-button-group.stories.d.ts +42 -17
  31. package/dist/pd-button-group/pd-button-group.stories.d.ts.map +1 -1
  32. package/dist/pd-button-select-group/PdButtonSelectGroup.d.ts +17 -3
  33. package/dist/pd-button-select-group/PdButtonSelectGroup.d.ts.map +1 -1
  34. package/dist/pd-button-select-group/PdButtonSelectGroup.js +23 -19
  35. package/dist/pd-button-select-group/pd-button-select-group.stories.d.ts +43 -18
  36. package/dist/pd-button-select-group/pd-button-select-group.stories.d.ts.map +1 -1
  37. package/dist/pd-checkbox/PdCheckbox.d.ts +23 -2
  38. package/dist/pd-checkbox/PdCheckbox.d.ts.map +1 -1
  39. package/dist/pd-checkbox/PdCheckbox.js +85 -21
  40. package/dist/pd-checkbox/pd-checkbox.stories.d.ts +43 -27
  41. package/dist/pd-checkbox/pd-checkbox.stories.d.ts.map +1 -1
  42. package/dist/pd-form-container/PdFormContainer.d.ts +30 -9
  43. package/dist/pd-form-container/PdFormContainer.d.ts.map +1 -1
  44. package/dist/pd-form-container/PdFormContainer.js +59 -8
  45. package/dist/pd-form-container/pd-form-container.stories.d.ts +49 -0
  46. package/dist/pd-form-container/pd-form-container.stories.d.ts.map +1 -0
  47. package/dist/pd-form-field/PdFormField.d.ts +35 -0
  48. package/dist/pd-form-field/PdFormField.d.ts.map +1 -0
  49. package/dist/pd-form-field/PdFormField.js +38 -0
  50. package/dist/pd-form-field/pd-form-field.d.ts +3 -0
  51. package/dist/pd-form-field/pd-form-field.d.ts.map +1 -0
  52. package/dist/pd-form-field/pd-form-field.stories.d.ts +40 -0
  53. package/dist/pd-form-field/pd-form-field.stories.d.ts.map +1 -0
  54. package/dist/pd-form-field.d.ts +2 -0
  55. package/dist/pd-form-field.js +8 -0
  56. package/dist/pd-form-fieldset/PdFormFieldset.d.ts +144 -0
  57. package/dist/pd-form-fieldset/PdFormFieldset.d.ts.map +1 -0
  58. package/dist/pd-form-fieldset/PdFormFieldset.js +364 -0
  59. package/dist/pd-form-fieldset/index.d.ts +2 -0
  60. package/dist/pd-form-fieldset/index.d.ts.map +1 -0
  61. package/dist/pd-form-fieldset/pd-form-fieldset.d.ts +3 -0
  62. package/dist/pd-form-fieldset/pd-form-fieldset.d.ts.map +1 -0
  63. package/dist/pd-form-fieldset/pd-form-fieldset.js +8 -0
  64. package/dist/pd-form-fieldset/pd-form-fieldset.stories.d.ts +38 -0
  65. package/dist/pd-form-fieldset/pd-form-fieldset.stories.d.ts.map +1 -0
  66. package/dist/pd-form-row/PdFormRow.d.ts +35 -5
  67. package/dist/pd-form-row/PdFormRow.d.ts.map +1 -1
  68. package/dist/pd-form-row/PdFormRow.js +135 -69
  69. package/dist/pd-form-row/pd-form-row.stories.d.ts +41 -25
  70. package/dist/pd-form-row/pd-form-row.stories.d.ts.map +1 -1
  71. package/dist/pd-generic-form/PdGenericForm.d.ts +50 -0
  72. package/dist/pd-generic-form/PdGenericForm.d.ts.map +1 -0
  73. package/dist/pd-generic-form/PdGenericForm.js +334 -0
  74. package/dist/pd-generic-form/pd-generic-form.d.ts +3 -0
  75. package/dist/pd-generic-form/pd-generic-form.d.ts.map +1 -0
  76. package/dist/pd-generic-form/pd-generic-form.stories.d.ts +35 -0
  77. package/dist/pd-generic-form/pd-generic-form.stories.d.ts.map +1 -0
  78. package/dist/pd-generic-form/pd-generic-form.styles.d.ts +2 -0
  79. package/dist/pd-generic-form/pd-generic-form.styles.d.ts.map +1 -0
  80. package/dist/pd-generic-form/pd-generic-form.styles.js +110 -0
  81. package/dist/pd-generic-form/pd-generic-form.test.d.ts +1 -0
  82. package/dist/pd-generic-form/pd-generic-form.test.d.ts.map +1 -0
  83. package/dist/pd-generic-form.d.ts +2 -0
  84. package/dist/pd-generic-form.js +8 -0
  85. package/dist/pd-hover-box/PdHoverBox.d.ts +61 -11
  86. package/dist/pd-hover-box/PdHoverBox.d.ts.map +1 -1
  87. package/dist/pd-hover-box/PdHoverBox.js +130 -28
  88. package/dist/pd-hover-box/pd-hover-box.stories.d.ts +28 -5
  89. package/dist/pd-hover-box/pd-hover-box.stories.d.ts.map +1 -1
  90. package/dist/pd-input/PdComboboxInput.d.ts +20 -0
  91. package/dist/pd-input/PdComboboxInput.d.ts.map +1 -0
  92. package/dist/pd-input/PdComboboxInput.js +67 -0
  93. package/dist/pd-input/PdInput.d.ts +33 -15
  94. package/dist/pd-input/PdInput.d.ts.map +1 -1
  95. package/dist/pd-input/PdInput.js +49 -21
  96. package/dist/pd-input/pd-input.stories.d.ts +71 -35
  97. package/dist/pd-input/pd-input.stories.d.ts.map +1 -1
  98. package/dist/pd-input-area/PdInputArea.d.ts +19 -6
  99. package/dist/pd-input-area/PdInputArea.d.ts.map +1 -1
  100. package/dist/pd-input-area/PdInputArea.js +17 -15
  101. package/dist/pd-input-area/pd-input-area.stories.d.ts +65 -52
  102. package/dist/pd-input-area/pd-input-area.stories.d.ts.map +1 -1
  103. package/dist/pd-input-file/PdInputFile.d.ts +24 -0
  104. package/dist/pd-input-file/PdInputFile.d.ts.map +1 -1
  105. package/dist/pd-input-file/PdInputFile.js +53 -22
  106. package/dist/pd-input-file/pd-input-file.stories.d.ts +51 -47
  107. package/dist/pd-input-file/pd-input-file.stories.d.ts.map +1 -1
  108. package/dist/pd-input-time/PdInputTime.d.ts +21 -0
  109. package/dist/pd-input-time/PdInputTime.d.ts.map +1 -1
  110. package/dist/pd-input-time/PdInputTime.js +48 -22
  111. package/dist/pd-input-time/pd-input-time.stories.d.ts +94 -0
  112. package/dist/pd-input-time/pd-input-time.stories.d.ts.map +1 -0
  113. package/dist/pd-panel-button/PdPanelButton.d.ts +50 -34
  114. package/dist/pd-panel-button/PdPanelButton.d.ts.map +1 -1
  115. package/dist/pd-panel-button/PdPanelButton.js +149 -262
  116. package/dist/pd-panel-button/pd-panel-button.stories.d.ts +55 -25
  117. package/dist/pd-panel-button/pd-panel-button.stories.d.ts.map +1 -1
  118. package/dist/pd-radio-group/PdRadioGroup.d.ts +14 -0
  119. package/dist/pd-radio-group/PdRadioGroup.d.ts.map +1 -1
  120. package/dist/pd-radio-group/PdRadioGroup.js +48 -11
  121. package/dist/pd-radio-group/pd-radio-group.stories.d.ts +37 -7
  122. package/dist/pd-radio-group/pd-radio-group.stories.d.ts.map +1 -1
  123. package/dist/pd-range/PdRange.d.ts +22 -2
  124. package/dist/pd-range/PdRange.d.ts.map +1 -1
  125. package/dist/pd-range/PdRange.js +54 -43
  126. package/dist/pd-range/pd-range.stories.d.ts +49 -7
  127. package/dist/pd-range/pd-range.stories.d.ts.map +1 -1
  128. package/dist/pd-select/PdSelect.d.ts +16 -4
  129. package/dist/pd-select/PdSelect.d.ts.map +1 -1
  130. package/dist/pd-select/PdSelect.js +23 -21
  131. package/dist/pd-select/pd-select.stories.d.ts +56 -35
  132. package/dist/pd-select/pd-select.stories.d.ts.map +1 -1
  133. package/dist/pd-suggestion-box/PdSuggestionBox.d.ts +74 -0
  134. package/dist/pd-suggestion-box/PdSuggestionBox.d.ts.map +1 -0
  135. package/dist/pd-suggestion-box/PdSuggestionBox.js +277 -0
  136. package/dist/pd-suggestion-box/PdSuggestionPanel.d.ts +42 -0
  137. package/dist/pd-suggestion-box/PdSuggestionPanel.d.ts.map +1 -0
  138. package/dist/pd-suggestion-box/PdSuggestionPanel.js +227 -0
  139. package/dist/pd-suggestion-box/pd-suggestion-box.d.ts +3 -0
  140. package/dist/pd-suggestion-box/pd-suggestion-box.d.ts.map +1 -0
  141. package/dist/pd-suggestion-box/pd-suggestion-box.stories.d.ts +79 -0
  142. package/dist/pd-suggestion-box/pd-suggestion-box.stories.d.ts.map +1 -0
  143. package/dist/pd-suggestion-box.d.ts +2 -0
  144. package/dist/pd-suggestion-box.js +8 -0
  145. package/dist/pd-utils/dist/position-helper.js +35 -0
  146. package/dist/stories/pd-forms-overview.stories.d.ts +48 -0
  147. package/dist/stories/pd-forms-overview.stories.d.ts.map +1 -0
  148. package/dist/stories/story-helpers.d.ts +10 -0
  149. package/dist/stories/story-helpers.d.ts.map +1 -0
  150. package/dist/styles/shared-input-field-styles.d.ts.map +1 -1
  151. package/dist/styles/shared-input-field-styles.js +13 -19
  152. package/dist/styles/shared-input-styles.d.ts.map +1 -1
  153. package/dist/styles/shared-input-styles.js +18 -14
  154. package/dist/types.d.ts +11 -0
  155. package/dist/types.d.ts.map +1 -1
  156. package/package.json +11 -4
  157. package/dist/pd-form-container/form-container.stories.d.ts +0 -28
  158. package/dist/pd-form-container/form-container.stories.d.ts.map +0 -1
  159. package/dist/pd-form-container/form-container2.stories.d.ts +0 -8
  160. package/dist/pd-form-container/form-container2.stories.d.ts.map +0 -1
  161. package/dist/pd-form-container/form-container3.stories.d.ts +0 -11
  162. package/dist/pd-form-container/form-container3.stories.d.ts.map +0 -1
  163. package/dist/stories/01_index.stories.d.ts +0 -58
  164. package/dist/stories/01_index.stories.d.ts.map +0 -1
@@ -2,16 +2,6 @@ import { css, html } from 'lit';
2
2
  import { classMap } from 'lit/directives/class-map.js';
3
3
  import { PdBaseUIInput } from '../base/pd-base-ui-input.js';
4
4
 
5
- /**
6
- * @license
7
- * Copyright (c) 2021 PD Progressive Development UG. All rights reserved.
8
- *
9
- * RadioGroup für pd-checkbox Elemente.
10
- *
11
- * - Erlaubt Auswahl genau eines Wertes aus mehreren Checkboxen
12
- * - Setzt `readonly` auf die selektierte Option
13
- * - Sendet `validate-form` Event nach Änderungen
14
- */
15
5
  class PdRadioGroup extends PdBaseUIInput {
16
6
  static {
17
7
  this.styles = [
@@ -47,7 +37,12 @@ class PdRadioGroup extends PdBaseUIInput {
47
37
  return html`
48
38
  ${this._renderLabel(radioInputId)}
49
39
  <div
50
- id=${radioInputId}
40
+ id="${radioInputId}"
41
+ role="radiogroup"
42
+ aria-label="${this.label || ""}"
43
+ aria-disabled="${this.disabled}"
44
+ aria-readonly="${this.readonly}"
45
+ @keydown="${this._onKeyDown}"
51
46
  class="${classMap(
52
47
  this.getClassmap({
53
48
  "group-style": true,
@@ -60,6 +55,48 @@ class PdRadioGroup extends PdBaseUIInput {
60
55
  ${this._renderErrorMsg()}
61
56
  `;
62
57
  }
58
+ _onKeyDown(event) {
59
+ if (this.disabled || this.readonly) return;
60
+ const checkboxes = Array.from(
61
+ this.querySelectorAll("pd-checkbox")
62
+ );
63
+ if (checkboxes.length === 0) return;
64
+ const focusedIndex = checkboxes.findIndex(
65
+ (el) => el.shadowRoot?.activeElement || el.matches(":focus-within")
66
+ );
67
+ let nextIndex = -1;
68
+ switch (event.key) {
69
+ case "ArrowDown":
70
+ case "ArrowRight":
71
+ event.preventDefault();
72
+ nextIndex = focusedIndex < checkboxes.length - 1 ? focusedIndex + 1 : 0;
73
+ break;
74
+ case "ArrowUp":
75
+ case "ArrowLeft":
76
+ event.preventDefault();
77
+ nextIndex = focusedIndex > 0 ? focusedIndex - 1 : checkboxes.length - 1;
78
+ break;
79
+ case "Home":
80
+ event.preventDefault();
81
+ nextIndex = 0;
82
+ break;
83
+ case "End":
84
+ event.preventDefault();
85
+ nextIndex = checkboxes.length - 1;
86
+ break;
87
+ default:
88
+ return;
89
+ }
90
+ if (nextIndex >= 0 && nextIndex < checkboxes.length) {
91
+ const targetCheckbox = checkboxes[nextIndex];
92
+ const radioControl = targetCheckbox.shadowRoot?.querySelector(
93
+ '[role="radio"]'
94
+ );
95
+ if (radioControl) {
96
+ radioControl.focus();
97
+ }
98
+ }
99
+ }
63
100
  _onInternalBlur(e) {
64
101
  e.stopPropagation();
65
102
  }
@@ -1,9 +1,39 @@
1
- import { StoryObj } from '@storybook/web-components';
2
- declare const meta: {
3
- title: string;
4
- argTypes: {};
5
- };
1
+ import { Meta, StoryObj } from '@storybook/web-components-vite';
2
+ interface PdRadioGroupArgs {
3
+ label: string;
4
+ id: string;
5
+ valueName: string;
6
+ required: boolean;
7
+ direction: "row" | "column";
8
+ gap: string;
9
+ }
10
+ /**
11
+ * ## pd-radio-group
12
+ *
13
+ * A radio group container for `pd-checkbox` elements with single-selection behavior.
14
+ *
15
+ * ### Features
16
+ * - **Single Selection**: Only one option can be selected at a time
17
+ * - **Flexible Layout**: Horizontal (row) or vertical (column) arrangement via CSS custom properties
18
+ * - **Form Integration**: Works with `pd-form-container` for validation
19
+ * - **Slot-based**: Uses slotted `pd-checkbox` elements as radio options
20
+ * - **Keyboard Navigation**: Arrow keys, Home/End for option cycling
21
+ */
22
+ declare const meta: Meta<PdRadioGroupArgs>;
6
23
  export default meta;
7
- type Story = StoryObj;
8
- export declare const RadioGroup: Story;
24
+ type Story = StoryObj<PdRadioGroupArgs>;
25
+ /** Default horizontal radio group with three options. Interactive via Controls panel. */
26
+ export declare const Default: Story;
27
+ /** All visual states at a glance: default, preselected, required, and with many options. */
28
+ export declare const AllVariants: Story;
29
+ /** Vertical (column) layout for longer option labels. */
30
+ export declare const VerticalLayout: Story;
31
+ /** Visual difference between radio-style (checkType="RADIO") and checkbox-style children. */
32
+ export declare const StyleComparison: Story;
33
+ /** Required radio group inside a form — triggers validation on button click. */
34
+ export declare const RequiredValidation: Story;
35
+ /** Real-world form pattern with multiple radio groups and submit action. */
36
+ export declare const CompleteFormExample: Story;
37
+ /** CSS Custom Properties — Branded and Redesigned variants. */
38
+ export declare const CustomStyling: Story;
9
39
  //# sourceMappingURL=pd-radio-group.stories.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pd-radio-group.stories.d.ts","sourceRoot":"","sources":["../../src/pd-radio-group/pd-radio-group.stories.ts"],"names":[],"mappings":"AACA,OAAO,EAAQ,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAE3D,OAAO,+BAA+B,CAAC;AACvC,OAAO,qBAAqB,CAAC;AAC7B,OAAO,2CAA2C,CAAC;AAGnD,QAAA,MAAM,IAAI;;;CAGM,CAAC;AAEjB,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC;AAEtB,eAAO,MAAM,UAAU,EAAE,KAiDxB,CAAC"}
1
+ {"version":3,"file":"pd-radio-group.stories.d.ts","sourceRoot":"","sources":["../../src/pd-radio-group/pd-radio-group.stories.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAErE,OAAO,+BAA+B,CAAC;AACvC,OAAO,qBAAqB,CAAC;AAC7B,OAAO,2CAA2C,CAAC;AACnD,OAAO,+BAA+B,CAAC;AACvC,OAAO,2BAA2B,CAAC;AAMnC,UAAU,gBAAgB;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,KAAK,GAAG,QAAQ,CAAC;IAC5B,GAAG,EAAE,MAAM,CAAC;CACb;AAMD;;;;;;;;;;;GAWG;AACH,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,gBAAgB,CA6EhC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,gBAAgB,CAAC,CAAC;AAMxC,yFAAyF;AACzF,eAAO,MAAM,OAAO,EAAE,KAoBrB,CAAC;AAMF,4FAA4F;AAC5F,eAAO,MAAM,WAAW,EAAE,KAoGzB,CAAC;AAMF,yDAAyD;AACzD,eAAO,MAAM,cAAc,EAAE,KAwB5B,CAAC;AAMF,6FAA6F;AAC7F,eAAO,MAAM,eAAe,EAAE,KAwC7B,CAAC;AAMF,gFAAgF;AAChF,eAAO,MAAM,kBAAkB,EAAE,KAoChC,CAAC;AAMF,4EAA4E;AAC5E,eAAO,MAAM,mBAAmB,EAAE,KAqFjC,CAAC;AAMF,+DAA+D;AAC/D,eAAO,MAAM,aAAa,EAAE,KAoH3B,CAAC"}
@@ -1,13 +1,33 @@
1
1
  import { CSSResultGroup, PropertyValues } from 'lit';
2
2
  import { PdBaseUIInput } from '../base/pd-base-ui-input.js';
3
3
  /**
4
+ * Range slider input component.
5
+ *
4
6
  * @tagname pd-range
7
+ * @summary Range slider input with customizable min/max/step.
8
+ *
9
+ * @event validate-form - Fired when value changes for validation.
10
+ * @event field-change - Fired when value changes.
11
+ * @event pd-form-element-blur - Fired when the range input loses focus.
12
+ * @event pd-form-element-focus - Fired when the range input gains focus.
13
+ *
14
+ * @cssprop --pd-input-field-width - Slider width.
15
+ * @cssprop --pd-input-field-range-height - Slider height.
16
+ * @cssprop --pd-range-bg-col - Slider background.
17
+ * @cssprop --pd-range-thumb-col - Thumb color.
18
+ * @cssprop --pd-range-track-col - Track color.
19
+ * @cssprop --pd-range-track-hover-col - Track hover color.
5
20
  */
6
21
  export declare class PdRange extends PdBaseUIInput {
22
+ /** Minimum value. */
7
23
  min: number;
24
+ /** Maximum value. */
8
25
  max: number;
26
+ /** Step increment. */
9
27
  step: number;
28
+ /** Map of values to display labels. */
10
29
  optionValueMapper: Record<string, string>;
30
+ /** Form field name. */
11
31
  name: string;
12
32
  protected _input: HTMLInputElement | null | undefined;
13
33
  static styles: CSSResultGroup;
@@ -15,8 +35,8 @@ export declare class PdRange extends PdBaseUIInput {
15
35
  update(changedProps: PropertyValues<this>): void;
16
36
  firstUpdated(): void;
17
37
  protected _onChange(e: Event): void;
18
- protected _onBlur(event: Event): void;
19
- protected _onFocus(event: Event): void;
38
+ protected _onBlur(_event: Event): void;
39
+ protected _onFocus(_event: Event): void;
20
40
  focus(): void;
21
41
  render(): import('lit').TemplateResult<1>;
22
42
  _getInitialValue(): string;
@@ -1 +1 @@
1
- {"version":3,"file":"PdRange.d.ts","sourceRoot":"","sources":["../../src/pd-range/PdRange.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAa,cAAc,EAAE,cAAc,EAAE,MAAM,KAAK,CAAC;AAIhE,OAAO,EAAE,aAAa,EAAoB,MAAM,6BAA6B,CAAC;AAE9E;;GAEG;AACH,qBAAa,OAAQ,SAAQ,aAAa;IAExC,GAAG,EAAE,MAAM,CAAK;IAGhB,GAAG,EAAE,MAAM,CAAM;IAGjB,IAAI,SAAK;IAGT,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAM;IAG/C,IAAI,SAAM;IAEV,SAAS,CAAC,MAAM,EAAG,gBAAgB,GAAG,IAAI,GAAG,SAAS,CAAC;IAEvD,OAAgB,MAAM,EAAE,cAAc,CAqJpC;;IAOO,MAAM,CAAC,YAAY,EAAE,cAAc,CAAC,IAAI,CAAC,GAAG,IAAI;IAOhD,YAAY,IAAI,IAAI;IAK7B,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,GAAG,IAAI;IAInC,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAgBrC,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IActC,KAAK,IAAI,IAAI;IAIJ,MAAM;IAuCN,gBAAgB,IAAI,MAAM;IAI5B,KAAK,IAAI,IAAI;CAGrB"}
1
+ {"version":3,"file":"PdRange.d.ts","sourceRoot":"","sources":["../../src/pd-range/PdRange.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAa,cAAc,EAAE,cAAc,EAAE,MAAM,KAAK,CAAC;AAIhE,OAAO,EAAE,aAAa,EAAoB,MAAM,6BAA6B,CAAC;AAE9E;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,OAAQ,SAAQ,aAAa;IACxC,qBAAqB;IAErB,GAAG,EAAE,MAAM,CAAK;IAEhB,qBAAqB;IAErB,GAAG,EAAE,MAAM,CAAM;IAEjB,sBAAsB;IAEtB,IAAI,SAAK;IAET,uCAAuC;IAEvC,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAM;IAE/C,uBAAuB;IAEvB,IAAI,SAAM;IAEV,SAAS,CAAC,MAAM,EAAG,gBAAgB,GAAG,IAAI,GAAG,SAAS,CAAC;IAEvD,OAAgB,MAAM,EAAE,cAAc,CA0JpC;;IAOO,MAAM,CAAC,YAAY,EAAE,cAAc,CAAC,IAAI,CAAC,GAAG,IAAI;IAOhD,YAAY,IAAI,IAAI;IAK7B,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,GAAG,IAAI;IAInC,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,KAAK,GAAG,IAAI;IAgBtC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,KAAK,GAAG,IAAI;IAcvC,KAAK,IAAI,IAAI;IAIJ,MAAM;IA6CN,gBAAgB,IAAI,MAAM;IAI5B,KAAK,IAAI,IAAI;CAGrB"}
@@ -26,14 +26,25 @@ class PdRange extends PdBaseUIInput {
26
26
  this.styles = [
27
27
  PdBaseUIInput.styles,
28
28
  css`
29
+ :host {
30
+ display: inline-block;
31
+ box-sizing: border-box;
32
+ }
33
+
29
34
  :host([disabled]) {
30
- --pd-range-bg-col: grey;
31
- --pd-range-thumb-col: lightgrey;
35
+ --pd-range-bg-col: var(--pd-default-disabled-col);
36
+ --pd-range-thumb-col: var(--pd-default-disabled-light-col);
37
+ }
38
+
39
+ .input-range {
40
+ display: inline-block;
41
+ width: var(--pd-input-field-width, 250px);
42
+ box-sizing: border-box;
32
43
  }
33
44
 
34
45
  input[type="range"] {
35
46
  -webkit-appearance: none;
36
- width: var(--pd-input-field-width, 250px);
47
+ width: 100%;
37
48
  background: transparent;
38
49
  background-color: var(--pd-range-bg-col, var(--pd-default-col));
39
50
  padding: 0.5rem;
@@ -46,6 +57,11 @@ class PdRange extends PdBaseUIInput {
46
57
  outline: none;
47
58
  }
48
59
 
60
+ input[type="range"]:focus-visible {
61
+ outline: 2px solid var(--pd-focus-ring-col);
62
+ outline-offset: 2px;
63
+ }
64
+
49
65
  input[type="range"]::-webkit-slider-thumb {
50
66
  -webkit-appearance: none;
51
67
  margin-top: -6px;
@@ -55,9 +71,7 @@ class PdRange extends PdBaseUIInput {
55
71
  background: var(--pd-range-thumb-col, var(--pd-default-hover-col));
56
72
  border: 1px solid var(--pd-default-dark-col);
57
73
  border-radius: 3px;
58
- box-shadow:
59
- 1px 1px 1px #000000,
60
- 0px 0px 1px #0d0d0d;
74
+ box-shadow: var(--pd-shadow-sm);
61
75
  }
62
76
 
63
77
  input[type="range"]::-moz-range-thumb {
@@ -67,9 +81,7 @@ class PdRange extends PdBaseUIInput {
67
81
  background: var(--pd-range-thumb-col, var(--pd-default-hover-col));
68
82
  border: 1px solid var(--pd-default-dark-col);
69
83
  border-radius: 3px;
70
- box-shadow:
71
- 1px 1px 1px #000000,
72
- 0px 0px 1px #0d0d0d;
84
+ box-shadow: var(--pd-shadow-sm);
73
85
  }
74
86
 
75
87
  input[type="range"]::-ms-thumb {
@@ -79,20 +91,16 @@ class PdRange extends PdBaseUIInput {
79
91
  background: var(--pd-range-thumb-col, var(--pd-default-hover-col));
80
92
  border: 1px solid var(--pd-default-dark-col);
81
93
  border-radius: 3px;
82
- box-shadow:
83
- 1px 1px 1px #000000,
84
- 0px 0px 1px #0d0d0d;
94
+ box-shadow: var(--pd-shadow-sm);
85
95
  }
86
96
 
87
97
  input[type="range"]::-webkit-slider-runnable-track {
88
98
  width: 100%;
89
99
  height: 8.4px;
90
100
  cursor: pointer;
91
- box-shadow:
92
- 1px 1px 1px #000000,
93
- 0px 0px 1px #0d0d0d;
101
+ box-shadow: var(--pd-shadow-sm);
94
102
  background: var(--pd-range-track-col, var(--pd-default-light-col));
95
- border: 0.2px solid #010101;
103
+ border: 0.2px solid var(--pd-default-darkest-col);
96
104
  border-radius: 0.75rem;
97
105
  }
98
106
 
@@ -108,12 +116,10 @@ class PdRange extends PdBaseUIInput {
108
116
  width: 100%;
109
117
  height: 8.4px;
110
118
  cursor: pointer;
111
- box-shadow:
112
- 1px 1px 1px #000000,
113
- 0px 0px 1px #0d0d0d;
119
+ box-shadow: var(--pd-shadow-sm);
114
120
  background: var(--pd-range-track-col, var(--pd-default-light-col));
115
121
  border-radius: 0.75rem;
116
- border: 0.2px solid #010101;
122
+ border: 0.2px solid var(--pd-default-darkest-col);
117
123
  }
118
124
 
119
125
  input[type="range"]::-ms-track {
@@ -129,25 +135,24 @@ class PdRange extends PdBaseUIInput {
129
135
  input[type="range"]::-ms-fill-lower,
130
136
  input[type="range"]::-ms-fill-upper {
131
137
  background: var(--pd-range-track-col, var(--pd-default-light-col));
132
- border: 0.2px solid #010101;
138
+ border: 0.2px solid var(--pd-default-darkest-col);
133
139
  border-radius: 0.75rem;
134
- box-shadow:
135
- 1px 1px 1px #000000,
136
- 0px 0px 1px #0d0d0d;
140
+ box-shadow: var(--pd-shadow-sm);
137
141
  }
138
142
 
139
143
  input[type="range"]:focus::-ms-fill-lower {
140
- background: #3071a9;
144
+ background: var(--pd-default-col);
141
145
  }
142
146
 
143
147
  input[type="range"]:focus::-ms-fill-upper {
144
- background: #367ebd;
148
+ background: var(--pd-default-lighter-col);
145
149
  }
146
150
 
147
151
  .ticks {
148
152
  display: flex;
149
153
  justify-content: space-between;
150
- padding: 10px 30px;
154
+ padding: 10px 20px;
155
+ box-sizing: border-box;
151
156
  }
152
157
 
153
158
  .tick {
@@ -159,7 +164,7 @@ class PdRange extends PdBaseUIInput {
159
164
  }
160
165
 
161
166
  .ticks.disabled {
162
- color: grey;
167
+ color: var(--pd-default-disabled-col);
163
168
  }
164
169
 
165
170
  .ticks.enabled {
@@ -187,7 +192,7 @@ class PdRange extends PdBaseUIInput {
187
192
  _onChange(e) {
188
193
  this._handleChangedValue(this._input?.value ?? "", e, true);
189
194
  }
190
- _onBlur(event) {
195
+ _onBlur(_event) {
191
196
  this._focused = false;
192
197
  this._touched = true;
193
198
  this.dispatchEvent(
@@ -201,7 +206,7 @@ class PdRange extends PdBaseUIInput {
201
206
  })
202
207
  );
203
208
  }
204
- _onFocus(event) {
209
+ _onFocus(_event) {
205
210
  this._focused = true;
206
211
  this.dispatchEvent(
207
212
  new CustomEvent("pd-form-element-focus", {
@@ -230,22 +235,28 @@ class PdRange extends PdBaseUIInput {
230
235
  )}"
231
236
  >
232
237
  <input
233
- id=${inputId}
234
- name=${this.name || this.valueName || ""}
238
+ id="${inputId}"
239
+ name="${this.name || this.valueName || ""}"
235
240
  class="input-range-style ${this.gradient ? "gradient" : ""}"
236
241
  type="range"
237
- .value=${this._value}
238
- ?readonly=${this.readonly}
239
- ?disabled=${this.disabled}
240
- min=${this.min}
241
- max=${this.max}
242
- step=${this.step}
243
- @change=${this._onChange}
244
- @input=${this._onChange}
245
- @blur=${this._onBlur}
246
- @focus=${this._onFocus}
242
+ .value="${this._value}"
243
+ ?disabled="${this.disabled}"
244
+ min="${this.min}"
245
+ max="${this.max}"
246
+ step="${this.step}"
247
+ aria-valuemin="${this.min}"
248
+ aria-valuemax="${this.max}"
249
+ aria-valuenow="${this._value}"
250
+ aria-valuetext="${labelDetail}"
251
+ @change="${this._onChange}"
252
+ @input="${this._onChange}"
253
+ @blur="${this._onBlur}"
254
+ @focus="${this._onFocus}"
247
255
  />
248
- <div class="ticks ${this.disabled ? "disabled" : "enabled"}">
256
+ <div
257
+ class="ticks ${this.disabled ? "disabled" : "enabled"}"
258
+ aria-hidden="true"
259
+ >
249
260
  ${Array.from({ length: this.max - this.min + 1 }).map(
250
261
  () => html`<span class="tick">|</span>`
251
262
  )}
@@ -1,9 +1,51 @@
1
- import { StoryObj } from '@storybook/web-components';
2
- declare const meta: {
3
- title: string;
4
- argTypes: {};
5
- };
1
+ import { Meta, StoryObj } from '@storybook/web-components-vite';
2
+ interface PdRangeArgs {
3
+ label: string;
4
+ min: number;
5
+ max: number;
6
+ step: number;
7
+ initValue: string;
8
+ helperTxt: string;
9
+ disabled: boolean;
10
+ required: boolean;
11
+ optionValueMapper: Record<string, string>;
12
+ }
13
+ /**
14
+ * ## pd-range
15
+ *
16
+ * A styled range slider for selecting numeric values with optional label mapping.
17
+ *
18
+ * ### Features
19
+ * - **Value Mapping**: Map numeric values to descriptive labels via `optionValueMapper`
20
+ * - **Custom Range**: Configurable min, max, and step values
21
+ * - **Visual Ticks**: Shows tick marks for each step on the slider
22
+ * - **Form Integration**: Works with `pd-form-container` for validation
23
+ *
24
+ * ### Accessibility
25
+ * - Native range input for keyboard navigation
26
+ * - Label displays current mapped value
27
+ * - Disabled state support
28
+ *
29
+ * ## Usage
30
+ * ```html
31
+ * <pd-range
32
+ * label="Satisfaction"
33
+ * min="1" max="5" initValue="3"
34
+ * .optionValueMapper=${{ 1: "Poor", 5: "Excellent" }}
35
+ * ></pd-range>
36
+ * ```
37
+ */
38
+ declare const meta: Meta<PdRangeArgs>;
6
39
  export default meta;
7
- type Story = StoryObj;
8
- export declare const Range: Story;
40
+ type Story = StoryObj<PdRangeArgs>;
41
+ /** Default range slider with value mapping. Interactive via Controls panel. */
42
+ export declare const Default: Story;
43
+ /** All range slider states at a glance: default, helper text, disabled, required. */
44
+ export declare const AllStates: Story;
45
+ /** Different value mappers and range configurations side by side. */
46
+ export declare const ValueMappers: Story;
47
+ /** Range slider within a pd-form-container for validation. */
48
+ export declare const FormIntegration: Story;
49
+ /** CSS Custom Properties -- Branded and Redesigned variants. */
50
+ export declare const CustomStyling: Story;
9
51
  //# sourceMappingURL=pd-range.stories.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pd-range.stories.d.ts","sourceRoot":"","sources":["../../src/pd-range/pd-range.stories.ts"],"names":[],"mappings":"AACA,OAAO,EAAQ,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAE3D,OAAO,eAAe,CAAC;AACvB,OAAO,2CAA2C,CAAC;AACnD,OAAO,+BAA+B,CAAC;AAGvC,QAAA,MAAM,IAAI;;;CAGM,CAAC;AAEjB,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC;AAUtB,eAAO,MAAM,KAAK,EAAE,KAkFnB,CAAC"}
1
+ {"version":3,"file":"pd-range.stories.d.ts","sourceRoot":"","sources":["../../src/pd-range/pd-range.stories.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAErE,OAAO,eAAe,CAAC;AACvB,OAAO,2CAA2C,CAAC;AACnD,OAAO,+BAA+B,CAAC;AAMvC,UAAU,WAAW;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC3C;AA8CD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,WAAW,CA2F3B,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC;AAMnC,+EAA+E;AAC/E,eAAO,MAAM,OAAO,EAAE,KAoBrB,CAAC;AAMF,qFAAqF;AACrF,eAAO,MAAM,SAAS,EAAE,KAqEvB,CAAC;AAMF,qEAAqE;AACrE,eAAO,MAAM,YAAY,EAAE,KAkE1B,CAAC;AAMF,8DAA8D;AAC9D,eAAO,MAAM,eAAe,EAAE,KA8B7B,CAAC;AAMF,gEAAgE;AAChE,eAAO,MAAM,aAAa,EAAE,KA6F3B,CAAC"}
@@ -2,19 +2,31 @@ import { CSSResultGroup, PropertyValues } from 'lit';
2
2
  import { PdBaseInputElement } from '../base/pd-base-input-element.js';
3
3
  import { PdSelectOption } from '../types.js';
4
4
  /**
5
+ * Select dropdown component for forms.
6
+ *
5
7
  * @tagname pd-select
8
+ * @summary Styled select dropdown with native accessibility.
9
+ *
10
+ * @event validate-form - Fired when selection changes for validation.
11
+ * @event field-change - Fired when selection changes.
12
+ *
13
+ * @cssprop --pd-input-field-width - Select width. Default: `250px`.
14
+ * @cssprop --pd-input-field-height - Select height. Default: `2.2rem`.
15
+ * @cssprop --pd-input-field-padding - Select padding. Default: `0.25rem`.
16
+ * @cssprop --pd-input-field-bg-col - Background color. Default: `var(--pd-default-bg-col)`.
17
+ * @cssprop --pd-input-field-border - Border style. Default: `1px solid var(--pd-default-light-col)`.
18
+ * @cssprop --pd-input-field-border-bottom - Bottom border. Default: `2px solid var(--pd-default-col)`.
19
+ * @cssprop --pd-input-field-border-focus - Focus border. Default: `2px solid var(--pd-default-col)`.
20
+ * @cssprop --pd-input-field-border-col-hover - Hover border color. Default: `var(--pd-default-hover-col)`.
6
21
  */
7
22
  export declare class PdSelect extends PdBaseInputElement {
23
+ /** Array of options to display in the dropdown. */
8
24
  values: PdSelectOption[];
9
25
  static styles: CSSResultGroup;
10
26
  constructor();
11
27
  update(changedProps: PropertyValues<this>): void;
12
28
  render(): import('lit').TemplateResult<1>;
13
29
  protected _onSelectChange(event: Event): void;
14
- /**
15
- * Empty, reserved for possible future enhancements on keyup for select.
16
- */
17
- protected _onSelectKeyUp(): void;
18
30
  _getInitialValue(): string;
19
31
  clear(): void;
20
32
  }
@@ -1 +1 @@
1
- {"version":3,"file":"PdSelect.d.ts","sourceRoot":"","sources":["../../src/pd-select/PdSelect.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAa,cAAc,EAAE,cAAc,EAAE,MAAM,KAAK,CAAC;AAKhE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C;;GAEG;AACH,qBAAa,QAAS,SAAQ,kBAAkB;IAE9C,MAAM,EAAE,cAAc,EAAE,CAAM;IAE9B,OAAgB,MAAM,EAAE,cAAc,CA0DpC;;IAOO,MAAM,CAAC,YAAY,EAAE,cAAc,CAAC,IAAI,CAAC,GAAG,IAAI;IAWhD,MAAM;IAoCf,SAAS,CAAC,eAAe,CAAC,KAAK,EAAE,KAAK;IAItC;;OAEG;IACH,SAAS,CAAC,cAAc,IAAI,IAAI;IAIvB,gBAAgB,IAAI,MAAM;IAI5B,KAAK,IAAI,IAAI;CAGrB"}
1
+ {"version":3,"file":"PdSelect.d.ts","sourceRoot":"","sources":["../../src/pd-select/PdSelect.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAa,cAAc,EAAE,cAAc,EAAE,MAAM,KAAK,CAAC;AAKhE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,QAAS,SAAQ,kBAAkB;IAC9C,mDAAmD;IAEnD,MAAM,EAAE,cAAc,EAAE,CAAM;IAE9B,OAAgB,MAAM,EAAE,cAAc,CA4DpC;;IAOO,MAAM,CAAC,YAAY,EAAE,cAAc,CAAC,IAAI,CAAC,GAAG,IAAI;IAchD,MAAM;IAyCf,SAAS,CAAC,eAAe,CAAC,KAAK,EAAE,KAAK;IAI7B,gBAAgB,IAAI,MAAM;IAI5B,KAAK,IAAI,IAAI;CAGrB"}
@@ -23,13 +23,14 @@ class PdSelect extends PdBaseInputElement {
23
23
  this.styles = [
24
24
  PdBaseInputElement.styles,
25
25
  css`
26
+ /* SVG arrow color #067394 is hardcoded in data URI - matches --pd-default-col */
26
27
  .select-css {
27
28
  display: block;
28
29
  -moz-appearance: none;
29
30
  -webkit-appearance: none;
30
31
  appearance: none;
31
- padding: 5px;
32
- background-image: url("data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22%23007CB2%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E");
32
+ padding: var(--pd-input-field-padding, 0.25rem);
33
+ background-image: url("data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22%23067394%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E");
33
34
  background-repeat: no-repeat, repeat;
34
35
  background-position:
35
36
  right 0.5em top 50%,
@@ -51,7 +52,7 @@ class PdSelect extends PdBaseInputElement {
51
52
 
52
53
  .gradient {
53
54
  background-image:
54
- url("data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22%23007CB2%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E"),
55
+ url("data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22%23067394%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E"),
55
56
  linear-gradient(
56
57
  to bottom,
57
58
  var(--my-background-gradient-color),
@@ -60,13 +61,14 @@ class PdSelect extends PdBaseInputElement {
60
61
  background-color: var(--my-background-color);
61
62
  }
62
63
 
64
+ /* SVG arrow color is hardcoded in data URI - uses disabled gray for error state */
63
65
  .error .gradient {
64
66
  background-image:
65
- url("data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22graytext%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E"),
67
+ url("data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22%23878787%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E"),
66
68
  linear-gradient(
67
69
  to bottom,
68
70
  var(--my-background-gradient-color) 10%,
69
- #f5979b 100%
71
+ var(--pd-default-error-light-col) 100%
70
72
  );
71
73
  background-repeat: no-repeat, repeat;
72
74
  background-position:
@@ -81,13 +83,14 @@ class PdSelect extends PdBaseInputElement {
81
83
  ];
82
84
  }
83
85
  update(changedProps) {
84
- if (changedProps.has("values") && this.values?.length > 0 && !this.initValue) {
86
+ if (changedProps.has("values") && this.values?.length > 0 && !this.initValue && !this._value) {
85
87
  this._value = this.values[0].value;
86
88
  }
87
89
  super.update(changedProps);
88
90
  }
89
91
  render() {
90
92
  const selectId = `${this.id}Select`;
93
+ const errorId = `${this.id}Error`;
91
94
  return html`
92
95
  ${this._renderLabel(selectId)}
93
96
  <div
@@ -98,36 +101,35 @@ class PdSelect extends PdBaseInputElement {
98
101
  )}"
99
102
  >
100
103
  <select
101
- id=${selectId}
104
+ id="${selectId}"
102
105
  class="input-style select-css ${this.gradient ? "gradient" : ""}"
103
- ?disabled=${this.disabled}
104
- name=${this.name || this.valueName || this.autoCompleteName}
105
- autocomplete=${this.autoCompleteName ?? "off"}
106
- @change=${this._onSelectChange}
107
- @keyup=${this._onSelectKeyUp}
108
- @blur=${this._onBlur}
109
- @focus=${this._onFocus}
106
+ ?disabled="${this.disabled}"
107
+ name="${this.name || this.valueName || this.autoCompleteName}"
108
+ autocomplete="${this.autoCompleteName ?? "off"}"
109
+ aria-invalid="${this._invalid}"
110
+ aria-describedby="${this._errorMsg ? errorId : ""}"
111
+ @change="${this._onSelectChange}"
112
+ @blur="${this._onBlur}"
113
+ @focus="${this._onFocus}"
110
114
  >
111
115
  ${this.values.map(
112
116
  (val) => html`
113
- <option value=${val.value} ?selected=${this._value == val.value}>
117
+ <option
118
+ value="${val.value}"
119
+ ?selected="${String(this._value) === String(val.value)}"
120
+ >
114
121
  ${val.name}
115
122
  </option>
116
123
  `
117
124
  )}
118
125
  </select>
119
126
  </div>
120
- ${this._renderErrorMsg()}
127
+ ${this._renderErrorMsg(errorId)}
121
128
  `;
122
129
  }
123
130
  _onSelectChange(event) {
124
131
  this._handleChangedValue(this._input.value, event, true);
125
132
  }
126
- /**
127
- * Empty, reserved for possible future enhancements on keyup for select.
128
- */
129
- _onSelectKeyUp() {
130
- }
131
133
  _getInitialValue() {
132
134
  return this.initValue || this.values[0]?.value || "";
133
135
  }