代码演示
如何引入
<script setup lang="ts">
import { OverflowList } from '@fibrous/semi-ui-vue';
</script>
折叠模式 - 默认
通过 renderMode="collapse" (默认) 来实现内容的折叠。
items 只放数据,不放节点。每个展示项用 #item="{ item, index }" 插槽渲染;溢出项用 #overflow="{ items, position }" 插槽渲染,collapse 模式只调用一次,items 是放不下的项。
代码
<script setup lang="ts">
import { ref, type Component } from 'vue';
import { IconAlarm, IconBookmark, IconCamera, IconDuration, IconEdit, IconFolder } from '@fibrous/semi-icons-vue';
import { OverflowList, Slider, Tag } from '@fibrous/semi-ui-vue';
interface Item {
key: string;
}
const icons: Record<string, Component> = {
alarm: IconAlarm,
bookmark: IconBookmark,
camera: IconCamera,
duration: IconDuration,
edit: IconEdit,
folder: IconFolder,
};
const items: Item[] = Object.keys(icons).map((key) => ({ key }));
const width = ref(100);
const changeWidth = (value: number | number[]) => {
if (typeof value === 'number') width.value = value;
};
</script>
<template>
<div>
<Slider aria-label="Container width" :modelValue="width" :step="1" @update:modelValue="changeWidth" />
<br />
<br />
<div :style="{ width: `${width}%` }">
<OverflowList :items="items">
<template #item="{ item }">
<Tag color="blue" :style="{ marginRight: '8px', flex: '0 0 auto' }">
<component :is="icons[item.key]" :style="{ marginRight: '4px' }" />
<span>{{ item.key }}</span>
</Tag>
</template>
<template #overflow="{ items: hidden }">
<Tag v-if="hidden.length" :style="{ flex: '0 0 auto', fontVariantNumeric: 'tabular-nums' }"> +{{ hidden.length }} </Tag>
</template>
</OverflowList>
</div>
</div>
</template>折叠模式 - 方向
collapse 模式下支持 collapseFrom 设置折叠方向。
代码
<script setup lang="ts">
import { ref, type Component } from 'vue';
import { IconAlarm, IconBookmark, IconCamera, IconDuration, IconEdit, IconFolder } from '@fibrous/semi-icons-vue';
import { OverflowList, Slider, Tag } from '@fibrous/semi-ui-vue';
interface Item {
key: string;
}
const icons: Record<string, Component> = {
alarm: IconAlarm,
bookmark: IconBookmark,
camera: IconCamera,
duration: IconDuration,
edit: IconEdit,
folder: IconFolder,
};
const items: Item[] = Object.keys(icons).map((key) => ({ key }));
const width = ref(100);
const changeWidth = (value: number | number[]) => {
if (typeof value === 'number') width.value = value;
};
</script>
<template>
<div>
<Slider aria-label="Container width" :modelValue="width" :step="1" @update:modelValue="changeWidth" />
<br />
<br />
<div :style="{ width: `${width}%` }">
<OverflowList collapseFrom="start" :items="items">
<template #item="{ item }">
<Tag color="blue" :style="{ marginRight: '8px', flex: '0 0 auto' }">
<component :is="icons[item.key]" :style="{ marginRight: '4px' }" />
<span>{{ item.key }}</span>
</Tag>
</template>
<template #overflow="{ items: hidden }">
<Tag v-if="hidden.length" :style="{ marginRight: '8px', flex: '0 0 auto', fontVariantNumeric: 'tabular-nums' }"> +{{ hidden.length }} </Tag>
</template>
</OverflowList>
</div>
</div>
</template>折叠模式 - 最小展示的数目
collapse 模式下支持 minVisibleItems 设置最小展示的数目。
代码
<script setup lang="ts">
import { ref, type Component } from 'vue';
import { IconAlarm, IconBookmark, IconCamera, IconDuration, IconEdit, IconFolder } from '@fibrous/semi-icons-vue';
import { OverflowList, Slider, Tag } from '@fibrous/semi-ui-vue';
interface Item {
key: string;
}
const icons: Record<string, Component> = {
alarm: IconAlarm,
bookmark: IconBookmark,
camera: IconCamera,
duration: IconDuration,
edit: IconEdit,
folder: IconFolder,
};
const items: Item[] = Object.keys(icons).map((key) => ({ key }));
const width = ref(100);
const changeWidth = (value: number | number[]) => {
if (typeof value === 'number') width.value = value;
};
</script>
<template>
<div>
<Slider aria-label="Container width" :modelValue="width" :step="1" @update:modelValue="changeWidth" />
<br />
<br />
<div :style="{ width: `${width}%` }">
<OverflowList :items="items" :minVisibleItems="3">
<template #item="{ item }">
<Tag color="blue" :style="{ marginRight: '8px', flex: '0 0 auto' }">
<component :is="icons[item.key]" :style="{ marginRight: '4px' }" />
<span>{{ item.key }}</span>
</Tag>
</template>
<template #overflow="{ items: hidden }">
<Tag v-if="hidden.length" :style="{ flex: '0 0 auto', fontVariantNumeric: 'tabular-nums' }"> +{{ hidden.length }} </Tag>
</template>
</OverflowList>
</div>
</div>
</template>滚动模式
通过 renderMode="scroll" 来使用滚动模式的折叠列表。如果需要 scrollIntoView,可以通过选择器: document.querySelector(`.item-cls[data-scrollkey="${key}"] 来选取。
滚动模式下 #overflow 在两侧各调用一次,position 为 start 或 end,items 是该侧滚出可见区域的项。
+0
alarm
bookmark
camera
duration
edit
folder
+0
代码
<script setup lang="ts">
import { ref, type Component } from 'vue';
import { IconAlarm, IconBookmark, IconCamera, IconDuration, IconEdit, IconFolder } from '@fibrous/semi-icons-vue';
import { OverflowList, Slider, Tag } from '@fibrous/semi-ui-vue';
interface Item {
key: string;
}
const icons: Record<string, Component> = {
alarm: IconAlarm,
bookmark: IconBookmark,
camera: IconCamera,
duration: IconDuration,
edit: IconEdit,
folder: IconFolder,
};
const items: Item[] = Object.keys(icons).map((key) => ({ key }));
const width = ref(100);
const changeWidth = (value: number | number[]) => {
if (typeof value === 'number') width.value = value;
};
</script>
<template>
<div>
<Slider aria-label="Container width" :modelValue="width" :step="1" @update:modelValue="changeWidth" />
<br />
<br />
<div :style="{ width: `${width}%` }">
<OverflowList :items="items" renderMode="scroll">
<template #item="{ item }">
<Tag color="blue" :style="{ marginRight: '8px', flex: '0 0 auto' }">
<component :is="icons[item.key]" :style="{ marginRight: '4px' }" />
<span>{{ item.key }}</span>
</Tag>
</template>
<template #overflow="{ items: hidden }">
<Tag
:style="{
marginRight: '8px',
marginLeft: '8px',
flex: '0 0 auto',
fontVariantNumeric: 'tabular-nums',
}"
>
+{{ hidden.length }}
</Tag>
</template>
</OverflowList>
</div>
</div>
</template>API 参考
Props
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| collapseFrom | collapse 模式的折叠方向,可选 start 或 end。 | "start" | "end" | semiDefault("OverflowList", "collapseFrom", "end") |
| items | 渲染项目,只放数据,不放节点;scroll 模式要求每项含 key。 | T[] | semiGlobalDefault("OverflowList", "items") |
| itemKey | 每项 key 的字段名,或取 key 的函数;默认读取 key 字段,没有时取该项在 items 中的位置。 | TypeOverflowListKey | ((item: T) => OverflowListKey) | undefined |
| minVisibleItems | collapse 模式下最少展示的项数。 | number | semiDefault("OverflowList", "minVisibleItems", 0) |
| overflowRenderDirection | scroll 模式下溢出节点的位置,可选 both、start 或 end;供 Tabs 使用,不面向使用方。 | "start" | "end" | "both" | semiDefault("OverflowList", "overflowRenderDirection", "both") |
| renderMode | 渲染模式,可选 collapse 或 scroll。 | "collapse" | "scroll" | semiDefault("OverflowList", "renderMode", "collapse") |
| threshold | scroll 模式下触发溢出回调的可见比例阈值。 | number | semiDefault("OverflowList", "threshold", 0.75) |
| wrapperClassName | scroll 模式下滚动 wrapper 的类名。 | string | semiGlobalDefault("OverflowList", "wrapperClassName") |
| wrapperProps | scroll 模式下滚动 wrapper 的其他属性,例如承载可见项的 role。 | Type(HTMLAttributes & Record<string, unknown>) | semiGlobalDefault("OverflowList", "wrapperProps") |
| wrapperStyle | scroll 模式下滚动 wrapper 的样式。 | StyleValue | semiGlobalDefault("OverflowList", "wrapperStyle") |
Events
| 事件 | 说明 | 回调参数 |
|---|---|---|
| overflow | collapse 模式下溢出项变化时触发,全部放得下时参数为空数组。 | [overflowItems: T[]] |
| intersect | scroll 模式下各项的相交状态变化时触发。 | Type[res: Record<string, IntersectionObserverEntry>] |
| visibleStateChange | scroll 模式下各项的显示或隐藏状态变化时触发。 | Type[visibleState: Map<string, boolean>] |
Slots
| 插槽 | 说明 | 作用域参数 |
|---|---|---|
| item | 单个展示项的内容,参数为数据项及其在 items 中的位置。 | TypeOverflowListItemSlotProps<T> |
| overflow | 溢出项的内容。collapse 模式调用一次,items 为放不下的项;scroll 模式在两侧各调用一次,position 为 start 或 end,items 为该侧滚出可见区域的项。 | TypeOverflowListOverflowSlotProps<T> |
Exposes
| 名称 | 说明 | 类型 |
|---|---|---|
| 无 |
class、style 与 aria-* 等原生属性经 attrs 落在根元素上;滚动 wrapper 的类名、样式和其他属性用 wrapperClassName、wrapperStyle、wrapperProps 传入。
Accessibility
ARIA
- 传入
aria-label或aria-labelledby时,根元素带role="group",使这组项目有可读的名称;未传时根元素没有角色