@sellmate/design-system 0.0.56 → 1.0.0

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 (494) hide show
  1. package/dist/cjs/{select-keyboard-navigation-6fO_V4En.js → base-dropdown-event-Dc6AuxR4.js} +26 -26
  2. package/dist/cjs/base-dropdown-event-Dc6AuxR4.js.map +1 -0
  3. package/dist/cjs/design-system.cjs.js +2 -2
  4. package/dist/cjs/{index-B7tkxTye.js → index-D_J8ScR5.js} +3 -3
  5. package/dist/cjs/index-D_J8ScR5.js.map +1 -0
  6. package/dist/cjs/loader.cjs.js +2 -2
  7. package/dist/cjs/{resolveColor-DxvExwgo.js → resolveColor-B7Ku3IGq.js} +4 -5
  8. package/dist/{esm/resolveColor-BYf-ybt2.js.map → cjs/resolveColor-B7Ku3IGq.js.map} +1 -1
  9. package/dist/cjs/sd-badge.cjs.entry.js +4 -4
  10. package/dist/cjs/{sd-button_24.cjs.entry.js → sd-button_6.cjs.entry.js} +292 -2842
  11. package/dist/cjs/sd-card.cjs.entry.js +3 -3
  12. package/dist/cjs/sd-checkbox.cjs.entry.js +89 -0
  13. package/dist/cjs/sd-date-box.cjs.entry.js +10 -10
  14. package/dist/cjs/sd-date-picker.cjs.entry.js +5 -5
  15. package/dist/cjs/sd-date-range-picker.cjs.entry.js +8 -8
  16. package/dist/cjs/sd-field_3.cjs.entry.js +422 -0
  17. package/dist/cjs/sd-file-picker.cjs.entry.js +121 -0
  18. package/dist/cjs/sd-form.cjs.entry.js +74 -0
  19. package/dist/cjs/sd-guide.cjs.entry.js +81 -0
  20. package/dist/cjs/sd-loading-spinner_2.cjs.entry.js +195 -0
  21. package/dist/cjs/sd-modal-card.cjs.entry.js +8 -8
  22. package/dist/cjs/sd-number-input.cjs.entry.js +261 -0
  23. package/dist/cjs/sd-popover.cjs.entry.js +7 -7
  24. package/dist/cjs/sd-progress.cjs.entry.js +3 -3
  25. package/dist/cjs/sd-radio-button-group.cjs.entry.js +8 -21
  26. package/dist/cjs/sd-radio-group.cjs.entry.js +71 -0
  27. package/dist/cjs/sd-select-dropdown_3.cjs.entry.js +266 -0
  28. package/dist/cjs/sd-select-multiple-group.cjs.entry.js +446 -0
  29. package/dist/cjs/sd-select-multiple.cjs.entry.js +74 -152
  30. package/dist/cjs/sd-select-option-group.cjs.entry.js +69 -0
  31. package/dist/cjs/sd-table.cjs.entry.js +515 -85
  32. package/dist/cjs/sd-tabs.cjs.entry.js +66 -0
  33. package/dist/cjs/sd-tag.cjs.entry.js +57 -0
  34. package/dist/cjs/sd-toast-message.cjs.entry.js +61 -0
  35. package/dist/cjs/sd-toggle-button.cjs.entry.js +50 -0
  36. package/dist/cjs/sd-toggle.cjs.entry.js +46 -0
  37. package/dist/cjs/{tooltipArrow-8I9A3AOE.js → tooltipArrow-DU2DB2AD.js} +3 -3
  38. package/dist/cjs/{tooltipArrow-8I9A3AOE.js.map → tooltipArrow-DU2DB2AD.js.map} +1 -1
  39. package/dist/collection/collection-manifest.json +7 -8
  40. package/dist/collection/components/sd-badge/sd-badge.css +8 -9
  41. package/dist/collection/components/sd-badge/sd-badge.js +1 -2
  42. package/dist/collection/components/sd-badge/sd-badge.js.map +1 -1
  43. package/dist/collection/components/sd-button/sd-button.css +2 -1
  44. package/dist/collection/components/sd-button/sd-button.js +2 -34
  45. package/dist/collection/components/sd-button/sd-button.js.map +1 -1
  46. package/dist/collection/components/sd-card/sd-card.css +1 -0
  47. package/dist/collection/components/sd-card/sd-card.js +1 -1
  48. package/dist/collection/components/sd-checkbox/sd-checkbox.js +16 -16
  49. package/dist/collection/components/sd-checkbox/sd-checkbox.js.map +1 -1
  50. package/dist/collection/components/sd-date-box/sd-date-box.css +1 -0
  51. package/dist/collection/components/sd-date-box/sd-date-box.js +8 -8
  52. package/dist/collection/components/sd-date-box/sd-date-box.js.map +1 -1
  53. package/dist/collection/components/sd-date-picker/sd-date-picker.js +5 -5
  54. package/dist/collection/components/sd-date-picker/sd-date-picker.js.map +1 -1
  55. package/dist/collection/components/sd-date-range-picker/sd-date-range-picker.css +9 -6
  56. package/dist/collection/components/sd-date-range-picker/sd-date-range-picker.js +8 -8
  57. package/dist/collection/components/sd-date-range-picker/sd-date-range-picker.js.map +1 -1
  58. package/dist/collection/components/sd-field/sd-field.css +100 -0
  59. package/dist/collection/components/sd-field/sd-field.js +472 -0
  60. package/dist/collection/components/sd-field/sd-field.js.map +1 -0
  61. package/dist/collection/components/sd-file-picker/sd-file-picker.css +6 -0
  62. package/dist/collection/components/sd-file-picker/sd-file-picker.js +8 -8
  63. package/dist/collection/components/sd-file-picker/sd-file-picker.js.map +1 -1
  64. package/dist/collection/components/sd-floating-portal/sd-floating-portal.css +103 -0
  65. package/dist/collection/components/{sd-tooltip-portal/sd-tooltip-portal.js → sd-floating-portal/sd-floating-portal.js} +18 -9
  66. package/dist/collection/components/sd-floating-portal/sd-floating-portal.js.map +1 -0
  67. package/dist/collection/components/sd-form/sd-form.js +200 -0
  68. package/dist/collection/components/sd-form/sd-form.js.map +1 -0
  69. package/dist/collection/components/sd-guide/sd-guide.css +3 -2
  70. package/dist/collection/components/sd-guide/sd-guide.js +7 -8
  71. package/dist/collection/components/sd-guide/sd-guide.js.map +1 -1
  72. package/dist/collection/components/sd-icon/sd-icon.js +1 -1
  73. package/dist/collection/components/sd-input/sd-input.css +43 -100
  74. package/dist/collection/components/sd-input/sd-input.js +285 -114
  75. package/dist/collection/components/sd-input/sd-input.js.map +1 -1
  76. package/dist/collection/components/sd-loading-spinner/sd-loading-spinner.js +1 -1
  77. package/dist/collection/components/sd-modal-card/sd-modal-card.css +1 -0
  78. package/dist/collection/components/sd-modal-card/sd-modal-card.js +5 -5
  79. package/dist/collection/components/sd-modal-card/sd-modal-card.js.map +1 -1
  80. package/dist/collection/components/sd-number-input/sd-number-input.js +18 -84
  81. package/dist/collection/components/sd-number-input/sd-number-input.js.map +1 -1
  82. package/dist/collection/components/sd-pagination/sd-pagination.js +4 -3
  83. package/dist/collection/components/sd-pagination/sd-pagination.js.map +1 -1
  84. package/dist/collection/components/sd-popover/sd-popover.css +2 -2
  85. package/dist/collection/components/sd-popover/sd-popover.js +4 -5
  86. package/dist/collection/components/sd-popover/sd-popover.js.map +1 -1
  87. package/dist/collection/components/sd-portal/sd-portal.js +4 -4
  88. package/dist/collection/components/sd-portal/sd-portal.js.map +1 -1
  89. package/dist/collection/components/sd-progress/sd-progress.js +2 -2
  90. package/dist/collection/components/sd-radio-button-group/sd-radio-button-group.js +9 -30
  91. package/dist/collection/components/sd-radio-button-group/sd-radio-button-group.js.map +1 -1
  92. package/dist/collection/components/sd-radio-group/sd-radio-group.js +5 -5
  93. package/dist/collection/components/sd-radio-group/sd-radio-group.js.map +1 -1
  94. package/dist/collection/components/sd-select/sd-select-dropdown/sd-select-dropdown.css +52 -0
  95. package/dist/collection/components/sd-select/sd-select-dropdown/sd-select-dropdown.js +441 -0
  96. package/dist/collection/components/sd-select/sd-select-dropdown/sd-select-dropdown.js.map +1 -0
  97. package/dist/collection/components/sd-select/sd-select-option/sd-select-option.js +4 -4
  98. package/dist/collection/components/sd-select/sd-select-option/sd-select-option.js.map +1 -1
  99. package/dist/collection/components/sd-select/sd-select-search-input/sd-select-search-input.css +11 -3
  100. package/dist/collection/components/sd-select/sd-select-search-input/sd-select-search-input.js +15 -15
  101. package/dist/collection/components/sd-select/sd-select-search-input/sd-select-search-input.js.map +1 -1
  102. package/dist/collection/components/sd-select/sd-select.css +9 -97
  103. package/dist/collection/components/sd-select/sd-select.js +320 -219
  104. package/dist/collection/components/sd-select/sd-select.js.map +1 -1
  105. package/dist/collection/components/sd-select-multiple/sd-select-multiple.css +16 -102
  106. package/dist/collection/components/sd-select-multiple/sd-select-multiple.js +328 -179
  107. package/dist/collection/components/sd-select-multiple/sd-select-multiple.js.map +1 -1
  108. package/dist/collection/components/sd-select-multiple-group/sd-select-multiple-group.css +8 -45
  109. package/dist/collection/components/sd-select-multiple-group/sd-select-multiple-group.js +265 -47
  110. package/dist/collection/components/sd-select-multiple-group/sd-select-multiple-group.js.map +1 -1
  111. package/dist/collection/components/sd-select-multiple-group/sd-select-option-group/sd-select-option-group.js +3 -3
  112. package/dist/collection/components/sd-select-multiple-group/sd-select-option-group/sd-select-option-group.js.map +1 -1
  113. package/dist/collection/components/sd-table/sd-table.css +121 -30
  114. package/dist/collection/components/sd-table/sd-table.js +629 -92
  115. package/dist/collection/components/sd-table/sd-table.js.map +1 -1
  116. package/dist/collection/components/sd-tabs/sd-tabs.css +10 -7
  117. package/dist/collection/components/sd-tabs/sd-tabs.js +10 -17
  118. package/dist/collection/components/sd-tabs/sd-tabs.js.map +1 -1
  119. package/dist/collection/components/sd-tag/sd-tag.js +1 -1
  120. package/dist/collection/components/sd-textarea/sd-textarea.css +66 -0
  121. package/dist/collection/components/sd-textarea/sd-textarea.js +400 -0
  122. package/dist/collection/components/sd-textarea/sd-textarea.js.map +1 -0
  123. package/dist/collection/components/sd-toast-message/sd-toast-message.js +11 -11
  124. package/dist/collection/components/sd-toast-message/sd-toast-message.js.map +1 -1
  125. package/dist/collection/components/sd-toggle/sd-toggle.js +8 -14
  126. package/dist/collection/components/sd-toggle/sd-toggle.js.map +1 -1
  127. package/dist/collection/components/sd-toggle-button/sd-toggle-button.js +5 -5
  128. package/dist/collection/components/sd-toggle-button/sd-toggle-button.js.map +1 -1
  129. package/dist/collection/components/sd-tooltip/sd-tooltip.css +6 -65
  130. package/dist/collection/components/sd-tooltip/sd-tooltip.js +12 -29
  131. package/dist/collection/components/sd-tooltip/sd-tooltip.js.map +1 -1
  132. package/dist/collection/types/select.js.map +1 -1
  133. package/dist/components/index.js +1 -1
  134. package/dist/components/p-7xekTQRB.js +104 -0
  135. package/dist/components/p-7xekTQRB.js.map +1 -0
  136. package/dist/components/{p-BDkKpeVz.js → p-BKSlQGJv.js} +3 -3
  137. package/dist/components/{p-BDkKpeVz.js.map → p-BKSlQGJv.js.map} +1 -1
  138. package/dist/components/{p-C5U6Otnl.js → p-CVMprLsE.js} +17 -15
  139. package/dist/components/p-CVMprLsE.js.map +1 -0
  140. package/dist/components/p-CdGD6AqM.js +92 -0
  141. package/dist/components/p-CdGD6AqM.js.map +1 -0
  142. package/dist/components/p-CpRkV7pg.js +201 -0
  143. package/dist/components/p-CpRkV7pg.js.map +1 -0
  144. package/dist/components/p-D2movWkD.js +289 -0
  145. package/dist/components/p-D2movWkD.js.map +1 -0
  146. package/dist/components/p-D54IEoI6.js +238 -0
  147. package/dist/components/p-D54IEoI6.js.map +1 -0
  148. package/dist/components/{p-B8yBkdjE.js → p-DbebUQwg.js} +7 -7
  149. package/dist/components/{p-B8yBkdjE.js.map → p-DbebUQwg.js.map} +1 -1
  150. package/dist/components/{p-BYf-ybt2.js → p-DcGvp3RM.js} +5 -5
  151. package/dist/components/p-DcGvp3RM.js.map +1 -0
  152. package/dist/components/{p-CfivfPAO.js → p-DdKGhMHk.js} +5 -5
  153. package/dist/components/{p-CfivfPAO.js.map → p-DdKGhMHk.js.map} +1 -1
  154. package/dist/components/{p-BxPT3VKO.js → p-DlJtPR_C.js} +12 -12
  155. package/dist/components/p-DlJtPR_C.js.map +1 -0
  156. package/dist/components/{p-BHHbLFXg.js → p-DnQF6htq.js} +5 -5
  157. package/dist/components/{p-BHHbLFXg.js.map → p-DnQF6htq.js.map} +1 -1
  158. package/dist/components/{p-BA38jFi5.js → p-DssRJcAn.js} +4 -4
  159. package/dist/components/{p-BA38jFi5.js.map → p-DssRJcAn.js.map} +1 -1
  160. package/dist/components/{p-B3H_uLbl.js → p-Dt-KAeBx.js} +3 -3
  161. package/dist/components/{p-B3H_uLbl.js.map → p-Dt-KAeBx.js.map} +1 -1
  162. package/dist/components/{p-BREduhZA.js → p-DxSmO6Tr.js} +8 -7
  163. package/dist/components/p-DxSmO6Tr.js.map +1 -0
  164. package/dist/components/{p-O3tgQfvT.js → p-JF61vPAh.js} +9 -9
  165. package/dist/components/p-JF61vPAh.js.map +1 -0
  166. package/dist/components/p-RhBqdixM.js +102 -0
  167. package/dist/components/p-RhBqdixM.js.map +1 -0
  168. package/dist/components/{p-Bj4u0G5b.js → p-UZEmuyIR.js} +19 -19
  169. package/dist/components/p-UZEmuyIR.js.map +1 -0
  170. package/dist/components/{p-CQBrru3e.js → p-YLoygqPr.js} +3 -3
  171. package/dist/components/p-YLoygqPr.js.map +1 -0
  172. package/dist/components/p-s4Mg_xSz.js +260 -0
  173. package/dist/components/p-s4Mg_xSz.js.map +1 -0
  174. package/dist/components/{p-w5tohH2H.js → p-zvZtN3nR.js} +8 -8
  175. package/dist/components/{p-w5tohH2H.js.map → p-zvZtN3nR.js.map} +1 -1
  176. package/dist/components/sd-badge.js +5 -5
  177. package/dist/components/sd-badge.js.map +1 -1
  178. package/dist/components/sd-button.js +1 -1
  179. package/dist/components/sd-card.js +3 -3
  180. package/dist/components/sd-card.js.map +1 -1
  181. package/dist/components/sd-checkbox.js +1 -1
  182. package/dist/components/sd-date-box.js +1 -1
  183. package/dist/components/sd-date-picker.js +37 -13
  184. package/dist/components/sd-date-picker.js.map +1 -1
  185. package/dist/components/sd-date-range-picker.js +41 -17
  186. package/dist/components/sd-date-range-picker.js.map +1 -1
  187. package/dist/components/{sd-td.d.ts → sd-field.d.ts} +4 -4
  188. package/dist/components/sd-field.js +9 -0
  189. package/dist/components/sd-field.js.map +1 -0
  190. package/dist/components/sd-file-picker.js +10 -10
  191. package/dist/components/sd-file-picker.js.map +1 -1
  192. package/dist/components/{sd-table-backup.d.ts → sd-floating-portal.d.ts} +4 -4
  193. package/dist/components/sd-floating-portal.js +9 -0
  194. package/dist/components/sd-floating-portal.js.map +1 -0
  195. package/dist/components/{sd-th.d.ts → sd-form.d.ts} +4 -4
  196. package/dist/components/sd-form.js +99 -0
  197. package/dist/components/sd-form.js.map +1 -0
  198. package/dist/components/sd-guide.js +12 -13
  199. package/dist/components/sd-guide.js.map +1 -1
  200. package/dist/components/sd-icon.js +1 -1
  201. package/dist/components/sd-input.js +1 -1
  202. package/dist/components/sd-loading-spinner.js +1 -1
  203. package/dist/components/sd-modal-card.js +10 -10
  204. package/dist/components/sd-modal-card.js.map +1 -1
  205. package/dist/components/sd-number-input.js +19 -43
  206. package/dist/components/sd-number-input.js.map +1 -1
  207. package/dist/components/sd-pagination.js +1 -1
  208. package/dist/components/sd-popover.js +14 -15
  209. package/dist/components/sd-popover.js.map +1 -1
  210. package/dist/components/sd-portal.js +1 -1
  211. package/dist/components/sd-progress.js +3 -3
  212. package/dist/components/sd-radio-button-group.js +10 -26
  213. package/dist/components/sd-radio-button-group.js.map +1 -1
  214. package/dist/components/sd-radio-group.js +5 -5
  215. package/dist/components/sd-radio-group.js.map +1 -1
  216. package/dist/components/{sd-tbody.d.ts → sd-select-dropdown.d.ts} +4 -4
  217. package/dist/components/sd-select-dropdown.js +9 -0
  218. package/dist/components/sd-select-dropdown.js.map +1 -0
  219. package/dist/components/sd-select-multiple-group.js +97 -40
  220. package/dist/components/sd-select-multiple-group.js.map +1 -1
  221. package/dist/components/sd-select-multiple.js +133 -168
  222. package/dist/components/sd-select-multiple.js.map +1 -1
  223. package/dist/components/sd-select-option-group.js +1 -1
  224. package/dist/components/sd-select-option.js +1 -1
  225. package/dist/components/sd-select-search-input.js +1 -1
  226. package/dist/components/sd-select.js +1 -1
  227. package/dist/components/sd-table.js +555 -113
  228. package/dist/components/sd-table.js.map +1 -1
  229. package/dist/components/sd-tabs.js +13 -16
  230. package/dist/components/sd-tabs.js.map +1 -1
  231. package/dist/components/sd-tag.js +1 -1
  232. package/dist/components/{sd-tr.d.ts → sd-textarea.d.ts} +4 -4
  233. package/dist/components/sd-textarea.js +145 -0
  234. package/dist/components/sd-textarea.js.map +1 -0
  235. package/dist/components/sd-toast-message.js +14 -14
  236. package/dist/components/sd-toast-message.js.map +1 -1
  237. package/dist/components/sd-toggle-button.js +5 -5
  238. package/dist/components/sd-toggle-button.js.map +1 -1
  239. package/dist/components/sd-toggle.js +9 -11
  240. package/dist/components/sd-toggle.js.map +1 -1
  241. package/dist/components/sd-tooltip.js +1 -1
  242. package/dist/design-system/design-system.css +1 -1
  243. package/dist/design-system/design-system.esm.js +1 -1
  244. package/dist/design-system/p-02e23509.entry.js +2 -0
  245. package/dist/design-system/p-02e23509.entry.js.map +1 -0
  246. package/dist/design-system/p-0a2f733d.entry.js +2 -0
  247. package/dist/design-system/p-0a2f733d.entry.js.map +1 -0
  248. package/dist/design-system/p-0d3f019d.entry.js +2 -0
  249. package/dist/design-system/p-0d3f019d.entry.js.map +1 -0
  250. package/dist/design-system/p-15dd1289.entry.js +2 -0
  251. package/dist/design-system/p-15dd1289.entry.js.map +1 -0
  252. package/dist/design-system/p-216c6543.entry.js +2 -0
  253. package/dist/design-system/p-216c6543.entry.js.map +1 -0
  254. package/dist/design-system/p-2400d67b.entry.js +2 -0
  255. package/dist/design-system/p-2400d67b.entry.js.map +1 -0
  256. package/dist/design-system/p-282f4087.entry.js +2 -0
  257. package/dist/design-system/{p-ddfe63b8.entry.js.map → p-282f4087.entry.js.map} +1 -1
  258. package/dist/design-system/{p-b5720c60.entry.js → p-388d5b9f.entry.js} +2 -2
  259. package/dist/design-system/p-4d7bb5b6.entry.js +2 -0
  260. package/dist/design-system/p-4d7bb5b6.entry.js.map +1 -0
  261. package/dist/design-system/p-53972259.entry.js +2 -0
  262. package/dist/design-system/p-53972259.entry.js.map +1 -0
  263. package/dist/design-system/p-6277b220.entry.js +2 -0
  264. package/dist/design-system/p-6277b220.entry.js.map +1 -0
  265. package/dist/design-system/p-652c4d37.entry.js +2 -0
  266. package/dist/design-system/p-652c4d37.entry.js.map +1 -0
  267. package/dist/design-system/p-661c4553.entry.js +2 -0
  268. package/dist/design-system/p-661c4553.entry.js.map +1 -0
  269. package/dist/design-system/p-686958c5.entry.js +2 -0
  270. package/dist/design-system/p-686958c5.entry.js.map +1 -0
  271. package/dist/design-system/p-811c5aa4.entry.js +2 -0
  272. package/dist/design-system/p-811c5aa4.entry.js.map +1 -0
  273. package/dist/design-system/p-827ca975.entry.js +2 -0
  274. package/dist/design-system/p-827ca975.entry.js.map +1 -0
  275. package/dist/design-system/p-8df72aa2.entry.js +2 -0
  276. package/dist/design-system/p-8df72aa2.entry.js.map +1 -0
  277. package/dist/design-system/p-9d2459ed.entry.js +2 -0
  278. package/dist/design-system/p-9d2459ed.entry.js.map +1 -0
  279. package/dist/design-system/p-BShXSO5x.js +2 -0
  280. package/dist/design-system/p-BShXSO5x.js.map +1 -0
  281. package/dist/design-system/{p-7X2nzJWz.js → p-C3qNZ7Qh.js} +3 -3
  282. package/dist/design-system/p-C3qNZ7Qh.js.map +1 -0
  283. package/dist/design-system/{p-CdbtuKYR.js → p-DPxE68eG.js} +2 -2
  284. package/dist/design-system/{p-CdbtuKYR.js.map → p-DPxE68eG.js.map} +1 -1
  285. package/dist/design-system/{p-BYf-ybt2.js → p-DcGvp3RM.js} +2 -2
  286. package/dist/design-system/{p-BYf-ybt2.js.map → p-DcGvp3RM.js.map} +1 -1
  287. package/dist/design-system/p-a7d4c6bd.entry.js +2 -0
  288. package/dist/design-system/p-a7d4c6bd.entry.js.map +1 -0
  289. package/dist/design-system/p-ac29c52c.entry.js +2 -0
  290. package/dist/design-system/p-ac29c52c.entry.js.map +1 -0
  291. package/dist/design-system/{p-7a424f6b.entry.js → p-b0277422.entry.js} +2 -2
  292. package/dist/design-system/p-b0277422.entry.js.map +1 -0
  293. package/dist/design-system/p-c25c4bd6.entry.js +2 -0
  294. package/dist/design-system/p-c25c4bd6.entry.js.map +1 -0
  295. package/dist/design-system/p-c3061828.entry.js +2 -0
  296. package/dist/design-system/p-c3061828.entry.js.map +1 -0
  297. package/dist/design-system/p-cde56c79.entry.js +2 -0
  298. package/dist/design-system/{p-5576f0f0.entry.js.map → p-cde56c79.entry.js.map} +1 -1
  299. package/dist/design-system/p-d77422e4.entry.js +2 -0
  300. package/dist/design-system/p-d77422e4.entry.js.map +1 -0
  301. package/dist/design-system/p-dc410414.entry.js +2 -0
  302. package/dist/design-system/p-dc410414.entry.js.map +1 -0
  303. package/dist/design-system/p-f254b09a.entry.js +2 -0
  304. package/dist/design-system/p-f254b09a.entry.js.map +1 -0
  305. package/dist/design-system/p-f3287206.entry.js +2 -0
  306. package/dist/design-system/p-f3287206.entry.js.map +1 -0
  307. package/dist/esm/{select-keyboard-navigation-C2JaR3A6.js → base-dropdown-event-BShXSO5x.js} +26 -26
  308. package/dist/esm/base-dropdown-event-BShXSO5x.js.map +1 -0
  309. package/dist/esm/design-system.js +3 -3
  310. package/dist/esm/{index-7X2nzJWz.js → index-C3qNZ7Qh.js} +3 -3
  311. package/dist/esm/index-C3qNZ7Qh.js.map +1 -0
  312. package/dist/esm/loader.js +3 -3
  313. package/dist/esm/{resolveColor-BYf-ybt2.js → resolveColor-DcGvp3RM.js} +5 -5
  314. package/dist/{cjs/resolveColor-DxvExwgo.js.map → esm/resolveColor-DcGvp3RM.js.map} +1 -1
  315. package/dist/esm/sd-badge.entry.js +4 -4
  316. package/dist/esm/sd-badge.entry.js.map +1 -1
  317. package/dist/esm/{sd-button_24.entry.js → sd-button_6.entry.js} +291 -2823
  318. package/dist/esm/sd-card.entry.js +3 -3
  319. package/dist/esm/sd-card.entry.js.map +1 -1
  320. package/dist/esm/sd-checkbox.entry.js +87 -0
  321. package/dist/esm/sd-checkbox.entry.js.map +1 -0
  322. package/dist/esm/sd-date-box.entry.js +10 -10
  323. package/dist/esm/sd-date-box.entry.js.map +1 -1
  324. package/dist/esm/sd-date-picker.entry.js +5 -5
  325. package/dist/esm/sd-date-picker.entry.js.map +1 -1
  326. package/dist/esm/sd-date-range-picker.entry.js +8 -8
  327. package/dist/esm/sd-date-range-picker.entry.js.map +1 -1
  328. package/dist/esm/sd-field_3.entry.js +418 -0
  329. package/dist/esm/sd-file-picker.entry.js +119 -0
  330. package/dist/esm/sd-file-picker.entry.js.map +1 -0
  331. package/dist/esm/sd-form.entry.js +72 -0
  332. package/dist/esm/sd-form.entry.js.map +1 -0
  333. package/dist/esm/sd-guide.entry.js +79 -0
  334. package/dist/esm/sd-guide.entry.js.map +1 -0
  335. package/dist/esm/sd-loading-spinner_2.entry.js +192 -0
  336. package/dist/esm/sd-modal-card.entry.js +8 -8
  337. package/dist/esm/sd-modal-card.entry.js.map +1 -1
  338. package/dist/esm/sd-number-input.entry.js +259 -0
  339. package/dist/esm/sd-number-input.entry.js.map +1 -0
  340. package/dist/esm/sd-popover.entry.js +7 -7
  341. package/dist/esm/sd-popover.entry.js.map +1 -1
  342. package/dist/esm/sd-progress.entry.js +3 -3
  343. package/dist/esm/sd-radio-button-group.entry.js +8 -21
  344. package/dist/esm/sd-radio-button-group.entry.js.map +1 -1
  345. package/dist/esm/sd-radio-group.entry.js +69 -0
  346. package/dist/esm/sd-radio-group.entry.js.map +1 -0
  347. package/dist/esm/sd-select-dropdown_3.entry.js +262 -0
  348. package/dist/esm/sd-select-multiple-group.entry.js +444 -0
  349. package/dist/esm/sd-select-multiple-group.entry.js.map +1 -0
  350. package/dist/esm/sd-select-multiple.entry.js +72 -150
  351. package/dist/esm/sd-select-multiple.entry.js.map +1 -1
  352. package/dist/esm/sd-select-option-group.entry.js +67 -0
  353. package/dist/esm/sd-select-option-group.entry.js.map +1 -0
  354. package/dist/esm/sd-table.entry.js +515 -85
  355. package/dist/esm/sd-table.entry.js.map +1 -1
  356. package/dist/esm/sd-tabs.entry.js +64 -0
  357. package/dist/esm/sd-tabs.entry.js.map +1 -0
  358. package/dist/esm/sd-tag.entry.js +55 -0
  359. package/dist/esm/sd-tag.entry.js.map +1 -0
  360. package/dist/esm/sd-toast-message.entry.js +59 -0
  361. package/dist/esm/sd-toast-message.entry.js.map +1 -0
  362. package/dist/esm/sd-toggle-button.entry.js +48 -0
  363. package/dist/esm/sd-toggle-button.entry.js.map +1 -0
  364. package/dist/esm/sd-toggle.entry.js +44 -0
  365. package/dist/esm/sd-toggle.entry.js.map +1 -0
  366. package/dist/esm/{tooltipArrow-DFRZWz6D.js → tooltipArrow-Ck_14rXC.js} +3 -3
  367. package/dist/esm/{tooltipArrow-DFRZWz6D.js.map → tooltipArrow-Ck_14rXC.js.map} +1 -1
  368. package/dist/types/components/sd-button/sd-button.d.ts +0 -3
  369. package/dist/types/components/sd-checkbox/sd-checkbox.d.ts +2 -2
  370. package/dist/types/components/sd-date-box/sd-date-box.d.ts +2 -2
  371. package/dist/types/components/sd-date-picker/sd-date-picker.d.ts +1 -1
  372. package/dist/types/components/sd-date-range-picker/sd-date-range-picker.d.ts +1 -1
  373. package/dist/types/components/sd-field/sd-field.d.ts +34 -0
  374. package/dist/types/components/sd-file-picker/sd-file-picker.d.ts +1 -1
  375. package/dist/types/components/{sd-tooltip-portal/sd-tooltip-portal.d.ts → sd-floating-portal/sd-floating-portal.d.ts} +2 -2
  376. package/dist/types/components/sd-form/sd-form.d.ts +23 -0
  377. package/dist/types/components/sd-input/sd-input.d.ts +23 -14
  378. package/dist/types/components/sd-modal-card/sd-modal-card.d.ts +2 -2
  379. package/dist/types/components/sd-number-input/sd-number-input.d.ts +4 -14
  380. package/dist/types/components/sd-portal/sd-portal.d.ts +1 -1
  381. package/dist/types/components/sd-radio-button-group/sd-radio-button-group.d.ts +2 -4
  382. package/dist/types/components/sd-radio-group/sd-radio-group.d.ts +1 -1
  383. package/dist/types/components/sd-select/sd-select-dropdown/sd-select-dropdown.d.ts +41 -0
  384. package/dist/types/components/sd-select/sd-select-option/sd-select-option.d.ts +1 -1
  385. package/dist/types/components/sd-select/sd-select-search-input/sd-select-search-input.d.ts +4 -4
  386. package/dist/types/components/sd-select/sd-select.d.ts +28 -21
  387. package/dist/types/components/sd-select-multiple/sd-select-multiple.d.ts +26 -20
  388. package/dist/types/components/sd-select-multiple-group/sd-select-multiple-group.d.ts +19 -4
  389. package/dist/types/components/sd-table/sd-table.d.ts +62 -3
  390. package/dist/types/components/sd-tabs/sd-tabs.d.ts +1 -2
  391. package/dist/types/components/sd-textarea/sd-textarea.d.ts +32 -0
  392. package/dist/types/components/sd-toast-message/sd-toast-message.d.ts +3 -3
  393. package/dist/types/components/sd-toggle/sd-toggle.d.ts +1 -2
  394. package/dist/types/components/sd-toggle-button/sd-toggle-button.d.ts +1 -1
  395. package/dist/types/components/sd-tooltip/sd-tooltip.d.ts +14 -2
  396. package/dist/types/components.d.ts +703 -397
  397. package/dist/types/types/form.d.ts +1 -0
  398. package/dist/types/types/select.d.ts +1 -1
  399. package/hydrate/index.js +1397 -1325
  400. package/hydrate/index.mjs +1397 -1325
  401. package/package.json +4 -3
  402. package/dist/cjs/index-B7tkxTye.js.map +0 -1
  403. package/dist/cjs/sd-tbody_3.cjs.entry.js +0 -44
  404. package/dist/cjs/sd-td.cjs.entry.js +0 -26
  405. package/dist/cjs/select-keyboard-navigation-6fO_V4En.js.map +0 -1
  406. package/dist/collection/components/sd-table/sd-tbody/sd-tbody.css +0 -3
  407. package/dist/collection/components/sd-table/sd-tbody/sd-tbody.js +0 -18
  408. package/dist/collection/components/sd-table/sd-tbody/sd-tbody.js.map +0 -1
  409. package/dist/collection/components/sd-table/sd-td/sd-td.css +0 -9
  410. package/dist/collection/components/sd-table/sd-td/sd-td.js +0 -111
  411. package/dist/collection/components/sd-table/sd-td/sd-td.js.map +0 -1
  412. package/dist/collection/components/sd-table/sd-th/sd-th.css +0 -8
  413. package/dist/collection/components/sd-table/sd-th/sd-th.js +0 -18
  414. package/dist/collection/components/sd-table/sd-th/sd-th.js.map +0 -1
  415. package/dist/collection/components/sd-table/sd-tr/sd-tr.css +0 -3
  416. package/dist/collection/components/sd-table/sd-tr/sd-tr.js +0 -18
  417. package/dist/collection/components/sd-table/sd-tr/sd-tr.js.map +0 -1
  418. package/dist/collection/components/sd-table-backup/sd-table-backup.css +0 -309
  419. package/dist/collection/components/sd-table-backup/sd-table-backup.js +0 -1219
  420. package/dist/collection/components/sd-table-backup/sd-table-backup.js.map +0 -1
  421. package/dist/collection/components/sd-tooltip-portal/sd-tooltip-portal.js.map +0 -1
  422. package/dist/components/p-6qJVnQg4.js +0 -34
  423. package/dist/components/p-6qJVnQg4.js.map +0 -1
  424. package/dist/components/p-BREduhZA.js.map +0 -1
  425. package/dist/components/p-BYf-ybt2.js.map +0 -1
  426. package/dist/components/p-Bj4u0G5b.js.map +0 -1
  427. package/dist/components/p-BxPT3VKO.js.map +0 -1
  428. package/dist/components/p-C4kdHNdl.js +0 -175
  429. package/dist/components/p-C4kdHNdl.js.map +0 -1
  430. package/dist/components/p-C5U6Otnl.js.map +0 -1
  431. package/dist/components/p-CNrsaSqW.js +0 -34
  432. package/dist/components/p-CNrsaSqW.js.map +0 -1
  433. package/dist/components/p-CQBrru3e.js.map +0 -1
  434. package/dist/components/p-D8KGixEs.js +0 -326
  435. package/dist/components/p-D8KGixEs.js.map +0 -1
  436. package/dist/components/p-DLrb7Zq3.js +0 -102
  437. package/dist/components/p-DLrb7Zq3.js.map +0 -1
  438. package/dist/components/p-K42WRBPA.js +0 -121
  439. package/dist/components/p-K42WRBPA.js.map +0 -1
  440. package/dist/components/p-O3tgQfvT.js.map +0 -1
  441. package/dist/components/p-QpwY2yqY.js +0 -78
  442. package/dist/components/p-QpwY2yqY.js.map +0 -1
  443. package/dist/components/p-xme-KFvK.js +0 -34
  444. package/dist/components/p-xme-KFvK.js.map +0 -1
  445. package/dist/components/sd-table-backup.js +0 -802
  446. package/dist/components/sd-table-backup.js.map +0 -1
  447. package/dist/components/sd-tbody.js +0 -9
  448. package/dist/components/sd-tbody.js.map +0 -1
  449. package/dist/components/sd-td.js +0 -50
  450. package/dist/components/sd-td.js.map +0 -1
  451. package/dist/components/sd-th.js +0 -9
  452. package/dist/components/sd-th.js.map +0 -1
  453. package/dist/components/sd-tooltip-portal.d.ts +0 -11
  454. package/dist/components/sd-tooltip-portal.js +0 -9
  455. package/dist/components/sd-tooltip-portal.js.map +0 -1
  456. package/dist/components/sd-tr.js +0 -9
  457. package/dist/components/sd-tr.js.map +0 -1
  458. package/dist/design-system/p-0893dbd0.entry.js +0 -2
  459. package/dist/design-system/p-0893dbd0.entry.js.map +0 -1
  460. package/dist/design-system/p-2633690f.entry.js +0 -2
  461. package/dist/design-system/p-2633690f.entry.js.map +0 -1
  462. package/dist/design-system/p-27985b84.entry.js +0 -2
  463. package/dist/design-system/p-27985b84.entry.js.map +0 -1
  464. package/dist/design-system/p-5576f0f0.entry.js +0 -2
  465. package/dist/design-system/p-7X2nzJWz.js.map +0 -1
  466. package/dist/design-system/p-7a424f6b.entry.js.map +0 -1
  467. package/dist/design-system/p-7ca988ab.entry.js +0 -2
  468. package/dist/design-system/p-7ca988ab.entry.js.map +0 -1
  469. package/dist/design-system/p-9ade8cd7.entry.js +0 -2
  470. package/dist/design-system/p-9ade8cd7.entry.js.map +0 -1
  471. package/dist/design-system/p-C2JaR3A6.js +0 -2
  472. package/dist/design-system/p-C2JaR3A6.js.map +0 -1
  473. package/dist/design-system/p-a7bdb6ba.entry.js +0 -2
  474. package/dist/design-system/p-a7bdb6ba.entry.js.map +0 -1
  475. package/dist/design-system/p-b1b828e6.entry.js +0 -2
  476. package/dist/design-system/p-b1b828e6.entry.js.map +0 -1
  477. package/dist/design-system/p-bdd9afaf.entry.js +0 -2
  478. package/dist/design-system/p-bdd9afaf.entry.js.map +0 -1
  479. package/dist/design-system/p-ddfe63b8.entry.js +0 -2
  480. package/dist/design-system/p-de826a92.entry.js +0 -2
  481. package/dist/design-system/p-de826a92.entry.js.map +0 -1
  482. package/dist/design-system/p-e180c69c.entry.js +0 -2
  483. package/dist/design-system/p-e180c69c.entry.js.map +0 -1
  484. package/dist/esm/index-7X2nzJWz.js.map +0 -1
  485. package/dist/esm/sd-tbody_3.entry.js +0 -40
  486. package/dist/esm/sd-td.entry.js +0 -24
  487. package/dist/esm/sd-td.entry.js.map +0 -1
  488. package/dist/esm/select-keyboard-navigation-C2JaR3A6.js.map +0 -1
  489. package/dist/types/components/sd-table/sd-tbody/sd-tbody.d.ts +0 -3
  490. package/dist/types/components/sd-table/sd-td/sd-td.d.ts +0 -7
  491. package/dist/types/components/sd-table/sd-th/sd-th.d.ts +0 -3
  492. package/dist/types/components/sd-table/sd-tr/sd-tr.d.ts +0 -3
  493. package/dist/types/components/sd-table-backup/sd-table-backup.d.ts +0 -135
  494. /package/dist/design-system/{p-b5720c60.entry.js.map → p-388d5b9f.entry.js.map} +0 -0
@@ -1,11 +1,10 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-B7tkxTye.js');
4
- var resolveColor = require('./resolveColor-DxvExwgo.js');
5
- var selectKeyboardNavigation = require('./select-keyboard-navigation-6fO_V4En.js');
6
- var tooltipArrow = require('./tooltipArrow-8I9A3AOE.js');
3
+ var index = require('./index-D_J8ScR5.js');
4
+ var resolveColor = require('./resolveColor-B7Ku3IGq.js');
5
+ var tooltipArrow = require('./tooltipArrow-DU2DB2AD.js');
7
6
 
8
- const sdButtonCss = () => `sd-button{display:inline-block;width:fit-content;height:fit-content}.sd-button{text-decoration:none;cursor:pointer;border-radius:4px;transition:all 0.2s ease-in-out;position:relative;overflow:hidden;white-space:nowrap;-webkit-user-select:none;user-select:none;box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center}.sd-button--xs{padding:0 8px;font-size:12px;font-weight:500;line-height:20px;min-height:24px}.sd-button--sm{padding:0 12px;font-size:12px;font-weight:500;line-height:20px;min-height:28px}.sd-button--md{padding:0 20px;font-size:16px;font-weight:500;line-height:26px;min-height:34px}.sd-button--lg{padding:0 28px;font-size:18px;font-weight:500;line-height:30px;min-height:62px}.sd-button--primary{background-color:var(--button-color);color:white;transition:filter 0.2s ease}.sd-button--primary::before{content:"";position:absolute;inset:0;background:#000000;opacity:0;transition:opacity 0.2s ease;z-index:0}.sd-button--primary:hover:not(.sd-button--disabled):not(.sd-button--loading)::before{opacity:0.25}.sd-button--outline{background:white;border:1px solid var(--button-color);color:var(--button-color)}.sd-button--outline::before{content:"";position:absolute;inset:0;background:var(--button-color);opacity:0;transition:opacity 0.2s ease;z-index:0}.sd-button--outline:hover:not(.sd-button--disabled):not(.sd-button--loading)::before{opacity:0.15}.sd-button--outline .sd-button__content{position:relative;z-index:1}.sd-button--ghost{background-color:transparent;color:var(--button-color);border-color:transparent}.sd-button--ghost::before{content:"";position:absolute;inset:0;background:var(--button-color);opacity:0;transition:opacity 0.2s ease;z-index:0}.sd-button--ghost:hover:not(.sd-button--disabled):not(.sd-button--loading)::before{opacity:0.15}.sd-button--ghost .sd-button__content{position:relative;z-index:1}.sd-button--disabled{border:1px solid #cccccc;background:#e1e1e1;color:#888888;cursor:not-allowed !important}.sd-button--icon-only{padding:0;width:fit-content;height:fit-content;aspect-ratio:1/1}.sd-button--no-hover:hover::before{opacity:0 !important}.sd-button .sd-button__content{display:inline-flex;align-items:center;justify-content:center;gap:4px;z-index:1;font-weight:500}`;
7
+ const sdButtonCss = () => `sd-button{display:inline-flex;width:fit-content;height:fit-content}.sd-button{text-decoration:none;cursor:pointer;border-radius:4px;transition:all 0.2s ease-in-out;position:relative;overflow:hidden;white-space:nowrap;-webkit-user-select:none;user-select:none;box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;border:none}.sd-button--xs{padding:0 8px;font-size:12px;font-weight:500;line-height:20px;min-height:24px}.sd-button--sm{padding:0 12px;font-size:12px;font-weight:500;line-height:20px;min-height:28px}.sd-button--md{padding:0 20px;font-size:16px;font-weight:500;line-height:26px;min-height:34px}.sd-button--lg{padding:0 28px;font-size:18px;font-weight:500;line-height:30px;min-height:62px}.sd-button--primary{background-color:var(--button-color);color:white;transition:filter 0.2s ease}.sd-button--primary::before{content:"";position:absolute;inset:0;background:#000000;opacity:0;transition:opacity 0.2s ease;z-index:0}.sd-button--primary:hover:not(.sd-button--disabled):not(.sd-button--loading)::before{opacity:0.25}.sd-button--outline{background:white;border:1px solid var(--button-color);color:var(--button-color)}.sd-button--outline::before{content:"";position:absolute;inset:0;background:var(--button-color);opacity:0;transition:opacity 0.2s ease;z-index:0}.sd-button--outline:hover:not(.sd-button--disabled):not(.sd-button--loading)::before{opacity:0.15}.sd-button--outline .sd-button__content{position:relative;z-index:1}.sd-button--ghost{background-color:transparent;color:var(--button-color);border-color:transparent}.sd-button--ghost::before{content:"";position:absolute;inset:0;background:var(--button-color);opacity:0;transition:opacity 0.2s ease;z-index:0}.sd-button--ghost:hover:not(.sd-button--disabled):not(.sd-button--loading)::before{opacity:0.15}.sd-button--ghost .sd-button__content{position:relative;z-index:1}.sd-button--disabled{border:1px solid #cccccc;background:#e1e1e1;color:#888888;cursor:not-allowed !important}.sd-button--icon-only{padding:0;width:fit-content;height:fit-content;aspect-ratio:1/1}.sd-button--no-hover:hover::before{opacity:0 !important}.sd-button .sd-button__content{display:inline-flex;align-items:center;justify-content:center;gap:4px;z-index:1;font-weight:500}`;
9
8
 
10
9
  const ICON_SIZES = {
11
10
  xs: 12,
@@ -16,7 +15,6 @@ const ICON_SIZES = {
16
15
  const SdButton = class {
17
16
  constructor(hostRef) {
18
17
  index.registerInstance(this, hostRef);
19
- this.sdClick = index.createEvent(this, "sdClick");
20
18
  }
21
19
  get el() { return index.getElement(this); }
22
20
  variant = 'primary';
@@ -31,15 +29,6 @@ const SdButton = class {
31
29
  iconRight;
32
30
  noHover = false;
33
31
  class = '';
34
- sdClick;
35
- handleClick = (event) => {
36
- if (this.disabled) {
37
- event.preventDefault();
38
- event.stopPropagation();
39
- return;
40
- }
41
- this.sdClick.emit(event);
42
- };
43
32
  getButtonClasses() {
44
33
  const classes = ['sd-button'];
45
34
  classes.push(`sd-button--${this.variant}`);
@@ -60,283 +49,166 @@ const SdButton = class {
60
49
  const buttonClasses = this.getButtonClasses();
61
50
  // 유틸로 색상 키 -> HEX 매핑 (없으면 원본 그대로)
62
51
  const resolvedColor = resolveColor.resolveColor(this.color);
63
- return (index.h(index.Host, { key: '7ad8b189abbee6a59fee2ba3fc97dee48c5e3058', style: { '--button-color': resolvedColor }, disabled: this.disabled }, index.h("button", { key: 'd335be4ddcbc4f4d9908a1cdf20bfd94bbaff3e3', class: `${buttonClasses} ${this.class}`, type: this.type, disabled: this.disabled, onClick: this.handleClick }, index.h("div", { key: '362c6bd73c38108058ea1cdb16149c1906588cbd', class: "sd-button__content" }, this.icon && (index.h("sd-icon", { key: '85d8ccc677e6cb633a35b2a2a76432ac7f67b807', class: "sd-button__icon sd-button__icon--left", name: this.icon, size: this.iconSize ?? ICON_SIZES[this.size], color: this.iconColor ?? (this.variant === 'primary' ? '#fff' : resolvedColor) })), this.label && index.h("div", { key: 'fa51d7ab94e039ee52c122dc022429253bdca921', class: "sd-button__label" }, this.label), this.iconRight && (index.h("sd-icon", { key: 'b4c0c866b86832146b8f156b68f931df280ec83a', class: "sd-button__icon sd-button__icon--right", name: this.iconRight, size: ICON_SIZES[this.size], color: this.variant === 'primary' ? '#fff' : resolvedColor }))))));
52
+ return (index.h("button", { key: '9b92f98528d06453492eab68bb6137bcaefbf656', class: `${buttonClasses} ${this.class}`, type: this.type, disabled: this.disabled, style: { '--button-color': resolvedColor } }, index.h("div", { key: 'a7dae76ec9112b95c2ee765cb2f9b0b4fe5f705a', class: "sd-button__content" }, this.icon && (index.h("sd-icon", { key: '71784bfcb2d08c77305a70311192dfc2c059ff0a', class: "sd-button__icon sd-button__icon--left", name: this.icon, size: this.iconSize ?? ICON_SIZES[this.size], color: this.iconColor ?? (this.variant === 'primary' ? '#fff' : resolvedColor) })), this.label && index.h("div", { key: 'bc4b7dec430602765e98fa484d397b141686d8e7', class: "sd-button__label" }, this.label), this.iconRight && (index.h("sd-icon", { key: '26744c6ace43cbbfc9758a8fdf0174b49f24cd2c', class: "sd-button__icon sd-button__icon--right", name: this.iconRight, size: ICON_SIZES[this.size], color: this.variant === 'primary' ? '#fff' : resolvedColor })))));
64
53
  }
65
54
  };
66
55
  SdButton.style = sdButtonCss();
67
56
 
68
- const sdCheckboxCss = () => `sd-checkbox{display:block;height:20px;line-height:0}sd-checkbox .sd-checkbox{cursor:pointer;display:inline-flex;align-items:center;gap:8px;height:20px;max-height:20px}sd-checkbox .sd-checkbox>input{display:none}sd-checkbox .sd-checkbox:hover.sd-checkbox--checked .sd-checkbox__bg,sd-checkbox .sd-checkbox:hover.sd-checkbox--indeterminate .sd-checkbox__bg{border-color:#005cc9;background:#005cc9}sd-checkbox .sd-checkbox:hover.sd-checkbox--unchecked .sd-checkbox__bg{border:1px solid #0075ff;background:#d9eaff}sd-checkbox .sd-checkbox:hover.sd-checkbox--disabled .sd-checkbox__bg{border:1px solid transparent;background:#eeeeee}sd-checkbox .sd-checkbox__bg{width:16px;height:16px;border-radius:2px;border:1px solid #888888;box-sizing:border-box;display:inline-flex;justify-content:center;align-items:center;overflow:hidden;line-height:0}sd-checkbox .sd-checkbox__label{font-size:12px;color:#333333;line-height:20px}sd-checkbox .sd-checkbox--checked.sd-checkbox--disabled .sd-checkbox__bg,sd-checkbox .sd-checkbox--indeterminate.sd-checkbox--disabled .sd-checkbox__bg{background:#eeeeee;border:1px solid #cccccc !important}sd-checkbox .sd-checkbox--checked .sd-checkbox__bg,sd-checkbox .sd-checkbox--indeterminate .sd-checkbox__bg{border:1px solid #0075ff;background:#0075ff}sd-checkbox .sd-checkbox--unchecked .sd-checkbox__bg{background:white}sd-checkbox .sd-checkbox--disabled{cursor:not-allowed}sd-checkbox .sd-checkbox--disabled .sd-checkbox__bg{background:#eeeeee;border:1px solid #cccccc !important}`;
57
+ const sdFloatingPortalCss = () => `.sd-floating-menu{width:fit-content;padding:12px 20px;border-radius:4px;font-size:12px;position:relative;box-sizing:border-box;background:#07284a;color:#ffffff}.sd-floating-menu .sd-floating-menu__arrow{color:#07284a}.sd-floating-menu--default{background:#07284a;color:#ffffff}.sd-floating-menu--default .sd-floating-menu__arrow{color:#07284a}.sd-floating-menu--caution{background:#fce6e6;color:#fb4444}.sd-floating-menu--caution .sd-floating-menu__arrow{color:#fce6e6}.sd-floating-menu--notice{background:#ffead7;color:#ff6b00}.sd-floating-menu--notice .sd-floating-menu__arrow{color:#ffead7}.sd-floating-menu--accent{background:#e6f1ff;color:#0075ff}.sd-floating-menu--accent .sd-floating-menu__arrow{color:#e6f1ff}.sd-floating-menu__arrow{position:absolute;display:flex;width:9.6px;height:7.2px}.sd-floating-menu__arrow svg{width:100%;height:100%}.sd-floating-menu__arrow--top{bottom:-7.2px;left:50%;transform:translateX(-50%)}.sd-floating-menu__arrow--bottom{top:-7.2px;left:50%;transform:translateX(-50%) rotate(180deg)}.sd-floating-menu__arrow--left{right:-7.2px;top:50%;transform:translateY(-50%) rotate(-90deg)}.sd-floating-menu__arrow--right{left:-7.2px;top:50%;transform:translateY(-50%) rotate(90deg)}.sd-floating-menu__content{font-size:12px;line-height:20px}.sd-floating-menu__content .sd-floating-menu__title{font-weight:700;margin-bottom:4px}.sd-floating-menu__content .sd-floating-menu__messages{font-weight:500}.sd-floating-menu__content .sd-floating-menu__buttons{margin-top:12px;display:flex;gap:8px;align-items:center}.sd-floating-menu__content .sd-floating-menu__buttons--1{justify-content:flex-end}.sd-floating-menu__content .sd-floating-menu__buttons--2{justify-content:space-between}.sd-floating-menu__close-button{position:absolute;top:16px;right:12px;padding:0;background:none;border:none;cursor:pointer}`;
69
58
 
70
- const SdCheckbox = class {
59
+ const SdFloatingPopover = class {
71
60
  constructor(hostRef) {
72
61
  index.registerInstance(this, hostRef);
73
- this.sdChange = index.createEvent(this, "sdChange");
62
+ this.close = index.createEvent(this, "sdClose");
74
63
  }
75
64
  get el() { return index.getElement(this); }
76
- /** 현재 선택 상태 또는 배열 형태의 값 */
77
- checked;
78
- /** 배열 모드에서의 개별 값 */
79
- val;
80
- /** 비활성화 여부 */
81
- disabled = false;
82
- /** 표시할 라벨 텍스트 */
83
- label = '';
84
- /** 내부 체크 상태 */
85
- isChecked = false;
86
- /** 변경 이벤트 */
87
- sdChange;
88
- componentWillLoad() {
89
- this.updateCheckedState(this.checked);
90
- }
91
- componentWillRender() {
92
- this.updateCheckedState(this.checked);
93
- }
94
- watchValueHandler(newValue) {
95
- this.updateCheckedState(newValue);
96
- }
97
- get checkboxClasses() {
98
- const classes = [
99
- 'sd-checkbox',
100
- `sd-checkbox--${this.isChecked ? 'checked' : this.isChecked === null ? 'indeterminate' : 'unchecked'}`,
101
- ];
102
- if (this.disabled) {
103
- classes.push('sd-checkbox--disabled');
104
- }
105
- return classes.join(' ');
106
- }
107
- updateCheckedState(value) {
108
- if (value === null) {
109
- this.isChecked = null;
110
- }
111
- else if (typeof value === 'boolean') {
112
- this.isChecked = value;
113
- }
114
- else if (Array.isArray(value)) {
115
- this.isChecked = this.val !== undefined && value.includes(this.val);
116
- }
117
- else {
118
- this.isChecked = false;
119
- }
65
+ to = 'body';
66
+ parentRef = null;
67
+ offset = [0, 0];
68
+ zIndex = 9999;
69
+ placement = 'bottom';
70
+ open = false;
71
+ close;
72
+ container;
73
+ wrapper;
74
+ rafId;
75
+ isInsideClick = false;
76
+ resizeObserver;
77
+ mutationObserver;
78
+ static ARROW_SIZE = 11.2;
79
+ componentDidLoad() {
80
+ this.container = this.resolveContainer();
81
+ this.createWrapper();
82
+ this.moveSlotContent();
83
+ // DOM이 완전히 렌더링된 후 위치 계산
84
+ requestAnimationFrame(() => {
85
+ this.updatePosition();
86
+ if (this.wrapper) {
87
+ this.wrapper.style.visibility = 'visible'; // 위치 계산 후 표시
88
+ }
89
+ });
90
+ this.observeParent();
120
91
  }
121
- handleChange = () => {
122
- if (this.disabled)
92
+ componentDidRender() {
93
+ if (!this.wrapper)
123
94
  return;
124
- let newValue;
125
- if (typeof this.checked === 'boolean') {
126
- newValue = !this.checked;
127
- }
128
- else if (Array.isArray(this.checked)) {
129
- if (this.val === undefined) {
130
- console.warn('A "val" property is required when using an array for the "value" property.');
131
- }
132
- const valueSet = new Set(this.checked);
133
- valueSet.has(this.val) ? valueSet.delete(this.val) : valueSet.add(this.val);
134
- newValue = Array.from(valueSet);
95
+ // this.wrapper.style.display = this.open ? 'block' : 'none';
96
+ // if (this.open) this.updatePosition();
97
+ if (this.open) {
98
+ this.wrapper.style.display = 'block';
99
+ // RAF를 사용해서 다음 프레임에 위치 업데이트
100
+ requestAnimationFrame(() => {
101
+ this.updatePosition();
102
+ if (this.wrapper) {
103
+ this.wrapper.style.visibility = 'visible';
104
+ }
105
+ });
135
106
  }
136
107
  else {
137
- newValue = !this.isChecked;
108
+ this.wrapper.style.display = 'none';
109
+ this.wrapper.style.visibility = 'hidden';
138
110
  }
139
- this.checked = newValue;
140
- this.sdChange.emit(newValue);
141
- };
142
- render() {
143
- return (index.h("label", { key: '9d70b760dedd75f6af927111338f488c4fb3c149', "aria-checked": this.isChecked === null ? 'mixed' : this.isChecked.toString(), "aria-disabled": this.disabled.toString(), role: "checkbox", "aria-label": this.label || 'checkbox', class: this.checkboxClasses }, index.h("input", { key: 'd5c09f8ffca898bb1a7f848ba5f5c09b3cc32f57', type: "checkbox", value: this.val, checked: !!this.isChecked, disabled: this.disabled, onChange: this.handleChange, name: this.label || 'checkbox' }), index.h("div", { key: '4e2c090cad23c420f4597194e9dab8b5718f4ec9', class: "sd-checkbox__bg" }, this.isChecked !== false ? (index.h("sd-icon", { name: this.isChecked === true ? 'check' : 'minus', size: 12, color: this.disabled ? '#888888' : 'white' })) : null), this.label && index.h("span", { key: '99e3e1f4f5959f57fd5d7c2f0611a2e02cb41f6a', class: "sd-checkbox__label" }, this.label)));
144
111
  }
145
- static get watchers() { return {
146
- "checked": ["watchValueHandler"]
147
- }; }
148
- };
149
- SdCheckbox.style = sdCheckboxCss();
150
-
151
- const sdFilePickerCss = () => `.sd-file-picker{display:inline-flex;align-items:center;max-width:var(--picker-width, 100%);height:28px;gap:8px;padding:4px 8px;border:1px solid #aaaaaa;border-radius:4px;background-color:#ffffff;cursor:pointer;user-select:none;position:relative;vertical-align:middle}.sd-file-picker__text{flex:1;min-width:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;font-weight:400;font-size:12px;line-height:20px;color:#aaaaaa}.sd-file-picker__text--active{color:#222222}.sd-file-picker__text--placeholder{color:#aaaaaa}.sd-file-picker__icon{flex-shrink:0}.sd-file-picker__clear-icon{flex-shrink:0;cursor:pointer;transition:opacity 0.2s ease}.sd-file-picker__clear-icon:hover{opacity:0.7}.sd-file-picker__input{display:none}.sd-file-picker__tooltip{position:absolute;top:calc(100% - 4px);left:50%;transform:translate(-50%);z-index:1000;white-space:nowrap;padding:8px 12px;background:rgba(0, 0, 0, 0.8);color:white;font-size:12px;line-height:18px;border-radius:4px;pointer-events:none}.sd-file-picker:hover:not(.sd-file-picker--inline):not(.sd-file-picker--disabled){background-color:#f6f6f6}.sd-file-picker--active:not(.sd-file-picker--inline):not(.sd-file-picker--disabled){background-color:#ffffff}.sd-file-picker--active:not(.sd-file-picker--inline):not(.sd-file-picker--disabled) .sd-file-picker__text{color:#222222}.sd-file-picker--disabled:not(.sd-file-picker--inline){background-color:#eeeeee;border-color:#cccccc}.sd-file-picker--disabled:not(.sd-file-picker--inline) .sd-file-picker__text{color:#888888}.sd-file-picker--inline{border:none;background-color:transparent;padding:0;height:auto}.sd-file-picker--inline .sd-file-picker__text{color:#aaaaaa}.sd-file-picker--inline:hover:not(.sd-file-picker--disabled) .sd-file-picker__text{color:#737373}.sd-file-picker--inline.sd-file-picker--active:not(.sd-file-picker--disabled) .sd-file-picker__text--active{color:#222222}.sd-file-picker--inline.sd-file-picker--disabled .sd-file-picker__text{color:#cccccc}`;
152
-
153
- const SdFilePicker = class {
154
- constructor(hostRef) {
155
- index.registerInstance(this, hostRef);
156
- this.sdChange = index.createEvent(this, "sdChange");
157
- }
158
- get el() { return index.getElement(this); }
159
- value = null;
160
- placeholder = 'Click to upload';
161
- disabled = false;
162
- inline = false;
163
- multiple = false;
164
- accept;
165
- width;
166
- internalValue = null;
167
- hovered = false;
168
- showTooltip = false;
169
- fileInputRef;
170
- fileNamesRef;
171
- sdChange;
172
- valueChanged(newValue) {
173
- this.internalValue = newValue;
112
+ disconnectedCallback() {
113
+ if (this.rafId)
114
+ cancelAnimationFrame(this.rafId);
115
+ this.unobserveParent();
116
+ this.wrapper?.remove();
174
117
  }
175
- componentDidLoad() {
176
- this.checkOverflow();
118
+ resolveContainer() {
119
+ const el = typeof this.to === 'string' ? document.querySelector(this.to) : this.to;
120
+ return el instanceof HTMLElement ? el : document.body;
177
121
  }
178
- componentDidUpdate() {
179
- this.checkOverflow();
122
+ createWrapper() {
123
+ this.wrapper = document.createElement('div');
124
+ Object.assign(this.wrapper.style, {
125
+ position: 'absolute',
126
+ zIndex: this.zIndex.toString(),
127
+ transition: 'opacity 0.4s',
128
+ top: '-9999px',
129
+ left: '-9999px',
130
+ });
131
+ this.container.appendChild(this.wrapper);
180
132
  }
181
- handleFileChange = (event) => {
182
- const input = event.target;
183
- const files = input.files;
184
- if (!files || files.length === 0) {
185
- return;
186
- }
187
- const fileArray = Array.from(files);
188
- if (this.multiple) {
189
- this.internalValue = fileArray;
190
- }
191
- else {
192
- this.internalValue = fileArray[0];
193
- }
194
- this.value = this.internalValue;
195
- this.sdChange?.emit(this.value);
196
- };
197
- handleClear = (event) => {
198
- event.stopPropagation();
199
- const clearedValue = this.multiple ? [] : null;
200
- this.value = clearedValue;
201
- this.internalValue = clearedValue;
202
- this.sdChange?.emit(clearedValue);
203
- if (this.fileInputRef) {
204
- this.fileInputRef.value = '';
205
- }
206
- };
207
- handleClick = () => {
208
- if (this.disabled)
133
+ moveSlotContent() {
134
+ if (!this.wrapper)
209
135
  return;
210
- this.fileInputRef?.click();
211
- };
212
- getStatusClass() {
213
- if (this.disabled)
214
- return 'sd-file-picker--disabled';
215
- if (this.hasFiles())
216
- return 'sd-file-picker--active';
217
- return '';
218
- }
219
- hasFiles() {
220
- if (!this.internalValue)
221
- return false;
222
- if (Array.isArray(this.internalValue)) {
223
- return this.internalValue.length > 0;
224
- }
225
- return true;
136
+ const nodes = Array.from(this.el.childNodes).filter(n => n.nodeType !== Node.COMMENT_NODE);
137
+ nodes.forEach(n => this.wrapper.appendChild(n));
226
138
  }
227
- getDisplayText() {
228
- if (!this.hasFiles())
229
- return this.placeholder;
230
- if (Array.isArray(this.internalValue)) {
231
- return this.internalValue.map(f => f.name).join(', ');
232
- }
233
- return this.internalValue?.name || this.placeholder;
139
+ // 위치 갱신 (scroll / resize)
140
+ updatePosition() {
141
+ if (this.rafId)
142
+ cancelAnimationFrame(this.rafId);
143
+ this.rafId = requestAnimationFrame(() => {
144
+ if (!this.parentRef || !this.wrapper)
145
+ return;
146
+ const rect = this.parentRef.getBoundingClientRect();
147
+ if (!rect.width && !rect.height)
148
+ return; // 요소가 보이지 않는 경우
149
+ const [offsetX, offsetY] = this.offset;
150
+ const ARROW_SIZE = SdFloatingPopover.ARROW_SIZE;
151
+ let top = 0;
152
+ let left = 0;
153
+ switch (this.placement) {
154
+ case 'top':
155
+ top = rect.top + window.scrollY - this.wrapper.offsetHeight + offsetY - ARROW_SIZE;
156
+ left = rect.left + window.scrollX + rect.width / 2 - this.wrapper.offsetWidth / 2 + offsetX;
157
+ break;
158
+ case 'bottom':
159
+ top = rect.bottom + window.scrollY + offsetY + ARROW_SIZE;
160
+ left = rect.left + window.scrollX + rect.width / 2 - this.wrapper.offsetWidth / 2 + offsetX;
161
+ break;
162
+ case 'left':
163
+ top = rect.top + window.scrollY + rect.height / 2 - this.wrapper.offsetHeight / 2 + offsetY;
164
+ left = rect.left + window.scrollX - this.wrapper.offsetWidth - offsetX - ARROW_SIZE;
165
+ break;
166
+ case 'right':
167
+ top = rect.top + window.scrollY + rect.height / 2 - this.wrapper.offsetHeight / 2 + offsetY;
168
+ left = rect.right + window.scrollX + offsetX + ARROW_SIZE;
169
+ break;
170
+ }
171
+ Object.assign(this.wrapper.style, {
172
+ top: `${top}px`,
173
+ left: `${left}px`,
174
+ });
175
+ });
234
176
  }
235
- checkOverflow() {
236
- if (!this.fileNamesRef)
177
+ // parentRef의 이동 / 크기변경 감지
178
+ observeParent() {
179
+ if (!this.parentRef)
237
180
  return;
238
- const isOverflowing = this.fileNamesRef.scrollWidth > this.fileNamesRef.clientWidth;
239
- this.showTooltip = isOverflowing;
240
- }
241
- getIconColor() {
242
- if (this.disabled) {
243
- return this.inline ? 'grey_45' : 'grey_55';
244
- }
245
- return 'grey_70';
181
+ this.resizeObserver = new ResizeObserver(() => this.updatePosition());
182
+ this.resizeObserver.observe(this.parentRef);
183
+ this.mutationObserver = new MutationObserver(() => this.updatePosition());
184
+ this.mutationObserver.observe(document.body, {
185
+ childList: true,
186
+ subtree: true,
187
+ });
246
188
  }
247
- render() {
248
- const hasFiles = this.hasFiles();
249
- const displayText = this.getDisplayText();
250
- return (index.h("div", { key: '467ea6ab920e23a8cf98db73f3ba5507e0634bc8', class: {
251
- 'sd-file-picker': true,
252
- [this.getStatusClass()]: true,
253
- 'sd-file-picker--inline': this.inline,
254
- }, onClick: this.handleClick, onMouseEnter: () => (this.hovered = true), onMouseLeave: () => (this.hovered = false) }, index.h("input", { key: '20ff1404f15beaeff2f4f3e0b1772aadbd986934', ref: el => (this.fileInputRef = el), type: "file", class: "sd-file-picker__input", disabled: this.disabled, multiple: this.multiple, accept: this.accept, onInput: this.handleFileChange, "aria-label": this.placeholder }), index.h("sd-icon", { key: '59e00f4ba49547aacf99dfab54c391c49895d8df', name: "attachFile", size: 16, color: this.getIconColor(), class: "sd-file-picker__icon" }), index.h("div", { key: 'be74c5aebcc947aacf6841b15915cc98af5453e6', ref: el => (this.fileNamesRef = el), class: {
255
- 'sd-file-picker__text': true,
256
- 'sd-file-picker__text--placeholder': !hasFiles,
257
- 'sd-file-picker__text--active': hasFiles,
258
- } }, displayText), !this.disabled && hasFiles && (index.h("sd-icon", { key: '0547537e85b8eb0f2678c3023eeec9241caf0ced', name: "close", size: 12, color: "#888888", class: "sd-file-picker__clear-icon", onClick: this.handleClear })), this.showTooltip && hasFiles && this.hovered && (index.h("div", { key: '86bf77f26f2aea00c31c9770c2142353d92d239c', class: "sd-file-picker__tooltip" }, displayText))));
189
+ unobserveParent() {
190
+ this.resizeObserver?.disconnect();
191
+ this.mutationObserver?.disconnect();
259
192
  }
260
- static get watchers() { return {
261
- "value": ["valueChanged"]
262
- }; }
263
- };
264
- SdFilePicker.style = sdFilePickerCss();
265
-
266
- const sdGuideCss = () => `@charset "UTF-8";sd-button{display:inline-block;width:fit-content;height:fit-content}.sd-button{text-decoration:none;cursor:pointer;border-radius:4px;transition:all 0.2s ease-in-out;position:relative;overflow:hidden;white-space:nowrap;-webkit-user-select:none;user-select:none;box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center}.sd-button--xs{padding:0 8px;font-size:12px;font-weight:500;line-height:20px;min-height:24px}.sd-button--sm{padding:0 12px;font-size:12px;font-weight:500;line-height:20px;min-height:28px}.sd-button--md{padding:0 20px;font-size:16px;font-weight:500;line-height:26px;min-height:34px}.sd-button--lg{padding:0 28px;font-size:18px;font-weight:500;line-height:30px;min-height:62px}.sd-button--primary{background-color:var(--button-color);color:white;transition:filter 0.2s ease}.sd-button--primary::before{content:"";position:absolute;inset:0;background:#000000;opacity:0;transition:opacity 0.2s ease;z-index:0}.sd-button--primary:hover:not(.sd-button--disabled):not(.sd-button--loading)::before{opacity:0.25}.sd-button--outline{background:white;border:1px solid var(--button-color);color:var(--button-color)}.sd-button--outline::before{content:"";position:absolute;inset:0;background:var(--button-color);opacity:0;transition:opacity 0.2s ease;z-index:0}.sd-button--outline:hover:not(.sd-button--disabled):not(.sd-button--loading)::before{opacity:0.15}.sd-button--outline .sd-button__content{position:relative;z-index:1}.sd-button--ghost{background-color:transparent;color:var(--button-color);border-color:transparent}.sd-button--ghost::before{content:"";position:absolute;inset:0;background:var(--button-color);opacity:0;transition:opacity 0.2s ease;z-index:0}.sd-button--ghost:hover:not(.sd-button--disabled):not(.sd-button--loading)::before{opacity:0.15}.sd-button--ghost .sd-button__content{position:relative;z-index:1}.sd-button--disabled{border:1px solid #cccccc;background:#e1e1e1;color:#888888;cursor:not-allowed !important}.sd-button--icon-only{padding:0;width:fit-content;height:fit-content;aspect-ratio:1/1}.sd-button--no-hover:hover::before{opacity:0 !important}.sd-button .sd-button__content{display:inline-flex;align-items:center;justify-content:center;gap:4px;z-index:1;font-weight:500}sd-guide{display:inline-flex;align-items:center}sd-guide .sd-guide{display:inline-flex}sd-guide .sd-guide .sd-button{padding:0 16px 0 12px;border-radius:16px;color:#333333 !important;display:flex;align-items:center;transition:none}sd-guide .sd-guide .sd-button .sd-button__content{color:#333333 !important}sd-guide .sd-guide .sd-button .sd-button__content .sd-button__label{color:#333333 !important;margin-left:4px}sd-guide .sd-guide--active .sd-button{border:1px solid #12b553}sd-guide .sd-guide--active .sd-button .sd-button__content .sd-button__label{color:white !important}.sd-guide__popup{position:relative;padding:20px 32px;border-radius:8px;box-shadow:4px 4px 24px 4px rgba(0, 0, 0, 0.1);background:white}.sd-guide__popup>.sd-guide__popup__close{position:absolute;top:12px;right:12px}.sd-guide__popup__header{display:flex;align-items:center;gap:8px;margin-bottom:12px}.sd-guide__popup__header .sd-guide__popup__title{margin-top:0;font-size:16px;font-weight:700;line-height:26px;color:#333333}.sd-guide__popup__list{width:100%;padding:0;margin:0}.sd-guide__popup__list__item{display:flex;width:100%;align-items:start;list-style:none;color:#333333;font-size:12px;font-weight:400}.sd-guide__popup__list__item p{width:100%;padding:0;margin:0;word-wrap:break-word;word-break:break-word;white-space:normal;overflow-wrap:break-word;min-width:0}.sd-guide__popup__list__item::before{display:block;content:"-";width:6px;color:#333333;font-size:12px;font-weight:400;margin-left:10px;margin-right:12px;flex-shrink:0}.sd-guide__popup__list__item--depth-2::before{content:"•"}.sd-guide__popup__list__item--depth-2{padding-left:26px}`;
267
-
268
- const GUIDE_LABEL = {
269
- help: '활용 TIP',
270
- pdf: 'PDF Guide',
271
- youtube: 'Video Guide',
272
- notion: '사용법 안내',
273
- event: 'Event Button',
274
- };
275
- const GUIDE_ICON = {
276
- help: {
277
- name: 'helpOutline',
278
- size: 20,
279
- color: resolveColor.colors.green_75,
280
- },
281
- pdf: { name: 'pdf', size: 20, color: resolveColor.colors.red_75 },
282
- youtube: { name: 'youtube', size: 20, color: resolveColor.colors.red_75 },
283
- notion: { name: 'notion', size: 16, color: resolveColor.colors.black },
284
- event: { name: 'event', size: 16, color: resolveColor.colors.brilliantblue_70 },
285
- };
286
- const SdGuide = class {
287
- constructor(hostRef) {
288
- index.registerInstance(this, hostRef);
193
+ // 외부 클릭 감지
194
+ handleMouseDown(e) {
195
+ this.isInsideClick = !!((this.wrapper && this.wrapper.contains(e.target)) ||
196
+ (this.parentRef && this.parentRef.contains(e.target)));
289
197
  }
290
- get el() { return index.getElement(this); }
291
- type = 'help';
292
- label = '';
293
- message = '';
294
- guideUrl = '';
295
- popupTitle = '';
296
- popupWidth;
297
- popupShow = false;
298
- guideRef;
299
- handleClickGuide = () => {
300
- if (this.type === 'help') {
301
- this.popupShow = !this.popupShow;
198
+ handleWindowClick(e) {
199
+ if (this.isInsideClick) {
200
+ this.isInsideClick = false;
302
201
  return;
303
202
  }
304
- if (this.guideUrl) {
305
- window.open(this.guideUrl, '_blank');
306
- }
307
- };
308
- get guideClass() {
309
- const classes = ['sd-guide', `sd-guide--${this.type}`];
310
- if (this.popupShow)
311
- classes.push('sd-guide--active');
312
- return classes.join(' ');
203
+ if (this.wrapper?.contains(e.target))
204
+ return;
205
+ this.close.emit();
313
206
  }
314
- closeDropdown = () => {
315
- this.popupShow = false;
316
- };
317
207
  render() {
318
- const { name: iconName, size: iconSize, color: iconColor } = GUIDE_ICON[this.type];
319
- return (index.h(index.Host, { key: '73cc9c84ec4e921e83e9d0cde2971c5088cbb48f', style: {
320
- '--sd-guide-color': GUIDE_ICON[this.type].color,
321
- } }, index.h("sd-button", { key: '310afd874d062a91fab4b179a9a4e2f340a95175', ref: el => (this.guideRef = el), class: this.guideClass, variant: this.popupShow ? 'primary' : 'outline', label: this.label || GUIDE_LABEL[this.type], size: "sm", color: this.popupShow ? GUIDE_ICON[this.type].color : 'grey_45', icon: iconName, iconColor: this.popupShow ? 'white' : iconColor, iconSize: iconSize, noHover: this.popupShow, onSdClick: this.handleClickGuide }), this.type === 'help' && this.popupShow && (index.h("sd-portal", { key: '133bb71a98efd9a15407aad915937caec728aa38', open: this.popupShow, parentRef: this.guideRef, onSdClose: this.closeDropdown, offset: [0, 4] }, index.h("div", { key: '4a39145ce20e1e37ebc3f639712f635231f34f2d', style: { position: 'absolute', width: '0px', height: '0px' } }, index.h("div", { key: 'e71a8217b3969db9fadf9083835402cf69e62c3c', class: "sd-guide__popup", style: { width: this.popupWidth ? this.popupWidth + 'px' : '426px' } }, index.h("sd-button", { key: 'f035ca961013d99305b0409f406fdd3063e11155', class: "sd-guide__popup__close", icon: "close", color: resolveColor.colors.grey_65, size: "md", variant: "ghost", noHover: true, onSdClick: this.closeDropdown }), index.h("div", { key: 'a3d505a21abd77e85fac45a792ca7bb2b2448a6a', class: "sd-guide__popup__header" }, index.h("sd-icon", { key: '785bfbe594936b56f407edd2349e19076cf6ece9', name: "helpOutline", size: 24, color: resolveColor.colors.green_65 }), index.h("h3", { key: 'da5dfaed05a11ccef574580a4c18341646d59e4f', class: "sd-guide__popup__title" }, this.popupTitle || GUIDE_LABEL[this.type])), index.h("ul", { key: '0faa4a71c1d77d21490436323c2d80c792397991', class: "sd-guide__popup__list" }, this.renderListItem(this.message))))))));
322
- }
323
- // 현재 2depth까지만 스타일 적용
324
- renderListItem(message, depth = 0) {
325
- const listItems = [];
326
- if (Array.isArray(message)) {
327
- const depthMsg = message.map(msg => this.renderListItem(msg, depth + 1));
328
- listItems.push(...depthMsg.flat());
329
- }
330
- else {
331
- listItems.push(this.renderLi(message, depth));
332
- }
333
- return listItems;
208
+ return index.h("slot", { key: 'f2000891d7d3bd71982f591bf953d1421f67fb5e' });
334
209
  }
335
- renderLi = (message, depth) => {
336
- return (index.h("li", { class: `sd-guide__popup__list__item sd-guide__popup__list__item--depth-${depth}` }, index.h("p", { innerHTML: message })));
337
- };
338
210
  };
339
- SdGuide.style = sdGuideCss();
211
+ SdFloatingPopover.style = sdFloatingPortalCss();
340
212
 
341
213
  const Add8 = (props) => (index.h("svg", { width: "8", height: "8", viewBox: "0 0 8 8", fill: "none", xmlns: "http://www.w3.org/2000/svg", ...props }, index.h("path", { d: "M3.99969 0.633484C4.16537 0.633484 4.29948 0.767622 4.2995 0.933289V3.69989H7.06708C7.23245 3.70014 7.36672 3.8343 7.36688 3.99969C7.36688 4.16523 7.23255 4.29925 7.06708 4.2995H4.2995V7.06708C4.29925 7.23255 4.16523 7.36688 3.99969 7.36688C3.8343 7.36672 3.70014 7.23245 3.69989 7.06708V4.2995H0.933289C0.767622 4.29948 0.633484 4.16537 0.633484 3.99969C0.633648 3.83416 0.767724 3.69991 0.933289 3.69989H3.69989V0.933289C3.69991 0.767724 3.83416 0.633648 3.99969 0.633484Z", fill: "currentColor" })));
342
214
 
@@ -2347,2433 +2219,199 @@ const SdIcon = class {
2347
2219
  }
2348
2220
  render() {
2349
2221
  const IconComponent = Icons[this.name]?.[this.size];
2350
- return (index.h("i", { key: '49cc8a7c8a0af18d920065232ef3e2127f6abb6c', class: this.getIconClasses(), style: this.iconStyle }, index.h(IconComponent, { key: 'cb8464e125ecfddc96621b57183fb26f37043f51', color: this.resolvedColor })));
2222
+ return (index.h("i", { key: '851c9b6fd0ac6bc9393a21e95184e158bced5fe6', class: this.getIconClasses(), style: this.iconStyle }, index.h(IconComponent, { key: 'a10dcad82179ba12a9e9754b0b2cdd1ef548b4a5', color: this.resolvedColor })));
2351
2223
  }
2352
2224
  };
2353
2225
  SdIcon.style = sdIconCss();
2354
2226
 
2355
- const sdInputCss = () => `sd-icon{display:inline-block;line-height:0}sd-icon .sd-icon--rotate-90{transform:rotate(90deg)}sd-icon .sd-icon--rotate-180{transform:rotate(180deg)}sd-icon .sd-icon--rotate-270{transform:rotate(270deg)}.sd-date-picker{width:100%;display:inline-block}.sd-date-picker .sd-date-picker--disabled .date-icon{cursor:not-allowed !important;color:#888888 !important}.sd-date-picker .sd-date-picker__input{text-align:center !important}.sd-date-picker__menu{width:304px;box-sizing:border-box;border-radius:8px;padding:24px 19px;box-shadow:2px 2px 12px 2px rgba(0, 0, 0, 0.2);background:white}.sd-date-picker__menu .sd-date-picker__header{display:flex;flex-flow:row nowrap;align-items:center;gap:20px;font-size:14px;padding:0 5px;height:24px;line-height:24px}.sd-date-picker__menu .sd-date-picker__header .year-nav,.sd-date-picker__menu .sd-date-picker__header .month-nav{display:flex;flex-flow:row nowrap;align-items:center;gap:12px}.sd-date-picker__menu .sd-date-picker__header .year-nav button,.sd-date-picker__menu .sd-date-picker__header .month-nav button{background:none;border:none;cursor:pointer;margin:0;padding:0}.sd-date-picker__menu .sd-date-picker__header .year-nav__current{width:40px;text-align:center}.sd-date-picker__menu .sd-date-picker__header .month-nav__current{width:100px;text-align:center}.sd-date-picker__menu .sd-date-picker__days{margin-top:8px;display:grid;grid-template-columns:repeat(7, minmax(0, 1fr));column-gap:10px;padding:0 5px}.sd-date-picker__menu .sd-date-picker__days .day{width:28px;height:20px;font-size:12px;line-height:20px;text-align:center;color:#888888}.sd-date-picker__menu .sd-date-picker__body{margin-top:12px;display:grid;grid-template-columns:repeat(7, minmax(0, 1fr))}.sd-date-range-picker{width:fit-content;display:inline-block}.sd-date-range-picker .sd-date-range-picker--disabled .date-icon{cursor:not-allowed !important;color:#888888 !important}.sd-date-range-picker .sd-input .sd-input__container{width:210px}.sd-date-range-picker .sd-input .sd-date-range-picker__input{margin-left:17px !important}.sd-date-range-picker__menu{width:609px;box-sizing:border-box;border-radius:8px;padding:24px 19px;box-shadow:2px 2px 12px 2px rgba(0, 0, 0, 0.2);background:white}.sd-date-range-picker__menu .sd-date-range-picker__header{margin-bottom:16px;display:flex;flex-flow:row nowrap;align-items:center;justify-content:center}.sd-date-range-picker__menu .sd-date-range-picker__header .header-label{margin:0 12px;width:40px;text-align:center;font-size:14px;line-height:24px}.sd-date-range-picker__menu .sd-date-range-picker__body{display:flex;flex-flow:row nowrap;align-items:stretch;gap:19px}.sd-date-range-picker__menu .sd-date-range-picker__body .calendar-container{width:266px}.sd-date-range-picker__menu .sd-date-range-picker__body .calendar-container .calendar-header{width:100%;height:24px;line-height:24px;font-size:14px;text-align:center;position:relative;padding:0 5px}.sd-date-range-picker__menu .sd-date-range-picker__body .calendar-container .calendar-header button{position:absolute;top:50%;transform:translateY(-50%)}.sd-date-range-picker__menu .sd-date-range-picker__body .calendar-container .calendar-header button.header-button-prev{left:5px}.sd-date-range-picker__menu .sd-date-range-picker__body .calendar-container .calendar-header button.header-button-next{right:5px;left:auto}.sd-date-range-picker__menu .sd-date-range-picker__body .calendar-container .calendar-days{padding:0 5px;margin-top:8px;display:grid;grid-template-columns:repeat(7, minmax(0, 1fr));column-gap:10px}.sd-date-range-picker__menu .sd-date-range-picker__body .calendar-container .calendar-days .day{width:28px;height:20px;font-size:12px;line-height:20px;text-align:center;color:#888888}.sd-date-range-picker__menu .sd-date-range-picker__body .calendar-container .calendar-body{margin-top:12px;display:grid;grid-template-columns:repeat(7, minmax(0, 1fr))}.sd-date-range-picker__menu .sd-date-range-picker__body .separator{width:1px;background-color:#d8d8d8}.sd-input{display:flex;flex-flow:row nowrap;align-items:center;border:1px solid #aaaaaa;border-radius:4px;color:#333333;font-size:12px;line-height:20px;width:var(--input-width, 100%);height:28px;background:white}.sd-input.sd-input--with-label:not(.sd-input--inside-label){border:none}.sd-input.sd-input--with-label:not(.sd-input--inside-label) .sd-input__label{margin-right:8px}.sd-input.sd-input--with-label:not(.sd-input--inside-label) .sd-input__container{border:1px solid #aaaaaa;border-radius:4px;height:28px}.sd-input.sd-input--inside-label .sd-input__label{background:#f6f6f6;padding:0 12px;display:flex;align-items:center;justify-content:center;height:100%;border-radius:4px 0 0 4px}.sd-input.sd-input--disabled{cursor:not-allowed !important;box-shadow:none !important;border:1px solid #cccccc !important;background:#eeeeee !important;color:#888888 !important}.sd-input.sd-input--disabled.sd-input--with-label:not(.sd-input--inside-label){border:none !important;background:transparent !important}.sd-input.sd-input--disabled.sd-input--with-label:not(.sd-input--inside-label) .sd-input__container{border:1px solid #cccccc !important;background:#eeeeee !important;color:#888888 !important}.sd-input.sd-input--disabled .sd-input__container{color:#737373 !important}.sd-input.sd-input--disabled .sd-input__container .sd-input__native_element{color:#888888 !important;cursor:not-allowed !important}.sd-input--hovered,.sd-input--focused{border-color:#0075ff;box-shadow:0 0 4px 0 rgba(0, 113, 255, 0.4)}.sd-input--hovered.sd-input--with-label:not(.sd-input--inside-label),.sd-input--focused.sd-input--with-label:not(.sd-input--inside-label){border-color:transparent;box-shadow:none}.sd-input--hovered.sd-input--with-label:not(.sd-input--inside-label) .sd-input__container,.sd-input--focused.sd-input--with-label:not(.sd-input--inside-label) .sd-input__container{border-color:#0075ff;box-shadow:0 0 4px 0 rgba(0, 113, 255, 0.4)}.sd-input.sd-input--error{border-color:#fb4444}.sd-input.sd-input--pass{border-color:#2bce6c}.sd-input.sd-input--barcode:not(.sd-input--disabled){background-color:#fafaa1}.sd-input .sd-input__container{display:flex;align-items:center;padding:4px 8px;width:100%}.sd-input .sd-input__container .sd-input__native_element{display:block;width:100%;height:20px;line-height:20px;border:none;outline:none;background:transparent;font-size:inherit;color:#333333;margin-left:4px;margin-right:4px;padding-block:0;padding-inline:0}.sd-input .sd-input__container .sd-input__native_element::placeholder{font-size:12px;height:20px;line-height:20px;color:#aaaaaa}.sd-input .sd-input__container .sd-input__clear-icon{cursor:pointer;margin-left:8px}`;
2227
+ const sdPaginationCss = () => `.sd-pagination{display:flex;flex-flow:row nowrap;align-items:center;justify-content:center;gap:8px;color:#555555;width:100%;font-size:12px}.sd-pagination .prepend-btns{display:flex;flex-flow:row nowrap;align-items:center;gap:8px;width:60px}.sd-pagination .prepend-btns button{width:26px;height:26px;border:0;background:none}.sd-pagination .prepend-btns button:hover{border:1px solid #006ac1;border-radius:14px}.sd-pagination .append-btns{display:flex;flex-flow:row nowrap;align-items:center;gap:8px;width:60px}.sd-pagination .append-btns button{width:26px;height:26px;border:0;background:none}.sd-pagination .append-btns button:hover{border:1px solid #006ac1;border-radius:14px}.sd-pagination .pagination-btn{display:flex;align-items:center;justify-content:center;border-radius:14px;outline:none;border:none;cursor:pointer;height:26px;color:#555555;width:var(--pagination-btn-width, 26px)}.sd-pagination .pagination-btn--selected{background-color:#006ac1;color:white}.sd-pagination .pagination-btn:hover{border:1px solid #006ac1}.sd-pagination--simple .pagination-info{line-height:26px;display:flex;flex-flow:row nowrap;align-items:center;gap:8px}.sd-pagination--simple .pagination-info .current-page,.sd-pagination--simple .pagination-info .last-page{padding:0 2px}`;
2356
2228
 
2357
- const SdInput = class {
2229
+ const BUTTON_WIDTH = {
2230
+ 1: 26,
2231
+ 2: 36,
2232
+ 3: 42,
2233
+ 4: 50,
2234
+ 5: 58,
2235
+ };
2236
+ const PER_PAGE = 10;
2237
+ const SdPagination = class {
2358
2238
  constructor(hostRef) {
2359
2239
  index.registerInstance(this, hostRef);
2360
- this.sdClick = index.createEvent(this, "sdClick");
2361
- this.sdInput = index.createEvent(this, "sdInput");
2362
- this.sdChange = index.createEvent(this, "sdChange");
2363
- this.sdFocus = index.createEvent(this, "sdFocus");
2364
- this.sdBlur = index.createEvent(this, "sdBlur");
2365
- }
2366
- get el() { return index.getElement(this); }
2367
- value = null;
2368
- label;
2369
- insideLabel = false;
2370
- placeholder = '입력해 주세요.';
2371
- disabled = false;
2372
- clearable = false;
2373
- width;
2374
- barcode = false;
2375
- rules;
2376
- autoFocus = false;
2377
- status;
2378
- inputClass = '';
2379
- readonly = false;
2380
- // props - custom styles
2381
- inputStyle = {};
2382
- internalValue = null;
2383
- error = false;
2384
- focused = false;
2385
- hovered = false;
2386
- nativeEl = undefined;
2387
- sdClick;
2388
- sdInput;
2389
- sdChange;
2390
- sdFocus;
2391
- sdBlur;
2392
- valueChanged(newValue) {
2393
- this.internalValue = newValue;
2240
+ this.pageChange = index.createEvent(this, "sdPageChange");
2394
2241
  }
2395
- internalValueChanged(newValue) {
2396
- if (newValue !== this.value) {
2397
- this.value = newValue;
2398
- this.sdInput?.emit(this.value);
2399
- }
2400
- if (!this.rules || this.rules.length === 0)
2401
- return;
2402
- this.error = false;
2403
- for (const rule of this.rules) {
2404
- const result = rule(newValue);
2405
- if (result !== true) {
2406
- this.error = true;
2407
- break;
2408
- }
2242
+ currentPage = 1;
2243
+ lastPage = 1;
2244
+ simple = false;
2245
+ pageChange;
2246
+ get paginationClasses() {
2247
+ const classes = ['sd-pagination'];
2248
+ if (this.simple) {
2249
+ classes.push('sd-pagination--simple');
2409
2250
  }
2251
+ return classes.join(' ');
2410
2252
  }
2411
- async getNativeElement() {
2412
- return this.nativeEl || null;
2253
+ get pageNumbers() {
2254
+ const start = Math.floor((this.currentPage - 1) / PER_PAGE) * PER_PAGE + 1;
2255
+ const end = Math.min(start + PER_PAGE - 1, this.lastPage);
2256
+ return Array.from({ length: end - start + 1 }, (_, i) => start + i);
2413
2257
  }
2414
- componentWillLoad() {
2415
- if (this.value) {
2416
- this.internalValue = this.value;
2417
- }
2418
- }
2419
- handleInput = (event) => {
2420
- const target = event.target;
2421
- this.internalValue = target.value;
2422
- this.sdInput?.emit(this.internalValue);
2423
- };
2424
- handleChange = (event) => {
2425
- const target = event.target;
2426
- this.internalValue = target.value;
2427
- this.sdChange?.emit(this.internalValue);
2428
- };
2429
- handleFocus = (type, event) => {
2430
- this.focused = type === 'focus';
2431
- if (type === 'blur')
2432
- this.sdBlur?.emit(event);
2433
- else
2434
- this.sdFocus?.emit(event);
2435
- };
2436
- getInputStatus() {
2437
- // input 상태 우선순위: hovered > focused > status(상태 주입) > error(rules 검사)
2438
- if (this.disabled)
2439
- return 'sd-input--disabled';
2440
- if (this.hovered)
2441
- return 'sd-input--hovered';
2442
- if (this.focused)
2443
- return 'sd-input--focused';
2444
- if (this.status)
2445
- return `sd-input--${this.status}`;
2446
- if (this.error)
2447
- return 'sd-input--error';
2448
- return '';
2449
- }
2450
- render() {
2451
- const inputWidth = this.width
2452
- ? {
2453
- '--input-width': typeof this.width === 'number' ? `${this.width}px` : this.width,
2454
- }
2455
- : {};
2456
- return (index.h(index.Host, { key: '3babaa8e892b3e5e484d1bdbc28b0d209945ad69', style: inputWidth }, index.h("div", { key: '31ea7cd711a33881144da3f0d4a6e98e6ec55244', class: {
2457
- 'sd-input': true,
2458
- 'sd-input--with-label': !!this.label,
2459
- 'sd-input--inside-label': !!this.label && this.insideLabel,
2460
- 'sd-input--barcode': !!this.barcode,
2461
- [this.getInputStatus()]: true,
2462
- } }, this.label && (index.h("div", { key: '85596e41249b0f136c9c07bebe40e2bc2166ceba', class: {
2463
- 'sd-input__label': true,
2464
- } }, this.label)), index.h("label", { key: 'd942a7cc950506a5cf2bcfd8984d3981af18cc7f', class: {
2465
- 'sd-input__container': true,
2466
- }, onMouseEnter: () => (this.hovered = true), onMouseLeave: () => (this.hovered = false), style: this.inputStyle }, index.h("slot", { key: '3add3a8c845be67ccd31ae98b30f5989d7e7dbf1', name: "prefix" }), index.h("input", { key: 'b7297ae85e0f07c8a5696cc7072833dc6ade82bc', ref: el => (this.nativeEl = el), class: `sd-input__native_element ${this.inputClass}`, type: "text", value: this.internalValue || '', placeholder: this.placeholder, disabled: this.disabled, readonly: this.readonly, autofocus: this.autoFocus, onInput: this.handleInput, onChange: this.handleChange, onFocus: event => this.handleFocus('focus', event), onBlur: event => this.handleFocus('blur', event) }), index.h("slot", { key: 'c6ae6cb3f58da00c0ae80261e41841889347b73d', name: "suffix" }), this.clearable && this.internalValue && (index.h("sd-icon", { key: '662f365d57707b631f7a58b18330666521846e84', name: "close", color: "#888", class: "sd-input__clear-icon", onClick: () => {
2467
- this.internalValue = '';
2468
- this.sdChange?.emit(this.internalValue);
2469
- this.sdInput?.emit(this.internalValue);
2470
- } }))))));
2471
- }
2472
- static get watchers() { return {
2473
- "value": ["valueChanged"],
2474
- "internalValue": ["internalValueChanged"]
2475
- }; }
2476
- };
2477
- SdInput.style = sdInputCss();
2478
-
2479
- const sdLoadingSpinnerCss = () => `sd-loading-spinner{display:block}sd-loading-spinner .sd-loading-spinner{animation:sd-loading-spin 2s linear infinite;transform-origin:center center}sd-loading-spinner .sd-loading-spinner .path{animation:sd-loading-spin-path 1.5s ease-in-out infinite}@keyframes sd-loading-spin{0%{transform:rotate3d(0, 0, 1, 0deg)}25%{transform:rotate3d(0, 0, 1, 90deg)}50%{transform:rotate3d(0, 0, 1, 180deg)}75%{transform:rotate3d(0, 0, 1, 270deg)}100%{transform:rotate3d(0, 0, 1, 359deg)}}@keyframes sd-loading-spin-path{0%{stroke-dasharray:1, 200;stroke-dashoffset:0}50%{stroke-dasharray:89, 200;stroke-dashoffset:-35px}100%{stroke-dasharray:89, 200;stroke-dashoffset:-124px}}`;
2480
-
2481
- const SdLoadingSpinner = class {
2482
- constructor(hostRef) {
2483
- index.registerInstance(this, hostRef);
2484
- }
2485
- color = '#0075ff';
2486
- get resolvedColor() {
2487
- return resolveColor.resolveColor(this.color);
2488
- }
2489
- render() {
2490
- return (index.h(index.Host, { key: 'a04395d2aaacdb74c06aebff6674ba82cc089a88' }, index.h("svg", { key: 'e4a28205405702bb37b40aac4a73ae369605791d', class: "sd-loading-spinner", width: "72px", height: "72px", viewBox: "25 25 50 50", style: { color: this.resolvedColor } }, index.h("circle", { key: '31e0b13b0ab8dbf824fc6b40b020e7eb290f05f5', class: "path", cx: "50", cy: "50", r: "20", fill: "none", stroke: "currentColor", "stroke-width": "5", "stroke-miterlimit": "10" }))));
2491
- }
2492
- };
2493
- SdLoadingSpinner.style = sdLoadingSpinnerCss();
2494
-
2495
- const sdNumberInputCss = () => `sd-icon{display:inline-block;line-height:0}sd-icon .sd-icon--rotate-90{transform:rotate(90deg)}sd-icon .sd-icon--rotate-180{transform:rotate(180deg)}sd-icon .sd-icon--rotate-270{transform:rotate(270deg)}.sd-number-input{box-sizing:border-box;display:flex;width:var(--input-width, 100%);align-items:center;height:28px;padding:4px 8px;border:1px solid #aaaaaa;border-radius:4px;color:#333333;font-size:12px;line-height:20px;background:white;position:relative}.sd-number-input--hovered{border-color:#0075ff;box-shadow:0 0 4px 0 rgba(0, 113, 255, 0.4)}.sd-number-input.sd-number-input--error{border-color:#fb4444}.sd-number-input.sd-number-input--pass{border-color:#2bce6c}.sd-number-input.sd-number-input--disabled{background-color:#eeeeee !important;border-color:#cccccc !important;cursor:not-allowed !important;box-shadow:none !important}.sd-number-input.sd-number-input--disabled .sd-number-input__input{color:#888888 !important;cursor:not-allowed !important}.sd-number-input .sd-number-input__input{display:block;width:100%;height:20px;line-height:20px;border:none;outline:none;background:transparent;font-size:inherit;color:#333333;margin-left:4px;margin-right:4px;padding-block:0;padding-inline:0;text-align:right}.sd-number-input .sd-number-input__input::placeholder{font-size:12px;height:20px;line-height:20px;color:#aaaaaa}.sd-number-input .sd-number-input__clear-icon{cursor:pointer;margin-left:8px}.sd-number-input .sd-number-input__buttons{padding:4px;display:flex;justify-content:space-between;align-items:center;position:absolute;inset:0;opacity:0;pointer-events:none;transition:opacity 0.2s ease}.sd-number-input .sd-number-input__button{width:20px;height:20px;border:none;border-radius:2px;background-color:#eff6ff;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0;margin:0;transition:background-color 0.2s ease}.sd-number-input .sd-number-input__button:hover:not(:disabled){background-color:#e6f1ff}.sd-number-input .sd-number-input__button:disabled{background-color:#eeeeee;cursor:not-allowed}.sd-number-input .sd-number-input__button--decrement{border-bottom-left-radius:0;border-bottom-right-radius:0}.sd-number-input .sd-number-input__button--increment{border-top-left-radius:0;border-top-right-radius:0}.sd-number-input .sd-number-input__label{margin-bottom:8px;font-weight:500;color:#333333}sd-number-input:focus-within .sd-number-input__buttons{opacity:1;pointer-events:auto}sd-number-input:focus-within .sd-number-input{border-color:#0075ff;box-shadow:0 0 4px 0 rgba(0, 113, 255, 0.4)}`;
2496
-
2497
- const SdNumberInput = class {
2498
- constructor(hostRef) {
2499
- index.registerInstance(this, hostRef);
2500
- this.sdIncrement = index.createEvent(this, "sdIncrement");
2501
- this.sdDecrement = index.createEvent(this, "sdDecrement");
2502
- this.sdInput = index.createEvent(this, "sdInput");
2503
- this.sdChange = index.createEvent(this, "sdChange");
2504
- this.sdFocus = index.createEvent(this, "sdFocus");
2505
- this.sdBlur = index.createEvent(this, "sdBlur");
2506
- }
2507
- get el() { return index.getElement(this); }
2508
- min = Number.NEGATIVE_INFINITY;
2509
- max = Number.POSITIVE_INFINITY;
2510
- step = 1;
2511
- useButton = false;
2512
- useDecimal = false;
2513
- value = null;
2514
- label;
2515
- placeholder = '입력해 주세요.';
2516
- disabled = false;
2517
- width;
2518
- rules;
2519
- autoFocus = false;
2520
- status;
2521
- inputClass = '';
2522
- readonly = false;
2523
- inputStyle = {};
2524
- internalValue = null;
2525
- displayValue = '';
2526
- hovered = false;
2527
- error = false;
2528
- nativeEl = undefined;
2529
- sdIncrement;
2530
- sdDecrement;
2531
- sdInput;
2532
- sdChange;
2533
- sdFocus;
2534
- sdBlur;
2535
- formatWithCommas(value) {
2536
- if (value === null || value === undefined)
2537
- return '';
2538
- const isNegative = value < 0;
2539
- const absValue = Math.abs(value);
2540
- const [intPart, decPart] = absValue.toString().split('.');
2541
- const formatted = (+intPart).toLocaleString();
2542
- const result = isNegative ? '-' + formatted : formatted;
2543
- return decPart ? result + '.' + decPart : String(result);
2544
- }
2545
- parseInput(input) {
2546
- if (!input || input.trim() === '')
2547
- return null;
2548
- const cleaned = input.replace(/,/g, '').trim();
2549
- // -로 시작을 할 수 있을 수 있고, 소수점 0.n | .n
2550
- if (!/^-?(\d+\.?\d*|\d*\.\d+)$/.test(cleaned)) {
2551
- return null;
2552
- }
2553
- const parsed = parseFloat(cleaned);
2554
- if (isNaN(parsed))
2555
- return null;
2556
- // 소수점 사용 하지 않는데 . 이 있는 경우
2557
- if (!this.useDecimal && cleaned.includes('.')) {
2558
- return null;
2559
- }
2560
- return parsed;
2561
- }
2562
- clampMinMax(value) {
2563
- return Math.min(Math.max(value, this.min), this.max);
2564
- }
2565
- updateDisplay() {
2566
- this.displayValue = this.formatWithCommas(this.internalValue);
2567
- }
2568
- isIncrementDisabled() {
2569
- if (this.disabled || this.readonly)
2570
- return true;
2571
- if (this.internalValue !== null) {
2572
- return this.internalValue >= this.max;
2573
- }
2574
- return false;
2575
- }
2576
- isDecrementDisabled() {
2577
- if (this.disabled || this.readonly)
2578
- return true;
2579
- if (this.internalValue !== null) {
2580
- return this.internalValue <= this.min;
2581
- }
2582
- return false;
2583
- }
2584
- valueChanged(newValue) {
2585
- if (newValue === null || newValue === '') {
2586
- this.internalValue = null;
2587
- }
2588
- else {
2589
- const parsed = typeof newValue === 'string' ? this.parseInput(newValue) : newValue;
2590
- if (parsed !== null) {
2591
- this.internalValue = this.clampMinMax(parsed);
2592
- }
2593
- }
2594
- this.updateDisplay();
2595
- }
2596
- internalValueChanged(newValue) {
2597
- this.updateDisplay();
2598
- if (newValue !== this.value) {
2599
- this.value = newValue;
2600
- this.sdInput?.emit(newValue);
2601
- }
2602
- if (!this.rules || this.rules.length === 0)
2603
- return;
2604
- this.error = false;
2605
- for (const rule of this.rules) {
2606
- const result = rule(newValue);
2607
- if (result !== true) {
2608
- this.error = true;
2609
- break;
2610
- }
2611
- }
2612
- }
2613
- componentWillLoad() {
2614
- if (this.value !== null && this.value !== undefined) {
2615
- const parsed = typeof this.value === 'string' ? this.parseInput(this.value) : this.value;
2616
- if (parsed !== null) {
2617
- this.internalValue = this.clampMinMax(parsed);
2618
- }
2619
- }
2620
- this.updateDisplay();
2621
- }
2622
- handleInput = (event) => {
2623
- const target = event.target;
2624
- const inputValue = target.value;
2625
- if (inputValue === '') {
2626
- this.internalValue = null;
2627
- this.displayValue = '';
2628
- return;
2629
- }
2630
- const commasRemoved = inputValue.replace(/,/g, '');
2631
- // 만약에 소수점 (.) 이 여러개 일 경우
2632
- const decimalCount = (commasRemoved.match(/\./g) || []).length;
2633
- if (decimalCount > 1) {
2634
- target.value = this.displayValue;
2635
- return;
2636
- }
2637
- // 가능: "-", ".", "-." (단순 기호만 있는 경우)
2638
- if (commasRemoved === '-' || commasRemoved === '.' || commasRemoved === '-.') {
2639
- target.value = commasRemoved;
2640
- return;
2641
- }
2642
- // 숫자 뒤에 . 이 있는 경우 (예: "1000.") -> 콤마 포맷 적용 + . 유지
2643
- if (commasRemoved.endsWith('.') && decimalCount === 1) {
2644
- const numberPart = commasRemoved.slice(0, -1);
2645
- const parsed = this.parseInput(numberPart);
2646
- if (parsed !== null) {
2647
- const formatted = this.formatWithCommas(parsed);
2648
- target.value = formatted + '.';
2649
- return;
2650
- }
2651
- }
2652
- const parsed = this.parseInput(commasRemoved);
2653
- if (parsed !== null) {
2654
- if (parsed < this.min) {
2655
- target.value = this.displayValue;
2656
- return;
2657
- }
2658
- if (parsed > this.max) {
2659
- target.value = this.displayValue;
2660
- return;
2661
- }
2662
- this.internalValue = parsed;
2663
- this.displayValue = this.formatWithCommas(parsed);
2664
- target.value = this.displayValue;
2665
- }
2666
- else {
2667
- target.value = this.displayValue;
2668
- }
2669
- };
2670
- handleChange = (event) => {
2671
- const target = event.target;
2672
- const inputValue = target.value;
2673
- if (inputValue === '') {
2674
- this.internalValue = null;
2675
- }
2676
- else {
2677
- const parsed = this.parseInput(inputValue);
2678
- if (parsed !== null) {
2679
- this.internalValue = this.clampMinMax(parsed);
2680
- }
2681
- }
2682
- this.sdChange?.emit(this.internalValue);
2683
- };
2684
- handleFocus = (event) => {
2685
- this.sdFocus?.emit(event);
2686
- };
2687
- handleBlur = (event) => {
2688
- this.updateDisplay();
2689
- if (this.nativeEl) {
2690
- this.nativeEl.value = this.displayValue;
2691
- }
2692
- this.sdBlur?.emit(event);
2693
- };
2694
- handleKeyDown = (event) => {
2695
- if (event.key === 'ArrowUp') {
2696
- event.preventDefault();
2697
- this.handleIncrement();
2698
- }
2699
- else if (event.key === 'ArrowDown') {
2700
- event.preventDefault();
2701
- this.handleDecrement();
2702
- }
2703
- };
2704
- handleIncrement = () => {
2705
- if (this.isIncrementDisabled())
2706
- return;
2707
- const currentVal = this.internalValue ?? (this.min ?? 0);
2708
- let nextVal = currentVal + this.step;
2709
- if (nextVal > this.max) {
2710
- nextVal = this.max;
2711
- }
2712
- if (nextVal === currentVal)
2713
- return;
2714
- this.sdIncrement?.emit({ currentVal: nextVal, prevVal: currentVal });
2715
- this.internalValue = nextVal;
2716
- this.sdChange?.emit(nextVal);
2717
- };
2718
- handleDecrement = () => {
2719
- if (this.isDecrementDisabled())
2720
- return;
2721
- const currentVal = this.internalValue ?? (this.min ?? 0);
2722
- let nextVal = currentVal - this.step;
2723
- if (nextVal < this.min) {
2724
- nextVal = this.min;
2725
- }
2726
- if (nextVal === currentVal)
2727
- return;
2728
- this.sdDecrement?.emit({ currentVal: nextVal, prevVal: currentVal });
2729
- this.internalValue = nextVal;
2730
- this.sdChange?.emit(nextVal);
2731
- };
2732
- async getNativeElement() {
2733
- return this.nativeEl || null;
2734
- }
2735
- getInputStatus() {
2736
- if (this.disabled)
2737
- return 'sd-number-input--disabled';
2738
- if (this.hovered)
2739
- return 'sd-number-input--hovered';
2740
- if (this.status)
2741
- return `sd-number-input--${this.status}`;
2742
- if (this.error)
2743
- return 'sd-number-input--error';
2744
- return '';
2745
- }
2746
- render() {
2747
- const inputWidth = this.width
2748
- ? {
2749
- '--input-width': typeof this.width === 'number' ? `${this.width}px` : this.width,
2750
- }
2751
- : {};
2752
- const inputStyles = {
2753
- textAlign: this.useButton ? 'center' : 'right',
2754
- };
2755
- return (index.h(index.Host, { key: '00862eac1b5ac354058dfc63ac7cbae7ea675c2e', style: inputWidth, onFocus: this.handleFocus, onBlur: this.handleBlur }, this.useButton ? 'use buttons' : 'dont use buttons', this.label && index.h("div", { key: '368ea9ee71d69fccd1f4793e990b1345e7d87cfe', class: "sd-number-input__label" }, this.label), index.h("label", { key: '0f8d107bc23e308d6e9523f04199eccc39bd1268', class: {
2756
- 'sd-number-input': true,
2757
- [this.getInputStatus()]: true,
2758
- 'sd-number-input--with-buttons': this.useButton,
2759
- }, onMouseEnter: () => (this.hovered = true), onMouseLeave: () => (this.hovered = false), style: this.inputStyle }, index.h("input", { key: '7f6f4a677ba9460ea022ae2060a73872123d19be', ref: el => (this.nativeEl = el), class: `sd-number-input__input ${this.inputClass}`, type: "text", inputMode: "numeric", value: this.displayValue, placeholder: this.placeholder, disabled: this.disabled, readonly: this.readonly, autofocus: this.autoFocus, onInput: this.handleInput, onChange: this.handleChange, onKeyDown: this.handleKeyDown, style: inputStyles }), this.useButton && (index.h("div", { key: 'fd85f670c841fd7aee190fa040b4e228af3075a6', class: "sd-number-input__buttons" }, index.h("button", { key: 'c49d7ca15872cf5dc9fa6e46a3a7bca02a10d4d1', type: "button", class: {
2760
- 'sd-number-input__button': true,
2761
- 'sd-number-input__button--decrement': true,
2762
- }, disabled: this.isDecrementDisabled(), onClick: this.handleDecrement, tabindex: -1 }, index.h("sd-icon", { key: '9fe03669015bbac1704f06bcacf8625c6937253d', name: "minus", size: 12, color: this.isDecrementDisabled() ? '#CCCCCC' : '#2D8DFF' })), index.h("button", { key: '98ea1cc55299f03e1689bb9becc6e87ab5720d7a', type: "button", class: {
2763
- 'sd-number-input__button': true,
2764
- 'sd-number-input__button--increment': true,
2765
- }, disabled: this.isIncrementDisabled(), onClick: this.handleIncrement, tabindex: -1 }, index.h("sd-icon", { key: 'b6d446dfdd0435b8c991901a2cb100af4ae4d8b5', name: "add", size: 12, color: this.isIncrementDisabled() ? '#CCCCCC' : '#2D8DFF' })))))));
2766
- }
2767
- static get watchers() { return {
2768
- "value": ["valueChanged"],
2769
- "internalValue": ["internalValueChanged"]
2770
- }; }
2771
- };
2772
- SdNumberInput.style = sdNumberInputCss();
2773
-
2774
- const sdPaginationCss = () => `.sd-pagination{display:flex;flex-flow:row nowrap;align-items:center;justify-content:center;gap:8px;color:#555555;width:100%;font-size:12px}.sd-pagination .prepend-btns{display:flex;flex-flow:row nowrap;align-items:center;gap:8px;width:60px}.sd-pagination .prepend-btns button{width:26px;height:26px;border:0;background:none}.sd-pagination .prepend-btns button:hover{border:1px solid #006ac1;border-radius:14px}.sd-pagination .append-btns{display:flex;flex-flow:row nowrap;align-items:center;gap:8px;width:60px}.sd-pagination .append-btns button{width:26px;height:26px;border:0;background:none}.sd-pagination .append-btns button:hover{border:1px solid #006ac1;border-radius:14px}.sd-pagination .pagination-btn{display:flex;align-items:center;justify-content:center;border-radius:14px;outline:none;border:none;cursor:pointer;height:26px;color:#555555;width:var(--pagination-btn-width, 26px)}.sd-pagination .pagination-btn--selected{background-color:#006ac1;color:white}.sd-pagination .pagination-btn:hover{border:1px solid #006ac1}.sd-pagination--simple .pagination-info{line-height:26px;display:flex;flex-flow:row nowrap;align-items:center;gap:8px}.sd-pagination--simple .pagination-info .current-page,.sd-pagination--simple .pagination-info .last-page{padding:0 2px}`;
2775
-
2776
- const BUTTON_WIDTH = {
2777
- 1: 26,
2778
- 2: 36,
2779
- 3: 42,
2780
- 4: 50,
2781
- 5: 58,
2782
- };
2783
- const PER_PAGE = 10;
2784
- const SdPagination = class {
2785
- constructor(hostRef) {
2786
- index.registerInstance(this, hostRef);
2787
- this.pageChange = index.createEvent(this, "pageChange");
2788
- }
2789
- currentPage = 1;
2790
- lastPage = 1;
2791
- simple = false;
2792
- pageChange;
2793
- get paginationClasses() {
2794
- const classes = ['sd-pagination'];
2795
- if (this.simple) {
2796
- classes.push('sd-pagination--simple');
2797
- }
2798
- return classes.join(' ');
2799
- }
2800
- get pageNumbers() {
2801
- const start = Math.floor((this.currentPage - 1) / PER_PAGE) * PER_PAGE + 1;
2802
- const end = Math.min(start + PER_PAGE - 1, this.lastPage);
2803
- return Array.from({ length: end - start + 1 }, (_, i) => start + i);
2804
- }
2805
- get buttonWidth() {
2806
- const lastPageNum = this.pageNumbers.at(-1) ?? 1;
2807
- const maxPageLength = lastPageNum.toString().length;
2808
- return BUTTON_WIDTH[maxPageLength] || BUTTON_WIDTH[1];
2258
+ get buttonWidth() {
2259
+ const lastPageNum = this.pageNumbers.at(-1) ?? 1;
2260
+ const maxPageLength = lastPageNum.toString().length;
2261
+ return BUTTON_WIDTH[maxPageLength] || BUTTON_WIDTH[1];
2809
2262
  }
2810
2263
  handlePageChange(page) {
2811
2264
  if (page < 1 || page > this.lastPage)
2812
2265
  return;
2813
- this.pageChange.emit(page);
2814
- }
2815
- handleGroupChange(direction) {
2816
- const delta = direction === 'forward' ? PER_PAGE : -10;
2817
- const newPage = Math.min(Math.max(this.currentPage + delta, 1), this.lastPage);
2818
- this.handlePageChange(newPage);
2819
- }
2820
- get isFirstGroup() {
2821
- return this.currentPage <= PER_PAGE;
2822
- }
2823
- get isLastGroup() {
2824
- const startPageGroup = Math.floor((this.currentPage - 1) / PER_PAGE) * PER_PAGE + 1;
2825
- return startPageGroup + PER_PAGE - 1 >= this.lastPage;
2826
- }
2827
- renderPrevButtons() {
2828
- if (this.simple) {
2829
- if (this.currentPage <= 1)
2830
- return null;
2831
- return (index.h(index.Fragment, null, index.h("button", { "aria-label": "Go to first page", onClick: () => this.handlePageChange(1) }, index.h("sd-icon", { name: "arrowLeftEnd", size: "12", color: "#222222" })), index.h("button", { "aria-label": "Go to previous page", onClick: () => this.handlePageChange(this.currentPage - 1) }, index.h("sd-icon", { name: "arrowLeft", size: "12", color: "#222222" }))));
2832
- }
2833
- if (!this.isFirstGroup) {
2834
- return (index.h(index.Fragment, null, index.h("button", { "aria-label": "Go to first page", onClick: () => this.handlePageChange(1) }, index.h("sd-icon", { name: "arrowLeftEnd", size: "12", color: "#222222" })), index.h("button", { "aria-label": "Go to previous page group", onClick: () => this.handleGroupChange('backward') }, index.h("sd-icon", { name: "arrowLeft", size: "12", color: "#222222" }))));
2835
- }
2836
- }
2837
- renderNextButtons() {
2838
- if (this.simple) {
2839
- if (this.currentPage >= this.lastPage)
2840
- return null;
2841
- return (index.h(index.Fragment, null, index.h("button", { "aria-label": "Go to next page", onClick: () => this.handlePageChange(this.currentPage + 1) }, index.h("sd-icon", { name: "arrowRight", size: "12", color: "#222222" })), index.h("button", { "aria-label": "Go to last page", onClick: () => this.handlePageChange(this.lastPage) }, index.h("sd-icon", { name: "arrowRightEnd", size: "12", color: "#222222" }))));
2842
- }
2843
- if (!this.isLastGroup) {
2844
- return (index.h(index.Fragment, null, index.h("button", { "aria-label": "Go to next page group", onClick: () => this.handleGroupChange('forward') }, index.h("sd-icon", { name: "arrowRight", size: "12", color: "#222222" })), index.h("button", { "aria-label": "Go to last page", onClick: () => this.handlePageChange(this.lastPage) }, index.h("sd-icon", { name: "arrowRightEnd", size: "12", color: "#222222" }))));
2845
- }
2846
- }
2847
- render() {
2848
- return (index.h("div", { key: '0a55eddc4c434d3a7dc6afaa2386e68a6767300e', class: this.paginationClasses }, index.h("div", { key: '8bb73906c74f1a8646286d0858ab6276531e4bd9', class: "prepend-btns" }, this.renderPrevButtons()), this.simple ? (index.h("div", { class: "pagination-info" }, index.h("span", { class: "current-page" }, this.currentPage), index.h("span", null, "/"), index.h("span", { class: "last-page" }, this.lastPage))) : (this.pageNumbers.map(n => (index.h("button", { type: "button", "aria-current": this.currentPage === n ? 'page' : undefined, class: {
2849
- 'pagination-btn': true,
2850
- 'pagination-btn--selected': this.currentPage === n,
2851
- }, disabled: this.currentPage === n, style: {
2852
- '--pagination-btn-width': `${this.buttonWidth}px`,
2853
- }, onClick: () => this.handlePageChange(n) }, n)))), index.h("div", { key: '2f6945f41f351153a9c182262ecef8c96d0ec1eb', class: "append-btns" }, this.renderNextButtons())));
2854
- }
2855
- };
2856
- SdPagination.style = sdPaginationCss();
2857
-
2858
- const SdPortal = class {
2859
- constructor(hostRef) {
2860
- index.registerInstance(this, hostRef);
2861
- this.sdClose = index.createEvent(this, "sdClose");
2862
- }
2863
- get hostEl() { return index.getElement(this); }
2864
- to = 'body';
2865
- parentRef = null;
2866
- offset = [0, 4];
2867
- zIndex = 9999;
2868
- open = false;
2869
- sdClose;
2870
- container;
2871
- wrapper;
2872
- rafId;
2873
- isInsideClick = false;
2874
- resizeObserver;
2875
- mutationObserver;
2876
- componentDidLoad() {
2877
- this.container = this.resolveContainer();
2878
- this.createWrapper();
2879
- this.moveSlotContent();
2880
- this.updatePosition();
2881
- this.observeParent();
2882
- }
2883
- componentDidRender() {
2884
- if (!this.wrapper)
2885
- return;
2886
- this.wrapper.style.display = this.open ? 'block' : 'none';
2887
- if (this.open)
2888
- this.updatePosition();
2889
- }
2890
- disconnectedCallback() {
2891
- this.unobserveParent();
2892
- this.wrapper?.remove();
2893
- }
2894
- resolveContainer() {
2895
- const el = typeof this.to === 'string' ? document.querySelector(this.to) : this.to;
2896
- return el instanceof HTMLElement ? el : document.body;
2897
- }
2898
- createWrapper() {
2899
- this.wrapper = document.createElement('div');
2900
- Object.assign(this.wrapper.style, {
2901
- position: 'absolute',
2902
- zIndex: this.zIndex.toString(),
2903
- transition: 'opacity 0.4s',
2904
- });
2905
- this.container.appendChild(this.wrapper);
2906
- }
2907
- moveSlotContent() {
2908
- if (!this.wrapper)
2909
- return;
2910
- const nodes = Array.from(this.hostEl.childNodes).filter(n => n.nodeType !== Node.COMMENT_NODE);
2911
- nodes.forEach(n => this.wrapper.appendChild(n));
2912
- }
2913
- // 위치 갱신 (scroll / resize)
2914
- updatePosition() {
2915
- if (this.rafId)
2916
- cancelAnimationFrame(this.rafId);
2917
- this.rafId = requestAnimationFrame(() => {
2918
- if (!this.parentRef || !this.wrapper)
2919
- return;
2920
- const parentRect = this.parentRef.getBoundingClientRect();
2921
- const wrapperRect = this.wrapper.getBoundingClientRect();
2922
- const viewport = {
2923
- width: window.innerWidth,
2924
- height: window.innerHeight,
2925
- };
2926
- let top = parentRect.bottom + window.scrollY + this.offset[1];
2927
- let left = parentRect.left + window.scrollX + this.offset[0];
2928
- // 화면 상하단 넘어갈 시 반전
2929
- if (parentRect.bottom + wrapperRect.height + this.offset[1] > viewport.height) {
2930
- top = parentRect.top + window.scrollY - wrapperRect.height - this.offset[1];
2931
- }
2932
- if (top < window.scrollY) {
2933
- top = parentRect.bottom + window.scrollY + this.offset[1];
2934
- }
2935
- // 화면 좌우측 넘어갈 시 반전
2936
- if (parentRect.left + wrapperRect.width + this.offset[0] > viewport.width) {
2937
- left = parentRect.right + window.scrollX - wrapperRect.width - this.offset[0];
2938
- }
2939
- if (left < 0) {
2940
- left = this.offset[0];
2941
- }
2942
- this.wrapper.style.top = `${top}px`;
2943
- this.wrapper.style.left = `${left}px`;
2944
- });
2945
- }
2946
- // parentRef의 이동 / 크기변경 감지
2947
- observeParent() {
2948
- if (!this.parentRef)
2949
- return;
2950
- this.resizeObserver = new ResizeObserver(() => this.updatePosition());
2951
- this.resizeObserver.observe(this.parentRef);
2952
- this.mutationObserver = new MutationObserver(() => this.updatePosition());
2953
- this.mutationObserver.observe(document.body, {
2954
- childList: true,
2955
- subtree: true,
2956
- });
2957
- }
2958
- unobserveParent() {
2959
- this.resizeObserver?.disconnect();
2960
- this.mutationObserver?.disconnect();
2961
- }
2962
- // 외부 클릭 감지
2963
- handleMouseDown(e) {
2964
- this.isInsideClick = !!(this.wrapper && this.wrapper.contains(e.target));
2965
- }
2966
- handleWindowClick(e) {
2967
- if (this.isInsideClick) {
2968
- this.isInsideClick = false;
2969
- return;
2970
- }
2971
- if (this.wrapper?.contains(e.target))
2972
- return;
2973
- this.sdClose.emit();
2974
- }
2975
- render() {
2976
- return index.h("slot", { key: '05a54c512300d0616811e11a795170490feff876' });
2977
- }
2978
- };
2979
-
2980
- const sdRadioGroupCss = () => `sd-radio-group{display:inline-block}sd-radio-group .sd-radio-group{display:flex}sd-radio-group .sd-radio-group--vertical{flex-direction:column;gap:8px}sd-radio-group .sd-radio-group--horizontal{flex-direction:row;align-items:center;gap:20px}sd-radio-group .sd-radio-group__option{width:fit-content;display:flex;align-items:center;gap:8px;font-weight:400;font-size:12px;line-height:20px;cursor:pointer}sd-radio-group .sd-radio-group__option:has(input:disabled){cursor:not-allowed}sd-radio-group .sd-radio-group__option input{position:relative;appearance:none;margin:0;width:16px;height:16px;border:1px solid #888888;border-radius:50%;cursor:pointer;accent-color:#0075ff;background-color:white}sd-radio-group .sd-radio-group__option input:checked{border-color:#0075ff;background-color:white}sd-radio-group .sd-radio-group__option input:checked::before{content:"";position:absolute;top:50%;left:50%;transform:translate(-50%, -50%);width:10px;height:10px;border-radius:50%;background-color:#0075ff}sd-radio-group .sd-radio-group__option input:disabled{cursor:not-allowed;border-color:#cccccc;background-color:#eeeeee}sd-radio-group .sd-radio-group__option input:disabled:checked::before{background-color:#cccccc}sd-radio-group .sd-radio-group__option input:not(:disabled):hover{border-color:#0075ff;background-color:#d9eaff}sd-radio-group .sd-radio-group__label{font-size:12px;color:#333333;line-height:20px;user-select:none}sd-radio-group .sd-radio-group__option--disabled{cursor:not-allowed}sd-radio-group .sd-radio-group__option--disabled .sd-radio-group__label{color:#888888}`;
2981
-
2982
- const SdRadioGroup = class {
2983
- constructor(hostRef) {
2984
- index.registerInstance(this, hostRef);
2985
- this.sdChange = index.createEvent(this, "sdChange");
2986
- }
2987
- value;
2988
- radioOptions = [];
2989
- direction = 'vertical';
2990
- disabled = false;
2991
- name;
2992
- selectedValue;
2993
- sdChange;
2994
- componentWillLoad() {
2995
- if (this.value) {
2996
- this.selectedValue = this.value;
2997
- }
2998
- }
2999
- valueChanged(newValue) {
3000
- this.selectedValue = newValue;
3001
- }
3002
- handleRadioChange = (optionValue, optionDisabled) => {
3003
- if (this.disabled || optionDisabled)
3004
- return;
3005
- this.selectedValue = optionValue;
3006
- this.value = optionValue;
3007
- this.sdChange.emit(optionValue);
3008
- };
3009
- isOptionSelected(option) {
3010
- return this.selectedValue === option.value;
3011
- }
3012
- isOptionDisabled(option) {
3013
- return this.disabled || !!option.disabled;
3014
- }
3015
- getRadioClasses(option) {
3016
- const classes = [
3017
- 'sd-radio-group__option',
3018
- this.isOptionSelected(option)
3019
- ? 'sd-radio-group__option--selected'
3020
- : 'sd-radio-group__option--unselected',
3021
- ];
3022
- if (this.isOptionDisabled(option)) {
3023
- classes.push('sd-radio-group__option--disabled');
3024
- }
3025
- return classes.join(' ');
3026
- }
3027
- getGroupClasses() {
3028
- const classes = ['sd-radio-group', `sd-radio-group--${this.direction}`];
3029
- return classes.join(' ');
3030
- }
3031
- render() {
3032
- const groupName = this.name || `sd-radio-group-${Math.random().toString(36).substring(2, 11)}`;
3033
- return (index.h("div", { key: 'c66984dc882990512082493a67df0d7cc6daea99', class: this.getGroupClasses(), role: "radiogroup", "aria-disabled": this.disabled.toString() }, this.radioOptions.map((option, index$1) => {
3034
- const isSelected = this.isOptionSelected(option);
3035
- const isDisabled = this.isOptionDisabled(option);
3036
- return (index.h("label", { key: `radio-${index$1}`, class: this.getRadioClasses(option), role: "radio", "aria-checked": isSelected.toString(), "aria-disabled": isDisabled.toString(), "aria-label": option.label || 'radio option' }, index.h("input", { type: "radio", name: groupName, value: option.value.toString(), checked: isSelected, disabled: isDisabled, onInput: () => this.handleRadioChange(option.value, option.disabled) }), option.label && index.h("span", { class: "sd-radio-group__label" }, option.label)));
3037
- })));
3038
- }
3039
- static get watchers() { return {
3040
- "value": ["valueChanged"]
3041
- }; }
3042
- };
3043
- SdRadioGroup.style = sdRadioGroupCss();
3044
-
3045
- const sdSelectCss = () => `.sd-select__dropdown{overflow-y:auto;overflow-x:hidden;scroll-behavior:smooth}.sd-select__dropdown::-webkit-scrollbar{opacity:0;background:#e5e5e5}.sd-select__dropdown::-webkit-scrollbar:horizontal{height:8px}.sd-select__dropdown::-webkit-scrollbar:vertical{width:8px}.sd-select__dropdown::-webkit-scrollbar-thumb{height:80px;background-color:#cccccc;border-radius:4px}.sd-select__dropdown::-webkit-scrollbar-track{background-color:transparent}.sd-select__dropdown .sd-select__option-placeholder{height:48px;display:flex;align-items:center;padding:8px 16px;font-size:12px;line-height:0;text-align:left;color:#888888}sd-select{display:inline-flex;width:fit-content;height:fit-content}sd-select *:focus,sd-select *:focus-visible,sd-select *:focus-within{outline:none !important}sd-select .sd-select{display:flex;width:var(--select-width, 200px);height:28px;position:relative;color:#333333;cursor:pointer;user-select:none;border:1px solid #aaaaaa;border-radius:4px;background-color:white}sd-select .sd-select:hover:not(.sd-select--disabled){background:#f6f6f6}sd-select .sd-select.sd-select--disabled{cursor:not-allowed;background-color:#eeeeee;border-color:#cccccc}sd-select .sd-select.sd-select--disabled .sd-select__label{border-right:1px solid #cccccc}sd-select .sd-select.sd-select--disabled .sd-select__trigger{color:#888888}sd-select .sd-select.sd-select--disabled .sd-select__trigger:focus,sd-select .sd-select.sd-select--disabled .sd-select__trigger:focus-visible,sd-select .sd-select.sd-select--disabled .sd-select__trigger:focus-within{outline:none !important}sd-select .sd-select__label{font-size:12px;line-height:20px;font-weight:500;color:#333333;padding:4px 12px;border-right:1px solid #cccccc;border-radius:4px 0 0 4px;background-color:#f6f6f6;display:inline-block;white-space:nowrap}sd-select .sd-select__container{position:relative;width:100%;display:flex}sd-select .sd-select__container .sd-select__trigger{padding:4px 20px 4px 12px;display:flex;width:100%;align-items:center}sd-select .sd-select__container .sd-select__trigger .sd-select__value{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:20px;font-size:12px;font-weight:400;text-align:left}sd-select .sd-select__container .sd-select__trigger .sd-select__clear{margin:0 4px;width:8px;height:8px;background-color:transparent;outline:none;border:none}sd-select .sd-select__container .sd-select__arrow{position:absolute;top:8px;right:8px;width:12px;height:12px;color:#888888;transition:transform 0.3s ease}sd-select .sd-select__container .sd-select__arrow--open{transform:rotate(180deg)}.sd-select__dropdown{width:var(--select-dropdown-width, 200px);max-height:var(--select-dropdown-height, 260px);padding-bottom:2px;background-color:white;box-shadow:2px 2px 12px 2px rgba(0, 0, 0, 0.1);border-radius:4px;overflow-y:auto;color:#333333;display:flex;flex-direction:column}`;
3046
-
3047
- const SdSelect = class extends selectKeyboardNavigation.BaseDropdownEvent {
3048
- constructor(hostRef) {
3049
- super();
3050
- index.registerInstance(this, hostRef);
3051
- this.sdChange = index.createEvent(this, "sdChange");
3052
- this.dropDownShow = index.createEvent(this, "dropDownShow");
3053
- }
3054
- get el() { return index.getElement(this); }
3055
- // props
3056
- value = null;
3057
- label = '';
3058
- options = [];
3059
- placeholder = '선택';
3060
- optionPlaceholder = '옵션이 없습니다.';
3061
- width = '200px';
3062
- dropdownHeight = '260px';
3063
- disabled = false;
3064
- clearable = false;
3065
- searchable = false;
3066
- // props - custom slots
3067
- optionRenderer;
3068
- // states
3069
- filteredOptions = this.options;
3070
- isOpen = false;
3071
- searchText = null;
3072
- itemIndex = -1;
3073
- isScrolled = false;
3074
- // events
3075
- sdChange;
3076
- dropDownShow;
3077
- selectRef;
3078
- searchRef;
3079
- optionRef;
3080
- dropdownRef;
3081
- async open() {
3082
- this.isOpen = true;
3083
- }
3084
- valueChanged() {
3085
- const selectedOption = this.getSelectedOption();
3086
- this.sdChange?.emit({ value: selectedOption?.value || null, option: selectedOption || null });
3087
- }
3088
- optionsChanged() {
3089
- this.filteredOptions = this.options;
3090
- this.filterOptions();
3091
- }
3092
- searchTextChanged() {
3093
- this.filterOptions();
3094
- }
3095
- async itemIndexChanged(newIndex, oldIndex) {
3096
- if (this.searchable) {
3097
- const searchInput = await this.getNativeInputElement();
3098
- if (this.itemIndex === -1) {
3099
- searchInput?.focus({ preventScroll: true });
3100
- return;
3101
- }
3102
- else if (searchInput?.matches(':focus')) {
3103
- searchInput?.blur();
3104
- }
3105
- }
3106
- const optionElements = this.dropdownRef?.querySelectorAll('.sd-select__dropdown sd-select-option') || [];
3107
- const currentItem = optionElements?.[this.itemIndex];
3108
- if (!currentItem || !this.isOpen)
3109
- return;
3110
- this.optionRef = currentItem;
3111
- const isOptionDisabled = await this.optionRef.isDisabled();
3112
- if (isOptionDisabled) {
3113
- newIndex > oldIndex ? this.itemIndex++ : this.itemIndex--;
3114
- return;
3115
- }
3116
- this.scrollToOption(currentItem);
3117
- }
3118
- componentWillLoad() {
3119
- // props가 모두 설정된 후에 실행되므로 올바른 options 값을 가져올 수 있음
3120
- this.filteredOptions = this.options;
3121
- this.initializeEvent(); // global dropdown Manager에 등록 + 이벤트 핸들러 초기화
3122
- }
3123
- disconnectedCallback() {
3124
- this.cleanupEvent(); // global dropdown Manager에서 제거 + 이벤트 정리
3125
- }
3126
- async isOpenChanged() {
3127
- // Base class의 이벤트 관리 호출 - 다른 select와의 이벤트 충돌 방지
3128
- this.onDropdownToggle(this.isOpen);
3129
- const selectedOption = this.getSelectedOption();
3130
- if (!selectedOption) {
3131
- this.itemIndex = /* this.searchable ? */ -1 /* : 0 */;
3132
- }
3133
- else {
3134
- this.itemIndex = this.options.indexOf(selectedOption);
3135
- }
3136
- this.dropDownShow?.emit({ isOpen: this.isOpen });
3137
- if (this.isOpen === false)
3138
- return;
3139
- await new Promise(resolve => setTimeout(resolve, 10));
3140
- const optionElements = this.dropdownRef?.querySelectorAll('.sd-select__dropdown sd-select-option') || [];
3141
- const currentItem = optionElements?.[this.itemIndex];
3142
- if (this.searchable) {
3143
- const searchInput = await this.getNativeInputElement();
3144
- searchInput?.focus({ preventScroll: true });
3145
- }
3146
- if (!currentItem)
3147
- return;
3148
- await new Promise(resolve => setTimeout(resolve, 10));
3149
- this.scrollToOption(currentItem);
3150
- }
3151
- handleDocumentClick(event) {
3152
- if (!this.selectRef?.contains(event.target)) {
3153
- this.isOpen = false;
3154
- }
3155
- }
3156
- handleDocumentKeydown(keyboardEvent) {
3157
- keyboardEvent.stopPropagation();
3158
- const targetKey = ['ArrowDown', 'ArrowUp', 'Enter', 'Escape'];
3159
- if (!targetKey.includes(keyboardEvent.key))
3160
- return;
3161
- keyboardEvent.preventDefault();
3162
- switch (keyboardEvent.key) {
3163
- case 'ArrowDown':
3164
- case 'ArrowUp':
3165
- const keyboardNavigation = new selectKeyboardNavigation.SelectKeyboardNavigation(this.searchable, this.filteredOptions);
3166
- const nextIndex = keyboardNavigation.getNextIndex(this.itemIndex, keyboardEvent.key);
3167
- this.itemIndex = nextIndex;
3168
- break;
3169
- case 'Enter':
3170
- const selectedOption = this.filteredOptions[this.itemIndex];
3171
- if (selectedOption && !selectedOption.disabled) {
3172
- this.value = selectedOption.value;
3173
- this.searchText = null;
3174
- this.isOpen = false;
3175
- }
3176
- break;
3177
- case 'Escape':
3178
- this.isOpen = false;
3179
- break;
3180
- }
3181
- }
3182
- // closeDropdown 메서드 구현 (Manager에서 호출됨)
3183
- closeDropdown() {
3184
- this.isOpen = false;
3185
- }
3186
- // event handlers
3187
- handleTriggerClick = (event) => {
3188
- event.stopPropagation();
3189
- if (!this.disabled) {
3190
- this.isOpen = !this.isOpen;
3191
- this.dropDownShow?.emit({ isOpen: this.isOpen });
3192
- }
3193
- };
3194
- handleOptionClick = (detail) => {
3195
- const { option, event } = detail;
3196
- event.stopPropagation();
3197
- if (!option.disabled) {
3198
- this.value = option.value;
3199
- this.isOpen = false;
3200
- }
3201
- };
3202
- filterOptions() {
3203
- if (!this.searchText || this.searchText.trim() === '') {
3204
- // 검색어가 없으면 전체 옵션 표시
3205
- this.filteredOptions = this.options;
3206
- }
3207
- else {
3208
- // 검색어가 있으면 필터링
3209
- this.filteredOptions = this.options.filter(option => option.label.toLowerCase().includes(this.searchText.toLowerCase()));
3210
- }
3211
- }
3212
- getSelectedOption() {
3213
- return this.options.find(option => option.value === this.value);
3214
- }
3215
- handleDropdownScroll = (event) => {
3216
- const target = event.target;
3217
- const scrollTop = target.scrollTop;
3218
- // 스크롤이 조금이라도 되면 그림자 표시
3219
- this.isScrolled = scrollTop > 0;
3220
- };
3221
- async getNativeInputElement() {
3222
- if (this.searchRef) {
3223
- return this.searchRef.getNativeElement();
3224
- }
3225
- return null;
3226
- }
3227
- scrollToOption(optionElement) {
3228
- if (!this.dropdownRef || !optionElement)
3229
- return;
3230
- const dropdown = this.dropdownRef;
3231
- const optionTop = optionElement.offsetTop;
3232
- const optionHeight = optionElement.offsetHeight;
3233
- const dropdownScrollTop = dropdown.scrollTop;
3234
- const dropdownHeight = dropdown.clientHeight;
3235
- const searchContainer = dropdown.querySelector('.sd-select__search-container');
3236
- const searchOffset = searchContainer ? searchContainer.offsetHeight : 0;
3237
- const visibleTop = dropdownScrollTop + searchOffset;
3238
- const visibleBottom = dropdownScrollTop + dropdownHeight;
3239
- if (optionTop < visibleTop) {
3240
- dropdown.scrollTop = optionTop - searchOffset;
3241
- }
3242
- else if (optionTop + optionHeight > visibleBottom) {
3243
- dropdown.scrollTop = optionTop + optionHeight - dropdownHeight + searchOffset;
3244
- }
3245
- }
3246
- // render method
3247
- render() {
3248
- const style = {
3249
- '--select-width': this.width || '200px',
3250
- '--select-dropdown-height': this.dropdownHeight || '260px',
3251
- };
3252
- return (index.h(index.Host, { key: '8f90fd48d8e20b97d35a047d15507d3116c79b23', style: style }, index.h("div", { key: '91bc6bab24b9d99ab595357ec5591b56510ed161', class: {
3253
- 'sd-select': true,
3254
- 'sd-select--open': this.isOpen,
3255
- 'sd-select--disabled': this.disabled,
3256
- }, ref: el => (this.selectRef = el) }, this.renderLabel(this.label), index.h("div", { key: 'a2ceb7cc71b13887f55f3a44e0f1babd4be388b9', class: "sd-select__container" }, this.renderTrigger(), this.renderDropdown()))));
3257
- }
3258
- renderLabel(label) {
3259
- if (!label)
3260
- return null;
3261
- return index.h("label", { class: "sd-select__label" }, label);
3262
- }
3263
- renderTrigger() {
3264
- const selectedOption = this.getSelectedOption();
3265
- return (index.h("div", { class: "sd-select__trigger", tabindex: this.disabled ? -1 : 0, onClick: this.handleTriggerClick }, index.h("span", { class: "sd-select__value" }, selectedOption ? selectedOption.label : this.placeholder), this.clearable && selectedOption && !this.disabled && (index.h("sd-icon", { key: "clear-icon", name: "close", size: 10, color: "#888", class: "sd-select__clear", onClick: event => {
3266
- event.stopPropagation();
3267
- this.value = null;
3268
- } })), index.h("sd-icon", { key: "arrow-icon", name: "arrowDown", color: "#888", class: { 'sd-select__arrow': true, 'sd-select__arrow--open': this.isOpen } })));
3269
- }
3270
- renderDropdown() {
3271
- const style = {
3272
- '--select-dropdown-width': this.width || '200px',
3273
- '--select-dropdown-height': this.dropdownHeight || '260px',
3274
- };
3275
- if (this.isOpen === false)
3276
- return null;
3277
- return (index.h("sd-portal", { open: this.isOpen, parentRef: this.selectRef, onSdClose: this.closeDropdown }, index.h("div", { class: "sd-select__dropdown", style: style, onScroll: this.handleDropdownScroll, ref: el => (this.dropdownRef = el) }, this.searchable && (index.h("sd-select-search-input", { ref: el => (this.searchRef = el), isScrolled: this.isScrolled, searchText: this.searchText, onSdSearchInput: (event) => (this.searchText = event.detail || ''), onSdSearchFocus: () => (this.itemIndex = -1) })), this.filteredOptions.length > 0 ? (this.filteredOptions.map((option, index$1) => (index.h("slot", { name: `option-${option.value}` }, index.h("sd-select-option", { option: option, index: index$1, isSelected: option.value === this.value, isFocused: index$1 === this.itemIndex, onOptionClick: ({ detail }) => this.handleOptionClick(detail) }))))) : (index.h("slot", { name: "option-placeholder" }, index.h("div", { class: 'sd-select__option-placeholder' }, this.optionPlaceholder))))));
3278
- }
3279
- static get watchers() { return {
3280
- "value": ["valueChanged"],
3281
- "options": ["optionsChanged"],
3282
- "searchText": ["searchTextChanged"],
3283
- "itemIndex": ["itemIndexChanged"],
3284
- "isOpen": ["isOpenChanged"]
3285
- }; }
3286
- };
3287
- SdSelect.style = sdSelectCss();
3288
-
3289
- const sdSelectMultipleGroupCss = () => `.sd-select-multiple-group__dropdown{overflow-y:auto;overflow-x:hidden;scroll-behavior:smooth}.sd-select-multiple-group__dropdown::-webkit-scrollbar{opacity:0;background:#e5e5e5}.sd-select-multiple-group__dropdown::-webkit-scrollbar:horizontal{height:8px}.sd-select-multiple-group__dropdown::-webkit-scrollbar:vertical{width:8px}.sd-select-multiple-group__dropdown::-webkit-scrollbar-thumb{height:80px;background-color:#cccccc;border-radius:4px}.sd-select-multiple-group__dropdown::-webkit-scrollbar-track{background-color:transparent}.sd-select-multiple-group__dropdown .sd-select-multiple-group__option-placeholder{height:48px;display:flex;align-items:center;padding:8px 16px;font-size:12px;line-height:0;text-align:left;color:#888888}sd-select-multiple-group{display:inline-block;height:fit-content}sd-select-multiple-group:focus,sd-select-multiple-group:focus-visible,sd-select-multiple-group:focus-within{outline:none !important}sd-select-multiple-group .sd-select-multiple-group{display:flex;flex-wrap:nowrap;width:var(--select-width, 200px);cursor:pointer;user-select:none;border:1px solid #aaaaaa;border-radius:4px;background-color:white;color:#333333}sd-select-multiple-group .sd-select-multiple-group:hover:not(.sd-select-multiple-group--disabled){background:#f6f6f6}sd-select-multiple-group .sd-select-multiple-group.sd-select-multiple-group--disabled{cursor:not-allowed;background-color:#eeeeee;border-color:#cccccc}sd-select-multiple-group .sd-select-multiple-group.sd-select-multiple-group--disabled .sd-select-multiple-group__label{border-right:1px solid #cccccc}sd-select-multiple-group .sd-select-multiple-group.sd-select-multiple-group--disabled .sd-select-multiple-group__trigger{color:#888888}sd-select-multiple-group .sd-select-multiple-group.sd-select-multiple-group--disabled .sd-select-multiple-group__trigger:focus,sd-select-multiple-group .sd-select-multiple-group.sd-select-multiple-group--disabled .sd-select-multiple-group__trigger:focus-visible,sd-select-multiple-group .sd-select-multiple-group.sd-select-multiple-group--disabled .sd-select-multiple-group__trigger:focus-within{outline:none !important}sd-select-multiple-group .sd-select-multiple-group__label{font-size:12px;font-weight:500;color:#333333;padding:4px 12px;border-right:1px solid #cccccc;border-radius:4px 0 0 4px;background-color:#f6f6f6}sd-select-multiple-group .sd-select-multiple-group__container{position:relative;width:100%;display:flex}sd-select-multiple-group .sd-select-multiple-group__container .sd-select-multiple-group__trigger{padding:4px 20px 4px 12px;display:flex;width:100%;align-items:center}sd-select-multiple-group .sd-select-multiple-group__container .sd-select-multiple-group__trigger .sd-select-multiple-group__value{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:20px;font-size:12px;font-weight:400}sd-select-multiple-group .sd-select-multiple-group__container .sd-select-multiple-group__trigger .sd-select-multiple-group__clear{margin:0 4px;width:8px;height:8px;background-color:transparent;outline:none;border:none}sd-select-multiple-group .sd-select-multiple-group__container .sd-select-multiple-group__arrow{position:absolute;top:8px;right:8px;width:12px;height:12px;color:#888888;transition:transform 0.3s ease}sd-select-multiple-group .sd-select-multiple-group__container .sd-select-multiple-group__arrow--open{transform:rotate(180deg)}.sd-select-multiple-group__dropdown{width:var(--select-width, 200px);max-height:var(--select-dropdown-height, 260px);padding-bottom:2px;background-color:white;box-shadow:2px 2px 12px 2px rgba(0, 0, 0, 0.1);border-radius:4px;overflow-y:auto;color:#333333;opacity:0.5;transition:opacity 0.15s ease-in}.sd-select-multiple-group__dropdown--ready{opacity:1}`;
3290
-
3291
- const SdSelectMultipleGroup = class extends selectKeyboardNavigation.BaseDropdownEvent {
3292
- constructor(hostRef) {
3293
- super();
3294
- index.registerInstance(this, hostRef);
3295
- this.sdChange = index.createEvent(this, "sdChange");
3296
- this.dropDownShow = index.createEvent(this, "dropDownShow");
3297
- }
3298
- get el() { return index.getElement(this); }
3299
- // props
3300
- value = null;
3301
- label = '';
3302
- options = [];
3303
- placeholder = '선택';
3304
- optionPlaceholder = '옵션이 없습니다.';
3305
- width = '200px';
3306
- dropdownHeight = '260px';
3307
- disabled = false;
3308
- clearable = false;
3309
- searchable = false;
3310
- useCheckbox = false;
3311
- useAll = false;
3312
- allCheckedLabel = '전체';
3313
- allCheckOptionLabel = '전체';
3314
- // props - custom styles
3315
- containerStyle = {};
3316
- triggerStyle = {};
3317
- dropdownStyle = {};
3318
- optionStyle = {};
3319
- labelStyle = {};
3320
- // props - custom slots
3321
- optionRenderer;
3322
- // states
3323
- filteredOptions = this.options;
3324
- isOpen = false;
3325
- searchText = null;
3326
- itemIndex = -1;
3327
- isScrolled = false;
3328
- isDropdownReady = false;
3329
- // events
3330
- sdChange;
3331
- dropDownShow;
3332
- selectRef;
3333
- searchRef;
3334
- optionRef;
3335
- dropdownRef;
3336
- valueChanged() {
3337
- this.sdChange?.emit(this.value);
3338
- }
3339
- optionsChanged() {
3340
- this.filteredOptions = this.options;
3341
- this.filterOptions();
3342
- }
3343
- searchTextChanged() {
3344
- this.filterOptions();
3345
- }
3346
- async itemIndexChanged(newIndex, oldIndex) {
3347
- if (this.searchable) {
3348
- const searchInput = await this.getNativeInputElement();
3349
- if (this.itemIndex === -1) {
3350
- searchInput?.focus({ preventScroll: true });
3351
- return;
3352
- }
3353
- else if (searchInput?.matches(':focus')) {
3354
- searchInput?.blur();
3355
- }
3356
- }
3357
- const optionElements = Array.from(this.dropdownRef?.querySelectorAll('sd-select-option-group') || []);
3358
- // useAll 사용시 "전체" 옵션 포함한 인덱스 사용
3359
- const actualIndex = this.useAll ? this.itemIndex + 1 : this.itemIndex;
3360
- const currentItem = optionElements?.[actualIndex];
3361
- if (!currentItem || !this.isOpen)
3362
- return;
3363
- this.optionRef = currentItem;
3364
- const isOptionDisabled = await this.optionRef.isDisabled();
3365
- if (isOptionDisabled) {
3366
- newIndex > oldIndex ? this.itemIndex++ : this.itemIndex--;
3367
- return;
3368
- }
3369
- this.scrollToOption(currentItem);
3370
- }
3371
- async isOpenChanged() {
3372
- // Base class의 이벤트 관리 호출 - 다른 select와의 이벤트 충돌 방지
3373
- this.onDropdownToggle(this.isOpen);
3374
- this.dropDownShow?.emit({ isOpen: this.isOpen });
3375
- this.isDropdownReady = false;
3376
- if (this.isOpen === false) {
3377
- return;
3378
- }
3379
- // DOM 렌더링을 기다리기 위해 이중 requestAnimationFrame 사용 - (레이아웃/스타일 계산 - 페인트 이후)
3380
- requestAnimationFrame(() => {
3381
- requestAnimationFrame(async () => {
3382
- const selectedOptions = this.getSelectedOption();
3383
- // 선택된 옵션이 있으면 첫 번째 선택된 항목으로 스크롤
3384
- if (selectedOptions && selectedOptions.length > 0) {
3385
- const selectedIndex = this.options.indexOf(selectedOptions[0]);
3386
- const optionElements = Array.from(this.dropdownRef?.querySelectorAll('sd-select-option-group') || []);
3387
- // useAll 사용시 "전체" 옵션 포함한 인덱스 사용
3388
- const actualIndex = this.useAll ? selectedIndex + 1 : selectedIndex;
3389
- // 선택된 옵션이 화면 가운데에 오도록 index 조정
3390
- const targetIndex = Math.min(actualIndex + 4, optionElements.length - 1);
3391
- const currentItem = optionElements?.[targetIndex];
3392
- if (currentItem) {
3393
- this.scrollToOption(currentItem);
3394
- }
3395
- }
3396
- this.isDropdownReady = true;
3397
- if (this.searchable) {
3398
- const searchInput = await this.getNativeInputElement();
3399
- if (searchInput) {
3400
- requestAnimationFrame(() => {
3401
- searchInput.focus({ preventScroll: true });
3402
- });
3403
- }
3404
- }
3405
- });
3406
- });
3407
- }
3408
- async open() {
3409
- await new Promise(resolve => setTimeout(resolve, 0));
3410
- this.isOpen = true;
3411
- }
3412
- componentWillLoad() {
3413
- // props가 모두 설정된 후에 실행되므로 올바른 options 값을 가져올 수 있음
3414
- this.filteredOptions = this.options;
3415
- this.initializeEvent(); // global dropdown Manager에 등록 + 이벤트 핸들러 초기화
3416
- }
3417
- disconnectedCallback() {
3418
- this.cleanupEvent(); // global dropdown Manager에서 제거 + 이벤트 정리
3419
- }
3420
- handleDocumentClick(event) {
3421
- if (!this.selectRef?.contains(event.target)) {
3422
- this.isOpen = false;
3423
- }
3424
- }
3425
- handleDocumentKeydown(keyboardEvent) {
3426
- keyboardEvent.stopPropagation();
3427
- const targetKey = ['ArrowDown', 'ArrowUp', 'Enter', 'Escape'];
3428
- if (!targetKey.includes(keyboardEvent.key))
3429
- return;
3430
- keyboardEvent.preventDefault();
3431
- switch (keyboardEvent.key) {
3432
- case 'ArrowDown':
3433
- case 'ArrowUp':
3434
- const keyboardNavigation = new selectKeyboardNavigation.SelectKeyboardNavigation(this.searchable, this.filteredOptions);
3435
- const nextIndex = keyboardNavigation.getNextIndex(this.itemIndex, keyboardEvent.key);
3436
- this.itemIndex = nextIndex;
3437
- break;
3438
- case 'Enter':
3439
- const selectedOption = this.filteredOptions[this.itemIndex];
3440
- if (selectedOption && !selectedOption.disabled) {
3441
- this.handleOptionSelection(selectedOption);
3442
- }
3443
- break;
3444
- case 'Escape':
3445
- this.isOpen = false;
3446
- break;
3447
- }
3448
- }
3449
- // event handlers
3450
- handleTriggerClick = (event) => {
3451
- event.stopPropagation();
3452
- if (!this.disabled) {
3453
- this.isOpen = !this.isOpen;
3454
- this.dropDownShow?.emit({ isOpen: this.isOpen });
3455
- }
3456
- };
3457
- handleAllOptionClick = (detail) => {
3458
- if (detail.isSelected) {
3459
- // 이미 선택된 옵션인 경우, 선택 해제
3460
- const filterDisabledOptions = this.filteredOptions.filter(opt => opt.type === 'item' && !opt.disabled);
3461
- this.value =
3462
- this.value?.filter(selected => !filterDisabledOptions.some(opt => opt.value === selected.value)) || this.value;
3463
- }
3464
- else {
3465
- // 새로운 옵션 선택
3466
- const valueSet = new Set([
3467
- ...(this.value || []),
3468
- ...this.filteredOptions.filter(opt => opt.type === 'item' && !opt.disabled),
3469
- ]);
3470
- this.value = Array.from(valueSet);
3471
- }
3472
- };
3473
- handleOptionClick = (detail) => {
3474
- const { option, event } = detail;
3475
- event.stopPropagation();
3476
- if (option.type === 'group')
3477
- this.handleGroupOptionClick(detail);
3478
- if (option.type === 'subgroup')
3479
- this.handleSubGroupOptionClick(detail);
3480
- if (option.type === 'item')
3481
- this.handleOptionSelection(option);
3482
- };
3483
- handleGroupOptionClick = (detail) => {
3484
- const { option, isSelected } = detail;
3485
- const childOptions = this.filteredOptions.filter(opt => opt.parent === option.value && !opt.disabled);
3486
- childOptions.forEach(subgroup => {
3487
- this.handleSubGroupOptionClick({
3488
- option: subgroup,
3489
- isSelected: isSelected || isSelected === null,
3490
- });
3491
- });
3492
- };
3493
- handleSubGroupOptionClick = (detail) => {
3494
- const { option, isSelected } = detail;
3495
- const childOptions = this.filteredOptions.filter(opt => opt.parent === option.value && !opt.disabled);
3496
- if (isSelected || isSelected === null) {
3497
- // 모든 자식 옵션이 선택된 경우, 모두 선택 해제
3498
- this.value =
3499
- this.value?.filter(selected => !childOptions.some(child => child.value === selected.value)) ||
3500
- null;
3501
- }
3502
- else {
3503
- // 일부 또는 전체 자식 옵션이 선택되지 않은 경우, 모두 선택
3504
- const newSelections = childOptions.filter(child => !this.value?.some(selected => selected.value === child.value));
3505
- this.value = [...(this.value || []), ...newSelections];
3506
- }
3507
- };
3508
- filterOptions() {
3509
- if (!this.searchText || this.searchText.trim() === '') {
3510
- // 검색어가 없으면 전체 옵션 표시
3511
- this.filteredOptions = this.options;
3512
- return;
3513
- }
3514
- const searchTerm = this.searchText.toLowerCase();
3515
- const matchedOptions = new Set();
3516
- // 1. 직접 매칭되는 옵션들 찾기
3517
- this.options.forEach(option => {
3518
- if (option.label.toLowerCase().includes(searchTerm)) {
3519
- matchedOptions.add(option);
3520
- // 매칭된 옵션의 상위 그룹들도 포함
3521
- this.addParentGroups(option, matchedOptions);
3522
- }
3523
- });
3524
- // 2. Set을 배열로 변환하고 원본 순서 유지
3525
- this.filteredOptions = this.options.filter(option => matchedOptions.has(option));
3526
- }
3527
- addParentGroups(option, matchedSet) {
3528
- if (!option.parent)
3529
- return;
3530
- const parentOption = this.options.find(opt => opt.value === option.parent);
3531
- if (parentOption && !matchedSet.has(parentOption)) {
3532
- matchedSet.add(parentOption);
3533
- // 재귀적으로 상위 그룹들도 추가
3534
- this.addParentGroups(parentOption, matchedSet);
3535
- }
3536
- }
3537
- getSelectedOption() {
3538
- return this.options.filter(option => this.value?.includes(option));
3539
- }
3540
- handleDropdownScroll = (event) => {
3541
- const target = event.target;
3542
- const scrollTop = target.scrollTop;
3543
- // 스크롤이 조금이라도 되면 그림자 표시
3544
- this.isScrolled = scrollTop > 0;
3545
- };
3546
- async getNativeInputElement() {
3547
- if (this.searchRef) {
3548
- return this.searchRef.getNativeElement();
3549
- }
3550
- return null;
3551
- }
3552
- handleOptionSelection = (option) => {
3553
- if (!option || option.disabled)
3554
- return;
3555
- const isAlreadySelected = this.value?.some(opt => opt.value === option.value);
3556
- if (isAlreadySelected) {
3557
- // 이미 선택된 옵션인 경우, 선택 해제
3558
- this.value = this.value?.filter(opt => opt.value !== option.value) || null;
3559
- }
3560
- else {
3561
- // 새로운 옵션 선택
3562
- this.value = [...(this.value || []), option];
3563
- }
3564
- };
3565
- getAllItemsUnderOption(parentOption, includeDisabled = false) {
3566
- const filterChildrenWithParent = (option) => option.parent === parentOption.value && (includeDisabled || !option.disabled);
3567
- if (parentOption.type === 'subgroup') {
3568
- return this.filteredOptions.filter(option => filterChildrenWithParent(option) && option.type === 'item');
3569
- }
3570
- const allItems = [];
3571
- const childOptions = this.filteredOptions.filter(filterChildrenWithParent);
3572
- const subgroupOptions = childOptions.filter(option => option.type === 'subgroup');
3573
- subgroupOptions.forEach(subgroup => {
3574
- const itemsUnderSubgroup = this.filteredOptions.filter(option => option.parent === subgroup.value &&
3575
- option.type === 'item' &&
3576
- (includeDisabled ? true : !option.disabled));
3577
- allItems.push(...itemsUnderSubgroup);
3578
- });
3579
- const directItems = childOptions.filter(option => option.type === 'item');
3580
- allItems.push(...directItems);
3581
- return allItems;
3582
- }
3583
- isAllChildrenSelected(groupOption) {
3584
- const allItems = this.getAllItemsUnderOption(groupOption);
3585
- if (allItems.length === 0)
3586
- return false;
3587
- const selectedItems = allItems.filter(item => this.value?.some(selected => selected.value === item.value));
3588
- if (selectedItems.length === allItems.length)
3589
- return true;
3590
- if (selectedItems.length > 0)
3591
- return null;
3592
- return false;
3593
- }
3594
- getChildrenOptions(parentOption) {
3595
- const allItems = this.getAllItemsUnderOption(parentOption, true);
3596
- const selectedCount = allItems.filter(item => this.value?.some(val => val.value === item.value)).length;
3597
- return {
3598
- selectedCount,
3599
- totalCount: allItems.length,
3600
- };
3601
- }
3602
- isAllOptionsSelected() {
3603
- if (!this.value || this.value.length === 0)
3604
- return false;
3605
- const selectableItems = this.options.filter(opt => opt.type === 'item' && !opt.disabled);
3606
- if (selectableItems.length === 0)
3607
- return false;
3608
- const selectedValues = new Set(this.value.map(v => v.value));
3609
- return selectableItems.every(option => selectedValues.has(option.value));
3610
- }
3611
- getTriggerLabel() {
3612
- const selectedOption = this.getSelectedOption();
3613
- if (!selectedOption)
3614
- return '선택';
3615
- if (selectedOption.length === 0)
3616
- return this.placeholder;
3617
- const isAllChecked = this.isAllOptionsSelected();
3618
- return isAllChecked
3619
- ? this.allCheckedLabel
3620
- : selectedOption.map(option => option.label).join(', ');
3621
- }
3622
- closeDropdown() {
3623
- this.isOpen = false;
3624
- }
3625
- async scrollToOption(optionElement) {
3626
- if (!this.dropdownRef || !optionElement)
3627
- return;
3628
- requestAnimationFrame(() => {
3629
- const dropdown = this.dropdownRef;
3630
- const optionTop = optionElement.offsetTop;
3631
- const optionHeight = optionElement.offsetHeight;
3632
- const dropdownScrollTop = dropdown.scrollTop;
3633
- const dropdownHeight = dropdown.clientHeight;
3634
- const searchContainer = dropdown.querySelector('.sd-select-multiple-group__search-container');
3635
- const searchOffset = searchContainer ? searchContainer.offsetHeight : 0;
3636
- const visibleContentHeight = dropdownHeight - searchOffset;
3637
- const visibleTop = dropdownScrollTop + searchOffset;
3638
- const visibleBottom = dropdownScrollTop + dropdownHeight;
3639
- if (optionTop < visibleTop) {
3640
- dropdown.scrollTo({ top: optionTop - searchOffset, behavior: 'instant' });
3641
- }
3642
- else if (optionTop + optionHeight > visibleBottom) {
3643
- dropdown.scrollTo({
3644
- top: optionTop + optionHeight - visibleContentHeight - searchOffset,
3645
- behavior: 'instant',
3646
- });
3647
- }
3648
- });
3649
- }
3650
- render() {
3651
- const style = {
3652
- '--select-width': this.width || '200px',
3653
- '--select-dropdown-height': this.dropdownHeight || '260px',
3654
- };
3655
- return (index.h(index.Host, { key: '9b9985d412b87c72d6408acd74f8f120a5918bc2', style: style }, index.h("div", { key: '3e2c08541d14cc31ecf3f2d383ac20804ce809ef', class: {
3656
- 'sd-select-multiple-group': true,
3657
- 'sd-select-multiple-group--open': this.isOpen,
3658
- 'sd-select-multiple-group--disabled': this.disabled,
3659
- }, style: this.containerStyle, ref: el => (this.selectRef = el) }, this.renderLabel(this.label, this.labelStyle), index.h("div", { key: '2eded5c3c25b200bae874e0830ce9433744b2a53', class: "sd-select-multiple-group__container" }, this.renderTrigger(), this.renderDropdown()))));
3660
- }
3661
- renderLabel(label, labelStyle) {
3662
- if (!label)
3663
- return null;
3664
- return (index.h("label", { class: "sd-select-multiple-group__label", style: labelStyle }, label));
3665
- }
3666
- renderTrigger() {
3667
- const selectedOption = this.getSelectedOption();
3668
- return (index.h("div", { class: "sd-select-multiple-group__trigger", tabindex: this.disabled ? -1 : 0, onClick: this.handleTriggerClick, style: this.triggerStyle }, index.h("span", { class: "sd-select-multiple-group__value" }, this.getTriggerLabel()), this.clearable && selectedOption?.length > 0 && !this.disabled && (index.h("sd-icon", { key: "close-icon", name: "close", size: 10, color: "#888", class: "sd-select-multiple-group__clear", onClick: event => {
3669
- event.stopPropagation();
3670
- this.value = null;
3671
- } })), index.h("sd-icon", { key: "arrow-icon", name: "arrowDown", color: "#888", class: {
3672
- 'sd-select-multiple-group__arrow': true,
3673
- 'sd-select-multiple-group__arrow--open': this.isOpen,
3674
- } })));
3675
- }
3676
- renderDropdown() {
3677
- const style = {
3678
- '--select-width': this.width || '200px',
3679
- '--select-dropdown-height': this.dropdownHeight || '260px',
3680
- };
3681
- if (this.isOpen === false)
3682
- return null;
3683
- return (index.h("sd-portal", { open: this.isOpen, parentRef: this.selectRef, onSdClose: this.closeDropdown }, index.h("div", { style: { width: '0', height: '0', overflow: 'visible' } }, index.h("div", { class: {
3684
- 'sd-select-multiple-group__dropdown': true,
3685
- 'sd-select-multiple-group__dropdown--ready': this.isDropdownReady,
3686
- }, style: { ...style, ...this.dropdownStyle }, onScroll: this.handleDropdownScroll, ref: el => (this.dropdownRef = el) }, this.searchable && (index.h("sd-select-search-input", { ref: el => (this.searchRef = el), isScrolled: this.isScrolled, searchText: this.searchText, onSdSearchInput: (event) => (this.searchText = event.detail || ''), onSdSearchFocus: () => (this.itemIndex = -1) })), this.filteredOptions.length > 0 ? (index.h(index.Fragment, null, this.useAll && (index.h("sd-select-option-group", { option: { label: this.allCheckOptionLabel, value: '', type: 'all' }, index: 0, isSelected: this.isAllOptionsSelected(), isFocused: this.itemIndex === 0, optionStyle: this.optionStyle, onOptionClick: ({ detail, }) => this.handleAllOptionClick(detail), useCheckbox: this.useCheckbox, useIndicator: false })), this.filteredOptions.map((option, index$1) => (index.h("slot", { name: `option-${option.value}` }, index.h("sd-select-option-group", { option: option, index: index$1, isSelected: option.type === 'item'
3687
- ? this.value?.some(selected => selected.value === option.value)
3688
- : this.isAllChildrenSelected(option), isFocused: index$1 === this.itemIndex, optionStyle: this.optionStyle, onOptionClick: ({ detail, }) => {
3689
- if (option.type !== 'item' && !this.useCheckbox) {
3690
- return;
3691
- }
3692
- this.handleOptionClick(detail);
3693
- }, useCheckbox: this.useCheckbox, ...(option.type !== 'item' && { countInfo: this.getChildrenOptions(option) }) })))))) : (index.h("slot", { name: "option-placeholder" }, index.h("div", { class: 'sd-select-multiple-group__option-placeholder', style: this.optionStyle }, this.optionPlaceholder)))))));
3694
- }
3695
- static get watchers() { return {
3696
- "value": ["valueChanged"],
3697
- "options": ["optionsChanged"],
3698
- "searchText": ["searchTextChanged"],
3699
- "itemIndex": ["itemIndexChanged"],
3700
- "isOpen": ["isOpenChanged"]
3701
- }; }
3702
- };
3703
- SdSelectMultipleGroup.style = sdSelectMultipleGroupCss();
3704
-
3705
- const sdSelectOptionCss = () => `sd-select-option{display:block;height:fit-content;line-height:0}sd-select-option .sd-select__option{display:flex;padding:4px 12px;font-size:12px;line-height:20px;cursor:pointer}sd-select-option .sd-select__option__checkbox-wrapper{display:flex;width:100%;column-gap:8px;align-items:center;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}sd-select-option .sd-select__option--focused{background-color:#e6f1ff}sd-select-option .sd-select__option--selected:not(:hover):not(.sd-select__option--use-checkbox),sd-select-option .sd-select__option--focused:not(:hover):not(.sd-select__option--use-checkbox){color:#0075ff;font-weight:700}sd-select-option .sd-select__option--disabled{color:#aaaaaa;cursor:not-allowed}sd-select-option .sd-select__option:hover:not(.sd-select__option--disabled){background-color:#0075ff;color:white}`;
3706
-
3707
- const SdSelectOption = class {
3708
- constructor(hostRef) {
3709
- index.registerInstance(this, hostRef);
3710
- this.optionClick = index.createEvent(this, "optionClick");
3711
- }
3712
- get el() { return index.getElement(this); }
3713
- option;
3714
- index;
3715
- isSelected = false;
3716
- isFocused = false;
3717
- optionStyle;
3718
- disabled = false;
3719
- useCheckbox = false;
3720
- isHovered = false;
3721
- async isDisabled() {
3722
- return !!this.option.disabled;
3723
- }
3724
- optionClick;
3725
- handleClick = (event) => {
3726
- event.stopPropagation();
3727
- if (!this.option.disabled && !this.disabled) {
3728
- this.optionClick.emit({
3729
- option: this.option,
3730
- index: this.index,
3731
- event,
3732
- });
3733
- }
3734
- };
3735
- render() {
3736
- return (index.h(index.Host, { key: 'cfb999f7001240e6bd5dc302b24aade477671f74' }, index.h("div", { key: '053e073fee23e99bd23a9b9fa95cb9ddabf9d6bf', class: {
3737
- 'sd-select__option': true,
3738
- 'sd-select__option--selected': this.isSelected,
3739
- 'sd-select__option--disabled': !!this.option.disabled,
3740
- 'sd-select__option--focused': this.isFocused,
3741
- 'sd-select__option--use-checkbox': this.useCheckbox,
3742
- }, onMouseEnter: () => (this.isHovered = true), onMouseLeave: () => (this.isHovered = false), style: this.optionStyle, "data-index": this.index, onClick: this.handleClick }, this.useCheckbox ? (index.h("div", { class: "sd-select__option__checkbox-wrapper" }, index.h("sd-checkbox", { checked: this.isSelected, disabled: this.option.disabled,
3743
- // checkboxStyle={
3744
- // !this.isSelected
3745
- // ? { borderColor: '#888' }
3746
- // : this.isHovered
3747
- // ? { borderColor: 'white' }
3748
- // : { borderColor: '#0075ff' }
3749
- // }
3750
- onClick: e => {
3751
- e.preventDefault();
3752
- this.handleClick(e);
3753
- } }), index.h("span", { class: "sd-select__option-label" }, this.option.label))) : (this.option.label))));
3754
- }
3755
- };
3756
- SdSelectOption.style = sdSelectOptionCss();
3757
-
3758
- const sdSelectOptionGroupCss = () => `sd-select-option-group{display:block;height:fit-content}sd-select-option-group .sd-select__option-group{display:flex;padding:4px 12px;padding-left:12px;font-size:12px;line-height:20px;cursor:pointer}sd-select-option-group .sd-select__option-group.sd-select__option-group--group:not(.sd-select__option-group--use-checkbox),sd-select-option-group .sd-select__option-group.sd-select__option-group--subgroup:not(.sd-select__option-group--use-checkbox){cursor:default !important}sd-select-option-group .sd-select__option-group.sd-select__option-group--group{background-color:#f5faff !important;color:#333333 !important;font-weight:700}sd-select-option-group .sd-select__option-group.sd-select__option-group--subgroup{padding-left:20px;background-color:#f9f9f9 !important;color:#333333 !important;font-weight:500}sd-select-option-group .sd-select__option-group.sd-select__option-group--item{padding-left:28px}sd-select-option-group .sd-select__option-group sd-checkbox__bg{border-color:#888888}sd-select-option-group .sd-select__option-group__label-wrapper{display:flex;width:100%;column-gap:8px;align-items:center;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}sd-select-option-group .sd-select__option-group__label-wrapper sd-checkbox{flex-shrink:0}sd-select-option-group .sd-select__option-group__label-wrapper .sd-select__option-group-label{flex:0 1 auto;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}sd-select-option-group .sd-select__option-group__label-wrapper .sd-select__option-group__count-indicator{width:fit-content;flex-shrink:0;font-size:12px;font-weight:500;color:#888888}sd-select-option-group .sd-select__option-group--focused{background-color:#e6f1ff}sd-select-option-group .sd-select__option-group--selected.sd-select__option-group--item:not(:hover):not(.sd-select__option-group--use-checkbox),sd-select-option-group .sd-select__option-group--focused.sd-select__option-group--item:not(:hover):not(.sd-select__option-group--use-checkbox){color:#0075ff;font-weight:700}sd-select-option-group .sd-select__option-group--disabled{color:#aaaaaa;cursor:not-allowed}sd-select-option-group .sd-select__option-group:hover:not(.sd-select__option-group--disabled){background-color:#0075ff;color:white}sd-select-option-group .sd-select__option-group:hover.sd-select__option-group--selected:not(.sd-select__option-group--group):not(.sd-select__option-group--subgroup) sd-checkbox .sd-checkbox__bg{border-color:white !important}`;
3759
-
3760
- const SdSelectOptionGroup = class {
3761
- constructor(hostRef) {
3762
- index.registerInstance(this, hostRef);
3763
- this.optionClick = index.createEvent(this, "optionClick");
3764
- }
3765
- get el() { return index.getElement(this); }
3766
- option;
3767
- index;
3768
- isSelected = false;
3769
- isFocused = false;
3770
- optionStyle;
3771
- disabled = false;
3772
- useCheckbox = false;
3773
- useIndicator = true;
3774
- countInfo = {
3775
- selectedCount: 0,
3776
- totalCount: 0,
3777
- };
3778
- isHovered = false;
3779
- async isDisabled() {
3780
- return !!this.option.disabled || this.option.type === 'group' || this.option.type === 'subgroup';
3781
- }
3782
- optionClick;
3783
- handleClick = (option, isSelected, event) => {
3784
- event.stopPropagation();
3785
- if (option.type === 'group' || option.type === 'subgroup') {
3786
- this.optionClick.emit({
3787
- option: this.option,
3788
- isSelected,
3789
- index: this.index,
3790
- event,
3791
- });
3792
- return;
3793
- }
3794
- if (!this.option.disabled && !this.disabled) {
3795
- this.optionClick.emit({
3796
- option: this.option,
3797
- isSelected,
3798
- index: this.index,
3799
- event,
3800
- });
3801
- }
3802
- };
3803
- render() {
3804
- return (index.h("div", { key: 'ed43a2fa2ae5b182f1c99b272126fb3629617681', class: {
3805
- 'sd-select__option-group': true,
3806
- 'sd-select__option-group--selected': !!this.isSelected,
3807
- 'sd-select__option-group--disabled': !!this.option.disabled,
3808
- 'sd-select__option-group--focused': this.isFocused,
3809
- 'sd-select__option-group--use-checkbox': this.useCheckbox,
3810
- 'sd-select__option-group--group': this.option.type === 'group',
3811
- 'sd-select__option-group--subgroup': this.option.type === 'subgroup',
3812
- 'sd-select__option-group--item': this.option.type === 'item',
3813
- }, onMouseEnter: () => (this.isHovered = true), onMouseLeave: () => (this.isHovered = false), style: this.optionStyle, "data-index": this.index, onClick: event => this.handleClick(this.option, this.isSelected, event) }, index.h("div", { key: '97de3f6a855bf737cbaa5f23f7986b2c5ee10c52', class: "sd-select__option-group__label-wrapper" }, this.useCheckbox && (index.h("sd-checkbox", { key: '7d8814dc060dd769f100be09d87edcc440cbf93d', checked: this.isSelected, disabled: this.option.disabled, onClick: e => {
3814
- e.preventDefault();
3815
- this.handleClick(this.option, this.isSelected, e);
3816
- } })), index.h("span", { key: '8fd8bf56260bf49f42a0cb205868a45912e5a4de', class: "sd-select__option-group-label" }, this.option.label), this.useIndicator && this.option.type !== 'item' && (index.h("span", { key: 'eaa10fa1f13f4f6bc48b22967b1b31a2e894865c', class: "sd-select__option-group__count-indicator" }, `(${this.countInfo?.selectedCount}/${this.countInfo?.totalCount})`)))));
3817
- }
3818
- };
3819
- SdSelectOptionGroup.style = sdSelectOptionGroupCss();
3820
-
3821
- const sdSelectSearchInputCss = () => `.sd-select-search-input{position:sticky;top:0;display:flex;width:100%;background-color:white;align-items:center;padding:4px 8px}.sd-select-search-input sd-input{width:100%}.sd-select-search-input--scrolled{box-shadow:2px 2px 8px 2px rgba(0, 0, 0, 0.2)}`;
3822
-
3823
- const SdSelectSearchInput = class {
3824
- constructor(hostRef) {
3825
- index.registerInstance(this, hostRef);
3826
- this.sdSearchInput = index.createEvent(this, "sdSearchInput");
3827
- this.sdSearchFocus = index.createEvent(this, "sdSearchFocus");
3828
- }
3829
- isScrolled = false;
3830
- searchText = '';
3831
- sdSearchInput;
3832
- sdSearchFocus;
3833
- searchRef;
3834
- async getNativeElement() {
3835
- if (this.searchRef) {
3836
- return this.searchRef.getNativeElement();
3837
- }
3838
- return null;
3839
- }
3840
- async searchInputFocus() {
3841
- const input = await this.getNativeElement();
3842
- input?.focus({ preventScroll: true });
3843
- }
3844
- render() {
3845
- return (index.h("div", { key: '6d05eba9ab9a951d126f703ec9366d8b425581b7', class: {
3846
- 'sd-select-search-input': true,
3847
- 'sd-select-search-input--scrolled': !!this.isScrolled,
3848
- }, onClick: event => event.stopPropagation() }, index.h("sd-input", { key: 'e00b8cab50be8a096893c4cb4aceff0446cbfde4', ref: el => (this.searchRef = el), value: this.searchText, placeholder: "\uAC80\uC0C9", clearable: true, inputStyle: { 'padding-left': '8px' }, autofocus: true, onSdInput: event => {
3849
- this.sdSearchInput.emit(String(event?.detail));
3850
- }, onSdFocus: () => {
3851
- this.sdSearchFocus.emit();
3852
- }, onKeyDown: event => {
3853
- if (event.code === 'Enter')
3854
- event.stopPropagation();
3855
- } }, index.h("sd-icon", { key: '951178d9cbe80fc944e708207b57949ecd6ed8fc', name: "search", size: 16, color: "#737373", style: { marginRight: '4px' }, slot: "prefix" }))));
3856
- }
3857
- };
3858
- SdSelectSearchInput.style = sdSelectSearchInputCss();
3859
-
3860
- const sdTableBackupCss = () => `.sd-table__wrapper .sd-table__container .sd-table__middle{overflow-y:auto;overflow-x:hidden;scroll-behavior:smooth}.sd-table__wrapper .sd-table__container .sd-table__middle::-webkit-scrollbar{opacity:0;background:#e5e5e5}.sd-table__wrapper .sd-table__container .sd-table__middle::-webkit-scrollbar:horizontal{height:8px}.sd-table__wrapper .sd-table__container .sd-table__middle::-webkit-scrollbar:vertical{width:8px}.sd-table__wrapper .sd-table__container .sd-table__middle::-webkit-scrollbar-thumb{height:80px;background-color:#cccccc;border-radius:4px}.sd-table__wrapper .sd-table__container .sd-table__middle::-webkit-scrollbar-track{background-color:transparent}.sd-table__wrapper{height:var(--table-height, auto);width:var(--table-width, 100%);color:#222222}.sd-table__wrapper .sd-table__container{width:100%;height:var(--table-container-height, auto);position:relative;border:1px solid #e1e1e1;border-radius:8px;font-size:12px;overflow:hidden;background:#ffffff}.sd-table__wrapper .sd-table__container .sd-table__middle{overflow:auto;will-change:scroll-position;min-height:var(--table-container-height, auto)}.sd-table__wrapper .sd-table__container .sd-table__middle--scrollable{height:var(--table-container-height, auto)}.sd-table__wrapper .sd-table__container .sd-table__middle--loading{overflow:hidden !important;pointer-events:none}.sd-table__wrapper .sd-table__container .sd-table__middle--loading__spinner{position:absolute;top:0;left:0;width:100%;height:var(--table-container-height, 100%);min-height:var(--table-container-height, 100%);background:rgba(255, 255, 255, 0.6);z-index:200;display:flex;align-items:center;justify-content:center}.sd-table__wrapper .sd-table__container .sd-table__middle .sd-table{background-color:white;display:table;width:100%;border-collapse:separate;border-spacing:0;table-layout:fixed}.sd-table__wrapper .sd-table__container .sd-table__middle .sd-table tbody.sd-table-tbody--virtual-scroll{position:relative;height:var(--total-virtual-height, --table-container-height, auto)}.sd-table__wrapper .sd-table__container .sd-table__middle .sd-table tbody.sd-table-tbody--virtual-scroll tr:not([aria-hidden=true]){width:100%}.sd-table__wrapper .sd-table__container .sd-table__middle .sd-table tbody.sd-table-tbody--virtual-scroll tr[aria-hidden=true]{padding:0;border:none}.sd-table__wrapper .sd-table__container .sd-table__middle .sd-table tbody.sd-table-tbody--virtual-scroll tr[aria-hidden=true]:not(.sd-table__virtual-row-spacer) td{display:none}.sd-table__wrapper .sd-table__container .sd-table__middle .sd-table--selectable td.sd-td--selected,.sd-table__wrapper .sd-table__container .sd-table__middle .sd-table--selectable th.sd-th--selected{width:52px !important;max-width:52px !important;min-width:52px !important;padding:0 10px 0 24px;text-align:left}.sd-table__wrapper .sd-table__container .sd-table__middle .sd-table--sticky-header thead{position:sticky;top:0;z-index:120}.sd-table__wrapper .sd-table__container .sd-table__middle .sd-table--sticky-column th.sticky-left,.sd-table__wrapper .sd-table__container .sd-table__middle .sd-table--sticky-column th.sticky-right{position:sticky;background-color:#f5faff;z-index:110 !important}.sd-table__wrapper .sd-table__container .sd-table__middle .sd-table--sticky-column td.sticky-left,.sd-table__wrapper .sd-table__container .sd-table__middle .sd-table--sticky-column td.sticky-right{position:sticky;background-color:white;z-index:100 !important}.sd-table__wrapper .sd-table__container .sd-table__middle .sd-table--sticky-column .sticky-left{left:var(--sticky-left-offset, 0)}.sd-table__wrapper .sd-table__container .sd-table__middle .sd-table--sticky-column .sticky-right{right:var(--sticky-right-offset, 0)}.sd-table__wrapper .sd-table__container .sd-table__middle .sd-table--sticky-column th.sticky-cell{position:sticky;z-index:102;background-color:#f5faff}.sd-table__wrapper .sd-table__container .sd-table__middle .sd-table--sticky-column td.sticky-cell{position:sticky;z-index:101;background-color:white}.sd-table__wrapper .sd-table__container .sd-table__middle .sd-table--scrolled-left th.sticky-left-edge,.sd-table__wrapper .sd-table__container .sd-table__middle .sd-table--scrolled-left td.sticky-left-edge{overflow:visible}.sd-table__wrapper .sd-table__container .sd-table__middle .sd-table--scrolled-left th.sticky-left-edge:after,.sd-table__wrapper .sd-table__container .sd-table__middle .sd-table--scrolled-left td.sticky-left-edge:after{content:"";position:absolute;top:0;left:100%;right:-20px;width:20px;height:100%;z-index:101 !important;box-shadow:inset 12px 0 20px -25px;opacity:1;pointer-events:none}.sd-table__wrapper .sd-table__container .sd-table__middle .sd-table--scrolled-right th.sticky-right-edge,.sd-table__wrapper .sd-table__container .sd-table__middle .sd-table--scrolled-right td.sticky-right-edge{overflow:visible}.sd-table__wrapper .sd-table__container .sd-table__middle .sd-table--scrolled-right th.sticky-right-edge:after,.sd-table__wrapper .sd-table__container .sd-table__middle .sd-table--scrolled-right td.sticky-right-edge:after{content:"";position:absolute;top:0;left:-20px;width:20px;height:100%;z-index:101 !important;box-shadow:inset -12px 0 20px -25px;opacity:1;pointer-events:none}.sd-table__wrapper .sd-table__container .sd-table__middle .sd-table--no-data thead{opacity:0.4}.sd-table__wrapper .sd-table__container .sd-table__middle .sd-table--no-data thead tr th.sd-th{border-bottom:1px solid rgba(225, 225, 225, 0.4) !important}.sd-table__wrapper .sd-table__container .sd-table__middle .sd-table sd-td,.sd-table__wrapper .sd-table__container .sd-table__middle .sd-table sd-th,.sd-table__wrapper .sd-table__container .sd-table__middle .sd-table .sd-th__content--label{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;word-break:keep-all}.sd-table__wrapper .sd-table__container .sd-table__middle .sd-table thead{height:36px}.sd-table__wrapper .sd-table__container .sd-table__middle .sd-table thead tr{width:100%}.sd-table__wrapper .sd-table__container .sd-table__middle .sd-table thead tr th{background:#f5faff;height:36px;padding:0 16px;font-weight:500;vertical-align:middle;border-bottom:1px solid #e1e1e1;-webkit-user-select:none;user-select:none;position:relative}.sd-table__wrapper .sd-table__container .sd-table__middle .sd-table thead tr th.sd-th .sd-th__content{display:flex;flex-flow:row nowrap;align-items:center;gap:4px}.sd-table__wrapper .sd-table__container .sd-table__middle .sd-table thead tr th.sd-th .sd-th__content--left{justify-content:flex-start}.sd-table__wrapper .sd-table__container .sd-table__middle .sd-table thead tr th.sd-th .sd-th__content--center{justify-content:center}.sd-table__wrapper .sd-table__container .sd-table__middle .sd-table thead tr th.sd-th .sd-th__content--right{justify-content:flex-end}.sd-table__wrapper .sd-table__container .sd-table__middle .sd-table thead tr th.sd-th .sd-th__resizer{position:absolute;top:50%;right:0;transform:translateY(-50%);width:4px;height:16px;cursor:col-resize;z-index:3;border-left:1px solid #cccccc;border-right:1px solid #cccccc}.sd-table__wrapper .sd-table__container .sd-table__middle .sd-table tbody tr td{height:44px;padding:0 16px;border-bottom:1px solid #e1e1e1;background:white;vertical-align:middle}.sd-table__wrapper .sd-table__container .sd-table__middle .sd-table tbody tr td.sd-td--left{text-align:left}.sd-table__wrapper .sd-table__container .sd-table__middle .sd-table tbody tr td.sd-td--center{text-align:center}.sd-table__wrapper .sd-table__container .sd-table__middle .sd-table tbody tr td.sd-td--right{text-align:right}.sd-table__wrapper .sd-table__container .sd-table__bottom{background:white;text-align:center}.sd-table__wrapper .sd-table__container .sd-table__bottom .sd-table__no-data{padding-top:15%;color:#888888}.sd-table__wrapper .sd-table__pagination{position:relative;background:#f9f9f9;height:48px;display:flex;align-items:center;justify-content:center;border:1px solid #e1e1e1;border-top:none;border-radius:8px}.sd-table__wrapper .sd-table__pagination sd-select{position:absolute;right:10px;top:50%;transform:translateY(-50%)}.sd-table__wrapper .sd-table__virtual-spacer,.sd-table__wrapper .sd-table__virtual-row-spacer{padding:0 !important}.sd-table__wrapper .sd-table__virtual-spacer td,.sd-table__wrapper .sd-table__virtual-row-spacer td{padding:0 !important;border:none}.sd-table__wrapper .sd-table__virtual-spacer .sd-table__skeleton,.sd-table__wrapper .sd-table__virtual-row-spacer .sd-table__skeleton{width:100%;height:100%;background-image:repeating-linear-gradient(0deg, rgba(246, 246, 246, 0.3) 0px, rgba(225, 225, 225, 0.5) calc(var(--row-height, 44px) / 2), rgba(246, 246, 246, 0.3) var(--row-height, 44px));background-size:100% 200%;animation:skeleton-loading 1.5s ease-in-out infinite;position:relative}.sd-table__wrapper .sd-table__virtual-spacer .sd-table__skeleton::before,.sd-table__wrapper .sd-table__virtual-row-spacer .sd-table__skeleton::before{content:"";position:absolute;top:0;left:0;right:0;bottom:0;background-image:repeating-linear-gradient(to bottom, transparent 0, transparent calc(var(--row-height, 44px) - 1px), #e1e1e1 calc(var(--row-height, 44px) - 1px), #e1e1e1 var(--row-height, 44px));pointer-events:none}.sd-table__wrapper .sd-table__skeleton-cell{width:100%;height:20px;background:linear-gradient(90deg, rgba(246, 246, 246, 0.3) 0%, rgba(225, 225, 225, 0.5) 50%, rgba(246, 246, 246, 0.3) 100%);background-size:200% 100%;animation:skeleton-loading 1.5s ease-in-out infinite;border-radius:4px}@keyframes skeleton-loading{0%{background-position:0% 0%}50%{background-position:100% 100%}100%{background-position:0% 0%}}`;
3861
-
3862
- const SdTable = class {
3863
- constructor(hostRef) {
3864
- index.registerInstance(this, hostRef);
3865
- this.sdSelectChange = index.createEvent(this, "sdSelectChange");
3866
- this.sdPageChange = index.createEvent(this, "sdPageChange");
3867
- this.sdRowsPerPageChange = index.createEvent(this, "sdRowsPerPageChange");
3868
- }
3869
- get el() { return index.getElement(this); }
3870
- columns;
3871
- rows;
3872
- selected = new Set();
3873
- rowKey = 'id';
3874
- selectable = false;
3875
- resizable = false;
3876
- width;
3877
- height;
3878
- stickyHeader = false;
3879
- stickyColumn = { left: 0, right: 0 };
3880
- noDataLabel = '데이터가 없습니다.';
3881
- isLoading = false;
3882
- pagination;
3883
- headerCellRenderer;
3884
- bodyCellRenderer;
3885
- useInternalPagination = false;
3886
- useRowsPerPageSelect = false;
3887
- rowsPerPageOption = [
3888
- { label: '10개씩 보기', value: 10 },
3889
- { label: '25개씩 보기', value: 25 },
3890
- { label: '50개씩 보기', value: 50 },
3891
- { label: '100개씩 보기', value: 100 },
3892
- ];
3893
- useVirtualScroll = {}; // 가상 스크롤 사용 여부
3894
- virtualRowHeight = 44; // 가상 스크롤 사용시 각 행의 높이 - 세로 가상 스크롤 사용시 필수값
3895
- // 가상 스크롤 사용시 각 열의 너비 - 가로 가상 스크롤 사용시 필수값
3896
- // 가상화하려는 컬럼의 넓이는 무조건 고정(resizable의 경우 넓이가 변동되는데 이때에는 고려 x)
3897
- virtualColumnWidth = 120;
3898
- virtualBufferSize = {
3899
- vertical: 5,
3900
- horizontal: 5,
3901
- }; // 가상 스크롤 위아래 버퍼 크기
3902
- sdSelectChange;
3903
- sdPageChange;
3904
- sdRowsPerPageChange;
3905
- currentPage = this.pagination?.page || 1;
3906
- innerRows = [];
3907
- innerSelected = new Set();
3908
- columnWidths = [];
3909
- scrolledLeft = false;
3910
- scrolledRight = false;
3911
- // 세로 가상 스크롤 상태값
3912
- virtualStartIndex = 0;
3913
- virtualEndIndex = 0;
3914
- scrollTopPosition = 0;
3915
- // 가로 가상 스크롤 상태값
3916
- virtualStartColIdx = 0;
3917
- virtualEndColIdx = 0;
3918
- scrollLeftPosition = 0;
3919
- // 가상 스크롤 Raf(Request Animation Frame) 관리
3920
- scrollRequestAnimationFrame = null;
3921
- scrollContainer = null;
3922
- rafScheduled = false;
3923
- pendingUpdates = {
3924
- vertical: false,
3925
- horizontal: false,
3926
- };
3927
- // 상태 캐시값
3928
- cachedVisibleColumns = null;
3929
- lastColumnsRef = null;
3930
- cachedVirtualRows = null;
3931
- cachedVirtualIndexKey = '';
3932
- cachedColumnOrder = null;
3933
- lastColumnOrderKey = '';
3934
- // DOM 측정 캐시값
3935
- cachedContainerHeight = 0;
3936
- cachedContainerWidth = 0;
3937
- // 스타일 캐시
3938
- stickyStyleCache = new Map();
3939
- // isAllChecked 캐시
3940
- cachedIsAllChecked;
3941
- lastSelectionKey = '';
3942
- onScroll;
3943
- handleColumnsChange(newCols) {
3944
- this.columnWidths = newCols.map(c => parseInt(c.width || '120', 10));
3945
- this.cleanUpVirtualCache();
3946
- this.stickyStyleCache.clear();
3947
- if (this.useVirtualScroll.horizontal) {
3948
- this.scheduleUpdate('horizontal');
3949
- }
3950
- }
3951
- handleColumnWidthsChange() {
3952
- this.stickyStyleCache.clear();
3953
- if (this.useVirtualScroll.horizontal) {
3954
- this.scheduleUpdate('horizontal');
3955
- }
3956
- }
3957
- handleRowsChange(newRows) {
3958
- this.innerRows = [...newRows];
3959
- this.cleanUpVirtualCache();
3960
- if (this.useVirtualScroll.vertical) {
3961
- this.scheduleUpdate('vertical');
3962
- }
3963
- }
3964
- handleSelectedChange(newSelected) {
3965
- this.innerSelected = new Set(newSelected);
3966
- }
3967
- cleanUpVirtualCache() {
3968
- this.cachedVisibleColumns = null;
3969
- this.lastColumnsRef = null;
3970
- this.cachedVirtualRows = null;
3971
- this.cachedVirtualIndexKey = '';
3972
- this.cachedColumnOrder = null;
3973
- this.lastColumnOrderKey = '';
3974
- }
3975
- handlePaginationChange(newVal) {
3976
- if (newVal?.page && newVal.page !== this.currentPage) {
3977
- this.currentPage = newVal.page;
3978
- if (this.useVirtualScroll.vertical && this.scrollContainer) {
3979
- this.scrollContainer.scrollTo({ top: 0, behavior: 'instant' });
3980
- this.scrollTopPosition = 0;
3981
- this.calculateVisibleRange();
3982
- }
3983
- }
3984
- }
3985
- componentWillLoad() {
3986
- this.innerRows = [...(this.rows || [])];
3987
- this.innerSelected = new Set(this.selected);
3988
- this.columnWidths = (this.columns || []).map(c => parseInt(c.width || '120', 10));
3989
- if (this.pagination?.page) {
3990
- this.currentPage = this.pagination.page;
3991
- }
3992
- }
3993
- componentDidLoad() {
3994
- index.readTask(() => {
3995
- const middle = this.el.querySelector('.sd-table__middle');
3996
- if (!middle)
3997
- return;
3998
- this.onScroll = () => {
3999
- const scrollLeft = middle.scrollLeft;
4000
- const scrollWidth = middle.scrollWidth;
4001
- const clientWidth = middle.clientWidth;
4002
- const scrollTop = middle.scrollTop;
4003
- const verticalChanged = this.useVirtualScroll.vertical && this.scrollTopPosition !== scrollTop;
4004
- const horizontalChanged = this.useVirtualScroll.horizontal && this.scrollLeftPosition !== scrollLeft;
4005
- const newScrolledLeft = scrollLeft > 0;
4006
- const newScrolledRight = scrollLeft + clientWidth < scrollWidth;
4007
- if (this.scrolledLeft !== newScrolledLeft || this.scrolledRight !== newScrolledRight) {
4008
- this.scrolledLeft = newScrolledLeft;
4009
- this.scrolledRight = newScrolledRight;
4010
- }
4011
- if (verticalChanged || horizontalChanged) {
4012
- if (this.scrollRequestAnimationFrame !== null) {
4013
- cancelAnimationFrame(this.scrollRequestAnimationFrame);
4014
- }
4015
- this.scrollRequestAnimationFrame = requestAnimationFrame(() => {
4016
- if (verticalChanged) {
4017
- this.scrollTopPosition = scrollTop;
4018
- this.calculateVisibleRange();
4019
- }
4020
- if (horizontalChanged) {
4021
- this.scrollLeftPosition = scrollLeft;
4022
- this.calculateVisibleColumnRange();
4023
- }
4024
- this.scrollRequestAnimationFrame = null;
4025
- });
4026
- }
4027
- };
4028
- this.scrollContainer = middle;
4029
- requestAnimationFrame(() => {
4030
- if (this.scrollContainer && this.onScroll) {
4031
- this.cachedContainerHeight = this.scrollContainer.clientHeight;
4032
- this.cachedContainerWidth = this.scrollContainer.clientWidth;
4033
- middle.addEventListener('scroll', this.onScroll, { passive: true });
4034
- if (this.useVirtualScroll.vertical) {
4035
- this.calculateVisibleRange();
4036
- }
4037
- if (this.useVirtualScroll.horizontal) {
4038
- this.calculateVisibleColumnRange();
4039
- }
4040
- this.onScroll();
4041
- }
4042
- });
4043
- });
4044
- }
4045
- changePage(page) {
4046
- if (!this.useInternalPagination) {
4047
- this.sdPageChange.emit(page);
4048
- return;
4049
- }
4050
2266
  this.currentPage = page;
4051
- this.sdPageChange.emit(this.currentPage);
4052
- }
4053
- changeRowsPerPage(perPage) {
4054
- const changedRowsPerPage = perPage ? Number(perPage) : 0;
4055
- if (!this.useInternalPagination) {
4056
- this.sdRowsPerPageChange.emit(changedRowsPerPage);
4057
- return;
4058
- }
4059
- const newRowsPerPage = Number(perPage || 0);
4060
- let newLastPage = Math.max(1, Math.ceil(this.innerRows.length / newRowsPerPage));
4061
- let newCurrentPage = this.currentPage;
4062
- if (newCurrentPage > newLastPage) {
4063
- newCurrentPage = newLastPage;
4064
- }
4065
- this.pagination = {
4066
- page: newCurrentPage,
4067
- rowsPerPage: newRowsPerPage,
4068
- lastPage: newLastPage,
4069
- };
4070
- this.currentPage = newCurrentPage;
4071
- this.sdRowsPerPageChange.emit(changedRowsPerPage);
4072
- }
4073
- disconnectedCallback() {
4074
- if (this.scrollContainer && this.onScroll) {
4075
- this.scrollContainer.removeEventListener('scroll', this.onScroll);
4076
- }
4077
- if (this.scrollRequestAnimationFrame !== null) {
4078
- cancelAnimationFrame(this.scrollRequestAnimationFrame);
4079
- }
4080
- }
4081
- // ----- Derived getters -----
4082
- get visibleColumns() {
4083
- if (this.cachedVisibleColumns && this.lastColumnsRef === this.columns) {
4084
- return this.cachedVisibleColumns;
4085
- }
4086
- this.lastColumnsRef = this.columns;
4087
- this.cachedVisibleColumns = this.columns.filter(col => col.visible !== false);
4088
- return this.cachedVisibleColumns;
4089
- }
4090
- get paginatedRows() {
4091
- if (!this.pagination || !this.useInternalPagination)
4092
- return this.innerRows;
4093
- const { rowsPerPage = this.rows.length } = this.pagination || {};
4094
- return this.innerRows.slice((this.currentPage - 1) * rowsPerPage, this.currentPage * rowsPerPage);
4095
- }
4096
- get virtualRows() {
4097
- const newVirtualIndexKey = `${this.virtualStartIndex}-${this.virtualEndIndex}`;
4098
- if (this.cachedVirtualRows && this.cachedVirtualIndexKey === newVirtualIndexKey) {
4099
- return this.cachedVirtualRows;
4100
- }
4101
- this.cachedVirtualIndexKey = newVirtualIndexKey;
4102
- if (!this.useVirtualScroll.vertical) {
4103
- this.cachedVirtualRows = this.paginatedRows.map((row, idx) => ({ row, actualIndex: idx }));
4104
- }
4105
- else {
4106
- this.cachedVirtualRows = this.paginatedRows
4107
- .slice(this.virtualStartIndex, this.virtualEndIndex + 1)
4108
- .map((row, relativeIdx) => ({
4109
- row,
4110
- actualIndex: this.virtualStartIndex + relativeIdx,
4111
- }));
4112
- }
4113
- return this.cachedVirtualRows;
4114
- }
4115
- get topSpacerHeight() {
4116
- if (!this.useVirtualScroll.vertical || this.virtualStartIndex === 0)
4117
- return 0;
4118
- return this.virtualStartIndex * this.virtualRowHeight;
4119
- }
4120
- get bottomSpacerHeight() {
4121
- if (!this.useVirtualScroll.vertical)
4122
- return 0;
4123
- const remainingRows = this.paginatedRows.length - this.virtualEndIndex - 1;
4124
- return remainingRows > 0 ? remainingRows * this.virtualRowHeight : 0;
4125
- }
4126
- getHorizontalSpacerWidth(position) {
4127
- const stickyLeftCount = this.stickyColumn.left || 0;
4128
- const stickyRightCount = this.stickyColumn.right || 0;
4129
- const virtualColumnWidths = this.columnWidths.slice(stickyLeftCount, this.visibleColumns.length - stickyRightCount);
4130
- const remainingCols = virtualColumnWidths.length - this.virtualEndColIdx - 1;
4131
- if (position === 'right' && remainingCols <= 0)
4132
- return 0;
4133
- const targetIndex = position === 'left' ? [0, this.virtualStartColIdx] : [this.virtualEndColIdx + 1];
4134
- return virtualColumnWidths.slice(...targetIndex).reduce((sum, width) => sum + width, 0);
4135
- }
4136
- get leftSpacerWidth() {
4137
- if (!this.useVirtualScroll.horizontal || this.virtualStartColIdx === 0) {
4138
- return 0;
4139
- }
4140
- return this.getHorizontalSpacerWidth('left');
4141
- }
4142
- get rightSpacerWidth() {
4143
- if (!this.useVirtualScroll.horizontal) {
4144
- return 0;
4145
- }
4146
- return this.getHorizontalSpacerWidth('right');
4147
- }
4148
- get totalVirtualHeight() {
4149
- if (!this.useVirtualScroll.vertical)
4150
- return 0;
4151
- return this.paginatedRows.length * this.virtualRowHeight;
4152
- }
4153
- get lastPageNumber() {
4154
- const { lastPage, rowsPerPage = this.rows.length } = this.pagination || {};
4155
- return lastPage ?? Math.max(1, Math.ceil(this.rows.length / rowsPerPage));
4156
- }
4157
- get sdTableClasses() {
4158
- return [
4159
- 'sd-table',
4160
- this.stickyHeader && 'sd-table--sticky-header',
4161
- this.selectable && 'sd-table--selectable',
4162
- this.resizable && 'sd-table--resizable',
4163
- !this.innerRows.length && 'sd-table--no-data',
4164
- ((this.stickyColumn?.left ?? 0) > 0 || (this.stickyColumn?.right ?? 0) > 0) &&
4165
- 'sd-table--sticky-column',
4166
- this.scrolledLeft && 'sd-table--scrolled-left',
4167
- this.scrolledRight && 'sd-table--scrolled-right',
4168
- ]
4169
- .filter(Boolean)
4170
- .join(' ');
4171
- }
4172
- // ----- Selection -----
4173
- isRowSelected(row) {
4174
- return Array.from(this.innerSelected).some(r => r[this.rowKey] === row[this.rowKey]);
4175
- }
4176
- updateRowSelect(row) {
4177
- const selectedArray = Array.from(this.innerSelected);
4178
- const exists = this.isRowSelected(row);
4179
- const newSelected = exists
4180
- ? selectedArray.filter(r => r[this.rowKey] !== row[this.rowKey])
4181
- : [...selectedArray, row];
4182
- // 동일 상태면 set하지 않음 → 불필요 렌더 방지
4183
- if (newSelected.length === selectedArray.length)
4184
- return;
4185
- this.innerSelected = new Set(newSelected);
4186
- this.cachedIsAllChecked = undefined;
4187
- this.sdSelectChange.emit(Array.from(this.innerSelected));
4188
- }
4189
- toggleSelectAll(checked) {
4190
- if (checked) {
4191
- const pageRows = new Set([...this.paginatedRows]);
4192
- this.innerSelected = new Set([...this.innerSelected, ...pageRows]);
4193
- }
4194
- else {
4195
- const currentPageKeys = this.paginatedRows.map(r => r[this.rowKey]);
4196
- this.innerSelected = new Set([...this.innerSelected].filter(r => !currentPageKeys.includes(r[this.rowKey])));
4197
- }
4198
- this.cachedIsAllChecked = undefined;
4199
- this.sdSelectChange.emit(Array.from(this.innerSelected));
4200
- }
4201
- get isAllChecked() {
4202
- const selectionKey = `${this.paginatedRows.length}-${this.innerSelected.size}`;
4203
- if (this.cachedIsAllChecked !== undefined && this.lastSelectionKey === selectionKey) {
4204
- return this.cachedIsAllChecked;
4205
- }
4206
- const total = this.paginatedRows.length;
4207
- const selectedCount = this.paginatedRows.filter(row => Array.from(this.innerSelected).some(selectedRow => selectedRow[this.rowKey] === row[this.rowKey])).length;
4208
- let result;
4209
- if (selectedCount === 0) {
4210
- result = false; // 아무것도 안 선택됨
4211
- }
4212
- else if (selectedCount === total) {
4213
- result = true; // 전부 선택됨
4214
- }
4215
- else {
4216
- result = null; // 일부만 선택됨
4217
- }
4218
- this.cachedIsAllChecked = result;
4219
- this.lastSelectionKey = selectionKey;
4220
- return result;
4221
- }
4222
- // RAF 통합 관리
4223
- scheduleUpdate(type) {
4224
- this.pendingUpdates[type] = true;
4225
- if (!this.rafScheduled) {
4226
- this.rafScheduled = true;
4227
- this.scrollRequestAnimationFrame = requestAnimationFrame(() => {
4228
- if (this.pendingUpdates.vertical)
4229
- this.calculateVisibleRange();
4230
- if (this.pendingUpdates.horizontal)
4231
- this.calculateVisibleColumnRange();
4232
- this.pendingUpdates = { vertical: false, horizontal: false };
4233
- this.rafScheduled = false;
4234
- this.scrollRequestAnimationFrame = null;
4235
- });
4236
- }
4237
- }
4238
- // 세로 가상 스크롤 렌더링 계산
4239
- calculateVisibleRange() {
4240
- if (!this.useVirtualScroll.vertical) {
4241
- this.virtualStartIndex = 0;
4242
- this.virtualEndIndex = this.paginatedRows.length - 1;
4243
- return;
4244
- }
4245
- const scrollTop = this.scrollTopPosition;
4246
- let containerHeight = this.cachedContainerHeight;
4247
- if (containerHeight === 0 && this.scrollContainer) {
4248
- containerHeight = this.scrollContainer.clientHeight;
4249
- this.cachedContainerHeight = containerHeight;
4250
- }
4251
- const bufferSize = this.virtualBufferSize.vertical || 5;
4252
- const startIndex = Math.floor(scrollTop / this.virtualRowHeight);
4253
- const visibleCount = Math.ceil(containerHeight / this.virtualRowHeight);
4254
- const endIndex = startIndex + visibleCount - 1;
4255
- const newStartIndex = Math.max(0, startIndex - bufferSize);
4256
- const newEndIndex = Math.min(this.paginatedRows.length - 1, endIndex + bufferSize);
4257
- // 실제로 변경된 경우에만 상태 업데이트
4258
- if (this.virtualStartIndex !== newStartIndex || this.virtualEndIndex !== newEndIndex) {
4259
- this.virtualStartIndex = newStartIndex;
4260
- this.virtualEndIndex = newEndIndex;
4261
- }
4262
- }
4263
- // 가로 가상 스크롤 렌더링 계산
4264
- calculateVisibleColumnRange() {
4265
- if (!this.useVirtualScroll.horizontal) {
4266
- this.virtualStartColIdx = 0;
4267
- this.virtualEndColIdx = this.visibleColumns.length - 1;
4268
- return;
4269
- }
4270
- const scrollLeft = this.scrollLeftPosition;
4271
- // 캐시된 값 사용, 없으면 측정 후 캐시
4272
- let containerWidth = this.cachedContainerWidth;
4273
- if (containerWidth === 0 && this.scrollContainer) {
4274
- containerWidth = this.scrollContainer.clientWidth;
4275
- this.cachedContainerWidth = containerWidth;
4276
- }
4277
- const stickyLeftCount = this.stickyColumn.left || 0;
4278
- const stickyRightCount = this.stickyColumn.right || 0;
4279
- // 가상 스크롤 컬럼 - sticky column 제외
4280
- const virtualColumns = this.visibleColumns.slice(stickyLeftCount, this.visibleColumns.length - stickyRightCount);
4281
- if (virtualColumns.length === 0) {
4282
- this.virtualStartColIdx = 0;
4283
- this.virtualEndColIdx = 0;
4284
- return;
4285
- }
4286
- const stickyLeftWidth = this.columnWidths.slice(0, stickyLeftCount).reduce((sum, width) => sum + width, 0) +
4287
- (this.selectable ? 52 : 0);
4288
- const stickyRightWidth = this.columnWidths
4289
- .slice(this.visibleColumns.length - stickyRightCount)
4290
- .reduce((sum, width) => sum + width, 0);
4291
- // 가상 스크롤 영역의 너비 계산
4292
- const virtualScrollableWidth = containerWidth - stickyLeftWidth - stickyRightWidth;
4293
- const virtualColumnWidths = this.columnWidths.slice(stickyLeftCount, this.visibleColumns.length - stickyRightCount);
4294
- const virtualScrollLeft = Math.max(0, scrollLeft - stickyLeftWidth);
4295
- const reducedVirtualWidth = virtualColumnWidths.reduce((acc, width, idx) => {
4296
- acc.push((acc[idx - 1] || 0) + width);
4297
- return acc;
4298
- }, []);
4299
- let startIdx = 0; // 가상 스크롤 시작 인덱스
4300
- let endIdx = virtualColumns.length - 1; // 가상 스크롤 종료 인덱스
4301
- // sticky left 영역 제외한 스크롤 위치
4302
- for (let i = 0; i < reducedVirtualWidth.length; i++) {
4303
- if (reducedVirtualWidth[i] > virtualScrollLeft) {
4304
- startIdx = Math.max(0, i);
4305
- break;
4306
- }
4307
- }
4308
- const scrollRight = virtualScrollLeft + virtualScrollableWidth;
4309
- for (let i = startIdx; i < reducedVirtualWidth.length; i++) {
4310
- if (reducedVirtualWidth[i] >= scrollRight) {
4311
- endIdx = Math.min(virtualColumns.length - 1, i);
4312
- break;
4313
- }
4314
- }
4315
- const bufferSize = this.virtualBufferSize.horizontal || 5;
4316
- const newStartColIdx = Math.max(0, startIdx - bufferSize);
4317
- const newEndColIdx = Math.min(virtualColumns.length - 1, endIdx + bufferSize);
4318
- // 실제로 변경된 경우에만 상태 업데이트
4319
- if (this.virtualStartColIdx !== newStartColIdx || this.virtualEndColIdx !== newEndColIdx) {
4320
- this.virtualStartColIdx = newStartColIdx;
4321
- this.virtualEndColIdx = newEndColIdx;
4322
- }
4323
- }
4324
- // ----- Helpers -----
4325
- getStickyStyle(colIdx) {
4326
- // 캐시된 스타일이 있으면 반환
4327
- if (this.stickyStyleCache.has(colIdx)) {
4328
- return this.stickyStyleCache.get(colIdx);
4329
- }
4330
- const leftOffset = this.columnWidths.slice(0, colIdx).reduce((a, b) => a + b, 0) + (this.selectable ? 52 : 0);
4331
- const rightOffset = this.columnWidths
4332
- .filter((_, i) => i >= this.visibleColumns.length - (this.stickyColumn.right || 0) && i > colIdx)
4333
- .reduce((a, b) => a + b, 0);
4334
- const style = {
4335
- '--sticky-left-offset': `${leftOffset}px`,
4336
- '--sticky-right-offset': `${rightOffset}px`,
4337
- 'width': `${this.columnWidths[colIdx]}px`,
4338
- 'minWidth': `${this.columnWidths[colIdx]}px`,
4339
- 'maxWidth': `${this.columnWidths[colIdx]}px`,
4340
- };
4341
- // 스타일 캐시에 저장
4342
- this.stickyStyleCache.set(colIdx, style);
4343
- return style;
4344
- }
4345
- handleResize(index, event) {
4346
- // SSR 환경 체크
4347
- if (typeof document === 'undefined')
4348
- return;
4349
- const startX = event.clientX;
4350
- const startWidth = this.columnWidths[index];
4351
- const handleMouseMove = (moveEvent) => {
4352
- const targetColumn = this.columnWidths[index];
4353
- if (!targetColumn)
4354
- return;
4355
- const minWidth = this.columns[index]?.minWidth || 50;
4356
- const maxWidth = this.columns[index]?.maxWidth || 9999;
4357
- const newWidth = Math.min(Math.max(startWidth + moveEvent.clientX - startX, minWidth), maxWidth);
4358
- this.columnWidths = this.columnWidths.map((width, idx) => (idx === index ? newWidth : width));
4359
- };
4360
- const handleMouseUp = () => {
4361
- document.removeEventListener('mousemove', handleMouseMove);
4362
- document.removeEventListener('mouseup', handleMouseUp);
4363
- };
4364
- document.addEventListener('mousemove', handleMouseMove);
4365
- document.addEventListener('mouseup', handleMouseUp);
4366
- }
4367
- getCellValue(column, row) {
4368
- const { field, format, name } = column;
4369
- const value = typeof field === 'function' ? field(row) : field ? row[field] : row[name];
4370
- return format ? format(value, row) : value;
4371
- }
4372
- getColumnRenderedInOrder() {
4373
- const orderKey = `${this.visibleColumns.length}-${this.virtualStartColIdx}-${this.virtualEndColIdx}`;
4374
- if (this.cachedColumnOrder && this.lastColumnOrderKey === orderKey) {
4375
- return this.cachedColumnOrder;
4376
- }
4377
- const stickyLeftCount = this.stickyColumn.left || 0;
4378
- const stickyRightCount = this.stickyColumn.right || 0;
4379
- // Sticky left 컬럼들
4380
- const stickyLeftCols = this.visibleColumns.slice(0, stickyLeftCount);
4381
- const stickyRightCols = this.visibleColumns.slice(this.visibleColumns.length - stickyRightCount);
4382
- const middleCols = this.useVirtualScroll.horizontal
4383
- ? this.visibleColumns
4384
- .slice(stickyLeftCount, this.visibleColumns.length - stickyRightCount)
4385
- .slice(this.virtualStartColIdx, this.virtualEndColIdx + 1)
4386
- : this.visibleColumns.slice(stickyLeftCount, this.visibleColumns.length - stickyRightCount);
4387
- this.cachedColumnOrder = {
4388
- stickyLeftCount,
4389
- stickyRightCount,
4390
- stickyLeftCols,
4391
- middleCols,
4392
- stickyRightCols,
4393
- };
4394
- this.lastColumnOrderKey = orderKey;
4395
- return this.cachedColumnOrder;
4396
- }
4397
- // ----- Render -----
4398
- renderHead() {
4399
- const { stickyLeftCount, stickyRightCount, stickyLeftCols, middleCols, stickyRightCols } = this.getColumnRenderedInOrder();
4400
- return (index.h("thead", null, index.h("tr", null, this.selectable && (index.h("th", { class: {
4401
- 'sd-th': true,
4402
- 'sd-th--selected': true,
4403
- 'sticky-left': Boolean(this.stickyColumn.left && this.stickyColumn.left > 0),
4404
- }, style: {
4405
- '--sticky-left-offset': '0px',
4406
- } }, index.h("sd-checkbox", { checked: this.isAllChecked, disabled: !this.paginatedRows.length, onSdChange: (e) => this.toggleSelectAll(e.detail) }))), stickyLeftCols.map((col, idx) => {
4407
- const rendered = this.headerCellRenderer?.(col);
4408
- return (index.h("th", { key: col.name, class: {
4409
- 'sd-th': true,
4410
- [`${col.thClass}`]: Boolean(col.thClass),
4411
- 'sticky-left': true,
4412
- 'sticky-left-edge': idx === stickyLeftCount - 1,
4413
- }, style: { ...col.thStyle, ...this.getStickyStyle(idx) } }, index.h("div", { class: `sd-th__content sd-th__content--${col.align || 'left'}` }, index.h("slot", { name: `header-cell-${col.name}` }, index.h("div", { class: "sd-th__content--label" }, rendered ? (typeof rendered === 'string' ? (index.h("span", { innerHTML: rendered })) : (rendered)) : (col.label))), col.usePageMoveIcon && index.h("sd-icon", { name: "pageMove", size: "12", color: "#006AC1" }), col.tooltip && (index.h("sd-tooltip", { ...col.tooltipOptions }, index.h("div", { slot: "content" }, col.tooltip.map(text => (index.h("p", null, text))))))), this.resizable && typeof window !== 'undefined' && (index.h("div", { class: "sd-th__resizer", onMouseDown: (evt) => this.handleResize(idx, evt) }))));
4414
- }), this.renderSpacerTd('left', -1), middleCols.map((col, relativeIdx) => {
4415
- const actualColIdx = stickyLeftCount + this.virtualStartColIdx + relativeIdx;
4416
- const rendered = this.headerCellRenderer?.(col);
4417
- return (index.h("th", { key: col.name, class: {
4418
- 'sd-th': true,
4419
- [`${col.thClass}`]: Boolean(col.thClass),
4420
- }, style: { ...col.thStyle, ...this.getStickyStyle(actualColIdx) } }, index.h("div", { class: `sd-th__content sd-th__content--${col.align || 'left'}` }, index.h("slot", { name: `header-cell-${col.name}` }, index.h("div", { class: "sd-th__content--label" }, rendered ? (typeof rendered === 'string' ? (index.h("span", { innerHTML: rendered })) : (rendered)) : (col.label))), col.usePageMoveIcon && index.h("sd-icon", { name: "pageMove", size: "12", color: "#006AC1" }), col.tooltip && (index.h("sd-tooltip", { ...col.tooltipOptions }, index.h("div", { slot: "content" }, col.tooltip.map(text => (index.h("p", null, text))))))), this.resizable && typeof window !== 'undefined' && (index.h("div", { class: "sd-th__resizer", onMouseDown: (evt) => this.handleResize(actualColIdx, evt) }))));
4421
- }), this.renderSpacerTd('right', -1), stickyRightCols.map((col, relativeIdx) => {
4422
- const actualColIdx = this.visibleColumns.length - stickyRightCount + relativeIdx;
4423
- const rendered = this.headerCellRenderer?.(col);
4424
- return (index.h("th", { key: col.name, class: {
4425
- 'sd-th': true,
4426
- [`${col.thClass}`]: Boolean(col.thClass),
4427
- 'sticky-right': true,
4428
- 'sticky-right-edge': relativeIdx === 0,
4429
- }, style: { ...col.thStyle, ...this.getStickyStyle(actualColIdx) } }, index.h("div", { class: `sd-th__content sd-th__content--${col.align || 'left'}` }, index.h("slot", { name: `header-cell-${col.name}` }, index.h("div", { class: "sd-th__content--label" }, rendered ? (typeof rendered === 'string' ? (index.h("span", { innerHTML: rendered })) : (rendered)) : (col.label))), col.usePageMoveIcon && index.h("sd-icon", { name: "pageMove", size: "12", color: "#006AC1" }), col.tooltip && (index.h("sd-tooltip", { ...col.tooltipOptions }, index.h("div", { slot: "content" }, col.tooltip.map(text => (index.h("p", null, text))))))), this.resizable && typeof window !== 'undefined' && (index.h("div", { class: "sd-th__resizer", onMouseDown: (evt) => this.handleResize(actualColIdx, evt) }))));
4430
- }))));
4431
- }
4432
- renderBody() {
4433
- return (index.h("tbody", { ...(!this.paginatedRows.length && { part: 'tbody-empty' }), class: `sd-table-tbody ${this.useVirtualScroll.vertical ? 'sd-table-tbody--virtual-scroll' : ''}`, style: { '--total-virtual-height': `${this.totalVirtualHeight}px` } }, this.useVirtualScroll.vertical && this.topSpacerHeight > 0 && this.renderSpacerRow('top'), this.paginatedRows.length > 0 &&
4434
- this.virtualRows.map(({ row, actualIndex }) => this.renderRow(row, actualIndex)), this.useVirtualScroll.vertical &&
4435
- this.bottomSpacerHeight > 0 &&
4436
- this.renderSpacerRow('bottom')));
4437
- }
4438
- renderRow(row, rowIdx) {
4439
- const { stickyLeftCount, stickyRightCount, stickyLeftCols, middleCols, stickyRightCols } = this.getColumnRenderedInOrder();
4440
- return (index.h("tr", { key: row[this.rowKey], class: "hover:bg-Grey_Lighten-6", style: this.useVirtualScroll.vertical
4441
- ? {
4442
- height: `${this.virtualRowHeight}px`,
4443
- }
4444
- : {} }, this.selectable && (index.h("td", { class: {
4445
- 'sd-td': true,
4446
- 'sd-td--selected': true,
4447
- 'sticky-left': Boolean(this.stickyColumn.left && this.stickyColumn.left > 0),
4448
- }, style: {
4449
- '--sticky-left-offset': '0px',
4450
- } }, index.h("sd-checkbox", { checked: this.isRowSelected(row), disabled: !this.paginatedRows.length, onSdChange: () => this.updateRowSelect(row) }))), stickyLeftCols.map((column, idx) => {
4451
- const rendered = this.bodyCellRenderer?.(column, row);
4452
- return (index.h("td", { key: column.name, part: `td-${column.name}`, class: {
4453
- 'sd-td': true,
4454
- [`sd-td--${column.align || 'left'}`]: true,
4455
- 'sticky-left': true,
4456
- 'sticky-left-edge': idx === stickyLeftCount - 1,
4457
- [`${column.tdClass}`]: Boolean(column.tdClass),
4458
- }, style: this.getStickyStyle(idx) }, index.h("slot", { name: `body-cell-${column.name}-${rowIdx}` }, rendered ? (typeof rendered === 'string' ? (index.h("span", { innerHTML: rendered })) : (rendered)) : (this.getCellValue(column, row)))));
4459
- }), this.renderSpacerTd('left', rowIdx), middleCols.map((column, relativeIdx) => {
4460
- const actualColIdx = stickyLeftCount + this.virtualStartColIdx + relativeIdx;
4461
- const rendered = this.bodyCellRenderer?.(column, row);
4462
- return (index.h("td", { key: column.name, part: `td-${column.name}`, class: {
4463
- 'sd-td': true,
4464
- [`sd-td--${column.align || 'left'}`]: true,
4465
- [`${column.tdClass}`]: Boolean(column.tdClass),
4466
- }, style: this.getStickyStyle(actualColIdx) }, index.h("slot", { name: `body-cell-${column.name}-${rowIdx}` }, rendered ? (typeof rendered === 'string' ? (index.h("span", { innerHTML: rendered })) : (rendered)) : (this.getCellValue(column, row)))));
4467
- }), this.renderSpacerTd('right', rowIdx), stickyRightCols.map((column, relativeIdx) => {
4468
- const actualColIdx = this.visibleColumns.length - stickyRightCount + relativeIdx;
4469
- const rendered = this.bodyCellRenderer?.(column, row);
4470
- return (index.h("td", { key: column.name, part: `td-${column.name}`, class: {
4471
- 'sd-td': true,
4472
- [`sd-td--${column.align || 'left'}`]: true,
4473
- 'sticky-right': true,
4474
- 'sticky-right-edge': relativeIdx === 0,
4475
- [`${column.tdClass}`]: Boolean(column.tdClass),
4476
- }, style: this.getStickyStyle(actualColIdx) }, index.h("slot", { name: `body-cell-${column.name}-${rowIdx}` }, rendered ? (typeof rendered === 'string' ? (index.h("span", { innerHTML: rendered })) : (rendered)) : (this.getCellValue(column, row)))));
4477
- })));
4478
- }
4479
- renderSpacerRow(position) {
4480
- const spacerHeight = position === 'top' ? this.topSpacerHeight : this.bottomSpacerHeight;
4481
- return (index.h("tr", { key: `virtual-${position}-spacer`, class: "sd-table__virtual-row-spacer", style: {
4482
- height: `${spacerHeight}px`,
4483
- }, "aria-hidden": "true" }, index.h("td", { colSpan: this.visibleColumns.length + (this.selectable ? 1 : 0) }, index.h("div", { class: "sd-table__skeleton", style: {
4484
- '--row-height': `${this.virtualRowHeight}px`,
4485
- } }))));
4486
- }
4487
- renderSpacerTd(position, rowIdx) {
4488
- const spacerWidth = position === 'left' ? this.leftSpacerWidth : this.rightSpacerWidth;
4489
- const showSpacer = position === 'left'
4490
- ? this.useVirtualScroll.horizontal && this.leftSpacerWidth > 0
4491
- : this.useVirtualScroll.horizontal && this.rightSpacerWidth > 0;
4492
- if (!showSpacer)
4493
- return null;
4494
- return (index.h("td", { key: `virtual-${position}-spacer-${rowIdx}`, class: "sd-table__virtual-spacer", style: {
4495
- width: `${spacerWidth}px`,
4496
- minWidth: `${spacerWidth}px`,
4497
- maxWidth: `${spacerWidth}px`,
4498
- padding: '0',
4499
- border: 'none',
4500
- }, "aria-hidden": "true" }, index.h("div", { class: "sd-table__skeleton-cell" })));
4501
- }
4502
- render() {
4503
- return (index.h(index.Host, { key: 'efc61eba99d3b97fe5b102374b94f1f1eaadd7eb' }, index.h("div", { key: '71e7c6d7b7bd4fdd53e1c95a821600e11735ec76', class: "sd-table__wrapper", style: {
4504
- '--table-width': this.width,
4505
- '--table-height': this.height,
4506
- } }, index.h("div", { key: 'e77acaaefdd2948540fcadec624944b66140556e', class: "sd-table__container", style: {
4507
- '--table-container-height': `calc(${this.height} - ${this.pagination && this.innerRows.length > 0 ? 48 : 0}px)`,
4508
- } }, index.h("div", { key: 'd4c6a8fadd18abc1f6020ae9f5e7cf60afc79d7f', class: {
4509
- 'sd-table__middle': true,
4510
- 'sd-table__middle--scrollable': this.paginatedRows.length > 0,
4511
- 'sd-table__middle--loading': this.isLoading,
4512
- } }, this.isLoading && (index.h("div", { key: 'ed768c01fe4a3f6fb85c25061ff6f7789571d149', class: "sd-table__middle--loading__spinner" }, index.h("sd-loading-spinner", { key: 'a563c071edee17150d728f233d2700224e96c09b' }))), index.h("table", { key: 'fbdab865f8fd3c83fb6e778324fb56239c1790f3', part: "table", class: this.sdTableClasses }, this.renderHead(), this.renderBody())), index.h("div", { key: '04e385b3ace1983ce0bb2b29db44ee1d1d8e147d', class: "sd-table__bottom" }, !this.paginatedRows.length && (index.h("div", { key: 'b1a964204f68fc2058a6ff8c833e65567442f9ee', class: "sd-table__no-data" }, index.h("slot", { key: '8d078f856e54f4be105b1c60c137b28f51a21bb4', name: "no-data" }, this.noDataLabel))))), this.pagination && this.innerRows.length > 0 && (index.h("div", { key: '718ff6d9be7f909e20673ab2af7a0d357fe8a6a2', class: "sd-table__pagination" }, index.h("sd-pagination", { key: '23a117bc9f93fb68162c9c18ff309a110a0992a2', currentPage: !this.useInternalPagination ? this.pagination.page : this.currentPage, lastPage: !this.useInternalPagination ? this.pagination.lastPage : this.lastPageNumber, onPageChange: (e) => this.changePage(e.detail) }), this.useRowsPerPageSelect && (index.h("sd-select", { key: 'd233637ddd86f1abc63701443601bddc1439957d', value: this.pagination.rowsPerPage, options: this.rowsPerPageOption, width: "128px", onSdChange: (e) => this.changeRowsPerPage(e.detail.value) })))))));
4513
- }
4514
- static get watchers() { return {
4515
- "columns": ["handleColumnsChange"],
4516
- "columnWidths": ["handleColumnWidthsChange"],
4517
- "rows": ["handleRowsChange"],
4518
- "selected": ["handleSelectedChange"],
4519
- "pagination": ["handlePaginationChange"]
4520
- }; }
4521
- };
4522
- SdTable.style = sdTableBackupCss();
4523
-
4524
- const sdTabsCss = () => `sd-tabs{display:inline-block}sd-tabs .sd-tabs{display:flex;flex-direction:row;gap:4px;border-bottom:1px solid #0075ff}sd-tabs .sd-tabs__tab{display:flex;align-items:center;justify-content:center;gap:8px;cursor:pointer;border:1px solid #cccccc;border-bottom:none;border-radius:4px 4px 0 0;background-color:#f6f6f6;color:#888888;font-weight:400;transition:all 0.2s ease;position:relative;user-select:none}sd-tabs .sd-tabs__tab::after{content:attr(data-label);position:absolute;font-weight:400;transition:font-weight 0.2s ease}sd-tabs .sd-tabs__tab::before{content:"";position:absolute;inset:0;opacity:0;transition:all 0.3s}sd-tabs .sd-tabs__tab--selected{border-color:#0075ff;color:#0075ff;background-color:white}sd-tabs .sd-tabs__tab--selected::after{font-weight:700}sd-tabs .sd-tabs__tab--selected:hover::before{background-color:#0075ff;opacity:0.15}sd-tabs .sd-tabs__tab--unselected:hover::before{background-color:#888888;opacity:0.15}sd-tabs .sd-tabs__label{user-select:none;font-weight:700;visibility:hidden}sd-tabs .sd-tabs--md .sd-tabs__tab{padding:12px 32px;font-size:12px;line-height:20px}sd-tabs .sd-tabs--sm .sd-tabs__tab{padding:8px 20px;font-size:12px;line-height:16px}sd-tabs .sd-tabs--sub{gap:32px;border-bottom:none}sd-tabs .sd-tabs--sub .sd-tabs__tab{border:none;border-radius:0;background-color:transparent;color:#222222;font-weight:400;padding:0 0 2px 0;position:relative}sd-tabs .sd-tabs--sub .sd-tabs__tab::before{content:"";position:absolute;top:100%;left:0;right:0;height:1px;width:100%;background-color:#0075ff;opacity:0;transition:opacity 0.2s ease}sd-tabs .sd-tabs--sub .sd-tabs__tab::after{font-weight:400}sd-tabs .sd-tabs--sub .sd-tabs__tab--selected{color:#0075ff;background-color:transparent}sd-tabs .sd-tabs--sub .sd-tabs__tab--selected::before{opacity:1}sd-tabs .sd-tabs--sub .sd-tabs__tab--selected::after{font-weight:700}`;
4525
-
4526
- const SdTabs = class {
4527
- constructor(hostRef) {
4528
- index.registerInstance(this, hostRef);
4529
- this.sdChange = index.createEvent(this, "sdChange");
4530
- }
4531
- value;
4532
- tabs = [];
4533
- size = 'md';
4534
- isSub = false;
4535
- selectedValue;
4536
- sdChange;
4537
- componentWillLoad() {
4538
- if (this.value !== undefined && this.value !== null) {
4539
- this.selectedValue = this.value;
4540
- }
4541
- }
4542
- valueChanged(newValue) {
4543
- this.selectedValue = newValue;
4544
- }
4545
- handleTabClick = (tabValue) => {
4546
- this.selectedValue = tabValue;
4547
- this.value = tabValue;
4548
- this.sdChange.emit(tabValue);
4549
- };
4550
- isTabSelected(tab) {
4551
- return this.selectedValue === tab.value;
4552
- }
4553
- getTabClasses(tab) {
4554
- const classes = [
4555
- 'sd-tabs__tab',
4556
- this.isTabSelected(tab) ? 'sd-tabs__tab--selected' : 'sd-tabs__tab--unselected',
4557
- ];
4558
- return classes.join(' ');
4559
- }
4560
- getContainerClasses() {
4561
- const classes = ['sd-tabs', `sd-tabs--${this.size}`];
4562
- if (this.isSub) {
4563
- classes.push('sd-tabs--sub');
4564
- }
4565
- return classes.join(' ');
4566
- }
4567
- getBadgeColors(tab) {
4568
- if (this.isTabSelected(tab)) {
4569
- return { bgColor: '#E6F1FF', textColor: '#0075FF' };
4570
- }
4571
- return { bgColor: '#E5E5E5', textColor: '#737373' };
4572
- }
4573
- render() {
4574
- return (index.h("div", { key: 'c495facf1cbf50eaa08d663d16a6a67a0f6369e9', class: this.getContainerClasses(), role: "tablist" }, this.tabs.map((tab, index$1) => {
4575
- const isSelected = this.isTabSelected(tab);
4576
- const badgeColors = this.getBadgeColors(tab);
4577
- return (index.h("div", { key: `tab-${index$1}`, class: this.getTabClasses(tab), role: "tab", "aria-selected": isSelected.toString(), "aria-label": tab.label || 'tab', "data-label": tab.label, onClick: () => this.handleTabClick(tab.value) }, index.h("span", { class: "sd-tabs__label" }, tab.label), tab.badge && (index.h("sd-tag", { size: this.size, label: tab.badge.toString(), bgColor: badgeColors.bgColor, textColor: badgeColors.textColor, rounded: true }))));
4578
- })));
4579
- }
4580
- static get watchers() { return {
4581
- "value": ["valueChanged"]
4582
- }; }
4583
- };
4584
- SdTabs.style = sdTabsCss();
4585
-
4586
- const sdTagCss = () => `:host{display:inline-block}:host([full-width]){display:block}.sd-tag{display:inline-flex;width:100%;align-items:center;justify-content:center;gap:8px;text-decoration:none;border:1px solid transparent;border-radius:4px;transition:all 0.2s ease-in-out;position:relative;overflow:hidden;white-space:nowrap;-webkit-user-select:none;user-select:none;box-sizing:border-box}.sd-tag__content{display:inline-block;width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.sd-tag--custom-color{background:var(--tag-bg-color);color:var(--tag-text-color)}.sd-tag--sm{padding:0 6px;font-size:11px;line-height:18px;height:20px;border-radius:4px}.sd-tag--md{padding:0 8px;font-size:12px;font-weight:700;line-height:20px;height:24px;border-radius:4px}.sd-tag--lg{padding:0 10px;font-size:14px;font-weight:700;line-height:24px;min-height:28px;border-radius:5px}.sd-tag--rounded.sd-tag--sm{border-radius:20px}.sd-tag--rounded.sd-tag--md{border-radius:20px}.sd-tag--rounded.sd-tag--lg{border-radius:15px}`;
4587
-
4588
- const TAG_COLORS = {
4589
- grey: 'bg-grey_20 text-grey_70',
4590
- red: 'bg-red_15 text-red_70',
4591
- orange: 'bg-orange_10 text-orange_65',
4592
- yellow: 'bg-yellow_10 text-yellow_70',
4593
- green: 'bg-green_15 text-green_75',
4594
- blue: 'bg-brilliantblue_20 text-brilliantblue_75',
4595
- darkblue: 'bg-oceanblue_15 text-oceanblue_70',
4596
- indigo: 'bg-brilliantblue_10 text-brilliantblue_85',
4597
- };
4598
- const SdTag = class {
4599
- constructor(hostRef) {
4600
- index.registerInstance(this, hostRef);
4601
- }
4602
- get el() { return index.getElement(this); }
4603
- size = 'md';
4604
- color = 'grey';
4605
- rounded = false;
4606
- label = '';
4607
- bgColor;
4608
- textColor;
4609
- getTagClasses() {
4610
- const classes = ['sd-tag', `sd-tag--${this.size}`];
4611
- if (this.rounded) {
4612
- classes.push('sd-tag--rounded');
4613
- }
4614
- if (this.color && !this.bgColor && !this.textColor) {
4615
- classes.push(TAG_COLORS[this.color]);
4616
- }
4617
- if (this.bgColor || this.textColor) {
4618
- classes.push('sd-tag--custom-color');
4619
- }
4620
- return classes.join(' ');
2267
+ this.pageChange.emit(page);
4621
2268
  }
4622
- renderContent() {
4623
- return [
4624
- index.h("span", { class: "sd-tag__content" }, index.h("slot", null, this.label)),
4625
- ];
2269
+ handleGroupChange(direction) {
2270
+ const delta = direction === 'forward' ? PER_PAGE : -10;
2271
+ const newPage = Math.min(Math.max(this.currentPage + delta, 1), this.lastPage);
2272
+ this.handlePageChange(newPage);
4626
2273
  }
4627
- render() {
4628
- const tagClasses = this.getTagClasses();
4629
- return (index.h("span", { key: '44457ea67e6c6bc78f134df71beb8d16cc069f41', class: tagClasses, style: {
4630
- '--tag-bg-color': this.bgColor,
4631
- '--tag-text-color': this.textColor,
4632
- }, "aria-label": this.label || 'tag' }, this.renderContent()));
2274
+ get isFirstGroup() {
2275
+ return this.currentPage <= PER_PAGE;
4633
2276
  }
4634
- };
4635
- SdTag.style = sdTagCss();
4636
-
4637
- const sdToastMessageCss = () => `.sd-toast-message.sc-sd-toast-message{display:flex;width:fit-content;align-items:center;gap:16px;padding:12px 24px;border-radius:4px;background-color:var(--sd-toast-bg);color:var(--sd-toast-text);transition:opacity 0.2s ease, visibility 0.2s ease;box-shadow:2px 2px 8px 2px rgba(0, 0, 0, 0.2)}.sd-toast-message--hidden.sc-sd-toast-message{opacity:0;visibility:hidden;pointer-events:none}.sd-toast-message__icon.sc-sd-toast-message{display:flex;align-items:center;flex-shrink:0}.sd-toast-message__content.sc-sd-toast-message{display:flex;flex:1}.sd-toast-message__message.sc-sd-toast-message{font-size:14px;line-height:20px;font-weight:400}.sd-toast-message__link.sc-sd-toast-message{font-size:14px;line-height:20px;color:var(--sd-toast-text);text-decoration:underline;cursor:pointer;transition:opacity 0.2s ease;margin-left:4px}.sd-toast-message__link.sc-sd-toast-message:hover{opacity:0.8}.sd-toast-message__button.sc-sd-toast-message{flex-shrink:0}.sd-toast-message__button.sc-sd-toast-message button.sc-sd-toast-message{color:var(--button-text-color, inherit) !important}.sd-toast-message__close.sc-sd-toast-message{display:flex;align-items:center;justify-content:center;padding:4px;background-color:transparent;border:none;cursor:pointer;transition:opacity 0.2s ease;flex-shrink:0}.sd-toast-message__close.sc-sd-toast-message:hover{opacity:0.7}.sd-toast-message__close.sc-sd-toast-message:active{opacity:0.5}`;
4638
-
4639
- const SdToastMessage = class {
4640
- constructor(hostRef) {
4641
- index.registerInstance(this, hostRef);
4642
- this.sdClose = index.createEvent(this, "sdClose");
4643
- this.sdButtonClick = index.createEvent(this, "sdButtonClick");
2277
+ get isLastGroup() {
2278
+ const startPageGroup = Math.floor((this.currentPage - 1) / PER_PAGE) * PER_PAGE + 1;
2279
+ return startPageGroup + PER_PAGE - 1 >= this.lastPage;
4644
2280
  }
4645
- icon;
4646
- message;
4647
- link;
4648
- linkLabel;
4649
- buttonLabel;
4650
- close = false;
4651
- type = 'basicDark';
4652
- sdClose;
4653
- sdButtonClick;
4654
- isVisible = true;
4655
- static COLOR_OF_TYPE = {
4656
- basicLight: { background: 'white', text: 'grey_95' },
4657
- basicDark: { background: 'steelblue_90', text: 'white' },
4658
- error: { background: 'red_70', text: 'white' },
4659
- caution: { background: 'yellow_40', text: 'grey_90' },
4660
- complete: { background: 'green_75', text: 'white' },
4661
- progress: { background: 'brilliantblue_80', text: 'white' },
4662
- };
4663
- handleClose = () => {
4664
- this.isVisible = false;
4665
- this.sdClose.emit();
4666
- };
4667
- handleButtonClick = () => {
4668
- this.sdButtonClick.emit();
4669
- };
4670
- getContainerClasses() {
4671
- const classes = ['sd-toast-message', `sd-toast-message--${this.type}`];
4672
- if (!this.isVisible) {
4673
- classes.push('sd-toast-message--hidden');
2281
+ renderPrevButtons() {
2282
+ if (this.simple) {
2283
+ if (this.currentPage <= 1)
2284
+ return null;
2285
+ return (index.h(index.Fragment, null, index.h("button", { "aria-label": "Go to first page", onClick: () => this.handlePageChange(1) }, index.h("sd-icon", { name: "arrowLeftEnd", size: "12", color: "#222222" })), index.h("button", { "aria-label": "Go to previous page", onClick: () => this.handlePageChange(this.currentPage - 1) }, index.h("sd-icon", { name: "arrowLeft", size: "12", color: "#222222" }))));
2286
+ }
2287
+ if (!this.isFirstGroup) {
2288
+ return (index.h(index.Fragment, null, index.h("button", { "aria-label": "Go to first page", onClick: () => this.handlePageChange(1) }, index.h("sd-icon", { name: "arrowLeftEnd", size: "12", color: "#222222" })), index.h("button", { "aria-label": "Go to previous page group", onClick: () => this.handleGroupChange('backward') }, index.h("sd-icon", { name: "arrowLeft", size: "12", color: "#222222" }))));
2289
+ }
2290
+ }
2291
+ renderNextButtons() {
2292
+ if (this.simple) {
2293
+ if (this.currentPage >= this.lastPage)
2294
+ return null;
2295
+ return (index.h(index.Fragment, null, index.h("button", { "aria-label": "Go to next page", onClick: () => this.handlePageChange(this.currentPage + 1) }, index.h("sd-icon", { name: "arrowRight", size: "12", color: "#222222" })), index.h("button", { "aria-label": "Go to last page", onClick: () => this.handlePageChange(this.lastPage) }, index.h("sd-icon", { name: "arrowRightEnd", size: "12", color: "#222222" }))));
2296
+ }
2297
+ if (!this.isLastGroup) {
2298
+ return (index.h(index.Fragment, null, index.h("button", { "aria-label": "Go to next page group", onClick: () => this.handleGroupChange('forward') }, index.h("sd-icon", { name: "arrowRight", size: "12", color: "#222222" })), index.h("button", { "aria-label": "Go to last page", onClick: () => this.handlePageChange(this.lastPage) }, index.h("sd-icon", { name: "arrowRightEnd", size: "12", color: "#222222" }))));
4674
2299
  }
4675
- return classes.join(' ');
4676
2300
  }
4677
2301
  render() {
4678
- const colorTokens = SdToastMessage.COLOR_OF_TYPE[this.type];
4679
- const colors = {
4680
- background: resolveColor.resolveColor(colorTokens.background),
4681
- text: resolveColor.resolveColor(colorTokens.text),
4682
- };
4683
- return (index.h(index.Host, { key: '08b9ea203d36fbb3c6da642f3fc4355209867042', style: {
4684
- '--sd-toast-bg': colors.background,
4685
- '--sd-toast-text': colors.text,
4686
- } }, index.h("div", { key: '9b93919198c900453ff04a7dd71985f829967803', class: this.getContainerClasses(), role: "status", "aria-live": "polite", "aria-atomic": "true" }, this.icon && (index.h("div", { key: '6d1775a1d5c9e4b55fdac888f9dea6e806a76b14', class: "sd-toast-message__icon" }, index.h("sd-icon", { key: 'd122832fa3b011792eb81f31296177d2dd99d571', name: this.icon, size: 16, color: colors.text }))), index.h("div", { key: '63e5f2f2bc800d24559fb5fb8a2e92e575f2b119', class: "sd-toast-message__content" }, index.h("span", { key: '2422d351d2019333f5085e8c0fdcb3cbf58b5b67', class: "sd-toast-message__message" }, this.message)), this.link && (index.h("a", { key: '766716d0ddf7da45d78b4e84a55f12c66e95a8f3', href: this.link, class: "sd-toast-message__link", target: "_blank", rel: "noopener noreferrer" }, this.linkLabel || this.link)), this.buttonLabel && (index.h("sd-button", { key: '8b1e262e5da42e324cb392fc950c02c82005987c', class: `sd-toast-message__button ${this.type === 'basicLight' ? 'text-white' : ''}`, label: this.buttonLabel, variant: "primary", color: this.type === 'basicLight' ? 'oceanblue_75' : 'white', size: "sm", onSdClick: this.handleButtonClick, style: this.type !== 'basicLight' ? { '--button-text-color': resolveColor.resolveColor('grey_95') } : {} })), this.close && (index.h("button", { key: '42d20adef4a675644958116f8bbb987f131e194c', type: "button", class: "sd-toast-message__close", onClick: this.handleClose, "aria-label": "Close", title: "Close" }, index.h("sd-icon", { key: '5141cf3044ba13b541091bb79b3040e1eabc0b17', name: "close", size: 12, color: colors.text }))))));
2302
+ return (index.h("div", { key: 'de62debd728759c709660924b2d9a5691f1e60ea', class: this.paginationClasses }, index.h("div", { key: '9da6071df92e8910fe19a9e20cdc38e2ef1e4fe7', class: "prepend-btns" }, this.renderPrevButtons()), this.simple ? (index.h("div", { class: "pagination-info" }, index.h("span", { class: "current-page" }, this.currentPage), index.h("span", null, "/"), index.h("span", { class: "last-page" }, this.lastPage))) : (this.pageNumbers.map(n => (index.h("button", { type: "button", "aria-current": this.currentPage === n ? 'page' : undefined, class: {
2303
+ 'pagination-btn': true,
2304
+ 'pagination-btn--selected': this.currentPage === n,
2305
+ }, disabled: this.currentPage === n, style: {
2306
+ '--pagination-btn-width': `${this.buttonWidth}px`,
2307
+ }, onClick: () => this.handlePageChange(n) }, n)))), index.h("div", { key: '7951a5ea2aabf30619d21073cd728dffaf14b7bd', class: "append-btns" }, this.renderNextButtons())));
4687
2308
  }
4688
2309
  };
4689
- SdToastMessage.style = sdToastMessageCss();
2310
+ SdPagination.style = sdPaginationCss();
4690
2311
 
4691
- const sdToggleCss = () => `sd-toggle{display:inline-block;height:20px;line-height:0}sd-toggle .sd-toggle{cursor:pointer;display:inline-flex;align-items:center;gap:8px;height:20px}sd-toggle .sd-toggle>input{display:none}sd-toggle .sd-toggle__label{font-size:12px;color:#333333;line-height:20px}sd-toggle .sd-toggle__track{width:36px;height:20px;border-radius:12px;background:#cccccc;position:relative;transition:background-color 0.2s ease}sd-toggle .sd-toggle__thumb{width:16px;height:16px;border-radius:50%;background:white;position:absolute;top:2px;left:2px;transition:transform 0.2s ease}sd-toggle .sd-toggle--checked .sd-toggle__track{background:#0075ff}sd-toggle .sd-toggle--checked .sd-toggle__thumb{transform:translateX(16px)}sd-toggle .sd-toggle--disabled{cursor:not-allowed}sd-toggle .sd-toggle--disabled.sd-toggle--checked .sd-toggle__track{background:#bbdaff}sd-toggle .sd-toggle--disabled.sd-toggle--unchecked .sd-toggle__track{background:#eeeeee}sd-toggle .sd-toggle:hover:not(.sd-toggle--disabled).sd-toggle--checked .sd-toggle__track{background:#005cc9}sd-toggle .sd-toggle:hover:not(.sd-toggle--disabled).sd-toggle--unchecked .sd-toggle__track{background:#bbbbbb}`;
2312
+ const sdTextareaCss = () => `.sd-textarea{display:flex;flex-direction:column;color:#333333;font-size:12px;line-height:20px;width:var(--textarea-width, 100%)}.sd-textarea .sd-textarea__content{width:100%;display:flex;border:1px solid #aaaaaa;border-radius:4px;background:white}.sd-textarea .sd-textarea__content .sd-textarea__native{width:100%;min-height:100px;border:none;outline:none;background:transparent;padding:4px 8px;font-family:inherit;font-size:12px;line-height:20px;color:#333333;resize:vertical}.sd-textarea .sd-textarea__content .sd-textarea__native::placeholder{color:#aaaaaa}.sd-textarea--hovered .sd-textarea__content,.sd-textarea--focused .sd-textarea__content{border-color:#0075ff;box-shadow:0 0 4px 0 rgba(0, 113, 255, 0.4)}.sd-textarea--disabled{cursor:not-allowed !important;box-shadow:none !important}.sd-textarea--disabled .sd-textarea__content{background:#eeeeee !important;border:1px solid #cccccc !important;color:#888888 !important}.sd-textarea--disabled .sd-textarea__content .sd-textarea__native{cursor:not-allowed !important;color:#888888 !important}.sd-textarea .sd-textarea__footer{display:flex;justify-content:space-between;align-items:center;margin-top:4px;font-size:12px;line-height:20px}.sd-textarea .sd-textarea__help-text{font-size:12px;line-height:20px;font-weight:400;color:#222222}.sd-textarea .sd-textarea__counter{color:#cccccc;margin-left:auto}`;
4692
2313
 
4693
- const SdToggle = class {
2314
+ const SdTextarea = class {
4694
2315
  constructor(hostRef) {
4695
2316
  index.registerInstance(this, hostRef);
4696
- this.sdChange = index.createEvent(this, "sdChange");
2317
+ this.input = index.createEvent(this, "sdUpdate");
2318
+ this.focus = index.createEvent(this, "sdFocus");
2319
+ this.blur = index.createEvent(this, "sdBlur");
4697
2320
  }
4698
- value = false;
4699
- label = '';
2321
+ get host() { return index.getElement(this); }
2322
+ value = null;
2323
+ name;
4700
2324
  disabled = false;
4701
- isChecked = false;
4702
- sdChange;
4703
- componentWillLoad() {
4704
- this.updateCheckedState(this.value);
4705
- }
4706
- componentWillRender() {
4707
- this.updateCheckedState(this.value);
4708
- }
4709
- updateCheckedState(value) {
4710
- this.isChecked = value;
2325
+ width;
2326
+ autoFocus = false;
2327
+ textareaClass = '';
2328
+ helpText;
2329
+ maxLength;
2330
+ placeholder = '입력해 주세요.';
2331
+ internalValue = null;
2332
+ focused = false;
2333
+ hovered = false;
2334
+ nativeEl = undefined;
2335
+ input;
2336
+ focus;
2337
+ blur;
2338
+ valueChanged(newValue) {
2339
+ this.internalValue = newValue;
4711
2340
  }
4712
- get toggleClasses() {
4713
- const classes = ['sd-toggle', this.isChecked ? 'sd-toggle--checked' : 'sd-toggle--unchecked'];
4714
- if (this.disabled) {
4715
- classes.push('sd-toggle--disabled');
2341
+ internalValueChanged(newValue) {
2342
+ if (newValue !== this.value) {
2343
+ this.value = newValue;
2344
+ this.input?.emit(this.value);
4716
2345
  }
4717
- return classes.join(' ');
4718
2346
  }
4719
- handleChange = () => {
4720
- if (this.disabled)
4721
- return;
4722
- const newValue = !this.value;
4723
- this.value = newValue;
4724
- this.sdChange.emit(newValue);
4725
- };
4726
- render() {
4727
- return (index.h("label", { key: 'ba2398d6eb054c00c526ab1ada37b09e4d6602a3', "aria-checked": this.isChecked.toString(), "aria-disabled": this.disabled.toString(), role: "switch", "aria-label": this.label || 'toggle', class: this.toggleClasses }, index.h("input", { key: 'b7da299e1dacd7d41bc1cd72d5bc135d5ecd52fd', type: "checkbox", checked: this.isChecked, disabled: this.disabled, onInput: this.handleChange }), this.label && index.h("span", { key: 'b6ddc87485036dee698eb099d7343edd4163d7b0', class: "sd-toggle__label" }, this.label), index.h("div", { key: '2439852af329488d50907ee132a6fd819129a6a0', class: "sd-toggle__track" }, index.h("div", { key: '72114f2bec9e0372b05d90df8099dc9aad812e3d', class: "sd-toggle__thumb" }))));
2347
+ async sdFocus() {
2348
+ this.nativeEl?.focus();
4728
2349
  }
4729
- };
4730
- SdToggle.style = sdToggleCss();
4731
-
4732
- const sdToggleButtonCss = () => `sd-toggle-button{display:inline-block;line-height:0}.sd-toggle-button{display:inline-flex;align-items:center;justify-content:center;height:28px;padding:4px 12px;gap:6px;border-radius:14px;border:1px solid #888888;background-color:#ffffff;color:#737373;font-size:12px;line-height:20px;font-weight:400;cursor:pointer;transition:border-color 0.2s ease, color 0.2s ease, background-color 0.2s ease;white-space:nowrap;user-select:none;box-sizing:border-box}.sd-toggle-button--active{border-color:#0075ff;color:#0075ff}.sd-toggle-button--disabled{background-color:#eeeeee;border-color:#cccccc;color:#888888;cursor:not-allowed}.sd-toggle-button--disabled.sd-toggle-button--active{background-color:#eeeeee;border-color:#cccccc;color:#888888}.sd-toggle-button:hover:not(.sd-toggle-button--disabled):not(.sd-toggle-button--active){border-color:#737373}.sd-toggle-button:hover:not(.sd-toggle-button--disabled).sd-toggle-button--active{border-color:#005cc9;color:#005cc9}`;
4733
-
4734
- const SdToggleButton = class {
4735
- constructor(hostRef) {
4736
- index.registerInstance(this, hostRef);
4737
- this.sdChange = index.createEvent(this, "sdChange");
2350
+ async getNativeElement() {
2351
+ return this.nativeEl || null;
4738
2352
  }
4739
- value = false;
4740
- label = '';
4741
- disabled = false;
4742
- isActive = false;
4743
- sdChange;
4744
2353
  componentWillLoad() {
4745
- this.updateActiveState(this.value);
2354
+ if (this.value !== null && this.value !== undefined) {
2355
+ this.internalValue = this.value;
2356
+ }
4746
2357
  }
4747
- componentWillRender() {
4748
- this.updateActiveState(this.value);
2358
+ componentDidLoad() {
2359
+ if (this.autoFocus) {
2360
+ this.nativeEl?.focus();
2361
+ }
4749
2362
  }
4750
- updateActiveState(value) {
4751
- this.isActive = value;
2363
+ handleInput(event) {
2364
+ const target = event.target;
2365
+ this.internalValue = target.value;
4752
2366
  }
4753
- get buttonClasses() {
4754
- const classes = ['sd-toggle-button'];
4755
- if (this.isActive) {
4756
- classes.push('sd-toggle-button--active');
2367
+ handleFocus(type, event) {
2368
+ this.focused = type === 'focus';
2369
+ if (type === 'blur') {
2370
+ this.blur?.emit(event);
4757
2371
  }
4758
- if (this.disabled) {
4759
- classes.push('sd-toggle-button--disabled');
2372
+ else {
2373
+ this.focus?.emit(event);
4760
2374
  }
4761
- return classes.join(' ');
4762
2375
  }
4763
- handleChange = () => {
2376
+ getTextareaStatus() {
4764
2377
  if (this.disabled)
4765
- return;
4766
- const newValue = !this.value;
4767
- this.value = newValue;
4768
- this.sdChange.emit(newValue);
4769
- };
2378
+ return 'sd-textarea--disabled';
2379
+ if (this.hovered)
2380
+ return 'sd-textarea--hovered';
2381
+ if (this.focused)
2382
+ return 'sd-textarea--focused';
2383
+ return '';
2384
+ }
2385
+ getMaxLengthCounter() {
2386
+ if (this.maxLength === undefined) {
2387
+ return null;
2388
+ }
2389
+ const currentLength = (this.internalValue || '').length;
2390
+ return `${currentLength}/${this.maxLength}`;
2391
+ }
2392
+ hasFooter() {
2393
+ return this.helpText !== undefined || this.maxLength !== undefined;
2394
+ }
4770
2395
  render() {
4771
- return (index.h("label", { key: '54d45d11b3944c61147d5bd0fa68078aa28737f1', class: this.buttonClasses, role: "button", "aria-pressed": this.isActive.toString(), "aria-disabled": this.disabled.toString(), "aria-label": this.label || 'toggle button' }, this.label, index.h("input", { key: 'cafb7edbcaead5e487b756a006cfee9b9d890558', style: { display: 'none' }, type: "checkbox", onInput: this.handleChange })));
2396
+ const textareaWidth = this.width
2397
+ ? {
2398
+ '--textarea-width': typeof this.width === 'number' ? `${this.width}px` : this.width,
2399
+ }
2400
+ : {};
2401
+ const maxLengthCounter = this.getMaxLengthCounter();
2402
+ return (index.h(index.Host, { key: 'db95720b6b96d950d6435b1881f95d58c6bc4637', style: textareaWidth, class: {
2403
+ 'sd-textarea': true,
2404
+ [this.getTextareaStatus()]: true,
2405
+ }, onMouseEnter: () => (this.hovered = true), onMouseLeave: () => (this.hovered = false) }, index.h("div", { key: '3dae36a9b56837fa7d770f295359d8ed9aa2a3e4', class: "sd-textarea__content" }, index.h("textarea", { key: 'b9e4ff3cffc1b06e4ef6e5ffee240579c80c6d94', name: this.name, ref: el => (this.nativeEl = el), class: `sd-textarea__native ${this.textareaClass}`, value: this.internalValue || '', placeholder: this.placeholder, disabled: this.disabled, autofocus: this.autoFocus, maxLength: this.maxLength, onInput: this.handleInput.bind(this), onFocus: event => this.handleFocus('focus', event), onBlur: event => this.handleFocus('blur', event) })), this.hasFooter() && (index.h("div", { key: 'b0de9e449897f2a8d1e6a7204d2383551d3ae2e4', class: "sd-textarea__footer" }, this.helpText !== undefined && index.h("span", { key: 'b4528beb70095d70a030a70f451c59e511865fcb', class: "sd-textarea__help-text" }, this.helpText), maxLengthCounter !== null && index.h("span", { key: 'ce2d33888c7bd85ea240ce00851aec7ecd945adc', class: "sd-textarea__counter" }, maxLengthCounter)))));
4772
2406
  }
2407
+ static get watchers() { return {
2408
+ "value": ["valueChanged"],
2409
+ "internalValue": ["internalValueChanged"]
2410
+ }; }
4773
2411
  };
4774
- SdToggleButton.style = sdToggleButtonCss();
2412
+ SdTextarea.style = sdTextareaCss();
4775
2413
 
4776
- const sdTooltipCss = () => `sd-tooltip [slot=content]{display:none}sd-tooltip .sd-tooltip{position:relative;cursor:pointer;display:inline-flex;align-items:center;justify-content:center}.sd-tooltip-menu{width:fit-content;padding:8px 16px;border-radius:4px;font-size:12px;position:relative;box-sizing:border-box;display:flex;align-items:start;justify-content:center;gap:12px}.sd-tooltip-menu--with-close{padding-right:12px !important}.sd-tooltip-menu__arrow{position:absolute;display:flex;width:9.6px;height:7.2px}.sd-tooltip-menu__arrow svg{width:100%;height:100%}.sd-tooltip-menu__arrow--top{bottom:-7.2px;left:50%;transform:translateX(-50%)}.sd-tooltip-menu__arrow--bottom{top:-7.2px;left:50%;transform:translateX(-50%) rotate(180deg)}.sd-tooltip-menu__arrow--left{right:-7.2px;top:50%;transform:translateY(-50%) rotate(-90deg)}.sd-tooltip-menu__arrow--right{left:-7.2px;top:50%;transform:translateY(-50%) rotate(90deg)}.sd-tooltip-menu__content{line-height:20px;font-weight:500}.sd-tooltip-menu__content p{margin:0}.sd-tooltip-menu__close-button{padding-top:4px;display:flex}.sd-tooltip-menu__close-button button{padding:0;background:none;border:none;cursor:pointer}`;
2414
+ const sdTooltipCss = () => `sd-tooltip{visibility:hidden !important;display:inline-flex}sd-tooltip.visible{visibility:visible !important}sd-tooltip .sd-tooltip{position:relative;cursor:pointer;display:inline-flex;align-items:center;justify-content:center}`;
4777
2415
 
4778
2416
  const SdTooltip = class {
4779
2417
  constructor(hostRef) {
@@ -4792,25 +2430,16 @@ const SdTooltip = class {
4792
2430
  noHover = true;
4793
2431
  useClose = false;
4794
2432
  showTooltip = false;
4795
- slotContent = null;
4796
- static COLOR_OF_TYPE = {
4797
- default: { background: 'oceanblue_85', text: 'white' },
4798
- caution: { background: 'red_20', text: 'red_70' },
4799
- notice: { background: 'orange_10', text: 'orange_65' },
4800
- accent: { background: 'brilliantblue_20', text: 'brilliantblue_75' },
4801
- };
2433
+ slotContentHTML = '';
4802
2434
  buttonEl;
4803
2435
  handleClose = () => {
4804
2436
  this.showTooltip = false;
4805
2437
  };
4806
- // 현재 tooltip popover가 조건부 렌더링이여서 초기 slot이 렌더링 되지 않은 시점에
4807
- // 데이터 매핑에 실패 (light dom에 저장된 slot내용을 shadow dom을 찾지못해 매핑 실패)
4808
- // 따라서 slot내용을 받은 후에 복제하여 state에 저장
4809
2438
  componentWillLoad() {
4810
- const contentEl = this.el.querySelector('[slot="content"]');
4811
- if (contentEl) {
4812
- this.slotContent = contentEl.cloneNode(true);
4813
- }
2439
+ this.slotContentHTML = this.el.innerHTML;
2440
+ this.el.replaceChildren();
2441
+ // 깜빡이는 현상을 막기 위해 기본으로 <sd-tooltip></sd-tooltip> hidden이 된 elment를 visible로 만들어줌
2442
+ this.el.classList.toggle('visible', true);
4814
2443
  }
4815
2444
  render() {
4816
2445
  const handleTrigger = this.trigger === 'hover'
@@ -4821,199 +2450,20 @@ const SdTooltip = class {
4821
2450
  : {
4822
2451
  onClick: () => (this.showTooltip = !this.showTooltip),
4823
2452
  };
4824
- return (index.h(index.Fragment, { key: '1016ad941100e902068b5a7d7773a2dbf7ab0667' }, this.label ? (index.h("sd-button", { ref: el => (this.buttonEl = el), label: this.label, icon: this.icon, size: this.buttonSize, color: this.color, variant: this.buttonVariant, class: "sd-tooltip", ...handleTrigger })) : (index.h("sd-icon", { ref: el => (this.buttonEl = el), name: this.icon, size: this.iconSize, color: this.color, class: "sd-tooltip", ...handleTrigger })), this.showTooltip && (index.h("sd-tooltip-portal", { key: '8370b55d3bafa7a5ca429ee17c7555cfdb9e51a2', parentRef: this.buttonEl, onSdClose: () => this.handleClose(), placement: this.placement }, index.h("div", { key: '94a8d13f88050792b3e307901c2545995d92fdaf', class: {
4825
- 'sd-tooltip-menu': true,
4826
- [`sd-tooltip-menu--${this.type}`]: true,
4827
- [`sd-tooltip-menu--${this.placement}`]: true,
4828
- 'sd-tooltip-menu--with-close': this.useClose,
4829
- [`bg-${SdTooltip.COLOR_OF_TYPE[this.type].background}`]: true,
4830
- [`text-${SdTooltip.COLOR_OF_TYPE[this.type].text}`]: true,
4831
- } }, index.h("i", { key: 'b13f215dc7f51af86e7748a0ac565f62cbd936ef', class: `sd-tooltip-menu__arrow sd-tooltip-menu__arrow--${this.placement}` }, index.h(tooltipArrow.TooltipArrow, { key: 'a043ccc525e18baed8c9b4d5cdd7651c4600b4e4', class: {
4832
- [`text-${SdTooltip.COLOR_OF_TYPE[this.type].background}`]: true,
4833
- } })), index.h("div", { key: '60e67cc4620b07153a8cef098446e0a292f08230', class: "sd-tooltip-menu__content", ref: el => {
4834
- if (el && this.slotContent && !el.hasChildNodes()) {
4835
- el.appendChild(this.slotContent.cloneNode(true));
4836
- }
4837
- } }, !this.slotContent && index.h("span", { key: 'e2e2afd2e2607be01d474c9329cd15b280214cd0' }, this.el.textContent)), this.useClose && (index.h("div", { key: '25962f34a91f8838e32c25529cacf048b2bbcf6b', class: "sd-tooltip-menu__close-button" }, index.h("button", { key: '5e37a4c9bace03a0c2a26edb0125ac0f25c65784', type: "button", "aria-label": "Close tooltip", title: "Close tooltip", onClick: () => this.handleClose() }, index.h("sd-icon", { key: 'ed7c97b16a507b8fad10d58f4e5a38061517b88a', name: "close", size: "12", color: "#AAAAAA" })))))))));
2453
+ return (index.h(index.Fragment, { key: 'd0db4bd2d57b38eae1522abd96c2776d6ffdd7c7' }, this.label ? (index.h("sd-button", { ref: el => (this.buttonEl = el), label: this.label, icon: this.icon, size: this.buttonSize, color: this.color, variant: this.buttonVariant, class: "sd-tooltip", ...handleTrigger })) : (index.h("sd-icon", { ref: el => (this.buttonEl = el), name: this.icon, size: this.iconSize, color: this.color, class: "sd-tooltip", ...handleTrigger })), this.showTooltip && (index.h("sd-floating-portal", { key: 'ef5951d34aa4a0b5b831eadf464ab2c6711b9320', parentRef: this.buttonEl, onSdClose: this.handleClose.bind(this), placement: this.placement }, index.h("div", { key: '07f7090e1de9461d1a67b092631e1c8daae1abaa', class: {
2454
+ 'sd-floating-menu': true,
2455
+ [`sd-floating-menu--${this.type}`]: true,
2456
+ [`sd-floating-menu--${this.placement}`]: true,
2457
+ 'sd-floating-menu--with-close': this.useClose,
2458
+ } }, index.h("i", { key: '2e8a1f6d7c2159ed48819229ee41ab75237ad2c2', class: `sd-floating-menu__arrow sd-floating-menu__arrow--${this.placement}` }, index.h(tooltipArrow.TooltipArrow, { key: '8bc18f6aeb197026ead06ef02837a70f924752f5' })), index.h("div", { key: 'cb91d969f481e7e1cf22e4a84aed3237b7b22376', class: "sd-floating-menu__content", innerHTML: this.slotContentHTML }), this.useClose && (index.h("div", { key: '856bf6d63862406177c32400e3d919f5fcd1c8df', class: "sd-floating-menu__close-button" }, index.h("button", { key: '83e107c58f9bc7927c449a186b19e6fa4730e53f', type: "button", "aria-label": "Close tooltip", title: "Close tooltip", onClick: this.handleClose.bind(this) }, index.h("sd-icon", { key: 'dc9dc331be0c6eb3ae96150ea50515f021746260', name: "close", size: "12", color: "#AAAAAA" })))))))));
4838
2459
  }
4839
2460
  };
4840
2461
  SdTooltip.style = sdTooltipCss();
4841
2462
 
4842
- const SdTooltipPortal = class {
4843
- constructor(hostRef) {
4844
- index.registerInstance(this, hostRef);
4845
- this.sdClose = index.createEvent(this, "sdClose");
4846
- }
4847
- get el() { return index.getElement(this); }
4848
- to = 'body';
4849
- parentRef = null;
4850
- offset = [0, 0];
4851
- zIndex = 9999;
4852
- placement = 'bottom';
4853
- open = false;
4854
- sdClose;
4855
- container;
4856
- wrapper;
4857
- rafId;
4858
- isInsideClick = false;
4859
- resizeObserver;
4860
- mutationObserver;
4861
- static ARROW_SIZE = 11.2;
4862
- componentDidLoad() {
4863
- this.container = this.resolveContainer();
4864
- this.createWrapper();
4865
- this.moveSlotContent();
4866
- // DOM이 완전히 렌더링된 후 위치 계산
4867
- requestAnimationFrame(() => {
4868
- this.updatePosition();
4869
- if (this.wrapper) {
4870
- this.wrapper.style.visibility = 'visible'; // 위치 계산 후 표시
4871
- }
4872
- });
4873
- this.observeParent();
4874
- }
4875
- componentDidRender() {
4876
- if (!this.wrapper)
4877
- return;
4878
- // this.wrapper.style.display = this.open ? 'block' : 'none';
4879
- // if (this.open) this.updatePosition();
4880
- if (this.open) {
4881
- this.wrapper.style.display = 'block';
4882
- // RAF를 사용해서 다음 프레임에 위치 업데이트
4883
- requestAnimationFrame(() => {
4884
- this.updatePosition();
4885
- if (this.wrapper) {
4886
- this.wrapper.style.visibility = 'visible';
4887
- }
4888
- });
4889
- }
4890
- else {
4891
- this.wrapper.style.display = 'none';
4892
- this.wrapper.style.visibility = 'hidden';
4893
- }
4894
- }
4895
- disconnectedCallback() {
4896
- if (this.rafId)
4897
- cancelAnimationFrame(this.rafId);
4898
- this.unobserveParent();
4899
- this.wrapper?.remove();
4900
- }
4901
- resolveContainer() {
4902
- const el = typeof this.to === 'string' ? document.querySelector(this.to) : this.to;
4903
- return el instanceof HTMLElement ? el : document.body;
4904
- }
4905
- createWrapper() {
4906
- this.wrapper = document.createElement('div');
4907
- Object.assign(this.wrapper.style, {
4908
- position: 'absolute',
4909
- zIndex: this.zIndex.toString(),
4910
- transition: 'opacity 0.4s',
4911
- top: '-9999px',
4912
- left: '-9999px',
4913
- });
4914
- this.container.appendChild(this.wrapper);
4915
- }
4916
- moveSlotContent() {
4917
- if (!this.wrapper)
4918
- return;
4919
- const nodes = Array.from(this.el.childNodes).filter(n => n.nodeType !== Node.COMMENT_NODE);
4920
- nodes.forEach(n => this.wrapper.appendChild(n));
4921
- }
4922
- // 위치 갱신 (scroll / resize)
4923
- updatePosition() {
4924
- if (this.rafId)
4925
- cancelAnimationFrame(this.rafId);
4926
- this.rafId = requestAnimationFrame(() => {
4927
- if (!this.parentRef || !this.wrapper)
4928
- return;
4929
- const rect = this.parentRef.getBoundingClientRect();
4930
- if (!rect.width && !rect.height)
4931
- return; // 요소가 보이지 않는 경우
4932
- const [offsetX, offsetY] = this.offset;
4933
- const ARROW_SIZE = SdTooltipPortal.ARROW_SIZE;
4934
- let top = 0;
4935
- let left = 0;
4936
- switch (this.placement) {
4937
- case 'top':
4938
- top = rect.top + window.scrollY - this.wrapper.offsetHeight + offsetY - ARROW_SIZE;
4939
- left = rect.left + window.scrollX + rect.width / 2 - this.wrapper.offsetWidth / 2 + offsetX;
4940
- break;
4941
- case 'bottom':
4942
- top = rect.bottom + window.scrollY + offsetY + ARROW_SIZE;
4943
- left = rect.left + window.scrollX + rect.width / 2 - this.wrapper.offsetWidth / 2 + offsetX;
4944
- break;
4945
- case 'left':
4946
- top = rect.top + window.scrollY + rect.height / 2 - this.wrapper.offsetHeight / 2 + offsetY;
4947
- left = rect.left + window.scrollX - this.wrapper.offsetWidth - offsetX - ARROW_SIZE;
4948
- break;
4949
- case 'right':
4950
- top = rect.top + window.scrollY + rect.height / 2 - this.wrapper.offsetHeight / 2 + offsetY;
4951
- left = rect.right + window.scrollX + offsetX + ARROW_SIZE;
4952
- break;
4953
- }
4954
- Object.assign(this.wrapper.style, {
4955
- top: `${top}px`,
4956
- left: `${left}px`,
4957
- });
4958
- });
4959
- }
4960
- // parentRef의 이동 / 크기변경 감지
4961
- observeParent() {
4962
- if (!this.parentRef)
4963
- return;
4964
- this.resizeObserver = new ResizeObserver(() => this.updatePosition());
4965
- this.resizeObserver.observe(this.parentRef);
4966
- this.mutationObserver = new MutationObserver(() => this.updatePosition());
4967
- this.mutationObserver.observe(document.body, {
4968
- childList: true,
4969
- subtree: true,
4970
- });
4971
- }
4972
- unobserveParent() {
4973
- this.resizeObserver?.disconnect();
4974
- this.mutationObserver?.disconnect();
4975
- }
4976
- // 외부 클릭 감지
4977
- handleMouseDown(e) {
4978
- this.isInsideClick = !!((this.wrapper && this.wrapper.contains(e.target)) ||
4979
- (this.parentRef && this.parentRef.contains(e.target)));
4980
- }
4981
- handleWindowClick(e) {
4982
- if (this.isInsideClick) {
4983
- this.isInsideClick = false;
4984
- return;
4985
- }
4986
- if (this.wrapper?.contains(e.target))
4987
- return;
4988
- this.sdClose.emit();
4989
- }
4990
- render() {
4991
- return index.h("slot", { key: 'f26d3228d5c0965c2303e599259a6e93307009dc' });
4992
- }
4993
- };
4994
-
4995
2463
  exports.sd_button = SdButton;
4996
- exports.sd_checkbox = SdCheckbox;
4997
- exports.sd_file_picker = SdFilePicker;
4998
- exports.sd_guide = SdGuide;
2464
+ exports.sd_floating_portal = SdFloatingPopover;
4999
2465
  exports.sd_icon = SdIcon;
5000
- exports.sd_input = SdInput;
5001
- exports.sd_loading_spinner = SdLoadingSpinner;
5002
- exports.sd_number_input = SdNumberInput;
5003
2466
  exports.sd_pagination = SdPagination;
5004
- exports.sd_portal = SdPortal;
5005
- exports.sd_radio_group = SdRadioGroup;
5006
- exports.sd_select = SdSelect;
5007
- exports.sd_select_multiple_group = SdSelectMultipleGroup;
5008
- exports.sd_select_option = SdSelectOption;
5009
- exports.sd_select_option_group = SdSelectOptionGroup;
5010
- exports.sd_select_search_input = SdSelectSearchInput;
5011
- exports.sd_table_backup = SdTable;
5012
- exports.sd_tabs = SdTabs;
5013
- exports.sd_tag = SdTag;
5014
- exports.sd_toast_message = SdToastMessage;
5015
- exports.sd_toggle = SdToggle;
5016
- exports.sd_toggle_button = SdToggleButton;
2467
+ exports.sd_textarea = SdTextarea;
5017
2468
  exports.sd_tooltip = SdTooltip;
5018
- exports.sd_tooltip_portal = SdTooltipPortal;
5019
- //# sourceMappingURL=sd-button.sd-checkbox.sd-file-picker.sd-guide.sd-icon.sd-input.sd-loading-spinner.sd-number-input.sd-pagination.sd-portal.sd-radio-group.sd-select.sd-select-multiple-group.sd-select-option.sd-select-option-group.sd-select-search-input.sd-table-backup.sd-tabs.sd-tag.sd-toast-message.sd-toggle.sd-toggle-button.sd-tooltip.sd-tooltip-portal.entry.cjs.js.map
2469
+ //# sourceMappingURL=sd-button.sd-floating-portal.sd-icon.sd-pagination.sd-textarea.sd-tooltip.entry.cjs.js.map