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",
|
"@babel/preset-typescript": "^7.18.6",
|
||||||
"@lexical/react": "0.9.2",
|
"@lexical/react": "0.9.2",
|
||||||
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.10",
|
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.10",
|
||||||
"@reach/checkbox": "^0.18.0",
|
|
||||||
"@reach/disclosure": "^0.18.0",
|
"@reach/disclosure": "^0.18.0",
|
||||||
"@reach/listbox": "^0.18.0",
|
"@reach/listbox": "^0.18.0",
|
||||||
"@simplewebauthn/browser": "^7.1.0",
|
"@simplewebauthn/browser": "^7.1.0",
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { FOCUSABLE_BUT_NOT_TABBABLE } from '@/Constants/Constants'
|
|
||||||
import { FilesController } from '@/Controllers/FilesController'
|
import { FilesController } from '@/Controllers/FilesController'
|
||||||
import { FileItem } from '@standardnotes/snjs'
|
import { FileItem } from '@standardnotes/snjs'
|
||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
@@ -6,8 +5,8 @@ import { FileItemActionType } from '../AttachedFilesPopover/PopoverFileItemActio
|
|||||||
import { FileContextMenuBackupOption } from '../FileContextMenu/FileContextMenuBackupOption'
|
import { FileContextMenuBackupOption } from '../FileContextMenu/FileContextMenuBackupOption'
|
||||||
import Icon from '../Icon/Icon'
|
import Icon from '../Icon/Icon'
|
||||||
import MenuItem from '../Menu/MenuItem'
|
import MenuItem from '../Menu/MenuItem'
|
||||||
|
import MenuSwitchButtonItem from '../Menu/MenuSwitchButtonItem'
|
||||||
import HorizontalSeparator from '../Shared/HorizontalSeparator'
|
import HorizontalSeparator from '../Shared/HorizontalSeparator'
|
||||||
import Switch from '../Switch/Switch'
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
file: FileItem
|
file: FileItem
|
||||||
@@ -37,9 +36,10 @@ const LinkedFileMenuOptions = ({ file, closeMenu, handleFileAction, setIsRenamin
|
|||||||
Preview file
|
Preview file
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<HorizontalSeparator classes="my-1" />
|
<HorizontalSeparator classes="my-1" />
|
||||||
<MenuItem
|
<MenuSwitchButtonItem
|
||||||
className="justify-between"
|
className="justify-between"
|
||||||
onClick={() => {
|
checked={isFileProtected}
|
||||||
|
onChange={() => {
|
||||||
handleFileAction({
|
handleFileAction({
|
||||||
type: FileItemActionType.ToggleFileProtection,
|
type: FileItemActionType.ToggleFileProtection,
|
||||||
payload: { file },
|
payload: { file },
|
||||||
@@ -49,12 +49,9 @@ const LinkedFileMenuOptions = ({ file, closeMenu, handleFileAction, setIsRenamin
|
|||||||
}).catch(console.error)
|
}).catch(console.error)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span className="flex items-center">
|
<Icon type="lock" className="mr-2 text-neutral" />
|
||||||
<Icon type="lock" className="mr-2 text-neutral" />
|
Password protect
|
||||||
Password protect
|
</MenuSwitchButtonItem>
|
||||||
</span>
|
|
||||||
<Switch className="pointer-events-none px-0" tabIndex={FOCUSABLE_BUT_NOT_TABBABLE} checked={isFileProtected} />
|
|
||||||
</MenuItem>
|
|
||||||
<HorizontalSeparator classes="my-1" />
|
<HorizontalSeparator classes="my-1" />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
|||||||
@@ -4,13 +4,12 @@ import { PlatformedKeyboardShortcut } from '@standardnotes/ui-services'
|
|||||||
import { ComponentPropsWithoutRef, ForwardedRef, forwardRef, ReactNode } from 'react'
|
import { ComponentPropsWithoutRef, ForwardedRef, forwardRef, ReactNode } from 'react'
|
||||||
import { KeyboardShortcutIndicator } from '../KeyboardShortcutIndicator/KeyboardShortcutIndicator'
|
import { KeyboardShortcutIndicator } from '../KeyboardShortcutIndicator/KeyboardShortcutIndicator'
|
||||||
import Switch from '../Switch/Switch'
|
import Switch from '../Switch/Switch'
|
||||||
import { SwitchProps } from '../Switch/SwitchProps'
|
|
||||||
import MenuListItem from './MenuListItem'
|
import MenuListItem from './MenuListItem'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
checked: boolean
|
checked: boolean
|
||||||
children: ReactNode
|
children: ReactNode
|
||||||
onChange: NonNullable<SwitchProps['onChange']>
|
onChange: (checked: boolean) => void
|
||||||
shortcut?: PlatformedKeyboardShortcut
|
shortcut?: PlatformedKeyboardShortcut
|
||||||
} & Omit<ComponentPropsWithoutRef<'button'>, 'onChange'>
|
} & Omit<ComponentPropsWithoutRef<'button'>, 'onChange'>
|
||||||
|
|
||||||
@@ -42,7 +41,7 @@ const MenuSwitchButtonItem = forwardRef(
|
|||||||
<span className="flex flex-grow items-center">{children}</span>
|
<span className="flex flex-grow items-center">{children}</span>
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
{shortcut && <KeyboardShortcutIndicator className="mr-2" shortcut={shortcut} />}
|
{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>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
</MenuListItem>
|
</MenuListItem>
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
import { WebApplication } from '@/Application/Application'
|
import { WebApplication } from '@/Application/Application'
|
||||||
import { FunctionComponent, MouseEventHandler, useCallback, useMemo } from 'react'
|
import { FunctionComponent, useCallback, useMemo } from 'react'
|
||||||
import Switch from '@/Components/Switch/Switch'
|
|
||||||
import { isMobileScreen } from '@/Utils'
|
import { isMobileScreen } from '@/Utils'
|
||||||
import { TOGGLE_FOCUS_MODE_COMMAND } from '@standardnotes/ui-services'
|
import { TOGGLE_FOCUS_MODE_COMMAND } from '@standardnotes/ui-services'
|
||||||
import { KeyboardShortcutIndicator } from '../KeyboardShortcutIndicator/KeyboardShortcutIndicator'
|
import MenuSwitchButtonItem from '../Menu/MenuSwitchButtonItem'
|
||||||
import MenuItem from '../Menu/MenuItem'
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
application: WebApplication
|
application: WebApplication
|
||||||
@@ -14,15 +12,10 @@ type Props = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const FocusModeSwitch: FunctionComponent<Props> = ({ application, onToggle, onClose, isEnabled }) => {
|
const FocusModeSwitch: FunctionComponent<Props> = ({ application, onToggle, onClose, isEnabled }) => {
|
||||||
const toggle: MouseEventHandler = useCallback(
|
const toggle = useCallback(() => {
|
||||||
(e) => {
|
onToggle(!isEnabled)
|
||||||
e.preventDefault()
|
onClose()
|
||||||
|
}, [onToggle, isEnabled, onClose])
|
||||||
onToggle(!isEnabled)
|
|
||||||
onClose()
|
|
||||||
},
|
|
||||||
[onToggle, isEnabled, onClose],
|
|
||||||
)
|
|
||||||
|
|
||||||
const shortcut = useMemo(
|
const shortcut = useMemo(
|
||||||
() => application.keyboardService.keyboardShortcutForCommand(TOGGLE_FOCUS_MODE_COMMAND),
|
() => application.keyboardService.keyboardShortcutForCommand(TOGGLE_FOCUS_MODE_COMMAND),
|
||||||
@@ -36,13 +29,9 @@ const FocusModeSwitch: FunctionComponent<Props> = ({ application, onToggle, onCl
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MenuItem onClick={toggle}>
|
<MenuSwitchButtonItem onChange={toggle} shortcut={shortcut} checked={isEnabled}>
|
||||||
<div className="flex items-center">Focus Mode</div>
|
Focus Mode
|
||||||
<div className="ml-auto flex">
|
</MenuSwitchButtonItem>
|
||||||
{shortcut && <KeyboardShortcutIndicator className="mr-2" shortcut={shortcut} />}
|
|
||||||
<Switch className="px-0" checked={isEnabled} />
|
|
||||||
</div>
|
|
||||||
</MenuItem>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,49 +1,46 @@
|
|||||||
import { CustomCheckboxContainer, CustomCheckboxInput, CustomCheckboxInputProps } from '@reach/checkbox'
|
import { Checkbox, VisuallyHidden } from '@ariakit/react'
|
||||||
import { FunctionComponent, useState } from 'react'
|
import { classNames } from '@standardnotes/snjs'
|
||||||
import { SwitchProps } from './SwitchProps'
|
|
||||||
|
|
||||||
const Switch: FunctionComponent<SwitchProps> = (props: SwitchProps) => {
|
const Switch = ({
|
||||||
const [checkedState, setChecked] = useState(props.checked || false)
|
checked,
|
||||||
const checked = props.checked ?? checkedState
|
onChange,
|
||||||
const className = props.className ?? ''
|
className,
|
||||||
|
disabled = false,
|
||||||
const isDisabled = !!props.disabled
|
tabIndex,
|
||||||
const isActive = checked && !isDisabled
|
}: {
|
||||||
|
checked: boolean
|
||||||
|
onChange: (checked: boolean) => void
|
||||||
|
className?: string
|
||||||
|
disabled?: boolean
|
||||||
|
tabIndex?: number
|
||||||
|
}) => {
|
||||||
|
const isActive = checked && !disabled
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<label
|
<label
|
||||||
className={`sn-component flex cursor-pointer items-center justify-between px-3 ${className} ${
|
className={classNames(
|
||||||
isDisabled ? 'opacity-50' : ''
|
'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',
|
||||||
{...(props.role ? { role: props.role } : {})}
|
disabled ? 'opacity-50' : '',
|
||||||
|
isActive ? 'bg-info' : 'bg-neutral',
|
||||||
|
className,
|
||||||
|
)}
|
||||||
>
|
>
|
||||||
{props.children}
|
<VisuallyHidden>
|
||||||
<CustomCheckboxContainer
|
<Checkbox
|
||||||
checked={checked}
|
checked={checked}
|
||||||
onChange={(event) => {
|
onChange={(event) => {
|
||||||
setChecked(event.target.checked)
|
onChange(event.target.checked)
|
||||||
props.onChange?.(event.target.checked)
|
}}
|
||||||
}}
|
tabIndex={tabIndex}
|
||||||
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)}
|
|
||||||
/>
|
/>
|
||||||
<span
|
</VisuallyHidden>
|
||||||
aria-hidden
|
<div
|
||||||
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 ${
|
className={classNames(
|
||||||
checked ? 'translate-x-[calc(2rem-1.125rem)]' : ''
|
'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>
|
</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
|
languageName: node
|
||||||
linkType: hard
|
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":
|
"@reach/descendants@npm:0.18.0":
|
||||||
version: 0.18.0
|
version: 0.18.0
|
||||||
resolution: "@reach/descendants@npm:0.18.0"
|
resolution: "@reach/descendants@npm:0.18.0"
|
||||||
@@ -5694,7 +5679,6 @@ __metadata:
|
|||||||
"@lexical/react": 0.9.2
|
"@lexical/react": 0.9.2
|
||||||
"@pmmmwh/react-refresh-webpack-plugin": ^0.5.10
|
"@pmmmwh/react-refresh-webpack-plugin": ^0.5.10
|
||||||
"@radix-ui/react-slot": ^1.0.1
|
"@radix-ui/react-slot": ^1.0.1
|
||||||
"@reach/checkbox": ^0.18.0
|
|
||||||
"@reach/disclosure": ^0.18.0
|
"@reach/disclosure": ^0.18.0
|
||||||
"@reach/listbox": ^0.18.0
|
"@reach/listbox": ^0.18.0
|
||||||
"@simplewebauthn/browser": ^7.1.0
|
"@simplewebauthn/browser": ^7.1.0
|
||||||
|
|||||||
Reference in New Issue
Block a user