@simplysm/solid 13.0.16 → 13.0.24
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.
- package/README.md +0 -10
- package/dist/components/data/calendar/Calendar.d.ts +5 -5
- package/dist/components/data/calendar/Calendar.d.ts.map +1 -1
- package/dist/components/data/calendar/Calendar.js.map +1 -1
- package/dist/components/data/sheet/DataSheetColumn.d.ts +1 -1
- package/dist/components/data/sheet/DataSheetColumn.d.ts.map +1 -1
- package/dist/components/data/sheet/DataSheetColumn.js.map +1 -1
- package/dist/components/data/sheet/sheetUtils.d.ts +4 -4
- package/dist/components/data/sheet/sheetUtils.d.ts.map +1 -1
- package/dist/components/data/sheet/sheetUtils.js.map +1 -1
- package/dist/components/data/sheet/types.d.ts +23 -23
- package/dist/components/data/sheet/types.d.ts.map +1 -1
- package/dist/components/disclosure/DialogInstanceContext.d.ts +3 -3
- package/dist/components/disclosure/DialogInstanceContext.d.ts.map +1 -1
- package/dist/components/disclosure/DialogInstanceContext.js.map +1 -1
- package/dist/components/form-control/checkbox/CheckboxGroup.d.ts +7 -7
- package/dist/components/form-control/checkbox/CheckboxGroup.d.ts.map +1 -1
- package/dist/components/form-control/checkbox/CheckboxGroup.js.map +1 -1
- package/dist/components/form-control/checkbox/RadioGroup.d.ts +7 -7
- package/dist/components/form-control/checkbox/RadioGroup.d.ts.map +1 -1
- package/dist/components/form-control/checkbox/RadioGroup.js.map +1 -1
- package/dist/components/form-control/combobox/Combobox.d.ts +9 -9
- package/dist/components/form-control/combobox/Combobox.d.ts.map +1 -1
- package/dist/components/form-control/combobox/ComboboxContext.d.ts +4 -4
- package/dist/components/form-control/combobox/ComboboxContext.d.ts.map +1 -1
- package/dist/components/form-control/combobox/ComboboxContext.js.map +1 -1
- package/dist/components/form-control/combobox/ComboboxItem.d.ts +2 -2
- package/dist/components/form-control/combobox/ComboboxItem.d.ts.map +1 -1
- package/dist/components/form-control/select/Select.d.ts +16 -16
- package/dist/components/form-control/select/Select.d.ts.map +1 -1
- package/dist/components/form-control/select/SelectContext.d.ts +4 -4
- package/dist/components/form-control/select/SelectContext.d.ts.map +1 -1
- package/dist/components/form-control/select/SelectContext.js.map +1 -1
- package/dist/components/form-control/select/SelectItem.d.ts +3 -3
- package/dist/components/form-control/select/SelectItem.d.ts.map +1 -1
- package/dist/components/form-control/state-preset/StatePreset.d.ts +4 -4
- package/dist/components/form-control/state-preset/StatePreset.d.ts.map +1 -1
- package/dist/components/form-control/state-preset/StatePreset.js.map +1 -1
- package/dist/components/layout/sidebar/SidebarUser.d.ts.map +1 -1
- package/dist/components/layout/sidebar/SidebarUser.js +13 -9
- package/dist/components/layout/sidebar/SidebarUser.js.map +2 -2
- package/dist/helpers/createAppStructure.d.ts +1 -0
- package/dist/helpers/createAppStructure.d.ts.map +1 -1
- package/dist/helpers/createAppStructure.js +16 -1
- package/dist/helpers/createAppStructure.js.map +1 -1
- package/dist/hooks/createControllableSignal.d.ts +5 -5
- package/dist/hooks/createControllableSignal.d.ts.map +1 -1
- package/dist/hooks/createControllableSignal.js.map +1 -1
- package/dist/hooks/useLocalStorage.d.ts +1 -1
- package/dist/hooks/useLocalStorage.d.ts.map +1 -1
- package/dist/hooks/useLocalStorage.js.map +1 -1
- package/dist/hooks/useSyncConfig.d.ts +1 -1
- package/dist/hooks/useSyncConfig.d.ts.map +1 -1
- package/dist/hooks/useSyncConfig.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/providers/InitializeProvider.d.ts +0 -1
- package/dist/providers/InitializeProvider.d.ts.map +1 -1
- package/dist/providers/InitializeProvider.js +1 -6
- package/dist/providers/InitializeProvider.js.map +2 -2
- package/dist/providers/shared-data/SharedDataContext.d.ts +10 -10
- package/dist/providers/shared-data/SharedDataContext.d.ts.map +1 -1
- package/dist/providers/shared-data/SharedDataContext.js.map +1 -1
- package/dist/providers/shared-data/SharedDataProvider.d.ts +2 -2
- package/dist/providers/shared-data/SharedDataProvider.d.ts.map +1 -1
- package/dist/providers/shared-data/SharedDataProvider.js.map +1 -1
- package/docs/hooks.md +19 -0
- package/package.json +5 -5
- package/src/components/data/calendar/Calendar.tsx +8 -8
- package/src/components/data/sheet/DataSheetColumn.tsx +1 -1
- package/src/components/data/sheet/sheetUtils.ts +16 -13
- package/src/components/data/sheet/types.ts +23 -23
- package/src/components/disclosure/DialogInstanceContext.ts +4 -4
- package/src/components/form-control/checkbox/CheckboxGroup.tsx +10 -10
- package/src/components/form-control/checkbox/RadioGroup.tsx +10 -10
- package/src/components/form-control/combobox/Combobox.tsx +9 -9
- package/src/components/form-control/combobox/ComboboxContext.ts +5 -5
- package/src/components/form-control/combobox/ComboboxItem.tsx +2 -2
- package/src/components/form-control/select/Select.tsx +20 -20
- package/src/components/form-control/select/SelectContext.ts +5 -5
- package/src/components/form-control/select/SelectItem.tsx +3 -3
- package/src/components/form-control/state-preset/StatePreset.tsx +10 -10
- package/src/components/layout/sidebar/SidebarUser.tsx +5 -3
- package/src/helpers/createAppStructure.ts +22 -0
- package/src/hooks/createControllableSignal.ts +7 -7
- package/src/hooks/useLocalStorage.ts +11 -8
- package/src/hooks/useSyncConfig.ts +8 -5
- package/src/index.ts +58 -13
- package/src/providers/InitializeProvider.tsx +2 -5
- package/src/providers/shared-data/SharedDataContext.ts +13 -11
- package/src/providers/shared-data/SharedDataProvider.tsx +2 -2
- package/tailwind.config.ts +1 -1
|
@@ -30,18 +30,18 @@ const SelectItemChildren: ParentComponent = (props) => (
|
|
|
30
30
|
</div>
|
|
31
31
|
);
|
|
32
32
|
|
|
33
|
-
export interface SelectItemProps<
|
|
33
|
+
export interface SelectItemProps<TValue = unknown> extends Omit<
|
|
34
34
|
JSX.ButtonHTMLAttributes<HTMLButtonElement>,
|
|
35
35
|
"value" | "onClick"
|
|
36
36
|
> {
|
|
37
37
|
/** 아이템의 값 */
|
|
38
|
-
value:
|
|
38
|
+
value: TValue;
|
|
39
39
|
|
|
40
40
|
/** 비활성화 */
|
|
41
41
|
disabled?: boolean;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
interface SelectItemComponent<
|
|
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<
|
|
15
|
+
interface StatePresetItem<TValue> {
|
|
16
16
|
name: string;
|
|
17
|
-
state:
|
|
17
|
+
state: TValue;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
type StatePresetSize = ComponentSize;
|
|
21
21
|
|
|
22
|
-
export interface StatePresetProps<
|
|
22
|
+
export interface StatePresetProps<TValue> {
|
|
23
23
|
presetKey: string;
|
|
24
|
-
value:
|
|
25
|
-
onValueChange: (value:
|
|
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<
|
|
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<
|
|
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<
|
|
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<
|
|
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 <
|
|
281
|
+
export const StatePreset = StatePresetInner as <TValue>(props: StatePresetProps<TValue>) => JSX.Element;
|
|
@@ -17,10 +17,12 @@ const headerClass = clsx(
|
|
|
17
17
|
"flex",
|
|
18
18
|
"items-center",
|
|
19
19
|
"p-2",
|
|
20
|
+
"m-1",
|
|
21
|
+
"rounded-md",
|
|
20
22
|
"text-left",
|
|
21
23
|
"cursor-pointer",
|
|
22
24
|
"transition-colors",
|
|
23
|
-
"hover:bg-base-
|
|
25
|
+
"hover:bg-base-500/10",
|
|
24
26
|
"dark:hover:bg-base-700",
|
|
25
27
|
);
|
|
26
28
|
|
|
@@ -95,8 +97,7 @@ export const SidebarUser: Component<SidebarUserProps> = (props) => {
|
|
|
95
97
|
menu.onClick();
|
|
96
98
|
};
|
|
97
99
|
|
|
98
|
-
const getHeaderClassName = () =>
|
|
99
|
-
twMerge(headerClass, !hasMenus() && headerReadonlyClass, open() && "border-b border-b-base-50");
|
|
100
|
+
const getHeaderClassName = () => twMerge(headerClass, !hasMenus() && headerReadonlyClass);
|
|
100
101
|
|
|
101
102
|
const getContainerClassName = () => twMerge(containerClass, local.class);
|
|
102
103
|
|
|
@@ -123,6 +124,7 @@ export const SidebarUser: Component<SidebarUserProps> = (props) => {
|
|
|
123
124
|
</button>
|
|
124
125
|
<Show when={hasMenus()}>
|
|
125
126
|
<Collapse open={open()}>
|
|
127
|
+
<hr class={clsx("border-base-200 dark:border-base-700")} />
|
|
126
128
|
<List inset>
|
|
127
129
|
<For each={local.menus}>
|
|
128
130
|
{(menu) => <ListItem onClick={() => handleMenuClick(menu)}>{menu.title}</ListItem>}
|
|
@@ -54,6 +54,7 @@ export interface AppStructure<TModule> {
|
|
|
54
54
|
usableMenus: Accessor<SidebarMenuItem[]>;
|
|
55
55
|
usableFlatMenus: Accessor<AppFlatMenu[]>;
|
|
56
56
|
permRecord: Accessor<Record<string, boolean>>;
|
|
57
|
+
getTitleChainByHref(href: string): string[];
|
|
57
58
|
}
|
|
58
59
|
|
|
59
60
|
// ── 내부 헬퍼 ──
|
|
@@ -150,6 +151,23 @@ function flattenMenus(menus: SidebarMenuItem[], titleChain: string[] = []): AppF
|
|
|
150
151
|
return result;
|
|
151
152
|
}
|
|
152
153
|
|
|
154
|
+
function findItemChainByCodes<TModule>(
|
|
155
|
+
items: AppStructureItem<TModule>[],
|
|
156
|
+
codes: string[],
|
|
157
|
+
): AppStructureItem<TModule>[] {
|
|
158
|
+
const result: AppStructureItem<TModule>[] = [];
|
|
159
|
+
|
|
160
|
+
let currentItems = items;
|
|
161
|
+
for (const code of codes) {
|
|
162
|
+
const found = currentItems.find((item) => item.code === code);
|
|
163
|
+
if (found === undefined) break;
|
|
164
|
+
result.push(found);
|
|
165
|
+
currentItems = isGroupItem(found) ? found.children : [];
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return result;
|
|
169
|
+
}
|
|
170
|
+
|
|
153
171
|
// ── 메인 함수 ──
|
|
154
172
|
|
|
155
173
|
export function createAppStructure<TModule>(opts: {
|
|
@@ -179,5 +197,9 @@ export function createAppStructure<TModule>(opts: {
|
|
|
179
197
|
usableMenus,
|
|
180
198
|
usableFlatMenus,
|
|
181
199
|
permRecord,
|
|
200
|
+
getTitleChainByHref(href: string): string[] {
|
|
201
|
+
const codes = href.split("/").filter(Boolean);
|
|
202
|
+
return findItemChainByCodes(opts.items, codes).map((item) => item.title);
|
|
203
|
+
},
|
|
182
204
|
};
|
|
183
205
|
}
|
|
@@ -7,7 +7,7 @@ import { createSignal, createEffect } from "solid-js";
|
|
|
7
7
|
* @remarks
|
|
8
8
|
* 함수를 저장해야 할 경우 객체로 감싸기: `createControllableSignal<{ fn: () => void }>(...)`
|
|
9
9
|
*/
|
|
10
|
-
type NotFunction<
|
|
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<
|
|
39
|
-
value: () =>
|
|
40
|
-
onChange: () => ((value:
|
|
38
|
+
export function createControllableSignal<TValue>(options: {
|
|
39
|
+
value: () => TValue & NotFunction<TValue>;
|
|
40
|
+
onChange: () => ((value: TValue) => void) | undefined;
|
|
41
41
|
}) {
|
|
42
|
-
const [internalValue, setInternalValue] = createSignal<
|
|
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:
|
|
53
|
-
const resolved = typeof newValue === "function" ? (newValue as (prev:
|
|
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<
|
|
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:
|
|
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
|
|
42
|
+
storedValue = JSON.parse(item) as TValue;
|
|
40
43
|
}
|
|
41
44
|
} catch {
|
|
42
45
|
// JSON 파싱 실패 시 초기값 사용
|
|
43
46
|
}
|
|
44
47
|
|
|
45
|
-
const [value, setValue] = createSignal<
|
|
48
|
+
const [value, setValue] = createSignal<TValue | undefined>(storedValue);
|
|
46
49
|
|
|
47
|
-
const setAndStore = (newValue:
|
|
48
|
-
let resolved:
|
|
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:
|
|
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<
|
|
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<
|
|
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<
|
|
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
|
|
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
|
|
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
|
|
61
|
+
setValue(() => JSON.parse(stored) as TValue);
|
|
59
62
|
}
|
|
60
63
|
} catch {
|
|
61
64
|
// Ignore parse errors
|
package/src/index.ts
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
|
-
|
|
1
|
+
//#region ========== Form Control ==========
|
|
2
|
+
|
|
3
|
+
// Button
|
|
2
4
|
export * from "./components/form-control/Button";
|
|
5
|
+
|
|
6
|
+
// Select
|
|
3
7
|
export * from "./components/form-control/select/Select";
|
|
4
8
|
export * from "./components/form-control/select/SelectContext";
|
|
9
|
+
|
|
10
|
+
// Combobox
|
|
5
11
|
export * from "./components/form-control/combobox/Combobox";
|
|
6
12
|
export * from "./components/form-control/combobox/ComboboxContext";
|
|
13
|
+
|
|
14
|
+
// Field
|
|
7
15
|
export * from "./components/form-control/field/TextInput";
|
|
8
16
|
export * from "./components/form-control/field/NumberInput";
|
|
9
17
|
export * from "./components/form-control/field/DatePicker";
|
|
@@ -11,11 +19,15 @@ export * from "./components/form-control/field/DateTimePicker";
|
|
|
11
19
|
export * from "./components/form-control/field/TimePicker";
|
|
12
20
|
export * from "./components/form-control/field/Textarea";
|
|
13
21
|
export * from "./components/form-control/field/Field.styles";
|
|
22
|
+
|
|
23
|
+
// Checkbox / Radio
|
|
14
24
|
export * from "./components/form-control/checkbox/Checkbox";
|
|
15
25
|
export * from "./components/form-control/checkbox/Checkbox.styles";
|
|
16
26
|
export * from "./components/form-control/checkbox/Radio";
|
|
17
27
|
export * from "./components/form-control/checkbox/CheckboxGroup";
|
|
18
28
|
export * from "./components/form-control/checkbox/RadioGroup";
|
|
29
|
+
|
|
30
|
+
// Specialty inputs
|
|
19
31
|
export * from "./components/form-control/color-picker/ColorPicker";
|
|
20
32
|
export * from "./components/form-control/date-range-picker/DateRangePicker";
|
|
21
33
|
export * from "./components/form-control/editor/RichTextEditor";
|
|
@@ -24,14 +36,20 @@ export * from "./components/form-control/state-preset/StatePreset";
|
|
|
24
36
|
export * from "./components/form-control/ThemeToggle";
|
|
25
37
|
export * from "./components/form-control/Invalid";
|
|
26
38
|
|
|
27
|
-
|
|
39
|
+
//#endregion
|
|
40
|
+
|
|
41
|
+
//#region ========== Layout ==========
|
|
42
|
+
|
|
28
43
|
export * from "./components/layout/FormGroup";
|
|
29
44
|
export * from "./components/layout/FormTable";
|
|
30
45
|
export * from "./components/layout/sidebar/Sidebar";
|
|
31
46
|
export * from "./components/layout/sidebar/SidebarContext";
|
|
32
47
|
export * from "./components/layout/topbar/Topbar";
|
|
33
48
|
|
|
34
|
-
|
|
49
|
+
//#endregion
|
|
50
|
+
|
|
51
|
+
//#region ========== Data ==========
|
|
52
|
+
|
|
35
53
|
export * from "./components/data/Table";
|
|
36
54
|
export * from "./components/data/list/List";
|
|
37
55
|
export * from "./components/data/list/ListContext";
|
|
@@ -45,7 +63,10 @@ export * from "./components/data/permission-table/PermissionTable";
|
|
|
45
63
|
export * from "./components/data/kanban/Kanban";
|
|
46
64
|
export * from "./components/data/kanban/KanbanContext";
|
|
47
65
|
|
|
48
|
-
|
|
66
|
+
//#endregion
|
|
67
|
+
|
|
68
|
+
//#region ========== Display ==========
|
|
69
|
+
|
|
49
70
|
export * from "./components/display/Barcode";
|
|
50
71
|
export * from "./components/display/Card";
|
|
51
72
|
export * from "./components/display/Echarts";
|
|
@@ -53,7 +74,10 @@ export * from "./components/display/Icon";
|
|
|
53
74
|
export * from "./components/display/Tag";
|
|
54
75
|
export * from "./components/display/Alert";
|
|
55
76
|
|
|
56
|
-
|
|
77
|
+
//#endregion
|
|
78
|
+
|
|
79
|
+
//#region ========== Disclosure ==========
|
|
80
|
+
|
|
57
81
|
export * from "./components/disclosure/Collapse";
|
|
58
82
|
export * from "./components/disclosure/Dropdown";
|
|
59
83
|
export * from "./components/disclosure/Dialog";
|
|
@@ -62,23 +86,30 @@ export * from "./components/disclosure/DialogInstanceContext";
|
|
|
62
86
|
export * from "./components/disclosure/DialogProvider";
|
|
63
87
|
export * from "./components/disclosure/Tabs";
|
|
64
88
|
|
|
65
|
-
|
|
89
|
+
//#endregion
|
|
90
|
+
|
|
91
|
+
//#region ========== Feedback ==========
|
|
92
|
+
|
|
93
|
+
// Notification
|
|
66
94
|
export * from "./components/feedback/notification/NotificationContext";
|
|
67
95
|
export * from "./components/feedback/notification/NotificationBell";
|
|
68
96
|
export * from "./components/feedback/notification/NotificationProvider";
|
|
69
97
|
export * from "./components/feedback/notification/NotificationBanner";
|
|
70
98
|
|
|
71
|
-
//
|
|
99
|
+
// Loading
|
|
72
100
|
export * from "./components/feedback/loading/LoadingContext";
|
|
73
101
|
export * from "./components/feedback/loading/LoadingContainer";
|
|
74
102
|
export * from "./components/feedback/loading/LoadingProvider";
|
|
75
103
|
|
|
76
|
-
//
|
|
104
|
+
// Print
|
|
77
105
|
export * from "./components/feedback/print/Print";
|
|
78
106
|
export * from "./components/feedback/print/PrintInstanceContext";
|
|
79
107
|
export * from "./components/feedback/Progress";
|
|
80
108
|
|
|
81
|
-
|
|
109
|
+
//#endregion
|
|
110
|
+
|
|
111
|
+
//#region ========== Providers ==========
|
|
112
|
+
|
|
82
113
|
export * from "./providers/ConfigContext";
|
|
83
114
|
export * from "./providers/InitializeProvider";
|
|
84
115
|
export { useTheme } from "./providers/ThemeContext";
|
|
@@ -89,7 +120,10 @@ export * from "./providers/shared-data/SharedDataContext";
|
|
|
89
120
|
export * from "./providers/shared-data/SharedDataProvider";
|
|
90
121
|
export * from "./providers/shared-data/SharedDataChangeEvent";
|
|
91
122
|
|
|
92
|
-
|
|
123
|
+
//#endregion
|
|
124
|
+
|
|
125
|
+
//#region ========== Hooks ==========
|
|
126
|
+
|
|
93
127
|
export * from "./hooks/useLocalStorage";
|
|
94
128
|
export * from "./hooks/useSyncConfig";
|
|
95
129
|
export * from "./hooks/useLogger";
|
|
@@ -100,14 +134,23 @@ export { createMountTransition } from "./hooks/createMountTransition";
|
|
|
100
134
|
export { createPwaUpdate } from "./hooks/createPwaUpdate";
|
|
101
135
|
export { useRouterLink } from "./hooks/useRouterLink";
|
|
102
136
|
|
|
103
|
-
|
|
137
|
+
//#endregion
|
|
138
|
+
|
|
139
|
+
//#region ========== Styles ==========
|
|
140
|
+
|
|
104
141
|
export * from "./styles/tokens.styles";
|
|
105
142
|
export * from "./styles/patterns.styles";
|
|
106
143
|
|
|
107
|
-
|
|
144
|
+
//#endregion
|
|
145
|
+
|
|
146
|
+
//#region ========== Directives ==========
|
|
147
|
+
|
|
108
148
|
export { ripple } from "./directives/ripple";
|
|
109
149
|
|
|
110
|
-
|
|
150
|
+
//#endregion
|
|
151
|
+
|
|
152
|
+
//#region ========== Helpers ==========
|
|
153
|
+
|
|
111
154
|
export { mergeStyles } from "./helpers/mergeStyles";
|
|
112
155
|
export { splitSlots } from "./helpers/splitSlots";
|
|
113
156
|
export { createAppStructure } from "./helpers/createAppStructure";
|
|
@@ -120,3 +163,5 @@ export type {
|
|
|
120
163
|
AppFlatMenu,
|
|
121
164
|
AppStructure,
|
|
122
165
|
} from "./helpers/createAppStructure";
|
|
166
|
+
|
|
167
|
+
//#endregion
|
|
@@ -6,7 +6,7 @@ import { ThemeProvider } from "./ThemeContext";
|
|
|
6
6
|
import { NotificationProvider } from "../components/feedback/notification/NotificationProvider";
|
|
7
7
|
import { NotificationBanner } from "../components/feedback/notification/NotificationBanner";
|
|
8
8
|
import { LoadingProvider } from "../components/feedback/loading/LoadingProvider";
|
|
9
|
-
|
|
9
|
+
|
|
10
10
|
import { createPwaUpdate } from "../hooks/createPwaUpdate";
|
|
11
11
|
import { useLogger } from "../hooks/useLogger";
|
|
12
12
|
|
|
@@ -50,7 +50,6 @@ function GlobalErrorLogger() {
|
|
|
50
50
|
* - 알림 시스템 + 배너
|
|
51
51
|
* - 전역 에러 캡처 (window.onerror, unhandledrejection)
|
|
52
52
|
* - 루트 로딩 오버레이
|
|
53
|
-
* - 프로그래매틱 다이얼로그
|
|
54
53
|
*
|
|
55
54
|
* @example
|
|
56
55
|
* ```tsx
|
|
@@ -71,9 +70,7 @@ export const InitializeProvider: ParentComponent<{ config: AppConfig }> = (props
|
|
|
71
70
|
<NotificationBanner />
|
|
72
71
|
<GlobalErrorLogger />
|
|
73
72
|
<PwaUpdater />
|
|
74
|
-
<LoadingProvider variant={props.config.loadingVariant}>
|
|
75
|
-
<DialogProvider>{props.children}</DialogProvider>
|
|
76
|
-
</LoadingProvider>
|
|
73
|
+
<LoadingProvider variant={props.config.loadingVariant}>{props.children}</LoadingProvider>
|
|
77
74
|
</NotificationProvider>
|
|
78
75
|
</ThemeProvider>
|
|
79
76
|
</ConfigContext.Provider>
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import { type Accessor, createContext, useContext } from "solid-js";
|
|
2
2
|
|
|
3
|
-
export interface SharedDataDefinition<
|
|
3
|
+
export interface SharedDataDefinition<TData> {
|
|
4
4
|
serviceKey: string;
|
|
5
|
-
fetch: (changeKeys?: Array<string | number>) => Promise<
|
|
6
|
-
getKey: (item:
|
|
7
|
-
orderBy: [(item:
|
|
5
|
+
fetch: (changeKeys?: Array<string | number>) => Promise<TData[]>;
|
|
6
|
+
getKey: (item: TData) => string | number;
|
|
7
|
+
orderBy: [(item: TData) => unknown, "asc" | "desc"][];
|
|
8
8
|
filter?: unknown;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
export interface SharedDataAccessor<
|
|
12
|
-
items: Accessor<
|
|
13
|
-
get: (key: string | number | undefined) =>
|
|
11
|
+
export interface SharedDataAccessor<TData> {
|
|
12
|
+
items: Accessor<TData[]>;
|
|
13
|
+
get: (key: string | number | undefined) => TData | undefined;
|
|
14
14
|
emit: (changeKeys?: Array<string | number>) => Promise<void>;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
export type SharedDataValue<
|
|
18
|
-
[K in keyof
|
|
17
|
+
export type SharedDataValue<TSharedData extends Record<string, unknown>> = {
|
|
18
|
+
[K in keyof TSharedData]: SharedDataAccessor<TSharedData[K]>;
|
|
19
19
|
} & {
|
|
20
20
|
wait: () => Promise<void>;
|
|
21
21
|
loading: Accessor<boolean>;
|
|
@@ -23,12 +23,14 @@ export type SharedDataValue<T extends Record<string, unknown>> = {
|
|
|
23
23
|
|
|
24
24
|
export const SharedDataContext = createContext<SharedDataValue<Record<string, unknown>>>();
|
|
25
25
|
|
|
26
|
-
export function useSharedData<
|
|
26
|
+
export function useSharedData<
|
|
27
|
+
TSharedData extends Record<string, unknown> = Record<string, unknown>,
|
|
28
|
+
>(): SharedDataValue<TSharedData> {
|
|
27
29
|
const context = useContext(SharedDataContext);
|
|
28
30
|
if (!context) {
|
|
29
31
|
throw new Error(
|
|
30
32
|
"useSharedData는 SharedDataProvider 내부에서만 사용할 수 있습니다. SharedDataProvider는 ServiceClientProvider 아래에 위치해야 합니다",
|
|
31
33
|
);
|
|
32
34
|
}
|
|
33
|
-
return context as unknown as SharedDataValue<
|
|
35
|
+
return context as unknown as SharedDataValue<TSharedData>;
|
|
34
36
|
}
|
|
@@ -11,8 +11,8 @@ import { useServiceClient } from "../ServiceClientContext";
|
|
|
11
11
|
import { useNotification } from "../../components/feedback/notification/NotificationContext";
|
|
12
12
|
import { useLogger } from "../../hooks/useLogger";
|
|
13
13
|
|
|
14
|
-
export function SharedDataProvider<
|
|
15
|
-
definitions: { [K in keyof
|
|
14
|
+
export function SharedDataProvider<TSharedData extends Record<string, unknown>>(props: {
|
|
15
|
+
definitions: { [K in keyof TSharedData]: SharedDataDefinition<TSharedData[K]> };
|
|
16
16
|
children: JSX.Element;
|
|
17
17
|
}): JSX.Element {
|
|
18
18
|
const serviceClient = useServiceClient();
|