kang-components 0.9.1 → 0.9.3

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
@@ -23,6 +23,10 @@ export { ConfirmDialog } from './confirm-dialog.js';
23
23
  export type { ConfirmDialogProps } from './confirm-dialog.js';
24
24
  export { BottomSheet } from './bottom-sheet.js';
25
25
  export type { BottomSheetProps } from './bottom-sheet.js';
26
+ export { SearchField } from './search-field.js';
27
+ export type { SearchFieldProps } from './search-field.js';
28
+ export { SearchBar } from './search-bar.js';
29
+ export type { SearchBarProps } from './search-bar.js';
26
30
  export { buildTheme, theme, hexToRgb } from './theme.js';
27
31
  export type { ThemeType } from './theme.js';
28
32
  export { lightPalette, darkPalette } from './palettes.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,YAAY,EACZ,mBAAmB,EACnB,kBAAkB,EAClB,YAAY,EACZ,WAAW,EACX,iBAAiB,EACjB,gBAAgB,GAChB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,YAAY,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAE3D,OAAO,EACN,oBAAoB,EACpB,eAAe,EACf,cAAc,GACd,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACjE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,OAAO,EACN,kBAAkB,EAClB,uBAAuB,EACvB,aAAa,EACb,iBAAiB,EACjB,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,cAAc,EACd,aAAa,GACb,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAExD,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC7D,YAAY,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE5D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACzD,YAAY,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AACtE,YAAY,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACrF,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC7D,YAAY,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC7D,YAAY,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,YAAY,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACzD,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC1D,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEtD,YAAY,EACX,eAAe,EACf,mBAAmB,EACnB,cAAc,GACd,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,QAAQ,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AACtE,YAAY,EACX,aAAa,EACb,gBAAgB,EAChB,kBAAkB,GAClB,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,YAAY,EACZ,mBAAmB,EACnB,kBAAkB,EAClB,YAAY,EACZ,WAAW,EACX,iBAAiB,EACjB,gBAAgB,GAChB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,YAAY,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAE3D,OAAO,EACN,oBAAoB,EACpB,eAAe,EACf,cAAc,GACd,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACjE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,OAAO,EACN,kBAAkB,EAClB,uBAAuB,EACvB,aAAa,EACb,iBAAiB,EACjB,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,cAAc,EACd,aAAa,GACb,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAExD,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC7D,YAAY,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE5D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACzD,YAAY,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AACtE,YAAY,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACrF,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC7D,YAAY,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC7D,YAAY,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,YAAY,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,YAAY,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACzD,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC1D,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEtD,YAAY,EACX,eAAe,EACf,mBAAmB,EACnB,cAAc,GACd,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,QAAQ,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AACtE,YAAY,EACX,aAAa,EACb,gBAAgB,EAChB,kBAAkB,GAClB,MAAM,gBAAgB,CAAC"}
package/dist/index.js CHANGED
@@ -12,6 +12,8 @@ export { Badge } from './badge.js';
12
12
  export { default as ToggleSwitch } from './toggle-switch.js';
13
13
  export { ConfirmDialog } from './confirm-dialog.js';
14
14
  export { BottomSheet } from './bottom-sheet.js';
15
+ export { SearchField } from './search-field.js';
16
+ export { SearchBar } from './search-bar.js';
15
17
  export { buildTheme, theme, hexToRgb } from './theme.js';
16
18
  export { lightPalette, darkPalette } from './palettes.js';
17
19
  export { ListItem, UnorderedListItemContainer } from './list-item.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,YAAY,EACZ,mBAAmB,EACnB,kBAAkB,EAClB,YAAY,EACZ,WAAW,EACX,iBAAiB,EACjB,gBAAgB,GAChB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAGzD,OAAO,EACN,oBAAoB,EACpB,eAAe,EACf,cAAc,GACd,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAGjE,OAAO,EACN,kBAAkB,EAClB,uBAAuB,EACvB,aAAa,EACb,iBAAiB,EACjB,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,cAAc,EACd,aAAa,GACb,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAG7D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEzD,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEtE,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAE7D,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAE7D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhD,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEzD,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAS1D,OAAO,EAAE,QAAQ,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,YAAY,EACZ,mBAAmB,EACnB,kBAAkB,EAClB,YAAY,EACZ,WAAW,EACX,iBAAiB,EACjB,gBAAgB,GAChB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAGzD,OAAO,EACN,oBAAoB,EACpB,eAAe,EACf,cAAc,GACd,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAGjE,OAAO,EACN,kBAAkB,EAClB,uBAAuB,EACvB,aAAa,EACb,iBAAiB,EACjB,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,cAAc,EACd,aAAa,GACb,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAG7D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEzD,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEtE,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAE7D,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAE7D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAG5C,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEzD,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAS1D,OAAO,EAAE,QAAQ,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * SearchBar — a *composite*: a back button + the expanding {@link SearchField} +
3
+ * a slide-in reveal, wired together with their animation as one unit. This is
4
+ * the next tier above kang's primitives — a group of components that must work
5
+ * together — so apps (xunzi's native search, the Hua Wen Reader add-on) mount
6
+ * the same animated search bar rather than re-implementing it.
7
+ *
8
+ * Presentational + domain-free: the host controls `active` (drives the reveal),
9
+ * owns the `value`/`onChange`, and supplies an optional `onBack`. Positioning
10
+ * (e.g. over a shell/backstage) and any decoration (titles, watermarks) stay
11
+ * with the host, which can wrap this or pass a `title` slot.
12
+ *
13
+ * Composes kang's own `BackButton` + `SearchField`; `styled-components`, `react`
14
+ * and `@react-spring/web` are the only things it pulls in.
15
+ */
16
+ import { type ReactElement, type ReactNode } from 'react';
17
+ export interface SearchBarProps {
18
+ /** Drives the slide-in/out reveal (and whether the field is interactive). */
19
+ active: boolean;
20
+ value: string;
21
+ onChange: (value: string) => void;
22
+ /** Optional back/close button rendered before the field. */
23
+ onBack?: () => void;
24
+ backAriaLabel?: string;
25
+ placeholder?: string;
26
+ ariaLabel?: string;
27
+ /** Optional leading title/label rendered above the field row. */
28
+ title?: ReactNode;
29
+ className?: string;
30
+ }
31
+ export declare function SearchBar({ active, value, onChange, onBack, backAriaLabel, placeholder, ariaLabel, title, className, }: SearchBarProps): ReactElement;
32
+ export default SearchBar;
33
+ //# sourceMappingURL=search-bar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-bar.d.ts","sourceRoot":"","sources":["../src/search-bar.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAa,KAAK,YAAY,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAMrE,MAAM,WAAW,cAAc;IAC9B,6EAA6E;IAC7E,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,4DAA4D;IAC5D,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iEAAiE;IACjE,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAqBD,wBAAgB,SAAS,CAAC,EACzB,MAAM,EACN,KAAK,EACL,QAAQ,EACR,MAAM,EACN,aAAsB,EACtB,WAAW,EACX,SAAS,EACT,KAAK,EACL,SAAS,GACT,EAAE,cAAc,GAAG,YAAY,CA+C/B;AAED,eAAe,SAAS,CAAC"}
@@ -0,0 +1,65 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * SearchBar — a *composite*: a back button + the expanding {@link SearchField} +
4
+ * a slide-in reveal, wired together with their animation as one unit. This is
5
+ * the next tier above kang's primitives — a group of components that must work
6
+ * together — so apps (xunzi's native search, the Hua Wen Reader add-on) mount
7
+ * the same animated search bar rather than re-implementing it.
8
+ *
9
+ * Presentational + domain-free: the host controls `active` (drives the reveal),
10
+ * owns the `value`/`onChange`, and supplies an optional `onBack`. Positioning
11
+ * (e.g. over a shell/backstage) and any decoration (titles, watermarks) stay
12
+ * with the host, which can wrap this or pass a `title` slot.
13
+ *
14
+ * Composes kang's own `BackButton` + `SearchField`; `styled-components`, `react`
15
+ * and `@react-spring/web` are the only things it pulls in.
16
+ */
17
+ import { useEffect } from 'react';
18
+ import { styled } from 'styled-components';
19
+ import { animated, useSpring } from '@react-spring/web';
20
+ import BackButton from './back-button.js';
21
+ import { SearchField } from './search-field.js';
22
+ const Reveal = styled(animated.div) `
23
+ display: flex;
24
+ flex-direction: column;
25
+ gap: 0.5rem;
26
+ will-change: transform, opacity;
27
+ `;
28
+ const Row = styled.div `
29
+ display: flex;
30
+ align-items: center;
31
+ gap: 0.5rem;
32
+ `;
33
+ /** Lets the (explicitly-width-animated) SearchField fill the row beside the back button. */
34
+ const FieldWrap = styled.div `
35
+ flex: 1 1 auto;
36
+ min-width: 0;
37
+ `;
38
+ export function SearchBar({ active, value, onChange, onBack, backAriaLabel = 'Back', placeholder, ariaLabel, title, className, }) {
39
+ const [reveal, revealApi] = useSpring(() => ({
40
+ y: -16,
41
+ opacity: 0,
42
+ display: 'none',
43
+ }));
44
+ useEffect(() => {
45
+ const config = { tension: 300, friction: 30 };
46
+ if (active) {
47
+ revealApi.start({ y: 0, opacity: 1, display: 'flex', config });
48
+ }
49
+ else {
50
+ revealApi.start({
51
+ y: -16,
52
+ opacity: 0,
53
+ config,
54
+ onRest: () => revealApi.set({ display: 'none' }),
55
+ });
56
+ }
57
+ }, [active, revealApi]);
58
+ return (_jsxs(Reveal, { className: className, style: {
59
+ opacity: reveal.opacity,
60
+ display: reveal.display,
61
+ transform: reveal.y.to((v) => `translateY(${v}px)`),
62
+ }, children: [title, _jsxs(Row, { children: [onBack && _jsx(BackButton, { onClick: onBack, ariaLabel: backAriaLabel }), _jsx(FieldWrap, { children: _jsx(SearchField, { value: value, onChange: onChange, placeholder: placeholder, ariaLabel: ariaLabel, autoExpand: active }, active ? 'open' : 'closed') })] })] }));
63
+ }
64
+ export default SearchBar;
65
+ //# sourceMappingURL=search-bar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-bar.js","sourceRoot":"","sources":["../src/search-bar.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,SAAS,EAAqC,MAAM,OAAO,CAAC;AACrE,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,UAAU,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAiBhD,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAA;;;;;CAKlC,CAAC;AAEF,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAA;;;;CAIrB,CAAC;AAEF,4FAA4F;AAC5F,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAA;;;CAG3B,CAAC;AAEF,MAAM,UAAU,SAAS,CAAC,EACzB,MAAM,EACN,KAAK,EACL,QAAQ,EACR,MAAM,EACN,aAAa,GAAG,MAAM,EACtB,WAAW,EACX,SAAS,EACT,KAAK,EACL,SAAS,GACO;IAChB,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,SAAS,CAAC,GAAG,EAAE,CAAC,CAAC;QAC5C,CAAC,EAAE,CAAC,EAAE;QACN,OAAO,EAAE,CAAC;QACV,OAAO,EAAE,MAAyB;KAClC,CAAC,CAAC,CAAC;IAEJ,SAAS,CAAC,GAAG,EAAE;QACd,MAAM,MAAM,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;QAC9C,IAAI,MAAM,EAAE,CAAC;YACZ,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QAChE,CAAC;aAAM,CAAC;YACP,SAAS,CAAC,KAAK,CAAC;gBACf,CAAC,EAAE,CAAC,EAAE;gBACN,OAAO,EAAE,CAAC;gBACV,MAAM;gBACN,MAAM,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;aAChD,CAAC,CAAC;QACJ,CAAC;IACF,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;IAExB,OAAO,CACN,MAAC,MAAM,IACN,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE;YACN,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC;SACnD,aAEA,KAAK,EACN,MAAC,GAAG,eACF,MAAM,IAAI,KAAC,UAAU,IAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,GAAI,EACpE,KAAC,SAAS,cAET,KAAC,WAAW,IAEX,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,QAAQ,EAClB,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE,SAAS,EACpB,UAAU,EAAE,MAAM,IALb,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAM9B,GACS,IACP,IACE,CACT,CAAC;AACH,CAAC;AAED,eAAe,SAAS,CAAC"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * SearchField — a domain-free, animated search input. A surface "pill" that
3
+ * expands from an icon-only circle to a full-width field on mount, with a
4
+ * primary-colored magnifier, a borderless input that fades in once expanded,
5
+ * and a round clear (×) button that appears when there is text.
6
+ *
7
+ * Extracted as a shared primitive so xunzi's search banner, the Hua Wen Reader
8
+ * surface, and future apps all render the same field. Theming follows kang
9
+ * conventions: every color reads a `theme.colors.*` token with a literal
10
+ * fallback, so it adapts to a `ThemeProvider` yet still renders without one.
11
+ *
12
+ * `styled-components`, `react`, and (for the expand animation) `@react-spring/web`
13
+ * are the only things this module pulls in; react-spring is an optional peer.
14
+ */
15
+ import { type ReactElement } from 'react';
16
+ export interface SearchFieldProps {
17
+ /** Current input value (controlled). */
18
+ value: string;
19
+ /** Called with the new value on input, and with `''` when cleared. */
20
+ onChange: (value: string) => void;
21
+ /** Placeholder shown in the (expanded) field. */
22
+ placeholder?: string;
23
+ /** Accessible label for the input. */
24
+ ariaLabel?: string;
25
+ /** Play the expand-from-circle animation on mount (default: true). */
26
+ autoExpand?: boolean;
27
+ /** Class name passthrough for layout/positioning by the consumer. */
28
+ className?: string;
29
+ }
30
+ export declare function SearchField({ value, onChange, placeholder, ariaLabel, autoExpand, className, }: SearchFieldProps): ReactElement;
31
+ export default SearchField;
32
+ //# sourceMappingURL=search-field.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-field.d.ts","sourceRoot":"","sources":["../src/search-field.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAA+B,KAAK,YAAY,EAAE,MAAM,OAAO,CAAC;AAIvE,MAAM,WAAW,gBAAgB;IAChC,wCAAwC;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,sEAAsE;IACtE,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,iDAAiD;IACjD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sCAAsC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sEAAsE;IACtE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,qEAAqE;IACrE,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AA8ED,wBAAgB,WAAW,CAAC,EAC3B,KAAK,EACL,QAAQ,EACR,WAAW,EACX,SAAS,EACT,UAAiB,EACjB,SAAS,GACT,EAAE,gBAAgB,GAAG,YAAY,CAgFjC;AAED,eAAe,WAAW,CAAC"}
@@ -0,0 +1,121 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * SearchField — a domain-free, animated search input. A surface "pill" that
4
+ * expands from an icon-only circle to a full-width field on mount, with a
5
+ * primary-colored magnifier, a borderless input that fades in once expanded,
6
+ * and a round clear (×) button that appears when there is text.
7
+ *
8
+ * Extracted as a shared primitive so xunzi's search banner, the Hua Wen Reader
9
+ * surface, and future apps all render the same field. Theming follows kang
10
+ * conventions: every color reads a `theme.colors.*` token with a literal
11
+ * fallback, so it adapts to a `ThemeProvider` yet still renders without one.
12
+ *
13
+ * `styled-components`, `react`, and (for the expand animation) `@react-spring/web`
14
+ * are the only things this module pulls in; react-spring is an optional peer.
15
+ */
16
+ import { useEffect, useRef, useState } from 'react';
17
+ import { styled } from 'styled-components';
18
+ import { animated, useSpring } from '@react-spring/web';
19
+ const c = (token, fallback) => ({ theme }) => theme?.colors?.[token] ?? fallback;
20
+ const Pill = styled(animated.div) `
21
+ display: flex;
22
+ align-items: center;
23
+ height: 2.75rem;
24
+ min-height: 2.75rem;
25
+ box-sizing: border-box;
26
+ border-radius: 999px;
27
+ background: ${c('surface', '#fdfcf8')};
28
+ box-shadow: 0 2px 8px ${c('shadowSubtle', 'rgba(0, 0, 0, 0.08)')};
29
+ overflow: hidden;
30
+ will-change: width, padding, gap;
31
+ `;
32
+ const IconWrap = styled.span `
33
+ display: flex;
34
+ align-items: center;
35
+ color: ${c('primary', '#4db6ac')};
36
+ font-size: 1.25rem;
37
+ flex-shrink: 0;
38
+ `;
39
+ const Field = styled(animated.input) `
40
+ border: none;
41
+ outline: none;
42
+ background: transparent;
43
+ font-size: 1rem;
44
+ color: ${c('onSurface', '#333')};
45
+ font-family: inherit;
46
+ min-width: 0;
47
+
48
+ &::placeholder {
49
+ color: ${c('onSurface', '#333')};
50
+ opacity: 0.4;
51
+ }
52
+ `;
53
+ const Clear = styled(animated.button) `
54
+ display: flex;
55
+ align-items: center;
56
+ justify-content: center;
57
+ width: 1.5rem;
58
+ height: 1.5rem;
59
+ border: none;
60
+ border-radius: 50%;
61
+ background: ${c('outline', '#9e9e9e')};
62
+ color: ${c('surface', '#fdfcf8')};
63
+ cursor: pointer;
64
+ padding: 0;
65
+ flex-shrink: 0;
66
+ opacity: 0.7;
67
+ transition: opacity 0.2s ease;
68
+ &:active {
69
+ opacity: 1;
70
+ }
71
+ `;
72
+ const SearchGlyph = () => (_jsxs("svg", { viewBox: "0 0 24 24", width: "1em", height: "1em", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", children: [_jsx("circle", { cx: "11", cy: "11", r: "7" }), _jsx("line", { x1: "16.5", y1: "16.5", x2: "21", y2: "21" })] }));
73
+ const CloseGlyph = () => (_jsxs("svg", { viewBox: "0 0 24 24", width: "0.85em", height: "0.85em", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", children: [_jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" }), _jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" })] }));
74
+ export function SearchField({ value, onChange, placeholder, ariaLabel, autoExpand = true, className, }) {
75
+ const inputRef = useRef(null);
76
+ const [expanded, setExpanded] = useState(false);
77
+ const [field, fieldApi] = useSpring(() => ({ expand: 0 }));
78
+ const [input, inputApi] = useSpring(() => ({ opacity: 0, y: 10 }));
79
+ useEffect(() => {
80
+ // Treat opt-out / reduced-motion / non-browser (test/SSR) envs as already
81
+ // expanded so the field is immediately usable.
82
+ const skip = !autoExpand ||
83
+ typeof window === 'undefined' ||
84
+ !window.matchMedia ||
85
+ window.matchMedia('(prefers-reduced-motion: reduce)').matches;
86
+ if (skip) {
87
+ fieldApi.set({ expand: 1 });
88
+ inputApi.set({ opacity: 1, y: 0 });
89
+ setExpanded(true);
90
+ return;
91
+ }
92
+ const raf = requestAnimationFrame(() => {
93
+ fieldApi.start({
94
+ expand: 1,
95
+ config: { tension: 220, friction: 24 },
96
+ onRest: () => {
97
+ setExpanded(true);
98
+ inputApi.start({ opacity: 1, y: 0, config: { tension: 260, friction: 22 } });
99
+ },
100
+ });
101
+ });
102
+ return () => cancelAnimationFrame(raf);
103
+ }, [autoExpand, fieldApi, inputApi]);
104
+ return (_jsxs(Pill, { className: className, style: {
105
+ width: field.expand.to((v) => `calc(2.75rem + (100% - 2.75rem) * ${v})`),
106
+ gap: field.expand.to((v) => `${0.5 * v}rem`),
107
+ paddingLeft: '0.75rem',
108
+ paddingRight: field.expand.to((v) => `${0.75 + 0.25 * v}rem`),
109
+ }, children: [_jsx(IconWrap, { children: _jsx(SearchGlyph, {}) }), _jsx(Field, { ref: inputRef, style: {
110
+ opacity: input.opacity,
111
+ transform: input.y.to((y) => `translateY(${y}px)`),
112
+ flex: expanded ? '1 1 auto' : '0 0 0',
113
+ width: expanded ? 'auto' : 0,
114
+ pointerEvents: expanded ? 'auto' : 'none',
115
+ }, type: "text", inputMode: "search", autoComplete: "off", autoCorrect: "off", autoCapitalize: "off", spellCheck: false, placeholder: placeholder, value: value, onChange: (e) => onChange(e.target.value), "aria-label": ariaLabel }), value.length > 0 && (_jsx(Clear, { style: { opacity: input.opacity, pointerEvents: expanded ? 'auto' : 'none' }, onClick: () => {
116
+ onChange('');
117
+ inputRef.current?.focus();
118
+ }, "aria-label": "Clear search", children: _jsx(CloseGlyph, {}) }))] }));
119
+ }
120
+ export default SearchField;
121
+ //# sourceMappingURL=search-field.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-field.js","sourceRoot":"","sources":["../src/search-field.tsx"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kang-components",
3
- "version": "0.9.1",
3
+ "version": "0.9.3",
4
4
  "description": "Generic, domain-free React UI primitives (CSS-first press feedback, delayed-action hook, spring presets, cross-fading text, circle icon button).",
5
5
  "type": "module",
6
6
  "license": "MIT",