@deepfuture/dui-components 0.0.14 → 0.0.16

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.
@@ -0,0 +1,430 @@
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, nothing } from "lit";
40
+ import { property, state } from "lit/decorators.js";
41
+ import { consume } from "@lit/context";
42
+ import { live } from "lit/directives/live.js";
43
+ import { base } from "@deepfuture/dui-core/base";
44
+ import { customEvent } from "@deepfuture/dui-core/event";
45
+ import { fieldContext } from "@deepfuture/dui-components/field";
46
+ export const valueChangeEvent = customEvent("value-change", { bubbles: true, composed: true });
47
+ export const valueCommittedEvent = customEvent("value-committed", { bubbles: true, composed: true });
48
+ /** Structural styles only — layout CSS. */
49
+ const styles = css `
50
+ :host {
51
+ display: block;
52
+ }
53
+
54
+ [part="root"] {
55
+ display: inline-flex;
56
+ align-items: center;
57
+ }
58
+
59
+ [part="input"] {
60
+ box-sizing: border-box;
61
+ outline: none;
62
+ border: none;
63
+ background: none;
64
+ font: inherit;
65
+ color: inherit;
66
+ text-align: center;
67
+ min-width: 0;
68
+ }
69
+
70
+ [part="input"]:disabled {
71
+ cursor: not-allowed;
72
+ }
73
+
74
+ [part="decrement"],
75
+ [part="increment"] {
76
+ display: inline-flex;
77
+ align-items: center;
78
+ justify-content: center;
79
+ cursor: pointer;
80
+ border: none;
81
+ background: none;
82
+ padding: 0;
83
+ margin: 0;
84
+ font: inherit;
85
+ color: inherit;
86
+ flex-shrink: 0;
87
+ }
88
+
89
+ [part="decrement"]:disabled,
90
+ [part="increment"]:disabled {
91
+ cursor: not-allowed;
92
+ }
93
+
94
+ .HiddenInput {
95
+ position: absolute;
96
+ pointer-events: none;
97
+ opacity: 0;
98
+ margin: 0;
99
+ width: 0;
100
+ height: 0;
101
+ }
102
+ `;
103
+ /**
104
+ * `<dui-stepper>` — A numeric input with increment/decrement buttons.
105
+ *
106
+ * Simple component for stepping values up and down via buttons, keyboard,
107
+ * or manual text entry. No labels, icons, scrubbing, or other extras.
108
+ *
109
+ * @csspart root - The outer container.
110
+ * @csspart input - The text input element.
111
+ * @csspart decrement - The decrement button.
112
+ * @csspart increment - The increment button.
113
+ * @fires value-change - Fired when value changes. Detail: { value: number }
114
+ * @fires value-committed - Fired on blur or Enter. Detail: { value: number }
115
+ */
116
+ let DuiStepper = (() => {
117
+ let _classSuper = LitElement;
118
+ let _value_decorators;
119
+ let _value_initializers = [];
120
+ let _value_extraInitializers = [];
121
+ let _defaultValue_decorators;
122
+ let _defaultValue_initializers = [];
123
+ let _defaultValue_extraInitializers = [];
124
+ let _min_decorators;
125
+ let _min_initializers = [];
126
+ let _min_extraInitializers = [];
127
+ let _max_decorators;
128
+ let _max_initializers = [];
129
+ let _max_extraInitializers = [];
130
+ let _step_decorators;
131
+ let _step_initializers = [];
132
+ let _step_extraInitializers = [];
133
+ let _largeStep_decorators;
134
+ let _largeStep_initializers = [];
135
+ let _largeStep_extraInitializers = [];
136
+ let _disabled_decorators;
137
+ let _disabled_initializers = [];
138
+ let _disabled_extraInitializers = [];
139
+ let _readOnly_decorators;
140
+ let _readOnly_initializers = [];
141
+ let _readOnly_extraInitializers = [];
142
+ let _required_decorators;
143
+ let _required_initializers = [];
144
+ let _required_extraInitializers = [];
145
+ let _name_decorators;
146
+ let _name_initializers = [];
147
+ let _name_extraInitializers = [];
148
+ let _private_internalValue_decorators;
149
+ let _private_internalValue_initializers = [];
150
+ let _private_internalValue_extraInitializers = [];
151
+ let _private_internalValue_descriptor;
152
+ let _private_inputText_decorators;
153
+ let _private_inputText_initializers = [];
154
+ let _private_inputText_extraInitializers = [];
155
+ let _private_inputText_descriptor;
156
+ let __fieldCtx_decorators;
157
+ let __fieldCtx_initializers = [];
158
+ let __fieldCtx_extraInitializers = [];
159
+ return class DuiStepper extends _classSuper {
160
+ static {
161
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
162
+ _value_decorators = [property({ type: Number })];
163
+ _defaultValue_decorators = [property({ type: Number, attribute: "default-value" })];
164
+ _min_decorators = [property({ type: Number })];
165
+ _max_decorators = [property({ type: Number })];
166
+ _step_decorators = [property({ type: Number })];
167
+ _largeStep_decorators = [property({ type: Number, attribute: "large-step" })];
168
+ _disabled_decorators = [property({ type: Boolean, reflect: true })];
169
+ _readOnly_decorators = [property({ type: Boolean, reflect: true, attribute: "read-only" })];
170
+ _required_decorators = [property({ type: Boolean })];
171
+ _name_decorators = [property()];
172
+ _private_internalValue_decorators = [state()];
173
+ _private_inputText_decorators = [state()];
174
+ __fieldCtx_decorators = [consume({ context: fieldContext, subscribe: true }), state()];
175
+ __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
+ __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
+ __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);
178
+ __esDecorate(this, null, _max_decorators, { kind: "accessor", name: "max", static: false, private: false, access: { has: obj => "max" in obj, get: obj => obj.max, set: (obj, value) => { obj.max = value; } }, metadata: _metadata }, _max_initializers, _max_extraInitializers);
179
+ __esDecorate(this, null, _step_decorators, { kind: "accessor", name: "step", static: false, private: false, access: { has: obj => "step" in obj, get: obj => obj.step, set: (obj, value) => { obj.step = value; } }, metadata: _metadata }, _step_initializers, _step_extraInitializers);
180
+ __esDecorate(this, null, _largeStep_decorators, { kind: "accessor", name: "largeStep", static: false, private: false, access: { has: obj => "largeStep" in obj, get: obj => obj.largeStep, set: (obj, value) => { obj.largeStep = value; } }, metadata: _metadata }, _largeStep_initializers, _largeStep_extraInitializers);
181
+ __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);
182
+ __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);
183
+ __esDecorate(this, null, _required_decorators, { kind: "accessor", name: "required", static: false, private: false, access: { has: obj => "required" in obj, get: obj => obj.required, set: (obj, value) => { obj.required = value; } }, metadata: _metadata }, _required_initializers, _required_extraInitializers);
184
+ __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
+ __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
+ __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
+ if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
189
+ }
190
+ static tagName = "dui-stepper";
191
+ static shadowRootOptions = {
192
+ ...LitElement.shadowRootOptions,
193
+ delegatesFocus: true,
194
+ };
195
+ static styles = [base, styles];
196
+ #value_accessor_storage = __runInitializers(this, _value_initializers, undefined);
197
+ get value() { return this.#value_accessor_storage; }
198
+ set value(value) { this.#value_accessor_storage = value; }
199
+ #defaultValue_accessor_storage = (__runInitializers(this, _value_extraInitializers), __runInitializers(this, _defaultValue_initializers, undefined));
200
+ get defaultValue() { return this.#defaultValue_accessor_storage; }
201
+ set defaultValue(value) { this.#defaultValue_accessor_storage = value; }
202
+ #min_accessor_storage = (__runInitializers(this, _defaultValue_extraInitializers), __runInitializers(this, _min_initializers, undefined));
203
+ get min() { return this.#min_accessor_storage; }
204
+ set min(value) { this.#min_accessor_storage = value; }
205
+ #max_accessor_storage = (__runInitializers(this, _min_extraInitializers), __runInitializers(this, _max_initializers, undefined));
206
+ get max() { return this.#max_accessor_storage; }
207
+ set max(value) { this.#max_accessor_storage = value; }
208
+ #step_accessor_storage = (__runInitializers(this, _max_extraInitializers), __runInitializers(this, _step_initializers, 1));
209
+ get step() { return this.#step_accessor_storage; }
210
+ set step(value) { this.#step_accessor_storage = value; }
211
+ #largeStep_accessor_storage = (__runInitializers(this, _step_extraInitializers), __runInitializers(this, _largeStep_initializers, 10));
212
+ get largeStep() { return this.#largeStep_accessor_storage; }
213
+ set largeStep(value) { this.#largeStep_accessor_storage = value; }
214
+ #disabled_accessor_storage = (__runInitializers(this, _largeStep_extraInitializers), __runInitializers(this, _disabled_initializers, false));
215
+ get disabled() { return this.#disabled_accessor_storage; }
216
+ set disabled(value) { this.#disabled_accessor_storage = value; }
217
+ #readOnly_accessor_storage = (__runInitializers(this, _disabled_extraInitializers), __runInitializers(this, _readOnly_initializers, false));
218
+ get readOnly() { return this.#readOnly_accessor_storage; }
219
+ set readOnly(value) { this.#readOnly_accessor_storage = value; }
220
+ #required_accessor_storage = (__runInitializers(this, _readOnly_extraInitializers), __runInitializers(this, _required_initializers, false));
221
+ get required() { return this.#required_accessor_storage; }
222
+ set required(value) { this.#required_accessor_storage = value; }
223
+ #name_accessor_storage = (__runInitializers(this, _required_extraInitializers), __runInitializers(this, _name_initializers, undefined));
224
+ get name() { return this.#name_accessor_storage; }
225
+ set name(value) { this.#name_accessor_storage = value; }
226
+ #internalValue_accessor_storage = (__runInitializers(this, _name_extraInitializers), __runInitializers(this, _private_internalValue_initializers, undefined));
227
+ // ── Internal state ─────────────────────────────────────────────────
228
+ get #internalValue() { return _private_internalValue_descriptor.get.call(this); }
229
+ set #internalValue(value) { return _private_internalValue_descriptor.set.call(this, value); }
230
+ #inputText_accessor_storage = (__runInitializers(this, _private_internalValue_extraInitializers), __runInitializers(this, _private_inputText_initializers, ""));
231
+ get #inputText() { return _private_inputText_descriptor.get.call(this); }
232
+ 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
+ // ── Computed getters ───────────────────────────────────────────────
237
+ get #currentValue() {
238
+ return this.value ?? this.#internalValue;
239
+ }
240
+ get #isDisabled() {
241
+ return this.disabled || (this._fieldCtx?.disabled ?? false);
242
+ }
243
+ get #isInvalid() {
244
+ return this._fieldCtx?.invalid ?? false;
245
+ }
246
+ get #canDecrement() {
247
+ const v = this.#currentValue;
248
+ if (v === undefined)
249
+ return true;
250
+ return this.min === undefined || v > this.min;
251
+ }
252
+ get #canIncrement() {
253
+ const v = this.#currentValue;
254
+ if (v === undefined)
255
+ return true;
256
+ return this.max === undefined || v < this.max;
257
+ }
258
+ // ── Lifecycle ──────────────────────────────────────────────────────
259
+ connectedCallback() {
260
+ super.connectedCallback();
261
+ if (this.value === undefined && this.defaultValue !== undefined) {
262
+ this.#internalValue = this.#clamp(this.defaultValue);
263
+ }
264
+ this.#syncInputText();
265
+ }
266
+ willUpdate() {
267
+ this.#syncInputText();
268
+ }
269
+ // ── Value helpers ──────────────────────────────────────────────────
270
+ #syncInputText() {
271
+ const v = this.#currentValue;
272
+ this.#inputText = v !== undefined ? String(v) : "";
273
+ }
274
+ #clamp(val) {
275
+ if (this.min !== undefined)
276
+ val = Math.max(this.min, val);
277
+ if (this.max !== undefined)
278
+ val = Math.min(this.max, val);
279
+ return val;
280
+ }
281
+ #setValue(val) {
282
+ const clamped = this.#clamp(val);
283
+ if (this.value === undefined) {
284
+ this.#internalValue = clamped;
285
+ }
286
+ this._fieldCtx?.markDirty();
287
+ this._fieldCtx?.setFilled(true);
288
+ this.dispatchEvent(valueChangeEvent({ value: clamped }));
289
+ }
290
+ #increment = (__runInitializers(this, __fieldCtx_extraInitializers), (amount) => {
291
+ if (this.#isDisabled || this.readOnly)
292
+ return;
293
+ const current = this.#currentValue ?? this.min ?? 0;
294
+ this.#setValue(current + amount);
295
+ });
296
+ #decrement = (amount) => {
297
+ if (this.#isDisabled || this.readOnly)
298
+ return;
299
+ const current = this.#currentValue ?? this.max ?? 0;
300
+ this.#setValue(current - amount);
301
+ };
302
+ #commitInput() {
303
+ const parsed = parseFloat(this.#inputText);
304
+ if (Number.isNaN(parsed)) {
305
+ this.#syncInputText();
306
+ }
307
+ else {
308
+ this.#setValue(parsed);
309
+ }
310
+ const v = this.#currentValue;
311
+ if (v !== undefined) {
312
+ this.dispatchEvent(valueCommittedEvent({ value: v }));
313
+ }
314
+ }
315
+ // ── Event handlers ─────────────────────────────────────────────────
316
+ #onInput = (e) => {
317
+ this.#inputText = e.target.value;
318
+ };
319
+ #onBlur = () => {
320
+ this.#commitInput();
321
+ this._fieldCtx?.setFocused(false);
322
+ this._fieldCtx?.markTouched();
323
+ };
324
+ #onFocus = () => {
325
+ this._fieldCtx?.setFocused(true);
326
+ };
327
+ #onKeyDown = (e) => {
328
+ switch (e.key) {
329
+ case "ArrowUp":
330
+ e.preventDefault();
331
+ this.#increment(e.shiftKey ? this.largeStep : this.step);
332
+ this.#syncInputText();
333
+ break;
334
+ case "ArrowDown":
335
+ e.preventDefault();
336
+ this.#decrement(e.shiftKey ? this.largeStep : this.step);
337
+ this.#syncInputText();
338
+ break;
339
+ case "Home":
340
+ if (this.min !== undefined) {
341
+ e.preventDefault();
342
+ this.#setValue(this.min);
343
+ }
344
+ break;
345
+ case "End":
346
+ if (this.max !== undefined) {
347
+ e.preventDefault();
348
+ this.#setValue(this.max);
349
+ }
350
+ break;
351
+ case "Enter":
352
+ this.#commitInput();
353
+ break;
354
+ }
355
+ };
356
+ #onDecrementClick = () => {
357
+ this.#decrement(this.step);
358
+ const v = this.#currentValue;
359
+ if (v !== undefined) {
360
+ this.dispatchEvent(valueCommittedEvent({ value: v }));
361
+ }
362
+ };
363
+ #onIncrementClick = () => {
364
+ this.#increment(this.step);
365
+ const v = this.#currentValue;
366
+ if (v !== undefined) {
367
+ this.dispatchEvent(valueCommittedEvent({ value: v }));
368
+ }
369
+ };
370
+ // ── Render ─────────────────────────────────────────────────────────
371
+ render() {
372
+ const isDisabled = this.#isDisabled;
373
+ const isInvalid = this.#isInvalid;
374
+ const controlId = this._fieldCtx?.controlId ?? "";
375
+ const currentValue = this.#currentValue;
376
+ return html `
377
+ <div
378
+ part="root"
379
+ ?data-disabled="${isDisabled}"
380
+ ?data-invalid="${isInvalid}"
381
+ >
382
+ <button
383
+ part="decrement"
384
+ type="button"
385
+ tabindex="-1"
386
+ aria-label="Decrease"
387
+ ?disabled="${isDisabled || this.readOnly || !this.#canDecrement}"
388
+ @click="${this.#onDecrementClick}"
389
+ >
390
+ <slot name="decrement">&minus;</slot>
391
+ </button>
392
+ <input
393
+ part="input"
394
+ id="${controlId || nothing}"
395
+ type="text"
396
+ inputmode="decimal"
397
+ .value="${live(this.#inputText)}"
398
+ ?disabled="${isDisabled}"
399
+ ?readonly="${this.readOnly}"
400
+ ?required="${this.required}"
401
+ aria-invalid="${isInvalid ? "true" : nothing}"
402
+ ?data-disabled="${isDisabled}"
403
+ @input="${this.#onInput}"
404
+ @keydown="${this.#onKeyDown}"
405
+ @focus="${this.#onFocus}"
406
+ @blur="${this.#onBlur}"
407
+ />
408
+ <button
409
+ part="increment"
410
+ type="button"
411
+ tabindex="-1"
412
+ aria-label="Increase"
413
+ ?disabled="${isDisabled || this.readOnly || !this.#canIncrement}"
414
+ @click="${this.#onIncrementClick}"
415
+ >
416
+ <slot name="increment">+</slot>
417
+ </button>
418
+ ${this.name
419
+ ? html `<input
420
+ type="hidden"
421
+ name="${this.name}"
422
+ .value="${String(currentValue ?? "")}"
423
+ />`
424
+ : nothing}
425
+ </div>
426
+ `;
427
+ }
428
+ };
429
+ })();
430
+ export { DuiStepper };