Skip to content

Commit f328ae4

Browse files
committed
feat(QSplitter): "reverse" and "unit" props; perf improvements quasarframework#5286
1 parent 0fbf726 commit f328ae4

File tree

3 files changed

+128
-120
lines changed

3 files changed

+128
-120
lines changed

ui/dev/components/components/splitter.vue

Lines changed: 92 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
<template>
22
<div class="q-layout-padding q-mx-auto">
3-
<div class="row q-gutter-x-sm items-center">
3+
<div class="row q-gutter-sm items-center">
44
<q-toggle v-model="horizontal" label="Horizontal" />
5-
<q-toggle v-model="modelReverse" label="Reverse model" />
6-
<q-toggle v-model="modelPixels" label="Pixel model" />
5+
<q-toggle v-model="modelReverse" label="Reverse" />
6+
<q-select dense filled v-model="modelUnit" :options="[ '%', 'px', 'em' ]" prefix="Unit:" />
77
<q-toggle v-model="disable" label="Disable" />
88
<q-toggle v-model="funkyLimits" label="Funky limits" />
99
<q-toggle v-model="showSeparator" label="Show separator" />
10-
</div>
11-
<div class="row q-gutter-x-sm items-center">
1210
<q-input
1311
v-model="model"
1412
standout
@@ -31,22 +29,24 @@
3129
<q-splitter
3230
v-model="model"
3331
:horizontal="horizontal"
34-
:model-reverse="modelReverse"
35-
:model-pixels="modelPixels"
32+
:reverse="modelReverse"
33+
:unit="modelUnit"
3634
:limits="limits"
3735
:disable="disable"
3836

3937
class="q-mt-md"
4038
style="height: 700px; border: 1px solid black"
4139
>
42-
<div slot="before" class="q-layout-padding">
43-
<div class="text-h1 q-mb-md">
44-
Before
45-
</div>
46-
<div v-for="n in 20" :key="n" class="q-my-md">
47-
{{ n }}. Lorem ipsum dolor sit, amet consectetur adipisicing elit. Quis praesentium cumque magnam odio iure quidem, quod illum numquam possimus obcaecati commodi minima assumenda consectetur culpa fuga nulla ullam. In, libero.
40+
<template v-slot:before>
41+
<div class="q-layout-padding">
42+
<div class="text-h1 q-mb-md">
43+
Before
44+
</div>
45+
<div v-for="n in 20" :key="n" class="q-my-md">
46+
{{ n }}. Lorem ipsum dolor sit, amet consectetur adipisicing elit. Quis praesentium cumque magnam odio iure quidem, quod illum numquam possimus obcaecati commodi minima assumenda consectetur culpa fuga nulla ullam. In, libero.
47+
</div>
4848
</div>
49-
</div>
49+
</template>
5050

5151
<q-icon
5252
v-if="showSeparator"
@@ -57,32 +57,38 @@
5757
@click="separatorLog"
5858
/>
5959

60-
<div slot="after" class="q-layout-padding">
61-
<div class="text-h1 q-mb-md">
62-
After
63-
</div>
64-
<div v-for="n in 20" :key="n" class="q-my-md">
65-
{{ n }}. Lorem ipsum dolor sit, amet consectetur adipisicing elit. Quis praesentium cumque magnam odio iure quidem, quod illum numquam possimus obcaecati commodi minima assumenda consectetur culpa fuga nulla ullam. In, libero.
60+
<template v-slot:after>
61+
<div class="q-layout-padding">
62+
<div class="text-h1 q-mb-md">
63+
After
64+
</div>
65+
<div v-for="n in 20" :key="n" class="q-my-md">
66+
{{ n }}. Lorem ipsum dolor sit, amet consectetur adipisicing elit. Quis praesentium cumque magnam odio iure quidem, quod illum numquam possimus obcaecati commodi minima assumenda consectetur culpa fuga nulla ullam. In, libero.
67+
</div>
6668
</div>
67-
</div>
69+
</template>
6870
</q-splitter>
6971

7072
<q-splitter
7173
v-model="model"
74+
:reverse="modelReverse"
75+
:unit="modelUnit"
7276
:limits="limits"
7377
:disable="disable"
7478

7579
class="q-mt-md stylish-splitter"
7680
separator-class="bg-deep-orange"
7781
>
78-
<div slot="before" class="q-layout-padding">
79-
<div class="text-h1 q-mb-md">
80-
Before
81-
</div>
82-
<div v-for="n in 20" :key="n" class="q-my-md">
83-
{{ n }}. Lorem ipsum dolor sit, amet consectetur adipisicing elit. Quis praesentium cumque magnam odio iure quidem, quod illum numquam possimus obcaecati commodi minima assumenda consectetur culpa fuga nulla ullam. In, libero.
82+
<template v-slot:before>
83+
<div class="q-layout-padding">
84+
<div class="text-h1 q-mb-md">
85+
Before
86+
</div>
87+
<div v-for="n in 20" :key="n" class="q-my-md">
88+
{{ n }}. Lorem ipsum dolor sit, amet consectetur adipisicing elit. Quis praesentium cumque magnam odio iure quidem, quod illum numquam possimus obcaecati commodi minima assumenda consectetur culpa fuga nulla ullam. In, libero.
89+
</div>
8490
</div>
85-
</div>
91+
</template>
8692

8793
<div v-if="showSeparator" slot="separator" class="flex justify-center">
8894
<q-btn
@@ -94,61 +100,72 @@
94100
/>
95101
<q-splitter
96102
v-model="innerSeparatorSplitModel"
103+
:reverse="modelReverse"
97104
vertical
98105
:disable="disable"
99106
separator-class="bg-deep-orange"
100107
class="bg-white rounded-borders"
101108
style="width: 50vw; height: 30vh"
102109
>
103-
<div slot="before" class="q-layout-padding">
104-
<div v-for="n in 20" :key="n" class="q-my-md">
105-
{{ n }}. Lorem ipsum dolor sit.
110+
<template v-slot:before>
111+
<div class="q-layout-padding">
112+
<div v-for="n in 20" :key="n" class="q-my-md">
113+
{{ n }}. Lorem ipsum dolor sit.
114+
</div>
106115
</div>
107-
</div>
116+
</template>
108117

109-
<div slot="after" class="q-layout-padding">
110-
<div v-for="n in 20" :key="n" class="q-my-md">
111-
{{ n }}. Lorem ipsum dolor sit.
118+
<template v-slot:after>
119+
<div class="q-layout-padding">
120+
<div v-for="n in 20" :key="n" class="q-my-md">
121+
{{ n }}. Lorem ipsum dolor sit.
122+
</div>
112123
</div>
113-
</div>
124+
</template>
114125
</q-splitter>
115126
</div>
116127

117-
<q-splitter
118-
slot="after"
119-
v-model="insideModel"
120-
horizontal
121-
:disable="disable"
122-
separator-class="bg-deep-orange"
123-
>
124-
<div slot="before" class="q-layout-padding">
125-
<div class="text-h1 q-mb-md">
126-
After - Before
127-
</div>
128-
<div v-for="n in 20" :key="n" class="q-my-md">
129-
{{ n }}. Lorem ipsum dolor sit, amet consectetur adipisicing elit. Quis praesentium cumque magnam odio iure quidem, quod illum numquam possimus obcaecati commodi minima assumenda consectetur culpa fuga nulla ullam. In, libero.
130-
</div>
131-
</div>
132-
133-
<q-btn
134-
v-if="showSeparator"
135-
color="primary"
136-
unelevated
137-
class="q-px-sm test-separator"
138-
slot="separator"
139-
icon="touch_app"
140-
@click="separatorLog"
141-
/>
142-
143-
<div slot="after" class="q-layout-padding">
144-
<div class="text-h1 q-mb-md">
145-
After - After
146-
</div>
147-
<div v-for="n in 20" :key="n" class="q-my-md">
148-
{{ n }}. Lorem ipsum dolor sit, amet consectetur adipisicing elit. Quis praesentium cumque magnam odio iure quidem, quod illum numquam possimus obcaecati commodi minima assumenda consectetur culpa fuga nulla ullam. In, libero.
149-
</div>
150-
</div>
151-
</q-splitter>
128+
<template v-slot:after>
129+
<q-splitter
130+
v-model="insideModel"
131+
:reverse="modelReverse"
132+
horizontal
133+
:disable="disable"
134+
separator-class="bg-deep-orange"
135+
>
136+
<template v-slot:before>
137+
<div class="q-layout-padding">
138+
<div class="text-h1 q-mb-md">
139+
After - Before
140+
</div>
141+
<div v-for="n in 20" :key="n" class="q-my-md">
142+
{{ n }}. Lorem ipsum dolor sit, amet consectetur adipisicing elit. Quis praesentium cumque magnam odio iure quidem, quod illum numquam possimus obcaecati commodi minima assumenda consectetur culpa fuga nulla ullam. In, libero.
143+
</div>
144+
</div>
145+
</template>
146+
147+
<q-btn
148+
v-if="showSeparator"
149+
color="primary"
150+
unelevated
151+
class="q-px-sm test-separator"
152+
slot="separator"
153+
icon="touch_app"
154+
@click="separatorLog"
155+
/>
156+
157+
<template v-slot:after>
158+
<div class="q-layout-padding">
159+
<div class="text-h1 q-mb-md">
160+
After - After
161+
</div>
162+
<div v-for="n in 20" :key="n" class="q-my-md">
163+
{{ n }}. Lorem ipsum dolor sit, amet consectetur adipisicing elit. Quis praesentium cumque magnam odio iure quidem, quod illum numquam possimus obcaecati commodi minima assumenda consectetur culpa fuga nulla ullam. In, libero.
164+
</div>
165+
</div>
166+
</template>
167+
</q-splitter>
168+
</template>
152169
</q-splitter>
153170
</div>
154171
</template>
@@ -162,7 +179,7 @@ export default {
162179
innerSeparatorSplitModel: 50,
163180
horizontal: false,
164181
modelReverse: false,
165-
modelPixels: false,
182+
modelUnit: '%',
166183
funkyLimits: false,
167184
disable: false,
168185
showSeparator: true
@@ -171,11 +188,9 @@ export default {
171188
172189
computed: {
173190
limits () {
174-
if (this.modelPixels === true) {
175-
return this.funkyLimits === true ? [100, 500] : [0, Infinity]
176-
}
177-
178-
return this.funkyLimits === true ? [0, 30] : [10, 90]
191+
return this.modelUnit === '%'
192+
? this.funkyLimits === true ? [70, 100] : [10, 90]
193+
: this.funkyLimits === true ? [100, 500] : [0, Infinity]
179194
}
180195
},
181196

ui/src/components/splitter/QSplitter.js

Lines changed: 25 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,25 @@ export default Vue.extend({
1717
type: Number,
1818
required: true
1919
},
20-
modelReverse: Boolean,
21-
modelPixels: Boolean,
22-
horizontal: Boolean,
20+
reverse: Boolean,
21+
unit: {
22+
type: String,
23+
default: '%',
24+
validator: v => [ '%', 'px' ].includes(v)
25+
},
2326

2427
limits: {
2528
type: Array,
26-
default: () => [10, 90],
29+
default: () => [ 10, 90 ],
2730
validator: v => {
2831
if (v.length !== 2) return false
2932
if (typeof v[0] !== 'number' || typeof v[1] !== 'number') return false
3033
return v[0] >= 0 && v[0] <= v[1]
3134
}
3235
},
3336

37+
horizontal: Boolean,
3438
disable: Boolean,
35-
3639
dark: Boolean,
3740

3841
beforeClass: [Array, String, Object],
@@ -70,33 +73,36 @@ export default Vue.extend({
7073
return this.horizontal === true ? 'height' : 'width'
7174
},
7275

73-
styles () {
74-
const styles = this.__cssValues(this.value)
76+
side () {
77+
return this.reverse !== true ? 'before' : 'after'
78+
},
7579

80+
styles () {
7681
return {
77-
before: { [this.prop]: styles.before },
78-
after: { [this.prop]: styles.after }
82+
[this.side]: {
83+
[this.prop]: this.__getCSSValue(this.value)
84+
}
7985
}
8086
}
8187
},
8288

8389
methods: {
8490
__pan (evt) {
85-
if (evt.isFirst) {
91+
if (evt.isFirst === true) {
8692
const size = this.$el.getBoundingClientRect()[this.prop]
8793

8894
this.__dir = this.horizontal === true ? 'up' : 'left'
89-
this.__maxValue = this.modelPixels !== true ? 100 : size
95+
this.__maxValue = this.unit === '%' ? 100 : size
9096
this.__value = Math.min(this.__maxValue, this.limits[1], Math.max(this.limits[0], this.value))
91-
this.__multiplier = (this.modelReverse !== true ? 1 : -1) *
97+
this.__multiplier = (this.reverse !== true ? 1 : -1) *
9298
(this.horizontal === true ? 1 : (this.$q.lang.rtl === true ? -1 : 1)) *
93-
(this.modelPixels !== true ? (size === 0 ? 0 : 100 / size) : 1)
99+
(this.unit === '%' ? (size === 0 ? 0 : 100 / size) : 1)
94100

95101
this.$el.classList.add('q-splitter--active')
96102
return
97103
}
98104

99-
if (evt.isFinal) {
105+
if (evt.isFinal === true) {
100106
if (this.__normalized !== this.value) {
101107
this.$emit('input', this.__normalized)
102108
}
@@ -112,10 +118,7 @@ export default Vue.extend({
112118

113119
this.__normalized = Math.min(this.__maxValue, this.limits[1], Math.max(this.limits[0], val))
114120

115-
const { before, after } = this.__cssValues(this.__normalized)
116-
117-
this.$refs.before.style[this.prop] = before
118-
this.$refs.after.style[this.prop] = after
121+
this.$refs[this.side].style[this.prop] = this.__getCSSValue(this.__normalized)
119122
},
120123

121124
__normalize (val, limits) {
@@ -127,22 +130,8 @@ export default Vue.extend({
127130
}
128131
},
129132

130-
__cssValues (val) {
131-
const
132-
main = this.modelPixels === true
133-
? Math.round(val) + 'px'
134-
: val + '%',
135-
rest = 'calc(100% - ' + main + ')'
136-
137-
return this.modelReverse !== true
138-
? {
139-
before: main,
140-
after: rest
141-
}
142-
: {
143-
before: rest,
144-
after: main
145-
}
133+
__getCSSValue (value) {
134+
return (this.unit === '%' ? value : Math.round(value)) + this.unit
146135
}
147136
},
148137

@@ -154,7 +143,7 @@ export default Vue.extend({
154143
}, [
155144
h('div', {
156145
ref: 'before',
157-
staticClass: 'q-splitter__panel q-splitter__before',
146+
staticClass: 'q-splitter__panel q-splitter__before' + (this.reverse === true ? ' col' : ''),
158147
style: this.styles.before,
159148
class: this.beforeClass,
160149
on: { input: stop }
@@ -184,7 +173,7 @@ export default Vue.extend({
184173

185174
h('div', {
186175
ref: 'after',
187-
staticClass: 'q-splitter__panel q-splitter__after',
176+
staticClass: 'q-splitter__panel q-splitter__after' + (this.reverse === true ? '' : ' col'),
188177
style: this.styles.after,
189178
class: this.afterClass,
190179
on: { input: stop }

0 commit comments

Comments
 (0)