@ledgerhq/react-ui 0.5.0 → 0.7.2
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/components/asorted/Divider/index.d.ts +1 -1
- package/components/asorted/Icon/BoxedIcon.js +6 -2
- package/components/asorted/index.d.ts +1 -1
- package/components/asorted/index.js +1 -1
- package/components/cta/Button/index.d.ts +11 -8
- package/components/cta/Button/index.js +34 -23
- package/components/form/BaseInput/index.js +1 -1
- package/components/form/Dropdown/index.d.ts +3 -2
- package/components/form/Dropdown/index.js +9 -8
- package/components/form/DropdownGeneric/index.d.ts +42 -0
- package/components/form/DropdownGeneric/index.js +115 -0
- package/components/form/Radio/RadioElement.d.ts +3 -2
- package/components/form/Radio/RadioElement.js +72 -3
- package/components/form/Radio/index.d.ts +1 -1
- package/components/form/SelectInput/Control.d.ts +3 -9
- package/components/form/SelectInput/Control.js +2 -1
- package/components/form/SelectInput/DropdownIndicator.d.ts +3 -9
- package/components/form/SelectInput/IndicatorsContainer.d.ts +2 -5
- package/components/form/SelectInput/IndicatorsContainer.js +1 -1
- package/components/form/SelectInput/MenuList.d.ts +3 -9
- package/components/form/SelectInput/MenuList.js +2 -1
- package/components/form/SelectInput/Option.d.ts +6 -18
- package/components/form/SelectInput/ValueContainer.d.ts +5 -14
- package/components/form/SelectInput/ValueContainer.js +1 -1
- package/components/form/SelectInput/VirtualMenuList.d.ts +2 -5
- package/components/form/SelectInput/VirtualMenuList.js +2 -1
- package/components/form/SelectInput/index.d.ts +7 -16
- package/components/form/SelectInput/index.js +9 -1
- package/components/form/index.d.ts +1 -0
- package/components/form/index.js +1 -0
- package/components/layout/Drawer/index.d.ts +17 -2
- package/components/layout/Drawer/index.js +45 -36
- package/components/layout/Popin/index.d.ts +2 -1
- package/components/layout/Popin/index.js +10 -5
- package/components/loaders/InfiniteLoader/index.d.ts +8 -7
- package/components/loaders/InfiniteLoader/index.js +35 -9
- package/components/loaders/ProgressLoader/index.d.ts +22 -1
- package/components/loaders/ProgressLoader/index.js +10 -12
- package/components/message/Alert/index.d.ts +20 -11
- package/components/message/Alert/index.js +6 -7
- package/components/message/Log/index.d.ts +5 -2
- package/components/message/Log/index.js +3 -4
- package/components/navigation/FlowStepper/index.d.ts +77 -0
- package/components/navigation/FlowStepper/index.js +35 -0
- package/components/navigation/index.d.ts +1 -0
- package/components/navigation/index.js +1 -0
- package/components/navigation/progress/Stepper/index.d.ts +27 -10
- package/components/navigation/progress/Stepper/index.js +37 -18
- package/components/navigation/sideBar/SideBar/SideBar.js +9 -7
- package/index.d.ts +1 -1
- package/index.js +1 -1
- package/package.json +5 -5
- package/styles/InvertTheme.d.ts +4 -1
- package/styles/InvertTheme.js +5 -5
- package/styles/index.d.ts +1 -0
- package/styles/index.js +1 -0
- package/styles/theme.d.ts +1 -1
- package/styles/theme.js +7 -7
- package/components/loaders/InfiniteLoader/image.d.ts +0 -2
- package/components/loaders/InfiniteLoader/image.js +0 -1
|
@@ -15,6 +15,9 @@ import Flex from "../../layout/Flex";
|
|
|
15
15
|
export const DEFAULT_BOX_SIZE = 40;
|
|
16
16
|
export const DEFAULT_ICON_SIZE = 16;
|
|
17
17
|
export const DEFAULT_BADGE_SIZE = 20;
|
|
18
|
+
function getClipRectangleSize(badgeSize) {
|
|
19
|
+
return (3 / 4) * badgeSize;
|
|
20
|
+
}
|
|
18
21
|
const getTopRightSquareClippedPolygon = (boxSize, rectangleSize) => {
|
|
19
22
|
// clipping path that hides top right square of size `${rectangleSize}px`
|
|
20
23
|
const diff = boxSize - rectangleSize;
|
|
@@ -32,7 +35,8 @@ const IconBoxBackground = styled(Flex) `
|
|
|
32
35
|
height: ${(p) => p.size}px;
|
|
33
36
|
width: ${(p) => p.size}px;
|
|
34
37
|
${(p) => {
|
|
35
|
-
return p.hasBadge &&
|
|
38
|
+
return (p.hasBadge &&
|
|
39
|
+
`clip-path: ${getTopRightSquareClippedPolygon(p.size, getClipRectangleSize(p.badgeSize))};`);
|
|
36
40
|
}};
|
|
37
41
|
border-radius: ${(p) => p.theme.radii[2]}px;
|
|
38
42
|
`;
|
|
@@ -45,7 +49,7 @@ const BadgeContainer = styled.div `
|
|
|
45
49
|
export const IconBox = ({ Badge, size = DEFAULT_BOX_SIZE, children, borderColor = "neutral.c40", badgeColor, badgeSize = DEFAULT_BADGE_SIZE, }) => {
|
|
46
50
|
const hasBadge = !!Badge;
|
|
47
51
|
return (React.createElement(Container, { size: size },
|
|
48
|
-
React.createElement(IconBoxBackground, { size: size, hasBadge: hasBadge, border: "1px solid", borderColor: borderColor }),
|
|
52
|
+
React.createElement(IconBoxBackground, { size: size, badgeSize: badgeSize, hasBadge: hasBadge, border: "1px solid", borderColor: borderColor }),
|
|
49
53
|
children,
|
|
50
54
|
hasBadge && (React.createElement(BadgeContainer, { badgeSize: badgeSize },
|
|
51
55
|
React.createElement(Badge, { size: badgeSize, color: badgeColor })))));
|
|
@@ -14,13 +14,14 @@ interface BaseProps extends BaseStyledProps, BordersProps {
|
|
|
14
14
|
iconButton?: boolean;
|
|
15
15
|
disabled?: boolean;
|
|
16
16
|
}
|
|
17
|
-
export interface ButtonProps extends BaseProps {
|
|
17
|
+
export interface ButtonProps extends BaseProps, React.RefAttributes<HTMLButtonElement> {
|
|
18
|
+
iconName?: string;
|
|
18
19
|
Icon?: React.ComponentType<{
|
|
19
20
|
size: number;
|
|
20
21
|
color?: string;
|
|
21
22
|
}>;
|
|
22
23
|
children?: React.ReactNode;
|
|
23
|
-
onClick
|
|
24
|
+
onClick?: (event: React.SyntheticEvent<HTMLButtonElement>) => void;
|
|
24
25
|
iconSize?: number;
|
|
25
26
|
style?: React.CSSProperties;
|
|
26
27
|
}
|
|
@@ -29,13 +30,15 @@ export declare const Base: import("styled-components").StyledComponent<"button",
|
|
|
29
30
|
fontFamily: string;
|
|
30
31
|
fontSize: number;
|
|
31
32
|
} & BaseProps, "fontFamily" | "fontSize">;
|
|
32
|
-
declare const
|
|
33
|
-
({ Icon, iconPosition, iconSize, children, onClick, ...props }: ButtonProps): React.ReactElement;
|
|
33
|
+
declare const ButtonWithRef: {
|
|
34
|
+
({ Icon, iconPosition, iconSize, children, onClick, iconName, ...props }: ButtonProps, ref?: React.ForwardedRef<HTMLButtonElement> | undefined): React.ReactElement;
|
|
34
35
|
Unstyled: import("styled-components").StyledComponent<"button", import("styled-components").DefaultTheme, {}, never>;
|
|
36
|
+
Expand: React.ForwardRefExoticComponent<Pick<ButtonProps & {
|
|
37
|
+
onToggle?: ((arg0: boolean) => void) | undefined;
|
|
38
|
+
}, "overflow" | "p" | "style" | "key" | "color" | "children" | "onClick" | "variant" | "size" | "rowGap" | "alignContent" | "alignItems" | "alignSelf" | "backgroundColor" | "borderBottomColor" | "borderBottomLeftRadius" | "borderBottomRightRadius" | "borderBottomStyle" | "borderBottomWidth" | "borderLeftColor" | "borderLeftStyle" | "borderLeftWidth" | "borderRightColor" | "borderRightStyle" | "borderRightWidth" | "borderTopColor" | "borderTopLeftRadius" | "borderTopRightRadius" | "borderTopStyle" | "borderTopWidth" | "bottom" | "columnGap" | "display" | "flexBasis" | "flexDirection" | "flexGrow" | "flexShrink" | "flexWrap" | "fontSize" | "height" | "justifyContent" | "justifyItems" | "justifySelf" | "left" | "marginBottom" | "marginLeft" | "marginRight" | "marginTop" | "maxHeight" | "maxWidth" | "minHeight" | "minWidth" | "opacity" | "order" | "overflowX" | "overflowY" | "paddingBottom" | "paddingLeft" | "paddingRight" | "paddingTop" | "position" | "right" | "top" | "verticalAlign" | "width" | "zIndex" | "border" | "borderBottom" | "borderColor" | "borderLeft" | "borderRadius" | "borderRight" | "borderStyle" | "borderTop" | "borderWidth" | "flex" | "margin" | "outline" | "padding" | "disabled" | "onToggle" | "m" | "mt" | "mr" | "mb" | "ml" | "mx" | "marginX" | "my" | "marginY" | "pt" | "pr" | "pb" | "pl" | "px" | "paddingX" | "py" | "paddingY" | "bg" | "borderX" | "borderY" | "Icon" | "iconSize" | "ff" | "iconPosition" | "iconButton" | "iconName"> & React.RefAttributes<HTMLButtonElement>>;
|
|
35
39
|
};
|
|
36
|
-
export declare type
|
|
40
|
+
export declare type ButtonExpandProps = React.PropsWithChildren<ButtonProps & {
|
|
37
41
|
onToggle?: (arg0: boolean) => void;
|
|
38
|
-
onClick?: (arg0: React.SyntheticEvent<HTMLButtonElement>) => void;
|
|
39
42
|
}>;
|
|
40
|
-
export declare
|
|
41
|
-
export default
|
|
43
|
+
export declare function ButtonExpand({ onToggle, onClick, ...props }: ButtonExpandProps, ref?: React.ForwardedRef<HTMLButtonElement>): React.ReactElement;
|
|
44
|
+
export default ButtonWithRef;
|
|
@@ -9,13 +9,15 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
9
9
|
}
|
|
10
10
|
return t;
|
|
11
11
|
};
|
|
12
|
-
import React, { useState } from "react";
|
|
12
|
+
import React, { useState, useMemo } from "react";
|
|
13
13
|
import styled, { css } from "styled-components";
|
|
14
14
|
import baseStyled from "../../styled";
|
|
15
15
|
import { fontSize, border, compose } from "styled-system";
|
|
16
16
|
import fontFamily from "../../../styles/styled/fontFamily";
|
|
17
17
|
import { fontSizes } from "../../../styles/theme";
|
|
18
|
+
import { rgba } from "../../../styles/helpers";
|
|
18
19
|
import ChevronBottom from "@ledgerhq/icons-ui/react/ChevronBottomRegular";
|
|
20
|
+
import IconComponent from "../../asorted/Icon";
|
|
19
21
|
const IconContainer = styled.div `
|
|
20
22
|
display: inline-block;
|
|
21
23
|
${(p) => `${p.iconPosition === "left" ? "margin-right" : "margin-left"}: ${p.theme.space[4]}px;`}
|
|
@@ -26,12 +28,12 @@ const getVariantColors = (p) => ({
|
|
|
26
28
|
outline: `
|
|
27
29
|
border-color: ${p.theme.colors.neutral.c100};
|
|
28
30
|
color: ${p.theme.colors.neutral.c100};
|
|
29
|
-
background-color:
|
|
31
|
+
background-color: transparent;
|
|
30
32
|
&:hover, &:focus {
|
|
31
|
-
background-color: ${p.theme.colors.neutral.
|
|
33
|
+
background-color: ${rgba(p.theme.colors.neutral.c100, 0.03)};
|
|
32
34
|
}
|
|
33
35
|
&:active {
|
|
34
|
-
background-color: ${p.theme.colors.neutral.
|
|
36
|
+
background-color: ${rgba(p.theme.colors.neutral.c100, 0.05)};
|
|
35
37
|
}
|
|
36
38
|
`,
|
|
37
39
|
filled: `
|
|
@@ -62,12 +64,12 @@ const getVariantColors = (p) => ({
|
|
|
62
64
|
outline: `
|
|
63
65
|
border-color: ${p.theme.colors.error.c100};
|
|
64
66
|
color: ${p.theme.colors.error.c100};
|
|
65
|
-
background-color:
|
|
67
|
+
background-color: transparent;
|
|
66
68
|
&:hover {
|
|
67
|
-
background-color: ${p.theme.colors.error.
|
|
69
|
+
background-color: ${rgba(p.theme.colors.error.c100, 0.02)};
|
|
68
70
|
}
|
|
69
71
|
&:active {
|
|
70
|
-
background-color: ${p.theme.colors.error.
|
|
72
|
+
background-color: ${rgba(p.theme.colors.error.c100, 0.05)};
|
|
71
73
|
}
|
|
72
74
|
`,
|
|
73
75
|
filled: `
|
|
@@ -82,12 +84,12 @@ const getVariantColors = (p) => ({
|
|
|
82
84
|
outline: `
|
|
83
85
|
border-color: ${p.theme.colors.primary.c80};
|
|
84
86
|
color: ${p.theme.colors.primary.c80};
|
|
85
|
-
background-color:
|
|
87
|
+
background-color: transparent;
|
|
86
88
|
&:hover {
|
|
87
|
-
background-color: ${p.theme.colors.primary.
|
|
89
|
+
background-color: ${rgba(p.theme.colors.primary.c100, 0.02)};
|
|
88
90
|
}
|
|
89
91
|
&:active {
|
|
90
|
-
background-color: ${p.theme.colors.primary.
|
|
92
|
+
background-color: ${rgba(p.theme.colors.primary.c100, 0.05)};
|
|
91
93
|
}
|
|
92
94
|
`,
|
|
93
95
|
filled: `
|
|
@@ -102,7 +104,7 @@ const getVariantColors = (p) => ({
|
|
|
102
104
|
outline: `
|
|
103
105
|
border-color: ${p.theme.colors.neutral.c50};
|
|
104
106
|
color: ${p.theme.colors.neutral.c50};
|
|
105
|
-
background-color:
|
|
107
|
+
background-color: transparent;
|
|
106
108
|
`,
|
|
107
109
|
filled: `
|
|
108
110
|
color: ${p.theme.colors.neutral.c50};
|
|
@@ -153,7 +155,10 @@ export const Base = baseStyled.button.attrs((p) => {
|
|
|
153
155
|
position: relative;
|
|
154
156
|
cursor: ${(p) => (p.disabled ? "default" : "pointer")};
|
|
155
157
|
&:active {
|
|
156
|
-
box-shadow: 0 0 0 4px ${(p) => p.theme.colors.primary.c60};
|
|
158
|
+
box-shadow: 0 0 0 4px ${(p) => rgba(p.theme.colors.primary.c60, 0.4)};
|
|
159
|
+
}
|
|
160
|
+
&:focus {
|
|
161
|
+
box-shadow: 0 0 0 2px ${(p) => rgba(p.theme.colors.primary.c60, 0.4)};
|
|
157
162
|
}
|
|
158
163
|
|
|
159
164
|
${(p) => {
|
|
@@ -188,19 +193,22 @@ export const Base = baseStyled.button.attrs((p) => {
|
|
|
188
193
|
}
|
|
189
194
|
`
|
|
190
195
|
: ""}
|
|
191
|
-
${(p) => p.theme.transition(["background-color", "color", "border-color"])}
|
|
196
|
+
${(p) => p.theme.transition(["background-color", "color", "border-color", "box-shadow"], "0.2s")}
|
|
192
197
|
`;
|
|
193
198
|
const ContentContainer = styled.div ``;
|
|
194
|
-
const Button = (_a) => {
|
|
199
|
+
const Button = (_a, ref) => {
|
|
195
200
|
var _b;
|
|
196
|
-
var { Icon, iconPosition = "right", iconSize = 16, children, onClick } = _a, props = __rest(_a, ["Icon", "iconPosition", "iconSize", "children", "onClick"]);
|
|
197
|
-
|
|
201
|
+
var { Icon, iconPosition = "right", iconSize = 16, children, onClick, iconName } = _a, props = __rest(_a, ["Icon", "iconPosition", "iconSize", "children", "onClick", "iconName"]);
|
|
202
|
+
const iconNodeSize = iconSize || fontSizes[(_b = props.fontSize) !== null && _b !== void 0 ? _b : 4];
|
|
203
|
+
const IconNode = useMemo(() => (iconName && React.createElement(IconComponent, { name: iconName, size: iconNodeSize })) ||
|
|
204
|
+
(Icon && React.createElement(Icon, { size: iconNodeSize })), [iconName, iconNodeSize, Icon]);
|
|
205
|
+
return (React.createElement(Base, Object.assign({}, props, { ref: ref, iconButton: !(Icon == null) && !children, onClick: onClick }),
|
|
198
206
|
iconPosition === "right" ? React.createElement(ContentContainer, null, children) : null,
|
|
199
|
-
|
|
200
|
-
React.createElement(Icon, { size: iconSize || fontSizes[(_b = props.fontSize) !== null && _b !== void 0 ? _b : 4] }))) : null,
|
|
207
|
+
IconNode && React.createElement(IconContainer, { iconPosition: iconPosition }, IconNode),
|
|
201
208
|
iconPosition === "left" ? React.createElement(ContentContainer, null, children) : null));
|
|
202
209
|
};
|
|
203
|
-
const
|
|
210
|
+
const ButtonWithRef = React.forwardRef(Button);
|
|
211
|
+
const StyledButtonExpand = styled(ButtonWithRef).attrs((props) => ({
|
|
204
212
|
Icon: props.Icon != null || ChevronBottom,
|
|
205
213
|
iconPosition: props.iconPosition || "right",
|
|
206
214
|
})) `
|
|
@@ -209,14 +217,17 @@ const StyledExpandButton = styled(Button).attrs((props) => ({
|
|
|
209
217
|
${(p) => (p.expanded ? "transform: rotate(180deg)" : "")}
|
|
210
218
|
}
|
|
211
219
|
`;
|
|
212
|
-
export
|
|
220
|
+
export function ButtonExpand(_a, ref) {
|
|
213
221
|
var { onToggle, onClick } = _a, props = __rest(_a, ["onToggle", "onClick"]);
|
|
214
222
|
const [expanded, setExpanded] = useState(false);
|
|
215
|
-
return (React.createElement(
|
|
223
|
+
return (React.createElement(StyledButtonExpand, Object.assign({}, props, { ref: ref, expanded: expanded, onClick: (event) => {
|
|
216
224
|
setExpanded((expanded) => !expanded);
|
|
217
225
|
onToggle != null && onToggle(!expanded);
|
|
218
226
|
onClick != null && onClick(event);
|
|
219
227
|
} })));
|
|
220
|
-
}
|
|
228
|
+
}
|
|
221
229
|
Button.Unstyled = ButtonUnstyled;
|
|
222
|
-
|
|
230
|
+
Button.Expand = React.forwardRef(ButtonExpand);
|
|
231
|
+
ButtonWithRef.Unstyled = Button.Unstyled;
|
|
232
|
+
ButtonWithRef.Expand = Button.Expand;
|
|
233
|
+
export default ButtonWithRef;
|
|
@@ -28,7 +28,7 @@ export const InputContainer = styled.div `
|
|
|
28
28
|
!p.warning &&
|
|
29
29
|
css `
|
|
30
30
|
border: 1px solid ${p.theme.colors.primary.c80};
|
|
31
|
-
box-shadow: 0 0 0 4px ${rgba(p.theme.colors.primary.c60, 0.
|
|
31
|
+
box-shadow: 0 0 0 4px ${rgba(p.theme.colors.primary.c60, 0.4)};
|
|
32
32
|
`};
|
|
33
33
|
|
|
34
34
|
${(p) => p.error &&
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { GroupBase } from "react-select";
|
|
1
2
|
import { Props as SelectInputProps } from "../../form/SelectInput";
|
|
2
|
-
export declare type Props = SelectInputProps & {
|
|
3
|
+
export declare type Props<O> = SelectInputProps<O, false, GroupBase<O>> & {
|
|
3
4
|
label: string;
|
|
4
5
|
};
|
|
5
|
-
export default function Dropdown(props: Props): JSX.Element;
|
|
6
|
+
export default function Dropdown<O>(props: Props<O>): JSX.Element;
|
|
@@ -14,22 +14,23 @@ import { components } from "react-select";
|
|
|
14
14
|
import { useTheme } from "styled-components";
|
|
15
15
|
import SelectInput from "../../form/SelectInput";
|
|
16
16
|
import Text from "../../asorted/Text";
|
|
17
|
+
import { Icons } from "../../../";
|
|
17
18
|
import { ValueContainer } from "../../form/SelectInput/ValueContainer";
|
|
18
|
-
import { ChevronBottomMedium, ChevronTopMedium } from "@ledgerhq/icons-ui/react";
|
|
19
19
|
import FlexBox from "../../layout/Flex";
|
|
20
20
|
function DropdownControl(props) {
|
|
21
|
-
const { selectProps
|
|
21
|
+
const { selectProps, children } = props;
|
|
22
|
+
const { label } = selectProps;
|
|
22
23
|
return (React.createElement(components.Control, Object.assign({}, props),
|
|
23
|
-
React.createElement(Text, {
|
|
24
|
+
React.createElement(Text, { variant: "paragraph", fontWeight: "medium", color: "neutral.c80", mr: 2 }, label),
|
|
24
25
|
children));
|
|
25
26
|
}
|
|
26
27
|
function DropdownValueContainer(props) {
|
|
27
|
-
const
|
|
28
|
-
return (React.createElement(ValueContainer, Object.assign({}, props, { render: () => (React.createElement(FlexBox,
|
|
29
|
-
React.createElement(Text, {
|
|
28
|
+
const isOpen = props.selectProps.menuIsOpen;
|
|
29
|
+
return (React.createElement(ValueContainer, Object.assign({}, props, { render: () => (React.createElement(FlexBox, { alignItems: "center" },
|
|
30
|
+
React.createElement(Text, { variant: "paragraph", fontWeight: "medium", mr: 2 },
|
|
30
31
|
React.createElement(FlexBox, null, props.children)),
|
|
31
|
-
React.createElement(FlexBox, { alignItems: "center" },
|
|
32
|
-
React.createElement(
|
|
32
|
+
React.createElement(FlexBox, { alignItems: "center", style: { transform: isOpen ? "rotate(180deg)" : "" } },
|
|
33
|
+
React.createElement(Icons.DropdownMedium, { size: 20 })))) })));
|
|
33
34
|
}
|
|
34
35
|
function DropdownIndicatorsContainer() {
|
|
35
36
|
return null;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export declare const placements: readonly ["bottom-start", "bottom", "bottom-end"];
|
|
3
|
+
declare type Placement = typeof placements[number];
|
|
4
|
+
export declare type Props = {
|
|
5
|
+
/**
|
|
6
|
+
* Label of the dropdown button, displayed before the dropdown icon.
|
|
7
|
+
*/
|
|
8
|
+
label: string | React.ReactNode;
|
|
9
|
+
/**
|
|
10
|
+
* Controls whether the dropdown can be open.
|
|
11
|
+
* Defaults to false.
|
|
12
|
+
*/
|
|
13
|
+
disabled?: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Controls whether the dropdown will close on a click event happening outside of this component.
|
|
16
|
+
* Defaults to true.
|
|
17
|
+
*/
|
|
18
|
+
closeOnClickOutside?: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Controls whether the dropdown will close on a click event happening inside the dropdown.
|
|
21
|
+
* Defaults to false.
|
|
22
|
+
*/
|
|
23
|
+
closeOnClickInside?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Content of the dropdown.
|
|
26
|
+
*/
|
|
27
|
+
children: React.ReactNode;
|
|
28
|
+
/**
|
|
29
|
+
* Vertical alignment of the dropdown relative to the dropdown button.
|
|
30
|
+
* Will automatically adjust to the document to avoid overflowing.
|
|
31
|
+
* Defaults to "bottom".
|
|
32
|
+
*/
|
|
33
|
+
placement?: Placement;
|
|
34
|
+
/**
|
|
35
|
+
* Controls whether the dropdown will flip its side to keep it in view
|
|
36
|
+
* in case there isn't enough space available. See https://floating-ui.com/docs/flip
|
|
37
|
+
* Defaults to false.
|
|
38
|
+
*/
|
|
39
|
+
flipDisabled?: boolean;
|
|
40
|
+
};
|
|
41
|
+
declare const DropdownGeneric: ({ label, closeOnClickOutside, closeOnClickInside, disabled, placement, flipDisabled, children, }: Props) => JSX.Element;
|
|
42
|
+
export default DropdownGeneric;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import React, { useCallback, useEffect, useRef, useState } from "react";
|
|
2
|
+
import { useFloating, getScrollParents, shift, size, flip } from "@floating-ui/react-dom";
|
|
3
|
+
import styled from "styled-components";
|
|
4
|
+
import { Icons } from "../../../";
|
|
5
|
+
import Flex from "../../layout/Flex";
|
|
6
|
+
import Box from "../../layout/Flex";
|
|
7
|
+
import Text from "../../asorted/Text";
|
|
8
|
+
const ButtonContainer = styled(Box).attrs({
|
|
9
|
+
flexDirection: "row",
|
|
10
|
+
width: "auto",
|
|
11
|
+
alignItems: "center",
|
|
12
|
+
height: "36px",
|
|
13
|
+
}) `
|
|
14
|
+
cursor: ${(p) => !p.disabled && "pointer"};
|
|
15
|
+
> :last-child {
|
|
16
|
+
/* targeting the dropdown icon */
|
|
17
|
+
${(p) => p.opened && "transform: rotate(180deg);"}
|
|
18
|
+
margin-left: ${(p) => p.theme.space[3]}px;
|
|
19
|
+
}
|
|
20
|
+
`;
|
|
21
|
+
const DropdownContainer = styled(Flex).attrs(({ theme }) => {
|
|
22
|
+
const isLight = theme.colors.type === "light";
|
|
23
|
+
return {
|
|
24
|
+
zIndex: 1,
|
|
25
|
+
flexDirection: "column",
|
|
26
|
+
padding: 3,
|
|
27
|
+
border: `1px solid ${theme.colors.neutral[isLight ? "c20" : "c30"]}`,
|
|
28
|
+
borderRadius: "8px",
|
|
29
|
+
backgroundColor: isLight ? "neutral.c00" : "neutral.c20",
|
|
30
|
+
color: theme.colors.neutral.c80,
|
|
31
|
+
};
|
|
32
|
+
}) `
|
|
33
|
+
overflow-y: auto;
|
|
34
|
+
box-shadow: 0px 6px 12px rgba(0, 0, 0, ${(p) => (p.theme.colors.type === "light" ? 0.04 : 0.08)});
|
|
35
|
+
`;
|
|
36
|
+
export const placements = ["bottom-start", "bottom", "bottom-end"];
|
|
37
|
+
const DropdownGeneric = ({ label, closeOnClickOutside = true, closeOnClickInside = false, disabled = false, placement = "bottom", flipDisabled = false, children, }) => {
|
|
38
|
+
const divRef = useRef(null);
|
|
39
|
+
const [maxHeight, setMaxHeight] = useState();
|
|
40
|
+
const [maxWidth, setMaxWidth] = useState();
|
|
41
|
+
const [opened, setOpened] = useState(false);
|
|
42
|
+
const handleClickButton = useCallback(() => {
|
|
43
|
+
if (!disabled)
|
|
44
|
+
setOpened(!opened);
|
|
45
|
+
}, [opened, disabled]);
|
|
46
|
+
const handleClickInside = useCallback(() => {
|
|
47
|
+
if (closeOnClickInside)
|
|
48
|
+
setOpened(false);
|
|
49
|
+
}, [setOpened, closeOnClickInside]);
|
|
50
|
+
const { x, y, reference, floating, strategy, update, refs } = useFloating({
|
|
51
|
+
placement: placements.includes(placement) ? placement : "bottom",
|
|
52
|
+
middleware: [
|
|
53
|
+
shift(),
|
|
54
|
+
...(flipDisabled ? [] : [flip()]),
|
|
55
|
+
size({
|
|
56
|
+
padding: 6,
|
|
57
|
+
apply({ height, width }) {
|
|
58
|
+
setMaxHeight(height);
|
|
59
|
+
setMaxWidth(width);
|
|
60
|
+
},
|
|
61
|
+
}),
|
|
62
|
+
],
|
|
63
|
+
});
|
|
64
|
+
const handleResizeOrScroll = useCallback(() => {
|
|
65
|
+
if (opened && !disabled)
|
|
66
|
+
update();
|
|
67
|
+
}, [opened, disabled, update]);
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
if (!refs.reference.current || !refs.floating.current) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const parents = [
|
|
73
|
+
...getScrollParents(refs.reference.current),
|
|
74
|
+
...getScrollParents(refs.floating.current),
|
|
75
|
+
];
|
|
76
|
+
parents.forEach((parent) => {
|
|
77
|
+
parent.addEventListener("scroll", handleResizeOrScroll);
|
|
78
|
+
parent.addEventListener("resize", handleResizeOrScroll);
|
|
79
|
+
});
|
|
80
|
+
return () => {
|
|
81
|
+
parents.forEach((parent) => {
|
|
82
|
+
parent.removeEventListener("scroll", handleResizeOrScroll);
|
|
83
|
+
parent.removeEventListener("resize", handleResizeOrScroll);
|
|
84
|
+
});
|
|
85
|
+
};
|
|
86
|
+
}, [flipDisabled, refs.reference, refs.floating, handleResizeOrScroll]);
|
|
87
|
+
useEffect(() => {
|
|
88
|
+
function handleClickOutside(event) {
|
|
89
|
+
if (closeOnClickOutside &&
|
|
90
|
+
opened &&
|
|
91
|
+
divRef.current &&
|
|
92
|
+
!divRef.current.contains(event.target)) {
|
|
93
|
+
setOpened(false);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
97
|
+
return () => {
|
|
98
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
99
|
+
};
|
|
100
|
+
}, [closeOnClickOutside, opened, setOpened, divRef]);
|
|
101
|
+
const color = disabled ? "neutral.c50" : "neutral.c100";
|
|
102
|
+
return (React.createElement(Box, { ref: divRef },
|
|
103
|
+
React.createElement(ButtonContainer, { ref: reference, onClick: handleClickButton, disabled: disabled, opened: opened && !disabled },
|
|
104
|
+
React.createElement(Text, { variant: "paragraph", fontWeight: "medium", color: color }, label),
|
|
105
|
+
React.createElement(Icons.DropdownMedium, { size: 20, color: color })),
|
|
106
|
+
opened && !disabled && (React.createElement(DropdownContainer, { ref: floating, style: {
|
|
107
|
+
position: strategy,
|
|
108
|
+
top: y !== null && y !== void 0 ? y : "",
|
|
109
|
+
left: x !== null && x !== void 0 ? x : "",
|
|
110
|
+
maxHeight: maxHeight ? `${maxHeight}px` : "",
|
|
111
|
+
maxWidth: maxWidth ? "" : "",
|
|
112
|
+
// maxWidth: maxWidth ? `${maxWidth}px` : "", /* TODO: fix this */
|
|
113
|
+
}, onClick: handleClickInside }, children))));
|
|
114
|
+
};
|
|
115
|
+
export default DropdownGeneric;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { InputHTMLAttributes } from "react";
|
|
2
2
|
declare type InputAttributes = Omit<InputHTMLAttributes<HTMLInputElement>, "type" | "onChange" | "name">;
|
|
3
3
|
export declare type RadioElementProps = InputAttributes & {
|
|
4
|
-
variant?: "default" | "success" | "error";
|
|
4
|
+
variant?: "default" | "main" | "success" | "error";
|
|
5
5
|
label: string;
|
|
6
|
+
outlined?: boolean;
|
|
6
7
|
};
|
|
7
8
|
declare const Element: {
|
|
8
|
-
({ label, value, disabled, variant, ...props }: RadioElementProps): JSX.Element;
|
|
9
|
+
({ label, value, disabled, outlined, variant, ...props }: RadioElementProps): JSX.Element;
|
|
9
10
|
displayName: string;
|
|
10
11
|
};
|
|
11
12
|
export default Element;
|
|
@@ -10,7 +10,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
10
10
|
return t;
|
|
11
11
|
};
|
|
12
12
|
import React, { useContext, useMemo } from "react";
|
|
13
|
-
import styled from "styled-components";
|
|
13
|
+
import styled, { css } from "styled-components";
|
|
14
14
|
import { rgba } from "../../../styles/helpers";
|
|
15
15
|
import Text from "../../asorted/Text";
|
|
16
16
|
import { RadioContext } from "./index";
|
|
@@ -25,6 +25,7 @@ const Input = styled.input `
|
|
|
25
25
|
appearance: none;
|
|
26
26
|
width: var(--ledger-ui-checkbox-size);
|
|
27
27
|
height: var(--ledger-ui-checkbox-size);
|
|
28
|
+
flex-shrink: 0;
|
|
28
29
|
border-radius: ${(p) => `${p.theme.radii[1]}px`};
|
|
29
30
|
border: 1px solid var(--ledger-ui-checkbox-color);
|
|
30
31
|
cursor: pointer;
|
|
@@ -60,6 +61,20 @@ const Input = styled.input `
|
|
|
60
61
|
}
|
|
61
62
|
}
|
|
62
63
|
|
|
64
|
+
&[data-variant="main"] {
|
|
65
|
+
:hover {
|
|
66
|
+
--ledger-ui-checkbox-color: ${(p) => p.theme.colors.neutral.c90};
|
|
67
|
+
}
|
|
68
|
+
:active,
|
|
69
|
+
:checked,
|
|
70
|
+
:focus {
|
|
71
|
+
--ledger-ui-checkbox-color: ${(p) => p.theme.colors.neutral.c100};
|
|
72
|
+
}
|
|
73
|
+
:focus {
|
|
74
|
+
box-shadow: 0px 0px 0px 4px ${(p) => rgba(p.theme.colors.neutral.c60, 0.48)};
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
63
78
|
&[data-variant="success"] {
|
|
64
79
|
:hover,
|
|
65
80
|
:checked:not([disabled]),
|
|
@@ -88,13 +103,67 @@ const Input = styled.input `
|
|
|
88
103
|
background-color: ${(p) => p.theme.colors.neutral.c30};
|
|
89
104
|
}
|
|
90
105
|
`;
|
|
106
|
+
const outlinedCSS = css `
|
|
107
|
+
padding: 20px;
|
|
108
|
+
border: 1px solid ${(p) => p.theme.colors.neutral.c50};
|
|
109
|
+
border-radius: ${(p) => p.theme.radii[2]}px;
|
|
110
|
+
&[data-variant="default"] {
|
|
111
|
+
:hover {
|
|
112
|
+
border-color: ${(p) => p.theme.colors.primary.c90};
|
|
113
|
+
}
|
|
114
|
+
&[data-checked] :active {
|
|
115
|
+
border-color: ${(p) => p.theme.colors.primary.c100};
|
|
116
|
+
}
|
|
117
|
+
:focus {
|
|
118
|
+
border-color: ${(p) => p.theme.colors.primary.c80};
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
&[data-variant="main"] {
|
|
123
|
+
:hover {
|
|
124
|
+
border-color: ${(p) => p.theme.colors.neutral.c90};
|
|
125
|
+
}
|
|
126
|
+
&[data-checked],
|
|
127
|
+
:active :focus {
|
|
128
|
+
border-color: ${(p) => p.theme.colors.neutral.c100};
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
&[data-variant="success"] {
|
|
133
|
+
&[data-checked]:not([disabled]) {
|
|
134
|
+
border-color: ${(p) => p.theme.colors.success.c100};
|
|
135
|
+
}
|
|
136
|
+
:hover {
|
|
137
|
+
border-color: ${(p) => p.theme.colors.success.c100};
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
&[data-variant="error"] {
|
|
142
|
+
&[data-checked]:not([disabled]) {
|
|
143
|
+
border-color: ${(p) => p.theme.colors.error.c100};
|
|
144
|
+
}
|
|
145
|
+
:hover {
|
|
146
|
+
border-color: ${(p) => p.theme.colors.error.c100};
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
&[data-variant]:disabled {
|
|
151
|
+
border-color: ${(p) => p.theme.colors.neutral.c40};
|
|
152
|
+
cursor: unset;
|
|
153
|
+
}
|
|
154
|
+
`;
|
|
91
155
|
const RadioElement = styled.label.attrs({ tabIndex: -1 }) `
|
|
92
156
|
display: inline-flex;
|
|
93
157
|
column-gap: 0.75rem;
|
|
94
158
|
align-items: center;
|
|
159
|
+
cursor: pointer;
|
|
160
|
+
&[data-variant]:disabled {
|
|
161
|
+
cursor: unset;
|
|
162
|
+
}
|
|
163
|
+
${(p) => p.outlined && outlinedCSS}
|
|
95
164
|
`;
|
|
96
165
|
const Element = (_a) => {
|
|
97
|
-
var { label, value, disabled, variant = "default" } = _a, props = __rest(_a, ["label", "value", "disabled", "variant"]);
|
|
166
|
+
var { label, value, disabled, outlined, variant = "default" } = _a, props = __rest(_a, ["label", "value", "disabled", "outlined", "variant"]);
|
|
98
167
|
const context = useContext(RadioContext);
|
|
99
168
|
if (context === undefined)
|
|
100
169
|
throw new Error("RadioElement must be used within a RadioProvider");
|
|
@@ -103,7 +172,7 @@ const Element = (_a) => {
|
|
|
103
172
|
const handleChange = (event) => {
|
|
104
173
|
context.onChange(event.target.value);
|
|
105
174
|
};
|
|
106
|
-
return (React.createElement(RadioElement,
|
|
175
|
+
return (React.createElement(RadioElement, Object.assign({ "data-variant": variant }, (isChecked ? { "data-checked": true } : {}), { outlined: outlined }),
|
|
107
176
|
React.createElement(Input, Object.assign({ type: "radio", "data-variant": variant, checked: isChecked, disabled: disabled, onChange: handleChange, value: value, name: context.name }, props)),
|
|
108
177
|
React.createElement(Label, { variant: "paragraph" }, label)));
|
|
109
178
|
};
|
|
@@ -11,7 +11,7 @@ export declare const RadioContext: React.Context<Omit<RadioProps, "children" | "
|
|
|
11
11
|
declare const Radio: {
|
|
12
12
|
({ currentValue, name, onChange, children, containerProps, }: RadioProps): JSX.Element;
|
|
13
13
|
Element: {
|
|
14
|
-
({ label, value, disabled, variant, ...props }: import("./RadioElement").RadioElementProps): JSX.Element;
|
|
14
|
+
({ label, value, disabled, outlined, variant, ...props }: import("./RadioElement").RadioElementProps): JSX.Element;
|
|
15
15
|
displayName: string;
|
|
16
16
|
};
|
|
17
17
|
ListElement: {
|
|
@@ -1,10 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { GroupBase, StylesConfig, ControlProps } from "react-select";
|
|
2
2
|
import { DefaultTheme } from "styled-components";
|
|
3
|
-
export declare function getStyles<
|
|
4
|
-
|
|
5
|
-
value: string;
|
|
6
|
-
}, M extends boolean = false>(theme: DefaultTheme): NonNullable<Styles<T, M>["control"]>;
|
|
7
|
-
export declare function Control<T extends OptionTypeBase = {
|
|
8
|
-
label: string;
|
|
9
|
-
value: string;
|
|
10
|
-
}, M extends boolean = false>(props: ControlProps<T, M>): JSX.Element;
|
|
3
|
+
export declare function getStyles<O = unknown, M extends boolean = false, G extends GroupBase<O> = GroupBase<O>>(theme: DefaultTheme): NonNullable<StylesConfig<O, M, G>["control"]>;
|
|
4
|
+
export declare function Control<O = unknown, M extends boolean = false, G extends GroupBase<O> = GroupBase<O>>(props: ControlProps<O, M, G>): JSX.Element;
|
|
@@ -5,7 +5,8 @@ export function getStyles(theme) {
|
|
|
5
5
|
return (provided) => (Object.assign(Object.assign({}, provided), { display: "flex", alignItems: "center", width: "100%", border: 0, padding: `0px ${theme.space[7]}px`, boxShadow: "none", borderRadius: "inherit", background: "transparent" }));
|
|
6
6
|
}
|
|
7
7
|
export function Control(props) {
|
|
8
|
-
const { isFocused, selectProps
|
|
8
|
+
const { isFocused, selectProps, children } = props;
|
|
9
|
+
const { isDisabled, error, renderLeft } = selectProps;
|
|
9
10
|
return (React.createElement(InputContainer, { disabled: isDisabled, error: error, focus: isFocused },
|
|
10
11
|
React.createElement(components.Control, Object.assign({}, props),
|
|
11
12
|
renderLeft ? renderLeft(props) : null,
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare function getStyles<
|
|
3
|
-
|
|
4
|
-
value: string;
|
|
5
|
-
}, M extends boolean = false>(): NonNullable<Styles<T, M>["dropdownIndicator"]>;
|
|
6
|
-
export declare function DropdownIndicator<T extends OptionTypeBase = {
|
|
7
|
-
label: string;
|
|
8
|
-
value: string;
|
|
9
|
-
}, M extends boolean = false>(props: IndicatorProps<T, M>): JSX.Element;
|
|
1
|
+
import { GroupBase, StylesConfig, DropdownIndicatorProps } from "react-select";
|
|
2
|
+
export declare function getStyles<O = unknown, M extends boolean = false, G extends GroupBase<O> = GroupBase<O>>(): NonNullable<StylesConfig<O, M, G>["dropdownIndicator"]>;
|
|
3
|
+
export declare function DropdownIndicator<O = unknown, M extends boolean = false, G extends GroupBase<O> = GroupBase<O>>(props: DropdownIndicatorProps<O, M, G>): JSX.Element;
|
|
@@ -1,5 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare function IndicatorsContainer<
|
|
3
|
-
label: string;
|
|
4
|
-
value: string;
|
|
5
|
-
}, M extends boolean = false>(props: IndicatorContainerProps<T, M>): JSX.Element;
|
|
1
|
+
import { GroupBase, IndicatorsContainerProps } from "react-select";
|
|
2
|
+
export declare function IndicatorsContainer<O = unknown, M extends boolean = false, G extends GroupBase<O> = GroupBase<O>>(props: IndicatorsContainerProps<O, M, G>): JSX.Element;
|
|
@@ -2,7 +2,7 @@ import React from "react";
|
|
|
2
2
|
import { components } from "react-select";
|
|
3
3
|
import FlexBox from "../../layout/Flex";
|
|
4
4
|
export function IndicatorsContainer(props) {
|
|
5
|
-
const {
|
|
5
|
+
const { renderRight } = props.selectProps;
|
|
6
6
|
return (React.createElement(FlexBox, { alignItems: "center" },
|
|
7
7
|
renderRight ? renderRight(props) : null,
|
|
8
8
|
React.createElement(components.IndicatorsContainer, Object.assign({}, props))));
|