@snack-uikit/toggles 0.7.1-preview-104ad22c.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/CHANGELOG.md +357 -0
- package/LICENSE +201 -0
- package/README.md +169 -0
- package/dist/components/Checkbox/Checkbox.d.ts +12 -0
- package/dist/components/Checkbox/Checkbox.js +41 -0
- package/dist/components/Checkbox/index.d.ts +1 -0
- package/dist/components/Checkbox/index.js +1 -0
- package/dist/components/Checkbox/styles.module.css +86 -0
- package/dist/components/Favorite/Favorite.d.ts +10 -0
- package/dist/components/Favorite/Favorite.js +36 -0
- package/dist/components/Favorite/index.d.ts +1 -0
- package/dist/components/Favorite/index.js +1 -0
- package/dist/components/Favorite/styles.module.css +47 -0
- package/dist/components/Radio/Radio.d.ts +7 -0
- package/dist/components/Radio/Radio.js +24 -0
- package/dist/components/Radio/index.d.ts +1 -0
- package/dist/components/Radio/index.js +1 -0
- package/dist/components/Radio/styles.module.css +90 -0
- package/dist/components/Switch/Switch.d.ts +10 -0
- package/dist/components/Switch/Switch.js +27 -0
- package/dist/components/Switch/index.d.ts +1 -0
- package/dist/components/Switch/index.js +1 -0
- package/dist/components/Switch/styles.module.css +150 -0
- package/dist/components/ToggleGroup/ToggleGroup.d.ts +28 -0
- package/dist/components/ToggleGroup/ToggleGroup.js +31 -0
- package/dist/components/ToggleGroup/hooks.d.ts +9 -0
- package/dist/components/ToggleGroup/hooks.js +23 -0
- package/dist/components/ToggleGroup/index.d.ts +2 -0
- package/dist/components/ToggleGroup/index.js +2 -0
- package/dist/components/TogglePrivate/TogglePrivate.d.ts +22 -0
- package/dist/components/TogglePrivate/TogglePrivate.js +38 -0
- package/dist/components/TogglePrivate/index.d.ts +1 -0
- package/dist/components/TogglePrivate/index.js +1 -0
- package/dist/components/TogglePrivate/styles.module.css +38 -0
- package/dist/components/index.d.ts +5 -0
- package/dist/components/index.js +5 -0
- package/dist/components/styles.module.css +0 -0
- package/dist/constants.d.ts +16 -0
- package/dist/constants.js +20 -0
- package/dist/context.d.ts +10 -0
- package/dist/context.js +8 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/types.d.ts +47 -0
- package/dist/types.js +1 -0
- package/dist/utils.d.ts +4 -0
- package/dist/utils.js +18 -0
- package/package.json +42 -0
- package/src/components/Checkbox/Checkbox.tsx +72 -0
- package/src/components/Checkbox/index.ts +1 -0
- package/src/components/Checkbox/styles.module.scss +77 -0
- package/src/components/Favorite/Favorite.tsx +54 -0
- package/src/components/Favorite/index.ts +1 -0
- package/src/components/Favorite/styles.module.scss +36 -0
- package/src/components/Radio/Radio.tsx +30 -0
- package/src/components/Radio/index.ts +1 -0
- package/src/components/Radio/styles.module.scss +74 -0
- package/src/components/Switch/Switch.tsx +50 -0
- package/src/components/Switch/index.ts +1 -0
- package/src/components/Switch/styles.module.scss +124 -0
- package/src/components/ToggleGroup/ToggleGroup.tsx +76 -0
- package/src/components/ToggleGroup/hooks.ts +34 -0
- package/src/components/ToggleGroup/index.ts +2 -0
- package/src/components/TogglePrivate/TogglePrivate.tsx +69 -0
- package/src/components/TogglePrivate/index.ts +1 -0
- package/src/components/TogglePrivate/styles.module.scss +56 -0
- package/src/components/index.ts +5 -0
- package/src/components/styles.module.scss +24 -0
- package/src/constants.ts +19 -0
- package/src/context.ts +17 -0
- package/src/index.ts +1 -0
- package/src/types.ts +71 -0
- package/src/utils.ts +21 -0
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
.container{
|
|
2
|
+
display:flex;
|
|
3
|
+
align-items:center;
|
|
4
|
+
justify-content:center;
|
|
5
|
+
box-sizing:border-box;
|
|
6
|
+
}
|
|
7
|
+
.container[data-size=s]{
|
|
8
|
+
width:var(--size-toggles-s-container-switch-width, 24px);
|
|
9
|
+
height:var(--size-toggles-s-container, 16px);
|
|
10
|
+
border-radius:var(--radius-toggles-s-box-switch, 16px);
|
|
11
|
+
}
|
|
12
|
+
.container[data-size=m]{
|
|
13
|
+
width:var(--size-toggles-m-container-switch-width, 36px);
|
|
14
|
+
height:var(--size-toggles-m-container, 24px);
|
|
15
|
+
border-radius:var(--radius-toggles-m-box-switch, 16px);
|
|
16
|
+
}
|
|
17
|
+
.container[data-focusvisible=true]{
|
|
18
|
+
outline-width:var(--border-state-focus-s-border-width, 2px);
|
|
19
|
+
outline-style:var(--border-state-focus-s-border-style, solid);
|
|
20
|
+
outline-color:var(--border-state-focus-s-border-color, );
|
|
21
|
+
}
|
|
22
|
+
.container[data-focusvisible=true][data-size=s]{
|
|
23
|
+
outline-offset:var(--border-width-state-focus-s, 2px);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.box{
|
|
27
|
+
position:relative;
|
|
28
|
+
background-color:var(--sys-neutral-accent-default, #757575);
|
|
29
|
+
}
|
|
30
|
+
.box[data-size=s]{
|
|
31
|
+
width:var(--size-toggles-s-box-switch-width, 24px);
|
|
32
|
+
height:var(--size-toggles-s-box-switch-height, 16px);
|
|
33
|
+
border-radius:var(--radius-toggles-s-box-switch, 16px);
|
|
34
|
+
}
|
|
35
|
+
.box[data-size=m]{
|
|
36
|
+
width:var(--size-toggles-m-box-switch-width, 32px);
|
|
37
|
+
height:var(--size-toggles-m-box-switch-height, 20px);
|
|
38
|
+
border-radius:var(--radius-toggles-m-box-switch, 16px);
|
|
39
|
+
}
|
|
40
|
+
.box[data-hover=true]{
|
|
41
|
+
background-color:var(--sys-neutral-accent-hovered, #666666);
|
|
42
|
+
}
|
|
43
|
+
.box[data-disabled=true]{
|
|
44
|
+
background-color:var(--sys-neutral-decor-disabled, #e7e7e7);
|
|
45
|
+
}
|
|
46
|
+
.box[data-checked=true]{
|
|
47
|
+
background-color:var(--sys-primary-accent-default, #794ed3);
|
|
48
|
+
}
|
|
49
|
+
.box[data-checked=true][data-hover=true]{
|
|
50
|
+
background-color:var(--sys-primary-accent-hovered, #6851a6);
|
|
51
|
+
}
|
|
52
|
+
.box[data-checked=true][data-disabled=true]{
|
|
53
|
+
background-color:var(--sys-neutral-decor-disabled, #e7e7e7);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.containerFlag{
|
|
57
|
+
position:absolute;
|
|
58
|
+
left:0;
|
|
59
|
+
display:flex;
|
|
60
|
+
align-items:center;
|
|
61
|
+
justify-content:center;
|
|
62
|
+
transition-timing-function:linear;
|
|
63
|
+
transition-duration:0.1s;
|
|
64
|
+
transition-property:left;
|
|
65
|
+
}
|
|
66
|
+
.containerFlag[data-size=s]{
|
|
67
|
+
width:var(--size-toggles-s-container, 16px);
|
|
68
|
+
height:var(--size-toggles-s-container, 16px);
|
|
69
|
+
}
|
|
70
|
+
.containerFlag[data-size=s][data-checked=true]{
|
|
71
|
+
left:calc(100% - var(--size-toggles-s-container, 16px));
|
|
72
|
+
}
|
|
73
|
+
.containerFlag[data-size=m]{
|
|
74
|
+
width:var(--size-toggles-m-container, 24px);
|
|
75
|
+
height:var(--size-toggles-m-container, 24px);
|
|
76
|
+
}
|
|
77
|
+
.containerFlag[data-size=m][data-checked=true]{
|
|
78
|
+
left:calc(100% - var(--size-toggles-m-container, 24px));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.flag{
|
|
82
|
+
background-color:var(--sys-neutral-on-accent, #fdfdfd);
|
|
83
|
+
}
|
|
84
|
+
.flag[data-size=s]{
|
|
85
|
+
border-radius:var(--radius-toggles-s-box-switch, 16px);
|
|
86
|
+
width:var(--size-toggles-s-flag-switch, 12px);
|
|
87
|
+
height:var(--size-toggles-s-flag-switch, 12px);
|
|
88
|
+
}
|
|
89
|
+
.flag[data-size=m]{
|
|
90
|
+
border-radius:var(--radius-toggles-m-box-switch, 16px);
|
|
91
|
+
width:var(--size-toggles-m-flag-switch, 16px);
|
|
92
|
+
height:var(--size-toggles-m-flag-switch, 16px);
|
|
93
|
+
}
|
|
94
|
+
.flag[data-disabled=true]{
|
|
95
|
+
background-color:var(--sys-neutral-text-disabled, #9e9e9e);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.flag_icon_off{
|
|
99
|
+
position:absolute;
|
|
100
|
+
top:50%;
|
|
101
|
+
left:50%;
|
|
102
|
+
transform:translate(-50%, -50%);
|
|
103
|
+
display:flex;
|
|
104
|
+
color:var(--sys-neutral-accent-default, #757575);
|
|
105
|
+
fill:transparent;
|
|
106
|
+
transition:opacity 0.1s linear;
|
|
107
|
+
opacity:1;
|
|
108
|
+
}
|
|
109
|
+
.flag_icon_off[data-hover=true]{
|
|
110
|
+
color:var(--sys-neutral-accent-hovered, #666666);
|
|
111
|
+
}
|
|
112
|
+
.flag_icon_off[data-checked=true]{
|
|
113
|
+
color:var(--sys-primary-accent-default, #794ed3);
|
|
114
|
+
}
|
|
115
|
+
.flag_icon_off[data-checked=true][data-hover=true]{
|
|
116
|
+
color:var(--sys-primary-accent-hovered, #6851a6);
|
|
117
|
+
}
|
|
118
|
+
.flag_icon_off[data-disabled=true]{
|
|
119
|
+
color:var(--sys-neutral-decor-disabled, #e7e7e7);
|
|
120
|
+
}
|
|
121
|
+
.flag_icon_off[data-checked=true]{
|
|
122
|
+
opacity:0;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.flag_icon_on{
|
|
126
|
+
position:absolute;
|
|
127
|
+
top:50%;
|
|
128
|
+
left:50%;
|
|
129
|
+
transform:translate(-50%, -50%);
|
|
130
|
+
display:flex;
|
|
131
|
+
color:var(--sys-neutral-accent-default, #757575);
|
|
132
|
+
fill:transparent;
|
|
133
|
+
transition:opacity 0.1s linear;
|
|
134
|
+
opacity:0;
|
|
135
|
+
}
|
|
136
|
+
.flag_icon_on[data-hover=true]{
|
|
137
|
+
color:var(--sys-neutral-accent-hovered, #666666);
|
|
138
|
+
}
|
|
139
|
+
.flag_icon_on[data-checked=true]{
|
|
140
|
+
color:var(--sys-primary-accent-default, #794ed3);
|
|
141
|
+
}
|
|
142
|
+
.flag_icon_on[data-checked=true][data-hover=true]{
|
|
143
|
+
color:var(--sys-primary-accent-hovered, #6851a6);
|
|
144
|
+
}
|
|
145
|
+
.flag_icon_on[data-disabled=true]{
|
|
146
|
+
color:var(--sys-neutral-decor-disabled, #e7e7e7);
|
|
147
|
+
}
|
|
148
|
+
.flag_icon_on[data-checked=true]{
|
|
149
|
+
opacity:1;
|
|
150
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { SelectionMode } from '../../constants';
|
|
3
|
+
export type ToggleGroupProps = {
|
|
4
|
+
/** Вложенный контент */
|
|
5
|
+
children: ReactNode;
|
|
6
|
+
} & ({
|
|
7
|
+
/** Начальное состояние */
|
|
8
|
+
defaultValue?: string;
|
|
9
|
+
/** Controlled состояние */
|
|
10
|
+
value?: string;
|
|
11
|
+
/** Controlled обработчик измения состояния */
|
|
12
|
+
onChange?(value: (string | undefined) | string): void;
|
|
13
|
+
/** Режим выбора */
|
|
14
|
+
selectionMode?: SelectionMode.Single;
|
|
15
|
+
} | {
|
|
16
|
+
/** Начальное состояние */
|
|
17
|
+
defaultValue?: string[];
|
|
18
|
+
/** Controlled состояние */
|
|
19
|
+
value?: string[];
|
|
20
|
+
/** Controlled обработчик измения состояния */
|
|
21
|
+
onChange?(value: (string[] | undefined) | string[]): void;
|
|
22
|
+
/** Режим выбора */
|
|
23
|
+
selectionMode?: SelectionMode.Multiple;
|
|
24
|
+
});
|
|
25
|
+
export declare function ToggleGroup({ children, value: valueProp, onChange: onChangeProp, selectionMode, defaultValue, }: ToggleGroupProps): import("react/jsx-runtime").JSX.Element;
|
|
26
|
+
export declare namespace ToggleGroup {
|
|
27
|
+
var selectionModes: typeof SelectionMode;
|
|
28
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback } from 'react';
|
|
3
|
+
import { useUncontrolledProp } from 'uncontrollable';
|
|
4
|
+
import { SelectionMode } from '../../constants';
|
|
5
|
+
import { ToggleGroupContext } from '../../context';
|
|
6
|
+
export function ToggleGroup({ children, value: valueProp, onChange: onChangeProp, selectionMode = SelectionMode.Single, defaultValue, }) {
|
|
7
|
+
const [value, setValue] = useUncontrolledProp(valueProp, defaultValue, cb => {
|
|
8
|
+
onChangeProp === null || onChangeProp === void 0 ? void 0 : onChangeProp(cb(value));
|
|
9
|
+
});
|
|
10
|
+
const onChange = useCallback((newValue) => {
|
|
11
|
+
if (selectionMode === SelectionMode.Single) {
|
|
12
|
+
return setValue((oldValue) => {
|
|
13
|
+
if (newValue !== oldValue) {
|
|
14
|
+
return newValue;
|
|
15
|
+
}
|
|
16
|
+
return undefined;
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
return setValue((oldValues = []) => {
|
|
20
|
+
if (Array.isArray(oldValues)) {
|
|
21
|
+
if (oldValues.includes(newValue)) {
|
|
22
|
+
return oldValues.filter(oldValue => oldValue !== newValue);
|
|
23
|
+
}
|
|
24
|
+
return oldValues.concat(newValue);
|
|
25
|
+
}
|
|
26
|
+
return undefined;
|
|
27
|
+
});
|
|
28
|
+
}, [selectionMode, setValue]);
|
|
29
|
+
return (_jsx(ToggleGroupContext.Provider, Object.assign({ value: { value, onChange, selectionMode } }, { children: children })));
|
|
30
|
+
}
|
|
31
|
+
ToggleGroup.selectionModes = SelectionMode;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { useCallback, useMemo } from 'react';
|
|
2
|
+
import { SelectionMode } from '../../constants';
|
|
3
|
+
import { useToggleGroupContext } from '../../context';
|
|
4
|
+
export function useToggleGroup({ value: itemValue }) {
|
|
5
|
+
const { value, onChange, selectionMode } = useToggleGroupContext();
|
|
6
|
+
const isChecked = useMemo(() => {
|
|
7
|
+
if (typeof value === 'string') {
|
|
8
|
+
return value === itemValue;
|
|
9
|
+
}
|
|
10
|
+
if (Array.isArray(value)) {
|
|
11
|
+
return value.includes(itemValue);
|
|
12
|
+
}
|
|
13
|
+
return false;
|
|
14
|
+
}, [value, itemValue]);
|
|
15
|
+
const handleClick = useCallback(() => {
|
|
16
|
+
onChange === null || onChange === void 0 ? void 0 : onChange(itemValue);
|
|
17
|
+
}, [itemValue, onChange]);
|
|
18
|
+
return {
|
|
19
|
+
isChecked,
|
|
20
|
+
handleClick,
|
|
21
|
+
multipleSelection: selectionMode === SelectionMode.Multiple,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { Mode, Size } from '../../constants';
|
|
3
|
+
export declare const TogglePrivate: import("react").ForwardRefExoticComponent<{
|
|
4
|
+
'data-test-id'?: string | undefined;
|
|
5
|
+
} & import("react").AriaAttributes & {
|
|
6
|
+
className?: string | undefined;
|
|
7
|
+
size?: Size | undefined;
|
|
8
|
+
render: (visualState: import("../../types").InputVisualState) => import("react").ReactNode;
|
|
9
|
+
mode?: Mode | undefined;
|
|
10
|
+
id?: string | undefined;
|
|
11
|
+
value?: string | undefined;
|
|
12
|
+
name?: string | undefined;
|
|
13
|
+
tabIndex?: number | undefined;
|
|
14
|
+
autofocus?: boolean | undefined;
|
|
15
|
+
checked?: boolean | undefined;
|
|
16
|
+
defaultChecked?: boolean | undefined;
|
|
17
|
+
disabled?: boolean | undefined;
|
|
18
|
+
onChange?: ((checked: boolean) => void) | undefined;
|
|
19
|
+
onClick?: import("react").MouseEventHandler<HTMLInputElement> | undefined;
|
|
20
|
+
onBlur?: import("react").FocusEventHandler<HTMLInputElement> | undefined;
|
|
21
|
+
onFocus?: import("react").FocusEventHandler<HTMLInputElement> | undefined;
|
|
22
|
+
} & import("react").RefAttributes<HTMLInputElement>>;
|
|
@@ -0,0 +1,38 @@
|
|
|
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 { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
13
|
+
import cn from 'classnames';
|
|
14
|
+
import { forwardRef, useState } from 'react';
|
|
15
|
+
import { useUncontrolledProp } from 'uncontrollable';
|
|
16
|
+
import { Mode, Size } from '../../constants';
|
|
17
|
+
import { getVisualStateAttributes } from '../../utils';
|
|
18
|
+
import styles from './styles.module.css';
|
|
19
|
+
export const TogglePrivate = forwardRef(function TogglePrivate(_a, ref) {
|
|
20
|
+
var { render, checked: checkedProp, defaultChecked, onChange, onBlur, onFocus, disabled, className, size = Size.M, mode = Mode.Checkbox, 'data-test-id': testId } = _a, otherProps = __rest(_a, ["render", "checked", "defaultChecked", "onChange", "onBlur", "onFocus", "disabled", "className", "size", "mode", 'data-test-id']);
|
|
21
|
+
const [checked, setChecked] = useUncontrolledProp(checkedProp, Boolean(defaultChecked), onChange);
|
|
22
|
+
const [focusVisible, setFocusVisible] = useState(false);
|
|
23
|
+
const [hover, setHover] = useState(false);
|
|
24
|
+
const visualState = {
|
|
25
|
+
disabled: Boolean(disabled),
|
|
26
|
+
focusVisible,
|
|
27
|
+
checked,
|
|
28
|
+
hover,
|
|
29
|
+
size,
|
|
30
|
+
};
|
|
31
|
+
return (_jsxs("span", Object.assign({ className: cn(className, styles.toggleLayout), "data-size": size, "data-test-id": testId, onMouseEnter: () => setHover(true), onMouseLeave: () => setHover(false) }, getVisualStateAttributes(visualState), { children: [render(visualState), _jsx("input", Object.assign({}, otherProps, { "data-test-id": `${testId}-native-input`, ref: ref, type: mode, className: styles.togglePrivate, checked: checked, disabled: disabled, onChange: e => setChecked(e.target.checked), onFocus: event => {
|
|
32
|
+
setFocusVisible(event.target.matches(':focus-visible'));
|
|
33
|
+
onFocus === null || onFocus === void 0 ? void 0 : onFocus(event);
|
|
34
|
+
}, onBlur: event => {
|
|
35
|
+
setFocusVisible(false);
|
|
36
|
+
onBlur === null || onBlur === void 0 ? void 0 : onBlur(event);
|
|
37
|
+
} }))] })));
|
|
38
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './TogglePrivate';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './TogglePrivate';
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
.toggleLayout{
|
|
2
|
+
cursor:pointer;
|
|
3
|
+
position:relative;
|
|
4
|
+
display:inline-flex;
|
|
5
|
+
flex-direction:row;
|
|
6
|
+
flex-grow:0;
|
|
7
|
+
flex-shrink:0;
|
|
8
|
+
align-items:center;
|
|
9
|
+
}
|
|
10
|
+
.toggleLayout[data-size=s] svg{
|
|
11
|
+
width:var(--dimension-2m, 16px) !important;
|
|
12
|
+
height:var(--dimension-2m, 16px) !important;
|
|
13
|
+
}
|
|
14
|
+
.toggleLayout[data-size=m] svg{
|
|
15
|
+
width:var(--dimension-3m, 24px) !important;
|
|
16
|
+
height:var(--dimension-3m, 24px) !important;
|
|
17
|
+
}
|
|
18
|
+
.toggleLayout[data-disabled=true]{
|
|
19
|
+
cursor:not-allowed;
|
|
20
|
+
color:var(--sys-neutral-text-disabled, #9e9e9e);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.togglePrivate{
|
|
24
|
+
cursor:pointer;
|
|
25
|
+
position:absolute;
|
|
26
|
+
top:0;
|
|
27
|
+
right:0;
|
|
28
|
+
bottom:0;
|
|
29
|
+
left:0;
|
|
30
|
+
width:100%;
|
|
31
|
+
height:100%;
|
|
32
|
+
margin:0;
|
|
33
|
+
padding:0;
|
|
34
|
+
opacity:0;
|
|
35
|
+
}
|
|
36
|
+
.togglePrivate:disabled{
|
|
37
|
+
cursor:not-allowed;
|
|
38
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare enum Mode {
|
|
2
|
+
Checkbox = "checkbox",
|
|
3
|
+
Radio = "radio"
|
|
4
|
+
}
|
|
5
|
+
export declare enum Size {
|
|
6
|
+
S = "s",
|
|
7
|
+
M = "m"
|
|
8
|
+
}
|
|
9
|
+
export declare enum FavoriteIcon {
|
|
10
|
+
Star = "star",
|
|
11
|
+
Heart = "heart"
|
|
12
|
+
}
|
|
13
|
+
export declare enum SelectionMode {
|
|
14
|
+
Single = "single",
|
|
15
|
+
Multiple = "multiple"
|
|
16
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export var Mode;
|
|
2
|
+
(function (Mode) {
|
|
3
|
+
Mode["Checkbox"] = "checkbox";
|
|
4
|
+
Mode["Radio"] = "radio";
|
|
5
|
+
})(Mode || (Mode = {}));
|
|
6
|
+
export var Size;
|
|
7
|
+
(function (Size) {
|
|
8
|
+
Size["S"] = "s";
|
|
9
|
+
Size["M"] = "m";
|
|
10
|
+
})(Size || (Size = {}));
|
|
11
|
+
export var FavoriteIcon;
|
|
12
|
+
(function (FavoriteIcon) {
|
|
13
|
+
FavoriteIcon["Star"] = "star";
|
|
14
|
+
FavoriteIcon["Heart"] = "heart";
|
|
15
|
+
})(FavoriteIcon || (FavoriteIcon = {}));
|
|
16
|
+
export var SelectionMode;
|
|
17
|
+
(function (SelectionMode) {
|
|
18
|
+
SelectionMode["Single"] = "single";
|
|
19
|
+
SelectionMode["Multiple"] = "multiple";
|
|
20
|
+
})(SelectionMode || (SelectionMode = {}));
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { SelectionMode } from './constants';
|
|
3
|
+
type ToggleGroupContextType = {
|
|
4
|
+
value: string | undefined | string[];
|
|
5
|
+
onChange: ((id: string) => void) | undefined;
|
|
6
|
+
selectionMode: SelectionMode;
|
|
7
|
+
};
|
|
8
|
+
export declare const ToggleGroupContext: import("react").Context<ToggleGroupContextType>;
|
|
9
|
+
export declare const useToggleGroupContext: () => ToggleGroupContextType;
|
|
10
|
+
export {};
|
package/dist/context.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { createContext, useContext } from 'react';
|
|
2
|
+
import { SelectionMode } from './constants';
|
|
3
|
+
export const ToggleGroupContext = createContext({
|
|
4
|
+
value: undefined,
|
|
5
|
+
onChange: undefined,
|
|
6
|
+
selectionMode: SelectionMode.Single,
|
|
7
|
+
});
|
|
8
|
+
export const useToggleGroupContext = () => useContext(ToggleGroupContext);
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './components';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './components';
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { FocusEventHandler, MouseEventHandler, ReactNode, RefObject } from 'react';
|
|
2
|
+
import { WithSupportProps } from '@snack-uikit/utils';
|
|
3
|
+
import { Mode, Size } from './constants';
|
|
4
|
+
export type InputVisualState = {
|
|
5
|
+
focusVisible: boolean;
|
|
6
|
+
disabled: boolean;
|
|
7
|
+
checked: boolean;
|
|
8
|
+
hover: boolean;
|
|
9
|
+
size: Size;
|
|
10
|
+
};
|
|
11
|
+
export type DataAttributes = Record<`data-${string}`, string | boolean>;
|
|
12
|
+
export type TogglePrivateProps = WithSupportProps<{
|
|
13
|
+
className?: string;
|
|
14
|
+
/** Размер */
|
|
15
|
+
size?: Size;
|
|
16
|
+
/** Колбек рендера компонента */
|
|
17
|
+
render: (visualState: InputVisualState) => ReactNode;
|
|
18
|
+
/** Режим работы */
|
|
19
|
+
mode?: Mode;
|
|
20
|
+
/** HTML-аттрибут id */
|
|
21
|
+
id?: string;
|
|
22
|
+
/** HTML-аттрибут value */
|
|
23
|
+
value?: string;
|
|
24
|
+
/** HTML-аттрибут name */
|
|
25
|
+
name?: string;
|
|
26
|
+
/** HTML-аттрибут tab-index */
|
|
27
|
+
tabIndex?: number;
|
|
28
|
+
/** HTML-аттрибут autofocus */
|
|
29
|
+
autofocus?: boolean;
|
|
30
|
+
/** HTML-аттрибут checked */
|
|
31
|
+
checked?: boolean;
|
|
32
|
+
/** HTML-аттрибут checked по-умолчанию */
|
|
33
|
+
defaultChecked?: boolean;
|
|
34
|
+
/** HTML-аттрибут disabled */
|
|
35
|
+
disabled?: boolean;
|
|
36
|
+
/** Колбек смены значения */
|
|
37
|
+
onChange?: (checked: boolean) => void;
|
|
38
|
+
/** Колбек клика */
|
|
39
|
+
onClick?: MouseEventHandler<HTMLInputElement>;
|
|
40
|
+
/** Колбек потери фокуса */
|
|
41
|
+
onBlur?: FocusEventHandler<HTMLInputElement>;
|
|
42
|
+
/** Колбек приобретения фокуса */
|
|
43
|
+
onFocus?: FocusEventHandler<HTMLInputElement>;
|
|
44
|
+
}>;
|
|
45
|
+
export type ToggleProps = WithSupportProps<Pick<TogglePrivateProps, 'id' | 'name' | 'value' | 'tabIndex' | 'autofocus' | 'checked' | 'defaultChecked' | 'disabled' | 'onChange' | 'onClick' | 'onBlur' | 'onFocus' | 'className' | 'size'> & {
|
|
46
|
+
inputRef?: RefObject<HTMLInputElement>;
|
|
47
|
+
}>;
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/utils.d.ts
ADDED
package/dist/utils.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Size } from './constants';
|
|
2
|
+
export function getVisualStateAttributes(state) {
|
|
3
|
+
return Object.entries(state).reduce(function (result, [name, value]) {
|
|
4
|
+
result[`data-${name.toLowerCase()}`] = value;
|
|
5
|
+
return result;
|
|
6
|
+
}, {});
|
|
7
|
+
}
|
|
8
|
+
export function getIconSize(size) {
|
|
9
|
+
switch (size) {
|
|
10
|
+
case Size.S: {
|
|
11
|
+
return 16;
|
|
12
|
+
}
|
|
13
|
+
case Size.M:
|
|
14
|
+
default: {
|
|
15
|
+
return 24;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@snack-uikit/toggles",
|
|
3
|
+
"publishConfig": {
|
|
4
|
+
"access": "public"
|
|
5
|
+
},
|
|
6
|
+
"title": "Toggles",
|
|
7
|
+
"version": "0.7.1-preview-104ad22c.0",
|
|
8
|
+
"sideEffects": [
|
|
9
|
+
"*.css",
|
|
10
|
+
"*.woff",
|
|
11
|
+
"*.woff2"
|
|
12
|
+
],
|
|
13
|
+
"description": "",
|
|
14
|
+
"main": "./dist/index.js",
|
|
15
|
+
"module": "./dist/index.js",
|
|
16
|
+
"homepage": "https://git.sbercloud.tech/sbercloud-ui/tokens-design-system/snack-uikit/-/tree/master/packages/toggles",
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "https://git.sbercloud.tech/sbercloud-ui/tokens-design-system/snack-uikit.git",
|
|
20
|
+
"directory": "packages/toggles"
|
|
21
|
+
},
|
|
22
|
+
"author": "Сергей Хлупин <svhlupin@cloud.ru>",
|
|
23
|
+
"contributors": [
|
|
24
|
+
"Сергей Хлупин <svhlupin@cloud.ru>"
|
|
25
|
+
],
|
|
26
|
+
"files": [
|
|
27
|
+
"dist",
|
|
28
|
+
"src",
|
|
29
|
+
"./CHANGELOG.md",
|
|
30
|
+
"./LICENSE"
|
|
31
|
+
],
|
|
32
|
+
"license": "Apache-2.0",
|
|
33
|
+
"scripts": {},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"@snack-uikit/icons": "0.18.2-preview-104ad22c.0",
|
|
36
|
+
"@snack-uikit/utils": "2.0.2-preview-104ad22c.0",
|
|
37
|
+
"classnames": "2.3.2",
|
|
38
|
+
"merge-refs": "1.2.1",
|
|
39
|
+
"uncontrollable": "8.0.0"
|
|
40
|
+
},
|
|
41
|
+
"gitHead": "580e0d5c22d04d609bcdf7cb0873114f9fce5f66"
|
|
42
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import mergeRefs from 'merge-refs';
|
|
2
|
+
import { useCallback, useEffect, useMemo, useRef } from 'react';
|
|
3
|
+
import { useUncontrolledProp } from 'uncontrollable';
|
|
4
|
+
|
|
5
|
+
import { CheckSVG, MinusSVG } from '@snack-uikit/icons';
|
|
6
|
+
|
|
7
|
+
import { Size } from '../../constants';
|
|
8
|
+
import { ToggleProps } from '../../types';
|
|
9
|
+
import { getIconSize, getVisualStateAttributes } from '../../utils';
|
|
10
|
+
import { TogglePrivate } from '../TogglePrivate';
|
|
11
|
+
import styles from './styles.module.scss';
|
|
12
|
+
|
|
13
|
+
export type CheckboxProps = ToggleProps & {
|
|
14
|
+
/** Состояние частичного выбора */
|
|
15
|
+
indeterminate?: boolean;
|
|
16
|
+
/** Состояние частичного выбора по-умолчанию */
|
|
17
|
+
indeterminateDefault?: boolean;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export function Checkbox({
|
|
21
|
+
inputRef,
|
|
22
|
+
indeterminate: indeterminateProp,
|
|
23
|
+
indeterminateDefault,
|
|
24
|
+
onChange: onChangeProp,
|
|
25
|
+
'data-test-id': dataTestId,
|
|
26
|
+
size = Size.M,
|
|
27
|
+
...restProps
|
|
28
|
+
}: CheckboxProps) {
|
|
29
|
+
const localRef = useRef<HTMLInputElement>(null);
|
|
30
|
+
const ref = mergeRefs<HTMLInputElement>(localRef, inputRef);
|
|
31
|
+
|
|
32
|
+
const [indeterminate, setIndeterminate] = useUncontrolledProp(indeterminateProp, indeterminateDefault);
|
|
33
|
+
|
|
34
|
+
const onChange = useCallback(
|
|
35
|
+
(checked: boolean) => {
|
|
36
|
+
onChangeProp?.(checked);
|
|
37
|
+
setIndeterminate(false);
|
|
38
|
+
},
|
|
39
|
+
[onChangeProp, setIndeterminate],
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
if (localRef.current) {
|
|
44
|
+
localRef.current.indeterminate = Boolean(indeterminate);
|
|
45
|
+
}
|
|
46
|
+
}, [localRef, indeterminate]);
|
|
47
|
+
|
|
48
|
+
const iconSize = useMemo(() => getIconSize(size), [size]);
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<TogglePrivate
|
|
52
|
+
{...restProps}
|
|
53
|
+
size={size}
|
|
54
|
+
onChange={onChange}
|
|
55
|
+
data-test-id={dataTestId}
|
|
56
|
+
ref={ref}
|
|
57
|
+
render={function Checkbox(visualState) {
|
|
58
|
+
const data = getVisualStateAttributes({ ...visualState, indeterminate: Boolean(indeterminate) });
|
|
59
|
+
return (
|
|
60
|
+
<div className={styles.container} {...data}>
|
|
61
|
+
<div className={styles.box} {...data} />
|
|
62
|
+
<div className={styles.icon} {...data}>
|
|
63
|
+
{indeterminate ? <MinusSVG size={iconSize} /> : <CheckSVG size={iconSize} />}
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
);
|
|
67
|
+
}}
|
|
68
|
+
/>
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
Checkbox.sizes = Size;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './Checkbox';
|