@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.
Files changed (73) hide show
  1. package/CHANGELOG.md +357 -0
  2. package/LICENSE +201 -0
  3. package/README.md +169 -0
  4. package/dist/components/Checkbox/Checkbox.d.ts +12 -0
  5. package/dist/components/Checkbox/Checkbox.js +41 -0
  6. package/dist/components/Checkbox/index.d.ts +1 -0
  7. package/dist/components/Checkbox/index.js +1 -0
  8. package/dist/components/Checkbox/styles.module.css +86 -0
  9. package/dist/components/Favorite/Favorite.d.ts +10 -0
  10. package/dist/components/Favorite/Favorite.js +36 -0
  11. package/dist/components/Favorite/index.d.ts +1 -0
  12. package/dist/components/Favorite/index.js +1 -0
  13. package/dist/components/Favorite/styles.module.css +47 -0
  14. package/dist/components/Radio/Radio.d.ts +7 -0
  15. package/dist/components/Radio/Radio.js +24 -0
  16. package/dist/components/Radio/index.d.ts +1 -0
  17. package/dist/components/Radio/index.js +1 -0
  18. package/dist/components/Radio/styles.module.css +90 -0
  19. package/dist/components/Switch/Switch.d.ts +10 -0
  20. package/dist/components/Switch/Switch.js +27 -0
  21. package/dist/components/Switch/index.d.ts +1 -0
  22. package/dist/components/Switch/index.js +1 -0
  23. package/dist/components/Switch/styles.module.css +150 -0
  24. package/dist/components/ToggleGroup/ToggleGroup.d.ts +28 -0
  25. package/dist/components/ToggleGroup/ToggleGroup.js +31 -0
  26. package/dist/components/ToggleGroup/hooks.d.ts +9 -0
  27. package/dist/components/ToggleGroup/hooks.js +23 -0
  28. package/dist/components/ToggleGroup/index.d.ts +2 -0
  29. package/dist/components/ToggleGroup/index.js +2 -0
  30. package/dist/components/TogglePrivate/TogglePrivate.d.ts +22 -0
  31. package/dist/components/TogglePrivate/TogglePrivate.js +38 -0
  32. package/dist/components/TogglePrivate/index.d.ts +1 -0
  33. package/dist/components/TogglePrivate/index.js +1 -0
  34. package/dist/components/TogglePrivate/styles.module.css +38 -0
  35. package/dist/components/index.d.ts +5 -0
  36. package/dist/components/index.js +5 -0
  37. package/dist/components/styles.module.css +0 -0
  38. package/dist/constants.d.ts +16 -0
  39. package/dist/constants.js +20 -0
  40. package/dist/context.d.ts +10 -0
  41. package/dist/context.js +8 -0
  42. package/dist/index.d.ts +1 -0
  43. package/dist/index.js +1 -0
  44. package/dist/types.d.ts +47 -0
  45. package/dist/types.js +1 -0
  46. package/dist/utils.d.ts +4 -0
  47. package/dist/utils.js +18 -0
  48. package/package.json +42 -0
  49. package/src/components/Checkbox/Checkbox.tsx +72 -0
  50. package/src/components/Checkbox/index.ts +1 -0
  51. package/src/components/Checkbox/styles.module.scss +77 -0
  52. package/src/components/Favorite/Favorite.tsx +54 -0
  53. package/src/components/Favorite/index.ts +1 -0
  54. package/src/components/Favorite/styles.module.scss +36 -0
  55. package/src/components/Radio/Radio.tsx +30 -0
  56. package/src/components/Radio/index.ts +1 -0
  57. package/src/components/Radio/styles.module.scss +74 -0
  58. package/src/components/Switch/Switch.tsx +50 -0
  59. package/src/components/Switch/index.ts +1 -0
  60. package/src/components/Switch/styles.module.scss +124 -0
  61. package/src/components/ToggleGroup/ToggleGroup.tsx +76 -0
  62. package/src/components/ToggleGroup/hooks.ts +34 -0
  63. package/src/components/ToggleGroup/index.ts +2 -0
  64. package/src/components/TogglePrivate/TogglePrivate.tsx +69 -0
  65. package/src/components/TogglePrivate/index.ts +1 -0
  66. package/src/components/TogglePrivate/styles.module.scss +56 -0
  67. package/src/components/index.ts +5 -0
  68. package/src/components/styles.module.scss +24 -0
  69. package/src/constants.ts +19 -0
  70. package/src/context.ts +17 -0
  71. package/src/index.ts +1 -0
  72. package/src/types.ts +71 -0
  73. 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,9 @@
1
+ type UseToggleGroupProps = {
2
+ value: string;
3
+ };
4
+ export declare function useToggleGroup({ value: itemValue }: UseToggleGroupProps): {
5
+ isChecked: boolean;
6
+ handleClick: () => void;
7
+ multipleSelection: boolean;
8
+ };
9
+ export {};
@@ -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,2 @@
1
+ export * from './ToggleGroup';
2
+ export * from './hooks';
@@ -0,0 +1,2 @@
1
+ export * from './ToggleGroup';
2
+ export * from './hooks';
@@ -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
+ }
@@ -0,0 +1,5 @@
1
+ export * from './Checkbox';
2
+ export * from './Switch';
3
+ export * from './Radio';
4
+ export * from './Favorite';
5
+ export * from './ToggleGroup';
@@ -0,0 +1,5 @@
1
+ export * from './Checkbox';
2
+ export * from './Switch';
3
+ export * from './Radio';
4
+ export * from './Favorite';
5
+ export * from './ToggleGroup';
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 {};
@@ -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);
@@ -0,0 +1 @@
1
+ export * from './components';
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ export * from './components';
@@ -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 {};
@@ -0,0 +1,4 @@
1
+ import { Size } from './constants';
2
+ import { DataAttributes } from './types';
3
+ export declare function getVisualStateAttributes(state: Record<string, string | boolean>): DataAttributes;
4
+ export declare function getIconSize(size?: Size): 16 | 24;
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';