@thinkpixellab-public/px-vue 4.0.17 → 4.0.18
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/assets/icons/ellipsis.svg +7 -1
- package/assets/icons/eyedropper.svg +5 -1
- package/bases/PxBaseItemsSelect.vue +10 -0
- package/components/PxArrowScroller.vue +5 -1
- package/components/PxBalancedText.vue +3 -0
- package/components/PxBaseColor.vue +187 -0
- package/components/PxColorPalette.vue +7 -4
- package/components/PxDropdown.vue +0 -3
- package/components/PxIconButton.vue +3 -1
- package/components/PxPivot.vue +7 -1
- package/components/PxToggleButtonList.vue +1 -4
- package/package.json +1 -1
- package/utils/SharedHeightManager.js +213 -0
- package/utils/textWidth.js +1 -1
|
@@ -1 +1,7 @@
|
|
|
1
|
-
<svg viewBox="0 0 24 24"
|
|
1
|
+
<svg viewBox="0 0 24 24">
|
|
2
|
+
<g transform="translate(4 11)" fill="currentColor" fill-rule="evenodd">
|
|
3
|
+
<circle cx="1.5" cy="1.5" r="1.5"/>
|
|
4
|
+
<circle cx="8" cy="1.5" r="1.5"/>
|
|
5
|
+
<circle cx="14.5" cy="1.5" r="1.5"/>
|
|
6
|
+
</g>
|
|
7
|
+
</svg>
|
|
@@ -1 +1,5 @@
|
|
|
1
|
-
<svg viewBox="0 0 24 24"
|
|
1
|
+
<svg viewBox="0 0 24 24">
|
|
2
|
+
<g fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round" stroke="currentColor" stroke-width="2">
|
|
3
|
+
<path d="M16.716 2.498a3.067 3.067 0 0 1 2.962-.793c1.059.283 2.654 1.878 2.937 2.937a3.067 3.067 0 0 1-.793 2.962l-4.152 4.152-.538-.537-9.72 9.72L1.6 22.72l1.78-5.811 9.721-9.721-.537-.538 4.152-4.152ZM11.315 5.402l7.526 7.526"/>
|
|
4
|
+
</g>
|
|
5
|
+
</svg>
|
|
@@ -43,6 +43,7 @@ export default {
|
|
|
43
43
|
return {
|
|
44
44
|
selectedKeys: [],
|
|
45
45
|
baseUpdateMode: 'single',
|
|
46
|
+
isMounted: false,
|
|
46
47
|
};
|
|
47
48
|
},
|
|
48
49
|
|
|
@@ -157,11 +158,16 @@ export default {
|
|
|
157
158
|
},
|
|
158
159
|
|
|
159
160
|
mounted() {
|
|
161
|
+
this.isMounted = true;
|
|
160
162
|
this.$nextTick(() => {
|
|
161
163
|
this.tryAutoSelect();
|
|
162
164
|
});
|
|
163
165
|
},
|
|
164
166
|
|
|
167
|
+
unmounted() {
|
|
168
|
+
this.isMounted = false;
|
|
169
|
+
},
|
|
170
|
+
|
|
165
171
|
methods: {
|
|
166
172
|
tryAutoSelect() {
|
|
167
173
|
if (this.autoSelectFirst && isKeySetEmpty(this.selected) && this.items?.length) {
|
|
@@ -173,6 +179,10 @@ export default {
|
|
|
173
179
|
* Emit the change / update:selected event
|
|
174
180
|
*/
|
|
175
181
|
emitUpdateEvent() {
|
|
182
|
+
if (!this.isMounted) {
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
|
|
176
186
|
let updateArg;
|
|
177
187
|
|
|
178
188
|
if (this.updateMode == 'single') {
|
|
@@ -207,7 +207,8 @@ export default {
|
|
|
207
207
|
&__button {
|
|
208
208
|
position: relative;
|
|
209
209
|
align-self: center;
|
|
210
|
-
padding:
|
|
210
|
+
padding: 0;
|
|
211
|
+
height: 1.25em;
|
|
211
212
|
|
|
212
213
|
&--start {
|
|
213
214
|
grid-area: arrow-start;
|
|
@@ -242,6 +243,9 @@ export default {
|
|
|
242
243
|
padding-left: 0;
|
|
243
244
|
padding-right: 0;
|
|
244
245
|
}
|
|
246
|
+
|
|
247
|
+
min-height: 0.8em;
|
|
248
|
+
height: 100%;
|
|
245
249
|
}
|
|
246
250
|
}
|
|
247
251
|
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import tinycolor from 'tinycolor2';
|
|
3
|
+
import {
|
|
4
|
+
hsvaEnsureObject,
|
|
5
|
+
hsvaIsEqual,
|
|
6
|
+
hsvaToHsla,
|
|
7
|
+
hslaToStr,
|
|
8
|
+
hsvaContrastColor,
|
|
9
|
+
} from '../utils/color.js';
|
|
10
|
+
|
|
11
|
+
const TINY_FORMATS = ['rgb', 'prgb', 'hex6', 'hex3', 'hex8', 'name', 'hsl', 'hsv'];
|
|
12
|
+
|
|
13
|
+
export default {
|
|
14
|
+
name: 'px-color-picker',
|
|
15
|
+
|
|
16
|
+
props: {
|
|
17
|
+
/**
|
|
18
|
+
* The color value.
|
|
19
|
+
*/
|
|
20
|
+
color: { default: '#FF0000' },
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* The format of the color value (used for emitting events, v-model, and the default format
|
|
24
|
+
* for getColor). Allowed values are the same as those available from the tinycolor library
|
|
25
|
+
* (rgb, prgb, hex6, hex3, hex8, name, hsl, hsv) as well as 'auto' (which will attempt to
|
|
26
|
+
* use the same format as the last value set with the color prop) and 'tiny' (which will
|
|
27
|
+
* return a tinycolor object) and 'hsva' which will return hsva values as an object. The
|
|
28
|
+
* format has the advantage of not requiring a tinycolor object to be created when the color
|
|
29
|
+
* changes.
|
|
30
|
+
*
|
|
31
|
+
* @values rgb, prgb, hex6, hex3, hex8, name, hsl, hsv, auto, tiny
|
|
32
|
+
*/
|
|
33
|
+
format: { type: String, default: 'hsva' },
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Whether alpha colors are enabled.
|
|
37
|
+
*/
|
|
38
|
+
alphaEnabled: { type: Boolean, default: false },
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
data() {
|
|
42
|
+
return { autoFormat: this.format, h: 0, s: 0, v: 0, a: 1 };
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
computed: {
|
|
46
|
+
hsva() {
|
|
47
|
+
return { h: this.h, s: this.s, v: this.v, a: this.alphaEnabled ? this.a : 1 };
|
|
48
|
+
},
|
|
49
|
+
hsla() {
|
|
50
|
+
return hsvaToHsla(this.hsva);
|
|
51
|
+
},
|
|
52
|
+
hslStr() {
|
|
53
|
+
return hslaToStr(this.hsla, false);
|
|
54
|
+
},
|
|
55
|
+
hslaStr() {
|
|
56
|
+
return hslaToStr(this.hsla, true);
|
|
57
|
+
},
|
|
58
|
+
hslaTransparentStr() {
|
|
59
|
+
return hslaToStr({ ...this.hsla, a: 0 }, true);
|
|
60
|
+
},
|
|
61
|
+
hueStr() {
|
|
62
|
+
return `hsl(${this.h}, 100%, 50%)`;
|
|
63
|
+
},
|
|
64
|
+
contrastStr() {
|
|
65
|
+
return hsvaContrastColor(this.hsva);
|
|
66
|
+
},
|
|
67
|
+
eyedropperSupported() {
|
|
68
|
+
return window?.EyeDropper;
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
watch: {
|
|
73
|
+
color(nv) {
|
|
74
|
+
// update colorValue when color changes
|
|
75
|
+
this.setColor(nv);
|
|
76
|
+
},
|
|
77
|
+
hsla() {
|
|
78
|
+
// emit change when this changes as a proxy for changes to hsva as individual props
|
|
79
|
+
this.emitChange();
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
mounted() {
|
|
84
|
+
if (this.color) {
|
|
85
|
+
this.setColor(this.color);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// TODO: default is hsva, but that isn't in the TINY_FORMATS list
|
|
89
|
+
// if (this.format) {
|
|
90
|
+
// if (!TINY_FORMATS.includes(this.format)) {
|
|
91
|
+
// console.warn(
|
|
92
|
+
// `[PxBaseColor] Invalid format: "${this.format}". See comments in PxBaseColor.vue`,
|
|
93
|
+
// );
|
|
94
|
+
// }
|
|
95
|
+
// }
|
|
96
|
+
},
|
|
97
|
+
methods: {
|
|
98
|
+
setColor(strOrHsva) {
|
|
99
|
+
if (typeof strOrHsva === 'string') {
|
|
100
|
+
this.setColorStr(strOrHsva);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (typeof strOrHsva === 'object') {
|
|
104
|
+
this.setColorHsva(strOrHsva);
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
|
|
108
|
+
setColorStr(str) {
|
|
109
|
+
// this is for efficiency but also to prevent color creep as we convert between formats
|
|
110
|
+
if (this.lastEmit == str) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const tiny = tinycolor(str);
|
|
115
|
+
this.autoFormat = tiny.getFormat();
|
|
116
|
+
|
|
117
|
+
const hsva = tiny.toHsv();
|
|
118
|
+
this.setColorHsva(hsva);
|
|
119
|
+
},
|
|
120
|
+
|
|
121
|
+
setColorHsva(hsva) {
|
|
122
|
+
if (this.isCurrentHsva(hsva)) {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
this.h = hsva.h;
|
|
127
|
+
this.s = hsva.s;
|
|
128
|
+
this.v = hsva.v;
|
|
129
|
+
this.a = hsva.a;
|
|
130
|
+
},
|
|
131
|
+
|
|
132
|
+
emitChange() {
|
|
133
|
+
const clr = this.getColor(this.format);
|
|
134
|
+
|
|
135
|
+
this.lastEmit = clr;
|
|
136
|
+
|
|
137
|
+
this.$emit('update:color', clr);
|
|
138
|
+
this.$emit('change', clr);
|
|
139
|
+
},
|
|
140
|
+
|
|
141
|
+
getColor(format = null) {
|
|
142
|
+
format = format || this.format;
|
|
143
|
+
|
|
144
|
+
if (format == 'auto') {
|
|
145
|
+
format = this.autoFormat;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
let clr = { h: this.h, s: this.s, v: this.v, a: this.a };
|
|
149
|
+
|
|
150
|
+
if (format == 'hsva') {
|
|
151
|
+
return clr;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (format && [...TINY_FORMATS, 'tiny'].includes(format)) {
|
|
155
|
+
const tiny = tinycolor(clr);
|
|
156
|
+
|
|
157
|
+
if (format == 'tiny') {
|
|
158
|
+
clr = tiny;
|
|
159
|
+
} else {
|
|
160
|
+
clr = tiny.toString(format);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return clr;
|
|
165
|
+
},
|
|
166
|
+
|
|
167
|
+
colorStrToHsva(str) {
|
|
168
|
+
const tiny = tinycolor(str);
|
|
169
|
+
return tiny.toHsv();
|
|
170
|
+
},
|
|
171
|
+
|
|
172
|
+
isCurrentHsva(hOrObj, s, v, a) {
|
|
173
|
+
const hsvaCompare = hsvaEnsureObject(hOrObj, s, v, a);
|
|
174
|
+
return hsvaIsEqual(this.hsva, hsvaCompare);
|
|
175
|
+
},
|
|
176
|
+
|
|
177
|
+
setColorFromEyedropper() {
|
|
178
|
+
if (this.eyedropperSupported) {
|
|
179
|
+
const eyeDropper = new EyeDropper();
|
|
180
|
+
eyeDropper.open().then(result => {
|
|
181
|
+
this.setColorStr(result.sRGBHex);
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
};
|
|
187
|
+
</script>
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Describe this component...
|
|
3
|
+
-->
|
|
1
4
|
<template>
|
|
2
5
|
<div :class="bem()">
|
|
3
6
|
<PxColorPaletteButton
|
|
@@ -20,10 +23,10 @@
|
|
|
20
23
|
</template>
|
|
21
24
|
|
|
22
25
|
<script>
|
|
23
|
-
import PxBaseColor from '
|
|
26
|
+
import PxBaseColor from './PxBaseColor.vue';
|
|
24
27
|
import tinycolor from 'tinycolor2';
|
|
25
28
|
import PxColorPaletteButton from './PxColorPaletteButton.vue';
|
|
26
|
-
import
|
|
29
|
+
import PxColorPicker from './PxColorPicker.vue';
|
|
27
30
|
|
|
28
31
|
export default {
|
|
29
32
|
name: 'px-color-palette',
|
|
@@ -74,12 +77,12 @@ export default {
|
|
|
74
77
|
'eyedropper-only': 'eyedropper',
|
|
75
78
|
}[this.pickerMode];
|
|
76
79
|
|
|
77
|
-
return
|
|
80
|
+
return {
|
|
78
81
|
iconFallback,
|
|
79
82
|
eyedropperMode,
|
|
80
83
|
alphaEnabled: this.alphaEnabled,
|
|
81
84
|
...this.pickerAttrs,
|
|
82
|
-
}
|
|
85
|
+
};
|
|
83
86
|
},
|
|
84
87
|
showPicker() {
|
|
85
88
|
return this.pickerMode != 'none';
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"
|
|
10
10
|
@click="tryToggleChecked"
|
|
11
11
|
>
|
|
12
|
-
<px-icon v-bind="calcIconAttrs" />
|
|
12
|
+
<px-icon :class="iconClass" v-bind="calcIconAttrs" />
|
|
13
13
|
</button>
|
|
14
14
|
</template>
|
|
15
15
|
|
|
@@ -65,6 +65,8 @@ export default {
|
|
|
65
65
|
* Set this to true to enable toggling on the button (see PxBaseToggle for details).
|
|
66
66
|
**/
|
|
67
67
|
toggles: { type: Boolean, default: false },
|
|
68
|
+
|
|
69
|
+
iconClass: { type: String, default: null },
|
|
68
70
|
},
|
|
69
71
|
computed: {
|
|
70
72
|
calcIcon() {
|
package/components/PxPivot.vue
CHANGED
|
@@ -128,7 +128,13 @@ export default {
|
|
|
128
128
|
return;
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
-
const
|
|
131
|
+
const refName = this.getTabContentRefName(this.selectedItem);
|
|
132
|
+
|
|
133
|
+
if (!this.$refs[refName]) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const selected = this.$refs[refName][0];
|
|
132
138
|
const selectedRect = getClientRect(selected, this.$refs.tabs);
|
|
133
139
|
|
|
134
140
|
if (selected) {
|
|
@@ -57,9 +57,6 @@ export default {
|
|
|
57
57
|
mixins: [PxBaseItemsSelect, PxBaseVariants],
|
|
58
58
|
components: { PxToggleButton, PxRadioButton },
|
|
59
59
|
props: {
|
|
60
|
-
// // spacing between items (see PxFlex for details)
|
|
61
|
-
// gap: { default: 0.5 },
|
|
62
|
-
|
|
63
60
|
/**
|
|
64
61
|
* The icon that gets displayed when a button is checked
|
|
65
62
|
*/
|
|
@@ -118,7 +115,7 @@ export default {
|
|
|
118
115
|
|
|
119
116
|
// variant: connected
|
|
120
117
|
|
|
121
|
-
gap: 0.
|
|
118
|
+
gap: 0.6em;
|
|
122
119
|
display: flex;
|
|
123
120
|
|
|
124
121
|
&--connected {
|
package/package.json
CHANGED
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
class HeightGroup {
|
|
2
|
+
constructor(id, ops = {}) {
|
|
3
|
+
this.id = id;
|
|
4
|
+
|
|
5
|
+
this.ops = {
|
|
6
|
+
// set to null to disable css variables
|
|
7
|
+
varsParent: window.document.body,
|
|
8
|
+
|
|
9
|
+
// debounce time in ms
|
|
10
|
+
debounce: 0,
|
|
11
|
+
|
|
12
|
+
// css variable prefix (e.g. --hg-groupId-h)
|
|
13
|
+
prefix: 'hg',
|
|
14
|
+
|
|
15
|
+
// ignore heights that are larger than this value in pixels
|
|
16
|
+
ignoreMax: null,
|
|
17
|
+
|
|
18
|
+
// ignore heights that are larger than this value as a standard deviation of the mean height
|
|
19
|
+
ignoreVariance: null,
|
|
20
|
+
|
|
21
|
+
// debug mode (adds some loging that can help with debugging)
|
|
22
|
+
debug: false,
|
|
23
|
+
|
|
24
|
+
changeCallback: null,
|
|
25
|
+
|
|
26
|
+
...ops,
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
this.max = null;
|
|
30
|
+
this.elements = [];
|
|
31
|
+
this.currentMaxElements = [];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
updateOptions(ops) {
|
|
35
|
+
this.ops = { ...this.ops, ...ops };
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
getVariableName() {
|
|
39
|
+
return '--' + (this.ops.prefix ? this.ops.prefix + '-' : '') + this.id + '-h';
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
trySync() {
|
|
43
|
+
clearTimeout(this.lastTimeout);
|
|
44
|
+
|
|
45
|
+
this.lastTimeout = setTimeout(() => {
|
|
46
|
+
let heights = this.elements.map(el => el.height);
|
|
47
|
+
let ignore = Number.MAX_VALUE;
|
|
48
|
+
|
|
49
|
+
if (this.ops.ignoreVariance) {
|
|
50
|
+
const mean = heights.reduce((sum, height) => sum + height, 0) / heights.length;
|
|
51
|
+
const variance =
|
|
52
|
+
heights.reduce((sum, height) => sum + Math.pow(height - mean, 2), 0) /
|
|
53
|
+
heights.length;
|
|
54
|
+
const stdDev = Math.sqrt(variance);
|
|
55
|
+
|
|
56
|
+
if (this.ops.debug) {
|
|
57
|
+
console.log(`stdDev: ${stdDev}`);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
ignore = this.ops.ignoreVariance * stdDev + mean;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (this.ops.ignoreMax) {
|
|
64
|
+
ignore = Math.min(ignore, this.ops.ignoreMax);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const max = Math.max(...heights.filter(height => height <= ignore));
|
|
68
|
+
|
|
69
|
+
if (this.max !== max) {
|
|
70
|
+
this.max = max;
|
|
71
|
+
|
|
72
|
+
// store the elements that have the max height
|
|
73
|
+
this.currentMaxElements = this.elements.filter(el => el.height === max);
|
|
74
|
+
|
|
75
|
+
if (this.ops.varsParent) {
|
|
76
|
+
this.ops.varsParent.style.setProperty(this.getVariableName(), max + 'px');
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (this.ops.changeCallback) {
|
|
80
|
+
this.ops.changeCallback(this.id, this.max);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (this.ops.debug) {
|
|
85
|
+
console.log(`ignore: ${ignore}`);
|
|
86
|
+
console.log(
|
|
87
|
+
'valid heights:',
|
|
88
|
+
heights.filter(height => height <= ignore)
|
|
89
|
+
);
|
|
90
|
+
console.log(
|
|
91
|
+
'invalid heights:',
|
|
92
|
+
heights.filter(height => height > ignore)
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
}, this.ops.debounce);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
updateElement(element, height) {
|
|
99
|
+
if (!element) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
let el = this.elements.find(el => el.element == element);
|
|
104
|
+
|
|
105
|
+
if (!el) {
|
|
106
|
+
el = { element, height: null };
|
|
107
|
+
this.elements.push(el);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (el.height !== height) {
|
|
111
|
+
el.height = height;
|
|
112
|
+
|
|
113
|
+
if (this.currentMaxElements.includes(el)) {
|
|
114
|
+
// this element was the max height, so we need to recalculate the max height even if smaller
|
|
115
|
+
this.max = null;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
this.trySync();
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
removeElement(element) {
|
|
123
|
+
const el = this.elements.find(el => el.element === element);
|
|
124
|
+
if (el) {
|
|
125
|
+
this.elements = this.elements.filter(el => el.element !== element);
|
|
126
|
+
|
|
127
|
+
if (this.currentMaxElements.includes(el.element)) {
|
|
128
|
+
this.currentMaxElements = [];
|
|
129
|
+
this.max = null;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
this.trySync();
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export default {
|
|
138
|
+
getGroups() {
|
|
139
|
+
if (!window.$heightGroups) {
|
|
140
|
+
window.$heightGroups = {};
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return window.$heightGroups;
|
|
144
|
+
},
|
|
145
|
+
|
|
146
|
+
getGroup(id) {
|
|
147
|
+
if (!id) {
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const groups = this.getGroups();
|
|
152
|
+
|
|
153
|
+
if (id in groups) {
|
|
154
|
+
return groups[id];
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return null;
|
|
158
|
+
},
|
|
159
|
+
|
|
160
|
+
addGroup(group) {
|
|
161
|
+
const groups = this.getGroups();
|
|
162
|
+
groups[group.id] = group;
|
|
163
|
+
},
|
|
164
|
+
|
|
165
|
+
createGroup(id, ops) {
|
|
166
|
+
if (!id) {
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const group = new HeightGroup(id, ops);
|
|
171
|
+
this.addGroup(group);
|
|
172
|
+
|
|
173
|
+
return group;
|
|
174
|
+
},
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
export class SharedHeightScopeManager {
|
|
178
|
+
constructor(scopeElement, changeCallback) {
|
|
179
|
+
this.groups = {};
|
|
180
|
+
this.scopeElement = scopeElement;
|
|
181
|
+
this.groupMaxChanged = changeCallback;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
getGroup(id) {
|
|
185
|
+
if (!id) {
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
if (id in this.groups) {
|
|
190
|
+
return this.groups[id];
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return null;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
addGroup(group) {
|
|
197
|
+
this.groups[group.id] = group;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
createGroup(id, ops = {}) {
|
|
201
|
+
if (!id) {
|
|
202
|
+
return null;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
ops.varsParent = this.scopeElement;
|
|
206
|
+
ops.changeCallback = this.groupMaxChanged;
|
|
207
|
+
|
|
208
|
+
const group = new HeightGroup(id, ops);
|
|
209
|
+
this.addGroup(group);
|
|
210
|
+
|
|
211
|
+
return group;
|
|
212
|
+
}
|
|
213
|
+
}
|
package/utils/textWidth.js
CHANGED