@purpurds/toggle 7.6.1 → 7.8.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/dist/LICENSE.txt +3 -3
- package/dist/toggle.cjs.js +5 -5
- package/dist/toggle.cjs.js.map +1 -1
- package/dist/toggle.d.ts +3 -57
- package/dist/toggle.d.ts.map +1 -1
- package/dist/toggle.es.js +340 -376
- package/dist/toggle.es.js.map +1 -1
- package/package.json +8 -8
- package/src/toggle.stories.tsx +2 -2
- package/src/toggle.tsx +73 -81
package/src/toggle.tsx
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { forwardRef, useState } from "react";
|
|
2
|
+
import type { BaseProps } from "@purpurds/common-types";
|
|
2
3
|
import { Icon } from "@purpurds/icon";
|
|
3
4
|
import { checkmarkBold } from "@purpurds/icon/assets/checkmark-bold";
|
|
4
5
|
import { Label } from "@purpurds/label";
|
|
5
6
|
import { Paragraph } from "@purpurds/paragraph";
|
|
6
7
|
import * as Switch from "@radix-ui/react-switch";
|
|
7
|
-
import c from "classnames";
|
|
8
|
+
import c from "classnames/bind";
|
|
8
9
|
|
|
9
10
|
import { DraggableX } from "./DraggableX";
|
|
10
11
|
import { useToggleDrag } from "./hooks/useToggleDrag";
|
|
11
12
|
import styles from "./toggle.module.scss";
|
|
12
13
|
|
|
13
|
-
export type ToggleProps = Omit<
|
|
14
|
+
export type ToggleProps = Omit<BaseProps<"button">, "onChange" | "children" | "id"> & {
|
|
14
15
|
/**
|
|
15
16
|
* To use when no label is given.
|
|
16
17
|
* */
|
|
@@ -19,7 +20,6 @@ export type ToggleProps = Omit<React.HTMLAttributes<HTMLElement>, "onChange"> &
|
|
|
19
20
|
* To use with custom label (not recommended).
|
|
20
21
|
* */
|
|
21
22
|
["aria-labelledby"]?: string;
|
|
22
|
-
["data-testid"]?: string;
|
|
23
23
|
/**
|
|
24
24
|
* The controlled state of the toggle. Must be used in conjunction with `onChange`.
|
|
25
25
|
* */
|
|
@@ -66,88 +66,80 @@ export type ToggleProps = Omit<React.HTMLAttributes<HTMLElement>, "onChange"> &
|
|
|
66
66
|
value?: string;
|
|
67
67
|
};
|
|
68
68
|
|
|
69
|
+
const cx = c.bind(styles);
|
|
69
70
|
const rootClassName = "purpur-toggle";
|
|
70
71
|
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
ref: ForwardedRef<HTMLButtonElement>
|
|
84
|
-
) => {
|
|
85
|
-
const [internalChecked, setInternalChecked] = useState(
|
|
86
|
-
typeof checked === "boolean" ? checked : !!defaultChecked
|
|
87
|
-
);
|
|
88
|
-
const isChecked = Boolean(typeof checked === "boolean" ? checked : internalChecked);
|
|
89
|
-
const { thumbRef, trackRef, isDragging, onChangeWithDrag, ...draggableXProps } = useToggleDrag({
|
|
90
|
-
checked: isChecked,
|
|
91
|
-
onChange: (value) => {
|
|
92
|
-
if (!props.disabled) {
|
|
93
|
-
onChange?.(value);
|
|
94
|
-
setInternalChecked(value);
|
|
95
|
-
}
|
|
72
|
+
export const Toggle = forwardRef<HTMLButtonElement, ToggleProps>(
|
|
73
|
+
(
|
|
74
|
+
{
|
|
75
|
+
["data-testid"]: dataTestId,
|
|
76
|
+
className,
|
|
77
|
+
label,
|
|
78
|
+
onChange,
|
|
79
|
+
labelPosition = "right",
|
|
80
|
+
checked,
|
|
81
|
+
disableDrag,
|
|
82
|
+
defaultChecked,
|
|
83
|
+
...props
|
|
96
84
|
},
|
|
97
|
-
|
|
85
|
+
ref
|
|
86
|
+
) => {
|
|
87
|
+
const [internalChecked, setInternalChecked] = useState(
|
|
88
|
+
typeof checked === "boolean" ? checked : !!defaultChecked
|
|
89
|
+
);
|
|
90
|
+
const isChecked = Boolean(typeof checked === "boolean" ? checked : internalChecked);
|
|
91
|
+
const { thumbRef, trackRef, isDragging, onChangeWithDrag, ...draggableXProps } = useToggleDrag({
|
|
92
|
+
checked: isChecked,
|
|
93
|
+
onChange: (value) => {
|
|
94
|
+
if (!props.disabled) {
|
|
95
|
+
onChange?.(value);
|
|
96
|
+
setInternalChecked(value);
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
});
|
|
98
100
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
styles[`${rootClassName}__label`],
|
|
106
|
-
styles[`${rootClassName}__label--${labelPosition}`]
|
|
107
|
-
)}
|
|
108
|
-
>
|
|
109
|
-
<Paragraph disabled={props.disabled}>{label}</Paragraph>
|
|
110
|
-
</Label>
|
|
111
|
-
);
|
|
112
|
-
|
|
113
|
-
return (
|
|
114
|
-
<div className={c([className, styles[`${rootClassName}__container`]])}>
|
|
115
|
-
{label && labelPosition === "left" && renderLabel()}
|
|
116
|
-
<Switch.Root
|
|
117
|
-
{...props}
|
|
118
|
-
ref={ref}
|
|
119
|
-
id={props.id}
|
|
120
|
-
data-testid={dataTestId}
|
|
121
|
-
className={styles[rootClassName]}
|
|
122
|
-
onCheckedChange={onChangeWithDrag}
|
|
123
|
-
checked={isChecked}
|
|
101
|
+
const renderLabel = () => (
|
|
102
|
+
<Label
|
|
103
|
+
htmlFor={props.id}
|
|
104
|
+
data-testid={dataTestId && `${dataTestId}-label`}
|
|
105
|
+
disabled={props.disabled}
|
|
106
|
+
className={cx(`${rootClassName}__label`, `${rootClassName}__label--${labelPosition}`)}
|
|
124
107
|
>
|
|
125
|
-
<
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
108
|
+
<Paragraph disabled={props.disabled}>{label}</Paragraph>
|
|
109
|
+
</Label>
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
return (
|
|
113
|
+
<div className={cx(className, `${rootClassName}__container`)}>
|
|
114
|
+
{label && labelPosition === "left" && renderLabel()}
|
|
115
|
+
<Switch.Root
|
|
116
|
+
{...props}
|
|
117
|
+
ref={ref}
|
|
118
|
+
id={props.id}
|
|
119
|
+
data-testid={dataTestId}
|
|
120
|
+
className={cx(rootClassName)}
|
|
121
|
+
onCheckedChange={onChangeWithDrag}
|
|
122
|
+
checked={isChecked}
|
|
123
|
+
>
|
|
124
|
+
<span ref={trackRef} className={cx(`${rootClassName}__track`)}>
|
|
125
|
+
<span className={cx(`${rootClassName}__checkmark-container`)}>
|
|
126
|
+
<Icon className={cx(`${rootClassName}__checkmark`)} svg={checkmarkBold} size="xxs" />
|
|
127
|
+
</span>
|
|
128
|
+
<DraggableX disabled={disableDrag} {...draggableXProps}>
|
|
129
|
+
<Switch.Thumb
|
|
130
|
+
ref={thumbRef}
|
|
131
|
+
data-testid={dataTestId && `${dataTestId}-thumb`}
|
|
132
|
+
className={cx(`${rootClassName}__thumb`, {
|
|
133
|
+
[`${rootClassName}__thumb--dragging`]: isDragging,
|
|
134
|
+
})}
|
|
135
|
+
/>
|
|
136
|
+
</DraggableX>
|
|
132
137
|
</span>
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
{
|
|
140
|
-
[styles[`${rootClassName}__thumb--dragging`]]: isDragging,
|
|
141
|
-
},
|
|
142
|
-
])}
|
|
143
|
-
/>
|
|
144
|
-
</DraggableX>
|
|
145
|
-
</span>
|
|
146
|
-
</Switch.Root>
|
|
147
|
-
{label && labelPosition === "right" && renderLabel()}
|
|
148
|
-
</div>
|
|
149
|
-
);
|
|
150
|
-
};
|
|
138
|
+
</Switch.Root>
|
|
139
|
+
{label && labelPosition === "right" && renderLabel()}
|
|
140
|
+
</div>
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
);
|
|
151
144
|
|
|
152
|
-
export const Toggle = forwardRef(ToggleComponent);
|
|
153
145
|
Toggle.displayName = "Toggle";
|