1
- import React , { useEffect , useState } from 'react' ;
1
+ import styled from '@emotion/styled' ;
2
+ import React , { useCallback , useEffect , useState } from 'react' ;
2
3
import { Link } from 'react-router-dom' ;
3
4
import { NoteId } from '../../2-entities/Note' ;
4
5
import { useNavigator } from '../../6-hooks/useNavigator' ;
5
6
import { useNote } from '../../6-hooks/useNote' ;
6
7
import { useUsername } from '../../6-hooks/useUsername' ;
7
- import { GithubIcon } from '../atoms/GithubIcon' ;
8
8
import { IconButton } from '../atoms/IconButton' ;
9
- import './NoteItem.scss' ;
9
+ import { IconLink } from '../atoms/IconLink' ;
10
+ import { GithubIcon , TrashIcon } from '../atoms/icons' ;
11
+ import { FavoriteButton } from '../molecule/FavoriteButton' ;
12
+
13
+ const Actions = styled . div `
14
+ display: flex;
15
+ align-items: center;
16
+ gap: var(--sidebar-gap);
17
+ ` ;
18
+
19
+ const Title = styled . h5 `
20
+ flex: 1;
21
+ overflow: hidden;
22
+ white-space: nowrap;
23
+ text-overflow: ellipsis;
24
+ line-height: 1.5em;
25
+ ` ;
26
+
27
+ const NoteItemContainer = styled ( Link ) `
28
+ display: flex;
29
+ align-items: center;
30
+ cursor: pointer;
31
+ gap: var(--sidebar-gap);
32
+ padding: var(--sidebar-gap);
33
+ font-weight: 500;
34
+ // border-left: var(--status-line-width) solid var(--status-line-color);
35
+ border-bottom: 1px solid transparent;
36
+ background-color: var(--note-item-color);
37
+ user-select: none;
38
+ color: var(--fg-color);
39
+ text-decoration: none;
40
+
41
+ &:hover {
42
+ background-color: var(--bg-color-hover);
43
+ }
44
+
45
+ &:not(:hover) {
46
+ ${ Actions } {
47
+ display: none;
48
+ }
49
+
50
+ &:not(.favorite) .star {
51
+ visibility: hidden;
52
+ }
53
+ }
54
+
55
+ &.active {
56
+ color: var(--fg-color-active);
57
+ background-color: var(--bg-color-active);
58
+ }
59
+ ` ;
10
60
11
61
export function NoteItem ( { id } : { id : NoteId } ) {
12
62
const navigator = useNavigator ( ) ;
13
63
const username = useUsername ( ) ;
14
- const [ note , { toggleFavorite , remove } ] = useNote ( id ) ;
64
+ const [ note , { remove } ] = useNote ( id ) ;
15
65
const [ active , setActive ] = useState < boolean > ( navigator . isNote ( id ) ) ;
16
66
17
67
useEffect ( ( ) =>
@@ -24,64 +74,45 @@ export function NoteItem({ id }: { id: NoteId }) {
24
74
} ) ,
25
75
) ;
26
76
27
- if ( ! note ) return null ;
28
-
29
- const githubUrl = `https://github.com/${ username } /pensieve-data/blob/main/note/${ note . id } ` ;
77
+ const handleRemove = useCallback (
78
+ ( event : React . MouseEvent < HTMLButtonElement , MouseEvent > ) => {
79
+ if ( ! confirm ( `Delete ${ note ! . title } ?` ) ) {
80
+ return ;
81
+ }
30
82
31
- const cn = [
32
- 'note-item' ,
33
- note . favorite ? 'favorite' : '' ,
34
- active ? 'active' : '' ,
35
- ] ;
83
+ event . preventDefault ( ) ;
36
84
37
- const extraProps = note . group ? { 'data-group' : note . group } : { } ;
85
+ if ( navigator . isNote ( id ) ) {
86
+ navigator . goRoot ( ) ;
87
+ }
38
88
39
- const ghLink = (
40
- < a
41
- target = "_blank"
42
- href = { githubUrl }
43
- onClick = { event => event . stopPropagation ( ) }
44
- >
45
- < GithubIcon title = "Open note in Github" />
46
- </ a >
89
+ return remove ( ) ;
90
+ } ,
91
+ [ navigator , note , remove ] ,
47
92
) ;
48
93
94
+ if ( ! note ) return null ;
95
+
96
+ const githubUrl = `https://github.com/${ username } /pensieve-data/blob/main/note/${ note . id } ` ;
97
+
49
98
return (
50
- < Link className = { cn . join ( ' ' ) } { ...extraProps } to = { navigator . toNote ( note ) } >
51
- < div className = "star-part" >
99
+ < NoteItemContainer
100
+ to = { navigator . toNote ( note ) }
101
+ className = { `${ active ? 'active' : '' } ${ note . favorite ? 'favorite' : '' } ` }
102
+ >
103
+ < FavoriteButton id = { note . id } className = "star" />
104
+ < Title > { note . title } </ Title >
105
+
106
+ < Actions >
107
+ < IconLink
108
+ icon = { < GithubIcon title = "Open note in Github" /> }
109
+ href = { githubUrl }
110
+ />
52
111
< IconButton
53
- icon = { note . favorite ? 'star' : 'far star' }
54
- onClick = { applyFavorite }
112
+ icon = { < TrashIcon title = "Remove note" /> }
113
+ onClick = { handleRemove }
55
114
/>
56
- </ div >
57
-
58
- < h5 className = "title-part" > { note . title } </ h5 >
59
-
60
- < div className = "actions-part" >
61
- { ghLink }
62
- < IconButton icon = "trash" onClick = { applyRemove } />
63
- </ div >
64
- </ Link >
115
+ </ Actions >
116
+ </ NoteItemContainer >
65
117
) ;
66
-
67
- type ClickEvent = React . MouseEvent < HTMLButtonElement , MouseEvent > ;
68
-
69
- function applyRemove ( event : ClickEvent ) {
70
- if ( ! confirm ( `Delete ${ note ! . title } ?` ) ) {
71
- return ;
72
- }
73
-
74
- event . preventDefault ( ) ;
75
-
76
- if ( navigator . isNote ( id ) ) {
77
- navigator . goRoot ( ) ;
78
- }
79
-
80
- return remove ( ) ;
81
- }
82
-
83
- function applyFavorite ( event : ClickEvent ) {
84
- event . preventDefault ( ) ;
85
- toggleFavorite ( ) ;
86
- }
87
118
}
0 commit comments