@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.
- package/accordion/accordion-item.js +1 -0
- package/all.d.ts +80 -38
- package/all.js +84 -38
- package/collapsible/collapsible.js +1 -0
- package/number-field/index.d.ts +2 -2
- package/number-field/index.js +2 -2
- package/number-field/number-field.d.ts +24 -3
- package/number-field/number-field.js +426 -66
- package/package.json +10 -2
- package/popover/popover-trigger.d.ts +1 -0
- package/popover/popover-trigger.js +17 -0
- package/select/select.js +5 -0
- package/slider/slider.d.ts +8 -1
- package/slider/slider.js +92 -10
- package/split-button/index.d.ts +1 -0
- package/split-button/index.js +1 -0
- package/split-button/register.d.ts +1 -0
- package/split-button/register.js +4 -0
- package/split-button/split-button.d.ts +33 -0
- package/split-button/split-button.js +397 -0
- package/stepper/index.d.ts +3 -0
- package/stepper/index.js +3 -0
- package/stepper/stepper.d.ts +45 -0
- package/stepper/stepper.js +430 -0
|
@@ -44,6 +44,7 @@ import { base } from "@deepfuture/dui-core/base";
|
|
|
44
44
|
import { customEvent } from "@deepfuture/dui-core/event";
|
|
45
45
|
import { fieldContext } from "@deepfuture/dui-components/field";
|
|
46
46
|
export const valueChangeEvent = customEvent("value-change", { bubbles: true, composed: true });
|
|
47
|
+
export const valueCommittedEvent = customEvent("value-committed", { bubbles: true, composed: true });
|
|
47
48
|
/** Structural styles only — layout CSS. */
|
|
48
49
|
const styles = css `
|
|
49
50
|
:host {
|
|
@@ -51,8 +52,40 @@ const styles = css `
|
|
|
51
52
|
}
|
|
52
53
|
|
|
53
54
|
[part="root"] {
|
|
54
|
-
display:
|
|
55
|
+
display: flex;
|
|
55
56
|
align-items: center;
|
|
57
|
+
width: 100%;
|
|
58
|
+
position: relative;
|
|
59
|
+
box-sizing: border-box;
|
|
60
|
+
user-select: none;
|
|
61
|
+
-webkit-tap-highlight-color: transparent;
|
|
62
|
+
transition-property: background, box-shadow, border-color, color, opacity;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
[part="root"][data-scrub] {
|
|
66
|
+
cursor: ew-resize;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
[part="root"][data-disabled] {
|
|
70
|
+
pointer-events: none;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
[part="label"] {
|
|
74
|
+
display: flex;
|
|
75
|
+
align-items: center;
|
|
76
|
+
justify-content: center;
|
|
77
|
+
flex-shrink: 0;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
[part="label"][data-scrub] {
|
|
81
|
+
cursor: ew-resize;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
[part="icon"] {
|
|
85
|
+
display: flex;
|
|
86
|
+
align-items: center;
|
|
87
|
+
justify-content: center;
|
|
88
|
+
flex-shrink: 0;
|
|
56
89
|
}
|
|
57
90
|
|
|
58
91
|
[part="input"] {
|
|
@@ -62,32 +95,21 @@ const styles = css `
|
|
|
62
95
|
background: none;
|
|
63
96
|
font: inherit;
|
|
64
97
|
color: inherit;
|
|
65
|
-
text-align: center;
|
|
66
98
|
min-width: 0;
|
|
99
|
+
flex: 1;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
[part="input"][data-scrub] {
|
|
103
|
+
cursor: ew-resize;
|
|
67
104
|
}
|
|
68
105
|
|
|
69
106
|
[part="input"]:disabled {
|
|
70
107
|
cursor: not-allowed;
|
|
71
108
|
}
|
|
72
109
|
|
|
73
|
-
[part="
|
|
74
|
-
[part="increment"] {
|
|
75
|
-
display: inline-flex;
|
|
76
|
-
align-items: center;
|
|
77
|
-
justify-content: center;
|
|
78
|
-
cursor: pointer;
|
|
79
|
-
border: none;
|
|
80
|
-
background: none;
|
|
81
|
-
padding: 0;
|
|
82
|
-
margin: 0;
|
|
83
|
-
font: inherit;
|
|
84
|
-
color: inherit;
|
|
110
|
+
[part="unit"] {
|
|
85
111
|
flex-shrink: 0;
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
[part="decrement"]:disabled,
|
|
89
|
-
[part="increment"]:disabled {
|
|
90
|
-
cursor: not-allowed;
|
|
112
|
+
pointer-events: none;
|
|
91
113
|
}
|
|
92
114
|
|
|
93
115
|
.HiddenInput {
|
|
@@ -99,14 +121,21 @@ const styles = css `
|
|
|
99
121
|
height: 0;
|
|
100
122
|
}
|
|
101
123
|
`;
|
|
124
|
+
/** Drag threshold in px before scrub starts. */
|
|
125
|
+
const DRAG_THRESHOLD = 3;
|
|
102
126
|
/**
|
|
103
|
-
* `<dui-number-field>` — A numeric input with
|
|
127
|
+
* `<dui-number-field>` — A numeric input with optional label, icon,
|
|
128
|
+
* unit suffix, drag-to-scrub behavior, and precision formatting.
|
|
129
|
+
*
|
|
130
|
+
* For simple step-up/step-down with buttons, use `<dui-stepper>` instead.
|
|
104
131
|
*
|
|
105
132
|
* @csspart root - The outer container.
|
|
133
|
+
* @csspart label - Label text element.
|
|
134
|
+
* @csspart icon - Icon slot wrapper.
|
|
106
135
|
* @csspart input - The text input element.
|
|
107
|
-
* @csspart
|
|
108
|
-
* @csspart increment - The increment button.
|
|
136
|
+
* @csspart unit - Unit suffix element.
|
|
109
137
|
* @fires value-change - Fired when value changes. Detail: { value: number }
|
|
138
|
+
* @fires value-committed - Fired on pointerup (end of drag), blur, or Enter. Detail: { value: number }
|
|
110
139
|
*/
|
|
111
140
|
let DuiNumberField = (() => {
|
|
112
141
|
let _classSuper = LitElement;
|
|
@@ -140,6 +169,39 @@ let DuiNumberField = (() => {
|
|
|
140
169
|
let _name_decorators;
|
|
141
170
|
let _name_initializers = [];
|
|
142
171
|
let _name_extraInitializers = [];
|
|
172
|
+
let _label_decorators;
|
|
173
|
+
let _label_initializers = [];
|
|
174
|
+
let _label_extraInitializers = [];
|
|
175
|
+
let _labelPosition_decorators;
|
|
176
|
+
let _labelPosition_initializers = [];
|
|
177
|
+
let _labelPosition_extraInitializers = [];
|
|
178
|
+
let _iconPosition_decorators;
|
|
179
|
+
let _iconPosition_initializers = [];
|
|
180
|
+
let _iconPosition_extraInitializers = [];
|
|
181
|
+
let _unit_decorators;
|
|
182
|
+
let _unit_initializers = [];
|
|
183
|
+
let _unit_extraInitializers = [];
|
|
184
|
+
let _precision_decorators;
|
|
185
|
+
let _precision_initializers = [];
|
|
186
|
+
let _precision_extraInitializers = [];
|
|
187
|
+
let _scrubLabel_decorators;
|
|
188
|
+
let _scrubLabel_initializers = [];
|
|
189
|
+
let _scrubLabel_extraInitializers = [];
|
|
190
|
+
let _scrubValue_decorators;
|
|
191
|
+
let _scrubValue_initializers = [];
|
|
192
|
+
let _scrubValue_extraInitializers = [];
|
|
193
|
+
let _scrubField_decorators;
|
|
194
|
+
let _scrubField_initializers = [];
|
|
195
|
+
let _scrubField_extraInitializers = [];
|
|
196
|
+
let _clickLabel_decorators;
|
|
197
|
+
let _clickLabel_initializers = [];
|
|
198
|
+
let _clickLabel_extraInitializers = [];
|
|
199
|
+
let _clickValue_decorators;
|
|
200
|
+
let _clickValue_initializers = [];
|
|
201
|
+
let _clickValue_extraInitializers = [];
|
|
202
|
+
let _clickField_decorators;
|
|
203
|
+
let _clickField_initializers = [];
|
|
204
|
+
let _clickField_extraInitializers = [];
|
|
143
205
|
let _private_internalValue_decorators;
|
|
144
206
|
let _private_internalValue_initializers = [];
|
|
145
207
|
let _private_internalValue_extraInitializers = [];
|
|
@@ -148,6 +210,14 @@ let DuiNumberField = (() => {
|
|
|
148
210
|
let _private_inputText_initializers = [];
|
|
149
211
|
let _private_inputText_extraInitializers = [];
|
|
150
212
|
let _private_inputText_descriptor;
|
|
213
|
+
let _private_dragging_decorators;
|
|
214
|
+
let _private_dragging_initializers = [];
|
|
215
|
+
let _private_dragging_extraInitializers = [];
|
|
216
|
+
let _private_dragging_descriptor;
|
|
217
|
+
let _private_editing_decorators;
|
|
218
|
+
let _private_editing_initializers = [];
|
|
219
|
+
let _private_editing_extraInitializers = [];
|
|
220
|
+
let _private_editing_descriptor;
|
|
151
221
|
let __fieldCtx_decorators;
|
|
152
222
|
let __fieldCtx_initializers = [];
|
|
153
223
|
let __fieldCtx_extraInitializers = [];
|
|
@@ -164,8 +234,21 @@ let DuiNumberField = (() => {
|
|
|
164
234
|
_readOnly_decorators = [property({ type: Boolean, reflect: true, attribute: "read-only" })];
|
|
165
235
|
_required_decorators = [property({ type: Boolean })];
|
|
166
236
|
_name_decorators = [property()];
|
|
237
|
+
_label_decorators = [property({ reflect: true })];
|
|
238
|
+
_labelPosition_decorators = [property({ reflect: true, attribute: "label-position" })];
|
|
239
|
+
_iconPosition_decorators = [property({ reflect: true, attribute: "icon-position" })];
|
|
240
|
+
_unit_decorators = [property({ reflect: true })];
|
|
241
|
+
_precision_decorators = [property({ type: Number })];
|
|
242
|
+
_scrubLabel_decorators = [property({ type: Boolean, reflect: true, attribute: "scrub-label" })];
|
|
243
|
+
_scrubValue_decorators = [property({ type: Boolean, reflect: true, attribute: "scrub-value" })];
|
|
244
|
+
_scrubField_decorators = [property({ type: Boolean, reflect: true, attribute: "scrub-field" })];
|
|
245
|
+
_clickLabel_decorators = [property({ type: Boolean, reflect: true, attribute: "click-label" })];
|
|
246
|
+
_clickValue_decorators = [property({ type: Boolean, reflect: true, attribute: "click-value" })];
|
|
247
|
+
_clickField_decorators = [property({ type: Boolean, reflect: true, attribute: "click-field" })];
|
|
167
248
|
_private_internalValue_decorators = [state()];
|
|
168
249
|
_private_inputText_decorators = [state()];
|
|
250
|
+
_private_dragging_decorators = [state()];
|
|
251
|
+
_private_editing_decorators = [state()];
|
|
169
252
|
__fieldCtx_decorators = [consume({ context: fieldContext, subscribe: true }), state()];
|
|
170
253
|
__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);
|
|
171
254
|
__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,8 +260,21 @@ let DuiNumberField = (() => {
|
|
|
177
260
|
__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);
|
|
178
261
|
__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);
|
|
179
262
|
__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);
|
|
263
|
+
__esDecorate(this, null, _label_decorators, { kind: "accessor", name: "label", static: false, private: false, access: { has: obj => "label" in obj, get: obj => obj.label, set: (obj, value) => { obj.label = value; } }, metadata: _metadata }, _label_initializers, _label_extraInitializers);
|
|
264
|
+
__esDecorate(this, null, _labelPosition_decorators, { kind: "accessor", name: "labelPosition", static: false, private: false, access: { has: obj => "labelPosition" in obj, get: obj => obj.labelPosition, set: (obj, value) => { obj.labelPosition = value; } }, metadata: _metadata }, _labelPosition_initializers, _labelPosition_extraInitializers);
|
|
265
|
+
__esDecorate(this, null, _iconPosition_decorators, { kind: "accessor", name: "iconPosition", static: false, private: false, access: { has: obj => "iconPosition" in obj, get: obj => obj.iconPosition, set: (obj, value) => { obj.iconPosition = value; } }, metadata: _metadata }, _iconPosition_initializers, _iconPosition_extraInitializers);
|
|
266
|
+
__esDecorate(this, null, _unit_decorators, { kind: "accessor", name: "unit", static: false, private: false, access: { has: obj => "unit" in obj, get: obj => obj.unit, set: (obj, value) => { obj.unit = value; } }, metadata: _metadata }, _unit_initializers, _unit_extraInitializers);
|
|
267
|
+
__esDecorate(this, null, _precision_decorators, { kind: "accessor", name: "precision", static: false, private: false, access: { has: obj => "precision" in obj, get: obj => obj.precision, set: (obj, value) => { obj.precision = value; } }, metadata: _metadata }, _precision_initializers, _precision_extraInitializers);
|
|
268
|
+
__esDecorate(this, null, _scrubLabel_decorators, { kind: "accessor", name: "scrubLabel", static: false, private: false, access: { has: obj => "scrubLabel" in obj, get: obj => obj.scrubLabel, set: (obj, value) => { obj.scrubLabel = value; } }, metadata: _metadata }, _scrubLabel_initializers, _scrubLabel_extraInitializers);
|
|
269
|
+
__esDecorate(this, null, _scrubValue_decorators, { kind: "accessor", name: "scrubValue", static: false, private: false, access: { has: obj => "scrubValue" in obj, get: obj => obj.scrubValue, set: (obj, value) => { obj.scrubValue = value; } }, metadata: _metadata }, _scrubValue_initializers, _scrubValue_extraInitializers);
|
|
270
|
+
__esDecorate(this, null, _scrubField_decorators, { kind: "accessor", name: "scrubField", static: false, private: false, access: { has: obj => "scrubField" in obj, get: obj => obj.scrubField, set: (obj, value) => { obj.scrubField = value; } }, metadata: _metadata }, _scrubField_initializers, _scrubField_extraInitializers);
|
|
271
|
+
__esDecorate(this, null, _clickLabel_decorators, { kind: "accessor", name: "clickLabel", static: false, private: false, access: { has: obj => "clickLabel" in obj, get: obj => obj.clickLabel, set: (obj, value) => { obj.clickLabel = value; } }, metadata: _metadata }, _clickLabel_initializers, _clickLabel_extraInitializers);
|
|
272
|
+
__esDecorate(this, null, _clickValue_decorators, { kind: "accessor", name: "clickValue", static: false, private: false, access: { has: obj => "clickValue" in obj, get: obj => obj.clickValue, set: (obj, value) => { obj.clickValue = value; } }, metadata: _metadata }, _clickValue_initializers, _clickValue_extraInitializers);
|
|
273
|
+
__esDecorate(this, null, _clickField_decorators, { kind: "accessor", name: "clickField", static: false, private: false, access: { has: obj => "clickField" in obj, get: obj => obj.clickField, set: (obj, value) => { obj.clickField = value; } }, metadata: _metadata }, _clickField_initializers, _clickField_extraInitializers);
|
|
180
274
|
__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);
|
|
181
275
|
__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);
|
|
276
|
+
__esDecorate(this, _private_dragging_descriptor = { get: __setFunctionName(function () { return this.#dragging_accessor_storage; }, "#dragging", "get"), set: __setFunctionName(function (value) { this.#dragging_accessor_storage = value; }, "#dragging", "set") }, _private_dragging_decorators, { kind: "accessor", name: "#dragging", static: false, private: true, access: { has: obj => #dragging in obj, get: obj => obj.#dragging, set: (obj, value) => { obj.#dragging = value; } }, metadata: _metadata }, _private_dragging_initializers, _private_dragging_extraInitializers);
|
|
277
|
+
__esDecorate(this, _private_editing_descriptor = { get: __setFunctionName(function () { return this.#editing_accessor_storage; }, "#editing", "get"), set: __setFunctionName(function (value) { this.#editing_accessor_storage = value; }, "#editing", "set") }, _private_editing_decorators, { kind: "accessor", name: "#editing", static: false, private: true, access: { has: obj => #editing in obj, get: obj => obj.#editing, set: (obj, value) => { obj.#editing = value; } }, metadata: _metadata }, _private_editing_initializers, _private_editing_extraInitializers);
|
|
182
278
|
__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);
|
|
183
279
|
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
184
280
|
}
|
|
@@ -189,6 +285,7 @@ let DuiNumberField = (() => {
|
|
|
189
285
|
};
|
|
190
286
|
static styles = [base, styles];
|
|
191
287
|
#value_accessor_storage = __runInitializers(this, _value_initializers, undefined);
|
|
288
|
+
// ── Core properties ────────────────────────────────────────────────
|
|
192
289
|
get value() { return this.#value_accessor_storage; }
|
|
193
290
|
set value(value) { this.#value_accessor_storage = value; }
|
|
194
291
|
#defaultValue_accessor_storage = (__runInitializers(this, _value_extraInitializers), __runInitializers(this, _defaultValue_initializers, undefined));
|
|
@@ -218,15 +315,64 @@ let DuiNumberField = (() => {
|
|
|
218
315
|
#name_accessor_storage = (__runInitializers(this, _required_extraInitializers), __runInitializers(this, _name_initializers, undefined));
|
|
219
316
|
get name() { return this.#name_accessor_storage; }
|
|
220
317
|
set name(value) { this.#name_accessor_storage = value; }
|
|
221
|
-
#
|
|
318
|
+
#label_accessor_storage = (__runInitializers(this, _name_extraInitializers), __runInitializers(this, _label_initializers, ""));
|
|
319
|
+
// ── Display properties ─────────────────────────────────────────────
|
|
320
|
+
get label() { return this.#label_accessor_storage; }
|
|
321
|
+
set label(value) { this.#label_accessor_storage = value; }
|
|
322
|
+
#labelPosition_accessor_storage = (__runInitializers(this, _label_extraInitializers), __runInitializers(this, _labelPosition_initializers, ""));
|
|
323
|
+
get labelPosition() { return this.#labelPosition_accessor_storage; }
|
|
324
|
+
set labelPosition(value) { this.#labelPosition_accessor_storage = value; }
|
|
325
|
+
#iconPosition_accessor_storage = (__runInitializers(this, _labelPosition_extraInitializers), __runInitializers(this, _iconPosition_initializers, ""));
|
|
326
|
+
get iconPosition() { return this.#iconPosition_accessor_storage; }
|
|
327
|
+
set iconPosition(value) { this.#iconPosition_accessor_storage = value; }
|
|
328
|
+
#unit_accessor_storage = (__runInitializers(this, _iconPosition_extraInitializers), __runInitializers(this, _unit_initializers, ""));
|
|
329
|
+
get unit() { return this.#unit_accessor_storage; }
|
|
330
|
+
set unit(value) { this.#unit_accessor_storage = value; }
|
|
331
|
+
#precision_accessor_storage = (__runInitializers(this, _unit_extraInitializers), __runInitializers(this, _precision_initializers, undefined));
|
|
332
|
+
get precision() { return this.#precision_accessor_storage; }
|
|
333
|
+
set precision(value) { this.#precision_accessor_storage = value; }
|
|
334
|
+
#scrubLabel_accessor_storage = (__runInitializers(this, _precision_extraInitializers), __runInitializers(this, _scrubLabel_initializers, false));
|
|
335
|
+
// ── Interaction zone booleans ──────────────────────────────────────
|
|
336
|
+
get scrubLabel() { return this.#scrubLabel_accessor_storage; }
|
|
337
|
+
set scrubLabel(value) { this.#scrubLabel_accessor_storage = value; }
|
|
338
|
+
#scrubValue_accessor_storage = (__runInitializers(this, _scrubLabel_extraInitializers), __runInitializers(this, _scrubValue_initializers, false));
|
|
339
|
+
get scrubValue() { return this.#scrubValue_accessor_storage; }
|
|
340
|
+
set scrubValue(value) { this.#scrubValue_accessor_storage = value; }
|
|
341
|
+
#scrubField_accessor_storage = (__runInitializers(this, _scrubValue_extraInitializers), __runInitializers(this, _scrubField_initializers, false));
|
|
342
|
+
get scrubField() { return this.#scrubField_accessor_storage; }
|
|
343
|
+
set scrubField(value) { this.#scrubField_accessor_storage = value; }
|
|
344
|
+
#clickLabel_accessor_storage = (__runInitializers(this, _scrubField_extraInitializers), __runInitializers(this, _clickLabel_initializers, false));
|
|
345
|
+
get clickLabel() { return this.#clickLabel_accessor_storage; }
|
|
346
|
+
set clickLabel(value) { this.#clickLabel_accessor_storage = value; }
|
|
347
|
+
#clickValue_accessor_storage = (__runInitializers(this, _clickLabel_extraInitializers), __runInitializers(this, _clickValue_initializers, false));
|
|
348
|
+
get clickValue() { return this.#clickValue_accessor_storage; }
|
|
349
|
+
set clickValue(value) { this.#clickValue_accessor_storage = value; }
|
|
350
|
+
#clickField_accessor_storage = (__runInitializers(this, _clickValue_extraInitializers), __runInitializers(this, _clickField_initializers, false));
|
|
351
|
+
get clickField() { return this.#clickField_accessor_storage; }
|
|
352
|
+
set clickField(value) { this.#clickField_accessor_storage = value; }
|
|
353
|
+
#internalValue_accessor_storage = (__runInitializers(this, _clickField_extraInitializers), __runInitializers(this, _private_internalValue_initializers, undefined));
|
|
354
|
+
// ── Internal state ─────────────────────────────────────────────────
|
|
222
355
|
get #internalValue() { return _private_internalValue_descriptor.get.call(this); }
|
|
223
356
|
set #internalValue(value) { return _private_internalValue_descriptor.set.call(this, value); }
|
|
224
357
|
#inputText_accessor_storage = (__runInitializers(this, _private_internalValue_extraInitializers), __runInitializers(this, _private_inputText_initializers, ""));
|
|
225
358
|
get #inputText() { return _private_inputText_descriptor.get.call(this); }
|
|
226
359
|
set #inputText(value) { return _private_inputText_descriptor.set.call(this, value); }
|
|
227
|
-
#
|
|
360
|
+
#dragging_accessor_storage = (__runInitializers(this, _private_inputText_extraInitializers), __runInitializers(this, _private_dragging_initializers, false));
|
|
361
|
+
get #dragging() { return _private_dragging_descriptor.get.call(this); }
|
|
362
|
+
set #dragging(value) { return _private_dragging_descriptor.set.call(this, value); }
|
|
363
|
+
#editing_accessor_storage = (__runInitializers(this, _private_dragging_extraInitializers), __runInitializers(this, _private_editing_initializers, false));
|
|
364
|
+
get #editing() { return _private_editing_descriptor.get.call(this); }
|
|
365
|
+
set #editing(value) { return _private_editing_descriptor.set.call(this, value); }
|
|
366
|
+
#_fieldCtx_accessor_storage = (__runInitializers(this, _private_editing_extraInitializers), __runInitializers(this, __fieldCtx_initializers, void 0));
|
|
228
367
|
get _fieldCtx() { return this.#_fieldCtx_accessor_storage; }
|
|
229
368
|
set _fieldCtx(value) { this.#_fieldCtx_accessor_storage = value; }
|
|
369
|
+
// ── Drag state (not reactive) ──────────────────────────────────────
|
|
370
|
+
#dragStartX = (__runInitializers(this, __fieldCtx_extraInitializers), 0);
|
|
371
|
+
#dragStartValue = 0;
|
|
372
|
+
#dragStarted = false;
|
|
373
|
+
#dragPointerId = null;
|
|
374
|
+
#dragZoneAllowsClick = false;
|
|
375
|
+
// ── Computed getters ───────────────────────────────────────────────
|
|
230
376
|
get #currentValue() {
|
|
231
377
|
return this.value ?? this.#internalValue;
|
|
232
378
|
}
|
|
@@ -236,18 +382,68 @@ let DuiNumberField = (() => {
|
|
|
236
382
|
get #isInvalid() {
|
|
237
383
|
return this._fieldCtx?.invalid ?? false;
|
|
238
384
|
}
|
|
239
|
-
get #
|
|
240
|
-
const
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
385
|
+
get #inferredPrecision() {
|
|
386
|
+
const stepStr = String(this.step);
|
|
387
|
+
const dotIndex = stepStr.indexOf(".");
|
|
388
|
+
if (dotIndex === -1)
|
|
389
|
+
return 0;
|
|
390
|
+
return stepStr.length - dotIndex - 1;
|
|
244
391
|
}
|
|
245
|
-
get #
|
|
392
|
+
get #displayValue() {
|
|
246
393
|
const v = this.#currentValue;
|
|
247
394
|
if (v === undefined)
|
|
248
|
-
return
|
|
249
|
-
|
|
395
|
+
return "";
|
|
396
|
+
const p = this.precision ?? this.#inferredPrecision;
|
|
397
|
+
return v.toFixed(p);
|
|
398
|
+
}
|
|
399
|
+
/** Whether any interaction boolean is explicitly set by the consumer. */
|
|
400
|
+
get #hasExplicitInteraction() {
|
|
401
|
+
return (this.scrubLabel ||
|
|
402
|
+
this.scrubValue ||
|
|
403
|
+
this.scrubField ||
|
|
404
|
+
this.clickLabel ||
|
|
405
|
+
this.clickValue ||
|
|
406
|
+
this.clickField);
|
|
407
|
+
}
|
|
408
|
+
/** Effective scrub-label: explicit or default. */
|
|
409
|
+
get #effectiveScrubLabel() {
|
|
410
|
+
if (this.#hasExplicitInteraction)
|
|
411
|
+
return this.scrubLabel;
|
|
412
|
+
// Default: scrub on label when a label is present
|
|
413
|
+
return this.label !== "";
|
|
250
414
|
}
|
|
415
|
+
/** Effective scrub-value: explicit or default. */
|
|
416
|
+
get #effectiveScrubValue() {
|
|
417
|
+
if (this.#hasExplicitInteraction)
|
|
418
|
+
return this.scrubValue;
|
|
419
|
+
return false;
|
|
420
|
+
}
|
|
421
|
+
/** Effective scrub-field: explicit or default. */
|
|
422
|
+
get #effectiveScrubField() {
|
|
423
|
+
if (this.#hasExplicitInteraction)
|
|
424
|
+
return this.scrubField;
|
|
425
|
+
// Default: scrub on field when no label
|
|
426
|
+
return this.label === "";
|
|
427
|
+
}
|
|
428
|
+
/** Effective click-label: explicit or default. */
|
|
429
|
+
get #effectiveClickLabel() {
|
|
430
|
+
if (this.#hasExplicitInteraction)
|
|
431
|
+
return this.clickLabel;
|
|
432
|
+
return false;
|
|
433
|
+
}
|
|
434
|
+
/** Effective click-value: explicit or default. */
|
|
435
|
+
get #effectiveClickValue() {
|
|
436
|
+
if (this.#hasExplicitInteraction)
|
|
437
|
+
return this.clickValue;
|
|
438
|
+
return true;
|
|
439
|
+
}
|
|
440
|
+
/** Effective click-field: explicit or default. */
|
|
441
|
+
get #effectiveClickField() {
|
|
442
|
+
if (this.#hasExplicitInteraction)
|
|
443
|
+
return this.clickField;
|
|
444
|
+
return false;
|
|
445
|
+
}
|
|
446
|
+
// ── Lifecycle ──────────────────────────────────────────────────────
|
|
251
447
|
connectedCallback() {
|
|
252
448
|
super.connectedCallback();
|
|
253
449
|
if (this.value === undefined && this.defaultValue !== undefined) {
|
|
@@ -256,11 +452,13 @@ let DuiNumberField = (() => {
|
|
|
256
452
|
this.#syncInputText();
|
|
257
453
|
}
|
|
258
454
|
willUpdate() {
|
|
259
|
-
this.#
|
|
455
|
+
if (!this.#editing) {
|
|
456
|
+
this.#syncInputText();
|
|
457
|
+
}
|
|
260
458
|
}
|
|
459
|
+
// ── Value helpers ──────────────────────────────────────────────────
|
|
261
460
|
#syncInputText() {
|
|
262
|
-
|
|
263
|
-
this.#inputText = v !== undefined ? String(v) : "";
|
|
461
|
+
this.#inputText = this.#displayValue;
|
|
264
462
|
}
|
|
265
463
|
#clamp(val) {
|
|
266
464
|
if (this.min !== undefined)
|
|
@@ -278,12 +476,12 @@ let DuiNumberField = (() => {
|
|
|
278
476
|
this._fieldCtx?.setFilled(true);
|
|
279
477
|
this.dispatchEvent(valueChangeEvent({ value: clamped }));
|
|
280
478
|
}
|
|
281
|
-
#increment = (
|
|
479
|
+
#increment = (amount) => {
|
|
282
480
|
if (this.#isDisabled || this.readOnly)
|
|
283
481
|
return;
|
|
284
482
|
const current = this.#currentValue ?? this.min ?? 0;
|
|
285
483
|
this.#setValue(current + amount);
|
|
286
|
-
}
|
|
484
|
+
};
|
|
287
485
|
#decrement = (amount) => {
|
|
288
486
|
if (this.#isDisabled || this.readOnly)
|
|
289
487
|
return;
|
|
@@ -298,27 +496,179 @@ let DuiNumberField = (() => {
|
|
|
298
496
|
else {
|
|
299
497
|
this.#setValue(parsed);
|
|
300
498
|
}
|
|
499
|
+
this.#editing = false;
|
|
500
|
+
const v = this.#currentValue;
|
|
501
|
+
if (v !== undefined) {
|
|
502
|
+
this.dispatchEvent(valueCommittedEvent({ value: v }));
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
#focusInputAndSelectAll() {
|
|
506
|
+
const input = this.shadowRoot?.querySelector('[part="input"]');
|
|
507
|
+
if (input) {
|
|
508
|
+
this.#editing = true;
|
|
509
|
+
input.focus();
|
|
510
|
+
input.select();
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
// ── Drag-to-scrub ─────────────────────────────────────────────────
|
|
514
|
+
#startDrag(e, allowsClick) {
|
|
515
|
+
if (this.#isDisabled || this.readOnly)
|
|
516
|
+
return;
|
|
517
|
+
this.#dragPointerId = e.pointerId;
|
|
518
|
+
this.#dragStartX = e.clientX;
|
|
519
|
+
this.#dragStartValue = this.#currentValue ?? 0;
|
|
520
|
+
this.#dragStarted = false;
|
|
521
|
+
this.#dragZoneAllowsClick = allowsClick;
|
|
522
|
+
this.setPointerCapture(e.pointerId);
|
|
523
|
+
this.addEventListener("pointermove", this.#onPointerMove);
|
|
524
|
+
this.addEventListener("pointerup", this.#onPointerUp);
|
|
525
|
+
this.addEventListener("pointercancel", this.#onPointerUp);
|
|
301
526
|
}
|
|
527
|
+
#onPointerMove = (e) => {
|
|
528
|
+
if (e.pointerId !== this.#dragPointerId)
|
|
529
|
+
return;
|
|
530
|
+
const deltaX = e.clientX - this.#dragStartX;
|
|
531
|
+
if (!this.#dragStarted) {
|
|
532
|
+
if (Math.abs(deltaX) < DRAG_THRESHOLD)
|
|
533
|
+
return;
|
|
534
|
+
this.#dragStarted = true;
|
|
535
|
+
this.#dragging = true;
|
|
536
|
+
}
|
|
537
|
+
let sensitivity = this.step;
|
|
538
|
+
if (e.shiftKey) {
|
|
539
|
+
sensitivity = this.step * 0.1;
|
|
540
|
+
}
|
|
541
|
+
else if (e.ctrlKey || e.metaKey) {
|
|
542
|
+
sensitivity = this.largeStep;
|
|
543
|
+
}
|
|
544
|
+
const newValue = this.#dragStartValue + deltaX * sensitivity;
|
|
545
|
+
this.#setValue(newValue);
|
|
546
|
+
};
|
|
547
|
+
#onPointerUp = (e) => {
|
|
548
|
+
if (e.pointerId !== this.#dragPointerId)
|
|
549
|
+
return;
|
|
550
|
+
this.releasePointerCapture(e.pointerId);
|
|
551
|
+
this.removeEventListener("pointermove", this.#onPointerMove);
|
|
552
|
+
this.removeEventListener("pointerup", this.#onPointerUp);
|
|
553
|
+
this.removeEventListener("pointercancel", this.#onPointerUp);
|
|
554
|
+
if (this.#dragStarted) {
|
|
555
|
+
this.#dragging = false;
|
|
556
|
+
const v = this.#currentValue;
|
|
557
|
+
if (v !== undefined) {
|
|
558
|
+
this.dispatchEvent(valueCommittedEvent({ value: v }));
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
else if (this.#dragZoneAllowsClick) {
|
|
562
|
+
this.#focusInputAndSelectAll();
|
|
563
|
+
}
|
|
564
|
+
this.#dragPointerId = null;
|
|
565
|
+
};
|
|
566
|
+
// ── Zone pointer handlers ──────────────────────────────────────────
|
|
567
|
+
#onLabelPointerDown = (e) => {
|
|
568
|
+
if (e.button !== 0)
|
|
569
|
+
return;
|
|
570
|
+
// Field-wide flags apply to all zones
|
|
571
|
+
const allowsScrub = this.#effectiveScrubLabel || this.#effectiveScrubField;
|
|
572
|
+
const allowsClick = this.#effectiveClickLabel || this.#effectiveClickField;
|
|
573
|
+
if (allowsScrub && allowsClick) {
|
|
574
|
+
e.preventDefault();
|
|
575
|
+
this.#startDrag(e, true);
|
|
576
|
+
}
|
|
577
|
+
else if (allowsScrub) {
|
|
578
|
+
e.preventDefault();
|
|
579
|
+
this.#startDrag(e, false);
|
|
580
|
+
}
|
|
581
|
+
else if (allowsClick) {
|
|
582
|
+
e.preventDefault();
|
|
583
|
+
this.#focusInputAndSelectAll();
|
|
584
|
+
}
|
|
585
|
+
};
|
|
586
|
+
#onInputPointerDown = (e) => {
|
|
587
|
+
if (e.button !== 0)
|
|
588
|
+
return;
|
|
589
|
+
// Field-wide flags apply to all zones
|
|
590
|
+
const allowsScrub = this.#effectiveScrubValue || this.#effectiveScrubField;
|
|
591
|
+
const allowsClick = this.#effectiveClickValue || this.#effectiveClickField;
|
|
592
|
+
if (allowsScrub && allowsClick) {
|
|
593
|
+
e.preventDefault();
|
|
594
|
+
this.#startDrag(e, true);
|
|
595
|
+
}
|
|
596
|
+
else if (allowsScrub) {
|
|
597
|
+
e.preventDefault();
|
|
598
|
+
this.#startDrag(e, false);
|
|
599
|
+
}
|
|
600
|
+
else if (allowsClick) {
|
|
601
|
+
this.#editing = true;
|
|
602
|
+
}
|
|
603
|
+
};
|
|
604
|
+
#onRootPointerDown = (e) => {
|
|
605
|
+
if (e.button !== 0)
|
|
606
|
+
return;
|
|
607
|
+
// Root handler only fires for clicks on the root background itself
|
|
608
|
+
const rootEl = this.shadowRoot?.querySelector('[part="root"]');
|
|
609
|
+
if (e.target !== rootEl)
|
|
610
|
+
return;
|
|
611
|
+
const allowsScrub = this.#effectiveScrubField;
|
|
612
|
+
const allowsClick = this.#effectiveClickField;
|
|
613
|
+
if (allowsScrub && allowsClick) {
|
|
614
|
+
e.preventDefault();
|
|
615
|
+
this.#startDrag(e, true);
|
|
616
|
+
}
|
|
617
|
+
else if (allowsScrub) {
|
|
618
|
+
e.preventDefault();
|
|
619
|
+
this.#startDrag(e, false);
|
|
620
|
+
}
|
|
621
|
+
else if (allowsClick) {
|
|
622
|
+
e.preventDefault();
|
|
623
|
+
this.#focusInputAndSelectAll();
|
|
624
|
+
}
|
|
625
|
+
};
|
|
626
|
+
// ── Input event handlers ───────────────────────────────────────────
|
|
302
627
|
#onInput = (e) => {
|
|
303
628
|
this.#inputText = e.target.value;
|
|
304
629
|
};
|
|
305
630
|
#onBlur = () => {
|
|
306
|
-
this.#
|
|
631
|
+
if (this.#editing) {
|
|
632
|
+
this.#commitInput();
|
|
633
|
+
}
|
|
307
634
|
this._fieldCtx?.setFocused(false);
|
|
308
635
|
this._fieldCtx?.markTouched();
|
|
309
636
|
};
|
|
310
637
|
#onFocus = () => {
|
|
638
|
+
this.#editing = true;
|
|
311
639
|
this._fieldCtx?.setFocused(true);
|
|
640
|
+
const input = this.shadowRoot?.querySelector('[part="input"]');
|
|
641
|
+
if (input) {
|
|
642
|
+
requestAnimationFrame(() => input.select());
|
|
643
|
+
}
|
|
312
644
|
};
|
|
313
645
|
#onKeyDown = (e) => {
|
|
314
646
|
switch (e.key) {
|
|
315
647
|
case "ArrowUp":
|
|
316
648
|
e.preventDefault();
|
|
317
|
-
|
|
649
|
+
if (e.shiftKey) {
|
|
650
|
+
this.#increment(this.step * 0.1);
|
|
651
|
+
}
|
|
652
|
+
else if (e.ctrlKey || e.metaKey) {
|
|
653
|
+
this.#increment(this.largeStep);
|
|
654
|
+
}
|
|
655
|
+
else {
|
|
656
|
+
this.#increment(this.step);
|
|
657
|
+
}
|
|
658
|
+
this.#syncInputText();
|
|
318
659
|
break;
|
|
319
660
|
case "ArrowDown":
|
|
320
661
|
e.preventDefault();
|
|
321
|
-
|
|
662
|
+
if (e.shiftKey) {
|
|
663
|
+
this.#decrement(this.step * 0.1);
|
|
664
|
+
}
|
|
665
|
+
else if (e.ctrlKey || e.metaKey) {
|
|
666
|
+
this.#decrement(this.largeStep);
|
|
667
|
+
}
|
|
668
|
+
else {
|
|
669
|
+
this.#decrement(this.step);
|
|
670
|
+
}
|
|
671
|
+
this.#syncInputText();
|
|
322
672
|
break;
|
|
323
673
|
case "Home":
|
|
324
674
|
if (this.min !== undefined) {
|
|
@@ -335,61 +685,71 @@ let DuiNumberField = (() => {
|
|
|
335
685
|
case "Enter":
|
|
336
686
|
this.#commitInput();
|
|
337
687
|
break;
|
|
688
|
+
case "Escape": {
|
|
689
|
+
this.#editing = false;
|
|
690
|
+
this.#syncInputText();
|
|
691
|
+
const input = this.shadowRoot?.querySelector('[part="input"]');
|
|
692
|
+
if (input)
|
|
693
|
+
input.blur();
|
|
694
|
+
break;
|
|
695
|
+
}
|
|
338
696
|
}
|
|
339
697
|
};
|
|
340
|
-
|
|
341
|
-
this.#decrement(this.step);
|
|
342
|
-
};
|
|
343
|
-
#onIncrementClick = () => {
|
|
344
|
-
this.#increment(this.step);
|
|
345
|
-
};
|
|
698
|
+
// ── Render ─────────────────────────────────────────────────────────
|
|
346
699
|
render() {
|
|
347
700
|
const isDisabled = this.#isDisabled;
|
|
348
701
|
const isInvalid = this.#isInvalid;
|
|
349
702
|
const controlId = this._fieldCtx?.controlId ?? "";
|
|
350
703
|
const currentValue = this.#currentValue;
|
|
704
|
+
// Compute which zones are scrubbable for cursor styling
|
|
705
|
+
const labelScrub = this.#effectiveScrubLabel || this.#effectiveScrubField;
|
|
706
|
+
const inputScrub = this.#effectiveScrubValue || this.#effectiveScrubField;
|
|
707
|
+
const rootScrub = this.#effectiveScrubField;
|
|
351
708
|
return html `
|
|
709
|
+
<span
|
|
710
|
+
part="label"
|
|
711
|
+
?data-scrub="${labelScrub}"
|
|
712
|
+
@pointerdown="${this.#onLabelPointerDown}"
|
|
713
|
+
>${this.label}</span>
|
|
714
|
+
|
|
352
715
|
<div
|
|
353
716
|
part="root"
|
|
717
|
+
?data-scrub="${rootScrub}"
|
|
718
|
+
?data-dragging="${this.#dragging}"
|
|
354
719
|
?data-disabled="${isDisabled}"
|
|
720
|
+
?data-readonly="${this.readOnly}"
|
|
355
721
|
?data-invalid="${isInvalid}"
|
|
722
|
+
@pointerdown="${this.#onRootPointerDown}"
|
|
356
723
|
>
|
|
357
|
-
<
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
aria-label="Decrease"
|
|
362
|
-
?disabled="${isDisabled || this.readOnly || !this.#canDecrement}"
|
|
363
|
-
@click="${this.#onDecrementClick}"
|
|
364
|
-
>
|
|
365
|
-
<slot name="decrement">−</slot>
|
|
366
|
-
</button>
|
|
724
|
+
<span part="icon">
|
|
725
|
+
<slot name="icon"></slot>
|
|
726
|
+
</span>
|
|
727
|
+
|
|
367
728
|
<input
|
|
368
729
|
part="input"
|
|
369
730
|
id="${controlId || nothing}"
|
|
370
731
|
type="text"
|
|
371
732
|
inputmode="decimal"
|
|
733
|
+
?data-scrub="${inputScrub}"
|
|
372
734
|
.value="${live(this.#inputText)}"
|
|
373
735
|
?disabled="${isDisabled}"
|
|
374
736
|
?readonly="${this.readOnly}"
|
|
375
737
|
?required="${this.required}"
|
|
738
|
+
aria-label="${this.label || nothing}"
|
|
739
|
+
aria-valuenow="${currentValue ?? nothing}"
|
|
740
|
+
aria-valuemin="${this.min ?? nothing}"
|
|
741
|
+
aria-valuemax="${this.max ?? nothing}"
|
|
376
742
|
aria-invalid="${isInvalid ? "true" : nothing}"
|
|
377
743
|
?data-disabled="${isDisabled}"
|
|
744
|
+
@pointerdown="${this.#onInputPointerDown}"
|
|
378
745
|
@input="${this.#onInput}"
|
|
379
746
|
@keydown="${this.#onKeyDown}"
|
|
380
747
|
@focus="${this.#onFocus}"
|
|
381
748
|
@blur="${this.#onBlur}"
|
|
382
749
|
/>
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
tabindex="-1"
|
|
387
|
-
aria-label="Increase"
|
|
388
|
-
?disabled="${isDisabled || this.readOnly || !this.#canIncrement}"
|
|
389
|
-
@click="${this.#onIncrementClick}"
|
|
390
|
-
>
|
|
391
|
-
<slot name="increment">+</slot>
|
|
392
|
-
</button>
|
|
750
|
+
|
|
751
|
+
<span part="unit">${this.unit}</span>
|
|
752
|
+
|
|
393
753
|
${this.name
|
|
394
754
|
? html `<input
|
|
395
755
|
type="hidden"
|