@pulog/component 0.0.0-stage → 0.1.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.
- package/README.md +815 -2
- package/dist/SelectionSummary-N6MMSND2.js +3 -0
- package/dist/SelectionSummary-N6MMSND2.js.map +1 -0
- package/dist/chunk-3JJG43AS.js +213 -0
- package/dist/chunk-3JJG43AS.js.map +1 -0
- package/dist/index.d.ts +550 -0
- package/dist/index.js +3844 -0
- package/dist/index.js.map +1 -0
- package/package.json +43 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"SelectionSummary-N6MMSND2.js"}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { Button } from '@pulog/ui';
|
|
2
|
+
import { createContext, useState, useCallback, useContext } from 'react';
|
|
3
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
4
|
+
import { X } from 'lucide-react';
|
|
5
|
+
import { AnimatePresence, motion } from 'framer-motion';
|
|
6
|
+
import { useTranslation } from 'react-i18next';
|
|
7
|
+
|
|
8
|
+
// src/data-table/selection/SelectionSummary.tsx
|
|
9
|
+
var SelectionContext = createContext(
|
|
10
|
+
void 0
|
|
11
|
+
);
|
|
12
|
+
function SelectionProvider({
|
|
13
|
+
children,
|
|
14
|
+
selectionMode: propSelectionMode
|
|
15
|
+
}) {
|
|
16
|
+
const selectionMode = propSelectionMode || "checkbox";
|
|
17
|
+
const [rowSelection, setRowSelection] = useState({});
|
|
18
|
+
const [expandedRows, setExpandedRows] = useState({});
|
|
19
|
+
const [selectAllTotal, setSelectAllTotal] = useState(0);
|
|
20
|
+
const [excludedRows, setExcludedRows] = useState(/* @__PURE__ */ new Set());
|
|
21
|
+
const isSelectAll = selectAllTotal > 0;
|
|
22
|
+
const toggleRow = useCallback((rowId, currentPageRowIds) => {
|
|
23
|
+
if (selectionMode === "radio") {
|
|
24
|
+
setRowSelection({ [rowId]: true });
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
if (selectAllTotal > 0) {
|
|
28
|
+
setExcludedRows((prev) => {
|
|
29
|
+
const next = new Set(prev);
|
|
30
|
+
if (next.has(rowId)) {
|
|
31
|
+
next.delete(rowId);
|
|
32
|
+
} else {
|
|
33
|
+
next.add(rowId);
|
|
34
|
+
}
|
|
35
|
+
return next;
|
|
36
|
+
});
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
setRowSelection((prev) => {
|
|
40
|
+
const newSelection = { ...prev };
|
|
41
|
+
if (currentPageRowIds?.length) {
|
|
42
|
+
currentPageRowIds.forEach((id) => {
|
|
43
|
+
if (newSelection[id] === void 0) newSelection[id] = false;
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
newSelection[rowId] = !prev[rowId];
|
|
47
|
+
return newSelection;
|
|
48
|
+
});
|
|
49
|
+
}, [selectAllTotal, selectionMode]);
|
|
50
|
+
const toggleAll = useCallback((rowIds, selected, total) => {
|
|
51
|
+
if (selected) {
|
|
52
|
+
setSelectAllTotal(total ?? rowIds.length);
|
|
53
|
+
setExcludedRows(/* @__PURE__ */ new Set());
|
|
54
|
+
setRowSelection((prev) => {
|
|
55
|
+
const newSelection = { ...prev };
|
|
56
|
+
rowIds.forEach((id) => {
|
|
57
|
+
newSelection[id] = true;
|
|
58
|
+
});
|
|
59
|
+
return newSelection;
|
|
60
|
+
});
|
|
61
|
+
} else {
|
|
62
|
+
setSelectAllTotal(0);
|
|
63
|
+
setExcludedRows(/* @__PURE__ */ new Set());
|
|
64
|
+
setRowSelection({});
|
|
65
|
+
}
|
|
66
|
+
}, []);
|
|
67
|
+
const selectRows = useCallback((rowIds) => {
|
|
68
|
+
setSelectAllTotal(0);
|
|
69
|
+
setExcludedRows(/* @__PURE__ */ new Set());
|
|
70
|
+
setRowSelection((prev) => {
|
|
71
|
+
const newSelection = { ...prev };
|
|
72
|
+
rowIds.forEach((id) => {
|
|
73
|
+
newSelection[id] = true;
|
|
74
|
+
});
|
|
75
|
+
return newSelection;
|
|
76
|
+
});
|
|
77
|
+
}, []);
|
|
78
|
+
const deselectRows = useCallback((rowIds) => {
|
|
79
|
+
setSelectAllTotal(0);
|
|
80
|
+
setExcludedRows(/* @__PURE__ */ new Set());
|
|
81
|
+
setRowSelection((prev) => {
|
|
82
|
+
const newSelection = { ...prev };
|
|
83
|
+
rowIds.forEach((id) => {
|
|
84
|
+
delete newSelection[id];
|
|
85
|
+
});
|
|
86
|
+
return newSelection;
|
|
87
|
+
});
|
|
88
|
+
}, []);
|
|
89
|
+
const clearSelection = useCallback(() => {
|
|
90
|
+
setSelectAllTotal(0);
|
|
91
|
+
setExcludedRows(/* @__PURE__ */ new Set());
|
|
92
|
+
setRowSelection({});
|
|
93
|
+
}, []);
|
|
94
|
+
const clearSelectAll = useCallback(() => {
|
|
95
|
+
setSelectAllTotal(0);
|
|
96
|
+
setExcludedRows(/* @__PURE__ */ new Set());
|
|
97
|
+
}, []);
|
|
98
|
+
const isRowSelected = useCallback(
|
|
99
|
+
(rowId) => {
|
|
100
|
+
if (selectAllTotal > 0) {
|
|
101
|
+
return !excludedRows.has(rowId);
|
|
102
|
+
}
|
|
103
|
+
return !!rowSelection[rowId];
|
|
104
|
+
},
|
|
105
|
+
[rowSelection, selectAllTotal, excludedRows]
|
|
106
|
+
);
|
|
107
|
+
const selectedCount = selectAllTotal > 0 ? selectAllTotal - excludedRows.size : Object.values(rowSelection).filter(Boolean).length;
|
|
108
|
+
const toggleExpanded = useCallback((rowId) => {
|
|
109
|
+
setExpandedRows((prev) => ({
|
|
110
|
+
...prev,
|
|
111
|
+
[rowId]: !prev[rowId]
|
|
112
|
+
}));
|
|
113
|
+
}, []);
|
|
114
|
+
const isRowExpanded = useCallback(
|
|
115
|
+
(rowId) => !!expandedRows[rowId],
|
|
116
|
+
[expandedRows]
|
|
117
|
+
);
|
|
118
|
+
const expandedCount = Object.values(expandedRows).filter(Boolean).length;
|
|
119
|
+
const getSelectedRowIds = useCallback(
|
|
120
|
+
() => {
|
|
121
|
+
if (selectAllTotal > 0) {
|
|
122
|
+
return Object.keys(rowSelection).filter((id) => rowSelection[id] && !excludedRows.has(id));
|
|
123
|
+
}
|
|
124
|
+
return Object.keys(rowSelection).filter((id) => rowSelection[id]);
|
|
125
|
+
},
|
|
126
|
+
[rowSelection, selectAllTotal, excludedRows]
|
|
127
|
+
);
|
|
128
|
+
const value = {
|
|
129
|
+
rowSelection,
|
|
130
|
+
expandedRows,
|
|
131
|
+
isSelectAll,
|
|
132
|
+
toggleRow,
|
|
133
|
+
toggleAll,
|
|
134
|
+
selectRows,
|
|
135
|
+
deselectRows,
|
|
136
|
+
clearSelection,
|
|
137
|
+
isRowSelected,
|
|
138
|
+
selectedCount,
|
|
139
|
+
toggleExpanded,
|
|
140
|
+
isRowExpanded,
|
|
141
|
+
expandedCount,
|
|
142
|
+
getSelectedRowIds,
|
|
143
|
+
clearSelectAll,
|
|
144
|
+
selectionMode
|
|
145
|
+
};
|
|
146
|
+
return /* @__PURE__ */ jsx(SelectionContext.Provider, { value, children });
|
|
147
|
+
}
|
|
148
|
+
function useSelection() {
|
|
149
|
+
const context = useContext(SelectionContext);
|
|
150
|
+
if (!context) {
|
|
151
|
+
throw new Error(
|
|
152
|
+
"useSelection must be used within a SelectionProvider"
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
return context;
|
|
156
|
+
}
|
|
157
|
+
function SelectionSummary({
|
|
158
|
+
onAction,
|
|
159
|
+
actionLabel = "Action"
|
|
160
|
+
}) {
|
|
161
|
+
const { t } = useTranslation("datatable");
|
|
162
|
+
const { selectedCount, getSelectedRowIds, clearSelection } = useSelection();
|
|
163
|
+
const selectedIds = getSelectedRowIds();
|
|
164
|
+
return /* @__PURE__ */ jsx(AnimatePresence, { children: selectedCount > 0 && /* @__PURE__ */ jsxs(
|
|
165
|
+
motion.div,
|
|
166
|
+
{
|
|
167
|
+
initial: { opacity: 0, height: 0 },
|
|
168
|
+
animate: { opacity: 1, height: "auto" },
|
|
169
|
+
exit: { opacity: 0, height: 0 },
|
|
170
|
+
transition: { duration: 0.2 },
|
|
171
|
+
className: "flex items-center gap-2 p-3 bg-primary/5 border border-primary/10 rounded-lg overflow-hidden",
|
|
172
|
+
children: [
|
|
173
|
+
/* @__PURE__ */ jsxs("span", { className: "text-sm text-muted-foreground", children: [
|
|
174
|
+
t("totalSelected"),
|
|
175
|
+
":"
|
|
176
|
+
] }),
|
|
177
|
+
/* @__PURE__ */ jsxs("span", { className: "text-sm font-medium text-primary", children: [
|
|
178
|
+
selectedCount,
|
|
179
|
+
" ",
|
|
180
|
+
actionLabel
|
|
181
|
+
] }),
|
|
182
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
|
|
183
|
+
onAction && /* @__PURE__ */ jsx(
|
|
184
|
+
Button,
|
|
185
|
+
{
|
|
186
|
+
size: "sm",
|
|
187
|
+
variant: "default",
|
|
188
|
+
onClick: () => onAction(selectedIds),
|
|
189
|
+
children: actionLabel
|
|
190
|
+
}
|
|
191
|
+
),
|
|
192
|
+
/* @__PURE__ */ jsxs(
|
|
193
|
+
Button,
|
|
194
|
+
{
|
|
195
|
+
size: "sm",
|
|
196
|
+
variant: "outline",
|
|
197
|
+
onClick: clearSelection,
|
|
198
|
+
className: "gap-1",
|
|
199
|
+
children: [
|
|
200
|
+
/* @__PURE__ */ jsx(X, { className: "h-2.5 w-2.5" }),
|
|
201
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs", children: t("clearSelections") })
|
|
202
|
+
]
|
|
203
|
+
}
|
|
204
|
+
)
|
|
205
|
+
] })
|
|
206
|
+
]
|
|
207
|
+
}
|
|
208
|
+
) });
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
export { SelectionProvider, SelectionSummary, useSelection };
|
|
212
|
+
//# sourceMappingURL=chunk-3JJG43AS.js.map
|
|
213
|
+
//# sourceMappingURL=chunk-3JJG43AS.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/data-table/contexts/SelectionContext.tsx","../src/data-table/selection/SelectionSummary.tsx"],"names":["jsx"],"mappings":"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","file":"chunk-3JJG43AS.js","sourcesContent":["'use client';\r\n\r\nimport React, { createContext, useContext, useState, useCallback } from 'react';\r\nimport { RowSelectionState, ExpandedRowState } from '../lib/types';\r\n\r\ninterface SelectionContextType {\r\n rowSelection: RowSelectionState;\r\n expandedRows: ExpandedRowState;\r\n isSelectAll: boolean;\r\n toggleRow: (rowId: string, currentPageRowIds?: string[]) => void;\r\n toggleAll: (rowIds: string[], selected: boolean, total?: number) => void;\r\n selectRows: (rowIds: string[]) => void;\r\n deselectRows: (rowIds: string[]) => void;\r\n clearSelection: () => void;\r\n isRowSelected: (rowId: string) => boolean;\r\n selectedCount: number;\r\n toggleExpanded: (rowId: string) => void;\r\n isRowExpanded: (rowId: string) => boolean;\r\n expandedCount: number;\r\n getSelectedRowIds: () => string[];\r\n clearSelectAll: () => void;\r\n selectionMode: 'checkbox' | 'radio';\r\n}\r\n\r\nconst SelectionContext = createContext<SelectionContextType | undefined>(\r\n undefined\r\n);\r\n\r\nexport function SelectionProvider({\r\n children,\r\n selectionMode: propSelectionMode,\r\n}: {\r\n children: React.ReactNode;\r\n selectionMode?: 'checkbox' | 'radio';\r\n}) {\r\n const selectionMode = propSelectionMode || 'checkbox';\r\n const [rowSelection, setRowSelection] = useState<RowSelectionState>({});\r\n const [expandedRows, setExpandedRows] = useState<ExpandedRowState>({});\r\n const [selectAllTotal, setSelectAllTotal] = useState(0);\r\n const [excludedRows, setExcludedRows] = useState<Set<string>>(new Set());\r\n\r\n const isSelectAll = selectAllTotal > 0;\r\n\r\n const toggleRow = useCallback((rowId: string, currentPageRowIds?: string[]) => {\r\n if (selectionMode === 'radio') {\r\n setRowSelection({ [rowId]: true });\r\n return;\r\n }\r\n\r\n if (selectAllTotal > 0) {\r\n setExcludedRows((prev) => {\r\n const next = new Set(prev);\r\n if (next.has(rowId)) {\r\n next.delete(rowId);\r\n } else {\r\n next.add(rowId);\r\n }\r\n return next;\r\n });\r\n return;\r\n }\r\n\r\n setRowSelection((prev) => {\r\n const newSelection = { ...prev };\r\n if (currentPageRowIds?.length) {\r\n currentPageRowIds.forEach((id) => {\r\n if (newSelection[id] === undefined) newSelection[id] = false;\r\n });\r\n }\r\n newSelection[rowId] = !prev[rowId];\r\n return newSelection;\r\n });\r\n }, [selectAllTotal, selectionMode]);\r\n\r\n const toggleAll = useCallback((rowIds: string[], selected: boolean, total?: number) => {\r\n if (selected) {\r\n setSelectAllTotal(total ?? rowIds.length);\r\n setExcludedRows(new Set());\r\n setRowSelection((prev) => {\r\n const newSelection = { ...prev };\r\n rowIds.forEach((id) => {\r\n newSelection[id] = true;\r\n });\r\n return newSelection;\r\n });\r\n } else {\r\n // Leaving global select-all must clear every remembered page. Removing only\r\n // the current page IDs leaves stale checked rows when the user navigates back.\r\n setSelectAllTotal(0);\r\n setExcludedRows(new Set());\r\n setRowSelection({});\r\n }\r\n }, []);\r\n\r\n const selectRows = useCallback((rowIds: string[]) => {\r\n setSelectAllTotal(0);\r\n setExcludedRows(new Set());\r\n setRowSelection((prev) => {\r\n const newSelection = { ...prev };\r\n rowIds.forEach((id) => {\r\n newSelection[id] = true;\r\n });\r\n return newSelection;\r\n });\r\n }, []);\r\n\r\n const deselectRows = useCallback((rowIds: string[]) => {\r\n setSelectAllTotal(0);\r\n setExcludedRows(new Set());\r\n setRowSelection((prev) => {\r\n const newSelection = { ...prev };\r\n rowIds.forEach((id) => {\r\n delete newSelection[id];\r\n });\r\n return newSelection;\r\n });\r\n }, []);\r\n\r\n const clearSelection = useCallback(() => {\r\n setSelectAllTotal(0);\r\n setExcludedRows(new Set());\r\n setRowSelection({});\r\n }, []);\r\n\r\n const clearSelectAll = useCallback(() => {\r\n setSelectAllTotal(0);\r\n setExcludedRows(new Set());\r\n }, []);\r\n\r\n const isRowSelected = useCallback(\r\n (rowId: string) => {\r\n if (selectAllTotal > 0) {\r\n return !excludedRows.has(rowId);\r\n }\r\n return !!rowSelection[rowId];\r\n },\r\n [rowSelection, selectAllTotal, excludedRows]\r\n );\r\n\r\n const selectedCount = selectAllTotal > 0\r\n ? selectAllTotal - excludedRows.size\r\n : Object.values(rowSelection).filter(Boolean).length;\r\n\r\n const toggleExpanded = useCallback((rowId: string) => {\r\n setExpandedRows((prev) => ({\r\n ...prev,\r\n [rowId]: !prev[rowId],\r\n }));\r\n }, []);\r\n\r\n const isRowExpanded = useCallback(\r\n (rowId: string) => !!expandedRows[rowId],\r\n [expandedRows]\r\n );\r\n\r\n const expandedCount = Object.values(expandedRows).filter(Boolean).length;\r\n\r\n const getSelectedRowIds = useCallback(\r\n () => {\r\n if (selectAllTotal > 0) {\r\n return Object.keys(rowSelection).filter((id) => rowSelection[id] && !excludedRows.has(id));\r\n }\r\n return Object.keys(rowSelection).filter((id) => rowSelection[id]);\r\n },\r\n [rowSelection, selectAllTotal, excludedRows]\r\n );\r\n\r\n const value: SelectionContextType = {\r\n rowSelection,\r\n expandedRows,\r\n isSelectAll,\r\n toggleRow,\r\n toggleAll,\r\n selectRows,\r\n deselectRows,\r\n clearSelection,\r\n isRowSelected,\r\n selectedCount,\r\n toggleExpanded,\r\n isRowExpanded,\r\n expandedCount,\r\n getSelectedRowIds,\r\n clearSelectAll,\r\n selectionMode,\r\n };\r\n\r\n return (\r\n <SelectionContext.Provider value={value}>\r\n {children}\r\n </SelectionContext.Provider>\r\n );\r\n}\r\n\r\nexport function useSelection(): SelectionContextType {\r\n const context = useContext(SelectionContext);\r\n if (!context) {\r\n throw new Error(\r\n 'useSelection must be used within a SelectionProvider'\r\n );\r\n }\r\n return context;\r\n}\r\n","'use client';\r\n\r\nimport React from 'react';\r\nimport { Button } from '@pulog/ui';\r\nimport { Badge } from '@pulog/ui';\r\nimport { useSelection } from '../contexts/SelectionContext';\r\nimport { X } from 'lucide-react';\r\nimport { AnimatePresence, motion } from 'framer-motion';\r\nimport { useTranslation } from 'react-i18next';\r\n\r\ninterface SelectionSummaryProps {\r\n onAction?: (selectedIds: string[]) => void;\r\n actionLabel?: string;\r\n}\r\n\r\nexport function SelectionSummary({\r\n onAction,\r\n actionLabel = 'Action',\r\n}: SelectionSummaryProps) {\r\n const { t } = useTranslation('datatable');\r\n const { selectedCount, getSelectedRowIds, clearSelection } = useSelection();\r\n\r\n const selectedIds = getSelectedRowIds();\r\n\r\n return (\r\n <AnimatePresence>\r\n {selectedCount > 0 && (\r\n <motion.div\r\n initial={{ opacity: 0, height: 0 }}\r\n animate={{ opacity: 1, height: 'auto' }}\r\n exit={{ opacity: 0, height: 0 }}\r\n transition={{ duration: 0.2 }}\r\n className=\"flex items-center gap-2 p-3 bg-primary/5 border border-primary/10 rounded-lg overflow-hidden\"\r\n >\r\n <span className=\"text-sm text-muted-foreground\">\r\n {t('totalSelected')}:\r\n </span>\r\n <span className=\"text-sm font-medium text-primary\">\r\n {selectedCount} {actionLabel}\r\n </span>\r\n <div className=\"flex gap-2\">\r\n {onAction && (\r\n <Button\r\n size=\"sm\"\r\n variant=\"default\"\r\n onClick={() => onAction(selectedIds)}\r\n >\r\n {actionLabel}\r\n </Button>\r\n )}\r\n <Button\r\n size=\"sm\"\r\n variant=\"outline\"\r\n onClick={clearSelection}\r\n className=\"gap-1\"\r\n >\r\n <X className=\"h-2.5 w-2.5\" />\r\n <span className=\"text-xs\">{t('clearSelections')}</span>\r\n </Button>\r\n </div>\r\n </motion.div>\r\n )}\r\n </AnimatePresence>\r\n );\r\n}\r\n"]}
|