Skip to content

Commit 2db0171

Browse files
feat(check): narroweded types for const values
1 parent fc403cc commit 2db0171

File tree

2 files changed

+42
-49
lines changed

2 files changed

+42
-49
lines changed

lib/input/check/CheckMultiple.tsx

Lines changed: 20 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,27 @@ import { classesGridCols3xl } from "~ui/static/container/classesGridCols"
66
import { classArr } from "~ui/utils/classArr"
77
import { classMerge } from "~ui/utils/classMerge"
88
import type { SignalObject } from "~ui/utils/createSignalObject"
9-
import type { HasGetOptions } from "~ui/utils/HasGetOptions"
10-
import type { HasValueSignalStringArray } from "~ui/utils/HasValueSignalStringArray"
11-
import type { MayHaveValueText } from "~ui/utils/HasValueText"
129
import type { MayHaveButtonVariant } from "~ui/utils/MayHaveButtonVariant"
1310
import type { MayHaveClass } from "~ui/utils/MayHaveClass"
1411
import type { MayHaveDisabled } from "~ui/utils/MayHaveDisabled"
1512
import type { MayHaveId } from "~ui/utils/MayHaveId"
1613
import type { MayHaveInnerClass } from "~ui/utils/MayHaveInnerClass"
1714

18-
export interface CheckMultipleProps
19-
extends HasValueSignalStringArray,
20-
HasGetOptions,
21-
MayHaveValueText,
22-
MayHaveId,
15+
export interface CheckMultipleProps<T extends string>
16+
extends MayHaveId,
2317
MayHaveButtonVariant,
2418
MayHaveClass,
2519
MayHaveInnerClass,
2620
MayHaveDisabled {
21+
// state
22+
valueSignal: SignalObject<T[]>
23+
getOptions: () => T[]
24+
valueText?: (value: T) => string
2725
// styling
2826
optionClass?: string
2927
}
3028

31-
export function CheckMultiple(p: CheckMultipleProps) {
29+
export function CheckMultiple<T extends string = string>(p: CheckMultipleProps<T>) {
3230
return (
3331
<div
3432
id={p.id}
@@ -54,17 +52,14 @@ export function CheckMultiple(p: CheckMultipleProps) {
5452
)
5553
}
5654

57-
interface OptionListProps
58-
extends HasValueSignalStringArray,
59-
HasGetOptions,
60-
MayHaveValueText,
61-
MayHaveButtonVariant,
62-
MayHaveInnerClass,
63-
MayHaveDisabled {
55+
interface OptionListProps<T extends string> extends MayHaveButtonVariant, MayHaveDisabled, MayHaveInnerClass {
56+
valueSignal: SignalObject<T[]>
57+
getOptions: () => T[]
58+
valueText?: (value: T) => string
6459
optionClass?: string
6560
}
6661

67-
function OptionList(p: OptionListProps) {
62+
function OptionList<T extends string>(p: OptionListProps<T>) {
6863
return (
6964
<div class={innerClass(p.getOptions().length, p.innerClass)}>
7065
<For each={p.getOptions()}>
@@ -83,14 +78,14 @@ function OptionList(p: OptionListProps) {
8378
)
8479
}
8580

86-
interface CheckOptionProps extends MayHaveButtonVariant, MayHaveDisabled {
87-
option: string
88-
valueSignal: SignalObject<string[]>
89-
valueText?: (value: string) => string
81+
interface CheckOptionProps<T extends string> extends MayHaveButtonVariant, MayHaveDisabled {
82+
option: T
83+
valueSignal: SignalObject<T[]>
84+
valueText?: (value: T) => string
9085
optionClass?: string
9186
}
9287

93-
function CheckOption(p: CheckOptionProps) {
88+
function CheckOption<T extends string>(p: CheckOptionProps<T>) {
9489
const label = () => (p.valueText ? p.valueText(p.option) : p.option)
9590
const isSelected = () => p.valueSignal.get().includes(p.option)
9691

@@ -119,7 +114,7 @@ function innerClass(optionAmount: number, innerClass?: string): string {
119114
return classArr(classesGridCols3xl, base)
120115
}
121116

122-
function toggleOption(p: CheckOptionProps) {
117+
function toggleOption<T extends string>(p: CheckOptionProps<T>) {
123118
const hasOption = p.valueSignal.get().includes(p.option)
124119
if (hasOption) {
125120
optionRemove(p)
@@ -128,12 +123,12 @@ function toggleOption(p: CheckOptionProps) {
128123
}
129124
}
130125

131-
function optionRemove(p: CheckOptionProps) {
126+
function optionRemove<T extends string>(p: CheckOptionProps<T>) {
132127
const newValues = p.valueSignal.get().filter((v) => v !== p.option)
133128
p.valueSignal.set(newValues)
134129
}
135130

136-
function optionAdd(p: CheckOptionProps) {
131+
function optionAdd<T extends string>(p: CheckOptionProps<T>) {
137132
const newValues = [...p.valueSignal.get(), p.option]
138133
newValues.sort((a, b) => a.localeCompare(b))
139134
p.valueSignal.set(newValues)

lib/input/check/CheckSingle.tsx

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,29 @@ import { classesGridCols3xl } from "~ui/static/container/classesGridCols"
66
import { classArr } from "~ui/utils/classArr"
77
import { classMerge } from "~ui/utils/classMerge"
88
import type { SignalObject } from "~ui/utils/createSignalObject"
9-
import type { HasGetOptions } from "~ui/utils/HasGetOptions"
10-
import type { HasValueSignalString } from "~ui/utils/HasValueSignalString"
11-
import type { MayHaveValueText } from "~ui/utils/HasValueText"
129
import type { MayHaveButtonVariant } from "~ui/utils/MayHaveButtonVariant"
1310
import type { MayHaveClass } from "~ui/utils/MayHaveClass"
1411
import type { MayHaveDisabled } from "~ui/utils/MayHaveDisabled"
1512
import type { MayHaveId } from "~ui/utils/MayHaveId"
1613
import type { MayHaveInnerClass } from "~ui/utils/MayHaveInnerClass"
1714

18-
export interface CheckSingleProps
19-
extends HasValueSignalString,
20-
HasGetOptions,
21-
MayHaveValueText,
22-
MayHaveId,
15+
export interface CheckSingleProps<T extends string>
16+
extends MayHaveId,
2317
MayHaveButtonVariant,
2418
MayHaveClass,
2519
MayHaveInnerClass,
2620
MayHaveDisabled {
21+
// state
22+
valueSignal: SignalObject<T>
23+
getOptions: () => T[]
24+
valueText?: (value: T) => string
25+
// behavior
2726
disallowDeselection?: boolean
27+
// styling
2828
optionClass?: string
2929
}
3030

31-
export function CheckSingle(p: CheckSingleProps) {
31+
export function CheckSingle<T extends string = string>(p: CheckSingleProps<T>) {
3232
return (
3333
<div
3434
id={p.id}
@@ -55,18 +55,16 @@ export function CheckSingle(p: CheckSingleProps) {
5555
)
5656
}
5757

58-
interface OptionListProps
59-
extends HasValueSignalString,
60-
HasGetOptions,
61-
MayHaveValueText,
62-
MayHaveButtonVariant,
63-
MayHaveDisabled,
64-
MayHaveInnerClass {
58+
interface OptionListProps<T extends string> extends MayHaveButtonVariant, MayHaveDisabled, MayHaveInnerClass {
59+
valueSignal: SignalObject<T>
60+
getOptions: () => T[]
61+
valueText?: (value: T) => string
62+
6563
disallowDeselection?: boolean
6664
optionClass?: string
6765
}
6866

69-
function OptionList(p: OptionListProps) {
67+
function OptionList<T extends string>(p: OptionListProps<T>) {
7068
return (
7169
<div class={innerClass(p.getOptions().length, p.innerClass)}>
7270
<For each={p.getOptions()}>
@@ -95,15 +93,15 @@ function innerClass(optionAmount: number, innerClass?: string): string {
9593
return classArr(classesGridCols3xl, base)
9694
}
9795

98-
interface CheckOptionProps extends MayHaveButtonVariant, MayHaveDisabled {
99-
option: string
100-
valueSignal: SignalObject<string>
101-
valueText?: (value: string) => string
96+
interface CheckOptionProps<T extends string> extends MayHaveButtonVariant, MayHaveDisabled {
97+
option: T
98+
valueSignal: SignalObject<T>
99+
valueText?: (value: T) => string
102100
disallowDeselection?: boolean
103101
optionClass?: string
104102
}
105103

106-
function CheckOption(p: CheckOptionProps) {
104+
function CheckOption<T extends string>(p: CheckOptionProps<T>) {
107105
const label = () => (p.valueText ? p.valueText(p.option) : p.option)
108106
const isSelected = () => p.valueSignal.get() === p.option
109107

@@ -123,10 +121,10 @@ function CheckOption(p: CheckOptionProps) {
123121
)
124122
}
125123

126-
function toggleOption(p: CheckOptionProps, disallowDeselection?: boolean) {
124+
function toggleOption<T extends string>(p: CheckOptionProps<T>, disallowDeselection?: boolean) {
127125
const isSelected = p.valueSignal.get() === p.option
128126
if (isSelected && !disallowDeselection) {
129-
p.valueSignal.set("")
127+
p.valueSignal.set("" as T)
130128
} else {
131129
p.valueSignal.set(p.option)
132130
}

0 commit comments

Comments
 (0)