가져오기Imports
컴포넌트를 진입점에서 한 번에 받거나, 쓰는 파일만 하위 경로로 가져옵니다.Take every component from the entry point, or only the files you use through a subpath.
진입점과 하위 경로Entry point and subpaths
@horon-ai/react는 빌드 산출물 없이 TypeScript 소스를 그대로 배포합니다. 진입점은 모든 컴포넌트를 다시 내보내고, 하위 경로는 export map으로 같은 소스 파일을 가리킵니다. 두 경로는 같은 파일에 도착하므로 타입과 동작이 같습니다.The package ships TypeScript source with no build output. The entry point re-exports every component, and a subpath points at the same source file through the export map. Both routes reach the same file, so types and behavior match.
- 진입점: import { Button, Card } from "@horon-ai/react" 한 줄로 이름을 가져옵니다.Entry point: one line, import { Button, Card } from "@horon-ai/react", pulls the names you name.
- 하위 경로: 파일 이름이 곧 경로입니다. @horon-ai/react/components/button은 src/components/button.tsx로 연결됩니다.Subpath: the file name is the path. @horon-ai/react/components/button maps to src/components/button.tsx.
- 하위 경로는 번들을 쓰는 컴포넌트로 좁힙니다. 여러 컴포넌트를 쓰는 화면은 진입점 목록이 읽기 쉽습니다.A subpath keeps a bundle to the components it uses. A screen that uses several reads better as one entry-point list.
import { Button, Card, Input } from "@horon-ai/react"; export function Example() { return ( <Card title="Inbox Manager" description="6 emails need you."> <Input surface="solid" placeholder="Search bots" /> <Button>New bot</Button> </Card> ); }
import { Button } from "@horon-ai/react/components/button"; import { Card } from "@horon-ai/react/components/card";
Prop 타입Prop types
각 컴포넌트 파일은 자기 prop 타입을 함께 내보냅니다. ButtonProps, CardProps, KbdProps처럼 컴포넌트 이름에 Props를 붙인 이름이고, 진입점과 하위 경로 어디서나 같은 이름으로 가져옵니다.Each component file exports its prop type: the component name with Props, such as ButtonProps, CardProps or KbdProps. The name is the same from the entry point and from a subpath.
- 타입만 필요하면 import type으로 가져옵니다. 번들에는 남지 않습니다.When you only need the type, use import type. Nothing reaches the bundle.
- 컴포넌트를 감싸는 쪽은 이 타입을 그대로 펼쳐 쓰면 prop 목록을 다시 적지 않아도 됩니다.A wrapper can spread the type instead of restating the prop list.
import { Card, type CardProps } from "@horon-ai/react"; export function Panel(props: CardProps) { return <Card {...props} />; }
훅과 플랫폼 헬퍼Hooks and platform helpers
훅과 플랫폼 헬퍼에는 하위 경로가 없습니다. 진입점에서만 가져옵니다. 플랫폼 헬퍼는 detectOs, detectRuntime, formatShortcut, isModKey, matchesShortcut 다섯 함수이고, Os, PlatformInput, Runtime, RuntimeWindow, ShortcutEvent 타입을 함께 내보냅니다.Hooks and platform helpers have no subpath; they come from the entry point only. The platform helpers are five functions, detectOs, detectRuntime, formatShortcut, isModKey and matchesShortcut, with the Os, PlatformInput, Runtime, RuntimeWindow and ShortcutEvent types.
- 클래스 병합에 쓰는 cn도 진입점에 있습니다. Horon 토큰 이름을 아는 tailwind-merge라서 넘긴 클래스가 컴포넌트 기본값을 덮습니다.cn lives on the entry point too: a tailwind-merge that knows the Horon token names, so a class you pass overrides a component default.
- 훅은 컴포넌트 하위 경로에 섞여 있지 않습니다. 목록은 사이드바의 React · 훅 그룹에 있습니다.Hooks are not mixed into the component subpaths. The sidebar's React · Hooks group lists them.
import { cn, detectOs, formatShortcut } from "@horon-ai/react"; function shortcutLabel(userAgent: string) { const os = detectOs({ userAgent }); return formatShortcut("Mod+K", os); } const className = cn("bg-bg-surface", "bg-glass-regular");
클라이언트 경계The client boundary
패키지 소스에는 "use client" 지시문이 없습니다. 훅을 쓰는 컴포넌트도 예외가 아닙니다. 경계는 소비하는 쪽이 정합니다. Astro에서는 client:load 같은 지시문이 아일랜드를 브라우저에서 켜고, Next.js App Router에서는 컴포넌트를 가져오는 자기 파일 위에 "use client"를 둡니다.The package source has no "use client" directive, and components that call hooks are no exception. The consumer sets the boundary: in Astro a client:load style directive starts the island in the browser, and in the Next.js App Router you put "use client" on your own file that imports the component.
- 지시문을 패키지에 넣으면 서버 컴포넌트에서 쓸 수 있는 정적 컴포넌트까지 클라이언트로 넘어갑니다. 그래서 패키지는 지시문을 두지 않습니다.A directive inside the package would push even the static components a server component can use across the boundary, so the package leaves it out.
"use client"; import { useState } from "react"; import { Switch } from "@horon-ai/react"; export function Setting() { const [on, setOn] = useState(false); return <Switch label="Notifications" checked={on} onCheckedChange={setOn} />; }
커서 잔상 가져오기Import the cursor ghost
잔상은 컴포넌트가 아니라 부수 효과 import입니다. import "@horon-ai/react/cursor-ghost" 한 줄이면 React 없이도 붙습니다. 이 사이트도 BaseLayout에서 이 줄을 씁니다. 붙는 조건과 옵션은 커서 잔상 페이지에 있습니다.The ghost is a side-effect import, not a component. One line, import "@horon-ai/react/cursor-ghost", mounts it without React. This site does it in BaseLayout. The cursor ghost page covers when it mounts and how to configure it.