Commit 144ab577da06ff0bd1f258d1901b87864f232e45

Authored by vben
1 parent 8d7d0835

fix(modal): height calc error #161

CHANGELOG.zh_CN.md
@@ -13,6 +13,7 @@ @@ -13,6 +13,7 @@
13 - 恢复 table 的`isTreeTable`属性 13 - 恢复 table 的`isTreeTable`属性
14 - 修复表格内存溢出问题 14 - 修复表格内存溢出问题
15 - 修复`layout` 收缩展开功能在分割模式下失效 15 - 修复`layout` 收缩展开功能在分割模式下失效
  16 +- 修复 modal 高度计算错误
16 17
17 ## 2.0.0-rc.15 (2020-12-31) 18 ## 2.0.0-rc.15 (2020-12-31)
18 19
README.md
@@ -256,8 +256,8 @@ yarn clean:lib # 删除node_modules,兼容window系统 @@ -256,8 +256,8 @@ yarn clean:lib # 删除node_modules,兼容window系统
256 256
257 如果这些插件对你有帮助,可以给一个 star 支持下 257 如果这些插件对你有帮助,可以给一个 star 支持下
258 258
259 -- [vite-plugin-mock](https://github.com/anncwb/vite-plugin-mock)  
260 -- [vite-plugin-html](https://github.com/anncwb/vite-plugin-html) 259 +- [vite-plugin-mock](https://github.com/vbenjs/vite-plugin-mock)
  260 +- [vite-plugin-html](https://github.com/vbenjs/vite-plugin-html)
261 261
262 ## 加入我们 262 ## 加入我们
263 263
src/components/Basic/src/BasicArrow.vue
@@ -15,6 +15,7 @@ @@ -15,6 +15,7 @@
15 15
16 export default defineComponent({ 16 export default defineComponent({
17 name: 'BasicArrow', 17 name: 'BasicArrow',
  18 + inheritAttrs: false,
18 components: { RightOutlined }, 19 components: { RightOutlined },
19 props: { 20 props: {
20 // Expand contract, expand by default 21 // Expand contract, expand by default
src/components/Basic/src/BasicHelp.vue
@@ -12,6 +12,7 @@ @@ -12,6 +12,7 @@
12 import { useDesign } from '/@/hooks/web/useDesign'; 12 import { useDesign } from '/@/hooks/web/useDesign';
13 export default defineComponent({ 13 export default defineComponent({
14 name: 'BasicHelp', 14 name: 'BasicHelp',
  15 + inheritAttrs: false,
15 components: { Tooltip }, 16 components: { Tooltip },
16 props: { 17 props: {
17 // max-width 18 // max-width
src/components/Basic/src/BasicTitle.vue
@@ -15,6 +15,7 @@ @@ -15,6 +15,7 @@
15 15
16 export default defineComponent({ 16 export default defineComponent({
17 name: 'BasicTitle', 17 name: 'BasicTitle',
  18 + inheritAttrs: false,
18 components: { BasicHelp }, 19 components: { BasicHelp },
19 props: { 20 props: {
20 helpMessage: { 21 helpMessage: {
src/components/Container/src/LazyContainer.vue
@@ -35,6 +35,7 @@ @@ -35,6 +35,7 @@
35 35
36 export default defineComponent({ 36 export default defineComponent({
37 name: 'LazyContainer', 37 name: 'LazyContainer',
  38 + inheritAttrs: false,
38 components: { Skeleton }, 39 components: { Skeleton },
39 props: { 40 props: {
40 // Waiting time, if the time is specified, whether visible or not, it will be automatically loaded after the specified time 41 // Waiting time, if the time is specified, whether visible or not, it will be automatically loaded after the specified time
src/components/Container/src/ScrollContainer.vue
@@ -12,6 +12,7 @@ @@ -12,6 +12,7 @@
12 12
13 export default defineComponent({ 13 export default defineComponent({
14 name: 'ScrollContainer', 14 name: 'ScrollContainer',
  15 + inheritAttrs: false,
15 components: { Scrollbar }, 16 components: { Scrollbar },
16 setup() { 17 setup() {
17 const scrollbarRef = ref<Nullable<ScrollbarType>>(null); 18 const scrollbarRef = ref<Nullable<ScrollbarType>>(null);
src/components/Markdown/src/index.vue
@@ -8,19 +8,23 @@ @@ -8,19 +8,23 @@
8 8
9 import { propTypes } from '/@/utils/propTypes'; 9 import { propTypes } from '/@/utils/propTypes';
10 import { useLocale } from '/@/hooks/web/useLocale'; 10 import { useLocale } from '/@/hooks/web/useLocale';
  11 + import { useModalContext } from '../../Modal';
11 12
12 type Lang = 'zh_CN' | 'en_US' | 'ja_JP' | 'ko_KR' | undefined; 13 type Lang = 'zh_CN' | 'en_US' | 'ja_JP' | 'ko_KR' | undefined;
13 export default defineComponent({ 14 export default defineComponent({
14 - emits: ['change'], 15 + inheritAttrs: false,
15 props: { 16 props: {
16 height: propTypes.number.def(360), 17 height: propTypes.number.def(360),
17 value: propTypes.string.def(''), 18 value: propTypes.string.def(''),
18 }, 19 },
  20 + emits: ['change', 'get'],
19 setup(props, { attrs, emit }) { 21 setup(props, { attrs, emit }) {
20 const wrapRef = ref<ElRef>(null); 22 const wrapRef = ref<ElRef>(null);
21 const vditorRef = ref<Nullable<Vditor>>(null); 23 const vditorRef = ref<Nullable<Vditor>>(null);
22 const initedRef = ref(false); 24 const initedRef = ref(false);
23 25
  26 + const modalFn = useModalContext();
  27 +
24 const lang = ref<Lang>(); 28 const lang = ref<Lang>();
25 29
26 const { getLang } = useLocale(); 30 const { getLang } = useLocale();
@@ -66,10 +70,19 @@ @@ -66,10 +70,19 @@
66 initedRef.value = true; 70 initedRef.value = true;
67 } 71 }
68 72
  73 + const instance = {
  74 + getVditor: (): Vditor => vditorRef.value!,
  75 + };
  76 +
69 onMounted(() => { 77 onMounted(() => {
70 nextTick(() => { 78 nextTick(() => {
71 init(); 79 init();
  80 + setTimeout(() => {
  81 + modalFn?.redoModalHeight?.();
  82 + }, 200);
72 }); 83 });
  84 +
  85 + emit('get', instance);
73 }); 86 });
74 87
75 onUnmounted(() => { 88 onUnmounted(() => {
@@ -82,7 +95,7 @@ @@ -82,7 +95,7 @@
82 95
83 return { 96 return {
84 wrapRef, 97 wrapRef,
85 - getVditor: (): Vditor => vditorRef.value!, 98 + ...instance,
86 }; 99 };
87 }, 100 },
88 }); 101 });
src/components/Modal/src/BasicModal.vue
@@ -27,7 +27,7 @@ @@ -27,7 +27,7 @@
27 :height="getProps.height" 27 :height="getProps.height"
28 :visible="visibleRef" 28 :visible="visibleRef"
29 :modalFooterHeight="footer !== undefined && !footer ? 0 : undefined" 29 :modalFooterHeight="footer !== undefined && !footer ? 0 : undefined"
30 - v-bind="omit(getProps.wrapperProps, 'visible')" 30 + v-bind="omit(getProps.wrapperProps, 'visible', 'height')"
31 @ext-height="handleExtHeight" 31 @ext-height="handleExtHeight"
32 @height-change="handleHeightChange" 32 @height-change="handleHeightChange"
33 > 33 >
@@ -51,6 +51,7 @@ @@ -51,6 +51,7 @@
51 watchEffect, 51 watchEffect,
52 toRef, 52 toRef,
53 getCurrentInstance, 53 getCurrentInstance,
  54 + nextTick,
54 } from 'vue'; 55 } from 'vue';
55 56
56 import Modal from './components/Modal'; 57 import Modal from './components/Modal';
@@ -67,6 +68,7 @@ @@ -67,6 +68,7 @@
67 import { omit } from 'lodash-es'; 68 import { omit } from 'lodash-es';
68 export default defineComponent({ 69 export default defineComponent({
69 name: 'BasicModal', 70 name: 'BasicModal',
  71 + inheritAttrs: false,
70 components: { Modal, ModalWrapper, ModalClose, ModalFooter, ModalHeader }, 72 components: { Modal, ModalWrapper, ModalClose, ModalFooter, ModalHeader },
71 props: basicProps, 73 props: basicProps,
72 emits: ['visible-change', 'height-change', 'cancel', 'ok', 'register'], 74 emits: ['visible-change', 'height-change', 'cancel', 'ok', 'register'],
src/components/Modal/src/components/ModalWrapper.vue
@@ -31,6 +31,7 @@ @@ -31,6 +31,7 @@
31 31
32 export default defineComponent({ 32 export default defineComponent({
33 name: 'ModalWrapper', 33 name: 'ModalWrapper',
  34 + inheritAttrs: false,
34 components: { Spin, ScrollContainer }, 35 components: { Spin, ScrollContainer },
35 props: { 36 props: {
36 loading: propTypes.bool, 37 loading: propTypes.bool,
@@ -51,6 +52,8 @@ @@ -51,6 +52,8 @@
51 const realHeightRef = ref(0); 52 const realHeightRef = ref(0);
52 const minRealHeightRef = ref(0); 53 const minRealHeightRef = ref(0);
53 54
  55 + let realHeight = 0;
  56 +
54 let stopElResizeFn: Fn = () => {}; 57 let stopElResizeFn: Fn = () => {};
55 58
56 useWindowSizeFn(setModalHeight); 59 useWindowSizeFn(setModalHeight);
@@ -137,8 +140,9 @@ @@ -137,8 +140,9 @@
137 140
138 if (!spinEl) return; 141 if (!spinEl) return;
139 142
140 - const realHeight = spinEl.scrollHeight;  
141 - 143 + if (!realHeight) {
  144 + realHeight = spinEl.scrollHeight;
  145 + }
142 if (props.fullScreen) { 146 if (props.fullScreen) {
143 realHeightRef.value = 147 realHeightRef.value =
144 window.innerHeight - props.modalFooterHeight - props.modalHeaderHeight; 148 window.innerHeight - props.modalFooterHeight - props.modalHeaderHeight;
@@ -147,7 +151,7 @@ @@ -147,7 +151,7 @@
147 ? props.height 151 ? props.height
148 : realHeight > maxHeight 152 : realHeight > maxHeight
149 ? maxHeight 153 ? maxHeight
150 - : realHeight + 16 + 30; 154 + : realHeight + 46;
151 } 155 }
152 emit('height-change', unref(realHeightRef)); 156 emit('height-change', unref(realHeightRef));
153 } catch (error) { 157 } catch (error) {
src/components/Scrollbar/src/index.vue
@@ -33,6 +33,7 @@ @@ -33,6 +33,7 @@
33 33
34 export default defineComponent({ 34 export default defineComponent({
35 name: 'Scrollbar', 35 name: 'Scrollbar',
  36 + inheritAttrs: false,
36 components: { Bar }, 37 components: { Bar },
37 props: { 38 props: {
38 native: { 39 native: {
@@ -91,12 +92,18 @@ @@ -91,12 +92,18 @@
91 onMounted(() => { 92 onMounted(() => {
92 if (props.native) return; 93 if (props.native) return;
93 nextTick(update); 94 nextTick(update);
94 - !props.noresize && addResizeListener(resize.value, update); 95 + if (!props.noresize) {
  96 + addResizeListener(resize.value, update);
  97 + addResizeListener(wrap.value, update);
  98 + }
95 }); 99 });
96 100
97 onBeforeUnmount(() => { 101 onBeforeUnmount(() => {
98 if (props.native) return; 102 if (props.native) return;
99 - !props.noresize && removeResizeListener(resize.value, update); 103 + if (!props.noresize) {
  104 + removeResizeListener(resize.value, update);
  105 + removeResizeListener(wrap.value, update);
  106 + }
100 }); 107 });
101 const style = computed(() => { 108 const style = computed(() => {
102 let style: any = props.wrapStyle; 109 let style: any = props.wrapStyle;
@@ -127,7 +134,7 @@ @@ -127,7 +134,7 @@
127 134
128 &__wrap { 135 &__wrap {
129 height: 100%; 136 height: 100%;
130 - overflow: scroll; 137 + overflow: auto;
131 138
132 &--hidden-default { 139 &--hidden-default {
133 scrollbar-width: none; 140 scrollbar-width: none;
src/components/Tinymce/src/Editor.vue
@@ -31,6 +31,7 @@ @@ -31,6 +31,7 @@
31 31
32 export default defineComponent({ 32 export default defineComponent({
33 name: 'Tinymce', 33 name: 'Tinymce',
  34 + inheritAttrs: false,
34 props: basicProps, 35 props: basicProps,
35 emits: ['change', 'update:modelValue'], 36 emits: ['change', 'update:modelValue'],
36 setup(props, { emit, attrs }) { 37 setup(props, { emit, attrs }) {
src/components/Tree/src/BasicTree.tsx
@@ -15,6 +15,7 @@ import { extendSlots } from &#39;/@/utils/helper/tsxHelper&#39;; @@ -15,6 +15,7 @@ import { extendSlots } from &#39;/@/utils/helper/tsxHelper&#39;;
15 import { basicProps } from './props'; 15 import { basicProps } from './props';
16 import { useTree } from './useTree'; 16 import { useTree } from './useTree';
17 import { useExpose } from '/@/hooks/core/useExpose'; 17 import { useExpose } from '/@/hooks/core/useExpose';
  18 +import { onMounted } from 'vue';
18 19
19 interface State { 20 interface State {
20 expandedKeys: Keys; 21 expandedKeys: Keys;
@@ -25,7 +26,7 @@ const prefixCls = &#39;basic-tree&#39;; @@ -25,7 +26,7 @@ const prefixCls = &#39;basic-tree&#39;;
25 export default defineComponent({ 26 export default defineComponent({
26 name: 'BasicTree', 27 name: 'BasicTree',
27 props: basicProps, 28 props: basicProps,
28 - emits: ['update:expandedKeys', 'update:selectedKeys', 'update:value'], 29 + emits: ['update:expandedKeys', 'update:selectedKeys', 'update:value', 'get'],
29 setup(props, { attrs, slots, emit }) { 30 setup(props, { attrs, slots, emit }) {
30 const state = reactive<State>({ 31 const state = reactive<State>({
31 expandedKeys: props.expandedKeys || [], 32 expandedKeys: props.expandedKeys || [],
@@ -182,7 +183,7 @@ export default defineComponent({ @@ -182,7 +183,7 @@ export default defineComponent({
182 state.checkedKeys = props.checkedKeys; 183 state.checkedKeys = props.checkedKeys;
183 }); 184 });
184 185
185 - useExpose<TreeActionType>({ 186 + const instance: TreeActionType = {
186 setExpandedKeys, 187 setExpandedKeys,
187 getExpandedKeys, 188 getExpandedKeys,
188 setSelectedKeys, 189 setSelectedKeys,
@@ -195,6 +196,12 @@ export default defineComponent({ @@ -195,6 +196,12 @@ export default defineComponent({
195 filterByLevel: (level: number) => { 196 filterByLevel: (level: number) => {
196 state.expandedKeys = filterByLevel(level); 197 state.expandedKeys = filterByLevel(level);
197 }, 198 },
  199 + };
  200 +
  201 + useExpose<TreeActionType>(instance);
  202 +
  203 + onMounted(() => {
  204 + emit('get', instance);
198 }); 205 });
199 206
200 return () => { 207 return () => {
src/hooks/component/usePageContext.ts
1 import type { InjectionKey, ComputedRef, Ref } from 'vue'; 1 import type { InjectionKey, ComputedRef, Ref } from 'vue';
2 import { createContext, useContext } from '/@/hooks/core/useContext'; 2 import { createContext, useContext } from '/@/hooks/core/useContext';
3 3
4 -import {} from 'vue';  
5 -  
6 export interface PageContextProps { 4 export interface PageContextProps {
7 contentHeight: ComputedRef<number>; 5 contentHeight: ComputedRef<number>;
8 pageHeight: Ref<number>; 6 pageHeight: Ref<number>;
src/layouts/default/sider/MixSider.vue
@@ -113,7 +113,6 @@ @@ -113,7 +113,6 @@
113 const activePath = ref(''); 113 const activePath = ref('');
114 const chilrenMenus = ref<Menu[]>([]); 114 const chilrenMenus = ref<Menu[]>([]);
115 const openMenu = ref(false); 115 const openMenu = ref(false);
116 - const isInit = ref(false);  
117 const dragBarRef = ref<ElRef>(null); 116 const dragBarRef = ref<ElRef>(null);
118 const sideRef = ref<ElRef>(null); 117 const sideRef = ref<ElRef>(null);
119 const currentRoute = ref<Nullable<RouteLocationNormalized>>(null); 118 const currentRoute = ref<Nullable<RouteLocationNormalized>>(null);
@@ -251,8 +250,8 @@ @@ -251,8 +250,8 @@
251 } 250 }
252 251
253 function handleClickOutside() { 252 function handleClickOutside() {
  253 + setActive(true);
254 closeMenu(); 254 closeMenu();
255 - setActive();  
256 } 255 }
257 256
258 function getItemEvents(item: Menu) { 257 function getItemEvents(item: Menu) {
src/utils/browser.ts
@@ -75,7 +75,7 @@ export function isOperaFn() { @@ -75,7 +75,7 @@ export function isOperaFn() {
75 * set page Title 75 * set page Title
76 * @param {*} title :page Title 76 * @param {*} title :page Title
77 */ 77 */
78 -const setDocumentTitle = (title: string) => { 78 +function setDocumentTitle(title: string) {
79 document.title = title; 79 document.title = title;
80 const ua = navigator.userAgent; 80 const ua = navigator.userAgent;
81 const regex = /\bMicroMessenger\/([\d.]+)/; 81 const regex = /\bMicroMessenger\/([\d.]+)/;
@@ -91,7 +91,7 @@ const setDocumentTitle = (title: string) =&gt; { @@ -91,7 +91,7 @@ const setDocumentTitle = (title: string) =&gt; {
91 }; 91 };
92 document.body.appendChild(i); 92 document.body.appendChild(i);
93 } 93 }
94 -}; 94 +}
95 95
96 export function setTitle(title: string, appTitle?: string) { 96 export function setTitle(title: string, appTitle?: string) {
97 if (title) { 97 if (title) {
src/utils/color.ts
@@ -5,10 +5,10 @@ @@ -5,10 +5,10 @@
5 * @param String color 十六进制颜色值 5 * @param String color 十六进制颜色值
6 * @return Boolean 6 * @return Boolean
7 */ 7 */
8 -export const isHexColor = function (color: string) { 8 +export function isHexColor(color: string) {
9 const reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/; 9 const reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
10 return reg.test(color); 10 return reg.test(color);
11 -}; 11 +}
12 12
13 /** 13 /**
14 * RGB 颜色值转换为 十六进制颜色值. 14 * RGB 颜色值转换为 十六进制颜色值.
@@ -19,18 +19,18 @@ export const isHexColor = function (color: string) { @@ -19,18 +19,18 @@ export const isHexColor = function (color: string) {
19 * @param g 19 * @param g
20 * @param b 20 * @param b
21 */ 21 */
22 -export const rgbToHex = function (r: number, g: number, b: number) { 22 +export function rgbToHex(r: number, g: number, b: number) {
23 // tslint:disable-next-line:no-bitwise 23 // tslint:disable-next-line:no-bitwise
24 const hex = ((r << 16) | (g << 8) | b).toString(16); 24 const hex = ((r << 16) | (g << 8) | b).toString(16);
25 return '#' + new Array(Math.abs(hex.length - 7)).join('0') + hex; 25 return '#' + new Array(Math.abs(hex.length - 7)).join('0') + hex;
26 -}; 26 +}
27 27
28 /** 28 /**
29 * Transform a HEX color to its RGB representation 29 * Transform a HEX color to its RGB representation
30 * @param {string} hex The color to transform 30 * @param {string} hex The color to transform
31 * @returns The RGB representation of the passed color 31 * @returns The RGB representation of the passed color
32 */ 32 */
33 -export const hexToRGB = function (hex: string) { 33 +export function hexToRGB(hex: string) {
34 let sHex = hex.toLowerCase(); 34 let sHex = hex.toLowerCase();
35 if (isHexColor(hex)) { 35 if (isHexColor(hex)) {
36 if (sHex.length === 4) { 36 if (sHex.length === 4) {
@@ -47,16 +47,16 @@ export const hexToRGB = function (hex: string) { @@ -47,16 +47,16 @@ export const hexToRGB = function (hex: string) {
47 return 'RGB(' + sColorChange.join(',') + ')'; 47 return 'RGB(' + sColorChange.join(',') + ')';
48 } 48 }
49 return sHex; 49 return sHex;
50 -}; 50 +}
51 51
52 -export const colorIsDark = (color: string) => { 52 +export function colorIsDark(color: string) {
53 if (!isHexColor(color)) return; 53 if (!isHexColor(color)) return;
54 const [r, g, b] = hexToRGB(color) 54 const [r, g, b] = hexToRGB(color)
55 .replace(/(?:\(|\)|rgb|RGB)*/g, '') 55 .replace(/(?:\(|\)|rgb|RGB)*/g, '')
56 .split(',') 56 .split(',')
57 .map((item) => Number(item)); 57 .map((item) => Number(item));
58 return r * 0.299 + g * 0.578 + b * 0.114 < 192; 58 return r * 0.299 + g * 0.578 + b * 0.114 < 192;
59 -}; 59 +}
60 60
61 /** 61 /**
62 * Darkens a HEX color given the passed percentage 62 * Darkens a HEX color given the passed percentage
@@ -64,14 +64,14 @@ export const colorIsDark = (color: string) =&gt; { @@ -64,14 +64,14 @@ export const colorIsDark = (color: string) =&gt; {
64 * @param {number} amount The amount to change the color by 64 * @param {number} amount The amount to change the color by
65 * @returns {string} The HEX representation of the processed color 65 * @returns {string} The HEX representation of the processed color
66 */ 66 */
67 -export const darken = (color: string, amount: number) => { 67 +export function darken(color: string, amount: number) {
68 color = color.indexOf('#') >= 0 ? color.substring(1, color.length) : color; 68 color = color.indexOf('#') >= 0 ? color.substring(1, color.length) : color;
69 amount = Math.trunc((255 * amount) / 100); 69 amount = Math.trunc((255 * amount) / 100);
70 return `#${subtractLight(color.substring(0, 2), amount)}${subtractLight( 70 return `#${subtractLight(color.substring(0, 2), amount)}${subtractLight(
71 color.substring(2, 4), 71 color.substring(2, 4),
72 amount 72 amount
73 )}${subtractLight(color.substring(4, 6), amount)}`; 73 )}${subtractLight(color.substring(4, 6), amount)}`;
74 -}; 74 +}
75 75
76 /** 76 /**
77 * Lightens a 6 char HEX color according to the passed percentage 77 * Lightens a 6 char HEX color according to the passed percentage
@@ -79,14 +79,14 @@ export const darken = (color: string, amount: number) =&gt; { @@ -79,14 +79,14 @@ export const darken = (color: string, amount: number) =&gt; {
79 * @param {number} amount The amount to change the color by 79 * @param {number} amount The amount to change the color by
80 * @returns {string} The processed color represented as HEX 80 * @returns {string} The processed color represented as HEX
81 */ 81 */
82 -export const lighten = (color: string, amount: number) => { 82 +export function lighten(color: string, amount: number) {
83 color = color.indexOf('#') >= 0 ? color.substring(1, color.length) : color; 83 color = color.indexOf('#') >= 0 ? color.substring(1, color.length) : color;
84 amount = Math.trunc((255 * amount) / 100); 84 amount = Math.trunc((255 * amount) / 100);
85 return `#${addLight(color.substring(0, 2), amount)}${addLight( 85 return `#${addLight(color.substring(0, 2), amount)}${addLight(
86 color.substring(2, 4), 86 color.substring(2, 4),
87 amount 87 amount
88 )}${addLight(color.substring(4, 6), amount)}`; 88 )}${addLight(color.substring(4, 6), amount)}`;
89 -}; 89 +}
90 90
91 /* Suma el porcentaje indicado a un color (RR, GG o BB) hexadecimal para aclararlo */ 91 /* Suma el porcentaje indicado a un color (RR, GG o BB) hexadecimal para aclararlo */
92 /** 92 /**
@@ -95,11 +95,11 @@ export const lighten = (color: string, amount: number) =&gt; { @@ -95,11 +95,11 @@ export const lighten = (color: string, amount: number) =&gt; {
95 * @param {number} amount The amount to change the color by 95 * @param {number} amount The amount to change the color by
96 * @returns {string} The processed part of the color 96 * @returns {string} The processed part of the color
97 */ 97 */
98 -const addLight = (color: string, amount: number) => { 98 +function addLight(color: string, amount: number) {
99 const cc = parseInt(color, 16) + amount; 99 const cc = parseInt(color, 16) + amount;
100 const c = cc > 255 ? 255 : cc; 100 const c = cc > 255 ? 255 : cc;
101 return c.toString(16).length > 1 ? c.toString(16) : `0${c.toString(16)}`; 101 return c.toString(16).length > 1 ? c.toString(16) : `0${c.toString(16)}`;
102 -}; 102 +}
103 103
104 /** 104 /**
105 * Calculates luminance of an rgb color 105 * Calculates luminance of an rgb color
@@ -107,33 +107,36 @@ const addLight = (color: string, amount: number) =&gt; { @@ -107,33 +107,36 @@ const addLight = (color: string, amount: number) =&gt; {
107 * @param {number} g green 107 * @param {number} g green
108 * @param {number} b blue 108 * @param {number} b blue
109 */ 109 */
110 -const luminanace = (r: number, g: number, b: number) => { 110 +function luminanace(r: number, g: number, b: number) {
111 const a = [r, g, b].map((v) => { 111 const a = [r, g, b].map((v) => {
112 v /= 255; 112 v /= 255;
113 return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4); 113 return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);
114 }); 114 });
115 return a[0] * 0.2126 + a[1] * 0.7152 + a[2] * 0.0722; 115 return a[0] * 0.2126 + a[1] * 0.7152 + a[2] * 0.0722;
116 -}; 116 +}
117 117
118 /** 118 /**
119 * Calculates contrast between two rgb colors 119 * Calculates contrast between two rgb colors
120 * @param {string} rgb1 rgb color 1 120 * @param {string} rgb1 rgb color 1
121 * @param {string} rgb2 rgb color 2 121 * @param {string} rgb2 rgb color 2
122 */ 122 */
123 -const contrast = (rgb1: string[], rgb2: number[]) =>  
124 - (luminanace(~~rgb1[0], ~~rgb1[1], ~~rgb1[2]) + 0.05) /  
125 - (luminanace(rgb2[0], rgb2[1], rgb2[2]) + 0.05); 123 +function contrast(rgb1: string[], rgb2: number[]) {
  124 + return (
  125 + (luminanace(~~rgb1[0], ~~rgb1[1], ~~rgb1[2]) + 0.05) /
  126 + (luminanace(rgb2[0], rgb2[1], rgb2[2]) + 0.05)
  127 + );
  128 +}
126 129
127 /** 130 /**
128 * Determines what the best text color is (black or white) based con the contrast with the background 131 * Determines what the best text color is (black or white) based con the contrast with the background
129 * @param hexColor - Last selected color by the user 132 * @param hexColor - Last selected color by the user
130 */ 133 */
131 -export const calculateBestTextColor = (hexColor: string) => { 134 +export function calculateBestTextColor(hexColor: string) {
132 const rgbColor = hexToRGB(hexColor.substring(1)); 135 const rgbColor = hexToRGB(hexColor.substring(1));
133 const contrastWithBlack = contrast(rgbColor.split(','), [0, 0, 0]); 136 const contrastWithBlack = contrast(rgbColor.split(','), [0, 0, 0]);
134 137
135 return contrastWithBlack >= 12 ? '#000000' : '#FFFFFF'; 138 return contrastWithBlack >= 12 ? '#000000' : '#FFFFFF';
136 -}; 139 +}
137 140
138 /** 141 /**
139 * Subtracts the indicated percentage to the R, G or B of a HEX color 142 * Subtracts the indicated percentage to the R, G or B of a HEX color
@@ -141,8 +144,8 @@ export const calculateBestTextColor = (hexColor: string) =&gt; { @@ -141,8 +144,8 @@ export const calculateBestTextColor = (hexColor: string) =&gt; {
141 * @param {number} amount The amount to change the color by 144 * @param {number} amount The amount to change the color by
142 * @returns {string} The processed part of the color 145 * @returns {string} The processed part of the color
143 */ 146 */
144 -const subtractLight = (color: string, amount: number) => { 147 +function subtractLight(color: string, amount: number) {
145 const cc = parseInt(color, 16) - amount; 148 const cc = parseInt(color, 16) - amount;
146 const c = cc < 0 ? 0 : cc; 149 const c = cc < 0 ? 0 : cc;
147 return c.toString(16).length > 1 ? c.toString(16) : `0${c.toString(16)}`; 150 return c.toString(16).length > 1 ? c.toString(16) : `0${c.toString(16)}`;
148 -}; 151 +}
src/utils/dateUtil.ts
@@ -14,7 +14,7 @@ export function formatToDate(date: moment.MomentInput = null, format = DATE_FORM @@ -14,7 +14,7 @@ export function formatToDate(date: moment.MomentInput = null, format = DATE_FORM
14 return moment(date).format(format); 14 return moment(date).format(format);
15 } 15 }
16 16
17 -export const formatAgo = (str: string | number) => { 17 +export function formatAgo(str: string | number) {
18 if (!str) return ''; 18 if (!str) return '';
19 const date = new Date(Number(str)); 19 const date = new Date(Number(str));
20 const time = new Date().getTime() - date.getTime(); // 现在的时间-传入的时间 = 相差的时间(单位 = 毫秒) 20 const time = new Date().getTime() - date.getTime(); // 现在的时间-传入的时间 = 相差的时间(单位 = 毫秒)
@@ -35,6 +35,6 @@ export const formatAgo = (str: string | number) =&gt; { @@ -35,6 +35,6 @@ export const formatAgo = (str: string | number) =&gt; {
35 } else { 35 } else {
36 return parseInt(String(time / 31536000000)) + '年前'; 36 return parseInt(String(time / 31536000000)) + '年前';
37 } 37 }
38 -}; 38 +}
39 39
40 export const dateUtil = moment; 40 export const dateUtil = moment;
src/utils/domUtils.ts
@@ -132,7 +132,7 @@ export function hackCss(attr: string, value: string) { @@ -132,7 +132,7 @@ export function hackCss(attr: string, value: string) {
132 } 132 }
133 133
134 /* istanbul ignore next */ 134 /* istanbul ignore next */
135 -export const on = function ( 135 +export function on(
136 element: Element | HTMLElement | Document | Window, 136 element: Element | HTMLElement | Document | Window,
137 event: string, 137 event: string,
138 handler: EventListenerOrEventListenerObject 138 handler: EventListenerOrEventListenerObject
@@ -140,10 +140,10 @@ export const on = function ( @@ -140,10 +140,10 @@ export const on = function (
140 if (element && event && handler) { 140 if (element && event && handler) {
141 element.addEventListener(event, handler, false); 141 element.addEventListener(event, handler, false);
142 } 142 }
143 -}; 143 +}
144 144
145 /* istanbul ignore next */ 145 /* istanbul ignore next */
146 -export const off = function ( 146 +export function off(
147 element: Element | HTMLElement | Document | Window, 147 element: Element | HTMLElement | Document | Window,
148 event: string, 148 event: string,
149 handler: Fn 149 handler: Fn
@@ -151,10 +151,10 @@ export const off = function ( @@ -151,10 +151,10 @@ export const off = function (
151 if (element && event && handler) { 151 if (element && event && handler) {
152 element.removeEventListener(event, handler, false); 152 element.removeEventListener(event, handler, false);
153 } 153 }
154 -}; 154 +}
155 155
156 /* istanbul ignore next */ 156 /* istanbul ignore next */
157 -export const once = function (el: HTMLElement, event: string, fn: EventListener): void { 157 +export function once(el: HTMLElement, event: string, fn: EventListener): void {
158 const listener = function (this: any, ...args: unknown[]) { 158 const listener = function (this: any, ...args: unknown[]) {
159 if (fn) { 159 if (fn) {
160 fn.apply(this, args); 160 fn.apply(this, args);
@@ -162,4 +162,4 @@ export const once = function (el: HTMLElement, event: string, fn: EventListener) @@ -162,4 +162,4 @@ export const once = function (el: HTMLElement, event: string, fn: EventListener)
162 off(el, event, listener); 162 off(el, event, listener);
163 }; 163 };
164 on(el, event, listener); 164 on(el, event, listener);
165 -}; 165 +}
src/utils/env.ts
1 import type { GlobEnvConfig } from '/@/types/config'; 1 import type { GlobEnvConfig } from '/@/types/config';
2 2
3 -export const getGlobEnvConfig = (): GlobEnvConfig => { 3 +export function getGlobEnvConfig(): GlobEnvConfig {
4 const env = import.meta.env; 4 const env = import.meta.env;
5 return (env as unknown) as GlobEnvConfig; 5 return (env as unknown) as GlobEnvConfig;
6 -}; 6 +}
7 7
8 /** 8 /**
9 * @description: 开发模式 9 * @description: 开发模式
@@ -20,25 +20,33 @@ export const prodMode = &#39;production&#39;; @@ -20,25 +20,33 @@ export const prodMode = &#39;production&#39;;
20 * @returns: 20 * @returns:
21 * @example: 21 * @example:
22 */ 22 */
23 -export const getEnv = (): string => import.meta.env.MODE; 23 +export function getEnv(): string {
  24 + return import.meta.env.MODE;
  25 +}
24 26
25 /** 27 /**
26 * @description: 是否是开发模式 28 * @description: 是否是开发模式
27 * @returns: 29 * @returns:
28 * @example: 30 * @example:
29 */ 31 */
30 -export const isDevMode = (): boolean => import.meta.env.DEV; 32 +export function isDevMode(): boolean {
  33 + return import.meta.env.DEV;
  34 +}
31 35
32 /** 36 /**
33 * @description: 是否是生产模式模式 37 * @description: 是否是生产模式模式
34 * @returns: 38 * @returns:
35 * @example: 39 * @example:
36 */ 40 */
37 -export const isProdMode = (): boolean => import.meta.env.PROD; 41 +export function isProdMode(): boolean {
  42 + return import.meta.env.PROD;
  43 +}
38 44
39 /** 45 /**
40 * @description: 是否开启mock 46 * @description: 是否开启mock
41 * @returns: 47 * @returns:
42 * @example: 48 * @example:
43 */ 49 */
44 -export const isUseMock = (): boolean => import.meta.env.VITE_USE_MOCK === 'true'; 50 +export function isUseMock(): boolean {
  51 + return import.meta.env.VITE_USE_MOCK === 'true';
  52 +}
src/utils/event/resizeEvent.ts
@@ -3,7 +3,7 @@ import ResizeObserver from &#39;resize-observer-polyfill&#39;; @@ -3,7 +3,7 @@ import ResizeObserver from &#39;resize-observer-polyfill&#39;;
3 const isServer = typeof window === 'undefined'; 3 const isServer = typeof window === 'undefined';
4 4
5 /* istanbul ignore next */ 5 /* istanbul ignore next */
6 -const resizeHandler = function (entries: any[]) { 6 +function resizeHandler(entries: any[]) {
7 for (const entry of entries) { 7 for (const entry of entries) {
8 const listeners = entry.target.__resizeListeners__ || []; 8 const listeners = entry.target.__resizeListeners__ || [];
9 if (listeners.length) { 9 if (listeners.length) {
@@ -12,10 +12,10 @@ const resizeHandler = function (entries: any[]) { @@ -12,10 +12,10 @@ const resizeHandler = function (entries: any[]) {
12 }); 12 });
13 } 13 }
14 } 14 }
15 -}; 15 +}
16 16
17 /* istanbul ignore next */ 17 /* istanbul ignore next */
18 -export const addResizeListener = function (element: any, fn: () => any) { 18 +export function addResizeListener(element: any, fn: () => any) {
19 if (isServer) return; 19 if (isServer) return;
20 if (!element.__resizeListeners__) { 20 if (!element.__resizeListeners__) {
21 element.__resizeListeners__ = []; 21 element.__resizeListeners__ = [];
@@ -23,13 +23,13 @@ export const addResizeListener = function (element: any, fn: () =&gt; any) { @@ -23,13 +23,13 @@ export const addResizeListener = function (element: any, fn: () =&gt; any) {
23 element.__ro__.observe(element); 23 element.__ro__.observe(element);
24 } 24 }
25 element.__resizeListeners__.push(fn); 25 element.__resizeListeners__.push(fn);
26 -}; 26 +}
27 27
28 /* istanbul ignore next */ 28 /* istanbul ignore next */
29 -export const removeResizeListener = function (element: any, fn: () => any) { 29 +export function removeResizeListener(element: any, fn: () => any) {
30 if (!element || !element.__resizeListeners__) return; 30 if (!element || !element.__resizeListeners__) return;
31 element.__resizeListeners__.splice(element.__resizeListeners__.indexOf(fn), 1); 31 element.__resizeListeners__.splice(element.__resizeListeners__.indexOf(fn), 1);
32 if (!element.__resizeListeners__.length) { 32 if (!element.__resizeListeners__.length) {
33 element.__ro__.disconnect(); 33 element.__ro__.disconnect();
34 } 34 }
35 -}; 35 +}
src/utils/event/triggerWindowResizeEvent.ts
@@ -4,6 +4,6 @@ @@ -4,6 +4,6 @@
4 export function triggerWindowResize() { 4 export function triggerWindowResize() {
5 const event = document.createEvent('HTMLEvents'); 5 const event = document.createEvent('HTMLEvents');
6 event.initEvent('resize', true, true); 6 event.initEvent('resize', true, true);
7 - (event as ChangeEvent).eventType = 'message'; 7 + (event as any).eventType = 'message';
8 window.dispatchEvent(event); 8 window.dispatchEvent(event);
9 } 9 }
src/utils/helper/envHelper.ts
@@ -4,6 +4,6 @@ import pkg from &#39;../../../package.json&#39;; @@ -4,6 +4,6 @@ import pkg from &#39;../../../package.json&#39;;
4 const globSetting = useGlobSetting(); 4 const globSetting = useGlobSetting();
5 5
6 // Generate cache key according to version 6 // Generate cache key according to version
7 -export const getStorageShortName = () => { 7 +export function getStorageShortName() {
8 return `${globSetting.shortName}__${getEnv()}${`__${pkg.version}`}__`.toUpperCase(); 8 return `${globSetting.shortName}__${getEnv()}${`__${pkg.version}`}__`.toUpperCase();
9 -}; 9 +}
src/utils/index.ts
@@ -85,3 +85,17 @@ export function getDynamicProps&lt;T, U&gt;(props: T): Partial&lt;U&gt; { @@ -85,3 +85,17 @@ export function getDynamicProps&lt;T, U&gt;(props: T): Partial&lt;U&gt; {
85 85
86 return ret as Partial<U>; 86 return ret as Partial<U>;
87 } 87 }
  88 +
  89 +export function getLastItem<T extends any>(list: T) {
  90 + if (Array.isArray(list)) {
  91 + return list.slice(-1)[0];
  92 + }
  93 +
  94 + if (list instanceof Set) {
  95 + return Array.from(list).slice(-1)[0];
  96 + }
  97 +
  98 + if (list instanceof Map) {
  99 + return Array.from(list.values()).slice(-1)[0];
  100 + }
  101 +}
src/utils/is.ts
@@ -4,17 +4,33 @@ export function is(val: unknown, type: string) { @@ -4,17 +4,33 @@ export function is(val: unknown, type: string) {
4 return toString.call(val) === `[object ${type}]`; 4 return toString.call(val) === `[object ${type}]`;
5 } 5 }
6 6
7 -export const isDef = <T = unknown>(val?: T): val is T => { 7 +export function isDef<T = unknown>(val?: T): val is T {
8 return typeof val !== 'undefined'; 8 return typeof val !== 'undefined';
9 -}; 9 +}
10 10
11 -export const isUnDef = <T = unknown>(val?: T): val is T => { 11 +export function isUnDef<T = unknown>(val?: T): val is T {
12 return !isDef(val); 12 return !isDef(val);
13 -}; 13 +}
14 14
15 -export const isObject = (val: any): val is Record<any, any> => { 15 +export function isObject(val: any): val is Record<any, any> {
16 return val !== null && is(val, 'Object'); 16 return val !== null && is(val, 'Object');
17 -}; 17 +}
  18 +
  19 +export function isEmpty<T = unknown>(val: T): val is T {
  20 + if (isArray(val) || isString(val)) {
  21 + return val.length === 0;
  22 + }
  23 +
  24 + if (val instanceof Map || val instanceof Set) {
  25 + return val.size === 0;
  26 + }
  27 +
  28 + if (isObject(val)) {
  29 + return Object.keys(val).length === 0;
  30 + }
  31 +
  32 + return false;
  33 +}
18 34
19 export function isDate(val: unknown): val is Date { 35 export function isDate(val: unknown): val is Date {
20 return is(val, 'Date'); 36 return is(val, 'Date');
@@ -40,7 +56,9 @@ export function isString(val: unknown): val is string { @@ -40,7 +56,9 @@ export function isString(val: unknown): val is string {
40 return is(val, 'String'); 56 return is(val, 'String');
41 } 57 }
42 58
43 -export const isFunction = (val: unknown): val is Function => typeof val === 'function'; 59 +export function isFunction(val: unknown): val is Function {
  60 + return typeof val === 'function';
  61 +}
44 62
45 export function isBoolean(val: unknown): val is boolean { 63 export function isBoolean(val: unknown): val is boolean {
46 return is(val, 'Boolean'); 64 return is(val, 'Boolean');
@@ -54,13 +72,13 @@ export function isArray(val: any): val is Array&lt;any&gt; { @@ -54,13 +72,13 @@ export function isArray(val: any): val is Array&lt;any&gt; {
54 return val && Array.isArray(val); 72 return val && Array.isArray(val);
55 } 73 }
56 74
57 -export const isWindow = (val: any): val is Window => { 75 +export function isWindow(val: any): val is Window {
58 return typeof window !== 'undefined' && is(val, 'Window'); 76 return typeof window !== 'undefined' && is(val, 'Window');
59 -}; 77 +}
60 78
61 -export const isElement = (val: unknown): val is Element => { 79 +export function isElement(val: unknown): val is Element {
62 return isObject(val) && !!val.tagName; 80 return isObject(val) && !!val.tagName;
63 -}; 81 +}
64 82
65 export const isServer = typeof window === 'undefined'; 83 export const isServer = typeof window === 'undefined';
66 84
@@ -70,17 +88,17 @@ export function isImageDom(o: Element) { @@ -70,17 +88,17 @@ export function isImageDom(o: Element) {
70 return o && ['IMAGE', 'IMG'].includes(o.tagName); 88 return o && ['IMAGE', 'IMG'].includes(o.tagName);
71 } 89 }
72 90
73 -export const isTextarea = (element: Element | null): element is HTMLTextAreaElement => { 91 +export function isTextarea(element: Element | null): element is HTMLTextAreaElement {
74 return element !== null && element.tagName.toLowerCase() === 'textarea'; 92 return element !== null && element.tagName.toLowerCase() === 'textarea';
75 -}; 93 +}
76 94
77 -export const isMobile = (): boolean => { 95 +export function isMobile(): boolean {
78 return !!navigator.userAgent.match( 96 return !!navigator.userAgent.match(
79 /(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i 97 /(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i
80 ); 98 );
81 -}; 99 +}
82 100
83 -export const isUrl = (path: string): boolean => { 101 +export function isUrl(path: string): boolean {
84 const reg = /(((^https?:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)$/; 102 const reg = /(((^https?:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)$/;
85 return reg.test(path); 103 return reg.test(path);
86 -}; 104 +}
src/utils/scrollbarWidth.ts deleted 100644 → 0
1 -import { isWindow } from '/@/utils/is';  
2 -  
3 -let scrollBarWidth: number;  
4 -  
5 -export default function (): number {  
6 - if (!isWindow) return 0;  
7 - if (scrollBarWidth !== undefined) return scrollBarWidth;  
8 -  
9 - const outer = document.createElement('div');  
10 - outer.className = 'scrollbar__wrap';  
11 - outer.style.visibility = 'hidden';  
12 - outer.style.width = '100px';  
13 - outer.style.position = 'absolute';  
14 - outer.style.top = '-9999px';  
15 - document.body.appendChild(outer);  
16 -  
17 - const widthNoScroll = outer.offsetWidth;  
18 - outer.style.overflow = 'scroll';  
19 -  
20 - const inner = document.createElement('div');  
21 - inner.style.width = '100%';  
22 - outer.appendChild(inner);  
23 -  
24 - const widthWithScroll = inner.offsetWidth;  
25 - const parentNode = outer.parentNode;  
26 - parentNode && parentNode.removeChild(outer);  
27 - scrollBarWidth = widthNoScroll - widthWithScroll;  
28 -  
29 - return scrollBarWidth;  
30 -}