@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
@@ -0,0 +1,334 @@
1
+ import { LitElement, html } from 'lit';
2
+ import { property, state } from 'lit/decorators.js';
3
+ import { ifDefined } from 'lit/directives/if-defined.js';
4
+ import { msg } from '@lit/localize';
5
+ import { pdSchema } from '@progressive-development/pd-model';
6
+ import '../pd-form-row.js';
7
+ import '../pd-form-fieldset/pd-form-fieldset.js';
8
+ import '../pd-input.js';
9
+ import '../pd-input-area.js';
10
+ import '../pd-radio-group.js';
11
+ import '../pd-checkbox.js';
12
+ import '../pd-select.js';
13
+ import { pdGenericFormStyles } from './pd-generic-form.styles.js';
14
+
15
+ var __defProp = Object.defineProperty;
16
+ var __decorateClass = (decorators, target, key, kind) => {
17
+ var result = void 0 ;
18
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
19
+ if (decorator = decorators[i])
20
+ result = (decorator(target, key, result) ) || result;
21
+ if (result) __defProp(target, key, result);
22
+ return result;
23
+ };
24
+ const _PdGenericForm = class _PdGenericForm extends LitElement {
25
+ constructor() {
26
+ super(...arguments);
27
+ this.schema = [];
28
+ this.data = {};
29
+ this.mode = "view";
30
+ this.disabled = false;
31
+ this._formValues = {};
32
+ this._onFieldChange = (e) => {
33
+ const name = e.detail?.name;
34
+ if (name) {
35
+ this._formValues = { ...this._formValues, [name]: e.detail.value };
36
+ }
37
+ };
38
+ }
39
+ static {
40
+ this.styles = [pdGenericFormStyles];
41
+ }
42
+ connectedCallback() {
43
+ super.connectedCallback();
44
+ this.addEventListener(
45
+ "pd-form-element-change",
46
+ this._onFieldChange
47
+ );
48
+ }
49
+ disconnectedCallback() {
50
+ this.removeEventListener(
51
+ "pd-form-element-change",
52
+ this._onFieldChange
53
+ );
54
+ super.disconnectedCallback();
55
+ }
56
+ _isVisible(showWhen) {
57
+ if (!showWhen) return true;
58
+ const currentValue = this._formValues[showWhen.fieldId];
59
+ if (currentValue !== void 0) {
60
+ return currentValue === showWhen.equals;
61
+ }
62
+ const fieldValue = this.data[showWhen.fieldId];
63
+ if (!fieldValue) return false;
64
+ return fieldValue.value === showWhen.equals;
65
+ }
66
+ /**
67
+ * Extracts schema fields from raw form values
68
+ * and converts them into typed SchemaFieldData.
69
+ *
70
+ * @param formValues - Raw values from pd-form-container.getValues().origin
71
+ */
72
+ extractFormData(formValues) {
73
+ const result = {};
74
+ for (const entry of this.schema) {
75
+ if (pdSchema.isRow(entry)) {
76
+ for (const field of entry.fields) {
77
+ this._extractField(field, formValues, result);
78
+ }
79
+ } else if (pdSchema.isFieldset(entry)) {
80
+ const nested = formValues[entry.name] ?? {};
81
+ for (const row of entry.rows) {
82
+ for (const field of row) {
83
+ this._extractField(field, nested, result);
84
+ }
85
+ }
86
+ } else {
87
+ this._extractField(entry, formValues, result);
88
+ }
89
+ }
90
+ return result;
91
+ }
92
+ _extractField(field, source, result) {
93
+ if (!(field.fieldId in source)) return;
94
+ const formValue = source[field.fieldId];
95
+ let value;
96
+ if (field.type === "boolean") {
97
+ value = formValue === "yes";
98
+ } else if (field.type === "number") {
99
+ value = parseFloat(String(formValue)) || 0;
100
+ } else {
101
+ value = formValue || "";
102
+ }
103
+ result[field.fieldId] = pdSchema.createSchemaFieldValue(value, field.type);
104
+ }
105
+ render() {
106
+ return this.mode === "edit" ? this._renderEdit() : this._renderView();
107
+ }
108
+ // ── View Mode ──────────────────────────────────────────────────────────
109
+ _renderView() {
110
+ if (!this.schema.length) return html``;
111
+ const hasData = this.data && Object.keys(this.data).length > 0;
112
+ if (!hasData)
113
+ return html`<p class="empty-state">
114
+ ${msg("Keine Daten vorhanden", { id: "pd.generic-form.no-data" })}
115
+ </p>`;
116
+ return html`
117
+ <div class="view-list">
118
+ ${this.schema.map((e) => {
119
+ if (pdSchema.isRow(e)) {
120
+ if (!this._isVisible(e.showWhen)) return html``;
121
+ return html`${e.fields.map((f) => this._renderViewField(f))}`;
122
+ }
123
+ if (pdSchema.isFieldset(e)) {
124
+ if (!this._isVisible(e.showWhen)) return html``;
125
+ return html` ${e.legend ? html`<div class="view-fieldset-legend">${e.legend}</div>` : ""}
126
+ ${e.rows.flat().map((f) => this._renderViewField(f))}`;
127
+ }
128
+ if (!this._isVisible(e.showWhen)) return html``;
129
+ return this._renderViewField(e);
130
+ })}
131
+ </div>
132
+ `;
133
+ }
134
+ _renderViewField(field) {
135
+ const fieldValue = this.data[field.fieldId];
136
+ const displayValue = this._formatForView(field, fieldValue);
137
+ return html`
138
+ <div class="view-item">
139
+ <div class="view-label">${field.label}</div>
140
+ <div class="view-value">${displayValue}</div>
141
+ </div>
142
+ `;
143
+ }
144
+ _formatForView(field, fieldValue) {
145
+ if (field.type === "boolean") {
146
+ return pdSchema.formatSchemaFieldValue(fieldValue, {
147
+ boolTrue: msg("Ja", { id: "pd.generic-form.yes" }),
148
+ boolFalse: msg("Nein", { id: "pd.generic-form.no" })
149
+ });
150
+ }
151
+ const value = pdSchema.formatSchemaFieldValue(fieldValue);
152
+ switch (field.viewFormat) {
153
+ case "mailto":
154
+ return value !== "–" ? html`<a href="mailto:${value}">${value}</a>` : value;
155
+ case "tel":
156
+ return value !== "–" ? html`<a href="tel:${value}">${value}</a>` : value;
157
+ case "link":
158
+ return value !== "–" ? html`<a href="${value}" target="_blank" rel="noopener">${value}</a>` : value;
159
+ default:
160
+ return value;
161
+ }
162
+ }
163
+ // ── Edit Mode ──────────────────────────────────────────────────────────
164
+ _renderEdit() {
165
+ return html`${this.schema.map((e) => {
166
+ if (pdSchema.isRow(e)) {
167
+ return this._isVisible(e.showWhen) ? this._renderRow(e) : html``;
168
+ }
169
+ if (pdSchema.isFieldset(e)) {
170
+ return this._isVisible(e.showWhen) ? this._renderFieldset(e) : html``;
171
+ }
172
+ return this._isVisible(e.showWhen) ? this._renderFieldInRow(e) : html``;
173
+ })}`;
174
+ }
175
+ static {
176
+ /** InputType → pd-input fieldType mapping */
177
+ this._fieldTypeMap = {
178
+ number: "number",
179
+ email: "mail",
180
+ phone: "phone"
181
+ };
182
+ }
183
+ /** Single field wrapped in its own pd-form-row. */
184
+ _renderFieldInRow(field) {
185
+ return html`
186
+ <pd-form-row> ${this._renderFieldControl(field)} </pd-form-row>
187
+ `;
188
+ }
189
+ /** Multiple fields in a single pd-form-row. */
190
+ _renderRow(row) {
191
+ return html`
192
+ <pd-form-row>
193
+ ${row.fields.map((f) => this._renderFieldControl(f))}
194
+ </pd-form-row>
195
+ `;
196
+ }
197
+ /** Fieldset with nested pd-form-rows per row entry. */
198
+ _renderFieldset(fs) {
199
+ return html`
200
+ <pd-form-row>
201
+ <pd-form-fieldset
202
+ name="${fs.name}"
203
+ legend="${ifDefined(fs.legend)}"
204
+ span="${fs.span || "full"}"
205
+ >
206
+ ${fs.rows.map(
207
+ (row) => html`
208
+ <pd-form-row>
209
+ ${row.map((f) => this._renderFieldControl(f))}
210
+ </pd-form-row>
211
+ `
212
+ )}
213
+ </pd-form-fieldset>
214
+ </pd-form-row>
215
+ `;
216
+ }
217
+ /** Renders a field control (without pd-form-row wrapper), respecting field.span. */
218
+ _renderFieldControl(field) {
219
+ switch (field.inputType) {
220
+ case "radio-yes-no":
221
+ return this._renderBooleanControl(field);
222
+ case "textarea":
223
+ return this._renderTextareaControl(field);
224
+ case "text":
225
+ case "number":
226
+ case "email":
227
+ case "phone":
228
+ case "url":
229
+ return this._renderInputControl(field);
230
+ case "select":
231
+ return this._renderSelectControl(field);
232
+ default:
233
+ console.warn(
234
+ `pd-generic-form: Unsupported inputType "${field.inputType}"`
235
+ );
236
+ return html``;
237
+ }
238
+ }
239
+ _renderBooleanControl(field) {
240
+ const initValue = pdSchema.getSchemaFieldValue(this.data, field.fieldId) === true;
241
+ return html`
242
+ <pd-radio-group
243
+ id="${field.fieldId}"
244
+ valueName="${field.fieldId}"
245
+ label="${field.label}"
246
+ span="${field.span || "full"}"
247
+ ?required="${field.required}"
248
+ ?disabled="${this.disabled}"
249
+ ?handleChangeForInitVal="${true}"
250
+ initValue="${initValue ? "yes" : "no"}"
251
+ >
252
+ <pd-checkbox valueName="yes" initValue="${initValue.toString()}"
253
+ >${msg("Ja", { id: "pd.generic-form.yes" })}</pd-checkbox
254
+ >
255
+ <pd-checkbox valueName="no" initValue="${(!initValue).toString()}"
256
+ >${msg("Nein", { id: "pd.generic-form.no" })}</pd-checkbox
257
+ >
258
+ </pd-radio-group>
259
+ `;
260
+ }
261
+ _renderTextareaControl(field) {
262
+ const initValue = pdSchema.getSchemaFieldValue(this.data, field.fieldId) || "";
263
+ return html`
264
+ <pd-input-area
265
+ id="${field.fieldId}"
266
+ valueName="${field.fieldId}"
267
+ span="${field.span || "full"}"
268
+ minlength="${ifDefined(field.minlength)}"
269
+ maxlength="${ifDefined(field.maxlength)}"
270
+ label="${field.label}"
271
+ placeHolder="${field.placeholder || ""}"
272
+ ?required="${field.required}"
273
+ ?disabled="${this.disabled}"
274
+ ?handleChangeForInitVal="${true}"
275
+ initValue="${initValue}"
276
+ ></pd-input-area>
277
+ `;
278
+ }
279
+ _renderSelectControl(field) {
280
+ const initValue = pdSchema.getSchemaFieldValue(this.data, field.fieldId) || "";
281
+ return html`
282
+ <pd-select
283
+ id="${field.fieldId}"
284
+ valueName="${field.fieldId}"
285
+ span="${field.span || "full"}"
286
+ label="${field.label}"
287
+ .values="${field.options || []}"
288
+ ?required="${field.required}"
289
+ ?disabled="${this.disabled}"
290
+ ?handleChangeForInitVal="${true}"
291
+ initValue="${initValue}"
292
+ ></pd-select>
293
+ `;
294
+ }
295
+ _renderInputControl(field) {
296
+ const initValue = pdSchema.getSchemaFieldValue(this.data, field.fieldId)?.toString() || "";
297
+ const fieldType = _PdGenericForm._fieldTypeMap[field.inputType] || "text";
298
+ return html`
299
+ <pd-input
300
+ id="${field.fieldId}"
301
+ valueName="${field.fieldId}"
302
+ span="${field.span || "full"}"
303
+ minlength="${ifDefined(field.minlength)}"
304
+ maxlength="${ifDefined(field.maxlength)}"
305
+ label="${field.label}"
306
+ placeHolder="${field.placeholder || ""}"
307
+ fieldType="${fieldType}"
308
+ autoCompleteName="${ifDefined(field.autocomplete)}"
309
+ ?required="${field.required}"
310
+ ?disabled="${this.disabled}"
311
+ ?handleChangeForInitVal="${true}"
312
+ initValue="${initValue}"
313
+ ></pd-input>
314
+ `;
315
+ }
316
+ };
317
+ __decorateClass([
318
+ property({ type: Array })
319
+ ], _PdGenericForm.prototype, "schema");
320
+ __decorateClass([
321
+ property({ type: Object })
322
+ ], _PdGenericForm.prototype, "data");
323
+ __decorateClass([
324
+ property({ type: String, reflect: true })
325
+ ], _PdGenericForm.prototype, "mode");
326
+ __decorateClass([
327
+ property({ type: Boolean })
328
+ ], _PdGenericForm.prototype, "disabled");
329
+ __decorateClass([
330
+ state()
331
+ ], _PdGenericForm.prototype, "_formValues");
332
+ let PdGenericForm = _PdGenericForm;
333
+
334
+ export { PdGenericForm };
@@ -0,0 +1,3 @@
1
+ import { PdGenericForm } from './PdGenericForm.js';
2
+ export { PdGenericForm };
3
+ //# sourceMappingURL=pd-generic-form.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pd-generic-form.d.ts","sourceRoot":"","sources":["../../src/pd-generic-form/pd-generic-form.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAOnD,OAAO,EAAE,aAAa,EAAE,CAAC"}
@@ -0,0 +1,35 @@
1
+ import { Meta, StoryObj } from '@storybook/web-components-vite';
2
+ /**
3
+ * ## pd-generic-form
4
+ *
5
+ * Schema-driven form component that renders fields from a JSON schema definition.
6
+ *
7
+ * ### Features
8
+ * - View mode: renders label/value list
9
+ * - Edit mode: renders pd-forms components (inputs, selects, radio groups, textareas)
10
+ * - Layout support: rows, fieldsets, and per-field span control
11
+ * - Conditional visibility via `showWhen`
12
+ * - Can be combined with custom fields in the same pd-form-container
13
+ */
14
+ declare const meta: Meta;
15
+ export default meta;
16
+ type Story = StoryObj;
17
+ /** Default: View mode renders a label/value list from schema data. */
18
+ export declare const Default: Story;
19
+ /** View mode with no data shows an empty state message. */
20
+ export declare const ViewModeEmpty: Story;
21
+ /** Edit mode renders pd-forms components for each schema field. */
22
+ export declare const EditMode: Story;
23
+ /** Custom fields alongside schema-driven fields in the same form container. */
24
+ export declare const CombinedWithOwnFields: Story;
25
+ /**
26
+ * Schema with layout features: multi-field rows, fieldsets with legend
27
+ * and nested rows, and per-field span control.
28
+ */
29
+ export declare const RowsAndFieldsets: Story;
30
+ /**
31
+ * Conditional visibility with `showWhen`: fields, rows, and fieldsets
32
+ * appear or disappear based on another field's value.
33
+ */
34
+ export declare const ConditionalVisibility: Story;
35
+ //# sourceMappingURL=pd-generic-form.stories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pd-generic-form.stories.d.ts","sourceRoot":"","sources":["../../src/pd-generic-form/pd-generic-form.stories.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAKrE,OAAO,sBAAsB,CAAC;AAC9B,OAAO,2CAA2C,CAAC;AACnD,OAAO,+BAA+B,CAAC;AACvC,OAAO,mCAAmC,CAAC;AAC3C,OAAO,2BAA2B,CAAC;AA6SnC;;;;;;;;;;;GAWG;AACH,QAAA,MAAM,IAAI,EAAE,IAiEX,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC;AAMtB,sEAAsE;AACtE,eAAO,MAAM,OAAO,EAAE,KAQrB,CAAC;AAMF,2DAA2D;AAC3D,eAAO,MAAM,aAAa,EAAE,KAQ3B,CAAC;AAMF,mEAAmE;AACnE,eAAO,MAAM,QAAQ,EAAE,KAYtB,CAAC;AAMF,+EAA+E;AAC/E,eAAO,MAAM,qBAAqB,EAAE,KA+BnC,CAAC;AAMF;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,KA0B9B,CAAC;AAMF;;;GAGG;AACH,eAAO,MAAM,qBAAqB,EAAE,KA0BnC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const pdGenericFormStyles: import('lit').CSSResult;
2
+ //# sourceMappingURL=pd-generic-form.styles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pd-generic-form.styles.d.ts","sourceRoot":"","sources":["../../src/pd-generic-form/pd-generic-form.styles.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,mBAAmB,yBAyG/B,CAAC"}
@@ -0,0 +1,110 @@
1
+ import { css } from 'lit';
2
+
3
+ const pdGenericFormStyles = css`
4
+ :host {
5
+ display: block;
6
+ }
7
+
8
+ :host([mode="edit"]) {
9
+ display: flex;
10
+ flex-direction: column;
11
+ gap: var(--pd-form-container-row-gap, var(--pd-spacing-md));
12
+ }
13
+
14
+ /* View-Modus */
15
+ .view-list {
16
+ display: flex;
17
+ flex-direction: column;
18
+ gap: var(--pd-generic-form-view-gap, var(--pd-spacing-sm, 0.75rem));
19
+ }
20
+
21
+ .view-item {
22
+ display: flex;
23
+ align-items: center;
24
+ justify-content: space-between;
25
+ background: var(
26
+ --pd-generic-form-view-item-bg,
27
+ var(--pd-default-bg-light-col, #f8f9fc)
28
+ );
29
+ border-radius: var(
30
+ --pd-generic-form-view-item-radius,
31
+ var(--pd-radius-md, 0.5rem)
32
+ );
33
+ padding: var(--pd-generic-form-view-item-padding, 0.75rem 1rem);
34
+ box-shadow: var(
35
+ --pd-generic-form-view-item-shadow,
36
+ inset 0 0 0 1px var(--pd-default-disabled-light-col, #e0e0e0)
37
+ );
38
+ }
39
+
40
+ .view-label {
41
+ font-weight: var(--pd-generic-form-view-label-weight, 500);
42
+ font-size: var(
43
+ --pd-generic-form-view-label-size,
44
+ var(--pd-default-font-content-size, 0.95rem)
45
+ );
46
+ color: var(
47
+ --pd-generic-form-view-label-col,
48
+ var(--pd-default-font-content-col, #333)
49
+ );
50
+ font-family: var(--pd-default-font-content-family);
51
+ }
52
+
53
+ .view-value {
54
+ font-weight: var(--pd-generic-form-view-value-weight, 600);
55
+ color: var(
56
+ --pd-generic-form-view-value-col,
57
+ var(--pd-default-col, #067394)
58
+ );
59
+ font-family: var(--pd-default-font-content-family);
60
+ white-space: nowrap;
61
+ }
62
+
63
+ .view-value a {
64
+ color: var(
65
+ --pd-generic-form-view-link-col,
66
+ var(--pd-default-font-link-col, inherit)
67
+ );
68
+ text-decoration: none;
69
+ }
70
+
71
+ .view-value a:hover {
72
+ color: var(
73
+ --pd-generic-form-view-link-hover-col,
74
+ var(--pd-default-font-link-col-hover)
75
+ );
76
+ }
77
+
78
+ .view-fieldset-legend {
79
+ font-weight: var(--pd-generic-form-view-legend-weight, 600);
80
+ font-size: var(
81
+ --pd-generic-form-view-legend-size,
82
+ var(--pd-default-font-content-size, 0.95rem)
83
+ );
84
+ color: var(
85
+ --pd-generic-form-view-legend-col,
86
+ var(--pd-default-font-content-col, #333)
87
+ );
88
+ font-family: var(--pd-default-font-content-family);
89
+ padding: var(--pd-generic-form-view-legend-padding, 0.5rem 0 0.25rem);
90
+ }
91
+
92
+ .empty-state {
93
+ color: var(--pd-default-font-muted-col, #6b7280);
94
+ font-family: var(--pd-default-font-content-family);
95
+ }
96
+
97
+ @media (max-width: 600px) {
98
+ .view-item {
99
+ flex-direction: column;
100
+ align-items: flex-start;
101
+ }
102
+ .view-value {
103
+ margin-top: 0.25rem;
104
+ white-space: normal;
105
+ word-break: break-word;
106
+ }
107
+ }
108
+ `;
109
+
110
+ export { pdGenericFormStyles };
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=pd-generic-form.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pd-generic-form.test.d.ts","sourceRoot":"","sources":["../../src/pd-generic-form/pd-generic-form.test.ts"],"names":[],"mappings":"AAQA,OAAO,sBAAsB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from './pd-generic-form/pd-generic-form'
2
+ export {}
@@ -0,0 +1,8 @@
1
+ import { PdGenericForm } from './pd-generic-form/PdGenericForm.js';
2
+
3
+ const tag = "pd-generic-form";
4
+ if (!customElements.get(tag)) {
5
+ customElements.define(tag, PdGenericForm);
6
+ }
7
+
8
+ export { PdGenericForm };
@@ -1,31 +1,81 @@
1
1
  import { TemplateResult, CSSResultGroup } from 'lit';
2
2
  import { PdBaseUI } from '../base/pd-base-ui.js';
3
3
  /**
4
+ * Floating info box that appears on click.
5
+ *
4
6
  * @tagname pd-hover-box
5
- * A floating hover container for displaying slot-based info.
7
+ * @summary Click-to-show info tooltip with auto-positioning.
8
+ *
9
+ * @slot normal-view - Trigger element (e.g., icon).
10
+ * @slot info-view - Info content to display.
6
11
  *
7
- * @slot normal-view - Trigger (e.g. icon)
8
- * @slot info-view - Info content
9
- * @event toggle-info - Fired when info box is toggled
12
+ * @cssprop --pd-hover-box-bg-col - Info box background. Default: `var(--pd-default-dark-col)`.
13
+ * @cssprop --pd-hover-box-border-col - Info box border color. Default: `var(--pd-default-col)`.
14
+ * @cssprop --pd-hover-box-width - Info box width. Default: `240px`.
15
+ * @cssprop --pd-hover-box-font-col - Info box text color. Default: `var(--pd-default-bg-col)`.
16
+ * @cssprop --pd-hover-box-font-size - Info box font size. Default: `0.8em`.
10
17
  */
11
18
  export declare class PdHoverBox extends PdBaseUI {
12
19
  /**
13
- * Controls visibility of the info box
20
+ * Accessible label for the trigger element.
21
+ * Used as aria-label on the trigger button.
14
22
  */
23
+ triggerLabel: string;
24
+ /**
25
+ * Controls visibility of the info box
26
+ * @ignore */
15
27
  private _visible;
16
28
  /**
17
- * True if the info box should open downward
18
- */
19
- private _toBottom;
29
+ * Fixed position top value in pixels
30
+ * @ignore */
31
+ private _posTop;
32
+ /**
33
+ * Fixed position left value in pixels
34
+ * @ignore */
35
+ private _posLeft;
36
+ /** @ignore - Unique ID for aria-controls */
37
+ private _infoId;
38
+ /** @ignore - Bound method for click-outside listener */
39
+ private _boundHandleClickOutside;
40
+ /** @ignore - Bound method for keyboard listener */
41
+ private _boundHandleKeyDown;
42
+ /** @ignore - Bound method for scroll listener */
43
+ private _boundHandleScroll;
20
44
  static styles: CSSResultGroup;
21
45
  render(): TemplateResult;
22
46
  /**
23
- * Activates and positions the info box based on current viewport height.
47
+ * Calculates fixed position based on trigger location and available space.
48
+ * Uses viewport-relative coordinates for position: fixed.
24
49
  */
25
- private _activateInfo;
50
+ private _calculatePosition;
26
51
  /**
27
- * Hides the info box again
52
+ * Opens the info box and registers close listeners.
53
+ * Uses fixed positioning to escape overflow containers.
54
+ */
55
+ private _openInfo;
56
+ /**
57
+ * Closes the info box and removes close listeners.
28
58
  */
29
59
  private _closeInfo;
60
+ /**
61
+ * Toggles the info box visibility.
62
+ */
63
+ private _toggleInfo;
64
+ /**
65
+ * Handles keyboard events on the trigger.
66
+ */
67
+ private _onTriggerKeyDown;
68
+ /**
69
+ * Handles Escape key to close.
70
+ */
71
+ private _handleKeyDown;
72
+ /**
73
+ * Handles clicks outside to close.
74
+ */
75
+ private _handleClickOutside;
76
+ /**
77
+ * Handles scroll to close (fixed position doesn't follow scroll).
78
+ */
79
+ private _handleScroll;
30
80
  }
31
81
  //# sourceMappingURL=PdHoverBox.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"PdHoverBox.d.ts","sourceRoot":"","sources":["../../src/pd-hover-box/PdHoverBox.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AAEH,OAAO,EAAa,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AAG1E,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEjD;;;;;;;GAOG;AACH,qBAAa,UAAW,SAAQ,QAAQ;IACtC;;OAEG;IAEH,OAAO,CAAC,QAAQ,CAAS;IAEzB;;OAEG;IAEH,OAAO,CAAC,SAAS,CAAS;IAE1B,OAAgB,MAAM,EAAE,cAAc,CAqDpC;IAEO,MAAM,IAAI,cAAc;IAqBjC;;OAEG;IACH,OAAO,CAAC,aAAa;IAqBrB;;OAEG;IACH,OAAO,CAAC,UAAU;CAGnB"}
1
+ {"version":3,"file":"PdHoverBox.d.ts","sourceRoot":"","sources":["../../src/pd-hover-box/PdHoverBox.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAIL,KAAK,cAAc,EACnB,KAAK,cAAc,EACpB,MAAM,KAAK,CAAC;AAKb,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAIjD;;;;;;;;;;;;;;GAcG;AACH,qBAAa,UAAW,SAAQ,QAAQ;IACtC;;;OAGG;IAEH,YAAY,SAAe;IAE3B;;iBAEa;IAEb,OAAO,CAAC,QAAQ,CAAS;IAEzB;;iBAEa;IAEb,OAAO,CAAC,OAAO,CAAK;IAEpB;;iBAEa;IAEb,OAAO,CAAC,QAAQ,CAAK;IAErB,4CAA4C;IAC5C,OAAO,CAAC,OAAO,CAAyC;IAExD,wDAAwD;IACxD,OAAO,CAAC,wBAAwB,CAAuC;IAEvE,mDAAmD;IACnD,OAAO,CAAC,mBAAmB,CAAkC;IAE7D,iDAAiD;IACjD,OAAO,CAAC,kBAAkB,CAAiC;IAE3D,OAAgB,MAAM,EAAE,cAAc,CA6DpC;IAEO,MAAM,IAAI,cAAc;IA6BjC;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAiB1B;;;OAGG;IACH,OAAO,CAAC,SAAS;IASjB;;OAEG;IACH,OAAO,CAAC,UAAU;IAOlB;;OAEG;IACH,OAAO,CAAC,WAAW;IASnB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAOzB;;OAEG;IACH,OAAO,CAAC,cAAc;IAQtB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAO3B;;OAEG;IACH,OAAO,CAAC,aAAa;CAGtB"}