@tappify/extension-sdk 2.1.0-beta.1 → 2.1.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 (137) hide show
  1. package/README.md +18 -54
  2. package/dist/{chunk-6HETNZJY.cjs → chunk-2DBSVKAU.cjs} +1 -1
  3. package/dist/{chunk-6HETNZJY.cjs.map → chunk-2DBSVKAU.cjs.map} +1 -1
  4. package/dist/{chunk-O357OJXL.cjs → chunk-3YWVYA42.cjs} +18 -14
  5. package/dist/chunk-3YWVYA42.cjs.map +1 -0
  6. package/dist/{chunk-GAUZYBXE.cjs → chunk-5AAPD5WV.cjs} +11 -11
  7. package/dist/chunk-5AAPD5WV.cjs.map +1 -0
  8. package/dist/{chunk-SGEYDV3K.mjs → chunk-BDCX6LRQ.mjs} +3 -3
  9. package/dist/chunk-BDCX6LRQ.mjs.map +1 -0
  10. package/dist/{chunk-KZ5NGFUP.mjs → chunk-C3YNVHBP.mjs} +7 -20
  11. package/dist/chunk-C3YNVHBP.mjs.map +1 -0
  12. package/dist/{chunk-QXD7WVKK.mjs → chunk-CSTYBKZC.mjs} +1 -1
  13. package/dist/chunk-CSTYBKZC.mjs.map +1 -0
  14. package/dist/{chunk-SWG7CNTZ.mjs → chunk-CTSZ5D7S.mjs} +5 -9
  15. package/dist/chunk-CTSZ5D7S.mjs.map +1 -0
  16. package/dist/chunk-EW54H7CR.cjs +722 -0
  17. package/dist/chunk-EW54H7CR.cjs.map +1 -0
  18. package/dist/chunk-EX3NFXDK.mjs +722 -0
  19. package/dist/chunk-EX3NFXDK.mjs.map +1 -0
  20. package/dist/{chunk-A74HCO6T.cjs → chunk-G7XZSN2Q.cjs} +18 -31
  21. package/dist/chunk-G7XZSN2Q.cjs.map +1 -0
  22. package/dist/{chunk-RBIQT75L.mjs → chunk-GG3IX52W.mjs} +2 -2
  23. package/dist/{chunk-SLGOHIBL.mjs → chunk-IGK2AP6J.mjs} +17 -13
  24. package/dist/chunk-IGK2AP6J.mjs.map +1 -0
  25. package/dist/{chunk-VV7ELNRW.cjs → chunk-JMUK3K47.cjs} +3 -3
  26. package/dist/{chunk-VV7ELNRW.cjs.map → chunk-JMUK3K47.cjs.map} +1 -1
  27. package/dist/{chunk-SGCYEEXD.mjs → chunk-MNDVYPEP.mjs} +2 -9
  28. package/dist/chunk-MNDVYPEP.mjs.map +1 -0
  29. package/dist/{chunk-BPCGXXMD.cjs → chunk-NFUPPCX4.cjs} +18 -22
  30. package/dist/chunk-NFUPPCX4.cjs.map +1 -0
  31. package/dist/{chunk-PRCZMOLD.cjs → chunk-OPPYEA7F.cjs} +3 -3
  32. package/dist/{chunk-PRCZMOLD.cjs.map → chunk-OPPYEA7F.cjs.map} +1 -1
  33. package/dist/{chunk-7YKH4LZN.cjs → chunk-PYJMJF44.cjs} +2 -9
  34. package/dist/chunk-PYJMJF44.cjs.map +1 -0
  35. package/dist/{chunk-QA5AL3VZ.mjs → chunk-QHM7XNRK.mjs} +2 -2
  36. package/dist/{chunk-QA5AL3VZ.mjs.map → chunk-QHM7XNRK.mjs.map} +1 -1
  37. package/dist/codegen.cjs.map +1 -1
  38. package/dist/codegen.d.cts +7 -40
  39. package/dist/codegen.d.ts +7 -40
  40. package/dist/codegen.mjs.map +1 -1
  41. package/dist/{constants-BAimnqOK.d.cts → constants-DJ_KgZpN.d.cts} +8 -41
  42. package/dist/{constants-BAimnqOK.d.ts → constants-DJ_KgZpN.d.ts} +8 -41
  43. package/dist/{context-Cr93B05o.d.ts → context-Dt6xh_5t.d.cts} +4 -5
  44. package/dist/{context-DJ3REtdT.d.cts → context-Ml7k_V14.d.ts} +4 -5
  45. package/dist/{errors-Cqh0wrqt.d.ts → errors-COsBh7kd.d.cts} +2 -3
  46. package/dist/{errors-Cqh0wrqt.d.cts → errors-COsBh7kd.d.ts} +2 -3
  47. package/dist/handler-CZIlZ5vu.d.ts +227 -0
  48. package/dist/handler-kU9Jf36K.d.cts +227 -0
  49. package/dist/host.cjs +4 -4
  50. package/dist/host.d.cts +4 -4
  51. package/dist/host.d.ts +4 -4
  52. package/dist/host.mjs +3 -3
  53. package/dist/index.cjs +34 -5
  54. package/dist/index.cjs.map +1 -1
  55. package/dist/index.d.cts +627 -69
  56. package/dist/index.d.ts +627 -69
  57. package/dist/index.mjs +33 -4
  58. package/dist/manifest.cjs +23 -132
  59. package/dist/manifest.cjs.map +1 -1
  60. package/dist/manifest.d.cts +12 -93
  61. package/dist/manifest.d.ts +12 -93
  62. package/dist/manifest.mjs +9 -118
  63. package/dist/manifest.mjs.map +1 -1
  64. package/dist/server.cjs +66 -14
  65. package/dist/server.cjs.map +1 -1
  66. package/dist/server.d.cts +6 -6
  67. package/dist/server.d.ts +6 -6
  68. package/dist/server.mjs +61 -9
  69. package/dist/server.mjs.map +1 -1
  70. package/dist/styles.css +367 -0
  71. package/dist/testing/index.cjs +13 -72
  72. package/dist/testing/index.cjs.map +1 -1
  73. package/dist/testing/index.d.cts +10 -29
  74. package/dist/testing/index.d.ts +10 -29
  75. package/dist/testing/index.mjs +13 -72
  76. package/dist/testing/index.mjs.map +1 -1
  77. package/dist/testing/jest.cjs +5 -5
  78. package/dist/testing/jest.mjs +2 -2
  79. package/dist/testing/vitest.cjs +5 -5
  80. package/dist/testing/vitest.cjs.map +1 -1
  81. package/dist/testing/vitest.d.cts +0 -10
  82. package/dist/testing/vitest.d.ts +0 -10
  83. package/dist/testing/vitest.mjs +2 -2
  84. package/dist/testing/vitest.mjs.map +1 -1
  85. package/dist/{types-BYGcp5pZ.d.ts → types-DDAGLpov.d.ts} +3 -4
  86. package/dist/{types-I1JOZyI_.d.cts → types-DrpQSv_2.d.cts} +3 -4
  87. package/dist/vite-preview.cjs +125 -294
  88. package/dist/vite-preview.cjs.map +1 -1
  89. package/dist/vite-preview.d.cts +24 -6
  90. package/dist/vite-preview.d.ts +24 -6
  91. package/dist/vite-preview.mjs +118 -287
  92. package/dist/vite-preview.mjs.map +1 -1
  93. package/dist/vite.cjs +23 -133
  94. package/dist/vite.cjs.map +1 -1
  95. package/dist/vite.d.cts +7 -40
  96. package/dist/vite.d.ts +7 -40
  97. package/dist/vite.mjs +17 -127
  98. package/dist/vite.mjs.map +1 -1
  99. package/package.json +2 -12
  100. package/schema/extension-v2.json +121 -432
  101. package/dist/chunk-2CY5HVY7.mjs +0 -59
  102. package/dist/chunk-2CY5HVY7.mjs.map +0 -1
  103. package/dist/chunk-7YKH4LZN.cjs.map +0 -1
  104. package/dist/chunk-A74HCO6T.cjs.map +0 -1
  105. package/dist/chunk-BPCGXXMD.cjs.map +0 -1
  106. package/dist/chunk-EB5XWQAU.cjs +0 -132
  107. package/dist/chunk-EB5XWQAU.cjs.map +0 -1
  108. package/dist/chunk-GAUZYBXE.cjs.map +0 -1
  109. package/dist/chunk-KZ5NGFUP.mjs.map +0 -1
  110. package/dist/chunk-O357OJXL.cjs.map +0 -1
  111. package/dist/chunk-ONJMPO3P.cjs +0 -59
  112. package/dist/chunk-ONJMPO3P.cjs.map +0 -1
  113. package/dist/chunk-QJMZRV7A.mjs +0 -132
  114. package/dist/chunk-QJMZRV7A.mjs.map +0 -1
  115. package/dist/chunk-QXD7WVKK.mjs.map +0 -1
  116. package/dist/chunk-SGCYEEXD.mjs.map +0 -1
  117. package/dist/chunk-SGEYDV3K.mjs.map +0 -1
  118. package/dist/chunk-SLGOHIBL.mjs.map +0 -1
  119. package/dist/chunk-SWG7CNTZ.mjs.map +0 -1
  120. package/dist/client-CV1qzQgx.d.cts +0 -25
  121. package/dist/client-CnlSHDWE.d.ts +0 -25
  122. package/dist/ui/styles.css +0 -740
  123. package/dist/ui.cjs +0 -1018
  124. package/dist/ui.cjs.map +0 -1
  125. package/dist/ui.d.cts +0 -231
  126. package/dist/ui.d.ts +0 -231
  127. package/dist/ui.mjs +0 -1018
  128. package/dist/ui.mjs.map +0 -1
  129. package/dist/vite-preview-bootstrap.cjs +0 -66
  130. package/dist/vite-preview-bootstrap.cjs.map +0 -1
  131. package/dist/vite-preview-bootstrap.d.cts +0 -15
  132. package/dist/vite-preview-bootstrap.d.ts +0 -15
  133. package/dist/vite-preview-bootstrap.mjs +0 -66
  134. package/dist/vite-preview-bootstrap.mjs.map +0 -1
  135. package/dist/work-events-DB3WR468.d.ts +0 -547
  136. package/dist/work-events-Dxe7Djdy.d.cts +0 -547
  137. /package/dist/{chunk-RBIQT75L.mjs.map → chunk-GG3IX52W.mjs.map} +0 -0
@@ -0,0 +1,722 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
10
+
11
+
12
+
13
+
14
+
15
+
16
+
17
+
18
+ var _chunk5AAPD5WVcjs = require('./chunk-5AAPD5WV.cjs');
19
+
20
+
21
+ var _chunkOPPYEA7Fcjs = require('./chunk-OPPYEA7F.cjs');
22
+
23
+
24
+
25
+
26
+ var _chunk2DBSVKAUcjs = require('./chunk-2DBSVKAU.cjs');
27
+
28
+
29
+ var _chunkQ7SFCCGTcjs = require('./chunk-Q7SFCCGT.cjs');
30
+
31
+ // src/index.ts
32
+ var src_exports = {};
33
+ _chunkQ7SFCCGTcjs.__export.call(void 0, src_exports, {
34
+ TAP_ERROR_CODES: () => _chunk2DBSVKAUcjs.TAP_ERROR_CODES,
35
+ TapButton: () => TapButton,
36
+ TapCard: () => TapCard,
37
+ TapDialog: () => TapDialog,
38
+ TapEmptyState: () => TapEmptyState,
39
+ TapError: () => _chunk2DBSVKAUcjs.TapError,
40
+ TapErrorState: () => TapErrorState,
41
+ TapForm: () => TapForm,
42
+ TapInput: () => TapInput,
43
+ TapPageHeader: () => TapPageHeader,
44
+ TapSelect: () => TapSelect,
45
+ TapServerError: () => _chunk2DBSVKAUcjs.TapServerError,
46
+ TapSkeleton: () => TapSkeleton,
47
+ TapStat: () => TapStat,
48
+ TapTable: () => TapTable,
49
+ cn: () => cn,
50
+ dataQueryKey: () => _chunk5AAPD5WVcjs.dataQueryKey,
51
+ formFields: () => formFields,
52
+ installPrefix: () => _chunk5AAPD5WVcjs.installPrefix,
53
+ procedurePrefix: () => _chunk5AAPD5WVcjs.procedurePrefix,
54
+ procedureQueryKey: () => _chunk5AAPD5WVcjs.procedureQueryKey,
55
+ storageQueryKey: () => _chunk5AAPD5WVcjs.storageQueryKey,
56
+ useTap: () => _chunkOPPYEA7Fcjs.useTap,
57
+ useTapAuth: () => _chunk5AAPD5WVcjs.useTapAuth,
58
+ useTapContext: () => _chunk5AAPD5WVcjs.useTapContext,
59
+ useTapFilters: () => _chunk5AAPD5WVcjs.useTapFilters,
60
+ useTapParams: () => _chunk5AAPD5WVcjs.useTapParams,
61
+ useTapProject: () => _chunk5AAPD5WVcjs.useTapProject,
62
+ useTapQuery: () => _chunk5AAPD5WVcjs.useTapQuery,
63
+ useTapServer: () => _chunk5AAPD5WVcjs.useTapServer,
64
+ useTapSize: () => _chunk5AAPD5WVcjs.useTapSize,
65
+ useTapState: () => _chunk5AAPD5WVcjs.useTapState,
66
+ useTapStorage: () => _chunk5AAPD5WVcjs.useTapStorage,
67
+ useTapTheme: () => _chunk5AAPD5WVcjs.useTapTheme
68
+ });
69
+
70
+ // src/client/ui/cn.ts
71
+ var _clsx = require('clsx'); var _clsx2 = _interopRequireDefault(_clsx);
72
+ function cn(...values) {
73
+ return _clsx2.default.call(void 0, values);
74
+ }
75
+
76
+ // src/client/ui/primitives.tsx
77
+
78
+
79
+ var _react = require('react');
80
+ var _jsxruntime = require('react/jsx-runtime');
81
+ function TapButton({
82
+ variant = "primary",
83
+ size = "md",
84
+ loading = false,
85
+ disabled,
86
+ className,
87
+ children,
88
+ ...rest
89
+ }) {
90
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
91
+ "button",
92
+ {
93
+ type: "button",
94
+ ...rest,
95
+ disabled: disabled === true || loading,
96
+ "aria-busy": loading || void 0,
97
+ className: cn(
98
+ "tap-btn",
99
+ `tap-btn--${variant}`,
100
+ size === "sm" && "tap-btn--sm",
101
+ className
102
+ ),
103
+ children
104
+ }
105
+ );
106
+ }
107
+ function TapCard({
108
+ title,
109
+ action,
110
+ footer,
111
+ className,
112
+ children
113
+ }) {
114
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "section", { className: cn("tap-card", className), children: [
115
+ (title !== void 0 || action !== void 0) && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "header", { className: "tap-card__head", children: [
116
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: title }),
117
+ action
118
+ ] }),
119
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "tap-card__body", children }),
120
+ footer !== void 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "footer", { className: "tap-card__foot", children: footer })
121
+ ] });
122
+ }
123
+ function TapPageHeader({
124
+ title,
125
+ description,
126
+ actions
127
+ }) {
128
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "tap-page-header", children: [
129
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
130
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h2", { className: "tap-page-header__title", children: title }),
131
+ description !== void 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "tap-page-header__description", children: description })
132
+ ] }),
133
+ actions !== void 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "tap-row", children: actions })
134
+ ] });
135
+ }
136
+ function TapSkeleton({
137
+ lines = 1,
138
+ width,
139
+ className
140
+ }) {
141
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { "aria-hidden": "true", children: Array.from({ length: lines }, (_, index) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
142
+ "span",
143
+ {
144
+ className: cn("tap-skeleton", className),
145
+ style: { width: _nullishCoalesce(width, () => ( `${String(100 - index * 12)}%`)) }
146
+ },
147
+ index
148
+ )) });
149
+ }
150
+ function TapEmptyState({
151
+ title,
152
+ description,
153
+ action
154
+ }) {
155
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "tap-state", children: [
156
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "tap-state__title", children: title }),
157
+ description !== void 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: description }),
158
+ action
159
+ ] });
160
+ }
161
+ function TapErrorState({
162
+ title,
163
+ description,
164
+ code,
165
+ onRetry
166
+ }) {
167
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "tap-state tap-state--error", role: "alert", children: [
168
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "tap-state__title", children: title }),
169
+ description !== void 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: description }),
170
+ code !== void 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "tap-state__code", children: code }),
171
+ onRetry !== void 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TapButton, { variant: "secondary", size: "sm", onClick: onRetry, children: "Retry" })
172
+ ] });
173
+ }
174
+ function TapStat({
175
+ label,
176
+ value,
177
+ delta,
178
+ hint
179
+ }) {
180
+ const percent = delta === void 0 ? void 0 : `${delta > 0 ? "+" : ""}${String(Math.round(delta * 100))}%`;
181
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "tap-stat", children: [
182
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "tap-stat__label", children: label }),
183
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "tap-stat__value", children: value }),
184
+ percent !== void 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
185
+ "span",
186
+ {
187
+ className: cn(
188
+ delta !== void 0 && delta < 0 ? "tap-stat__delta--down" : "tap-stat__delta--up"
189
+ ),
190
+ children: percent
191
+ }
192
+ ),
193
+ hint !== void 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "tap-field__hint", children: hint })
194
+ ] });
195
+ }
196
+ function FieldFrame({
197
+ id,
198
+ label,
199
+ hint,
200
+ error,
201
+ hintId,
202
+ errorId,
203
+ children
204
+ }) {
205
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "tap-field", children: [
206
+ label !== void 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "label", { className: "tap-field__label", htmlFor: id, children: label }),
207
+ children,
208
+ hint !== void 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "tap-field__hint", id: hintId, children: hint }),
209
+ error !== void 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "tap-field__error", id: errorId, children: error })
210
+ ] });
211
+ }
212
+ function describedByOf(fieldId, hint, error) {
213
+ const value = cn(
214
+ hint !== void 0 && `${fieldId}-hint`,
215
+ error !== void 0 && `${fieldId}-error`
216
+ );
217
+ return value === "" ? void 0 : value;
218
+ }
219
+ function TapSingleLineInput({
220
+ label,
221
+ error,
222
+ hint,
223
+ className,
224
+ id,
225
+ ...rest
226
+ }) {
227
+ const generated = _react.useId.call(void 0, );
228
+ const fieldId = _nullishCoalesce(id, () => ( generated));
229
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
230
+ FieldFrame,
231
+ {
232
+ id: fieldId,
233
+ label,
234
+ hint,
235
+ error,
236
+ hintId: `${fieldId}-hint`,
237
+ errorId: `${fieldId}-error`,
238
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
239
+ "input",
240
+ {
241
+ ...rest,
242
+ id: fieldId,
243
+ className: cn(
244
+ "tap-control",
245
+ error !== void 0 && "tap-control--invalid",
246
+ className
247
+ ),
248
+ "aria-invalid": error !== void 0 || void 0,
249
+ "aria-describedby": describedByOf(fieldId, hint, error)
250
+ }
251
+ )
252
+ }
253
+ );
254
+ }
255
+ function TapTextarea({
256
+ label,
257
+ error,
258
+ hint,
259
+ className,
260
+ id,
261
+ rows,
262
+ ...rest
263
+ }) {
264
+ const generated = _react.useId.call(void 0, );
265
+ const fieldId = _nullishCoalesce(id, () => ( generated));
266
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
267
+ FieldFrame,
268
+ {
269
+ id: fieldId,
270
+ label,
271
+ hint,
272
+ error,
273
+ hintId: `${fieldId}-hint`,
274
+ errorId: `${fieldId}-error`,
275
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
276
+ "textarea",
277
+ {
278
+ ...rest,
279
+ id: fieldId,
280
+ rows: _nullishCoalesce(rows, () => ( 4)),
281
+ className: cn(
282
+ "tap-control",
283
+ error !== void 0 && "tap-control--invalid",
284
+ className
285
+ ),
286
+ "aria-invalid": error !== void 0 || void 0,
287
+ "aria-describedby": describedByOf(fieldId, hint, error)
288
+ }
289
+ )
290
+ }
291
+ );
292
+ }
293
+ function TapInput(props) {
294
+ if (props.multiline === true) {
295
+ const { multiline: _multiline2, ...rest2 } = props;
296
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TapTextarea, { ...rest2 });
297
+ }
298
+ const { multiline: _multiline, ...rest } = props;
299
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TapSingleLineInput, { ...rest });
300
+ }
301
+ function TapSelect({
302
+ label,
303
+ error,
304
+ hint,
305
+ options,
306
+ className,
307
+ id,
308
+ ...rest
309
+ }) {
310
+ const generated = _react.useId.call(void 0, );
311
+ const fieldId = _nullishCoalesce(id, () => ( generated));
312
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
313
+ FieldFrame,
314
+ {
315
+ id: fieldId,
316
+ label,
317
+ hint,
318
+ error,
319
+ hintId: `${fieldId}-hint`,
320
+ errorId: `${fieldId}-error`,
321
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
322
+ "select",
323
+ {
324
+ ...rest,
325
+ id: fieldId,
326
+ className: cn(
327
+ "tap-control",
328
+ error !== void 0 && "tap-control--invalid",
329
+ className
330
+ ),
331
+ "aria-invalid": error !== void 0 || void 0,
332
+ "aria-describedby": describedByOf(fieldId, hint, error),
333
+ children: options.map((option) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "option", { value: option.value, children: option.label }, option.value))
334
+ }
335
+ )
336
+ }
337
+ );
338
+ }
339
+ function cellText(row, key) {
340
+ if (row === null || typeof row !== "object") return "";
341
+ const value = Reflect.get(row, key);
342
+ if (typeof value === "string") return value;
343
+ if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
344
+ return String(value);
345
+ }
346
+ return "";
347
+ }
348
+ function TapTable({
349
+ columns,
350
+ rows,
351
+ rowKey,
352
+ empty,
353
+ onRowClick
354
+ }) {
355
+ if (rows.length === 0 && empty !== void 0) {
356
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _jsxruntime.Fragment, { children: empty });
357
+ }
358
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "tap-table-wrap", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "table", { className: "tap-table", children: [
359
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "thead", { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "tr", { children: columns.map((column) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
360
+ "th",
361
+ {
362
+ className: cn(column.align === "end" && "tap-table__end"),
363
+ scope: "col",
364
+ children: column.label
365
+ },
366
+ column.key
367
+ )) }) }),
368
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "tbody", { children: rows.map((row) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
369
+ "tr",
370
+ {
371
+ "data-clickable": onRowClick !== void 0,
372
+ tabIndex: onRowClick === void 0 ? void 0 : 0,
373
+ onClick: onRowClick === void 0 ? void 0 : () => onRowClick(row),
374
+ onKeyDown: onRowClick === void 0 ? void 0 : (event) => {
375
+ if (event.key !== "Enter" && event.key !== " ") return;
376
+ event.preventDefault();
377
+ onRowClick(row);
378
+ },
379
+ children: columns.map((column) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
380
+ "td",
381
+ {
382
+ className: cn(column.align === "end" && "tap-table__end"),
383
+ children: column.render ? column.render(row) : cellText(row, column.key)
384
+ },
385
+ column.key
386
+ ))
387
+ },
388
+ rowKey(row)
389
+ )) })
390
+ ] }) });
391
+ }
392
+
393
+ // src/client/ui/TapDialog.tsx
394
+
395
+
396
+
397
+
398
+
399
+
400
+ var _reactdom = require('react-dom');
401
+
402
+ var DIALOG_CLOSE_EVENT = "tap:dialog-close";
403
+ var FOCUSABLE = 'a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])';
404
+ function activeElementNear(node) {
405
+ const root = _optionalChain([node, 'optionalAccess', _2 => _2.getRootNode, 'call', _3 => _3()]);
406
+ return root instanceof ShadowRoot ? root.activeElement : document.activeElement;
407
+ }
408
+ function TapDialog({
409
+ open,
410
+ title,
411
+ onClose,
412
+ footer,
413
+ children,
414
+ labelledBy
415
+ }) {
416
+ const tap = _chunkOPPYEA7Fcjs.useTap.call(void 0, );
417
+ const dialogRef = _react.useRef.call(void 0, null);
418
+ const titleId = _react.useId.call(void 0, );
419
+ const focusables = _react.useCallback.call(void 0, () => {
420
+ const root = dialogRef.current;
421
+ if (root === null) return [];
422
+ return Array.from(root.querySelectorAll(FOCUSABLE));
423
+ }, []);
424
+ _react.useEffect.call(void 0, () => {
425
+ if (!open) return;
426
+ const previous = activeElementNear(dialogRef.current);
427
+ _optionalChain([focusables, 'call', _4 => _4(), 'access', _5 => _5[0], 'optionalAccess', _6 => _6.focus, 'call', _7 => _7()]);
428
+ return () => {
429
+ if (previous instanceof HTMLElement) previous.focus();
430
+ };
431
+ }, [open, focusables]);
432
+ _react.useEffect.call(void 0, () => {
433
+ const portal = tap.__portal;
434
+ if (!open || portal === null) return;
435
+ const close = () => {
436
+ onClose();
437
+ };
438
+ portal.addEventListener(DIALOG_CLOSE_EVENT, close);
439
+ return () => {
440
+ portal.removeEventListener(DIALOG_CLOSE_EVENT, close);
441
+ };
442
+ }, [open, tap, onClose]);
443
+ if (!open) return null;
444
+ if (tap.__portal === null) {
445
+ throw new (0, _chunk2DBSVKAUcjs.TapError)(
446
+ "TAP_NO_PORTAL",
447
+ "TapDialog needs the host portal node, which the mount sets inside its shadow root. Render this dialog from a contribution entry, or use renderWithTap() in tests."
448
+ );
449
+ }
450
+ const onKeyDown = (event) => {
451
+ if (event.key === "Escape") {
452
+ event.stopPropagation();
453
+ event.preventDefault();
454
+ onClose();
455
+ return;
456
+ }
457
+ if (event.key !== "Tab") return;
458
+ const items = focusables();
459
+ if (items.length === 0) return;
460
+ const first = items[0];
461
+ const last = items[items.length - 1];
462
+ const active = activeElementNear(dialogRef.current);
463
+ if (event.shiftKey && active === first) {
464
+ event.preventDefault();
465
+ last.focus();
466
+ return;
467
+ }
468
+ if (!event.shiftKey && active === last) {
469
+ event.preventDefault();
470
+ first.focus();
471
+ }
472
+ };
473
+ return _reactdom.createPortal.call(void 0,
474
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
475
+ "div",
476
+ {
477
+ className: "tap-dialog-scrim",
478
+ onKeyDown,
479
+ onMouseDown: (event) => {
480
+ if (event.target === event.currentTarget) onClose();
481
+ },
482
+ children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
483
+ "div",
484
+ {
485
+ ref: dialogRef,
486
+ className: "tap-dialog",
487
+ role: "dialog",
488
+ "aria-modal": "true",
489
+ "aria-labelledby": _nullishCoalesce(labelledBy, () => ( titleId)),
490
+ children: [
491
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "header", { className: "tap-dialog__head", id: titleId, children: title }),
492
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "tap-dialog__body", children }),
493
+ footer !== void 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "footer", { className: "tap-dialog__foot", children: footer })
494
+ ]
495
+ }
496
+ )
497
+ }
498
+ ),
499
+ tap.__portal
500
+ );
501
+ }
502
+
503
+ // src/client/ui/TapForm.tsx
504
+
505
+
506
+
507
+
508
+ var _zod = require('zod');
509
+
510
+ function humanise(name) {
511
+ const spaced = name.replace(/[_-]+/g, " ").replace(/([a-z0-9])([A-Z])/g, "$1 $2").trim();
512
+ return spaced.charAt(0).toUpperCase() + spaced.slice(1);
513
+ }
514
+ function readString(source, key) {
515
+ const value = source[key];
516
+ return typeof value === "string" ? value : void 0;
517
+ }
518
+ function kindOf(property) {
519
+ if (Array.isArray(property.enum)) return "enum";
520
+ const type = readString(property, "type");
521
+ if (type === "boolean") return "boolean";
522
+ if (type === "number" || type === "integer") return "number";
523
+ const format = readString(property, "format");
524
+ if (format === "textarea") return "textarea";
525
+ if (format === "date") return "date";
526
+ return "text";
527
+ }
528
+ function formFields(schema) {
529
+ const properties = schema.properties;
530
+ if (typeof properties !== "object" || properties === null) return [];
531
+ const required = new Set(
532
+ Array.isArray(schema.required) ? schema.required.filter(
533
+ (name) => typeof name === "string"
534
+ ) : []
535
+ );
536
+ return Object.entries(properties).flatMap(([name, raw]) => {
537
+ if (typeof raw !== "object" || raw === null) return [];
538
+ const property = { ...raw };
539
+ const kind = kindOf(property);
540
+ const field = {
541
+ name,
542
+ label: _nullishCoalesce(readString(property, "title"), () => ( humanise(name))),
543
+ kind,
544
+ required: required.has(name)
545
+ };
546
+ const hint = readString(property, "description");
547
+ if (hint !== void 0) field.hint = hint;
548
+ if (kind === "enum" && Array.isArray(property.enum)) {
549
+ field.options = property.enum.filter((option) => typeof option === "string").map((option) => ({ value: option, label: option }));
550
+ }
551
+ return [field];
552
+ });
553
+ }
554
+ function requiredErrors(fields, values) {
555
+ const errors = {};
556
+ for (const field of fields) {
557
+ const value = values[field.name];
558
+ if (field.required && (value === void 0 || value === "")) {
559
+ errors[field.name] = `${field.label} is required.`;
560
+ }
561
+ }
562
+ return errors;
563
+ }
564
+ function compile(schema) {
565
+ try {
566
+ return _zod.z.fromJSONSchema(schema);
567
+ } catch (e) {
568
+ return null;
569
+ }
570
+ }
571
+ function validate(fields, compiled, values) {
572
+ const errors = requiredErrors(fields, values);
573
+ if (compiled === null) return errors;
574
+ const result = compiled.safeParse(values);
575
+ if (result.success) return errors;
576
+ for (const issue of result.error.issues) {
577
+ const key = issue.path[0];
578
+ if (typeof key === "string" && errors[key] === void 0) {
579
+ errors[key] = issue.message;
580
+ }
581
+ }
582
+ return errors;
583
+ }
584
+ function clean(fields, values) {
585
+ const output = {};
586
+ for (const field of fields) {
587
+ const value = values[field.name];
588
+ if (value === void 0 || value === "") continue;
589
+ output[field.name] = value;
590
+ }
591
+ return output;
592
+ }
593
+ function TapForm({
594
+ schema,
595
+ value,
596
+ submitLabel = "Submit",
597
+ cancelLabel = "Cancel",
598
+ busy = false,
599
+ onSubmit,
600
+ onCancel
601
+ }) {
602
+ const fields = _react.useMemo.call(void 0, () => formFields(schema), [schema]);
603
+ const compiled = _react.useMemo.call(void 0, () => compile(schema), [schema]);
604
+ const [values, setValues] = _react.useState.call(void 0, () => ({ ...value }));
605
+ const [errors, setErrors] = _react.useState.call(void 0, {});
606
+ const set = (name, next) => {
607
+ setValues((current) => ({ ...current, [name]: next }));
608
+ setErrors((current) => {
609
+ if (current[name] === void 0) return current;
610
+ const { [name]: _cleared, ...rest } = current;
611
+ return rest;
612
+ });
613
+ };
614
+ const submit = (event) => {
615
+ event.preventDefault();
616
+ const candidate = clean(fields, values);
617
+ const found = validate(fields, compiled, candidate);
618
+ setErrors(found);
619
+ if (Object.keys(found).length > 0) return;
620
+ void onSubmit(candidate);
621
+ };
622
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "form", { className: "tap-form", onSubmit: submit, noValidate: true, children: [
623
+ fields.map((field) => {
624
+ const raw = values[field.name];
625
+ if (field.kind === "enum") {
626
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
627
+ TapSelect,
628
+ {
629
+ label: field.label,
630
+ hint: field.hint,
631
+ error: errors[field.name],
632
+ required: field.required,
633
+ value: typeof raw === "string" ? raw : "",
634
+ options: [
635
+ { value: "", label: "Choose one" },
636
+ ..._nullishCoalesce(field.options, () => ( []))
637
+ ],
638
+ onChange: (event) => {
639
+ set(field.name, event.target.value);
640
+ }
641
+ },
642
+ field.name
643
+ );
644
+ }
645
+ if (field.kind === "boolean") {
646
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
647
+ TapInput,
648
+ {
649
+ type: "checkbox",
650
+ label: field.label,
651
+ hint: field.hint,
652
+ error: errors[field.name],
653
+ className: "tap-control--checkbox",
654
+ checked: raw === true,
655
+ onChange: (event) => {
656
+ set(field.name, event.target.checked);
657
+ }
658
+ },
659
+ field.name
660
+ );
661
+ }
662
+ if (field.kind === "textarea") {
663
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
664
+ TapInput,
665
+ {
666
+ multiline: true,
667
+ label: field.label,
668
+ hint: field.hint,
669
+ error: errors[field.name],
670
+ required: field.required,
671
+ value: typeof raw === "string" ? raw : "",
672
+ onChange: (event) => {
673
+ set(field.name, event.target.value);
674
+ }
675
+ },
676
+ field.name
677
+ );
678
+ }
679
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
680
+ TapInput,
681
+ {
682
+ type: field.kind === "number" ? "number" : field.kind === "date" ? "date" : "text",
683
+ label: field.label,
684
+ hint: field.hint,
685
+ error: errors[field.name],
686
+ required: field.required,
687
+ value: typeof raw === "string" || typeof raw === "number" ? String(raw) : "",
688
+ onChange: (event) => {
689
+ set(
690
+ field.name,
691
+ field.kind === "number" ? event.target.value === "" ? "" : Number(event.target.value) : event.target.value
692
+ );
693
+ }
694
+ },
695
+ field.name
696
+ );
697
+ }),
698
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "tap-form__actions", children: [
699
+ onCancel !== void 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TapButton, { variant: "secondary", onClick: onCancel, children: cancelLabel }),
700
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TapButton, { type: "submit", loading: busy, children: submitLabel })
701
+ ] })
702
+ ] });
703
+ }
704
+
705
+
706
+
707
+
708
+
709
+
710
+
711
+
712
+
713
+
714
+
715
+
716
+
717
+
718
+
719
+
720
+
721
+ exports.cn = cn; exports.TapButton = TapButton; exports.TapCard = TapCard; exports.TapPageHeader = TapPageHeader; exports.TapSkeleton = TapSkeleton; exports.TapEmptyState = TapEmptyState; exports.TapErrorState = TapErrorState; exports.TapStat = TapStat; exports.TapInput = TapInput; exports.TapSelect = TapSelect; exports.TapTable = TapTable; exports.TapDialog = TapDialog; exports.formFields = formFields; exports.TapForm = TapForm; exports.src_exports = src_exports;
722
+ //# sourceMappingURL=chunk-EW54H7CR.cjs.map