1
1
<script setup lang="ts">
2
- import { NEmpty , NFlex , NSkeleton , NTime , NTimelineItem } from ' naive-ui' ;
2
+ import { NButtonGroup , NEmpty , NFlex , NSkeleton , NTime , NTimelineItem } from ' naive-ui' ;
3
3
4
4
import {
5
5
computed ,
@@ -115,8 +115,13 @@ const i18n = useI18n('list', 'item');
115
115
const { item, noHeader, nextHasHeader, poster, hideDate, scrollIntoView, height, color } =
116
116
toRefs (props );
117
117
118
- const onHover = (_hover : boolean ) => {
118
+ const itemRef = ref <HTMLElement & InstanceType <typeof NTimelineItem >>();
119
+
120
+ const open = ref (false );
121
+ const onHover = (_event : MouseEvent , _hover : boolean ) => {
119
122
emit (' onHover' , { item: item ?.value , hover: _hover });
123
+ itemRef ?.value ?.$el ?.focus ();
124
+ open .value = _hover && (_event .altKey || _event .ctrlKey );
120
125
};
121
126
122
127
const noHead = computed (
@@ -135,8 +140,6 @@ const year = new Date().getFullYear();
135
140
const sameYear = computed (() => date .value ?.getFullYear () === year );
136
141
const loading = computed (() => item ?.value ?.loading );
137
142
138
- const itemRef = ref <HTMLElement & InstanceType <typeof NTimelineItem >>();
139
-
140
143
onMounted (() => {
141
144
if (! scrollIntoView .value ) return ;
142
145
emit (' onScrollIntoView' , {
@@ -165,6 +168,7 @@ const onClick = (e: MouseEvent | KeyboardEvent) =>
165
168
<NTimelineItem
166
169
ref =" itemRef"
167
170
:key =" item.key"
171
+ tabindex =" 0"
168
172
class =" timeline-item"
169
173
:class =" {
170
174
'no-header': noHead,
@@ -182,8 +186,11 @@ const onClick = (e: MouseEvent | KeyboardEvent) =>
182
186
:line-type =" loading ? 'dashed' : lineType"
183
187
:color =" loading ? 'grey' : _color"
184
188
@click =" onClick"
185
- @mouseenter =" onHover(true)"
186
- @mouseleave =" onHover(false)"
189
+ @keydown.enter =" onClick"
190
+ @keydown.alt =" open = !open"
191
+ @keydown.ctrl =" open = !open"
192
+ @mouseenter =" e => onHover(e, true)"
193
+ @mouseleave =" e => onHover(e, false)"
187
194
>
188
195
<template #icon >
189
196
<slot name =" tag" />
@@ -198,6 +205,7 @@ const onClick = (e: MouseEvent | KeyboardEvent) =>
198
205
size =" small"
199
206
:theme-overrides =" { gapSmall: '0' }"
200
207
:wrap =" false"
208
+ align =" center"
201
209
>
202
210
<NFlex
203
211
v-if =" !hideDate"
@@ -250,6 +258,14 @@ const onClick = (e: MouseEvent | KeyboardEvent) =>
250
258
>
251
259
<slot :item =" item" :loading =" loading" />
252
260
</ListItemPanel >
261
+ <NButtonGroup
262
+ v-if =" $slots.buttons"
263
+ class =" tile-buttons"
264
+ :class =" { open }"
265
+ vertical
266
+ >
267
+ <slot name =" buttons" :open =" open" :item =" item" />
268
+ </NButtonGroup >
253
269
</NFlex >
254
270
</NFlex >
255
271
</template >
@@ -268,6 +284,7 @@ const onClick = (e: MouseEvent | KeyboardEvent) =>
268
284
.timeline-item {
269
285
height : var (--list-item-height , 145px );
270
286
margin : 0 1rem ;
287
+ outline : none ;
271
288
272
289
& .show-date {
273
290
margin-left : 4rem ;
@@ -286,19 +303,49 @@ const onClick = (e: MouseEvent | KeyboardEvent) =>
286
303
flex : 1 1 auto ;
287
304
margin : 0.25rem 0 ;
288
305
padding : 0.3rem 0.25rem 0.25rem ;
306
+ overflow : hidden ;
289
307
border-radius : 0.75rem ;
290
308
291
309
& :active {
292
310
background-color : var (--bg-color-30 );
293
311
box-shadow : var (--inset-box-shadow );
294
312
}
313
+
314
+ & -buttons {
315
+ position : absolute ;
316
+ right : 0 ;
317
+ z-index : layers .$in-front ;
318
+ transition : translate 0.25s var (--n-bezier );
319
+ translate : 150% ;
320
+
321
+ & :focus-within ,
322
+ & .open {
323
+ translate : 0 ;
324
+ display : flex ;
325
+ }
326
+
327
+ :first-child {
328
+ border-top-right-radius : 0.75rem ;
329
+ }
330
+
331
+ :last-child {
332
+ border-bottom-right-radius : 0.75rem ;
333
+ }
334
+ }
295
335
}
296
336
297
337
.placeholder {
298
338
flex : 1 1 auto ;
299
339
}
300
340
}
301
341
342
+ & :focus-visible .content .tile {
343
+ background-color : var (--bg-color-20 );
344
+ // stylelint-disable-next-line property-no-vendor-prefix -- necessary for safari
345
+ -webkit-backdrop-filter : var (--bg-blur-hover );
346
+ backdrop-filter : var (--bg-blur-hover );
347
+ }
348
+
302
349
.header {
303
350
position : absolute ;
304
351
top : 0 ;
@@ -311,6 +358,7 @@ const onClick = (e: MouseEvent | KeyboardEvent) =>
311
358
transition :
312
359
color 0.2s var (--n-bezier ),
313
360
border 0.2s var (--n-bezier );
361
+ pointer-events : none ;
314
362
315
363
& .today {
316
364
color : var (--color-warning );
0 commit comments