@loword/loword-design-system 0.0.1

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 (246) hide show
  1. package/README.md +20 -0
  2. package/dist/components/Avatar/Avatar.d.ts +11 -0
  3. package/dist/components/Avatar/Avatar.d.ts.map +1 -0
  4. package/dist/components/Avatar/Avatar.js +24 -0
  5. package/dist/components/Avatar/AvatarBase.d.ts +32 -0
  6. package/dist/components/Avatar/AvatarBase.d.ts.map +1 -0
  7. package/dist/components/Avatar/AvatarBase.js +49 -0
  8. package/dist/components/Badge/Badge.d.ts +25 -0
  9. package/dist/components/Badge/Badge.d.ts.map +1 -0
  10. package/dist/components/Badge/Badge.js +36 -0
  11. package/dist/components/Badge/BadgeBase.d.ts +10 -0
  12. package/dist/components/Badge/BadgeBase.d.ts.map +1 -0
  13. package/dist/components/Badge/BadgeBase.js +9 -0
  14. package/dist/components/Button/Button.d.ts +26 -0
  15. package/dist/components/Button/Button.d.ts.map +1 -0
  16. package/dist/components/Button/Button.js +102 -0
  17. package/dist/components/Button/ButtonBase.d.ts +5 -0
  18. package/dist/components/Button/ButtonBase.d.ts.map +1 -0
  19. package/dist/components/Button/ButtonBase.js +10 -0
  20. package/dist/components/Button/ButtonSpinner.d.ts +9 -0
  21. package/dist/components/Button/ButtonSpinner.d.ts.map +1 -0
  22. package/dist/components/Button/ButtonSpinner.js +14 -0
  23. package/dist/components/Calendar/Calendar.d.ts +16 -0
  24. package/dist/components/Calendar/Calendar.d.ts.map +1 -0
  25. package/dist/components/Calendar/Calendar.js +75 -0
  26. package/dist/components/Carousel/Carousel.d.ts +50 -0
  27. package/dist/components/Carousel/Carousel.d.ts.map +1 -0
  28. package/dist/components/Carousel/Carousel.js +22 -0
  29. package/dist/components/Carousel/CarouselBase.d.ts +98 -0
  30. package/dist/components/Carousel/CarouselBase.d.ts.map +1 -0
  31. package/dist/components/Carousel/CarouselBase.js +144 -0
  32. package/dist/components/Checkbox/Checkbox.d.ts +27 -0
  33. package/dist/components/Checkbox/Checkbox.d.ts.map +1 -0
  34. package/dist/components/Checkbox/Checkbox.js +30 -0
  35. package/dist/components/Checkbox/CheckboxBase.d.ts +40 -0
  36. package/dist/components/Checkbox/CheckboxBase.d.ts.map +1 -0
  37. package/dist/components/Checkbox/CheckboxBase.js +57 -0
  38. package/dist/components/Checkbox/CheckboxGroup.d.ts +22 -0
  39. package/dist/components/Checkbox/CheckboxGroup.d.ts.map +1 -0
  40. package/dist/components/Checkbox/CheckboxGroup.js +13 -0
  41. package/dist/components/Checkbox/FormCheckbox.d.ts +14 -0
  42. package/dist/components/Checkbox/FormCheckbox.d.ts.map +1 -0
  43. package/dist/components/Checkbox/FormCheckbox.js +9 -0
  44. package/dist/components/Checkbox/FormCheckboxGroup.d.ts +13 -0
  45. package/dist/components/Checkbox/FormCheckboxGroup.d.ts.map +1 -0
  46. package/dist/components/Checkbox/FormCheckboxGroup.js +9 -0
  47. package/dist/components/DataCalendar/DataCalendar.d.ts +12 -0
  48. package/dist/components/DataCalendar/DataCalendar.d.ts.map +1 -0
  49. package/dist/components/DataCalendar/DataCalendar.js +13 -0
  50. package/dist/components/DataCalendar/DataCalendarBase.d.ts +45 -0
  51. package/dist/components/DataCalendar/DataCalendarBase.d.ts.map +1 -0
  52. package/dist/components/DataCalendar/DataCalendarBase.js +57 -0
  53. package/dist/components/DatePicker/DatePicker.d.ts +34 -0
  54. package/dist/components/DatePicker/DatePicker.d.ts.map +1 -0
  55. package/dist/components/DatePicker/DatePicker.js +44 -0
  56. package/dist/components/DatePicker/FormDatePicker.d.ts +12 -0
  57. package/dist/components/DatePicker/FormDatePicker.d.ts.map +1 -0
  58. package/dist/components/DatePicker/FormDatePicker.js +12 -0
  59. package/dist/components/DateRangePicker/DateRangePicker.d.ts +49 -0
  60. package/dist/components/DateRangePicker/DateRangePicker.d.ts.map +1 -0
  61. package/dist/components/DateRangePicker/DateRangePicker.js +197 -0
  62. package/dist/components/DateRangePicker/FormDateRangePicker.d.ts +12 -0
  63. package/dist/components/DateRangePicker/FormDateRangePicker.d.ts.map +1 -0
  64. package/dist/components/DateRangePicker/FormDateRangePicker.js +10 -0
  65. package/dist/components/Drawer/Drawer.d.ts +51 -0
  66. package/dist/components/Drawer/Drawer.d.ts.map +1 -0
  67. package/dist/components/Drawer/Drawer.js +30 -0
  68. package/dist/components/Drawer/DrawerBase.d.ts +52 -0
  69. package/dist/components/Drawer/DrawerBase.d.ts.map +1 -0
  70. package/dist/components/Drawer/DrawerBase.js +38 -0
  71. package/dist/components/Editor/Editor.d.ts +12 -0
  72. package/dist/components/Editor/Editor.d.ts.map +1 -0
  73. package/dist/components/Editor/Editor.js +162 -0
  74. package/dist/components/Editor/EditorBase.d.ts +52 -0
  75. package/dist/components/Editor/EditorBase.d.ts.map +1 -0
  76. package/dist/components/Editor/EditorBase.js +89 -0
  77. package/dist/components/Editor/Viewer.d.ts +7 -0
  78. package/dist/components/Editor/Viewer.d.ts.map +1 -0
  79. package/dist/components/Editor/Viewer.js +9 -0
  80. package/dist/components/Editor/extensions.d.ts +6 -0
  81. package/dist/components/Editor/extensions.d.ts.map +1 -0
  82. package/dist/components/Editor/extensions.js +38 -0
  83. package/dist/components/FileUpload/FileUploadBase.d.ts +50 -0
  84. package/dist/components/FileUpload/FileUploadBase.d.ts.map +1 -0
  85. package/dist/components/FileUpload/FileUploadBase.js +102 -0
  86. package/dist/components/Form/Form.d.ts +21 -0
  87. package/dist/components/Form/Form.d.ts.map +1 -0
  88. package/dist/components/Form/Form.js +18 -0
  89. package/dist/components/Form/FormErrorMessage.d.ts +9 -0
  90. package/dist/components/Form/FormErrorMessage.d.ts.map +1 -0
  91. package/dist/components/Form/FormErrorMessage.js +6 -0
  92. package/dist/components/Form/FormField.d.ts +55 -0
  93. package/dist/components/Form/FormField.d.ts.map +1 -0
  94. package/dist/components/Form/FormField.js +43 -0
  95. package/dist/components/Icon/LucideIcon.d.ts +11 -0
  96. package/dist/components/Icon/LucideIcon.d.ts.map +1 -0
  97. package/dist/components/Icon/LucideIcon.js +41 -0
  98. package/dist/components/Input/FormInput.d.ts +15 -0
  99. package/dist/components/Input/FormInput.d.ts.map +1 -0
  100. package/dist/components/Input/FormInput.js +19 -0
  101. package/dist/components/Input/Input.d.ts +24 -0
  102. package/dist/components/Input/Input.d.ts.map +1 -0
  103. package/dist/components/Input/Input.js +71 -0
  104. package/dist/components/Input/InputBase.d.ts +22 -0
  105. package/dist/components/Input/InputBase.d.ts.map +1 -0
  106. package/dist/components/Input/InputBase.js +17 -0
  107. package/dist/components/LNB/LNBBase.d.ts +82 -0
  108. package/dist/components/LNB/LNBBase.d.ts.map +1 -0
  109. package/dist/components/LNB/LNBBase.js +108 -0
  110. package/dist/components/LoadingDots/LoadingDots.d.ts +8 -0
  111. package/dist/components/LoadingDots/LoadingDots.d.ts.map +1 -0
  112. package/dist/components/LoadingDots/LoadingDots.js +29 -0
  113. package/dist/components/MenuBar/MenuBar.d.ts +21 -0
  114. package/dist/components/MenuBar/MenuBar.d.ts.map +1 -0
  115. package/dist/components/MenuBar/MenuBar.js +33 -0
  116. package/dist/components/MenuBar/MenuBarBase.d.ts +43 -0
  117. package/dist/components/MenuBar/MenuBarBase.d.ts.map +1 -0
  118. package/dist/components/MenuBar/MenuBarBase.js +69 -0
  119. package/dist/components/Modal/Modal.d.ts +51 -0
  120. package/dist/components/Modal/Modal.d.ts.map +1 -0
  121. package/dist/components/Modal/Modal.js +72 -0
  122. package/dist/components/Modal/ModalBase.d.ts +42 -0
  123. package/dist/components/Modal/ModalBase.d.ts.map +1 -0
  124. package/dist/components/Modal/ModalBase.js +30 -0
  125. package/dist/components/Modal/openModal.d.ts +24 -0
  126. package/dist/components/Modal/openModal.d.ts.map +1 -0
  127. package/dist/components/Modal/openModal.js +52 -0
  128. package/dist/components/OTPInput/OTPInput.d.ts +46 -0
  129. package/dist/components/OTPInput/OTPInput.d.ts.map +1 -0
  130. package/dist/components/OTPInput/OTPInput.js +87 -0
  131. package/dist/components/Pagination/Pagination.d.ts +12 -0
  132. package/dist/components/Pagination/Pagination.d.ts.map +1 -0
  133. package/dist/components/Pagination/Pagination.js +5 -0
  134. package/dist/components/Pagination/PaginationBase.d.ts +36 -0
  135. package/dist/components/Pagination/PaginationBase.d.ts.map +1 -0
  136. package/dist/components/Pagination/PaginationBase.js +44 -0
  137. package/dist/components/Pagination/paginationUtils.d.ts +2 -0
  138. package/dist/components/Pagination/paginationUtils.d.ts.map +1 -0
  139. package/dist/components/Pagination/paginationUtils.js +18 -0
  140. package/dist/components/Popover/Popover.d.ts +42 -0
  141. package/dist/components/Popover/Popover.d.ts.map +1 -0
  142. package/dist/components/Popover/Popover.js +31 -0
  143. package/dist/components/Popover/PopoverBase.d.ts +31 -0
  144. package/dist/components/Popover/PopoverBase.d.ts.map +1 -0
  145. package/dist/components/Popover/PopoverBase.js +18 -0
  146. package/dist/components/Radio/FormRadioGroup.d.ts +13 -0
  147. package/dist/components/Radio/FormRadioGroup.d.ts.map +1 -0
  148. package/dist/components/Radio/FormRadioGroup.js +9 -0
  149. package/dist/components/Radio/Radio.d.ts +24 -0
  150. package/dist/components/Radio/Radio.d.ts.map +1 -0
  151. package/dist/components/Radio/Radio.js +39 -0
  152. package/dist/components/Radio/RadioBase.d.ts +38 -0
  153. package/dist/components/Radio/RadioBase.d.ts.map +1 -0
  154. package/dist/components/Radio/RadioBase.js +46 -0
  155. package/dist/components/Radio/RadioGroup.d.ts +22 -0
  156. package/dist/components/Radio/RadioGroup.d.ts.map +1 -0
  157. package/dist/components/Radio/RadioGroup.js +7 -0
  158. package/dist/components/ScrollArea/ScrollArea.d.ts +15 -0
  159. package/dist/components/ScrollArea/ScrollArea.d.ts.map +1 -0
  160. package/dist/components/ScrollArea/ScrollArea.js +10 -0
  161. package/dist/components/Select/FormMultiSelect.d.ts +13 -0
  162. package/dist/components/Select/FormMultiSelect.d.ts.map +1 -0
  163. package/dist/components/Select/FormMultiSelect.js +14 -0
  164. package/dist/components/Select/FormSelect.d.ts +13 -0
  165. package/dist/components/Select/FormSelect.d.ts.map +1 -0
  166. package/dist/components/Select/FormSelect.js +10 -0
  167. package/dist/components/Select/MultiSelect.d.ts +31 -0
  168. package/dist/components/Select/MultiSelect.d.ts.map +1 -0
  169. package/dist/components/Select/MultiSelect.js +59 -0
  170. package/dist/components/Select/Select.d.ts +41 -0
  171. package/dist/components/Select/Select.d.ts.map +1 -0
  172. package/dist/components/Select/Select.js +55 -0
  173. package/dist/components/Select/SelectBase.d.ts +59 -0
  174. package/dist/components/Select/SelectBase.d.ts.map +1 -0
  175. package/dist/components/Select/SelectBase.js +211 -0
  176. package/dist/components/Skeleton/Skeleton.d.ts +10 -0
  177. package/dist/components/Skeleton/Skeleton.d.ts.map +1 -0
  178. package/dist/components/Skeleton/Skeleton.js +8 -0
  179. package/dist/components/Slider/Slider.d.ts +23 -0
  180. package/dist/components/Slider/Slider.d.ts.map +1 -0
  181. package/dist/components/Slider/Slider.js +195 -0
  182. package/dist/components/Spinner/Spinner.d.ts +25 -0
  183. package/dist/components/Spinner/Spinner.d.ts.map +1 -0
  184. package/dist/components/Spinner/Spinner.js +20 -0
  185. package/dist/components/Table/Table.d.ts +34 -0
  186. package/dist/components/Table/Table.d.ts.map +1 -0
  187. package/dist/components/Table/Table.js +29 -0
  188. package/dist/components/Table/TableBase.d.ts +37 -0
  189. package/dist/components/Table/TableBase.d.ts.map +1 -0
  190. package/dist/components/Table/TableBase.js +39 -0
  191. package/dist/components/Table/TableField.d.ts +64 -0
  192. package/dist/components/Table/TableField.d.ts.map +1 -0
  193. package/dist/components/Table/TableField.js +87 -0
  194. package/dist/components/Table/TanstackTable.d.ts +23 -0
  195. package/dist/components/Table/TanstackTable.d.ts.map +1 -0
  196. package/dist/components/Table/TanstackTable.js +35 -0
  197. package/dist/components/TimePicker/FormTimePicker.d.ts +12 -0
  198. package/dist/components/TimePicker/FormTimePicker.d.ts.map +1 -0
  199. package/dist/components/TimePicker/FormTimePicker.js +12 -0
  200. package/dist/components/TimePicker/TimePicker.d.ts +27 -0
  201. package/dist/components/TimePicker/TimePicker.d.ts.map +1 -0
  202. package/dist/components/TimePicker/TimePicker.js +120 -0
  203. package/dist/components/Toast/Toast.d.ts +18 -0
  204. package/dist/components/Toast/Toast.d.ts.map +1 -0
  205. package/dist/components/Toast/Toast.js +42 -0
  206. package/dist/components/Toast/Toaster.d.ts +7 -0
  207. package/dist/components/Toast/Toaster.d.ts.map +1 -0
  208. package/dist/components/Toast/Toaster.js +7 -0
  209. package/dist/components/ToggleButton/FormToggleButton.d.ts +12 -0
  210. package/dist/components/ToggleButton/FormToggleButton.d.ts.map +1 -0
  211. package/dist/components/ToggleButton/FormToggleButton.js +9 -0
  212. package/dist/components/ToggleButton/ToggleButton.d.ts +31 -0
  213. package/dist/components/ToggleButton/ToggleButton.d.ts.map +1 -0
  214. package/dist/components/ToggleButton/ToggleButton.js +42 -0
  215. package/dist/components/ToggleButton/ToggleButtonBase.d.ts +41 -0
  216. package/dist/components/ToggleButton/ToggleButtonBase.d.ts.map +1 -0
  217. package/dist/components/ToggleButton/ToggleButtonBase.js +59 -0
  218. package/dist/components/Tooltip/Tooltip.d.ts +18 -0
  219. package/dist/components/Tooltip/Tooltip.d.ts.map +1 -0
  220. package/dist/components/Tooltip/Tooltip.js +13 -0
  221. package/dist/components/Tooltip/TooltipBase.d.ts +39 -0
  222. package/dist/components/Tooltip/TooltipBase.d.ts.map +1 -0
  223. package/dist/components/Tooltip/TooltipBase.js +46 -0
  224. package/dist/constants/file.d.ts +42 -0
  225. package/dist/constants/file.d.ts.map +1 -0
  226. package/dist/constants/file.js +47 -0
  227. package/dist/index.css +4061 -0
  228. package/dist/index.d.ts +54 -0
  229. package/dist/index.d.ts.map +1 -0
  230. package/dist/index.js +88 -0
  231. package/dist/types/polymorphic.d.ts +19 -0
  232. package/dist/types/polymorphic.d.ts.map +1 -0
  233. package/dist/types/polymorphic.js +1 -0
  234. package/dist/utils/cn.d.ts +4 -0
  235. package/dist/utils/cn.d.ts.map +1 -0
  236. package/dist/utils/cn.js +6 -0
  237. package/dist/utils/file.d.ts +16 -0
  238. package/dist/utils/file.d.ts.map +1 -0
  239. package/dist/utils/file.js +58 -0
  240. package/dist/utils/renderIcon.d.ts +4 -0
  241. package/dist/utils/renderIcon.d.ts.map +1 -0
  242. package/dist/utils/renderIcon.js +11 -0
  243. package/dist/utils/utils.d.ts +2 -0
  244. package/dist/utils/utils.d.ts.map +1 -0
  245. package/dist/utils/utils.js +5 -0
  246. package/package.json +239 -0
@@ -0,0 +1,195 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useRef, useState, useCallback, useMemo } from 'react';
3
+ import cn from '../../utils/cn.js';
4
+ // ── 헬퍼 함수 ────────────────────────────────────────────────────────────────
5
+ //퍼센테이지 계산
6
+ const toPercent = (value, min, max) => {
7
+ return ((value - min) / (max - min)) * 100;
8
+ };
9
+ //값 제한
10
+ const clamp = (value, min, max) => {
11
+ return Math.min(Math.max(value, min), max);
12
+ };
13
+ //값 범위
14
+ const getValueFromPointer = (clientPos, rect, isVertical, min, max, step) => {
15
+ const ratio = isVertical
16
+ ? 1 - (clientPos - rect.top) / rect.height
17
+ : (clientPos - rect.left) / rect.width;
18
+ const raw = min + clamp(ratio, 0, 1) * (max - min);
19
+ const stepped = Math.round((raw - min) / step) * step + min;
20
+ return clamp(stepped, min, max);
21
+ };
22
+ // ── 컴포넌트 ──────────────────────────────────────────────────────────────
23
+ const Slider = (props) => {
24
+ const { min = 0, max = 100, step = 1, disabled = false, orientation = 'horizontal', showLabel = false, className, style, } = props;
25
+ const isVertical = orientation === 'vertical';
26
+ const isRange = Array.isArray(props.value ??
27
+ props.defaultValue);
28
+ // ── 단일 상태일 경우 제어, 비제어 상태 확인 ──
29
+ const singleControlled = !isRange && props.value !== undefined;
30
+ const [singleInternal, setSingleInternal] = useState(!isRange ? (props.defaultValue ?? min) : min);
31
+ const singleValue = singleControlled
32
+ ? props.value
33
+ : singleInternal;
34
+ // ── 범위 상태일 경우 제어, 비제어 상태 확인 ──
35
+ const rangeControlled = isRange && props.value !== undefined;
36
+ const [rangeInternal, setRangeInternal] = useState(isRange
37
+ ? (props.defaultValue ?? [min, max])
38
+ : [min, max]);
39
+ const rangeValue = rangeControlled
40
+ ? props.value
41
+ : rangeInternal;
42
+ // stale closure 방지: 핸들러에서 항상 최신 rangeValue 참조
43
+ const rangeValueRef = useRef(rangeValue);
44
+ rangeValueRef.current = rangeValue;
45
+ // ── 범위 모드 시 활성화된 손잡이(Thumb) 관리 ──
46
+ const trackRef = useRef(null);
47
+ const activeThumbRef = useRef('a');
48
+ const resolveActiveThumb = useCallback((clientPos) => {
49
+ if (!trackRef.current)
50
+ return 'a';
51
+ const rect = trackRef.current.getBoundingClientRect();
52
+ const ratio = isVertical
53
+ ? 1 - (clientPos - rect.top) / rect.height
54
+ : (clientPos - rect.left) / rect.width;
55
+ const pointValue = min + ratio * (max - min);
56
+ const current = rangeValueRef.current;
57
+ const distA = Math.abs(pointValue - current[0]);
58
+ const distB = Math.abs(pointValue - current[1]);
59
+ return distA <= distB ? 'a' : 'b';
60
+ }, [isVertical, min, max]);
61
+ // ── 변경 핸들러 ──
62
+ const handleSingleChange = useCallback((raw) => {
63
+ if (!singleControlled)
64
+ setSingleInternal(raw);
65
+ props.onChange?.(raw);
66
+ },
67
+ // eslint-disable-next-line react-hooks/exhaustive-deps
68
+ [singleControlled]);
69
+ const handleRangeChangeA = useCallback((raw) => {
70
+ const next = [
71
+ Math.min(raw, rangeValueRef.current[1]),
72
+ rangeValueRef.current[1],
73
+ ];
74
+ if (!rangeControlled)
75
+ setRangeInternal(next);
76
+ props.onChange?.(next);
77
+ },
78
+ // eslint-disable-next-line react-hooks/exhaustive-deps
79
+ [rangeControlled]);
80
+ const handleRangeChangeB = useCallback((raw) => {
81
+ const next = [
82
+ rangeValueRef.current[0],
83
+ Math.max(raw, rangeValueRef.current[0]),
84
+ ];
85
+ if (!rangeControlled)
86
+ setRangeInternal(next);
87
+ props.onChange?.(next);
88
+ },
89
+ // eslint-disable-next-line react-hooks/exhaustive-deps
90
+ [rangeControlled]);
91
+ // ── 트랙 포인터 핸들러 (클릭 이동 + 드래그) ──
92
+ const handleTrackPointerDown = useCallback((e) => {
93
+ if (disabled || !trackRef.current)
94
+ return;
95
+ e.currentTarget.setPointerCapture(e.pointerId);
96
+ const rect = trackRef.current.getBoundingClientRect();
97
+ const v = getValueFromPointer(isVertical ? e.clientY : e.clientX, rect, isVertical, min, max, step);
98
+ if (isRange) {
99
+ const which = resolveActiveThumb(isVertical ? e.clientY : e.clientX);
100
+ activeThumbRef.current = which;
101
+ if (which === 'a')
102
+ handleRangeChangeA(v);
103
+ else
104
+ handleRangeChangeB(v);
105
+ }
106
+ else {
107
+ handleSingleChange(v);
108
+ }
109
+ }, [
110
+ disabled,
111
+ isVertical,
112
+ min,
113
+ max,
114
+ step,
115
+ isRange,
116
+ resolveActiveThumb,
117
+ handleRangeChangeA,
118
+ handleRangeChangeB,
119
+ handleSingleChange,
120
+ ]);
121
+ const handleTrackPointerMove = useCallback((e) => {
122
+ if (disabled ||
123
+ !e.currentTarget.hasPointerCapture(e.pointerId) ||
124
+ !trackRef.current)
125
+ return;
126
+ const rect = trackRef.current.getBoundingClientRect();
127
+ const v = getValueFromPointer(isVertical ? e.clientY : e.clientX, rect, isVertical, min, max, step);
128
+ if (isRange) {
129
+ if (activeThumbRef.current === 'a')
130
+ handleRangeChangeA(v);
131
+ else
132
+ handleRangeChangeB(v);
133
+ }
134
+ else {
135
+ handleSingleChange(v);
136
+ }
137
+ }, [
138
+ disabled,
139
+ isVertical,
140
+ min,
141
+ max,
142
+ step,
143
+ isRange,
144
+ handleRangeChangeA,
145
+ handleRangeChangeB,
146
+ handleSingleChange,
147
+ ]);
148
+ // ── 채워지는 영역 퍼센트 계산 ──
149
+ const fillStyle = useMemo(() => {
150
+ if (isRange) {
151
+ const lo = toPercent(rangeValue[0], min, max);
152
+ const hi = toPercent(rangeValue[1], min, max);
153
+ return isVertical
154
+ ? { bottom: `${lo}%`, height: `${hi - lo}%` }
155
+ : { left: `${lo}%`, width: `${hi - lo}%` };
156
+ }
157
+ const pct = toPercent(clamp(singleValue, min, max), min, max);
158
+ return isVertical
159
+ ? { bottom: 0, height: `${pct}%` }
160
+ : { left: 0, width: `${pct}%` };
161
+ }, [isRange, isVertical, min, max, singleValue, rangeValue]);
162
+ // ── 라벨 위치 계산 ──
163
+ const labelAPercent = isRange
164
+ ? toPercent(rangeValue[0], min, max)
165
+ : toPercent(clamp(singleValue, min, max), min, max);
166
+ const labelBPercent = isRange ? toPercent(rangeValue[1], min, max) : 0;
167
+ const shouldOffsetLabel = isRange && Math.abs(labelBPercent - labelAPercent) < 8;
168
+ const getLabelStyle = (percent, which) => {
169
+ const offset = shouldOffsetLabel ? (which === 'a' ? -16 : 16) : 0;
170
+ if (isVertical) {
171
+ return {
172
+ position: 'absolute',
173
+ left: 'calc(100% + 8px)',
174
+ bottom: `${percent}%`,
175
+ transform: `translateY(calc(50% + ${offset}px))`,
176
+ };
177
+ }
178
+ return {
179
+ position: 'absolute',
180
+ bottom: 'calc(100% + 8px)',
181
+ left: `${percent}%`,
182
+ transform: `translateX(calc(-50% + ${offset}px))`,
183
+ };
184
+ };
185
+ // ── 수직 모드용 입력창 공통 스타일 ──
186
+ const inputStyle = isVertical
187
+ ? { writingMode: 'vertical-lr', direction: 'rtl' }
188
+ : {};
189
+ // ── 렌더링 ──────────────────────────────────────────────────────────────
190
+ return (_jsxs("div", { className: cn('relative flex items-center', isVertical ? 'flex-col h-48 w-fit' : 'flex-row w-full', className), style: style, children: [_jsxs("div", { ref: trackRef, onPointerDown: handleTrackPointerDown, onPointerMove: handleTrackPointerMove, className: cn('relative rounded-full bg-mono200', isVertical ? 'w-1.5 h-full' : 'h-1.5 w-full', disabled ? 'opacity-40 cursor-not-allowed' : 'cursor-pointer'), children: [_jsx("div", { className: "absolute rounded-full bg-lb500 pointer-events-none", style: {
191
+ ...(isVertical ? { left: 0, right: 0 } : { top: 0, bottom: 0 }),
192
+ ...fillStyle,
193
+ } }), !isRange && (_jsx("input", { type: "range", min: min, max: max, step: step, value: singleValue, disabled: disabled, onChange: (e) => handleSingleChange(e.target.valueAsNumber), className: "ld-slider-thumb absolute inset-0 w-full h-full", style: inputStyle })), isRange && (_jsxs(_Fragment, { children: [_jsx("input", { type: "range", min: min, max: max, step: step, value: rangeValue[0], disabled: disabled, onChange: (e) => handleRangeChangeA(e.target.valueAsNumber), className: "ld-slider-thumb absolute inset-0 w-full h-full z-0", style: inputStyle }), _jsx("input", { type: "range", min: min, max: max, step: step, value: rangeValue[1], disabled: disabled, onChange: (e) => handleRangeChangeB(e.target.valueAsNumber), className: "ld-slider-thumb absolute inset-0 w-full h-full z-0", style: inputStyle })] }))] }), showLabel && (_jsxs(_Fragment, { children: [_jsx("span", { className: "text-xs font-medium text-lb500 whitespace-nowrap pointer-events-none select-none", style: getLabelStyle(labelAPercent, 'a'), children: isRange ? rangeValue[0] : singleValue }), isRange && (_jsx("span", { className: "text-xs font-medium text-lb500 whitespace-nowrap pointer-events-none select-none", style: getLabelStyle(labelBPercent, 'b'), children: rangeValue[1] }))] }))] }));
194
+ };
195
+ export default Slider;
@@ -0,0 +1,25 @@
1
+ export type SpinnerSize = 'xSmall' | 'small' | 'medium' | 'large' | 'big' | 'xLarge';
2
+ export interface SpinnerProps {
3
+ /**
4
+ * Spinner의 크기를 지정합니다. 프리셋 이름이나 숫자(px)를 사용할 수 있습니다. (기본값: 'large' / 24px)
5
+ */
6
+ size?: SpinnerSize | number;
7
+ /**
8
+ * 추가적인 스타일 클래스를 지정합니다. (색상 등을 변경할 때 사용)
9
+ */
10
+ className?: string;
11
+ /**
12
+ * 사용할 아이콘 타입을 지정합니다. (기본값: 'default')
13
+ */
14
+ variant?: 'default' | 'circle';
15
+ /**
16
+ * 접근성을 위한 라벨입니다. (기본값: 'loading')
17
+ */
18
+ label?: string;
19
+ }
20
+ /**
21
+ * 디자인 시스템 표준을 따르는 Spinner 컴포넌트입니다.
22
+ */
23
+ declare const Spinner: ({ size, className, variant, label, }: SpinnerProps) => import("react/jsx-runtime").JSX.Element;
24
+ export default Spinner;
25
+ //# sourceMappingURL=Spinner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Spinner.d.ts","sourceRoot":"","sources":["../../../src/components/Spinner/Spinner.tsx"],"names":[],"mappings":"AAGA,MAAM,MAAM,WAAW,GACnB,QAAQ,GACR,OAAO,GACP,QAAQ,GACR,OAAO,GACP,KAAK,GACL,QAAQ,CAAC;AAWb,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,IAAI,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC;IAC5B;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,OAAO,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC/B;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,QAAA,MAAM,OAAO,GAAI,sCAKd,YAAY,4CAYd,CAAC;AAEF,eAAe,OAAO,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { LoaderIcon, LoaderCircleIcon } from 'lucide-react';
3
+ import cn from '../../utils/cn.js';
4
+ const sizeMap = {
5
+ xSmall: 12,
6
+ small: 16,
7
+ medium: 20,
8
+ large: 24,
9
+ big: 32,
10
+ xLarge: 48,
11
+ };
12
+ /**
13
+ * 디자인 시스템 표준을 따르는 Spinner 컴포넌트입니다.
14
+ */
15
+ const Spinner = ({ size = 'large', className, variant = 'default', label = 'loading', }) => {
16
+ const Icon = variant === 'circle' ? LoaderCircleIcon : LoaderIcon;
17
+ const pixelSize = typeof size === 'number' ? size : sizeMap[size];
18
+ return (_jsx(Icon, { size: pixelSize, className: cn('animate-spin text-muted-foreground', className), role: "status", "aria-label": label }));
19
+ };
20
+ export default Spinner;
@@ -0,0 +1,34 @@
1
+ import { type ReactNode, type CSSProperties } from 'react';
2
+ export interface TableProps {
3
+ /** 테이블 콘텐츠 (Table.Header, Table.Body 등) */
4
+ children: ReactNode;
5
+ /** 상단 타이틀 텍스트 */
6
+ title?: string;
7
+ /** 전체 데이터 건수 (타이틀 옆에 표시) */
8
+ totalCount?: number;
9
+ /** 타이틀 우측에 배치할 요소 (버튼, 필터 등) */
10
+ /** 테이블 상단에 배치할 요소 */
11
+ /** 테이블 하단에 배치할 요소 (Pagination 등) */
12
+ footer?: ReactNode;
13
+ /** 데이터 없음 상태 여부 */
14
+ isEmpty?: boolean;
15
+ /** 데이터 없을 때 표시할 메시지 */
16
+ emptyMessage?: string | ReactNode;
17
+ /** 빈 상태 행의 colSpan 값 */
18
+ columnCount?: number;
19
+ className?: string;
20
+ style?: CSSProperties;
21
+ }
22
+ declare const Table: {
23
+ ({ children, title, totalCount, footer, isEmpty, emptyMessage, columnCount, className, style, }: TableProps): import("react/jsx-runtime").JSX.Element;
24
+ Header: ({ className, children, ...props }: React.HTMLAttributes<HTMLTableSectionElement>) => import("react/jsx-runtime").JSX.Element;
25
+ HeaderRow: ({ className, children, ...props }: React.HTMLAttributes<HTMLTableRowElement>) => import("react/jsx-runtime").JSX.Element;
26
+ HeaderCell: ({ className, children, ...props }: React.ThHTMLAttributes<HTMLTableCellElement>) => import("react/jsx-runtime").JSX.Element;
27
+ Body: ({ className, children, ...props }: React.HTMLAttributes<HTMLTableSectionElement>) => import("react/jsx-runtime").JSX.Element;
28
+ Row: ({ className, children, ...props }: React.HTMLAttributes<HTMLTableRowElement> & {
29
+ selected?: boolean;
30
+ }) => import("react/jsx-runtime").JSX.Element;
31
+ Cell: ({ className, children, ...props }: React.TdHTMLAttributes<HTMLTableCellElement>) => import("react/jsx-runtime").JSX.Element;
32
+ };
33
+ export default Table;
34
+ //# sourceMappingURL=Table.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Table.d.ts","sourceRoot":"","sources":["../../../src/components/Table/Table.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAI3D,MAAM,WAAW,UAAU;IACzB,2CAA2C;IAC3C,QAAQ,EAAE,SAAS,CAAC;IACpB,iBAAiB;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4BAA4B;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,gCAAgC;IAGhC,qBAAqB;IAGrB,oCAAoC;IACpC,MAAM,CAAC,EAAE,SAAS,CAAC;IAQnB,mBAAmB;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,uBAAuB;IACvB,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAElC,wBAAwB;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;CAOvB;AAED,QAAA,MAAM,KAAK;qGAgBR,UAAU;gDAmCV,KAAK,CAAC,cAAc,CAAC,uBAAuB,CAAC;mDAgB7C,KAAK,CAAC,cAAc,CAAC,mBAAmB,CAAC;oDAUzC,KAAK,CAAC,gBAAgB,CAAC,oBAAoB,CAAC;8CAa5C,KAAK,CAAC,cAAc,CAAC,uBAAuB,CAAC;6CAU7C,KAAK,CAAC,cAAc,CAAC,mBAAmB,CAAC,GAAG;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE;8CAgBlE,KAAK,CAAC,gBAAgB,CAAC,oBAAoB,CAAC;CAxE9C,CAAC;AAqFF,eAAe,KAAK,CAAC"}
@@ -0,0 +1,29 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ import TableBase from './TableBase.js';
3
+ import cn from '../../utils/cn.js';
4
+ const Table = ({ children, title, totalCount,
5
+ // rightSideContents,
6
+ // tableTop,
7
+ footer,
8
+ // scrollable = false,
9
+ // scrollMinWidth = '1440px',
10
+ isEmpty = false, emptyMessage = '조회하신 데이터가 없습니다.', columnCount, className, style,
11
+ // wrapperClassName,
12
+ // wrapperStyle,
13
+ }) => {
14
+ return (_jsxs("div", { className: cn('flex flex-col justify-between h-full gap-sm'), children: [title && (_jsxs("h3", { className: "whitespace-nowrap display16 bold", children: [title, totalCount !== undefined && ` (${totalCount.toLocaleString()})`] })), _jsxs(TableBase.Root, { className: cn('w-full', className), style: style, children: [children, isEmpty && columnCount && (_jsx(TableBase.Body, { children: _jsx(TableBase.Row, { children: _jsx(TableBase.Cell, { colSpan: columnCount, className: "text-center h-24 py-24", children: emptyMessage }) }) }))] }), footer] }));
15
+ };
16
+ // ── Styled Sub-components ──
17
+ const Header = ({ className, children, ...props }) => (_jsx(TableBase.Header, { className: cn('border-b border-neutral700 bg-mono100 hover:bg-mono200 ld-transition', className), ...props, children: children }));
18
+ const HeaderRow = ({ className, children, ...props }) => (_jsx(TableBase.HeaderRow, { className: cn('bg-neutral5', className), ...props, children: children }));
19
+ const HeaderCell = ({ className, children, ...props }) => (_jsx(TableBase.HeaderCell, { className: cn('px-4 py-3 text-left display12 regular', className), ...props, children: children }));
20
+ const Body = ({ className, children, ...props }) => (_jsx(TableBase.Body, { className: className, ...props, children: children }));
21
+ const Row = ({ className, children, ...props }) => (_jsx(TableBase.Row, { className: cn('border-b border-neutral100 hover:bg-black/3 ld-transition', className), ...props, children: children }));
22
+ const Cell = ({ className, children, ...props }) => (_jsx(TableBase.Cell, { className: cn('px-4 py-3 display14', className), ...props, children: children }));
23
+ Table.Header = Header;
24
+ Table.HeaderRow = HeaderRow;
25
+ Table.HeaderCell = HeaderCell;
26
+ Table.Body = Body;
27
+ Table.Row = Row;
28
+ Table.Cell = Cell;
29
+ export default Table;
@@ -0,0 +1,37 @@
1
+ import { type HTMLAttributes, type TdHTMLAttributes, type ThHTMLAttributes, type ReactNode, type Ref } from 'react';
2
+ interface RootProps extends HTMLAttributes<HTMLTableElement> {
3
+ children?: ReactNode;
4
+ ref?: Ref<HTMLTableElement>;
5
+ }
6
+ interface HeaderProps extends HTMLAttributes<HTMLTableSectionElement> {
7
+ children?: ReactNode;
8
+ }
9
+ interface BodyProps extends HTMLAttributes<HTMLTableSectionElement> {
10
+ children?: ReactNode;
11
+ }
12
+ interface HeaderRowProps extends HTMLAttributes<HTMLTableRowElement> {
13
+ children?: ReactNode;
14
+ }
15
+ interface RowProps extends HTMLAttributes<HTMLTableRowElement> {
16
+ children?: ReactNode;
17
+ selected?: boolean;
18
+ }
19
+ interface HeaderCellProps extends ThHTMLAttributes<HTMLTableCellElement> {
20
+ children?: ReactNode;
21
+ sortable?: boolean;
22
+ sortDirection?: 'asc' | 'desc' | false;
23
+ }
24
+ interface CellProps extends TdHTMLAttributes<HTMLTableCellElement> {
25
+ children?: ReactNode;
26
+ }
27
+ export declare const TableBase: {
28
+ Root: ({ className, children, ref, ...props }: RootProps) => import("react/jsx-runtime").JSX.Element;
29
+ Header: ({ className, children, ...props }: HeaderProps) => import("react/jsx-runtime").JSX.Element;
30
+ Body: ({ className, children, ...props }: BodyProps) => import("react/jsx-runtime").JSX.Element;
31
+ HeaderRow: ({ className, children, ...props }: HeaderRowProps) => import("react/jsx-runtime").JSX.Element;
32
+ Row: ({ className, children, selected, ...props }: RowProps) => import("react/jsx-runtime").JSX.Element;
33
+ HeaderCell: ({ className, children, sortable, sortDirection, ...props }: HeaderCellProps) => import("react/jsx-runtime").JSX.Element;
34
+ Cell: ({ className, children, ...props }: CellProps) => import("react/jsx-runtime").JSX.Element;
35
+ };
36
+ export default TableBase;
37
+ //# sourceMappingURL=TableBase.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TableBase.d.ts","sourceRoot":"","sources":["../../../src/components/Table/TableBase.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,SAAS,EACd,KAAK,GAAG,EACT,MAAM,OAAO,CAAC;AAIf,UAAU,SAAU,SAAQ,cAAc,CAAC,gBAAgB,CAAC;IAC1D,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,GAAG,CAAC,EAAE,GAAG,CAAC,gBAAgB,CAAC,CAAC;CAC7B;AAgBD,UAAU,WAAY,SAAQ,cAAc,CAAC,uBAAuB,CAAC;IACnE,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAWD,UAAU,SAAU,SAAQ,cAAc,CAAC,uBAAuB,CAAC;IACjE,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAWD,UAAU,cAAe,SAAQ,cAAc,CAAC,mBAAmB,CAAC;IAClE,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAWD,UAAU,QAAS,SAAQ,cAAc,CAAC,mBAAmB,CAAC;IAC5D,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAiBD,UAAU,eAAgB,SAAQ,gBAAgB,CAAC,oBAAoB,CAAC;IACtE,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,aAAa,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,CAAC;CACxC;AA8BD,UAAU,SAAU,SAAQ,gBAAgB,CAAC,oBAAoB,CAAC;IAChE,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAUD,eAAO,MAAM,SAAS;mDAvHgC,SAAS;gDAkBZ,WAAW;8CAab,SAAS;mDAaJ,cAAc;uDAcV,QAAQ;6EA2B/D,eAAe;8CA0B+B,SAAS;CAgBzD,CAAC;AAEF,eAAe,SAAS,CAAC"}
@@ -0,0 +1,39 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import cn from '../../utils/cn.js';
3
+ const Root = ({ className, children, ref, ...props }) => {
4
+ return (_jsx("table", { ref: ref, role: "table", className: cn('w-full', className), ...props, children: children }));
5
+ };
6
+ const Header = ({ className, children, ...props }) => {
7
+ return (_jsx("thead", { role: "rowgroup", className: className, ...props, children: children }));
8
+ };
9
+ const Body = ({ className, children, ...props }) => {
10
+ return (_jsx("tbody", { role: "rowgroup", className: className, ...props, children: children }));
11
+ };
12
+ const HeaderRow = ({ className, children, ...props }) => {
13
+ return (_jsx("tr", { role: "row", className: className, ...props, children: children }));
14
+ };
15
+ const Row = ({ className, children, selected, ...props }) => {
16
+ return (_jsx("tr", { role: "row", "aria-selected": selected, "data-state": selected ? 'selected' : undefined, className: className, ...props, children: children }));
17
+ };
18
+ const HeaderCell = ({ className, children, sortable, sortDirection, ...props }) => {
19
+ return (_jsx("th", { role: "columnheader", "aria-sort": sortDirection === 'asc'
20
+ ? 'ascending'
21
+ : sortDirection === 'desc'
22
+ ? 'descending'
23
+ : sortable
24
+ ? 'none'
25
+ : undefined, className: className, ...props, children: children }));
26
+ };
27
+ const Cell = ({ className, children, ...props }) => {
28
+ return (_jsx("td", { role: "cell", className: className, ...props, children: children }));
29
+ };
30
+ export const TableBase = {
31
+ Root,
32
+ Header,
33
+ Body,
34
+ HeaderRow,
35
+ Row,
36
+ HeaderCell,
37
+ Cell,
38
+ };
39
+ export default TableBase;
@@ -0,0 +1,64 @@
1
+ import { type ReactNode, type Dispatch, type SetStateAction } from 'react';
2
+ import { flexRender, type ColumnDef, type RowSelectionState, type PaginationState, type SortingState, type Row, type HeaderGroup, type Header, type Cell } from '@tanstack/react-table';
3
+ export interface Pageable<T> {
4
+ data: T[];
5
+ page?: number;
6
+ limit?: number;
7
+ totalCount: number;
8
+ totalPages?: number;
9
+ hasNext?: boolean;
10
+ hasPrev?: boolean;
11
+ }
12
+ export interface TableFieldProps<TData, TColumn> {
13
+ /** 컬럼 정의 */
14
+ columns: ColumnDef<TData, TColumn>[];
15
+ /** 테이블 데이터 */
16
+ data: TData[];
17
+ /** 페이지네이션 */
18
+ pageable?: Pageable<TData>;
19
+ paginationState?: [
20
+ PaginationState,
21
+ Dispatch<SetStateAction<PaginationState>>
22
+ ];
23
+ onPageChange?: (page: number) => void;
24
+ /** 정렬 */
25
+ sortingState?: [SortingState, Dispatch<SetStateAction<SortingState>>];
26
+ /** 행 선택 */
27
+ enableRowSelection?: boolean | ((row: Row<TData>) => boolean);
28
+ enableMultiRowSelection?: boolean;
29
+ rowSelectionState?: [
30
+ RowSelectionState,
31
+ Dispatch<SetStateAction<RowSelectionState>>
32
+ ];
33
+ enableToggleAllRowsSelection?: boolean;
34
+ getRowId?: (row: TData, index: number) => string;
35
+ /** render props */
36
+ children: (props: TableFieldRenderProps<TData>) => ReactNode;
37
+ }
38
+ export interface TableFieldRenderProps<TData> {
39
+ headerGroups: HeaderGroup<TData>[];
40
+ rows: Row<TData>[];
41
+ isEmpty: boolean;
42
+ currentPage: number;
43
+ totalPages: number;
44
+ toggleAllRowsSelected: () => void;
45
+ setPageIndex: (index: number) => void;
46
+ onPageChange: (page: number) => void;
47
+ flexRender: typeof flexRender;
48
+ getHeader: (header: Header<TData, unknown>) => {
49
+ id: string;
50
+ canSort: boolean;
51
+ isSorted: false | 'asc' | 'desc';
52
+ size: number;
53
+ toggleSortingHandler: ((event: unknown) => void) | undefined;
54
+ renderHeader: () => ReactNode;
55
+ meta: Record<string, unknown> | undefined;
56
+ };
57
+ getCell: (cell: Cell<TData, unknown>) => {
58
+ id: string;
59
+ renderCell: () => ReactNode;
60
+ };
61
+ }
62
+ declare const TableField: <TData, TColumn>({ columns, data, pageable, paginationState, onPageChange, sortingState, enableRowSelection, enableMultiRowSelection, rowSelectionState, enableToggleAllRowsSelection, getRowId, children, }: TableFieldProps<TData, TColumn>) => ReactNode;
63
+ export default TableField;
64
+ //# sourceMappingURL=TableField.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TableField.d.ts","sourceRoot":"","sources":["../../../src/components/Table/TableField.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,87 @@
1
+ 'use client';
2
+ import { useReactTable, getCoreRowModel, getSortedRowModel, flexRender, } from '@tanstack/react-table';
3
+ import { useRouter, useSearchParams, usePathname } from 'next/navigation';
4
+ const TableField = ({ columns, data, pageable, paginationState, onPageChange, sortingState, enableRowSelection = false, enableMultiRowSelection = false, rowSelectionState, enableToggleAllRowsSelection = false, getRowId, children, }) => {
5
+ const router = useRouter();
6
+ const searchParams = useSearchParams();
7
+ const pathname = usePathname();
8
+ const [pagination, setPagination] = paginationState ?? [
9
+ { pageIndex: 0, pageSize: 10 },
10
+ () => { },
11
+ ];
12
+ const [rowSelection, setRowSelection] = rowSelectionState ?? [
13
+ undefined,
14
+ undefined,
15
+ ];
16
+ const [sorting, setSorting] = sortingState ?? [[], () => { }];
17
+ const processedColumns = columns.map((col) => ({
18
+ ...col,
19
+ enableSorting: col.enableSorting ?? false,
20
+ sortDescFirst: col.sortDescFirst ?? false,
21
+ }));
22
+ const table = useReactTable({
23
+ columns: processedColumns,
24
+ data,
25
+ getCoreRowModel: getCoreRowModel(),
26
+ state: {
27
+ pagination,
28
+ rowSelection: rowSelection ?? {},
29
+ sorting,
30
+ },
31
+ enableMultiRowSelection,
32
+ enableRowSelection,
33
+ onRowSelectionChange: setRowSelection,
34
+ getRowId,
35
+ onPaginationChange: setPagination,
36
+ manualPagination: true,
37
+ rowCount: pageable?.totalCount,
38
+ onSortingChange: setSorting,
39
+ getSortedRowModel: getSortedRowModel(),
40
+ });
41
+ const headerGroups = table.getHeaderGroups();
42
+ const rows = table.getRowModel().rows;
43
+ const isEmpty = rows.length === 0;
44
+ const currentPage = (pagination?.pageIndex ?? 0) + 1;
45
+ const totalPages = table.getPageCount();
46
+ const handlePageChange = (page) => {
47
+ table.setPageIndex(page - 1);
48
+ if (onPageChange) {
49
+ onPageChange(page);
50
+ }
51
+ else {
52
+ const params = new URLSearchParams(searchParams.toString());
53
+ params.set('page', page.toString());
54
+ router.push(`${pathname}?${params.toString()}`, { scroll: false });
55
+ }
56
+ };
57
+ const getHeader = (header) => ({
58
+ id: header.id,
59
+ canSort: header.column.getCanSort(),
60
+ isSorted: header.column.getIsSorted(),
61
+ size: header.getSize(),
62
+ toggleSortingHandler: header.column.getToggleSortingHandler(),
63
+ renderHeader: () => flexRender(header.column.columnDef.header, header.getContext()),
64
+ meta: header.column.columnDef.meta,
65
+ });
66
+ const getCell = (cell) => ({
67
+ id: cell.id,
68
+ renderCell: () => flexRender(cell.column.columnDef.cell, cell.getContext()),
69
+ });
70
+ return children({
71
+ headerGroups,
72
+ rows,
73
+ isEmpty,
74
+ currentPage,
75
+ totalPages,
76
+ toggleAllRowsSelected: () => {
77
+ if (enableToggleAllRowsSelection)
78
+ table.toggleAllRowsSelected();
79
+ },
80
+ setPageIndex: (index) => table.setPageIndex(index),
81
+ onPageChange: handlePageChange,
82
+ flexRender,
83
+ getHeader,
84
+ getCell,
85
+ });
86
+ };
87
+ export default TableField;
@@ -0,0 +1,23 @@
1
+ import { type ReactNode, type CSSProperties } from 'react';
2
+ import { type TableFieldProps, type Pageable } from './TableField.js';
3
+ export type { Pageable };
4
+ export interface TanstackTableProps<TData, TColumn> extends Omit<TableFieldProps<TData, TColumn>, 'children'> {
5
+ title?: string;
6
+ rightSideContents?: ReactNode;
7
+ tableTop?: ReactNode;
8
+ showPagination?: boolean;
9
+ emptyMessage?: string | ReactNode;
10
+ scrollable?: boolean;
11
+ stickyHeader?: boolean;
12
+ className?: string;
13
+ wrapperClassName?: string;
14
+ wrapperStyle?: CSSProperties;
15
+ headerClassName?: string;
16
+ theadClassName?: string;
17
+ rowClassName?: string;
18
+ cellClassName?: string;
19
+ paginationClassName?: string;
20
+ }
21
+ declare const TanstackTable: <TData, TColumn>({ columns, data, pageable, paginationState, onPageChange, sortingState, enableRowSelection, enableMultiRowSelection, rowSelectionState, enableToggleAllRowsSelection, getRowId, title, showPagination, emptyMessage, stickyHeader, className, headerClassName, theadClassName, rowClassName, cellClassName, paginationClassName, }: TanstackTableProps<TData, TColumn>) => import("react/jsx-runtime").JSX.Element;
22
+ export default TanstackTable;
23
+ //# sourceMappingURL=TanstackTable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TanstackTable.d.ts","sourceRoot":"","sources":["../../../src/components/Table/TanstackTable.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAE3D,OAAmB,EAAE,KAAK,eAAe,EAAE,KAAK,QAAQ,EAAE,MAAM,cAAc,CAAC;AAM/E,YAAY,EAAE,QAAQ,EAAE,CAAC;AAEzB,MAAM,WAAW,kBAAkB,CAAC,KAAK,EAAE,OAAO,CAAE,SAAQ,IAAI,CAC9D,eAAe,CAAC,KAAK,EAAE,OAAO,CAAC,EAC/B,UAAU,CACX;IAEC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iBAAiB,CAAC,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,EAAE,SAAS,CAAC;IAGrB,cAAc,CAAC,EAAE,OAAO,CAAC;IAGzB,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,YAAY,CAAC,EAAE,OAAO,CAAC;IAGvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,aAAa,CAAC;IAC7B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,QAAA,MAAM,aAAa,GAAI,KAAK,EAAE,OAAO,EAAE,oUAwBpC,kBAAkB,CAAC,KAAK,EAAE,OAAO,CAAC,4CA+HpC,CAAC;AAEF,eAAe,aAAa,CAAC"}
@@ -0,0 +1,35 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { ArrowUp, ArrowDown } from 'lucide-react';
4
+ import TableField from './TableField.js';
5
+ import Table from './Table.js';
6
+ import Pagination from '../Pagination/Pagination.js';
7
+ import cn from '../../utils/cn.js';
8
+ const TanstackTable = ({
9
+ // TableField props
10
+ columns, data, pageable, paginationState, onPageChange, sortingState, enableRowSelection, enableMultiRowSelection, rowSelectionState, enableToggleAllRowsSelection, getRowId,
11
+ // 프레젠테이션 props
12
+ title, showPagination = true, emptyMessage, stickyHeader = false, className, headerClassName, theadClassName, rowClassName, cellClassName, paginationClassName, }) => {
13
+ return (_jsx(TableField, { columns: columns, data: data, pageable: pageable, paginationState: paginationState, onPageChange: onPageChange, sortingState: sortingState, enableRowSelection: enableRowSelection, enableMultiRowSelection: enableMultiRowSelection, rowSelectionState: rowSelectionState, enableToggleAllRowsSelection: enableToggleAllRowsSelection, getRowId: getRowId, children: ({ headerGroups, rows, isEmpty, currentPage, totalPages, toggleAllRowsSelected, onPageChange: handlePageChange, getHeader, getCell, }) => {
14
+ const paginationFooter = showPagination && !isEmpty && pageable && totalPages > 0 ? (_jsx(Pagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: handlePageChange, className: paginationClassName })) : null;
15
+ return (_jsxs(Table, { title: title, totalCount: pageable?.totalCount,
16
+ // rightSideContents={rightSideContents}
17
+ // tableTop={tableTop}
18
+ // scrollable={scrollable}
19
+ isEmpty: isEmpty, emptyMessage: emptyMessage, columnCount: columns.length, footer: paginationFooter, className: className, children: [_jsx(Table.Header, { className: cn('hover:bg-mono11 ld-transition', theadClassName), children: headerGroups.map((hg) => (_jsx(Table.HeaderRow, { className: "w-full", onClick: toggleAllRowsSelected, children: hg.headers.map((header) => {
20
+ const h = getHeader(header);
21
+ return (_jsxs(Table.HeaderCell, { className: cn('relative h-9', headerClassName, stickyHeader &&
22
+ 'sticky top-0 bg-mono10 z-10 border-b border-neutral10', h.canSort && 'cursor-pointer', h.meta
23
+ ?.headerAlign === 'left'
24
+ ? 'text-left'
25
+ : h.meta
26
+ ?.headerAlign === 'right'
27
+ ? 'text-right'
28
+ : 'text-center'), style: { width: h.size }, onClick: h.toggleSortingHandler, children: [h.renderHeader(), h.isSorted === 'asc' && (_jsx(ArrowUp, { className: "inline-block w-3 h-3 ml-1 align-middle" })), h.isSorted === 'desc' && (_jsx(ArrowDown, { className: "inline-block w-3 h-3 ml-1 align-middle" }))] }, h.id));
29
+ }) }, hg.id))) }), !isEmpty && (_jsx(Table.Body, { children: rows.map((row) => (_jsx(Table.Row, { selected: row.getIsSelected(), className: cn('hover:bg-black/3 ld-transition h-13', rowClassName), onClick: () => row.toggleSelected(), children: row.getVisibleCells().map((cell) => {
30
+ const c = getCell(cell);
31
+ return (_jsx(Table.Cell, { className: cellClassName, children: c.renderCell() }, c.id));
32
+ }) }, row.id))) }))] }));
33
+ } }));
34
+ };
35
+ export default TanstackTable;
@@ -0,0 +1,12 @@
1
+ import { type RegisterOptions } from 'react-hook-form';
2
+ import { type TimePickerProps } from './TimePicker.js';
3
+ interface FormTimePickerProps extends Omit<TimePickerProps, 'value' | 'onChange'> {
4
+ name: string;
5
+ options?: RegisterOptions;
6
+ customErrorMessage?: string;
7
+ isHiddenErrorMessage?: boolean;
8
+ errorClassName?: string;
9
+ }
10
+ declare const FormTimePicker: ({ name, options, customErrorMessage, isHiddenErrorMessage, errorClassName, disabled, block, ...props }: FormTimePickerProps) => import("react/jsx-runtime").JSX.Element;
11
+ export default FormTimePicker;
12
+ //# sourceMappingURL=FormTimePicker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FormTimePicker.d.ts","sourceRoot":"","sources":["../../../src/components/TimePicker/FormTimePicker.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAmB,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAKhE,UAAU,mBAAoB,SAAQ,IAAI,CACxC,eAAe,EACf,OAAO,GAAG,UAAU,CACrB;IACC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,QAAA,MAAM,cAAc,GAAI,wGASrB,mBAAmB,4CAoCrB,CAAC;AAEF,eAAe,cAAc,CAAC"}