Skip to content

Commit e456d97

Browse files
refactor(multiselect): allow passing styling classe to sub components, extract used props into separate interfaces
1 parent 2483a2f commit e456d97

File tree

1 file changed

+49
-12
lines changed

1 file changed

+49
-12
lines changed

lib/input/select/Multiselect.tsx

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,20 @@ export interface Multiselect2Props extends MayHaveClass, MayHaveInnerClass, MayH
2525
valueSignal: SignalObject<string[]>
2626
getOptions: Accessor<string[]>
2727
valueText?: (value: string) => string
28+
addEntryClass?: string
29+
noItemsClass?: string
30+
listOptionClass?: string
2831
}
2932

3033
export function Multiselect(p: Multiselect2Props) {
34+
const buttonClass = classMerge(p.addEntryClass, p.buttonProps.class)
3135
const buttonProps = mergeProps(
3236
{
3337
icon: mdiPlus,
3438
children: p.textAddEntry ?? ct0(t4multiselect.Add_entry),
3539
},
3640
p.buttonProps,
41+
{ class: buttonClass },
3742
)
3843
return (
3944
<div
@@ -47,18 +52,30 @@ export function Multiselect(p: Multiselect2Props) {
4752
p.class,
4853
)}
4954
>
50-
<SelectedValues valueSignal={p.valueSignal} valueText={p.valueText} />
55+
<SelectedValues valueSignal={p.valueSignal} valueText={p.valueText} noItemsClass={p.noItemsClass} />
5156
<CorvuPopover {...buttonProps} innerClass={classArr(p.innerClass ?? "grid grid-cols-3 gap-x-2 gap-y-1")}>
52-
<OptionList valueSignal={p.valueSignal} getOptions={p.getOptions} valueText={p.valueText} />
57+
<OptionList
58+
valueSignal={p.valueSignal}
59+
getOptions={p.getOptions}
60+
valueText={p.valueText}
61+
noItemsClass={p.noItemsClass}
62+
listOptionClass={p.listOptionClass}
63+
/>
5364
</CorvuPopover>
5465
</div>
5566
)
5667
}
5768

58-
function SelectedValues(p: { valueSignal: SignalObject<string[]>; valueText?: (value: string) => string }) {
69+
interface SelectedValuesProps {
70+
valueSignal: SignalObject<string[]>
71+
valueText?: (value: string) => string
72+
noItemsClass?: string
73+
}
74+
75+
function SelectedValues(p: SelectedValuesProps) {
5976
return (
6077
<div class={"flex flex-wrap gap-1"}>
61-
<Key each={p.valueSignal.get()} by={(item) => item} fallback={<NoItems />}>
78+
<Key each={p.valueSignal.get()} by={(item) => item} fallback={<NoItems class={p.noItemsClass} />}>
6279
{(item) => <SelectedValue option={item()} valueSignal={p.valueSignal} valueText={p.valueText} />}
6380
</Key>
6481
</div>
@@ -70,7 +87,10 @@ interface MultiselectOptionState {
7087
valueSignal: SignalObject<string[]>
7188
valueText?: (value: string) => string
7289
}
73-
function SelectedValue(p: MultiselectOptionState) {
90+
91+
interface SelectedValueProps extends MultiselectOptionState {}
92+
93+
function SelectedValue(p: SelectedValueProps) {
7494
const label = () => (p.valueText ? p.valueText(p.option) : p.option)
7595
return (
7696
<ButtonIcon
@@ -87,21 +107,36 @@ function SelectedValue(p: MultiselectOptionState) {
87107
)
88108
}
89109

90-
function OptionList(p: {
110+
interface OptionListProps {
91111
valueSignal: SignalObject<string[]>
92112
getOptions: Accessor<string[]>
93113
valueText?: (value: string) => string
94-
}) {
114+
noItemsClass?: string
115+
listOptionClass?: string
116+
}
117+
118+
function OptionList(p: OptionListProps) {
95119
return (
96120
<>
97-
<Key each={p.getOptions()} by={(item) => item} fallback={<NoItems />}>
98-
{(item) => <ListOption option={item()} valueSignal={p.valueSignal} valueText={p.valueText} />}
121+
<Key each={p.getOptions()} by={(item) => item} fallback={<NoItems class={p.noItemsClass} />}>
122+
{(item) => (
123+
<ListOption
124+
option={item()}
125+
valueSignal={p.valueSignal}
126+
valueText={p.valueText}
127+
listOptionClass={p.listOptionClass}
128+
/>
129+
)}
99130
</Key>
100131
</>
101132
)
102133
}
103134

104-
function ListOption(p: MultiselectOptionState) {
135+
interface ListOptionProps extends MultiselectOptionState {
136+
listOptionClass?: string
137+
}
138+
139+
function ListOption(p: ListOptionProps) {
105140
const label = () => (p.valueText ? p.valueText(p.option) : p.option)
106141
return (
107142
<>
@@ -115,7 +150,7 @@ function ListOption(p: MultiselectOptionState) {
115150
toggleOption(p)
116151
}}
117152
variant={buttonVariant.ghost}
118-
class={"justify-start"}
153+
class={classMerge("justify-start", p.listOptionClass)}
119154
>
120155
{label()}
121156
</ButtonIcon>
@@ -146,7 +181,9 @@ function optionIsSelected(p: MultiselectOptionState) {
146181
return p.valueSignal.get().includes(p.option)
147182
}
148183

149-
function NoItems(p: MayHaveClass = {}) {
184+
interface NoItemsProps extends MayHaveClass {}
185+
186+
function NoItems(p: NoItemsProps) {
150187
return (
151188
<div
152189
class={classMerge(

0 commit comments

Comments
 (0)