Skip to content

Commit 08ce352

Browse files
committed
feat(Switch): Add labelPosition for Switch.
Switch has a prop `label` to set its label. And its position is defaultly at the end. To put the label at the start of `Switch` is hard. So I add `labelPosition`, using `gap: 2` instead of the `mr: 2` to make sure that those children's space is right. By the way, I move those inner components outside, to make those code more clear than before. I hope that works.
1 parent 3003ff4 commit 08ce352

File tree

3 files changed

+39
-5
lines changed

3 files changed

+39
-5
lines changed

packages/components/index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,4 +398,5 @@ export const Switch: ForwardRef<HTMLInputElement, SwitchProps>
398398
export interface SwitchProps
399399
extends Assign<React.ComponentProps<'input'>, BoxOwnProps> {
400400
label?: string
401+
labelPosition?: 'start' | 'end'
401402
}

packages/components/src/Switch.js

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@ const GUTTER = 2
66
const SIZE = 18
77

88
export const Switch = React.forwardRef(function Switch(
9-
{ className, label, sx, variant = 'switch', ...props },
9+
{ className, label, labelPosition = 'end', sx, variant = 'switch', ...props },
1010
ref
1111
) {
12-
return (
13-
<Label sx={{ cursor: 'pointer' }}>
12+
// Inner really checkbox (but hidden).
13+
const ReallyHiddenCheckbox = ({ ref, label, ...props }) => {
14+
return (
1415
<Box
1516
ref={ref}
1617
as="input"
@@ -27,6 +28,12 @@ export const Switch = React.forwardRef(function Switch(
2728
overflow: 'hidden',
2829
}}
2930
/>
31+
);
32+
};
33+
34+
// Switch just for show
35+
const SwitchForShow = ({ variant, className, sx }) => {
36+
return (
3037
<Box
3138
css={{
3239
padding: GUTTER,
@@ -42,7 +49,6 @@ export const Switch = React.forwardRef(function Switch(
4249
borderRadius: SIZE,
4350
height: SIZE + GUTTER * 2,
4451
width: SIZE * 2 + GUTTER * 2,
45-
mr: 2,
4652
'input:disabled ~ &': {
4753
opacity: 0.5,
4854
cursor: 'not-allowed',
@@ -69,7 +75,15 @@ export const Switch = React.forwardRef(function Switch(
6975
>
7076
<Box />
7177
</Box>
72-
<span>{label}</span>
78+
)
79+
};
80+
81+
return (
82+
<Label sx={{ cursor: 'pointer', gap: 2 }}>
83+
{ labelPosition === 'start' && label ? <span>{label}</span> : null }
84+
<ReallyHiddenCheckbox ref={ref} label={label} {...props} />
85+
<SwitchForShow variant={variant} className={className} sx={sx} />
86+
{ labelPosition === 'end' && label ? <span>{label}</span> : null }
7387
</Label>
7488
)
7589
})

packages/docs/src/pages/components/switch.mdx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
title: Switch
33
---
44

5+
import Note from '../../components/note.js';
6+
57
# Switch
68

79
Form switch input component
@@ -42,8 +44,25 @@ To show different style based on the input state, you can use
4244
/>
4345
```
4446

47+
## `labelPosition`
48+
49+
May you want to change the label's position, so there are props
50+
`labelPosition`. Its value can be `'start'`, `'end'`(default).
51+
52+
```jsx live=true
53+
<Switch label="Click Me!" labelPosition='start' />
54+
```
55+
56+
```jsx live=true
57+
<Switch label="Do Not Click Me!" labelPosition='end' />
58+
```
59+
4560
## External label
4661

62+
<Note>
63+
Try to use `labelPosition` prop rather than another Label layer!
64+
</Note>
65+
4766
Even though the Switch component already renders a label, but you can also
4867
opt-in for an external label instead.
4968

0 commit comments

Comments
 (0)