gi-component 0.0.47 → 0.0.49
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.
- package/README.md +2 -0
- package/dist/components/flex/src/flex.vue.d.ts +1 -0
- package/dist/components/flex/src/type.d.ts +2 -0
- package/dist/components/page-layout/src/page-layout.vue.d.ts +3 -1
- package/dist/components/page-layout/src/type.d.ts +4 -0
- package/dist/components/page-layout/src/useAutoCollapse.d.ts +11 -0
- package/dist/gi.css +1 -1
- package/dist/index.es.js +115 -16
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/index.umd.js.map +1 -1
- package/package.json +1 -1
- package/packages/components/button/src/button.vue +1 -1
- package/packages/components/flex/src/flex.vue +15 -2
- package/packages/components/flex/src/type.ts +2 -0
- package/packages/components/page-layout/src/page-layout.vue +40 -7
- package/packages/components/page-layout/src/type.ts +4 -0
- package/packages/components/page-layout/src/useAutoCollapse.ts +88 -0
- package/packages/components/table/src/table.vue +1 -1
- package/packages/components/tabs/src/tabs.vue +1 -1
- package/packages/components/tag/src/tag.vue +1 -1
- package/packages/styles/index.scss +2 -2
package/package.json
CHANGED
|
@@ -15,12 +15,19 @@ const props = withDefaults(defineProps<FlexProps>(), {
|
|
|
15
15
|
wrap: false,
|
|
16
16
|
justify: 'normal',
|
|
17
17
|
align: 'normal',
|
|
18
|
-
flex: 'normal'
|
|
18
|
+
flex: 'normal',
|
|
19
|
+
full: false
|
|
19
20
|
})
|
|
20
21
|
|
|
21
22
|
const { b } = useBemClass()
|
|
22
23
|
|
|
23
|
-
const classNames = computed(() =>
|
|
24
|
+
const classNames = computed(() => {
|
|
25
|
+
const arr: string[] = [b('flex'), b(`flex__size--${props.gap}`)]
|
|
26
|
+
if (props.full) {
|
|
27
|
+
arr.push(b('flex--full'))
|
|
28
|
+
}
|
|
29
|
+
return arr
|
|
30
|
+
})
|
|
24
31
|
|
|
25
32
|
const SIZE_MAP = ['small', 'middle', 'large']
|
|
26
33
|
|
|
@@ -67,6 +74,12 @@ const style = computed<CSSProperties>(() => {
|
|
|
67
74
|
}
|
|
68
75
|
|
|
69
76
|
.#{a.$prefix}-flex {
|
|
77
|
+
&--full {
|
|
78
|
+
width: 100%;
|
|
79
|
+
height: 100%;
|
|
80
|
+
overflow: hidden;
|
|
81
|
+
}
|
|
82
|
+
|
|
70
83
|
&__size--small {
|
|
71
84
|
gap: 8px;
|
|
72
85
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<ElSplitter :class="getClass">
|
|
2
|
+
<ElSplitter ref="splitterRef" :class="getClass">
|
|
3
3
|
<ElSplitterPanel v-if="slots.left" v-model:size="size">
|
|
4
4
|
<div :class="b('page-layout__left')" :style="props.leftStyle">
|
|
5
5
|
<slot name="left"></slot>
|
|
@@ -27,14 +27,17 @@
|
|
|
27
27
|
<script lang="ts" setup>
|
|
28
28
|
import type { PageLayoutProps } from './type'
|
|
29
29
|
import { ElSplitter, ElSplitterPanel } from 'element-plus'
|
|
30
|
-
import { computed, ref, useSlots } from 'vue'
|
|
30
|
+
import { computed, onBeforeUnmount, ref, useSlots } from 'vue'
|
|
31
31
|
import { useBemClass } from '../../../hooks'
|
|
32
32
|
import SplitButton from './split-button.vue'
|
|
33
|
+
import { useAutoCollapse } from './useAutoCollapse'
|
|
33
34
|
|
|
34
35
|
const props = withDefaults(defineProps<PageLayoutProps>(), {
|
|
35
36
|
size: 270,
|
|
36
37
|
bordered: false,
|
|
37
38
|
collapse: true,
|
|
39
|
+
autoCollapse: false,
|
|
40
|
+
collapseBreakpoint: 850,
|
|
38
41
|
leftStyle: () => ({}),
|
|
39
42
|
headerStyle: () => ({}),
|
|
40
43
|
toolStyle: () => ({}),
|
|
@@ -50,8 +53,42 @@ defineSlots<{
|
|
|
50
53
|
|
|
51
54
|
const slots = useSlots()
|
|
52
55
|
const { b } = useBemClass()
|
|
56
|
+
const splitterRef = ref<InstanceType<typeof ElSplitter>>()
|
|
53
57
|
const size = ref(props.size)
|
|
54
58
|
const collapsing = ref(false)
|
|
59
|
+
let collapsingTimer: ReturnType<typeof setTimeout> | null = null
|
|
60
|
+
|
|
61
|
+
const COLLAPSE_TRANSITION_MS = 300
|
|
62
|
+
|
|
63
|
+
function setCollapsingSize(newSize: typeof size.value) {
|
|
64
|
+
if (collapsingTimer) {
|
|
65
|
+
clearTimeout(collapsingTimer)
|
|
66
|
+
}
|
|
67
|
+
collapsing.value = true
|
|
68
|
+
collapsingTimer = setTimeout(() => {
|
|
69
|
+
collapsing.value = false
|
|
70
|
+
collapsingTimer = null
|
|
71
|
+
}, COLLAPSE_TRANSITION_MS)
|
|
72
|
+
size.value = newSize
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const autoCollapseEnabled = props.collapse && props.autoCollapse && !!slots.left && !!props.collapseBreakpoint
|
|
76
|
+
|
|
77
|
+
useAutoCollapse({
|
|
78
|
+
splitterRef,
|
|
79
|
+
size,
|
|
80
|
+
enabled: autoCollapseEnabled,
|
|
81
|
+
collapseBreakpoint: props.collapseBreakpoint,
|
|
82
|
+
panelSize: () => props.size,
|
|
83
|
+
setCollapsingSize
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
onBeforeUnmount(() => {
|
|
87
|
+
if (collapsingTimer) {
|
|
88
|
+
clearTimeout(collapsingTimer)
|
|
89
|
+
collapsingTimer = null
|
|
90
|
+
}
|
|
91
|
+
})
|
|
55
92
|
|
|
56
93
|
const getClass = computed(() => {
|
|
57
94
|
const arr: string[] = [b('page-layout')]
|
|
@@ -71,11 +108,7 @@ const getClass = computed(() => {
|
|
|
71
108
|
})
|
|
72
109
|
|
|
73
110
|
function handleClick() {
|
|
74
|
-
|
|
75
|
-
setTimeout(() => {
|
|
76
|
-
collapsing.value = false
|
|
77
|
-
}, 300)
|
|
78
|
-
size.value = Number(size.value) > 30 ? 0 : props.size
|
|
111
|
+
setCollapsingSize(Number(size.value) > 30 ? 0 : props.size)
|
|
79
112
|
}
|
|
80
113
|
</script>
|
|
81
114
|
|
|
@@ -5,6 +5,10 @@ export interface PageLayoutProps {
|
|
|
5
5
|
size?: SplitterPanelProps['size']
|
|
6
6
|
bordered?: boolean
|
|
7
7
|
collapse?: boolean
|
|
8
|
+
/** 是否开启容器宽度自动折叠左侧面板 */
|
|
9
|
+
autoCollapse?: boolean
|
|
10
|
+
/** 容器宽度小于该值时自动折叠左侧面板,大于该值时自动展开(单位 px) */
|
|
11
|
+
collapseBreakpoint?: number
|
|
8
12
|
leftStyle?: CSSProperties
|
|
9
13
|
headerStyle?: CSSProperties
|
|
10
14
|
toolStyle?: CSSProperties
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import type { ElSplitter, SplitterPanelProps } from 'element-plus'
|
|
2
|
+
import type { Ref } from 'vue'
|
|
3
|
+
import { nextTick, onBeforeUnmount, onMounted } from 'vue'
|
|
4
|
+
|
|
5
|
+
const RESIZE_DEBOUNCE_MS = 150
|
|
6
|
+
|
|
7
|
+
export interface UseAutoCollapseOptions<TSize extends SplitterPanelProps['size'] = SplitterPanelProps['size']> {
|
|
8
|
+
splitterRef: Ref<InstanceType<typeof ElSplitter> | undefined>
|
|
9
|
+
size: Ref<TSize>
|
|
10
|
+
enabled: boolean
|
|
11
|
+
collapseBreakpoint: number
|
|
12
|
+
panelSize: () => TSize
|
|
13
|
+
setCollapsingSize: (newSize: TSize) => void
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function useAutoCollapse<TSize extends SplitterPanelProps['size']>(
|
|
17
|
+
options: UseAutoCollapseOptions<TSize>
|
|
18
|
+
) {
|
|
19
|
+
if (!options.enabled) {
|
|
20
|
+
return
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
let resizeObserver: ResizeObserver | null = null
|
|
24
|
+
let debounceTimer: ReturnType<typeof setTimeout> | null = null
|
|
25
|
+
|
|
26
|
+
function getSplitterWidth() {
|
|
27
|
+
const el = options.splitterRef.value?.$el as HTMLElement | undefined
|
|
28
|
+
return el?.clientWidth ?? 0
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function applyAutoCollapseWidth(width: number) {
|
|
32
|
+
const threshold = options.collapseBreakpoint
|
|
33
|
+
|
|
34
|
+
if (width < threshold && Number(options.size.value) > 30) {
|
|
35
|
+
options.setCollapsingSize(0 as TSize)
|
|
36
|
+
}
|
|
37
|
+
else if (width > threshold && Number(options.size.value) === 0) {
|
|
38
|
+
options.setCollapsingSize(options.panelSize())
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function debouncedApplyAutoCollapseWidth() {
|
|
43
|
+
if (debounceTimer) {
|
|
44
|
+
clearTimeout(debounceTimer)
|
|
45
|
+
}
|
|
46
|
+
debounceTimer = setTimeout(() => {
|
|
47
|
+
debounceTimer = null
|
|
48
|
+
applyAutoCollapseWidth(getSplitterWidth())
|
|
49
|
+
}, RESIZE_DEBOUNCE_MS)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function clearDebounceTimer() {
|
|
53
|
+
if (debounceTimer) {
|
|
54
|
+
clearTimeout(debounceTimer)
|
|
55
|
+
debounceTimer = null
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function bindResizeObserver() {
|
|
60
|
+
unbindResizeObserver()
|
|
61
|
+
|
|
62
|
+
const el = options.splitterRef.value?.$el as HTMLElement | undefined
|
|
63
|
+
if (!el || typeof ResizeObserver === 'undefined') {
|
|
64
|
+
return
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
resizeObserver = new ResizeObserver(() => {
|
|
68
|
+
debouncedApplyAutoCollapseWidth()
|
|
69
|
+
})
|
|
70
|
+
resizeObserver.observe(el)
|
|
71
|
+
applyAutoCollapseWidth(getSplitterWidth())
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function unbindResizeObserver() {
|
|
75
|
+
resizeObserver?.disconnect()
|
|
76
|
+
resizeObserver = null
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
onMounted(async () => {
|
|
80
|
+
await nextTick()
|
|
81
|
+
bindResizeObserver()
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
onBeforeUnmount(() => {
|
|
85
|
+
clearDebounceTimer()
|
|
86
|
+
unbindResizeObserver()
|
|
87
|
+
})
|
|
88
|
+
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<div :class="getClass">
|
|
3
3
|
<div :class="b('tabs__default')">
|
|
4
4
|
<slot>
|
|
5
|
-
<ElTabs v-model="model" :type="props.type" :stretch="props.stretch"
|
|
5
|
+
<ElTabs :key="props.type" v-model="model" :type="props.type" :stretch="props.stretch"
|
|
6
6
|
@tab-click="(p, e) => emits('tab-click', p, e)" @tab-change="emits('tab-change', $event as any)">
|
|
7
7
|
<ElTabPane v-for="item in props.options" :key="item.name" :name="item.name" :disabled="item?.disabled">
|
|
8
8
|
<template #label>
|
|
@@ -349,7 +349,7 @@ $tag-size-large-padding: 0 10px;
|
|
|
349
349
|
.#{a.$prefix}-tag__type--outline,
|
|
350
350
|
.#{a.$prefix}-tag__type--light-outline {
|
|
351
351
|
&.#{a.$prefix}-tag__color--info {
|
|
352
|
-
color: var(--el-color-
|
|
352
|
+
color: var(--el-text-color-primary);
|
|
353
353
|
}
|
|
354
354
|
}
|
|
355
355
|
</style>
|