@mitcsutt/kiln-ui 0.6.0 → 0.7.0
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/actions/CopyButton/CopyButton.d.ts +58 -0
- package/dist/components/actions/CopyButton/CopyButton.js +63 -0
- package/dist/components/actions/CopyButton/CopyButton.js.map +1 -0
- package/dist/components/actions/CopyButton/CopyButton.module.js +9 -0
- package/dist/components/actions/CopyButton/CopyButton.module.js.map +1 -0
- package/dist/components/actions/CopyButton/index.d.ts +4 -0
- package/dist/components/actions/CopyButton/useClipboard.d.ts +35 -0
- package/dist/components/actions/CopyButton/useClipboard.js +62 -0
- package/dist/components/actions/CopyButton/useClipboard.js.map +1 -0
- package/dist/components/actions/ToggleChip/ToggleChip.d.ts +6 -0
- package/dist/components/actions/ToggleChip/ToggleChip.js +26 -24
- package/dist/components/actions/ToggleChip/ToggleChip.js.map +1 -1
- package/dist/components/display/Badge/Badge.d.ts +6 -0
- package/dist/components/display/Badge/Badge.js +16 -15
- package/dist/components/display/Badge/Badge.js.map +1 -1
- package/dist/components/display/CodeBlock/CodeBlock.js +45 -58
- package/dist/components/display/CodeBlock/CodeBlock.js.map +1 -1
- package/dist/components/display/Swatch/Swatch.d.ts +52 -0
- package/dist/components/display/Swatch/Swatch.js +27 -0
- package/dist/components/display/Swatch/Swatch.js.map +1 -0
- package/dist/components/display/Swatch/Swatch.module.js +6 -0
- package/dist/components/display/Swatch/Swatch.module.js.map +1 -0
- package/dist/components/display/Swatch/index.d.ts +2 -0
- package/dist/components/display/Tag/Tag.d.ts +7 -0
- package/dist/components/display/Tag/Tag.js +31 -26
- package/dist/components/display/Tag/Tag.js.map +1 -1
- package/dist/components/feedback/Indicator/Indicator.d.ts +74 -0
- package/dist/components/feedback/Indicator/Indicator.js +50 -0
- package/dist/components/feedback/Indicator/Indicator.js.map +1 -0
- package/dist/components/feedback/Indicator/Indicator.module.js +12 -0
- package/dist/components/feedback/Indicator/Indicator.module.js.map +1 -0
- package/dist/components/feedback/Indicator/index.d.ts +2 -0
- package/dist/components/feedback/Toaster/Toaster.d.ts +71 -0
- package/dist/components/feedback/Toaster/Toaster.js +121 -0
- package/dist/components/feedback/Toaster/Toaster.js.map +1 -0
- package/dist/components/feedback/Toaster/Toaster.module.js +20 -0
- package/dist/components/feedback/Toaster/Toaster.module.js.map +1 -0
- package/dist/components/feedback/Toaster/index.d.ts +4 -0
- package/dist/components/feedback/Toaster/toast.d.ts +96 -0
- package/dist/components/feedback/Toaster/toast.js +131 -0
- package/dist/components/feedback/Toaster/toast.js.map +1 -0
- package/dist/components/inputs/Calendar/Calendar.d.ts +87 -0
- package/dist/components/inputs/Calendar/Calendar.js +217 -0
- package/dist/components/inputs/Calendar/Calendar.js.map +1 -0
- package/dist/components/inputs/Calendar/Calendar.module.js +18 -0
- package/dist/components/inputs/Calendar/Calendar.module.js.map +1 -0
- package/dist/components/inputs/Calendar/index.d.ts +2 -0
- package/dist/components/inputs/Combobox/Combobox.js +36 -44
- package/dist/components/inputs/Combobox/Combobox.js.map +1 -1
- package/dist/components/inputs/DateField/DateField.d.ts +17 -0
- package/dist/components/inputs/DateField/DateField.js +26 -0
- package/dist/components/inputs/DateField/DateField.js.map +1 -0
- package/dist/components/inputs/DateField/index.d.ts +2 -0
- package/dist/components/inputs/DateInput/DateInput.d.ts +75 -0
- package/dist/components/inputs/DateInput/DateInput.js +139 -0
- package/dist/components/inputs/DateInput/DateInput.js.map +1 -0
- package/dist/components/inputs/DateInput/index.d.ts +3 -0
- package/dist/components/inputs/DateRangeField/DateRangeField.d.ts +18 -3
- package/dist/components/inputs/DateRangeField/DateRangeField.js.map +1 -1
- package/dist/components/inputs/DateRangeField/DateRangeField.module.js +8 -3
- package/dist/components/inputs/DateRangeField/DateRangeField.module.js.map +1 -1
- package/dist/components/inputs/DateRangeField/DateRangePickerField.d.ts +48 -0
- package/dist/components/inputs/DateRangeField/DateRangePickerField.js +246 -0
- package/dist/components/inputs/DateRangeField/DateRangePickerField.js.map +1 -0
- package/dist/components/inputs/DateRangeField/index.d.ts +2 -0
- package/dist/components/inputs/DateTimeField/DateTimeField.d.ts +17 -0
- package/dist/components/inputs/DateTimeField/DateTimeField.js +26 -0
- package/dist/components/inputs/DateTimeField/DateTimeField.js.map +1 -0
- package/dist/components/inputs/DateTimeField/index.d.ts +2 -0
- package/dist/components/inputs/DateTimeInput/DateTimeInput.d.ts +83 -0
- package/dist/components/inputs/DateTimeInput/DateTimeInput.js +216 -0
- package/dist/components/inputs/DateTimeInput/DateTimeInput.js.map +1 -0
- package/dist/components/inputs/DateTimeInput/index.d.ts +2 -0
- package/dist/components/inputs/JsonField/JsonField.d.ts +23 -0
- package/dist/components/inputs/JsonField/JsonField.js +33 -0
- package/dist/components/inputs/JsonField/JsonField.js.map +1 -0
- package/dist/components/inputs/JsonField/index.d.ts +2 -0
- package/dist/components/inputs/JsonInput/JsonInput.d.ts +119 -0
- package/dist/components/inputs/JsonInput/JsonInput.js +282 -0
- package/dist/components/inputs/JsonInput/JsonInput.js.map +1 -0
- package/dist/components/inputs/JsonInput/JsonInput.module.js +16 -0
- package/dist/components/inputs/JsonInput/JsonInput.module.js.map +1 -0
- package/dist/components/inputs/JsonInput/index.d.ts +4 -0
- package/dist/components/inputs/JsonInput/json.d.ts +59 -0
- package/dist/components/inputs/JsonInput/json.js +231 -0
- package/dist/components/inputs/JsonInput/json.js.map +1 -0
- package/dist/components/inputs/TagsInput/TagsInput.js +5 -5
- package/dist/components/inputs/TimeField/TimeField.d.ts +17 -0
- package/dist/components/inputs/TimeField/TimeField.js +26 -0
- package/dist/components/inputs/TimeField/TimeField.js.map +1 -0
- package/dist/components/inputs/TimeField/index.d.ts +2 -0
- package/dist/components/inputs/TimeInput/TimeInput.d.ts +54 -0
- package/dist/components/inputs/TimeInput/TimeInput.js +107 -0
- package/dist/components/inputs/TimeInput/TimeInput.js.map +1 -0
- package/dist/components/inputs/TimeInput/index.d.ts +2 -0
- package/dist/components/inputs/internal/DateSegments.d.ts +80 -0
- package/dist/components/inputs/internal/DateSegments.js +345 -0
- package/dist/components/inputs/internal/DateSegments.js.map +1 -0
- package/dist/components/inputs/internal/dates.d.ts +101 -0
- package/dist/components/inputs/internal/dates.js +262 -0
- package/dist/components/inputs/internal/dates.js.map +1 -0
- package/dist/components/inputs/internal/filterOptions.d.ts +22 -1
- package/dist/components/inputs/internal/filterOptions.js +32 -1
- package/dist/components/inputs/internal/filterOptions.js.map +1 -1
- package/dist/components/inputs/internal/picker.d.ts +31 -0
- package/dist/components/inputs/internal/picker.js +29 -0
- package/dist/components/inputs/internal/picker.js.map +1 -0
- package/dist/components/inputs/internal/picker.module.js +15 -0
- package/dist/components/inputs/internal/picker.module.js.map +1 -0
- package/dist/components/inputs/internal/segments.module.js +10 -0
- package/dist/components/inputs/internal/segments.module.js.map +1 -0
- package/dist/components/layout/Collapse/Collapse.d.ts +39 -0
- package/dist/components/layout/Collapse/Collapse.js +24 -0
- package/dist/components/layout/Collapse/Collapse.js.map +1 -0
- package/dist/components/layout/Collapse/Collapse.module.js +6 -0
- package/dist/components/layout/Collapse/Collapse.module.js.map +1 -0
- package/dist/components/layout/Collapse/index.d.ts +2 -0
- package/dist/components/layout/Collapse/useHeightMotion.d.ts +16 -0
- package/dist/components/layout/Collapse/useHeightMotion.js +60 -0
- package/dist/components/layout/Collapse/useHeightMotion.js.map +1 -0
- package/dist/components/layout/ShowMore/ShowMore.d.ts +59 -0
- package/dist/components/layout/ShowMore/ShowMore.js +114 -0
- package/dist/components/layout/ShowMore/ShowMore.js.map +1 -0
- package/dist/components/layout/ShowMore/ShowMore.module.js +12 -0
- package/dist/components/layout/ShowMore/ShowMore.module.js.map +1 -0
- package/dist/components/layout/ShowMore/index.d.ts +2 -0
- package/dist/components/layout/Transition/Transition.d.ts +63 -0
- package/dist/components/layout/Transition/Transition.js +63 -0
- package/dist/components/layout/Transition/Transition.js.map +1 -0
- package/dist/components/layout/Transition/Transition.module.js +17 -0
- package/dist/components/layout/Transition/Transition.module.js.map +1 -0
- package/dist/components/layout/Transition/index.d.ts +2 -0
- package/dist/components/navigation/Collapsible/Collapsible.d.ts +49 -0
- package/dist/components/navigation/Collapsible/Collapsible.js +83 -0
- package/dist/components/navigation/Collapsible/Collapsible.js.map +1 -0
- package/dist/components/navigation/Collapsible/Collapsible.module.js +11 -0
- package/dist/components/navigation/Collapsible/Collapsible.module.js.map +1 -0
- package/dist/components/navigation/Collapsible/index.d.ts +2 -0
- package/dist/components/navigation/NavLinks/NavLinks.d.ts +32 -4
- package/dist/components/navigation/NavLinks/NavLinks.js +69 -39
- package/dist/components/navigation/NavLinks/NavLinks.js.map +1 -1
- package/dist/components/navigation/NavLinks/NavLinks.module.js +13 -3
- package/dist/components/navigation/NavLinks/NavLinks.module.js.map +1 -1
- package/dist/components/navigation/NavLinks/NavLinksGroup.d.ts +49 -0
- package/dist/components/navigation/NavLinks/NavLinksGroup.js +185 -0
- package/dist/components/navigation/NavLinks/NavLinksGroup.js.map +1 -0
- package/dist/components/navigation/NavLinks/context.d.ts +28 -0
- package/dist/components/navigation/NavLinks/context.js +13 -0
- package/dist/components/navigation/NavLinks/context.js.map +1 -0
- package/dist/components/navigation/NavLinks/index.d.ts +2 -0
- package/dist/components/navigation/NavLinks/treeKeys.d.ts +8 -0
- package/dist/components/navigation/NavLinks/treeKeys.js +57 -0
- package/dist/components/navigation/NavLinks/treeKeys.js.map +1 -0
- package/dist/components/overlays/CommandPalette/CommandPalette.d.ts +120 -0
- package/dist/components/overlays/CommandPalette/CommandPalette.js +386 -0
- package/dist/components/overlays/CommandPalette/CommandPalette.js.map +1 -0
- package/dist/components/overlays/CommandPalette/CommandPalette.module.js +31 -0
- package/dist/components/overlays/CommandPalette/CommandPalette.module.js.map +1 -0
- package/dist/components/overlays/CommandPalette/index.d.ts +2 -0
- package/dist/components/overlays/CommandPalette/shortcut.d.ts +28 -0
- package/dist/components/overlays/CommandPalette/shortcut.js +104 -0
- package/dist/components/overlays/CommandPalette/shortcut.js.map +1 -0
- package/dist/index.d.ts +40 -4
- package/dist/index.js +123 -100
- package/dist/styles.css +1 -1
- package/dist/themes/fiesta.css +1 -1
- package/dist/themes/flightdeck.css +1 -1
- package/dist/themes/ledger.css +1 -1
- package/dist/themes/monograph.css +1 -1
- package/dist/themes/riso.css +1 -1
- package/package.json +1 -1
- package/skills/custom-theme/SKILL.md +32 -0
- package/skills/custom-theme/references/colour.md +20 -0
- package/skills/custom-theme/references/motion.md +9 -0
- package/skills/custom-theme/references/tokens.md +35 -0
- package/skills/design-rules/SKILL.md +5 -2
- package/skills/setup-and-theming/SKILL.md +1 -1
- package/skills/setup-and-theming/references/paper.md +1 -1
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
//#region src/components/inputs/JsonInput/json.ts
|
|
2
|
+
var e = class extends Error {
|
|
3
|
+
offset;
|
|
4
|
+
constructor(e, t) {
|
|
5
|
+
super(e), this.offset = t;
|
|
6
|
+
}
|
|
7
|
+
}, t = /-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?/y, n = /* @__PURE__ */ new Set([
|
|
8
|
+
"\"",
|
|
9
|
+
"\\",
|
|
10
|
+
"/",
|
|
11
|
+
"b",
|
|
12
|
+
"f",
|
|
13
|
+
"n",
|
|
14
|
+
"r",
|
|
15
|
+
"t"
|
|
16
|
+
]), r = /^[0-9a-fA-F]{4}$/, i = /[A-Za-z0-9_$.+-]/;
|
|
17
|
+
function a(e, t) {
|
|
18
|
+
let n = e[t];
|
|
19
|
+
return n === void 0 ? "the end of the text" : n === "\n" || n === "\r" ? "a line break" : `“${n}”`;
|
|
20
|
+
}
|
|
21
|
+
function o(o) {
|
|
22
|
+
let s = 0, c = () => {
|
|
23
|
+
for (; s < o.length;) {
|
|
24
|
+
let e = o[s];
|
|
25
|
+
if (e === " " || e === " " || e === "\n" || e === "\r") s++;
|
|
26
|
+
else break;
|
|
27
|
+
}
|
|
28
|
+
}, l = () => {
|
|
29
|
+
let t = s;
|
|
30
|
+
for (s++; s < o.length;) {
|
|
31
|
+
let i = o[s];
|
|
32
|
+
if (i === "\"") return s++, o.slice(t, s);
|
|
33
|
+
if (i === "\\") {
|
|
34
|
+
let t = o[s + 1];
|
|
35
|
+
if (t === "u") {
|
|
36
|
+
if (!r.test(o.slice(s + 2, s + 6))) throw new e("A \\u escape needs four hex digits", s);
|
|
37
|
+
s += 6;
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
if (t === void 0 || !n.has(t)) throw new e(`“\\${t ?? ""}” isn't an escape JSON knows`, s);
|
|
41
|
+
s += 2;
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
if (i === "\n" || i === "\r") throw new e("This string isn’t closed before the end of the line", t);
|
|
45
|
+
if (i !== void 0 && i < " ") throw new e("Strings can’t contain control characters: escape them", s);
|
|
46
|
+
s++;
|
|
47
|
+
}
|
|
48
|
+
throw new e("This string isn’t closed", t);
|
|
49
|
+
}, u = () => {
|
|
50
|
+
c();
|
|
51
|
+
let n = o[s];
|
|
52
|
+
if (n === "{") return d();
|
|
53
|
+
if (n === "[") return f();
|
|
54
|
+
if (n === "\"") return {
|
|
55
|
+
kind: "literal",
|
|
56
|
+
raw: l()
|
|
57
|
+
};
|
|
58
|
+
if (n === "-" || n !== void 0 && n >= "0" && n <= "9") {
|
|
59
|
+
t.lastIndex = s;
|
|
60
|
+
let n = t.exec(o), r = n ? s + n[0].length : s;
|
|
61
|
+
if (!n || i.test(o[r] ?? "")) throw new e("This isn’t a valid number", s);
|
|
62
|
+
let a = n[0];
|
|
63
|
+
return s = r, {
|
|
64
|
+
kind: "literal",
|
|
65
|
+
raw: a
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
for (let e of [
|
|
69
|
+
"true",
|
|
70
|
+
"false",
|
|
71
|
+
"null"
|
|
72
|
+
]) if (o.startsWith(e, s) && !i.test(o[s + e.length] ?? "")) return s += e.length, {
|
|
73
|
+
kind: "literal",
|
|
74
|
+
raw: e
|
|
75
|
+
};
|
|
76
|
+
throw n === void 0 ? new e("Expected a value, but the text ends here", s) : n === "'" ? new e("Strings need double quotes", s) : new e(`Expected a value, not ${a(o, s)}`, s);
|
|
77
|
+
}, d = () => {
|
|
78
|
+
let t = s;
|
|
79
|
+
s++;
|
|
80
|
+
let n = [];
|
|
81
|
+
if (c(), o[s] === "}") return s++, {
|
|
82
|
+
kind: "object",
|
|
83
|
+
members: n
|
|
84
|
+
};
|
|
85
|
+
for (;;) {
|
|
86
|
+
if (c(), o[s] !== "\"") throw o[s] === void 0 ? new e("This object isn’t closed with “}”", t) : new e("Expected a property name in double quotes", s);
|
|
87
|
+
let r = l();
|
|
88
|
+
if (c(), o[s] !== ":") throw new e("Expected “:” after the property name", s);
|
|
89
|
+
if (s++, n.push({
|
|
90
|
+
key: r,
|
|
91
|
+
value: u()
|
|
92
|
+
}), c(), o[s] === ",") {
|
|
93
|
+
let t = s;
|
|
94
|
+
if (s++, c(), o[s] === "}") throw new e("Remove this comma: nothing follows it", t);
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
if (o[s] === "}") return s++, {
|
|
98
|
+
kind: "object",
|
|
99
|
+
members: n
|
|
100
|
+
};
|
|
101
|
+
throw o[s] === void 0 ? new e("This object isn’t closed with “}”", t) : new e(`Expected “,” or “}”, not ${a(o, s)}`, s);
|
|
102
|
+
}
|
|
103
|
+
}, f = () => {
|
|
104
|
+
let t = s;
|
|
105
|
+
s++;
|
|
106
|
+
let n = [];
|
|
107
|
+
if (c(), o[s] === "]") return s++, {
|
|
108
|
+
kind: "array",
|
|
109
|
+
items: n
|
|
110
|
+
};
|
|
111
|
+
for (;;) {
|
|
112
|
+
if (o[s] === void 0) throw new e("This array isn’t closed with “]”", t);
|
|
113
|
+
if (n.push(u()), c(), o[s] === ",") {
|
|
114
|
+
let t = s;
|
|
115
|
+
if (s++, c(), o[s] === "]") throw new e("Remove this comma: nothing follows it", t);
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
if (o[s] === "]") return s++, {
|
|
119
|
+
kind: "array",
|
|
120
|
+
items: n
|
|
121
|
+
};
|
|
122
|
+
throw o[s] === void 0 ? new e("This array isn’t closed with “]”", t) : new e(`Expected “,” or “]”, not ${a(o, s)}`, s);
|
|
123
|
+
}
|
|
124
|
+
}, p = u();
|
|
125
|
+
if (c(), s < o.length) throw new e("Unexpected text after the JSON value", s);
|
|
126
|
+
return p;
|
|
127
|
+
}
|
|
128
|
+
function s(e, t) {
|
|
129
|
+
let n = 1, r = 0;
|
|
130
|
+
for (let i = 0; i < t && i < e.length; i++) e[i] === "\n" && (n++, r = i + 1);
|
|
131
|
+
return {
|
|
132
|
+
line: n,
|
|
133
|
+
column: t - r + 1
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
function c(t) {
|
|
137
|
+
try {
|
|
138
|
+
return {
|
|
139
|
+
ok: !0,
|
|
140
|
+
node: o(t),
|
|
141
|
+
value: JSON.parse(t)
|
|
142
|
+
};
|
|
143
|
+
} catch (n) {
|
|
144
|
+
let r = n instanceof e ? n.offset : 0;
|
|
145
|
+
return {
|
|
146
|
+
ok: !1,
|
|
147
|
+
error: {
|
|
148
|
+
message: n instanceof Error ? n.message : String(n),
|
|
149
|
+
offset: r,
|
|
150
|
+
...s(t, r)
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
var l = (e) => JSON.parse(e);
|
|
156
|
+
function u(e, t, n, r) {
|
|
157
|
+
if (e.kind === "literal") return e.raw;
|
|
158
|
+
let i = t !== "", a = i ? `\n${t.repeat(r + 1)}` : "", o = i ? `\n${t.repeat(r)}` : "", s = i ? ": " : ":";
|
|
159
|
+
return e.kind === "array" ? e.items.length === 0 ? "[]" : `[${a}${e.items.map((e) => u(e, t, n, r + 1)).join(`,${a}`)}${o}]` : e.members.length === 0 ? "{}" : `{${a}${(n ? [...e.members].sort((e, t) => {
|
|
160
|
+
let n = l(e.key), r = l(t.key);
|
|
161
|
+
return n < r ? -1 : +(n > r);
|
|
162
|
+
}) : e.members).map(({ key: e, value: i }) => `${e}${s}${u(i, t, n, r + 1)}`).join(`,${a}`)}${o}}`;
|
|
163
|
+
}
|
|
164
|
+
function d(e, { indent: t = 2, sortKeys: n = !1 } = {}) {
|
|
165
|
+
let r = c(e);
|
|
166
|
+
if (r.ok) return u(r.node, t === "tab" ? " " : " ".repeat(t), n, 0);
|
|
167
|
+
}
|
|
168
|
+
function f(e, { sortKeys: t = !1 } = {}) {
|
|
169
|
+
let n = c(e);
|
|
170
|
+
if (n.ok) return u(n.node, "", t, 0);
|
|
171
|
+
}
|
|
172
|
+
var p = /* @__PURE__ */ new Set([
|
|
173
|
+
"{",
|
|
174
|
+
"}",
|
|
175
|
+
"[",
|
|
176
|
+
"]",
|
|
177
|
+
":",
|
|
178
|
+
","
|
|
179
|
+
]), m = /-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?/y, h = /true|false|null/y;
|
|
180
|
+
function g(e) {
|
|
181
|
+
let t = [], n = (e, n) => {
|
|
182
|
+
let r = t.at(-1);
|
|
183
|
+
r && r.type === n ? r.content += e : t.push(n ? {
|
|
184
|
+
content: e,
|
|
185
|
+
type: n
|
|
186
|
+
} : { content: e });
|
|
187
|
+
}, r = 0;
|
|
188
|
+
for (; r < e.length;) {
|
|
189
|
+
let t = e.charAt(r);
|
|
190
|
+
if (t === "\"") {
|
|
191
|
+
let t = r + 1;
|
|
192
|
+
for (; t < e.length;) {
|
|
193
|
+
let n = e[t];
|
|
194
|
+
if (n === "\\") t += 2;
|
|
195
|
+
else if (n === "\"") {
|
|
196
|
+
t++;
|
|
197
|
+
break;
|
|
198
|
+
} else if (n === "\n") break;
|
|
199
|
+
else t++;
|
|
200
|
+
}
|
|
201
|
+
t = Math.min(t, e.length);
|
|
202
|
+
let i = t;
|
|
203
|
+
for (; i < e.length && /\s/.test(e.charAt(i));) i++;
|
|
204
|
+
n(e.slice(r, t), e[i] === ":" ? "type" : "string"), r = t;
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
if (p.has(t)) {
|
|
208
|
+
n(t, "punctuation"), r++;
|
|
209
|
+
continue;
|
|
210
|
+
}
|
|
211
|
+
m.lastIndex = r, h.lastIndex = r;
|
|
212
|
+
let i = m.exec(e) ?? h.exec(e);
|
|
213
|
+
if (i?.index === r) {
|
|
214
|
+
n(i[0], "constant"), r += i[0].length;
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
n(t), r++;
|
|
218
|
+
}
|
|
219
|
+
let i = [[]];
|
|
220
|
+
for (let e of t) e.content.split("\n").forEach((t, n) => {
|
|
221
|
+
n > 0 && i.push([]), t && i[i.length - 1]?.push({
|
|
222
|
+
...e,
|
|
223
|
+
content: t
|
|
224
|
+
});
|
|
225
|
+
});
|
|
226
|
+
return i;
|
|
227
|
+
}
|
|
228
|
+
//#endregion
|
|
229
|
+
export { d as formatJson, f as minifyJson, c as parseJson, s as positionOf, g as tokenizeJson };
|
|
230
|
+
|
|
231
|
+
//# sourceMappingURL=json.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json.js","names":["Failure","message","offset","NUMBER","ESCAPES","HEX","WORD","describe","ch","text","at","parseNode","i","skip","string","start","next","value","object","array","match","end","raw","word","open","members","key","comma","items","node","positionOf","line","parseJson","reason","keyOf","print","pretty","unit","inner","depth","outer","separator","item","sortKeys","x","a","y","b","formatJson","parsed","indent","minifyJson","PUNCTUATION","LOOSE_NUMBER","LOOSE_WORD","tokenizeJson","flat","push","previous","type","content","c","after","literal","lines","token","index","part"],"sources":["../../../../src/components/inputs/JsonInput/json.ts"],"sourcesContent":["/*\n * JSON for JsonInput: a strict parser that reports where the text goes wrong in words, a printer\n * that formats or minifies without round-tripping through numbers (so `1.50` and\n * `12345678901234567890` keep their text), and a tolerant tokenizer that highlights text that\n * isn't valid yet. No dependencies, and the same messages in every browser.\n */\nimport type { CodeToken } from '#components/display/CodeBlock'\n\n/** Where a JSON text goes wrong: a message, and the 1-based line and column it points at. */\nexport interface JsonSyntaxError {\n message: string\n line: number\n column: number\n /** 0-based offset into the text. */\n offset: number\n}\n\n/** How formatted JSON is indented: two spaces, four spaces, or a tab. */\nexport type JsonIndent = 2 | 4 | 'tab'\n\ntype JsonNode =\n | { kind: 'object'; members: { key: string; value: JsonNode }[] }\n | { kind: 'array'; items: JsonNode[] }\n | { kind: 'literal'; raw: string }\n\nexport type JsonParse =\n { ok: true; node: JsonNode; value: unknown } | { ok: false; error: JsonSyntaxError }\n\nclass Failure extends Error {\n constructor(\n message: string,\n readonly offset: number,\n ) {\n super(message)\n }\n}\n\nconst NUMBER = /-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?/y\nconst ESCAPES = new Set(['\"', '\\\\', '/', 'b', 'f', 'n', 'r', 't'])\nconst HEX = /^[0-9a-fA-F]{4}$/\nconst WORD = /[A-Za-z0-9_$.+-]/\n\n/** Describes the character at `at` for a message: \"}\", \"the end of the text\". */\nfunction describe(text: string, at: number): string {\n const ch = text[at]\n if (ch === undefined) return 'the end of the text'\n if (ch === '\\n' || ch === '\\r') return 'a line break'\n return `“${ch}”`\n}\n\nfunction parseNode(text: string): JsonNode {\n let i = 0\n const skip = () => {\n while (i < text.length) {\n const ch = text[i]\n if (ch === ' ' || ch === '\\t' || ch === '\\n' || ch === '\\r') i++\n else break\n }\n }\n const string = (): string => {\n const start = i\n i++\n while (i < text.length) {\n const ch = text[i]\n if (ch === '\"') {\n i++\n return text.slice(start, i)\n }\n if (ch === '\\\\') {\n const next = text[i + 1]\n if (next === 'u') {\n if (!HEX.test(text.slice(i + 2, i + 6)))\n throw new Failure('A \\\\u escape needs four hex digits', i)\n i += 6\n continue\n }\n if (next === undefined || !ESCAPES.has(next))\n throw new Failure(`“\\\\${next ?? ''}” isn't an escape JSON knows`, i)\n i += 2\n continue\n }\n if (ch === '\\n' || ch === '\\r')\n throw new Failure('This string isn’t closed before the end of the line', start)\n if (ch !== undefined && ch < ' ')\n throw new Failure('Strings can’t contain control characters: escape them', i)\n i++\n }\n throw new Failure('This string isn’t closed', start)\n }\n const value = (): JsonNode => {\n skip()\n const ch = text[i]\n if (ch === '{') return object()\n if (ch === '[') return array()\n if (ch === '\"') return { kind: 'literal', raw: string() }\n if (ch === '-' || (ch !== undefined && ch >= '0' && ch <= '9')) {\n NUMBER.lastIndex = i\n const match = NUMBER.exec(text)\n const end = match ? i + match[0].length : i\n if (!match || WORD.test(text[end] ?? '')) throw new Failure('This isn’t a valid number', i)\n const raw = match[0]\n i = end\n return { kind: 'literal', raw }\n }\n for (const word of ['true', 'false', 'null']) {\n if (text.startsWith(word, i) && !WORD.test(text[i + word.length] ?? '')) {\n i += word.length\n return { kind: 'literal', raw: word }\n }\n }\n if (ch === undefined) throw new Failure('Expected a value, but the text ends here', i)\n if (ch === \"'\") throw new Failure('Strings need double quotes', i)\n throw new Failure(`Expected a value, not ${describe(text, i)}`, i)\n }\n const object = (): JsonNode => {\n const open = i\n i++\n const members: { key: string; value: JsonNode }[] = []\n skip()\n if (text[i] === '}') {\n i++\n return { kind: 'object', members }\n }\n for (;;) {\n skip()\n if (text[i] !== '\"') {\n if (text[i] === undefined) throw new Failure('This object isn’t closed with “}”', open)\n throw new Failure('Expected a property name in double quotes', i)\n }\n const key = string()\n skip()\n if (text[i] !== ':') throw new Failure('Expected “:” after the property name', i)\n i++\n members.push({ key, value: value() })\n skip()\n if (text[i] === ',') {\n const comma = i\n i++\n skip()\n if (text[i] === '}') throw new Failure('Remove this comma: nothing follows it', comma)\n continue\n }\n if (text[i] === '}') {\n i++\n return { kind: 'object', members }\n }\n if (text[i] === undefined) throw new Failure('This object isn’t closed with “}”', open)\n throw new Failure(`Expected “,” or “}”, not ${describe(text, i)}`, i)\n }\n }\n const array = (): JsonNode => {\n const open = i\n i++\n const items: JsonNode[] = []\n skip()\n if (text[i] === ']') {\n i++\n return { kind: 'array', items }\n }\n for (;;) {\n if (text[i] === undefined) throw new Failure('This array isn’t closed with “]”', open)\n items.push(value())\n skip()\n if (text[i] === ',') {\n const comma = i\n i++\n skip()\n if (text[i] === ']') throw new Failure('Remove this comma: nothing follows it', comma)\n continue\n }\n if (text[i] === ']') {\n i++\n return { kind: 'array', items }\n }\n if (text[i] === undefined) throw new Failure('This array isn’t closed with “]”', open)\n throw new Failure(`Expected “,” or “]”, not ${describe(text, i)}`, i)\n }\n }\n\n const node = value()\n skip()\n if (i < text.length) throw new Failure('Unexpected text after the JSON value', i)\n return node\n}\n\n/** 1-based line and column of `offset`. */\nexport function positionOf(text: string, offset: number): { line: number; column: number } {\n let line = 1\n let start = 0\n for (let i = 0; i < offset && i < text.length; i++) {\n if (text[i] === '\\n') {\n line++\n start = i + 1\n }\n }\n return { line, column: offset - start + 1 }\n}\n\n/** Parses `text` strictly, with the position and a plain message when it isn't valid. */\nexport function parseJson(text: string): JsonParse {\n try {\n const node = parseNode(text)\n return { ok: true, node, value: JSON.parse(text) as unknown }\n } catch (reason) {\n const offset = reason instanceof Failure ? reason.offset : 0\n const message = reason instanceof Error ? reason.message : String(reason)\n return { ok: false, error: { message, offset, ...positionOf(text, offset) } }\n }\n}\n\nconst keyOf = (raw: string) => JSON.parse(raw) as string\n\nfunction print(node: JsonNode, unit: string, sortKeys: boolean, depth: number): string {\n if (node.kind === 'literal') return node.raw\n const pretty = unit !== ''\n const inner = pretty ? `\\n${unit.repeat(depth + 1)}` : ''\n const outer = pretty ? `\\n${unit.repeat(depth)}` : ''\n const separator = pretty ? ': ' : ':'\n if (node.kind === 'array') {\n if (node.items.length === 0) return '[]'\n const items = node.items.map((item) => print(item, unit, sortKeys, depth + 1))\n return `[${inner}${items.join(`,${inner}`)}${outer}]`\n }\n if (node.members.length === 0) return '{}'\n const members = sortKeys\n ? [...node.members].sort((a, b) => {\n const x = keyOf(a.key)\n const y = keyOf(b.key)\n return x < y ? -1 : x > y ? 1 : 0\n })\n : node.members\n const lines = members.map(\n ({ key, value }) => `${key}${separator}${print(value, unit, sortKeys, depth + 1)}`,\n )\n return `{${inner}${lines.join(`,${inner}`)}${outer}}`\n}\n\n/**\n * `text` re-indented, or `undefined` when it isn't valid JSON. Numbers and strings keep their\n * exact text, and keys keep their order unless `sortKeys`.\n */\nexport function formatJson(\n text: string,\n { indent = 2, sortKeys = false }: { indent?: JsonIndent; sortKeys?: boolean } = {},\n): string | undefined {\n const parsed = parseJson(text)\n if (!parsed.ok) return undefined\n return print(parsed.node, indent === 'tab' ? '\\t' : ' '.repeat(indent), sortKeys, 0)\n}\n\n/** `text` on one line with no spaces, or `undefined` when it isn't valid JSON. */\nexport function minifyJson(\n text: string,\n { sortKeys = false }: { sortKeys?: boolean } = {},\n): string | undefined {\n const parsed = parseJson(text)\n if (!parsed.ok) return undefined\n return print(parsed.node, '', sortKeys, 0)\n}\n\nconst PUNCTUATION = new Set(['{', '}', '[', ']', ':', ','])\nconst LOOSE_NUMBER = /-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?/y\nconst LOOSE_WORD = /true|false|null/y\n\n/**\n * Tokens for highlighting, one array per line, in `CodeBlock`'s token types: property names are\n * `type`, strings `string`, numbers, `true`, `false` and `null` `constant`, and brackets, colons\n * and commas `punctuation`. Tolerant: text that isn't valid JSON yet still highlights as far as\n * it reads.\n */\nexport function tokenizeJson(text: string): CodeToken[][] {\n const flat: CodeToken[] = []\n const push = (content: string, type?: CodeToken['type']) => {\n const previous = flat.at(-1)\n if (previous && previous.type === type) previous.content += content\n else flat.push(type ? { content, type } : { content })\n }\n let i = 0\n while (i < text.length) {\n const ch = text.charAt(i)\n if (ch === '\"') {\n let end = i + 1\n while (end < text.length) {\n const c = text[end]\n if (c === '\\\\') end += 2\n else if (c === '\"') {\n end++\n break\n } else if (c === '\\n') break\n else end++\n }\n end = Math.min(end, text.length)\n let after = end\n while (after < text.length && /\\s/.test(text.charAt(after))) after++\n push(text.slice(i, end), text[after] === ':' ? 'type' : 'string')\n i = end\n continue\n }\n if (PUNCTUATION.has(ch)) {\n push(ch, 'punctuation')\n i++\n continue\n }\n LOOSE_NUMBER.lastIndex = i\n LOOSE_WORD.lastIndex = i\n const literal = LOOSE_NUMBER.exec(text) ?? LOOSE_WORD.exec(text)\n if (literal?.index === i) {\n push(literal[0], 'constant')\n i += literal[0].length\n continue\n }\n push(ch)\n i++\n }\n // Split into lines. Only plain runs (whitespace, stray text) can hold a line break.\n const lines: CodeToken[][] = [[]]\n for (const token of flat) {\n const parts = token.content.split('\\n')\n parts.forEach((part, index) => {\n if (index > 0) lines.push([])\n if (part) lines[lines.length - 1]?.push({ ...token, content: part })\n })\n }\n return lines\n}\n"],"mappings":"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"}
|
|
@@ -2,8 +2,8 @@ import { cx as e } from "../../../utils/cx.js";
|
|
|
2
2
|
import { useMergedRefs as t } from "../internal/refs.js";
|
|
3
3
|
import { markFieldAware as n, useResolvedField as r } from "../internal/FieldContext.js";
|
|
4
4
|
import i from "../internal/control.module.js";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
5
|
+
import { useControllableState as a } from "../Combobox/useControllableState.js";
|
|
6
|
+
import { Tag as o, TagList as s } from "../../display/Tag/Tag.js";
|
|
7
7
|
import c from "./TagsInput.module.js";
|
|
8
8
|
import { forwardRef as l, useRef as u, useState as d } from "react";
|
|
9
9
|
import { jsx as f, jsxs as p } from "react/jsx-runtime";
|
|
@@ -25,7 +25,7 @@ var _ = n(l(function({ value: n, defaultValue: l, onValueChange: h, delimiters:
|
|
|
25
25
|
required: E,
|
|
26
26
|
disabled: oe,
|
|
27
27
|
readOnly: D
|
|
28
|
-
}), H = !V.disabled && !V.readOnly, U = u(null), W = u(null), G = t(B, U), [K, q] =
|
|
28
|
+
}), H = !V.disabled && !V.readOnly, U = u(null), W = u(null), G = t(B, U), [K, q] = a(n, l ?? [], (e) => h?.([...e])), [J, Y] = d(""), X = g(_), se = (e) => b === "none" ? e : b === "lowercase" ? e.trim().toLowerCase() : e.trim(), Z = (e) => {
|
|
29
29
|
if (!H) return !1;
|
|
30
30
|
let t = [...K];
|
|
31
31
|
for (let n of e) {
|
|
@@ -102,9 +102,9 @@ var _ = n(l(function({ value: n, defaultValue: l, onValueChange: h, delimiters:
|
|
|
102
102
|
}),
|
|
103
103
|
/* @__PURE__ */ p("div", {
|
|
104
104
|
className: c.values,
|
|
105
|
-
children: [K.length > 0 ? /* @__PURE__ */ f(
|
|
105
|
+
children: [K.length > 0 ? /* @__PURE__ */ f(s, {
|
|
106
106
|
className: c.chips,
|
|
107
|
-
children: K.map((e, t) => /* @__PURE__ */ f(
|
|
107
|
+
children: K.map((e, t) => /* @__PURE__ */ f(o, {
|
|
108
108
|
className: c.chip,
|
|
109
109
|
onRemove: H ? () => {
|
|
110
110
|
$(t), U.current?.focus();
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type FieldLabelProps } from '../Field/index.js';
|
|
2
|
+
import { type TimeInputProps } from '../TimeInput/index.js';
|
|
3
|
+
export interface TimeFieldProps extends FieldLabelProps, Omit<TimeInputProps, 'invalid' | keyof FieldLabelProps> {
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* A labelled time of day, typed part by part on the locale's clock.
|
|
7
|
+
*
|
|
8
|
+
* @remarks
|
|
9
|
+
* `TimeField` is a {@link Field | Field} around a {@link TimeInput | TimeInput}.
|
|
10
|
+
*
|
|
11
|
+
* @privateRemarks
|
|
12
|
+
* Label + TimeInput + description + error. Input props and the ref go to the input's box;
|
|
13
|
+
* `className`/`style` go to the wrapper.
|
|
14
|
+
*
|
|
15
|
+
* <TimeField label="Opens at" value={opens} onValueChange={setOpens} />
|
|
16
|
+
*/
|
|
17
|
+
export declare const TimeField: import("react").ForwardRefExoticComponent<TimeFieldProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Field as e } from "../Field/Field.js";
|
|
2
|
+
import { splitFieldLabelProps as t } from "../internal/fieldProps.js";
|
|
3
|
+
import { TimeInput as n } from "../TimeInput/TimeInput.js";
|
|
4
|
+
import { forwardRef as r } from "react";
|
|
5
|
+
import { jsx as i } from "react/jsx-runtime";
|
|
6
|
+
//#region src/components/inputs/TimeField/TimeField.tsx
|
|
7
|
+
var a = r(function(r, a) {
|
|
8
|
+
let [o, s] = t(r), { id: c, disabled: l, className: u, style: d, ...f } = s;
|
|
9
|
+
return /* @__PURE__ */ i(e, {
|
|
10
|
+
...o,
|
|
11
|
+
htmlFor: c,
|
|
12
|
+
disabled: l,
|
|
13
|
+
className: u,
|
|
14
|
+
style: d,
|
|
15
|
+
children: /* @__PURE__ */ i(n, {
|
|
16
|
+
ref: a,
|
|
17
|
+
id: c,
|
|
18
|
+
disabled: l,
|
|
19
|
+
...f
|
|
20
|
+
})
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
//#endregion
|
|
24
|
+
export { a as TimeField };
|
|
25
|
+
|
|
26
|
+
//# sourceMappingURL=TimeField.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TimeField.js","names":["TimeField","forwardRef","fieldProps","rest","splitFieldLabelProps","props","inputRest","Field","id","TimeInput"],"sources":["../../../../src/components/inputs/TimeField/TimeField.tsx"],"sourcesContent":["import { forwardRef } from 'react'\nimport { Field, type FieldLabelProps } from '#components/inputs/Field'\nimport { TimeInput, type TimeInputProps } from '#components/inputs/TimeInput'\nimport { splitFieldLabelProps } from '#components/inputs/internal/fieldProps'\n\nexport interface TimeFieldProps\n extends FieldLabelProps, Omit<TimeInputProps, 'invalid' | keyof FieldLabelProps> {}\n\n/**\n * A labelled time of day, typed part by part on the locale's clock.\n *\n * @remarks\n * `TimeField` is a {@link Field | Field} around a {@link TimeInput | TimeInput}.\n *\n * @privateRemarks\n * Label + TimeInput + description + error. Input props and the ref go to the input's box;\n * `className`/`style` go to the wrapper.\n *\n * <TimeField label=\"Opens at\" value={opens} onValueChange={setOpens} />\n */\nexport const TimeField = forwardRef<HTMLDivElement, TimeFieldProps>(function TimeField(props, ref) {\n const [fieldProps, rest] = splitFieldLabelProps(props)\n const { id, disabled, className, style, ...inputRest } = rest\n return (\n <Field {...fieldProps} htmlFor={id} disabled={disabled} className={className} style={style}>\n <TimeInput ref={ref} id={id} disabled={disabled} {...inputRest} />\n </Field>\n )\n})\n"],"mappings":";;;;;;AAoBA,IAAaA,IAAYC,EAA2C,SAAmB,GAAO,GAAK;CACjG,IAAM,CAACC,GAAYC,KAAQC,EAAqBC,CAAK,GAC/C,EAAE,OAAI,aAAU,cAAW,UAAO,GAAGC,MAAcH;CACzD,OACE,kBAACI,GAAD;EAAO,GAAIL;EAAY,SAASM;EAAc;EAAqB;EAAkB;EACnF,UAAA,kBAACC,GAAD;GAAgB;GAAS;GAAc;GAAU,GAAIH;EAAY,CAAA;CAC5D,CAAA;AAEX,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { type FocusEventHandler, type HTMLAttributes } from 'react';
|
|
2
|
+
import type { Size } from '../../../utils/tokens.js';
|
|
3
|
+
import { type TimeGranularity } from '../internal/dates.js';
|
|
4
|
+
import { type DateTimeLabels } from '../internal/picker.js';
|
|
5
|
+
export interface TimeInputProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onChange' | 'defaultValue' | 'onBlur' | 'onFocus'> {
|
|
6
|
+
/** `HH:mm` (or `HH:mm:ss` with `granularity="second"`) on the 24-hour clock, or `''`. */
|
|
7
|
+
value?: string;
|
|
8
|
+
defaultValue?: string;
|
|
9
|
+
onValueChange?: (value: string) => void;
|
|
10
|
+
/** `minute` (default) or `second`: the smallest part shown and kept. */
|
|
11
|
+
granularity?: TimeGranularity;
|
|
12
|
+
/** 12 (with am/pm) or 24. Defaults to the locale's own clock. The value is always 24-hour. */
|
|
13
|
+
hourCycle?: 12 | 24;
|
|
14
|
+
/** Earliest time (`HH:mm`); an earlier one is marked invalid. */
|
|
15
|
+
min?: string;
|
|
16
|
+
/** Latest time (`HH:mm`). */
|
|
17
|
+
max?: string;
|
|
18
|
+
/** BCP 47 locale for the clock and the order of the parts. Default `en-AU`. */
|
|
19
|
+
locale?: string;
|
|
20
|
+
/** Show a clear button while there's a value. */
|
|
21
|
+
clearable?: boolean;
|
|
22
|
+
/** Submits the time (`''` when incomplete). */
|
|
23
|
+
name?: string;
|
|
24
|
+
form?: string;
|
|
25
|
+
size?: Size;
|
|
26
|
+
disabled?: boolean;
|
|
27
|
+
readOnly?: boolean;
|
|
28
|
+
required?: boolean;
|
|
29
|
+
/** Critical border + `aria-invalid`. Inside a `<Field error>` this is set for you. */
|
|
30
|
+
invalid?: boolean;
|
|
31
|
+
/** Fires once focus leaves the whole control, not as it moves between parts. */
|
|
32
|
+
onBlur?: FocusEventHandler<HTMLElement>;
|
|
33
|
+
onFocus?: FocusEventHandler<HTMLElement>;
|
|
34
|
+
labels?: Partial<DateTimeLabels>;
|
|
35
|
+
}
|
|
36
|
+
/** Whether `value` falls before `min` or after `max` (all `HH:mm[:ss]`). */
|
|
37
|
+
export declare function isTimeOutOfRange(value: string, min?: string, max?: string): boolean;
|
|
38
|
+
/**
|
|
39
|
+
* A time of day typed part by part, on the locale's 12- or 24-hour clock.
|
|
40
|
+
*
|
|
41
|
+
* @remarks
|
|
42
|
+
* `TimeInput` holds a time as `HH:mm` on the 24-hour clock (`14:30`), or `HH:mm:ss` with
|
|
43
|
+
* `granularity="second"`, whatever clock it shows. The hour, minute, second and am/pm are separate
|
|
44
|
+
* parts: type the digits and it moves on by itself, step a part with the arrow keys, or type `a`
|
|
45
|
+
* or `p` for am or pm. The clock follows `locale` unless you set `hourCycle`. For the usual
|
|
46
|
+
* labelled field, use {@link TimeField | TimeField}.
|
|
47
|
+
*
|
|
48
|
+
* @privateRemarks
|
|
49
|
+
* Same segment engine as DateInput, no popover: a time is quicker typed than picked. The ref goes
|
|
50
|
+
* to the `role="group"` box; the first part takes the Field's `id`.
|
|
51
|
+
*
|
|
52
|
+
* <TimeInput value={opens} onValueChange={setOpens} hourCycle={12} />
|
|
53
|
+
*/
|
|
54
|
+
export declare const TimeInput: import("react").ForwardRefExoticComponent<TimeInputProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { cx as e } from "../../../utils/cx.js";
|
|
2
|
+
import { CloseIcon as t } from "../../../icons/icons.js";
|
|
3
|
+
import { useMergedRefs as n } from "../internal/refs.js";
|
|
4
|
+
import { markFieldAware as r, useResolvedField as i } from "../internal/FieldContext.js";
|
|
5
|
+
import a from "../internal/control.module.js";
|
|
6
|
+
import { DEFAULT_LOCALE as ee, dayPeriodNames as te, defaultHourCycle as ne, formatTime as re, parseTime as o } from "../internal/dates.js";
|
|
7
|
+
import { useControllableState as ie } from "../Combobox/useControllableState.js";
|
|
8
|
+
import { DateSegments as s, draftFromParts as c, draftTime as l, segmentPattern as u, useSegmentDraft as d } from "../internal/DateSegments.js";
|
|
9
|
+
import { DEFAULT_DATE_TIME_LABELS as f, focusSegment as p, handleBoxPointerDown as m, isLeaving as h } from "../internal/picker.js";
|
|
10
|
+
import g from "../internal/picker.module.js";
|
|
11
|
+
import { forwardRef as _, useMemo as v, useRef as ae } from "react";
|
|
12
|
+
import { jsx as y, jsxs as oe } from "react/jsx-runtime";
|
|
13
|
+
//#region src/components/inputs/TimeInput/TimeInput.tsx
|
|
14
|
+
var b = (e) => {
|
|
15
|
+
let t = o(e ?? "");
|
|
16
|
+
return t ? (t.hour * 60 + t.minute) * 60 + t.second : null;
|
|
17
|
+
};
|
|
18
|
+
function x(e, t, n) {
|
|
19
|
+
let r = b(e);
|
|
20
|
+
if (r === null) return !1;
|
|
21
|
+
let i = b(t), a = b(n);
|
|
22
|
+
return i !== null && r < i || a !== null && r > a;
|
|
23
|
+
}
|
|
24
|
+
var S = r(_(function({ value: r, defaultValue: _, onValueChange: b, granularity: S = "minute", hourCycle: C, min: w, max: T, locale: E = ee, clearable: D = !1, name: O, form: k, size: A = "md", id: j, disabled: M, readOnly: N, required: P, invalid: F, onBlur: I, onFocus: L, labels: R, className: z, "aria-describedby": se, "aria-invalid": B, "aria-labelledby": V, ...H }, U) {
|
|
25
|
+
let W = {
|
|
26
|
+
...f,
|
|
27
|
+
...R
|
|
28
|
+
}, G = i({
|
|
29
|
+
id: j,
|
|
30
|
+
describedBy: se,
|
|
31
|
+
invalid: F,
|
|
32
|
+
ariaInvalid: B,
|
|
33
|
+
disabled: M,
|
|
34
|
+
readOnly: N,
|
|
35
|
+
required: P
|
|
36
|
+
}), K = ae(null), ce = n(U, K), q = C ?? ne(E), le = v(() => u("time", E, S, q), [
|
|
37
|
+
E,
|
|
38
|
+
S,
|
|
39
|
+
q
|
|
40
|
+
]), ue = v(() => te(E), [E]), [J, de] = ie(r, _ ?? "", b), [Y, X] = d(J, (e) => c(null, o(e)), (e) => {
|
|
41
|
+
let t = l(e);
|
|
42
|
+
return t && (S === "minute" || e.second !== void 0) ? re(t, S) : "";
|
|
43
|
+
}, de), Z = !G.disabled && !G.readOnly, Q = G.invalid || x(J, w, T), fe = Object.keys(Y).length > 0, $ = /* @__PURE__ */ new Date(), pe = {
|
|
44
|
+
hour: $.getHours(),
|
|
45
|
+
minute: $.getMinutes(),
|
|
46
|
+
second: 0
|
|
47
|
+
};
|
|
48
|
+
return /* @__PURE__ */ oe("div", {
|
|
49
|
+
ref: ce,
|
|
50
|
+
role: "group",
|
|
51
|
+
className: e(a.box, g.root, z),
|
|
52
|
+
"data-size": A,
|
|
53
|
+
"data-invalid": Q || void 0,
|
|
54
|
+
"data-disabled": G.disabled || void 0,
|
|
55
|
+
"data-readonly": G.readOnly || void 0,
|
|
56
|
+
"aria-labelledby": V ?? G.labelId,
|
|
57
|
+
"aria-describedby": G.describedBy,
|
|
58
|
+
"aria-busy": G.busy || void 0,
|
|
59
|
+
...H,
|
|
60
|
+
onPointerDown: m,
|
|
61
|
+
onFocus: (e) => {
|
|
62
|
+
h(e, K) && L?.(e);
|
|
63
|
+
},
|
|
64
|
+
onBlur: (e) => {
|
|
65
|
+
h(e, K) && I?.(e);
|
|
66
|
+
},
|
|
67
|
+
children: [
|
|
68
|
+
/* @__PURE__ */ y(s, {
|
|
69
|
+
pattern: le,
|
|
70
|
+
draft: Y,
|
|
71
|
+
onDraftChange: X,
|
|
72
|
+
hourCycle: q,
|
|
73
|
+
periodNames: ue,
|
|
74
|
+
labels: W,
|
|
75
|
+
reference: pe,
|
|
76
|
+
firstId: G.id,
|
|
77
|
+
disabled: G.disabled,
|
|
78
|
+
readOnly: G.readOnly,
|
|
79
|
+
invalid: Q,
|
|
80
|
+
required: G.required
|
|
81
|
+
}),
|
|
82
|
+
D && Z && fe ? /* @__PURE__ */ y("span", {
|
|
83
|
+
className: g.trailing,
|
|
84
|
+
children: /* @__PURE__ */ y("button", {
|
|
85
|
+
type: "button",
|
|
86
|
+
className: g.button,
|
|
87
|
+
"aria-label": W.clear,
|
|
88
|
+
onClick: () => {
|
|
89
|
+
X({}), p(K.current, "first");
|
|
90
|
+
},
|
|
91
|
+
children: /* @__PURE__ */ y(t, {})
|
|
92
|
+
})
|
|
93
|
+
}) : null,
|
|
94
|
+
O === void 0 ? null : /* @__PURE__ */ y("input", {
|
|
95
|
+
type: "hidden",
|
|
96
|
+
name: O,
|
|
97
|
+
form: k,
|
|
98
|
+
value: J,
|
|
99
|
+
disabled: G.disabled || void 0
|
|
100
|
+
})
|
|
101
|
+
]
|
|
102
|
+
});
|
|
103
|
+
}));
|
|
104
|
+
//#endregion
|
|
105
|
+
export { S as TimeInput, x as isTimeOutOfRange };
|
|
106
|
+
|
|
107
|
+
//# sourceMappingURL=TimeInput.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TimeInput.js","names":["control","picker","control_module_default","picker_module_default","secondsOf","time","parseTime","text","isTimeOutOfRange","seconds","value","lower","min","upper","max","TimeInput","markFieldAware","forwardRef","valueProp","hourCycleProp","DEFAULT_LOCALE","idProp","disabledProp","readOnlyProp","requiredProp","invalidProp","labelsProp","describedByProp","ariaInvalid","ariaLabelledBy","rest","labels","DEFAULT_DATE_TIME_LABELS","field","useResolvedField","rootRef","useRef","composedRef","useMergedRefs","ref","hourCycle","defaultHourCycle","locale","pattern","useMemo","segmentPattern","granularity","periodNames","dayPeriodNames","setValue","useControllableState","defaultValue","onValueChange","draft","setDraft","useSegmentDraft","draftFromParts","draftTime","formatTime","interactive","invalid","hasEntry","now","reference","cx","className","size","handleBoxPointerDown","isLeaving","event","onFocus","onBlur","DateSegments","clearable","focusSegment","CloseIcon","name"],"sources":["../../../../src/components/inputs/TimeInput/TimeInput.tsx"],"sourcesContent":["import { forwardRef, useMemo, useRef, type FocusEventHandler, type HTMLAttributes } from 'react'\nimport { CloseIcon } from '#icons'\nimport { cx } from '#utils/cx'\nimport type { Size } from '#utils/tokens'\nimport { useControllableState } from '#components/inputs/Combobox/useControllableState'\nimport { markFieldAware, useResolvedField } from '#components/inputs/internal/FieldContext'\nimport { useMergedRefs } from '#components/inputs/internal/refs'\nimport {\n DateSegments,\n draftFromParts,\n draftTime,\n segmentPattern,\n useSegmentDraft,\n type Draft,\n} from '#components/inputs/internal/DateSegments'\nimport {\n DEFAULT_LOCALE,\n dayPeriodNames,\n defaultHourCycle,\n formatTime,\n parseTime,\n type TimeGranularity,\n} from '#components/inputs/internal/dates'\nimport {\n DEFAULT_DATE_TIME_LABELS,\n focusSegment,\n handleBoxPointerDown,\n isLeaving,\n type DateTimeLabels,\n} from '#components/inputs/internal/picker'\nimport control from '#components/inputs/internal/control.module.css'\nimport picker from '#components/inputs/internal/picker.module.css'\n\nexport interface TimeInputProps extends Omit<\n HTMLAttributes<HTMLDivElement>,\n 'onChange' | 'defaultValue' | 'onBlur' | 'onFocus'\n> {\n /** `HH:mm` (or `HH:mm:ss` with `granularity=\"second\"`) on the 24-hour clock, or `''`. */\n value?: string\n defaultValue?: string\n onValueChange?: (value: string) => void\n /** `minute` (default) or `second`: the smallest part shown and kept. */\n granularity?: TimeGranularity\n /** 12 (with am/pm) or 24. Defaults to the locale's own clock. The value is always 24-hour. */\n hourCycle?: 12 | 24\n /** Earliest time (`HH:mm`); an earlier one is marked invalid. */\n min?: string\n /** Latest time (`HH:mm`). */\n max?: string\n /** BCP 47 locale for the clock and the order of the parts. Default `en-AU`. */\n locale?: string\n /** Show a clear button while there's a value. */\n clearable?: boolean\n /** Submits the time (`''` when incomplete). */\n name?: string\n form?: string\n size?: Size\n disabled?: boolean\n readOnly?: boolean\n required?: boolean\n /** Critical border + `aria-invalid`. Inside a `<Field error>` this is set for you. */\n invalid?: boolean\n /** Fires once focus leaves the whole control, not as it moves between parts. */\n onBlur?: FocusEventHandler<HTMLElement>\n onFocus?: FocusEventHandler<HTMLElement>\n labels?: Partial<DateTimeLabels>\n}\n\nconst secondsOf = (text: string | undefined): number | null => {\n const time = parseTime(text ?? '')\n return time ? (time.hour * 60 + time.minute) * 60 + time.second : null\n}\n\n/** Whether `value` falls before `min` or after `max` (all `HH:mm[:ss]`). */\nexport function isTimeOutOfRange(value: string, min?: string, max?: string): boolean {\n const seconds = secondsOf(value)\n if (seconds === null) return false\n const lower = secondsOf(min)\n const upper = secondsOf(max)\n return (lower !== null && seconds < lower) || (upper !== null && seconds > upper)\n}\n\n/**\n * A time of day typed part by part, on the locale's 12- or 24-hour clock.\n *\n * @remarks\n * `TimeInput` holds a time as `HH:mm` on the 24-hour clock (`14:30`), or `HH:mm:ss` with\n * `granularity=\"second\"`, whatever clock it shows. The hour, minute, second and am/pm are separate\n * parts: type the digits and it moves on by itself, step a part with the arrow keys, or type `a`\n * or `p` for am or pm. The clock follows `locale` unless you set `hourCycle`. For the usual\n * labelled field, use {@link TimeField | TimeField}.\n *\n * @privateRemarks\n * Same segment engine as DateInput, no popover: a time is quicker typed than picked. The ref goes\n * to the `role=\"group\"` box; the first part takes the Field's `id`.\n *\n * <TimeInput value={opens} onValueChange={setOpens} hourCycle={12} />\n */\nexport const TimeInput = markFieldAware(\n forwardRef<HTMLDivElement, TimeInputProps>(function TimeInput(\n {\n value: valueProp,\n defaultValue,\n onValueChange,\n granularity = 'minute',\n hourCycle: hourCycleProp,\n min,\n max,\n locale = DEFAULT_LOCALE,\n clearable = false,\n name,\n form,\n size = 'md',\n id: idProp,\n disabled: disabledProp,\n readOnly: readOnlyProp,\n required: requiredProp,\n invalid: invalidProp,\n onBlur,\n onFocus,\n labels: labelsProp,\n className,\n 'aria-describedby': describedByProp,\n 'aria-invalid': ariaInvalid,\n 'aria-labelledby': ariaLabelledBy,\n ...rest\n },\n ref,\n ) {\n const labels = { ...DEFAULT_DATE_TIME_LABELS, ...labelsProp }\n const field = useResolvedField({\n id: idProp,\n describedBy: describedByProp,\n invalid: invalidProp,\n ariaInvalid,\n disabled: disabledProp,\n readOnly: readOnlyProp,\n required: requiredProp,\n })\n const rootRef = useRef<HTMLDivElement>(null)\n const composedRef = useMergedRefs(ref, rootRef)\n const hourCycle = hourCycleProp ?? defaultHourCycle(locale)\n const pattern = useMemo(\n () => segmentPattern('time', locale, granularity, hourCycle),\n [locale, granularity, hourCycle],\n )\n const periodNames = useMemo(() => dayPeriodNames(locale), [locale])\n const [value, setValue] = useControllableState(valueProp, defaultValue ?? '', onValueChange)\n const toDraft = (text: string): Draft => draftFromParts(null, parseTime(text))\n const fromDraft = (draft: Draft): string => {\n const time = draftTime(draft)\n return time && (granularity === 'minute' || draft.second !== undefined)\n ? formatTime(time, granularity)\n : ''\n }\n const [draft, setDraft] = useSegmentDraft(value, toDraft, fromDraft, setValue)\n const interactive = !field.disabled && !field.readOnly\n const invalid = field.invalid || isTimeOutOfRange(value, min, max)\n const hasEntry = Object.keys(draft).length > 0\n const now = new Date()\n const reference: Draft = { hour: now.getHours(), minute: now.getMinutes(), second: 0 }\n\n return (\n <div\n ref={composedRef}\n role=\"group\"\n className={cx(control.box, picker.root, className)}\n data-size={size}\n data-invalid={invalid || undefined}\n data-disabled={field.disabled || undefined}\n data-readonly={field.readOnly || undefined}\n aria-labelledby={ariaLabelledBy ?? field.labelId}\n aria-describedby={field.describedBy}\n aria-busy={field.busy || undefined}\n {...rest}\n onPointerDown={handleBoxPointerDown}\n onFocus={(event) => {\n if (isLeaving(event, rootRef)) onFocus?.(event)\n }}\n onBlur={(event) => {\n if (isLeaving(event, rootRef)) onBlur?.(event)\n }}\n >\n <DateSegments\n pattern={pattern}\n draft={draft}\n onDraftChange={setDraft}\n hourCycle={hourCycle}\n periodNames={periodNames}\n labels={labels}\n reference={reference}\n firstId={field.id}\n disabled={field.disabled}\n readOnly={field.readOnly}\n invalid={invalid}\n required={field.required}\n />\n {clearable && interactive && hasEntry ? (\n <span className={picker.trailing}>\n <button\n type=\"button\"\n className={picker.button}\n aria-label={labels.clear}\n onClick={() => {\n setDraft({})\n focusSegment(rootRef.current, 'first')\n }}\n >\n <CloseIcon />\n </button>\n </span>\n ) : null}\n {name !== undefined ? (\n <input\n type=\"hidden\"\n name={name}\n form={form}\n value={value}\n disabled={field.disabled || undefined}\n />\n ) : null}\n </div>\n )\n }),\n)\n"],"mappings":"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"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { type FocusEvent } from 'react';
|
|
2
|
+
import { type CalendarDate, type TimeGranularity, type TimeOfDay } from './dates.js';
|
|
3
|
+
/**
|
|
4
|
+
* Segmented entry for dates and times: each part (day, month, year, hour, minute, second,
|
|
5
|
+
* am/pm) is its own spin button. Typing digits fills a part and moves on once it can't take
|
|
6
|
+
* another digit; arrows step it; Backspace clears it. Shared by DateInput, TimeInput,
|
|
7
|
+
* DateTimeInput and DateRangePickerField (internal, not exported).
|
|
8
|
+
*
|
|
9
|
+
* Each part is `contenteditable` only so a phone opens its numeric keyboard: every key and
|
|
10
|
+
* `beforeinput` is handled here and the DOM text never changes under React.
|
|
11
|
+
*/
|
|
12
|
+
export type SegmentField = 'year' | 'month' | 'day' | 'hour' | 'minute' | 'second';
|
|
13
|
+
export type SegmentType = SegmentField | 'dayPeriod';
|
|
14
|
+
/** The parts typed so far. `hour` is 0 to 23; `period` holds am/pm while the hour is empty. */
|
|
15
|
+
export type Draft = Partial<Record<SegmentField, number>> & {
|
|
16
|
+
period?: 'am' | 'pm';
|
|
17
|
+
};
|
|
18
|
+
export type SegmentPattern = ({
|
|
19
|
+
type: SegmentType;
|
|
20
|
+
} | {
|
|
21
|
+
type: 'literal';
|
|
22
|
+
value: string;
|
|
23
|
+
})[];
|
|
24
|
+
/** Accessible names of the parts, and the text an empty part shows. */
|
|
25
|
+
export interface SegmentLabels {
|
|
26
|
+
year: string;
|
|
27
|
+
month: string;
|
|
28
|
+
day: string;
|
|
29
|
+
hour: string;
|
|
30
|
+
minute: string;
|
|
31
|
+
second: string;
|
|
32
|
+
dayPeriod: string;
|
|
33
|
+
/** Read for an empty part. */
|
|
34
|
+
empty: string;
|
|
35
|
+
yearPlaceholder: string;
|
|
36
|
+
monthPlaceholder: string;
|
|
37
|
+
dayPlaceholder: string;
|
|
38
|
+
hourPlaceholder: string;
|
|
39
|
+
minutePlaceholder: string;
|
|
40
|
+
secondPlaceholder: string;
|
|
41
|
+
}
|
|
42
|
+
export declare const DEFAULT_SEGMENT_LABELS: SegmentLabels;
|
|
43
|
+
/**
|
|
44
|
+
* The parts and separators for `kind`, in the locale's order: "15/10/2026", "2:30 pm",
|
|
45
|
+
* "15/10/2026, 2:30 pm" in en-AU.
|
|
46
|
+
*/
|
|
47
|
+
export declare function segmentPattern(kind: 'date' | 'time' | 'datetime', locale: string, granularity: TimeGranularity, hourCycle: 12 | 24): SegmentPattern;
|
|
48
|
+
/** Whether every part in `pattern` has a value. */
|
|
49
|
+
export declare function isDraftComplete(draft: Draft, pattern: SegmentPattern): boolean;
|
|
50
|
+
export declare function draftFromParts(date?: CalendarDate | null, time?: TimeOfDay | null): Draft;
|
|
51
|
+
export declare function draftDate(draft: Draft): CalendarDate | null;
|
|
52
|
+
export declare function draftTime(draft: Draft): TimeOfDay | null;
|
|
53
|
+
/**
|
|
54
|
+
* Value ↔ draft for a segmented control. The draft holds partial entry (a day and month with
|
|
55
|
+
* no year yet); the value only changes once the draft is complete, or empties when a complete
|
|
56
|
+
* draft loses a part. A new value from outside (controlled, or a calendar pick) resets it.
|
|
57
|
+
*/
|
|
58
|
+
export declare function useSegmentDraft(value: string, toDraft: (value: string) => Draft, fromDraft: (draft: Draft) => string, setValue: (value: string) => void): [Draft, (next: Draft) => void];
|
|
59
|
+
export interface DateSegmentsProps {
|
|
60
|
+
pattern: SegmentPattern;
|
|
61
|
+
draft: Draft;
|
|
62
|
+
onDraftChange: (next: Draft) => void;
|
|
63
|
+
hourCycle: 12 | 24;
|
|
64
|
+
/** The locale's am and pm markers. */
|
|
65
|
+
periodNames: [string, string];
|
|
66
|
+
labels: SegmentLabels;
|
|
67
|
+
/** What an arrow key starts an empty part from (today, now). */
|
|
68
|
+
reference: Draft;
|
|
69
|
+
/** Id of the first part, which the field label points at. */
|
|
70
|
+
firstId?: string;
|
|
71
|
+
disabled?: boolean;
|
|
72
|
+
readOnly?: boolean;
|
|
73
|
+
invalid?: boolean;
|
|
74
|
+
required?: boolean;
|
|
75
|
+
describedBy?: string;
|
|
76
|
+
onFocus?: (event: FocusEvent<HTMLElement>) => void;
|
|
77
|
+
onBlur?: (event: FocusEvent<HTMLElement>) => void;
|
|
78
|
+
}
|
|
79
|
+
/** The parts and separators. The caller supplies the box and the `group` role around it. */
|
|
80
|
+
export declare const DateSegments: import("react").ForwardRefExoticComponent<DateSegmentsProps & import("react").RefAttributes<HTMLSpanElement>>;
|