First pass at hover actions on the library items

This commit is contained in:
Jackson Harper 2023-06-22 11:04:45 +08:00
parent 6ef970a6e4
commit fa0efe7794
9 changed files with 187 additions and 44 deletions

View file

@ -242,15 +242,29 @@ export const Button = styled('button', {
border: 'none',
cursor: 'pointer',
'&:hover': {
opacity: 0.8,
opacity: 0.7,
},
},
articleActionIcon: {
bg: 'transparent',
border: 'none',
cursor: 'pointer',
padding: '4px',
borderRadius: '5px',
'&:hover': {
opacity: 0.8,
opacity: 0.7,
},
},
hoverActionIcon: {
bg: 'transparent',
border: 'none',
cursor: 'pointer',
padding: '4px',
borderRadius: '5px',
'&:hover': {
opacity: 0.7,
},
},
ghost: {

View file

@ -8,7 +8,7 @@ import {
useState,
} from 'react'
import { formattedShortTime } from '../../lib/dateFormatting'
import { HStack, SpanBox, VStack } from '../elements/LayoutPrimitives'
import { Box, HStack, SpanBox, VStack } from '../elements/LayoutPrimitives'
import MarkdownIt from 'markdown-it'
import MdEditor, { Plugins } from 'react-markdown-editor-lite'
@ -307,7 +307,7 @@ export function MarkdownNote(props: MarkdownNote): JSX.Element {
p: '5px',
width: '100%',
fontSize: '15px',
borderRadius: '3px',
// borderRadius: '3px',
marginTop: props.fillBackground || !props.text ? '10px' : '0px',
paddingLeft:
@ -323,7 +323,7 @@ export function MarkdownNote(props: MarkdownNote): JSX.Element {
? '5px'
: '0px',
color: props.text ? '$thHighContrast' : '#898989',
border: props.text ? 'unset' : '1px solid $thBorderColor',
// border: props.text ? 'unset' : '1px solid $thBorderColor',
background:
props.text && props.fillBackground ? '$thBackground5' : 'unset',
'> *': {

View file

@ -1,5 +1,5 @@
/* eslint-disable react/no-children-prop */
import { BookOpen, PencilLine } from 'phosphor-react'
import { BookOpen, CaretDown, PencilLine } from 'phosphor-react'
import { useState } from 'react'
import type { Highlight } from '../../lib/networking/fragments/highlightFragment'
import { LabelChip } from '../elements/LabelChip'
@ -37,24 +37,38 @@ export function HighlightView(props: HighlightViewProps): JSX.Element {
width: '100%',
height: '100%',
alignItems: 'stretch',
background: '$thBackground',
borderRadius: '6px',
boxShadow: '0px 4px 4px rgba(33, 33, 33, 0.1)',
}}
// <Box
// css={{
// width: '100%',
// height: '100%',
// padding: '10px',
// background: '$thBackground',
// borderRadius: '6px',
// boxShadow: '0px 4px 4px rgba(33, 33, 33, 0.1)',
// }}
// >
>
<VStack css={{ minHeight: '100%', width: '10px' }}>
<Box
css={{
mt: '5px',
width: '10px',
height: '10px',
background: '#FFD234',
borderRadius: '7px',
}}
/>
<VStack
css={{
minHeight: '100%',
width: '10px',
pt: '15px',
pl: '10px',
}}
>
<CaretDown size={15} color="#898989" weight="fill" />
<Box
css={{
width: '2px',
flexGrow: '1',
background: '#FFD234',
marginLeft: '4px',
marginTop: '5px',
marginLeft: '6px',
flex: '1',
marginBottom: '10px',
}}
@ -63,8 +77,8 @@ export function HighlightView(props: HighlightViewProps): JSX.Element {
<VStack
css={{
width: '100%',
padding: '0px',
paddingLeft: '15px',
padding: '10px',
paddingLeft: '20px',
}}
>
<StyledQuote>

View file

@ -18,16 +18,12 @@ export const MenuStyle = {
display: 'flex',
marginLeft: 'auto',
height: '30px',
width: '30px',
width: '150px',
mt: '-5px',
mr: '-5px',
pt: '2px',
alignItems: 'center',
justifyContent: 'center',
borderRadius: '1000px',
'&:hover': {
bg: '$thBackground4',
},
}
export const TitleStyle = {

View file

@ -5,7 +5,14 @@ import { CoverImage } from '../../elements/CoverImage'
import dayjs from 'dayjs'
import relativeTime from 'dayjs/plugin/relativeTime'
import { useCallback, useState } from 'react'
import { DotsThreeVertical } from 'phosphor-react'
import {
ArchiveBox,
DotsThree,
DotsThreeVertical,
Tag,
Trash,
Tray,
} from 'phosphor-react'
import Link from 'next/link'
import { CardMenu } from '../CardMenu'
import {
@ -19,6 +26,8 @@ import {
TitleStyle,
} from './LibraryCardStyles'
import { sortedLabels } from '../../../lib/labelsSort'
import { Button } from '../../elements/Button'
import { theme } from '../../tokens/stitches.config'
dayjs.extend(relativeTime)
@ -133,19 +142,63 @@ const LibraryGridCardContent = (props: LinkedItemCardProps): JSX.Element => {
<Box
css={{
...MenuStyle,
gap: '10px',
px: '20px',
borderRadius: '1000px',
bg: 'red',
visibility: props.isHovered || menuOpen ? 'unset' : 'hidden',
'@media (hover: none)': {
visibility: 'unset',
},
}}
>
<Button
style="hoverActionIcon"
onClick={(event) => {
const action = props.item.isArchived ? 'unarchive' : 'archive'
props.handleAction(action)
event.preventDefault()
}}
>
{props.item.isArchived ? (
<Tray
size={18}
color={theme.colors.thHighContrast.toString()}
/>
) : (
<ArchiveBox
size={18}
color={theme.colors.thHighContrast.toString()}
/>
)}
</Button>
<Button
style="hoverActionIcon"
onClick={(event) => {
props.handleAction('delete')
event.preventDefault()
}}
>
<Trash size={18} color={theme.colors.thHighContrast.toString()} />
</Button>
<Button
style="hoverActionIcon"
onClick={(event) => {
props.handleAction('set-labels')
event.preventDefault()
}}
>
<Tag size={18} color={theme.colors.thHighContrast.toString()} />
</Button>
<CardMenu
item={props.item}
viewer={props.viewer}
onOpenChange={(open) => setMenuOpen(open)}
actionHandler={props.handleAction}
triggerElement={
<DotsThreeVertical size={25} weight="bold" color="#ADADAD" />
<DotsThree size={25} weight="bold" color="#ADADAD" />
}
/>
</Box>

View file

@ -2,7 +2,14 @@ import { Box, VStack, HStack, SpanBox } from '../../elements/LayoutPrimitives'
import { LabelChip } from '../../elements/LabelChip'
import type { LinkedItemCardProps } from './CardTypes'
import { useCallback, useState } from 'react'
import { DotsThree } from 'phosphor-react'
import {
Archive,
ArchiveBox,
DotsThree,
Tag,
Trash,
Tray,
} from 'phosphor-react'
import Link from 'next/link'
import { CardMenu } from '../CardMenu'
import {
@ -16,6 +23,8 @@ import {
} from './LibraryCardStyles'
import { sortedLabels } from '../../../lib/labelsSort'
import { LIBRARY_LEFT_MENU_WIDTH } from '../../templates/homeFeed/LibraryFilterMenu'
import { Button } from '../../elements/Button'
import { theme } from '../../tokens/stitches.config'
export function LibraryListCard(props: LinkedItemCardProps): JSX.Element {
const [isHovered, setIsHovered] = useState(false)
@ -99,12 +108,52 @@ export function LibraryListCardContent(
<Box
css={{
...MenuStyle,
gap: '10px',
px: '20px',
visibility: props.isHovered || menuOpen ? 'unset' : 'hidden',
'@media (hover: none)': {
visibility: 'unset',
},
}}
>
<Button
style="hoverActionIcon"
onClick={(event) => {
const action = props.item.isArchived ? 'unarchive' : 'archive'
props.handleAction(action)
event.preventDefault()
}}
>
{props.item.isArchived ? (
<Tray
size={18}
color={theme.colors.thHighContrast.toString()}
/>
) : (
<ArchiveBox
size={18}
color={theme.colors.thHighContrast.toString()}
/>
)}
</Button>
<Button
style="hoverActionIcon"
onClick={(event) => {
props.handleAction('delete')
event.preventDefault()
}}
>
<Trash size={18} color={theme.colors.thHighContrast.toString()} />
</Button>
<Button
style="hoverActionIcon"
onClick={(event) => {
props.handleAction('set-labels')
event.preventDefault()
}}
>
<Tag size={18} color={theme.colors.thHighContrast.toString()} />
</Button>
<CardMenu
item={props.item}
viewer={props.viewer}

View file

@ -3,7 +3,7 @@ import { StyledText } from '../../elements/StyledText'
import { theme } from '../../tokens/stitches.config'
import type { Highlight } from '../../../lib/networking/fragments/highlightFragment'
import { useCallback, useEffect, useMemo, useReducer, useState } from 'react'
import { BookOpen, PencilLine, X } from 'phosphor-react'
import { BookOpen, CaretDown, PencilLine, X } from 'phosphor-react'
import { updateHighlightMutation } from '../../../lib/networking/mutations/updateHighlightMutation'
import { showErrorToast, showSuccessToast } from '../../../lib/toastHelpers'
import { diff_match_patch } from 'diff-match-patch'
@ -19,6 +19,7 @@ import { TrashIcon } from '../../elements/images/TrashIcon'
import { UserBasicData } from '../../../lib/networking/queries/useGetViewerQuery'
import { ReadableItem } from '../../../lib/networking/queries/useGetLibraryItemsQuery'
import { SetHighlightLabelsModalPresenter } from './SetLabelsModalPresenter'
import { Button } from '../../elements/Button'
type NotebookProps = {
viewer: UserBasicData
@ -290,21 +291,32 @@ export function Notebook(props: NotebookProps): JSX.Element {
css={{ height: '100%', width: '100%', p: '20px' }}
>
<TitledSection
title="ARTICLE NOTES"
title="Article Notes"
editMode={notesEditMode == 'edit'}
setEditMode={(edit) => setNotesEditMode(edit ? 'edit' : 'preview')}
/>
<HighlightNoteBox
mode={notesEditMode}
sizeMode={props.sizeMode}
setEditMode={setNotesEditMode}
text={annotations.note?.annotation}
placeHolder="Add notes to this document..."
saveText={handleSaveNoteText}
/>
<Box
css={{
width: '100%',
height: '100%',
padding: '10px',
background: '$thBackground',
borderRadius: '6px',
boxShadow: '0px 4px 4px rgba(33, 33, 33, 0.1)',
}}
>
<HighlightNoteBox
mode={notesEditMode}
sizeMode={props.sizeMode}
setEditMode={setNotesEditMode}
text={annotations.note?.annotation}
placeHolder="Add notes to this document..."
saveText={handleSaveNoteText}
/>
</Box>
<SpanBox css={{ mt: '10px', mb: '25px' }} />
<Box css={{ width: '100%' }}>
<TitledSection title="HIGHLIGHTS" />
<TitledSection title="Highlights" />
{sortedHighlights.map((highlight) => (
<HighlightViewItem
@ -417,19 +429,19 @@ function TitledSection(props: TitledSectionProps): JSX.Element {
return (
<>
<HStack
css={{ width: '100%', borderBottom: '1px solid $thBorderColor' }}
alignment="start"
css={{ width: '100%', gap: '10px' }}
alignment="center"
distribution="start"
>
{/* <CaretDown size={12} color={theme.colors.thNotebookSubtle.toString()} /> */}
<StyledText
css={{
fontFamily: '$display',
pt: '2px',
fontFamily: '$inter',
fontStyle: 'normal',
fontWeight: '700',
fontSize: '12px',
lineHeight: '20px',
color: '#898989',
marginBottom: '1px',
color: '$thNotebookSubtle',
}}
>
{props.title}

View file

@ -88,6 +88,7 @@ export function NotebookModal(props: NotebookModalProps): JSX.Element {
}}
css={{
overflow: 'auto',
bg: '$thLibraryBackground',
height: sizeMode === 'normal' ? 'unset' : '100%',
maxWidth: sizeMode === 'normal' ? '640px' : '100%',
minHeight: sizeMode === 'normal' ? '525px' : 'unset',

View file

@ -180,6 +180,8 @@ export const { styled, css, theme, getCssText, globalCss, keyframes, config } =
thLibraryMenuUnselected: '#898989',
thLibrarySelectionColor: '#FFEA9F',
thNotebookSubtle: '#6A6968',
thTextContrast: '#1E1E1E',
thTextContrast2: '#3D3D3D',
@ -274,6 +276,8 @@ const darkThemeSpec = {
thLibraryMenuUnselected: '#898989',
thLibrarySelectionColor: '#3D3D3D',
thNotebookSubtle: '#898989',
thTextContrast: '#FFFFFF',
thTextContrast2: '#EBEBEB',