@fibery/ui-kit 1.27.1 → 1.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fibery/ui-kit",
3
- "version": "1.27.1",
3
+ "version": "1.28.0",
4
4
  "private": false,
5
5
  "files": [
6
6
  "src/antd/styles.ts",
@@ -32,7 +32,8 @@
32
32
  "src/dropdown-menu",
33
33
  "src/shortcut-badge",
34
34
  "src/tsfixme",
35
- "src/togle.tsx"
35
+ "src/toggle.tsx",
36
+ "src/toggle-on-off.tsx"
36
37
  ],
37
38
  "license": "UNLICENSED",
38
39
  "dependencies": {
@@ -0,0 +1,36 @@
1
+ import chroma from "chroma-js";
2
+ import {FC, ComponentProps, useMemo} from "react";
3
+ import {opacity, ThemeColors} from "./design-system";
4
+ import {useTheme} from "./theme-provider";
5
+ import {Toggle} from "./toggle";
6
+
7
+ const getBackgroundColors = (accentColor: string | undefined, theme: ThemeColors) => {
8
+ return accentColor && chroma.valid(accentColor)
9
+ ? {
10
+ enabledColor: accentColor,
11
+ disabledColor: chroma(accentColor).alpha(opacity.opacity35).css(),
12
+ }
13
+ : {
14
+ enabledColor: theme.primaryBlue,
15
+ disabledColor: theme.disabledTextColor,
16
+ };
17
+ };
18
+
19
+ interface ToggleOnOffProps extends Omit<ComponentProps<typeof Toggle>, "backgroundColor"> {
20
+ color?: string;
21
+ }
22
+
23
+ export const ToggleOnOff: FC<ToggleOnOffProps> = ({value, color, ...rest}) => {
24
+ const theme = useTheme();
25
+ const {enabledColor, disabledColor} = useMemo(() => getBackgroundColors(color, theme), [color, theme]);
26
+ return <Toggle value={Boolean(value)} backgroundColor={value ? enabledColor : disabledColor} {...rest} />;
27
+ };
28
+
29
+ interface ReduxFormToggleOnOffProps extends ToggleOnOffProps {
30
+ input?: ToggleOnOffProps;
31
+ }
32
+
33
+ export const ReduxFormToggleOnOff: FC<ReduxFormToggleOnOffProps> = ({input, ...rest}) => {
34
+ const theme = useTheme();
35
+ return <ToggleOnOff color={theme.primaryBlue} {...input} {...rest} />;
36
+ };
package/src/toggle.tsx ADDED
@@ -0,0 +1,158 @@
1
+ import {css, cx} from "@linaria/core";
2
+ import {styled} from "@linaria/react";
3
+ import chroma from "chroma-js";
4
+ import {ComponentProps, FC, ReactNode} from "react";
5
+ import {layout, space, textStyles, transition} from "./design-system";
6
+ import _ from "lodash";
7
+
8
+ const Input = styled.input<{containerSize: number; containerWidth: number; outlineColor: string}>`
9
+ position: absolute;
10
+ cursor: pointer;
11
+ top: 0;
12
+ left: 0;
13
+ appearance: none;
14
+ margin-right: 0;
15
+ background-color: transparent;
16
+ height: ${({containerSize}) => containerSize}px;
17
+ width: ${({containerWidth}) => containerWidth}px;
18
+ border-radius: ${({containerSize}) => containerSize / 2}px;
19
+
20
+ &:focus {
21
+ outline: none;
22
+ }
23
+
24
+ &:focus-visible {
25
+ box-shadow: ${({outlineColor}) => `inset 0 0 0 1px ${outlineColor}`};
26
+ }
27
+ `;
28
+
29
+ const Label = styled.div<{labelPosition: "last" | "first"; disabled?: boolean}>`
30
+ ${textStyles.regular}
31
+ margin-left: ${({labelPosition}) => (labelPosition === "last" ? `${space.s8}px` : 0)};
32
+ margin-right: ${({labelPosition}) => (labelPosition === "first" ? `${space.s8}px` : 0)};
33
+ opacity: ${({disabled}) => (disabled ? 0.5 : 1)};
34
+ line-height: ${layout.checkboxSize}px;
35
+ width: 100%;
36
+ `;
37
+
38
+ const labelWrapperStyle = css`
39
+ display: flex;
40
+ position: relative;
41
+ align-items: center;
42
+ `;
43
+
44
+ const getOutlineColor = _.memoize((color: string) => {
45
+ const alpha = chroma(color).alpha();
46
+ if (alpha < 1) {
47
+ return chroma(color)
48
+ .alpha(alpha + 0.3)
49
+ .css();
50
+ } else {
51
+ return chroma(color).darken(1).css();
52
+ }
53
+ });
54
+
55
+ const CircleContainer = styled.div<{
56
+ containerSize: number;
57
+ containerWidth: number;
58
+ backgroundColor: string;
59
+ disabled?: boolean;
60
+ }>`
61
+ position: relative;
62
+ height: ${({containerSize}) => containerSize}px;
63
+ width: ${({containerWidth}) => containerWidth}px;
64
+ flex-shrink: 0;
65
+ border-radius: ${({containerSize}) => containerSize / 2}px;
66
+ background-color: ${({backgroundColor}) => backgroundColor};
67
+ padding: ${space.s2}px;
68
+ transition: background-color ${transition};
69
+ opacity: ${({disabled}) => (disabled ? 0.5 : 1)};
70
+ `;
71
+
72
+ const Circle = styled.div<{containerSize: number}>`
73
+ height: ${({containerSize}) => containerSize - space.s2 * 2}px;
74
+ width: ${({containerSize}) => containerSize - space.s2 * 2}px;
75
+ border-radius: ${({containerSize}) => containerSize / 2 - space.s2}px;
76
+ background-color: white;
77
+ transition: transform ${transition};
78
+ `;
79
+
80
+ interface ToggleProps extends Omit<ComponentProps<"input">, "value"> {
81
+ value?: boolean;
82
+ label?: ReactNode;
83
+ labelTitle?: string;
84
+ backgroundColor: string;
85
+ labelPosition?: "first" | "last";
86
+ wrapperClassName?: string;
87
+ }
88
+
89
+ export const Toggle: FC<ToggleProps> = ({
90
+ value,
91
+ label,
92
+ labelTitle,
93
+ disabled = false,
94
+ backgroundColor,
95
+ size = 16,
96
+ onChange,
97
+ labelPosition = "last",
98
+ className,
99
+ wrapperClassName,
100
+ ...rest
101
+ }) => {
102
+ const width = size * 1.75;
103
+ const outlineColor = getOutlineColor(backgroundColor);
104
+
105
+ const circleTransformStyle = {
106
+ transform: `translateX(${value ? width - size : 0}px)`,
107
+ };
108
+
109
+ return (
110
+ <label
111
+ className={cx(
112
+ wrapperClassName,
113
+ labelWrapperStyle,
114
+ disabled
115
+ ? css`
116
+ cursor: default;
117
+ `
118
+ : css`
119
+ cursor: pointer;
120
+ `,
121
+ labelPosition === "first"
122
+ ? css`
123
+ flex-direction: row-reverse;
124
+ `
125
+ : css`
126
+ flex-direction: row;
127
+ `
128
+ )}
129
+ title={labelTitle}
130
+ >
131
+ <CircleContainer
132
+ containerSize={size}
133
+ containerWidth={width}
134
+ backgroundColor={backgroundColor}
135
+ disabled={disabled}
136
+ >
137
+ <Circle containerSize={size} style={circleTransformStyle} />
138
+ <Input
139
+ containerSize={size}
140
+ containerWidth={width}
141
+ outlineColor={outlineColor}
142
+ onChange={onChange}
143
+ className={className}
144
+ type="checkbox"
145
+ disabled={disabled}
146
+ checked={value}
147
+ {...rest}
148
+ />
149
+ </CircleContainer>
150
+
151
+ {label && (
152
+ <Label disabled={disabled} labelPosition={labelPosition}>
153
+ {label}
154
+ </Label>
155
+ )}
156
+ </label>
157
+ );
158
+ };