@ftdata/ui 0.0.15 → 0.0.17
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/Collapse/styles.js +2 -0
- package/dist/components/IconButton/index.d.ts +15 -0
- package/dist/components/IconButton/index.js +37 -0
- package/dist/components/IconButton/modifiers/color.d.ts +36 -0
- package/dist/components/IconButton/modifiers/color.js +38 -0
- package/dist/components/IconButton/styles.d.ts +10 -0
- package/dist/components/IconButton/styles.js +32 -0
- package/dist/components/Menu/constants/icons.d.ts +2 -16
- package/dist/components/Menu/constants/icons.js +13 -58
- package/dist/components/Menu/helpers/createMenus.js +13 -6
- package/dist/components/Menu/helpers/createSubMenus.d.ts +1 -1
- package/dist/components/Menu/helpers/createSubMenus.js +1 -1
- package/dist/components/Menu/helpers/generateColorScale.js +2 -2
- package/dist/components/Menu/helpers/getLuminance.d.ts +1 -1
- package/dist/components/Menu/helpers/getLuminance.js +2 -2
- package/dist/components/Menu/index.d.ts +1 -1
- package/dist/components/Menu/index.js +18 -31
- package/dist/components/Menu/styles.d.ts +0 -1
- package/dist/components/Menu/styles.js +29 -45
- package/dist/components/Menu/types/IconKeysType.d.ts +1 -1
- package/dist/components/Menu/types/MenuItem.d.ts +3 -2
- package/dist/components/Modal/index.d.ts +25 -0
- package/dist/components/Modal/index.js +69 -0
- package/dist/components/Modal/styles.d.ts +8 -0
- package/dist/components/Modal/styles.js +81 -0
- package/dist/components/MultiSelect/components/Badge/index.d.ts +2 -1
- package/dist/components/MultiSelect/components/Badge/index.js +5 -2
- package/dist/components/MultiSelect/components/Badge/styles.d.ts +5 -1
- package/dist/components/MultiSelect/components/Badge/styles.js +2 -1
- package/dist/components/MultiSelect/components/MultiSelectList/Row/index.d.ts +3 -2
- package/dist/components/MultiSelect/components/MultiSelectList/Row/index.js +21 -10
- package/dist/components/MultiSelect/components/MultiSelectList/Row/style.js +0 -1
- package/dist/components/MultiSelect/components/MultiSelectList/index.d.ts +3 -3
- package/dist/components/MultiSelect/components/MultiSelectList/index.js +8 -11
- package/dist/components/MultiSelect/components/MultiSelectList/style.d.ts +1 -1
- package/dist/components/MultiSelect/components/MultiSelectList/style.js +21 -3
- package/dist/components/MultiSelect/helpers/addOption.d.ts +3 -3
- package/dist/components/MultiSelect/helpers/computeUnselected.d.ts +1 -1
- package/dist/components/MultiSelect/helpers/computeUnselected.js +1 -1
- package/dist/components/MultiSelect/helpers/feedbackText.d.ts +1 -1
- package/dist/components/MultiSelect/helpers/feedbackText.js +9 -9
- package/dist/components/MultiSelect/helpers/filterOptions.d.ts +1 -1
- package/dist/components/MultiSelect/helpers/removeOptions.d.ts +3 -3
- package/dist/components/MultiSelect/index.d.ts +37 -19
- package/dist/components/MultiSelect/index.js +92 -135
- package/dist/components/MultiSelect/styles.js +8 -23
- package/dist/components/Texts/paragraphs.d.ts +12 -0
- package/dist/components/Texts/paragraphs.js +14 -0
- package/dist/components/Texts/text.d.ts +17 -0
- package/dist/components/Texts/text.js +21 -0
- package/dist/components/Texts/titles.d.ts +7 -0
- package/dist/components/Texts/titles.js +37 -0
- package/dist/components/fields/modifiers/selectColorModifier.d.ts +1 -1
- package/dist/components/fields/modifiers/selectColorModifier.js +7 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.js +4 -2
- package/package.json +3 -3
- package/dist/components/Collapse/Colapse.stories.d.ts +0 -10
- package/dist/components/Collapse/Colapse.stories.js +0 -108
- package/dist/components/Menu/Menu.stories.d.ts +0 -6
- package/dist/components/Menu/Menu.stories.js +0 -116
- package/dist/components/MultiSelect/helpers/arraysEqual.d.ts +0 -2
- package/dist/components/MultiSelect/helpers/arraysEqual.js +0 -5
- package/dist/components/MultiSelect/helpers/computeSelected.d.ts +0 -2
- package/dist/components/MultiSelect/helpers/computeSelected.js +0 -2
- package/dist/components/MultiSelect/helpers/getChangedFieds.d.ts +0 -2
- package/dist/components/MultiSelect/helpers/getChangedFieds.js +0 -17
- package/dist/components/MultiSelect/hooks/useMultiSelect.d.ts +0 -10
- package/dist/components/MultiSelect/hooks/useMultiSelect.js +0 -44
- package/dist/components/MultiSelect/interfaces/actions.d.ts +0 -4
- package/dist/components/MultiSelect/interfaces/actions.js +0 -0
- package/dist/components/MultiSelect/interfaces/config.d.ts +0 -17
- package/dist/components/MultiSelect/interfaces/config.js +0 -0
- package/dist/components/MultiSelect/interfaces/state.d.ts +0 -10
- package/dist/components/MultiSelect/interfaces/state.js +0 -0
- package/dist/components/MultiSelect/reducers/stateReducer.d.ts +0 -21
- package/dist/components/MultiSelect/reducers/stateReducer.js +0 -44
- package/dist/components/Text/Paragraph/Paragraph.stories.d.ts +0 -29
- package/dist/components/Text/Paragraph/Paragraph.stories.js +0 -124
- package/dist/components/Text/Title/Title.stories.d.ts +0 -41
- package/dist/components/Text/Title/Title.stories.js +0 -106
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { HTMLAttributes, ReactNode } from "react";
|
|
2
|
+
export type ModalSizeCustom = {
|
|
3
|
+
width: string;
|
|
4
|
+
height: string;
|
|
5
|
+
};
|
|
6
|
+
export type ModalSizes = "small" | "medium" | "large" | ModalSizeCustom;
|
|
7
|
+
export type ModalAction = {
|
|
8
|
+
onClick: () => void;
|
|
9
|
+
label: string;
|
|
10
|
+
shouldClose?: boolean;
|
|
11
|
+
disabled?: boolean;
|
|
12
|
+
};
|
|
13
|
+
export type ModalActions = {
|
|
14
|
+
primary?: ModalAction;
|
|
15
|
+
secondary?: ModalAction;
|
|
16
|
+
};
|
|
17
|
+
export interface ModalProps extends HTMLAttributes<HTMLDivElement> {
|
|
18
|
+
children: ReactNode;
|
|
19
|
+
size?: ModalSizes;
|
|
20
|
+
title?: string;
|
|
21
|
+
message?: string;
|
|
22
|
+
closeHandler: () => void;
|
|
23
|
+
actions?: ModalActions;
|
|
24
|
+
}
|
|
25
|
+
export default function Modal({ children, size, title, message, closeHandler, actions, }: ModalProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useState } from "react";
|
|
3
|
+
import { ActionsContainer, ContentContainer, ModalContainer } from "./styles.js";
|
|
4
|
+
import { Title } from "../Texts/titles.js";
|
|
5
|
+
import { Paragraph } from "../Texts/paragraphs.js";
|
|
6
|
+
import Button from "../Button/index.js";
|
|
7
|
+
import IconButton from "../IconButton/index.js";
|
|
8
|
+
function Modal({ children, size, title, message, closeHandler, actions }) {
|
|
9
|
+
const [isClosing, setIsClosing] = useState(false);
|
|
10
|
+
const handleClose = useCallback(()=>{
|
|
11
|
+
setIsClosing(true);
|
|
12
|
+
setTimeout(()=>{
|
|
13
|
+
closeHandler();
|
|
14
|
+
}, 200);
|
|
15
|
+
}, [
|
|
16
|
+
closeHandler
|
|
17
|
+
]);
|
|
18
|
+
const handleActionClick = useCallback((action)=>{
|
|
19
|
+
action.onClick();
|
|
20
|
+
if (action.shouldClose) handleClose();
|
|
21
|
+
}, [
|
|
22
|
+
handleClose
|
|
23
|
+
]);
|
|
24
|
+
return /*#__PURE__*/ jsxs(ModalContainer, {
|
|
25
|
+
size: size,
|
|
26
|
+
isClosing: isClosing,
|
|
27
|
+
children: [
|
|
28
|
+
/*#__PURE__*/ jsx(IconButton, {
|
|
29
|
+
icon: "ui delete-disabled",
|
|
30
|
+
size: "small",
|
|
31
|
+
onClick: handleClose,
|
|
32
|
+
style: {
|
|
33
|
+
position: "absolute",
|
|
34
|
+
top: "1rem",
|
|
35
|
+
right: "1rem"
|
|
36
|
+
}
|
|
37
|
+
}),
|
|
38
|
+
/*#__PURE__*/ jsxs(ContentContainer, {
|
|
39
|
+
children: [
|
|
40
|
+
title && /*#__PURE__*/ jsx(Title, {
|
|
41
|
+
as: "h2",
|
|
42
|
+
children: title
|
|
43
|
+
}),
|
|
44
|
+
message && /*#__PURE__*/ jsx(Paragraph, {
|
|
45
|
+
children: message
|
|
46
|
+
})
|
|
47
|
+
]
|
|
48
|
+
}),
|
|
49
|
+
children,
|
|
50
|
+
actions && /*#__PURE__*/ jsxs(ActionsContainer, {
|
|
51
|
+
children: [
|
|
52
|
+
actions.secondary && /*#__PURE__*/ jsx(Button, {
|
|
53
|
+
onClick: ()=>handleActionClick(actions.secondary),
|
|
54
|
+
type: "button",
|
|
55
|
+
variant: "secondary",
|
|
56
|
+
children: actions.secondary.label
|
|
57
|
+
}),
|
|
58
|
+
actions.primary && /*#__PURE__*/ jsx(Button, {
|
|
59
|
+
onClick: ()=>handleActionClick(actions.primary),
|
|
60
|
+
type: "button",
|
|
61
|
+
variant: "primary",
|
|
62
|
+
children: actions.primary.label
|
|
63
|
+
})
|
|
64
|
+
]
|
|
65
|
+
})
|
|
66
|
+
]
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
export { Modal as default };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ModalProps, ModalSizes } from '.';
|
|
2
|
+
export declare const getSize: (size?: ModalSizes) => import("styled-components").RuleSet<object> | undefined;
|
|
3
|
+
export declare const ModalOverlay: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
4
|
+
export declare const ModalContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, Partial<ModalProps> & {
|
|
5
|
+
isClosing?: boolean;
|
|
6
|
+
}>> & string;
|
|
7
|
+
export declare const ActionsContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
8
|
+
export declare const ContentContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import styled_components, { css, keyframes } from "styled-components";
|
|
2
|
+
import { COLOR_NEUTRAL_DARKER, COLOR_NEUTRAL_DAY, COLOR_NEUTRAL_DUSK } from "@ftdata/f-tokens";
|
|
3
|
+
const SIZES = {
|
|
4
|
+
small: '31.5rem',
|
|
5
|
+
medium: '42.5rem',
|
|
6
|
+
large: '53.5rem'
|
|
7
|
+
};
|
|
8
|
+
const slideIn = keyframes`
|
|
9
|
+
from {
|
|
10
|
+
opacity: 0.5;
|
|
11
|
+
transform: translateY(0.625rem) scale(0.97);
|
|
12
|
+
}
|
|
13
|
+
to {
|
|
14
|
+
opacity: 1;
|
|
15
|
+
transform: translateY(0) scale(1);
|
|
16
|
+
}
|
|
17
|
+
`;
|
|
18
|
+
const fadeOut = keyframes`
|
|
19
|
+
from {
|
|
20
|
+
opacity: 1;
|
|
21
|
+
}
|
|
22
|
+
to {
|
|
23
|
+
opacity: 0;
|
|
24
|
+
}
|
|
25
|
+
`;
|
|
26
|
+
const getSize = (size)=>{
|
|
27
|
+
if (!size) return;
|
|
28
|
+
if ('object' == typeof size) return css`
|
|
29
|
+
height: ${size.height};
|
|
30
|
+
width: ${size.width};
|
|
31
|
+
`;
|
|
32
|
+
return css`
|
|
33
|
+
width: ${SIZES[size]};
|
|
34
|
+
`;
|
|
35
|
+
};
|
|
36
|
+
const ModalOverlay = styled_components.div`
|
|
37
|
+
background-color: ${COLOR_NEUTRAL_DUSK};
|
|
38
|
+
position: fixed;
|
|
39
|
+
height: 100vh;
|
|
40
|
+
opacity: 0.32;
|
|
41
|
+
right: 0;
|
|
42
|
+
top: 0;
|
|
43
|
+
width: 100vw;
|
|
44
|
+
z-index: 999;
|
|
45
|
+
`;
|
|
46
|
+
const ModalContainer = styled_components.div`
|
|
47
|
+
display: flex;
|
|
48
|
+
position: relative;
|
|
49
|
+
padding: 2rem;
|
|
50
|
+
box-sizing: border-box;
|
|
51
|
+
border-radius: 0.5rem;
|
|
52
|
+
box-shadow: 0px 4px 8px 0px #6b757c52;
|
|
53
|
+
gap: 2rem;
|
|
54
|
+
position: relative;
|
|
55
|
+
flex-direction: column;
|
|
56
|
+
background-color: ${COLOR_NEUTRAL_DAY};
|
|
57
|
+
animation: ${({ isClosing })=>isClosing ? fadeOut : slideIn} 0.2s ease-out;
|
|
58
|
+
|
|
59
|
+
${({ size })=>getSize(size)};
|
|
60
|
+
`;
|
|
61
|
+
const ActionsContainer = styled_components.div`
|
|
62
|
+
display: flex;
|
|
63
|
+
width: 100%;
|
|
64
|
+
gap: 1rem;
|
|
65
|
+
justify-content: flex-end;
|
|
66
|
+
`;
|
|
67
|
+
const ContentContainer = styled_components.div`
|
|
68
|
+
display: flex;
|
|
69
|
+
width: 100%;
|
|
70
|
+
gap: 1.5rem;
|
|
71
|
+
flex-direction: column;
|
|
72
|
+
|
|
73
|
+
h2 {
|
|
74
|
+
color: ${COLOR_NEUTRAL_DUSK};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
p {
|
|
78
|
+
color: ${COLOR_NEUTRAL_DARKER};
|
|
79
|
+
}
|
|
80
|
+
`;
|
|
81
|
+
export { ActionsContainer, ContentContainer, ModalContainer, ModalOverlay, getSize };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
interface BadgeProps {
|
|
2
2
|
text: string;
|
|
3
3
|
remove: () => void;
|
|
4
|
+
disabled?: boolean;
|
|
4
5
|
}
|
|
5
|
-
export default function Badge({ text, remove }: BadgeProps): import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export default function Badge({ text, remove, disabled }: BadgeProps): import("react/jsx-runtime").JSX.Element;
|
|
6
7
|
export {};
|
|
@@ -2,7 +2,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { useState } from "react";
|
|
3
3
|
import { BadgeContainer } from "./styles.js";
|
|
4
4
|
import { Icon } from "@ftdata/f-icons";
|
|
5
|
-
function Badge({ text, remove }) {
|
|
5
|
+
function Badge({ text, remove, disabled }) {
|
|
6
6
|
const [isVisible, setIsVisible] = useState(true);
|
|
7
7
|
const handleRemove = ()=>{
|
|
8
8
|
setIsVisible(false);
|
|
@@ -12,12 +12,15 @@ function Badge({ text, remove }) {
|
|
|
12
12
|
};
|
|
13
13
|
return /*#__PURE__*/ jsxs(BadgeContainer, {
|
|
14
14
|
className: isVisible ? "" : "remove",
|
|
15
|
+
disabled: disabled,
|
|
16
|
+
title: text,
|
|
15
17
|
children: [
|
|
16
18
|
/*#__PURE__*/ jsx("span", {
|
|
17
19
|
children: text
|
|
18
20
|
}),
|
|
19
|
-
/*#__PURE__*/ jsx("button", {
|
|
21
|
+
!disabled && /*#__PURE__*/ jsx("button", {
|
|
20
22
|
onClick: handleRemove,
|
|
23
|
+
type: "button",
|
|
21
24
|
children: /*#__PURE__*/ jsx(Icon, {
|
|
22
25
|
name: "ui delete-disabled",
|
|
23
26
|
size: "1rem",
|
|
@@ -1 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
interface BadgeContainerProps {
|
|
2
|
+
disabled?: boolean;
|
|
3
|
+
}
|
|
4
|
+
export declare const BadgeContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, BadgeContainerProps>> & string;
|
|
5
|
+
export {};
|
|
@@ -21,7 +21,7 @@ const popOut = keyframes`
|
|
|
21
21
|
}
|
|
22
22
|
`;
|
|
23
23
|
const BadgeContainer = styled_components.div`
|
|
24
|
-
background-color: ${COLOR_NEUTRAL_LIGHTER};
|
|
24
|
+
background-color: ${({ disabled })=>disabled ? "rgba(0, 0, 0, 0.06)" : COLOR_NEUTRAL_LIGHTER};
|
|
25
25
|
border-radius: 0.25rem;
|
|
26
26
|
display: flex;
|
|
27
27
|
padding: 0.25rem 0.5rem;
|
|
@@ -29,6 +29,7 @@ const BadgeContainer = styled_components.div`
|
|
|
29
29
|
opacity: 0;
|
|
30
30
|
transform: scale(0.8);
|
|
31
31
|
animation: ${popIn} 0.15s forwards;
|
|
32
|
+
cursor: default;
|
|
32
33
|
|
|
33
34
|
&.remove {
|
|
34
35
|
animation: ${popOut} 0.15s forwards;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { type RowComponentProps } from "react-window";
|
|
2
|
-
import { IMultiSelectOption } from "
|
|
3
|
-
export default function Row({ index, style, options, onClickOption, addAll, }: RowComponentProps<{
|
|
2
|
+
import { IMultiSelectOption } from "../../..";
|
|
3
|
+
export default function Row({ index, style, options, onClickOption, addAll, translation, }: RowComponentProps<{
|
|
4
4
|
options: IMultiSelectOption[];
|
|
5
5
|
onClickOption?: (event: React.MouseEvent<HTMLDivElement>, option: IMultiSelectOption) => void;
|
|
6
6
|
addAll?: (event: React.MouseEvent<HTMLDivElement>) => void;
|
|
7
|
+
translation: (key: string) => string;
|
|
7
8
|
}>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import { jsx
|
|
2
|
-
import { OptionContainer
|
|
3
|
-
function Row({ index, style, options, onClickOption, addAll }) {
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { OptionContainer } from "./style.js";
|
|
3
|
+
function Row({ index, style, options, onClickOption, addAll, translation }) {
|
|
4
4
|
const option = options[index];
|
|
5
5
|
const hasSelectAll = "__select_all" === option.value;
|
|
6
|
+
const isLoading = "__loading__" === option.value;
|
|
6
7
|
const handleClick = (event)=>{
|
|
8
|
+
if (isLoading) return;
|
|
7
9
|
if (hasSelectAll) {
|
|
8
10
|
console.log(addAll);
|
|
9
11
|
addAll?.(event);
|
|
@@ -11,16 +13,25 @@ function Row({ index, style, options, onClickOption, addAll }) {
|
|
|
11
13
|
}
|
|
12
14
|
onClickOption?.(event, option);
|
|
13
15
|
};
|
|
14
|
-
return /*#__PURE__*/
|
|
16
|
+
if (isLoading) return /*#__PURE__*/ jsx(OptionContainer, {
|
|
17
|
+
style: style,
|
|
18
|
+
className: "__loading",
|
|
19
|
+
title: translation("loading_more"),
|
|
20
|
+
children: /*#__PURE__*/ jsx("span", {
|
|
21
|
+
style: {
|
|
22
|
+
opacity: 0.6
|
|
23
|
+
},
|
|
24
|
+
children: translation("loading_more")
|
|
25
|
+
})
|
|
26
|
+
});
|
|
27
|
+
return /*#__PURE__*/ jsx(OptionContainer, {
|
|
15
28
|
style: style,
|
|
16
29
|
onClick: handleClick,
|
|
17
30
|
className: hasSelectAll ? "__select_all" : "",
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
"__loading__" === option.value && /*#__PURE__*/ jsx(SkeletonLine, {})
|
|
23
|
-
]
|
|
31
|
+
title: option.label,
|
|
32
|
+
children: /*#__PURE__*/ jsx("span", {
|
|
33
|
+
children: option.label
|
|
34
|
+
})
|
|
24
35
|
});
|
|
25
36
|
}
|
|
26
37
|
export { Row as default };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IMultiSelectOption } from "
|
|
1
|
+
import { IMultiSelectOption } from "../..";
|
|
2
2
|
interface MultiSelectListProps {
|
|
3
3
|
onClickOption?: (event: React.MouseEvent<HTMLDivElement>, option: IMultiSelectOption) => void;
|
|
4
4
|
options: IMultiSelectOption[];
|
|
@@ -6,7 +6,7 @@ interface MultiSelectListProps {
|
|
|
6
6
|
addAll?: (event: React.MouseEvent<HTMLDivElement>) => void;
|
|
7
7
|
translation: (key: string) => string;
|
|
8
8
|
onLoadMore?: () => Promise<void>;
|
|
9
|
-
|
|
9
|
+
listPosition?: "top" | "bottom";
|
|
10
10
|
}
|
|
11
|
-
export default function MultiSelectList({ options, onClickOption, loading, addAll, translation, onLoadMore,
|
|
11
|
+
export default function MultiSelectList({ options, onClickOption, loading, addAll, translation, onLoadMore, listPosition, }: MultiSelectListProps): import("react/jsx-runtime").JSX.Element;
|
|
12
12
|
export {};
|
|
@@ -3,8 +3,8 @@ import { List } from "react-window";
|
|
|
3
3
|
import Row from "./Row/index.js";
|
|
4
4
|
import { LoadingContainer, SelectDropdown } from "./style.js";
|
|
5
5
|
import Loading from "../../../Loading/index.js";
|
|
6
|
-
import {
|
|
7
|
-
function MultiSelectList({ options, onClickOption, loading, addAll, translation, onLoadMore,
|
|
6
|
+
import { useState } from "react";
|
|
7
|
+
function MultiSelectList({ options, onClickOption, loading, addAll, translation, onLoadMore, listPosition = "bottom" }) {
|
|
8
8
|
const [lastIndex, setLastIndex] = useState(0);
|
|
9
9
|
const [loadingMore, setLoadingMore] = useState(false);
|
|
10
10
|
const selectAll = {
|
|
@@ -18,7 +18,7 @@ function MultiSelectList({ options, onClickOption, loading, addAll, translation,
|
|
|
18
18
|
const OPTION_SIZE = 36;
|
|
19
19
|
const optionLength = allOptions.length;
|
|
20
20
|
const height = OPTION_SIZE * (0 === optionLength ? 1 : optionLength >= 7 ? 7 : optionLength);
|
|
21
|
-
const onItemsRendered =
|
|
21
|
+
const onItemsRendered = async ({ stopIndex })=>{
|
|
22
22
|
const isAtEnd = stopIndex >= (addAll ? options.length : options.length - 1);
|
|
23
23
|
if (loadingMore) return;
|
|
24
24
|
try {
|
|
@@ -30,17 +30,13 @@ function MultiSelectList({ options, onClickOption, loading, addAll, translation,
|
|
|
30
30
|
} finally{
|
|
31
31
|
setLoadingMore(false);
|
|
32
32
|
}
|
|
33
|
-
}
|
|
34
|
-
options.length,
|
|
35
|
-
onLoadMore,
|
|
36
|
-
lastIndex
|
|
37
|
-
]);
|
|
33
|
+
};
|
|
38
34
|
const loadingOption = {
|
|
39
35
|
value: "__loading__",
|
|
40
|
-
label: "
|
|
36
|
+
label: translation("loading_more")
|
|
41
37
|
};
|
|
42
38
|
return /*#__PURE__*/ jsx(SelectDropdown, {
|
|
43
|
-
|
|
39
|
+
listPosition: listPosition,
|
|
44
40
|
children: loading ? /*#__PURE__*/ jsx(LoadingContainer, {
|
|
45
41
|
children: /*#__PURE__*/ jsx(Loading, {
|
|
46
42
|
size: "lg",
|
|
@@ -56,7 +52,8 @@ function MultiSelectList({ options, onClickOption, loading, addAll, translation,
|
|
|
56
52
|
loadingOption
|
|
57
53
|
] : allOptions,
|
|
58
54
|
onClickOption,
|
|
59
|
-
addAll
|
|
55
|
+
addAll,
|
|
56
|
+
translation
|
|
60
57
|
},
|
|
61
58
|
style: {
|
|
62
59
|
height: `${height / 16}rem`,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
interface SelectDropdownProps {
|
|
2
|
-
|
|
2
|
+
listPosition?: "top" | "bottom";
|
|
3
3
|
}
|
|
4
4
|
export declare const SelectDropdown: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, SelectDropdownProps>> & string;
|
|
5
5
|
export declare const LoadingContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
@@ -1,5 +1,21 @@
|
|
|
1
|
-
import styled_components from "styled-components";
|
|
1
|
+
import styled_components, { keyframes } from "styled-components";
|
|
2
2
|
import { COLOR_ACCENT_MEDIUM, COLOR_NEUTRAL_DAY, COLOR_NEUTRAL_DUSK, FONT_WEIGHT_BOLD } from "@ftdata/f-tokens";
|
|
3
|
+
const slideDown = keyframes`
|
|
4
|
+
0% {
|
|
5
|
+
transform: translateY(-0.25rem);
|
|
6
|
+
}
|
|
7
|
+
100% {
|
|
8
|
+
transform: translateY(0);
|
|
9
|
+
}
|
|
10
|
+
`;
|
|
11
|
+
const slideUp = keyframes`
|
|
12
|
+
0% {
|
|
13
|
+
transform: translateY(0.25rem);
|
|
14
|
+
}
|
|
15
|
+
100% {
|
|
16
|
+
transform: translateY(0);
|
|
17
|
+
}
|
|
18
|
+
`;
|
|
3
19
|
const SelectDropdown = styled_components.div`
|
|
4
20
|
background-color: ${COLOR_NEUTRAL_DAY};
|
|
5
21
|
border-radius: 0.25rem;
|
|
@@ -11,8 +27,10 @@ const SelectDropdown = styled_components.div`
|
|
|
11
27
|
height: auto;
|
|
12
28
|
z-index: 3;
|
|
13
29
|
|
|
14
|
-
|
|
15
|
-
|
|
30
|
+
animation: ${({ listPosition })=>"top" === listPosition ? slideUp : slideDown}
|
|
31
|
+
0.18s ease-out;
|
|
32
|
+
top: ${({ listPosition })=>"top" === listPosition ? "auto" : "calc(100% + 0.5rem)"};
|
|
33
|
+
bottom: ${({ listPosition })=>"top" === listPosition ? "calc(100% + 0.5rem)" : "auto"};
|
|
16
34
|
|
|
17
35
|
& > div {
|
|
18
36
|
border-radius: 0.25rem;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { IMultiSelectOption } from "
|
|
1
|
+
import { IMultiSelectOption } from "..";
|
|
2
2
|
export declare const addOption: (selected: IMultiSelectOption[], options: IMultiSelectOption[], option: IMultiSelectOption, max?: number) => {
|
|
3
|
-
selected:
|
|
4
|
-
unselected:
|
|
3
|
+
selected: import("../../Select").ISelectOption[];
|
|
4
|
+
unselected: import("../../Select").ISelectOption[];
|
|
5
5
|
} | undefined;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { IMultiSelectOption } from "
|
|
1
|
+
import { IMultiSelectOption } from "..";
|
|
2
2
|
export declare const computeUnselected: (options: IMultiSelectOption[], selected: IMultiSelectOption[]) => IMultiSelectOption[];
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const computeUnselected = (options, selected)=>options.filter((opt)=>!selected.some((
|
|
1
|
+
const computeUnselected = (options, selected)=>options.filter((opt)=>!selected.some((selected)=>selected.value === opt.value));
|
|
2
2
|
export { computeUnselected };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IMultiSelectOption } from "
|
|
1
|
+
import { IMultiSelectOption } from "..";
|
|
2
2
|
export declare function feedbackText(translation: (key: string) => string, options: IMultiSelectOption[], filtered: IMultiSelectOption[], selected: IMultiSelectOption[], query: string, max?: number): {
|
|
3
3
|
value: string;
|
|
4
4
|
label: string;
|
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
import { computeUnselected } from "./computeUnselected.js";
|
|
2
2
|
function feedbackText(translation, options, filtered, selected, query, max) {
|
|
3
|
-
if (!options.length) return [
|
|
4
|
-
{
|
|
5
|
-
value: "feedback__",
|
|
6
|
-
label: translation("no_data_is_available")
|
|
7
|
-
}
|
|
8
|
-
];
|
|
9
3
|
if (max && selected.length >= max) return [
|
|
10
4
|
{
|
|
11
|
-
value: "
|
|
5
|
+
value: "__feedback",
|
|
12
6
|
label: translation("the_selection_limit_has_been_reached")
|
|
13
7
|
}
|
|
14
8
|
];
|
|
15
9
|
if (query && !filtered.length) return [
|
|
16
10
|
{
|
|
17
|
-
value: "
|
|
11
|
+
value: "__feedback",
|
|
18
12
|
label: translation("no_data_was_found")
|
|
19
13
|
}
|
|
20
14
|
];
|
|
15
|
+
if (!options.length) return [
|
|
16
|
+
{
|
|
17
|
+
value: "__feedback",
|
|
18
|
+
label: translation("no_data_is_available")
|
|
19
|
+
}
|
|
20
|
+
];
|
|
21
21
|
const unselected = computeUnselected(options, selected);
|
|
22
22
|
if (!query && !unselected.length) return [
|
|
23
23
|
{
|
|
24
|
-
value: "
|
|
24
|
+
value: "__feedback",
|
|
25
25
|
label: translation("all_were_selected")
|
|
26
26
|
}
|
|
27
27
|
];
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { IMultiSelectOption } from "
|
|
1
|
+
import { IMultiSelectOption } from "..";
|
|
2
2
|
export declare const filterOptions: (options: IMultiSelectOption[], query: string) => IMultiSelectOption[];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { IMultiSelectOption } from "
|
|
1
|
+
import { IMultiSelectOption } from "..";
|
|
2
2
|
export declare const removeOption: (selected: IMultiSelectOption[], options: IMultiSelectOption[], option: IMultiSelectOption) => {
|
|
3
|
-
selected:
|
|
4
|
-
unselected:
|
|
3
|
+
selected: import("../../Select").ISelectOption[];
|
|
4
|
+
unselected: import("../../Select").ISelectOption[];
|
|
5
5
|
};
|
|
@@ -1,28 +1,46 @@
|
|
|
1
1
|
import { InputHTMLAttributes, JSX } from "react";
|
|
2
|
-
import { FieldFeedbackType } from "../../types/feedback";
|
|
3
2
|
import { IconsNames } from "@ftdata/f-icons";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
export
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
helpIcon?: IconsNames;
|
|
10
|
-
icon?: IconsNames | JSX.Element;
|
|
11
|
-
rightItem?: JSX.Element;
|
|
3
|
+
import { FieldFeedbackType } from "../../types/feedback";
|
|
4
|
+
import { ISelectOption } from "../Select";
|
|
5
|
+
export type IMultiSelectOption = ISelectOption;
|
|
6
|
+
export interface MultiSelectProps extends InputHTMLAttributes<HTMLInputElement> {
|
|
7
|
+
/** Texto do label exibido acima do campo. */
|
|
12
8
|
label?: string;
|
|
9
|
+
/** Texto auxiliar exibido abaixo do label. */
|
|
13
10
|
sublabel?: string;
|
|
11
|
+
/** Texto de ajuda exibido abaixo do campo. */
|
|
12
|
+
helpText?: string;
|
|
13
|
+
/** Ícone exibido junto ao texto de ajuda. */
|
|
14
|
+
helpIcon?: IconsNames;
|
|
15
|
+
/** Estado de feedback visual do campo (ex.: erro, sucesso, aviso). */
|
|
14
16
|
feedback?: FieldFeedbackType;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
translation: (key: string) => string;
|
|
21
|
-
max?: number;
|
|
17
|
+
/** Define se o campo está desabilitado. */
|
|
18
|
+
disabled?: boolean;
|
|
19
|
+
/** Quantidade máxima de itens que podem ser selecionados. */
|
|
20
|
+
maxItems?: number;
|
|
21
|
+
/** Define se a opção "Selecionar todos" deve ser exibida. */
|
|
22
22
|
selectAll?: boolean;
|
|
23
|
-
|
|
23
|
+
/** Define se a lista de opções está em estado de carregamento. */
|
|
24
|
+
isLoading?: boolean;
|
|
25
|
+
/** Lista de opções disponíveis para seleção. */
|
|
26
|
+
options: IMultiSelectOption[];
|
|
27
|
+
/** Lista de opções atualmente selecionadas. */
|
|
28
|
+
selected: IMultiSelectOption[];
|
|
29
|
+
/** Função chamada sempre que a lista de selecionados for alterada. */
|
|
30
|
+
onChangeSelected: (selected: IMultiSelectOption[]) => void;
|
|
31
|
+
/** Função usada para traduzir textos internos do componente. */
|
|
32
|
+
translation: (key: string) => string;
|
|
33
|
+
/** Função chamada ao digitar no campo de busca. */
|
|
34
|
+
onSearch?: (query: string) => void;
|
|
35
|
+
/** Função chamada ao solicitar mais itens (scroll infinito/paginação). */
|
|
24
36
|
onLoadMore?: () => Promise<void>;
|
|
37
|
+
/** Ícone exibido à esquerda do input. Pode ser `IconName` ou JSX. */
|
|
38
|
+
icon?: IconsNames | JSX.Element;
|
|
39
|
+
/** Define o estilo do componente. `alt` mostra caret, `default` não. */
|
|
40
|
+
variant?: "default" | "alt";
|
|
41
|
+
/** Define a posição da lista do componente */
|
|
42
|
+
listPosition?: "top" | "bottom";
|
|
43
|
+
/** Executa junto com o toggle da lista */
|
|
25
44
|
toggle?: (open: boolean) => void;
|
|
26
|
-
dropdownPosition?: "top" | "bottom";
|
|
27
45
|
}
|
|
28
|
-
export default function MultiSelect({
|
|
46
|
+
export default function MultiSelect({ label, sublabel, helpText, helpIcon, feedback, disabled, maxItems, selectAll, isLoading, options, selected, onChangeSelected, translation, onSearch, onLoadMore, placeholder, required, name, icon, listPosition, toggle, variant, }: MultiSelectProps): import("react/jsx-runtime").JSX.Element;
|