@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.
Files changed (60) hide show
  1. package/components/asorted/Divider/index.d.ts +1 -1
  2. package/components/asorted/Icon/BoxedIcon.js +6 -2
  3. package/components/asorted/index.d.ts +1 -1
  4. package/components/asorted/index.js +1 -1
  5. package/components/cta/Button/index.d.ts +11 -8
  6. package/components/cta/Button/index.js +34 -23
  7. package/components/form/BaseInput/index.js +1 -1
  8. package/components/form/Dropdown/index.d.ts +3 -2
  9. package/components/form/Dropdown/index.js +9 -8
  10. package/components/form/DropdownGeneric/index.d.ts +42 -0
  11. package/components/form/DropdownGeneric/index.js +115 -0
  12. package/components/form/Radio/RadioElement.d.ts +3 -2
  13. package/components/form/Radio/RadioElement.js +72 -3
  14. package/components/form/Radio/index.d.ts +1 -1
  15. package/components/form/SelectInput/Control.d.ts +3 -9
  16. package/components/form/SelectInput/Control.js +2 -1
  17. package/components/form/SelectInput/DropdownIndicator.d.ts +3 -9
  18. package/components/form/SelectInput/IndicatorsContainer.d.ts +2 -5
  19. package/components/form/SelectInput/IndicatorsContainer.js +1 -1
  20. package/components/form/SelectInput/MenuList.d.ts +3 -9
  21. package/components/form/SelectInput/MenuList.js +2 -1
  22. package/components/form/SelectInput/Option.d.ts +6 -18
  23. package/components/form/SelectInput/ValueContainer.d.ts +5 -14
  24. package/components/form/SelectInput/ValueContainer.js +1 -1
  25. package/components/form/SelectInput/VirtualMenuList.d.ts +2 -5
  26. package/components/form/SelectInput/VirtualMenuList.js +2 -1
  27. package/components/form/SelectInput/index.d.ts +7 -16
  28. package/components/form/SelectInput/index.js +9 -1
  29. package/components/form/index.d.ts +1 -0
  30. package/components/form/index.js +1 -0
  31. package/components/layout/Drawer/index.d.ts +17 -2
  32. package/components/layout/Drawer/index.js +45 -36
  33. package/components/layout/Popin/index.d.ts +2 -1
  34. package/components/layout/Popin/index.js +10 -5
  35. package/components/loaders/InfiniteLoader/index.d.ts +8 -7
  36. package/components/loaders/InfiniteLoader/index.js +35 -9
  37. package/components/loaders/ProgressLoader/index.d.ts +22 -1
  38. package/components/loaders/ProgressLoader/index.js +10 -12
  39. package/components/message/Alert/index.d.ts +20 -11
  40. package/components/message/Alert/index.js +6 -7
  41. package/components/message/Log/index.d.ts +5 -2
  42. package/components/message/Log/index.js +3 -4
  43. package/components/navigation/FlowStepper/index.d.ts +77 -0
  44. package/components/navigation/FlowStepper/index.js +35 -0
  45. package/components/navigation/index.d.ts +1 -0
  46. package/components/navigation/index.js +1 -0
  47. package/components/navigation/progress/Stepper/index.d.ts +27 -10
  48. package/components/navigation/progress/Stepper/index.js +37 -18
  49. package/components/navigation/sideBar/SideBar/SideBar.js +9 -7
  50. package/index.d.ts +1 -1
  51. package/index.js +1 -1
  52. package/package.json +5 -5
  53. package/styles/InvertTheme.d.ts +4 -1
  54. package/styles/InvertTheme.js +5 -5
  55. package/styles/index.d.ts +1 -0
  56. package/styles/index.js +1 -0
  57. package/styles/theme.d.ts +1 -1
  58. package/styles/theme.js +7 -7
  59. package/components/loaders/InfiniteLoader/image.d.ts +0 -2
  60. package/components/loaders/InfiniteLoader/image.js +0 -1
@@ -1,4 +1,4 @@
1
- declare type Props = {
1
+ export declare type Props = {
2
2
  variant: "default" | "light";
3
3
  };
4
4
  declare const _default: ({ variant }: Props) => JSX.Element;
@@ -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 && `clip-path: ${getTopRightSquareClippedPolygon(p.size, 15)};`;
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 })))));
@@ -1,3 +1,3 @@
1
1
  export { default as Divider } from "./Divider";
2
- export { default as Icon, IconBox } from "./Icon";
2
+ export { default as Icon, IconBox, BoxedIcon } from "./Icon";
3
3
  export { default as Text } from "./Text";
@@ -1,3 +1,3 @@
1
1
  export { default as Divider } from "./Divider";
2
- export { default as Icon, IconBox } from "./Icon";
2
+ export { default as Icon, IconBox, BoxedIcon } from "./Icon";
3
3
  export { default as Text } from "./Text";
@@ -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: (event?: React.SyntheticEvent<HTMLButtonElement>) => void;
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 Button: {
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 ExpandButtonProps = React.PropsWithChildren<{
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 const ExpandButton: ({ onToggle, onClick, ...props }: ExpandButtonProps) => React.ReactElement;
41
- export default Button;
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: ${p.theme.colors.neutral.c00};
31
+ background-color: transparent;
30
32
  &:hover, &:focus {
31
- background-color: ${p.theme.colors.neutral.c20};
33
+ background-color: ${rgba(p.theme.colors.neutral.c100, 0.03)};
32
34
  }
33
35
  &:active {
34
- background-color: ${p.theme.colors.neutral.c30};
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: ${p.theme.colors.neutral.c00};
67
+ background-color: transparent;
66
68
  &:hover {
67
- background-color: ${p.theme.colors.error.c10};
69
+ background-color: ${rgba(p.theme.colors.error.c100, 0.02)};
68
70
  }
69
71
  &:active {
70
- background-color: ${p.theme.colors.error.c30};
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: ${p.theme.colors.neutral.c00};
87
+ background-color: transparent;
86
88
  &:hover {
87
- background-color: ${p.theme.colors.primary.c10};
89
+ background-color: ${rgba(p.theme.colors.primary.c100, 0.02)};
88
90
  }
89
91
  &:active {
90
- background-color: ${p.theme.colors.primary.c20};
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: ${p.theme.colors.neutral.c00};
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
- return (React.createElement(Base, Object.assign({}, props, { iconButton: !(Icon == null) && !children, onClick: 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]);
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
- Icon != null ? (React.createElement(IconContainer, { iconPosition: iconPosition },
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 StyledExpandButton = styled(Button).attrs((props) => ({
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 const ExpandButton = function ExpandButton(_a) {
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(StyledExpandButton, Object.assign({}, props, { expanded: expanded, onClick: (event) => {
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
- export default Button;
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.48)};
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: { label }, children, } = props;
21
+ const { selectProps, children } = props;
22
+ const { label } = selectProps;
22
23
  return (React.createElement(components.Control, Object.assign({}, props),
23
- React.createElement(Text, { fontWeight: "semiBold", variant: "paragraph", color: "neutral.c80", mr: 2 }, label),
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 ChevronIcon = props.selectProps.menuIsOpen ? ChevronTopMedium : ChevronBottomMedium;
28
- return (React.createElement(ValueContainer, Object.assign({}, props, { render: () => (React.createElement(FlexBox, null,
29
- React.createElement(Text, { fontWeight: "semiBold", variant: "paragraph", mr: 2 },
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(ChevronIcon, { size: 12 })))) })));
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, null,
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 { Styles, ControlProps, OptionTypeBase } from "react-select";
1
+ import { GroupBase, StylesConfig, ControlProps } from "react-select";
2
2
  import { DefaultTheme } from "styled-components";
3
- export declare function getStyles<T extends OptionTypeBase = {
4
- label: string;
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: { isDisabled, error, renderLeft }, children, } = props;
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 { Styles, IndicatorProps, OptionTypeBase } from "react-select";
2
- export declare function getStyles<T extends OptionTypeBase = {
3
- label: string;
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 { IndicatorContainerProps, OptionTypeBase } from "react-select";
2
- export declare function IndicatorsContainer<T extends OptionTypeBase = {
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 { selectProps: { renderRight }, } = props;
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))));