@pure-ds/core 0.7.62 → 0.7.63
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/types/src/js/pds-core/pds-enhancers-meta.d.ts.map +1 -1
- package/dist/types/src/js/pds-core/pds-enhancers.d.ts.map +1 -1
- package/dist/types/src/js/pds-core/pds-generator.d.ts.map +1 -1
- package/package.json +1 -1
- package/public/assets/js/app.js +1 -1
- package/public/assets/js/pds-enhancers.js +1 -1
- package/public/assets/js/pds-manager.js +404 -267
- package/public/assets/pds/core/pds-enhancers.js +1 -1
- package/public/assets/pds/core/pds-manager.js +404 -267
- package/src/js/pds-core/pds-enhancers-meta.js +58 -9
- package/src/js/pds-core/pds-enhancers.js +193 -0
- package/src/js/pds-core/pds-generator.js +118 -0
|
@@ -11,7 +11,7 @@ export const defaultPDSEnhancerMetadata = [
|
|
|
11
11
|
selector: ".accordion",
|
|
12
12
|
description:
|
|
13
13
|
"Ensures only one <details> element can be open at a time within the accordion.",
|
|
14
|
-
demoHtml:
|
|
14
|
+
demoHtml: /*html*/`
|
|
15
15
|
<div class="accordion">
|
|
16
16
|
<details>
|
|
17
17
|
<summary>Section 1</summary>
|
|
@@ -46,7 +46,7 @@ export const defaultPDSEnhancerMetadata = [
|
|
|
46
46
|
appliesTo: "Any clickable element inside nav[data-dropdown] menu/panel content",
|
|
47
47
|
},
|
|
48
48
|
],
|
|
49
|
-
demoHtml:
|
|
49
|
+
demoHtml: /*html*/`
|
|
50
50
|
<nav data-dropdown>
|
|
51
51
|
<button class="btn-primary">Menu</button>
|
|
52
52
|
<menu>
|
|
@@ -59,7 +59,7 @@ export const defaultPDSEnhancerMetadata = [
|
|
|
59
59
|
{
|
|
60
60
|
selector: "label[data-toggle]",
|
|
61
61
|
description: "Creates a toggle switch element from a checkbox.",
|
|
62
|
-
demoHtml:
|
|
62
|
+
demoHtml: /*html*/`
|
|
63
63
|
<label data-toggle>
|
|
64
64
|
<input type="checkbox">
|
|
65
65
|
<span data-label>Enable notifications</span>
|
|
@@ -70,17 +70,66 @@ export const defaultPDSEnhancerMetadata = [
|
|
|
70
70
|
selector: "label[data-color]",
|
|
71
71
|
description:
|
|
72
72
|
"Wraps color inputs with a styled control shell and synced hex output while keeping the native picker.",
|
|
73
|
-
demoHtml:
|
|
73
|
+
demoHtml: /*html*/`
|
|
74
74
|
<label data-color>
|
|
75
75
|
<span>Brand color</span>
|
|
76
76
|
<input type="color" value="#7c3aed">
|
|
77
77
|
</label>
|
|
78
78
|
`.trim(),
|
|
79
79
|
},
|
|
80
|
+
{
|
|
81
|
+
selector: 'input[autocomplete="one-time-code"]',
|
|
82
|
+
description:
|
|
83
|
+
"Enhances a single text input into a segmented one-time-code / OTP field with numeric sanitizing, full-code paste support, and optional auto-submit when the expected length is reached.",
|
|
84
|
+
attributes: [
|
|
85
|
+
{
|
|
86
|
+
name: "data-otp-length",
|
|
87
|
+
description:
|
|
88
|
+
"Expected code length. Defaults to the input maxlength, or 6 when neither is provided.",
|
|
89
|
+
appliesTo: 'input[autocomplete="one-time-code"]',
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
name: 'data-otp-autosubmit="false"',
|
|
93
|
+
description:
|
|
94
|
+
"Opt out of automatically submitting the parent form when the code is complete.",
|
|
95
|
+
appliesTo: 'input[autocomplete="one-time-code"]',
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
name: "data-otp-submit-selector",
|
|
99
|
+
description:
|
|
100
|
+
"Optional selector for the preferred submit button passed to form.requestSubmit().",
|
|
101
|
+
appliesTo: 'input[autocomplete="one-time-code"]',
|
|
102
|
+
},
|
|
103
|
+
],
|
|
104
|
+
demoHtml: /*html*/`
|
|
105
|
+
<form action="#verify" method="post">
|
|
106
|
+
<label>
|
|
107
|
+
<span data-label>Email address</span>
|
|
108
|
+
<input type="email" autocomplete="email" value="marc@example.com">
|
|
109
|
+
</label>
|
|
110
|
+
<label>
|
|
111
|
+
<span data-label>Verification code</span>
|
|
112
|
+
<input
|
|
113
|
+
autocomplete="one-time-code"
|
|
114
|
+
inputmode="numeric"
|
|
115
|
+
maxlength="6"
|
|
116
|
+
data-otp-length="6"
|
|
117
|
+
aria-describedby="otp-help"
|
|
118
|
+
>
|
|
119
|
+
</label>
|
|
120
|
+
<small id="otp-help" class="field-description">
|
|
121
|
+
We sent a 6-digit code to marc@example.com. You can paste the full code.
|
|
122
|
+
</small>
|
|
123
|
+
<nav class="form-actions">
|
|
124
|
+
<button type="submit" class="btn-primary">Verify</button>
|
|
125
|
+
</nav>
|
|
126
|
+
</form>
|
|
127
|
+
`.trim(),
|
|
128
|
+
},
|
|
80
129
|
{
|
|
81
130
|
selector: 'input[type="range"]',
|
|
82
131
|
description: "Enhances range inputs with an attached <output>.",
|
|
83
|
-
demoHtml:
|
|
132
|
+
demoHtml: /*html*/`
|
|
84
133
|
<label class="range-output">
|
|
85
134
|
<span data-label>Volume</span>
|
|
86
135
|
<input type="range" min="0" max="100" value="40">
|
|
@@ -91,7 +140,7 @@ export const defaultPDSEnhancerMetadata = [
|
|
|
91
140
|
selector: "form[data-required]",
|
|
92
141
|
description:
|
|
93
142
|
"Enhances required form fields using an asterisk in the label.",
|
|
94
|
-
demoHtml:
|
|
143
|
+
demoHtml: /*html*/`
|
|
95
144
|
<form data-required action="#" method="post">
|
|
96
145
|
<label>
|
|
97
146
|
<span>Field Label</span>
|
|
@@ -107,7 +156,7 @@ export const defaultPDSEnhancerMetadata = [
|
|
|
107
156
|
selector: "fieldset[role=group][data-open]",
|
|
108
157
|
description:
|
|
109
158
|
"Enhances a checkbox/radio group to be open (have a way to add and remove items).",
|
|
110
|
-
demoHtml:
|
|
159
|
+
demoHtml: /*html*/`
|
|
111
160
|
<fieldset role="group" data-open>
|
|
112
161
|
<label>
|
|
113
162
|
<span data-label>Test</span>
|
|
@@ -120,7 +169,7 @@ export const defaultPDSEnhancerMetadata = [
|
|
|
120
169
|
selector: "[data-clip]",
|
|
121
170
|
description:
|
|
122
171
|
"Enables click/keyboard toggling for line-clamped content blocks.",
|
|
123
|
-
demoHtml:
|
|
172
|
+
demoHtml: /*html*/`
|
|
124
173
|
<div data-clip="2" data-clip-more="more...">
|
|
125
174
|
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
|
|
126
175
|
<p>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris.</p>
|
|
@@ -132,7 +181,7 @@ export const defaultPDSEnhancerMetadata = [
|
|
|
132
181
|
selector: "button, a[class*='btn-']",
|
|
133
182
|
description:
|
|
134
183
|
"Automatically manages spinner icon for buttons with .btn-working class",
|
|
135
|
-
demoHtml:
|
|
184
|
+
demoHtml: /*html*/`
|
|
136
185
|
<button class="btn-primary btn-working">
|
|
137
186
|
<span>Saving</span>
|
|
138
187
|
</button>
|
|
@@ -18,6 +18,7 @@ const enhancerDefinitions = [
|
|
|
18
18
|
{ selector: "nav[data-dropdown]" },
|
|
19
19
|
{ selector: "label[data-toggle]" },
|
|
20
20
|
{ selector: "label[data-color]" },
|
|
21
|
+
{ selector: 'input[autocomplete="one-time-code"]' },
|
|
21
22
|
{ selector: 'input[type="range"]' },
|
|
22
23
|
{ selector: "form[data-required]" },
|
|
23
24
|
{ selector: "fieldset[role=group][data-open]" },
|
|
@@ -566,6 +567,197 @@ function enhanceColorInput(elem) {
|
|
|
566
567
|
input.addEventListener("change", setResolved, { passive: true });
|
|
567
568
|
}
|
|
568
569
|
|
|
570
|
+
function enhanceOneTimeCodeInput(elem) {
|
|
571
|
+
if (elem.dataset.enhancedOneTimeCode) return;
|
|
572
|
+
elem.dataset.enhancedOneTimeCode = "true";
|
|
573
|
+
|
|
574
|
+
const configuredLength = Number.parseInt(
|
|
575
|
+
elem.getAttribute("data-otp-length") || elem.getAttribute("maxlength") || "6",
|
|
576
|
+
10,
|
|
577
|
+
);
|
|
578
|
+
const length = Number.isFinite(configuredLength) && configuredLength > 0 ? configuredLength : 6;
|
|
579
|
+
const autoSubmit = elem.getAttribute("data-otp-autosubmit") !== "false";
|
|
580
|
+
const allowAlphanumeric = elem.getAttribute("data-otp-format") === "alphanumeric";
|
|
581
|
+
const statusId =
|
|
582
|
+
elem.getAttribute("data-otp-status-id") ||
|
|
583
|
+
`${elem.id || `otp-${Math.random().toString(36).slice(2, 9)}`}-status`;
|
|
584
|
+
|
|
585
|
+
const normalizeValue = (value) => {
|
|
586
|
+
const compact = String(value || "").replace(/\s+/g, "");
|
|
587
|
+
const filtered = allowAlphanumeric
|
|
588
|
+
? compact.replace(/[^0-9a-z]/gi, "")
|
|
589
|
+
: compact.replace(/\D+/g, "");
|
|
590
|
+
return filtered.slice(0, length);
|
|
591
|
+
};
|
|
592
|
+
|
|
593
|
+
elem.classList.add("input-otp");
|
|
594
|
+
elem.dataset.otpLength = String(length);
|
|
595
|
+
elem.dataset.otpComplete = "false";
|
|
596
|
+
elem.style.setProperty("--otp-digits", String(length));
|
|
597
|
+
elem.style.setProperty("--_otp-digit", "0");
|
|
598
|
+
|
|
599
|
+
if (!elem.hasAttribute("type") || elem.getAttribute("type")?.toLowerCase() === "number") {
|
|
600
|
+
elem.setAttribute("type", "text");
|
|
601
|
+
}
|
|
602
|
+
elem.setAttribute("maxlength", String(length));
|
|
603
|
+
if (!elem.hasAttribute("inputmode")) {
|
|
604
|
+
elem.setAttribute("inputmode", allowAlphanumeric ? "text" : "numeric");
|
|
605
|
+
}
|
|
606
|
+
if (!elem.hasAttribute("enterkeyhint")) {
|
|
607
|
+
elem.setAttribute("enterkeyhint", "done");
|
|
608
|
+
}
|
|
609
|
+
if (!elem.hasAttribute("autocapitalize")) {
|
|
610
|
+
elem.setAttribute("autocapitalize", "off");
|
|
611
|
+
}
|
|
612
|
+
if (!elem.hasAttribute("spellcheck")) {
|
|
613
|
+
elem.setAttribute("spellcheck", "false");
|
|
614
|
+
}
|
|
615
|
+
if (!elem.hasAttribute("pattern")) {
|
|
616
|
+
elem.setAttribute(
|
|
617
|
+
"pattern",
|
|
618
|
+
allowAlphanumeric ? `[0-9A-Za-z]{${length}}` : `\\d{${length}}`,
|
|
619
|
+
);
|
|
620
|
+
}
|
|
621
|
+
if (!elem.hasAttribute("aria-label") && !elem.labels?.length) {
|
|
622
|
+
elem.setAttribute("aria-label", msg("One-time code"));
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
const form = elem.form || elem.closest("form");
|
|
626
|
+
let autoSubmitPending = false;
|
|
627
|
+
let status = null;
|
|
628
|
+
|
|
629
|
+
const syncActiveDigit = () => {
|
|
630
|
+
const selectionStart =
|
|
631
|
+
typeof elem.selectionStart === "number" ? elem.selectionStart : elem.value.length;
|
|
632
|
+
const clamped = Math.max(0, Math.min(selectionStart, Math.max(length - 1, 0)));
|
|
633
|
+
elem.style.setProperty("--_otp-digit", String(clamped));
|
|
634
|
+
};
|
|
635
|
+
|
|
636
|
+
const syncScrollPosition = () => {
|
|
637
|
+
if (typeof elem.scrollLeft === "number") {
|
|
638
|
+
elem.scrollLeft = 0;
|
|
639
|
+
}
|
|
640
|
+
};
|
|
641
|
+
|
|
642
|
+
if (typeof document !== "undefined") {
|
|
643
|
+
status = document.getElementById(statusId);
|
|
644
|
+
if (!status) {
|
|
645
|
+
status = document.createElement("span");
|
|
646
|
+
status.id = statusId;
|
|
647
|
+
status.className = "otp-status";
|
|
648
|
+
status.setAttribute("aria-live", "polite");
|
|
649
|
+
status.setAttribute("aria-atomic", "true");
|
|
650
|
+
elem.insertAdjacentElement("afterend", status);
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
const describedBy = new Set(
|
|
654
|
+
(elem.getAttribute("aria-describedby") || "")
|
|
655
|
+
.split(/\s+/)
|
|
656
|
+
.filter(Boolean),
|
|
657
|
+
);
|
|
658
|
+
describedBy.add(statusId);
|
|
659
|
+
elem.setAttribute("aria-describedby", Array.from(describedBy).join(" "));
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
const updateStatus = () => {
|
|
663
|
+
if (!status) return;
|
|
664
|
+
const count = elem.value.length;
|
|
665
|
+
status.textContent =
|
|
666
|
+
count === 0
|
|
667
|
+
? msg("Enter the verification code")
|
|
668
|
+
: count >= length
|
|
669
|
+
? msg("Code complete")
|
|
670
|
+
: `${count}/${length}`;
|
|
671
|
+
};
|
|
672
|
+
|
|
673
|
+
const attemptSubmit = () => {
|
|
674
|
+
if (!autoSubmit || autoSubmitPending || !form) return;
|
|
675
|
+
if (typeof form.checkValidity === "function" && !form.checkValidity()) return;
|
|
676
|
+
autoSubmitPending = true;
|
|
677
|
+
requestAnimationFrame(() => {
|
|
678
|
+
autoSubmitPending = false;
|
|
679
|
+
const submitSelector = elem.getAttribute("data-otp-submit-selector");
|
|
680
|
+
const submitter = submitSelector ? form.querySelector(submitSelector) : undefined;
|
|
681
|
+
if (typeof form.requestSubmit === "function") {
|
|
682
|
+
form.requestSubmit(submitter || undefined);
|
|
683
|
+
} else {
|
|
684
|
+
form.submit();
|
|
685
|
+
}
|
|
686
|
+
});
|
|
687
|
+
};
|
|
688
|
+
|
|
689
|
+
const syncValue = (nextValue, { dispatchChange = false } = {}) => {
|
|
690
|
+
const normalized = normalizeValue(nextValue);
|
|
691
|
+
if (elem.value !== normalized) {
|
|
692
|
+
elem.value = normalized;
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
const isComplete = normalized.length === length;
|
|
696
|
+
elem.dataset.otpComplete = isComplete ? "true" : "false";
|
|
697
|
+
updateStatus();
|
|
698
|
+
syncActiveDigit();
|
|
699
|
+
syncScrollPosition();
|
|
700
|
+
|
|
701
|
+
if (dispatchChange) {
|
|
702
|
+
elem.dispatchEvent(new Event("change", { bubbles: true }));
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
if (isComplete) {
|
|
706
|
+
attemptSubmit();
|
|
707
|
+
}
|
|
708
|
+
};
|
|
709
|
+
|
|
710
|
+
elem.addEventListener("beforeinput", (event) => {
|
|
711
|
+
if (event.defaultPrevented) return;
|
|
712
|
+
if (event.inputType?.startsWith("delete")) return;
|
|
713
|
+
if (typeof event.data !== "string" || event.data.length === 0) return;
|
|
714
|
+
|
|
715
|
+
const normalized = normalizeValue(event.data);
|
|
716
|
+
if (!normalized && event.data.trim()) {
|
|
717
|
+
event.preventDefault();
|
|
718
|
+
}
|
|
719
|
+
});
|
|
720
|
+
|
|
721
|
+
elem.addEventListener("input", () => {
|
|
722
|
+
syncValue(elem.value);
|
|
723
|
+
try {
|
|
724
|
+
const end = elem.value.length;
|
|
725
|
+
elem.setSelectionRange(end, end);
|
|
726
|
+
} catch {
|
|
727
|
+
// Ignore selection API issues on unsupported input modes
|
|
728
|
+
}
|
|
729
|
+
syncActiveDigit();
|
|
730
|
+
syncScrollPosition();
|
|
731
|
+
});
|
|
732
|
+
|
|
733
|
+
["focus", "click", "keyup", "select"].forEach((eventName) => {
|
|
734
|
+
elem.addEventListener(eventName, () => {
|
|
735
|
+
requestAnimationFrame(() => {
|
|
736
|
+
syncActiveDigit();
|
|
737
|
+
syncScrollPosition();
|
|
738
|
+
});
|
|
739
|
+
});
|
|
740
|
+
});
|
|
741
|
+
|
|
742
|
+
elem.addEventListener("paste", (event) => {
|
|
743
|
+
const pasted = event.clipboardData?.getData("text") || "";
|
|
744
|
+
if (!pasted) return;
|
|
745
|
+
|
|
746
|
+
event.preventDefault();
|
|
747
|
+
elem.value = normalizeValue(pasted);
|
|
748
|
+
elem.dispatchEvent(new Event("input", { bubbles: true }));
|
|
749
|
+
elem.dispatchEvent(new Event("change", { bubbles: true }));
|
|
750
|
+
});
|
|
751
|
+
|
|
752
|
+
elem.addEventListener("keydown", (event) => {
|
|
753
|
+
if (event.key === "Enter" && elem.value.length === length) {
|
|
754
|
+
attemptSubmit();
|
|
755
|
+
}
|
|
756
|
+
});
|
|
757
|
+
|
|
758
|
+
syncValue(elem.value);
|
|
759
|
+
}
|
|
760
|
+
|
|
569
761
|
function enhanceRange(elem) {
|
|
570
762
|
if (elem.dataset.enhancedRange) return;
|
|
571
763
|
|
|
@@ -891,6 +1083,7 @@ const enhancerRunners = new Map([
|
|
|
891
1083
|
["nav[data-dropdown]", enhanceDropdown],
|
|
892
1084
|
["label[data-toggle]", enhanceToggle],
|
|
893
1085
|
["label[data-color]", enhanceColorInput],
|
|
1086
|
+
['input[autocomplete="one-time-code"]', enhanceOneTimeCodeInput],
|
|
894
1087
|
['input[type="range"]', enhanceRange],
|
|
895
1088
|
["form[data-required]", enhanceRequired],
|
|
896
1089
|
["fieldset[role=group][data-open]", enhanceOpenGroup],
|
|
@@ -2628,6 +2628,124 @@ input, textarea, select {
|
|
|
2628
2628
|
}
|
|
2629
2629
|
}
|
|
2630
2630
|
|
|
2631
|
+
/* One-time-code / OTP input enhancement — single input, segmented visual style */
|
|
2632
|
+
input[autocomplete="one-time-code"],
|
|
2633
|
+
input.input-otp {
|
|
2634
|
+
--otp-digits: 6;
|
|
2635
|
+
--otp-ls: 1.6ch;
|
|
2636
|
+
--otp-gap: 1.15;
|
|
2637
|
+
--otp-edge-pad: max(var(--spacing-2), calc(var(--radius-md) * 0.8));
|
|
2638
|
+
--otp-start-shift: calc((((var(--_otp-bgsz) - 1ch) / 2) * 0.98));
|
|
2639
|
+
--otp-pad-start: calc(var(--otp-edge-pad) + var(--otp-start-shift));
|
|
2640
|
+
--otp-pad-end: var(--otp-edge-pad);
|
|
2641
|
+
--otp-cell-bg: color-mix(in oklab, var(--color-surface-subtle) 94%, var(--color-primary-fill) 6%);
|
|
2642
|
+
--otp-active-bg: color-mix(in oklab, var(--color-primary-fill) 18%, var(--color-surface-base));
|
|
2643
|
+
--_otp-bgsz: calc(var(--otp-ls) + 1ch);
|
|
2644
|
+
--_otp-digit: 0;
|
|
2645
|
+
|
|
2646
|
+
all: unset;
|
|
2647
|
+
display: block;
|
|
2648
|
+
box-sizing: border-box;
|
|
2649
|
+
inline-size: calc((var(--otp-digits) * var(--_otp-bgsz)) + var(--otp-pad-start) + var(--otp-pad-end));
|
|
2650
|
+
max-inline-size: 100%;
|
|
2651
|
+
min-inline-size: 0;
|
|
2652
|
+
min-block-size: auto;
|
|
2653
|
+
padding-block: max(var(--spacing-3), 0.9ch);
|
|
2654
|
+
padding-inline-start: var(--otp-pad-start);
|
|
2655
|
+
padding-inline-end: var(--otp-pad-end);
|
|
2656
|
+
border-radius: max(var(--radius-md), calc(var(--otp-edge-pad) * 0.9));
|
|
2657
|
+
text-align: left;
|
|
2658
|
+
text-indent: 0;
|
|
2659
|
+
letter-spacing: var(--otp-ls);
|
|
2660
|
+
font-family: var(--font-family-mono, monospace);
|
|
2661
|
+
font-variant-numeric: tabular-nums;
|
|
2662
|
+
font-size: clamp(var(--font-size-lg), 2vw, calc(var(--font-size-xl) + var(--font-size-xs)));
|
|
2663
|
+
line-height: 1;
|
|
2664
|
+
white-space: nowrap;
|
|
2665
|
+
direction: ltr;
|
|
2666
|
+
color: var(--color-text-primary);
|
|
2667
|
+
caret-color: var(--color-text-primary);
|
|
2668
|
+
cursor: text;
|
|
2669
|
+
overflow: hidden;
|
|
2670
|
+
scrollbar-width: none;
|
|
2671
|
+
background:
|
|
2672
|
+
linear-gradient(
|
|
2673
|
+
90deg,
|
|
2674
|
+
var(--otp-active-bg) 0 calc(var(--otp-gap) * var(--otp-ls)),
|
|
2675
|
+
transparent calc(var(--otp-gap) * var(--otp-ls)) 100%
|
|
2676
|
+
) calc(var(--_otp-digit) * var(--_otp-bgsz)) 0 / var(--_otp-bgsz) 100% no-repeat,
|
|
2677
|
+
repeating-linear-gradient(
|
|
2678
|
+
90deg,
|
|
2679
|
+
var(--otp-cell-bg) 0 calc(var(--otp-gap) * var(--otp-ls)),
|
|
2680
|
+
transparent calc(var(--otp-gap) * var(--otp-ls)) var(--_otp-bgsz)
|
|
2681
|
+
) 0 0 / var(--_otp-bgsz) 100% repeat-x,
|
|
2682
|
+
var(--color-input-bg);
|
|
2683
|
+
background-origin: content-box, content-box, border-box;
|
|
2684
|
+
background-clip: content-box, content-box, border-box;
|
|
2685
|
+
box-shadow:
|
|
2686
|
+
inset 0 0 0 var(--border-width-medium) var(--color-border),
|
|
2687
|
+
var(--shadow-sm);
|
|
2688
|
+
|
|
2689
|
+
&::-webkit-scrollbar {
|
|
2690
|
+
display: none;
|
|
2691
|
+
}
|
|
2692
|
+
|
|
2693
|
+
&::placeholder {
|
|
2694
|
+
color: transparent;
|
|
2695
|
+
}
|
|
2696
|
+
|
|
2697
|
+
&:focus {
|
|
2698
|
+
box-shadow:
|
|
2699
|
+
inset 0 0 0 var(--border-width-medium) var(--color-focus-ring, var(--color-primary-500)),
|
|
2700
|
+
0 0 0 ${focusWidth}px color-mix(in oklab, var(--color-focus-ring, var(--color-primary-500)) ${Math.round(
|
|
2701
|
+
(focusRingOpacity || 0.3) * 100,
|
|
2702
|
+
)}%, transparent);
|
|
2703
|
+
}
|
|
2704
|
+
|
|
2705
|
+
&:invalid {
|
|
2706
|
+
box-shadow:
|
|
2707
|
+
inset 0 0 0 var(--border-width-medium) var(--color-border),
|
|
2708
|
+
var(--shadow-sm);
|
|
2709
|
+
}
|
|
2710
|
+
|
|
2711
|
+
&:invalid:focus {
|
|
2712
|
+
box-shadow:
|
|
2713
|
+
inset 0 0 0 var(--border-width-medium) var(--color-focus-ring, var(--color-primary-500)),
|
|
2714
|
+
0 0 0 ${focusWidth}px color-mix(in oklab, var(--color-focus-ring, var(--color-primary-500)) ${Math.round(
|
|
2715
|
+
(focusRingOpacity || 0.3) * 100,
|
|
2716
|
+
)}%, transparent);
|
|
2717
|
+
}
|
|
2718
|
+
|
|
2719
|
+
&[data-otp-complete="true"] {
|
|
2720
|
+
--otp-active-bg: color-mix(in oklab, var(--color-success-fill, var(--color-primary-fill)) 18%, var(--color-surface-base));
|
|
2721
|
+
}
|
|
2722
|
+
|
|
2723
|
+
&:disabled {
|
|
2724
|
+
color: var(--color-input-disabled-text);
|
|
2725
|
+
caret-color: transparent;
|
|
2726
|
+
background:
|
|
2727
|
+
linear-gradient(
|
|
2728
|
+
90deg,
|
|
2729
|
+
color-mix(in oklab, var(--color-input-disabled-bg) 90%, var(--color-border) 10%) calc(var(--otp-gap) * var(--otp-ls)),
|
|
2730
|
+
transparent 0
|
|
2731
|
+
) 0 0 / var(--_otp-bgsz) 100% repeat-x;
|
|
2732
|
+
box-shadow: inset 0 0 0 var(--border-width-medium) var(--color-border);
|
|
2733
|
+
}
|
|
2734
|
+
}
|
|
2735
|
+
|
|
2736
|
+
.otp-status {
|
|
2737
|
+
position: absolute;
|
|
2738
|
+
width: 1px;
|
|
2739
|
+
height: 1px;
|
|
2740
|
+
padding: 0;
|
|
2741
|
+
margin: -1px;
|
|
2742
|
+
overflow: hidden;
|
|
2743
|
+
clip: rect(0 0 0 0);
|
|
2744
|
+
clip-path: inset(50%);
|
|
2745
|
+
white-space: nowrap;
|
|
2746
|
+
border: 0;
|
|
2747
|
+
}
|
|
2748
|
+
|
|
2631
2749
|
input[type="range"] {
|
|
2632
2750
|
padding: 0;
|
|
2633
2751
|
background: transparent;
|