@icij/murmur-next 4.0.1 → 4.0.4
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/lib/components/AccordionStep.vue +53 -42
- package/lib/components/AccordionWrapper.vue +25 -24
- package/lib/components/ActiveTextTruncate.vue +44 -22
- package/lib/components/AdvancedLinkForm.vue +96 -46
- package/lib/components/Brand.vue +30 -23
- package/lib/components/BrandExpansion.vue +12 -3
- package/lib/components/ConfirmButton.vue +30 -26
- package/lib/components/ContentPlaceholder.vue +11 -7
- package/lib/components/CustomPagination.vue +50 -32
- package/lib/components/DigitsInput.vue +64 -60
- package/lib/components/DonateForm.vue +112 -83
- package/lib/components/EmbedForm.vue +37 -21
- package/lib/components/EmbeddableFooter.vue +14 -10
- package/lib/components/FollowUsPopover.vue +42 -40
- package/lib/components/GenericFooter.vue +98 -23
- package/lib/components/GenericHeader.vue +66 -29
- package/lib/components/HapticCopy.vue +41 -29
- package/lib/components/ImddbHeader.vue +113 -92
- package/lib/components/OrdinalLegend.vue +43 -20
- package/lib/components/RangePicker.vue +63 -42
- package/lib/components/ResponsiveIframe.vue +9 -2
- package/lib/components/ScaleLegend.vue +56 -18
- package/lib/components/SecretInput.vue +7 -8
- package/lib/components/SelectableDropdown.vue +120 -74
- package/lib/components/SharingOptions.vue +93 -36
- package/lib/components/SharingOptionsLink.vue +11 -5
- package/lib/components/SignUpForm.vue +44 -23
- package/lib/components/SlideUpDown.vue +7 -2
- package/lib/components/TexturedDeck.vue +24 -14
- package/lib/components/TinyPagination.vue +35 -22
- package/lib/composables/chart.ts +174 -157
- package/lib/composables/resizeObserver.ts +29 -29
- package/lib/composables/sendEmail.ts +53 -42
- package/lib/config.default.ts +17 -10
- package/lib/config.ts +34 -27
- package/lib/datavisualisations/BarChart.vue +48 -42
- package/lib/datavisualisations/ColumnChart.vue +133 -89
- package/lib/datavisualisations/LineChart.vue +79 -57
- package/lib/datavisualisations/StackedBarChart.vue +116 -68
- package/lib/datavisualisations/StackedColumnChart.vue +196 -115
- package/lib/enums.ts +25 -15
- package/lib/i18n.ts +3 -3
- package/lib/keys.ts +2 -2
- package/lib/main.ts +14 -10
- package/lib/maps/ChoroplethMap.vue +299 -160
- package/lib/maps/ChoroplethMapAnnotation.vue +29 -18
- package/lib/maps/SymbolMap.vue +194 -123
- package/lib/shims-bootstrap-vue.d.ts +1 -1
- package/lib/shims-vue.d.ts +3 -3
- package/lib/styles/functions.scss +10 -6
- package/lib/styles/lib.scss +2 -4
- package/lib/styles/mixins.scss +8 -8
- package/lib/styles/utilities.scss +1 -1
- package/lib/styles/variables.scss +24 -18
- package/lib/types.ts +26 -10
- package/lib/utils/animation.ts +4 -4
- package/lib/utils/assets.ts +31 -28
- package/lib/utils/clipboard.ts +16 -10
- package/lib/utils/iframe-resizer.ts +18 -13
- package/lib/utils/placeholder.ts +54 -23
- package/lib/utils/placeholderTypes.ts +3 -3
- package/package.json +7 -2
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import {isFunction, isString} from 'lodash'
|
|
2
|
+
import { isFunction, isString } from 'lodash'
|
|
3
3
|
import * as d3 from 'd3'
|
|
4
4
|
import * as scaleFunctions from 'd3-scale'
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
defineComponent,
|
|
7
|
+
PropType,
|
|
8
|
+
ref,
|
|
9
|
+
computed,
|
|
10
|
+
onMounted,
|
|
11
|
+
watch,
|
|
12
|
+
nextTick,
|
|
13
|
+
toRef
|
|
14
|
+
} from 'vue'
|
|
6
15
|
|
|
7
16
|
type ClassListLegend = { 'scale-legend--has-cursor': boolean }
|
|
8
17
|
// eslint-disable-next-line no-unused-vars
|
|
@@ -39,7 +48,9 @@ export default defineComponent({
|
|
|
39
48
|
type: [Function, String] as PropType<ColorScaleFn | string>,
|
|
40
49
|
default: 'scaleLinear',
|
|
41
50
|
validator(colorScale: ColorScale) {
|
|
42
|
-
return
|
|
51
|
+
return (
|
|
52
|
+
isFunction(colorScale) || (colorScale as string) in scaleFunctions
|
|
53
|
+
)
|
|
43
54
|
}
|
|
44
55
|
},
|
|
45
56
|
colorScaleEnd: {
|
|
@@ -76,7 +87,11 @@ export default defineComponent({
|
|
|
76
87
|
return isNaN(left) ? '0%' : `${left}%`
|
|
77
88
|
})
|
|
78
89
|
const colorScaleBaseCanvas = computed((): HTMLCanvasElement | null => {
|
|
79
|
-
return d3
|
|
90
|
+
return d3
|
|
91
|
+
.create('canvas')
|
|
92
|
+
.attr('width', props.width)
|
|
93
|
+
.attr('height', props.height)
|
|
94
|
+
.node()
|
|
80
95
|
})
|
|
81
96
|
const colorScaleContext = computed((): CanvasRenderingContext2D | null => {
|
|
82
97
|
return colorScaleBaseCanvas.value?.getContext('2d') ?? null
|
|
@@ -97,12 +112,18 @@ export default defineComponent({
|
|
|
97
112
|
if (isString(props.colorScale)) {
|
|
98
113
|
// @ts-ignore
|
|
99
114
|
const fn: () => any = scaleFunctions[props.colorScale]
|
|
100
|
-
return fn()
|
|
115
|
+
return fn()
|
|
116
|
+
.domain([props.min, props.max])
|
|
117
|
+
.range([props.colorScaleStart, props.colorScaleEnd])
|
|
101
118
|
}
|
|
102
119
|
return props.colorScale
|
|
103
120
|
})
|
|
104
121
|
const cursorLeftScale = computed((): d3.ScaleLinear<number, number> => {
|
|
105
|
-
return d3
|
|
122
|
+
return d3
|
|
123
|
+
.scaleLinear()
|
|
124
|
+
.domain([props.min, props.max])
|
|
125
|
+
.range([0, 100])
|
|
126
|
+
.interpolate(d3.interpolateRound)
|
|
106
127
|
})
|
|
107
128
|
const widthScaleColor = computed((): WidthScaleFn => {
|
|
108
129
|
return (x: number) => {
|
|
@@ -111,7 +132,10 @@ export default defineComponent({
|
|
|
111
132
|
}
|
|
112
133
|
})
|
|
113
134
|
const widthScale = computed((): d3.ScaleLinear<number, number> => {
|
|
114
|
-
return d3
|
|
135
|
+
return d3
|
|
136
|
+
.scaleLinear()
|
|
137
|
+
.domain([0, props.width])
|
|
138
|
+
.range([props.min, props.max])
|
|
115
139
|
})
|
|
116
140
|
|
|
117
141
|
const formatNumber = d3.format(',')
|
|
@@ -119,8 +143,10 @@ export default defineComponent({
|
|
|
119
143
|
function setCursorWrapperOffset(): void {
|
|
120
144
|
const cursor = el.value?.querySelector('.scale-legend__cursor')
|
|
121
145
|
if (cursor && el.value) {
|
|
122
|
-
const {x: cursorX, width: cursorWidth} =
|
|
123
|
-
|
|
146
|
+
const { x: cursorX, width: cursorWidth } =
|
|
147
|
+
cursor.getBoundingClientRect()
|
|
148
|
+
const { x: legendX, width: legendWidth } =
|
|
149
|
+
el.value.getBoundingClientRect()
|
|
124
150
|
const left = legendX - cursorX - 6
|
|
125
151
|
const right = legendX + legendWidth - (cursorX + cursorWidth) + 6
|
|
126
152
|
cursorWrapperOffset.value = Math.max(0, left) || Math.min(0, right)
|
|
@@ -139,11 +165,10 @@ export default defineComponent({
|
|
|
139
165
|
}
|
|
140
166
|
}
|
|
141
167
|
|
|
142
|
-
watch(cursorValue,
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
})
|
|
168
|
+
watch(cursorValue, async () => {
|
|
169
|
+
await nextTick()
|
|
170
|
+
setCursorWrapperOffset()
|
|
171
|
+
})
|
|
147
172
|
|
|
148
173
|
return {
|
|
149
174
|
classList,
|
|
@@ -155,7 +180,7 @@ export default defineComponent({
|
|
|
155
180
|
//CD: function below are only uses in unit tests. use callable?
|
|
156
181
|
widthScale,
|
|
157
182
|
colorScaleFunction,
|
|
158
|
-
widthScaleColor
|
|
183
|
+
widthScaleColor
|
|
159
184
|
}
|
|
160
185
|
}
|
|
161
186
|
})
|
|
@@ -168,14 +193,27 @@ export default defineComponent({
|
|
|
168
193
|
{{ formatNumber(min) }}
|
|
169
194
|
</slot>
|
|
170
195
|
</div>
|
|
171
|
-
<img
|
|
196
|
+
<img
|
|
197
|
+
:height="height"
|
|
198
|
+
:src="colorScaleBase64"
|
|
199
|
+
:width="width"
|
|
200
|
+
class="scale-legend__scale"
|
|
201
|
+
alt="legend scale"
|
|
202
|
+
/>
|
|
172
203
|
<div class="scale-legend__bound scale-legend__bound--max">
|
|
173
204
|
<slot name="legend-cursor-max" v-bind="{ max }">
|
|
174
205
|
{{ formatNumber(max) }}
|
|
175
206
|
</slot>
|
|
176
207
|
</div>
|
|
177
|
-
<div
|
|
178
|
-
|
|
208
|
+
<div
|
|
209
|
+
v-if="hasCursor"
|
|
210
|
+
:style="{ left: cursorLeft }"
|
|
211
|
+
class="scale-legend__cursor"
|
|
212
|
+
>
|
|
213
|
+
<div
|
|
214
|
+
:style="{ transform: `translateX(${cursorWrapperOffset}px)` }"
|
|
215
|
+
class="scale-legend__cursor__wrapper"
|
|
216
|
+
>
|
|
179
217
|
<slot name="cursor" v-bind="{ value: cursorValue }">
|
|
180
218
|
{{ formatNumber(cursorValue) }}
|
|
181
219
|
</slot>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { faEye, faEyeSlash } from '@fortawesome/free-regular-svg-icons'
|
|
3
3
|
|
|
4
|
-
import { computed,ref,onBeforeMount, watch,defineComponent} from 'vue'
|
|
4
|
+
import { computed, ref, onBeforeMount, watch, defineComponent } from 'vue'
|
|
5
5
|
import { library, default as Fa } from './Fa'
|
|
6
6
|
import HapticCopy from './HapticCopy.vue'
|
|
7
7
|
|
|
@@ -49,12 +49,12 @@ export default defineComponent({
|
|
|
49
49
|
type: Boolean
|
|
50
50
|
}
|
|
51
51
|
},
|
|
52
|
-
emits:['update:visible'],
|
|
53
|
-
setup(props,{emit}){
|
|
54
|
-
onBeforeMount(() =>{
|
|
52
|
+
emits: ['update:visible'],
|
|
53
|
+
setup(props, { emit }) {
|
|
54
|
+
onBeforeMount(() => {
|
|
55
55
|
library.add(faEye, faEyeSlash)
|
|
56
56
|
})
|
|
57
|
-
const secretInput = ref<HTMLInputElement|null>(null)
|
|
57
|
+
const secretInput = ref<HTMLInputElement | null>(null)
|
|
58
58
|
const inputType = computed(() => {
|
|
59
59
|
return props.visible ? 'text' : 'password'
|
|
60
60
|
})
|
|
@@ -62,10 +62,9 @@ export default defineComponent({
|
|
|
62
62
|
return props.visible ? ['far', 'eye-slash'] : ['far', 'eye']
|
|
63
63
|
})
|
|
64
64
|
const hapticCopyClassList = computed(() => {
|
|
65
|
-
|
|
65
|
+
return `btn-${props.hapticCopyVariant}`
|
|
66
66
|
})
|
|
67
67
|
|
|
68
|
-
|
|
69
68
|
function toggle() {
|
|
70
69
|
/**
|
|
71
70
|
* Emitted when the visibility of the input changes.
|
|
@@ -73,7 +72,7 @@ export default defineComponent({
|
|
|
73
72
|
* @event update:visible
|
|
74
73
|
* @type {Boolean}
|
|
75
74
|
*/
|
|
76
|
-
emit(
|
|
75
|
+
emit('update:visible', !props.visible)
|
|
77
76
|
}
|
|
78
77
|
function selectInput() {
|
|
79
78
|
if (props.visible) {
|
|
@@ -10,12 +10,20 @@ import { faCheckSquare, faSquare } from '@fortawesome/free-regular-svg-icons'
|
|
|
10
10
|
import { RecycleScroller } from 'vue-virtual-scroller'
|
|
11
11
|
|
|
12
12
|
import Fa from './Fa'
|
|
13
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
defineComponent,
|
|
15
|
+
ref,
|
|
16
|
+
computed,
|
|
17
|
+
watch,
|
|
18
|
+
onMounted,
|
|
19
|
+
onUnmounted,
|
|
20
|
+
PropType
|
|
21
|
+
} from 'vue'
|
|
14
22
|
|
|
15
23
|
const KEY_ESC_CODE = 27
|
|
16
24
|
const KEY_UP_CODE = 38
|
|
17
25
|
const KEY_DOWN_CODE = 40
|
|
18
|
-
type Item = any
|
|
26
|
+
type Item = any
|
|
19
27
|
export default defineComponent({
|
|
20
28
|
name: 'SelectableDropdown',
|
|
21
29
|
components: {
|
|
@@ -108,74 +116,91 @@ export default defineComponent({
|
|
|
108
116
|
default: 'inherit'
|
|
109
117
|
}
|
|
110
118
|
},
|
|
111
|
-
emits:['click','update:modelValue', 'deactivate'],
|
|
112
|
-
setup(props,{emit}){
|
|
113
|
-
onMounted(()=> {
|
|
119
|
+
emits: ['click', 'update:modelValue', 'deactivate'],
|
|
120
|
+
setup(props, { emit }) {
|
|
121
|
+
onMounted(() => {
|
|
114
122
|
activateItemOrItems()
|
|
115
123
|
toggleKeys()
|
|
116
124
|
})
|
|
117
125
|
onUnmounted(() => {
|
|
118
126
|
unbindKeys()
|
|
119
127
|
})
|
|
120
|
-
const scroller=ref(null)
|
|
121
|
-
const activeItems =
|
|
122
|
-
const cssProps = computed(()=>{
|
|
128
|
+
const scroller = ref(null)
|
|
129
|
+
const activeItems = ref<Item[]>([])
|
|
130
|
+
const cssProps = computed(() => {
|
|
123
131
|
return {
|
|
124
132
|
'--scroller-height': props.scrollerHeight
|
|
125
133
|
}
|
|
126
134
|
})
|
|
127
|
-
const keyField = computed(()=>{
|
|
135
|
+
const keyField = computed(() => {
|
|
128
136
|
return typeof items_.value[0] === 'string' ? null : 'recycle_scroller_id'
|
|
129
137
|
})
|
|
130
|
-
const items_ = computed(():Item[]=>{
|
|
138
|
+
const items_ = computed((): Item[] => {
|
|
131
139
|
if (typeof props.items[0] === 'string') {
|
|
132
140
|
return props.items
|
|
133
141
|
}
|
|
134
|
-
return props.items.map((item:Item) => ({
|
|
142
|
+
return props.items.map((item: Item) => ({
|
|
143
|
+
...item,
|
|
144
|
+
recycle_scroller_id: `id-${uniqueId()}`
|
|
145
|
+
}))
|
|
135
146
|
})
|
|
136
|
-
const firstActiveItemIndex = computed(()=>{
|
|
137
|
-
return activeItems.value.length
|
|
147
|
+
const firstActiveItemIndex = computed(() => {
|
|
148
|
+
return activeItems.value.length
|
|
149
|
+
? items_.value.indexOf(activeItems.value[0])
|
|
150
|
+
: -1
|
|
138
151
|
})
|
|
139
|
-
const lastActiveItemIndex = computed(()=>{
|
|
140
|
-
return activeItems.value.length
|
|
152
|
+
const lastActiveItemIndex = computed(() => {
|
|
153
|
+
return activeItems.value.length
|
|
154
|
+
? items_.value.indexOf(activeItems.value.slice(-1))
|
|
155
|
+
: -1
|
|
141
156
|
})
|
|
142
|
-
const keysMap = computed(():{[key:string]:Function }=>{
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
}
|
|
149
|
-
)
|
|
150
|
-
watch(()=>props.hide,()=> {
|
|
151
|
-
toggleKeys()
|
|
152
|
-
})
|
|
153
|
-
watch(()=>activeItems.value,
|
|
154
|
-
()=> {
|
|
155
|
-
/**
|
|
156
|
-
* Fired when the selected value change. It will pass a canonical value
|
|
157
|
-
* or an array of values if the property `multiple` is set to true.
|
|
158
|
-
*
|
|
159
|
-
* @event input
|
|
160
|
-
* @type {String, Object, Array, Number}
|
|
161
|
-
*/
|
|
162
|
-
emit('update:modelValue', props.multiple ? activeItems.value : activeItems.value[0])
|
|
157
|
+
const keysMap = computed((): { [key: string]: Function } => {
|
|
158
|
+
return {
|
|
159
|
+
[KEY_UP_CODE]: activatePreviousItem,
|
|
160
|
+
[KEY_DOWN_CODE]: activateNextItem,
|
|
161
|
+
[KEY_ESC_CODE]: deactivateItems
|
|
162
|
+
}
|
|
163
163
|
})
|
|
164
|
-
watch(
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
activateItemOrItems(items)
|
|
164
|
+
watch(
|
|
165
|
+
() => props.hide,
|
|
166
|
+
() => {
|
|
167
|
+
toggleKeys()
|
|
169
168
|
}
|
|
169
|
+
)
|
|
170
|
+
watch(
|
|
171
|
+
() => activeItems.value,
|
|
172
|
+
() => {
|
|
173
|
+
/**
|
|
174
|
+
* Fired when the selected value change. It will pass a canonical value
|
|
175
|
+
* or an array of values if the property `multiple` is set to true.
|
|
176
|
+
*
|
|
177
|
+
* @event input
|
|
178
|
+
* @type {String, Object, Array, Number}
|
|
179
|
+
*/
|
|
180
|
+
emit(
|
|
181
|
+
'update:modelValue',
|
|
182
|
+
props.multiple ? activeItems.value : activeItems.value[0]
|
|
183
|
+
)
|
|
170
184
|
},
|
|
171
|
-
|
|
172
|
-
|
|
185
|
+
{ deep: true }
|
|
186
|
+
)
|
|
187
|
+
watch(
|
|
188
|
+
() => props.modelValue,
|
|
189
|
+
(itemOrItems) => {
|
|
190
|
+
const items = castArray(itemOrItems)
|
|
191
|
+
if (!isEqual(activeItems.value, items)) {
|
|
192
|
+
activateItemOrItems(items)
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
{ deep: true }
|
|
196
|
+
)
|
|
197
|
+
function indexIcon(item: Item) {
|
|
173
198
|
return itemActivated(item) ? faCheckSquare : faSquare
|
|
174
199
|
}
|
|
175
|
-
function itemActivated(item:Item) {
|
|
200
|
+
function itemActivated(item: Item) {
|
|
176
201
|
return findIndex(activeItems.value, (i) => props.eq(item, i)) > -1
|
|
177
202
|
}
|
|
178
|
-
function clickToSelectItem(item:Item) {
|
|
203
|
+
function clickToSelectItem(item: Item) {
|
|
179
204
|
/**
|
|
180
205
|
* Fired when user click on an item
|
|
181
206
|
*
|
|
@@ -189,7 +214,7 @@ export default defineComponent({
|
|
|
189
214
|
selectItem(item)
|
|
190
215
|
}
|
|
191
216
|
}
|
|
192
|
-
function clickToAddItem(item:Item) {
|
|
217
|
+
function clickToAddItem(item: Item) {
|
|
193
218
|
/**
|
|
194
219
|
* Fired when user click on an item
|
|
195
220
|
*
|
|
@@ -199,7 +224,7 @@ export default defineComponent({
|
|
|
199
224
|
emit('click', item)
|
|
200
225
|
addItem(item)
|
|
201
226
|
}
|
|
202
|
-
function clickToSelectRangeToItem(item:Item) {
|
|
227
|
+
function clickToSelectRangeToItem(item: Item) {
|
|
203
228
|
/**
|
|
204
229
|
* Fired when user click on an item
|
|
205
230
|
*
|
|
@@ -209,33 +234,42 @@ export default defineComponent({
|
|
|
209
234
|
emit('click', item)
|
|
210
235
|
selectRangeToItem(item)
|
|
211
236
|
}
|
|
212
|
-
function emitEventOnItem(
|
|
237
|
+
function emitEventOnItem(
|
|
238
|
+
name: 'click' | 'update:modelValue' | 'deactivate',
|
|
239
|
+
item: Item
|
|
240
|
+
) {
|
|
213
241
|
emit(name, item)
|
|
214
242
|
}
|
|
215
|
-
function selectItem(item:Item) {
|
|
243
|
+
function selectItem(item: Item) {
|
|
216
244
|
if (itemActivated(item) && activeItems.value.length === 1) {
|
|
217
245
|
activeItems.value = filter(activeItems.value, (i) => !props.eq(item, i))
|
|
218
246
|
} else {
|
|
219
247
|
activeItems.value = [item]
|
|
220
248
|
}
|
|
221
249
|
}
|
|
222
|
-
function addItem(item:Item) {
|
|
250
|
+
function addItem(item: Item) {
|
|
223
251
|
if (itemActivated(item)) {
|
|
224
252
|
activeItems.value = filter(activeItems.value, (i) => !props.eq(item, i))
|
|
225
253
|
} else {
|
|
226
254
|
activeItems.value.push(item)
|
|
227
255
|
}
|
|
228
256
|
}
|
|
229
|
-
function selectRangeToItem(item:Item) {
|
|
257
|
+
function selectRangeToItem(item: Item) {
|
|
230
258
|
// No activated items
|
|
231
259
|
if (!activeItems.value.length || !props.multiple) {
|
|
232
260
|
selectItem(item)
|
|
233
261
|
} else {
|
|
234
262
|
const index = items_.value.indexOf(item)
|
|
235
263
|
if (index > firstActiveItemIndex.value) {
|
|
236
|
-
activeItems.value = items_.value.slice(
|
|
264
|
+
activeItems.value = items_.value.slice(
|
|
265
|
+
firstActiveItemIndex.value,
|
|
266
|
+
index + 1
|
|
267
|
+
)
|
|
237
268
|
} else {
|
|
238
|
-
activeItems.value = items_.value.slice(
|
|
269
|
+
activeItems.value = items_.value.slice(
|
|
270
|
+
index,
|
|
271
|
+
firstActiveItemIndex.value + 1
|
|
272
|
+
)
|
|
239
273
|
}
|
|
240
274
|
}
|
|
241
275
|
}
|
|
@@ -244,10 +278,16 @@ export default defineComponent({
|
|
|
244
278
|
activeItems.value = [...items]
|
|
245
279
|
}
|
|
246
280
|
function activatePreviousItem() {
|
|
247
|
-
activeItems.value = [
|
|
281
|
+
activeItems.value = [
|
|
282
|
+
items_.value[Math.max(firstActiveItemIndex.value - 1, -1)]
|
|
283
|
+
]
|
|
248
284
|
}
|
|
249
285
|
function activateNextItem() {
|
|
250
|
-
activeItems.value = [
|
|
286
|
+
activeItems.value = [
|
|
287
|
+
items_.value[
|
|
288
|
+
Math.min(firstActiveItemIndex.value + 1, items_.value.length - 1)
|
|
289
|
+
]
|
|
290
|
+
]
|
|
251
291
|
}
|
|
252
292
|
function deactivateItems() {
|
|
253
293
|
activeItems.value = []
|
|
@@ -258,7 +298,7 @@ export default defineComponent({
|
|
|
258
298
|
*/
|
|
259
299
|
emit('deactivate')
|
|
260
300
|
}
|
|
261
|
-
function keyDown(event:KeyboardEvent) {
|
|
301
|
+
function keyDown(event: KeyboardEvent) {
|
|
262
302
|
const keyCode = event.keyCode || event.which
|
|
263
303
|
// The dropdown must be active
|
|
264
304
|
if (props.deactivateKeys || props.hide || !isKnownKey(keyCode)) return
|
|
@@ -270,7 +310,7 @@ export default defineComponent({
|
|
|
270
310
|
// Then call the right method
|
|
271
311
|
keysMap.value[keyCode]()
|
|
272
312
|
}
|
|
273
|
-
function isKnownKey(keycode:number) {
|
|
313
|
+
function isKnownKey(keycode: number) {
|
|
274
314
|
return Object.keys(keysMap.value).map(Number).indexOf(keycode) > -1
|
|
275
315
|
}
|
|
276
316
|
function unbindKeys() {
|
|
@@ -286,7 +326,7 @@ export default defineComponent({
|
|
|
286
326
|
bindKeys()
|
|
287
327
|
}
|
|
288
328
|
}
|
|
289
|
-
function itemId(item:Item){
|
|
329
|
+
function itemId(item: Item) {
|
|
290
330
|
return `dropdown-item-${item.recycle_scroller_id ?? item.toLowerCase()}`
|
|
291
331
|
}
|
|
292
332
|
|
|
@@ -310,32 +350,38 @@ export default defineComponent({
|
|
|
310
350
|
|
|
311
351
|
<template>
|
|
312
352
|
<div
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
353
|
+
v-if="!hide"
|
|
354
|
+
class="selectable-dropdown show"
|
|
355
|
+
:class="{ 'selectable-dropdown--multiple': multiple, [listClass]: true }"
|
|
316
356
|
>
|
|
317
357
|
<recycle-scroller
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
358
|
+
v-slot="{ item, active }"
|
|
359
|
+
:style="cssProps"
|
|
360
|
+
class="scroller"
|
|
361
|
+
:items="items_"
|
|
362
|
+
:key-field="keyField"
|
|
363
|
+
:item-size="itemSize"
|
|
324
364
|
>
|
|
325
365
|
<span
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
366
|
+
:id="itemId(item)"
|
|
367
|
+
:class="{
|
|
368
|
+
'recycle_scroller-item--active': active,
|
|
369
|
+
active: itemActivated(item),
|
|
370
|
+
[itemClass]: true
|
|
371
|
+
}"
|
|
372
|
+
class="selectable-dropdown__item px-3 d-flex"
|
|
373
|
+
@click.exact="clickToSelectItem(item)"
|
|
374
|
+
@click.ctrl="clickToAddItem(item)"
|
|
375
|
+
@click.shift="clickToSelectRangeToItem(item)"
|
|
332
376
|
>
|
|
333
377
|
<!-- @slot Item content -->
|
|
334
378
|
<slot name="item" :item="item">
|
|
335
379
|
<div v-if="multiple" class="selectable-dropdown__item__check">
|
|
336
380
|
<fa :icon="indexIcon(item)" class="me-2" />
|
|
337
381
|
</div>
|
|
338
|
-
<div
|
|
382
|
+
<div
|
|
383
|
+
class="flex-grow-1 text-truncate selectable-dropdown__item__label"
|
|
384
|
+
>
|
|
339
385
|
<!-- @slot Item's label content -->
|
|
340
386
|
<slot name="item-label" :item="item">
|
|
341
387
|
{{ serializer(item) }}
|