mirror of
https://ghproxy.net/https://github.com/abhijitb/helix.git
synced 2025-08-28 06:26:00 +08:00
fixed toggle input
This commit is contained in:
parent
6235dc79c4
commit
c29c823d56
4 changed files with 122 additions and 57 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -2,7 +2,7 @@ import React from 'react';
|
||||||
import FormField from './FormField';
|
import FormField from './FormField';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggle/Checkbox input component
|
* Toggle switch component with proper accessibility
|
||||||
* @param root0
|
* @param root0
|
||||||
* @param root0.label
|
* @param root0.label
|
||||||
* @param root0.description
|
* @param root0.description
|
||||||
|
@ -12,6 +12,7 @@ import FormField from './FormField';
|
||||||
* @param root0.disabled
|
* @param root0.disabled
|
||||||
* @param root0.error
|
* @param root0.error
|
||||||
* @param root0.className
|
* @param root0.className
|
||||||
|
* @param root0.id
|
||||||
*/
|
*/
|
||||||
const ToggleInput = ( {
|
const ToggleInput = ( {
|
||||||
label,
|
label,
|
||||||
|
@ -22,10 +23,14 @@ const ToggleInput = ( {
|
||||||
disabled = false,
|
disabled = false,
|
||||||
error = null,
|
error = null,
|
||||||
className = '',
|
className = '',
|
||||||
|
id = `toggle-${ Math.random().toString( 36 ).substr( 2, 9 ) }`,
|
||||||
...props
|
...props
|
||||||
} ) => {
|
} ) => {
|
||||||
const handleChange = ( event ) => {
|
const handleToggle = () => {
|
||||||
onChange( event.target.checked );
|
if ( disabled ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
onChange( ! value );
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -35,19 +40,41 @@ const ToggleInput = ( {
|
||||||
required={ required }
|
required={ required }
|
||||||
className={ `helix-toggle-field ${ className }` }
|
className={ `helix-toggle-field ${ className }` }
|
||||||
>
|
>
|
||||||
<label className="helix-toggle-wrapper">
|
<div className="helix-toggle-wrapper">
|
||||||
<input
|
{ label && (
|
||||||
type="checkbox"
|
<label
|
||||||
checked={ !! value }
|
htmlFor={ id }
|
||||||
onChange={ handleChange }
|
className={ `helix-toggle-label ${
|
||||||
required={ required }
|
disabled ? 'helix-toggle-label-disabled' : ''
|
||||||
disabled={ disabled }
|
}` }
|
||||||
className="helix-toggle-input"
|
>
|
||||||
{ ...props }
|
{ label }
|
||||||
/>
|
|
||||||
<span className="helix-toggle-slider"></span>
|
|
||||||
<span className="helix-toggle-label">{ label }</span>
|
|
||||||
</label>
|
</label>
|
||||||
|
) }
|
||||||
|
|
||||||
|
<button
|
||||||
|
id={ id }
|
||||||
|
type="button"
|
||||||
|
role="switch"
|
||||||
|
aria-checked={ !! value }
|
||||||
|
onClick={ handleToggle }
|
||||||
|
disabled={ disabled }
|
||||||
|
className={ `helix-toggle-switch ${
|
||||||
|
value
|
||||||
|
? 'helix-toggle-switch-on'
|
||||||
|
: 'helix-toggle-switch-off'
|
||||||
|
} ${ disabled ? 'helix-toggle-switch-disabled' : '' }` }
|
||||||
|
{ ...props }
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className={ `helix-toggle-knob ${
|
||||||
|
value
|
||||||
|
? 'helix-toggle-knob-on'
|
||||||
|
: 'helix-toggle-knob-off'
|
||||||
|
}` }
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</FormField>
|
</FormField>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -364,45 +364,83 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.helix-toggle-input {
|
|
||||||
position: relative;
|
|
||||||
width: 48px;
|
|
||||||
height: 24px;
|
|
||||||
appearance: none;
|
|
||||||
background: var(--helix-color-3);
|
|
||||||
border-radius: 12px;
|
|
||||||
outline: none;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: background-color 0.2s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.helix-toggle-input:checked {
|
|
||||||
background: var(--helix-color-8);
|
|
||||||
}
|
|
||||||
|
|
||||||
.helix-toggle-input::before {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
top: 2px;
|
|
||||||
left: 2px;
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
background: var(--helix-color-1);
|
|
||||||
border-radius: 50%;
|
|
||||||
transition: transform 0.2s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.helix-toggle-input:checked::before {
|
|
||||||
transform: translateX(24px);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.helix-toggle-label {
|
.helix-toggle-label {
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
color: var(--helix-color-9);
|
color: var(--helix-color-9);
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.helix-toggle-label-disabled {
|
||||||
|
opacity: 0.5;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Toggle Switch Button */
|
||||||
|
.helix-toggle-switch {
|
||||||
|
position: relative;
|
||||||
|
width: 48px;
|
||||||
|
height: 24px;
|
||||||
|
border-radius: 24px;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease-in-out;
|
||||||
|
flex-shrink: 0;
|
||||||
|
outline: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.helix-toggle-switch:focus {
|
||||||
|
box-shadow: 0 0 0 3px var(--helix-color-3);
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Switch States */
|
||||||
|
.helix-toggle-switch-off {
|
||||||
|
background-color: var(--helix-color-3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.helix-toggle-switch-off:hover:not(:disabled) {
|
||||||
|
background-color: var(--helix-color-4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.helix-toggle-switch-on {
|
||||||
|
background-color: var(--helix-color-8);
|
||||||
|
}
|
||||||
|
|
||||||
|
.helix-toggle-switch-on:hover:not(:disabled) {
|
||||||
|
background-color: var(--helix-color-9);
|
||||||
|
}
|
||||||
|
|
||||||
|
.helix-toggle-switch-disabled {
|
||||||
|
opacity: 0.5;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Toggle Knob */
|
||||||
|
.helix-toggle-knob {
|
||||||
|
display: inline-block;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 50%;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
||||||
|
transition: transform 0.2s ease-in-out;
|
||||||
|
transform: translateX(2px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.helix-toggle-knob-on {
|
||||||
|
transform: translateX(26px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.helix-toggle-knob-off {
|
||||||
|
transform: translateX(2px);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Notifications */
|
/* Notifications */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue