1
1
import { Button , Card , Elevation , H4 , H5 , Icon , Tag } from '@blueprintjs/core'
2
2
import { Tooltip2 } from '@blueprintjs/popover2'
3
3
4
+ import clsx from 'clsx'
4
5
import { handleCopyShortCode , handleDownloadJSON } from 'services/operation'
5
6
6
7
import { ReLink } from 'components/ReLink'
@@ -19,22 +20,21 @@ export const NeoOperationCard = ({ operation }: { operation: Operation }) => {
19
20
const { data : levels } = useLevels ( )
20
21
21
22
return (
22
- < ReLink search = { { op : operation . id } } className = "no-underline" >
23
- < Card
24
- interactive = { true }
25
- elevation = { Elevation . TWO }
26
- className = "flex flex-col gap-2"
27
- >
23
+ < Card
24
+ interactive = { true }
25
+ elevation = { Elevation . TWO }
26
+ className = "relative flex flex-col gap-2"
27
+ >
28
+ < ReLink search = { { op : operation . id } } className = "block no-underline" >
28
29
< div className = "flex" >
29
30
< Tooltip2
30
31
content = { operation . parsedContent . doc . title }
31
32
className = "grow flex-1 whitespace-nowrap overflow-hidden text-ellipsis"
32
33
>
33
- < H4 className = "p-0 m-0 whitespace-nowrap overflow-hidden text-ellipsis" >
34
+ < H4 className = "p-0 m-0 mr-20 whitespace-nowrap overflow-hidden text-ellipsis" >
34
35
{ operation . parsedContent . doc . title }
35
36
</ H4 >
36
37
</ Tooltip2 >
37
- < CardActions operation = { operation } />
38
38
</ div >
39
39
< div className = "flex items-center text-slate-900" >
40
40
< div className = "flex flex-wrap" >
@@ -105,28 +105,30 @@ export const NeoOperationCard = ({ operation }: { operation: Operation }) => {
105
105
</ Tooltip2 >
106
106
</ div >
107
107
</ div >
108
- </ Card >
109
- </ ReLink >
108
+ </ ReLink >
109
+
110
+ < CardActions className = "absolute top-4 right-4" operation = { operation } />
111
+ </ Card >
110
112
)
111
113
}
112
114
113
115
export const OperationCard = ( { operation } : { operation : Operation } ) => {
114
116
const { data : levels } = useLevels ( )
115
117
116
118
return (
117
- < ReLink
118
- search = { { op : operation . id } }
119
- className = "block mb-4 sm:mb-2 last:mb-0 no-underline"
119
+ < Card
120
+ interactive = { true }
121
+ elevation = { Elevation . TWO }
122
+ className = "relative mb-4 sm:mb-2 last:mb-0"
120
123
>
121
- < Card interactive = { true } elevation = { Elevation . TWO } >
124
+ < ReLink search = { { op : operation . id } } className = "block no-underline" >
122
125
< div className = "flex flex-wrap mb-4 sm:mb-2" >
123
126
{ /* title */ }
124
127
< div className = "flex flex-col gap-3" >
125
128
< div className = "flex gap-2" >
126
129
< H4 className = "inline-block pb-1 border-b-2 border-zinc-200 border-solid mb-2" >
127
130
{ operation . parsedContent . doc . title }
128
131
</ H4 >
129
- < CardActions operation = { operation } />
130
132
</ div >
131
133
< H5 className = "flex items-center text-slate-900 -mt-3" >
132
134
< EDifficultyLevel
@@ -141,43 +143,40 @@ export const OperationCard = ({ operation }: { operation: Operation }) => {
141
143
</ H5 >
142
144
</ div >
143
145
144
- < div className = "lg:flex-1 hidden " />
146
+ < div className = "grow basis-full xl:basis-0 " />
145
147
146
148
{ /* meta */ }
147
- < div className = "flex flex-col flex-1 gap-y-1.5 gap-x-4" >
148
- < div className = "flex flex-wrap sm:justify-end items-center gap-x-4 gap-y-1 text-zinc-500" >
149
- < div className = "flex items-center gap-1.5" >
150
- < Icon icon = "star" />
151
- < OperationRating
152
- className = "text-sm"
153
- operation = { operation }
154
- layout = "horizontal"
155
- />
149
+ < div className = "flex flex-wrap items-start gap-x-4 gap-y-1 text-zinc-500" >
150
+ < div className = "flex items-center gap-1.5" >
151
+ < Icon icon = "star" />
152
+ < OperationRating
153
+ className = "text-sm"
154
+ operation = { operation }
155
+ layout = "horizontal"
156
+ />
157
+ </ div >
158
+
159
+ < Tooltip2 placement = "top" content = { `访问量:${ operation . views } ` } >
160
+ < div >
161
+ < Icon icon = "eye-open" className = "mr-1.5" />
162
+ < span > { operation . views } </ span >
156
163
</ div >
164
+ </ Tooltip2 >
157
165
158
- < Tooltip2 placement = "top" content = { `访问量:${ operation . views } ` } >
159
- < div >
160
- < Icon icon = "eye-open" className = "mr-1.5" />
161
- < span > { operation . views } </ span >
162
- </ div >
163
- </ Tooltip2 >
166
+ < div >
167
+ < Icon icon = "time" className = "mr-1.5" />
168
+ < RelativeTime
169
+ Tooltip2Props = { { placement : 'top' } }
170
+ moment = { operation . uploadTime }
171
+ />
172
+ </ div >
164
173
174
+ < Tooltip2 placement = "top" content = { `作者:${ operation . uploader } ` } >
165
175
< div >
166
- < Icon icon = "time" className = "mr-1.5" />
167
- < RelativeTime
168
- Tooltip2Props = { { placement : 'top' } }
169
- moment = { operation . uploadTime }
170
- />
176
+ < Icon icon = "user" className = "mr-1.5" />
177
+ < span > { operation . uploader } </ span >
171
178
</ div >
172
- </ div >
173
- < div className = "text-zinc-500 self-end" >
174
- < Tooltip2 placement = "top" content = { `作者:${ operation . uploader } ` } >
175
- < div >
176
- < Icon icon = "user" className = "mr-1.5" />
177
- < span > { operation . uploader } </ span >
178
- </ div >
179
- </ Tooltip2 >
180
- </ div >
179
+ </ Tooltip2 >
181
180
</ div >
182
181
</ div >
183
182
< div className = "flex md:flex-row flex-col gap-4" >
@@ -195,8 +194,13 @@ export const OperationCard = ({ operation }: { operation: Operation }) => {
195
194
< OperatorTags operation = { operation } />
196
195
</ div >
197
196
</ div >
198
- </ Card >
199
- </ ReLink >
197
+ </ ReLink >
198
+
199
+ < CardActions
200
+ className = "absolute top-4 xl:top-12 right-[18px]"
201
+ operation = { operation }
202
+ />
203
+ </ Card >
200
204
)
201
205
}
202
206
@@ -230,16 +234,15 @@ const OperatorTags = ({ operation }: { operation: Operation }) => {
230
234
)
231
235
}
232
236
233
- const CardActions = ( { operation } : { operation : Operation } ) => {
237
+ const CardActions = ( {
238
+ className,
239
+ operation,
240
+ } : {
241
+ className ?: string
242
+ operation : Operation
243
+ } ) => {
234
244
return (
235
- // eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
236
- < div
237
- className = "flex gap-1"
238
- onClick = { ( e ) => {
239
- // 避免点击按钮时触发卡片的链接跳转
240
- e . stopPropagation ( )
241
- } }
242
- >
245
+ < div className = { clsx ( 'flex gap-1' , className ) } >
243
246
< Tooltip2
244
247
placement = "bottom"
245
248
content = {
@@ -249,10 +252,7 @@ const CardActions = ({ operation }: { operation: Operation }) => {
249
252
< Button
250
253
small
251
254
icon = "download"
252
- onClick = { ( e ) => {
253
- e . stopPropagation ( )
254
- handleDownloadJSON ( operation . parsedContent )
255
- } }
255
+ onClick = { ( ) => handleDownloadJSON ( operation . parsedContent ) }
256
256
/>
257
257
</ Tooltip2 >
258
258
< Tooltip2
@@ -264,10 +264,7 @@ const CardActions = ({ operation }: { operation: Operation }) => {
264
264
< Button
265
265
small
266
266
icon = "clipboard"
267
- onClick = { ( e ) => {
268
- e . stopPropagation ( )
269
- handleCopyShortCode ( operation )
270
- } }
267
+ onClick = { ( ) => handleCopyShortCode ( operation ) }
271
268
/>
272
269
</ Tooltip2 >
273
270
< Tooltip2
0 commit comments