@conduction/nextcloud-vue 2.100.0 → 2.102.0
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/dist/esm/components/CnActionsBar/CnActionsBar.vue2.js +22 -0
- package/dist/esm/components/CnActionsBar/CnActionsBar.vue2.js.map +1 -1
- package/dist/esm/components/CnActionsBar/CnActionsBar.vue3.js +8 -6
- package/dist/esm/components/CnActionsBar/CnActionsBar.vue3.js.map +1 -1
- package/dist/esm/components/CnChartWidget/CnChartWidget.vue.js +1 -1
- package/dist/esm/components/CnChartWidget/CnChartWidget.vue2.js +29 -4
- package/dist/esm/components/CnChartWidget/CnChartWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnChartWidget/CnChartWidget.vue3.js +9 -1
- package/dist/esm/components/CnChartWidget/CnChartWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue.js +1 -1
- package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue2.js +22 -1
- package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue2.js.map +1 -1
- package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue3.js +26 -16
- package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue3.js.map +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue.js +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js +70 -6
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js.map +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js +105 -74
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js.map +1 -1
- package/dist/esm/components/CnExportsWidget/CnExportsWidget.vue.js +9 -0
- package/dist/esm/components/CnExportsWidget/CnExportsWidget.vue.js.map +1 -0
- package/dist/esm/components/CnExportsWidget/CnExportsWidget.vue2.js +139 -0
- package/dist/esm/components/CnExportsWidget/CnExportsWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnExportsWidget/CnExportsWidget.vue3.js +76 -0
- package/dist/esm/components/CnExportsWidget/CnExportsWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue.js +1 -1
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js +160 -2
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js.map +1 -1
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js +206 -94
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js.map +1 -1
- package/dist/esm/components/CnFilesBrowser/filesReview.js +61 -0
- package/dist/esm/components/CnFilesBrowser/filesReview.js.map +1 -0
- package/dist/esm/components/CnGroupedCardsWidget/CnGroupedCardsWidget.vue.js +9 -0
- package/dist/esm/components/CnGroupedCardsWidget/CnGroupedCardsWidget.vue.js.map +1 -0
- package/dist/esm/components/CnGroupedCardsWidget/CnGroupedCardsWidget.vue2.js +279 -0
- package/dist/esm/components/CnGroupedCardsWidget/CnGroupedCardsWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnGroupedCardsWidget/CnGroupedCardsWidget.vue3.js +122 -0
- package/dist/esm/components/CnGroupedCardsWidget/CnGroupedCardsWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnGroupedCardsWidget/index.js +29 -0
- package/dist/esm/components/CnGroupedCardsWidget/index.js.map +1 -0
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +320 -74
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +323 -213
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
- package/dist/esm/components/CnIndexPage/useNamedSource.js +30 -3
- package/dist/esm/components/CnIndexPage/useNamedSource.js.map +1 -1
- package/dist/esm/components/CnMapWidget/CnMapWidget.vue.js +1 -1
- package/dist/esm/components/CnMapWidget/CnMapWidget.vue2.js +15 -0
- package/dist/esm/components/CnMapWidget/CnMapWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnMapWidget/CnMapWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnMenuWidget/CnMenuWidget.vue.js +1 -1
- package/dist/esm/components/CnMenuWidget/CnMenuWidget.vue2.js +25 -1
- package/dist/esm/components/CnMenuWidget/CnMenuWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnMenuWidget/CnMenuWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue.js +1 -1
- package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js +14 -1
- package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js +14 -6
- package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue.js +1 -1
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue2.js +10 -0
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue3.js +6 -1
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue3.js.map +1 -1
- package/dist/esm/components/CnOrderedListField/CnOrderedListField.vue.js +1 -1
- package/dist/esm/components/CnOrderedListField/CnOrderedListField.vue2.js +91 -4
- package/dist/esm/components/CnOrderedListField/CnOrderedListField.vue2.js.map +1 -1
- package/dist/esm/components/CnOrderedListField/CnOrderedListField.vue3.js +63 -38
- package/dist/esm/components/CnOrderedListField/CnOrderedListField.vue3.js.map +1 -1
- package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.vue.js +1 -1
- package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.vue2.js +106 -4
- package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.vue2.js.map +1 -1
- package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.vue3.js +70 -25
- package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.vue3.js.map +1 -1
- package/dist/esm/components/CnSavedViewAlertWidget/CnSavedViewAlertWidget.vue.js +9 -0
- package/dist/esm/components/CnSavedViewAlertWidget/CnSavedViewAlertWidget.vue.js.map +1 -0
- package/dist/esm/components/CnSavedViewAlertWidget/CnSavedViewAlertWidget.vue2.js +175 -0
- package/dist/esm/components/CnSavedViewAlertWidget/CnSavedViewAlertWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnSavedViewAlertWidget/CnSavedViewAlertWidget.vue3.js +77 -0
- package/dist/esm/components/CnSavedViewAlertWidget/CnSavedViewAlertWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue.js +1 -1
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue2.js +35 -2
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue2.js.map +1 -1
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue3.js.map +1 -1
- package/dist/esm/components/CnWidgetGrid/builtInWidgets.js +4 -0
- package/dist/esm/components/CnWidgetGrid/builtInWidgets.js.map +1 -1
- package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js +1 -0
- package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js.map +1 -1
- package/dist/esm/components/CnWidgetObjectTable/CnWidgetObjectTable.vue.js +1 -1
- package/dist/esm/components/CnWidgetObjectTable/CnWidgetObjectTable.vue2.js +2 -23
- package/dist/esm/components/CnWidgetObjectTable/CnWidgetObjectTable.vue2.js.map +1 -1
- package/dist/esm/components/CnWidgetObjectTable/CnWidgetObjectTable.vue3.js.map +1 -1
- package/dist/esm/composables/indexSources.js +176 -20
- package/dist/esm/composables/indexSources.js.map +1 -1
- package/dist/esm/composables/useEndpointSource.js +28 -6
- package/dist/esm/composables/useEndpointSource.js.map +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/l10n/en.json.js +41 -1
- package/dist/esm/l10n/en.json.js.map +1 -1
- package/dist/esm/l10n/nl.json.js +39 -1
- package/dist/esm/l10n/nl.json.js.map +1 -1
- package/dist/esm/library-style.js +1 -1
- package/dist/esm/nextcloud-vue.css +939 -376
- package/dist/esm/utils/builtInFormatters.js +24 -4
- package/dist/esm/utils/builtInFormatters.js.map +1 -1
- package/dist/esm/utils/languageMapText.js +50 -0
- package/dist/esm/utils/languageMapText.js.map +1 -0
- package/dist/esm/utils/libraryWidgetKeys.js +3 -0
- package/dist/esm/utils/libraryWidgetKeys.js.map +1 -1
- package/dist/esm/utils/mapList.js +71 -0
- package/dist/esm/utils/mapList.js.map +1 -0
- package/dist/esm/utils/rowClassRules.js +43 -0
- package/dist/esm/utils/rowClassRules.js.map +1 -0
- package/dist/esm/utils/validateManifestV2.compiled.js +3 -3
- package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
- package/dist/esm/utils/visibleWhen.js +19 -2
- package/dist/esm/utils/visibleWhen.js.map +1 -1
- package/dist/nextcloud-vue.cjs.js +9681 -7136
- package/dist/nextcloud-vue.cjs.js.map +2 -2
- package/dist/nextcloud-vue.css +939 -376
- package/l10n/en.json +41 -1
- package/l10n/nl.json +39 -1
- package/package.json +1 -1
- package/src/components/CnActionsBar/CnActionsBar.md +1 -0
- package/src/components/CnActionsBar/CnActionsBar.vue +31 -4
- package/src/components/CnChartWidget/CnChartWidget.md +3 -2
- package/src/components/CnChartWidget/CnChartWidget.vue +42 -4
- package/src/components/CnChoiceCards/CnChoiceCards.md +39 -0
- package/src/components/CnChoiceCards/CnChoiceCards.vue +93 -16
- package/src/components/CnDashboardPage/CnDashboardPage.vue +110 -21
- package/src/components/CnExportsWidget/CnExportsWidget.vue +233 -0
- package/src/components/CnExportsWidget/index.js +7 -0
- package/src/components/CnFilesBrowser/CnFilesBrowser.vue +324 -0
- package/src/components/CnFilesBrowser/filesReview.js +57 -0
- package/src/components/CnGroupedCardsWidget/CnGroupedCardsWidget.vue +433 -0
- package/src/components/CnGroupedCardsWidget/index.js +28 -0
- package/src/components/CnIndexPage/CnIndexPage.md +5 -1
- package/src/components/CnIndexPage/CnIndexPage.vue +313 -9
- package/src/components/CnIndexPage/useNamedSource.js +30 -3
- package/src/components/CnMapWidget/CnMapWidget.vue +37 -0
- package/src/components/CnMenuWidget/CnMenuWidget.vue +25 -1
- package/src/components/CnObjectListWidget/CnObjectListWidget.vue +29 -1
- package/src/components/CnObjectSidebar/CnFilesTab.vue +15 -0
- package/src/components/CnOrderedListField/CnOrderedListField.vue +151 -5
- package/src/components/CnQuickFilterBar/CnQuickFilterBar.md +1 -0
- package/src/components/CnQuickFilterBar/CnQuickFilterBar.vue +159 -5
- package/src/components/CnSavedViewAlertWidget/CnSavedViewAlertWidget.vue +272 -0
- package/src/components/CnSavedViewAlertWidget/index.js +7 -0
- package/src/components/CnSetupWizard/CnSetupWizard.vue +35 -2
- package/src/components/CnWidgetGrid/builtInWidgets.js +4 -0
- package/src/components/CnWidgetGrid/registerDashboardWidgets.js +1 -0
- package/src/components/CnWidgetObjectTable/CnWidgetObjectTable.vue +2 -23
- package/src/components/index.js +3 -0
- package/src/composables/indexSources.js +175 -19
- package/src/composables/useEndpointSource.js +28 -6
- package/src/css/index-page.css +117 -0
- package/src/css/look-board-index.css +10 -0
- package/src/css/look-board.css +44 -0
- package/src/index.js +1 -0
- package/src/schemas/app-manifest-v2.schema.json +85 -3
- package/src/utils/builtInFormatters.js +24 -4
- package/src/utils/languageMapText.js +46 -0
- package/src/utils/libraryWidgetKeys.js +3 -0
- package/src/utils/mapList.js +67 -0
- package/src/utils/rowClassRules.js +39 -0
- package/src/utils/validateManifestV2.compiled.js +3 -3
- package/src/utils/visibleWhen.js +19 -2
|
@@ -3,6 +3,7 @@ import { NcSelect } from '@nextcloud/vue';
|
|
|
3
3
|
import ChevronDown from 'vue-material-design-icons/ChevronDown.vue';
|
|
4
4
|
import ChevronUp from 'vue-material-design-icons/ChevronUp.vue';
|
|
5
5
|
import Close from 'vue-material-design-icons/Close.vue';
|
|
6
|
+
import DragVertical from 'vue-material-design-icons/DragVertical.vue';
|
|
6
7
|
import __sfc_main from '../CnIcon/CnIcon.vue.js';
|
|
7
8
|
|
|
8
9
|
let orderedListUid = 0;
|
|
@@ -33,7 +34,7 @@ let orderedListUid = 0;
|
|
|
33
34
|
var script = {
|
|
34
35
|
name: 'CnOrderedListField',
|
|
35
36
|
|
|
36
|
-
components: { ChevronDown, ChevronUp, Close, CnIcon: __sfc_main, NcSelect },
|
|
37
|
+
components: { ChevronDown, ChevronUp, Close, CnIcon: __sfc_main, DragVertical, NcSelect },
|
|
37
38
|
|
|
38
39
|
props: {
|
|
39
40
|
/** The values in their order. */
|
|
@@ -104,6 +105,12 @@ var script = {
|
|
|
104
105
|
return {
|
|
105
106
|
labelId: `cn-ordered-list-label-${orderedListUid}`,
|
|
106
107
|
announcement: '',
|
|
108
|
+
/** The value whose handle takes focus after the next render, or null. */
|
|
109
|
+
pendingHandleFocus: null,
|
|
110
|
+
/** The index of the row being dragged, or -1. */
|
|
111
|
+
dragIndex: -1,
|
|
112
|
+
/** The index of the row the drag is over, or -1. */
|
|
113
|
+
dropIndex: -1,
|
|
107
114
|
}
|
|
108
115
|
},
|
|
109
116
|
|
|
@@ -143,6 +150,20 @@ var script = {
|
|
|
143
150
|
},
|
|
144
151
|
},
|
|
145
152
|
|
|
153
|
+
watch: {
|
|
154
|
+
// The parent's new order arrives as new rows; the moved row's handle
|
|
155
|
+
// lost focus when its row moved in the DOM, so it takes it back.
|
|
156
|
+
rows: {
|
|
157
|
+
flush: 'post',
|
|
158
|
+
handler() {
|
|
159
|
+
if (this.pendingHandleFocus !== null) {
|
|
160
|
+
this.focusPendingHandle();
|
|
161
|
+
this.pendingHandleFocus = null;
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
},
|
|
166
|
+
|
|
146
167
|
methods: {
|
|
147
168
|
t: translate,
|
|
148
169
|
|
|
@@ -169,13 +190,15 @@ var script = {
|
|
|
169
190
|
},
|
|
170
191
|
|
|
171
192
|
/**
|
|
172
|
-
* Move a row to another place and keep focus on the pressed
|
|
173
|
-
* where it still makes sense
|
|
193
|
+
* Move a row to another place and keep focus on the pressed control
|
|
194
|
+
* where it still makes sense: the row's handle after an arrow key on
|
|
195
|
+
* it, else the up or down button.
|
|
174
196
|
*
|
|
175
197
|
* @param {number} from Its index.
|
|
176
198
|
* @param {number} to The index it moves to.
|
|
199
|
+
* @param {string} [via] `handle` when the move came from the handle.
|
|
177
200
|
*/
|
|
178
|
-
move(from, to) {
|
|
201
|
+
move(from, to, via = '') {
|
|
179
202
|
if (to < 0 || to >= this.rows.length) {
|
|
180
203
|
return
|
|
181
204
|
}
|
|
@@ -185,7 +208,16 @@ var script = {
|
|
|
185
208
|
const row = this.rows[from];
|
|
186
209
|
this.emitValue(values);
|
|
187
210
|
this.announcement = translate('nextcloud-vue', '{item} moved to position {position} of {total}', { item: row.label, position: to + 1, total: values.length });
|
|
211
|
+
if (via === 'handle') {
|
|
212
|
+
// Re-focused once the parent hands the new order back: moving the
|
|
213
|
+
// row in the DOM takes focus off its handle.
|
|
214
|
+
this.pendingHandleFocus = row.value;
|
|
215
|
+
}
|
|
188
216
|
this.$nextTick(() => {
|
|
217
|
+
if (via === 'handle') {
|
|
218
|
+
this.focusPendingHandle();
|
|
219
|
+
return
|
|
220
|
+
}
|
|
189
221
|
const direction = to < from ? 'up' : 'down';
|
|
190
222
|
const atEdge = (direction === 'up' && to === 0) || (direction === 'down' && to === values.length - 1);
|
|
191
223
|
const target = this.$el.querySelector(`[data-testid="cn-ordered-list-${atEdge ? (direction === 'up' ? 'down' : 'up') : direction}-${row.value}"]`);
|
|
@@ -195,6 +227,61 @@ var script = {
|
|
|
195
227
|
});
|
|
196
228
|
},
|
|
197
229
|
|
|
230
|
+
/** Put focus back on the handle of the row just moved by its handle. */
|
|
231
|
+
focusPendingHandle() {
|
|
232
|
+
if (this.pendingHandleFocus === null) {
|
|
233
|
+
return
|
|
234
|
+
}
|
|
235
|
+
const handle = this.$el.querySelector(`[data-testid="cn-ordered-list-handle-${this.pendingHandleFocus}"]`);
|
|
236
|
+
if (handle) {
|
|
237
|
+
handle.focus();
|
|
238
|
+
}
|
|
239
|
+
},
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Start dragging a row by its handle.
|
|
243
|
+
*
|
|
244
|
+
* @param {DragEvent} event The drag event.
|
|
245
|
+
* @param {number} index The row's index.
|
|
246
|
+
*/
|
|
247
|
+
onDragStart(event, index) {
|
|
248
|
+
this.dragIndex = index;
|
|
249
|
+
if (event && event.dataTransfer) {
|
|
250
|
+
event.dataTransfer.effectAllowed = 'move';
|
|
251
|
+
event.dataTransfer.setData('text/plain', String(this.rows[index].value));
|
|
252
|
+
}
|
|
253
|
+
},
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Mark the row a drag is over as where the row will land.
|
|
257
|
+
*
|
|
258
|
+
* @param {number} index The row's index.
|
|
259
|
+
*/
|
|
260
|
+
onDragOver(index) {
|
|
261
|
+
if (this.dragIndex !== -1) {
|
|
262
|
+
this.dropIndex = index;
|
|
263
|
+
}
|
|
264
|
+
},
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Drop the dragged row in the place of the row it is over.
|
|
268
|
+
*
|
|
269
|
+
* @param {number} index The row's index.
|
|
270
|
+
*/
|
|
271
|
+
onDrop(index) {
|
|
272
|
+
const from = this.dragIndex;
|
|
273
|
+
this.onDragEnd();
|
|
274
|
+
if (from !== -1 && from !== index) {
|
|
275
|
+
this.move(from, index, 'handle');
|
|
276
|
+
}
|
|
277
|
+
},
|
|
278
|
+
|
|
279
|
+
/** End a drag, dropped or not. */
|
|
280
|
+
onDragEnd() {
|
|
281
|
+
this.dragIndex = -1;
|
|
282
|
+
this.dropIndex = -1;
|
|
283
|
+
},
|
|
284
|
+
|
|
198
285
|
/**
|
|
199
286
|
* Remove a row.
|
|
200
287
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CnOrderedListField.vue2.js","sources":["../../../../src/components/CnOrderedListField/CnOrderedListField.vue"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2026 Conduction B.V.\n - SPDX-License-Identifier: EUPL-1.2\n-->\n\n<template>\n\t<div class=\"cn-ordered-list-field\" data-testid=\"cn-ordered-list-field\">\n\t\t<p v-if=\"label\" :id=\"labelId\" class=\"cn-ordered-list-field__label\">\n\t\t\t{{ label }}\n\t\t</p>\n\t\t<ol\n\t\t\tv-if=\"rows.length > 0\"\n\t\t\tclass=\"cn-ordered-list-field__rows\"\n\t\t\t:aria-labelledby=\"label ? labelId : null\"\n\t\t\t:aria-label=\"label ? null : listLabel\">\n\t\t\t<li\n\t\t\t\tv-for=\"(row, index) in rows\"\n\t\t\t\t:key=\"row.value\"\n\t\t\t\tclass=\"cn-ordered-list-field__row\"\n\t\t\t\t:data-testid=\"`cn-ordered-list-row-${row.value}`\">\n\t\t\t\t<span class=\"cn-ordered-list-field__position\" aria-hidden=\"true\">{{ index + 1 }}</span>\n\t\t\t\t<span v-if=\"row.icon\" class=\"cn-ordered-list-field__tile\" aria-hidden=\"true\">\n\t\t\t\t\t<CnIcon :name=\"row.icon\" :size=\"18\" />\n\t\t\t\t</span>\n\t\t\t\t<span class=\"cn-ordered-list-field__text\">\n\t\t\t\t\t<span class=\"cn-ordered-list-field__name\">{{ row.label }}</span>\n\t\t\t\t\t<span v-if=\"row.description\"\n\t\t\t\t\t\t:id=\"descriptionId(row)\"\n\t\t\t\t\t\tclass=\"cn-ordered-list-field__description\"\n\t\t\t\t\t\t:data-testid=\"`cn-ordered-list-description-${row.value}`\">{{ row.description }}</span>\n\t\t\t\t</span>\n\t\t\t\t<span class=\"cn-ordered-list-field__actions\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"cn-ordered-list-field__button\"\n\t\t\t\t\t\t:disabled=\"disabled || index === 0\"\n\t\t\t\t\t\t:aria-label=\"t('nextcloud-vue', 'Move {item} up', { item: row.label })\"\n\t\t\t\t\t\t:data-testid=\"`cn-ordered-list-up-${row.value}`\"\n\t\t\t\t\t\t:aria-describedby=\"row.description ? descriptionId(row) : null\"\n\t\t\t\t\t\t@click=\"move(index, index - 1)\">\n\t\t\t\t\t\t<ChevronUp :size=\"20\" />\n\t\t\t\t\t</button>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"cn-ordered-list-field__button\"\n\t\t\t\t\t\t:disabled=\"disabled || index === rows.length - 1\"\n\t\t\t\t\t\t:aria-label=\"t('nextcloud-vue', 'Move {item} down', { item: row.label })\"\n\t\t\t\t\t\t:data-testid=\"`cn-ordered-list-down-${row.value}`\"\n\t\t\t\t\t\t:aria-describedby=\"row.description ? descriptionId(row) : null\"\n\t\t\t\t\t\t@click=\"move(index, index + 1)\">\n\t\t\t\t\t\t<ChevronDown :size=\"20\" />\n\t\t\t\t\t</button>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"cn-ordered-list-field__button\"\n\t\t\t\t\t\t:disabled=\"disabled\"\n\t\t\t\t\t\t:aria-label=\"t('nextcloud-vue', 'Remove {item}', { item: row.label })\"\n\t\t\t\t\t\t:data-testid=\"`cn-ordered-list-remove-${row.value}`\"\n\t\t\t\t\t\t:aria-describedby=\"row.description ? descriptionId(row) : null\"\n\t\t\t\t\t\t@click=\"remove(index)\">\n\t\t\t\t\t\t<Close :size=\"20\" />\n\t\t\t\t\t</button>\n\t\t\t\t</span>\n\t\t\t</li>\n\t\t</ol>\n\t\t<p v-else class=\"cn-ordered-list-field__empty\" data-testid=\"cn-ordered-list-empty\">\n\t\t\t{{ emptyText || t('nextcloud-vue', 'Nothing added yet.') }}\n\t\t</p>\n\t\t<div v-if=\"!disabled\" class=\"cn-ordered-list-field__add\">\n\t\t\t<NcSelect\n\t\t\t\t:modelValue=\"null\"\n\t\t\t\t:options=\"available\"\n\t\t\t\tlabel=\"label\"\n\t\t\t\t:inputLabel=\"addLabel || t('nextcloud-vue', 'Add')\"\n\t\t\t\t:placeholder=\"addPlaceholder\"\n\t\t\t\t:loading=\"loading\"\n\t\t\t\t:clearable=\"false\"\n\t\t\t\t:filterable=\"!searchable\"\n\t\t\t\tdata-testid=\"cn-ordered-list-add\"\n\t\t\t\t@search=\"onSearch\"\n\t\t\t\t@update:modelValue=\"add\">\n\t\t\t\t<template #option=\"option\">\n\t\t\t\t\t<span class=\"cn-ordered-list-field__option\">\n\t\t\t\t\t\t<span v-if=\"option.icon\" class=\"cn-ordered-list-field__tile\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t<CnIcon :name=\"option.icon\" :size=\"18\" />\n\t\t\t\t\t\t</span>\n\t\t\t\t\t\t<span class=\"cn-ordered-list-field__text\">\n\t\t\t\t\t\t\t<span class=\"cn-ordered-list-field__name\">{{ option.label }}</span>\n\t\t\t\t\t\t\t<span v-if=\"option.description\" class=\"cn-ordered-list-field__description\">{{ option.description }}</span>\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</span>\n\t\t\t\t</template>\n\t\t\t</NcSelect>\n\t\t</div>\n\t\t<p class=\"hidden-visually\" aria-live=\"polite\" data-testid=\"cn-ordered-list-live\">\n\t\t\t{{ announcement }}\n\t\t</p>\n\t</div>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\nimport { NcSelect } from '@nextcloud/vue'\nimport ChevronDown from 'vue-material-design-icons/ChevronDown.vue'\nimport ChevronUp from 'vue-material-design-icons/ChevronUp.vue'\nimport Close from 'vue-material-design-icons/Close.vue'\nimport CnIcon from '../CnIcon/CnIcon.vue'\n\nlet orderedListUid = 0\n\n/**\n * CnOrderedListField - an ordered list a user keeps for themselves: rows in\n * their order with a move up, a move down and a remove button each, and a\n * search-as-you-type picker under it that adds a row (board\n * DqPersoonlijkeInstellingen, \"Zaaktypen in mijn menu\").\n *\n * The app supplies the choices (`options`) and keeps the value: every change\n * emits `update:modelValue` with the new list of values. With `searchable`\n * the picker emits `search` as the user types, so the app can fetch matching\n * choices itself; otherwise it filters `options`. Every move is announced in a\n * polite live region, so reordering works with the keyboard and a screen\n * reader, not by dragging.\n *\n * ```vue\n * <CnOrderedListField\n * v-model=\"menuCaseTypes\"\n * label=\"Case types in my menu\"\n * add-label=\"Add case type\"\n * :options=\"caseTypes\" />\n * ```\n *\n * @spec openspec/changes/ordered-list-field/specs/ordered-list-field/spec.md#requirement-a-user-keeps-an-ordered-list-with-the-keyboard\n */\nexport default {\n\tname: 'CnOrderedListField',\n\n\tcomponents: { ChevronDown, ChevronUp, Close, CnIcon, NcSelect },\n\n\tprops: {\n\t\t/** The values in their order. */\n\t\tmodelValue: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/**\n\t\t * The choices, `{ value, label, description?, icon? }` (a plain string\n\t\t * is its own label). `description` is a muted second line (\"19 open\n\t\t * cases\"), in the row and in the picker; `icon` an MDI name drawn in a\n\t\t * small tile before the label. A value in `modelValue` without a\n\t\t * choice shows the value itself.\n\t\t */\n\t\toptions: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/** The list's label, also its accessible name. */\n\t\tlabel: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** The picker's label. */\n\t\taddLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Placeholder in the picker. */\n\t\taddPlaceholder: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Shown when the list is empty. */\n\t\temptyText: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Whether the app searches (`search` event) instead of the picker filtering `options`. */\n\t\tsearchable: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** Whether the app is fetching choices. */\n\t\tloading: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** A read-only list: no buttons and no picker. */\n\t\tdisabled: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t},\n\n\temits: ['update:modelValue', 'search'],\n\n\tdata() {\n\t\torderedListUid += 1\n\t\treturn {\n\t\t\tlabelId: `cn-ordered-list-label-${orderedListUid}`,\n\t\t\tannouncement: '',\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/** @return {Array<{value: string, label: string}>} The choices in one shape. */\n\t\tchoices() {\n\t\t\treturn (Array.isArray(this.options) ? this.options : [])\n\t\t\t\t.map((option) => (option && typeof option === 'object'\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tvalue: String(option.value ?? option.id ?? ''),\n\t\t\t\t\t\t\tlabel: String(option.label ?? option.title ?? option.value ?? ''),\n\t\t\t\t\t\t\tdescription: typeof option.description === 'string' ? option.description : '',\n\t\t\t\t\t\t\ticon: typeof option.icon === 'string' ? option.icon : '',\n\t\t\t\t\t\t}\n\t\t\t\t\t: { value: String(option), label: String(option), description: '', icon: '' }))\n\t\t\t\t.filter((option) => option.value !== '')\n\t\t},\n\n\t\t/** @return {Array<{value: string, label: string, description: string, icon: string}>} The rows, in order. */\n\t\trows() {\n\t\t\treturn (Array.isArray(this.modelValue) ? this.modelValue : []).map((value) => {\n\t\t\t\tconst key = String(value)\n\t\t\t\tconst choice = this.choices.find((option) => option.value === key)\n\t\t\t\treturn choice || { value: key, label: key, description: '', icon: '' }\n\t\t\t})\n\t\t},\n\n\t\t/** @return {Array<{value: string, label: string}>} The choices not in the list yet. */\n\t\tavailable() {\n\t\t\tconst taken = new Set(this.rows.map((row) => row.value))\n\t\t\treturn this.choices.filter((option) => !taken.has(option.value))\n\t\t},\n\n\t\t/** @return {string} The list's accessible name without a label. */\n\t\tlistLabel() {\n\t\t\treturn t('nextcloud-vue', 'Ordered list')\n\t\t},\n\t},\n\n\tmethods: {\n\t\tt,\n\n\t\t/**\n\t\t * The id of a row's description, which its buttons name as their description.\n\t\t *\n\t\t * @param {{value: string}} row The row.\n\t\t * @return {string}\n\t\t */\n\t\tdescriptionId(row) {\n\t\t\treturn `${this.labelId}-desc-${String(row.value).replace(/[^\\w-]/g, '-')}`\n\t\t},\n\n\t\t/**\n\t\t * Emit the new order.\n\t\t *\n\t\t * @param {Array<string>} values The values.\n\t\t */\n\t\temitValue(values) {\n\t\t\t/**\n\t\t\t * @event update:modelValue The list changed. Payload: the values in their order.\n\t\t\t */\n\t\t\tthis.$emit('update:modelValue', values)\n\t\t},\n\n\t\t/**\n\t\t * Move a row to another place and keep focus on the pressed button\n\t\t * where it still makes sense.\n\t\t *\n\t\t * @param {number} from Its index.\n\t\t * @param {number} to The index it moves to.\n\t\t */\n\t\tmove(from, to) {\n\t\t\tif (to < 0 || to >= this.rows.length) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst values = this.rows.map((row) => row.value)\n\t\t\tconst [value] = values.splice(from, 1)\n\t\t\tvalues.splice(to, 0, value)\n\t\t\tconst row = this.rows[from]\n\t\t\tthis.emitValue(values)\n\t\t\tthis.announcement = t('nextcloud-vue', '{item} moved to position {position} of {total}', { item: row.label, position: to + 1, total: values.length })\n\t\t\tthis.$nextTick(() => {\n\t\t\t\tconst direction = to < from ? 'up' : 'down'\n\t\t\t\tconst atEdge = (direction === 'up' && to === 0) || (direction === 'down' && to === values.length - 1)\n\t\t\t\tconst target = this.$el.querySelector(`[data-testid=\"cn-ordered-list-${atEdge ? (direction === 'up' ? 'down' : 'up') : direction}-${row.value}\"]`)\n\t\t\t\tif (target && !target.disabled) {\n\t\t\t\t\ttarget.focus()\n\t\t\t\t}\n\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * Remove a row.\n\t\t *\n\t\t * @param {number} index Its index.\n\t\t */\n\t\tremove(index) {\n\t\t\tconst row = this.rows[index]\n\t\t\tthis.emitValue(this.rows.filter((_, i) => i !== index).map((r) => r.value))\n\t\t\tthis.announcement = t('nextcloud-vue', '{item} removed', { item: row.label })\n\t\t},\n\n\t\t/**\n\t\t * Add the picked choice at the end.\n\t\t *\n\t\t * @param {{value: string, label: string}|null} option The choice.\n\t\t */\n\t\tadd(option) {\n\t\t\tif (!option) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.emitValue([...this.rows.map((row) => row.value), option.value])\n\t\t\tthis.announcement = t('nextcloud-vue', '{item} added', { item: option.label })\n\t\t},\n\n\t\t/**\n\t\t * Pass the typed text on when the app searches.\n\t\t *\n\t\t * @param {string} query The text.\n\t\t */\n\t\tonSearch(query) {\n\t\t\tif (this.searchable) {\n\t\t\t\t/**\n\t\t\t\t * @event search The user typed in the picker (with `searchable`). Payload: the text.\n\t\t\t\t */\n\t\t\t\tthis.$emit('search', query)\n\t\t\t}\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-ordered-list-field {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 10px;\n}\n\n.cn-ordered-list-field__label {\n\tmargin: 0;\n\tfont-weight: 600;\n}\n\n.cn-ordered-list-field__rows {\n\tdisplay: flex;\n\tflex-direction: column;\n\tmargin: 0;\n\tpadding: 0;\n\tborder: 1px solid var(--color-border);\n\tborder-radius: var(--border-radius-element, 8px);\n\tlist-style: none;\n}\n\n.cn-ordered-list-field__row {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 10px;\n\tmin-height: 44px;\n\tpadding: 2px 6px 2px 12px;\n}\n\n.cn-ordered-list-field__row + .cn-ordered-list-field__row {\n\tborder-top: 1px solid var(--color-border);\n}\n\n.cn-ordered-list-field__position {\n\tflex: none;\n\tmin-width: 18px;\n\tcolor: var(--color-text-maxcontrast);\n\tfont-size: 13px;\n\tfont-variant-numeric: tabular-nums;\n}\n\n.cn-ordered-list-field__text {\n\tflex: 1 1 auto;\n\tmin-width: 0;\n\toverflow-wrap: anywhere;\n}\n\n.cn-ordered-list-field__actions {\n\tdisplay: flex;\n\tflex: none;\n\tgap: 2px;\n}\n\n.cn-ordered-list-field__button {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 40px;\n\tmin-width: 40px;\n\theight: 40px;\n\tmin-height: 40px;\n\tmargin: 0;\n\tpadding: 0;\n\tborder: 0;\n\tborder-radius: var(--border-radius-element, 8px);\n\tbackground: transparent;\n\tcolor: var(--color-main-text);\n\tcursor: pointer;\n}\n\n.cn-ordered-list-field__button:hover:not(:disabled) {\n\tbackground: var(--color-background-hover);\n}\n\n.cn-ordered-list-field__button:focus-visible {\n\toutline: 2px solid var(--color-primary-element);\n\toutline-offset: 1px;\n}\n\n.cn-ordered-list-field__button:disabled {\n\topacity: 0.4;\n\tcursor: default;\n}\n\n.cn-ordered-list-field__empty {\n\tmargin: 0;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-ordered-list-field__tile {\n\tdisplay: inline-flex;\n\tflex: none;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 32px;\n\theight: 32px;\n\tborder-radius: var(--border-radius-element, 8px);\n\tbackground: var(--color-background-dark);\n\tcolor: var(--color-main-text);\n}\n\n.cn-ordered-list-field__name {\n\tdisplay: block;\n}\n\n.cn-ordered-list-field__description {\n\tdisplay: block;\n\tcolor: var(--color-text-maxcontrast);\n\tfont-size: 13px;\n}\n\n.cn-ordered-list-field__option {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 10px;\n\tmin-width: 0;\n}\n</style>\n"],"names":["CnIcon","t"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CnOrderedListField.vue2.js","sources":["../../../../src/components/CnOrderedListField/CnOrderedListField.vue"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2026 Conduction B.V.\n - SPDX-License-Identifier: EUPL-1.2\n-->\n\n<template>\n\t<div class=\"cn-ordered-list-field\" data-testid=\"cn-ordered-list-field\">\n\t\t<p v-if=\"label\" :id=\"labelId\" class=\"cn-ordered-list-field__label\">\n\t\t\t{{ label }}\n\t\t</p>\n\t\t<ol\n\t\t\tv-if=\"rows.length > 0\"\n\t\t\tclass=\"cn-ordered-list-field__rows\"\n\t\t\t:aria-labelledby=\"label ? labelId : null\"\n\t\t\t:aria-label=\"label ? null : listLabel\">\n\t\t\t<li\n\t\t\t\tv-for=\"(row, index) in rows\"\n\t\t\t\t:key=\"row.value\"\n\t\t\t\tclass=\"cn-ordered-list-field__row\"\n\t\t\t\t:class=\"{\n\t\t\t\t\t'cn-ordered-list-field__row--dragging': dragIndex === index,\n\t\t\t\t\t'cn-ordered-list-field__row--over': dropIndex === index && dragIndex !== index,\n\t\t\t\t}\"\n\t\t\t\t:data-testid=\"`cn-ordered-list-row-${row.value}`\"\n\t\t\t\t@dragover.prevent=\"onDragOver(index)\"\n\t\t\t\t@drop.prevent=\"onDrop(index)\">\n\t\t\t\t<!-- A drag handle (DqPersoonlijkeInstellingen). It is a button: a\n\t\t\t\t keyboard user moves the row with the arrow keys on it, and the\n\t\t\t\t up and down buttons stay for anyone who neither drags nor uses\n\t\t\t\t arrow keys. -->\n\t\t\t\t<button\n\t\t\t\t\tv-if=\"!disabled\"\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"cn-ordered-list-field__handle\"\n\t\t\t\t\tdraggable=\"true\"\n\t\t\t\t\t:aria-label=\"t('nextcloud-vue', 'Reorder {item}: drag, or press the up and down arrow keys', { item: row.label })\"\n\t\t\t\t\t:data-testid=\"`cn-ordered-list-handle-${row.value}`\"\n\t\t\t\t\t@dragstart=\"onDragStart($event, index)\"\n\t\t\t\t\t@dragend=\"onDragEnd\"\n\t\t\t\t\t@keydown.up.prevent=\"move(index, index - 1, 'handle')\"\n\t\t\t\t\t@keydown.down.prevent=\"move(index, index + 1, 'handle')\">\n\t\t\t\t\t<DragVertical :size=\"20\" />\n\t\t\t\t</button>\n\t\t\t\t<span class=\"cn-ordered-list-field__position\" aria-hidden=\"true\">{{ index + 1 }}</span>\n\t\t\t\t<span v-if=\"row.icon\" class=\"cn-ordered-list-field__tile\" aria-hidden=\"true\">\n\t\t\t\t\t<CnIcon :name=\"row.icon\" :size=\"18\" />\n\t\t\t\t</span>\n\t\t\t\t<span class=\"cn-ordered-list-field__text\">\n\t\t\t\t\t<span class=\"cn-ordered-list-field__name\">{{ row.label }}</span>\n\t\t\t\t\t<span v-if=\"row.description\"\n\t\t\t\t\t\t:id=\"descriptionId(row)\"\n\t\t\t\t\t\tclass=\"cn-ordered-list-field__description\"\n\t\t\t\t\t\t:data-testid=\"`cn-ordered-list-description-${row.value}`\">{{ row.description }}</span>\n\t\t\t\t</span>\n\t\t\t\t<span class=\"cn-ordered-list-field__actions\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"cn-ordered-list-field__button\"\n\t\t\t\t\t\t:disabled=\"disabled || index === 0\"\n\t\t\t\t\t\t:aria-label=\"t('nextcloud-vue', 'Move {item} up', { item: row.label })\"\n\t\t\t\t\t\t:data-testid=\"`cn-ordered-list-up-${row.value}`\"\n\t\t\t\t\t\t:aria-describedby=\"row.description ? descriptionId(row) : null\"\n\t\t\t\t\t\t@click=\"move(index, index - 1)\">\n\t\t\t\t\t\t<ChevronUp :size=\"20\" />\n\t\t\t\t\t</button>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"cn-ordered-list-field__button\"\n\t\t\t\t\t\t:disabled=\"disabled || index === rows.length - 1\"\n\t\t\t\t\t\t:aria-label=\"t('nextcloud-vue', 'Move {item} down', { item: row.label })\"\n\t\t\t\t\t\t:data-testid=\"`cn-ordered-list-down-${row.value}`\"\n\t\t\t\t\t\t:aria-describedby=\"row.description ? descriptionId(row) : null\"\n\t\t\t\t\t\t@click=\"move(index, index + 1)\">\n\t\t\t\t\t\t<ChevronDown :size=\"20\" />\n\t\t\t\t\t</button>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"cn-ordered-list-field__button\"\n\t\t\t\t\t\t:disabled=\"disabled\"\n\t\t\t\t\t\t:aria-label=\"t('nextcloud-vue', 'Remove {item}', { item: row.label })\"\n\t\t\t\t\t\t:data-testid=\"`cn-ordered-list-remove-${row.value}`\"\n\t\t\t\t\t\t:aria-describedby=\"row.description ? descriptionId(row) : null\"\n\t\t\t\t\t\t@click=\"remove(index)\">\n\t\t\t\t\t\t<Close :size=\"20\" />\n\t\t\t\t\t</button>\n\t\t\t\t</span>\n\t\t\t</li>\n\t\t</ol>\n\t\t<p v-else class=\"cn-ordered-list-field__empty\" data-testid=\"cn-ordered-list-empty\">\n\t\t\t{{ emptyText || t('nextcloud-vue', 'Nothing added yet.') }}\n\t\t</p>\n\t\t<div v-if=\"!disabled\" class=\"cn-ordered-list-field__add\">\n\t\t\t<NcSelect\n\t\t\t\t:modelValue=\"null\"\n\t\t\t\t:options=\"available\"\n\t\t\t\tlabel=\"label\"\n\t\t\t\t:inputLabel=\"addLabel || t('nextcloud-vue', 'Add')\"\n\t\t\t\t:placeholder=\"addPlaceholder\"\n\t\t\t\t:loading=\"loading\"\n\t\t\t\t:clearable=\"false\"\n\t\t\t\t:filterable=\"!searchable\"\n\t\t\t\tdata-testid=\"cn-ordered-list-add\"\n\t\t\t\t@search=\"onSearch\"\n\t\t\t\t@update:modelValue=\"add\">\n\t\t\t\t<template #option=\"option\">\n\t\t\t\t\t<span class=\"cn-ordered-list-field__option\">\n\t\t\t\t\t\t<span v-if=\"option.icon\" class=\"cn-ordered-list-field__tile\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t<CnIcon :name=\"option.icon\" :size=\"18\" />\n\t\t\t\t\t\t</span>\n\t\t\t\t\t\t<span class=\"cn-ordered-list-field__text\">\n\t\t\t\t\t\t\t<span class=\"cn-ordered-list-field__name\">{{ option.label }}</span>\n\t\t\t\t\t\t\t<span v-if=\"option.description\" class=\"cn-ordered-list-field__description\">{{ option.description }}</span>\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</span>\n\t\t\t\t</template>\n\t\t\t</NcSelect>\n\t\t</div>\n\t\t<p class=\"hidden-visually\" aria-live=\"polite\" data-testid=\"cn-ordered-list-live\">\n\t\t\t{{ announcement }}\n\t\t</p>\n\t</div>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\nimport { NcSelect } from '@nextcloud/vue'\nimport ChevronDown from 'vue-material-design-icons/ChevronDown.vue'\nimport ChevronUp from 'vue-material-design-icons/ChevronUp.vue'\nimport Close from 'vue-material-design-icons/Close.vue'\nimport DragVertical from 'vue-material-design-icons/DragVertical.vue'\nimport CnIcon from '../CnIcon/CnIcon.vue'\n\nlet orderedListUid = 0\n\n/**\n * CnOrderedListField - an ordered list a user keeps for themselves: rows in\n * their order with a move up, a move down and a remove button each, and a\n * search-as-you-type picker under it that adds a row (board\n * DqPersoonlijkeInstellingen, \"Zaaktypen in mijn menu\").\n *\n * The app supplies the choices (`options`) and keeps the value: every change\n * emits `update:modelValue` with the new list of values. With `searchable`\n * the picker emits `search` as the user types, so the app can fetch matching\n * choices itself; otherwise it filters `options`. Every move is announced in a\n * polite live region, so reordering works with the keyboard and a screen\n * reader, not by dragging.\n *\n * ```vue\n * <CnOrderedListField\n * v-model=\"menuCaseTypes\"\n * label=\"Case types in my menu\"\n * add-label=\"Add case type\"\n * :options=\"caseTypes\" />\n * ```\n *\n * @spec openspec/changes/ordered-list-field/specs/ordered-list-field/spec.md#requirement-a-user-keeps-an-ordered-list-with-the-keyboard\n */\nexport default {\n\tname: 'CnOrderedListField',\n\n\tcomponents: { ChevronDown, ChevronUp, Close, CnIcon, DragVertical, NcSelect },\n\n\tprops: {\n\t\t/** The values in their order. */\n\t\tmodelValue: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/**\n\t\t * The choices, `{ value, label, description?, icon? }` (a plain string\n\t\t * is its own label). `description` is a muted second line (\"19 open\n\t\t * cases\"), in the row and in the picker; `icon` an MDI name drawn in a\n\t\t * small tile before the label. A value in `modelValue` without a\n\t\t * choice shows the value itself.\n\t\t */\n\t\toptions: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/** The list's label, also its accessible name. */\n\t\tlabel: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** The picker's label. */\n\t\taddLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Placeholder in the picker. */\n\t\taddPlaceholder: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Shown when the list is empty. */\n\t\temptyText: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Whether the app searches (`search` event) instead of the picker filtering `options`. */\n\t\tsearchable: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** Whether the app is fetching choices. */\n\t\tloading: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** A read-only list: no buttons and no picker. */\n\t\tdisabled: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t},\n\n\temits: ['update:modelValue', 'search'],\n\n\tdata() {\n\t\torderedListUid += 1\n\t\treturn {\n\t\t\tlabelId: `cn-ordered-list-label-${orderedListUid}`,\n\t\t\tannouncement: '',\n\t\t\t/** The value whose handle takes focus after the next render, or null. */\n\t\t\tpendingHandleFocus: null,\n\t\t\t/** The index of the row being dragged, or -1. */\n\t\t\tdragIndex: -1,\n\t\t\t/** The index of the row the drag is over, or -1. */\n\t\t\tdropIndex: -1,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/** @return {Array<{value: string, label: string}>} The choices in one shape. */\n\t\tchoices() {\n\t\t\treturn (Array.isArray(this.options) ? this.options : [])\n\t\t\t\t.map((option) => (option && typeof option === 'object'\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tvalue: String(option.value ?? option.id ?? ''),\n\t\t\t\t\t\t\tlabel: String(option.label ?? option.title ?? option.value ?? ''),\n\t\t\t\t\t\t\tdescription: typeof option.description === 'string' ? option.description : '',\n\t\t\t\t\t\t\ticon: typeof option.icon === 'string' ? option.icon : '',\n\t\t\t\t\t\t}\n\t\t\t\t\t: { value: String(option), label: String(option), description: '', icon: '' }))\n\t\t\t\t.filter((option) => option.value !== '')\n\t\t},\n\n\t\t/** @return {Array<{value: string, label: string, description: string, icon: string}>} The rows, in order. */\n\t\trows() {\n\t\t\treturn (Array.isArray(this.modelValue) ? this.modelValue : []).map((value) => {\n\t\t\t\tconst key = String(value)\n\t\t\t\tconst choice = this.choices.find((option) => option.value === key)\n\t\t\t\treturn choice || { value: key, label: key, description: '', icon: '' }\n\t\t\t})\n\t\t},\n\n\t\t/** @return {Array<{value: string, label: string}>} The choices not in the list yet. */\n\t\tavailable() {\n\t\t\tconst taken = new Set(this.rows.map((row) => row.value))\n\t\t\treturn this.choices.filter((option) => !taken.has(option.value))\n\t\t},\n\n\t\t/** @return {string} The list's accessible name without a label. */\n\t\tlistLabel() {\n\t\t\treturn t('nextcloud-vue', 'Ordered list')\n\t\t},\n\t},\n\n\twatch: {\n\t\t// The parent's new order arrives as new rows; the moved row's handle\n\t\t// lost focus when its row moved in the DOM, so it takes it back.\n\t\trows: {\n\t\t\tflush: 'post',\n\t\t\thandler() {\n\t\t\t\tif (this.pendingHandleFocus !== null) {\n\t\t\t\t\tthis.focusPendingHandle()\n\t\t\t\t\tthis.pendingHandleFocus = null\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t},\n\n\tmethods: {\n\t\tt,\n\n\t\t/**\n\t\t * The id of a row's description, which its buttons name as their description.\n\t\t *\n\t\t * @param {{value: string}} row The row.\n\t\t * @return {string}\n\t\t */\n\t\tdescriptionId(row) {\n\t\t\treturn `${this.labelId}-desc-${String(row.value).replace(/[^\\w-]/g, '-')}`\n\t\t},\n\n\t\t/**\n\t\t * Emit the new order.\n\t\t *\n\t\t * @param {Array<string>} values The values.\n\t\t */\n\t\temitValue(values) {\n\t\t\t/**\n\t\t\t * @event update:modelValue The list changed. Payload: the values in their order.\n\t\t\t */\n\t\t\tthis.$emit('update:modelValue', values)\n\t\t},\n\n\t\t/**\n\t\t * Move a row to another place and keep focus on the pressed control\n\t\t * where it still makes sense: the row's handle after an arrow key on\n\t\t * it, else the up or down button.\n\t\t *\n\t\t * @param {number} from Its index.\n\t\t * @param {number} to The index it moves to.\n\t\t * @param {string} [via] `handle` when the move came from the handle.\n\t\t */\n\t\tmove(from, to, via = '') {\n\t\t\tif (to < 0 || to >= this.rows.length) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst values = this.rows.map((row) => row.value)\n\t\t\tconst [value] = values.splice(from, 1)\n\t\t\tvalues.splice(to, 0, value)\n\t\t\tconst row = this.rows[from]\n\t\t\tthis.emitValue(values)\n\t\t\tthis.announcement = t('nextcloud-vue', '{item} moved to position {position} of {total}', { item: row.label, position: to + 1, total: values.length })\n\t\t\tif (via === 'handle') {\n\t\t\t\t// Re-focused once the parent hands the new order back: moving the\n\t\t\t\t// row in the DOM takes focus off its handle.\n\t\t\t\tthis.pendingHandleFocus = row.value\n\t\t\t}\n\t\t\tthis.$nextTick(() => {\n\t\t\t\tif (via === 'handle') {\n\t\t\t\t\tthis.focusPendingHandle()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tconst direction = to < from ? 'up' : 'down'\n\t\t\t\tconst atEdge = (direction === 'up' && to === 0) || (direction === 'down' && to === values.length - 1)\n\t\t\t\tconst target = this.$el.querySelector(`[data-testid=\"cn-ordered-list-${atEdge ? (direction === 'up' ? 'down' : 'up') : direction}-${row.value}\"]`)\n\t\t\t\tif (target && !target.disabled) {\n\t\t\t\t\ttarget.focus()\n\t\t\t\t}\n\t\t\t})\n\t\t},\n\n\t\t/** Put focus back on the handle of the row just moved by its handle. */\n\t\tfocusPendingHandle() {\n\t\t\tif (this.pendingHandleFocus === null) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst handle = this.$el.querySelector(`[data-testid=\"cn-ordered-list-handle-${this.pendingHandleFocus}\"]`)\n\t\t\tif (handle) {\n\t\t\t\thandle.focus()\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Start dragging a row by its handle.\n\t\t *\n\t\t * @param {DragEvent} event The drag event.\n\t\t * @param {number} index The row's index.\n\t\t */\n\t\tonDragStart(event, index) {\n\t\t\tthis.dragIndex = index\n\t\t\tif (event && event.dataTransfer) {\n\t\t\t\tevent.dataTransfer.effectAllowed = 'move'\n\t\t\t\tevent.dataTransfer.setData('text/plain', String(this.rows[index].value))\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Mark the row a drag is over as where the row will land.\n\t\t *\n\t\t * @param {number} index The row's index.\n\t\t */\n\t\tonDragOver(index) {\n\t\t\tif (this.dragIndex !== -1) {\n\t\t\t\tthis.dropIndex = index\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Drop the dragged row in the place of the row it is over.\n\t\t *\n\t\t * @param {number} index The row's index.\n\t\t */\n\t\tonDrop(index) {\n\t\t\tconst from = this.dragIndex\n\t\t\tthis.onDragEnd()\n\t\t\tif (from !== -1 && from !== index) {\n\t\t\t\tthis.move(from, index, 'handle')\n\t\t\t}\n\t\t},\n\n\t\t/** End a drag, dropped or not. */\n\t\tonDragEnd() {\n\t\t\tthis.dragIndex = -1\n\t\t\tthis.dropIndex = -1\n\t\t},\n\n\t\t/**\n\t\t * Remove a row.\n\t\t *\n\t\t * @param {number} index Its index.\n\t\t */\n\t\tremove(index) {\n\t\t\tconst row = this.rows[index]\n\t\t\tthis.emitValue(this.rows.filter((_, i) => i !== index).map((r) => r.value))\n\t\t\tthis.announcement = t('nextcloud-vue', '{item} removed', { item: row.label })\n\t\t},\n\n\t\t/**\n\t\t * Add the picked choice at the end.\n\t\t *\n\t\t * @param {{value: string, label: string}|null} option The choice.\n\t\t */\n\t\tadd(option) {\n\t\t\tif (!option) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.emitValue([...this.rows.map((row) => row.value), option.value])\n\t\t\tthis.announcement = t('nextcloud-vue', '{item} added', { item: option.label })\n\t\t},\n\n\t\t/**\n\t\t * Pass the typed text on when the app searches.\n\t\t *\n\t\t * @param {string} query The text.\n\t\t */\n\t\tonSearch(query) {\n\t\t\tif (this.searchable) {\n\t\t\t\t/**\n\t\t\t\t * @event search The user typed in the picker (with `searchable`). Payload: the text.\n\t\t\t\t */\n\t\t\t\tthis.$emit('search', query)\n\t\t\t}\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-ordered-list-field {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 10px;\n}\n\n.cn-ordered-list-field__label {\n\tmargin: 0;\n\tfont-weight: 600;\n}\n\n.cn-ordered-list-field__rows {\n\tdisplay: flex;\n\tflex-direction: column;\n\tmargin: 0;\n\tpadding: 0;\n\tborder: 1px solid var(--color-border);\n\tborder-radius: var(--border-radius-element, 8px);\n\tlist-style: none;\n}\n\n.cn-ordered-list-field__row {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 10px;\n\tmin-height: 44px;\n\tpadding: 2px 6px 2px 12px;\n}\n\n.cn-ordered-list-field__row + .cn-ordered-list-field__row {\n\tborder-top: 1px solid var(--color-border);\n}\n\n.cn-ordered-list-field__row--dragging {\n\topacity: 0.5;\n}\n\n/* Where a dragged row will land: a primary line on the row's top edge. */\n.cn-ordered-list-field__row--over {\n\tbox-shadow: inset 0 2px 0 var(--color-primary-element);\n}\n\n.cn-ordered-list-field__handle {\n\tdisplay: inline-flex;\n\tflex: none;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 28px;\n\tmin-width: 28px;\n\theight: 34px;\n\tmin-height: 34px;\n\tmargin: 0 -6px 0 -8px;\n\tpadding: 0;\n\tborder: 0;\n\tborder-radius: var(--border-radius-element, 8px);\n\tbackground: transparent;\n\tcolor: var(--color-text-maxcontrast);\n\tcursor: grab;\n}\n\n.cn-ordered-list-field__handle:active {\n\tcursor: grabbing;\n}\n\n.cn-ordered-list-field__handle:focus-visible {\n\toutline: 2px solid var(--color-primary-element);\n\toutline-offset: 1px;\n}\n\n.cn-ordered-list-field__position {\n\tflex: none;\n\tmin-width: 18px;\n\tcolor: var(--color-text-maxcontrast);\n\tfont-size: 13px;\n\tfont-variant-numeric: tabular-nums;\n}\n\n.cn-ordered-list-field__text {\n\tflex: 1 1 auto;\n\tmin-width: 0;\n\toverflow-wrap: anywhere;\n}\n\n.cn-ordered-list-field__actions {\n\tdisplay: flex;\n\tflex: none;\n\tgap: 2px;\n}\n\n.cn-ordered-list-field__button {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 40px;\n\tmin-width: 40px;\n\theight: 40px;\n\tmin-height: 40px;\n\tmargin: 0;\n\tpadding: 0;\n\tborder: 0;\n\tborder-radius: var(--border-radius-element, 8px);\n\tbackground: transparent;\n\tcolor: var(--color-main-text);\n\tcursor: pointer;\n}\n\n.cn-ordered-list-field__button:hover:not(:disabled) {\n\tbackground: var(--color-background-hover);\n}\n\n.cn-ordered-list-field__button:focus-visible {\n\toutline: 2px solid var(--color-primary-element);\n\toutline-offset: 1px;\n}\n\n.cn-ordered-list-field__button:disabled {\n\topacity: 0.4;\n\tcursor: default;\n}\n\n.cn-ordered-list-field__empty {\n\tmargin: 0;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-ordered-list-field__tile {\n\tdisplay: inline-flex;\n\tflex: none;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 32px;\n\theight: 32px;\n\tborder-radius: var(--border-radius-element, 8px);\n\tbackground: var(--color-background-dark);\n\tcolor: var(--color-main-text);\n}\n\n.cn-ordered-list-field__name {\n\tdisplay: block;\n}\n\n.cn-ordered-list-field__description {\n\tdisplay: block;\n\tcolor: var(--color-text-maxcontrast);\n\tfont-size: 13px;\n}\n\n.cn-ordered-list-field__option {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 10px;\n\tmin-width: 0;\n}\n</style>\n"],"names":["CnIcon","t"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { resolveComponent, openBlock, createElementBlock, toDisplayString, createCommentVNode, Fragment, renderList,
|
|
1
|
+
import { resolveComponent, openBlock, createElementBlock, toDisplayString, createCommentVNode, Fragment, renderList, normalizeClass, withModifiers, withKeys, createVNode, createElementVNode, withCtx } from 'vue';
|
|
2
2
|
|
|
3
3
|
const _hoisted_1 = {
|
|
4
4
|
class: "cn-ordered-list-field",
|
|
@@ -6,51 +6,53 @@ const _hoisted_1 = {
|
|
|
6
6
|
};
|
|
7
7
|
const _hoisted_2 = ["id"];
|
|
8
8
|
const _hoisted_3 = ["aria-labelledby", "aria-label"];
|
|
9
|
-
const _hoisted_4 = ["data-testid"];
|
|
10
|
-
const _hoisted_5 =
|
|
9
|
+
const _hoisted_4 = ["data-testid", "onDragover", "onDrop"];
|
|
10
|
+
const _hoisted_5 = ["aria-label", "data-testid", "onDragstart", "onKeydown"];
|
|
11
|
+
const _hoisted_6 = {
|
|
11
12
|
class: "cn-ordered-list-field__position",
|
|
12
13
|
"aria-hidden": "true"
|
|
13
14
|
};
|
|
14
|
-
const
|
|
15
|
-
key:
|
|
15
|
+
const _hoisted_7 = {
|
|
16
|
+
key: 1,
|
|
16
17
|
class: "cn-ordered-list-field__tile",
|
|
17
18
|
"aria-hidden": "true"
|
|
18
19
|
};
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
const
|
|
22
|
-
const
|
|
23
|
-
const _hoisted_11 = ["disabled", "aria-label", "data-testid", "aria-describedby", "onClick"];
|
|
20
|
+
const _hoisted_8 = { class: "cn-ordered-list-field__text" };
|
|
21
|
+
const _hoisted_9 = { class: "cn-ordered-list-field__name" };
|
|
22
|
+
const _hoisted_10 = ["id", "data-testid"];
|
|
23
|
+
const _hoisted_11 = { class: "cn-ordered-list-field__actions" };
|
|
24
24
|
const _hoisted_12 = ["disabled", "aria-label", "data-testid", "aria-describedby", "onClick"];
|
|
25
25
|
const _hoisted_13 = ["disabled", "aria-label", "data-testid", "aria-describedby", "onClick"];
|
|
26
|
-
const _hoisted_14 =
|
|
26
|
+
const _hoisted_14 = ["disabled", "aria-label", "data-testid", "aria-describedby", "onClick"];
|
|
27
|
+
const _hoisted_15 = {
|
|
27
28
|
key: 2,
|
|
28
29
|
class: "cn-ordered-list-field__empty",
|
|
29
30
|
"data-testid": "cn-ordered-list-empty"
|
|
30
31
|
};
|
|
31
|
-
const
|
|
32
|
+
const _hoisted_16 = {
|
|
32
33
|
key: 3,
|
|
33
34
|
class: "cn-ordered-list-field__add"
|
|
34
35
|
};
|
|
35
|
-
const
|
|
36
|
-
const
|
|
36
|
+
const _hoisted_17 = { class: "cn-ordered-list-field__option" };
|
|
37
|
+
const _hoisted_18 = {
|
|
37
38
|
key: 0,
|
|
38
39
|
class: "cn-ordered-list-field__tile",
|
|
39
40
|
"aria-hidden": "true"
|
|
40
41
|
};
|
|
41
|
-
const
|
|
42
|
-
const
|
|
43
|
-
const
|
|
42
|
+
const _hoisted_19 = { class: "cn-ordered-list-field__text" };
|
|
43
|
+
const _hoisted_20 = { class: "cn-ordered-list-field__name" };
|
|
44
|
+
const _hoisted_21 = {
|
|
44
45
|
key: 0,
|
|
45
46
|
class: "cn-ordered-list-field__description"
|
|
46
47
|
};
|
|
47
|
-
const
|
|
48
|
+
const _hoisted_22 = {
|
|
48
49
|
class: "hidden-visually",
|
|
49
50
|
"aria-live": "polite",
|
|
50
51
|
"data-testid": "cn-ordered-list-live"
|
|
51
52
|
};
|
|
52
53
|
|
|
53
54
|
function render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
55
|
+
const _component_DragVertical = resolveComponent("DragVertical");
|
|
54
56
|
const _component_CnIcon = resolveComponent("CnIcon");
|
|
55
57
|
const _component_ChevronUp = resolveComponent("ChevronUp");
|
|
56
58
|
const _component_ChevronDown = resolveComponent("ChevronDown");
|
|
@@ -75,30 +77,53 @@ function render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
75
77
|
(openBlock(true), createElementBlock(Fragment, null, renderList($options.rows, (row, index) => {
|
|
76
78
|
return (openBlock(), createElementBlock("li", {
|
|
77
79
|
key: row.value,
|
|
78
|
-
class: "cn-ordered-list-field__row",
|
|
79
|
-
|
|
80
|
+
class: normalizeClass(["cn-ordered-list-field__row", {
|
|
81
|
+
'cn-ordered-list-field__row--dragging': $data.dragIndex === index,
|
|
82
|
+
'cn-ordered-list-field__row--over': $data.dropIndex === index && $data.dragIndex !== index,
|
|
83
|
+
}]),
|
|
84
|
+
"data-testid": `cn-ordered-list-row-${row.value}`,
|
|
85
|
+
onDragover: withModifiers($event => ($options.onDragOver(index)), ["prevent"]),
|
|
86
|
+
onDrop: withModifiers($event => ($options.onDrop(index)), ["prevent"])
|
|
80
87
|
}, [
|
|
81
|
-
|
|
88
|
+
(!$props.disabled)
|
|
89
|
+
? (openBlock(), createElementBlock("button", {
|
|
90
|
+
key: 0,
|
|
91
|
+
type: "button",
|
|
92
|
+
class: "cn-ordered-list-field__handle",
|
|
93
|
+
draggable: "true",
|
|
94
|
+
"aria-label": $options.t('nextcloud-vue', 'Reorder {item}: drag, or press the up and down arrow keys', { item: row.label }),
|
|
95
|
+
"data-testid": `cn-ordered-list-handle-${row.value}`,
|
|
96
|
+
onDragstart: $event => ($options.onDragStart($event, index)),
|
|
97
|
+
onDragend: _cache[0] || (_cache[0] = (...args) => ($options.onDragEnd && $options.onDragEnd(...args))),
|
|
98
|
+
onKeydown: [
|
|
99
|
+
withKeys(withModifiers($event => ($options.move(index, index - 1, 'handle')), ["prevent"]), ["up"]),
|
|
100
|
+
withKeys(withModifiers($event => ($options.move(index, index + 1, 'handle')), ["prevent"]), ["down"])
|
|
101
|
+
]
|
|
102
|
+
}, [
|
|
103
|
+
createVNode(_component_DragVertical, { size: 20 })
|
|
104
|
+
], 40 /* PROPS, NEED_HYDRATION */, _hoisted_5))
|
|
105
|
+
: createCommentVNode("v-if", true),
|
|
106
|
+
createElementVNode("span", _hoisted_6, toDisplayString(index + 1), 1 /* TEXT */),
|
|
82
107
|
(row.icon)
|
|
83
|
-
? (openBlock(), createElementBlock("span",
|
|
108
|
+
? (openBlock(), createElementBlock("span", _hoisted_7, [
|
|
84
109
|
createVNode(_component_CnIcon, {
|
|
85
110
|
name: row.icon,
|
|
86
111
|
size: 18
|
|
87
112
|
}, null, 8 /* PROPS */, ["name"])
|
|
88
113
|
]))
|
|
89
114
|
: createCommentVNode("v-if", true),
|
|
90
|
-
createElementVNode("span",
|
|
91
|
-
createElementVNode("span",
|
|
115
|
+
createElementVNode("span", _hoisted_8, [
|
|
116
|
+
createElementVNode("span", _hoisted_9, toDisplayString(row.label), 1 /* TEXT */),
|
|
92
117
|
(row.description)
|
|
93
118
|
? (openBlock(), createElementBlock("span", {
|
|
94
119
|
key: 0,
|
|
95
120
|
id: $options.descriptionId(row),
|
|
96
121
|
class: "cn-ordered-list-field__description",
|
|
97
122
|
"data-testid": `cn-ordered-list-description-${row.value}`
|
|
98
|
-
}, toDisplayString(row.description), 9 /* TEXT, PROPS */,
|
|
123
|
+
}, toDisplayString(row.description), 9 /* TEXT, PROPS */, _hoisted_10))
|
|
99
124
|
: createCommentVNode("v-if", true)
|
|
100
125
|
]),
|
|
101
|
-
createElementVNode("span",
|
|
126
|
+
createElementVNode("span", _hoisted_11, [
|
|
102
127
|
createElementVNode("button", {
|
|
103
128
|
type: "button",
|
|
104
129
|
class: "cn-ordered-list-field__button",
|
|
@@ -109,7 +134,7 @@ function render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
109
134
|
onClick: $event => ($options.move(index, index - 1))
|
|
110
135
|
}, [
|
|
111
136
|
createVNode(_component_ChevronUp, { size: 20 })
|
|
112
|
-
], 8 /* PROPS */,
|
|
137
|
+
], 8 /* PROPS */, _hoisted_12),
|
|
113
138
|
createElementVNode("button", {
|
|
114
139
|
type: "button",
|
|
115
140
|
class: "cn-ordered-list-field__button",
|
|
@@ -120,7 +145,7 @@ function render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
120
145
|
onClick: $event => ($options.move(index, index + 1))
|
|
121
146
|
}, [
|
|
122
147
|
createVNode(_component_ChevronDown, { size: 20 })
|
|
123
|
-
], 8 /* PROPS */,
|
|
148
|
+
], 8 /* PROPS */, _hoisted_13),
|
|
124
149
|
createElementVNode("button", {
|
|
125
150
|
type: "button",
|
|
126
151
|
class: "cn-ordered-list-field__button",
|
|
@@ -131,14 +156,14 @@ function render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
131
156
|
onClick: $event => ($options.remove(index))
|
|
132
157
|
}, [
|
|
133
158
|
createVNode(_component_Close, { size: 20 })
|
|
134
|
-
], 8 /* PROPS */,
|
|
159
|
+
], 8 /* PROPS */, _hoisted_14)
|
|
135
160
|
])
|
|
136
|
-
],
|
|
161
|
+
], 42 /* CLASS, PROPS, NEED_HYDRATION */, _hoisted_4))
|
|
137
162
|
}), 128 /* KEYED_FRAGMENT */))
|
|
138
163
|
], 8 /* PROPS */, _hoisted_3))
|
|
139
|
-
: (openBlock(), createElementBlock("p",
|
|
164
|
+
: (openBlock(), createElementBlock("p", _hoisted_15, toDisplayString($props.emptyText || $options.t('nextcloud-vue', 'Nothing added yet.')), 1 /* TEXT */)),
|
|
140
165
|
(!$props.disabled)
|
|
141
|
-
? (openBlock(), createElementBlock("div",
|
|
166
|
+
? (openBlock(), createElementBlock("div", _hoisted_16, [
|
|
142
167
|
createVNode(_component_NcSelect, {
|
|
143
168
|
modelValue: null,
|
|
144
169
|
options: $options.available,
|
|
@@ -153,19 +178,19 @@ function render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
153
178
|
"onUpdate:modelValue": $options.add
|
|
154
179
|
}, {
|
|
155
180
|
option: withCtx((option) => [
|
|
156
|
-
createElementVNode("span",
|
|
181
|
+
createElementVNode("span", _hoisted_17, [
|
|
157
182
|
(option.icon)
|
|
158
|
-
? (openBlock(), createElementBlock("span",
|
|
183
|
+
? (openBlock(), createElementBlock("span", _hoisted_18, [
|
|
159
184
|
createVNode(_component_CnIcon, {
|
|
160
185
|
name: option.icon,
|
|
161
186
|
size: 18
|
|
162
187
|
}, null, 8 /* PROPS */, ["name"])
|
|
163
188
|
]))
|
|
164
189
|
: createCommentVNode("v-if", true),
|
|
165
|
-
createElementVNode("span",
|
|
166
|
-
createElementVNode("span",
|
|
190
|
+
createElementVNode("span", _hoisted_19, [
|
|
191
|
+
createElementVNode("span", _hoisted_20, toDisplayString(option.label), 1 /* TEXT */),
|
|
167
192
|
(option.description)
|
|
168
|
-
? (openBlock(), createElementBlock("span",
|
|
193
|
+
? (openBlock(), createElementBlock("span", _hoisted_21, toDisplayString(option.description), 1 /* TEXT */))
|
|
169
194
|
: createCommentVNode("v-if", true)
|
|
170
195
|
])
|
|
171
196
|
])
|
|
@@ -174,7 +199,7 @@ function render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
174
199
|
}, 8 /* PROPS */, ["options", "inputLabel", "placeholder", "loading", "filterable", "onSearch", "onUpdate:modelValue"])
|
|
175
200
|
]))
|
|
176
201
|
: createCommentVNode("v-if", true),
|
|
177
|
-
createElementVNode("p",
|
|
202
|
+
createElementVNode("p", _hoisted_22, toDisplayString($data.announcement), 1 /* TEXT */)
|
|
178
203
|
]))
|
|
179
204
|
}
|
|
180
205
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CnOrderedListField.vue3.js","sources":["../../../../src/components/CnOrderedListField/CnOrderedListField.vue?vue&type=template&id=3ab313d4&lang.js"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2026 Conduction B.V.\n - SPDX-License-Identifier: EUPL-1.2\n-->\n\n<template>\n\t<div class=\"cn-ordered-list-field\" data-testid=\"cn-ordered-list-field\">\n\t\t<p v-if=\"label\" :id=\"labelId\" class=\"cn-ordered-list-field__label\">\n\t\t\t{{ label }}\n\t\t</p>\n\t\t<ol\n\t\t\tv-if=\"rows.length > 0\"\n\t\t\tclass=\"cn-ordered-list-field__rows\"\n\t\t\t:aria-labelledby=\"label ? labelId : null\"\n\t\t\t:aria-label=\"label ? null : listLabel\">\n\t\t\t<li\n\t\t\t\tv-for=\"(row, index) in rows\"\n\t\t\t\t:key=\"row.value\"\n\t\t\t\tclass=\"cn-ordered-list-field__row\"\n\t\t\t\t:data-testid=\"`cn-ordered-list-row-${row.value}`\">\n\t\t\t\t<span class=\"cn-ordered-list-field__position\" aria-hidden=\"true\">{{ index + 1 }}</span>\n\t\t\t\t<span v-if=\"row.icon\" class=\"cn-ordered-list-field__tile\" aria-hidden=\"true\">\n\t\t\t\t\t<CnIcon :name=\"row.icon\" :size=\"18\" />\n\t\t\t\t</span>\n\t\t\t\t<span class=\"cn-ordered-list-field__text\">\n\t\t\t\t\t<span class=\"cn-ordered-list-field__name\">{{ row.label }}</span>\n\t\t\t\t\t<span v-if=\"row.description\"\n\t\t\t\t\t\t:id=\"descriptionId(row)\"\n\t\t\t\t\t\tclass=\"cn-ordered-list-field__description\"\n\t\t\t\t\t\t:data-testid=\"`cn-ordered-list-description-${row.value}`\">{{ row.description }}</span>\n\t\t\t\t</span>\n\t\t\t\t<span class=\"cn-ordered-list-field__actions\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"cn-ordered-list-field__button\"\n\t\t\t\t\t\t:disabled=\"disabled || index === 0\"\n\t\t\t\t\t\t:aria-label=\"t('nextcloud-vue', 'Move {item} up', { item: row.label })\"\n\t\t\t\t\t\t:data-testid=\"`cn-ordered-list-up-${row.value}`\"\n\t\t\t\t\t\t:aria-describedby=\"row.description ? descriptionId(row) : null\"\n\t\t\t\t\t\t@click=\"move(index, index - 1)\">\n\t\t\t\t\t\t<ChevronUp :size=\"20\" />\n\t\t\t\t\t</button>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"cn-ordered-list-field__button\"\n\t\t\t\t\t\t:disabled=\"disabled || index === rows.length - 1\"\n\t\t\t\t\t\t:aria-label=\"t('nextcloud-vue', 'Move {item} down', { item: row.label })\"\n\t\t\t\t\t\t:data-testid=\"`cn-ordered-list-down-${row.value}`\"\n\t\t\t\t\t\t:aria-describedby=\"row.description ? descriptionId(row) : null\"\n\t\t\t\t\t\t@click=\"move(index, index + 1)\">\n\t\t\t\t\t\t<ChevronDown :size=\"20\" />\n\t\t\t\t\t</button>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"cn-ordered-list-field__button\"\n\t\t\t\t\t\t:disabled=\"disabled\"\n\t\t\t\t\t\t:aria-label=\"t('nextcloud-vue', 'Remove {item}', { item: row.label })\"\n\t\t\t\t\t\t:data-testid=\"`cn-ordered-list-remove-${row.value}`\"\n\t\t\t\t\t\t:aria-describedby=\"row.description ? descriptionId(row) : null\"\n\t\t\t\t\t\t@click=\"remove(index)\">\n\t\t\t\t\t\t<Close :size=\"20\" />\n\t\t\t\t\t</button>\n\t\t\t\t</span>\n\t\t\t</li>\n\t\t</ol>\n\t\t<p v-else class=\"cn-ordered-list-field__empty\" data-testid=\"cn-ordered-list-empty\">\n\t\t\t{{ emptyText || t('nextcloud-vue', 'Nothing added yet.') }}\n\t\t</p>\n\t\t<div v-if=\"!disabled\" class=\"cn-ordered-list-field__add\">\n\t\t\t<NcSelect\n\t\t\t\t:modelValue=\"null\"\n\t\t\t\t:options=\"available\"\n\t\t\t\tlabel=\"label\"\n\t\t\t\t:inputLabel=\"addLabel || t('nextcloud-vue', 'Add')\"\n\t\t\t\t:placeholder=\"addPlaceholder\"\n\t\t\t\t:loading=\"loading\"\n\t\t\t\t:clearable=\"false\"\n\t\t\t\t:filterable=\"!searchable\"\n\t\t\t\tdata-testid=\"cn-ordered-list-add\"\n\t\t\t\t@search=\"onSearch\"\n\t\t\t\t@update:modelValue=\"add\">\n\t\t\t\t<template #option=\"option\">\n\t\t\t\t\t<span class=\"cn-ordered-list-field__option\">\n\t\t\t\t\t\t<span v-if=\"option.icon\" class=\"cn-ordered-list-field__tile\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t<CnIcon :name=\"option.icon\" :size=\"18\" />\n\t\t\t\t\t\t</span>\n\t\t\t\t\t\t<span class=\"cn-ordered-list-field__text\">\n\t\t\t\t\t\t\t<span class=\"cn-ordered-list-field__name\">{{ option.label }}</span>\n\t\t\t\t\t\t\t<span v-if=\"option.description\" class=\"cn-ordered-list-field__description\">{{ option.description }}</span>\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</span>\n\t\t\t\t</template>\n\t\t\t</NcSelect>\n\t\t</div>\n\t\t<p class=\"hidden-visually\" aria-live=\"polite\" data-testid=\"cn-ordered-list-live\">\n\t\t\t{{ announcement }}\n\t\t</p>\n\t</div>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\nimport { NcSelect } from '@nextcloud/vue'\nimport ChevronDown from 'vue-material-design-icons/ChevronDown.vue'\nimport ChevronUp from 'vue-material-design-icons/ChevronUp.vue'\nimport Close from 'vue-material-design-icons/Close.vue'\nimport CnIcon from '../CnIcon/CnIcon.vue'\n\nlet orderedListUid = 0\n\n/**\n * CnOrderedListField - an ordered list a user keeps for themselves: rows in\n * their order with a move up, a move down and a remove button each, and a\n * search-as-you-type picker under it that adds a row (board\n * DqPersoonlijkeInstellingen, \"Zaaktypen in mijn menu\").\n *\n * The app supplies the choices (`options`) and keeps the value: every change\n * emits `update:modelValue` with the new list of values. With `searchable`\n * the picker emits `search` as the user types, so the app can fetch matching\n * choices itself; otherwise it filters `options`. Every move is announced in a\n * polite live region, so reordering works with the keyboard and a screen\n * reader, not by dragging.\n *\n * ```vue\n * <CnOrderedListField\n * v-model=\"menuCaseTypes\"\n * label=\"Case types in my menu\"\n * add-label=\"Add case type\"\n * :options=\"caseTypes\" />\n * ```\n *\n * @spec openspec/changes/ordered-list-field/specs/ordered-list-field/spec.md#requirement-a-user-keeps-an-ordered-list-with-the-keyboard\n */\nexport default {\n\tname: 'CnOrderedListField',\n\n\tcomponents: { ChevronDown, ChevronUp, Close, CnIcon, NcSelect },\n\n\tprops: {\n\t\t/** The values in their order. */\n\t\tmodelValue: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/**\n\t\t * The choices, `{ value, label, description?, icon? }` (a plain string\n\t\t * is its own label). `description` is a muted second line (\"19 open\n\t\t * cases\"), in the row and in the picker; `icon` an MDI name drawn in a\n\t\t * small tile before the label. A value in `modelValue` without a\n\t\t * choice shows the value itself.\n\t\t */\n\t\toptions: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/** The list's label, also its accessible name. */\n\t\tlabel: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** The picker's label. */\n\t\taddLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Placeholder in the picker. */\n\t\taddPlaceholder: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Shown when the list is empty. */\n\t\temptyText: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Whether the app searches (`search` event) instead of the picker filtering `options`. */\n\t\tsearchable: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** Whether the app is fetching choices. */\n\t\tloading: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** A read-only list: no buttons and no picker. */\n\t\tdisabled: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t},\n\n\temits: ['update:modelValue', 'search'],\n\n\tdata() {\n\t\torderedListUid += 1\n\t\treturn {\n\t\t\tlabelId: `cn-ordered-list-label-${orderedListUid}`,\n\t\t\tannouncement: '',\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/** @return {Array<{value: string, label: string}>} The choices in one shape. */\n\t\tchoices() {\n\t\t\treturn (Array.isArray(this.options) ? this.options : [])\n\t\t\t\t.map((option) => (option && typeof option === 'object'\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tvalue: String(option.value ?? option.id ?? ''),\n\t\t\t\t\t\t\tlabel: String(option.label ?? option.title ?? option.value ?? ''),\n\t\t\t\t\t\t\tdescription: typeof option.description === 'string' ? option.description : '',\n\t\t\t\t\t\t\ticon: typeof option.icon === 'string' ? option.icon : '',\n\t\t\t\t\t\t}\n\t\t\t\t\t: { value: String(option), label: String(option), description: '', icon: '' }))\n\t\t\t\t.filter((option) => option.value !== '')\n\t\t},\n\n\t\t/** @return {Array<{value: string, label: string, description: string, icon: string}>} The rows, in order. */\n\t\trows() {\n\t\t\treturn (Array.isArray(this.modelValue) ? this.modelValue : []).map((value) => {\n\t\t\t\tconst key = String(value)\n\t\t\t\tconst choice = this.choices.find((option) => option.value === key)\n\t\t\t\treturn choice || { value: key, label: key, description: '', icon: '' }\n\t\t\t})\n\t\t},\n\n\t\t/** @return {Array<{value: string, label: string}>} The choices not in the list yet. */\n\t\tavailable() {\n\t\t\tconst taken = new Set(this.rows.map((row) => row.value))\n\t\t\treturn this.choices.filter((option) => !taken.has(option.value))\n\t\t},\n\n\t\t/** @return {string} The list's accessible name without a label. */\n\t\tlistLabel() {\n\t\t\treturn t('nextcloud-vue', 'Ordered list')\n\t\t},\n\t},\n\n\tmethods: {\n\t\tt,\n\n\t\t/**\n\t\t * The id of a row's description, which its buttons name as their description.\n\t\t *\n\t\t * @param {{value: string}} row The row.\n\t\t * @return {string}\n\t\t */\n\t\tdescriptionId(row) {\n\t\t\treturn `${this.labelId}-desc-${String(row.value).replace(/[^\\w-]/g, '-')}`\n\t\t},\n\n\t\t/**\n\t\t * Emit the new order.\n\t\t *\n\t\t * @param {Array<string>} values The values.\n\t\t */\n\t\temitValue(values) {\n\t\t\t/**\n\t\t\t * @event update:modelValue The list changed. Payload: the values in their order.\n\t\t\t */\n\t\t\tthis.$emit('update:modelValue', values)\n\t\t},\n\n\t\t/**\n\t\t * Move a row to another place and keep focus on the pressed button\n\t\t * where it still makes sense.\n\t\t *\n\t\t * @param {number} from Its index.\n\t\t * @param {number} to The index it moves to.\n\t\t */\n\t\tmove(from, to) {\n\t\t\tif (to < 0 || to >= this.rows.length) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst values = this.rows.map((row) => row.value)\n\t\t\tconst [value] = values.splice(from, 1)\n\t\t\tvalues.splice(to, 0, value)\n\t\t\tconst row = this.rows[from]\n\t\t\tthis.emitValue(values)\n\t\t\tthis.announcement = t('nextcloud-vue', '{item} moved to position {position} of {total}', { item: row.label, position: to + 1, total: values.length })\n\t\t\tthis.$nextTick(() => {\n\t\t\t\tconst direction = to < from ? 'up' : 'down'\n\t\t\t\tconst atEdge = (direction === 'up' && to === 0) || (direction === 'down' && to === values.length - 1)\n\t\t\t\tconst target = this.$el.querySelector(`[data-testid=\"cn-ordered-list-${atEdge ? (direction === 'up' ? 'down' : 'up') : direction}-${row.value}\"]`)\n\t\t\t\tif (target && !target.disabled) {\n\t\t\t\t\ttarget.focus()\n\t\t\t\t}\n\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * Remove a row.\n\t\t *\n\t\t * @param {number} index Its index.\n\t\t */\n\t\tremove(index) {\n\t\t\tconst row = this.rows[index]\n\t\t\tthis.emitValue(this.rows.filter((_, i) => i !== index).map((r) => r.value))\n\t\t\tthis.announcement = t('nextcloud-vue', '{item} removed', { item: row.label })\n\t\t},\n\n\t\t/**\n\t\t * Add the picked choice at the end.\n\t\t *\n\t\t * @param {{value: string, label: string}|null} option The choice.\n\t\t */\n\t\tadd(option) {\n\t\t\tif (!option) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.emitValue([...this.rows.map((row) => row.value), option.value])\n\t\t\tthis.announcement = t('nextcloud-vue', '{item} added', { item: option.label })\n\t\t},\n\n\t\t/**\n\t\t * Pass the typed text on when the app searches.\n\t\t *\n\t\t * @param {string} query The text.\n\t\t */\n\t\tonSearch(query) {\n\t\t\tif (this.searchable) {\n\t\t\t\t/**\n\t\t\t\t * @event search The user typed in the picker (with `searchable`). Payload: the text.\n\t\t\t\t */\n\t\t\t\tthis.$emit('search', query)\n\t\t\t}\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-ordered-list-field {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 10px;\n}\n\n.cn-ordered-list-field__label {\n\tmargin: 0;\n\tfont-weight: 600;\n}\n\n.cn-ordered-list-field__rows {\n\tdisplay: flex;\n\tflex-direction: column;\n\tmargin: 0;\n\tpadding: 0;\n\tborder: 1px solid var(--color-border);\n\tborder-radius: var(--border-radius-element, 8px);\n\tlist-style: none;\n}\n\n.cn-ordered-list-field__row {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 10px;\n\tmin-height: 44px;\n\tpadding: 2px 6px 2px 12px;\n}\n\n.cn-ordered-list-field__row + .cn-ordered-list-field__row {\n\tborder-top: 1px solid var(--color-border);\n}\n\n.cn-ordered-list-field__position {\n\tflex: none;\n\tmin-width: 18px;\n\tcolor: var(--color-text-maxcontrast);\n\tfont-size: 13px;\n\tfont-variant-numeric: tabular-nums;\n}\n\n.cn-ordered-list-field__text {\n\tflex: 1 1 auto;\n\tmin-width: 0;\n\toverflow-wrap: anywhere;\n}\n\n.cn-ordered-list-field__actions {\n\tdisplay: flex;\n\tflex: none;\n\tgap: 2px;\n}\n\n.cn-ordered-list-field__button {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 40px;\n\tmin-width: 40px;\n\theight: 40px;\n\tmin-height: 40px;\n\tmargin: 0;\n\tpadding: 0;\n\tborder: 0;\n\tborder-radius: var(--border-radius-element, 8px);\n\tbackground: transparent;\n\tcolor: var(--color-main-text);\n\tcursor: pointer;\n}\n\n.cn-ordered-list-field__button:hover:not(:disabled) {\n\tbackground: var(--color-background-hover);\n}\n\n.cn-ordered-list-field__button:focus-visible {\n\toutline: 2px solid var(--color-primary-element);\n\toutline-offset: 1px;\n}\n\n.cn-ordered-list-field__button:disabled {\n\topacity: 0.4;\n\tcursor: default;\n}\n\n.cn-ordered-list-field__empty {\n\tmargin: 0;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-ordered-list-field__tile {\n\tdisplay: inline-flex;\n\tflex: none;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 32px;\n\theight: 32px;\n\tborder-radius: var(--border-radius-element, 8px);\n\tbackground: var(--color-background-dark);\n\tcolor: var(--color-main-text);\n}\n\n.cn-ordered-list-field__name {\n\tdisplay: block;\n}\n\n.cn-ordered-list-field__description {\n\tdisplay: block;\n\tcolor: var(--color-text-maxcontrast);\n\tfont-size: 13px;\n}\n\n.cn-ordered-list-field__option {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 10px;\n\tmin-width: 0;\n}\n</style>\n"],"names":["_openBlock","_createElementBlock","_Fragment","_renderList","_toDisplayString","_createElementVNode","_createVNode","_withCtx"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CnOrderedListField.vue3.js","sources":["../../../../src/components/CnOrderedListField/CnOrderedListField.vue?vue&type=template&id=ca9d4198&lang.js"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2026 Conduction B.V.\n - SPDX-License-Identifier: EUPL-1.2\n-->\n\n<template>\n\t<div class=\"cn-ordered-list-field\" data-testid=\"cn-ordered-list-field\">\n\t\t<p v-if=\"label\" :id=\"labelId\" class=\"cn-ordered-list-field__label\">\n\t\t\t{{ label }}\n\t\t</p>\n\t\t<ol\n\t\t\tv-if=\"rows.length > 0\"\n\t\t\tclass=\"cn-ordered-list-field__rows\"\n\t\t\t:aria-labelledby=\"label ? labelId : null\"\n\t\t\t:aria-label=\"label ? null : listLabel\">\n\t\t\t<li\n\t\t\t\tv-for=\"(row, index) in rows\"\n\t\t\t\t:key=\"row.value\"\n\t\t\t\tclass=\"cn-ordered-list-field__row\"\n\t\t\t\t:class=\"{\n\t\t\t\t\t'cn-ordered-list-field__row--dragging': dragIndex === index,\n\t\t\t\t\t'cn-ordered-list-field__row--over': dropIndex === index && dragIndex !== index,\n\t\t\t\t}\"\n\t\t\t\t:data-testid=\"`cn-ordered-list-row-${row.value}`\"\n\t\t\t\t@dragover.prevent=\"onDragOver(index)\"\n\t\t\t\t@drop.prevent=\"onDrop(index)\">\n\t\t\t\t<!-- A drag handle (DqPersoonlijkeInstellingen). It is a button: a\n\t\t\t\t keyboard user moves the row with the arrow keys on it, and the\n\t\t\t\t up and down buttons stay for anyone who neither drags nor uses\n\t\t\t\t arrow keys. -->\n\t\t\t\t<button\n\t\t\t\t\tv-if=\"!disabled\"\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"cn-ordered-list-field__handle\"\n\t\t\t\t\tdraggable=\"true\"\n\t\t\t\t\t:aria-label=\"t('nextcloud-vue', 'Reorder {item}: drag, or press the up and down arrow keys', { item: row.label })\"\n\t\t\t\t\t:data-testid=\"`cn-ordered-list-handle-${row.value}`\"\n\t\t\t\t\t@dragstart=\"onDragStart($event, index)\"\n\t\t\t\t\t@dragend=\"onDragEnd\"\n\t\t\t\t\t@keydown.up.prevent=\"move(index, index - 1, 'handle')\"\n\t\t\t\t\t@keydown.down.prevent=\"move(index, index + 1, 'handle')\">\n\t\t\t\t\t<DragVertical :size=\"20\" />\n\t\t\t\t</button>\n\t\t\t\t<span class=\"cn-ordered-list-field__position\" aria-hidden=\"true\">{{ index + 1 }}</span>\n\t\t\t\t<span v-if=\"row.icon\" class=\"cn-ordered-list-field__tile\" aria-hidden=\"true\">\n\t\t\t\t\t<CnIcon :name=\"row.icon\" :size=\"18\" />\n\t\t\t\t</span>\n\t\t\t\t<span class=\"cn-ordered-list-field__text\">\n\t\t\t\t\t<span class=\"cn-ordered-list-field__name\">{{ row.label }}</span>\n\t\t\t\t\t<span v-if=\"row.description\"\n\t\t\t\t\t\t:id=\"descriptionId(row)\"\n\t\t\t\t\t\tclass=\"cn-ordered-list-field__description\"\n\t\t\t\t\t\t:data-testid=\"`cn-ordered-list-description-${row.value}`\">{{ row.description }}</span>\n\t\t\t\t</span>\n\t\t\t\t<span class=\"cn-ordered-list-field__actions\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"cn-ordered-list-field__button\"\n\t\t\t\t\t\t:disabled=\"disabled || index === 0\"\n\t\t\t\t\t\t:aria-label=\"t('nextcloud-vue', 'Move {item} up', { item: row.label })\"\n\t\t\t\t\t\t:data-testid=\"`cn-ordered-list-up-${row.value}`\"\n\t\t\t\t\t\t:aria-describedby=\"row.description ? descriptionId(row) : null\"\n\t\t\t\t\t\t@click=\"move(index, index - 1)\">\n\t\t\t\t\t\t<ChevronUp :size=\"20\" />\n\t\t\t\t\t</button>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"cn-ordered-list-field__button\"\n\t\t\t\t\t\t:disabled=\"disabled || index === rows.length - 1\"\n\t\t\t\t\t\t:aria-label=\"t('nextcloud-vue', 'Move {item} down', { item: row.label })\"\n\t\t\t\t\t\t:data-testid=\"`cn-ordered-list-down-${row.value}`\"\n\t\t\t\t\t\t:aria-describedby=\"row.description ? descriptionId(row) : null\"\n\t\t\t\t\t\t@click=\"move(index, index + 1)\">\n\t\t\t\t\t\t<ChevronDown :size=\"20\" />\n\t\t\t\t\t</button>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"cn-ordered-list-field__button\"\n\t\t\t\t\t\t:disabled=\"disabled\"\n\t\t\t\t\t\t:aria-label=\"t('nextcloud-vue', 'Remove {item}', { item: row.label })\"\n\t\t\t\t\t\t:data-testid=\"`cn-ordered-list-remove-${row.value}`\"\n\t\t\t\t\t\t:aria-describedby=\"row.description ? descriptionId(row) : null\"\n\t\t\t\t\t\t@click=\"remove(index)\">\n\t\t\t\t\t\t<Close :size=\"20\" />\n\t\t\t\t\t</button>\n\t\t\t\t</span>\n\t\t\t</li>\n\t\t</ol>\n\t\t<p v-else class=\"cn-ordered-list-field__empty\" data-testid=\"cn-ordered-list-empty\">\n\t\t\t{{ emptyText || t('nextcloud-vue', 'Nothing added yet.') }}\n\t\t</p>\n\t\t<div v-if=\"!disabled\" class=\"cn-ordered-list-field__add\">\n\t\t\t<NcSelect\n\t\t\t\t:modelValue=\"null\"\n\t\t\t\t:options=\"available\"\n\t\t\t\tlabel=\"label\"\n\t\t\t\t:inputLabel=\"addLabel || t('nextcloud-vue', 'Add')\"\n\t\t\t\t:placeholder=\"addPlaceholder\"\n\t\t\t\t:loading=\"loading\"\n\t\t\t\t:clearable=\"false\"\n\t\t\t\t:filterable=\"!searchable\"\n\t\t\t\tdata-testid=\"cn-ordered-list-add\"\n\t\t\t\t@search=\"onSearch\"\n\t\t\t\t@update:modelValue=\"add\">\n\t\t\t\t<template #option=\"option\">\n\t\t\t\t\t<span class=\"cn-ordered-list-field__option\">\n\t\t\t\t\t\t<span v-if=\"option.icon\" class=\"cn-ordered-list-field__tile\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t<CnIcon :name=\"option.icon\" :size=\"18\" />\n\t\t\t\t\t\t</span>\n\t\t\t\t\t\t<span class=\"cn-ordered-list-field__text\">\n\t\t\t\t\t\t\t<span class=\"cn-ordered-list-field__name\">{{ option.label }}</span>\n\t\t\t\t\t\t\t<span v-if=\"option.description\" class=\"cn-ordered-list-field__description\">{{ option.description }}</span>\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</span>\n\t\t\t\t</template>\n\t\t\t</NcSelect>\n\t\t</div>\n\t\t<p class=\"hidden-visually\" aria-live=\"polite\" data-testid=\"cn-ordered-list-live\">\n\t\t\t{{ announcement }}\n\t\t</p>\n\t</div>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\nimport { NcSelect } from '@nextcloud/vue'\nimport ChevronDown from 'vue-material-design-icons/ChevronDown.vue'\nimport ChevronUp from 'vue-material-design-icons/ChevronUp.vue'\nimport Close from 'vue-material-design-icons/Close.vue'\nimport DragVertical from 'vue-material-design-icons/DragVertical.vue'\nimport CnIcon from '../CnIcon/CnIcon.vue'\n\nlet orderedListUid = 0\n\n/**\n * CnOrderedListField - an ordered list a user keeps for themselves: rows in\n * their order with a move up, a move down and a remove button each, and a\n * search-as-you-type picker under it that adds a row (board\n * DqPersoonlijkeInstellingen, \"Zaaktypen in mijn menu\").\n *\n * The app supplies the choices (`options`) and keeps the value: every change\n * emits `update:modelValue` with the new list of values. With `searchable`\n * the picker emits `search` as the user types, so the app can fetch matching\n * choices itself; otherwise it filters `options`. Every move is announced in a\n * polite live region, so reordering works with the keyboard and a screen\n * reader, not by dragging.\n *\n * ```vue\n * <CnOrderedListField\n * v-model=\"menuCaseTypes\"\n * label=\"Case types in my menu\"\n * add-label=\"Add case type\"\n * :options=\"caseTypes\" />\n * ```\n *\n * @spec openspec/changes/ordered-list-field/specs/ordered-list-field/spec.md#requirement-a-user-keeps-an-ordered-list-with-the-keyboard\n */\nexport default {\n\tname: 'CnOrderedListField',\n\n\tcomponents: { ChevronDown, ChevronUp, Close, CnIcon, DragVertical, NcSelect },\n\n\tprops: {\n\t\t/** The values in their order. */\n\t\tmodelValue: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/**\n\t\t * The choices, `{ value, label, description?, icon? }` (a plain string\n\t\t * is its own label). `description` is a muted second line (\"19 open\n\t\t * cases\"), in the row and in the picker; `icon` an MDI name drawn in a\n\t\t * small tile before the label. A value in `modelValue` without a\n\t\t * choice shows the value itself.\n\t\t */\n\t\toptions: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/** The list's label, also its accessible name. */\n\t\tlabel: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** The picker's label. */\n\t\taddLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Placeholder in the picker. */\n\t\taddPlaceholder: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Shown when the list is empty. */\n\t\temptyText: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Whether the app searches (`search` event) instead of the picker filtering `options`. */\n\t\tsearchable: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** Whether the app is fetching choices. */\n\t\tloading: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** A read-only list: no buttons and no picker. */\n\t\tdisabled: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t},\n\n\temits: ['update:modelValue', 'search'],\n\n\tdata() {\n\t\torderedListUid += 1\n\t\treturn {\n\t\t\tlabelId: `cn-ordered-list-label-${orderedListUid}`,\n\t\t\tannouncement: '',\n\t\t\t/** The value whose handle takes focus after the next render, or null. */\n\t\t\tpendingHandleFocus: null,\n\t\t\t/** The index of the row being dragged, or -1. */\n\t\t\tdragIndex: -1,\n\t\t\t/** The index of the row the drag is over, or -1. */\n\t\t\tdropIndex: -1,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/** @return {Array<{value: string, label: string}>} The choices in one shape. */\n\t\tchoices() {\n\t\t\treturn (Array.isArray(this.options) ? this.options : [])\n\t\t\t\t.map((option) => (option && typeof option === 'object'\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tvalue: String(option.value ?? option.id ?? ''),\n\t\t\t\t\t\t\tlabel: String(option.label ?? option.title ?? option.value ?? ''),\n\t\t\t\t\t\t\tdescription: typeof option.description === 'string' ? option.description : '',\n\t\t\t\t\t\t\ticon: typeof option.icon === 'string' ? option.icon : '',\n\t\t\t\t\t\t}\n\t\t\t\t\t: { value: String(option), label: String(option), description: '', icon: '' }))\n\t\t\t\t.filter((option) => option.value !== '')\n\t\t},\n\n\t\t/** @return {Array<{value: string, label: string, description: string, icon: string}>} The rows, in order. */\n\t\trows() {\n\t\t\treturn (Array.isArray(this.modelValue) ? this.modelValue : []).map((value) => {\n\t\t\t\tconst key = String(value)\n\t\t\t\tconst choice = this.choices.find((option) => option.value === key)\n\t\t\t\treturn choice || { value: key, label: key, description: '', icon: '' }\n\t\t\t})\n\t\t},\n\n\t\t/** @return {Array<{value: string, label: string}>} The choices not in the list yet. */\n\t\tavailable() {\n\t\t\tconst taken = new Set(this.rows.map((row) => row.value))\n\t\t\treturn this.choices.filter((option) => !taken.has(option.value))\n\t\t},\n\n\t\t/** @return {string} The list's accessible name without a label. */\n\t\tlistLabel() {\n\t\t\treturn t('nextcloud-vue', 'Ordered list')\n\t\t},\n\t},\n\n\twatch: {\n\t\t// The parent's new order arrives as new rows; the moved row's handle\n\t\t// lost focus when its row moved in the DOM, so it takes it back.\n\t\trows: {\n\t\t\tflush: 'post',\n\t\t\thandler() {\n\t\t\t\tif (this.pendingHandleFocus !== null) {\n\t\t\t\t\tthis.focusPendingHandle()\n\t\t\t\t\tthis.pendingHandleFocus = null\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t},\n\n\tmethods: {\n\t\tt,\n\n\t\t/**\n\t\t * The id of a row's description, which its buttons name as their description.\n\t\t *\n\t\t * @param {{value: string}} row The row.\n\t\t * @return {string}\n\t\t */\n\t\tdescriptionId(row) {\n\t\t\treturn `${this.labelId}-desc-${String(row.value).replace(/[^\\w-]/g, '-')}`\n\t\t},\n\n\t\t/**\n\t\t * Emit the new order.\n\t\t *\n\t\t * @param {Array<string>} values The values.\n\t\t */\n\t\temitValue(values) {\n\t\t\t/**\n\t\t\t * @event update:modelValue The list changed. Payload: the values in their order.\n\t\t\t */\n\t\t\tthis.$emit('update:modelValue', values)\n\t\t},\n\n\t\t/**\n\t\t * Move a row to another place and keep focus on the pressed control\n\t\t * where it still makes sense: the row's handle after an arrow key on\n\t\t * it, else the up or down button.\n\t\t *\n\t\t * @param {number} from Its index.\n\t\t * @param {number} to The index it moves to.\n\t\t * @param {string} [via] `handle` when the move came from the handle.\n\t\t */\n\t\tmove(from, to, via = '') {\n\t\t\tif (to < 0 || to >= this.rows.length) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst values = this.rows.map((row) => row.value)\n\t\t\tconst [value] = values.splice(from, 1)\n\t\t\tvalues.splice(to, 0, value)\n\t\t\tconst row = this.rows[from]\n\t\t\tthis.emitValue(values)\n\t\t\tthis.announcement = t('nextcloud-vue', '{item} moved to position {position} of {total}', { item: row.label, position: to + 1, total: values.length })\n\t\t\tif (via === 'handle') {\n\t\t\t\t// Re-focused once the parent hands the new order back: moving the\n\t\t\t\t// row in the DOM takes focus off its handle.\n\t\t\t\tthis.pendingHandleFocus = row.value\n\t\t\t}\n\t\t\tthis.$nextTick(() => {\n\t\t\t\tif (via === 'handle') {\n\t\t\t\t\tthis.focusPendingHandle()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tconst direction = to < from ? 'up' : 'down'\n\t\t\t\tconst atEdge = (direction === 'up' && to === 0) || (direction === 'down' && to === values.length - 1)\n\t\t\t\tconst target = this.$el.querySelector(`[data-testid=\"cn-ordered-list-${atEdge ? (direction === 'up' ? 'down' : 'up') : direction}-${row.value}\"]`)\n\t\t\t\tif (target && !target.disabled) {\n\t\t\t\t\ttarget.focus()\n\t\t\t\t}\n\t\t\t})\n\t\t},\n\n\t\t/** Put focus back on the handle of the row just moved by its handle. */\n\t\tfocusPendingHandle() {\n\t\t\tif (this.pendingHandleFocus === null) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst handle = this.$el.querySelector(`[data-testid=\"cn-ordered-list-handle-${this.pendingHandleFocus}\"]`)\n\t\t\tif (handle) {\n\t\t\t\thandle.focus()\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Start dragging a row by its handle.\n\t\t *\n\t\t * @param {DragEvent} event The drag event.\n\t\t * @param {number} index The row's index.\n\t\t */\n\t\tonDragStart(event, index) {\n\t\t\tthis.dragIndex = index\n\t\t\tif (event && event.dataTransfer) {\n\t\t\t\tevent.dataTransfer.effectAllowed = 'move'\n\t\t\t\tevent.dataTransfer.setData('text/plain', String(this.rows[index].value))\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Mark the row a drag is over as where the row will land.\n\t\t *\n\t\t * @param {number} index The row's index.\n\t\t */\n\t\tonDragOver(index) {\n\t\t\tif (this.dragIndex !== -1) {\n\t\t\t\tthis.dropIndex = index\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Drop the dragged row in the place of the row it is over.\n\t\t *\n\t\t * @param {number} index The row's index.\n\t\t */\n\t\tonDrop(index) {\n\t\t\tconst from = this.dragIndex\n\t\t\tthis.onDragEnd()\n\t\t\tif (from !== -1 && from !== index) {\n\t\t\t\tthis.move(from, index, 'handle')\n\t\t\t}\n\t\t},\n\n\t\t/** End a drag, dropped or not. */\n\t\tonDragEnd() {\n\t\t\tthis.dragIndex = -1\n\t\t\tthis.dropIndex = -1\n\t\t},\n\n\t\t/**\n\t\t * Remove a row.\n\t\t *\n\t\t * @param {number} index Its index.\n\t\t */\n\t\tremove(index) {\n\t\t\tconst row = this.rows[index]\n\t\t\tthis.emitValue(this.rows.filter((_, i) => i !== index).map((r) => r.value))\n\t\t\tthis.announcement = t('nextcloud-vue', '{item} removed', { item: row.label })\n\t\t},\n\n\t\t/**\n\t\t * Add the picked choice at the end.\n\t\t *\n\t\t * @param {{value: string, label: string}|null} option The choice.\n\t\t */\n\t\tadd(option) {\n\t\t\tif (!option) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.emitValue([...this.rows.map((row) => row.value), option.value])\n\t\t\tthis.announcement = t('nextcloud-vue', '{item} added', { item: option.label })\n\t\t},\n\n\t\t/**\n\t\t * Pass the typed text on when the app searches.\n\t\t *\n\t\t * @param {string} query The text.\n\t\t */\n\t\tonSearch(query) {\n\t\t\tif (this.searchable) {\n\t\t\t\t/**\n\t\t\t\t * @event search The user typed in the picker (with `searchable`). Payload: the text.\n\t\t\t\t */\n\t\t\t\tthis.$emit('search', query)\n\t\t\t}\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-ordered-list-field {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 10px;\n}\n\n.cn-ordered-list-field__label {\n\tmargin: 0;\n\tfont-weight: 600;\n}\n\n.cn-ordered-list-field__rows {\n\tdisplay: flex;\n\tflex-direction: column;\n\tmargin: 0;\n\tpadding: 0;\n\tborder: 1px solid var(--color-border);\n\tborder-radius: var(--border-radius-element, 8px);\n\tlist-style: none;\n}\n\n.cn-ordered-list-field__row {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 10px;\n\tmin-height: 44px;\n\tpadding: 2px 6px 2px 12px;\n}\n\n.cn-ordered-list-field__row + .cn-ordered-list-field__row {\n\tborder-top: 1px solid var(--color-border);\n}\n\n.cn-ordered-list-field__row--dragging {\n\topacity: 0.5;\n}\n\n/* Where a dragged row will land: a primary line on the row's top edge. */\n.cn-ordered-list-field__row--over {\n\tbox-shadow: inset 0 2px 0 var(--color-primary-element);\n}\n\n.cn-ordered-list-field__handle {\n\tdisplay: inline-flex;\n\tflex: none;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 28px;\n\tmin-width: 28px;\n\theight: 34px;\n\tmin-height: 34px;\n\tmargin: 0 -6px 0 -8px;\n\tpadding: 0;\n\tborder: 0;\n\tborder-radius: var(--border-radius-element, 8px);\n\tbackground: transparent;\n\tcolor: var(--color-text-maxcontrast);\n\tcursor: grab;\n}\n\n.cn-ordered-list-field__handle:active {\n\tcursor: grabbing;\n}\n\n.cn-ordered-list-field__handle:focus-visible {\n\toutline: 2px solid var(--color-primary-element);\n\toutline-offset: 1px;\n}\n\n.cn-ordered-list-field__position {\n\tflex: none;\n\tmin-width: 18px;\n\tcolor: var(--color-text-maxcontrast);\n\tfont-size: 13px;\n\tfont-variant-numeric: tabular-nums;\n}\n\n.cn-ordered-list-field__text {\n\tflex: 1 1 auto;\n\tmin-width: 0;\n\toverflow-wrap: anywhere;\n}\n\n.cn-ordered-list-field__actions {\n\tdisplay: flex;\n\tflex: none;\n\tgap: 2px;\n}\n\n.cn-ordered-list-field__button {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 40px;\n\tmin-width: 40px;\n\theight: 40px;\n\tmin-height: 40px;\n\tmargin: 0;\n\tpadding: 0;\n\tborder: 0;\n\tborder-radius: var(--border-radius-element, 8px);\n\tbackground: transparent;\n\tcolor: var(--color-main-text);\n\tcursor: pointer;\n}\n\n.cn-ordered-list-field__button:hover:not(:disabled) {\n\tbackground: var(--color-background-hover);\n}\n\n.cn-ordered-list-field__button:focus-visible {\n\toutline: 2px solid var(--color-primary-element);\n\toutline-offset: 1px;\n}\n\n.cn-ordered-list-field__button:disabled {\n\topacity: 0.4;\n\tcursor: default;\n}\n\n.cn-ordered-list-field__empty {\n\tmargin: 0;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-ordered-list-field__tile {\n\tdisplay: inline-flex;\n\tflex: none;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 32px;\n\theight: 32px;\n\tborder-radius: var(--border-radius-element, 8px);\n\tbackground: var(--color-background-dark);\n\tcolor: var(--color-main-text);\n}\n\n.cn-ordered-list-field__name {\n\tdisplay: block;\n}\n\n.cn-ordered-list-field__description {\n\tdisplay: block;\n\tcolor: var(--color-text-maxcontrast);\n\tfont-size: 13px;\n}\n\n.cn-ordered-list-field__option {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 10px;\n\tmin-width: 0;\n}\n</style>\n"],"names":["_openBlock","_createElementBlock","_Fragment","_renderList","_withModifiers","_createVNode","_toDisplayString","_createElementVNode","_withCtx"],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ import script from './CnQuickFilterBar.vue2.js';
|
|
|
2
2
|
import { render } from './CnQuickFilterBar.vue3.js';
|
|
3
3
|
|
|
4
4
|
script.render = render;
|
|
5
|
-
script.__scopeId = "data-v-
|
|
5
|
+
script.__scopeId = "data-v-2d5e5fa6";
|
|
6
6
|
const __sfc_main = script;
|
|
7
7
|
|
|
8
8
|
export { __sfc_main as default };
|