@simplysm/solid 13.0.16 → 13.0.23

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.
Files changed (81) hide show
  1. package/README.md +0 -10
  2. package/dist/components/data/calendar/Calendar.d.ts +5 -5
  3. package/dist/components/data/calendar/Calendar.d.ts.map +1 -1
  4. package/dist/components/data/calendar/Calendar.js.map +1 -1
  5. package/dist/components/data/sheet/DataSheetColumn.d.ts +1 -1
  6. package/dist/components/data/sheet/DataSheetColumn.d.ts.map +1 -1
  7. package/dist/components/data/sheet/DataSheetColumn.js.map +1 -1
  8. package/dist/components/data/sheet/sheetUtils.d.ts +4 -4
  9. package/dist/components/data/sheet/sheetUtils.d.ts.map +1 -1
  10. package/dist/components/data/sheet/sheetUtils.js.map +1 -1
  11. package/dist/components/data/sheet/types.d.ts +23 -23
  12. package/dist/components/data/sheet/types.d.ts.map +1 -1
  13. package/dist/components/disclosure/DialogInstanceContext.d.ts +3 -3
  14. package/dist/components/disclosure/DialogInstanceContext.d.ts.map +1 -1
  15. package/dist/components/disclosure/DialogInstanceContext.js.map +1 -1
  16. package/dist/components/form-control/checkbox/CheckboxGroup.d.ts +7 -7
  17. package/dist/components/form-control/checkbox/CheckboxGroup.d.ts.map +1 -1
  18. package/dist/components/form-control/checkbox/CheckboxGroup.js.map +1 -1
  19. package/dist/components/form-control/checkbox/RadioGroup.d.ts +7 -7
  20. package/dist/components/form-control/checkbox/RadioGroup.d.ts.map +1 -1
  21. package/dist/components/form-control/checkbox/RadioGroup.js.map +1 -1
  22. package/dist/components/form-control/combobox/Combobox.d.ts +9 -9
  23. package/dist/components/form-control/combobox/Combobox.d.ts.map +1 -1
  24. package/dist/components/form-control/combobox/ComboboxContext.d.ts +4 -4
  25. package/dist/components/form-control/combobox/ComboboxContext.d.ts.map +1 -1
  26. package/dist/components/form-control/combobox/ComboboxContext.js.map +1 -1
  27. package/dist/components/form-control/combobox/ComboboxItem.d.ts +2 -2
  28. package/dist/components/form-control/combobox/ComboboxItem.d.ts.map +1 -1
  29. package/dist/components/form-control/select/Select.d.ts +16 -16
  30. package/dist/components/form-control/select/Select.d.ts.map +1 -1
  31. package/dist/components/form-control/select/SelectContext.d.ts +4 -4
  32. package/dist/components/form-control/select/SelectContext.d.ts.map +1 -1
  33. package/dist/components/form-control/select/SelectContext.js.map +1 -1
  34. package/dist/components/form-control/select/SelectItem.d.ts +3 -3
  35. package/dist/components/form-control/select/SelectItem.d.ts.map +1 -1
  36. package/dist/components/form-control/state-preset/StatePreset.d.ts +4 -4
  37. package/dist/components/form-control/state-preset/StatePreset.d.ts.map +1 -1
  38. package/dist/components/form-control/state-preset/StatePreset.js.map +1 -1
  39. package/dist/hooks/createControllableSignal.d.ts +5 -5
  40. package/dist/hooks/createControllableSignal.d.ts.map +1 -1
  41. package/dist/hooks/createControllableSignal.js.map +1 -1
  42. package/dist/hooks/useLocalStorage.d.ts +1 -1
  43. package/dist/hooks/useLocalStorage.d.ts.map +1 -1
  44. package/dist/hooks/useLocalStorage.js.map +1 -1
  45. package/dist/hooks/useSyncConfig.d.ts +1 -1
  46. package/dist/hooks/useSyncConfig.d.ts.map +1 -1
  47. package/dist/hooks/useSyncConfig.js.map +1 -1
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js.map +1 -1
  50. package/dist/providers/InitializeProvider.d.ts +0 -1
  51. package/dist/providers/InitializeProvider.d.ts.map +1 -1
  52. package/dist/providers/InitializeProvider.js +1 -6
  53. package/dist/providers/InitializeProvider.js.map +2 -2
  54. package/dist/providers/shared-data/SharedDataContext.d.ts +10 -10
  55. package/dist/providers/shared-data/SharedDataContext.d.ts.map +1 -1
  56. package/dist/providers/shared-data/SharedDataContext.js.map +1 -1
  57. package/dist/providers/shared-data/SharedDataProvider.d.ts +2 -2
  58. package/dist/providers/shared-data/SharedDataProvider.d.ts.map +1 -1
  59. package/dist/providers/shared-data/SharedDataProvider.js.map +1 -1
  60. package/package.json +5 -5
  61. package/src/components/data/calendar/Calendar.tsx +8 -8
  62. package/src/components/data/sheet/DataSheetColumn.tsx +1 -1
  63. package/src/components/data/sheet/sheetUtils.ts +16 -13
  64. package/src/components/data/sheet/types.ts +23 -23
  65. package/src/components/disclosure/DialogInstanceContext.ts +4 -4
  66. package/src/components/form-control/checkbox/CheckboxGroup.tsx +10 -10
  67. package/src/components/form-control/checkbox/RadioGroup.tsx +10 -10
  68. package/src/components/form-control/combobox/Combobox.tsx +9 -9
  69. package/src/components/form-control/combobox/ComboboxContext.ts +5 -5
  70. package/src/components/form-control/combobox/ComboboxItem.tsx +2 -2
  71. package/src/components/form-control/select/Select.tsx +20 -20
  72. package/src/components/form-control/select/SelectContext.ts +5 -5
  73. package/src/components/form-control/select/SelectItem.tsx +3 -3
  74. package/src/components/form-control/state-preset/StatePreset.tsx +10 -10
  75. package/src/hooks/createControllableSignal.ts +7 -7
  76. package/src/hooks/useLocalStorage.ts +11 -8
  77. package/src/hooks/useSyncConfig.ts +8 -5
  78. package/src/index.ts +58 -13
  79. package/src/providers/InitializeProvider.tsx +2 -5
  80. package/src/providers/shared-data/SharedDataContext.ts +13 -11
  81. package/src/providers/shared-data/SharedDataProvider.tsx +2 -2
@@ -1,8 +1,8 @@
1
1
  import type { JSX } from "solid-js";
2
2
 
3
- export interface DataSheetProps<T> {
3
+ export interface DataSheetProps<TItem> {
4
4
  // 데이터
5
- items?: T[];
5
+ items?: TItem[];
6
6
  // 설정
7
7
  persistKey?: string;
8
8
  hideConfigBar?: boolean;
@@ -23,29 +23,29 @@ export interface DataSheetProps<T> {
23
23
 
24
24
  // 선택
25
25
  selectMode?: "single" | "multiple";
26
- selectedItems?: T[];
27
- onSelectedItemsChange?: (items: T[]) => void;
26
+ selectedItems?: TItem[];
27
+ onSelectedItemsChange?: (items: TItem[]) => void;
28
28
  autoSelect?: "click";
29
- isItemSelectable?: (item: T) => boolean | string;
29
+ isItemSelectable?: (item: TItem) => boolean | string;
30
30
 
31
31
  // 트리 확장
32
- expandedItems?: T[];
33
- onExpandedItemsChange?: (items: T[]) => void;
34
- getChildren?: (item: T, index: number) => T[] | undefined;
32
+ expandedItems?: TItem[];
33
+ onExpandedItemsChange?: (items: TItem[]) => void;
34
+ getChildren?: (item: TItem, index: number) => TItem[] | undefined;
35
35
 
36
36
  // 셀 스타일
37
- cellClass?: (item: T, colKey: string) => string | undefined;
38
- cellStyle?: (item: T, colKey: string) => string | undefined;
37
+ cellClass?: (item: TItem, colKey: string) => string | undefined;
38
+ cellStyle?: (item: TItem, colKey: string) => string | undefined;
39
39
 
40
40
  // 재정렬
41
- onItemsReorder?: (event: DataSheetReorderEvent<T>) => void;
41
+ onItemsReorder?: (event: DataSheetReorderEvent<TItem>) => void;
42
42
 
43
43
  // 기타
44
44
  class?: string;
45
45
  children: JSX.Element;
46
46
  }
47
47
 
48
- export interface DataSheetColumnProps<T> {
48
+ export interface DataSheetColumnProps<TItem> {
49
49
  key: string;
50
50
  header?: string | string[];
51
51
  headerContent?: () => JSX.Element;
@@ -59,11 +59,11 @@ export interface DataSheetColumnProps<T> {
59
59
  class?: string;
60
60
  sortable?: boolean;
61
61
  resizable?: boolean;
62
- children: (ctx: DataSheetCellContext<T>) => JSX.Element;
62
+ children: (ctx: DataSheetCellContext<TItem>) => JSX.Element;
63
63
  }
64
64
 
65
- export interface DataSheetCellContext<T> {
66
- item: T;
65
+ export interface DataSheetCellContext<TItem> {
66
+ item: TItem;
67
67
  index: number;
68
68
  depth: number;
69
69
  }
@@ -84,7 +84,7 @@ export interface DataSheetConfigColumn {
84
84
  hidden?: boolean;
85
85
  }
86
86
 
87
- export interface DataSheetColumnDef<T> {
87
+ export interface DataSheetColumnDef<TItem> {
88
88
  __type: "sheet-column";
89
89
  key: string;
90
90
  header: string[];
@@ -99,7 +99,7 @@ export interface DataSheetColumnDef<T> {
99
99
  class?: string;
100
100
  sortable: boolean;
101
101
  resizable: boolean;
102
- cell: (ctx: DataSheetCellContext<T>) => JSX.Element;
102
+ cell: (ctx: DataSheetCellContext<TItem>) => JSX.Element;
103
103
  }
104
104
 
105
105
  export interface HeaderDef {
@@ -114,21 +114,21 @@ export interface HeaderDef {
114
114
  headerContent?: () => JSX.Element;
115
115
  }
116
116
 
117
- export interface FlatItem<T> {
118
- item: T;
117
+ export interface FlatItem<TItem> {
118
+ item: TItem;
119
119
  index: number;
120
120
  depth: number;
121
121
  hasChildren: boolean;
122
- parent?: T;
122
+ parent?: TItem;
123
123
  }
124
124
 
125
125
  // 드래그 앤 드롭 위치
126
126
  export type DataSheetDragPosition = "before" | "after" | "inside";
127
127
 
128
128
  // 재정렬 이벤트
129
- export interface DataSheetReorderEvent<T> {
130
- item: T;
131
- targetItem: T;
129
+ export interface DataSheetReorderEvent<TItem> {
130
+ item: TItem;
131
+ targetItem: TItem;
132
132
  position: DataSheetDragPosition;
133
133
  }
134
134
 
@@ -1,11 +1,11 @@
1
1
  import { createContext, useContext } from "solid-js";
2
2
 
3
- export interface DialogInstance<T> {
4
- close: (result?: T) => void;
3
+ export interface DialogInstance<TResult> {
4
+ close: (result?: TResult) => void;
5
5
  }
6
6
 
7
7
  export const DialogInstanceContext = createContext<DialogInstance<unknown>>();
8
8
 
9
- export function useDialogInstance<T = undefined>(): DialogInstance<T> | undefined {
10
- return useContext(DialogInstanceContext) as DialogInstance<T> | undefined;
9
+ export function useDialogInstance<TResult = undefined>(): DialogInstance<TResult> | undefined {
10
+ return useContext(DialogInstanceContext) as DialogInstance<TResult> | undefined;
11
11
  }
@@ -4,9 +4,9 @@ import { createControllableSignal } from "../../../hooks/createControllableSigna
4
4
  import { Checkbox } from "./Checkbox";
5
5
  import type { CheckboxSize, CheckboxTheme } from "./Checkbox.styles";
6
6
 
7
- interface CheckboxGroupContextValue<T> {
8
- value: () => T[];
9
- toggle: (item: T) => void;
7
+ interface CheckboxGroupContextValue<TValue> {
8
+ value: () => TValue[];
9
+ toggle: (item: TValue) => void;
10
10
  disabled: () => boolean;
11
11
  size: () => CheckboxSize | undefined;
12
12
  theme: () => CheckboxTheme | undefined;
@@ -18,13 +18,13 @@ const CheckboxGroupContext = createContext<CheckboxGroupContextValue<any>>();
18
18
 
19
19
  // --- CheckboxGroup.Item ---
20
20
 
21
- interface CheckboxGroupItemProps<T> {
22
- value: T;
21
+ interface CheckboxGroupItemProps<TValue> {
22
+ value: TValue;
23
23
  disabled?: boolean;
24
24
  children?: JSX.Element;
25
25
  }
26
26
 
27
- function CheckboxGroupItemInner<T>(props: CheckboxGroupItemProps<T>) {
27
+ function CheckboxGroupItemInner<TValue>(props: CheckboxGroupItemProps<TValue>) {
28
28
  const ctx = useContext(CheckboxGroupContext);
29
29
  if (!ctx) throw new Error("CheckboxGroup.Item은 CheckboxGroup 내부에서만 사용할 수 있습니다");
30
30
 
@@ -47,9 +47,9 @@ function CheckboxGroupItemInner<T>(props: CheckboxGroupItemProps<T>) {
47
47
 
48
48
  // --- CheckboxGroup ---
49
49
 
50
- interface CheckboxGroupProps<T> {
51
- value?: T[];
52
- onValueChange?: (value: T[]) => void;
50
+ interface CheckboxGroupProps<TValue> {
51
+ value?: TValue[];
52
+ onValueChange?: (value: TValue[]) => void;
53
53
  disabled?: boolean;
54
54
  size?: CheckboxSize;
55
55
  theme?: CheckboxTheme;
@@ -61,7 +61,7 @@ interface CheckboxGroupProps<T> {
61
61
  }
62
62
 
63
63
  interface CheckboxGroupComponent {
64
- <T = unknown>(props: CheckboxGroupProps<T>): JSX.Element;
64
+ <TValue = unknown>(props: CheckboxGroupProps<TValue>): JSX.Element;
65
65
  Item: typeof CheckboxGroupItemInner;
66
66
  }
67
67
 
@@ -4,9 +4,9 @@ import { createControllableSignal } from "../../../hooks/createControllableSigna
4
4
  import { Radio } from "./Radio";
5
5
  import type { CheckboxSize, CheckboxTheme } from "./Checkbox.styles";
6
6
 
7
- interface RadioGroupContextValue<T> {
8
- value: () => T | undefined;
9
- select: (item: T) => void;
7
+ interface RadioGroupContextValue<TValue> {
8
+ value: () => TValue | undefined;
9
+ select: (item: TValue) => void;
10
10
  disabled: () => boolean;
11
11
  size: () => CheckboxSize | undefined;
12
12
  theme: () => CheckboxTheme | undefined;
@@ -18,13 +18,13 @@ const RadioGroupContext = createContext<RadioGroupContextValue<any>>();
18
18
 
19
19
  // --- RadioGroup.Item ---
20
20
 
21
- interface RadioGroupItemProps<T> {
22
- value: T;
21
+ interface RadioGroupItemProps<TValue> {
22
+ value: TValue;
23
23
  disabled?: boolean;
24
24
  children?: JSX.Element;
25
25
  }
26
26
 
27
- function RadioGroupItemInner<T>(props: RadioGroupItemProps<T>) {
27
+ function RadioGroupItemInner<TValue>(props: RadioGroupItemProps<TValue>) {
28
28
  const ctx = useContext(RadioGroupContext);
29
29
  if (!ctx) throw new Error("RadioGroup.Item은 RadioGroup 내부에서만 사용할 수 있습니다");
30
30
 
@@ -47,9 +47,9 @@ function RadioGroupItemInner<T>(props: RadioGroupItemProps<T>) {
47
47
 
48
48
  // --- RadioGroup ---
49
49
 
50
- interface RadioGroupProps<T> {
51
- value?: T;
52
- onValueChange?: (value: T) => void;
50
+ interface RadioGroupProps<TValue> {
51
+ value?: TValue;
52
+ onValueChange?: (value: TValue) => void;
53
53
  disabled?: boolean;
54
54
  size?: CheckboxSize;
55
55
  theme?: CheckboxTheme;
@@ -61,7 +61,7 @@ interface RadioGroupProps<T> {
61
61
  }
62
62
 
63
63
  interface RadioGroupComponent {
64
- <T = unknown>(props: RadioGroupProps<T>): JSX.Element;
64
+ <TValue = unknown>(props: RadioGroupProps<TValue>): JSX.Element;
65
65
  Item: typeof RadioGroupItemInner;
66
66
  }
67
67
 
@@ -28,8 +28,8 @@ const noResultsClass = clsx("px-3 py-2", textMuted);
28
28
  /**
29
29
  * Combobox 아이템 렌더링 템플릿
30
30
  */
31
- interface ComboboxItemTemplateProps<T> {
32
- children: (item: T, index: number) => JSX.Element;
31
+ interface ComboboxItemTemplateProps<TItem> {
32
+ children: (item: TItem, index: number) => JSX.Element;
33
33
  }
34
34
 
35
35
  // 템플릿 함수를 저장하는 전역 WeakMap
@@ -46,15 +46,15 @@ const ComboboxItemTemplate = <T,>(props: ComboboxItemTemplateProps<T>) => (
46
46
  );
47
47
 
48
48
  // Props 정의
49
- export interface ComboboxProps<T = unknown> {
49
+ export interface ComboboxProps<TValue = unknown> {
50
50
  /** 현재 선택된 값 */
51
- value?: T;
51
+ value?: TValue;
52
52
 
53
53
  /** 값 변경 콜백 */
54
- onValueChange?: (value: T) => void;
54
+ onValueChange?: (value: TValue) => void;
55
55
 
56
56
  /** 아이템 로드 함수 (필수) */
57
- loadItems: (query: string) => Promise<T[]>;
57
+ loadItems: (query: string) => Promise<TValue[]>;
58
58
 
59
59
  /** 디바운스 딜레이 (기본값: 300ms) */
60
60
  debounceMs?: number;
@@ -63,10 +63,10 @@ export interface ComboboxProps<T = unknown> {
63
63
  allowCustomValue?: boolean;
64
64
 
65
65
  /** 커스텀 값 파싱 함수 */
66
- parseCustomValue?: (text: string) => T;
66
+ parseCustomValue?: (text: string) => TValue;
67
67
 
68
68
  /** 선택된 값을 렌더링하는 함수 (필수) */
69
- renderValue: (value: T) => JSX.Element;
69
+ renderValue: (value: TValue) => JSX.Element;
70
70
 
71
71
  /** 비활성화 */
72
72
  disabled?: boolean;
@@ -94,7 +94,7 @@ export interface ComboboxProps<T = unknown> {
94
94
  }
95
95
 
96
96
  interface ComboboxComponent {
97
- <T = unknown>(props: ComboboxProps<T>): JSX.Element;
97
+ <TValue = unknown>(props: ComboboxProps<TValue>): JSX.Element;
98
98
  Item: typeof ComboboxItem;
99
99
  ItemTemplate: typeof ComboboxItemTemplate;
100
100
  }
@@ -1,11 +1,11 @@
1
1
  import { createContext, useContext } from "solid-js";
2
2
 
3
- export interface ComboboxContextValue<T = unknown> {
3
+ export interface ComboboxContextValue<TValue = unknown> {
4
4
  /** 값이 선택되어 있는지 확인 */
5
- isSelected: (value: T) => boolean;
5
+ isSelected: (value: TValue) => boolean;
6
6
 
7
7
  /** 값 선택 */
8
- selectValue: (value: T) => void;
8
+ selectValue: (value: TValue) => void;
9
9
 
10
10
  /** 드롭다운 닫기 */
11
11
  closeDropdown: () => void;
@@ -13,10 +13,10 @@ export interface ComboboxContextValue<T = unknown> {
13
13
 
14
14
  export const ComboboxContext = createContext<ComboboxContextValue>();
15
15
 
16
- export function useComboboxContext<T = unknown>(): ComboboxContextValue<T> {
16
+ export function useComboboxContext<TValue = unknown>(): ComboboxContextValue<TValue> {
17
17
  const context = useContext(ComboboxContext);
18
18
  if (!context) {
19
19
  throw new Error("useComboboxContext는 Combobox 컴포넌트 내부에서만 사용할 수 있습니다");
20
20
  }
21
- return context as ComboboxContextValue<T>;
21
+ return context as ComboboxContextValue<TValue>;
22
22
  }
@@ -11,12 +11,12 @@ import {
11
11
 
12
12
  void ripple;
13
13
 
14
- export interface ComboboxItemProps<T = unknown> extends Omit<
14
+ export interface ComboboxItemProps<TValue = unknown> extends Omit<
15
15
  JSX.ButtonHTMLAttributes<HTMLButtonElement>,
16
16
  "value" | "onClick"
17
17
  > {
18
18
  /** 아이템의 값 */
19
- value: T;
19
+ value: TValue;
20
20
 
21
21
  /** 비활성화 */
22
22
  disabled?: boolean;
@@ -65,8 +65,8 @@ const SelectHeader: ParentComponent = (props) => <div data-select-header>{props.
65
65
  *
66
66
  * 함수 참조를 저장하기 위해 전역 Map 사용
67
67
  */
68
- interface SelectItemTemplateProps<T> {
69
- children: (item: T, index: number, depth: number) => JSX.Element;
68
+ interface SelectItemTemplateProps<TValue> {
69
+ children: (item: TValue, index: number, depth: number) => JSX.Element;
70
70
  }
71
71
 
72
72
  // 템플릿 함수를 저장하는 전역 Map (WeakMap 사용하여 메모리 누수 방지)
@@ -109,15 +109,15 @@ interface SelectCommonProps {
109
109
  }
110
110
 
111
111
  // 단일 선택 Props
112
- interface SelectSingleBaseProps<T> extends SelectCommonProps {
112
+ interface SelectSingleBaseProps<TValue> extends SelectCommonProps {
113
113
  /** 다중 선택 모드 */
114
114
  multiple?: false;
115
115
 
116
116
  /** 현재 선택된 값 */
117
- value?: T;
117
+ value?: TValue;
118
118
 
119
119
  /** 값 변경 콜백 */
120
- onValueChange?: (value: T) => void;
120
+ onValueChange?: (value: TValue) => void;
121
121
 
122
122
  /** 다중 선택 시 표시 방향 (단일 선택에서는 사용 안 함) */
123
123
  multiDisplayDirection?: never;
@@ -127,15 +127,15 @@ interface SelectSingleBaseProps<T> extends SelectCommonProps {
127
127
  }
128
128
 
129
129
  // 다중 선택 Props
130
- interface SelectMultipleBaseProps<T> extends SelectCommonProps {
130
+ interface SelectMultipleBaseProps<TValue> extends SelectCommonProps {
131
131
  /** 다중 선택 모드 */
132
132
  multiple: true;
133
133
 
134
134
  /** 현재 선택된 값 */
135
- value?: T[];
135
+ value?: TValue[];
136
136
 
137
137
  /** 값 변경 콜백 */
138
- onValueChange?: (value: T[]) => void;
138
+ onValueChange?: (value: TValue[]) => void;
139
139
 
140
140
  /** 다중 선택 시 표시 방향 */
141
141
  multiDisplayDirection?: "horizontal" | "vertical";
@@ -145,29 +145,29 @@ interface SelectMultipleBaseProps<T> extends SelectCommonProps {
145
145
  }
146
146
 
147
147
  // items 방식
148
- interface SelectWithItemsPropsBase<T> {
149
- items: T[];
150
- getChildren?: (item: T, index: number, depth: number) => T[] | undefined;
151
- renderValue?: (value: T) => JSX.Element;
148
+ interface SelectWithItemsPropsBase<TValue> {
149
+ items: TValue[];
150
+ getChildren?: (item: TValue, index: number, depth: number) => TValue[] | undefined;
151
+ renderValue?: (value: TValue) => JSX.Element;
152
152
  children?: JSX.Element;
153
153
  }
154
154
 
155
155
  // children 방식
156
- interface SelectWithChildrenPropsBase<T> {
156
+ interface SelectWithChildrenPropsBase<TValue> {
157
157
  items?: never;
158
158
  getChildren?: never;
159
- renderValue: (value: T) => JSX.Element;
159
+ renderValue: (value: TValue) => JSX.Element;
160
160
  children: JSX.Element;
161
161
  }
162
162
 
163
- export type SelectProps<T = unknown> =
164
- | (SelectSingleBaseProps<T> & SelectWithItemsPropsBase<T>)
165
- | (SelectSingleBaseProps<T> & SelectWithChildrenPropsBase<T>)
166
- | (SelectMultipleBaseProps<T> & SelectWithItemsPropsBase<T>)
167
- | (SelectMultipleBaseProps<T> & SelectWithChildrenPropsBase<T>);
163
+ export type SelectProps<TValue = unknown> =
164
+ | (SelectSingleBaseProps<TValue> & SelectWithItemsPropsBase<TValue>)
165
+ | (SelectSingleBaseProps<TValue> & SelectWithChildrenPropsBase<TValue>)
166
+ | (SelectMultipleBaseProps<TValue> & SelectWithItemsPropsBase<TValue>)
167
+ | (SelectMultipleBaseProps<TValue> & SelectWithChildrenPropsBase<TValue>);
168
168
 
169
169
  interface SelectComponent {
170
- <T = unknown>(props: SelectProps<T>): JSX.Element;
170
+ <TValue = unknown>(props: SelectProps<TValue>): JSX.Element;
171
171
  Item: typeof SelectItem;
172
172
  Action: typeof SelectAction;
173
173
  Header: typeof SelectHeader;
@@ -1,14 +1,14 @@
1
1
  import { createContext, useContext, type Accessor } from "solid-js";
2
2
 
3
- export interface SelectContextValue<T = unknown> {
3
+ export interface SelectContextValue<TValue = unknown> {
4
4
  /** 다중 선택 모드 여부 */
5
5
  multiple: Accessor<boolean>;
6
6
 
7
7
  /** 값이 선택되어 있는지 확인 */
8
- isSelected: (value: T) => boolean;
8
+ isSelected: (value: TValue) => boolean;
9
9
 
10
10
  /** 값 선택/해제 토글 */
11
- toggleValue: (value: T) => void;
11
+ toggleValue: (value: TValue) => void;
12
12
 
13
13
  /** 드롭다운 닫기 */
14
14
  closeDropdown: () => void;
@@ -16,10 +16,10 @@ export interface SelectContextValue<T = unknown> {
16
16
 
17
17
  export const SelectContext = createContext<SelectContextValue>();
18
18
 
19
- export function useSelectContext<T = unknown>(): SelectContextValue<T> {
19
+ export function useSelectContext<TValue = unknown>(): SelectContextValue<TValue> {
20
20
  const context = useContext(SelectContext);
21
21
  if (!context) {
22
22
  throw new Error("useSelectContext는 Select 컴포넌트 내부에서만 사용할 수 있습니다");
23
23
  }
24
- return context as SelectContextValue<T>;
24
+ return context as SelectContextValue<TValue>;
25
25
  }
@@ -30,18 +30,18 @@ const SelectItemChildren: ParentComponent = (props) => (
30
30
  </div>
31
31
  );
32
32
 
33
- export interface SelectItemProps<T = unknown> extends Omit<
33
+ export interface SelectItemProps<TValue = unknown> extends Omit<
34
34
  JSX.ButtonHTMLAttributes<HTMLButtonElement>,
35
35
  "value" | "onClick"
36
36
  > {
37
37
  /** 아이템의 값 */
38
- value: T;
38
+ value: TValue;
39
39
 
40
40
  /** 비활성화 */
41
41
  disabled?: boolean;
42
42
  }
43
43
 
44
- interface SelectItemComponent<T = unknown> extends ParentComponent<SelectItemProps<T>> {
44
+ interface SelectItemComponent<TValue = unknown> extends ParentComponent<SelectItemProps<TValue>> {
45
45
  Children: typeof SelectItemChildren;
46
46
  }
47
47
 
@@ -12,17 +12,17 @@ import type { ComponentSize } from "../../../styles/tokens.styles";
12
12
 
13
13
  // ── Types ──
14
14
 
15
- interface StatePresetItem<T> {
15
+ interface StatePresetItem<TValue> {
16
16
  name: string;
17
- state: T;
17
+ state: TValue;
18
18
  }
19
19
 
20
20
  type StatePresetSize = ComponentSize;
21
21
 
22
- export interface StatePresetProps<T> {
22
+ export interface StatePresetProps<TValue> {
23
23
  presetKey: string;
24
- value: T;
25
- onValueChange: (value: T) => void;
24
+ value: TValue;
25
+ onValueChange: (value: TValue) => void;
26
26
  size?: StatePresetSize;
27
27
  class?: string;
28
28
  style?: JSX.CSSProperties;
@@ -107,14 +107,14 @@ const iconSize = "0.85em";
107
107
 
108
108
  // ── Component ──
109
109
 
110
- function StatePresetInner<T>(props: StatePresetProps<T>): JSX.Element {
110
+ function StatePresetInner<TValue>(props: StatePresetProps<TValue>): JSX.Element {
111
111
  const [local] = splitProps(props, ["presetKey", "value", "onValueChange", "size", "class", "style"]);
112
112
 
113
113
  const notification = useNotification();
114
114
 
115
115
  // presetKey는 마운트 시 한 번만 설정되는 식별자이므로 즉시 평가하여 캡처
116
116
  /* eslint-disable solid/reactivity */
117
- const [presets, setPresets] = useSyncConfig<StatePresetItem<T>[]>(`state-preset.${local.presetKey}`, []);
117
+ const [presets, setPresets] = useSyncConfig<StatePresetItem<TValue>[]>(`state-preset.${local.presetKey}`, []);
118
118
  /* eslint-enable solid/reactivity */
119
119
  const [adding, setAdding] = createSignal(false);
120
120
  const [inputValue, setInputValue] = createSignal("");
@@ -143,7 +143,7 @@ function StatePresetInner<T>(props: StatePresetProps<T>): JSX.Element {
143
143
  return;
144
144
  }
145
145
 
146
- const newPreset: StatePresetItem<T> = {
146
+ const newPreset: StatePresetItem<TValue> = {
147
147
  name,
148
148
  state: objClone(local.value),
149
149
  };
@@ -153,7 +153,7 @@ function StatePresetInner<T>(props: StatePresetProps<T>): JSX.Element {
153
153
  setInputValue("");
154
154
  }
155
155
 
156
- function handleRestore(preset: StatePresetItem<T>): void {
156
+ function handleRestore(preset: StatePresetItem<TValue>): void {
157
157
  if (!objEqual(local.value, preset.state)) {
158
158
  local.onValueChange(objClone(preset.state));
159
159
  }
@@ -278,4 +278,4 @@ function StatePresetInner<T>(props: StatePresetProps<T>): JSX.Element {
278
278
  );
279
279
  }
280
280
 
281
- export const StatePreset = StatePresetInner as <T>(props: StatePresetProps<T>) => JSX.Element;
281
+ export const StatePreset = StatePresetInner as <TValue>(props: StatePresetProps<TValue>) => JSX.Element;
@@ -7,7 +7,7 @@ import { createSignal, createEffect } from "solid-js";
7
7
  * @remarks
8
8
  * 함수를 저장해야 할 경우 객체로 감싸기: `createControllableSignal<{ fn: () => void }>(...)`
9
9
  */
10
- type NotFunction<T> = T extends (...args: unknown[]) => unknown ? never : T;
10
+ type NotFunction<TValue> = TValue extends (...args: unknown[]) => unknown ? never : TValue;
11
11
 
12
12
  /**
13
13
  * Controlled/Uncontrolled 패턴을 지원하는 signal hook
@@ -35,11 +35,11 @@ type NotFunction<T> = T extends (...args: unknown[]) => unknown ? never : T;
35
35
  * setOpen(prev => !prev);
36
36
  * ```
37
37
  */
38
- export function createControllableSignal<T>(options: {
39
- value: () => T & NotFunction<T>;
40
- onChange: () => ((value: T) => void) | undefined;
38
+ export function createControllableSignal<TValue>(options: {
39
+ value: () => TValue & NotFunction<TValue>;
40
+ onChange: () => ((value: TValue) => void) | undefined;
41
41
  }) {
42
- const [internalValue, setInternalValue] = createSignal<T>(options.value());
42
+ const [internalValue, setInternalValue] = createSignal<TValue>(options.value());
43
43
 
44
44
  // props 변경 시 내부 상태 동기화 (props 우선)
45
45
  createEffect(() => {
@@ -49,8 +49,8 @@ export function createControllableSignal<T>(options: {
49
49
 
50
50
  const isControlled = () => options.onChange() !== undefined;
51
51
  const value = () => (isControlled() ? options.value() : internalValue());
52
- const setValue = (newValue: T | ((prev: T) => T)) => {
53
- const resolved = typeof newValue === "function" ? (newValue as (prev: T) => T)(value()) : newValue;
52
+ const setValue = (newValue: TValue | ((prev: TValue) => TValue)) => {
53
+ const resolved = typeof newValue === "function" ? (newValue as (prev: TValue) => TValue)(value()) : newValue;
54
54
 
55
55
  if (isControlled()) {
56
56
  options.onChange()?.(resolved);
@@ -27,28 +27,31 @@ import { useConfig } from "../providers/ConfigContext";
27
27
  * setToken(undefined);
28
28
  * ```
29
29
  */
30
- export function useLocalStorage<T>(key: string, initialValue?: T): [Accessor<T | undefined>, Setter<T | undefined>] {
30
+ export function useLocalStorage<TValue>(
31
+ key: string,
32
+ initialValue?: TValue,
33
+ ): [Accessor<TValue | undefined>, Setter<TValue | undefined>] {
31
34
  const config = useConfig();
32
35
  const prefixedKey = `${config.clientName}.${key}`;
33
36
 
34
37
  // localStorage에서 초기값 읽기
35
- let storedValue: T | undefined = initialValue;
38
+ let storedValue: TValue | undefined = initialValue;
36
39
  try {
37
40
  const item = localStorage.getItem(prefixedKey);
38
41
  if (item !== null) {
39
- storedValue = JSON.parse(item) as T;
42
+ storedValue = JSON.parse(item) as TValue;
40
43
  }
41
44
  } catch {
42
45
  // JSON 파싱 실패 시 초기값 사용
43
46
  }
44
47
 
45
- const [value, setValue] = createSignal<T | undefined>(storedValue);
48
+ const [value, setValue] = createSignal<TValue | undefined>(storedValue);
46
49
 
47
- const setAndStore = (newValue: T | undefined | ((prev: T | undefined) => T | undefined)) => {
48
- let resolved: T | undefined;
50
+ const setAndStore = (newValue: TValue | undefined | ((prev: TValue | undefined) => TValue | undefined)) => {
51
+ let resolved: TValue | undefined;
49
52
 
50
53
  if (typeof newValue === "function") {
51
- resolved = (newValue as (prev: T | undefined) => T | undefined)(value());
54
+ resolved = (newValue as (prev: TValue | undefined) => TValue | undefined)(value());
52
55
  setValue(() => resolved);
53
56
  } else {
54
57
  resolved = newValue;
@@ -64,5 +67,5 @@ export function useLocalStorage<T>(key: string, initialValue?: T): [Accessor<T |
64
67
  return resolved;
65
68
  };
66
69
 
67
- return [value, setAndStore as Setter<T | undefined>];
70
+ return [value, setAndStore as Setter<TValue | undefined>];
68
71
  }
@@ -22,10 +22,13 @@ import { useConfig } from "../providers/ConfigContext";
22
22
  * </Show>
23
23
  * ```
24
24
  */
25
- export function useSyncConfig<T>(key: string, defaultValue: T): [Accessor<T>, Setter<T>, Accessor<boolean>] {
25
+ export function useSyncConfig<TValue>(
26
+ key: string,
27
+ defaultValue: TValue,
28
+ ): [Accessor<TValue>, Setter<TValue>, Accessor<boolean>] {
26
29
  const config = useConfig();
27
30
  const prefixedKey = `${config.clientName}.${key}`;
28
- const [value, setValue] = createSignal<T>(defaultValue);
31
+ const [value, setValue] = createSignal<TValue>(defaultValue);
29
32
  const [loading, setLoading] = createSignal(false);
30
33
 
31
34
  // Initialize from storage
@@ -35,7 +38,7 @@ export function useSyncConfig<T>(key: string, defaultValue: T): [Accessor<T>, Se
35
38
  try {
36
39
  const stored = localStorage.getItem(prefixedKey);
37
40
  if (stored !== null) {
38
- setValue(() => JSON.parse(stored) as T);
41
+ setValue(() => JSON.parse(stored) as TValue);
39
42
  }
40
43
  } catch {
41
44
  // Ignore parse errors, keep default value
@@ -48,14 +51,14 @@ export function useSyncConfig<T>(key: string, defaultValue: T): [Accessor<T>, Se
48
51
  try {
49
52
  const stored = await config.syncStorage.getItem(prefixedKey);
50
53
  if (stored !== null) {
51
- setValue(() => JSON.parse(stored) as T);
54
+ setValue(() => JSON.parse(stored) as TValue);
52
55
  }
53
56
  } catch {
54
57
  // Fall back to localStorage on error
55
58
  try {
56
59
  const stored = localStorage.getItem(prefixedKey);
57
60
  if (stored !== null) {
58
- setValue(() => JSON.parse(stored) as T);
61
+ setValue(() => JSON.parse(stored) as TValue);
59
62
  }
60
63
  } catch {
61
64
  // Ignore parse errors