Skip to content

Commit 00784f2

Browse files
authored
MultiSelect fire oncreate event for all user-created options (#316)
- update `oncreate` event in MultiSelect to trigger for all user-created options (now consistent behavior across different option types) - unit tests to verify correct payload for `oncreate` event (covering string, number, and object cases)
1 parent ecade96 commit 00784f2

File tree

3 files changed

+55
-2
lines changed

3 files changed

+55
-2
lines changed

src/lib/MultiSelect.svelte

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,8 +232,9 @@
232232
} else {
233233
option_to_add = searchText as Option // else create custom option as string
234234
}
235-
oncreate?.({ option: option_to_add })
236235
}
236+
// Fire oncreate event for all user-created options, regardless of type
237+
oncreate?.({ option: option_to_add })
237238
if (allowUserOptions === `append`) options = [...options, option_to_add]
238239
}
239240

src/lib/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export interface MultiSelectNativeEvents {
4545
// custom events created by MultiSelect
4646
export interface MultiSelectEvents<T extends Option = Option> {
4747
onadd?: (data: { option: T }) => unknown
48-
oncreate?: (data: { option: T }) => unknown
48+
oncreate?: (data: { option: T }) => unknown // fires when users entered custom text from which new option is created
4949
onremove?: (data: { option: T }) => unknown
5050
onremoveAll?: (data: { options: T[] }) => unknown
5151
onchange?: (data: {

tests/unit/MultiSelect.svelte.test.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1250,6 +1250,58 @@ test.each([
12501250
},
12511251
)
12521252

1253+
test.each([
1254+
// String options case
1255+
[[`foo`, `bar`, `baz`], `new-string-option`, `new-string-option`],
1256+
// Number options case
1257+
[[1, 2, 3], `42`, 42],
1258+
// Object options case
1259+
[
1260+
[{ label: `foo` }, { label: `bar` }, { label: `baz` }],
1261+
`new-object-option`,
1262+
{ label: `new-object-option` },
1263+
],
1264+
])(
1265+
`fires oncreate event with correct payload when user creates new option for different option types`,
1266+
async (options, search_text, expected_created_option) => {
1267+
const oncreate_spy = vi.fn()
1268+
const onadd_spy = vi.fn()
1269+
1270+
mount(MultiSelect, {
1271+
target: document.body,
1272+
props: {
1273+
options,
1274+
allowUserOptions: true,
1275+
oncreate: oncreate_spy,
1276+
onadd: onadd_spy,
1277+
},
1278+
})
1279+
1280+
const input = doc_query<HTMLInputElement>(`input[autocomplete]`)
1281+
1282+
// Enter text that doesn't match any existing option
1283+
input.value = search_text
1284+
input.dispatchEvent(input_event)
1285+
await tick()
1286+
1287+
// Click on the "Create this option..." message
1288+
const create_option_li = doc_query(`ul.options li.user-msg`)
1289+
create_option_li.click()
1290+
1291+
// Verify oncreate event was fired with correct payload
1292+
expect(oncreate_spy).toHaveBeenCalledTimes(1)
1293+
expect(oncreate_spy).toHaveBeenCalledWith({
1294+
option: expected_created_option,
1295+
})
1296+
1297+
// Verify onadd event was also fired (user-created options trigger both events)
1298+
expect(onadd_spy).toHaveBeenCalledTimes(1)
1299+
expect(onadd_spy).toHaveBeenCalledWith({
1300+
option: expected_created_option,
1301+
})
1302+
},
1303+
)
1304+
12531305
describe.each([
12541306
[true, (opt: Option) => opt],
12551307
[false, (opt: Option) => opt],

0 commit comments

Comments
 (0)