@progressive-development/pd-forms 0.9.2 → 1.0.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 (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 +171 -37
  23. package/dist/pd-button/PdButton.d.ts.map +1 -1
  24. package/dist/pd-button/PdButton.js +502 -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
@@ -1,8 +1,7 @@
1
- import { css, html } from 'lit';
2
- import { property, state } from 'lit/decorators.js';
3
- import '@progressive-development/pd-icon/pd-icon';
4
- import { PdBaseUI } from '../base/pd-base-ui.js';
1
+ import { css, html, nothing } from 'lit';
2
+ import { property, state, query } from 'lit/decorators.js';
5
3
  import { pdIcons } from '@progressive-development/pd-icon';
4
+ import { PdButton } from '../pd-button/PdButton.js';
6
5
 
7
6
  var __defProp = Object.defineProperty;
8
7
  var __decorateClass = (decorators, target, key, kind) => {
@@ -13,172 +12,58 @@ var __decorateClass = (decorators, target, key, kind) => {
13
12
  if (result) __defProp(target, key, result);
14
13
  return result;
15
14
  };
16
- class PdPanelButton extends PdBaseUI {
15
+ let panelIdCounter = 0;
16
+ class PdPanelButton extends PdButton {
17
17
  constructor() {
18
18
  super(...arguments);
19
- this.buttonText = "Ok";
20
- this.panelButton = false;
21
- this.loading = false;
22
- this.selected = false;
23
- this.primary = false;
24
- this.disableOnClickTime = -1;
25
19
  this.hideClose = false;
26
- this._timerDisabled = false;
20
+ this.up = false;
21
+ this.right = false;
27
22
  this._panelOpen = false;
28
- this._closePanel = () => {
29
- this._panelOpen = false;
30
- };
23
+ /** @ignore - Unique ID for aria-controls */
24
+ this._panelId = `pd-panel-${++panelIdCounter}`;
25
+ /** @ignore - Bound method reference for event listener cleanup */
26
+ this._boundClosePanel = this._closePanel.bind(this);
27
+ /** @ignore - Bound method reference for keyboard event listener */
28
+ this._boundHandleKeyDown = this._handlePanelKeyDown.bind(this);
31
29
  }
32
30
  static {
31
+ // ============================================================================
32
+ // STYLES (Panel-specific only - Button styles inherited from PdButton)
33
+ // ============================================================================
33
34
  this.styles = [
35
+ PdButton.styles,
34
36
  css`
35
37
  :host {
36
- display: inline-block; /* Verhindert, dass :host die volle Breite bekommt */
37
38
  position: relative;
38
39
  }
39
40
 
40
- :host([disabled]),
41
- :host([_timerDisabled]) {
42
- pointer-events: none;
41
+ /* Toggle arrow icon styling - inherits color from .button-icon in PdButton */
42
+ .toggle-icon {
43
+ margin-left: calc(0.25rem * var(--pd-button-scale, 1));
43
44
  }
44
45
 
45
- .icon-button-style {
46
- --pd-icon-size: var(--pd-icon-button-size, 32px);
47
- box-sizing: border-box;
48
- width: var(--pd-icon-button-width, auto);
49
- z-index: 6;
50
-
51
- display: inline-flex;
52
- align-items: center;
53
- justify-content: var(--pd-icon-button-justify, center);
54
- gap: var(--pd-icon-button-gap, 0.5rem);
55
-
56
- height: var(--pd-icon-button-height, auto);
57
- line-height: var(--pd-icon-button-line-height, 1);
58
- padding: var(--pd-icon-button-padding, 0 1rem);
59
-
60
- background: var(
61
- --pd-icon-button-bg,
62
- #58a linear-gradient(hsla(0, 0%, 100%, 0.2), transparent)
63
- );
64
- background-color: var(--pd-icon-button-bgcol, var(--pd-default-col));
65
- border: 1px solid
66
- var(--pd-icon-button-bordercol, var(--pd-default-dark-col));
67
- border-radius: var(--pd-icon-button-border-radius, 0.2em);
68
- transition: background-color 0.3s ease;
69
-
70
- vertical-align: middle;
71
- text-align: center;
72
-
73
- color: var(--pd-icon-button-txtcol, var(--pd-secondary-light-col));
74
- --pd-icon-col: var(
75
- --pd-icon-button-txtcol,
76
- var(--pd-secondary-light-col)
77
- );
78
- --pd-icon-col-active: var(
79
- --pd-icon-button-txtcol,
80
- var(--pd-secondary-light-col)
81
- );
82
- }
83
-
84
- .button-text {
85
- text-shadow: 0 -0.05em 0.05em rgba(0, 0, 0, 0.5);
86
- font-size: var(--pd-icon-button-font-size, 1.5rem);
87
- font-weight: bold;
88
- font-family: var(--pd-default-font-title-family);
89
- padding: 0.55rem 0;
90
- }
91
-
92
- .button-icon {
93
- padding: 0.3rem 0;
94
- }
95
-
96
- .toggle-button {
97
- padding-left: var(--pd-icon-button-gap, 0.5rem);
98
- }
99
-
100
- .loader {
101
- border: 12px solid var(--pd-secondary-col);
102
- border-top: 12px solid var(--pd-secondary-light-col);
103
- border-radius: 50%;
104
- width: 10px;
105
- height: 10px;
106
- animation: spin 2s linear infinite;
107
-
108
- margin: 0.3rem 0.1rem 0.3rem 0;
109
- }
110
-
111
- :host(:not([disabled]):not([_timerDisabled])) .icon-button-style:hover {
112
- background-color: var(
113
- --pd-icon-button-bgcol-hover,
114
- var(--pd-default-hover-col)
115
- );
116
- cursor: pointer;
117
- }
118
-
119
- :host([disabled]) .icon-button-style,
120
- :host([_timerDisabled]) .icon-button-style {
121
- background: linear-gradient(
122
- to bottom,
123
- #e0e0e0,
124
- #c4c4c4
125
- ); /* Matte, deaktivierte Optik */
126
- color: var(--pd-default-disabled-dark-col);
127
- --pd-icon-col: var(--pd-default-disabled-dark-col);
128
- --pd-icon-col-active: var(--pd-default-disabled-dark-col);
129
- border-color: var(--pd-default-disabled-col);
130
- cursor: not-allowed;
131
- opacity: 0.6; /* Leichter "inaktiv"-Effekt */
132
- text-shadow: none;
133
- }
134
-
135
- :host(:not([disabled]):not([_timerDisabled])[primary])
136
- .icon-button-style {
137
- background-color: var(
138
- --pd-icon-button-primary-bgcol,
139
- var(--pd-secondary-col)
140
- );
141
- color: var(--pd-icon-button-primary-txtcol, var(--pd-default-dark-col));
142
- --pd-icon-col: var(
143
- --pd-icon-button-primary-txtcol,
144
- var(--pd-default-dark-col)
145
- );
146
- --pd-icon-col-active: var(
147
- --pd-icon-button-primary-txtcol,
148
- var(--pd-default-dark-col)
149
- );
150
- }
151
-
152
- :host(:not([disabled]):not([_timerDisabled])[primary])
153
- .icon-button-style:hover {
154
- background-color: var(--pd-default-hover-col);
155
- cursor: pointer;
46
+ /* Icon-only panel button: reduce padding since we have icon + toggle arrow */
47
+ :host([icon-only]) button {
48
+ padding: calc(0.5rem * var(--pd-button-scale, 1));
49
+ aspect-ratio: auto;
50
+ min-width: auto;
156
51
  }
157
52
 
53
+ /* Panel container */
158
54
  .panel {
159
55
  position: absolute;
160
-
161
- min-width: var(
162
- --pd-icon-button-panel-min-width,
163
- auto
164
- ); /* Panel wird so breit wie der Button */
165
- max-width: var(
166
- --pd-icon-button-panel-max-width,
167
- 300px
168
- ); /* Optional: Maximale Breite */
169
-
56
+ min-width: var(--pd-panel-min-width, auto);
57
+ max-width: var(--pd-panel-max-width, 300px);
170
58
  transform: scaleY(0);
171
- background: var(
172
- --pd-icon-button-panel-bg-col,
173
- var(--pd-default-bg-col)
174
- );
175
- border-radius: 5px;
176
- box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
59
+ background: var(--pd-panel-bg-col, var(--pd-default-bg-col));
60
+ border-radius: var(--pd-radius-lg);
61
+ box-shadow: var(--pd-shadow-md);
177
62
  transition:
178
63
  transform 0.2s ease-out,
179
64
  opacity 0.2s ease-out;
180
65
  opacity: 0;
181
- z-index: 5;
66
+ z-index: var(--pd-panel-z-index, 100);
182
67
  }
183
68
 
184
69
  .panel.open {
@@ -187,10 +72,11 @@ class PdPanelButton extends PdBaseUI {
187
72
  }
188
73
 
189
74
  .panel-content {
190
- padding: var(--pd-panel-button-panel-padding, 1rem);
75
+ padding: var(--pd-panel-padding, 1rem);
191
76
  min-height: 50px;
192
77
  }
193
78
 
79
+ /* Close button in panel */
194
80
  .close-button {
195
81
  position: absolute;
196
82
  top: 5px;
@@ -205,103 +91,107 @@ class PdPanelButton extends PdBaseUI {
205
91
  transition: color 0.2s ease-in-out;
206
92
  }
207
93
 
208
- .close-button:hover {
209
- color: var(--pd-default-darkest-col);
94
+ button.close-button:hover:not(:disabled) {
95
+ background: transparent;
96
+ color: var(--pd-default-hover-col);
210
97
  }
211
98
 
212
- /* Standard (nach unten öffnend, linksbündig) */
99
+ /* Panel positioning variants */
100
+
101
+ /* Default: opens downward, left-aligned */
213
102
  :host(:not([right]):not([up])) .panel {
214
- left: 0; /* Panel beginnt exakt unter dem Button */
215
- top: 100%; /* Panel öffnet sich nach unten */
216
- transform-origin: top; /* Wächst nach unten */
103
+ left: 0;
104
+ top: 100%;
105
+ transform-origin: top;
217
106
  }
218
107
 
219
- /* Standard (nach unten öffnend, rechtsbündig) */
108
+ /* Right-aligned, opens downward */
220
109
  :host([right]:not([up])) .panel {
221
- right: 0; /* Panel beginnt rechtsbündig am Button */
110
+ right: 0;
222
111
  top: 100%;
223
112
  transform-origin: top right;
224
113
  }
225
114
 
226
- /* Panel öffnet sich nach OBEN (links ausgerichtet) */
115
+ /* Left-aligned, opens upward */
227
116
  :host(:not([right])[up]) .panel {
228
117
  left: 0;
229
- bottom: 100%; /* Panel öffnet sich nach oben */
118
+ bottom: 100%;
230
119
  transform-origin: bottom;
231
120
  }
232
121
 
233
- /* Panel öffnet sich nach OBEN (rechts ausgerichtet) */
122
+ /* Right-aligned, opens upward */
234
123
  :host([right][up]) .panel {
235
124
  right: 0;
236
- bottom: 100%; /* Panel öffnet sich nach oben */
125
+ bottom: 100%;
237
126
  transform-origin: bottom right;
238
127
  }
239
-
240
- :host([selected]:not([disabled]):not([_timerDisabled]))
241
- .icon-button-style {
242
- background-color: var(
243
- --pd-icon-button-selected-bgcol,
244
- var(--pd-secondary-light-col)
245
- );
246
- color: var(--pd-icon-button-selected-txtcol, var(--pd-default-col));
247
- --pd-icon-col: var(
248
- --pd-icon-button-selected-txtcol,
249
- var(--pd-default-col)
250
- );
251
- box-shadow: var(
252
- --pd-icon-button-selected-shadow,
253
- inset 0 2px 6px rgba(0, 0, 0, 0.4),
254
- 0 0 0 2px rgba(0, 0, 0, 0.1)
255
- );
256
- text-shadow: none;
257
- }
258
-
259
- @keyframes spin {
260
- 0% {
261
- transform: rotate(0deg);
262
- }
263
- 100% {
264
- transform: rotate(360deg);
265
- }
266
- }
267
128
  `
268
129
  ];
269
130
  }
131
+ // ============================================================================
132
+ // LIFECYCLE
133
+ // ============================================================================
270
134
  connectedCallback() {
271
135
  super.connectedCallback();
272
- window.addEventListener("close-button-panel-event", this._closePanel);
136
+ window.addEventListener("close-button-panel-event", this._boundClosePanel);
137
+ window.addEventListener("keydown", this._boundHandleKeyDown);
273
138
  }
274
139
  disconnectedCallback() {
275
- window.removeEventListener("close-button-panel-event", this._closePanel);
140
+ window.removeEventListener(
141
+ "close-button-panel-event",
142
+ this._boundClosePanel
143
+ );
144
+ window.removeEventListener("keydown", this._boundHandleKeyDown);
276
145
  super.disconnectedCallback();
277
146
  }
278
- // ${this._daySyncDisabled ? "element-hint" : ""} => for div class
279
- render() {
147
+ // ============================================================================
148
+ // ARIA ATTRIBUTE OVERRIDES
149
+ // ============================================================================
150
+ get buttonAriaExpanded() {
151
+ return this._panelOpen ? "true" : "false";
152
+ }
153
+ get buttonAriaHasPopup() {
154
+ return "true";
155
+ }
156
+ get buttonAriaControls() {
157
+ return this._panelId;
158
+ }
159
+ // ============================================================================
160
+ // RENDER OVERRIDES
161
+ // ============================================================================
162
+ /**
163
+ * Renders the toggle arrow inside the button (as suffix content).
164
+ * Uses activeIcon to switch between up/down arrow states.
165
+ * activeIcon=true shows arrow up (panel open), activeIcon=false shows arrow down (panel closed).
166
+ */
167
+ renderSuffixContent() {
168
+ return html`
169
+ <pd-icon
170
+ icon="${pdIcons.ICON_TOOGLE_ARROW}"
171
+ ?activeIcon="${!this._panelOpen}"
172
+ class="button-icon toggle-icon"
173
+ ></pd-icon>
174
+ `;
175
+ }
176
+ /**
177
+ * Renders the dropdown panel after the button.
178
+ */
179
+ renderAfterButton() {
280
180
  return html`
281
181
  <div
282
- class="icon-button-style"
283
- role="button"
284
- tabindex="0"
285
- @click="${this._buttonClicked}"
286
- @keydown="${this._onKeyDown}"
182
+ id="${this._panelId}"
183
+ class="panel ${this._panelOpen ? "open" : ""}"
184
+ role="menu"
185
+ aria-hidden="${!this._panelOpen}"
186
+ ?inert="${!this._panelOpen}"
287
187
  >
288
- ${this.loading ? html`<div class="loader"></div>` : this.pdButtonIcon ? html`
289
- <pd-icon
290
- class="button-icon action-icon-color"
291
- icon="${this.pdButtonIcon}"
292
- ></pd-icon>
293
- ` : ""}
294
- ${this.buttonText ? html`<span class="button-text">${this.buttonText}</span>` : ""}
295
- ${this.panelButton ? html` <pd-icon
296
- icon=${pdIcons.ICON_TOOGLE_ARROW}
297
- ?activeIcon=${!this._panelOpen}
298
- class="small toggle-button"
299
- ></pd-icon>` : ""}
300
- </div>
301
-
302
- <div class="panel ${this._panelOpen ? "open" : ""}">
303
- ${this.hideClose ? "" : html`
304
- <button class="close-button" @click="${this._togglePanel}">
188
+ ${this.hideClose ? nothing : html`
189
+ <button
190
+ class="close-button"
191
+ @click="${this._togglePanel}"
192
+ @keydown="${this._handleCloseButtonKeyDown}"
193
+ aria-label="Close panel"
194
+ >
305
195
  &times;
306
196
  </button>
307
197
  `}
@@ -311,72 +201,69 @@ class PdPanelButton extends PdBaseUI {
311
201
  </div>
312
202
  `;
313
203
  }
314
- _onKeyDown(event) {
315
- if (event.key === "Enter" || event.key === " ") {
316
- event.preventDefault();
317
- this._buttonClicked();
318
- }
319
- }
320
- _buttonClicked() {
321
- if (this.panelButton) {
204
+ // ============================================================================
205
+ // EVENT HANDLERS (Override)
206
+ // ============================================================================
207
+ /**
208
+ * Override: Click toggles the panel instead of emitting button-clicked.
209
+ */
210
+ handleClick() {
211
+ if (!this.disabled && !this.loading) {
322
212
  this._togglePanel();
323
- } else {
324
- if (this.disableOnClickTime > 0) {
325
- this._timerDisabled = true;
326
- window.setTimeout(() => {
327
- this._timerDisabled = false;
328
- }, this.disableOnClickTime);
329
- }
330
- this.dispatchEvent(
331
- new CustomEvent("button-clicked", {
332
- detail: this.value,
333
- bubbles: true,
334
- composed: true
335
- })
336
- );
337
213
  }
338
214
  }
215
+ // ============================================================================
216
+ // PUBLIC METHODS
217
+ // ============================================================================
218
+ /** Focuses the internal button element. */
219
+ focus() {
220
+ this._buttonEl?.focus();
221
+ }
222
+ // ============================================================================
223
+ // PRIVATE METHODS
224
+ // ============================================================================
225
+ _closePanel() {
226
+ this._panelOpen = false;
227
+ }
339
228
  _togglePanel() {
340
229
  this._panelOpen = !this._panelOpen;
341
230
  this.dispatchEvent(
342
231
  new CustomEvent("panel-button-toggled", {
343
- detail: { open: this._panelOpen }
232
+ detail: { open: this._panelOpen },
233
+ bubbles: true,
234
+ composed: true
344
235
  })
345
236
  );
346
237
  }
238
+ /** Handles Escape key to close the panel */
239
+ _handlePanelKeyDown(e) {
240
+ if (e.key === "Escape" && this._panelOpen) {
241
+ this._closePanel();
242
+ this._buttonEl?.focus();
243
+ }
244
+ }
245
+ /** Handles keyboard events on the close button */
246
+ _handleCloseButtonKeyDown(e) {
247
+ if (e.key === "Enter" || e.key === " ") {
248
+ e.preventDefault();
249
+ this._togglePanel();
250
+ }
251
+ }
347
252
  }
348
253
  __decorateClass([
349
- property({ type: String })
350
- ], PdPanelButton.prototype, "pdButtonIcon");
351
- __decorateClass([
352
- property({ type: String })
353
- ], PdPanelButton.prototype, "buttonText");
354
- __decorateClass([
355
- property({ type: String })
356
- ], PdPanelButton.prototype, "value");
357
- __decorateClass([
358
- property({ type: Boolean })
359
- ], PdPanelButton.prototype, "panelButton");
360
- __decorateClass([
361
- property({ type: Boolean, reflect: true })
362
- ], PdPanelButton.prototype, "loading");
363
- __decorateClass([
364
- property({ type: Boolean, reflect: true })
365
- ], PdPanelButton.prototype, "selected");
254
+ property({ type: Boolean, attribute: "hide-close" })
255
+ ], PdPanelButton.prototype, "hideClose");
366
256
  __decorateClass([
367
257
  property({ type: Boolean, reflect: true })
368
- ], PdPanelButton.prototype, "primary");
369
- __decorateClass([
370
- property({ type: Number })
371
- ], PdPanelButton.prototype, "disableOnClickTime");
372
- __decorateClass([
373
- property({ type: Boolean })
374
- ], PdPanelButton.prototype, "hideClose");
258
+ ], PdPanelButton.prototype, "up");
375
259
  __decorateClass([
376
260
  property({ type: Boolean, reflect: true })
377
- ], PdPanelButton.prototype, "_timerDisabled");
261
+ ], PdPanelButton.prototype, "right");
378
262
  __decorateClass([
379
263
  state()
380
264
  ], PdPanelButton.prototype, "_panelOpen");
265
+ __decorateClass([
266
+ query("button")
267
+ ], PdPanelButton.prototype, "_buttonEl");
381
268
 
382
269
  export { PdPanelButton };
@@ -1,27 +1,57 @@
1
- import { StoryObj } from '@storybook/web-components';
2
- declare const meta: {
3
- title: string;
4
- component: string;
5
- render: (args: import('@storybook/web-components').Args) => import('lit').TemplateResult<1>;
6
- tags: string[];
7
- };
1
+ import { Meta, StoryObj } from '@storybook/web-components-vite';
2
+ interface PdPanelButtonArgs {
3
+ text: string;
4
+ icon: string;
5
+ primary: boolean;
6
+ disabled: boolean;
7
+ loading: boolean;
8
+ selected: boolean;
9
+ right: boolean;
10
+ up: boolean;
11
+ hideClose: boolean;
12
+ fullWidth: boolean;
13
+ iconPosition: string;
14
+ value: string;
15
+ size: "sm" | "md" | "lg" | "xl";
16
+ }
17
+ /**
18
+ * ## pd-panel-button
19
+ *
20
+ * A button with dropdown panel functionality. Extends pd-button with panel support.
21
+ *
22
+ * ### Features
23
+ * - Inherits all pd-button features (icons, states, sizing)
24
+ * - Dropdown panel with configurable position (up/down, left/right)
25
+ * - Toggle arrow indicator
26
+ * - Auto-close via global event
27
+ * - Keyboard accessible (Enter/Space/Escape)
28
+ *
29
+ * ### Accessibility
30
+ * - Inherits all pd-button accessibility features
31
+ * - Panel can be closed via close button, Escape key, or global event
32
+ *
33
+ * ### Usage
34
+ * ```html
35
+ * <pd-panel-button text="Options" icon="settings">
36
+ * <div>Panel content here</div>
37
+ * </pd-panel-button>
38
+ * ```
39
+ */
40
+ declare const meta: Meta<PdPanelButtonArgs>;
8
41
  export default meta;
9
- type Story = StoryObj;
10
- export declare const DefaultButton: Story;
11
- export declare const DefaulIcontButton: Story;
12
- export declare const DefaulIcontButtonDisabled: Story;
13
- export declare const DefaulIcontButtonTimerDisabled: Story;
14
- export declare const DefaulIcontButtonLoading: Story;
15
- export declare const DefaulIcontButtonPrimary: Story;
16
- export declare const DefaulIcontButtonPrimaryWithPanel: Story;
17
- export declare const DefaulIcontButtonPrimaryDisabled: Story;
18
- export declare const DefaulTextIcontButton: Story;
19
- export declare const PanelButton: Story;
20
- export declare const PanelButtonWithContent: Story;
21
- export declare const PanelButtonWithContentRight: Story;
22
- export declare const PanelButtonWithContentUp: Story;
23
- export declare const PanelButtonWithContentRightUp: Story;
24
- export declare const ButtonSelected: Story;
25
- export declare const ButtonSelectedWithIcon: Story;
26
- export declare const ButtonTransparent: Story;
42
+ type Story = StoryObj<PdPanelButtonArgs>;
43
+ /** Default panel button with text. Interactive via Controls panel. */
44
+ export declare const Default: Story;
45
+ /** All panel button variants and states at a glance. */
46
+ export declare const AllVariants: Story;
47
+ /** All size variants displayed together. */
48
+ export declare const AllSizes: Story;
49
+ /** Panel positioning options: right-aligned and upward. */
50
+ export declare const PanelPositions: Story;
51
+ /** Panel with hidden close button. */
52
+ export declare const HiddenCloseButton: Story;
53
+ /** Panel with rich slotted content. */
54
+ export declare const RichContent: Story;
55
+ /** CSS Custom Properties -- Branded and Redesigned variants. */
56
+ export declare const CustomStyling: Story;
27
57
  //# sourceMappingURL=pd-panel-button.stories.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pd-panel-button.stories.d.ts","sourceRoot":"","sources":["../../src/pd-panel-button/pd-panel-button.stories.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAEhE,OAAO,sBAAsB,CAAC;AAI9B,QAAA,MAAM,IAAI;;;;;CAoBM,CAAC;AAEjB,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC;AAGtB,eAAO,MAAM,aAAa,EAAE,KAK3B,CAAC;AAGF,eAAO,MAAM,iBAAiB,EAAE,KAO/B,CAAC;AAEF,eAAO,MAAM,yBAAyB,EAAE,KAQvC,CAAC;AAEF,eAAO,MAAM,8BAA8B,EAAE,KAQ5C,CAAC;AAEF,eAAO,MAAM,wBAAwB,EAAE,KAQtC,CAAC;AAEF,eAAO,MAAM,wBAAwB,EAAE,KAQtC,CAAC;AAEF,eAAO,MAAM,iCAAiC,EAAE,KAQ/C,CAAC;AAEF,eAAO,MAAM,gCAAgC,EAAE,KAS9C,CAAC;AAGF,eAAO,MAAM,qBAAqB,EAAE,KAMnC,CAAC;AAGF,eAAO,MAAM,WAAW,EAAE,KAOzB,CAAC;AAGF,eAAO,MAAM,sBAAsB,EAAE,KAgBpC,CAAC;AAGF,eAAO,MAAM,2BAA2B,EAAE,KAiBzC,CAAC;AAGF,eAAO,MAAM,wBAAwB,EAAE,KAiBtC,CAAC;AAGF,eAAO,MAAM,6BAA6B,EAAE,KAkB3C,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,KAuB5B,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,KAwBpC,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,KAgH/B,CAAC"}
1
+ {"version":3,"file":"pd-panel-button.stories.d.ts","sourceRoot":"","sources":["../../src/pd-panel-button/pd-panel-button.stories.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAKrE,OAAO,sBAAsB,CAAC;AAM9B,UAAU,iBAAiB;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;IACf,EAAE,EAAE,OAAO,CAAC;IACZ,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;CACjC;AAMD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,iBAAiB,CAyGjC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,iBAAiB,CAAC,CAAC;AAMzC,sEAAsE;AACtE,eAAO,MAAM,OAAO,EAAE,KAIrB,CAAC;AAMF,wDAAwD;AACxD,eAAO,MAAM,WAAW,EAAE,KAuEzB,CAAC;AAMF,4CAA4C;AAC5C,eAAO,MAAM,QAAQ,EAAE,KAqDtB,CAAC;AAMF,2DAA2D;AAC3D,eAAO,MAAM,cAAc,EAAE,KAgD5B,CAAC;AAMF,sCAAsC;AACtC,eAAO,MAAM,iBAAiB,EAAE,KA2B/B,CAAC;AAMF,uCAAuC;AACvC,eAAO,MAAM,WAAW,EAAE,KA4BzB,CAAC;AAMF,gEAAgE;AAChE,eAAO,MAAM,aAAa,EAAE,KAuF3B,CAAC"}
@@ -1,12 +1,26 @@
1
1
  import { CSSResultGroup } from 'lit';
2
2
  import { PdBaseUIInput } from '../base/pd-base-ui-input.js';
3
3
  /**
4
+ * Radio group container for pd-checkbox elements with radio behavior.
5
+ *
4
6
  * @tagname pd-radio-group
7
+ *
8
+ * @event validate-form - Fired when selection changes for validation.
9
+ * @event field-change - Fired when selection changes.
10
+ *
11
+ * @slot - pd-checkbox elements to display as radio options.
12
+ *
13
+ * @cssprop --pd-cb-group-gap - Gap between radio options. Default: `20px`.
14
+ * @cssprop --pd-cb-group-direction - Flex direction for layout. Default: `row`.
15
+ * @cssprop --pd-input-label-padding - Label padding. Default: `0`.
16
+ * @cssprop --pd-cb-border-col - Border color for child checkboxes in readonly state. Default: `var(--pd-default-col)`.
17
+ * @cssprop --pd-cb-border-col-readonly - Readonly border color forwarded to child checkboxes. Default: `var(--pd-cb-border-col, var(--pd-default-col))`.
5
18
  */
6
19
  export declare class PdRadioGroup extends PdBaseUIInput {
7
20
  static styles: CSSResultGroup;
8
21
  firstUpdated(): void;
9
22
  render(): import('lit').TemplateResult<1>;
23
+ private _onKeyDown;
10
24
  private _onInternalBlur;
11
25
  private _onInternalFocus;
12
26
  private _onInternalChange;
@@ -1 +1 @@
1
- {"version":3,"file":"PdRadioGroup.d.ts","sourceRoot":"","sources":["../../src/pd-radio-group/PdRadioGroup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAa,cAAc,EAAE,MAAM,KAAK,CAAC;AAGhD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAE5D;;GAEG;AACH,qBAAa,YAAa,SAAQ,aAAa;IAC7C,OAAgB,MAAM,EAAE,cAAc,CAmBpC;IAEO,YAAY,IAAI,IAAI;IAyBpB,MAAM;IAmBf,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,gBAAgB;IAIxB,OAAO,CAAC,iBAAiB;IAqBzB,OAAO,CAAC,mBAAmB;IAS3B,OAAO,CAAC,qBAAqB;CAmB9B"}
1
+ {"version":3,"file":"PdRadioGroup.d.ts","sourceRoot":"","sources":["../../src/pd-radio-group/PdRadioGroup.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAa,cAAc,EAAE,MAAM,KAAK,CAAC;AAGhD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAE5D;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,YAAa,SAAQ,aAAa;IAC7C,OAAgB,MAAM,EAAE,cAAc,CAmBpC;IAEO,YAAY,IAAI,IAAI;IAyBpB,MAAM;IAwBf,OAAO,CAAC,UAAU;IAkDlB,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,gBAAgB;IAIxB,OAAO,CAAC,iBAAiB;IAqBzB,OAAO,CAAC,mBAAmB;IAS3B,OAAO,CAAC,qBAAqB;CAmB9B"}