@synerise/ds-search-bar 1.4.33 → 1.4.35
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/CHANGELOG.md +8 -0
- package/CLAUDE.md +120 -0
- package/dist/SearchBar.styles.js +2 -2
- package/package.json +8 -7
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,14 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [1.4.35](https://github.com/Synerise/synerise-design/compare/@synerise/ds-search-bar@1.4.34...@synerise/ds-search-bar@1.4.35) (2026-07-23)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @synerise/ds-search-bar
|
|
9
|
+
|
|
10
|
+
## [1.4.34](https://github.com/Synerise/synerise-design/compare/@synerise/ds-search-bar@1.4.33...@synerise/ds-search-bar@1.4.34) (2026-07-09)
|
|
11
|
+
|
|
12
|
+
**Note:** Version bump only for package @synerise/ds-search-bar
|
|
13
|
+
|
|
6
14
|
## [1.4.33](https://github.com/Synerise/synerise-design/compare/@synerise/ds-search-bar@1.4.32...@synerise/ds-search-bar@1.4.33) (2026-06-17)
|
|
7
15
|
|
|
8
16
|
**Note:** Version bump only for package @synerise/ds-search-bar
|
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# SearchBar (`@synerise/ds-search-bar`)
|
|
2
|
+
|
|
3
|
+
> Controlled search input with optional left icon, value prefix, and clear button.
|
|
4
|
+
|
|
5
|
+
## Package structure
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
src/
|
|
9
|
+
SearchBar.tsx — main component (forwardRef to HTMLDivElement)
|
|
10
|
+
SearchBar.types.ts — SearchBarProps, StyledSearchBar types
|
|
11
|
+
SearchBar.styles.tsx — all styled-components (SearchBarWrapper, SearchBar, etc.)
|
|
12
|
+
SearchBar.constants.ts — pixel layout constants
|
|
13
|
+
ValuePrefix.tsx — internal sub-component for the prefix label
|
|
14
|
+
index.ts — public exports
|
|
15
|
+
modules.d.ts — @testing-library/jest-dom ambient import
|
|
16
|
+
__specs__/
|
|
17
|
+
SearchBar.spec.tsx — Vitest tests
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Public exports
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
export default SearchBar; // default export
|
|
24
|
+
export type { SearchBarProps, StyledSearchBar }; // named type exports
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### `SearchBar`
|
|
28
|
+
|
|
29
|
+
`forwardRef<HTMLDivElement, SearchBarProps>` — spreads remaining HTML attributes onto the outer wrapper div.
|
|
30
|
+
|
|
31
|
+
| Prop | Type | Default | Description |
|
|
32
|
+
|------|------|---------|-------------|
|
|
33
|
+
| `value` | `string` | — | **Required.** Controlled input value. |
|
|
34
|
+
| `onSearchChange` | `(value: string) => void` | — | **Required.** Called on every keystroke with the current input string. |
|
|
35
|
+
| `placeholder` | `ReactNode` | — | **Required.** Rendered via a custom overlay div (native input placeholder is kept transparent). String value is also forwarded to the native `<input>` as a fallback for a11y. |
|
|
36
|
+
| `onClearInput` | `() => void` | — | When provided, a clear button appears whenever `value` is non-empty **or** `valuePrefix` is set. |
|
|
37
|
+
| `clearTooltip` | `ReactNode` | `<FormattedMessage id="DS.SEARCH-BAR.CLEAR-TOOLTIP" defaultMessage="Clear" />` | Tooltip content for the clear icon. |
|
|
38
|
+
| `clearTooltipProps` | `Partial<TooltipProps>` | — | Extra props forwarded to the `<Tooltip>` wrapping the clear icon. |
|
|
39
|
+
| `iconLeft` | `ReactNode` | — | Element rendered in the absolute left slot (24 px reserved, 12 px gap). |
|
|
40
|
+
| `valuePrefix` | `ReactNode` | — | Label rendered between the left icon and the input. Its width is measured via `ResizeObserver` and the input padding adjusts dynamically. |
|
|
41
|
+
| `autofocus` | `boolean` | — | If `true`, focuses the `<input>` on mount (uses `preventScroll`). |
|
|
42
|
+
| `autofocusDelay` | `number` | — | Milliseconds to wait before focusing when `autofocus` is `true`. |
|
|
43
|
+
| `disabled` | `boolean` | — | Disables pointer-events and user-select on the wrapper; propagates `disabled` to the inner `<Input>`. |
|
|
44
|
+
| `borderRadius` | `boolean` | — | Adds `border-radius: 3px` to the wrapper (off by default — wrapper has no radius). |
|
|
45
|
+
| `handleInputRef` | `(ref: MutableRefObject<HTMLInputElement \| null>) => void` | — | Callback to access the inner `<input>` element. Inherited from `InputProps`. |
|
|
46
|
+
| `className` | `string` | — | Merged with `is-focused` class when the input has focus. |
|
|
47
|
+
|
|
48
|
+
### `SearchBarProps`
|
|
49
|
+
|
|
50
|
+
Full prop type — `WithHTMLAttributes<HTMLDivElement, …>` so all standard div attributes are accepted and forwarded.
|
|
51
|
+
|
|
52
|
+
### `StyledSearchBar`
|
|
53
|
+
|
|
54
|
+
Utility type for extending `SearchBar` with additional styled-component props:
|
|
55
|
+
```ts
|
|
56
|
+
type StyledSearchBar<CustomProps extends object = object> = StyledComponent<
|
|
57
|
+
ForwardRefExoticComponent<SearchBarProps & RefAttributes<HTMLDivElement>>,
|
|
58
|
+
object,
|
|
59
|
+
CustomProps,
|
|
60
|
+
never
|
|
61
|
+
>;
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Usage patterns
|
|
65
|
+
|
|
66
|
+
```tsx
|
|
67
|
+
import SearchBar from '@synerise/ds-search-bar';
|
|
68
|
+
import { SearchM } from '@synerise/ds-icon';
|
|
69
|
+
|
|
70
|
+
// Minimal controlled usage
|
|
71
|
+
const [query, setQuery] = React.useState('');
|
|
72
|
+
|
|
73
|
+
<SearchBar
|
|
74
|
+
value={query}
|
|
75
|
+
placeholder="Search"
|
|
76
|
+
onSearchChange={setQuery}
|
|
77
|
+
/>
|
|
78
|
+
|
|
79
|
+
// With left icon, clear button, and prefix
|
|
80
|
+
<SearchBar
|
|
81
|
+
value={query}
|
|
82
|
+
placeholder="Search"
|
|
83
|
+
onSearchChange={setQuery}
|
|
84
|
+
onClearInput={() => setQuery('')}
|
|
85
|
+
iconLeft={<SearchM />}
|
|
86
|
+
valuePrefix="Name:"
|
|
87
|
+
autofocus
|
|
88
|
+
/>
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Styling
|
|
92
|
+
|
|
93
|
+
- Fixed height of **52 px** for the inner `<input>` element and placeholder overlay.
|
|
94
|
+
- Bottom border: `1px solid grey-100`. No border-radius unless `borderRadius` prop is set.
|
|
95
|
+
- Input padding is computed dynamically from constants in `SearchBar.constants.ts` based on whether `iconLeft` and `valuePrefix` are present.
|
|
96
|
+
- Placeholder is a custom absolutely-positioned `<div>` — native placeholder is hidden via transparent color across all vendor prefixes. This is intentional to allow `ReactNode` placeholders.
|
|
97
|
+
- On hover and when focused (`.is-focused`), `IconLeftWrapper` SVG and `ValuePrefixTitle` turn `blue-600`; `ClearInputWrapper` SVG turns `red-600`.
|
|
98
|
+
- `disabled` state: SVGs fill `grey-400`; `pointer-events: none`.
|
|
99
|
+
- Minimum wrapper width: `150px`.
|
|
100
|
+
|
|
101
|
+
## Key dependencies
|
|
102
|
+
|
|
103
|
+
- `@synerise/ds-input` — inner `<Input>` component; `StyledInput` type used for the `SearchBar` styled component
|
|
104
|
+
- `@synerise/ds-icon` — renders the clear (`Close3M`) and left icons
|
|
105
|
+
- `@synerise/ds-tooltip` — wraps the clear icon
|
|
106
|
+
- `@synerise/ds-typography` — `Title` (level 6) used to render `valuePrefix`
|
|
107
|
+
- `@synerise/ds-utils` — `useResizeObserver` (measures `valuePrefix` width), `WithHTMLAttributes` type
|
|
108
|
+
- `@synerise/ds-core` — `useTheme` for palette access; `renderWithProvider` in tests
|
|
109
|
+
- `classnames` — merges `className` with `is-focused` state class
|
|
110
|
+
- `react-intl` — default `clearTooltip` message (`DS.SEARCH-BAR.CLEAR-TOOLTIP`)
|
|
111
|
+
|
|
112
|
+
## Implementation notes
|
|
113
|
+
|
|
114
|
+
- The component is a **controlled input** — there is no internal value state; `value` must be managed by the parent.
|
|
115
|
+
- The clear button only appears when `onClearInput` is provided **and** either `value` or `valuePrefix` is non-empty. Callers must reset `valuePrefix` themselves if needed.
|
|
116
|
+
- `ValuePrefix` is an internal-only component (not exported). It uses `useResizeObserver` to track its rendered width and notifies the parent via `setValuePrefixWidth`; on unmount it resets the width to `0`.
|
|
117
|
+
- `autofocusDelay` only takes effect when `autofocus` is also `true`; the timeout is cleaned up on unmount/dependency change.
|
|
118
|
+
- The `forwardedRef` is attached to the outer `SearchBarWrapper` div, not the `<input>`. Use `handleInputRef` to get the inner `<input>` element.
|
|
119
|
+
- `VALUE_PREFIX_WRAPPER_LEFT_VALUE` is fixed at `16 + 24 + 12 = 52 px` — this always reserves space for a left icon, even when no `iconLeft` is provided. This means the prefix will appear offset from the left edge even without an icon.
|
|
120
|
+
- Tests use Jest (not Vitest) — `jest.config.js` present; the package has not been migrated to Vitest.
|
package/dist/SearchBar.styles.js
CHANGED
|
@@ -39,11 +39,11 @@ const PlaceholderWrapper = /* @__PURE__ */ styled.div.withConfig({
|
|
|
39
39
|
const SearchBar = /* @__PURE__ */ styled(Input).withConfig({
|
|
40
40
|
displayName: "SearchBarstyles__SearchBar",
|
|
41
41
|
componentId: "sc-qhi5c4-5"
|
|
42
|
-
})(["&&&{position:relative;height:52px;padding:0;input
|
|
42
|
+
})(["&&&{position:relative;height:52px;padding:0;input{position:absolute;top:0;left:0;max-width:100%;height:52px;border:0;background:", ";box-sizing:content-box;&:focus{box-shadow:inset 0px -2px 0px 0px ", ";}::-webkit-input-placeholder{line-height:52px;color:transparent;}:-moz-placeholder{line-height:52px;color:transparent;}::-moz-placeholder{line-height:52px;color:transparent;}:-ms-input-placeholder{line-height:52px;color:transparent;}}}"], (props) => props.theme.palette["grey-050"], (props) => props.theme.palette["blue-600"]);
|
|
43
43
|
const SearchBarWrapper = /* @__PURE__ */ styled.div.withConfig({
|
|
44
44
|
displayName: "SearchBarstyles__SearchBarWrapper",
|
|
45
45
|
componentId: "sc-qhi5c4-6"
|
|
46
|
-
})(["position:relative;overflow:hidden;border-bottom:1px solid ", ";pointer-events:", ";user-select:", ";border-radius:", ";min-width:150px;&&&{svg{transition:all 0.3s ease-out;fill:", ";}input
|
|
46
|
+
})(["position:relative;overflow:hidden;border-bottom:1px solid ", ";pointer-events:", ";user-select:", ";border-radius:", ";min-width:150px;&&&{svg{transition:all 0.3s ease-out;fill:", ";}input{border-radius:0;line-height:18px;", "}&:hover{", "{svg{fill:", ";}}", "{svg{fill:", ";}}", "{color:", ";}}}&.is-focused{", "{svg{fill:", ";}}", "{svg{fill:", ";}}", "{color:", ";}}"], (props) => props.theme.palette["grey-100"], (props) => props.disabled ? "none" : "", (props) => props.disabled ? "none" : "", (props) => props.borderRadius ? "3px" : "", (props) => props.disabled ? props.theme.palette["grey-400"] : "", getPaddingAndWidthForSearchBarAntInput, IconLeftWrapper, (props) => props.theme.palette["blue-600"], ClearInputWrapper, (props) => props.theme.palette["red-600"], ValuePrefixTitle, (props) => props.theme.palette["blue-600"], IconLeftWrapper, (props) => props.theme.palette["blue-600"], ClearInputWrapper, (props) => props.theme.palette["red-600"], ValuePrefixTitle, (props) => props.theme.palette["blue-600"]);
|
|
47
47
|
export {
|
|
48
48
|
ClearInputWrapper,
|
|
49
49
|
IconLeftWrapper,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@synerise/ds-search-bar",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.35",
|
|
4
4
|
"description": "SearchBar UI Component for the Synerise Design System",
|
|
5
5
|
"license": "ISC",
|
|
6
6
|
"repository": "Synerise/synerise-design",
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
"files": [
|
|
18
18
|
"/dist",
|
|
19
19
|
"CHANGELOG.md",
|
|
20
|
+
"CLAUDE.md",
|
|
20
21
|
"README.md",
|
|
21
22
|
"package.json",
|
|
22
23
|
"LICENSE.md"
|
|
@@ -41,11 +42,11 @@
|
|
|
41
42
|
],
|
|
42
43
|
"types": "dist/index.d.ts",
|
|
43
44
|
"dependencies": {
|
|
44
|
-
"@synerise/ds-icon": "^1.18.
|
|
45
|
-
"@synerise/ds-input": "^1.7.
|
|
46
|
-
"@synerise/ds-tooltip": "^1.5.
|
|
47
|
-
"@synerise/ds-typography": "^1.1.
|
|
48
|
-
"@synerise/ds-utils": "^1.10.
|
|
45
|
+
"@synerise/ds-icon": "^1.18.5",
|
|
46
|
+
"@synerise/ds-input": "^1.7.13",
|
|
47
|
+
"@synerise/ds-tooltip": "^1.5.4",
|
|
48
|
+
"@synerise/ds-typography": "^1.1.27",
|
|
49
|
+
"@synerise/ds-utils": "^1.10.2",
|
|
49
50
|
"classnames": "^2.5.1"
|
|
50
51
|
},
|
|
51
52
|
"peerDependencies": {
|
|
@@ -55,5 +56,5 @@
|
|
|
55
56
|
"styled-components": "^5.3.3",
|
|
56
57
|
"vitest": "4"
|
|
57
58
|
},
|
|
58
|
-
"gitHead": "
|
|
59
|
+
"gitHead": "d0a43cc43d8528a36f105aceea52ab470edb71d9"
|
|
59
60
|
}
|