@m1kapp/kit 0.0.24 → 0.0.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as React$1 from 'react';
3
- import React__default, { ReactNode, CSSProperties, RefObject } from 'react';
3
+ import React__default, { ReactNode, CSSProperties, RefObject, SyntheticEvent } from 'react';
4
4
  import { MetadataRoute, Viewport } from 'next';
5
5
  import { ClassValue } from 'clsx';
6
6
 
@@ -45,13 +45,19 @@ interface AppShellProps {
45
45
  maxWidth?: number;
46
46
  /** Max height of the shell. Default: 932px (iPhone 15 Pro Max) */
47
47
  maxHeight?: number;
48
+ /**
49
+ * Accent color (any CSS color) propagated to kit components as `--kit-accent`.
50
+ * Lets you re-skin the whole shell — Switch, SegmentedControl, ChatBubble,
51
+ * ActionCard, ListRow… — in one place. e.g. accent="#e2603f"
52
+ */
53
+ accent?: string;
48
54
  style?: CSSProperties;
49
55
  }
50
56
  /**
51
57
  * Mobile app-like container with rounded corners, shadow, and ring.
52
58
  * Centers content and constrains width for a phone-like viewport.
53
59
  */
54
- declare function AppShell({ children, className, maxWidth, maxHeight, style, }: AppShellProps): react_jsx_runtime.JSX.Element;
60
+ declare function AppShell({ children, className, maxWidth, maxHeight, accent, style, }: AppShellProps): react_jsx_runtime.JSX.Element;
55
61
  interface AppShellHeaderProps {
56
62
  children: ReactNode;
57
63
  className?: string;
@@ -202,6 +208,20 @@ interface WatermarkProps {
202
208
  * Default: false (badge is shown)
203
209
  */
204
210
  hidePoweredBy?: boolean;
211
+ /**
212
+ * m1k.app visitor-tracker slug, forwarded to the embedded PoweredByKit badge.
213
+ * Falls back to `NEXT_PUBLIC_M1K_SLUG`. No slug → no tracking (off by default).
214
+ */
215
+ trackSlug?: string;
216
+ /** Set false to disable the visitor beacon even when a slug is present */
217
+ track?: boolean;
218
+ /** Mark the site as claimed (인증됨). When tracking but not claimed, a "미인증" marker shows. */
219
+ claimed?: boolean;
220
+ /** Visitor counts for the footer ({ today, total }). Omit to auto-fetch from m1k.app. */
221
+ counts?: {
222
+ today?: number;
223
+ total?: number;
224
+ };
205
225
  }
206
226
  /**
207
227
  * Full-screen colored background with repeating animated text watermark pattern.
@@ -209,7 +229,7 @@ interface WatermarkProps {
209
229
  * Renders as a single SVG element with a <pattern> — zero extra DOM nodes per tile.
210
230
  * Sponsor tiles inside the pattern are clickable and support hover effects.
211
231
  */
212
- declare function Watermark({ children, color, text, maxWidth, sponsor, speed, hidePoweredBy, }: WatermarkProps): react_jsx_runtime.JSX.Element;
232
+ declare function Watermark({ children, color, text, maxWidth, sponsor, speed, hidePoweredBy, trackSlug, track, claimed, counts, }: WatermarkProps): react_jsx_runtime.JSX.Element;
213
233
 
214
234
  declare const colors: {
215
235
  readonly blue: "#3b82f6";
@@ -670,6 +690,31 @@ interface PoweredByKitProps {
670
690
  version?: string;
671
691
  /** "default" for inside AppShell, "overlay" for on top of Watermark background */
672
692
  variant?: "default" | "overlay";
693
+ /**
694
+ * m1k.app visitor-tracker slug. When set (explicitly or via the
695
+ * `NEXT_PUBLIC_M1K_SLUG` env var) a tiny hidden beacon counts each page view.
696
+ * No slug → no tracking (off by default). Register one with `npx m1kkit track`.
697
+ */
698
+ slug?: string;
699
+ /** Tracker host. Default: "m1k.app" */
700
+ trackerHost?: string;
701
+ /** Set false to disable the visitor beacon even when a slug is present */
702
+ track?: boolean;
703
+ /**
704
+ * Whether the registered site has been claimed (귀속/인증) to an m1k.app account.
705
+ * When tracking is active but this is false, the badge shows a "미인증" marker.
706
+ * Set true after running `npx m1kkit claim`. Defaults to false.
707
+ */
708
+ claimed?: boolean;
709
+ /**
710
+ * Visitor counts to display ({ today, total }). If omitted, fetched from
711
+ * `https://<trackerHost>/api/sites/<slug>` (needs CORS). Pass explicitly to
712
+ * avoid the fetch (SSR, custom source, or cross-origin without CORS).
713
+ */
714
+ counts?: {
715
+ today?: number;
716
+ total?: number;
717
+ };
673
718
  className?: string;
674
719
  }
675
720
  /**
@@ -679,7 +724,571 @@ interface PoweredByKitProps {
679
724
  * Fetches /kit-stats.json (generated by `m1kkit stats`) on first open
680
725
  * to show real code analysis results.
681
726
  */
682
- declare function PoweredByKit({ statsUrl, version, variant, className }: PoweredByKitProps): react_jsx_runtime.JSX.Element;
727
+ declare function PoweredByKit({ statsUrl, version, variant, slug, trackerHost, track, claimed, counts, className }: PoweredByKitProps): react_jsx_runtime.JSX.Element;
728
+
729
+ interface SwitchProps {
730
+ /** Whether the switch is on */
731
+ checked: boolean;
732
+ /** Called with the next value when toggled */
733
+ onChange: (next: boolean) => void;
734
+ disabled?: boolean;
735
+ /** On-state track color (any CSS color). Defaults to `var(--kit-accent)`. */
736
+ accent?: string;
737
+ /** Accessible label */
738
+ "aria-label"?: string;
739
+ className?: string;
740
+ }
741
+ /**
742
+ * On/off toggle switch. Pill track + sliding knob, adapts to dark mode.
743
+ * On-state color follows `--kit-accent` (set via `<AppShell accent>`) or the `accent` prop.
744
+ *
745
+ * @example
746
+ * <Switch checked={on} onChange={setOn} aria-label="알림" />
747
+ * <Switch checked={on} onChange={setOn} accent="#e2603f" />
748
+ */
749
+ declare function Switch({ checked, onChange, disabled, accent, className, ...rest }: SwitchProps): react_jsx_runtime.JSX.Element;
750
+
751
+ interface FieldProps {
752
+ /** Label shown above (or beside, when `inline`) the input */
753
+ label: ReactNode;
754
+ value: string;
755
+ /** Omit to render a read-only display row */
756
+ onChange?: (value: string) => void;
757
+ placeholder?: string;
758
+ /** input type (text, email, tel…). Ignored when `multiline`. */
759
+ type?: string;
760
+ /** Render a textarea instead of an input */
761
+ multiline?: boolean;
762
+ rows?: number;
763
+ readOnly?: boolean;
764
+ disabled?: boolean;
765
+ /** Helper text under the field */
766
+ hint?: ReactNode;
767
+ /** Label beside the input on one line (settings-row style) instead of stacked */
768
+ inline?: boolean;
769
+ className?: string;
770
+ }
771
+ /**
772
+ * Labeled input row for forms. Stacked by default, or `inline` for a
773
+ * settings-style "label … value" row. Supports textarea via `multiline`.
774
+ *
775
+ * @example
776
+ * <Field label="이름" value={name} onChange={setName} placeholder="이름" />
777
+ * <Field label="메모" value={memo} onChange={setMemo} multiline rows={3} />
778
+ * <Field label="이메일" value={email} inline readOnly />
779
+ */
780
+ declare function Field({ label, value, onChange, placeholder, type, multiline, rows, readOnly, disabled, hint, inline, className, }: FieldProps): react_jsx_runtime.JSX.Element;
781
+
782
+ interface SegmentOption<T extends string> {
783
+ value: T;
784
+ label: ReactNode;
785
+ }
786
+ interface SegmentedControlProps<T extends string> {
787
+ options: SegmentOption<T>[];
788
+ value: T;
789
+ onChange: (value: T) => void;
790
+ /** Active-segment label color (any CSS color). Defaults to `var(--kit-accent)`. */
791
+ accent?: string;
792
+ className?: string;
793
+ }
794
+ /**
795
+ * Inline segmented toggle (e.g. 오늘 / 이번 주). The active segment lifts onto a
796
+ * card; its label takes the accent color. For global bottom nav use `TabBar` instead.
797
+ *
798
+ * @example
799
+ * <SegmentedControl
800
+ * value={view}
801
+ * onChange={setView}
802
+ * options={[{ value: "today", label: "오늘" }, { value: "week", label: "이번 주" }]}
803
+ * />
804
+ */
805
+ declare function SegmentedControl<T extends string>({ options, value, onChange, accent, className, }: SegmentedControlProps<T>): react_jsx_runtime.JSX.Element;
806
+
807
+ type ChatRole = "user" | "assistant";
808
+ interface ChatBubbleProps {
809
+ role: ChatRole;
810
+ children: ReactNode;
811
+ /** User-bubble background (any CSS color). Defaults to `var(--kit-accent)`. */
812
+ accent?: string;
813
+ className?: string;
814
+ }
815
+ /**
816
+ * Chat message bubble. User messages align right with the accent color and a
817
+ * tail on the bottom-right; assistant messages align left on a neutral surface.
818
+ * Preserves newlines (`whitespace-pre-wrap`).
819
+ *
820
+ * @example
821
+ * <ChatBubble role="user">오늘 3시 회의 잡아줘</ChatBubble>
822
+ * <ChatBubble role="assistant">네, 잡아드릴게요.</ChatBubble>
823
+ */
824
+ declare function ChatBubble({ role, children, accent, className }: ChatBubbleProps): react_jsx_runtime.JSX.Element;
825
+ interface TypingIndicatorProps {
826
+ className?: string;
827
+ }
828
+ /**
829
+ * Three-dot "typing…" indicator on an assistant-style surface.
830
+ *
831
+ * @example
832
+ * {pending && <TypingIndicator />}
833
+ */
834
+ declare function TypingIndicator({ className }: TypingIndicatorProps): react_jsx_runtime.JSX.Element;
835
+ interface ChatMessage {
836
+ id?: string | number;
837
+ role: ChatRole;
838
+ content: ReactNode;
839
+ /** Epoch ms — required for day dividers */
840
+ timestamp?: number;
841
+ }
842
+ interface MessageListProps {
843
+ messages: ChatMessage[];
844
+ /** Insert a date divider when the day changes between messages */
845
+ dayDivider?: boolean;
846
+ /** User-bubble accent (forwarded to each ChatBubble) */
847
+ accent?: string;
848
+ /** Format a divider label from a timestamp. Defaults to a Korean date label. */
849
+ formatDay?: (ts: number) => string;
850
+ /** Rendered after the last message — e.g. a <TypingIndicator /> */
851
+ children?: ReactNode;
852
+ className?: string;
853
+ }
854
+ /**
855
+ * Renders a vertical list of chat messages as bubbles, optionally inserting a
856
+ * date divider when the calendar day changes (requires `timestamp` on messages).
857
+ *
858
+ * @example
859
+ * <MessageList messages={msgs} dayDivider>
860
+ * {pending && <TypingIndicator />}
861
+ * </MessageList>
862
+ */
863
+ declare function MessageList({ messages, dayDivider, accent, formatDay, children, className, }: MessageListProps): react_jsx_runtime.JSX.Element;
864
+
865
+ type ActionCardState = "pending" | "loading" | "done" | "cancelled";
866
+ interface ActionCardLabels {
867
+ /** Title shown while pending (defaults to `title`) */
868
+ pending?: string;
869
+ loading?: string;
870
+ done?: string;
871
+ cancelled?: string;
872
+ confirm?: string;
873
+ cancel?: string;
874
+ }
875
+ interface ActionCardProps {
876
+ /** Title shown in the pending state */
877
+ title?: string;
878
+ /** Lines of content (e.g. a proposed plan) */
879
+ items?: ReactNode[];
880
+ /** Free-form body rendered below items */
881
+ children?: ReactNode;
882
+ state?: ActionCardState;
883
+ onConfirm?: () => void;
884
+ onCancel?: () => void;
885
+ /** Accent (any CSS color) for the pending border/title/confirm button. Defaults to `var(--kit-accent)`. */
886
+ accent?: string;
887
+ /** Override default Korean status labels */
888
+ labels?: ActionCardLabels;
889
+ className?: string;
890
+ }
891
+ /**
892
+ * Inline confirm card for the "propose → confirm → execute" pattern (LLM tool
893
+ * calls, etc.). Unlike `Dialog` it sits inside the message flow. Its color and
894
+ * affordances change with `state`; action buttons show only while `pending`.
895
+ *
896
+ * @example
897
+ * <ActionCard
898
+ * title="이렇게 기록해둘까요?"
899
+ * state={state}
900
+ * items={["🗓 6/4 15:00 디자인리뷰"]}
901
+ * onConfirm={commit}
902
+ * onCancel={cancel}
903
+ * />
904
+ */
905
+ declare function ActionCard({ title, items, children, state, onConfirm, onCancel, accent, labels, className, }: ActionCardProps): react_jsx_runtime.JSX.Element;
906
+
907
+ interface ListRowProps {
908
+ /** Left color bar + active highlight tint. Defaults to `var(--kit-accent)`. */
909
+ accent?: string;
910
+ /** Leading column, e.g. a time like "14:00" */
911
+ lead?: ReactNode;
912
+ /** Secondary leading line under `lead`, e.g. an end time */
913
+ leadSub?: ReactNode;
914
+ title: ReactNode;
915
+ /** Secondary line under the title */
916
+ sub?: ReactNode;
917
+ /** Trailing content, e.g. "● 지금" or a count badge */
918
+ trailing?: ReactNode;
919
+ /** Highlight as the current/active row */
920
+ active?: boolean;
921
+ /**
922
+ * Scale the row height in units (1 = base height, clamped 46–130px). Useful
923
+ * for any timeline where rows have different magnitudes.
924
+ * For a schedule, pass `durationMinutes / 30`.
925
+ */
926
+ heightScale?: number;
927
+ onClick?: () => void;
928
+ className?: string;
929
+ }
930
+ /**
931
+ * Timeline / list row: left color bar, a leading column (time), a title with an
932
+ * optional subtitle, and trailing content. Height can scale via `heightScale` —
933
+ * handy for schedules, to-dos, Gantt-style timelines, and time blocks.
934
+ *
935
+ * @example
936
+ * <ListRow accent="#7fc06a" lead="14:00" title="회의" sub="👥 김상훈" heightScale={2} onClick={open} />
937
+ * <ListRow lead="09:00" title="스탠드업" trailing="● 지금" active />
938
+ */
939
+ declare function ListRow({ accent, lead, leadSub, title, sub, trailing, active, heightScale, onClick, className, }: ListRowProps): react_jsx_runtime.JSX.Element;
940
+
941
+ interface LinkifiedTextProps {
942
+ children: string;
943
+ /** Link color (any CSS color). Defaults to `var(--kit-accent)`. */
944
+ accent?: string;
945
+ /** Also linkify bare domains with a path, e.g. `meet.google.com/abc`. Default: true */
946
+ linkifyBareDomains?: boolean;
947
+ className?: string;
948
+ }
949
+ /**
950
+ * Renders plain text with URLs auto-linked. Preserves newlines
951
+ * (`whitespace-pre-wrap`). Link color follows `--kit-accent` or the `accent` prop.
952
+ *
953
+ * @example
954
+ * <LinkifiedText>회의록: https://docs.google.com/… 그리고 meet.google.com/abc-def</LinkifiedText>
955
+ */
956
+ declare function LinkifiedText({ children, accent, linkifyBareDomains, className, }: LinkifiedTextProps): react_jsx_runtime.JSX.Element;
957
+
958
+ interface Step {
959
+ label: ReactNode;
960
+ /** Optional icon/emoji shown in the badge while incomplete */
961
+ icon?: ReactNode;
962
+ }
963
+ interface StepperProps {
964
+ steps: Step[];
965
+ /** Active step index (0-based) */
966
+ current: number;
967
+ /** Last completed index (default: current - 1). Steps ≤ this show a check. */
968
+ completedThrough?: number;
969
+ /** Makes steps up to `current` clickable */
970
+ onStepClick?: (index: number) => void;
971
+ /** Active/complete color (any CSS color). Defaults to `var(--kit-accent)`. */
972
+ accent?: string;
973
+ className?: string;
974
+ }
975
+ /**
976
+ * Horizontal multi-step progress indicator with connectors. Steps before the
977
+ * cursor show a check, the current step is highlighted, the rest are muted.
978
+ * Great for wizards, multi-phase flows, and onboarding.
979
+ *
980
+ * @example
981
+ * <Stepper current={phase} onStepClick={setPhase} steps={[
982
+ * { label: "분석", icon: "📝" },
983
+ * { label: "준비", icon: "📸" },
984
+ * { label: "생성", icon: "✨" },
985
+ * ]} />
986
+ */
987
+ declare function Stepper({ steps, current, completedThrough, onStepClick, accent, className, }: StepperProps): react_jsx_runtime.JSX.Element;
988
+
989
+ interface CollapsibleProps {
990
+ title: ReactNode;
991
+ /** Subtitle shown only while collapsed */
992
+ subtitle?: ReactNode;
993
+ /** Small badge text shown only while collapsed */
994
+ badge?: ReactNode;
995
+ /** Leading marker — a step number, letter, or icon */
996
+ leading?: ReactNode;
997
+ open: boolean;
998
+ onToggle: () => void;
999
+ /** Show the leading marker as completed (accent + check) */
1000
+ completed?: boolean;
1001
+ /** Small "선택"-style optional tag next to the title */
1002
+ optionalTag?: ReactNode;
1003
+ /** Accent (any CSS color) for expanded ring / completed marker. Defaults to `var(--kit-accent)`. */
1004
+ accent?: string;
1005
+ children: ReactNode;
1006
+ className?: string;
1007
+ }
1008
+ /**
1009
+ * Collapsible card with a header (leading marker, title, optional subtitle/badge)
1010
+ * and a body that shows when `open`. State-aware styling for expanded/completed.
1011
+ * Good for step lists, accordions, and disclosure sections.
1012
+ *
1013
+ * @example
1014
+ * <Collapsible leading={1} title="페르소나 분석" subtitle="스타일 파악"
1015
+ * open={open === 1} onToggle={() => setOpen(open === 1 ? null : 1)} completed>
1016
+ * <p>…</p>
1017
+ * </Collapsible>
1018
+ */
1019
+ declare function Collapsible({ title, subtitle, badge, leading, open, onToggle, completed, optionalTag, accent, children, className, }: CollapsibleProps): react_jsx_runtime.JSX.Element;
1020
+
1021
+ /**
1022
+ * Clipboard copy + feedback. `copied` is `true` (or the passed `key`) for
1023
+ * `timeout` ms after a copy, so one hook can drive many copy targets.
1024
+ *
1025
+ * @example
1026
+ * const { copied, copy } = useCopy();
1027
+ * copy(text); // copied === true
1028
+ * copy(text, "row-3"); // copied === "row-3" (multiple targets)
1029
+ */
1030
+ declare function useCopy(timeout?: number): {
1031
+ copied: string | boolean | null;
1032
+ copy: (text: string, key?: string) => void;
1033
+ };
1034
+ interface CopyButtonProps {
1035
+ /** Text to copy */
1036
+ text: string;
1037
+ /** Button label (default: "복사") */
1038
+ children?: ReactNode;
1039
+ /** Label shown briefly after copying (default: "복사됨!") */
1040
+ copiedLabel?: ReactNode;
1041
+ /** Accent (any CSS color) for the copied state. Defaults to `var(--kit-accent)`. */
1042
+ accent?: string;
1043
+ timeout?: number;
1044
+ className?: string;
1045
+ }
1046
+ /**
1047
+ * Button that copies `text` to the clipboard and flips its label to a confirmation.
1048
+ *
1049
+ * @example
1050
+ * <CopyButton text="npm i @m1kapp/kit">설치 명령 복사</CopyButton>
1051
+ */
1052
+ declare function CopyButton({ text, children, copiedLabel, accent, timeout, className, }: CopyButtonProps): react_jsx_runtime.JSX.Element;
1053
+
1054
+ type ImgStatus = "loading" | "loaded" | "failed";
1055
+ /**
1056
+ * Tries an ordered list of image URLs, falling back to the next on error or
1057
+ * when an image loads too small/broken. Handles already-cached images.
1058
+ * Returns props to spread onto an `<img>`.
1059
+ *
1060
+ * @example
1061
+ * const { status, url, refCallback, handleLoad, handleError } = useImageLoader([a, b]);
1062
+ * if (status === "failed") return <Fallback />;
1063
+ * return <img ref={refCallback} src={url!} onLoad={handleLoad} onError={handleError} />;
1064
+ */
1065
+ declare function useImageLoader(urls: string[]): {
1066
+ status: ImgStatus;
1067
+ url: string | null;
1068
+ refCallback: (el: HTMLImageElement | null) => void;
1069
+ handleLoad: (e: SyntheticEvent<HTMLImageElement>) => void;
1070
+ handleError: () => void;
1071
+ };
1072
+ interface ImgProps {
1073
+ /** Single source, or use `candidates` for ordered fallback */
1074
+ src?: string | null;
1075
+ /** Ordered candidate URLs; first one that loads wins */
1076
+ candidates?: string[];
1077
+ /** Shown when all sources fail (or none given) */
1078
+ fallback?: ReactNode;
1079
+ alt?: string;
1080
+ className?: string;
1081
+ style?: CSSProperties;
1082
+ }
1083
+ /**
1084
+ * `<img>` with multi-URL fallback and a render fallback when every source fails.
1085
+ *
1086
+ * @example
1087
+ * <Img candidates={[avatarUrl, gravatar]} fallback={<Avatar fallback="MH" />} alt="" className="h-10 w-10 rounded-full" />
1088
+ */
1089
+ declare function Img({ src, candidates, fallback, alt, className, style }: ImgProps): react_jsx_runtime.JSX.Element;
1090
+
1091
+ interface SelectOption<T extends string | number> {
1092
+ value: T;
1093
+ label: ReactNode;
1094
+ /** Optional count shown on the right (e.g. number of matches) */
1095
+ count?: number;
1096
+ /** Disable selection (e.g. count === 0) */
1097
+ disabled?: boolean;
1098
+ }
1099
+ interface SelectProps<T extends string | number> {
1100
+ options: SelectOption<T>[];
1101
+ value: T | null;
1102
+ onChange: (value: T | null) => void;
1103
+ /** Trigger text when nothing is selected (default: "전체") */
1104
+ placeholder?: ReactNode;
1105
+ /** Show a top "clear" row that sets value to null (default: true) */
1106
+ allowClear?: boolean;
1107
+ /** Label for the clear row (default: "전체") */
1108
+ clearLabel?: ReactNode;
1109
+ /** Accent (any CSS color) for the selected trigger. Defaults to `var(--kit-accent)`. */
1110
+ accent?: string;
1111
+ className?: string;
1112
+ }
1113
+ /**
1114
+ * Styled dropdown select: a trigger button + an anchored options list with
1115
+ * optional count badges and disabled options. Closes on outside click / Escape.
1116
+ *
1117
+ * @example
1118
+ * <Select value={cat} onChange={setCat} placeholder="카테고리"
1119
+ * options={[{ value: "a", label: "초급", count: 12 }, { value: "b", label: "고급", count: 0, disabled: true }]} />
1120
+ */
1121
+ declare function Select<T extends string | number>({ options, value, onChange, placeholder, allowClear, clearLabel, accent, className, }: SelectProps<T>): react_jsx_runtime.JSX.Element;
1122
+
1123
+ interface ColorPickerProps {
1124
+ /** Selected color as a hex string (e.g. "#e2603f") */
1125
+ value: string;
1126
+ onChange: (hex: string) => void;
1127
+ /** Preset swatches. Defaults to the kit `colors` palette. */
1128
+ palette?: string[];
1129
+ /** Allow picking an arbitrary color via the native color input (default: true) */
1130
+ allowCustom?: boolean;
1131
+ className?: string;
1132
+ }
1133
+ /**
1134
+ * Color swatch picker — preset circles plus an optional custom color input.
1135
+ * The selected swatch gets a ring. Any hex is allowed via the custom input.
1136
+ *
1137
+ * @example
1138
+ * <ColorPicker value={color} onChange={setColor} />
1139
+ * <ColorPicker value={color} onChange={setColor} palette={["#e2603f", "#3b82f6"]} />
1140
+ */
1141
+ declare function ColorPicker({ value, onChange, palette, allowCustom, className, }: ColorPickerProps): react_jsx_runtime.JSX.Element;
1142
+
1143
+ interface CodeBlockProps {
1144
+ code: string;
1145
+ /** Small uppercase label above the code (e.g. "bash", "install") */
1146
+ label?: ReactNode;
1147
+ /** Hint shown on the right while idle (default: "탭하여 복사") */
1148
+ copyHint?: ReactNode;
1149
+ /** Confirmation shown after copying (default: "복사됨!") */
1150
+ copiedLabel?: ReactNode;
1151
+ /** Accent (any CSS color) for the copied state. Defaults to `var(--kit-accent)`. */
1152
+ accent?: string;
1153
+ className?: string;
1154
+ }
1155
+ /**
1156
+ * Tap-to-copy code block with a label and copy feedback.
1157
+ *
1158
+ * @example
1159
+ * <CodeBlock label="install" code="npm i @m1kapp/kit" />
1160
+ */
1161
+ declare function CodeBlock({ code, label, copyHint, copiedLabel, accent, className, }: CodeBlockProps): react_jsx_runtime.JSX.Element;
1162
+
1163
+ interface InlineEditProps {
1164
+ value: string;
1165
+ /** Called with the trimmed value on commit (Enter or blur) */
1166
+ onChange: (value: string) => void;
1167
+ placeholder?: string;
1168
+ /** Disable editing — renders as plain text */
1169
+ readOnly?: boolean;
1170
+ /** Text color (any CSS color), e.g. an entity's color */
1171
+ color?: string;
1172
+ /** Class applied to both the display and the input (for shared typography) */
1173
+ className?: string;
1174
+ }
1175
+ /**
1176
+ * Tap-to-edit text. Shows the value as text; clicking turns it into an
1177
+ * autofocused input that commits on Enter/blur and cancels on Escape.
1178
+ *
1179
+ * @example
1180
+ * <InlineEdit value={name} onChange={rename} placeholder="이름" className="text-lg font-bold" />
1181
+ */
1182
+ declare function InlineEdit({ value, onChange, placeholder, readOnly, color, className, }: InlineEditProps): react_jsx_runtime.JSX.Element;
1183
+
1184
+ interface BarListItem {
1185
+ label: ReactNode;
1186
+ value: number;
1187
+ /** Optional link — the label becomes an anchor */
1188
+ href?: string;
1189
+ }
1190
+ interface BarListProps {
1191
+ items: BarListItem[];
1192
+ /** Bar fill color (any CSS color). Defaults to `var(--kit-accent)`. */
1193
+ accent?: string;
1194
+ /** Format the trailing value (default: localized number) */
1195
+ formatValue?: (value: number) => ReactNode;
1196
+ /** Bars are sized relative to this. Default: sum of values. Pass the max for "share of peak". */
1197
+ total?: number;
1198
+ className?: string;
1199
+ }
1200
+ /**
1201
+ * Horizontal bar list for ranked breakdowns (top pages, referrers, tags…).
1202
+ * Each row is a labeled bar whose width is proportional to its value.
1203
+ *
1204
+ * @example
1205
+ * <BarList items={[{ label: "/", value: 120 }, { label: "/about", value: 64, href: "/about" }]} />
1206
+ */
1207
+ declare function BarList({ items, accent, formatValue, total, className }: BarListProps): react_jsx_runtime.JSX.Element;
1208
+
1209
+ interface ProgressRingProps {
1210
+ /** Current value */
1211
+ value: number;
1212
+ /** Max value (default 1, so `value` is treated as a 0–1 fraction) */
1213
+ max?: number;
1214
+ /** Diameter in px (default 96) */
1215
+ size?: number;
1216
+ /** Stroke width in px (default 8) */
1217
+ thickness?: number;
1218
+ /** Progress stroke color (any CSS color). Defaults to `var(--kit-accent)`. */
1219
+ accent?: string;
1220
+ /** Center content (e.g. the number). Defaults to a percentage. */
1221
+ children?: ReactNode;
1222
+ /** Animate the stroke from empty on mount (default: true) */
1223
+ animate?: boolean;
1224
+ className?: string;
1225
+ }
1226
+ /**
1227
+ * Circular progress ring with a center slot. Good for scores, completion, and
1228
+ * quota indicators.
1229
+ *
1230
+ * @example
1231
+ * <ProgressRing value={7} max={10}><span className="text-2xl font-black">7</span></ProgressRing>
1232
+ * <ProgressRing value={0.42} size={64} />
1233
+ */
1234
+ declare function ProgressRing({ value, max, size, thickness, accent, children, animate, className, }: ProgressRingProps): react_jsx_runtime.JSX.Element;
1235
+
1236
+ interface CountdownLabels {
1237
+ days?: string;
1238
+ hours?: string;
1239
+ mins?: string;
1240
+ secs?: string;
1241
+ }
1242
+ interface CountdownProps {
1243
+ /** Target time — Date, epoch ms, or ISO/parseable date string */
1244
+ to: Date | number | string;
1245
+ /** Called once when the target is reached */
1246
+ onComplete?: () => void;
1247
+ /** Render when the target has passed. Default: a "+Nd" overdue line. */
1248
+ renderOverdue?: (daysOverdue: number) => ReactNode;
1249
+ /** Hide the days cell when 0 */
1250
+ hideZeroDays?: boolean;
1251
+ labels?: CountdownLabels;
1252
+ /** Separator/label color (any CSS color). Defaults to `var(--kit-accent)`. */
1253
+ accent?: string;
1254
+ className?: string;
1255
+ }
1256
+ /**
1257
+ * Live countdown to a target time (days/hours/mins/secs), ticking each second.
1258
+ * Renders an SSR-safe placeholder on first paint and supports overdue display.
1259
+ *
1260
+ * @example
1261
+ * <Countdown to="2026-12-31" onComplete={celebrate} />
1262
+ * <Countdown to={deadline} hideZeroDays />
1263
+ */
1264
+ declare function Countdown({ to, onComplete, renderOverdue, hideZeroDays, labels, accent, className, }: CountdownProps): react_jsx_runtime.JSX.Element | null;
1265
+
1266
+ interface CarouselProps {
1267
+ /** Total number of slides */
1268
+ count: number;
1269
+ /** Active slide index (controlled) */
1270
+ index: number;
1271
+ onChange: (index: number) => void;
1272
+ /** Active slide content (the caller renders based on `index`) */
1273
+ children: ReactNode;
1274
+ /** Wrap around at the ends (default: true) */
1275
+ loop?: boolean;
1276
+ showArrows?: boolean;
1277
+ showDots?: boolean;
1278
+ /** Active dot color (any CSS color). Defaults to `var(--kit-accent)`. */
1279
+ accent?: string;
1280
+ className?: string;
1281
+ }
1282
+ /**
1283
+ * Swipeable carousel with dot indicators and prev/next arrows. Controlled —
1284
+ * you hold the index and render the active slide as children.
1285
+ *
1286
+ * @example
1287
+ * <Carousel count={items.length} index={i} onChange={setI}>
1288
+ * <SlideView item={items[i]} />
1289
+ * </Carousel>
1290
+ */
1291
+ declare function Carousel({ count, index, onChange, children, loop, showArrows, showDots, accent, className, }: CarouselProps): react_jsx_runtime.JSX.Element;
683
1292
 
684
1293
  type PWAInstallState = "android-ready" | "ios-safari" | "installed" | "unsupported";
685
1294
  interface UsePWAInstallReturn {
@@ -893,5 +1502,21 @@ declare function formatNumber(n: number): string;
893
1502
  declare function formatPrice(amount: number, currency?: string, locale?: string): string;
894
1503
 
895
1504
  declare function cn(...inputs: ClassValue[]): string;
1505
+ declare function formatDuration(ms: number, opts?: {
1506
+ style?: "short" | "clock";
1507
+ }): string;
1508
+ interface DayGroup<T> {
1509
+ /** YYYY-MM-DD */
1510
+ date: string;
1511
+ /** 오늘 / 어제 / "M월 D일 (요일)" */
1512
+ label: string;
1513
+ items: T[];
1514
+ }
1515
+ /**
1516
+ * Korean day label relative to today: "오늘" / "어제" / "4월 19일 (토)".
1517
+ * Shared by `groupByDay` and `MessageList`'s day dividers.
1518
+ */
1519
+ declare function formatDayLabel(time: number | string | Date): string;
1520
+ declare function groupByDay<T>(items: T[], getTime: (item: T) => number | string | Date): DayGroup<T>[];
896
1521
 
897
- export { type ApiClient, type ApiClientOptions, ApiError, AppShell, AppShellContent, type AppShellContentProps, AppShellHeader, type AppShellHeaderProps, type AppShellProps, Avatar, type AvatarProps, Badge, type BadgeProps, Button, type ButtonProps, type ColorName, Dialog, type DialogProps, Divider, EmojiButton, type EmojiButtonProps, EmojiPicker, type EmojiPickerLabels, type EmojiPickerProps, EmptyState, type EmptyStateProps, Fab, type FabProps, FontLinks, type FontName, GrassMap, type GrassMapData, type GrassMapLabels, type GrassMapProps, IOSInstallSheet, InAppSheet, type InAppSheetProps, KitStyles, PWAInstallButton, type PWAInstallState, PoweredByKit, type PoweredByKitProps, Section, SectionHeader, type SectionHeaderProps, type SectionProps, ShareButton, type ShareButtonProps, Skeleton, type SkeletonProps, StatChip, type StatChipProps, THEME_SCRIPT, Tab, TabBar, type TabBarProps, type TabProps, ThemeButton, type ThemeButtonProps, ThemeDialog, type ThemeDialogLabels, type ThemeDialogProps, type ToastOptions, ToastProvider, type ToastVariant, Tooltip, type TooltipProps, Typewriter, type TypewriterProps, 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, fontFamily, fonts, formatNumber, formatPrice, mobileViewport, relativeTime, svgIcon, useDebounce, useEscapeKey, useFetch, useFocusTrap, useFormSubmit, useInView, useLocalStorage, usePWAInstall, usePolling, usePortalTarget, useScrollLock, useShare, useToast };
1522
+ export { ActionCard, type ActionCardLabels, type ActionCardProps, type ActionCardState, type ApiClient, type ApiClientOptions, ApiError, AppShell, AppShellContent, type AppShellContentProps, AppShellHeader, type AppShellHeaderProps, type AppShellProps, 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 DayGroup, Dialog, type DialogProps, Divider, EmojiButton, type EmojiButtonProps, EmojiPicker, type EmojiPickerLabels, type EmojiPickerProps, EmptyState, type EmptyStateProps, Fab, type FabProps, Field, type FieldProps, FontLinks, type FontName, GrassMap, type GrassMapData, type GrassMapLabels, type GrassMapProps, IOSInstallSheet, Img, type ImgProps, InAppSheet, type InAppSheetProps, InlineEdit, type InlineEditProps, KitStyles, LinkifiedText, type LinkifiedTextProps, ListRow, type ListRowProps, 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, ThemeButton, type ThemeButtonProps, ThemeDialog, type ThemeDialogLabels, type ThemeDialogProps, type ToastOptions, ToastProvider, type ToastVariant, Tooltip, type TooltipProps, Typewriter, type TypewriterProps, TypingIndicator, type TypingIndicatorProps, 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, fontFamily, fonts, formatDayLabel, formatDuration, formatNumber, formatPrice, groupByDay, mobileViewport, relativeTime, svgIcon, useCopy, useDebounce, useEscapeKey, useFetch, useFocusTrap, useFormSubmit, useImageLoader, useInView, useLocalStorage, usePWAInstall, usePolling, usePortalTarget, useScrollLock, useShare, useToast };