refactor: migrate checkbox from reach-ui
This commit is contained in:
Binary file not shown.
@@ -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",
|
||||
|
||||
@@ -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={() => {
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
16
yarn.lock
16
yarn.lock
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user