@ledgerhq/react-ui 0.6.0 → 0.7.3
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/cta/Button/index.d.ts +3 -2
- package/components/cta/Button/index.js +20 -14
- package/components/form/Dropdown/index.js +7 -7
- package/components/form/DropdownGeneric/index.d.ts +42 -0
- package/components/form/DropdownGeneric/index.js +115 -0
- package/components/form/SelectInput/MenuList.js +2 -1
- package/components/form/index.d.ts +1 -0
- package/components/form/index.js +1 -0
- package/components/layout/Drawer/index.d.ts +14 -2
- package/components/layout/Drawer/index.js +30 -38
- package/components/layout/Popin/index.d.ts +2 -1
- package/components/layout/Popin/index.js +10 -5
- package/components/message/Log/index.d.ts +5 -2
- package/components/message/Log/index.js +3 -4
- package/components/navigation/FlowStepper/index.d.ts +136 -0
- package/components/navigation/FlowStepper/index.js +84 -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/package.json +4 -3
- package/styles/InvertTheme.d.ts +4 -1
- package/styles/InvertTheme.js +4 -4
|
@@ -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 })))));
|
|
@@ -15,6 +15,7 @@ interface BaseProps extends BaseStyledProps, BordersProps {
|
|
|
15
15
|
disabled?: boolean;
|
|
16
16
|
}
|
|
17
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;
|
|
@@ -30,11 +31,11 @@ export declare const Base: import("styled-components").StyledComponent<"button",
|
|
|
30
31
|
fontSize: number;
|
|
31
32
|
} & BaseProps, "fontFamily" | "fontSize">;
|
|
32
33
|
declare const ButtonWithRef: {
|
|
33
|
-
({ Icon, iconPosition, iconSize, children, onClick, ...props }: ButtonProps, ref?: React.ForwardedRef<HTMLButtonElement> | undefined): React.ReactElement;
|
|
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>;
|
|
35
36
|
Expand: React.ForwardRefExoticComponent<Pick<ButtonProps & {
|
|
36
37
|
onToggle?: ((arg0: boolean) => void) | undefined;
|
|
37
|
-
}, "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"> & React.RefAttributes<HTMLButtonElement>>;
|
|
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>>;
|
|
38
39
|
};
|
|
39
40
|
export declare type ButtonExpandProps = React.PropsWithChildren<ButtonProps & {
|
|
40
41
|
onToggle?: (arg0: boolean) => void;
|
|
@@ -9,7 +9,7 @@ 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";
|
|
@@ -17,6 +17,7 @@ import fontFamily from "../../../styles/styled/fontFamily";
|
|
|
17
17
|
import { fontSizes } from "../../../styles/theme";
|
|
18
18
|
import { rgba } from "../../../styles/helpers";
|
|
19
19
|
import ChevronBottom from "@ledgerhq/icons-ui/react/ChevronBottomRegular";
|
|
20
|
+
import IconComponent from "../../asorted/Icon";
|
|
20
21
|
const IconContainer = styled.div `
|
|
21
22
|
display: inline-block;
|
|
22
23
|
${(p) => `${p.iconPosition === "left" ? "margin-right" : "margin-left"}: ${p.theme.space[4]}px;`}
|
|
@@ -27,12 +28,12 @@ const getVariantColors = (p) => ({
|
|
|
27
28
|
outline: `
|
|
28
29
|
border-color: ${p.theme.colors.neutral.c100};
|
|
29
30
|
color: ${p.theme.colors.neutral.c100};
|
|
30
|
-
background-color:
|
|
31
|
+
background-color: transparent;
|
|
31
32
|
&:hover, &:focus {
|
|
32
|
-
background-color: ${p.theme.colors.neutral.
|
|
33
|
+
background-color: ${rgba(p.theme.colors.neutral.c100, 0.03)};
|
|
33
34
|
}
|
|
34
35
|
&:active {
|
|
35
|
-
background-color: ${p.theme.colors.neutral.
|
|
36
|
+
background-color: ${rgba(p.theme.colors.neutral.c100, 0.05)};
|
|
36
37
|
}
|
|
37
38
|
`,
|
|
38
39
|
filled: `
|
|
@@ -63,12 +64,12 @@ const getVariantColors = (p) => ({
|
|
|
63
64
|
outline: `
|
|
64
65
|
border-color: ${p.theme.colors.error.c100};
|
|
65
66
|
color: ${p.theme.colors.error.c100};
|
|
66
|
-
background-color:
|
|
67
|
+
background-color: transparent;
|
|
67
68
|
&:hover {
|
|
68
|
-
background-color: ${p.theme.colors.error.
|
|
69
|
+
background-color: ${rgba(p.theme.colors.error.c100, 0.02)};
|
|
69
70
|
}
|
|
70
71
|
&:active {
|
|
71
|
-
background-color: ${p.theme.colors.error.
|
|
72
|
+
background-color: ${rgba(p.theme.colors.error.c100, 0.05)};
|
|
72
73
|
}
|
|
73
74
|
`,
|
|
74
75
|
filled: `
|
|
@@ -83,12 +84,12 @@ const getVariantColors = (p) => ({
|
|
|
83
84
|
outline: `
|
|
84
85
|
border-color: ${p.theme.colors.primary.c80};
|
|
85
86
|
color: ${p.theme.colors.primary.c80};
|
|
86
|
-
background-color:
|
|
87
|
+
background-color: transparent;
|
|
87
88
|
&:hover {
|
|
88
|
-
background-color: ${p.theme.colors.primary.
|
|
89
|
+
background-color: ${rgba(p.theme.colors.primary.c100, 0.02)};
|
|
89
90
|
}
|
|
90
91
|
&:active {
|
|
91
|
-
background-color: ${p.theme.colors.primary.
|
|
92
|
+
background-color: ${rgba(p.theme.colors.primary.c100, 0.05)};
|
|
92
93
|
}
|
|
93
94
|
`,
|
|
94
95
|
filled: `
|
|
@@ -103,7 +104,7 @@ const getVariantColors = (p) => ({
|
|
|
103
104
|
outline: `
|
|
104
105
|
border-color: ${p.theme.colors.neutral.c50};
|
|
105
106
|
color: ${p.theme.colors.neutral.c50};
|
|
106
|
-
background-color:
|
|
107
|
+
background-color: transparent;
|
|
107
108
|
`,
|
|
108
109
|
filled: `
|
|
109
110
|
color: ${p.theme.colors.neutral.c50};
|
|
@@ -156,6 +157,9 @@ export const Base = baseStyled.button.attrs((p) => {
|
|
|
156
157
|
&:active {
|
|
157
158
|
box-shadow: 0 0 0 4px ${(p) => rgba(p.theme.colors.primary.c60, 0.4)};
|
|
158
159
|
}
|
|
160
|
+
&:focus, &:hover {
|
|
161
|
+
box-shadow: 0 0 0 2px ${(p) => rgba(p.theme.colors.primary.c60, 0.4)};
|
|
162
|
+
}
|
|
159
163
|
|
|
160
164
|
${(p) => {
|
|
161
165
|
var _a;
|
|
@@ -194,11 +198,13 @@ export const Base = baseStyled.button.attrs((p) => {
|
|
|
194
198
|
const ContentContainer = styled.div ``;
|
|
195
199
|
const Button = (_a, ref) => {
|
|
196
200
|
var _b;
|
|
197
|
-
var { Icon, iconPosition = "right", iconSize = 16, children, onClick } = _a, props = __rest(_a, ["Icon", "iconPosition", "iconSize", "children", "onClick"]);
|
|
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]);
|
|
198
205
|
return (React.createElement(Base, Object.assign({}, props, { ref: ref, iconButton: !(Icon == null) && !children, onClick: onClick }),
|
|
199
206
|
iconPosition === "right" ? React.createElement(ContentContainer, null, children) : null,
|
|
200
|
-
|
|
201
|
-
React.createElement(Icon, { size: iconSize || fontSizes[(_b = props.fontSize) !== null && _b !== void 0 ? _b : 4] }))) : null,
|
|
207
|
+
IconNode && React.createElement(IconContainer, { iconPosition: iconPosition }, IconNode),
|
|
202
208
|
iconPosition === "left" ? React.createElement(ContentContainer, null, children) : null));
|
|
203
209
|
};
|
|
204
210
|
const ButtonWithRef = React.forwardRef(Button);
|
|
@@ -14,23 +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
21
|
const { selectProps, children } = props;
|
|
22
22
|
const { label } = selectProps;
|
|
23
23
|
return (React.createElement(components.Control, Object.assign({}, props),
|
|
24
|
-
React.createElement(Text, {
|
|
24
|
+
React.createElement(Text, { variant: "paragraph", fontWeight: "medium", color: "neutral.c80", mr: 2 }, label),
|
|
25
25
|
children));
|
|
26
26
|
}
|
|
27
27
|
function DropdownValueContainer(props) {
|
|
28
|
-
const
|
|
29
|
-
return (React.createElement(ValueContainer, Object.assign({}, props, { render: () => (React.createElement(FlexBox,
|
|
30
|
-
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 },
|
|
31
31
|
React.createElement(FlexBox, null, props.children)),
|
|
32
|
-
React.createElement(FlexBox, { alignItems: "center" },
|
|
33
|
-
React.createElement(
|
|
32
|
+
React.createElement(FlexBox, { alignItems: "center", style: { transform: isOpen ? "rotate(180deg)" : "" } },
|
|
33
|
+
React.createElement(Icons.DropdownMedium, { size: 20 })))) })));
|
|
34
34
|
}
|
|
35
35
|
function DropdownIndicatorsContainer() {
|
|
36
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,7 +1,8 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { components } from "react-select";
|
|
3
3
|
export function getStyles(theme) {
|
|
4
|
-
|
|
4
|
+
const isLight = theme.colors.type === "light";
|
|
5
|
+
return (provided) => (Object.assign(Object.assign({}, provided), { display: "flex", flexDirection: "column", gap: theme.space[2], padding: theme.space[3], border: `1px solid ${theme.colors.neutral[isLight ? "c20" : "c30"]}`, borderRadius: "8px", boxShadow: `0px 6px 12px rgba(0, 0, 0, ${isLight ? 0.04 : 0.08})`, background: theme.colors.neutral[isLight ? "c00" : "c20"], color: theme.colors.neutral.c80 }));
|
|
5
6
|
}
|
|
6
7
|
export function MenuList(props) {
|
|
7
8
|
return React.createElement(components.MenuList, Object.assign({}, props), props.children);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { default as Input } from "./BaseInput";
|
|
2
2
|
export { default as Checkbox } from "./Checkbox";
|
|
3
3
|
export { default as Dropdown } from "./Dropdown";
|
|
4
|
+
export { default as DropdownGeneric } from "./DropdownGeneric";
|
|
4
5
|
export { default as LegendInput } from "./LegendInput";
|
|
5
6
|
export { default as NumberInput } from "./NumberInput";
|
|
6
7
|
export { default as QrCodeInput } from "./QrCodeInput";
|
package/components/form/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { default as Input } from "./BaseInput";
|
|
2
2
|
export { default as Checkbox } from "./Checkbox";
|
|
3
3
|
export { default as Dropdown } from "./Dropdown";
|
|
4
|
+
export { default as DropdownGeneric } from "./DropdownGeneric";
|
|
4
5
|
export { default as LegendInput } from "./LegendInput";
|
|
5
6
|
export { default as NumberInput } from "./NumberInput";
|
|
6
7
|
export { default as QrCodeInput } from "./QrCodeInput";
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
+
import { FlexBoxProps } from "../Flex";
|
|
3
|
+
import { Props as DividerProps } from "../../asorted/Divider";
|
|
4
|
+
export declare enum Direction {
|
|
5
|
+
Left = "left",
|
|
6
|
+
Right = "right"
|
|
7
|
+
}
|
|
2
8
|
export interface DrawerProps {
|
|
3
9
|
isOpen: boolean;
|
|
4
10
|
children: React.ReactNode;
|
|
@@ -11,6 +17,12 @@ export interface DrawerProps {
|
|
|
11
17
|
onBack?: () => void;
|
|
12
18
|
setTransitionsEnabled?: (arg0: boolean) => void;
|
|
13
19
|
hideNavigation?: boolean;
|
|
20
|
+
menuPortalTarget?: Element | null;
|
|
21
|
+
direction?: Direction;
|
|
22
|
+
extraContainerProps?: Partial<FlexBoxProps>;
|
|
23
|
+
extraHeaderProps?: Partial<FlexBoxProps>;
|
|
24
|
+
extraFooterProps?: Partial<FlexBoxProps>;
|
|
25
|
+
extraFooterDividerProps?: Partial<DividerProps>;
|
|
14
26
|
}
|
|
15
|
-
declare const
|
|
16
|
-
export default
|
|
27
|
+
declare const _default: React.ForwardRefExoticComponent<DrawerProps & React.RefAttributes<HTMLDivElement>>;
|
|
28
|
+
export default _default;
|
|
@@ -19,26 +19,19 @@ import ArrowLeft from "@ledgerhq/icons-ui/react/ArrowLeftRegular";
|
|
|
19
19
|
import TransitionSlide from "../../transitions/TransitionSlide";
|
|
20
20
|
import TransitionInOut from "../../transitions/TransitionInOut";
|
|
21
21
|
import Text from "../../asorted/Text";
|
|
22
|
+
export var Direction;
|
|
23
|
+
(function (Direction) {
|
|
24
|
+
Direction["Left"] = "left";
|
|
25
|
+
Direction["Right"] = "right";
|
|
26
|
+
})(Direction || (Direction = {}));
|
|
22
27
|
const Container = styled(FlexBox) `
|
|
23
28
|
width: 100%;
|
|
24
29
|
height: 100%;
|
|
25
30
|
flex-direction: column;
|
|
26
31
|
`;
|
|
27
|
-
const
|
|
28
|
-
justify-content: space-between;
|
|
29
|
-
align-items: center;
|
|
30
|
-
padding: ${(p) => p.theme.space[12]}px;
|
|
31
|
-
padding-bottom: ${(p) => p.theme.space[10]}px;
|
|
32
|
-
`;
|
|
33
|
-
const Footer = styled(FlexBox) `
|
|
34
|
-
align-items: center;
|
|
35
|
-
padding: ${(p) => p.theme.space[8]}px ${(p) => p.theme.space[12]}px;
|
|
36
|
-
`;
|
|
37
|
-
const Wrapper = styled.div `
|
|
32
|
+
const Wrapper = styled(FlexBox) `
|
|
38
33
|
height: 100%;
|
|
39
34
|
width: ${(p) => p.big ? p.theme.sizes.drawer.side.big.width : p.theme.sizes.drawer.side.small.width}px;
|
|
40
|
-
background-color: ${(p) => { var _a; return (_a = p.backgroundColor) !== null && _a !== void 0 ? _a : p.theme.colors.neutral.c00; }};
|
|
41
|
-
display: flex;
|
|
42
35
|
flex-direction: column;
|
|
43
36
|
align-items: stretch;
|
|
44
37
|
justify-content: space-between;
|
|
@@ -47,21 +40,15 @@ const Wrapper = styled.div `
|
|
|
47
40
|
const Overlay = styled.div `
|
|
48
41
|
display: flex;
|
|
49
42
|
position: fixed;
|
|
50
|
-
justify-content: flex-end;
|
|
43
|
+
justify-content: ${(p) => (p.direction === Direction.Left ? "flex-end" : "flex-start")};
|
|
51
44
|
top: 0;
|
|
52
45
|
left: 0;
|
|
53
46
|
width: 100vw;
|
|
54
47
|
height: 100vh;
|
|
55
48
|
z-index: 999;
|
|
56
|
-
background-color: ${(p) => p.theme.colors.
|
|
49
|
+
background-color: ${(p) => p.theme.colors.constant.overlay};
|
|
57
50
|
`;
|
|
58
|
-
const ScrollWrapper = styled
|
|
59
|
-
overflow: scroll;
|
|
60
|
-
position: relative;
|
|
61
|
-
padding: ${(p) => p.theme.space[12]}px;
|
|
62
|
-
padding-top: 0px;
|
|
63
|
-
flex: 1;
|
|
64
|
-
|
|
51
|
+
const ScrollWrapper = styled(FlexBox) `
|
|
65
52
|
&::-webkit-scrollbar {
|
|
66
53
|
display: none;
|
|
67
54
|
}
|
|
@@ -75,7 +62,7 @@ const Button = styled.button `
|
|
|
75
62
|
cursor: pointer;
|
|
76
63
|
color: ${(p) => p.theme.colors.neutral.c100};
|
|
77
64
|
`;
|
|
78
|
-
const DrawerContent = ({ isOpen, title, children, footer, big, onClose, backgroundColor, setTransitionsEnabled = () => 0, onBack, ignoreBackdropClick = false, hideNavigation = true, }) => {
|
|
65
|
+
const DrawerContent = React.forwardRef(({ isOpen, title, children, footer, big, onClose, backgroundColor, setTransitionsEnabled = () => 0, onBack, extraContainerProps, extraHeaderProps, extraFooterProps, extraFooterDividerProps, ignoreBackdropClick = false, hideNavigation = true, direction = Direction.Left, }, ref) => {
|
|
79
66
|
const disableChildAnimations = useCallback(() => setTransitionsEnabled(false), [setTransitionsEnabled]);
|
|
80
67
|
const enableChildAnimations = useCallback(() => setTransitionsEnabled(true), [setTransitionsEnabled]);
|
|
81
68
|
const handleBackdropClick = useCallback(() => {
|
|
@@ -87,27 +74,32 @@ const DrawerContent = ({ isOpen, title, children, footer, big, onClose, backgrou
|
|
|
87
74
|
e.stopPropagation();
|
|
88
75
|
}, []);
|
|
89
76
|
return (React.createElement(TransitionInOut, { in: isOpen, appear: true, mountOnEnter: true, unmountOnExit: true, onEntering: disableChildAnimations, onEntered: enableChildAnimations, onExiting: disableChildAnimations },
|
|
90
|
-
React.createElement(Overlay, { onClick: handleBackdropClick },
|
|
91
|
-
React.createElement(TransitionSlide, { in: isOpen, fixed: true, reverseExit: true, appear: true, mountOnEnter: true, unmountOnExit: true },
|
|
92
|
-
React.createElement(Wrapper, { big: big, onClick: stopClickPropagation, backgroundColor: backgroundColor },
|
|
77
|
+
React.createElement(Overlay, { direction: direction, onClick: handleBackdropClick, ref: ref },
|
|
78
|
+
React.createElement(TransitionSlide, { in: isOpen, direction: direction, fixed: true, reverseExit: true, appear: true, mountOnEnter: true, unmountOnExit: true },
|
|
79
|
+
React.createElement(Wrapper, { big: big, onClick: stopClickPropagation, backgroundColor: backgroundColor !== null && backgroundColor !== void 0 ? backgroundColor : "neutral.c00" },
|
|
93
80
|
React.createElement(Container, null,
|
|
94
|
-
React.createElement(
|
|
81
|
+
React.createElement(FlexBox, Object.assign({ justifyContent: "space-between", alignItems: "center", p: 12, pb: 10 }, extraHeaderProps),
|
|
95
82
|
!hideNavigation && (React.createElement(React.Fragment, null, onBack != null ? (React.createElement(Button, { onClick: onBack },
|
|
96
83
|
React.createElement(ArrowLeft, { size: 21 }))) : (React.createElement(ButtonPlaceholder, null)))),
|
|
97
84
|
(React.createElement(Text, { variant: "h3", flex: 1, textAlign: "center" }, title)) || React.createElement("div", null),
|
|
98
85
|
React.createElement(FlexBox, { alignSelf: "flex-start" },
|
|
99
86
|
React.createElement(Button, { onClick: onClose },
|
|
100
87
|
React.createElement(Close, null)))),
|
|
101
|
-
React.createElement(ScrollWrapper,
|
|
88
|
+
React.createElement(ScrollWrapper, Object.assign({ flexDirection: "column", alignItems: "stretch", overflow: "scroll", position: "relative", p: 12, pt: 0, flex: 1 }, extraContainerProps), children),
|
|
102
89
|
footer && (React.createElement(React.Fragment, null,
|
|
103
|
-
React.createElement(Divider, { variant: "light" }),
|
|
104
|
-
React.createElement(
|
|
105
|
-
};
|
|
106
|
-
const Drawer = (_a) => {
|
|
107
|
-
var { children } = _a, sideProps = __rest(_a, ["children"]);
|
|
108
|
-
const $root = React.useMemo(() => document
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
90
|
+
React.createElement(Divider, Object.assign({ variant: "light" }, extraFooterDividerProps)),
|
|
91
|
+
React.createElement(FlexBox, Object.assign({ alignItems: "center", py: 8, px: 12 }, extraFooterProps), footer)))))))));
|
|
92
|
+
});
|
|
93
|
+
const Drawer = (_a, ref) => {
|
|
94
|
+
var { children, menuPortalTarget } = _a, sideProps = __rest(_a, ["children", "menuPortalTarget"]);
|
|
95
|
+
const $root = React.useMemo(() => menuPortalTarget === undefined && typeof document !== undefined
|
|
96
|
+
? document.querySelector("body")
|
|
97
|
+
: menuPortalTarget, [menuPortalTarget]);
|
|
98
|
+
if (!$root) {
|
|
99
|
+
return (React.createElement(DrawerContent, Object.assign({ ref: ref }, sideProps), children));
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
return ReactDOM.createPortal(React.createElement(DrawerContent, Object.assign({ ref: ref }, sideProps), children), $root);
|
|
103
|
+
}
|
|
112
104
|
};
|
|
113
|
-
export default Drawer;
|
|
105
|
+
export default React.forwardRef(Drawer);
|
|
@@ -3,6 +3,7 @@ import { BaseStyledProps } from "../../styled";
|
|
|
3
3
|
export interface PopinProps extends BaseStyledProps {
|
|
4
4
|
isOpen: boolean;
|
|
5
5
|
children: React.ReactNode;
|
|
6
|
+
menuPortalTarget?: Element | null;
|
|
6
7
|
}
|
|
7
8
|
export declare type PopinHeaderProps = BaseStyledProps & {
|
|
8
9
|
onClose?: () => void;
|
|
@@ -10,7 +11,7 @@ export declare type PopinHeaderProps = BaseStyledProps & {
|
|
|
10
11
|
children: React.ReactNode;
|
|
11
12
|
};
|
|
12
13
|
declare const PopinWrapper: {
|
|
13
|
-
({ children, ...popinProps }: PopinProps): React.ReactElement;
|
|
14
|
+
({ children, menuPortalTarget, ...popinProps }: PopinProps): React.ReactElement;
|
|
14
15
|
Header: ({ children, onClose, onBack, ...props }: PopinHeaderProps) => JSX.Element;
|
|
15
16
|
Body: import("styled-components").StyledComponent<"div", import("styled-components").DefaultTheme, import("styled-system").SpaceProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>, string | number | symbol> & import("styled-system").FlexboxProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>> & import("styled-system").PositionProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>> & import("styled-system").ColorProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>, string | number | symbol> & import("styled-system").LayoutProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>> & import("styled-system").BorderProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>, import("csstype").Property.Border<import("styled-system").TLengthStyledSystem>> & import("styled-system").OverflowProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>> & {
|
|
16
17
|
columnGap?: string | number | undefined;
|
|
@@ -82,11 +82,16 @@ const Popin = (_a) => {
|
|
|
82
82
|
React.createElement(Wrapper, Object.assign({ width: width, height: height }, props), children)))));
|
|
83
83
|
};
|
|
84
84
|
const PopinWrapper = (_a) => {
|
|
85
|
-
var { children } = _a, popinProps = __rest(_a, ["children"]);
|
|
86
|
-
const $root = React.useMemo(() => document
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
85
|
+
var { children, menuPortalTarget } = _a, popinProps = __rest(_a, ["children", "menuPortalTarget"]);
|
|
86
|
+
const $root = React.useMemo(() => menuPortalTarget === undefined && typeof document !== undefined
|
|
87
|
+
? document.querySelector("body")
|
|
88
|
+
: menuPortalTarget, [menuPortalTarget]);
|
|
89
|
+
if (!$root) {
|
|
90
|
+
return React.createElement(Popin, Object.assign({}, popinProps), children);
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
return ReactDOM.createPortal(React.createElement(Popin, Object.assign({}, popinProps), children), $root);
|
|
94
|
+
}
|
|
90
95
|
};
|
|
91
96
|
PopinWrapper.Header = PopinHeader;
|
|
92
97
|
PopinWrapper.Body = PopinBody;
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
+
import { TextProps } from "../../asorted/Text";
|
|
2
3
|
import { FlexBoxProps } from "../../layout/Flex";
|
|
3
|
-
export declare type Props = React.PropsWithChildren<FlexBoxProps
|
|
4
|
-
|
|
4
|
+
export declare type Props = React.PropsWithChildren<FlexBoxProps & {
|
|
5
|
+
extraTextProps?: TextProps;
|
|
6
|
+
}>;
|
|
7
|
+
declare function Log({ children, extraTextProps, ...props }: Props): JSX.Element;
|
|
5
8
|
declare const _default: React.MemoExoticComponent<typeof Log>;
|
|
6
9
|
export default _default;
|
|
@@ -19,7 +19,6 @@ const Container = styled(FlexBox) `
|
|
|
19
19
|
flex-wrap: wrap;
|
|
20
20
|
align-items: stretch;
|
|
21
21
|
min-height: ${(p) => p.theme.space[12]}px;
|
|
22
|
-
color: ${(p) => p.theme.colors.neutral.c100};
|
|
23
22
|
`;
|
|
24
23
|
const TextContainer = styled(FlexBox).attrs(() => ({
|
|
25
24
|
flex: "1",
|
|
@@ -31,11 +30,11 @@ const TextContainer = styled(FlexBox).attrs(() => ({
|
|
|
31
30
|
}
|
|
32
31
|
`;
|
|
33
32
|
function Log(_a) {
|
|
34
|
-
var { children } = _a, props = __rest(_a, ["children"]);
|
|
35
|
-
return (React.createElement(Container, Object.assign({}, props),
|
|
33
|
+
var { children, extraTextProps } = _a, props = __rest(_a, ["children", "extraTextProps"]);
|
|
34
|
+
return (React.createElement(Container, Object.assign({ color: "neutral.c100" }, props),
|
|
36
35
|
React.createElement(BracketLeft, null),
|
|
37
36
|
React.createElement(TextContainer, { flex: "1", alignItems: "center", justifyContent: "center" },
|
|
38
|
-
React.createElement(Text, { variant: "h3", textTransform: "uppercase", textAlign: "center" }, children)),
|
|
37
|
+
React.createElement(Text, Object.assign({ variant: "h3", textTransform: "uppercase", textAlign: "center", color: "inherit" }, extraTextProps), children)),
|
|
39
38
|
React.createElement(BracketRight, null)));
|
|
40
39
|
}
|
|
41
40
|
export default memo(Log);
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Props as StepperProps } from "../progress/Stepper";
|
|
3
|
+
import { FlexBoxProps as FlexProps } from "../../layout/Flex";
|
|
4
|
+
export declare type StepProps = {
|
|
5
|
+
/**
|
|
6
|
+
* A specific index, can be used to explicitely order steps.
|
|
7
|
+
*/
|
|
8
|
+
index?: number;
|
|
9
|
+
/**
|
|
10
|
+
* Custom header for this step.
|
|
11
|
+
*/
|
|
12
|
+
header?: React.ReactNode;
|
|
13
|
+
/**
|
|
14
|
+
* Custom footer for this step.
|
|
15
|
+
*/
|
|
16
|
+
footer?: React.ReactNode;
|
|
17
|
+
/**
|
|
18
|
+
* The label of the step.
|
|
19
|
+
*/
|
|
20
|
+
label: string;
|
|
21
|
+
/**
|
|
22
|
+
* Hides the step from the progress stepper.
|
|
23
|
+
*/
|
|
24
|
+
hidden?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* The step contents.
|
|
27
|
+
*/
|
|
28
|
+
children: React.ReactNode;
|
|
29
|
+
};
|
|
30
|
+
interface InnerProps {
|
|
31
|
+
/**
|
|
32
|
+
* The active index.
|
|
33
|
+
*/
|
|
34
|
+
activeIndex: number;
|
|
35
|
+
/**
|
|
36
|
+
* The total number of steps.
|
|
37
|
+
*/
|
|
38
|
+
stepsLength: number;
|
|
39
|
+
}
|
|
40
|
+
declare type StepChild = React.ReactElement<StepProps>;
|
|
41
|
+
declare type SectionRenderFunc<ExtraProps> = (props: InnerProps & ExtraProps) => React.ReactNode;
|
|
42
|
+
declare type SectionStepRenderFunc<ExtraProps> = (args: InnerProps & ExtraProps & {
|
|
43
|
+
children: React.ReactNode;
|
|
44
|
+
}) => React.ReactNode;
|
|
45
|
+
export interface Props<ExtraProps> {
|
|
46
|
+
/**
|
|
47
|
+
* The index of the active step.
|
|
48
|
+
*/
|
|
49
|
+
activeIndex: number;
|
|
50
|
+
/**
|
|
51
|
+
* An optional generic header displayed above the stepper.
|
|
52
|
+
*/
|
|
53
|
+
header?: SectionRenderFunc<ExtraProps>;
|
|
54
|
+
/**
|
|
55
|
+
* Custom rendering function to wrap the header (only used if the `header` is defined
|
|
56
|
+
* on the child for the current step.)
|
|
57
|
+
*/
|
|
58
|
+
renderStepHeader?: SectionStepRenderFunc<ExtraProps>;
|
|
59
|
+
/**
|
|
60
|
+
* An optional generic footer displayed below the body.
|
|
61
|
+
*/
|
|
62
|
+
footer?: SectionRenderFunc<ExtraProps>;
|
|
63
|
+
/**
|
|
64
|
+
* Custom rendering function to wrap the footer (only used if the `footer` is defined
|
|
65
|
+
* on the child for the current step.)
|
|
66
|
+
*/
|
|
67
|
+
renderStepFooter?: SectionStepRenderFunc<ExtraProps>;
|
|
68
|
+
/**
|
|
69
|
+
* Extra props that are passed to the header and footer render functions.
|
|
70
|
+
*/
|
|
71
|
+
extraProps?: ExtraProps;
|
|
72
|
+
/**
|
|
73
|
+
* Extra props that are passed to the container `Flex` element.
|
|
74
|
+
*/
|
|
75
|
+
extraContainerProps?: FlexProps;
|
|
76
|
+
/**
|
|
77
|
+
* Extra props that are passed to the stepper component.
|
|
78
|
+
*/
|
|
79
|
+
extraStepperProps?: Partial<StepperProps>;
|
|
80
|
+
/**
|
|
81
|
+
* Extra props that are passed to the stepper `Flex` wrapper.
|
|
82
|
+
*/
|
|
83
|
+
extraStepperContainerProps?: FlexProps;
|
|
84
|
+
/**
|
|
85
|
+
* Custom rendering function to wrap children.
|
|
86
|
+
*/
|
|
87
|
+
renderChildren?: (args: InnerProps & ExtraProps & {
|
|
88
|
+
children: React.ReactNode;
|
|
89
|
+
}) => React.ReactNode;
|
|
90
|
+
/**
|
|
91
|
+
* A list of children representing each step of the flow.
|
|
92
|
+
* Each child can have a prop `stepHeader` and/or `stepFooter` that will
|
|
93
|
+
* associate a custom header/footer to this particular step.
|
|
94
|
+
* The custom header/footer can be wrapped using the prop renderStepHeader/renderStepFooter.
|
|
95
|
+
*/
|
|
96
|
+
children: StepChild | StepChild[];
|
|
97
|
+
}
|
|
98
|
+
declare function FlowStepper<ExtraProps>({ activeIndex, header, renderStepHeader, footer, renderStepFooter, extraProps, extraContainerProps, extraStepperProps, extraStepperContainerProps, renderChildren, children, }: Props<ExtraProps>): JSX.Element;
|
|
99
|
+
declare namespace FlowStepper {
|
|
100
|
+
var Step: ({ children }: StepProps) => JSX.Element;
|
|
101
|
+
var Indexed: typeof FlowStepperIndexed;
|
|
102
|
+
}
|
|
103
|
+
export default FlowStepper;
|
|
104
|
+
export declare type IndexedStepProps = StepProps & {
|
|
105
|
+
/**
|
|
106
|
+
* String to identify the step. Must be different from sibling steps's `key` prop.
|
|
107
|
+
*/
|
|
108
|
+
itemKey: string;
|
|
109
|
+
};
|
|
110
|
+
declare type IndexedStepperChild = React.ReactElement<IndexedStepProps>;
|
|
111
|
+
export declare type IndexedProps<ExtraProps> = Omit<Props<ExtraProps>, "activeIndex" | "children"> & {
|
|
112
|
+
/**
|
|
113
|
+
* The key of the active step
|
|
114
|
+
*/
|
|
115
|
+
activeKey: string;
|
|
116
|
+
/**
|
|
117
|
+
* A list of children representing each step of the flow.
|
|
118
|
+
*/
|
|
119
|
+
children: IndexedStepperChild | IndexedStepperChild[];
|
|
120
|
+
};
|
|
121
|
+
/**
|
|
122
|
+
* This is a FlowStepper where each child must have an `itemKey: string` prop
|
|
123
|
+
* and the active step is defined by the `activeKey: string` prop.
|
|
124
|
+
*
|
|
125
|
+
* This allows for usages with a lot of steps where dealing with indices could be
|
|
126
|
+
* painful and error prone (for instance inserting/removing a step somewhere would shift
|
|
127
|
+
* the indices of the following steps and navigation would be impacted).
|
|
128
|
+
*
|
|
129
|
+
* By using string identifiers (`itemKey`) for each step, it's more "human readable"
|
|
130
|
+
* and less error prone to setup a navigation logic between steps.
|
|
131
|
+
*/
|
|
132
|
+
declare function FlowStepperIndexed<ExtraProps>(props: IndexedProps<ExtraProps>): JSX.Element;
|
|
133
|
+
declare namespace FlowStepperIndexed {
|
|
134
|
+
var Step: typeof IndexedStep;
|
|
135
|
+
}
|
|
136
|
+
declare function IndexedStep({ children }: IndexedStepProps): JSX.Element;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
+
var t = {};
|
|
3
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
+
t[p] = s[p];
|
|
5
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
+
t[p[i]] = s[p[i]];
|
|
9
|
+
}
|
|
10
|
+
return t;
|
|
11
|
+
};
|
|
12
|
+
import React from "react";
|
|
13
|
+
import { isElement } from "react-is";
|
|
14
|
+
import Flex from "../../layout/Flex";
|
|
15
|
+
import { Stepper } from "..";
|
|
16
|
+
function FlowStepper({ activeIndex, header, renderStepHeader, footer, renderStepFooter, extraProps, extraContainerProps, extraStepperProps, extraStepperContainerProps, renderChildren, children, }) {
|
|
17
|
+
const { steps, innerContents, stepFooter, stepHeader } = React.Children.toArray(children).reduce((acc, child, idx) => {
|
|
18
|
+
var _a;
|
|
19
|
+
const index = (_a = (isElement(child) && child.props.index)) !== null && _a !== void 0 ? _a : idx;
|
|
20
|
+
const label = isElement(child) && child.props.label;
|
|
21
|
+
const hidden = isElement(child) && child.props.hidden;
|
|
22
|
+
const stepHeader = isElement(child) && child.props.header;
|
|
23
|
+
const stepFooter = isElement(child) && child.props.footer;
|
|
24
|
+
if (label && !hidden) {
|
|
25
|
+
acc.steps[index] = label;
|
|
26
|
+
}
|
|
27
|
+
if (index === activeIndex) {
|
|
28
|
+
acc.innerContents = child;
|
|
29
|
+
acc.stepFooter = stepFooter;
|
|
30
|
+
acc.stepHeader = stepHeader;
|
|
31
|
+
}
|
|
32
|
+
return acc;
|
|
33
|
+
}, {
|
|
34
|
+
steps: [],
|
|
35
|
+
innerContents: null,
|
|
36
|
+
stepHeader: null,
|
|
37
|
+
stepFooter: null,
|
|
38
|
+
});
|
|
39
|
+
const renderArgs = Object.assign(Object.assign({}, extraProps), { activeIndex, stepsLength: steps.length });
|
|
40
|
+
function getSectionContents(renderFunc, stepSection, renderStepFunc) {
|
|
41
|
+
return stepSection
|
|
42
|
+
? renderStepFunc
|
|
43
|
+
? renderStepFunc(Object.assign(Object.assign({}, renderArgs), { children: stepSection }))
|
|
44
|
+
: stepSection
|
|
45
|
+
: renderFunc && renderFunc(renderArgs);
|
|
46
|
+
}
|
|
47
|
+
return (React.createElement(Flex, Object.assign({ flex: 1, flexDirection: "column" }, extraContainerProps),
|
|
48
|
+
getSectionContents(header, stepHeader, renderStepHeader),
|
|
49
|
+
React.createElement(Flex, Object.assign({ my: 8, justifyContent: "center" }, extraStepperContainerProps),
|
|
50
|
+
React.createElement(Stepper, Object.assign({ activeIndex: activeIndex, steps: steps, flex: 1 }, extraStepperProps))),
|
|
51
|
+
React.createElement(Flex, { flex: 1, flexDirection: "column", position: "relative" }, renderChildren
|
|
52
|
+
? renderChildren(Object.assign(Object.assign({}, renderArgs), { children: innerContents }))
|
|
53
|
+
: innerContents),
|
|
54
|
+
getSectionContents(footer, stepFooter, renderStepFooter)));
|
|
55
|
+
}
|
|
56
|
+
function Step({ children }) {
|
|
57
|
+
return React.createElement(React.Fragment, null, children);
|
|
58
|
+
}
|
|
59
|
+
FlowStepper.Step = Step;
|
|
60
|
+
export default FlowStepper;
|
|
61
|
+
/**
|
|
62
|
+
* This is a FlowStepper where each child must have an `itemKey: string` prop
|
|
63
|
+
* and the active step is defined by the `activeKey: string` prop.
|
|
64
|
+
*
|
|
65
|
+
* This allows for usages with a lot of steps where dealing with indices could be
|
|
66
|
+
* painful and error prone (for instance inserting/removing a step somewhere would shift
|
|
67
|
+
* the indices of the following steps and navigation would be impacted).
|
|
68
|
+
*
|
|
69
|
+
* By using string identifiers (`itemKey`) for each step, it's more "human readable"
|
|
70
|
+
* and less error prone to setup a navigation logic between steps.
|
|
71
|
+
*/
|
|
72
|
+
function FlowStepperIndexed(props) {
|
|
73
|
+
const { activeKey, children } = props, otherProps = __rest(props, ["activeKey", "children"]);
|
|
74
|
+
const activeIndex = React.Children.toArray(children).findIndex((child) => {
|
|
75
|
+
const res = isElement(child) && child.props.itemKey === activeKey;
|
|
76
|
+
return res;
|
|
77
|
+
});
|
|
78
|
+
return (React.createElement(FlowStepper, Object.assign({}, otherProps, { activeIndex: activeIndex }), children));
|
|
79
|
+
}
|
|
80
|
+
function IndexedStep({ children }) {
|
|
81
|
+
return React.createElement(React.Fragment, null, children);
|
|
82
|
+
}
|
|
83
|
+
FlowStepperIndexed.Step = IndexedStep;
|
|
84
|
+
FlowStepper.Indexed = FlowStepperIndexed;
|
|
@@ -1,10 +1,21 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { BorderProps, ColorProps, SpaceProps } from "styled-system";
|
|
3
|
-
|
|
3
|
+
import { FlexBoxProps } from "../../../layout/Flex";
|
|
4
|
+
/**
|
|
5
|
+
* The state of a progress bar step.
|
|
6
|
+
*/
|
|
7
|
+
export declare type StepState = "pending" | "current" | "completed" | "errored" | "disabled";
|
|
8
|
+
declare type LabelType = string | React.ComponentType<{
|
|
9
|
+
state: StepState;
|
|
10
|
+
}>;
|
|
11
|
+
export interface Props extends FlexBoxProps {
|
|
4
12
|
/**
|
|
5
13
|
* An array of labels that will determine the progress bar steps.
|
|
14
|
+
* A label is either a string or a component that will be rendered with the
|
|
15
|
+
* prop `state: "pending" | "current" | "completed" | "errored"`.
|
|
16
|
+
* A styled StepText component is exported to allow easy styling of such a custom label.
|
|
6
17
|
*/
|
|
7
|
-
steps:
|
|
18
|
+
steps: LabelType[];
|
|
8
19
|
/**
|
|
9
20
|
* Index of the active step, starting at zero and defaulting to 0 if omitted.
|
|
10
21
|
*/
|
|
@@ -13,20 +24,22 @@ export interface Props {
|
|
|
13
24
|
* If true the current step is considered as a failure.
|
|
14
25
|
*/
|
|
15
26
|
errored?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Steps with indexes contained inside the array will be shown as disabled.
|
|
29
|
+
*/
|
|
30
|
+
disabledIndexes?: number[];
|
|
16
31
|
}
|
|
17
|
-
/**
|
|
18
|
-
* The state of a progress bar step.
|
|
19
|
-
*/
|
|
20
|
-
declare type StepState = "pending" | "current" | "completed" | "errored";
|
|
21
32
|
export declare type StepProps = {
|
|
22
33
|
/**
|
|
23
34
|
* State of the step.
|
|
24
35
|
*/
|
|
25
36
|
state: StepState;
|
|
26
37
|
/**
|
|
27
|
-
* The label to display.
|
|
38
|
+
* The label to display. To display more than text, this can be a component that will be rendered with the
|
|
39
|
+
* prop `state: "pending" | "current" | "completed" | "errored" | "disabled"`.
|
|
40
|
+
* A styled StepText component is exported to allow easy styling of such a custom Label
|
|
28
41
|
*/
|
|
29
|
-
label:
|
|
42
|
+
label: LabelType;
|
|
30
43
|
/**
|
|
31
44
|
* If true, hides the left "separator" bar that bridges the gap between the wider separator and the item.
|
|
32
45
|
*/
|
|
@@ -48,9 +61,13 @@ export declare const Item: {
|
|
|
48
61
|
backgroundColor: string;
|
|
49
62
|
} & ColorProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>, string | number | symbol>, "backgroundColor">;
|
|
50
63
|
Completed: () => JSX.Element;
|
|
64
|
+
Disabled: () => JSX.Element;
|
|
51
65
|
Errored: () => JSX.Element;
|
|
52
66
|
};
|
|
67
|
+
export declare const StepText: import("styled-components").StyledComponent<"span", import("styled-components").DefaultTheme, import("../../../asorted/Text").TextProps & {
|
|
68
|
+
state: StepState;
|
|
69
|
+
}, keyof import("../../../asorted/Text").TextProps>;
|
|
53
70
|
export declare const Step: React.NamedExoticComponent<StepProps>;
|
|
54
|
-
declare function
|
|
55
|
-
declare const _default: React.MemoExoticComponent<typeof
|
|
71
|
+
declare function Stepper({ steps, activeIndex, errored, disabledIndexes, ...extraProps }: Props): JSX.Element;
|
|
72
|
+
declare const _default: React.MemoExoticComponent<typeof Stepper>;
|
|
56
73
|
export default _default;
|
|
@@ -1,8 +1,18 @@
|
|
|
1
|
-
|
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
+
var t = {};
|
|
3
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
+
t[p] = s[p];
|
|
5
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
+
t[p[i]] = s[p[i]];
|
|
9
|
+
}
|
|
10
|
+
return t;
|
|
11
|
+
};
|
|
12
|
+
import React, { memo, Fragment } from "react";
|
|
2
13
|
import styled from "styled-components";
|
|
3
14
|
import { border, color, space } from "styled-system";
|
|
4
|
-
import
|
|
5
|
-
import CloseMedium from "@ledgerhq/icons-ui/react/CloseMedium";
|
|
15
|
+
import { Icons } from "../../../../index";
|
|
6
16
|
import Text from "../../../asorted/Text";
|
|
7
17
|
import Flex from "../../../layout/Flex";
|
|
8
18
|
export const Item = {
|
|
@@ -39,15 +49,19 @@ export const Item = {
|
|
|
39
49
|
border-radius: ${(p) => p.theme.space[2]}px;
|
|
40
50
|
${color}
|
|
41
51
|
`,
|
|
42
|
-
Completed: () => React.createElement(
|
|
43
|
-
|
|
52
|
+
Completed: () => React.createElement(Icons.CheckAloneMedium, { size: 16 }),
|
|
53
|
+
Disabled: () => React.createElement(Icons.CloseMedium, { size: 16 }),
|
|
54
|
+
Errored: () => React.createElement(Icons.CloseMedium, { size: 16 }),
|
|
44
55
|
};
|
|
45
|
-
const StepText = styled(Text) `
|
|
56
|
+
export const StepText = styled(Text) `
|
|
46
57
|
color: ${(p) => {
|
|
47
|
-
if (p.errored) {
|
|
58
|
+
if (p.state === "errored") {
|
|
48
59
|
return p.theme.colors.error.c100;
|
|
49
60
|
}
|
|
50
|
-
if (p.
|
|
61
|
+
if (p.state === "disabled") {
|
|
62
|
+
return p.theme.colors.neutral.c50;
|
|
63
|
+
}
|
|
64
|
+
if (p.state === "pending") {
|
|
51
65
|
return p.theme.colors.neutral.c70;
|
|
52
66
|
}
|
|
53
67
|
return p.theme.colors.neutral.c100;
|
|
@@ -74,19 +88,23 @@ const stepContentsByState = {
|
|
|
74
88
|
React.createElement(Item.Completed, null))),
|
|
75
89
|
errored: (React.createElement(Item.Container, { color: "error.c100", backgroundColor: "warning.c30", borderRadius: "8px" },
|
|
76
90
|
React.createElement(Item.Errored, null))),
|
|
91
|
+
disabled: (React.createElement(Item.Container, { color: "neutral.c50" },
|
|
92
|
+
React.createElement(Item.Disabled, null))),
|
|
77
93
|
};
|
|
78
|
-
export const Step = memo(function Step({ state, label, hideLeftSeparator, nextState, }) {
|
|
94
|
+
export const Step = memo(function Step({ state, label: Label, hideLeftSeparator, nextState, }) {
|
|
79
95
|
const inactive = state === "pending";
|
|
80
|
-
const nextInactive =
|
|
81
|
-
const errored = state === "errored";
|
|
96
|
+
const nextInactive = state === "pending";
|
|
82
97
|
return (React.createElement(Flex, { flexDirection: "column", alignItems: "center" },
|
|
83
98
|
React.createElement(Item.Spacer, { mb: 5 },
|
|
84
99
|
(!hideLeftSeparator && React.createElement(Separator.Item, { inactive: inactive, position: "left" })) || (React.createElement(Flex, { flex: "1" })),
|
|
85
100
|
stepContentsByState[state],
|
|
86
101
|
(nextState && React.createElement(Separator.Item, { inactive: nextInactive, position: "right" })) || (React.createElement(Flex, { flex: "1" }))),
|
|
87
|
-
React.createElement(StepText, {
|
|
102
|
+
typeof Label === "string" ? (React.createElement(StepText, { state: state, variant: "small" }, Label)) : (React.createElement(Label, { state: state }))));
|
|
88
103
|
});
|
|
89
|
-
function getState(activeIndex, index, errored) {
|
|
104
|
+
function getState(activeIndex, index, errored, disabled) {
|
|
105
|
+
if (disabled) {
|
|
106
|
+
return "disabled";
|
|
107
|
+
}
|
|
90
108
|
if (activeIndex < index) {
|
|
91
109
|
return "pending";
|
|
92
110
|
}
|
|
@@ -95,13 +113,14 @@ function getState(activeIndex, index, errored) {
|
|
|
95
113
|
}
|
|
96
114
|
return "completed";
|
|
97
115
|
}
|
|
98
|
-
function
|
|
99
|
-
|
|
100
|
-
|
|
116
|
+
function Stepper(_a) {
|
|
117
|
+
var { steps, activeIndex = 0, errored, disabledIndexes } = _a, extraProps = __rest(_a, ["steps", "activeIndex", "errored", "disabledIndexes"]);
|
|
118
|
+
return (React.createElement(Flex, Object.assign({ flexWrap: "nowrap", justifyContent: "space-between" }, extraProps), steps.map((step, idx) => {
|
|
119
|
+
const state = getState(activeIndex, idx, errored, disabledIndexes === null || disabledIndexes === void 0 ? void 0 : disabledIndexes.includes(idx));
|
|
101
120
|
const nextState = idx < steps.length - 1 ? getState(activeIndex, idx + 1) : undefined;
|
|
102
|
-
return (React.createElement(
|
|
121
|
+
return (React.createElement(Fragment, { key: idx },
|
|
103
122
|
idx > 0 && React.createElement(Separator.Step, { inactive: state === "pending" }),
|
|
104
123
|
React.createElement(Step, { label: step, state: state, nextState: nextState, hideLeftSeparator: idx === 0 })));
|
|
105
124
|
})));
|
|
106
125
|
}
|
|
107
|
-
export default memo(
|
|
126
|
+
export default memo(Stepper);
|
|
@@ -11,24 +11,26 @@ const Nav = styled(Flex) `
|
|
|
11
11
|
padding: ${(p) => `${p.theme.space[19]}px ${p.theme.space[5]}px 0`};
|
|
12
12
|
row-gap: 1.5rem;
|
|
13
13
|
height: 100vh;
|
|
14
|
-
|
|
14
|
+
width: 14.875rem;
|
|
15
15
|
color: ${(props) => props.theme.colors.neutral.c100};
|
|
16
16
|
border-right: 1px solid ${(props) => props.theme.colors.neutral.c40};
|
|
17
17
|
background-color: ${(props) => props.theme.colors.background.main};
|
|
18
|
-
transition:
|
|
19
|
-
will-change:
|
|
18
|
+
transition: width 200ms;
|
|
19
|
+
will-change: width;
|
|
20
|
+
flex-shrink: 0;
|
|
21
|
+
z-index: ${(p) => p.theme.zIndexes[2]};
|
|
20
22
|
|
|
21
23
|
&.nav-enter {
|
|
22
|
-
|
|
24
|
+
width: ${(p) => p.theme.space[19]}px;
|
|
23
25
|
}
|
|
24
26
|
&.nav-enter-done {
|
|
25
|
-
|
|
27
|
+
width: 14.875rem;
|
|
26
28
|
}
|
|
27
29
|
&.nav-exit {
|
|
28
|
-
|
|
30
|
+
width: 14.875rem;
|
|
29
31
|
}
|
|
30
32
|
&.nav-exit-done {
|
|
31
|
-
|
|
33
|
+
width: ${(p) => `${p.theme.space[19]}px`};
|
|
32
34
|
}
|
|
33
35
|
`;
|
|
34
36
|
const TransparentMouseZone = styled.div `
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ledgerhq/react-ui",
|
|
3
3
|
"description": "Ledger Live - Desktop UI",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.7.3",
|
|
5
5
|
"author": "Ledger Live Team <team-live@ledger.fr>",
|
|
6
6
|
"repository": "https://github.com/LedgerHQ/ui",
|
|
7
7
|
"license": "MIT",
|
|
@@ -27,8 +27,9 @@
|
|
|
27
27
|
"index.js"
|
|
28
28
|
],
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@
|
|
31
|
-
"@ledgerhq/ui
|
|
30
|
+
"@floating-ui/react-dom": "^0.4.0",
|
|
31
|
+
"@ledgerhq/icons-ui": "^0.2.3",
|
|
32
|
+
"@ledgerhq/ui-shared": "^0.1.5",
|
|
32
33
|
"@tippyjs/react": "^4.2.6",
|
|
33
34
|
"@types/color": "^3.0.2",
|
|
34
35
|
"@types/react": "~17.0.37",
|
package/styles/InvertTheme.d.ts
CHANGED
|
@@ -1,2 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
export declare
|
|
2
|
+
export declare type Props = {
|
|
3
|
+
if?: boolean;
|
|
4
|
+
};
|
|
5
|
+
export declare const InvertTheme: ({ if: condition, children, }: React.PropsWithChildren<Props>) => React.ReactElement;
|
package/styles/InvertTheme.js
CHANGED
|
@@ -2,9 +2,9 @@ import React, { useMemo } from "react";
|
|
|
2
2
|
import { ThemeProvider, useTheme } from "styled-components";
|
|
3
3
|
import { defaultTheme } from ".";
|
|
4
4
|
import { palettes } from "@ledgerhq/ui-shared";
|
|
5
|
-
export const InvertTheme = ({ children }) => {
|
|
6
|
-
const
|
|
7
|
-
const revertTheme = theme === "light" ? "dark" : "light";
|
|
5
|
+
export const InvertTheme = ({ if: condition, children, }) => {
|
|
6
|
+
const theme = useTheme();
|
|
7
|
+
const revertTheme = theme.theme === "light" ? "dark" : "light";
|
|
8
8
|
const newTheme = useMemo(() => (Object.assign(Object.assign({}, defaultTheme), { colors: Object.assign(Object.assign({}, palettes[revertTheme]), { palette: palettes[revertTheme] }), theme: revertTheme })), [revertTheme]);
|
|
9
|
-
return React.createElement(ThemeProvider, { theme: newTheme }, children);
|
|
9
|
+
return React.createElement(ThemeProvider, { theme: condition ? newTheme : theme }, children);
|
|
10
10
|
};
|