@c2n/number-input 0.0.8

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Nguyen Thai Vinh
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,11 @@
1
+ # Number Input
2
+
3
+ A form-associated, themeable numeric input with consistent step controls.
4
+
5
+ ```bash
6
+ npm install @c2n/number-input
7
+ ```
8
+
9
+ ```html
10
+ <c2-number-input name="quantity" value="1" min="0" max="10" aria-label="Quantity"></c2-number-input>
11
+ ```
@@ -0,0 +1,291 @@
1
+ import { LitElement, html, nothing, unsafeCSS } from "lit";
2
+ import { property, query, state } from "lit/decorators.js";
3
+ import { customElement } from "@c2n/core/element-helper.js";
4
+ import { redispatchEvent } from "@c2n/core/dom-helper.js";
5
+ import { classMap } from "lit/directives/class-map.js";
6
+ import { ifDefined } from "lit/directives/if-defined.js";
7
+ import { live } from "lit/directives/live.js";
8
+ //#region src/number-input.scss?inline
9
+ var number_input_default = "/* ex : var((width: 24px), width, c2-checkbox) returns var(--c2-checkbox-width, 24px) */\n:host {\n display: inline-flex;\n flex-direction: column;\n gap: var(--c2-number-input__supporting-text--gap,4px);\n vertical-align: middle;\n}\n\n:host([hidden]) {\n display: none;\n}\n\n.field {\n display: flex;\n box-sizing: border-box;\n min-height: var(--c2-number-input--min-height,36px);\n overflow: hidden;\n border: var(--c2-number-input--border,1px solid #bcbcc6);\n border-radius: var(--c2-number-input--border-radius,6px);\n color: var(--c2-number-input--color,#18181b);\n background: var(--c2-number-input--background,#ffffff);\n font-size: var(--c2-number-input--font-size,14px);\n font-family: var(--c2-number-input--font-family,inherit);\n line-height: var(--c2-number-input--line-height,20px);\n cursor: text;\n outline: var(--c2-number-input__focus--outline,2px solid rgba(2, 101, 220, 0.4));\n outline-color: transparent;\n outline-offset: var(--c2-number-input__focus--outline-offset,0px);\n transition: border 250ms cubic-bezier(0.2, 0, 0, 1), background 250ms cubic-bezier(0.2, 0, 0, 1), outline-color 250ms cubic-bezier(0.2, 0, 0, 1);\n}\n.field:hover {\n border: var(--c2-number-input__hover--border,1px solid #a1a1aa);\n}\n.field.focused {\n border: var(--c2-number-input__focus--border,1px solid #0265dc);\n outline: var(--c2-number-input__focus--outline,2px solid rgba(2, 101, 220, 0.4));\n outline-offset: var(--c2-number-input__focus--outline-offset,0px);\n}\n.field.error {\n border: var(--c2-number-input__error--border,1px solid #dc2626);\n}\n.field.error.focused {\n outline: var(--c2-number-input__error__focus--outline,2px solid rgba(220, 38, 38, 0.25));\n}\n.field.read-only {\n cursor: default;\n background: var(--c2-number-input__read-only--background,#fafafa);\n}\n.field.disabled {\n cursor: default;\n opacity: var(--c2-number-input__disabled--opacity,0.38);\n pointer-events: none;\n}\n\n.value-area {\n display: flex;\n flex: 1;\n min-width: 0;\n align-items: center;\n gap: var(--c2-number-input__value--gap,8px);\n padding: var(--c2-number-input__value--padding,6px 10px 6px 12px);\n}\n\ninput {\n flex: 1;\n min-width: 0;\n width: 8ch;\n margin: 0;\n padding: 0;\n border: 0;\n outline: 0;\n color: inherit;\n background: transparent;\n font: inherit;\n line-height: inherit;\n appearance: textfield;\n}\ninput::placeholder {\n color: var(--c2-number-input__placeholder--color,#71717a);\n opacity: 1;\n}\ninput::-webkit-inner-spin-button, input::-webkit-outer-spin-button {\n margin: 0;\n appearance: none;\n}\n\n::slotted([slot=prefix]),\n::slotted([slot=suffix]) {\n flex: none;\n color: var(--c2-number-input__adornment--color,#71717a);\n font-size: var(--c2-number-input__adornment--font-size,14px);\n}\n\n.steppers {\n display: grid;\n flex: 0 0 var(--c2-number-input__stepper--width,28px);\n grid-template-rows: 1fr 1fr;\n border-left: var(--c2-number-input__stepper--border-left,1px solid #e4e4e7);\n}\n\n.stepper {\n display: grid;\n min-width: 0;\n margin: 0;\n padding: 0;\n place-items: center;\n border: 0;\n color: var(--c2-number-input__stepper--color,#71717a);\n background: transparent;\n cursor: pointer;\n}\n.stepper:hover:not(:disabled) {\n color: var(--c2-number-input__stepper__hover--color,#18181b);\n background: var(--c2-number-input__stepper__hover--background,#f4f4f5);\n}\n.stepper:disabled {\n cursor: default;\n opacity: 0.38;\n}\n\n.stepper.up {\n border-bottom: var(--c2-number-input__stepper--border-left,1px solid #e4e4e7);\n}\n\n.stepper svg,\n::slotted([slot=decrement-icon]),\n::slotted([slot=increment-icon]) {\n width: var(--c2-number-input__stepper-icon--size,14px);\n height: var(--c2-number-input__stepper-icon--size,14px);\n}\n\n.supporting-text {\n color: var(--c2-number-input__supporting-text--color,#71717a);\n font-size: var(--c2-number-input__supporting-text--font-size,12px);\n line-height: var(--c2-number-input__supporting-text--line-height,16px);\n}\n.supporting-text.error {\n color: var(--c2-number-input__supporting-text__error--color,#dc2626);\n}";
10
+ //#endregion
11
+ //#region \0@oxc-project+runtime@0.148.0/helpers/esm/decorate.js
12
+ function __decorate(decorators, target, key, desc) {
13
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
14
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
15
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
16
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
17
+ }
18
+ //#endregion
19
+ //#region src/number-input.ts
20
+ var NumberInput = class NumberInput extends LitElement {
21
+ constructor(..._args) {
22
+ super(..._args);
23
+ this.internals = this.attachInternals();
24
+ this.customValidityMessage = "";
25
+ this.defaultValue = "";
26
+ this.defaultCaptured = false;
27
+ this.disabledByForm = false;
28
+ this.focused = false;
29
+ this.hasSupportingSlot = false;
30
+ this.value = "";
31
+ this.step = "1";
32
+ this.name = "";
33
+ this.autocomplete = "";
34
+ this.placeholder = "";
35
+ this.required = false;
36
+ this.readOnly = false;
37
+ this.disabled = false;
38
+ this.hideSteppers = false;
39
+ this.error = false;
40
+ this.help = "";
41
+ this.errorText = "";
42
+ this.ariaLabel = null;
43
+ }
44
+ static {
45
+ this.formAssociated = true;
46
+ }
47
+ static {
48
+ this.styles = unsafeCSS(number_input_default);
49
+ }
50
+ get form() {
51
+ return this.internals.form;
52
+ }
53
+ get labels() {
54
+ return this.internals.labels;
55
+ }
56
+ get validity() {
57
+ return this.internals.validity;
58
+ }
59
+ get validationMessage() {
60
+ return this.internals.validationMessage;
61
+ }
62
+ get willValidate() {
63
+ return this.internals.willValidate;
64
+ }
65
+ /** Parsed value, or `NaN` when empty. */
66
+ get valueAsNumber() {
67
+ return this.input?.valueAsNumber ?? NaN;
68
+ }
69
+ connectedCallback() {
70
+ super.connectedCallback();
71
+ if (!this.defaultCaptured) {
72
+ this.defaultValue = this.getAttribute("value") ?? "";
73
+ this.defaultCaptured = true;
74
+ }
75
+ }
76
+ focus(options) {
77
+ this.input?.focus(options);
78
+ }
79
+ /** Selects the numeric text. */
80
+ select() {
81
+ this.input?.select();
82
+ }
83
+ /** Increases the value by `step` a given number of times. */
84
+ stepUp(amount = 1) {
85
+ this.stepBy(Math.max(1, Math.trunc(amount)));
86
+ }
87
+ /** Decreases the value by `step` a given number of times. */
88
+ stepDown(amount = 1) {
89
+ this.stepBy(-Math.max(1, Math.trunc(amount)));
90
+ }
91
+ checkValidity() {
92
+ return this.internals.checkValidity();
93
+ }
94
+ reportValidity() {
95
+ return this.internals.reportValidity();
96
+ }
97
+ setCustomValidity(message) {
98
+ this.customValidityMessage = message;
99
+ this.input?.setCustomValidity(message);
100
+ this.syncFormState();
101
+ }
102
+ formResetCallback() {
103
+ this.value = this.defaultValue;
104
+ this.error = false;
105
+ }
106
+ formDisabledCallback(disabled) {
107
+ this.disabledByForm = disabled && !this.hasAttribute("disabled");
108
+ }
109
+ formStateRestoreCallback(state) {
110
+ if (typeof state === "string") this.value = state;
111
+ }
112
+ get effectiveDisabled() {
113
+ return this.disabled || this.disabledByForm;
114
+ }
115
+ get steppersDisabled() {
116
+ return this.effectiveDisabled || this.readOnly || this.step === "any";
117
+ }
118
+ get atMinimum() {
119
+ const value = Number(this.value);
120
+ return this.value !== "" && this.min !== void 0 && Number.isFinite(value) && value <= this.min;
121
+ }
122
+ get atMaximum() {
123
+ const value = Number(this.value);
124
+ return this.value !== "" && this.max !== void 0 && Number.isFinite(value) && value >= this.max;
125
+ }
126
+ handleInput(event) {
127
+ this.value = event.target.value;
128
+ redispatchEvent(this, event);
129
+ }
130
+ handleChange(event) {
131
+ this.value = event.target.value;
132
+ redispatchEvent(this, event);
133
+ }
134
+ handleFocusIn(event) {
135
+ this.focused = true;
136
+ redispatchEvent(this, event);
137
+ }
138
+ handleFocusOut(event) {
139
+ this.focused = false;
140
+ redispatchEvent(this, event);
141
+ }
142
+ handleSlotChange(event) {
143
+ this.hasSupportingSlot = event.target.assignedNodes({ flatten: true }).length > 0;
144
+ }
145
+ keepInputFocus(event) {
146
+ event.preventDefault();
147
+ }
148
+ forwardFocus(event) {
149
+ if (!event.target.closest(".stepper")) this.input?.focus();
150
+ }
151
+ stepBy(amount) {
152
+ if (!this.input || this.steppersDisabled) return;
153
+ if (amount > 0) this.input.stepUp(amount);
154
+ else this.input.stepDown(-amount);
155
+ this.value = this.input.value;
156
+ this.input.focus();
157
+ this.dispatchEvent(new InputEvent("input", {
158
+ bubbles: true,
159
+ composed: true,
160
+ inputType: "insertReplacementText"
161
+ }));
162
+ this.dispatchEvent(new Event("change", {
163
+ bubbles: true,
164
+ composed: true
165
+ }));
166
+ }
167
+ updated(changed) {
168
+ if (changed.has("value") && this.input && this.input.value !== this.value) {
169
+ this.value = this.input.value;
170
+ return;
171
+ }
172
+ this.syncFormState();
173
+ }
174
+ syncFormState() {
175
+ if (!this.input) return;
176
+ if (this.effectiveDisabled) {
177
+ this.internals.setFormValue(null);
178
+ this.internals.setValidity({});
179
+ return;
180
+ }
181
+ this.internals.setFormValue(this.value, this.value);
182
+ this.input.setCustomValidity(this.customValidityMessage);
183
+ this.internals.setValidity(this.input.validity, this.input.validationMessage, this.input);
184
+ }
185
+ renderStepper(direction) {
186
+ const down = direction === "down";
187
+ const disabled = this.steppersDisabled || (down ? this.atMinimum : this.atMaximum);
188
+ return html`<button
189
+ class="stepper ${direction}"
190
+ type="button"
191
+ tabindex="-1"
192
+ aria-label=${down ? "Decrease value" : "Increase value"}
193
+ ?disabled=${disabled}
194
+ @pointerdown=${this.keepInputFocus}
195
+ @click=${() => down ? this.stepDown() : this.stepUp()}
196
+ >
197
+ <slot name=${down ? "decrement-icon" : "increment-icon"}>
198
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true">
199
+ <path d=${down ? "M5 12h14" : "M12 5v14M5 12h14"}></path>
200
+ </svg>
201
+ </slot>
202
+ </button>`;
203
+ }
204
+ render() {
205
+ const showError = this.error && !this.effectiveDisabled;
206
+ const message = showError ? this.errorText : this.help;
207
+ const showSupporting = !!message || this.hasSupportingSlot;
208
+ return html`
209
+ <div
210
+ class="field ${classMap({
211
+ focused: this.focused,
212
+ error: showError,
213
+ "read-only": this.readOnly,
214
+ disabled: this.effectiveDisabled
215
+ })}"
216
+ @click=${this.forwardFocus}
217
+ >
218
+ <div class="value-area">
219
+ <slot name="prefix"></slot>
220
+ <input
221
+ type="number"
222
+ inputmode="decimal"
223
+ aria-label=${ifDefined(this.ariaLabel || void 0)}
224
+ aria-invalid=${showError ? "true" : nothing}
225
+ aria-describedby=${showSupporting ? "supporting-text" : nothing}
226
+ name=${ifDefined(this.name || void 0)}
227
+ autocomplete=${ifDefined(this.autocomplete || void 0)}
228
+ min=${ifDefined(this.min)}
229
+ max=${ifDefined(this.max)}
230
+ step=${this.step}
231
+ placeholder=${this.placeholder || nothing}
232
+ ?required=${this.required}
233
+ ?readonly=${this.readOnly}
234
+ ?disabled=${this.effectiveDisabled}
235
+ .value=${live(this.value)}
236
+ @input=${this.handleInput}
237
+ @change=${this.handleChange}
238
+ @focusin=${this.handleFocusIn}
239
+ @focusout=${this.handleFocusOut}
240
+ />
241
+ <slot name="suffix"></slot>
242
+ </div>
243
+ ${this.hideSteppers ? nothing : html`<div class="steppers">${this.renderStepper("up")}${this.renderStepper("down")}</div>`}
244
+ </div>
245
+ ${showSupporting ? html`<div id="supporting-text" class="supporting-text ${classMap({ error: showError })}">
246
+ <slot name="supporting-text" @slotchange=${this.handleSlotChange}>${message}</slot>
247
+ </div>` : html`<slot name="supporting-text" hidden @slotchange=${this.handleSlotChange}></slot>`}
248
+ `;
249
+ }
250
+ };
251
+ __decorate([state()], NumberInput.prototype, "disabledByForm", void 0);
252
+ __decorate([state()], NumberInput.prototype, "focused", void 0);
253
+ __decorate([state()], NumberInput.prototype, "hasSupportingSlot", void 0);
254
+ __decorate([query("input")], NumberInput.prototype, "input", void 0);
255
+ __decorate([property({
256
+ type: String,
257
+ reflect: true
258
+ })], NumberInput.prototype, "value", void 0);
259
+ __decorate([property({ type: Number })], NumberInput.prototype, "min", void 0);
260
+ __decorate([property({ type: Number })], NumberInput.prototype, "max", void 0);
261
+ __decorate([property({ type: String })], NumberInput.prototype, "step", void 0);
262
+ __decorate([property({ type: String })], NumberInput.prototype, "name", void 0);
263
+ __decorate([property({ type: String })], NumberInput.prototype, "autocomplete", void 0);
264
+ __decorate([property({ type: String })], NumberInput.prototype, "placeholder", void 0);
265
+ __decorate([property({
266
+ type: Boolean,
267
+ reflect: true
268
+ })], NumberInput.prototype, "required", void 0);
269
+ __decorate([property({
270
+ type: Boolean,
271
+ reflect: true
272
+ })], NumberInput.prototype, "readOnly", void 0);
273
+ __decorate([property({
274
+ type: Boolean,
275
+ reflect: true
276
+ })], NumberInput.prototype, "disabled", void 0);
277
+ __decorate([property({
278
+ type: Boolean,
279
+ reflect: true,
280
+ attribute: "hide-steppers"
281
+ })], NumberInput.prototype, "hideSteppers", void 0);
282
+ __decorate([property({
283
+ type: Boolean,
284
+ reflect: true
285
+ })], NumberInput.prototype, "error", void 0);
286
+ __decorate([property({ type: String })], NumberInput.prototype, "help", void 0);
287
+ __decorate([property({ attribute: "error-text" })], NumberInput.prototype, "errorText", void 0);
288
+ __decorate([property({ attribute: "aria-label" })], NumberInput.prototype, "ariaLabel", void 0);
289
+ NumberInput = __decorate([customElement("c2-number-input")], NumberInput);
290
+ //#endregion
291
+ export { NumberInput };
package/package.json ADDED
@@ -0,0 +1,73 @@
1
+ {
2
+ "name": "@c2n/number-input",
3
+ "version": "0.0.8",
4
+ "type": "module",
5
+ "main": "dist/number-input.js",
6
+ "exports": {
7
+ ".": {
8
+ "types": "./types/src/number-input.d.ts",
9
+ "default": "./dist/number-input.js"
10
+ },
11
+ "./react": {
12
+ "types": "./react.d.ts",
13
+ "default": "./react.js"
14
+ },
15
+ "./vue": {
16
+ "types": "./vue.d.ts",
17
+ "default": "./vue.js"
18
+ },
19
+ "./custom-elements.json": "./custom-elements.json"
20
+ },
21
+ "files": [
22
+ "dist",
23
+ "types",
24
+ "react.d.ts",
25
+ "react.js",
26
+ "vue.d.ts",
27
+ "vue.js"
28
+ ],
29
+ "keywords": [
30
+ "number-input",
31
+ "web component",
32
+ "lit"
33
+ ],
34
+ "license": "MIT",
35
+ "author": "code2nguyen@gmail.com",
36
+ "publishConfig": {
37
+ "registry": "https://registry.npmjs.org",
38
+ "access": "public"
39
+ },
40
+ "repository": {
41
+ "type": "git",
42
+ "url": "https://github.com/code2nguyen/web-components.git"
43
+ },
44
+ "scripts": {
45
+ "dev": "vite",
46
+ "build": "wireit",
47
+ "build:only": "vite build",
48
+ "type-check": "wireit"
49
+ },
50
+ "wireit": {
51
+ "type-check": {
52
+ "dependencies": [
53
+ "../../core:build"
54
+ ],
55
+ "command": "tsc -p tsconfig.lib.json --composite false"
56
+ },
57
+ "build": {
58
+ "dependencies": [
59
+ "type-check"
60
+ ],
61
+ "command": "vite build"
62
+ }
63
+ },
64
+ "dependencies": {
65
+ "@c2n/core": "0.0.8",
66
+ "lit": "3.3.3"
67
+ },
68
+ "devDependencies": {
69
+ "@c2n/config": "*"
70
+ },
71
+ "customElements": "custom-elements.json",
72
+ "gitHead": "be59cbccee1d33ca248e39f69b05c0b595ec6c6d"
73
+ }
package/react.d.ts ADDED
@@ -0,0 +1,24 @@
1
+ // GENERATED by @c2n/framework-types. Do not edit by hand.
2
+ //
3
+ // JSX types for the custom elements of @c2n/number-input. Import once, anywhere in the program:
4
+ //
5
+ // import '@c2n/number-input/react'
6
+ //
7
+ // Register the elements at module scope before React renders, or React writes an object prop as an
8
+ // attribute and it stringifies.
9
+
10
+ import type { DetailedHTMLProps, HTMLAttributes } from 'react'
11
+ import type { NumberInput } from '@c2n/number-input'
12
+
13
+ /** Standard React host-element attributes plus the element's own public properties. */
14
+ type C2Props<T> = DetailedHTMLProps<HTMLAttributes<T>, T> & Partial<Omit<T, keyof HTMLElement>>
15
+
16
+ declare module 'react' {
17
+ namespace JSX {
18
+ interface IntrinsicElements {
19
+ 'c2-number-input': C2Props<NumberInput>
20
+ }
21
+ }
22
+ }
23
+
24
+ export {}
package/react.js ADDED
@@ -0,0 +1,3 @@
1
+ // GENERATED by @c2n/framework-types. Do not edit by hand.
2
+ // Types only — see the matching .d.ts.
3
+ export {}
@@ -0,0 +1,145 @@
1
+ import { LitElement, type PropertyValues } from 'lit';
2
+ import type { TypedAddEventListener, TypedRemoveEventListener } from '@c2n/core/event-helper.js';
3
+ /** Events fired by {@link NumberInput}, keyed for `addEventListener`. */
4
+ export interface NumberInputEventMap {
5
+ input: InputEvent;
6
+ change: Event;
7
+ }
8
+ export interface NumberInput {
9
+ addEventListener: TypedAddEventListener<NumberInput, NumberInputEventMap>;
10
+ removeEventListener: TypedRemoveEventListener<NumberInput, NumberInputEventMap>;
11
+ }
12
+ /**
13
+ * A form-associated number field backed by a native `<input type="number">`. It keeps native decimal parsing,
14
+ * validation and Arrow Up/Down behavior, replaces browser-specific spinners with themeable decrement/increment
15
+ * controls, and supports prefix/suffix adornments, helper text and an error state.
16
+ *
17
+ * @tag c2-number-input
18
+ *
19
+ * @slot prefix - Currency symbol or other adornment before the value.
20
+ * @slot suffix - Unit or other adornment after the value.
21
+ * @slot decrement-icon - Replaces the minus icon in the decrement control.
22
+ * @slot increment-icon - Replaces the plus icon in the increment control.
23
+ * @slot supporting-text - Rich helper content below the field. `help` and `error-text` are plain-text shortcuts.
24
+ *
25
+ * @event {InputEvent} input - Re-dispatched when typing or stepping changes the value.
26
+ * @event {Event} change - Re-dispatched when a typed value is committed or a step control changes the value.
27
+ *
28
+ * @cssproperty {pixel} [--c2-number-input--min-height=36px]
29
+ * @cssproperty {border} [--c2-number-input--border=1px solid #bcbcc6]
30
+ * @cssproperty {border-radius} [--c2-number-input--border-radius=6px]
31
+ * @cssproperty {color} [--c2-number-input--color=#18181b]
32
+ * @cssproperty {color} [--c2-number-input--background=#ffffff]
33
+ * @cssproperty {font-size} [--c2-number-input--font-size=14px]
34
+ * @cssproperty {font-family} [--c2-number-input--font-family=inherit]
35
+ * @cssproperty {pixel} [--c2-number-input--line-height=20px]
36
+ * @cssproperty {padding} [--c2-number-input__value--padding=6px 10px 6px 12px]
37
+ * @cssproperty {pixel} [--c2-number-input__value--gap=8px]
38
+ * @cssproperty {color} [--c2-number-input__placeholder--color=#71717a]
39
+ * @cssproperty {border} [--c2-number-input__hover--border=1px solid #a1a1aa]
40
+ * @cssproperty {border} [--c2-number-input__focus--border=1px solid #0265dc]
41
+ * @cssproperty {outline} [--c2-number-input__focus--outline=2px solid rgba(2, 101, 220, 0.4)]
42
+ * @cssproperty {pixel} [--c2-number-input__focus--outline-offset=0px]
43
+ * @cssproperty {border} [--c2-number-input__error--border=1px solid #dc2626]
44
+ * @cssproperty {outline} [--c2-number-input__error__focus--outline=2px solid rgba(220, 38, 38, 0.25)]
45
+ * @cssproperty {color} [--c2-number-input__read-only--background=#fafafa]
46
+ * @cssproperty {opacity} [--c2-number-input__disabled--opacity=0.38]
47
+ * @cssproperty {pixel} [--c2-number-input__stepper--width=28px]
48
+ * @cssproperty {border} [--c2-number-input__stepper--border-left=1px solid #e4e4e7]
49
+ * @cssproperty {color} [--c2-number-input__stepper--color=#71717a]
50
+ * @cssproperty {color} [--c2-number-input__stepper__hover--color=#18181b]
51
+ * @cssproperty {color} [--c2-number-input__stepper__hover--background=#f4f4f5]
52
+ * @cssproperty {pixel} [--c2-number-input__stepper-icon--size=14px]
53
+ * @cssproperty {color} [--c2-number-input__adornment--color=#71717a]
54
+ * @cssproperty {font-size} [--c2-number-input__adornment--font-size=14px]
55
+ * @cssproperty {pixel} [--c2-number-input__supporting-text--gap=4px]
56
+ * @cssproperty {font-size} [--c2-number-input__supporting-text--font-size=12px]
57
+ * @cssproperty {pixel} [--c2-number-input__supporting-text--line-height=16px]
58
+ * @cssproperty {color} [--c2-number-input__supporting-text--color=#71717a]
59
+ * @cssproperty {color} [--c2-number-input__supporting-text__error--color=#dc2626]
60
+ */
61
+ export declare class NumberInput extends LitElement {
62
+ static formAssociated: boolean;
63
+ static styles: import("lit").CSSResult;
64
+ private readonly internals;
65
+ private customValidityMessage;
66
+ private defaultValue;
67
+ private defaultCaptured;
68
+ private disabledByForm;
69
+ private focused;
70
+ private hasSupportingSlot;
71
+ private readonly input?;
72
+ /** Current numeric text, or an empty string. Use `valueAsNumber` for a parsed value. */
73
+ value: string;
74
+ /** Minimum valid value. */
75
+ min?: number;
76
+ /** Maximum valid value. */
77
+ max?: number;
78
+ /** Increment used by Arrow keys and the step controls, or `any` to disable step controls. */
79
+ step: string;
80
+ /** Form field name. */
81
+ name: string;
82
+ /** Browser autocomplete hint. */
83
+ autocomplete: string;
84
+ /** Text shown while the field is empty. */
85
+ placeholder: string;
86
+ /** Requires a number before the form can be submitted. */
87
+ required: boolean;
88
+ /** Prevents editing while keeping the value in form submission. */
89
+ readOnly: boolean;
90
+ /** Prevents interaction and excludes the value from form submission. */
91
+ disabled: boolean;
92
+ /** Hides the decrement and increment controls. */
93
+ hideSteppers: boolean;
94
+ /** Applies the visual error state and sets `aria-invalid`. */
95
+ error: boolean;
96
+ /** Helper text shown below the field. */
97
+ help: string;
98
+ /** Message shown below the field while `error` is set. */
99
+ errorText: string;
100
+ /** Accessible name forwarded to the native number input. */
101
+ ariaLabel: string | null;
102
+ get form(): HTMLFormElement | null;
103
+ get labels(): NodeList;
104
+ get validity(): ValidityState;
105
+ get validationMessage(): string;
106
+ get willValidate(): boolean;
107
+ /** Parsed value, or `NaN` when empty. */
108
+ get valueAsNumber(): number;
109
+ connectedCallback(): void;
110
+ focus(options?: FocusOptions): void;
111
+ /** Selects the numeric text. */
112
+ select(): void;
113
+ /** Increases the value by `step` a given number of times. */
114
+ stepUp(amount?: number): void;
115
+ /** Decreases the value by `step` a given number of times. */
116
+ stepDown(amount?: number): void;
117
+ checkValidity(): boolean;
118
+ reportValidity(): boolean;
119
+ setCustomValidity(message: string): void;
120
+ formResetCallback(): void;
121
+ formDisabledCallback(disabled: boolean): void;
122
+ formStateRestoreCallback(state: string | File | FormData | null): void;
123
+ private get effectiveDisabled();
124
+ private get steppersDisabled();
125
+ private get atMinimum();
126
+ private get atMaximum();
127
+ private handleInput;
128
+ private handleChange;
129
+ private handleFocusIn;
130
+ private handleFocusOut;
131
+ private handleSlotChange;
132
+ private keepInputFocus;
133
+ private forwardFocus;
134
+ private stepBy;
135
+ protected updated(changed: PropertyValues<this>): void;
136
+ private syncFormState;
137
+ private renderStepper;
138
+ render(): import("lit-html").TemplateResult<1>;
139
+ }
140
+ declare global {
141
+ interface HTMLElementTagNameMap {
142
+ 'c2-number-input': NumberInput;
143
+ }
144
+ }
145
+ //# sourceMappingURL=number-input.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"number-input.d.ts","sourceRoot":"","sources":["../../src/number-input.ts"],"names":[],"mappings":"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"}
package/vue.d.ts ADDED
@@ -0,0 +1,37 @@
1
+ // GENERATED by @c2n/framework-types. Do not edit by hand.
2
+ //
3
+ // Vue template types for the custom elements of @c2n/number-input. Import once, anywhere in the program:
4
+ //
5
+ // import '@c2n/number-input/vue'
6
+ //
7
+ // Tell the compiler about the tags as well, or every c2-* tag is resolved as a Vue component and renders
8
+ // nothing: template.compilerOptions.isCustomElement = (tag) => tag.startsWith('c2-') in vite.config.ts.
9
+
10
+ import type { DefineComponent, HTMLAttributes } from 'vue'
11
+ import type { NumberInput, NumberInputEventMap } from '@c2n/number-input'
12
+
13
+ /** The element's own public properties, plus every attribute Vue understands on a host element. */
14
+ type C2Props<T> = Partial<Omit<T, keyof HTMLElement>> & HTMLAttributes
15
+
16
+ declare module 'vue' {
17
+ interface GlobalComponents {
18
+ 'c2-number-input': DefineComponent<
19
+ C2Props<NumberInput> & {
20
+ 'hide-steppers'?: unknown
21
+ 'error-text'?: unknown
22
+ 'aria-label'?: unknown
23
+ onInput?: (event: NumberInputEventMap['input']) => void
24
+ onChange?: (event: NumberInputEventMap['change']) => void
25
+ }
26
+ >
27
+ }
28
+ }
29
+
30
+ declare module '@vue/runtime-dom' {
31
+ interface HTMLAttributes {
32
+ /** Vue's own definition omits it, and slotting a plain element into a component needs it. */
33
+ slot?: string
34
+ }
35
+ }
36
+
37
+ export {}
package/vue.js ADDED
@@ -0,0 +1,3 @@
1
+ // GENERATED by @c2n/framework-types. Do not edit by hand.
2
+ // Types only — see the matching .d.ts.
3
+ export {}