Skip to content

Commit 27266c2

Browse files
refactor: remove SelectionItem, refactor components to use string or string[] as values and having functions for text display, icons, children or amount
1 parent 1e518d5 commit 27266c2

File tree

12 files changed

+311
-305
lines changed

12 files changed

+311
-305
lines changed

lib/input/radio/RadioSwitch.tsx

Lines changed: 30 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,17 @@ import { ct0 } from "~ui/i18n/ct0"
33
import { t4multiselect } from "~ui/input/select/t4multiselect"
44
import { classArr } from "~ui/utils/classArr"
55
import type { SignalObject } from "~ui/utils/createSignalObject"
6-
import type { HasGetOptions } from "~ui/utils/HasGetOptions"
7-
import type { MayHaveChildren } from "~ui/utils/MayHaveChildren"
86
import type { MayHaveClass } from "~ui/utils/MayHaveClass"
9-
import { type MayHaveDisabledAccessor, isDisabled } from "~ui/utils/MayHaveDisabledAccessor"
10-
import type { SelectionItem } from "~ui/utils/SelectionItem"
11-
import type { ValueOrAccessor } from "~ui/utils/ValueOrAccessor"
127

138
/**
149
* https://github.com/radix-ui/primitives/blob/main/packages/react/radio-group/src/Radio.tsx
1510
*/
16-
export interface RadioSwitchProps extends MayHaveClass, MayHaveChildren, RadioSwitchStateProps, HasGetOptions, MayHaveDisabledAccessor {
11+
export interface RadioSwitchProps extends MayHaveClass {
1712
id?: string
18-
disabled?: ValueOrAccessor<boolean>
19-
}
20-
21-
type RadioSwitchStateProps = {
22-
valueSignal: SignalObject<SelectionItem | null>
13+
valueSignal: SignalObject<string>
14+
getOptions: () => string[]
15+
valueText?: (value: string) => string
16+
disabled?: boolean
2317
}
2418

2519
export function RadioSwitch(p: RadioSwitchProps) {
@@ -28,7 +22,7 @@ export function RadioSwitch(p: RadioSwitchProps) {
2822
<div
2923
id={p.id}
3024
role="radiogroup"
31-
data-disabled={isDisabled(p)}
25+
data-disabled={p.disabled}
3226
class={classArr(
3327
"flex flex-wrap gap-2",
3428
// "grid gap-2 rounded-md p-2",
@@ -37,8 +31,16 @@ export function RadioSwitch(p: RadioSwitchProps) {
3731
p.class,
3832
)}
3933
>
40-
<Key each={p.getOptions()} by={(item) => item.value} fallback={<NoItems />}>
41-
{(item) => <Option item={item()} valueSignal={p.valueSignal} disabled={p.disabled} filled={filled} />}
34+
<Key each={p.getOptions()} by={(item) => item} fallback={<NoItems />}>
35+
{(item) => (
36+
<Option
37+
item={item()}
38+
valueSignal={p.valueSignal}
39+
disabled={p.disabled}
40+
filled={filled}
41+
valueText={p.valueText}
42+
/>
43+
)}
4244
</Key>
4345
</div>
4446
)
@@ -48,57 +50,49 @@ function NoItems(p: MayHaveClass) {
4850
return <div class={p.class}>{ct0(t4multiselect.No_entries)}</div>
4951
}
5052

51-
interface Option2Props extends RadioSwitchStateProps, MayHaveDisabledAccessor, MayHaveClass {
52-
item: SelectionItem
53+
interface Option2Props extends MayHaveClass {
54+
item: string
55+
valueSignal: SignalObject<string>
5356
filled: boolean
57+
valueText?: (value: string) => string
58+
disabled?: boolean
5459
}
5560

5661
function Option(p: Option2Props) {
57-
// console.log("Option", p.item.value, "value:", p.valueSignal.get())
5862
return (
5963
<button
6064
type="button"
6165
role="radio"
62-
// value={p.item.value}
63-
disabled={isDisabled(p) || isDisabled(p.item)}
66+
disabled={p.disabled}
6467
aria-checked={isChecked(p)}
6568
data-checked={isChecked(p)}
6669
data-state={isChecked(p) ? "checked" : "unchecked"}
67-
data-disabled={isDisabled(p) || isDisabled(p.item)}
70+
data-disabled={p.disabled}
6871
value={isChecked(p) ? "on" : "off"}
6972
class={classArr(
70-
// "block",
7173
"cursor-pointer select-none",
7274
"rounded-sm",
7375
"px-3 py-2 text-center",
7476
isChecked(p) ? "bg-blue-500 text-white" : "hover:bg-slate-50 dark:hover:bg-slate-900", // bg hover
7577
"flex gap-2",
7678
p.class,
7779
)}
78-
onClick={(e) => optionToggle(p)}
80+
onClick={() => optionToggle(p)}
7981
>
8082
{getText(p)}
8183
</button>
8284
)
8385
}
8486

85-
function optionToggle(p: OptionProps) {
86-
let prev = p.valueSignal.get()
87-
// console.log("optionToggle", p.item.value, "prev:", prev)
88-
if (prev === p.item) return
87+
function optionToggle(p: Option2Props) {
88+
if (p.valueSignal.get() === p.item) return
8989
p.valueSignal.set(p.item)
9090
}
9191

92-
export interface OptionProps extends RadioSwitchStateProps {
93-
item: SelectionItem
94-
}
95-
96-
function isChecked(p: OptionProps) {
97-
return p.item.value === p.valueSignal.get()?.value
92+
function isChecked(p: Option2Props) {
93+
return p.item === p.valueSignal.get()
9894
}
9995

100-
function getText(p: OptionProps): string {
101-
const amount = p.item.amount?.()
102-
if (!amount) return p.item.label
103-
return `${p.item.label} (${amount})`
96+
function getText(p: Option2Props): string {
97+
return p.valueText ? p.valueText(p.item) : p.item
10498
}

lib/input/select/Multiselect.tsx

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ export interface Multiselect2Props extends MayHaveClass, MayHaveChildren {
2121
buttonProps: CorvuPopoverProps
2222
textNoEntries?: string
2323
textAddEntry?: string
24-
getOptions: Accessor<string[]>
2524
valueSignal: SignalObject<string[]>
26-
valueDisplay?: (value: string) => string
25+
getOptions: Accessor<string[]>
26+
valueText?: (value: string) => string
2727
}
2828

2929
export function Multiselect(p: Multiselect2Props) {
@@ -46,10 +46,10 @@ export function Multiselect(p: Multiselect2Props) {
4646
p.class,
4747
)}
4848
>
49-
<SelectedValues2 valueSignal={p.valueSignal} valueDisplay={p.valueDisplay} />
49+
<SelectedValues2 valueSignal={p.valueSignal} valueText={p.valueText} />
5050
<CorvuPopover {...buttonProps}>
5151
<div class={classArr("bg-white dark:bg-black", "max-h-dvh", "grid grid-cols-3 gap-x-2 gap-y-1")}>
52-
<OptionList2 valueSignal={p.valueSignal} getOptions={p.getOptions} valueDisplay={p.valueDisplay} />
52+
<OptionList2 valueSignal={p.valueSignal} getOptions={p.getOptions} valueText={p.valueText} />
5353
</div>
5454
</CorvuPopover>
5555
</div>
@@ -62,21 +62,21 @@ interface Multiselect2OptionState {
6262

6363
interface Multiselect2OptionState {
6464
valueSignal: SignalObject<string[]>
65-
valueDisplay?: (value: string) => string
65+
valueText?: (value: string) => string
6666
}
6767

68-
function SelectedValues2(p: { valueSignal: SignalObject<string[]>; valueDisplay?: (value: string) => string }) {
68+
function SelectedValues2(p: { valueSignal: SignalObject<string[]>; valueText?: (value: string) => string }) {
6969
return (
7070
<div class={"flex flex-wrap gap-1"}>
7171
<Key each={p.valueSignal.get()} by={(item) => item} fallback={<NoItems2 />}>
72-
{(item) => <SelectedValue2 option={item()} valueSignal={p.valueSignal} valueDisplay={p.valueDisplay} />}
72+
{(item) => <SelectedValue2 option={item()} valueSignal={p.valueSignal} valueText={p.valueText} />}
7373
</Key>
7474
</div>
7575
)
7676
}
7777

7878
function SelectedValue2(p: Multiselect2OptionState) {
79-
const label = () => (p.valueDisplay ? p.valueDisplay(p.option) : p.option)
79+
const label = () => (p.valueText ? p.valueText(p.option) : p.option)
8080
return (
8181
<ButtonIcon
8282
variant={buttonVariant.outline}
@@ -95,19 +95,19 @@ function SelectedValue2(p: Multiselect2OptionState) {
9595
function OptionList2(p: {
9696
valueSignal: SignalObject<string[]>
9797
getOptions: Accessor<string[]>
98-
valueDisplay?: (value: string) => string
98+
valueText?: (value: string) => string
9999
}) {
100100
return (
101101
<>
102102
<Key each={p.getOptions()} by={(item) => item} fallback={<NoItems2 />}>
103-
{(item) => <ListOption2 option={item()} valueSignal={p.valueSignal} valueDisplay={p.valueDisplay} />}
103+
{(item) => <ListOption2 option={item()} valueSignal={p.valueSignal} valueText={p.valueText} />}
104104
</Key>
105105
</>
106106
)
107107
}
108108

109109
function ListOption2(p: Multiselect2OptionState) {
110-
const label = () => (p.valueDisplay ? p.valueDisplay(p.option) : p.option)
110+
const label = () => (p.valueText ? p.valueText(p.option) : p.option)
111111
return (
112112
<>
113113
<ButtonIcon

lib/input/select/NativeSingleSelect.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export type StringStringFn = (value: string) => string
1212
export interface NativeSingleSelectProps extends MayHaveClass, MayHaveChildren {
1313
valueSignal: SignalObject<string>
1414
getOptions: Accessor<string[]>
15-
valueDisplay?: StringStringFn
15+
valueText?: StringStringFn
1616
id?: string
1717
}
1818

@@ -33,7 +33,7 @@ export function NativeSingleSelect(p: NativeSingleSelectProps) {
3333
onChange={(e) => onChange(e, p)}
3434
>
3535
<Key each={p.getOptions()} by={(item) => item} fallback={<NoItems />}>
36-
{(getItem) => <SelectItem itemValue={getItem()} valueDisplay={p.valueDisplay} />}
36+
{(getItem) => <SelectItem itemValue={getItem()} valueText={p.valueText} />}
3737
</Key>
3838
</select>
3939
)
@@ -55,20 +55,20 @@ function NoItems(p: MayHaveClass) {
5555

5656
interface SelectItemProps extends MayHaveClass {
5757
itemValue: string
58-
valueDisplay?: StringStringFn
58+
valueText?: StringStringFn
5959
}
6060

6161
function SelectItem(p: SelectItemProps) {
6262
return (
6363
<option value={p.itemValue} class={p.class}>
64-
{getDisplayValue(p.itemValue, p.valueDisplay)}
64+
{getDisplayValue(p.itemValue, p.valueText)}
6565
</option>
6666
)
6767
}
6868

69-
function getDisplayValue(itemValue: string, valueDisplay?: StringStringFn) {
70-
if (!valueDisplay) return itemValue
71-
const hasValue = valueDisplay(itemValue)
69+
function getDisplayValue(itemValue: string, valueText?: StringStringFn) {
70+
if (!valueText) return itemValue
71+
const hasValue = valueText(itemValue)
7272
if (!hasValue) return itemValue
7373
return hasValue
7474
}

lib/interactive/tabs/TabItem.tsx

Lines changed: 0 additions & 6 deletions
This file was deleted.

0 commit comments

Comments
 (0)