- 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>
42 lines
2.0 KiB
TypeScript
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>
|
|
)
|
|
}
|