@simplysm/solid 13.0.62 → 13.0.65
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 +6 -0
- package/dist/components/data/sheet/DataSheet.d.ts.map +1 -1
- package/dist/components/data/sheet/DataSheet.js +3 -2
- package/dist/components/data/sheet/DataSheet.js.map +2 -2
- package/dist/components/features/address/AddressSearch.d.ts +8 -0
- package/dist/components/features/address/AddressSearch.d.ts.map +1 -0
- package/dist/components/features/address/AddressSearch.js +72 -0
- package/dist/components/features/address/AddressSearch.js.map +6 -0
- package/dist/components/features/crud-detail/CrudDetail.d.ts.map +1 -0
- package/dist/components/{data → features}/crud-detail/CrudDetail.js +62 -41
- package/dist/components/features/crud-detail/CrudDetail.js.map +6 -0
- package/dist/components/features/crud-detail/CrudDetailAfter.d.ts.map +1 -0
- package/dist/components/{data → features}/crud-detail/CrudDetailAfter.js.map +1 -1
- package/dist/components/features/crud-detail/CrudDetailBefore.d.ts.map +1 -0
- package/dist/components/{data → features}/crud-detail/CrudDetailBefore.js.map +1 -1
- package/dist/components/features/crud-detail/CrudDetailTools.d.ts.map +1 -0
- package/dist/components/{data → features}/crud-detail/CrudDetailTools.js.map +1 -1
- package/dist/components/features/crud-detail/types.d.ts.map +1 -0
- package/dist/components/features/crud-sheet/CrudSheet.d.ts.map +1 -0
- package/dist/components/{data → features}/crud-sheet/CrudSheet.js +166 -21
- package/dist/components/features/crud-sheet/CrudSheet.js.map +6 -0
- package/dist/components/features/crud-sheet/CrudSheetColumn.d.ts.map +1 -0
- package/dist/components/{data → features}/crud-sheet/CrudSheetColumn.js +1 -1
- package/dist/components/{data → features}/crud-sheet/CrudSheetColumn.js.map +1 -1
- package/dist/components/features/crud-sheet/CrudSheetFilter.d.ts.map +1 -0
- package/dist/components/{data → features}/crud-sheet/CrudSheetFilter.js.map +1 -1
- package/dist/components/features/crud-sheet/CrudSheetHeader.d.ts.map +1 -0
- package/dist/components/{data → features}/crud-sheet/CrudSheetHeader.js.map +1 -1
- package/dist/components/features/crud-sheet/CrudSheetTools.d.ts.map +1 -0
- package/dist/components/{data → features}/crud-sheet/CrudSheetTools.js.map +1 -1
- package/dist/components/{data → features}/crud-sheet/types.d.ts +10 -4
- package/dist/components/features/crud-sheet/types.d.ts.map +1 -0
- package/dist/components/features/data-select-button/DataSelectButton.d.ts +38 -0
- package/dist/components/features/data-select-button/DataSelectButton.d.ts.map +1 -0
- package/dist/components/features/data-select-button/DataSelectButton.js +184 -0
- package/dist/components/features/data-select-button/DataSelectButton.js.map +6 -0
- package/dist/components/features/permission-table/PermissionTable.d.ts.map +1 -0
- package/dist/components/{data → features}/permission-table/PermissionTable.js +1 -1
- package/dist/components/{data → features}/permission-table/PermissionTable.js.map +1 -1
- package/dist/components/features/shared-data/SharedDataSelect.d.ts +32 -0
- package/dist/components/features/shared-data/SharedDataSelect.d.ts.map +1 -0
- package/dist/components/features/shared-data/SharedDataSelect.js +74 -0
- package/dist/components/features/shared-data/SharedDataSelect.js.map +6 -0
- package/dist/components/features/shared-data/SharedDataSelectButton.d.ts +29 -0
- package/dist/components/features/shared-data/SharedDataSelectButton.d.ts.map +1 -0
- package/dist/components/features/shared-data/SharedDataSelectButton.js +17 -0
- package/dist/components/features/shared-data/SharedDataSelectButton.js.map +6 -0
- package/dist/components/features/shared-data/SharedDataSelectList.d.ts +29 -0
- package/dist/components/features/shared-data/SharedDataSelectList.d.ts.map +1 -0
- package/dist/components/features/shared-data/SharedDataSelectList.js +80 -0
- package/dist/components/features/shared-data/SharedDataSelectList.js.map +6 -0
- package/dist/components/form-control/checkbox/Checkbox.d.ts.map +1 -1
- package/dist/components/form-control/checkbox/Checkbox.js +10 -10
- package/dist/components/form-control/checkbox/Checkbox.js.map +2 -2
- package/dist/components/form-control/checkbox/Checkbox.styles.d.ts.map +1 -1
- package/dist/components/form-control/checkbox/Checkbox.styles.js +2 -2
- package/dist/components/form-control/checkbox/Checkbox.styles.js.map +1 -1
- package/dist/components/form-control/checkbox/Radio.d.ts.map +1 -1
- package/dist/components/form-control/checkbox/Radio.js +13 -13
- package/dist/components/form-control/checkbox/Radio.js.map +2 -2
- package/dist/components/form-control/select/Select.d.ts +7 -3
- package/dist/components/form-control/select/Select.d.ts.map +1 -1
- package/dist/components/form-control/select/Select.js +146 -45
- package/dist/components/form-control/select/Select.js.map +2 -2
- package/dist/components/form-control/select-list/SelectList.d.ts +54 -0
- package/dist/components/form-control/select-list/SelectList.d.ts.map +1 -0
- package/dist/components/form-control/select-list/SelectList.js +280 -0
- package/dist/components/form-control/select-list/SelectList.js.map +6 -0
- package/dist/components/form-control/select-list/SelectListContext.d.ts +13 -0
- package/dist/components/form-control/select-list/SelectListContext.d.ts.map +1 -0
- package/dist/components/form-control/select-list/SelectListContext.js +14 -0
- package/dist/components/form-control/select-list/SelectListContext.js.map +6 -0
- package/dist/index.d.ts +11 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -5
- package/dist/index.js.map +1 -1
- package/dist/providers/ServiceClientContext.d.ts +5 -5
- package/dist/providers/ServiceClientContext.d.ts.map +1 -1
- package/dist/providers/ServiceClientProvider.d.ts.map +1 -1
- package/dist/providers/ServiceClientProvider.js +12 -8
- package/dist/providers/ServiceClientProvider.js.map +2 -2
- package/dist/providers/shared-data/SharedDataContext.d.ts +16 -2
- 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 +1 -2
- package/dist/providers/shared-data/SharedDataProvider.d.ts.map +1 -1
- package/dist/providers/shared-data/SharedDataProvider.js +27 -13
- package/dist/providers/shared-data/SharedDataProvider.js.map +2 -2
- package/docs/data-components.md +15 -4
- package/docs/form-controls.md +257 -0
- package/docs/hooks.md +30 -0
- package/docs/providers.md +7 -0
- package/package.json +5 -3
- package/src/components/data/sheet/DataSheet.tsx +6 -7
- package/src/components/features/address/AddressSearch.tsx +75 -0
- package/src/components/{data → features}/crud-detail/CrudDetail.tsx +51 -26
- package/src/components/{data → features}/crud-sheet/CrudSheet.tsx +160 -23
- package/src/components/{data → features}/crud-sheet/CrudSheetColumn.tsx +1 -1
- package/src/components/{data → features}/crud-sheet/types.ts +14 -4
- package/src/components/features/data-select-button/DataSelectButton.tsx +279 -0
- package/src/components/{data → features}/permission-table/PermissionTable.tsx +1 -1
- package/src/components/features/shared-data/SharedDataSelect.tsx +101 -0
- package/src/components/features/shared-data/SharedDataSelectButton.tsx +47 -0
- package/src/components/features/shared-data/SharedDataSelectList.tsx +85 -0
- package/src/components/form-control/checkbox/Checkbox.styles.ts +2 -2
- package/src/components/form-control/checkbox/Checkbox.tsx +18 -20
- package/src/components/form-control/checkbox/Radio.tsx +18 -20
- package/src/components/form-control/select/Select.tsx +192 -36
- package/src/components/form-control/select-list/SelectList.tsx +385 -0
- package/src/components/form-control/select-list/SelectListContext.ts +23 -0
- package/src/index.ts +29 -5
- package/src/providers/ServiceClientContext.ts +5 -5
- package/src/providers/ServiceClientProvider.tsx +17 -12
- package/src/providers/shared-data/SharedDataContext.ts +16 -2
- package/src/providers/shared-data/SharedDataProvider.tsx +33 -17
- package/dist/components/data/crud-detail/CrudDetail.d.ts.map +0 -1
- package/dist/components/data/crud-detail/CrudDetail.js.map +0 -6
- package/dist/components/data/crud-detail/CrudDetailAfter.d.ts.map +0 -1
- package/dist/components/data/crud-detail/CrudDetailBefore.d.ts.map +0 -1
- package/dist/components/data/crud-detail/CrudDetailTools.d.ts.map +0 -1
- package/dist/components/data/crud-detail/types.d.ts.map +0 -1
- package/dist/components/data/crud-sheet/CrudSheet.d.ts.map +0 -1
- package/dist/components/data/crud-sheet/CrudSheet.js.map +0 -6
- package/dist/components/data/crud-sheet/CrudSheetColumn.d.ts.map +0 -1
- package/dist/components/data/crud-sheet/CrudSheetFilter.d.ts.map +0 -1
- package/dist/components/data/crud-sheet/CrudSheetHeader.d.ts.map +0 -1
- package/dist/components/data/crud-sheet/CrudSheetTools.d.ts.map +0 -1
- package/dist/components/data/crud-sheet/types.d.ts.map +0 -1
- package/dist/components/data/permission-table/PermissionTable.d.ts.map +0 -1
- /package/dist/components/{data → features}/crud-detail/CrudDetail.d.ts +0 -0
- /package/dist/components/{data → features}/crud-detail/CrudDetailAfter.d.ts +0 -0
- /package/dist/components/{data → features}/crud-detail/CrudDetailAfter.js +0 -0
- /package/dist/components/{data → features}/crud-detail/CrudDetailBefore.d.ts +0 -0
- /package/dist/components/{data → features}/crud-detail/CrudDetailBefore.js +0 -0
- /package/dist/components/{data → features}/crud-detail/CrudDetailTools.d.ts +0 -0
- /package/dist/components/{data → features}/crud-detail/CrudDetailTools.js +0 -0
- /package/dist/components/{data → features}/crud-detail/types.d.ts +0 -0
- /package/dist/components/{data → features}/crud-detail/types.js +0 -0
- /package/dist/components/{data → features}/crud-detail/types.js.map +0 -0
- /package/dist/components/{data → features}/crud-sheet/CrudSheet.d.ts +0 -0
- /package/dist/components/{data → features}/crud-sheet/CrudSheetColumn.d.ts +0 -0
- /package/dist/components/{data → features}/crud-sheet/CrudSheetFilter.d.ts +0 -0
- /package/dist/components/{data → features}/crud-sheet/CrudSheetFilter.js +0 -0
- /package/dist/components/{data → features}/crud-sheet/CrudSheetHeader.d.ts +0 -0
- /package/dist/components/{data → features}/crud-sheet/CrudSheetHeader.js +0 -0
- /package/dist/components/{data → features}/crud-sheet/CrudSheetTools.d.ts +0 -0
- /package/dist/components/{data → features}/crud-sheet/CrudSheetTools.js +0 -0
- /package/dist/components/{data → features}/crud-sheet/types.js +0 -0
- /package/dist/components/{data → features}/crud-sheet/types.js.map +0 -0
- /package/dist/components/{data → features}/permission-table/PermissionTable.d.ts +0 -0
- /package/src/components/{data → features}/crud-detail/CrudDetailAfter.tsx +0 -0
- /package/src/components/{data → features}/crud-detail/CrudDetailBefore.tsx +0 -0
- /package/src/components/{data → features}/crud-detail/CrudDetailTools.tsx +0 -0
- /package/src/components/{data → features}/crud-detail/types.ts +0 -0
- /package/src/components/{data → features}/crud-sheet/CrudSheetFilter.tsx +0 -0
- /package/src/components/{data → features}/crud-sheet/CrudSheetHeader.tsx +0 -0
- /package/src/components/{data → features}/crud-sheet/CrudSheetTools.tsx +0 -0
|
@@ -6,8 +6,8 @@ import { type Accessor } from "solid-js";
|
|
|
6
6
|
* SharedDataProvider에 전달하여 서버 데이터 구독을 설정한다.
|
|
7
7
|
*/
|
|
8
8
|
export interface SharedDataDefinition<TData> {
|
|
9
|
-
/** 서비스 연결 key (
|
|
10
|
-
serviceKey
|
|
9
|
+
/** 서비스 연결 key (생략 시 "default") */
|
|
10
|
+
serviceKey?: string;
|
|
11
11
|
/** 데이터 조회 함수 (changeKeys가 있으면 해당 항목만 부분 갱신) */
|
|
12
12
|
fetch: (changeKeys?: Array<string | number>) => Promise<TData[]>;
|
|
13
13
|
/** 항목의 고유 key 추출 함수 */
|
|
@@ -16,6 +16,12 @@ export interface SharedDataDefinition<TData> {
|
|
|
16
16
|
orderBy: [(item: TData) => unknown, "asc" | "desc"][];
|
|
17
17
|
/** 서버 이벤트 필터 (같은 name의 이벤트 중 filter가 일치하는 것만 수신) */
|
|
18
18
|
filter?: unknown;
|
|
19
|
+
/** 항목에서 검색 텍스트를 추출하는 함수 */
|
|
20
|
+
getSearchText?: (item: TData) => string;
|
|
21
|
+
/** 항목이 숨김 상태인지 판별하는 함수 */
|
|
22
|
+
getIsHidden?: (item: TData) => boolean;
|
|
23
|
+
/** 항목의 부모 key를 추출하는 함수 (트리 구조 지원) */
|
|
24
|
+
getParentKey?: (item: TData) => string | number | undefined;
|
|
19
25
|
}
|
|
20
26
|
/**
|
|
21
27
|
* 공유 데이터 접근자
|
|
@@ -30,6 +36,14 @@ export interface SharedDataAccessor<TData> {
|
|
|
30
36
|
get: (key: string | number | undefined) => TData | undefined;
|
|
31
37
|
/** 서버에 변경 이벤트 전파 (모든 구독자에게 refetch 트리거) */
|
|
32
38
|
emit: (changeKeys?: Array<string | number>) => Promise<void>;
|
|
39
|
+
/** 항목의 고유 key 추출 함수 */
|
|
40
|
+
getKey: (item: TData) => string | number;
|
|
41
|
+
/** 항목에서 검색 텍스트를 추출하는 함수 */
|
|
42
|
+
getSearchText?: (item: TData) => string;
|
|
43
|
+
/** 항목이 숨김 상태인지 판별하는 함수 */
|
|
44
|
+
getIsHidden?: (item: TData) => boolean;
|
|
45
|
+
/** 항목의 부모 key를 추출하는 함수 (트리 구조 지원) */
|
|
46
|
+
getParentKey?: (item: TData) => string | number | undefined;
|
|
33
47
|
}
|
|
34
48
|
/**
|
|
35
49
|
* 공유 데이터 Context 값
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SharedDataContext.d.ts","sourceRoot":"","sources":["..\\..\\..\\src\\providers\\shared-data\\SharedDataContext.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAA6B,MAAM,UAAU,CAAC;AAEpE;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB,CAAC,KAAK;IACzC,
|
|
1
|
+
{"version":3,"file":"SharedDataContext.d.ts","sourceRoot":"","sources":["..\\..\\..\\src\\providers\\shared-data\\SharedDataContext.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/providers/shared-data/SharedDataContext.ts"],
|
|
4
|
-
"mappings": "AAAA,SAAwB,eAAe,kBAAkB;
|
|
4
|
+
"mappings": "AAAA,SAAwB,eAAe,kBAAkB;AA2ElD,MAAM,oBAAoB,cAAwD;AAOlF,SAAS,gBAEkB;AAChC,QAAM,UAAU,WAAW,iBAAiB;AAC5C,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,0HAAoD;AAAA,EACtE;AACA,SAAO;AACT;",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
|
@@ -6,7 +6,7 @@ import { type JSX } from "solid-js";
|
|
|
6
6
|
* - ServiceClientProvider와 NotificationProvider 내부에서 사용해야 함
|
|
7
7
|
* - LoggerProvider가 있으면 fetch 실패를 로거에도 기록
|
|
8
8
|
* - configure() 호출 전: wait, busy, configure만 접근 가능. 데이터 접근 시 throw
|
|
9
|
-
* - configure() 호출 후: definitions
|
|
9
|
+
* - configure() 호출 후: definitions 등록. 각 key의 items()/get() 첫 접근 시 서버 이벤트 리스너 등록 + fetch (lazy)
|
|
10
10
|
* - 동시 fetch 호출 시 version counter로 데이터 역전 방지
|
|
11
11
|
* - fetch 실패 시 사용자에게 danger 알림 표시
|
|
12
12
|
* - cleanup 시 모든 이벤트 리스너 자동 해제
|
|
@@ -20,7 +20,6 @@ import { type JSX } from "solid-js";
|
|
|
20
20
|
* // 자식 컴포넌트에서 나중에 설정:
|
|
21
21
|
* useSharedData().configure(() => ({
|
|
22
22
|
* users: {
|
|
23
|
-
* serviceKey: "main",
|
|
24
23
|
* fetch: async (changeKeys) => fetchUsers(changeKeys),
|
|
25
24
|
* getKey: (item) => item.id,
|
|
26
25
|
* orderBy: [[(item) => item.name, "asc"]],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SharedDataProvider.d.ts","sourceRoot":"","sources":["..\\..\\..\\src\\providers\\shared-data\\SharedDataProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,GAAG,EAAuC,MAAM,UAAU,CAAC;AAaxF
|
|
1
|
+
{"version":3,"file":"SharedDataProvider.d.ts","sourceRoot":"","sources":["..\\..\\..\\src\\providers\\shared-data\\SharedDataProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,GAAG,EAAuC,MAAM,UAAU,CAAC;AAaxF;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE;IAAE,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAA;CAAE,GAAG,GAAG,CAAC,OAAO,CAyLhF"}
|
|
@@ -68,6 +68,20 @@ function SharedDataProvider(props) {
|
|
|
68
68
|
const definitions = fn({});
|
|
69
69
|
currentDefinitions = definitions;
|
|
70
70
|
for (const [name, def] of Object.entries(definitions)) {
|
|
71
|
+
let ensureInitialized2 = function() {
|
|
72
|
+
if (initialized) return;
|
|
73
|
+
initialized = true;
|
|
74
|
+
void client.addEventListener(SharedDataChangeEvent, {
|
|
75
|
+
name,
|
|
76
|
+
filter: def.filter
|
|
77
|
+
}, async (changeKeys) => {
|
|
78
|
+
await loadData(name, def, changeKeys);
|
|
79
|
+
}).then((key) => {
|
|
80
|
+
listenerKeyMap.set(name, key);
|
|
81
|
+
});
|
|
82
|
+
void loadData(name, def);
|
|
83
|
+
};
|
|
84
|
+
var ensureInitialized = ensureInitialized2;
|
|
71
85
|
const [items, setItems] = createSignal([]);
|
|
72
86
|
signalMap.set(name, [items, setItems]);
|
|
73
87
|
const itemMap = createMemo(() => {
|
|
@@ -78,25 +92,25 @@ function SharedDataProvider(props) {
|
|
|
78
92
|
return map;
|
|
79
93
|
});
|
|
80
94
|
memoMap.set(name, itemMap);
|
|
81
|
-
const client = serviceClient.get(def.serviceKey);
|
|
82
|
-
|
|
83
|
-
name,
|
|
84
|
-
filter: def.filter
|
|
85
|
-
}, async (changeKeys) => {
|
|
86
|
-
await loadData(name, def, changeKeys);
|
|
87
|
-
}).then((key) => {
|
|
88
|
-
listenerKeyMap.set(name, key);
|
|
89
|
-
});
|
|
90
|
-
void loadData(name, def);
|
|
95
|
+
const client = serviceClient.get(def.serviceKey ?? "default");
|
|
96
|
+
let initialized = false;
|
|
91
97
|
accessors[name] = {
|
|
92
|
-
items
|
|
98
|
+
items: () => {
|
|
99
|
+
ensureInitialized2();
|
|
100
|
+
return items();
|
|
101
|
+
},
|
|
93
102
|
get: (key) => {
|
|
103
|
+
ensureInitialized2();
|
|
94
104
|
if (key === void 0) return void 0;
|
|
95
105
|
return itemMap().get(key);
|
|
96
106
|
},
|
|
97
107
|
emit: async (changeKeys) => {
|
|
98
108
|
await client.emitToServer(SharedDataChangeEvent, (info) => info.name === name && objEqual(info.filter, def.filter), changeKeys);
|
|
99
|
-
}
|
|
109
|
+
},
|
|
110
|
+
getKey: def.getKey,
|
|
111
|
+
getSearchText: def.getSearchText,
|
|
112
|
+
getIsHidden: def.getIsHidden,
|
|
113
|
+
getParentKey: def.getParentKey
|
|
100
114
|
};
|
|
101
115
|
}
|
|
102
116
|
}
|
|
@@ -106,7 +120,7 @@ function SharedDataProvider(props) {
|
|
|
106
120
|
const listenerKey = listenerKeyMap.get(name);
|
|
107
121
|
if (listenerKey != null) {
|
|
108
122
|
const def = currentDefinitions[name];
|
|
109
|
-
const client = serviceClient.get(def.serviceKey);
|
|
123
|
+
const client = serviceClient.get(def.serviceKey ?? "default");
|
|
110
124
|
void client.removeEventListener(listenerKey);
|
|
111
125
|
}
|
|
112
126
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/providers/shared-data/SharedDataProvider.tsx"],
|
|
4
|
-
"mappings": ";AAAA,SAAkCA,YAAYC,cAAcC,iBAAiB;AAC7E,SAASC,UAAUC,iBAAiB;AACpC,SACEC,yBAIK;AACP,SAASC,6BAA6B;AACtC,SAASC,wBAAwB;AACjC,SAASC,uBAAuB;AAChC,SAASC,iBAAiB;
|
|
5
|
-
"names": ["createMemo", "createSignal", "onCleanup", "objEqual", "waitUntil", "SharedDataContext", "SharedDataChangeEvent", "useServiceClient", "useNotification", "useLogger", "SharedDataProvider", "props", "serviceClient", "notification", "logger", "configured", "busyCount", "setBusyCount", "busy", "signalMap", "Map", "memoMap", "listenerKeyMap", "versionMap", "accessors", "currentDefinitions", "ordering", "data", "orderByList", "result", "orderBy", "reverse", "selector", "item", "orderByDesc", "loadData", "name", "def", "changeKeys", "currentVersion", "get", "set", "c", "signal", "Error", "setItems", "resData", "fetch", "prev", "filtered", "filter", "includes", "getKey", "push", "err", "error", "danger", "message", "wait", "configure", "fn", "definitions", "Object", "entries", "
|
|
4
|
+
"mappings": "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",
|
|
5
|
+
"names": ["createMemo", "createSignal", "onCleanup", "objEqual", "waitUntil", "SharedDataContext", "SharedDataChangeEvent", "useServiceClient", "useNotification", "useLogger", "SharedDataProvider", "props", "serviceClient", "notification", "logger", "configured", "busyCount", "setBusyCount", "busy", "signalMap", "Map", "memoMap", "listenerKeyMap", "versionMap", "accessors", "currentDefinitions", "ordering", "data", "orderByList", "result", "orderBy", "reverse", "selector", "item", "orderByDesc", "loadData", "name", "def", "changeKeys", "currentVersion", "get", "set", "c", "signal", "Error", "setItems", "resData", "fetch", "prev", "filtered", "filter", "includes", "getKey", "push", "err", "error", "danger", "message", "wait", "configure", "fn", "definitions", "Object", "entries", "ensureInitialized", "initialized", "client", "addEventListener", "then", "key", "items", "itemMap", "map", "serviceKey", "undefined", "emit", "emitToServer", "info", "getSearchText", "getIsHidden", "getParentKey", "listenerKey", "removeEventListener", "KNOWN_KEYS", "Set", "contextValue", "Proxy", "target", "prop", "has", "_$createComponent", "Provider", "value", "children"]
|
|
6
6
|
}
|
package/docs/data-components.md
CHANGED
|
@@ -137,11 +137,22 @@ import { DataSheet } from "@simplysm/solid";
|
|
|
137
137
|
| `width` | `string` | - | Column width (e.g., `"100px"`, `"10rem"`) |
|
|
138
138
|
| `class` | `string` | - | Cell CSS class |
|
|
139
139
|
| `fixed` | `boolean` | `false` | Fixed column |
|
|
140
|
-
| `hidden` | `boolean` | `false` |
|
|
140
|
+
| `hidden` | `boolean` | `false` | Default hidden state (overridable by user column config) |
|
|
141
141
|
| `collapse` | `boolean` | `false` | Hidden in config modal |
|
|
142
142
|
| `sortable` | `boolean` | `true` | Sortable |
|
|
143
143
|
| `resizable` | `boolean` | `true` | Resizable |
|
|
144
|
-
| `children` | `(ctx:
|
|
144
|
+
| `children` | `(ctx: DataSheetCellContext<T>) => JSX.Element` | **(required)** | Cell rendering function |
|
|
145
|
+
|
|
146
|
+
**DataSheetCellContext:**
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
interface DataSheetCellContext<T> {
|
|
150
|
+
item: T;
|
|
151
|
+
index: number; // Position within parent array (root: items[], child: parent.children[])
|
|
152
|
+
row: number; // Flat display row position (within current page)
|
|
153
|
+
depth: number;
|
|
154
|
+
}
|
|
155
|
+
```
|
|
145
156
|
|
|
146
157
|
---
|
|
147
158
|
|
|
@@ -724,8 +735,8 @@ const handleEdit = async () => {
|
|
|
724
735
|
| `children` | `(ctx: CrudDetailContext<TData>) => JSX.Element` | **(required)** | Render prop receiving context |
|
|
725
736
|
| `submit` | `(data: TData) => Promise<boolean \| undefined>` | - | Save function. Return `true` to trigger success notification |
|
|
726
737
|
| `toggleDelete` | `(del: boolean) => Promise<boolean \| undefined>` | - | Soft-delete/restore function. `del=true` for delete, `false` for restore |
|
|
727
|
-
| `editable` | `
|
|
728
|
-
| `deletable` | `
|
|
738
|
+
| `editable` | `boolean` | `true` | Whether editing is allowed |
|
|
739
|
+
| `deletable` | `boolean` | `true` | Whether delete/restore is allowed |
|
|
729
740
|
| `data` | `TData` | - | Controlled data state |
|
|
730
741
|
| `onDataChange` | `(data: TData) => void` | - | Data change callback (controlled mode) |
|
|
731
742
|
| `class` | `string` | - | CSS class |
|
package/docs/form-controls.md
CHANGED
|
@@ -436,6 +436,263 @@ import { Select } from "@simplysm/solid";
|
|
|
436
436
|
|
|
437
437
|
---
|
|
438
438
|
|
|
439
|
+
## SelectList
|
|
440
|
+
|
|
441
|
+
List-style single selection component with built-in search, pagination, and slot-based customization. Uses compound component pattern with `SelectList.Header`, `SelectList.Filter`, and `SelectList.ItemTemplate`.
|
|
442
|
+
|
|
443
|
+
```tsx
|
|
444
|
+
import { SelectList } from "@simplysm/solid";
|
|
445
|
+
|
|
446
|
+
// Basic usage with search
|
|
447
|
+
<SelectList
|
|
448
|
+
items={users()}
|
|
449
|
+
value={selectedUser()}
|
|
450
|
+
onValueChange={setSelectedUser}
|
|
451
|
+
getSearchText={(user) => user.name}
|
|
452
|
+
>
|
|
453
|
+
<SelectList.ItemTemplate>
|
|
454
|
+
{(user) => <>{user.name} ({user.email})</>}
|
|
455
|
+
</SelectList.ItemTemplate>
|
|
456
|
+
</SelectList>
|
|
457
|
+
|
|
458
|
+
// With pagination and header
|
|
459
|
+
<SelectList
|
|
460
|
+
items={items()}
|
|
461
|
+
value={selected()}
|
|
462
|
+
onValueChange={setSelected}
|
|
463
|
+
pageSize={20}
|
|
464
|
+
header="Select an item"
|
|
465
|
+
>
|
|
466
|
+
<SelectList.ItemTemplate>
|
|
467
|
+
{(item) => <>{item.name}</>}
|
|
468
|
+
</SelectList.ItemTemplate>
|
|
469
|
+
</SelectList>
|
|
470
|
+
|
|
471
|
+
// With custom header and filter slots
|
|
472
|
+
<SelectList
|
|
473
|
+
items={items()}
|
|
474
|
+
value={selected()}
|
|
475
|
+
onValueChange={setSelected}
|
|
476
|
+
>
|
|
477
|
+
<SelectList.Header>
|
|
478
|
+
<div class="flex items-center gap-1">Custom Header</div>
|
|
479
|
+
</SelectList.Header>
|
|
480
|
+
<SelectList.Filter>
|
|
481
|
+
<MyCustomFilter />
|
|
482
|
+
</SelectList.Filter>
|
|
483
|
+
<SelectList.ItemTemplate>
|
|
484
|
+
{(item) => <>{item.label}</>}
|
|
485
|
+
</SelectList.ItemTemplate>
|
|
486
|
+
</SelectList>
|
|
487
|
+
|
|
488
|
+
// With canChange guard
|
|
489
|
+
<SelectList
|
|
490
|
+
items={items()}
|
|
491
|
+
value={selected()}
|
|
492
|
+
onValueChange={setSelected}
|
|
493
|
+
canChange={async (item) => {
|
|
494
|
+
if (hasUnsavedChanges()) return confirm("Discard changes?");
|
|
495
|
+
return true;
|
|
496
|
+
}}
|
|
497
|
+
>
|
|
498
|
+
<SelectList.ItemTemplate>
|
|
499
|
+
{(item) => <>{item.name}</>}
|
|
500
|
+
</SelectList.ItemTemplate>
|
|
501
|
+
</SelectList>
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
| Prop | Type | Default | Description |
|
|
505
|
+
|------|------|---------|-------------|
|
|
506
|
+
| `items` | `T[]` | **(required)** | Item array |
|
|
507
|
+
| `value` | `T` | - | Selected value |
|
|
508
|
+
| `onValueChange` | `(value: T \| undefined) => void` | - | Value change callback |
|
|
509
|
+
| `required` | `boolean` | - | Required (hides "unspecified" item) |
|
|
510
|
+
| `disabled` | `boolean` | - | Disabled state |
|
|
511
|
+
| `getSearchText` | `(item: T) => string` | - | Search text extractor (auto-shows search input) |
|
|
512
|
+
| `getIsHidden` | `(item: T) => boolean` | - | Hidden item filter |
|
|
513
|
+
| `filterFn` | `(item: T, index: number) => boolean` | - | Custom filter function |
|
|
514
|
+
| `canChange` | `(item: T \| undefined) => boolean \| Promise<boolean>` | - | Change guard (return `false` to block) |
|
|
515
|
+
| `pageSize` | `number` | - | Page size (auto-shows pagination) |
|
|
516
|
+
| `header` | `string` | - | Header text |
|
|
517
|
+
| `class` | `string` | - | CSS class |
|
|
518
|
+
| `style` | `JSX.CSSProperties` | - | Inline style |
|
|
519
|
+
|
|
520
|
+
**Sub-components:**
|
|
521
|
+
- `SelectList.Header` -- Custom header slot (overrides `header` prop)
|
|
522
|
+
- `SelectList.Filter` -- Custom filter slot (overrides default search input)
|
|
523
|
+
- `SelectList.ItemTemplate` -- Item rendering template
|
|
524
|
+
|
|
525
|
+
---
|
|
526
|
+
|
|
527
|
+
## DataSelectButton
|
|
528
|
+
|
|
529
|
+
Modal-based selection button. Displays selected items inline and opens a dialog for selection. Supports single and multiple selection with key-based loading.
|
|
530
|
+
|
|
531
|
+
```tsx
|
|
532
|
+
import { DataSelectButton, type DataSelectModalResult } from "@simplysm/solid";
|
|
533
|
+
|
|
534
|
+
// Single selection
|
|
535
|
+
<DataSelectButton
|
|
536
|
+
value={selectedUserId()}
|
|
537
|
+
onValueChange={setSelectedUserId}
|
|
538
|
+
load={async (keys) => await api.getUsersByIds(keys)}
|
|
539
|
+
modal={() => <UserSelectModal />}
|
|
540
|
+
renderItem={(user) => <>{user.name}</>}
|
|
541
|
+
/>
|
|
542
|
+
|
|
543
|
+
// Multiple selection
|
|
544
|
+
<DataSelectButton
|
|
545
|
+
value={selectedIds()}
|
|
546
|
+
onValueChange={setSelectedIds}
|
|
547
|
+
multiple
|
|
548
|
+
load={async (keys) => await api.getItemsByIds(keys)}
|
|
549
|
+
modal={() => <ItemSelectModal />}
|
|
550
|
+
renderItem={(item) => <>{item.name}</>}
|
|
551
|
+
/>
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
The modal should return `DataSelectModalResult<TKey>` via `dialogInstance.close({ selectedKeys: [...] })`.
|
|
555
|
+
|
|
556
|
+
| Prop | Type | Default | Description |
|
|
557
|
+
|------|------|---------|-------------|
|
|
558
|
+
| `value` | `TKey \| TKey[]` | - | Selected key(s) |
|
|
559
|
+
| `onValueChange` | `(value: TKey \| TKey[] \| undefined) => void` | - | Value change callback |
|
|
560
|
+
| `load` | `(keys: TKey[]) => TItem[] \| Promise<TItem[]>` | **(required)** | Load items by keys |
|
|
561
|
+
| `modal` | `() => JSX.Element` | **(required)** | Selection modal factory |
|
|
562
|
+
| `renderItem` | `(item: TItem) => JSX.Element` | **(required)** | Item display renderer |
|
|
563
|
+
| `multiple` | `boolean` | - | Multiple selection mode |
|
|
564
|
+
| `required` | `boolean` | - | Required field |
|
|
565
|
+
| `disabled` | `boolean` | - | Disabled state |
|
|
566
|
+
| `size` | `"xs" \| "sm" \| "lg" \| "xl"` | - | Size |
|
|
567
|
+
| `inset` | `boolean` | - | Inset style |
|
|
568
|
+
| `validate` | `(value: unknown) => string \| undefined` | - | Custom validation function |
|
|
569
|
+
| `touchMode` | `boolean` | - | Show error only after focus loss |
|
|
570
|
+
| `dialogOptions` | `DialogShowOptions` | - | Dialog options for modal |
|
|
571
|
+
|
|
572
|
+
**DataSelectModalResult:**
|
|
573
|
+
|
|
574
|
+
```typescript
|
|
575
|
+
interface DataSelectModalResult<TKey> {
|
|
576
|
+
selectedKeys: TKey[];
|
|
577
|
+
}
|
|
578
|
+
```
|
|
579
|
+
|
|
580
|
+
---
|
|
581
|
+
|
|
582
|
+
## SharedData Wrappers
|
|
583
|
+
|
|
584
|
+
Convenience wrappers that connect `SharedDataAccessor` (from `useSharedData()`) to `Select`, `DataSelectButton`, and `SelectList` components. They auto-wire `items`, tree structure (`getChildren`), search, and hidden filtering from the shared data definition.
|
|
585
|
+
|
|
586
|
+
### SharedDataSelect
|
|
587
|
+
|
|
588
|
+
Wraps `Select` with `SharedDataAccessor`. Optionally adds search modal and edit modal action buttons.
|
|
589
|
+
|
|
590
|
+
```tsx
|
|
591
|
+
import { SharedDataSelect } from "@simplysm/solid";
|
|
592
|
+
|
|
593
|
+
const sharedData = useSharedData<MySharedData>();
|
|
594
|
+
|
|
595
|
+
<SharedDataSelect data={sharedData.departments} value={deptId()} onValueChange={setDeptId}>
|
|
596
|
+
{(dept) => <>{dept.name}</>}
|
|
597
|
+
</SharedDataSelect>
|
|
598
|
+
|
|
599
|
+
// With search modal and edit modal
|
|
600
|
+
<SharedDataSelect
|
|
601
|
+
data={sharedData.users}
|
|
602
|
+
value={userId()}
|
|
603
|
+
onValueChange={setUserId}
|
|
604
|
+
modal={() => <UserSearchModal />}
|
|
605
|
+
editModal={() => <UserEditModal />}
|
|
606
|
+
>
|
|
607
|
+
{(user) => <>{user.name}</>}
|
|
608
|
+
</SharedDataSelect>
|
|
609
|
+
```
|
|
610
|
+
|
|
611
|
+
| Prop | Type | Default | Description |
|
|
612
|
+
|------|------|---------|-------------|
|
|
613
|
+
| `data` | `SharedDataAccessor<TItem>` | **(required)** | Shared data accessor |
|
|
614
|
+
| `value` | `unknown` | - | Selected value |
|
|
615
|
+
| `onValueChange` | `(value: unknown) => void` | - | Value change callback |
|
|
616
|
+
| `multiple` | `boolean` | - | Multiple selection |
|
|
617
|
+
| `required` | `boolean` | - | Required field |
|
|
618
|
+
| `disabled` | `boolean` | - | Disabled state |
|
|
619
|
+
| `size` | `"xs" \| "sm" \| "lg" \| "xl"` | - | Size |
|
|
620
|
+
| `inset` | `boolean` | - | Inset style |
|
|
621
|
+
| `filterFn` | `(item: TItem, index: number) => boolean` | - | Item filter function |
|
|
622
|
+
| `modal` | `() => JSX.Element` | - | Search modal factory (adds search icon action) |
|
|
623
|
+
| `editModal` | `() => JSX.Element` | - | Edit modal factory (adds edit icon action) |
|
|
624
|
+
| `children` | `(item: TItem, index: number, depth: number) => JSX.Element` | **(required)** | Item render function |
|
|
625
|
+
|
|
626
|
+
### SharedDataSelectButton
|
|
627
|
+
|
|
628
|
+
Wraps `DataSelectButton` with `SharedDataAccessor`. Auto-wires `load` from shared data items.
|
|
629
|
+
|
|
630
|
+
```tsx
|
|
631
|
+
import { SharedDataSelectButton } from "@simplysm/solid";
|
|
632
|
+
|
|
633
|
+
const sharedData = useSharedData<MySharedData>();
|
|
634
|
+
|
|
635
|
+
<SharedDataSelectButton
|
|
636
|
+
data={sharedData.users}
|
|
637
|
+
value={userId()}
|
|
638
|
+
onValueChange={setUserId}
|
|
639
|
+
modal={() => <UserSelectModal />}
|
|
640
|
+
>
|
|
641
|
+
{(user) => <>{user.name}</>}
|
|
642
|
+
</SharedDataSelectButton>
|
|
643
|
+
```
|
|
644
|
+
|
|
645
|
+
| Prop | Type | Default | Description |
|
|
646
|
+
|------|------|---------|-------------|
|
|
647
|
+
| `data` | `SharedDataAccessor<TItem>` | **(required)** | Shared data accessor |
|
|
648
|
+
| `value` | `TKey \| TKey[]` | - | Selected key(s) |
|
|
649
|
+
| `onValueChange` | `(value: TKey \| TKey[] \| undefined) => void` | - | Value change callback |
|
|
650
|
+
| `multiple` | `boolean` | - | Multiple selection |
|
|
651
|
+
| `required` | `boolean` | - | Required field |
|
|
652
|
+
| `disabled` | `boolean` | - | Disabled state |
|
|
653
|
+
| `size` | `"xs" \| "sm" \| "lg" \| "xl"` | - | Size |
|
|
654
|
+
| `inset` | `boolean` | - | Inset style |
|
|
655
|
+
| `modal` | `() => JSX.Element` | **(required)** | Selection modal factory |
|
|
656
|
+
| `children` | `(item: TItem) => JSX.Element` | **(required)** | Item render function |
|
|
657
|
+
|
|
658
|
+
### SharedDataSelectList
|
|
659
|
+
|
|
660
|
+
Wraps `SelectList` with `SharedDataAccessor`. Optionally adds a management modal link in header.
|
|
661
|
+
|
|
662
|
+
```tsx
|
|
663
|
+
import { SharedDataSelectList } from "@simplysm/solid";
|
|
664
|
+
|
|
665
|
+
const sharedData = useSharedData<MySharedData>();
|
|
666
|
+
|
|
667
|
+
<SharedDataSelectList
|
|
668
|
+
data={sharedData.categories}
|
|
669
|
+
value={selectedCategory()}
|
|
670
|
+
onValueChange={setSelectedCategory}
|
|
671
|
+
header="Category"
|
|
672
|
+
modal={() => <CategoryManageModal />}
|
|
673
|
+
>
|
|
674
|
+
<SelectList.ItemTemplate>
|
|
675
|
+
{(cat) => <>{cat.name}</>}
|
|
676
|
+
</SelectList.ItemTemplate>
|
|
677
|
+
</SharedDataSelectList>
|
|
678
|
+
```
|
|
679
|
+
|
|
680
|
+
| Prop | Type | Default | Description |
|
|
681
|
+
|------|------|---------|-------------|
|
|
682
|
+
| `data` | `SharedDataAccessor<TItem>` | **(required)** | Shared data accessor |
|
|
683
|
+
| `value` | `TItem` | - | Selected value |
|
|
684
|
+
| `onValueChange` | `(value: TItem \| undefined) => void` | - | Value change callback |
|
|
685
|
+
| `required` | `boolean` | - | Required field |
|
|
686
|
+
| `disabled` | `boolean` | - | Disabled state |
|
|
687
|
+
| `filterFn` | `(item: TItem, index: number) => boolean` | - | Item filter function |
|
|
688
|
+
| `canChange` | `(item: TItem \| undefined) => boolean \| Promise<boolean>` | - | Change guard |
|
|
689
|
+
| `pageSize` | `number` | - | Page size (auto-shows pagination) |
|
|
690
|
+
| `header` | `string` | - | Header text |
|
|
691
|
+
| `modal` | `() => JSX.Element` | - | Management modal factory (adds link icon in header) |
|
|
692
|
+
| `children` | `JSX.Element` | **(required)** | Sub-component children (e.g., `SelectList.ItemTemplate`) |
|
|
693
|
+
|
|
694
|
+
---
|
|
695
|
+
|
|
439
696
|
## Combobox
|
|
440
697
|
|
|
441
698
|
Autocomplete component with async search and item selection support. Debouncing is built-in.
|
package/docs/hooks.md
CHANGED
|
@@ -269,6 +269,36 @@ const {
|
|
|
269
269
|
|
|
270
270
|
---
|
|
271
271
|
|
|
272
|
+
## createSlotSignal
|
|
273
|
+
|
|
274
|
+
Signal factory for slot registration pattern. Used internally by compound components (`SelectList`, etc.) to register child slot content.
|
|
275
|
+
|
|
276
|
+
```tsx
|
|
277
|
+
import { createSlotSignal, type SlotAccessor } from "@simplysm/solid";
|
|
278
|
+
|
|
279
|
+
const [headerSlot, setHeader] = createSlotSignal();
|
|
280
|
+
|
|
281
|
+
// Register slot content (typically from a sub-component)
|
|
282
|
+
setHeader(() => <div>Header Content</div>);
|
|
283
|
+
|
|
284
|
+
// Read slot content (in parent render)
|
|
285
|
+
<Show when={headerSlot()}>
|
|
286
|
+
{headerSlot()!()}
|
|
287
|
+
</Show>
|
|
288
|
+
|
|
289
|
+
// Unregister
|
|
290
|
+
setHeader(undefined);
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
| Return | Type | Description |
|
|
294
|
+
|--------|------|-------------|
|
|
295
|
+
| `[0]` | `Accessor<SlotAccessor>` | Slot accessor (`(() => JSX.Element) \| undefined`) |
|
|
296
|
+
| `[1]` | `(content: SlotAccessor) => void` | Slot setter |
|
|
297
|
+
|
|
298
|
+
**`SlotAccessor` type:** `(() => JSX.Element) | undefined`
|
|
299
|
+
|
|
300
|
+
---
|
|
301
|
+
|
|
272
302
|
## useRouterLink
|
|
273
303
|
|
|
274
304
|
`@solidjs/router`-based navigation hook. Automatically handles Ctrl/Alt + click (new tab), Shift + click (new window), and regular click (SPA routing).
|
package/docs/providers.md
CHANGED
|
@@ -106,6 +106,9 @@ interface SharedDataDefinition<TData> {
|
|
|
106
106
|
getKey: (item: TData) => string | number; // Primary key extractor
|
|
107
107
|
orderBy: [(item: TData) => unknown, "asc" | "desc"][]; // Sort order
|
|
108
108
|
filter?: unknown; // Optional filter for change events
|
|
109
|
+
getSearchText?: (item: TData) => string; // Search text extractor (for SelectList/Select filtering)
|
|
110
|
+
getIsHidden?: (item: TData) => boolean; // Hidden item filter
|
|
111
|
+
getParentKey?: (item: TData) => string | number | undefined; // Parent key extractor (for tree structure)
|
|
109
112
|
}
|
|
110
113
|
```
|
|
111
114
|
|
|
@@ -116,6 +119,10 @@ interface SharedDataDefinition<TData> {
|
|
|
116
119
|
| `items` | `Accessor<TData[]>` | Reactive item array |
|
|
117
120
|
| `get` | `(key: string \| number \| undefined) => TData \| undefined` | Get item by key |
|
|
118
121
|
| `emit` | `(changeKeys?: Array<string \| number>) => Promise<void>` | Emit change event to server (triggers refetch in all subscribers) |
|
|
122
|
+
| `getKey` | `(item: TData) => string \| number` | Primary key extractor |
|
|
123
|
+
| `getSearchText` | `((item: TData) => string) \| undefined` | Search text extractor |
|
|
124
|
+
| `getIsHidden` | `((item: TData) => boolean) \| undefined` | Hidden item filter |
|
|
125
|
+
| `getParentKey` | `((item: TData) => string \| number \| undefined) \| undefined` | Parent key extractor (tree structure) |
|
|
119
126
|
|
|
120
127
|
**SharedDataValue extras:**
|
|
121
128
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@simplysm/solid",
|
|
3
|
-
"version": "13.0.
|
|
3
|
+
"version": "13.0.65",
|
|
4
4
|
"description": "심플리즘 패키지 - SolidJS 라이브러리",
|
|
5
5
|
"author": "김석래",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -50,8 +50,10 @@
|
|
|
50
50
|
"solid-tiptap": "^0.8.0",
|
|
51
51
|
"tailwind-merge": "^3.5.0",
|
|
52
52
|
"tailwindcss": "^3.4.19",
|
|
53
|
-
"@simplysm/core-
|
|
54
|
-
"@simplysm/core-
|
|
53
|
+
"@simplysm/core-browser": "13.0.65",
|
|
54
|
+
"@simplysm/core-common": "13.0.65",
|
|
55
|
+
"@simplysm/service-client": "13.0.65",
|
|
56
|
+
"@simplysm/service-common": "13.0.65"
|
|
55
57
|
},
|
|
56
58
|
"devDependencies": {
|
|
57
59
|
"@solidjs/testing-library": "^0.8.10"
|
|
@@ -114,10 +114,8 @@ export const DataSheet: DataSheetComponent = <T,>(props: DataSheetProps<T>) => {
|
|
|
114
114
|
|
|
115
115
|
// #region Column Collection
|
|
116
116
|
const resolved = children(() => local.children);
|
|
117
|
-
const columnDefs = createMemo(
|
|
118
|
-
(resolved.toArray().filter(isDataSheetColumnDef) as unknown as DataSheetColumnDef<T>[]
|
|
119
|
-
(col) => !col.hidden,
|
|
120
|
-
),
|
|
117
|
+
const columnDefs = createMemo(
|
|
118
|
+
() => resolved.toArray().filter(isDataSheetColumnDef) as unknown as DataSheetColumnDef<T>[],
|
|
121
119
|
);
|
|
122
120
|
|
|
123
121
|
// #region Config (useSyncConfig)
|
|
@@ -130,14 +128,15 @@ export const DataSheet: DataSheetComponent = <T,>(props: DataSheetProps<T>) => {
|
|
|
130
128
|
|
|
131
129
|
// 설정이 적용된 최종 컬럼 — config의 hidden/fixed/width/displayOrder 오버라이드 적용
|
|
132
130
|
const effectiveColumns = createMemo(() => {
|
|
133
|
-
const cols = columnDefs();
|
|
131
|
+
const cols = columnDefs();
|
|
134
132
|
const record = config().columnRecord ?? {};
|
|
135
133
|
|
|
136
134
|
return cols
|
|
137
135
|
.filter((col) => {
|
|
138
|
-
// config
|
|
136
|
+
// config 오버라이드가 있으면 config 우선, 없으면 원래 col.hidden 사용
|
|
139
137
|
const saved = record[col.key];
|
|
140
|
-
|
|
138
|
+
const isHidden = saved?.hidden ?? col.hidden;
|
|
139
|
+
return !isHidden;
|
|
141
140
|
})
|
|
142
141
|
.map((col) => {
|
|
143
142
|
const saved = record[col.key];
|