@povio/ui 0.1.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/Menu/MenuItem.js +2 -1
- package/dist/components/buttons/Button/button.cva.d.ts +5 -5
- package/dist/components/buttons/Button/button.cva.js +188 -214
- package/dist/components/buttons/InlineIconButton/InlineIconButton.js +1 -1
- package/dist/components/buttons/PillButton/pillButton.cva.d.ts +2 -0
- package/dist/components/buttons/PillButton/pillButton.cva.js +227 -45
- package/dist/components/buttons/SplitButton/SplitButton.js +2 -2
- package/dist/components/buttons/TextButton/TextButton.js +1 -1
- package/dist/components/inputs/Checkbox/CheckboxCheckmark.js +2 -19
- package/dist/components/inputs/Checkbox/checkbox.cva.js +4 -0
- package/dist/components/inputs/DateTime/shared/CalendarCell.js +3 -3
- package/dist/components/inputs/DateTime/shared/CalendarSelectHeader.js +1 -1
- package/dist/components/inputs/DateTime/shared/DatePickerInput.js +1 -1
- package/dist/components/inputs/DateTime/shared/RangeCalendar.js +6 -4
- package/dist/components/inputs/File/FileUpload.js +2 -2
- package/dist/components/inputs/File/shared/FileUploadContentLoading.js +3 -3
- package/dist/components/inputs/File/shared/InputUploadContent.js +1 -2
- package/dist/components/inputs/File/shared/ProgressBar.d.ts +6 -0
- package/dist/components/inputs/File/shared/ProgressBar.js +42 -0
- package/dist/components/inputs/File/shared/inputUploadButton.cva.js +2 -2
- package/dist/components/inputs/FormField/FormFieldHeader.js +1 -1
- package/dist/components/inputs/RadioGroup/RadioGroup.js +1 -11
- package/dist/components/inputs/RadioGroup/radio.cva.js +12 -2
- package/dist/components/inputs/shared/input.cva.js +23 -17
- package/dist/components/inputs/shared/label.cva.js +9 -14
- package/dist/components/overlays/Modal/Modal.d.ts +2 -1
- package/dist/components/overlays/Modal/Modal.js +7 -3
- package/dist/components/overlays/Tooltip/tooltip.cva.js +4 -4
- package/dist/components/segment/SegmentItem.js +9 -8
- package/dist/components/shared/pagination/PaginationList.d.ts +1 -1
- package/dist/components/shared/pagination/minWidth.cva.d.ts +1 -1
- package/dist/components/status/Toast/Toast.js +2 -1
- package/dist/hooks/useFilters.d.ts +5 -1
- package/dist/hooks/useFilters.js +123 -69
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -0
- package/package.json +1 -1
- package/dist/components/inputs/File/shared/FileProgressBar.d.ts +0 -3
- package/dist/components/inputs/File/shared/FileProgressBar.js +0 -32
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { mergeRefs } from "@react-aria/utils";
|
|
3
|
-
import { clsx } from "clsx";
|
|
4
3
|
import { RadioGroup as RadioGroup$1, Radio } from "react-aria-components";
|
|
5
4
|
import { Controller } from "react-hook-form";
|
|
6
5
|
import { FormField } from "../FormField/FormField.js";
|
|
@@ -62,16 +61,7 @@ const RadioGroupBase = (props) => {
|
|
|
62
61
|
className: radioCva({
|
|
63
62
|
variant,
|
|
64
63
|
...rest
|
|
65
|
-
})
|
|
66
|
-
children: /* @__PURE__ */ jsx(
|
|
67
|
-
"div",
|
|
68
|
-
{
|
|
69
|
-
className: clsx(
|
|
70
|
-
"absolute hidden size-1 rounded-full group-selected:block",
|
|
71
|
-
"bg-interactive-contained-primary-on-idle group-hover:bg-interactive-contained-primary-on-hover"
|
|
72
|
-
)
|
|
73
|
-
}
|
|
74
|
-
)
|
|
64
|
+
})
|
|
75
65
|
}
|
|
76
66
|
),
|
|
77
67
|
/* @__PURE__ */ jsx(CheckContent, { typography: radioTypographyMap({ variant, ...rest }), children: option.label })
|
|
@@ -2,7 +2,12 @@ import { cva } from "class-variance-authority";
|
|
|
2
2
|
import { uiGroupOutlineClass } from "../../outline.clsx.js";
|
|
3
3
|
import { compoundMapper } from "../../../utils/compoundMapper.js";
|
|
4
4
|
const radio = cva(
|
|
5
|
-
[
|
|
5
|
+
[
|
|
6
|
+
"flex items-center justify-center border-2",
|
|
7
|
+
"relative size-3-5 rounded-full p-1-5",
|
|
8
|
+
"before:absolute before:hidden before:size-1 before:rounded-full",
|
|
9
|
+
uiGroupOutlineClass
|
|
10
|
+
],
|
|
6
11
|
{
|
|
7
12
|
variants: {
|
|
8
13
|
variant: {
|
|
@@ -17,6 +22,8 @@ const radio = cva(
|
|
|
17
22
|
"group-selected:group-hover:border-interactive-contained-primary-hover",
|
|
18
23
|
"group-selected:group-pressed:bg-interactive-contained-primary-pressed",
|
|
19
24
|
"group-selected:group-pressed:border-interactive-contained-primary-pressed",
|
|
25
|
+
"group-selected:group-disabled:bg-interactive-contained-primary-disabled",
|
|
26
|
+
"group-selected:group-disabled:border-interactive-contained-primary-disabled",
|
|
20
27
|
"group-indeterminate:border-interactive-contained-primary-idle",
|
|
21
28
|
"group-indeterminate:bg-interactive-contained-primary-idle",
|
|
22
29
|
"group-indeterminate:group-hover:bg-interactive-contained-primary-hover",
|
|
@@ -24,7 +31,10 @@ const radio = cva(
|
|
|
24
31
|
"group-indeterminate:group-pressed:bg-interactive-contained-primary-pressed",
|
|
25
32
|
"group-indeterminate:group-pressed:border-interactive-contained-primary-pressed",
|
|
26
33
|
"group-invalid:border-interactive-contained-error-idle",
|
|
27
|
-
"group-focus-visible:outline-interactive-contained-primary-focus"
|
|
34
|
+
"group-focus-visible:outline-interactive-contained-primary-focus",
|
|
35
|
+
"before:bg-interactive-contained-primary-on-idle",
|
|
36
|
+
"group-hover:before:bg-interactive-contained-primary-on-hover",
|
|
37
|
+
"group-selected:before:block"
|
|
28
38
|
]
|
|
29
39
|
}
|
|
30
40
|
},
|
|
@@ -10,7 +10,13 @@ const inputBase = cva([uiOutlineClass, "flex w-full truncate"], {
|
|
|
10
10
|
},
|
|
11
11
|
as: {
|
|
12
12
|
default: "rounded-input-rounding-default",
|
|
13
|
-
floating:
|
|
13
|
+
floating: [
|
|
14
|
+
"rounded-input-rounding-default",
|
|
15
|
+
"py-floating-label-input-height-empty!",
|
|
16
|
+
"group-has-[input:not(:placeholder-shown)]/input-content:pb-floating-label-input-height-filled!",
|
|
17
|
+
"group-has-[input:not(:placeholder-shown)]/input-content:pt-[calc(var(--spacing-input-height-default)+14px)]!"
|
|
18
|
+
// TODO: remove this hardcoded value
|
|
19
|
+
],
|
|
14
20
|
filter: "rounded-input-rounding-default",
|
|
15
21
|
inline: [
|
|
16
22
|
"h-full",
|
|
@@ -110,10 +116,10 @@ const inputBase = cva([uiOutlineClass, "flex w-full truncate"], {
|
|
|
110
116
|
const inputSize = cva("", {
|
|
111
117
|
variants: {
|
|
112
118
|
size: {
|
|
113
|
-
"extra-small": "px-input-side-
|
|
114
|
-
small: "px-input-side-
|
|
115
|
-
default: "px-input-side-
|
|
116
|
-
large: "px-input-side-
|
|
119
|
+
"extra-small": "px-input-side-default py-input-height-default text-label-1",
|
|
120
|
+
small: "px-input-side-default py-input-height-default text-label-1",
|
|
121
|
+
default: "px-input-side-default py-input-height-default text-label-1",
|
|
122
|
+
large: "px-input-side-default py-input-height-default text-label-1"
|
|
117
123
|
}
|
|
118
124
|
},
|
|
119
125
|
defaultVariants: {
|
|
@@ -135,18 +141,18 @@ const inputSide = cva("", {
|
|
|
135
141
|
}
|
|
136
142
|
},
|
|
137
143
|
compoundVariants: [
|
|
138
|
-
{ type: "left", size: "extra-small", className: "left-input-side-
|
|
139
|
-
{ type: "right", size: "extra-small", className: "right-input-side-
|
|
140
|
-
{ type: "var", size: "extra-small", className: "--spacing-input-side-
|
|
141
|
-
{ type: "left", size: "small", className: "left-input-side-
|
|
142
|
-
{ type: "right", size: "small", className: "right-input-side-
|
|
143
|
-
{ type: "var", size: "small", className: "--spacing-input-side-
|
|
144
|
-
{ type: "left", size: "default", className: "left-input-side-
|
|
145
|
-
{ type: "right", size: "default", className: "right-input-side-
|
|
146
|
-
{ type: "var", size: "default", className: "--spacing-input-side-
|
|
147
|
-
{ type: "left", size: "large", className: "left-input-side-
|
|
148
|
-
{ type: "right", size: "large", className: "right-input-side-
|
|
149
|
-
{ type: "var", size: "large", className: "--spacing-input-side-
|
|
144
|
+
{ type: "left", size: "extra-small", className: "left-input-side-default" },
|
|
145
|
+
{ type: "right", size: "extra-small", className: "right-input-side-default" },
|
|
146
|
+
{ type: "var", size: "extra-small", className: "--spacing-input-side-default" },
|
|
147
|
+
{ type: "left", size: "small", className: "left-input-side-default" },
|
|
148
|
+
{ type: "right", size: "small", className: "right-input-side-default" },
|
|
149
|
+
{ type: "var", size: "small", className: "--spacing-input-side-default" },
|
|
150
|
+
{ type: "left", size: "default", className: "left-input-side-default" },
|
|
151
|
+
{ type: "right", size: "default", className: "right-input-side-default" },
|
|
152
|
+
{ type: "var", size: "default", className: "--spacing-input-side-default" },
|
|
153
|
+
{ type: "left", size: "large", className: "left-input-side-default" },
|
|
154
|
+
{ type: "right", size: "large", className: "right-input-side-default" },
|
|
155
|
+
{ type: "var", size: "large", className: "--spacing-input-side-default" }
|
|
150
156
|
],
|
|
151
157
|
defaultVariants: {
|
|
152
158
|
size: "default"
|
|
@@ -7,6 +7,7 @@ const labelBase = cva("text-text-default-1", {
|
|
|
7
7
|
filter: ["-translate-y-1/2 absolute top-1/2"],
|
|
8
8
|
inline: ["flex items-start gap-1"],
|
|
9
9
|
floating: [
|
|
10
|
+
"pointer-events-none",
|
|
10
11
|
"absolute transition-all duration-75",
|
|
11
12
|
"-translate-y-1/2 top-1/2",
|
|
12
13
|
"text-text-default-2 group-has-[input:disabled]/input-content:text-interactive-text-secondary-disabled",
|
|
@@ -19,17 +20,11 @@ const labelBase = cva("text-text-default-1", {
|
|
|
19
20
|
// TextEditor default positioning
|
|
20
21
|
"group-data-[text-editor]/text-editor:top-5 group-data-[text-editor]/text-editor:left-2 group-data-[text-editor]/text-editor:translate-y-0",
|
|
21
22
|
// Text and Number Input
|
|
22
|
-
"group-
|
|
23
|
-
"group-focus-within/input-content:top-1 group-focus-within/input-content:translate-y-0",
|
|
24
|
-
"group-has-[input:not(:placeholder-shown)]/input-content:top-1 group-has-[input:not(:placeholder-shown)]/input-content:translate-y-0",
|
|
23
|
+
"group-has-[input:not(:placeholder-shown)]/input-content:top-floating-label-input-height-filled group-has-[input:not(:placeholder-shown)]/input-content:translate-y-0",
|
|
25
24
|
// TextArea
|
|
26
|
-
"group-
|
|
27
|
-
"group-focus-within/text-area:top-1 group-focus-within/text-area:translate-y-0",
|
|
28
|
-
"group-has-[textarea:not(:placeholder-shown)]/text-area:top-1 group-has-[textarea:not(:placeholder-shown)]/text-area:translate-y-0",
|
|
25
|
+
"group-has-[textarea:not(:placeholder-shown)]/text-area:top-floating-label-input-height-filled group-has-[textarea:not(:placeholder-shown)]/text-area:translate-y-0",
|
|
29
26
|
// TextEditor
|
|
30
|
-
"group-
|
|
31
|
-
"group-focus-within/text-editor:top-1 group-focus-within/text-editor:translate-y-0",
|
|
32
|
-
"group-data-[is-filled=true]/text-editor:top-1 group-data-[is-filled=true]/text-editor:translate-y-0",
|
|
27
|
+
"group-data-[is-filled=true]/text-editor:top-floating-label-input-height-filled group-data-[is-filled=true]/text-editor:translate-y-0",
|
|
33
28
|
// Date and Time Picker
|
|
34
29
|
"group-data-[has-selection]/date-picker-content:top-1 group-data-[has-selection]/date-picker-content:translate-y-0",
|
|
35
30
|
"group-focus-within/date-picker-content:top-1 group-focus-within/date-picker-content:translate-y-0",
|
|
@@ -40,12 +35,12 @@ const labelBase = cva("text-text-default-1", {
|
|
|
40
35
|
// Text and Number Input
|
|
41
36
|
"group-has-[input:placeholder-shown]/input-content:text-text-default-3",
|
|
42
37
|
"group-has-[input:placeholder-shown]/input-content:!font-medium",
|
|
43
|
-
"group-has-[input:not(placeholder-shown)]/input-content:!font-semibold",
|
|
38
|
+
"group-has-[input:not(:placeholder-shown)]/input-content:!font-semibold",
|
|
44
39
|
"group-has-[input:not(:placeholder-shown)]/input-content:!text-label-3",
|
|
45
|
-
"group-has-[input:not(placeholder-shown)]/input-content:text-text-default-1",
|
|
46
|
-
"group-focus-within/input-content:!text-text-default-1",
|
|
47
|
-
"group-focus-within/input-content:text-label-3",
|
|
48
|
-
"group-has-[input:focus-within]/input-content:!font-semibold",
|
|
40
|
+
"group-has-[input:not(:placeholder-shown)]/input-content:text-text-default-1",
|
|
41
|
+
// "group-focus-within/input-content:!text-text-default-1",
|
|
42
|
+
// "group-focus-within/input-content:text-label-3",
|
|
43
|
+
// "group-has-[input:focus-within]/input-content:!font-semibold",
|
|
49
44
|
// TextArea
|
|
50
45
|
"group-has-[textarea:placeholder-shown]/text-area:text-text-default-3",
|
|
51
46
|
"group-has-[textarea:placeholder-shown]/text-area:!font-medium",
|
|
@@ -5,7 +5,8 @@ export interface ModalProps extends ModalVariantProps {
|
|
|
5
5
|
portalContainerRef?: RefObject<HTMLElement>;
|
|
6
6
|
onClose: () => void;
|
|
7
7
|
modalClassName?: string;
|
|
8
|
+
closeIconClassName?: string;
|
|
8
9
|
showCloseIcon?: boolean;
|
|
9
10
|
isDismissable?: boolean;
|
|
10
11
|
}
|
|
11
|
-
export declare const Modal: ({ isOpen, portalContainerRef, onClose, aside, children, modalClassName, showCloseIcon, isDismissable, }: PropsWithChildren<ModalProps>) => import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
export declare const Modal: ({ isOpen, portalContainerRef, onClose, aside, children, modalClassName, closeIconClassName, showCloseIcon, isDismissable, }: PropsWithChildren<ModalProps>) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -4,7 +4,7 @@ import { ModalOverlay, Modal as Modal$1, Dialog } from "react-aria-components";
|
|
|
4
4
|
import { useTranslation } from "react-i18next";
|
|
5
5
|
import { CloseIcon } from "../../../assets/icons/Close.js";
|
|
6
6
|
import { InlineIconButton } from "../../buttons/InlineIconButton/InlineIconButton.js";
|
|
7
|
-
import { modalOverlay,
|
|
7
|
+
import { modalOverlay, modalMain, modalContent } from "./modal.cva.js";
|
|
8
8
|
import { ns } from "../../../config/i18n.js";
|
|
9
9
|
const Modal = ({
|
|
10
10
|
isOpen,
|
|
@@ -13,6 +13,7 @@ const Modal = ({
|
|
|
13
13
|
aside,
|
|
14
14
|
children,
|
|
15
15
|
modalClassName,
|
|
16
|
+
closeIconClassName,
|
|
16
17
|
showCloseIcon,
|
|
17
18
|
isDismissable = true
|
|
18
19
|
}) => {
|
|
@@ -32,14 +33,17 @@ const Modal = ({
|
|
|
32
33
|
onClose();
|
|
33
34
|
}
|
|
34
35
|
},
|
|
35
|
-
children: /* @__PURE__ */ jsx(Modal$1, { className:
|
|
36
|
+
children: /* @__PURE__ */ jsx(Modal$1, { className: modalMain({ aside }), children: /* @__PURE__ */ jsxs(Dialog, { className: modalContent({ aside, className: modalClassName }), children: [
|
|
36
37
|
showCloseIcon && /* @__PURE__ */ jsx(
|
|
37
38
|
InlineIconButton,
|
|
38
39
|
{
|
|
39
40
|
color: "secondary",
|
|
40
41
|
onPress: onClose,
|
|
41
42
|
icon: CloseIcon,
|
|
42
|
-
className:
|
|
43
|
+
className: clsx(
|
|
44
|
+
"absolute top-0 right-0 p-modal-gap-desktop-modal-close-icon-top-right",
|
|
45
|
+
closeIconClassName
|
|
46
|
+
),
|
|
43
47
|
label: t(($) => $.ui.modal.closeBtn)
|
|
44
48
|
}
|
|
45
49
|
),
|
|
@@ -5,7 +5,7 @@ const tooltipCva = cva(
|
|
|
5
5
|
variants: {
|
|
6
6
|
color: {
|
|
7
7
|
default: ["bg-interactive-contained-secondary-idle"],
|
|
8
|
-
error: ["w-max bg-
|
|
8
|
+
error: ["w-max bg-elevation-fill-error-1"]
|
|
9
9
|
}
|
|
10
10
|
},
|
|
11
11
|
defaultVariants: {
|
|
@@ -19,7 +19,7 @@ const tooltipPointerHorizontalCva = cva(
|
|
|
19
19
|
variants: {
|
|
20
20
|
color: {
|
|
21
21
|
default: ["text-interactive-contained-secondary-idle"],
|
|
22
|
-
error: ["text-
|
|
22
|
+
error: ["text-elevation-fill-error-1"]
|
|
23
23
|
}
|
|
24
24
|
},
|
|
25
25
|
defaultVariants: {
|
|
@@ -33,7 +33,7 @@ const tooltipPointerVerticalCva = cva(
|
|
|
33
33
|
variants: {
|
|
34
34
|
color: {
|
|
35
35
|
default: ["text-interactive-contained-secondary-idle"],
|
|
36
|
-
error: ["text-
|
|
36
|
+
error: ["text-elevation-fill-error-1"]
|
|
37
37
|
}
|
|
38
38
|
},
|
|
39
39
|
defaultVariants: {
|
|
@@ -45,7 +45,7 @@ const tooltipTextCva = cva([], {
|
|
|
45
45
|
variants: {
|
|
46
46
|
color: {
|
|
47
47
|
default: ["text-text-inverted-3"],
|
|
48
|
-
error: ["text-
|
|
48
|
+
error: ["text-text-error-inverted-1"]
|
|
49
49
|
}
|
|
50
50
|
},
|
|
51
51
|
defaultVariants: {
|
|
@@ -11,16 +11,17 @@ const SegmentItem = ({ label, icon, id, isDisabled, ...props }) => {
|
|
|
11
11
|
...props,
|
|
12
12
|
id,
|
|
13
13
|
className: clsx(
|
|
14
|
-
"flex items-center justify-center gap-
|
|
15
|
-
"border border-transparent",
|
|
14
|
+
"flex items-center justify-center gap-segmented-control-gap-content-icon-to-text transition-all duration-200",
|
|
15
|
+
"border border-support-transparent-outline",
|
|
16
16
|
"py-segmented-control-height-segment",
|
|
17
|
-
iconOnly ? "px-segmented-control-height-segment" : "px-segmented-control-side-segment
|
|
17
|
+
iconOnly ? "px-segmented-control-height-segment" : "px-segmented-control-side-segment",
|
|
18
18
|
"rounded-segmented-control-rounding-segment",
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"disabled:
|
|
23
|
-
"selected:
|
|
19
|
+
"text-interactive-subtle-secondary-on-idle",
|
|
20
|
+
"hover:border-interactive-subtle-secondary-hover hover:bg-interactive-subtle-secondary-hover hover:text-interactive-subtle-secondary-on-hover",
|
|
21
|
+
"pressed:border-interactive-subtle-secondary-pressed pressed:bg-interactive-subtle-secondary-pressed pressed:text-interactive-subtle-secondary-on-pressed",
|
|
22
|
+
"disabled:border-support-transparent-outline disabled:text-interactive-subtle-secondary-on-disabled",
|
|
23
|
+
"selected:border-interactive-subtle-secondary-toggled-idle selected:bg-interactive-subtle-secondary-toggled-idle selected:text-interactive-subtle-secondary-on-toggled-idle",
|
|
24
|
+
"selected:disabled:border-interactive-subtle-secondary-toggled-disabled selected:disabled:bg-interactive-subtle-secondary-toggled-disabled selected:disabled:text-interactive-subtle-secondary-on-toggled-disabled"
|
|
24
25
|
),
|
|
25
26
|
isDisabled,
|
|
26
27
|
children: [
|
|
@@ -6,7 +6,7 @@ export interface PaginationListProps {
|
|
|
6
6
|
hideFirstLast?: boolean;
|
|
7
7
|
hidePrevNext?: boolean;
|
|
8
8
|
hideNumbers?: boolean;
|
|
9
|
-
size?: ButtonProps["size"]
|
|
9
|
+
size?: Exclude<ButtonProps["size"], "none">;
|
|
10
10
|
color?: ButtonProps["color"];
|
|
11
11
|
variant?: ButtonProps["variant"];
|
|
12
12
|
className?: string;
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
type FilterValue = string | string[] | boolean | number;
|
|
1
3
|
export interface FilterStore<TFilterData> {
|
|
2
4
|
filterData: TFilterData;
|
|
3
5
|
setFilterValue: (data: Partial<TFilterData>) => void;
|
|
4
6
|
getFilterValue: (keys: (keyof TFilterData)[]) => Partial<TFilterData>;
|
|
5
7
|
clearAllFilters: () => void;
|
|
6
8
|
}
|
|
7
|
-
export declare
|
|
9
|
+
export declare function parseFilterFromQuery(query: Record<string, any>, schema?: z.ZodObject<any>): Record<string, FilterValue>;
|
|
10
|
+
export declare function useFilters<TFilterData>(defaultFilterValues?: TFilterData, prefix?: string, schema?: z.ZodObject<any>): FilterStore<TFilterData>;
|
|
11
|
+
export {};
|
package/dist/hooks/useFilters.js
CHANGED
|
@@ -1,107 +1,160 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
1
|
+
import { useNavigate, useLocation } from "@tanstack/react-router";
|
|
2
|
+
import { useMemo, useRef, useState, useEffect } from "react";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
function getFieldType(schema, fieldKey) {
|
|
5
|
+
if (!schema || !schema.shape) return "unknown";
|
|
6
|
+
let fieldSchema = schema.shape[fieldKey];
|
|
7
|
+
while (fieldSchema) {
|
|
8
|
+
if (fieldSchema instanceof z.ZodOptional || fieldSchema instanceof z.ZodNullable) {
|
|
9
|
+
fieldSchema = fieldSchema.unwrap();
|
|
10
|
+
} else {
|
|
11
|
+
break;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
if (!fieldSchema) return "unknown";
|
|
15
|
+
if (fieldSchema instanceof z.ZodNumber) return "number";
|
|
16
|
+
if (fieldSchema instanceof z.ZodBoolean) return "boolean";
|
|
17
|
+
if (fieldSchema instanceof z.ZodString) return "string";
|
|
18
|
+
return "unknown";
|
|
19
|
+
}
|
|
20
|
+
function serializeFiltersToQuery(filterData, prefix) {
|
|
4
21
|
const query = {};
|
|
5
22
|
for (const [key, value] of Object.entries(filterData)) {
|
|
6
23
|
if (value === null || value === void 0) {
|
|
7
24
|
continue;
|
|
8
25
|
}
|
|
9
|
-
const filterKey = `filter[${prefix && `${prefix}-`}${key}]`;
|
|
10
26
|
if (Array.isArray(value) || typeof value === "object") {
|
|
11
|
-
query[
|
|
27
|
+
query[`filter[${prefix && `${prefix}-`}${key}]`] = JSON.stringify(value);
|
|
12
28
|
} else if (typeof value === "boolean") {
|
|
13
|
-
query[
|
|
29
|
+
query[`filter[${prefix && `${prefix}-`}${key}]`] = value ? "true" : "false";
|
|
30
|
+
} else if (typeof value === "number") {
|
|
31
|
+
query[`filter[${prefix && `${prefix}-`}${key}]`] = value.toString();
|
|
14
32
|
} else {
|
|
15
|
-
query[
|
|
33
|
+
query[`filter[${prefix && `${prefix}-`}${key}]`] = value;
|
|
16
34
|
}
|
|
17
35
|
}
|
|
18
36
|
return query;
|
|
19
|
-
}
|
|
20
|
-
|
|
37
|
+
}
|
|
38
|
+
function parseFilterFromQuery(query, schema) {
|
|
21
39
|
const filter = {};
|
|
22
40
|
for (const [key, value] of Object.entries(query)) {
|
|
23
|
-
const match = /^filter\[(.+?)\]
|
|
24
|
-
if (
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
41
|
+
const match = key.match(/^filter\[(.+?)\]$/);
|
|
42
|
+
if (match) {
|
|
43
|
+
const filterKey = match[1];
|
|
44
|
+
const baseKey = filterKey.includes("-") ? filterKey.split("-").pop() || filterKey : filterKey;
|
|
45
|
+
if (value.startsWith("[") && value.endsWith("]") || value.startsWith("{") && value.endsWith("}")) {
|
|
46
|
+
filter[filterKey] = JSON.parse(value);
|
|
47
|
+
} else if (["true", "false"].includes(value)) {
|
|
48
|
+
filter[filterKey] = value === "true";
|
|
49
|
+
} else {
|
|
50
|
+
const expectedType = getFieldType(schema, baseKey);
|
|
51
|
+
if (expectedType === "number" && !Number.isNaN(Number(value)) && value !== "" && value !== null) {
|
|
52
|
+
filter[filterKey] = Number(value);
|
|
53
|
+
} else if (expectedType === "boolean" && ["true", "false"].includes(value)) {
|
|
54
|
+
filter[filterKey] = value === "true";
|
|
55
|
+
} else {
|
|
56
|
+
filter[filterKey] = value;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
38
59
|
}
|
|
39
60
|
}
|
|
40
61
|
return filter;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const
|
|
44
|
-
const
|
|
62
|
+
}
|
|
63
|
+
function useFilters(defaultFilterValues, prefix = "", schema) {
|
|
64
|
+
const navigate = useNavigate();
|
|
65
|
+
const location = useLocation();
|
|
66
|
+
const queryObject = useMemo(
|
|
67
|
+
() => Object.fromEntries(new URLSearchParams(location.searchStr || "").entries()),
|
|
68
|
+
[location.searchStr]
|
|
69
|
+
);
|
|
70
|
+
const hasAppliedDefaultsRef = useRef(false);
|
|
71
|
+
const lastPathnameRef = useRef(location.pathname);
|
|
72
|
+
const queryFilters = parseFilterFromQuery(queryObject, schema);
|
|
45
73
|
const [filterData, setFilterData] = useState(queryFilters);
|
|
46
74
|
useEffect(() => {
|
|
47
|
-
|
|
75
|
+
if (lastPathnameRef.current !== location.pathname) {
|
|
76
|
+
hasAppliedDefaultsRef.current = false;
|
|
77
|
+
lastPathnameRef.current = location.pathname;
|
|
78
|
+
}
|
|
79
|
+
}, [location.pathname]);
|
|
80
|
+
useEffect(() => {
|
|
81
|
+
const currentQueryObject = Object.fromEntries(new URLSearchParams(location.searchStr || "").entries());
|
|
82
|
+
const currentFilters = parseFilterFromQuery(currentQueryObject, schema);
|
|
83
|
+
const shouldApplyDefaults = defaultFilterValues && Object.keys(currentFilters).length === 0 && !hasAppliedDefaultsRef.current;
|
|
84
|
+
if (shouldApplyDefaults) {
|
|
48
85
|
const flatFilterQuery = serializeFiltersToQuery(defaultFilterValues, prefix);
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
86
|
+
const sp = new URLSearchParams(location.searchStr || "");
|
|
87
|
+
let needsNavigation = false;
|
|
88
|
+
Object.entries(flatFilterQuery).forEach(([k, v]) => {
|
|
89
|
+
const currentValue = sp.get(k);
|
|
90
|
+
if (Array.isArray(v)) {
|
|
91
|
+
const currentValues = sp.getAll(k);
|
|
92
|
+
if (JSON.stringify(currentValues.sort()) !== JSON.stringify(v.sort())) {
|
|
93
|
+
needsNavigation = true;
|
|
94
|
+
}
|
|
95
|
+
} else {
|
|
96
|
+
if (currentValue !== v) {
|
|
97
|
+
needsNavigation = true;
|
|
98
|
+
}
|
|
54
99
|
}
|
|
55
100
|
});
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
101
|
+
if (needsNavigation) {
|
|
102
|
+
Object.entries(flatFilterQuery).forEach(([k, v]) => {
|
|
103
|
+
sp.delete(k);
|
|
104
|
+
if (Array.isArray(v)) {
|
|
105
|
+
v.forEach((val) => sp.append(k, val));
|
|
106
|
+
} else {
|
|
107
|
+
sp.set(k, v);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
const to = `${location.pathname}${sp.toString() ? `?${sp.toString()}` : ""}`;
|
|
111
|
+
navigate({ to, replace: true });
|
|
112
|
+
}
|
|
113
|
+
hasAppliedDefaultsRef.current = true;
|
|
61
114
|
}
|
|
62
|
-
}, [defaultFilterValues, prefix]);
|
|
115
|
+
}, [defaultFilterValues, prefix, location.pathname, location.searchStr]);
|
|
63
116
|
useEffect(() => {
|
|
64
|
-
const newQueryFilters = parseFilterFromQuery(
|
|
117
|
+
const newQueryFilters = parseFilterFromQuery(queryObject, schema);
|
|
65
118
|
setFilterData(newQueryFilters);
|
|
66
|
-
}, [
|
|
119
|
+
}, [queryObject, schema]);
|
|
67
120
|
const setFilterValue = (data) => {
|
|
68
|
-
|
|
121
|
+
const next = { ...filterData };
|
|
69
122
|
const isReset = Object.keys(data).length === 0;
|
|
70
123
|
const isResetToDefault = data === defaultFilterValues;
|
|
71
124
|
if (isResetToDefault) {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
} else {
|
|
125
|
+
Object.keys(next).forEach((key) => delete next[key]);
|
|
126
|
+
Object.entries(defaultFilterValues ?? {}).forEach(([key, value]) => {
|
|
127
|
+
next[key] = value;
|
|
128
|
+
});
|
|
129
|
+
} else if (!isReset) {
|
|
78
130
|
Object.entries(data).forEach(([key, value]) => {
|
|
79
131
|
if (value === void 0) {
|
|
80
|
-
delete
|
|
132
|
+
delete next[key];
|
|
81
133
|
} else {
|
|
82
|
-
|
|
134
|
+
next[key] = value;
|
|
83
135
|
}
|
|
84
136
|
});
|
|
137
|
+
} else {
|
|
138
|
+
Object.keys(next).forEach((key) => delete next[key]);
|
|
85
139
|
}
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
(
|
|
89
|
-
|
|
90
|
-
acc[k] = query[k];
|
|
91
|
-
}
|
|
92
|
-
return acc;
|
|
93
|
-
},
|
|
94
|
-
{}
|
|
95
|
-
);
|
|
96
|
-
const flatFilterQuery = serializeFiltersToQuery(newFilters, prefix);
|
|
97
|
-
replace({
|
|
98
|
-
pathname,
|
|
99
|
-
query: {
|
|
100
|
-
...cleanedQuery,
|
|
101
|
-
...flatFilterQuery
|
|
140
|
+
const sp = new URLSearchParams(location.searchStr || "");
|
|
141
|
+
Array.from(sp.keys()).forEach((key) => {
|
|
142
|
+
if (key.startsWith(`filter[${prefix && `${prefix}-`}`)) {
|
|
143
|
+
sp.delete(key);
|
|
102
144
|
}
|
|
103
145
|
});
|
|
104
|
-
|
|
146
|
+
const flatFilterQuery = serializeFiltersToQuery(next, prefix);
|
|
147
|
+
Object.entries(flatFilterQuery).forEach(([k, v]) => {
|
|
148
|
+
sp.delete(k);
|
|
149
|
+
if (Array.isArray(v)) {
|
|
150
|
+
v.forEach((val) => sp.append(k, val));
|
|
151
|
+
} else {
|
|
152
|
+
sp.set(k, v);
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
const to = `${location.pathname}${sp.toString() ? `?${sp.toString()}` : ""}`;
|
|
156
|
+
navigate({ to, replace: true });
|
|
157
|
+
setFilterData(next);
|
|
105
158
|
};
|
|
106
159
|
const getFilterValue = (keys) => {
|
|
107
160
|
const result = {};
|
|
@@ -114,7 +167,8 @@ const useFilters = (defaultFilterValues, prefix = "") => {
|
|
|
114
167
|
setFilterValue(defaultFilterValues ?? {});
|
|
115
168
|
};
|
|
116
169
|
return { filterData, setFilterValue, getFilterValue, clearAllFilters };
|
|
117
|
-
}
|
|
170
|
+
}
|
|
118
171
|
export {
|
|
172
|
+
parseFilterFromQuery,
|
|
119
173
|
useFilters
|
|
120
174
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -69,6 +69,7 @@ export type { FileUploadContainerProps } from './components/inputs/File/FileUplo
|
|
|
69
69
|
export { FileUploadContainer } from './components/inputs/File/FileUploadContainer';
|
|
70
70
|
export type { InputUploadProps } from './components/inputs/File/InputUpload';
|
|
71
71
|
export { InputUpload } from './components/inputs/File/InputUpload';
|
|
72
|
+
export { ProgressBar } from './components/inputs/File/shared/ProgressBar';
|
|
72
73
|
export type { FormFieldProps } from './components/inputs/FormField/FormField';
|
|
73
74
|
export { FormField } from './components/inputs/FormField/FormField';
|
|
74
75
|
export type { ControlledNumberInputProps, NumberInputProps } from './components/inputs/Input/NumberInput/NumberInput';
|
package/dist/index.js
CHANGED
|
@@ -51,6 +51,7 @@ import { TimePicker } from "./components/inputs/DateTime/TimePicker/TimePicker.j
|
|
|
51
51
|
import { FileUpload } from "./components/inputs/File/FileUpload.js";
|
|
52
52
|
import { FileUploadContainer } from "./components/inputs/File/FileUploadContainer.js";
|
|
53
53
|
import { InputUpload } from "./components/inputs/File/InputUpload.js";
|
|
54
|
+
import { ProgressBar } from "./components/inputs/File/shared/ProgressBar.js";
|
|
54
55
|
import { FormField } from "./components/inputs/FormField/FormField.js";
|
|
55
56
|
import { NumberInput } from "./components/inputs/Input/NumberInput/NumberInput.js";
|
|
56
57
|
import { PasswordInput } from "./components/inputs/Input/PasswordInput/PasswordInput.js";
|
|
@@ -216,6 +217,7 @@ export {
|
|
|
216
217
|
PillButton,
|
|
217
218
|
PointerHorizontalIcon,
|
|
218
219
|
PointerVerticalIcon,
|
|
220
|
+
ProgressBar,
|
|
219
221
|
QueriesUtils,
|
|
220
222
|
QueryAutocomplete,
|
|
221
223
|
RadioGroup,
|
package/package.json
CHANGED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
-
import { Typography } from "../../../text/Typography/Typography.js";
|
|
3
|
-
const FileProgressBar = ({ progress = 0 }) => {
|
|
4
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex w-full items-center justify-center gap-file-upload-content-gap-progress-actions", children: [
|
|
5
|
-
/* @__PURE__ */ jsx("div", { className: "flex flex-fill flex-col items-start gap-2 py-progress-height-height", children: /* @__PURE__ */ jsxs("div", { className: "relative h-1 w-full", children: [
|
|
6
|
-
/* @__PURE__ */ jsx("div", { className: "h-1 w-full flex-shrink-0 rounded-xs bg-input-filled-idle" }),
|
|
7
|
-
/* @__PURE__ */ jsx(
|
|
8
|
-
"div",
|
|
9
|
-
{
|
|
10
|
-
className: "absolute top-0 left-0 h-1 flex-shrink-0 rounded-xs bg-interactive-contained-primary-idle transition-all duration-300",
|
|
11
|
-
style: { width: `${progress}%` }
|
|
12
|
-
}
|
|
13
|
-
)
|
|
14
|
-
] }) }),
|
|
15
|
-
/* @__PURE__ */ jsxs(
|
|
16
|
-
Typography,
|
|
17
|
-
{
|
|
18
|
-
variant: "default",
|
|
19
|
-
size: "label-2",
|
|
20
|
-
as: "span",
|
|
21
|
-
className: "text-center text-text-default-1",
|
|
22
|
-
children: [
|
|
23
|
-
progress,
|
|
24
|
-
"%"
|
|
25
|
-
]
|
|
26
|
-
}
|
|
27
|
-
)
|
|
28
|
-
] });
|
|
29
|
-
};
|
|
30
|
-
export {
|
|
31
|
-
FileProgressBar
|
|
32
|
-
};
|