feat: Preferences view layout on mobile has been updated, and can be dismissed by swiping from the right
This commit is contained in:
@@ -1,3 +1,5 @@
|
|||||||
<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path d="M6.4167 6.90759L10.2417 10.7326L14.0667 6.90759L15.2417 8.09093L10.2417 13.0909L5.2417 8.09093L6.4167 6.90759Z" fill="#181818"/>
|
<path
|
||||||
|
d="M6.4167 6.90759L10.2417 10.7326L14.0667 6.90759L15.2417 8.09093L10.2417 13.0909L5.2417 8.09093L6.4167 6.90759Z"
|
||||||
|
fill="currentColor" />
|
||||||
</svg>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 222 B After Width: | Height: | Size: 243 B |
@@ -6,29 +6,32 @@ import { useModalAnimation } from '../Modal/useModalAnimation'
|
|||||||
type Props = {
|
type Props = {
|
||||||
isOpen: boolean
|
isOpen: boolean
|
||||||
children: ReactNode
|
children: ReactNode
|
||||||
|
animationVariant?: 'horizontal' | 'vertical'
|
||||||
}
|
}
|
||||||
|
|
||||||
const ModalOverlay = forwardRef(({ isOpen, children, ...props }: Props, ref: ForwardedRef<HTMLDivElement>) => {
|
const ModalOverlay = forwardRef(
|
||||||
const [isMounted, setElement] = useModalAnimation(isOpen)
|
({ isOpen, children, animationVariant, ...props }: Props, ref: ForwardedRef<HTMLDivElement>) => {
|
||||||
const dialog = useDialogStore({
|
const [isMounted, setElement] = useModalAnimation(isOpen, animationVariant)
|
||||||
open: isMounted,
|
const dialog = useDialogStore({
|
||||||
})
|
open: isMounted,
|
||||||
|
})
|
||||||
|
|
||||||
if (!isMounted) {
|
if (!isMounted) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialog
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
className="fixed top-0 left-0 z-modal h-full w-full"
|
className="fixed top-0 left-0 z-modal h-full w-full"
|
||||||
ref={mergeRefs([setElement, ref])}
|
ref={mergeRefs([setElement, ref])}
|
||||||
store={dialog}
|
store={dialog}
|
||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</Dialog>
|
</Dialog>
|
||||||
)
|
)
|
||||||
})
|
},
|
||||||
|
)
|
||||||
|
|
||||||
export default ModalOverlay
|
export default ModalOverlay
|
||||||
|
|||||||
@@ -3,49 +3,86 @@ import { useMediaQuery, MutuallyExclusiveMediaQueryBreakpoints } from '@/Hooks/u
|
|||||||
|
|
||||||
export const IosModalAnimationEasing = 'cubic-bezier(.36,.66,.04,1)'
|
export const IosModalAnimationEasing = 'cubic-bezier(.36,.66,.04,1)'
|
||||||
|
|
||||||
export const useModalAnimation = (isOpen: boolean) => {
|
const Animations = {
|
||||||
|
vertical: {
|
||||||
|
enter: {
|
||||||
|
keyframes: [
|
||||||
|
{
|
||||||
|
transform: 'translateY(100%)',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
transform: 'translateY(0)',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
transformOrigin: 'bottom',
|
||||||
|
},
|
||||||
|
exit: {
|
||||||
|
keyframes: [
|
||||||
|
{
|
||||||
|
transform: 'translateY(0)',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
transform: 'translateY(100%)',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
transformOrigin: 'bottom',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
horizontal: {
|
||||||
|
enter: {
|
||||||
|
keyframes: [
|
||||||
|
{
|
||||||
|
transform: 'translateX(100%)',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
transform: 'translateX(0)',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
transformOrigin: 'right',
|
||||||
|
},
|
||||||
|
exit: {
|
||||||
|
keyframes: [
|
||||||
|
{
|
||||||
|
transform: 'translateX(0)',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
transform: 'translateX(100%)',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
transformOrigin: 'right',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useModalAnimation = (isOpen: boolean, variant: 'horizontal' | 'vertical' = 'vertical') => {
|
||||||
const isMobileScreen = useMediaQuery(MutuallyExclusiveMediaQueryBreakpoints.sm)
|
const isMobileScreen = useMediaQuery(MutuallyExclusiveMediaQueryBreakpoints.sm)
|
||||||
|
|
||||||
return useLifecycleAnimation(
|
return useLifecycleAnimation(
|
||||||
{
|
{
|
||||||
open: isOpen,
|
open: isOpen,
|
||||||
enter: {
|
enter: {
|
||||||
keyframes: [
|
keyframes: Animations[variant].enter.keyframes,
|
||||||
{
|
|
||||||
transform: 'translateY(100%)',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
transform: 'translateY(0)',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
options: {
|
options: {
|
||||||
easing: IosModalAnimationEasing,
|
easing: IosModalAnimationEasing,
|
||||||
duration: 250,
|
duration: 250,
|
||||||
fill: 'forwards',
|
fill: 'forwards',
|
||||||
},
|
},
|
||||||
initialStyle: {
|
initialStyle: {
|
||||||
transformOrigin: 'bottom',
|
transformOrigin: Animations[variant].enter.transformOrigin,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
enterCallback: (element) => {
|
enterCallback: (element) => {
|
||||||
element.scrollTop = 0
|
element.scrollTop = 0
|
||||||
},
|
},
|
||||||
exit: {
|
exit: {
|
||||||
keyframes: [
|
keyframes: Animations[variant].exit.keyframes,
|
||||||
{
|
|
||||||
transform: 'translateY(0)',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
transform: 'translateY(100%)',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
options: {
|
options: {
|
||||||
easing: IosModalAnimationEasing,
|
easing: IosModalAnimationEasing,
|
||||||
duration: 250,
|
duration: 250,
|
||||||
fill: 'forwards',
|
fill: 'forwards',
|
||||||
},
|
},
|
||||||
initialStyle: {
|
initialStyle: {
|
||||||
transformOrigin: 'bottom',
|
transformOrigin: Animations[variant].exit.transformOrigin,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ const Email: FunctionComponent<Props> = ({ application }: Props) => {
|
|||||||
<PreferencesSegment>
|
<PreferencesSegment>
|
||||||
<Title>Email</Title>
|
<Title>Email</Title>
|
||||||
<div>
|
<div>
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-start justify-between gap-2 md:items-center">
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<Subtitle>Mute sign-in notification emails</Subtitle>
|
<Subtitle>Mute sign-in notification emails</Subtitle>
|
||||||
{isMuteSignInEmailsFeatureAvailable ? (
|
{isMuteSignInEmailsFeatureAvailable ? (
|
||||||
@@ -132,7 +132,7 @@ const Email: FunctionComponent<Props> = ({ application }: Props) => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
<Spinner className="ml-2 flex-shrink-0" />
|
<Spinner className="h-5 w-5 flex-shrink-0" />
|
||||||
) : (
|
) : (
|
||||||
isMuteSignInEmailsFeatureAvailable && (
|
isMuteSignInEmailsFeatureAvailable && (
|
||||||
<Switch
|
<Switch
|
||||||
@@ -143,13 +143,13 @@ const Email: FunctionComponent<Props> = ({ application }: Props) => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<HorizontalSeparator classes="my-4" />
|
<HorizontalSeparator classes="my-4" />
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-start justify-between gap-2 md:items-center">
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<Subtitle>Mute marketing notification emails</Subtitle>
|
<Subtitle>Mute marketing notification emails</Subtitle>
|
||||||
<Text>Disables email notifications with special deals and promotions.</Text>
|
<Text>Disables email notifications with special deals and promotions.</Text>
|
||||||
</div>
|
</div>
|
||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
<Spinner className="ml-2 flex-shrink-0" />
|
<Spinner className="h-5 w-5 flex-shrink-0" />
|
||||||
) : (
|
) : (
|
||||||
<Switch
|
<Switch
|
||||||
onChange={toggleMuteMarketingEmails}
|
onChange={toggleMuteMarketingEmails}
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ const Appearance: FunctionComponent<Props> = ({ application }) => {
|
|||||||
<PreferencesSegment>
|
<PreferencesSegment>
|
||||||
<Title>Themes</Title>
|
<Title>Themes</Title>
|
||||||
<div className="mt-2">
|
<div className="mt-2">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex justify-between gap-2 md:items-center">
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<Subtitle>Use system color scheme</Subtitle>
|
<Subtitle>Use system color scheme</Subtitle>
|
||||||
<Text>Automatically change active theme based on your system settings.</Text>
|
<Text>Automatically change active theme based on your system settings.</Text>
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ const EditorDefaults = ({ application }: Props) => {
|
|||||||
<PreferencesSegment>
|
<PreferencesSegment>
|
||||||
<Title>Editor appearance</Title>
|
<Title>Editor appearance</Title>
|
||||||
<div className="mt-2">
|
<div className="mt-2">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex justify-between gap-2 md:items-center">
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<Subtitle>Monospace Font</Subtitle>
|
<Subtitle>Monospace Font</Subtitle>
|
||||||
<Text>Toggles the font style in plaintext and Super notes</Text>
|
<Text>Toggles the font style in plaintext and Super notes</Text>
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ const EmailBackups = ({ application }: Props) => {
|
|||||||
<Text>How often to receive backups.</Text>
|
<Text>How often to receive backups.</Text>
|
||||||
<div className="mt-2">
|
<div className="mt-2">
|
||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
<Spinner className="h-4 w-4" />
|
<Spinner className="h-5 w-5 flex-shrink-0" />
|
||||||
) : (
|
) : (
|
||||||
<Dropdown
|
<Dropdown
|
||||||
label="Select email frequency"
|
label="Select email frequency"
|
||||||
@@ -134,12 +134,12 @@ const EmailBackups = ({ application }: Props) => {
|
|||||||
</div>
|
</div>
|
||||||
<HorizontalSeparator classes="my-4" />
|
<HorizontalSeparator classes="my-4" />
|
||||||
<Subtitle>Email preferences</Subtitle>
|
<Subtitle>Email preferences</Subtitle>
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex justify-between gap-2 md:items-center">
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<Text>Receive a notification email if an email backup fails.</Text>
|
<Text>Receive a notification email if an email backup fails.</Text>
|
||||||
</div>
|
</div>
|
||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
<Spinner className="h-4 w-4" />
|
<Spinner className="h-5 w-5 flex-shrink-0" />
|
||||||
) : (
|
) : (
|
||||||
<Switch onChange={toggleMuteFailedBackupEmails} checked={!isFailedBackupEmailMuted} />
|
<Switch onChange={toggleMuteFailedBackupEmails} checked={!isFailedBackupEmailMuted} />
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ const Defaults: FunctionComponent<Props> = ({ application }) => {
|
|||||||
<Title>Defaults</Title>
|
<Title>Defaults</Title>
|
||||||
{application.platform === Platform.Android && (
|
{application.platform === Platform.Android && (
|
||||||
<>
|
<>
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex justify-between gap-2 md:items-center">
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<Subtitle>Always ask before closing app (Android)</Subtitle>
|
<Subtitle>Always ask before closing app (Android)</Subtitle>
|
||||||
<Text>Whether a confirmation dialog should be shown before closing the app.</Text>
|
<Text>Whether a confirmation dialog should be shown before closing the app.</Text>
|
||||||
@@ -54,7 +54,7 @@ const Defaults: FunctionComponent<Props> = ({ application }) => {
|
|||||||
<HorizontalSeparator classes="my-4" />
|
<HorizontalSeparator classes="my-4" />
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex justify-between gap-2 md:items-center">
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<Subtitle>Spellcheck</Subtitle>
|
<Subtitle>Spellcheck</Subtitle>
|
||||||
<Text>
|
<Text>
|
||||||
@@ -65,7 +65,7 @@ const Defaults: FunctionComponent<Props> = ({ application }) => {
|
|||||||
<Switch onChange={toggleSpellcheck} checked={spellcheck} />
|
<Switch onChange={toggleSpellcheck} checked={spellcheck} />
|
||||||
</div>
|
</div>
|
||||||
<HorizontalSeparator classes="my-4" />
|
<HorizontalSeparator classes="my-4" />
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex justify-between gap-2 md:items-center">
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<Subtitle>Add all parent tags when adding a nested tag to a note</Subtitle>
|
<Subtitle>Add all parent tags when adding a nested tag to a note</Subtitle>
|
||||||
<Text>When enabled, adding a nested tag to a note will automatically add all associated parent tags.</Text>
|
<Text>When enabled, adding a nested tag to a note will automatically add all associated parent tags.</Text>
|
||||||
|
|||||||
@@ -62,13 +62,14 @@ const LabsPane: FunctionComponent<Props> = ({ application }) => {
|
|||||||
const premiumModal = usePremiumModal()
|
const premiumModal = usePremiumModal()
|
||||||
|
|
||||||
const isMobileScreen = useMediaQuery(MutuallyExclusiveMediaQueryBreakpoints.sm)
|
const isMobileScreen = useMediaQuery(MutuallyExclusiveMediaQueryBreakpoints.sm)
|
||||||
|
const canShowPaneGesturesOption = isMobileScreen && typeof isPaneGesturesEnabled === 'boolean'
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PreferencesGroup>
|
<PreferencesGroup>
|
||||||
<PreferencesSegment>
|
<PreferencesSegment>
|
||||||
<Title>Labs</Title>
|
<Title>Labs</Title>
|
||||||
<div>
|
<div>
|
||||||
{isMobileScreen && (
|
{canShowPaneGesturesOption && (
|
||||||
<LabsFeature
|
<LabsFeature
|
||||||
name="Pane switch gestures"
|
name="Pane switch gestures"
|
||||||
description="Allows using gestures to navigate"
|
description="Allows using gestures to navigate"
|
||||||
@@ -103,7 +104,7 @@ const LabsPane: FunctionComponent<Props> = ({ application }) => {
|
|||||||
</Fragment>
|
</Fragment>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
{(experimentalFeatures.length === 0 || typeof isPaneGesturesEnabled === 'boolean') && (
|
{experimentalFeatures.length === 0 && !canShowPaneGesturesOption && (
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<Text>No experimental features available.</Text>
|
<Text>No experimental features available.</Text>
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ type Props = {
|
|||||||
|
|
||||||
const LabsFeature = ({ name, description, toggleFeature, isEnabled }: Props) => {
|
const LabsFeature = ({ name, description, toggleFeature, isEnabled }: Props) => {
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex justify-between gap-2 md:items-center">
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<Subtitle>{name}</Subtitle>
|
<Subtitle>{name}</Subtitle>
|
||||||
<Text>{description}</Text>
|
<Text>{description}</Text>
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ const Tools: FunctionComponent<Props> = ({ application }: Props) => {
|
|||||||
<PreferencesSegment>
|
<PreferencesSegment>
|
||||||
<Title>Tools</Title>
|
<Title>Tools</Title>
|
||||||
<div>
|
<div>
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex justify-between gap-2 md:items-center">
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<Subtitle>Show note saving status while editing</Subtitle>
|
<Subtitle>Show note saving status while editing</Subtitle>
|
||||||
<Text>
|
<Text>
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ const Privacy: FunctionComponent<Props> = ({ application }: Props) => {
|
|||||||
<PreferencesSegment>
|
<PreferencesSegment>
|
||||||
<Title>Privacy</Title>
|
<Title>Privacy</Title>
|
||||||
<div>
|
<div>
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex justify-between gap-2 md:items-center">
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<Subtitle>Session user agent logging</Subtitle>
|
<Subtitle>Session user agent logging</Subtitle>
|
||||||
<Text>
|
<Text>
|
||||||
@@ -87,7 +87,7 @@ const Privacy: FunctionComponent<Props> = ({ application }: Props) => {
|
|||||||
</Text>
|
</Text>
|
||||||
</div>
|
</div>
|
||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
<Spinner className="ml-2 flex-shrink-0" />
|
<Spinner className="h-5 w-5 flex-shrink-0" />
|
||||||
) : (
|
) : (
|
||||||
<Switch
|
<Switch
|
||||||
onChange={toggleSessionLogging}
|
onChange={toggleSessionLogging}
|
||||||
|
|||||||
@@ -91,14 +91,12 @@ const TwoFactorAuthView: FunctionComponent<Props> = ({ auth, application }) => {
|
|||||||
<>
|
<>
|
||||||
<PreferencesGroup>
|
<PreferencesGroup>
|
||||||
<PreferencesSegment>
|
<PreferencesSegment>
|
||||||
<div className="flex flex-row items-center">
|
<div className="flex flex-row gap-2 md:items-center">
|
||||||
<div className="flex flex-grow flex-col">
|
<div className="flex flex-grow flex-col">
|
||||||
<TwoFactorTitle auth={auth} />
|
<TwoFactorTitle auth={auth} />
|
||||||
<TwoFactorDescription auth={auth} />
|
<TwoFactorDescription auth={auth} />
|
||||||
</div>
|
</div>
|
||||||
<div className="flex min-w-15 flex-col items-center justify-center">
|
<TwoFactorSwitch auth={auth} />
|
||||||
<TwoFactorSwitch auth={auth} />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</PreferencesSegment>
|
</PreferencesSegment>
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import PaneSelector from './PaneSelector'
|
|||||||
import { PreferencesProps } from './PreferencesProps'
|
import { PreferencesProps } from './PreferencesProps'
|
||||||
|
|
||||||
const PreferencesCanvas: FunctionComponent<PreferencesProps & { menu: PreferencesMenu }> = (props) => (
|
const PreferencesCanvas: FunctionComponent<PreferencesProps & { menu: PreferencesMenu }> = (props) => (
|
||||||
<div className="flex min-h-0 flex-grow flex-col-reverse md:flex-row md:justify-between">
|
<div className="flex min-h-0 flex-grow flex-col md:flex-row md:justify-between">
|
||||||
<PreferencesMenuView menu={props.menu} />
|
<PreferencesMenuView menu={props.menu} />
|
||||||
<div className="min-h-0 flex-grow overflow-auto bg-contrast">
|
<div className="min-h-0 flex-grow overflow-auto bg-contrast">
|
||||||
<PaneSelector {...props} />
|
<PaneSelector {...props} />
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ const PreferencesMenuView: FunctionComponent<Props> = ({ menu }) => {
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={classNames(
|
className={classNames(
|
||||||
'border-t border-border bg-default px-5 pt-2 md:border-0 md:bg-contrast md:px-0 md:py-0',
|
'border-b border-border bg-default px-5 pt-2 md:border-0 md:bg-contrast md:px-0 md:py-0',
|
||||||
hasBottomInset ? 'pb-safe-bottom' : 'pb-2 md:pb-0',
|
hasBottomInset ? 'pb-safe-bottom' : 'pb-2 md:pb-0',
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
@@ -60,7 +60,7 @@ const PreferencesMenuView: FunctionComponent<Props> = ({ menu }) => {
|
|||||||
wrapper: 'relative',
|
wrapper: 'relative',
|
||||||
button: 'focus:outline-none focus:shadow-none focus:ring-none',
|
button: 'focus:outline-none focus:shadow-none focus:ring-none',
|
||||||
}}
|
}}
|
||||||
popoverPlacement="top"
|
popoverPlacement="bottom"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -47,7 +47,11 @@ const PreferencesViewWrapper: FunctionComponent<PreferencesViewWrapperProps> = (
|
|||||||
})
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ModalOverlay isOpen={viewControllerManager.preferencesController.isOpen} ref={setElement}>
|
<ModalOverlay
|
||||||
|
isOpen={viewControllerManager.preferencesController.isOpen}
|
||||||
|
ref={setElement}
|
||||||
|
animationVariant="horizontal"
|
||||||
|
>
|
||||||
<PreferencesView
|
<PreferencesView
|
||||||
closePreferences={viewControllerManager.preferencesController.closePreferences}
|
closePreferences={viewControllerManager.preferencesController.closePreferences}
|
||||||
application={application}
|
application={application}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { FunctionComponent, ReactNode, useRef, useState } from 'react'
|
import { FunctionComponent, ReactNode, useRef, useState } from 'react'
|
||||||
import { ArrowDownCheckmarkIcon } from '@standardnotes/icons'
|
import { ArrowDownCheckmarkIcon } from '@standardnotes/icons'
|
||||||
import { Title } from '@/Components/Preferences/PreferencesComponents/Content'
|
import { Title } from '@/Components/Preferences/PreferencesComponents/Content'
|
||||||
|
import { classNames } from '@standardnotes/snjs'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
title: string | JSX.Element
|
title: string | JSX.Element
|
||||||
@@ -21,12 +22,7 @@ const AccordionItem: FunctionComponent<Props> = ({ title, className = '', childr
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Title>{title}</Title>
|
<Title>{title}</Title>
|
||||||
<ArrowDownCheckmarkIcon
|
<ArrowDownCheckmarkIcon className={classNames('h-5 w-5 text-info', isExpanded && 'rotate-180')} />
|
||||||
className="sn-accordion-arrow-icon"
|
|
||||||
width={20}
|
|
||||||
height={20}
|
|
||||||
data-is-expanded={isExpanded}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div className={'accordion-contents-container cursor-auto'} data-is-expanded={isExpanded} ref={elementRef}>
|
<div className={'accordion-contents-container cursor-auto'} data-is-expanded={isExpanded} ref={elementRef}>
|
||||||
{children}
|
{children}
|
||||||
|
|||||||
@@ -16,12 +16,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.sn-accordion-arrow-icon {
|
|
||||||
&[data-is-expanded='true'] {
|
|
||||||
transform: rotate(180deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.accordion-contents-container {
|
.accordion-contents-container {
|
||||||
transition: all 0.23s ease-out;
|
transition: all 0.23s ease-out;
|
||||||
transform-origin: top;
|
transform-origin: top;
|
||||||
|
|||||||
Reference in New Issue
Block a user