@deepfuture/dui-components 0.0.19 → 0.0.21

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 (52) hide show
  1. package/all.d.ts +6 -2
  2. package/all.js +12 -4
  3. package/card/card.d.ts +29 -0
  4. package/card/card.js +179 -0
  5. package/card/index.d.ts +3 -0
  6. package/card/index.js +3 -0
  7. package/checkbox/checkbox.d.ts +3 -2
  8. package/checkbox/checkbox.js +21 -46
  9. package/combobox/combobox.d.ts +3 -0
  10. package/combobox/combobox.js +21 -10
  11. package/data-table/data-table.js +4 -4
  12. package/dropzone/dropzone.js +1 -0
  13. package/field/field.d.ts +32 -0
  14. package/field/field.js +363 -0
  15. package/field/index.d.ts +1 -2
  16. package/field/index.js +1 -1
  17. package/fieldset/fieldset.d.ts +20 -0
  18. package/fieldset/fieldset.js +116 -0
  19. package/fieldset/index.d.ts +1 -0
  20. package/fieldset/index.js +1 -0
  21. package/global.d.ts +0 -2
  22. package/input/input.d.ts +4 -2
  23. package/input/input.js +27 -52
  24. package/menu/menu.d.ts +2 -0
  25. package/menu/menu.js +13 -3
  26. package/number-field/number-field.d.ts +2 -2
  27. package/number-field/number-field.js +13 -49
  28. package/package.json +10 -6
  29. package/preview-card/preview-card-popup.js +1 -0
  30. package/radio/radio.d.ts +3 -2
  31. package/radio/radio.js +22 -44
  32. package/scroll-area/scroll-area.d.ts +1 -1
  33. package/scroll-area/scroll-area.js +5 -16
  34. package/select/select.d.ts +5 -2
  35. package/select/select.js +38 -34
  36. package/separator/separator.js +1 -0
  37. package/slider/slider.d.ts +3 -0
  38. package/slider/slider.js +12 -5
  39. package/split-button/split-button.d.ts +2 -0
  40. package/split-button/split-button.js +11 -1
  41. package/stepper/stepper.d.ts +0 -2
  42. package/stepper/stepper.js +7 -38
  43. package/switch/switch.d.ts +3 -2
  44. package/switch/switch.js +16 -41
  45. package/textarea/textarea.d.ts +4 -0
  46. package/textarea/textarea.js +20 -0
  47. package/field/field-context.d.ts +0 -20
  48. package/field/field-context.js +0 -2
  49. package/link/index.d.ts +0 -3
  50. package/link/index.js +0 -3
  51. package/link/link.d.ts +0 -27
  52. package/link/link.js +0 -95
@@ -0,0 +1,32 @@
1
+ import { LitElement, type PropertyValues, type TemplateResult } from "lit";
2
+ /**
3
+ * `<dui-field>` — Slot-based form field wrapper.
4
+ *
5
+ * Provides label, description, and error slots around a default-slotted
6
+ * form control. Manages ARIA wiring, field state (dirty, touched, focused,
7
+ * filled), disabled propagation, and label click-to-focus.
8
+ *
9
+ * @slot label - Label text (e.g. `<span slot="label">Email</span>`).
10
+ * @slot - Default slot for the form control.
11
+ * @slot description - Help text (e.g. `<span slot="description">…</span>`).
12
+ * @slot error - Error message (e.g. `<span slot="error">Required</span>`).
13
+ * @csspart root - The field container element.
14
+ * @csspart label - The label wrapper.
15
+ * @csspart description - The description wrapper.
16
+ * @csspart error - The error wrapper (hidden unless invalid).
17
+ */
18
+ export declare class DuiField extends LitElement {
19
+ #private;
20
+ static tagName: "dui-field";
21
+ static styles: import("lit").CSSResult[];
22
+ /** Whether the child control is disabled. */
23
+ accessor disabled: boolean;
24
+ /** Whether the field is in an invalid state. */
25
+ accessor invalid: boolean;
26
+ /** Layout direction: vertical (column) or horizontal (row). */
27
+ accessor orientation: "vertical" | "horizontal";
28
+ connectedCallback(): void;
29
+ disconnectedCallback(): void;
30
+ willUpdate(changed: PropertyValues): void;
31
+ render(): TemplateResult;
32
+ }
package/field/field.js ADDED
@@ -0,0 +1,363 @@
1
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
2
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
3
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
4
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
5
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
6
+ var _, done = false;
7
+ for (var i = decorators.length - 1; i >= 0; i--) {
8
+ var context = {};
9
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
10
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
11
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
12
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
13
+ if (kind === "accessor") {
14
+ if (result === void 0) continue;
15
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
16
+ if (_ = accept(result.get)) descriptor.get = _;
17
+ if (_ = accept(result.set)) descriptor.set = _;
18
+ if (_ = accept(result.init)) initializers.unshift(_);
19
+ }
20
+ else if (_ = accept(result)) {
21
+ if (kind === "field") initializers.unshift(_);
22
+ else descriptor[key] = _;
23
+ }
24
+ }
25
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
26
+ done = true;
27
+ };
28
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
29
+ var useValue = arguments.length > 2;
30
+ for (var i = 0; i < initializers.length; i++) {
31
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
32
+ }
33
+ return useValue ? value : void 0;
34
+ };
35
+ var __setFunctionName = (this && this.__setFunctionName) || function (f, name, prefix) {
36
+ if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";
37
+ return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
38
+ };
39
+ import { css, html, LitElement } from "lit";
40
+ import { property, state } from "lit/decorators.js";
41
+ import { base } from "@deepfuture/dui-core/base";
42
+ /** Selector matching all DUI form controls that can be wired by a field. */
43
+ const CONTROL_SELECTOR = [
44
+ "dui-input",
45
+ "dui-textarea",
46
+ "dui-select",
47
+ "dui-checkbox",
48
+ "dui-checkbox-group",
49
+ "dui-radio",
50
+ "dui-radio-group",
51
+ "dui-switch",
52
+ "dui-number-field",
53
+ "dui-stepper",
54
+ "dui-slider",
55
+ "dui-combobox",
56
+ "dui-dropzone",
57
+ ].join(", ");
58
+ /** Structural styles only — layout CSS. */
59
+ const styles = css `
60
+ :host {
61
+ display: block;
62
+ }
63
+
64
+ [part="root"] {
65
+ display: flex;
66
+ flex-direction: column;
67
+ }
68
+
69
+ [part="root"][data-orientation="horizontal"] {
70
+ flex-direction: row;
71
+ align-items: start;
72
+ }
73
+
74
+ /* Hide wrapper parts when no content is slotted */
75
+ [part="label"]:not([data-slotted]) { display: none; }
76
+ [part="label"] { cursor: default; }
77
+ [part="label"][data-disabled] { cursor: not-allowed; }
78
+
79
+ [part="description"]:not([data-slotted]) { display: none; }
80
+
81
+ [part="error"] { display: none; }
82
+ [part="error"][data-invalid] { display: block; }
83
+ `;
84
+ /**
85
+ * `<dui-field>` — Slot-based form field wrapper.
86
+ *
87
+ * Provides label, description, and error slots around a default-slotted
88
+ * form control. Manages ARIA wiring, field state (dirty, touched, focused,
89
+ * filled), disabled propagation, and label click-to-focus.
90
+ *
91
+ * @slot label - Label text (e.g. `<span slot="label">Email</span>`).
92
+ * @slot - Default slot for the form control.
93
+ * @slot description - Help text (e.g. `<span slot="description">…</span>`).
94
+ * @slot error - Error message (e.g. `<span slot="error">Required</span>`).
95
+ * @csspart root - The field container element.
96
+ * @csspart label - The label wrapper.
97
+ * @csspart description - The description wrapper.
98
+ * @csspart error - The error wrapper (hidden unless invalid).
99
+ */
100
+ let DuiField = (() => {
101
+ let _classSuper = LitElement;
102
+ let _disabled_decorators;
103
+ let _disabled_initializers = [];
104
+ let _disabled_extraInitializers = [];
105
+ let _invalid_decorators;
106
+ let _invalid_initializers = [];
107
+ let _invalid_extraInitializers = [];
108
+ let _orientation_decorators;
109
+ let _orientation_initializers = [];
110
+ let _orientation_extraInitializers = [];
111
+ let _private_dirty_decorators;
112
+ let _private_dirty_initializers = [];
113
+ let _private_dirty_extraInitializers = [];
114
+ let _private_dirty_descriptor;
115
+ let _private_touched_decorators;
116
+ let _private_touched_initializers = [];
117
+ let _private_touched_extraInitializers = [];
118
+ let _private_touched_descriptor;
119
+ let _private_focused_decorators;
120
+ let _private_focused_initializers = [];
121
+ let _private_focused_extraInitializers = [];
122
+ let _private_focused_descriptor;
123
+ let _private_filled_decorators;
124
+ let _private_filled_initializers = [];
125
+ let _private_filled_extraInitializers = [];
126
+ let _private_filled_descriptor;
127
+ let _private_hasLabel_decorators;
128
+ let _private_hasLabel_initializers = [];
129
+ let _private_hasLabel_extraInitializers = [];
130
+ let _private_hasLabel_descriptor;
131
+ let _private_hasDescription_decorators;
132
+ let _private_hasDescription_initializers = [];
133
+ let _private_hasDescription_extraInitializers = [];
134
+ let _private_hasDescription_descriptor;
135
+ let _private_hasError_decorators;
136
+ let _private_hasError_initializers = [];
137
+ let _private_hasError_extraInitializers = [];
138
+ let _private_hasError_descriptor;
139
+ return class DuiField extends _classSuper {
140
+ static {
141
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
142
+ _disabled_decorators = [property({ type: Boolean, reflect: true })];
143
+ _invalid_decorators = [property({ type: Boolean, reflect: true })];
144
+ _orientation_decorators = [property()];
145
+ _private_dirty_decorators = [state()];
146
+ _private_touched_decorators = [state()];
147
+ _private_focused_decorators = [state()];
148
+ _private_filled_decorators = [state()];
149
+ _private_hasLabel_decorators = [state()];
150
+ _private_hasDescription_decorators = [state()];
151
+ _private_hasError_decorators = [state()];
152
+ __esDecorate(this, null, _disabled_decorators, { kind: "accessor", name: "disabled", static: false, private: false, access: { has: obj => "disabled" in obj, get: obj => obj.disabled, set: (obj, value) => { obj.disabled = value; } }, metadata: _metadata }, _disabled_initializers, _disabled_extraInitializers);
153
+ __esDecorate(this, null, _invalid_decorators, { kind: "accessor", name: "invalid", static: false, private: false, access: { has: obj => "invalid" in obj, get: obj => obj.invalid, set: (obj, value) => { obj.invalid = value; } }, metadata: _metadata }, _invalid_initializers, _invalid_extraInitializers);
154
+ __esDecorate(this, null, _orientation_decorators, { kind: "accessor", name: "orientation", static: false, private: false, access: { has: obj => "orientation" in obj, get: obj => obj.orientation, set: (obj, value) => { obj.orientation = value; } }, metadata: _metadata }, _orientation_initializers, _orientation_extraInitializers);
155
+ __esDecorate(this, _private_dirty_descriptor = { get: __setFunctionName(function () { return this.#dirty_accessor_storage; }, "#dirty", "get"), set: __setFunctionName(function (value) { this.#dirty_accessor_storage = value; }, "#dirty", "set") }, _private_dirty_decorators, { kind: "accessor", name: "#dirty", static: false, private: true, access: { has: obj => #dirty in obj, get: obj => obj.#dirty, set: (obj, value) => { obj.#dirty = value; } }, metadata: _metadata }, _private_dirty_initializers, _private_dirty_extraInitializers);
156
+ __esDecorate(this, _private_touched_descriptor = { get: __setFunctionName(function () { return this.#touched_accessor_storage; }, "#touched", "get"), set: __setFunctionName(function (value) { this.#touched_accessor_storage = value; }, "#touched", "set") }, _private_touched_decorators, { kind: "accessor", name: "#touched", static: false, private: true, access: { has: obj => #touched in obj, get: obj => obj.#touched, set: (obj, value) => { obj.#touched = value; } }, metadata: _metadata }, _private_touched_initializers, _private_touched_extraInitializers);
157
+ __esDecorate(this, _private_focused_descriptor = { get: __setFunctionName(function () { return this.#focused_accessor_storage; }, "#focused", "get"), set: __setFunctionName(function (value) { this.#focused_accessor_storage = value; }, "#focused", "set") }, _private_focused_decorators, { kind: "accessor", name: "#focused", static: false, private: true, access: { has: obj => #focused in obj, get: obj => obj.#focused, set: (obj, value) => { obj.#focused = value; } }, metadata: _metadata }, _private_focused_initializers, _private_focused_extraInitializers);
158
+ __esDecorate(this, _private_filled_descriptor = { get: __setFunctionName(function () { return this.#filled_accessor_storage; }, "#filled", "get"), set: __setFunctionName(function (value) { this.#filled_accessor_storage = value; }, "#filled", "set") }, _private_filled_decorators, { kind: "accessor", name: "#filled", static: false, private: true, access: { has: obj => #filled in obj, get: obj => obj.#filled, set: (obj, value) => { obj.#filled = value; } }, metadata: _metadata }, _private_filled_initializers, _private_filled_extraInitializers);
159
+ __esDecorate(this, _private_hasLabel_descriptor = { get: __setFunctionName(function () { return this.#hasLabel_accessor_storage; }, "#hasLabel", "get"), set: __setFunctionName(function (value) { this.#hasLabel_accessor_storage = value; }, "#hasLabel", "set") }, _private_hasLabel_decorators, { kind: "accessor", name: "#hasLabel", static: false, private: true, access: { has: obj => #hasLabel in obj, get: obj => obj.#hasLabel, set: (obj, value) => { obj.#hasLabel = value; } }, metadata: _metadata }, _private_hasLabel_initializers, _private_hasLabel_extraInitializers);
160
+ __esDecorate(this, _private_hasDescription_descriptor = { get: __setFunctionName(function () { return this.#hasDescription_accessor_storage; }, "#hasDescription", "get"), set: __setFunctionName(function (value) { this.#hasDescription_accessor_storage = value; }, "#hasDescription", "set") }, _private_hasDescription_decorators, { kind: "accessor", name: "#hasDescription", static: false, private: true, access: { has: obj => #hasDescription in obj, get: obj => obj.#hasDescription, set: (obj, value) => { obj.#hasDescription = value; } }, metadata: _metadata }, _private_hasDescription_initializers, _private_hasDescription_extraInitializers);
161
+ __esDecorate(this, _private_hasError_descriptor = { get: __setFunctionName(function () { return this.#hasError_accessor_storage; }, "#hasError", "get"), set: __setFunctionName(function (value) { this.#hasError_accessor_storage = value; }, "#hasError", "set") }, _private_hasError_decorators, { kind: "accessor", name: "#hasError", static: false, private: true, access: { has: obj => #hasError in obj, get: obj => obj.#hasError, set: (obj, value) => { obj.#hasError = value; } }, metadata: _metadata }, _private_hasError_initializers, _private_hasError_extraInitializers);
162
+ if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
163
+ }
164
+ static tagName = "dui-field";
165
+ static styles = [base, styles];
166
+ #disabled_accessor_storage = __runInitializers(this, _disabled_initializers, false);
167
+ /** Whether the child control is disabled. */
168
+ get disabled() { return this.#disabled_accessor_storage; }
169
+ set disabled(value) { this.#disabled_accessor_storage = value; }
170
+ #invalid_accessor_storage = (__runInitializers(this, _disabled_extraInitializers), __runInitializers(this, _invalid_initializers, false));
171
+ /** Whether the field is in an invalid state. */
172
+ get invalid() { return this.#invalid_accessor_storage; }
173
+ set invalid(value) { this.#invalid_accessor_storage = value; }
174
+ #orientation_accessor_storage = (__runInitializers(this, _invalid_extraInitializers), __runInitializers(this, _orientation_initializers, "vertical"));
175
+ /** Layout direction: vertical (column) or horizontal (row). */
176
+ get orientation() { return this.#orientation_accessor_storage; }
177
+ set orientation(value) { this.#orientation_accessor_storage = value; }
178
+ #dirty_accessor_storage = (__runInitializers(this, _orientation_extraInitializers), __runInitializers(this, _private_dirty_initializers, false));
179
+ // --- Internal state ---
180
+ get #dirty() { return _private_dirty_descriptor.get.call(this); }
181
+ set #dirty(value) { return _private_dirty_descriptor.set.call(this, value); }
182
+ #touched_accessor_storage = (__runInitializers(this, _private_dirty_extraInitializers), __runInitializers(this, _private_touched_initializers, false));
183
+ get #touched() { return _private_touched_descriptor.get.call(this); }
184
+ set #touched(value) { return _private_touched_descriptor.set.call(this, value); }
185
+ #focused_accessor_storage = (__runInitializers(this, _private_touched_extraInitializers), __runInitializers(this, _private_focused_initializers, false));
186
+ get #focused() { return _private_focused_descriptor.get.call(this); }
187
+ set #focused(value) { return _private_focused_descriptor.set.call(this, value); }
188
+ #filled_accessor_storage = (__runInitializers(this, _private_focused_extraInitializers), __runInitializers(this, _private_filled_initializers, false));
189
+ get #filled() { return _private_filled_descriptor.get.call(this); }
190
+ set #filled(value) { return _private_filled_descriptor.set.call(this, value); }
191
+ #hasLabel_accessor_storage = (__runInitializers(this, _private_filled_extraInitializers), __runInitializers(this, _private_hasLabel_initializers, false));
192
+ get #hasLabel() { return _private_hasLabel_descriptor.get.call(this); }
193
+ set #hasLabel(value) { return _private_hasLabel_descriptor.set.call(this, value); }
194
+ #hasDescription_accessor_storage = (__runInitializers(this, _private_hasLabel_extraInitializers), __runInitializers(this, _private_hasDescription_initializers, false));
195
+ get #hasDescription() { return _private_hasDescription_descriptor.get.call(this); }
196
+ set #hasDescription(value) { return _private_hasDescription_descriptor.set.call(this, value); }
197
+ #hasError_accessor_storage = (__runInitializers(this, _private_hasDescription_extraInitializers), __runInitializers(this, _private_hasError_initializers, false));
198
+ get #hasError() { return _private_hasError_descriptor.get.call(this); }
199
+ set #hasError(value) { return _private_hasError_descriptor.set.call(this, value); }
200
+ // --- Stable IDs ---
201
+ #fieldId = (__runInitializers(this, _private_hasError_extraInitializers), crypto.randomUUID().slice(0, 8));
202
+ get #labelId() {
203
+ return `field-${this.#fieldId}-label`;
204
+ }
205
+ get #descriptionId() {
206
+ return `field-${this.#fieldId}-desc`;
207
+ }
208
+ get #errorId() {
209
+ return `field-${this.#fieldId}-error`;
210
+ }
211
+ // --- Control reference ---
212
+ #control;
213
+ #controlWasDisabled = false;
214
+ // --- Lifecycle ---
215
+ connectedCallback() {
216
+ super.connectedCallback();
217
+ this.addEventListener("focusin", this.#onFocusIn);
218
+ this.addEventListener("focusout", this.#onFocusOut);
219
+ this.addEventListener("input", this.#onInput);
220
+ this.addEventListener("change", this.#onChange);
221
+ }
222
+ disconnectedCallback() {
223
+ super.disconnectedCallback();
224
+ this.removeEventListener("focusin", this.#onFocusIn);
225
+ this.removeEventListener("focusout", this.#onFocusOut);
226
+ this.removeEventListener("input", this.#onInput);
227
+ this.removeEventListener("change", this.#onChange);
228
+ }
229
+ willUpdate(changed) {
230
+ if (changed.has("invalid") && this.#control) {
231
+ this.#wireControl();
232
+ }
233
+ if (changed.has("disabled") && this.#control) {
234
+ if (this.disabled) {
235
+ this.#controlWasDisabled = this.#control.hasAttribute("disabled");
236
+ this.#control.setAttribute("disabled", "");
237
+ }
238
+ else if (!this.#controlWasDisabled) {
239
+ this.#control.removeAttribute("disabled");
240
+ }
241
+ }
242
+ }
243
+ // --- Field state from DOM events ---
244
+ #onFocusIn = () => {
245
+ this.#focused = true;
246
+ };
247
+ #onFocusOut = () => {
248
+ this.#focused = false;
249
+ this.#touched = true;
250
+ };
251
+ #onInput = () => {
252
+ this.#dirty = true;
253
+ this.#filled = true;
254
+ };
255
+ #onChange = () => {
256
+ this.#dirty = true;
257
+ };
258
+ // --- Slot change handlers ---
259
+ #onControlSlotChange = () => {
260
+ const slot = this.shadowRoot?.querySelector("slot:not([name])");
261
+ const nodes = slot?.assignedElements({ flatten: true }) ?? [];
262
+ this.#control = nodes.find((el) => el.matches(CONTROL_SELECTOR));
263
+ if (this.#control) {
264
+ this.#wireControl();
265
+ if (this.disabled) {
266
+ this.#controlWasDisabled = this.#control.hasAttribute("disabled");
267
+ this.#control.setAttribute("disabled", "");
268
+ }
269
+ }
270
+ };
271
+ #onLabelSlotChange = (e) => {
272
+ const slot = e.target;
273
+ this.#hasLabel = slot.assignedNodes({ flatten: true }).length > 0;
274
+ };
275
+ #onDescriptionSlotChange = (e) => {
276
+ const slot = e.target;
277
+ this.#hasDescription = slot.assignedNodes({ flatten: true }).length > 0;
278
+ this.#wireControl();
279
+ };
280
+ #onErrorSlotChange = (e) => {
281
+ const slot = e.target;
282
+ this.#hasError = slot.assignedNodes({ flatten: true }).length > 0;
283
+ this.#wireControl();
284
+ };
285
+ // --- ARIA wiring ---
286
+ #wireControl() {
287
+ const ctrl = this.#control;
288
+ if (!ctrl)
289
+ return;
290
+ // Build aria-describedby from present slots
291
+ const parts = [];
292
+ if (this.#hasDescription)
293
+ parts.push(this.#descriptionId);
294
+ if (this.invalid && this.#hasError)
295
+ parts.push(this.#errorId);
296
+ const describedBy = parts.join(" ") || null;
297
+ if (describedBy)
298
+ ctrl.setAttribute("aria-describedby", describedBy);
299
+ else
300
+ ctrl.removeAttribute("aria-describedby");
301
+ ctrl.setAttribute("aria-invalid", String(this.invalid));
302
+ }
303
+ // --- Label click-to-focus ---
304
+ #onLabelClick = () => {
305
+ if (!this.disabled) {
306
+ this.#control?.focus();
307
+ }
308
+ };
309
+ // --- Render ---
310
+ render() {
311
+ return html `
312
+ <div
313
+ part="root"
314
+ role="group"
315
+ ?data-disabled="${this.disabled}"
316
+ ?data-invalid="${this.invalid}"
317
+ ?data-valid="${!this.invalid}"
318
+ ?data-dirty="${this.#dirty}"
319
+ ?data-touched="${this.#touched}"
320
+ ?data-filled="${this.#filled}"
321
+ ?data-focused="${this.#focused}"
322
+ data-orientation="${this.orientation}"
323
+ >
324
+ <div
325
+ part="label"
326
+ id="${this.#labelId}"
327
+ ?data-slotted="${this.#hasLabel}"
328
+ ?data-disabled="${this.disabled}"
329
+ @click="${this.#onLabelClick}"
330
+ >
331
+ <slot
332
+ name="label"
333
+ @slotchange="${this.#onLabelSlotChange}"
334
+ ></slot>
335
+ </div>
336
+ <slot @slotchange="${this.#onControlSlotChange}"></slot>
337
+ <div
338
+ part="description"
339
+ id="${this.#descriptionId}"
340
+ ?data-slotted="${this.#hasDescription}"
341
+ >
342
+ <slot
343
+ name="description"
344
+ @slotchange="${this.#onDescriptionSlotChange}"
345
+ ></slot>
346
+ </div>
347
+ <div
348
+ part="error"
349
+ id="${this.#errorId}"
350
+ role="alert"
351
+ ?data-invalid="${this.invalid}"
352
+ >
353
+ <slot
354
+ name="error"
355
+ @slotchange="${this.#onErrorSlotChange}"
356
+ ></slot>
357
+ </div>
358
+ </div>
359
+ `;
360
+ }
361
+ };
362
+ })();
363
+ export { DuiField };
package/field/index.d.ts CHANGED
@@ -1,2 +1 @@
1
- export { fieldContext } from "./field-context.js";
2
- export type { FieldContext } from "./field-context.js";
1
+ export { DuiField } from "./field.js";
package/field/index.js CHANGED
@@ -1 +1 @@
1
- export { fieldContext } from "./field-context.js";
1
+ export { DuiField } from "./field.js";
@@ -0,0 +1,20 @@
1
+ import { LitElement, type TemplateResult } from "lit";
2
+ /**
3
+ * `<dui-fieldset>` — Semantic grouping for related form fields.
4
+ *
5
+ * Wraps content in a native `<fieldset>` element, providing semantic
6
+ * grouping for radio groups, checkbox groups, or logical field clusters.
7
+ *
8
+ * @slot legend - Legend text (e.g. `<span slot="legend">Personal Info</span>`).
9
+ * @slot - Default slot for field children.
10
+ * @csspart root - The native `<fieldset>` element.
11
+ * @csspart legend - The native `<legend>` element.
12
+ */
13
+ export declare class DuiFieldset extends LitElement {
14
+ #private;
15
+ static tagName: "dui-fieldset";
16
+ static styles: import("lit").CSSResult[];
17
+ /** Disables all child form controls. */
18
+ accessor disabled: boolean;
19
+ render(): TemplateResult;
20
+ }
@@ -0,0 +1,116 @@
1
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
2
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
3
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
4
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
5
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
6
+ var _, done = false;
7
+ for (var i = decorators.length - 1; i >= 0; i--) {
8
+ var context = {};
9
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
10
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
11
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
12
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
13
+ if (kind === "accessor") {
14
+ if (result === void 0) continue;
15
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
16
+ if (_ = accept(result.get)) descriptor.get = _;
17
+ if (_ = accept(result.set)) descriptor.set = _;
18
+ if (_ = accept(result.init)) initializers.unshift(_);
19
+ }
20
+ else if (_ = accept(result)) {
21
+ if (kind === "field") initializers.unshift(_);
22
+ else descriptor[key] = _;
23
+ }
24
+ }
25
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
26
+ done = true;
27
+ };
28
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
29
+ var useValue = arguments.length > 2;
30
+ for (var i = 0; i < initializers.length; i++) {
31
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
32
+ }
33
+ return useValue ? value : void 0;
34
+ };
35
+ var __setFunctionName = (this && this.__setFunctionName) || function (f, name, prefix) {
36
+ if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";
37
+ return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
38
+ };
39
+ import { css, html, LitElement } from "lit";
40
+ import { property, state } from "lit/decorators.js";
41
+ import { base } from "@deepfuture/dui-core/base";
42
+ /** Structural styles only — layout CSS. */
43
+ const styles = css `
44
+ :host {
45
+ display: block;
46
+ }
47
+
48
+ [part="root"] {
49
+ border: none;
50
+ margin: 0;
51
+ padding: 0;
52
+ min-width: 0;
53
+ }
54
+
55
+ [part="legend"]:not([data-slotted]) { display: none; }
56
+ [part="legend"] { padding: 0; }
57
+ `;
58
+ /**
59
+ * `<dui-fieldset>` — Semantic grouping for related form fields.
60
+ *
61
+ * Wraps content in a native `<fieldset>` element, providing semantic
62
+ * grouping for radio groups, checkbox groups, or logical field clusters.
63
+ *
64
+ * @slot legend - Legend text (e.g. `<span slot="legend">Personal Info</span>`).
65
+ * @slot - Default slot for field children.
66
+ * @csspart root - The native `<fieldset>` element.
67
+ * @csspart legend - The native `<legend>` element.
68
+ */
69
+ let DuiFieldset = (() => {
70
+ let _classSuper = LitElement;
71
+ let _disabled_decorators;
72
+ let _disabled_initializers = [];
73
+ let _disabled_extraInitializers = [];
74
+ let _private_hasLegend_decorators;
75
+ let _private_hasLegend_initializers = [];
76
+ let _private_hasLegend_extraInitializers = [];
77
+ let _private_hasLegend_descriptor;
78
+ return class DuiFieldset extends _classSuper {
79
+ static {
80
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
81
+ _disabled_decorators = [property({ type: Boolean, reflect: true })];
82
+ _private_hasLegend_decorators = [state()];
83
+ __esDecorate(this, null, _disabled_decorators, { kind: "accessor", name: "disabled", static: false, private: false, access: { has: obj => "disabled" in obj, get: obj => obj.disabled, set: (obj, value) => { obj.disabled = value; } }, metadata: _metadata }, _disabled_initializers, _disabled_extraInitializers);
84
+ __esDecorate(this, _private_hasLegend_descriptor = { get: __setFunctionName(function () { return this.#hasLegend_accessor_storage; }, "#hasLegend", "get"), set: __setFunctionName(function (value) { this.#hasLegend_accessor_storage = value; }, "#hasLegend", "set") }, _private_hasLegend_decorators, { kind: "accessor", name: "#hasLegend", static: false, private: true, access: { has: obj => #hasLegend in obj, get: obj => obj.#hasLegend, set: (obj, value) => { obj.#hasLegend = value; } }, metadata: _metadata }, _private_hasLegend_initializers, _private_hasLegend_extraInitializers);
85
+ if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
86
+ }
87
+ static tagName = "dui-fieldset";
88
+ static styles = [base, styles];
89
+ #disabled_accessor_storage = __runInitializers(this, _disabled_initializers, false);
90
+ /** Disables all child form controls. */
91
+ get disabled() { return this.#disabled_accessor_storage; }
92
+ set disabled(value) { this.#disabled_accessor_storage = value; }
93
+ #hasLegend_accessor_storage = (__runInitializers(this, _disabled_extraInitializers), __runInitializers(this, _private_hasLegend_initializers, false));
94
+ get #hasLegend() { return _private_hasLegend_descriptor.get.call(this); }
95
+ set #hasLegend(value) { return _private_hasLegend_descriptor.set.call(this, value); }
96
+ #onLegendSlotChange = (__runInitializers(this, _private_hasLegend_extraInitializers), (e) => {
97
+ const slot = e.target;
98
+ this.#hasLegend = slot.assignedNodes({ flatten: true }).length > 0;
99
+ });
100
+ render() {
101
+ return html `
102
+ <fieldset
103
+ part="root"
104
+ ?disabled="${this.disabled}"
105
+ ?data-disabled="${this.disabled}"
106
+ >
107
+ <legend part="legend" ?data-slotted="${this.#hasLegend}">
108
+ <slot name="legend" @slotchange="${this.#onLegendSlotChange}"></slot>
109
+ </legend>
110
+ <slot></slot>
111
+ </fieldset>
112
+ `;
113
+ }
114
+ };
115
+ })();
116
+ export { DuiFieldset };
@@ -0,0 +1 @@
1
+ export { DuiFieldset } from "./fieldset.js";
@@ -0,0 +1 @@
1
+ export { DuiFieldset } from "./fieldset.js";
package/global.d.ts CHANGED
@@ -42,7 +42,6 @@ import type { DuiDialogClose } from "./dialog/dialog-close.js";
42
42
  import type { DuiDropzone } from "./dropzone/dropzone.js";
43
43
  import type { DuiIcon } from "./icon/icon.js";
44
44
  import type { DuiInput } from "./input/input.js";
45
- import type { DuiLink } from "./link/link.js";
46
45
  import type { DuiMenu } from "./menu/menu.js";
47
46
  import type { DuiMenuItem } from "./menu/menu-item.js";
48
47
  import type { DuiMenubar } from "./menubar/menubar.js";
@@ -129,7 +128,6 @@ declare global {
129
128
  "dui-dropzone": DuiDropzone;
130
129
  "dui-icon": DuiIcon;
131
130
  "dui-input": DuiInput;
132
- "dui-link": DuiLink;
133
131
  "dui-menu": DuiMenu;
134
132
  "dui-menu-item": DuiMenuItem;
135
133
  "dui-menubar": DuiMenubar;
package/input/input.d.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  /** Ported from original DUI: deep-future-app/app/client/components/dui/input */
2
2
  import { LitElement, type TemplateResult } from "lit";
3
- import { type FieldContext } from "@deepfuture/dui-components/field";
4
3
  export declare const inputChangeEvent: (detail: {
5
4
  value: string;
6
5
  }) => CustomEvent<{
@@ -17,8 +16,10 @@ export declare const inputChangeEvent: (detail: {
17
16
  export declare class DuiInput extends LitElement {
18
17
  #private;
19
18
  static tagName: "dui-input";
19
+ static formAssociated: boolean;
20
20
  static shadowRootOptions: ShadowRootInit;
21
21
  static styles: import("lit").CSSResult[];
22
+ constructor();
22
23
  /** Input type (text, email, password, etc.) */
23
24
  accessor type: string;
24
25
  /** Current input value. */
@@ -43,7 +44,8 @@ export declare class DuiInput extends LitElement {
43
44
  accessor autocomplete: string | undefined;
44
45
  /** Whether the input should receive focus on mount. */
45
46
  accessor autofocus: boolean;
46
- accessor _fieldCtx: FieldContext;
47
47
  firstUpdated(): void;
48
+ updated(): void;
49
+ willUpdate(): void;
48
50
  render(): TemplateResult;
49
51
  }