mirror of
https://github.com/fantastic-admin/basic.git
synced 2026-10-06 12:03:02 +08:00
refactor: 重构 components 子包组件目录和导出结构
This commit is contained in:
@@ -45,14 +45,6 @@ const routes: RouteRecordRaw = {
|
||||
title: '按钮',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'button_group',
|
||||
name: 'componentExampleButtonGroup',
|
||||
component: () => import('@/views/component_example/button_group.vue'),
|
||||
meta: {
|
||||
title: '按钮组',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'card',
|
||||
name: 'componentExampleCard',
|
||||
@@ -69,14 +61,6 @@ const routes: RouteRecordRaw = {
|
||||
title: '复选框',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'checkbox_group',
|
||||
name: 'componentExampleCheckboxGroup',
|
||||
component: () => import('@/views/component_example/checkbox_group.vue'),
|
||||
meta: {
|
||||
title: '复选框组',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'collapsible',
|
||||
name: 'componentExampleCollapsible',
|
||||
|
||||
@@ -4,7 +4,7 @@ import { button } from '@fantastic-admin/components/examples'
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<FaPageHeader title="按钮" description="FaButton" />
|
||||
<FaPageHeader title="按钮" description="FaButton / FaButtonGroup" />
|
||||
<FaPageMain
|
||||
v-for="example in button"
|
||||
:key="example.title"
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { buttonGroup } from '@fantastic-admin/components/examples'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<FaPageHeader title="按钮组" description="FaButtonGroup" />
|
||||
<FaPageMain
|
||||
v-for="example in buttonGroup"
|
||||
:key="example.title"
|
||||
:code="example.componentRaw"
|
||||
:title="example.title"
|
||||
>
|
||||
<component :is="example.component" />
|
||||
</FaPageMain>
|
||||
</div>
|
||||
</template>
|
||||
@@ -4,7 +4,7 @@ import { checkbox } from '@fantastic-admin/components/examples'
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<FaPageHeader title="复选框" description="FaCheckbox" />
|
||||
<FaPageHeader title="复选框" description="FaCheckbox / FaCheckboxGroup" />
|
||||
<FaPageMain
|
||||
v-for="example in checkbox"
|
||||
:key="example.title"
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { checkboxGroup } from '@fantastic-admin/components/examples'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<FaPageHeader title="复选框组" description="FaCheckboxGroup" />
|
||||
<FaPageMain
|
||||
v-for="example in checkboxGroup"
|
||||
:key="example.title"
|
||||
:code="example.componentRaw"
|
||||
:title="example.title"
|
||||
>
|
||||
<component :is="example.component" />
|
||||
</FaPageMain>
|
||||
</div>
|
||||
</template>
|
||||
@@ -1,20 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import { kbd, kbdGroup } from '@fantastic-admin/components/examples'
|
||||
|
||||
const examples = [
|
||||
...kbd,
|
||||
...kbdGroup.map(example => ({
|
||||
...example,
|
||||
title: '组合',
|
||||
})),
|
||||
]
|
||||
import { kbd } from '@fantastic-admin/components/examples'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<FaPageHeader title="键盘" description="FaKbd" />
|
||||
<FaPageHeader title="键盘" description="FaKbd / FaKbdGroup" />
|
||||
<FaPageMain
|
||||
v-for="example in examples"
|
||||
v-for="example in kbd"
|
||||
:key="example.title"
|
||||
:code="example.componentRaw"
|
||||
:title="example.title"
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export { default as Alert } from './index.vue'
|
||||
@@ -0,0 +1 @@
|
||||
export { default as Avatar } from './index.vue'
|
||||
@@ -0,0 +1 @@
|
||||
export { default as Badge } from './index.vue'
|
||||
@@ -1,26 +0,0 @@
|
||||
# FaButtonGroup 按钮组
|
||||
|
||||
将多个按钮组合在一起的容器组件,支持水平/垂直排列和分割线。
|
||||
|
||||
## 使用场景
|
||||
|
||||
- 将多个按钮组合在一起的容器组件,支持水平/垂直排列和分割线。
|
||||
- 常见用法:垂直排列、带分割线、工具栏按钮组、垂直菜单。
|
||||
|
||||
## Props
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
|------|------|------|--------|
|
||||
| orientation | 排列方向 | `'horizontal' \| 'vertical'` | `'horizontal'` |
|
||||
| separator | 是否显示分割线 | `boolean` | `false` |
|
||||
| class | 自定义类名 | `HTMLAttributes['class']` | `undefined` |
|
||||
|
||||
## Slots
|
||||
|
||||
| 名称 | 说明 |
|
||||
|------|------|
|
||||
| default | 默认插槽,放置 FaButton 组件 |
|
||||
|
||||
## 注意事项
|
||||
|
||||
- 无特殊限制,建议按示例中的受控方式接入,并结合业务容器尺寸验证最终展示效果。
|
||||
@@ -1,38 +0,0 @@
|
||||
import Basic from './_basic.vue'
|
||||
import BasicRaw from './_basic.vue?raw'
|
||||
import Nested from './_nested.vue'
|
||||
import NestedRaw from './_nested.vue?raw'
|
||||
import Separator from './_separator.vue'
|
||||
import SeparatorRaw from './_separator.vue?raw'
|
||||
import Vertical from './_vertical.vue'
|
||||
import VerticalRaw from './_vertical.vue?raw'
|
||||
import WithComponents from './_with-components.vue'
|
||||
import WithComponentsRaw from './_with-components.vue?raw'
|
||||
|
||||
export default [
|
||||
{
|
||||
title: '基础',
|
||||
component: Basic,
|
||||
componentRaw: BasicRaw,
|
||||
},
|
||||
{
|
||||
title: '垂直',
|
||||
component: Vertical,
|
||||
componentRaw: VerticalRaw,
|
||||
},
|
||||
{
|
||||
title: '分割线',
|
||||
component: Separator,
|
||||
componentRaw: SeparatorRaw,
|
||||
},
|
||||
{
|
||||
title: '嵌套',
|
||||
component: Nested,
|
||||
componentRaw: NestedRaw,
|
||||
},
|
||||
{
|
||||
title: '与其他组件组合',
|
||||
component: WithComponents,
|
||||
componentRaw: WithComponentsRaw,
|
||||
},
|
||||
]
|
||||
@@ -41,3 +41,30 @@
|
||||
- `ghost`:幽灵按钮,用于更次要的操作
|
||||
- `link`:链接样式
|
||||
- `expand`:展开动画效果按钮
|
||||
|
||||
## FaButtonGroup 按钮组
|
||||
|
||||
将多个按钮组合在一起的容器组件,支持水平/垂直排列和分割线。
|
||||
|
||||
## 使用场景
|
||||
|
||||
- 将多个按钮组合在一起的容器组件,支持水平/垂直排列和分割线。
|
||||
- 常见用法:垂直排列、带分割线、工具栏按钮组、垂直菜单。
|
||||
|
||||
## Props
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
|------|------|------|--------|
|
||||
| orientation | 排列方向 | `'horizontal' \| 'vertical'` | `'horizontal'` |
|
||||
| separator | 是否显示分割线 | `boolean` | `false` |
|
||||
| class | 自定义类名 | `HTMLAttributes['class']` | `undefined` |
|
||||
|
||||
## Slots
|
||||
|
||||
| 名称 | 说明 |
|
||||
|------|------|
|
||||
| default | 默认插槽,放置 FaButton 组件 |
|
||||
|
||||
## 注意事项
|
||||
|
||||
- 无特殊限制,建议按示例中的受控方式接入,并结合业务容器尺寸验证最终展示效果。
|
||||
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
// 组件实际使用时无需手动导入,框架会自动导入
|
||||
import FaButton from '../../button/index.vue'
|
||||
import FaIcon from '../../icon/index.vue'
|
||||
import FaButtonGroup from '../index.vue'
|
||||
import FaButtonGroup from '../ButtonGroup.vue'
|
||||
// 组件实际使用时无需手动导入,框架会自动导入
|
||||
import FaButton from '../index.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
// 组件实际使用时无需手动导入,框架会自动导入
|
||||
import FaButton from '../../button/index.vue'
|
||||
import FaIcon from '../../icon/index.vue'
|
||||
import FaButtonGroup from '../index.vue'
|
||||
import FaButtonGroup from '../ButtonGroup.vue'
|
||||
// 组件实际使用时无需手动导入,框架会自动导入
|
||||
import FaButton from '../index.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
// 组件实际使用时无需手动导入,框架会自动导入
|
||||
import FaButton from '../../button/index.vue'
|
||||
import FaIcon from '../../icon/index.vue'
|
||||
import FaButtonGroup from '../index.vue'
|
||||
import FaButtonGroup from '../ButtonGroup.vue'
|
||||
// 组件实际使用时无需手动导入,框架会自动导入
|
||||
import FaButton from '../index.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
// 组件实际使用时无需手动导入,框架会自动导入
|
||||
import FaButton from '../../button/index.vue'
|
||||
import FaIcon from '../../icon/index.vue'
|
||||
import FaButtonGroup from '../index.vue'
|
||||
import FaButtonGroup from '../ButtonGroup.vue'
|
||||
// 组件实际使用时无需手动导入,框架会自动导入
|
||||
import FaButton from '../index.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
+3
-3
@@ -1,13 +1,13 @@
|
||||
<script setup lang="ts">
|
||||
import { shallowRef } from 'vue'
|
||||
|
||||
// 组件实际使用时无需手动导入,框架会自动导入
|
||||
import FaButton from '../../button/index.vue'
|
||||
import FaDropdown from '../../dropdown/index.vue'
|
||||
import FaIcon from '../../icon/index.vue'
|
||||
import FaInput from '../../input/index.vue'
|
||||
import FaSelect from '../../select/index.vue'
|
||||
import FaButtonGroup from '../index.vue'
|
||||
import FaButtonGroup from '../ButtonGroup.vue'
|
||||
// 组件实际使用时无需手动导入,框架会自动导入
|
||||
import FaButton from '../index.vue'
|
||||
|
||||
const currency = shallowRef('CNY')
|
||||
</script>
|
||||
@@ -2,6 +2,16 @@ import Basic from './_basic.vue'
|
||||
import BasicRaw from './_basic.vue?raw'
|
||||
import Disabled from './_disabled.vue'
|
||||
import DisabledRaw from './_disabled.vue?raw'
|
||||
import GroupBasic from './_group-basic.vue'
|
||||
import GroupBasicRaw from './_group-basic.vue?raw'
|
||||
import GroupNested from './_group-nested.vue'
|
||||
import GroupNestedRaw from './_group-nested.vue?raw'
|
||||
import GroupSeparator from './_group-separator.vue'
|
||||
import GroupSeparatorRaw from './_group-separator.vue?raw'
|
||||
import GroupVertical from './_group-vertical.vue'
|
||||
import GroupVerticalRaw from './_group-vertical.vue?raw'
|
||||
import GroupWithComponents from './_group-with-components.vue'
|
||||
import GroupWithComponentsRaw from './_group-with-components.vue?raw'
|
||||
import Loading from './_loading.vue'
|
||||
import LoadingRaw from './_loading.vue?raw'
|
||||
import Size from './_size.vue'
|
||||
@@ -35,4 +45,29 @@ export default [
|
||||
component: Loading,
|
||||
componentRaw: LoadingRaw,
|
||||
},
|
||||
{
|
||||
title: '按钮组 - 基础',
|
||||
component: GroupBasic,
|
||||
componentRaw: GroupBasicRaw,
|
||||
},
|
||||
{
|
||||
title: '按钮组 - 垂直',
|
||||
component: GroupVertical,
|
||||
componentRaw: GroupVerticalRaw,
|
||||
},
|
||||
{
|
||||
title: '按钮组 - 分割线',
|
||||
component: GroupSeparator,
|
||||
componentRaw: GroupSeparatorRaw,
|
||||
},
|
||||
{
|
||||
title: '按钮组 - 嵌套',
|
||||
component: GroupNested,
|
||||
componentRaw: GroupNestedRaw,
|
||||
},
|
||||
{
|
||||
title: '按钮组 - 与其他组件组合',
|
||||
component: GroupWithComponents,
|
||||
componentRaw: GroupWithComponentsRaw,
|
||||
},
|
||||
]
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
export { default as ButtonGroup } from './ButtonGroup.vue'
|
||||
export { default as Button } from './index.vue'
|
||||
@@ -0,0 +1 @@
|
||||
export { default as Card } from './index.vue'
|
||||
@@ -1,61 +0,0 @@
|
||||
# FaCheckboxGroup 复选框组
|
||||
|
||||
基于选项数组的复选框组组件,支持描述文案、自定义布局样式和选项插槽扩展。
|
||||
|
||||
## 使用场景
|
||||
|
||||
- 表单中的多选配置项
|
||||
- 多标签偏好选择
|
||||
- 权限点批量选择
|
||||
- 带说明文案的多选列表
|
||||
- 需要卡片式多选交互的场景
|
||||
|
||||
## Props
|
||||
|
||||
| 属性 | 类型 | 默认值 | 说明 |
|
||||
|------|------|--------|------|
|
||||
| `options` | `CheckboxGroupOption[]` | **必需** | 复选框组选项数据 |
|
||||
| `disabled` | `boolean` | `false` | 是否整体禁用 |
|
||||
| `min` | `number` | - | 最少选中数量,达到后已选项会被禁用 |
|
||||
| `max` | `number` | - | 最多选中数量,达到后未选项会被禁用 |
|
||||
| `dir` | `'ltr' \| 'rtl'` | - | 文本方向 |
|
||||
| `class` | `HTMLAttributes['class']` | - | 组容器类名 |
|
||||
| `optionClass` | `HTMLAttributes['class']` | - | 每个选项外层容器类名 |
|
||||
| `itemClass` | `HTMLAttributes['class']` | - | 复选框本体类名 |
|
||||
| `labelClass` | `HTMLAttributes['class']` | - | 标签内容类名 |
|
||||
|
||||
### CheckboxGroupOption 接口
|
||||
|
||||
```ts
|
||||
export interface CheckboxGroupOption {
|
||||
label: string
|
||||
value: AcceptableValue
|
||||
description?: string
|
||||
disabled?: boolean
|
||||
id?: string
|
||||
}
|
||||
```
|
||||
|
||||
## Slots
|
||||
|
||||
| 名称 | 说明 |
|
||||
|------|------|
|
||||
| `option` | 自定义选项内容,slot props: `{ option, checked, disabled, id }`,`option` 会保留 `options` 中的扩展字段类型 |
|
||||
|
||||
## Events
|
||||
|
||||
| 事件名 | 说明 | 回调参数 |
|
||||
|--------|------|----------|
|
||||
| `change` | 选中值变化时触发 | `value: AcceptableValue[]` |
|
||||
|
||||
通过 `v-model` 实现双向绑定。
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **数据驱动**:组选项必须通过 `options` 传入,不再使用多个 `FaCheckbox` 手工拼接。
|
||||
2. **v-model 类型**:组件通过 `v-model` 管理选中值数组。
|
||||
3. **禁用优先级**:组件整体 `disabled` 为 `true` 时,会覆盖单项可用状态。
|
||||
4. **数量限制**:当选中数量小于等于 `min` 时,已选项会被禁用;当选中数量大于等于 `max` 时,未选项会被禁用。
|
||||
5. **布局控制**:通过 `class` 和 `optionClass` 自定义多列或卡片式排列,不再提供 `orientation`。
|
||||
6. **描述文案布局**:存在 `description` 时,选项会自动切换为顶部对齐布局。
|
||||
7. **自定义插槽**:使用 `option` 插槽后,默认复选框本体会隐藏,需要由插槽内容自行承担完整视觉表现。
|
||||
@@ -1,38 +0,0 @@
|
||||
import Basic from './_basic.vue'
|
||||
import BasicRaw from './_basic.vue?raw'
|
||||
import CustomOption from './_custom-option.vue'
|
||||
import CustomOptionRaw from './_custom-option.vue?raw'
|
||||
import Description from './_description.vue'
|
||||
import DescriptionRaw from './_description.vue?raw'
|
||||
import Disabled from './_disabled.vue'
|
||||
import DisabledRaw from './_disabled.vue?raw'
|
||||
import Limit from './_limit.vue'
|
||||
import LimitRaw from './_limit.vue?raw'
|
||||
|
||||
export default [
|
||||
{
|
||||
title: '基础',
|
||||
component: Basic,
|
||||
componentRaw: BasicRaw,
|
||||
},
|
||||
{
|
||||
title: '描述',
|
||||
component: Description,
|
||||
componentRaw: DescriptionRaw,
|
||||
},
|
||||
{
|
||||
title: '禁用',
|
||||
component: Disabled,
|
||||
componentRaw: DisabledRaw,
|
||||
},
|
||||
{
|
||||
title: '数量限制',
|
||||
component: Limit,
|
||||
componentRaw: LimitRaw,
|
||||
},
|
||||
{
|
||||
title: '自定义选项内容',
|
||||
component: CustomOption,
|
||||
componentRaw: CustomOptionRaw,
|
||||
},
|
||||
]
|
||||
+1
-1
@@ -4,8 +4,8 @@ import type { HTMLAttributes } from 'vue'
|
||||
import { useTextDirection } from '@vueuse/core'
|
||||
import { computed, useId, watch } from 'vue'
|
||||
import { cn } from '#utils'
|
||||
import { Checkbox } from '../checkbox/checkbox'
|
||||
import { Label } from '../label/label'
|
||||
import { Checkbox } from './checkbox'
|
||||
|
||||
export interface CheckboxGroupOption {
|
||||
label: string
|
||||
@@ -40,3 +40,65 @@
|
||||
3. **标签点击**:点击标签文字也能触发复选框状态切换。
|
||||
4. **空标签隐藏**:当不提供默认插槽内容时,标签元素会自动隐藏。
|
||||
5. **禁用状态**:禁用状态下复选框和标签都无法点击。
|
||||
|
||||
## FaCheckboxGroup 复选框组
|
||||
|
||||
基于选项数组的复选框组组件,支持描述文案、自定义布局样式和选项插槽扩展。
|
||||
|
||||
## 使用场景
|
||||
|
||||
- 表单中的多选配置项
|
||||
- 多标签偏好选择
|
||||
- 权限点批量选择
|
||||
- 带说明文案的多选列表
|
||||
- 需要卡片式多选交互的场景
|
||||
|
||||
## Props
|
||||
|
||||
| 属性 | 类型 | 默认值 | 说明 |
|
||||
|------|------|--------|------|
|
||||
| `options` | `CheckboxGroupOption[]` | **必需** | 复选框组选项数据 |
|
||||
| `disabled` | `boolean` | `false` | 是否整体禁用 |
|
||||
| `min` | `number` | - | 最少选中数量,达到后已选项会被禁用 |
|
||||
| `max` | `number` | - | 最多选中数量,达到后未选项会被禁用 |
|
||||
| `dir` | `'ltr' \| 'rtl'` | - | 文本方向 |
|
||||
| `class` | `HTMLAttributes['class']` | - | 组容器类名 |
|
||||
| `optionClass` | `HTMLAttributes['class']` | - | 每个选项外层容器类名 |
|
||||
| `itemClass` | `HTMLAttributes['class']` | - | 复选框本体类名 |
|
||||
| `labelClass` | `HTMLAttributes['class']` | - | 标签内容类名 |
|
||||
|
||||
### CheckboxGroupOption 接口
|
||||
|
||||
```ts
|
||||
export interface CheckboxGroupOption {
|
||||
label: string
|
||||
value: AcceptableValue
|
||||
description?: string
|
||||
disabled?: boolean
|
||||
id?: string
|
||||
}
|
||||
```
|
||||
|
||||
## Slots
|
||||
|
||||
| 名称 | 说明 |
|
||||
|------|------|
|
||||
| `option` | 自定义选项内容,slot props: `{ option, checked, disabled, id }`,`option` 会保留 `options` 中的扩展字段类型 |
|
||||
|
||||
## Events
|
||||
|
||||
| 事件名 | 说明 | 回调参数 |
|
||||
|--------|------|----------|
|
||||
| `change` | 选中值变化时触发 | `value: AcceptableValue[]` |
|
||||
|
||||
通过 `v-model` 实现双向绑定。
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **数据驱动**:组选项必须通过 `options` 传入,不再使用多个 `FaCheckbox` 手工拼接。
|
||||
2. **v-model 类型**:组件通过 `v-model` 管理选中值数组。
|
||||
3. **禁用优先级**:组件整体 `disabled` 为 `true` 时,会覆盖单项可用状态。
|
||||
4. **数量限制**:当选中数量小于等于 `min` 时,已选项会被禁用;当选中数量大于等于 `max` 时,未选项会被禁用。
|
||||
5. **布局控制**:通过 `class` 和 `optionClass` 自定义多列或卡片式排列,不再提供 `orientation`。
|
||||
6. **描述文案布局**:存在 `description` 时,选项会自动切换为顶部对齐布局。
|
||||
7. **自定义插槽**:使用 `option` 插槽后,默认复选框本体会隐藏,需要由插槽内容自行承担完整视觉表现。
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
import { computed, shallowRef } from 'vue'
|
||||
|
||||
// 组件实际使用时无需手动导入,框架会自动导入
|
||||
import FaCheckboxGroup from '../index.vue'
|
||||
import FaCheckboxGroup from '../CheckboxGroup.vue'
|
||||
|
||||
const value = shallowRef(['music'])
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
import { shallowRef } from 'vue'
|
||||
|
||||
// 组件实际使用时无需手动导入,框架会自动导入
|
||||
import FaCheckboxGroup from '../index.vue'
|
||||
import FaCheckboxGroup from '../CheckboxGroup.vue'
|
||||
|
||||
const value = shallowRef(['focus', 'balanced'])
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
import { computed, shallowRef } from 'vue'
|
||||
|
||||
// 组件实际使用时无需手动导入,框架会自动导入
|
||||
import FaCheckboxGroup from '../index.vue'
|
||||
import FaCheckboxGroup from '../CheckboxGroup.vue'
|
||||
|
||||
const value = shallowRef(['dashboard', 'report'])
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
import { computed, shallowRef } from 'vue'
|
||||
|
||||
// 组件实际使用时无需手动导入,框架会自动导入
|
||||
import FaCheckboxGroup from '../index.vue'
|
||||
import FaCheckboxGroup from '../CheckboxGroup.vue'
|
||||
|
||||
const value = shallowRef(['basic'])
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
import { computed, shallowRef } from 'vue'
|
||||
|
||||
// 组件实际使用时无需手动导入,框架会自动导入
|
||||
import FaCheckboxGroup from '../index.vue'
|
||||
import FaCheckboxGroup from '../CheckboxGroup.vue'
|
||||
|
||||
const value = shallowRef(['dashboard'])
|
||||
|
||||
@@ -4,6 +4,16 @@ import CustomStyle from './_custom-style.vue'
|
||||
import CustomStyleRaw from './_custom-style.vue?raw'
|
||||
import Disabled from './_disabled.vue'
|
||||
import DisabledRaw from './_disabled.vue?raw'
|
||||
import GroupBasic from './_group-basic.vue'
|
||||
import GroupBasicRaw from './_group-basic.vue?raw'
|
||||
import GroupCustomOption from './_group-custom-option.vue'
|
||||
import GroupCustomOptionRaw from './_group-custom-option.vue?raw'
|
||||
import GroupDescription from './_group-description.vue'
|
||||
import GroupDescriptionRaw from './_group-description.vue?raw'
|
||||
import GroupDisabled from './_group-disabled.vue'
|
||||
import GroupDisabledRaw from './_group-disabled.vue?raw'
|
||||
import GroupLimit from './_group-limit.vue'
|
||||
import GroupLimitRaw from './_group-limit.vue?raw'
|
||||
import Indeterminate from './_indeterminate.vue'
|
||||
import IndeterminateRaw from './_indeterminate.vue?raw'
|
||||
|
||||
@@ -13,19 +23,44 @@ export default [
|
||||
component: Basic,
|
||||
componentRaw: BasicRaw,
|
||||
},
|
||||
{
|
||||
title: '半选状态',
|
||||
component: Indeterminate,
|
||||
componentRaw: IndeterminateRaw,
|
||||
},
|
||||
{
|
||||
title: '禁用',
|
||||
component: Disabled,
|
||||
componentRaw: DisabledRaw,
|
||||
},
|
||||
{
|
||||
title: '半选',
|
||||
component: Indeterminate,
|
||||
componentRaw: IndeterminateRaw,
|
||||
},
|
||||
{
|
||||
title: '自定义样式',
|
||||
component: CustomStyle,
|
||||
componentRaw: CustomStyleRaw,
|
||||
},
|
||||
{
|
||||
title: '复选框组 - 基础',
|
||||
component: GroupBasic,
|
||||
componentRaw: GroupBasicRaw,
|
||||
},
|
||||
{
|
||||
title: '复选框组 - 描述',
|
||||
component: GroupDescription,
|
||||
componentRaw: GroupDescriptionRaw,
|
||||
},
|
||||
{
|
||||
title: '复选框组 - 禁用',
|
||||
component: GroupDisabled,
|
||||
componentRaw: GroupDisabledRaw,
|
||||
},
|
||||
{
|
||||
title: '复选框组 - 数量限制',
|
||||
component: GroupLimit,
|
||||
componentRaw: GroupLimitRaw,
|
||||
},
|
||||
{
|
||||
title: '复选框组 - 自定义选项',
|
||||
component: GroupCustomOption,
|
||||
componentRaw: GroupCustomOptionRaw,
|
||||
},
|
||||
]
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
export { default as CheckboxGroup } from './CheckboxGroup.vue'
|
||||
export { default as Checkbox } from './index.vue'
|
||||
@@ -0,0 +1 @@
|
||||
export { default as Collapsible } from './index.vue'
|
||||
@@ -0,0 +1 @@
|
||||
export { default as ContextMenu } from './index.vue'
|
||||
@@ -0,0 +1,2 @@
|
||||
export { default as Descriptions } from './index.vue'
|
||||
export type { DescriptionDirection, DescriptionItem, DescriptionItemBase, DescriptionSize, DescriptionSlotProps, DescriptionsProps, DescriptionValue } from './index.vue'
|
||||
@@ -0,0 +1 @@
|
||||
export { default as Divider } from './index.vue'
|
||||
@@ -1,135 +1,3 @@
|
||||
import type { Component, HTMLAttributes, VNode } from 'vue'
|
||||
import { createVNode, getCurrentInstance, h, isVNode, onUnmounted, ref, render, shallowRef, watchEffect } from 'vue'
|
||||
import Drawer from './index.vue'
|
||||
|
||||
export interface DrawerProps {
|
||||
id?: string
|
||||
modelValue?: boolean
|
||||
zIndex?: number
|
||||
side?: 'top' | 'bottom' | 'left' | 'right'
|
||||
title?: string | (() => string)
|
||||
description?: string | (() => string)
|
||||
loading?: boolean
|
||||
closable?: boolean
|
||||
centered?: boolean
|
||||
bordered?: boolean
|
||||
overlay?: boolean
|
||||
overlayBlur?: boolean
|
||||
showConfirmButton?: boolean
|
||||
showCancelButton?: boolean
|
||||
confirmButtonText?: string | (() => string)
|
||||
cancelButtonText?: string | (() => string)
|
||||
confirmButtonDisabled?: boolean
|
||||
confirmButtonLoading?: boolean
|
||||
beforeClose?: (
|
||||
action: 'confirm' | 'cancel' | 'close',
|
||||
done: () => void,
|
||||
) => void
|
||||
header?: boolean
|
||||
footer?: boolean
|
||||
closeOnClickOverlay?: boolean
|
||||
closeOnPressEscape?: boolean
|
||||
destroyOnClose?: boolean
|
||||
openAutoFocus?: boolean
|
||||
contentClass?: HTMLAttributes['class']
|
||||
headerClass?: HTMLAttributes['class']
|
||||
footerClass?: HTMLAttributes['class']
|
||||
}
|
||||
|
||||
export interface DrawerEmits {
|
||||
'update:modelValue': [value: boolean]
|
||||
'open': []
|
||||
'opened': []
|
||||
'close': []
|
||||
'closed': []
|
||||
'confirm': []
|
||||
'cancel': []
|
||||
}
|
||||
|
||||
type BaseOptions = Omit<DrawerProps, 'modelValue'> & {
|
||||
content?: Component | VNode | string
|
||||
onOpen?: () => void
|
||||
onOpened?: () => void
|
||||
onClose?: () => void
|
||||
onClosed?: () => void
|
||||
onConfirm?: () => void
|
||||
onCancel?: () => void
|
||||
}
|
||||
|
||||
export function useDrawer() {
|
||||
function create(initialOptions: BaseOptions) {
|
||||
const container = document.createElement('div')
|
||||
const visible = ref(false)
|
||||
const options = shallowRef<BaseOptions>({ ...initialOptions })
|
||||
const instance = getCurrentInstance()
|
||||
let vnode: VNode | null = null
|
||||
|
||||
const updateVNode = () => {
|
||||
vnode = createVNode(Drawer, Object.assign({
|
||||
'id': instance && instance.uid ? `FaDrawer-${instance.uid}` : undefined,
|
||||
'modelValue': visible.value,
|
||||
'onUpdate:modelValue': (val: boolean) => {
|
||||
visible.value = val
|
||||
},
|
||||
...options.value,
|
||||
}), {
|
||||
default: () => {
|
||||
if (typeof options.value.content === 'string') {
|
||||
return options.value.content
|
||||
}
|
||||
else if (isVNode(options.value.content)) {
|
||||
return options.value.content
|
||||
}
|
||||
else if (options.value.content) {
|
||||
return h(options.value.content)
|
||||
}
|
||||
return null
|
||||
},
|
||||
})
|
||||
// 继承主应用的上下文
|
||||
if (instance && instance.appContext) {
|
||||
vnode.appContext = instance.appContext
|
||||
}
|
||||
render(vnode, container)
|
||||
}
|
||||
|
||||
// 监听 visible 和 options 变化,自动重新渲染
|
||||
watchEffect(() => {
|
||||
updateVNode()
|
||||
})
|
||||
|
||||
// 挂载到当前实例
|
||||
instance?.proxy?.$el?.appendChild(container)
|
||||
|
||||
// 监听组件卸载,自动清理
|
||||
if (instance) {
|
||||
onUnmounted(() => {
|
||||
if (vnode) {
|
||||
render(null, container)
|
||||
vnode = null
|
||||
}
|
||||
if (container.parentNode) {
|
||||
container.parentNode.removeChild(container)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const open = () => {
|
||||
visible.value = true
|
||||
}
|
||||
const close = () => {
|
||||
visible.value = false
|
||||
}
|
||||
const update = (newOptions: BaseOptions) => {
|
||||
options.value = { ...options.value, ...newOptions }
|
||||
}
|
||||
return {
|
||||
open,
|
||||
close,
|
||||
update,
|
||||
}
|
||||
}
|
||||
return {
|
||||
create,
|
||||
}
|
||||
}
|
||||
export { default as Drawer } from './index.vue'
|
||||
export { useDrawer } from './useDrawer'
|
||||
export type { DrawerEmits, DrawerProps } from './useDrawer'
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
import type { Component, HTMLAttributes, VNode } from 'vue'
|
||||
import { createVNode, getCurrentInstance, h, isVNode, onUnmounted, ref, render, shallowRef, watchEffect } from 'vue'
|
||||
import Drawer from './index.vue'
|
||||
|
||||
export interface DrawerProps {
|
||||
id?: string
|
||||
modelValue?: boolean
|
||||
zIndex?: number
|
||||
side?: 'top' | 'bottom' | 'left' | 'right'
|
||||
title?: string | (() => string)
|
||||
description?: string | (() => string)
|
||||
loading?: boolean
|
||||
closable?: boolean
|
||||
centered?: boolean
|
||||
bordered?: boolean
|
||||
overlay?: boolean
|
||||
overlayBlur?: boolean
|
||||
showConfirmButton?: boolean
|
||||
showCancelButton?: boolean
|
||||
confirmButtonText?: string | (() => string)
|
||||
cancelButtonText?: string | (() => string)
|
||||
confirmButtonDisabled?: boolean
|
||||
confirmButtonLoading?: boolean
|
||||
beforeClose?: (
|
||||
action: 'confirm' | 'cancel' | 'close',
|
||||
done: () => void,
|
||||
) => void
|
||||
header?: boolean
|
||||
footer?: boolean
|
||||
closeOnClickOverlay?: boolean
|
||||
closeOnPressEscape?: boolean
|
||||
destroyOnClose?: boolean
|
||||
openAutoFocus?: boolean
|
||||
contentClass?: HTMLAttributes['class']
|
||||
headerClass?: HTMLAttributes['class']
|
||||
footerClass?: HTMLAttributes['class']
|
||||
}
|
||||
|
||||
export interface DrawerEmits {
|
||||
'update:modelValue': [value: boolean]
|
||||
'open': []
|
||||
'opened': []
|
||||
'close': []
|
||||
'closed': []
|
||||
'confirm': []
|
||||
'cancel': []
|
||||
}
|
||||
|
||||
type BaseOptions = Omit<DrawerProps, 'modelValue'> & {
|
||||
content?: Component | VNode | string
|
||||
onOpen?: () => void
|
||||
onOpened?: () => void
|
||||
onClose?: () => void
|
||||
onClosed?: () => void
|
||||
onConfirm?: () => void
|
||||
onCancel?: () => void
|
||||
}
|
||||
|
||||
export function useDrawer() {
|
||||
function create(initialOptions: BaseOptions) {
|
||||
const container = document.createElement('div')
|
||||
const visible = ref(false)
|
||||
const options = shallowRef<BaseOptions>({ ...initialOptions })
|
||||
const instance = getCurrentInstance()
|
||||
let vnode: VNode | null = null
|
||||
|
||||
const updateVNode = () => {
|
||||
vnode = createVNode(Drawer, Object.assign({
|
||||
'id': instance && instance.uid ? `FaDrawer-${instance.uid}` : undefined,
|
||||
'modelValue': visible.value,
|
||||
'onUpdate:modelValue': (val: boolean) => {
|
||||
visible.value = val
|
||||
},
|
||||
...options.value,
|
||||
}), {
|
||||
default: () => {
|
||||
if (typeof options.value.content === 'string') {
|
||||
return options.value.content
|
||||
}
|
||||
else if (isVNode(options.value.content)) {
|
||||
return options.value.content
|
||||
}
|
||||
else if (options.value.content) {
|
||||
return h(options.value.content)
|
||||
}
|
||||
return null
|
||||
},
|
||||
})
|
||||
// 继承主应用的上下文
|
||||
if (instance && instance.appContext) {
|
||||
vnode.appContext = instance.appContext
|
||||
}
|
||||
render(vnode, container)
|
||||
}
|
||||
|
||||
// 监听 visible 和 options 变化,自动重新渲染
|
||||
watchEffect(() => {
|
||||
updateVNode()
|
||||
})
|
||||
|
||||
// 挂载到当前实例
|
||||
instance?.proxy?.$el?.appendChild(container)
|
||||
|
||||
// 监听组件卸载,自动清理
|
||||
if (instance) {
|
||||
onUnmounted(() => {
|
||||
if (vnode) {
|
||||
render(null, container)
|
||||
vnode = null
|
||||
}
|
||||
if (container.parentNode) {
|
||||
container.parentNode.removeChild(container)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const open = () => {
|
||||
visible.value = true
|
||||
}
|
||||
const close = () => {
|
||||
visible.value = false
|
||||
}
|
||||
const update = (newOptions: BaseOptions) => {
|
||||
options.value = { ...options.value, ...newOptions }
|
||||
}
|
||||
return {
|
||||
open,
|
||||
close,
|
||||
update,
|
||||
}
|
||||
}
|
||||
return {
|
||||
create,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export { default as Dropdown } from './index.vue'
|
||||
@@ -0,0 +1,2 @@
|
||||
export { default as FileUpload } from './index.vue'
|
||||
export type { FileItem, FileUploadRequestOptions } from './index.vue'
|
||||
@@ -2,7 +2,7 @@
|
||||
import axios from 'axios'
|
||||
import { filesize } from 'filesize'
|
||||
import { computed, onMounted, onUnmounted, ref, useTemplateRef } from 'vue'
|
||||
import ButtonGroup from '../button-group/index.vue'
|
||||
import ButtonGroup from '../button/ButtonGroup.vue'
|
||||
import Button from '../button/index.vue'
|
||||
import Icon from '../icon/index.vue'
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export { default as FixedBar } from './index.vue'
|
||||
@@ -0,0 +1 @@
|
||||
export { default as HoverCard } from './index.vue'
|
||||
@@ -0,0 +1 @@
|
||||
export { default as Icon } from './index.vue'
|
||||
@@ -1,22 +1,2 @@
|
||||
import { createApp, h } from 'vue'
|
||||
import Preview from './preview.vue'
|
||||
|
||||
export function useImagePreview() {
|
||||
function open(src: string | string[], index = 0) {
|
||||
const container = document.createElement('div')
|
||||
const app = createApp({
|
||||
render() {
|
||||
return h(Preview, {
|
||||
modelValue: true,
|
||||
src,
|
||||
index,
|
||||
})
|
||||
},
|
||||
})
|
||||
app.mount(container)
|
||||
}
|
||||
|
||||
return {
|
||||
open,
|
||||
}
|
||||
}
|
||||
export { default as ImagePreview } from './index.vue'
|
||||
export { useImagePreview } from './useImagePreview'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { VisuallyHidden } from 'reka-ui'
|
||||
import { computed, onMounted, onUnmounted, ref, watch } from 'vue'
|
||||
import ButtonGroup from '../button-group/index.vue'
|
||||
import ButtonGroup from '../button/ButtonGroup.vue'
|
||||
import Button from '../button/index.vue'
|
||||
import Icon from '../icon/index.vue'
|
||||
import { Dialog, DialogContent, DialogDescription, DialogTitle } from './dialog'
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
import { createApp, h } from 'vue'
|
||||
import Preview from './preview.vue'
|
||||
|
||||
export function useImagePreview() {
|
||||
function open(src: string | string[], index = 0) {
|
||||
const container = document.createElement('div')
|
||||
const app = createApp({
|
||||
render() {
|
||||
return h(Preview, {
|
||||
modelValue: true,
|
||||
src,
|
||||
index,
|
||||
})
|
||||
},
|
||||
})
|
||||
app.mount(container)
|
||||
}
|
||||
|
||||
return {
|
||||
open,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export { default as ImageUpload } from './index.vue'
|
||||
export type { UploadRequestOptions } from './index.vue'
|
||||
@@ -0,0 +1 @@
|
||||
export { default as InputOTP } from './index.vue'
|
||||
@@ -0,0 +1 @@
|
||||
export { default as Input } from './index.vue'
|
||||
@@ -1,28 +0,0 @@
|
||||
# FaKbdGroup 键盘组合
|
||||
|
||||
用于包裹多个 `FaKbd` 组件,展示组合按键的容器组件。
|
||||
|
||||
## 使用场景
|
||||
|
||||
- 快捷键组合展示
|
||||
- 键盘操作说明
|
||||
- 命令面板提示
|
||||
- 帮助文档中的多键组合说明
|
||||
|
||||
## Props
|
||||
|
||||
| 属性 | 类型 | 默认值 | 说明 |
|
||||
|------|------|--------|------|
|
||||
| `class` | `HTMLAttributes['class']` | - | 自定义 CSS 类 |
|
||||
|
||||
## Slots
|
||||
|
||||
| 名称 | 说明 |
|
||||
|------|------|
|
||||
| `default` | 包含的 `FaKbd` 组件 |
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **仅用于组合**:此组件仅用于包裹多个 `FaKbd`,不建议单独使用
|
||||
2. **间距自动**:内部的 `FaKbd` 会自动添加适当间距
|
||||
3. **灵活内容**:除了 `FaKbd` 外,也可以放入其他内容(如分隔符)
|
||||
@@ -1,10 +0,0 @@
|
||||
import Basic from './_basic.vue'
|
||||
import BasicRaw from './_basic.vue?raw'
|
||||
|
||||
export default [
|
||||
{
|
||||
title: '基础',
|
||||
component: Basic,
|
||||
componentRaw: BasicRaw,
|
||||
},
|
||||
]
|
||||
@@ -34,3 +34,32 @@
|
||||
1. **配合使用**:组合按键时请使用 `FaKbdGroup` 包裹多个 `FaKbd`
|
||||
2. **内容长度**:按键内容不宜过长,适合单个字符或简短单词
|
||||
3. **图标支持**:可以使用 `FaIcon` 组件显示图标,图标会自动调整为合适尺寸
|
||||
|
||||
## FaKbdGroup 键盘组合
|
||||
|
||||
用于包裹多个 `FaKbd` 组件,展示组合按键的容器组件。
|
||||
|
||||
## 使用场景
|
||||
|
||||
- 快捷键组合展示
|
||||
- 键盘操作说明
|
||||
- 命令面板提示
|
||||
- 帮助文档中的多键组合说明
|
||||
|
||||
## Props
|
||||
|
||||
| 属性 | 类型 | 默认值 | 说明 |
|
||||
|------|------|--------|------|
|
||||
| `class` | `HTMLAttributes['class']` | - | 自定义 CSS 类 |
|
||||
|
||||
## Slots
|
||||
|
||||
| 名称 | 说明 |
|
||||
|------|------|
|
||||
| `default` | 包含的 `FaKbd` 组件 |
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **仅用于组合**:此组件仅用于包裹多个 `FaKbd`,不建议单独使用
|
||||
2. **间距自动**:内部的 `FaKbd` 会自动添加适当间距
|
||||
3. **灵活内容**:除了 `FaKbd` 外,也可以放入其他内容(如分隔符)
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
// 组件实际使用时无需手动导入,框架会自动导入
|
||||
import FaKbd from '../../kbd/index.vue'
|
||||
import FaKbdGroup from '../index.vue'
|
||||
import FaKbd from '../index.vue'
|
||||
import FaKbdGroup from '../KbdGroup.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -1,5 +1,7 @@
|
||||
import Basic from './_basic.vue'
|
||||
import BasicRaw from './_basic.vue?raw'
|
||||
import GroupBasic from './_group-basic.vue'
|
||||
import GroupBasicRaw from './_group-basic.vue?raw'
|
||||
|
||||
export default [
|
||||
{
|
||||
@@ -7,4 +9,9 @@ export default [
|
||||
component: Basic,
|
||||
componentRaw: BasicRaw,
|
||||
},
|
||||
{
|
||||
title: '组合',
|
||||
component: GroupBasic,
|
||||
componentRaw: GroupBasicRaw,
|
||||
},
|
||||
]
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
export { default as Kbd } from './index.vue'
|
||||
export { default as KbdGroup } from './KbdGroup.vue'
|
||||
@@ -0,0 +1 @@
|
||||
export { default as Label } from './index.vue'
|
||||
@@ -1,231 +1,3 @@
|
||||
import type { Component, HTMLAttributes, VNode } from 'vue'
|
||||
import { createVNode, getCurrentInstance, h, isVNode, onUnmounted, ref, render, shallowRef, watchEffect } from 'vue'
|
||||
import Modal from './index.vue'
|
||||
|
||||
export interface ModalProps {
|
||||
id?: string
|
||||
modelValue?: boolean
|
||||
zIndex?: number
|
||||
title?: string | (() => string)
|
||||
description?: string | (() => string)
|
||||
icon?: 'info' | 'success' | 'warning' | 'error'
|
||||
loading?: boolean
|
||||
closable?: boolean
|
||||
maximize?: boolean
|
||||
maximizable?: boolean
|
||||
draggable?: boolean
|
||||
center?: boolean
|
||||
border?: boolean
|
||||
alignCenter?: boolean
|
||||
overlay?: boolean
|
||||
overlayBlur?: boolean
|
||||
showConfirmButton?: boolean
|
||||
showCancelButton?: boolean
|
||||
confirmButtonText?: string | (() => string)
|
||||
cancelButtonText?: string | (() => string)
|
||||
confirmButtonDisabled?: boolean
|
||||
confirmButtonLoading?: boolean
|
||||
beforeClose?: (
|
||||
action: 'confirm' | 'cancel' | 'close',
|
||||
done: () => void,
|
||||
) => void
|
||||
header?: boolean
|
||||
footer?: boolean
|
||||
closeOnClickOverlay?: boolean
|
||||
closeOnPressEscape?: boolean
|
||||
destroyOnClose?: boolean
|
||||
openAutoFocus?: boolean
|
||||
class?: HTMLAttributes['class']
|
||||
headerClass?: HTMLAttributes['class']
|
||||
contentClass?: HTMLAttributes['class']
|
||||
footerClass?: HTMLAttributes['class']
|
||||
}
|
||||
export interface ModalEmits {
|
||||
'update:modelValue': [value: boolean]
|
||||
'open': []
|
||||
'opened': []
|
||||
'close': []
|
||||
'closed': []
|
||||
'confirm': []
|
||||
'cancel': []
|
||||
}
|
||||
|
||||
type BaseOptions = Omit<ModalProps, 'modelValue'> & {
|
||||
content?: Component | VNode | string
|
||||
onOpen?: () => void
|
||||
onOpened?: () => void
|
||||
onClose?: () => void
|
||||
onClosed?: () => void
|
||||
onConfirm?: () => void
|
||||
onCancel?: () => void
|
||||
}
|
||||
|
||||
type alertOptions = Pick<BaseOptions, 'title' | 'description' | 'icon' | 'alignCenter' | 'overlay' | 'overlayBlur' | 'confirmButtonText' | 'confirmButtonDisabled' | 'confirmButtonLoading' | 'closeOnClickOverlay' | 'closeOnPressEscape' | 'class' | 'headerClass' | 'contentClass' | 'footerClass' | 'content' | 'onConfirm'>
|
||||
|
||||
type confirmOptions = Pick<BaseOptions, 'title' | 'description' | 'alignCenter' | 'overlay' | 'overlayBlur' | 'confirmButtonText' | 'cancelButtonText' | 'confirmButtonDisabled' | 'confirmButtonLoading' | 'beforeClose' | 'closeOnClickOverlay' | 'closeOnPressEscape' | 'class' | 'headerClass' | 'contentClass' | 'footerClass' | 'content' | 'onConfirm' | 'onCancel'>
|
||||
|
||||
export function useModal() {
|
||||
function create(initialOptions: BaseOptions) {
|
||||
const container = document.createElement('div')
|
||||
const visible = ref(false)
|
||||
const options = shallowRef<BaseOptions>({ ...initialOptions })
|
||||
const instance = getCurrentInstance()
|
||||
let vnode: VNode | null = null
|
||||
|
||||
const updateVNode = () => {
|
||||
vnode = createVNode(Modal, Object.assign({
|
||||
'id': instance && instance.uid ? `FaModal-${instance.uid}` : undefined,
|
||||
'modelValue': visible.value,
|
||||
'onUpdate:modelValue': (val: boolean) => {
|
||||
visible.value = val
|
||||
},
|
||||
...options.value,
|
||||
}), {
|
||||
default: () => {
|
||||
if (typeof options.value.content === 'string') {
|
||||
return options.value.content
|
||||
}
|
||||
else if (isVNode(options.value.content)) {
|
||||
return options.value.content
|
||||
}
|
||||
else if (options.value.content) {
|
||||
return h(options.value.content)
|
||||
}
|
||||
return null
|
||||
},
|
||||
})
|
||||
// 继承主应用的上下文
|
||||
if (instance && instance.appContext) {
|
||||
vnode.appContext = instance.appContext
|
||||
}
|
||||
render(vnode, container)
|
||||
}
|
||||
|
||||
// 监听 visible 和 options 变化,自动重新渲染
|
||||
watchEffect(() => {
|
||||
updateVNode()
|
||||
})
|
||||
|
||||
// 挂载到当前实例
|
||||
instance?.proxy?.$el?.appendChild(container)
|
||||
|
||||
// 监听组件卸载,自动清理
|
||||
if (instance) {
|
||||
onUnmounted(() => {
|
||||
if (vnode) {
|
||||
render(null, container)
|
||||
vnode = null
|
||||
}
|
||||
if (container.parentNode) {
|
||||
container.parentNode.removeChild(container)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const open = () => {
|
||||
visible.value = true
|
||||
}
|
||||
const close = () => {
|
||||
visible.value = false
|
||||
}
|
||||
const update = (newOptions: BaseOptions) => {
|
||||
options.value = { ...options.value, ...newOptions }
|
||||
}
|
||||
return {
|
||||
open,
|
||||
close,
|
||||
update,
|
||||
}
|
||||
}
|
||||
function info(options: alertOptions) {
|
||||
const defaultOptions: BaseOptions = {
|
||||
icon: 'info',
|
||||
closable: false,
|
||||
border: false,
|
||||
alignCenter: true,
|
||||
closeOnClickOverlay: false,
|
||||
destroyOnClose: true,
|
||||
openAutoFocus: true,
|
||||
class: 'min-h-auto max-w-[calc(100%-2rem)]',
|
||||
contentClass: 'py-0 min-h-auto text-center sm:text-start',
|
||||
footerClass: 'p-4',
|
||||
}
|
||||
const { open } = create(Object.assign(defaultOptions, options))
|
||||
open()
|
||||
}
|
||||
function success(options: alertOptions) {
|
||||
const defaultOptions: BaseOptions = {
|
||||
icon: 'success',
|
||||
closable: false,
|
||||
border: false,
|
||||
alignCenter: true,
|
||||
closeOnClickOverlay: false,
|
||||
destroyOnClose: true,
|
||||
openAutoFocus: true,
|
||||
class: 'min-h-auto max-w-[calc(100%-2rem)]',
|
||||
contentClass: 'py-0 min-h-auto text-center sm:text-start',
|
||||
footerClass: 'p-4',
|
||||
}
|
||||
const { open } = create(Object.assign(defaultOptions, options))
|
||||
open()
|
||||
}
|
||||
function warning(options: alertOptions) {
|
||||
const defaultOptions: BaseOptions = {
|
||||
icon: 'warning',
|
||||
closable: false,
|
||||
border: false,
|
||||
alignCenter: true,
|
||||
closeOnClickOverlay: false,
|
||||
destroyOnClose: true,
|
||||
openAutoFocus: true,
|
||||
class: 'min-h-auto max-w-[calc(100%-2rem)]',
|
||||
contentClass: 'py-0 min-h-auto text-center sm:text-start',
|
||||
footerClass: 'p-4',
|
||||
}
|
||||
const { open } = create(Object.assign(defaultOptions, options))
|
||||
open()
|
||||
}
|
||||
function error(options: alertOptions) {
|
||||
const defaultOptions: BaseOptions = {
|
||||
icon: 'error',
|
||||
closable: false,
|
||||
border: false,
|
||||
alignCenter: true,
|
||||
closeOnClickOverlay: false,
|
||||
destroyOnClose: true,
|
||||
openAutoFocus: true,
|
||||
class: 'min-h-auto max-w-[calc(100%-2rem)]',
|
||||
contentClass: 'py-0 min-h-auto text-center sm:text-start',
|
||||
footerClass: 'p-4',
|
||||
}
|
||||
const { open } = create(Object.assign(defaultOptions, options))
|
||||
open()
|
||||
}
|
||||
function confirm(options: confirmOptions) {
|
||||
const defaultOptions: BaseOptions = {
|
||||
closable: false,
|
||||
border: false,
|
||||
alignCenter: true,
|
||||
showCancelButton: true,
|
||||
closeOnClickOverlay: false,
|
||||
destroyOnClose: true,
|
||||
openAutoFocus: true,
|
||||
class: 'min-h-auto max-w-[calc(100%-2rem)]',
|
||||
contentClass: 'py-0 min-h-auto text-center sm:text-start',
|
||||
footerClass: 'p-4',
|
||||
}
|
||||
const { open, update } = create(Object.assign(defaultOptions, options))
|
||||
open()
|
||||
return {
|
||||
update,
|
||||
}
|
||||
}
|
||||
return {
|
||||
create,
|
||||
info,
|
||||
success,
|
||||
warning,
|
||||
error,
|
||||
confirm,
|
||||
}
|
||||
}
|
||||
export { default as Modal } from './index.vue'
|
||||
export { useModal } from './useModal'
|
||||
export type { ModalEmits, ModalProps } from './useModal'
|
||||
|
||||
@@ -0,0 +1,231 @@
|
||||
import type { Component, HTMLAttributes, VNode } from 'vue'
|
||||
import { createVNode, getCurrentInstance, h, isVNode, onUnmounted, ref, render, shallowRef, watchEffect } from 'vue'
|
||||
import Modal from './index.vue'
|
||||
|
||||
export interface ModalProps {
|
||||
id?: string
|
||||
modelValue?: boolean
|
||||
zIndex?: number
|
||||
title?: string | (() => string)
|
||||
description?: string | (() => string)
|
||||
icon?: 'info' | 'success' | 'warning' | 'error'
|
||||
loading?: boolean
|
||||
closable?: boolean
|
||||
maximize?: boolean
|
||||
maximizable?: boolean
|
||||
draggable?: boolean
|
||||
center?: boolean
|
||||
border?: boolean
|
||||
alignCenter?: boolean
|
||||
overlay?: boolean
|
||||
overlayBlur?: boolean
|
||||
showConfirmButton?: boolean
|
||||
showCancelButton?: boolean
|
||||
confirmButtonText?: string | (() => string)
|
||||
cancelButtonText?: string | (() => string)
|
||||
confirmButtonDisabled?: boolean
|
||||
confirmButtonLoading?: boolean
|
||||
beforeClose?: (
|
||||
action: 'confirm' | 'cancel' | 'close',
|
||||
done: () => void,
|
||||
) => void
|
||||
header?: boolean
|
||||
footer?: boolean
|
||||
closeOnClickOverlay?: boolean
|
||||
closeOnPressEscape?: boolean
|
||||
destroyOnClose?: boolean
|
||||
openAutoFocus?: boolean
|
||||
class?: HTMLAttributes['class']
|
||||
headerClass?: HTMLAttributes['class']
|
||||
contentClass?: HTMLAttributes['class']
|
||||
footerClass?: HTMLAttributes['class']
|
||||
}
|
||||
export interface ModalEmits {
|
||||
'update:modelValue': [value: boolean]
|
||||
'open': []
|
||||
'opened': []
|
||||
'close': []
|
||||
'closed': []
|
||||
'confirm': []
|
||||
'cancel': []
|
||||
}
|
||||
|
||||
type BaseOptions = Omit<ModalProps, 'modelValue'> & {
|
||||
content?: Component | VNode | string
|
||||
onOpen?: () => void
|
||||
onOpened?: () => void
|
||||
onClose?: () => void
|
||||
onClosed?: () => void
|
||||
onConfirm?: () => void
|
||||
onCancel?: () => void
|
||||
}
|
||||
|
||||
type alertOptions = Pick<BaseOptions, 'title' | 'description' | 'icon' | 'alignCenter' | 'overlay' | 'overlayBlur' | 'confirmButtonText' | 'confirmButtonDisabled' | 'confirmButtonLoading' | 'closeOnClickOverlay' | 'closeOnPressEscape' | 'class' | 'headerClass' | 'contentClass' | 'footerClass' | 'content' | 'onConfirm'>
|
||||
|
||||
type confirmOptions = Pick<BaseOptions, 'title' | 'description' | 'alignCenter' | 'overlay' | 'overlayBlur' | 'confirmButtonText' | 'cancelButtonText' | 'confirmButtonDisabled' | 'confirmButtonLoading' | 'beforeClose' | 'closeOnClickOverlay' | 'closeOnPressEscape' | 'class' | 'headerClass' | 'contentClass' | 'footerClass' | 'content' | 'onConfirm' | 'onCancel'>
|
||||
|
||||
export function useModal() {
|
||||
function create(initialOptions: BaseOptions) {
|
||||
const container = document.createElement('div')
|
||||
const visible = ref(false)
|
||||
const options = shallowRef<BaseOptions>({ ...initialOptions })
|
||||
const instance = getCurrentInstance()
|
||||
let vnode: VNode | null = null
|
||||
|
||||
const updateVNode = () => {
|
||||
vnode = createVNode(Modal, Object.assign({
|
||||
'id': instance && instance.uid ? `FaModal-${instance.uid}` : undefined,
|
||||
'modelValue': visible.value,
|
||||
'onUpdate:modelValue': (val: boolean) => {
|
||||
visible.value = val
|
||||
},
|
||||
...options.value,
|
||||
}), {
|
||||
default: () => {
|
||||
if (typeof options.value.content === 'string') {
|
||||
return options.value.content
|
||||
}
|
||||
else if (isVNode(options.value.content)) {
|
||||
return options.value.content
|
||||
}
|
||||
else if (options.value.content) {
|
||||
return h(options.value.content)
|
||||
}
|
||||
return null
|
||||
},
|
||||
})
|
||||
// 继承主应用的上下文
|
||||
if (instance && instance.appContext) {
|
||||
vnode.appContext = instance.appContext
|
||||
}
|
||||
render(vnode, container)
|
||||
}
|
||||
|
||||
// 监听 visible 和 options 变化,自动重新渲染
|
||||
watchEffect(() => {
|
||||
updateVNode()
|
||||
})
|
||||
|
||||
// 挂载到当前实例
|
||||
instance?.proxy?.$el?.appendChild(container)
|
||||
|
||||
// 监听组件卸载,自动清理
|
||||
if (instance) {
|
||||
onUnmounted(() => {
|
||||
if (vnode) {
|
||||
render(null, container)
|
||||
vnode = null
|
||||
}
|
||||
if (container.parentNode) {
|
||||
container.parentNode.removeChild(container)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const open = () => {
|
||||
visible.value = true
|
||||
}
|
||||
const close = () => {
|
||||
visible.value = false
|
||||
}
|
||||
const update = (newOptions: BaseOptions) => {
|
||||
options.value = { ...options.value, ...newOptions }
|
||||
}
|
||||
return {
|
||||
open,
|
||||
close,
|
||||
update,
|
||||
}
|
||||
}
|
||||
function info(options: alertOptions) {
|
||||
const defaultOptions: BaseOptions = {
|
||||
icon: 'info',
|
||||
closable: false,
|
||||
border: false,
|
||||
alignCenter: true,
|
||||
closeOnClickOverlay: false,
|
||||
destroyOnClose: true,
|
||||
openAutoFocus: true,
|
||||
class: 'min-h-auto max-w-[calc(100%-2rem)]',
|
||||
contentClass: 'py-0 min-h-auto text-center sm:text-start',
|
||||
footerClass: 'p-4',
|
||||
}
|
||||
const { open } = create(Object.assign(defaultOptions, options))
|
||||
open()
|
||||
}
|
||||
function success(options: alertOptions) {
|
||||
const defaultOptions: BaseOptions = {
|
||||
icon: 'success',
|
||||
closable: false,
|
||||
border: false,
|
||||
alignCenter: true,
|
||||
closeOnClickOverlay: false,
|
||||
destroyOnClose: true,
|
||||
openAutoFocus: true,
|
||||
class: 'min-h-auto max-w-[calc(100%-2rem)]',
|
||||
contentClass: 'py-0 min-h-auto text-center sm:text-start',
|
||||
footerClass: 'p-4',
|
||||
}
|
||||
const { open } = create(Object.assign(defaultOptions, options))
|
||||
open()
|
||||
}
|
||||
function warning(options: alertOptions) {
|
||||
const defaultOptions: BaseOptions = {
|
||||
icon: 'warning',
|
||||
closable: false,
|
||||
border: false,
|
||||
alignCenter: true,
|
||||
closeOnClickOverlay: false,
|
||||
destroyOnClose: true,
|
||||
openAutoFocus: true,
|
||||
class: 'min-h-auto max-w-[calc(100%-2rem)]',
|
||||
contentClass: 'py-0 min-h-auto text-center sm:text-start',
|
||||
footerClass: 'p-4',
|
||||
}
|
||||
const { open } = create(Object.assign(defaultOptions, options))
|
||||
open()
|
||||
}
|
||||
function error(options: alertOptions) {
|
||||
const defaultOptions: BaseOptions = {
|
||||
icon: 'error',
|
||||
closable: false,
|
||||
border: false,
|
||||
alignCenter: true,
|
||||
closeOnClickOverlay: false,
|
||||
destroyOnClose: true,
|
||||
openAutoFocus: true,
|
||||
class: 'min-h-auto max-w-[calc(100%-2rem)]',
|
||||
contentClass: 'py-0 min-h-auto text-center sm:text-start',
|
||||
footerClass: 'p-4',
|
||||
}
|
||||
const { open } = create(Object.assign(defaultOptions, options))
|
||||
open()
|
||||
}
|
||||
function confirm(options: confirmOptions) {
|
||||
const defaultOptions: BaseOptions = {
|
||||
closable: false,
|
||||
border: false,
|
||||
alignCenter: true,
|
||||
showCancelButton: true,
|
||||
closeOnClickOverlay: false,
|
||||
destroyOnClose: true,
|
||||
openAutoFocus: true,
|
||||
class: 'min-h-auto max-w-[calc(100%-2rem)]',
|
||||
contentClass: 'py-0 min-h-auto text-center sm:text-start',
|
||||
footerClass: 'p-4',
|
||||
}
|
||||
const { open, update } = create(Object.assign(defaultOptions, options))
|
||||
open()
|
||||
return {
|
||||
update,
|
||||
}
|
||||
}
|
||||
return {
|
||||
create,
|
||||
info,
|
||||
success,
|
||||
warning,
|
||||
error,
|
||||
confirm,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export { default as NumberField } from './index.vue'
|
||||
@@ -0,0 +1 @@
|
||||
export { default as PageHeader } from './index.vue'
|
||||
@@ -0,0 +1 @@
|
||||
export { default as PageMain } from './index.vue'
|
||||
@@ -0,0 +1 @@
|
||||
export { default as Pagination } from './index.vue'
|
||||
@@ -0,0 +1 @@
|
||||
export { default as PasswordStrength } from './index.vue'
|
||||
@@ -0,0 +1 @@
|
||||
export { default as Popover } from './index.vue'
|
||||
@@ -0,0 +1 @@
|
||||
export { default as Progress } from './index.vue'
|
||||
@@ -0,0 +1 @@
|
||||
export { default as RadioGroup } from './index.vue'
|
||||
@@ -0,0 +1 @@
|
||||
export { default as ScrollArea } from './index.vue'
|
||||
@@ -0,0 +1 @@
|
||||
export { default as SearchBar } from './index.vue'
|
||||
@@ -0,0 +1 @@
|
||||
export { default as Select } from './index.vue'
|
||||
@@ -0,0 +1 @@
|
||||
export { default as Slider } from './index.vue'
|
||||
@@ -0,0 +1 @@
|
||||
export { default as Switch } from './index.vue'
|
||||
@@ -0,0 +1,2 @@
|
||||
export { default as Table } from './index.vue'
|
||||
export type { TableAlign, TableCellSlotProps, TableColumn, TableColumnFixed, TableEmptySlotProps, TableExpandedState, TableFooterSlotProps, TableHeaderSlotProps, TableProps, TableSelectionColumn, TableSelectionDisabled, TableSortingState, TableToolbarSlotProps } from './index.vue'
|
||||
@@ -0,0 +1 @@
|
||||
export { default as Tabs } from './index.vue'
|
||||
@@ -0,0 +1 @@
|
||||
export { default as Tag } from './index.vue'
|
||||
@@ -0,0 +1 @@
|
||||
export { default as Textarea } from './index.vue'
|
||||
@@ -1,5 +1,2 @@
|
||||
import { toast } from 'vue-sonner'
|
||||
|
||||
export function useToast() {
|
||||
return toast
|
||||
}
|
||||
export { default as Toast } from './index.vue'
|
||||
export { useToast } from './useToast'
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
import { toast } from 'vue-sonner'
|
||||
|
||||
export function useToast() {
|
||||
return toast
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export { default as Tooltip } from './index.vue'
|
||||
@@ -0,0 +1 @@
|
||||
export { default as Trend } from './index.vue'
|
||||
@@ -1,10 +1,8 @@
|
||||
export { default as alert } from './basic/alert/_examples'
|
||||
export { default as avatar } from './basic/avatar/_examples'
|
||||
export { default as badge } from './basic/badge/_examples'
|
||||
export { default as buttonGroup } from './basic/button-group/_examples'
|
||||
export { default as button } from './basic/button/_examples'
|
||||
export { default as card } from './basic/card/_examples'
|
||||
export { default as checkboxGroup } from './basic/checkbox-group/_examples'
|
||||
export { default as checkbox } from './basic/checkbox/_examples'
|
||||
export { default as collapsible } from './basic/collapsible/_examples'
|
||||
export { default as contextMenu } from './basic/context-menu/_examples'
|
||||
@@ -20,7 +18,6 @@ export { default as imagePreview } from './basic/image-preview/_examples'
|
||||
export { default as imageUpload } from './basic/image-upload/_examples'
|
||||
export { default as inputOtp } from './basic/input-otp/_examples'
|
||||
export { default as input } from './basic/input/_examples'
|
||||
export { default as kbdGroup } from './basic/kbd-group/_examples'
|
||||
export { default as kbd } from './basic/kbd/_examples'
|
||||
export { default as label } from './basic/label/_examples'
|
||||
export { default as modal } from './basic/modal/_examples'
|
||||
|
||||
@@ -1,57 +1,54 @@
|
||||
// 基础版组件
|
||||
export { default as FaAlert } from './basic/alert/index.vue'
|
||||
export { default as FaAvatar } from './basic/avatar/index.vue'
|
||||
export { default as FaBadge } from './basic/badge/index.vue'
|
||||
export { default as FaButtonGroup } from './basic/button-group/index.vue'
|
||||
export { default as FaButton } from './basic/button/index.vue'
|
||||
export { default as FaCard } from './basic/card/index.vue'
|
||||
export { default as FaCheckboxGroup } from './basic/checkbox-group/index.vue'
|
||||
export { default as FaCheckbox } from './basic/checkbox/index.vue'
|
||||
export { default as FaCollapsible } from './basic/collapsible/index.vue'
|
||||
export { default as FaContextMenu } from './basic/context-menu/index.vue'
|
||||
export { default as FaDescriptions } from './basic/descriptions/index.vue'
|
||||
export type { DescriptionDirection, DescriptionItem, DescriptionItemBase, DescriptionSize, DescriptionSlotProps, DescriptionsProps, DescriptionValue } from './basic/descriptions/index.vue'
|
||||
export { default as FaDivider } from './basic/divider/index.vue'
|
||||
export type { DrawerEmits, DrawerProps } from './basic/drawer/index'
|
||||
export { useDrawer as useFaDrawer } from './basic/drawer/index'
|
||||
export { default as FaDrawer } from './basic/drawer/index.vue'
|
||||
export { default as FaDropdown } from './basic/dropdown/index.vue'
|
||||
export { default as FaFileUpload } from './basic/file-upload/index.vue'
|
||||
export type { FileItem, FileUploadRequestOptions } from './basic/file-upload/index.vue'
|
||||
export { default as FaFixedBar } from './basic/fixed-bar/index.vue'
|
||||
export { default as FaHoverCard } from './basic/hover-card/index.vue'
|
||||
export { default as FaIcon } from './basic/icon/index.vue'
|
||||
export { useImagePreview as useFaImagePreview } from './basic/image-preview/index'
|
||||
export { default as FaImagePreview } from './basic/image-preview/index.vue'
|
||||
export { default as FaImageUpload } from './basic/image-upload/index.vue'
|
||||
export type { UploadRequestOptions } from './basic/image-upload/index.vue'
|
||||
export { default as FaInputOTP } from './basic/input-otp/index.vue'
|
||||
export { default as FaInput } from './basic/input/index.vue'
|
||||
export { default as FaKbdGroup } from './basic/kbd-group/index.vue'
|
||||
export { default as FaKbd } from './basic/kbd/index.vue'
|
||||
export { default as FaLabel } from './basic/label/index.vue'
|
||||
export type { ModalEmits, ModalProps } from './basic/modal/index'
|
||||
export { useModal as useFaModal } from './basic/modal/index'
|
||||
export { default as FaModal } from './basic/modal/index.vue'
|
||||
export { default as FaNumberField } from './basic/number-field/index.vue'
|
||||
export { default as FaPageHeader } from './basic/page-header/index.vue'
|
||||
export { default as FaPageMain } from './basic/page-main/index.vue'
|
||||
export { default as FaPagination } from './basic/pagination/index.vue'
|
||||
export { default as FaPasswordStrength } from './basic/password-strength/index.vue'
|
||||
export { default as FaPopover } from './basic/popover/index.vue'
|
||||
export { default as FaProgress } from './basic/progress/index.vue'
|
||||
export { default as FaRadioGroup } from './basic/radio-group/index.vue'
|
||||
export { default as FaScrollArea } from './basic/scroll-area/index.vue'
|
||||
export { default as FaSearchBar } from './basic/search-bar/index.vue'
|
||||
export { default as FaSelect } from './basic/select/index.vue'
|
||||
export { default as FaSlider } from './basic/slider/index.vue'
|
||||
export { default as FaSwitch } from './basic/switch/index.vue'
|
||||
export { default as FaTable } from './basic/table/index.vue'
|
||||
export type { TableAlign, TableCellSlotProps, TableColumn, TableColumnFixed, TableEmptySlotProps, TableExpandedState, TableFooterSlotProps, TableHeaderSlotProps, TableProps, TableSelectionColumn, TableSelectionDisabled, TableSortingState, TableToolbarSlotProps } from './basic/table/index.vue'
|
||||
export { default as FaTabs } from './basic/tabs/index.vue'
|
||||
export { default as FaTag } from './basic/tag/index.vue'
|
||||
export { default as FaTextarea } from './basic/textarea/index.vue'
|
||||
export { useToast as useFaToast } from './basic/toast/index'
|
||||
export { default as FaToast } from './basic/toast/index.vue'
|
||||
export { default as FaTooltip } from './basic/tooltip/index.vue'
|
||||
export { default as FaTrend } from './basic/trend/index.vue'
|
||||
export { Alert as FaAlert } from './basic/alert'
|
||||
export { Avatar as FaAvatar } from './basic/avatar'
|
||||
export { Badge as FaBadge } from './basic/badge'
|
||||
export { Button as FaButton, ButtonGroup as FaButtonGroup } from './basic/button'
|
||||
export { Card as FaCard } from './basic/card'
|
||||
export { Checkbox as FaCheckbox, CheckboxGroup as FaCheckboxGroup } from './basic/checkbox'
|
||||
export { Collapsible as FaCollapsible } from './basic/collapsible'
|
||||
export { ContextMenu as FaContextMenu } from './basic/context-menu'
|
||||
export { Descriptions as FaDescriptions } from './basic/descriptions'
|
||||
export type { DescriptionDirection, DescriptionItem, DescriptionItemBase, DescriptionSize, DescriptionSlotProps, DescriptionsProps, DescriptionValue } from './basic/descriptions'
|
||||
export { Divider as FaDivider } from './basic/divider'
|
||||
export { Drawer as FaDrawer } from './basic/drawer'
|
||||
export type { DrawerEmits, DrawerProps } from './basic/drawer'
|
||||
export { useDrawer as useFaDrawer } from './basic/drawer'
|
||||
export { Dropdown as FaDropdown } from './basic/dropdown'
|
||||
export { FileUpload as FaFileUpload } from './basic/file-upload'
|
||||
export type { FileItem, FileUploadRequestOptions } from './basic/file-upload'
|
||||
export { FixedBar as FaFixedBar } from './basic/fixed-bar'
|
||||
export { HoverCard as FaHoverCard } from './basic/hover-card'
|
||||
export { Icon as FaIcon } from './basic/icon'
|
||||
export { ImagePreview as FaImagePreview } from './basic/image-preview'
|
||||
export { useImagePreview as useFaImagePreview } from './basic/image-preview'
|
||||
export { ImageUpload as FaImageUpload } from './basic/image-upload'
|
||||
export type { UploadRequestOptions } from './basic/image-upload'
|
||||
export { Input as FaInput } from './basic/input'
|
||||
export { InputOTP as FaInputOTP } from './basic/input-otp'
|
||||
export { Kbd as FaKbd, KbdGroup as FaKbdGroup } from './basic/kbd'
|
||||
export { Label as FaLabel } from './basic/label'
|
||||
export { Modal as FaModal } from './basic/modal'
|
||||
export type { ModalEmits, ModalProps } from './basic/modal'
|
||||
export { useModal as useFaModal } from './basic/modal'
|
||||
export { NumberField as FaNumberField } from './basic/number-field'
|
||||
export { PageHeader as FaPageHeader } from './basic/page-header'
|
||||
export { PageMain as FaPageMain } from './basic/page-main'
|
||||
export { Pagination as FaPagination } from './basic/pagination'
|
||||
export { PasswordStrength as FaPasswordStrength } from './basic/password-strength'
|
||||
export { Popover as FaPopover } from './basic/popover'
|
||||
export { Progress as FaProgress } from './basic/progress'
|
||||
export { RadioGroup as FaRadioGroup } from './basic/radio-group'
|
||||
export { ScrollArea as FaScrollArea } from './basic/scroll-area'
|
||||
export { SearchBar as FaSearchBar } from './basic/search-bar'
|
||||
export { Select as FaSelect } from './basic/select'
|
||||
export { Slider as FaSlider } from './basic/slider'
|
||||
export { Switch as FaSwitch } from './basic/switch'
|
||||
export { Table as FaTable } from './basic/table'
|
||||
export type { TableAlign, TableCellSlotProps, TableColumn, TableColumnFixed, TableEmptySlotProps, TableExpandedState, TableFooterSlotProps, TableHeaderSlotProps, TableProps, TableSelectionColumn, TableSelectionDisabled, TableSortingState, TableToolbarSlotProps } from './basic/table'
|
||||
export { Tabs as FaTabs } from './basic/tabs'
|
||||
export { Tag as FaTag } from './basic/tag'
|
||||
export { Textarea as FaTextarea } from './basic/textarea'
|
||||
export { Toast as FaToast } from './basic/toast'
|
||||
export { useToast as useFaToast } from './basic/toast'
|
||||
export { Tooltip as FaTooltip } from './basic/tooltip'
|
||||
export { Trend as FaTrend } from './basic/trend'
|
||||
|
||||
Reference in New Issue
Block a user