Skip to content

Commit 8c70a6a

Browse files
committed
fix(NcListItem): Do not use a as wrapper to prevent invalid HTML due to use of button within anchor
Signed-off-by: Ferdinand Thiessen <[email protected]>
1 parent 4a2da57 commit 8c70a6a

1 file changed

Lines changed: 94 additions & 72 deletions

File tree

src/components/NcListItem/NcListItem.vue

Lines changed: 94 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -248,66 +248,77 @@
248248
```
249249

250250
### NcListItem compact mode
251-
```
252-
<ul style="width: 350px;">
253-
<NcListItem
254-
:name="'Name of the element'"
255-
:counter-number="1"
256-
:compact="true" >
257-
<template #icon>
258-
<div class="icon-edit" />
259-
</template>
260-
<template #subname>
261-
This one is with subname
262-
</template>
263-
<template #actions>
264-
<NcActionButton>
265-
Button one
266-
</NcActionButton>
267-
<NcActionButton>
268-
Button two
269-
</NcActionButton>
270-
</template>
271-
</NcListItem>
272-
<NcListItem
273-
:name="'Name of the element'"
274-
:compact="true" >
275-
<template #icon>
276-
<div class="icon-edit" />
277-
</template>
278-
</NcListItem>
279-
<NcListItem
280-
:name="'Name of the element'"
281-
:counter-number="3"
282-
:compact="true" >
283-
<template #icon>
284-
<div class="icon-edit" />
285-
</template>
286-
<template #subname>
287-
This one is with subname
288-
</template>
289-
<template #actions>
290-
<NcActionButton>
291-
Button one
292-
</NcActionButton>
293-
<NcActionButton>
294-
Button two
295-
</NcActionButton>
296-
</template>
297-
</NcListItem>
298-
<NcListItem
299-
:name="'Name of the element'"
300-
:compact="true"
301-
:counter-number="4"
302-
href="https://nextcloud.com">
303-
<template #icon>
304-
<div class="icon-edit" />
305-
</template>
306-
<template #subname>
307-
This one is with an external link
308-
</template>
309-
</NcListItem>
310-
</ul>
251+
```vue
252+
<template>
253+
<ul style="width: 350px;">
254+
<NcListItem
255+
:name="'Name of the element'"
256+
:counter-number="1"
257+
:compact="true" >
258+
<template #icon>
259+
<IconNoteText :size="20" />
260+
</template>
261+
<template #subname>
262+
This one is with subname
263+
</template>
264+
<template #actions>
265+
<NcActionButton>
266+
Button one
267+
</NcActionButton>
268+
<NcActionButton>
269+
Button two
270+
</NcActionButton>
271+
</template>
272+
</NcListItem>
273+
<NcListItem
274+
:name="'Name of the element'"
275+
:compact="true" >
276+
<template #icon>
277+
<IconNoteText :size="20" />
278+
</template>
279+
</NcListItem>
280+
<NcListItem
281+
:name="'Name of the element'"
282+
:counter-number="3"
283+
:compact="true" >
284+
<template #icon>
285+
<IconNoteText :size="20" />
286+
</template>
287+
<template #subname>
288+
This one is with subname
289+
</template>
290+
<template #actions>
291+
<NcActionButton>
292+
Button one
293+
</NcActionButton>
294+
<NcActionButton>
295+
Button two
296+
</NcActionButton>
297+
</template>
298+
</NcListItem>
299+
<NcListItem
300+
:name="'Name of the element'"
301+
:compact="true"
302+
:counter-number="4"
303+
href="https://nextcloud.com">
304+
<template #icon>
305+
<IconNoteText :size="20" />
306+
</template>
307+
<template #subname>
308+
This one is with an external link
309+
</template>
310+
</NcListItem>
311+
</ul>
312+
</template>
313+
<script>
314+
import IconNoteText from 'vue-material-design-icons/NoteText.vue'
315+
316+
export default {
317+
components: {
318+
IconNoteText,
319+
},
320+
}
321+
</script>
311322
```
312323
</docs>
313324

@@ -320,28 +331,30 @@
320331
:exact="to ? exact : null">
321332
<li class="list-item__wrapper"
322333
:class="{ 'list-item__wrapper--active' : isActive || active }">
323-
<a :id="anchorId"
324-
ref="list-item"
325-
:href="routerLinkHref || href"
326-
:target="target || (href === '#' ? undefined : '_blank')"
327-
:rel="href === '#' ? undefined : 'noopener noreferrer'"
334+
<div ref="list-item"
328335
class="list-item"
329-
:aria-label="linkAriaLabel"
336+
tabindex="0"
330337
@mouseover="handleMouseover"
331338
@mouseleave="handleMouseleave"
332339
@focus="handleFocus"
333340
@blur="handleBlur"
334341
@keydown.tab.exact="handleTab"
335342
@click="onClick($event, navigate, routerLinkHref)"
336343
@keydown.esc="hideActions">
337-
338-
<div class="list-item-content__wrapper"
339-
:class="{ 'list-item-content__wrapper--compact': compact }">
344+
<div :class="['list-item-content__wrapper', {
345+
'list-item-content__wrapper--compact': compact
346+
}]">
340347
<!-- @slot This slot is used for the NcAvatar or icon -->
341348
<slot name="icon" />
342349

343350
<!-- Main content -->
344-
<div class="list-item-content">
351+
<a :id="anchorId || undefined"
352+
tabindex="-1"
353+
class="list-item-content"
354+
:aria-label="linkAriaLabel"
355+
:href="routerLinkHref || href"
356+
:target="target || (href === '#' ? undefined : '_blank')"
357+
:rel="href === '#' ? undefined : 'noopener noreferrer'">
345358
<div class="list-item-content__main"
346359
:class="{ 'list-item-content__main--oneline': oneLine }">
347360

@@ -383,7 +396,8 @@
383396
</span>
384397
</div>
385398
</div>
386-
</div>
399+
</a>
400+
387401
<!-- Actions -->
388402
<div v-show="forceDisplayActions || displayActionsOnHoverFocus"
389403
class="list-item-content__actions"
@@ -402,7 +416,7 @@
402416
<div v-if="$slots.extra" class="list-item__extra">
403417
<slot name="extra" />
404418
</div>
405-
</a>
419+
</div>
406420
</li>
407421
</component>
408422
</template>
@@ -704,6 +718,7 @@ export default {
704718
<style lang="scss" scoped>
705719
706720
.list-item__wrapper {
721+
display: flex;
707722
position: relative;
708723
width: 100%;
709724
@@ -738,6 +753,8 @@ export default {
738753
flex: 0 0 auto;
739754
justify-content: flex-start;
740755
padding: 8px 10px;
756+
// 4px padding for the focus-visible styles
757+
margin: 4px;
741758
// Fix for border-radius being too large for 3-line entries like in Mail
742759
// 44px avatar size / 2 + 8px padding, and 2px for better visual quality
743760
border-radius: 32px;
@@ -753,6 +770,11 @@ export default {
753770
background-color: var(--color-background-hover);
754771
}
755772
773+
&:focus-visible {
774+
outline: 2px solid var(--color-main-text);
775+
box-shadow: 0 0 0 4px var(--color-main-background);
776+
}
777+
756778
&-content__wrapper {
757779
display: flex;
758780
align-items: center;

0 commit comments

Comments
 (0)