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>
This commit is contained in:
1 parent
50bf5bda8e
commit
e27385e0f0
26 files changed
+1349
-1
No files matched your search
@@ -0,0 +1,41 @@
|
||||
// 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>
|
||||
)
|
||||
}
|
||||
Reference in new issue
Block a user