diff --git a/compiled/alipay/demo/app.json b/compiled/alipay/demo/app.json index 5d59e2224..7e4f492d9 100644 --- a/compiled/alipay/demo/app.json +++ b/compiled/alipay/demo/app.json @@ -97,7 +97,8 @@ "pages/Slider/index", "pages/TabsElevator/index", "pages/IndexBarScrollView/index", - "pages/SelectorFilter/index" + "pages/SelectorFilter/index", + "pages/Typography/index" ], "window": { "enableWK": "YES", diff --git a/compiled/alipay/demo/pages/Typography/index.axml b/compiled/alipay/demo/pages/Typography/index.axml new file mode 100644 index 000000000..87e7fe527 --- /dev/null +++ b/compiled/alipay/demo/pages/Typography/index.axml @@ -0,0 +1,136 @@ + + + 简短文字 + + + + 简短文字中等加粗 + + + + 简短文字重度加粗 + + + + 简短文字 + + + + 简短文字 + + + + 完整展示:Ant Design, a design language for background applications, is refined by Ant UED Team. Ant Design, a design language for background applications, is refined by Ant UED Team. + + + + 超出 3 行的内容省略展示:Ant Design, a design language for background applications, is refined by Ant UED Team. Ant Design, a design language for background applications, is refined by Ant UED Team. + + + + + + 链接禁用 + + + + 链接 + + + + 复制 + + + + 删除 + + + + 编辑 + + + + 定位 + + + + 分享 + + + + + 分享试试 + + diff --git a/compiled/alipay/demo/pages/Typography/index.js b/compiled/alipay/demo/pages/Typography/index.js new file mode 100644 index 000000000..495043faa --- /dev/null +++ b/compiled/alipay/demo/pages/Typography/index.js @@ -0,0 +1,20 @@ +Page({ + data: {}, + handleTap(e) { + const { type, text } = e.currentTarget.dataset; + if (type === 'copy') { + my.setClipboard({ + text, + success() { + my.showToast({ type: 'success', content: `复制成功` }); + }, + }); + return; + } + my.alert({ content: `点击${type}` }); + }, + handleDisabledTap(e) { + const { type } = e.currentTarget.dataset; + my.alert({ content: `禁用状态下点击${type}` }); + }, +}); diff --git a/compiled/alipay/demo/pages/Typography/index.json b/compiled/alipay/demo/pages/Typography/index.json new file mode 100644 index 000000000..ec4f6ac0b --- /dev/null +++ b/compiled/alipay/demo/pages/Typography/index.json @@ -0,0 +1,7 @@ +{ + "defaultTitle": "Typography", + "usingComponents": { + "ant-typography": "../../../src/Typography/index", + "ant-container": "../../../src/Container/index" + } +} \ No newline at end of file diff --git a/compiled/alipay/demo/pages/Typography/index.less b/compiled/alipay/demo/pages/Typography/index.less new file mode 100644 index 000000000..4e1c25d2a --- /dev/null +++ b/compiled/alipay/demo/pages/Typography/index.less @@ -0,0 +1,3 @@ +.typography { + margin-bottom: 16px; +} diff --git a/compiled/alipay/demo/utils/constants.js b/compiled/alipay/demo/utils/constants.js index 63c189485..4262c0463 100644 --- a/compiled/alipay/demo/utils/constants.js +++ b/compiled/alipay/demo/utils/constants.js @@ -464,5 +464,15 @@ export const componentList = [ }, ], }, + { + type: '实验性质的组件', + list: [ + { + name: 'Typography', + nameZN: '排版', + path: '/pages/Typography/index', + }, + ], + }, ]; export const allComponents = componentList.reduce((re, v) => [...re, ...v.list], []); diff --git a/compiled/alipay/src/Typography/index.axml b/compiled/alipay/src/Typography/index.axml new file mode 100644 index 000000000..b1bd2030f --- /dev/null +++ b/compiled/alipay/src/Typography/index.axml @@ -0,0 +1,41 @@ + + + + + + + + + + + + {{text}} + + + + + + + + diff --git a/compiled/alipay/src/Typography/index.json b/compiled/alipay/src/Typography/index.json new file mode 100644 index 000000000..07a8bdbc4 --- /dev/null +++ b/compiled/alipay/src/Typography/index.json @@ -0,0 +1,6 @@ +{ + "component": true, + "usingComponents": { + "icon": "../Icon/index" + } +} diff --git a/compiled/alipay/src/Typography/index.less b/compiled/alipay/src/Typography/index.less new file mode 100644 index 000000000..d5da1cdfc --- /dev/null +++ b/compiled/alipay/src/Typography/index.less @@ -0,0 +1,60 @@ +@import (reference) '../style/themes/index.less'; + +@tabsPrefix: ant-typography; + +.@{tabsPrefix} { + &-container { + font-size: 28 * @rpx; + display: flex; + align-items: center; + width: fit-content; + .@{tabsPrefix} { + &-text { + line-height: @default-line-height; + + &.lineThrough { + text-decoration: line-through; + } + &.underline { + text-decoration: underline; + text-decoration-skip-ink: auto; + } + + &-normal { + font-family: PingFangSC-Regular; + } + + &-medium { + font-family: PingFangSC-Medium; + } + + &-bold { + font-family: PingFangSC-SemiBold; + } + } + &-icon { + &-container { + display: flex; + align-items: center; + &.left { + margin-right: @size-1; + } + &.right { + margin-left: @size-1; + } + } + &-image { + display: block; + } + } + } + } + + &-disabled { + opacity: @opacity-disabled; + } + + &-hover { + opacity: @opacity-disabled; + } +} diff --git a/compiled/alipay/src/Typography/index.md b/compiled/alipay/src/Typography/index.md new file mode 100644 index 000000000..515a2f687 --- /dev/null +++ b/compiled/alipay/src/Typography/index.md @@ -0,0 +1,46 @@ +--- +nav: + path: /components +group: + title: 实验性质的组件 + order: 15 +toc: content +--- + +# Typography 排版 + +## 何时使用 + +- 需要对一段文本进行展示时使用,支持省略,兼容不同平台的加粗等。 +- 当需要带图标的行动点操作按钮时可以使用。 + +## 注意事项 + +- `icon` 属性可以支持 `Icon` 组件的 `type` 属性,也可以直接传入图标的链接地址。 +- 禁用模式下,可以传入 `onDisabledTap` 事件,用于监听禁用状态下,用户对文本的点击。 + +## 代码示例 + +### 基础用法 + + + +## 属性 + +| 属性 | 说明 | 类型 | 默认值 | +| --------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------ | -------- | +| text | 文本内容 | string | - | +| iconPosition | 图标位置 | `left` \| `right` | `right` | +| icon | 图标,可以支持 Icon 组件的 type 属性,也可以直接传入图标的链接地址 | IconType \| string | '' | +| className | 样式类 | string | - | +| activeClassName | 点击是激活态样式类 | string | - | +| style | 样式 | string | - | +| disabled | 是否禁用 | boolean | false | +| selectable | 是否可被选中 | boolean | false | +| fontWeight | 字重,兼容 iOS、Android 平台的加粗效果 | `normal` \| `medium` \| `bold` | `normal` | +| lineThrough | 添加删除线样式 | boolean | false | +| underline | 添加下划线样式 | boolean | false | +| ellipsisRow | 多行省略,值须大于等于 1,表现同 css 的 -webkit-line-clamp 属性一致 | number | - | +| onTap | 点击按钮,触发此回调 | (e: Event) => void | - | +| catchTap | 点击按钮,触发此回调,非冒泡 | (e: Event) => void | - | +| onDisabledTap | 禁用状态下,点击按钮,触发此回调 | (e: Event) => void | - | diff --git a/compiled/alipay/src/Typography/index.sjs b/compiled/alipay/src/Typography/index.sjs new file mode 100644 index 000000000..9e5cbb5ea --- /dev/null +++ b/compiled/alipay/src/Typography/index.sjs @@ -0,0 +1,28 @@ +function isUrl(string) { + return !!(string.startsWith('http://') || string.startsWith('https://')); +} +function getFontWeight(fontWeight, phonemodel) { + var type2weight = { + normal: { + Android: 'normal', + iOS: 'normal' + }, + medium: { + Android: 'bold', + iOS: '500' + }, + bold: { + Android: 'bold', + iOS: 'bold' + } + }; + return (type2weight[fontWeight] || type2weight['normal'])[phonemodel]; +} +function isiOS(phonemodel) { + return phonemodel === 'iOS'; +} +export default { + isUrl: isUrl, + getFontWeight: getFontWeight, + isiOS: isiOS +}; \ No newline at end of file diff --git a/compiled/alipay/src/Typography/index.ts b/compiled/alipay/src/Typography/index.ts new file mode 100644 index 000000000..3a44aff5a --- /dev/null +++ b/compiled/alipay/src/Typography/index.ts @@ -0,0 +1,39 @@ +import { + Component, + triggerEventOnly, + triggerCatchEvent, + getValueFromProps, +} from '../_util/simply'; +import { TypographyDefaultProps } from './props'; + +Component( + TypographyDefaultProps, + { + onTap(e) { + const disabled = getValueFromProps(this, 'disabled'); + if (disabled) { + triggerEventOnly(this, 'disabledTap', e); + return; + } + triggerEventOnly(this, 'tap', e); + }, + catchTap(e) { + const disabled = getValueFromProps(this, 'disabled'); + if (disabled) { + triggerEventOnly(this, 'disabledTap', e); + return; + } + triggerCatchEvent(this, 'catchTap', e); + }, + }, + { phonemodel: '' }, + null, + { + onInit() { + const { platform } = my.env; + this.setData({ + phonemodel: platform, + }); + }, + } +); diff --git a/compiled/alipay/src/Typography/props.ts b/compiled/alipay/src/Typography/props.ts new file mode 100644 index 000000000..195befd63 --- /dev/null +++ b/compiled/alipay/src/Typography/props.ts @@ -0,0 +1,32 @@ +import { IBaseProps, IconType } from '../_util/base'; + +export interface ITypographyProps extends IBaseProps { + text?: string; + iconPosition?: 'left' | 'right'; + icon?: IconType | string; + activeClassName?: string; + disabled?: boolean; + selectable?: boolean; + fontWeight?: 'normal' | 'medium' | 'bold' | ''; + lineThrough?: boolean; + underline?: boolean; + ellipsisRow?: number; + onTap?: (event: any) => void; + catchTap?: (event: any) => void; + onDisabledTap?: (event: any) => void; +} + +export const TypographyDefaultProps: ITypographyProps = { + text: '', + iconPosition: 'right', + icon: '', + className: '', + activeClassName: '', + style: '', + disabled: false, + selectable: false, + fontWeight: 'normal', + lineThrough: false, + underline: false, + ellipsisRow: null, +}; diff --git a/compiled/wechat/demo/utils/constants.js b/compiled/wechat/demo/utils/constants.js index c8280a47d..6955bc970 100644 --- a/compiled/wechat/demo/utils/constants.js +++ b/compiled/wechat/demo/utils/constants.js @@ -459,5 +459,15 @@ export const componentList = [ }, ], }, + { + type: '实验性质的组件', + list: [ + { + name: 'Typography', + nameZN: '排版', + path: '/pages/Typography/index', + }, + ], + }, ]; export const allComponents = componentList.reduce((re, v) => [...re, ...v.list], []); diff --git a/demo/pages/Typography/index.axml b/demo/pages/Typography/index.axml new file mode 100644 index 000000000..87e7fe527 --- /dev/null +++ b/demo/pages/Typography/index.axml @@ -0,0 +1,136 @@ + + + 简短文字 + + + + 简短文字中等加粗 + + + + 简短文字重度加粗 + + + + 简短文字 + + + + 简短文字 + + + + 完整展示:Ant Design, a design language for background applications, is refined by Ant UED Team. Ant Design, a design language for background applications, is refined by Ant UED Team. + + + + 超出 3 行的内容省略展示:Ant Design, a design language for background applications, is refined by Ant UED Team. Ant Design, a design language for background applications, is refined by Ant UED Team. + + + + + + 链接禁用 + + + + 链接 + + + + 复制 + + + + 删除 + + + + 编辑 + + + + 定位 + + + + 分享 + + + + + 分享试试 + + diff --git a/demo/pages/Typography/index.json5 b/demo/pages/Typography/index.json5 new file mode 100644 index 000000000..68b10aa81 --- /dev/null +++ b/demo/pages/Typography/index.json5 @@ -0,0 +1,14 @@ +{ + /// #if WECHAT + "navigationBarTitleText": "Typography", + /// #endif + + /// #if ALIPAY + "defaultTitle": "Typography", + /// #endif + + "usingComponents": { + "ant-typography": "../../../src/Typography/index", + "ant-container": "../../../src/Container/index" + } +} diff --git a/demo/pages/Typography/index.less b/demo/pages/Typography/index.less new file mode 100644 index 000000000..4e1c25d2a --- /dev/null +++ b/demo/pages/Typography/index.less @@ -0,0 +1,3 @@ +.typography { + margin-bottom: 16px; +} diff --git a/demo/pages/Typography/index.ts b/demo/pages/Typography/index.ts new file mode 100644 index 000000000..47b284cd4 --- /dev/null +++ b/demo/pages/Typography/index.ts @@ -0,0 +1,20 @@ +Page({ + data: {}, + handleTap(e) { + const { type, text } = e.currentTarget.dataset; + if (type === 'copy') { + my.setClipboard({ + text, + success() { + my.showToast({ type: 'success', content: `复制成功` }); + }, + }); + return; + } + my.alert({ content: `点击${type}` }); + }, + handleDisabledTap(e) { + const { type } = e.currentTarget.dataset; + my.alert({ content: `禁用状态下点击${type}` }); + }, +}); diff --git a/demo/utils/constants.ts b/demo/utils/constants.ts index 4b411ad07..e8b544817 100644 --- a/demo/utils/constants.ts +++ b/demo/utils/constants.ts @@ -466,6 +466,16 @@ export const componentList = [ }, ], }, + { + type: '实验性质的组件', + list: [ + { + name: 'Typography', + nameZN: '排版', + path: '/pages/Typography/index', + }, + ], + }, ]; export const allComponents = componentList.reduce( diff --git a/src/Typography/index.axml b/src/Typography/index.axml new file mode 100644 index 000000000..b1bd2030f --- /dev/null +++ b/src/Typography/index.axml @@ -0,0 +1,41 @@ + + + + + + + + + + + + {{text}} + + + + + + + + diff --git a/src/Typography/index.json b/src/Typography/index.json new file mode 100644 index 000000000..07a8bdbc4 --- /dev/null +++ b/src/Typography/index.json @@ -0,0 +1,6 @@ +{ + "component": true, + "usingComponents": { + "icon": "../Icon/index" + } +} diff --git a/src/Typography/index.less b/src/Typography/index.less new file mode 100644 index 000000000..d5da1cdfc --- /dev/null +++ b/src/Typography/index.less @@ -0,0 +1,60 @@ +@import (reference) '../style/themes/index.less'; + +@tabsPrefix: ant-typography; + +.@{tabsPrefix} { + &-container { + font-size: 28 * @rpx; + display: flex; + align-items: center; + width: fit-content; + .@{tabsPrefix} { + &-text { + line-height: @default-line-height; + + &.lineThrough { + text-decoration: line-through; + } + &.underline { + text-decoration: underline; + text-decoration-skip-ink: auto; + } + + &-normal { + font-family: PingFangSC-Regular; + } + + &-medium { + font-family: PingFangSC-Medium; + } + + &-bold { + font-family: PingFangSC-SemiBold; + } + } + &-icon { + &-container { + display: flex; + align-items: center; + &.left { + margin-right: @size-1; + } + &.right { + margin-left: @size-1; + } + } + &-image { + display: block; + } + } + } + } + + &-disabled { + opacity: @opacity-disabled; + } + + &-hover { + opacity: @opacity-disabled; + } +} diff --git a/src/Typography/index.md b/src/Typography/index.md new file mode 100644 index 000000000..515a2f687 --- /dev/null +++ b/src/Typography/index.md @@ -0,0 +1,46 @@ +--- +nav: + path: /components +group: + title: 实验性质的组件 + order: 15 +toc: content +--- + +# Typography 排版 + +## 何时使用 + +- 需要对一段文本进行展示时使用,支持省略,兼容不同平台的加粗等。 +- 当需要带图标的行动点操作按钮时可以使用。 + +## 注意事项 + +- `icon` 属性可以支持 `Icon` 组件的 `type` 属性,也可以直接传入图标的链接地址。 +- 禁用模式下,可以传入 `onDisabledTap` 事件,用于监听禁用状态下,用户对文本的点击。 + +## 代码示例 + +### 基础用法 + + + +## 属性 + +| 属性 | 说明 | 类型 | 默认值 | +| --------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------ | -------- | +| text | 文本内容 | string | - | +| iconPosition | 图标位置 | `left` \| `right` | `right` | +| icon | 图标,可以支持 Icon 组件的 type 属性,也可以直接传入图标的链接地址 | IconType \| string | '' | +| className | 样式类 | string | - | +| activeClassName | 点击是激活态样式类 | string | - | +| style | 样式 | string | - | +| disabled | 是否禁用 | boolean | false | +| selectable | 是否可被选中 | boolean | false | +| fontWeight | 字重,兼容 iOS、Android 平台的加粗效果 | `normal` \| `medium` \| `bold` | `normal` | +| lineThrough | 添加删除线样式 | boolean | false | +| underline | 添加下划线样式 | boolean | false | +| ellipsisRow | 多行省略,值须大于等于 1,表现同 css 的 -webkit-line-clamp 属性一致 | number | - | +| onTap | 点击按钮,触发此回调 | (e: Event) => void | - | +| catchTap | 点击按钮,触发此回调,非冒泡 | (e: Event) => void | - | +| onDisabledTap | 禁用状态下,点击按钮,触发此回调 | (e: Event) => void | - | diff --git a/src/Typography/index.sjs.ts b/src/Typography/index.sjs.ts new file mode 100644 index 000000000..a9aca93d1 --- /dev/null +++ b/src/Typography/index.sjs.ts @@ -0,0 +1,31 @@ +function isUrl(string) { + return !!(string.startsWith('http://') || string.startsWith('https://')); +} + +function getFontWeight(fontWeight, phonemodel) { + const type2weight = { + normal: { + Android: 'normal', + iOS: 'normal', + }, + medium: { + Android: 'bold', + iOS: '500', + }, + bold: { + Android: 'bold', + iOS: 'bold', + }, + }; + return (type2weight[fontWeight] || type2weight['normal'])[phonemodel]; +} + +function isiOS(phonemodel) { + return phonemodel === 'iOS'; +} + +export default { + isUrl, + getFontWeight, + isiOS, +}; diff --git a/src/Typography/index.ts b/src/Typography/index.ts new file mode 100644 index 000000000..3a44aff5a --- /dev/null +++ b/src/Typography/index.ts @@ -0,0 +1,39 @@ +import { + Component, + triggerEventOnly, + triggerCatchEvent, + getValueFromProps, +} from '../_util/simply'; +import { TypographyDefaultProps } from './props'; + +Component( + TypographyDefaultProps, + { + onTap(e) { + const disabled = getValueFromProps(this, 'disabled'); + if (disabled) { + triggerEventOnly(this, 'disabledTap', e); + return; + } + triggerEventOnly(this, 'tap', e); + }, + catchTap(e) { + const disabled = getValueFromProps(this, 'disabled'); + if (disabled) { + triggerEventOnly(this, 'disabledTap', e); + return; + } + triggerCatchEvent(this, 'catchTap', e); + }, + }, + { phonemodel: '' }, + null, + { + onInit() { + const { platform } = my.env; + this.setData({ + phonemodel: platform, + }); + }, + } +); diff --git a/src/Typography/props.ts b/src/Typography/props.ts new file mode 100644 index 000000000..195befd63 --- /dev/null +++ b/src/Typography/props.ts @@ -0,0 +1,32 @@ +import { IBaseProps, IconType } from '../_util/base'; + +export interface ITypographyProps extends IBaseProps { + text?: string; + iconPosition?: 'left' | 'right'; + icon?: IconType | string; + activeClassName?: string; + disabled?: boolean; + selectable?: boolean; + fontWeight?: 'normal' | 'medium' | 'bold' | ''; + lineThrough?: boolean; + underline?: boolean; + ellipsisRow?: number; + onTap?: (event: any) => void; + catchTap?: (event: any) => void; + onDisabledTap?: (event: any) => void; +} + +export const TypographyDefaultProps: ITypographyProps = { + text: '', + iconPosition: 'right', + icon: '', + className: '', + activeClassName: '', + style: '', + disabled: false, + selectable: false, + fontWeight: 'normal', + lineThrough: false, + underline: false, + ellipsisRow: null, +}; diff --git a/tests/alipay/Typography/index.spec.ts b/tests/alipay/Typography/index.spec.ts new file mode 100644 index 000000000..b6a8dc268 --- /dev/null +++ b/tests/alipay/Typography/index.spec.ts @@ -0,0 +1,72 @@ +import { getInstance, sleep } from 'tests/utils'; +import { describe, expect, it, vi } from 'vitest'; +import { ITypographyProps } from '../../../src/Typography/props'; + +const createTypography = (options: Partial) => { + const my = { + canIUse() { + return true; + }, + env: { + platform: 'iOS', + }, + }; + const instance = getInstance( + 'Typography', + { + ...options, + }, + my + ); + return { + instance, + }; +}; + +describe('typography', () => { + it('typography config', () => { + const { instance } = createTypography({}); + const { data, props } = instance.getConfig(); + expect({ data, props }).toMatchFileSnapshot( + 'snapshot/typography_alipay_config.txt' + ); + }); + + it('test tap', async () => { + const onTap = vi.fn(); + const catchTap = vi.fn(); + const onDisabledTap = vi.fn(); + const { instance } = createTypography({ + onTap, + catchTap, + onDisabledTap, + }); + + await instance.callMethod('onTap'); + await instance.callMethod('catchTap'); + await sleep(10); + + expect(catchTap).toBeCalledTimes(1); + expect(onTap).toBeCalledTimes(1); + expect(onDisabledTap).toBeCalledTimes(0); + }); + + it('disabled 为 true', async () => { + const onTap = vi.fn(); + const catchTap = vi.fn(); + const onDisabledTap = vi.fn(); + const { instance } = createTypography({ + disabled: true, + onTap, + catchTap, + onDisabledTap, + }); + + await instance.callMethod('onTap'); + await sleep(10); + + expect(catchTap).toBeCalledTimes(0); + expect(onTap).toBeCalledTimes(0); + expect(onDisabledTap).toBeCalledTimes(1); + }); +}); diff --git a/tests/alipay/Typography/snapshot/typography_alipay_config.txt b/tests/alipay/Typography/snapshot/typography_alipay_config.txt new file mode 100644 index 000000000..a716f9267 --- /dev/null +++ b/tests/alipay/Typography/snapshot/typography_alipay_config.txt @@ -0,0 +1,18 @@ +{ + "data": { + "phonemodel": "", + }, + "props": { + "activeClassName": "", + "className": "", + "disabled": false, + "fontWeight": "normal", + "icon": "", + "iconPosition": "right", + "lineThrough": false, + "selectable": false, + "style": "", + "text": "", + "underline": false, + }, +}