@m1kapp/ui 0.1.2 → 0.1.4
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.js +4 -305
- package/dist/index.mjs +4 -264
- package/package.json +2 -2
- package/dist/index.js.map +0 -1
- package/dist/index.mjs.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,306 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
"use strict";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
var
|
|
6
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
-
var __export = (target, all) => {
|
|
8
|
-
for (var name in all)
|
|
9
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
-
};
|
|
11
|
-
var __copyProps = (to, from, except, desc) => {
|
|
12
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
-
for (let key of __getOwnPropNames(from))
|
|
14
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
-
}
|
|
17
|
-
return to;
|
|
18
|
-
};
|
|
19
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
-
|
|
21
|
-
// src/index.ts
|
|
22
|
-
var index_exports = {};
|
|
23
|
-
__export(index_exports, {
|
|
24
|
-
AppShell: () => AppShell,
|
|
25
|
-
AppShellContent: () => AppShellContent,
|
|
26
|
-
AppShellHeader: () => AppShellHeader,
|
|
27
|
-
Divider: () => Divider,
|
|
28
|
-
EmptyState: () => EmptyState,
|
|
29
|
-
Section: () => Section,
|
|
30
|
-
SectionHeader: () => SectionHeader,
|
|
31
|
-
StatChip: () => StatChip,
|
|
32
|
-
Tab: () => Tab,
|
|
33
|
-
TabBar: () => TabBar,
|
|
34
|
-
ThemeButton: () => ThemeButton,
|
|
35
|
-
ThemeDialog: () => ThemeDialog,
|
|
36
|
-
Watermark: () => Watermark,
|
|
37
|
-
colors: () => colors,
|
|
38
|
-
fontFamily: () => fontFamily,
|
|
39
|
-
fonts: () => fonts
|
|
40
|
-
});
|
|
41
|
-
module.exports = __toCommonJS(index_exports);
|
|
42
|
-
|
|
43
|
-
// src/components/app-shell.tsx
|
|
44
|
-
var import_jsx_runtime = require("react/jsx-runtime");
|
|
45
|
-
function AppShell({
|
|
46
|
-
children,
|
|
47
|
-
className = "",
|
|
48
|
-
maxWidth = 430,
|
|
49
|
-
style
|
|
50
|
-
}) {
|
|
51
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
52
|
-
"div",
|
|
53
|
-
{
|
|
54
|
-
className: `w-full h-full flex flex-col bg-white dark:bg-zinc-950 shadow-2xl ring-1 ring-black/5 dark:ring-white/10 rounded-2xl overflow-hidden ${className}`,
|
|
55
|
-
style: { maxWidth, ...style },
|
|
56
|
-
children
|
|
57
|
-
}
|
|
58
|
-
);
|
|
59
|
-
}
|
|
60
|
-
function AppShellHeader({ children, className = "" }) {
|
|
61
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
62
|
-
"header",
|
|
63
|
-
{
|
|
64
|
-
className: `sticky top-0 z-20 px-4 py-3 flex items-center justify-between border-b border-zinc-100 dark:border-zinc-800 bg-white/90 dark:bg-zinc-950/90 backdrop-blur-md rounded-t-2xl ${className}`,
|
|
65
|
-
children
|
|
66
|
-
}
|
|
67
|
-
);
|
|
68
|
-
}
|
|
69
|
-
function AppShellContent({ children, className = "" }) {
|
|
70
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: `flex-1 overflow-y-auto scrollbar-hide ${className}`, children });
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// src/components/tab-bar.tsx
|
|
74
|
-
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
75
|
-
function TabBar({ children, className = "" }) {
|
|
76
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
77
|
-
"nav",
|
|
78
|
-
{
|
|
79
|
-
className: `sticky bottom-0 z-20 border-t border-zinc-200 dark:border-zinc-800 flex bg-white/90 dark:bg-zinc-950/90 backdrop-blur-md rounded-b-2xl ${className}`,
|
|
80
|
-
children
|
|
81
|
-
}
|
|
82
|
-
);
|
|
83
|
-
}
|
|
84
|
-
function Tab({ active, onClick, icon, label, activeColor }) {
|
|
85
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
86
|
-
"button",
|
|
87
|
-
{
|
|
88
|
-
onClick,
|
|
89
|
-
className: `flex-1 flex flex-col items-center gap-0.5 py-2.5 transition-colors ${!active ? "text-zinc-300 dark:text-zinc-600" : ""}`,
|
|
90
|
-
style: active ? { color: activeColor } : void 0,
|
|
91
|
-
children: [
|
|
92
|
-
icon,
|
|
93
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-[10px] font-medium", children: label })
|
|
94
|
-
]
|
|
95
|
-
}
|
|
96
|
-
);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// src/components/section.tsx
|
|
100
|
-
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
101
|
-
function Section({ children, className = "" }) {
|
|
102
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("section", { className: `px-4 ${className}`, children });
|
|
103
|
-
}
|
|
104
|
-
function SectionHeader({ children }) {
|
|
105
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { className: "text-[11px] font-semibold text-zinc-400 dark:text-zinc-500 uppercase tracking-wider mb-3", children });
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// src/components/divider.tsx
|
|
109
|
-
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
110
|
-
function Divider({ className = "" }) {
|
|
111
|
-
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: `mx-4 my-6 h-px bg-zinc-200 dark:bg-zinc-800 ${className}` });
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// src/components/stat-chip.tsx
|
|
115
|
-
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
116
|
-
function StatChip({ label, value, className = "" }) {
|
|
117
|
-
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: `flex-1 rounded-xl bg-zinc-100 dark:bg-zinc-900 px-3 py-3 text-center ${className}`, children: [
|
|
118
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-[10px] text-zinc-500 dark:text-zinc-400 font-medium mb-0.5", children: label }),
|
|
119
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-lg font-bold tabular-nums text-zinc-900 dark:text-white", children: value.toLocaleString() })
|
|
120
|
-
] });
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// src/components/empty-state.tsx
|
|
124
|
-
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
125
|
-
function EmptyState({ message, icon }) {
|
|
126
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex flex-col items-center justify-center py-12 gap-2", children: [
|
|
127
|
-
icon || /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("svg", { width: "32", height: "32", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", className: "text-zinc-200 dark:text-zinc-700", children: [
|
|
128
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
|
|
129
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M8 15h8" }),
|
|
130
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("circle", { cx: "9", cy: "9", r: "1", fill: "currentColor", stroke: "none" }),
|
|
131
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("circle", { cx: "15", cy: "9", r: "1", fill: "currentColor", stroke: "none" })
|
|
132
|
-
] }),
|
|
133
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "text-sm text-zinc-400 dark:text-zinc-500", children: message })
|
|
134
|
-
] });
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// src/components/watermark.tsx
|
|
138
|
-
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
139
|
-
function buildSvgPattern(text, opacity = 0.08) {
|
|
140
|
-
const w = 220;
|
|
141
|
-
const h = 120;
|
|
142
|
-
const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${w}" height="${h}">
|
|
143
|
-
<text x="10" y="45" font-family="system-ui,sans-serif" font-size="44" font-weight="900" fill="white" opacity="${opacity}">${text}</text>
|
|
144
|
-
<text x="120" y="100" font-family="system-ui,sans-serif" font-size="44" font-weight="900" fill="white" opacity="${opacity}">${text}</text>
|
|
145
|
-
</svg>`;
|
|
146
|
-
return `url("data:image/svg+xml,${encodeURIComponent(svg)}")`;
|
|
147
|
-
}
|
|
148
|
-
function Watermark({
|
|
149
|
-
children,
|
|
150
|
-
color = "#0f172a",
|
|
151
|
-
text = "m1k",
|
|
152
|
-
maxWidth = 430,
|
|
153
|
-
padding = 12
|
|
154
|
-
}) {
|
|
155
|
-
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
156
|
-
"div",
|
|
157
|
-
{
|
|
158
|
-
className: "h-dvh w-full relative overflow-hidden",
|
|
159
|
-
style: { backgroundColor: color, transition: "background-color 0.5s ease" },
|
|
160
|
-
children: [
|
|
161
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
162
|
-
"div",
|
|
163
|
-
{
|
|
164
|
-
className: "absolute inset-0 pointer-events-none select-none",
|
|
165
|
-
style: {
|
|
166
|
-
backgroundImage: buildSvgPattern(text),
|
|
167
|
-
backgroundRepeat: "repeat",
|
|
168
|
-
transform: "rotate(-12deg) scale(1.5)",
|
|
169
|
-
transformOrigin: "center center"
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
),
|
|
173
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
174
|
-
"div",
|
|
175
|
-
{
|
|
176
|
-
className: "relative z-10 h-full flex items-center justify-center mx-auto",
|
|
177
|
-
style: { maxWidth, padding },
|
|
178
|
-
children
|
|
179
|
-
}
|
|
180
|
-
)
|
|
181
|
-
]
|
|
182
|
-
}
|
|
183
|
-
);
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
// src/components/colors.ts
|
|
187
|
-
var colors = {
|
|
188
|
-
blue: "#3b82f6",
|
|
189
|
-
purple: "#8b5cf6",
|
|
190
|
-
green: "#10b981",
|
|
191
|
-
orange: "#f97316",
|
|
192
|
-
pink: "#ec4899",
|
|
193
|
-
red: "#ef4444",
|
|
194
|
-
yellow: "#eab308",
|
|
195
|
-
cyan: "#06b6d4",
|
|
196
|
-
slate: "#0f172a",
|
|
197
|
-
zinc: "#27272a"
|
|
198
|
-
};
|
|
199
|
-
|
|
200
|
-
// src/components/theme-picker.tsx
|
|
201
|
-
var import_react = require("react");
|
|
202
|
-
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
203
|
-
function ThemeButton({ color, onClick, className = "" }) {
|
|
204
|
-
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
205
|
-
"button",
|
|
206
|
-
{
|
|
207
|
-
onClick,
|
|
208
|
-
className: `w-7 h-7 rounded-full border-2 border-white dark:border-zinc-700 shadow-sm transition-transform hover:scale-110 ${className}`,
|
|
209
|
-
style: { backgroundColor: color },
|
|
210
|
-
title: "Change theme"
|
|
211
|
-
}
|
|
212
|
-
);
|
|
213
|
-
}
|
|
214
|
-
function ThemeDialog({
|
|
215
|
-
open,
|
|
216
|
-
onClose,
|
|
217
|
-
current,
|
|
218
|
-
onSelect,
|
|
219
|
-
palette = colors
|
|
220
|
-
}) {
|
|
221
|
-
(0, import_react.useEffect)(() => {
|
|
222
|
-
if (!open) return;
|
|
223
|
-
const handler = (e) => {
|
|
224
|
-
if (e.key === "Escape") onClose();
|
|
225
|
-
};
|
|
226
|
-
window.addEventListener("keydown", handler);
|
|
227
|
-
return () => window.removeEventListener("keydown", handler);
|
|
228
|
-
}, [open, onClose]);
|
|
229
|
-
if (!open) return null;
|
|
230
|
-
const entries = Object.entries(palette);
|
|
231
|
-
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "fixed inset-0 z-50 flex items-end justify-center", onClick: onClose, children: [
|
|
232
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "absolute inset-0 bg-black/40 backdrop-blur-sm" }),
|
|
233
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
234
|
-
"div",
|
|
235
|
-
{
|
|
236
|
-
className: "relative z-10 w-full max-w-[406px] mb-3 mx-3 rounded-2xl bg-white dark:bg-zinc-900 shadow-2xl overflow-hidden",
|
|
237
|
-
onClick: (e) => e.stopPropagation(),
|
|
238
|
-
children: [
|
|
239
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "px-4 pt-4 pb-2", children: [
|
|
240
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "text-sm font-bold text-zinc-900 dark:text-white", children: "Theme Color" }),
|
|
241
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "text-xs text-zinc-400 dark:text-zinc-500 mt-0.5", children: "Change the Watermark background" })
|
|
242
|
-
] }),
|
|
243
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "px-4 pb-3 grid grid-cols-5 gap-3 justify-items-center", children: entries.map(([name, value]) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
244
|
-
"button",
|
|
245
|
-
{
|
|
246
|
-
onClick: () => {
|
|
247
|
-
onSelect(value);
|
|
248
|
-
onClose();
|
|
249
|
-
},
|
|
250
|
-
className: `relative w-11 h-11 rounded-full transition-all hover:scale-110 ${current === value ? "ring-2 ring-offset-2 ring-offset-white dark:ring-offset-zinc-900" : ""}`,
|
|
251
|
-
style: {
|
|
252
|
-
backgroundColor: value,
|
|
253
|
-
...current === value ? { ["--tw-ring-color"]: value } : {}
|
|
254
|
-
},
|
|
255
|
-
children: current === value && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "white", strokeWidth: "3", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("polyline", { points: "20 6 9 17 4 12" }) }) })
|
|
256
|
-
},
|
|
257
|
-
value
|
|
258
|
-
)) }),
|
|
259
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "px-4 py-3 border-t border-zinc-100 dark:border-zinc-800", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
260
|
-
"button",
|
|
261
|
-
{
|
|
262
|
-
onClick: onClose,
|
|
263
|
-
className: "w-full py-2.5 rounded-xl bg-zinc-100 dark:bg-zinc-800 text-sm font-medium text-zinc-600 dark:text-zinc-400 hover:bg-zinc-200 dark:hover:bg-zinc-700 transition-colors",
|
|
264
|
-
children: "Close"
|
|
265
|
-
}
|
|
266
|
-
) })
|
|
267
|
-
]
|
|
268
|
-
}
|
|
269
|
-
)
|
|
270
|
-
] });
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
// src/components/fonts.ts
|
|
274
|
-
var fonts = {
|
|
275
|
-
/** Toss Product Sans — from toss.im (free for commercial use) */
|
|
276
|
-
toss: "https://static.toss.im/dist/tps.css",
|
|
277
|
-
/** Pretendard — popular Korean web font */
|
|
278
|
-
pretendard: "https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css",
|
|
279
|
-
/** Inter — clean Latin sans-serif */
|
|
280
|
-
inter: "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;900&display=swap"
|
|
281
|
-
};
|
|
282
|
-
var fontFamily = {
|
|
283
|
-
toss: '"Toss Product Sans", "Pretendard", system-ui, sans-serif',
|
|
284
|
-
pretendard: '"Pretendard Variable", "Pretendard", system-ui, sans-serif',
|
|
285
|
-
inter: '"Inter", system-ui, sans-serif'
|
|
286
|
-
};
|
|
287
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
288
|
-
0 && (module.exports = {
|
|
289
|
-
AppShell,
|
|
290
|
-
AppShellContent,
|
|
291
|
-
AppShellHeader,
|
|
292
|
-
Divider,
|
|
293
|
-
EmptyState,
|
|
294
|
-
Section,
|
|
295
|
-
SectionHeader,
|
|
296
|
-
StatChip,
|
|
297
|
-
Tab,
|
|
298
|
-
TabBar,
|
|
299
|
-
ThemeButton,
|
|
300
|
-
ThemeDialog,
|
|
301
|
-
Watermark,
|
|
302
|
-
colors,
|
|
303
|
-
fontFamily,
|
|
304
|
-
fonts
|
|
305
|
-
});
|
|
306
|
-
//# sourceMappingURL=index.js.map
|
|
2
|
+
"use strict";var x=Object.defineProperty;var H=Object.getOwnPropertyDescriptor;var W=Object.getOwnPropertyNames;var D=Object.prototype.hasOwnProperty;var L=(e,t)=>{for(var r in t)x(e,r,{get:t[r],enumerable:!0})},F=(e,t,r,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of W(t))!D.call(e,n)&&n!==r&&x(e,n,{get:()=>t[n],enumerable:!(s=H(t,n))||s.enumerable});return e};var I=e=>F(x({},"__esModule",{value:!0}),e);var O={};L(O,{AppShell:()=>b,AppShellContent:()=>g,AppShellHeader:()=>u,Divider:()=>w,EmptyState:()=>S,Section:()=>v,SectionHeader:()=>N,StatChip:()=>P,Tab:()=>k,TabBar:()=>y,ThemeButton:()=>R,ThemeDialog:()=>$,Watermark:()=>C,colors:()=>f,fontFamily:()=>B,fonts:()=>A});module.exports=I(O);var m=require("react/jsx-runtime");function b({children:e,className:t="",maxWidth:r=430,style:s}){return(0,m.jsx)("div",{className:`w-full h-full flex flex-col bg-white dark:bg-zinc-950 shadow-2xl ring-1 ring-black/5 dark:ring-white/10 rounded-2xl overflow-hidden ${t}`,style:{maxWidth:r,...s},children:e})}function u({children:e,className:t=""}){return(0,m.jsx)("header",{className:`sticky top-0 z-20 px-4 py-3 flex items-center justify-between border-b border-zinc-100 dark:border-zinc-800 bg-white/90 dark:bg-zinc-950/90 backdrop-blur-md rounded-t-2xl ${t}`,children:e})}function g({children:e,className:t=""}){return(0,m.jsx)("div",{className:`flex-1 overflow-y-auto scrollbar-hide ${t}`,children:e})}var p=require("react/jsx-runtime");function y({children:e,className:t=""}){return(0,p.jsx)("nav",{className:`sticky bottom-0 z-20 border-t border-zinc-200 dark:border-zinc-800 flex bg-white/90 dark:bg-zinc-950/90 backdrop-blur-md rounded-b-2xl ${t}`,children:e})}function k({active:e,onClick:t,icon:r,label:s,activeColor:n}){return(0,p.jsxs)("button",{onClick:t,className:`flex-1 flex flex-col items-center gap-0.5 py-2.5 transition-colors ${e?"":"text-zinc-300 dark:text-zinc-600"}`,style:e?{color:n}:void 0,children:[r,(0,p.jsx)("span",{className:"text-[10px] font-medium",children:s})]})}var h=require("react/jsx-runtime");function v({children:e,className:t=""}){return(0,h.jsx)("section",{className:`px-4 ${t}`,children:e})}function N({children:e}){return(0,h.jsx)("h2",{className:"text-[11px] font-semibold text-zinc-400 dark:text-zinc-500 uppercase tracking-wider mb-3",children:e})}var z=require("react/jsx-runtime");function w({className:e=""}){return(0,z.jsx)("div",{className:`mx-4 my-6 h-px bg-zinc-200 dark:bg-zinc-800 ${e}`})}var l=require("react/jsx-runtime");function P({label:e,value:t,className:r=""}){return(0,l.jsxs)("div",{className:`flex-1 rounded-xl bg-zinc-100 dark:bg-zinc-900 px-3 py-3 text-center ${r}`,children:[(0,l.jsx)("p",{className:"text-[10px] text-zinc-500 dark:text-zinc-400 font-medium mb-0.5",children:e}),(0,l.jsx)("p",{className:"text-lg font-bold tabular-nums text-zinc-900 dark:text-white",children:t.toLocaleString()})]})}var a=require("react/jsx-runtime");function S({message:e,icon:t}){return(0,a.jsxs)("div",{className:"flex flex-col items-center justify-center py-12 gap-2",children:[t||(0,a.jsxs)("svg",{width:"32",height:"32",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",className:"text-zinc-200 dark:text-zinc-700",children:[(0,a.jsx)("circle",{cx:"12",cy:"12",r:"10"}),(0,a.jsx)("path",{d:"M8 15h8"}),(0,a.jsx)("circle",{cx:"9",cy:"9",r:"1",fill:"currentColor",stroke:"none"}),(0,a.jsx)("circle",{cx:"15",cy:"9",r:"1",fill:"currentColor",stroke:"none"})]}),(0,a.jsx)("p",{className:"text-sm text-zinc-400 dark:text-zinc-500",children:e})]})}var d=require("react/jsx-runtime");function j(e,t=.08){let n=`<svg xmlns="http://www.w3.org/2000/svg" width="220" height="120">
|
|
3
|
+
<text x="10" y="45" font-family="system-ui,sans-serif" font-size="44" font-weight="900" fill="white" opacity="${t}">${e}</text>
|
|
4
|
+
<text x="120" y="100" font-family="system-ui,sans-serif" font-size="44" font-weight="900" fill="white" opacity="${t}">${e}</text>
|
|
5
|
+
</svg>`;return`url("data:image/svg+xml,${encodeURIComponent(n)}")`}function C({children:e,color:t="#0f172a",text:r="m1k",maxWidth:s=430,padding:n=12}){return(0,d.jsxs)("div",{className:"h-dvh w-full relative overflow-hidden",style:{backgroundColor:t,transition:"background-color 0.5s ease"},children:[(0,d.jsx)("div",{className:"absolute inset-0 pointer-events-none select-none",style:{backgroundImage:j(r),backgroundRepeat:"repeat",transform:"rotate(-12deg) scale(1.5)",transformOrigin:"center center"}}),(0,d.jsx)("div",{className:"relative z-10 h-full flex items-center justify-center mx-auto",style:{maxWidth:s,padding:n},children:e})]})}var f={blue:"#3b82f6",purple:"#8b5cf6",green:"#10b981",orange:"#f97316",pink:"#ec4899",red:"#ef4444",yellow:"#eab308",cyan:"#06b6d4",slate:"#0f172a",zinc:"#27272a"};var T=require("react");var o=require("react/jsx-runtime");function R({color:e,onClick:t,className:r=""}){return(0,o.jsx)("button",{onClick:t,className:`w-7 h-7 rounded-full border-2 border-white dark:border-zinc-700 shadow-sm transition-transform hover:scale-110 ${r}`,style:{backgroundColor:e},title:"Change theme"})}function $({open:e,onClose:t,current:r,onSelect:s,palette:n=f}){if((0,T.useEffect)(()=>{if(!e)return;let c=i=>{i.key==="Escape"&&t()};return window.addEventListener("keydown",c),()=>window.removeEventListener("keydown",c)},[e,t]),!e)return null;let E=Object.entries(n);return(0,o.jsxs)("div",{className:"fixed inset-0 z-50 flex items-end justify-center",onClick:t,children:[(0,o.jsx)("div",{className:"absolute inset-0 bg-black/40 backdrop-blur-sm"}),(0,o.jsxs)("div",{className:"relative z-10 w-full max-w-[406px] mb-3 mx-3 rounded-2xl bg-white dark:bg-zinc-900 shadow-2xl overflow-hidden",onClick:c=>c.stopPropagation(),children:[(0,o.jsxs)("div",{className:"px-4 pt-4 pb-2",children:[(0,o.jsx)("p",{className:"text-sm font-bold text-zinc-900 dark:text-white",children:"Theme Color"}),(0,o.jsx)("p",{className:"text-xs text-zinc-400 dark:text-zinc-500 mt-0.5",children:"Change the Watermark background"})]}),(0,o.jsx)("div",{className:"px-4 pb-3 grid grid-cols-5 gap-3 justify-items-center",children:E.map(([c,i])=>(0,o.jsx)("button",{onClick:()=>{s(i),t()},className:`relative w-11 h-11 rounded-full transition-all hover:scale-110 ${r===i?"ring-2 ring-offset-2 ring-offset-white dark:ring-offset-zinc-900":""}`,style:{backgroundColor:i,...r===i?{"--tw-ring-color":i}:{}},children:r===i&&(0,o.jsx)("div",{className:"absolute inset-0 flex items-center justify-center",children:(0,o.jsx)("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"white",strokeWidth:"3",strokeLinecap:"round",strokeLinejoin:"round",children:(0,o.jsx)("polyline",{points:"20 6 9 17 4 12"})})})},i))}),(0,o.jsx)("div",{className:"px-4 py-3 border-t border-zinc-100 dark:border-zinc-800",children:(0,o.jsx)("button",{onClick:t,className:"w-full py-2.5 rounded-xl bg-zinc-100 dark:bg-zinc-800 text-sm font-medium text-zinc-600 dark:text-zinc-400 hover:bg-zinc-200 dark:hover:bg-zinc-700 transition-colors",children:"Close"})})]})]})}var A={toss:"https://static.toss.im/dist/tps.css",pretendard:"https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css",inter:"https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;900&display=swap"},B={toss:'"Toss Product Sans", "Pretendard", system-ui, sans-serif',pretendard:'"Pretendard Variable", "Pretendard", system-ui, sans-serif',inter:'"Inter", system-ui, sans-serif'};0&&(module.exports={AppShell,AppShellContent,AppShellHeader,Divider,EmptyState,Section,SectionHeader,StatChip,Tab,TabBar,ThemeButton,ThemeDialog,Watermark,colors,fontFamily,fonts});
|
package/dist/index.mjs
CHANGED
|
@@ -1,265 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
function
|
|
6
|
-
children,
|
|
7
|
-
className = "",
|
|
8
|
-
maxWidth = 430,
|
|
9
|
-
style
|
|
10
|
-
}) {
|
|
11
|
-
return /* @__PURE__ */ jsx(
|
|
12
|
-
"div",
|
|
13
|
-
{
|
|
14
|
-
className: `w-full h-full flex flex-col bg-white dark:bg-zinc-950 shadow-2xl ring-1 ring-black/5 dark:ring-white/10 rounded-2xl overflow-hidden ${className}`,
|
|
15
|
-
style: { maxWidth, ...style },
|
|
16
|
-
children
|
|
17
|
-
}
|
|
18
|
-
);
|
|
19
|
-
}
|
|
20
|
-
function AppShellHeader({ children, className = "" }) {
|
|
21
|
-
return /* @__PURE__ */ jsx(
|
|
22
|
-
"header",
|
|
23
|
-
{
|
|
24
|
-
className: `sticky top-0 z-20 px-4 py-3 flex items-center justify-between border-b border-zinc-100 dark:border-zinc-800 bg-white/90 dark:bg-zinc-950/90 backdrop-blur-md rounded-t-2xl ${className}`,
|
|
25
|
-
children
|
|
26
|
-
}
|
|
27
|
-
);
|
|
28
|
-
}
|
|
29
|
-
function AppShellContent({ children, className = "" }) {
|
|
30
|
-
return /* @__PURE__ */ jsx("div", { className: `flex-1 overflow-y-auto scrollbar-hide ${className}`, children });
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// src/components/tab-bar.tsx
|
|
34
|
-
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
35
|
-
function TabBar({ children, className = "" }) {
|
|
36
|
-
return /* @__PURE__ */ jsx2(
|
|
37
|
-
"nav",
|
|
38
|
-
{
|
|
39
|
-
className: `sticky bottom-0 z-20 border-t border-zinc-200 dark:border-zinc-800 flex bg-white/90 dark:bg-zinc-950/90 backdrop-blur-md rounded-b-2xl ${className}`,
|
|
40
|
-
children
|
|
41
|
-
}
|
|
42
|
-
);
|
|
43
|
-
}
|
|
44
|
-
function Tab({ active, onClick, icon, label, activeColor }) {
|
|
45
|
-
return /* @__PURE__ */ jsxs(
|
|
46
|
-
"button",
|
|
47
|
-
{
|
|
48
|
-
onClick,
|
|
49
|
-
className: `flex-1 flex flex-col items-center gap-0.5 py-2.5 transition-colors ${!active ? "text-zinc-300 dark:text-zinc-600" : ""}`,
|
|
50
|
-
style: active ? { color: activeColor } : void 0,
|
|
51
|
-
children: [
|
|
52
|
-
icon,
|
|
53
|
-
/* @__PURE__ */ jsx2("span", { className: "text-[10px] font-medium", children: label })
|
|
54
|
-
]
|
|
55
|
-
}
|
|
56
|
-
);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// src/components/section.tsx
|
|
60
|
-
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
61
|
-
function Section({ children, className = "" }) {
|
|
62
|
-
return /* @__PURE__ */ jsx3("section", { className: `px-4 ${className}`, children });
|
|
63
|
-
}
|
|
64
|
-
function SectionHeader({ children }) {
|
|
65
|
-
return /* @__PURE__ */ jsx3("h2", { className: "text-[11px] font-semibold text-zinc-400 dark:text-zinc-500 uppercase tracking-wider mb-3", children });
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// src/components/divider.tsx
|
|
69
|
-
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
70
|
-
function Divider({ className = "" }) {
|
|
71
|
-
return /* @__PURE__ */ jsx4("div", { className: `mx-4 my-6 h-px bg-zinc-200 dark:bg-zinc-800 ${className}` });
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// src/components/stat-chip.tsx
|
|
75
|
-
import { jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
76
|
-
function StatChip({ label, value, className = "" }) {
|
|
77
|
-
return /* @__PURE__ */ jsxs2("div", { className: `flex-1 rounded-xl bg-zinc-100 dark:bg-zinc-900 px-3 py-3 text-center ${className}`, children: [
|
|
78
|
-
/* @__PURE__ */ jsx5("p", { className: "text-[10px] text-zinc-500 dark:text-zinc-400 font-medium mb-0.5", children: label }),
|
|
79
|
-
/* @__PURE__ */ jsx5("p", { className: "text-lg font-bold tabular-nums text-zinc-900 dark:text-white", children: value.toLocaleString() })
|
|
80
|
-
] });
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// src/components/empty-state.tsx
|
|
84
|
-
import { jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
85
|
-
function EmptyState({ message, icon }) {
|
|
86
|
-
return /* @__PURE__ */ jsxs3("div", { className: "flex flex-col items-center justify-center py-12 gap-2", children: [
|
|
87
|
-
icon || /* @__PURE__ */ jsxs3("svg", { width: "32", height: "32", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", className: "text-zinc-200 dark:text-zinc-700", children: [
|
|
88
|
-
/* @__PURE__ */ jsx6("circle", { cx: "12", cy: "12", r: "10" }),
|
|
89
|
-
/* @__PURE__ */ jsx6("path", { d: "M8 15h8" }),
|
|
90
|
-
/* @__PURE__ */ jsx6("circle", { cx: "9", cy: "9", r: "1", fill: "currentColor", stroke: "none" }),
|
|
91
|
-
/* @__PURE__ */ jsx6("circle", { cx: "15", cy: "9", r: "1", fill: "currentColor", stroke: "none" })
|
|
92
|
-
] }),
|
|
93
|
-
/* @__PURE__ */ jsx6("p", { className: "text-sm text-zinc-400 dark:text-zinc-500", children: message })
|
|
94
|
-
] });
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// src/components/watermark.tsx
|
|
98
|
-
import { jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
99
|
-
function buildSvgPattern(text, opacity = 0.08) {
|
|
100
|
-
const w = 220;
|
|
101
|
-
const h = 120;
|
|
102
|
-
const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${w}" height="${h}">
|
|
103
|
-
<text x="10" y="45" font-family="system-ui,sans-serif" font-size="44" font-weight="900" fill="white" opacity="${opacity}">${text}</text>
|
|
104
|
-
<text x="120" y="100" font-family="system-ui,sans-serif" font-size="44" font-weight="900" fill="white" opacity="${opacity}">${text}</text>
|
|
105
|
-
</svg>`;
|
|
106
|
-
return `url("data:image/svg+xml,${encodeURIComponent(svg)}")`;
|
|
107
|
-
}
|
|
108
|
-
function Watermark({
|
|
109
|
-
children,
|
|
110
|
-
color = "#0f172a",
|
|
111
|
-
text = "m1k",
|
|
112
|
-
maxWidth = 430,
|
|
113
|
-
padding = 12
|
|
114
|
-
}) {
|
|
115
|
-
return /* @__PURE__ */ jsxs4(
|
|
116
|
-
"div",
|
|
117
|
-
{
|
|
118
|
-
className: "h-dvh w-full relative overflow-hidden",
|
|
119
|
-
style: { backgroundColor: color, transition: "background-color 0.5s ease" },
|
|
120
|
-
children: [
|
|
121
|
-
/* @__PURE__ */ jsx7(
|
|
122
|
-
"div",
|
|
123
|
-
{
|
|
124
|
-
className: "absolute inset-0 pointer-events-none select-none",
|
|
125
|
-
style: {
|
|
126
|
-
backgroundImage: buildSvgPattern(text),
|
|
127
|
-
backgroundRepeat: "repeat",
|
|
128
|
-
transform: "rotate(-12deg) scale(1.5)",
|
|
129
|
-
transformOrigin: "center center"
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
),
|
|
133
|
-
/* @__PURE__ */ jsx7(
|
|
134
|
-
"div",
|
|
135
|
-
{
|
|
136
|
-
className: "relative z-10 h-full flex items-center justify-center mx-auto",
|
|
137
|
-
style: { maxWidth, padding },
|
|
138
|
-
children
|
|
139
|
-
}
|
|
140
|
-
)
|
|
141
|
-
]
|
|
142
|
-
}
|
|
143
|
-
);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
// src/components/colors.ts
|
|
147
|
-
var colors = {
|
|
148
|
-
blue: "#3b82f6",
|
|
149
|
-
purple: "#8b5cf6",
|
|
150
|
-
green: "#10b981",
|
|
151
|
-
orange: "#f97316",
|
|
152
|
-
pink: "#ec4899",
|
|
153
|
-
red: "#ef4444",
|
|
154
|
-
yellow: "#eab308",
|
|
155
|
-
cyan: "#06b6d4",
|
|
156
|
-
slate: "#0f172a",
|
|
157
|
-
zinc: "#27272a"
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
// src/components/theme-picker.tsx
|
|
161
|
-
import { useEffect } from "react";
|
|
162
|
-
import { jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
163
|
-
function ThemeButton({ color, onClick, className = "" }) {
|
|
164
|
-
return /* @__PURE__ */ jsx8(
|
|
165
|
-
"button",
|
|
166
|
-
{
|
|
167
|
-
onClick,
|
|
168
|
-
className: `w-7 h-7 rounded-full border-2 border-white dark:border-zinc-700 shadow-sm transition-transform hover:scale-110 ${className}`,
|
|
169
|
-
style: { backgroundColor: color },
|
|
170
|
-
title: "Change theme"
|
|
171
|
-
}
|
|
172
|
-
);
|
|
173
|
-
}
|
|
174
|
-
function ThemeDialog({
|
|
175
|
-
open,
|
|
176
|
-
onClose,
|
|
177
|
-
current,
|
|
178
|
-
onSelect,
|
|
179
|
-
palette = colors
|
|
180
|
-
}) {
|
|
181
|
-
useEffect(() => {
|
|
182
|
-
if (!open) return;
|
|
183
|
-
const handler = (e) => {
|
|
184
|
-
if (e.key === "Escape") onClose();
|
|
185
|
-
};
|
|
186
|
-
window.addEventListener("keydown", handler);
|
|
187
|
-
return () => window.removeEventListener("keydown", handler);
|
|
188
|
-
}, [open, onClose]);
|
|
189
|
-
if (!open) return null;
|
|
190
|
-
const entries = Object.entries(palette);
|
|
191
|
-
return /* @__PURE__ */ jsxs5("div", { className: "fixed inset-0 z-50 flex items-end justify-center", onClick: onClose, children: [
|
|
192
|
-
/* @__PURE__ */ jsx8("div", { className: "absolute inset-0 bg-black/40 backdrop-blur-sm" }),
|
|
193
|
-
/* @__PURE__ */ jsxs5(
|
|
194
|
-
"div",
|
|
195
|
-
{
|
|
196
|
-
className: "relative z-10 w-full max-w-[406px] mb-3 mx-3 rounded-2xl bg-white dark:bg-zinc-900 shadow-2xl overflow-hidden",
|
|
197
|
-
onClick: (e) => e.stopPropagation(),
|
|
198
|
-
children: [
|
|
199
|
-
/* @__PURE__ */ jsxs5("div", { className: "px-4 pt-4 pb-2", children: [
|
|
200
|
-
/* @__PURE__ */ jsx8("p", { className: "text-sm font-bold text-zinc-900 dark:text-white", children: "Theme Color" }),
|
|
201
|
-
/* @__PURE__ */ jsx8("p", { className: "text-xs text-zinc-400 dark:text-zinc-500 mt-0.5", children: "Change the Watermark background" })
|
|
202
|
-
] }),
|
|
203
|
-
/* @__PURE__ */ jsx8("div", { className: "px-4 pb-3 grid grid-cols-5 gap-3 justify-items-center", children: entries.map(([name, value]) => /* @__PURE__ */ jsx8(
|
|
204
|
-
"button",
|
|
205
|
-
{
|
|
206
|
-
onClick: () => {
|
|
207
|
-
onSelect(value);
|
|
208
|
-
onClose();
|
|
209
|
-
},
|
|
210
|
-
className: `relative w-11 h-11 rounded-full transition-all hover:scale-110 ${current === value ? "ring-2 ring-offset-2 ring-offset-white dark:ring-offset-zinc-900" : ""}`,
|
|
211
|
-
style: {
|
|
212
|
-
backgroundColor: value,
|
|
213
|
-
...current === value ? { ["--tw-ring-color"]: value } : {}
|
|
214
|
-
},
|
|
215
|
-
children: current === value && /* @__PURE__ */ jsx8("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsx8("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "white", strokeWidth: "3", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx8("polyline", { points: "20 6 9 17 4 12" }) }) })
|
|
216
|
-
},
|
|
217
|
-
value
|
|
218
|
-
)) }),
|
|
219
|
-
/* @__PURE__ */ jsx8("div", { className: "px-4 py-3 border-t border-zinc-100 dark:border-zinc-800", children: /* @__PURE__ */ jsx8(
|
|
220
|
-
"button",
|
|
221
|
-
{
|
|
222
|
-
onClick: onClose,
|
|
223
|
-
className: "w-full py-2.5 rounded-xl bg-zinc-100 dark:bg-zinc-800 text-sm font-medium text-zinc-600 dark:text-zinc-400 hover:bg-zinc-200 dark:hover:bg-zinc-700 transition-colors",
|
|
224
|
-
children: "Close"
|
|
225
|
-
}
|
|
226
|
-
) })
|
|
227
|
-
]
|
|
228
|
-
}
|
|
229
|
-
)
|
|
230
|
-
] });
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
// src/components/fonts.ts
|
|
234
|
-
var fonts = {
|
|
235
|
-
/** Toss Product Sans — from toss.im (free for commercial use) */
|
|
236
|
-
toss: "https://static.toss.im/dist/tps.css",
|
|
237
|
-
/** Pretendard — popular Korean web font */
|
|
238
|
-
pretendard: "https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css",
|
|
239
|
-
/** Inter — clean Latin sans-serif */
|
|
240
|
-
inter: "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;900&display=swap"
|
|
241
|
-
};
|
|
242
|
-
var fontFamily = {
|
|
243
|
-
toss: '"Toss Product Sans", "Pretendard", system-ui, sans-serif',
|
|
244
|
-
pretendard: '"Pretendard Variable", "Pretendard", system-ui, sans-serif',
|
|
245
|
-
inter: '"Inter", system-ui, sans-serif'
|
|
246
|
-
};
|
|
247
|
-
export {
|
|
248
|
-
AppShell,
|
|
249
|
-
AppShellContent,
|
|
250
|
-
AppShellHeader,
|
|
251
|
-
Divider,
|
|
252
|
-
EmptyState,
|
|
253
|
-
Section,
|
|
254
|
-
SectionHeader,
|
|
255
|
-
StatChip,
|
|
256
|
-
Tab,
|
|
257
|
-
TabBar,
|
|
258
|
-
ThemeButton,
|
|
259
|
-
ThemeDialog,
|
|
260
|
-
Watermark,
|
|
261
|
-
colors,
|
|
262
|
-
fontFamily,
|
|
263
|
-
fonts
|
|
264
|
-
};
|
|
265
|
-
//# sourceMappingURL=index.mjs.map
|
|
2
|
+
import{jsx as p}from"react/jsx-runtime";function g({children:e,className:t="",maxWidth:r=430,style:s}){return p("div",{className:`w-full h-full flex flex-col bg-white dark:bg-zinc-950 shadow-2xl ring-1 ring-black/5 dark:ring-white/10 rounded-2xl overflow-hidden ${t}`,style:{maxWidth:r,...s},children:e})}function y({children:e,className:t=""}){return p("header",{className:`sticky top-0 z-20 px-4 py-3 flex items-center justify-between border-b border-zinc-100 dark:border-zinc-800 bg-white/90 dark:bg-zinc-950/90 backdrop-blur-md rounded-t-2xl ${t}`,children:e})}function k({children:e,className:t=""}){return p("div",{className:`flex-1 overflow-y-auto scrollbar-hide ${t}`,children:e})}import{jsx as m,jsxs as w}from"react/jsx-runtime";function v({children:e,className:t=""}){return m("nav",{className:`sticky bottom-0 z-20 border-t border-zinc-200 dark:border-zinc-800 flex bg-white/90 dark:bg-zinc-950/90 backdrop-blur-md rounded-b-2xl ${t}`,children:e})}function N({active:e,onClick:t,icon:r,label:s,activeColor:i}){return w("button",{onClick:t,className:`flex-1 flex flex-col items-center gap-0.5 py-2.5 transition-colors ${e?"":"text-zinc-300 dark:text-zinc-600"}`,style:e?{color:i}:void 0,children:[r,m("span",{className:"text-[10px] font-medium",children:s})]})}import{jsx as f}from"react/jsx-runtime";function z({children:e,className:t=""}){return f("section",{className:`px-4 ${t}`,children:e})}function P({children:e}){return f("h2",{className:"text-[11px] font-semibold text-zinc-400 dark:text-zinc-500 uppercase tracking-wider mb-3",children:e})}import{jsx as C}from"react/jsx-runtime";function S({className:e=""}){return C("div",{className:`mx-4 my-6 h-px bg-zinc-200 dark:bg-zinc-800 ${e}`})}import{jsx as x,jsxs as R}from"react/jsx-runtime";function T({label:e,value:t,className:r=""}){return R("div",{className:`flex-1 rounded-xl bg-zinc-100 dark:bg-zinc-900 px-3 py-3 text-center ${r}`,children:[x("p",{className:"text-[10px] text-zinc-500 dark:text-zinc-400 font-medium mb-0.5",children:e}),x("p",{className:"text-lg font-bold tabular-nums text-zinc-900 dark:text-white",children:t.toLocaleString()})]})}import{jsx as c,jsxs as h}from"react/jsx-runtime";function $({message:e,icon:t}){return h("div",{className:"flex flex-col items-center justify-center py-12 gap-2",children:[t||h("svg",{width:"32",height:"32",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",className:"text-zinc-200 dark:text-zinc-700",children:[c("circle",{cx:"12",cy:"12",r:"10"}),c("path",{d:"M8 15h8"}),c("circle",{cx:"9",cy:"9",r:"1",fill:"currentColor",stroke:"none"}),c("circle",{cx:"15",cy:"9",r:"1",fill:"currentColor",stroke:"none"})]}),c("p",{className:"text-sm text-zinc-400 dark:text-zinc-500",children:e})]})}import{jsx as b,jsxs as E}from"react/jsx-runtime";function A(e,t=.08){let i=`<svg xmlns="http://www.w3.org/2000/svg" width="220" height="120">
|
|
3
|
+
<text x="10" y="45" font-family="system-ui,sans-serif" font-size="44" font-weight="900" fill="white" opacity="${t}">${e}</text>
|
|
4
|
+
<text x="120" y="100" font-family="system-ui,sans-serif" font-size="44" font-weight="900" fill="white" opacity="${t}">${e}</text>
|
|
5
|
+
</svg>`;return`url("data:image/svg+xml,${encodeURIComponent(i)}")`}function B({children:e,color:t="#0f172a",text:r="m1k",maxWidth:s=430,padding:i=12}){return E("div",{className:"h-dvh w-full relative overflow-hidden",style:{backgroundColor:t,transition:"background-color 0.5s ease"},children:[b("div",{className:"absolute inset-0 pointer-events-none select-none",style:{backgroundImage:A(r),backgroundRepeat:"repeat",transform:"rotate(-12deg) scale(1.5)",transformOrigin:"center center"}}),b("div",{className:"relative z-10 h-full flex items-center justify-center mx-auto",style:{maxWidth:s,padding:i},children:e})]})}var l={blue:"#3b82f6",purple:"#8b5cf6",green:"#10b981",orange:"#f97316",pink:"#ec4899",red:"#ef4444",yellow:"#eab308",cyan:"#06b6d4",slate:"#0f172a",zinc:"#27272a"};import{useEffect as H}from"react";import{jsx as o,jsxs as d}from"react/jsx-runtime";function W({color:e,onClick:t,className:r=""}){return o("button",{onClick:t,className:`w-7 h-7 rounded-full border-2 border-white dark:border-zinc-700 shadow-sm transition-transform hover:scale-110 ${r}`,style:{backgroundColor:e},title:"Change theme"})}function D({open:e,onClose:t,current:r,onSelect:s,palette:i=l}){if(H(()=>{if(!e)return;let a=n=>{n.key==="Escape"&&t()};return window.addEventListener("keydown",a),()=>window.removeEventListener("keydown",a)},[e,t]),!e)return null;let u=Object.entries(i);return d("div",{className:"fixed inset-0 z-50 flex items-end justify-center",onClick:t,children:[o("div",{className:"absolute inset-0 bg-black/40 backdrop-blur-sm"}),d("div",{className:"relative z-10 w-full max-w-[406px] mb-3 mx-3 rounded-2xl bg-white dark:bg-zinc-900 shadow-2xl overflow-hidden",onClick:a=>a.stopPropagation(),children:[d("div",{className:"px-4 pt-4 pb-2",children:[o("p",{className:"text-sm font-bold text-zinc-900 dark:text-white",children:"Theme Color"}),o("p",{className:"text-xs text-zinc-400 dark:text-zinc-500 mt-0.5",children:"Change the Watermark background"})]}),o("div",{className:"px-4 pb-3 grid grid-cols-5 gap-3 justify-items-center",children:u.map(([a,n])=>o("button",{onClick:()=>{s(n),t()},className:`relative w-11 h-11 rounded-full transition-all hover:scale-110 ${r===n?"ring-2 ring-offset-2 ring-offset-white dark:ring-offset-zinc-900":""}`,style:{backgroundColor:n,...r===n?{"--tw-ring-color":n}:{}},children:r===n&&o("div",{className:"absolute inset-0 flex items-center justify-center",children:o("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"white",strokeWidth:"3",strokeLinecap:"round",strokeLinejoin:"round",children:o("polyline",{points:"20 6 9 17 4 12"})})})},n))}),o("div",{className:"px-4 py-3 border-t border-zinc-100 dark:border-zinc-800",children:o("button",{onClick:t,className:"w-full py-2.5 rounded-xl bg-zinc-100 dark:bg-zinc-800 text-sm font-medium text-zinc-600 dark:text-zinc-400 hover:bg-zinc-200 dark:hover:bg-zinc-700 transition-colors",children:"Close"})})]})]})}var L={toss:"https://static.toss.im/dist/tps.css",pretendard:"https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css",inter:"https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;900&display=swap"},F={toss:'"Toss Product Sans", "Pretendard", system-ui, sans-serif',pretendard:'"Pretendard Variable", "Pretendard", system-ui, sans-serif',inter:'"Inter", system-ui, sans-serif'};export{g as AppShell,k as AppShellContent,y as AppShellHeader,S as Divider,$ as EmptyState,z as Section,P as SectionHeader,T as StatChip,N as Tab,v as TabBar,W as ThemeButton,D as ThemeDialog,B as Watermark,l as colors,F as fontFamily,L as fonts};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@m1kapp/ui",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "Mobile-first app shell UI components for side projects",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"license": "MIT",
|
|
48
48
|
"repository": {
|
|
49
49
|
"type": "git",
|
|
50
|
-
"url": "https://github.com/
|
|
50
|
+
"url": "https://github.com/m1kapp/ui"
|
|
51
51
|
},
|
|
52
52
|
"homepage": "https://m1k.app"
|
|
53
53
|
}
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/components/app-shell.tsx","../src/components/tab-bar.tsx","../src/components/section.tsx","../src/components/divider.tsx","../src/components/stat-chip.tsx","../src/components/empty-state.tsx","../src/components/watermark.tsx","../src/components/colors.ts","../src/components/theme-picker.tsx","../src/components/fonts.ts"],"sourcesContent":["export { AppShell, AppShellHeader, AppShellContent } from \"./components/app-shell\";\nexport type { AppShellProps, AppShellHeaderProps, AppShellContentProps } from \"./components/app-shell\";\n\nexport { TabBar, Tab } from \"./components/tab-bar\";\nexport type { TabBarProps, TabProps } from \"./components/tab-bar\";\n\nexport { Section, SectionHeader } from \"./components/section\";\nexport type { SectionProps, SectionHeaderProps } from \"./components/section\";\n\nexport { Divider } from \"./components/divider\";\n\nexport { StatChip } from \"./components/stat-chip\";\nexport type { StatChipProps } from \"./components/stat-chip\";\n\nexport { EmptyState } from \"./components/empty-state\";\nexport type { EmptyStateProps } from \"./components/empty-state\";\n\nexport { Watermark } from \"./components/watermark\";\nexport type { WatermarkProps } from \"./components/watermark\";\n\nexport { colors } from \"./components/colors\";\nexport type { ColorName } from \"./components/colors\";\n\nexport { ThemeButton, ThemeDialog } from \"./components/theme-picker\";\nexport type { ThemeButtonProps, ThemeDialogProps } from \"./components/theme-picker\";\n\nexport { fonts, fontFamily } from \"./components/fonts\";\nexport type { FontName } from \"./components/fonts\";\n","import { type ReactNode, type CSSProperties } from \"react\";\n\nexport interface AppShellProps {\n children: ReactNode;\n className?: string;\n /** Max width of the shell. Default: 430px */\n maxWidth?: number;\n style?: CSSProperties;\n}\n\n/**\n * Mobile app-like container with rounded corners, shadow, and ring.\n * Centers content and constrains width for a phone-like viewport.\n */\nexport function AppShell({\n children,\n className = \"\",\n maxWidth = 430,\n style,\n}: AppShellProps) {\n return (\n <div\n className={`w-full h-full flex flex-col bg-white dark:bg-zinc-950 shadow-2xl ring-1 ring-black/5 dark:ring-white/10 rounded-2xl overflow-hidden ${className}`}\n style={{ maxWidth, ...style }}\n >\n {children}\n </div>\n );\n}\n\nexport interface AppShellHeaderProps {\n children: ReactNode;\n className?: string;\n}\n\n/**\n * Sticky top header with blur backdrop.\n */\nexport function AppShellHeader({ children, className = \"\" }: AppShellHeaderProps) {\n return (\n <header\n className={`sticky top-0 z-20 px-4 py-3 flex items-center justify-between border-b border-zinc-100 dark:border-zinc-800 bg-white/90 dark:bg-zinc-950/90 backdrop-blur-md rounded-t-2xl ${className}`}\n >\n {children}\n </header>\n );\n}\n\nexport interface AppShellContentProps {\n children: ReactNode;\n className?: string;\n}\n\n/**\n * Scrollable main content area.\n */\nexport function AppShellContent({ children, className = \"\" }: AppShellContentProps) {\n return (\n <div className={`flex-1 overflow-y-auto scrollbar-hide ${className}`}>\n {children}\n </div>\n );\n}\n","import { type ReactNode } from \"react\";\n\nexport interface TabBarProps {\n children: ReactNode;\n className?: string;\n}\n\n/**\n * Sticky bottom navigation tab bar.\n */\nexport function TabBar({ children, className = \"\" }: TabBarProps) {\n return (\n <nav\n className={`sticky bottom-0 z-20 border-t border-zinc-200 dark:border-zinc-800 flex bg-white/90 dark:bg-zinc-950/90 backdrop-blur-md rounded-b-2xl ${className}`}\n >\n {children}\n </nav>\n );\n}\n\nexport interface TabProps {\n active: boolean;\n onClick: () => void;\n icon: ReactNode;\n label: string;\n /** Active tab color. Default: current text color */\n activeColor?: string;\n}\n\n/**\n * Individual tab button for the TabBar.\n */\nexport function Tab({ active, onClick, icon, label, activeColor }: TabProps) {\n return (\n <button\n onClick={onClick}\n className={`flex-1 flex flex-col items-center gap-0.5 py-2.5 transition-colors ${\n !active ? \"text-zinc-300 dark:text-zinc-600\" : \"\"\n }`}\n style={active ? { color: activeColor } : undefined}\n >\n {icon}\n <span className=\"text-[10px] font-medium\">{label}</span>\n </button>\n );\n}\n","import { type ReactNode } from \"react\";\n\nexport interface SectionProps {\n children: ReactNode;\n className?: string;\n}\n\n/**\n * Padded section wrapper (px-4).\n */\nexport function Section({ children, className = \"\" }: SectionProps) {\n return <section className={`px-4 ${className}`}>{children}</section>;\n}\n\nexport interface SectionHeaderProps {\n children: ReactNode;\n}\n\n/**\n * Small uppercase section title.\n */\nexport function SectionHeader({ children }: SectionHeaderProps) {\n return (\n <h2 className=\"text-[11px] font-semibold text-zinc-400 dark:text-zinc-500 uppercase tracking-wider mb-3\">\n {children}\n </h2>\n );\n}\n","/**\n * Horizontal divider line with margin.\n */\nexport function Divider({ className = \"\" }: { className?: string }) {\n return <div className={`mx-4 my-6 h-px bg-zinc-200 dark:bg-zinc-800 ${className}`} />;\n}\n","export interface StatChipProps {\n label: string;\n value: number;\n className?: string;\n}\n\n/**\n * Compact stat display chip with label and number.\n */\nexport function StatChip({ label, value, className = \"\" }: StatChipProps) {\n return (\n <div className={`flex-1 rounded-xl bg-zinc-100 dark:bg-zinc-900 px-3 py-3 text-center ${className}`}>\n <p className=\"text-[10px] text-zinc-500 dark:text-zinc-400 font-medium mb-0.5\">\n {label}\n </p>\n <p className=\"text-lg font-bold tabular-nums text-zinc-900 dark:text-white\">\n {value.toLocaleString()}\n </p>\n </div>\n );\n}\n","import { type ReactNode } from \"react\";\n\nexport interface EmptyStateProps {\n message: string;\n icon?: ReactNode;\n}\n\n/**\n * Empty state placeholder with icon and message.\n */\nexport function EmptyState({ message, icon }: EmptyStateProps) {\n return (\n <div className=\"flex flex-col items-center justify-center py-12 gap-2\">\n {icon || (\n <svg width=\"32\" height=\"32\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" className=\"text-zinc-200 dark:text-zinc-700\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M8 15h8\" />\n <circle cx=\"9\" cy=\"9\" r=\"1\" fill=\"currentColor\" stroke=\"none\" />\n <circle cx=\"15\" cy=\"9\" r=\"1\" fill=\"currentColor\" stroke=\"none\" />\n </svg>\n )}\n <p className=\"text-sm text-zinc-400 dark:text-zinc-500\">{message}</p>\n </div>\n );\n}\n","import { type ReactNode } from \"react\";\n\nexport interface WatermarkProps {\n children: ReactNode;\n /** Background color */\n color?: string;\n /** Watermark text. Default: \"m1k\" */\n text?: string;\n /** Max width of content area. Default: 430 */\n maxWidth?: number;\n /** Padding around the app shell. Default: 12px */\n padding?: number;\n}\n\nfunction buildSvgPattern(text: string, opacity: number = 0.08): string {\n const w = 220;\n const h = 120;\n const svg = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${w}\" height=\"${h}\">\n <text x=\"10\" y=\"45\" font-family=\"system-ui,sans-serif\" font-size=\"44\" font-weight=\"900\" fill=\"white\" opacity=\"${opacity}\">${text}</text>\n <text x=\"120\" y=\"100\" font-family=\"system-ui,sans-serif\" font-size=\"44\" font-weight=\"900\" fill=\"white\" opacity=\"${opacity}\">${text}</text>\n </svg>`;\n return `url(\"data:image/svg+xml,${encodeURIComponent(svg)}\")`;\n}\n\n/**\n * Full-screen colored background with repeating text watermark pattern.\n * Wraps the AppShell and provides the \"floating app\" look.\n */\nexport function Watermark({\n children,\n color = \"#0f172a\",\n text = \"m1k\",\n maxWidth = 430,\n padding = 12,\n}: WatermarkProps) {\n return (\n <div\n className=\"h-dvh w-full relative overflow-hidden\"\n style={{ backgroundColor: color, transition: \"background-color 0.5s ease\" }}\n >\n <div\n className=\"absolute inset-0 pointer-events-none select-none\"\n style={{\n backgroundImage: buildSvgPattern(text),\n backgroundRepeat: \"repeat\",\n transform: \"rotate(-12deg) scale(1.5)\",\n transformOrigin: \"center center\",\n }}\n />\n <div\n className=\"relative z-10 h-full flex items-center justify-center mx-auto\"\n style={{ maxWidth, padding }}\n >\n {children}\n </div>\n </div>\n );\n}\n","export const colors = {\n blue: \"#3b82f6\",\n purple: \"#8b5cf6\",\n green: \"#10b981\",\n orange: \"#f97316\",\n pink: \"#ec4899\",\n red: \"#ef4444\",\n yellow: \"#eab308\",\n cyan: \"#06b6d4\",\n slate: \"#0f172a\",\n zinc: \"#27272a\",\n} as const;\n\nexport type ColorName = keyof typeof colors;\n","import { type ReactNode, useState, useEffect } from \"react\";\nimport { colors } from \"./colors\";\n\nexport interface ThemeButtonProps {\n color: string;\n onClick: () => void;\n className?: string;\n}\n\n/**\n * Small circular button showing the current theme color.\n * Designed for the AppShellHeader top-right slot.\n */\nexport function ThemeButton({ color, onClick, className = \"\" }: ThemeButtonProps) {\n return (\n <button\n onClick={onClick}\n className={`w-7 h-7 rounded-full border-2 border-white dark:border-zinc-700 shadow-sm transition-transform hover:scale-110 ${className}`}\n style={{ backgroundColor: color }}\n title=\"Change theme\"\n />\n );\n}\n\nexport interface ThemeDialogProps {\n open: boolean;\n onClose: () => void;\n current: string;\n onSelect: (color: string) => void;\n /** Override the color palette. Defaults to built-in colors. */\n palette?: Record<string, string>;\n}\n\n/**\n * Bottom-sheet style color picker dialog.\n * Shows a 5-column grid of color circles with check on the active one.\n */\nexport function ThemeDialog({\n open,\n onClose,\n current,\n onSelect,\n palette = colors,\n}: ThemeDialogProps) {\n useEffect(() => {\n if (!open) return;\n const handler = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") onClose();\n };\n window.addEventListener(\"keydown\", handler);\n return () => window.removeEventListener(\"keydown\", handler);\n }, [open, onClose]);\n\n if (!open) return null;\n\n const entries = Object.entries(palette);\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-end justify-center\" onClick={onClose}>\n <div className=\"absolute inset-0 bg-black/40 backdrop-blur-sm\" />\n <div\n className=\"relative z-10 w-full max-w-[406px] mb-3 mx-3 rounded-2xl bg-white dark:bg-zinc-900 shadow-2xl overflow-hidden\"\n onClick={(e) => e.stopPropagation()}\n >\n <div className=\"px-4 pt-4 pb-2\">\n <p className=\"text-sm font-bold text-zinc-900 dark:text-white\">Theme Color</p>\n <p className=\"text-xs text-zinc-400 dark:text-zinc-500 mt-0.5\">\n Change the Watermark background\n </p>\n </div>\n\n <div className=\"px-4 pb-3 grid grid-cols-5 gap-3 justify-items-center\">\n {entries.map(([name, value]) => (\n <button\n key={value}\n onClick={() => {\n onSelect(value);\n onClose();\n }}\n className={`relative w-11 h-11 rounded-full transition-all hover:scale-110 ${\n current === value\n ? \"ring-2 ring-offset-2 ring-offset-white dark:ring-offset-zinc-900\"\n : \"\"\n }`}\n style={{\n backgroundColor: value,\n ...(current === value ? { [\"--tw-ring-color\" as string]: value } : {}),\n }}\n >\n {current === value && (\n <div className=\"absolute inset-0 flex items-center justify-center\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"white\" strokeWidth=\"3\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n </div>\n )}\n </button>\n ))}\n </div>\n\n <div className=\"px-4 py-3 border-t border-zinc-100 dark:border-zinc-800\">\n <button\n onClick={onClose}\n className=\"w-full py-2.5 rounded-xl bg-zinc-100 dark:bg-zinc-800 text-sm font-medium text-zinc-600 dark:text-zinc-400 hover:bg-zinc-200 dark:hover:bg-zinc-700 transition-colors\"\n >\n Close\n </button>\n </div>\n </div>\n </div>\n );\n}\n","/**\n * Font presets for @m1kapp/ui.\n * These return CSS @import strings to load fonts from official CDNs.\n * No font files are bundled — only references to the original sources.\n */\n\nexport const fonts = {\n /** Toss Product Sans — from toss.im (free for commercial use) */\n toss: 'https://static.toss.im/dist/tps.css',\n /** Pretendard — popular Korean web font */\n pretendard: 'https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css',\n /** Inter — clean Latin sans-serif */\n inter: 'https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;900&display=swap',\n} as const;\n\nexport type FontName = keyof typeof fonts;\n\n/**\n * Returns a <link> href for the given font preset.\n * Usage in your HTML head or via a <link> tag:\n *\n * ```tsx\n * <link rel=\"stylesheet\" href={fonts.toss} />\n * ```\n *\n * Or in CSS:\n * ```css\n * @import url(\"https://static.toss.im/dist/tps.css\");\n * body { font-family: \"Toss Product Sans\", sans-serif; }\n * ```\n */\nexport const fontFamily = {\n toss: '\"Toss Product Sans\", \"Pretendard\", system-ui, sans-serif',\n pretendard: '\"Pretendard Variable\", \"Pretendard\", system-ui, sans-serif',\n inter: '\"Inter\", system-ui, sans-serif',\n} as const;\n"],"mappings":"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","names":["import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime"]}
|
package/dist/index.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/app-shell.tsx","../src/components/tab-bar.tsx","../src/components/section.tsx","../src/components/divider.tsx","../src/components/stat-chip.tsx","../src/components/empty-state.tsx","../src/components/watermark.tsx","../src/components/colors.ts","../src/components/theme-picker.tsx","../src/components/fonts.ts"],"sourcesContent":["import { type ReactNode, type CSSProperties } from \"react\";\n\nexport interface AppShellProps {\n children: ReactNode;\n className?: string;\n /** Max width of the shell. Default: 430px */\n maxWidth?: number;\n style?: CSSProperties;\n}\n\n/**\n * Mobile app-like container with rounded corners, shadow, and ring.\n * Centers content and constrains width for a phone-like viewport.\n */\nexport function AppShell({\n children,\n className = \"\",\n maxWidth = 430,\n style,\n}: AppShellProps) {\n return (\n <div\n className={`w-full h-full flex flex-col bg-white dark:bg-zinc-950 shadow-2xl ring-1 ring-black/5 dark:ring-white/10 rounded-2xl overflow-hidden ${className}`}\n style={{ maxWidth, ...style }}\n >\n {children}\n </div>\n );\n}\n\nexport interface AppShellHeaderProps {\n children: ReactNode;\n className?: string;\n}\n\n/**\n * Sticky top header with blur backdrop.\n */\nexport function AppShellHeader({ children, className = \"\" }: AppShellHeaderProps) {\n return (\n <header\n className={`sticky top-0 z-20 px-4 py-3 flex items-center justify-between border-b border-zinc-100 dark:border-zinc-800 bg-white/90 dark:bg-zinc-950/90 backdrop-blur-md rounded-t-2xl ${className}`}\n >\n {children}\n </header>\n );\n}\n\nexport interface AppShellContentProps {\n children: ReactNode;\n className?: string;\n}\n\n/**\n * Scrollable main content area.\n */\nexport function AppShellContent({ children, className = \"\" }: AppShellContentProps) {\n return (\n <div className={`flex-1 overflow-y-auto scrollbar-hide ${className}`}>\n {children}\n </div>\n );\n}\n","import { type ReactNode } from \"react\";\n\nexport interface TabBarProps {\n children: ReactNode;\n className?: string;\n}\n\n/**\n * Sticky bottom navigation tab bar.\n */\nexport function TabBar({ children, className = \"\" }: TabBarProps) {\n return (\n <nav\n className={`sticky bottom-0 z-20 border-t border-zinc-200 dark:border-zinc-800 flex bg-white/90 dark:bg-zinc-950/90 backdrop-blur-md rounded-b-2xl ${className}`}\n >\n {children}\n </nav>\n );\n}\n\nexport interface TabProps {\n active: boolean;\n onClick: () => void;\n icon: ReactNode;\n label: string;\n /** Active tab color. Default: current text color */\n activeColor?: string;\n}\n\n/**\n * Individual tab button for the TabBar.\n */\nexport function Tab({ active, onClick, icon, label, activeColor }: TabProps) {\n return (\n <button\n onClick={onClick}\n className={`flex-1 flex flex-col items-center gap-0.5 py-2.5 transition-colors ${\n !active ? \"text-zinc-300 dark:text-zinc-600\" : \"\"\n }`}\n style={active ? { color: activeColor } : undefined}\n >\n {icon}\n <span className=\"text-[10px] font-medium\">{label}</span>\n </button>\n );\n}\n","import { type ReactNode } from \"react\";\n\nexport interface SectionProps {\n children: ReactNode;\n className?: string;\n}\n\n/**\n * Padded section wrapper (px-4).\n */\nexport function Section({ children, className = \"\" }: SectionProps) {\n return <section className={`px-4 ${className}`}>{children}</section>;\n}\n\nexport interface SectionHeaderProps {\n children: ReactNode;\n}\n\n/**\n * Small uppercase section title.\n */\nexport function SectionHeader({ children }: SectionHeaderProps) {\n return (\n <h2 className=\"text-[11px] font-semibold text-zinc-400 dark:text-zinc-500 uppercase tracking-wider mb-3\">\n {children}\n </h2>\n );\n}\n","/**\n * Horizontal divider line with margin.\n */\nexport function Divider({ className = \"\" }: { className?: string }) {\n return <div className={`mx-4 my-6 h-px bg-zinc-200 dark:bg-zinc-800 ${className}`} />;\n}\n","export interface StatChipProps {\n label: string;\n value: number;\n className?: string;\n}\n\n/**\n * Compact stat display chip with label and number.\n */\nexport function StatChip({ label, value, className = \"\" }: StatChipProps) {\n return (\n <div className={`flex-1 rounded-xl bg-zinc-100 dark:bg-zinc-900 px-3 py-3 text-center ${className}`}>\n <p className=\"text-[10px] text-zinc-500 dark:text-zinc-400 font-medium mb-0.5\">\n {label}\n </p>\n <p className=\"text-lg font-bold tabular-nums text-zinc-900 dark:text-white\">\n {value.toLocaleString()}\n </p>\n </div>\n );\n}\n","import { type ReactNode } from \"react\";\n\nexport interface EmptyStateProps {\n message: string;\n icon?: ReactNode;\n}\n\n/**\n * Empty state placeholder with icon and message.\n */\nexport function EmptyState({ message, icon }: EmptyStateProps) {\n return (\n <div className=\"flex flex-col items-center justify-center py-12 gap-2\">\n {icon || (\n <svg width=\"32\" height=\"32\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" className=\"text-zinc-200 dark:text-zinc-700\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M8 15h8\" />\n <circle cx=\"9\" cy=\"9\" r=\"1\" fill=\"currentColor\" stroke=\"none\" />\n <circle cx=\"15\" cy=\"9\" r=\"1\" fill=\"currentColor\" stroke=\"none\" />\n </svg>\n )}\n <p className=\"text-sm text-zinc-400 dark:text-zinc-500\">{message}</p>\n </div>\n );\n}\n","import { type ReactNode } from \"react\";\n\nexport interface WatermarkProps {\n children: ReactNode;\n /** Background color */\n color?: string;\n /** Watermark text. Default: \"m1k\" */\n text?: string;\n /** Max width of content area. Default: 430 */\n maxWidth?: number;\n /** Padding around the app shell. Default: 12px */\n padding?: number;\n}\n\nfunction buildSvgPattern(text: string, opacity: number = 0.08): string {\n const w = 220;\n const h = 120;\n const svg = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${w}\" height=\"${h}\">\n <text x=\"10\" y=\"45\" font-family=\"system-ui,sans-serif\" font-size=\"44\" font-weight=\"900\" fill=\"white\" opacity=\"${opacity}\">${text}</text>\n <text x=\"120\" y=\"100\" font-family=\"system-ui,sans-serif\" font-size=\"44\" font-weight=\"900\" fill=\"white\" opacity=\"${opacity}\">${text}</text>\n </svg>`;\n return `url(\"data:image/svg+xml,${encodeURIComponent(svg)}\")`;\n}\n\n/**\n * Full-screen colored background with repeating text watermark pattern.\n * Wraps the AppShell and provides the \"floating app\" look.\n */\nexport function Watermark({\n children,\n color = \"#0f172a\",\n text = \"m1k\",\n maxWidth = 430,\n padding = 12,\n}: WatermarkProps) {\n return (\n <div\n className=\"h-dvh w-full relative overflow-hidden\"\n style={{ backgroundColor: color, transition: \"background-color 0.5s ease\" }}\n >\n <div\n className=\"absolute inset-0 pointer-events-none select-none\"\n style={{\n backgroundImage: buildSvgPattern(text),\n backgroundRepeat: \"repeat\",\n transform: \"rotate(-12deg) scale(1.5)\",\n transformOrigin: \"center center\",\n }}\n />\n <div\n className=\"relative z-10 h-full flex items-center justify-center mx-auto\"\n style={{ maxWidth, padding }}\n >\n {children}\n </div>\n </div>\n );\n}\n","export const colors = {\n blue: \"#3b82f6\",\n purple: \"#8b5cf6\",\n green: \"#10b981\",\n orange: \"#f97316\",\n pink: \"#ec4899\",\n red: \"#ef4444\",\n yellow: \"#eab308\",\n cyan: \"#06b6d4\",\n slate: \"#0f172a\",\n zinc: \"#27272a\",\n} as const;\n\nexport type ColorName = keyof typeof colors;\n","import { type ReactNode, useState, useEffect } from \"react\";\nimport { colors } from \"./colors\";\n\nexport interface ThemeButtonProps {\n color: string;\n onClick: () => void;\n className?: string;\n}\n\n/**\n * Small circular button showing the current theme color.\n * Designed for the AppShellHeader top-right slot.\n */\nexport function ThemeButton({ color, onClick, className = \"\" }: ThemeButtonProps) {\n return (\n <button\n onClick={onClick}\n className={`w-7 h-7 rounded-full border-2 border-white dark:border-zinc-700 shadow-sm transition-transform hover:scale-110 ${className}`}\n style={{ backgroundColor: color }}\n title=\"Change theme\"\n />\n );\n}\n\nexport interface ThemeDialogProps {\n open: boolean;\n onClose: () => void;\n current: string;\n onSelect: (color: string) => void;\n /** Override the color palette. Defaults to built-in colors. */\n palette?: Record<string, string>;\n}\n\n/**\n * Bottom-sheet style color picker dialog.\n * Shows a 5-column grid of color circles with check on the active one.\n */\nexport function ThemeDialog({\n open,\n onClose,\n current,\n onSelect,\n palette = colors,\n}: ThemeDialogProps) {\n useEffect(() => {\n if (!open) return;\n const handler = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") onClose();\n };\n window.addEventListener(\"keydown\", handler);\n return () => window.removeEventListener(\"keydown\", handler);\n }, [open, onClose]);\n\n if (!open) return null;\n\n const entries = Object.entries(palette);\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-end justify-center\" onClick={onClose}>\n <div className=\"absolute inset-0 bg-black/40 backdrop-blur-sm\" />\n <div\n className=\"relative z-10 w-full max-w-[406px] mb-3 mx-3 rounded-2xl bg-white dark:bg-zinc-900 shadow-2xl overflow-hidden\"\n onClick={(e) => e.stopPropagation()}\n >\n <div className=\"px-4 pt-4 pb-2\">\n <p className=\"text-sm font-bold text-zinc-900 dark:text-white\">Theme Color</p>\n <p className=\"text-xs text-zinc-400 dark:text-zinc-500 mt-0.5\">\n Change the Watermark background\n </p>\n </div>\n\n <div className=\"px-4 pb-3 grid grid-cols-5 gap-3 justify-items-center\">\n {entries.map(([name, value]) => (\n <button\n key={value}\n onClick={() => {\n onSelect(value);\n onClose();\n }}\n className={`relative w-11 h-11 rounded-full transition-all hover:scale-110 ${\n current === value\n ? \"ring-2 ring-offset-2 ring-offset-white dark:ring-offset-zinc-900\"\n : \"\"\n }`}\n style={{\n backgroundColor: value,\n ...(current === value ? { [\"--tw-ring-color\" as string]: value } : {}),\n }}\n >\n {current === value && (\n <div className=\"absolute inset-0 flex items-center justify-center\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"white\" strokeWidth=\"3\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n </div>\n )}\n </button>\n ))}\n </div>\n\n <div className=\"px-4 py-3 border-t border-zinc-100 dark:border-zinc-800\">\n <button\n onClick={onClose}\n className=\"w-full py-2.5 rounded-xl bg-zinc-100 dark:bg-zinc-800 text-sm font-medium text-zinc-600 dark:text-zinc-400 hover:bg-zinc-200 dark:hover:bg-zinc-700 transition-colors\"\n >\n Close\n </button>\n </div>\n </div>\n </div>\n );\n}\n","/**\n * Font presets for @m1kapp/ui.\n * These return CSS @import strings to load fonts from official CDNs.\n * No font files are bundled — only references to the original sources.\n */\n\nexport const fonts = {\n /** Toss Product Sans — from toss.im (free for commercial use) */\n toss: 'https://static.toss.im/dist/tps.css',\n /** Pretendard — popular Korean web font */\n pretendard: 'https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css',\n /** Inter — clean Latin sans-serif */\n inter: 'https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;900&display=swap',\n} as const;\n\nexport type FontName = keyof typeof fonts;\n\n/**\n * Returns a <link> href for the given font preset.\n * Usage in your HTML head or via a <link> tag:\n *\n * ```tsx\n * <link rel=\"stylesheet\" href={fonts.toss} />\n * ```\n *\n * Or in CSS:\n * ```css\n * @import url(\"https://static.toss.im/dist/tps.css\");\n * body { font-family: \"Toss Product Sans\", sans-serif; }\n * ```\n */\nexport const fontFamily = {\n toss: '\"Toss Product Sans\", \"Pretendard\", system-ui, sans-serif',\n pretendard: '\"Pretendard Variable\", \"Pretendard\", system-ui, sans-serif',\n inter: '\"Inter\", system-ui, sans-serif',\n} as const;\n"],"mappings":"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","names":["jsx","jsx","jsx","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsxs"]}
|