dn-react-router-toolkit 0.7.15 → 0.8.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 (67) hide show
  1. package/dist/api/create_api_handler.d.mts +5 -4
  2. package/dist/api/create_api_handler.d.ts +5 -4
  3. package/dist/api/create_api_handler.js +0 -1
  4. package/dist/api/create_api_handler.mjs +0 -1
  5. package/dist/api/index.d.mts +1 -0
  6. package/dist/api/index.d.ts +1 -0
  7. package/dist/api/index.js +13 -6
  8. package/dist/api/index.mjs +14 -7
  9. package/dist/api/item_api_handler.d.mts +8 -5
  10. package/dist/api/item_api_handler.d.ts +8 -5
  11. package/dist/api/item_api_handler.js +13 -5
  12. package/dist/api/item_api_handler.mjs +14 -6
  13. package/dist/crud/crud_loader.d.mts +6 -5
  14. package/dist/crud/crud_loader.d.ts +6 -5
  15. package/dist/crud/crud_loader.js +79 -38
  16. package/dist/crud/crud_loader.mjs +81 -39
  17. package/dist/crud/crud_page.d.mts +3 -2
  18. package/dist/crud/crud_page.d.ts +3 -2
  19. package/dist/crud/crud_page.js +279 -201
  20. package/dist/crud/crud_page.mjs +277 -205
  21. package/dist/crud/generate_handlers.d.mts +3 -2
  22. package/dist/crud/generate_handlers.d.ts +3 -2
  23. package/dist/crud/generate_pages.d.mts +2 -1
  24. package/dist/crud/generate_pages.d.ts +2 -1
  25. package/dist/crud/index.d.mts +5 -3
  26. package/dist/crud/index.d.ts +5 -3
  27. package/dist/crud/index.js +338 -219
  28. package/dist/crud/index.mjs +346 -232
  29. package/dist/post/index.js +71 -64
  30. package/dist/post/index.mjs +76 -74
  31. package/dist/post/post_form_page.js +71 -64
  32. package/dist/post/post_form_page.mjs +76 -74
  33. package/dist/table/index.d.mts +7 -3
  34. package/dist/table/index.d.ts +7 -3
  35. package/dist/table/index.js +233 -111
  36. package/dist/table/index.mjs +230 -116
  37. package/dist/table/item_loader.d.mts +5 -4
  38. package/dist/table/item_loader.d.ts +5 -4
  39. package/dist/table/load_table.d.mts +36 -0
  40. package/dist/table/load_table.d.ts +36 -0
  41. package/dist/table/load_table.js +87 -0
  42. package/dist/table/load_table.mjs +66 -0
  43. package/dist/table/loader.d.mts +10 -15
  44. package/dist/table/loader.d.ts +10 -15
  45. package/dist/table/loader.js +67 -31
  46. package/dist/table/loader.mjs +67 -32
  47. package/dist/table/page.d.mts +6 -16
  48. package/dist/table/page.d.ts +6 -16
  49. package/dist/table/page.js +247 -169
  50. package/dist/table/page.mjs +248 -176
  51. package/dist/table/repository.d.mts +14 -10
  52. package/dist/table/repository.d.ts +14 -10
  53. package/dist/table/repository.js +5 -1
  54. package/dist/table/repository.mjs +5 -1
  55. package/dist/table/table.d.mts +4 -1
  56. package/dist/table/table.d.ts +4 -1
  57. package/dist/table/table.js +55 -6
  58. package/dist/table/table.mjs +55 -6
  59. package/dist/table/table_form.d.mts +13 -0
  60. package/dist/table/table_form.d.ts +13 -0
  61. package/dist/table/table_form.js +345 -0
  62. package/dist/table/table_form.mjs +320 -0
  63. package/dist/table/use_table.d.mts +4 -0
  64. package/dist/table/use_table.d.ts +4 -0
  65. package/dist/table/use_table.js +34 -0
  66. package/dist/table/use_table.mjs +9 -0
  67. package/package.json +2 -2
@@ -0,0 +1,320 @@
1
+ // src/table/table_form.tsx
2
+ import { useLocation as useLocation2, useNavigate, useSearchParams as useSearchParams3 } from "react-router";
3
+ import { GoSearch } from "react-icons/go";
4
+
5
+ // src/table/table.tsx
6
+ import { cn } from "dn-react-toolkit/utils";
7
+ import { GoArrowDown, GoArrowUp } from "react-icons/go";
8
+ import { Link, useSearchParams } from "react-router";
9
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
10
+ function Table({
11
+ className = "min-w-full whitespace-nowrap",
12
+ data,
13
+ columns,
14
+ mapper: Mapper,
15
+ getLink,
16
+ limit,
17
+ offset,
18
+ orderBy,
19
+ direction,
20
+ filters
21
+ }) {
22
+ const keys = Object.entries(columns).filter((entry) => entry[1]).map(([key]) => key);
23
+ const sortedArray = [...data];
24
+ const [_, setSearchParams] = useSearchParams();
25
+ return /* @__PURE__ */ jsxs(
26
+ "table",
27
+ {
28
+ className: cn(
29
+ className,
30
+ "text-[15px] border-separate border-spacing-0"
31
+ ),
32
+ children: [
33
+ /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsx("tr", { children: keys.map((key) => {
34
+ const value = columns[key];
35
+ function getReactNode() {
36
+ if (value && typeof value === "object" && "label" in value) {
37
+ return value.label;
38
+ }
39
+ return value;
40
+ }
41
+ function Head() {
42
+ const reactNode = getReactNode();
43
+ if (typeof reactNode === "string") {
44
+ return /* @__PURE__ */ jsxs(
45
+ "button",
46
+ {
47
+ className: cn(
48
+ orderBy === key ? "text-gray-900 font-medium" : "text-gray-500 font-medium",
49
+ "px-4 flex items-center w-full"
50
+ ),
51
+ onClick: () => {
52
+ let newDirection = "asc";
53
+ if (orderBy === key) {
54
+ newDirection = direction === "asc" ? "desc" : "asc";
55
+ }
56
+ setSearchParams({
57
+ orderBy: key,
58
+ direction: newDirection
59
+ });
60
+ },
61
+ children: [
62
+ reactNode,
63
+ orderBy === key && /* @__PURE__ */ jsx("div", { className: "ml-0.5", children: direction === "asc" ? /* @__PURE__ */ jsx(GoArrowUp, {}) : /* @__PURE__ */ jsx(GoArrowDown, {}) })
64
+ ]
65
+ }
66
+ );
67
+ }
68
+ return /* @__PURE__ */ jsx(Fragment, { children: reactNode });
69
+ }
70
+ const filter = filters[key];
71
+ return /* @__PURE__ */ jsxs(
72
+ "th",
73
+ {
74
+ className: cn(
75
+ "py-4 border-y font-normal align-top"
76
+ ),
77
+ children: [
78
+ /* @__PURE__ */ jsx(Head, {}),
79
+ filter && /* @__PURE__ */ jsx("div", { className: "px-3 mt-4", children: /* @__PURE__ */ jsxs(
80
+ "select",
81
+ {
82
+ className: "w-full h-10 px-1.5 border rounded-full outline-none",
83
+ onChange: (e) => {
84
+ const value2 = e.target.value;
85
+ setSearchParams((prev) => {
86
+ if (value2) {
87
+ prev.set(
88
+ key,
89
+ encodeURIComponent(
90
+ value2
91
+ )
92
+ );
93
+ } else {
94
+ prev.delete(key);
95
+ }
96
+ return prev;
97
+ });
98
+ },
99
+ children: [
100
+ /* @__PURE__ */ jsx("option", { value: "", children: "\uC804\uCCB4" }),
101
+ filter.map((option) => /* @__PURE__ */ jsx(
102
+ "option",
103
+ {
104
+ value: option,
105
+ children: option
106
+ },
107
+ option
108
+ ))
109
+ ]
110
+ }
111
+ ) })
112
+ ]
113
+ },
114
+ key
115
+ );
116
+ }) }) }),
117
+ /* @__PURE__ */ jsxs("tbody", { children: [
118
+ sortedArray.length === 0 && /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx(
119
+ "td",
120
+ {
121
+ colSpan: keys.length,
122
+ className: "px-4 h-20 text-gray-400 text-center",
123
+ children: "\uB370\uC774\uD130\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."
124
+ }
125
+ ) }),
126
+ sortedArray.map((item, i) => /* @__PURE__ */ jsx("tr", { className: "hover:bg-gray-50 transition-colors", children: keys.map((key, i2) => {
127
+ const value = item[key];
128
+ function Content() {
129
+ if (key in columns) {
130
+ const column = columns[key];
131
+ if (column && typeof column === "object" && "mapper" in column) {
132
+ const mapper = column.mapper;
133
+ if (mapper) {
134
+ return /* @__PURE__ */ jsx(Fragment, { children: mapper(item) });
135
+ }
136
+ }
137
+ }
138
+ return /* @__PURE__ */ jsx(Fragment, { children: String(value) });
139
+ }
140
+ const linkedContent = getLink ? /* @__PURE__ */ jsx(
141
+ Link,
142
+ {
143
+ to: getLink(item),
144
+ className: "block content-center px-4 w-full h-full",
145
+ children: /* @__PURE__ */ jsx(Content, {})
146
+ }
147
+ ) : /* @__PURE__ */ jsx(Content, {});
148
+ const cell = Mapper ? /* @__PURE__ */ jsx(Mapper, { item, index: i2, children: linkedContent }) : linkedContent;
149
+ return /* @__PURE__ */ jsx("td", { className: "px-0 h-14 border-b", children: cell }, key);
150
+ }) }, i))
151
+ ] })
152
+ ]
153
+ }
154
+ );
155
+ }
156
+
157
+ // src/table/use_table.tsx
158
+ import { useLoaderData } from "react-router";
159
+ function useTable() {
160
+ const { table } = useLoaderData();
161
+ return table;
162
+ }
163
+
164
+ // src/table/buttons.tsx
165
+ import { cn as cn2 } from "dn-react-toolkit/utils";
166
+ import { Link as Link2, useLocation, useSearchParams as useSearchParams2 } from "react-router";
167
+ import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
168
+ function TablePageButtons({
169
+ MAX_PAGES_TO_SHOW,
170
+ total,
171
+ limit,
172
+ offset
173
+ }) {
174
+ const pages = Math.ceil(total / limit);
175
+ const { pathname } = useLocation();
176
+ const [searchParams] = useSearchParams2();
177
+ const currentPage = Math.floor(offset / limit) + 1;
178
+ const startButton = (Math.ceil(currentPage / MAX_PAGES_TO_SHOW) - 1) * MAX_PAGES_TO_SHOW;
179
+ const endButton = Math.min(startButton + MAX_PAGES_TO_SHOW - 1, pages);
180
+ return /* @__PURE__ */ jsx2(Fragment2, { children: pages > 1 && /* @__PURE__ */ jsxs2("div", { className: "flex justify-center items-center my-8 gap-4 text-neutral-400", children: [
181
+ startButton > 1 && /* @__PURE__ */ jsx2(
182
+ Link2,
183
+ {
184
+ to: (() => {
185
+ searchParams.set(
186
+ "offset",
187
+ String((startButton - 1) * limit)
188
+ );
189
+ return `${pathname}?${searchParams.toString()}`;
190
+ })(),
191
+ className: "w-10 block text-center transition-colors hover:text-primary",
192
+ children: "\uC774\uC804"
193
+ }
194
+ ),
195
+ Array.from({
196
+ length: Math.min(
197
+ MAX_PAGES_TO_SHOW,
198
+ pages - startButton
199
+ )
200
+ }).map((_, index) => {
201
+ return /* @__PURE__ */ jsx2(
202
+ Link2,
203
+ {
204
+ to: (() => {
205
+ searchParams.set(
206
+ "offset",
207
+ String((startButton + index) * limit)
208
+ );
209
+ return `${pathname}?${searchParams.toString()}`;
210
+ })(),
211
+ className: cn2(
212
+ "w-6 block text-center transition-colors",
213
+ currentPage === startButton + index + 1 ? "font-bold text-primary" : "hover:text-primary"
214
+ ),
215
+ children: startButton + index + 1
216
+ },
217
+ index
218
+ );
219
+ }),
220
+ endButton < pages && /* @__PURE__ */ jsx2(
221
+ Link2,
222
+ {
223
+ to: (() => {
224
+ searchParams.set(
225
+ "offset",
226
+ String((endButton + 1) * limit)
227
+ );
228
+ return `${pathname}?${searchParams.toString()}`;
229
+ })(),
230
+ className: "w-10 block text-center transition-colors hover:text-primary",
231
+ children: "\uB2E4\uC74C"
232
+ }
233
+ )
234
+ ] }) });
235
+ }
236
+
237
+ // src/table/table_form.tsx
238
+ import { Fragment as Fragment3, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
239
+ function TableForm({
240
+ columns,
241
+ primaryKey = "id"
242
+ }) {
243
+ const { pathname } = useLocation2();
244
+ const {
245
+ items,
246
+ total,
247
+ limit,
248
+ offset,
249
+ orderBy,
250
+ direction,
251
+ searchKey,
252
+ filters
253
+ } = useTable();
254
+ const navigate = useNavigate();
255
+ const search = (query) => {
256
+ const searchParams2 = new URLSearchParams(window.location.search);
257
+ searchParams2.set("query", query);
258
+ searchParams2.set("offset", "0");
259
+ navigate(`${pathname}?${searchParams2.toString()}`);
260
+ };
261
+ const [searchParams] = useSearchParams3();
262
+ return /* @__PURE__ */ jsxs3(Fragment3, { children: [
263
+ searchKey && /* @__PURE__ */ jsxs3(
264
+ "form",
265
+ {
266
+ className: "h-20 px-4 flex items-center border-t",
267
+ onSubmit: (e) => {
268
+ e.preventDefault();
269
+ const formData = new FormData(e.currentTarget);
270
+ const query = formData.get("query");
271
+ search(query);
272
+ },
273
+ children: [
274
+ /* @__PURE__ */ jsx3(
275
+ "button",
276
+ {
277
+ type: "submit",
278
+ className: "w-10 h-10 flex justify-center items-center",
279
+ children: /* @__PURE__ */ jsx3(GoSearch, { className: "text-xl mr-4" })
280
+ }
281
+ ),
282
+ /* @__PURE__ */ jsx3(
283
+ "input",
284
+ {
285
+ className: "outline-none h-full flex-1",
286
+ placeholder: "\uC5EC\uAE30\uC5D0 \uAC80\uC0C9\uD558\uC138\uC694...",
287
+ name: "query",
288
+ defaultValue: searchParams.get("query") ?? ""
289
+ }
290
+ )
291
+ ]
292
+ }
293
+ ),
294
+ /* @__PURE__ */ jsx3(
295
+ Table,
296
+ {
297
+ data: items,
298
+ columns,
299
+ getLink: primaryKey ? (item) => `${pathname}/${item[primaryKey]}` : void 0,
300
+ limit,
301
+ offset,
302
+ orderBy,
303
+ direction,
304
+ filters
305
+ }
306
+ ),
307
+ /* @__PURE__ */ jsx3(
308
+ TablePageButtons,
309
+ {
310
+ total,
311
+ limit,
312
+ offset,
313
+ MAX_PAGES_TO_SHOW: 10
314
+ }
315
+ )
316
+ ] });
317
+ }
318
+ export {
319
+ TableForm
320
+ };
@@ -0,0 +1,4 @@
1
+ type TableLoaderData<T extends (...args: any) => any> = Awaited<ReturnType<T>>["table"];
2
+ declare function useTable<T extends (...args: any) => any>(): TableLoaderData<T>;
3
+
4
+ export { type TableLoaderData, useTable };
@@ -0,0 +1,4 @@
1
+ type TableLoaderData<T extends (...args: any) => any> = Awaited<ReturnType<T>>["table"];
2
+ declare function useTable<T extends (...args: any) => any>(): TableLoaderData<T>;
3
+
4
+ export { type TableLoaderData, useTable };
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/table/use_table.tsx
21
+ var use_table_exports = {};
22
+ __export(use_table_exports, {
23
+ useTable: () => useTable
24
+ });
25
+ module.exports = __toCommonJS(use_table_exports);
26
+ var import_react_router = require("react-router");
27
+ function useTable() {
28
+ const { table } = (0, import_react_router.useLoaderData)();
29
+ return table;
30
+ }
31
+ // Annotate the CommonJS export names for ESM import in node:
32
+ 0 && (module.exports = {
33
+ useTable
34
+ });
@@ -0,0 +1,9 @@
1
+ // src/table/use_table.tsx
2
+ import { useLoaderData } from "react-router";
3
+ function useTable() {
4
+ const { table } = useLoaderData();
5
+ return table;
6
+ }
7
+ export {
8
+ useTable
9
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dn-react-router-toolkit",
3
- "version": "0.7.15",
3
+ "version": "0.8.1",
4
4
  "types": "./dist/index.d.ts",
5
5
  "main": "./dist/index.mjs",
6
6
  "module": "./dist/index.js",
@@ -100,4 +100,4 @@
100
100
  "react-dom": "^19",
101
101
  "react-router": "^7.13.1"
102
102
  }
103
- }
103
+ }