@apotech-os/ui-sdk 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +371 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +135 -0
- package/dist/index.d.ts +135 -0
- package/dist/index.js +323 -0
- package/dist/index.js.map +1 -0
- package/package.json +52 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var clsx = require('clsx');
|
|
4
|
+
var tailwindMerge = require('tailwind-merge');
|
|
5
|
+
var React = require('react');
|
|
6
|
+
var classVarianceAuthority = require('class-variance-authority');
|
|
7
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
8
|
+
|
|
9
|
+
function _interopNamespace(e) {
|
|
10
|
+
if (e && e.__esModule) return e;
|
|
11
|
+
var n = Object.create(null);
|
|
12
|
+
if (e) {
|
|
13
|
+
Object.keys(e).forEach(function (k) {
|
|
14
|
+
if (k !== 'default') {
|
|
15
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
16
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
17
|
+
enumerable: true,
|
|
18
|
+
get: function () { return e[k]; }
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
n.default = e;
|
|
24
|
+
return Object.freeze(n);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
28
|
+
|
|
29
|
+
// src/cn.ts
|
|
30
|
+
function cn(...inputs) {
|
|
31
|
+
return tailwindMerge.twMerge(clsx.clsx(inputs));
|
|
32
|
+
}
|
|
33
|
+
var AppContextInternalCtx = React.createContext(null);
|
|
34
|
+
var AppContextProvider = AppContextInternalCtx.Provider;
|
|
35
|
+
function useAppContext() {
|
|
36
|
+
const ctx = React.useContext(AppContextInternalCtx);
|
|
37
|
+
if (!ctx) throw new Error("useAppContext must be used inside an app page mounted by the shell");
|
|
38
|
+
return ctx;
|
|
39
|
+
}
|
|
40
|
+
var AppApiCtx = React.createContext(null);
|
|
41
|
+
var AppApiProvider = AppApiCtx.Provider;
|
|
42
|
+
function useAppApi() {
|
|
43
|
+
const client = React.useContext(AppApiCtx);
|
|
44
|
+
if (!client) throw new Error("useAppApi must be used inside an app page mounted by the shell");
|
|
45
|
+
return client;
|
|
46
|
+
}
|
|
47
|
+
var buttonVariants = classVarianceAuthority.cva(
|
|
48
|
+
"inline-flex cursor-pointer items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50",
|
|
49
|
+
{
|
|
50
|
+
variants: {
|
|
51
|
+
variant: {
|
|
52
|
+
default: "bg-primary text-primary-foreground hover:bg-primary/90",
|
|
53
|
+
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
54
|
+
outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
|
|
55
|
+
ghost: "hover:bg-accent hover:text-accent-foreground",
|
|
56
|
+
destructive: "bg-destructive text-white hover:bg-destructive/90"
|
|
57
|
+
},
|
|
58
|
+
size: {
|
|
59
|
+
default: "h-9 px-4 py-2",
|
|
60
|
+
sm: "h-8 rounded-md px-3 text-xs",
|
|
61
|
+
lg: "h-10 rounded-md px-6",
|
|
62
|
+
icon: "h-9 w-9"
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
defaultVariants: { variant: "default", size: "default" }
|
|
66
|
+
}
|
|
67
|
+
);
|
|
68
|
+
var Button = React__namespace.forwardRef(
|
|
69
|
+
({ className, variant, size, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("button", { ref, className: cn(buttonVariants({ variant, size, className })), ...props })
|
|
70
|
+
);
|
|
71
|
+
Button.displayName = "Button";
|
|
72
|
+
var badgeVariants = classVarianceAuthority.cva(
|
|
73
|
+
"inline-flex items-center gap-1.5 rounded-full border px-2 py-0.5 text-xs font-medium whitespace-nowrap",
|
|
74
|
+
{
|
|
75
|
+
variants: {
|
|
76
|
+
variant: {
|
|
77
|
+
neutral: "border-border bg-muted text-muted-foreground",
|
|
78
|
+
brand: "border-primary/20 bg-primary/10 text-primary",
|
|
79
|
+
success: "border-status-success/25 bg-status-success/10 text-status-success",
|
|
80
|
+
warning: "border-status-pending/30 bg-status-pending/10 text-status-pending",
|
|
81
|
+
danger: "border-status-blocked/25 bg-status-blocked/10 text-status-blocked",
|
|
82
|
+
info: "border-status-info/25 bg-status-info/10 text-status-info",
|
|
83
|
+
outline: "border-border bg-transparent text-muted-foreground"
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
defaultVariants: { variant: "neutral" }
|
|
87
|
+
}
|
|
88
|
+
);
|
|
89
|
+
function Badge({ className, variant, dot, children, ...props }) {
|
|
90
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn(badgeVariants({ variant }), className), ...props, children: [
|
|
91
|
+
dot && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "size-1.5 rounded-full bg-current" }),
|
|
92
|
+
children
|
|
93
|
+
] });
|
|
94
|
+
}
|
|
95
|
+
function Card({ className, ...props }) {
|
|
96
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
97
|
+
"div",
|
|
98
|
+
{
|
|
99
|
+
className: cn("rounded-xl border bg-card text-card-foreground shadow-sm", className),
|
|
100
|
+
...props
|
|
101
|
+
}
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
function CardHeader({ className, ...props }) {
|
|
105
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex flex-col space-y-1.5 p-6", className), ...props });
|
|
106
|
+
}
|
|
107
|
+
function CardTitle({ className, ...props }) {
|
|
108
|
+
return /* @__PURE__ */ jsxRuntime.jsx("h3", { className: cn("text-lg font-semibold leading-none tracking-tight", className), ...props });
|
|
109
|
+
}
|
|
110
|
+
function CardContent({ className, ...props }) {
|
|
111
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("p-6 pt-0", className), ...props });
|
|
112
|
+
}
|
|
113
|
+
var Input = React__namespace.forwardRef(
|
|
114
|
+
({ className, type, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
115
|
+
"input",
|
|
116
|
+
{
|
|
117
|
+
type,
|
|
118
|
+
className: cn(
|
|
119
|
+
"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
|
|
120
|
+
className
|
|
121
|
+
),
|
|
122
|
+
ref,
|
|
123
|
+
...props
|
|
124
|
+
}
|
|
125
|
+
)
|
|
126
|
+
);
|
|
127
|
+
Input.displayName = "Input";
|
|
128
|
+
function Table({ className, ...props }) {
|
|
129
|
+
return /* @__PURE__ */ jsxRuntime.jsx("table", { className: cn("w-full text-sm", className), ...props });
|
|
130
|
+
}
|
|
131
|
+
function TableHeader({ className, ...props }) {
|
|
132
|
+
return /* @__PURE__ */ jsxRuntime.jsx("thead", { className: cn("[&_tr]:border-b", className), ...props });
|
|
133
|
+
}
|
|
134
|
+
function TableBody({ className, ...props }) {
|
|
135
|
+
return /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: cn("[&_tr:last-child]:border-0", className), ...props });
|
|
136
|
+
}
|
|
137
|
+
function TableRow({ className, ...props }) {
|
|
138
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
139
|
+
"tr",
|
|
140
|
+
{
|
|
141
|
+
className: cn("border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted", className),
|
|
142
|
+
...props
|
|
143
|
+
}
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
function TableHead({ className, ...props }) {
|
|
147
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
148
|
+
"th",
|
|
149
|
+
{
|
|
150
|
+
className: cn("h-10 px-4 text-left align-middle text-xs font-medium text-muted-foreground", className),
|
|
151
|
+
...props
|
|
152
|
+
}
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
function TableCell({ className, ...props }) {
|
|
156
|
+
return /* @__PURE__ */ jsxRuntime.jsx("td", { className: cn("p-4 align-middle", className), ...props });
|
|
157
|
+
}
|
|
158
|
+
var Select = React__namespace.forwardRef(
|
|
159
|
+
({ className, children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
160
|
+
"select",
|
|
161
|
+
{
|
|
162
|
+
ref,
|
|
163
|
+
className: cn(
|
|
164
|
+
"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
|
|
165
|
+
className
|
|
166
|
+
),
|
|
167
|
+
...props,
|
|
168
|
+
children
|
|
169
|
+
}
|
|
170
|
+
)
|
|
171
|
+
);
|
|
172
|
+
Select.displayName = "Select";
|
|
173
|
+
var TabsContext = React__namespace.createContext(null);
|
|
174
|
+
function useTabsContext() {
|
|
175
|
+
const ctx = React__namespace.useContext(TabsContext);
|
|
176
|
+
if (!ctx) throw new Error("Tabs sub-component must be used within <Tabs>");
|
|
177
|
+
return ctx;
|
|
178
|
+
}
|
|
179
|
+
function Tabs({ defaultValue, value, onValueChange, className, children }) {
|
|
180
|
+
const [internal, setInternal] = React__namespace.useState(defaultValue ?? "");
|
|
181
|
+
const current = value ?? internal;
|
|
182
|
+
const setValue = (v) => {
|
|
183
|
+
setInternal(v);
|
|
184
|
+
onValueChange?.(v);
|
|
185
|
+
};
|
|
186
|
+
return /* @__PURE__ */ jsxRuntime.jsx(TabsContext.Provider, { value: { value: current, setValue }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className, children }) });
|
|
187
|
+
}
|
|
188
|
+
function TabsList({ className, children }) {
|
|
189
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("inline-flex items-center gap-1 rounded-lg bg-muted p-1", className), children });
|
|
190
|
+
}
|
|
191
|
+
function TabsTrigger({
|
|
192
|
+
value,
|
|
193
|
+
className,
|
|
194
|
+
children
|
|
195
|
+
}) {
|
|
196
|
+
const { value: current, setValue } = useTabsContext();
|
|
197
|
+
const active = current === value;
|
|
198
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
199
|
+
"button",
|
|
200
|
+
{
|
|
201
|
+
type: "button",
|
|
202
|
+
onClick: () => setValue(value),
|
|
203
|
+
className: cn(
|
|
204
|
+
"rounded-md px-3 py-1.5 text-sm font-medium transition-colors",
|
|
205
|
+
active ? "bg-card text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground",
|
|
206
|
+
className
|
|
207
|
+
),
|
|
208
|
+
children
|
|
209
|
+
}
|
|
210
|
+
);
|
|
211
|
+
}
|
|
212
|
+
function TabsContent({
|
|
213
|
+
value,
|
|
214
|
+
className,
|
|
215
|
+
children
|
|
216
|
+
}) {
|
|
217
|
+
const { value: current } = useTabsContext();
|
|
218
|
+
if (current !== value) return null;
|
|
219
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className, children });
|
|
220
|
+
}
|
|
221
|
+
function Modal({ open, onClose, title, children, className }) {
|
|
222
|
+
if (!open) return null;
|
|
223
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "fixed inset-0 z-50 flex items-center justify-center p-4", children: [
|
|
224
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
225
|
+
"button",
|
|
226
|
+
{
|
|
227
|
+
type: "button",
|
|
228
|
+
"aria-label": "Close",
|
|
229
|
+
className: "absolute inset-0 cursor-default bg-foreground/40",
|
|
230
|
+
onClick: onClose
|
|
231
|
+
}
|
|
232
|
+
),
|
|
233
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
234
|
+
"div",
|
|
235
|
+
{
|
|
236
|
+
role: "dialog",
|
|
237
|
+
"aria-modal": true,
|
|
238
|
+
className: cn("relative z-10 w-full max-w-md rounded-xl border bg-card p-5 shadow-lg", className),
|
|
239
|
+
children: [
|
|
240
|
+
title && /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "mb-3 text-base font-semibold", children: title }),
|
|
241
|
+
children
|
|
242
|
+
]
|
|
243
|
+
}
|
|
244
|
+
)
|
|
245
|
+
] });
|
|
246
|
+
}
|
|
247
|
+
var spinnerSizes = { sm: "size-4", md: "size-6", lg: "size-8" };
|
|
248
|
+
function Spinner({ className, size = "md" }) {
|
|
249
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
250
|
+
"svg",
|
|
251
|
+
{
|
|
252
|
+
className: cn("animate-spin text-muted-foreground", spinnerSizes[size], className),
|
|
253
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
254
|
+
fill: "none",
|
|
255
|
+
viewBox: "0 0 24 24",
|
|
256
|
+
"aria-label": "Loading",
|
|
257
|
+
role: "status",
|
|
258
|
+
children: [
|
|
259
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
|
|
260
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
261
|
+
"path",
|
|
262
|
+
{
|
|
263
|
+
className: "opacity-75",
|
|
264
|
+
fill: "currentColor",
|
|
265
|
+
d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
|
|
266
|
+
}
|
|
267
|
+
)
|
|
268
|
+
]
|
|
269
|
+
}
|
|
270
|
+
);
|
|
271
|
+
}
|
|
272
|
+
var Link = React__namespace.forwardRef(
|
|
273
|
+
({ className, variant = "default", ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
274
|
+
"a",
|
|
275
|
+
{
|
|
276
|
+
ref,
|
|
277
|
+
className: cn(
|
|
278
|
+
"underline-offset-4 hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
279
|
+
variant === "default" ? "text-primary" : "text-muted-foreground",
|
|
280
|
+
className
|
|
281
|
+
),
|
|
282
|
+
...props
|
|
283
|
+
}
|
|
284
|
+
)
|
|
285
|
+
);
|
|
286
|
+
Link.displayName = "Link";
|
|
287
|
+
function Switch({ checked = false, onCheckedChange, disabled, className, ...props }) {
|
|
288
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
289
|
+
"button",
|
|
290
|
+
{
|
|
291
|
+
type: "button",
|
|
292
|
+
role: "switch",
|
|
293
|
+
"aria-checked": checked,
|
|
294
|
+
disabled,
|
|
295
|
+
onClick: () => onCheckedChange?.(!checked),
|
|
296
|
+
className: cn(
|
|
297
|
+
"relative inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
|
|
298
|
+
checked ? "bg-primary" : "bg-input",
|
|
299
|
+
className
|
|
300
|
+
),
|
|
301
|
+
...props,
|
|
302
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
303
|
+
"span",
|
|
304
|
+
{
|
|
305
|
+
className: cn(
|
|
306
|
+
"inline-block size-4 transform rounded-full bg-white shadow transition-transform",
|
|
307
|
+
checked ? "translate-x-4" : "translate-x-0.5"
|
|
308
|
+
)
|
|
309
|
+
}
|
|
310
|
+
)
|
|
311
|
+
}
|
|
312
|
+
);
|
|
313
|
+
}
|
|
314
|
+
function DateRangePicker({ value, onChange, className, disabled }) {
|
|
315
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex items-center gap-2", className), children: [
|
|
316
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
317
|
+
"input",
|
|
318
|
+
{
|
|
319
|
+
type: "date",
|
|
320
|
+
disabled,
|
|
321
|
+
value: value.from,
|
|
322
|
+
max: value.to || void 0,
|
|
323
|
+
onChange: (e) => onChange({ ...value, from: e.target.value }),
|
|
324
|
+
className: "flex h-9 rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50"
|
|
325
|
+
}
|
|
326
|
+
),
|
|
327
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground text-sm", children: "\u2192" }),
|
|
328
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
329
|
+
"input",
|
|
330
|
+
{
|
|
331
|
+
type: "date",
|
|
332
|
+
disabled,
|
|
333
|
+
value: value.to,
|
|
334
|
+
min: value.from || void 0,
|
|
335
|
+
onChange: (e) => onChange({ ...value, to: e.target.value }),
|
|
336
|
+
className: "flex h-9 rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50"
|
|
337
|
+
}
|
|
338
|
+
)
|
|
339
|
+
] });
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
exports.AppApiProvider = AppApiProvider;
|
|
343
|
+
exports.AppContextProvider = AppContextProvider;
|
|
344
|
+
exports.Badge = Badge;
|
|
345
|
+
exports.Button = Button;
|
|
346
|
+
exports.Card = Card;
|
|
347
|
+
exports.CardContent = CardContent;
|
|
348
|
+
exports.CardHeader = CardHeader;
|
|
349
|
+
exports.CardTitle = CardTitle;
|
|
350
|
+
exports.DateRangePicker = DateRangePicker;
|
|
351
|
+
exports.Input = Input;
|
|
352
|
+
exports.Link = Link;
|
|
353
|
+
exports.Modal = Modal;
|
|
354
|
+
exports.Select = Select;
|
|
355
|
+
exports.Spinner = Spinner;
|
|
356
|
+
exports.Switch = Switch;
|
|
357
|
+
exports.Table = Table;
|
|
358
|
+
exports.TableBody = TableBody;
|
|
359
|
+
exports.TableCell = TableCell;
|
|
360
|
+
exports.TableHead = TableHead;
|
|
361
|
+
exports.TableHeader = TableHeader;
|
|
362
|
+
exports.TableRow = TableRow;
|
|
363
|
+
exports.Tabs = Tabs;
|
|
364
|
+
exports.TabsContent = TabsContent;
|
|
365
|
+
exports.TabsList = TabsList;
|
|
366
|
+
exports.TabsTrigger = TabsTrigger;
|
|
367
|
+
exports.cn = cn;
|
|
368
|
+
exports.useAppApi = useAppApi;
|
|
369
|
+
exports.useAppContext = useAppContext;
|
|
370
|
+
//# sourceMappingURL=index.cjs.map
|
|
371
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cn.ts","../src/hooks.ts","../src/components.tsx"],"names":["twMerge","clsx","createContext","useContext","cva","React","jsx","jsxs"],"mappings":"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","file":"index.cjs","sourcesContent":["import { type ClassValue, clsx } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n","/**\n * Runtime hooks provided by the shell via @apotech-os/ui-sdk.\n *\n * These hooks are implemented by the shell and injected at runtime via the\n * import map. App pages call them without knowing the shell internals.\n *\n * The default implementations throw if called outside of the shell context\n * (which should never happen in production — the shell always provides them\n * via the import map before mounting an app page).\n */\n\nimport { useContext, createContext } from 'react';\n\n// ---------------------------------------------------------------------------\n// AppContext\n// ---------------------------------------------------------------------------\n\nexport interface AppContextValue {\n /** The slug of the installed app owning this page. */\n appSlug: string;\n /** The page path within the app (e.g. 'attribution'). */\n pagePath: string;\n /** The active space id, when applicable. */\n spaceId?: string;\n}\n\nconst AppContextInternalCtx = createContext<AppContextValue | null>(null);\n\nexport const AppContextProvider = AppContextInternalCtx.Provider;\n\n/** Returns context info for the current app page (appSlug, pagePath, spaceId). */\nexport function useAppContext(): AppContextValue {\n const ctx = useContext(AppContextInternalCtx);\n if (!ctx) throw new Error('useAppContext must be used inside an app page mounted by the shell');\n return ctx;\n}\n\n// ---------------------------------------------------------------------------\n// AppApi\n// ---------------------------------------------------------------------------\n\nexport interface AppApiClient {\n /**\n * Perform a GET request to a platform-data endpoint.\n * The session cookie is forwarded automatically (same-origin, withCredentials).\n */\n get<T>(path: string, params?: Record<string, string>): Promise<T>;\n /**\n * Perform a POST request to a platform-data endpoint.\n */\n post<T>(path: string, body?: unknown): Promise<T>;\n}\n\nconst AppApiCtx = createContext<AppApiClient | null>(null);\n\nexport const AppApiProvider = AppApiCtx.Provider;\n\n/**\n * Returns an API client scoped to the current user session.\n * Requests go to /api/data/* with the session cookie (RBAC applies server-side).\n */\nexport function useAppApi(): AppApiClient {\n const client = useContext(AppApiCtx);\n if (!client) throw new Error('useAppApi must be used inside an app page mounted by the shell');\n return client;\n}\n","/**\n * Design system components exported by @apotech-os/ui-sdk.\n *\n * These are minimal self-contained copies of the shell's component library.\n * They use the same Tailwind utility classes as the shell — Tailwind classes\n * are plain strings and work without any build step when the shell's stylesheet\n * is loaded (which it is, since these pages run inside the shell).\n *\n * Strategy note:\n * - Not imported from apps/web (would create a circular dep pkg → app).\n * - Copied/adapted here to keep the SDK self-contained and publishable.\n * - The exhaustive component inventory is tracked in #75.\n */\n\nimport { type VariantProps, cva } from 'class-variance-authority';\nimport * as React from 'react';\nimport { cn } from './cn';\n\n// ---------------------------------------------------------------------------\n// Button\n// ---------------------------------------------------------------------------\n\nconst buttonVariants = cva(\n 'inline-flex cursor-pointer items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50',\n {\n variants: {\n variant: {\n default: 'bg-primary text-primary-foreground hover:bg-primary/90',\n secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',\n outline: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground',\n ghost: 'hover:bg-accent hover:text-accent-foreground',\n destructive: 'bg-destructive text-white hover:bg-destructive/90',\n },\n size: {\n default: 'h-9 px-4 py-2',\n sm: 'h-8 rounded-md px-3 text-xs',\n lg: 'h-10 rounded-md px-6',\n icon: 'h-9 w-9',\n },\n },\n defaultVariants: { variant: 'default', size: 'default' },\n },\n);\n\nexport interface ButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement>,\n VariantProps<typeof buttonVariants> {}\n\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant, size, ...props }, ref) => (\n <button ref={ref} className={cn(buttonVariants({ variant, size, className }))} {...props} />\n ),\n);\nButton.displayName = 'Button';\n\n// ---------------------------------------------------------------------------\n// Badge\n// ---------------------------------------------------------------------------\n\nconst badgeVariants = cva(\n 'inline-flex items-center gap-1.5 rounded-full border px-2 py-0.5 text-xs font-medium whitespace-nowrap',\n {\n variants: {\n variant: {\n neutral: 'border-border bg-muted text-muted-foreground',\n brand: 'border-primary/20 bg-primary/10 text-primary',\n success: 'border-status-success/25 bg-status-success/10 text-status-success',\n warning: 'border-status-pending/30 bg-status-pending/10 text-status-pending',\n danger: 'border-status-blocked/25 bg-status-blocked/10 text-status-blocked',\n info: 'border-status-info/25 bg-status-info/10 text-status-info',\n outline: 'border-border bg-transparent text-muted-foreground',\n },\n },\n defaultVariants: { variant: 'neutral' },\n },\n);\n\nexport interface BadgeProps\n extends React.HTMLAttributes<HTMLSpanElement>,\n VariantProps<typeof badgeVariants> {\n dot?: boolean;\n}\n\nexport function Badge({ className, variant, dot, children, ...props }: BadgeProps) {\n return (\n <span className={cn(badgeVariants({ variant }), className)} {...props}>\n {dot && <span className=\"size-1.5 rounded-full bg-current\" />}\n {children}\n </span>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Card\n// ---------------------------------------------------------------------------\n\nexport function Card({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {\n return (\n <div\n className={cn('rounded-xl border bg-card text-card-foreground shadow-sm', className)}\n {...props}\n />\n );\n}\n\nexport function CardHeader({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {\n return <div className={cn('flex flex-col space-y-1.5 p-6', className)} {...props} />;\n}\n\nexport function CardTitle({ className, ...props }: React.HTMLAttributes<HTMLHeadingElement>) {\n return <h3 className={cn('text-lg font-semibold leading-none tracking-tight', className)} {...props} />;\n}\n\nexport function CardContent({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {\n return <div className={cn('p-6 pt-0', className)} {...props} />;\n}\n\n// ---------------------------------------------------------------------------\n// Input\n// ---------------------------------------------------------------------------\n\nexport const Input = React.forwardRef<HTMLInputElement, React.InputHTMLAttributes<HTMLInputElement>>(\n ({ className, type, ...props }, ref) => (\n <input\n type={type}\n className={cn(\n 'flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50',\n className,\n )}\n ref={ref}\n {...props}\n />\n ),\n);\nInput.displayName = 'Input';\n\n// ---------------------------------------------------------------------------\n// Table\n// ---------------------------------------------------------------------------\n\nexport function Table({ className, ...props }: React.HTMLAttributes<HTMLTableElement>) {\n return <table className={cn('w-full text-sm', className)} {...props} />;\n}\n\nexport function TableHeader({ className, ...props }: React.HTMLAttributes<HTMLTableSectionElement>) {\n return <thead className={cn('[&_tr]:border-b', className)} {...props} />;\n}\n\nexport function TableBody({ className, ...props }: React.HTMLAttributes<HTMLTableSectionElement>) {\n return <tbody className={cn('[&_tr:last-child]:border-0', className)} {...props} />;\n}\n\nexport function TableRow({ className, ...props }: React.HTMLAttributes<HTMLTableRowElement>) {\n return (\n <tr\n className={cn('border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted', className)}\n {...props}\n />\n );\n}\n\nexport function TableHead({ className, ...props }: React.ThHTMLAttributes<HTMLTableCellElement>) {\n return (\n <th\n className={cn('h-10 px-4 text-left align-middle text-xs font-medium text-muted-foreground', className)}\n {...props}\n />\n );\n}\n\nexport function TableCell({ className, ...props }: React.TdHTMLAttributes<HTMLTableCellElement>) {\n return <td className={cn('p-4 align-middle', className)} {...props} />;\n}\n\n// ---------------------------------------------------------------------------\n// Select\n// ---------------------------------------------------------------------------\n\nexport interface SelectProps extends React.SelectHTMLAttributes<HTMLSelectElement> {}\n\nexport const Select = React.forwardRef<HTMLSelectElement, SelectProps>(\n ({ className, children, ...props }, ref) => (\n <select\n ref={ref}\n className={cn(\n 'flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50',\n className,\n )}\n {...props}\n >\n {children}\n </select>\n ),\n);\nSelect.displayName = 'Select';\n\n// ---------------------------------------------------------------------------\n// Tabs\n// ---------------------------------------------------------------------------\n\ninterface TabsContextValue {\n value: string;\n setValue: (v: string) => void;\n}\n\nconst TabsContext = React.createContext<TabsContextValue | null>(null);\n\nfunction useTabsContext(): TabsContextValue {\n const ctx = React.useContext(TabsContext);\n if (!ctx) throw new Error('Tabs sub-component must be used within <Tabs>');\n return ctx;\n}\n\nexport interface TabsProps {\n defaultValue?: string;\n value?: string;\n onValueChange?: (v: string) => void;\n className?: string;\n children: React.ReactNode;\n}\n\nexport function Tabs({ defaultValue, value, onValueChange, className, children }: TabsProps) {\n const [internal, setInternal] = React.useState(defaultValue ?? '');\n const current = value ?? internal;\n const setValue = (v: string) => {\n setInternal(v);\n onValueChange?.(v);\n };\n return (\n <TabsContext.Provider value={{ value: current, setValue }}>\n <div className={className}>{children}</div>\n </TabsContext.Provider>\n );\n}\n\nexport function TabsList({ className, children }: { className?: string; children: React.ReactNode }) {\n return (\n <div className={cn('inline-flex items-center gap-1 rounded-lg bg-muted p-1', className)}>\n {children}\n </div>\n );\n}\n\nexport function TabsTrigger({\n value,\n className,\n children,\n}: {\n value: string;\n className?: string;\n children: React.ReactNode;\n}) {\n const { value: current, setValue } = useTabsContext();\n const active = current === value;\n return (\n <button\n type=\"button\"\n onClick={() => setValue(value)}\n className={cn(\n 'rounded-md px-3 py-1.5 text-sm font-medium transition-colors',\n active ? 'bg-card text-foreground shadow-sm' : 'text-muted-foreground hover:text-foreground',\n className,\n )}\n >\n {children}\n </button>\n );\n}\n\nexport function TabsContent({\n value,\n className,\n children,\n}: {\n value: string;\n className?: string;\n children: React.ReactNode;\n}) {\n const { value: current } = useTabsContext();\n if (current !== value) return null;\n return <div className={className}>{children}</div>;\n}\n\n// ---------------------------------------------------------------------------\n// Modal (controlled, no Radix)\n// ---------------------------------------------------------------------------\n\nexport interface ModalProps {\n open: boolean;\n onClose: () => void;\n title?: React.ReactNode;\n children: React.ReactNode;\n className?: string;\n}\n\nexport function Modal({ open, onClose, title, children, className }: ModalProps) {\n if (!open) return null;\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center p-4\">\n <button\n type=\"button\"\n aria-label=\"Close\"\n className=\"absolute inset-0 cursor-default bg-foreground/40\"\n onClick={onClose}\n />\n <div\n role=\"dialog\"\n aria-modal\n className={cn('relative z-10 w-full max-w-md rounded-xl border bg-card p-5 shadow-lg', className)}\n >\n {title && <h2 className=\"mb-3 text-base font-semibold\">{title}</h2>}\n {children}\n </div>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Spinner\n// ---------------------------------------------------------------------------\n\nexport interface SpinnerProps {\n className?: string;\n size?: 'sm' | 'md' | 'lg';\n}\n\nconst spinnerSizes = { sm: 'size-4', md: 'size-6', lg: 'size-8' };\n\nexport function Spinner({ className, size = 'md' }: SpinnerProps) {\n return (\n <svg\n className={cn('animate-spin text-muted-foreground', spinnerSizes[size], className)}\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n aria-label=\"Loading\"\n role=\"status\"\n >\n <circle className=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" strokeWidth=\"4\" />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z\"\n />\n </svg>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Link\n// ---------------------------------------------------------------------------\n\nexport interface LinkProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {\n variant?: 'default' | 'muted';\n}\n\nexport const Link = React.forwardRef<HTMLAnchorElement, LinkProps>(\n ({ className, variant = 'default', ...props }, ref) => (\n <a\n ref={ref}\n className={cn(\n 'underline-offset-4 hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',\n variant === 'default' ? 'text-primary' : 'text-muted-foreground',\n className,\n )}\n {...props}\n />\n ),\n);\nLink.displayName = 'Link';\n\n// ---------------------------------------------------------------------------\n// Switch\n// ---------------------------------------------------------------------------\n\nexport interface SwitchProps {\n checked?: boolean;\n onCheckedChange?: (checked: boolean) => void;\n disabled?: boolean;\n className?: string;\n 'aria-label'?: string;\n}\n\nexport function Switch({ checked = false, onCheckedChange, disabled, className, ...props }: SwitchProps) {\n return (\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={checked}\n disabled={disabled}\n onClick={() => onCheckedChange?.(!checked)}\n className={cn(\n 'relative inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50',\n checked ? 'bg-primary' : 'bg-input',\n className,\n )}\n {...props}\n >\n <span\n className={cn(\n 'inline-block size-4 transform rounded-full bg-white shadow transition-transform',\n checked ? 'translate-x-4' : 'translate-x-0.5',\n )}\n />\n </button>\n );\n}\n\n// ---------------------------------------------------------------------------\n// DateRangePicker\n// ---------------------------------------------------------------------------\n\nexport interface DateRange {\n from: string;\n to: string;\n}\n\nexport interface DateRangePickerProps {\n value: DateRange;\n onChange: (range: DateRange) => void;\n className?: string;\n disabled?: boolean;\n}\n\n/** Minimal controlled date-range picker using two native date inputs. */\nexport function DateRangePicker({ value, onChange, className, disabled }: DateRangePickerProps) {\n return (\n <div className={cn('flex items-center gap-2', className)}>\n <input\n type=\"date\"\n disabled={disabled}\n value={value.from}\n max={value.to || undefined}\n onChange={(e) => onChange({ ...value, from: e.target.value })}\n className=\"flex h-9 rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50\"\n />\n <span className=\"text-muted-foreground text-sm\">→</span>\n <input\n type=\"date\"\n disabled={disabled}\n value={value.to}\n min={value.from || undefined}\n onChange={(e) => onChange({ ...value, to: e.target.value })}\n className=\"flex h-9 rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50\"\n />\n </div>\n );\n}\n"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { ClassValue } from 'clsx';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import * as class_variance_authority_types from 'class-variance-authority/types';
|
|
4
|
+
import { VariantProps } from 'class-variance-authority';
|
|
5
|
+
|
|
6
|
+
declare function cn(...inputs: ClassValue[]): string;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Runtime hooks provided by the shell via @apotech-os/ui-sdk.
|
|
10
|
+
*
|
|
11
|
+
* These hooks are implemented by the shell and injected at runtime via the
|
|
12
|
+
* import map. App pages call them without knowing the shell internals.
|
|
13
|
+
*
|
|
14
|
+
* The default implementations throw if called outside of the shell context
|
|
15
|
+
* (which should never happen in production — the shell always provides them
|
|
16
|
+
* via the import map before mounting an app page).
|
|
17
|
+
*/
|
|
18
|
+
interface AppContextValue {
|
|
19
|
+
/** The slug of the installed app owning this page. */
|
|
20
|
+
appSlug: string;
|
|
21
|
+
/** The page path within the app (e.g. 'attribution'). */
|
|
22
|
+
pagePath: string;
|
|
23
|
+
/** The active space id, when applicable. */
|
|
24
|
+
spaceId?: string;
|
|
25
|
+
}
|
|
26
|
+
declare const AppContextProvider: React.Provider<AppContextValue | null>;
|
|
27
|
+
/** Returns context info for the current app page (appSlug, pagePath, spaceId). */
|
|
28
|
+
declare function useAppContext(): AppContextValue;
|
|
29
|
+
interface AppApiClient {
|
|
30
|
+
/**
|
|
31
|
+
* Perform a GET request to a platform-data endpoint.
|
|
32
|
+
* The session cookie is forwarded automatically (same-origin, withCredentials).
|
|
33
|
+
*/
|
|
34
|
+
get<T>(path: string, params?: Record<string, string>): Promise<T>;
|
|
35
|
+
/**
|
|
36
|
+
* Perform a POST request to a platform-data endpoint.
|
|
37
|
+
*/
|
|
38
|
+
post<T>(path: string, body?: unknown): Promise<T>;
|
|
39
|
+
}
|
|
40
|
+
declare const AppApiProvider: React.Provider<AppApiClient | null>;
|
|
41
|
+
/**
|
|
42
|
+
* Returns an API client scoped to the current user session.
|
|
43
|
+
* Requests go to /api/data/* with the session cookie (RBAC applies server-side).
|
|
44
|
+
*/
|
|
45
|
+
declare function useAppApi(): AppApiClient;
|
|
46
|
+
|
|
47
|
+
declare const buttonVariants: (props?: ({
|
|
48
|
+
variant?: "default" | "secondary" | "outline" | "ghost" | "destructive" | null | undefined;
|
|
49
|
+
size?: "default" | "sm" | "lg" | "icon" | null | undefined;
|
|
50
|
+
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
51
|
+
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
|
|
52
|
+
}
|
|
53
|
+
declare const Button: React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLButtonElement>>;
|
|
54
|
+
declare const badgeVariants: (props?: ({
|
|
55
|
+
variant?: "outline" | "neutral" | "brand" | "success" | "warning" | "danger" | "info" | null | undefined;
|
|
56
|
+
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
57
|
+
interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement>, VariantProps<typeof badgeVariants> {
|
|
58
|
+
dot?: boolean;
|
|
59
|
+
}
|
|
60
|
+
declare function Badge({ className, variant, dot, children, ...props }: BadgeProps): React.JSX.Element;
|
|
61
|
+
declare function Card({ className, ...props }: React.HTMLAttributes<HTMLDivElement>): React.JSX.Element;
|
|
62
|
+
declare function CardHeader({ className, ...props }: React.HTMLAttributes<HTMLDivElement>): React.JSX.Element;
|
|
63
|
+
declare function CardTitle({ className, ...props }: React.HTMLAttributes<HTMLHeadingElement>): React.JSX.Element;
|
|
64
|
+
declare function CardContent({ className, ...props }: React.HTMLAttributes<HTMLDivElement>): React.JSX.Element;
|
|
65
|
+
declare const Input: React.ForwardRefExoticComponent<React.InputHTMLAttributes<HTMLInputElement> & React.RefAttributes<HTMLInputElement>>;
|
|
66
|
+
declare function Table({ className, ...props }: React.HTMLAttributes<HTMLTableElement>): React.JSX.Element;
|
|
67
|
+
declare function TableHeader({ className, ...props }: React.HTMLAttributes<HTMLTableSectionElement>): React.JSX.Element;
|
|
68
|
+
declare function TableBody({ className, ...props }: React.HTMLAttributes<HTMLTableSectionElement>): React.JSX.Element;
|
|
69
|
+
declare function TableRow({ className, ...props }: React.HTMLAttributes<HTMLTableRowElement>): React.JSX.Element;
|
|
70
|
+
declare function TableHead({ className, ...props }: React.ThHTMLAttributes<HTMLTableCellElement>): React.JSX.Element;
|
|
71
|
+
declare function TableCell({ className, ...props }: React.TdHTMLAttributes<HTMLTableCellElement>): React.JSX.Element;
|
|
72
|
+
interface SelectProps extends React.SelectHTMLAttributes<HTMLSelectElement> {
|
|
73
|
+
}
|
|
74
|
+
declare const Select: React.ForwardRefExoticComponent<SelectProps & React.RefAttributes<HTMLSelectElement>>;
|
|
75
|
+
interface TabsProps {
|
|
76
|
+
defaultValue?: string;
|
|
77
|
+
value?: string;
|
|
78
|
+
onValueChange?: (v: string) => void;
|
|
79
|
+
className?: string;
|
|
80
|
+
children: React.ReactNode;
|
|
81
|
+
}
|
|
82
|
+
declare function Tabs({ defaultValue, value, onValueChange, className, children }: TabsProps): React.JSX.Element;
|
|
83
|
+
declare function TabsList({ className, children }: {
|
|
84
|
+
className?: string;
|
|
85
|
+
children: React.ReactNode;
|
|
86
|
+
}): React.JSX.Element;
|
|
87
|
+
declare function TabsTrigger({ value, className, children, }: {
|
|
88
|
+
value: string;
|
|
89
|
+
className?: string;
|
|
90
|
+
children: React.ReactNode;
|
|
91
|
+
}): React.JSX.Element;
|
|
92
|
+
declare function TabsContent({ value, className, children, }: {
|
|
93
|
+
value: string;
|
|
94
|
+
className?: string;
|
|
95
|
+
children: React.ReactNode;
|
|
96
|
+
}): React.JSX.Element | null;
|
|
97
|
+
interface ModalProps {
|
|
98
|
+
open: boolean;
|
|
99
|
+
onClose: () => void;
|
|
100
|
+
title?: React.ReactNode;
|
|
101
|
+
children: React.ReactNode;
|
|
102
|
+
className?: string;
|
|
103
|
+
}
|
|
104
|
+
declare function Modal({ open, onClose, title, children, className }: ModalProps): React.JSX.Element | null;
|
|
105
|
+
interface SpinnerProps {
|
|
106
|
+
className?: string;
|
|
107
|
+
size?: 'sm' | 'md' | 'lg';
|
|
108
|
+
}
|
|
109
|
+
declare function Spinner({ className, size }: SpinnerProps): React.JSX.Element;
|
|
110
|
+
interface LinkProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
|
|
111
|
+
variant?: 'default' | 'muted';
|
|
112
|
+
}
|
|
113
|
+
declare const Link: React.ForwardRefExoticComponent<LinkProps & React.RefAttributes<HTMLAnchorElement>>;
|
|
114
|
+
interface SwitchProps {
|
|
115
|
+
checked?: boolean;
|
|
116
|
+
onCheckedChange?: (checked: boolean) => void;
|
|
117
|
+
disabled?: boolean;
|
|
118
|
+
className?: string;
|
|
119
|
+
'aria-label'?: string;
|
|
120
|
+
}
|
|
121
|
+
declare function Switch({ checked, onCheckedChange, disabled, className, ...props }: SwitchProps): React.JSX.Element;
|
|
122
|
+
interface DateRange {
|
|
123
|
+
from: string;
|
|
124
|
+
to: string;
|
|
125
|
+
}
|
|
126
|
+
interface DateRangePickerProps {
|
|
127
|
+
value: DateRange;
|
|
128
|
+
onChange: (range: DateRange) => void;
|
|
129
|
+
className?: string;
|
|
130
|
+
disabled?: boolean;
|
|
131
|
+
}
|
|
132
|
+
/** Minimal controlled date-range picker using two native date inputs. */
|
|
133
|
+
declare function DateRangePicker({ value, onChange, className, disabled }: DateRangePickerProps): React.JSX.Element;
|
|
134
|
+
|
|
135
|
+
export { type AppApiClient, AppApiProvider, AppContextProvider, type AppContextValue, Badge, type BadgeProps, Button, type ButtonProps, Card, CardContent, CardHeader, CardTitle, type DateRange, DateRangePicker, type DateRangePickerProps, Input, Link, type LinkProps, Modal, type ModalProps, Select, type SelectProps, Spinner, type SpinnerProps, Switch, type SwitchProps, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, type TabsProps, TabsTrigger, cn, useAppApi, useAppContext };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { ClassValue } from 'clsx';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import * as class_variance_authority_types from 'class-variance-authority/types';
|
|
4
|
+
import { VariantProps } from 'class-variance-authority';
|
|
5
|
+
|
|
6
|
+
declare function cn(...inputs: ClassValue[]): string;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Runtime hooks provided by the shell via @apotech-os/ui-sdk.
|
|
10
|
+
*
|
|
11
|
+
* These hooks are implemented by the shell and injected at runtime via the
|
|
12
|
+
* import map. App pages call them without knowing the shell internals.
|
|
13
|
+
*
|
|
14
|
+
* The default implementations throw if called outside of the shell context
|
|
15
|
+
* (which should never happen in production — the shell always provides them
|
|
16
|
+
* via the import map before mounting an app page).
|
|
17
|
+
*/
|
|
18
|
+
interface AppContextValue {
|
|
19
|
+
/** The slug of the installed app owning this page. */
|
|
20
|
+
appSlug: string;
|
|
21
|
+
/** The page path within the app (e.g. 'attribution'). */
|
|
22
|
+
pagePath: string;
|
|
23
|
+
/** The active space id, when applicable. */
|
|
24
|
+
spaceId?: string;
|
|
25
|
+
}
|
|
26
|
+
declare const AppContextProvider: React.Provider<AppContextValue | null>;
|
|
27
|
+
/** Returns context info for the current app page (appSlug, pagePath, spaceId). */
|
|
28
|
+
declare function useAppContext(): AppContextValue;
|
|
29
|
+
interface AppApiClient {
|
|
30
|
+
/**
|
|
31
|
+
* Perform a GET request to a platform-data endpoint.
|
|
32
|
+
* The session cookie is forwarded automatically (same-origin, withCredentials).
|
|
33
|
+
*/
|
|
34
|
+
get<T>(path: string, params?: Record<string, string>): Promise<T>;
|
|
35
|
+
/**
|
|
36
|
+
* Perform a POST request to a platform-data endpoint.
|
|
37
|
+
*/
|
|
38
|
+
post<T>(path: string, body?: unknown): Promise<T>;
|
|
39
|
+
}
|
|
40
|
+
declare const AppApiProvider: React.Provider<AppApiClient | null>;
|
|
41
|
+
/**
|
|
42
|
+
* Returns an API client scoped to the current user session.
|
|
43
|
+
* Requests go to /api/data/* with the session cookie (RBAC applies server-side).
|
|
44
|
+
*/
|
|
45
|
+
declare function useAppApi(): AppApiClient;
|
|
46
|
+
|
|
47
|
+
declare const buttonVariants: (props?: ({
|
|
48
|
+
variant?: "default" | "secondary" | "outline" | "ghost" | "destructive" | null | undefined;
|
|
49
|
+
size?: "default" | "sm" | "lg" | "icon" | null | undefined;
|
|
50
|
+
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
51
|
+
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
|
|
52
|
+
}
|
|
53
|
+
declare const Button: React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLButtonElement>>;
|
|
54
|
+
declare const badgeVariants: (props?: ({
|
|
55
|
+
variant?: "outline" | "neutral" | "brand" | "success" | "warning" | "danger" | "info" | null | undefined;
|
|
56
|
+
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
57
|
+
interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement>, VariantProps<typeof badgeVariants> {
|
|
58
|
+
dot?: boolean;
|
|
59
|
+
}
|
|
60
|
+
declare function Badge({ className, variant, dot, children, ...props }: BadgeProps): React.JSX.Element;
|
|
61
|
+
declare function Card({ className, ...props }: React.HTMLAttributes<HTMLDivElement>): React.JSX.Element;
|
|
62
|
+
declare function CardHeader({ className, ...props }: React.HTMLAttributes<HTMLDivElement>): React.JSX.Element;
|
|
63
|
+
declare function CardTitle({ className, ...props }: React.HTMLAttributes<HTMLHeadingElement>): React.JSX.Element;
|
|
64
|
+
declare function CardContent({ className, ...props }: React.HTMLAttributes<HTMLDivElement>): React.JSX.Element;
|
|
65
|
+
declare const Input: React.ForwardRefExoticComponent<React.InputHTMLAttributes<HTMLInputElement> & React.RefAttributes<HTMLInputElement>>;
|
|
66
|
+
declare function Table({ className, ...props }: React.HTMLAttributes<HTMLTableElement>): React.JSX.Element;
|
|
67
|
+
declare function TableHeader({ className, ...props }: React.HTMLAttributes<HTMLTableSectionElement>): React.JSX.Element;
|
|
68
|
+
declare function TableBody({ className, ...props }: React.HTMLAttributes<HTMLTableSectionElement>): React.JSX.Element;
|
|
69
|
+
declare function TableRow({ className, ...props }: React.HTMLAttributes<HTMLTableRowElement>): React.JSX.Element;
|
|
70
|
+
declare function TableHead({ className, ...props }: React.ThHTMLAttributes<HTMLTableCellElement>): React.JSX.Element;
|
|
71
|
+
declare function TableCell({ className, ...props }: React.TdHTMLAttributes<HTMLTableCellElement>): React.JSX.Element;
|
|
72
|
+
interface SelectProps extends React.SelectHTMLAttributes<HTMLSelectElement> {
|
|
73
|
+
}
|
|
74
|
+
declare const Select: React.ForwardRefExoticComponent<SelectProps & React.RefAttributes<HTMLSelectElement>>;
|
|
75
|
+
interface TabsProps {
|
|
76
|
+
defaultValue?: string;
|
|
77
|
+
value?: string;
|
|
78
|
+
onValueChange?: (v: string) => void;
|
|
79
|
+
className?: string;
|
|
80
|
+
children: React.ReactNode;
|
|
81
|
+
}
|
|
82
|
+
declare function Tabs({ defaultValue, value, onValueChange, className, children }: TabsProps): React.JSX.Element;
|
|
83
|
+
declare function TabsList({ className, children }: {
|
|
84
|
+
className?: string;
|
|
85
|
+
children: React.ReactNode;
|
|
86
|
+
}): React.JSX.Element;
|
|
87
|
+
declare function TabsTrigger({ value, className, children, }: {
|
|
88
|
+
value: string;
|
|
89
|
+
className?: string;
|
|
90
|
+
children: React.ReactNode;
|
|
91
|
+
}): React.JSX.Element;
|
|
92
|
+
declare function TabsContent({ value, className, children, }: {
|
|
93
|
+
value: string;
|
|
94
|
+
className?: string;
|
|
95
|
+
children: React.ReactNode;
|
|
96
|
+
}): React.JSX.Element | null;
|
|
97
|
+
interface ModalProps {
|
|
98
|
+
open: boolean;
|
|
99
|
+
onClose: () => void;
|
|
100
|
+
title?: React.ReactNode;
|
|
101
|
+
children: React.ReactNode;
|
|
102
|
+
className?: string;
|
|
103
|
+
}
|
|
104
|
+
declare function Modal({ open, onClose, title, children, className }: ModalProps): React.JSX.Element | null;
|
|
105
|
+
interface SpinnerProps {
|
|
106
|
+
className?: string;
|
|
107
|
+
size?: 'sm' | 'md' | 'lg';
|
|
108
|
+
}
|
|
109
|
+
declare function Spinner({ className, size }: SpinnerProps): React.JSX.Element;
|
|
110
|
+
interface LinkProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
|
|
111
|
+
variant?: 'default' | 'muted';
|
|
112
|
+
}
|
|
113
|
+
declare const Link: React.ForwardRefExoticComponent<LinkProps & React.RefAttributes<HTMLAnchorElement>>;
|
|
114
|
+
interface SwitchProps {
|
|
115
|
+
checked?: boolean;
|
|
116
|
+
onCheckedChange?: (checked: boolean) => void;
|
|
117
|
+
disabled?: boolean;
|
|
118
|
+
className?: string;
|
|
119
|
+
'aria-label'?: string;
|
|
120
|
+
}
|
|
121
|
+
declare function Switch({ checked, onCheckedChange, disabled, className, ...props }: SwitchProps): React.JSX.Element;
|
|
122
|
+
interface DateRange {
|
|
123
|
+
from: string;
|
|
124
|
+
to: string;
|
|
125
|
+
}
|
|
126
|
+
interface DateRangePickerProps {
|
|
127
|
+
value: DateRange;
|
|
128
|
+
onChange: (range: DateRange) => void;
|
|
129
|
+
className?: string;
|
|
130
|
+
disabled?: boolean;
|
|
131
|
+
}
|
|
132
|
+
/** Minimal controlled date-range picker using two native date inputs. */
|
|
133
|
+
declare function DateRangePicker({ value, onChange, className, disabled }: DateRangePickerProps): React.JSX.Element;
|
|
134
|
+
|
|
135
|
+
export { type AppApiClient, AppApiProvider, AppContextProvider, type AppContextValue, Badge, type BadgeProps, Button, type ButtonProps, Card, CardContent, CardHeader, CardTitle, type DateRange, DateRangePicker, type DateRangePickerProps, Input, Link, type LinkProps, Modal, type ModalProps, Select, type SelectProps, Spinner, type SpinnerProps, Switch, type SwitchProps, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, type TabsProps, TabsTrigger, cn, useAppApi, useAppContext };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
import { clsx } from 'clsx';
|
|
2
|
+
import { twMerge } from 'tailwind-merge';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { createContext, useContext } from 'react';
|
|
5
|
+
import { cva } from 'class-variance-authority';
|
|
6
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
7
|
+
|
|
8
|
+
// src/cn.ts
|
|
9
|
+
function cn(...inputs) {
|
|
10
|
+
return twMerge(clsx(inputs));
|
|
11
|
+
}
|
|
12
|
+
var AppContextInternalCtx = createContext(null);
|
|
13
|
+
var AppContextProvider = AppContextInternalCtx.Provider;
|
|
14
|
+
function useAppContext() {
|
|
15
|
+
const ctx = useContext(AppContextInternalCtx);
|
|
16
|
+
if (!ctx) throw new Error("useAppContext must be used inside an app page mounted by the shell");
|
|
17
|
+
return ctx;
|
|
18
|
+
}
|
|
19
|
+
var AppApiCtx = createContext(null);
|
|
20
|
+
var AppApiProvider = AppApiCtx.Provider;
|
|
21
|
+
function useAppApi() {
|
|
22
|
+
const client = useContext(AppApiCtx);
|
|
23
|
+
if (!client) throw new Error("useAppApi must be used inside an app page mounted by the shell");
|
|
24
|
+
return client;
|
|
25
|
+
}
|
|
26
|
+
var buttonVariants = cva(
|
|
27
|
+
"inline-flex cursor-pointer items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50",
|
|
28
|
+
{
|
|
29
|
+
variants: {
|
|
30
|
+
variant: {
|
|
31
|
+
default: "bg-primary text-primary-foreground hover:bg-primary/90",
|
|
32
|
+
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
33
|
+
outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
|
|
34
|
+
ghost: "hover:bg-accent hover:text-accent-foreground",
|
|
35
|
+
destructive: "bg-destructive text-white hover:bg-destructive/90"
|
|
36
|
+
},
|
|
37
|
+
size: {
|
|
38
|
+
default: "h-9 px-4 py-2",
|
|
39
|
+
sm: "h-8 rounded-md px-3 text-xs",
|
|
40
|
+
lg: "h-10 rounded-md px-6",
|
|
41
|
+
icon: "h-9 w-9"
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
defaultVariants: { variant: "default", size: "default" }
|
|
45
|
+
}
|
|
46
|
+
);
|
|
47
|
+
var Button = React.forwardRef(
|
|
48
|
+
({ className, variant, size, ...props }, ref) => /* @__PURE__ */ jsx("button", { ref, className: cn(buttonVariants({ variant, size, className })), ...props })
|
|
49
|
+
);
|
|
50
|
+
Button.displayName = "Button";
|
|
51
|
+
var badgeVariants = cva(
|
|
52
|
+
"inline-flex items-center gap-1.5 rounded-full border px-2 py-0.5 text-xs font-medium whitespace-nowrap",
|
|
53
|
+
{
|
|
54
|
+
variants: {
|
|
55
|
+
variant: {
|
|
56
|
+
neutral: "border-border bg-muted text-muted-foreground",
|
|
57
|
+
brand: "border-primary/20 bg-primary/10 text-primary",
|
|
58
|
+
success: "border-status-success/25 bg-status-success/10 text-status-success",
|
|
59
|
+
warning: "border-status-pending/30 bg-status-pending/10 text-status-pending",
|
|
60
|
+
danger: "border-status-blocked/25 bg-status-blocked/10 text-status-blocked",
|
|
61
|
+
info: "border-status-info/25 bg-status-info/10 text-status-info",
|
|
62
|
+
outline: "border-border bg-transparent text-muted-foreground"
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
defaultVariants: { variant: "neutral" }
|
|
66
|
+
}
|
|
67
|
+
);
|
|
68
|
+
function Badge({ className, variant, dot, children, ...props }) {
|
|
69
|
+
return /* @__PURE__ */ jsxs("span", { className: cn(badgeVariants({ variant }), className), ...props, children: [
|
|
70
|
+
dot && /* @__PURE__ */ jsx("span", { className: "size-1.5 rounded-full bg-current" }),
|
|
71
|
+
children
|
|
72
|
+
] });
|
|
73
|
+
}
|
|
74
|
+
function Card({ className, ...props }) {
|
|
75
|
+
return /* @__PURE__ */ jsx(
|
|
76
|
+
"div",
|
|
77
|
+
{
|
|
78
|
+
className: cn("rounded-xl border bg-card text-card-foreground shadow-sm", className),
|
|
79
|
+
...props
|
|
80
|
+
}
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
function CardHeader({ className, ...props }) {
|
|
84
|
+
return /* @__PURE__ */ jsx("div", { className: cn("flex flex-col space-y-1.5 p-6", className), ...props });
|
|
85
|
+
}
|
|
86
|
+
function CardTitle({ className, ...props }) {
|
|
87
|
+
return /* @__PURE__ */ jsx("h3", { className: cn("text-lg font-semibold leading-none tracking-tight", className), ...props });
|
|
88
|
+
}
|
|
89
|
+
function CardContent({ className, ...props }) {
|
|
90
|
+
return /* @__PURE__ */ jsx("div", { className: cn("p-6 pt-0", className), ...props });
|
|
91
|
+
}
|
|
92
|
+
var Input = React.forwardRef(
|
|
93
|
+
({ className, type, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
94
|
+
"input",
|
|
95
|
+
{
|
|
96
|
+
type,
|
|
97
|
+
className: cn(
|
|
98
|
+
"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
|
|
99
|
+
className
|
|
100
|
+
),
|
|
101
|
+
ref,
|
|
102
|
+
...props
|
|
103
|
+
}
|
|
104
|
+
)
|
|
105
|
+
);
|
|
106
|
+
Input.displayName = "Input";
|
|
107
|
+
function Table({ className, ...props }) {
|
|
108
|
+
return /* @__PURE__ */ jsx("table", { className: cn("w-full text-sm", className), ...props });
|
|
109
|
+
}
|
|
110
|
+
function TableHeader({ className, ...props }) {
|
|
111
|
+
return /* @__PURE__ */ jsx("thead", { className: cn("[&_tr]:border-b", className), ...props });
|
|
112
|
+
}
|
|
113
|
+
function TableBody({ className, ...props }) {
|
|
114
|
+
return /* @__PURE__ */ jsx("tbody", { className: cn("[&_tr:last-child]:border-0", className), ...props });
|
|
115
|
+
}
|
|
116
|
+
function TableRow({ className, ...props }) {
|
|
117
|
+
return /* @__PURE__ */ jsx(
|
|
118
|
+
"tr",
|
|
119
|
+
{
|
|
120
|
+
className: cn("border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted", className),
|
|
121
|
+
...props
|
|
122
|
+
}
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
function TableHead({ className, ...props }) {
|
|
126
|
+
return /* @__PURE__ */ jsx(
|
|
127
|
+
"th",
|
|
128
|
+
{
|
|
129
|
+
className: cn("h-10 px-4 text-left align-middle text-xs font-medium text-muted-foreground", className),
|
|
130
|
+
...props
|
|
131
|
+
}
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
function TableCell({ className, ...props }) {
|
|
135
|
+
return /* @__PURE__ */ jsx("td", { className: cn("p-4 align-middle", className), ...props });
|
|
136
|
+
}
|
|
137
|
+
var Select = React.forwardRef(
|
|
138
|
+
({ className, children, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
139
|
+
"select",
|
|
140
|
+
{
|
|
141
|
+
ref,
|
|
142
|
+
className: cn(
|
|
143
|
+
"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
|
|
144
|
+
className
|
|
145
|
+
),
|
|
146
|
+
...props,
|
|
147
|
+
children
|
|
148
|
+
}
|
|
149
|
+
)
|
|
150
|
+
);
|
|
151
|
+
Select.displayName = "Select";
|
|
152
|
+
var TabsContext = React.createContext(null);
|
|
153
|
+
function useTabsContext() {
|
|
154
|
+
const ctx = React.useContext(TabsContext);
|
|
155
|
+
if (!ctx) throw new Error("Tabs sub-component must be used within <Tabs>");
|
|
156
|
+
return ctx;
|
|
157
|
+
}
|
|
158
|
+
function Tabs({ defaultValue, value, onValueChange, className, children }) {
|
|
159
|
+
const [internal, setInternal] = React.useState(defaultValue ?? "");
|
|
160
|
+
const current = value ?? internal;
|
|
161
|
+
const setValue = (v) => {
|
|
162
|
+
setInternal(v);
|
|
163
|
+
onValueChange?.(v);
|
|
164
|
+
};
|
|
165
|
+
return /* @__PURE__ */ jsx(TabsContext.Provider, { value: { value: current, setValue }, children: /* @__PURE__ */ jsx("div", { className, children }) });
|
|
166
|
+
}
|
|
167
|
+
function TabsList({ className, children }) {
|
|
168
|
+
return /* @__PURE__ */ jsx("div", { className: cn("inline-flex items-center gap-1 rounded-lg bg-muted p-1", className), children });
|
|
169
|
+
}
|
|
170
|
+
function TabsTrigger({
|
|
171
|
+
value,
|
|
172
|
+
className,
|
|
173
|
+
children
|
|
174
|
+
}) {
|
|
175
|
+
const { value: current, setValue } = useTabsContext();
|
|
176
|
+
const active = current === value;
|
|
177
|
+
return /* @__PURE__ */ jsx(
|
|
178
|
+
"button",
|
|
179
|
+
{
|
|
180
|
+
type: "button",
|
|
181
|
+
onClick: () => setValue(value),
|
|
182
|
+
className: cn(
|
|
183
|
+
"rounded-md px-3 py-1.5 text-sm font-medium transition-colors",
|
|
184
|
+
active ? "bg-card text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground",
|
|
185
|
+
className
|
|
186
|
+
),
|
|
187
|
+
children
|
|
188
|
+
}
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
function TabsContent({
|
|
192
|
+
value,
|
|
193
|
+
className,
|
|
194
|
+
children
|
|
195
|
+
}) {
|
|
196
|
+
const { value: current } = useTabsContext();
|
|
197
|
+
if (current !== value) return null;
|
|
198
|
+
return /* @__PURE__ */ jsx("div", { className, children });
|
|
199
|
+
}
|
|
200
|
+
function Modal({ open, onClose, title, children, className }) {
|
|
201
|
+
if (!open) return null;
|
|
202
|
+
return /* @__PURE__ */ jsxs("div", { className: "fixed inset-0 z-50 flex items-center justify-center p-4", children: [
|
|
203
|
+
/* @__PURE__ */ jsx(
|
|
204
|
+
"button",
|
|
205
|
+
{
|
|
206
|
+
type: "button",
|
|
207
|
+
"aria-label": "Close",
|
|
208
|
+
className: "absolute inset-0 cursor-default bg-foreground/40",
|
|
209
|
+
onClick: onClose
|
|
210
|
+
}
|
|
211
|
+
),
|
|
212
|
+
/* @__PURE__ */ jsxs(
|
|
213
|
+
"div",
|
|
214
|
+
{
|
|
215
|
+
role: "dialog",
|
|
216
|
+
"aria-modal": true,
|
|
217
|
+
className: cn("relative z-10 w-full max-w-md rounded-xl border bg-card p-5 shadow-lg", className),
|
|
218
|
+
children: [
|
|
219
|
+
title && /* @__PURE__ */ jsx("h2", { className: "mb-3 text-base font-semibold", children: title }),
|
|
220
|
+
children
|
|
221
|
+
]
|
|
222
|
+
}
|
|
223
|
+
)
|
|
224
|
+
] });
|
|
225
|
+
}
|
|
226
|
+
var spinnerSizes = { sm: "size-4", md: "size-6", lg: "size-8" };
|
|
227
|
+
function Spinner({ className, size = "md" }) {
|
|
228
|
+
return /* @__PURE__ */ jsxs(
|
|
229
|
+
"svg",
|
|
230
|
+
{
|
|
231
|
+
className: cn("animate-spin text-muted-foreground", spinnerSizes[size], className),
|
|
232
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
233
|
+
fill: "none",
|
|
234
|
+
viewBox: "0 0 24 24",
|
|
235
|
+
"aria-label": "Loading",
|
|
236
|
+
role: "status",
|
|
237
|
+
children: [
|
|
238
|
+
/* @__PURE__ */ jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
|
|
239
|
+
/* @__PURE__ */ jsx(
|
|
240
|
+
"path",
|
|
241
|
+
{
|
|
242
|
+
className: "opacity-75",
|
|
243
|
+
fill: "currentColor",
|
|
244
|
+
d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
|
|
245
|
+
}
|
|
246
|
+
)
|
|
247
|
+
]
|
|
248
|
+
}
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
var Link = React.forwardRef(
|
|
252
|
+
({ className, variant = "default", ...props }, ref) => /* @__PURE__ */ jsx(
|
|
253
|
+
"a",
|
|
254
|
+
{
|
|
255
|
+
ref,
|
|
256
|
+
className: cn(
|
|
257
|
+
"underline-offset-4 hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
258
|
+
variant === "default" ? "text-primary" : "text-muted-foreground",
|
|
259
|
+
className
|
|
260
|
+
),
|
|
261
|
+
...props
|
|
262
|
+
}
|
|
263
|
+
)
|
|
264
|
+
);
|
|
265
|
+
Link.displayName = "Link";
|
|
266
|
+
function Switch({ checked = false, onCheckedChange, disabled, className, ...props }) {
|
|
267
|
+
return /* @__PURE__ */ jsx(
|
|
268
|
+
"button",
|
|
269
|
+
{
|
|
270
|
+
type: "button",
|
|
271
|
+
role: "switch",
|
|
272
|
+
"aria-checked": checked,
|
|
273
|
+
disabled,
|
|
274
|
+
onClick: () => onCheckedChange?.(!checked),
|
|
275
|
+
className: cn(
|
|
276
|
+
"relative inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
|
|
277
|
+
checked ? "bg-primary" : "bg-input",
|
|
278
|
+
className
|
|
279
|
+
),
|
|
280
|
+
...props,
|
|
281
|
+
children: /* @__PURE__ */ jsx(
|
|
282
|
+
"span",
|
|
283
|
+
{
|
|
284
|
+
className: cn(
|
|
285
|
+
"inline-block size-4 transform rounded-full bg-white shadow transition-transform",
|
|
286
|
+
checked ? "translate-x-4" : "translate-x-0.5"
|
|
287
|
+
)
|
|
288
|
+
}
|
|
289
|
+
)
|
|
290
|
+
}
|
|
291
|
+
);
|
|
292
|
+
}
|
|
293
|
+
function DateRangePicker({ value, onChange, className, disabled }) {
|
|
294
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-2", className), children: [
|
|
295
|
+
/* @__PURE__ */ jsx(
|
|
296
|
+
"input",
|
|
297
|
+
{
|
|
298
|
+
type: "date",
|
|
299
|
+
disabled,
|
|
300
|
+
value: value.from,
|
|
301
|
+
max: value.to || void 0,
|
|
302
|
+
onChange: (e) => onChange({ ...value, from: e.target.value }),
|
|
303
|
+
className: "flex h-9 rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50"
|
|
304
|
+
}
|
|
305
|
+
),
|
|
306
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground text-sm", children: "\u2192" }),
|
|
307
|
+
/* @__PURE__ */ jsx(
|
|
308
|
+
"input",
|
|
309
|
+
{
|
|
310
|
+
type: "date",
|
|
311
|
+
disabled,
|
|
312
|
+
value: value.to,
|
|
313
|
+
min: value.from || void 0,
|
|
314
|
+
onChange: (e) => onChange({ ...value, to: e.target.value }),
|
|
315
|
+
className: "flex h-9 rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50"
|
|
316
|
+
}
|
|
317
|
+
)
|
|
318
|
+
] });
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
export { AppApiProvider, AppContextProvider, Badge, Button, Card, CardContent, CardHeader, CardTitle, DateRangePicker, Input, Link, Modal, Select, Spinner, Switch, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, cn, useAppApi, useAppContext };
|
|
322
|
+
//# sourceMappingURL=index.js.map
|
|
323
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cn.ts","../src/hooks.ts","../src/components.tsx"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import { type ClassValue, clsx } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n","/**\n * Runtime hooks provided by the shell via @apotech-os/ui-sdk.\n *\n * These hooks are implemented by the shell and injected at runtime via the\n * import map. App pages call them without knowing the shell internals.\n *\n * The default implementations throw if called outside of the shell context\n * (which should never happen in production — the shell always provides them\n * via the import map before mounting an app page).\n */\n\nimport { useContext, createContext } from 'react';\n\n// ---------------------------------------------------------------------------\n// AppContext\n// ---------------------------------------------------------------------------\n\nexport interface AppContextValue {\n /** The slug of the installed app owning this page. */\n appSlug: string;\n /** The page path within the app (e.g. 'attribution'). */\n pagePath: string;\n /** The active space id, when applicable. */\n spaceId?: string;\n}\n\nconst AppContextInternalCtx = createContext<AppContextValue | null>(null);\n\nexport const AppContextProvider = AppContextInternalCtx.Provider;\n\n/** Returns context info for the current app page (appSlug, pagePath, spaceId). */\nexport function useAppContext(): AppContextValue {\n const ctx = useContext(AppContextInternalCtx);\n if (!ctx) throw new Error('useAppContext must be used inside an app page mounted by the shell');\n return ctx;\n}\n\n// ---------------------------------------------------------------------------\n// AppApi\n// ---------------------------------------------------------------------------\n\nexport interface AppApiClient {\n /**\n * Perform a GET request to a platform-data endpoint.\n * The session cookie is forwarded automatically (same-origin, withCredentials).\n */\n get<T>(path: string, params?: Record<string, string>): Promise<T>;\n /**\n * Perform a POST request to a platform-data endpoint.\n */\n post<T>(path: string, body?: unknown): Promise<T>;\n}\n\nconst AppApiCtx = createContext<AppApiClient | null>(null);\n\nexport const AppApiProvider = AppApiCtx.Provider;\n\n/**\n * Returns an API client scoped to the current user session.\n * Requests go to /api/data/* with the session cookie (RBAC applies server-side).\n */\nexport function useAppApi(): AppApiClient {\n const client = useContext(AppApiCtx);\n if (!client) throw new Error('useAppApi must be used inside an app page mounted by the shell');\n return client;\n}\n","/**\n * Design system components exported by @apotech-os/ui-sdk.\n *\n * These are minimal self-contained copies of the shell's component library.\n * They use the same Tailwind utility classes as the shell — Tailwind classes\n * are plain strings and work without any build step when the shell's stylesheet\n * is loaded (which it is, since these pages run inside the shell).\n *\n * Strategy note:\n * - Not imported from apps/web (would create a circular dep pkg → app).\n * - Copied/adapted here to keep the SDK self-contained and publishable.\n * - The exhaustive component inventory is tracked in #75.\n */\n\nimport { type VariantProps, cva } from 'class-variance-authority';\nimport * as React from 'react';\nimport { cn } from './cn';\n\n// ---------------------------------------------------------------------------\n// Button\n// ---------------------------------------------------------------------------\n\nconst buttonVariants = cva(\n 'inline-flex cursor-pointer items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50',\n {\n variants: {\n variant: {\n default: 'bg-primary text-primary-foreground hover:bg-primary/90',\n secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',\n outline: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground',\n ghost: 'hover:bg-accent hover:text-accent-foreground',\n destructive: 'bg-destructive text-white hover:bg-destructive/90',\n },\n size: {\n default: 'h-9 px-4 py-2',\n sm: 'h-8 rounded-md px-3 text-xs',\n lg: 'h-10 rounded-md px-6',\n icon: 'h-9 w-9',\n },\n },\n defaultVariants: { variant: 'default', size: 'default' },\n },\n);\n\nexport interface ButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement>,\n VariantProps<typeof buttonVariants> {}\n\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant, size, ...props }, ref) => (\n <button ref={ref} className={cn(buttonVariants({ variant, size, className }))} {...props} />\n ),\n);\nButton.displayName = 'Button';\n\n// ---------------------------------------------------------------------------\n// Badge\n// ---------------------------------------------------------------------------\n\nconst badgeVariants = cva(\n 'inline-flex items-center gap-1.5 rounded-full border px-2 py-0.5 text-xs font-medium whitespace-nowrap',\n {\n variants: {\n variant: {\n neutral: 'border-border bg-muted text-muted-foreground',\n brand: 'border-primary/20 bg-primary/10 text-primary',\n success: 'border-status-success/25 bg-status-success/10 text-status-success',\n warning: 'border-status-pending/30 bg-status-pending/10 text-status-pending',\n danger: 'border-status-blocked/25 bg-status-blocked/10 text-status-blocked',\n info: 'border-status-info/25 bg-status-info/10 text-status-info',\n outline: 'border-border bg-transparent text-muted-foreground',\n },\n },\n defaultVariants: { variant: 'neutral' },\n },\n);\n\nexport interface BadgeProps\n extends React.HTMLAttributes<HTMLSpanElement>,\n VariantProps<typeof badgeVariants> {\n dot?: boolean;\n}\n\nexport function Badge({ className, variant, dot, children, ...props }: BadgeProps) {\n return (\n <span className={cn(badgeVariants({ variant }), className)} {...props}>\n {dot && <span className=\"size-1.5 rounded-full bg-current\" />}\n {children}\n </span>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Card\n// ---------------------------------------------------------------------------\n\nexport function Card({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {\n return (\n <div\n className={cn('rounded-xl border bg-card text-card-foreground shadow-sm', className)}\n {...props}\n />\n );\n}\n\nexport function CardHeader({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {\n return <div className={cn('flex flex-col space-y-1.5 p-6', className)} {...props} />;\n}\n\nexport function CardTitle({ className, ...props }: React.HTMLAttributes<HTMLHeadingElement>) {\n return <h3 className={cn('text-lg font-semibold leading-none tracking-tight', className)} {...props} />;\n}\n\nexport function CardContent({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {\n return <div className={cn('p-6 pt-0', className)} {...props} />;\n}\n\n// ---------------------------------------------------------------------------\n// Input\n// ---------------------------------------------------------------------------\n\nexport const Input = React.forwardRef<HTMLInputElement, React.InputHTMLAttributes<HTMLInputElement>>(\n ({ className, type, ...props }, ref) => (\n <input\n type={type}\n className={cn(\n 'flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50',\n className,\n )}\n ref={ref}\n {...props}\n />\n ),\n);\nInput.displayName = 'Input';\n\n// ---------------------------------------------------------------------------\n// Table\n// ---------------------------------------------------------------------------\n\nexport function Table({ className, ...props }: React.HTMLAttributes<HTMLTableElement>) {\n return <table className={cn('w-full text-sm', className)} {...props} />;\n}\n\nexport function TableHeader({ className, ...props }: React.HTMLAttributes<HTMLTableSectionElement>) {\n return <thead className={cn('[&_tr]:border-b', className)} {...props} />;\n}\n\nexport function TableBody({ className, ...props }: React.HTMLAttributes<HTMLTableSectionElement>) {\n return <tbody className={cn('[&_tr:last-child]:border-0', className)} {...props} />;\n}\n\nexport function TableRow({ className, ...props }: React.HTMLAttributes<HTMLTableRowElement>) {\n return (\n <tr\n className={cn('border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted', className)}\n {...props}\n />\n );\n}\n\nexport function TableHead({ className, ...props }: React.ThHTMLAttributes<HTMLTableCellElement>) {\n return (\n <th\n className={cn('h-10 px-4 text-left align-middle text-xs font-medium text-muted-foreground', className)}\n {...props}\n />\n );\n}\n\nexport function TableCell({ className, ...props }: React.TdHTMLAttributes<HTMLTableCellElement>) {\n return <td className={cn('p-4 align-middle', className)} {...props} />;\n}\n\n// ---------------------------------------------------------------------------\n// Select\n// ---------------------------------------------------------------------------\n\nexport interface SelectProps extends React.SelectHTMLAttributes<HTMLSelectElement> {}\n\nexport const Select = React.forwardRef<HTMLSelectElement, SelectProps>(\n ({ className, children, ...props }, ref) => (\n <select\n ref={ref}\n className={cn(\n 'flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50',\n className,\n )}\n {...props}\n >\n {children}\n </select>\n ),\n);\nSelect.displayName = 'Select';\n\n// ---------------------------------------------------------------------------\n// Tabs\n// ---------------------------------------------------------------------------\n\ninterface TabsContextValue {\n value: string;\n setValue: (v: string) => void;\n}\n\nconst TabsContext = React.createContext<TabsContextValue | null>(null);\n\nfunction useTabsContext(): TabsContextValue {\n const ctx = React.useContext(TabsContext);\n if (!ctx) throw new Error('Tabs sub-component must be used within <Tabs>');\n return ctx;\n}\n\nexport interface TabsProps {\n defaultValue?: string;\n value?: string;\n onValueChange?: (v: string) => void;\n className?: string;\n children: React.ReactNode;\n}\n\nexport function Tabs({ defaultValue, value, onValueChange, className, children }: TabsProps) {\n const [internal, setInternal] = React.useState(defaultValue ?? '');\n const current = value ?? internal;\n const setValue = (v: string) => {\n setInternal(v);\n onValueChange?.(v);\n };\n return (\n <TabsContext.Provider value={{ value: current, setValue }}>\n <div className={className}>{children}</div>\n </TabsContext.Provider>\n );\n}\n\nexport function TabsList({ className, children }: { className?: string; children: React.ReactNode }) {\n return (\n <div className={cn('inline-flex items-center gap-1 rounded-lg bg-muted p-1', className)}>\n {children}\n </div>\n );\n}\n\nexport function TabsTrigger({\n value,\n className,\n children,\n}: {\n value: string;\n className?: string;\n children: React.ReactNode;\n}) {\n const { value: current, setValue } = useTabsContext();\n const active = current === value;\n return (\n <button\n type=\"button\"\n onClick={() => setValue(value)}\n className={cn(\n 'rounded-md px-3 py-1.5 text-sm font-medium transition-colors',\n active ? 'bg-card text-foreground shadow-sm' : 'text-muted-foreground hover:text-foreground',\n className,\n )}\n >\n {children}\n </button>\n );\n}\n\nexport function TabsContent({\n value,\n className,\n children,\n}: {\n value: string;\n className?: string;\n children: React.ReactNode;\n}) {\n const { value: current } = useTabsContext();\n if (current !== value) return null;\n return <div className={className}>{children}</div>;\n}\n\n// ---------------------------------------------------------------------------\n// Modal (controlled, no Radix)\n// ---------------------------------------------------------------------------\n\nexport interface ModalProps {\n open: boolean;\n onClose: () => void;\n title?: React.ReactNode;\n children: React.ReactNode;\n className?: string;\n}\n\nexport function Modal({ open, onClose, title, children, className }: ModalProps) {\n if (!open) return null;\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center p-4\">\n <button\n type=\"button\"\n aria-label=\"Close\"\n className=\"absolute inset-0 cursor-default bg-foreground/40\"\n onClick={onClose}\n />\n <div\n role=\"dialog\"\n aria-modal\n className={cn('relative z-10 w-full max-w-md rounded-xl border bg-card p-5 shadow-lg', className)}\n >\n {title && <h2 className=\"mb-3 text-base font-semibold\">{title}</h2>}\n {children}\n </div>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Spinner\n// ---------------------------------------------------------------------------\n\nexport interface SpinnerProps {\n className?: string;\n size?: 'sm' | 'md' | 'lg';\n}\n\nconst spinnerSizes = { sm: 'size-4', md: 'size-6', lg: 'size-8' };\n\nexport function Spinner({ className, size = 'md' }: SpinnerProps) {\n return (\n <svg\n className={cn('animate-spin text-muted-foreground', spinnerSizes[size], className)}\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n aria-label=\"Loading\"\n role=\"status\"\n >\n <circle className=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" strokeWidth=\"4\" />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z\"\n />\n </svg>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Link\n// ---------------------------------------------------------------------------\n\nexport interface LinkProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {\n variant?: 'default' | 'muted';\n}\n\nexport const Link = React.forwardRef<HTMLAnchorElement, LinkProps>(\n ({ className, variant = 'default', ...props }, ref) => (\n <a\n ref={ref}\n className={cn(\n 'underline-offset-4 hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',\n variant === 'default' ? 'text-primary' : 'text-muted-foreground',\n className,\n )}\n {...props}\n />\n ),\n);\nLink.displayName = 'Link';\n\n// ---------------------------------------------------------------------------\n// Switch\n// ---------------------------------------------------------------------------\n\nexport interface SwitchProps {\n checked?: boolean;\n onCheckedChange?: (checked: boolean) => void;\n disabled?: boolean;\n className?: string;\n 'aria-label'?: string;\n}\n\nexport function Switch({ checked = false, onCheckedChange, disabled, className, ...props }: SwitchProps) {\n return (\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={checked}\n disabled={disabled}\n onClick={() => onCheckedChange?.(!checked)}\n className={cn(\n 'relative inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50',\n checked ? 'bg-primary' : 'bg-input',\n className,\n )}\n {...props}\n >\n <span\n className={cn(\n 'inline-block size-4 transform rounded-full bg-white shadow transition-transform',\n checked ? 'translate-x-4' : 'translate-x-0.5',\n )}\n />\n </button>\n );\n}\n\n// ---------------------------------------------------------------------------\n// DateRangePicker\n// ---------------------------------------------------------------------------\n\nexport interface DateRange {\n from: string;\n to: string;\n}\n\nexport interface DateRangePickerProps {\n value: DateRange;\n onChange: (range: DateRange) => void;\n className?: string;\n disabled?: boolean;\n}\n\n/** Minimal controlled date-range picker using two native date inputs. */\nexport function DateRangePicker({ value, onChange, className, disabled }: DateRangePickerProps) {\n return (\n <div className={cn('flex items-center gap-2', className)}>\n <input\n type=\"date\"\n disabled={disabled}\n value={value.from}\n max={value.to || undefined}\n onChange={(e) => onChange({ ...value, from: e.target.value })}\n className=\"flex h-9 rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50\"\n />\n <span className=\"text-muted-foreground text-sm\">→</span>\n <input\n type=\"date\"\n disabled={disabled}\n value={value.to}\n min={value.from || undefined}\n onChange={(e) => onChange({ ...value, to: e.target.value })}\n className=\"flex h-9 rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50\"\n />\n </div>\n );\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@apotech-os/ui-sdk",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/index.cjs",
|
|
6
|
+
"module": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"require": {
|
|
15
|
+
"types": "./dist/index.d.cts",
|
|
16
|
+
"default": "./dist/index.cjs"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist"
|
|
22
|
+
],
|
|
23
|
+
"publishConfig": {
|
|
24
|
+
"access": "public"
|
|
25
|
+
},
|
|
26
|
+
"repository": {
|
|
27
|
+
"type": "git",
|
|
28
|
+
"url": "https://github.com/apotech-studio/wopilo-os.git"
|
|
29
|
+
},
|
|
30
|
+
"peerDependencies": {
|
|
31
|
+
"react": ">=18",
|
|
32
|
+
"react-dom": ">=18"
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"class-variance-authority": "^0.7.1",
|
|
36
|
+
"clsx": "^2.1.1",
|
|
37
|
+
"tailwind-merge": "^3.3.0"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@types/react": "^19.2.17",
|
|
41
|
+
"@types/react-dom": "^19.2.3",
|
|
42
|
+
"tsup": "^8.5.0",
|
|
43
|
+
"typescript": "~5.9.3",
|
|
44
|
+
"vitest": "^4.1.9"
|
|
45
|
+
},
|
|
46
|
+
"scripts": {
|
|
47
|
+
"build": "tsup",
|
|
48
|
+
"dev": "tsup --watch",
|
|
49
|
+
"typecheck": "tsc --noEmit",
|
|
50
|
+
"test": "vitest run"
|
|
51
|
+
}
|
|
52
|
+
}
|