fix: remove tablet specific responsive UI (#1411)
* fix: revert tablet responsiveness UI * fix: don't let the "Saving..." text container hide the note title on tablets * chore: better visibility of css classes list * fix: fixed width of notes container column on Tablets
This commit is contained in:
@@ -21,6 +21,7 @@ import ResponsivePaneContent from '../ResponsivePane/ResponsivePaneContent'
|
|||||||
import { AppPaneId } from '../ResponsivePane/AppPaneMetadata'
|
import { AppPaneId } from '../ResponsivePane/AppPaneMetadata'
|
||||||
import { useResponsiveAppPane } from '../ResponsivePane/ResponsivePaneProvider'
|
import { useResponsiveAppPane } from '../ResponsivePane/ResponsivePaneProvider'
|
||||||
import { StreamingFileReader } from '@standardnotes/filepicker'
|
import { StreamingFileReader } from '@standardnotes/filepicker'
|
||||||
|
import { classNames } from '@/Utils/ConcatenateClassNames'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
accountMenuController: AccountMenuController
|
accountMenuController: AccountMenuController
|
||||||
@@ -179,7 +180,10 @@ const ContentListView: FunctionComponent<Props> = ({
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
id="items-column"
|
id="items-column"
|
||||||
className="sn-component section app-column flex flex-col border-b border-solid border-border xl:w-87.5 xsm-only:!w-full sm-only:!w-full md-only:!w-52 lg-only:!w-52"
|
className={classNames(
|
||||||
|
'sn-component section app-column flex flex-col border-b border-solid border-border ',
|
||||||
|
'xl:w-87.5 xsm-only:!w-full sm-only:!w-full md-only:!w-52 lg-only:!w-52',
|
||||||
|
)}
|
||||||
aria-label={'Notes & Files'}
|
aria-label={'Notes & Files'}
|
||||||
ref={itemsViewPanelRef}
|
ref={itemsViewPanelRef}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import SearchBar from '@/Components/SearchBar/SearchBar'
|
|||||||
import ResponsivePaneContent from '@/Components/ResponsivePane/ResponsivePaneContent'
|
import ResponsivePaneContent from '@/Components/ResponsivePane/ResponsivePaneContent'
|
||||||
import { AppPaneId } from '@/Components/ResponsivePane/AppPaneMetadata'
|
import { AppPaneId } from '@/Components/ResponsivePane/AppPaneMetadata'
|
||||||
import { classNames } from '@/Utils/ConcatenateClassNames'
|
import { classNames } from '@/Utils/ConcatenateClassNames'
|
||||||
import Icon from '@/Components/Icon/Icon'
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
application: WebApplication
|
application: WebApplication
|
||||||
@@ -20,7 +19,6 @@ const Navigation: FunctionComponent<Props> = ({ application }) => {
|
|||||||
const viewControllerManager = useMemo(() => application.getViewControllerManager(), [application])
|
const viewControllerManager = useMemo(() => application.getViewControllerManager(), [application])
|
||||||
const ref = useRef<HTMLDivElement>(null)
|
const ref = useRef<HTMLDivElement>(null)
|
||||||
const [panelWidth, setPanelWidth] = useState<number>(0)
|
const [panelWidth, setPanelWidth] = useState<number>(0)
|
||||||
const [isPanelExpanded, setIsPanelExpanded] = useState(true)
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const removeObserver = application.addEventObserver(async () => {
|
const removeObserver = application.addEventObserver(async () => {
|
||||||
@@ -51,37 +49,21 @@ const Navigation: FunctionComponent<Props> = ({ application }) => {
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
id="navigation"
|
id="navigation"
|
||||||
className={classNames(
|
className={'sn-component section app-column w-[220px] xsm-only:!w-full sm-only:!w-full'}
|
||||||
'sn-component section app-column xl:w-[220px] xsm-only:!w-full sm-only:!w-full md-only:transition-width lg-only:transition-width',
|
|
||||||
isPanelExpanded ? 'md-only:!w-[220px] lg-only:!w-[220px]' : 'md-only:!w-18 lg-only:!w-18',
|
|
||||||
)}
|
|
||||||
ref={ref}
|
ref={ref}
|
||||||
>
|
>
|
||||||
<ResponsivePaneContent paneId={AppPaneId.Navigation} contentElementId="navigation-content">
|
<ResponsivePaneContent paneId={AppPaneId.Navigation} contentElementId="navigation-content">
|
||||||
{isPanelExpanded && (
|
<SearchBar
|
||||||
<SearchBar
|
itemListController={viewControllerManager.itemListController}
|
||||||
itemListController={viewControllerManager.itemListController}
|
searchOptionsController={viewControllerManager.searchOptionsController}
|
||||||
searchOptionsController={viewControllerManager.searchOptionsController}
|
selectedViewTitle={viewControllerManager.navigationController.selected?.title}
|
||||||
selectedViewTitle={viewControllerManager.navigationController.selected?.title}
|
/>
|
||||||
/>
|
<div className={'section-title-bar'}>
|
||||||
)}
|
<div className="section-title-bar-header">
|
||||||
<div className={'flex justify-end'}>
|
<div className="title text-sm">
|
||||||
<div className={classNames('section-title-bar block w-full xl:block', !isPanelExpanded && 'hidden')}>
|
<span className="font-bold">Views</span>
|
||||||
<div className="section-title-bar-header">
|
|
||||||
<div className="title text-sm">
|
|
||||||
<span className="font-bold">Views</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
|
||||||
className={classNames(
|
|
||||||
'hidden items-end self-end rounded-full rounded-tr-none rounded-br-none bg-default p-1 text-foreground md:flex xl:hidden',
|
|
||||||
isPanelExpanded ? 'mb-1 w-fit' : 'mt-4.5 mb-3 ml-3 w-full',
|
|
||||||
)}
|
|
||||||
onClick={() => setIsPanelExpanded(!isPanelExpanded)}
|
|
||||||
>
|
|
||||||
<Icon type="chevron-down" className={isPanelExpanded ? 'rotate-90' : '-rotate-90'} />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className={classNames(
|
className={classNames(
|
||||||
@@ -90,8 +72,8 @@ const Navigation: FunctionComponent<Props> = ({ application }) => {
|
|||||||
'md:hover:[overflow-y:_overlay]',
|
'md:hover:[overflow-y:_overlay]',
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<SmartViewsSection viewControllerManager={viewControllerManager} isCollapsed={!isPanelExpanded} />
|
<SmartViewsSection viewControllerManager={viewControllerManager} />
|
||||||
<TagsSection viewControllerManager={viewControllerManager} isCollapsed={!isPanelExpanded} />
|
<TagsSection viewControllerManager={viewControllerManager} />
|
||||||
</div>
|
</div>
|
||||||
</ResponsivePaneContent>
|
</ResponsivePaneContent>
|
||||||
{ref.current && (
|
{ref.current && (
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import {
|
|||||||
import { reloadFont } from './FontFunctions'
|
import { reloadFont } from './FontFunctions'
|
||||||
import { NoteViewProps } from './NoteViewProps'
|
import { NoteViewProps } from './NoteViewProps'
|
||||||
import IndicatorCircle from '../IndicatorCircle/IndicatorCircle'
|
import IndicatorCircle from '../IndicatorCircle/IndicatorCircle'
|
||||||
|
import { classNames } from '@/Utils/ConcatenateClassNames'
|
||||||
|
|
||||||
const MINIMUM_STATUS_DURATION = 400
|
const MINIMUM_STATUS_DURATION = 400
|
||||||
const TEXTAREA_DEBOUNCE = 100
|
const TEXTAREA_DEBOUNCE = 100
|
||||||
@@ -911,7 +912,7 @@ class NoteView extends PureComponent<NoteViewProps, State> {
|
|||||||
|
|
||||||
{this.note && (
|
{this.note && (
|
||||||
<div id="editor-title-bar" className="content-title-bar section-title-bar z-editor-title-bar w-full">
|
<div id="editor-title-bar" className="content-title-bar section-title-bar z-editor-title-bar w-full">
|
||||||
<div className="mb-2 flex flex-wrap items-center justify-between gap-2 md:mb-0 md:flex-nowrap md:gap-0">
|
<div className="mb-2 flex flex-wrap items-start justify-between gap-2 md:mb-0 md:flex-nowrap md:gap-0 xl:items-center">
|
||||||
<div className={(this.state.noteLocked ? 'locked' : '') + ' flex-grow'}>
|
<div className={(this.state.noteLocked ? 'locked' : '') + ' flex-grow'}>
|
||||||
<div className="title overflow-auto">
|
<div className="title overflow-auto">
|
||||||
<input
|
<input
|
||||||
@@ -929,9 +930,14 @@ class NoteView extends PureComponent<NoteViewProps, State> {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col flex-wrap items-start gap-3 md:flex-row md:flex-nowrap md:items-center">
|
<div
|
||||||
|
className={classNames(
|
||||||
|
'flex flex-col flex-wrap items-start gap-3 md:flex-col-reverse md:items-end',
|
||||||
|
'xl:flex-row xl:flex-nowrap xl:items-center',
|
||||||
|
)}
|
||||||
|
>
|
||||||
{this.state.noteStatus?.message?.length && (
|
{this.state.noteStatus?.message?.length && (
|
||||||
<div id="save-status-container">
|
<div id="save-status-container" className={'xl:mr-5 xl:max-w-[16ch]'}>
|
||||||
<div id="save-status">
|
<div id="save-status">
|
||||||
<div
|
<div
|
||||||
className={
|
className={
|
||||||
|
|||||||
@@ -5,10 +5,9 @@ import SmartViewsListItem from './SmartViewsListItem'
|
|||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
viewControllerManager: ViewControllerManager
|
viewControllerManager: ViewControllerManager
|
||||||
isCollapsed: boolean
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const SmartViewsList: FunctionComponent<Props> = ({ viewControllerManager, isCollapsed }: Props) => {
|
const SmartViewsList: FunctionComponent<Props> = ({ viewControllerManager }: Props) => {
|
||||||
const allViews = viewControllerManager.navigationController.smartViews
|
const allViews = viewControllerManager.navigationController.smartViews
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -20,7 +19,6 @@ const SmartViewsList: FunctionComponent<Props> = ({ viewControllerManager, isCol
|
|||||||
view={view}
|
view={view}
|
||||||
tagsState={viewControllerManager.navigationController}
|
tagsState={viewControllerManager.navigationController}
|
||||||
features={viewControllerManager.featuresController}
|
features={viewControllerManager.featuresController}
|
||||||
isCollapsed={isCollapsed}
|
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ type Props = {
|
|||||||
view: SmartView
|
view: SmartView
|
||||||
tagsState: NavigationController
|
tagsState: NavigationController
|
||||||
features: FeaturesController
|
features: FeaturesController
|
||||||
isCollapsed: boolean
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const PADDING_BASE_PX = 14
|
const PADDING_BASE_PX = 14
|
||||||
@@ -47,7 +46,7 @@ const smartViewIconType = (view: SmartView, isSelected: boolean): IconType => {
|
|||||||
return 'hashtag'
|
return 'hashtag'
|
||||||
}
|
}
|
||||||
|
|
||||||
const SmartViewsListItem: FunctionComponent<Props> = ({ view, tagsState, isCollapsed }) => {
|
const SmartViewsListItem: FunctionComponent<Props> = ({ view, tagsState }) => {
|
||||||
const { toggleAppPane } = useResponsiveAppPane()
|
const { toggleAppPane } = useResponsiveAppPane()
|
||||||
|
|
||||||
const [title, setTitle] = useState(view.title || '')
|
const [title, setTitle] = useState(view.title || '')
|
||||||
@@ -113,31 +112,19 @@ const SmartViewsListItem: FunctionComponent<Props> = ({ view, tagsState, isColla
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div
|
<div
|
||||||
className={classNames(
|
className={classNames('tag', isSelected && 'selected', isFaded && 'opacity-50')}
|
||||||
'tag',
|
|
||||||
isSelected && 'selected',
|
|
||||||
isFaded && 'opacity-50',
|
|
||||||
isCollapsed && '!bg-transparent',
|
|
||||||
)}
|
|
||||||
onClick={selectCurrentTag}
|
onClick={selectCurrentTag}
|
||||||
style={{
|
style={{
|
||||||
paddingLeft: `${level * PADDING_PER_LEVEL_PX + PADDING_BASE_PX}px`,
|
paddingLeft: `${level * PADDING_PER_LEVEL_PX + PADDING_BASE_PX}px`,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className="tag-info relative">
|
<div className="tag-info">
|
||||||
<div
|
<div className={'tag-icon mr-2'}>
|
||||||
className={classNames(
|
|
||||||
isCollapsed
|
|
||||||
? `relative flex h-[40px] w-[40px] items-center justify-center
|
|
||||||
${isSelected ? 'transparent-info-color-background' : 'transparent-info-color-background-hover'}`
|
|
||||||
: 'tag-icon mr-2',
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<Icon type={iconType} className={isSelected ? 'text-info' : 'text-neutral'} />
|
<Icon type={iconType} className={isSelected ? 'text-info' : 'text-neutral'} />
|
||||||
</div>
|
</div>
|
||||||
{isEditing ? (
|
{isEditing ? (
|
||||||
<input
|
<input
|
||||||
className={classNames('title editing', isCollapsed ? 'hidden' : 'block')}
|
className={'title editing'}
|
||||||
id={`react-tag-${view.uuid}`}
|
id={`react-tag-${view.uuid}`}
|
||||||
onBlur={onBlur}
|
onBlur={onBlur}
|
||||||
onInput={onInput}
|
onInput={onInput}
|
||||||
@@ -147,19 +134,14 @@ const SmartViewsListItem: FunctionComponent<Props> = ({ view, tagsState, isColla
|
|||||||
ref={inputRef}
|
ref={inputRef}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<div
|
<div className={'title overflow-hidden text-left'} id={`react-tag-${view.uuid}`}>
|
||||||
className={classNames('title overflow-hidden text-left', isCollapsed ? 'hidden' : 'block')}
|
|
||||||
id={`react-tag-${view.uuid}`}
|
|
||||||
>
|
|
||||||
{title}
|
{title}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className={classNames('count', isCollapsed ? 'absolute top-0 right-0' : '')}>
|
<div className={'count'}>{view.uuid === SystemViewId.AllNotes && tagsState.allNotesCount}</div>
|
||||||
{view.uuid === SystemViewId.AllNotes && tagsState.allNotesCount}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{!isSystemView(view) && !isCollapsed && (
|
{!isSystemView(view) && (
|
||||||
<div className="meta">
|
<div className="meta">
|
||||||
{view.conflictOf && (
|
{view.conflictOf && (
|
||||||
<div className="danger text-[0.625rem] font-bold">Conflicted Copy {view.conflictOf}</div>
|
<div className="danger text-[0.625rem] font-bold">Conflicted Copy {view.conflictOf}</div>
|
||||||
|
|||||||
@@ -5,13 +5,12 @@ import SmartViewsList from './SmartViewsList'
|
|||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
viewControllerManager: ViewControllerManager
|
viewControllerManager: ViewControllerManager
|
||||||
isCollapsed: boolean
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const SmartViewsSection: FunctionComponent<Props> = ({ viewControllerManager, isCollapsed }) => {
|
const SmartViewsSection: FunctionComponent<Props> = ({ viewControllerManager }) => {
|
||||||
return (
|
return (
|
||||||
<section>
|
<section>
|
||||||
<SmartViewsList viewControllerManager={viewControllerManager} isCollapsed={isCollapsed} />
|
<SmartViewsList viewControllerManager={viewControllerManager} />
|
||||||
</section>
|
</section>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,10 +9,9 @@ import { TagsListItem } from './TagsListItem'
|
|||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
viewControllerManager: ViewControllerManager
|
viewControllerManager: ViewControllerManager
|
||||||
isCollapsed: boolean
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const TagsList: FunctionComponent<Props> = ({ viewControllerManager, isCollapsed }: Props) => {
|
const TagsList: FunctionComponent<Props> = ({ viewControllerManager }: Props) => {
|
||||||
const tagsState = viewControllerManager.navigationController
|
const tagsState = viewControllerManager.navigationController
|
||||||
const allTags = tagsState.allLocalRootTags
|
const allTags = tagsState.allLocalRootTags
|
||||||
|
|
||||||
@@ -53,7 +52,6 @@ const TagsList: FunctionComponent<Props> = ({ viewControllerManager, isCollapsed
|
|||||||
tagsState={tagsState}
|
tagsState={tagsState}
|
||||||
features={viewControllerManager.featuresController}
|
features={viewControllerManager.featuresController}
|
||||||
onContextMenu={onContextMenu}
|
onContextMenu={onContextMenu}
|
||||||
isCollapsed={isCollapsed}
|
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ import { useDrag, useDrop } from 'react-dnd'
|
|||||||
import { DropItem, DropProps, ItemTypes } from './DragNDrop'
|
import { DropItem, DropProps, ItemTypes } from './DragNDrop'
|
||||||
import { useResponsiveAppPane } from '../ResponsivePane/ResponsivePaneProvider'
|
import { useResponsiveAppPane } from '../ResponsivePane/ResponsivePaneProvider'
|
||||||
import { AppPaneId } from '../ResponsivePane/AppPaneMetadata'
|
import { AppPaneId } from '../ResponsivePane/AppPaneMetadata'
|
||||||
import { classNames } from '@/Utils/ConcatenateClassNames'
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
tag: SNTag
|
tag: SNTag
|
||||||
@@ -30,306 +29,287 @@ type Props = {
|
|||||||
features: FeaturesController
|
features: FeaturesController
|
||||||
level: number
|
level: number
|
||||||
onContextMenu: (tag: SNTag, posX: number, posY: number) => void
|
onContextMenu: (tag: SNTag, posX: number, posY: number) => void
|
||||||
isCollapsed: boolean
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const PADDING_BASE_PX = 14
|
const PADDING_BASE_PX = 14
|
||||||
const PADDING_BASE_WHEN_COLLAPSED_PX = 6
|
|
||||||
const PADDING_PER_LEVEL_PX = 21
|
const PADDING_PER_LEVEL_PX = 21
|
||||||
const PADDING_PER_LEVEL_WHEN_COLLAPSED_PX = 10
|
|
||||||
|
|
||||||
export const TagsListItem: FunctionComponent<Props> = observer(
|
export const TagsListItem: FunctionComponent<Props> = observer(({ tag, features, tagsState, level, onContextMenu }) => {
|
||||||
({ tag, features, tagsState, level, onContextMenu, isCollapsed }) => {
|
const { toggleAppPane } = useResponsiveAppPane()
|
||||||
const { toggleAppPane } = useResponsiveAppPane()
|
|
||||||
|
|
||||||
const [title, setTitle] = useState(tag.title || '')
|
const [title, setTitle] = useState(tag.title || '')
|
||||||
const [subtagTitle, setSubtagTitle] = useState('')
|
const [subtagTitle, setSubtagTitle] = useState('')
|
||||||
const inputRef = useRef<HTMLInputElement>(null)
|
const inputRef = useRef<HTMLInputElement>(null)
|
||||||
const subtagInputRef = useRef<HTMLInputElement>(null)
|
const subtagInputRef = useRef<HTMLInputElement>(null)
|
||||||
const menuButtonRef = useRef<HTMLAnchorElement>(null)
|
const menuButtonRef = useRef<HTMLAnchorElement>(null)
|
||||||
|
|
||||||
const isSelected = tagsState.selected === tag
|
const isSelected = tagsState.selected === tag
|
||||||
const isEditing = tagsState.editingTag === tag
|
const isEditing = tagsState.editingTag === tag
|
||||||
const isAddingSubtag = tagsState.addingSubtagTo === tag
|
const isAddingSubtag = tagsState.addingSubtagTo === tag
|
||||||
const noteCounts = computed(() => tagsState.getNotesCount(tag))
|
const noteCounts = computed(() => tagsState.getNotesCount(tag))
|
||||||
|
|
||||||
const childrenTags = computed(() => tagsState.getChildren(tag)).get()
|
const childrenTags = computed(() => tagsState.getChildren(tag)).get()
|
||||||
const hasChildren = childrenTags.length > 0
|
const hasChildren = childrenTags.length > 0
|
||||||
|
|
||||||
const hasFolders = features.hasFolders
|
const hasFolders = features.hasFolders
|
||||||
const hasAtLeastOneFolder = tagsState.hasAtLeastOneFolder
|
const hasAtLeastOneFolder = tagsState.hasAtLeastOneFolder
|
||||||
|
|
||||||
const premiumModal = usePremiumModal()
|
const premiumModal = usePremiumModal()
|
||||||
|
|
||||||
const [showChildren, setShowChildren] = useState(tag.expanded)
|
const [showChildren, setShowChildren] = useState(tag.expanded)
|
||||||
const [hadChildren, setHadChildren] = useState(hasChildren)
|
const [hadChildren, setHadChildren] = useState(hasChildren)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!hadChildren && hasChildren) {
|
if (!hadChildren && hasChildren) {
|
||||||
setShowChildren(true)
|
setShowChildren(true)
|
||||||
}
|
}
|
||||||
setHadChildren(hasChildren)
|
setHadChildren(hasChildren)
|
||||||
}, [hadChildren, hasChildren])
|
}, [hadChildren, hasChildren])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setTitle(tag.title || '')
|
setTitle(tag.title || '')
|
||||||
}, [setTitle, tag])
|
}, [setTitle, tag])
|
||||||
|
|
||||||
const toggleChildren: MouseEventHandler = useCallback(
|
const toggleChildren: MouseEventHandler = useCallback(
|
||||||
(e) => {
|
(e) => {
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
setShowChildren((x) => {
|
setShowChildren((x) => {
|
||||||
tagsState.setExpanded(tag, !x)
|
tagsState.setExpanded(tag, !x)
|
||||||
return !x
|
return !x
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
[setShowChildren, tag, tagsState],
|
[setShowChildren, tag, tagsState],
|
||||||
)
|
)
|
||||||
|
|
||||||
const selectCurrentTag = useCallback(async () => {
|
const selectCurrentTag = useCallback(async () => {
|
||||||
await tagsState.setSelectedTag(tag)
|
await tagsState.setSelectedTag(tag)
|
||||||
toggleAppPane(AppPaneId.Items)
|
toggleAppPane(AppPaneId.Items)
|
||||||
}, [tagsState, tag, toggleAppPane])
|
}, [tagsState, tag, toggleAppPane])
|
||||||
|
|
||||||
const onBlur = useCallback(() => {
|
const onBlur = useCallback(() => {
|
||||||
tagsState.save(tag, title).catch(console.error)
|
tagsState.save(tag, title).catch(console.error)
|
||||||
setTitle(tag.title)
|
setTitle(tag.title)
|
||||||
}, [tagsState, tag, title, setTitle])
|
}, [tagsState, tag, title, setTitle])
|
||||||
|
|
||||||
const onInput: FormEventHandler = useCallback(
|
const onInput: FormEventHandler = useCallback(
|
||||||
(e) => {
|
(e) => {
|
||||||
const value = (e.target as HTMLInputElement).value
|
|
||||||
setTitle(value)
|
|
||||||
},
|
|
||||||
[setTitle],
|
|
||||||
)
|
|
||||||
|
|
||||||
const onKeyDown: KeyboardEventHandler = useCallback(
|
|
||||||
(e) => {
|
|
||||||
if (e.key === KeyboardKey.Enter) {
|
|
||||||
inputRef.current?.blur()
|
|
||||||
e.preventDefault()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[inputRef],
|
|
||||||
)
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isEditing) {
|
|
||||||
inputRef.current?.focus()
|
|
||||||
}
|
|
||||||
}, [inputRef, isEditing])
|
|
||||||
|
|
||||||
const onSubtagInput = useCallback((e) => {
|
|
||||||
const value = (e.target as HTMLInputElement).value
|
const value = (e.target as HTMLInputElement).value
|
||||||
setSubtagTitle(value)
|
setTitle(value)
|
||||||
}, [])
|
},
|
||||||
|
[setTitle],
|
||||||
|
)
|
||||||
|
|
||||||
const onSubtagInputBlur = useCallback(() => {
|
const onKeyDown: KeyboardEventHandler = useCallback(
|
||||||
tagsState.createSubtagAndAssignParent(tag, subtagTitle).catch(console.error)
|
(e) => {
|
||||||
setSubtagTitle('')
|
if (e.key === KeyboardKey.Enter) {
|
||||||
}, [subtagTitle, tag, tagsState])
|
inputRef.current?.blur()
|
||||||
|
e.preventDefault()
|
||||||
const onSubtagKeyDown: KeyboardEventHandler = useCallback(
|
|
||||||
(e) => {
|
|
||||||
if (e.key === KeyboardKey.Enter) {
|
|
||||||
e.preventDefault()
|
|
||||||
subtagInputRef.current?.blur()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[subtagInputRef],
|
|
||||||
)
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isAddingSubtag) {
|
|
||||||
subtagInputRef.current?.focus()
|
|
||||||
}
|
}
|
||||||
}, [subtagInputRef, isAddingSubtag])
|
},
|
||||||
|
[inputRef],
|
||||||
|
)
|
||||||
|
|
||||||
const [, dragRef] = useDrag(
|
useEffect(() => {
|
||||||
() => ({
|
if (isEditing) {
|
||||||
type: ItemTypes.TAG,
|
inputRef.current?.focus()
|
||||||
item: { uuid: tag.uuid },
|
}
|
||||||
canDrag: () => {
|
}, [inputRef, isEditing])
|
||||||
return true
|
|
||||||
},
|
const onSubtagInput = useCallback((e) => {
|
||||||
collect: (monitor) => ({
|
const value = (e.target as HTMLInputElement).value
|
||||||
isDragging: !!monitor.isDragging(),
|
setSubtagTitle(value)
|
||||||
}),
|
}, [])
|
||||||
|
|
||||||
|
const onSubtagInputBlur = useCallback(() => {
|
||||||
|
tagsState.createSubtagAndAssignParent(tag, subtagTitle).catch(console.error)
|
||||||
|
setSubtagTitle('')
|
||||||
|
}, [subtagTitle, tag, tagsState])
|
||||||
|
|
||||||
|
const onSubtagKeyDown: KeyboardEventHandler = useCallback(
|
||||||
|
(e) => {
|
||||||
|
if (e.key === KeyboardKey.Enter) {
|
||||||
|
e.preventDefault()
|
||||||
|
subtagInputRef.current?.blur()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[subtagInputRef],
|
||||||
|
)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (isAddingSubtag) {
|
||||||
|
subtagInputRef.current?.focus()
|
||||||
|
}
|
||||||
|
}, [subtagInputRef, isAddingSubtag])
|
||||||
|
|
||||||
|
const [, dragRef] = useDrag(
|
||||||
|
() => ({
|
||||||
|
type: ItemTypes.TAG,
|
||||||
|
item: { uuid: tag.uuid },
|
||||||
|
canDrag: () => {
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
collect: (monitor) => ({
|
||||||
|
isDragging: !!monitor.isDragging(),
|
||||||
}),
|
}),
|
||||||
[tag],
|
}),
|
||||||
)
|
[tag],
|
||||||
|
)
|
||||||
|
|
||||||
const [{ isOver, canDrop }, dropRef] = useDrop<DropItem, void, DropProps>(
|
const [{ isOver, canDrop }, dropRef] = useDrop<DropItem, void, DropProps>(
|
||||||
() => ({
|
() => ({
|
||||||
accept: ItemTypes.TAG,
|
accept: ItemTypes.TAG,
|
||||||
canDrop: (item) => {
|
canDrop: (item) => {
|
||||||
return tagsState.isValidTagParent(tag, item as SNTag)
|
return tagsState.isValidTagParent(tag, item as SNTag)
|
||||||
},
|
},
|
||||||
drop: (item) => {
|
drop: (item) => {
|
||||||
if (!hasFolders) {
|
if (!hasFolders) {
|
||||||
premiumModal.activate(TAG_FOLDERS_FEATURE_NAME)
|
premiumModal.activate(TAG_FOLDERS_FEATURE_NAME)
|
||||||
return
|
|
||||||
}
|
|
||||||
tagsState.assignParent(item.uuid, tag.uuid).catch(console.error)
|
|
||||||
},
|
|
||||||
collect: (monitor) => ({
|
|
||||||
isOver: !!monitor.isOver(),
|
|
||||||
canDrop: !!monitor.canDrop(),
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
[tag, tagsState, hasFolders, premiumModal],
|
|
||||||
)
|
|
||||||
|
|
||||||
const readyToDrop = isOver && canDrop
|
|
||||||
|
|
||||||
const toggleContextMenu: MouseEventHandler<HTMLAnchorElement> = useCallback(
|
|
||||||
(event) => {
|
|
||||||
event.preventDefault()
|
|
||||||
event.stopPropagation()
|
|
||||||
|
|
||||||
if (!menuButtonRef.current) {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
tagsState.assignParent(item.uuid, tag.uuid).catch(console.error)
|
||||||
const contextMenuOpen = tagsState.contextMenuOpen
|
|
||||||
const menuButtonRect = menuButtonRef.current?.getBoundingClientRect()
|
|
||||||
|
|
||||||
if (contextMenuOpen) {
|
|
||||||
tagsState.setContextMenuOpen(false)
|
|
||||||
} else {
|
|
||||||
onContextMenu(tag, menuButtonRect.right, menuButtonRect.top)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
[onContextMenu, tagsState, tag],
|
collect: (monitor) => ({
|
||||||
)
|
isOver: !!monitor.isOver(),
|
||||||
|
canDrop: !!monitor.canDrop(),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
[tag, tagsState, hasFolders, premiumModal],
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
const readyToDrop = isOver && canDrop
|
||||||
<>
|
|
||||||
<button
|
const toggleContextMenu: MouseEventHandler<HTMLAnchorElement> = useCallback(
|
||||||
className={`tag focus:shadow-inner ${isSelected ? 'selected' : ''} ${readyToDrop ? 'is-drag-over' : ''}`}
|
(event) => {
|
||||||
onClick={selectCurrentTag}
|
event.preventDefault()
|
||||||
ref={dragRef}
|
event.stopPropagation()
|
||||||
style={{
|
|
||||||
paddingLeft: `${
|
if (!menuButtonRef.current) {
|
||||||
isCollapsed
|
return
|
||||||
? level * PADDING_PER_LEVEL_WHEN_COLLAPSED_PX + PADDING_BASE_WHEN_COLLAPSED_PX
|
}
|
||||||
: level * PADDING_PER_LEVEL_PX + PADDING_BASE_PX
|
|
||||||
}px`,
|
const contextMenuOpen = tagsState.contextMenuOpen
|
||||||
}}
|
const menuButtonRect = menuButtonRef.current?.getBoundingClientRect()
|
||||||
onContextMenu={(e) => {
|
|
||||||
e.preventDefault()
|
if (contextMenuOpen) {
|
||||||
onContextMenu(tag, e.clientX, e.clientY)
|
tagsState.setContextMenuOpen(false)
|
||||||
}}
|
} else {
|
||||||
>
|
onContextMenu(tag, menuButtonRect.right, menuButtonRect.top)
|
||||||
<div className="tag-info" title={title} ref={dropRef}>
|
}
|
||||||
{hasAtLeastOneFolder && (
|
},
|
||||||
<div className="tag-fold-container">
|
[onContextMenu, tagsState, tag],
|
||||||
<a
|
)
|
||||||
role="button"
|
|
||||||
className={`tag-fold focus:shadow-inner ${showChildren ? 'opened' : 'closed'} ${
|
return (
|
||||||
!hasChildren ? 'invisible' : ''
|
<>
|
||||||
}`}
|
<button
|
||||||
onClick={hasChildren ? toggleChildren : undefined}
|
className={`tag focus:shadow-inner ${isSelected ? 'selected' : ''} ${readyToDrop ? 'is-drag-over' : ''}`}
|
||||||
>
|
onClick={selectCurrentTag}
|
||||||
<Icon className={'text-neutral'} type={showChildren ? 'menu-arrow-down-alt' : 'menu-arrow-right'} />
|
ref={dragRef}
|
||||||
</a>
|
style={{
|
||||||
</div>
|
paddingLeft: `${level * PADDING_PER_LEVEL_PX + PADDING_BASE_PX}px`,
|
||||||
)}
|
}}
|
||||||
<div
|
onContextMenu={(e) => {
|
||||||
className={classNames('tag-icon draggable mr-2', isCollapsed ? 'md-only:!hidden lg-only:!hidden' : '')}
|
e.preventDefault()
|
||||||
ref={dragRef}
|
onContextMenu(tag, e.clientX, e.clientY)
|
||||||
>
|
}}
|
||||||
<Icon type="hashtag" className={`${isSelected ? 'text-info' : 'text-neutral'}`} />
|
>
|
||||||
</div>
|
<div className="tag-info" title={title} ref={dropRef}>
|
||||||
{isEditing ? (
|
{hasAtLeastOneFolder && (
|
||||||
<input
|
<div className="tag-fold-container">
|
||||||
className={classNames(
|
|
||||||
'title editing focus:shadow-none focus:outline-none',
|
|
||||||
isCollapsed ? 'md-only:!w-min lg-only:!w-min' : '',
|
|
||||||
)}
|
|
||||||
id={`react-tag-${tag.uuid}`}
|
|
||||||
onBlur={onBlur}
|
|
||||||
onInput={onInput}
|
|
||||||
value={title}
|
|
||||||
onKeyDown={onKeyDown}
|
|
||||||
spellCheck={false}
|
|
||||||
ref={inputRef}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<div
|
|
||||||
className={classNames(
|
|
||||||
'title overflow-hidden text-left focus:shadow-none focus:outline-none',
|
|
||||||
isCollapsed ? 'md-only:!w-min lg-only:!w-min' : '',
|
|
||||||
)}
|
|
||||||
id={`react-tag-${tag.uuid}`}
|
|
||||||
>
|
|
||||||
{title}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<div className="flex items-center">
|
|
||||||
<a
|
<a
|
||||||
role="button"
|
role="button"
|
||||||
className={`mr-2 cursor-pointer border-0 bg-transparent hover:bg-contrast focus:shadow-inner ${
|
className={`tag-fold focus:shadow-inner ${showChildren ? 'opened' : 'closed'} ${
|
||||||
isSelected ? 'visible' : 'invisible'
|
!hasChildren ? 'invisible' : ''
|
||||||
}`}
|
}`}
|
||||||
onClick={toggleContextMenu}
|
onClick={hasChildren ? toggleChildren : undefined}
|
||||||
ref={menuButtonRef}
|
|
||||||
>
|
>
|
||||||
<Icon type="more" className="text-neutral" />
|
<Icon className={'text-neutral'} type={showChildren ? 'menu-arrow-down-alt' : 'menu-arrow-right'} />
|
||||||
</a>
|
</a>
|
||||||
<div className="count">{noteCounts.get()}</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
|
<div className={'tag-icon draggable mr-2'} ref={dragRef}>
|
||||||
|
<Icon type="hashtag" className={`${isSelected ? 'text-info' : 'text-neutral'}`} />
|
||||||
</div>
|
</div>
|
||||||
|
{isEditing ? (
|
||||||
|
<input
|
||||||
|
className={'title editing focus:shadow-none focus:outline-none'}
|
||||||
|
id={`react-tag-${tag.uuid}`}
|
||||||
|
onBlur={onBlur}
|
||||||
|
onInput={onInput}
|
||||||
|
value={title}
|
||||||
|
onKeyDown={onKeyDown}
|
||||||
|
spellCheck={false}
|
||||||
|
ref={inputRef}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<div
|
||||||
|
className={'title overflow-hidden text-left focus:shadow-none focus:outline-none'}
|
||||||
|
id={`react-tag-${tag.uuid}`}
|
||||||
|
>
|
||||||
|
{title}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div className="flex items-center">
|
||||||
|
<a
|
||||||
|
role="button"
|
||||||
|
className={`mr-2 cursor-pointer border-0 bg-transparent hover:bg-contrast focus:shadow-inner ${
|
||||||
|
isSelected ? 'visible' : 'invisible'
|
||||||
|
}`}
|
||||||
|
onClick={toggleContextMenu}
|
||||||
|
ref={menuButtonRef}
|
||||||
|
>
|
||||||
|
<Icon type="more" className="text-neutral" />
|
||||||
|
</a>
|
||||||
|
<div className="count">{noteCounts.get()}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className={`meta ${hasAtLeastOneFolder ? 'with-folders' : ''}`}>
|
<div className={`meta ${hasAtLeastOneFolder ? 'with-folders' : ''}`}>
|
||||||
{tag.conflictOf && <div className="danger text-[0.625rem] font-bold">Conflicted Copy {tag.conflictOf}</div>}
|
{tag.conflictOf && <div className="danger text-[0.625rem] font-bold">Conflicted Copy {tag.conflictOf}</div>}
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
{isAddingSubtag && (
|
{isAddingSubtag && (
|
||||||
<div
|
<div
|
||||||
className="tag overflow-hidden"
|
className="tag overflow-hidden"
|
||||||
style={{
|
style={{
|
||||||
paddingLeft: `${(level + 1) * PADDING_PER_LEVEL_PX + PADDING_BASE_PX}px`,
|
paddingLeft: `${(level + 1) * PADDING_PER_LEVEL_PX + PADDING_BASE_PX}px`,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className="tag-info">
|
<div className="tag-info">
|
||||||
<div className="flex h-full min-w-[22px] items-center border-0 bg-transparent p-0" />
|
<div className="flex h-full min-w-[22px] items-center border-0 bg-transparent p-0" />
|
||||||
<div className="tag-icon mr-1">
|
<div className="tag-icon mr-1">
|
||||||
<Icon type="hashtag" className="mr-1 text-neutral" />
|
<Icon type="hashtag" className="mr-1 text-neutral" />
|
||||||
</div>
|
|
||||||
<input
|
|
||||||
className="title w-full focus:shadow-none focus:outline-none"
|
|
||||||
type="text"
|
|
||||||
ref={subtagInputRef}
|
|
||||||
onBlur={onSubtagInputBlur}
|
|
||||||
onKeyDown={onSubtagKeyDown}
|
|
||||||
value={subtagTitle}
|
|
||||||
onInput={onSubtagInput}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
<input
|
||||||
|
className="title w-full focus:shadow-none focus:outline-none"
|
||||||
|
type="text"
|
||||||
|
ref={subtagInputRef}
|
||||||
|
onBlur={onSubtagInputBlur}
|
||||||
|
onKeyDown={onSubtagKeyDown}
|
||||||
|
value={subtagTitle}
|
||||||
|
onInput={onSubtagInput}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
</div>
|
||||||
{showChildren && (
|
)}
|
||||||
<>
|
{showChildren && (
|
||||||
{childrenTags.map((tag) => {
|
<>
|
||||||
return (
|
{childrenTags.map((tag) => {
|
||||||
<TagsListItem
|
return (
|
||||||
level={level + 1}
|
<TagsListItem
|
||||||
key={tag.uuid}
|
level={level + 1}
|
||||||
tag={tag}
|
key={tag.uuid}
|
||||||
tagsState={tagsState}
|
tag={tag}
|
||||||
features={features}
|
tagsState={tagsState}
|
||||||
onContextMenu={onContextMenu}
|
features={features}
|
||||||
isCollapsed={isCollapsed}
|
onContextMenu={onContextMenu}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
},
|
})
|
||||||
)
|
|
||||||
|
|
||||||
TagsListItem.displayName = 'TagsListItem'
|
TagsListItem.displayName = 'TagsListItem'
|
||||||
|
|||||||
@@ -5,14 +5,12 @@ import { observer } from 'mobx-react-lite'
|
|||||||
import { FunctionComponent, useCallback, useEffect, useState } from 'react'
|
import { FunctionComponent, useCallback, useEffect, useState } from 'react'
|
||||||
import TagsSectionAddButton from './TagsSectionAddButton'
|
import TagsSectionAddButton from './TagsSectionAddButton'
|
||||||
import TagsSectionTitle from './TagsSectionTitle'
|
import TagsSectionTitle from './TagsSectionTitle'
|
||||||
import { classNames } from '@/Utils/ConcatenateClassNames'
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
viewControllerManager: ViewControllerManager
|
viewControllerManager: ViewControllerManager
|
||||||
isCollapsed: boolean
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const TagsSection: FunctionComponent<Props> = ({ viewControllerManager, isCollapsed }) => {
|
const TagsSection: FunctionComponent<Props> = ({ viewControllerManager }) => {
|
||||||
const [hasMigration, setHasMigration] = useState<boolean>(false)
|
const [hasMigration, setHasMigration] = useState<boolean>(false)
|
||||||
|
|
||||||
const checkIfMigrationNeeded = useCallback(() => {
|
const checkIfMigrationNeeded = useCallback(() => {
|
||||||
@@ -55,7 +53,7 @@ const TagsSection: FunctionComponent<Props> = ({ viewControllerManager, isCollap
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<section>
|
<section>
|
||||||
<div className={classNames('section-title-bar', isCollapsed ? 'md-only:hidden lg-only:hidden' : '')}>
|
<div className={'section-title-bar'}>
|
||||||
<div className="section-title-bar-header">
|
<div className="section-title-bar-header">
|
||||||
<TagsSectionTitle
|
<TagsSectionTitle
|
||||||
features={viewControllerManager.featuresController}
|
features={viewControllerManager.featuresController}
|
||||||
@@ -68,13 +66,7 @@ const TagsSection: FunctionComponent<Props> = ({ viewControllerManager, isCollap
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<TagsList viewControllerManager={viewControllerManager} />
|
||||||
className={classNames(
|
|
||||||
'hidden',
|
|
||||||
isCollapsed ? 'mt-6 mb-7 border border-border md-only:block lg-only:block' : '',
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<TagsList viewControllerManager={viewControllerManager} isCollapsed={isCollapsed} />
|
|
||||||
</section>
|
</section>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,16 +7,15 @@ import { FunctionComponent } from 'react'
|
|||||||
type Props = {
|
type Props = {
|
||||||
tags: NavigationController
|
tags: NavigationController
|
||||||
features: FeaturesController
|
features: FeaturesController
|
||||||
className?: string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const TagsSectionAddButton: FunctionComponent<Props> = ({ tags, className = '' }) => {
|
const TagsSectionAddButton: FunctionComponent<Props> = ({ tags }) => {
|
||||||
return (
|
return (
|
||||||
<IconButton
|
<IconButton
|
||||||
focusable={true}
|
focusable={true}
|
||||||
icon="add"
|
icon="add"
|
||||||
title="Create a new tag"
|
title="Create a new tag"
|
||||||
className={`p-0 text-neutral ${className}`}
|
className="p-0 text-neutral"
|
||||||
onClick={() => tags.createNewTemplate()}
|
onClick={() => tags.createNewTemplate()}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -9,10 +9,9 @@ type Props = {
|
|||||||
features: FeaturesController
|
features: FeaturesController
|
||||||
hasMigration: boolean
|
hasMigration: boolean
|
||||||
onClickMigration: () => void
|
onClickMigration: () => void
|
||||||
className?: string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const TagsSectionTitle: FunctionComponent<Props> = ({ features, hasMigration, onClickMigration, className = '' }) => {
|
const TagsSectionTitle: FunctionComponent<Props> = ({ features, hasMigration, onClickMigration }) => {
|
||||||
const entitledToFolders = features.hasFolders
|
const entitledToFolders = features.hasFolders
|
||||||
const modal = usePremiumModal()
|
const modal = usePremiumModal()
|
||||||
|
|
||||||
@@ -23,7 +22,7 @@ const TagsSectionTitle: FunctionComponent<Props> = ({ features, hasMigration, on
|
|||||||
if (entitledToFolders) {
|
if (entitledToFolders) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className={`title text-sm ${className}`}>
|
<div className="title text-sm">
|
||||||
<span className="font-bold">Folders</span>
|
<span className="font-bold">Folders</span>
|
||||||
{hasMigration && (
|
{hasMigration && (
|
||||||
<label className="ml-1 cursor-pointer font-bold text-info" onClick={onClickMigration}>
|
<label className="ml-1 cursor-pointer font-bold text-info" onClick={onClickMigration}>
|
||||||
@@ -37,7 +36,7 @@ const TagsSectionTitle: FunctionComponent<Props> = ({ features, hasMigration, on
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className={`title text-sm ${className}`}>
|
<div className="title text-sm">
|
||||||
<span className="font-bold">Tags</span>
|
<span className="font-bold">Tags</span>
|
||||||
<Tooltip label={TAG_FOLDERS_FEATURE_TOOLTIP}>
|
<Tooltip label={TAG_FOLDERS_FEATURE_TOOLTIP}>
|
||||||
<label className="ml-1 cursor-pointer font-bold text-passive-2" onClick={showPremiumAlert}>
|
<label className="ml-1 cursor-pointer font-bold text-passive-2" onClick={showPremiumAlert}>
|
||||||
|
|||||||
@@ -67,11 +67,6 @@ $heading-height: 75px;
|
|||||||
position: relative;
|
position: relative;
|
||||||
min-width: 16ch;
|
min-width: 16ch;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
margin-right: 20px;
|
|
||||||
|
|
||||||
@media screen and (min-width: 768px) {
|
|
||||||
max-width: 16ch;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#save-status {
|
#save-status {
|
||||||
|
|||||||
@@ -132,21 +132,6 @@
|
|||||||
@include DimmedBackground(var(--sn-stylekit-info-color), 0.08);
|
@include DimmedBackground(var(--sn-stylekit-info-color), 0.08);
|
||||||
}
|
}
|
||||||
|
|
||||||
.transparent-info-color-background {
|
|
||||||
&::after {
|
|
||||||
@include DimmedBackground(var(--sn-stylekit-info-color), 0.12);
|
|
||||||
border-radius: 100px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.transparent-info-color-background-hover {
|
|
||||||
&:hover {
|
|
||||||
&::after {
|
|
||||||
@extend .transparent-info-color-background;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
svg.sk-circular-progress {
|
svg.sk-circular-progress {
|
||||||
$pi: 3.14159265358979;
|
$pi: 3.14159265358979;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user