@kumori/aurora-wui-components 0.0.306-dev4506.1 → 0.0.306-dev4506.2
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/dist/components/axebow-input/axebow-numeric-format.d.ts +15 -0
- package/dist/components/axebow-input/axebow-numeric-format.d.ts.map +1 -0
- package/dist/components/axebow-input/axebow-numeric-input.d.ts +3 -0
- package/dist/components/axebow-input/axebow-numeric-input.d.ts.map +1 -1
- package/dist/index.js +101 -24
- package/dist/index.js.map +1 -1
- package/dist/styles/axebow-theme.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface TypedNumericText {
|
|
2
|
+
text: string;
|
|
3
|
+
value: string;
|
|
4
|
+
caret: number;
|
|
5
|
+
}
|
|
6
|
+
export interface TypedNumericOptions {
|
|
7
|
+
integerOnly: boolean;
|
|
8
|
+
max: number;
|
|
9
|
+
}
|
|
10
|
+
export declare function toNumber(text: unknown): number | null;
|
|
11
|
+
export declare function formatNumericText(raw: string): string;
|
|
12
|
+
export declare function formatNumericValue(value: unknown): string;
|
|
13
|
+
export declare function sanitizeNumericText(text: string, integerOnly: boolean): string;
|
|
14
|
+
export declare function processTypedText(typed: string, caret: number, options: TypedNumericOptions): TypedNumericText;
|
|
15
|
+
//# sourceMappingURL=axebow-numeric-format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"axebow-numeric-format.d.ts","sourceRoot":"","sources":["../../../src/components/axebow-input/axebow-numeric-format.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,OAAO,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAKrD;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAQrD;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAOzD;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,GAAG,MAAM,CAS9E;AAeD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,mBAAmB,GAAG,gBAAgB,CAM7G"}
|
|
@@ -11,8 +11,11 @@ export declare class AxebowNumericInput extends AxebowInputBase {
|
|
|
11
11
|
stepAmount: number;
|
|
12
12
|
fixedField: boolean;
|
|
13
13
|
minWidth?: string;
|
|
14
|
+
private _text;
|
|
15
|
+
willUpdate(changed: PropertyValues): void;
|
|
14
16
|
updated(changed: PropertyValues): void;
|
|
15
17
|
protected handleChange(e: Event): void;
|
|
18
|
+
private _emitValue;
|
|
16
19
|
protected handleKeyDown(e: KeyboardEvent): void;
|
|
17
20
|
private _bumpValue;
|
|
18
21
|
private _renderStepper;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"axebow-numeric-input.d.ts","sourceRoot":"","sources":["../../../src/components/axebow-input/axebow-numeric-input.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,cAAc,EAAE,MAAM,KAAK,CAAC;AAGhD,OAAO,yDAAyD,CAAC;
|
|
1
|
+
{"version":3,"file":"axebow-numeric-input.d.ts","sourceRoot":"","sources":["../../../src/components/axebow-input/axebow-numeric-input.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,cAAc,EAAE,MAAM,KAAK,CAAC;AAGhD,OAAO,yDAAyD,CAAC;AAEjE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAGzD,qBACa,kBAAmB,SAAQ,eAAe;IACrD,MAAM,CAAC,MAAM,4BA6DX;IAE0B,GAAG,SAA2B;IAC9B,GAAG,SAAK;IACP,WAAW,UAAS;IAErB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,UAAQ;IACpB,UAAU,SAAK;IACd,UAAU,UAAS;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAErC,OAAO,CAAC,KAAK,CAAM;IAE5B,UAAU,CAAC,OAAO,EAAE,cAAc;IAOlC,OAAO,CAAC,OAAO,EAAE,cAAc;IAkC/B,SAAS,CAAC,YAAY,CAAC,CAAC,EAAE,KAAK;IAkB/B,OAAO,CAAC,UAAU;IAOlB,SAAS,CAAC,aAAa,CAAC,CAAC,EAAE,aAAa;IASxC,OAAO,CAAC,UAAU;IAYlB,OAAO,CAAC,cAAc;IA2BtB,MAAM;CAsBP"}
|
package/dist/index.js
CHANGED
|
@@ -30,6 +30,7 @@ var axebowTheme = css`
|
|
|
30
30
|
:host, .theme {
|
|
31
31
|
--axebow-primary: var(--color-primary, #34495e);
|
|
32
32
|
--axebow-primary-light: var(--color-primary-light, #b4cded);
|
|
33
|
+
--axebow-indigo-blue: var(--color-indigo-blue, #344966);
|
|
33
34
|
--axebow-tertiary: var(--color-tertiary, #006bff);
|
|
34
35
|
--axebow-success: var(--color-success, #0ecd9a);
|
|
35
36
|
--axebow-secondary: var(--color-secondary, #78787a);
|
|
@@ -2514,6 +2515,68 @@ var AxebowTextInput = class AxebowTextInput extends AxebowInputBase {
|
|
|
2514
2515
|
};
|
|
2515
2516
|
AxebowTextInput = __decorate([customElement("axebow-text-input")], AxebowTextInput);
|
|
2516
2517
|
//#endregion
|
|
2518
|
+
//#region src/components/axebow-input/axebow-numeric-format.ts
|
|
2519
|
+
var DECIMAL_SEPARATOR = ".";
|
|
2520
|
+
var THOUSANDS_SEPARATOR = ",";
|
|
2521
|
+
var NEGATIVE_SIGN = "-";
|
|
2522
|
+
var SIGNIFICANT_CHARACTER = /[\d.-]/;
|
|
2523
|
+
function toNumber(text) {
|
|
2524
|
+
const normalized = String(text ?? "").replace(/,/g, "").trim();
|
|
2525
|
+
if (normalized === "") return null;
|
|
2526
|
+
const parsed = Number(normalized);
|
|
2527
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
2528
|
+
}
|
|
2529
|
+
function formatNumericText(raw) {
|
|
2530
|
+
const negative = raw.startsWith(NEGATIVE_SIGN);
|
|
2531
|
+
const unsigned = negative ? raw.slice(1) : raw;
|
|
2532
|
+
const separatorIndex = unsigned.indexOf(DECIMAL_SEPARATOR);
|
|
2533
|
+
const integerPart = separatorIndex === -1 ? unsigned : unsigned.slice(0, separatorIndex);
|
|
2534
|
+
const fractionPart = separatorIndex === -1 ? "" : unsigned.slice(separatorIndex);
|
|
2535
|
+
const grouped = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, THOUSANDS_SEPARATOR);
|
|
2536
|
+
return `${negative ? NEGATIVE_SIGN : ""}${grouped}${fractionPart}`;
|
|
2537
|
+
}
|
|
2538
|
+
function formatNumericValue(value) {
|
|
2539
|
+
const text = String(value ?? "").trim();
|
|
2540
|
+
if (text === "") return "";
|
|
2541
|
+
if (/^-?\d*\.?\d*$/.test(text)) return formatNumericText(text);
|
|
2542
|
+
const parsed = toNumber(text);
|
|
2543
|
+
if (parsed === null) return "";
|
|
2544
|
+
return formatNumericText(parsed.toLocaleString("en-US", {
|
|
2545
|
+
useGrouping: false,
|
|
2546
|
+
maximumFractionDigits: 20
|
|
2547
|
+
}));
|
|
2548
|
+
}
|
|
2549
|
+
function sanitizeNumericText(text, integerOnly) {
|
|
2550
|
+
const negative = text.trim().startsWith(NEGATIVE_SIGN);
|
|
2551
|
+
const cleaned = text.replace(/[^\d.]/g, "");
|
|
2552
|
+
const separatorIndex = cleaned.indexOf(DECIMAL_SEPARATOR);
|
|
2553
|
+
const integerPart = (separatorIndex === -1 ? cleaned : cleaned.slice(0, separatorIndex)).replace(/^0+(?=\d)/, "");
|
|
2554
|
+
const fractionDigits = separatorIndex === -1 ? "" : cleaned.slice(separatorIndex + 1).replace(/\./g, "");
|
|
2555
|
+
const body = integerOnly || separatorIndex === -1 ? integerPart : `${integerPart}${DECIMAL_SEPARATOR}${fractionDigits}`;
|
|
2556
|
+
return `${negative ? NEGATIVE_SIGN : ""}${body}`;
|
|
2557
|
+
}
|
|
2558
|
+
function caretInText(typed, caret, text) {
|
|
2559
|
+
const significantBefore = Array.from(typed.slice(0, caret)).filter((character) => SIGNIFICANT_CHARACTER.test(character)).length;
|
|
2560
|
+
let position = 0;
|
|
2561
|
+
let seen = 0;
|
|
2562
|
+
while (position < text.length && seen < significantBefore) {
|
|
2563
|
+
if (SIGNIFICANT_CHARACTER.test(text[position])) seen++;
|
|
2564
|
+
position++;
|
|
2565
|
+
}
|
|
2566
|
+
return position;
|
|
2567
|
+
}
|
|
2568
|
+
function processTypedText(typed, caret, options) {
|
|
2569
|
+
let raw = sanitizeNumericText(typed, options.integerOnly);
|
|
2570
|
+
const parsed = toNumber(raw);
|
|
2571
|
+
if (options.integerOnly && parsed !== null && parsed > options.max) raw = String(options.max);
|
|
2572
|
+
const text = formatNumericText(raw);
|
|
2573
|
+
return {
|
|
2574
|
+
text,
|
|
2575
|
+
value: toNumber(raw) === null ? "" : raw,
|
|
2576
|
+
caret: caretInText(typed, caret, text)
|
|
2577
|
+
};
|
|
2578
|
+
}
|
|
2579
|
+
//#endregion
|
|
2517
2580
|
//#region src/components/axebow-input/axebow-numeric-input.ts
|
|
2518
2581
|
var AxebowNumericInput = class AxebowNumericInput extends AxebowInputBase {
|
|
2519
2582
|
constructor(..._args) {
|
|
@@ -2524,6 +2587,7 @@ var AxebowNumericInput = class AxebowNumericInput extends AxebowInputBase {
|
|
|
2524
2587
|
this.showStepper = true;
|
|
2525
2588
|
this.stepAmount = 1;
|
|
2526
2589
|
this.fixedField = false;
|
|
2590
|
+
this._text = "";
|
|
2527
2591
|
}
|
|
2528
2592
|
static {
|
|
2529
2593
|
this.styles = [...AxebowInputBase.baseStyles, css`
|
|
@@ -2531,14 +2595,6 @@ var AxebowNumericInput = class AxebowNumericInput extends AxebowInputBase {
|
|
|
2531
2595
|
display: block;
|
|
2532
2596
|
width: 100%;
|
|
2533
2597
|
}
|
|
2534
|
-
sl-input::part(input)::-webkit-outer-spin-button,
|
|
2535
|
-
sl-input::part(input)::-webkit-inner-spin-button {
|
|
2536
|
-
-webkit-appearance: none;
|
|
2537
|
-
margin: 0;
|
|
2538
|
-
}
|
|
2539
|
-
sl-input::part(input) {
|
|
2540
|
-
-moz-appearance: textfield;
|
|
2541
|
-
}
|
|
2542
2598
|
:host(.axebow-fixed-width) sl-input {
|
|
2543
2599
|
width: var(--axebow-input-width) !important;
|
|
2544
2600
|
}
|
|
@@ -2594,6 +2650,10 @@ var AxebowNumericInput = class AxebowNumericInput extends AxebowInputBase {
|
|
|
2594
2650
|
}
|
|
2595
2651
|
`];
|
|
2596
2652
|
}
|
|
2653
|
+
willUpdate(changed) {
|
|
2654
|
+
super.willUpdate(changed);
|
|
2655
|
+
if (changed.has("value") && toNumber(this.value) !== toNumber(this._text)) this._text = formatNumericValue(this.value);
|
|
2656
|
+
}
|
|
2597
2657
|
updated(changed) {
|
|
2598
2658
|
super.updated(changed);
|
|
2599
2659
|
if (changed.has("fixedWidth")) if (this.fixedWidth) {
|
|
@@ -2621,28 +2681,43 @@ var AxebowNumericInput = class AxebowNumericInput extends AxebowInputBase {
|
|
|
2621
2681
|
}
|
|
2622
2682
|
handleChange(e) {
|
|
2623
2683
|
if (this.disabled) return;
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2684
|
+
const input = e.target;
|
|
2685
|
+
const typed = input.value;
|
|
2686
|
+
const { text, value, caret } = processTypedText(typed, input.input?.selectionStart ?? typed.length, {
|
|
2687
|
+
integerOnly: this.integerOnly,
|
|
2688
|
+
max: this.max
|
|
2689
|
+
});
|
|
2690
|
+
if (text !== typed) {
|
|
2691
|
+
const hasFocus = input.shadowRoot?.activeElement === input.input;
|
|
2692
|
+
input.value = text;
|
|
2693
|
+
if (hasFocus) input.updateComplete.then(() => input.setSelectionRange(caret, caret));
|
|
2632
2694
|
}
|
|
2633
|
-
|
|
2695
|
+
this._text = text;
|
|
2696
|
+
this.value = value;
|
|
2697
|
+
this._emitValue(value);
|
|
2698
|
+
}
|
|
2699
|
+
_emitValue(value) {
|
|
2700
|
+
const source = document.createElement("input");
|
|
2701
|
+
source.value = value;
|
|
2702
|
+
source.addEventListener("input", (event) => this.callback?.(event), { once: true });
|
|
2703
|
+
source.dispatchEvent(new Event("input"));
|
|
2634
2704
|
}
|
|
2635
2705
|
handleKeyDown(e) {
|
|
2636
|
-
if (
|
|
2706
|
+
if (e.key === "ArrowUp" || e.key === "ArrowDown") {
|
|
2707
|
+
e.preventDefault();
|
|
2708
|
+
this._bumpValue(e.key === "ArrowUp" ? 1 : -1);
|
|
2709
|
+
return;
|
|
2710
|
+
}
|
|
2711
|
+
if (this.integerOnly && e.key === ".") e.preventDefault();
|
|
2637
2712
|
}
|
|
2638
2713
|
_bumpValue(sign) {
|
|
2639
2714
|
if (this.disabled) return;
|
|
2640
2715
|
const step = this.integerOnly ? Math.trunc(this.stepAmount) || 1 : this.stepAmount;
|
|
2641
|
-
const current =
|
|
2716
|
+
const current = toNumber(this.value) ?? 0;
|
|
2642
2717
|
const next = Math.min(this.max, Math.max(this.min, current + sign * step));
|
|
2643
2718
|
const input = this.renderRoot.querySelector("sl-input");
|
|
2644
2719
|
if (!input) return;
|
|
2645
|
-
input.value = next
|
|
2720
|
+
input.value = formatNumericValue(next);
|
|
2646
2721
|
input.dispatchEvent(new Event("sl-input", {
|
|
2647
2722
|
bubbles: true,
|
|
2648
2723
|
composed: true
|
|
@@ -2650,7 +2725,7 @@ var AxebowNumericInput = class AxebowNumericInput extends AxebowInputBase {
|
|
|
2650
2725
|
}
|
|
2651
2726
|
_renderStepper() {
|
|
2652
2727
|
if (!this.showStepper) return "";
|
|
2653
|
-
const current =
|
|
2728
|
+
const current = toNumber(this.value) ?? 0;
|
|
2654
2729
|
return html`
|
|
2655
2730
|
<div slot="suffix" class="axebow-numeric-stepper">
|
|
2656
2731
|
<button
|
|
@@ -2678,15 +2753,16 @@ var AxebowNumericInput = class AxebowNumericInput extends AxebowInputBase {
|
|
|
2678
2753
|
const content = html`
|
|
2679
2754
|
<div class="${this.hasError ? "input-error" : ""}">
|
|
2680
2755
|
<sl-input
|
|
2681
|
-
type="
|
|
2756
|
+
type="text"
|
|
2757
|
+
inputmode="${this.integerOnly ? "numeric" : "decimal"}"
|
|
2758
|
+
autocomplete="off"
|
|
2682
2759
|
placeholder="${this.placeholder}"
|
|
2683
2760
|
@sl-input="${this.handleChange}"
|
|
2684
2761
|
@keydown="${this.handleKeyDown}"
|
|
2685
|
-
.value="${live(this.
|
|
2762
|
+
.value="${live(this._text)}"
|
|
2686
2763
|
?disabled="${this.disabled}"
|
|
2687
2764
|
max=${this.max}
|
|
2688
2765
|
min=${this.min}
|
|
2689
|
-
step=${this.integerOnly ? "1" : "any"}
|
|
2690
2766
|
>
|
|
2691
2767
|
${this._renderStepper()}
|
|
2692
2768
|
</sl-input>
|
|
@@ -2704,6 +2780,7 @@ __decorate([property({ type: Boolean })], AxebowNumericInput.prototype, "showSte
|
|
|
2704
2780
|
__decorate([property({ type: Number })], AxebowNumericInput.prototype, "stepAmount", void 0);
|
|
2705
2781
|
__decorate([property({ type: Boolean })], AxebowNumericInput.prototype, "fixedField", void 0);
|
|
2706
2782
|
__decorate([property({ type: String })], AxebowNumericInput.prototype, "minWidth", void 0);
|
|
2783
|
+
__decorate([state()], AxebowNumericInput.prototype, "_text", void 0);
|
|
2707
2784
|
AxebowNumericInput = __decorate([customElement("axebow-numeric-input")], AxebowNumericInput);
|
|
2708
2785
|
//#endregion
|
|
2709
2786
|
//#region src/components/axebow-input/axebow-checkbox-input.ts
|