@deepfuture/dui-components 0.0.18 → 0.0.20

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 (46) 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/radio/radio.d.ts +3 -2
  30. package/radio/radio.js +22 -44
  31. package/select/select.d.ts +3 -2
  32. package/select/select.js +15 -33
  33. package/slider/slider.d.ts +3 -0
  34. package/slider/slider.js +12 -5
  35. package/stepper/stepper.d.ts +0 -2
  36. package/stepper/stepper.js +7 -38
  37. package/switch/switch.d.ts +3 -2
  38. package/switch/switch.js +16 -41
  39. package/textarea/textarea.d.ts +4 -0
  40. package/textarea/textarea.js +20 -0
  41. package/field/field-context.d.ts +0 -20
  42. package/field/field-context.js +0 -2
  43. package/link/index.d.ts +0 -3
  44. package/link/index.js +0 -3
  45. package/link/link.d.ts +0 -27
  46. package/link/link.js +0 -95
package/radio/radio.js CHANGED
@@ -34,12 +34,10 @@ var __runInitializers = (this && this.__runInitializers) || function (thisArg, i
34
34
  return useValue ? value : void 0;
35
35
  };
36
36
  import { css, html, LitElement, nothing } from "lit";
37
- import { property, state } from "lit/decorators.js";
37
+ import { property } from "lit/decorators.js";
38
38
  import { ContextConsumer } from "@lit/context";
39
- import { consume } from "@lit/context";
40
39
  import { base } from "@deepfuture/dui-core/base";
41
40
  import { radioGroupContext } from "./radio-group-context.js";
42
- import { fieldContext } from "@deepfuture/dui-components/field";
43
41
  /** Structural styles only — layout CSS. */
44
42
  const styles = css `
45
43
  :host {
@@ -62,6 +60,7 @@ const styles = css `
62
60
  padding: 0;
63
61
  margin: 0;
64
62
  border: none;
63
+ user-select: none;
65
64
  }
66
65
 
67
66
  [part="root"][data-disabled] {
@@ -84,14 +83,6 @@ const styles = css `
84
83
  display: none;
85
84
  }
86
85
 
87
- .hidden-input {
88
- position: absolute;
89
- pointer-events: none;
90
- opacity: 0;
91
- margin: 0;
92
- width: 0;
93
- height: 0;
94
- }
95
86
  `;
96
87
  /**
97
88
  * `<dui-radio>` — A radio button input.
@@ -115,24 +106,25 @@ let DuiRadio = (() => {
115
106
  let _readOnly_decorators;
116
107
  let _readOnly_initializers = [];
117
108
  let _readOnly_extraInitializers = [];
118
- let __fieldCtx_decorators;
119
- let __fieldCtx_initializers = [];
120
- let __fieldCtx_extraInitializers = [];
121
109
  return class DuiRadio extends _classSuper {
122
110
  static {
123
111
  const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
124
112
  _value_decorators = [property()];
125
113
  _disabled_decorators = [property({ type: Boolean, reflect: true })];
126
114
  _readOnly_decorators = [property({ type: Boolean, reflect: true, attribute: "read-only" })];
127
- __fieldCtx_decorators = [consume({ context: fieldContext, subscribe: true }), state()];
128
115
  __esDecorate(this, null, _value_decorators, { kind: "accessor", name: "value", static: false, private: false, access: { has: obj => "value" in obj, get: obj => obj.value, set: (obj, value) => { obj.value = value; } }, metadata: _metadata }, _value_initializers, _value_extraInitializers);
129
116
  __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);
130
117
  __esDecorate(this, null, _readOnly_decorators, { kind: "accessor", name: "readOnly", static: false, private: false, access: { has: obj => "readOnly" in obj, get: obj => obj.readOnly, set: (obj, value) => { obj.readOnly = value; } }, metadata: _metadata }, _readOnly_initializers, _readOnly_extraInitializers);
131
- __esDecorate(this, null, __fieldCtx_decorators, { kind: "accessor", name: "_fieldCtx", static: false, private: false, access: { has: obj => "_fieldCtx" in obj, get: obj => obj._fieldCtx, set: (obj, value) => { obj._fieldCtx = value; } }, metadata: _metadata }, __fieldCtx_initializers, __fieldCtx_extraInitializers);
132
118
  if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
133
119
  }
134
120
  static tagName = "dui-radio";
121
+ static formAssociated = true;
135
122
  static styles = [base, styles];
123
+ #internals;
124
+ constructor() {
125
+ super();
126
+ this.#internals = this.attachInternals();
127
+ }
136
128
  #value_accessor_storage = __runInitializers(this, _value_initializers, "");
137
129
  /** The value attribute for this radio option. */
138
130
  get value() { return this.#value_accessor_storage; }
@@ -149,16 +141,12 @@ let DuiRadio = (() => {
149
141
  context: radioGroupContext,
150
142
  subscribe: true,
151
143
  }));
152
- #_fieldCtx_accessor_storage = __runInitializers(this, __fieldCtx_initializers, void 0);
153
- get _fieldCtx() { return this.#_fieldCtx_accessor_storage; }
154
- set _fieldCtx(value) { this.#_fieldCtx_accessor_storage = value; }
155
144
  get #isChecked() {
156
145
  return this.#groupCtx.value?.value === this.value;
157
146
  }
158
147
  get #isDisabled() {
159
148
  return (this.disabled ||
160
- (this.#groupCtx.value?.disabled ?? false) ||
161
- (this._fieldCtx?.disabled ?? false));
149
+ (this.#groupCtx.value?.disabled ?? false));
162
150
  }
163
151
  get #isReadOnly() {
164
152
  return this.readOnly || (this.#groupCtx.value?.readOnly ?? false);
@@ -166,30 +154,36 @@ let DuiRadio = (() => {
166
154
  get #isRequired() {
167
155
  return this.#groupCtx.value?.required ?? false;
168
156
  }
169
- get #isInvalid() {
170
- return this._fieldCtx?.invalid ?? false;
171
- }
172
157
  connectedCallback() {
173
158
  super.connectedCallback();
174
159
  this.addEventListener("click", this.#handleHostClick);
175
160
  }
161
+ willUpdate() {
162
+ this.#syncFormValue();
163
+ }
164
+ #syncFormValue() {
165
+ if (this.#isChecked) {
166
+ this.#internals.setFormValue(this.value);
167
+ }
168
+ else {
169
+ this.#internals.setFormValue(null);
170
+ }
171
+ }
176
172
  disconnectedCallback() {
177
173
  super.disconnectedCallback();
178
174
  this.removeEventListener("click", this.#handleHostClick);
179
175
  }
180
- #handleHostClick = (__runInitializers(this, __fieldCtx_extraInitializers), (e) => {
176
+ #handleHostClick = (e) => {
181
177
  if (e.target.closest("[part='root']"))
182
178
  return;
183
179
  this.#handleClick(e);
184
- });
180
+ };
185
181
  #handleClick = (_e) => {
186
182
  if (this.#isDisabled || this.#isReadOnly)
187
183
  return;
188
184
  const ctx = this.#groupCtx.value;
189
185
  if (ctx) {
190
186
  ctx.select(this.value);
191
- this._fieldCtx?.markDirty();
192
- this._fieldCtx?.markTouched();
193
187
  }
194
188
  };
195
189
  #handleKeyDown = (e) => {
@@ -203,25 +197,20 @@ let DuiRadio = (() => {
203
197
  const isDisabled = this.#isDisabled;
204
198
  const isReadOnly = this.#isReadOnly;
205
199
  const isRequired = this.#isRequired;
206
- const isInvalid = this.#isInvalid;
207
- const controlId = this._fieldCtx?.controlId ?? "";
208
200
  return html `
209
201
  <span
210
202
  part="root"
211
203
  role="radio"
212
- id="${controlId || nothing}"
213
204
  aria-checked="${String(isChecked)}"
214
205
  aria-disabled="${isDisabled ? "true" : nothing}"
215
206
  aria-readonly="${isReadOnly ? "true" : nothing}"
216
207
  aria-required="${isRequired ? "true" : nothing}"
217
- aria-invalid="${isInvalid ? "true" : nothing}"
218
208
  tabindex="${isDisabled ? nothing : "0"}"
219
209
  ?data-checked="${isChecked}"
220
210
  ?data-unchecked="${!isChecked}"
221
211
  ?data-disabled="${isDisabled}"
222
212
  ?data-readonly="${isReadOnly}"
223
213
  ?data-required="${isRequired}"
224
- ?data-invalid="${isInvalid}"
225
214
  @click="${this.#handleClick}"
226
215
  @keydown="${this.#handleKeyDown}"
227
216
  >
@@ -232,17 +221,6 @@ let DuiRadio = (() => {
232
221
  >
233
222
  ${isChecked ? html `<span part="dot"></span>` : nothing}
234
223
  </span>
235
- <input
236
- type="radio"
237
- name="${this.#groupCtx.value?.name ?? nothing}"
238
- value="${this.value}"
239
- .checked="${isChecked}"
240
- ?disabled="${isDisabled}"
241
- ?required="${isRequired}"
242
- class="hidden-input"
243
- aria-hidden="true"
244
- tabindex="-1"
245
- />
246
224
  </span>
247
225
  <slot></slot>
248
226
  `;
@@ -1,6 +1,5 @@
1
1
  /** Ported from original DUI: deep-future-app/app/client/components/dui/select */
2
2
  import { LitElement, type TemplateResult } from "lit";
3
- import { type FieldContext } from "../field/field-context.js";
4
3
  export type SelectOption = {
5
4
  label: string;
6
5
  value: string;
@@ -22,7 +21,9 @@ export declare const valueChangeEvent: (detail: SelectValueChangeDetail) => Cust
22
21
  export declare class DuiSelect extends LitElement {
23
22
  #private;
24
23
  static tagName: "dui-select";
24
+ static formAssociated: boolean;
25
25
  static styles: import("lit").CSSResult[];
26
+ constructor();
26
27
  /** The available options. */
27
28
  accessor options: SelectOption[];
28
29
  /** Currently selected value. */
@@ -33,6 +34,6 @@ export declare class DuiSelect extends LitElement {
33
34
  accessor disabled: boolean;
34
35
  /** Name for form submission. */
35
36
  accessor name: string;
36
- accessor _fieldCtx: FieldContext;
37
+ willUpdate(): void;
37
38
  render(): TemplateResult;
38
39
  }
package/select/select.js CHANGED
@@ -40,11 +40,9 @@ var __setFunctionName = (this && this.__setFunctionName) || function (f, name, p
40
40
  import { css, html, LitElement, nothing } from "lit";
41
41
  import { property, state } from "lit/decorators.js";
42
42
  import { repeat } from "lit/directives/repeat.js";
43
- import { consume } from "@lit/context";
44
43
  import { base } from "@deepfuture/dui-core/base";
45
44
  import { customEvent } from "@deepfuture/dui-core/event";
46
45
  import { FloatingPortalController } from "@deepfuture/dui-core/floating-portal-controller";
47
- import { fieldContext } from "../field/field-context.js";
48
46
  export const valueChangeEvent = customEvent("value-change", { bubbles: true, composed: true });
49
47
  /** Structural styles only — layout CSS. */
50
48
  const hostStyles = css `
@@ -146,9 +144,6 @@ let DuiSelect = (() => {
146
144
  let _name_decorators;
147
145
  let _name_initializers = [];
148
146
  let _name_extraInitializers = [];
149
- let __fieldCtx_decorators;
150
- let __fieldCtx_initializers = [];
151
- let __fieldCtx_extraInitializers = [];
152
147
  let _private_highlightedIndex_decorators;
153
148
  let _private_highlightedIndex_initializers = [];
154
149
  let _private_highlightedIndex_extraInitializers = [];
@@ -161,19 +156,23 @@ let DuiSelect = (() => {
161
156
  _placeholder_decorators = [property({ type: String })];
162
157
  _disabled_decorators = [property({ type: Boolean, reflect: true })];
163
158
  _name_decorators = [property({ type: String })];
164
- __fieldCtx_decorators = [consume({ context: fieldContext, subscribe: true }), state()];
165
159
  _private_highlightedIndex_decorators = [state()];
166
160
  __esDecorate(this, null, _options_decorators, { kind: "accessor", name: "options", static: false, private: false, access: { has: obj => "options" in obj, get: obj => obj.options, set: (obj, value) => { obj.options = value; } }, metadata: _metadata }, _options_initializers, _options_extraInitializers);
167
161
  __esDecorate(this, null, _value_decorators, { kind: "accessor", name: "value", static: false, private: false, access: { has: obj => "value" in obj, get: obj => obj.value, set: (obj, value) => { obj.value = value; } }, metadata: _metadata }, _value_initializers, _value_extraInitializers);
168
162
  __esDecorate(this, null, _placeholder_decorators, { kind: "accessor", name: "placeholder", static: false, private: false, access: { has: obj => "placeholder" in obj, get: obj => obj.placeholder, set: (obj, value) => { obj.placeholder = value; } }, metadata: _metadata }, _placeholder_initializers, _placeholder_extraInitializers);
169
163
  __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);
170
164
  __esDecorate(this, null, _name_decorators, { kind: "accessor", name: "name", static: false, private: false, access: { has: obj => "name" in obj, get: obj => obj.name, set: (obj, value) => { obj.name = value; } }, metadata: _metadata }, _name_initializers, _name_extraInitializers);
171
- __esDecorate(this, null, __fieldCtx_decorators, { kind: "accessor", name: "_fieldCtx", static: false, private: false, access: { has: obj => "_fieldCtx" in obj, get: obj => obj._fieldCtx, set: (obj, value) => { obj._fieldCtx = value; } }, metadata: _metadata }, __fieldCtx_initializers, __fieldCtx_extraInitializers);
172
165
  __esDecorate(this, _private_highlightedIndex_descriptor = { get: __setFunctionName(function () { return this.#highlightedIndex_accessor_storage; }, "#highlightedIndex", "get"), set: __setFunctionName(function (value) { this.#highlightedIndex_accessor_storage = value; }, "#highlightedIndex", "set") }, _private_highlightedIndex_decorators, { kind: "accessor", name: "#highlightedIndex", static: false, private: true, access: { has: obj => #highlightedIndex in obj, get: obj => obj.#highlightedIndex, set: (obj, value) => { obj.#highlightedIndex = value; } }, metadata: _metadata }, _private_highlightedIndex_initializers, _private_highlightedIndex_extraInitializers);
173
166
  if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
174
167
  }
175
168
  static tagName = "dui-select";
169
+ static formAssociated = true;
176
170
  static styles = [base, hostStyles, componentStyles];
171
+ #internals;
172
+ constructor() {
173
+ super();
174
+ this.#internals = this.attachInternals();
175
+ }
177
176
  #options_accessor_storage = __runInitializers(this, _options_initializers, []);
178
177
  /** The available options. */
179
178
  get options() { return this.#options_accessor_storage; }
@@ -194,10 +193,7 @@ let DuiSelect = (() => {
194
193
  /** Name for form submission. */
195
194
  get name() { return this.#name_accessor_storage; }
196
195
  set name(value) { this.#name_accessor_storage = value; }
197
- #_fieldCtx_accessor_storage = (__runInitializers(this, _name_extraInitializers), __runInitializers(this, __fieldCtx_initializers, void 0));
198
- get _fieldCtx() { return this.#_fieldCtx_accessor_storage; }
199
- set _fieldCtx(value) { this.#_fieldCtx_accessor_storage = value; }
200
- #highlightedIndex_accessor_storage = (__runInitializers(this, __fieldCtx_extraInitializers), __runInitializers(this, _private_highlightedIndex_initializers, -1));
196
+ #highlightedIndex_accessor_storage = (__runInitializers(this, _name_extraInitializers), __runInitializers(this, _private_highlightedIndex_initializers, -1));
201
197
  get #highlightedIndex() { return _private_highlightedIndex_descriptor.get.call(this); }
202
198
  set #highlightedIndex(value) { return _private_highlightedIndex_descriptor.set.call(this, value); }
203
199
  #triggerId = (__runInitializers(this, _private_highlightedIndex_extraInitializers), `select-trigger-${crypto.randomUUID().slice(0, 8)}`);
@@ -212,7 +208,6 @@ let DuiSelect = (() => {
212
208
  },
213
209
  onClose: () => {
214
210
  this.#highlightedIndex = -1;
215
- this._fieldCtx?.markTouched();
216
211
  },
217
212
  renderPopup: (portal) => {
218
213
  return html `
@@ -225,7 +220,7 @@ let DuiSelect = (() => {
225
220
  class="Listbox"
226
221
  id="${this.#listboxId}"
227
222
  role="listbox"
228
- aria-labelledby="${this._fieldCtx?.labelId ?? ""}"
223
+
229
224
  @mousedown="${this.#onListMouseDown}"
230
225
  >
231
226
  ${repeat(this.options, (option) => option.value, this.#renderItem)}
@@ -234,13 +229,10 @@ let DuiSelect = (() => {
234
229
  `;
235
230
  },
236
231
  });
237
- // ---- Computed ----
238
- get #isDisabled() {
239
- return this.disabled || (this._fieldCtx?.disabled ?? false);
240
- }
241
- get #isInvalid() {
242
- return this._fieldCtx?.invalid ?? false;
232
+ willUpdate() {
233
+ this.#internals.setFormValue(this.value);
243
234
  }
235
+ // ---- Computed ----
244
236
  get #selectedOption() {
245
237
  return this.options.find((o) => o.value === this.value);
246
238
  }
@@ -253,7 +245,7 @@ let DuiSelect = (() => {
253
245
  // ---- Event handlers ----
254
246
  #onTriggerClick = (event) => {
255
247
  event.stopPropagation();
256
- if (this.#isDisabled)
248
+ if (this.disabled)
257
249
  return;
258
250
  if (this.#popup.isOpen) {
259
251
  this.#popup.close();
@@ -263,7 +255,7 @@ let DuiSelect = (() => {
263
255
  }
264
256
  };
265
257
  #onTriggerKeyDown = (event) => {
266
- if (this.#isDisabled)
258
+ if (this.disabled)
267
259
  return;
268
260
  switch (event.key) {
269
261
  case "Enter":
@@ -346,8 +338,6 @@ let DuiSelect = (() => {
346
338
  // ---- Selection ----
347
339
  #selectOption(option) {
348
340
  this.value = option.value;
349
- this._fieldCtx?.markDirty();
350
- this._fieldCtx?.setFilled(this.value.length > 0);
351
341
  this.dispatchEvent(valueChangeEvent({ value: option.value, option }));
352
342
  this.#popup.close();
353
343
  this.#focusTrigger();
@@ -399,22 +389,17 @@ let DuiSelect = (() => {
399
389
  part="trigger"
400
390
  id="${this.#triggerId}"
401
391
  role="combobox"
402
- tabindex="${this.#isDisabled ? -1 : 0}"
392
+ tabindex="${this.disabled ? -1 : 0}"
403
393
  aria-haspopup="listbox"
404
394
  aria-expanded="${this.#popup.isOpen}"
405
395
  aria-controls="${this.#listboxId}"
406
396
  aria-activedescendant="${this.#highlightedIndex >= 0
407
397
  ? `${this.#listboxId}-option-${this.#highlightedIndex}`
408
398
  : nothing}"
409
- aria-labelledby="${this._fieldCtx?.labelId ?? ""}"
410
- aria-invalid="${this.#isInvalid}"
411
- ?data-disabled="${this.#isDisabled}"
412
- ?data-invalid="${this.#isInvalid}"
399
+ ?data-disabled="${this.disabled}"
413
400
  ?data-open="${this.#popup.isOpen}"
414
401
  @click="${this.#onTriggerClick}"
415
402
  @keydown="${this.#onTriggerKeyDown}"
416
- @focus="${() => this._fieldCtx?.setFocused(true)}"
417
- @blur="${() => this._fieldCtx?.setFocused(false)}"
418
403
  >
419
404
  <span
420
405
  class="Value"
@@ -428,9 +413,6 @@ let DuiSelect = (() => {
428
413
  </span>
429
414
  </div>
430
415
 
431
- ${this.name
432
- ? html `<input type="hidden" name="${this.name}" .value="${this.value}" />`
433
- : nothing}
434
416
  `;
435
417
  }
436
418
  };
@@ -20,7 +20,9 @@ export declare const valueCommittedEvent: (detail: {
20
20
  export declare class DuiSlider extends LitElement {
21
21
  #private;
22
22
  static tagName: "dui-slider";
23
+ static formAssociated: boolean;
23
24
  static styles: import("lit").CSSResult[];
25
+ constructor();
24
26
  /** Current value. */
25
27
  accessor value: number;
26
28
  /** Minimum value. */
@@ -39,6 +41,7 @@ export declare class DuiSlider extends LitElement {
39
41
  accessor unit: string;
40
42
  /** Decimal places for value readout. Auto-inferred from `step` if not set. */
41
43
  accessor precision: number | undefined;
44
+ willUpdate(): void;
42
45
  disconnectedCallback(): void;
43
46
  render(): TemplateResult;
44
47
  }
package/slider/slider.js CHANGED
@@ -201,7 +201,13 @@ let DuiSlider = (() => {
201
201
  if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
202
202
  }
203
203
  static tagName = "dui-slider";
204
+ static formAssociated = true;
204
205
  static styles = [base, styles];
206
+ #internals;
207
+ constructor() {
208
+ super();
209
+ this.#internals = this.attachInternals();
210
+ }
205
211
  #value_accessor_storage = __runInitializers(this, _value_initializers, 0);
206
212
  /** Current value. */
207
213
  get value() { return this.#value_accessor_storage; }
@@ -238,6 +244,9 @@ let DuiSlider = (() => {
238
244
  /** Decimal places for value readout. Auto-inferred from `step` if not set. */
239
245
  get precision() { return this.#precision_accessor_storage; }
240
246
  set precision(value) { this.#precision_accessor_storage = value; }
247
+ willUpdate() {
248
+ this.#internals.setFormValue(String(this.value));
249
+ }
241
250
  #dragging_accessor_storage = (__runInitializers(this, _precision_extraInitializers), __runInitializers(this, _private_dragging_initializers, false));
242
251
  get #dragging() { return _private_dragging_descriptor.get.call(this); }
243
252
  set #dragging(value) { return _private_dragging_descriptor.set.call(this, value); }
@@ -275,7 +284,6 @@ let DuiSlider = (() => {
275
284
  if (this.disabled)
276
285
  return;
277
286
  event.preventDefault();
278
- this.#dragging = true;
279
287
  const newValue = this.#getValueFromPosition(event.clientX);
280
288
  if (newValue !== this.value) {
281
289
  this.value = newValue;
@@ -286,7 +294,7 @@ let DuiSlider = (() => {
286
294
  });
287
295
  #onPointerMove = (event) => {
288
296
  if (!this.#dragging)
289
- return;
297
+ this.#dragging = true;
290
298
  const newValue = this.#getValueFromPosition(event.clientX);
291
299
  if (newValue !== this.value) {
292
300
  this.value = newValue;
@@ -294,12 +302,11 @@ let DuiSlider = (() => {
294
302
  }
295
303
  };
296
304
  #onPointerUp = () => {
297
- if (!this.#dragging)
298
- return;
305
+ const wasDragging = this.#dragging;
299
306
  this.#dragging = false;
300
- this.dispatchEvent(valueCommittedEvent({ value: this.value }));
301
307
  document.removeEventListener("pointermove", this.#onPointerMove);
302
308
  document.removeEventListener("pointerup", this.#onPointerUp);
309
+ this.dispatchEvent(valueCommittedEvent({ value: this.value }));
303
310
  };
304
311
  #onKeyDown = (event) => {
305
312
  if (this.disabled)
@@ -1,5 +1,4 @@
1
1
  import { LitElement, type TemplateResult } from "lit";
2
- import { type FieldContext } from "@deepfuture/dui-components/field";
3
2
  export declare const valueChangeEvent: (detail: {
4
3
  value: number;
5
4
  }) => CustomEvent<{
@@ -38,7 +37,6 @@ export declare class DuiStepper extends LitElement {
38
37
  accessor readOnly: boolean;
39
38
  accessor required: boolean;
40
39
  accessor name: string | undefined;
41
- accessor _fieldCtx: FieldContext;
42
40
  connectedCallback(): void;
43
41
  willUpdate(): void;
44
42
  render(): TemplateResult;
@@ -38,11 +38,9 @@ var __setFunctionName = (this && this.__setFunctionName) || function (f, name, p
38
38
  };
39
39
  import { css, html, LitElement, nothing } from "lit";
40
40
  import { property, state } from "lit/decorators.js";
41
- import { consume } from "@lit/context";
42
41
  import { live } from "lit/directives/live.js";
43
42
  import { base } from "@deepfuture/dui-core/base";
44
43
  import { customEvent } from "@deepfuture/dui-core/event";
45
- import { fieldContext } from "@deepfuture/dui-components/field";
46
44
  export const valueChangeEvent = customEvent("value-change", { bubbles: true, composed: true });
47
45
  export const valueCommittedEvent = customEvent("value-committed", { bubbles: true, composed: true });
48
46
  /** Structural styles only — layout CSS. */
@@ -153,9 +151,6 @@ let DuiStepper = (() => {
153
151
  let _private_inputText_initializers = [];
154
152
  let _private_inputText_extraInitializers = [];
155
153
  let _private_inputText_descriptor;
156
- let __fieldCtx_decorators;
157
- let __fieldCtx_initializers = [];
158
- let __fieldCtx_extraInitializers = [];
159
154
  return class DuiStepper extends _classSuper {
160
155
  static {
161
156
  const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
@@ -171,7 +166,6 @@ let DuiStepper = (() => {
171
166
  _name_decorators = [property()];
172
167
  _private_internalValue_decorators = [state()];
173
168
  _private_inputText_decorators = [state()];
174
- __fieldCtx_decorators = [consume({ context: fieldContext, subscribe: true }), state()];
175
169
  __esDecorate(this, null, _value_decorators, { kind: "accessor", name: "value", static: false, private: false, access: { has: obj => "value" in obj, get: obj => obj.value, set: (obj, value) => { obj.value = value; } }, metadata: _metadata }, _value_initializers, _value_extraInitializers);
176
170
  __esDecorate(this, null, _defaultValue_decorators, { kind: "accessor", name: "defaultValue", static: false, private: false, access: { has: obj => "defaultValue" in obj, get: obj => obj.defaultValue, set: (obj, value) => { obj.defaultValue = value; } }, metadata: _metadata }, _defaultValue_initializers, _defaultValue_extraInitializers);
177
171
  __esDecorate(this, null, _min_decorators, { kind: "accessor", name: "min", static: false, private: false, access: { has: obj => "min" in obj, get: obj => obj.min, set: (obj, value) => { obj.min = value; } }, metadata: _metadata }, _min_initializers, _min_extraInitializers);
@@ -184,7 +178,6 @@ let DuiStepper = (() => {
184
178
  __esDecorate(this, null, _name_decorators, { kind: "accessor", name: "name", static: false, private: false, access: { has: obj => "name" in obj, get: obj => obj.name, set: (obj, value) => { obj.name = value; } }, metadata: _metadata }, _name_initializers, _name_extraInitializers);
185
179
  __esDecorate(this, _private_internalValue_descriptor = { get: __setFunctionName(function () { return this.#internalValue_accessor_storage; }, "#internalValue", "get"), set: __setFunctionName(function (value) { this.#internalValue_accessor_storage = value; }, "#internalValue", "set") }, _private_internalValue_decorators, { kind: "accessor", name: "#internalValue", static: false, private: true, access: { has: obj => #internalValue in obj, get: obj => obj.#internalValue, set: (obj, value) => { obj.#internalValue = value; } }, metadata: _metadata }, _private_internalValue_initializers, _private_internalValue_extraInitializers);
186
180
  __esDecorate(this, _private_inputText_descriptor = { get: __setFunctionName(function () { return this.#inputText_accessor_storage; }, "#inputText", "get"), set: __setFunctionName(function (value) { this.#inputText_accessor_storage = value; }, "#inputText", "set") }, _private_inputText_decorators, { kind: "accessor", name: "#inputText", static: false, private: true, access: { has: obj => #inputText in obj, get: obj => obj.#inputText, set: (obj, value) => { obj.#inputText = value; } }, metadata: _metadata }, _private_inputText_initializers, _private_inputText_extraInitializers);
187
- __esDecorate(this, null, __fieldCtx_decorators, { kind: "accessor", name: "_fieldCtx", static: false, private: false, access: { has: obj => "_fieldCtx" in obj, get: obj => obj._fieldCtx, set: (obj, value) => { obj._fieldCtx = value; } }, metadata: _metadata }, __fieldCtx_initializers, __fieldCtx_extraInitializers);
188
181
  if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
189
182
  }
190
183
  static tagName = "dui-stepper";
@@ -230,19 +223,10 @@ let DuiStepper = (() => {
230
223
  #inputText_accessor_storage = (__runInitializers(this, _private_internalValue_extraInitializers), __runInitializers(this, _private_inputText_initializers, ""));
231
224
  get #inputText() { return _private_inputText_descriptor.get.call(this); }
232
225
  set #inputText(value) { return _private_inputText_descriptor.set.call(this, value); }
233
- #_fieldCtx_accessor_storage = (__runInitializers(this, _private_inputText_extraInitializers), __runInitializers(this, __fieldCtx_initializers, void 0));
234
- get _fieldCtx() { return this.#_fieldCtx_accessor_storage; }
235
- set _fieldCtx(value) { this.#_fieldCtx_accessor_storage = value; }
236
226
  // ── Computed getters ───────────────────────────────────────────────
237
227
  get #currentValue() {
238
228
  return this.value ?? this.#internalValue;
239
229
  }
240
- get #isDisabled() {
241
- return this.disabled || (this._fieldCtx?.disabled ?? false);
242
- }
243
- get #isInvalid() {
244
- return this._fieldCtx?.invalid ?? false;
245
- }
246
230
  get #canDecrement() {
247
231
  const v = this.#currentValue;
248
232
  if (v === undefined)
@@ -283,18 +267,16 @@ let DuiStepper = (() => {
283
267
  if (this.value === undefined) {
284
268
  this.#internalValue = clamped;
285
269
  }
286
- this._fieldCtx?.markDirty();
287
- this._fieldCtx?.setFilled(true);
288
270
  this.dispatchEvent(valueChangeEvent({ value: clamped }));
289
271
  }
290
- #increment = (__runInitializers(this, __fieldCtx_extraInitializers), (amount) => {
291
- if (this.#isDisabled || this.readOnly)
272
+ #increment = (__runInitializers(this, _private_inputText_extraInitializers), (amount) => {
273
+ if (this.disabled || this.readOnly)
292
274
  return;
293
275
  const current = this.#currentValue ?? this.min ?? 0;
294
276
  this.#setValue(current + amount);
295
277
  });
296
278
  #decrement = (amount) => {
297
- if (this.#isDisabled || this.readOnly)
279
+ if (this.disabled || this.readOnly)
298
280
  return;
299
281
  const current = this.#currentValue ?? this.max ?? 0;
300
282
  this.#setValue(current - amount);
@@ -318,11 +300,6 @@ let DuiStepper = (() => {
318
300
  };
319
301
  #onBlur = () => {
320
302
  this.#commitInput();
321
- this._fieldCtx?.setFocused(false);
322
- this._fieldCtx?.markTouched();
323
- };
324
- #onFocus = () => {
325
- this._fieldCtx?.setFocused(true);
326
303
  };
327
304
  #onKeyDown = (e) => {
328
305
  switch (e.key) {
@@ -369,40 +346,32 @@ let DuiStepper = (() => {
369
346
  };
370
347
  // ── Render ─────────────────────────────────────────────────────────
371
348
  render() {
372
- const isDisabled = this.#isDisabled;
373
- const isInvalid = this.#isInvalid;
374
- const controlId = this._fieldCtx?.controlId ?? "";
375
349
  const currentValue = this.#currentValue;
376
350
  return html `
377
351
  <div
378
352
  part="root"
379
- ?data-disabled="${isDisabled}"
380
- ?data-invalid="${isInvalid}"
353
+ ?data-disabled="${this.disabled}"
381
354
  >
382
355
  <button
383
356
  part="decrement"
384
357
  type="button"
385
358
  tabindex="-1"
386
359
  aria-label="Decrease"
387
- ?disabled="${isDisabled || this.readOnly || !this.#canDecrement}"
360
+ ?disabled="${this.disabled || this.readOnly || !this.#canDecrement}"
388
361
  @click="${this.#onDecrementClick}"
389
362
  >
390
363
  <slot name="decrement">&minus;</slot>
391
364
  </button>
392
365
  <input
393
366
  part="input"
394
- id="${controlId || nothing}"
395
367
  type="text"
396
368
  inputmode="decimal"
397
369
  .value="${live(this.#inputText)}"
398
- ?disabled="${isDisabled}"
370
+ ?disabled="${this.disabled}"
399
371
  ?readonly="${this.readOnly}"
400
372
  ?required="${this.required}"
401
- aria-invalid="${isInvalid ? "true" : nothing}"
402
- ?data-disabled="${isDisabled}"
403
373
  @input="${this.#onInput}"
404
374
  @keydown="${this.#onKeyDown}"
405
- @focus="${this.#onFocus}"
406
375
  @blur="${this.#onBlur}"
407
376
  />
408
377
  <button
@@ -410,7 +379,7 @@ let DuiStepper = (() => {
410
379
  type="button"
411
380
  tabindex="-1"
412
381
  aria-label="Increase"
413
- ?disabled="${isDisabled || this.readOnly || !this.#canIncrement}"
382
+ ?disabled="${this.disabled || this.readOnly || !this.#canIncrement}"
414
383
  @click="${this.#onIncrementClick}"
415
384
  >
416
385
  <slot name="increment">+</slot>
@@ -1,5 +1,4 @@
1
1
  import { LitElement, type TemplateResult } from "lit";
2
- import { type FieldContext } from "../field/field-context.js";
3
2
  export declare const checkedChangeEvent: (detail: {
4
3
  checked: boolean;
5
4
  }) => CustomEvent<{
@@ -15,7 +14,9 @@ export declare const checkedChangeEvent: (detail: {
15
14
  export declare class DuiSwitch extends LitElement {
16
15
  #private;
17
16
  static tagName: "dui-switch";
17
+ static formAssociated: boolean;
18
18
  static styles: import("lit").CSSResult[];
19
+ constructor();
19
20
  accessor checked: boolean | undefined;
20
21
  accessor defaultChecked: boolean;
21
22
  accessor disabled: boolean;
@@ -24,8 +25,8 @@ export declare class DuiSwitch extends LitElement {
24
25
  accessor name: string | undefined;
25
26
  accessor value: string;
26
27
  accessor uncheckedValue: string;
27
- accessor _fieldCtx: FieldContext;
28
28
  connectedCallback(): void;
29
+ willUpdate(): void;
29
30
  disconnectedCallback(): void;
30
31
  render(): TemplateResult;
31
32
  }