@g4rcez/components 3.0.0-0 → 3.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.
- package/dist/ai/SKILL.md +266 -0
- package/dist/ai/docs/Alert.md +167 -0
- package/dist/ai/docs/AnimatedList.md +205 -0
- package/dist/ai/docs/Autocomplete.md +225 -0
- package/dist/ai/docs/Button.md +182 -0
- package/dist/ai/docs/Calendar.md +219 -0
- package/dist/ai/docs/Card.md +174 -0
- package/dist/ai/docs/Checkbox.md +199 -0
- package/dist/ai/docs/CommandPalette.md +293 -0
- package/dist/ai/docs/DatePicker.md +171 -0
- package/dist/ai/docs/Dropdown.md +223 -0
- package/dist/ai/docs/Empty.md +163 -0
- package/dist/ai/docs/Expand.md +143 -0
- package/dist/ai/docs/FileUpload.md +225 -0
- package/dist/ai/docs/Form.md +107 -0
- package/dist/ai/docs/FormReset.md +117 -0
- package/dist/ai/docs/Heading.md +88 -0
- package/dist/ai/docs/Input.md +237 -0
- package/dist/ai/docs/InputField.md +170 -0
- package/dist/ai/docs/List.md +205 -0
- package/dist/ai/docs/Menu.md +166 -0
- package/dist/ai/docs/Modal.md +280 -0
- package/dist/ai/docs/MultiSelect.md +196 -0
- package/dist/ai/docs/Notifications.md +231 -0
- package/dist/ai/docs/PageCalendar.md +271 -0
- package/dist/ai/docs/Polymorph.md +159 -0
- package/dist/ai/docs/Progress.md +145 -0
- package/dist/ai/docs/Radiobox.md +128 -0
- package/dist/ai/docs/RenderOnView.md +138 -0
- package/dist/ai/docs/Resizable.md +159 -0
- package/dist/ai/docs/Select.md +284 -0
- package/dist/ai/docs/Shortcut.md +105 -0
- package/dist/ai/docs/Skeleton.md +166 -0
- package/dist/ai/docs/Slider.md +144 -0
- package/dist/ai/docs/Slot.md +173 -0
- package/dist/ai/docs/Spinner.md +118 -0
- package/dist/ai/docs/Stats.md +137 -0
- package/dist/ai/docs/Step.md +159 -0
- package/dist/ai/docs/Switch.md +167 -0
- package/dist/ai/docs/Table.md +298 -0
- package/dist/ai/docs/Tabs.md +191 -0
- package/dist/ai/docs/Tag.md +224 -0
- package/dist/ai/docs/TaskList.md +144 -0
- package/dist/ai/docs/Textarea.md +167 -0
- package/dist/ai/docs/Timeline.md +210 -0
- package/dist/ai/docs/Toolbar.md +132 -0
- package/dist/ai/docs/Tooltip.md +231 -0
- package/dist/ai/docs/TransferList.md +142 -0
- package/dist/ai/docs/Typography.md +187 -0
- package/dist/ai/docs/Wizard.md +213 -0
- package/dist/ai/docs/index.md +183 -0
- package/dist/components/core/button.d.ts +2 -8
- package/dist/components/core/button.d.ts.map +1 -1
- package/dist/components/core/polymorph.d.ts.map +1 -1
- package/dist/components/core/slot.d.ts +1 -1
- package/dist/components/core/slot.d.ts.map +1 -1
- package/dist/components/core/tag.d.ts +2 -2
- package/dist/components/core/tag.d.ts.map +1 -1
- package/dist/components/core/typography.d.ts.map +1 -1
- package/dist/components/display/alert.d.ts.map +1 -1
- package/dist/components/display/calendar.d.ts.map +1 -1
- package/dist/components/display/card.d.ts.map +1 -1
- package/dist/components/display/list.d.ts.map +1 -1
- package/dist/components/display/notifications.d.ts +2 -0
- package/dist/components/display/notifications.d.ts.map +1 -1
- package/dist/components/display/progress.d.ts.map +1 -1
- package/dist/components/display/skeleton.d.ts.map +1 -1
- package/dist/components/display/step.d.ts.map +1 -1
- package/dist/components/display/tabs.d.ts.map +1 -1
- package/dist/components/floating/command-palette.d.ts +1 -0
- package/dist/components/floating/command-palette.d.ts.map +1 -1
- package/dist/components/floating/dropdown.d.ts +1 -0
- package/dist/components/floating/dropdown.d.ts.map +1 -1
- package/dist/components/floating/menu.d.ts +2 -2
- package/dist/components/floating/menu.d.ts.map +1 -1
- package/dist/components/floating/modal.d.ts +20 -53
- package/dist/components/floating/modal.d.ts.map +1 -1
- package/dist/components/floating/tooltip.d.ts.map +1 -1
- package/dist/components/floating/wizard.d.ts +1 -1
- package/dist/components/floating/wizard.d.ts.map +1 -1
- package/dist/components/form/autocomplete.d.ts.map +1 -1
- package/dist/components/form/date-picker.d.ts.map +1 -1
- package/dist/components/form/free-text.d.ts.map +1 -1
- package/dist/components/form/input-field.d.ts +3 -2
- package/dist/components/form/input-field.d.ts.map +1 -1
- package/dist/components/form/multi-select.d.ts.map +1 -1
- package/dist/components/form/select.d.ts.map +1 -1
- package/dist/components/form/slider.d.ts.map +1 -1
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/page-calendar/calendar-header.d.ts +16 -0
- package/dist/components/page-calendar/calendar-header.d.ts.map +1 -0
- package/dist/components/page-calendar/day-view.d.ts +12 -0
- package/dist/components/page-calendar/day-view.d.ts.map +1 -0
- package/dist/components/page-calendar/event-pill.d.ts +9 -0
- package/dist/components/page-calendar/event-pill.d.ts.map +1 -0
- package/dist/components/page-calendar/index.d.ts +4 -0
- package/dist/components/page-calendar/index.d.ts.map +1 -0
- package/dist/components/page-calendar/month-view.d.ts +11 -0
- package/dist/components/page-calendar/month-view.d.ts.map +1 -0
- package/dist/components/page-calendar/page-calendar.d.ts +18 -0
- package/dist/components/page-calendar/page-calendar.d.ts.map +1 -0
- package/dist/components/page-calendar/page-calendar.types.d.ts +18 -0
- package/dist/components/page-calendar/page-calendar.types.d.ts.map +1 -0
- package/dist/components/page-calendar/page-calendar.utils.d.ts +18 -0
- package/dist/components/page-calendar/page-calendar.utils.d.ts.map +1 -0
- package/dist/components/page-calendar/week-view.d.ts +11 -0
- package/dist/components/page-calendar/week-view.d.ts.map +1 -0
- package/dist/components/table/index.d.ts.map +1 -1
- package/dist/components/table/inner-table.d.ts.map +1 -1
- package/dist/components/table/metadata.d.ts.map +1 -1
- package/dist/components/table/row.d.ts.map +1 -1
- package/dist/components/table/table-lib.d.ts.map +1 -1
- package/dist/components/table/thead.d.ts.map +1 -1
- package/dist/config/context.d.ts.map +1 -1
- package/dist/config/default-translations.d.ts +21 -4
- package/dist/config/default-translations.d.ts.map +1 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/hooks/use-components-provider.d.ts.map +1 -1
- package/dist/hooks/use-form.d.ts +11 -11
- package/dist/hooks/use-form.d.ts.map +1 -1
- package/dist/hooks/use-input-id.d.ts.map +1 -1
- package/dist/hooks/use-preferences.d.ts.map +1 -1
- package/dist/hooks/use-previous.d.ts.map +1 -1
- package/dist/hooks/use-reactive.d.ts.map +1 -1
- package/dist/hooks/use-resize-observer.d.ts.map +1 -1
- package/dist/hooks/use-stable-ref.d.ts.map +1 -1
- package/dist/hooks/use-swipe.d.ts.map +1 -1
- package/dist/hooks/use-translations.d.ts +21 -4
- package/dist/hooks/use-translations.d.ts.map +1 -1
- package/dist/index.css +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +28 -20
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +13862 -12512
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +24 -17
- package/dist/index.umd.js.map +1 -1
- package/dist/lib/dom.d.ts +1 -0
- package/dist/lib/dom.d.ts.map +1 -1
- package/dist/lib/fns.d.ts.map +1 -1
- package/dist/preset/plugin.tailwind.d.ts +9 -0
- package/dist/preset/plugin.tailwind.d.ts.map +1 -0
- package/dist/preset/plugin.tailwind.js +27 -0
- package/dist/preset/preset.tailwind.d.ts +8 -0
- package/dist/preset/preset.tailwind.d.ts.map +1 -0
- package/dist/preset/preset.tailwind.js +54 -0
- package/dist/preset/src/styles/common.d.ts +2 -14
- package/dist/preset/src/styles/common.d.ts.map +1 -1
- package/dist/preset/src/styles/common.js +1 -0
- package/dist/preset/src/styles/dark.d.ts.map +1 -1
- package/dist/preset/src/styles/dark.js +119 -114
- package/dist/preset/src/styles/light.d.ts.map +1 -1
- package/dist/preset/src/styles/light.js +111 -106
- package/dist/preset/src/styles/theme.types.d.ts +17 -8
- package/dist/preset/src/styles/theme.types.d.ts.map +1 -1
- package/dist/styles/common.d.ts +2 -14
- package/dist/styles/common.d.ts.map +1 -1
- package/dist/styles/dark.d.ts.map +1 -1
- package/dist/styles/light.d.ts.map +1 -1
- package/dist/styles/theme.types.d.ts +17 -8
- package/dist/styles/theme.types.d.ts.map +1 -1
- package/package.json +299 -301
- package/dist/components/core/button.jsx +0 -86
- package/dist/components/core/heading.jsx +0 -4
- package/dist/components/core/polymorph.jsx +0 -5
- package/dist/components/core/render-on-view.jsx +0 -31
- package/dist/components/core/resizable.jsx +0 -51
- package/dist/components/core/slot.jsx +0 -163
- package/dist/components/core/tag.jsx +0 -51
- package/dist/components/core/typography.jsx +0 -26
- package/dist/components/display/alert.jsx +0 -56
- package/dist/components/display/calendar.jsx +0 -301
- package/dist/components/display/card.jsx +0 -43
- package/dist/components/display/empty.jsx +0 -11
- package/dist/components/display/list.jsx +0 -81
- package/dist/components/display/notifications.jsx +0 -98
- package/dist/components/display/progress.jsx +0 -13
- package/dist/components/display/shortcut.jsx +0 -23
- package/dist/components/display/skeleton.jsx +0 -14
- package/dist/components/display/spinner.jsx +0 -7
- package/dist/components/display/stats.jsx +0 -20
- package/dist/components/display/step.jsx +0 -131
- package/dist/components/display/tabs.jsx +0 -100
- package/dist/components/display/timeline.jsx +0 -25
- package/dist/components/floating/command-palette.jsx +0 -172
- package/dist/components/floating/dropdown.jsx +0 -53
- package/dist/components/floating/expand.jsx +0 -44
- package/dist/components/floating/menu.jsx +0 -147
- package/dist/components/floating/modal.jsx +0 -241
- package/dist/components/floating/toolbar.jsx +0 -5
- package/dist/components/floating/tooltip.jsx +0 -64
- package/dist/components/floating/wizard.jsx +0 -164
- package/dist/components/form/autocomplete.jsx +0 -275
- package/dist/components/form/checkbox.jsx +0 -12
- package/dist/components/form/date-picker.jsx +0 -115
- package/dist/components/form/file-upload.jsx +0 -133
- package/dist/components/form/form.jsx +0 -10
- package/dist/components/form/formReset.jsx +0 -17
- package/dist/components/form/free-text.jsx +0 -41
- package/dist/components/form/input-field.jsx +0 -54
- package/dist/components/form/input.jsx +0 -36
- package/dist/components/form/multi-select.jsx +0 -328
- package/dist/components/form/radiobox.jsx +0 -6
- package/dist/components/form/select.jsx +0 -42
- package/dist/components/form/slider.jsx +0 -45
- package/dist/components/form/switch.jsx +0 -46
- package/dist/components/form/task-list.jsx +0 -26
- package/dist/components/form/textarea.jsx +0 -12
- package/dist/components/form/transfer-list.jsx +0 -39
- package/dist/components/index.js +0 -43
- package/dist/components/table/filter.jsx +0 -141
- package/dist/components/table/group.jsx +0 -68
- package/dist/components/table/index.jsx +0 -60
- package/dist/components/table/inner-table.jsx +0 -104
- package/dist/components/table/metadata.jsx +0 -37
- package/dist/components/table/pagination.jsx +0 -73
- package/dist/components/table/row.jsx +0 -58
- package/dist/components/table/sort.jsx +0 -105
- package/dist/components/table/table-lib.js +0 -84
- package/dist/components/table/table.context.jsx +0 -4
- package/dist/components/table/thead.jsx +0 -103
- package/dist/config/context.js +0 -12
- package/dist/config/default-translations.jsx +0 -66
- package/dist/config/default-tweaks.js +0 -4
- package/dist/constants.js +0 -2
- package/dist/hooks/use-click-outside.js +0 -17
- package/dist/hooks/use-color-parser.js +0 -9
- package/dist/hooks/use-components-provider.jsx +0 -16
- package/dist/hooks/use-debounce.js +0 -12
- package/dist/hooks/use-floating-ref.js +0 -6
- package/dist/hooks/use-form.js +0 -549
- package/dist/hooks/use-hover.js +0 -18
- package/dist/hooks/use-input-id.js +0 -5
- package/dist/hooks/use-is-coarse-device.js +0 -12
- package/dist/hooks/use-locale.js +0 -10
- package/dist/hooks/use-media-query.js +0 -25
- package/dist/hooks/use-on-event.js +0 -7
- package/dist/hooks/use-parent.js +0 -21
- package/dist/hooks/use-preferences.js +0 -23
- package/dist/hooks/use-previous.js +0 -8
- package/dist/hooks/use-reactive.js +0 -8
- package/dist/hooks/use-remove-scroll.js +0 -61
- package/dist/hooks/use-resize-observer.js +0 -17
- package/dist/hooks/use-stable-ref.js +0 -8
- package/dist/hooks/use-swipe.js +0 -16
- package/dist/hooks/use-translations.js +0 -9
- package/dist/hooks/use-tweaks.js +0 -9
- package/dist/hooks/use-window-size.js +0 -14
- package/dist/lib/combi-keys.js +0 -60
- package/dist/lib/dict.js +0 -39
- package/dist/lib/dom.js +0 -44
- package/dist/lib/fns.js +0 -46
- package/dist/lib/fzf.js +0 -117
- package/dist/lib/keyboard-area.js +0 -14
- package/dist/preset/tailwindcssv4.d.ts +0 -3
- package/dist/preset/tailwindcssv4.d.ts.map +0 -1
- package/dist/preset/tailwindcssv4.js +0 -75
- package/dist/styles/common.js +0 -28
- package/dist/styles/dark.js +0 -209
- package/dist/styles/design-tokens.js +0 -69
- package/dist/styles/light.js +0 -209
- package/dist/styles/theme.js +0 -4
- package/dist/styles/theme.types.js +0 -1
- package/dist/types.js +0 -1
package/dist/components/index.js
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
export * from "./core/tag";
|
|
2
|
-
export * from "./form/form";
|
|
3
|
-
export * from "./form/input";
|
|
4
|
-
export * from "./core/button";
|
|
5
|
-
export * from "./form/select";
|
|
6
|
-
export * from "./form/slider";
|
|
7
|
-
export * from "./form/switch";
|
|
8
|
-
export * from "./table/index";
|
|
9
|
-
export * from "./display/card";
|
|
10
|
-
export * from "./display/list";
|
|
11
|
-
export * from "./display/step";
|
|
12
|
-
export * from "./display/tabs";
|
|
13
|
-
export * from "./display/alert";
|
|
14
|
-
export * from "./display/empty";
|
|
15
|
-
export * from "./display/stats";
|
|
16
|
-
export * from "./floating/menu";
|
|
17
|
-
export * from "./form/checkbox";
|
|
18
|
-
export * from "./form/radiobox";
|
|
19
|
-
export * from "./form/textarea";
|
|
20
|
-
export * from "./core/polymorph";
|
|
21
|
-
export * from "./floating/modal";
|
|
22
|
-
export * from "./form/task-list";
|
|
23
|
-
export * from "./core/typography";
|
|
24
|
-
export * from "./display/spinner";
|
|
25
|
-
export * from "./floating/expand";
|
|
26
|
-
export * from "./floating/wizard";
|
|
27
|
-
export * from "./display/calendar";
|
|
28
|
-
export * from "./display/progress";
|
|
29
|
-
export * from "./display/timeline";
|
|
30
|
-
export * from "./floating/toolbar";
|
|
31
|
-
export * from "./floating/tooltip";
|
|
32
|
-
export * from "./form/date-picker";
|
|
33
|
-
export * from "./form/file-upload";
|
|
34
|
-
export * from "./form/input-field";
|
|
35
|
-
export * from "./floating/dropdown";
|
|
36
|
-
export * from "./form/autocomplete";
|
|
37
|
-
export * from "./form/multi-select";
|
|
38
|
-
export * from "./form/transfer-list";
|
|
39
|
-
export * from "./core/render-on-view";
|
|
40
|
-
export * from "./display/notifications";
|
|
41
|
-
export * from "./floating/command-palette";
|
|
42
|
-
export { formReset } from "./form/formReset";
|
|
43
|
-
export { createColumns, createOptionCols, useTablePreferences } from "./table/table-lib";
|
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
import { ListFilterIcon, PlusIcon, Trash2Icon } from "lucide-react";
|
|
2
|
-
import React, { Fragment, useMemo } from "react";
|
|
3
|
-
import { useTranslations } from "../../hooks/use-translations";
|
|
4
|
-
import { uuid } from "../../lib/fns";
|
|
5
|
-
import { Dropdown } from "../floating/dropdown";
|
|
6
|
-
import { Input } from "../form/input";
|
|
7
|
-
import { Select } from "../form/select";
|
|
8
|
-
import { ColType, getLabel, valueFromType } from "./table-lib";
|
|
9
|
-
export const createFilterFromCol = (f, options, operations, rest = {}) => {
|
|
10
|
-
const name = f.id;
|
|
11
|
-
const type = f.type ?? ColType.Text;
|
|
12
|
-
const typeOptions = options[type] ?? [];
|
|
13
|
-
const operatorId = (typeOptions.find((x) => x["data-default"])?.value ?? typeOptions[0]?.value);
|
|
14
|
-
const operation = operations[operatorId];
|
|
15
|
-
return { id: uuid(), operation, label: getLabel(f), name, type, value: "", ...rest };
|
|
16
|
-
};
|
|
17
|
-
export const useOperators = () => {
|
|
18
|
-
const translation = useTranslations();
|
|
19
|
-
const operations = useMemo(() => ({
|
|
20
|
-
contains: {
|
|
21
|
-
value: "contains",
|
|
22
|
-
label: translation.tableFilterTypeContains,
|
|
23
|
-
symbol: "includes",
|
|
24
|
-
"data-default": "true",
|
|
25
|
-
},
|
|
26
|
-
is: { value: "is", label: translation.tableFilterTypeIs, symbol: "is" },
|
|
27
|
-
isNot: { value: "isNot", label: translation.tableFilterTypeIsNot, symbol: "!==" },
|
|
28
|
-
notContains: {
|
|
29
|
-
value: "notContains",
|
|
30
|
-
label: translation.tableFilterTypeNotContains,
|
|
31
|
-
symbol: "notIncludes",
|
|
32
|
-
},
|
|
33
|
-
lessThan: { value: "lessThan", label: translation.tableFilterTypeLessThan, symbol: "<=" },
|
|
34
|
-
greaterThan: { value: "greaterThan", label: translation.tableFilterTypeGreaterThan, symbol: ">=" },
|
|
35
|
-
startsWith: { value: "startsWith", label: translation.tableFilterTypeStartsWith, symbol: "startsWith" },
|
|
36
|
-
endsWith: { value: "endsWith", label: translation.tableFilterTypeEndsWith, symbol: "endsWith" },
|
|
37
|
-
}), [translation]);
|
|
38
|
-
const options = useMemo(() => ({
|
|
39
|
-
[ColType.Text]: [
|
|
40
|
-
operations.is,
|
|
41
|
-
operations.isNot,
|
|
42
|
-
operations.contains,
|
|
43
|
-
operations.notContains,
|
|
44
|
-
operations.startsWith,
|
|
45
|
-
operations.endsWith,
|
|
46
|
-
],
|
|
47
|
-
[ColType.Boolean]: [operations.is, operations.isNot],
|
|
48
|
-
[ColType.Number]: [operations.is, operations.isNot, operations.greaterThan, operations.lessThan],
|
|
49
|
-
}), [operations]);
|
|
50
|
-
return { options, operations };
|
|
51
|
-
};
|
|
52
|
-
export const Filter = (props) => {
|
|
53
|
-
const translation = useTranslations();
|
|
54
|
-
const operators = useOperators();
|
|
55
|
-
const onAddFilter = () => {
|
|
56
|
-
const col = props.cols.at(0);
|
|
57
|
-
props.set((prev) => [...prev, createFilterFromCol(col, operators.options, operators.operations)]);
|
|
58
|
-
};
|
|
59
|
-
const onSelectProperty = (e) => {
|
|
60
|
-
const changedId = e.target.dataset.id || "";
|
|
61
|
-
const newId = e.target.value;
|
|
62
|
-
props.set((prev) => prev.map((x) => {
|
|
63
|
-
if (changedId !== x.id)
|
|
64
|
-
return x;
|
|
65
|
-
const col = props.cols.find((x) => newId === x.id);
|
|
66
|
-
return createFilterFromCol(col, operators.options, operators.operations, { value: "" });
|
|
67
|
-
}));
|
|
68
|
-
};
|
|
69
|
-
const onSelectOperation = (e) => {
|
|
70
|
-
const id = e.target.dataset.id || "";
|
|
71
|
-
const operator = e.target.value;
|
|
72
|
-
props.set((prev) => prev.map((x) => x.id === id
|
|
73
|
-
? {
|
|
74
|
-
...x,
|
|
75
|
-
operation: operators.operations[operator],
|
|
76
|
-
}
|
|
77
|
-
: x));
|
|
78
|
-
};
|
|
79
|
-
const onDelete = (e) => {
|
|
80
|
-
const id = e.currentTarget.dataset.id || "";
|
|
81
|
-
props.set((prev) => prev.filter((x) => x.id !== id));
|
|
82
|
-
};
|
|
83
|
-
const onChangeValue = (e) => {
|
|
84
|
-
const id = e.target.dataset.id || "";
|
|
85
|
-
const value = valueFromType(e.target);
|
|
86
|
-
props.set((prev) => prev.map((x) => (x.id === id ? { ...x, value } : x)));
|
|
87
|
-
};
|
|
88
|
-
return (<Fragment>
|
|
89
|
-
<Dropdown arrow title={translation.tableFilterDropdownTitle} trigger={<span className="flex gap-1 items-center proportional-nums">
|
|
90
|
-
<ListFilterIcon size={14}/>
|
|
91
|
-
{translation.tableFilterLabel} {props.filters.length === 0 ? "" : ` (${props.filters.length})`}
|
|
92
|
-
</span>}>
|
|
93
|
-
<ul className="mt-4 space-y-2">
|
|
94
|
-
{props.filters.map((filter) => {
|
|
95
|
-
const options = operators.options[filter.type];
|
|
96
|
-
return (<li key={`filter-select-${filter.id}`} className="flex flex-nowrap gap-3">
|
|
97
|
-
<Select options={props.options} title={translation.tableFilterColumnTitle} placeholder={translation.tableFilterColumnPlaceholder} value={filter.name} data-id={filter.id} onChange={onSelectProperty}/>
|
|
98
|
-
<Select data-id={filter.id} onChange={onSelectOperation} value={filter.operation.value} options={options} title={translation.tableFilterOperatorTitle} placeholder={translation.tableFilterOperatorPlaceholder}/>
|
|
99
|
-
<Input optionalText="" data-id={filter.id} onChange={onChangeValue} value={filter.value} type={filter.type} title={translation.tableFilterValueTitle} placeholder={translation.tableFilterValuePlaceholder}/>
|
|
100
|
-
<div className="flex justify-center items-center mt-5">
|
|
101
|
-
<button data-id={filter.id} type="button" onClick={onDelete}>
|
|
102
|
-
<Trash2Icon className="text-danger" size={16}/>
|
|
103
|
-
</button>
|
|
104
|
-
</div>
|
|
105
|
-
</li>);
|
|
106
|
-
})}
|
|
107
|
-
<li>
|
|
108
|
-
<button type="button" onClick={onAddFilter} className="flex gap-1 items-center text-primary">
|
|
109
|
-
<PlusIcon size={14}/> {translation.tableFilterNewFilter}
|
|
110
|
-
</button>
|
|
111
|
-
</li>
|
|
112
|
-
</ul>
|
|
113
|
-
</Dropdown>
|
|
114
|
-
</Fragment>);
|
|
115
|
-
};
|
|
116
|
-
export const ColumnHeaderFilter = ({ filter, onDelete, set }) => {
|
|
117
|
-
const translation = useTranslations();
|
|
118
|
-
const operators = useOperators();
|
|
119
|
-
const onSelectOperation = (e) => {
|
|
120
|
-
const operator = e.target.value;
|
|
121
|
-
const id = e.target.dataset.id || "";
|
|
122
|
-
set((prev) => prev.map((x) => x.id === id
|
|
123
|
-
? {
|
|
124
|
-
...x,
|
|
125
|
-
operation: operators.operations[operator],
|
|
126
|
-
}
|
|
127
|
-
: x));
|
|
128
|
-
};
|
|
129
|
-
const onChangeValue = (e) => {
|
|
130
|
-
const id = e.target.dataset.id || "";
|
|
131
|
-
const value = valueFromType(e.target);
|
|
132
|
-
set((prev) => prev.map((x) => (x.id === id ? { ...x, value } : x)));
|
|
133
|
-
};
|
|
134
|
-
return (<div className="flex flex-nowrap gap-4 items-center py-2">
|
|
135
|
-
<Select data-id={filter.id} onChange={onSelectOperation} value={filter.operation.value} options={operators.options[filter.type]} title={translation.tableFilterColumnTitle} placeholder={translation.tableFilterColumnPlaceholder}/>
|
|
136
|
-
<Input optionalText=" " data-id={filter.id} onChange={onChangeValue} value={filter.value} type={filter.type} title={translation.tableFilterValueTitle} placeholder={translation.tableFilterValueTitle}/>
|
|
137
|
-
<button onClick={onDelete} data-id={filter.id} type="button" className="mt-4">
|
|
138
|
-
<Trash2Icon className="text-danger" size={14}/>
|
|
139
|
-
</button>
|
|
140
|
-
</div>);
|
|
141
|
-
};
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { LayoutGroup, Reorder, useDragControls, useMotionValue } from "motion/react";
|
|
3
|
-
import Linq from "linq-arrays";
|
|
4
|
-
import { GripVerticalIcon, Trash2Icon, UngroupIcon } from "lucide-react";
|
|
5
|
-
import React, { Fragment, useState } from "react";
|
|
6
|
-
import { keys } from "sidekicker";
|
|
7
|
-
import { useTranslations } from "../../hooks/use-translations";
|
|
8
|
-
import { uuid } from "../../lib/fns";
|
|
9
|
-
import { Button } from "../core/button";
|
|
10
|
-
import { Dropdown } from "../floating/dropdown";
|
|
11
|
-
import { Select } from "../form/select";
|
|
12
|
-
import { createOptionCols } from "./table-lib";
|
|
13
|
-
const Item = ({ item, onPointerDown }) => {
|
|
14
|
-
const y = useMotionValue(0);
|
|
15
|
-
return (<Reorder.Item onPointerDown={onPointerDown} id={item.groupId} className="flex flex-row items-center gap-2" key={item.groupId} value={item} style={{ y }}>
|
|
16
|
-
<button type="button" className="cursor-grab">
|
|
17
|
-
<GripVerticalIcon size={14}/>
|
|
18
|
-
</button>
|
|
19
|
-
<span>{item.groupName}</span>
|
|
20
|
-
</Reorder.Item>);
|
|
21
|
-
};
|
|
22
|
-
export const Group = (props) => {
|
|
23
|
-
const translations = useTranslations();
|
|
24
|
-
const options = createOptionCols(props.cols);
|
|
25
|
-
const controls = useDragControls();
|
|
26
|
-
const [group, setGroup] = useState(props.groups[0]?.thead || "");
|
|
27
|
-
const onChange = (e) => {
|
|
28
|
-
const select = e.target;
|
|
29
|
-
const key = select.value;
|
|
30
|
-
const index = select.options.selectedIndex;
|
|
31
|
-
const label = select.options.item(index)?.label || "";
|
|
32
|
-
setGroup(label);
|
|
33
|
-
const groupBy = new Linq(props.rows).GroupBy(key);
|
|
34
|
-
const col = props.cols.find((x) => x.id === key);
|
|
35
|
-
props.setGroups(keys(groupBy).map((groupName, index) => {
|
|
36
|
-
const rows = groupBy[groupName];
|
|
37
|
-
return { ...col, groupId: uuid(), groupKey: key, index, rows, groupName: groupName };
|
|
38
|
-
}));
|
|
39
|
-
};
|
|
40
|
-
const onDelete = () => props.setGroups([]);
|
|
41
|
-
return (<Fragment>
|
|
42
|
-
<Dropdown arrow={false} title={translations.tableGroupLabel} trigger={<span className="flex items-center gap-1 proportional-nums">
|
|
43
|
-
<UngroupIcon size={14}/>
|
|
44
|
-
{translations.tableGroupLabelWithCount}
|
|
45
|
-
{props.groups.length > 0 ? ` - ${group}(${props.groups.length})` : ""}
|
|
46
|
-
</span>}>
|
|
47
|
-
<div className="flex flex-nowrap items-center">
|
|
48
|
-
<Select value={group} title="Tipo de agrupamento" onChange={onChange} options={options} placeholder="Agrupar por..."/>
|
|
49
|
-
<Button className="mt-4" onClick={onDelete} theme="raw" data-id={group}>
|
|
50
|
-
<Trash2Icon size={16} className="text-danger"/>
|
|
51
|
-
</Button>
|
|
52
|
-
</div>
|
|
53
|
-
{props.groups.length > 0 ? (<section className="my-4">
|
|
54
|
-
<header>
|
|
55
|
-
<h2 className="text-xl font-medium">Order groups</h2>
|
|
56
|
-
</header>
|
|
57
|
-
<LayoutGroup>
|
|
58
|
-
<Reorder.Group axis="y" className="relative space-y-2" drag dragControls={controls} dragListener={false} layoutScroll onReorder={props.setGroups} values={props.groups}>
|
|
59
|
-
{props.groups.map((item) => (<Item key={item.groupId} item={item} onPointerDown={(e) => {
|
|
60
|
-
controls.start(e);
|
|
61
|
-
props.setGroups([...props.groups]);
|
|
62
|
-
}}/>))}
|
|
63
|
-
</Reorder.Group>
|
|
64
|
-
</LayoutGroup>
|
|
65
|
-
</section>) : null}
|
|
66
|
-
</Dropdown>
|
|
67
|
-
</Fragment>);
|
|
68
|
-
};
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { AnimatePresence } from "motion/react";
|
|
3
|
-
import { useEffect, useMemo } from "react";
|
|
4
|
-
import { useReducer } from "use-typed-reducer";
|
|
5
|
-
import { useTweaks } from "../../hooks/use-tweaks";
|
|
6
|
-
import { InnerTable } from "./inner-table";
|
|
7
|
-
import { Metadata } from "./metadata";
|
|
8
|
-
import { createOptionCols } from "./table-lib";
|
|
9
|
-
import { TableProvider } from "./table.context";
|
|
10
|
-
const dispatcherFun = (prev, setter) => typeof setter === "function" ? setter(prev) : setter;
|
|
11
|
-
const compareAndExec = (prev, state, exec) => (prev === state ? undefined : exec?.(state));
|
|
12
|
-
export const Table = (props) => {
|
|
13
|
-
const tweaks = useTweaks();
|
|
14
|
-
const contextState = useMemo(() => ({
|
|
15
|
-
sticky: props.sticky === undefined ? tweaks.table.sticky ?? undefined : props.sticky ?? undefined
|
|
16
|
-
}), [props.sticky, tweaks.table.sticky]);
|
|
17
|
-
const operations = props.operations ?? tweaks.table.operations ?? true;
|
|
18
|
-
const optionCols = useMemo(() => createOptionCols(props.cols), [props.cols]);
|
|
19
|
-
const [state, dispatch] = useReducer({
|
|
20
|
-
cols: props.cols,
|
|
21
|
-
sorters: (props.sorters ?? []),
|
|
22
|
-
groups: (props.groups ?? []),
|
|
23
|
-
filters: (props.filters ?? []),
|
|
24
|
-
}, (get) => {
|
|
25
|
-
const create = (key) => (arg) => {
|
|
26
|
-
const state = get.state();
|
|
27
|
-
return { ...state, [key]: dispatcherFun(state[key], arg) };
|
|
28
|
-
};
|
|
29
|
-
return {
|
|
30
|
-
cols: create("cols"),
|
|
31
|
-
sorters: create("sorters"),
|
|
32
|
-
groups: create("groups"),
|
|
33
|
-
filters: create("filters"),
|
|
34
|
-
};
|
|
35
|
-
}, {
|
|
36
|
-
postMiddleware: [
|
|
37
|
-
(state, prev) => {
|
|
38
|
-
props.set?.(state);
|
|
39
|
-
compareAndExec(prev?.filters ?? [], state.filters ?? [], props.setFilters);
|
|
40
|
-
compareAndExec(prev?.sorters ?? [], state.sorters ?? [], props.setSorters);
|
|
41
|
-
compareAndExec(prev?.groups ?? [], state.groups ?? [], props.setGroups);
|
|
42
|
-
compareAndExec(prev?.cols ?? [], state.cols ?? [], props.setCols);
|
|
43
|
-
return state;
|
|
44
|
-
},
|
|
45
|
-
],
|
|
46
|
-
});
|
|
47
|
-
useEffect(() => {
|
|
48
|
-
dispatch.cols(props.cols);
|
|
49
|
-
}, [props.cols]);
|
|
50
|
-
return (<TableProvider value={contextState}>
|
|
51
|
-
<AnimatePresence initial={false}>
|
|
52
|
-
{operations ? (<Metadata cols={state.cols} rows={props.rows} options={optionCols} groups={state.groups} filters={state.filters} setCols={dispatch.cols} sorters={state.sorters} setGroups={dispatch.groups} setFilters={dispatch.filters} setSorters={dispatch.sorters} pagination={props.pagination ?? null} inlineFilter={props.inlineFilter ?? true} inlineSorter={props.inlineSorter ?? true}/>) : null}
|
|
53
|
-
{state.groups.length === 0 ? (<InnerTable {...props} index={0} cols={state.cols} options={optionCols} groups={state.groups} filters={state.filters} optionCols={optionCols} setCols={dispatch.cols} sorters={state.sorters} setGroups={dispatch.groups} setFilters={dispatch.filters} setSorters={dispatch.sorters} onScrollEnd={props.onScrollEnd} pagination={props.pagination ?? null} inlineFilter={props.inlineFilter ?? true} inlineSorter={props.inlineSorter ?? true}/>) : (<div className="flex flex-wrap gap-4">
|
|
54
|
-
{state.groups.map((group, index) => (<div className="min-w-full" key={`group-${group.groupId}`}>
|
|
55
|
-
<InnerTable {...props} group={group} index={index} cols={state.cols} pagination={null} rows={group.rows} options={optionCols} groups={state.groups} filters={state.filters} optionCols={optionCols} setCols={dispatch.cols} sorters={state.sorters} setGroups={dispatch.groups} setFilters={dispatch.filters} setSorters={dispatch.sorters} onScrollEnd={props.onScrollEnd} inlineFilter={props.inlineFilter ?? true} inlineSorter={props.inlineSorter ?? true}/>
|
|
56
|
-
</div>))}
|
|
57
|
-
</div>)}
|
|
58
|
-
</AnimatePresence>
|
|
59
|
-
</TableProvider>);
|
|
60
|
-
};
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
import Linq from "linq-arrays";
|
|
2
|
-
import { AnimatePresence } from "motion/react";
|
|
3
|
-
import React, { Fragment, useEffect, useMemo, useRef, useState } from "react";
|
|
4
|
-
import { TableVirtuoso } from "react-virtuoso";
|
|
5
|
-
import { Is } from "sidekicker";
|
|
6
|
-
import { useStableRef } from "../../hooks/use-stable-ref";
|
|
7
|
-
import { Empty } from "../display/empty";
|
|
8
|
-
import { SkeletonCell } from "../display/skeleton";
|
|
9
|
-
import { Pagination } from "./pagination";
|
|
10
|
-
import { Row } from "./row";
|
|
11
|
-
import { multiSort } from "./sort";
|
|
12
|
-
import { useTable } from "./table.context";
|
|
13
|
-
import { TableHeader } from "./thead";
|
|
14
|
-
const TableBody = React.forwardRef(({ context, className = "", ...props }, ref) => {
|
|
15
|
-
return (<tbody {...props} role="rowgroup" className={`divide-y divide-table-border ${className}`} ref={ref}>
|
|
16
|
-
<AnimatePresence>{props.children}</AnimatePresence>
|
|
17
|
-
</tbody>);
|
|
18
|
-
});
|
|
19
|
-
const VirtualTable = React.forwardRef(({ context, className = "", ...props }, ref) => (<table {...props} role="table" ref={ref} style={{ ...props.style, "--table-cell-padding": "0.75rem" }} className={`table w-full table-fixed border-spacing-0 border-separate text-left ${className ?? ""}`}/>));
|
|
20
|
-
const Thead = React.forwardRef(({ context, ...props }, ref) => {
|
|
21
|
-
const ctx = useTable();
|
|
22
|
-
const style = {
|
|
23
|
-
...props?.style,
|
|
24
|
-
top: Is.number(ctx.sticky) ? `${ctx.sticky}px` : undefined,
|
|
25
|
-
};
|
|
26
|
-
return (<thead {...props} ref={ref} style={style} role="rowgroup" className="hidden top-0 bg-transparent md:table-header-group group:sticky"/>);
|
|
27
|
-
});
|
|
28
|
-
const TRow = React.forwardRef(({ context, item, ...props }, ref) => {
|
|
29
|
-
const contextProps = context?.getRowProps?.(item);
|
|
30
|
-
const innerProps = { ...props, ...contextProps };
|
|
31
|
-
return (<tr {...innerProps} role="row" ref={ref} className={`group-table-row pb-4 flex h-fit flex-col flex-wrap justify-center gap-1 md:table-row ${props?.className ?? ""}`}/>);
|
|
32
|
-
});
|
|
33
|
-
const TFoot = React.forwardRef((props, ref) => {
|
|
34
|
-
if (props.context.loadingMore) {
|
|
35
|
-
return (<tfoot {...props} ref={ref} className="bg-card-background">
|
|
36
|
-
<tr role="row" className="bg-card-background">
|
|
37
|
-
<td colSpan={999} className="px-2 h-14 bg-card-background">
|
|
38
|
-
<span className="block w-full h-2 rounded-sm opacity-60 animate-pulse bg-foreground"/>
|
|
39
|
-
</td>
|
|
40
|
-
</tr>
|
|
41
|
-
</tfoot>);
|
|
42
|
-
}
|
|
43
|
-
return null;
|
|
44
|
-
});
|
|
45
|
-
const components = {
|
|
46
|
-
TableRow: TRow,
|
|
47
|
-
TableFoot: TFoot,
|
|
48
|
-
TableHead: Thead,
|
|
49
|
-
Table: VirtualTable,
|
|
50
|
-
TableBody: TableBody,
|
|
51
|
-
};
|
|
52
|
-
const loadingArray = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
|
53
|
-
const EmptyContent = (props) => (<div className="flex justify-center items-center px-2 w-full h-48">{props.loading ? SkeletonCell : <Empty />}</div>);
|
|
54
|
-
const EmptyCell = () => <Fragment />;
|
|
55
|
-
const emptyRows = [];
|
|
56
|
-
export const InnerTable = ({ cols, filters, setCols, sorters, setFilters, setSorters, onScrollEnd, getScrollRef, pagination = null, useControl = false, ...props }) => {
|
|
57
|
-
const ref = useRef(null);
|
|
58
|
-
const [, setShowLoadingFooter] = useState(false);
|
|
59
|
-
const onScrollEndRef = useStableRef(onScrollEnd);
|
|
60
|
-
const loadingMoreRef = useStableRef(props.loadingMore);
|
|
61
|
-
const rows = useMemo(() => {
|
|
62
|
-
if (props.loading)
|
|
63
|
-
return loadingArray;
|
|
64
|
-
if (useControl)
|
|
65
|
-
return props.rows;
|
|
66
|
-
const linq = new Linq(props.rows);
|
|
67
|
-
if (filters.length > 0) {
|
|
68
|
-
filters.forEach((x) => x.value === "" || Number.isNaN(x.value) ? undefined : linq.Where(x.name, x.operation.symbol, x.value));
|
|
69
|
-
}
|
|
70
|
-
if (sorters.length === 0)
|
|
71
|
-
return linq.Select();
|
|
72
|
-
return multiSort(linq.Select(), sorters);
|
|
73
|
-
}, [props.loading, props.rows, useControl, filters, sorters]);
|
|
74
|
-
useEffect(() => {
|
|
75
|
-
if (ref.current === null)
|
|
76
|
-
return () => { };
|
|
77
|
-
const div = ref.current;
|
|
78
|
-
const observer = new IntersectionObserver((entries) => {
|
|
79
|
-
const endOfPage = entries[entries.length - 1];
|
|
80
|
-
const condition = endOfPage.isIntersecting && loadingMoreRef.current;
|
|
81
|
-
if (condition) {
|
|
82
|
-
onScrollEndRef.current?.();
|
|
83
|
-
return void setShowLoadingFooter(true);
|
|
84
|
-
}
|
|
85
|
-
return setShowLoadingFooter(false);
|
|
86
|
-
});
|
|
87
|
-
observer.observe(div);
|
|
88
|
-
return () => observer.disconnect();
|
|
89
|
-
}, [loadingMoreRef, onScrollEndRef]);
|
|
90
|
-
const empty = rows.length === 0;
|
|
91
|
-
const context = {
|
|
92
|
-
cols: cols,
|
|
93
|
-
Aside: props.Aside,
|
|
94
|
-
loading: props.loading,
|
|
95
|
-
getRowProps: props.getRowProps,
|
|
96
|
-
loadingMore: props.loadingMore,
|
|
97
|
-
};
|
|
98
|
-
return (<div className="flex relative flex-col w-full whitespace-nowrap rounded-lg group">
|
|
99
|
-
<TableVirtuoso components={components} context={context} totalCount={rows.length} itemContent={empty ? EmptyCell : Row} data={empty ? emptyRows : rows} useWindowScroll={getScrollRef ? false : true} customScrollParent={getScrollRef ? getScrollRef() : undefined} fixedHeaderContent={() => (<TableHeader headers={cols} filters={filters} setCols={setCols} sorters={sorters} setFilters={setFilters} setSorters={setSorters} loading={!!props.loading} inlineFilter={props.inlineFilter} inlineSorter={props.inlineSorter}/>)}/>
|
|
100
|
-
{empty ? <EmptyContent loading={props.loading}/> : null}
|
|
101
|
-
<div aria-hidden="true" ref={ref} className="w-full h-0.5"/>
|
|
102
|
-
{pagination !== null ? <Pagination {...pagination}/> : null}
|
|
103
|
-
</div>);
|
|
104
|
-
};
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { Filter } from "./filter";
|
|
2
|
-
import { Group } from "./group";
|
|
3
|
-
import { Sort } from "./sort";
|
|
4
|
-
import { valueFromType } from "./table-lib";
|
|
5
|
-
export const Metadata = (props) => (<header className="mb-1 min-w-full">
|
|
6
|
-
<div className="flex flex-wrap gap-y-1 gap-x-4 justify-between items-center min-w-full">
|
|
7
|
-
<div className="flex gap-4 py-2 whitespace-nowrap w-fit items-centeend">
|
|
8
|
-
<span>
|
|
9
|
-
<Filter cols={props.cols} options={props.options} filters={props.filters} set={props.setFilters}/>
|
|
10
|
-
</span>
|
|
11
|
-
<span>
|
|
12
|
-
<Sort options={props.options} cols={props.cols} sorters={props.sorters} set={props.setSorters}/>
|
|
13
|
-
</span>
|
|
14
|
-
<span>
|
|
15
|
-
<Group rows={props.rows} groups={props.groups} setGroups={props.setGroups} options={props.options} cols={props.cols}/>
|
|
16
|
-
</span>
|
|
17
|
-
</div>
|
|
18
|
-
<ul className="flex flex-row flex-wrap flex-1 grow gap-4 items-center w-full md:justify-end">
|
|
19
|
-
{props.filters.map((x) => (<li key={`filter-table-${x.id}`} className="flex gap-1 items-center py-0.5 px-4 rounded-xl border border-card-border">
|
|
20
|
-
<span>
|
|
21
|
-
<span className="inline-block mr-2 rounded-full size-3 aspect-square bg-primary" aria-hidden="true"/>
|
|
22
|
-
{x.label} {x.operation.label.toLowerCase()}:
|
|
23
|
-
</span>
|
|
24
|
-
<div className="relative w-min min-w-[1ch]">
|
|
25
|
-
<span aria-hidden="true" className="invisible p-0 whitespace-pre">
|
|
26
|
-
{x.value || " "}
|
|
27
|
-
</span>
|
|
28
|
-
<input type={x.type} value={x.value} className="absolute left-0 top-0 m-0 inline-block w-full bg-transparent p-0 placeholder-primary/70 outline-hidden [appearance:textfield] empty:after:text-primary/70 [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none" onChange={(e) => {
|
|
29
|
-
const value = valueFromType(e.target);
|
|
30
|
-
props.setFilters((prev) => prev.map((item) => x.id === item.id
|
|
31
|
-
? { ...item, value, } : item));
|
|
32
|
-
}}/>
|
|
33
|
-
</div>
|
|
34
|
-
</li>))}
|
|
35
|
-
</ul>
|
|
36
|
-
</div>
|
|
37
|
-
</header>);
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import { Fragment, useId, useMemo } from "react";
|
|
2
|
-
import { useTranslations } from "../../hooks/use-translations";
|
|
3
|
-
import { Polymorph } from "../core/polymorph";
|
|
4
|
-
function createPaginationItems(current, max) {
|
|
5
|
-
if (!current || !max)
|
|
6
|
-
return [];
|
|
7
|
-
const items = [1];
|
|
8
|
-
if (current === 1 && max === 1)
|
|
9
|
-
return items;
|
|
10
|
-
if (current > 4)
|
|
11
|
-
items.push("-");
|
|
12
|
-
const r = 2;
|
|
13
|
-
const r1 = current - r;
|
|
14
|
-
const r2 = current + r;
|
|
15
|
-
for (let i = r1 > 2 ? r1 : 2; i <= Math.min(max, r2); i++)
|
|
16
|
-
items.push(i);
|
|
17
|
-
const p2 = max - 2;
|
|
18
|
-
if (r2 + 1 !== p2) {
|
|
19
|
-
if (r2 + 1 < max)
|
|
20
|
-
items.push("_");
|
|
21
|
-
}
|
|
22
|
-
if (r2 < max) {
|
|
23
|
-
items.push(max - 2);
|
|
24
|
-
items.push(max - 1);
|
|
25
|
-
items.push(max);
|
|
26
|
-
}
|
|
27
|
-
return Array.from(new Set(items));
|
|
28
|
-
}
|
|
29
|
-
export const Pagination = (pagination) => {
|
|
30
|
-
const id = useId();
|
|
31
|
-
const translation = useTranslations();
|
|
32
|
-
const pageNavigation = useMemo(() => createPaginationItems(pagination.current, pagination.pages), [pagination.current, pagination.pages]);
|
|
33
|
-
const hasNext = pagination.current < pagination.pages;
|
|
34
|
-
return (<footer className="flex flex-wrap items-center justify-center gap-4 p-3 border-t-muted text-sm lg:flex-nowrap lg:justify-between">
|
|
35
|
-
<p>
|
|
36
|
-
<translation.tablePaginationFooter {...pagination} sizes={pagination.sizes} select={pagination.onChangeSize && Array.isArray(pagination.sizes) ? (<Fragment>
|
|
37
|
-
<label htmlFor={id}>{translation.tablePaginationSelectLabel}</label>
|
|
38
|
-
<select id={id} value={pagination.size} className="cursor-pointer bg-transparent" onChange={(e) => {
|
|
39
|
-
pagination.onChangeSize?.(Number(e.target.value));
|
|
40
|
-
}}>
|
|
41
|
-
{pagination.sizes.map((value) => (<option key={`pagination-opt-${value}`} value={value}>
|
|
42
|
-
{value}
|
|
43
|
-
</option>))}
|
|
44
|
-
</select>{" "}
|
|
45
|
-
</Fragment>) : null}/>
|
|
46
|
-
</p>
|
|
47
|
-
<nav>
|
|
48
|
-
<ul className="flex items-center gap-2">
|
|
49
|
-
{pagination.current > 1 ? (<li>
|
|
50
|
-
<Polymorph as={pagination.asLink || "button"} href="previous" className="">
|
|
51
|
-
{translation.tablePaginationPrevious}
|
|
52
|
-
</Polymorph>
|
|
53
|
-
</li>) : null}
|
|
54
|
-
{pageNavigation.map((x) => {
|
|
55
|
-
if (x === null)
|
|
56
|
-
return null;
|
|
57
|
-
return (<Fragment key={`pagination-${x}`}>
|
|
58
|
-
{typeof x === "string" ? (<li>...</li>) : (<li>
|
|
59
|
-
<Polymorph href={x} as={pagination.asLink || "button"} className={`cursor-pointer border-b-2 px-3 py-1 proportional-nums transition-colors hover:border-primary-subtle hover:text-primary-subtle ${x === pagination.current ? "border-primary text-primary" : "border-transparent"}`}>
|
|
60
|
-
{x}
|
|
61
|
-
</Polymorph>
|
|
62
|
-
</li>)}
|
|
63
|
-
</Fragment>);
|
|
64
|
-
})}
|
|
65
|
-
{hasNext ? (<li>
|
|
66
|
-
<Polymorph as={pagination.asLink || "button"} href="next" className="">
|
|
67
|
-
{translation.tablePaginationNext}
|
|
68
|
-
</Polymorph>
|
|
69
|
-
</li>) : null}
|
|
70
|
-
</ul>
|
|
71
|
-
</nav>
|
|
72
|
-
</footer>);
|
|
73
|
-
};
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import React, { Fragment, useEffect, useRef, useState } from "react";
|
|
2
|
-
import { Is } from "sidekicker";
|
|
3
|
-
import { path } from "../../lib/fns";
|
|
4
|
-
import { SkeletonCell } from "../display/skeleton";
|
|
5
|
-
const RowAside = (props) => {
|
|
6
|
-
const parentRef = useRef(null);
|
|
7
|
-
const ref = useRef(null);
|
|
8
|
-
const [className, setClassName] = useState("opacity-0");
|
|
9
|
-
const ariaHidden = className === "opacity-0";
|
|
10
|
-
const onLeave = () => setClassName("opacity-0");
|
|
11
|
-
const callback = () => {
|
|
12
|
-
const child = ref.current;
|
|
13
|
-
const parent = parentRef.current;
|
|
14
|
-
if (child === null || parent === null)
|
|
15
|
-
return;
|
|
16
|
-
parent.style.left = `-${child.getBoundingClientRect().width + 4}px`;
|
|
17
|
-
};
|
|
18
|
-
const onEnter = () => setClassName("opacity-100");
|
|
19
|
-
useEffect(() => {
|
|
20
|
-
const child = ref.current;
|
|
21
|
-
if (child === null || parent === null)
|
|
22
|
-
return;
|
|
23
|
-
callback();
|
|
24
|
-
const observer = new IntersectionObserver((entries) => entries.forEach(callback), { root: document.documentElement });
|
|
25
|
-
observer.observe(child);
|
|
26
|
-
return () => observer.disconnect();
|
|
27
|
-
}, []);
|
|
28
|
-
return (<div ref={parentRef} onMouseEnter={onEnter} onMouseLeave={onLeave} data-component="cell-aside" inert={ariaHidden ? true : undefined} tabIndex={ariaHidden ? -1 : undefined} className={`group-table-cell-aside absolute inset-0 top-0 flex h-full w-full items-stretch transition-opacity duration-300 ease-in-out ${className}`}>
|
|
29
|
-
<div ref={ref} className="block isolate">
|
|
30
|
-
{props.children}
|
|
31
|
-
</div>
|
|
32
|
-
</div>);
|
|
33
|
-
};
|
|
34
|
-
export const Row = (index, row, context) => {
|
|
35
|
-
const cols = context.cols;
|
|
36
|
-
const loading = context.loading;
|
|
37
|
-
return (<Fragment>
|
|
38
|
-
{cols.map((col, colIndex) => {
|
|
39
|
-
const matrix = `${colIndex},${index}`;
|
|
40
|
-
const value = path(row, col.id);
|
|
41
|
-
const Component = col.Element;
|
|
42
|
-
const className = col.cellProps?.className || "";
|
|
43
|
-
const exposeAside = colIndex === 0 && context.Aside && loading === false;
|
|
44
|
-
const Aside = context.Aside;
|
|
45
|
-
return (<td {...col.cellProps} role="cell" data-matrix={matrix} key={`accessor-${index}-${colIndex}`} className={`typography group-table-cell p-(--table-cell-padding) whitespace-pre-wrap flex flex-col md:table-cell border-b border md:border-l-transparent md:border-b-0 border-y border-collapse border-table-border md:border-r md:last:border-r-transparent ${className}`}>
|
|
46
|
-
{exposeAside ? (<RowAside>
|
|
47
|
-
<Aside col={col} row={row} rowIndex={index}/>
|
|
48
|
-
</RowAside>) : null}
|
|
49
|
-
<span className="block text-sm font-bold leading-tight md:hidden">{col.thead}</span>
|
|
50
|
-
<span className="relative">
|
|
51
|
-
{loading ? SkeletonCell : Component ? (<Fragment>
|
|
52
|
-
<Component row={row} matrix={matrix} col={col} rowIndex={index} value={value}/>
|
|
53
|
-
</Fragment>) : (<Fragment>{Is.nil(value) ? "" : value}</Fragment>)}
|
|
54
|
-
</span>
|
|
55
|
-
</td>);
|
|
56
|
-
})}
|
|
57
|
-
</Fragment>);
|
|
58
|
-
};
|