@tdesign/uniapp 0.7.3 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (197) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +1 -1
  3. package/dist/action-sheet/README.md +1 -1
  4. package/dist/action-sheet/action-sheet.vue +158 -150
  5. package/dist/action-sheet/props.ts +2 -2
  6. package/dist/action-sheet/type.ts +1 -1
  7. package/dist/avatar/avatar.vue +89 -87
  8. package/dist/avatar-group/avatar-group.vue +69 -67
  9. package/dist/back-top/back-top.vue +60 -58
  10. package/dist/badge/badge.vue +69 -59
  11. package/dist/button/button.vue +121 -116
  12. package/dist/button/props.ts +2 -2
  13. package/dist/button/type.ts +1 -1
  14. package/dist/calendar/calendar-header.vue +4 -4
  15. package/dist/calendar/calendar.vue +308 -297
  16. package/dist/calendar/template.vue +1 -1
  17. package/dist/cascader/README.en-US.md +2 -1
  18. package/dist/cascader/README.md +2 -1
  19. package/dist/cascader/cascader.vue +340 -328
  20. package/dist/cascader/props.ts +6 -1
  21. package/dist/cascader/type.ts +6 -0
  22. package/dist/cell/cell.vue +127 -121
  23. package/dist/cell-group/cell-group.vue +32 -30
  24. package/dist/check-tag/check-tag.vue +73 -71
  25. package/dist/checkbox/checkbox.vue +127 -127
  26. package/dist/checkbox/props.ts +6 -6
  27. package/dist/checkbox/type.ts +3 -3
  28. package/dist/checkbox-group/checkbox-group.vue +175 -173
  29. package/dist/checkbox-group/props.ts +6 -6
  30. package/dist/checkbox-group/type.ts +4 -4
  31. package/dist/col/col.vue +26 -24
  32. package/dist/collapse/collapse.vue +83 -81
  33. package/dist/collapse-panel/collapse-panel.vue +121 -119
  34. package/dist/collapse-panel/props.ts +4 -4
  35. package/dist/collapse-panel/type.ts +2 -2
  36. package/dist/color-picker/README.md +1 -1
  37. package/dist/color-picker/color-picker.vue +324 -322
  38. package/dist/color-picker/props.ts +2 -2
  39. package/dist/color-picker/template.vue +14 -10
  40. package/dist/common/common.ts +1 -0
  41. package/dist/common/style/theme/index.css +5 -5
  42. package/dist/common/utils.js +7 -2
  43. package/dist/common/validator.js +172 -0
  44. package/dist/config-provider/README.en-US.md +184 -0
  45. package/dist/config-provider/README.md +234 -0
  46. package/dist/config-provider/config-provider.vue +105 -0
  47. package/dist/config-provider/config-store.js +70 -0
  48. package/dist/config-provider/props.ts +16 -0
  49. package/dist/config-provider/reactive-state.js +39 -0
  50. package/dist/config-provider/type.ts +401 -0
  51. package/dist/config-provider/use-config.js +29 -0
  52. package/dist/config-provider/utils.js +29 -0
  53. package/dist/count-down/count-down.vue +98 -97
  54. package/dist/date-time-picker/date-time-picker.vue +410 -395
  55. package/dist/demo/demo.vue +1 -0
  56. package/dist/dialog/dialog.vue +175 -173
  57. package/dist/divider/divider.vue +38 -36
  58. package/dist/draggable/draggable.vue +60 -58
  59. package/dist/drawer/README.md +1 -1
  60. package/dist/drawer/drawer.vue +48 -46
  61. package/dist/dropdown-item/dropdown-item.vue +209 -207
  62. package/dist/dropdown-item/props.ts +4 -4
  63. package/dist/dropdown-item/type.ts +3 -3
  64. package/dist/dropdown-menu/dropdown-menu.vue +93 -99
  65. package/dist/empty/empty.vue +43 -42
  66. package/dist/fab/fab.vue +88 -86
  67. package/dist/footer/footer.vue +36 -34
  68. package/dist/form/README.en-US.md +17 -24
  69. package/dist/form/README.md +18 -25
  70. package/dist/form/form.css +1 -166
  71. package/dist/form/form.vue +251 -236
  72. package/dist/form/props.ts +2 -21
  73. package/dist/form/type.ts +7 -70
  74. package/dist/form-item/README.en-US.md +4 -5
  75. package/dist/form-item/README.md +4 -5
  76. package/dist/form-item/form-item.css +69 -96
  77. package/dist/form-item/form-item.vue +315 -336
  78. package/dist/form-item/form-model.ts +125 -173
  79. package/dist/form-item/props.ts +4 -17
  80. package/dist/form-item/type.ts +43 -1
  81. package/dist/grid/grid.vue +53 -51
  82. package/dist/grid-item/grid-item.vue +121 -119
  83. package/dist/guide/README.md +1 -1
  84. package/dist/guide/guide.vue +281 -277
  85. package/dist/icon/README.md +2 -4
  86. package/dist/icon/icon.vue +78 -76
  87. package/dist/image/README.md +1 -1
  88. package/dist/image/image.vue +103 -101
  89. package/dist/image-viewer/image-viewer.vue +160 -158
  90. package/dist/image-viewer/props.ts +2 -2
  91. package/dist/image-viewer/type.ts +1 -1
  92. package/dist/index.js +3 -0
  93. package/dist/indexes/indexes.vue +264 -267
  94. package/dist/indexes-anchor/indexes-anchor.vue +41 -41
  95. package/dist/input/input.vue +192 -192
  96. package/dist/input/props.ts +6 -6
  97. package/dist/input/type.ts +3 -3
  98. package/dist/link/link.vue +73 -71
  99. package/dist/loading/loading.vue +59 -59
  100. package/dist/locale/ar_KW.ts +157 -0
  101. package/dist/locale/en_US.ts +146 -0
  102. package/dist/locale/it_IT.ts +145 -0
  103. package/dist/locale/ja_JP.ts +132 -0
  104. package/dist/locale/ko_KR.ts +132 -0
  105. package/dist/locale/ru_RU.ts +157 -0
  106. package/dist/locale/zh_CN.ts +133 -0
  107. package/dist/locale/zh_TW.ts +132 -0
  108. package/dist/message/message.vue +181 -173
  109. package/dist/message/props.ts +2 -2
  110. package/dist/message/type.ts +1 -1
  111. package/dist/message-item/message-item.vue +192 -184
  112. package/dist/mixins/using-config.js +39 -0
  113. package/dist/navbar/navbar.vue +201 -199
  114. package/dist/notice-bar/notice-bar.vue +175 -171
  115. package/dist/notice-bar/props.ts +2 -2
  116. package/dist/notice-bar/type.ts +1 -1
  117. package/dist/npm/dayjs/esm/locale/ar.js +81 -0
  118. package/dist/npm/dayjs/esm/locale/it.js +39 -0
  119. package/dist/overlay/overlay.vue +50 -48
  120. package/dist/picker/picker.vue +168 -161
  121. package/dist/picker-item/picker-item.vue +269 -269
  122. package/dist/popover/README.md +1 -1
  123. package/dist/popover/popover.vue +262 -261
  124. package/dist/popover/props.ts +4 -4
  125. package/dist/popover/type.ts +2 -2
  126. package/dist/popup/popup.vue +46 -45
  127. package/dist/progress/README.md +1 -1
  128. package/dist/progress/progress.vue +76 -76
  129. package/dist/pull-down-refresh/props.ts +2 -2
  130. package/dist/pull-down-refresh/pull-down-refresh.vue +240 -234
  131. package/dist/pull-down-refresh/type.ts +1 -1
  132. package/dist/qrcode/README.md +1 -1
  133. package/dist/qrcode/components/qrcode-canvas/qrcode-canvas.vue +340 -338
  134. package/dist/qrcode/components/qrcode-status/qrcode-status.vue +6 -6
  135. package/dist/qrcode/qrcode.vue +93 -87
  136. package/dist/radio/props.ts +6 -6
  137. package/dist/radio/radio.vue +118 -120
  138. package/dist/radio/type.ts +3 -3
  139. package/dist/radio-group/props.ts +4 -4
  140. package/dist/radio-group/radio-group.vue +136 -134
  141. package/dist/radio-group/type.ts +4 -4
  142. package/dist/rate/computed.js +2 -2
  143. package/dist/rate/props.ts +4 -4
  144. package/dist/rate/rate.vue +155 -154
  145. package/dist/rate/type.ts +2 -2
  146. package/dist/result/result.vue +41 -39
  147. package/dist/row/row.vue +38 -36
  148. package/dist/scroll-view/scroll-view.vue +24 -22
  149. package/dist/search/props.ts +2 -2
  150. package/dist/search/search.vue +127 -125
  151. package/dist/search/type.ts +1 -1
  152. package/dist/side-bar/side-bar.vue +57 -55
  153. package/dist/side-bar-item/side-bar-item.vue +86 -86
  154. package/dist/skeleton/skeleton.vue +126 -124
  155. package/dist/slider/README.md +1 -1
  156. package/dist/slider/props.ts +2 -2
  157. package/dist/slider/slider.vue +457 -457
  158. package/dist/slider/type.ts +1 -1
  159. package/dist/step-item/step-item.vue +77 -75
  160. package/dist/stepper/props.ts +2 -2
  161. package/dist/stepper/stepper.vue +168 -149
  162. package/dist/stepper/type.ts +1 -1
  163. package/dist/steps/props.ts +2 -2
  164. package/dist/steps/steps.vue +83 -81
  165. package/dist/steps/type.ts +1 -1
  166. package/dist/sticky/sticky.vue +104 -102
  167. package/dist/swipe-cell/swipe-cell.vue +91 -89
  168. package/dist/swiper/README.md +1 -1
  169. package/dist/swiper/swiper.vue +91 -89
  170. package/dist/swiper-nav/swiper-nav.vue +38 -36
  171. package/dist/switch/props.ts +2 -2
  172. package/dist/switch/switch.vue +62 -62
  173. package/dist/switch/type.ts +1 -1
  174. package/dist/tab-bar/tab-bar.vue +88 -86
  175. package/dist/tab-bar-item/tab-bar-item.vue +85 -82
  176. package/dist/tab-panel/tab-panel.vue +66 -64
  177. package/dist/tabs/tabs.vue +294 -287
  178. package/dist/tag/tag.vue +79 -77
  179. package/dist/textarea/props.ts +6 -6
  180. package/dist/textarea/textarea.vue +127 -126
  181. package/dist/textarea/type.ts +3 -3
  182. package/dist/toast/toast.vue +107 -106
  183. package/dist/transition/transition.vue +30 -28
  184. package/dist/tree-select/tree-select.vue +151 -151
  185. package/dist/types/config-provider.d.ts +7 -0
  186. package/dist/types/index.d.ts +2 -0
  187. package/dist/types/popover.d.ts +7 -0
  188. package/dist/upload/README.en-US.md +13 -14
  189. package/dist/upload/README.md +11 -12
  190. package/dist/upload/props.ts +2 -4
  191. package/dist/upload/type.ts +12 -11
  192. package/dist/upload/upload.css +1 -1
  193. package/dist/upload/upload.vue +672 -512
  194. package/dist/watermark/watermark.vue +151 -149
  195. package/global.d.ts +2 -0
  196. package/package.json +15 -3
  197. package/dist/form/form-item-props.ts +0 -56
@@ -8,12 +8,12 @@
8
8
  <template v-else>
9
9
  <view
10
10
  v-if="status === 'expired'"
11
- :class="`${prefix}-expired`"
11
+ :class="'' + `${prefix}-expired`"
12
12
  >
13
- <view :class="`${prefix}-expired__text`">
13
+ <view :class="'' + `${prefix}-expired__text`">
14
14
  {{ locale.expiredText }}
15
15
  <view
16
- :class="`${prefix}-expired__button`"
16
+ :class="'' + `${prefix}-expired__button`"
17
17
  @click="handleRefresh"
18
18
  >
19
19
  <t-icon
@@ -27,7 +27,7 @@
27
27
 
28
28
  <view
29
29
  v-else-if="status === 'loading'"
30
- :class="`${prefix}-loading-container`"
30
+ :class="'' + `${prefix}-loading-container`"
31
31
  >
32
32
  <t-loading
33
33
  size="64rpx"
@@ -37,11 +37,11 @@
37
37
 
38
38
  <view
39
39
  v-else-if="status === 'scanned'"
40
- :class="`${prefix}-scanned`"
40
+ :class="'' + `${prefix}-scanned`"
41
41
  >
42
42
  <t-icon
43
43
  name="check-circle-filled"
44
- :class="`${prefix}-scanned__icon`"
44
+ :class="'' + `${prefix}-scanned__icon`"
45
45
  size="44rpx"
46
46
  />
47
47
  {{ locale.scannedText }}
@@ -1,9 +1,9 @@
1
1
  <template>
2
2
  <view
3
- :style="`${tools._style([customStyle])}; width:${containerSize}px; height: ${containerSize}px; background-color: ${bgColor};`"
4
- :class="`${classPrefix} ${borderless ? prefix + '-' + 'borderless' : ''} ${tClass}`"
3
+ :style="'' + `${tools._style([customStyle])}; width:${containerSize}px; height: ${containerSize}px; background-color: ${bgColor};`"
4
+ :class="''+`${classPrefix} ${borderless ? prefix + '-' + 'borderless' : ''} ${tClass}`"
5
5
  >
6
- <QrcodeCanvas
6
+ <qrcode-canvas
7
7
  ref="qrcodeCanvas"
8
8
  :t-class="tClassCanvas"
9
9
  :size="size"
@@ -19,17 +19,18 @@
19
19
 
20
20
  <view
21
21
  v-if="showMask && canvasReady"
22
- :class="`${prefix}-mask`"
22
+ :class="'' + `${prefix}-mask`"
23
23
  >
24
- <QrcodeStatus
24
+ <qrcode-status
25
25
  :status="status"
26
26
  :status-render="statusRender"
27
+ :locale="globalConfig"
27
28
  @refresh="handleRefresh"
28
29
  >
29
30
  <template #statusRender>
30
31
  <slot name="statusRender" />
31
32
  </template>
32
- </QrcodeStatus>
33
+ </qrcode-status>
33
34
  </view>
34
35
  </view>
35
36
  </template>
@@ -42,101 +43,106 @@ import props from './props';
42
43
  import { uniComponent } from '../common/src/index';
43
44
  import tools from '../common/utils.wxs';
44
45
 
45
- const name = `${prefix}-qrcode`;
46
+ import usingConfig from '../mixins/using-config';
47
+ const componentName = 'qrcode';
48
+ const name = `${prefix}-${componentName}`;
46
49
 
47
- export default uniComponent({
48
- name,
49
- options: {
50
- styleIsolation: 'shared',
51
- },
52
- externalClasses: [
53
- `${prefix}-class`,
54
- `${prefix}-class-canvas`,
55
- ],
50
+ export default {
56
51
  components: {
57
52
  QrcodeCanvas,
58
53
  QrcodeStatus,
59
54
  },
60
- props: {
61
- ...props,
62
- },
63
- data() {
64
- return {
65
- prefix,
66
- tools,
67
- showMask: false,
68
- classPrefix: name,
69
- canvasReady: false,
70
- canvasNode: null,
71
- };
72
- },
73
- computed: {
74
- // 容器尺寸 = Canvas 尺寸 + padding * 2
55
+ ...uniComponent({
56
+ name,
57
+ mixins: [usingConfig({ componentName })],
58
+ options: {
59
+ styleIsolation: 'shared',
60
+ },
61
+ externalClasses: [
62
+ `${prefix}-class`,
63
+ `${prefix}-class-canvas`,
64
+ ],
65
+ props: {
66
+ ...props,
67
+ },
68
+ data() {
69
+ return {
70
+ prefix,
71
+ tools,
72
+ showMask: false,
73
+ classPrefix: name,
74
+ canvasReady: false,
75
+ canvasNode: null,
76
+ };
77
+ },
78
+ computed: {
79
+ // 容器尺寸 = Canvas 尺寸 + padding * 2
75
80
  // padding 为 12px,所以容器需要额外 24px
76
- containerSize() {
77
- return this.size + 24;
81
+ containerSize() {
82
+ return this.size + 24;
83
+ },
78
84
  },
79
- },
80
- watch: {
81
- status: {
82
- handler(newVal) {
83
- this.showMask = newVal !== 'active';
85
+ watch: {
86
+ status: {
87
+ handler(newVal) {
88
+ this.showMask = newVal !== 'active';
89
+ },
90
+ immediate: true,
84
91
  },
85
- immediate: true,
86
92
  },
87
- },
88
- mounted() {
89
- this.initCanvas();
90
- },
91
- methods: {
92
- async initCanvas() {
93
- // 获取 canvas 实例
94
- const canvasComp = this.$refs.qrcodeCanvas;
95
- if (canvasComp) {
96
- const canvas = await canvasComp.getCanvasNode();
97
- this.canvasNode = canvas;
98
- }
93
+ mounted() {
94
+ this.initCanvas();
99
95
  },
96
+ methods: {
97
+ async initCanvas() {
98
+ // 获取 canvas 实例
99
+ const canvasComp = this.$refs.qrcodeCanvas;
100
+ if (canvasComp) {
101
+ const canvas = await canvasComp.getCanvasNode();
102
+ this.canvasNode = canvas;
103
+ }
104
+ },
100
105
 
101
- // 用于外部调用,重新绘制二维码
102
- init() {
103
- const canvasComp = this.$refs.qrcodeCanvas;
104
- if (canvasComp) {
105
- canvasComp.initCanvas();
106
- }
107
- },
106
+ // 用于外部调用,重新绘制二维码
107
+ init() {
108
+ const canvasComp = this.$refs.qrcodeCanvas;
109
+ if (canvasComp) {
110
+ canvasComp.initCanvas();
111
+ }
112
+ },
108
113
 
109
- handleDrawCompleted() {
110
- this.canvasReady = true;
111
- },
112
- handleDrawError(err) {
113
- console.error('二维码绘制失败', err);
114
- },
115
- handleRefresh() {
116
- this.$emit('refresh');
117
- },
118
- // 二维码下载方法
119
- async handleDownload() {
120
- if (!this.canvasNode) {
121
- console.error('未找到 canvas 节点');
122
- return;
123
- }
114
+ handleDrawCompleted() {
115
+ this.canvasReady = true;
116
+ },
117
+ handleDrawError(err) {
118
+ console.error('二维码绘制失败', err);
119
+ },
120
+ handleRefresh() {
121
+ this.$emit('refresh');
122
+ },
123
+ // 二维码下载方法
124
+ async handleDownload() {
125
+ if (!this.canvasNode) {
126
+ console.error('未找到 canvas 节点');
127
+ return;
128
+ }
124
129
 
125
- // 注意:此方法在非小程序环境需要适配
126
- if (typeof wx !== 'undefined' && uni.canvasToTempFilePath) {
127
- uni.canvasToTempFilePath({
128
- canvas: this.canvasNode,
129
- success: (res) => {
130
- uni.saveImageToPhotosAlbum({ filePath: res.tempFilePath });
131
- },
132
- fail: (err) => {
133
- console.error('canvasToTempFilePath failed', err);
134
- },
135
- });
136
- }
130
+ // 注意:此方法在非小程序环境需要适配
131
+ if (typeof wx !== 'undefined' && uni.canvasToTempFilePath) {
132
+ uni.canvasToTempFilePath({
133
+ canvas: this.canvasNode,
134
+ success: (res) => {
135
+ uni.saveImageToPhotosAlbum({ filePath: res.tempFilePath });
136
+ },
137
+ fail: (err) => {
138
+ console.error('canvasToTempFilePath failed', err);
139
+ },
140
+ });
141
+ }
142
+ },
137
143
  },
138
- },
139
- });
144
+ }),
145
+ };
140
146
  </script>
141
147
 
142
148
  <style scoped src="./qrcode.css"></style>
@@ -15,8 +15,8 @@ export default {
15
15
  },
16
16
  /** 是否选中 */
17
17
  checked: {
18
- type: Boolean,
19
- default: undefined,
18
+ type: [Boolean, null],
19
+ default: null as TdRadioProps['checked'],
20
20
  },
21
21
  /** 是否选中,非受控属性 */
22
22
  defaultChecked: Boolean,
@@ -28,8 +28,8 @@ export default {
28
28
  contentDisabled: Boolean,
29
29
  /** 是否为禁用态 */
30
30
  disabled: {
31
- type: Boolean,
32
- default: undefined,
31
+ type: [Boolean, null],
32
+ default: null as TdRadioProps['disabled'],
33
33
  },
34
34
  /** 自定义选中图标和非选中图标。使用 Array 时表示:`[选中态图标,非选中态图标]`。使用 String 时,值为 circle 表示填充型图标、值为 line 表示描边型图标、值为 dot 表示圆点图标,值为 slot 时使用插槽 */
35
35
  icon: {
@@ -65,8 +65,8 @@ export default {
65
65
  },
66
66
  /** 只读状态 */
67
67
  readonly: {
68
- type: Boolean,
69
- default: undefined,
68
+ type: [Boolean, null],
69
+ default: null as TdRadioProps['readonly'],
70
70
  },
71
71
  /** -1 时代表独立,不再寻找 parent,用于头条小程序 */
72
72
  relationKey: {
@@ -1,8 +1,8 @@
1
1
  <template>
2
2
  <view
3
3
  :id="tId"
4
- :style="tools._style([customStyle])"
5
- :class="tools.cls(classPrefix, [innerPlacement, ['block', block], ['disabled', iDisabled]]) + ' ' + tClass"
4
+ :style="'' + tools._style([customStyle])"
5
+ :class="'' + tools.cls(classPrefix, [innerPlacement, ['block', block], ['disabled', iDisabled]]) + ' ' + tClass"
6
6
  :disabled="iDisabled"
7
7
  aria-role="radio"
8
8
  :aria-checked="dataChecked"
@@ -10,7 +10,7 @@
10
10
  :aria-disabled="iDisabled"
11
11
  @click.stop="handleTap"
12
12
  >
13
- <view :class="tools.cls(classPrefix + '__icon', [innerPlacement, ['checked', dataChecked], ['disabled', iDisabled]]) + ' ' + tClassIcon">
13
+ <view :class="'' + tools.cls(classPrefix + '__icon', [innerPlacement, ['checked', dataChecked], ['disabled', iDisabled]]) + ' ' + tClassIcon">
14
14
  <slot
15
15
  v-if="slotIcon"
16
16
  name="icon"
@@ -33,11 +33,11 @@
33
33
  />
34
34
  <view
35
35
  v-if="dataChecked && icon == 'dot'"
36
- :class="tools.cls(classPrefix + '__icon-' + icon, [['disabled', iDisabled]])"
36
+ :class="'' + tools.cls(classPrefix + '__icon-' + icon, [['disabled', iDisabled]])"
37
37
  />
38
38
  <view
39
39
  v-if="!dataChecked && (icon == 'circle' || icon == 'dot')"
40
- :class="tools.cls(classPrefix + '__icon-circle', [['disabled', iDisabled]])"
40
+ :class="'' + tools.cls(classPrefix + '__icon-circle', [['disabled', iDisabled]])"
41
41
  />
42
42
  <view
43
43
  v-if="!dataChecked && icon == 'line'"
@@ -51,14 +51,12 @@
51
51
  @click.stop="handleTap"
52
52
  >
53
53
  <view
54
- :class="
55
- tools.cls(classPrefix + '__title', [
56
- ['disabled', iDisabled],
57
- ['checked', dataChecked]
58
- ]) +
59
- ' ' +
60
- tClassLabel
61
- "
54
+ :class="'' + tools.cls(classPrefix + '__title', [
55
+ ['disabled', iDisabled],
56
+ ['checked', dataChecked]
57
+ ]) +
58
+ ' ' +
59
+ tClassLabel"
62
60
  :style="'-webkit-line-clamp:' + maxLabelRow"
63
61
  >
64
62
  <block v-if="label">
@@ -68,14 +66,12 @@
68
66
  <slot name="label" />
69
67
  </view>
70
68
  <view
71
- :class="
72
- tools.cls(classPrefix + '__description', [
73
- ['disabled', iDisabled],
74
- ['checked', dataChecked]
75
- ]) +
76
- ' ' +
77
- tClassContent
78
- "
69
+ :class="'' + tools.cls(classPrefix + '__description', [
70
+ ['disabled', iDisabled],
71
+ ['checked', dataChecked]
72
+ ]) +
73
+ ' ' +
74
+ tClassContent"
79
75
  :style="'-webkit-line-clamp:' + maxContentRow"
80
76
  >
81
77
  <block v-if="content">
@@ -86,7 +82,7 @@
86
82
  </view>
87
83
  <view
88
84
  v-if="!borderless"
89
- :class="tools.cls(classPrefix + '__border', [innerPlacement]) + ' ' + tClassBorder"
85
+ :class="'' + tools.cls(classPrefix + '__border', [innerPlacement]) + ' ' + tClassBorder"
90
86
  />
91
87
  </view>
92
88
  </template>
@@ -102,124 +98,126 @@ import { ChildrenMixin, RELATION_MAP } from '../common/relation';
102
98
 
103
99
  const name = `${prefix}-radio`;
104
100
 
105
- export default uniComponent({
106
- name,
107
- options: {
108
- styleIsolation: 'shared',
109
- },
110
- controlledProps: [
111
- {
112
- key: 'checked',
113
- event: 'change',
114
- },
115
- ],
116
- externalClasses: [
117
- `${prefix}-class`,
118
- `${prefix}-class-label`,
119
- `${prefix}-class-icon`,
120
- `${prefix}-class-content`,
121
- `${prefix}-class-border`,
122
- ],
123
- mixins: [ChildrenMixin(RELATION_MAP.Radio)],
101
+ export default {
124
102
  components: {
125
103
  TIcon,
126
104
  },
127
- props: {
128
- ...props,
129
- borderless: {
130
- type: Boolean,
131
- default: false,
105
+ ...uniComponent({
106
+ name,
107
+ options: {
108
+ styleIsolation: 'shared',
132
109
  },
133
- tId: {
134
- type: String,
110
+ controlledProps: [
111
+ {
112
+ key: 'checked',
113
+ event: 'change',
114
+ },
115
+ ],
116
+ externalClasses: [
117
+ `${prefix}-class`,
118
+ `${prefix}-class-label`,
119
+ `${prefix}-class-icon`,
120
+ `${prefix}-class-content`,
121
+ `${prefix}-class-border`,
122
+ ],
123
+ mixins: [ChildrenMixin(RELATION_MAP.Radio)],
124
+ props: {
125
+ ...props,
126
+ borderless: {
127
+ type: Boolean,
128
+ default: false,
129
+ },
130
+ tId: {
131
+ type: String,
132
+ },
135
133
  },
136
- },
137
- data() {
138
- return {
139
- prefix,
140
- classPrefix: name,
141
- customIcon: false,
142
- slotIcon: false,
143
- optionLinked: false,
144
- iconVal: [],
145
- innerPlacement: '',
146
- iDisabled: false,
147
- iReadonly: false,
148
- tools,
134
+ data() {
135
+ return {
136
+ prefix,
137
+ classPrefix: name,
138
+ customIcon: false,
139
+ slotIcon: false,
140
+ optionLinked: false,
141
+ iconVal: [],
142
+ innerPlacement: '',
143
+ iDisabled: false,
144
+ iReadonly: false,
145
+ tools,
149
146
 
150
- dataChecked: coalesce(this.checked, this.defaultChecked),
151
- };
152
- },
153
- computed: {
154
- isIsolated() {
155
- return this.relationKey === ISOLATED_RELATION_KEY;
147
+ dataChecked: coalesce(this.checked, this.defaultChecked),
148
+ };
156
149
  },
157
- },
158
- watch: {
159
- checked: {
160
- handler(v) {
161
- this.dataChecked = v;
150
+ computed: {
151
+ isIsolated() {
152
+ return this.relationKey === ISOLATED_RELATION_KEY;
162
153
  },
163
- immediate: true,
164
154
  },
165
- disabled: {
166
- handler(v) {
167
- this.iDisabled = v;
155
+ watch: {
156
+ checked: {
157
+ handler(v) {
158
+ this.dataChecked = v;
159
+ },
160
+ immediate: true,
168
161
  },
169
- immediate: true,
170
- },
171
- readonly: {
172
- handler(v) {
173
- this.iReadonly = v;
162
+ disabled: {
163
+ handler(v) {
164
+ this.iDisabled = v;
165
+ },
166
+ immediate: true,
167
+ },
168
+ readonly: {
169
+ handler(v) {
170
+ this.iReadonly = v;
171
+ },
172
+ immediate: true,
174
173
  },
175
- immediate: true,
176
174
  },
177
- },
178
- mounted() {
179
- this.init();
180
- },
181
- methods: {
182
- handleTap(e) {
183
- const { iDisabled, iReadonly, contentDisabled } = this;
184
- const { target } = e.currentTarget.dataset;
175
+ mounted() {
176
+ this.init();
177
+ },
178
+ methods: {
179
+ handleTap(e) {
180
+ const { iDisabled, iReadonly, contentDisabled } = this;
181
+ const { target } = e.currentTarget.dataset;
185
182
 
186
- if (iDisabled || iReadonly || (target === 'text' && contentDisabled)) return;
183
+ if (iDisabled || iReadonly || (target === 'text' && contentDisabled)) return;
187
184
 
188
- this.doChange();
189
- },
190
- doChange() {
191
- const { value, dataChecked, allowUncheck } = this;
192
- const parent = this.isIsolated ? null : this[RELATION_MAP.Radio];
185
+ this.doChange();
186
+ },
187
+ doChange() {
188
+ const { value, dataChecked, allowUncheck } = this;
189
+ const parent = this.isIsolated ? null : this[RELATION_MAP.Radio];
193
190
 
194
- const isAllowUncheck = Boolean(allowUncheck || parent?.allowUncheck);
191
+ const isAllowUncheck = Boolean(allowUncheck || parent?.allowUncheck);
195
192
 
196
- if (parent) {
197
- this[RELATION_MAP.Radio].updateValue(dataChecked && isAllowUncheck ? null : value);
198
- } else {
199
- this._trigger('change', { checked: isAllowUncheck ? !dataChecked : true });
200
- }
201
- },
202
- init() {
203
- const { icon } = this;
204
- const parent = this.isIsolated ? null : this[RELATION_MAP.Radio];
205
- const isIdArr = Array.isArray(parent?.icon || icon);
193
+ if (parent) {
194
+ this[RELATION_MAP.Radio].updateValue(dataChecked && isAllowUncheck ? null : value);
195
+ } else {
196
+ this._trigger('change', { checked: isAllowUncheck ? !dataChecked : true });
197
+ }
198
+ },
199
+ init() {
200
+ const { icon } = this;
201
+ const parent = this.isIsolated ? null : this[RELATION_MAP.Radio];
202
+ const isIdArr = Array.isArray(parent?.icon || icon);
206
203
 
207
- this.customIcon = isIdArr;
208
- this.slotIcon = icon === 'slot';
209
- this.iconVal = isIdArr ? parent?.icon || icon : [];
210
- this.innerPlacement = this.placement || parent?.placement || 'left';
211
- },
204
+ this.customIcon = isIdArr;
205
+ this.slotIcon = icon === 'slot';
206
+ this.iconVal = isIdArr ? parent?.icon || icon : [];
207
+ this.innerPlacement = this.placement || parent?.placement || 'left';
208
+ },
212
209
 
213
- setDisabled(disabled) {
214
- if (this.isIsolated) return;
210
+ setDisabled(disabled) {
211
+ if (this.isIsolated) return;
215
212
 
216
- this.iDisabled = this.disabled || disabled;
217
- },
213
+ this.iDisabled = this.disabled || disabled;
214
+ },
218
215
 
219
- setReadonly(readonly) {
220
- this.iReadonly = this.readonly || readonly;
216
+ setReadonly(readonly) {
217
+ this.iReadonly = this.readonly || readonly;
218
+ },
221
219
  },
222
- },
223
- });
220
+ }),
221
+ };
224
222
  </script>
225
223
  <style scoped src="./radio.css"></style>
@@ -19,7 +19,7 @@ export interface TdRadioProps<T = RadioValue> {
19
19
  * 是否选中
20
20
  * @default false
21
21
  */
22
- checked?: boolean;
22
+ checked?: boolean | null;
23
23
  /**
24
24
  * 是否选中,非受控属性
25
25
  * @default false
@@ -37,7 +37,7 @@ export interface TdRadioProps<T = RadioValue> {
37
37
  /**
38
38
  * 是否为禁用态
39
39
  */
40
- disabled?: boolean;
40
+ disabled?: boolean | null;
41
41
  /**
42
42
  * 自定义选中图标和非选中图标。使用 Array 时表示:`[选中态图标,非选中态图标]`。使用 String 时,值为 circle 表示填充型图标、值为 line 表示描边型图标、值为 dot 表示圆点图标,值为 slot 时使用插槽
43
43
  * @default 'circle'
@@ -69,7 +69,7 @@ export interface TdRadioProps<T = RadioValue> {
69
69
  /**
70
70
  * 只读状态
71
71
  */
72
- readonly?: boolean;
72
+ readonly?: boolean | null;
73
73
  /**
74
74
  * -1 时代表独立,不再寻找 parent,用于头条小程序
75
75
  * @default ''
@@ -12,8 +12,8 @@ export default {
12
12
  borderless: Boolean,
13
13
  /** 是否禁用全部子单选框 */
14
14
  disabled: {
15
- type: Boolean,
16
- default: undefined,
15
+ type: [Boolean, null],
16
+ default: null as TdRadioGroupProps['disabled'],
17
17
  },
18
18
  /** 自定义选中图标和非选中图标。示例:[选中态图标,非选中态图标]。使用 String 时,值为 circle 表示填充型图标、值为 line 表示描边型图标、值为 dot 表示圆点图标;仅在使用 options 时生效 */
19
19
  icon: {
@@ -44,8 +44,8 @@ export default {
44
44
  },
45
45
  /** 只读状态 */
46
46
  readonly: {
47
- type: Boolean,
48
- default: undefined,
47
+ type: [Boolean, null],
48
+ default: null as TdRadioGroupProps['readonly'],
49
49
  },
50
50
  /** -1 时代表独立,不再寻找 parent,用于头条小程序 */
51
51
  relationKey: {