@m1kapp/kit 0.0.32 → 0.0.36
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 +19 -2
- package/bin/favicon.mjs +73 -24
- package/bin/skills/m1kapp-pwa.md +10 -3
- package/dist/index.d.mts +36 -5
- package/dist/index.d.ts +36 -5
- package/dist/index.js +4 -4
- package/dist/index.mjs +3 -3
- package/dist/meta.json +18 -12
- package/dist/ogimage.d.mts +3 -1
- package/dist/ogimage.d.ts +3 -1
- package/dist/ogimage.js +1 -1
- package/dist/ogimage.mjs +1 -1
- package/dist/pwa.js +2 -2
- package/dist/pwa.mjs +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -22,6 +22,7 @@ import { Watermark, AppShell, AppShellHeader, AppShellContent, Section, TabBar,
|
|
|
22
22
|
export default function App() {
|
|
23
23
|
return (
|
|
24
24
|
// Watermark가 뷰포트 전체 높이/중앙정렬/하단 크레딧을 같이 줍니다.
|
|
25
|
+
// (크레딧 스트립은 셸 바로 밑에 붙어서 셸과 한 덩어리로 중앙정렬됨 — 화면 진짜 바닥에 고정되는 게 아님)
|
|
25
26
|
// AppShell만 단독으로 쓰면 콘텐츠 높이만큼 쪼그라들어요.
|
|
26
27
|
<Watermark color="#e2603f" text="myapp">
|
|
27
28
|
<AppShell>
|
|
@@ -458,14 +459,16 @@ npx m1kkit track https://myside.app
|
|
|
458
459
|
```
|
|
459
460
|
|
|
460
461
|
```bash
|
|
461
|
-
# 2) .env 에 한 줄 → 이후 자동 집계 (스니펫 붙여넣기 불필요)
|
|
462
|
+
# 2) Next.js면 .env 에 한 줄 → 이후 자동 집계 (스니펫 붙여넣기 불필요)
|
|
462
463
|
NEXT_PUBLIC_M1K_SLUG=your-slug
|
|
463
464
|
```
|
|
464
465
|
|
|
466
|
+
Vite 등 Next.js가 아닌 앱은 `NEXT_PUBLIC_*` env가 안 읽히니 `trackSlug` prop으로 직접 지정하세요:
|
|
467
|
+
|
|
465
468
|
```tsx
|
|
466
469
|
// 끄기 / 명시 지정
|
|
467
470
|
<Watermark track={false}>…</Watermark> // 비콘 끔
|
|
468
|
-
<Watermark trackSlug="your-slug">…</Watermark> // env 대신 직접 지정
|
|
471
|
+
<Watermark trackSlug="your-slug">…</Watermark> // env 대신 직접 지정 (Vite는 이 방식 사용)
|
|
469
472
|
// PoweredByKit 단독 사용 시: <PoweredByKit slug="your-slug" track={false} />
|
|
470
473
|
```
|
|
471
474
|
|
|
@@ -525,6 +528,20 @@ export async function GET() {
|
|
|
525
528
|
<OGImage type="product" title="@m1kapp/kit" tagline="올인원 킷" features={["기능1", "기능2"]} color={c} bg={bg} />
|
|
526
529
|
```
|
|
527
530
|
|
|
531
|
+
### CLI로 한 번에 (Next.js 라우트 없이)
|
|
532
|
+
|
|
533
|
+
Vite 등 서버 없는 SPA라 `app/og/route.tsx`를 못 만든다면, 빌드 없이 CLI로
|
|
534
|
+
파비콘부터 OG 이미지, manifest까지 한 번에 생성하세요:
|
|
535
|
+
|
|
536
|
+
```bash
|
|
537
|
+
npx m1kkit favicon --appname="My App" --slogan="한 줄 소개" --color=#3b82f6 --domain=myapp.com
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
`favicon.ico` · `apple-touch-icon.png` · `icon-192.png` · `icon-512.png` ·
|
|
541
|
+
`icon-maskable-512.png` · `og-image.png`(1200×630, 위 `default` 템플릿 사용) ·
|
|
542
|
+
`manifest.json` 7개가 `public/`(자동 감지)에 한 번에 생기고, `<head>`에 붙여넣을
|
|
543
|
+
태그 스니펫도 콘솔에 출력됩니다.
|
|
544
|
+
|
|
528
545
|
### 폰트 & 이모지
|
|
529
546
|
|
|
530
547
|
```tsx
|
package/bin/favicon.mjs
CHANGED
|
@@ -1,16 +1,23 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* @m1kapp/kit favicon
|
|
3
|
+
* @m1kapp/kit favicon + SEO 이미지 생성 CLI
|
|
4
4
|
*
|
|
5
5
|
* Usage:
|
|
6
6
|
* npx @m1kapp/kit favicon
|
|
7
7
|
* npx @m1kapp/kit favicon --text=kit --color=#0f0f1a
|
|
8
8
|
* npx @m1kapp/kit favicon --text=W --color=#7c3aed --out=./static
|
|
9
|
+
* npx @m1kapp/kit favicon --appname="My App" --slogan="한 줄 소개" --domain=myapp.com
|
|
9
10
|
*
|
|
10
11
|
* Options:
|
|
11
|
-
* --text 표시할 텍스트 (기본: package.json name 첫 글자)
|
|
12
|
-
* --
|
|
12
|
+
* --text 파비콘에 표시할 짧은 텍스트 (기본: package.json name 첫 글자)
|
|
13
|
+
* --appname OG 이미지/manifest용 앱 이름 (기본: package.json name)
|
|
14
|
+
* --slogan OG 이미지 부제
|
|
15
|
+
* --domain OG 이미지 하단 도메인 (선택)
|
|
16
|
+
* --color 브랜드색 hex (기본: #0f0f1a)
|
|
13
17
|
* --out 출력 디렉토리 (기본: 자동 감지)
|
|
18
|
+
*
|
|
19
|
+
* 생성 파일: favicon.ico · apple-touch-icon.png · icon-192.png · icon-512.png ·
|
|
20
|
+
* icon-maskable-512.png · og-image.png · manifest.json
|
|
14
21
|
*/
|
|
15
22
|
|
|
16
23
|
import { ImageResponse } from "@vercel/og";
|
|
@@ -61,48 +68,90 @@ function detectOutDir() {
|
|
|
61
68
|
return cwd;
|
|
62
69
|
}
|
|
63
70
|
|
|
64
|
-
|
|
65
|
-
function detectText() {
|
|
66
|
-
if (args.text) return args.text;
|
|
71
|
+
function readPkgName() {
|
|
67
72
|
try {
|
|
68
73
|
const pkg = JSON.parse(fs.readFileSync(path.join(process.cwd(), "package.json"), "utf8"));
|
|
69
|
-
|
|
70
|
-
return name.slice(0, 3); // 최대 3글자
|
|
74
|
+
return (pkg.name ?? "app").replace(/^@[^/]+\//, ""); // scoped 패키지 처리
|
|
71
75
|
} catch {
|
|
72
76
|
return "app";
|
|
73
77
|
}
|
|
74
78
|
}
|
|
75
79
|
|
|
76
|
-
/* ───
|
|
80
|
+
/* ─── Auto-detect short favicon text ─── */
|
|
81
|
+
function detectText() {
|
|
82
|
+
if (args.text) return args.text;
|
|
83
|
+
return readPkgName().slice(0, 3); // 최대 3글자
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/* ─── Auto-detect full app name (OG/manifest용) ─── */
|
|
87
|
+
function detectAppName() {
|
|
88
|
+
if (args.appname) return args.appname;
|
|
89
|
+
return readPkgName();
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/* ─── Load generators from dist ─── */
|
|
77
93
|
const distPath = path.resolve(__dirname, "../dist/ogimage.mjs");
|
|
78
|
-
const { createFaviconElement } = await import(distPath);
|
|
94
|
+
const { createFaviconElement, OGImage } = await import(distPath);
|
|
79
95
|
|
|
80
96
|
/* ─── Generate ─── */
|
|
81
97
|
const text = detectText();
|
|
98
|
+
const appName = detectAppName();
|
|
99
|
+
const slogan = args.slogan;
|
|
100
|
+
const domain = args.domain;
|
|
82
101
|
const color = args.color ?? "#0f0f1a";
|
|
83
102
|
const outDir = detectOutDir();
|
|
84
103
|
|
|
85
|
-
async function generatePng(sizePx) {
|
|
104
|
+
async function generatePng(sizePx, maskable = false) {
|
|
86
105
|
const res = new ImageResponse(
|
|
87
|
-
h(createFaviconElement, { text, color, size: sizePx }),
|
|
106
|
+
h(createFaviconElement, { text, color, size: sizePx, maskable }),
|
|
88
107
|
{ width: sizePx, height: sizePx }
|
|
89
108
|
);
|
|
90
109
|
return Buffer.from(await res.arrayBuffer());
|
|
91
110
|
}
|
|
92
111
|
|
|
93
|
-
|
|
112
|
+
function write(name, buffer) {
|
|
113
|
+
fs.writeFileSync(path.join(outDir, name), buffer);
|
|
114
|
+
console.log(`✓ ${path.relative(process.cwd(), path.join(outDir, name))}`);
|
|
115
|
+
}
|
|
94
116
|
|
|
95
|
-
|
|
96
|
-
const icoBuffer = await pngToIco(icoBuffers);
|
|
97
|
-
fs.writeFileSync(path.join(outDir, "favicon.ico"), icoBuffer);
|
|
98
|
-
console.log(`✓ ${path.relative(process.cwd(), path.join(outDir, "favicon.ico"))}`);
|
|
117
|
+
fs.mkdirSync(outDir, { recursive: true });
|
|
99
118
|
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
console.log(`✓ ${path.relative(process.cwd(), path.join(outDir, "apple-touch-icon.png"))}`);
|
|
119
|
+
const icoBuffers = await Promise.all([16, 32, 48].map((s) => generatePng(s)));
|
|
120
|
+
write("favicon.ico", await pngToIco(icoBuffers));
|
|
103
121
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
122
|
+
write("apple-touch-icon.png", await generatePng(180));
|
|
123
|
+
write("icon-192.png", await generatePng(192));
|
|
124
|
+
write("icon-512.png", await generatePng(512));
|
|
125
|
+
write("icon-maskable-512.png", await generatePng(512, true));
|
|
107
126
|
|
|
108
|
-
|
|
127
|
+
const ogRes = new ImageResponse(
|
|
128
|
+
h(OGImage, { type: "default", title: appName, sub: slogan, appName, color, domain }),
|
|
129
|
+
{ width: 1200, height: 630 }
|
|
130
|
+
);
|
|
131
|
+
write("og-image.png", Buffer.from(await ogRes.arrayBuffer()));
|
|
132
|
+
|
|
133
|
+
const manifest = {
|
|
134
|
+
name: appName,
|
|
135
|
+
short_name: appName,
|
|
136
|
+
start_url: "/",
|
|
137
|
+
display: "standalone",
|
|
138
|
+
background_color: color,
|
|
139
|
+
theme_color: color,
|
|
140
|
+
icons: [
|
|
141
|
+
{ src: "/icon-192.png", sizes: "192x192", type: "image/png" },
|
|
142
|
+
{ src: "/icon-512.png", sizes: "512x512", type: "image/png" },
|
|
143
|
+
{ src: "/icon-maskable-512.png", sizes: "512x512", type: "image/png", purpose: "maskable" },
|
|
144
|
+
],
|
|
145
|
+
};
|
|
146
|
+
write("manifest.json", JSON.stringify(manifest, null, 2) + "\n");
|
|
147
|
+
|
|
148
|
+
console.log(`\n🎉 appname="${appName}" color="${color}" → ${path.relative(process.cwd(), outDir) || "."}/`);
|
|
149
|
+
console.log(`
|
|
150
|
+
<head>에 붙여넣기:
|
|
151
|
+
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
|
|
152
|
+
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
|
|
153
|
+
<link rel="manifest" href="/manifest.json" />
|
|
154
|
+
<meta property="og:image" content="https://<도메인>/og-image.png" />
|
|
155
|
+
<meta property="og:image:width" content="1200" />
|
|
156
|
+
<meta property="og:image:height" content="630" />
|
|
157
|
+
`);
|
package/bin/skills/m1kapp-pwa.md
CHANGED
|
@@ -36,12 +36,19 @@ PWA 설정 현황
|
|
|
36
36
|
|
|
37
37
|
빠진 항목에 대해 확인 후 적용한다.
|
|
38
38
|
|
|
39
|
-
아이콘이 없으면: `npx m1kkit favicon`
|
|
40
|
-
|
|
39
|
+
아이콘이 없으면: `npx m1kkit favicon --appname="[앱 이름]" --color="[테마 컬러]"` 안내
|
|
40
|
+
— favicon.ico/apple-touch-icon/icon-192/icon-512/icon-maskable-512 뿐 아니라
|
|
41
|
+
og-image.png와 manifest.json까지 한 번에 만들어줌.
|
|
42
|
+
|
|
43
|
+
manifest가 없으면:
|
|
44
|
+
- Next.js면 앱 이름·테마 컬러를 물어보고 `createManifest` 적용 (아래).
|
|
45
|
+
- Vite 등 App Router가 없는 프로젝트면 `npx m1kkit favicon`이 만든
|
|
46
|
+
`public/manifest.json`을 그대로 쓰면 됨 — 따로 만들 필요 없음.
|
|
47
|
+
|
|
41
48
|
viewport가 없으면: `mobileViewport` 적용
|
|
42
49
|
|
|
43
50
|
```ts
|
|
44
|
-
// app/manifest.ts
|
|
51
|
+
// app/manifest.ts (Next.js App Router)
|
|
45
52
|
import { createManifest } from "@m1kapp/kit/pwa"
|
|
46
53
|
|
|
47
54
|
export default function manifest() {
|
package/dist/index.d.mts
CHANGED
|
@@ -71,6 +71,10 @@ interface AppShellProps {
|
|
|
71
71
|
* strip) rather than a hand-rolled height/centering div; without a sized
|
|
72
72
|
* parent the shell just collapses to content height.
|
|
73
73
|
*
|
|
74
|
+
* The shell and the credit strip are centered together as one group — the
|
|
75
|
+
* strip sits directly under the shell and moves with it, it does not pin to
|
|
76
|
+
* the screen's true bottom edge.
|
|
77
|
+
*
|
|
74
78
|
* @example
|
|
75
79
|
* <Watermark color="#e2603f" text="myapp">
|
|
76
80
|
* <AppShell>
|
|
@@ -84,8 +88,21 @@ interface AppShellHeaderProps {
|
|
|
84
88
|
children: ReactNode;
|
|
85
89
|
className?: string;
|
|
86
90
|
}
|
|
91
|
+
/**
|
|
92
|
+
* `AppShellHeader`'s rendered height (base 3.5rem/56px + the top safe-area
|
|
93
|
+
* inset on notched devices). Pass this as `<FetchProgress top={APP_SHELL_HEADER_HEIGHT}>`
|
|
94
|
+
* instead of hardcoding `56` so the progress bar still sits flush under the
|
|
95
|
+
* header on a device with a Dynamic Island / notch.
|
|
96
|
+
*/
|
|
97
|
+
declare const APP_SHELL_HEADER_HEIGHT = "calc(3.5rem + env(safe-area-inset-top))";
|
|
87
98
|
/**
|
|
88
99
|
* Sticky top header with blur backdrop.
|
|
100
|
+
*
|
|
101
|
+
* On mobile the shell is full-bleed (no `sm:` margin from Watermark), so this
|
|
102
|
+
* is the actual topmost element under the device status bar / Dynamic Island
|
|
103
|
+
* in an installed PWA — `min-height` (not `height`) plus `padding-top` let the
|
|
104
|
+
* safe-area inset grow the header without squeezing its content, the same
|
|
105
|
+
* ownership split PoweredByKit uses for the bottom inset.
|
|
89
106
|
*/
|
|
90
107
|
declare function AppShellHeader({ children, className }: AppShellHeaderProps): react_jsx_runtime.JSX.Element;
|
|
91
108
|
interface AppShellContentProps {
|
|
@@ -102,6 +119,8 @@ declare function AppShellContent({ children, className }: AppShellContentProps):
|
|
|
102
119
|
interface FabProps {
|
|
103
120
|
onClick: () => void;
|
|
104
121
|
icon: ReactNode;
|
|
122
|
+
/** Accessible label — icon-only button has no other text for screen readers */
|
|
123
|
+
label: string;
|
|
105
124
|
/** Accent background color. Default: zinc-900/white (follows dark mode) */
|
|
106
125
|
color?: string;
|
|
107
126
|
className?: string;
|
|
@@ -115,10 +134,10 @@ interface FabProps {
|
|
|
115
134
|
* @example
|
|
116
135
|
* <AppShellContent>
|
|
117
136
|
* {content}
|
|
118
|
-
* <Fab onClick={handleAdd} icon={<PlusIcon />} color="#6366f1" />
|
|
137
|
+
* <Fab onClick={handleAdd} icon={<PlusIcon />} label="추가" color="#6366f1" />
|
|
119
138
|
* </AppShellContent>
|
|
120
139
|
*/
|
|
121
|
-
declare function Fab({ onClick, icon, color, className }: FabProps): react_jsx_runtime.JSX.Element;
|
|
140
|
+
declare function Fab({ onClick, icon, label, color, className }: FabProps): react_jsx_runtime.JSX.Element;
|
|
122
141
|
|
|
123
142
|
interface TabBarProps {
|
|
124
143
|
children: ReactNode;
|
|
@@ -126,6 +145,13 @@ interface TabBarProps {
|
|
|
126
145
|
}
|
|
127
146
|
/**
|
|
128
147
|
* Sticky bottom navigation tab bar.
|
|
148
|
+
*
|
|
149
|
+
* Carries no safe-area padding of its own — TabBar is meant to sit inside
|
|
150
|
+
* `AppShell`, which sits inside `Watermark`. `Watermark` appends its
|
|
151
|
+
* `PoweredByKit` credit strip right after `AppShell`, and that strip is the
|
|
152
|
+
* one that owns the home-indicator safe area (`variant="overlay"`). If
|
|
153
|
+
* TabBar also padded itself for the safe area, the reservation would be
|
|
154
|
+
* doubled — a blank gap between the tab icons and the credit strip.
|
|
129
155
|
*/
|
|
130
156
|
declare function TabBar({ children, className }: TabBarProps): react_jsx_runtime.JSX.Element;
|
|
131
157
|
interface TabRootProps {
|
|
@@ -176,8 +202,13 @@ interface FetchProgressProps {
|
|
|
176
202
|
* When omitted, the bar shows while ANY useFetch request is in flight.
|
|
177
203
|
*/
|
|
178
204
|
active?: boolean;
|
|
179
|
-
/**
|
|
180
|
-
|
|
205
|
+
/**
|
|
206
|
+
* Distance from the top of the positioned ancestor — a number of px, or any
|
|
207
|
+
* CSS length (e.g. `"calc(3.5rem + env(safe-area-inset-top))"` to sit below
|
|
208
|
+
* `AppShellHeader`, whose height grows with the safe-area inset on notched
|
|
209
|
+
* devices). Default: 0
|
|
210
|
+
*/
|
|
211
|
+
top?: number | string;
|
|
181
212
|
/** Bar thickness in px. Default: 3 */
|
|
182
213
|
height?: number;
|
|
183
214
|
className?: string;
|
|
@@ -1761,4 +1792,4 @@ declare function parseIsoDuration(duration: string): IsoDuration;
|
|
|
1761
1792
|
/** "PT1H2M3S" → 3723 (초) */
|
|
1762
1793
|
declare function isoDurationToSec(duration: string): number;
|
|
1763
1794
|
|
|
1764
|
-
export { ActionCard, type ActionCardLabels, type ActionCardProps, type ActionCardState, type ApiClient, type ApiClientOptions, ApiError, AppShell, AppShellContent, type AppShellContentProps, AppShellHeader, type AppShellHeaderProps, type AppShellProps, AsyncList, type AsyncListProps, type AsyncListStatus, Avatar, type AvatarProps, Badge, type BadgeProps, BarList, type BarListItem, type BarListProps, Button, type ButtonProps, Carousel, type CarouselProps, ChatBubble, type ChatBubbleProps, type ChatMessage, type ChatRole, CodeBlock, type CodeBlockProps, Collapsible, type CollapsibleProps, type ColorName, ColorPicker, type ColorPickerProps, CopyButton, type CopyButtonProps, Countdown, type CountdownLabels, type CountdownProps, type DateCount, type DayGroup, Dialog, type DialogProps, Divider, type DividerProps, EmojiButton, type EmojiButtonProps, EmojiPicker, type EmojiPickerLabels, type EmojiPickerProps, EmptyState, type EmptyStateProps, Fab, type FabProps, FetchProgress, type FetchProgressProps, Field, type FieldProps, FontLinks, type FontName, GrassMap, type GrassMapData, type GrassMapLabels, type GrassMapProps, IOSInstallSheet, IconButton, type IconButtonProps, Img, type ImgProps, InAppSheet, type InAppSheetProps, InlineEdit, type InlineEditProps, Input, type InputProps, type IsoDuration, KitStyles, LinkifiedText, type LinkifiedTextProps, ListRow, type ListRowProps, MediaCard, type MediaCardProps, MessageList, type MessageListProps, PWAInstallButton, type PWAInstallState, PoweredByKit, type PoweredByKitProps, ProgressRing, type ProgressRingProps, Section, SectionHeader, type SectionHeaderProps, type SectionProps, type SegmentOption, SegmentedControl, type SegmentedControlProps, Select, type SelectOption, type SelectProps, ShareButton, type ShareButtonProps, Skeleton, type SkeletonProps, StatChip, type StatChipProps, type Step, Stepper, type StepperProps, Switch, type SwitchProps, THEME_SCRIPT, Tab, TabBar, type TabBarProps, type TabProps, type TabRootProps, Textarea, type TextareaProps, ThemeButton, type ThemeButtonProps, ThemeDialog, type ThemeDialogLabels, type ThemeDialogProps, type ToastOptions, ToastProvider, type ToastVariant, Tooltip, type TooltipProps, Typewriter, type TypewriterProps, TypingIndicator, type TypingIndicatorProps, type UnderlineTab, UnderlineTabs, type UnderlineTabsProps, type UseFetchOptions, type UseFetchResult, type UseFormSubmitOptions, type UseFormSubmitResult, type UseInViewOptions, type UseInViewResult, type UsePWAInstallReturn, type UsePollingOptions, type UsePollingResult, type UseShareOptions, type UseShareReturn, Watermark, type WatermarkProps, type WatermarkSponsor, clearFetchCache, cn, colors, createApiClient, createManifest, fillDateSeries, fontFamily, fonts, formatDayLabel, formatDuration, formatKoreanNumber, formatNumber, formatPrice, getFetchActiveCount, groupByDay, invalidateFetch, isoDurationToSec, mobileViewport, parseIsoDuration, postJson, relativeTime, subscribeFetchActivity, svgIcon, useCopy, useDebounce, useEscapeKey, useFetch, useFocusTrap, useFormSubmit, useImageLoader, useInView, useLocalStorage, usePWAInstall, usePolling, usePortalTarget, useScrollLock, useShare, useToast };
|
|
1795
|
+
export { APP_SHELL_HEADER_HEIGHT, ActionCard, type ActionCardLabels, type ActionCardProps, type ActionCardState, type ApiClient, type ApiClientOptions, ApiError, AppShell, AppShellContent, type AppShellContentProps, AppShellHeader, type AppShellHeaderProps, type AppShellProps, AsyncList, type AsyncListProps, type AsyncListStatus, Avatar, type AvatarProps, Badge, type BadgeProps, BarList, type BarListItem, type BarListProps, Button, type ButtonProps, Carousel, type CarouselProps, ChatBubble, type ChatBubbleProps, type ChatMessage, type ChatRole, CodeBlock, type CodeBlockProps, Collapsible, type CollapsibleProps, type ColorName, ColorPicker, type ColorPickerProps, CopyButton, type CopyButtonProps, Countdown, type CountdownLabels, type CountdownProps, type DateCount, type DayGroup, Dialog, type DialogProps, Divider, type DividerProps, EmojiButton, type EmojiButtonProps, EmojiPicker, type EmojiPickerLabels, type EmojiPickerProps, EmptyState, type EmptyStateProps, Fab, type FabProps, FetchProgress, type FetchProgressProps, Field, type FieldProps, FontLinks, type FontName, GrassMap, type GrassMapData, type GrassMapLabels, type GrassMapProps, IOSInstallSheet, IconButton, type IconButtonProps, Img, type ImgProps, InAppSheet, type InAppSheetProps, InlineEdit, type InlineEditProps, Input, type InputProps, type IsoDuration, KitStyles, LinkifiedText, type LinkifiedTextProps, ListRow, type ListRowProps, MediaCard, type MediaCardProps, MessageList, type MessageListProps, PWAInstallButton, type PWAInstallState, PoweredByKit, type PoweredByKitProps, ProgressRing, type ProgressRingProps, Section, SectionHeader, type SectionHeaderProps, type SectionProps, type SegmentOption, SegmentedControl, type SegmentedControlProps, Select, type SelectOption, type SelectProps, ShareButton, type ShareButtonProps, Skeleton, type SkeletonProps, StatChip, type StatChipProps, type Step, Stepper, type StepperProps, Switch, type SwitchProps, THEME_SCRIPT, Tab, TabBar, type TabBarProps, type TabProps, type TabRootProps, Textarea, type TextareaProps, ThemeButton, type ThemeButtonProps, ThemeDialog, type ThemeDialogLabels, type ThemeDialogProps, type ToastOptions, ToastProvider, type ToastVariant, Tooltip, type TooltipProps, Typewriter, type TypewriterProps, TypingIndicator, type TypingIndicatorProps, type UnderlineTab, UnderlineTabs, type UnderlineTabsProps, type UseFetchOptions, type UseFetchResult, type UseFormSubmitOptions, type UseFormSubmitResult, type UseInViewOptions, type UseInViewResult, type UsePWAInstallReturn, type UsePollingOptions, type UsePollingResult, type UseShareOptions, type UseShareReturn, Watermark, type WatermarkProps, type WatermarkSponsor, clearFetchCache, cn, colors, createApiClient, createManifest, fillDateSeries, fontFamily, fonts, formatDayLabel, formatDuration, formatKoreanNumber, formatNumber, formatPrice, getFetchActiveCount, groupByDay, invalidateFetch, isoDurationToSec, mobileViewport, parseIsoDuration, postJson, relativeTime, subscribeFetchActivity, svgIcon, useCopy, useDebounce, useEscapeKey, useFetch, useFocusTrap, useFormSubmit, useImageLoader, useInView, useLocalStorage, usePWAInstall, usePolling, usePortalTarget, useScrollLock, useShare, useToast };
|
package/dist/index.d.ts
CHANGED
|
@@ -71,6 +71,10 @@ interface AppShellProps {
|
|
|
71
71
|
* strip) rather than a hand-rolled height/centering div; without a sized
|
|
72
72
|
* parent the shell just collapses to content height.
|
|
73
73
|
*
|
|
74
|
+
* The shell and the credit strip are centered together as one group — the
|
|
75
|
+
* strip sits directly under the shell and moves with it, it does not pin to
|
|
76
|
+
* the screen's true bottom edge.
|
|
77
|
+
*
|
|
74
78
|
* @example
|
|
75
79
|
* <Watermark color="#e2603f" text="myapp">
|
|
76
80
|
* <AppShell>
|
|
@@ -84,8 +88,21 @@ interface AppShellHeaderProps {
|
|
|
84
88
|
children: ReactNode;
|
|
85
89
|
className?: string;
|
|
86
90
|
}
|
|
91
|
+
/**
|
|
92
|
+
* `AppShellHeader`'s rendered height (base 3.5rem/56px + the top safe-area
|
|
93
|
+
* inset on notched devices). Pass this as `<FetchProgress top={APP_SHELL_HEADER_HEIGHT}>`
|
|
94
|
+
* instead of hardcoding `56` so the progress bar still sits flush under the
|
|
95
|
+
* header on a device with a Dynamic Island / notch.
|
|
96
|
+
*/
|
|
97
|
+
declare const APP_SHELL_HEADER_HEIGHT = "calc(3.5rem + env(safe-area-inset-top))";
|
|
87
98
|
/**
|
|
88
99
|
* Sticky top header with blur backdrop.
|
|
100
|
+
*
|
|
101
|
+
* On mobile the shell is full-bleed (no `sm:` margin from Watermark), so this
|
|
102
|
+
* is the actual topmost element under the device status bar / Dynamic Island
|
|
103
|
+
* in an installed PWA — `min-height` (not `height`) plus `padding-top` let the
|
|
104
|
+
* safe-area inset grow the header without squeezing its content, the same
|
|
105
|
+
* ownership split PoweredByKit uses for the bottom inset.
|
|
89
106
|
*/
|
|
90
107
|
declare function AppShellHeader({ children, className }: AppShellHeaderProps): react_jsx_runtime.JSX.Element;
|
|
91
108
|
interface AppShellContentProps {
|
|
@@ -102,6 +119,8 @@ declare function AppShellContent({ children, className }: AppShellContentProps):
|
|
|
102
119
|
interface FabProps {
|
|
103
120
|
onClick: () => void;
|
|
104
121
|
icon: ReactNode;
|
|
122
|
+
/** Accessible label — icon-only button has no other text for screen readers */
|
|
123
|
+
label: string;
|
|
105
124
|
/** Accent background color. Default: zinc-900/white (follows dark mode) */
|
|
106
125
|
color?: string;
|
|
107
126
|
className?: string;
|
|
@@ -115,10 +134,10 @@ interface FabProps {
|
|
|
115
134
|
* @example
|
|
116
135
|
* <AppShellContent>
|
|
117
136
|
* {content}
|
|
118
|
-
* <Fab onClick={handleAdd} icon={<PlusIcon />} color="#6366f1" />
|
|
137
|
+
* <Fab onClick={handleAdd} icon={<PlusIcon />} label="추가" color="#6366f1" />
|
|
119
138
|
* </AppShellContent>
|
|
120
139
|
*/
|
|
121
|
-
declare function Fab({ onClick, icon, color, className }: FabProps): react_jsx_runtime.JSX.Element;
|
|
140
|
+
declare function Fab({ onClick, icon, label, color, className }: FabProps): react_jsx_runtime.JSX.Element;
|
|
122
141
|
|
|
123
142
|
interface TabBarProps {
|
|
124
143
|
children: ReactNode;
|
|
@@ -126,6 +145,13 @@ interface TabBarProps {
|
|
|
126
145
|
}
|
|
127
146
|
/**
|
|
128
147
|
* Sticky bottom navigation tab bar.
|
|
148
|
+
*
|
|
149
|
+
* Carries no safe-area padding of its own — TabBar is meant to sit inside
|
|
150
|
+
* `AppShell`, which sits inside `Watermark`. `Watermark` appends its
|
|
151
|
+
* `PoweredByKit` credit strip right after `AppShell`, and that strip is the
|
|
152
|
+
* one that owns the home-indicator safe area (`variant="overlay"`). If
|
|
153
|
+
* TabBar also padded itself for the safe area, the reservation would be
|
|
154
|
+
* doubled — a blank gap between the tab icons and the credit strip.
|
|
129
155
|
*/
|
|
130
156
|
declare function TabBar({ children, className }: TabBarProps): react_jsx_runtime.JSX.Element;
|
|
131
157
|
interface TabRootProps {
|
|
@@ -176,8 +202,13 @@ interface FetchProgressProps {
|
|
|
176
202
|
* When omitted, the bar shows while ANY useFetch request is in flight.
|
|
177
203
|
*/
|
|
178
204
|
active?: boolean;
|
|
179
|
-
/**
|
|
180
|
-
|
|
205
|
+
/**
|
|
206
|
+
* Distance from the top of the positioned ancestor — a number of px, or any
|
|
207
|
+
* CSS length (e.g. `"calc(3.5rem + env(safe-area-inset-top))"` to sit below
|
|
208
|
+
* `AppShellHeader`, whose height grows with the safe-area inset on notched
|
|
209
|
+
* devices). Default: 0
|
|
210
|
+
*/
|
|
211
|
+
top?: number | string;
|
|
181
212
|
/** Bar thickness in px. Default: 3 */
|
|
182
213
|
height?: number;
|
|
183
214
|
className?: string;
|
|
@@ -1761,4 +1792,4 @@ declare function parseIsoDuration(duration: string): IsoDuration;
|
|
|
1761
1792
|
/** "PT1H2M3S" → 3723 (초) */
|
|
1762
1793
|
declare function isoDurationToSec(duration: string): number;
|
|
1763
1794
|
|
|
1764
|
-
export { ActionCard, type ActionCardLabels, type ActionCardProps, type ActionCardState, type ApiClient, type ApiClientOptions, ApiError, AppShell, AppShellContent, type AppShellContentProps, AppShellHeader, type AppShellHeaderProps, type AppShellProps, AsyncList, type AsyncListProps, type AsyncListStatus, Avatar, type AvatarProps, Badge, type BadgeProps, BarList, type BarListItem, type BarListProps, Button, type ButtonProps, Carousel, type CarouselProps, ChatBubble, type ChatBubbleProps, type ChatMessage, type ChatRole, CodeBlock, type CodeBlockProps, Collapsible, type CollapsibleProps, type ColorName, ColorPicker, type ColorPickerProps, CopyButton, type CopyButtonProps, Countdown, type CountdownLabels, type CountdownProps, type DateCount, type DayGroup, Dialog, type DialogProps, Divider, type DividerProps, EmojiButton, type EmojiButtonProps, EmojiPicker, type EmojiPickerLabels, type EmojiPickerProps, EmptyState, type EmptyStateProps, Fab, type FabProps, FetchProgress, type FetchProgressProps, Field, type FieldProps, FontLinks, type FontName, GrassMap, type GrassMapData, type GrassMapLabels, type GrassMapProps, IOSInstallSheet, IconButton, type IconButtonProps, Img, type ImgProps, InAppSheet, type InAppSheetProps, InlineEdit, type InlineEditProps, Input, type InputProps, type IsoDuration, KitStyles, LinkifiedText, type LinkifiedTextProps, ListRow, type ListRowProps, MediaCard, type MediaCardProps, MessageList, type MessageListProps, PWAInstallButton, type PWAInstallState, PoweredByKit, type PoweredByKitProps, ProgressRing, type ProgressRingProps, Section, SectionHeader, type SectionHeaderProps, type SectionProps, type SegmentOption, SegmentedControl, type SegmentedControlProps, Select, type SelectOption, type SelectProps, ShareButton, type ShareButtonProps, Skeleton, type SkeletonProps, StatChip, type StatChipProps, type Step, Stepper, type StepperProps, Switch, type SwitchProps, THEME_SCRIPT, Tab, TabBar, type TabBarProps, type TabProps, type TabRootProps, Textarea, type TextareaProps, ThemeButton, type ThemeButtonProps, ThemeDialog, type ThemeDialogLabels, type ThemeDialogProps, type ToastOptions, ToastProvider, type ToastVariant, Tooltip, type TooltipProps, Typewriter, type TypewriterProps, TypingIndicator, type TypingIndicatorProps, type UnderlineTab, UnderlineTabs, type UnderlineTabsProps, type UseFetchOptions, type UseFetchResult, type UseFormSubmitOptions, type UseFormSubmitResult, type UseInViewOptions, type UseInViewResult, type UsePWAInstallReturn, type UsePollingOptions, type UsePollingResult, type UseShareOptions, type UseShareReturn, Watermark, type WatermarkProps, type WatermarkSponsor, clearFetchCache, cn, colors, createApiClient, createManifest, fillDateSeries, fontFamily, fonts, formatDayLabel, formatDuration, formatKoreanNumber, formatNumber, formatPrice, getFetchActiveCount, groupByDay, invalidateFetch, isoDurationToSec, mobileViewport, parseIsoDuration, postJson, relativeTime, subscribeFetchActivity, svgIcon, useCopy, useDebounce, useEscapeKey, useFetch, useFocusTrap, useFormSubmit, useImageLoader, useInView, useLocalStorage, usePWAInstall, usePolling, usePortalTarget, useScrollLock, useShare, useToast };
|
|
1795
|
+
export { APP_SHELL_HEADER_HEIGHT, ActionCard, type ActionCardLabels, type ActionCardProps, type ActionCardState, type ApiClient, type ApiClientOptions, ApiError, AppShell, AppShellContent, type AppShellContentProps, AppShellHeader, type AppShellHeaderProps, type AppShellProps, AsyncList, type AsyncListProps, type AsyncListStatus, Avatar, type AvatarProps, Badge, type BadgeProps, BarList, type BarListItem, type BarListProps, Button, type ButtonProps, Carousel, type CarouselProps, ChatBubble, type ChatBubbleProps, type ChatMessage, type ChatRole, CodeBlock, type CodeBlockProps, Collapsible, type CollapsibleProps, type ColorName, ColorPicker, type ColorPickerProps, CopyButton, type CopyButtonProps, Countdown, type CountdownLabels, type CountdownProps, type DateCount, type DayGroup, Dialog, type DialogProps, Divider, type DividerProps, EmojiButton, type EmojiButtonProps, EmojiPicker, type EmojiPickerLabels, type EmojiPickerProps, EmptyState, type EmptyStateProps, Fab, type FabProps, FetchProgress, type FetchProgressProps, Field, type FieldProps, FontLinks, type FontName, GrassMap, type GrassMapData, type GrassMapLabels, type GrassMapProps, IOSInstallSheet, IconButton, type IconButtonProps, Img, type ImgProps, InAppSheet, type InAppSheetProps, InlineEdit, type InlineEditProps, Input, type InputProps, type IsoDuration, KitStyles, LinkifiedText, type LinkifiedTextProps, ListRow, type ListRowProps, MediaCard, type MediaCardProps, MessageList, type MessageListProps, PWAInstallButton, type PWAInstallState, PoweredByKit, type PoweredByKitProps, ProgressRing, type ProgressRingProps, Section, SectionHeader, type SectionHeaderProps, type SectionProps, type SegmentOption, SegmentedControl, type SegmentedControlProps, Select, type SelectOption, type SelectProps, ShareButton, type ShareButtonProps, Skeleton, type SkeletonProps, StatChip, type StatChipProps, type Step, Stepper, type StepperProps, Switch, type SwitchProps, THEME_SCRIPT, Tab, TabBar, type TabBarProps, type TabProps, type TabRootProps, Textarea, type TextareaProps, ThemeButton, type ThemeButtonProps, ThemeDialog, type ThemeDialogLabels, type ThemeDialogProps, type ToastOptions, ToastProvider, type ToastVariant, Tooltip, type TooltipProps, Typewriter, type TypewriterProps, TypingIndicator, type TypingIndicatorProps, type UnderlineTab, UnderlineTabs, type UnderlineTabsProps, type UseFetchOptions, type UseFetchResult, type UseFormSubmitOptions, type UseFormSubmitResult, type UseInViewOptions, type UseInViewResult, type UsePWAInstallReturn, type UsePollingOptions, type UsePollingResult, type UseShareOptions, type UseShareReturn, Watermark, type WatermarkProps, type WatermarkSponsor, clearFetchCache, cn, colors, createApiClient, createManifest, fillDateSeries, fontFamily, fonts, formatDayLabel, formatDuration, formatKoreanNumber, formatNumber, formatPrice, getFetchActiveCount, groupByDay, invalidateFetch, isoDurationToSec, mobileViewport, parseIsoDuration, postJson, relativeTime, subscribeFetchActivity, svgIcon, useCopy, useDebounce, useEscapeKey, useFetch, useFocusTrap, useFormSubmit, useImageLoader, useInView, useLocalStorage, usePWAInstall, usePolling, usePortalTarget, useScrollLock, useShare, useToast };
|