Files
HMDesign/packages/sw/ai/examples/SWSearchControl.tsx
T
shkim4andClaude Opus 5.5 e27385e0f0 feat(sw): prepare reusable AI-friendly component package
- Ship an AI guide in the package (ai/: usage rules, component catalog,
  design rules, composition patterns) via package.json files.
- Add examples A-D that import only public exports: default header,
  viewer header, feature header, and a consumer-side search extension
  that reuses SWHeaderInput and the public SW tokens.
- Add SW-only checks: docs/API consistency, tarball consumer project
  (React 19 + TS + Vite typecheck/build) and a browser check (27/27).
- No runtime source or public API change; README gains a pointer section.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 11:22:07 +09:00

42 lines
2.0 KiB
TypeScript

// Example D extension — a NEW control written in the consuming project (3rd priority).
// Decision record: the package has no search component (MISSING). Its editable SWHeaderInput covers the
// text entry (Enter / blur commit, Escape cancel, IME), so it is reused; only the field surface and the
// search icon button are new. They read the public SW tokens (sw-search-control.css) — no copied
// package code, no hm-sw-* class, no new design values. Not registered as a package component.
import { SWHeaderInput } from "@hm-design/sw"
import "./sw-search-control.css"
export interface SWSearchControlProps {
/** Committed query (host state). */
value: string
/** A new query was committed with Enter or by leaving the input. */
onValueChange?: (value: string) => void
/** Search with the current query (icon button or a committed query). */
onSearch?: (query: string) => void
label?: string
disabled?: boolean
}
export function SWSearchControl({ value, onValueChange, onSearch, label = "검색", disabled }: SWSearchControlProps) {
return (
<div className="app-sw-search" role="search" data-disabled={disabled || undefined}>
<span className="app-sw-search__text">
<span className="app-sw-search__label" aria-hidden="true">{label}</span>
<SWHeaderInput
aria-label={`${label}어`}
value={value}
placeholder="객체 이름"
disabled={disabled}
onCommit={next => { onValueChange?.(next); onSearch?.(next) }}
/>
</span>
<button type="button" className="app-sw-search__button" aria-label={label} disabled={disabled} onClick={() => onSearch?.(value)}>
<svg width="16" height="16" viewBox="0 0 16 16" aria-hidden="true" focusable="false">
<circle cx="7" cy="7" r="4.75" fill="none" stroke="currentColor" strokeWidth="1.5" />
<path d="M10.5 10.5 14 14" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" />
</svg>
</button>
</div>
)
}