20260720172840

This commit is contained in:
oneao committed 2026-07-20 17:28:47 +08:00
1 parent cda7f16d3a
commit 94207c77ff
3117 files changed
+201407 -1236

No files matched your search

@@ -0,0 +1,38 @@
# _semantic
## Source
```vue
<script setup lang="ts">
import { AppstoreOutlined, BarsOutlined } from '@antdv-next/icons'
import { computed, h } from 'vue'
import { SemanticPreview } from '@/components/semantic'
import { useComponentLocale } from '@/composables/use-locale'
import { locales } from '../locales'
const { t } = useComponentLocale(locales)
const semantics = computed(() => [
{ name: 'root', desc: t('root'), version: '1.0.0' },
{ name: 'item', desc: t('item'), version: '1.0.0' },
{ name: 'label', desc: t('label'), version: '1.0.0' },
{ name: 'icon', desc: t('icon'), version: '1.0.0' },
])
const options = [
{ label: 'List', value: 'List', icon: h(BarsOutlined) },
{ label: 'Kanban', value: 'Kanban', icon: h(AppstoreOutlined) },
]
</script>
<template>
<SemanticPreview
component-name="Segmented"
:semantics="semantics"
>
<template #default="{ classes }">
<a-segmented :options="options" :classes="classes" />
</template>
</SemanticPreview>
</template>
```
@@ -0,0 +1,19 @@
# Basic
## Description (en-US)
The most basic usage.
## Source
```vue
<script lang="ts" setup>
import { ref } from 'vue'
const value = ref('Daily')
</script>
<template>
<a-segmented v-model:value="value" :options="['Daily', 'Weekly', 'Monthly', 'Quarterly', 'Yearly']" @change="(value) => console.log(value)" />
</template>
```
@@ -0,0 +1,20 @@
# Block Segmented
## Description (en-US)
`block` property will make the Segmented fit to its parent width.
## Source
```vue
<script lang="ts" setup>
import { reactive, ref } from 'vue'
const data = reactive([123, 456, 'longtext-longtext-longtext-longtext'])
const value = ref(data[0])
</script>
<template>
<a-segmented v-model:value="value" block :options="data" />
</template>
```
@@ -0,0 +1,101 @@
# Custom Render
## Description (en-US)
Custom each Segmented Item.
## Source
```vue
<script setup lang="ts">
import { ref } from 'vue'
const spring = ref('spring')
</script>
<template>
<a-segmented
:options="[
{
value: 'user1',
tooltip: { title: 'hello user1', color: 'gold' },
},
{
value: 'user2',
tooltip: { title: 'hello user2', color: 'pink' },
},
{
value: 'user3',
tooltip: { title: 'hello user3', color: 'geekblue' },
},
]"
>
<template #labelRender="{ value }">
<template v-if="value === 'user1'">
<div style="padding: 4px">
<a-avatar src="https://api.dicebear.com/7.x/miniavs/svg?seed=8" />
<div>User 1</div>
</div>
</template>
<template v-else-if="value === 'user2'">
<div style="padding: 4px">
<a-avatar src="https://api.dicebear.com/7.x/miniavs/svg?seed=8" />
<div>User 2</div>
</div>
</template>
<template v-else-if="value === 'user3'">
<div style="padding: 4px">
<a-avatar src="https://api.dicebear.com/7.x/miniavs/svg?seed=8" />
<div>User 3</div>
</div>
</template>
</template>
</a-segmented>
<br>
<br>
<a-segmented
v-model:value="spring"
:options="[
{
value: 'spring',
},
{
value: 'summer',
},
{
value: 'autumn',
},
{
value: 'winter',
},
]"
>
<template #labelRender="{ value }">
<template v-if="value === 'spring'">
<div style="padding: 4px">
<div>Spring</div>
<div>Jan-Mar</div>
</div>
</template>
<template v-else-if="value === 'summer'">
<div style="padding: 4px">
<div>Summer</div>
<div>Apr-Jun</div>
</div>
</template>
<template v-else-if="value === 'autumn'">
<div style="padding: 4px">
<div>Autumn</div>
<div>Jul-Sept</div>
</div>
</template>
<template v-else-if="value === 'winter'">
<div style="padding: 4px">
<div>Winter</div>
<div>Oct-Dec</div>
</div>
</template>
</template>
</a-segmented>
</template>
```
@@ -0,0 +1,33 @@
# Disabled
## Description (en-US)
Disabled Segmented.
## Source
```vue
<script lang="ts" setup>
import { reactive, ref } from 'vue'
const data = reactive(['Map', 'Transit', 'Satellite'])
const data2 = reactive([
'Daily',
{ label: 'Weekly', value: 'Weekly', disabled: true },
'Monthly',
{ label: 'Quarterly', value: 'Quarterly', disabled: true },
'Yearly',
])
const value = ref(data[0])
const value2 = ref('Daily')
</script>
<template>
<div>
<a-segmented v-model:value="value" disabled :options="data" />
<br>
<br>
<a-segmented v-model:value="value2" :options="data2" />
</div>
</template>
```
@@ -0,0 +1,30 @@
# Dynamic
## Description (en-US)
Load options dynamically.
## Source
```vue
<script lang="ts" setup>
import { reactive, ref } from 'vue'
const data = reactive(['Daily', 'Weekly', 'Monthly'])
const isDisabled = ref(false)
function loadMore() {
data.push(...['Quarterly', 'Yearly'])
isDisabled.value = true
};
const value = ref(data[0])
</script>
<template>
<a-segmented v-model:value="value" :options="data" />
<br>
<br>
<a-button type="primary" :disabled="isDisabled" @click="loadMore">
Load More
</a-button>
</template>
```
@@ -0,0 +1,39 @@
# With Icon only
## Description (en-US)
Set icon without label for Segmented Item.
## Source
```vue
<script setup lang="ts">
import { AppstoreOutlined, BarsOutlined } from '@antdv-next/icons'
import { h } from 'vue'
const options = [
{ value: 'List', icon: h(BarsOutlined) },
{ value: 'Kanban', icon: h(AppstoreOutlined) },
]
const options2 = [
{ value: 'List' },
{ value: 'Kanban' },
]
</script>
<template>
<a-segmented :options="options" />
<br>
<br>
<a-segmented :options="options2">
<template #iconRender="{ value }">
<template v-if="value === 'List'">
<BarsOutlined />
</template>
<template v-else-if="value === 'Kanban'">
<AppstoreOutlined />
</template>
</template>
</a-segmented>
</template>
```
@@ -0,0 +1,31 @@
# Round shape
## Description (en-US)
Round shape of Segmented.
## Source
```vue
<script setup lang="ts">
import { MoonOutlined, SunOutlined } from '@antdv-next/icons'
import { shallowRef } from 'vue'
const size = shallowRef<any>('middle')
const iconObj: Record<string, any> = {
light: SunOutlined,
dark: MoonOutlined,
}
</script>
<template>
<a-flex gap="small" align="flex-start" vertical>
<a-segmented v-model:value="size" :options="['small', 'middle', 'large']" />
<a-segmented :options="[{ value: 'light' }, { value: 'dark' }]" :size="size" shape="round">
<template #iconRender="{ value }">
<component :is="iconObj[value]" v-if="iconObj[value]" />
</template>
</a-segmented>
</a-flex>
</template>
```
@@ -0,0 +1,28 @@
# Three sizes of Segmented
## Description (en-US)
There are three sizes of an Segmented: large (40px), default (32px) and small (24px).
## Source
```vue
<script lang="ts" setup>
import { reactive, ref } from 'vue'
const data = reactive(['Daily', 'Weekly', 'Monthly', 'Quarterly', 'Yearly'])
const value = ref(data[0])
const value2 = ref(data[0])
const value3 = ref(data[0])
</script>
<template>
<a-segmented v-model:value="value" :options="data" size="large" />
<br>
<br>
<a-segmented v-model:value="value2" :options="data" />
<br>
<br>
<a-segmented v-model:value="value3" :options="data" size="small" />
</template>
```
@@ -0,0 +1,77 @@
# Custom semantic dom styling
## Description (en-US)
## Source
```vue
<script setup lang="ts">
import type { SegmentedProps } from 'antdv-next'
import { CloudOutlined, RocketOutlined, ThunderboltOutlined } from '@antdv-next/icons'
import { h } from 'vue'
const classes: SegmentedProps['classes'] = {
root: 'custom-segmented-root',
}
const styleFn: SegmentedProps['styles'] = (info) => {
if (info.props.vertical) {
return {
root: {
border: '1px solid #77BEF0',
padding: '4px',
width: '100px',
},
icon: {
color: '#77BEF0',
},
item: {
textAlign: 'start',
},
} satisfies SegmentedProps['styles']
}
return {}
}
const styles: SegmentedProps['styles'] = {
root: {
padding: '4px',
width: '260px',
},
}
const options: SegmentedProps['options'] = [
{
label: 'Boost',
value: 'boost',
icon: h(RocketOutlined),
},
{
label: 'Stream',
value: 'stream',
icon: h(ThunderboltOutlined),
},
{
label: 'Cloud',
value: 'cloud',
icon: h(CloudOutlined),
},
]
const segmentedSharedProps: SegmentedProps = {
options,
classes,
}
</script>
<template>
<a-flex vertical gap="middle">
<a-segmented v-bind="segmentedSharedProps" :styles="styles" />
<a-segmented v-bind="segmentedSharedProps" :styles="styleFn" vertical />
</a-flex>
</template>
<style scoped>
.custom-segmented-root {
padding: 2px;
}
</style>
```
@@ -0,0 +1,32 @@
# Vertical Direction
## Description (en-US)
Make it vertical.
## Source
```vue
<script setup lang="ts">
import { AppstoreOutlined, BarsOutlined } from '@antdv-next/icons'
const iconObj: Record<string, any> = {
List: BarsOutlined,
Kanban: AppstoreOutlined,
}
</script>
<template>
<a-segmented
orientation="vertical"
:options="[
{ value: 'List' },
{ value: 'Kanban' },
]"
>
<template #iconRender="{ value }">
<component :is="iconObj[value]" v-if="iconObj[value]" />
</template>
</a-segmented>
</template>
```
@@ -0,0 +1,40 @@
# With Icon
## Description (en-US)
Set icon for Segmented Item.
## Source
```vue
<script setup lang="ts">
import { AppstoreOutlined, BarsOutlined } from '@antdv-next/icons'
import { h } from 'vue'
const options = [
{ label: 'List', value: 'List', icon: h(BarsOutlined) },
{ label: 'Kanban', value: 'Kanban', icon: h(AppstoreOutlined) },
]
const options2 = [
{ label: 'List', value: 'List' },
{ label: 'Kanban', value: 'Kanban' },
]
</script>
<template>
<a-segmented :options="options" />
<br>
<br>
<a-segmented :options="options2">
<template #iconRender="{ value }">
<template v-if="value === 'List'">
<BarsOutlined />
</template>
<template v-else-if="value === 'Kanban'">
<AppstoreOutlined />
</template>
</template>
</a-segmented>
</template>
```
@@ -0,0 +1,19 @@
# With name
## Description (en-US)
Passing the name property to all input[type="radio"] that are in the same Segmented. It is usually used to let the browser see your Segmented as a real "group" and keep the default behavior. For example, using left/right keyboard arrow to change your selection that in the same Segmented.
## Source
```vue
<script lang="ts" setup>
import { ref } from 'vue'
const value = ref('Weekly')
</script>
<template>
<a-segmented v-model:value="value" :options="['Daily', 'Weekly', 'Monthly', 'Quarterly', 'Yearly']" name="group" />
</template>
```
@@ -0,0 +1,74 @@
---
title: Segmented
description: Display multiple options and allow users to select a single option.
---
## When To Use
- When displaying multiple options and user can select a single option;
- When switching the selected option, the content of the associated area changes.
## Demos
| Demo | Path |
| --- | --- |
| Basic | demo/basic.md |
| Vertical Direction | demo/vertical.md |
| Block Segmented | demo/block.md |
| Round shape | demo/shape.md |
| Custom Render | demo/custom.md |
| Dynamic | demo/dynamic.md |
| Disabled | demo/disabled.md |
| Three sizes of Segmented | demo/size.md |
| With Icon | demo/with-icon.md |
| With Icon only | demo/icon-only.md |
| With name | demo/with-name.md |
| Custom semantic dom styling | demo/style-class.md |
## API
Common props ref:[Common props](../../docs/vue/common-props.md)
### Props
| Property | Description | Type | Default | Version | [Global Config](../config-provider/docs.md#component-config) |
| --- | --- | --- | --- | --- | --- |
| block | Option to fit width to its parent\'s width | boolean | false | | × |
| defaultValue | Default selected value | string \| number | | | × |
| disabled | Disable all segments | boolean | false | | × |
| options | Set children optional | string\[] \| number\[] \| SegmentedItemType\[] | [] | | × |
| orientation | Orientation | `horizontal` \| `vertical` | `horizontal` | | × |
| size | The size of the Segmented. | `large` \| `middle` \| `small` | `middle` | | × |
| vertical | Orientation,Simultaneously existing with `orientation`, `orientation` takes priority | boolean | `false` | - | × |
| value | Currently selected value, support `v-model:value` | string \| number | | | × |
| shape | shape of Segmented | `default` \| `round` | `default` | - | × |
| name | The `name` property of all `input[type="radio"]` children. if not set, it will fallback to a randomly generated name | string | |- | × |
### Events
| Event | Description | Type | Version |
| --- | --- | --- | --- |
| change | The callback function that is triggered when the state changes | function(value: string \| number) | - |
### Slots
| Slot | Description | Type | Version |
| --- | --- | --- | --- |
| iconRender | icon render slot | (option: SegmentedLabeledOption) =&gt; any | - |
| labelRender | label render slot | (option: SegmentedLabeledOption) =&gt; any | - |
## Types
### SegmentedItemType
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| disabled | Disabled state of segmented item | boolean | false | |
| class | The additional css class | string | - | |
| icon | Display icon for Segmented item | VueNode | - | |
| label | Display text for Segmented item | VueNode | - | |
| tooltip | tooltip for Segmented item | string \| [TooltipProps](../tooltip#api) | - | |
| value | Value for Segmented item | string \| number | - | |
## Semantic DOM
| _semantic | demo/_semantic.md |
@@ -0,0 +1,33 @@
# segmented Token
Use these variables through `theme.components.Segmented`. This document lists definitions only and does not include values.
```vue
<a-config-provider
:theme="{
token: {
// Global token configuration
},
components: {
Segmented: {
// Token name: value
},
},
}"
>
...
</a-config-provider>
```
## Token List
| Token | Type | Description |
| --- | --- | --- |
| `itemColor` | `string` | Text color of item |
| `itemHoverColor` | `string` | Text color of item when hover |
| `itemHoverBg` | `string` | Background color of item when hover |
| `itemActiveBg` | `string` | Background color of item when active |
| `itemSelectedBg` | `string` | Background color of item when selected |
| `itemSelectedColor` | `string` | Text color of item when selected |
| `trackPadding` | `string \| number` | Padding of Segmented container |
| `trackBg` | `string` | Background of Segmented container |