@mitcsutt/kiln-ui 0.5.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.
Files changed (188) hide show
  1. package/dist/components/actions/CopyButton/CopyButton.d.ts +58 -0
  2. package/dist/components/actions/CopyButton/CopyButton.js +63 -0
  3. package/dist/components/actions/CopyButton/CopyButton.js.map +1 -0
  4. package/dist/components/actions/CopyButton/CopyButton.module.js +9 -0
  5. package/dist/components/actions/CopyButton/CopyButton.module.js.map +1 -0
  6. package/dist/components/actions/CopyButton/index.d.ts +4 -0
  7. package/dist/components/actions/CopyButton/useClipboard.d.ts +35 -0
  8. package/dist/components/actions/CopyButton/useClipboard.js +62 -0
  9. package/dist/components/actions/CopyButton/useClipboard.js.map +1 -0
  10. package/dist/components/actions/ToggleChip/ToggleChip.d.ts +6 -0
  11. package/dist/components/actions/ToggleChip/ToggleChip.js +26 -24
  12. package/dist/components/actions/ToggleChip/ToggleChip.js.map +1 -1
  13. package/dist/components/display/Badge/Badge.d.ts +6 -0
  14. package/dist/components/display/Badge/Badge.js +16 -15
  15. package/dist/components/display/Badge/Badge.js.map +1 -1
  16. package/dist/components/display/CodeBlock/CodeBlock.d.ts +44 -3
  17. package/dist/components/display/CodeBlock/CodeBlock.js +39 -47
  18. package/dist/components/display/CodeBlock/CodeBlock.js.map +1 -1
  19. package/dist/components/display/CodeBlock/CodeBlock.module.js +4 -3
  20. package/dist/components/display/CodeBlock/CodeBlock.module.js.map +1 -1
  21. package/dist/components/display/CodeBlock/index.d.ts +1 -1
  22. package/dist/components/display/Swatch/Swatch.d.ts +52 -0
  23. package/dist/components/display/Swatch/Swatch.js +27 -0
  24. package/dist/components/display/Swatch/Swatch.js.map +1 -0
  25. package/dist/components/display/Swatch/Swatch.module.js +6 -0
  26. package/dist/components/display/Swatch/Swatch.module.js.map +1 -0
  27. package/dist/components/display/Swatch/index.d.ts +2 -0
  28. package/dist/components/display/Tag/Tag.d.ts +7 -0
  29. package/dist/components/display/Tag/Tag.js +31 -26
  30. package/dist/components/display/Tag/Tag.js.map +1 -1
  31. package/dist/components/feedback/Indicator/Indicator.d.ts +74 -0
  32. package/dist/components/feedback/Indicator/Indicator.js +50 -0
  33. package/dist/components/feedback/Indicator/Indicator.js.map +1 -0
  34. package/dist/components/feedback/Indicator/Indicator.module.js +12 -0
  35. package/dist/components/feedback/Indicator/Indicator.module.js.map +1 -0
  36. package/dist/components/feedback/Indicator/index.d.ts +2 -0
  37. package/dist/components/feedback/Toaster/Toaster.d.ts +71 -0
  38. package/dist/components/feedback/Toaster/Toaster.js +121 -0
  39. package/dist/components/feedback/Toaster/Toaster.js.map +1 -0
  40. package/dist/components/feedback/Toaster/Toaster.module.js +20 -0
  41. package/dist/components/feedback/Toaster/Toaster.module.js.map +1 -0
  42. package/dist/components/feedback/Toaster/index.d.ts +4 -0
  43. package/dist/components/feedback/Toaster/toast.d.ts +96 -0
  44. package/dist/components/feedback/Toaster/toast.js +131 -0
  45. package/dist/components/feedback/Toaster/toast.js.map +1 -0
  46. package/dist/components/inputs/Calendar/Calendar.d.ts +87 -0
  47. package/dist/components/inputs/Calendar/Calendar.js +217 -0
  48. package/dist/components/inputs/Calendar/Calendar.js.map +1 -0
  49. package/dist/components/inputs/Calendar/Calendar.module.js +18 -0
  50. package/dist/components/inputs/Calendar/Calendar.module.js.map +1 -0
  51. package/dist/components/inputs/Calendar/index.d.ts +2 -0
  52. package/dist/components/inputs/Combobox/Combobox.js +36 -44
  53. package/dist/components/inputs/Combobox/Combobox.js.map +1 -1
  54. package/dist/components/inputs/DateField/DateField.d.ts +17 -0
  55. package/dist/components/inputs/DateField/DateField.js +26 -0
  56. package/dist/components/inputs/DateField/DateField.js.map +1 -0
  57. package/dist/components/inputs/DateField/index.d.ts +2 -0
  58. package/dist/components/inputs/DateInput/DateInput.d.ts +75 -0
  59. package/dist/components/inputs/DateInput/DateInput.js +139 -0
  60. package/dist/components/inputs/DateInput/DateInput.js.map +1 -0
  61. package/dist/components/inputs/DateInput/index.d.ts +3 -0
  62. package/dist/components/inputs/DateRangeField/DateRangeField.d.ts +18 -3
  63. package/dist/components/inputs/DateRangeField/DateRangeField.js.map +1 -1
  64. package/dist/components/inputs/DateRangeField/DateRangeField.module.js +8 -3
  65. package/dist/components/inputs/DateRangeField/DateRangeField.module.js.map +1 -1
  66. package/dist/components/inputs/DateRangeField/DateRangePickerField.d.ts +48 -0
  67. package/dist/components/inputs/DateRangeField/DateRangePickerField.js +246 -0
  68. package/dist/components/inputs/DateRangeField/DateRangePickerField.js.map +1 -0
  69. package/dist/components/inputs/DateRangeField/index.d.ts +2 -0
  70. package/dist/components/inputs/DateTimeField/DateTimeField.d.ts +17 -0
  71. package/dist/components/inputs/DateTimeField/DateTimeField.js +26 -0
  72. package/dist/components/inputs/DateTimeField/DateTimeField.js.map +1 -0
  73. package/dist/components/inputs/DateTimeField/index.d.ts +2 -0
  74. package/dist/components/inputs/DateTimeInput/DateTimeInput.d.ts +83 -0
  75. package/dist/components/inputs/DateTimeInput/DateTimeInput.js +216 -0
  76. package/dist/components/inputs/DateTimeInput/DateTimeInput.js.map +1 -0
  77. package/dist/components/inputs/DateTimeInput/index.d.ts +2 -0
  78. package/dist/components/inputs/JsonField/JsonField.d.ts +23 -0
  79. package/dist/components/inputs/JsonField/JsonField.js +33 -0
  80. package/dist/components/inputs/JsonField/JsonField.js.map +1 -0
  81. package/dist/components/inputs/JsonField/index.d.ts +2 -0
  82. package/dist/components/inputs/JsonInput/JsonInput.d.ts +119 -0
  83. package/dist/components/inputs/JsonInput/JsonInput.js +282 -0
  84. package/dist/components/inputs/JsonInput/JsonInput.js.map +1 -0
  85. package/dist/components/inputs/JsonInput/JsonInput.module.js +16 -0
  86. package/dist/components/inputs/JsonInput/JsonInput.module.js.map +1 -0
  87. package/dist/components/inputs/JsonInput/index.d.ts +4 -0
  88. package/dist/components/inputs/JsonInput/json.d.ts +59 -0
  89. package/dist/components/inputs/JsonInput/json.js +231 -0
  90. package/dist/components/inputs/JsonInput/json.js.map +1 -0
  91. package/dist/components/inputs/TagsInput/TagsInput.js +5 -5
  92. package/dist/components/inputs/TimeField/TimeField.d.ts +17 -0
  93. package/dist/components/inputs/TimeField/TimeField.js +26 -0
  94. package/dist/components/inputs/TimeField/TimeField.js.map +1 -0
  95. package/dist/components/inputs/TimeField/index.d.ts +2 -0
  96. package/dist/components/inputs/TimeInput/TimeInput.d.ts +54 -0
  97. package/dist/components/inputs/TimeInput/TimeInput.js +107 -0
  98. package/dist/components/inputs/TimeInput/TimeInput.js.map +1 -0
  99. package/dist/components/inputs/TimeInput/index.d.ts +2 -0
  100. package/dist/components/inputs/internal/DateSegments.d.ts +80 -0
  101. package/dist/components/inputs/internal/DateSegments.js +345 -0
  102. package/dist/components/inputs/internal/DateSegments.js.map +1 -0
  103. package/dist/components/inputs/internal/dates.d.ts +101 -0
  104. package/dist/components/inputs/internal/dates.js +262 -0
  105. package/dist/components/inputs/internal/dates.js.map +1 -0
  106. package/dist/components/inputs/internal/filterOptions.d.ts +22 -1
  107. package/dist/components/inputs/internal/filterOptions.js +32 -1
  108. package/dist/components/inputs/internal/filterOptions.js.map +1 -1
  109. package/dist/components/inputs/internal/picker.d.ts +31 -0
  110. package/dist/components/inputs/internal/picker.js +29 -0
  111. package/dist/components/inputs/internal/picker.js.map +1 -0
  112. package/dist/components/inputs/internal/picker.module.js +15 -0
  113. package/dist/components/inputs/internal/picker.module.js.map +1 -0
  114. package/dist/components/inputs/internal/segments.module.js +10 -0
  115. package/dist/components/inputs/internal/segments.module.js.map +1 -0
  116. package/dist/components/layout/Collapse/Collapse.d.ts +39 -0
  117. package/dist/components/layout/Collapse/Collapse.js +24 -0
  118. package/dist/components/layout/Collapse/Collapse.js.map +1 -0
  119. package/dist/components/layout/Collapse/Collapse.module.js +6 -0
  120. package/dist/components/layout/Collapse/Collapse.module.js.map +1 -0
  121. package/dist/components/layout/Collapse/index.d.ts +2 -0
  122. package/dist/components/layout/Collapse/useHeightMotion.d.ts +16 -0
  123. package/dist/components/layout/Collapse/useHeightMotion.js +60 -0
  124. package/dist/components/layout/Collapse/useHeightMotion.js.map +1 -0
  125. package/dist/components/layout/ShowMore/ShowMore.d.ts +59 -0
  126. package/dist/components/layout/ShowMore/ShowMore.js +114 -0
  127. package/dist/components/layout/ShowMore/ShowMore.js.map +1 -0
  128. package/dist/components/layout/ShowMore/ShowMore.module.js +12 -0
  129. package/dist/components/layout/ShowMore/ShowMore.module.js.map +1 -0
  130. package/dist/components/layout/ShowMore/index.d.ts +2 -0
  131. package/dist/components/layout/Transition/Transition.d.ts +63 -0
  132. package/dist/components/layout/Transition/Transition.js +63 -0
  133. package/dist/components/layout/Transition/Transition.js.map +1 -0
  134. package/dist/components/layout/Transition/Transition.module.js +17 -0
  135. package/dist/components/layout/Transition/Transition.module.js.map +1 -0
  136. package/dist/components/layout/Transition/index.d.ts +2 -0
  137. package/dist/components/navigation/Collapsible/Collapsible.d.ts +49 -0
  138. package/dist/components/navigation/Collapsible/Collapsible.js +83 -0
  139. package/dist/components/navigation/Collapsible/Collapsible.js.map +1 -0
  140. package/dist/components/navigation/Collapsible/Collapsible.module.js +11 -0
  141. package/dist/components/navigation/Collapsible/Collapsible.module.js.map +1 -0
  142. package/dist/components/navigation/Collapsible/index.d.ts +2 -0
  143. package/dist/components/navigation/NavLinks/NavLinks.d.ts +32 -4
  144. package/dist/components/navigation/NavLinks/NavLinks.js +69 -39
  145. package/dist/components/navigation/NavLinks/NavLinks.js.map +1 -1
  146. package/dist/components/navigation/NavLinks/NavLinks.module.js +13 -3
  147. package/dist/components/navigation/NavLinks/NavLinks.module.js.map +1 -1
  148. package/dist/components/navigation/NavLinks/NavLinksGroup.d.ts +49 -0
  149. package/dist/components/navigation/NavLinks/NavLinksGroup.js +185 -0
  150. package/dist/components/navigation/NavLinks/NavLinksGroup.js.map +1 -0
  151. package/dist/components/navigation/NavLinks/context.d.ts +28 -0
  152. package/dist/components/navigation/NavLinks/context.js +13 -0
  153. package/dist/components/navigation/NavLinks/context.js.map +1 -0
  154. package/dist/components/navigation/NavLinks/index.d.ts +2 -0
  155. package/dist/components/navigation/NavLinks/treeKeys.d.ts +8 -0
  156. package/dist/components/navigation/NavLinks/treeKeys.js +57 -0
  157. package/dist/components/navigation/NavLinks/treeKeys.js.map +1 -0
  158. package/dist/components/overlays/CommandPalette/CommandPalette.d.ts +120 -0
  159. package/dist/components/overlays/CommandPalette/CommandPalette.js +386 -0
  160. package/dist/components/overlays/CommandPalette/CommandPalette.js.map +1 -0
  161. package/dist/components/overlays/CommandPalette/CommandPalette.module.js +31 -0
  162. package/dist/components/overlays/CommandPalette/CommandPalette.module.js.map +1 -0
  163. package/dist/components/overlays/CommandPalette/index.d.ts +2 -0
  164. package/dist/components/overlays/CommandPalette/shortcut.d.ts +28 -0
  165. package/dist/components/overlays/CommandPalette/shortcut.js +104 -0
  166. package/dist/components/overlays/CommandPalette/shortcut.js.map +1 -0
  167. package/dist/highlight/index.d.ts +18 -0
  168. package/dist/highlight/index.js +103 -0
  169. package/dist/highlight/index.js.map +1 -0
  170. package/dist/index.d.ts +41 -5
  171. package/dist/index.js +123 -100
  172. package/dist/styles.css +1 -1
  173. package/dist/themes/fiesta.css +1 -1
  174. package/dist/themes/flightdeck.css +1 -1
  175. package/dist/themes/ledger.css +1 -1
  176. package/dist/themes/monograph.css +1 -1
  177. package/dist/themes/riso.css +1 -1
  178. package/dist/utils/newlines.d.ts +2 -0
  179. package/dist/utils/newlines.js +10 -0
  180. package/dist/utils/newlines.js.map +1 -0
  181. package/package.json +13 -2
  182. package/skills/custom-theme/SKILL.md +32 -0
  183. package/skills/custom-theme/references/colour.md +20 -0
  184. package/skills/custom-theme/references/motion.md +9 -0
  185. package/skills/custom-theme/references/tokens.md +35 -0
  186. package/skills/design-rules/SKILL.md +5 -2
  187. package/skills/setup-and-theming/SKILL.md +2 -1
  188. package/skills/setup-and-theming/references/paper.md +1 -1
@@ -0,0 +1,282 @@
1
+ import { cx as e } from "../../../utils/cx.js";
2
+ import { mergeStyles as t } from "../../../utils/responsive.js";
3
+ import { joinIds as n, useMergedRefs as r } from "../internal/refs.js";
4
+ import { useLatest as i } from "../internal/useLatest.js";
5
+ import { Button as a } from "../../actions/Button/Button.js";
6
+ import { CopyButton as o } from "../../actions/CopyButton/CopyButton.js";
7
+ import { markFieldAware as s, useResolvedField as c } from "../internal/FieldContext.js";
8
+ import ee from "../internal/control.module.js";
9
+ import { formatJson as l, minifyJson as te, parseJson as u, tokenizeJson as ne } from "./json.js";
10
+ import d from "./JsonInput.module.js";
11
+ import { forwardRef as f, useEffect as p, useId as re, useLayoutEffect as m, useMemo as h, useRef as g, useState as _ } from "react";
12
+ import { Fragment as ie, jsx as v, jsxs as y } from "react/jsx-runtime";
13
+ //#region src/components/inputs/JsonInput/JsonInput.tsx
14
+ var b = typeof document > "u" ? p : m, x = {
15
+ parsed: void 0,
16
+ valid: !0
17
+ };
18
+ function S(e, t) {
19
+ if (e.trim() === "") return x;
20
+ let n = u(e);
21
+ if (!n.ok) {
22
+ let { message: e, line: t, column: r } = n.error;
23
+ return {
24
+ parsed: void 0,
25
+ valid: !1,
26
+ error: {
27
+ message: e,
28
+ line: t,
29
+ column: r
30
+ }
31
+ };
32
+ }
33
+ let r = t?.(n.value);
34
+ return r === void 0 ? {
35
+ parsed: n.value,
36
+ valid: !0
37
+ } : {
38
+ parsed: n.value,
39
+ valid: !1,
40
+ error: { message: r }
41
+ };
42
+ }
43
+ function ae(e, t) {
44
+ return e.valid === t.valid && e.error?.message === t.error?.message && e.error?.line === t.error?.line && e.error?.column === t.error?.column && (e.parsed === t.parsed || JSON.stringify(e.parsed) === JSON.stringify(t.parsed));
45
+ }
46
+ var C = {
47
+ "{": "}",
48
+ "[": "]",
49
+ "\"": "\""
50
+ }, oe = /* @__PURE__ */ new Set([
51
+ "}",
52
+ "]",
53
+ "\""
54
+ ]), se = (e) => e === "tab" ? " " : " ".repeat(e), w = (e, t) => e.lastIndexOf("\n", t - 1) + 1, T = s(f(function({ value: s, defaultValue: u = "", onValueChange: f, onValidationChange: m, validate: x, validationDelay: T = 500, indent: E = 2, sortKeys: D = !1, formatOnBlur: ce = !1, autoClose: O = !0, lineNumbers: k = !0, wrap: A = !1, toolbar: le = !0, minRows: ue = 4, maxRows: j, invalid: de, copyLabel: fe = "Copy JSON", id: pe, disabled: me, required: he, readOnly: ge, className: _e, style: ve, onChange: M, onKeyDown: N, onBlur: P, "aria-describedby": F, "aria-invalid": ye, ...be }, xe) {
55
+ let I = g(null), Se = r(xe, I), L = c({
56
+ id: pe,
57
+ describedBy: F,
58
+ invalid: de,
59
+ ariaInvalid: ye,
60
+ disabled: me,
61
+ readOnly: ge
62
+ }), R = !L.disabled && !L.readOnly, z = re(), [Ce, we] = _(u), B = s ?? Ce, V = i({
63
+ onValueChange: f,
64
+ onValidationChange: m,
65
+ validate: x
66
+ }), H = h(() => S(B, x), [B, x]), [U, Te] = _(H), [W, Ee] = _({
67
+ text: "",
68
+ count: 0
69
+ }), G = (e) => {
70
+ Ee((t) => ({
71
+ text: e,
72
+ count: t.count + 1
73
+ }));
74
+ }, K = g(!1), q = g(null), J = (e) => {
75
+ Te((t) => ae(t, e) ? t : e);
76
+ };
77
+ p(() => {
78
+ if (H.valid) {
79
+ J(H);
80
+ return;
81
+ }
82
+ let e = setTimeout(() => {
83
+ J(H);
84
+ }, T);
85
+ return () => {
86
+ clearTimeout(e);
87
+ };
88
+ }, [H, T]), p(() => {
89
+ V.current.onValidationChange?.(U);
90
+ }, [U, V]), b(() => {
91
+ let e = q.current;
92
+ e && I.current && (q.current = null, I.current.setSelectionRange(e[0], e[1]));
93
+ });
94
+ let Y = (e) => {
95
+ s === void 0 && we(e), V.current.onValueChange?.(e, S(e, V.current.validate));
96
+ }, X = (e, t, n, r = [e + n.length, e + n.length]) => {
97
+ let i = I.current;
98
+ if (!i) return;
99
+ let a = B.slice(0, e) + n + B.slice(t);
100
+ if (i.focus(), i.setSelectionRange(e, t), typeof document.execCommand == "function" && document.execCommand(n === "" ? "delete" : "insertText", !1, n) && i.value === a) {
101
+ i.setSelectionRange(...r);
102
+ return;
103
+ }
104
+ q.current = r, Y(a);
105
+ }, Z = (e) => {
106
+ let t = e === "format" ? l(B, {
107
+ indent: E,
108
+ sortKeys: D
109
+ }) : te(B, { sortKeys: D });
110
+ if (t === void 0) {
111
+ let e = H.error?.line;
112
+ G(B.trim() === "" ? "Nothing to format" : `Fix the error${e ? ` on line ${String(e)}` : ""} first`), J(H);
113
+ return;
114
+ }
115
+ if (G(e === "format" ? "Formatted" : "Minified"), t === B) return;
116
+ let n = Math.min(I.current?.selectionStart ?? 0, t.length);
117
+ X(0, B.length, t, [n, n]);
118
+ }, De = (e) => {
119
+ M?.(e), Y(e.target.value);
120
+ }, Oe = (e) => {
121
+ if (P?.(e), K.current = !1, J(H), ce && R && H.valid) {
122
+ let e = l(B, {
123
+ indent: E,
124
+ sortKeys: D
125
+ });
126
+ e !== void 0 && e !== B && Y(e);
127
+ }
128
+ }, ke = (e) => {
129
+ if (N?.(e), e.defaultPrevented || e.nativeEvent.isComposing || !R) return;
130
+ let t = e.currentTarget, { selectionStart: n, selectionEnd: r } = t, i = se(E);
131
+ if (e.key === "Escape") {
132
+ K.current = !0, G("Press Tab to leave the editor");
133
+ return;
134
+ }
135
+ if (e.key === "Tab" && !e.ctrlKey && !e.metaKey && !e.altKey) {
136
+ if (K.current) {
137
+ K.current = !1;
138
+ return;
139
+ }
140
+ e.preventDefault();
141
+ let t = w(B, n), a = B.slice(n, r).includes("\n");
142
+ if (!e.shiftKey && !a) {
143
+ X(n, r, i);
144
+ return;
145
+ }
146
+ let o = r > n && B[r - 1] === "\n" ? r - 1 : r, s = B.slice(t, o), c = s.split("\n").map((t) => e.shiftKey ? t.startsWith(i) ? t.slice(i.length) : t.replace(/^[ \t]+/, (e) => e.slice(i.length)) : `${i}${t}`).join("\n");
147
+ if (c === s) return;
148
+ X(t, o, c, [t, t + c.length]);
149
+ return;
150
+ }
151
+ if (K.current = !1, e.key === "F" || e.code === "KeyF") {
152
+ e.shiftKey && e.altKey && !e.ctrlKey && !e.metaKey && (e.preventDefault(), Z("format"));
153
+ return;
154
+ }
155
+ if (e.ctrlKey || e.metaKey || e.altKey) return;
156
+ if (e.key === "Enter") {
157
+ e.preventDefault();
158
+ let t = w(B, n), a = /^[ \t]*/.exec(B.slice(t, n))?.[0] ?? "", o = B.slice(0, n).trimEnd().at(-1), s = B[r], c = o === "{" || o === "[";
159
+ if (c && s === C[o]) {
160
+ let e = `\n${a}${i}`, t = n + e.length;
161
+ X(n, r, `${e}\n${a}`, [t, t]);
162
+ } else X(n, r, `\n${a}${c ? i : ""}`);
163
+ return;
164
+ }
165
+ if (e.key === "Backspace" && n === r && n > 0) {
166
+ let t = B.charAt(n - 1);
167
+ O && C[t] !== void 0 && B[n] === C[t] && (e.preventDefault(), X(n - 1, n + 1, ""));
168
+ return;
169
+ }
170
+ if (!O || e.key.length !== 1) return;
171
+ if (oe.has(e.key) && n === r && B[n] === e.key && (e.key !== "\"" || B[n - 1] !== "\\")) {
172
+ e.preventDefault(), t.setSelectionRange(n + 1, n + 1);
173
+ return;
174
+ }
175
+ let a = C[e.key];
176
+ if (a === void 0) return;
177
+ if (e.key === "\"") {
178
+ let e = B[n - 1] ?? "", t = B[r] ?? "";
179
+ if (/[\w"\\]/.test(e) || /[\w"]/.test(t)) return;
180
+ }
181
+ e.preventDefault();
182
+ let o = B.slice(n, r), s = n + 1 + o.length;
183
+ X(n, r, `${e.key}${o}${a}`, [s, s]);
184
+ }, Q = h(() => ne(B), [B]), Ae = U.error?.line, $ = L.invalid || !U.valid, je = String(Q.length).length;
185
+ return /* @__PURE__ */ y("div", {
186
+ className: e(ee.box, d.root, _e),
187
+ style: t({
188
+ "--_min-rows": ue,
189
+ "--_max-rows": j,
190
+ "--_digits": je
191
+ }, ve),
192
+ "data-invalid": $ || void 0,
193
+ "data-disabled": L.disabled || void 0,
194
+ "data-readonly": L.readOnly || void 0,
195
+ "data-wrap": A || void 0,
196
+ "data-line-numbers": k || void 0,
197
+ "data-max-rows": j ? "" : void 0,
198
+ children: [
199
+ le ? /* @__PURE__ */ y("div", {
200
+ className: d.toolbar,
201
+ children: [R ? /* @__PURE__ */ y(ie, { children: [/* @__PURE__ */ v(a, {
202
+ variant: "ghost",
203
+ tone: "neutral",
204
+ size: "sm",
205
+ onClick: () => {
206
+ Z("format");
207
+ },
208
+ children: "Format"
209
+ }), /* @__PURE__ */ v(a, {
210
+ variant: "ghost",
211
+ tone: "neutral",
212
+ size: "sm",
213
+ onClick: () => {
214
+ Z("minify");
215
+ },
216
+ children: "Minify"
217
+ })] }) : null, /* @__PURE__ */ v(o, {
218
+ className: d.copy,
219
+ value: () => B,
220
+ label: fe,
221
+ size: "sm",
222
+ disabled: L.disabled
223
+ })]
224
+ }) : null,
225
+ /* @__PURE__ */ v("div", {
226
+ className: d.scroller,
227
+ children: /* @__PURE__ */ y("div", {
228
+ className: d.stack,
229
+ children: [/* @__PURE__ */ v("pre", {
230
+ className: d.highlight,
231
+ "aria-hidden": "true",
232
+ children: Q.map((e, t) => /* @__PURE__ */ v("span", {
233
+ className: d.line,
234
+ "data-line": k ? t + 1 : void 0,
235
+ "data-error": Ae === t + 1 || void 0,
236
+ children: e.map((e, t) => e.type ? /* @__PURE__ */ v("span", {
237
+ className: d.token,
238
+ "data-token": e.type,
239
+ children: e.content
240
+ }, t) : e.content)
241
+ }, t))
242
+ }), /* @__PURE__ */ v("textarea", {
243
+ ref: Se,
244
+ id: L.id,
245
+ className: d.textarea,
246
+ value: B,
247
+ onChange: De,
248
+ onKeyDown: ke,
249
+ onBlur: Oe,
250
+ wrap: A ? "soft" : "off",
251
+ spellCheck: !1,
252
+ autoCapitalize: "off",
253
+ autoComplete: "off",
254
+ autoCorrect: "off",
255
+ disabled: L.disabled,
256
+ readOnly: L.readOnly,
257
+ required: he ?? L.required,
258
+ "aria-describedby": n(L.describedBy, R ? z : void 0),
259
+ "aria-invalid": $ || void 0,
260
+ "aria-required": L.required || void 0,
261
+ "aria-busy": L.busy || void 0,
262
+ ...be
263
+ })]
264
+ })
265
+ }),
266
+ R ? /* @__PURE__ */ v("span", {
267
+ id: z,
268
+ hidden: !0,
269
+ children: "Tab inserts an indent. Press Escape, then Tab, to leave the editor."
270
+ }) : null,
271
+ /* @__PURE__ */ v("span", {
272
+ className: d.status,
273
+ role: "status",
274
+ children: W.text ? /* @__PURE__ */ v("span", { children: W.text }, W.count) : null
275
+ })
276
+ ]
277
+ });
278
+ }));
279
+ //#endregion
280
+ export { T as JsonInput, S as validateJson };
281
+
282
+ //# sourceMappingURL=JsonInput.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JsonInput.js","names":["control","styles","_Fragment","control_module_default","JsonInput_module_default","Fragment$1","useIsomorphicLayoutEffect","useEffect","useLayoutEffect","EMPTY","validateJson","text","parsed","parseJson","message","validate","sameValidation","a","b","PAIRS","CLOSERS","unitOf","indent","lineStart","offset","JsonInput","markFieldAware","forwardRef","valueProp","invalidProp","idProp","disabledProp","requiredProp","readOnlyProp","describedByProp","ariaInvalid","rest","area","useRef","composedRef","useMergedRefs","ref","field","useResolvedField","editable","hintId","useId","uncontrolled","setUncontrolled","useState","defaultValue","latest","useLatest","validation","useMemo","shown","setShown","announcement","setAnnouncement","announce","previous","escaped","pendingSelection","show","next","timer","validationDelay","selection","commit","edit","start","insert","el","end","reformat","mode","formatJson","minifyJson","line","caret","handleChange","onChange","event","handleBlur","onBlur","formatOnBlur","handleKeyDown","onKeyDown","unit","from","multiline","to","block","lead","before","after","opens","inner","open","autoClose","close","selected","lines","tokenizeJson","errorLine","invalid","digits","cx","className","mergeStyles","minRows","maxRows","style","wrap","lineNumbers","toolbar","Button","CopyButton","copyLabel","i","tokens","token","j","joinIds"],"sources":["../../../../src/components/inputs/JsonInput/JsonInput.tsx"],"sourcesContent":["import {\n forwardRef,\n useEffect,\n useId,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type ChangeEvent,\n type CSSProperties,\n type FocusEvent,\n type KeyboardEvent,\n type TextareaHTMLAttributes,\n} from 'react'\nimport { cx } from '#utils/cx'\nimport { mergeStyles } from '#utils/responsive'\nimport { Button } from '#components/actions/Button'\nimport { CopyButton } from '#components/actions/CopyButton'\nimport { markFieldAware, useResolvedField } from '#components/inputs/internal/FieldContext'\nimport { joinIds, useMergedRefs } from '#components/inputs/internal/refs'\nimport { useLatest } from '#components/inputs/internal/useLatest'\nimport control from '#components/inputs/internal/control.module.css'\nimport { formatJson, minifyJson, parseJson, tokenizeJson, type JsonIndent } from './json'\nimport styles from './JsonInput.module.css'\n\n// Layout effects warn during server rendering; on the server there's nothing to restore anyway.\nconst useIsomorphicLayoutEffect = typeof document === 'undefined' ? useEffect : useLayoutEffect\n\n/** Why the text isn't acceptable. A syntax error has the line and column it points at. */\nexport interface JsonInputError {\n message: string\n line?: number\n column?: number\n}\n\n/** What a JSON text holds, and whether it's acceptable. */\nexport interface JsonValidation {\n /** The parsed value, when the text is valid JSON. `undefined` when it's empty or invalid. */\n parsed: unknown\n /** `true` when the text is valid JSON that passes `validate`, or is empty. */\n valid: boolean\n /** Why it isn't valid. */\n error?: JsonInputError\n}\n\nexport interface JsonInputProps extends Omit<\n TextareaHTMLAttributes<HTMLTextAreaElement>,\n 'value' | 'defaultValue' | 'wrap' | 'rows' | 'cols' | 'children'\n> {\n /** The text (controlled). */\n value?: string\n /** The starting text (uncontrolled). */\n defaultValue?: string\n /** Called with the new text, and what it holds, on every change. */\n onValueChange?: (value: string, validation: JsonValidation) => void\n /**\n * Called when the validation the input shows changes: once typing pauses for\n * `validationDelay`, on blur, and straight away when the text becomes valid again.\n */\n onValidationChange?: (validation: JsonValidation) => void\n /**\n * Your own rules for a value that parses: return a message to reject it, or `undefined` to\n * accept it. Wire a JSON Schema validator in here.\n */\n validate?: (parsed: unknown) => string | undefined\n /** How long typing has to pause before an error shows, in ms. Default `500`. */\n validationDelay?: number\n /** How Format indents: `2` (default), `4` or `'tab'`. Also what Tab inserts. */\n indent?: JsonIndent\n /** Sort object keys when formatting or minifying. */\n sortKeys?: boolean\n /** Format the text when the input loses focus, if it's valid. */\n formatOnBlur?: boolean\n /** Close brackets and quotes as you type them. Default `true`. */\n autoClose?: boolean\n /** Number the lines. Default `true`. */\n lineNumbers?: boolean\n /** Wrap long lines instead of scrolling sideways. */\n wrap?: boolean\n /** Show the Format, Minify and Copy actions above the text. Default `true`. */\n toolbar?: boolean\n /** The least height, in lines. Default `4`. */\n minRows?: number\n /** Grow with the text up to this many lines, then scroll. Without it, it keeps growing. */\n maxRows?: number\n /** Critical border and `aria-invalid`, on top of its own validation. Set for you inside a `Field`. */\n invalid?: boolean\n /** Name of the copy action. Default \"Copy JSON\". */\n copyLabel?: string\n}\n\nconst EMPTY: JsonValidation = { parsed: undefined, valid: true }\n\n/** Parses `text` and runs `validate` on the result. Empty text is valid and holds nothing. */\nexport function validateJson(\n text: string,\n validate?: (parsed: unknown) => string | undefined,\n): JsonValidation {\n if (text.trim() === '') return EMPTY\n const parsed = parseJson(text)\n if (!parsed.ok) {\n const { message, line, column } = parsed.error\n return { parsed: undefined, valid: false, error: { message, line, column } }\n }\n const message = validate?.(parsed.value)\n return message === undefined\n ? { parsed: parsed.value, valid: true }\n : { parsed: parsed.value, valid: false, error: { message } }\n}\n\n/** Whether two validations would show the same thing. `parsed` is compared by its JSON text. */\nfunction sameValidation(a: JsonValidation, b: JsonValidation): boolean {\n return (\n a.valid === b.valid &&\n a.error?.message === b.error?.message &&\n a.error?.line === b.error?.line &&\n a.error?.column === b.error?.column &&\n (a.parsed === b.parsed || JSON.stringify(a.parsed) === JSON.stringify(b.parsed))\n )\n}\n\nconst PAIRS: Record<string, string> = { '{': '}', '[': ']', '\"': '\"' }\nconst CLOSERS = new Set(['}', ']', '\"'])\n\nconst unitOf = (indent: JsonIndent) => (indent === 'tab' ? '\\t' : ' '.repeat(indent))\n\n/** Start of the line `offset` is on. */\nconst lineStart = (text: string, offset: number) => text.lastIndexOf('\\n', offset - 1) + 1\n\n/**\n * A JSON editor in a field box: it highlights with the theme, numbers the lines, marks the line\n * with an error, and formats or minifies on demand.\n *\n * @remarks\n * `JsonInput` is for JSON that people edit by hand: a config blob, a request payload, a fixture.\n * It parses as you type and, once typing pauses, marks the line that's wrong and sets\n * `aria-invalid`. It never changes text that isn't valid. `onValueChange` gets the text and what\n * it holds (`parsed`, `valid` and `error`) on every change. For a labelled field that shows the\n * error message, use {@link JsonField | JsonField}.\n *\n * Format re-indents the text (`indent` is `2`, `4` or `'tab'`), and Minify puts it on one line.\n * Both keep numbers and strings exactly as written, so a long ID or a price like `1.50` survives,\n * and both keep the order of keys unless you pass `sortKeys`. `formatOnBlur` formats valid text\n * as the input loses focus.\n *\n * It grows with its content from `minRows` up to `maxRows`, then scrolls. `readOnly` makes it a\n * viewer: no Format or Minify, and Tab moves on as usual.\n *\n * ## Keyboard\n *\n * - **Tab** indents, and **Shift+Tab** outdents, the line or the selected lines. To leave the\n * editor with the keyboard, press **Escape**, then **Tab**. Screen readers hear this in the\n * input's description.\n * - **Enter** keeps the indent, and indents again after `{` or `[`.\n * - Typing `{`, `[` or `\"` closes it for you (`autoClose`), and typing the closer steps over it.\n * - **Shift+Alt+F** formats.\n *\n * ## Your own rules and JSON Schema\n *\n * `validate` gets the parsed value and returns a message to reject it. That's where a JSON Schema\n * validator goes, so Kiln doesn't bundle one. With [Ajv](https://ajv.js.org):\n *\n * ```tsx\n * import Ajv from 'ajv'\n * import { JsonField } from '@mitcsutt/kiln-ui'\n *\n * const ajv = new Ajv()\n * const check = ajv.compile(payloadSchema)\n *\n * export function PayloadField() {\n * return (\n * <JsonField\n * label=\"Payload\"\n * validate={(value) => (check(value) ? undefined : ajv.errorsText(check.errors))}\n * />\n * )\n * }\n * ```\n *\n * @privateRemarks\n * A transparent textarea over a highlighted <pre> in the same grid cell, so the browser does the\n * editing, selection, undo and IME, and the <pre> only paints. Highlighting is a built-in JSON\n * tokenizer rather than the shiki `highlight` entry: JSON's grammar is small enough to get exactly\n * right without a peer dependency, so the field works the same everywhere. Edits from the keyboard\n * go through execCommand('insertText') so they stay on the native undo stack.\n */\nexport const JsonInput = markFieldAware(\n forwardRef<HTMLTextAreaElement, JsonInputProps>(function JsonInput(\n {\n value: valueProp,\n defaultValue = '',\n onValueChange,\n onValidationChange,\n validate,\n validationDelay = 500,\n indent = 2,\n sortKeys = false,\n formatOnBlur = false,\n autoClose = true,\n lineNumbers = true,\n wrap = false,\n toolbar = true,\n minRows = 4,\n maxRows,\n invalid: invalidProp,\n copyLabel = 'Copy JSON',\n id: idProp,\n disabled: disabledProp,\n required: requiredProp,\n readOnly: readOnlyProp,\n className,\n style,\n onChange,\n onKeyDown,\n onBlur,\n 'aria-describedby': describedByProp,\n 'aria-invalid': ariaInvalid,\n ...rest\n },\n ref,\n ) {\n const area = useRef<HTMLTextAreaElement>(null)\n const composedRef = useMergedRefs(ref, area)\n const field = useResolvedField({\n id: idProp,\n describedBy: describedByProp,\n invalid: invalidProp,\n ariaInvalid,\n disabled: disabledProp,\n readOnly: readOnlyProp,\n })\n const editable = !field.disabled && !field.readOnly\n const hintId = useId()\n\n const [uncontrolled, setUncontrolled] = useState(defaultValue)\n const text = valueProp ?? uncontrolled\n const latest = useLatest({ onValueChange, onValidationChange, validate })\n\n const validation = useMemo(() => validateJson(text, validate), [text, validate])\n const [shown, setShown] = useState<JsonValidation>(validation)\n const [announcement, setAnnouncement] = useState({ text: '', count: 0 })\n // A new node each time, so the same message (\"Formatted\") is announced again.\n const announce = (message: string) => {\n setAnnouncement((previous) => ({ text: message, count: previous.count + 1 }))\n }\n const escaped = useRef(false)\n const pendingSelection = useRef<[number, number] | null>(null)\n\n const show = (next: JsonValidation) => {\n setShown((previous) => (sameValidation(previous, next) ? previous : next))\n }\n\n // Show a fix at once; hold a new error back until typing pauses.\n useEffect(() => {\n if (validation.valid) {\n show(validation)\n return\n }\n const timer = setTimeout(() => {\n show(validation)\n }, validationDelay)\n return () => {\n clearTimeout(timer)\n }\n }, [validation, validationDelay])\n\n useEffect(() => {\n latest.current.onValidationChange?.(shown)\n }, [shown, latest])\n\n // Restore the caret after an edit that went through state rather than the browser.\n useIsomorphicLayoutEffect(() => {\n const selection = pendingSelection.current\n if (selection && area.current) {\n pendingSelection.current = null\n area.current.setSelectionRange(selection[0], selection[1])\n }\n })\n\n const commit = (next: string) => {\n if (valueProp === undefined) setUncontrolled(next)\n latest.current.onValueChange?.(next, validateJson(next, latest.current.validate))\n }\n\n /**\n * Replace `start`–`end` with `insert`, then select `selection` (by default, a caret after the\n * insert). Through the browser's own editing where it can, so Undo works, or through state.\n */\n const edit = (\n start: number,\n end: number,\n insert: string,\n selection: [number, number] = [start + insert.length, start + insert.length],\n ) => {\n const el = area.current\n if (!el) return\n const next = text.slice(0, start) + insert + text.slice(end)\n el.focus()\n el.setSelectionRange(start, end)\n // execCommand is deprecated, but it's the only edit that joins the native undo stack.\n const native =\n // eslint-disable-next-line @typescript-eslint/no-deprecated -- see above\n typeof document.execCommand === 'function' &&\n // eslint-disable-next-line @typescript-eslint/no-deprecated -- see above\n document.execCommand(insert === '' ? 'delete' : 'insertText', false, insert)\n if (native && el.value === next) {\n el.setSelectionRange(...selection)\n return\n }\n pendingSelection.current = selection\n commit(next)\n }\n\n const reformat = (mode: 'format' | 'minify') => {\n const next =\n mode === 'format' ? formatJson(text, { indent, sortKeys }) : minifyJson(text, { sortKeys })\n if (next === undefined) {\n const line = validation.error?.line\n announce(\n text.trim() === ''\n ? 'Nothing to format'\n : `Fix the error${line ? ` on line ${String(line)}` : ''} first`,\n )\n show(validation)\n return\n }\n announce(mode === 'format' ? 'Formatted' : 'Minified')\n if (next === text) return\n const caret = Math.min(area.current?.selectionStart ?? 0, next.length)\n edit(0, text.length, next, [caret, caret])\n }\n\n const handleChange = (event: ChangeEvent<HTMLTextAreaElement>) => {\n onChange?.(event)\n commit(event.target.value)\n }\n\n const handleBlur = (event: FocusEvent<HTMLTextAreaElement>) => {\n onBlur?.(event)\n escaped.current = false\n show(validation)\n if (formatOnBlur && editable && validation.valid) {\n const next = formatJson(text, { indent, sortKeys })\n if (next !== undefined && next !== text) commit(next)\n }\n }\n\n const handleKeyDown = (event: KeyboardEvent<HTMLTextAreaElement>) => {\n onKeyDown?.(event)\n if (event.defaultPrevented || event.nativeEvent.isComposing || !editable) return\n const el = event.currentTarget\n const { selectionStart: start, selectionEnd: end } = el\n const unit = unitOf(indent)\n\n if (event.key === 'Escape') {\n escaped.current = true\n announce('Press Tab to leave the editor')\n return\n }\n if (event.key === 'Tab' && !event.ctrlKey && !event.metaKey && !event.altKey) {\n if (escaped.current) {\n escaped.current = false\n return\n }\n event.preventDefault()\n const from = lineStart(text, start)\n const multiline = text.slice(start, end).includes('\\n')\n if (!event.shiftKey && !multiline) {\n edit(start, end, unit)\n return\n }\n const to = end > start && text[end - 1] === '\\n' ? end - 1 : end\n const block = text.slice(from, to)\n const lines = block.split('\\n')\n const changed = lines.map((line) =>\n event.shiftKey\n ? line.startsWith(unit)\n ? line.slice(unit.length)\n : line.replace(/^[ \\t]+/, (lead) => lead.slice(unit.length))\n : `${unit}${line}`,\n )\n const next = changed.join('\\n')\n if (next === block) return\n // Keep the lines selected, so Tab and Shift+Tab can be pressed again.\n edit(from, to, next, [from, from + next.length])\n return\n }\n escaped.current = false\n\n if (event.key === 'F' || event.code === 'KeyF') {\n if (event.shiftKey && event.altKey && !event.ctrlKey && !event.metaKey) {\n event.preventDefault()\n reformat('format')\n }\n return\n }\n if (event.ctrlKey || event.metaKey || event.altKey) return\n\n if (event.key === 'Enter') {\n event.preventDefault()\n const from = lineStart(text, start)\n const lead = /^[ \\t]*/.exec(text.slice(from, start))?.[0] ?? ''\n const before = text.slice(0, start).trimEnd().at(-1)\n const after = text[end]\n const opens = before === '{' || before === '['\n if (opens && after === PAIRS[before]) {\n const inner = `\\n${lead}${unit}`\n const caret = start + inner.length\n edit(start, end, `${inner}\\n${lead}`, [caret, caret])\n } else {\n edit(start, end, `\\n${lead}${opens ? unit : ''}`)\n }\n return\n }\n if (event.key === 'Backspace' && start === end && start > 0) {\n const open = text.charAt(start - 1)\n if (autoClose && PAIRS[open] !== undefined && text[start] === PAIRS[open]) {\n event.preventDefault()\n edit(start - 1, start + 1, '')\n }\n return\n }\n if (!autoClose || event.key.length !== 1) return\n if (CLOSERS.has(event.key) && start === end && text[start] === event.key) {\n // Step over the closer that was typed for you.\n if (event.key !== '\"' || text[start - 1] !== '\\\\') {\n event.preventDefault()\n el.setSelectionRange(start + 1, start + 1)\n return\n }\n }\n const close = PAIRS[event.key]\n if (close === undefined) return\n if (event.key === '\"') {\n const previous = text[start - 1] ?? ''\n const next = text[end] ?? ''\n if (/[\\w\"\\\\]/.test(previous) || /[\\w\"]/.test(next)) return\n }\n event.preventDefault()\n const selected = text.slice(start, end)\n const caret = start + 1 + selected.length\n edit(start, end, `${event.key}${selected}${close}`, [caret, caret])\n }\n\n const lines = useMemo(() => tokenizeJson(text), [text])\n const errorLine = shown.error?.line\n const invalid = field.invalid || !shown.valid\n const digits = String(lines.length).length\n\n return (\n <div\n className={cx(control.box, styles.root, className)}\n style={mergeStyles(\n {\n '--_min-rows': minRows,\n '--_max-rows': maxRows,\n '--_digits': digits,\n } as CSSProperties,\n style,\n )}\n data-invalid={invalid || undefined}\n data-disabled={field.disabled || undefined}\n data-readonly={field.readOnly || undefined}\n data-wrap={wrap || undefined}\n data-line-numbers={lineNumbers || undefined}\n data-max-rows={maxRows ? '' : undefined}\n >\n {toolbar ? (\n <div className={styles.toolbar}>\n {editable ? (\n <>\n <Button\n variant=\"ghost\"\n tone=\"neutral\"\n size=\"sm\"\n onClick={() => {\n reformat('format')\n }}\n >\n Format\n </Button>\n <Button\n variant=\"ghost\"\n tone=\"neutral\"\n size=\"sm\"\n onClick={() => {\n reformat('minify')\n }}\n >\n Minify\n </Button>\n </>\n ) : null}\n <CopyButton\n className={styles.copy}\n value={() => text}\n label={copyLabel}\n size=\"sm\"\n disabled={field.disabled}\n />\n </div>\n ) : null}\n <div className={styles.scroller}>\n <div className={styles.stack}>\n <pre className={styles.highlight} aria-hidden=\"true\">\n {lines.map((tokens, i) => (\n <span\n key={i}\n className={styles.line}\n data-line={lineNumbers ? i + 1 : undefined}\n data-error={errorLine === i + 1 || undefined}\n >\n {tokens.map((token, j) =>\n token.type ? (\n <span key={j} className={styles.token} data-token={token.type}>\n {token.content}\n </span>\n ) : (\n token.content\n ),\n )}\n </span>\n ))}\n </pre>\n <textarea\n ref={composedRef}\n id={field.id}\n className={styles.textarea}\n value={text}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n onBlur={handleBlur}\n wrap={wrap ? 'soft' : 'off'}\n spellCheck={false}\n autoCapitalize=\"off\"\n autoComplete=\"off\"\n autoCorrect=\"off\"\n disabled={field.disabled}\n readOnly={field.readOnly}\n required={requiredProp ?? field.required}\n aria-describedby={joinIds(field.describedBy, editable ? hintId : undefined)}\n aria-invalid={invalid || undefined}\n aria-required={field.required || undefined}\n aria-busy={field.busy || undefined}\n {...rest}\n />\n </div>\n </div>\n {editable ? (\n <span id={hintId} hidden>\n Tab inserts an indent. Press Escape, then Tab, to leave the editor.\n </span>\n ) : null}\n <span className={styles.status} role=\"status\">\n {announcement.text ? <span key={announcement.count}>{announcement.text}</span> : null}\n </span>\n </div>\n )\n }),\n)\n"],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ //#region src/components/inputs/JsonInput/JsonInput.module.css
2
+ var e = "kiln-JsonInput__root", t = "kiln-JsonInput__textarea", n = "kiln-JsonInput__toolbar", r = "kiln-JsonInput__scroller", i = "kiln-JsonInput__stack", a = "kiln-JsonInput__highlight", o = "kiln-JsonInput__line", s = "kiln-JsonInput__token", c = "kiln-JsonInput__status", l = {
3
+ root: e,
4
+ textarea: t,
5
+ toolbar: n,
6
+ scroller: r,
7
+ stack: i,
8
+ highlight: a,
9
+ line: o,
10
+ token: s,
11
+ status: c
12
+ };
13
+ //#endregion
14
+ export { l as default, a as highlight, o as line, e as root, r as scroller, i as stack, c as status, t as textarea, s as token, n as toolbar };
15
+
16
+ //# sourceMappingURL=JsonInput.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JsonInput.module.js","names":["root","textarea","toolbar","scroller","stack","highlight","line","token","status","JsonInput_module_default"],"sources":["../../../../src/components/inputs/JsonInput/JsonInput.module.css"],"sourcesContent":["/*\n * The box, its border and its states are the field box (inputs/internal/control.module.css).\n *\n * Component tokens (themes may set any of these on [data-theme]):\n * --json-input-size code size, default var(--text-sm)\n * --json-input-error-bg the marked line's fill, default var(--tone-critical-soft)\n *\n * The text is a transparent <textarea> laid over a highlighted <pre> in one grid cell: the\n * browser edits, the <pre> paints. Both must set the same font, padding, line height, tab size\n * and wrapping, or the caret drifts from the glyphs. Line numbers sit in each line's start\n * padding, so they stay with their line when it wraps. --_min-rows, --_max-rows and --_digits\n * are written inline.\n */\n.root {\n --_min-rows: 4;\n --_max-rows: 0;\n --_digits: 1;\n --_pad: var(--space-3);\n --_py: var(--space-2);\n --_gutter: 0px;\n\n display: flex;\n flex-direction: column;\n min-inline-size: 0;\n overflow: hidden;\n padding: 0;\n}\n\n.root[data-line-numbers] {\n --_gutter: calc(var(--_digits) * 1ch + var(--space-3));\n}\n\n/* The ring goes round the whole box while the text has focus, never round the toolbar's buttons. */\n.root:has(.textarea:focus-visible) {\n outline: 2px solid var(--color-focus);\n outline-offset: 2px;\n}\n\n.toolbar {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: var(--space-1);\n padding: var(--space-1);\n border-block-end: var(--border-width) solid var(--color-line);\n}\n\n.scroller {\n overflow: auto;\n font-family: var(--font-mono);\n font-stretch: var(--mono-stretch);\n font-size: var(--json-input-size, var(--text-sm));\n font-variant-ligatures: none;\n line-height: 1.6;\n scrollbar-width: thin;\n}\n.root[data-max-rows] .scroller {\n max-block-size: calc(var(--_max-rows) * 1lh + 2 * var(--_py));\n}\n\n.stack {\n display: grid;\n min-inline-size: 100%;\n inline-size: max-content;\n min-block-size: calc(var(--_min-rows) * 1lh + 2 * var(--_py));\n}\n.root[data-wrap] .stack {\n inline-size: 100%;\n}\n\n.highlight,\n.textarea {\n grid-area: 1 / 1;\n box-sizing: border-box;\n margin: 0;\n padding-block: var(--_py);\n font: inherit;\n letter-spacing: 0;\n tab-size: 2;\n white-space: pre;\n overflow-wrap: normal;\n}\n.root[data-wrap] .highlight,\n.root[data-wrap] .textarea {\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n\n.highlight {\n padding-inline: 0;\n color: var(--color-ink);\n pointer-events: none;\n user-select: none;\n}\n\n.line {\n display: block;\n position: relative;\n min-block-size: 1lh;\n padding-inline: calc(var(--_pad) + var(--_gutter)) var(--_pad);\n}\n.root[data-line-numbers] .line::before {\n content: attr(data-line);\n position: absolute;\n inset-inline-start: 0;\n inline-size: calc(var(--_pad) + var(--_digits) * 1ch);\n text-align: end;\n color: var(--color-ink-subtle);\n font-variant-numeric: tabular-nums;\n}\n.line[data-error] {\n background: var(--json-input-error-bg, var(--tone-critical-soft));\n}\n.root[data-line-numbers] .line[data-error]::before {\n color: var(--tone-critical-text);\n}\n\n.textarea {\n display: block;\n inline-size: 100%;\n block-size: 100%;\n min-inline-size: 0;\n padding-inline: calc(var(--_pad) + var(--_gutter)) var(--_pad);\n border: 0;\n border-radius: 0;\n outline: none;\n background: transparent;\n color: transparent;\n caret-color: var(--color-ink);\n overflow: hidden;\n resize: none;\n}\n.textarea::selection {\n background: var(--color-selection);\n color: transparent;\n}\n.textarea::placeholder {\n color: var(--color-ink-subtle);\n}\n.textarea:disabled {\n cursor: not-allowed;\n}\n\n/* The theme's code colours, as CodeBlock's highlighting maps them. */\n.token[data-token='type'] {\n color: var(--tone-info-text);\n}\n.token[data-token='string'] {\n color: var(--tone-positive-text);\n}\n.token[data-token='constant'] {\n color: var(--tone-caution-text);\n}\n.token[data-token='punctuation'] {\n color: var(--color-ink-muted);\n}\n\n.root[data-disabled] .highlight {\n color: var(--color-ink-subtle);\n}\n.root[data-disabled] .token {\n color: inherit;\n}\n\n.status {\n position: absolute;\n inline-size: 1px;\n block-size: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n border: 0;\n}\n\n/* High contrast: show the text itself, since the painted layer may lose its colours. */\n@media (forced-colors: active) {\n .textarea {\n color: CanvasText;\n }\n .highlight {\n visibility: hidden;\n }\n}\n"],"mappings":""}
@@ -0,0 +1,4 @@
1
+ export { JsonInput, validateJson } from './JsonInput.js';
2
+ export type { JsonInputProps, JsonValidation, JsonInputError } from './JsonInput.js';
3
+ export { formatJson, minifyJson } from './json.js';
4
+ export type { JsonIndent, JsonSyntaxError } from './json.js';
@@ -0,0 +1,59 @@
1
+ import type { CodeToken } from '../../display/CodeBlock/index.js';
2
+ /** Where a JSON text goes wrong: a message, and the 1-based line and column it points at. */
3
+ export interface JsonSyntaxError {
4
+ message: string;
5
+ line: number;
6
+ column: number;
7
+ /** 0-based offset into the text. */
8
+ offset: number;
9
+ }
10
+ /** How formatted JSON is indented: two spaces, four spaces, or a tab. */
11
+ export type JsonIndent = 2 | 4 | 'tab';
12
+ type JsonNode = {
13
+ kind: 'object';
14
+ members: {
15
+ key: string;
16
+ value: JsonNode;
17
+ }[];
18
+ } | {
19
+ kind: 'array';
20
+ items: JsonNode[];
21
+ } | {
22
+ kind: 'literal';
23
+ raw: string;
24
+ };
25
+ export type JsonParse = {
26
+ ok: true;
27
+ node: JsonNode;
28
+ value: unknown;
29
+ } | {
30
+ ok: false;
31
+ error: JsonSyntaxError;
32
+ };
33
+ /** 1-based line and column of `offset`. */
34
+ export declare function positionOf(text: string, offset: number): {
35
+ line: number;
36
+ column: number;
37
+ };
38
+ /** Parses `text` strictly, with the position and a plain message when it isn't valid. */
39
+ export declare function parseJson(text: string): JsonParse;
40
+ /**
41
+ * `text` re-indented, or `undefined` when it isn't valid JSON. Numbers and strings keep their
42
+ * exact text, and keys keep their order unless `sortKeys`.
43
+ */
44
+ export declare function formatJson(text: string, { indent, sortKeys }?: {
45
+ indent?: JsonIndent;
46
+ sortKeys?: boolean;
47
+ }): string | undefined;
48
+ /** `text` on one line with no spaces, or `undefined` when it isn't valid JSON. */
49
+ export declare function minifyJson(text: string, { sortKeys }?: {
50
+ sortKeys?: boolean;
51
+ }): string | undefined;
52
+ /**
53
+ * Tokens for highlighting, one array per line, in `CodeBlock`'s token types: property names are
54
+ * `type`, strings `string`, numbers, `true`, `false` and `null` `constant`, and brackets, colons
55
+ * and commas `punctuation`. Tolerant: text that isn't valid JSON yet still highlights as far as
56
+ * it reads.
57
+ */
58
+ export declare function tokenizeJson(text: string): CodeToken[][];
59
+ export {};