mirror of
https://github.com/omnivore-app/omnivore.git
synced 2026-03-11 08:54:26 +00:00
First pass at hover actions on the library items
This commit is contained in:
parent
6ef970a6e4
commit
fa0efe7794
9 changed files with 187 additions and 44 deletions
|
|
@ -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: {
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
'> *': {
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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 = {
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue