diff --git a/src/ui/generic/Toggle.css b/src/ui/generic/Toggle.css index 207c19b..d9b9dba 100644 --- a/src/ui/generic/Toggle.css +++ b/src/ui/generic/Toggle.css @@ -1,52 +1,53 @@ .toggle { - -webkit-appearance: none; - border: 0; - width: 2.4rem; - padding: 0.25rem; + background: none; + border: none; + cursor: inherit; + display: block; + outline: inherit; + padding: 0; + position: relative; + width: 2rem; + z-index: 0; } -.toggle, -.toggle:focus { - background-color: transparent; - box-shadow: none; -} +.toggle__bar { + background-color: var(--secondary); -.toggle:disabled { - background-color: transparent; -} + border-radius: 2rem; -.toggle::-webkit-slider-runnable-track { - height: 1rem; border-radius: 1rem; cursor: pointer; -} -.toggle--off::-webkit-slider-runnable-track { - background-color: var(--secondary); - opacity: 0.8; -} -.toggle--on::-webkit-slider-runnable-track { - background-color: var(--primary-opacity-2); -} -.toggle::-webkit-slider-thumb { - -webkit-appearance: none; - width: 1rem; + top: 2px; + left: 0px; + height: 1rem; - border-radius: 1rem; - margin-right: -0.125rem; - background-color: var(--secondary); + width: 100%; + + position: absolute; + z-index: 0; } -.toggle--off::-webkit-slider-thumb { - background-color: var(--text-muted); - opacity: 0.2; + +.toggle__bar--active { + background-color: rgba(28, 126, 214, 0.2); } -.toggle--off::-webkit-slider-thumb:active { - background-color: var(--primary); - opacity: 0.5; + +.toggle__knob { + background-color: var(--text-muted); + opacity: 0.8; + border-radius: 0.5rem; + + display: block; + + height: 1rem; + width: 16px; + margin-top: 2px; + + position: relative; + z-index: 1; } -.toggle--on::-webkit-slider-thumb { + +.toggle__knob--active { background-color: var(--primary); -} -.toggle--on::-webkit-slider-thumb:active { - opacity: 0.7; + transform: translate3d(18px, 0, 0); } diff --git a/src/ui/generic/Toggle.tsx b/src/ui/generic/Toggle.tsx index 8a00c3b..2091b16 100644 --- a/src/ui/generic/Toggle.tsx +++ b/src/ui/generic/Toggle.tsx @@ -30,75 +30,46 @@ export class Toggle extends React.PureComponent { public render(): JSX.Element | null { const value = this.state.value === undefined ? this.props.value : this.state.value - // console.log({ value, stateValue: this.state.value, propsValue: this.props.value }) + return ( - + > + + + ) } - // Track mousedown state to avoid a click triggering both the change and click events (and toggling the value - // twice). Also track whether the value changed during mousedown so that clicking and releasing on one side - // will toggle it. - private mouseDown = false - private changedDuringMouseDown = false - private onMouseDown: React.MouseEventHandler = e => { - this.mouseDown = true - this.changedDuringMouseDown = false - } - - private onChange: React.FormEventHandler = e => { - const value = e.currentTarget.valueAsNumber === 1 - if (this.mouseDown) { - this.changedDuringMouseDown = true - this.setState({ value }) - } else { - this.onToggle(value) - } - } - - private onMouseUp: React.MouseEventHandler = e => { - if (!this.mouseDown) { + private onClick: React.FormEventHandler = e => { + if (this.props.disabled) { return } - this.mouseDown = false - // Clicking and releasing entirely on one side will toggle the current value. - let value = e.currentTarget.valueAsNumber === 1 - if (!this.changedDuringMouseDown) { - const rect = e.currentTarget.getBoundingClientRect() - const mouseOverElement = - rect.left <= e.pageX && - rect.left + rect.width >= e.pageX && - rect.top <= e.pageY && - rect.top + rect.height >= e.pageY - if (!mouseOverElement) { - return + this.setState( + ({ value }) => ({ value: !value }), + () => { + this.onToggle(this.state.value!) } - value = !value - } - this.setState({ value: undefined }, () => this.onToggle(value)) + ) } private onToggle(value: boolean): void { - if (value !== !!this.props.value) { - if (this.props.onToggle) { - this.props.onToggle(value) - } + if (value !== !!this.props.value && this.props.onToggle) { + this.props.onToggle(value) } } }