refactor: menu items (#2057)
This commit is contained in:
@@ -9,7 +9,6 @@ import { AccountMenuPane } from './AccountMenuPane'
|
|||||||
import Menu from '@/Components/Menu/Menu'
|
import Menu from '@/Components/Menu/Menu'
|
||||||
import MenuItem from '@/Components/Menu/MenuItem'
|
import MenuItem from '@/Components/Menu/MenuItem'
|
||||||
import MenuItemSeparator from '@/Components/Menu/MenuItemSeparator'
|
import MenuItemSeparator from '@/Components/Menu/MenuItemSeparator'
|
||||||
import { MenuItemType } from '@/Components/Menu/MenuItemType'
|
|
||||||
import WorkspaceSwitcherOption from './WorkspaceSwitcher/WorkspaceSwitcherOption'
|
import WorkspaceSwitcherOption from './WorkspaceSwitcher/WorkspaceSwitcherOption'
|
||||||
import { ApplicationGroup } from '@/Application/ApplicationGroup'
|
import { ApplicationGroup } from '@/Application/ApplicationGroup'
|
||||||
import { formatLastSyncDate } from '@/Utils/DateUtils'
|
import { formatLastSyncDate } from '@/Utils/DateUtils'
|
||||||
@@ -150,23 +149,23 @@ const GeneralAccountMenu: FunctionComponent<Props> = ({
|
|||||||
/>
|
/>
|
||||||
<MenuItemSeparator />
|
<MenuItemSeparator />
|
||||||
{user ? (
|
{user ? (
|
||||||
<MenuItem type={MenuItemType.IconButton} onClick={openPreferences}>
|
<MenuItem onClick={openPreferences}>
|
||||||
<Icon type="user" className={iconClassName} />
|
<Icon type="user" className={iconClassName} />
|
||||||
Account settings
|
Account settings
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<MenuItem type={MenuItemType.IconButton} onClick={activateRegisterPane}>
|
<MenuItem onClick={activateRegisterPane}>
|
||||||
<Icon type="user" className={iconClassName} />
|
<Icon type="user" className={iconClassName} />
|
||||||
Create free account
|
Create free account
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem type={MenuItemType.IconButton} onClick={activateSignInPane}>
|
<MenuItem onClick={activateSignInPane}>
|
||||||
<Icon type="signIn" className={iconClassName} />
|
<Icon type="signIn" className={iconClassName} />
|
||||||
Sign in
|
Sign in
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
<MenuItem className="justify-between" type={MenuItemType.IconButton} onClick={openHelp}>
|
<MenuItem className="justify-between" onClick={openHelp}>
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<Icon type="help" className={iconClassName} />
|
<Icon type="help" className={iconClassName} />
|
||||||
Help & feedback
|
Help & feedback
|
||||||
@@ -176,7 +175,7 @@ const GeneralAccountMenu: FunctionComponent<Props> = ({
|
|||||||
{user ? (
|
{user ? (
|
||||||
<>
|
<>
|
||||||
<MenuItemSeparator />
|
<MenuItemSeparator />
|
||||||
<MenuItem type={MenuItemType.IconButton} onClick={signOut}>
|
<MenuItem onClick={signOut}>
|
||||||
<Icon type="signOut" className={iconClassName} />
|
<Icon type="signOut" className={iconClassName} />
|
||||||
Sign out workspace
|
Sign out workspace
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
import Icon from '@/Components/Icon/Icon'
|
import Icon from '@/Components/Icon/Icon'
|
||||||
import MenuItem from '@/Components/Menu/MenuItem'
|
|
||||||
import { MenuItemType } from '@/Components/Menu/MenuItemType'
|
|
||||||
import { KeyboardKey } from '@standardnotes/ui-services'
|
import { KeyboardKey } from '@standardnotes/ui-services'
|
||||||
import { ApplicationDescriptor } from '@standardnotes/snjs'
|
import { ApplicationDescriptor } from '@standardnotes/snjs'
|
||||||
import {
|
import {
|
||||||
@@ -13,6 +11,7 @@ import {
|
|||||||
useRef,
|
useRef,
|
||||||
useState,
|
useState,
|
||||||
} from 'react'
|
} from 'react'
|
||||||
|
import MenuRadioButtonItem from '@/Components/Menu/MenuRadioButtonItem'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
descriptor: ApplicationDescriptor
|
descriptor: ApplicationDescriptor
|
||||||
@@ -56,8 +55,7 @@ const WorkspaceMenuItem: FunctionComponent<Props> = ({
|
|||||||
}, [inputValue, renameDescriptor])
|
}, [inputValue, renameDescriptor])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MenuItem
|
<MenuRadioButtonItem
|
||||||
type={MenuItemType.RadioButton}
|
|
||||||
className="flex w-full cursor-pointer items-center border-0 bg-transparent px-3 py-2 text-left text-sm text-text hover:bg-contrast hover:text-foreground focus:bg-info-backdrop focus:shadow-none"
|
className="flex w-full cursor-pointer items-center border-0 bg-transparent px-3 py-2 text-left text-sm text-text hover:bg-contrast hover:text-foreground focus:bg-info-backdrop focus:shadow-none"
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
checked={descriptor.primary}
|
checked={descriptor.primary}
|
||||||
@@ -100,7 +98,7 @@ const WorkspaceMenuItem: FunctionComponent<Props> = ({
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</MenuItem>
|
</MenuRadioButtonItem>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import Icon from '@/Components/Icon/Icon'
|
|||||||
import Menu from '@/Components/Menu/Menu'
|
import Menu from '@/Components/Menu/Menu'
|
||||||
import MenuItem from '@/Components/Menu/MenuItem'
|
import MenuItem from '@/Components/Menu/MenuItem'
|
||||||
import MenuItemSeparator from '@/Components/Menu/MenuItemSeparator'
|
import MenuItemSeparator from '@/Components/Menu/MenuItemSeparator'
|
||||||
import { MenuItemType } from '@/Components/Menu/MenuItemType'
|
|
||||||
import WorkspaceMenuItem from './WorkspaceMenuItem'
|
import WorkspaceMenuItem from './WorkspaceMenuItem'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
@@ -85,13 +84,13 @@ const WorkspaceSwitcherMenu: FunctionComponent<Props> = ({
|
|||||||
))}
|
))}
|
||||||
<MenuItemSeparator />
|
<MenuItemSeparator />
|
||||||
|
|
||||||
<MenuItem type={MenuItemType.IconButton} onClick={addAnotherWorkspace}>
|
<MenuItem onClick={addAnotherWorkspace}>
|
||||||
<Icon type="user-add" className="mr-2 text-neutral" />
|
<Icon type="user-add" className="mr-2 text-neutral" />
|
||||||
Add another workspace
|
Add another workspace
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
|
||||||
{!hideWorkspaceOptions && (
|
{!hideWorkspaceOptions && (
|
||||||
<MenuItem type={MenuItemType.IconButton} onClick={signoutAll}>
|
<MenuItem onClick={signoutAll}>
|
||||||
<Icon type="signOut" className="mr-2 text-neutral" />
|
<Icon type="signOut" className="mr-2 text-neutral" />
|
||||||
Sign out all workspaces
|
Sign out all workspaces
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import { FunctionComponent, useCallback, useRef, useState } from 'react'
|
|||||||
import Icon from '@/Components/Icon/Icon'
|
import Icon from '@/Components/Icon/Icon'
|
||||||
import WorkspaceSwitcherMenu from './WorkspaceSwitcherMenu'
|
import WorkspaceSwitcherMenu from './WorkspaceSwitcherMenu'
|
||||||
import MenuItem from '@/Components/Menu/MenuItem'
|
import MenuItem from '@/Components/Menu/MenuItem'
|
||||||
import { MenuItemType } from '@/Components/Menu/MenuItemType'
|
|
||||||
import Popover from '@/Components/Popover/Popover'
|
import Popover from '@/Components/Popover/Popover'
|
||||||
import { MenuItemIconSize } from '@/Constants/TailwindClassNames'
|
import { MenuItemIconSize } from '@/Constants/TailwindClassNames'
|
||||||
|
|
||||||
@@ -25,13 +24,7 @@ const WorkspaceSwitcherOption: FunctionComponent<Props> = ({ mainApplicationGrou
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<MenuItem
|
<MenuItem tabIndex={FOCUSABLE_BUT_NOT_TABBABLE} ref={buttonRef} onClick={toggleMenu} className="justify-between">
|
||||||
tabIndex={FOCUSABLE_BUT_NOT_TABBABLE}
|
|
||||||
ref={buttonRef}
|
|
||||||
type={MenuItemType.IconButton}
|
|
||||||
onClick={toggleMenu}
|
|
||||||
className="justify-between"
|
|
||||||
>
|
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<Icon type="user-switch" className={`mr-2 text-neutral ${MenuItemIconSize}`} />
|
<Icon type="user-switch" className={`mr-2 text-neutral ${MenuItemIconSize}`} />
|
||||||
Switch workspace
|
Switch workspace
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import Icon from '@/Components/Icon/Icon'
|
import Icon from '@/Components/Icon/Icon'
|
||||||
import Menu from '@/Components/Menu/Menu'
|
import Menu from '@/Components/Menu/Menu'
|
||||||
import MenuItem from '@/Components/Menu/MenuItem'
|
|
||||||
import { MenuItemType } from '@/Components/Menu/MenuItemType'
|
|
||||||
import { usePremiumModal } from '@/Hooks/usePremiumModal'
|
import { usePremiumModal } from '@/Hooks/usePremiumModal'
|
||||||
import { STRING_EDIT_LOCKED_ATTEMPT } from '@/Constants/Strings'
|
import { STRING_EDIT_LOCKED_ATTEMPT } from '@/Constants/Strings'
|
||||||
import { WebApplication } from '@/Application/Application'
|
import { WebApplication } from '@/Application/Application'
|
||||||
@@ -13,6 +11,7 @@ import { createEditorMenuGroups } from '../../Utils/createEditorMenuGroups'
|
|||||||
import { reloadFont } from '../NoteView/FontFunctions'
|
import { reloadFont } from '../NoteView/FontFunctions'
|
||||||
import { PremiumFeatureIconClass, PremiumFeatureIconName } from '../Icon/PremiumFeatureIcon'
|
import { PremiumFeatureIconClass, PremiumFeatureIconName } from '../Icon/PremiumFeatureIcon'
|
||||||
import { SuperNoteImporter } from '../NoteView/SuperEditor/SuperNoteImporter'
|
import { SuperNoteImporter } from '../NoteView/SuperEditor/SuperNoteImporter'
|
||||||
|
import MenuRadioButtonItem from '../Menu/MenuRadioButtonItem'
|
||||||
|
|
||||||
type ChangeEditorMenuProps = {
|
type ChangeEditorMenuProps = {
|
||||||
application: WebApplication
|
application: WebApplication
|
||||||
@@ -190,12 +189,11 @@ const ChangeEditorMenu: FunctionComponent<ChangeEditorMenuProps> = ({
|
|||||||
selectItem(item).catch(console.error)
|
selectItem(item).catch(console.error)
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<MenuItem
|
<MenuRadioButtonItem
|
||||||
key={item.name}
|
key={item.name}
|
||||||
type={MenuItemType.RadioButton}
|
|
||||||
onClick={onClickEditorItem}
|
onClick={onClickEditorItem}
|
||||||
className={'flex-row-reverse py-2'}
|
className={'flex-row-reverse py-2'}
|
||||||
checked={item.isEntitled ? isSelected(item) : undefined}
|
checked={item.isEntitled ? isSelected(item) : false}
|
||||||
>
|
>
|
||||||
<div className="flex flex-grow items-center justify-between">
|
<div className="flex flex-grow items-center justify-between">
|
||||||
<div className={`flex items-center ${group.featured ? 'font-bold' : ''}`}>
|
<div className={`flex items-center ${group.featured ? 'font-bold' : ''}`}>
|
||||||
@@ -206,7 +204,7 @@ const ChangeEditorMenu: FunctionComponent<ChangeEditorMenuProps> = ({
|
|||||||
<Icon type={PremiumFeatureIconName} className={PremiumFeatureIconClass} />
|
<Icon type={PremiumFeatureIconName} className={PremiumFeatureIconClass} />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</MenuItem>
|
</MenuRadioButtonItem>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -13,15 +13,15 @@ import { observer } from 'mobx-react-lite'
|
|||||||
import { FunctionComponent, useCallback, useEffect, useState } from 'react'
|
import { FunctionComponent, useCallback, useEffect, useState } from 'react'
|
||||||
import Icon from '@/Components/Icon/Icon'
|
import Icon from '@/Components/Icon/Icon'
|
||||||
import Menu from '@/Components/Menu/Menu'
|
import Menu from '@/Components/Menu/Menu'
|
||||||
import MenuItem from '@/Components/Menu/MenuItem'
|
|
||||||
import MenuItemSeparator from '@/Components/Menu/MenuItemSeparator'
|
import MenuItemSeparator from '@/Components/Menu/MenuItemSeparator'
|
||||||
import { MenuItemType } from '@/Components/Menu/MenuItemType'
|
|
||||||
import { DisplayOptionsMenuProps } from './DisplayOptionsMenuProps'
|
import { DisplayOptionsMenuProps } from './DisplayOptionsMenuProps'
|
||||||
import { PrefDefaults } from '@/Constants/PrefDefaults'
|
import { PrefDefaults } from '@/Constants/PrefDefaults'
|
||||||
import NewNotePreferences from './NewNotePreferences'
|
import NewNotePreferences from './NewNotePreferences'
|
||||||
import { PreferenceMode } from './PreferenceMode'
|
import { PreferenceMode } from './PreferenceMode'
|
||||||
import { classNames } from '@standardnotes/utils'
|
import { classNames } from '@standardnotes/utils'
|
||||||
import NoSubscriptionBanner from '@/Components/NoSubscriptionBanner/NoSubscriptionBanner'
|
import NoSubscriptionBanner from '@/Components/NoSubscriptionBanner/NoSubscriptionBanner'
|
||||||
|
import MenuRadioButtonItem from '@/Components/Menu/MenuRadioButtonItem'
|
||||||
|
import MenuSwitchButtonItem from '@/Components/Menu/MenuSwitchButtonItem'
|
||||||
|
|
||||||
const DailyEntryModeEnabled = true
|
const DailyEntryModeEnabled = true
|
||||||
|
|
||||||
@@ -230,10 +230,9 @@ const DisplayOptionsMenu: FunctionComponent<DisplayOptionsMenuProps> = ({
|
|||||||
<MenuItemSeparator />
|
<MenuItemSeparator />
|
||||||
|
|
||||||
<div className="my-1 px-3 text-base font-semibold uppercase text-text lg:text-xs">Sort by</div>
|
<div className="my-1 px-3 text-base font-semibold uppercase text-text lg:text-xs">Sort by</div>
|
||||||
<MenuItem
|
<MenuRadioButtonItem
|
||||||
disabled={controlsDisabled || isDailyEntry}
|
disabled={controlsDisabled || isDailyEntry}
|
||||||
className="py-2"
|
className="py-2"
|
||||||
type={MenuItemType.RadioButton}
|
|
||||||
onClick={toggleSortByDateModified}
|
onClick={toggleSortByDateModified}
|
||||||
checked={preferences.sortBy === CollectionSort.UpdatedAt}
|
checked={preferences.sortBy === CollectionSort.UpdatedAt}
|
||||||
>
|
>
|
||||||
@@ -247,11 +246,10 @@ const DisplayOptionsMenu: FunctionComponent<DisplayOptionsMenuProps> = ({
|
|||||||
)
|
)
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
</MenuItem>
|
</MenuRadioButtonItem>
|
||||||
<MenuItem
|
<MenuRadioButtonItem
|
||||||
disabled={controlsDisabled || isDailyEntry}
|
disabled={controlsDisabled || isDailyEntry}
|
||||||
className="py-2"
|
className="py-2"
|
||||||
type={MenuItemType.RadioButton}
|
|
||||||
onClick={toggleSortByCreationDate}
|
onClick={toggleSortByCreationDate}
|
||||||
checked={preferences.sortBy === CollectionSort.CreatedAt}
|
checked={preferences.sortBy === CollectionSort.CreatedAt}
|
||||||
>
|
>
|
||||||
@@ -265,11 +263,10 @@ const DisplayOptionsMenu: FunctionComponent<DisplayOptionsMenuProps> = ({
|
|||||||
)
|
)
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
</MenuItem>
|
</MenuRadioButtonItem>
|
||||||
<MenuItem
|
<MenuRadioButtonItem
|
||||||
disabled={controlsDisabled || isDailyEntry}
|
disabled={controlsDisabled || isDailyEntry}
|
||||||
className="py-2"
|
className="py-2"
|
||||||
type={MenuItemType.RadioButton}
|
|
||||||
onClick={toggleSortByTitle}
|
onClick={toggleSortByTitle}
|
||||||
checked={preferences.sortBy === CollectionSort.Title}
|
checked={preferences.sortBy === CollectionSort.Title}
|
||||||
>
|
>
|
||||||
@@ -283,92 +280,83 @@ const DisplayOptionsMenu: FunctionComponent<DisplayOptionsMenuProps> = ({
|
|||||||
)
|
)
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
</MenuItem>
|
</MenuRadioButtonItem>
|
||||||
<MenuItemSeparator />
|
<MenuItemSeparator />
|
||||||
<div className="px-3 py-1 text-base font-semibold uppercase text-text lg:text-xs">View</div>
|
<div className="px-3 py-1 text-base font-semibold uppercase text-text lg:text-xs">View</div>
|
||||||
{!isFilesSmartView && (
|
{!isFilesSmartView && (
|
||||||
<MenuItem
|
<MenuSwitchButtonItem
|
||||||
disabled={controlsDisabled}
|
disabled={controlsDisabled}
|
||||||
type={MenuItemType.SwitchButton}
|
|
||||||
className="py-1 hover:bg-contrast focus:bg-info-backdrop"
|
className="py-1 hover:bg-contrast focus:bg-info-backdrop"
|
||||||
checked={!preferences.hideNotePreview}
|
checked={!preferences.hideNotePreview}
|
||||||
onChange={toggleHidePreview}
|
onChange={toggleHidePreview}
|
||||||
>
|
>
|
||||||
<div className="max-w-3/4 flex flex-col">Show note preview</div>
|
<div className="max-w-3/4 flex flex-col">Show note preview</div>
|
||||||
</MenuItem>
|
</MenuSwitchButtonItem>
|
||||||
)}
|
)}
|
||||||
<MenuItem
|
<MenuSwitchButtonItem
|
||||||
disabled={controlsDisabled}
|
disabled={controlsDisabled}
|
||||||
type={MenuItemType.SwitchButton}
|
|
||||||
className="py-1 hover:bg-contrast focus:bg-info-backdrop"
|
className="py-1 hover:bg-contrast focus:bg-info-backdrop"
|
||||||
checked={!preferences.hideDate}
|
checked={!preferences.hideDate}
|
||||||
onChange={toggleHideDate}
|
onChange={toggleHideDate}
|
||||||
>
|
>
|
||||||
Show date
|
Show date
|
||||||
</MenuItem>
|
</MenuSwitchButtonItem>
|
||||||
<MenuItem
|
<MenuSwitchButtonItem
|
||||||
disabled={controlsDisabled}
|
disabled={controlsDisabled}
|
||||||
type={MenuItemType.SwitchButton}
|
|
||||||
className="py-1 hover:bg-contrast focus:bg-info-backdrop"
|
className="py-1 hover:bg-contrast focus:bg-info-backdrop"
|
||||||
checked={!preferences.hideTags}
|
checked={!preferences.hideTags}
|
||||||
onChange={toggleHideTags}
|
onChange={toggleHideTags}
|
||||||
>
|
>
|
||||||
Show tags
|
Show tags
|
||||||
</MenuItem>
|
</MenuSwitchButtonItem>
|
||||||
<MenuItem
|
<MenuSwitchButtonItem
|
||||||
disabled={controlsDisabled}
|
disabled={controlsDisabled}
|
||||||
type={MenuItemType.SwitchButton}
|
|
||||||
className="py-1 hover:bg-contrast focus:bg-info-backdrop"
|
className="py-1 hover:bg-contrast focus:bg-info-backdrop"
|
||||||
checked={!preferences.hideEditorIcon}
|
checked={!preferences.hideEditorIcon}
|
||||||
onChange={toggleEditorIcon}
|
onChange={toggleEditorIcon}
|
||||||
>
|
>
|
||||||
Show icon
|
Show icon
|
||||||
</MenuItem>
|
</MenuSwitchButtonItem>
|
||||||
<MenuItemSeparator />
|
<MenuItemSeparator />
|
||||||
<div className="px-3 py-1 text-base font-semibold uppercase text-text lg:text-xs">Other</div>
|
<div className="px-3 py-1 text-base font-semibold uppercase text-text lg:text-xs">Other</div>
|
||||||
<MenuItem
|
<MenuSwitchButtonItem
|
||||||
disabled={controlsDisabled}
|
disabled={controlsDisabled}
|
||||||
type={MenuItemType.SwitchButton}
|
|
||||||
className="py-1 hover:bg-contrast focus:bg-info-backdrop"
|
className="py-1 hover:bg-contrast focus:bg-info-backdrop"
|
||||||
checked={!preferences.hidePinned}
|
checked={!preferences.hidePinned}
|
||||||
onChange={toggleHidePinned}
|
onChange={toggleHidePinned}
|
||||||
>
|
>
|
||||||
Show pinned
|
Show pinned
|
||||||
</MenuItem>
|
</MenuSwitchButtonItem>
|
||||||
<MenuItem
|
<MenuSwitchButtonItem
|
||||||
disabled={controlsDisabled}
|
disabled={controlsDisabled}
|
||||||
type={MenuItemType.SwitchButton}
|
|
||||||
className="py-1 hover:bg-contrast focus:bg-info-backdrop"
|
className="py-1 hover:bg-contrast focus:bg-info-backdrop"
|
||||||
checked={!preferences.hideProtected}
|
checked={!preferences.hideProtected}
|
||||||
onChange={toggleHideProtected}
|
onChange={toggleHideProtected}
|
||||||
>
|
>
|
||||||
Show protected
|
Show protected
|
||||||
</MenuItem>
|
</MenuSwitchButtonItem>
|
||||||
<MenuItem
|
<MenuSwitchButtonItem
|
||||||
disabled={controlsDisabled}
|
disabled={controlsDisabled}
|
||||||
type={MenuItemType.SwitchButton}
|
|
||||||
className="py-1 hover:bg-contrast focus:bg-info-backdrop"
|
className="py-1 hover:bg-contrast focus:bg-info-backdrop"
|
||||||
checked={preferences.showArchived}
|
checked={Boolean(preferences.showArchived)}
|
||||||
onChange={toggleShowArchived}
|
onChange={toggleShowArchived}
|
||||||
>
|
>
|
||||||
Show archived
|
Show archived
|
||||||
</MenuItem>
|
</MenuSwitchButtonItem>
|
||||||
<MenuItem
|
<MenuSwitchButtonItem
|
||||||
disabled={controlsDisabled}
|
disabled={controlsDisabled}
|
||||||
type={MenuItemType.SwitchButton}
|
|
||||||
className="py-1 hover:bg-contrast focus:bg-info-backdrop"
|
className="py-1 hover:bg-contrast focus:bg-info-backdrop"
|
||||||
checked={preferences.showTrashed}
|
checked={Boolean(preferences.showTrashed)}
|
||||||
onChange={toggleShowTrashed}
|
onChange={toggleShowTrashed}
|
||||||
>
|
>
|
||||||
Show trashed
|
Show trashed
|
||||||
</MenuItem>
|
</MenuSwitchButtonItem>
|
||||||
|
|
||||||
{currentMode === 'tag' && DailyEntryModeEnabled && (
|
{currentMode === 'tag' && DailyEntryModeEnabled && (
|
||||||
<>
|
<>
|
||||||
<MenuItemSeparator />
|
<MenuItemSeparator />
|
||||||
<MenuItem
|
<MenuSwitchButtonItem
|
||||||
disabled={controlsDisabled}
|
disabled={controlsDisabled}
|
||||||
type={MenuItemType.SwitchButton}
|
|
||||||
className="py-1 hover:bg-contrast focus:bg-info-backdrop"
|
className="py-1 hover:bg-contrast focus:bg-info-backdrop"
|
||||||
checked={isDailyEntry}
|
checked={isDailyEntry}
|
||||||
onChange={toggleEntryMode}
|
onChange={toggleEntryMode}
|
||||||
@@ -382,7 +370,7 @@ const DisplayOptionsMenu: FunctionComponent<DisplayOptionsMenuProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
<div className="mt-1">Capture new notes daily with a calendar-based layout</div>
|
<div className="mt-1">Capture new notes daily with a calendar-based layout</div>
|
||||||
</div>
|
</div>
|
||||||
</MenuItem>
|
</MenuSwitchButtonItem>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ import { formatSizeToReadableString } from '@standardnotes/filepicker'
|
|||||||
import { useResponsiveAppPane } from '../ResponsivePane/ResponsivePaneProvider'
|
import { useResponsiveAppPane } from '../ResponsivePane/ResponsivePaneProvider'
|
||||||
import { AppPaneId } from '../ResponsivePane/AppPaneMetadata'
|
import { AppPaneId } from '../ResponsivePane/AppPaneMetadata'
|
||||||
import MenuItem from '../Menu/MenuItem'
|
import MenuItem from '../Menu/MenuItem'
|
||||||
import { MenuItemType } from '../Menu/MenuItemType'
|
|
||||||
import { FileContextMenuBackupOption } from './FileContextMenuBackupOption'
|
import { FileContextMenuBackupOption } from './FileContextMenuBackupOption'
|
||||||
|
import MenuSwitchButtonItem from '../Menu/MenuSwitchButtonItem'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
closeMenu: () => void
|
closeMenu: () => void
|
||||||
@@ -83,8 +83,7 @@ const FileMenuOptions: FunctionComponent<Props> = ({
|
|||||||
) : null}
|
) : null}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
<MenuItem
|
<MenuSwitchButtonItem
|
||||||
type={MenuItemType.SwitchButton}
|
|
||||||
checked={hasProtectedFiles}
|
checked={hasProtectedFiles}
|
||||||
onChange={(hasProtectedFiles) => {
|
onChange={(hasProtectedFiles) => {
|
||||||
void filesController.setProtectionForFiles(hasProtectedFiles, selectionController.selectedFiles)
|
void filesController.setProtectionForFiles(hasProtectedFiles, selectionController.selectedFiles)
|
||||||
@@ -92,7 +91,7 @@ const FileMenuOptions: FunctionComponent<Props> = ({
|
|||||||
>
|
>
|
||||||
<Icon type="lock" className="mr-2 text-neutral" />
|
<Icon type="lock" className="mr-2 text-neutral" />
|
||||||
Password protect
|
Password protect
|
||||||
</MenuItem>
|
</MenuSwitchButtonItem>
|
||||||
<HorizontalSeparator classes="my-1" />
|
<HorizontalSeparator classes="my-1" />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import { useApplication } from '../ApplicationView/ApplicationProvider'
|
|||||||
import { PopoverFileItemActionType } from '../AttachedFilesPopover/PopoverFileItemAction'
|
import { PopoverFileItemActionType } from '../AttachedFilesPopover/PopoverFileItemAction'
|
||||||
import Icon from '../Icon/Icon'
|
import Icon from '../Icon/Icon'
|
||||||
import MenuItem from '../Menu/MenuItem'
|
import MenuItem from '../Menu/MenuItem'
|
||||||
import { MenuItemType } from '../Menu/MenuItemType'
|
|
||||||
import Popover from '../Popover/Popover'
|
import Popover from '../Popover/Popover'
|
||||||
import HorizontalSeparator from '../Shared/HorizontalSeparator'
|
import HorizontalSeparator from '../Shared/HorizontalSeparator'
|
||||||
import LinkedFileMenuOptions from './LinkedFileMenuOptions'
|
import LinkedFileMenuOptions from './LinkedFileMenuOptions'
|
||||||
@@ -107,7 +106,6 @@ export const LinkedItemsSectionItem = ({
|
|||||||
className="py-2"
|
className="py-2"
|
||||||
>
|
>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
type={MenuItemType.IconButton}
|
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
unlinkItem()
|
unlinkItem()
|
||||||
toggleMenu()
|
toggleMenu()
|
||||||
|
|||||||
@@ -1,79 +1,34 @@
|
|||||||
import { forwardRef, MouseEventHandler, ReactNode, Ref } from 'react'
|
import { ComponentPropsWithoutRef, forwardRef, MouseEventHandler, ReactNode, Ref } from 'react'
|
||||||
import Icon from '@/Components/Icon/Icon'
|
import Icon from '@/Components/Icon/Icon'
|
||||||
import Switch from '@/Components/Switch/Switch'
|
|
||||||
import { SwitchProps } from '@/Components/Switch/SwitchProps'
|
|
||||||
import { IconType } from '@standardnotes/snjs'
|
import { IconType } from '@standardnotes/snjs'
|
||||||
import { FOCUSABLE_BUT_NOT_TABBABLE } from '@/Constants/Constants'
|
import { FOCUSABLE_BUT_NOT_TABBABLE } from '@/Constants/Constants'
|
||||||
import { MenuItemType } from './MenuItemType'
|
|
||||||
import RadioIndicator from '../Radio/RadioIndicator'
|
|
||||||
import { classNames } from '@standardnotes/utils'
|
import { classNames } from '@standardnotes/utils'
|
||||||
import { PlatformedKeyboardShortcut } from '@standardnotes/ui-services'
|
import { PlatformedKeyboardShortcut } from '@standardnotes/ui-services'
|
||||||
import { KeyboardShortcutIndicator } from '../KeyboardShortcutIndicator/KeyboardShortcutIndicator'
|
import { KeyboardShortcutIndicator } from '../KeyboardShortcutIndicator/KeyboardShortcutIndicator'
|
||||||
|
import MenuListItem from './MenuListItem'
|
||||||
|
|
||||||
type MenuItemProps = {
|
type MenuItemProps = {
|
||||||
children: ReactNode
|
children: ReactNode
|
||||||
type?: MenuItemType
|
|
||||||
onClick?: MouseEventHandler<HTMLButtonElement>
|
onClick?: MouseEventHandler<HTMLButtonElement>
|
||||||
onChange?: SwitchProps['onChange']
|
|
||||||
onBlur?: (event: { relatedTarget: EventTarget | null }) => void
|
onBlur?: (event: { relatedTarget: EventTarget | null }) => void
|
||||||
className?: string
|
className?: string
|
||||||
checked?: boolean
|
|
||||||
icon?: IconType
|
icon?: IconType
|
||||||
iconClassName?: string
|
iconClassName?: string
|
||||||
tabIndex?: number
|
tabIndex?: number
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
shortcut?: PlatformedKeyboardShortcut
|
shortcut?: PlatformedKeyboardShortcut
|
||||||
}
|
} & ComponentPropsWithoutRef<'button'>
|
||||||
|
|
||||||
const MenuItem = forwardRef(
|
const MenuItem = forwardRef(
|
||||||
(
|
(
|
||||||
{
|
{ children, className = '', icon, iconClassName, tabIndex, shortcut, ...props }: MenuItemProps,
|
||||||
children,
|
|
||||||
onClick,
|
|
||||||
onChange,
|
|
||||||
onBlur,
|
|
||||||
className = '',
|
|
||||||
type = MenuItemType.IconButton,
|
|
||||||
checked,
|
|
||||||
icon,
|
|
||||||
iconClassName,
|
|
||||||
tabIndex,
|
|
||||||
disabled,
|
|
||||||
shortcut,
|
|
||||||
}: MenuItemProps,
|
|
||||||
ref: Ref<HTMLButtonElement>,
|
ref: Ref<HTMLButtonElement>,
|
||||||
) => {
|
) => {
|
||||||
return type === MenuItemType.SwitchButton && typeof onChange === 'function' ? (
|
return (
|
||||||
<li className="list-none" role="none">
|
<MenuListItem>
|
||||||
<button
|
<button
|
||||||
disabled={disabled}
|
|
||||||
ref={ref}
|
ref={ref}
|
||||||
className={classNames(
|
role="menuitem"
|
||||||
'flex w-full cursor-pointer items-center justify-between border-0 bg-transparent px-3 py-2 md:py-1.5',
|
|
||||||
'text-left text-text hover:bg-contrast hover:text-foreground focus:bg-info-backdrop focus:shadow-none',
|
|
||||||
'text-mobile-menu-item md:text-tablet-menu-item lg:text-menu-item',
|
|
||||||
)}
|
|
||||||
onClick={() => {
|
|
||||||
onChange(!checked)
|
|
||||||
}}
|
|
||||||
onBlur={onBlur}
|
|
||||||
tabIndex={typeof tabIndex === 'number' ? tabIndex : FOCUSABLE_BUT_NOT_TABBABLE}
|
|
||||||
role="menuitemcheckbox"
|
|
||||||
aria-checked={checked}
|
|
||||||
>
|
|
||||||
<span className="flex flex-grow items-center">{children}</span>
|
|
||||||
<div className="flex">
|
|
||||||
{shortcut && <KeyboardShortcutIndicator className="mr-2" shortcut={shortcut} />}
|
|
||||||
<Switch disabled={disabled} className="px-0" checked={checked} />
|
|
||||||
</div>
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
) : (
|
|
||||||
<li className="list-none" role="none">
|
|
||||||
<button
|
|
||||||
disabled={disabled}
|
|
||||||
ref={ref}
|
|
||||||
role={type === MenuItemType.RadioButton ? 'menuitemradio' : 'menuitem'}
|
|
||||||
tabIndex={typeof tabIndex === 'number' ? tabIndex : FOCUSABLE_BUT_NOT_TABBABLE}
|
tabIndex={typeof tabIndex === 'number' ? tabIndex : FOCUSABLE_BUT_NOT_TABBABLE}
|
||||||
className={classNames(
|
className={classNames(
|
||||||
'flex w-full cursor-pointer border-0 bg-transparent px-3 py-2 text-left md:py-1.5',
|
'flex w-full cursor-pointer border-0 bg-transparent px-3 py-2 text-left md:py-1.5',
|
||||||
@@ -82,20 +37,13 @@ const MenuItem = forwardRef(
|
|||||||
className,
|
className,
|
||||||
className.includes('items-') ? '' : 'items-center',
|
className.includes('items-') ? '' : 'items-center',
|
||||||
)}
|
)}
|
||||||
onClick={onClick}
|
{...props}
|
||||||
onBlur={onBlur}
|
|
||||||
{...(type === MenuItemType.RadioButton ? { 'aria-checked': checked } : {})}
|
|
||||||
>
|
>
|
||||||
{shortcut && <KeyboardShortcutIndicator className="mr-2" shortcut={shortcut} />}
|
{shortcut && <KeyboardShortcutIndicator className="mr-2" shortcut={shortcut} />}
|
||||||
{type === MenuItemType.IconButton && icon ? (
|
{icon ? <Icon type={icon} className={classNames('flex-shrink-0', iconClassName)} /> : null}
|
||||||
<Icon type={icon} className={`${iconClassName} flex-shrink-0`} />
|
|
||||||
) : null}
|
|
||||||
{type === MenuItemType.RadioButton && typeof checked === 'boolean' ? (
|
|
||||||
<RadioIndicator disabled={disabled} checked={checked} className="flex-shrink-0" />
|
|
||||||
) : null}
|
|
||||||
{children}
|
{children}
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</MenuListItem>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import { ReactNode } from 'react'
|
||||||
|
|
||||||
|
const MenuListItem = ({ children }: { children: ReactNode }) => {
|
||||||
|
return (
|
||||||
|
<li className="list-none" role="none">
|
||||||
|
{children}
|
||||||
|
</li>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MenuListItem
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
import { FOCUSABLE_BUT_NOT_TABBABLE } from '@/Constants/Constants'
|
||||||
|
import { classNames } from '@standardnotes/snjs'
|
||||||
|
import { PlatformedKeyboardShortcut } from '@standardnotes/ui-services'
|
||||||
|
import { ComponentPropsWithoutRef, ForwardedRef, forwardRef, ReactNode } from 'react'
|
||||||
|
import { KeyboardShortcutIndicator } from '../KeyboardShortcutIndicator/KeyboardShortcutIndicator'
|
||||||
|
import RadioIndicator from '../Radio/RadioIndicator'
|
||||||
|
import MenuListItem from './MenuListItem'
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
checked: boolean
|
||||||
|
children: ReactNode
|
||||||
|
shortcut?: PlatformedKeyboardShortcut
|
||||||
|
} & ComponentPropsWithoutRef<'button'>
|
||||||
|
|
||||||
|
const MenuRadioButtonItem = forwardRef(
|
||||||
|
(
|
||||||
|
{ checked, disabled, tabIndex, children, shortcut, className, ...props }: Props,
|
||||||
|
ref: ForwardedRef<HTMLButtonElement>,
|
||||||
|
) => {
|
||||||
|
return (
|
||||||
|
<MenuListItem>
|
||||||
|
<button
|
||||||
|
ref={ref}
|
||||||
|
role="menuitemradio"
|
||||||
|
tabIndex={typeof tabIndex === 'number' ? tabIndex : FOCUSABLE_BUT_NOT_TABBABLE}
|
||||||
|
className={classNames(
|
||||||
|
'flex w-full cursor-pointer border-0 bg-transparent px-3 py-2 text-left md:py-1.5',
|
||||||
|
'text-mobile-menu-item text-text hover:bg-contrast hover:text-foreground',
|
||||||
|
'focus:bg-info-backdrop focus:shadow-none md:text-tablet-menu-item lg:text-menu-item',
|
||||||
|
className,
|
||||||
|
className?.includes('items-') ? '' : 'items-center',
|
||||||
|
)}
|
||||||
|
aria-checked={checked}
|
||||||
|
disabled={disabled}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
{shortcut && <KeyboardShortcutIndicator className="mr-2" shortcut={shortcut} />}
|
||||||
|
<RadioIndicator disabled={disabled} checked={checked} className="flex-shrink-0" />
|
||||||
|
{children}
|
||||||
|
</button>
|
||||||
|
</MenuListItem>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
export default MenuRadioButtonItem
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
import { FOCUSABLE_BUT_NOT_TABBABLE } from '@/Constants/Constants'
|
||||||
|
import { classNames } from '@standardnotes/snjs'
|
||||||
|
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']>
|
||||||
|
shortcut?: PlatformedKeyboardShortcut
|
||||||
|
} & Omit<ComponentPropsWithoutRef<'button'>, 'onChange'>
|
||||||
|
|
||||||
|
const MenuSwitchButtonItem = forwardRef(
|
||||||
|
(
|
||||||
|
{ checked, onChange, disabled, onBlur, tabIndex, children, shortcut, className, ...props }: Props,
|
||||||
|
ref: ForwardedRef<HTMLButtonElement>,
|
||||||
|
) => {
|
||||||
|
return (
|
||||||
|
<MenuListItem>
|
||||||
|
<button
|
||||||
|
disabled={disabled}
|
||||||
|
ref={ref}
|
||||||
|
className={classNames(
|
||||||
|
'flex w-full cursor-pointer border-0 bg-transparent px-3 py-2 md:py-1.5',
|
||||||
|
'text-left text-text hover:bg-contrast hover:text-foreground focus:bg-info-backdrop focus:shadow-none',
|
||||||
|
'text-mobile-menu-item md:text-tablet-menu-item lg:text-menu-item',
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
onClick={() => {
|
||||||
|
onChange(!checked)
|
||||||
|
}}
|
||||||
|
onBlur={onBlur}
|
||||||
|
tabIndex={typeof tabIndex === 'number' ? tabIndex : FOCUSABLE_BUT_NOT_TABBABLE}
|
||||||
|
role="menuitemcheckbox"
|
||||||
|
aria-checked={checked}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<span className="flex flex-grow items-center">{children}</span>
|
||||||
|
<div className="flex">
|
||||||
|
{shortcut && <KeyboardShortcutIndicator className="mr-2" shortcut={shortcut} />}
|
||||||
|
<Switch disabled={disabled} className="px-0" checked={checked} />
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
</MenuListItem>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
export default MenuSwitchButtonItem
|
||||||
@@ -1,12 +1,13 @@
|
|||||||
import { observer } from 'mobx-react-lite'
|
import { observer } from 'mobx-react-lite'
|
||||||
import NotesOptions from '@/Components/NotesOptions/NotesOptions'
|
import NotesOptions from '@/Components/NotesOptions/NotesOptions'
|
||||||
import { useCallback, useRef, useState } from 'react'
|
import { useCallback, useState } from 'react'
|
||||||
import { WebApplication } from '@/Application/Application'
|
import { WebApplication } from '@/Application/Application'
|
||||||
import { NotesController } from '@/Controllers/NotesController/NotesController'
|
import { NotesController } from '@/Controllers/NotesController/NotesController'
|
||||||
import { NavigationController } from '@/Controllers/Navigation/NavigationController'
|
import { NavigationController } from '@/Controllers/Navigation/NavigationController'
|
||||||
import { HistoryModalController } from '@/Controllers/NoteHistory/HistoryModalController'
|
import { HistoryModalController } from '@/Controllers/NoteHistory/HistoryModalController'
|
||||||
import Popover from '../Popover/Popover'
|
import Popover from '../Popover/Popover'
|
||||||
import { LinkingController } from '@/Controllers/LinkingController'
|
import { LinkingController } from '@/Controllers/LinkingController'
|
||||||
|
import Menu from '../Menu/Menu'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
application: WebApplication
|
application: WebApplication
|
||||||
@@ -25,8 +26,6 @@ const NotesContextMenu = ({
|
|||||||
}: Props) => {
|
}: Props) => {
|
||||||
const { contextMenuOpen, contextMenuClickLocation, setContextMenuOpen } = notesController
|
const { contextMenuOpen, contextMenuClickLocation, setContextMenuOpen } = notesController
|
||||||
|
|
||||||
const contextMenuRef = useRef<HTMLDivElement>(null)
|
|
||||||
|
|
||||||
const closeMenu = () => setContextMenuOpen(!contextMenuOpen)
|
const closeMenu = () => setContextMenuOpen(!contextMenuOpen)
|
||||||
|
|
||||||
const [disableClickOutside, setDisableClickOutside] = useState(false)
|
const [disableClickOutside, setDisableClickOutside] = useState(false)
|
||||||
@@ -46,7 +45,7 @@ const NotesContextMenu = ({
|
|||||||
open={contextMenuOpen}
|
open={contextMenuOpen}
|
||||||
togglePopover={closeMenu}
|
togglePopover={closeMenu}
|
||||||
>
|
>
|
||||||
<div className="select-none" ref={contextMenuRef}>
|
<Menu className="select-none" a11yLabel="Note context menu" isOpen={contextMenuOpen}>
|
||||||
<NotesOptions
|
<NotesOptions
|
||||||
application={application}
|
application={application}
|
||||||
navigationController={navigationController}
|
navigationController={navigationController}
|
||||||
@@ -56,7 +55,7 @@ const NotesContextMenu = ({
|
|||||||
requestDisableClickOutside={handleDisableClickOutsideRequest}
|
requestDisableClickOutside={handleDisableClickOutsideRequest}
|
||||||
closeMenu={closeMenu}
|
closeMenu={closeMenu}
|
||||||
/>
|
/>
|
||||||
</div>
|
</Menu>
|
||||||
</Popover>
|
</Popover>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,20 +8,15 @@ import Popover from '../Popover/Popover'
|
|||||||
import { IconType } from '@standardnotes/snjs'
|
import { IconType } from '@standardnotes/snjs'
|
||||||
import { getTitleForLinkedTag } from '@/Utils/Items/Display/getTitleForLinkedTag'
|
import { getTitleForLinkedTag } from '@/Utils/Items/Display/getTitleForLinkedTag'
|
||||||
import { useApplication } from '../ApplicationView/ApplicationProvider'
|
import { useApplication } from '../ApplicationView/ApplicationProvider'
|
||||||
|
import MenuItem from '../Menu/MenuItem'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
navigationController: NavigationController
|
navigationController: NavigationController
|
||||||
notesController: NotesController
|
notesController: NotesController
|
||||||
className: string
|
|
||||||
iconClassName: string
|
iconClassName: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const AddTagOption: FunctionComponent<Props> = ({
|
const AddTagOption: FunctionComponent<Props> = ({ navigationController, notesController, iconClassName }) => {
|
||||||
navigationController,
|
|
||||||
notesController,
|
|
||||||
className,
|
|
||||||
iconClassName,
|
|
||||||
}) => {
|
|
||||||
const application = useApplication()
|
const application = useApplication()
|
||||||
const menuContainerRef = useRef<HTMLDivElement>(null)
|
const menuContainerRef = useRef<HTMLDivElement>(null)
|
||||||
const buttonRef = useRef<HTMLButtonElement>(null)
|
const buttonRef = useRef<HTMLButtonElement>(null)
|
||||||
@@ -34,7 +29,8 @@ const AddTagOption: FunctionComponent<Props> = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={menuContainerRef}>
|
<div ref={menuContainerRef}>
|
||||||
<button
|
<MenuItem
|
||||||
|
className="justify-between"
|
||||||
onClick={toggleMenu}
|
onClick={toggleMenu}
|
||||||
onKeyDown={(event) => {
|
onKeyDown={(event) => {
|
||||||
if (event.key === KeyboardKey.Escape) {
|
if (event.key === KeyboardKey.Escape) {
|
||||||
@@ -42,14 +38,13 @@ const AddTagOption: FunctionComponent<Props> = ({
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
ref={buttonRef}
|
ref={buttonRef}
|
||||||
className={className}
|
|
||||||
>
|
>
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<Icon type="hashtag" className={`${iconClassName} mr-2 text-neutral`} />
|
<Icon type="hashtag" className={`${iconClassName} mr-2 text-neutral`} />
|
||||||
Add tag
|
Add tag
|
||||||
</div>
|
</div>
|
||||||
<Icon type="chevron-right" className="text-neutral" />
|
<Icon type="chevron-right" className="text-neutral" />
|
||||||
</button>
|
</MenuItem>
|
||||||
<Popover
|
<Popover
|
||||||
togglePopover={toggleMenu}
|
togglePopover={toggleMenu}
|
||||||
anchorElement={buttonRef.current}
|
anchorElement={buttonRef.current}
|
||||||
@@ -59,9 +54,8 @@ const AddTagOption: FunctionComponent<Props> = ({
|
|||||||
className="py-2"
|
className="py-2"
|
||||||
>
|
>
|
||||||
{navigationController.tags.map((tag) => (
|
{navigationController.tags.map((tag) => (
|
||||||
<button
|
<MenuItem
|
||||||
key={tag.uuid}
|
key={tag.uuid}
|
||||||
className={`max-w-80 ${className.replace('justify-between', 'justify-start')}`}
|
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
notesController.isTagInSelectedNotes(tag)
|
notesController.isTagInSelectedNotes(tag)
|
||||||
? notesController.removeTagFromSelectedNotes(tag).catch(console.error)
|
? notesController.removeTagFromSelectedNotes(tag).catch(console.error)
|
||||||
@@ -81,7 +75,7 @@ const AddTagOption: FunctionComponent<Props> = ({
|
|||||||
>
|
>
|
||||||
{getTitleForLinkedTag(tag, application)?.longTitle}
|
{getTitleForLinkedTag(tag, application)?.longTitle}
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</MenuItem>
|
||||||
))}
|
))}
|
||||||
</Popover>
|
</Popover>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -6,20 +6,15 @@ import Icon from '@/Components/Icon/Icon'
|
|||||||
import ChangeEditorMenu from '@/Components/ChangeEditor/ChangeEditorMenu'
|
import ChangeEditorMenu from '@/Components/ChangeEditor/ChangeEditorMenu'
|
||||||
import Popover from '../Popover/Popover'
|
import Popover from '../Popover/Popover'
|
||||||
import { KeyboardShortcutIndicator } from '../KeyboardShortcutIndicator/KeyboardShortcutIndicator'
|
import { KeyboardShortcutIndicator } from '../KeyboardShortcutIndicator/KeyboardShortcutIndicator'
|
||||||
|
import MenuItem from '../Menu/MenuItem'
|
||||||
|
|
||||||
type ChangeEditorOptionProps = {
|
type ChangeEditorOptionProps = {
|
||||||
application: WebApplication
|
application: WebApplication
|
||||||
note: SNNote
|
note: SNNote
|
||||||
className: string
|
|
||||||
iconClassName: string
|
iconClassName: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const ChangeEditorOption: FunctionComponent<ChangeEditorOptionProps> = ({
|
const ChangeEditorOption: FunctionComponent<ChangeEditorOptionProps> = ({ application, note, iconClassName }) => {
|
||||||
application,
|
|
||||||
note,
|
|
||||||
className,
|
|
||||||
iconClassName,
|
|
||||||
}) => {
|
|
||||||
const [isOpen, setIsOpen] = useState(false)
|
const [isOpen, setIsOpen] = useState(false)
|
||||||
const menuContainerRef = useRef<HTMLDivElement>(null)
|
const menuContainerRef = useRef<HTMLDivElement>(null)
|
||||||
const buttonRef = useRef<HTMLButtonElement>(null)
|
const buttonRef = useRef<HTMLButtonElement>(null)
|
||||||
@@ -35,7 +30,8 @@ const ChangeEditorOption: FunctionComponent<ChangeEditorOptionProps> = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={menuContainerRef}>
|
<div ref={menuContainerRef}>
|
||||||
<button
|
<MenuItem
|
||||||
|
className="justify-between"
|
||||||
onClick={toggleMenu}
|
onClick={toggleMenu}
|
||||||
onKeyDown={(event) => {
|
onKeyDown={(event) => {
|
||||||
if (event.key === KeyboardKey.Escape) {
|
if (event.key === KeyboardKey.Escape) {
|
||||||
@@ -43,7 +39,6 @@ const ChangeEditorOption: FunctionComponent<ChangeEditorOptionProps> = ({
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
ref={buttonRef}
|
ref={buttonRef}
|
||||||
className={className}
|
|
||||||
>
|
>
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<Icon type="dashboard" className={`${iconClassName} mr-2 text-neutral`} />
|
<Icon type="dashboard" className={`${iconClassName} mr-2 text-neutral`} />
|
||||||
@@ -53,7 +48,7 @@ const ChangeEditorOption: FunctionComponent<ChangeEditorOptionProps> = ({
|
|||||||
{shortcut && <KeyboardShortcutIndicator className={'mr-2'} shortcut={shortcut} />}
|
{shortcut && <KeyboardShortcutIndicator className={'mr-2'} shortcut={shortcut} />}
|
||||||
<Icon type="chevron-right" className="text-neutral" />
|
<Icon type="chevron-right" className="text-neutral" />
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</MenuItem>
|
||||||
<Popover
|
<Popover
|
||||||
align="start"
|
align="start"
|
||||||
anchorElement={buttonRef.current}
|
anchorElement={buttonRef.current}
|
||||||
|
|||||||
@@ -1,13 +1,3 @@
|
|||||||
import { MenuItemIconSize } from '@/Constants/TailwindClassNames'
|
import { MenuItemIconSize } from '@/Constants/TailwindClassNames'
|
||||||
import { classNames } from '@standardnotes/utils'
|
|
||||||
|
|
||||||
export const menuItemTextClassNames = 'text-mobile-menu-item md:text-tablet-menu-item lg:text-menu-item'
|
|
||||||
|
|
||||||
export const menuItemClassNames = classNames(
|
|
||||||
menuItemTextClassNames,
|
|
||||||
'flex w-full cursor-pointer items-center border-0 bg-transparent px-3 py-1.5 text-left text-text hover:bg-contrast hover:text-foreground focus:bg-info-backdrop focus:shadow-none',
|
|
||||||
)
|
|
||||||
|
|
||||||
export const menuItemSwitchClassNames = classNames(menuItemTextClassNames, menuItemClassNames, 'justify-between')
|
|
||||||
|
|
||||||
export const iconClass = `text-neutral mr-2 ${MenuItemIconSize}`
|
export const iconClass = `text-neutral mr-2 ${MenuItemIconSize}`
|
||||||
|
|||||||
@@ -1,19 +1,13 @@
|
|||||||
import Icon from '@/Components/Icon/Icon'
|
import Icon from '@/Components/Icon/Icon'
|
||||||
import { classNames } from '@standardnotes/utils'
|
import MenuItem from '../Menu/MenuItem'
|
||||||
|
|
||||||
type DeletePermanentlyButtonProps = {
|
type DeletePermanentlyButtonProps = {
|
||||||
onClick: () => void
|
onClick: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DeletePermanentlyButton = ({ onClick }: DeletePermanentlyButtonProps) => (
|
export const DeletePermanentlyButton = ({ onClick }: DeletePermanentlyButtonProps) => (
|
||||||
<button
|
<MenuItem onClick={onClick}>
|
||||||
className={classNames(
|
|
||||||
'flex w-full cursor-pointer items-center border-0 bg-transparent px-3 py-1.5 text-left text-mobile-menu-item',
|
|
||||||
'text-text hover:bg-contrast hover:text-foreground focus:bg-info-backdrop focus:shadow-none md:text-menu-item',
|
|
||||||
)}
|
|
||||||
onClick={onClick}
|
|
||||||
>
|
|
||||||
<Icon type="close" className="mr-2 text-danger" />
|
<Icon type="close" className="mr-2 text-danger" />
|
||||||
<span className="text-danger">Delete permanently</span>
|
<span className="text-danger">Delete permanently</span>
|
||||||
</button>
|
</MenuItem>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,15 +5,15 @@ import Icon from '@/Components/Icon/Icon'
|
|||||||
import ListedActionsMenu from './ListedActionsMenu'
|
import ListedActionsMenu from './ListedActionsMenu'
|
||||||
import { KeyboardKey } from '@standardnotes/ui-services'
|
import { KeyboardKey } from '@standardnotes/ui-services'
|
||||||
import Popover from '../../Popover/Popover'
|
import Popover from '../../Popover/Popover'
|
||||||
|
import MenuItem from '@/Components/Menu/MenuItem'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
application: WebApplication
|
application: WebApplication
|
||||||
note: SNNote
|
note: SNNote
|
||||||
className: string
|
|
||||||
iconClassName: string
|
iconClassName: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const ListedActionsOption: FunctionComponent<Props> = ({ application, note, className, iconClassName }) => {
|
const ListedActionsOption: FunctionComponent<Props> = ({ application, note, iconClassName }) => {
|
||||||
const menuContainerRef = useRef<HTMLDivElement>(null)
|
const menuContainerRef = useRef<HTMLDivElement>(null)
|
||||||
const buttonRef = useRef<HTMLButtonElement>(null)
|
const buttonRef = useRef<HTMLButtonElement>(null)
|
||||||
|
|
||||||
@@ -31,7 +31,8 @@ const ListedActionsOption: FunctionComponent<Props> = ({ application, note, clas
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={menuContainerRef}>
|
<div ref={menuContainerRef}>
|
||||||
<button
|
<MenuItem
|
||||||
|
className="justify-between"
|
||||||
onClick={toggleMenu}
|
onClick={toggleMenu}
|
||||||
onKeyDown={(event) => {
|
onKeyDown={(event) => {
|
||||||
if (event.key === KeyboardKey.Escape) {
|
if (event.key === KeyboardKey.Escape) {
|
||||||
@@ -39,14 +40,13 @@ const ListedActionsOption: FunctionComponent<Props> = ({ application, note, clas
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
ref={buttonRef}
|
ref={buttonRef}
|
||||||
className={className}
|
|
||||||
>
|
>
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<Icon type="listed" className={`mr-2 text-neutral ${iconClassName}`} />
|
<Icon type="listed" className={`mr-2 text-neutral ${iconClassName}`} />
|
||||||
Listed actions
|
Listed actions
|
||||||
</div>
|
</div>
|
||||||
<Icon type="chevron-right" className="text-neutral" />
|
<Icon type="chevron-right" className="text-neutral" />
|
||||||
</button>
|
</MenuItem>
|
||||||
<Popover
|
<Popover
|
||||||
togglePopover={toggleMenu}
|
togglePopover={toggleMenu}
|
||||||
anchorElement={buttonRef.current}
|
anchorElement={buttonRef.current}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import Icon from '@/Components/Icon/Icon'
|
import Icon from '@/Components/Icon/Icon'
|
||||||
import Switch from '@/Components/Switch/Switch'
|
|
||||||
import { observer } from 'mobx-react-lite'
|
import { observer } from 'mobx-react-lite'
|
||||||
import { useState, useEffect, useMemo, useCallback } from 'react'
|
import { useState, useEffect, useMemo, useCallback } from 'react'
|
||||||
import { NoteType, Platform, SNNote } from '@standardnotes/snjs'
|
import { NoteType, Platform, SNNote } from '@standardnotes/snjs'
|
||||||
@@ -22,7 +21,6 @@ import { getNoteBlob, getNoteFileName } from '@/Utils/NoteExportUtils'
|
|||||||
import { shareSelectedNotes } from '@/NativeMobileWeb/ShareSelectedNotes'
|
import { shareSelectedNotes } from '@/NativeMobileWeb/ShareSelectedNotes'
|
||||||
import { downloadSelectedNotesOnAndroid } from '@/NativeMobileWeb/DownloadSelectedNotesOnAndroid'
|
import { downloadSelectedNotesOnAndroid } from '@/NativeMobileWeb/DownloadSelectedNotesOnAndroid'
|
||||||
import ProtectedUnauthorizedLabel from '../ProtectedItemOverlay/ProtectedUnauthorizedLabel'
|
import ProtectedUnauthorizedLabel from '../ProtectedItemOverlay/ProtectedUnauthorizedLabel'
|
||||||
import { classNames } from '@standardnotes/utils'
|
|
||||||
import { MenuItemIconSize } from '@/Constants/TailwindClassNames'
|
import { MenuItemIconSize } from '@/Constants/TailwindClassNames'
|
||||||
import { KeyboardShortcutIndicator } from '../KeyboardShortcutIndicator/KeyboardShortcutIndicator'
|
import { KeyboardShortcutIndicator } from '../KeyboardShortcutIndicator/KeyboardShortcutIndicator'
|
||||||
import { NoteAttributes } from './NoteAttributes'
|
import { NoteAttributes } from './NoteAttributes'
|
||||||
@@ -30,8 +28,10 @@ import { SpellcheckOptions } from './SpellcheckOptions'
|
|||||||
import { NoteSizeWarning } from './NoteSizeWarning'
|
import { NoteSizeWarning } from './NoteSizeWarning'
|
||||||
import { DeletePermanentlyButton } from './DeletePermanentlyButton'
|
import { DeletePermanentlyButton } from './DeletePermanentlyButton'
|
||||||
import { useCommandService } from '../ApplicationView/CommandProvider'
|
import { useCommandService } from '../ApplicationView/CommandProvider'
|
||||||
import { menuItemClassNames, menuItemSwitchClassNames, iconClass } from './ClassNames'
|
import { iconClass } from './ClassNames'
|
||||||
import SuperNoteOptions from './SuperNoteOptions'
|
import SuperNoteOptions from './SuperNoteOptions'
|
||||||
|
import MenuSwitchButtonItem from '../Menu/MenuSwitchButtonItem'
|
||||||
|
import MenuItem from '../Menu/MenuItem'
|
||||||
|
|
||||||
const iconSize = MenuItemIconSize
|
const iconSize = MenuItemIconSize
|
||||||
const iconClassDanger = `text-danger mr-2 ${iconSize}`
|
const iconClassDanger = `text-danger mr-2 ${iconSize}`
|
||||||
@@ -160,132 +160,94 @@ const NotesOptions = ({
|
|||||||
return <ProtectedUnauthorizedLabel />
|
return <ProtectedUnauthorizedLabel />
|
||||||
}
|
}
|
||||||
|
|
||||||
const firstItemClass = 'pt-4'
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{notes.length === 1 && (
|
{notes.length === 1 && (
|
||||||
<>
|
<>
|
||||||
<button className={classNames(menuItemClassNames, firstItemClass)} onClick={openRevisionHistoryModal}>
|
<MenuItem onClick={openRevisionHistoryModal}>
|
||||||
<div className="flex w-full items-center justify-between">
|
<Icon type="history" className={iconClass} />
|
||||||
<span className="flex">
|
Note history
|
||||||
<Icon type="history" className={iconClass} />
|
{historyShortcut && <KeyboardShortcutIndicator className="ml-auto" shortcut={historyShortcut} />}
|
||||||
Note history
|
</MenuItem>
|
||||||
</span>
|
|
||||||
{historyShortcut && <KeyboardShortcutIndicator className={''} shortcut={historyShortcut} />}
|
|
||||||
</div>
|
|
||||||
</button>
|
|
||||||
<HorizontalSeparator classes="my-2" />
|
<HorizontalSeparator classes="my-2" />
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
<button
|
<MenuSwitchButtonItem
|
||||||
className={menuItemSwitchClassNames}
|
checked={locked}
|
||||||
onClick={() => {
|
onChange={(locked) => {
|
||||||
notesController.setLockSelectedNotes(!locked)
|
notesController.setLockSelectedNotes(locked)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span className="flex items-center">
|
<Icon type="pencil-off" className={iconClass} />
|
||||||
<Icon type="pencil-off" className={iconClass} />
|
Prevent editing
|
||||||
Prevent editing
|
</MenuSwitchButtonItem>
|
||||||
</span>
|
<MenuSwitchButtonItem
|
||||||
<Switch className="px-0" checked={locked} />
|
checked={!hidePreviews}
|
||||||
</button>
|
onChange={(hidePreviews) => {
|
||||||
<button
|
|
||||||
className={menuItemSwitchClassNames}
|
|
||||||
onClick={() => {
|
|
||||||
notesController.setHideSelectedNotePreviews(!hidePreviews)
|
notesController.setHideSelectedNotePreviews(!hidePreviews)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span className="flex items-center">
|
<Icon type="rich-text" className={iconClass} />
|
||||||
<Icon type="rich-text" className={iconClass} />
|
Show preview
|
||||||
Show preview
|
</MenuSwitchButtonItem>
|
||||||
</span>
|
<MenuSwitchButtonItem
|
||||||
<Switch className="px-0" checked={!hidePreviews} />
|
checked={protect}
|
||||||
</button>
|
onChange={(protect) => {
|
||||||
<button
|
notesController.setProtectSelectedNotes(protect).catch(console.error)
|
||||||
className={menuItemSwitchClassNames}
|
|
||||||
onClick={() => {
|
|
||||||
notesController.setProtectSelectedNotes(!protect).catch(console.error)
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span className="flex items-center">
|
<Icon type="lock" className={iconClass} />
|
||||||
<Icon type="lock" className={iconClass} />
|
Password protect
|
||||||
Password protect
|
</MenuSwitchButtonItem>
|
||||||
</span>
|
|
||||||
<Switch className="px-0" checked={protect} />
|
|
||||||
</button>
|
|
||||||
{notes.length === 1 && (
|
{notes.length === 1 && (
|
||||||
<>
|
<>
|
||||||
<HorizontalSeparator classes="my-2" />
|
<HorizontalSeparator classes="my-2" />
|
||||||
<ChangeEditorOption
|
<ChangeEditorOption iconClassName={iconClass} application={application} note={notes[0]} />
|
||||||
iconClassName={iconClass}
|
|
||||||
className={menuItemSwitchClassNames}
|
|
||||||
application={application}
|
|
||||||
note={notes[0]}
|
|
||||||
/>
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
<HorizontalSeparator classes="my-2" />
|
<HorizontalSeparator classes="my-2" />
|
||||||
{navigationController.tagsCount > 0 && (
|
{navigationController.tagsCount > 0 && (
|
||||||
<AddTagOption
|
<AddTagOption
|
||||||
iconClassName={iconClass}
|
iconClassName={iconClass}
|
||||||
className={menuItemSwitchClassNames}
|
|
||||||
navigationController={navigationController}
|
navigationController={navigationController}
|
||||||
notesController={notesController}
|
notesController={notesController}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
<MenuItem
|
||||||
<button
|
|
||||||
className={menuItemClassNames}
|
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
notesController.setStarSelectedNotes(!starred)
|
notesController.setStarSelectedNotes(!starred)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className="flex w-full items-center justify-between">
|
<Icon type="star" className={iconClass} />
|
||||||
<span className="flex">
|
{starred ? 'Unstar' : 'Star'}
|
||||||
<Icon type="star" className={iconClass} />
|
{starShortcut && <KeyboardShortcutIndicator className="ml-auto" shortcut={starShortcut} />}
|
||||||
{starred ? 'Unstar' : 'Star'}
|
</MenuItem>
|
||||||
</span>
|
|
||||||
{starShortcut && <KeyboardShortcutIndicator className={''} shortcut={starShortcut} />}
|
|
||||||
</div>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
{unpinned && (
|
{unpinned && (
|
||||||
<button
|
<MenuItem
|
||||||
className={menuItemClassNames}
|
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
notesController.setPinSelectedNotes(true)
|
notesController.setPinSelectedNotes(true)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className="flex w-full items-center justify-between">
|
<Icon type="pin" className={iconClass} />
|
||||||
<span className="flex">
|
Pin to top
|
||||||
<Icon type="pin" className={iconClass} />
|
{pinShortcut && <KeyboardShortcutIndicator className="ml-auto" shortcut={pinShortcut} />}
|
||||||
Pin to top
|
</MenuItem>
|
||||||
</span>
|
|
||||||
{pinShortcut && <KeyboardShortcutIndicator className={''} shortcut={pinShortcut} />}
|
|
||||||
</div>
|
|
||||||
</button>
|
|
||||||
)}
|
)}
|
||||||
{pinned && (
|
{pinned && (
|
||||||
<button
|
<MenuItem
|
||||||
className={menuItemClassNames}
|
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
notesController.setPinSelectedNotes(false)
|
notesController.setPinSelectedNotes(false)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className="flex w-full items-center justify-between">
|
<Icon type="unpin" className={iconClass} />
|
||||||
<span className="flex">
|
Unpin
|
||||||
<Icon type="unpin" className={iconClass} />
|
{pinShortcut && <KeyboardShortcutIndicator className="ml-auto" shortcut={pinShortcut} />}
|
||||||
Unpin
|
</MenuItem>
|
||||||
</span>
|
|
||||||
{pinShortcut && <KeyboardShortcutIndicator className={''} shortcut={pinShortcut} />}
|
|
||||||
</div>
|
|
||||||
</button>
|
|
||||||
)}
|
)}
|
||||||
{notes[0].noteType !== NoteType.Super && (
|
{notes[0].noteType !== NoteType.Super && (
|
||||||
<>
|
<>
|
||||||
<button
|
<MenuItem
|
||||||
className={menuItemClassNames}
|
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
application.isNativeMobileWeb()
|
application.isNativeMobileWeb()
|
||||||
? void shareSelectedNotes(application, notes)
|
? void shareSelectedNotes(application, notes)
|
||||||
@@ -294,22 +256,21 @@ const NotesOptions = ({
|
|||||||
>
|
>
|
||||||
<Icon type={application.platform === Platform.Android ? 'share' : 'download'} className={iconClass} />
|
<Icon type={application.platform === Platform.Android ? 'share' : 'download'} className={iconClass} />
|
||||||
{application.platform === Platform.Android ? 'Share' : 'Export'}
|
{application.platform === Platform.Android ? 'Share' : 'Export'}
|
||||||
</button>
|
</MenuItem>
|
||||||
{application.platform === Platform.Android && (
|
{application.platform === Platform.Android && (
|
||||||
<button className={menuItemClassNames} onClick={() => downloadSelectedNotesOnAndroid(application, notes)}>
|
<MenuItem onClick={() => downloadSelectedNotesOnAndroid(application, notes)}>
|
||||||
<Icon type="download" className={iconClass} />
|
<Icon type="download" className={iconClass} />
|
||||||
Export
|
Export
|
||||||
</button>
|
</MenuItem>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
<button className={menuItemClassNames} onClick={duplicateSelectedItems}>
|
<MenuItem onClick={duplicateSelectedItems}>
|
||||||
<Icon type="copy" className={iconClass} />
|
<Icon type="copy" className={iconClass} />
|
||||||
Duplicate
|
Duplicate
|
||||||
</button>
|
</MenuItem>
|
||||||
{unarchived && (
|
{unarchived && (
|
||||||
<button
|
<MenuItem
|
||||||
className={menuItemClassNames}
|
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
await notesController.setArchiveSelectedNotes(true).catch(console.error)
|
await notesController.setArchiveSelectedNotes(true).catch(console.error)
|
||||||
closeMenuAndToggleNotesList()
|
closeMenuAndToggleNotesList()
|
||||||
@@ -317,11 +278,10 @@ const NotesOptions = ({
|
|||||||
>
|
>
|
||||||
<Icon type="archive" className={iconClassWarning} />
|
<Icon type="archive" className={iconClassWarning} />
|
||||||
<span className="text-warning">Archive</span>
|
<span className="text-warning">Archive</span>
|
||||||
</button>
|
</MenuItem>
|
||||||
)}
|
)}
|
||||||
{archived && (
|
{archived && (
|
||||||
<button
|
<MenuItem
|
||||||
className={menuItemClassNames}
|
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
await notesController.setArchiveSelectedNotes(false).catch(console.error)
|
await notesController.setArchiveSelectedNotes(false).catch(console.error)
|
||||||
closeMenuAndToggleNotesList()
|
closeMenuAndToggleNotesList()
|
||||||
@@ -329,7 +289,7 @@ const NotesOptions = ({
|
|||||||
>
|
>
|
||||||
<Icon type="unarchive" className={iconClassWarning} />
|
<Icon type="unarchive" className={iconClassWarning} />
|
||||||
<span className="text-warning">Unarchive</span>
|
<span className="text-warning">Unarchive</span>
|
||||||
</button>
|
</MenuItem>
|
||||||
)}
|
)}
|
||||||
{notTrashed &&
|
{notTrashed &&
|
||||||
(altKeyDown ? (
|
(altKeyDown ? (
|
||||||
@@ -340,8 +300,7 @@ const NotesOptions = ({
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<button
|
<MenuItem
|
||||||
className={menuItemClassNames}
|
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
await notesController.setTrashSelectedNotes(true)
|
await notesController.setTrashSelectedNotes(true)
|
||||||
closeMenuAndToggleNotesList()
|
closeMenuAndToggleNotesList()
|
||||||
@@ -349,12 +308,11 @@ const NotesOptions = ({
|
|||||||
>
|
>
|
||||||
<Icon type="trash" className={iconClassDanger} />
|
<Icon type="trash" className={iconClassDanger} />
|
||||||
<span className="text-danger">Move to trash</span>
|
<span className="text-danger">Move to trash</span>
|
||||||
</button>
|
</MenuItem>
|
||||||
))}
|
))}
|
||||||
{trashed && (
|
{trashed && (
|
||||||
<>
|
<>
|
||||||
<button
|
<MenuItem
|
||||||
className={menuItemClassNames}
|
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
await notesController.setTrashSelectedNotes(false)
|
await notesController.setTrashSelectedNotes(false)
|
||||||
closeMenuAndToggleNotesList()
|
closeMenuAndToggleNotesList()
|
||||||
@@ -362,15 +320,14 @@ const NotesOptions = ({
|
|||||||
>
|
>
|
||||||
<Icon type="restore" className={iconClassSuccess} />
|
<Icon type="restore" className={iconClassSuccess} />
|
||||||
<span className="text-success">Restore</span>
|
<span className="text-success">Restore</span>
|
||||||
</button>
|
</MenuItem>
|
||||||
<DeletePermanentlyButton
|
<DeletePermanentlyButton
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
await notesController.deleteNotesPermanently()
|
await notesController.deleteNotesPermanently()
|
||||||
closeMenuAndToggleNotesList()
|
closeMenuAndToggleNotesList()
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<button
|
<MenuItem
|
||||||
className={menuItemClassNames}
|
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
await notesController.emptyTrash()
|
await notesController.emptyTrash()
|
||||||
closeMenuAndToggleNotesList()
|
closeMenuAndToggleNotesList()
|
||||||
@@ -383,7 +340,7 @@ const NotesOptions = ({
|
|||||||
<div className="text-xs">{notesController.trashedNotesCount} notes in Trash</div>
|
<div className="text-xs">{notesController.trashedNotesCount} notes in Trash</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</MenuItem>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@@ -398,21 +355,11 @@ const NotesOptions = ({
|
|||||||
)}
|
)}
|
||||||
<HorizontalSeparator classes="my-2" />
|
<HorizontalSeparator classes="my-2" />
|
||||||
|
|
||||||
<ListedActionsOption
|
<ListedActionsOption iconClassName={iconClass} application={application} note={notes[0]} />
|
||||||
iconClassName={iconClass}
|
|
||||||
className={menuItemSwitchClassNames}
|
|
||||||
application={application}
|
|
||||||
note={notes[0]}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<HorizontalSeparator classes="my-2" />
|
<HorizontalSeparator classes="my-2" />
|
||||||
|
|
||||||
<SpellcheckOptions
|
<SpellcheckOptions editorForNote={editorForNote} notesController={notesController} note={notes[0]} />
|
||||||
className={menuItemSwitchClassNames}
|
|
||||||
editorForNote={editorForNote}
|
|
||||||
notesController={notesController}
|
|
||||||
note={notes[0]}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<HorizontalSeparator classes="my-2" />
|
<HorizontalSeparator classes="my-2" />
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { HistoryModalController } from '@/Controllers/NoteHistory/HistoryModalCo
|
|||||||
import Popover from '../Popover/Popover'
|
import Popover from '../Popover/Popover'
|
||||||
import { LinkingController } from '@/Controllers/LinkingController'
|
import { LinkingController } from '@/Controllers/LinkingController'
|
||||||
import RoundIconButton from '../Button/RoundIconButton'
|
import RoundIconButton from '../Button/RoundIconButton'
|
||||||
|
import Menu from '../Menu/Menu'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
application: WebApplication
|
application: WebApplication
|
||||||
@@ -50,17 +51,19 @@ const NotesOptionsPanel = ({
|
|||||||
togglePopover={toggleMenu}
|
togglePopover={toggleMenu}
|
||||||
anchorElement={buttonRef.current}
|
anchorElement={buttonRef.current}
|
||||||
open={isOpen}
|
open={isOpen}
|
||||||
className="select-none"
|
className="select-none md:pt-2"
|
||||||
>
|
>
|
||||||
<NotesOptions
|
<Menu a11yLabel="Note options menu" isOpen={isOpen}>
|
||||||
application={application}
|
<NotesOptions
|
||||||
navigationController={navigationController}
|
application={application}
|
||||||
notesController={notesController}
|
navigationController={navigationController}
|
||||||
linkingController={linkingController}
|
notesController={notesController}
|
||||||
historyModalController={historyModalController}
|
linkingController={linkingController}
|
||||||
requestDisableClickOutside={handleDisableClickOutsideRequest}
|
historyModalController={historyModalController}
|
||||||
closeMenu={toggleMenu}
|
requestDisableClickOutside={handleDisableClickOutsideRequest}
|
||||||
/>
|
closeMenu={toggleMenu}
|
||||||
|
/>
|
||||||
|
</Menu>
|
||||||
</Popover>
|
</Popover>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,16 +1,15 @@
|
|||||||
import Icon from '@/Components/Icon/Icon'
|
import Icon from '@/Components/Icon/Icon'
|
||||||
import Switch from '@/Components/Switch/Switch'
|
|
||||||
import { FunctionComponent } from 'react'
|
import { FunctionComponent } from 'react'
|
||||||
import { SNComponent, SNNote } from '@standardnotes/snjs'
|
import { SNComponent, SNNote } from '@standardnotes/snjs'
|
||||||
import { NotesController } from '@/Controllers/NotesController/NotesController'
|
import { NotesController } from '@/Controllers/NotesController/NotesController'
|
||||||
import { iconClass } from './ClassNames'
|
import { iconClass } from './ClassNames'
|
||||||
|
import MenuSwitchButtonItem from '../Menu/MenuSwitchButtonItem'
|
||||||
|
|
||||||
export const SpellcheckOptions: FunctionComponent<{
|
export const SpellcheckOptions: FunctionComponent<{
|
||||||
editorForNote: SNComponent | undefined
|
editorForNote: SNComponent | undefined
|
||||||
notesController: NotesController
|
notesController: NotesController
|
||||||
note: SNNote
|
note: SNNote
|
||||||
className: string
|
}> = ({ editorForNote, notesController, note }) => {
|
||||||
}> = ({ editorForNote, notesController, note, className }) => {
|
|
||||||
const spellcheckControllable = Boolean(!editorForNote || editorForNote.package_info.spellcheckControl)
|
const spellcheckControllable = Boolean(!editorForNote || editorForNote.package_info.spellcheckControl)
|
||||||
const noteSpellcheck = !spellcheckControllable
|
const noteSpellcheck = !spellcheckControllable
|
||||||
? true
|
? true
|
||||||
@@ -20,19 +19,16 @@ export const SpellcheckOptions: FunctionComponent<{
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<button
|
<MenuSwitchButtonItem
|
||||||
className={className}
|
checked={Boolean(noteSpellcheck)}
|
||||||
onClick={() => {
|
onChange={() => {
|
||||||
notesController.toggleGlobalSpellcheckForNote(note).catch(console.error)
|
notesController.toggleGlobalSpellcheckForNote(note).catch(console.error)
|
||||||
}}
|
}}
|
||||||
disabled={!spellcheckControllable}
|
disabled={!spellcheckControllable}
|
||||||
>
|
>
|
||||||
<span className="flex items-center">
|
<Icon type="notes" className={iconClass} />
|
||||||
<Icon type="notes" className={iconClass} />
|
Spellcheck
|
||||||
Spellcheck
|
</MenuSwitchButtonItem>
|
||||||
</span>
|
|
||||||
<Switch className="px-0" checked={noteSpellcheck} disabled={!spellcheckControllable} />
|
|
||||||
</button>
|
|
||||||
{!spellcheckControllable && (
|
{!spellcheckControllable && (
|
||||||
<p className="px-3 py-1.5 text-xs">Spellcheck cannot be controlled for this editor.</p>
|
<p className="px-3 py-1.5 text-xs">Spellcheck cannot be controlled for this editor.</p>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import Menu from '../Menu/Menu'
|
|||||||
import MenuItem from '../Menu/MenuItem'
|
import MenuItem from '../Menu/MenuItem'
|
||||||
import Popover from '../Popover/Popover'
|
import Popover from '../Popover/Popover'
|
||||||
import HorizontalSeparator from '../Shared/HorizontalSeparator'
|
import HorizontalSeparator from '../Shared/HorizontalSeparator'
|
||||||
import { iconClass, menuItemClassNames, menuItemSwitchClassNames } from './ClassNames'
|
import { iconClass } from './ClassNames'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
note: SNNote
|
note: SNNote
|
||||||
@@ -33,19 +33,14 @@ const SuperNoteOptions = ({ note, markdownShortcut, enableSuperMarkdownPreview }
|
|||||||
|
|
||||||
<div className="my-1 px-3 text-base font-semibold uppercase text-text lg:text-xs">Super</div>
|
<div className="my-1 px-3 text-base font-semibold uppercase text-text lg:text-xs">Super</div>
|
||||||
|
|
||||||
<button className={menuItemClassNames} onClick={enableSuperMarkdownPreview}>
|
<MenuItem onClick={enableSuperMarkdownPreview}>
|
||||||
<div className="flex w-full items-center justify-between">
|
<Icon type="markdown" className={iconClass} />
|
||||||
<span className="flex">
|
Show Markdown
|
||||||
<Icon type="markdown" className={iconClass} />
|
{markdownShortcut && <KeyboardShortcutIndicator className="ml-auto" shortcut={markdownShortcut} />}
|
||||||
Show Markdown
|
</MenuItem>
|
||||||
</span>
|
|
||||||
{markdownShortcut && <KeyboardShortcutIndicator shortcut={markdownShortcut} />}
|
|
||||||
</div>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button
|
<MenuItem
|
||||||
ref={exportButtonRef}
|
ref={exportButtonRef}
|
||||||
className={menuItemSwitchClassNames}
|
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setIsExportMenuOpen((open) => !open)
|
setIsExportMenuOpen((open) => !open)
|
||||||
}}
|
}}
|
||||||
@@ -54,8 +49,8 @@ const SuperNoteOptions = ({ note, markdownShortcut, enableSuperMarkdownPreview }
|
|||||||
<Icon type="download" className={iconClass} />
|
<Icon type="download" className={iconClass} />
|
||||||
Export
|
Export
|
||||||
</div>
|
</div>
|
||||||
<Icon type="chevron-right" className="text-neutral" />
|
<Icon type="chevron-right" className="ml-auto text-neutral" />
|
||||||
</button>
|
</MenuItem>
|
||||||
<Popover
|
<Popover
|
||||||
side="left"
|
side="left"
|
||||||
align="start"
|
align="start"
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import { TOGGLE_LIST_PANE_KEYBOARD_COMMAND, TOGGLE_NAVIGATION_PANE_KEYBOARD_COMMAND } from '@standardnotes/ui-services'
|
import { TOGGLE_LIST_PANE_KEYBOARD_COMMAND, TOGGLE_NAVIGATION_PANE_KEYBOARD_COMMAND } from '@standardnotes/ui-services'
|
||||||
import { useMemo } from 'react'
|
import { useMemo } from 'react'
|
||||||
import MenuItem from '../Menu/MenuItem'
|
|
||||||
import { MenuItemType } from '../Menu/MenuItemType'
|
|
||||||
import { observer } from 'mobx-react-lite'
|
import { observer } from 'mobx-react-lite'
|
||||||
import { useResponsiveAppPane } from '../ResponsivePane/ResponsivePaneProvider'
|
import { useResponsiveAppPane } from '../ResponsivePane/ResponsivePaneProvider'
|
||||||
import { useCommandService } from '../ApplicationView/CommandProvider'
|
import { useCommandService } from '../ApplicationView/CommandProvider'
|
||||||
|
import MenuSwitchButtonItem from '../Menu/MenuSwitchButtonItem'
|
||||||
|
|
||||||
const PanelSettingsSection = () => {
|
const PanelSettingsSection = () => {
|
||||||
const { isListPaneCollapsed, isNavigationPaneCollapsed, toggleListPane, toggleNavigationPane } =
|
const { isListPaneCollapsed, isNavigationPaneCollapsed, toggleListPane, toggleNavigationPane } =
|
||||||
@@ -24,24 +23,22 @@ const PanelSettingsSection = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="hidden md:block pointer-coarse:md-only:hidden pointer-coarse:lg-only:hidden">
|
<div className="hidden md:block pointer-coarse:md-only:hidden pointer-coarse:lg-only:hidden">
|
||||||
<MenuItem
|
<MenuSwitchButtonItem
|
||||||
type={MenuItemType.SwitchButton}
|
|
||||||
className="py-1 hover:bg-contrast focus:bg-info-backdrop"
|
className="py-1 hover:bg-contrast focus:bg-info-backdrop"
|
||||||
checked={isNavigationPaneCollapsed}
|
checked={isNavigationPaneCollapsed}
|
||||||
onChange={toggleNavigationPane}
|
onChange={toggleNavigationPane}
|
||||||
shortcut={navigationShortcut}
|
shortcut={navigationShortcut}
|
||||||
>
|
>
|
||||||
Show Tags Panel
|
Show Tags Panel
|
||||||
</MenuItem>
|
</MenuSwitchButtonItem>
|
||||||
<MenuItem
|
<MenuSwitchButtonItem
|
||||||
type={MenuItemType.SwitchButton}
|
|
||||||
className="py-1 hover:bg-contrast focus:bg-info-backdrop"
|
className="py-1 hover:bg-contrast focus:bg-info-backdrop"
|
||||||
checked={isListPaneCollapsed}
|
checked={isListPaneCollapsed}
|
||||||
onChange={toggleListPane}
|
onChange={toggleListPane}
|
||||||
shortcut={listShortcut}
|
shortcut={listShortcut}
|
||||||
>
|
>
|
||||||
Show Notes Panel
|
Show Notes Panel
|
||||||
</MenuItem>
|
</MenuSwitchButtonItem>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import { useCallback, useRef, useMemo } from 'react'
|
|||||||
import Icon from '@/Components/Icon/Icon'
|
import Icon from '@/Components/Icon/Icon'
|
||||||
import Menu from '@/Components/Menu/Menu'
|
import Menu from '@/Components/Menu/Menu'
|
||||||
import MenuItem from '@/Components/Menu/MenuItem'
|
import MenuItem from '@/Components/Menu/MenuItem'
|
||||||
import { MenuItemType } from '@/Components/Menu/MenuItemType'
|
|
||||||
import { usePremiumModal } from '@/Hooks/usePremiumModal'
|
import { usePremiumModal } from '@/Hooks/usePremiumModal'
|
||||||
import { SNTag, VectorIconNameOrEmoji, DefaultTagIconName } from '@standardnotes/snjs'
|
import { SNTag, VectorIconNameOrEmoji, DefaultTagIconName } from '@standardnotes/snjs'
|
||||||
import { useCloseOnClickOutside } from '@/Hooks/useCloseOnClickOutside'
|
import { useCloseOnClickOutside } from '@/Hooks/useCloseOnClickOutside'
|
||||||
@@ -82,24 +81,24 @@ const TagContextMenu = ({ navigationController, isEntitledToFolders, selectedTag
|
|||||||
iconGridClassName="max-h-30"
|
iconGridClassName="max-h-30"
|
||||||
/>
|
/>
|
||||||
<HorizontalSeparator classes="my-2" />
|
<HorizontalSeparator classes="my-2" />
|
||||||
<MenuItem type={MenuItemType.IconButton} className={'justify-between py-1.5'} onClick={onClickStar}>
|
<MenuItem className={'justify-between py-1.5'} onClick={onClickStar}>
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<Icon type="star" className="mr-2 text-neutral" />
|
<Icon type="star" className="mr-2 text-neutral" />
|
||||||
{selectedTag.starred ? 'Unfavorite' : 'Favorite'}
|
{selectedTag.starred ? 'Unfavorite' : 'Favorite'}
|
||||||
</div>
|
</div>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem type={MenuItemType.IconButton} className={'justify-between py-1.5'} onClick={onClickAddSubtag}>
|
<MenuItem className={'justify-between py-1.5'} onClick={onClickAddSubtag}>
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<Icon type="add" className="mr-2 text-neutral" />
|
<Icon type="add" className="mr-2 text-neutral" />
|
||||||
Add subtag
|
Add subtag
|
||||||
</div>
|
</div>
|
||||||
{!isEntitledToFolders && <Icon type={PremiumFeatureIconName} className={PremiumFeatureIconClass} />}
|
{!isEntitledToFolders && <Icon type={PremiumFeatureIconName} className={PremiumFeatureIconClass} />}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem type={MenuItemType.IconButton} className={'py-1.5'} onClick={onClickRename}>
|
<MenuItem className={'py-1.5'} onClick={onClickRename}>
|
||||||
<Icon type="pencil-filled" className="mr-2 text-neutral" />
|
<Icon type="pencil-filled" className="mr-2 text-neutral" />
|
||||||
Rename
|
Rename
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem type={MenuItemType.IconButton} className={'py-1.5'} onClick={onClickDelete}>
|
<MenuItem className={'py-1.5'} onClick={onClickDelete}>
|
||||||
<Icon type="trash" className="mr-2 text-danger" />
|
<Icon type="trash" className="mr-2 text-danger" />
|
||||||
<span className="text-danger">Delete</span>
|
<span className="text-danger">Delete</span>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
|||||||
Reference in New Issue
Block a user