refactor: migrate checkbox from reach-ui

This commit is contained in:
Aman Harwara
2023-04-21 14:58:35 +05:30
parent 0d235ed1d2
commit a5d536b5f2
8 changed files with 55 additions and 101 deletions

View File

@@ -30,7 +30,6 @@
"@babel/preset-typescript": "^7.18.6",
"@lexical/react": "0.9.2",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.10",
"@reach/checkbox": "^0.18.0",
"@reach/disclosure": "^0.18.0",
"@reach/listbox": "^0.18.0",
"@simplewebauthn/browser": "^7.1.0",

View File

@@ -1,4 +1,3 @@
import { FOCUSABLE_BUT_NOT_TABBABLE } from '@/Constants/Constants'
import { FilesController } from '@/Controllers/FilesController'
import { FileItem } from '@standardnotes/snjs'
import { useState } from 'react'
@@ -6,8 +5,8 @@ import { FileItemActionType } from '../AttachedFilesPopover/PopoverFileItemActio
import { FileContextMenuBackupOption } from '../FileContextMenu/FileContextMenuBackupOption'
import Icon from '../Icon/Icon'
import MenuItem from '../Menu/MenuItem'
import MenuSwitchButtonItem from '../Menu/MenuSwitchButtonItem'
import HorizontalSeparator from '../Shared/HorizontalSeparator'
import Switch from '../Switch/Switch'
type Props = {
file: FileItem
@@ -37,9 +36,10 @@ const LinkedFileMenuOptions = ({ file, closeMenu, handleFileAction, setIsRenamin
Preview file
</MenuItem>
<HorizontalSeparator classes="my-1" />
<MenuItem
<MenuSwitchButtonItem
className="justify-between"
onClick={() => {
checked={isFileProtected}
onChange={() => {
handleFileAction({
type: FileItemActionType.ToggleFileProtection,
payload: { file },
@@ -49,12 +49,9 @@ const LinkedFileMenuOptions = ({ file, closeMenu, handleFileAction, setIsRenamin
}).catch(console.error)
}}
>
<span className="flex items-center">
<Icon type="lock" className="mr-2 text-neutral" />
Password protect
</span>
<Switch className="pointer-events-none px-0" tabIndex={FOCUSABLE_BUT_NOT_TABBABLE} checked={isFileProtected} />
</MenuItem>
</MenuSwitchButtonItem>
<HorizontalSeparator classes="my-1" />
<MenuItem
onClick={() => {

View File

@@ -4,13 +4,12 @@ import { PlatformedKeyboardShortcut } from '@standardnotes/ui-services'
import { ComponentPropsWithoutRef, ForwardedRef, forwardRef, ReactNode } from 'react'
import { KeyboardShortcutIndicator } from '../KeyboardShortcutIndicator/KeyboardShortcutIndicator'
import Switch from '../Switch/Switch'
import { SwitchProps } from '../Switch/SwitchProps'
import MenuListItem from './MenuListItem'
type Props = {
checked: boolean
children: ReactNode
onChange: NonNullable<SwitchProps['onChange']>
onChange: (checked: boolean) => void
shortcut?: PlatformedKeyboardShortcut
} & Omit<ComponentPropsWithoutRef<'button'>, 'onChange'>
@@ -42,7 +41,7 @@ const MenuSwitchButtonItem = forwardRef(
<span className="flex flex-grow items-center">{children}</span>
<div className="flex items-center">
{shortcut && <KeyboardShortcutIndicator className="mr-2" shortcut={shortcut} />}
<Switch disabled={disabled} className="px-0" checked={checked} />
<Switch disabled={disabled} className="pointer-events-none px-0" checked={checked} onChange={onChange} />
</div>
</button>
</MenuListItem>

View File

@@ -1,10 +1,8 @@
import { WebApplication } from '@/Application/Application'
import { FunctionComponent, MouseEventHandler, useCallback, useMemo } from 'react'
import Switch from '@/Components/Switch/Switch'
import { FunctionComponent, useCallback, useMemo } from 'react'
import { isMobileScreen } from '@/Utils'
import { TOGGLE_FOCUS_MODE_COMMAND } from '@standardnotes/ui-services'
import { KeyboardShortcutIndicator } from '../KeyboardShortcutIndicator/KeyboardShortcutIndicator'
import MenuItem from '../Menu/MenuItem'
import MenuSwitchButtonItem from '../Menu/MenuSwitchButtonItem'
type Props = {
application: WebApplication
@@ -14,15 +12,10 @@ type Props = {
}
const FocusModeSwitch: FunctionComponent<Props> = ({ application, onToggle, onClose, isEnabled }) => {
const toggle: MouseEventHandler = useCallback(
(e) => {
e.preventDefault()
const toggle = useCallback(() => {
onToggle(!isEnabled)
onClose()
},
[onToggle, isEnabled, onClose],
)
}, [onToggle, isEnabled, onClose])
const shortcut = useMemo(
() => application.keyboardService.keyboardShortcutForCommand(TOGGLE_FOCUS_MODE_COMMAND),
@@ -36,13 +29,9 @@ const FocusModeSwitch: FunctionComponent<Props> = ({ application, onToggle, onCl
}
return (
<MenuItem onClick={toggle}>
<div className="flex items-center">Focus Mode</div>
<div className="ml-auto flex">
{shortcut && <KeyboardShortcutIndicator className="mr-2" shortcut={shortcut} />}
<Switch className="px-0" checked={isEnabled} />
</div>
</MenuItem>
<MenuSwitchButtonItem onChange={toggle} shortcut={shortcut} checked={isEnabled}>
Focus Mode
</MenuSwitchButtonItem>
)
}

View File

@@ -1,49 +1,46 @@
import { CustomCheckboxContainer, CustomCheckboxInput, CustomCheckboxInputProps } from '@reach/checkbox'
import { FunctionComponent, useState } from 'react'
import { SwitchProps } from './SwitchProps'
import { Checkbox, VisuallyHidden } from '@ariakit/react'
import { classNames } from '@standardnotes/snjs'
const Switch: FunctionComponent<SwitchProps> = (props: SwitchProps) => {
const [checkedState, setChecked] = useState(props.checked || false)
const checked = props.checked ?? checkedState
const className = props.className ?? ''
const isDisabled = !!props.disabled
const isActive = checked && !isDisabled
const Switch = ({
checked,
onChange,
className,
disabled = false,
tabIndex,
}: {
checked: boolean
onChange: (checked: boolean) => void
className?: string
disabled?: boolean
tabIndex?: number
}) => {
const isActive = checked && !disabled
return (
<label
className={`sn-component flex cursor-pointer items-center justify-between px-3 ${className} ${
isDisabled ? 'opacity-50' : ''
}`}
{...(props.role ? { role: props.role } : {})}
className={classNames(
'relative box-content inline-block h-4.5 w-8 flex-shrink-0 cursor-pointer rounded-full border-2 border-solid border-transparent bg-clip-padding transition-colors duration-150 ease-out',
'ring-2 ring-transparent focus-within:border-default focus-within:shadow-none focus-within:outline-none focus-within:ring-info',
disabled ? 'opacity-50' : '',
isActive ? 'bg-info' : 'bg-neutral',
className,
)}
>
{props.children}
<CustomCheckboxContainer
<VisuallyHidden>
<Checkbox
checked={checked}
onChange={(event) => {
setChecked(event.target.checked)
props.onChange?.(event.target.checked)
onChange(event.target.checked)
}}
className={`relative box-content inline-block h-4.5 w-8 cursor-pointer rounded-full border-2 border-solid border-transparent bg-clip-padding transition-colors duration-150 ease-out focus-within:border-default focus-within:shadow-none focus-within:outline-none focus-within:ring-info ${
isActive ? 'bg-info' : 'bg-neutral'
}`}
disabled={props.disabled}
>
<CustomCheckboxInput
{...({
...props,
className:
'absolute top-0 left-0 m-0 p-0 w-full h-full opacity-0 z-[1] shadow-none outline-none cursor-pointer',
children: undefined,
} as CustomCheckboxInputProps)}
tabIndex={tabIndex}
/>
<span
aria-hidden
className={`absolute left-[2px] top-1/2 block h-3.5 w-3.5 -translate-y-1/2 rounded-full bg-default transition-transform duration-150 ease-out ${
checked ? 'translate-x-[calc(2rem-1.125rem)]' : ''
}`}
</VisuallyHidden>
<div
className={classNames(
'absolute left-[2px] top-1/2 block h-3.5 w-3.5 -translate-y-1/2 rounded-full bg-default transition-transform duration-150 ease-out',
checked ? 'translate-x-[calc(2rem-1.125rem)]' : '',
)}
/>
</CustomCheckboxContainer>
</label>
)
}

View File

@@ -1,11 +0,0 @@
import { ReactNode } from 'react'
export type SwitchProps = {
checked?: boolean
onChange?: (checked: boolean) => void
className?: string
children?: ReactNode
role?: string
disabled?: boolean
tabIndex?: number
}

View File

@@ -4272,21 +4272,6 @@ __metadata:
languageName: node
linkType: hard
"@reach/checkbox@npm:^0.18.0":
version: 0.18.0
resolution: "@reach/checkbox@npm:0.18.0"
dependencies:
"@reach/auto-id": 0.18.0
"@reach/machine": 0.18.0
"@reach/polymorphic": 0.18.0
"@reach/utils": 0.18.0
peerDependencies:
react: ^16.8.0 || 17.x
react-dom: ^16.8.0 || 17.x
checksum: 6f40bfb54661af2ae70a161e4275f8f7b36622ea33c74dbcc4370bd2deca71dc468fefc96668a62a1efd690f934d6e5d974f7c8a7e08bdb6b88a4bad960f347e
languageName: node
linkType: hard
"@reach/descendants@npm:0.18.0":
version: 0.18.0
resolution: "@reach/descendants@npm:0.18.0"
@@ -5694,7 +5679,6 @@ __metadata:
"@lexical/react": 0.9.2
"@pmmmwh/react-refresh-webpack-plugin": ^0.5.10
"@radix-ui/react-slot": ^1.0.1
"@reach/checkbox": ^0.18.0
"@reach/disclosure": ^0.18.0
"@reach/listbox": ^0.18.0
"@simplewebauthn/browser": ^7.1.0