@ecolovo/uniapp-components 1.0.9 → 2.0.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 (117) hide show
  1. package/README.md +83 -51
  2. package/components/aspect/aspect.vue +24 -15
  3. package/components/badge/badge.scss +20 -0
  4. package/components/badge/badge.vue +49 -40
  5. package/components/button/button.scss +15 -0
  6. package/components/button/button.vue +125 -181
  7. package/components/checkbox/checkbox.scss +10 -0
  8. package/components/checkbox/checkbox.vue +118 -146
  9. package/components/checkbox-group/checkbox-group.vue +79 -81
  10. package/components/checkbox-group2/checkbox-group2.vue +111 -107
  11. package/components/checkbox-group2/checkbox2.vue +104 -0
  12. package/components/data-list/data-list.scss +9 -0
  13. package/components/data-list/data-list.vue +70 -79
  14. package/components/date-picker/date-picker-view.vue +125 -124
  15. package/components/date-picker/date-picker.vue +145 -146
  16. package/components/dialog/dialog-content.vue +39 -47
  17. package/components/dialog/dialog.scss +11 -0
  18. package/components/dialog/dialog.vue +125 -138
  19. package/components/dropdown/dropdown.scss +11 -0
  20. package/components/dropdown/dropdown.vue +55 -97
  21. package/components/empty/empty.scss +14 -0
  22. package/components/empty/empty.vue +42 -41
  23. package/components/flex/flex.vue +45 -54
  24. package/components/form/form.vue +29 -24
  25. package/components/form-item/form-item.scss +11 -0
  26. package/components/form-item/form-item.vue +43 -40
  27. package/components/icon/icon.vue +70 -85
  28. package/components/image/image.vue +35 -38
  29. package/components/input/input.vue +65 -79
  30. package/components/input/password-input.vue +34 -42
  31. package/components/list-page/list-page.vue +73 -99
  32. package/components/load-more/load-more.scss +12 -0
  33. package/components/load-more/load-more.vue +29 -29
  34. package/components/loading/animations/loading-animation1.vue +8 -8
  35. package/components/loading/animations/loading-animation2.vue +8 -9
  36. package/components/loading/animations/loading-animation3.vue +11 -11
  37. package/components/loading/animations/loading-animation4.vue +8 -8
  38. package/components/loading/loading.vue +19 -20
  39. package/components/message-box/message-box.vue +59 -41
  40. package/components/number-dialog/number-dialog.scss +9 -0
  41. package/components/number-dialog/number-dialog.vue +209 -204
  42. package/components/number-input/number-input.scss +9 -0
  43. package/components/number-input/number-input.vue +233 -232
  44. package/components/numpad/numpad.scss +9 -0
  45. package/components/numpad/numpad.vue +133 -150
  46. package/components/page/page-body.scss +15 -0
  47. package/components/page/page-body.vue +137 -119
  48. package/components/page/page-footer.scss +13 -0
  49. package/components/page/page-footer.vue +31 -33
  50. package/components/page/page-header.scss +17 -0
  51. package/components/page/page-header.vue +89 -94
  52. package/components/page/page.scss +9 -0
  53. package/components/page/page.vue +105 -81
  54. package/components/picker/picker-popup.vue +218 -209
  55. package/components/picker/picker.vue +99 -104
  56. package/components/popover/popover-content.vue +54 -63
  57. package/components/popover/popover-mask.vue +63 -63
  58. package/components/popover/popover.scss +28 -0
  59. package/components/popover/popover.vue +49 -47
  60. package/components/popup/popup-content.vue +49 -53
  61. package/components/popup/popup.scss +11 -0
  62. package/components/popup/popup.vue +117 -132
  63. package/components/price/price.scss +20 -0
  64. package/components/price/price.vue +31 -42
  65. package/components/search/search.scss +12 -0
  66. package/components/search/search.vue +93 -117
  67. package/components/searching/searching.vue +33 -40
  68. package/components/selector/selector.vue +43 -48
  69. package/components/switch/switch.scss +12 -0
  70. package/components/switch/switch.vue +99 -96
  71. package/components/tab/tab.scss +19 -0
  72. package/components/tab/tab.vue +151 -145
  73. package/components/textarea/textarea.vue +104 -101
  74. package/composable/component-name.ts +10 -0
  75. package/configs/index.ts +82 -0
  76. package/{easyCom.js → easyCom.ts} +1 -1
  77. package/index.ts +1 -0
  78. package/init.ts +34 -0
  79. package/package.json +12 -4
  80. package/styles/utils/css-var.scss +12 -15
  81. package/styles/utils/ellipsis.scss +0 -7
  82. package/styles/utils/z-index.scss +1 -1
  83. package/styles/var/component.scss +21 -245
  84. package/utils/{date.js → date.ts} +44 -42
  85. package/utils/freezeDeep.ts +9 -0
  86. package/utils/price.ts +57 -0
  87. package/utils/round.ts +11 -0
  88. package/utils/{windowInfo.js → windowInfo.ts} +12 -35
  89. package/components/checkbox-group2/checkbox.vue +0 -109
  90. package/components/datetime-picker/datetime-picker-view.vue +0 -209
  91. package/components/datetime-picker/datetime-picker.vue +0 -235
  92. package/components/form/mixin.js +0 -13
  93. package/components/list-page/list-page.js +0 -10
  94. package/components/table/table.vue +0 -112
  95. package/components/time-picker/time-picker-view.vue +0 -127
  96. package/components/time-picker/time-picker.vue +0 -140
  97. package/components/uploader/download.js +0 -81
  98. package/components/uploader/file-uploader.vue +0 -52
  99. package/components/uploader/files.js +0 -225
  100. package/components/uploader/media-uploader.vue +0 -179
  101. package/components/uploader/mixin.js +0 -171
  102. package/components/uploader/uni.js +0 -38
  103. package/components/uploader/upload-button.vue +0 -29
  104. package/components/uploader/uploader copy.vue +0 -547
  105. package/components/uploader/uploader.vue +0 -117
  106. package/configs/index.d.ts +0 -22
  107. package/configs/index.js +0 -68
  108. package/init.d.ts +0 -19
  109. package/init.js +0 -20
  110. package/mixins/componentName.js +0 -32
  111. package/mixins/listPage.js +0 -1
  112. package/mixins/windowInfo.js +0 -1
  113. package/utils/fileSize.js +0 -39
  114. package/utils/floor.js +0 -20
  115. package/utils/freezeDeep.js +0 -19
  116. package/utils/price.js +0 -32
  117. package/utils/round.js +0 -22
@@ -0,0 +1,82 @@
1
+ import defaultIconfonts from '../resources/iconfont/uniapp_ui_icon/iconfont.json';
2
+
3
+ /** 组件前缀 */
4
+ let componentPrefix = 'app';
5
+ /** 首页路径 */
6
+ let homePath = '/pages/index/index';
7
+
8
+ /**
9
+ * 设置组件前缀
10
+ * @param prefix 组件前缀
11
+ */
12
+ function setComponentPrefix(prefix: string = 'app') {
13
+ if (!prefix) throw new Error('组件前缀不能为空');
14
+ componentPrefix = prefix;
15
+ }
16
+
17
+ /**
18
+ * 设置首页路径
19
+ * @param path 首页路径
20
+ */
21
+ function setHomePath(path: string = '/pages/index/index') {
22
+ if (!path) throw new Error('app 首页不能为空');
23
+ homePath = path;
24
+ }
25
+
26
+ interface IconInfo {
27
+ /** 字体文件名 */
28
+ fontFamily: string;
29
+ /** 图标前缀 */
30
+ prefix: string;
31
+ /** 图标名称 */
32
+ name: string;
33
+ }
34
+
35
+ /** iconfont 图标 map */
36
+ const iconMap: Map<string, IconInfo> = new Map();
37
+
38
+ /**
39
+ * 添加单个图标
40
+ * @param fontFamily 字体文件名
41
+ * @param prefix 图标前缀
42
+ * @param name 图标名称
43
+ */
44
+ function addIconToMap(fontFamily: string, prefix: string, name: string) {
45
+ if (iconMap.has(name)) {
46
+ // eslint-disable-next-line no-console
47
+ console.warn(
48
+ `图标库 "${fontFamily}" 中的图标 "${name}" 在图标库 "${
49
+ iconMap.get(name)!.fontFamily
50
+ }" 中已存在,新的图标将会覆盖已存在的同名图标`
51
+ );
52
+ }
53
+ iconMap.set(name, {
54
+ fontFamily,
55
+ prefix,
56
+ name,
57
+ });
58
+ }
59
+
60
+ export interface IconFontJson {
61
+ font_family: string;
62
+ css_prefix_text: string;
63
+ glyphs: { font_class: string }[];
64
+ }
65
+
66
+ /**
67
+ * 添加一组图标,传入 iconfont.json 文件内容
68
+ * @param iconJson iconfont.json 文件内容
69
+ */
70
+ function addIcons(iconJson: IconFontJson) {
71
+ const fontFamily = iconJson.font_family;
72
+ const prefix = iconJson.css_prefix_text;
73
+ const glyphs = iconJson.glyphs;
74
+ glyphs.forEach((glyph) => {
75
+ addIconToMap(fontFamily, prefix, glyph.font_class);
76
+ });
77
+ }
78
+
79
+ // 添加内部图标库
80
+ addIcons(defaultIconfonts);
81
+
82
+ export { componentPrefix, homePath, setComponentPrefix, setHomePath, iconMap, addIcons };
@@ -28,4 +28,4 @@ function componentEasyCom(componentPrefix = 'app') {
28
28
  }
29
29
 
30
30
  // 导出 easycom 配置
31
- module.exports = componentEasyCom;
31
+ export default componentEasyCom;
package/index.ts ADDED
@@ -0,0 +1 @@
1
+ export { default as init } from './init';
package/init.ts ADDED
@@ -0,0 +1,34 @@
1
+ import { setComponentPrefix, setHomePath, addIcons } from './configs';
2
+ import type { IconFontJson } from './configs';
3
+
4
+ /** 组件库初始化配置 */
5
+ interface InitOptions {
6
+ /** 组件前缀 */
7
+ componentPrefix?: string;
8
+ /** 首页路径 */
9
+ homePath?: string;
10
+ /** iconfont 图标 json 文件 */
11
+ iconfont?: IconFontJson | IconFontJson[];
12
+ }
13
+
14
+ /**
15
+ * 组件库初始化方法,在使用组件库前调用
16
+ * @param options 组件库初始化配置
17
+ */
18
+ function init(options: InitOptions = {}) {
19
+ if (options.componentPrefix) {
20
+ setComponentPrefix(options.componentPrefix);
21
+ }
22
+ if (options.homePath) {
23
+ setHomePath(options.homePath);
24
+ }
25
+ if (options.iconfont) {
26
+ if (Array.isArray(options.iconfont)) {
27
+ options.iconfont.forEach(addIcons);
28
+ } else {
29
+ addIcons(options.iconfont);
30
+ }
31
+ }
32
+ }
33
+
34
+ export default init;
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@ecolovo/uniapp-components",
3
- "version": "1.0.9",
4
- "description": "Ecolovo UniApp 组件库",
3
+ "version": "2.0.0",
4
+ "description": "Ecolovo UniApp Vue3 组件库",
5
5
  "scripts": {
6
- "lint": "eslint . --fix"
6
+ "lint": "eslint --fix"
7
7
  },
8
8
  "keywords": [
9
9
  "uniapp",
@@ -12,18 +12,26 @@
12
12
  "author": "Yang",
13
13
  "license": "ISC",
14
14
  "dependencies": {
15
+ "@ecolovo/utils": "^1.0.7",
15
16
  "case-anything": "3.1.2",
16
- "lodash-es": "4.17.21"
17
+ "lodash-es": "4.17.21",
18
+ "vue": "^3.4.21"
17
19
  },
18
20
  "devDependencies": {
19
21
  "@dcloudio/types": "^3.4.30",
20
22
  "@eslint/js": "^10.0.1",
23
+ "@types/lodash-es": "^4.17.12",
24
+ "@vue/eslint-config-prettier": "^10.2.0",
25
+ "@vue/eslint-config-typescript": "^14.8.0",
26
+ "@vue/tsconfig": "^0.1.3",
21
27
  "eslint": "^10.0.3",
22
28
  "eslint-config-prettier": "^10.1.8",
23
29
  "eslint-plugin-prettier": "^5.5.5",
24
30
  "eslint-plugin-vue": "^10.8.0",
25
31
  "globals": "^17.4.0",
32
+ "miniprogram-api-typings": "^5.2.1",
26
33
  "prettier": "^2.8.8",
34
+ "typescript": "^4.9.4",
27
35
  "vue-eslint-parser": "^10.4.0"
28
36
  }
29
37
  }
@@ -4,11 +4,8 @@
4
4
  @use 'sass:string';
5
5
  @use '../var/theme' as *;
6
6
 
7
- $component-name: null !default;
8
- $component-vars: null !default;
9
-
10
7
  // 返回组件外部变量名
11
- @function UTILS__VAR_NAME($name, $component: $component-name) {
8
+ @function UTILS__VAR_NAME($name, $component) {
12
9
  @return string.unquote('--#{$component-prefix}-#{$component}--#{$name}');
13
10
  }
14
11
 
@@ -25,7 +22,7 @@ $component-vars: null !default;
25
22
  }
26
23
 
27
24
  // 返回组件外部变量值
28
- @function UTILS__VAR($name, $component: $component-name, $default: null) {
25
+ @function UTILS__VAR($name, $component, $default: null) {
29
26
  @if $default != null {
30
27
  @return var(UTILS__VAR_NAME($name, $component), $default);
31
28
  }
@@ -43,17 +40,17 @@ $component-vars: null !default;
43
40
  }
44
41
 
45
42
  // 定义组件变量
46
- @mixin UTILS__DEFINE_COMPONENT_VARS() {
47
- @if not $component-name {
48
- @error "请在调用 UTILS__DEFINE_COMPONENT_VARS 之前设置 $component-name";
43
+ @mixin UTILS__DEFINE_COMPONENT_VARS($vars, $name) {
44
+ @if not $name {
45
+ @error "请传入 $name";
49
46
  }
50
47
 
51
- @if (not $component-vars) or (meta.type-of($component-vars) != 'map') {
52
- @error "请在调用 UTILS__DEFINE_COMPONENT_VARS 之前设置 $component-vars";
48
+ @if (not $vars) or (meta.type-of($vars) != 'map') {
49
+ @error "请传入 $vars";
53
50
  }
54
51
 
55
- @each $key, $value in $component-vars {
56
- @include __DO_NOT_USE__define-component-var($key, $value);
52
+ @each $key, $value in $vars {
53
+ @include __DO_NOT_USE__define-component-var($name, $key, $value);
57
54
  }
58
55
  }
59
56
 
@@ -65,12 +62,12 @@ $component-vars: null !default;
65
62
  }
66
63
 
67
64
  // 定义单个组件变量,不要直接调用
68
- @mixin __DO_NOT_USE__define-component-var($name, $value) {
65
+ @mixin __DO_NOT_USE__define-component-var($component, $name, $value) {
69
66
  @if not $component-prefix {
70
67
  @error "请在调用 __DO_NOT_USE__define-component-var 之前设置 component-prefix";
71
68
  }
72
69
 
73
- $var-prefix: '#{$component-prefix}-#{$component-name}';
70
+ $var-prefix: '#{$component-prefix}-#{$component}';
74
71
 
75
72
  $default: false;
76
73
 
@@ -78,7 +75,7 @@ $component-vars: null !default;
78
75
  $default: true;
79
76
  }
80
77
 
81
- $var-name: UTILS__VAR_NAME($name);
78
+ $var-name: UTILS__VAR_NAME($name, $component);
82
79
  $local-name: __DO_NOT_USE__local-var-name($name);
83
80
 
84
81
  @if $default {
@@ -1,10 +1,3 @@
1
- // 单行
2
- .ellipsis {
3
- overflow-x: hidden;
4
- text-overflow: ellipsis;
5
- white-space: nowrap;
6
- }
7
-
8
1
  @mixin UTILS__ELLIPSIS($line: 1) {
9
2
  @if $line < 1 {
10
3
  @error "$line 必须为非 0 正整数";
@@ -5,6 +5,6 @@
5
5
  @use '../var/theme' as *;
6
6
  @use './css-var' as *;
7
7
 
8
- @function UTILS__z-index($key: $component-name) {
8
+ @function UTILS__z-index($key) {
9
9
  @return map.get($z-index-maps, $key);
10
10
  }
@@ -1,245 +1,21 @@
1
- @use 'sass:map';
2
- @use '../utils' as *;
3
-
4
- $badge: () !default;
5
- $badge-default: (
6
- // 相对于右上角偏移量
7
- translate: 40% -40%,
8
- // 字号
9
- font-size: UTILS__GLOBAL_VAR(font-size, small),
10
- // 文字颜色
11
- color: #fff,
12
- // 背景色
13
- background: #ff0000,
14
- // 边框
15
- border: none,
16
- // 高度
17
- height: calc(#{UTILS__LOCAL_VAR(font-size)} + 12rpx),
18
- // 圆角
19
- border-radius: 40rpx
20
- );
21
- $badge: map.merge($badge-default, $badge);
22
-
23
- $page-header: () !default;
24
- $page-header-default: (
25
- // 背景色
26
- background: #fff,
27
- // 字体大小
28
- font-size: 28rpx,
29
- // 标题栏下的额外内容高度,有内容时需设置次值
30
- extra-height: 0px,
31
- // 亮色主题下的文本颜色
32
- color-light: #000,
33
- // 暗色主题下的文本颜色
34
- color-dark: #fff
35
- );
36
- $page-header: map.merge($page-header-default, $page-header);
37
-
38
- $page-body: () !default;
39
- $page-body-default: (
40
- // 可视区域背景
41
- background: transparent,
42
- padding: 20rpx,
43
- padding-top: null,
44
- padding-right: null,
45
- padding-bottom: null,
46
- padding-left: null
47
- );
48
- $page-body: map.merge($page-body-default, $page-body);
49
-
50
- $page-footer: () !default;
51
- $page-footer-default: (
52
- // 背景色
53
- background: #fff,
54
- // 高度
55
- height: 100rpx,
56
- // 横向两端间距
57
- spacing-horizontal: 30rpx
58
- );
59
- $page-footer: map.merge($page-footer-default, $page-footer);
60
-
61
- $page: () !default;
62
- $page-default: (
63
- // 页面背景
64
- background: transparent
65
- );
66
- $page: map.merge($page-default, $page);
67
-
68
- $button: () !default;
69
- $button-default: (
70
- // 按钮主题颜色,默认取值组件 props 中的 type
71
- theme: var(--theme-from-prop),
72
- // 按钮文本颜色
73
- text-color: #fff,
74
- // 按钮激活态遮罩颜色
75
- active-mask: #ffffff,
76
- // plain 按钮的边框宽度
77
- border-width: 3rpx
78
- );
79
- $button: map.merge($button-default, $button);
80
-
81
- $data-list: () !default;
82
- $data-list-default: (
83
- // 触发加载更多的区域高度
84
- observer-height: 100vh
85
- );
86
- $data-list: map.merge($data-list-default, $data-list);
87
-
88
- $empty: () !default;
89
- $empty-default: (
90
- image-size: 300rpx,
91
- image-width: UTILS__LOCAL_VAR(image-size),
92
- image-height: UTILS__LOCAL_VAR(image-size),
93
- space: 20rpx,
94
- color: #ccc,
95
- font-size: UTILS__GLOBAL_VAR(font-size, normal),
96
- );
97
- $empty: map.merge($empty-default, $empty);
98
-
99
- $load-more: () !default;
100
- $load-more-default: (
101
- height: 60rpx,
102
- space: 40rpx,
103
- color: #ccc,
104
- font-size: UTILS__GLOBAL_VAR(font-size, normal),
105
- );
106
- $load-more: map.merge($load-more-default, $load-more);
107
-
108
- $checkbox: () !default;
109
- $checkbox-default: (
110
- checked-color: UTILS__GLOBAL_VAR(theme, primary),
111
- unchecked-color: UTILS__GLOBAL_VAR(color, foreground),
112
- );
113
- $checkbox: map.merge($checkbox-default, $checkbox);
114
-
115
- $popover: () !default;
116
- $popover-default: (
117
- // 遮罩层颜色
118
- mask-color: #00000080,
119
- // 背景色
120
- background: #fff,
121
- // 位置,position 为 center 时有效
122
- position: 50% auto auto 50%,
123
- // 宽度,position 为 left 、 right 或 center 时有效
124
- width: 80vw,
125
- // 最小高度,position 为 top 、 bottom 或 center 时有效
126
- min-height: 0px,
127
- // 最大高度,position 为 top 、 bottom 或 center 时有效
128
- max-height: 75vh,
129
- // 内边距
130
- padding: 20rpx,
131
- // 边框圆角
132
- radius: 20rpx,
133
- // 头高度
134
- header-height: 0px,
135
- // 尾高度
136
- footer-height: 0px
137
- );
138
- $popover: map.merge($popover-default, $popover);
139
-
140
- $dialog: () !default;
141
- $dialog-default: (
142
- // 标题栏高度
143
- header-height: 100rpx,
144
- // 操作栏高度
145
- footer-height: 134rpx
146
- );
147
- $dialog: map.merge($dialog-default, $dialog);
148
-
149
- $popup: () !default;
150
- $popup-default: (
151
- // 标题栏高度
152
- header-height: 100rpx,
153
- // 操作栏高度
154
- footer-height: 102rpx
155
- );
156
- $popup: map.merge($popup-default, $popup);
157
-
158
- $form-item: () !default;
159
- $form-item-default: (
160
- // label 宽度
161
- label-width: 6em,
162
- // 高度
163
- height: 80rpx
164
- );
165
- $form-item: map.merge($form-item-default, $form-item);
166
-
167
- $switch: () !default;
168
- $switch-default: (
169
- width: 92rpx,
170
- height: 48rpx,
171
- active-color: UTILS__GLOBAL_VAR(theme, primary),
172
- indicator-size: 42rpx,
173
- );
174
- $switch: map.merge($switch-default, $switch);
175
-
176
- $number-input: () !default;
177
- $number-input-default: (
178
- font-size: inherit,
179
- text-align: center,
180
- );
181
- $number-input: map.merge($number-input-default, $number-input);
182
-
183
- $numpad: () !default;
184
- $numpad-default: (
185
- row-gap: 20rpx,
186
- col-gap: 20rpx,
187
- );
188
- $numpad: map.merge($numpad-default, $numpad);
189
-
190
- $number-dialog: () !default;
191
- $number-dialog-default: (
192
- // 按钮尺寸
193
- button-size: 48rpx
194
- );
195
- $number-dialog: map.merge($number-dialog-default, $number-dialog);
196
-
197
- $tab: () !default;
198
- $tab-default: (
199
- height: 88rpx,
200
- tab-padding: 0 10rpx,
201
- tab-gaps: 0,
202
- color: UTILS__GLOBAL_VAR(color, foreground),
203
- font-size: UTILS__GLOBAL_VAR(font-size, large),
204
- font-weight: 600,
205
- background: #ffffff,
206
- border-radius: 0,
207
- active-color: UTILS__LOCAL_VAR(color),
208
- indicator-color: UTILS__GLOBAL_VAR(theme, primary),
209
- indicator-width: null,
210
- );
211
- $tab: map.merge($tab-default, $tab);
212
-
213
- $search: () !default;
214
- $search-default: (
215
- background: UTILS__GLOBAL_VAR(color, background),
216
- border-radius: 8rpx,
217
- height: 64rpx,
218
- padding: 0 20rpx,
219
- );
220
- $search: map.merge($search-default, $search);
221
-
222
- $price: () !default;
223
- $price-default: (
224
- color: inherit,
225
- font-size: inherit,
226
- font-weight: inherit,
227
- integer-color: UTILS__LOCAL_VAR(color),
228
- integer-font-size: UTILS__LOCAL_VAR(font-size),
229
- integer-font-weight: UTILS__LOCAL_VAR(font-weight),
230
- decimal-color: UTILS__LOCAL_VAR(color),
231
- decimal-font-size: UTILS__LOCAL_VAR(font-size),
232
- decimal-font-weight: UTILS__LOCAL_VAR(font-weight),
233
- unit-color: UTILS__LOCAL_VAR(color),
234
- unit-font-size: UTILS__LOCAL_VAR(font-size),
235
- unit-font-weight: UTILS__LOCAL_VAR(font-weight),
236
- );
237
- $price: map.merge($price-default, $price);
238
-
239
- // $page: () !default;
240
- // $page-default: ();
241
- // $page: map.merge($page-default, $page);
242
-
243
- // $page: () !default;
244
- // $page-default: ();
245
- // $page: map.merge($page-default, $page);
1
+ // @forward '../../components/badge/badge.scss';
2
+ @forward '../../components/button/button.scss';
3
+ // @forward '../../components/checkbox/checkbox.scss';
4
+ // @forward '../../components/data-list/data-list.scss';
5
+ // @forward '../../components/dialog/dialog.scss';
6
+ // @forward '../../components/empty/empty.scss';
7
+ // @forward '../../components/form-item/form-item.scss';
8
+ // @forward '../../components/load-more/load-more.scss';
9
+ // @forward '../../components/number-dialog/number-dialog.scss';
10
+ // @forward '../../components/number-input/number-input.scss';
11
+ // @forward '../../components/numpad/numpad.scss';
12
+ // @forward '../../components/page/page.scss';
13
+ // @forward '../../components/page/page-header.scss';
14
+ // @forward '../../components/page/page-body.scss';
15
+ // @forward '../../components/page/page-footer.scss';
16
+ // @forward '../../components/popover/popover.scss';
17
+ // @forward '../../components/popup/popup.scss';
18
+ // @forward '../../components/price/price.scss';
19
+ // @forward '../../components/search/search.scss';
20
+ // @forward '../../components/switch/switch.scss';
21
+ // @forward '../../components/tab/tab.scss';
@@ -1,25 +1,36 @@
1
+ type ValidDateValue = Date | number | string;
2
+
1
3
  /**
2
4
  * 将Date 对象、时间戳或时间格式字符串转为 Date 对象
3
- * @param {Date | number | string} dateValue Date 对象、时间戳或时间格式字符串
4
- * @returns {Date} Date 对象
5
+ * @param dateValue Date 对象、时间戳或时间格式字符串
6
+ * @returns Date 对象
5
7
  */
6
- export function toDate(dateValue) {
8
+ export function toDate(dateValue: ValidDateValue | null | undefined): Date | null {
7
9
  if (dateValue instanceof Date) return new Date(dateValue);
8
10
  if (typeof dateValue === 'number') return new Date(dateValue);
9
- if (!dateValue) {
10
- return null;
11
- }
12
- if (typeof dateValue !== 'string') {
13
- throw new Error("dateValue's type is invalid");
14
- }
11
+ if (!dateValue) return null;
12
+ if (typeof dateValue !== 'string') throw new Error("dateValue's type is invalid");
13
+
15
14
  // 兼容 iOS 日期格式
16
15
  const result = new Date(dateValue.replace(/-/g, '/'));
17
- if (isNaN(result.getTime())) {
18
- throw new Error('dateValue cannot be parsed to Date object');
19
- }
16
+ if (isNaN(result.getTime())) throw new Error('dateValue cannot be parsed to Date object');
20
17
  return result;
21
18
  }
22
19
 
20
+ type FormatFn = {
21
+ (date: Date | null | undefined, format?: string): string;
22
+ DATE: string;
23
+ DATE_WITH_YEAR: string;
24
+ TIME: string;
25
+ TIME_MS: string;
26
+ TIME_MINUTE: string;
27
+ DATE_TIME: string;
28
+ DATE_TIME_MS: string;
29
+ DATE_TIME_WITH_YEAR: string;
30
+ DATE_TIME_MS_WITH_YEAR: string;
31
+ DATE_MINUTE: string;
32
+ DATE_MINUTE_WITH_YEAR: string;
33
+ };
23
34
  /**
24
35
  * 格式化日期
25
36
  *
@@ -33,14 +44,12 @@ export function toDate(dateValue) {
33
44
  * - S: 毫秒
34
45
  * - w: 星期
35
46
  * - W: 星期(中文)
36
- * @param {Date | undefined} date 要格式化的日期对象
37
- * @param {string} format 格式化参数 默认值 YYYY-MM-DD
38
- * @returns {string} 格式化后的日期
47
+ * @param date 要格式化的日期对象
48
+ * @param format 格式化参数 默认值 YYYY-MM-DD
49
+ * @returns 格式化后的日期
39
50
  */
40
- export function formatDate(date, format = formatDate.DATE_WITH_YEAR) {
41
- if (!date) {
42
- return '';
43
- }
51
+ export const formatDate: FormatFn = (date, format = formatDate.DATE_WITH_YEAR) => {
52
+ if (!date) return '';
44
53
  const fullYear = date.getFullYear().toString();
45
54
  const year = fullYear.substring(fullYear.length - 2);
46
55
  const month = (date.getMonth() + 1).toString();
@@ -74,7 +83,6 @@ export function formatDate(date, format = formatDate.DATE_WITH_YEAR) {
74
83
  weekCN = '六';
75
84
  break;
76
85
  }
77
-
78
86
  const replacement = [
79
87
  { reg: 'Y{3,4}', val: fullYear, pad: 0 },
80
88
  { reg: 'Y{1,2}', val: year, pad: 0 },
@@ -87,15 +95,14 @@ export function formatDate(date, format = formatDate.DATE_WITH_YEAR) {
87
95
  { reg: 'w', val: week, pad: 0 },
88
96
  { reg: 'W', val: weekCN, pad: 0 },
89
97
  ];
90
-
91
98
  for (let i = 0; i < replacement.length; i++) {
92
- const r = replacement[i];
93
- format = format.replace(new RegExp(r.reg, 'g'), function (m) {
94
- return r.pad > 0 ? r.val.padStart(Math.min(r.pad, m.length), '0') : r.val;
95
- });
99
+ const r = replacement[i]!;
100
+ format = format.replace(new RegExp(r.reg, 'g'), (m) =>
101
+ r.pad > 0 ? r.val.padStart(Math.min(r.pad, m.length), '0') : r.val
102
+ );
96
103
  }
97
104
  return format;
98
- }
105
+ };
99
106
 
100
107
  /** 月日 */
101
108
  formatDate.DATE = 'MM-DD';
@@ -125,27 +132,22 @@ const TIMEZONE_OFFSET = new Date().getTimezoneOffset() * 60 * 1000;
125
132
 
126
133
  /**
127
134
  * 获取时间的UTC相对时间戳
128
- * @param {number | string | Date} date 时间
129
- * @returns {number} 毫秒数
135
+ * @param date 时间
136
+ * @returns 毫秒数
130
137
  */
131
- function toDayTimestamp(date) {
132
- let d = null;
133
- if (typeof date === 'number') {
134
- return date - TIMEZONE_OFFSET;
135
- } else if (typeof date === 'string') {
136
- d = toDate(date);
137
- } else if (!(date instanceof Date)) {
138
- d = new Date();
139
- }
140
- return d.getTime() - TIMEZONE_OFFSET;
138
+ function toDayTimestamp(date: ValidDateValue): number {
139
+ if (typeof date === 'number') return date - TIMEZONE_OFFSET;
140
+ if (typeof date === 'string') return toDate(date)!.getTime() - TIMEZONE_OFFSET;
141
+ if (date instanceof Date) return date.getTime() - TIMEZONE_OFFSET;
142
+ return Date.now() - TIMEZONE_OFFSET;
141
143
  }
142
144
 
143
145
  /**
144
146
  * 获取两个时间的天数差
145
- * @param {number | string | Date} day1 时间1
146
- * @param {number | string | Date} day2 时间2
147
- * @returns {number} 天数差,负数: day1 < day2
147
+ * @param day1 时间1
148
+ * @param day2 时间2
149
+ * @returns 天数差,负数: day1 < day2
148
150
  */
149
- export function daysDiff(day1, day2) {
151
+ export function daysDiff(day1: ValidDateValue, day2: ValidDateValue): number {
150
152
  return Math.floor(toDayTimestamp(day1) / 8.64e7) - Math.floor(toDayTimestamp(day2) / 8.64e7);
151
153
  }
@@ -0,0 +1,9 @@
1
+ export function freezeDeep<T>(obj: T): Readonly<T> {
2
+ if (!(typeof obj === 'object' && obj)) {
3
+ return obj;
4
+ }
5
+ for (const key in obj) {
6
+ freezeDeep((obj as Record<string, unknown>)[key]);
7
+ }
8
+ return Object.freeze(obj);
9
+ }