@synerise/ds-select 1.5.0 → 1.5.1
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 +6 -0
- package/CLAUDE.md +6 -0
- package/dist/Select.js +9 -3
- package/dist/Select.types.d.ts +2 -2
- package/dist/components/OptionList.js +19 -1
- package/dist/utils/helpers.d.ts +1 -1
- package/dist/utils/helpers.js +2 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,12 @@
|
|
|
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.5.1](https://github.com/synerise/synerise-design/compare/@synerise/ds-select@1.5.0...@synerise/ds-select@1.5.1) (2026-08-13)
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
- honour Option children, optionLabelProp and optionFilterProp in select ([640a1c2](https://github.com/synerise/synerise-design/commit/640a1c27e677de165e195072a22bac891a065fac))
|
|
11
|
+
|
|
6
12
|
# [1.5.0](https://github.com/synerise/synerise-design/compare/@synerise/ds-select@1.4.0...@synerise/ds-select@1.5.0) (2026-08-11)
|
|
7
13
|
|
|
8
14
|
### Features
|
package/CLAUDE.md
CHANGED
|
@@ -153,6 +153,12 @@ Class hooks are `ds-select-*` (`.ds-select`, `.ds-select-selection-item`, `.ds-s
|
|
|
153
153
|
- **Option resolution** — `useSelectOptions` returns `resolvedOptions` (from `options` prop, else
|
|
154
154
|
`getOptionsFromChildren(children)`) and `displayedOptions` (after client filtering and, in `tags`
|
|
155
155
|
mode, a create-row prepended for the typed text). `filterOption={false}` disables local filtering.
|
|
156
|
+
- **Row vs selector display (antd parity)** — the dropdown row renders `option.children ?? label ??
|
|
157
|
+
value`, the selector renders the field named by `optionLabelProp` (`label`, `children`, `value`,
|
|
158
|
+
`title`, …) and falls back to `label`. So `<Option label={compact}>{rich}</Option>` shows `rich` in
|
|
159
|
+
the list and `compact` in the selector, while options-as-data (no children) uses `label` for both.
|
|
160
|
+
- **Filtering** — `defaultFilter` matches the field named by `optionFilterProp` (`title`, `children`,
|
|
161
|
+
`value`, …), else `label` then `children`; non-string fields (JSX nodes) fall back to the value.
|
|
156
162
|
- **`Option.value` is optional** — falls back to the element's React `key` (antd parity); callbacks
|
|
157
163
|
expose `option.key`.
|
|
158
164
|
- **Keyboard nav is hand-rolled (not ds-dropdown's)** — Select is a *combobox*: focus stays on the
|
package/dist/Select.js
CHANGED
|
@@ -174,10 +174,16 @@ const SelectInner = forwardRef((props, ref) => {
|
|
|
174
174
|
const $size = size === "large" ? "large" : "default";
|
|
175
175
|
const labelFor = (v) => {
|
|
176
176
|
const option = findOption(resolvedOptions, v);
|
|
177
|
-
if (option
|
|
178
|
-
return
|
|
177
|
+
if (!option) {
|
|
178
|
+
return v;
|
|
179
179
|
}
|
|
180
|
-
|
|
180
|
+
if (optionLabelProp) {
|
|
181
|
+
const custom = option[optionLabelProp];
|
|
182
|
+
if (custom !== void 0) {
|
|
183
|
+
return custom;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return option.label ?? v;
|
|
181
187
|
};
|
|
182
188
|
const setOpen = (next) => {
|
|
183
189
|
if (isDisabled) {
|
package/dist/Select.types.d.ts
CHANGED
|
@@ -14,12 +14,12 @@ export type SelectOption = {
|
|
|
14
14
|
value: RawValueType;
|
|
15
15
|
/** antd-parity alias of `value`; some consumers read `option.key` in callbacks. */
|
|
16
16
|
key?: RawValueType;
|
|
17
|
-
/**
|
|
17
|
+
/** Selector display, and the dropdown row too unless `children` carries its own content. */
|
|
18
18
|
label?: ReactNode;
|
|
19
19
|
disabled?: boolean;
|
|
20
20
|
/** Native `title` on the option (hover tooltip / accessible text), mirrors antd. */
|
|
21
21
|
title?: ReactNode;
|
|
22
|
-
/**
|
|
22
|
+
/** Raw children of `<Select.Option>` — the dropdown row content (antd parity). */
|
|
23
23
|
children?: ReactNode;
|
|
24
24
|
/** antd parity: forwarded to the rendered option row. */
|
|
25
25
|
style?: CSSProperties;
|
|
@@ -25,7 +25,25 @@ const OptionList = ({
|
|
|
25
25
|
}, children: loading ? /* @__PURE__ */ jsx(Loading, { className: "ds-select-loading", children: /* @__PURE__ */ jsx(Loader, { size: "M" }) }) : options.length === 0 ? /* @__PURE__ */ jsx(NotFound, { className: "ds-select-empty", children: notFoundContent }) : /* @__PURE__ */ jsx(ScrollList, { children: /* @__PURE__ */ jsx(Scrollbar, { absolute: true, maxHeight: Number(listHeight) || DEFAULT_LIST_HEIGHT, onScroll: onPopupScroll ? (event) => onPopupScroll(event) : void 0, children: /* @__PURE__ */ jsx(Inner, { role: "listbox", id: listboxId, "aria-multiselectable": isMultiple || void 0, children: options.map((option, index) => {
|
|
26
26
|
const isSelected = selectedValues.includes(option.value);
|
|
27
27
|
const optionAttrs = Object.fromEntries(Object.entries(option).filter(([key]) => key.startsWith("data-") || key.startsWith("aria-")));
|
|
28
|
-
return /* @__PURE__ */ jsx(
|
|
28
|
+
return /* @__PURE__ */ jsx(
|
|
29
|
+
OptionItem,
|
|
30
|
+
{
|
|
31
|
+
id: optionDomId(index),
|
|
32
|
+
role: "option",
|
|
33
|
+
className: cx("ds-select-item-option", isSelected && "ds-select-item-option-selected", index === activeIndex && "ds-select-item-option-active"),
|
|
34
|
+
selected: isSelected,
|
|
35
|
+
"aria-selected": isSelected,
|
|
36
|
+
"data-testid": "select-option",
|
|
37
|
+
title: typeof option.title === "string" ? option.title : void 0,
|
|
38
|
+
text: option.children ?? option.label ?? option.value,
|
|
39
|
+
style: option.style,
|
|
40
|
+
disabled: option.disabled,
|
|
41
|
+
onMouseEnter: () => onOptionActivate(index),
|
|
42
|
+
onClick: () => onOptionSelect(option),
|
|
43
|
+
...optionAttrs
|
|
44
|
+
},
|
|
45
|
+
rowKey ? rowKey(option) : option.value
|
|
46
|
+
);
|
|
29
47
|
}) }) }) }) });
|
|
30
48
|
export {
|
|
31
49
|
OptionList
|
package/dist/utils/helpers.d.ts
CHANGED
|
@@ -5,5 +5,5 @@ export declare const DEFAULT_LIST_HEIGHT = 256;
|
|
|
5
5
|
export declare const cx: (...classes: (string | false | undefined)[]) => string;
|
|
6
6
|
/** Normalise a `SelectValue` to an array of raw values. */
|
|
7
7
|
export declare const toArray: (value: SelectValue) => RawValueType[];
|
|
8
|
-
/** Built-in filter: case-insensitive substring on `optionFilterProp` (or label/value). */
|
|
8
|
+
/** Built-in filter: case-insensitive substring on `optionFilterProp` (or label/children/value). */
|
|
9
9
|
export declare const defaultFilter: (optionFilterProp?: string) => FilterOptionFn;
|
package/dist/utils/helpers.js
CHANGED
|
@@ -7,7 +7,8 @@ const toArray = (value) => {
|
|
|
7
7
|
return Array.isArray(value) ? value : [value];
|
|
8
8
|
};
|
|
9
9
|
const defaultFilter = (optionFilterProp) => (input, option) => {
|
|
10
|
-
const
|
|
10
|
+
const candidates = optionFilterProp ? [option[optionFilterProp]] : [option.label, option.children];
|
|
11
|
+
const haystack = candidates.find((candidate) => typeof candidate === "string") ?? String(option.value);
|
|
11
12
|
return haystack.toLowerCase().includes(input.toLowerCase());
|
|
12
13
|
};
|
|
13
14
|
export {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@synerise/ds-select",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.1",
|
|
4
4
|
"description": "Select UI Component for the Synerise Design System",
|
|
5
5
|
"license": "ISC",
|
|
6
6
|
"repository": "synerise/synerise-design",
|
|
@@ -58,5 +58,5 @@
|
|
|
58
58
|
"styled-components": "^5.3.3",
|
|
59
59
|
"vitest": "4"
|
|
60
60
|
},
|
|
61
|
-
"gitHead": "
|
|
61
|
+
"gitHead": "0a103024461277b2f410e19a88d437764017c1d1"
|
|
62
62
|
}
|