first commit
This commit is contained in:
212
uni_modules/tdesign-uniapp/changelog.md
Normal file
212
uni_modules/tdesign-uniapp/changelog.md
Normal file
@@ -0,0 +1,212 @@
|
||||
## 0.7.0(2026-02-02)
|
||||
### Features
|
||||
|
||||
- `ActionSheet`: `item` 属性补充 `description` 字段 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- `Badge`:
|
||||
- `shape` 属性新增 `ribbon-right/ribbon-left/triangle-right/triangle-left` 可选项,其中 `ribbon` 与 `ribbon-right` 等效 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- 优化 `ribbon` 实现,改用 `background: linear-gradient()`,移除伪元素相关样式 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- `Calendar`: 新增 `allowSameDay` 属性,允许 `type='range'` 场景的起止时间相同 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- `Cascader`:
|
||||
- 支持通过 `keys` 属性定义 `children / disabled` 在 `options` 中对应的字段别名 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- 新增 `middle-content` 插槽,用于自定义中间区域内容 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- `CollapsePanel`: 新增 `--td-collapse-disabled-color` 和 `--td-collapse-left-icon-color`,用于自定义禁用态颜色和左侧图标颜色 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- `ImageViewer`: 新增 `image-props` 属性 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- `Navbar`: 新增 `placeholder` 属性,默认值为 `false`;新增 `zIndex` 属性,默认值为 `1` @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- `Picker`:
|
||||
- 优化性能减少掉帧 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- 优化大量数据时列表滚动性能 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- `itemHeight` 默认单位改用 `px`,避免单位转换带来的精度问题 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- 新增 `visibleItemCount` 属性,可自定义可视区域 `PickerItem` 的子项个数 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- `Popover`:
|
||||
- 新增 `fixed` API,适用于触发元素为 `fixed` 场景。当触发元素为 `fixed` 时,除了需要显示指定 `fixed` 属性为 `true`,还需在触发元素层添加 `t-popover-wrapper--fixed` 类,用于定位触发元素 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- 新增 `--td-popover-[theme]-color` 和 `--td-popover-[theme]-bg-color` 系列 `CSS Vars` @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- `QRCode`: 组件新增 `init()`,用于外部调用,重新绘制二维码 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- `Search`:
|
||||
- 确保点击清空按钮后,组件内容清空但保持聚焦 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- 新增 `cursor-color` 属性 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- `SidebarItem`:
|
||||
- 新增默认插槽,可自定义侧边栏子项内容 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- 支持由标签内容撑开高度 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- 完善激活项的前缀和后缀元素显示逻辑 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- `TabBar`: 新增 `placeholder` 属性,默认值为 `false`;新增 `zIndex` 属性,默认值为 `1` @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- `ActionSheet`:
|
||||
- 修复左对齐场景下,子项 `border` 左间距错误 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- 修复 `grid` 主题 + 无 `description` 描述文本场景下,顶部间距错误 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- `list` 主题最后一项不应设置底边框 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- 修复 `item` 属性的 `disabled` 配置无效 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- `BackTop`: 修复文本字重错误 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- `Badge`: 修复 `count` 插槽异常 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- `Calendar`:
|
||||
- 修复 `value[]` 结合 `swich-mode` 时,初始化错误 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- 修复翻页按钮状态错误 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- `Checkbox`: 修复 `icon` 属性使用 `svg` 资源时在 `iOS` 上不显示 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- `CollapsePanel`:
|
||||
- 修复深色模式下面板右侧图标颜色错误 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- 修复左侧图标颜色错误,默认主题色,支持使用 `css vars` 自定义 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- `ColorPicker`: 修复组件深色模式背景、边框、文本色错误 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- `DateTimePicker`: 修复插槽名重复导致的控制台告警 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- `DropdownItem`: 修复在 `iOS 26` 中弹窗定位不准 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- `Fab`: 修复 `yBounds` 未传值时,控制台报错问题 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- `Grid`: 修复 `column` 小于 4 或大于 4 时,文本字号大小错误 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- `Message`: 修复 `error` 主题图标错误 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- `Picker`:
|
||||
- 修复 `autoClose` 为 `false` 时,点击遮罩层会重置选项为拨动前选项值的问题 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- 修复平铺模式 `value` 变化未能准确监听 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- 修复 `keys` 动态变更时,子项列表数据不显示 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- 修复 `popupProps.showOverlay` 无效 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- `Popup`: 修复 `duration` 参数无效的问题 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- `Progress`:
|
||||
- 修复深色模式下环形进度条内部背景色错误 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- 修复环形进度条内部文本间距错误 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- 修复深色模式下环形进度条内部背景色错误 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- 修复环形进度条内部文本间距错误 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- `Slider`: 修复受控 + 双游标滑块模式下陷入死循环的问题 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- `SwipeCell`: 消除 `IntersectionObserver is using slowest path` 警告 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- `TabBar`: 修复子项背景色叠加的问题 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- `Tabs`: 消除 `IntersectionObserver is using slowest path` 警告 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- `Toast`:
|
||||
- 修复 `Toast` 嵌套调用时 `close` 回调陷入循环的问题 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- 修复弹窗与遮罩消失不同步的问题 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- 修复圆角样式错误 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- 修复 `showOverlay` 和 `preventScrollThrough` 均为 `true` 时,遮罩背景色错误 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- `Upload`:
|
||||
- 修复企业微信/桌面端环境中部分机型无法唤起上传 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- 修复当 `request-method` 返回 `Promise` 时,无法上传的问题 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- 修复 `draggable` 值变换时组件显示错误 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- 修复拖拽结束后拖拽元素 `zIndex` 异常 @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
|
||||
### Others
|
||||
|
||||
- `改用 Font token`,调整部分组件的 CSS Vars @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
- `--td-xx-icon-font-size` 统一更名为 `--td-xx-icon-size` @novlan1 ([#4201](https://github.com/Tencent/tdesign-miniprogram/pull/4201))
|
||||
|
||||
## 0.6.3(2026-01-05)
|
||||
### Features
|
||||
- `Form`: 支持 `change` 类型 `trigger` @novlan1 ([#143](https://github.com/novlan1/tdesign-uniapp/pull/143))
|
||||
- `Image`: 点击事件不禁用冒泡 @novlan1 ([#142](https://github.com/novlan1/tdesign-uniapp/pull/142))
|
||||
|
||||
## 0.6.2(2025-12-30)
|
||||
### Bug Fixes
|
||||
- `DateTimePicker`: 修复滚动日期时其他列向上跳动问题 @novlan1 ([#138](https://github.com/novlan1/tdesign-uniapp/pull/138))
|
||||
## 0.6.1(2025-12-29)
|
||||
### Features
|
||||
- `Navbar`: 增加 `right` 插槽 @novlan1 ([#136](https://github.com/novlan1/tdesign-uniapp/pull/136))
|
||||
|
||||
### Bug Fixes
|
||||
- `Upload`: 修复小程序下图片点击事件不触发问题 @novlan1 ([#136](https://github.com/novlan1/tdesign-uniapp/pull/136))
|
||||
|
||||
## 0.6.0(2025-12-17)
|
||||
### Features
|
||||
- `Popover`: 新增组件 @novlan1 ([#126](https://github.com/novlan1/tdesign-uniapp/pull/126))
|
||||
## 0.5.9(2025-12-11)
|
||||
### Bug Fixes
|
||||
- `Input`: 修复数据回显问题 @novlan1 ([#121](https://github.com/novlan1/tdesign-uniapp/pull/121))
|
||||
|
||||
|
||||
## 0.5.8(2025-12-01)
|
||||
#### Features
|
||||
- `Form`: 新增 `contentAlign` 属性 @novlan1 ([#115](https://github.com/novlan1/tdesign-uniapp/pull/115))
|
||||
|
||||
#### Bug Fixes
|
||||
- `SwipeCell`: 修复多个组件共存时的复位问题 @novlan1 ([#114](https://github.com/novlan1/tdesign-uniapp/pull/114))
|
||||
- `Form`: 修复 `help/label` 插槽不存在的问题 @novlan1 ([#115](https://github.com/novlan1/tdesign-uniapp/pull/115))
|
||||
|
||||
## 0.5.7(2025-11-27)
|
||||
#### Features
|
||||
- `Textarea`: 支持 `v-model:value` @novlan1 ([#102](https://github.com/novlan1/tdesign-uniapp/pull/102))
|
||||
- `Toast`: 函数式调用组件时,支持组件 Dom 预埋在页面下 @novlan1 ([#103](https://github.com/novlan1/tdesign-uniapp/pull/103))
|
||||
|
||||
#### Bug Fixes
|
||||
- `Input`: 修复 `clear` 事件的意外冒泡问题 @novlan1 ([#100](https://github.com/novlan1/tdesign-uniapp/pull/100))
|
||||
- `Calendar`: 修复 `switchMode` 为 `year-month` 时的编译问题 @novlan1 ([#106](https://github.com/novlan1/tdesign-uniapp/pull/106))
|
||||
|
||||
## 0.5.6(2025-11-25)
|
||||
#### Features
|
||||
- `Popup`: 支持 `v-model:visible` @novlan1 ([#90](https://github.com/novlan1/tdesign-uniapp/pull/90))
|
||||
- `Form`: 支持 `validate` 方法传参 @novlan1 ([#90](https://github.com/novlan1/tdesign-uniapp/pull/90))
|
||||
- `Input`: 支持 `v-model:value` @novlan1 ([#89](https://github.com/novlan1/tdesign-uniapp/pull/89))
|
||||
|
||||
#### Bug Fixes
|
||||
- `Form`: 修复深色模式背景错误问题 @novlan1 ([#91](https://github.com/novlan1/tdesign-uniapp/pull/91))
|
||||
|
||||
## 0.5.5(2025-11-18)
|
||||
#### Features
|
||||
- `Picker`: 支持 `v-model:visible` 语法糖 @novlan1 ([#77](https://github.com/novlan1/tdesign-uniapp/pull/77))
|
||||
- `PullDownRefresh`: 修改 `dragstart/dragging/dragend` 事件参数为 `TouchEvent` @novlan1 ([#63](https://github.com/novlan1/tdesign-uniapp/pull/63))
|
||||
|
||||
#### Bug Fixes
|
||||
- `Input`: 修复 `readonly` 时点击无效问题 @novlan1 ([#76](https://github.com/novlan1/tdesign-uniapp/pull/76))
|
||||
- `PullDownRefresh`: 修复加载中再次点击时触发的 `value` 变化问题 @novlan1 ([#63](https://github.com/novlan1/tdesign-uniapp/pull/63))
|
||||
## 0.5.4(2025-11-14)
|
||||
#### Bug Fixes
|
||||
- `DropdownMenu`: 修复使用自带导航栏时的高度错误 @novlan1 ([#56](https://github.com/novlan1/tdesign-uniapp/pull/56))
|
||||
## 0.5.3.beta-4(2025-11-12)
|
||||
#### 🐞 Bug Fixes
|
||||
- `Form`: 修复 `FormItem` 中 `padding` 错误问题 @novlan1
|
||||
|
||||
#### 🚧 Others
|
||||
- site: 使用 `history` 模式 @novlan1 ([#35](https://github.com/novlan1/tdesign-uniapp/pull/35))
|
||||
- ci: 使用多种 CI @novlan1 ([#42](https://github.com/novlan1/tdesign-uniapp/pull/42))
|
||||
|
||||
## 0.5.3.beta-3(2025-11-12)
|
||||
#### Bug Fixes
|
||||
- `Form`: 修复 `FormItem` 中 `padding` 错误问题 @novlan1
|
||||
|
||||
#### Others
|
||||
- site: 使用 `history` 模式 @novlan1 ([#35](https://github.com/novlan1/tdesign-uniapp/pull/35))
|
||||
- ci: 使用多种 CI @novlan1 ([#42](https://github.com/novlan1/tdesign-uniapp/pull/42))
|
||||
|
||||
## 0.5.3.beta-2(2025-11-12)
|
||||
### Bug Fixes
|
||||
- `Form`: 修复 `FormItem` 中 `padding` 错误问题 @novlan1
|
||||
|
||||
### Others
|
||||
- site: 使用 `history` 模式 @novlan1 ([#35](https://github.com/novlan1/tdesign-uniapp/pull/35))
|
||||
- ci: 使用多种 CI @novlan1 ([#42](https://github.com/novlan1/tdesign-uniapp/pull/42))
|
||||
|
||||
## 0.5.3.beta-1(2025-11-12)
|
||||
### Bug Fixes
|
||||
- `Form`: 修复 `FormItem` 中 `padding` 错误问题 @novlan1
|
||||
### Others
|
||||
- site: 使用 `history` 模式 @novlan1 ([#35](https://github.com/novlan1/tdesign-uniapp/pull/35))
|
||||
- ci: 使用多种 CI @novlan1 ([#42](https://github.com/novlan1/tdesign-uniapp/pull/42))
|
||||
|
||||
## 0.5.3(2025-11-12)
|
||||
🐞 Bug Fixes
|
||||
- `Form`: 修复 `FormItem` 中 `padding` 错误问题 @novlan1
|
||||
|
||||
🚧 Others
|
||||
- site: 使用 `history` 模式 @novlan1 ([#35](https://github.com/novlan1/tdesign-uniapp/pull/35))
|
||||
- ci: 使用多种 CI @novlan1 ([#42](https://github.com/novlan1/tdesign-uniapp/pull/42))
|
||||
|
||||
## 0.5.2(2025-11-10)
|
||||
- Popup: 修复滚动穿透问题
|
||||
- Tabs:修复scroll-view事件参数问题
|
||||
## 0.5.1(2025-11-07)
|
||||
- PullDownRefresh: 支持 successDuration 属性
|
||||
## 0.5.0(2025-11-07)
|
||||
- 支持类型提示
|
||||
## 0.4.2(2025-11-01)
|
||||
- 优化多个组件在支付宝小程序的表现
|
||||
## 0.4.0(2025-10-31)
|
||||
- 支持支付宝小程序
|
||||
## 0.3.2(2025-10-30)
|
||||
- `Calendar`: 修复引入问题
|
||||
## 0.3.1(2025-10-27)
|
||||
- Calendar: 支持 title 和 confirm-btn 的 slot
|
||||
## 0.3.0(2025-10-25)
|
||||
- `Guide`: 新增组件
|
||||
- `Watermark`: 新增组件
|
||||
## 0.2.5(2025-10-22)
|
||||
- 统一多个组件的事件参数
|
||||
## 0.2.3(2025-10-22)
|
||||
### 🚀 Features
|
||||
|
||||
- `ColorPicker`: 支持 APP-PLUS
|
||||
- `Collapse`: 支持 APP-PLUS
|
||||
- `QRCode`: 支持 APP-PLUS
|
||||
## 0.2.2(2025-10-17)
|
||||
- Swiper: 新增组件
|
||||
@@ -0,0 +1,60 @@
|
||||
:: BASE_DOC ::
|
||||
|
||||
## API
|
||||
|
||||
### ActionSheet Props
|
||||
|
||||
name | type | default | description | required
|
||||
-- | -- | -- | -- | --
|
||||
custom-style | Object | - | CSS(Cascading Style Sheets) | N
|
||||
align | String | center | options: center/left | N
|
||||
cancel-text | String | - | \- | N
|
||||
count | Number | 8 | \- | N
|
||||
description | String | - | \- | N
|
||||
items | Array | [] | Typescript: `Array<string \| ActionSheetItem>` `interface ActionSheetItem { label: string; description?: string; color?: string; disabled?: boolean; icon?: string; suffixIcon?: string }`。[see more ts definition](https://github.com/tencent/tdesign-miniprogram/blob/develop/packages/uniapp-components/action-sheet/type.ts) | N
|
||||
popup-props | Object | {} | Typescript: `PopupProps`,[Popup API Documents](./popup?tab=api)。[see more ts definition](https://github.com/tencent/tdesign-miniprogram/blob/develop/packages/uniapp-components/action-sheet/type.ts) | N
|
||||
show-cancel | Boolean | true | \- | N
|
||||
show-overlay | Boolean | true | \- | N
|
||||
theme | String | list | options: list/grid | N
|
||||
using-custom-navbar | Boolean | false | \- | N
|
||||
visible | Boolean | false | `v-model:visible` is supported | N
|
||||
default-visible | Boolean | false | uncontrolled property | N
|
||||
|
||||
### ActionSheet Events
|
||||
|
||||
name | params | description
|
||||
-- | -- | --
|
||||
cancel | \- | \-
|
||||
close | `(context: { trigger: ActionSheetTriggerSource })` | [see more ts definition](https://github.com/tencent/tdesign-miniprogram/blob/develop/packages/uniapp-components/action-sheet/type.ts)。<br/>`type ActionSheetTriggerSource = 'overlay' \| 'command' \| 'select' `<br/>
|
||||
selected | `(context: { selected: ActionSheetItem \| string, index: number })` | \-
|
||||
|
||||
### ActionSheet Slots
|
||||
|
||||
name | Description
|
||||
-- | --
|
||||
\- | \-
|
||||
|
||||
### ActionSheet External Classes
|
||||
|
||||
className | Description
|
||||
-- | --
|
||||
t-class | \-
|
||||
t-class-cancel | \-
|
||||
t-class-content | \-
|
||||
|
||||
### CSS Variables
|
||||
|
||||
The component provides the following CSS variables, which can be used to customize styles.
|
||||
Name | Default Value | Description
|
||||
-- | -- | --
|
||||
--td-action-sheet-border-color | @component-stroke | -
|
||||
--td-action-sheet-border-radius | @radius-extraLarge | -
|
||||
--td-action-sheet-cancel-color | @text-color-primary | -
|
||||
--td-action-sheet-color | @text-color-primary | -
|
||||
--td-action-sheet-description-color | @text-color-placeholder | -
|
||||
--td-action-sheet-description-font | @font-body-medium | -
|
||||
--td-action-sheet-disabled-color | @text-color-disabled | -
|
||||
--td-action-sheet-dot-active-color | @brand-color | -
|
||||
--td-action-sheet-dot-color | @text-color-disabled | -
|
||||
--td-action-sheet-dot-size | 16rpx | -
|
||||
--td-action-sheet-gap-color | @bg-color-page | -
|
||||
131
uni_modules/tdesign-uniapp/components/action-sheet/README.md
Normal file
131
uni_modules/tdesign-uniapp/components/action-sheet/README.md
Normal file
@@ -0,0 +1,131 @@
|
||||
---
|
||||
title: ActionSheet 动作面板
|
||||
description: 由用户操作后触发的一种特定的模态弹出框 ,呈现一组与当前情境相关的两个或多个选项。
|
||||
spline: data
|
||||
isComponent: true
|
||||
---
|
||||
|
||||
|
||||
## 引入
|
||||
|
||||
可在 `main.ts` 或在需要使用的页面或组件中引入。
|
||||
|
||||
```js
|
||||
import TActionSheet from '@tdesign/uniapp/action-sheet/action-sheet.vue';
|
||||
```
|
||||
|
||||
|
||||
### 组件类型
|
||||
|
||||
列表型动作面板
|
||||
|
||||
{{ list }}
|
||||
|
||||
宫格型动作面板
|
||||
|
||||
{{ grid }}
|
||||
|
||||
### 组件状态
|
||||
|
||||
宫格型动作面板
|
||||
|
||||
{{ status }}
|
||||
|
||||
### 组件样式
|
||||
|
||||
列表型对齐方式
|
||||
|
||||
{{ align }}
|
||||
|
||||
### 支持指令调用
|
||||
|
||||
```javascript
|
||||
import ActionSheet, { ActionSheetTheme } from '@tdesign/uniapp/action-sheet/index';
|
||||
|
||||
// 指令调用不同于组件引用不需要传入visible
|
||||
const basicListOption: ActionSheetShowOption = {
|
||||
theme: ActionSheetTheme.List,
|
||||
selector: '#t-action-sheet',
|
||||
items: [
|
||||
{
|
||||
label: '默认选项',
|
||||
},
|
||||
{
|
||||
label: '失效选项',
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
label: '警告选项',
|
||||
color: '#e34d59',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const handler = ActionSheet.show(basicListOption);
|
||||
```
|
||||
|
||||
指令调用的关闭如下
|
||||
|
||||
```javascript
|
||||
handler.close();
|
||||
```
|
||||
|
||||
|
||||
## API
|
||||
|
||||
### ActionSheet Props
|
||||
|
||||
名称 | 类型 | 默认值 | 描述 | 必传
|
||||
-- | -- | -- | -- | --
|
||||
custom-style | Object | - | 自定义样式 | N
|
||||
align | String | center | 水平对齐方式。可选项:center/left | N
|
||||
cancel-text | String | - | 设置取消按钮的文本 | N
|
||||
count | Number | 8 | 设置每页展示菜单的数量,仅当 type=grid 时有效 | N
|
||||
description | String | - | 动作面板描述文字 | N
|
||||
items | Array | [] | 菜单项。TS 类型:`Array<string \| ActionSheetItem>` `interface ActionSheetItem { label: string; description?: string; color?: string; disabled?: boolean; icon?: string; suffixIcon?: string }`。[详细类型定义](https://github.com/tencent/tdesign-miniprogram/blob/develop/packages/uniapp-components/action-sheet/type.ts) | N
|
||||
popup-props | Object | {} | 透传 Popup 组件全部属性。TS 类型:`PopupProps`,[Popup API Documents](./popup?tab=api)。[详细类型定义](https://github.com/tencent/tdesign-miniprogram/blob/develop/packages/uniapp-components/action-sheet/type.ts) | N
|
||||
show-cancel | Boolean | true | 是否显示取消按钮 | N
|
||||
show-overlay | Boolean | true | 是否显示遮罩层 | N
|
||||
theme | String | list | 展示类型,列表和表格形式展示。可选项:list/grid | N
|
||||
using-custom-navbar | Boolean | false | 是否使用了自定义导航栏 | N
|
||||
visible | Boolean | false | 显示与隐藏。支持语法糖 `v-model:visible` | N
|
||||
default-visible | Boolean | false | 显示与隐藏。非受控属性 | N
|
||||
|
||||
### ActionSheet Events
|
||||
|
||||
名称 | 参数 | 描述
|
||||
-- | -- | --
|
||||
cancel | \- | 点击取消按钮时触发
|
||||
close | `(context: { trigger: ActionSheetTriggerSource })` | 关闭时触发。[详细类型定义](https://github.com/tencent/tdesign-miniprogram/blob/develop/packages/uniapp-components/action-sheet/type.ts)。<br/>`type ActionSheetTriggerSource = 'overlay' \| 'command' \| 'select' `<br/>
|
||||
selected | `(context: { selected: ActionSheetItem \| string, index: number })` | 选择菜单项时触发
|
||||
|
||||
### ActionSheet Slots
|
||||
|
||||
名称 | 描述
|
||||
-- | --
|
||||
\- | 默认插槽,自定义内容区域内容
|
||||
|
||||
### ActionSheet External Classes
|
||||
|
||||
类名 | 描述
|
||||
-- | --
|
||||
t-class | 根节点样式类
|
||||
t-class-cancel | 取消样式类
|
||||
t-class-content | 内容样式类
|
||||
|
||||
### CSS Variables
|
||||
|
||||
组件提供了下列 CSS 变量,可用于自定义样式。
|
||||
名称 | 默认值 | 描述
|
||||
-- | -- | --
|
||||
--td-action-sheet-border-color | @component-stroke | -
|
||||
--td-action-sheet-border-radius | @radius-extraLarge | -
|
||||
--td-action-sheet-cancel-color | @text-color-primary | -
|
||||
--td-action-sheet-color | @text-color-primary | -
|
||||
--td-action-sheet-description-color | @text-color-placeholder | -
|
||||
--td-action-sheet-description-font | @font-body-medium | -
|
||||
--td-action-sheet-disabled-color | @text-color-disabled | -
|
||||
--td-action-sheet-dot-active-color | @brand-color | -
|
||||
--td-action-sheet-dot-color | @text-color-disabled | -
|
||||
--td-action-sheet-dot-size | 16rpx | -
|
||||
--td-action-sheet-gap-color | @bg-color-page | -
|
||||
@@ -0,0 +1,162 @@
|
||||
.t-action-sheet__content {
|
||||
color: var(--td-action-sheet-color, var(--td-text-color-primary, var(--td-font-gray-1, rgba(0, 0, 0, 0.9))));
|
||||
border-top-left-radius: var(--td-action-sheet-border-radius, var(--td-radius-extraLarge, 24rpx));
|
||||
border-top-right-radius: var(--td-action-sheet-border-radius, var(--td-radius-extraLarge, 24rpx));
|
||||
background-color: var(--td-bg-color-container, var(--td-font-white-1, #ffffff));
|
||||
overflow: hidden;
|
||||
}
|
||||
.t-action-sheet__content:focus {
|
||||
outline: 0;
|
||||
}
|
||||
.t-action-sheet--grid {
|
||||
padding-top: var(--td-spacer, 16rpx);
|
||||
}
|
||||
.t-action-sheet--grid .t-action-sheet__description::after {
|
||||
display: none;
|
||||
}
|
||||
.t-action-sheet--left .t-action-sheet__description {
|
||||
text-align: left;
|
||||
}
|
||||
.t-action-sheet--left .t-action-sheet__list-item-content,
|
||||
.t-action-sheet--left .t-action-sheet__list-item-desc {
|
||||
justify-content: start;
|
||||
}
|
||||
.t-action-sheet--left .t-action-sheet__list-item-icon--suffix {
|
||||
margin-left: auto;
|
||||
}
|
||||
.t-action-sheet__grid {
|
||||
padding-bottom: 16rpx;
|
||||
}
|
||||
.t-action-sheet__grid--swiper {
|
||||
padding-bottom: 48rpx;
|
||||
}
|
||||
.t-action-sheet__description {
|
||||
color: var(--td-action-sheet-description-color, var(--td-text-color-placeholder, var(--td-font-gray-3, rgba(0, 0, 0, 0.4))));
|
||||
font: var(--td-action-sheet-description-font, var(--td-font-body-medium, 28rpx / 44rpx var(--td-font-family, PingFang SC, Microsoft YaHei, Arial Regular)));
|
||||
text-align: center;
|
||||
padding: var(--td-spacer-1, 24rpx) var(--td-spacer-2, 32rpx);
|
||||
position: relative;
|
||||
}
|
||||
.t-action-sheet__description:focus {
|
||||
outline: 0;
|
||||
}
|
||||
.t-action-sheet__description::after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: unset;
|
||||
bottom: 0;
|
||||
left: unset;
|
||||
right: unset;
|
||||
background-color: var(--td-action-sheet-border-color, var(--td-component-stroke, var(--td-gray-color-3, #e7e7e7)));
|
||||
}
|
||||
.t-action-sheet__description::after {
|
||||
height: 1px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
transform: scaleY(0.5);
|
||||
}
|
||||
.t-action-sheet__list-item {
|
||||
flex-direction: column;
|
||||
padding: var(--td-spacer-2, 32rpx);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.t-action-sheet__list-item:not(:last-child) {
|
||||
position: relative;
|
||||
}
|
||||
.t-action-sheet__list-item:not(:last-child)::after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: unset;
|
||||
bottom: 0;
|
||||
left: unset;
|
||||
right: unset;
|
||||
background-color: var(--td-action-sheet-border-color, var(--td-component-stroke, var(--td-gray-color-3, #e7e7e7)));
|
||||
}
|
||||
.t-action-sheet__list-item:not(:last-child)::after {
|
||||
height: 1px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
transform: scaleY(0.5);
|
||||
}
|
||||
.t-action-sheet__list-item:focus {
|
||||
outline: 0;
|
||||
}
|
||||
.t-action-sheet__list-item--disabled {
|
||||
color: var(--td-action-sheet-disabled-color, var(--td-text-color-disabled, var(--td-font-gray-4, rgba(0, 0, 0, 0.26))));
|
||||
}
|
||||
.t-action-sheet__list-item-content,
|
||||
.t-action-sheet__list-item-desc {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.t-action-sheet__list-item-text {
|
||||
font: var(--td-font-body-large, 32rpx / 48rpx var(--td-font-family, PingFang SC, Microsoft YaHei, Arial Regular));
|
||||
}
|
||||
.t-action-sheet__list-item-desc {
|
||||
font: var(--td-font-body-small, 24rpx / 40rpx var(--td-font-family, PingFang SC, Microsoft YaHei, Arial Regular));
|
||||
color: var(--td-action-sheet-description-color, var(--td-text-color-placeholder, var(--td-font-gray-3, rgba(0, 0, 0, 0.4))));
|
||||
margin-top: var(--td-spacer, 16rpx);
|
||||
}
|
||||
.t-action-sheet__list-item-text,
|
||||
.t-action-sheet__list-item-desc {
|
||||
word-wrap: normal;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.t-action-sheet__list-item-icon {
|
||||
font-size: 48rpx;
|
||||
margin-right: var(--td-spacer, 16rpx);
|
||||
}
|
||||
.t-action-sheet__list-item-icon--suffix {
|
||||
margin-right: 0;
|
||||
margin-left: var(--td-spacer, 16rpx);
|
||||
}
|
||||
.t-action-sheet__swiper-wrap {
|
||||
margin-top: 8rpx;
|
||||
position: relative;
|
||||
}
|
||||
.t-action-sheet__footer {
|
||||
background-color: var(--td-bg-color-container, var(--td-font-white-1, #ffffff));
|
||||
}
|
||||
.t-action-sheet__gap-list {
|
||||
height: 16rpx;
|
||||
background-color: var(--td-action-sheet-gap-color, var(--td-bg-color-page, var(--td-gray-color-1, #f3f3f3)));
|
||||
}
|
||||
.t-action-sheet__gap-grid {
|
||||
height: 1rpx;
|
||||
background-color: var(--td-action-sheet-border-color, var(--td-component-stroke, var(--td-gray-color-3, #e7e7e7)));
|
||||
}
|
||||
.t-action-sheet__cancel {
|
||||
padding: var(--td-spacer-1, 24rpx) var(--td-spacer-2, 32rpx);
|
||||
font: var(--td-font-body-large, 32rpx / 48rpx var(--td-font-family, PingFang SC, Microsoft YaHei, Arial Regular));
|
||||
color: var(--td-action-sheet-cancel-color, var(--td-text-color-primary, var(--td-font-gray-1, rgba(0, 0, 0, 0.9))));
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.t-action-sheet__dots {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
bottom: var(--td-spacer-2, 32rpx);
|
||||
transform: translateX(-50%);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
.t-action-sheet__dots-item {
|
||||
width: var(--td-action-sheet-dot-size, 16rpx);
|
||||
height: var(--td-action-sheet-dot-size, 16rpx);
|
||||
background-color: var(--td-action-sheet-dot-color, var(--td-text-color-disabled, var(--td-font-gray-4, rgba(0, 0, 0, 0.26))));
|
||||
border-radius: 50%;
|
||||
margin: 0 var(--td-spacer, 16rpx);
|
||||
transition: all 0.4s ease-in;
|
||||
}
|
||||
.t-action-sheet__dots-item.t-is-active {
|
||||
background-color: var(--td-action-sheet-dot-active-color, var(--td-brand-color, var(--td-primary-color-7, #0052d9)));
|
||||
}
|
||||
@@ -0,0 +1,350 @@
|
||||
<template>
|
||||
<view
|
||||
:id="classPrefix"
|
||||
:style="tools._style([rootCustomStyle])"
|
||||
:class="tools.cls(classPrefix, [dataAlign, dataTheme, ['no-description', !description]]) + ' ' + tClass"
|
||||
>
|
||||
<t-popup
|
||||
:visible="dataVisible"
|
||||
placement="bottom"
|
||||
:using-custom-navbar="dataUsingCustomNavbar"
|
||||
:custom-navbar-height="customNavbarHeight"
|
||||
:show-overlay="dataShowOverlay"
|
||||
:z-index="(dataPopupProps && dataPopupProps.zIndex) || defaultPopUpzIndex"
|
||||
:overlay-props="(dataPopupProps && dataPopupProps.overlayProps) || defaultPopUpProps"
|
||||
@visible-change="onPopupVisibleChange"
|
||||
>
|
||||
<view
|
||||
:class="classPrefix + '__content ' + tClassContent"
|
||||
tabindex="0"
|
||||
>
|
||||
<view
|
||||
v-if="dataDescription"
|
||||
tabindex="0"
|
||||
:class="classPrefix + '__description'"
|
||||
>
|
||||
{{ dataDescription }}
|
||||
</view>
|
||||
<block v-if="gridThemeItems.length">
|
||||
<block v-if="gridThemeItems.length === 1">
|
||||
<t-grid
|
||||
align="center"
|
||||
:t-class="classPrefix + '__grid'"
|
||||
:column="dataCount / 2"
|
||||
:class="classPrefix + '__single-wrap'"
|
||||
>
|
||||
<t-grid-item
|
||||
v-for="(item, index) in gridThemeItems[0]"
|
||||
:key="index"
|
||||
:t-class="classPrefix + '__grid-item ' + classPrefix + '__square'"
|
||||
:data-index="index"
|
||||
:icon="{ name: item.icon, color: item.color }"
|
||||
:text="item.label || ''"
|
||||
:description="item.description || ''"
|
||||
:image="item.image || ''"
|
||||
:style="'--td-grid-item-text-color: ' + item.color"
|
||||
@click="onSelect($event, { index })"
|
||||
/>
|
||||
</t-grid>
|
||||
</block>
|
||||
<block v-else-if="gridThemeItems.length > 1">
|
||||
<view :class="classPrefix + '__swiper-wrap'">
|
||||
<swiper
|
||||
:style="heightStyle"
|
||||
:autoplay="false"
|
||||
:current="currentSwiperIndex"
|
||||
@change="onSwiperChange"
|
||||
>
|
||||
<swiper-item
|
||||
v-for="(item, index) in gridThemeItems"
|
||||
:key="index"
|
||||
>
|
||||
<t-grid
|
||||
align="center"
|
||||
:t-class="classPrefix + '__grid ' + classPrefix + '__grid--swiper'"
|
||||
:column="dataCount / 2"
|
||||
:custom-style="gridStyle"
|
||||
>
|
||||
<t-grid-item
|
||||
v-for="(item, index1) in item"
|
||||
:key="index1"
|
||||
:t-class="classPrefix + '__grid-item'"
|
||||
:class="classPrefix + '__square'"
|
||||
:data-index="index"
|
||||
:icon="{ name: item.icon, color: item.color }"
|
||||
:text="item.label || ''"
|
||||
:description="item.description || ''"
|
||||
:image="item.image || ''"
|
||||
:style="'--td-grid-item-text-color: ' + item.color"
|
||||
@click="onSelect($event, { index })"
|
||||
/>
|
||||
</t-grid>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
<view :class="classPrefix + '__nav'">
|
||||
<view :class="classPrefix + '__dots'">
|
||||
<view
|
||||
v-for="(item, index) in gridThemeItems.length"
|
||||
:key="index"
|
||||
:class="classPrefix + '__dots-item ' + (index === currentSwiperIndex ? prefix + '-is-active' : '')"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</block>
|
||||
<view
|
||||
v-else-if="dataItems && dataItems.length"
|
||||
:class="classPrefix + '__list'"
|
||||
>
|
||||
<block
|
||||
v-for="(item, index) in dataItems"
|
||||
:key="index"
|
||||
>
|
||||
<view
|
||||
:data-index="index"
|
||||
:style="item.color ? 'color: ' + item.color : ''"
|
||||
:class="tools.cls(classPrefix + '__list-item', [['disabled', item.disabled]])"
|
||||
:aria-role="ariaRole || 'button'"
|
||||
:aria-label="item.label || item"
|
||||
tabindex="0"
|
||||
@click="() => onSelect(item, { index })"
|
||||
>
|
||||
<view :class="classPrefix + '__list-item-content'">
|
||||
<t-icon
|
||||
v-if="item.icon"
|
||||
:name="item.icon"
|
||||
:t-class="classPrefix + '__list-item-icon'"
|
||||
:custom-style="iconCustomStyle"
|
||||
/>
|
||||
<view :class="classPrefix + '__list-item-text'">
|
||||
{{ item.label || item }}
|
||||
</view>
|
||||
<t-icon
|
||||
v-if="item.suffixIcon"
|
||||
:name="item.suffixIcon"
|
||||
:t-class="classPrefix + '__list-item-icon ' + classPrefix + '__list-item-icon--suffix'"
|
||||
style="margin-left: auto;"
|
||||
:custom-style="suffixIconCustomStyle"
|
||||
/>
|
||||
</view>
|
||||
<view
|
||||
v-if="item.description"
|
||||
:class="classPrefix + '__list-item-desc'"
|
||||
>
|
||||
{{ item.description }}
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
<slot />
|
||||
<view
|
||||
v-if="dataShowCancel"
|
||||
:class="classPrefix + '__footer'"
|
||||
>
|
||||
<view :class="classPrefix + '__gap-' + dataTheme" />
|
||||
<view
|
||||
:class="classPrefix + '__cancel ' + tClassCancel"
|
||||
:hover-class="classPrefix + '__cancel--hover'"
|
||||
hover-stay-time="70"
|
||||
aria-role="button"
|
||||
@click="onCancel"
|
||||
>
|
||||
{{ dataCancelText || '取消' }}
|
||||
</view>
|
||||
</view>
|
||||
</t-popup>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import TIcon from '../icon/icon';
|
||||
import TPopup from '../popup/popup';
|
||||
import TGrid from '../grid/grid';
|
||||
import TGridItem from '../grid-item/grid-item';
|
||||
import { chunk } from '../common/utils';
|
||||
import { uniComponent } from '../common/src/index';
|
||||
import { prefix } from '../common/config';
|
||||
import { actionSheetTheme } from './show';
|
||||
import props from './props';
|
||||
import useCustomNavbar from '../mixins/using-custom-navbar';
|
||||
import tools from '../common/utils.wxs';
|
||||
import { getFunctionalMixin } from '../common/functional/mixin';
|
||||
|
||||
|
||||
const name = `${prefix}-action-sheet`;
|
||||
|
||||
|
||||
export default uniComponent({
|
||||
name,
|
||||
options: {
|
||||
styleIsolation: 'shared',
|
||||
},
|
||||
controlledProps: [{
|
||||
key: 'visible',
|
||||
event: 'visible-change',
|
||||
}],
|
||||
externalClasses: [
|
||||
`${prefix}-class`,
|
||||
`${prefix}-class-content`,
|
||||
`${prefix}-class-cancel`,
|
||||
],
|
||||
mixins: [getFunctionalMixin(props), useCustomNavbar],
|
||||
components: {
|
||||
TIcon,
|
||||
TPopup,
|
||||
TGrid,
|
||||
TGridItem,
|
||||
},
|
||||
props: {
|
||||
...props,
|
||||
},
|
||||
emits: [
|
||||
'visible-change',
|
||||
'update:visible',
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
prefix,
|
||||
classPrefix: name,
|
||||
gridThemeItems: [],
|
||||
currentSwiperIndex: 0,
|
||||
defaultPopUpProps: {},
|
||||
defaultPopUpzIndex: 11500,
|
||||
tools,
|
||||
|
||||
heightStyle: 'height: 456rpx;',
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
rootCustomStyle() {
|
||||
return tools._style([
|
||||
this.customStyle,
|
||||
this.dataTheme === 'grid' ? 'padding-bottom: 16rpx' : '',
|
||||
]);
|
||||
},
|
||||
iconCustomStyle() {
|
||||
return 'margin-right: 8px;';
|
||||
},
|
||||
suffixIconCustomStyle() {
|
||||
return 'margin-right: 8px;margin-left: auto;';
|
||||
},
|
||||
gridStyle() {
|
||||
return `${this.heightStyle}padding-bottom: 48rpx;`;
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
dataVisible: {
|
||||
handler(e) {
|
||||
if (e) {
|
||||
this.init();
|
||||
}
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
dataItems: {
|
||||
handler() {
|
||||
if (this.dataVisible) {
|
||||
this.init();
|
||||
}
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
this.memoInitialData();
|
||||
this.splitGridThemeActions();
|
||||
},
|
||||
|
||||
memoInitialData() {
|
||||
this.initialData = {
|
||||
};
|
||||
},
|
||||
|
||||
splitGridThemeActions() {
|
||||
if (this.dataTheme !== actionSheetTheme.Grid) return;
|
||||
this.gridThemeItems = chunk(this.dataItems, this.dataCount);
|
||||
},
|
||||
|
||||
/** 指令调用显示 */
|
||||
show(options) {
|
||||
const defaultOptions = [
|
||||
'align',
|
||||
'cancelText',
|
||||
'count',
|
||||
'description',
|
||||
'items',
|
||||
'popupProps',
|
||||
'showCancel',
|
||||
'showOverlay',
|
||||
'theme',
|
||||
'usingCustomNavbar',
|
||||
].reduce((acc, key) => ({
|
||||
...acc,
|
||||
[key]: props[key].default,
|
||||
}));
|
||||
|
||||
this.setData({
|
||||
...defaultOptions,
|
||||
...options,
|
||||
visible: true,
|
||||
});
|
||||
this.splitGridThemeActions();
|
||||
this.autoClose = true;
|
||||
this._trigger('visible-change', { visible: true });
|
||||
},
|
||||
|
||||
/** 指令调用隐藏 */
|
||||
close() {
|
||||
this.$emit('close', { trigger: 'command' });
|
||||
this._trigger('visible-change', { visible: false });
|
||||
},
|
||||
|
||||
/** 默认点击遮罩关闭 */
|
||||
onPopupVisibleChange(detail) {
|
||||
if (!detail.visible) {
|
||||
this.$emit('close', { trigger: 'overlay' });
|
||||
this._trigger('visible-change', { visible: false });
|
||||
}
|
||||
if (this.autoClose) {
|
||||
this.dataVisible = false;
|
||||
this.autoClose = false;
|
||||
}
|
||||
},
|
||||
|
||||
onSwiperChange(e) {
|
||||
const { current } = e.detail;
|
||||
this.currentSwiperIndex = current;
|
||||
},
|
||||
|
||||
onSelect(event, { index }) {
|
||||
const { currentSwiperIndex, dataItems, gridThemeItems, dataCount, dataTheme } = this;
|
||||
const isSwiperMode = dataTheme === actionSheetTheme.Grid;
|
||||
const item = isSwiperMode ? gridThemeItems[currentSwiperIndex][index] : dataItems[index];
|
||||
const realIndex = isSwiperMode ? index + currentSwiperIndex * dataCount : index;
|
||||
|
||||
if (item) {
|
||||
this.$emit('selected', { selected: item, index: realIndex });
|
||||
|
||||
if (!item.disabled) {
|
||||
this.$emit('close', { trigger: 'select' });
|
||||
this._trigger('visible-change', { visible: false });
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
onCancel() {
|
||||
this.$emit('cancel');
|
||||
if (this.autoClose) {
|
||||
this.dataVisible = false;
|
||||
this.autoClose = false;
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@import './action-sheet.css';
|
||||
</style>
|
||||
@@ -0,0 +1,15 @@
|
||||
export const getListThemeItemClass = function (props) {
|
||||
const { classPrefix } = props;
|
||||
const { item } = props;
|
||||
const { prefix } = props;
|
||||
const classList = [`${classPrefix}__list-item`];
|
||||
if (item.disabled) {
|
||||
classList.push(`${prefix}-is-disabled`);
|
||||
}
|
||||
return classList.join(' ');
|
||||
};
|
||||
|
||||
export const isImage = function (name) {
|
||||
return name.indexOf('/') !== -1;
|
||||
};
|
||||
|
||||
11
uni_modules/tdesign-uniapp/components/action-sheet/index.d.ts
vendored
Normal file
11
uni_modules/tdesign-uniapp/components/action-sheet/index.d.ts
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
import type { ActionSheetItem, ActionSheetTheme, ActionSheetShowOption } from './show.d.ts';
|
||||
|
||||
export { ActionSheetItem, ActionSheetTheme, ActionSheetShowOption };
|
||||
|
||||
declare type Instance = any;
|
||||
|
||||
declare const Handler: {
|
||||
show(options: ActionSheetShowOption): Instance;
|
||||
close(options: ActionSheetShowOption): void;
|
||||
};
|
||||
export default Handler;
|
||||
13
uni_modules/tdesign-uniapp/components/action-sheet/index.js
Normal file
13
uni_modules/tdesign-uniapp/components/action-sheet/index.js
Normal file
@@ -0,0 +1,13 @@
|
||||
import { show, close, ActionSheetTheme, actionSheetTheme } from './show';
|
||||
|
||||
export { ActionSheetTheme, actionSheetTheme };
|
||||
|
||||
export default {
|
||||
show(options) {
|
||||
return show(options);
|
||||
},
|
||||
|
||||
close(options) {
|
||||
return close(options);
|
||||
},
|
||||
};
|
||||
86
uni_modules/tdesign-uniapp/components/action-sheet/props.ts
Normal file
86
uni_modules/tdesign-uniapp/components/action-sheet/props.ts
Normal file
@@ -0,0 +1,86 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
|
||||
* */
|
||||
|
||||
import type { TdActionSheetProps } from './type';
|
||||
export default {
|
||||
/** 水平对齐方式 */
|
||||
align: {
|
||||
type: String,
|
||||
default: 'center' as TdActionSheetProps['align'],
|
||||
validator(val: TdActionSheetProps['align']): boolean {
|
||||
if (!val) return true;
|
||||
return ['center', 'left'].includes(val);
|
||||
},
|
||||
},
|
||||
/** 设置取消按钮的文本 */
|
||||
cancelText: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
/** 设置每页展示菜单的数量,仅当 type=grid 时有效 */
|
||||
count: {
|
||||
type: Number,
|
||||
default: 8,
|
||||
},
|
||||
/** 动作面板描述文字 */
|
||||
description: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
/** 菜单项 */
|
||||
items: {
|
||||
type: Array,
|
||||
default: (): TdActionSheetProps['items'] => [],
|
||||
},
|
||||
/** 透传 Popup 组件全部属性 */
|
||||
popupProps: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
/** 是否显示取消按钮 */
|
||||
showCancel: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
/** 是否显示遮罩层 */
|
||||
showOverlay: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
/** 展示类型,列表和表格形式展示 */
|
||||
theme: {
|
||||
type: String,
|
||||
default: 'list' as TdActionSheetProps['theme'],
|
||||
validator(val: TdActionSheetProps['theme']): boolean {
|
||||
if (!val) return true;
|
||||
return ['list', 'grid'].includes(val);
|
||||
},
|
||||
},
|
||||
/** 是否使用了自定义导航栏 */
|
||||
usingCustomNavbar: Boolean,
|
||||
/** 显示与隐藏 */
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: undefined,
|
||||
},
|
||||
/** 显示与隐藏,非受控属性 */
|
||||
defaultVisible: Boolean,
|
||||
/** 点击取消按钮时触发 */
|
||||
onCancel: {
|
||||
type: Function,
|
||||
default: () => ({}),
|
||||
},
|
||||
/** 关闭时触发 */
|
||||
onClose: {
|
||||
type: Function,
|
||||
default: () => ({}),
|
||||
},
|
||||
/** 选择菜单项时触发 */
|
||||
onSelected: {
|
||||
type: Function,
|
||||
default: () => ({}),
|
||||
},
|
||||
};
|
||||
28
uni_modules/tdesign-uniapp/components/action-sheet/show.d.ts
vendored
Normal file
28
uni_modules/tdesign-uniapp/components/action-sheet/show.d.ts
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
import { ActionSheetItem } from './type';
|
||||
|
||||
export { ActionSheetItem };
|
||||
declare type Instance = any;
|
||||
declare type Context = any;
|
||||
|
||||
export declare enum ActionSheetTheme {
|
||||
List = 'list',
|
||||
Grid = 'grid'
|
||||
}
|
||||
|
||||
interface ActionSheetProps {
|
||||
align: 'center' | 'left';
|
||||
cancelText?: string;
|
||||
count?: number;
|
||||
description: string;
|
||||
items: Array<string | ActionSheetItem>;
|
||||
showCancel?: boolean;
|
||||
theme?: ActionSheetTheme;
|
||||
visible: boolean;
|
||||
defaultVisible?: boolean;
|
||||
}
|
||||
export interface ActionSheetShowOption extends Omit<ActionSheetProps, 'visible'> {
|
||||
context?: Context;
|
||||
selector?: string;
|
||||
}
|
||||
export declare const show: (options: ActionSheetShowOption) => Instance;
|
||||
export declare const close: (options: ActionSheetShowOption) => void;
|
||||
33
uni_modules/tdesign-uniapp/components/action-sheet/show.js
Normal file
33
uni_modules/tdesign-uniapp/components/action-sheet/show.js
Normal file
@@ -0,0 +1,33 @@
|
||||
import { getInstance } from '../common/utils';
|
||||
|
||||
|
||||
export const ActionSheetTheme = {
|
||||
List: 'list',
|
||||
Grid: 'grid',
|
||||
};
|
||||
|
||||
|
||||
export const actionSheetTheme = {
|
||||
List: ActionSheetTheme.List,
|
||||
Grid: ActionSheetTheme.Grid,
|
||||
} ;
|
||||
|
||||
export const show = function (options) {
|
||||
const { context, selector = '#t-action-sheet', ...otherOptions } = { ...options };
|
||||
const instance = getInstance(context, selector);
|
||||
if (instance) {
|
||||
instance.show({
|
||||
...otherOptions,
|
||||
});
|
||||
return instance;
|
||||
}
|
||||
console.error('未找到组件,请确认 selector && context 是否正确');
|
||||
};
|
||||
|
||||
export const close = function (options) {
|
||||
const { context, selector = '#t-action-sheet' } = { ...options };
|
||||
const instance = getInstance(context, selector);
|
||||
if (instance) {
|
||||
instance.close();
|
||||
}
|
||||
};
|
||||
93
uni_modules/tdesign-uniapp/components/action-sheet/type.ts
Normal file
93
uni_modules/tdesign-uniapp/components/action-sheet/type.ts
Normal file
@@ -0,0 +1,93 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
|
||||
* */
|
||||
|
||||
import type { TdPopupProps as PopupProps } from '../popup/type';
|
||||
|
||||
export interface TdActionSheetProps {
|
||||
/**
|
||||
* 水平对齐方式
|
||||
* @default center
|
||||
*/
|
||||
align?: 'center' | 'left';
|
||||
/**
|
||||
* 设置取消按钮的文本
|
||||
* @default ''
|
||||
*/
|
||||
cancelText?: string;
|
||||
/**
|
||||
* 设置每页展示菜单的数量,仅当 type=grid 时有效
|
||||
* @default 8
|
||||
*/
|
||||
count?: number;
|
||||
/**
|
||||
* 动作面板描述文字
|
||||
* @default ''
|
||||
*/
|
||||
description?: string;
|
||||
/**
|
||||
* 菜单项
|
||||
* @default []
|
||||
*/
|
||||
items?: Array<string | ActionSheetItem>;
|
||||
/**
|
||||
* 透传 Popup 组件全部属性
|
||||
* @default {}
|
||||
*/
|
||||
popupProps?: PopupProps;
|
||||
/**
|
||||
* 是否显示取消按钮
|
||||
* @default true
|
||||
*/
|
||||
showCancel?: boolean;
|
||||
/**
|
||||
* 是否显示遮罩层
|
||||
* @default true
|
||||
*/
|
||||
showOverlay?: boolean;
|
||||
/**
|
||||
* 展示类型,列表和表格形式展示
|
||||
* @default list
|
||||
*/
|
||||
theme?: 'list' | 'grid';
|
||||
/**
|
||||
* 是否使用了自定义导航栏
|
||||
* @default false
|
||||
*/
|
||||
usingCustomNavbar?: boolean;
|
||||
/**
|
||||
* 显示与隐藏
|
||||
* @default false
|
||||
*/
|
||||
visible?: boolean;
|
||||
/**
|
||||
* 显示与隐藏,非受控属性
|
||||
* @default false
|
||||
*/
|
||||
defaultVisible?: boolean;
|
||||
/**
|
||||
* 点击取消按钮时触发
|
||||
*/
|
||||
onCancel?: () => void;
|
||||
/**
|
||||
* 关闭时触发
|
||||
*/
|
||||
onClose?: (context: { trigger: ActionSheetTriggerSource }) => void;
|
||||
/**
|
||||
* 选择菜单项时触发
|
||||
*/
|
||||
onSelected?: (context: { selected: ActionSheetItem | string; index: number }) => void;
|
||||
}
|
||||
|
||||
export interface ActionSheetItem {
|
||||
label: string;
|
||||
description?: string;
|
||||
color?: string;
|
||||
disabled?: boolean;
|
||||
icon?: string;
|
||||
suffixIcon?: string;
|
||||
}
|
||||
|
||||
export type ActionSheetTriggerSource = 'overlay' | 'command' | 'select';
|
||||
@@ -0,0 +1,187 @@
|
||||
.t-avatar-group {
|
||||
display: inline-flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper,
|
||||
.t-avatar-group-offset-right .t-avatar__wrapper {
|
||||
padding: var(--td-avatar-group-line-spacing, 4rpx) 0;
|
||||
}
|
||||
.t-avatar-group-offset-left-small,
|
||||
.t-avatar-group-offset-right-small {
|
||||
--td-avatar-margin-left: var(--td-avatar-group-margin-left-small, -16rpx);
|
||||
}
|
||||
.t-avatar-group-offset-left-medium,
|
||||
.t-avatar-group-offset-right-medium {
|
||||
--td-avatar-margin-left: var(--td-avatar-group-margin-left-medium, -16rpx);
|
||||
}
|
||||
.t-avatar-group-offset-left-large,
|
||||
.t-avatar-group-offset-right-large {
|
||||
--td-avatar-margin-left: var(--td-avatar-group-margin-left-large, -16rpx);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(1) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 1);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(2) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 2);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(3) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 3);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(4) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 4);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(5) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 5);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(6) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 6);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(7) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 7);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(8) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 8);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(9) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 9);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(10) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 10);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(11) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 11);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(12) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 12);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(13) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 13);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(14) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 14);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(15) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 15);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(16) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 16);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(17) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 17);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(18) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 18);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(19) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 19);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(20) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 20);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(21) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 21);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(22) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 22);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(23) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 23);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(24) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 24);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(25) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 25);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(26) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 26);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(27) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 27);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(28) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 28);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(29) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 29);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(30) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 30);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(31) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 31);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(32) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 32);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(33) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 33);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(34) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 34);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(35) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 35);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(36) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 36);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(37) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 37);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(38) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 38);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(39) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 39);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(40) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 40);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(41) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 41);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(42) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 42);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(43) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 43);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(44) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 44);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(45) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 45);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(46) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 46);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(47) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 47);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(48) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 48);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(49) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 49);
|
||||
}
|
||||
.t-avatar-group-offset-left .t-avatar__wrapper:nth-child(50) {
|
||||
z-index: calc(var(--td-avatar-group-init-z-index, 50) - 50);
|
||||
}
|
||||
.t-avatar-group__collapse--slot,
|
||||
.t-avatar-group__collapse--default {
|
||||
z-index: 0;
|
||||
font-weight: 600;
|
||||
}
|
||||
.t-avatar-group__collapse--slot {
|
||||
float: left;
|
||||
}
|
||||
.t-avatar-group__collapse--slot:not(:empty) + .t-avatar-group__collapse--default {
|
||||
display: none;
|
||||
float: left;
|
||||
}
|
||||
.t-avatar-group__collapse--slot:empty + .t-avatar-group__collapse--default {
|
||||
display: block;
|
||||
float: left;
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
<template>
|
||||
<view
|
||||
:style="tools._style([customStyle])"
|
||||
:class="className"
|
||||
>
|
||||
<slot />
|
||||
<view :class="classPrefix + '__collapse--slot'">
|
||||
<slot name="collapse-avatar" />
|
||||
</view>
|
||||
<view
|
||||
v-if="max && max < length"
|
||||
:class="classPrefix + '__collapse--default'"
|
||||
@click="onCollapsedItemClick"
|
||||
>
|
||||
<t-avatar
|
||||
:t-class-image="prefix + '-avatar--border ' + prefix + '-avatar--border-' + size + ' ' + tClassImage"
|
||||
:t-class-content="tClassContent"
|
||||
:size="size"
|
||||
:shape="shape"
|
||||
:icon="collapseAvatar ? '' : 'user-add'"
|
||||
aria-role="none"
|
||||
>
|
||||
{{ collapseAvatar }}
|
||||
</t-avatar>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import TAvatar from '../avatar/avatar';
|
||||
import { uniComponent } from '../common/src/index';
|
||||
import { prefix } from '../common/config';
|
||||
import avatarGroupProps from './props';
|
||||
|
||||
import tools from '../common/utils.wxs';
|
||||
import { ParentMixin, RELATION_MAP } from '../common/relation';
|
||||
|
||||
|
||||
const name = `${prefix}-avatar-group`;
|
||||
const AVATAR_GROUP_INIT_Z_INDEX = 50;
|
||||
|
||||
|
||||
export default uniComponent({
|
||||
name,
|
||||
options: {
|
||||
styleIsolation: 'shared',
|
||||
},
|
||||
externalClasses: [
|
||||
`${prefix}-class`,
|
||||
`${prefix}-class-content`,
|
||||
`${prefix}-class-image`,
|
||||
],
|
||||
mixins: [ParentMixin(RELATION_MAP.Avatar)],
|
||||
components: {
|
||||
TAvatar,
|
||||
},
|
||||
props: {
|
||||
...avatarGroupProps,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
prefix,
|
||||
classPrefix: name,
|
||||
hasChild: true,
|
||||
length: 0,
|
||||
className: '',
|
||||
tools,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
cascading: 'setClass',
|
||||
size: 'setClass',
|
||||
},
|
||||
mounted() {
|
||||
this.setClass();
|
||||
this.length = this.children?.length || 0;
|
||||
if (this.length) {
|
||||
this.handleMax();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
setClass() {
|
||||
const { cascading, size } = this;
|
||||
const direction = cascading.split('-')[0];
|
||||
const classList = [
|
||||
name,
|
||||
this.tClass,
|
||||
`${name}-offset-${direction}`,
|
||||
`${name}-offset-${direction}-${size.indexOf('px') > -1 ? 'medium' : size || 'medium'}`,
|
||||
];
|
||||
|
||||
this.className = classList.join(' ');
|
||||
},
|
||||
|
||||
handleMax() {
|
||||
const { max, cascading } = this;
|
||||
const len = this.children.length;
|
||||
if (!max || max > len) return;
|
||||
|
||||
const restAvatars = this.children.splice(max, len - max);
|
||||
|
||||
const isLeft = cascading === 'left-up';
|
||||
this.children.forEach((child, index) => {
|
||||
child.setStyle({
|
||||
zIndex: isLeft && `calc(var(--td-avatar-group-init-z-index, ${AVATAR_GROUP_INIT_Z_INDEX}) - ${index})`,
|
||||
padding: 'var(--td-avatar-group-line-spacing, 2px) 0',
|
||||
});
|
||||
});
|
||||
|
||||
restAvatars.forEach((child) => {
|
||||
child.hide();
|
||||
});
|
||||
},
|
||||
onCollapsedItemClick(e) {
|
||||
this.$emit('collapsed-item-click', e);
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style scoped>
|
||||
@import './avatar-group.css';
|
||||
</style>
|
||||
44
uni_modules/tdesign-uniapp/components/avatar-group/props.ts
Normal file
44
uni_modules/tdesign-uniapp/components/avatar-group/props.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
|
||||
* */
|
||||
|
||||
import type { TdAvatarGroupProps } from './type';
|
||||
export default {
|
||||
/** 图片之间的层叠关系,可选值:左侧图片在上和右侧图片在上 */
|
||||
cascading: {
|
||||
type: String,
|
||||
default: 'left-up' as TdAvatarGroupProps['cascading'],
|
||||
validator(val: TdAvatarGroupProps['cascading']): boolean {
|
||||
if (!val) return true;
|
||||
return ['left-up', 'right-up'].includes(val);
|
||||
},
|
||||
},
|
||||
/** 头像数量超出时,会出现一个头像折叠元素。该元素内容可自定义。默认为 `+N`。示例:`+5`,`...`, `更多` */
|
||||
collapseAvatar: {
|
||||
type: String,
|
||||
},
|
||||
/** 能够同时显示的最多头像数量 */
|
||||
max: {
|
||||
type: Number,
|
||||
},
|
||||
/** 形状。优先级低于 Avatar.shape */
|
||||
shape: {
|
||||
type: String,
|
||||
validator(val: TdAvatarGroupProps['shape']): boolean {
|
||||
if (!val) return true;
|
||||
return ['circle', 'round'].includes(val);
|
||||
},
|
||||
},
|
||||
/** 尺寸,示例值:small/medium/large/24px/38px 等。优先级低于 Avatar.size */
|
||||
size: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
/** 点击头像折叠元素触发 */
|
||||
onCollapsedItemClick: {
|
||||
type: Function,
|
||||
default: () => ({}),
|
||||
},
|
||||
};
|
||||
38
uni_modules/tdesign-uniapp/components/avatar-group/type.ts
Normal file
38
uni_modules/tdesign-uniapp/components/avatar-group/type.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
|
||||
* */
|
||||
|
||||
import type { ShapeEnum } from '../common/common';
|
||||
|
||||
export interface TdAvatarGroupProps {
|
||||
/**
|
||||
* 图片之间的层叠关系,可选值:左侧图片在上和右侧图片在上
|
||||
* @default 'left-up'
|
||||
*/
|
||||
cascading?: CascadingValue;
|
||||
/**
|
||||
* 头像数量超出时,会出现一个头像折叠元素。该元素内容可自定义。默认为 `+N`。示例:`+5`,`...`, `更多`
|
||||
*/
|
||||
collapseAvatar?: string;
|
||||
/**
|
||||
* 能够同时显示的最多头像数量
|
||||
*/
|
||||
max?: number;
|
||||
/**
|
||||
* 形状。优先级低于 Avatar.shape
|
||||
*/
|
||||
shape?: ShapeEnum;
|
||||
/**
|
||||
* 尺寸,示例值:small/medium/large/24px/38px 等。优先级低于 Avatar.size
|
||||
* @default ''
|
||||
*/
|
||||
size?: string;
|
||||
/**
|
||||
* 点击头像折叠元素触发
|
||||
*/
|
||||
onCollapsedItemClick?: (e: MouseEvent) => void;
|
||||
}
|
||||
|
||||
export type CascadingValue = 'left-up' | 'right-up';
|
||||
102
uni_modules/tdesign-uniapp/components/avatar/README.en-US.md
Normal file
102
uni_modules/tdesign-uniapp/components/avatar/README.en-US.md
Normal file
@@ -0,0 +1,102 @@
|
||||
:: BASE_DOC ::
|
||||
|
||||
## API
|
||||
|
||||
### Avatar Props
|
||||
|
||||
name | type | default | description | required
|
||||
-- | -- | -- | -- | --
|
||||
custom-style | Object | - | CSS(Cascading Style Sheets) | N
|
||||
alt | String | - | show it when url is not valid | N
|
||||
badge-props | Object | {} | Typescript:`BadgeProps`,[Badge API Documents](./badge?tab=api)。[see more ts definition](https://github.com/Tencent/tdesign-miniprogram/tree/develop/packages/uniapp-components/avatar/type.ts) | N
|
||||
bordered | Boolean | false | \- | N
|
||||
hide-on-load-failed | Boolean | false | hide image when loading image failed | N
|
||||
icon | String / Object | - | \- | N
|
||||
image | String | - | images url | N
|
||||
image-props | Object | - | Typescript:`ImageProps`,[Image API Documents](./image?tab=api)。[see more ts definition](https://github.com/Tencent/tdesign-miniprogram/tree/develop/packages/uniapp-components/avatar/type.ts) | N
|
||||
shape | String | - | shape。options: circle/round。Typescript:`ShapeEnum`。[see more ts definition](https://github.com/Tencent/tdesign-miniprogram/tree/develop/packages/uniapp-components/common/common.ts) | N
|
||||
size | String | - | size | N
|
||||
|
||||
### Avatar Events
|
||||
|
||||
name | params | description
|
||||
-- | -- | --
|
||||
error | `(e: Event)` | trigger on image load failed
|
||||
|
||||
### Avatar Slots
|
||||
|
||||
name | Description
|
||||
-- | --
|
||||
\- | \-
|
||||
|
||||
### Avatar External Classes
|
||||
|
||||
className | Description
|
||||
-- | --
|
||||
t-class | \-
|
||||
t-class-alt | \-
|
||||
t-class-content | \-
|
||||
t-class-icon | \-
|
||||
t-class-image | \-
|
||||
|
||||
|
||||
### AvatarGroup Props
|
||||
|
||||
name | type | default | description | required
|
||||
-- | -- | -- | -- | --
|
||||
custom-style | Object | - | CSS(Cascading Style Sheets) | N
|
||||
cascading | String | 'left-up' | multiple images cascading。options: left-up/right-up。Typescript:`CascadingValue` `type CascadingValue = 'left-up' \| 'right-up'`。[see more ts definition](https://github.com/Tencent/tdesign-miniprogram/tree/develop/packages/uniapp-components/avatar-group/type.ts) | N
|
||||
collapse-avatar | String | - | \- | N
|
||||
max | Number | - | \- | N
|
||||
shape | String | - | shape。options: circle/round。Typescript:`ShapeEnum`。[see more ts definition](https://github.com/Tencent/tdesign-miniprogram/tree/develop/packages/uniapp-components/common/common.ts) | N
|
||||
size | String | - | size | N
|
||||
|
||||
### AvatarGroup Events
|
||||
|
||||
name | params | description
|
||||
-- | -- | --
|
||||
collapsed-item-click | `(e: MouseEvent)` | \-
|
||||
|
||||
### AvatarGroup Slots
|
||||
|
||||
name | Description
|
||||
-- | --
|
||||
\- | \-
|
||||
collapse-avatar | \-
|
||||
|
||||
### AvatarGroup External Classes
|
||||
|
||||
className | Description
|
||||
-- | --
|
||||
t-class | \-
|
||||
t-class-content | \-
|
||||
t-class-image | \-
|
||||
|
||||
### CSS Variables
|
||||
|
||||
The component provides the following CSS variables, which can be used to customize styles.
|
||||
Name | Default Value | Description
|
||||
-- | -- | --
|
||||
--td-avatar-group-init-z-index | @avatar-group-init-zIndex | -
|
||||
--td-avatar-group-line-spacing | 4rpx | -
|
||||
--td-avatar-group-margin-left-large | -16rpx | -
|
||||
--td-avatar-group-margin-left-medium | -16rpx | -
|
||||
--td-avatar-group-margin-left-small | -16rpx | -
|
||||
--td-avatar-bg-color | @brand-color-light-active | -
|
||||
--td-avatar-border-color | #fff | -
|
||||
--td-avatar-border-width-large | 6rpx | -
|
||||
--td-avatar-border-width-medium | 4rpx | -
|
||||
--td-avatar-border-width-small | 2rpx | -
|
||||
--td-avatar-circle-border-radius | @radius-circle | -
|
||||
--td-avatar-content-color | @brand-color | -
|
||||
--td-avatar-icon-large-font-size | 64rpx | -
|
||||
--td-avatar-icon-medium-font-size | 48rpx | -
|
||||
--td-avatar-icon-small-font-size | 40rpx | -
|
||||
--td-avatar-large-width | 128rpx | -
|
||||
--td-avatar-margin-left | 0 | -
|
||||
--td-avatar-medium-width | 96rpx | -
|
||||
--td-avatar-round-border-radius | @radius-default | -
|
||||
--td-avatar-small-width | 80rpx | -
|
||||
--td-avatar-text-large-font-size | @font-size-xl | -
|
||||
--td-avatar-text-medium-font-size | @font-size-m | -
|
||||
--td-avatar-text-small-font-size | @font-size-base | -
|
||||
152
uni_modules/tdesign-uniapp/components/avatar/README.md
Normal file
152
uni_modules/tdesign-uniapp/components/avatar/README.md
Normal file
@@ -0,0 +1,152 @@
|
||||
---
|
||||
title: Avatar 头像
|
||||
description: 用于展示用户头像信息,除了纯展示也可点击进入个人详情等操作。
|
||||
spline: data
|
||||
isComponent: true
|
||||
---
|
||||
|
||||
|
||||
## 引入
|
||||
|
||||
可在 `main.ts` 或在需要使用的页面或组件中引入。
|
||||
|
||||
```js
|
||||
import TAvatar from '@tdesign/uniapp/avatar/avatar.vue';
|
||||
import TAvatarGroup from '@tdesign/uniapp/avatar-group/avatar-group.vue';
|
||||
```
|
||||
|
||||
### 头像类型
|
||||
|
||||
图片头像
|
||||
|
||||
{{ image-avatar }}
|
||||
|
||||
字符头像
|
||||
|
||||
{{ character-avatar }}
|
||||
|
||||
图标头像
|
||||
|
||||
{{ icon-avatar }}
|
||||
|
||||
徽标头像
|
||||
|
||||
{{ badge-avatar }}
|
||||
|
||||
|
||||
### 组合头像
|
||||
|
||||
纯展示
|
||||
|
||||
{{ exhibition }}
|
||||
|
||||
带操作
|
||||
|
||||
{{ action }}
|
||||
|
||||
### 头像尺寸
|
||||
|
||||
头像 large/medium/small 尺寸
|
||||
|
||||
{{ size }}
|
||||
|
||||
## API
|
||||
|
||||
### Avatar Props
|
||||
|
||||
名称 | 类型 | 默认值 | 描述 | 必传
|
||||
-- | -- | -- | -- | --
|
||||
custom-style | Object | - | 自定义样式 | N
|
||||
alt | String | - | 头像替换文本,仅当图片加载失败时有效 | N
|
||||
badge-props | Object | {} | 头像右上角提示信息,继承 Badge 组件的全部特性。如:小红点,或者数字。TS 类型:`BadgeProps`,[Badge API Documents](./badge?tab=api)。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/packages/uniapp-components/avatar/type.ts) | N
|
||||
bordered | Boolean | false | 已废弃。是否显示外边框 | N
|
||||
hide-on-load-failed | Boolean | false | 加载失败时隐藏图片 | N
|
||||
icon | String / Object | - | 图标。值为字符串表示图标名称,值为 `Object` 类型,表示透传至 `icon` | N
|
||||
image | String | - | 图片地址 | N
|
||||
image-props | Object | - | 透传至 Image 组件。TS 类型:`ImageProps`,[Image API Documents](./image?tab=api)。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/packages/uniapp-components/avatar/type.ts) | N
|
||||
shape | String | - | 形状。优先级高于 AvatarGroup.shape 。Avatar 单独存在时,默认值为 circle。如果父组件 AvatarGroup 存在,默认值便由 AvatarGroup.shape 决定。可选项:circle/round。TS 类型:`ShapeEnum`。[通用类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/packages/uniapp-components/common/common.ts) | N
|
||||
size | String | - | 尺寸,示例值:small/medium/large/24px/38px 等。优先级高于 AvatarGroup.size 。Avatar 单独存在时,默认值为 medium。如果父组件 AvatarGroup 存在,默认值便由 AvatarGroup.size 决定 | N
|
||||
|
||||
### Avatar Events
|
||||
|
||||
名称 | 参数 | 描述
|
||||
-- | -- | --
|
||||
error | `(e: Event)` | 图片加载失败时触发
|
||||
|
||||
### Avatar Slots
|
||||
|
||||
名称 | 描述
|
||||
-- | --
|
||||
\- | 默认插槽,自定义内容区域内容
|
||||
|
||||
### Avatar External Classes
|
||||
|
||||
类名 | 描述
|
||||
-- | --
|
||||
t-class | 根节点样式类
|
||||
t-class-alt | 替代文本样式类
|
||||
t-class-content | 内容样式类
|
||||
t-class-icon | 图标样式类
|
||||
t-class-image | 图片样式类
|
||||
|
||||
|
||||
### AvatarGroup Props
|
||||
|
||||
名称 | 类型 | 默认值 | 描述 | 必传
|
||||
-- | -- | -- | -- | --
|
||||
custom-style | Object | - | 自定义样式 | N
|
||||
cascading | String | 'left-up' | 图片之间的层叠关系,可选值:左侧图片在上和右侧图片在上。可选项:left-up/right-up。TS 类型:`CascadingValue` `type CascadingValue = 'left-up' \| 'right-up'`。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/packages/uniapp-components/avatar-group/type.ts) | N
|
||||
collapse-avatar | String | - | 头像数量超出时,会出现一个头像折叠元素。该元素内容可自定义。默认为 `+N`。示例:`+5`,`...`, `更多` | N
|
||||
max | Number | - | 能够同时显示的最多头像数量 | N
|
||||
shape | String | - | 形状。优先级低于 Avatar.shape。可选项:circle/round。TS 类型:`ShapeEnum`。[通用类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/packages/uniapp-components/common/common.ts) | N
|
||||
size | String | - | 尺寸,示例值:small/medium/large/24px/38px 等。优先级低于 Avatar.size | N
|
||||
|
||||
### AvatarGroup Events
|
||||
|
||||
名称 | 参数 | 描述
|
||||
-- | -- | --
|
||||
collapsed-item-click | `(e: MouseEvent)` | 点击头像折叠元素触发
|
||||
|
||||
### AvatarGroup Slots
|
||||
|
||||
名称 | 描述
|
||||
-- | --
|
||||
\- | 默认插槽,自定义内容区域内容
|
||||
collapse-avatar | 自定义 `collapse-avatar` 显示内容
|
||||
|
||||
### AvatarGroup External Classes
|
||||
|
||||
类名 | 描述
|
||||
-- | --
|
||||
t-class | 根节点样式类
|
||||
t-class-content | 内容样式类
|
||||
t-class-image | 图片样式类
|
||||
|
||||
### CSS Variables
|
||||
|
||||
组件提供了下列 CSS 变量,可用于自定义样式。
|
||||
名称 | 默认值 | 描述
|
||||
-- | -- | --
|
||||
--td-avatar-group-init-z-index | @avatar-group-init-zIndex | -
|
||||
--td-avatar-group-line-spacing | 4rpx | -
|
||||
--td-avatar-group-margin-left-large | -16rpx | -
|
||||
--td-avatar-group-margin-left-medium | -16rpx | -
|
||||
--td-avatar-group-margin-left-small | -16rpx | -
|
||||
--td-avatar-bg-color | @brand-color-light-active | -
|
||||
--td-avatar-border-color | #fff | -
|
||||
--td-avatar-border-width-large | 6rpx | -
|
||||
--td-avatar-border-width-medium | 4rpx | -
|
||||
--td-avatar-border-width-small | 2rpx | -
|
||||
--td-avatar-circle-border-radius | @radius-circle | -
|
||||
--td-avatar-content-color | @brand-color | -
|
||||
--td-avatar-icon-large-font-size | 64rpx | -
|
||||
--td-avatar-icon-medium-font-size | 48rpx | -
|
||||
--td-avatar-icon-small-font-size | 40rpx | -
|
||||
--td-avatar-large-width | 128rpx | -
|
||||
--td-avatar-margin-left | 0 | -
|
||||
--td-avatar-medium-width | 96rpx | -
|
||||
--td-avatar-round-border-radius | @radius-default | -
|
||||
--td-avatar-small-width | 80rpx | -
|
||||
--td-avatar-text-large-font-size | @font-size-xl | -
|
||||
--td-avatar-text-medium-font-size | @font-size-m | -
|
||||
--td-avatar-text-small-font-size | @font-size-base | -
|
||||
77
uni_modules/tdesign-uniapp/components/avatar/avatar.css
Normal file
77
uni_modules/tdesign-uniapp/components/avatar/avatar.css
Normal file
@@ -0,0 +1,77 @@
|
||||
.t-avatar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-sizing: border-box;
|
||||
background-color: var(--td-avatar-bg-color, var(--td-brand-color-light-active, var(--td-primary-color-2, #d9e1ff)));
|
||||
color: var(--td-avatar-content-color, var(--td-brand-color, var(--td-primary-color-7, #0052d9)));
|
||||
}
|
||||
.t-avatar__wrapper {
|
||||
display: inline-flex;
|
||||
position: relative;
|
||||
vertical-align: top;
|
||||
margin-left: var(--td-avatar-margin-left, 0);
|
||||
}
|
||||
.t-avatar--large {
|
||||
width: var(--td-avatar-large-width, 128rpx);
|
||||
height: var(--td-avatar-large-width, 128rpx);
|
||||
font-size: var(--td-avatar-text-large-font-size, var(--td-font-size-xl, 40rpx));
|
||||
}
|
||||
.t-avatar--large .t-avatar__icon {
|
||||
font-size: var(--td-avatar-icon-large-font-size, 64rpx);
|
||||
}
|
||||
.t-avatar--medium {
|
||||
width: var(--td-avatar-medium-width, 96rpx);
|
||||
height: var(--td-avatar-medium-width, 96rpx);
|
||||
font-size: var(--td-avatar-text-medium-font-size, var(--td-font-size-m, 32rpx));
|
||||
}
|
||||
.t-avatar--medium .t-avatar__icon {
|
||||
font-size: var(--td-avatar-icon-medium-font-size, 48rpx);
|
||||
}
|
||||
.t-avatar--small {
|
||||
width: var(--td-avatar-small-width, 80rpx);
|
||||
height: var(--td-avatar-small-width, 80rpx);
|
||||
font-size: var(--td-avatar-text-small-font-size, var(--td-font-size-base, 28rpx));
|
||||
}
|
||||
.t-avatar--small .t-avatar__icon {
|
||||
font-size: var(--td-avatar-icon-small-font-size, 40rpx);
|
||||
}
|
||||
.t-avatar .t-image,
|
||||
.t-avatar__image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.t-avatar--circle {
|
||||
border-radius: var(--td-avatar-circle-border-radius, var(--td-radius-circle, 50%));
|
||||
overflow: hidden;
|
||||
}
|
||||
.t-avatar--round {
|
||||
border-radius: var(--td-avatar-round-border-radius, var(--td-radius-default, 12rpx));
|
||||
overflow: hidden;
|
||||
}
|
||||
.t-avatar__text,
|
||||
.t-avatar__icon {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.t-avatar__text:empty,
|
||||
.t-avatar__icon:empty {
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
.t-avatar--border {
|
||||
border-color: var(--td-avatar-border-color, #fff);
|
||||
border-style: solid;
|
||||
}
|
||||
.t-avatar--border-small {
|
||||
border-width: var(--td-avatar-border-width-small, 2rpx);
|
||||
}
|
||||
.t-avatar--border-medium {
|
||||
border-width: var(--td-avatar-border-width-medium, 4rpx);
|
||||
}
|
||||
.t-avatar--border-large {
|
||||
border-width: var(--td-avatar-border-width-large, 6rpx);
|
||||
}
|
||||
200
uni_modules/tdesign-uniapp/components/avatar/avatar.vue
Normal file
200
uni_modules/tdesign-uniapp/components/avatar/avatar.vue
Normal file
@@ -0,0 +1,200 @@
|
||||
<template>
|
||||
<view
|
||||
:class="[
|
||||
classPrefix + '__wrapper',
|
||||
tClass
|
||||
]"
|
||||
:style="tools._style([utils.getStyles(isShow), customStyle, innerStyle])"
|
||||
>
|
||||
<t-badge
|
||||
v-if="badgeProps"
|
||||
:color="badgeProps.color || ''"
|
||||
:content="badgeProps.content || ''"
|
||||
:count="badgeProps.count || 0"
|
||||
:dot="badgeProps.dot || false"
|
||||
:max-count="badgeProps.maxCount || 99"
|
||||
:offset="badgeProps.offset || []"
|
||||
:shape="badgeProps.shape || 'circle'"
|
||||
:show-zero="badgeProps.showZero || false"
|
||||
:size="badgeProps.size || 'medium'"
|
||||
:t-class="badgeProps.tClass"
|
||||
:t-class-content="badgeProps.tClassContent"
|
||||
:t-class-count="badgeProps.tClassCount"
|
||||
>
|
||||
<view
|
||||
:class="[
|
||||
utils.getClass(classPrefix, dataSize || 'medium', dataShape, dataBordered),
|
||||
tClassImage
|
||||
]"
|
||||
:style="utils.getSize(dataSize, windowWidth)"
|
||||
:aria-label="ariaLabel || alt || '头像'"
|
||||
:aria-role="ariaRole || 'img'"
|
||||
:aria-hidden="ariaHidden"
|
||||
>
|
||||
<t-image
|
||||
v-if="image"
|
||||
:t-class="prefix + '-image ' + classPrefix + '__image'"
|
||||
:t-class-load="tClassAlt"
|
||||
:custom-style="imageCustomStyle"
|
||||
style="width: 100%;height: 100%;"
|
||||
:src="image"
|
||||
:mode="(imageProps && imageProps.mode) || 'aspectFill'"
|
||||
:lazy="(imageProps && imageProps.lazy) || false"
|
||||
:loading="(imageProps && imageProps.loading) || 'default'"
|
||||
:shape="(imageProps && imageProps.shape) || 'round'"
|
||||
:webp="(imageProps && imageProps.webp) || false"
|
||||
:error="alt || 'default'"
|
||||
@error="onLoadError"
|
||||
/>
|
||||
<block
|
||||
v-else-if="iconName || tools.isNoEmptyObj(iconData)"
|
||||
name="icon"
|
||||
>
|
||||
<t-icon
|
||||
:t-class="classPrefix + '__icon ' + classPrefix + '__icon--' + (iconData.activeIdx == iconData.index ? 'active ' : ' ') + tClassIcon"
|
||||
:prefix="iconData.prefix"
|
||||
:name="iconName || iconData.name"
|
||||
:size="iconData.size"
|
||||
:color="iconData.color"
|
||||
:aria-hidden="!!iconData.ariaHidden"
|
||||
:aria-label="iconData.ariaLabel"
|
||||
:aria-role="iconData.ariaRole"
|
||||
:custom-style="iconCustomStyle"
|
||||
@click="iconData.click || ''"
|
||||
/>
|
||||
</block>
|
||||
<view
|
||||
v-else
|
||||
:class="[
|
||||
classPrefix + '__text ',
|
||||
tClassContent
|
||||
]"
|
||||
>
|
||||
<slot />
|
||||
</view>
|
||||
</view>
|
||||
</t-badge>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import TIcon from '../icon/icon';
|
||||
import TBadge from '../badge/badge';
|
||||
import TImage from '../image/image';
|
||||
import { uniComponent } from '../common/src/index';
|
||||
import { prefix } from '../common/config';
|
||||
import avatarProps from './props';
|
||||
import { setIcon, systemInfo } from '../common/utils';
|
||||
import tools from '../common/utils.wxs';
|
||||
import * as utils from './computed.js';
|
||||
import { ChildrenMixin, RELATION_MAP } from '../common/relation';
|
||||
|
||||
|
||||
const name = `${prefix}-avatar`;
|
||||
|
||||
|
||||
export default uniComponent({
|
||||
name,
|
||||
options: {
|
||||
styleIsolation: 'shared',
|
||||
},
|
||||
externalClasses: [
|
||||
`${prefix}-class`,
|
||||
`${prefix}-class-image`,
|
||||
`${prefix}-class-icon`,
|
||||
`${prefix}-class-alt`,
|
||||
`${prefix}-class-content`,
|
||||
],
|
||||
mixins: [ChildrenMixin(RELATION_MAP.Avatar)],
|
||||
components: {
|
||||
TIcon,
|
||||
TBadge,
|
||||
TImage,
|
||||
},
|
||||
props: {
|
||||
...avatarProps,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
prefix,
|
||||
classPrefix: name,
|
||||
isShow: true,
|
||||
zIndex: 0,
|
||||
windowWidth: systemInfo.windowWidth,
|
||||
utils,
|
||||
tools,
|
||||
|
||||
iconName: '',
|
||||
iconData: {},
|
||||
|
||||
dataShape: this.shape,
|
||||
dataSize: this.size,
|
||||
dataBordered: this.bordered,
|
||||
innerStyle: '',
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
iconCustomStyle() {
|
||||
const fontSize = {
|
||||
small: 'var(--td-avatar-icon-small-font-size, 20px)',
|
||||
medium: 'var(--td-avatar-icon-medium-font-size, 24px)',
|
||||
large: 'var(--td-avatar-icon-large-font-size, 32px)',
|
||||
};
|
||||
if (!fontSize[this.dataSize]) return '';
|
||||
return tools._style([
|
||||
{
|
||||
fontSize: fontSize[this.dataSize],
|
||||
},
|
||||
this.iconData.style || '',
|
||||
]);
|
||||
},
|
||||
imageCustomStyle() {
|
||||
return tools._style([
|
||||
{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
},
|
||||
this.imageProps?.style || '',
|
||||
]);
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
icon: {
|
||||
handler(t) {
|
||||
const obj = setIcon('icon', t, '');
|
||||
|
||||
Object.keys(obj).forEach((key) => {
|
||||
this[key] = obj[key];
|
||||
});
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
|
||||
},
|
||||
mounted() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
innerAfterLinked() {
|
||||
this.dataShape = this.shape || this[RELATION_MAP.Avatar]?.shape || 'circle';
|
||||
this.dataSize = this.size || this[RELATION_MAP.Avatar]?.size;
|
||||
this.dataBordered = true;
|
||||
},
|
||||
hide() {
|
||||
this.isShow = false;
|
||||
},
|
||||
onLoadError(e) {
|
||||
if (this.hideOnLoadFailed) {
|
||||
this.isShow = false;
|
||||
}
|
||||
this.$emit('error', e && e.e);
|
||||
},
|
||||
setStyle(val = '') {
|
||||
this.innerStyle = val;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
</script>
|
||||
<style scoped>
|
||||
@import './avatar.css';
|
||||
</style>
|
||||
30
uni_modules/tdesign-uniapp/components/avatar/computed.js
Normal file
30
uni_modules/tdesign-uniapp/components/avatar/computed.js
Normal file
@@ -0,0 +1,30 @@
|
||||
import { getRegExp } from '../common/runtime/wxs-polyfill';
|
||||
|
||||
export function getClass(classPrefix, size, shape, bordered) {
|
||||
const hasPx = (size || '').indexOf('px') > -1;
|
||||
const borderSize = hasPx ? 'medium' : size;
|
||||
const classNames = [
|
||||
classPrefix,
|
||||
classPrefix + (shape === 'round' ? '--round' : '--circle'),
|
||||
bordered ? `${classPrefix}--border ${classPrefix}--border-${borderSize}` : '',
|
||||
hasPx ? '' : `${classPrefix}--${size}`,
|
||||
];
|
||||
return classNames.join(' ');
|
||||
}
|
||||
|
||||
export function getSize(size = 'medium', windowWidth) {
|
||||
const res = getRegExp('^([0-9]+)(px|rpx)$').exec(size);
|
||||
|
||||
if (res && res.length >= 3) {
|
||||
let px = res[1];
|
||||
if (res[2] === 'rpx') {
|
||||
px = Math.floor((windowWidth * res[1]) / 750);
|
||||
}
|
||||
|
||||
return `width:${size};height:${size};font-size:${(px / 8) * 3 + 2}px`;
|
||||
}
|
||||
}
|
||||
|
||||
export function getStyles(isShow) {
|
||||
return isShow ? '' : 'display: none;';
|
||||
}
|
||||
54
uni_modules/tdesign-uniapp/components/avatar/props.ts
Normal file
54
uni_modules/tdesign-uniapp/components/avatar/props.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
|
||||
* */
|
||||
|
||||
import type { TdAvatarProps } from './type';
|
||||
export default {
|
||||
/** 头像替换文本,仅当图片加载失败时有效 */
|
||||
alt: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
/** 头像右上角提示信息,继承 Badge 组件的全部特性。如:小红点,或者数字 */
|
||||
badgeProps: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
/** 已废弃。是否显示外边框 */
|
||||
bordered: Boolean,
|
||||
/** 加载失败时隐藏图片 */
|
||||
hideOnLoadFailed: Boolean,
|
||||
/** 图标。值为字符串表示图标名称,值为 `Object` 类型,表示透传至 `icon` */
|
||||
icon: {
|
||||
type: [String, Object],
|
||||
},
|
||||
/** 图片地址 */
|
||||
image: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
/** 透传至 Image 组件 */
|
||||
imageProps: {
|
||||
type: Object,
|
||||
},
|
||||
/** 形状。优先级高于 AvatarGroup.shape 。Avatar 单独存在时,默认值为 circle。如果父组件 AvatarGroup 存在,默认值便由 AvatarGroup.shape 决定 */
|
||||
shape: {
|
||||
type: String,
|
||||
validator(val: TdAvatarProps['shape']): boolean {
|
||||
if (!val) return true;
|
||||
return ['circle', 'round'].includes(val);
|
||||
},
|
||||
},
|
||||
/** 尺寸,示例值:small/medium/large/24px/38px 等。优先级高于 AvatarGroup.size 。Avatar 单独存在时,默认值为 medium。如果父组件 AvatarGroup 存在,默认值便由 AvatarGroup.size 决定 */
|
||||
size: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
/** 图片加载失败时触发 */
|
||||
onError: {
|
||||
type: Function,
|
||||
default: () => ({}),
|
||||
},
|
||||
};
|
||||
58
uni_modules/tdesign-uniapp/components/avatar/type.ts
Normal file
58
uni_modules/tdesign-uniapp/components/avatar/type.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
|
||||
* */
|
||||
|
||||
import type { TdBadgeProps as BadgeProps } from '../badge/type';
|
||||
import type { TdImageProps as ImageProps } from '../image/type';
|
||||
import type { ShapeEnum } from '../common/common';
|
||||
|
||||
export interface TdAvatarProps {
|
||||
/**
|
||||
* 头像替换文本,仅当图片加载失败时有效
|
||||
* @default ''
|
||||
*/
|
||||
alt?: string;
|
||||
/**
|
||||
* 头像右上角提示信息,继承 Badge 组件的全部特性。如:小红点,或者数字
|
||||
* @default {}
|
||||
*/
|
||||
badgeProps?: BadgeProps;
|
||||
/**
|
||||
* 已废弃。是否显示外边框
|
||||
* @default false
|
||||
*/
|
||||
bordered?: boolean;
|
||||
/**
|
||||
* 加载失败时隐藏图片
|
||||
* @default false
|
||||
*/
|
||||
hideOnLoadFailed?: boolean;
|
||||
/**
|
||||
* 图标。值为字符串表示图标名称,值为 `Object` 类型,表示透传至 `icon`
|
||||
*/
|
||||
icon?: string | object;
|
||||
/**
|
||||
* 图片地址
|
||||
* @default ''
|
||||
*/
|
||||
image?: string;
|
||||
/**
|
||||
* 透传至 Image 组件
|
||||
*/
|
||||
imageProps?: ImageProps;
|
||||
/**
|
||||
* 形状。优先级高于 AvatarGroup.shape 。Avatar 单独存在时,默认值为 circle。如果父组件 AvatarGroup 存在,默认值便由 AvatarGroup.shape 决定
|
||||
*/
|
||||
shape?: ShapeEnum;
|
||||
/**
|
||||
* 尺寸,示例值:small/medium/large/24px/38px 等。优先级高于 AvatarGroup.size 。Avatar 单独存在时,默认值为 medium。如果父组件 AvatarGroup 存在,默认值便由 AvatarGroup.size 决定
|
||||
* @default ''
|
||||
*/
|
||||
size?: string;
|
||||
/**
|
||||
* 图片加载失败时触发
|
||||
*/
|
||||
onError?: (e: Event) => void;
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
:: BASE_DOC ::
|
||||
|
||||
## API
|
||||
|
||||
### BackTop Props
|
||||
|
||||
name | type | default | description | required
|
||||
-- | -- | -- | -- | --
|
||||
custom-style | Object | - | CSS(Cascading Style Sheets) | N
|
||||
fixed | Boolean | true | \- | N
|
||||
icon | String / Boolean / Object | true | \- | N
|
||||
scroll-top | Number | 0 | \- | N
|
||||
text | String | '' | \- | N
|
||||
theme | String | round | options: round/half-round/round-dark/half-round-dark | N
|
||||
visibility-height | Number | 200 | \- | N
|
||||
|
||||
### BackTop Events
|
||||
|
||||
name | params | description
|
||||
-- | -- | --
|
||||
to-top | \- | \-
|
||||
|
||||
### BackTop Slots
|
||||
|
||||
name | Description
|
||||
-- | --
|
||||
\- | \-
|
||||
icon | \-
|
||||
|
||||
### BackTop External Classes
|
||||
|
||||
className | Description
|
||||
-- | --
|
||||
t-class | \-
|
||||
t-class-icon | \-
|
||||
t-class-text | \-
|
||||
|
||||
### CSS Variables
|
||||
|
||||
The component provides the following CSS variables, which can be used to customize styles.
|
||||
Name | Default Value | Description
|
||||
-- | -- | --
|
||||
--td-back-top-half-round-border-radius | @radius-round | -
|
||||
--td-back-top-round-bg-color | @bg-color-container | -
|
||||
--td-back-top-round-border-color | @component-border | -
|
||||
--td-back-top-round-border-radius | @radius-circle | -
|
||||
--td-back-top-round-color | @text-color-primary | -
|
||||
--td-back-top-round-dark-bg-color | @gray-color-13 | -
|
||||
--td-back-top-round-dark-color | @text-color-anti | -
|
||||
67
uni_modules/tdesign-uniapp/components/back-top/README.md
Normal file
67
uni_modules/tdesign-uniapp/components/back-top/README.md
Normal file
@@ -0,0 +1,67 @@
|
||||
---
|
||||
title: BackTop 返回顶部
|
||||
description: 用于当页面过长往下滑动时,帮助用户快速回到页面顶部。
|
||||
spline: navigation
|
||||
isComponent: true
|
||||
---
|
||||
|
||||
|
||||
## 引入
|
||||
|
||||
可在 `main.ts` 或在需要使用的页面或组件中引入。
|
||||
|
||||
```js
|
||||
import TBackTop from '@tdesign/uniapp/back-top/back-top.vue';
|
||||
```
|
||||
|
||||
### 基础返回顶部
|
||||
|
||||
{{ base }}
|
||||
|
||||
## API
|
||||
|
||||
### BackTop Props
|
||||
|
||||
名称 | 类型 | 默认值 | 描述 | 必传
|
||||
-- | -- | -- | -- | --
|
||||
custom-style | Object | - | 自定义样式 | N
|
||||
fixed | Boolean | true | 是否绝对定位固定到屏幕右下方 | N
|
||||
icon | String / Boolean / Object | true | 图标。值为 `false` 表示不显示图标。不传表示使用默认图标 `'backtop'` | N
|
||||
scroll-top | Number | 0 | 页面滚动距离 | N
|
||||
text | String | '' | 文案 | N
|
||||
theme | String | round | 预设的样式类型。可选项:round/half-round/round-dark/half-round-dark | N
|
||||
visibility-height | Number | 200 | 滚动高度达到此参数值才出现 | N
|
||||
|
||||
### BackTop Events
|
||||
|
||||
名称 | 参数 | 描述
|
||||
-- | -- | --
|
||||
to-top | \- | 点击触发
|
||||
|
||||
### BackTop Slots
|
||||
|
||||
名称 | 描述
|
||||
-- | --
|
||||
\- | 默认插槽,自定义内容区域内容
|
||||
icon | 自定义图标内容
|
||||
|
||||
### BackTop External Classes
|
||||
|
||||
类名 | 描述
|
||||
-- | --
|
||||
t-class | 根节点样式类
|
||||
t-class-icon | 图标样式类
|
||||
t-class-text | 文本样式类
|
||||
|
||||
### CSS Variables
|
||||
|
||||
组件提供了下列 CSS 变量,可用于自定义样式。
|
||||
名称 | 默认值 | 描述
|
||||
-- | -- | --
|
||||
--td-back-top-half-round-border-radius | @radius-round | -
|
||||
--td-back-top-round-bg-color | @bg-color-container | -
|
||||
--td-back-top-round-border-color | @component-border | -
|
||||
--td-back-top-round-border-radius | @radius-circle | -
|
||||
--td-back-top-round-color | @text-color-primary | -
|
||||
--td-back-top-round-dark-bg-color | @gray-color-13 | -
|
||||
--td-back-top-round-dark-color | @text-color-anti | -
|
||||
65
uni_modules/tdesign-uniapp/components/back-top/back-top.css
Normal file
65
uni_modules/tdesign-uniapp/components/back-top/back-top.css
Normal file
@@ -0,0 +1,65 @@
|
||||
.t-back-top {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: transparent;
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
transition: height 0.2s;
|
||||
height: auto;
|
||||
}
|
||||
.t-back-top--fixed {
|
||||
position: fixed;
|
||||
right: var(--td-spacer, 16rpx);
|
||||
bottom: calc(var(--td-spacer-2, 32rpx) + env(safe-area-inset-bottom));
|
||||
}
|
||||
.t-back-top--round,
|
||||
.t-back-top--round-dark {
|
||||
width: 96rpx;
|
||||
height: 96rpx;
|
||||
border-radius: var(--td-back-top-round-border-radius, var(--td-radius-circle, 50%));
|
||||
}
|
||||
.t-back-top--round,
|
||||
.t-back-top--half-round {
|
||||
color: var(--td-back-top-round-color, var(--td-text-color-primary, var(--td-font-gray-1, rgba(0, 0, 0, 0.9))));
|
||||
border: 1rpx solid var(--td-back-top-round-border-color, var(--td-component-border, var(--td-gray-color-4, #dcdcdc)));
|
||||
background-color: var(--td-back-top-round-bg-color, var(--td-bg-color-container, var(--td-font-white-1, #ffffff)));
|
||||
}
|
||||
.t-back-top--round-dark,
|
||||
.t-back-top--half-round-dark {
|
||||
color: var(--td-back-top-round-dark-color, var(--td-text-color-anti, var(--td-font-white-1, #ffffff)));
|
||||
background-color: var(--td-back-top-round-dark-bg-color, var(--td-gray-color-13, #242424));
|
||||
}
|
||||
.t-back-top--half-round,
|
||||
.t-back-top--half-round-dark {
|
||||
width: 120rpx;
|
||||
height: 80rpx;
|
||||
border-radius: 0;
|
||||
border-top-left-radius: var(--td-back-top-half-round-border-radius, var(--td-radius-round, 999px));
|
||||
border-bottom-left-radius: var(--td-back-top-half-round-border-radius, var(--td-radius-round, 999px));
|
||||
flex-direction: row;
|
||||
right: 0;
|
||||
}
|
||||
.t-back-top__text--round,
|
||||
.t-back-top__text--round-dark,
|
||||
.t-back-top__text--half-round,
|
||||
.t-back-top__text--half-round-dark {
|
||||
font-weight: 600;
|
||||
font-size: var(--td-font-size, 20rpx);
|
||||
line-height: 24rpx;
|
||||
}
|
||||
.t-back-top__text--half-round,
|
||||
.t-back-top__text--half-round-dark {
|
||||
width: 48rpx;
|
||||
}
|
||||
.t-back-top__icon:not(:empty) + .t-back-top__text--half-round,
|
||||
.t-back-top__icon:not(:empty) + .t-back-top__text--half-round-dark {
|
||||
margin-left: 8rpx;
|
||||
}
|
||||
.t-back-top__icon {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 44rpx;
|
||||
}
|
||||
122
uni_modules/tdesign-uniapp/components/back-top/back-top.vue
Normal file
122
uni_modules/tdesign-uniapp/components/back-top/back-top.vue
Normal file
@@ -0,0 +1,122 @@
|
||||
<template>
|
||||
<view
|
||||
v-if="!hidden"
|
||||
:style="tools._style([customStyle])"
|
||||
:class="tClass + ' ' + tools.cls(classPrefix, [['fixed', fixed], theme])"
|
||||
aria-role="button"
|
||||
@click="toTop"
|
||||
>
|
||||
<view
|
||||
:class="classPrefix + '__icon'"
|
||||
aria-hidden
|
||||
>
|
||||
<slot name="icon" />
|
||||
<block
|
||||
v-if="_icon"
|
||||
name="icon"
|
||||
>
|
||||
<t-icon
|
||||
:custom-style="_icon.style || ''"
|
||||
:t-class="tClassIcon"
|
||||
:prefix="_icon.prefix"
|
||||
:name="_icon.name"
|
||||
:size="_icon.size"
|
||||
:color="_icon.color"
|
||||
:aria-hidden="!!_icon.ariaHidden"
|
||||
:aria-label="_icon.ariaLabel"
|
||||
:aria-role="_icon.ariaRole"
|
||||
@click="_icon.click || ''"
|
||||
/>
|
||||
</block>
|
||||
</view>
|
||||
<view
|
||||
v-if="!!text"
|
||||
:class="classPrefix + '__text--' + theme + ' ' + tClassText"
|
||||
>
|
||||
{{ text }}
|
||||
</view>
|
||||
<slot />
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import TIcon from '../icon/icon';
|
||||
import { uniComponent } from '../common/src/index';
|
||||
import { prefix } from '../common/config';
|
||||
import props from './props';
|
||||
import { calcIcon } from '../common/utils';
|
||||
import tools from '../common/utils.wxs';
|
||||
import { ChildrenMixin, RELATION_MAP } from '../common/relation';
|
||||
|
||||
|
||||
const name = `${prefix}-back-top`;
|
||||
|
||||
export default uniComponent({
|
||||
name,
|
||||
options: {
|
||||
styleIsolation: 'shared',
|
||||
},
|
||||
externalClasses: [
|
||||
`${prefix}-class`,
|
||||
`${prefix}-class-icon`,
|
||||
`${prefix}-class-text`,
|
||||
],
|
||||
mixins: [
|
||||
ChildrenMixin(RELATION_MAP.BackTop),
|
||||
],
|
||||
components: {
|
||||
TIcon,
|
||||
},
|
||||
props: {
|
||||
...props,
|
||||
},
|
||||
emits: [
|
||||
'to-top',
|
||||
],
|
||||
watch: {
|
||||
icon() {
|
||||
this.setIcon();
|
||||
},
|
||||
scrollTop: {
|
||||
handler(value) {
|
||||
const { visibilityHeight } = this;
|
||||
this.hidden = value < visibilityHeight;
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
const { icon } = this;
|
||||
this.setIcon(icon);
|
||||
},
|
||||
methods: {
|
||||
setIcon(v) {
|
||||
this._icon = calcIcon(v, 'backtop');
|
||||
},
|
||||
|
||||
toTop() {
|
||||
this.$emit('to-top');
|
||||
if (this[RELATION_MAP.BackTop]) {
|
||||
this[RELATION_MAP.BackTop]?.scrollToTop();
|
||||
this.hidden = true;
|
||||
} else {
|
||||
uni.pageScrollTo({
|
||||
scrollTop: 0,
|
||||
duration: 300,
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
prefix,
|
||||
classPrefix: name,
|
||||
_icon: null,
|
||||
hidden: true,
|
||||
tools,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style scoped>
|
||||
@import './back-top.css';
|
||||
</style>
|
||||
48
uni_modules/tdesign-uniapp/components/back-top/props.ts
Normal file
48
uni_modules/tdesign-uniapp/components/back-top/props.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
|
||||
* */
|
||||
|
||||
import type { TdBackTopProps } from './type';
|
||||
export default {
|
||||
/** 是否绝对定位固定到屏幕右下方 */
|
||||
fixed: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
/** 图标。值为 `false` 表示不显示图标。不传表示使用默认图标 `'backtop'` */
|
||||
icon: {
|
||||
type: [String, Boolean, Object],
|
||||
default: true as TdBackTopProps['icon'],
|
||||
},
|
||||
/** 页面滚动距离 */
|
||||
scrollTop: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
/** 文案 */
|
||||
text: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
/** 预设的样式类型 */
|
||||
theme: {
|
||||
type: String,
|
||||
default: 'round' as TdBackTopProps['theme'],
|
||||
validator(val: TdBackTopProps['theme']): boolean {
|
||||
if (!val) return true;
|
||||
return ['round', 'half-round', 'round-dark', 'half-round-dark'].includes(val);
|
||||
},
|
||||
},
|
||||
/** 滚动高度达到此参数值才出现 */
|
||||
visibilityHeight: {
|
||||
type: Number,
|
||||
default: 200,
|
||||
},
|
||||
/** 点击触发 */
|
||||
onToTop: {
|
||||
type: Function,
|
||||
default: () => ({}),
|
||||
},
|
||||
};
|
||||
42
uni_modules/tdesign-uniapp/components/back-top/type.ts
Normal file
42
uni_modules/tdesign-uniapp/components/back-top/type.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
|
||||
* */
|
||||
|
||||
export interface TdBackTopProps {
|
||||
/**
|
||||
* 是否绝对定位固定到屏幕右下方
|
||||
* @default true
|
||||
*/
|
||||
fixed?: boolean;
|
||||
/**
|
||||
* 图标。值为 `false` 表示不显示图标。不传表示使用默认图标 `'backtop'`
|
||||
* @default true
|
||||
*/
|
||||
icon?: string | boolean | object;
|
||||
/**
|
||||
* 页面滚动距离
|
||||
* @default 0
|
||||
*/
|
||||
scrollTop?: number;
|
||||
/**
|
||||
* 文案
|
||||
* @default ''
|
||||
*/
|
||||
text?: string;
|
||||
/**
|
||||
* 预设的样式类型
|
||||
* @default round
|
||||
*/
|
||||
theme?: 'round' | 'half-round' | 'round-dark' | 'half-round-dark';
|
||||
/**
|
||||
* 滚动高度达到此参数值才出现
|
||||
* @default 200
|
||||
*/
|
||||
visibilityHeight?: number;
|
||||
/**
|
||||
* 点击触发
|
||||
*/
|
||||
onToTop?: () => void;
|
||||
}
|
||||
54
uni_modules/tdesign-uniapp/components/badge/README.en-US.md
Normal file
54
uni_modules/tdesign-uniapp/components/badge/README.en-US.md
Normal file
@@ -0,0 +1,54 @@
|
||||
:: BASE_DOC ::
|
||||
|
||||
## API
|
||||
|
||||
### Badge Props
|
||||
|
||||
name | type | default | description | required
|
||||
-- | -- | -- | -- | --
|
||||
custom-style | Object | - | CSS(Cascading Style Sheets) | N
|
||||
color | String | - | \- | N
|
||||
content | String | - | \- | N
|
||||
count | String / Number | 0 | \- | N
|
||||
dot | Boolean | false | \- | N
|
||||
max-count | Number | 99 | \- | N
|
||||
offset | Array | - | Typescript: `Array<string \| number>` | N
|
||||
shape | String | circle | options: circle/square/bubble/ribbon/ribbon-right/ribbon-left/triangle-right/triangle-left | N
|
||||
show-zero | Boolean | false | \- | N
|
||||
size | String | medium | options: medium/large | N
|
||||
|
||||
### Badge Slots
|
||||
|
||||
name | Description
|
||||
-- | --
|
||||
\- | \-
|
||||
count | \-
|
||||
|
||||
### Badge External Classes
|
||||
|
||||
className | Description
|
||||
-- | --
|
||||
t-class | \-
|
||||
t-class-content | \-
|
||||
t-class-count | \-
|
||||
|
||||
### CSS Variables
|
||||
|
||||
The component provides the following CSS variables, which can be used to customize styles.
|
||||
Name | Default Value | Description
|
||||
-- | -- | --
|
||||
--td-badge-basic-height | 32rpx | -
|
||||
--td-badge-basic-padding | 8rpx | -
|
||||
--td-badge-basic-width | 32rpx | -
|
||||
--td-badge-bg-color | @error-color | -
|
||||
--td-badge-border-radius | 4rpx | -
|
||||
--td-badge-bubble-border-radius | 20rpx 20rpx 20rpx 1px | -
|
||||
--td-badge-content-text-color | @text-color-primary | -
|
||||
--td-badge-dot-size | 16rpx | -
|
||||
--td-badge-font | @font-mark-extraSmall | -
|
||||
--td-badge-large-font | @font-mark-small | -
|
||||
--td-badge-large-height | 40rpx | -
|
||||
--td-badge-large-padding | 10rpx | -
|
||||
--td-badge-text-color | @text-color-anti | -
|
||||
--td-line-height-mark-extraSmall | 32rpx | -
|
||||
--td-line-height-mark-small | 40rpx | -
|
||||
85
uni_modules/tdesign-uniapp/components/badge/README.md
Normal file
85
uni_modules/tdesign-uniapp/components/badge/README.md
Normal file
@@ -0,0 +1,85 @@
|
||||
---
|
||||
title: Badge 徽标
|
||||
description: 用于告知用户,该区域的状态变化或者待处理任务的数量。
|
||||
spline: data
|
||||
isComponent: true
|
||||
---
|
||||
|
||||
|
||||
## 引入
|
||||
|
||||
可在 `main.ts` 或在需要使用的页面或组件中引入。
|
||||
|
||||
```js
|
||||
import TBadge from '@tdesign/uniapp/badge/badge.vue';
|
||||
```
|
||||
|
||||
### 组件类型
|
||||
|
||||
{{ base }}
|
||||
|
||||
### 组件样式
|
||||
|
||||
{{ theme }}
|
||||
|
||||
### 组件尺寸
|
||||
|
||||
{{ size }}
|
||||
|
||||
## FAQ
|
||||
|
||||
### 如何处理由 ribbon 徽标溢出导致页面出现横向滚动?
|
||||
角标溢出问题建议从父容器组件处理。如 <a href="https://github.com/Tencent/tdesign-miniprogram/issues/3063" title="如 #3063 " target="_blank" rel="noopener noreferrer"> #3063 </a>,可以给父容器 `cell` 组件添加 `overflow: hidden`,处理溢出造成页面出现横向滚动的问题。
|
||||
|
||||
## API
|
||||
|
||||
### Badge Props
|
||||
|
||||
名称 | 类型 | 默认值 | 描述 | 必传
|
||||
-- | -- | -- | -- | --
|
||||
custom-style | Object | - | 自定义样式 | N
|
||||
color | String | - | 颜色 | N
|
||||
content | String | - | 徽标内容,示例:`content='自定义内容'`。也可以使用默认插槽定义 | N
|
||||
count | String / Number | 0 | 徽标右上角内容。可以是数字,也可以是文字。如:'new'/3/99+。特殊:值为空表示使用插槽渲染 | N
|
||||
dot | Boolean | false | 是否为红点 | N
|
||||
max-count | Number | 99 | 封顶的数字值 | N
|
||||
offset | Array | - | 设置状态点的位置偏移,示例:[-10, 20] 或 ['10em', '8rem']。TS 类型:`Array<string \| number>` | N
|
||||
shape | String | circle | 徽标形状,其中 ribbon 和 ribbon-right 等效。可选项:circle/square/bubble/ribbon/ribbon-right/ribbon-left/triangle-right/triangle-left | N
|
||||
show-zero | Boolean | false | 当数值为 0 时,是否展示徽标 | N
|
||||
size | String | medium | 尺寸。可选项:medium/large | N
|
||||
|
||||
### Badge Slots
|
||||
|
||||
名称 | 描述
|
||||
-- | --
|
||||
\- | 默认插槽,自定义内容区域内容
|
||||
count | 徽标右上角内容
|
||||
|
||||
### Badge External Classes
|
||||
|
||||
类名 | 描述
|
||||
-- | --
|
||||
t-class | 根节点样式类
|
||||
t-class-content | 内容样式类
|
||||
t-class-count | 计数样式类
|
||||
|
||||
### CSS Variables
|
||||
|
||||
组件提供了下列 CSS 变量,可用于自定义样式。
|
||||
名称 | 默认值 | 描述
|
||||
-- | -- | --
|
||||
--td-badge-basic-height | 32rpx | -
|
||||
--td-badge-basic-padding | 8rpx | -
|
||||
--td-badge-basic-width | 32rpx | -
|
||||
--td-badge-bg-color | @error-color | -
|
||||
--td-badge-border-radius | 4rpx | -
|
||||
--td-badge-bubble-border-radius | 20rpx 20rpx 20rpx 1px | -
|
||||
--td-badge-content-text-color | @text-color-primary | -
|
||||
--td-badge-dot-size | 16rpx | -
|
||||
--td-badge-font | @font-mark-extraSmall | -
|
||||
--td-badge-large-font | @font-mark-small | -
|
||||
--td-badge-large-height | 40rpx | -
|
||||
--td-badge-large-padding | 10rpx | -
|
||||
--td-badge-text-color | @text-color-anti | -
|
||||
--td-line-height-mark-extraSmall | 32rpx | -
|
||||
--td-line-height-mark-small | 40rpx | -
|
||||
140
uni_modules/tdesign-uniapp/components/badge/badge.css
Normal file
140
uni_modules/tdesign-uniapp/components/badge/badge.css
Normal file
@@ -0,0 +1,140 @@
|
||||
.t-badge {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
align-items: start;
|
||||
}
|
||||
.t-badge--basic {
|
||||
z-index: 100;
|
||||
padding: 0 var(--td-badge-basic-padding, 8rpx);
|
||||
font: var(--td-badge-font, var(--td-font-mark-extraSmall, 600 20rpx / 32rpx var(--td-font-family, PingFang SC, Microsoft YaHei, Arial Regular)));
|
||||
color: var(--td-badge-text-color, var(--td-text-color-anti, var(--td-font-white-1, #ffffff)));
|
||||
background-color: var(--td-badge-bg-color, var(--td-error-color, var(--td-error-color-6, #d54941)));
|
||||
text-align: center;
|
||||
height: var(--td-badge-basic-height, 32rpx);
|
||||
border-radius: var(--td-badge-border-radius, 4rpx);
|
||||
}
|
||||
.t-badge--dot {
|
||||
height: var(--td-badge-dot-size, 16rpx);
|
||||
border-radius: 50%;
|
||||
min-width: var(--td-badge-dot-size, 16rpx);
|
||||
padding: 0;
|
||||
}
|
||||
.t-badge--count {
|
||||
min-width: var(--td-badge-basic-width, 32rpx);
|
||||
white-space: nowrap;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.t-badge--circle {
|
||||
border-radius: calc(var(--td-badge-basic-height, 32rpx) / 2);
|
||||
}
|
||||
.t-badge__ribbon-outer,
|
||||
.t-badge__ribbon-right-outer,
|
||||
.t-badge__triangle-right-outer,
|
||||
.t-badge__ribbon-left-outer,
|
||||
.t-badge__triangle-left-outer {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
.t-badge__ribbon-outer,
|
||||
.t-badge__ribbon-right-outer,
|
||||
.t-badge__triangle-right-outer {
|
||||
right: 0;
|
||||
}
|
||||
.t-badge__ribbon-left-outer,
|
||||
.t-badge__triangle-left-outer {
|
||||
left: 0;
|
||||
}
|
||||
.t-badge--bubble {
|
||||
border-radius: var(--td-badge-bubble-border-radius, 20rpx 20rpx 20rpx 1px);
|
||||
}
|
||||
.t-badge--ribbon,
|
||||
.t-badge--ribbon-right,
|
||||
.t-badge--ribbon-left,
|
||||
.t-badge--triangle-left,
|
||||
.t-badge--triangle-right {
|
||||
width: calc(var(--td-badge-basic-height, 32rpx) * 2);
|
||||
height: calc(var(--td-badge-basic-height, 32rpx) * 2);
|
||||
border-radius: 0;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
}
|
||||
.t-badge--ribbon,
|
||||
.t-badge--ribbon-right {
|
||||
background: linear-gradient(45deg, transparent 50%, var(--td-badge-bg-color, var(--td-error-color, var(--td-error-color-6, #d54941))) 50%, var(--td-badge-bg-color, var(--td-error-color, var(--td-error-color-6, #d54941))) 85%, transparent 85%);
|
||||
}
|
||||
.t-badge--triangle-right {
|
||||
background: linear-gradient(45deg, transparent 50%, var(--td-badge-bg-color, var(--td-error-color, var(--td-error-color-6, #d54941))) 50%);
|
||||
}
|
||||
.t-badge--ribbon,
|
||||
.t-badge--ribbon-right,
|
||||
.t-badge--triangle-right {
|
||||
right: 0;
|
||||
}
|
||||
.t-badge--ribbon .t-badge__count,
|
||||
.t-badge--ribbon-right .t-badge__count,
|
||||
.t-badge--triangle-right .t-badge__count {
|
||||
transform: rotate(45deg) translateY(calc(-1 * var(--td-line-height-mark-extraSmall, 32rpx) / 2 + 1rpx));
|
||||
}
|
||||
.t-badge--ribbon-left {
|
||||
background: linear-gradient(-45deg, transparent 50%, var(--td-badge-bg-color, var(--td-error-color, var(--td-error-color-6, #d54941))) 50%, var(--td-badge-bg-color, var(--td-error-color, var(--td-error-color-6, #d54941))) 85%, transparent 85%);
|
||||
}
|
||||
.t-badge--triangle-left {
|
||||
background: linear-gradient(-45deg, transparent 50%, var(--td-badge-bg-color, var(--td-error-color, var(--td-error-color-6, #d54941))) 50%);
|
||||
}
|
||||
.t-badge--ribbon-left,
|
||||
.t-badge--triangle-left {
|
||||
left: 0;
|
||||
}
|
||||
.t-badge--ribbon-left .t-badge__count,
|
||||
.t-badge--triangle-left .t-badge__count {
|
||||
transform: rotate(-45deg) translateY(calc(-1 * var(--td-line-height-mark-extraSmall, 32rpx) / 2 + 1rpx));
|
||||
}
|
||||
.t-badge--large {
|
||||
font: var(--td-badge-large-font, var(--td-font-mark-small, 600 24rpx / 40rpx var(--td-font-family, PingFang SC, Microsoft YaHei, Arial Regular)));
|
||||
height: var(--td-badge-large-height, 40rpx);
|
||||
min-width: var(--td-badge-large-height, 40rpx);
|
||||
padding: 0 var(--td-badge-large-padding, 10rpx);
|
||||
}
|
||||
.t-badge--large.t-badge--circle {
|
||||
border-radius: calc(var(--td-badge-large-height, 40rpx) / 2);
|
||||
}
|
||||
.t-badge--large.t-badge--ribbon,
|
||||
.t-badge--large.t-badge--ribbon-right,
|
||||
.t-badge--large.t-badge--ribbon-left,
|
||||
.t-badge--large.t-badge--triangle-right,
|
||||
.t-badge--large.t-badge--triangle-left {
|
||||
width: calc(var(--td-badge-large-height, 40rpx) * 2);
|
||||
height: calc(var(--td-badge-large-height, 40rpx) * 2);
|
||||
padding: 0;
|
||||
}
|
||||
.t-badge--large.t-badge--ribbon .t-badge__count,
|
||||
.t-badge--large.t-badge--ribbon-right .t-badge__count,
|
||||
.t-badge--large.t-badge--triangle-right .t-badge__count {
|
||||
transform: rotate(45deg) translateY(calc(-1 * var(--td-line-height-mark-small, 40rpx) / 2 + 3rpx));
|
||||
}
|
||||
.t-badge--large.t-badge--ribbon-left .t-badge__count,
|
||||
.t-badge--large.t-badge--triangle-left .t-badge__count {
|
||||
transform: rotate(-45deg) translateY(calc(-1 * var(--td-line-height-mark-small, 40rpx) / 2 + 3rpx));
|
||||
}
|
||||
.t-badge__content:not(:empty) + .t-badge--bubble.t-has-count,
|
||||
.t-badge__content:not(:empty) + .t-badge--circle.t-has-count,
|
||||
.t-badge__content:not(:empty) + .t-badge--square.t-has-count {
|
||||
transform-origin: center center;
|
||||
transform: translate(-50%, -50%);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 100%;
|
||||
}
|
||||
.t-badge__content-text {
|
||||
display: block;
|
||||
font: var(--td-font-body-large, 32rpx / 48rpx var(--td-font-family, PingFang SC, Microsoft YaHei, Arial Regular));
|
||||
color: var(--td-badge-content-text-color, var(--td-text-color-primary, var(--td-font-gray-1, rgba(0, 0, 0, 0.9))));
|
||||
}
|
||||
.t-badge__count:empty {
|
||||
display: none;
|
||||
}
|
||||
134
uni_modules/tdesign-uniapp/components/badge/badge.vue
Normal file
134
uni_modules/tdesign-uniapp/components/badge/badge.vue
Normal file
@@ -0,0 +1,134 @@
|
||||
<template>
|
||||
<view
|
||||
:style="tools._style([customStyle])"
|
||||
:class="classPrefix + ' ' + (useOuterClass ? classPrefix + '__' + shape + '-outer' : '') + tClass"
|
||||
:aria-labelledby="labelID"
|
||||
:aria-describedby="descriptionID"
|
||||
:aria-role="ariaRole || 'option'"
|
||||
>
|
||||
<view
|
||||
:id="labelID"
|
||||
:class="tools.cls(classPrefix + '__content', [['empty', !content && !hasChild]]) + ' ' + tClassContent"
|
||||
:aria-hidden="true"
|
||||
>
|
||||
<!-- #ifdef H5 -->
|
||||
|
||||
<slot
|
||||
v-if="!content"
|
||||
:class="classPrefix + '__content-slot'"
|
||||
/>
|
||||
<!-- #endif -->
|
||||
|
||||
<!-- 小程序下在 slot 下加 :class 属性,会导致渲染失败 -->
|
||||
<!-- #ifndef H5 -->
|
||||
<slot
|
||||
v-if="!content"
|
||||
/>
|
||||
<!-- #endif -->
|
||||
|
||||
<text
|
||||
v-else
|
||||
:class="classPrefix + '__content-text'"
|
||||
>
|
||||
{{ content }}
|
||||
</text>
|
||||
</view>
|
||||
<view
|
||||
v-if="isShowBadge({ dot, count, showZero }) || count === null"
|
||||
:id="descriptionID"
|
||||
:aria-hidden="true"
|
||||
:aria-label="ariaLabel || tools.getBadgeAriaLabel({ dot, count, maxCount })"
|
||||
:class="[
|
||||
getBadgeInnerClass({ classPrefix, dot, size, shape, count }) + ' ' + prefix + '-has-count ',
|
||||
tClassCount
|
||||
]"
|
||||
:style="tools._style([getBadgeStyles({ color, offset })])"
|
||||
>
|
||||
<view :class="classPrefix + '__count'">
|
||||
<template v-if="isShowBadge({ dot, count, showZero })">
|
||||
{{ getBadgeValue({ dot, count, maxCount }) }}
|
||||
</template>
|
||||
<slot
|
||||
else
|
||||
name="count"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import { uniComponent } from '../common/src/index';
|
||||
import { prefix } from '../common/config';
|
||||
import props from './props';
|
||||
import { uniqueFactory, getRect } from '../common/utils';
|
||||
import tools from '../common/utils.wxs';
|
||||
|
||||
import {
|
||||
getBadgeValue,
|
||||
getBadgeStyles,
|
||||
getBadgeInnerClass,
|
||||
isShowBadge,
|
||||
} from './computed.js';
|
||||
|
||||
|
||||
const name = `${prefix}-badge`;
|
||||
const getUniqueID = uniqueFactory('badge');
|
||||
|
||||
|
||||
export default uniComponent({
|
||||
name,
|
||||
options: {
|
||||
styleIsolation: 'shared',
|
||||
},
|
||||
externalClasses: [
|
||||
`${prefix}-class`,
|
||||
`${prefix}-class-count`,
|
||||
`${prefix}-class-content`,
|
||||
],
|
||||
props: {
|
||||
...props,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
prefix,
|
||||
classPrefix: name,
|
||||
value: '',
|
||||
labelID: '',
|
||||
descriptionID: '',
|
||||
tools,
|
||||
useOuterClass: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
hasChild() {
|
||||
return !!this.$slots?.default;
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
const e = getUniqueID();
|
||||
this.labelID = `${e}_label`;
|
||||
this.descriptionID = `${e}_description`;
|
||||
this.checkForActualContent();
|
||||
},
|
||||
methods: {
|
||||
getBadgeValue,
|
||||
getBadgeStyles,
|
||||
getBadgeInnerClass,
|
||||
isShowBadge,
|
||||
checkForActualContent() {
|
||||
const target = ['ribbon', 'ribbon-right', 'ribbon-left', 'triangle-right', 'triangle-left'];
|
||||
if (this.content || !target.includes(this.shape)) {
|
||||
this.useOuterClass = false;
|
||||
return;
|
||||
}
|
||||
return getRect(this, `.${name}__content`).then((rect) => {
|
||||
const hasSlotContent = rect.width > 0 || rect.height > 0;
|
||||
this.useOuterClass = !hasSlotContent;
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style scoped>
|
||||
@import './badge.css';
|
||||
</style>
|
||||
63
uni_modules/tdesign-uniapp/components/badge/computed.js
Normal file
63
uni_modules/tdesign-uniapp/components/badge/computed.js
Normal file
@@ -0,0 +1,63 @@
|
||||
export const getBadgeValue = function (props) {
|
||||
if (props.dot) {
|
||||
return '';
|
||||
}
|
||||
// eslint-disable-next-line no-restricted-globals
|
||||
if (isNaN(props.count) || isNaN(props.maxCount)) {
|
||||
return props.count;
|
||||
}
|
||||
return parseInt(props.count, 10) > props.maxCount ? `${props.maxCount}+` : props.count;
|
||||
};
|
||||
|
||||
export const hasUnit = function (unit) {
|
||||
return (
|
||||
unit.indexOf('px') > 0
|
||||
|| unit.indexOf('rpx') > 0
|
||||
|| unit.indexOf('em') > 0
|
||||
|| unit.indexOf('rem') > 0
|
||||
|| unit.indexOf('%') > 0
|
||||
|| unit.indexOf('vh') > 0
|
||||
|| unit.indexOf('vm') > 0
|
||||
);
|
||||
};
|
||||
|
||||
export const getBadgeStyles = function (props) {
|
||||
let styleStr = '';
|
||||
if (props.color) {
|
||||
styleStr += `background:${props.color};`;
|
||||
}
|
||||
if (props.offset?.[0]) {
|
||||
styleStr
|
||||
+= `left: calc(100% + ${hasUnit(props.offset[0].toString()) ? props.offset[0] : `${props.offset[0]}px`});`;
|
||||
}
|
||||
if (props.offset?.[1]) {
|
||||
styleStr += `top:${hasUnit(props.offset[1].toString()) ? props.offset[1] : `${props.offset[1]}px`};`;
|
||||
}
|
||||
return styleStr;
|
||||
};
|
||||
|
||||
|
||||
export const getBadgeInnerClass = function (props) {
|
||||
const baseClass = props.classPrefix;
|
||||
const classNames = [
|
||||
`${baseClass}--basic`,
|
||||
props.dot ? `${baseClass}--dot` : '',
|
||||
`${baseClass}--${props.size}`,
|
||||
`${baseClass}--${props.shape}`,
|
||||
!props.dot ? `${baseClass}--count` : '',
|
||||
];
|
||||
return classNames.join(' ');
|
||||
};
|
||||
|
||||
export const isShowBadge = function (props) {
|
||||
if (props.dot) {
|
||||
return true;
|
||||
}
|
||||
// eslint-disable-next-line no-restricted-globals
|
||||
if (!props.showZero && !isNaN(props.count) && parseInt(props.count, 10) === 0) {
|
||||
return false;
|
||||
}
|
||||
if (props.count == null) return false;
|
||||
return true;
|
||||
};
|
||||
|
||||
55
uni_modules/tdesign-uniapp/components/badge/props.ts
Normal file
55
uni_modules/tdesign-uniapp/components/badge/props.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
|
||||
* */
|
||||
|
||||
import type { TdBadgeProps } from './type';
|
||||
export default {
|
||||
/** 颜色 */
|
||||
color: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
/** 徽标内容,示例:`content='自定义内容'`。也可以使用默认插槽定义 */
|
||||
content: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
/** 徽标右上角内容。可以是数字,也可以是文字。如:'new'/3/99+。特殊:值为空表示使用插槽渲染 */
|
||||
count: {
|
||||
type: [String, Number],
|
||||
default: 0 as TdBadgeProps['count'],
|
||||
},
|
||||
/** 是否为红点 */
|
||||
dot: Boolean,
|
||||
/** 封顶的数字值 */
|
||||
maxCount: {
|
||||
type: Number,
|
||||
default: 99,
|
||||
},
|
||||
/** 设置状态点的位置偏移,示例:[-10, 20] 或 ['10em', '8rem'] */
|
||||
offset: {
|
||||
type: Array,
|
||||
},
|
||||
/** 徽标形状,其中 ribbon 和 ribbon-right 等效 */
|
||||
shape: {
|
||||
type: String,
|
||||
default: 'circle' as TdBadgeProps['shape'],
|
||||
validator(val: TdBadgeProps['shape']): boolean {
|
||||
if (!val) return true;
|
||||
return ['circle', 'square', 'bubble', 'ribbon', 'ribbon-right', 'ribbon-left', 'triangle-right', 'triangle-left'].includes(val);
|
||||
},
|
||||
},
|
||||
/** 当数值为 0 时,是否展示徽标 */
|
||||
showZero: Boolean,
|
||||
/** 尺寸 */
|
||||
size: {
|
||||
type: String,
|
||||
default: 'medium' as TdBadgeProps['size'],
|
||||
validator(val: TdBadgeProps['size']): boolean {
|
||||
if (!val) return true;
|
||||
return ['medium', 'large'].includes(val);
|
||||
},
|
||||
},
|
||||
};
|
||||
60
uni_modules/tdesign-uniapp/components/badge/type.ts
Normal file
60
uni_modules/tdesign-uniapp/components/badge/type.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
|
||||
* */
|
||||
|
||||
export interface TdBadgeProps {
|
||||
/**
|
||||
* 颜色
|
||||
* @default ''
|
||||
*/
|
||||
color?: string;
|
||||
/**
|
||||
* 徽标内容,示例:`content='自定义内容'`。也可以使用默认插槽定义
|
||||
* @default ''
|
||||
*/
|
||||
content?: string;
|
||||
/**
|
||||
* 徽标右上角内容。可以是数字,也可以是文字。如:'new'/3/99+。特殊:值为空表示使用插槽渲染
|
||||
* @default 0
|
||||
*/
|
||||
count?: string | number;
|
||||
/**
|
||||
* 是否为红点
|
||||
* @default false
|
||||
*/
|
||||
dot?: boolean;
|
||||
/**
|
||||
* 封顶的数字值
|
||||
* @default 99
|
||||
*/
|
||||
maxCount?: number;
|
||||
/**
|
||||
* 设置状态点的位置偏移,示例:[-10, 20] 或 ['10em', '8rem']
|
||||
*/
|
||||
offset?: Array<string | number>;
|
||||
/**
|
||||
* 徽标形状,其中 ribbon 和 ribbon-right 等效
|
||||
* @default circle
|
||||
*/
|
||||
shape?:
|
||||
| 'circle'
|
||||
| 'square'
|
||||
| 'bubble'
|
||||
| 'ribbon'
|
||||
| 'ribbon-right'
|
||||
| 'ribbon-left'
|
||||
| 'triangle-right'
|
||||
| 'triangle-left';
|
||||
/**
|
||||
* 当数值为 0 时,是否展示徽标
|
||||
* @default false
|
||||
*/
|
||||
showZero?: boolean;
|
||||
/**
|
||||
* 尺寸
|
||||
* @default medium
|
||||
*/
|
||||
size?: 'medium' | 'large';
|
||||
}
|
||||
238
uni_modules/tdesign-uniapp/components/button/README.en-US.md
Normal file
238
uni_modules/tdesign-uniapp/components/button/README.en-US.md
Normal file
@@ -0,0 +1,238 @@
|
||||
---
|
||||
title: Button
|
||||
description: Buttons are used to open a closed-loop task, such as "delete" an object, "buy" an item, etc.
|
||||
spline: base
|
||||
isComponent: true
|
||||
---
|
||||
|
||||
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
For global import, configure it in `app.json` in the root directory of the miniprogram. For local import, configure it in `index.json` of the page or component that needs to be imported.
|
||||
|
||||
```json
|
||||
"usingComponents": {
|
||||
"t-button": "tdesign-miniprogram/button/button"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Code Demo
|
||||
|
||||
### 01 Component Type
|
||||
|
||||
#### Basic Buttons
|
||||
|
||||
{{ base }}
|
||||
|
||||
#### Icon Button
|
||||
|
||||
{{ icon-btn }}
|
||||
|
||||
#### Ghost Button
|
||||
|
||||
{{ ghost-btn }}
|
||||
|
||||
#### Combination Button
|
||||
|
||||
{{ group-btn }}
|
||||
|
||||
#### Banner Button
|
||||
|
||||
{{ block-btn }}
|
||||
|
||||
### 02 Component State
|
||||
|
||||
#### Buttons for different states
|
||||
|
||||
{{ disabled }}
|
||||
|
||||
### 03 Component Style
|
||||
|
||||
#### Different sizes of buttons
|
||||
|
||||
{{ size }}
|
||||
|
||||
#### Different shaped buttons
|
||||
|
||||
{{ shape }}
|
||||
|
||||
#### Different color theme buttons
|
||||
|
||||
{{ theme }}
|
||||
|
||||
|
||||
|
||||
## API
|
||||
|
||||
### Button Props
|
||||
|
||||
name | type | default | description | required
|
||||
-- | -- | -- | -- | --
|
||||
custom-style | Object | - | CSS(Cascading Style Sheets) | N
|
||||
app-parameter | String | - | \- | N
|
||||
block | Boolean | false | make button to be a block-level element | N
|
||||
content | String | - | button's children elements | N
|
||||
custom-dataset | String / Number / Boolean / Object / Array | {} | Typescript:`string \| number \| boolean \| object \| Array<string \| number \| boolean \| object>` | N
|
||||
disabled | Boolean | undefined | disable the button, make it can not be clicked | N
|
||||
ghost | Boolean | false | make background-color to be transparent | N
|
||||
hover-class | String | - | \- | N
|
||||
hover-start-time | Number | 20 | \- | N
|
||||
hover-stay-time | Number | 70 | \- | N
|
||||
hover-stop-propagation | Boolean | false | \- | N
|
||||
icon | String / Object | - | icon name | N
|
||||
lang | String | - | message language。options: en/zh_CN/zh_TW | N
|
||||
loading | Boolean | false | set button to be loading state | N
|
||||
loading-props | Object | {} | Typescript:`LoadingProps`,[Loading API Documents](./loading?tab=api)。[see more ts definition](https://github.com/Tencent/tdesign-miniprogram/tree/develop/packages/uniapp-components/button/type.ts) | N
|
||||
open-type | String | - | open type of button, [Miniprogram Button](https://developers.weixin.qq.com/miniprogram/dev/component/button.html)。options: contact/share/getPhoneNumber/getUserInfo/launchApp/openSetting/feedback/chooseAvatar/agreePrivacyAuthorization | N
|
||||
phone-number-no-quota-toast | Boolean | true | \- | N
|
||||
send-message-img | String | 截图 | \- | N
|
||||
send-message-path | String | 当前分享路径 | \- | N
|
||||
send-message-title | String | 当前标题 | \- | N
|
||||
session-from | String | - | \- | N
|
||||
shape | String | rectangle | button shape。options: rectangle/square/round/circle | N
|
||||
show-message-card | Boolean | false | \- | N
|
||||
size | String | medium | a button has four size。options: extra-small/small/medium/large | N
|
||||
t-id | String | - | id | N
|
||||
theme | String | default | button theme。options: default/primary/danger/light | N
|
||||
type | String | - | type of button element, same as formType of Miniprogram。options: submit/reset | N
|
||||
variant | String | base | variant of button。options: base/outline/dashed/text | N
|
||||
|
||||
### Button Events
|
||||
|
||||
name | params | description
|
||||
-- | -- | --
|
||||
agreeprivacyauthorization | \- | \-
|
||||
chooseavatar | \- | \-
|
||||
click | `(e: MouseEvent)` | trigger on click
|
||||
contact | \- | \-
|
||||
createliveactivity | \- | \-
|
||||
error | \- | \-
|
||||
getphonenumber | \- | \-
|
||||
getrealtimephonenumber | \- | \-
|
||||
getuserinfo | \- | \-
|
||||
launchapp | \- | \-
|
||||
opensetting | \- | \-
|
||||
|
||||
### Button Slots
|
||||
|
||||
name | Description
|
||||
-- | --
|
||||
\- | \-
|
||||
content | button's children elements
|
||||
suffix | \-
|
||||
|
||||
### Button External Classes
|
||||
|
||||
className | Description
|
||||
-- | --
|
||||
t-class | \-
|
||||
t-class-icon | class name of icon
|
||||
t-class-loading | class name of loading
|
||||
|
||||
### CSS Variables
|
||||
|
||||
The component provides the following CSS variables, which can be used to customize styles.
|
||||
Name | Default Value | Description
|
||||
-- | -- | --
|
||||
--td-button-border-radius | @radius-default | -
|
||||
--td-button-border-width | 4rpx | -
|
||||
--td-button-danger-active-bg-color | @error-color-active | -
|
||||
--td-button-danger-active-border-color | @error-color-active | -
|
||||
--td-button-danger-bg-color | @error-color | -
|
||||
--td-button-danger-border-color | @error-color | -
|
||||
--td-button-danger-color | @text-color-anti | -
|
||||
--td-button-danger-dashed-border-color | @button-danger-dashed-color | -
|
||||
--td-button-danger-dashed-color | @error-color | -
|
||||
--td-button-danger-dashed-disabled-color | @button-danger-disabled-color | -
|
||||
--td-button-danger-disabled-bg | @error-color-3 | -
|
||||
--td-button-danger-disabled-border-color | @error-color-3 | -
|
||||
--td-button-danger-disabled-color | @font-white-1 | -
|
||||
--td-button-danger-outline-active-bg-color | @bg-color-container-active | -
|
||||
--td-button-danger-outline-active-border-color | @error-color-active | -
|
||||
--td-button-danger-outline-border-color | @button-danger-outline-color | -
|
||||
--td-button-danger-outline-color | @error-color | -
|
||||
--td-button-danger-outline-disabled-color | @error-color-3 | -
|
||||
--td-button-danger-text-active-bg-color | @bg-color-container-active | -
|
||||
--td-button-danger-text-color | @error-color | -
|
||||
--td-button-danger-text-disabled-color | @button-danger-disabled-color | -
|
||||
--td-button-default-active-bg-color | @bg-color-component-active | -
|
||||
--td-button-default-active-border-color | @bg-color-component-active | -
|
||||
--td-button-default-bg-color | @bg-color-component | -
|
||||
--td-button-default-border-color | @bg-color-component | -
|
||||
--td-button-default-color | @text-color-primary | -
|
||||
--td-button-default-disabled-bg | @bg-color-component-disabled | -
|
||||
--td-button-default-disabled-border-color | @bg-color-component-disabled | -
|
||||
--td-button-default-disabled-color | @text-color-disabled | -
|
||||
--td-button-default-outline-active-bg-color | @bg-color-container-active | -
|
||||
--td-button-default-outline-active-border-color | @component-border | -
|
||||
--td-button-default-outline-border-color | @component-border | -
|
||||
--td-button-default-outline-color | @text-color-primary | -
|
||||
--td-button-default-outline-disabled-color | @component-border | -
|
||||
--td-button-default-text-active-bg-color | @bg-color-container-active | -
|
||||
--td-button-extra-small-font-size | @font-size-base | -
|
||||
--td-button-extra-small-height | 56rpx | -
|
||||
--td-button-extra-small-icon-size | 36rpx | -
|
||||
--td-button-extra-small-padding-horizontal | 16rpx | -
|
||||
--td-button-font-weight | 600 | -
|
||||
--td-button-ghost-border-color | @button-ghost-color | -
|
||||
--td-button-ghost-color | @text-color-anti | -
|
||||
--td-button-ghost-danger-border-color | @error-color | -
|
||||
--td-button-ghost-danger-color | @error-color | -
|
||||
--td-button-ghost-danger-hover-color | @error-color-active | -
|
||||
--td-button-ghost-disabled-color | @font-white-4 | -
|
||||
--td-button-ghost-hover-color | @font-white-2 | -
|
||||
--td-button-ghost-primary-border-color | @brand-color | -
|
||||
--td-button-ghost-primary-color | @brand-color | -
|
||||
--td-button-ghost-primary-hover-color | @brand-color-active | -
|
||||
--td-button-icon-border-radius | 8rpx | -
|
||||
--td-button-icon-spacer | @spacer | -
|
||||
--td-button-large-font-size | @font-size-m | -
|
||||
--td-button-large-height | 96rpx | -
|
||||
--td-button-large-icon-size | 48rpx | -
|
||||
--td-button-large-padding-horizontal | 40rpx | -
|
||||
--td-button-light-active-bg-color | @brand-color-light-active | -
|
||||
--td-button-light-active-border-color | @brand-color-light-active | -
|
||||
--td-button-light-bg-color | @brand-color-light | -
|
||||
--td-button-light-border-color | @brand-color-light | -
|
||||
--td-button-light-color | @brand-color | -
|
||||
--td-button-light-disabled-bg | @brand-color-light | -
|
||||
--td-button-light-disabled-border-color | @brand-color-light | -
|
||||
--td-button-light-disabled-color | @brand-color-disabled | -
|
||||
--td-button-light-outline-active-bg-color | @brand-color-light-active | -
|
||||
--td-button-light-outline-active-border-color | @brand-color-active | -
|
||||
--td-button-light-outline-bg-color | @brand-color-light | -
|
||||
--td-button-light-outline-border-color | @button-light-outline-color | -
|
||||
--td-button-light-outline-color | @brand-color | -
|
||||
--td-button-light-outline-disabled-color | @brand-color-disabled | -
|
||||
--td-button-light-text-active-bg-color | @bg-color-container-active | -
|
||||
--td-button-light-text-color | @brand-color | -
|
||||
--td-button-medium-font-size | @font-size-m | -
|
||||
--td-button-medium-height | 80rpx | -
|
||||
--td-button-medium-icon-size | 40rpx | -
|
||||
--td-button-medium-padding-horizontal | 32rpx | -
|
||||
--td-button-primary-active-bg-color | @brand-color-active | -
|
||||
--td-button-primary-active-border-color | @brand-color-active | -
|
||||
--td-button-primary-bg-color | @brand-color | -
|
||||
--td-button-primary-border-color | @brand-color | -
|
||||
--td-button-primary-color | @text-color-anti | -
|
||||
--td-button-primary-dashed-border-color | @button-primary-dashed-color | -
|
||||
--td-button-primary-dashed-color | @brand-color | -
|
||||
--td-button-primary-dashed-disabled-color | @brand-color-disabled | -
|
||||
--td-button-primary-disabled-bg | @brand-color-disabled | -
|
||||
--td-button-primary-disabled-border-color | @brand-color-disabled | -
|
||||
--td-button-primary-disabled-color | @text-color-anti | -
|
||||
--td-button-primary-outline-active-bg-color | @bg-color-container-active | -
|
||||
--td-button-primary-outline-active-border-color | @brand-color-active | -
|
||||
--td-button-primary-outline-border-color | @button-primary-outline-color | -
|
||||
--td-button-primary-outline-color | @brand-color | -
|
||||
--td-button-primary-outline-disabled-color | @brand-color-disabled | -
|
||||
--td-button-primary-text-active-bg-color | @bg-color-container-active | -
|
||||
--td-button-primary-text-color | @brand-color | -
|
||||
--td-button-primary-text-disabled-color | @brand-color-disabled | -
|
||||
--td-button-small-font-size | @font-size-base | -
|
||||
--td-button-small-height | 64rpx | -
|
||||
--td-button-small-icon-size | 36rpx | -
|
||||
--td-button-small-padding-horizontal | 24rpx | -
|
||||
229
uni_modules/tdesign-uniapp/components/button/README.md
Normal file
229
uni_modules/tdesign-uniapp/components/button/README.md
Normal file
@@ -0,0 +1,229 @@
|
||||
---
|
||||
title: Button 按钮
|
||||
description: 用于开启一个闭环的操作任务,如“删除”对象、“购买”商品等。
|
||||
spline: base
|
||||
isComponent: true
|
||||
---
|
||||
|
||||
|
||||
## 引入
|
||||
|
||||
可在 `main.ts` 或在需要使用的页面或组件中引入。
|
||||
|
||||
```js
|
||||
import TButton from '@tdesign/uniapp/button/button.vue';
|
||||
```
|
||||
|
||||
### 01 组件类型
|
||||
|
||||
#### 基础按钮
|
||||
|
||||
{{ base }}
|
||||
|
||||
#### 图标按钮
|
||||
|
||||
{{ icon-btn }}
|
||||
|
||||
#### 幽灵按钮
|
||||
|
||||
{{ ghost-btn }}
|
||||
|
||||
#### 组合按钮
|
||||
|
||||
{{ group-btn }}
|
||||
|
||||
#### 通栏按钮
|
||||
|
||||
{{ block-btn }}
|
||||
|
||||
### 02 组件状态
|
||||
|
||||
#### 按钮禁用态
|
||||
|
||||
{{ disabled }}
|
||||
|
||||
### 03 组件样式
|
||||
|
||||
#### 按钮尺寸
|
||||
|
||||
{{ size }}
|
||||
|
||||
#### 按钮形状
|
||||
|
||||
{{ shape }}
|
||||
|
||||
#### 按钮主题
|
||||
|
||||
{{ theme }}
|
||||
|
||||
## API
|
||||
|
||||
### Button Props
|
||||
|
||||
名称 | 类型 | 默认值 | 描述 | 必传
|
||||
-- | -- | -- | -- | --
|
||||
custom-style | Object | - | 自定义样式 | N
|
||||
app-parameter | String | - | 打开 APP 时,向 APP 传递的参数,open-type=launchApp时有效 | N
|
||||
block | Boolean | false | 是否为块级元素 | N
|
||||
content | String | - | 按钮内容 | N
|
||||
custom-dataset | String / Number / Boolean / Object / Array | {} | 自定义 dataset,可通过 event.currentTarget.dataset.custom 获取。TS 类型:`string \| number \| boolean \| object \| Array<string \| number \| boolean \| object>` | N
|
||||
disabled | Boolean | undefined | 禁用状态。优先级:Button.disabled > Form.disabled | N
|
||||
ghost | Boolean | false | 是否为幽灵按钮(镂空按钮) | N
|
||||
hover-class | String | - | 指定按钮按下去的样式类,按钮不为加载或禁用状态时有效。当 `hover-class="none"` 时,没有点击态效果 | N
|
||||
hover-start-time | Number | 20 | 按住后多久出现点击态,单位毫秒 | N
|
||||
hover-stay-time | Number | 70 | 手指松开后点击态保留时间,单位毫秒 | N
|
||||
hover-stop-propagation | Boolean | false | 指定是否阻止本节点的祖先节点出现点击态 | N
|
||||
icon | String / Object | - | 图标名称。值为字符串表示图标名称,值为 `Object` 类型,表示透传至 `icon` | N
|
||||
lang | String | - | 指定返回用户信息的语言,zh_CN 简体中文,zh_TW 繁体中文,en 英文。<br />具体释义:<br />`en` 英文;<br />`zh_CN` 简体中文;<br />`zh_TW` 繁体中文。<br />[小程序官方文档](https://developers.weixin.qq.com/miniprogram/dev/component/button.html)。可选项:en/zh_CN/zh_TW | N
|
||||
loading | Boolean | false | 是否显示为加载状态 | N
|
||||
loading-props | Object | {} | 透传 Loading 组件全部属性。TS 类型:`LoadingProps`,[Loading API Documents](./loading?tab=api)。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/packages/uniapp-components/button/type.ts) | N
|
||||
open-type | String | - | 微信开放能力。<br />具体释义:<br />`contact` 打开客服会话,如果用户在会话中点击消息卡片后返回小程序,可以从 bindcontact 回调中获得具体信息,<a href="https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/customer-message/customer-message.html">具体说明</a> (*鸿蒙 OS 暂不支持*);<br />`liveActivity` 通过前端获取<a href="https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/subscribe-message-2.html">新的一次性订阅消息下发机制</a>使用的 code;<br />`share` 触发用户转发,使用前建议先阅读<a href="https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/share.html#使用指引">使用指引</a>;<br />`getPhoneNumber` 获取用户手机号,可以从 bindgetphonenumber 回调中获取到用户信息,<a href="https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/getPhoneNumber.html">具体说明</a> (*小程序插件中不能使用*);<br />`getUserInfo` 获取用户信息,可以从 bindgetuserinfo 回调中获取到用户信息 (*小程序插件中不能使用*);<br />`launchApp` 打开APP,可以通过 app-parameter 属性设定向 APP 传的参数<a href="https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/launchApp.html">具体说明</a>;<br />`openSetting` 打开授权设置页;<br />`feedback` 打开“意见反馈”页面,用户可提交反馈内容并上传<a href="https://developers.weixin.qq.com/miniprogram/dev/api/base/debug/wx.getLogManager.html">日志</a>,开发者可以登录<a href="https://mp.weixin.qq.com/">小程序管理后台</a>后进入左侧菜单“客服反馈”页面获取到反馈内容;<br />`chooseAvatar` 获取用户头像,可以从 bindchooseavatar 回调中获取到头像信息;<br />`agreePrivacyAuthorization`用户同意隐私协议按钮。用户点击一次此按钮后,所有隐私接口可以正常调用。可通过`bindagreeprivacyauthorization`监听用户同意隐私协议事件。隐私合规开发指南详情可见《<a href="https://developers.weixin.qq.com/miniprogram/dev/framework/user-privacy/PrivacyAuthorize.html">小程序隐私协议开发指南</a>》。<br />[小程序官方文档](https://developers.weixin.qq.com/miniprogram/dev/component/button.html)。可选项:contact/share/getPhoneNumber/getUserInfo/launchApp/openSetting/feedback/chooseAvatar/agreePrivacyAuthorization | N
|
||||
phone-number-no-quota-toast | Boolean | true | 原生按钮属性,当手机号快速验证或手机号实时验证额度用尽时,是否对用户展示“申请获取你的手机号,但该功能使用次数已达当前小程序上限,暂时无法使用”的提示,默认展示,open-type="getPhoneNumber" 或 open-type="getRealtimePhoneNumber" 时有效 | N
|
||||
send-message-img | String | 截图 | 会话内消息卡片图片,open-type="contact"时有效 | N
|
||||
send-message-path | String | 当前分享路径 | 会话内消息卡片点击跳转小程序路径,open-type="contact"时有效 | N
|
||||
send-message-title | String | 当前标题 | 会话内消息卡片标题,open-type="contact"时有效 | N
|
||||
session-from | String | - | 会话来源,open-type="contact"时有效 | N
|
||||
shape | String | rectangle | 按钮形状,有 4 种:长方形、正方形、圆角长方形、圆形。可选项:rectangle/square/round/circle | N
|
||||
show-message-card | Boolean | false | 是否显示会话内消息卡片,设置此参数为 true,用户进入客服会话会在右下角显示"可能要发送的小程序"提示,用户点击后可以快速发送小程序消息,open-type="contact"时有效 | N
|
||||
size | String | medium | 组件尺寸。可选项:extra-small/small/medium/large | N
|
||||
t-id | String | - | 按钮标签id | N
|
||||
theme | String | default | 组件风格,依次为品牌色、危险色。可选项:default/primary/danger/light | N
|
||||
type | String | - | 同小程序的 formType。可选项:submit/reset | N
|
||||
variant | String | base | 按钮形式,基础、线框、虚线、文字。可选项:base/outline/dashed/text | N
|
||||
|
||||
### Button Events
|
||||
|
||||
名称 | 参数 | 描述
|
||||
-- | -- | --
|
||||
agreeprivacyauthorization | \- | 原生按钮属性,用户同意隐私协议事件回调,open-type=agreePrivacyAuthorization时有效 (Tips: 如果使用 onNeedPrivacyAuthorization 接口,需要在 bindagreeprivacyauthorization 触发后再调用 resolve({ event: "agree", buttonId }))
|
||||
chooseavatar | \- | 原生按钮属性,获取用户头像回调,`open-type=chooseAvatar` 时有效。返回 `e.detail.avatarUrl` 为头像临时文件链接
|
||||
click | `(e: MouseEvent)` | 点击时触发
|
||||
contact | \- | 原生按钮属性,客服消息回调,`open-type="contact"` 时有效
|
||||
createliveactivity | \- | 新的一次性订阅消息下发机制回调,`open-type=liveActivity` 时有效
|
||||
error | \- | 原生按钮属性,当使用开放能力时,发生错误的回调,`open-type=launchApp` 时有效
|
||||
getphonenumber | \- | 原生按钮属性,手机号快速验证回调,open-type=getPhoneNumber时有效。Tips:在触发 bindgetphonenumber 回调后应立即隐藏手机号按钮组件,或置为 disabled 状态,避免用户重复授权手机号产生额外费用
|
||||
getrealtimephonenumber | \- | 原生按钮属性,手机号实时验证回调,open-type=getRealtimePhoneNumber 时有效。Tips:在触发 bindgetrealtimephonenumber 回调后应立即隐藏手机号按钮组件,或置为 disabled 状态,避免用户重复授权手机号产生额外费用
|
||||
getuserinfo | \- | 原生按钮属性,用户点击该按钮时,会返回获取到的用户信息,回调的detail数据与wx.getUserInfo返回的一致,open-type="getUserInfo"时有效
|
||||
launchapp | \- | 打开 APP 成功的回调,`open-type=launchApp` 时有效
|
||||
opensetting | \- | 原生按钮属性,在打开授权设置页后回调,open-type=openSetting时有效
|
||||
|
||||
### Button Slots
|
||||
|
||||
名称 | 描述
|
||||
-- | --
|
||||
\- | 默认插槽,作用同 `content` 插槽
|
||||
content | 自定义 `content` 显示内容
|
||||
suffix | 右侧内容,可用于定义右侧图标
|
||||
|
||||
### Button External Classes
|
||||
|
||||
类名 | 描述
|
||||
-- | --
|
||||
t-class | 根节点样式类
|
||||
t-class-icon | 图标样式类
|
||||
t-class-loading | 加载样式类
|
||||
|
||||
### CSS Variables
|
||||
|
||||
组件提供了下列 CSS 变量,可用于自定义样式。
|
||||
名称 | 默认值 | 描述
|
||||
-- | -- | --
|
||||
--td-button-border-radius | @radius-default | -
|
||||
--td-button-border-width | 4rpx | -
|
||||
--td-button-danger-active-bg-color | @error-color-active | -
|
||||
--td-button-danger-active-border-color | @error-color-active | -
|
||||
--td-button-danger-bg-color | @error-color | -
|
||||
--td-button-danger-border-color | @error-color | -
|
||||
--td-button-danger-color | @text-color-anti | -
|
||||
--td-button-danger-dashed-border-color | @button-danger-dashed-color | -
|
||||
--td-button-danger-dashed-color | @error-color | -
|
||||
--td-button-danger-dashed-disabled-color | @button-danger-disabled-color | -
|
||||
--td-button-danger-disabled-bg | @error-color-3 | -
|
||||
--td-button-danger-disabled-border-color | @error-color-3 | -
|
||||
--td-button-danger-disabled-color | @font-white-1 | -
|
||||
--td-button-danger-outline-active-bg-color | @bg-color-container-active | -
|
||||
--td-button-danger-outline-active-border-color | @error-color-active | -
|
||||
--td-button-danger-outline-border-color | @button-danger-outline-color | -
|
||||
--td-button-danger-outline-color | @error-color | -
|
||||
--td-button-danger-outline-disabled-color | @error-color-3 | -
|
||||
--td-button-danger-text-active-bg-color | @bg-color-container-active | -
|
||||
--td-button-danger-text-color | @error-color | -
|
||||
--td-button-danger-text-disabled-color | @button-danger-disabled-color | -
|
||||
--td-button-default-active-bg-color | @bg-color-component-active | -
|
||||
--td-button-default-active-border-color | @bg-color-component-active | -
|
||||
--td-button-default-bg-color | @bg-color-component | -
|
||||
--td-button-default-border-color | @bg-color-component | -
|
||||
--td-button-default-color | @text-color-primary | -
|
||||
--td-button-default-disabled-bg | @bg-color-component-disabled | -
|
||||
--td-button-default-disabled-border-color | @bg-color-component-disabled | -
|
||||
--td-button-default-disabled-color | @text-color-disabled | -
|
||||
--td-button-default-outline-active-bg-color | @bg-color-container-active | -
|
||||
--td-button-default-outline-active-border-color | @component-border | -
|
||||
--td-button-default-outline-border-color | @component-border | -
|
||||
--td-button-default-outline-color | @text-color-primary | -
|
||||
--td-button-default-outline-disabled-color | @component-border | -
|
||||
--td-button-default-text-active-bg-color | @bg-color-container-active | -
|
||||
--td-button-extra-small-font-size | @font-size-base | -
|
||||
--td-button-extra-small-height | 56rpx | -
|
||||
--td-button-extra-small-icon-size | 36rpx | -
|
||||
--td-button-extra-small-padding-horizontal | 16rpx | -
|
||||
--td-button-font-weight | 600 | -
|
||||
--td-button-ghost-border-color | @button-ghost-color | -
|
||||
--td-button-ghost-color | @text-color-anti | -
|
||||
--td-button-ghost-danger-border-color | @error-color | -
|
||||
--td-button-ghost-danger-color | @error-color | -
|
||||
--td-button-ghost-danger-hover-color | @error-color-active | -
|
||||
--td-button-ghost-disabled-color | @font-white-4 | -
|
||||
--td-button-ghost-hover-color | @font-white-2 | -
|
||||
--td-button-ghost-primary-border-color | @brand-color | -
|
||||
--td-button-ghost-primary-color | @brand-color | -
|
||||
--td-button-ghost-primary-hover-color | @brand-color-active | -
|
||||
--td-button-icon-border-radius | 8rpx | -
|
||||
--td-button-icon-spacer | @spacer | -
|
||||
--td-button-large-font-size | @font-size-m | -
|
||||
--td-button-large-height | 96rpx | -
|
||||
--td-button-large-icon-size | 48rpx | -
|
||||
--td-button-large-padding-horizontal | 40rpx | -
|
||||
--td-button-light-active-bg-color | @brand-color-light-active | -
|
||||
--td-button-light-active-border-color | @brand-color-light-active | -
|
||||
--td-button-light-bg-color | @brand-color-light | -
|
||||
--td-button-light-border-color | @brand-color-light | -
|
||||
--td-button-light-color | @brand-color | -
|
||||
--td-button-light-disabled-bg | @brand-color-light | -
|
||||
--td-button-light-disabled-border-color | @brand-color-light | -
|
||||
--td-button-light-disabled-color | @brand-color-disabled | -
|
||||
--td-button-light-outline-active-bg-color | @brand-color-light-active | -
|
||||
--td-button-light-outline-active-border-color | @brand-color-active | -
|
||||
--td-button-light-outline-bg-color | @brand-color-light | -
|
||||
--td-button-light-outline-border-color | @button-light-outline-color | -
|
||||
--td-button-light-outline-color | @brand-color | -
|
||||
--td-button-light-outline-disabled-color | @brand-color-disabled | -
|
||||
--td-button-light-text-active-bg-color | @bg-color-container-active | -
|
||||
--td-button-light-text-color | @brand-color | -
|
||||
--td-button-medium-font-size | @font-size-m | -
|
||||
--td-button-medium-height | 80rpx | -
|
||||
--td-button-medium-icon-size | 40rpx | -
|
||||
--td-button-medium-padding-horizontal | 32rpx | -
|
||||
--td-button-primary-active-bg-color | @brand-color-active | -
|
||||
--td-button-primary-active-border-color | @brand-color-active | -
|
||||
--td-button-primary-bg-color | @brand-color | -
|
||||
--td-button-primary-border-color | @brand-color | -
|
||||
--td-button-primary-color | @text-color-anti | -
|
||||
--td-button-primary-dashed-border-color | @button-primary-dashed-color | -
|
||||
--td-button-primary-dashed-color | @brand-color | -
|
||||
--td-button-primary-dashed-disabled-color | @brand-color-disabled | -
|
||||
--td-button-primary-disabled-bg | @brand-color-disabled | -
|
||||
--td-button-primary-disabled-border-color | @brand-color-disabled | -
|
||||
--td-button-primary-disabled-color | @text-color-anti | -
|
||||
--td-button-primary-outline-active-bg-color | @bg-color-container-active | -
|
||||
--td-button-primary-outline-active-border-color | @brand-color-active | -
|
||||
--td-button-primary-outline-border-color | @button-primary-outline-color | -
|
||||
--td-button-primary-outline-color | @brand-color | -
|
||||
--td-button-primary-outline-disabled-color | @brand-color-disabled | -
|
||||
--td-button-primary-text-active-bg-color | @bg-color-container-active | -
|
||||
--td-button-primary-text-color | @brand-color | -
|
||||
--td-button-primary-text-disabled-color | @brand-color-disabled | -
|
||||
--td-button-small-font-size | @font-size-base | -
|
||||
--td-button-small-height | 64rpx | -
|
||||
--td-button-small-icon-size | 36rpx | -
|
||||
--td-button-small-padding-horizontal | 24rpx | -
|
||||
514
uni_modules/tdesign-uniapp/components/button/button.css
Normal file
514
uni_modules/tdesign-uniapp/components/button/button.css
Normal file
@@ -0,0 +1,514 @@
|
||||
.t-button--size-extra-small {
|
||||
font-size: var(--td-button-extra-small-font-size, var(--td-font-size-base, 28rpx));
|
||||
padding-left: var(--td-button-extra-small-padding-horizontal, 16rpx);
|
||||
padding-right: var(--td-button-extra-small-padding-horizontal, 16rpx);
|
||||
height: var(--td-button-extra-small-height, 56rpx);
|
||||
line-height: var(--td-button-extra-small-height, 56rpx);
|
||||
}
|
||||
.t-button--size-extra-small .t-button__icon {
|
||||
font-size: var(--td-button-extra-small-icon-size, 36rpx);
|
||||
}
|
||||
.t-button--size-small {
|
||||
font-size: var(--td-button-small-font-size, var(--td-font-size-base, 28rpx));
|
||||
padding-left: var(--td-button-small-padding-horizontal, 24rpx);
|
||||
padding-right: var(--td-button-small-padding-horizontal, 24rpx);
|
||||
height: var(--td-button-small-height, 64rpx);
|
||||
line-height: var(--td-button-small-height, 64rpx);
|
||||
}
|
||||
.t-button--size-small .t-button__icon {
|
||||
font-size: var(--td-button-small-icon-size, 36rpx);
|
||||
}
|
||||
.t-button--size-medium {
|
||||
font-size: var(--td-button-medium-font-size, var(--td-font-size-m, 32rpx));
|
||||
padding-left: var(--td-button-medium-padding-horizontal, 32rpx);
|
||||
padding-right: var(--td-button-medium-padding-horizontal, 32rpx);
|
||||
height: var(--td-button-medium-height, 80rpx);
|
||||
line-height: var(--td-button-medium-height, 80rpx);
|
||||
}
|
||||
.t-button--size-medium .t-button__icon {
|
||||
font-size: var(--td-button-medium-icon-size, 40rpx);
|
||||
}
|
||||
.t-button--size-large {
|
||||
font-size: var(--td-button-large-font-size, var(--td-font-size-m, 32rpx));
|
||||
padding-left: var(--td-button-large-padding-horizontal, 40rpx);
|
||||
padding-right: var(--td-button-large-padding-horizontal, 40rpx);
|
||||
height: var(--td-button-large-height, 96rpx);
|
||||
line-height: var(--td-button-large-height, 96rpx);
|
||||
}
|
||||
.t-button--size-large .t-button__icon {
|
||||
font-size: var(--td-button-large-icon-size, 48rpx);
|
||||
}
|
||||
.t-button--default {
|
||||
color: var(--td-button-default-color, var(--td-text-color-primary, var(--td-font-gray-1, rgba(0, 0, 0, 0.9))));
|
||||
background-color: var(--td-button-default-bg-color, var(--td-bg-color-component, var(--td-gray-color-3, #e7e7e7)));
|
||||
border-color: var(--td-button-default-border-color, var(--td-bg-color-component, var(--td-gray-color-3, #e7e7e7)));
|
||||
}
|
||||
.t-button--default::after {
|
||||
border-width: var(--td-button-border-width, 4rpx);
|
||||
border-color: var(--td-button-default-border-color, var(--td-bg-color-component, var(--td-gray-color-3, #e7e7e7)));
|
||||
}
|
||||
.t-button--default.t-button--hover {
|
||||
z-index: 0;
|
||||
}
|
||||
.t-button--default.t-button--hover,
|
||||
.t-button--default.t-button--hover::after {
|
||||
background-color: var(--td-button-default-active-bg-color, var(--td-bg-color-component-active, var(--td-gray-color-6, #a6a6a6)));
|
||||
border-color: var(--td-button-default-active-border-color, var(--td-bg-color-component-active, var(--td-gray-color-6, #a6a6a6)));
|
||||
}
|
||||
.t-button--default.t-button--disabled {
|
||||
color: var(--td-button-default-disabled-color, var(--td-text-color-disabled, var(--td-font-gray-4, rgba(0, 0, 0, 0.26))));
|
||||
background-color: var(--td-button-default-disabled-bg, var(--td-bg-color-component-disabled, var(--td-gray-color-2, #eeeeee)));
|
||||
}
|
||||
.t-button--default.t-button--disabled,
|
||||
.t-button--default.t-button--disabled::after {
|
||||
border-color: var(--td-button-default-disabled-border-color, var(--td-bg-color-component-disabled, var(--td-gray-color-2, #eeeeee)));
|
||||
}
|
||||
.t-button--primary {
|
||||
color: var(--td-button-primary-color, var(--td-text-color-anti, var(--td-font-white-1, #ffffff)));
|
||||
background-color: var(--td-button-primary-bg-color, var(--td-brand-color, var(--td-primary-color-7, #0052d9)));
|
||||
border-color: var(--td-button-primary-border-color, var(--td-brand-color, var(--td-primary-color-7, #0052d9)));
|
||||
}
|
||||
.t-button--primary::after {
|
||||
border-width: var(--td-button-border-width, 4rpx);
|
||||
border-color: var(--td-button-primary-border-color, var(--td-brand-color, var(--td-primary-color-7, #0052d9)));
|
||||
}
|
||||
.t-button--primary.t-button--hover {
|
||||
z-index: 0;
|
||||
}
|
||||
.t-button--primary.t-button--hover,
|
||||
.t-button--primary.t-button--hover::after {
|
||||
background-color: var(--td-button-primary-active-bg-color, var(--td-brand-color-active, var(--td-primary-color-8, #003cab)));
|
||||
border-color: var(--td-button-primary-active-border-color, var(--td-brand-color-active, var(--td-primary-color-8, #003cab)));
|
||||
}
|
||||
.t-button--primary.t-button--disabled {
|
||||
color: var(--td-button-primary-disabled-color, var(--td-text-color-anti, var(--td-font-white-1, #ffffff)));
|
||||
background-color: var(--td-button-primary-disabled-bg, var(--td-brand-color-disabled, var(--td-primary-color-3, #b5c7ff)));
|
||||
}
|
||||
.t-button--primary.t-button--disabled,
|
||||
.t-button--primary.t-button--disabled::after {
|
||||
border-color: var(--td-button-primary-disabled-border-color, var(--td-brand-color-disabled, var(--td-primary-color-3, #b5c7ff)));
|
||||
}
|
||||
.t-button--light {
|
||||
color: var(--td-button-light-color, var(--td-brand-color, var(--td-primary-color-7, #0052d9)));
|
||||
background-color: var(--td-button-light-bg-color, var(--td-brand-color-light, var(--td-primary-color-1, #f2f3ff)));
|
||||
border-color: var(--td-button-light-border-color, var(--td-brand-color-light, var(--td-primary-color-1, #f2f3ff)));
|
||||
}
|
||||
.t-button--light::after {
|
||||
border-width: var(--td-button-border-width, 4rpx);
|
||||
border-color: var(--td-button-light-border-color, var(--td-brand-color-light, var(--td-primary-color-1, #f2f3ff)));
|
||||
}
|
||||
.t-button--light.t-button--hover {
|
||||
z-index: 0;
|
||||
}
|
||||
.t-button--light.t-button--hover,
|
||||
.t-button--light.t-button--hover::after {
|
||||
background-color: var(--td-button-light-active-bg-color, var(--td-brand-color-light-active, var(--td-primary-color-2, #d9e1ff)));
|
||||
border-color: var(--td-button-light-active-border-color, var(--td-brand-color-light-active, var(--td-primary-color-2, #d9e1ff)));
|
||||
}
|
||||
.t-button--light.t-button--disabled {
|
||||
color: var(--td-button-light-disabled-color, var(--td-brand-color-disabled, var(--td-primary-color-3, #b5c7ff)));
|
||||
background-color: var(--td-button-light-disabled-bg, var(--td-brand-color-light, var(--td-primary-color-1, #f2f3ff)));
|
||||
}
|
||||
.t-button--light.t-button--disabled,
|
||||
.t-button--light.t-button--disabled::after {
|
||||
border-color: var(--td-button-light-disabled-border-color, var(--td-brand-color-light, var(--td-primary-color-1, #f2f3ff)));
|
||||
}
|
||||
.t-button--danger {
|
||||
color: var(--td-button-danger-color, var(--td-text-color-anti, var(--td-font-white-1, #ffffff)));
|
||||
background-color: var(--td-button-danger-bg-color, var(--td-error-color, var(--td-error-color-6, #d54941)));
|
||||
border-color: var(--td-button-danger-border-color, var(--td-error-color, var(--td-error-color-6, #d54941)));
|
||||
}
|
||||
.t-button--danger::after {
|
||||
border-width: var(--td-button-border-width, 4rpx);
|
||||
border-color: var(--td-button-danger-border-color, var(--td-error-color, var(--td-error-color-6, #d54941)));
|
||||
}
|
||||
.t-button--danger.t-button--hover {
|
||||
z-index: 0;
|
||||
}
|
||||
.t-button--danger.t-button--hover,
|
||||
.t-button--danger.t-button--hover::after {
|
||||
background-color: var(--td-button-danger-active-bg-color, var(--td-error-color-active, var(--td-error-color-7, #ad352f)));
|
||||
border-color: var(--td-button-danger-active-border-color, var(--td-error-color-active, var(--td-error-color-7, #ad352f)));
|
||||
}
|
||||
.t-button--danger.t-button--disabled {
|
||||
color: var(--td-button-danger-disabled-color, var(--td-font-white-1, #ffffff));
|
||||
background-color: var(--td-button-danger-disabled-bg, var(--td-error-color-3, #ffb9b0));
|
||||
}
|
||||
.t-button--danger.t-button--disabled,
|
||||
.t-button--danger.t-button--disabled::after {
|
||||
border-color: var(--td-button-danger-disabled-border-color, var(--td-error-color-3, #ffb9b0));
|
||||
}
|
||||
.t-button {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
white-space: nowrap;
|
||||
text-align: center;
|
||||
background-image: none;
|
||||
transition: all 0.3s;
|
||||
touch-action: manipulation;
|
||||
border-radius: var(--td-button-border-radius, var(--td-radius-default, 12rpx));
|
||||
outline: none;
|
||||
font-family: PingFang SC, Microsoft YaHei, Arial Regular;
|
||||
font-weight: var(--td-button-font-weight, 600);
|
||||
vertical-align: top;
|
||||
box-sizing: border-box;
|
||||
cursor: pointer;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
-webkit-user-select: none;
|
||||
user-select: none;
|
||||
/* stylelint-disable-next-line */
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
.t-button::after {
|
||||
border-radius: calc(var(--td-button-border-radius, var(--td-radius-default, 12rpx)) * 2);
|
||||
}
|
||||
.t-button--text {
|
||||
color: var(--td-button-default-color, var(--td-text-color-primary, var(--td-font-gray-1, rgba(0, 0, 0, 0.9))));
|
||||
background-color: transparent;
|
||||
}
|
||||
.t-button--text,
|
||||
.t-button--text::after {
|
||||
border: 0;
|
||||
}
|
||||
.t-button--text.t-button--hover,
|
||||
.t-button--text.t-button--hover::after {
|
||||
background-color: var(--td-button-default-text-active-bg-color, var(--td-bg-color-container-active, var(--td-gray-color-3, #e7e7e7)));
|
||||
}
|
||||
.t-button--text.t-button--primary {
|
||||
color: var(--td-button-primary-text-color, var(--td-brand-color, var(--td-primary-color-7, #0052d9)));
|
||||
background-color: transparent;
|
||||
}
|
||||
.t-button--text.t-button--primary.t-button--hover,
|
||||
.t-button--text.t-button--primary.t-button--hover::after {
|
||||
background-color: var(--td-button-primary-text-active-bg-color, var(--td-bg-color-container-active, var(--td-gray-color-3, #e7e7e7)));
|
||||
}
|
||||
.t-button--text.t-button--primary.t-button--disabled {
|
||||
color: var(--td-button-primary-text-disabled-color, var(--td-brand-color-disabled, var(--td-primary-color-3, #b5c7ff)));
|
||||
background-color: var(--td-bg-color-container, var(--td-font-white-1, #ffffff));
|
||||
}
|
||||
.t-button--text.t-button--danger {
|
||||
color: var(--td-button-danger-text-color, var(--td-error-color, var(--td-error-color-6, #d54941)));
|
||||
background-color: transparent;
|
||||
}
|
||||
.t-button--text.t-button--danger.t-button--hover,
|
||||
.t-button--text.t-button--danger.t-button--hover::after {
|
||||
background-color: var(--td-button-danger-text-active-bg-color, var(--td-bg-color-container-active, var(--td-gray-color-3, #e7e7e7)));
|
||||
}
|
||||
.t-button--text.t-button--danger.t-button--disabled {
|
||||
color: var(--td-button-danger-text-disabled-color, var(--td-button-danger-disabled-color, var(--td-font-white-1, #ffffff)));
|
||||
background-color: var(--td-bg-color-container, var(--td-font-white-1, #ffffff));
|
||||
}
|
||||
.t-button--text.t-button--light {
|
||||
color: var(--td-button-light-text-color, var(--td-brand-color, var(--td-primary-color-7, #0052d9)));
|
||||
background-color: transparent;
|
||||
}
|
||||
.t-button--text.t-button--light.t-button--hover,
|
||||
.t-button--text.t-button--light.t-button--hover::after {
|
||||
background-color: var(--td-button-light-text-active-bg-color, var(--td-bg-color-container-active, var(--td-gray-color-3, #e7e7e7)));
|
||||
}
|
||||
.t-button--text.t-button--disabled {
|
||||
color: var(--td-button-default-disabled-color, var(--td-text-color-disabled, var(--td-font-gray-4, rgba(0, 0, 0, 0.26))));
|
||||
}
|
||||
.t-button--outline {
|
||||
color: var(--td-button-default-outline-color, var(--td-text-color-primary, var(--td-font-gray-1, rgba(0, 0, 0, 0.9))));
|
||||
background-color: var(--td-bg-color-container, var(--td-font-white-1, #ffffff));
|
||||
}
|
||||
.t-button--outline,
|
||||
.t-button--outline::after {
|
||||
border-color: var(--td-button-default-outline-border-color, var(--td-component-border, var(--td-gray-color-4, #dcdcdc)));
|
||||
}
|
||||
.t-button--outline.t-button--hover,
|
||||
.t-button--outline.t-button--hover::after {
|
||||
background-color: var(--td-button-default-outline-active-bg-color, var(--td-bg-color-container-active, var(--td-gray-color-3, #e7e7e7)));
|
||||
border-color: var(--td-button-default-outline-active-border-color, var(--td-component-border, var(--td-gray-color-4, #dcdcdc)));
|
||||
}
|
||||
.t-button--outline.t-button--disabled {
|
||||
color: var(--td-button-default-outline-disabled-color, var(--td-component-border, var(--td-gray-color-4, #dcdcdc)));
|
||||
}
|
||||
.t-button--outline.t-button--disabled,
|
||||
.t-button--outline.t-button--disabled::after {
|
||||
border-color: var(--td-button-default-outline-disabled-color, var(--td-component-border, var(--td-gray-color-4, #dcdcdc)));
|
||||
}
|
||||
.t-button--outline.t-button--primary {
|
||||
color: var(--td-button-primary-outline-color, var(--td-brand-color, var(--td-primary-color-7, #0052d9)));
|
||||
}
|
||||
.t-button--outline.t-button--primary,
|
||||
.t-button--outline.t-button--primary::after {
|
||||
border-color: var(--td-button-primary-outline-border-color, var(--td-button-primary-outline-color, var(--td-brand-color, var(--td-primary-color-7, #0052d9))));
|
||||
}
|
||||
.t-button--outline.t-button--primary.t-button--hover {
|
||||
color: var(--td-button-primary-outline-active-border-color, var(--td-brand-color-active, var(--td-primary-color-8, #003cab)));
|
||||
}
|
||||
.t-button--outline.t-button--primary.t-button--hover::after {
|
||||
background-color: var(--td-button-primary-outline-active-bg-color, var(--td-bg-color-container-active, var(--td-gray-color-3, #e7e7e7)));
|
||||
border-color: var(--td-button-primary-outline-active-border-color, var(--td-brand-color-active, var(--td-primary-color-8, #003cab)));
|
||||
}
|
||||
.t-button--outline.t-button--primary.t-button--disabled {
|
||||
background-color: transparent;
|
||||
color: var(--td-button-primary-outline-disabled-color, var(--td-brand-color-disabled, var(--td-primary-color-3, #b5c7ff)));
|
||||
}
|
||||
.t-button--outline.t-button--primary.t-button--disabled,
|
||||
.t-button--outline.t-button--primary.t-button--disabled::after {
|
||||
border-color: var(--td-button-primary-outline-disabled-color, var(--td-brand-color-disabled, var(--td-primary-color-3, #b5c7ff)));
|
||||
}
|
||||
.t-button--outline.t-button--danger {
|
||||
color: var(--td-button-danger-outline-color, var(--td-error-color, var(--td-error-color-6, #d54941)));
|
||||
}
|
||||
.t-button--outline.t-button--danger,
|
||||
.t-button--outline.t-button--danger::after {
|
||||
border-color: var(--td-button-danger-outline-border-color, var(--td-button-danger-outline-color, var(--td-error-color, var(--td-error-color-6, #d54941))));
|
||||
}
|
||||
.t-button--outline.t-button--danger.t-button--hover {
|
||||
color: var(--td-button-danger-outline-active-border-color, var(--td-error-color-active, var(--td-error-color-7, #ad352f)));
|
||||
}
|
||||
.t-button--outline.t-button--danger.t-button--hover::after {
|
||||
background-color: var(--td-button-danger-outline-active-bg-color, var(--td-bg-color-container-active, var(--td-gray-color-3, #e7e7e7)));
|
||||
border-color: var(--td-button-danger-outline-active-border-color, var(--td-error-color-active, var(--td-error-color-7, #ad352f)));
|
||||
}
|
||||
.t-button--outline.t-button--danger.t-button--disabled {
|
||||
background-color: var(--td-bg-color-container, var(--td-font-white-1, #ffffff));
|
||||
color: var(--td-button-danger-outline-disabled-color, var(--td-error-color-3, #ffb9b0));
|
||||
}
|
||||
.t-button--outline.t-button--danger.t-button--disabled,
|
||||
.t-button--outline.t-button--danger.t-button--disabled::after {
|
||||
border-color: var(--td-button-danger-outline-disabled-color, var(--td-error-color-3, #ffb9b0));
|
||||
}
|
||||
.t-button--outline.t-button--light {
|
||||
color: var(--td-button-light-outline-color, var(--td-brand-color, var(--td-primary-color-7, #0052d9)));
|
||||
background-color: var(--td-button-light-outline-bg-color, var(--td-brand-color-light, var(--td-primary-color-1, #f2f3ff)));
|
||||
}
|
||||
.t-button--outline.t-button--light,
|
||||
.t-button--outline.t-button--light::after {
|
||||
border-color: var(--td-button-light-outline-border-color, var(--td-button-light-outline-color, var(--td-brand-color, var(--td-primary-color-7, #0052d9))));
|
||||
}
|
||||
.t-button--outline.t-button--light.t-button--hover {
|
||||
color: var(--td-button-light-outline-active-border-color, var(--td-brand-color-active, var(--td-primary-color-8, #003cab)));
|
||||
}
|
||||
.t-button--outline.t-button--light.t-button--hover,
|
||||
.t-button--outline.t-button--light.t-button--hover::after {
|
||||
background-color: var(--td-button-light-outline-active-bg-color, var(--td-brand-color-light-active, var(--td-primary-color-2, #d9e1ff)));
|
||||
border-color: var(--td-button-light-outline-active-border-color, var(--td-brand-color-active, var(--td-primary-color-8, #003cab)));
|
||||
}
|
||||
.t-button--outline.t-button--light.t-button--disabled {
|
||||
background-color: var(--td-bg-color-container, var(--td-font-white-1, #ffffff));
|
||||
color: var(--td-button-light-outline-disabled-color, var(--td-brand-color-disabled, var(--td-primary-color-3, #b5c7ff)));
|
||||
}
|
||||
.t-button--outline.t-button--light.t-button--disabled,
|
||||
.t-button--outline.t-button--light.t-button--disabled::after {
|
||||
border-color: var(--td-button-light-outline-disabled-color, var(--td-brand-color-disabled, var(--td-primary-color-3, #b5c7ff)));
|
||||
}
|
||||
.t-button--dashed {
|
||||
background-color: var(--td-bg-color-container, var(--td-font-white-1, #ffffff));
|
||||
border-style: dashed;
|
||||
border-width: 2rpx;
|
||||
}
|
||||
.t-button--dashed::after {
|
||||
border: 0;
|
||||
}
|
||||
.t-button--dashed.t-button--hover,
|
||||
.t-button--dashed.t-button--hover::after {
|
||||
background-color: var(--td-button-default-outline-active-bg-color, var(--td-bg-color-container-active, var(--td-gray-color-3, #e7e7e7)));
|
||||
border-color: var(--td-button-default-outline-active-border-color, var(--td-component-border, var(--td-gray-color-4, #dcdcdc)));
|
||||
}
|
||||
.t-button--dashed.t-button--primary {
|
||||
color: var(--td-button-primary-dashed-color, var(--td-brand-color, var(--td-primary-color-7, #0052d9)));
|
||||
}
|
||||
.t-button--dashed.t-button--primary,
|
||||
.t-button--dashed.t-button--primary::after {
|
||||
border-color: var(--td-button-primary-dashed-border-color, var(--td-button-primary-dashed-color, var(--td-brand-color, var(--td-primary-color-7, #0052d9))));
|
||||
}
|
||||
.t-button--dashed.t-button--primary.t-button--disabled {
|
||||
background-color: var(--td-bg-color-container, var(--td-font-white-1, #ffffff));
|
||||
color: var(--td-button-primary-dashed-disabled-color, var(--td-brand-color-disabled, var(--td-primary-color-3, #b5c7ff)));
|
||||
}
|
||||
.t-button--dashed.t-button--primary.t-button--disabled,
|
||||
.t-button--dashed.t-button--primary.t-button--disabled::after {
|
||||
border-color: var(--td-button-primary-dashed-disabled-color, var(--td-brand-color-disabled, var(--td-primary-color-3, #b5c7ff)));
|
||||
}
|
||||
.t-button--dashed.t-button--danger {
|
||||
color: var(--td-button-danger-dashed-color, var(--td-error-color, var(--td-error-color-6, #d54941)));
|
||||
}
|
||||
.t-button--dashed.t-button--danger,
|
||||
.t-button--dashed.t-button--danger::after {
|
||||
border-color: var(--td-button-danger-dashed-border-color, var(--td-button-danger-dashed-color, var(--td-error-color, var(--td-error-color-6, #d54941))));
|
||||
}
|
||||
.t-button--dashed.t-button--danger.t-button--disabled {
|
||||
background-color: transparent;
|
||||
color: var(--td-button-danger-dashed-disabled-color, var(--td-button-danger-disabled-color, var(--td-font-white-1, #ffffff)));
|
||||
}
|
||||
.t-button--dashed.t-button--danger.t-button--disabled::after {
|
||||
border-color: var(--td-button-danger-dashed-disabled-color, var(--td-button-danger-disabled-color, var(--td-font-white-1, #ffffff)));
|
||||
}
|
||||
.t-button--ghost {
|
||||
background-color: transparent;
|
||||
color: var(--td-button-ghost-color, var(--td-text-color-anti, var(--td-font-white-1, #ffffff)));
|
||||
}
|
||||
.t-button--ghost,
|
||||
.t-button--ghost::after {
|
||||
border-color: var(--td-button-ghost-border-color, var(--td-button-ghost-color, var(--td-text-color-anti, var(--td-font-white-1, #ffffff))));
|
||||
}
|
||||
.t-button--ghost.t-button--default.t-button--hover {
|
||||
color: var(--td-button-ghost-hover-color, var(--td-font-white-2, rgba(255, 255, 255, 0.55)));
|
||||
}
|
||||
.t-button--ghost.t-button--default.t-button--hover,
|
||||
.t-button--ghost.t-button--default.t-button--hover::after {
|
||||
background-color: transparent;
|
||||
border-color: var(--td-button-ghost-hover-color, var(--td-font-white-2, rgba(255, 255, 255, 0.55)));
|
||||
}
|
||||
.t-button--ghost.t-button--primary {
|
||||
color: var(--td-button-ghost-primary-color, var(--td-brand-color, var(--td-primary-color-7, #0052d9)));
|
||||
}
|
||||
.t-button--ghost.t-button--primary,
|
||||
.t-button--ghost.t-button--primary::after {
|
||||
border-color: var(--td-button-ghost-primary-border-color, var(--td-brand-color, var(--td-primary-color-7, #0052d9)));
|
||||
}
|
||||
.t-button--ghost.t-button--primary.t-button--hover {
|
||||
color: var(--td-button-ghost-primary-hover-color, var(--td-brand-color-active, var(--td-primary-color-8, #003cab)));
|
||||
}
|
||||
.t-button--ghost.t-button--primary.t-button--hover,
|
||||
.t-button--ghost.t-button--primary.t-button--hover::after {
|
||||
background-color: transparent;
|
||||
border-color: var(--td-button-ghost-primary-hover-color, var(--td-brand-color-active, var(--td-primary-color-8, #003cab)));
|
||||
}
|
||||
.t-button--ghost.t-button--primary.t-button--text.t-button--hover,
|
||||
.t-button--ghost.t-button--primary.t-button--text.t-button--hover::after {
|
||||
background-color: var(--td-gray-color-10, #4b4b4b);
|
||||
}
|
||||
.t-button--ghost.t-button--primary.t-button--disabled {
|
||||
background-color: transparent;
|
||||
color: var(--td-button-ghost-disabled-color, var(--td-font-white-4, rgba(255, 255, 255, 0.22)));
|
||||
}
|
||||
.t-button--ghost.t-button--primary.t-button--disabled,
|
||||
.t-button--ghost.t-button--primary.t-button--disabled::after {
|
||||
border-color: var(--td-button-ghost-disabled-color, var(--td-font-white-4, rgba(255, 255, 255, 0.22)));
|
||||
}
|
||||
.t-button--ghost.t-button--danger {
|
||||
color: var(--td-button-ghost-danger-color, var(--td-error-color, var(--td-error-color-6, #d54941)));
|
||||
}
|
||||
.t-button--ghost.t-button--danger,
|
||||
.t-button--ghost.t-button--danger::after {
|
||||
border-color: var(--td-button-ghost-danger-border-color, var(--td-error-color, var(--td-error-color-6, #d54941)));
|
||||
}
|
||||
.t-button--ghost.t-button--danger.t-button--hover {
|
||||
color: var(--td-button-ghost-danger-hover-color, var(--td-error-color-active, var(--td-error-color-7, #ad352f)));
|
||||
}
|
||||
.t-button--ghost.t-button--danger.t-button--hover,
|
||||
.t-button--ghost.t-button--danger.t-button--hover::after {
|
||||
background-color: transparent;
|
||||
border-color: var(--td-button-ghost-danger-hover-color, var(--td-error-color-active, var(--td-error-color-7, #ad352f)));
|
||||
}
|
||||
.t-button--ghost.t-button--danger.t-button--text.t-button--hover,
|
||||
.t-button--ghost.t-button--danger.t-button--text.t-button--hover::after {
|
||||
background-color: var(--td-gray-color-10, #4b4b4b);
|
||||
}
|
||||
.t-button--ghost.t-button--danger.t-button--disabled {
|
||||
background-color: transparent;
|
||||
color: var(--td-button-ghost-disabled-color, var(--td-font-white-4, rgba(255, 255, 255, 0.22)));
|
||||
}
|
||||
.t-button--ghost.t-button--danger.t-button--disabled,
|
||||
.t-button--ghost.t-button--danger.t-button--disabled::after {
|
||||
border-color: var(--td-button-ghost-disabled-color, var(--td-font-white-4, rgba(255, 255, 255, 0.22)));
|
||||
}
|
||||
.t-button--ghost.t-button--default.t-button--text.t-button--hover,
|
||||
.t-button--ghost.t-button--default.t-button--text.t-button--hover::after {
|
||||
background-color: var(--td-gray-color-10, #4b4b4b);
|
||||
}
|
||||
.t-button--ghost.t-button--default.t-button--disabled {
|
||||
background-color: transparent;
|
||||
color: var(--td-button-ghost-disabled-color, var(--td-font-white-4, rgba(255, 255, 255, 0.22)));
|
||||
}
|
||||
.t-button--ghost.t-button--default.t-button--disabled,
|
||||
.t-button--ghost.t-button--default.t-button--disabled::after {
|
||||
border-color: var(--td-button-ghost-disabled-color, var(--td-font-white-4, rgba(255, 255, 255, 0.22)));
|
||||
}
|
||||
.t-button__loading + .t-button__content:not(:empty),
|
||||
.t-button__icon + .t-button__content:not(:empty) {
|
||||
margin-left: 8rpx;
|
||||
}
|
||||
.t-button__icon {
|
||||
border-radius: var(--td-button-icon-border-radius, 8rpx);
|
||||
}
|
||||
.t-button--round.t-button--size-large {
|
||||
border-radius: calc(var(--td-button-large-height, 96rpx) / 2);
|
||||
}
|
||||
.t-button--round.t-button--size-large::after {
|
||||
border-radius: var(--td-button-large-height, 96rpx);
|
||||
}
|
||||
.t-button--round.t-button--size-medium {
|
||||
border-radius: calc(var(--td-button-medium-height, 80rpx) / 2);
|
||||
}
|
||||
.t-button--round.t-button--size-medium::after {
|
||||
border-radius: var(--td-button-medium-height, 80rpx);
|
||||
}
|
||||
.t-button--round.t-button--size-small {
|
||||
border-radius: calc(var(--td-button-small-height, 64rpx) / 2);
|
||||
}
|
||||
.t-button--round.t-button--size-small::after {
|
||||
border-radius: var(--td-button-small-height, 64rpx);
|
||||
}
|
||||
.t-button--round.t-button--size-extra-small {
|
||||
border-radius: calc(var(--td-button-extra-small-height, 56rpx) / 2);
|
||||
}
|
||||
.t-button--round.t-button--size-extra-small::after {
|
||||
border-radius: var(--td-button-extra-small-height, 56rpx);
|
||||
}
|
||||
.t-button--square {
|
||||
padding: 0;
|
||||
}
|
||||
.t-button--square.t-button--size-large {
|
||||
width: var(--td-button-large-height, 96rpx);
|
||||
}
|
||||
.t-button--square.t-button--size-medium {
|
||||
width: var(--td-button-medium-height, 80rpx);
|
||||
}
|
||||
.t-button--square.t-button--size-small {
|
||||
width: var(--td-button-small-height, 64rpx);
|
||||
}
|
||||
.t-button--square.t-button--size-extra-small {
|
||||
width: var(--td-button-extra-small-height, 56rpx);
|
||||
}
|
||||
.t-button--circle {
|
||||
padding: 0;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.t-button--circle.t-button--size-large {
|
||||
width: var(--td-button-large-height, 96rpx);
|
||||
}
|
||||
.t-button--circle.t-button--size-large::after {
|
||||
border-radius: 50%;
|
||||
}
|
||||
.t-button--circle.t-button--size-medium {
|
||||
width: var(--td-button-medium-height, 80rpx);
|
||||
}
|
||||
.t-button--circle.t-button--size-medium::after {
|
||||
border-radius: 50%;
|
||||
}
|
||||
.t-button--circle.t-button--size-small {
|
||||
width: var(--td-button-small-height, 64rpx);
|
||||
}
|
||||
.t-button--circle.t-button--size-small::after {
|
||||
border-radius: 50%;
|
||||
}
|
||||
.t-button--circle.t-button--size-extra-small {
|
||||
width: var(--td-button-extra-small-height, 56rpx);
|
||||
}
|
||||
.t-button--circle.t-button--size-extra-small::after {
|
||||
border-radius: 50%;
|
||||
}
|
||||
.t-button--block {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
}
|
||||
.t-button--disabled {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.t-button__loading--wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.t-button.t-button--hover::after {
|
||||
z-index: -1;
|
||||
}
|
||||
244
uni_modules/tdesign-uniapp/components/button/button.vue
Normal file
244
uni_modules/tdesign-uniapp/components/button/button.vue
Normal file
@@ -0,0 +1,244 @@
|
||||
<template>
|
||||
<button
|
||||
:id="tId"
|
||||
:style="tools._style([customStyle])"
|
||||
:data-custom="customDataset"
|
||||
:class="className"
|
||||
:form-type="disabled || loading ? '' : type"
|
||||
:open-type="disabled || loading ? '' : openType"
|
||||
:hover-stop-propagation="hoverStopPropagation"
|
||||
:hover-start-time="hoverStartTime"
|
||||
:hover-stay-time="hoverStayTime"
|
||||
:lang="lang"
|
||||
:session-from="sessionFrom"
|
||||
:hover-class="disabled || loading ? '' : hoverClass || classPrefix + '--hover'"
|
||||
:send-message-title="sendMessageTitle"
|
||||
:send-message-path="sendMessagePath"
|
||||
:send-message-img="sendMessageImg"
|
||||
:app-parameter="appParameter"
|
||||
:show-message-card="showMessageCard"
|
||||
:aria-label="ariaLabel"
|
||||
@click.stop.prevent="handleTap"
|
||||
@getuserinfo="getuserinfo"
|
||||
@contact="contact"
|
||||
@getphonenumber="getphonenumber"
|
||||
@error="error"
|
||||
@opensetting="opensetting"
|
||||
@launchapp="launchapp"
|
||||
@chooseavatar="chooseavatar"
|
||||
@agreeprivacyauthorization="agreeprivacyauthorization"
|
||||
>
|
||||
<block
|
||||
v-if="_icon"
|
||||
name="icon"
|
||||
>
|
||||
<t-icon
|
||||
:custom-style="iconCustomStyle"
|
||||
:t-class="classPrefix + '__icon ' + classPrefix + '__icon--' + (_icon.activeIdx == _icon.index ? 'active ' : ' ') + tClassIcon"
|
||||
:prefix="_icon.prefix"
|
||||
:name="_icon.name || ''"
|
||||
:size="_icon.size"
|
||||
:color="_icon.color"
|
||||
@click="'handleClose' || ''"
|
||||
/>
|
||||
</block>
|
||||
<t-loading
|
||||
v-if="loading"
|
||||
:delay="loadingProps.delay || 0"
|
||||
:duration="loadingProps.duration || 800"
|
||||
:indicator="loadingProps.indicator || true"
|
||||
:inherit-color="loadingProps.inheritColor || true"
|
||||
:layout="loadingProps.layout || 'horizontal'"
|
||||
:pause="loadingProps.pause || false"
|
||||
:progress="loadingProps.progress || 0"
|
||||
:reverse="loadingProps.reverse || false"
|
||||
:size="loadingProps.size || '40rpx'"
|
||||
:text="loadingProps.text || ''"
|
||||
:theme="loadingProps.theme || 'circular'"
|
||||
loading
|
||||
:t-class="classPrefix + '__loading ' + classPrefix + '__loading--wrapper'"
|
||||
:t-class-indicator="classPrefix + '__loading--indicator ' + tClassLoading"
|
||||
:custom-style="loadingCustomStyle"
|
||||
/>
|
||||
<view
|
||||
:class="classPrefix + '__content '
|
||||
+ ((_icon && _icon.name || loading) && content ? classPrefix + '__content--has-icon' : '')"
|
||||
>
|
||||
<slot name="content" />
|
||||
<block v-if="content">
|
||||
{{ content }}
|
||||
</block>
|
||||
<slot />
|
||||
</view>
|
||||
<slot name="suffix" />
|
||||
</button>
|
||||
</template>
|
||||
<script>
|
||||
import TIcon from '../icon/icon';
|
||||
import TLoading from '../loading/loading';
|
||||
import { uniComponent } from '../common/src/index';
|
||||
import { prefix } from '../common/config';
|
||||
import props from './props';
|
||||
import { calcIcon } from '../common/utils';
|
||||
import tools from '../common/utils.wxs';
|
||||
|
||||
|
||||
const name = `${prefix}-button`;
|
||||
|
||||
|
||||
export default uniComponent({
|
||||
name,
|
||||
options: {
|
||||
styleIsolation: 'shared',
|
||||
},
|
||||
externalClasses: [
|
||||
`${prefix}-class`,
|
||||
`${prefix}-class-icon`,
|
||||
`${prefix}-class-loading`,
|
||||
],
|
||||
components: {
|
||||
TIcon,
|
||||
TLoading,
|
||||
},
|
||||
props: {
|
||||
...props,
|
||||
},
|
||||
emits: [
|
||||
'click',
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
tools,
|
||||
prefix,
|
||||
className: '',
|
||||
classPrefix: name,
|
||||
_icon: undefined,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
iconCustomStyle() {
|
||||
const fontSize = {
|
||||
'extra-small': 'var(--td-button-extra-small-icon-font-size, 18px)',
|
||||
small: 'var(--td-button-small-icon-font-size, 18px)',
|
||||
medium: 'var(--td-button-medium-icon-font-size, 20px)',
|
||||
large: 'var(--td-button-large-icon-font-size, 24px)',
|
||||
};
|
||||
|
||||
return tools._style([
|
||||
{
|
||||
fontSize: fontSize[this.size || 'medium'],
|
||||
borderRadius: 'var(--td-button-icon-border-radius, 4px)',
|
||||
},
|
||||
this._icon.style || '',
|
||||
]);
|
||||
},
|
||||
loadingCustomStyle() {
|
||||
return tools._style({
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
});
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
icon: {
|
||||
handler(value) {
|
||||
this._icon = calcIcon(value, '');
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
theme: 'setClass',
|
||||
size: 'setClass',
|
||||
plain: 'setClass',
|
||||
block: 'setClass',
|
||||
shape: 'setClass',
|
||||
disabled: 'setClass',
|
||||
loading: 'setClass',
|
||||
variant: 'setClass',
|
||||
},
|
||||
mounted() {
|
||||
this.setClass();
|
||||
},
|
||||
methods: {
|
||||
setClass() {
|
||||
const t = [
|
||||
name,
|
||||
this.tClass,
|
||||
`${name}--${this.variant || 'base'}`,
|
||||
`${name}--${this.theme || 'default'}`,
|
||||
`${name}--${this.shape || 'rectangle'}`,
|
||||
`${name}--size-${this.size || 'medium'}`,
|
||||
];
|
||||
if (this.block) {
|
||||
t.push(`${name}--block`);
|
||||
}
|
||||
if (this.disabled) {
|
||||
t.push(`${name}--disabled`);
|
||||
}
|
||||
if (this.ghost) {
|
||||
t.push(`${name}--ghost`);
|
||||
}
|
||||
this.className = t.join(' ');
|
||||
},
|
||||
getuserinfo(t) {
|
||||
this.$emit('getuserinfo', t);
|
||||
},
|
||||
contact(t) {
|
||||
this.$emit('contact', t);
|
||||
},
|
||||
getphonenumber(t) {
|
||||
this.$emit('getphonenumber', t);
|
||||
},
|
||||
error(t) {
|
||||
this.$emit('error', t);
|
||||
},
|
||||
opensetting(t) {
|
||||
this.$emit('opensetting', t);
|
||||
},
|
||||
launchapp(t) {
|
||||
this.$emit('launchapp', t);
|
||||
},
|
||||
chooseavatar(t) {
|
||||
this.$emit('chooseavatar', t);
|
||||
},
|
||||
agreeprivacyauthorization(t) {
|
||||
this.$emit('agreeprivacyauthorization', t);
|
||||
},
|
||||
handleTap(t) {
|
||||
if (this.disabled || this.loading) return;
|
||||
this.$emit('click', t);
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style scoped>
|
||||
@import './button.css';
|
||||
|
||||
/* #ifdef MP-QQ */
|
||||
/* 适配 qq 小程序 */
|
||||
.t-button--outline {
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
}
|
||||
.t-button--ghost {
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
}
|
||||
/* #endif */
|
||||
|
||||
/* #ifdef H5 || MP-WEIXIN */
|
||||
:deep(.t-button__loading) + .t-button__content:not(:empty) {
|
||||
margin-left: 4px;
|
||||
}
|
||||
:deep(.t-button__icon) + .t-button__content:not(:empty) {
|
||||
margin-left: 4px;
|
||||
}
|
||||
/* #endif */
|
||||
|
||||
|
||||
.t-button {
|
||||
/* support my-alipay */
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
</style>
|
||||
207
uni_modules/tdesign-uniapp/components/button/props.ts
Normal file
207
uni_modules/tdesign-uniapp/components/button/props.ts
Normal file
@@ -0,0 +1,207 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
|
||||
* */
|
||||
|
||||
import type { TdButtonProps } from './type';
|
||||
export default {
|
||||
/** 打开 APP 时,向 APP 传递的参数,open-type=launchApp时有效 */
|
||||
appParameter: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
/** 是否为块级元素 */
|
||||
block: Boolean,
|
||||
/** 按钮内容 */
|
||||
content: {
|
||||
type: String,
|
||||
},
|
||||
/** 自定义 dataset,可通过 event.currentTarget.dataset.custom 获取 */
|
||||
customDataset: {
|
||||
type: [String, Number, Boolean, Object, Array],
|
||||
default: () => ({}) as TdButtonProps['customDataset'],
|
||||
},
|
||||
/** 禁用状态。优先级:Button.disabled > Form.disabled */
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: undefined,
|
||||
},
|
||||
/** 是否为幽灵按钮(镂空按钮) */
|
||||
ghost: Boolean,
|
||||
/** 指定按钮按下去的样式类,按钮不为加载或禁用状态时有效。当 `hover-class="none"` 时,没有点击态效果 */
|
||||
hoverClass: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
/** 按住后多久出现点击态,单位毫秒 */
|
||||
hoverStartTime: {
|
||||
type: Number,
|
||||
default: 20,
|
||||
},
|
||||
/** 手指松开后点击态保留时间,单位毫秒 */
|
||||
hoverStayTime: {
|
||||
type: Number,
|
||||
default: 70,
|
||||
},
|
||||
/** 指定是否阻止本节点的祖先节点出现点击态 */
|
||||
hoverStopPropagation: Boolean,
|
||||
/** 图标名称。值为字符串表示图标名称,值为 `Object` 类型,表示透传至 `icon` */
|
||||
icon: {
|
||||
type: [String, Object],
|
||||
},
|
||||
/** 指定返回用户信息的语言,zh_CN 简体中文,zh_TW 繁体中文,en 英文。<br />具体释义:<br />`en` 英文;<br />`zh_CN` 简体中文;<br />`zh_TW` 繁体中文。<br />[小程序官方文档](https://developers.weixin.qq.com/miniprogram/dev/component/button.html) */
|
||||
lang: {
|
||||
type: String,
|
||||
validator(val: TdButtonProps['lang']): boolean {
|
||||
if (!val) return true;
|
||||
return ['en', 'zh_CN', 'zh_TW'].includes(val);
|
||||
},
|
||||
},
|
||||
/** 是否显示为加载状态 */
|
||||
loading: Boolean,
|
||||
/** 透传 Loading 组件全部属性 */
|
||||
loadingProps: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
/** 微信开放能力。<br />具体释义:<br />`contact` 打开客服会话,如果用户在会话中点击消息卡片后返回小程序,可以从 bindcontact 回调中获得具体信息,<a href="https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/customer-message/customer-message.html">具体说明</a> (*鸿蒙 OS 暂不支持*);<br />`liveActivity` 通过前端获取<a href="https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/subscribe-message-2.html">新的一次性订阅消息下发机制</a>使用的 code;<br />`share` 触发用户转发,使用前建议先阅读<a href="https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/share.html#使用指引">使用指引</a>;<br />`getPhoneNumber` 获取用户手机号,可以从 bindgetphonenumber 回调中获取到用户信息,<a href="https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/getPhoneNumber.html">具体说明</a> (*小程序插件中不能使用*);<br />`getUserInfo` 获取用户信息,可以从 bindgetuserinfo 回调中获取到用户信息 (*小程序插件中不能使用*);<br />`launchApp` 打开APP,可以通过 app-parameter 属性设定向 APP 传的参数<a href="https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/launchApp.html">具体说明</a>;<br />`openSetting` 打开授权设置页;<br />`feedback` 打开“意见反馈”页面,用户可提交反馈内容并上传<a href="https://developers.weixin.qq.com/miniprogram/dev/api/base/debug/wx.getLogManager.html">日志</a>,开发者可以登录<a href="https://mp.weixin.qq.com/">小程序管理后台</a>后进入左侧菜单“客服反馈”页面获取到反馈内容;<br />`chooseAvatar` 获取用户头像,可以从 bindchooseavatar 回调中获取到头像信息;<br />`agreePrivacyAuthorization`用户同意隐私协议按钮。用户点击一次此按钮后,所有隐私接口可以正常调用。可通过`bindagreeprivacyauthorization`监听用户同意隐私协议事件。隐私合规开发指南详情可见《<a href="https://developers.weixin.qq.com/miniprogram/dev/framework/user-privacy/PrivacyAuthorize.html">小程序隐私协议开发指南</a>》。<br />[小程序官方文档](https://developers.weixin.qq.com/miniprogram/dev/component/button.html) */
|
||||
openType: {
|
||||
type: String,
|
||||
validator(val: TdButtonProps['openType']): boolean {
|
||||
if (!val) return true;
|
||||
return ['contact', 'share', 'getPhoneNumber', 'getUserInfo', 'launchApp', 'openSetting', 'feedback', 'chooseAvatar', 'agreePrivacyAuthorization'].includes(val);
|
||||
},
|
||||
},
|
||||
/** 原生按钮属性,当手机号快速验证或手机号实时验证额度用尽时,是否对用户展示“申请获取你的手机号,但该功能使用次数已达当前小程序上限,暂时无法使用”的提示,默认展示,open-type="getPhoneNumber" 或 open-type="getRealtimePhoneNumber" 时有效 */
|
||||
phoneNumberNoQuotaToast: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
/** 会话内消息卡片图片,open-type="contact"时有效 */
|
||||
sendMessageImg: {
|
||||
type: String,
|
||||
default: '截图',
|
||||
},
|
||||
/** 会话内消息卡片点击跳转小程序路径,open-type="contact"时有效 */
|
||||
sendMessagePath: {
|
||||
type: String,
|
||||
default: '当前分享路径',
|
||||
},
|
||||
/** 会话内消息卡片标题,open-type="contact"时有效 */
|
||||
sendMessageTitle: {
|
||||
type: String,
|
||||
default: '当前标题',
|
||||
},
|
||||
/** 会话来源,open-type="contact"时有效 */
|
||||
sessionFrom: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
/** 按钮形状,有 4 种:长方形、正方形、圆角长方形、圆形 */
|
||||
shape: {
|
||||
type: String,
|
||||
default: 'rectangle' as TdButtonProps['shape'],
|
||||
validator(val: TdButtonProps['shape']): boolean {
|
||||
if (!val) return true;
|
||||
return ['rectangle', 'square', 'round', 'circle'].includes(val);
|
||||
},
|
||||
},
|
||||
/** 是否显示会话内消息卡片,设置此参数为 true,用户进入客服会话会在右下角显示"可能要发送的小程序"提示,用户点击后可以快速发送小程序消息,open-type="contact"时有效 */
|
||||
showMessageCard: Boolean,
|
||||
/** 组件尺寸 */
|
||||
size: {
|
||||
type: String,
|
||||
default: 'medium' as TdButtonProps['size'],
|
||||
validator(val: TdButtonProps['size']): boolean {
|
||||
if (!val) return true;
|
||||
return ['extra-small', 'small', 'medium', 'large'].includes(val);
|
||||
},
|
||||
},
|
||||
/** 按钮标签id */
|
||||
tId: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
/** 组件风格,依次为品牌色、危险色 */
|
||||
theme: {
|
||||
type: String,
|
||||
default: 'default' as TdButtonProps['theme'],
|
||||
validator(val: TdButtonProps['theme']): boolean {
|
||||
if (!val) return true;
|
||||
return ['default', 'primary', 'danger', 'light'].includes(val);
|
||||
},
|
||||
},
|
||||
/** 同小程序的 formType */
|
||||
type: {
|
||||
type: String,
|
||||
validator(val: TdButtonProps['type']): boolean {
|
||||
if (!val) return true;
|
||||
return ['submit', 'reset'].includes(val);
|
||||
},
|
||||
},
|
||||
/** 按钮形式,基础、线框、虚线、文字 */
|
||||
variant: {
|
||||
type: String,
|
||||
default: 'base' as TdButtonProps['variant'],
|
||||
validator(val: TdButtonProps['variant']): boolean {
|
||||
if (!val) return true;
|
||||
return ['base', 'outline', 'dashed', 'text'].includes(val);
|
||||
},
|
||||
},
|
||||
/** 原生按钮属性,用户同意隐私协议事件回调,open-type=agreePrivacyAuthorization时有效 (Tips: 如果使用 onNeedPrivacyAuthorization 接口,需要在 bindagreeprivacyauthorization 触发后再调用 resolve({ event: "agree", buttonId })) */
|
||||
onAgreeprivacyauthorization: {
|
||||
type: Function,
|
||||
default: () => ({}),
|
||||
},
|
||||
/** 原生按钮属性,获取用户头像回调,`open-type=chooseAvatar` 时有效。返回 `e.detail.avatarUrl` 为头像临时文件链接 */
|
||||
onChooseavatar: {
|
||||
type: Function,
|
||||
default: () => ({}),
|
||||
},
|
||||
/** 点击时触发 */
|
||||
onClick: {
|
||||
type: Function,
|
||||
default: () => ({}),
|
||||
},
|
||||
/** 原生按钮属性,客服消息回调,`open-type="contact"` 时有效 */
|
||||
onContact: {
|
||||
type: Function,
|
||||
default: () => ({}),
|
||||
},
|
||||
/** 新的一次性订阅消息下发机制回调,`open-type=liveActivity` 时有效 */
|
||||
onCreateliveactivity: {
|
||||
type: Function,
|
||||
default: () => ({}),
|
||||
},
|
||||
/** 原生按钮属性,当使用开放能力时,发生错误的回调,`open-type=launchApp` 时有效 */
|
||||
onError: {
|
||||
type: Function,
|
||||
default: () => ({}),
|
||||
},
|
||||
/** 原生按钮属性,手机号快速验证回调,open-type=getPhoneNumber时有效。Tips:在触发 bindgetphonenumber 回调后应立即隐藏手机号按钮组件,或置为 disabled 状态,避免用户重复授权手机号产生额外费用 */
|
||||
onGetphonenumber: {
|
||||
type: Function,
|
||||
default: () => ({}),
|
||||
},
|
||||
/** 原生按钮属性,手机号实时验证回调,open-type=getRealtimePhoneNumber 时有效。Tips:在触发 bindgetrealtimephonenumber 回调后应立即隐藏手机号按钮组件,或置为 disabled 状态,避免用户重复授权手机号产生额外费用 */
|
||||
onGetrealtimephonenumber: {
|
||||
type: Function,
|
||||
default: () => ({}),
|
||||
},
|
||||
/** 原生按钮属性,用户点击该按钮时,会返回获取到的用户信息,回调的detail数据与wx.getUserInfo返回的一致,open-type="getUserInfo"时有效 */
|
||||
onGetuserinfo: {
|
||||
type: Function,
|
||||
default: () => ({}),
|
||||
},
|
||||
/** 打开 APP 成功的回调,`open-type=launchApp` 时有效 */
|
||||
onLaunchapp: {
|
||||
type: Function,
|
||||
default: () => ({}),
|
||||
},
|
||||
/** 原生按钮属性,在打开授权设置页后回调,open-type=openSetting时有效 */
|
||||
onOpensetting: {
|
||||
type: Function,
|
||||
default: () => ({}),
|
||||
},
|
||||
};
|
||||
192
uni_modules/tdesign-uniapp/components/button/type.ts
Normal file
192
uni_modules/tdesign-uniapp/components/button/type.ts
Normal file
@@ -0,0 +1,192 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
|
||||
* */
|
||||
|
||||
import type { TdLoadingProps as LoadingProps } from '../loading/type';
|
||||
|
||||
export interface TdButtonProps {
|
||||
/**
|
||||
* 打开 APP 时,向 APP 传递的参数,open-type=launchApp时有效
|
||||
* @default ''
|
||||
*/
|
||||
appParameter?: string;
|
||||
/**
|
||||
* 是否为块级元素
|
||||
* @default false
|
||||
*/
|
||||
block?: boolean;
|
||||
/**
|
||||
* 按钮内容
|
||||
*/
|
||||
content?: string;
|
||||
/**
|
||||
* 自定义 dataset,可通过 event.currentTarget.dataset.custom 获取
|
||||
* @default {}
|
||||
*/
|
||||
customDataset?: string | number | boolean | object | Array<string | number | boolean | object>;
|
||||
/**
|
||||
* 禁用状态。优先级:Button.disabled > Form.disabled
|
||||
*/
|
||||
disabled?: boolean;
|
||||
/**
|
||||
* 是否为幽灵按钮(镂空按钮)
|
||||
* @default false
|
||||
*/
|
||||
ghost?: boolean;
|
||||
/**
|
||||
* 指定按钮按下去的样式类,按钮不为加载或禁用状态时有效。当 `hover-class="none"` 时,没有点击态效果
|
||||
* @default ''
|
||||
*/
|
||||
hoverClass?: string;
|
||||
/**
|
||||
* 按住后多久出现点击态,单位毫秒
|
||||
* @default 20
|
||||
*/
|
||||
hoverStartTime?: number;
|
||||
/**
|
||||
* 手指松开后点击态保留时间,单位毫秒
|
||||
* @default 70
|
||||
*/
|
||||
hoverStayTime?: number;
|
||||
/**
|
||||
* 指定是否阻止本节点的祖先节点出现点击态
|
||||
* @default false
|
||||
*/
|
||||
hoverStopPropagation?: boolean;
|
||||
/**
|
||||
* 图标名称。值为字符串表示图标名称,值为 `Object` 类型,表示透传至 `icon`
|
||||
*/
|
||||
icon?: string | object;
|
||||
/**
|
||||
* 指定返回用户信息的语言,zh_CN 简体中文,zh_TW 繁体中文,en 英文。<br />具体释义:<br />`en` 英文;<br />`zh_CN` 简体中文;<br />`zh_TW` 繁体中文。<br />[小程序官方文档](https://developers.weixin.qq.com/miniprogram/dev/component/button.html)
|
||||
*/
|
||||
lang?: 'en' | 'zh_CN' | 'zh_TW';
|
||||
/**
|
||||
* 是否显示为加载状态
|
||||
* @default false
|
||||
*/
|
||||
loading?: boolean;
|
||||
/**
|
||||
* 透传 Loading 组件全部属性
|
||||
* @default {}
|
||||
*/
|
||||
loadingProps?: LoadingProps;
|
||||
/**
|
||||
* 微信开放能力。<br />具体释义:<br />`contact` 打开客服会话,如果用户在会话中点击消息卡片后返回小程序,可以从 bindcontact 回调中获得具体信息,<a href="https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/customer-message/customer-message.html">具体说明</a> (*鸿蒙 OS 暂不支持*);<br />`liveActivity` 通过前端获取<a href="https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/subscribe-message-2.html">新的一次性订阅消息下发机制</a>使用的 code;<br />`share` 触发用户转发,使用前建议先阅读<a href="https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/share.html#使用指引">使用指引</a>;<br />`getPhoneNumber` 获取用户手机号,可以从 bindgetphonenumber 回调中获取到用户信息,<a href="https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/getPhoneNumber.html">具体说明</a> (*小程序插件中不能使用*);<br />`getUserInfo` 获取用户信息,可以从 bindgetuserinfo 回调中获取到用户信息 (*小程序插件中不能使用*);<br />`launchApp` 打开APP,可以通过 app-parameter 属性设定向 APP 传的参数<a href="https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/launchApp.html">具体说明</a>;<br />`openSetting` 打开授权设置页;<br />`feedback` 打开“意见反馈”页面,用户可提交反馈内容并上传<a href="https://developers.weixin.qq.com/miniprogram/dev/api/base/debug/wx.getLogManager.html">日志</a>,开发者可以登录<a href="https://mp.weixin.qq.com/">小程序管理后台</a>后进入左侧菜单“客服反馈”页面获取到反馈内容;<br />`chooseAvatar` 获取用户头像,可以从 bindchooseavatar 回调中获取到头像信息;<br />`agreePrivacyAuthorization`用户同意隐私协议按钮。用户点击一次此按钮后,所有隐私接口可以正常调用。可通过`bindagreeprivacyauthorization`监听用户同意隐私协议事件。隐私合规开发指南详情可见《<a href="https://developers.weixin.qq.com/miniprogram/dev/framework/user-privacy/PrivacyAuthorize.html">小程序隐私协议开发指南</a>》。<br />[小程序官方文档](https://developers.weixin.qq.com/miniprogram/dev/component/button.html)
|
||||
*/
|
||||
openType?:
|
||||
| 'contact'
|
||||
| 'share'
|
||||
| 'getPhoneNumber'
|
||||
| 'getUserInfo'
|
||||
| 'launchApp'
|
||||
| 'openSetting'
|
||||
| 'feedback'
|
||||
| 'chooseAvatar'
|
||||
| 'agreePrivacyAuthorization';
|
||||
/**
|
||||
* 原生按钮属性,当手机号快速验证或手机号实时验证额度用尽时,是否对用户展示“申请获取你的手机号,但该功能使用次数已达当前小程序上限,暂时无法使用”的提示,默认展示,open-type="getPhoneNumber" 或 open-type="getRealtimePhoneNumber" 时有效
|
||||
* @default true
|
||||
*/
|
||||
phoneNumberNoQuotaToast?: boolean;
|
||||
/**
|
||||
* 会话内消息卡片图片,open-type="contact"时有效
|
||||
* @default 截图
|
||||
*/
|
||||
sendMessageImg?: string;
|
||||
/**
|
||||
* 会话内消息卡片点击跳转小程序路径,open-type="contact"时有效
|
||||
* @default 当前分享路径
|
||||
*/
|
||||
sendMessagePath?: string;
|
||||
/**
|
||||
* 会话内消息卡片标题,open-type="contact"时有效
|
||||
* @default 当前标题
|
||||
*/
|
||||
sendMessageTitle?: string;
|
||||
/**
|
||||
* 会话来源,open-type="contact"时有效
|
||||
* @default ''
|
||||
*/
|
||||
sessionFrom?: string;
|
||||
/**
|
||||
* 按钮形状,有 4 种:长方形、正方形、圆角长方形、圆形
|
||||
* @default rectangle
|
||||
*/
|
||||
shape?: 'rectangle' | 'square' | 'round' | 'circle';
|
||||
/**
|
||||
* 是否显示会话内消息卡片,设置此参数为 true,用户进入客服会话会在右下角显示"可能要发送的小程序"提示,用户点击后可以快速发送小程序消息,open-type="contact"时有效
|
||||
* @default false
|
||||
*/
|
||||
showMessageCard?: boolean;
|
||||
/**
|
||||
* 组件尺寸
|
||||
* @default medium
|
||||
*/
|
||||
size?: 'extra-small' | 'small' | 'medium' | 'large';
|
||||
/**
|
||||
* 按钮标签id
|
||||
* @default ''
|
||||
*/
|
||||
tId?: string;
|
||||
/**
|
||||
* 组件风格,依次为品牌色、危险色
|
||||
* @default default
|
||||
*/
|
||||
theme?: 'default' | 'primary' | 'danger' | 'light';
|
||||
/**
|
||||
* 同小程序的 formType
|
||||
*/
|
||||
type?: 'submit' | 'reset';
|
||||
/**
|
||||
* 按钮形式,基础、线框、虚线、文字
|
||||
* @default base
|
||||
*/
|
||||
variant?: 'base' | 'outline' | 'dashed' | 'text';
|
||||
/**
|
||||
* 原生按钮属性,用户同意隐私协议事件回调,open-type=agreePrivacyAuthorization时有效 (Tips: 如果使用 onNeedPrivacyAuthorization 接口,需要在 bindagreeprivacyauthorization 触发后再调用 resolve({ event: "agree", buttonId }))
|
||||
*/
|
||||
onAgreeprivacyauthorization?: () => void;
|
||||
/**
|
||||
* 原生按钮属性,获取用户头像回调,`open-type=chooseAvatar` 时有效。返回 `e.detail.avatarUrl` 为头像临时文件链接
|
||||
*/
|
||||
onChooseavatar?: () => void;
|
||||
/**
|
||||
* 点击时触发
|
||||
*/
|
||||
onClick?: (e: MouseEvent) => void;
|
||||
/**
|
||||
* 原生按钮属性,客服消息回调,`open-type="contact"` 时有效
|
||||
*/
|
||||
onContact?: () => void;
|
||||
/**
|
||||
* 新的一次性订阅消息下发机制回调,`open-type=liveActivity` 时有效
|
||||
*/
|
||||
onCreateliveactivity?: () => void;
|
||||
/**
|
||||
* 原生按钮属性,当使用开放能力时,发生错误的回调,`open-type=launchApp` 时有效
|
||||
*/
|
||||
onError?: () => void;
|
||||
/**
|
||||
* 原生按钮属性,手机号快速验证回调,open-type=getPhoneNumber时有效。Tips:在触发 bindgetphonenumber 回调后应立即隐藏手机号按钮组件,或置为 disabled 状态,避免用户重复授权手机号产生额外费用
|
||||
*/
|
||||
onGetphonenumber?: () => void;
|
||||
/**
|
||||
* 原生按钮属性,手机号实时验证回调,open-type=getRealtimePhoneNumber 时有效。Tips:在触发 bindgetrealtimephonenumber 回调后应立即隐藏手机号按钮组件,或置为 disabled 状态,避免用户重复授权手机号产生额外费用
|
||||
*/
|
||||
onGetrealtimephonenumber?: () => void;
|
||||
/**
|
||||
* 原生按钮属性,用户点击该按钮时,会返回获取到的用户信息,回调的detail数据与wx.getUserInfo返回的一致,open-type="getUserInfo"时有效
|
||||
*/
|
||||
onGetuserinfo?: () => void;
|
||||
/**
|
||||
* 打开 APP 成功的回调,`open-type=launchApp` 时有效
|
||||
*/
|
||||
onLaunchapp?: () => void;
|
||||
/**
|
||||
* 原生按钮属性,在打开授权设置页后回调,open-type=openSetting时有效
|
||||
*/
|
||||
onOpensetting?: () => void;
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
:: BASE_DOC ::
|
||||
|
||||
## API
|
||||
|
||||
### Calendar Props
|
||||
|
||||
name | type | default | description | required
|
||||
-- | -- | -- | -- | --
|
||||
custom-style | Object | - | CSS(Cascading Style Sheets) | N
|
||||
allow-same-day | Boolean | false | \- | N
|
||||
auto-close | Boolean | true | \- | N
|
||||
confirm-btn | String / Object | '' | [see more ts definition](https://github.com/tencent/tdesign-miniprogram/blob/develop/packages/uniapp-components/calendar/type.ts) | N
|
||||
first-day-of-week | Number | 0 | \- | N
|
||||
format | Function | - | Typescript: `CalendarFormatType ` `type CalendarFormatType = (day: TDate) => TDate` `type TDateType = 'selected' \| 'disabled' \| 'start' \| 'start-end' \|'centre' \| 'end' \| ''` `interface TDate { date: Date; day: number; type: TDateType; className?: string; prefix?: string; suffix?: string;}`。[see more ts definition](https://github.com/tencent/tdesign-miniprogram/blob/develop/packages/uniapp-components/calendar/type.ts) | N
|
||||
locale-text | Object | - | Typescript: `CalendarLocaleText` `interface CalendarLocaleText {title?: string; weekdays?: string[]; monthTitle?: string; months?: string[]; confirm?: string;}`。[see more ts definition](https://github.com/tencent/tdesign-miniprogram/blob/develop/packages/uniapp-components/calendar/type.ts) | N
|
||||
max-date | Number | - | \- | N
|
||||
min-date | Number | - | \- | N
|
||||
readonly | Boolean | - | \- | N
|
||||
switch-mode | String | none | options: none/month/year-month | N
|
||||
title | String | - | \- | N
|
||||
type | String | single | options: single/multiple/range | N
|
||||
use-popup | Boolean | true | \- | N
|
||||
using-custom-navbar | Boolean | false | \- | N
|
||||
value | Number / Array | - | `v-model:value` is supported。Typescript: `number \| number[]` | N
|
||||
default-value | Number / Array | - | uncontrolled property。Typescript: `number \| number[]` | N
|
||||
visible | Boolean | false | \- | N
|
||||
|
||||
### Calendar Events
|
||||
|
||||
name | params | description
|
||||
-- | -- | --
|
||||
change | `(context: { value: number \| number[] })` | \-
|
||||
close | `(context: { trigger: CalendarTrigger })` | [see more ts definition](https://github.com/tencent/tdesign-miniprogram/blob/develop/packages/uniapp-components/calendar/type.ts)。<br/>`type CalendarTrigger = 'close-btn' \| 'confirm-btn' \| 'overlay' \| 'auto-close'`<br/>
|
||||
confirm | `(context: { value: number \| number[] })` | \-
|
||||
panel-change | `(context: { year: number, month: number })` | \-
|
||||
scroll | `(context: {scrollLeft: number, scrollTop: number, scrollHeight: number, scrollWidth: number, deltaX: number, deltaY: number})` | triggered when scrolling
|
||||
select | `(context: { value: number \| number[] })` | \-
|
||||
|
||||
### Calendar Slots
|
||||
|
||||
name | Description
|
||||
-- | --
|
||||
confirm-btn | \-
|
||||
title | \-
|
||||
|
||||
### CSS Variables
|
||||
|
||||
The component provides the following CSS variables, which can be used to customize styles.
|
||||
Name | Default Value | Description
|
||||
-- | -- | --
|
||||
--td-calendar-active-color | @brand-color | -
|
||||
--td-calendar-bg-color | @bg-color-container | -
|
||||
--td-calendar-days-color | @text-color-secondary | -
|
||||
--td-calendar-item-centre-color | @brand-color-light | -
|
||||
--td-calendar-item-disabled-color | @text-color-disabled | -
|
||||
--td-calendar-item-suffix-color | @text-color-placeholder | -
|
||||
--td-calendar-radius | 24rpx | -
|
||||
--td-calendar-selected-border-radius | @radius-default | -
|
||||
--td-calendar-selected-color | @text-color-anti | -
|
||||
--td-calendar-switch-mode-icon-color | @text-color-secondary | -
|
||||
--td-calendar-switch-mode-icon-disabled-color | @text-color-disabled | -
|
||||
--td-calendar-title-color | @text-color-primary | -
|
||||
--td-calendar-title-font | @font-title-large | -
|
||||
113
uni_modules/tdesign-uniapp/components/calendar/README.md
Normal file
113
uni_modules/tdesign-uniapp/components/calendar/README.md
Normal file
@@ -0,0 +1,113 @@
|
||||
---
|
||||
title: Calendar 日历
|
||||
description: 按照日历形式展示数据或日期的容器。
|
||||
spline: form
|
||||
isComponent: true
|
||||
---
|
||||
|
||||
|
||||
## 引入
|
||||
|
||||
可在 `main.ts` 或在需要使用的页面或组件中引入。
|
||||
|
||||
```js
|
||||
import TCalendar from '@tdesign/uniapp/calendar/calendar.vue';
|
||||
```
|
||||
|
||||
### 组件类型
|
||||
|
||||
#### 单个选择日历
|
||||
|
||||
{{ base }}
|
||||
|
||||
#### 多个选择日历
|
||||
|
||||
{{ multiple }}
|
||||
|
||||
#### 带单行/双行描述的日历
|
||||
|
||||
{{ custom-text }}
|
||||
|
||||
#### 带翻页功能的日历
|
||||
|
||||
{{ switch-mode }}
|
||||
|
||||
#### 可选择区间日期的日历
|
||||
|
||||
{{ range }}
|
||||
|
||||
### 组件样式
|
||||
|
||||
#### 国际化
|
||||
|
||||
{{ local-text }}
|
||||
|
||||
#### 含不可选的日历
|
||||
|
||||
{{ custom-range }}
|
||||
|
||||
#### 不使用 Popup
|
||||
|
||||
{{ without-popup }}
|
||||
|
||||
## API
|
||||
|
||||
### Calendar Props
|
||||
|
||||
名称 | 类型 | 默认值 | 描述 | 必传
|
||||
-- | -- | -- | -- | --
|
||||
custom-style | Object | - | 自定义样式 | N
|
||||
allow-same-day | Boolean | false | 是否允许区间选择日历的起止时间相同,仅当 `type='range'` 时有效 | N
|
||||
auto-close | Boolean | true | 自动关闭;在点击关闭按钮、确认按钮、遮罩层时自动关闭,不需要手动设置 visible | N
|
||||
confirm-btn | String / Object | '' | 确认按钮。值为 null 则不显示确认按钮。值类型为字符串,则表示自定义按钮文本,值类型为 Object 则表示透传 Button 组件属性。[详细类型定义](https://github.com/tencent/tdesign-miniprogram/blob/develop/packages/uniapp-components/calendar/type.ts) | N
|
||||
first-day-of-week | Number | 0 | 第一天从星期几开始,默认 0 = 周日 | N
|
||||
format | Function | - | 用于格式化日期的函数。TS 类型:`CalendarFormatType ` `type CalendarFormatType = (day: TDate) => TDate` `type TDateType = 'selected' \| 'disabled' \| 'start' \| 'start-end' \|'centre' \| 'end' \| ''` `interface TDate { date: Date; day: number; type: TDateType; className?: string; prefix?: string; suffix?: string;}`。[详细类型定义](https://github.com/tencent/tdesign-miniprogram/blob/develop/packages/uniapp-components/calendar/type.ts) | N
|
||||
locale-text | Object | - | 国际化文案。TS 类型:`CalendarLocaleText` `interface CalendarLocaleText {title?: string; weekdays?: string[]; monthTitle?: string; months?: string[]; confirm?: string;}`。[详细类型定义](https://github.com/tencent/tdesign-miniprogram/blob/develop/packages/uniapp-components/calendar/type.ts) | N
|
||||
max-date | Number | - | 最大可选的日期,不传则默认半年后 | N
|
||||
min-date | Number | - | 最小可选的日期,不传则默认今天 | N
|
||||
readonly | Boolean | - | 是否只读,只读状态下不能选择日期 | N
|
||||
switch-mode | String | none | 切换模式。 `none` 表示平铺展示所有月份; `month` 表示支持按月切换, `year-month` 表示既按年切换,也支持按月切换。可选项:none/month/year-month | N
|
||||
title | String | - | 标题,不传默认为“请选择日期” | N
|
||||
type | String | single | 日历的选择类型,single = 单选;multiple = 多选; range = 区间选择。可选项:single/multiple/range | N
|
||||
use-popup | Boolean | true | 是否使用弹出层包裹日历 | N
|
||||
using-custom-navbar | Boolean | false | 是否使用了自定义导航栏 | N
|
||||
value | Number / Array | - | 当前选择的日期,不传则选用 minDate 属性值或今天,优先级:minDate > today。当 type = multiple 或 range 时传入数组。支持语法糖 `v-model:value`。TS 类型:`number \| number[]` | N
|
||||
default-value | Number / Array | - | 当前选择的日期,不传则选用 minDate 属性值或今天,优先级:minDate > today。当 type = multiple 或 range 时传入数组。非受控属性。TS 类型:`number \| number[]` | N
|
||||
visible | Boolean | false | 是否显示日历;`usePopup` 为 true 时有效 | N
|
||||
|
||||
### Calendar Events
|
||||
|
||||
名称 | 参数 | 描述
|
||||
-- | -- | --
|
||||
change | `(context: { value: number \| number[] })` | 不显示 confirm-btn 时,完成选择时触发(暂不支持 type = multiple)
|
||||
close | `(context: { trigger: CalendarTrigger })` | 关闭按钮时触发。[详细类型定义](https://github.com/tencent/tdesign-miniprogram/blob/develop/packages/uniapp-components/calendar/type.ts)。<br/>`type CalendarTrigger = 'close-btn' \| 'confirm-btn' \| 'overlay' \| 'auto-close'`<br/>
|
||||
confirm | `(context: { value: number \| number[] })` | 点击确认按钮时触发
|
||||
panel-change | `(context: { year: number, month: number })` | 切换月或年时触发(switch-mode 不为 none 时有效)
|
||||
scroll | `(context: {scrollLeft: number, scrollTop: number, scrollHeight: number, scrollWidth: number, deltaX: number, deltaY: number})` | 滚动时触发
|
||||
select | `(context: { value: number \| number[] })` | 点击日期时触发
|
||||
|
||||
### Calendar Slots
|
||||
|
||||
名称 | 描述
|
||||
-- | --
|
||||
confirm-btn | 确认按钮
|
||||
title | 标题
|
||||
|
||||
### CSS Variables
|
||||
|
||||
组件提供了下列 CSS 变量,可用于自定义样式。
|
||||
名称 | 默认值 | 描述
|
||||
-- | -- | --
|
||||
--td-calendar-active-color | @brand-color | -
|
||||
--td-calendar-bg-color | @bg-color-container | -
|
||||
--td-calendar-days-color | @text-color-secondary | -
|
||||
--td-calendar-item-centre-color | @brand-color-light | -
|
||||
--td-calendar-item-disabled-color | @text-color-disabled | -
|
||||
--td-calendar-item-suffix-color | @text-color-placeholder | -
|
||||
--td-calendar-radius | 24rpx | -
|
||||
--td-calendar-selected-border-radius | @radius-default | -
|
||||
--td-calendar-selected-color | @text-color-anti | -
|
||||
--td-calendar-switch-mode-icon-color | @text-color-secondary | -
|
||||
--td-calendar-switch-mode-icon-disabled-color | @text-color-disabled | -
|
||||
--td-calendar-title-color | @text-color-primary | -
|
||||
--td-calendar-title-font | @font-title-large | -
|
||||
@@ -0,0 +1,42 @@
|
||||
export default {
|
||||
tClass: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
classPrefix: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
switchMode: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
preYearBtnDisable: {
|
||||
type: Boolean,
|
||||
},
|
||||
prevMonthBtnDisable: {
|
||||
type: Boolean,
|
||||
},
|
||||
nextYearBtnDisable: {
|
||||
type: Boolean,
|
||||
},
|
||||
nextMonthBtnDisable: {
|
||||
type: Boolean,
|
||||
},
|
||||
tId: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
// realLocalText: {
|
||||
// type: Object,
|
||||
// default: () => ({}),
|
||||
// },
|
||||
// currentMonth: {
|
||||
// type: Array,
|
||||
// default: () => ([]),
|
||||
// },
|
||||
};
|
||||
@@ -0,0 +1,98 @@
|
||||
<template>
|
||||
<view
|
||||
:id="tId"
|
||||
:class="' ' + tClass + ' ' + classPrefix + ' '+(switchMode !== 'none' ? classPrefix + '__with-action' : '')"
|
||||
>
|
||||
<view
|
||||
v-if="switchMode !== 'none'"
|
||||
:class="classPrefix + '__action'"
|
||||
>
|
||||
<view
|
||||
v-if="switchMode === 'year-month'"
|
||||
:class="utils.cls(classPrefix + '__icon', [['disabled', preYearBtnDisable]])"
|
||||
:data-disabled="preYearBtnDisable"
|
||||
data-type="pre-year"
|
||||
@click="handleSwitchModeChange"
|
||||
>
|
||||
<t-icon name="chevron-left-double" />
|
||||
</view>
|
||||
<view
|
||||
:class="utils.cls(classPrefix + '__icon', [['disabled', prevMonthBtnDisable]])"
|
||||
:data-disabled="prevMonthBtnDisable"
|
||||
data-type="pre-month"
|
||||
@click="handleSwitchModeChange"
|
||||
>
|
||||
<t-icon name="chevron-left" />
|
||||
</view>
|
||||
</view>
|
||||
<view :class="classPrefix + '__title'">
|
||||
{{ title }}
|
||||
</view>
|
||||
<view
|
||||
v-if="switchMode !== 'none'"
|
||||
:class="classPrefix + '__action'"
|
||||
>
|
||||
<view
|
||||
:class="utils.cls(classPrefix + '__icon', [['disabled', nextMonthBtnDisable]])"
|
||||
:data-disabled="nextMonthBtnDisable"
|
||||
data-type="next-month"
|
||||
@click="handleSwitchModeChange"
|
||||
>
|
||||
<t-icon name="chevron-right" />
|
||||
</view>
|
||||
<view
|
||||
v-if="switchMode === 'year-month'"
|
||||
:class="utils.cls(classPrefix + '__icon', [['disabled', nextYearBtnDisable]])"
|
||||
:data-disabled="nextYearBtnDisable"
|
||||
data-type="next-year"
|
||||
@click="handleSwitchModeChange"
|
||||
>
|
||||
<t-icon name="chevron-right-double" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import TIcon from '../icon/icon.vue';
|
||||
import utils from '../common/utils.wxs';
|
||||
import props from './calendar-header.props';
|
||||
import { getMonthTitle } from './computed';
|
||||
|
||||
export default {
|
||||
name: 'TCalendarHeader',
|
||||
options: {
|
||||
styleIsolation: 'shared',
|
||||
},
|
||||
components: {
|
||||
TIcon,
|
||||
},
|
||||
props: {
|
||||
...props,
|
||||
},
|
||||
emits: [
|
||||
'handleSwitchModeChange',
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
utils,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
|
||||
},
|
||||
mounted() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
handleSwitchModeChange(...args) {
|
||||
this.$emit('handleSwitchModeChange', ...args);
|
||||
},
|
||||
getMonthTitle,
|
||||
},
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@import './calendar.css';
|
||||
</style>
|
||||
205
uni_modules/tdesign-uniapp/components/calendar/calendar.css
Normal file
205
uni_modules/tdesign-uniapp/components/calendar/calendar.css
Normal file
@@ -0,0 +1,205 @@
|
||||
.t-calendar {
|
||||
width: inherit;
|
||||
position: relative;
|
||||
z-index: 9999;
|
||||
background: var(--td-calendar-bg-color, var(--td-bg-color-container, var(--td-font-white-1, #ffffff)));
|
||||
overflow-x: hidden;
|
||||
}
|
||||
.t-calendar--popup {
|
||||
border-top-left-radius: var(--td-calendar-radius, 24rpx);
|
||||
border-top-right-radius: var(--td-calendar-radius, 24rpx);
|
||||
}
|
||||
.t-calendar__title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font: var(--td-calendar-title-font, var(--td-font-title-large, 600 36rpx / 52rpx var(--td-font-family, PingFang SC, Microsoft YaHei, Arial Regular)));
|
||||
color: var(--td-calendar-title-color, var(--td-text-color-primary, var(--td-font-gray-1, rgba(0, 0, 0, 0.9))));
|
||||
padding: var(--td-spacer-2, 32rpx);
|
||||
}
|
||||
.t-calendar__title:focus {
|
||||
outline: 0;
|
||||
}
|
||||
.t-calendar__close-btn {
|
||||
position: absolute;
|
||||
top: var(--td-spacer-2, 32rpx);
|
||||
right: var(--td-spacer-2, 32rpx);
|
||||
margin: calc(-1 * var(--td-spacer-1, 24rpx));
|
||||
padding: var(--td-spacer-1, 24rpx);
|
||||
color: var(--td-calendar-title-color, var(--td-text-color-primary, var(--td-font-gray-1, rgba(0, 0, 0, 0.9))));
|
||||
}
|
||||
.t-calendar__days {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(7, 1fr);
|
||||
grid-column-gap: 8rpx;
|
||||
padding: 0 32rpx;
|
||||
text-align: center;
|
||||
line-height: 92rpx;
|
||||
}
|
||||
.t-calendar__days-item {
|
||||
height: 92rpx;
|
||||
font-size: 28rpx;
|
||||
color: var(--td-calendar-days-color, var(--td-text-color-secondary, var(--td-font-gray-2, rgba(0, 0, 0, 0.6))));
|
||||
}
|
||||
.t-calendar__content {
|
||||
min-height: 400rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.t-calendar__month {
|
||||
font: var(--td-font-title-small, 600 28rpx / 44rpx var(--td-font-family, PingFang SC, Microsoft YaHei, Arial Regular));
|
||||
color: var(--td-calendar-title-color, var(--td-text-color-primary, var(--td-font-gray-1, rgba(0, 0, 0, 0.9))));
|
||||
padding: 32rpx 0 0;
|
||||
}
|
||||
.t-calendar__months {
|
||||
height: 712rpx;
|
||||
padding: 0 32rpx 32rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.t-calendar__months::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
.t-calendar__dates {
|
||||
flex: 1;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(7, 1fr);
|
||||
grid-column-gap: 8rpx;
|
||||
}
|
||||
.t-calendar__dates-item {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font: var(--td-font-title-medium, 600 32rpx / 48rpx var(--td-font-family, PingFang SC, Microsoft YaHei, Arial Regular));
|
||||
border-radius: var(--td-calendar-selected-border-radius, var(--td-radius-default, 12rpx));
|
||||
height: 120rpx;
|
||||
margin-top: 16rpx;
|
||||
color: var(--td-calendar-title-color, var(--td-text-color-primary, var(--td-font-gray-1, rgba(0, 0, 0, 0.9))));
|
||||
cursor: pointer;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
-webkit-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
.t-calendar__dates-item-prefix,
|
||||
.t-calendar__dates-item-suffix {
|
||||
position: absolute;
|
||||
font: var(--td-font-body-extraSmall, 20rpx / 32rpx var(--td-font-family, PingFang SC, Microsoft YaHei, Arial Regular));
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
.t-calendar__dates-item-prefix {
|
||||
top: 8rpx;
|
||||
}
|
||||
.t-calendar__dates-item-suffix {
|
||||
bottom: 8rpx;
|
||||
color: var(--td-calendar-item-suffix-color, var(--td-text-color-placeholder, var(--td-font-gray-3, rgba(0, 0, 0, 0.4))));
|
||||
}
|
||||
.t-calendar__dates-item-suffix--selected,
|
||||
.t-calendar__dates-item-suffix--start,
|
||||
.t-calendar__dates-item-suffix--end {
|
||||
color: var(--td-calendar-selected-color, var(--td-text-color-anti, var(--td-font-white-1, #ffffff)));
|
||||
}
|
||||
.t-calendar__dates-item-suffix--disabled {
|
||||
color: var(--td-calendar-item-disabled-color, var(--td-text-color-disabled, var(--td-font-gray-4, rgba(0, 0, 0, 0.26))));
|
||||
}
|
||||
.t-calendar__dates-item--selected,
|
||||
.t-calendar__dates-item--start-end,
|
||||
.t-calendar__dates-item--start,
|
||||
.t-calendar__dates-item--end {
|
||||
background: var(--td-calendar-active-color, var(--td-brand-color, var(--td-primary-color-7, #0052d9)));
|
||||
color: var(--td-calendar-selected-color, var(--td-text-color-anti, var(--td-font-white-1, #ffffff)));
|
||||
border-radius: var(--td-calendar-selected-border-radius, var(--td-radius-default, 12rpx));
|
||||
}
|
||||
.t-calendar__dates-item--start {
|
||||
border-radius: var(--td-calendar-selected-border-radius, var(--td-radius-default, 12rpx)) 0 0 var(--td-calendar-selected-border-radius, var(--td-radius-default, 12rpx));
|
||||
}
|
||||
.t-calendar__dates-item--end {
|
||||
border-radius: 0 var(--td-calendar-selected-border-radius, var(--td-radius-default, 12rpx)) var(--td-calendar-selected-border-radius, var(--td-radius-default, 12rpx)) 0;
|
||||
}
|
||||
.t-calendar__dates-item--start + .t-calendar__dates-item--end::before {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 8rpx;
|
||||
height: 100%;
|
||||
background: var(--td-calendar-active-color, var(--td-brand-color, var(--td-primary-color-7, #0052d9)));
|
||||
}
|
||||
.t-calendar__dates-item--start + .t-calendar__dates-item--end:before {
|
||||
left: -8rpx;
|
||||
}
|
||||
.t-calendar__dates-item--centre {
|
||||
border-radius: 0;
|
||||
background-color: var(--td-calendar-item-centre-color, var(--td-brand-color-light, var(--td-primary-color-1, #f2f3ff)));
|
||||
}
|
||||
.t-calendar__dates-item--centre::before,
|
||||
.t-calendar__dates-item--centre::after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 8rpx;
|
||||
height: 100%;
|
||||
background-color: var(--td-calendar-item-centre-color, var(--td-brand-color-light, var(--td-primary-color-1, #f2f3ff)));
|
||||
}
|
||||
.t-calendar__dates-item--centre:before {
|
||||
left: -8rpx;
|
||||
}
|
||||
.t-calendar__dates-item--centre:after {
|
||||
right: -8rpx;
|
||||
}
|
||||
.t-calendar__dates-item--disabled {
|
||||
color: var(--td-calendar-item-disabled-color, var(--td-text-color-disabled, var(--td-font-gray-4, rgba(0, 0, 0, 0.26))));
|
||||
cursor: default;
|
||||
}
|
||||
.t-calendar__footer {
|
||||
padding: 32rpx;
|
||||
}
|
||||
.t-calendar-switch-mode--none > .t-calendar__months {
|
||||
height: 60vh;
|
||||
}
|
||||
.t-calendar-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.t-calendar-header__with-action {
|
||||
padding: 0rpx 32rpx 16rpx 32rpx;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
}
|
||||
.t-calendar-header__with-action::after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: unset;
|
||||
bottom: 0;
|
||||
left: unset;
|
||||
right: unset;
|
||||
background-color: var(--td-border-color, var(--td-gray-color-3, #e7e7e7));
|
||||
}
|
||||
.t-calendar-header__with-action::after {
|
||||
height: 1px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
transform: scaleY(0.5);
|
||||
}
|
||||
.t-calendar-header__with-action .t-calendar-header__title {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
font: var(--td-font-title-small, 600 28rpx / 44rpx var(--td-font-family, PingFang SC, Microsoft YaHei, Arial Regular));
|
||||
}
|
||||
.t-calendar-header__action {
|
||||
display: flex;
|
||||
font-size: 40rpx;
|
||||
color: var(--td-calendar-switch-mode-icon-color, var(--td-text-color-secondary, var(--td-font-gray-2, rgba(0, 0, 0, 0.6))));
|
||||
}
|
||||
.t-calendar-header__icon {
|
||||
padding: 16rpx;
|
||||
}
|
||||
.t-calendar-header__icon--disabled {
|
||||
color: var(--td-calendar-switch-mode-icon-disabled-color, var(--td-text-color-disabled, var(--td-font-gray-4, rgba(0, 0, 0, 0.26))));
|
||||
}
|
||||
.t-calendar-header__title {
|
||||
text-align: left;
|
||||
}
|
||||
454
uni_modules/tdesign-uniapp/components/calendar/calendar.vue
Normal file
454
uni_modules/tdesign-uniapp/components/calendar/calendar.vue
Normal file
@@ -0,0 +1,454 @@
|
||||
<template>
|
||||
<view>
|
||||
<t-popup
|
||||
v-if="usePopup"
|
||||
:visible="visible"
|
||||
:using-custom-navbar="usingCustomNavbar"
|
||||
:custom-navbar-height="customNavbarHeight"
|
||||
placement="bottom"
|
||||
@visible-change="onVisibleChange"
|
||||
>
|
||||
<CalendarTemplate
|
||||
:class-prefix="classPrefix"
|
||||
:use-popup="usePopup"
|
||||
:switch-mode="switchMode"
|
||||
:t-class="tClass"
|
||||
:custom-style="tools._style([customStyle])"
|
||||
:title="title"
|
||||
:real-local-text="realLocalText"
|
||||
:months="months"
|
||||
:current-month="currentMonth"
|
||||
:action-buttons="actionButtons"
|
||||
:days="days"
|
||||
:scroll-into-view="scrollIntoView"
|
||||
:first-day-of-week="firstDayOfWeek"
|
||||
:inner-confirm-btn="innerConfirmBtn"
|
||||
@scroll="onScroll"
|
||||
@close="handleClose"
|
||||
@select="handleSelect"
|
||||
@clickButton="onTplButtonTap"
|
||||
@handleSwitchModeChange="handleSwitchModeChange"
|
||||
>
|
||||
<template #confirm-btn>
|
||||
<slot name="confirm-btn" />
|
||||
</template>
|
||||
<template #title>
|
||||
<slot name="title" />
|
||||
</template>
|
||||
</CalendarTemplate>
|
||||
</t-popup>
|
||||
<block v-else>
|
||||
<CalendarTemplate
|
||||
:class-prefix="classPrefix"
|
||||
:use-popup="usePopup"
|
||||
:switch-mode="switchMode"
|
||||
:t-class="tClass"
|
||||
:custom-style="tools._style([customStyle])"
|
||||
:title="title"
|
||||
:real-local-text="realLocalText"
|
||||
:months="months"
|
||||
:current-month="currentMonth"
|
||||
:action-buttons="actionButtons"
|
||||
:days="days"
|
||||
:scroll-into-view="scrollIntoView"
|
||||
:first-day-of-week="firstDayOfWeek"
|
||||
:inner-confirm-btn="innerConfirmBtn"
|
||||
@scroll="onScroll"
|
||||
@close="handleClose"
|
||||
@select="handleSelect"
|
||||
@clickButton="onTplButtonTap"
|
||||
@handleSwitchModeChange="handleSwitchModeChange"
|
||||
>
|
||||
<template #confirm-btn>
|
||||
<slot name="confirm-btn" />
|
||||
</template>
|
||||
<template #title>
|
||||
<slot name="title" />
|
||||
</template>
|
||||
</CalendarTemplate>
|
||||
</block>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import TPopup from '../popup/popup';
|
||||
import TButton from '../button/button';
|
||||
import TIcon from '../icon/icon';
|
||||
import CalendarTemplate from './template.vue';
|
||||
|
||||
import { uniComponent } from '../common/src/index';
|
||||
import { prefix } from '../common/config';
|
||||
import { coalesce } from '../common/utils';
|
||||
|
||||
import props from './props';
|
||||
import TCalendar from '../common/shared/calendar/index';
|
||||
import useCustomNavbar from '../mixins/using-custom-navbar';
|
||||
import { getPrevMonth, getPrevYear, getNextMonth, getNextYear } from './utils';
|
||||
import tools from '../common/utils.wxs';
|
||||
import {
|
||||
getMonthTitle,
|
||||
getDateLabel,
|
||||
isDateSelected,
|
||||
} from './computed.js';
|
||||
|
||||
|
||||
const name = `${prefix}-calendar`;
|
||||
|
||||
|
||||
const defaultLocaleText = {
|
||||
title: '请选择日期',
|
||||
weekdays: ['日', '一', '二', '三', '四', '五', '六'],
|
||||
monthTitle: '{year} 年 {month}',
|
||||
months: ['1 月', '2 月', '3 月', '4 月', '5 月', '6 月', '7 月', '8 月', '9 月', '10 月', '11 月', '12 月'],
|
||||
confirm: '确认',
|
||||
};
|
||||
|
||||
export default uniComponent({
|
||||
name,
|
||||
options: {
|
||||
styleIsolation: 'shared',
|
||||
},
|
||||
controlledProps: [
|
||||
{
|
||||
key: 'value',
|
||||
event: 'confirm',
|
||||
},
|
||||
{
|
||||
key: 'value',
|
||||
event: 'change',
|
||||
},
|
||||
],
|
||||
externalClasses: [
|
||||
`${prefix}-class`,
|
||||
],
|
||||
mixins: [useCustomNavbar],
|
||||
components: {
|
||||
TPopup,
|
||||
TButton,
|
||||
TIcon,
|
||||
CalendarTemplate,
|
||||
},
|
||||
props: {
|
||||
...props,
|
||||
},
|
||||
emits: [
|
||||
'update:visible',
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
prefix,
|
||||
classPrefix: name,
|
||||
months: [],
|
||||
scrollIntoView: '',
|
||||
innerConfirmBtn: {},
|
||||
realLocalText: {},
|
||||
currentMonth: {},
|
||||
actionButtons: {
|
||||
preYearBtnDisable: false,
|
||||
prevMonthBtnDisable: false,
|
||||
nextMonthBtnDisable: false,
|
||||
nextYearBtnDisable: false,
|
||||
},
|
||||
tools,
|
||||
|
||||
dataVisible: this.visible,
|
||||
dataValue: coalesce(this.value, this.defaultValue),
|
||||
days: [],
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
type: {
|
||||
handler(v) {
|
||||
this.base.type = v;
|
||||
},
|
||||
},
|
||||
|
||||
allowSameDay(v) {
|
||||
this.base.allowSameDay = v;
|
||||
},
|
||||
|
||||
confirmBtn: {
|
||||
handler(v) {
|
||||
if (typeof v === 'string') {
|
||||
this.innerConfirmBtn = v === 'slot' ? 'slot' : { content: v };
|
||||
} else if (typeof v === 'object') {
|
||||
this.innerConfirmBtn = v;
|
||||
}
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
|
||||
firstDayOfWeek: 'onWatchMinMaxDate',
|
||||
minDate: 'onWatchMinMaxDate',
|
||||
maxDate: 'onWatchMinMaxDate',
|
||||
|
||||
value: {
|
||||
handler(v) {
|
||||
this.dataValue = v;
|
||||
},
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
|
||||
visible: {
|
||||
handler(v) {
|
||||
this.dataVisible = v;
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
|
||||
dataValue: {
|
||||
handler(v) {
|
||||
this.base.value = v;
|
||||
this.calcMonths();
|
||||
this.updateCurrentMonth(Array.isArray(v) ? v[0] : v);
|
||||
},
|
||||
deep: true,
|
||||
},
|
||||
|
||||
dataVisible: {
|
||||
handler(v) {
|
||||
if (v) {
|
||||
this.onScrollIntoView();
|
||||
this.base.value = this.dataValue;
|
||||
this.calcMonths();
|
||||
}
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
format: {
|
||||
handler(v) {
|
||||
const { usePopup, dataVisible: visible } = this;
|
||||
|
||||
if (this.base) {
|
||||
this.base.format = v;
|
||||
}
|
||||
|
||||
if (!usePopup || visible) {
|
||||
this.calcMonths();
|
||||
}
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
},
|
||||
created() {
|
||||
const values = Object.keys(props).reduce((acc, key) => ({
|
||||
...acc,
|
||||
[key]: this[key],
|
||||
}));
|
||||
this.base = new TCalendar(values);
|
||||
},
|
||||
|
||||
mounted() {
|
||||
const realLocalText = { ...defaultLocaleText, ...this.localeText };
|
||||
this.initialValue();
|
||||
this.onWatchMinMaxDate();
|
||||
this.days = this.base.getDays(realLocalText.weekdays);
|
||||
this.realLocalText = realLocalText;
|
||||
|
||||
this.calcMonths();
|
||||
this.updateCurrentMonth();
|
||||
|
||||
if (!this.usePopup) {
|
||||
this.onScrollIntoView();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getMonthTitle,
|
||||
getDateLabel,
|
||||
isDateSelected,
|
||||
initialValue() {
|
||||
const { dataValue: value, type, minDate } = this;
|
||||
|
||||
if (!value) {
|
||||
const today = new Date();
|
||||
const now = minDate || new Date(today.getFullYear(), today.getMonth(), today.getDate()).getTime(); // 获取 0 点的时间戳
|
||||
const initialValue = type === 'single' ? now : [now];
|
||||
|
||||
if (type === 'range') {
|
||||
initialValue[1] = now + 24 * 3600 * 1000; // 第二天
|
||||
}
|
||||
|
||||
this.dataValue = initialValue;
|
||||
this.base.value = initialValue;
|
||||
}
|
||||
},
|
||||
|
||||
onScrollIntoView() {
|
||||
const { dataValue: value } = this;
|
||||
|
||||
if (!value) return;
|
||||
|
||||
const date = new Date(Array.isArray(value) ? value[0] : value);
|
||||
|
||||
if (date) {
|
||||
this.scrollIntoView = `year_${date.getFullYear()}_month_${date.getMonth()}`;
|
||||
}
|
||||
},
|
||||
|
||||
getCurrentYearAndMonth(v) {
|
||||
const date = new Date(v);
|
||||
return { year: date.getFullYear(), month: date.getMonth() };
|
||||
},
|
||||
|
||||
updateActionButton(value) {
|
||||
const _min = this.getCurrentYearAndMonth(this.base.minDate);
|
||||
const _max = this.getCurrentYearAndMonth(this.base.maxDate);
|
||||
const _value = this.getCurrentYearAndMonth(value);
|
||||
|
||||
const _minTimestamp = new Date(_min.year, _min.month, 1).getTime();
|
||||
const _maxTimestamp = new Date(_max.year, _max.month, 1).getTime();
|
||||
const _dateValue = new Date(_value.year, _value.month, 1);
|
||||
|
||||
const _prevYearTimestamp = getPrevYear(_dateValue).getTime();
|
||||
const _prevMonthTimestamp = getPrevMonth(_dateValue).getTime();
|
||||
const _nextMonthTimestamp = getNextMonth(_dateValue).getTime();
|
||||
const _nextYearTimestamp = getNextYear(_dateValue).getTime();
|
||||
|
||||
const preYearBtnDisable = _prevYearTimestamp < _minTimestamp || _prevMonthTimestamp < _minTimestamp;
|
||||
const prevMonthBtnDisable = _prevMonthTimestamp < _minTimestamp;
|
||||
const nextYearBtnDisable = _nextMonthTimestamp > _maxTimestamp || _nextYearTimestamp > _maxTimestamp;
|
||||
const nextMonthBtnDisable = _nextMonthTimestamp > _maxTimestamp;
|
||||
|
||||
this.actionButtons = {
|
||||
preYearBtnDisable,
|
||||
prevMonthBtnDisable,
|
||||
nextYearBtnDisable,
|
||||
nextMonthBtnDisable,
|
||||
};
|
||||
},
|
||||
|
||||
updateCurrentMonth(newValue) {
|
||||
if (this.switchMode === 'none') return;
|
||||
this.calcCurrentMonth(newValue);
|
||||
},
|
||||
|
||||
calcCurrentMonth(newValue) {
|
||||
const date = newValue || this.getCurrentDate();
|
||||
const { year, month } = this.getCurrentYearAndMonth(date);
|
||||
const currentMonth = this.months.filter(item => item.year === year && item.month === month);
|
||||
|
||||
this.updateActionButton(date);
|
||||
|
||||
this.currentMonth = currentMonth.length > 0 ? currentMonth : [this.months[0]];
|
||||
},
|
||||
|
||||
calcMonths() {
|
||||
if (!this.base) return;
|
||||
|
||||
const months = this.base.getMonths();
|
||||
|
||||
this.months = months;
|
||||
},
|
||||
|
||||
close(trigger) {
|
||||
if (this.autoClose) {
|
||||
this.$emit('update:visible', false);
|
||||
this.dataVisible = false;
|
||||
}
|
||||
this.$emit('close', { trigger });
|
||||
},
|
||||
|
||||
onVisibleChange() {
|
||||
this.close('overlay');
|
||||
},
|
||||
|
||||
handleClose() {
|
||||
this.close('close-btn');
|
||||
},
|
||||
|
||||
handleSelect(e) {
|
||||
const { readonly } = this;
|
||||
const { date, year, month } = e.currentTarget.dataset;
|
||||
|
||||
if (date.type === 'disabled' || readonly) return;
|
||||
|
||||
const rawValue = this.base.select({ cellType: date.type, year, month, date: date.day });
|
||||
|
||||
const value = this.toTime(rawValue);
|
||||
|
||||
this.calcMonths();
|
||||
this.updateCurrentMonth();
|
||||
|
||||
if (this.confirmBtn == null) {
|
||||
// 不显示确认按钮,则选择完即关闭 popup
|
||||
if (this.type === 'single' || rawValue.length === 2) {
|
||||
this.dataVisible = false;
|
||||
this._trigger('change', { value }); // 受控
|
||||
}
|
||||
}
|
||||
|
||||
this.$emit('select', { value });
|
||||
},
|
||||
|
||||
onTplButtonTap() {
|
||||
const rawValue = this.base.getTrimValue();
|
||||
const value = this.toTime(rawValue);
|
||||
|
||||
this.close('confirm-btn');
|
||||
this._trigger('confirm', { value });
|
||||
},
|
||||
|
||||
toTime(val) {
|
||||
if (!val) return null;
|
||||
if (Array.isArray(val)) {
|
||||
return val.map(item => item.getTime());
|
||||
}
|
||||
return val.getTime();
|
||||
},
|
||||
|
||||
onScroll(e) {
|
||||
this.$emit('scroll', e.detail);
|
||||
},
|
||||
|
||||
getCurrentDate() {
|
||||
let time = Array.isArray(this.base.value) ? this.base.value[0] : this.base.value;
|
||||
|
||||
if (this.currentMonth.length > 0) {
|
||||
const year = this.currentMonth[0]?.year;
|
||||
const month = this.currentMonth[0]?.month;
|
||||
time = new Date(year, month, 1).getTime();
|
||||
}
|
||||
|
||||
return time;
|
||||
},
|
||||
|
||||
handleSwitchModeChange(e) {
|
||||
const { type, disabled } = e.currentTarget.dataset;
|
||||
if (disabled) return;
|
||||
|
||||
const date = this.getCurrentDate();
|
||||
|
||||
const funcMap = {
|
||||
'pre-year': () => getPrevYear(date),
|
||||
'pre-month': () => getPrevMonth(date),
|
||||
'next-month': () => getNextMonth(date),
|
||||
'next-year': () => getNextYear(date),
|
||||
};
|
||||
const newValue = funcMap[type]();
|
||||
if (!newValue) return;
|
||||
|
||||
const { year, month } = this.getCurrentYearAndMonth(newValue);
|
||||
this.$emit('panel-change', { year, month: month + 1 });
|
||||
|
||||
this.calcCurrentMonth(newValue);
|
||||
},
|
||||
|
||||
onWatchMinMaxDate() {
|
||||
const { firstDayOfWeek, minDate, maxDate } = this;
|
||||
firstDayOfWeek && (this.base.firstDayOfWeek = firstDayOfWeek);
|
||||
minDate && (this.base.minDate = minDate);
|
||||
maxDate && (this.base.maxDate = maxDate);
|
||||
this.calcMonths();
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style scoped>
|
||||
@import './calendar.css';
|
||||
</style>
|
||||
<style scoped>
|
||||
.t-calendar-switch-mode--none > .t-calendar__months {
|
||||
/* support mp-alipay */
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
42
uni_modules/tdesign-uniapp/components/calendar/computed.js
Normal file
42
uni_modules/tdesign-uniapp/components/calendar/computed.js
Normal file
@@ -0,0 +1,42 @@
|
||||
import { getRegExp } from '../common/runtime/wxs-polyfill';
|
||||
|
||||
|
||||
export function isDateSelected(dateItem) {
|
||||
return ['start', 'end', 'selected', 'centre'].indexOf(dateItem.type) >= 0;
|
||||
}
|
||||
|
||||
export function getMonthTitle(year, month, pattern = '') {
|
||||
// prettier-ignore
|
||||
const REGEXP = getRegExp('\\{year\\}|\\{month\\}', 'g');
|
||||
|
||||
return pattern.replace(REGEXP, (match) => {
|
||||
const replacements = {
|
||||
'{year}': year,
|
||||
'{month}': month < 10 ? `0${month}` : month,
|
||||
};
|
||||
return replacements[match] || match;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
export function getDateLabel(monthItem, dateItem) {
|
||||
const weekdayText = ['日', '一', '二', '三', '四', '五', '六'];
|
||||
const weekday = (monthItem.weekdayOfFirstDay + dateItem.day - 1) % 7;
|
||||
let label = `${monthItem.month + 1}月${dateItem.day}日, 星期${weekdayText[weekday]}`;
|
||||
if (dateItem.type === 'start') {
|
||||
label = `开始日期:${label}`;
|
||||
}
|
||||
if (dateItem.type === 'end') {
|
||||
label = `结束日期:${label}`;
|
||||
}
|
||||
if (isDateSelected(dateItem)) {
|
||||
label = `已选中, ${label}`;
|
||||
}
|
||||
if (dateItem.prefix) {
|
||||
label += `, ${dateItem.prefix}`;
|
||||
}
|
||||
if (dateItem.suffix) {
|
||||
label += `, ${dateItem.suffix}`;
|
||||
}
|
||||
return label;
|
||||
}
|
||||
113
uni_modules/tdesign-uniapp/components/calendar/props.ts
Normal file
113
uni_modules/tdesign-uniapp/components/calendar/props.ts
Normal file
@@ -0,0 +1,113 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
|
||||
* */
|
||||
|
||||
import type { TdCalendarProps } from './type';
|
||||
export default {
|
||||
/** 是否允许区间选择日历的起止时间相同,仅当 `type='range'` 时有效 */
|
||||
allowSameDay: Boolean,
|
||||
/** 自动关闭;在点击关闭按钮、确认按钮、遮罩层时自动关闭,不需要手动设置 visible */
|
||||
autoClose: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
/** 确认按钮。值为 null 则不显示确认按钮。值类型为字符串,则表示自定义按钮文本,值类型为 Object 则表示透传 Button 组件属性 */
|
||||
confirmBtn: {
|
||||
type: [String, Object],
|
||||
default: '' as TdCalendarProps['confirmBtn'],
|
||||
},
|
||||
/** 第一天从星期几开始,默认 0 = 周日 */
|
||||
firstDayOfWeek: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
/** 用于格式化日期的函数 */
|
||||
format: {
|
||||
type: Function,
|
||||
},
|
||||
/** 国际化文案 */
|
||||
localeText: {
|
||||
type: Object,
|
||||
},
|
||||
/** 最大可选的日期,不传则默认半年后 */
|
||||
maxDate: {
|
||||
type: Number,
|
||||
},
|
||||
/** 最小可选的日期,不传则默认今天 */
|
||||
minDate: {
|
||||
type: Number,
|
||||
},
|
||||
/** 是否只读,只读状态下不能选择日期 */
|
||||
readonly: Boolean,
|
||||
/** 切换模式。 `none` 表示平铺展示所有月份; `month` 表示支持按月切换, `year-month` 表示既按年切换,也支持按月切换 */
|
||||
switchMode: {
|
||||
type: String,
|
||||
default: 'none' as TdCalendarProps['switchMode'],
|
||||
validator(val: TdCalendarProps['switchMode']): boolean {
|
||||
if (!val) return true;
|
||||
return ['none', 'month', 'year-month'].includes(val);
|
||||
},
|
||||
},
|
||||
/** 标题,不传默认为“请选择日期” */
|
||||
title: {
|
||||
type: String,
|
||||
},
|
||||
/** 日历的选择类型,single = 单选;multiple = 多选; range = 区间选择 */
|
||||
type: {
|
||||
type: String,
|
||||
default: 'single' as TdCalendarProps['type'],
|
||||
validator(val: TdCalendarProps['type']): boolean {
|
||||
if (!val) return true;
|
||||
return ['single', 'multiple', 'range'].includes(val);
|
||||
},
|
||||
},
|
||||
/** 是否使用弹出层包裹日历 */
|
||||
usePopup: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
/** 是否使用了自定义导航栏 */
|
||||
usingCustomNavbar: Boolean,
|
||||
/** 当前选择的日期,不传则选用 minDate 属性值或今天,优先级:minDate > today。当 type = multiple 或 range 时传入数组 */
|
||||
value: {
|
||||
type: [Number, Array],
|
||||
},
|
||||
/** 当前选择的日期,不传则选用 minDate 属性值或今天,优先级:minDate > today。当 type = multiple 或 range 时传入数组,非受控属性 */
|
||||
defaultValue: {
|
||||
type: [Number, Array],
|
||||
},
|
||||
/** 是否显示日历;`usePopup` 为 true 时有效 */
|
||||
visible: Boolean,
|
||||
/** 不显示 confirm-btn 时,完成选择时触发(暂不支持 type = multiple) */
|
||||
onChange: {
|
||||
type: Function,
|
||||
default: () => ({}),
|
||||
},
|
||||
/** 关闭按钮时触发 */
|
||||
onClose: {
|
||||
type: Function,
|
||||
default: () => ({}),
|
||||
},
|
||||
/** 点击确认按钮时触发 */
|
||||
onConfirm: {
|
||||
type: Function,
|
||||
default: () => ({}),
|
||||
},
|
||||
/** 切换月或年时触发(switch-mode 不为 none 时有效) */
|
||||
onPanelChange: {
|
||||
type: Function,
|
||||
default: () => ({}),
|
||||
},
|
||||
/** 滚动时触发 */
|
||||
onScroll: {
|
||||
type: Function,
|
||||
default: () => ({}),
|
||||
},
|
||||
/** 点击日期时触发 */
|
||||
onSelect: {
|
||||
type: Function,
|
||||
default: () => ({}),
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,57 @@
|
||||
export default {
|
||||
classPrefix: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
usePopup: {
|
||||
type: Boolean,
|
||||
},
|
||||
switchMode: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
tClass: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
customStyle: {
|
||||
type: [String, Object],
|
||||
default: '',
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
realLocalText: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
months: {
|
||||
type: Array,
|
||||
default: () => ([]),
|
||||
},
|
||||
currentMonth: {
|
||||
type: [Array, Object],
|
||||
default: () => ([]),
|
||||
},
|
||||
actionButtons: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
days: {
|
||||
type: Array,
|
||||
default: () => ([]),
|
||||
},
|
||||
scrollIntoView: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
firstDayOfWeek: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
innerConfirmBtn: {
|
||||
type: [Object, String],
|
||||
default: '',
|
||||
},
|
||||
};
|
||||
261
uni_modules/tdesign-uniapp/components/calendar/template.vue
Normal file
261
uni_modules/tdesign-uniapp/components/calendar/template.vue
Normal file
@@ -0,0 +1,261 @@
|
||||
<template>
|
||||
<view
|
||||
:class="utils.cls(classPrefix, [['popup', usePopup]]) + ' ' + classPrefix + '-switch-mode--' + switchMode + ' ' + tClass"
|
||||
:style="customStyle"
|
||||
>
|
||||
<view
|
||||
:class="classPrefix + '__title'"
|
||||
tabindex="0"
|
||||
>
|
||||
<slot name="title" />
|
||||
<text v-if="title || realLocalText.title">
|
||||
{{ title || realLocalText.title }}
|
||||
</text>
|
||||
</view>
|
||||
<t-icon
|
||||
v-if="usePopup"
|
||||
name="close"
|
||||
:t-class="classPrefix + '__close-btn'"
|
||||
size="48rpx"
|
||||
aria-role="button"
|
||||
aria-label="关闭"
|
||||
:custom-style="closeBtnCustomStyle"
|
||||
@click="handleClose"
|
||||
/>
|
||||
<block
|
||||
v-if="switchMode !== 'none'"
|
||||
name="calendar-header"
|
||||
>
|
||||
<calendar-header
|
||||
:class-prefix="classPrefix + '-header'"
|
||||
:switch-mode="switchMode"
|
||||
:title="getMonthTitle(
|
||||
currentMonth[0] && currentMonth[0].year,
|
||||
realLocalText.months && currentMonth[0] && realLocalText.months[currentMonth[0].month],
|
||||
realLocalText.monthTitle
|
||||
)"
|
||||
:pre-year-btn-disable="actionButtons.preYearBtnDisable"
|
||||
:prev-month-btn-disable="actionButtons.prevMonthBtnDisable"
|
||||
:next-year-btn-disable="actionButtons.nextYearBtnDisable"
|
||||
:next-month-btn-disable="actionButtons.nextMonthBtnDisable"
|
||||
@handleSwitchModeChange="handleSwitchModeChange"
|
||||
/>
|
||||
</block>
|
||||
<view
|
||||
aria-hidden
|
||||
:class="classPrefix + '__days'"
|
||||
>
|
||||
<view
|
||||
v-for="(item, index) in days"
|
||||
:key="index"
|
||||
:class="classPrefix + '__days-item'"
|
||||
>
|
||||
{{ item }}
|
||||
</view>
|
||||
</view>
|
||||
<scroll-view
|
||||
:class="classPrefix + '__months'"
|
||||
:scroll-into-view="scrollIntoView"
|
||||
scroll-y
|
||||
enhanced
|
||||
:show-scrollbar="false"
|
||||
@scroll="onScroll"
|
||||
>
|
||||
<block
|
||||
v-for="(item, index) in switchMode === 'none' ? months : currentMonth"
|
||||
:key="index"
|
||||
>
|
||||
<block
|
||||
v-if="switchMode === 'none'"
|
||||
name="calendar-header"
|
||||
>
|
||||
<calendar-header
|
||||
:t-class="classPrefix + '__month'"
|
||||
:class-prefix="classPrefix + '-header'"
|
||||
:switch-mode="switchMode"
|
||||
:t-id="'year_' + item.year + '_month_' + item.month"
|
||||
:title="getMonthTitle(item.year, realLocalText.months && realLocalText.months[item.month], realLocalText.monthTitle)"
|
||||
:pre-year-btn-disable="actionButtons.preYearBtnDisable"
|
||||
:prev-month-btn-disable="actionButtons.prevMonthBtnDisable"
|
||||
:next-year-btn-disable="actionButtons.nextYearBtnDisable"
|
||||
:next-month-btn-disable="actionButtons.nextMonthBtnDisable"
|
||||
@handleSwitchModeChange="handleSwitchModeChange"
|
||||
/>
|
||||
</block>
|
||||
|
||||
<view :class="classPrefix + '__dates'">
|
||||
<view
|
||||
v-for="(item, index1) in (item.weekdayOfFirstDay - firstDayOfWeek + 7) % 7"
|
||||
:key="index1"
|
||||
/>
|
||||
<block
|
||||
v-for="(dateItem, dateIndex) in item.months"
|
||||
:key="dateIndex"
|
||||
>
|
||||
<view
|
||||
:class="classPrefix + '__dates-item ' + dateItem.className + ' ' + classPrefix + '__dates-item--' + dateItem.type"
|
||||
:data-year="item.year"
|
||||
:data-month="item.month"
|
||||
:data-date="dateItem"
|
||||
aria-role="button"
|
||||
:aria-label="getDateLabel(item, dateItem)"
|
||||
:aria-disabled="dateItem.type === 'disabled'"
|
||||
@click="handleSelect"
|
||||
>
|
||||
<view
|
||||
v-if="dateItem.prefix"
|
||||
:class="classPrefix + '__dates-item-prefix'"
|
||||
>
|
||||
{{ dateItem.prefix }}
|
||||
</view>
|
||||
{{ dateItem.day }}
|
||||
<view
|
||||
v-if="dateItem.suffix"
|
||||
:class="classPrefix + '__dates-item-suffix ' + classPrefix + '__dates-item-suffix--' + dateItem.type"
|
||||
>
|
||||
{{ dateItem.suffix }}
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</block>
|
||||
</scroll-view>
|
||||
<view
|
||||
v-if="innerConfirmBtn != null && usePopup"
|
||||
:class="classPrefix + '__footer'"
|
||||
>
|
||||
<slot
|
||||
v-if="innerConfirmBtn === 'slot'"
|
||||
name="confirm-btn"
|
||||
/>
|
||||
<block v-else-if="innerConfirmBtn">
|
||||
<t-button
|
||||
:t-id="innerConfirmBtn.tId"
|
||||
:custom-style="innerConfirmBtn.style"
|
||||
:block="coalesce(innerConfirmBtn.block, true)"
|
||||
:t-class="coalesce(coalesce(innerConfirmBtn.tClass, prefix + '-class-action'))"
|
||||
:class="prefix + '-calendar__confirm-btn'"
|
||||
:disabled="innerConfirmBtn.disabled"
|
||||
:data-type="'action'"
|
||||
:data-extra="innerConfirmBtn.dataExtra"
|
||||
:custom-dataset="innerConfirmBtn.customDataset"
|
||||
:content="innerConfirmBtn.content || realLocalText.confirm"
|
||||
:icon="innerConfirmBtn.icon"
|
||||
:loading="innerConfirmBtn.loading"
|
||||
:loading-props="innerConfirmBtn.loadingProps"
|
||||
:theme="coalesce(innerConfirmBtn.theme, 'primary')"
|
||||
:ghost="innerConfirmBtn.ghost"
|
||||
:shape="innerConfirmBtn.shape"
|
||||
:size="innerConfirmBtn.size"
|
||||
:variant="innerConfirmBtn.variant"
|
||||
:open-type="innerConfirmBtn.openType"
|
||||
:hover-class="innerConfirmBtn.hoverClass"
|
||||
:hover-stop-propagation="innerConfirmBtn.hoverStopPropagation"
|
||||
:hover-start-time="innerConfirmBtn.hoverStartTime"
|
||||
:hover-stay-time="innerConfirmBtn.hoverStayTime"
|
||||
:lang="innerConfirmBtn.lang"
|
||||
:session-from="innerConfirmBtn.sessionFrom"
|
||||
:send-message-title="innerConfirmBtn.sendMessageTitle"
|
||||
:send-message-path="innerConfirmBtn.sendMessagePath"
|
||||
:send-message-img="innerConfirmBtn.sendMessageImg"
|
||||
:app-parameter="innerConfirmBtn.appParameter"
|
||||
:show-message-card="innerConfirmBtn.showMessageCard"
|
||||
:aria-label="innerConfirmBtn.ariaLabel"
|
||||
@click="onTplButtonTap"
|
||||
@getuserinfo="onTplButtonTap"
|
||||
@contact="onTplButtonTap"
|
||||
@getphonenumber="onTplButtonTap"
|
||||
@error="onTplButtonTap"
|
||||
@opensetting="onTplButtonTap"
|
||||
@launchapp="onTplButtonTap"
|
||||
@agreeprivacyauthorization="onTplButtonTap"
|
||||
>
|
||||
<slot v-if="innerConfirmBtn.useDefaultSlot" />
|
||||
</t-button>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import TIcon from '../icon/icon.vue';
|
||||
import TButton from '../button/button.vue';
|
||||
import utils from '../common/utils.wxs';
|
||||
import {
|
||||
getDateLabel,
|
||||
getMonthTitle,
|
||||
} from './computed.js';
|
||||
import CalendarHeader from './calendar-header.vue';
|
||||
import { prefix } from '../common/config';
|
||||
import { coalesce } from '../common/utils';
|
||||
import props from './template.props';
|
||||
|
||||
|
||||
export default {
|
||||
name: 'TCalendarContent',
|
||||
options: {
|
||||
styleIsolation: 'shared',
|
||||
},
|
||||
components: {
|
||||
CalendarHeader,
|
||||
TIcon,
|
||||
TButton,
|
||||
},
|
||||
props: {
|
||||
...props,
|
||||
},
|
||||
emits: [
|
||||
'clickButton',
|
||||
'close',
|
||||
'scroll',
|
||||
'select',
|
||||
'handleSwitchModeChange',
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
prefix,
|
||||
utils,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
closeBtnCustomStyle() {
|
||||
return utils._style({
|
||||
position: 'absolute',
|
||||
top: '16px',
|
||||
right: '16px',
|
||||
margin: '-12px',
|
||||
padding: '12px',
|
||||
color: 'var(--td-calendar-title-color, var(--td-text-color-primary, var(--td-font-gray-1, rgba(0, 0, 0, .9))))',
|
||||
});
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
},
|
||||
mounted() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
coalesce,
|
||||
getDateLabel,
|
||||
getMonthTitle,
|
||||
onTplButtonTap() {
|
||||
this.$emit('clickButton');
|
||||
},
|
||||
handleSelect(...args) {
|
||||
this.$emit('select', ...args);
|
||||
},
|
||||
handleClose() {
|
||||
this.$emit('close');
|
||||
},
|
||||
onScroll(...args) {
|
||||
this.$emit('scroll', ...args);
|
||||
},
|
||||
handleSwitchModeChange(...args) {
|
||||
this.$emit('handleSwitchModeChange', ...args);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
</script>
|
||||
<style scoped>
|
||||
@import './calendar.css';
|
||||
</style>
|
||||
141
uni_modules/tdesign-uniapp/components/calendar/type.ts
Normal file
141
uni_modules/tdesign-uniapp/components/calendar/type.ts
Normal file
@@ -0,0 +1,141 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
|
||||
* */
|
||||
|
||||
import type { TdButtonProps as ButtonProps } from '../button/type';
|
||||
|
||||
export interface TdCalendarProps {
|
||||
/**
|
||||
* 是否允许区间选择日历的起止时间相同,仅当 `type='range'` 时有效
|
||||
* @default false
|
||||
*/
|
||||
allowSameDay?: boolean;
|
||||
/**
|
||||
* 自动关闭;在点击关闭按钮、确认按钮、遮罩层时自动关闭,不需要手动设置 visible
|
||||
* @default true
|
||||
*/
|
||||
autoClose?: boolean;
|
||||
/**
|
||||
* 确认按钮。值为 null 则不显示确认按钮。值类型为字符串,则表示自定义按钮文本,值类型为 Object 则表示透传 Button 组件属性
|
||||
* @default ''
|
||||
*/
|
||||
confirmBtn?: string | ButtonProps | null;
|
||||
/**
|
||||
* 第一天从星期几开始,默认 0 = 周日
|
||||
* @default 0
|
||||
*/
|
||||
firstDayOfWeek?: number;
|
||||
/**
|
||||
* 用于格式化日期的函数
|
||||
*/
|
||||
format?: CalendarFormatType;
|
||||
/**
|
||||
* 国际化文案
|
||||
*/
|
||||
localeText?: CalendarLocaleText;
|
||||
/**
|
||||
* 最大可选的日期,不传则默认半年后
|
||||
*/
|
||||
maxDate?: number;
|
||||
/**
|
||||
* 最小可选的日期,不传则默认今天
|
||||
*/
|
||||
minDate?: number;
|
||||
/**
|
||||
* 是否只读,只读状态下不能选择日期
|
||||
*/
|
||||
readonly?: boolean;
|
||||
/**
|
||||
* 切换模式。 `none` 表示平铺展示所有月份; `month` 表示支持按月切换, `year-month` 表示既按年切换,也支持按月切换
|
||||
* @default none
|
||||
*/
|
||||
switchMode?: 'none' | 'month' | 'year-month';
|
||||
/**
|
||||
* 标题,不传默认为“请选择日期”
|
||||
*/
|
||||
title?: string;
|
||||
/**
|
||||
* 日历的选择类型,single = 单选;multiple = 多选; range = 区间选择
|
||||
* @default single
|
||||
*/
|
||||
type?: 'single' | 'multiple' | 'range';
|
||||
/**
|
||||
* 是否使用弹出层包裹日历
|
||||
* @default true
|
||||
*/
|
||||
usePopup?: boolean;
|
||||
/**
|
||||
* 是否使用了自定义导航栏
|
||||
* @default false
|
||||
*/
|
||||
usingCustomNavbar?: boolean;
|
||||
/**
|
||||
* 当前选择的日期,不传则选用 minDate 属性值或今天,优先级:minDate > today。当 type = multiple 或 range 时传入数组
|
||||
*/
|
||||
value?: number | number[];
|
||||
/**
|
||||
* 当前选择的日期,不传则选用 minDate 属性值或今天,优先级:minDate > today。当 type = multiple 或 range 时传入数组,非受控属性
|
||||
*/
|
||||
defaultValue?: number | number[];
|
||||
/**
|
||||
* 是否显示日历;`usePopup` 为 true 时有效
|
||||
* @default false
|
||||
*/
|
||||
visible?: boolean;
|
||||
/**
|
||||
* 不显示 confirm-btn 时,完成选择时触发(暂不支持 type = multiple)
|
||||
*/
|
||||
onChange?: (context: { value: number | number[] }) => void;
|
||||
/**
|
||||
* 关闭按钮时触发
|
||||
*/
|
||||
onClose?: (context: { trigger: CalendarTrigger }) => void;
|
||||
/**
|
||||
* 点击确认按钮时触发
|
||||
*/
|
||||
onConfirm?: (context: { value: number | number[] }) => void;
|
||||
/**
|
||||
* 切换月或年时触发(switch-mode 不为 none 时有效)
|
||||
*/
|
||||
onPanelChange?: (context: { year: number; month: number }) => void;
|
||||
/**
|
||||
* 滚动时触发
|
||||
*/
|
||||
onScroll?: (context: {
|
||||
scrollLeft: number;
|
||||
scrollTop: number;
|
||||
scrollHeight: number;
|
||||
scrollWidth: number;
|
||||
deltaX: number;
|
||||
deltaY: number;
|
||||
}) => void;
|
||||
/**
|
||||
* 点击日期时触发
|
||||
*/
|
||||
onSelect?: (context: { value: number | number[] }) => void;
|
||||
}
|
||||
|
||||
export type CalendarFormatType = (day: TDate) => TDate;
|
||||
|
||||
export type TDateType = 'selected' | 'disabled' | 'start' | 'start-end' | 'centre' | 'end' | '';
|
||||
|
||||
export interface TDate {
|
||||
date: Date;
|
||||
day: number;
|
||||
type: TDateType;
|
||||
className?: string;
|
||||
prefix?: string;
|
||||
suffix?: string;
|
||||
}
|
||||
|
||||
export interface CalendarLocaleText {
|
||||
title?: string;
|
||||
weekdays?: string[];
|
||||
monthTitle?: string;
|
||||
months?: string[];
|
||||
confirm?: string;
|
||||
}
|
||||
|
||||
export type CalendarTrigger = 'close-btn' | 'confirm-btn' | 'overlay' | 'auto-close';
|
||||
16
uni_modules/tdesign-uniapp/components/calendar/utils.js
Normal file
16
uni_modules/tdesign-uniapp/components/calendar/utils.js
Normal file
@@ -0,0 +1,16 @@
|
||||
export function getMonthByOffset(date, offset) {
|
||||
const _date = new Date(date);
|
||||
_date.setMonth(_date.getMonth() + offset);
|
||||
return _date;
|
||||
}
|
||||
|
||||
export function getYearByOffset(date, offset) {
|
||||
const _date = new Date(date);
|
||||
_date.setFullYear(_date.getFullYear() + offset);
|
||||
return _date;
|
||||
}
|
||||
|
||||
export const getPrevMonth = date => getMonthByOffset(date, -1);
|
||||
export const getNextMonth = date => getMonthByOffset(date, 1);
|
||||
export const getPrevYear = date => getYearByOffset(date, -1);
|
||||
export const getNextYear = date => getYearByOffset(date, 1);
|
||||
@@ -0,0 +1,56 @@
|
||||
:: BASE_DOC ::
|
||||
|
||||
## API
|
||||
|
||||
### Cascader Props
|
||||
|
||||
name | type | default | description | required
|
||||
-- | -- | -- | -- | --
|
||||
custom-style | Object | - | CSS(Cascading Style Sheets) | N
|
||||
check-strictly | Boolean | false | \- | N
|
||||
close-btn | Boolean | true | \- | N
|
||||
keys | Object | - | Typescript: `CascaderKeysType` `type CascaderKeysType = TreeKeysType`。[see more ts definition](https://github.com/tencent/tdesign-miniprogram/blob/develop/packages/uniapp-components/common/common.ts)。[see more ts definition](https://github.com/tencent/tdesign-miniprogram/blob/develop/packages/uniapp-components/cascader/type.ts) | N
|
||||
options | Array | [] | Typescript: `Array<CascaderOption>` | N
|
||||
placeholder | String | 选择选项 | \- | N
|
||||
sub-titles | Array | [] | Typescript: `Array<string>` | N
|
||||
theme | String | step | options: step/tab | N
|
||||
title | String | - | \- | N
|
||||
value | String / Number | - | `v-model:value` is supported | N
|
||||
default-value | String / Number | - | uncontrolled property | N
|
||||
visible | Boolean | false | \- | N
|
||||
|
||||
### Cascader Events
|
||||
|
||||
name | params | description
|
||||
-- | -- | --
|
||||
change | `(context: { value: string \| number, selectedOptions: string[] })` | \-
|
||||
close | `(context: { trigger: CascaderTriggerSource })` | [see more ts definition](https://github.com/tencent/tdesign-miniprogram/blob/develop/packages/uniapp-components/cascader/type.ts)。<br/>`type CascaderTriggerSource = 'overlay' \| 'close-btn' \| 'finish'`<br/>
|
||||
pick | `(context: { value: string \| number, label: string, index: number, level: number })` | \-
|
||||
|
||||
### Cascader Slots
|
||||
|
||||
name | Description
|
||||
-- | --
|
||||
close-btn | \-
|
||||
header | \-
|
||||
middle-content | \-
|
||||
title | \-
|
||||
|
||||
### CSS Variables
|
||||
|
||||
The component provides the following CSS variables, which can be used to customize styles.
|
||||
Name | Default Value | Description
|
||||
-- | -- | --
|
||||
--td-cascader-active-color | @brand-color | -
|
||||
--td-cascader-bg-color | @bg-color-container | -
|
||||
--td-cascader-border-color | @component-stroke | -
|
||||
--td-cascader-content-height | 78vh | -
|
||||
--td-cascader-disabled-color | @text-color-disabled | -
|
||||
--td-cascader-options-height | calc(100% - @cascader-step-height) | -
|
||||
--td-cascader-options-title-color | @text-color-placeholder | -
|
||||
--td-cascader-step-arrow-color | @text-color-placeholder | -
|
||||
--td-cascader-step-dot-size | 16rpx | -
|
||||
--td-cascader-step-height | 88rpx | -
|
||||
--td-cascader-title-color | @text-color-primary | -
|
||||
--td-cascader-title-font | @font-title-large | -
|
||||
--td-cascader-title-padding | @spacer-2 | -
|
||||
96
uni_modules/tdesign-uniapp/components/cascader/README.md
Normal file
96
uni_modules/tdesign-uniapp/components/cascader/README.md
Normal file
@@ -0,0 +1,96 @@
|
||||
---
|
||||
title: Cascader 级联选择器
|
||||
description: 级联选择器适用于有清晰层级结构的数据集合,用户可以通过逐级查看并选择。
|
||||
spline: form
|
||||
isComponent: true
|
||||
---
|
||||
|
||||
|
||||
## 引入
|
||||
|
||||
可在 `main.ts` 或在需要使用的页面或组件中引入。
|
||||
|
||||
```js
|
||||
import TCascader from '@tdesign/uniapp/cascader/cascader.vue';
|
||||
```
|
||||
|
||||
### 基础用法
|
||||
|
||||
{{ base }}
|
||||
|
||||
### 选项卡风格
|
||||
|
||||
{{ theme-tab }}
|
||||
|
||||
### 进阶
|
||||
|
||||
#### 带初始值
|
||||
|
||||
{{ with-value }}
|
||||
|
||||
#### 自定义 keys
|
||||
|
||||
{{ keys }}
|
||||
|
||||
#### 使用次级标题
|
||||
|
||||
{{ with-title }}
|
||||
|
||||
#### 选择任意一项
|
||||
|
||||
{{ check-strictly }}
|
||||
|
||||
## API
|
||||
|
||||
### Cascader Props
|
||||
|
||||
名称 | 类型 | 默认值 | 描述 | 必传
|
||||
-- | -- | -- | -- | --
|
||||
custom-style | Object | - | 自定义样式 | N
|
||||
check-strictly | Boolean | false | 父子节点选中状态不再关联,可各自选中或取消 | N
|
||||
close-btn | Boolean | true | 关闭按钮 | N
|
||||
keys | Object | - | 用来定义 value / label / children / disabled 在 `options` 中对应的字段别名。TS 类型:`CascaderKeysType` `type CascaderKeysType = TreeKeysType`。[通用类型定义](https://github.com/tencent/tdesign-miniprogram/blob/develop/packages/uniapp-components/common/common.ts)。[详细类型定义](https://github.com/tencent/tdesign-miniprogram/blob/develop/packages/uniapp-components/cascader/type.ts) | N
|
||||
options | Array | [] | 可选项数据源。TS 类型:`Array<CascaderOption>` | N
|
||||
placeholder | String | 选择选项 | 未选中时的提示文案 | N
|
||||
sub-titles | Array | [] | 每级展示的次标题。TS 类型:`Array<string>` | N
|
||||
theme | String | step | 展示风格。可选项:step/tab | N
|
||||
title | String | - | 标题 | N
|
||||
value | String / Number | - | 选项值。支持语法糖 `v-model:value` | N
|
||||
default-value | String / Number | - | 选项值。非受控属性 | N
|
||||
visible | Boolean | false | 是否展示 | N
|
||||
|
||||
### Cascader Events
|
||||
|
||||
名称 | 参数 | 描述
|
||||
-- | -- | --
|
||||
change | `(context: { value: string \| number, selectedOptions: string[] })` | 值发生变更时触发
|
||||
close | `(context: { trigger: CascaderTriggerSource })` | 关闭时触发。[详细类型定义](https://github.com/tencent/tdesign-miniprogram/blob/develop/packages/uniapp-components/cascader/type.ts)。<br/>`type CascaderTriggerSource = 'overlay' \| 'close-btn' \| 'finish'`<br/>
|
||||
pick | `(context: { value: string \| number, label: string, index: number, level: number })` | 选择后触发
|
||||
|
||||
### Cascader Slots
|
||||
|
||||
名称 | 描述
|
||||
-- | --
|
||||
close-btn | 自定义 `close-btn` 显示内容
|
||||
header | 头部
|
||||
middle-content | 中间内容
|
||||
title | 自定义 `title` 显示内容
|
||||
|
||||
### CSS Variables
|
||||
|
||||
组件提供了下列 CSS 变量,可用于自定义样式。
|
||||
名称 | 默认值 | 描述
|
||||
-- | -- | --
|
||||
--td-cascader-active-color | @brand-color | -
|
||||
--td-cascader-bg-color | @bg-color-container | -
|
||||
--td-cascader-border-color | @component-stroke | -
|
||||
--td-cascader-content-height | 78vh | -
|
||||
--td-cascader-disabled-color | @text-color-disabled | -
|
||||
--td-cascader-options-height | calc(100% - @cascader-step-height) | -
|
||||
--td-cascader-options-title-color | @text-color-placeholder | -
|
||||
--td-cascader-step-arrow-color | @text-color-placeholder | -
|
||||
--td-cascader-step-dot-size | 16rpx | -
|
||||
--td-cascader-step-height | 88rpx | -
|
||||
--td-cascader-title-color | @text-color-primary | -
|
||||
--td-cascader-title-font | @font-title-large | -
|
||||
--td-cascader-title-padding | @spacer-2 | -
|
||||
102
uni_modules/tdesign-uniapp/components/cascader/cascader.css
Normal file
102
uni_modules/tdesign-uniapp/components/cascader/cascader.css
Normal file
@@ -0,0 +1,102 @@
|
||||
.t-cascader {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: var(--td-cascader-bg-color, var(--td-bg-color-container, var(--td-font-white-1, #ffffff)));
|
||||
color: var(--td-cascader-title-color, var(--td-text-color-primary, var(--td-font-gray-1, rgba(0, 0, 0, 0.9))));
|
||||
border-radius: var(--td-radius-extraLarge, 24rpx) var(--td-radius-extraLarge, 24rpx) 0 0;
|
||||
--td-radio-icon-checked-color: var(--td-cascader-active-color, var(--td-brand-color, var(--td-primary-color-7, #0052d9)));
|
||||
--td-tab-item-active-color: var(--td-cascader-active-color, var(--td-brand-color, var(--td-primary-color-7, #0052d9)));
|
||||
--td-tab-track-color: var(--td-cascader-active-color, var(--td-brand-color, var(--td-primary-color-7, #0052d9)));
|
||||
}
|
||||
.t-cascader__close-btn {
|
||||
right: var(--td-spacer-2, 32rpx);
|
||||
top: var(--td-spacer-2, 32rpx);
|
||||
position: absolute;
|
||||
}
|
||||
.t-cascader__title {
|
||||
position: relative;
|
||||
font: var(--td-cascader-title-font, var(--td-font-title-large, 600 36rpx / 52rpx var(--td-font-family, PingFang SC, Microsoft YaHei, Arial Regular)));
|
||||
text-align: center;
|
||||
padding: var(--td-cascader-title-padding, var(--td-spacer-2, 32rpx));
|
||||
}
|
||||
.t-cascader__content {
|
||||
width: 100%;
|
||||
height: var(--td-cascader-content-height, 78vh);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.t-cascader__options {
|
||||
width: 100vw;
|
||||
}
|
||||
.t-cascader__options-title {
|
||||
color: var(--td-cascader-options-title-color, var(--td-text-color-placeholder, var(--td-font-gray-3, rgba(0, 0, 0, 0.4))));
|
||||
font: var(--td-font-body-medium, 28rpx / 44rpx var(--td-font-family, PingFang SC, Microsoft YaHei, Arial Regular));
|
||||
padding-top: 40rpx;
|
||||
padding-left: var(--td-spacer-2, 32rpx);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.t-cascader__options-container {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
transition: all ease 0.3s;
|
||||
}
|
||||
.t-cascader__step {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: var(--td-cascader-step-height, 88rpx);
|
||||
}
|
||||
.t-cascader__steps {
|
||||
padding: 0 32rpx 10rpx;
|
||||
position: relative;
|
||||
}
|
||||
.t-cascader__steps::after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: unset;
|
||||
bottom: 0;
|
||||
left: unset;
|
||||
right: unset;
|
||||
background-color: var(--td-cascader-border-color, var(--td-component-stroke, var(--td-gray-color-3, #e7e7e7)));
|
||||
}
|
||||
.t-cascader__steps::after {
|
||||
height: 1px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
transform: scaleY(0.5);
|
||||
}
|
||||
.t-cascader__step-dot {
|
||||
position: relative;
|
||||
width: var(--td-cascader-step-dot-size, 16rpx);
|
||||
height: var(--td-cascader-step-dot-size, 16rpx);
|
||||
border-radius: 50%;
|
||||
border: 2rpx solid var(--td-cascader-active-color, var(--td-brand-color, var(--td-primary-color-7, #0052d9)));
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.t-cascader__step-dot:not(.t-cascader__step-dot--last)::after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: calc(var(--td-cascader-step-dot-size, 16rpx) + 14rpx);
|
||||
height: 36rpx;
|
||||
width: 2rpx;
|
||||
background: var(--td-cascader-active-color, var(--td-brand-color, var(--td-primary-color-7, #0052d9)));
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
.t-cascader__step-dot--active {
|
||||
background: var(--td-cascader-active-color, var(--td-brand-color, var(--td-primary-color-7, #0052d9)));
|
||||
border-color: var(--td-cascader-active-color, var(--td-brand-color, var(--td-primary-color-7, #0052d9)));
|
||||
}
|
||||
.t-cascader__step-label {
|
||||
padding-left: var(--td-spacer-2, 32rpx);
|
||||
font: var(--td-font-body-medium, 28rpx / 44rpx var(--td-font-family, PingFang SC, Microsoft YaHei, Arial Regular));
|
||||
}
|
||||
.t-cascader__step-label--active {
|
||||
color: var(--td-cascader-active-color, var(--td-brand-color, var(--td-primary-color-7, #0052d9)));
|
||||
font-weight: 600;
|
||||
}
|
||||
.t-cascader__step-arrow {
|
||||
color: var(--td-cascader-step-arrow-color, var(--td-text-color-placeholder, var(--td-font-gray-3, rgba(0, 0, 0, 0.4))));
|
||||
margin-left: auto;
|
||||
}
|
||||
519
uni_modules/tdesign-uniapp/components/cascader/cascader.vue
Normal file
519
uni_modules/tdesign-uniapp/components/cascader/cascader.vue
Normal file
@@ -0,0 +1,519 @@
|
||||
<template>
|
||||
<view>
|
||||
<TPopup
|
||||
:class="tClass"
|
||||
:visible="dataVisible"
|
||||
placement="bottom"
|
||||
@visible-change="onVisibleChange"
|
||||
>
|
||||
<view
|
||||
:style="tools._style([customStyle])"
|
||||
:class="name"
|
||||
>
|
||||
<view :class="name + '__title'">
|
||||
<slot name="title" />
|
||||
{{ title }}
|
||||
</view>
|
||||
<view
|
||||
:class="name + '__close-btn'"
|
||||
@click="onClose"
|
||||
>
|
||||
<slot name="close-btn" />
|
||||
<TIcon
|
||||
v-if="closeBtn"
|
||||
size="48rpx"
|
||||
name="close"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<slot name="header" />
|
||||
|
||||
<view :class="name + '__content'">
|
||||
<block v-if="steps && steps.length">
|
||||
<view
|
||||
v-if="theme == 'step'"
|
||||
:class="name + '__steps'"
|
||||
>
|
||||
<view
|
||||
v-for="(item, index) in steps"
|
||||
:key="index"
|
||||
:class="name + '__step'"
|
||||
:data-index="index"
|
||||
@click="() => onStepClick(index)"
|
||||
>
|
||||
<view
|
||||
:class="
|
||||
name +
|
||||
'__step-dot ' +
|
||||
name +
|
||||
'__step-dot--' +
|
||||
(item !== placeholder ? 'active' : '') +
|
||||
' ' +
|
||||
name +
|
||||
'__step-dot--' +
|
||||
(index === steps.length - 1 ? 'last' : '')
|
||||
"
|
||||
/>
|
||||
|
||||
<view :class="name + '__step-label ' + name + '__step-label--' + (index === stepIndex ? 'active' : '')">
|
||||
{{ item }}
|
||||
</view>
|
||||
|
||||
<TIcon
|
||||
name="chevron-right"
|
||||
size="44rpx"
|
||||
:t-class="name + '__step-arrow'"
|
||||
:custom-style="stepArrowCustomStyle"
|
||||
style="margin-left: auto"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<TTabs
|
||||
v-if="theme == 'tab'"
|
||||
ref="tabs"
|
||||
:value="stepIndex"
|
||||
:space-evenly="false"
|
||||
@change="({value}) => onTabChange(value)"
|
||||
>
|
||||
<TTabPanel
|
||||
v-for="(item, index) in steps"
|
||||
:key="index"
|
||||
:ref="`tab-${index}`"
|
||||
:value="index"
|
||||
:label="item"
|
||||
/>
|
||||
</TTabs>
|
||||
</block>
|
||||
|
||||
<slot name="middle-content" />
|
||||
|
||||
<view
|
||||
v-if="subTitles && subTitles[stepIndex]"
|
||||
:class="name + '__options-title'"
|
||||
>
|
||||
{{ subTitles[stepIndex] }}
|
||||
</view>
|
||||
|
||||
<view
|
||||
:class="name + '__options-container'"
|
||||
:style="'width: ' + (items.length + 1) + '00vw; transform: translateX(-' + stepIndex + '00vw)'"
|
||||
>
|
||||
<scroll-view
|
||||
v-for="(options, index) in items"
|
||||
:key="index"
|
||||
:class="name + '__options'"
|
||||
scroll-y
|
||||
:scroll-top="scrollTopList[index]"
|
||||
type="list"
|
||||
:style="'height: ' + _optionsHeight + 'px'"
|
||||
>
|
||||
<view :class="'cascader-radio-group-' + index">
|
||||
<TRadioGroup
|
||||
:value="selectedValue[index]"
|
||||
:keys="keys"
|
||||
:options="options"
|
||||
:data-level="index"
|
||||
placement="right"
|
||||
icon="line"
|
||||
borderless
|
||||
@change="({ value }) => handleSelect($event, { level: index, value })"
|
||||
/>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</TPopup>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import TIcon from '../icon/icon';
|
||||
import TPopup from '../popup/popup';
|
||||
import TTabs from '../tabs/tabs';
|
||||
import TTabPanel from '../tab-panel/tab-panel';
|
||||
import TRadioGroup from '../radio-group/radio-group';
|
||||
import { uniComponent } from '../common/src/index';
|
||||
import { prefix } from '../common/config';
|
||||
import props from './props';
|
||||
import { getRect, coalesce, nextTick } from '../common/utils';
|
||||
|
||||
import tools from '../common/utils.wxs';
|
||||
|
||||
|
||||
const name = `${prefix}-cascader`;
|
||||
|
||||
function parseOptions(options, keys) {
|
||||
const label = coalesce(keys?.label, 'label');
|
||||
const value = coalesce(keys?.value, 'value');
|
||||
const disabled = coalesce(keys?.disabled, 'disabled');
|
||||
|
||||
return options.map(item => ({
|
||||
[label]: item[label],
|
||||
[value]: item[value],
|
||||
[disabled]: item[disabled],
|
||||
}));
|
||||
}
|
||||
|
||||
const defaultState = {
|
||||
contentHeight: 0,
|
||||
stepHeight: 0,
|
||||
tabsHeight: 0,
|
||||
subTitlesHeight: 0,
|
||||
stepsInitHeight: 0,
|
||||
};
|
||||
|
||||
export default uniComponent({
|
||||
name,
|
||||
options: {
|
||||
styleIsolation: 'shared',
|
||||
},
|
||||
controlledProps: [
|
||||
{
|
||||
key: 'value',
|
||||
event: 'change',
|
||||
},
|
||||
],
|
||||
externalClasses: [
|
||||
`${prefix}-class`,
|
||||
],
|
||||
components: {
|
||||
TIcon,
|
||||
TPopup,
|
||||
TTabs,
|
||||
TTabPanel,
|
||||
TRadioGroup,
|
||||
},
|
||||
props: {
|
||||
...props,
|
||||
},
|
||||
emits: [
|
||||
'update:visible',
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
prefix,
|
||||
name,
|
||||
stepIndex: 0,
|
||||
selectedIndexes: [],
|
||||
selectedValue: [],
|
||||
scrollTopList: [],
|
||||
steps: [],
|
||||
_optionsHeight: 0,
|
||||
tools,
|
||||
|
||||
dataVisible: this.visible,
|
||||
dataValue: coalesce(this.value, this.defaultValue),
|
||||
items: [],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
stepArrowCustomStyle() {
|
||||
return tools._style({
|
||||
color: 'var(--td-cascader-step-arrow-color, var(--td-text-color-placeholder, var(--td-font-gray-3, rgba(0, 0, 0, .4))))',
|
||||
marginLeft: 'auto',
|
||||
});
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
visible: {
|
||||
handler(v) {
|
||||
this.dataVisible = v;
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
dataVisible: {
|
||||
handler(v) {
|
||||
if (v) {
|
||||
nextTick().then(() => {
|
||||
const $tabs = this.$refs.tabs;
|
||||
$tabs?.setTrack();
|
||||
$tabs?.getTabHeight().then((res) => {
|
||||
this.state.tabsHeight = res.height;
|
||||
});
|
||||
});
|
||||
|
||||
// 不能使用 this.$nextTick,在头条小程序下会报错
|
||||
nextTick().then(() => {
|
||||
this.initOptionsHeight(this.steps.length);
|
||||
this.updateScrollTop();
|
||||
this.initWithValue();
|
||||
});
|
||||
} else {
|
||||
this.state = { ...defaultState };
|
||||
}
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
|
||||
value: {
|
||||
handler(v) {
|
||||
this.dataValue = v;
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
|
||||
dataValue: {
|
||||
handler() {
|
||||
this.initWithValue();
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
|
||||
options: {
|
||||
handler() {
|
||||
const { selectedValue, steps, items } = this.genItems();
|
||||
|
||||
this.steps = steps;
|
||||
this.items = items;
|
||||
this.selectedValue = selectedValue;
|
||||
this.stepIndex = items.length - 1;
|
||||
this.setTabParent();
|
||||
},
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
selectedIndexes: {
|
||||
handler() {
|
||||
const { visible, theme } = this;
|
||||
const { selectedValue, steps, items } = this.genItems();
|
||||
|
||||
this.steps = steps;
|
||||
this.setTabParent();
|
||||
this.selectedValue = selectedValue;
|
||||
this.stepIndex = items.length - 1;
|
||||
|
||||
if (JSON.stringify(items) !== JSON.stringify(this.items)) {
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
|
||||
if (visible && theme === 'step') {
|
||||
this.updateOptionsHeight(steps.length);
|
||||
}
|
||||
},
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
|
||||
stepIndex: {
|
||||
handler() {
|
||||
const { dataVisible: visible } = this;
|
||||
|
||||
if (visible) {
|
||||
this.updateScrollTop();
|
||||
}
|
||||
},
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.state = {
|
||||
...defaultState,
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
setTabParent() {
|
||||
// #ifdef MP-TOUTIAO
|
||||
nextTick().then(() => {
|
||||
const tabsRef = this.$refs.tabs;
|
||||
this.steps.forEach((tools, index) => {
|
||||
const tabRef = this.$refs[`tab-${index}`];
|
||||
tabRef?.[0]?.setParent(tabsRef);
|
||||
});
|
||||
});
|
||||
// #endif
|
||||
},
|
||||
updateOptionsHeight(steps) {
|
||||
const { contentHeight, stepsInitHeight, stepHeight, subTitlesHeight } = this.state;
|
||||
this._optionsHeight = contentHeight - stepsInitHeight - subTitlesHeight - (steps - 1) * stepHeight;
|
||||
},
|
||||
|
||||
async initOptionsHeight(steps) {
|
||||
const { theme, subTitles } = this;
|
||||
|
||||
const { height } = await getRect(this, `.${name}__content`);
|
||||
this.state.contentHeight = height;
|
||||
|
||||
if (theme === 'step') {
|
||||
await Promise.all([
|
||||
getRect(this, `.${name}__steps`),
|
||||
getRect(this, `.${name}__step`),
|
||||
])
|
||||
.then(([stepsRect, stepRect]) => {
|
||||
this.state.stepsInitHeight = stepsRect.height - (steps - 1) * stepRect.height;
|
||||
this.state.stepHeight = stepRect.height;
|
||||
})
|
||||
.catch(() => {
|
||||
});
|
||||
}
|
||||
|
||||
if (subTitles.length > 0) {
|
||||
const { height } = await getRect(this, `.${name}__options-title`);
|
||||
this.state.subTitlesHeight = height;
|
||||
}
|
||||
|
||||
const optionsInitHeight = this.state.contentHeight - this.state.subTitlesHeight;
|
||||
this._optionsHeight = theme === 'step'
|
||||
? optionsInitHeight - this.state.stepsInitHeight - (steps - 1) * this.state.stepHeight
|
||||
: optionsInitHeight - this.state.tabsHeight;
|
||||
},
|
||||
|
||||
initWithValue() {
|
||||
if (this.dataValue != null && this.dataValue !== '') {
|
||||
const selectedIndexes = this.getIndexesByValue(this.options, this.dataValue);
|
||||
|
||||
if (selectedIndexes) {
|
||||
this.selectedIndexes = selectedIndexes;
|
||||
}
|
||||
} else {
|
||||
this.selectedIndexes = [];
|
||||
}
|
||||
},
|
||||
getIndexesByValue(options, value) {
|
||||
const { keys } = this;
|
||||
|
||||
for (let i = 0, size = options.length; i < size; i += 1) {
|
||||
const opt = options[i];
|
||||
if (opt[coalesce(keys?.value, 'value')] === value) {
|
||||
return [i];
|
||||
}
|
||||
if (opt[coalesce(keys?.children, 'children')]) {
|
||||
const res = this.getIndexesByValue(opt[coalesce(keys?.children, 'children')], value);
|
||||
if (res) {
|
||||
return [i, ...res];
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
updateScrollTop() {
|
||||
const { dataVisible: visible, items, selectedIndexes, stepIndex } = this;
|
||||
|
||||
if (visible) {
|
||||
getRect(this, '.cascader-radio-group-0').then((rect) => {
|
||||
const eachRadioHeight = rect.height / items[0]?.length;
|
||||
|
||||
this[`scrollTopList[${stepIndex}]`] = eachRadioHeight * selectedIndexes[stepIndex];
|
||||
})
|
||||
.catch(() => {
|
||||
});
|
||||
}
|
||||
},
|
||||
hide(trigger) {
|
||||
this.dataVisible = false;
|
||||
this.$emit('close', { trigger });
|
||||
this.$emit('update:visible', false);
|
||||
},
|
||||
onVisibleChange() {
|
||||
this.hide('overlay');
|
||||
},
|
||||
onClose() {
|
||||
if (this.checkStrictly) {
|
||||
this.triggerChange();
|
||||
}
|
||||
this.hide('close-btn');
|
||||
},
|
||||
onStepClick(index) {
|
||||
this.stepIndex = index;
|
||||
},
|
||||
onTabChange(value) {
|
||||
this.stepIndex = value;
|
||||
},
|
||||
genItems() {
|
||||
const { options, selectedIndexes, keys, placeholder } = this;
|
||||
const selectedValue = [];
|
||||
const steps = [];
|
||||
const items = [parseOptions(options, keys)];
|
||||
|
||||
if (options.length > 0) {
|
||||
let current = options;
|
||||
for (let i = 0, size = selectedIndexes.length; i < size; i += 1) {
|
||||
const index = selectedIndexes[i];
|
||||
const next = current[index];
|
||||
current = next[coalesce(keys?.children, 'children')];
|
||||
|
||||
selectedValue.push(next[coalesce(keys?.value, 'value')]);
|
||||
steps.push(next[coalesce(keys?.label, 'label')]);
|
||||
|
||||
if (next[coalesce(keys?.children, 'children')]) {
|
||||
items.push(parseOptions(next[coalesce(keys?.children, 'children')], keys));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (steps.length < items.length) {
|
||||
steps.push(placeholder);
|
||||
}
|
||||
|
||||
return {
|
||||
selectedValue,
|
||||
steps,
|
||||
items,
|
||||
};
|
||||
},
|
||||
handleSelect(tools, { level, value }) {
|
||||
const { checkStrictly } = this;
|
||||
const { selectedIndexes, items, keys, options, selectedValue } = this;
|
||||
|
||||
const index = items[level].findIndex(item => item[coalesce(keys?.value, 'value')] === value);
|
||||
|
||||
let item = selectedIndexes.slice(0, level).reduce((acc, item, index) => {
|
||||
if (index === 0) {
|
||||
return acc[item];
|
||||
}
|
||||
return acc[coalesce(keys?.children, 'children')][item];
|
||||
}, options);
|
||||
|
||||
|
||||
if (level === 0) {
|
||||
item = item[index];
|
||||
} else {
|
||||
item = item[coalesce(keys?.children, 'children')][index];
|
||||
}
|
||||
|
||||
if (item[coalesce(keys?.disabled, 'disabled')]) {
|
||||
return;
|
||||
}
|
||||
this.$emit('pick', {
|
||||
value: item[coalesce(keys?.value, 'value')],
|
||||
label: item[coalesce(keys?.label, 'label')],
|
||||
index,
|
||||
level,
|
||||
});
|
||||
selectedIndexes[level] = index;
|
||||
if (checkStrictly && selectedValue.includes(String(value))) {
|
||||
selectedIndexes.length = level;
|
||||
this.selectedIndexes = selectedIndexes;
|
||||
return;
|
||||
}
|
||||
selectedIndexes.length = level + 1;
|
||||
|
||||
const { items: newItems } = this.genItems();
|
||||
if (item?.[coalesce(keys?.children, 'children')]?.length >= 0) {
|
||||
this.selectedIndexes = selectedIndexes;
|
||||
this[`items[${level + 1}]`] = newItems[level + 1];
|
||||
} else {
|
||||
// setCascaderValue(item.value);
|
||||
this.selectedIndexes = selectedIndexes;
|
||||
setTimeout(this.triggerChange);
|
||||
|
||||
this.hide('finish');
|
||||
}
|
||||
},
|
||||
triggerChange() {
|
||||
const { items, selectedValue, selectedIndexes } = this;
|
||||
this._trigger('change', {
|
||||
value: coalesce(selectedValue[selectedValue.length - 1], ''),
|
||||
selectedOptions: items.map((item, index) => item[selectedIndexes[index]]).filter(Boolean),
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style scoped>
|
||||
@import './cascader.css';
|
||||
</style>
|
||||
73
uni_modules/tdesign-uniapp/components/cascader/props.ts
Normal file
73
uni_modules/tdesign-uniapp/components/cascader/props.ts
Normal file
@@ -0,0 +1,73 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
|
||||
* */
|
||||
|
||||
import type { TdCascaderProps } from './type';
|
||||
export default {
|
||||
/** 父子节点选中状态不再关联,可各自选中或取消 */
|
||||
checkStrictly: Boolean,
|
||||
/** 关闭按钮 */
|
||||
closeBtn: {
|
||||
type: Boolean,
|
||||
default: true as TdCascaderProps['closeBtn'],
|
||||
},
|
||||
/** 用来定义 value / label / children / disabled 在 `options` 中对应的字段别名 */
|
||||
keys: {
|
||||
type: Object,
|
||||
},
|
||||
/** 可选项数据源 */
|
||||
options: {
|
||||
type: Array,
|
||||
default: (): TdCascaderProps['options'] => [],
|
||||
},
|
||||
/** 未选中时的提示文案 */
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: '选择选项',
|
||||
},
|
||||
/** 每级展示的次标题 */
|
||||
subTitles: {
|
||||
type: Array,
|
||||
default: (): TdCascaderProps['subTitles'] => [],
|
||||
},
|
||||
/** 展示风格 */
|
||||
theme: {
|
||||
type: String,
|
||||
default: 'step' as TdCascaderProps['theme'],
|
||||
validator(val: TdCascaderProps['theme']): boolean {
|
||||
if (!val) return true;
|
||||
return ['step', 'tab'].includes(val);
|
||||
},
|
||||
},
|
||||
/** 标题 */
|
||||
title: {
|
||||
type: String,
|
||||
},
|
||||
/** 选项值 */
|
||||
value: {
|
||||
type: [String, Number],
|
||||
},
|
||||
/** 选项值,非受控属性 */
|
||||
defaultValue: {
|
||||
type: [String, Number],
|
||||
},
|
||||
/** 是否展示 */
|
||||
visible: Boolean,
|
||||
/** 值发生变更时触发 */
|
||||
onChange: {
|
||||
type: Function,
|
||||
default: () => ({}),
|
||||
},
|
||||
/** 关闭时触发 */
|
||||
onClose: {
|
||||
type: Function,
|
||||
default: () => ({}),
|
||||
},
|
||||
/** 选择后触发 */
|
||||
onPick: {
|
||||
type: Function,
|
||||
default: () => ({}),
|
||||
},
|
||||
};
|
||||
77
uni_modules/tdesign-uniapp/components/cascader/type.ts
Normal file
77
uni_modules/tdesign-uniapp/components/cascader/type.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
|
||||
* */
|
||||
|
||||
import type { TreeOptionData, TreeKeysType } from '../common/common';
|
||||
|
||||
export interface TdCascaderProps<CascaderOption extends TreeOptionData = TreeOptionData> {
|
||||
/**
|
||||
* 父子节点选中状态不再关联,可各自选中或取消
|
||||
* @default false
|
||||
*/
|
||||
checkStrictly?: boolean;
|
||||
/**
|
||||
* 关闭按钮
|
||||
* @default true
|
||||
*/
|
||||
closeBtn?: boolean;
|
||||
/**
|
||||
* 用来定义 value / label / children / disabled 在 `options` 中对应的字段别名
|
||||
*/
|
||||
keys?: CascaderKeysType;
|
||||
/**
|
||||
* 可选项数据源
|
||||
* @default []
|
||||
*/
|
||||
options?: Array<CascaderOption>;
|
||||
/**
|
||||
* 未选中时的提示文案
|
||||
* @default 选择选项
|
||||
*/
|
||||
placeholder?: string;
|
||||
/**
|
||||
* 每级展示的次标题
|
||||
* @default []
|
||||
*/
|
||||
subTitles?: Array<string>;
|
||||
/**
|
||||
* 展示风格
|
||||
* @default step
|
||||
*/
|
||||
theme?: 'step' | 'tab';
|
||||
/**
|
||||
* 标题
|
||||
*/
|
||||
title?: string;
|
||||
/**
|
||||
* 选项值
|
||||
*/
|
||||
value?: string | number;
|
||||
/**
|
||||
* 选项值,非受控属性
|
||||
*/
|
||||
defaultValue?: string | number;
|
||||
/**
|
||||
* 是否展示
|
||||
* @default false
|
||||
*/
|
||||
visible?: boolean;
|
||||
/**
|
||||
* 值发生变更时触发
|
||||
*/
|
||||
onChange?: (context: { value: string | number; selectedOptions: string[] }) => void;
|
||||
/**
|
||||
* 关闭时触发
|
||||
*/
|
||||
onClose?: (context: { trigger: CascaderTriggerSource }) => void;
|
||||
/**
|
||||
* 选择后触发
|
||||
*/
|
||||
onPick?: (context: { value: string | number; label: string; index: number; level: number }) => void;
|
||||
}
|
||||
|
||||
export type CascaderKeysType = TreeKeysType;
|
||||
|
||||
export type CascaderTriggerSource = 'overlay' | 'close-btn' | 'finish';
|
||||
@@ -0,0 +1,44 @@
|
||||
.t-cell-group {
|
||||
position: relative;
|
||||
}
|
||||
.t-cell-group__title {
|
||||
font-family: PingFangSC-Regular;
|
||||
font-size: var(--td-cell-group-title-font-size, 28rpx);
|
||||
color: var(--td-cell-group-title-color, var(--td-text-color-placeholder, var(--td-font-gray-3, rgba(0, 0, 0, 0.4))));
|
||||
text-align: left;
|
||||
line-height: var(--td-cell-group-title-line-height, 90rpx);
|
||||
background-color: var(--td-cell-group-title-bg-color, var(--td-bg-color-secondarycontainer, var(--td-gray-color-1, #f3f3f3)));
|
||||
padding-left: var(--td-cell-group-title-padding-left, 32rpx);
|
||||
}
|
||||
.t-cell-group--bordered::before {
|
||||
position: absolute;
|
||||
box-sizing: border-box;
|
||||
content: ' ';
|
||||
pointer-events: none;
|
||||
right: 0;
|
||||
left: 0;
|
||||
top: 0;
|
||||
border-top: 1px solid var(--td-cell-group-border-color, var(--td-component-stroke, var(--td-gray-color-3, #e7e7e7)));
|
||||
transform: scaleY(0.5);
|
||||
transform-origin: 0 0;
|
||||
transform-origin: top;
|
||||
z-index: 1;
|
||||
}
|
||||
.t-cell-group--bordered::after {
|
||||
position: absolute;
|
||||
box-sizing: border-box;
|
||||
content: ' ';
|
||||
pointer-events: none;
|
||||
right: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
border-bottom: 1px solid var(--td-cell-group-border-color, var(--td-component-stroke, var(--td-gray-color-3, #e7e7e7)));
|
||||
transform: scaleY(0.5);
|
||||
transform-origin: bottom;
|
||||
z-index: 1;
|
||||
}
|
||||
.t-cell-group--card {
|
||||
margin: 0 32rpx;
|
||||
border-radius: var(--td-radius-large, 18rpx);
|
||||
overflow: hidden;
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<template>
|
||||
<view>
|
||||
<view
|
||||
v-if="title"
|
||||
:class="[
|
||||
classPrefix + '__title ',
|
||||
tClassTitle
|
||||
]"
|
||||
>
|
||||
{{ title }}
|
||||
</view>
|
||||
<view
|
||||
:style="tools._style([customStyle])"
|
||||
:class="[
|
||||
tools.cls(classPrefix, [['bordered', bordered], theme]),
|
||||
tClass
|
||||
]"
|
||||
>
|
||||
<slot />
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import { uniComponent } from '../common/src/index';
|
||||
import { prefix } from '../common/config';
|
||||
import props from './props';
|
||||
import tools from '../common/utils.wxs';
|
||||
import { ParentMixin, RELATION_MAP } from '../common/relation';
|
||||
|
||||
|
||||
const name = `${prefix}-cell-group`;
|
||||
|
||||
|
||||
export default uniComponent({
|
||||
name,
|
||||
options: {
|
||||
styleIsolation: 'shared',
|
||||
},
|
||||
externalClasses: [`${prefix}-class`, `${prefix}-class-title`],
|
||||
mixins: [ParentMixin(RELATION_MAP.Cell)],
|
||||
props: {
|
||||
...props,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
prefix,
|
||||
classPrefix: name,
|
||||
tools,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
innerAfterLinked() {
|
||||
this.updateLastChid();
|
||||
},
|
||||
innerAfterUnLinked() {
|
||||
this.updateLastChid();
|
||||
},
|
||||
updateLastChid() {
|
||||
const { children } = this;
|
||||
children.forEach((child, index) => {
|
||||
child.isLastChild = index === children.length - 1;
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style scoped>
|
||||
@import './cell-group.css';
|
||||
</style>
|
||||
25
uni_modules/tdesign-uniapp/components/cell-group/props.ts
Normal file
25
uni_modules/tdesign-uniapp/components/cell-group/props.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
|
||||
* */
|
||||
|
||||
import type { TdCellGroupProps } from './type';
|
||||
export default {
|
||||
/** 是否显示组边框 */
|
||||
bordered: Boolean,
|
||||
/** 单元格组风格 */
|
||||
theme: {
|
||||
type: String,
|
||||
default: 'default' as TdCellGroupProps['theme'],
|
||||
validator(val: TdCellGroupProps['theme']): boolean {
|
||||
if (!val) return true;
|
||||
return ['default', 'card'].includes(val);
|
||||
},
|
||||
},
|
||||
/** 单元格组标题 */
|
||||
title: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
};
|
||||
23
uni_modules/tdesign-uniapp/components/cell-group/type.ts
Normal file
23
uni_modules/tdesign-uniapp/components/cell-group/type.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
|
||||
* */
|
||||
|
||||
export interface TdCellGroupProps {
|
||||
/**
|
||||
* 是否显示组边框
|
||||
* @default false
|
||||
*/
|
||||
bordered?: boolean;
|
||||
/**
|
||||
* 单元格组风格
|
||||
* @default default
|
||||
*/
|
||||
theme?: 'default' | 'card';
|
||||
/**
|
||||
* 单元格组标题
|
||||
* @default ''
|
||||
*/
|
||||
title?: string;
|
||||
}
|
||||
116
uni_modules/tdesign-uniapp/components/cell/README.en-US.md
Normal file
116
uni_modules/tdesign-uniapp/components/cell/README.en-US.md
Normal file
@@ -0,0 +1,116 @@
|
||||
:: BASE_DOC ::
|
||||
|
||||
## API
|
||||
|
||||
### Cell Props
|
||||
|
||||
name | type | default | description | required
|
||||
-- | -- | -- | -- | --
|
||||
custom-style | Object | - | CSS(Cascading Style Sheets) | N
|
||||
align | String | middle | options: top/middle/bottom | N
|
||||
arrow | Boolean / Object | false | \- | N
|
||||
bordered | Boolean | true | \- | N
|
||||
description | String | - | \- | N
|
||||
hover | Boolean | - | \- | N
|
||||
image | String | - | \- | N
|
||||
jump-type | String | navigateTo | options: switchTab/reLaunch/redirectTo/navigateTo | N
|
||||
left-icon | String / Object | - | \- | N
|
||||
note | String | - | \- | N
|
||||
note-style | String / Object | - | \- | N
|
||||
required | Boolean | false | \- | N
|
||||
right-icon | String / Object | - | \- | N
|
||||
right-icon-style | String / Object | - | \- | N
|
||||
title | String | - | \- | N
|
||||
title-style | String / Object | - | \- | N
|
||||
url | String | - | \- | N
|
||||
|
||||
### Cell Events
|
||||
|
||||
name | params | description
|
||||
-- | -- | --
|
||||
click | `(e: MouseEvent)` | \-
|
||||
|
||||
### Cell Slots
|
||||
|
||||
name | Description
|
||||
-- | --
|
||||
description | \-
|
||||
image | \-
|
||||
left-icon | \-
|
||||
note | \-
|
||||
right-icon | \-
|
||||
title | \-
|
||||
|
||||
### Cell External Classes
|
||||
|
||||
className | Description
|
||||
-- | --
|
||||
t-class | \-
|
||||
t-class-center | \-
|
||||
t-class-description | \-
|
||||
t-class-hover | \-
|
||||
t-class-image | \-
|
||||
t-class-left | \-
|
||||
t-class-left-icon | \-
|
||||
t-class-note | \-
|
||||
t-class-right | \-
|
||||
t-class-right-icon | \-
|
||||
t-class-title | \-
|
||||
|
||||
|
||||
### CellGroup Props
|
||||
|
||||
name | type | default | description | required
|
||||
-- | -- | -- | -- | --
|
||||
custom-style | Object | - | CSS(Cascading Style Sheets) | N
|
||||
bordered | Boolean | false | \- | N
|
||||
theme | String | default | options: default/card | N
|
||||
title | String | - | \- | N
|
||||
|
||||
### CellGroup Slots
|
||||
|
||||
name | Description
|
||||
-- | --
|
||||
\- | \-
|
||||
|
||||
### CellGroup External Classes
|
||||
|
||||
className | Description
|
||||
-- | --
|
||||
t-class | \-
|
||||
t-class-title | \-
|
||||
|
||||
### CSS Variables
|
||||
|
||||
The component provides the following CSS variables, which can be used to customize styles.
|
||||
Name | Default Value | Description
|
||||
-- | -- | --
|
||||
--td-cell-group-border-color | @component-stroke | -
|
||||
--td-cell-group-title-bg-color | @bg-color-secondarycontainer | -
|
||||
--td-cell-group-title-color | @text-color-placeholder | -
|
||||
--td-cell-group-title-font-size | 28rpx | -
|
||||
--td-cell-group-title-line-height | 90rpx | -
|
||||
--td-cell-group-title-padding-left | 32rpx | -
|
||||
--td-cell-bg-color | @bg-color-container | -
|
||||
--td-cell-border-color | @component-stroke | -
|
||||
--td-cell-border-left-space | @cell-horizontal-padding | -
|
||||
--td-cell-border-right-space | 0 | -
|
||||
--td-cell-border-width | 1px | -
|
||||
--td-cell-description-color | @text-color-secondary | -
|
||||
--td-cell-description-font | @font-body-medium | -
|
||||
--td-cell-height | auto | -
|
||||
--td-cell-horizontal-padding | 32rpx | -
|
||||
--td-cell-hover-color | @bg-color-secondarycontainer | -
|
||||
--td-cell-image-height | 96rpx | -
|
||||
--td-cell-image-width | 96rpx | -
|
||||
--td-cell-left-icon-color | @brand-color | -
|
||||
--td-cell-left-icon-size | 48rpx | -
|
||||
--td-cell-note-color | @text-color-placeholder | -
|
||||
--td-cell-note-font-size | @font-size-m | -
|
||||
--td-cell-required-color | @error-color | -
|
||||
--td-cell-required-font-size | @font-size-m | -
|
||||
--td-cell-right-icon-color | @text-color-placeholder | -
|
||||
--td-cell-right-icon-size | 48rpx | -
|
||||
--td-cell-title-color | @text-color-primary | -
|
||||
--td-cell-title-font | @font-body-large | -
|
||||
--td-cell-vertical-padding | 32rpx | -
|
||||
147
uni_modules/tdesign-uniapp/components/cell/README.md
Normal file
147
uni_modules/tdesign-uniapp/components/cell/README.md
Normal file
@@ -0,0 +1,147 @@
|
||||
---
|
||||
title: Cell 单元格
|
||||
description: 用于各个类别行的信息展示。
|
||||
spline: data
|
||||
isComponent: true
|
||||
---
|
||||
|
||||
|
||||
## 引入
|
||||
|
||||
可在 `main.ts` 或在需要使用的页面或组件中引入。
|
||||
|
||||
```js
|
||||
import TCell from '@tdesign/uniapp/cell/cell.vue';
|
||||
import TCellGroup from '@tdesign/uniapp/cell-group/cell-group.vue';
|
||||
```
|
||||
|
||||
### 类型
|
||||
|
||||
单行单元格
|
||||
|
||||
{{ base }}
|
||||
|
||||
多行单元格
|
||||
|
||||
{{ multiple }}
|
||||
|
||||
### 样式
|
||||
|
||||
卡片单元格
|
||||
|
||||
{{ theme }}
|
||||
|
||||
## API
|
||||
|
||||
### Cell Props
|
||||
|
||||
名称 | 类型 | 默认值 | 描述 | 必传
|
||||
-- | -- | -- | -- | --
|
||||
custom-style | Object | - | 自定义样式 | N
|
||||
align | String | middle | 右侧内容的对齐方式,默认居中对齐。可选项:top/middle/bottom | N
|
||||
arrow | Boolean / Object | false | 是否显示右侧箭头 | N
|
||||
bordered | Boolean | true | 是否显示下边框 | N
|
||||
description | String | - | 下方内容描述 | N
|
||||
hover | Boolean | - | 是否开启点击反馈 | N
|
||||
image | String | - | 主图 | N
|
||||
jump-type | String | navigateTo | 链接跳转类型。可选项:switchTab/reLaunch/redirectTo/navigateTo | N
|
||||
left-icon | String / Object | - | 左侧图标,出现在单元格标题的左侧 | N
|
||||
note | String | - | 和标题同行的说明文字 | N
|
||||
note-style | String / Object | - | 说明文字自定义样式 | N
|
||||
required | Boolean | false | 是否显示表单必填星号 | N
|
||||
right-icon | String / Object | - | 最右侧图标 | N
|
||||
right-icon-style | String / Object | - | 右侧图标自定义样式 | N
|
||||
title | String | - | 标题 | N
|
||||
title-style | String / Object | - | 标题自定义样式 | N
|
||||
url | String | - | 点击后跳转链接地址。如果值为空,则表示不需要跳转 | N
|
||||
|
||||
### Cell Events
|
||||
|
||||
名称 | 参数 | 描述
|
||||
-- | -- | --
|
||||
click | `(e: MouseEvent)` | 右侧内容
|
||||
|
||||
### Cell Slots
|
||||
|
||||
名称 | 描述
|
||||
-- | --
|
||||
description | 自定义 `description` 显示内容
|
||||
image | 自定义 `image` 显示内容
|
||||
left-icon | 自定义 `left-icon` 显示内容
|
||||
note | 自定义 `note` 显示内容
|
||||
right-icon | 自定义 `right-icon` 显示内容
|
||||
title | 自定义 `title` 显示内容
|
||||
|
||||
### Cell External Classes
|
||||
|
||||
类名 | 描述
|
||||
-- | --
|
||||
t-class | 根节点样式类
|
||||
t-class-center | 中间(`title`, `description`)内容样式类
|
||||
t-class-description | 下方描述内容样式类
|
||||
t-class-hover | 悬停样式类
|
||||
t-class-image | 图片样式类
|
||||
t-class-left | 左侧内容样式类
|
||||
t-class-left-icon | 左侧图标样式类
|
||||
t-class-note | 右侧说明文字样式类
|
||||
t-class-right | 右侧内容样式类
|
||||
t-class-right-icon | 右侧图标样式类
|
||||
t-class-title | 标题样式类
|
||||
|
||||
|
||||
### CellGroup Props
|
||||
|
||||
名称 | 类型 | 默认值 | 描述 | 必传
|
||||
-- | -- | -- | -- | --
|
||||
custom-style | Object | - | 自定义样式 | N
|
||||
bordered | Boolean | false | 是否显示组边框 | N
|
||||
theme | String | default | 单元格组风格。可选项:default/card | N
|
||||
title | String | - | 单元格组标题 | N
|
||||
|
||||
### CellGroup Slots
|
||||
|
||||
名称 | 描述
|
||||
-- | --
|
||||
\- | 默认插槽,自定义内容区域内容
|
||||
|
||||
### CellGroup External Classes
|
||||
|
||||
类名 | 描述
|
||||
-- | --
|
||||
t-class | 根节点样式类
|
||||
t-class-title | 标题样式类
|
||||
|
||||
### CSS Variables
|
||||
|
||||
组件提供了下列 CSS 变量,可用于自定义样式。
|
||||
名称 | 默认值 | 描述
|
||||
-- | -- | --
|
||||
--td-cell-group-border-color | @component-stroke | -
|
||||
--td-cell-group-title-bg-color | @bg-color-secondarycontainer | -
|
||||
--td-cell-group-title-color | @text-color-placeholder | -
|
||||
--td-cell-group-title-font-size | 28rpx | -
|
||||
--td-cell-group-title-line-height | 90rpx | -
|
||||
--td-cell-group-title-padding-left | 32rpx | -
|
||||
--td-cell-bg-color | @bg-color-container | -
|
||||
--td-cell-border-color | @component-stroke | -
|
||||
--td-cell-border-left-space | @cell-horizontal-padding | -
|
||||
--td-cell-border-right-space | 0 | -
|
||||
--td-cell-border-width | 1px | -
|
||||
--td-cell-description-color | @text-color-secondary | -
|
||||
--td-cell-description-font | @font-body-medium | -
|
||||
--td-cell-height | auto | -
|
||||
--td-cell-horizontal-padding | 32rpx | -
|
||||
--td-cell-hover-color | @bg-color-secondarycontainer | -
|
||||
--td-cell-image-height | 96rpx | -
|
||||
--td-cell-image-width | 96rpx | -
|
||||
--td-cell-left-icon-color | @brand-color | -
|
||||
--td-cell-left-icon-size | 48rpx | -
|
||||
--td-cell-note-color | @text-color-placeholder | -
|
||||
--td-cell-note-font-size | @font-size-m | -
|
||||
--td-cell-required-color | @error-color | -
|
||||
--td-cell-required-font-size | @font-size-m | -
|
||||
--td-cell-right-icon-color | @text-color-placeholder | -
|
||||
--td-cell-right-icon-size | 48rpx | -
|
||||
--td-cell-title-color | @text-color-primary | -
|
||||
--td-cell-title-font | @font-body-large | -
|
||||
--td-cell-vertical-padding | 32rpx | -
|
||||
94
uni_modules/tdesign-uniapp/components/cell/cell.css
Normal file
94
uni_modules/tdesign-uniapp/components/cell/cell.css
Normal file
@@ -0,0 +1,94 @@
|
||||
.t-cell {
|
||||
position: relative;
|
||||
display: flex;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
padding: var(--td-cell-vertical-padding, 32rpx) var(--td-cell-horizontal-padding, 32rpx);
|
||||
height: var(--td-cell-height, auto);
|
||||
background-color: var(--td-cell-bg-color, var(--td-bg-color-container, var(--td-font-white-1, #ffffff)));
|
||||
}
|
||||
.t-cell--bordered::after {
|
||||
position: absolute;
|
||||
box-sizing: border-box;
|
||||
content: ' ';
|
||||
pointer-events: none;
|
||||
right: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
border-bottom: var(--td-cell-border-width, 1px) solid var(--td-cell-border-color, var(--td-component-stroke, var(--td-gray-color-3, #e7e7e7)));
|
||||
transform: scaleY(0.5);
|
||||
transform-origin: bottom;
|
||||
left: var(--td-cell-border-left-space, var(--td-cell-horizontal-padding, 32rpx));
|
||||
right: var(--td-cell-border-right-space, 0);
|
||||
}
|
||||
.t-cell__description {
|
||||
font: var(--td-cell-description-font, var(--td-font-body-medium, 28rpx / 44rpx var(--td-font-family, PingFang SC, Microsoft YaHei, Arial Regular)));
|
||||
color: var(--td-cell-description-color, var(--td-text-color-secondary, var(--td-font-gray-2, rgba(0, 0, 0, 0.6))));
|
||||
}
|
||||
.t-cell__description-text {
|
||||
margin-top: calc(var(--td-spacer, 16rpx) / 2);
|
||||
}
|
||||
.t-cell__note {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
color: var(--td-cell-note-color, var(--td-text-color-placeholder, var(--td-font-gray-3, rgba(0, 0, 0, 0.4))));
|
||||
font-size: var(--td-cell-note-font-size, var(--td-font-size-m, 32rpx));
|
||||
}
|
||||
.t-cell__title {
|
||||
margin-right: var(--td-spacer-2, 32rpx);
|
||||
}
|
||||
.t-cell__title,
|
||||
.t-cell__note {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
.t-cell__title:empty,
|
||||
.t-cell__note:empty {
|
||||
display: none;
|
||||
}
|
||||
.t-cell__title-text {
|
||||
display: flex;
|
||||
font: var(--td-cell-title-font, var(--td-font-body-large, 32rpx / 48rpx var(--td-font-family, PingFang SC, Microsoft YaHei, Arial Regular)));
|
||||
color: var(--td-cell-title-color, var(--td-text-color-primary, var(--td-font-gray-1, rgba(0, 0, 0, 0.9))));
|
||||
}
|
||||
.t-cell__left,
|
||||
.t-cell__right {
|
||||
align-self: stretch;
|
||||
}
|
||||
.t-cell__left:not(:empty) {
|
||||
margin-right: var(--td-spacer-1, 24rpx);
|
||||
}
|
||||
.t-cell__left-icon {
|
||||
color: var(--td-cell-left-icon-color, var(--td-brand-color, var(--td-primary-color-7, #0052d9)));
|
||||
font-size: var(--td-cell-left-icon-size, 48rpx);
|
||||
}
|
||||
.t-cell__left-image {
|
||||
height: var(--td-cell-image-height, 96rpx);
|
||||
width: var(--td-cell-image-width, 96rpx);
|
||||
}
|
||||
.t-cell__note:not(:empty) + .t-cell__right {
|
||||
margin-left: calc(var(--td-spacer, 16rpx) / 2);
|
||||
}
|
||||
.t-cell__right {
|
||||
display: flex;
|
||||
}
|
||||
.t-cell__right-icon {
|
||||
color: var(--td-cell-right-icon-color, var(--td-text-color-placeholder, var(--td-font-gray-3, rgba(0, 0, 0, 0.4))));
|
||||
font-size: var(--td-cell-right-icon-size, 48rpx);
|
||||
}
|
||||
.t-cell__right--middle {
|
||||
align-items: center;
|
||||
}
|
||||
.t-cell__right--top {
|
||||
align-items: flex-start;
|
||||
}
|
||||
.t-cell__right--bottom {
|
||||
align-items: flex-end;
|
||||
}
|
||||
.t-cell--hover {
|
||||
background-color: var(--td-cell-hover-color, var(--td-bg-color-secondarycontainer, var(--td-gray-color-1, #f3f3f3)));
|
||||
}
|
||||
.t-cell--required {
|
||||
font-size: var(--td-cell-required-font-size, var(--td-font-size-m, 32rpx));
|
||||
color: var(--td-cell-required-color, var(--td-error-color, var(--td-error-color-6, #d54941)));
|
||||
}
|
||||
260
uni_modules/tdesign-uniapp/components/cell/cell.vue
Normal file
260
uni_modules/tdesign-uniapp/components/cell/cell.vue
Normal file
@@ -0,0 +1,260 @@
|
||||
<template>
|
||||
<view
|
||||
:style="tools._style([customStyle])"
|
||||
:class="[
|
||||
tClass,
|
||||
tools.cls(classPrefix, [['bordered', bordered || isLastChild]])
|
||||
]"
|
||||
:hover-class="hover ? classPrefix + '--hover' : ''"
|
||||
hover-stay-time="70"
|
||||
:aria-role="ariaRole || (arrow ? 'button' : '')"
|
||||
:aria-label="ariaLabel"
|
||||
@click="onClick"
|
||||
>
|
||||
<view :class="classPrefix + '__left ' + tClassLeft">
|
||||
<block
|
||||
v-if="_leftIcon"
|
||||
name="icon"
|
||||
>
|
||||
<t-icon
|
||||
:custom-style="leftIconCustomStyle"
|
||||
:t-class="classPrefix + '__left-icon ' + tClassLeftIcon"
|
||||
:name="_leftIcon.name"
|
||||
:size="_leftIcon.size"
|
||||
:color="_leftIcon.color"
|
||||
:aria-hidden="true"
|
||||
:aria-label="_leftIcon.ariaLabel"
|
||||
:aria-role="_leftIcon.ariaRole"
|
||||
@click="'handleClose' || ''"
|
||||
/>
|
||||
</block>
|
||||
<slot name="left-icon" />
|
||||
<t-image
|
||||
v-if="image"
|
||||
shape="round"
|
||||
:t-class="classPrefix + '__left-image ' + tClassImage"
|
||||
:src="image"
|
||||
:custom-style="leftImageCustomStyle"
|
||||
/>
|
||||
<slot name="image" />
|
||||
</view>
|
||||
<view :class="classPrefix + '__title ' + tClassCenter">
|
||||
<view
|
||||
:class="[
|
||||
classPrefix + '__title-text ',
|
||||
tClassTitle
|
||||
]"
|
||||
:style="tools._style(titleStyle)"
|
||||
>
|
||||
<block v-if="title">
|
||||
{{ title }}
|
||||
</block>
|
||||
<slot name="title" />
|
||||
<block v-if="required">
|
||||
<text
|
||||
decode
|
||||
:class="classPrefix + '--required'"
|
||||
>
|
||||
*
|
||||
</text>
|
||||
</block>
|
||||
</view>
|
||||
<view
|
||||
:class="[
|
||||
classPrefix + '__description ',
|
||||
tClassDescription
|
||||
]"
|
||||
>
|
||||
<view
|
||||
v-if="description"
|
||||
:class="classPrefix + '__description-text'"
|
||||
>
|
||||
{{ description }}
|
||||
</view>
|
||||
<slot name="description" />
|
||||
</view>
|
||||
</view>
|
||||
<view
|
||||
:class="[
|
||||
classPrefix + '__note ',
|
||||
tClassNote
|
||||
]"
|
||||
:style="tools._style(noteStyle)"
|
||||
>
|
||||
<text v-if="note">
|
||||
{{ note }}
|
||||
</text>
|
||||
<slot name="note" />
|
||||
</view>
|
||||
<view
|
||||
:class="[
|
||||
tools.cls(classPrefix + '__right', [align]),
|
||||
tClassRight
|
||||
]"
|
||||
>
|
||||
<t-icon
|
||||
v-if="_arrow"
|
||||
:custom-style="rightArrowCustomStyle"
|
||||
:t-class=" classPrefix + '__right-icon ' + tClassRightIcon"
|
||||
:name="_arrow.name || ''"
|
||||
:size="_arrow.size"
|
||||
:color="_arrow.color"
|
||||
:aria-hidden="true"
|
||||
:aria-label="_arrow.ariaLabel"
|
||||
:aria-role="_arrow.ariaRole"
|
||||
@click="'handleClose' || ''"
|
||||
/>
|
||||
<block v-else>
|
||||
<block
|
||||
v-if="_rightIcon"
|
||||
name="icon"
|
||||
>
|
||||
<t-icon
|
||||
:custom-style="rightIconCustomStyle"
|
||||
:t-class=" classPrefix + '__right-icon ' + tClassRightIcon"
|
||||
:name="_rightIcon.name"
|
||||
:size="_rightIcon.size"
|
||||
:color="_rightIcon.color || ''"
|
||||
:aria-hidden="true"
|
||||
:aria-label="_rightIcon.ariaLabel"
|
||||
:aria-role="_rightIcon.ariaRole"
|
||||
@click="'handleClose' || ''"
|
||||
/>
|
||||
</block>
|
||||
<slot name="right-icon" />
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import TIcon from '../icon/icon';
|
||||
import TImage from '../image/image';
|
||||
import { uniComponent } from '../common/src/index';
|
||||
import { prefix } from '../common/config';
|
||||
import props from './props';
|
||||
import { calcIcon } from '../common/utils';
|
||||
import tools from '../common/utils.wxs';
|
||||
|
||||
import { ChildrenMixin, RELATION_MAP } from '../common/relation';
|
||||
|
||||
|
||||
const name = `${prefix}-cell`;
|
||||
const COMMON_RIGHT_ICON_STYLE = {
|
||||
color: 'var(--td-cell-right-icon-color, var(--td-text-color-placeholder, var(--td-font-gray-3, rgba(0, 0, 0, .4))))',
|
||||
fontSize: 'var(--td-cell-right-icon-font-size, 24px)',
|
||||
};
|
||||
|
||||
export default uniComponent({
|
||||
name,
|
||||
options: {
|
||||
styleIsolation: 'shared',
|
||||
},
|
||||
externalClasses: [
|
||||
`${prefix}-class`,
|
||||
`${prefix}-class-title`,
|
||||
`${prefix}-class-description`,
|
||||
`${prefix}-class-note`,
|
||||
`${prefix}-class-hover`,
|
||||
`${prefix}-class-image`,
|
||||
`${prefix}-class-left`,
|
||||
`${prefix}-class-left-icon`,
|
||||
`${prefix}-class-center`,
|
||||
`${prefix}-class-right`,
|
||||
`${prefix}-class-right-icon`,
|
||||
],
|
||||
mixins: [ChildrenMixin(RELATION_MAP.Cell)],
|
||||
components: {
|
||||
TIcon,
|
||||
TImage,
|
||||
},
|
||||
props: {
|
||||
...props,
|
||||
},
|
||||
emits: [
|
||||
'click',
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
prefix,
|
||||
classPrefix: name,
|
||||
_arrow: null,
|
||||
_rightIcon: null,
|
||||
_leftIcon: null,
|
||||
isLastChild: false,
|
||||
tools,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
rightArrowCustomStyle() {
|
||||
return tools._style([
|
||||
COMMON_RIGHT_ICON_STYLE,
|
||||
this.rightIconStyle || '',
|
||||
this._arrow.style || '',
|
||||
]);
|
||||
},
|
||||
rightIconCustomStyle() {
|
||||
return tools._style([
|
||||
COMMON_RIGHT_ICON_STYLE,
|
||||
this.rightIconStyle || '',
|
||||
this._rightIcon.style || '',
|
||||
]);
|
||||
},
|
||||
leftIconCustomStyle() {
|
||||
return tools._style([
|
||||
{
|
||||
color: 'var(--td-cell-left-icon-color, var(--td-brand-color, var(--td-primary-color-7, #0052d9)))',
|
||||
fontSize: 'var(--td-cell-left-icon-font-size, 24px)',
|
||||
},
|
||||
this._leftIcon.style || '',
|
||||
]);
|
||||
},
|
||||
leftImageCustomStyle() {
|
||||
return tools._style({
|
||||
height: 'var(--td-cell-image-height, 48px)',
|
||||
width: 'var(--td-cell-image-width, 48px)',
|
||||
});
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
leftIcon: {
|
||||
handler(e) {
|
||||
this.setIcon('_leftIcon', e, '');
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
rightIcon: {
|
||||
handler(e) {
|
||||
this.setIcon('_rightIcon', e, '');
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
arrow: {
|
||||
handler(e) {
|
||||
this.setIcon('_arrow', e, 'chevron-right');
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
setIcon(e, t, s) {
|
||||
this[e] = calcIcon(t, s);
|
||||
},
|
||||
onClick(e) {
|
||||
this.$emit('click', e);
|
||||
this.jumpLink();
|
||||
},
|
||||
jumpLink(e = 'url', t = 'jumpType') {
|
||||
const s = this[e];
|
||||
const i = this[t];
|
||||
if (s) {
|
||||
uni[i]({
|
||||
url: s,
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style scoped>
|
||||
@import './cell.css';
|
||||
</style>
|
||||
87
uni_modules/tdesign-uniapp/components/cell/props.ts
Normal file
87
uni_modules/tdesign-uniapp/components/cell/props.ts
Normal file
@@ -0,0 +1,87 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
|
||||
* */
|
||||
|
||||
import type { TdCellProps } from './type';
|
||||
export default {
|
||||
/** 右侧内容的对齐方式,默认居中对齐 */
|
||||
align: {
|
||||
type: String,
|
||||
default: 'middle' as TdCellProps['align'],
|
||||
validator(val: TdCellProps['align']): boolean {
|
||||
if (!val) return true;
|
||||
return ['top', 'middle', 'bottom'].includes(val);
|
||||
},
|
||||
},
|
||||
/** 是否显示右侧箭头 */
|
||||
arrow: {
|
||||
type: [Boolean, Object],
|
||||
default: false as TdCellProps['arrow'],
|
||||
},
|
||||
/** 是否显示下边框 */
|
||||
bordered: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
/** 下方内容描述 */
|
||||
description: {
|
||||
type: String,
|
||||
},
|
||||
/** 是否开启点击反馈 */
|
||||
hover: Boolean,
|
||||
/** 主图 */
|
||||
image: {
|
||||
type: String,
|
||||
},
|
||||
/** 链接跳转类型 */
|
||||
jumpType: {
|
||||
type: String,
|
||||
default: 'navigateTo' as TdCellProps['jumpType'],
|
||||
validator(val: TdCellProps['jumpType']): boolean {
|
||||
if (!val) return true;
|
||||
return ['switchTab', 'reLaunch', 'redirectTo', 'navigateTo'].includes(val);
|
||||
},
|
||||
},
|
||||
/** 左侧图标,出现在单元格标题的左侧 */
|
||||
leftIcon: {
|
||||
type: [String, Object],
|
||||
},
|
||||
/** 和标题同行的说明文字 */
|
||||
note: {
|
||||
type: String,
|
||||
},
|
||||
/** 说明文字自定义样式 */
|
||||
noteStyle: {
|
||||
type: [String, Object],
|
||||
},
|
||||
/** 是否显示表单必填星号 */
|
||||
required: Boolean,
|
||||
/** 最右侧图标 */
|
||||
rightIcon: {
|
||||
type: [String, Object],
|
||||
},
|
||||
/** 右侧图标自定义样式 */
|
||||
rightIconStyle: {
|
||||
type: [String, Object],
|
||||
},
|
||||
/** 标题 */
|
||||
title: {
|
||||
type: String,
|
||||
},
|
||||
/** 标题自定义样式 */
|
||||
titleStyle: {
|
||||
type: [String, Object],
|
||||
},
|
||||
/** 点击后跳转链接地址。如果值为空,则表示不需要跳转 */
|
||||
url: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
/** 右侧内容 */
|
||||
onClick: {
|
||||
type: Function,
|
||||
default: () => ({}),
|
||||
},
|
||||
};
|
||||
82
uni_modules/tdesign-uniapp/components/cell/type.ts
Normal file
82
uni_modules/tdesign-uniapp/components/cell/type.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
|
||||
* */
|
||||
|
||||
export interface TdCellProps {
|
||||
/**
|
||||
* 右侧内容的对齐方式,默认居中对齐
|
||||
* @default middle
|
||||
*/
|
||||
align?: 'top' | 'middle' | 'bottom';
|
||||
/**
|
||||
* 是否显示右侧箭头
|
||||
* @default false
|
||||
*/
|
||||
arrow?: boolean | object;
|
||||
/**
|
||||
* 是否显示下边框
|
||||
* @default true
|
||||
*/
|
||||
bordered?: boolean;
|
||||
/**
|
||||
* 下方内容描述
|
||||
*/
|
||||
description?: string;
|
||||
/**
|
||||
* 是否开启点击反馈
|
||||
*/
|
||||
hover?: boolean;
|
||||
/**
|
||||
* 主图
|
||||
*/
|
||||
image?: string;
|
||||
/**
|
||||
* 链接跳转类型
|
||||
* @default navigateTo
|
||||
*/
|
||||
jumpType?: 'switchTab' | 'reLaunch' | 'redirectTo' | 'navigateTo';
|
||||
/**
|
||||
* 左侧图标,出现在单元格标题的左侧
|
||||
*/
|
||||
leftIcon?: string | object;
|
||||
/**
|
||||
* 和标题同行的说明文字
|
||||
*/
|
||||
note?: string;
|
||||
/**
|
||||
* 说明文字自定义样式
|
||||
*/
|
||||
noteStyle?: string | object;
|
||||
/**
|
||||
* 是否显示表单必填星号
|
||||
* @default false
|
||||
*/
|
||||
required?: boolean;
|
||||
/**
|
||||
* 最右侧图标
|
||||
*/
|
||||
rightIcon?: string | object;
|
||||
/**
|
||||
* 右侧图标自定义样式
|
||||
*/
|
||||
rightIconStyle?: string | object;
|
||||
/**
|
||||
* 标题
|
||||
*/
|
||||
title?: string;
|
||||
/**
|
||||
* 标题自定义样式
|
||||
*/
|
||||
titleStyle?: string | object;
|
||||
/**
|
||||
* 点击后跳转链接地址。如果值为空,则表示不需要跳转
|
||||
* @default ''
|
||||
*/
|
||||
url?: string;
|
||||
/**
|
||||
* 右侧内容
|
||||
*/
|
||||
onClick?: (e: MouseEvent) => void;
|
||||
}
|
||||
197
uni_modules/tdesign-uniapp/components/check-tag/check-tag.css
Normal file
197
uni_modules/tdesign-uniapp/components/check-tag/check-tag.css
Normal file
@@ -0,0 +1,197 @@
|
||||
.t-tag {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
border: 2rpx solid transparent;
|
||||
box-sizing: border-box;
|
||||
border-radius: var(--td-tag-square-border-radius, 8rpx);
|
||||
user-select: none;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.t-tag__text {
|
||||
word-wrap: normal;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.t-tag__icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.t-tag__icon:not(:empty) + .t-tag__text:not(:empty) {
|
||||
margin-left: 8rpx;
|
||||
}
|
||||
.t-tag--small {
|
||||
padding: var(--td-tag-small-padding, 2rpx 10rpx);
|
||||
font: var(--td-tag-small-font, var(--td-font-body-extraSmall, 20rpx / 32rpx var(--td-font-family, PingFang SC, Microsoft YaHei, Arial Regular)));
|
||||
}
|
||||
.t-tag--small .t-icon,
|
||||
.t-tag--small .t-icon-close {
|
||||
font-size: var(--td-tag-small-icon-size, 24rpx);
|
||||
}
|
||||
.t-tag--medium {
|
||||
padding: var(--td-tag-medium-padding, 2rpx 14rpx);
|
||||
font: var(--td-tag-medium-font, var(--td-font-body-small, 24rpx / 40rpx var(--td-font-family, PingFang SC, Microsoft YaHei, Arial Regular)));
|
||||
}
|
||||
.t-tag--medium .t-icon,
|
||||
.t-tag--medium .t-icon-close {
|
||||
font-size: var(--td-tag-medium-icon-size, 28rpx);
|
||||
}
|
||||
.t-tag--large {
|
||||
padding: var(--td-tag-large-padding, 4rpx 14rpx);
|
||||
font: var(--td-tag-large-font, var(--td-font-body-medium, 28rpx / 44rpx var(--td-font-family, PingFang SC, Microsoft YaHei, Arial Regular)));
|
||||
}
|
||||
.t-tag--large .t-icon,
|
||||
.t-tag--large .t-icon-close {
|
||||
font-size: var(--td-tag-large-icon-size, 32rpx);
|
||||
}
|
||||
.t-tag--extra-large {
|
||||
padding: var(--td-tag-extra-large-padding, 16rpx 30rpx);
|
||||
font: var(--td-tag-extra-large-font, var(--td-font-body-medium, 28rpx / 44rpx var(--td-font-family, PingFang SC, Microsoft YaHei, Arial Regular)));
|
||||
}
|
||||
.t-tag--extra-large .t-icon,
|
||||
.t-tag--extra-large .t-icon-close {
|
||||
font-size: var(--td-tag-extra-large-icon-size, 32rpx);
|
||||
}
|
||||
.t-tag.t-tag--square {
|
||||
border-radius: var(--td-tag-square-border-radius, 8rpx);
|
||||
}
|
||||
.t-tag.t-tag--round {
|
||||
border-radius: var(--td-tag-round-border-radius, 999px);
|
||||
}
|
||||
.t-tag.t-tag--mark {
|
||||
border-radius: 0 var(--td-tag-mark-border-radius, var(--td-tag-round-border-radius, 999px)) var(--td-tag-mark-border-radius, var(--td-tag-round-border-radius, 999px)) 0;
|
||||
}
|
||||
.t-tag--dark.t-tag--default {
|
||||
color: var(--td-text-color-anti, var(--td-font-white-1, #ffffff));
|
||||
border-color: var(--td-tag-default-color, var(--td-bg-color-component, var(--td-gray-color-3, #e7e7e7)));
|
||||
background-color: var(--td-tag-default-color, var(--td-bg-color-component, var(--td-gray-color-3, #e7e7e7)));
|
||||
}
|
||||
.t-tag--dark.t-tag--primary {
|
||||
color: var(--td-text-color-anti, var(--td-font-white-1, #ffffff));
|
||||
border-color: var(--td-tag-primary-color, var(--td-brand-color, var(--td-primary-color-7, #0052d9)));
|
||||
background-color: var(--td-tag-primary-color, var(--td-brand-color, var(--td-primary-color-7, #0052d9)));
|
||||
}
|
||||
.t-tag--dark.t-tag--success {
|
||||
color: var(--td-text-color-anti, var(--td-font-white-1, #ffffff));
|
||||
border-color: var(--td-tag-success-color, var(--td-success-color, var(--td-success-color-5, #2ba471)));
|
||||
background-color: var(--td-tag-success-color, var(--td-success-color, var(--td-success-color-5, #2ba471)));
|
||||
}
|
||||
.t-tag--dark.t-tag--warning {
|
||||
color: var(--td-text-color-anti, var(--td-font-white-1, #ffffff));
|
||||
border-color: var(--td-tag-warning-color, var(--td-warning-color, var(--td-warning-color-5, #e37318)));
|
||||
background-color: var(--td-tag-warning-color, var(--td-warning-color, var(--td-warning-color-5, #e37318)));
|
||||
}
|
||||
.t-tag--dark.t-tag--danger {
|
||||
color: var(--td-text-color-anti, var(--td-font-white-1, #ffffff));
|
||||
border-color: var(--td-tag-danger-color, var(--td-error-color, var(--td-error-color-6, #d54941)));
|
||||
background-color: var(--td-tag-danger-color, var(--td-error-color, var(--td-error-color-6, #d54941)));
|
||||
}
|
||||
.t-tag--dark.t-tag--default {
|
||||
color: var(--td-tag-default-font-color, var(--td-text-color-primary, var(--td-font-gray-1, rgba(0, 0, 0, 0.9))));
|
||||
}
|
||||
.t-tag--outline.t-tag--default {
|
||||
color: var(--td-tag-default-color, var(--td-bg-color-component, var(--td-gray-color-3, #e7e7e7)));
|
||||
border-color: var(--td-tag-default-color, var(--td-bg-color-component, var(--td-gray-color-3, #e7e7e7)));
|
||||
background-color: var(--td-tag-default-light-color, var(--td-bg-color-secondarycontainer, var(--td-gray-color-1, #f3f3f3)));
|
||||
}
|
||||
.t-tag--outline.t-tag--primary {
|
||||
color: var(--td-tag-primary-color, var(--td-brand-color, var(--td-primary-color-7, #0052d9)));
|
||||
border-color: var(--td-tag-primary-color, var(--td-brand-color, var(--td-primary-color-7, #0052d9)));
|
||||
background-color: var(--td-tag-primary-light-color, var(--td-brand-color-light, var(--td-primary-color-1, #f2f3ff)));
|
||||
}
|
||||
.t-tag--outline.t-tag--success {
|
||||
color: var(--td-tag-success-color, var(--td-success-color, var(--td-success-color-5, #2ba471)));
|
||||
border-color: var(--td-tag-success-color, var(--td-success-color, var(--td-success-color-5, #2ba471)));
|
||||
background-color: var(--td-tag-success-light-color, var(--td-success-color-1, #e3f9e9));
|
||||
}
|
||||
.t-tag--outline.t-tag--warning {
|
||||
color: var(--td-tag-warning-color, var(--td-warning-color, var(--td-warning-color-5, #e37318)));
|
||||
border-color: var(--td-tag-warning-color, var(--td-warning-color, var(--td-warning-color-5, #e37318)));
|
||||
background-color: var(--td-tag-warning-light-color, var(--td-warning-color-1, #fff1e9));
|
||||
}
|
||||
.t-tag--outline.t-tag--danger {
|
||||
color: var(--td-tag-danger-color, var(--td-error-color, var(--td-error-color-6, #d54941)));
|
||||
border-color: var(--td-tag-danger-color, var(--td-error-color, var(--td-error-color-6, #d54941)));
|
||||
background-color: var(--td-tag-danger-light-color, var(--td-error-color-1, #fff0ed));
|
||||
}
|
||||
.t-tag--outline.t-tag--default {
|
||||
color: var(--td-tag-default-font-color, var(--td-text-color-primary, var(--td-font-gray-1, rgba(0, 0, 0, 0.9))));
|
||||
}
|
||||
.t-tag--outline.t-tag--default {
|
||||
background-color: var(--td-tag-outline-bg-color, var(--td-bg-color-container, var(--td-font-white-1, #ffffff)));
|
||||
}
|
||||
.t-tag--outline.t-tag--primary {
|
||||
background-color: var(--td-tag-outline-bg-color, var(--td-bg-color-container, var(--td-font-white-1, #ffffff)));
|
||||
}
|
||||
.t-tag--outline.t-tag--success {
|
||||
background-color: var(--td-tag-outline-bg-color, var(--td-bg-color-container, var(--td-font-white-1, #ffffff)));
|
||||
}
|
||||
.t-tag--outline.t-tag--warning {
|
||||
background-color: var(--td-tag-outline-bg-color, var(--td-bg-color-container, var(--td-font-white-1, #ffffff)));
|
||||
}
|
||||
.t-tag--outline.t-tag--danger {
|
||||
background-color: var(--td-tag-outline-bg-color, var(--td-bg-color-container, var(--td-font-white-1, #ffffff)));
|
||||
}
|
||||
.t-tag--light.t-tag--default {
|
||||
color: var(--td-tag-default-color, var(--td-bg-color-component, var(--td-gray-color-3, #e7e7e7)));
|
||||
border-color: var(--td-tag-default-light-color, var(--td-bg-color-secondarycontainer, var(--td-gray-color-1, #f3f3f3)));
|
||||
background-color: var(--td-tag-default-light-color, var(--td-bg-color-secondarycontainer, var(--td-gray-color-1, #f3f3f3)));
|
||||
}
|
||||
.t-tag--light.t-tag--primary {
|
||||
color: var(--td-tag-primary-color, var(--td-brand-color, var(--td-primary-color-7, #0052d9)));
|
||||
border-color: var(--td-tag-primary-light-color, var(--td-brand-color-light, var(--td-primary-color-1, #f2f3ff)));
|
||||
background-color: var(--td-tag-primary-light-color, var(--td-brand-color-light, var(--td-primary-color-1, #f2f3ff)));
|
||||
}
|
||||
.t-tag--light.t-tag--success {
|
||||
color: var(--td-tag-success-color, var(--td-success-color, var(--td-success-color-5, #2ba471)));
|
||||
border-color: var(--td-tag-success-light-color, var(--td-success-color-1, #e3f9e9));
|
||||
background-color: var(--td-tag-success-light-color, var(--td-success-color-1, #e3f9e9));
|
||||
}
|
||||
.t-tag--light.t-tag--warning {
|
||||
color: var(--td-tag-warning-color, var(--td-warning-color, var(--td-warning-color-5, #e37318)));
|
||||
border-color: var(--td-tag-warning-light-color, var(--td-warning-color-1, #fff1e9));
|
||||
background-color: var(--td-tag-warning-light-color, var(--td-warning-color-1, #fff1e9));
|
||||
}
|
||||
.t-tag--light.t-tag--danger {
|
||||
color: var(--td-tag-danger-color, var(--td-error-color, var(--td-error-color-6, #d54941)));
|
||||
border-color: var(--td-tag-danger-light-color, var(--td-error-color-1, #fff0ed));
|
||||
background-color: var(--td-tag-danger-light-color, var(--td-error-color-1, #fff0ed));
|
||||
}
|
||||
.t-tag--light.t-tag--default {
|
||||
color: var(--td-tag-default-font-color, var(--td-text-color-primary, var(--td-font-gray-1, rgba(0, 0, 0, 0.9))));
|
||||
}
|
||||
.t-tag--light-outline.t-tag--default {
|
||||
color: var(--td-tag-default-color, var(--td-bg-color-component, var(--td-gray-color-3, #e7e7e7)));
|
||||
border-color: var(--td-tag-default-color, var(--td-bg-color-component, var(--td-gray-color-3, #e7e7e7)));
|
||||
background-color: var(--td-tag-default-light-color, var(--td-bg-color-secondarycontainer, var(--td-gray-color-1, #f3f3f3)));
|
||||
}
|
||||
.t-tag--light-outline.t-tag--primary {
|
||||
color: var(--td-tag-primary-color, var(--td-brand-color, var(--td-primary-color-7, #0052d9)));
|
||||
border-color: var(--td-tag-primary-color, var(--td-brand-color, var(--td-primary-color-7, #0052d9)));
|
||||
background-color: var(--td-tag-primary-light-color, var(--td-brand-color-light, var(--td-primary-color-1, #f2f3ff)));
|
||||
}
|
||||
.t-tag--light-outline.t-tag--success {
|
||||
color: var(--td-tag-success-color, var(--td-success-color, var(--td-success-color-5, #2ba471)));
|
||||
border-color: var(--td-tag-success-color, var(--td-success-color, var(--td-success-color-5, #2ba471)));
|
||||
background-color: var(--td-tag-success-light-color, var(--td-success-color-1, #e3f9e9));
|
||||
}
|
||||
.t-tag--light-outline.t-tag--warning {
|
||||
color: var(--td-tag-warning-color, var(--td-warning-color, var(--td-warning-color-5, #e37318)));
|
||||
border-color: var(--td-tag-warning-color, var(--td-warning-color, var(--td-warning-color-5, #e37318)));
|
||||
background-color: var(--td-tag-warning-light-color, var(--td-warning-color-1, #fff1e9));
|
||||
}
|
||||
.t-tag--light-outline.t-tag--danger {
|
||||
color: var(--td-tag-danger-color, var(--td-error-color, var(--td-error-color-6, #d54941)));
|
||||
border-color: var(--td-tag-danger-color, var(--td-error-color, var(--td-error-color-6, #d54941)));
|
||||
background-color: var(--td-tag-danger-light-color, var(--td-error-color-1, #fff0ed));
|
||||
}
|
||||
.t-tag--light-outline.t-tag--default {
|
||||
color: var(--td-tag-default-font-color, var(--td-text-color-primary, var(--td-font-gray-1, rgba(0, 0, 0, 0.9))));
|
||||
border-color: var(--td-component-border, var(--td-gray-color-4, #dcdcdc));
|
||||
}
|
||||
.t-tag.t-tag--closable.t-tag--disabled {
|
||||
cursor: not-allowed;
|
||||
color: var(--td-tag-disabled-color, var(--td-text-color-disabled, var(--td-font-gray-4, rgba(0, 0, 0, 0.26))));
|
||||
background-color: var(--td-tag-disabled-background-color, var(--td-bg-color-component-disabled, var(--td-gray-color-2, #eeeeee)));
|
||||
border-color: var(--td-tag-disabled-border-color, var(--td-component-border, var(--td-gray-color-4, #dcdcdc)));
|
||||
}
|
||||
149
uni_modules/tdesign-uniapp/components/check-tag/check-tag.vue
Normal file
149
uni_modules/tdesign-uniapp/components/check-tag/check-tag.vue
Normal file
@@ -0,0 +1,149 @@
|
||||
<template>
|
||||
<view
|
||||
:style="tools._style([customStyle])"
|
||||
:class="className + ' ' + tClass"
|
||||
@click="onClick"
|
||||
>
|
||||
<view
|
||||
:aria-hidden="true"
|
||||
:class="classPrefix + '__icon'"
|
||||
>
|
||||
<block
|
||||
v-if="_icon"
|
||||
name="icon"
|
||||
>
|
||||
<t-icon
|
||||
:custom-style="_icon.style || ''"
|
||||
:t-class="prefix + '-icon'"
|
||||
:prefix="_icon.prefix"
|
||||
:name="_icon.name"
|
||||
:size="_icon.size"
|
||||
:color="_icon.color"
|
||||
:aria-hidden="!!_icon.ariaHidden"
|
||||
:aria-label="_icon.ariaLabel"
|
||||
:aria-role="_icon.ariaRole"
|
||||
/>
|
||||
</block>
|
||||
<slot name="icon" />
|
||||
</view>
|
||||
<view :class="classPrefix + '__text'">
|
||||
<slot />
|
||||
<slot name="content" />
|
||||
<block v-if="tools.isArray(content) && content.length == 2">
|
||||
{{ dataChecked ? content[0] : content[1] }}
|
||||
</block>
|
||||
<block v-else>
|
||||
{{ content }}
|
||||
</block>
|
||||
</view>
|
||||
<t-icon
|
||||
v-if="closable"
|
||||
:class="classPrefix + '__icon-close'"
|
||||
:t-class="prefix + '-icon'"
|
||||
name="close"
|
||||
aria-role="button"
|
||||
aria-label="关闭"
|
||||
@click="onClose"
|
||||
/>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import TIcon from '../icon/icon';
|
||||
import { uniComponent } from '../common/src/index';
|
||||
import { prefix } from '../common/config';
|
||||
import props from './props';
|
||||
import { classNames, calcIcon, coalesce } from '../common/utils';
|
||||
import tools from '../common/utils.wxs';
|
||||
|
||||
|
||||
const name = `${prefix}-tag`;
|
||||
|
||||
|
||||
export default uniComponent({
|
||||
name,
|
||||
options: {
|
||||
styleIsolation: 'shared',
|
||||
},
|
||||
controlledProps: [{
|
||||
key: 'checked',
|
||||
event: 'change',
|
||||
}],
|
||||
externalClasses: [
|
||||
`${prefix}-class`,
|
||||
|
||||
],
|
||||
components: {
|
||||
TIcon,
|
||||
},
|
||||
props: {
|
||||
...props,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
prefix,
|
||||
classPrefix: name,
|
||||
className: '',
|
||||
tools,
|
||||
_icon: null,
|
||||
|
||||
dataChecked: coalesce(this.checked, this.defaultChecked),
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
size: 'setClass',
|
||||
disabled: 'setClass',
|
||||
dataChecked: 'setClass',
|
||||
icon: {
|
||||
handler(e) {
|
||||
this._icon = calcIcon(e);
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
checked: {
|
||||
handler(value) {
|
||||
this.dataChecked = value;
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.setClass();
|
||||
},
|
||||
methods: {
|
||||
setClass() {
|
||||
const { classPrefix } = this;
|
||||
const { size, variant, disabled, dataChecked, shape } = this;
|
||||
const tagClass = [
|
||||
classPrefix,
|
||||
`${classPrefix}--checkable`,
|
||||
disabled ? `${classPrefix}--disabled` : '',
|
||||
dataChecked ? `${classPrefix}--checked` : '',
|
||||
`${classPrefix}--${dataChecked ? 'primary' : 'default'}`,
|
||||
`${classPrefix}--${size}`,
|
||||
`${classPrefix}--${variant}`,
|
||||
`${classPrefix}--${shape}`,
|
||||
];
|
||||
const className = classNames(tagClass);
|
||||
this.className = className;
|
||||
},
|
||||
|
||||
onClick() {
|
||||
if (this.disabled) return;
|
||||
const { dataChecked } = this;
|
||||
|
||||
this._trigger('click');
|
||||
this._trigger('change', { checked: !dataChecked });
|
||||
},
|
||||
|
||||
onClose(e) {
|
||||
if (this.disabled) return;
|
||||
this._trigger('close', e);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
</script>
|
||||
<style scoped>
|
||||
@import './check-tag.css';
|
||||
|
||||
</style>
|
||||
67
uni_modules/tdesign-uniapp/components/check-tag/props.ts
Normal file
67
uni_modules/tdesign-uniapp/components/check-tag/props.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
|
||||
* */
|
||||
|
||||
import type { TdCheckTagProps } from './type';
|
||||
export default {
|
||||
/** 标签选中的状态,默认风格(theme=default)才有选中态 */
|
||||
checked: Boolean,
|
||||
/** 标签选中的状态,默认风格(theme=default)才有选中态,非受控属性 */
|
||||
defaultChecked: Boolean,
|
||||
/** 标签是否可关闭 */
|
||||
closable: Boolean,
|
||||
/** 组件子元素;传入数组时:[选中内容,非选中内容] */
|
||||
content: {
|
||||
type: [String, Number, Array],
|
||||
},
|
||||
/** 标签禁用态,失效标签不能触发事件。默认风格(theme=default)才有禁用态 */
|
||||
disabled: Boolean,
|
||||
/** 标签图标 */
|
||||
icon: {
|
||||
type: [String, Object],
|
||||
},
|
||||
/** 标签类型,有三种:方形、圆角方形、标记型 */
|
||||
shape: {
|
||||
type: String,
|
||||
default: 'square' as TdCheckTagProps['shape'],
|
||||
validator(val: TdCheckTagProps['shape']): boolean {
|
||||
if (!val) return true;
|
||||
return ['square', 'round', 'mark'].includes(val);
|
||||
},
|
||||
},
|
||||
/** 标签尺寸 */
|
||||
size: {
|
||||
type: String,
|
||||
default: 'medium' as TdCheckTagProps['size'],
|
||||
validator(val: TdCheckTagProps['size']): boolean {
|
||||
if (!val) return true;
|
||||
return ['small', 'medium', 'large'].includes(val);
|
||||
},
|
||||
},
|
||||
/** 标签风格变体 */
|
||||
variant: {
|
||||
type: String,
|
||||
default: 'dark' as TdCheckTagProps['variant'],
|
||||
validator(val: TdCheckTagProps['variant']): boolean {
|
||||
if (!val) return true;
|
||||
return ['dark', 'light', 'outline', 'light-outline'].includes(val);
|
||||
},
|
||||
},
|
||||
/** 状态切换时触发 */
|
||||
onChange: {
|
||||
type: Function,
|
||||
default: () => ({}),
|
||||
},
|
||||
/** 点击标签时触发 */
|
||||
onClick: {
|
||||
type: Function,
|
||||
default: () => ({}),
|
||||
},
|
||||
/** 如果关闭按钮存在,点击关闭按钮时触发 */
|
||||
onClose: {
|
||||
type: Function,
|
||||
default: () => ({}),
|
||||
},
|
||||
};
|
||||
63
uni_modules/tdesign-uniapp/components/check-tag/type.ts
Normal file
63
uni_modules/tdesign-uniapp/components/check-tag/type.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
|
||||
* */
|
||||
|
||||
import type { SizeEnum } from '../common/common';
|
||||
|
||||
export interface TdCheckTagProps {
|
||||
/**
|
||||
* 标签选中的状态,默认风格(theme=default)才有选中态
|
||||
*/
|
||||
checked?: boolean;
|
||||
/**
|
||||
* 标签选中的状态,默认风格(theme=default)才有选中态,非受控属性
|
||||
*/
|
||||
defaultChecked?: boolean;
|
||||
/**
|
||||
* 标签是否可关闭
|
||||
* @default false
|
||||
*/
|
||||
closable?: boolean;
|
||||
/**
|
||||
* 组件子元素;传入数组时:[选中内容,非选中内容]
|
||||
*/
|
||||
content?: string | number | string[];
|
||||
/**
|
||||
* 标签禁用态,失效标签不能触发事件。默认风格(theme=default)才有禁用态
|
||||
* @default false
|
||||
*/
|
||||
disabled?: boolean;
|
||||
/**
|
||||
* 标签图标
|
||||
*/
|
||||
icon?: string | object;
|
||||
/**
|
||||
* 标签类型,有三种:方形、圆角方形、标记型
|
||||
* @default square
|
||||
*/
|
||||
shape?: 'square' | 'round' | 'mark';
|
||||
/**
|
||||
* 标签尺寸
|
||||
* @default medium
|
||||
*/
|
||||
size?: SizeEnum;
|
||||
/**
|
||||
* 标签风格变体
|
||||
* @default dark
|
||||
*/
|
||||
variant?: 'dark' | 'light' | 'outline' | 'light-outline';
|
||||
/**
|
||||
* 状态切换时触发
|
||||
*/
|
||||
onChange?: (context: { checked: boolean }) => void;
|
||||
/**
|
||||
* 点击标签时触发
|
||||
*/
|
||||
onClick?: () => void;
|
||||
/**
|
||||
* 如果关闭按钮存在,点击关闭按钮时触发
|
||||
*/
|
||||
onClose?: () => void;
|
||||
}
|
||||
@@ -0,0 +1,261 @@
|
||||
<template>
|
||||
<view
|
||||
:class="classPrefix + ' ' + tClass"
|
||||
:style="tools._style([customStyle])"
|
||||
>
|
||||
<slot />
|
||||
<t-checkbox
|
||||
v-for="(item, index) in checkboxOptions"
|
||||
:key="index"
|
||||
:ref="prefix + '-checkbox-option'"
|
||||
:class="prefix + '-checkbox-option'"
|
||||
:data-item="item"
|
||||
:label="item.label || item.text || ''"
|
||||
:value="item.value == null ? '' : item.value"
|
||||
:block="item.block || true"
|
||||
:check-all="item.checkAll || false"
|
||||
:checked="item.checked || false"
|
||||
:content="item.content || ''"
|
||||
:content-disabled="item.contentDisabled || false"
|
||||
:icon="item.icon || 'circle'"
|
||||
:indeterminate="item.indeterminate || false"
|
||||
:disabled="item.disabled == null ? disabled : item.disabled"
|
||||
:max-content-row="item.maxContentRow || 5"
|
||||
:max-label-row="item.maxLabelRow || 3"
|
||||
:name="item.name || ''"
|
||||
:borderless="borderless"
|
||||
:readonly="item.readonly || false"
|
||||
:placement="item.placement || 'left'"
|
||||
:relation-key="relationKey"
|
||||
@change="({checked}) => handleInnerChildChange($event, { item, checked })"
|
||||
/>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import TCheckbox from '../checkbox/checkbox';
|
||||
import { uniComponent } from '../common/src/index';
|
||||
import { prefix } from '../common/config';
|
||||
import { coalesce } from '../common/utils';
|
||||
import props from './props';
|
||||
import tools from '../common/utils.wxs';
|
||||
import { ParentMixin, RELATION_MAP } from '../common/relation';
|
||||
|
||||
|
||||
const name = `${prefix}-checkbox-group`;
|
||||
|
||||
|
||||
export default uniComponent({
|
||||
name,
|
||||
options: {
|
||||
styleIsolation: 'shared',
|
||||
},
|
||||
controlledProps: [
|
||||
{
|
||||
key: 'value',
|
||||
event: 'change',
|
||||
},
|
||||
],
|
||||
externalClasses: [
|
||||
`${prefix}-class`,
|
||||
],
|
||||
|
||||
inject: {
|
||||
[RELATION_MAP.FormKey]: {
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
|
||||
mixins: [ParentMixin(RELATION_MAP.Checkbox)],
|
||||
components: {
|
||||
TCheckbox,
|
||||
},
|
||||
props: {
|
||||
...props,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
prefix,
|
||||
classPrefix: name,
|
||||
checkboxOptions: [],
|
||||
tools,
|
||||
|
||||
dataValue: coalesce(this.value, this.defaultValue),
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
value: {
|
||||
handler(v) {
|
||||
this.dataValue = v;
|
||||
},
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
dataValue: {
|
||||
handler() {
|
||||
this.updateChildren();
|
||||
},
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
options: {
|
||||
handler() {
|
||||
this.initWithOptions();
|
||||
},
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
disabled: {
|
||||
handler(v) {
|
||||
if (this.options?.length) {
|
||||
this.initWithOptions();
|
||||
return;
|
||||
}
|
||||
this.getChildren()?.forEach((item) => {
|
||||
item.setDisabled(v);
|
||||
});
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.$checkAll = null;
|
||||
},
|
||||
mounted() {
|
||||
this.setCheckall();
|
||||
|
||||
this.getChildren()?.forEach((item) => {
|
||||
item.setDisabled(this.disabled);
|
||||
});
|
||||
setTimeout(() => {
|
||||
this.updateChildren();
|
||||
}, 33);
|
||||
},
|
||||
methods: {
|
||||
getChildren() {
|
||||
let items = this.children;
|
||||
if (!items?.length) {
|
||||
items = this.$refs[`${prefix}-checkbox-option`];
|
||||
}
|
||||
return items || [];
|
||||
},
|
||||
|
||||
updateChildren() {
|
||||
const items = this.getChildren();
|
||||
const { dataValue } = this;
|
||||
|
||||
|
||||
if (items.length > 0) {
|
||||
items.forEach((item) => {
|
||||
if (!item.checkAll) {
|
||||
item.dataChecked = dataValue?.includes(item.value);
|
||||
}
|
||||
});
|
||||
// 关联可全选项
|
||||
if (items.some(item => item.checkAll)) {
|
||||
this.setCheckall();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
updateValue({ validChildren, trigger, value, checked, checkAll, item, indeterminate }) {
|
||||
let { dataValue: newValue } = this;
|
||||
const { max } = this;
|
||||
|
||||
if (validChildren !== false) {
|
||||
const keySet = new Set(this.getChildren().map(item => item.value));
|
||||
newValue = newValue.filter(value => keySet.has(value));
|
||||
}
|
||||
|
||||
if (max && checked && newValue.length === max) return;
|
||||
|
||||
if (checkAll) {
|
||||
const items = this.getChildren();
|
||||
newValue = !checked && indeterminate
|
||||
? items
|
||||
.filter(data => !(data.disabled && !newValue.includes(data.value)))
|
||||
.map(item => item.value)
|
||||
: items
|
||||
.filter((data) => {
|
||||
if (data.disabled) {
|
||||
return newValue.includes(data.value);
|
||||
}
|
||||
return checked && !data.checkAll;
|
||||
})
|
||||
.map(data => data.value);
|
||||
} else if (checked) {
|
||||
newValue = newValue.concat(value);
|
||||
} else {
|
||||
const index = newValue.findIndex(v => v === value);
|
||||
newValue.splice(index, 1);
|
||||
}
|
||||
|
||||
if (trigger !== 'init') {
|
||||
this._trigger('change', { value: newValue, context: item });
|
||||
|
||||
this.onChange(newValue);
|
||||
}
|
||||
},
|
||||
|
||||
onChange(value) {
|
||||
if (this[RELATION_MAP.FormKey]
|
||||
&& this[RELATION_MAP.FormKey].onValueChange) {
|
||||
this[RELATION_MAP.FormKey].onValueChange(value);
|
||||
}
|
||||
},
|
||||
|
||||
initWithOptions() {
|
||||
const { options, dataValue: value, keys } = this;
|
||||
|
||||
if (!options?.length || !Array.isArray(options)) return;
|
||||
|
||||
const checkboxOptions = options.map((item) => {
|
||||
const isLabel = ['number', 'string'].includes(typeof item);
|
||||
return isLabel
|
||||
? {
|
||||
label: `${item}`,
|
||||
value: item,
|
||||
checked: value?.includes(item),
|
||||
}
|
||||
: {
|
||||
...item,
|
||||
label: item[coalesce(keys?.label, 'label')],
|
||||
value: item[coalesce(keys?.value, 'value')],
|
||||
checked: value?.includes(item[coalesce(keys?.value, 'value')]),
|
||||
};
|
||||
});
|
||||
|
||||
this.checkboxOptions = checkboxOptions;
|
||||
},
|
||||
|
||||
handleInnerChildChange(tools, { item, checked }) {
|
||||
const rect = {};
|
||||
|
||||
if (item.checkAll) {
|
||||
rect.indeterminate = this.$checkAll?.indeterminate;
|
||||
}
|
||||
|
||||
this.updateValue({ ...item, checked, item, ...rect });
|
||||
},
|
||||
|
||||
setCheckall() {
|
||||
const items = this.getChildren();
|
||||
|
||||
if (!this.$checkAll) {
|
||||
this.$checkAll = items.find(item => item.checkAll);
|
||||
}
|
||||
|
||||
if (!this.$checkAll) return;
|
||||
|
||||
const { dataValue } = this;
|
||||
const valueSet = new Set(dataValue?.filter(val => val !== this.$checkAll.value));
|
||||
const isCheckall = items.every(item => (item.checkAll ? true : valueSet.has(item.value)));
|
||||
|
||||
this.$checkAll.dataChecked = valueSet.size > 0;
|
||||
this.$checkAll.dataIndeterminate = !isCheckall;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
||||
@@ -0,0 +1,58 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
|
||||
* */
|
||||
|
||||
import type { TdCheckboxGroupProps } from './type';
|
||||
export default {
|
||||
/** 是否开启无边框模式。优先级低于 Checkbox.borderless */
|
||||
borderless: Boolean,
|
||||
/** 是否禁用组件。优先级:Form.disabled < CheckboxGroup.disabled < Checkbox.disabled */
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: undefined,
|
||||
},
|
||||
/** 用来定义 value / label / disabled 在 `options` 中对应的字段别名 */
|
||||
keys: {
|
||||
type: Object,
|
||||
},
|
||||
/** 支持最多选中的数量 */
|
||||
max: {
|
||||
type: Number,
|
||||
default: undefined,
|
||||
},
|
||||
/** 统一设置内部复选框 HTML 属性 */
|
||||
name: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
/** 以配置形式设置子元素。示例1:`['北京', '上海']` ,示例2: `[{ label: '全选', checkAll: true }, { label: '上海', value: 'shanghai' }]`。checkAll 值为 true 表示当前选项为「全选选项」 */
|
||||
options: {
|
||||
type: Array,
|
||||
default: (): TdCheckboxGroupProps['options'] => [],
|
||||
},
|
||||
/** 只读状态 */
|
||||
readonly: {
|
||||
type: Boolean,
|
||||
default: undefined,
|
||||
},
|
||||
/** -1 时代表独立,不再寻找 parent,用于头条小程序 */
|
||||
relationKey: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
/** 选中值 */
|
||||
value: {
|
||||
type: Array,
|
||||
},
|
||||
/** 选中值,非受控属性 */
|
||||
defaultValue: {
|
||||
type: Array,
|
||||
},
|
||||
/** 值变化时触发。`context` 表示当前点击项内容 */
|
||||
onChange: {
|
||||
type: Function,
|
||||
default: () => ({}),
|
||||
},
|
||||
};
|
||||
72
uni_modules/tdesign-uniapp/components/checkbox-group/type.ts
Normal file
72
uni_modules/tdesign-uniapp/components/checkbox-group/type.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
|
||||
* */
|
||||
|
||||
import type { KeysType } from '../common/common';
|
||||
|
||||
export interface TdCheckboxGroupProps<T = CheckboxGroupValue> {
|
||||
/**
|
||||
* 是否开启无边框模式。优先级低于 Checkbox.borderless
|
||||
* @default false
|
||||
*/
|
||||
borderless?: boolean;
|
||||
/**
|
||||
* 是否禁用组件。优先级:Form.disabled < CheckboxGroup.disabled < Checkbox.disabled
|
||||
*/
|
||||
disabled?: boolean;
|
||||
/**
|
||||
* 用来定义 value / label / disabled 在 `options` 中对应的字段别名
|
||||
*/
|
||||
keys?: KeysType;
|
||||
/**
|
||||
* 支持最多选中的数量
|
||||
*/
|
||||
max?: number;
|
||||
/**
|
||||
* 统一设置内部复选框 HTML 属性
|
||||
* @default ''
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* 以配置形式设置子元素。示例1:`['北京', '上海']` ,示例2: `[{ label: '全选', checkAll: true }, { label: '上海', value: 'shanghai' }]`。checkAll 值为 true 表示当前选项为「全选选项」
|
||||
* @default []
|
||||
*/
|
||||
options?: Array<CheckboxOption>;
|
||||
/**
|
||||
* 只读状态
|
||||
*/
|
||||
readonly?: boolean;
|
||||
/**
|
||||
* -1 时代表独立,不再寻找 parent,用于头条小程序
|
||||
* @default ''
|
||||
*/
|
||||
relationKey?: string;
|
||||
/**
|
||||
* 选中值
|
||||
*/
|
||||
value?: T;
|
||||
/**
|
||||
* 选中值,非受控属性
|
||||
*/
|
||||
defaultValue?: T;
|
||||
/**
|
||||
* 值变化时触发。`context` 表示当前点击项内容
|
||||
*/
|
||||
onChange?: (context: {
|
||||
value: CheckboxGroupValue;
|
||||
context: { value: boolean | number | string; label: boolean | number | string };
|
||||
}) => void;
|
||||
}
|
||||
|
||||
export type CheckboxOption = string | number | CheckboxOptionObj;
|
||||
|
||||
export interface CheckboxOptionObj {
|
||||
label?: string;
|
||||
value?: string | number;
|
||||
disabled?: boolean;
|
||||
checkAll?: true;
|
||||
}
|
||||
|
||||
export type CheckboxGroupValue = Array<string | number | boolean>;
|
||||
103
uni_modules/tdesign-uniapp/components/checkbox/README.en-US.md
Normal file
103
uni_modules/tdesign-uniapp/components/checkbox/README.en-US.md
Normal file
@@ -0,0 +1,103 @@
|
||||
:: BASE_DOC ::
|
||||
|
||||
## API
|
||||
|
||||
### Checkbox Props
|
||||
|
||||
name | type | default | description | required
|
||||
-- | -- | -- | -- | --
|
||||
custom-style | Object | - | CSS(Cascading Style Sheets) | N
|
||||
block | Boolean | true | \- | N
|
||||
borderless | Boolean | undefined | \- | N
|
||||
check-all | Boolean | false | \- | N
|
||||
checked | Boolean | - | `v-model:checked` is supported | N
|
||||
default-checked | Boolean | - | uncontrolled property | N
|
||||
content | String | - | \- | N
|
||||
content-disabled | Boolean | - | \- | N
|
||||
disabled | Boolean | undefined | \- | N
|
||||
icon | String / Array | 'circle' | Typescript:`'circle' \| 'line' \| 'rectangle' \| string[]` | N
|
||||
indeterminate | Boolean | false | \- | N
|
||||
label | String | - | \- | N
|
||||
max-content-row | Number | 5 | \- | N
|
||||
max-label-row | Number | 3 | \- | N
|
||||
name | String | - | \- | N
|
||||
placement | String | left | options: left/right | N
|
||||
readonly | Boolean | undefined | \- | N
|
||||
relation-key | String | - | \- | N
|
||||
value | String / Number / Boolean | - | value of checkbox。Typescript:`string \| number \| boolean` | N
|
||||
|
||||
### Checkbox Events
|
||||
|
||||
name | params | description
|
||||
-- | -- | --
|
||||
change | `(context: { checked: boolean, context: { value: boolean\|number\|string, label: boolean\|number\|string }})` | \-
|
||||
|
||||
### Checkbox Slots
|
||||
|
||||
name | Description
|
||||
-- | --
|
||||
\- | \-
|
||||
content | \-
|
||||
label | \-
|
||||
|
||||
### Checkbox External Classes
|
||||
|
||||
className | Description
|
||||
-- | --
|
||||
t-class | \-
|
||||
t-class-border | \-
|
||||
t-class-content | \-
|
||||
t-class-icon | \-
|
||||
t-class-label | \-
|
||||
|
||||
|
||||
### CheckboxGroup Props
|
||||
|
||||
name | type | default | description | required
|
||||
-- | -- | -- | -- | --
|
||||
custom-style | Object | - | CSS(Cascading Style Sheets) | N
|
||||
borderless | Boolean | false | \- | N
|
||||
disabled | Boolean | undefined | \- | N
|
||||
keys | Object | - | Typescript:`KeysType`。[see more ts definition](https://github.com/Tencent/tdesign-miniprogram/tree/develop/packages/uniapp-components/common/common.ts) | N
|
||||
max | Number | undefined | \- | N
|
||||
name | String | - | \- | N
|
||||
options | Array | [] | Typescript:`Array<CheckboxOption>` `type CheckboxOption = string \| number \| CheckboxOptionObj` `interface CheckboxOptionObj { label?: string; value?: string \| number; disabled?: boolean; checkAll?: true }`。[see more ts definition](https://github.com/Tencent/tdesign-miniprogram/tree/develop/packages/uniapp-components/checkbox-group/type.ts) | N
|
||||
readonly | Boolean | undefined | \- | N
|
||||
relation-key | String | - | \- | N
|
||||
value | Array | - | `v-model:value` is supported。Typescript:`T` `type CheckboxGroupValue = Array<string \| number \| boolean>`。[see more ts definition](https://github.com/Tencent/tdesign-miniprogram/tree/develop/packages/uniapp-components/checkbox-group/type.ts) | N
|
||||
default-value | Array | - | uncontrolled property。Typescript:`T` `type CheckboxGroupValue = Array<string \| number \| boolean>`。[see more ts definition](https://github.com/Tencent/tdesign-miniprogram/tree/develop/packages/uniapp-components/checkbox-group/type.ts) | N
|
||||
|
||||
### CheckboxGroup Events
|
||||
|
||||
name | params | description
|
||||
-- | -- | --
|
||||
change | `(context: { value: CheckboxGroupValue, context: { value: boolean\|number\|string, label: boolean\|number\|string }})` | \-
|
||||
|
||||
### CheckboxGroup Slots
|
||||
|
||||
name | Description
|
||||
-- | --
|
||||
\- | \-
|
||||
|
||||
### CSS Variables
|
||||
|
||||
The component provides the following CSS variables, which can be used to customize styles.
|
||||
Name | Default Value | Description
|
||||
-- | -- | --
|
||||
--td-checkbox-bg-color | @bg-color-container | -
|
||||
--td-checkbox-border-color | @component-stroke | -
|
||||
--td-checkbox-description-color | @text-color-secondary | -
|
||||
--td-checkbox-description-disabled-color | @text-color-disabled | -
|
||||
--td-checkbox-description-font | @font-body-medium | -
|
||||
--td-checkbox-icon-checked-color | @brand-color | -
|
||||
--td-checkbox-icon-color | @component-border | -
|
||||
--td-checkbox-icon-disabled-bg-color | @bg-color-component-disabled | -
|
||||
--td-checkbox-icon-disabled-color | @brand-color-disabled | -
|
||||
--td-checkbox-icon-size | 48rpx | -
|
||||
--td-checkbox-tag-active-bg-color | @brand-color-light | -
|
||||
--td-checkbox-tag-active-color | @brand-color | -
|
||||
--td-checkbox-title-color | @text-color-primary | -
|
||||
--td-checkbox-title-disabled-color | @text-color-disabled | -
|
||||
--td-checkbox-title-font | @font-body-large | -
|
||||
--td-checkbox-title-line-height | 48rpx | -
|
||||
--td-checkbox-vertical-padding | @spacer-2 | -
|
||||
158
uni_modules/tdesign-uniapp/components/checkbox/README.md
Normal file
158
uni_modules/tdesign-uniapp/components/checkbox/README.md
Normal file
@@ -0,0 +1,158 @@
|
||||
---
|
||||
title: Checkbox 多选框
|
||||
description: 用于预设的一组选项中执行多项选择,并呈现选择结果。
|
||||
spline: form
|
||||
isComponent: true
|
||||
---
|
||||
|
||||
|
||||
## 引入
|
||||
|
||||
可在 `main.ts` 或在需要使用的页面或组件中引入。
|
||||
|
||||
```js
|
||||
import TCheckbox from '@tdesign/uniapp/checkbox/checkbox.vue';
|
||||
import TCheckboxGroup from '@tdesign/uniapp/checkbox-group/checkbox-group.vue';
|
||||
```
|
||||
|
||||
### 组件类型
|
||||
|
||||
纵向多选框
|
||||
|
||||
{{ base }}
|
||||
|
||||
横向多选框
|
||||
|
||||
{{ horizontal }}
|
||||
|
||||
带全选多选框
|
||||
|
||||
{{ all }}
|
||||
|
||||
### 组件状态
|
||||
|
||||
多选框状态
|
||||
|
||||
{{ status }}
|
||||
|
||||
### 组件样式
|
||||
|
||||
勾选样式
|
||||
|
||||
{{ type }}
|
||||
|
||||
勾选显示位置
|
||||
|
||||
{{ right }}
|
||||
|
||||
非通栏多选样式
|
||||
|
||||
{{ card }}
|
||||
|
||||
### 组件规格
|
||||
|
||||
多选框尺寸规格
|
||||
|
||||
{{ special }}
|
||||
|
||||
## API
|
||||
|
||||
### Checkbox Props
|
||||
|
||||
名称 | 类型 | 默认值 | 描述 | 必传
|
||||
-- | -- | -- | -- | --
|
||||
custom-style | Object | - | 自定义样式 | N
|
||||
block | Boolean | true | 是否为块级元素 | N
|
||||
borderless | Boolean | undefined | 是否开启无边框模式 | N
|
||||
check-all | Boolean | false | 用于标识是否为「全选选项」。单独使用无效,需在 CheckboxGroup 中使用 | N
|
||||
checked | Boolean | - | 是否选中。支持语法糖 `v-model:checked` | N
|
||||
default-checked | Boolean | - | 是否选中。非受控属性 | N
|
||||
content | String | - | 多选框内容 | N
|
||||
content-disabled | Boolean | - | 是否禁用组件内容(content)触发选中 | N
|
||||
disabled | Boolean | undefined | 是否禁用组件。如果父组件存在 CheckboxGroup,默认值由 CheckboxGroup.disabled 控制。优先级:Checkbox.disabled > CheckboxGroup.disabled > Form.disabled | N
|
||||
icon | String / Array | 'circle' | 自定义选中图标和非选中图标。使用 Array 时表示:`[选中态图标,非选中态图标,半选中态图标]`。使用 String 时,值为 circle 表示填充圆形图标、值为 line 表示描边型图标、值为 rectangle 表示填充矩形图标。TS 类型:`'circle' \| 'line' \| 'rectangle' \| string[]` | N
|
||||
indeterminate | Boolean | false | 是否为半选 | N
|
||||
label | String | - | 主文案 | N
|
||||
max-content-row | Number | 5 | 内容最大行数限制 | N
|
||||
max-label-row | Number | 3 | 主文案最大行数限制 | N
|
||||
name | String | - | HTML 元素原生属性 | N
|
||||
placement | String | left | 多选框和内容相对位置。可选项:left/right | N
|
||||
readonly | Boolean | undefined | 只读状态 | N
|
||||
relation-key | String | - | -1 时代表独立,不再寻找 parent,用于头条小程序 | N
|
||||
value | String / Number / Boolean | - | 多选框的值。TS 类型:`string \| number \| boolean` | N
|
||||
|
||||
### Checkbox Events
|
||||
|
||||
名称 | 参数 | 描述
|
||||
-- | -- | --
|
||||
change | `(context: { checked: boolean, context: { value: boolean\|number\|string, label: boolean\|number\|string }})` | 值变化时触发。`context` 表示当前点击项内容
|
||||
|
||||
### Checkbox Slots
|
||||
|
||||
名称 | 描述
|
||||
-- | --
|
||||
\- | 默认插槽,主文案
|
||||
content | 自定义 `content` 显示内容
|
||||
label | 自定义 `label` 显示内容
|
||||
|
||||
### Checkbox External Classes
|
||||
|
||||
类名 | 描述
|
||||
-- | --
|
||||
t-class | 根节点样式类
|
||||
t-class-border | 边框样式类
|
||||
t-class-content | 内容样式类
|
||||
t-class-icon | 图标样式类
|
||||
t-class-label | 标签样式类
|
||||
|
||||
|
||||
### CheckboxGroup Props
|
||||
|
||||
名称 | 类型 | 默认值 | 描述 | 必传
|
||||
-- | -- | -- | -- | --
|
||||
custom-style | Object | - | 自定义样式 | N
|
||||
borderless | Boolean | false | 是否开启无边框模式。优先级低于 Checkbox.borderless | N
|
||||
disabled | Boolean | undefined | 是否禁用组件。优先级:Form.disabled < CheckboxGroup.disabled < Checkbox.disabled | N
|
||||
keys | Object | - | 用来定义 value / label / disabled 在 `options` 中对应的字段别名。TS 类型:`KeysType`。[通用类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/packages/uniapp-components/common/common.ts) | N
|
||||
max | Number | undefined | 支持最多选中的数量 | N
|
||||
name | String | - | 统一设置内部复选框 HTML 属性 | N
|
||||
options | Array | [] | 以配置形式设置子元素。示例1:`['北京', '上海']` ,示例2: `[{ label: '全选', checkAll: true }, { label: '上海', value: 'shanghai' }]`。checkAll 值为 true 表示当前选项为「全选选项」。TS 类型:`Array<CheckboxOption>` `type CheckboxOption = string \| number \| CheckboxOptionObj` `interface CheckboxOptionObj { label?: string; value?: string \| number; disabled?: boolean; checkAll?: true }`。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/packages/uniapp-components/checkbox-group/type.ts) | N
|
||||
readonly | Boolean | undefined | 只读状态 | N
|
||||
relation-key | String | - | -1 时代表独立,不再寻找 parent,用于头条小程序 | N
|
||||
value | Array | - | 选中值。支持语法糖 `v-model:value`。TS 类型:`T` `type CheckboxGroupValue = Array<string \| number \| boolean>`。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/packages/uniapp-components/checkbox-group/type.ts) | N
|
||||
default-value | Array | - | 选中值。非受控属性。TS 类型:`T` `type CheckboxGroupValue = Array<string \| number \| boolean>`。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/packages/uniapp-components/checkbox-group/type.ts) | N
|
||||
|
||||
### CheckboxGroup Events
|
||||
|
||||
名称 | 参数 | 描述
|
||||
-- | -- | --
|
||||
change | `(context: { value: CheckboxGroupValue, context: { value: boolean\|number\|string, label: boolean\|number\|string }})` | 值变化时触发。`context` 表示当前点击项内容
|
||||
|
||||
### CheckboxGroup Slots
|
||||
|
||||
名称 | 描述
|
||||
-- | --
|
||||
\- | 默认插槽,多选框组内容
|
||||
|
||||
### CSS Variables
|
||||
|
||||
组件提供了下列 CSS 变量,可用于自定义样式。
|
||||
名称 | 默认值 | 描述
|
||||
-- | -- | --
|
||||
--td-checkbox-bg-color | @bg-color-container | -
|
||||
--td-checkbox-border-color | @component-stroke | -
|
||||
--td-checkbox-description-color | @text-color-secondary | -
|
||||
--td-checkbox-description-disabled-color | @text-color-disabled | -
|
||||
--td-checkbox-description-font | @font-body-medium | -
|
||||
--td-checkbox-icon-checked-color | @brand-color | -
|
||||
--td-checkbox-icon-color | @component-border | -
|
||||
--td-checkbox-icon-disabled-bg-color | @bg-color-component-disabled | -
|
||||
--td-checkbox-icon-disabled-color | @brand-color-disabled | -
|
||||
--td-checkbox-icon-size | 48rpx | -
|
||||
--td-checkbox-tag-active-bg-color | @brand-color-light | -
|
||||
--td-checkbox-tag-active-color | @brand-color | -
|
||||
--td-checkbox-title-color | @text-color-primary | -
|
||||
--td-checkbox-title-disabled-color | @text-color-disabled | -
|
||||
--td-checkbox-title-font | @font-body-large | -
|
||||
--td-checkbox-title-line-height | 48rpx | -
|
||||
--td-checkbox-vertical-padding | @spacer-2 | -
|
||||
174
uni_modules/tdesign-uniapp/components/checkbox/checkbox.css
Normal file
174
uni_modules/tdesign-uniapp/components/checkbox/checkbox.css
Normal file
@@ -0,0 +1,174 @@
|
||||
.t-checkbox {
|
||||
display: inline-flex;
|
||||
vertical-align: middle;
|
||||
position: relative;
|
||||
background: var(--td-checkbox-bg-color, var(--td-bg-color-container, var(--td-font-white-1, #ffffff)));
|
||||
}
|
||||
.t-checkbox:focus {
|
||||
outline: 0;
|
||||
}
|
||||
.t-checkbox--block {
|
||||
display: flex;
|
||||
padding: var(--td-checkbox-vertical-padding, var(--td-spacer-2, 32rpx));
|
||||
}
|
||||
.t-checkbox--right {
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
.t-checkbox .limit-title-row {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
.t-checkbox .image-center {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
.t-checkbox__icon-left {
|
||||
margin-right: 20rpx;
|
||||
width: 40rpx;
|
||||
}
|
||||
.t-checkbox__icon-right {
|
||||
right: 0px;
|
||||
display: contents;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
.t-checkbox__icon-image {
|
||||
width: var(--td-checkbox-icon-size, 48rpx);
|
||||
height: var(--td-checkbox-icon-size, 48rpx);
|
||||
vertical-align: top;
|
||||
}
|
||||
.t-checkbox__icon {
|
||||
position: relative;
|
||||
display: block;
|
||||
width: var(--td-checkbox-icon-size, 48rpx);
|
||||
height: var(--td-checkbox-icon-size, 48rpx);
|
||||
color: var(--td-checkbox-icon-color, var(--td-component-border, var(--td-gray-color-4, #dcdcdc)));
|
||||
font-size: var(--td-checkbox-icon-size, 48rpx);
|
||||
margin-top: calc((var(--td-checkbox-title-line-height, 48rpx) - var(--td-checkbox-icon-size, 48rpx)) / 2);
|
||||
}
|
||||
.t-checkbox__icon:empty {
|
||||
display: none;
|
||||
}
|
||||
.t-checkbox__icon--checked {
|
||||
color: var(--td-checkbox-icon-checked-color, var(--td-brand-color, var(--td-primary-color-7, #0052d9)));
|
||||
}
|
||||
.t-checkbox__icon--disabled {
|
||||
cursor: not-allowed;
|
||||
color: var(--td-checkbox-icon-disabled-color, var(--td-brand-color-disabled, var(--td-primary-color-3, #b5c7ff)));
|
||||
}
|
||||
.t-checkbox__icon--left {
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
.t-checkbox__icon-circle {
|
||||
width: calc((var(--td-checkbox-icon-size, 48rpx) - 4rpx) * 2);
|
||||
height: calc((var(--td-checkbox-icon-size, 48rpx) - 4rpx) * 2);
|
||||
border: calc(4rpx * 2) solid var(--td-checkbox-icon-color, var(--td-component-border, var(--td-gray-color-4, #dcdcdc)));
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%) scale(0.5);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.t-checkbox__icon-circle--disabled {
|
||||
background: var(--td-checkbox-icon-disabled-bg-color, var(--td-bg-color-component-disabled, var(--td-gray-color-2, #eeeeee)));
|
||||
}
|
||||
.t-checkbox__icon-rectangle {
|
||||
width: calc((var(--td-checkbox-icon-size, 48rpx) - 4rpx * 2) * 2);
|
||||
height: calc((var(--td-checkbox-icon-size, 48rpx) - 4rpx * 2) * 2);
|
||||
border: calc(4rpx * 2) solid var(--td-checkbox-icon-color, var(--td-component-border, var(--td-gray-color-4, #dcdcdc)));
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%) scale(0.5);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.t-checkbox__icon-rectangle--disabled {
|
||||
background: var(--td-checkbox-icon-disabled-bg-color, var(--td-bg-color-component-disabled, var(--td-gray-color-2, #eeeeee)));
|
||||
}
|
||||
.t-checkbox__icon-line::before,
|
||||
.t-checkbox__icon-line::after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
width: 5rpx;
|
||||
border-radius: 2rpx;
|
||||
background: var(--td-checkbox-icon-checked-color, var(--td-brand-color, var(--td-primary-color-7, #0052d9)));
|
||||
transform-origin: top center;
|
||||
}
|
||||
.t-checkbox__icon-line::before {
|
||||
height: 16rpx;
|
||||
left: 8rpx;
|
||||
top: 22rpx;
|
||||
transform: rotate(-45deg);
|
||||
}
|
||||
.t-checkbox__icon-line::after {
|
||||
height: 26rpx;
|
||||
right: 8rpx;
|
||||
top: 14rpx;
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
.t-checkbox__icon-line--disabled::before,
|
||||
.t-checkbox__icon-line--disabled::after {
|
||||
background: var(--td-checkbox-icon-disabled-color, var(--td-brand-color-disabled, var(--td-primary-color-3, #b5c7ff)));
|
||||
}
|
||||
.t-checkbox__content {
|
||||
flex: 1;
|
||||
}
|
||||
.t-checkbox__title {
|
||||
color: var(--td-checkbox-title-color, var(--td-text-color-primary, var(--td-font-gray-1, rgba(0, 0, 0, 0.9))));
|
||||
font: var(--td-checkbox-title-font, var(--td-font-body-large, 32rpx / 48rpx var(--td-font-family, PingFang SC, Microsoft YaHei, Arial Regular)));
|
||||
line-height: var(--td-checkbox-title-line-height, 48rpx);
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
.t-checkbox__title--disabled {
|
||||
color: var(--td-checkbox-title-disabled-color, var(--td-text-color-disabled, var(--td-font-gray-4, rgba(0, 0, 0, 0.26))));
|
||||
}
|
||||
.t-checkbox__description {
|
||||
color: var(--td-checkbox-description-color, var(--td-text-color-secondary, var(--td-font-gray-2, rgba(0, 0, 0, 0.6))));
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
font: var(--td-checkbox-description-font, var(--td-font-body-medium, 28rpx / 44rpx var(--td-font-family, PingFang SC, Microsoft YaHei, Arial Regular)));
|
||||
}
|
||||
.t-checkbox__description--disabled {
|
||||
color: var(--td-checkbox-description-disabled-color, var(--td-text-color-disabled, var(--td-font-gray-4, rgba(0, 0, 0, 0.26))));
|
||||
}
|
||||
.t-checkbox__title + .t-checkbox__description:not(:empty) {
|
||||
margin-top: 8rpx;
|
||||
}
|
||||
.t-checkbox__border {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 96rpx;
|
||||
right: 0;
|
||||
height: 1px;
|
||||
background: var(--td-checkbox-border-color, var(--td-component-stroke, var(--td-gray-color-3, #e7e7e7)));
|
||||
transform: scaleY(0.5);
|
||||
}
|
||||
.t-checkbox__border--right {
|
||||
left: 32rpx;
|
||||
}
|
||||
.t-checkbox--tag {
|
||||
font-size: 28rpx;
|
||||
padding-top: 16rpx;
|
||||
padding-bottom: 16rpx;
|
||||
text-align: center;
|
||||
background-color: var(--td-bg-color-secondarycontainer, var(--td-gray-color-1, #f3f3f3));
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
.t-checkbox--tag.t-checkbox--checked {
|
||||
color: var(--td-checkbox-tag-active-color, var(--td-brand-color, var(--td-primary-color-7, #0052d9)));
|
||||
background-color: var(--td-checkbox-tag-active-bg-color, var(--td-brand-color-light, var(--td-primary-color-1, #f2f3ff)));
|
||||
}
|
||||
.t-checkbox--tag .t-checkbox__title--checked {
|
||||
color: var(--td-checkbox-tag-active-color, var(--td-brand-color, var(--td-primary-color-7, #0052d9)));
|
||||
}
|
||||
.t-checkbox--tag .t-checkbox__content {
|
||||
margin-right: 0;
|
||||
}
|
||||
238
uni_modules/tdesign-uniapp/components/checkbox/checkbox.vue
Normal file
238
uni_modules/tdesign-uniapp/components/checkbox/checkbox.vue
Normal file
@@ -0,0 +1,238 @@
|
||||
<template>
|
||||
<view
|
||||
:id="tId"
|
||||
:style="tools._style([customStyle])"
|
||||
:class="tools.cls(classPrefix, [placement, theme, ['checked', dataChecked], ['block', block], ['disabled', _disabled]]) + ' ' + tClass"
|
||||
aria-role="checkbox"
|
||||
:aria-checked="dataChecked ? (dataIndeterminate ? 'mixed' : true) : false"
|
||||
:aria-disabled="_disabled ? true : false"
|
||||
@click.stop="handleTap"
|
||||
>
|
||||
<view
|
||||
v-if="theme == 'default'"
|
||||
:class="tools.cls(classPrefix + '__icon', [placement, ['checked', dataChecked], ['disabled', _disabled]]) + ' ' + tClassIcon"
|
||||
>
|
||||
<slot
|
||||
v-if="icon === 'slot'"
|
||||
name="icon"
|
||||
/>
|
||||
<view
|
||||
v-else-if="tools.isArray(icon)"
|
||||
:class="classPrefix + '__icon'"
|
||||
>
|
||||
<image
|
||||
:src="dataChecked ? (dataIndeterminate && icon[2] ? icon[2] : icon[0]) : icon[1]"
|
||||
:class="classPrefix + '__icon-image'"
|
||||
/>
|
||||
</view>
|
||||
<block v-else>
|
||||
<t-icon
|
||||
v-if="dataChecked && (icon == 'circle' || icon == 'rectangle')"
|
||||
:name="dataIndeterminate ? 'minus-' + icon + '-filled' : 'check-' + icon + '-filled'"
|
||||
:class="tools.cls(classPrefix + '__icon-wrapper', [])"
|
||||
/>
|
||||
<t-icon
|
||||
v-if="dataChecked && icon == 'line'"
|
||||
:name="dataIndeterminate ? 'minus-' + icon + '-filled' : 'check'"
|
||||
:class="tools.cls(classPrefix + '__icon-wrapper', [])"
|
||||
/>
|
||||
<view
|
||||
v-else-if="!dataChecked && (icon == 'circle' || icon == 'rectangle')"
|
||||
:class="tools.cls(classPrefix + '__icon-' + icon, [['disabled', _disabled]])"
|
||||
/>
|
||||
<view
|
||||
v-if="!dataChecked && icon == 'line'"
|
||||
class="placeholder"
|
||||
/>
|
||||
</block>
|
||||
</view>
|
||||
<view
|
||||
:class="classPrefix + '__content'"
|
||||
data-target="text"
|
||||
@click.stop="handleTap"
|
||||
>
|
||||
<view
|
||||
:class="
|
||||
tools.cls(classPrefix + '__title', [
|
||||
['disabled', _disabled],
|
||||
['checked', dataChecked]
|
||||
]) +
|
||||
' ' +
|
||||
tClassLabel
|
||||
"
|
||||
:style="'-webkit-line-clamp:' + maxLabelRow"
|
||||
>
|
||||
<block v-if="label">
|
||||
{{ label }}
|
||||
</block>
|
||||
<slot />
|
||||
<slot name="label" />
|
||||
</view>
|
||||
<view
|
||||
:class="tools.cls(classPrefix + '__description', [['disabled', _disabled]]) + ' ' + tClassContent"
|
||||
:style="'-webkit-line-clamp:' + maxContentRow"
|
||||
>
|
||||
<block v-if="content">
|
||||
{{ content }}
|
||||
</block>
|
||||
<slot name="content" />
|
||||
</view>
|
||||
</view>
|
||||
<view
|
||||
v-if="theme == 'default' && !dataBorderless"
|
||||
:class="tools.cls(classPrefix + '__border', [placement]) + ' ' + tClassBorder"
|
||||
/>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import TIcon from '../icon/icon';
|
||||
import { uniComponent } from '../common/src/index';
|
||||
import { coalesce } from '../common/utils';
|
||||
import { prefix, ISOLATED_RELATION_KEY } from '../common/config';
|
||||
import props from './props';
|
||||
import tools from '../common/utils.wxs';
|
||||
import { ChildrenMixin, RELATION_MAP } from '../common/relation';
|
||||
|
||||
|
||||
const name = `${prefix}-checkbox`;
|
||||
|
||||
export default uniComponent({
|
||||
name,
|
||||
options: {
|
||||
styleIsolation: 'shared',
|
||||
},
|
||||
controlledProps: [
|
||||
{
|
||||
key: 'checked',
|
||||
event: 'change',
|
||||
},
|
||||
],
|
||||
externalClasses: [
|
||||
`${prefix}-class`,
|
||||
`${prefix}-class-label`,
|
||||
`${prefix}-class-icon`,
|
||||
`${prefix}-class-content`,
|
||||
`${prefix}-class-border`,
|
||||
],
|
||||
mixins: [ChildrenMixin(RELATION_MAP.Checkbox)],
|
||||
components: {
|
||||
TIcon,
|
||||
},
|
||||
props: {
|
||||
...props,
|
||||
theme: {
|
||||
type: String,
|
||||
default: 'default',
|
||||
},
|
||||
tId: {
|
||||
type: String,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
prefix,
|
||||
classPrefix: name,
|
||||
_disabled: false,
|
||||
tools,
|
||||
|
||||
dataBorderless: this.borderless,
|
||||
dataIndeterminate: this.indeterminate,
|
||||
dataChecked: coalesce(this.checked, this.defaultChecked),
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
isIsolated() {
|
||||
return this.relationKey === ISOLATED_RELATION_KEY;
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
borderless: {
|
||||
handler(v) {
|
||||
this.dataBorderless = v;
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
indeterminate: {
|
||||
handler(v) {
|
||||
this.dataIndeterminate = v;
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
checked: {
|
||||
handler(v) {
|
||||
this.dataChecked = v;
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
disabled: {
|
||||
handler(v) {
|
||||
this._disabled = v;
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
innerAfterLinked() {
|
||||
if (this.isIsolated) return;
|
||||
const parent = this[RELATION_MAP.Checkbox];
|
||||
const { value, disabled, borderless } = parent;
|
||||
const { dataValue, checked, checkAll, item, dataIndeterminate } = this;
|
||||
const valueSet = new Set(value);
|
||||
const checkedFromParent = valueSet.has(this.value);
|
||||
const data = {
|
||||
_disabled: this.disabled == null ? disabled : this.disabled,
|
||||
};
|
||||
|
||||
data.dataBorderless = !!(coalesce(this.borderless, borderless));
|
||||
|
||||
data.dataChecked = this.dataChecked || checkedFromParent;
|
||||
if (this.dataChecked) {
|
||||
parent.updateValue({
|
||||
value: dataValue,
|
||||
checked,
|
||||
checkAll,
|
||||
item,
|
||||
indeterminate: dataIndeterminate,
|
||||
trigger: 'init',
|
||||
});
|
||||
}
|
||||
|
||||
if (this.checkAll) {
|
||||
data.dataChecked = valueSet.size > 0;
|
||||
// data.indeterminate =
|
||||
}
|
||||
|
||||
Object.keys(data).forEach((key) => {
|
||||
this[key] = data[key];
|
||||
});
|
||||
},
|
||||
handleTap(e) {
|
||||
const { _disabled, readonly, contentDisabled } = this;
|
||||
const { target } = e.currentTarget.dataset;
|
||||
|
||||
if (_disabled || readonly || (target === 'text' && contentDisabled)) return;
|
||||
|
||||
const { value, label, checkAll, dataIndeterminate } = this;
|
||||
const checked = !this.dataChecked;
|
||||
const parent = this[RELATION_MAP.Checkbox];
|
||||
|
||||
|
||||
if (parent && !this.isIsolated) {
|
||||
parent.updateValue({ value, checkAll, indeterminate: dataIndeterminate, checked, item: { label, value, checked } });
|
||||
} else {
|
||||
this._trigger('change', { context: { value, label }, checked });
|
||||
}
|
||||
},
|
||||
|
||||
setDisabled(disabled) {
|
||||
this._disabled = this.disabled || disabled;
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style scoped>
|
||||
@import './checkbox.css';
|
||||
</style>
|
||||
90
uni_modules/tdesign-uniapp/components/checkbox/props.ts
Normal file
90
uni_modules/tdesign-uniapp/components/checkbox/props.ts
Normal file
@@ -0,0 +1,90 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
|
||||
* */
|
||||
|
||||
import type { TdCheckboxProps } from './type';
|
||||
export default {
|
||||
/** 是否为块级元素 */
|
||||
block: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
/** 是否开启无边框模式 */
|
||||
borderless: {
|
||||
type: Boolean,
|
||||
default: undefined,
|
||||
},
|
||||
/** 用于标识是否为「全选选项」。单独使用无效,需在 CheckboxGroup 中使用 */
|
||||
checkAll: Boolean,
|
||||
/** 是否选中 */
|
||||
checked: Boolean,
|
||||
/** 是否选中,非受控属性 */
|
||||
defaultChecked: Boolean,
|
||||
/** 多选框内容 */
|
||||
content: {
|
||||
type: String,
|
||||
},
|
||||
/** 是否禁用组件内容(content)触发选中 */
|
||||
contentDisabled: Boolean,
|
||||
/** 是否禁用组件。如果父组件存在 CheckboxGroup,默认值由 CheckboxGroup.disabled 控制。优先级:Checkbox.disabled > CheckboxGroup.disabled > Form.disabled */
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: undefined,
|
||||
},
|
||||
/** 自定义选中图标和非选中图标。使用 Array 时表示:`[选中态图标,非选中态图标,半选中态图标]`。使用 String 时,值为 circle 表示填充圆形图标、值为 line 表示描边型图标、值为 rectangle 表示填充矩形图标 */
|
||||
icon: {
|
||||
type: [String, Array],
|
||||
default: 'circle' as TdCheckboxProps['icon'],
|
||||
},
|
||||
/** 是否为半选 */
|
||||
indeterminate: Boolean,
|
||||
/** 主文案 */
|
||||
label: {
|
||||
type: String,
|
||||
},
|
||||
/** 内容最大行数限制 */
|
||||
maxContentRow: {
|
||||
type: Number,
|
||||
default: 5,
|
||||
},
|
||||
/** 主文案最大行数限制 */
|
||||
maxLabelRow: {
|
||||
type: Number,
|
||||
default: 3,
|
||||
},
|
||||
/** HTML 元素原生属性 */
|
||||
name: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
/** 多选框和内容相对位置 */
|
||||
placement: {
|
||||
type: String,
|
||||
default: 'left' as TdCheckboxProps['placement'],
|
||||
validator(val: TdCheckboxProps['placement']): boolean {
|
||||
if (!val) return true;
|
||||
return ['left', 'right'].includes(val);
|
||||
},
|
||||
},
|
||||
/** 只读状态 */
|
||||
readonly: {
|
||||
type: Boolean,
|
||||
default: undefined,
|
||||
},
|
||||
/** -1 时代表独立,不再寻找 parent,用于头条小程序 */
|
||||
relationKey: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
/** 多选框的值 */
|
||||
value: {
|
||||
type: [String, Number, Boolean],
|
||||
},
|
||||
/** 值变化时触发。`context` 表示当前点击项内容 */
|
||||
onChange: {
|
||||
type: Function,
|
||||
default: () => ({}),
|
||||
},
|
||||
};
|
||||
96
uni_modules/tdesign-uniapp/components/checkbox/type.ts
Normal file
96
uni_modules/tdesign-uniapp/components/checkbox/type.ts
Normal file
@@ -0,0 +1,96 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
|
||||
* */
|
||||
|
||||
export interface TdCheckboxProps {
|
||||
/**
|
||||
* 是否为块级元素
|
||||
* @default true
|
||||
*/
|
||||
block?: boolean;
|
||||
/**
|
||||
* 是否开启无边框模式
|
||||
*/
|
||||
borderless?: boolean;
|
||||
/**
|
||||
* 用于标识是否为「全选选项」。单独使用无效,需在 CheckboxGroup 中使用
|
||||
* @default false
|
||||
*/
|
||||
checkAll?: boolean;
|
||||
/**
|
||||
* 是否选中
|
||||
*/
|
||||
checked?: boolean;
|
||||
/**
|
||||
* 是否选中,非受控属性
|
||||
*/
|
||||
defaultChecked?: boolean;
|
||||
/**
|
||||
* 多选框内容
|
||||
*/
|
||||
content?: string;
|
||||
/**
|
||||
* 是否禁用组件内容(content)触发选中
|
||||
*/
|
||||
contentDisabled?: boolean;
|
||||
/**
|
||||
* 是否禁用组件。如果父组件存在 CheckboxGroup,默认值由 CheckboxGroup.disabled 控制。优先级:Checkbox.disabled > CheckboxGroup.disabled > Form.disabled
|
||||
*/
|
||||
disabled?: boolean;
|
||||
/**
|
||||
* 自定义选中图标和非选中图标。使用 Array 时表示:`[选中态图标,非选中态图标,半选中态图标]`。使用 String 时,值为 circle 表示填充圆形图标、值为 line 表示描边型图标、值为 rectangle 表示填充矩形图标
|
||||
* @default 'circle'
|
||||
*/
|
||||
icon?: 'circle' | 'line' | 'rectangle' | string[];
|
||||
/**
|
||||
* 是否为半选
|
||||
* @default false
|
||||
*/
|
||||
indeterminate?: boolean;
|
||||
/**
|
||||
* 主文案
|
||||
*/
|
||||
label?: string;
|
||||
/**
|
||||
* 内容最大行数限制
|
||||
* @default 5
|
||||
*/
|
||||
maxContentRow?: number;
|
||||
/**
|
||||
* 主文案最大行数限制
|
||||
* @default 3
|
||||
*/
|
||||
maxLabelRow?: number;
|
||||
/**
|
||||
* HTML 元素原生属性
|
||||
* @default ''
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* 多选框和内容相对位置
|
||||
* @default left
|
||||
*/
|
||||
placement?: 'left' | 'right';
|
||||
/**
|
||||
* 只读状态
|
||||
*/
|
||||
readonly?: boolean;
|
||||
/**
|
||||
* -1 时代表独立,不再寻找 parent,用于头条小程序
|
||||
* @default ''
|
||||
*/
|
||||
relationKey?: string;
|
||||
/**
|
||||
* 多选框的值
|
||||
*/
|
||||
value?: string | number | boolean;
|
||||
/**
|
||||
* 值变化时触发。`context` 表示当前点击项内容
|
||||
*/
|
||||
onChange?: (context: {
|
||||
checked: boolean;
|
||||
context: { value: boolean | number | string; label: boolean | number | string };
|
||||
}) => void;
|
||||
}
|
||||
31
uni_modules/tdesign-uniapp/components/col/README.en-US.md
Normal file
31
uni_modules/tdesign-uniapp/components/col/README.en-US.md
Normal file
@@ -0,0 +1,31 @@
|
||||
:: BASE_DOC ::
|
||||
|
||||
## API
|
||||
|
||||
### Col Props
|
||||
|
||||
name | type | default | description | required
|
||||
-- | -- | -- | -- | --
|
||||
custom-style | Object | - | CSS(Cascading Style Sheets) | N
|
||||
offset | String / Number | - | \- | N
|
||||
span | String / Number | - | \- | N
|
||||
|
||||
### Col Slots
|
||||
|
||||
name | Description
|
||||
-- | --
|
||||
\- | \-
|
||||
|
||||
|
||||
### Row Props
|
||||
|
||||
name | type | default | description | required
|
||||
-- | -- | -- | -- | --
|
||||
custom-style | Object | - | CSS(Cascading Style Sheets) | N
|
||||
gutter | String / Number | - | \- | N
|
||||
|
||||
### Row Slots
|
||||
|
||||
name | Description
|
||||
-- | --
|
||||
\- | \-
|
||||
60
uni_modules/tdesign-uniapp/components/col/README.md
Normal file
60
uni_modules/tdesign-uniapp/components/col/README.md
Normal file
@@ -0,0 +1,60 @@
|
||||
---
|
||||
title: Layout 布局
|
||||
description: 以规则的网格阵列来指导和规范页面中的版面布局以及信息分布,提高界面内布局的一致性,节约成本。
|
||||
spline: base
|
||||
isComponent: true
|
||||
---
|
||||
|
||||
|
||||
## 引入
|
||||
|
||||
可在 `main.ts` 或在需要使用的页面或组件中引入。
|
||||
|
||||
|
||||
```js
|
||||
import TRow from '@tdesign/uniapp/row/row.vue';
|
||||
import TCol from '@tdesign/uniapp/col/col.vue';
|
||||
```
|
||||
|
||||
### 组件类型
|
||||
|
||||
基础
|
||||
|
||||
{{ base }}
|
||||
|
||||
|
||||
增加间距
|
||||
|
||||
{{ offset }}
|
||||
|
||||
|
||||
|
||||
## API
|
||||
|
||||
### Col Props
|
||||
|
||||
名称 | 类型 | 默认值 | 描述 | 必传
|
||||
-- | -- | -- | -- | --
|
||||
custom-style | Object | - | 自定义样式 | N
|
||||
offset | String / Number | - | 列的偏移量(默认单位px) | N
|
||||
span | String / Number | - | 列的宽度(默认单位px) | N
|
||||
|
||||
### Col Slots
|
||||
|
||||
名称 | 描述
|
||||
-- | --
|
||||
\- | 默认插槽,列内容
|
||||
|
||||
|
||||
### Row Props
|
||||
|
||||
名称 | 类型 | 默认值 | 描述 | 必传
|
||||
-- | -- | -- | -- | --
|
||||
custom-style | Object | - | 自定义样式 | N
|
||||
gutter | String / Number | - | 列之间的间距(默认单位px) | N
|
||||
|
||||
### Row Slots
|
||||
|
||||
名称 | 描述
|
||||
-- | --
|
||||
\- | 默认插槽,行内容
|
||||
149
uni_modules/tdesign-uniapp/components/col/col.css
Normal file
149
uni_modules/tdesign-uniapp/components/col/col.css
Normal file
@@ -0,0 +1,149 @@
|
||||
.t-col {
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
min-height: 1px;
|
||||
}
|
||||
.t-col--1 {
|
||||
width: 4.16666667%;
|
||||
}
|
||||
.t-col--offset-1 {
|
||||
margin-left: 4.16666667%;
|
||||
}
|
||||
.t-col--2 {
|
||||
width: 8.33333333%;
|
||||
}
|
||||
.t-col--offset-2 {
|
||||
margin-left: 8.33333333%;
|
||||
}
|
||||
.t-col--3 {
|
||||
width: 12.5%;
|
||||
}
|
||||
.t-col--offset-3 {
|
||||
margin-left: 12.5%;
|
||||
}
|
||||
.t-col--4 {
|
||||
width: 16.66666667%;
|
||||
}
|
||||
.t-col--offset-4 {
|
||||
margin-left: 16.66666667%;
|
||||
}
|
||||
.t-col--5 {
|
||||
width: 20.83333333%;
|
||||
}
|
||||
.t-col--offset-5 {
|
||||
margin-left: 20.83333333%;
|
||||
}
|
||||
.t-col--6 {
|
||||
width: 25%;
|
||||
}
|
||||
.t-col--offset-6 {
|
||||
margin-left: 25%;
|
||||
}
|
||||
.t-col--7 {
|
||||
width: 29.16666667%;
|
||||
}
|
||||
.t-col--offset-7 {
|
||||
margin-left: 29.16666667%;
|
||||
}
|
||||
.t-col--8 {
|
||||
width: 33.33333333%;
|
||||
}
|
||||
.t-col--offset-8 {
|
||||
margin-left: 33.33333333%;
|
||||
}
|
||||
.t-col--9 {
|
||||
width: 37.5%;
|
||||
}
|
||||
.t-col--offset-9 {
|
||||
margin-left: 37.5%;
|
||||
}
|
||||
.t-col--10 {
|
||||
width: 41.66666667%;
|
||||
}
|
||||
.t-col--offset-10 {
|
||||
margin-left: 41.66666667%;
|
||||
}
|
||||
.t-col--11 {
|
||||
width: 45.83333333%;
|
||||
}
|
||||
.t-col--offset-11 {
|
||||
margin-left: 45.83333333%;
|
||||
}
|
||||
.t-col--12 {
|
||||
width: 50%;
|
||||
}
|
||||
.t-col--offset-12 {
|
||||
margin-left: 50%;
|
||||
}
|
||||
.t-col--13 {
|
||||
width: 54.16666667%;
|
||||
}
|
||||
.t-col--offset-13 {
|
||||
margin-left: 54.16666667%;
|
||||
}
|
||||
.t-col--14 {
|
||||
width: 58.33333333%;
|
||||
}
|
||||
.t-col--offset-14 {
|
||||
margin-left: 58.33333333%;
|
||||
}
|
||||
.t-col--15 {
|
||||
width: 62.5%;
|
||||
}
|
||||
.t-col--offset-15 {
|
||||
margin-left: 62.5%;
|
||||
}
|
||||
.t-col--16 {
|
||||
width: 66.66666667%;
|
||||
}
|
||||
.t-col--offset-16 {
|
||||
margin-left: 66.66666667%;
|
||||
}
|
||||
.t-col--17 {
|
||||
width: 70.83333333%;
|
||||
}
|
||||
.t-col--offset-17 {
|
||||
margin-left: 70.83333333%;
|
||||
}
|
||||
.t-col--18 {
|
||||
width: 75%;
|
||||
}
|
||||
.t-col--offset-18 {
|
||||
margin-left: 75%;
|
||||
}
|
||||
.t-col--19 {
|
||||
width: 79.16666667%;
|
||||
}
|
||||
.t-col--offset-19 {
|
||||
margin-left: 79.16666667%;
|
||||
}
|
||||
.t-col--20 {
|
||||
width: 83.33333333%;
|
||||
}
|
||||
.t-col--offset-20 {
|
||||
margin-left: 83.33333333%;
|
||||
}
|
||||
.t-col--21 {
|
||||
width: 87.5%;
|
||||
}
|
||||
.t-col--offset-21 {
|
||||
margin-left: 87.5%;
|
||||
}
|
||||
.t-col--22 {
|
||||
width: 91.66666667%;
|
||||
}
|
||||
.t-col--offset-22 {
|
||||
margin-left: 91.66666667%;
|
||||
}
|
||||
.t-col--23 {
|
||||
width: 95.83333333%;
|
||||
}
|
||||
.t-col--offset-23 {
|
||||
margin-left: 95.83333333%;
|
||||
}
|
||||
.t-col--24 {
|
||||
width: 100%;
|
||||
}
|
||||
.t-col--offset-24 {
|
||||
margin-left: 100%;
|
||||
}
|
||||
58
uni_modules/tdesign-uniapp/components/col/col.vue
Normal file
58
uni_modules/tdesign-uniapp/components/col/col.vue
Normal file
@@ -0,0 +1,58 @@
|
||||
<template>
|
||||
<view
|
||||
:class="[
|
||||
tClass,
|
||||
tools.cls(classPrefix, [span]),
|
||||
(offset ? classPrefix + '--offset-' + offset : '')
|
||||
]"
|
||||
:style="getColStyles(gutter, customStyle)"
|
||||
>
|
||||
<slot />
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import { uniComponent } from '../common/src/index';
|
||||
import { prefix } from '../common/config';
|
||||
import props from './props';
|
||||
import tools from '../common/utils.wxs';
|
||||
import { getColStyles } from './computed.js';
|
||||
import { ChildrenMixin, RELATION_MAP } from '../common/relation';
|
||||
|
||||
const name = `${prefix}-col`;
|
||||
|
||||
|
||||
export default uniComponent({
|
||||
name,
|
||||
options: {
|
||||
styleIsolation: 'shared',
|
||||
virtualHost: true,
|
||||
},
|
||||
externalClasses: [`${prefix}-class`],
|
||||
mixins: [ChildrenMixin(RELATION_MAP.Col)],
|
||||
props: {
|
||||
...props,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
prefix,
|
||||
classPrefix: name,
|
||||
tools,
|
||||
gutter: '',
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
getColStyles,
|
||||
},
|
||||
});
|
||||
|
||||
</script>
|
||||
<style scoped>
|
||||
@import './col.css';
|
||||
</style>
|
||||
<style scoped>
|
||||
.t-col {
|
||||
/* 适配 qq 小程序等 */
|
||||
display: unset;
|
||||
float: left;
|
||||
}
|
||||
</style>
|
||||
14
uni_modules/tdesign-uniapp/components/col/computed.js
Normal file
14
uni_modules/tdesign-uniapp/components/col/computed.js
Normal file
@@ -0,0 +1,14 @@
|
||||
import utils from '../common/utils.wxs';
|
||||
|
||||
export function getColStyles(gutter, customStyle) {
|
||||
let _style = '';
|
||||
if (gutter) {
|
||||
_style = utils._style({
|
||||
'padding-right': utils.addUnit(gutter / 2),
|
||||
'padding-left': utils.addUnit(gutter / 2),
|
||||
});
|
||||
}
|
||||
|
||||
return utils._style([customStyle]) + _style;
|
||||
}
|
||||
|
||||
16
uni_modules/tdesign-uniapp/components/col/props.ts
Normal file
16
uni_modules/tdesign-uniapp/components/col/props.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
|
||||
* */
|
||||
|
||||
export default {
|
||||
/** 列的偏移量(默认单位px) */
|
||||
offset: {
|
||||
type: [String, Number],
|
||||
},
|
||||
/** 列的宽度(默认单位px) */
|
||||
span: {
|
||||
type: [String, Number],
|
||||
},
|
||||
};
|
||||
16
uni_modules/tdesign-uniapp/components/col/type.ts
Normal file
16
uni_modules/tdesign-uniapp/components/col/type.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
|
||||
* */
|
||||
|
||||
export interface TdColProps {
|
||||
/**
|
||||
* 列的偏移量(默认单位px)
|
||||
*/
|
||||
offset?: string | number;
|
||||
/**
|
||||
* 列的宽度(默认单位px)
|
||||
*/
|
||||
span?: string | number;
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
.t-collapse-panel {
|
||||
background-color: var(--td-collapse-panel-bg-color, var(--td-bg-color-container, var(--td-font-white-1, #ffffff)));
|
||||
}
|
||||
.t-collapse-panel--disabled {
|
||||
pointer-events: none;
|
||||
}
|
||||
.t-collapse-panel--disabled .t-collapse-panel__content,
|
||||
.t-collapse-panel--disabled .t-collapse-panel__header {
|
||||
opacity: 0.3;
|
||||
}
|
||||
.t-collapse-panel--top {
|
||||
display: flex;
|
||||
flex-direction: column-reverse;
|
||||
}
|
||||
.t-collapse-panel__header {
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding-left: var(--td-collapse-horizontal-padding, 32rpx);
|
||||
height: var(--td-collapse-header-height, auto);
|
||||
}
|
||||
.t-collapse-panel__header--top {
|
||||
position: relative;
|
||||
}
|
||||
.t-collapse-panel__header--top::after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: unset;
|
||||
left: unset;
|
||||
right: unset;
|
||||
background-color: var(--td-collapse-border-color, var(--td-border-level-1-color, var(--td-gray-color-3, #e7e7e7)));
|
||||
}
|
||||
.t-collapse-panel__header--top::after {
|
||||
height: 1px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
transform: scaleY(0.5);
|
||||
}
|
||||
.t-collapse-panel__header--bottom {
|
||||
position: relative;
|
||||
}
|
||||
.t-collapse-panel__header--bottom::after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: unset;
|
||||
bottom: 0;
|
||||
left: unset;
|
||||
right: unset;
|
||||
background-color: var(--td-collapse-border-color, var(--td-border-level-1-color, var(--td-gray-color-3, #e7e7e7)));
|
||||
}
|
||||
.t-collapse-panel__header--bottom::after {
|
||||
height: 1px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
transform: scaleY(0.5);
|
||||
}
|
||||
.t-collapse-panel__header::after {
|
||||
left: var(--td-spacer-2, 32rpx);
|
||||
}
|
||||
.t-collapse-panel__extra {
|
||||
font: var(--td-collapse-extra-font, var(--td-font-body-large, 32rpx / 48rpx var(--td-font-family, PingFang SC, Microsoft YaHei, Arial Regular)));
|
||||
}
|
||||
.t-collapse-panel__body {
|
||||
position: relative;
|
||||
}
|
||||
.t-collapse-panel__body::after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: unset;
|
||||
bottom: 0;
|
||||
left: unset;
|
||||
right: unset;
|
||||
background-color: var(--td-collapse-border-color, var(--td-border-level-1-color, var(--td-gray-color-3, #e7e7e7)));
|
||||
}
|
||||
.t-collapse-panel__body::after {
|
||||
height: 1px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
transform: scaleY(0.5);
|
||||
}
|
||||
.t-collapse-panel__wrapper {
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
.t-collapse-panel__content {
|
||||
color: var(--td-collapse-content-text-color, var(--td-text-color-primary, var(--td-font-gray-1, rgba(0, 0, 0, 0.9))));
|
||||
font: var(--td-collapse-content-font, var(--td-font-body-medium, 28rpx / 44rpx var(--td-font-family, PingFang SC, Microsoft YaHei, Arial Regular)));
|
||||
padding: var(--td-collapse-content-padding, 32rpx);
|
||||
}
|
||||
.t-collapse-panel__content--disabled {
|
||||
color: var(--td-collapse-disabled-color, var(--td-text-color-disabled, var(--td-font-gray-4, rgba(0, 0, 0, 0.26))));
|
||||
}
|
||||
.t-collapse-panel__content--expanded.t-collapse-panel__content--bottom {
|
||||
position: relative;
|
||||
}
|
||||
.t-collapse-panel__content--expanded.t-collapse-panel__content--bottom::after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: unset;
|
||||
bottom: 0;
|
||||
left: unset;
|
||||
right: unset;
|
||||
background-color: var(--td-collapse-border-color, var(--td-border-level-1-color, var(--td-gray-color-3, #e7e7e7)));
|
||||
}
|
||||
.t-collapse-panel__content--expanded.t-collapse-panel__content--bottom::after {
|
||||
height: 1px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
transform: scaleY(0.5);
|
||||
}
|
||||
.t-collapse-panel__content--expanded.t-collapse-panel__content--top {
|
||||
position: relative;
|
||||
}
|
||||
.t-collapse-panel__content--expanded.t-collapse-panel__content--top::after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: unset;
|
||||
left: unset;
|
||||
right: unset;
|
||||
background-color: var(--td-collapse-border-color, var(--td-border-level-1-color, var(--td-gray-color-3, #e7e7e7)));
|
||||
}
|
||||
.t-collapse-panel__content--expanded.t-collapse-panel__content--top::after {
|
||||
height: 1px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
transform: scaleY(0.5);
|
||||
}
|
||||
.t-collapse-panel__arrow--top {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
.class-title {
|
||||
font: var(--td-collapse-title-font, var(--td-font-body-large, 32rpx / 48rpx var(--td-font-family, PingFang SC, Microsoft YaHei, Arial Regular)));
|
||||
color: var(--td-collapse-header-text-color, var(--td-text-color-primary, var(--td-font-gray-1, rgba(0, 0, 0, 0.9))));
|
||||
}
|
||||
.class-left-icon {
|
||||
color: var(--td-collapse-left-icon-color, var(--td-brand-color, var(--td-primary-color-7, #0052d9)));
|
||||
}
|
||||
.class-right-icon {
|
||||
color: var(--td-collapse-icon-color, var(--td-text-color-placeholder, var(--td-font-gray-3, rgba(0, 0, 0, 0.4))));
|
||||
}
|
||||
.class-title--disabled,
|
||||
.class-note--disabled,
|
||||
.class-left-icon--disabled,
|
||||
.class-right-icon--disabled {
|
||||
color: var(--td-collapse-disabled-color, var(--td-text-color-disabled, var(--td-font-gray-4, rgba(0, 0, 0, 0.26))));
|
||||
}
|
||||
@@ -0,0 +1,238 @@
|
||||
<template>
|
||||
<view
|
||||
:style="tools._style([customStyle])"
|
||||
:class="[
|
||||
classPrefix + ' ' + classPrefix + '--' + placement,
|
||||
tClass
|
||||
]"
|
||||
>
|
||||
<view
|
||||
:class="classPrefix + '__title'"
|
||||
aria-role="button"
|
||||
:aria-expanded="expanded"
|
||||
:aria-disabled="ultimateDisabled"
|
||||
@click="onClick"
|
||||
>
|
||||
<t-cell
|
||||
:title="header"
|
||||
:note="headerRightContent"
|
||||
bordered
|
||||
:left-icon="headerLeftIcon"
|
||||
:right-icon="ultimateExpandIcon ? (expanded ? 'chevron-up' : 'chevron-down') : ''"
|
||||
:t-class="tools.cls(classPrefix + '__header', [placement, ['expanded', expanded]]) + ' ' + tClassHeader"
|
||||
:t-class-title="'class-title ' + (ultimateDisabled ? 'class-title--disabled' : '')"
|
||||
:t-class-note="'class-note ' + (ultimateDisabled ? 'class-note--disabled' : '')"
|
||||
:t-class-left-icon="'class-left-icon ' + (ultimateDisabled ? 'class-left-icon--disabled' : '')"
|
||||
:t-class-right-icon="'class-right-icon ' + classPrefix + '__arrow--' + placement + ' ' + (ultimateDisabled ? 'class-right-icon--disabled' : '')"
|
||||
t-class-hover="class-header-hover"
|
||||
:title-style="titleCustomStyle"
|
||||
:note-style="noteCustomStyle"
|
||||
:right-icon-style="rightIconCustomStyle"
|
||||
>
|
||||
<template
|
||||
#left-icon
|
||||
>
|
||||
<slot
|
||||
name="header-left-icon"
|
||||
/>
|
||||
</template>
|
||||
<template
|
||||
#title
|
||||
>
|
||||
<slot
|
||||
name="header"
|
||||
/>
|
||||
</template>
|
||||
<template
|
||||
#note
|
||||
>
|
||||
<slot
|
||||
name="header-right-content"
|
||||
/>
|
||||
</template>
|
||||
<template
|
||||
#right-icon
|
||||
>
|
||||
<slot
|
||||
name="expand-icon"
|
||||
/>
|
||||
</template>
|
||||
</t-cell>
|
||||
</view>
|
||||
<view
|
||||
:class="classPrefix + '__wrapper'"
|
||||
:animation="animation"
|
||||
:aria-hidden="expanded ? '' : true"
|
||||
>
|
||||
<view :class="tools.cls(classPrefix + '__content', [['disabled', ultimateDisabled], ['expanded', expanded], placement]) + ' ' + tClassContent">
|
||||
{{ content }}
|
||||
<slot />
|
||||
<slot name="content" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import TCell from '../cell/cell';
|
||||
import { uniComponent } from '../common/src/index';
|
||||
import { prefix } from '../common/config';
|
||||
import props from './props';
|
||||
import { getRect } from '../common/utils';
|
||||
import tools from '../common/utils.wxs';
|
||||
import { ChildrenMixin, RELATION_MAP } from '../common/relation';
|
||||
|
||||
|
||||
const name = `${prefix}-collapse-panel`;
|
||||
const DISABLED_COLOR = 'var(--td-text-color-disabled, var(--td-font-gray-4, rgba(0, 0, 0, .26)))';
|
||||
|
||||
export default uniComponent({
|
||||
name,
|
||||
options: {
|
||||
styleIsolation: 'shared',
|
||||
},
|
||||
externalClasses: [
|
||||
`${prefix}-class`,
|
||||
`${prefix}-class-content`,
|
||||
`${prefix}-class-header`,
|
||||
],
|
||||
mixins: [ChildrenMixin(RELATION_MAP.CollapsePanel)],
|
||||
components: {
|
||||
TCell,
|
||||
},
|
||||
props: {
|
||||
...props,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
prefix,
|
||||
expanded: false,
|
||||
classPrefix: name,
|
||||
classBasePrefix: prefix,
|
||||
ultimateExpandIcon: false,
|
||||
ultimateDisabled: false,
|
||||
tools,
|
||||
animation: null,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
titleCustomStyle() {
|
||||
return tools._style({
|
||||
fontSize: 'var(--td-collapse-title-font-size, var(--td-font-size-m, 16px))',
|
||||
color: this.ultimateDisabled && DISABLED_COLOR,
|
||||
});
|
||||
},
|
||||
noteCustomStyle() {
|
||||
return tools._style({
|
||||
color: this.ultimateDisabled && DISABLED_COLOR,
|
||||
|
||||
});
|
||||
},
|
||||
rightIconCustomStyle() {
|
||||
return tools._style({
|
||||
color: this.ultimateDisabled && DISABLED_COLOR,
|
||||
});
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
disabled: {
|
||||
handler(e) {
|
||||
this.ultimateDisabled = !!e;
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
updateExpanded(activeValues = []) {
|
||||
if (!this[RELATION_MAP.CollapsePanel]) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { value } = this;
|
||||
const { defaultExpandAll } = this[RELATION_MAP.CollapsePanel];
|
||||
const expanded = defaultExpandAll ? !this.expanded : activeValues?.includes(value);
|
||||
|
||||
if (expanded === this.expanded) return;
|
||||
|
||||
this.expanded = expanded;
|
||||
this.updateStyle(expanded);
|
||||
},
|
||||
|
||||
updateStyle(expanded) {
|
||||
return getRect(this, `.${name}__content`)
|
||||
.then(rect => rect.height)
|
||||
.then((height) => {
|
||||
const animation = uni.createAnimation({
|
||||
duration: 0,
|
||||
timingFunction: 'ease-in-out',
|
||||
});
|
||||
|
||||
if (expanded) {
|
||||
animation
|
||||
.height(height)
|
||||
.top(0)
|
||||
.step({ duration: 300 })
|
||||
.height('auto')
|
||||
.step();
|
||||
} else {
|
||||
let doAnimation = false;
|
||||
|
||||
// #ifdef H5 || APP-PLUS
|
||||
animation
|
||||
.height(height)
|
||||
.top(1)
|
||||
.step({ duration: 17 })
|
||||
.height(0)
|
||||
.step({ duration: 300 });
|
||||
doAnimation = true;
|
||||
// #endif
|
||||
|
||||
if (!doAnimation) {
|
||||
animation
|
||||
.height(height)
|
||||
.top(1)
|
||||
.step({ duration: 1 })
|
||||
.height(0)
|
||||
.step({ duration: 300 });
|
||||
}
|
||||
}
|
||||
|
||||
this.animation = animation.export();
|
||||
});
|
||||
},
|
||||
|
||||
onClick() {
|
||||
const { ultimateDisabled } = this;
|
||||
const { value } = this;
|
||||
|
||||
|
||||
if (ultimateDisabled) return;
|
||||
|
||||
if (this[RELATION_MAP.CollapsePanel].defaultExpandAll) {
|
||||
this.updateExpanded();
|
||||
} else {
|
||||
this[RELATION_MAP.CollapsePanel].switch(value);
|
||||
}
|
||||
},
|
||||
|
||||
innerAfterLinked() {
|
||||
const { dataValue, expandIcon, disabled } = this[RELATION_MAP.CollapsePanel];
|
||||
|
||||
this.ultimateExpandIcon = this.expandIcon == null ? expandIcon : this.expandIcon;
|
||||
this.ultimateDisabled = this.disabled == null ? disabled : this.disabled;
|
||||
|
||||
|
||||
let interval = 0;
|
||||
// #ifdef APP-PLUS
|
||||
interval = 33;
|
||||
// #endif
|
||||
setTimeout(() => {
|
||||
this.updateExpanded(dataValue);
|
||||
}, interval);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
</script>
|
||||
<style scoped>
|
||||
@import './collapse-panel.css';
|
||||
</style>
|
||||
@@ -0,0 +1,48 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
|
||||
* */
|
||||
|
||||
import type { TdCollapsePanelProps } from './type';
|
||||
export default {
|
||||
/** 折叠面板内容 */
|
||||
content: {
|
||||
type: String,
|
||||
},
|
||||
/** 禁止当前面板展开,优先级大于 Collapse 的同名属性 */
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: undefined,
|
||||
},
|
||||
/** 当前折叠面板展开图标,优先级大于 Collapse 的同名属性 */
|
||||
expandIcon: {
|
||||
type: Boolean,
|
||||
default: undefined as TdCollapsePanelProps['expandIcon'],
|
||||
},
|
||||
/** 面板头内容 */
|
||||
header: {
|
||||
type: String,
|
||||
},
|
||||
/** 面板头左侧图标 */
|
||||
headerLeftIcon: {
|
||||
type: String,
|
||||
},
|
||||
/** 面板头的右侧区域,一般用于呈现面板操作 */
|
||||
headerRightContent: {
|
||||
type: String,
|
||||
},
|
||||
/** 选项卡内容的位置 */
|
||||
placement: {
|
||||
type: String,
|
||||
default: 'bottom' as TdCollapsePanelProps['placement'],
|
||||
validator(val: TdCollapsePanelProps['placement']): boolean {
|
||||
if (!val) return true;
|
||||
return ['bottom', 'top'].includes(val);
|
||||
},
|
||||
},
|
||||
/** 当前面板唯一标识,如果值为空则取当前面下标兜底作为唯一标识 */
|
||||
value: {
|
||||
type: [String, Number],
|
||||
},
|
||||
};
|
||||
41
uni_modules/tdesign-uniapp/components/collapse-panel/type.ts
Normal file
41
uni_modules/tdesign-uniapp/components/collapse-panel/type.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
|
||||
* */
|
||||
|
||||
export interface TdCollapsePanelProps {
|
||||
/**
|
||||
* 折叠面板内容
|
||||
*/
|
||||
content?: string;
|
||||
/**
|
||||
* 禁止当前面板展开,优先级大于 Collapse 的同名属性
|
||||
*/
|
||||
disabled?: boolean;
|
||||
/**
|
||||
* 当前折叠面板展开图标,优先级大于 Collapse 的同名属性
|
||||
*/
|
||||
expandIcon?: boolean;
|
||||
/**
|
||||
* 面板头内容
|
||||
*/
|
||||
header?: string;
|
||||
/**
|
||||
* 面板头左侧图标
|
||||
*/
|
||||
headerLeftIcon?: string;
|
||||
/**
|
||||
* 面板头的右侧区域,一般用于呈现面板操作
|
||||
*/
|
||||
headerRightContent?: string;
|
||||
/**
|
||||
* 选项卡内容的位置
|
||||
* @default bottom
|
||||
*/
|
||||
placement?: 'bottom' | 'top';
|
||||
/**
|
||||
* 当前面板唯一标识,如果值为空则取当前面下标兜底作为唯一标识
|
||||
*/
|
||||
value?: string | number;
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
:: BASE_DOC ::
|
||||
|
||||
## API
|
||||
|
||||
### Collapse Props
|
||||
|
||||
name | type | default | description | required
|
||||
-- | -- | -- | -- | --
|
||||
custom-style | Object | - | CSS(Cascading Style Sheets) | N
|
||||
default-expand-all | Boolean | false | \- | N
|
||||
disabled | Boolean | - | \- | N
|
||||
expand-icon | Boolean | true | \- | N
|
||||
expand-mutex | Boolean | false | \- | N
|
||||
theme | String | default | options: default/card | N
|
||||
value | Array | - | `v-model:value` is supported。Typescript:`CollapseValue` `type CollapseValue = Array<string \| number>`。[see more ts definition](https://github.com/Tencent/tdesign-miniprogram/tree/develop/packages/uniapp-components/collapse/type.ts) | N
|
||||
default-value | Array | - | uncontrolled property。Typescript:`CollapseValue` `type CollapseValue = Array<string \| number>`。[see more ts definition](https://github.com/Tencent/tdesign-miniprogram/tree/develop/packages/uniapp-components/collapse/type.ts) | N
|
||||
|
||||
### Collapse Events
|
||||
|
||||
name | params | description
|
||||
-- | -- | --
|
||||
change | `(context: { value: CollapseValue, context: { e: MouseEvent }})` | \-
|
||||
|
||||
### Collapse Slots
|
||||
|
||||
name | Description
|
||||
-- | --
|
||||
\- | \-
|
||||
|
||||
|
||||
### CollapsePanel Props
|
||||
|
||||
name | type | default | description | required
|
||||
-- | -- | -- | -- | --
|
||||
custom-style | Object | - | CSS(Cascading Style Sheets) | N
|
||||
content | String | - | \- | N
|
||||
disabled | Boolean | undefined | \- | N
|
||||
expand-icon | Boolean | undefined | \- | N
|
||||
header | String | - | \- | N
|
||||
header-left-icon | String | - | \- | N
|
||||
header-right-content | String | - | \- | N
|
||||
placement | String | bottom | options: bottom/top | N
|
||||
value | String / Number | - | \- | N
|
||||
|
||||
### CollapsePanel Slots
|
||||
|
||||
name | Description
|
||||
-- | --
|
||||
\- | \-
|
||||
content | \-
|
||||
expand-icon | \-
|
||||
header | \-
|
||||
header-left-icon | \-
|
||||
header-right-content | \-
|
||||
|
||||
### CollapsePanel External Classes
|
||||
|
||||
className | Description
|
||||
-- | --
|
||||
t-class | \-
|
||||
t-class-content | \-
|
||||
t-class-header | \-
|
||||
|
||||
### CSS Variables
|
||||
|
||||
The component provides the following CSS variables, which can be used to customize styles.
|
||||
Name | Default Value | Description
|
||||
-- | -- | --
|
||||
--td-collapse-border-color | @border-level-1-color | -
|
||||
--td-collapse-content-font | @font-body-medium | -
|
||||
--td-collapse-content-padding | 32rpx | -
|
||||
--td-collapse-content-text-color | @text-color-primary | -
|
||||
--td-collapse-disabled-color | @text-color-disabled | -
|
||||
--td-collapse-extra-font | @font-body-large | -
|
||||
--td-collapse-header-height | auto | -
|
||||
--td-collapse-header-text-color | @text-color-primary | -
|
||||
--td-collapse-header-text-disabled-color | @collapse-disabled-color | -
|
||||
--td-collapse-horizontal-padding | 32rpx | -
|
||||
--td-collapse-icon-color | @text-color-placeholder | -
|
||||
--td-collapse-left-icon-color | @brand-color | -
|
||||
--td-collapse-panel-bg-color | @bg-color-container | -
|
||||
--td-collapse-title-font | @font-body-large | -
|
||||
119
uni_modules/tdesign-uniapp/components/collapse/README.md
Normal file
119
uni_modules/tdesign-uniapp/components/collapse/README.md
Normal file
@@ -0,0 +1,119 @@
|
||||
---
|
||||
title: Collapse 折叠面板
|
||||
description: 用于对复杂区域进行分组和隐藏 常用于订单信息展示等
|
||||
spline: data
|
||||
isComponent: true
|
||||
---
|
||||
|
||||
|
||||
|
||||
## 引入
|
||||
|
||||
可在 `main.ts` 或在需要使用的页面或组件中引入。
|
||||
|
||||
```js
|
||||
import TCollapse from '@tdesign/uniapp/collapse/collapse.vue';
|
||||
import TCollapsePanel from '@tdesign/uniapp/collapse-panel/collapse-panel.vue';
|
||||
```
|
||||
|
||||
### 类型
|
||||
|
||||
基础折叠面板
|
||||
|
||||
{{ base }}
|
||||
|
||||
|
||||
带操作说明
|
||||
|
||||
{{ action }}
|
||||
|
||||
手风琴模式
|
||||
|
||||
{{ accordion }}
|
||||
|
||||
### 样式
|
||||
|
||||
卡片折叠面板
|
||||
|
||||
{{ theme }}
|
||||
|
||||
## API
|
||||
|
||||
### Collapse Props
|
||||
|
||||
名称 | 类型 | 默认值 | 描述 | 必传
|
||||
-- | -- | -- | -- | --
|
||||
custom-style | Object | - | 自定义样式 | N
|
||||
default-expand-all | Boolean | false | 默认是否展开全部 | N
|
||||
disabled | Boolean | - | 是否禁用面板展开/收起操作 | N
|
||||
expand-icon | Boolean | true | 展开图标 | N
|
||||
expand-mutex | Boolean | false | 每个面板互斥展开,每次只展开一个面板 | N
|
||||
theme | String | default | 折叠面板风格。可选项:default/card | N
|
||||
value | Array | - | 展开的面板集合。支持语法糖 `v-model:value`。TS 类型:`CollapseValue` `type CollapseValue = Array<string \| number>`。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/packages/uniapp-components/collapse/type.ts) | N
|
||||
default-value | Array | - | 展开的面板集合。非受控属性。TS 类型:`CollapseValue` `type CollapseValue = Array<string \| number>`。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/packages/uniapp-components/collapse/type.ts) | N
|
||||
|
||||
### Collapse Events
|
||||
|
||||
名称 | 参数 | 描述
|
||||
-- | -- | --
|
||||
change | `(context: { value: CollapseValue, context: { e: MouseEvent }})` | 切换面板时触发,返回变化的值
|
||||
|
||||
### Collapse Slots
|
||||
|
||||
名称 | 描述
|
||||
-- | --
|
||||
\- | 默认插槽,自定义内容区域内容
|
||||
|
||||
|
||||
### CollapsePanel Props
|
||||
|
||||
名称 | 类型 | 默认值 | 描述 | 必传
|
||||
-- | -- | -- | -- | --
|
||||
custom-style | Object | - | 自定义样式 | N
|
||||
content | String | - | 折叠面板内容 | N
|
||||
disabled | Boolean | undefined | 禁止当前面板展开,优先级大于 Collapse 的同名属性 | N
|
||||
expand-icon | Boolean | undefined | 当前折叠面板展开图标,优先级大于 Collapse 的同名属性 | N
|
||||
header | String | - | 面板头内容 | N
|
||||
header-left-icon | String | - | 面板头左侧图标 | N
|
||||
header-right-content | String | - | 面板头的右侧区域,一般用于呈现面板操作 | N
|
||||
placement | String | bottom | 选项卡内容的位置。可选项:bottom/top | N
|
||||
value | String / Number | - | 当前面板唯一标识,如果值为空则取当前面下标兜底作为唯一标识 | N
|
||||
|
||||
### CollapsePanel Slots
|
||||
|
||||
名称 | 描述
|
||||
-- | --
|
||||
\- | 默认插槽,作用同 `content` 插槽
|
||||
content | 自定义 `content` 显示内容
|
||||
expand-icon | 自定义 `expand-icon` 显示内容
|
||||
header | 自定义 `header` 显示内容
|
||||
header-left-icon | 自定义 `header-left-icon` 显示内容
|
||||
header-right-content | 自定义 `header-right-content` 显示内容
|
||||
|
||||
### CollapsePanel External Classes
|
||||
|
||||
类名 | 描述
|
||||
-- | --
|
||||
t-class | 根节点样式类
|
||||
t-class-content | 内容样式类
|
||||
t-class-header | 头部样式类
|
||||
|
||||
### CSS Variables
|
||||
|
||||
组件提供了下列 CSS 变量,可用于自定义样式。
|
||||
名称 | 默认值 | 描述
|
||||
-- | -- | --
|
||||
--td-collapse-border-color | @border-level-1-color | -
|
||||
--td-collapse-content-font | @font-body-medium | -
|
||||
--td-collapse-content-padding | 32rpx | -
|
||||
--td-collapse-content-text-color | @text-color-primary | -
|
||||
--td-collapse-disabled-color | @text-color-disabled | -
|
||||
--td-collapse-extra-font | @font-body-large | -
|
||||
--td-collapse-header-height | auto | -
|
||||
--td-collapse-header-text-color | @text-color-primary | -
|
||||
--td-collapse-header-text-disabled-color | @collapse-disabled-color | -
|
||||
--td-collapse-horizontal-padding | 32rpx | -
|
||||
--td-collapse-icon-color | @text-color-placeholder | -
|
||||
--td-collapse-left-icon-color | @brand-color | -
|
||||
--td-collapse-panel-bg-color | @bg-color-container | -
|
||||
--td-collapse-title-font | @font-body-large | -
|
||||
@@ -0,0 +1,5 @@
|
||||
.t-collapse--card {
|
||||
margin: 0 32rpx;
|
||||
border-radius: var(--td-radius-large, 18rpx);
|
||||
overflow: hidden;
|
||||
}
|
||||
119
uni_modules/tdesign-uniapp/components/collapse/collapse.vue
Normal file
119
uni_modules/tdesign-uniapp/components/collapse/collapse.vue
Normal file
@@ -0,0 +1,119 @@
|
||||
<template>
|
||||
<view
|
||||
:style="tools._style([customStyle])"
|
||||
:class="[
|
||||
tClass,
|
||||
tools.cls(classPrefix, [['hairline--top-bottom', border], theme])
|
||||
]"
|
||||
>
|
||||
<slot />
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import { uniComponent } from '../common/src/index';
|
||||
import { prefix } from '../common/config';
|
||||
import { coalesce } from '../common/utils';
|
||||
import props from './props';
|
||||
import tools from '../common/utils.wxs';
|
||||
import { ParentMixin, RELATION_MAP } from '../common/relation';
|
||||
|
||||
|
||||
const name = `${prefix}-collapse`;
|
||||
|
||||
|
||||
export default uniComponent({
|
||||
name,
|
||||
controlledProps: [
|
||||
{
|
||||
key: 'value',
|
||||
event: 'change',
|
||||
},
|
||||
],
|
||||
options: {
|
||||
styleIsolation: 'shared',
|
||||
},
|
||||
externalClasses: [`${prefix}-class`],
|
||||
mixins: [ParentMixin(RELATION_MAP.CollapsePanel)],
|
||||
props: {
|
||||
...props,
|
||||
},
|
||||
emits: [
|
||||
'update:value',
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
prefix,
|
||||
classPrefix: name,
|
||||
tools,
|
||||
border: false,
|
||||
dataValue: coalesce(this.value, this.defaultValue),
|
||||
mounted: false,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
value: {
|
||||
handler(value) {
|
||||
this.dataValue = value;
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
dataValue: {
|
||||
handler() {
|
||||
this.waitUntilMounted(this.updateExpanded);
|
||||
},
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
expandMutex: {
|
||||
handler() {
|
||||
this.waitUntilMounted(this.updateExpanded);
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
|
||||
},
|
||||
mounted() {
|
||||
let interval = 0;
|
||||
// #ifdef APP-PLUS
|
||||
interval = 33;
|
||||
// #endif
|
||||
setTimeout(() => {
|
||||
this.mounted = true;
|
||||
}, interval);
|
||||
},
|
||||
methods: {
|
||||
waitUntilMounted(cb) {
|
||||
if (this.mounted) {
|
||||
cb.call(this);
|
||||
return;
|
||||
}
|
||||
setTimeout(() => {
|
||||
cb.call(this);
|
||||
}, 33);
|
||||
},
|
||||
|
||||
updateExpanded() {
|
||||
this.children?.forEach((e) => {
|
||||
e.updateExpanded(this.dataValue);
|
||||
});
|
||||
},
|
||||
switch(panelValue) {
|
||||
const { expandMutex, dataValue: activeValues } = this;
|
||||
|
||||
let value = [];
|
||||
const hit = activeValues?.indexOf(panelValue);
|
||||
|
||||
if (hit > -1) {
|
||||
value = activeValues.filter(item => item !== panelValue);
|
||||
} else {
|
||||
value = expandMutex ? [panelValue] : activeValues.concat(panelValue);
|
||||
}
|
||||
|
||||
this._trigger('change', { value });
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style scoped>
|
||||
@import './collapse.css';
|
||||
</style>
|
||||
42
uni_modules/tdesign-uniapp/components/collapse/props.ts
Normal file
42
uni_modules/tdesign-uniapp/components/collapse/props.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
|
||||
* */
|
||||
|
||||
import type { TdCollapseProps } from './type';
|
||||
export default {
|
||||
/** 默认是否展开全部 */
|
||||
defaultExpandAll: Boolean,
|
||||
/** 是否禁用面板展开/收起操作 */
|
||||
disabled: Boolean,
|
||||
/** 展开图标 */
|
||||
expandIcon: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
/** 每个面板互斥展开,每次只展开一个面板 */
|
||||
expandMutex: Boolean,
|
||||
/** 折叠面板风格 */
|
||||
theme: {
|
||||
type: String,
|
||||
default: 'default' as TdCollapseProps['theme'],
|
||||
validator(val: TdCollapseProps['theme']): boolean {
|
||||
if (!val) return true;
|
||||
return ['default', 'card'].includes(val);
|
||||
},
|
||||
},
|
||||
/** 展开的面板集合 */
|
||||
value: {
|
||||
type: Array,
|
||||
},
|
||||
/** 展开的面板集合,非受控属性 */
|
||||
defaultValue: {
|
||||
type: Array,
|
||||
},
|
||||
/** 切换面板时触发,返回变化的值 */
|
||||
onChange: {
|
||||
type: Function,
|
||||
default: () => ({}),
|
||||
},
|
||||
};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user