@craftzbay/ui 0.10.0 → 0.11.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 (187) hide show
  1. package/README.md +14 -8
  2. package/dist-lib/__tests__/helpers/color.d.ts +9 -0
  3. package/dist-lib/__tests__/helpers/theme.d.ts +18 -0
  4. package/dist-lib/components/ui/Accordion.js +18 -7
  5. package/dist-lib/components/ui/Accordion.js.map +1 -1
  6. package/dist-lib/components/ui/Alert.d.ts +16 -0
  7. package/dist-lib/components/ui/Alert.js +47 -34
  8. package/dist-lib/components/ui/Alert.js.map +1 -1
  9. package/dist-lib/components/ui/Avatar.d.ts +1 -1
  10. package/dist-lib/components/ui/Avatar.js +45 -47
  11. package/dist-lib/components/ui/Avatar.js.map +1 -1
  12. package/dist-lib/components/ui/Badge.d.ts +3 -1
  13. package/dist-lib/components/ui/Badge.js +24 -15
  14. package/dist-lib/components/ui/Badge.js.map +1 -1
  15. package/dist-lib/components/ui/Breadcrumbs.d.ts +2 -0
  16. package/dist-lib/components/ui/Breadcrumbs.js +46 -28
  17. package/dist-lib/components/ui/Breadcrumbs.js.map +1 -1
  18. package/dist-lib/components/ui/Button.d.ts +5 -3
  19. package/dist-lib/components/ui/Button.js +59 -45
  20. package/dist-lib/components/ui/Button.js.map +1 -1
  21. package/dist-lib/components/ui/Calendar.d.ts +1 -1
  22. package/dist-lib/components/ui/Calendar.js +87 -59
  23. package/dist-lib/components/ui/Calendar.js.map +1 -1
  24. package/dist-lib/components/ui/Card.d.ts +2 -0
  25. package/dist-lib/components/ui/Card.js +48 -67
  26. package/dist-lib/components/ui/Card.js.map +1 -1
  27. package/dist-lib/components/ui/Carousel.d.ts +6 -6
  28. package/dist-lib/components/ui/Carousel.js +133 -102
  29. package/dist-lib/components/ui/Carousel.js.map +1 -1
  30. package/dist-lib/components/ui/Chart.d.ts +49 -10
  31. package/dist-lib/components/ui/Chart.js +415 -181
  32. package/dist-lib/components/ui/Chart.js.map +1 -1
  33. package/dist-lib/components/ui/Checkbox.js +42 -28
  34. package/dist-lib/components/ui/Checkbox.js.map +1 -1
  35. package/dist-lib/components/ui/Combobox.d.ts +2 -0
  36. package/dist-lib/components/ui/Combobox.js +142 -111
  37. package/dist-lib/components/ui/Combobox.js.map +1 -1
  38. package/dist-lib/components/ui/CommandPalette.d.ts +6 -3
  39. package/dist-lib/components/ui/CommandPalette.js +92 -87
  40. package/dist-lib/components/ui/CommandPalette.js.map +1 -1
  41. package/dist-lib/components/ui/ContextMenu.d.ts +7 -2
  42. package/dist-lib/components/ui/ContextMenu.js +77 -62
  43. package/dist-lib/components/ui/ContextMenu.js.map +1 -1
  44. package/dist-lib/components/ui/DataGrid.d.ts +17 -4
  45. package/dist-lib/components/ui/DataGrid.js +65 -50
  46. package/dist-lib/components/ui/DataGrid.js.map +1 -1
  47. package/dist-lib/components/ui/DatePicker.js +118 -99
  48. package/dist-lib/components/ui/DatePicker.js.map +1 -1
  49. package/dist-lib/components/ui/DesignSystemProvider.d.ts +94 -40
  50. package/dist-lib/components/ui/DesignSystemProvider.js +111 -55
  51. package/dist-lib/components/ui/DesignSystemProvider.js.map +1 -1
  52. package/dist-lib/components/ui/Dialog.d.ts +18 -3
  53. package/dist-lib/components/ui/Dialog.js +105 -80
  54. package/dist-lib/components/ui/Dialog.js.map +1 -1
  55. package/dist-lib/components/ui/Drawer.d.ts +17 -2
  56. package/dist-lib/components/ui/Drawer.js +89 -55
  57. package/dist-lib/components/ui/Drawer.js.map +1 -1
  58. package/dist-lib/components/ui/DropdownMenu.js +14 -9
  59. package/dist-lib/components/ui/DropdownMenu.js.map +1 -1
  60. package/dist-lib/components/ui/EmptyState.d.ts +2 -0
  61. package/dist-lib/components/ui/EmptyState.js +30 -16
  62. package/dist-lib/components/ui/EmptyState.js.map +1 -1
  63. package/dist-lib/components/ui/ErrorState.d.ts +13 -2
  64. package/dist-lib/components/ui/ErrorState.js +44 -23
  65. package/dist-lib/components/ui/ErrorState.js.map +1 -1
  66. package/dist-lib/components/ui/FileUpload.js +59 -56
  67. package/dist-lib/components/ui/FileUpload.js.map +1 -1
  68. package/dist-lib/components/ui/Form.d.ts +15 -2
  69. package/dist-lib/components/ui/Form.js +97 -71
  70. package/dist-lib/components/ui/Form.js.map +1 -1
  71. package/dist-lib/components/ui/Icon.d.ts +1 -1
  72. package/dist-lib/components/ui/Icon.js +20 -14
  73. package/dist-lib/components/ui/Icon.js.map +1 -1
  74. package/dist-lib/components/ui/IconButton.d.ts +2 -2
  75. package/dist-lib/components/ui/IconButton.js +28 -20
  76. package/dist-lib/components/ui/IconButton.js.map +1 -1
  77. package/dist-lib/components/ui/Input.d.ts +3 -1
  78. package/dist-lib/components/ui/Input.js +92 -78
  79. package/dist-lib/components/ui/Input.js.map +1 -1
  80. package/dist-lib/components/ui/Kbd.js +1 -1
  81. package/dist-lib/components/ui/Kbd.js.map +1 -1
  82. package/dist-lib/components/ui/MultiSelect.js +121 -107
  83. package/dist-lib/components/ui/MultiSelect.js.map +1 -1
  84. package/dist-lib/components/ui/Pagination.js +67 -62
  85. package/dist-lib/components/ui/Pagination.js.map +1 -1
  86. package/dist-lib/components/ui/Popover.js +14 -14
  87. package/dist-lib/components/ui/Popover.js.map +1 -1
  88. package/dist-lib/components/ui/Progress.d.ts +3 -3
  89. package/dist-lib/components/ui/Progress.js +77 -72
  90. package/dist-lib/components/ui/Progress.js.map +1 -1
  91. package/dist-lib/components/ui/RadioGroup.d.ts +1 -1
  92. package/dist-lib/components/ui/RadioGroup.js +69 -52
  93. package/dist-lib/components/ui/RadioGroup.js.map +1 -1
  94. package/dist-lib/components/ui/RelativeTime.d.ts +19 -0
  95. package/dist-lib/components/ui/RelativeTime.js +31 -0
  96. package/dist-lib/components/ui/RelativeTime.js.map +1 -0
  97. package/dist-lib/components/ui/ScrollArea.d.ts +9 -1
  98. package/dist-lib/components/ui/ScrollArea.js +43 -27
  99. package/dist-lib/components/ui/ScrollArea.js.map +1 -1
  100. package/dist-lib/components/ui/Select.d.ts +6 -1
  101. package/dist-lib/components/ui/Select.js +79 -71
  102. package/dist-lib/components/ui/Select.js.map +1 -1
  103. package/dist-lib/components/ui/Separator.js +1 -1
  104. package/dist-lib/components/ui/Separator.js.map +1 -1
  105. package/dist-lib/components/ui/Sheet.d.ts +9 -0
  106. package/dist-lib/components/ui/Sheet.js +69 -46
  107. package/dist-lib/components/ui/Sheet.js.map +1 -1
  108. package/dist-lib/components/ui/Sidebar.d.ts +12 -9
  109. package/dist-lib/components/ui/Sidebar.js +152 -109
  110. package/dist-lib/components/ui/Sidebar.js.map +1 -1
  111. package/dist-lib/components/ui/Skeleton.d.ts +13 -2
  112. package/dist-lib/components/ui/Skeleton.js +15 -14
  113. package/dist-lib/components/ui/Skeleton.js.map +1 -1
  114. package/dist-lib/components/ui/Slider.js +41 -29
  115. package/dist-lib/components/ui/Slider.js.map +1 -1
  116. package/dist-lib/components/ui/Snackbar.js +23 -22
  117. package/dist-lib/components/ui/Snackbar.js.map +1 -1
  118. package/dist-lib/components/ui/Spinner.js +18 -6
  119. package/dist-lib/components/ui/Spinner.js.map +1 -1
  120. package/dist-lib/components/ui/Stepper.d.ts +6 -0
  121. package/dist-lib/components/ui/Stepper.js +71 -48
  122. package/dist-lib/components/ui/Stepper.js.map +1 -1
  123. package/dist-lib/components/ui/Switch.js +46 -43
  124. package/dist-lib/components/ui/Switch.js.map +1 -1
  125. package/dist-lib/components/ui/Table.d.ts +33 -5
  126. package/dist-lib/components/ui/Table.js +141 -119
  127. package/dist-lib/components/ui/Table.js.map +1 -1
  128. package/dist-lib/components/ui/Tabs.js +50 -48
  129. package/dist-lib/components/ui/Tabs.js.map +1 -1
  130. package/dist-lib/components/ui/TagInput.js +45 -45
  131. package/dist-lib/components/ui/TagInput.js.map +1 -1
  132. package/dist-lib/components/ui/Textarea.js +65 -54
  133. package/dist-lib/components/ui/Textarea.js.map +1 -1
  134. package/dist-lib/components/ui/Timeline.js +39 -35
  135. package/dist-lib/components/ui/Timeline.js.map +1 -1
  136. package/dist-lib/components/ui/Toast.js +44 -57
  137. package/dist-lib/components/ui/Toast.js.map +1 -1
  138. package/dist-lib/components/ui/Tooltip.d.ts +4 -1
  139. package/dist-lib/components/ui/Tooltip.js +24 -22
  140. package/dist-lib/components/ui/Tooltip.js.map +1 -1
  141. package/dist-lib/components/ui/TopNav.d.ts +7 -3
  142. package/dist-lib/components/ui/TopNav.js +35 -25
  143. package/dist-lib/components/ui/TopNav.js.map +1 -1
  144. package/dist-lib/components/ui/Tree.d.ts +15 -10
  145. package/dist-lib/components/ui/Tree.js +82 -79
  146. package/dist-lib/components/ui/Tree.js.map +1 -1
  147. package/dist-lib/hooks/use-debounce.d.ts +19 -0
  148. package/dist-lib/hooks/use-debounce.js +36 -0
  149. package/dist-lib/hooks/use-debounce.js.map +1 -0
  150. package/dist-lib/hooks/use-delayed-loading.d.ts +21 -0
  151. package/dist-lib/hooks/use-delayed-loading.js +20 -0
  152. package/dist-lib/hooks/use-delayed-loading.js.map +1 -0
  153. package/dist-lib/hooks/use-field-ids.d.ts +2 -1
  154. package/dist-lib/hooks/use-field-ids.js +9 -9
  155. package/dist-lib/hooks/use-field-ids.js.map +1 -1
  156. package/dist-lib/hooks/use-media-query.d.ts +3 -1
  157. package/dist-lib/hooks/use-media-query.js +16 -12
  158. package/dist-lib/hooks/use-media-query.js.map +1 -1
  159. package/dist-lib/hooks/use-modifier-key.d.ts +13 -0
  160. package/dist-lib/hooks/use-modifier-key.js +19 -0
  161. package/dist-lib/hooks/use-modifier-key.js.map +1 -0
  162. package/dist-lib/hooks/use-toast.d.ts +7 -2
  163. package/dist-lib/hooks/use-toast.js +61 -30
  164. package/dist-lib/hooks/use-toast.js.map +1 -1
  165. package/dist-lib/icons/index.d.ts +9 -0
  166. package/dist-lib/icons/index.js +148 -130
  167. package/dist-lib/icons/index.js.map +1 -1
  168. package/dist-lib/illustrations/index.d.ts +1 -0
  169. package/dist-lib/illustrations/index.js +15 -6
  170. package/dist-lib/illustrations/index.js.map +1 -1
  171. package/dist-lib/index.d.ts +6 -0
  172. package/dist-lib/index.js +280 -260
  173. package/dist-lib/index.js.map +1 -1
  174. package/dist-lib/lib/format.d.ts +65 -0
  175. package/dist-lib/lib/format.js +95 -0
  176. package/dist-lib/lib/format.js.map +1 -0
  177. package/dist-lib/lib/return-focus.d.ts +11 -0
  178. package/dist-lib/lib/return-focus.js +12 -0
  179. package/dist-lib/lib/return-focus.js.map +1 -0
  180. package/dist-lib/lib/strings.d.ts +62 -1
  181. package/dist-lib/lib/strings.js +75 -19
  182. package/dist-lib/lib/strings.js.map +1 -1
  183. package/dist-lib/lib/strings.mn.js +50 -5
  184. package/dist-lib/lib/strings.mn.js.map +1 -1
  185. package/dist-lib/styles.css +1 -1
  186. package/dist-lib/theme.css +141 -78
  187. package/package.json +10 -3
@@ -1,18 +1,20 @@
1
1
  "use client";
2
- import { jsxs as E, jsx as e } from "react/jsx-runtime";
3
- import { forwardRef as K, useRef as Q, useState as I } from "react";
4
- import { X as U, EyeOff as W, Eye as Y, Search as Z } from "../../icons/index.js";
5
- import { cn as a } from "../../lib/utils.js";
6
- import { useStrings as $ } from "../../hooks/use-strings.js";
7
- import { useFieldIds as ee } from "../../hooks/use-field-ids.js";
8
- import { cva as P } from "class-variance-authority";
9
- const te = P(
2
+ import { jsxs as B, jsx as e } from "react/jsx-runtime";
3
+ import { forwardRef as Y, useRef as Z, useState as P } from "react";
4
+ import { X as $, EyeOff as ee, Eye as te, Search as re } from "../../icons/index.js";
5
+ import { cn as s } from "../../lib/utils.js";
6
+ import { useStrings as ne } from "../../hooks/use-strings.js";
7
+ import { useFieldIds as se } from "../../hooks/use-field-ids.js";
8
+ import { cva as j } from "class-variance-authority";
9
+ const ie = j(
10
10
  [
11
11
  "group inline-flex items-center w-full",
12
- "rounded-md border border-input bg-card text-sm",
12
+ "rounded-md border border-border-input bg-card text-sm",
13
13
  "transition-colors duration-[var(--duration-fast)] ease-[var(--ease-out)]",
14
14
  "has-disabled:opacity-50 has-disabled:pointer-events-none",
15
- "focus-within:ring-2 focus-within:ring-offset-2 focus-within:ring-offset-background"
15
+ "focus-within:ring-2 focus-within:ring-offset-2 focus-within:ring-offset-background",
16
+ // Invalid state comes from the input's aria-invalid so Form wiring needs no extra prop.
17
+ "has-aria-invalid:border-danger has-aria-invalid:focus-within:border-danger has-aria-invalid:focus-within:ring-danger"
16
18
  ],
17
19
  {
18
20
  variants: {
@@ -31,105 +33,117 @@ const te = P(
31
33
  tone: "default"
32
34
  }
33
35
  }
34
- ), re = P([
36
+ ), oe = j([
35
37
  "flex-1 min-w-0 bg-transparent outline-none",
36
38
  "placeholder:text-foreground-subtle",
37
39
  "text-foreground",
38
40
  // 16px below md so iOS Safari does not zoom the page on focus; --text-lg = 1rem.
39
41
  "text-lg md:text-sm",
40
42
  "disabled:cursor-not-allowed"
41
- ]), se = K(function({
42
- className: S,
43
- type: s = "text",
44
- size: R,
45
- tone: j,
46
- label: x,
47
- helperText: d,
48
- error: c,
49
- prefix: k,
50
- suffix: v,
51
- clearable: B,
52
- onClear: l,
53
- hideLabel: O,
54
- id: F,
55
- disabled: H,
56
- value: u,
57
- defaultValue: n,
43
+ ]), S = s(
44
+ "text-foreground-subtle hover:text-foreground relative -m-1 flex size-6 shrink-0 items-center justify-center rounded-sm",
45
+ 'before:absolute before:-inset-0.5 before:content-[""]',
46
+ "focus-visible:ring-ring focus-visible:ring-offset-background outline-none focus-visible:ring-2 focus-visible:ring-offset-2",
47
+ "disabled:pointer-events-none"
48
+ ), ae = Y(function({
49
+ className: R,
50
+ type: i = "text",
51
+ size: O,
52
+ tone: F,
53
+ label: v,
54
+ helperText: l,
55
+ error: o,
56
+ prefix: H,
57
+ suffix: w,
58
+ clearable: L,
59
+ onClear: u,
60
+ hideLabel: T,
61
+ id: _,
62
+ disabled: r,
63
+ value: N,
64
+ defaultValue: a,
58
65
  onInput: f,
59
- ...L
60
- }, o) {
61
- const m = $(), p = !!c, { fieldId: w, helperId: T, errorId: _, describedBy: D } = ee(F, {
62
- hasHelper: !!d,
63
- hasError: p
64
- }), r = Q(null), M = (t) => {
65
- r.current = t, typeof o == "function" ? o(t) : o && (o.current = t);
66
- }, [i, V] = I(!1), X = s === "password" ? i ? "text" : "password" : s, q = p ? "error" : j, N = k ?? (s === "search" ? /* @__PURE__ */ e(Z, { className: "text-foreground-subtle size-4", "aria-hidden": !0 }) : null), g = u !== void 0, [A, y] = I(
67
- n == null ? "" : String(n)
68
- ), h = g ? u : A, C = h !== void 0 && h !== "" && h !== null, G = (t) => {
69
- g || y(t.currentTarget.value), f == null || f(t);
70
- }, J = () => {
71
- var t, z;
72
- if (!g && r.current) {
73
- const b = (t = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value")) == null ? void 0 : t.set;
74
- b == null || b.call(r.current, ""), r.current.dispatchEvent(new Event("input", { bubbles: !0 })), y("");
66
+ "aria-describedby": D,
67
+ "aria-invalid": m,
68
+ ...M
69
+ }, c) {
70
+ const g = ne(), y = !!o || m === !0 || m === "true", { fieldId: z, helperId: V, errorId: X, describedBy: q } = se(_, {
71
+ hasHelper: !!l,
72
+ hasError: !!o,
73
+ extra: D
74
+ }), h = N === null ? "" : N, n = Z(null), A = (t) => {
75
+ n.current = t, typeof c == "function" ? c(t) : c && (c.current = t);
76
+ }, [d, C] = P(!1), G = i === "password" ? d ? "text" : "password" : i, J = y ? "error" : F, E = H ?? (i === "search" ? /* @__PURE__ */ e(re, { className: "text-foreground-subtle size-4", "aria-hidden": !0 }) : null), p = h !== void 0, [K, I] = P(
77
+ a == null ? "" : String(a)
78
+ ), b = p ? h : K, Q = b !== void 0 && b !== "" && b !== null, U = (t) => {
79
+ p || I(t.currentTarget.value), f == null || f(t);
80
+ }, W = () => {
81
+ var t, k;
82
+ if (!p && n.current) {
83
+ const x = (t = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value")) == null ? void 0 : t.set;
84
+ x == null || x.call(n.current, ""), n.current.dispatchEvent(new Event("input", { bubbles: !0 })), I("");
75
85
  }
76
- l == null || l(), (z = r.current) == null || z.focus();
86
+ u == null || u(), (k = n.current) == null || k.focus();
77
87
  };
78
- return /* @__PURE__ */ E("div", { className: a("flex flex-col gap-1.5", S), children: [
79
- x && /* @__PURE__ */ e(
88
+ return /* @__PURE__ */ B("div", { className: s("flex flex-col gap-1.5", R), children: [
89
+ v && /* @__PURE__ */ e(
80
90
  "label",
81
91
  {
82
- htmlFor: w,
83
- className: a("text-foreground text-sm font-medium", O && "sr-only"),
84
- children: x
92
+ htmlFor: z,
93
+ className: s("text-foreground text-sm font-medium", T && "sr-only"),
94
+ children: v
85
95
  }
86
96
  ),
87
- /* @__PURE__ */ E("div", { className: a(te({ size: R, tone: q })), children: [
88
- N && /* @__PURE__ */ e("span", { className: "text-foreground-subtle flex items-center [&_svg]:size-4", children: N }),
97
+ /* @__PURE__ */ B("div", { className: s(ie({ size: O, tone: J })), children: [
98
+ E && /* @__PURE__ */ e("span", { className: "text-foreground-subtle flex items-center [&_svg]:size-4", children: E }),
89
99
  /* @__PURE__ */ e(
90
100
  "input",
91
101
  {
92
- ref: M,
93
- id: w,
94
- type: X,
95
- disabled: H,
96
- value: u,
97
- defaultValue: n,
98
- onInput: G,
99
- "aria-invalid": p || void 0,
100
- "aria-describedby": D,
101
- className: a(re()),
102
- ...L
102
+ ref: A,
103
+ id: z,
104
+ type: G,
105
+ disabled: r,
106
+ value: h,
107
+ defaultValue: a,
108
+ onInput: U,
109
+ "aria-invalid": y ? !0 : m,
110
+ "aria-describedby": q,
111
+ className: s(oe()),
112
+ ...M
103
113
  }
104
114
  ),
105
- B && C && /* @__PURE__ */ e(
115
+ L && Q && /* @__PURE__ */ e(
106
116
  "button",
107
117
  {
108
118
  type: "button",
109
- onClick: J,
110
- "aria-label": m.input.clear,
111
- className: "text-foreground-subtle hover:text-foreground focus-visible:ring-ring flex items-center rounded-sm outline-none focus-visible:ring-2",
112
- children: /* @__PURE__ */ e(U, { className: "size-4", "aria-hidden": !0 })
119
+ onClick: W,
120
+ disabled: r,
121
+ tabIndex: r ? -1 : void 0,
122
+ "aria-label": g.input.clear,
123
+ className: S,
124
+ children: /* @__PURE__ */ e($, { className: "size-4", "aria-hidden": !0 })
113
125
  }
114
126
  ),
115
- s === "password" && /* @__PURE__ */ e(
127
+ i === "password" && /* @__PURE__ */ e(
116
128
  "button",
117
129
  {
118
130
  type: "button",
119
- onClick: () => V((t) => !t),
120
- "aria-label": i ? m.input.hidePassword : m.input.showPassword,
121
- "aria-pressed": i,
122
- className: "text-foreground-subtle hover:text-foreground focus-visible:ring-ring flex items-center rounded-sm outline-none focus-visible:ring-2",
123
- children: i ? /* @__PURE__ */ e(W, { className: "size-4", "aria-hidden": !0 }) : /* @__PURE__ */ e(Y, { className: "size-4", "aria-hidden": !0 })
131
+ onClick: () => C((t) => !t),
132
+ disabled: r,
133
+ tabIndex: r ? -1 : void 0,
134
+ "aria-label": d ? g.input.hidePassword : g.input.showPassword,
135
+ "aria-pressed": d,
136
+ className: S,
137
+ children: d ? /* @__PURE__ */ e(ee, { className: "size-4", "aria-hidden": !0 }) : /* @__PURE__ */ e(te, { className: "size-4", "aria-hidden": !0 })
124
138
  }
125
139
  ),
126
- v && /* @__PURE__ */ e("span", { className: "text-foreground-subtle flex items-center [&_svg]:size-4", children: v })
140
+ w && /* @__PURE__ */ e("span", { className: "text-foreground-subtle flex items-center [&_svg]:size-4", children: w })
127
141
  ] }),
128
- c ? /* @__PURE__ */ e("p", { id: _, role: "alert", className: "text-danger-text text-xs", children: c }) : d ? /* @__PURE__ */ e("p", { id: T, className: "text-foreground-subtle text-xs", children: d }) : null
142
+ o ? /* @__PURE__ */ e("p", { id: X, className: "text-danger-text text-xs", children: o }) : l ? /* @__PURE__ */ e("p", { id: V, className: "text-foreground-subtle text-xs", children: l }) : null
129
143
  ] });
130
144
  });
131
- se.displayName = "Input";
145
+ ae.displayName = "Input";
132
146
  export {
133
- se as Input
147
+ ae as Input
134
148
  };
135
149
  //# sourceMappingURL=Input.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Input.js","sources":["../../../src/components/ui/Input.tsx"],"sourcesContent":["'use client';\n\nimport {\n forwardRef,\n useRef,\n useState,\n type FormEvent,\n type InputHTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { Eye, EyeOff, Search, X } from '@/icons';\nimport { cn } from '@/lib/utils';\nimport { useStrings } from '@/hooks/use-strings';\nimport { cva, type VariantProps } from '@/lib/cva';\nimport { useFieldIds } from '@/hooks/use-field-ids';\n\n/* -----------------------------------------------------------------------------\n * Field-shell variants. The inner <input> is unstyled background and gets all\n * its visual treatment from this wrapper so prefix / suffix / clear slots\n * share the same border + focus state with no double rings.\n * --------------------------------------------------------------------------- */\nconst field = cva(\n [\n 'group inline-flex items-center w-full',\n 'rounded-md border border-input bg-card text-sm',\n 'transition-colors duration-[var(--duration-fast)] ease-[var(--ease-out)]',\n 'has-disabled:opacity-50 has-disabled:pointer-events-none',\n 'focus-within:ring-2 focus-within:ring-offset-2 focus-within:ring-offset-background',\n ],\n {\n variants: {\n size: {\n sm: 'h-8 px-2.5 gap-1.5',\n md: 'h-9 px-3 gap-2',\n lg: 'h-10 px-3.5 gap-2',\n },\n tone: {\n default: 'focus-within:border-accent focus-within:ring-ring',\n error: 'border-danger focus-within:border-danger focus-within:ring-danger',\n },\n },\n defaultVariants: {\n size: 'md',\n tone: 'default',\n },\n },\n);\n\nconst innerInput = cva([\n 'flex-1 min-w-0 bg-transparent outline-none',\n 'placeholder:text-foreground-subtle',\n 'text-foreground',\n // 16px below md so iOS Safari does not zoom the page on focus; --text-lg = 1rem.\n 'text-lg md:text-sm',\n 'disabled:cursor-not-allowed',\n]);\n\ntype InputType = NonNullable<InputHTMLAttributes<HTMLInputElement>['type']>;\n\nexport interface InputProps\n extends\n Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'prefix'>,\n VariantProps<typeof field> {\n /** Field type. `password` enables a show/hide toggle; `search` adds a clear button. */\n type?: InputType;\n /** Visible label rendered above the input. */\n label?: ReactNode;\n /** Hint below the input. Hidden while `error` is set. */\n helperText?: ReactNode;\n /** Validation message. Renders in `danger` colour and sets `aria-invalid`. */\n error?: ReactNode;\n /** Content rendered inside the field, before the input — icon or short text. */\n prefix?: ReactNode;\n /** Content rendered inside the field, after the input. */\n suffix?: ReactNode;\n /** Show an inline clear (×) button when the input has a value. */\n clearable?: boolean;\n /**\n * Fires when the clear button is pressed. Controlled inputs own their state\n * and should reset `value` here; uncontrolled inputs are cleared for you.\n */\n onClear?: () => void;\n /** Visually conceal the label while keeping it for screen readers. */\n hideLabel?: boolean;\n}\n\n/**\n * Text-style input with optional label, helper / error, prefix / suffix,\n * clear, and password show-hide. Wraps a single native `<input>` so it works\n * with `react-hook-form` and any controlled / uncontrolled pattern.\n *\n * @example Email with helper\n * <Input type=\"email\" label=\"Work email\" helperText=\"We never share this.\" />\n *\n * @example Password with show/hide\n * <Input type=\"password\" label=\"Password\" autoComplete=\"current-password\" />\n *\n * @example Search with clear\n * <Input type=\"search\" placeholder=\"Search…\" value={q} onChange={…}\n * clearable onClear={() => setQ('')} />\n *\n * @do Always pair an input with a visible label. If space forces hiding it,\n * use `hideLabel` so the label stays in the accessibility tree.\n * @dont Use placeholder as the only label — placeholders disappear on input\n * and fail accessibility.\n */\nexport const Input = forwardRef<HTMLInputElement, InputProps>(function Input(\n {\n className,\n type = 'text',\n size,\n tone,\n label,\n helperText,\n error,\n prefix,\n suffix,\n clearable,\n onClear,\n hideLabel,\n id,\n disabled,\n value,\n defaultValue,\n onInput,\n ...props\n },\n ref,\n) {\n const strings = useStrings();\n const isError = Boolean(error);\n const { fieldId, helperId, errorId, describedBy } = useFieldIds(id, {\n hasHelper: Boolean(helperText),\n hasError: isError,\n });\n const innerRef = useRef<HTMLInputElement | null>(null);\n const setRefs = (el: HTMLInputElement | null) => {\n innerRef.current = el;\n if (typeof ref === 'function') ref(el);\n else if (ref) ref.current = el;\n };\n\n const [showPassword, setShowPassword] = useState(false);\n const effectiveType = type === 'password' ? (showPassword ? 'text' : 'password') : type;\n\n const effectiveTone = isError ? 'error' : tone;\n\n // Pre-fill prefix slot for search type.\n const renderedPrefix =\n prefix ??\n (type === 'search' ? <Search className=\"text-foreground-subtle size-4\" aria-hidden /> : null);\n\n // Track the value of uncontrolled inputs so `clearable` can show/hide the\n // button without the consumer wiring state.\n const isControlled = value !== undefined;\n const [localValue, setLocalValue] = useState<string>(\n defaultValue === undefined || defaultValue === null ? '' : String(defaultValue),\n );\n const current = isControlled ? value : localValue;\n const hasValue = current !== undefined && current !== '' && current !== null;\n\n const handleInput = (e: FormEvent<HTMLInputElement>) => {\n if (!isControlled) setLocalValue(e.currentTarget.value);\n onInput?.(e);\n };\n\n const handleClear = () => {\n if (!isControlled && innerRef.current) {\n // Use the native setter so React's onChange/onInput listeners fire.\n const setter = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value')?.set;\n setter?.call(innerRef.current, '');\n innerRef.current.dispatchEvent(new Event('input', { bubbles: true }));\n setLocalValue('');\n }\n onClear?.();\n innerRef.current?.focus();\n };\n\n return (\n <div className={cn('flex flex-col gap-1.5', className)}>\n {label && (\n <label\n htmlFor={fieldId}\n className={cn('text-foreground text-sm font-medium', hideLabel && 'sr-only')}\n >\n {label}\n </label>\n )}\n\n <div className={cn(field({ size, tone: effectiveTone }))}>\n {renderedPrefix && (\n <span className=\"text-foreground-subtle flex items-center [&_svg]:size-4\">\n {renderedPrefix}\n </span>\n )}\n\n <input\n ref={setRefs}\n id={fieldId}\n type={effectiveType}\n disabled={disabled}\n value={value}\n defaultValue={defaultValue}\n onInput={handleInput}\n aria-invalid={isError || undefined}\n aria-describedby={describedBy}\n className={cn(innerInput())}\n {...props}\n />\n\n {clearable && hasValue && (\n <button\n type=\"button\"\n onClick={handleClear}\n aria-label={strings.input.clear}\n className=\"text-foreground-subtle hover:text-foreground focus-visible:ring-ring flex items-center rounded-sm outline-none focus-visible:ring-2\"\n >\n <X className=\"size-4\" aria-hidden />\n </button>\n )}\n\n {type === 'password' && (\n <button\n type=\"button\"\n onClick={() => setShowPassword((p) => !p)}\n aria-label={showPassword ? strings.input.hidePassword : strings.input.showPassword}\n aria-pressed={showPassword}\n className=\"text-foreground-subtle hover:text-foreground focus-visible:ring-ring flex items-center rounded-sm outline-none focus-visible:ring-2\"\n >\n {showPassword ? (\n <EyeOff className=\"size-4\" aria-hidden />\n ) : (\n <Eye className=\"size-4\" aria-hidden />\n )}\n </button>\n )}\n\n {suffix && (\n <span className=\"text-foreground-subtle flex items-center [&_svg]:size-4\">{suffix}</span>\n )}\n </div>\n\n {error ? (\n <p id={errorId} role=\"alert\" className=\"text-danger-text text-xs\">\n {error}\n </p>\n ) : helperText ? (\n <p id={helperId} className=\"text-foreground-subtle text-xs\">\n {helperText}\n </p>\n ) : null}\n </div>\n );\n});\n\nInput.displayName = 'Input';\n"],"names":["field","cva","innerInput","Input","forwardRef","className","type","size","tone","label","helperText","error","prefix","suffix","clearable","onClear","hideLabel","id","disabled","value","defaultValue","onInput","props","ref","strings","useStrings","isError","fieldId","helperId","errorId","describedBy","useFieldIds","innerRef","useRef","setRefs","el","showPassword","setShowPassword","useState","effectiveType","effectiveTone","renderedPrefix","jsx","Search","isControlled","localValue","setLocalValue","current","hasValue","handleInput","e","handleClear","setter","_a","_b","cn","jsxs","X","p","EyeOff","Eye"],"mappings":"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"}
1
+ {"version":3,"file":"Input.js","sources":["../../../src/components/ui/Input.tsx"],"sourcesContent":["'use client';\n\nimport {\n forwardRef,\n useRef,\n useState,\n type ComponentProps,\n type InputHTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { Eye, EyeOff, Search, X } from '@/icons';\nimport { cn } from '@/lib/utils';\nimport { useStrings } from '@/hooks/use-strings';\nimport { cva, type VariantProps } from '@/lib/cva';\nimport { useFieldIds } from '@/hooks/use-field-ids';\n\n/* -----------------------------------------------------------------------------\n * Field-shell variants. The inner <input> is unstyled background and gets all\n * its visual treatment from this wrapper so prefix / suffix / clear slots\n * share the same border + focus state with no double rings.\n * --------------------------------------------------------------------------- */\nconst field = cva(\n [\n 'group inline-flex items-center w-full',\n 'rounded-md border border-border-input bg-card text-sm',\n 'transition-colors duration-[var(--duration-fast)] ease-[var(--ease-out)]',\n 'has-disabled:opacity-50 has-disabled:pointer-events-none',\n 'focus-within:ring-2 focus-within:ring-offset-2 focus-within:ring-offset-background',\n // Invalid state comes from the input's aria-invalid so Form wiring needs no extra prop.\n 'has-aria-invalid:border-danger has-aria-invalid:focus-within:border-danger has-aria-invalid:focus-within:ring-danger',\n ],\n {\n variants: {\n size: {\n sm: 'h-8 px-2.5 gap-1.5',\n md: 'h-9 px-3 gap-2',\n lg: 'h-10 px-3.5 gap-2',\n },\n tone: {\n default: 'focus-within:border-accent focus-within:ring-ring',\n error: 'border-danger focus-within:border-danger focus-within:ring-danger',\n },\n },\n defaultVariants: {\n size: 'md',\n tone: 'default',\n },\n },\n);\n\nconst innerInput = cva([\n 'flex-1 min-w-0 bg-transparent outline-none',\n 'placeholder:text-foreground-subtle',\n 'text-foreground',\n // 16px below md so iOS Safari does not zoom the page on focus; --text-lg = 1rem.\n 'text-lg md:text-sm',\n 'disabled:cursor-not-allowed',\n]);\n\ntype InputType = NonNullable<InputHTMLAttributes<HTMLInputElement>['type']>;\n\n// Inline clear / password buttons: 24px box (WCAG 2.5.8 minimum) with a halo\n// that extends the hit area without growing the field.\nconst innerButton = cn(\n 'text-foreground-subtle hover:text-foreground relative -m-1 flex size-6 shrink-0 items-center justify-center rounded-sm',\n 'before:absolute before:-inset-0.5 before:content-[\"\"]',\n 'focus-visible:ring-ring focus-visible:ring-offset-background outline-none focus-visible:ring-2 focus-visible:ring-offset-2',\n 'disabled:pointer-events-none',\n);\n\nexport interface InputProps\n extends\n Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'prefix' | 'value'>,\n VariantProps<typeof field> {\n /** Controlled value. `null` is treated as an empty controlled value (no React warning). */\n value?: InputHTMLAttributes<HTMLInputElement>['value'] | null;\n /** Field type. `password` enables a show/hide toggle; `search` adds a clear button. */\n type?: InputType;\n /** Visible label rendered above the input. */\n label?: ReactNode;\n /** Hint below the input. Hidden while `error` is set. */\n helperText?: ReactNode;\n /** Validation message. Renders in `danger` colour and sets `aria-invalid`. */\n error?: ReactNode;\n /** Content rendered inside the field, before the input — icon or short text. */\n prefix?: ReactNode;\n /** Content rendered inside the field, after the input. */\n suffix?: ReactNode;\n /** Show an inline clear (×) button when the input has a value. */\n clearable?: boolean;\n /**\n * Fires when the clear button is pressed. Controlled inputs own their state\n * and should reset `value` here; uncontrolled inputs are cleared for you.\n */\n onClear?: () => void;\n /** Visually conceal the label while keeping it for screen readers. */\n hideLabel?: boolean;\n}\n\n/**\n * Text-style input with optional label, helper / error, prefix / suffix,\n * clear, and password show-hide. Wraps a single native `<input>` so it works\n * with `react-hook-form` and any controlled / uncontrolled pattern.\n *\n * @example Email with helper\n * <Input type=\"email\" label=\"Work email\" helperText=\"We never share this.\" />\n *\n * @example Password with show/hide\n * <Input type=\"password\" label=\"Password\" autoComplete=\"current-password\" />\n *\n * @example Search with clear\n * <Input type=\"search\" placeholder=\"Search…\" value={q} onChange={…}\n * clearable onClear={() => setQ('')} />\n *\n * @do Always pair an input with a visible label. If space forces hiding it,\n * use `hideLabel` so the label stays in the accessibility tree.\n * @dont Use placeholder as the only label — placeholders disappear on input\n * and fail accessibility.\n */\nexport const Input = forwardRef<HTMLInputElement, InputProps>(function Input(\n {\n className,\n type = 'text',\n size,\n tone,\n label,\n helperText,\n error,\n prefix,\n suffix,\n clearable,\n onClear,\n hideLabel,\n id,\n disabled,\n value: valueProp,\n defaultValue,\n onInput,\n 'aria-describedby': ariaDescribedby,\n 'aria-invalid': ariaInvalid,\n ...props\n },\n ref,\n) {\n const strings = useStrings();\n const isError = Boolean(error) || ariaInvalid === true || ariaInvalid === 'true';\n const { fieldId, helperId, errorId, describedBy } = useFieldIds(id, {\n hasHelper: Boolean(helperText),\n hasError: Boolean(error),\n extra: ariaDescribedby,\n });\n // `null` (nullable form state) is a controlled empty value, not \"uncontrolled\".\n const value = valueProp === null ? '' : valueProp;\n const innerRef = useRef<HTMLInputElement | null>(null);\n const setRefs = (el: HTMLInputElement | null) => {\n innerRef.current = el;\n if (typeof ref === 'function') ref(el);\n else if (ref) ref.current = el;\n };\n\n const [showPassword, setShowPassword] = useState(false);\n const effectiveType = type === 'password' ? (showPassword ? 'text' : 'password') : type;\n\n const effectiveTone = isError ? 'error' : tone;\n\n // Pre-fill prefix slot for search type.\n const renderedPrefix =\n prefix ??\n (type === 'search' ? <Search className=\"text-foreground-subtle size-4\" aria-hidden /> : null);\n\n // Track the value of uncontrolled inputs so `clearable` can show/hide the\n // button without the consumer wiring state.\n const isControlled = value !== undefined;\n const [localValue, setLocalValue] = useState<string>(\n defaultValue === undefined || defaultValue === null ? '' : String(defaultValue),\n );\n const current = isControlled ? value : localValue;\n const hasValue = current !== undefined && current !== '' && current !== null;\n\n // React 19 types `onInput` as `InputEventHandler`; `ComponentProps` keeps this portable.\n const handleInput: NonNullable<ComponentProps<'input'>['onInput']> = (e) => {\n if (!isControlled) setLocalValue(e.currentTarget.value);\n onInput?.(e);\n };\n\n const handleClear = () => {\n if (!isControlled && innerRef.current) {\n // Use the native setter so React's onChange/onInput listeners fire.\n const setter = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value')?.set;\n setter?.call(innerRef.current, '');\n innerRef.current.dispatchEvent(new Event('input', { bubbles: true }));\n setLocalValue('');\n }\n onClear?.();\n innerRef.current?.focus();\n };\n\n return (\n <div className={cn('flex flex-col gap-1.5', className)}>\n {label && (\n <label\n htmlFor={fieldId}\n className={cn('text-foreground text-sm font-medium', hideLabel && 'sr-only')}\n >\n {label}\n </label>\n )}\n\n <div className={cn(field({ size, tone: effectiveTone }))}>\n {renderedPrefix && (\n <span className=\"text-foreground-subtle flex items-center [&_svg]:size-4\">\n {renderedPrefix}\n </span>\n )}\n\n <input\n ref={setRefs}\n id={fieldId}\n type={effectiveType}\n disabled={disabled}\n value={value}\n defaultValue={defaultValue}\n onInput={handleInput}\n aria-invalid={isError ? true : ariaInvalid}\n aria-describedby={describedBy}\n className={cn(innerInput())}\n {...props}\n />\n\n {clearable && hasValue && (\n <button\n type=\"button\"\n onClick={handleClear}\n disabled={disabled}\n tabIndex={disabled ? -1 : undefined}\n aria-label={strings.input.clear}\n className={innerButton}\n >\n <X className=\"size-4\" aria-hidden />\n </button>\n )}\n\n {type === 'password' && (\n <button\n type=\"button\"\n onClick={() => setShowPassword((p) => !p)}\n disabled={disabled}\n tabIndex={disabled ? -1 : undefined}\n aria-label={showPassword ? strings.input.hidePassword : strings.input.showPassword}\n aria-pressed={showPassword}\n className={innerButton}\n >\n {showPassword ? (\n <EyeOff className=\"size-4\" aria-hidden />\n ) : (\n <Eye className=\"size-4\" aria-hidden />\n )}\n </button>\n )}\n\n {suffix && (\n <span className=\"text-foreground-subtle flex items-center [&_svg]:size-4\">{suffix}</span>\n )}\n </div>\n\n {error ? (\n <p id={errorId} className=\"text-danger-text text-xs\">\n {error}\n </p>\n ) : helperText ? (\n <p id={helperId} className=\"text-foreground-subtle text-xs\">\n {helperText}\n </p>\n ) : null}\n </div>\n );\n});\n\nInput.displayName = 'Input';\n"],"names":["field","cva","innerInput","innerButton","cn","Input","forwardRef","className","type","size","tone","label","helperText","error","prefix","suffix","clearable","onClear","hideLabel","id","disabled","valueProp","defaultValue","onInput","ariaDescribedby","ariaInvalid","props","ref","strings","useStrings","isError","fieldId","helperId","errorId","describedBy","useFieldIds","value","innerRef","useRef","setRefs","el","showPassword","setShowPassword","useState","effectiveType","effectiveTone","renderedPrefix","jsx","Search","isControlled","localValue","setLocalValue","current","hasValue","handleInput","e","handleClear","setter","_a","_b","jsxs","X","p","EyeOff","Eye"],"mappings":"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"}
@@ -8,7 +8,7 @@ const d = m(function({ size: e = "sm", className: r, ...o }, t) {
8
8
  {
9
9
  ref: t,
10
10
  className: s(
11
- "inline-flex items-center justify-center rounded-sm border border-border bg-background-subtle font-mono",
11
+ "border-border bg-background-subtle inline-flex items-center justify-center rounded-sm border font-mono",
12
12
  "text-foreground-muted shadow-xs",
13
13
  e === "sm" ? "h-5 min-w-5 px-1 text-xs" : "h-6 min-w-6 px-1.5 text-xs",
14
14
  r
@@ -1 +1 @@
1
- {"version":3,"file":"Kbd.js","sources":["../../../src/components/ui/Kbd.tsx"],"sourcesContent":["'use client';\n\nimport { forwardRef, type HTMLAttributes } from 'react';\nimport { cn } from '@/lib/utils';\n\nexport interface KbdProps extends HTMLAttributes<HTMLElement> {\n /** Visual size — match the surrounding text. */\n size?: 'sm' | 'md';\n}\n\n/**\n * Stylised keyboard shortcut indicator. Compose multiple `<Kbd>` for chords.\n *\n * @example\n * Press <Kbd>⌘</Kbd>+<Kbd>K</Kbd> to open the command palette.\n *\n * @do Use OS-conventional symbols (⌘ ⇧ ⌥ ⌃ ⏎) — keep visuals consistent\n * across the app.\n * @dont Use Kbd for clickable buttons — it implies a real keyboard input.\n */\nexport const Kbd = forwardRef<HTMLElement, KbdProps>(function Kbd(\n { size = 'sm', className, ...props },\n ref,\n) {\n return (\n <kbd\n ref={ref}\n className={cn(\n 'inline-flex items-center justify-center rounded-sm border border-border bg-background-subtle font-mono',\n 'text-foreground-muted shadow-xs',\n size === 'sm' ? 'h-5 min-w-5 px-1 text-xs' : 'h-6 min-w-6 px-1.5 text-xs',\n className,\n )}\n {...props}\n />\n );\n});\nKbd.displayName = 'Kbd';\n"],"names":["Kbd","forwardRef","size","className","props","ref","jsx","cn"],"mappings":";;;;AAoBO,MAAMA,IAAMC,EAAkC,SACnD,EAAE,MAAAC,IAAO,MAAM,WAAAC,GAAW,GAAGC,EAAA,GAC7BC,GACA;AACA,SACE,gBAAAC;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAAD;AAAA,MACA,WAAWE;AAAA,QACT;AAAA,QACA;AAAA,QACAL,MAAS,OAAO,6BAA6B;AAAA,QAC7CC;AAAA,MAAA;AAAA,MAED,GAAGC;AAAA,IAAA;AAAA,EAAA;AAGV,CAAC;AACDJ,EAAI,cAAc;"}
1
+ {"version":3,"file":"Kbd.js","sources":["../../../src/components/ui/Kbd.tsx"],"sourcesContent":["'use client';\n\nimport { forwardRef, type HTMLAttributes } from 'react';\nimport { cn } from '@/lib/utils';\n\nexport interface KbdProps extends HTMLAttributes<HTMLElement> {\n /** Visual size — match the surrounding text. */\n size?: 'sm' | 'md';\n}\n\n/**\n * Stylised keyboard shortcut indicator. Compose multiple `<Kbd>` for chords.\n *\n * @example\n * Press <Kbd>⌘</Kbd>+<Kbd>K</Kbd> to open the command palette.\n *\n * @do Use OS-conventional symbols (⌘ ⇧ ⌥ ⌃ ⏎) — keep visuals consistent\n * across the app.\n * @dont Use Kbd for clickable buttons — it implies a real keyboard input.\n */\nexport const Kbd = forwardRef<HTMLElement, KbdProps>(function Kbd(\n { size = 'sm', className, ...props },\n ref,\n) {\n return (\n <kbd\n ref={ref}\n className={cn(\n 'border-border bg-background-subtle inline-flex items-center justify-center rounded-sm border font-mono',\n 'text-foreground-muted shadow-xs',\n size === 'sm' ? 'h-5 min-w-5 px-1 text-xs' : 'h-6 min-w-6 px-1.5 text-xs',\n className,\n )}\n {...props}\n />\n );\n});\nKbd.displayName = 'Kbd';\n"],"names":["Kbd","forwardRef","size","className","props","ref","jsx","cn"],"mappings":";;;;AAoBO,MAAMA,IAAMC,EAAkC,SACnD,EAAE,MAAAC,IAAO,MAAM,WAAAC,GAAW,GAAGC,EAAA,GAC7BC,GACA;AACA,SACE,gBAAAC;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAAD;AAAA,MACA,WAAWE;AAAA,QACT;AAAA,QACA;AAAA,QACAL,MAAS,OAAO,6BAA6B;AAAA,QAC7CC;AAAA,MAAA;AAAA,MAED,GAAGC;AAAA,IAAA;AAAA,EAAA;AAGV,CAAC;AACDJ,EAAI,cAAc;"}