Compare commits

...

2 Commits

Author SHA1 Message Date
Nemo Shen
3f6a00ae20
feat(TextEllipsis): add action slot (#12560)
Co-authored-by: neverland <chenjiahan.jait@bytedance.com>
2024-01-11 14:22:01 +00:00
inottn
5cb8f3253b
feat(Notify): add teleport prop (#12556) 2024-01-11 19:47:09 +08:00
11 changed files with 222 additions and 11 deletions

View File

@ -1,5 +1,6 @@
import { defineComponent, type ExtractPropTypes } from 'vue';
import {
pick,
extend,
numericProp,
unknownProp,
@ -12,6 +13,14 @@ import type { NotifyType, NotifyPosition } from './types';
const [name, bem] = createNamespace('notify');
const popupInheritProps = [
'lockScroll',
'position',
'show',
'teleport',
'zIndex',
] as const;
export const notifyProps = extend({}, popupSharedProps, {
type: makeStringProp<NotifyType>('danger'),
color: String,
@ -36,18 +45,15 @@ export default defineComponent({
return () => (
<Popup
show={props.show}
class={[bem([props.type]), props.className]}
style={{
color: props.color,
background: props.background,
}}
overlay={false}
zIndex={props.zIndex}
position={props.position}
duration={0.2}
lockScroll={props.lockScroll}
onUpdate:show={updateShow}
{...pick(props, popupInheritProps)}
>
{slots.default ? slots.default() : props.message}
</Popup>

View File

@ -122,6 +122,8 @@ Vant exports following Notify utility functions:
### NotifyOptions
When calling the `showNotify` and other related methods, the following options are supported:
| Attribute | Description | Type | Default |
| --- | --- | --- | --- |
| type | Can be set to `primary` `success` `warning` | _NotifyType_ | `danger` |
@ -133,10 +135,46 @@ Vant exports following Notify utility functions:
| background | Background color | _string_ | - |
| className | Custom className | _string \| Array \| object_ | - |
| lockScroll | Whether to lock background scroll | _boolean_ | `false` |
| teleport | Specifies a target element where Notify will be mounted | _string \| Element_ | - |
| onClick | Callback function after click | _(event: MouseEvent) => void_ | - |
| onOpened | Callback function after opened | _() => void_ | - |
| onClose | Callback function after close | _() => void_ | - |
### Props
When using `Notify` as a component, the following props are supported:
| Attribute | Description | Type | Default |
| --- | --- | --- | --- |
| v-model:show | Whether to show notify | _boolean_ | `false` |
| type | Can be set to `primary` `success` `warning` | _NotifyType_ | `danger` |
| message | Message | _string_ | - |
| z-index | Set the z-index to a fixed value | _number \| string_ | `2000+` |
| position | Position, can be set to `bottom` | _NotifyPosition_ | `top` |
| color | Message color | _string_ | `white` |
| background | Background color | _string_ | - |
| class-name | Custom className | _string \| Array \| object_ | - |
| lock-scroll | Whether to lock background scroll | _boolean_ | `false` |
| teleport | Specifies a target element where Notify will be mounted | _string \| Element_ | - |
### Events
When using `Notify` as a component, the following events are supported:
| Event | Description | Parameters |
| ------ | ------------------------------ | ------------------- |
| click | Callback function after click | _event: MouseEvent_ |
| close | Callback function after close | - |
| opened | Callback function after opened | - |
### Slots
When using `Notify` as a component, the following slots are supported:
| Name | Description |
| ------- | -------------- |
| default | Custom content |
### Types
The component exports the following type definitions:

View File

@ -148,10 +148,46 @@ Vant 中导出了以下 Notify 相关的辅助函数:
| background | 背景颜色 | _string_ | - |
| className | 自定义类名 | _string \| Array \| object_ | - |
| lockScroll | 是否锁定背景滚动 | _boolean_ | `false` |
| teleport | 指定挂载的节点,等同于 Teleport 组件的 [to 属性](https://cn.vuejs.org/api/built-in-components.html#teleport) | _string \| Element_ | - |
| onClick | 点击时的回调函数 | _(event: MouseEvent): void_ | - |
| onOpened | 完全展示后的回调函数 | _() => void_ | - |
| onClose | 关闭时的回调函数 | _() => void_ | - |
### Props
通过组件调用 `Notify` 时,支持以下 Props
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| v-model:show | 是否显示通知 | _boolean_ | `false` |
| type | 类型,可选值为 `primary` `success` `warning` | _NotifyType_ | `danger` |
| message | 展示文案,支持通过`\n`换行 | _string_ | - |
| z-index | 将组件的 z-index 层级设置为一个固定值 | _number \| string_ | `2000+` |
| position | 弹出位置,可选值为 `bottom` | _NotifyPosition_ | `top` |
| color | 字体颜色 | _string_ | `white` |
| background | 背景颜色 | _string_ | - |
| class-name | 自定义类名 | _string \| Array \| object_ | - |
| lock-scroll | 是否锁定背景滚动 | _boolean_ | `false` |
| teleport | 指定挂载的节点,等同于 Teleport 组件的 [to 属性](https://cn.vuejs.org/api/built-in-components.html#teleport) | _string \| Element_ | - |
### Events
通过组件调用 `Notify` 时,支持以下事件:
| 事件名 | 说明 | 回调参数 |
| ------ | -------------------- | ------------------- |
| click | 点击时的回调函数 | _event: MouseEvent_ |
| close | 关闭时的回调函数 | - |
| opened | 完全展示后的回调函数 | - |
### Slots
通过组件调用 `Notify` 时,支持以下插槽:
| 名称 | 说明 |
| ------- | ---------- |
| default | 自定义内容 |
### 类型定义
组件导出以下类型定义:

View File

@ -127,6 +127,28 @@ export default {
};
```
### Custom Action
Use `action` slots to custom action.
```html
<van-text-ellipsis :content="text">
<template #action="{ expanded }">
{{ expanded ? 'Collapse' : 'Expand' }}
</template>
</van-text-ellipsis>
```
```js
export default {
setup() {
const text =
'Take your time and be patient. Life itself will eventually answer all those questions it once raised for you.';
return { text };
},
};
```
## API
### Props
@ -154,6 +176,12 @@ Use [ref](https://vuejs.org/guide/essentials/template-refs.html) to get TextElli
| ------ | ---------------------- | -------------------- | ------------ |
| toggle | Toggle expanded status | _expanded?: boolean_ | - |
### Slots
| Name | Description | SlotProps |
| --------------- | ------------- | ----------------------- |
| action `v4.8.3` | Custom action | _{ expanded: boolean }_ |
### Types
The component exports the following type definitions:

View File

@ -124,6 +124,25 @@ export default {
};
```
### 自定义操作内容
通过插槽 `action` 自定义操作内容。
```html
<van-text-ellipsis :content="text">
<template #action="{ expanded }">{{ expanded ? '收起' : '展开' }}</template>
</van-text-ellipsis>
```
```js
export default {
setup() {
const text = '慢慢来,不要急,生活给你出了难题,可也终有一天会给出答案。';
return { text };
},
};
```
## API
### Props
@ -151,6 +170,12 @@ export default {
| --- | --- | --- | --- |
| toggle | 切换文本的展开状态,传 `true` 为展开,`false` 为收起,不传参为切换 | _expanded?: boolean_ | - |
### Slots
| 名称 | 说明 | 参数 |
| --------------- | ---------- | ----------------------- |
| action `v4.8.3` | 自定义操作 | _{ expanded: boolean }_ |
### 类型定义
组件导出以下类型定义:

View File

@ -37,7 +37,7 @@ export default defineComponent({
emits: ['clickAction'],
setup(props, { emit }) {
setup(props, { emit, slots }) {
const text = ref('');
const expanded = ref(false);
const hasAction = ref(false);
@ -196,11 +196,16 @@ export default defineComponent({
emit('clickAction', event);
};
const renderAction = () => (
<span class={bem('action')} onClick={onClickAction}>
{actionText.value}
</span>
);
const renderAction = () => {
const action = slots.action
? slots.action({ expanded: expanded.value })
: actionText.value;
return (
<span class={bem('action')} onClick={onClickAction}>
{action}
</span>
);
};
onMounted(calcEllipsised);

View File

@ -16,6 +16,7 @@ const t = useTranslate({
collapsePosition: '自定义省略位置',
collapseStart: '头部省略',
collapseMiddle: '中部省略',
customAction: '自定义操作内容',
},
'en-US': {
text1:
@ -31,6 +32,7 @@ const t = useTranslate({
collapsePosition: 'Custom Collapse Position',
collapseStart: 'Head Area Collapse Position',
collapseMiddle: 'Middle Area Collapse Position',
customAction: 'Custom Action',
},
});
</script>
@ -77,6 +79,14 @@ const t = useTranslate({
position="middle"
/>
</demo-block>
<demo-block :title="t('customAction')">
<van-text-ellipsis :content="t('text1')">
<template #action="{ expanded }">
{{ expanded ? t('collapseText') : t('expandText') }}
</template>
</van-text-ellipsis>
</demo-block>
</demo-block>
</template>

View File

@ -29,5 +29,10 @@ exports[`should render demo and match snapshot 1`] = `
<div class="van-text-ellipsis">
</div>
</div>
<div>
<!--[-->
<div class="van-text-ellipsis">
</div>
</div>
</div>
`;

View File

@ -41,5 +41,13 @@ exports[`should render demo and match snapshot 1`] = `
</span>
</div>
</div>
<div>
<div class="van-text-ellipsis">
...
<span class="van-text-ellipsis__action">
expand
</span>
</div>
</div>
</div>
`;

View File

@ -1,5 +1,32 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`should render action slot correctly 1`] = `
<div class="van-text-ellipsis">
Vant is a lightweight, customizable mobile component library th...
<span class="van-text-ellipsis__action">
Collapse
</span>
</div>
`;
exports[`should render action slot correctly 2`] = `
<div class="van-text-ellipsis">
Vant is a lightweight, customizable mobile component library that was open sourced in 2017. Currently Vant officially provides Vue 2 version, Vue 3 version and WeChat applet version, and the community team maintains React version and Alipay applet version.
<span class="van-text-ellipsis__action">
Expand
</span>
</div>
`;
exports[`should render action slot correctly 3`] = `
<div class="van-text-ellipsis">
Vant is a lightweight, customizable mobile component library th...
<span class="van-text-ellipsis__action">
Collapse
</span>
</div>
`;
exports[`should render content correctly 1`] = `
<div class="van-text-ellipsis">
Vant is a lightweight, customizable mobile component library th...

View File

@ -1,6 +1,6 @@
import { mount } from '../../../test';
import { nextTick } from 'vue';
import TextEllipsis from '..';
import TextEllipsis, { type TextEllipsisInstance } from '..';
const originGetComputedStyle = window.getComputedStyle;
@ -32,6 +32,29 @@ afterAll(() => {
window.getComputedStyle = originGetComputedStyle;
});
test('should render action slot correctly', async () => {
const wrapper = mount(TextEllipsis, {
props: {
content,
},
slots: {
action: ({ expanded }) => (expanded ? 'Expand' : 'Collapse'),
},
});
await nextTick();
expect(wrapper.html()).toMatchSnapshot();
(wrapper.vm as TextEllipsisInstance).toggle();
await nextTick();
expect(wrapper.html()).toMatchSnapshot();
(wrapper.vm as TextEllipsisInstance).toggle();
await nextTick();
expect(wrapper.html()).toMatchSnapshot();
});
test('should render content correctly', async () => {
const wrapper = mount(TextEllipsis, {
props: {