@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.
Files changed (157) hide show
  1. package/README.md +6 -0
  2. package/dist/components/data/sheet/DataSheet.d.ts.map +1 -1
  3. package/dist/components/data/sheet/DataSheet.js +3 -2
  4. package/dist/components/data/sheet/DataSheet.js.map +2 -2
  5. package/dist/components/features/address/AddressSearch.d.ts +8 -0
  6. package/dist/components/features/address/AddressSearch.d.ts.map +1 -0
  7. package/dist/components/features/address/AddressSearch.js +72 -0
  8. package/dist/components/features/address/AddressSearch.js.map +6 -0
  9. package/dist/components/features/crud-detail/CrudDetail.d.ts.map +1 -0
  10. package/dist/components/{data → features}/crud-detail/CrudDetail.js +62 -41
  11. package/dist/components/features/crud-detail/CrudDetail.js.map +6 -0
  12. package/dist/components/features/crud-detail/CrudDetailAfter.d.ts.map +1 -0
  13. package/dist/components/{data → features}/crud-detail/CrudDetailAfter.js.map +1 -1
  14. package/dist/components/features/crud-detail/CrudDetailBefore.d.ts.map +1 -0
  15. package/dist/components/{data → features}/crud-detail/CrudDetailBefore.js.map +1 -1
  16. package/dist/components/features/crud-detail/CrudDetailTools.d.ts.map +1 -0
  17. package/dist/components/{data → features}/crud-detail/CrudDetailTools.js.map +1 -1
  18. package/dist/components/features/crud-detail/types.d.ts.map +1 -0
  19. package/dist/components/features/crud-sheet/CrudSheet.d.ts.map +1 -0
  20. package/dist/components/{data → features}/crud-sheet/CrudSheet.js +166 -21
  21. package/dist/components/features/crud-sheet/CrudSheet.js.map +6 -0
  22. package/dist/components/features/crud-sheet/CrudSheetColumn.d.ts.map +1 -0
  23. package/dist/components/{data → features}/crud-sheet/CrudSheetColumn.js +1 -1
  24. package/dist/components/{data → features}/crud-sheet/CrudSheetColumn.js.map +1 -1
  25. package/dist/components/features/crud-sheet/CrudSheetFilter.d.ts.map +1 -0
  26. package/dist/components/{data → features}/crud-sheet/CrudSheetFilter.js.map +1 -1
  27. package/dist/components/features/crud-sheet/CrudSheetHeader.d.ts.map +1 -0
  28. package/dist/components/{data → features}/crud-sheet/CrudSheetHeader.js.map +1 -1
  29. package/dist/components/features/crud-sheet/CrudSheetTools.d.ts.map +1 -0
  30. package/dist/components/{data → features}/crud-sheet/CrudSheetTools.js.map +1 -1
  31. package/dist/components/{data → features}/crud-sheet/types.d.ts +10 -4
  32. package/dist/components/features/crud-sheet/types.d.ts.map +1 -0
  33. package/dist/components/features/data-select-button/DataSelectButton.d.ts +38 -0
  34. package/dist/components/features/data-select-button/DataSelectButton.d.ts.map +1 -0
  35. package/dist/components/features/data-select-button/DataSelectButton.js +184 -0
  36. package/dist/components/features/data-select-button/DataSelectButton.js.map +6 -0
  37. package/dist/components/features/permission-table/PermissionTable.d.ts.map +1 -0
  38. package/dist/components/{data → features}/permission-table/PermissionTable.js +1 -1
  39. package/dist/components/{data → features}/permission-table/PermissionTable.js.map +1 -1
  40. package/dist/components/features/shared-data/SharedDataSelect.d.ts +32 -0
  41. package/dist/components/features/shared-data/SharedDataSelect.d.ts.map +1 -0
  42. package/dist/components/features/shared-data/SharedDataSelect.js +74 -0
  43. package/dist/components/features/shared-data/SharedDataSelect.js.map +6 -0
  44. package/dist/components/features/shared-data/SharedDataSelectButton.d.ts +29 -0
  45. package/dist/components/features/shared-data/SharedDataSelectButton.d.ts.map +1 -0
  46. package/dist/components/features/shared-data/SharedDataSelectButton.js +17 -0
  47. package/dist/components/features/shared-data/SharedDataSelectButton.js.map +6 -0
  48. package/dist/components/features/shared-data/SharedDataSelectList.d.ts +29 -0
  49. package/dist/components/features/shared-data/SharedDataSelectList.d.ts.map +1 -0
  50. package/dist/components/features/shared-data/SharedDataSelectList.js +80 -0
  51. package/dist/components/features/shared-data/SharedDataSelectList.js.map +6 -0
  52. package/dist/components/form-control/checkbox/Checkbox.d.ts.map +1 -1
  53. package/dist/components/form-control/checkbox/Checkbox.js +10 -10
  54. package/dist/components/form-control/checkbox/Checkbox.js.map +2 -2
  55. package/dist/components/form-control/checkbox/Checkbox.styles.d.ts.map +1 -1
  56. package/dist/components/form-control/checkbox/Checkbox.styles.js +2 -2
  57. package/dist/components/form-control/checkbox/Checkbox.styles.js.map +1 -1
  58. package/dist/components/form-control/checkbox/Radio.d.ts.map +1 -1
  59. package/dist/components/form-control/checkbox/Radio.js +13 -13
  60. package/dist/components/form-control/checkbox/Radio.js.map +2 -2
  61. package/dist/components/form-control/select/Select.d.ts +7 -3
  62. package/dist/components/form-control/select/Select.d.ts.map +1 -1
  63. package/dist/components/form-control/select/Select.js +146 -45
  64. package/dist/components/form-control/select/Select.js.map +2 -2
  65. package/dist/components/form-control/select-list/SelectList.d.ts +54 -0
  66. package/dist/components/form-control/select-list/SelectList.d.ts.map +1 -0
  67. package/dist/components/form-control/select-list/SelectList.js +280 -0
  68. package/dist/components/form-control/select-list/SelectList.js.map +6 -0
  69. package/dist/components/form-control/select-list/SelectListContext.d.ts +13 -0
  70. package/dist/components/form-control/select-list/SelectListContext.d.ts.map +1 -0
  71. package/dist/components/form-control/select-list/SelectListContext.js +14 -0
  72. package/dist/components/form-control/select-list/SelectListContext.js.map +6 -0
  73. package/dist/index.d.ts +11 -5
  74. package/dist/index.d.ts.map +1 -1
  75. package/dist/index.js +11 -5
  76. package/dist/index.js.map +1 -1
  77. package/dist/providers/ServiceClientContext.d.ts +5 -5
  78. package/dist/providers/ServiceClientContext.d.ts.map +1 -1
  79. package/dist/providers/ServiceClientProvider.d.ts.map +1 -1
  80. package/dist/providers/ServiceClientProvider.js +12 -8
  81. package/dist/providers/ServiceClientProvider.js.map +2 -2
  82. package/dist/providers/shared-data/SharedDataContext.d.ts +16 -2
  83. package/dist/providers/shared-data/SharedDataContext.d.ts.map +1 -1
  84. package/dist/providers/shared-data/SharedDataContext.js.map +1 -1
  85. package/dist/providers/shared-data/SharedDataProvider.d.ts +1 -2
  86. package/dist/providers/shared-data/SharedDataProvider.d.ts.map +1 -1
  87. package/dist/providers/shared-data/SharedDataProvider.js +27 -13
  88. package/dist/providers/shared-data/SharedDataProvider.js.map +2 -2
  89. package/docs/data-components.md +15 -4
  90. package/docs/form-controls.md +257 -0
  91. package/docs/hooks.md +30 -0
  92. package/docs/providers.md +7 -0
  93. package/package.json +5 -3
  94. package/src/components/data/sheet/DataSheet.tsx +6 -7
  95. package/src/components/features/address/AddressSearch.tsx +75 -0
  96. package/src/components/{data → features}/crud-detail/CrudDetail.tsx +51 -26
  97. package/src/components/{data → features}/crud-sheet/CrudSheet.tsx +160 -23
  98. package/src/components/{data → features}/crud-sheet/CrudSheetColumn.tsx +1 -1
  99. package/src/components/{data → features}/crud-sheet/types.ts +14 -4
  100. package/src/components/features/data-select-button/DataSelectButton.tsx +279 -0
  101. package/src/components/{data → features}/permission-table/PermissionTable.tsx +1 -1
  102. package/src/components/features/shared-data/SharedDataSelect.tsx +101 -0
  103. package/src/components/features/shared-data/SharedDataSelectButton.tsx +47 -0
  104. package/src/components/features/shared-data/SharedDataSelectList.tsx +85 -0
  105. package/src/components/form-control/checkbox/Checkbox.styles.ts +2 -2
  106. package/src/components/form-control/checkbox/Checkbox.tsx +18 -20
  107. package/src/components/form-control/checkbox/Radio.tsx +18 -20
  108. package/src/components/form-control/select/Select.tsx +192 -36
  109. package/src/components/form-control/select-list/SelectList.tsx +385 -0
  110. package/src/components/form-control/select-list/SelectListContext.ts +23 -0
  111. package/src/index.ts +29 -5
  112. package/src/providers/ServiceClientContext.ts +5 -5
  113. package/src/providers/ServiceClientProvider.tsx +17 -12
  114. package/src/providers/shared-data/SharedDataContext.ts +16 -2
  115. package/src/providers/shared-data/SharedDataProvider.tsx +33 -17
  116. package/dist/components/data/crud-detail/CrudDetail.d.ts.map +0 -1
  117. package/dist/components/data/crud-detail/CrudDetail.js.map +0 -6
  118. package/dist/components/data/crud-detail/CrudDetailAfter.d.ts.map +0 -1
  119. package/dist/components/data/crud-detail/CrudDetailBefore.d.ts.map +0 -1
  120. package/dist/components/data/crud-detail/CrudDetailTools.d.ts.map +0 -1
  121. package/dist/components/data/crud-detail/types.d.ts.map +0 -1
  122. package/dist/components/data/crud-sheet/CrudSheet.d.ts.map +0 -1
  123. package/dist/components/data/crud-sheet/CrudSheet.js.map +0 -6
  124. package/dist/components/data/crud-sheet/CrudSheetColumn.d.ts.map +0 -1
  125. package/dist/components/data/crud-sheet/CrudSheetFilter.d.ts.map +0 -1
  126. package/dist/components/data/crud-sheet/CrudSheetHeader.d.ts.map +0 -1
  127. package/dist/components/data/crud-sheet/CrudSheetTools.d.ts.map +0 -1
  128. package/dist/components/data/crud-sheet/types.d.ts.map +0 -1
  129. package/dist/components/data/permission-table/PermissionTable.d.ts.map +0 -1
  130. /package/dist/components/{data → features}/crud-detail/CrudDetail.d.ts +0 -0
  131. /package/dist/components/{data → features}/crud-detail/CrudDetailAfter.d.ts +0 -0
  132. /package/dist/components/{data → features}/crud-detail/CrudDetailAfter.js +0 -0
  133. /package/dist/components/{data → features}/crud-detail/CrudDetailBefore.d.ts +0 -0
  134. /package/dist/components/{data → features}/crud-detail/CrudDetailBefore.js +0 -0
  135. /package/dist/components/{data → features}/crud-detail/CrudDetailTools.d.ts +0 -0
  136. /package/dist/components/{data → features}/crud-detail/CrudDetailTools.js +0 -0
  137. /package/dist/components/{data → features}/crud-detail/types.d.ts +0 -0
  138. /package/dist/components/{data → features}/crud-detail/types.js +0 -0
  139. /package/dist/components/{data → features}/crud-detail/types.js.map +0 -0
  140. /package/dist/components/{data → features}/crud-sheet/CrudSheet.d.ts +0 -0
  141. /package/dist/components/{data → features}/crud-sheet/CrudSheetColumn.d.ts +0 -0
  142. /package/dist/components/{data → features}/crud-sheet/CrudSheetFilter.d.ts +0 -0
  143. /package/dist/components/{data → features}/crud-sheet/CrudSheetFilter.js +0 -0
  144. /package/dist/components/{data → features}/crud-sheet/CrudSheetHeader.d.ts +0 -0
  145. /package/dist/components/{data → features}/crud-sheet/CrudSheetHeader.js +0 -0
  146. /package/dist/components/{data → features}/crud-sheet/CrudSheetTools.d.ts +0 -0
  147. /package/dist/components/{data → features}/crud-sheet/CrudSheetTools.js +0 -0
  148. /package/dist/components/{data → features}/crud-sheet/types.js +0 -0
  149. /package/dist/components/{data → features}/crud-sheet/types.js.map +0 -0
  150. /package/dist/components/{data → features}/permission-table/PermissionTable.d.ts +0 -0
  151. /package/src/components/{data → features}/crud-detail/CrudDetailAfter.tsx +0 -0
  152. /package/src/components/{data → features}/crud-detail/CrudDetailBefore.tsx +0 -0
  153. /package/src/components/{data → features}/crud-detail/CrudDetailTools.tsx +0 -0
  154. /package/src/components/{data → features}/crud-detail/types.ts +0 -0
  155. /package/src/components/{data → features}/crud-sheet/CrudSheetFilter.tsx +0 -0
  156. /package/src/components/{data → features}/crud-sheet/CrudSheetHeader.tsx +0 -0
  157. /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 (useServiceClient의 connect key와 동일) */
10
- serviceKey: string;
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,qDAAqD;IACrD,UAAU,EAAE,MAAM,CAAC;IACnB,+CAA+C;IAC/C,KAAK,EAAE,CAAC,UAAU,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,KAAK,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IACjE,uBAAuB;IACvB,MAAM,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,MAAM,GAAG,MAAM,CAAC;IACzC,6BAA6B;IAC7B,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,KAAK,OAAO,EAAE,KAAK,GAAG,MAAM,CAAC,EAAE,CAAC;IACtD,oDAAoD;IACpD,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB,CAAC,KAAK;IACvC,gBAAgB;IAChB,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;IACzB,oBAAoB;IACpB,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,KAAK,KAAK,GAAG,SAAS,CAAC;IAC7D,2CAA2C;IAC3C,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9D;AAED;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,CAAC,WAAW,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI;KACxE,CAAC,IAAI,MAAM,WAAW,GAAG,kBAAkB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;CAC7D,GAAG;IACF,0BAA0B;IAC1B,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,oBAAoB;IACpB,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IACxB,iDAAiD;IACjD,SAAS,EAAE,CACT,EAAE,EAAE,CAAC,MAAM,EAAE;SACV,CAAC,IAAI,MAAM,WAAW,GAAG,oBAAoB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;KAC/D,KAAK;SACH,CAAC,IAAI,MAAM,WAAW,GAAG,oBAAoB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;KAC/D,KACE,IAAI,CAAC;CACX,CAAC;AAEF,qBAAqB;AACrB,eAAO,MAAM,iBAAiB,kFAA4D,CAAC;AAE3F;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,WAAW,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAClE,eAAe,CAAC,WAAW,CAAC,CAMhC"}
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;AA6DlD,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;",
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 각 key마다 서버 이벤트 리스너를 등록하여 실시간 동기화
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;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE;IAAE,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAA;CAAE,GAAG,GAAG,CAAC,OAAO,CAwKhF"}
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
- void client.addEventListener(SharedDataChangeEvent, {
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": "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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", "items", "itemMap", "map", "client", "serviceKey", "addEventListener", "then", "key", "undefined", "emit", "emitToServer", "info", "listenerKey", "removeEventListener", "KNOWN_KEYS", "Set", "contextValue", "Proxy", "target", "prop", "has", "_$createComponent", "Provider", "value", "children"]
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
  }
@@ -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` | Hidden column |
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: { item: T, index: number, depth: number }) => JSX.Element` | **(required)** | Cell rendering function |
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` | `() => boolean` | `() => true` | Whether editing is allowed |
728
- | `deletable` | `() => boolean` | `() => true` | Whether delete/restore is allowed |
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 |
@@ -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.62",
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-common": "13.0.62",
54
- "@simplysm/core-browser": "13.0.62"
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>[]).filter(
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(); // 이미 col.hidden (코드 설정) 필터링됨
131
+ const cols = columnDefs();
134
132
  const record = config().columnRecord ?? {};
135
133
 
136
134
  return cols
137
135
  .filter((col) => {
138
- // config에서 hidden으로 설정된 컬럼 제외
136
+ // config 오버라이드가 있으면 config 우선, 없으면 원래 col.hidden 사용
139
137
  const saved = record[col.key];
140
- return !saved?.hidden;
138
+ const isHidden = saved?.hidden ?? col.hidden;
139
+ return !isHidden;
141
140
  })
142
141
  .map((col) => {
143
142
  const saved = record[col.key];