@dataloop-ai/components 0.17.35 → 0.17.37
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/package.json +1 -1
- package/src/components/basic/DlButton/DlButton.vue +71 -2
- package/src/components/basic/DlGrid/DlGrid.vue +144 -0
- package/src/components/basic/DlGrid/index.ts +4 -0
- package/src/components/basic/DlGrid/types.ts +4 -0
- package/src/components/basic/DlWidget/DlWidget.vue +50 -41
- package/src/components/basic/DlWidget/index.ts +1 -3
- package/src/components/basic/DlWidget/utils.ts +63 -8
- package/src/components/basic/index.ts +1 -0
- package/src/components/compound/DlCharts/charts/DlBarChart/DlBarChart.vue +3 -0
- package/src/components/compound/DlCharts/charts/DlDoughnutChart/DlDoughnutChartWidget.vue +1 -2
- package/src/demos/DlAlertDemo.vue +14 -0
- package/src/demos/DlButtonDemo.vue +31 -4
- package/src/demos/DlGridDemo.vue +40 -0
- package/src/demos/DlWidgetDemo.vue +217 -61
- package/src/demos/index.ts +2 -0
- package/src/components/basic/DlWidget/DlGrid.vue +0 -33
- package/src/components/basic/DlWidget/DlGridRow.vue +0 -32
- package/src/utils/swapNodes.ts +0 -30
package/package.json
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
:disabled="disabled"
|
|
13
13
|
:style="[computedStyles]"
|
|
14
14
|
style="pointer-events: auto"
|
|
15
|
-
class="
|
|
15
|
+
:class="buttonClass"
|
|
16
16
|
@click="onClick"
|
|
17
17
|
@mousedown="onMouseDown"
|
|
18
18
|
>
|
|
@@ -74,6 +74,7 @@ import { v4 } from 'uuid'
|
|
|
74
74
|
import { ButtonColors } from './types'
|
|
75
75
|
import { transformOptions } from '../../shared/types'
|
|
76
76
|
import { stringStyleToRecord } from '../../../utils'
|
|
77
|
+
import { textTransform } from '../../../utils/string'
|
|
77
78
|
import { isString } from 'lodash'
|
|
78
79
|
|
|
79
80
|
export default defineComponent({
|
|
@@ -84,27 +85,66 @@ export default defineComponent({
|
|
|
84
85
|
},
|
|
85
86
|
|
|
86
87
|
props: {
|
|
88
|
+
/**
|
|
89
|
+
* The user will not be able to press on the button
|
|
90
|
+
*/
|
|
87
91
|
disabled: Boolean,
|
|
92
|
+
/**
|
|
93
|
+
* The color of the button
|
|
94
|
+
*/
|
|
88
95
|
color: {
|
|
89
96
|
type: String! as PropType<keyof typeof colorNames>,
|
|
90
97
|
default: ''
|
|
91
98
|
},
|
|
99
|
+
/**
|
|
100
|
+
* The button's padding is lowered and the white space shrinks
|
|
101
|
+
*/
|
|
92
102
|
dense: { type: Boolean, default: false },
|
|
103
|
+
/**
|
|
104
|
+
* The text content of the button
|
|
105
|
+
*/
|
|
93
106
|
label: { type: String, default: '' },
|
|
107
|
+
/**
|
|
108
|
+
* The color of the button's text
|
|
109
|
+
*/
|
|
94
110
|
textColor: { type: String!, default: '' },
|
|
95
111
|
colorsObject: {
|
|
96
112
|
type: Object as PropType<ButtonColors>,
|
|
97
113
|
default: null
|
|
98
114
|
},
|
|
115
|
+
/**
|
|
116
|
+
* The color of the icon inside the button
|
|
117
|
+
*/
|
|
99
118
|
iconColor: { type: String!, default: '' },
|
|
119
|
+
/** Padding inside the button */
|
|
100
120
|
padding: { type: String, default: '' },
|
|
121
|
+
/**
|
|
122
|
+
* The size of the button, it can be s,m,l or xl
|
|
123
|
+
*/
|
|
101
124
|
margin: { type: String, default: '0 auto' },
|
|
102
125
|
size: { type: String! as PropType<ButtonSizes>, default: 'm' },
|
|
126
|
+
/**
|
|
127
|
+
* The assigned color will fill the entirety of the button
|
|
128
|
+
*/
|
|
103
129
|
filled: { type: Boolean, default: true },
|
|
130
|
+
/** Makes the button rounded */
|
|
104
131
|
round: { type: Boolean, default: false },
|
|
132
|
+
/**
|
|
133
|
+
* The width of the button will take that of its container
|
|
134
|
+
*/
|
|
105
135
|
shaded: { type: Boolean, default: false },
|
|
106
136
|
fluid: Boolean,
|
|
137
|
+
/**
|
|
138
|
+
* The button will not have an outline
|
|
139
|
+
*/
|
|
107
140
|
flat: Boolean,
|
|
141
|
+
/**
|
|
142
|
+
* All the characters inside the button will be uppercase
|
|
143
|
+
*/
|
|
144
|
+
uppercase: Boolean,
|
|
145
|
+
/**
|
|
146
|
+
* The button will be transparent with a colored outline
|
|
147
|
+
*/
|
|
108
148
|
transform: {
|
|
109
149
|
type: String,
|
|
110
150
|
default: 'default',
|
|
@@ -112,10 +152,23 @@ export default defineComponent({
|
|
|
112
152
|
transformOptions.includes(value)
|
|
113
153
|
},
|
|
114
154
|
outlined: Boolean,
|
|
155
|
+
/**
|
|
156
|
+
* Doesn't allow the button's text to be wrapped along multiple rows
|
|
157
|
+
*/
|
|
115
158
|
noWrap: Boolean,
|
|
159
|
+
/**
|
|
160
|
+
* The name of the icon to go inside the button
|
|
161
|
+
*/
|
|
116
162
|
icon: { type: String, default: '' },
|
|
117
163
|
overflow: { type: Boolean, default: false, required: false },
|
|
164
|
+
/**
|
|
165
|
+
* The tooltip displayed when hovering over the button
|
|
166
|
+
*/
|
|
118
167
|
tooltip: { type: String, default: null, required: false },
|
|
168
|
+
/**
|
|
169
|
+
* The button will mentain the styles it has when it's pressed if this prop is active
|
|
170
|
+
*/
|
|
171
|
+
active: { type: Boolean, default: false, required: false },
|
|
119
172
|
styles: { type: [Object, String], default: null }
|
|
120
173
|
},
|
|
121
174
|
emits: ['click', 'mousedown'],
|
|
@@ -157,6 +210,12 @@ export default defineComponent({
|
|
|
157
210
|
this.label !== ''
|
|
158
211
|
)
|
|
159
212
|
},
|
|
213
|
+
buttonLabel(): string {
|
|
214
|
+
return textTransform(this.label)
|
|
215
|
+
},
|
|
216
|
+
buttonClass() {
|
|
217
|
+
return this.active ? 'dl-button active-class' : 'dl-button'
|
|
218
|
+
},
|
|
160
219
|
hasIcon(): boolean {
|
|
161
220
|
return typeof this.icon === 'string' && this.icon !== ''
|
|
162
221
|
},
|
|
@@ -383,7 +442,7 @@ export default defineComponent({
|
|
|
383
442
|
gap: var(--dl-button-content-gap, 7px);
|
|
384
443
|
}
|
|
385
444
|
|
|
386
|
-
.dl-
|
|
445
|
+
.dl-button-container.first-letter-capitalized {
|
|
387
446
|
&::first-letter,
|
|
388
447
|
& > *::first-letter {
|
|
389
448
|
text-transform: capitalize;
|
|
@@ -394,4 +453,14 @@ export default defineComponent({
|
|
|
394
453
|
display: inline-block;
|
|
395
454
|
width: var(--dl-button-container-width);
|
|
396
455
|
}
|
|
456
|
+
|
|
457
|
+
.active-class {
|
|
458
|
+
color: var(--dl-button-text-color-hover);
|
|
459
|
+
background-color: var(--dl-button-bg-hover);
|
|
460
|
+
border-color: var(--dl-button-border-hover);
|
|
461
|
+
& .dl-button-label {
|
|
462
|
+
transition: all ease-in 0.15s;
|
|
463
|
+
color: var(--dl-button-color-hover);
|
|
464
|
+
}
|
|
465
|
+
}
|
|
397
466
|
</style>
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
ref="grid"
|
|
4
|
+
:style="gridStyles"
|
|
5
|
+
:class="gridClass"
|
|
6
|
+
>
|
|
7
|
+
<slot />
|
|
8
|
+
</div>
|
|
9
|
+
</template>
|
|
10
|
+
|
|
11
|
+
<script lang="ts">
|
|
12
|
+
import { defineComponent, PropType } from 'vue-demi'
|
|
13
|
+
import {
|
|
14
|
+
getGridTemplate,
|
|
15
|
+
getElementAbove,
|
|
16
|
+
findIndexInMatrix,
|
|
17
|
+
swapElemensInMatrix,
|
|
18
|
+
isCustomEvent
|
|
19
|
+
} from '../DlWidget/utils'
|
|
20
|
+
|
|
21
|
+
export default defineComponent({
|
|
22
|
+
model: {
|
|
23
|
+
prop: 'modelValue',
|
|
24
|
+
event: 'update:modelValue'
|
|
25
|
+
},
|
|
26
|
+
props: {
|
|
27
|
+
modelValue: {
|
|
28
|
+
type: Array as PropType<number[][]>,
|
|
29
|
+
default: null
|
|
30
|
+
},
|
|
31
|
+
rowGap: {
|
|
32
|
+
type: String,
|
|
33
|
+
default: '10px'
|
|
34
|
+
},
|
|
35
|
+
columnGap: {
|
|
36
|
+
type: String,
|
|
37
|
+
default: '10px'
|
|
38
|
+
},
|
|
39
|
+
maxElementsPerRow: {
|
|
40
|
+
type: Number,
|
|
41
|
+
default: 3
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
emits: ['update:modelValue'],
|
|
45
|
+
computed: {
|
|
46
|
+
gridStyles(): object {
|
|
47
|
+
return {
|
|
48
|
+
'--row-gap': this.rowGap,
|
|
49
|
+
'--column-gap': this.columnGap
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
gridClass(): string {
|
|
53
|
+
return this.modelValue
|
|
54
|
+
? 'dl-grid-wrapper__grid'
|
|
55
|
+
: 'dl-grid-wrapper__flex'
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
watch: {
|
|
59
|
+
modelValue: {
|
|
60
|
+
handler(val) {
|
|
61
|
+
this.$nextTick(() => {
|
|
62
|
+
if (val) this.applyGridElementStyles()
|
|
63
|
+
})
|
|
64
|
+
},
|
|
65
|
+
immediate: true
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
mounted() {
|
|
69
|
+
Array.from((this.$refs.grid as HTMLElement).children).forEach(
|
|
70
|
+
(element: Element, index: number) => {
|
|
71
|
+
(element as HTMLElement).dataset.index = `${index}`
|
|
72
|
+
}
|
|
73
|
+
)
|
|
74
|
+
},
|
|
75
|
+
methods: {
|
|
76
|
+
applyGridElementStyles() {
|
|
77
|
+
if (!this.modelValue) return
|
|
78
|
+
const gridElements = Array.from(
|
|
79
|
+
(this.$refs.grid as HTMLElement).children
|
|
80
|
+
)
|
|
81
|
+
const gridTemplate = getGridTemplate(this.modelValue)
|
|
82
|
+
if (gridElements.length !== gridTemplate.length) return
|
|
83
|
+
|
|
84
|
+
const order = this.modelValue.flat()
|
|
85
|
+
gridElements.forEach((element: Element, index: number) => {
|
|
86
|
+
const orderIndex =
|
|
87
|
+
order.findIndex((nr: number) => nr === index + 1) + 1
|
|
88
|
+
const htmlElement = element as HTMLElement
|
|
89
|
+
htmlElement.style.order = `${orderIndex}`
|
|
90
|
+
htmlElement.style.gridColumn = gridTemplate[orderIndex - 1]
|
|
91
|
+
htmlElement.addEventListener('change-position', (e) => {
|
|
92
|
+
if (!isCustomEvent(e)) return
|
|
93
|
+
this.changePosition(e)
|
|
94
|
+
})
|
|
95
|
+
})
|
|
96
|
+
},
|
|
97
|
+
changePosition(e: CustomEvent) {
|
|
98
|
+
if (!this.modelValue) return
|
|
99
|
+
const side = e.detail.side
|
|
100
|
+
const className = (this.$refs.grid as HTMLElement).children[0]
|
|
101
|
+
.classList[0]
|
|
102
|
+
const sourceIndex =
|
|
103
|
+
parseInt(
|
|
104
|
+
getElementAbove(e.detail.source, className).dataset.index
|
|
105
|
+
) + 1
|
|
106
|
+
const targetIndex =
|
|
107
|
+
parseInt(
|
|
108
|
+
getElementAbove(e.detail.target, className).dataset.index
|
|
109
|
+
) + 1
|
|
110
|
+
const sourceMatrixIndex = findIndexInMatrix(
|
|
111
|
+
this.modelValue,
|
|
112
|
+
sourceIndex
|
|
113
|
+
)
|
|
114
|
+
const targetMatrixIndex = findIndexInMatrix(
|
|
115
|
+
this.modelValue,
|
|
116
|
+
targetIndex
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
const newLayout = swapElemensInMatrix(
|
|
120
|
+
this.modelValue,
|
|
121
|
+
sourceMatrixIndex,
|
|
122
|
+
targetMatrixIndex,
|
|
123
|
+
side,
|
|
124
|
+
this.maxElementsPerRow
|
|
125
|
+
)
|
|
126
|
+
this.$emit('update:modelValue', newLayout)
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
})
|
|
130
|
+
</script>
|
|
131
|
+
|
|
132
|
+
<style lang="scss" scoped>
|
|
133
|
+
.dl-grid-wrapper {
|
|
134
|
+
&__grid {
|
|
135
|
+
display: grid;
|
|
136
|
+
row-gap: var(--row-gap);
|
|
137
|
+
column-gap: var(--column-gap);
|
|
138
|
+
}
|
|
139
|
+
&__flex {
|
|
140
|
+
display: flex;
|
|
141
|
+
flex-wrap: wrap;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
</style>
|
|
@@ -7,18 +7,16 @@
|
|
|
7
7
|
:id="uuid"
|
|
8
8
|
ref="widget"
|
|
9
9
|
:class="widgetStyles"
|
|
10
|
+
@mouseenter="handleVisibleDragIcon(true)"
|
|
11
|
+
@mouseleave="handleVisibleDragIcon(false)"
|
|
10
12
|
>
|
|
11
|
-
<div
|
|
12
|
-
class="dl-widget__header"
|
|
13
|
-
@mouseenter="visibleDragIcon = true"
|
|
14
|
-
@mouseleave="visibleDragIcon = false"
|
|
15
|
-
>
|
|
13
|
+
<div class="dl-widget__header">
|
|
16
14
|
<div class="dl-widget__header--titles">
|
|
17
15
|
<slot name="header" />
|
|
18
16
|
</div>
|
|
19
17
|
<dl-icon
|
|
20
18
|
:style="`visibility: ${
|
|
21
|
-
visibleDragIcon ? 'visible' : 'hidden'
|
|
19
|
+
visibleDragIcon && !isDragging ? 'visible' : 'hidden'
|
|
22
20
|
}`"
|
|
23
21
|
class="dl-widget__header--drag-icon"
|
|
24
22
|
icon="icon-dl-drag"
|
|
@@ -47,14 +45,7 @@
|
|
|
47
45
|
import { v4 } from 'uuid'
|
|
48
46
|
import { defineComponent } from 'vue-demi'
|
|
49
47
|
import { DlIcon } from '../../essential'
|
|
50
|
-
import {
|
|
51
|
-
getElementAbove,
|
|
52
|
-
addMouseEnter,
|
|
53
|
-
removeMouseEnter,
|
|
54
|
-
setFlexBasis,
|
|
55
|
-
insertAfter
|
|
56
|
-
} from './utils'
|
|
57
|
-
import { swapNodes } from '../../../utils/swapNodes'
|
|
48
|
+
import { getElementAbove, addMouseEnter, removeMouseEnter } from './utils'
|
|
58
49
|
|
|
59
50
|
export default defineComponent({
|
|
60
51
|
name: 'DlWidget',
|
|
@@ -78,20 +69,20 @@ export default defineComponent({
|
|
|
78
69
|
return `${this.isDragging ? 'dl-widget__drag' : 'dl-widget'}`
|
|
79
70
|
}
|
|
80
71
|
},
|
|
81
|
-
mounted() {
|
|
82
|
-
setFlexBasis()
|
|
83
|
-
},
|
|
84
72
|
methods: {
|
|
85
73
|
startDragging(e: MouseEvent) {
|
|
86
74
|
this.isDragging = true
|
|
75
|
+
document.body.style.cursor = 'grabbing'
|
|
87
76
|
this.draggedWidget = getElementAbove(
|
|
88
77
|
e.target as HTMLElement,
|
|
89
78
|
'dl-widget'
|
|
90
79
|
)
|
|
91
80
|
if (this.draggedWidget) {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
81
|
+
const clone = this.$refs.clone as HTMLElement
|
|
82
|
+
clone.appendChild(this.draggedWidget.cloneNode(true))
|
|
83
|
+
clone.style.visibility = 'visible'
|
|
84
|
+
clone.style.width = `${this.draggedWidget.offsetWidth}px`
|
|
85
|
+
clone.style.height = `${this.draggedWidget.offsetHeight}px`
|
|
95
86
|
}
|
|
96
87
|
|
|
97
88
|
const sourceCanvas = this.draggedWidget?.querySelector('canvas')
|
|
@@ -118,13 +109,20 @@ export default defineComponent({
|
|
|
118
109
|
},
|
|
119
110
|
stopDragging(e: MouseEvent) {
|
|
120
111
|
this.isDragging = false
|
|
121
|
-
|
|
112
|
+
document.body.style.cursor = 'default'
|
|
113
|
+
const clone = this.$refs.clone as HTMLElement
|
|
114
|
+
clone.style.visibility = 'hidden'
|
|
115
|
+
clone.innerHTML = ''
|
|
122
116
|
const target = getElementAbove(e.target as HTMLElement, 'dl-widget')
|
|
117
|
+
const change = {
|
|
118
|
+
source: this.draggedWidget,
|
|
119
|
+
target
|
|
120
|
+
}
|
|
123
121
|
if (target && this.draggedWidget) {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
target
|
|
122
|
+
const event = new CustomEvent('change-position', {
|
|
123
|
+
detail: change
|
|
127
124
|
})
|
|
125
|
+
;(this.$refs.wrapper as HTMLElement).dispatchEvent(event)
|
|
128
126
|
}
|
|
129
127
|
window.removeEventListener('mousemove', this.moveClone)
|
|
130
128
|
window.removeEventListener('mouseup', this.stopDragging)
|
|
@@ -148,30 +146,26 @@ export default defineComponent({
|
|
|
148
146
|
this.handleMouseInsideWidget
|
|
149
147
|
)
|
|
150
148
|
})
|
|
151
|
-
this.timer = setTimeout(this.insertWidget,
|
|
149
|
+
this.timer = setTimeout(this.insertWidget, 200)
|
|
152
150
|
},
|
|
153
151
|
insertWidget() {
|
|
154
152
|
const targetWidget = getElementAbove(
|
|
155
153
|
this.hoveredWidget,
|
|
156
154
|
'widget-wrapper'
|
|
157
155
|
)
|
|
158
|
-
const
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
targetWidget
|
|
168
|
-
)
|
|
169
|
-
}
|
|
156
|
+
const event = new CustomEvent('change-position', {
|
|
157
|
+
detail: {
|
|
158
|
+
source: this.$refs.wrapper,
|
|
159
|
+
target: targetWidget,
|
|
160
|
+
side: this.isLeftSide ? 'left' : 'right'
|
|
161
|
+
}
|
|
162
|
+
})
|
|
163
|
+
;(this.$refs.wrapper as HTMLElement).dispatchEvent(event)
|
|
164
|
+
window.clearTimeout(this.timer)
|
|
170
165
|
this.hoveredWidget.removeEventListener(
|
|
171
166
|
'mousemove',
|
|
172
167
|
this.handleMouseInsideWidget
|
|
173
168
|
)
|
|
174
|
-
setFlexBasis()
|
|
175
169
|
},
|
|
176
170
|
handleMouseInsideWidget(e: MouseEvent) {
|
|
177
171
|
const mouseOffsetInside = e.clientX - this.hoveredWidget.offsetLeft
|
|
@@ -181,6 +175,11 @@ export default defineComponent({
|
|
|
181
175
|
clearTimeout(this.timer)
|
|
182
176
|
this.handleMouseEnter(e)
|
|
183
177
|
}
|
|
178
|
+
},
|
|
179
|
+
handleVisibleDragIcon(val: boolean) {
|
|
180
|
+
if (!document.querySelector('.drag-clone').innerHTML.toString()) {
|
|
181
|
+
this.visibleDragIcon = val
|
|
182
|
+
}
|
|
184
183
|
}
|
|
185
184
|
}
|
|
186
185
|
})
|
|
@@ -200,7 +199,7 @@ export default defineComponent({
|
|
|
200
199
|
|
|
201
200
|
&--drag-icon {
|
|
202
201
|
flex-grow: 1;
|
|
203
|
-
cursor:
|
|
202
|
+
cursor: grab;
|
|
204
203
|
|
|
205
204
|
&::v-deep .dl-icon {
|
|
206
205
|
transform: rotate(90deg) !important;
|
|
@@ -223,7 +222,17 @@ export default defineComponent({
|
|
|
223
222
|
}
|
|
224
223
|
|
|
225
224
|
&__drag {
|
|
226
|
-
|
|
225
|
+
position: relative;
|
|
226
|
+
&::after {
|
|
227
|
+
content: '';
|
|
228
|
+
position: absolute;
|
|
229
|
+
width: 100%;
|
|
230
|
+
height: 100%;
|
|
231
|
+
top: 0;
|
|
232
|
+
left: 0;
|
|
233
|
+
background: var(--dl-color-separator);
|
|
234
|
+
border-radius: 5px;
|
|
235
|
+
}
|
|
227
236
|
}
|
|
228
237
|
}
|
|
229
238
|
|
|
@@ -236,6 +245,6 @@ export default defineComponent({
|
|
|
236
245
|
.widget-wrapper {
|
|
237
246
|
flex-basis: var(--widget-flex-basis);
|
|
238
247
|
margin: var(--row-gap) var(--column-gap);
|
|
239
|
-
|
|
248
|
+
padding: 15px;
|
|
240
249
|
}
|
|
241
250
|
</style>
|
|
@@ -1,3 +1,30 @@
|
|
|
1
|
+
import { cloneDeep } from 'lodash'
|
|
2
|
+
|
|
3
|
+
export function leastCommonMultiple(arr: number[]) {
|
|
4
|
+
if (!arr) return
|
|
5
|
+
const gcd = (a: number, b: number): number => (a ? gcd(b % a, a) : b)
|
|
6
|
+
const lcm = (a: number, b: number): number => (a * b) / gcd(a, b)
|
|
7
|
+
return arr.reduce(lcm)
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function getGridTemplate(layout: number[][]) {
|
|
11
|
+
if (!layout) return
|
|
12
|
+
const flatLayout = layout.map((el) => el.length)
|
|
13
|
+
const template = []
|
|
14
|
+
const lcm = leastCommonMultiple(flatLayout)
|
|
15
|
+
for (let i = 0; i < flatLayout.length; i++) {
|
|
16
|
+
const columns = flatLayout[i]
|
|
17
|
+
let columnTrack = 1
|
|
18
|
+
for (let j = 0; j < columns; j++) {
|
|
19
|
+
let gridSpan = lcm / columns
|
|
20
|
+
template.push(`${columnTrack} / ${gridSpan + columnTrack}`)
|
|
21
|
+
columnTrack += gridSpan
|
|
22
|
+
gridSpan += gridSpan
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return template
|
|
26
|
+
}
|
|
27
|
+
|
|
1
28
|
export function getElementAbove(el: HTMLElement, className: string) {
|
|
2
29
|
//@ts-ignore
|
|
3
30
|
for (; el && el !== document; el = el.parentNode) {
|
|
@@ -22,16 +49,44 @@ export function removeMouseEnter(
|
|
|
22
49
|
})
|
|
23
50
|
}
|
|
24
51
|
|
|
25
|
-
export function
|
|
26
|
-
|
|
27
|
-
(
|
|
28
|
-
|
|
29
|
-
widget.style.flexBasis = `${100 / row.children.length}%`
|
|
30
|
-
})
|
|
52
|
+
export function findIndexInMatrix(matrix: number[][], nr: number) {
|
|
53
|
+
for (let i = 0; i < matrix.length; i++) {
|
|
54
|
+
for (let j = 0; j < matrix[i].length; j++) {
|
|
55
|
+
if (matrix[i][j] === nr) return { row: i, column: j }
|
|
31
56
|
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function swapElemensInMatrix(
|
|
61
|
+
layout: number[][],
|
|
62
|
+
sourceIndex: any,
|
|
63
|
+
targetIndex: any,
|
|
64
|
+
side: string,
|
|
65
|
+
maxElements: number
|
|
66
|
+
) {
|
|
67
|
+
if (targetIndex.column === sourceIndex.column + 1 && side === 'left')
|
|
68
|
+
return layout
|
|
69
|
+
const newLayout = cloneDeep(layout)
|
|
70
|
+
|
|
71
|
+
const removedElement = newLayout[sourceIndex.row].splice(
|
|
72
|
+
sourceIndex.column,
|
|
73
|
+
1
|
|
32
74
|
)
|
|
75
|
+
newLayout[targetIndex.row].splice(
|
|
76
|
+
side === 'right' ? targetIndex.column + 1 : targetIndex.column,
|
|
77
|
+
0,
|
|
78
|
+
removedElement[0]
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
return isTooLarge(newLayout, maxElements) ? layout : newLayout
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function isTooLarge(layout: number[][], max: number) {
|
|
85
|
+
const lengths = layout.map((row) => row.length)
|
|
86
|
+
const highest = Math.max(...lengths)
|
|
87
|
+
return highest > max
|
|
33
88
|
}
|
|
34
89
|
|
|
35
|
-
export function
|
|
36
|
-
|
|
90
|
+
export function isCustomEvent(event: Event): event is CustomEvent {
|
|
91
|
+
return 'detail' in event
|
|
37
92
|
}
|
|
@@ -225,6 +225,9 @@ export default defineComponent({
|
|
|
225
225
|
if (event.type !== 'mousemove') {
|
|
226
226
|
return
|
|
227
227
|
}
|
|
228
|
+
const hover = !!document.querySelector('.drag-clone')
|
|
229
|
+
chartJS.options.plugins.tooltip.enabled = !hover
|
|
230
|
+
if (hover) return
|
|
228
231
|
if (
|
|
229
232
|
items.length === 0 ||
|
|
230
233
|
chartJS.getElementsAtEventForMode(
|
|
@@ -26,14 +26,13 @@
|
|
|
26
26
|
import { defineComponent, PropType } from 'vue-demi'
|
|
27
27
|
import DlDoughnutChart from './DlDoughnutChart.vue'
|
|
28
28
|
import { TDoughnutChartData } from './types/TDoughnutChartData'
|
|
29
|
-
import { DlWidget,
|
|
29
|
+
import { DlWidget, DlGrid } from '../../../../basic'
|
|
30
30
|
|
|
31
31
|
export default defineComponent({
|
|
32
32
|
name: 'DlDoughnutChartWidget',
|
|
33
33
|
components: {
|
|
34
34
|
DlDoughnutChart,
|
|
35
35
|
DlGrid,
|
|
36
|
-
DlGridRow,
|
|
37
36
|
DlWidget
|
|
38
37
|
},
|
|
39
38
|
props: {
|
|
@@ -59,6 +59,20 @@
|
|
|
59
59
|
>
|
|
60
60
|
Lorem ipsum dolor sit amet, consectetur adipisicing elit.
|
|
61
61
|
</DlAlert>
|
|
62
|
+
<dl-alert
|
|
63
|
+
style="margin-top: 20px"
|
|
64
|
+
fluid
|
|
65
|
+
type="warning"
|
|
66
|
+
>
|
|
67
|
+
this is an annoying message with link, this is an annoying message
|
|
68
|
+
with linkthis is an annoying message with linkthis is an annoying
|
|
69
|
+
message with linkthis is an annoying message with linkthis is an
|
|
70
|
+
annoying message with linkthis is an annoying message with linkthis
|
|
71
|
+
is an annoying message with link
|
|
72
|
+
<span>
|
|
73
|
+
Please
|
|
74
|
+
<dl-link color="dl-color-link">Contact us</dl-link>.</span>
|
|
75
|
+
</dl-alert>
|
|
62
76
|
</div>
|
|
63
77
|
</template>
|
|
64
78
|
|
|
@@ -194,6 +194,33 @@
|
|
|
194
194
|
Disabled
|
|
195
195
|
</DlButton>
|
|
196
196
|
</div>
|
|
197
|
+
<div
|
|
198
|
+
style="
|
|
199
|
+
display: flex;
|
|
200
|
+
justify-content: center;
|
|
201
|
+
flex-direction: column;
|
|
202
|
+
"
|
|
203
|
+
>
|
|
204
|
+
<h3>Button keeping its active state with menu</h3>
|
|
205
|
+
<dl-button
|
|
206
|
+
:active="activeButtonState"
|
|
207
|
+
@click="activeButtonState = !activeButtonState"
|
|
208
|
+
>
|
|
209
|
+
{{ activeButtonState ? 'Close' : 'Open' }}
|
|
210
|
+
<dl-menu
|
|
211
|
+
:offset="[0, 5]"
|
|
212
|
+
anchor="bottom middle"
|
|
213
|
+
self="top middle"
|
|
214
|
+
:model-value="!activeButtonState"
|
|
215
|
+
>
|
|
216
|
+
<div
|
|
217
|
+
style="width: 100px; height: 100px; text-align: center"
|
|
218
|
+
>
|
|
219
|
+
Menu
|
|
220
|
+
</div>
|
|
221
|
+
</dl-menu>
|
|
222
|
+
</dl-button>
|
|
223
|
+
</div>
|
|
197
224
|
<div>
|
|
198
225
|
<h3>With badge</h3>
|
|
199
226
|
|
|
@@ -261,10 +288,9 @@
|
|
|
261
288
|
</template>
|
|
262
289
|
|
|
263
290
|
<script lang="ts">
|
|
264
|
-
import { defineComponent, reactive } from 'vue-demi'
|
|
265
|
-
import { DlButton, DlBadge, DlIcon } from '../components'
|
|
291
|
+
import { defineComponent, reactive, ref } from 'vue-demi'
|
|
292
|
+
import { DlButton, DlBadge, DlIcon, DlMenu } from '../components'
|
|
266
293
|
import { ButtonSizes } from '../components/basic/DlButton/utils'
|
|
267
|
-
import DlMenu from '../components/essential/DlMenu/DlMenu.vue'
|
|
268
294
|
import DlList from '../components/essential/DlList/DlList.vue'
|
|
269
295
|
import DlListItem from '../components/basic/DlListItem/DlListItem.vue'
|
|
270
296
|
|
|
@@ -280,9 +306,10 @@ export default defineComponent({
|
|
|
280
306
|
},
|
|
281
307
|
setup() {
|
|
282
308
|
const buttons = reactive<ButtonSizes[]>(['s', 'm', 'l', 'xl'])
|
|
309
|
+
const activeButtonState = ref(false)
|
|
283
310
|
|
|
284
311
|
const log = (e: Event) => console.log(e)
|
|
285
|
-
return { buttons, log }
|
|
312
|
+
return { buttons, log, activeButtonState }
|
|
286
313
|
}
|
|
287
314
|
})
|
|
288
315
|
</script>
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="container">
|
|
3
|
+
<dl-grid>
|
|
4
|
+
<img
|
|
5
|
+
v-for="(a, index) in 10"
|
|
6
|
+
:key="index"
|
|
7
|
+
class="grid-image"
|
|
8
|
+
:src="getRandomImg()"
|
|
9
|
+
>
|
|
10
|
+
</dl-grid>
|
|
11
|
+
</div>
|
|
12
|
+
</template>
|
|
13
|
+
|
|
14
|
+
<script lang="ts">
|
|
15
|
+
import { defineComponent } from 'vue-demi'
|
|
16
|
+
import { DlGrid } from '../components/'
|
|
17
|
+
|
|
18
|
+
const getRandomImg = () => {
|
|
19
|
+
const random = Math.floor(Math.random() * 3) + 1
|
|
20
|
+
const link = `https://picsum.photos/${random * 100}/${
|
|
21
|
+
random * 100
|
|
22
|
+
}?random=${random}`
|
|
23
|
+
return link
|
|
24
|
+
}
|
|
25
|
+
export default defineComponent({
|
|
26
|
+
components: {
|
|
27
|
+
DlGrid
|
|
28
|
+
},
|
|
29
|
+
setup() {
|
|
30
|
+
return { getRandomImg }
|
|
31
|
+
}
|
|
32
|
+
})
|
|
33
|
+
</script>
|
|
34
|
+
|
|
35
|
+
<style lang="scss" scoped>
|
|
36
|
+
.grid-image {
|
|
37
|
+
border: 2px solid var(--dl-color-darker);
|
|
38
|
+
margin: 5px;
|
|
39
|
+
}
|
|
40
|
+
</style>
|
|
@@ -1,11 +1,149 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<div class="options">
|
|
4
|
+
<div class="select-layout">
|
|
5
|
+
<select
|
|
6
|
+
class="select-layout__input"
|
|
7
|
+
@change="selectLayout"
|
|
8
|
+
>
|
|
9
|
+
<option
|
|
10
|
+
v-for="(layout, index) in layouts"
|
|
11
|
+
:key="index"
|
|
12
|
+
:value="index"
|
|
13
|
+
>
|
|
14
|
+
{{ layout.name }}
|
|
15
|
+
</option>
|
|
16
|
+
</select>
|
|
17
|
+
<button
|
|
18
|
+
class="select-layout__button"
|
|
19
|
+
@mousedown="saveLayout"
|
|
20
|
+
>
|
|
21
|
+
Save
|
|
22
|
+
</button>
|
|
23
|
+
<span class="select-layout__info">{{ hasBeenSaved }}</span>
|
|
24
|
+
</div>
|
|
25
|
+
<div class="widgets-per-row">
|
|
26
|
+
<span class="widgets-per-row__label"> Widgets per row: </span>
|
|
27
|
+
<input
|
|
28
|
+
v-model="widgetsPerRow"
|
|
29
|
+
class="widgets-per-row__input"
|
|
30
|
+
type="number"
|
|
31
|
+
>
|
|
32
|
+
</div>
|
|
33
|
+
</div>
|
|
34
|
+
<dl-grid
|
|
35
|
+
v-model="layout"
|
|
36
|
+
:max-elements-per-row="widgetsPerRow"
|
|
37
|
+
>
|
|
38
|
+
<dl-widget>
|
|
39
|
+
<template #header>
|
|
40
|
+
<span>Widget 1</span>
|
|
41
|
+
<span style="font-size: 12px; color: gray">Subtitle</span>
|
|
42
|
+
</template>
|
|
43
|
+
<template #content>
|
|
44
|
+
<dl-bar-chart
|
|
45
|
+
:legend-props="legendProps"
|
|
46
|
+
:data="data"
|
|
47
|
+
:options="options"
|
|
48
|
+
:items-in-view="8"
|
|
49
|
+
/>
|
|
50
|
+
</template>
|
|
51
|
+
<template #menu>
|
|
52
|
+
<div class="menu-icons">
|
|
53
|
+
<dl-icon
|
|
54
|
+
size="m"
|
|
55
|
+
icon="icon-dl-settings"
|
|
56
|
+
/>
|
|
57
|
+
<dl-icon
|
|
58
|
+
size="m"
|
|
59
|
+
icon="icon-dl-download"
|
|
60
|
+
/>
|
|
61
|
+
</div>
|
|
62
|
+
</template>
|
|
63
|
+
<template #description>
|
|
64
|
+
<span>Lorem ipsum dolor sit amet consectetur adipisicing
|
|
65
|
+
elit. Libero eligendi dolore, similique possimus
|
|
66
|
+
veritatis in vitae quia praesentium fuga quibusdam
|
|
67
|
+
autem. Doloremque tenetur repudiandae a cupiditate modi
|
|
68
|
+
dicta eveniet veritatis?</span>
|
|
69
|
+
</template>
|
|
70
|
+
</dl-widget>
|
|
71
|
+
|
|
72
|
+
<dl-widget>
|
|
73
|
+
<template #header>
|
|
74
|
+
<span>Widget 2</span>
|
|
75
|
+
</template>
|
|
76
|
+
<template #content>
|
|
77
|
+
<dl-bar-chart
|
|
78
|
+
:legend-props="legendProps"
|
|
79
|
+
:data="data"
|
|
80
|
+
:options="options"
|
|
81
|
+
:items-in-view="6"
|
|
82
|
+
/>
|
|
83
|
+
</template>
|
|
84
|
+
</dl-widget>
|
|
85
|
+
|
|
86
|
+
<dl-widget>
|
|
87
|
+
<template #header>
|
|
88
|
+
<span>Widget 3</span>
|
|
89
|
+
</template>
|
|
90
|
+
<template #content>
|
|
91
|
+
<dl-bar-chart
|
|
92
|
+
:legend-props="legendProps"
|
|
93
|
+
:data="data"
|
|
94
|
+
:options="options"
|
|
95
|
+
:items-in-view="6"
|
|
96
|
+
/>
|
|
97
|
+
</template>
|
|
98
|
+
</dl-widget>
|
|
99
|
+
|
|
100
|
+
<dl-widget>
|
|
101
|
+
<template #header>
|
|
102
|
+
<span>Widget 4</span>
|
|
103
|
+
<span style="font-size: 12px; color: gray">Subtitle</span>
|
|
104
|
+
</template>
|
|
105
|
+
<template #content>
|
|
106
|
+
<dl-bar-chart
|
|
107
|
+
:legend-props="legendProps"
|
|
108
|
+
:data="data"
|
|
109
|
+
:options="options"
|
|
110
|
+
:items-in-view="8"
|
|
111
|
+
/>
|
|
112
|
+
</template>
|
|
113
|
+
<template #description>
|
|
114
|
+
<span>Lorem ipsum dolor sit amet consectetur adipisicing
|
|
115
|
+
elit. Libero eligendi dolore, similique possimus
|
|
116
|
+
veritatis in vitae quia praesentium fuga quibusdam
|
|
117
|
+
autem. Doloremque tenetur repudiandae a cupiditate modi
|
|
118
|
+
dicta eveniet veritatis?</span>
|
|
119
|
+
</template>
|
|
120
|
+
</dl-widget>
|
|
121
|
+
|
|
122
|
+
<dl-widget>
|
|
123
|
+
<template #header>
|
|
124
|
+
<span>Widget 5</span>
|
|
125
|
+
</template>
|
|
126
|
+
<template #content>
|
|
127
|
+
<dl-bar-chart
|
|
128
|
+
:legend-props="legendProps"
|
|
129
|
+
:data="data"
|
|
130
|
+
:options="options"
|
|
131
|
+
:items-in-view="6"
|
|
132
|
+
/>
|
|
133
|
+
</template>
|
|
134
|
+
</dl-widget>
|
|
135
|
+
</dl-grid>
|
|
136
|
+
</div>
|
|
137
|
+
</template>
|
|
138
|
+
|
|
1
139
|
<script lang="ts">
|
|
2
|
-
import { defineComponent } from 'vue-demi'
|
|
140
|
+
import { defineComponent, ref } from 'vue-demi'
|
|
3
141
|
import {
|
|
4
142
|
DlWidget,
|
|
5
|
-
DlGridRow,
|
|
6
143
|
DlGrid,
|
|
7
144
|
DlBarChart,
|
|
8
|
-
|
|
145
|
+
DlGridLayout,
|
|
146
|
+
DlIcon
|
|
9
147
|
} from '../components'
|
|
10
148
|
|
|
11
149
|
const labelsFn = () => {
|
|
@@ -65,67 +203,85 @@ export default defineComponent({
|
|
|
65
203
|
DlGrid,
|
|
66
204
|
DlWidget,
|
|
67
205
|
DlBarChart,
|
|
68
|
-
|
|
69
|
-
DlConfusionMatrix
|
|
206
|
+
DlIcon
|
|
70
207
|
},
|
|
71
208
|
setup() {
|
|
72
|
-
|
|
209
|
+
const layout = ref([
|
|
210
|
+
[1, 5, 2],
|
|
211
|
+
[3, 4]
|
|
212
|
+
])
|
|
213
|
+
|
|
214
|
+
const layouts = ref<DlGridLayout[]>([
|
|
215
|
+
{
|
|
216
|
+
name: 'Layout 1',
|
|
217
|
+
value: layout.value
|
|
218
|
+
}
|
|
219
|
+
])
|
|
220
|
+
|
|
221
|
+
const widgetsPerRow = ref(3)
|
|
222
|
+
const hasBeenSaved = ref('')
|
|
223
|
+
|
|
224
|
+
const saveLayout = () => {
|
|
225
|
+
const newLayout = {
|
|
226
|
+
name: `Layout ${layouts.value.length + 1}`,
|
|
227
|
+
value: layout.value
|
|
228
|
+
}
|
|
229
|
+
layouts.value.push(newLayout)
|
|
230
|
+
hasBeenSaved.value = `${newLayout.name} has been saved.`
|
|
231
|
+
setTimeout(() => {
|
|
232
|
+
hasBeenSaved.value = ''
|
|
233
|
+
}, 2000)
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const selectLayout = (e: InputEvent) => {
|
|
237
|
+
const index = parseInt((e.target as HTMLInputElement).value)
|
|
238
|
+
layout.value = layouts.value[index].value
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return {
|
|
242
|
+
data,
|
|
243
|
+
layout,
|
|
244
|
+
layouts,
|
|
245
|
+
widgetsPerRow,
|
|
246
|
+
hasBeenSaved,
|
|
247
|
+
saveLayout,
|
|
248
|
+
selectLayout
|
|
249
|
+
}
|
|
73
250
|
}
|
|
74
251
|
})
|
|
75
252
|
</script>
|
|
76
253
|
|
|
77
|
-
<
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
/>
|
|
112
|
-
</template>
|
|
113
|
-
</dl-widget>
|
|
114
|
-
|
|
115
|
-
<dl-widget>
|
|
116
|
-
<template #header>
|
|
117
|
-
<span>Widget 3</span>
|
|
118
|
-
</template>
|
|
119
|
-
<template #content>
|
|
120
|
-
<dl-bar-chart
|
|
121
|
-
:legend-props="legendProps"
|
|
122
|
-
:data="data"
|
|
123
|
-
:options="options"
|
|
124
|
-
:items-in-view="6"
|
|
125
|
-
/>
|
|
126
|
-
</template>
|
|
127
|
-
</dl-widget>
|
|
128
|
-
</dl-grid-row>
|
|
129
|
-
</dl-grid>
|
|
130
|
-
</div>
|
|
131
|
-
</template>
|
|
254
|
+
<style lang="scss" scoped>
|
|
255
|
+
.options {
|
|
256
|
+
width: 100%;
|
|
257
|
+
display: flex;
|
|
258
|
+
justify-content: space-between;
|
|
259
|
+
}
|
|
260
|
+
.widgets-per-row {
|
|
261
|
+
&__input {
|
|
262
|
+
padding: 5px;
|
|
263
|
+
border-radius: 5px;
|
|
264
|
+
width: 50px;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
.select-layout {
|
|
268
|
+
&__input,
|
|
269
|
+
&__button {
|
|
270
|
+
padding: 5px;
|
|
271
|
+
border-radius: 5px;
|
|
272
|
+
margin: 0px 2px;
|
|
273
|
+
}
|
|
274
|
+
&__info {
|
|
275
|
+
font-size: 0.8em;
|
|
276
|
+
margin-left: 10px;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
.menu-icons {
|
|
280
|
+
display: flex;
|
|
281
|
+
align-items: center;
|
|
282
|
+
& > * {
|
|
283
|
+
cursor: pointer;
|
|
284
|
+
margin: 0px 5px;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
</style>
|
package/src/demos/index.ts
CHANGED
|
@@ -53,6 +53,7 @@ import DlKpiDemo from './DlKpiDemo.vue'
|
|
|
53
53
|
import DlEllipsisDemo from './DlEllipsisDemo.vue'
|
|
54
54
|
import DlSeparatorDemo from './DlSeparatorDemo.vue'
|
|
55
55
|
import DlCardDemo from './DlCardDemo.vue'
|
|
56
|
+
import DlGridDemo from './DlGridDemo.vue'
|
|
56
57
|
import DlMarkupTableDemo from './DlMarkupTableDemo.vue'
|
|
57
58
|
import DlVirtualScrollDemo from './DlVirtualScrollDemo.vue'
|
|
58
59
|
import DlJsonEditorDemo from './DlJsonEditorDemo.vue'
|
|
@@ -113,6 +114,7 @@ export default {
|
|
|
113
114
|
DlSeparatorDemo,
|
|
114
115
|
DlKpiDemo,
|
|
115
116
|
DlCardDemo,
|
|
117
|
+
DlGridDemo,
|
|
116
118
|
DlMarkupTableDemo,
|
|
117
119
|
DlVirtualScrollDemo,
|
|
118
120
|
DlJsonEditorDemo
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div
|
|
3
|
-
:style="rowGap"
|
|
4
|
-
class="dl-grid"
|
|
5
|
-
>
|
|
6
|
-
<slot />
|
|
7
|
-
</div>
|
|
8
|
-
</template>
|
|
9
|
-
|
|
10
|
-
<script lang="ts">
|
|
11
|
-
import { defineComponent } from 'vue-demi'
|
|
12
|
-
|
|
13
|
-
export default defineComponent({
|
|
14
|
-
props: {
|
|
15
|
-
gap: {
|
|
16
|
-
type: String,
|
|
17
|
-
default: '30px'
|
|
18
|
-
}
|
|
19
|
-
},
|
|
20
|
-
computed: {
|
|
21
|
-
rowGap(): Record<string, string> {
|
|
22
|
-
return { '--row-gap': this.gap }
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
})
|
|
26
|
-
</script>
|
|
27
|
-
|
|
28
|
-
<style lang="scss" scoped>
|
|
29
|
-
.dl-grid {
|
|
30
|
-
display: flex;
|
|
31
|
-
flex-direction: column;
|
|
32
|
-
}
|
|
33
|
-
</style>
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div
|
|
3
|
-
:style="columnGap"
|
|
4
|
-
class="dl-grid-row"
|
|
5
|
-
>
|
|
6
|
-
<slot />
|
|
7
|
-
</div>
|
|
8
|
-
</template>
|
|
9
|
-
|
|
10
|
-
<script lang="ts">
|
|
11
|
-
import { defineComponent } from 'vue-demi'
|
|
12
|
-
|
|
13
|
-
export default defineComponent({
|
|
14
|
-
props: {
|
|
15
|
-
gap: {
|
|
16
|
-
type: String,
|
|
17
|
-
default: '30px'
|
|
18
|
-
}
|
|
19
|
-
},
|
|
20
|
-
computed: {
|
|
21
|
-
columnGap(): Record<string, string> {
|
|
22
|
-
return { '--column-gap': this.gap }
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
})
|
|
26
|
-
</script>
|
|
27
|
-
|
|
28
|
-
<style scoped>
|
|
29
|
-
.dl-grid-row {
|
|
30
|
-
display: flex;
|
|
31
|
-
}
|
|
32
|
-
</style>
|
package/src/utils/swapNodes.ts
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
export function swapNodes({ source, target }: NodeSwap) {
|
|
2
|
-
const p1 = source.parentNode
|
|
3
|
-
const p2 = target.parentNode
|
|
4
|
-
let i1
|
|
5
|
-
let i2
|
|
6
|
-
|
|
7
|
-
if (!p1 || !p2 || p1.isEqualNode(target) || p2.isEqualNode(source)) return
|
|
8
|
-
|
|
9
|
-
for (var i = 0; i < p1.children.length; i++) {
|
|
10
|
-
if (p1.children[i].isEqualNode(source)) {
|
|
11
|
-
i1 = i
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
for (var i = 0; i < p2.children.length; i++) {
|
|
15
|
-
if (p2.children[i].isEqualNode(target)) {
|
|
16
|
-
i2 = i
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
if (p1.isEqualNode(p2) && i1 < i2) {
|
|
21
|
-
i2++
|
|
22
|
-
}
|
|
23
|
-
p1.insertBefore(target, p1.children[i1])
|
|
24
|
-
p2.insertBefore(source, p2.children[i2])
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export interface NodeSwap {
|
|
28
|
-
source: HTMLElement
|
|
29
|
-
target: HTMLElement
|
|
30
|
-
}
|