@g4rcez/components 0.0.25 → 0.0.27
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/components/core/button.d.ts.map +1 -1
- package/dist/components/core/button.js +1 -1
- package/dist/components/display/tabs.d.ts.map +1 -1
- package/dist/components/display/tabs.js +2 -2
- package/dist/components/floating/dropdown.d.ts +1 -0
- package/dist/components/floating/dropdown.d.ts.map +1 -1
- package/dist/components/floating/dropdown.js +1 -1
- package/dist/components/floating/menu.d.ts +17 -0
- package/dist/components/floating/menu.d.ts.map +1 -0
- package/dist/components/floating/menu.js +116 -0
- package/dist/components/floating/modal.d.ts +1 -1
- package/dist/components/floating/modal.d.ts.map +1 -1
- package/dist/components/floating/modal.js +33 -9
- package/dist/components/form/autocomplete.d.ts +3 -3
- package/dist/components/form/autocomplete.d.ts.map +1 -1
- package/dist/components/form/autocomplete.js +31 -22
- package/dist/components/form/date-picker.d.ts.map +1 -1
- package/dist/components/form/date-picker.js +5 -2
- package/dist/components/form/input-field.d.ts +6 -4
- package/dist/components/form/input-field.d.ts.map +1 -1
- package/dist/components/form/input-field.js +8 -4
- package/dist/components/form/input.d.ts +1 -1
- package/dist/components/form/input.d.ts.map +1 -1
- package/dist/components/form/input.js +3 -3
- package/dist/components/form/select.d.ts +2 -0
- package/dist/components/form/select.d.ts.map +1 -1
- package/dist/components/form/select.js +5 -3
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +1 -0
- package/dist/components/table/filter.d.ts +13 -44
- package/dist/components/table/filter.d.ts.map +1 -1
- package/dist/components/table/filter.js +41 -28
- package/dist/components/table/index.d.ts.map +1 -1
- package/dist/components/table/index.js +17 -9
- package/dist/components/table/pagination.d.ts.map +1 -1
- package/dist/components/table/pagination.js +7 -4
- package/dist/components/table/sort.d.ts.map +1 -1
- package/dist/components/table/sort.js +18 -12
- package/dist/components/table/thead.d.ts +1 -0
- package/dist/components/table/thead.d.ts.map +1 -1
- package/dist/components/table/thead.js +10 -3
- package/dist/hooks/use-media-query.d.ts +2 -0
- package/dist/hooks/use-media-query.d.ts.map +1 -0
- package/dist/hooks/use-media-query.js +25 -0
- package/dist/hooks/use-translate-context.d.ts +91 -0
- package/dist/hooks/use-translate-context.d.ts.map +1 -0
- package/dist/hooks/use-translate-context.js +49 -0
- package/dist/index.css +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +11032 -10370
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +47 -42
- package/dist/index.umd.js.map +1 -1
- package/dist/lib/fns.d.ts +1 -0
- package/dist/lib/fns.d.ts.map +1 -1
- package/dist/lib/fns.js +1 -0
- package/dist/preset/preset.tailwind.js +1 -1
- package/dist/preset/src/styles/theme.d.ts.map +1 -1
- package/dist/preset/src/styles/theme.js +3 -5
- package/dist/preset/src/styles/theme.types.d.ts +0 -1
- package/dist/preset/src/styles/theme.types.d.ts.map +1 -1
- package/dist/styles/theme.d.ts.map +1 -1
- package/dist/styles/theme.js +3 -5
- package/dist/styles/theme.types.d.ts +0 -1
- package/dist/styles/theme.types.d.ts.map +1 -1
- package/package.json +7 -1
|
@@ -3,9 +3,11 @@ import { InputFieldProps } from "./input-field";
|
|
|
3
3
|
import { Override } from "../../types";
|
|
4
4
|
export type OptionProps = Override<React.ComponentProps<"option">, {
|
|
5
5
|
value: string;
|
|
6
|
+
"data-dynamic"?: string;
|
|
6
7
|
}>;
|
|
7
8
|
export type SelectProps = Override<InputFieldProps<"select">, {
|
|
8
9
|
options: OptionProps[];
|
|
10
|
+
selectContainer?: string;
|
|
9
11
|
}>;
|
|
10
12
|
export declare const Select: React.ForwardRefExoticComponent<Omit<SelectProps, "ref"> & React.RefAttributes<HTMLSelectElement>>;
|
|
11
13
|
//# sourceMappingURL=select.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../../../src/components/form/select.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAwC,MAAM,OAAO,CAAC;AAC7D,OAAO,EAAc,eAAe,EAAE,MAAM,eAAe,CAAC;AAE5D,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../../../src/components/form/select.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAwC,MAAM,OAAO,CAAC;AAC7D,OAAO,EAAc,eAAe,EAAE,MAAM,eAAe,CAAC;AAE5D,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGvC,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAE/G,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE;IAC1D,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAA;CAC3B,CAAC,CAAC;AAEH,eAAO,MAAM,MAAM,oGAgEjB,CAAC"}
|
|
@@ -5,9 +5,11 @@ import { ChevronDown } from "lucide-react";
|
|
|
5
5
|
import { forwardRef, useEffect, useRef } from "react";
|
|
6
6
|
import { InputField } from "./input-field";
|
|
7
7
|
import { css, mergeRefs } from "../../lib/dom";
|
|
8
|
+
import { useTranslations } from "../../hooks/use-translate-context";
|
|
8
9
|
export const Select = forwardRef((_a, ref) => {
|
|
9
10
|
var _b;
|
|
10
|
-
var {
|
|
11
|
+
var { required = true, options, selectContainer = "", feedback = null, labelClassName, interactive, rightLabel, optionalText, container, hideLeft = false, right, left, error } = _a, props = __rest(_a, ["required", "options", "selectContainer", "feedback", "labelClassName", "interactive", "rightLabel", "optionalText", "container", "hideLeft", "right", "left", "error"]);
|
|
12
|
+
const translation = useTranslations();
|
|
11
13
|
const inputRef = useRef(null);
|
|
12
14
|
const id = (_b = props.id) !== null && _b !== void 0 ? _b : props.name;
|
|
13
15
|
useEffect(() => {
|
|
@@ -23,8 +25,8 @@ export const Select = forwardRef((_a, ref) => {
|
|
|
23
25
|
input.removeEventListener("change", change);
|
|
24
26
|
};
|
|
25
27
|
}, []);
|
|
26
|
-
return (_jsx(InputField,
|
|
28
|
+
return (_jsx(InputField, { container: css("group inline-block w-full", container), error: error, feedback: feedback, hideLeft: hideLeft, left: left, optionalText: optionalText, rightLabel: rightLabel, interactive: interactive, form: props.form, id: props.name || props.id, name: props.name, labelClassName: labelClassName, title: props.title, placeholder: props.placeholder, required: required, right: _jsxs("button", { type: "button", className: "hover:text-primary transition-colors", children: [_jsx(ChevronDown, { size: 20 }), _jsx("span", { className: "sr-only", children: translation.inputCaretDown })] }), children: _jsxs("select", Object.assign({}, props, { ref: mergeRefs(ref, inputRef), id: id, name: id, required: required, "data-selected": !!props.value || false, className: css("input bg-transparent text-foreground select group h-11 w-full flex-1 rounded-md p-2 placeholder-input-placeholder outline-none transition-colors group-error:text-danger group-error:placeholder-input-mask-error", "data-[selected=false]:text-input-placeholder", props.className), children: [_jsx("option", { value: "", hidden: true, disabled: true, children: props.placeholder }), options.map((option) => {
|
|
27
29
|
var _a;
|
|
28
30
|
return (_jsx("option", Object.assign({}, option, { children: (_a = option.label) !== null && _a !== void 0 ? _a : option.value }), `${id}-select-option-${option.value}`));
|
|
29
|
-
})] })) }))
|
|
31
|
+
})] })) }));
|
|
30
32
|
});
|
|
@@ -22,5 +22,6 @@ export * from "./form/select";
|
|
|
22
22
|
export * from "./form/switch";
|
|
23
23
|
export * from "./form/transfer-list";
|
|
24
24
|
export * from "./table/index";
|
|
25
|
+
export * from "./floating/menu";
|
|
25
26
|
export { createColumns, createOptionCols, type ColType, useTablePreferences, type TablePagination } from "./table/table-lib";
|
|
26
27
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,KAAK,OAAO,EAAE,mBAAmB,EAAE,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,KAAK,OAAO,EAAE,mBAAmB,EAAE,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAC"}
|
package/dist/components/index.js
CHANGED
|
@@ -22,4 +22,5 @@ export * from "./form/select";
|
|
|
22
22
|
export * from "./form/switch";
|
|
23
23
|
export * from "./form/transfer-list";
|
|
24
24
|
export * from "./table/index";
|
|
25
|
+
export * from "./floating/menu";
|
|
25
26
|
export { createColumns, createOptionCols, useTablePreferences } from "./table/table-lib";
|
|
@@ -1,51 +1,16 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { AllPaths } from "sidekicker";
|
|
3
3
|
import { Label } from "../../types";
|
|
4
|
+
import { OptionProps } from "../form/select";
|
|
4
5
|
import { Col, ColType, TableConfiguration } from "./table-lib";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
symbol: "includes";
|
|
10
|
-
};
|
|
11
|
-
is: {
|
|
12
|
-
value: string;
|
|
13
|
-
label: string;
|
|
14
|
-
symbol: "is";
|
|
15
|
-
};
|
|
16
|
-
isNot: {
|
|
17
|
-
value: string;
|
|
18
|
-
label: string;
|
|
19
|
-
symbol: "!==";
|
|
20
|
-
};
|
|
21
|
-
notContains: {
|
|
22
|
-
value: string;
|
|
23
|
-
label: string;
|
|
24
|
-
symbol: "notIncludes";
|
|
25
|
-
};
|
|
26
|
-
lessThan: {
|
|
27
|
-
value: string;
|
|
28
|
-
label: string;
|
|
29
|
-
symbol: "<=";
|
|
30
|
-
};
|
|
31
|
-
greaterThan: {
|
|
32
|
-
value: string;
|
|
33
|
-
label: string;
|
|
34
|
-
symbol: ">=";
|
|
35
|
-
};
|
|
36
|
-
startsWith: {
|
|
37
|
-
value: string;
|
|
38
|
-
label: string;
|
|
39
|
-
symbol: "startsWith";
|
|
40
|
-
};
|
|
41
|
-
endsWith: {
|
|
42
|
-
value: string;
|
|
43
|
-
label: string;
|
|
44
|
-
symbol: "endsWith";
|
|
45
|
-
};
|
|
6
|
+
type Operators = {
|
|
7
|
+
value: string;
|
|
8
|
+
label: string;
|
|
9
|
+
symbol: string;
|
|
46
10
|
};
|
|
47
|
-
type
|
|
48
|
-
type
|
|
11
|
+
type OperatorTypes = "contains" | "is" | "isNot" | "notContains" | "lessThan" | "greaterThan" | "startsWith" | "endsWith";
|
|
12
|
+
type Operations = Record<OperatorTypes, Operators>;
|
|
13
|
+
type OperationOptions = Partial<Record<ColType, OptionProps[]>>;
|
|
49
14
|
type FilterValue = string | number | string[] | boolean;
|
|
50
15
|
export type FilterConfig<T extends {} = {}> = {
|
|
51
16
|
id: string;
|
|
@@ -60,7 +25,11 @@ type Props<T extends {}> = TableConfiguration<T, {
|
|
|
60
25
|
filters: FilterConfig<T>[];
|
|
61
26
|
set: React.Dispatch<React.SetStateAction<FilterConfig<T>[]>>;
|
|
62
27
|
}>;
|
|
63
|
-
export declare const createFilterFromCol: <T extends {}>(f: Col<T>, rest?: Partial<FilterConfig<T>>) => FilterConfig<T>;
|
|
28
|
+
export declare const createFilterFromCol: <T extends {}>(f: Col<T>, options: OperationOptions, operations: Operations, rest?: Partial<FilterConfig<T>>) => FilterConfig<T>;
|
|
29
|
+
export declare const useOperators: () => {
|
|
30
|
+
operationOptions: Partial<Record<ColType, OptionProps[]>>;
|
|
31
|
+
operations: Operations;
|
|
32
|
+
};
|
|
64
33
|
export declare const Filter: <T extends {}>(props: Props<T>) => import("react/jsx-runtime").JSX.Element;
|
|
65
34
|
type ColumnHeaderFilterProps<T extends {}> = {
|
|
66
35
|
filter: FilterConfig<T>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter.d.ts","sourceRoot":"","sources":["../../../src/components/table/filter.tsx"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"filter.d.ts","sourceRoot":"","sources":["../../../src/components/table/filter.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA4B,MAAM,OAAO,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAGpC,OAAO,EAAE,WAAW,EAAU,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,GAAG,EAAE,OAAO,EAAY,kBAAkB,EAAiB,MAAM,aAAa,CAAC;AAGxF,KAAK,SAAS,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAA;AAEjE,KAAK,aAAa,GAAG,UAAU,GAAG,IAAI,GAAG,OAAO,GAAG,aAAa,GAAG,UAAU,GAAG,aAAa,GAAG,YAAY,GAAG,UAAU,CAAA;AAEzH,KAAK,UAAU,GAAG,MAAM,CAAC,aAAa,EAAE,SAAS,CAAC,CAAA;AAElD,KAAK,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC,CAAA;AAE/D,KAAK,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC;AAExD,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,EAAE,GAAG,EAAE,IAAI;IAC1C,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,KAAK,CAAC;IACb,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;IAClB,IAAI,EAAE,OAAO,CAAC;IACd,SAAS,EAAE,SAAS,CAAC;IACrB,KAAK,EAAE,WAAW,CAAC;CACtB,CAAC;AAEF,KAAK,KAAK,CAAC,CAAC,SAAS,EAAE,IAAI,kBAAkB,CACzC,CAAC,EACD;IACI,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IACf,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3B,GAAG,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;CAChE,CACJ,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,CAAC,SAAS,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,WAAW,gBAAgB,cAAc,UAAU,SAAQ,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,KAAQ,YAAY,CAAC,CAAC,CAMnK,CAAC;AAEF,eAAO,MAAM,YAAY;;;CAwBxB,CAAA;AAED,eAAO,MAAM,MAAM,GAAI,CAAC,SAAS,EAAE,SAAS,KAAK,CAAC,CAAC,CAAC,4CAiGnD,CAAC;AAEF,KAAK,uBAAuB,CAAC,CAAC,SAAS,EAAE,IAAI;IACzC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;IACxB,QAAQ,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,CAAC,iBAAiB,CAAC,KAAK,IAAI,CAAC;IAC3D,GAAG,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;CAChE,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,CAAC,SAAS,EAAE,6BAA6B,uBAAuB,CAAC,CAAC,CAAC,4CAsCrG,CAAC"}
|
|
@@ -1,38 +1,49 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { ListFilterIcon, PlusIcon, Trash2Icon } from "lucide-react";
|
|
3
|
-
import { Fragment } from "react";
|
|
3
|
+
import { Fragment, useMemo } from "react";
|
|
4
4
|
import { uuid } from "../../lib/fns";
|
|
5
5
|
import { Dropdown } from "../floating/dropdown";
|
|
6
6
|
import { Input } from "../form/input";
|
|
7
7
|
import { Select } from "../form/select";
|
|
8
8
|
import { ColType, getLabel, valueFromType } from "./table-lib";
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
is: { value: "is", label: "Is", symbol: "is" },
|
|
12
|
-
isNot: { value: "isNot", label: "Is not", symbol: "!==" },
|
|
13
|
-
notContains: { value: "notContains", label: "Does not contains", symbol: "notIncludes" },
|
|
14
|
-
lessThan: { value: "lessThan", label: "Less Than", symbol: "<=" },
|
|
15
|
-
greaterThan: { value: "greaterThan", label: "Greater than", symbol: ">=" },
|
|
16
|
-
startsWith: { value: "startsWith", label: "Starts with", symbol: "startsWith" },
|
|
17
|
-
endsWith: { value: "endsWith", label: "Ends with", symbol: "endsWith" },
|
|
18
|
-
};
|
|
19
|
-
const operatorOptions = {
|
|
20
|
-
[ColType.Text]: [operators.is, operators.isNot, operators.contains, operators.notContains, operators.startsWith, operators.endsWith],
|
|
21
|
-
[ColType.Boolean]: [operators.is, operators.isNot],
|
|
22
|
-
[ColType.Number]: [operators.is, operators.isNot, operators.greaterThan, operators.lessThan],
|
|
23
|
-
};
|
|
24
|
-
export const createFilterFromCol = (f, rest = {}) => {
|
|
9
|
+
import { useTranslations } from "../../hooks/use-translate-context";
|
|
10
|
+
export const createFilterFromCol = (f, options, operations, rest = {}) => {
|
|
25
11
|
var _a, _b;
|
|
26
12
|
const name = f.id;
|
|
27
13
|
const type = (_a = f.type) !== null && _a !== void 0 ? _a : ColType.Text;
|
|
28
|
-
const operatorId = (_b =
|
|
29
|
-
const operation =
|
|
14
|
+
const operatorId = (_b = options[type]) === null || _b === void 0 ? void 0 : _b[0].value;
|
|
15
|
+
const operation = operations[operatorId];
|
|
30
16
|
return Object.assign({ id: uuid(), operation, label: getLabel(f), name, type, value: "" }, rest);
|
|
31
17
|
};
|
|
18
|
+
export const useOperators = () => {
|
|
19
|
+
const translation = useTranslations();
|
|
20
|
+
const operations = useMemo(() => {
|
|
21
|
+
return {
|
|
22
|
+
contains: { value: "contains", label: translation.tableFilterTypeContains, symbol: "includes" },
|
|
23
|
+
is: { value: "is", label: translation.tableFilterTypeIs, symbol: "is" },
|
|
24
|
+
isNot: { value: "isNot", label: translation.tableFilterTypeIsNot, symbol: "!==" },
|
|
25
|
+
notContains: { value: "notContains", label: translation.tableFilterTypeNotContains, symbol: "notIncludes" },
|
|
26
|
+
lessThan: { value: "lessThan", label: translation.tableFilterTypeLessThan, symbol: "<=" },
|
|
27
|
+
greaterThan: { value: "greaterThan", label: translation.tableFilterTypeGreaterThan, symbol: ">=" },
|
|
28
|
+
startsWith: { value: "startsWith", label: translation.tableFilterTypeStartsWith, symbol: "startsWith" },
|
|
29
|
+
endsWith: { value: "endsWith", label: translation.tableFilterTypeEndsWith, symbol: "endsWith" },
|
|
30
|
+
};
|
|
31
|
+
}, [translation]);
|
|
32
|
+
const operationOptions = useMemo(() => {
|
|
33
|
+
return {
|
|
34
|
+
[ColType.Text]: [operations.is, operations.isNot, operations.contains, operations.notContains, operations.startsWith, operations.endsWith],
|
|
35
|
+
[ColType.Boolean]: [operations.is, operations.isNot],
|
|
36
|
+
[ColType.Number]: [operations.is, operations.isNot, operations.greaterThan, operations.lessThan],
|
|
37
|
+
};
|
|
38
|
+
}, [translation]);
|
|
39
|
+
return { operationOptions, operations };
|
|
40
|
+
};
|
|
32
41
|
export const Filter = (props) => {
|
|
42
|
+
const translation = useTranslations();
|
|
43
|
+
const { operationOptions, operations } = useOperators();
|
|
33
44
|
const onAddFilter = () => {
|
|
34
45
|
const col = props.cols.at(0);
|
|
35
|
-
props.set((prev) => [...prev, createFilterFromCol(col)]);
|
|
46
|
+
props.set((prev) => [...prev, createFilterFromCol(col, operationOptions, operations)]);
|
|
36
47
|
};
|
|
37
48
|
const onSelectProperty = (e) => {
|
|
38
49
|
const changedId = e.target.dataset.id || "";
|
|
@@ -41,13 +52,13 @@ export const Filter = (props) => {
|
|
|
41
52
|
if (changedId !== x.id)
|
|
42
53
|
return x;
|
|
43
54
|
const col = props.cols.find((x) => newId === x.id);
|
|
44
|
-
return createFilterFromCol(col, { value: "" });
|
|
55
|
+
return createFilterFromCol(col, operationOptions, operations, { value: "" });
|
|
45
56
|
}));
|
|
46
57
|
};
|
|
47
58
|
const onSelectOperation = (e) => {
|
|
48
59
|
const id = e.target.dataset.id || "";
|
|
49
60
|
const operator = e.target.value;
|
|
50
|
-
props.set((prev) => prev.map((x) => (x.id === id ? Object.assign(Object.assign({}, x), { operation:
|
|
61
|
+
props.set((prev) => prev.map((x) => (x.id === id ? Object.assign(Object.assign({}, x), { operation: operations[operator] }) : x)));
|
|
51
62
|
};
|
|
52
63
|
const onDelete = (e) => {
|
|
53
64
|
const id = e.currentTarget.dataset.id || "";
|
|
@@ -58,21 +69,23 @@ export const Filter = (props) => {
|
|
|
58
69
|
const value = valueFromType(e.target);
|
|
59
70
|
props.set((prev) => prev.map((x) => (x.id === id ? Object.assign(Object.assign({}, x), { value }) : x)));
|
|
60
71
|
};
|
|
61
|
-
return (_jsx(Fragment, { children: _jsx(Dropdown, { arrow:
|
|
62
|
-
const operators =
|
|
63
|
-
return (_jsxs("li", { className: "flex flex-nowrap gap-3", children: [_jsx(Select, {
|
|
64
|
-
}), _jsx("li", { children: _jsxs("button", { type: "button", onClick: onAddFilter, className: "text-primary flex items-center gap-1", children: [_jsx(PlusIcon, { size: 14 }), "
|
|
72
|
+
return (_jsx(Fragment, { children: _jsx(Dropdown, { arrow: true, title: translation.tableFilterDropdownTitle, trigger: _jsxs("span", { className: "flex items-center gap-1 proportional-nums", children: [_jsx(ListFilterIcon, { size: 14 }), translation.tableFilterLabel, " ", props.filters.length === 0 ? "" : ` (${props.filters.length})`] }), children: _jsxs("ul", { className: "mt-4 space-y-2", children: [props.filters.map((filter) => {
|
|
73
|
+
const operators = operationOptions[filter.type];
|
|
74
|
+
return (_jsxs("li", { className: "flex flex-nowrap gap-3", children: [_jsx(Select, { options: props.options, title: translation.tableFilterColumnTitle, placeholder: translation.tableFilterColumnPlaceholder, value: filter.name, "data-id": filter.id, onChange: onSelectProperty }), _jsx(Select, { "data-id": filter.id, onChange: onSelectOperation, value: filter.operation.value, options: operators, title: translation.tableFilterOperatorTitle, placeholder: translation.tableFilterOperatorPlaceholder }), _jsx(Input, { "data-id": filter.id, onChange: onChangeValue, title: translation.tableFilterValueTitle, placeholder: translation.tableFilterValuePlaceholder, type: filter.type, value: filter.value, optionalText: "" }), _jsx("div", { className: "flex items-center justify-center mt-5", children: _jsx("button", { "data-id": filter.id, type: "button", onClick: onDelete, children: _jsx(Trash2Icon, { className: "text-danger", size: 16 }) }) })] }, `filter-select-${filter.id}`));
|
|
75
|
+
}), _jsx("li", { children: _jsxs("button", { type: "button", onClick: onAddFilter, className: "text-primary flex items-center gap-1", children: [_jsx(PlusIcon, { size: 14 }), " ", translation.tableFilterNewFilter] }) })] }) }) }));
|
|
65
76
|
};
|
|
66
77
|
export const ColumnHeaderFilter = ({ filter, onDelete, set }) => {
|
|
78
|
+
const translation = useTranslations();
|
|
79
|
+
const { operationOptions, operations } = useOperators();
|
|
67
80
|
const onSelectOperation = (e) => {
|
|
68
81
|
const operator = e.target.value;
|
|
69
82
|
const id = e.target.dataset.id || "";
|
|
70
|
-
set((prev) => prev.map((x) => (x.id === id ? Object.assign(Object.assign({}, x), { operation:
|
|
83
|
+
set((prev) => prev.map((x) => (x.id === id ? Object.assign(Object.assign({}, x), { operation: operations[operator] }) : x)));
|
|
71
84
|
};
|
|
72
85
|
const onChangeValue = (e) => {
|
|
73
86
|
const id = e.target.dataset.id || "";
|
|
74
87
|
const value = valueFromType(e.target);
|
|
75
88
|
set((prev) => prev.map((x) => (x.id === id ? Object.assign(Object.assign({}, x), { value }) : x)));
|
|
76
89
|
};
|
|
77
|
-
return (_jsxs("div", { className: "flex flex-nowrap items-center gap-4 py-2", children: [_jsx(Select, { "data-id": filter.id, onChange: onSelectOperation, options:
|
|
90
|
+
return (_jsxs("div", { className: "flex flex-nowrap items-center gap-4 py-2", children: [_jsx(Select, { "data-id": filter.id, onChange: onSelectOperation, options: operationOptions[filter.type], title: translation.tableFilterColumnTitle, placeholder: translation.tableFilterColumnPlaceholder, value: filter.operation.value }), _jsx(Input, { "data-id": filter.id, onChange: onChangeValue, type: filter.type, value: filter.value, title: translation.tableFilterValueTitle, placeholder: translation.tableFilterValueTitle }), _jsx("button", { onClick: onDelete, "data-id": filter.id, type: "button", className: "mt-4", children: _jsx(Trash2Icon, { className: "text-danger", size: 14 }) })] }));
|
|
78
91
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/table/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/table/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAA2B,cAAc,EAAwC,MAAM,OAAO,CAAC;AAM7G,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAGpC,OAAO,EAAa,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC3C,OAAO,EAAoB,GAAG,EAA+B,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAKtG,KAAK,eAAe,CAAC,CAAC,SAAS,EAAE,IAAI,cAAc,CAAC,gBAAgB,CAAC,GACjE,mBAAmB,CAAC,CAAC,CAAC,GAAG;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;IACrB,MAAM,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;IACxB,UAAU,EAAE,WAAW,EAAE,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,OAAO,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5B,SAAS,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAChE,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,WAAW,CAAC,EAAE,OAAO,CAAC;CACzB,CAAC;AA2KN,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,EAAE,IAAI,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,aAAa,GAAG,QAAQ,CAAC,GAAG;IAC1G,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;CAC5B,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC,CAAC,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC;AAO/E,eAAO,MAAM,KAAK,GAAI,CAAC,SAAS,EAAE,SAAS,UAAU,CAAC,CAAC,CAAC,4CAgGvD,CAAC"}
|
|
@@ -5,7 +5,7 @@ import { AnimatePresence, motion } from "framer-motion";
|
|
|
5
5
|
import Linq from "linq-arrays";
|
|
6
6
|
import React, { Fragment, useEffect, useMemo, useRef, useState } from "react";
|
|
7
7
|
import { TableVirtuoso } from "react-virtuoso";
|
|
8
|
-
import { Is } from "sidekicker";
|
|
8
|
+
import { clamp, Is } from "sidekicker";
|
|
9
9
|
import { useReducer } from "use-typed-reducer";
|
|
10
10
|
import { useCallbackRef } from "../../hooks/use-callback-ref";
|
|
11
11
|
import { path } from "../../lib/fns";
|
|
@@ -14,19 +14,27 @@ import { Pagination } from "./pagination";
|
|
|
14
14
|
import { multiSort } from "./sort";
|
|
15
15
|
import { createOptionCols } from "./table-lib";
|
|
16
16
|
import { TableHeader } from "./thead";
|
|
17
|
+
const calculateSkeletonWidth = () => clamp(40, Math.random() * 90, 90);
|
|
17
18
|
const TableBody = React.forwardRef((props, ref) => {
|
|
18
19
|
var _a;
|
|
19
|
-
return (_jsx("tbody", Object.assign({}, props, { className: `divide-y divide-table-border ${(_a = props.className) !== null && _a !== void 0 ? _a : ""}`, ref: ref, children: _jsx(AnimatePresence, { children: props.children }) })));
|
|
20
|
+
return (_jsx("tbody", Object.assign({}, props, { role: "rowgroup", className: `divide-y divide-table-border ${(_a = props.className) !== null && _a !== void 0 ? _a : ""}`, ref: ref, children: _jsx(AnimatePresence, { children: props.children }) })));
|
|
20
21
|
});
|
|
21
22
|
const VirtualTable = React.forwardRef((props, ref) => {
|
|
22
23
|
var _a;
|
|
23
|
-
return (_jsx("table", Object.assign({}, props, { ref: ref, className: `table min-w-full divide-y divide-table-border table-auto text-left ${(_a = props.className) !== null && _a !== void 0 ? _a : ""}` })));
|
|
24
|
+
return (_jsx("table", Object.assign({}, props, { ref: ref, role: "table", className: `table min-w-full divide-y divide-table-border table-auto text-left ${(_a = props.className) !== null && _a !== void 0 ? _a : ""}` })));
|
|
25
|
+
});
|
|
26
|
+
const Thead = React.forwardRef((_a, ref) => {
|
|
27
|
+
var { context } = _a, props = __rest(_a, ["context"]);
|
|
28
|
+
return (_jsx("thead", Object.assign({}, props, { role: "rowgroup", className: "bg-card-background shadow-xs group:sticky top-0", ref: ref })));
|
|
29
|
+
});
|
|
30
|
+
const TRow = React.forwardRef((_a, ref) => {
|
|
31
|
+
var _b;
|
|
32
|
+
var { context, item } = _a, props = __rest(_a, ["context", "item"]);
|
|
33
|
+
return (_jsx("tr", Object.assign({}, props, { role: "row", ref: ref, className: `table-row ${(_b = props.className) !== null && _b !== void 0 ? _b : ""}` })));
|
|
24
34
|
});
|
|
25
|
-
const Thead = React.forwardRef((props, ref) => _jsx("thead", Object.assign({}, props, { className: "bg-card-background shadow-xs group:sticky top-0", ref: ref })));
|
|
26
|
-
const TRow = React.forwardRef((props, ref) => { var _a; return _jsx("tr", Object.assign({}, props, { ref: ref, className: `table-row ${(_a = props.className) !== null && _a !== void 0 ? _a : ""}` })); });
|
|
27
35
|
const TFoot = React.forwardRef((props, ref) => {
|
|
28
36
|
if (props.context.loadingMore) {
|
|
29
|
-
return (_jsx("tfoot", Object.assign({}, props, { ref: ref, className: "bg-card-background", children: _jsx("tr", { className: "bg-card-background", children: _jsx("td", { colSpan: 999, className: "px-2 h-14 bg-card-background", children: _jsx("span", { className: "block w-full h-2 bg-foreground rounded opacity-60 animate-pulse" }) }) }) })));
|
|
37
|
+
return (_jsx("tfoot", Object.assign({}, props, { ref: ref, className: "bg-card-background", children: _jsx("tr", { role: "row", className: "bg-card-background", children: _jsx("td", { colSpan: 999, className: "px-2 h-14 bg-card-background", children: _jsx("span", { className: "block w-full h-2 bg-foreground rounded opacity-60 animate-pulse" }) }) }) })));
|
|
30
38
|
}
|
|
31
39
|
return null;
|
|
32
40
|
});
|
|
@@ -45,7 +53,7 @@ const ItemContent = (index, row, context) => {
|
|
|
45
53
|
const matrix = `${colIndex},${index}`;
|
|
46
54
|
const value = path(row, col.id);
|
|
47
55
|
const Component = col.Element;
|
|
48
|
-
return (_createElement("td", Object.assign({}, col.cellProps, { "data-matrix": matrix, key: `accessor-${index}-${colIndex}`, className: "px-2 h-14 border-none first:table-cell hidden md:table-cell" }), loading ? (_jsx("div", { className: "animate-pulse h-2 bg-table-border rounded" })) : Component ? (_jsx(Component, { row: row, matrix: matrix, col: col, rowIndex: index, value: value })) : (_jsx(Fragment, { children: Is.nil(value) ? "" : value }))));
|
|
56
|
+
return (_createElement("td", Object.assign({}, col.cellProps, { "data-matrix": matrix, role: "cell", key: `accessor-${index}-${colIndex}`, className: "px-2 h-14 border-none first:table-cell hidden md:table-cell" }), loading ? (_jsx("div", { className: "animate-pulse h-2 bg-table-border rounded", style: { width: `${calculateSkeletonWidth()}%` } })) : Component ? (_jsx(Component, { row: row, matrix: matrix, col: col, rowIndex: index, value: value })) : (_jsx(Fragment, { children: Is.nil(value) ? "" : value }))));
|
|
49
57
|
}) }));
|
|
50
58
|
};
|
|
51
59
|
const Frag = () => _jsx(Fragment, {});
|
|
@@ -62,7 +70,7 @@ const InnerTable = (_a) => {
|
|
|
62
70
|
return props.rows;
|
|
63
71
|
const linq = new Linq(props.rows);
|
|
64
72
|
if (filters.length > 0) {
|
|
65
|
-
filters.forEach((x) =>
|
|
73
|
+
filters.forEach((x) => x.value === "" || Number.isNaN(x.value) ? undefined : linq.Where(x.name, x.operation.symbol, x.value));
|
|
66
74
|
}
|
|
67
75
|
if (sorters.length === 0)
|
|
68
76
|
return linq.Select();
|
|
@@ -86,7 +94,7 @@ const InnerTable = (_a) => {
|
|
|
86
94
|
observer.observe(div);
|
|
87
95
|
return () => observer.disconnect();
|
|
88
96
|
}, []);
|
|
89
|
-
return (_jsxs("div", { className: "min-w-full", children: [_jsxs("div", { className: `group rounded-lg px-1 ${border ? "border border-table-border" : ""}`, children: [_jsx(TableVirtuoso, { data: rows, useWindowScroll: true, components: components, totalCount: rows.length, itemContent: ItemContent, context: { loading: props.loading, loadingMore: props.loadingMore, cols: cols }, fixedFooterContent: showLoadingFooter ? Frag : null, fixedHeaderContent: () => (_jsx(TableHeader, {
|
|
97
|
+
return (_jsxs("div", { className: "min-w-full", children: [_jsxs("div", { className: `group rounded-lg px-1 ${border ? "border border-table-border" : ""}`, children: [_jsx(TableVirtuoso, { data: rows, useWindowScroll: true, components: components, totalCount: rows.length, itemContent: ItemContent, context: { loading: props.loading, loadingMore: props.loadingMore, cols: cols }, fixedFooterContent: showLoadingFooter ? Frag : null, fixedHeaderContent: () => (_jsx(TableHeader, { headers: cols, sorters: sorters, filters: filters, setCols: setCols, setSorters: setSorters, setFilters: setFilters, loading: !!props.loading })) }), _jsx("div", { "aria-hidden": "true", ref: ref, className: "h-0.5 w-full" })] }), pagination !== null ? _jsx(Pagination, Object.assign({}, pagination)) : null] }));
|
|
90
98
|
};
|
|
91
99
|
const dispatcherFun = (prev, setter) => typeof setter === "function" ? setter(prev) : setter;
|
|
92
100
|
export const Table = (props) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pagination.d.ts","sourceRoot":"","sources":["../../../src/components/table/pagination.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"pagination.d.ts","sourceRoot":"","sources":["../../../src/components/table/pagination.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAwB9C,eAAO,MAAM,UAAU,eAAgB,eAAe,4CAyErD,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Fragment, useMemo } from "react";
|
|
2
|
+
import { Fragment, useId, useMemo } from "react";
|
|
3
|
+
import { useTranslations } from "../../hooks/use-translate-context";
|
|
3
4
|
function createPaginationItems(current, max) {
|
|
4
5
|
if (!current || !max)
|
|
5
6
|
return [];
|
|
@@ -26,15 +27,17 @@ function createPaginationItems(current, max) {
|
|
|
26
27
|
return Array.from(new Set(items));
|
|
27
28
|
}
|
|
28
29
|
export const Pagination = (pagination) => {
|
|
30
|
+
const id = useId();
|
|
31
|
+
const translation = useTranslations();
|
|
29
32
|
const Render = pagination.asLink || "button";
|
|
30
33
|
const pageNavigation = useMemo(() => createPaginationItems(pagination.current, pagination.pages), [pagination.current, pagination.pages]);
|
|
31
34
|
const hasNext = pagination.current < pagination.pages;
|
|
32
|
-
return (_jsxs("footer", { className: "flex px-1 py-
|
|
35
|
+
return (_jsxs("footer", { className: "flex px-1 py-4 items-center justify-center gap-4 lg:justify-between flex-wrap lg:flex-nowrap", children: [_jsx("p", { children: _jsx(translation.tablePaginationFooter, Object.assign({}, pagination, { sizes: pagination.sizes, select: pagination.onChangeSize && Array.isArray(pagination.sizes) ? (_jsxs(Fragment, { children: [_jsx("label", { htmlFor: id, children: translation.tablePaginationSelectLabel }), _jsx("select", { id: id, value: pagination.size, className: "cursor-pointer bg-transparent", onChange: (e) => {
|
|
33
36
|
var _a;
|
|
34
37
|
(_a = pagination.onChangeSize) === null || _a === void 0 ? void 0 : _a.call(pagination, Number(e.target.value));
|
|
35
|
-
}, children: pagination.sizes.map((value) => (_jsx("option", { value: value, children: value }, `pagination-opt-${value}`))) }), " "
|
|
38
|
+
}, children: pagination.sizes.map((value) => (_jsx("option", { value: value, children: value }, `pagination-opt-${value}`))) }), " "] })) : null })) }), _jsx("nav", { children: _jsxs("ul", { className: "flex items-center gap-2", children: [pagination.current > 1 ? (_jsx("li", { children: _jsx(Render, { href: "previous", className: "", children: translation.tablePaginationPrevious }) })) : null, pageNavigation.map((x) => {
|
|
36
39
|
if (x === null)
|
|
37
40
|
return null;
|
|
38
41
|
return (_jsx(Fragment, { children: typeof x === "string" ? (_jsx("li", { children: "..." })) : (_jsx("li", { children: _jsx(Render, { href: x, className: `cursor-pointer px-3 py-1 transition-colors border-b-2 hover:text-primary-subtle hover:border-primary-subtle proportional-nums ${x === pagination.current ? "text-primary border-primary" : "border-transparent"}`, children: x }) })) }, `pagination-${x}`));
|
|
39
|
-
}), hasNext ? (_jsx("li", { children: _jsx(Render, { href: "next", className: "", children:
|
|
42
|
+
}), hasNext ? (_jsx("li", { children: _jsx(Render, { href: "next", className: "", children: translation.tablePaginationNext }) })) : null] }) })] }));
|
|
40
43
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sort.d.ts","sourceRoot":"","sources":["../../../src/components/table/sort.tsx"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"sort.d.ts","sourceRoot":"","sources":["../../../src/components/table/sort.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAuD,MAAM,OAAO,CAAC;AAE5E,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAGpC,OAAO,EAAE,GAAG,EAAY,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGrF,KAAK,KAAK,CAAC,CAAC,SAAS,EAAE,IAAI,MAAM,CAAC,SAAS,MAAM,CAAC,SAAS,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC;AAE9E,aAAK,KAAK;IACN,GAAG,QAAQ;IACX,IAAI,SAAS;IACb,SAAS,cAAc;CAC1B;AAED,MAAM,MAAM,MAAM,CAAC,CAAC,SAAS,EAAE,IAAI;IAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IAAC,IAAI,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,KAAK,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAY9F,eAAO,MAAM,SAAS,GAAI,CAAC,SAAS,EAAE,SAAS,CAAC,EAAE,UAAU,MAAM,CAAC,CAAC,CAAC,EAAE,QAAuC,CAAC;AAG/G,KAAK,KAAK,CAAC,CAAC,SAAS,EAAE,IAAI,kBAAkB,CACzC,CAAC,EACD;IACI,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IACrB,GAAG,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;CAC1D,CACJ,CAAC;AASF,eAAO,MAAM,IAAI,GAAI,CAAC,SAAS,EAAE,SAAS,KAAK,CAAC,CAAC,CAAC,4CA0EjD,CAAC;AAEF,KAAK,eAAe,CAAC,CAAC,SAAS,EAAE,IAAI,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,EAAE,SAAS,GAAG,YAAY,CAAC,GAAG;IAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAA;CAAE,CAAC;AAE9G,eAAO,MAAM,UAAU,GAAI,CAAC,SAAS,EAAE,SAAS,eAAe,CAAC,CAAC,CAAC,4CA+BjE,CAAC"}
|
|
@@ -5,6 +5,8 @@ import { Fragment, useEffect, useState } from "react";
|
|
|
5
5
|
import { uuid } from "../../lib/fns";
|
|
6
6
|
import { Dropdown } from "../floating/dropdown";
|
|
7
7
|
import { Select } from "../form/select";
|
|
8
|
+
import { getLabel } from "./table-lib";
|
|
9
|
+
import { useTranslations } from "../../hooks/use-translate-context";
|
|
8
10
|
var Order;
|
|
9
11
|
(function (Order) {
|
|
10
12
|
Order["Asc"] = "asc";
|
|
@@ -18,22 +20,23 @@ const createSorterFn = (fields) => (a, b) => fields.reduce((acc, x) => {
|
|
|
18
20
|
return acc !== 0 ? acc : p;
|
|
19
21
|
}, 0);
|
|
20
22
|
export const multiSort = (array, fields) => array.sort(createSorterFn(fields));
|
|
21
|
-
const
|
|
22
|
-
asc: { label: "Ascending", value: Order.Asc },
|
|
23
|
-
desc: { label: "Descending", value: Order.Desc },
|
|
24
|
-
};
|
|
25
|
-
const orderOptions = [orders.asc, orders.desc];
|
|
26
|
-
const createSorter = (col, order = Order.Asc) => ({
|
|
23
|
+
const createSorter = (col, label, order = Order.Asc) => ({
|
|
27
24
|
id: uuid(),
|
|
28
25
|
type: order,
|
|
29
26
|
value: col.id,
|
|
30
|
-
label
|
|
27
|
+
label,
|
|
31
28
|
});
|
|
32
29
|
export const Sort = (props) => {
|
|
30
|
+
const translation = useTranslations();
|
|
31
|
+
const orders = {
|
|
32
|
+
asc: { label: translation.tableSortAsc, value: Order.Asc },
|
|
33
|
+
desc: { label: translation.tableSortDesc, value: Order.Desc },
|
|
34
|
+
};
|
|
35
|
+
const orderOptions = [orders.asc, orders.desc];
|
|
33
36
|
const onAddSorter = () => {
|
|
34
37
|
const col = props.cols[0];
|
|
35
38
|
if (col)
|
|
36
|
-
props.set((prev) => [...prev, createSorter(col)]);
|
|
39
|
+
props.set((prev) => [...prev, createSorter(col, orders.asc.label)]);
|
|
37
40
|
};
|
|
38
41
|
const onSetSorter = (id) => (e) => {
|
|
39
42
|
const value = e.target.value;
|
|
@@ -47,11 +50,12 @@ export const Sort = (props) => {
|
|
|
47
50
|
const id = e.currentTarget.dataset.id || "";
|
|
48
51
|
props.set((prev) => prev.filter((x) => x.id !== id));
|
|
49
52
|
};
|
|
50
|
-
return (_jsx(Fragment, { children: _jsx(Dropdown, {
|
|
51
|
-
return (_jsxs("li", { className: "flex flex-nowrap gap-3", children: [_jsx(Select, {
|
|
52
|
-
}), _jsx("li", { children: _jsxs("button", { type: "button", onClick: onAddSorter, className: "text-primary flex items-center gap-1", children: [_jsx(PlusIcon, { size: 14 }), "
|
|
53
|
+
return (_jsx(Fragment, { children: _jsx(Dropdown, { title: translation.tableSortDropdownTitle, trigger: _jsxs("span", { className: "flex items-center gap-1 proportional-nums", children: [_jsx(ArrowUpDownIcon, { size: 14 }), translation.tableSortOrderByLabel, " ", props.sorters.length === 0 ? "" : ` (${props.sorters.length})`] }), children: _jsxs("ul", { className: "mt-4 space-y-2", children: [props.sorters.map((sorter) => {
|
|
54
|
+
return (_jsxs("li", { className: "flex flex-nowrap gap-3", children: [_jsx(Select, { options: props.options, value: sorter.value, onChange: onSetSorter(sorter.id), title: translation.tableSortOrderInputTitle, placeholder: translation.tableSortOrderInputPlaceholder }), _jsx(Select, { onChange: onSortOrderType(sorter.id), value: sorter.type, options: orderOptions, title: translation.tableSortTypeInputTitle, placeholder: translation.tableSortTypeInputPlaceholder }), _jsx("button", { className: "mt-4", "data-id": sorter.id, onClick: onDelete, children: _jsx(Trash2Icon, { className: "text-danger", size: 14 }) })] }, `sorter-select-${sorter.id}`));
|
|
55
|
+
}), _jsx("li", { children: _jsxs("button", { type: "button", onClick: onAddSorter, className: "text-primary flex items-center gap-1", children: [_jsx(PlusIcon, { size: 14 }), " ", translation.tableSortAddButton] }) })] }) }) }));
|
|
53
56
|
};
|
|
54
57
|
export const SorterHead = (props) => {
|
|
58
|
+
const translations = useTranslations();
|
|
55
59
|
const [status, setStatus] = useState(() => {
|
|
56
60
|
const sorter = props.sorters.find((sort) => sort.value === props.col.id);
|
|
57
61
|
return sorter ? sorter.type : Order.Undefined;
|
|
@@ -68,5 +72,7 @@ export const SorterHead = (props) => {
|
|
|
68
72
|
return [...prev];
|
|
69
73
|
});
|
|
70
74
|
}, [status, props.col]);
|
|
71
|
-
|
|
75
|
+
const labelId = `${props.col.id}-sorter-id`;
|
|
76
|
+
const label = getLabel(props.col);
|
|
77
|
+
return (_jsxs("button", { "aria-labelledby": labelId, className: "isolate flex items-center", onClick: onClick, type: "button", children: [_jsxs("span", { id: labelId, className: "sr-only", children: [translations.tableSortDropdownTitle, " ", label] }), status === Order.Asc ? _jsx(ArrowUp01Icon, { size: 14 }) : null, status === Order.Desc ? _jsx(ArrowDown01Icon, { size: 14 }) : null, status === Order.Undefined ? _jsx(ArrowUpDownIcon, { size: 14 }) : null] }));
|
|
72
78
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Col, TableOperationProps } from "./table-lib";
|
|
2
2
|
type TableHeaderProps<T extends {}> = {
|
|
3
|
+
loading: boolean;
|
|
3
4
|
headers: Col<T>[];
|
|
4
5
|
} & Pick<TableOperationProps<T>, "filters" | "setFilters" | "setCols" | "setSorters" | "sorters">;
|
|
5
6
|
export declare const TableHeader: <T extends {}>(props: TableHeaderProps<T>) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"thead.d.ts","sourceRoot":"","sources":["../../../src/components/table/thead.tsx"],"names":[],"mappings":"AAMA,OAAO,EAAE,GAAG,EAAY,mBAAmB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"thead.d.ts","sourceRoot":"","sources":["../../../src/components/table/thead.tsx"],"names":[],"mappings":"AAMA,OAAO,EAAE,GAAG,EAAY,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAIjE,KAAK,gBAAgB,CAAC,CAAC,SAAS,EAAE,IAAI;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;CACrB,GAAG,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,EAAE,SAAS,GAAG,YAAY,GAAG,SAAS,GAAG,YAAY,GAAG,SAAS,CAAC,CAAC;AAyFlG,eAAO,MAAM,WAAW,GAAI,CAAC,SAAS,EAAE,SAAS,gBAAgB,CAAC,CAAC,CAAC,4CA4BnE,CAAC"}
|
|
@@ -2,21 +2,28 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { AnimatePresence, Reorder } from "framer-motion";
|
|
3
3
|
import { PlusIcon, SearchIcon, ZoomInIcon } from "lucide-react";
|
|
4
4
|
import { Dropdown } from "../floating/dropdown";
|
|
5
|
-
import { ColumnHeaderFilter, createFilterFromCol } from "./filter";
|
|
5
|
+
import { ColumnHeaderFilter, createFilterFromCol, useOperators } from "./filter";
|
|
6
6
|
import { SorterHead } from "./sort";
|
|
7
7
|
import { getLabel } from "./table-lib";
|
|
8
|
+
import { useTranslations } from "../../hooks/use-translate-context";
|
|
9
|
+
import { Order } from "linq-arrays";
|
|
8
10
|
const targetTransitionAnimate = { opacity: 1 };
|
|
9
11
|
const whileDrag = { opacity: 0.75, backgroundColor: "var(--table-border)" };
|
|
10
12
|
const exit = { opacity: 0, transition: { duration: 0.4, type: "spring" } };
|
|
11
13
|
const HeaderChild = (props) => {
|
|
12
14
|
var _a, _b;
|
|
15
|
+
const translation = useTranslations();
|
|
13
16
|
const ownFilters = props.filters.filter((x) => x.name === props.header.id);
|
|
14
17
|
const hasFilters = ownFilters.length > 0;
|
|
15
18
|
const FilterIcon = hasFilters ? ZoomInIcon : SearchIcon;
|
|
19
|
+
const { operationOptions, operations } = useOperators();
|
|
16
20
|
const onDelete = (e) => {
|
|
17
21
|
const id = e.currentTarget.dataset.id || "";
|
|
18
22
|
return props.setFilters((prev) => prev.filter((x) => x.id !== id));
|
|
19
23
|
};
|
|
20
|
-
|
|
24
|
+
const ownSorter = props.sorters.find(x => props.header.id === x.value);
|
|
25
|
+
const ariaSort = !(ownSorter === null || ownSorter === void 0 ? void 0 : ownSorter.type) ? "none" : ownSorter.type === Order.Asc ? "ascending" : "descending";
|
|
26
|
+
const label = getLabel(props.header);
|
|
27
|
+
return (_jsx(Reorder.Item, Object.assign({}, props.header.thProps, { as: "th", exit: exit, initial: false, dragSnapToOrigin: true, dragDirectionLock: true, role: "columnheader", value: props.header, whileDrag: whileDrag, "aria-sort": ariaSort, "aria-busy": props.loading, animate: targetTransitionAnimate, className: `hidden font-medium px-2 py-4 first:table-cell md:table-cell ${(_b = (_a = props.header.thProps) === null || _a === void 0 ? void 0 : _a.className) !== null && _b !== void 0 ? _b : ""}`, children: _jsx("span", { className: "flex items-center justify-between", children: _jsxs("span", { className: "flex items-center gap-1", children: [_jsx(Dropdown, { arrow: true, trigger: _jsxs("span", { children: [_jsxs("span", { id: `${props.header.id}-filter-dropdown-button`, className: "sr-only", children: [translation.tableFilterDropdownTitleUnique, " ", label] }), _jsx(FilterIcon, { "aria-labelledby": `${props.header.id}-filter-dropdown-button`, size: 14 })] }), title: _jsxs("span", { children: [translation.tableFilterDropdownTitleUnique, " ", _jsx("span", { className: "text-primary", children: label })] }), children: (ownFilters.length === 0) === null ? null : (_jsxs("ul", { className: "font-medium", children: [ownFilters.map((filter) => (_jsx("li", { className: "my-1", children: _jsx(ColumnHeaderFilter, { onDelete: onDelete, filter: filter, set: props.setFilters }) }, `thead-filter-${filter.id}`))), _jsx("li", { children: _jsxs("button", { onClick: () => props.setFilters((prev) => prev.concat(createFilterFromCol(props.header, operationOptions, operations))), type: "button", className: "text-primary flex items-center gap-1", children: [_jsx(PlusIcon, { size: 14 }), " ", translation.tableFilterNewFilter] }) })] })) }), _jsx("span", { className: "pointer-events-auto text-balance text-base", children: props.header.thead }), _jsx(SorterHead, { col: props.header, setSorters: props.setSorters, sorters: props.sorters })] }) }) })));
|
|
21
28
|
};
|
|
22
|
-
export const TableHeader = (props) => (_jsx(Reorder.Group, { as: "tr", axis: "x", drag: true, layout: true, layoutRoot: true, layoutScroll: true, initial: false, values: props.headers, onReorder: props.setCols, className: "bg-table-background border-none text-lg", children: _jsx(AnimatePresence, { children: props.headers.map((header) => (_jsx(HeaderChild, { setFilters: props.setFilters, filters: props.filters, setSorters: props.setSorters, sorters: props.sorters, header: header }, `header-child-item-${header.id}`))) }) }));
|
|
29
|
+
export const TableHeader = (props) => (_jsx(Reorder.Group, { as: "tr", role: "row", axis: "x", drag: true, layout: true, layoutRoot: true, layoutScroll: true, initial: false, values: props.headers, onReorder: props.setCols, className: "bg-table-background border-none text-lg", children: _jsx(AnimatePresence, { children: props.headers.map((header) => (_jsx(HeaderChild, { loading: props.loading, setFilters: props.setFilters, filters: props.filters, setSorters: props.setSorters, sorters: props.sorters, header: header }, `header-child-item-${header.id}`))) }) }));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-media-query.d.ts","sourceRoot":"","sources":["../../src/hooks/use-media-query.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,aAAa,UAAW,MAAM,iBAAgB,OAAO,YAkBjE,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { useLayoutEffect, useState } from "react";
|
|
2
|
+
import { isSsr } from "../lib/fns";
|
|
3
|
+
const getMatches = (query, defaultValue) => {
|
|
4
|
+
if (isSsr()) {
|
|
5
|
+
return defaultValue;
|
|
6
|
+
}
|
|
7
|
+
return window.matchMedia(query).matches;
|
|
8
|
+
};
|
|
9
|
+
export const useMediaQuery = (query, defaultValue = true) => {
|
|
10
|
+
const [matches, setMatches] = useState(defaultValue);
|
|
11
|
+
useLayoutEffect(() => {
|
|
12
|
+
const matchMedia = window.matchMedia(query);
|
|
13
|
+
const onChange = () => setMatches(getMatches(query, defaultValue));
|
|
14
|
+
onChange();
|
|
15
|
+
if (matchMedia.addListener) {
|
|
16
|
+
matchMedia.addListener(onChange);
|
|
17
|
+
return () => {
|
|
18
|
+
return matchMedia.removeListener ? matchMedia.removeListener(onChange) : undefined;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
matchMedia.addEventListener("change", onChange);
|
|
22
|
+
return () => matchMedia.removeEventListener("change", onChange);
|
|
23
|
+
}, [query]);
|
|
24
|
+
return matches;
|
|
25
|
+
};
|