diff --git a/devui/breadcrumb/index.ts b/devui/breadcrumb/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..e06a2df4c8c1b9c3af69bfcff07531258dd53461 --- /dev/null +++ b/devui/breadcrumb/index.ts @@ -0,0 +1,19 @@ +import type { App } from 'vue' +import Breadcrumb from './src/breadcrumb' +import BreadcrumbItem from './src/breadcrumb-item' + +Breadcrumb.install = function (app: App): void { + app.component(Breadcrumb.name, Breadcrumb) + app.component(BreadcrumbItem.name, BreadcrumbItem) +} + +export { Breadcrumb } + +export default { + title: 'Breadcrumb 面包屑', + category: '导航', + status: '开发中', + install(app: App): void { + app.use(Breadcrumb as any) + }, +} diff --git a/devui/breadcrumb/src/breadcrumb-item-types.ts b/devui/breadcrumb/src/breadcrumb-item-types.ts new file mode 100644 index 0000000000000000000000000000000000000000..04542fad750a46614191d744c0e68a15b24cb422 --- /dev/null +++ b/devui/breadcrumb/src/breadcrumb-item-types.ts @@ -0,0 +1,32 @@ +import type { ExtractPropTypes, PropType } from 'vue' + +export interface MenuConfig { + name: string // 显示的名称 + link: string // 跳转的路径,可为绝对路径与相对路径,注意需要与路由的配置一致 + target?: string // 规定在何处打开链接文档 +} + +export const breadcrumbItemProps = { + /** + * 可选,是否需要显示下拉箭头及下拉列表内容 + */ + showMenu: { + type: Boolean, + default: false + }, + /** + * 可选,showMenu 为 true 时传入,下拉列表的显示内容 + */ + menuList: { + type: Array as PropType> + }, + /** + * 可选,showMenu 为 true 时传入,下拉列表是否需要搜索功能 + */ + isSearch: { + type: Boolean, + dafault: false + } +} as const + +export type BreadcrumbItemProps = ExtractPropTypes diff --git a/devui/breadcrumb/src/breadcrumb-item.scss b/devui/breadcrumb/src/breadcrumb-item.scss new file mode 100644 index 0000000000000000000000000000000000000000..dd06a51aa8420085696847f4577bba91ee02c269 --- /dev/null +++ b/devui/breadcrumb/src/breadcrumb-item.scss @@ -0,0 +1,39 @@ +@import '../../style/theme/color'; +@import '../../style/core/_font'; +@import '../../style/core/animation'; + +.devui-breadcrumb-font-style { + font-size: $devui-font-size; + color: $devui-aide-text; + line-height: 18px; +} + +.devui-breadcrumb-item { + @extend.devui-breadcrumb-font-style; + + cursor: auto; + + a { + @extend.devui-breadcrumb-font-style; + + cursor: pointer; + + &:hover { + color: $devui-text; + text-decoration: none; + } + } + + a, + span { + transition: + color $devui-animation-duration-slow + $devui-animation-ease-in-out-smooth; + } +} + +.devui-breadcrumb-separator { + @extend.devui-breadcrumb-font-style; + + margin: 0 4px; +} diff --git a/devui/breadcrumb/src/breadcrumb-item.tsx b/devui/breadcrumb/src/breadcrumb-item.tsx new file mode 100644 index 0000000000000000000000000000000000000000..39a2674a21fba7658b348db97c8b824b8a99eede --- /dev/null +++ b/devui/breadcrumb/src/breadcrumb-item.tsx @@ -0,0 +1,26 @@ +import { defineComponent, inject } from 'vue' + +import { + breadcrumbItemProps, + BreadcrumbItemProps +} from './breadcrumb-item-types' +import './breadcrumb-item.scss' + +export default defineComponent({ + name: 'DBreadcrumbItem', + props: breadcrumbItemProps, + setup(props: BreadcrumbItemProps, { slots }) { + const separatorIcon = inject('separatorIcon') + return () => { + const renderBreadcrumbSperator = () => { + return {separatorIcon} + } + return ( +
+ {slots?.default()} + {renderBreadcrumbSperator()} +
+ ) + } + } +}) diff --git a/devui/breadcrumb/src/breadcrumb-types.ts b/devui/breadcrumb/src/breadcrumb-types.ts new file mode 100644 index 0000000000000000000000000000000000000000..f8d43be8c3b06343c891aaa22d5d33cac4cd8998 --- /dev/null +++ b/devui/breadcrumb/src/breadcrumb-types.ts @@ -0,0 +1,26 @@ +import type { ExtractPropTypes, PropType } from 'vue' + +export interface SourceConfig { + title: string // 显示的名称 + link?: string // 跳转的路径 + target?: string // 规定在何处打开链接文档 + noNavigation?: boolean // 链接是否不可跳转,一般用于当前所处位置不可跳转的配置 +} + +export const breadcrumbProps = { + /** + * 可选,面包屑根据配置的 source 按照默认渲染方式显示 + */ + source: { + type: Array as PropType>, + default: [] + }, + /** + * 可选,自定义分隔符样式 + */ + separatorIcon: { + type: String + } +} as const + +export type BreadcrumbProps = ExtractPropTypes diff --git a/devui/breadcrumb/src/breadcrumb.scss b/devui/breadcrumb/src/breadcrumb.scss new file mode 100644 index 0000000000000000000000000000000000000000..231d8ebbc8e2fd86184367490f4e05d45d513a7b --- /dev/null +++ b/devui/breadcrumb/src/breadcrumb.scss @@ -0,0 +1,10 @@ +.devui-breadcrumb { + display: flex; + align-items: center; + + .devui-breadcrumb-item:last-child { + .devui-breadcrumb-separator { + display: none; + } + } +} diff --git a/devui/breadcrumb/src/breadcrumb.tsx b/devui/breadcrumb/src/breadcrumb.tsx new file mode 100644 index 0000000000000000000000000000000000000000..0da81a2945e7805bb4276a664fe65abf5d6f3a9f --- /dev/null +++ b/devui/breadcrumb/src/breadcrumb.tsx @@ -0,0 +1,45 @@ +import { defineComponent, provide } from 'vue' +import { + breadcrumbProps, + BreadcrumbProps, + SourceConfig +} from './breadcrumb-types' +import DBreadcrumbItem from './breadcrumb-item' +import { getPropsSlot } from '../../shared/util/props-util' +import './breadcrumb.scss' + +export default defineComponent({ + name: 'DBreadcrumb', + components: { + DBreadcrumbItem + }, + props: breadcrumbProps, + setup(props: BreadcrumbProps, { slots }) { + const separatorIcon = getPropsSlot(slots, props, 'separatorIcon') ?? '/' + provide('separatorIcon', separatorIcon) + + const renderBreadItemList = (source: SourceConfig[]) => { + return source.map((item: SourceConfig) => { + return ( + + {!item.noNavigation ? ( + + {item.title} + + ) : null} + {item.noNavigation ? {item.title} : null} + + ) + }) + } + return () => { + return ( +
+ {props.source && props.source.length + ? renderBreadItemList(props.source) + : slots?.default()} +
+ ) + } + } +}) diff --git a/devui/shared/util/props-util.ts b/devui/shared/util/props-util.ts new file mode 100644 index 0000000000000000000000000000000000000000..9411ed4d2e62d09762b63e19f720c9546ef9fe3c --- /dev/null +++ b/devui/shared/util/props-util.ts @@ -0,0 +1,8 @@ +import type { Slots, VNode } from 'vue' +export function getPropsSlot( + slots: Slots, + props: unknown, + prop = 'default' +): VNode | string | undefined { + return props[prop] ?? slots[prop]?.() +} diff --git a/docs/components/breadcrumb/index.md b/docs/components/breadcrumb/index.md new file mode 100644 index 0000000000000000000000000000000000000000..fd4499ac4bc6925b40c7087b1fdff23028ff4afe --- /dev/null +++ b/docs/components/breadcrumb/index.md @@ -0,0 +1,163 @@ +# Breadcrumb + +显示当前页面层级的组件。 + +**何时使用** + +1. 用户需要了解当前出于什么层级时; +2. 用户需要快速返回之前的层级时; +3. 用户需要导航至与指定层级相同的任意页面时。 + +### 基础面包屑 + +:::demo +```vue + +``` +::: + +### 传入source + +:::demo +```vue + + +``` +::: + +### 可下拉的面包屑【TODO】 + + + +### 自定义分隔符的面包屑 + +:::demo +```vue + +``` +::: +### API + +### d-breadcrumb 参数 + +| 参数 | 类型 | 默认 | 说明 | 跳转 Demo | +| :-----------: | :------------------------------------: | :---------------------------: | :------------------------------------------------- | ------------------------- | +| separatorIcon | [`string`](#自定义分隔符的面包屑) | '/' | 可选,自定义分隔符样式 | [自定义分隔符的面包屑](#自定义分隔符的面包屑) +| source | [`Array`](#SourceConfig) | [] | 可选,面包屑根据配置的 source 按照默认渲染方式显示 | [传入source](#传入source) | + + +### 接口 & 类型定义 + + + +### SourceConfig + +```ts +export interface SourceConfig { + title: string; // 显示的名称 + link?: string; // 跳转的路径 + target?: string // 规定在何处打开链接文档 + noNavigation?: boolean; // 链接是否不可跳转,一般用于当前所处位置不可跳转的配置 +} +``` \ No newline at end of file