Skip to content

Commit

Permalink
feat:链接组件开发完成
Browse files Browse the repository at this point in the history
  • Loading branch information
blankzhang authored and blankzhang committed May 13, 2024
1 parent 710af78 commit f8101a9
Show file tree
Hide file tree
Showing 12 changed files with 306 additions and 1 deletion.
1 change: 1 addition & 0 deletions components/_style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,4 @@ import './transfer/style';
import './input-file/style';
import './breadcrumb/style';
import './text-highlight/style';
import './link/style';
1 change: 1 addition & 0 deletions components/components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,4 @@ export * from './transfer';
export * from './input-file';
export * from './breadcrumb';
export * from './text-highlight';
export * from './link';
11 changes: 11 additions & 0 deletions components/link/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { withInstall } from '../_util/withInstall';
import type { SFCWithInstall } from '../_util/interface';
import Link from './link';

export { linkProps } from './props';
export type { LinkProps } from './props';

type LinkType = SFCWithInstall<typeof Link>;
export const FLink = withInstall<LinkType>(Link as LinkType);

export default FLink;
40 changes: 40 additions & 0 deletions components/link/link.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { computed, defineComponent } from 'vue';
import getPrefixCls from '../_util/getPrefixCls';
import { useTheme } from '../_theme/useTheme';
import { linkProps } from './props';

const prefixCls = getPrefixCls('link');

export default defineComponent({
name: 'FLink',
props: linkProps,
setup(props, { slots }) {
useTheme();

const linkClass = computed(() => {
const cls: string[] = [`${prefixCls}-container`,
`${prefixCls}-type-${props.type}`,
`${prefixCls}-size-${props.size}`,
];

props.disabled && cls.push(`${prefixCls}-container-disabled`);
props.underline && cls.push('underline');
return cls;
});

const renderLink = () => {
return (
<a href={props.href} target={props.target} class={linkClass.value}>
{slots.icon ? (<div class="icon"> {slots.icon?.()}</div>) : null}
{slots.default?.()}
</a>
);
};

return () => (
<div class={prefixCls}>
{renderLink()}
</div>
);
},
});
50 changes: 50 additions & 0 deletions components/link/props.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import type { ComponentObjectPropsOptions, PropType } from 'vue';
import type { ExtractPublicPropTypes } from '../_util/interface';

export enum Size {
LARGE = 'large',
MIDDLE = 'middle',
SMALL = 'small',
}

export enum Type {
PRIMARY = 'primary',
SUCCESS = 'success',
DANGER = 'danger',
WARNING = 'warning',
}

export enum TargetType {
BLANK = '_blank',
SELF = '_self',
PARENT = '_parent',
TOP = '_top',
}

export const linkProps = {
size: {
type: String as PropType<Size>,
default: Size.MIDDLE,
},
type: {
type: String as PropType<Type>,
default: Type.PRIMARY,
},
underline: {
type: Boolean,
default: true,
},
disabled: {
type: Boolean,
default: false,
},
href: {
type: String,
},
target: {
type: String as PropType<TargetType>,
default: TargetType.SELF,
},
} as const satisfies ComponentObjectPropsOptions;

export type LinkProps = ExtractPublicPropTypes<typeof linkProps>;
83 changes: 83 additions & 0 deletions components/link/style/index.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
@import '../../style/themes/index';
@import '../../style/mixins/index';


@link-prefix-cls: ~'@{cls-prefix}-link';

@link-height-small: @link-height-base - 2;
@link-height-base: 20px;
@link-height-large: @link-height-base + 2;

.@{link-prefix-cls} {
--f-link-height: @link-height-base;
display: inline-flex;
height: var(--f-link-height);
line-height: var(--f-link-height);

&-container {
position: relative;
display: inline-flex;
align-items: center;
height: var(--f-link-height);
line-height: var(--f-link-height);
cursor: pointer;

.icon {
display: flex;
align-items: center;
justify-content: center;
margin-right: 4px;
}

&-disabled, &:hover {
&::after {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgb(255 255 255 / 0.4); /* 半透明的白色 */
content: "";
pointer-events: none; /* 让鼠标事件穿透蒙层 */
}
}

&-disabled {
cursor: not-allowed;
}

&:not(&-disabled).underline:hover {
border-bottom: 1px solid currentcolor;
}
}

&-size-middle {
font-size: var(--f-font-size-base);
}

&-size-small {
--f-link-height: @link-height-small;
font-size: calc(var(--f-font-size-base) - 2px);
}

&-size-large {
--f-link-height: @link-height-large;
font-size: calc(var(--f-font-size-base) + 2px);
}

&-type-success {
color: var(--f-success-color);
}

&-type-danger {
color: var(--f-danger-color);
}

&-type-warning {
color: var(--f-warning-color);
}

&-type-primary {
color: var(--f-primary-color);
}
}
2 changes: 2 additions & 0 deletions components/link/style/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import '../../style';
import './index.less';
47 changes: 47 additions & 0 deletions docs/.vitepress/components/link/base.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<template>
<FForm :labelWidth="60">
<FFormItem label="尺寸:">
<FRadioGroup
v-model="size"
:options="[
{ label: 'small', value: 'small' },
{ label: 'middle(默认)', value: 'middle' },
{ label: 'large', value: 'large' },
]"
/>
</FFormItem>
<FFormItem label="下划线:">
<FRadioGroup
v-model="underline"
:options="[
{ label: '启用(默认)', value: true },
{ label: '不启用', value: false },
]"
/>
</FFormItem>
</FForm>

<FDivider />

<FSpace>
<FLink href="https://www.baidu.com" target="_blank" :underline="underline" :size="size" type="primary">primary</FLink>
<FLink :underline="underline" :size="size" type="success">success</FLink>
<FLink :underline="underline" :size="size" type="warning">warning</FLink>
<FLink :underline="underline" :size="size" type="danger">danger</FLink>
<FLink :underline="underline" disabled :size="size">disabled</FLink>
</FSpace>
</template>

<script setup>
import { ref } from 'vue';
const size = ref('middle');
const underline = ref(true);
</script>

<style scoped>
.fes-link {
margin-right: 8px;
}
</style>
3 changes: 3 additions & 0 deletions docs/.vitepress/components/link/href.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<template>
<FLink href="https://fesjs.mumblefe.cn/" target="_blank">Fes.js官网</FLink>
</template>
12 changes: 12 additions & 0 deletions docs/.vitepress/components/link/icon.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<template>
<FLink href="https://fes-design.mumblefe.cn/" target="_blank">
<template #icon>
<ProductOutlined />
</template>
首页
</FLink>
</template>

<script setup>
</script>
51 changes: 51 additions & 0 deletions docs/.vitepress/components/link/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Link 链接

文字超链接

## 组件注册

```js
import { FLink } from '@fesjs/fes-design';

app.use(FLink);
```

## 代码演示

### 基础用法

:::demo
base.vue
:::

### 跳转
通过设置`target`,设定跳转行为,同原生a标签的`target`属性
`href`不设置,则点击不会发生任何跳转

:::demo
href.vue
:::

### 图标
提供了图标的插槽

:::demo
icon.vue
:::

## Props
| 属性 | 说明 | 类型 | 默认值 |
| --------- | --------------------------------------------------- | --------- | --------- |
| size | 尺寸大小,可选`small``middle``large` | `string` | `middle` |
| type | 类型,可选`primary``success``danger``warning` | `string` | `primary` |
| underline | 展示下划线 | `boolean` | `true` |
| disabled | 是否禁用 | `boolean` | `false` |
| href | 跳转链接 | `string` | `-` |
| target | 跳转行为,同原生target | `string` | `_self` |

## Slots

| 名称 | 说明 | 参数 |
| ------- | -------- | ---- |
| default | 链接内容 | `-` |
| icon | 图标 | `-` |
6 changes: 5 additions & 1 deletion docs/.vitepress/configs/sidebar/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { type DefaultTheme } from 'vitepress';
import type { DefaultTheme } from 'vitepress';

const sidebarConfig: Record<string, DefaultTheme.Config['sidebar']> = {
zh: {
Expand Down Expand Up @@ -178,6 +178,10 @@ const sidebarConfig: Record<string, DefaultTheme.Config['sidebar']> = {
text: 'Image 图片',
link: '/zh/components/image',
},
{
text: 'Link 链接',
link: '/zh/components/link',
},
{
text: 'Table 表格',
link: '/zh/components/table',
Expand Down

0 comments on commit f8101a9

Please sign in to comment.