@m1kapp/ui 0.1.1 → 0.1.2

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/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # @m1k/ui
1
+ # @m1kapp/ui
2
2
 
3
3
  > Mobile-first app shell for side projects.
4
4
  > Build apps that feel like native — in minutes.
@@ -20,7 +20,7 @@
20
20
  ## Install
21
21
 
22
22
  ```bash
23
- npm install @m1k/ui
23
+ npm install @m1kapp/ui
24
24
  ```
25
25
 
26
26
  ## Quick Start
@@ -38,7 +38,7 @@ import {
38
38
  Divider,
39
39
  StatChip,
40
40
  EmptyState,
41
- } from "@m1k/ui";
41
+ } from "@m1kapp/ui";
42
42
 
43
43
  export default function App() {
44
44
  const [tab, setTab] = useState("home");
@@ -144,7 +144,7 @@ export default function App() {
144
144
  In the AI era, building a side project takes a day.
145
145
  But making it *feel* like an app still takes effort.
146
146
 
147
- `@m1k/ui` gives you the mobile app shell — header, scrollable content, bottom tabs, floating on a colored background — so you can focus on what matters: your idea.
147
+ `@m1kapp/ui` gives you the mobile app shell — header, scrollable content, bottom tabs, floating on a colored background — so you can focus on what matters: your idea.
148
148
 
149
149
  Built and battle-tested in [m1k](https://m1k.app).
150
150
 
package/dist/index.d.mts CHANGED
@@ -110,4 +110,76 @@ interface WatermarkProps {
110
110
  */
111
111
  declare function Watermark({ children, color, text, maxWidth, padding, }: WatermarkProps): react_jsx_runtime.JSX.Element;
112
112
 
113
- export { AppShell, AppShellContent, type AppShellContentProps, AppShellHeader, type AppShellHeaderProps, type AppShellProps, Divider, EmptyState, type EmptyStateProps, Section, SectionHeader, type SectionHeaderProps, type SectionProps, StatChip, type StatChipProps, Tab, TabBar, type TabBarProps, type TabProps, Watermark, type WatermarkProps };
113
+ declare const colors: {
114
+ readonly blue: "#3b82f6";
115
+ readonly purple: "#8b5cf6";
116
+ readonly green: "#10b981";
117
+ readonly orange: "#f97316";
118
+ readonly pink: "#ec4899";
119
+ readonly red: "#ef4444";
120
+ readonly yellow: "#eab308";
121
+ readonly cyan: "#06b6d4";
122
+ readonly slate: "#0f172a";
123
+ readonly zinc: "#27272a";
124
+ };
125
+ type ColorName = keyof typeof colors;
126
+
127
+ interface ThemeButtonProps {
128
+ color: string;
129
+ onClick: () => void;
130
+ className?: string;
131
+ }
132
+ /**
133
+ * Small circular button showing the current theme color.
134
+ * Designed for the AppShellHeader top-right slot.
135
+ */
136
+ declare function ThemeButton({ color, onClick, className }: ThemeButtonProps): react_jsx_runtime.JSX.Element;
137
+ interface ThemeDialogProps {
138
+ open: boolean;
139
+ onClose: () => void;
140
+ current: string;
141
+ onSelect: (color: string) => void;
142
+ /** Override the color palette. Defaults to built-in colors. */
143
+ palette?: Record<string, string>;
144
+ }
145
+ /**
146
+ * Bottom-sheet style color picker dialog.
147
+ * Shows a 5-column grid of color circles with check on the active one.
148
+ */
149
+ declare function ThemeDialog({ open, onClose, current, onSelect, palette, }: ThemeDialogProps): react_jsx_runtime.JSX.Element | null;
150
+
151
+ /**
152
+ * Font presets for @m1kapp/ui.
153
+ * These return CSS @import strings to load fonts from official CDNs.
154
+ * No font files are bundled — only references to the original sources.
155
+ */
156
+ declare const fonts: {
157
+ /** Toss Product Sans — from toss.im (free for commercial use) */
158
+ readonly toss: "https://static.toss.im/dist/tps.css";
159
+ /** Pretendard — popular Korean web font */
160
+ readonly pretendard: "https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css";
161
+ /** Inter — clean Latin sans-serif */
162
+ readonly inter: "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;900&display=swap";
163
+ };
164
+ type FontName = keyof typeof fonts;
165
+ /**
166
+ * Returns a <link> href for the given font preset.
167
+ * Usage in your HTML head or via a <link> tag:
168
+ *
169
+ * ```tsx
170
+ * <link rel="stylesheet" href={fonts.toss} />
171
+ * ```
172
+ *
173
+ * Or in CSS:
174
+ * ```css
175
+ * @import url("https://static.toss.im/dist/tps.css");
176
+ * body { font-family: "Toss Product Sans", sans-serif; }
177
+ * ```
178
+ */
179
+ declare const fontFamily: {
180
+ readonly toss: "\"Toss Product Sans\", \"Pretendard\", system-ui, sans-serif";
181
+ readonly pretendard: "\"Pretendard Variable\", \"Pretendard\", system-ui, sans-serif";
182
+ readonly inter: "\"Inter\", system-ui, sans-serif";
183
+ };
184
+
185
+ export { AppShell, AppShellContent, type AppShellContentProps, AppShellHeader, type AppShellHeaderProps, type AppShellProps, type ColorName, Divider, EmptyState, type EmptyStateProps, type FontName, Section, SectionHeader, type SectionHeaderProps, type SectionProps, StatChip, type StatChipProps, Tab, TabBar, type TabBarProps, type TabProps, ThemeButton, type ThemeButtonProps, ThemeDialog, type ThemeDialogProps, Watermark, type WatermarkProps, colors, fontFamily, fonts };
package/dist/index.d.ts CHANGED
@@ -110,4 +110,76 @@ interface WatermarkProps {
110
110
  */
111
111
  declare function Watermark({ children, color, text, maxWidth, padding, }: WatermarkProps): react_jsx_runtime.JSX.Element;
112
112
 
113
- export { AppShell, AppShellContent, type AppShellContentProps, AppShellHeader, type AppShellHeaderProps, type AppShellProps, Divider, EmptyState, type EmptyStateProps, Section, SectionHeader, type SectionHeaderProps, type SectionProps, StatChip, type StatChipProps, Tab, TabBar, type TabBarProps, type TabProps, Watermark, type WatermarkProps };
113
+ declare const colors: {
114
+ readonly blue: "#3b82f6";
115
+ readonly purple: "#8b5cf6";
116
+ readonly green: "#10b981";
117
+ readonly orange: "#f97316";
118
+ readonly pink: "#ec4899";
119
+ readonly red: "#ef4444";
120
+ readonly yellow: "#eab308";
121
+ readonly cyan: "#06b6d4";
122
+ readonly slate: "#0f172a";
123
+ readonly zinc: "#27272a";
124
+ };
125
+ type ColorName = keyof typeof colors;
126
+
127
+ interface ThemeButtonProps {
128
+ color: string;
129
+ onClick: () => void;
130
+ className?: string;
131
+ }
132
+ /**
133
+ * Small circular button showing the current theme color.
134
+ * Designed for the AppShellHeader top-right slot.
135
+ */
136
+ declare function ThemeButton({ color, onClick, className }: ThemeButtonProps): react_jsx_runtime.JSX.Element;
137
+ interface ThemeDialogProps {
138
+ open: boolean;
139
+ onClose: () => void;
140
+ current: string;
141
+ onSelect: (color: string) => void;
142
+ /** Override the color palette. Defaults to built-in colors. */
143
+ palette?: Record<string, string>;
144
+ }
145
+ /**
146
+ * Bottom-sheet style color picker dialog.
147
+ * Shows a 5-column grid of color circles with check on the active one.
148
+ */
149
+ declare function ThemeDialog({ open, onClose, current, onSelect, palette, }: ThemeDialogProps): react_jsx_runtime.JSX.Element | null;
150
+
151
+ /**
152
+ * Font presets for @m1kapp/ui.
153
+ * These return CSS @import strings to load fonts from official CDNs.
154
+ * No font files are bundled — only references to the original sources.
155
+ */
156
+ declare const fonts: {
157
+ /** Toss Product Sans — from toss.im (free for commercial use) */
158
+ readonly toss: "https://static.toss.im/dist/tps.css";
159
+ /** Pretendard — popular Korean web font */
160
+ readonly pretendard: "https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css";
161
+ /** Inter — clean Latin sans-serif */
162
+ readonly inter: "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;900&display=swap";
163
+ };
164
+ type FontName = keyof typeof fonts;
165
+ /**
166
+ * Returns a <link> href for the given font preset.
167
+ * Usage in your HTML head or via a <link> tag:
168
+ *
169
+ * ```tsx
170
+ * <link rel="stylesheet" href={fonts.toss} />
171
+ * ```
172
+ *
173
+ * Or in CSS:
174
+ * ```css
175
+ * @import url("https://static.toss.im/dist/tps.css");
176
+ * body { font-family: "Toss Product Sans", sans-serif; }
177
+ * ```
178
+ */
179
+ declare const fontFamily: {
180
+ readonly toss: "\"Toss Product Sans\", \"Pretendard\", system-ui, sans-serif";
181
+ readonly pretendard: "\"Pretendard Variable\", \"Pretendard\", system-ui, sans-serif";
182
+ readonly inter: "\"Inter\", system-ui, sans-serif";
183
+ };
184
+
185
+ export { AppShell, AppShellContent, type AppShellContentProps, AppShellHeader, type AppShellHeaderProps, type AppShellProps, type ColorName, Divider, EmptyState, type EmptyStateProps, type FontName, Section, SectionHeader, type SectionHeaderProps, type SectionProps, StatChip, type StatChipProps, Tab, TabBar, type TabBarProps, type TabProps, ThemeButton, type ThemeButtonProps, ThemeDialog, type ThemeDialogProps, Watermark, type WatermarkProps, colors, fontFamily, fonts };
package/dist/index.js CHANGED
@@ -31,7 +31,12 @@ __export(index_exports, {
31
31
  StatChip: () => StatChip,
32
32
  Tab: () => Tab,
33
33
  TabBar: () => TabBar,
34
- Watermark: () => Watermark
34
+ ThemeButton: () => ThemeButton,
35
+ ThemeDialog: () => ThemeDialog,
36
+ Watermark: () => Watermark,
37
+ colors: () => colors,
38
+ fontFamily: () => fontFamily,
39
+ fonts: () => fonts
35
40
  });
36
41
  module.exports = __toCommonJS(index_exports);
37
42
 
@@ -62,7 +67,7 @@ function AppShellHeader({ children, className = "" }) {
62
67
  );
63
68
  }
64
69
  function AppShellContent({ children, className = "" }) {
65
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: `flex-1 overflow-y-auto ${className}`, children });
70
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: `flex-1 overflow-y-auto scrollbar-hide ${className}`, children });
66
71
  }
67
72
 
68
73
  // src/components/tab-bar.tsx
@@ -177,6 +182,108 @@ function Watermark({
177
182
  }
178
183
  );
179
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
+ };
180
287
  // Annotate the CommonJS export names for ESM import in node:
181
288
  0 && (module.exports = {
182
289
  AppShell,
@@ -189,6 +296,11 @@ function Watermark({
189
296
  StatChip,
190
297
  Tab,
191
298
  TabBar,
192
- Watermark
299
+ ThemeButton,
300
+ ThemeDialog,
301
+ Watermark,
302
+ colors,
303
+ fontFamily,
304
+ fonts
193
305
  });
194
306
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
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"],"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","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 ${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"],"mappings":"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","names":["import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime"]}
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 CHANGED
@@ -27,7 +27,7 @@ function AppShellHeader({ children, className = "" }) {
27
27
  );
28
28
  }
29
29
  function AppShellContent({ children, className = "" }) {
30
- return /* @__PURE__ */ jsx("div", { className: `flex-1 overflow-y-auto ${className}`, children });
30
+ return /* @__PURE__ */ jsx("div", { className: `flex-1 overflow-y-auto scrollbar-hide ${className}`, children });
31
31
  }
32
32
 
33
33
  // src/components/tab-bar.tsx
@@ -142,6 +142,108 @@ function Watermark({
142
142
  }
143
143
  );
144
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
+ };
145
247
  export {
146
248
  AppShell,
147
249
  AppShellContent,
@@ -153,6 +255,11 @@ export {
153
255
  StatChip,
154
256
  Tab,
155
257
  TabBar,
156
- Watermark
258
+ ThemeButton,
259
+ ThemeDialog,
260
+ Watermark,
261
+ colors,
262
+ fontFamily,
263
+ fonts
157
264
  };
158
265
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
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"],"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 ${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"],"mappings":"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","names":["jsx","jsx","jsx","jsx","jsxs","jsx","jsxs","jsx","jsxs"]}
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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@m1kapp/ui",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Mobile-first app shell UI components for side projects",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",