Skip to content

Commit b69034f

Browse files
authored
Merge pull request #6791 from nextcloud-libraries/backport/6732/stable8
[stable8] feat: provide `NcSelectUsers` as replacement of `user-select` prop for `NcSelect`
2 parents 0a2de64 + a48b4cd commit b69034f

File tree

5 files changed

+436
-194
lines changed

5 files changed

+436
-194
lines changed

l10n/messages.pot

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,9 @@ msgstr ""
352352
msgid "Select a tag"
353353
msgstr ""
354354

355+
msgid "Select account"
356+
msgstr ""
357+
355358
msgid "Select provider"
356359
msgstr ""
357360

src/components/NcSelect/NcSelect.vue

Lines changed: 42 additions & 194 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ const selectArray = [
6868
{
6969
props: {
7070
inputLabel: 'Multiple (objects, pre-selected, stay open on select)',
71+
keepOpen: true,
7172
multiple: true,
72-
closeOnSelect: false,
7373
options: [
7474
{
7575
id: 'foo',
@@ -234,7 +234,7 @@ const data1 = {
234234
props: {
235235
inputLabel: 'Wrapped (Default)',
236236
multiple: true,
237-
closeOnSelect: false,
237+
keepOpen: true,
238238
options: [
239239
'foo',
240240
'bar',
@@ -265,8 +265,8 @@ const data1 = {
265265
const data2 = {
266266
props: {
267267
inputLabel: 'Not wrapped',
268+
keepOpen: true,
268269
multiple: true,
269-
closeOnSelect: false,
270270
options: [
271271
'foo',
272272
'bar',
@@ -319,178 +319,6 @@ export default {
319319
}
320320
</style>
321321
```
322-
323-
### User select examples
324-
325-
```vue
326-
<template>
327-
<div class="grid">
328-
<div v-for="{ props } in selectArray"
329-
class="container">
330-
<NcSelect v-bind="props"
331-
v-model="props.value" />
332-
</div>
333-
</div>
334-
</template>
335-
336-
<script>
337-
import AccountGroup from '@mdi/svg/svg/account-group.svg?raw'
338-
import Email from '@mdi/svg/svg/email.svg?raw'
339-
340-
const selectArray = [
341-
{
342-
props: {
343-
inputLabel: 'User select',
344-
userSelect: true,
345-
options: [
346-
{
347-
id: '0-john',
348-
displayName: 'John',
349-
isNoUser: false,
350-
subname: 'john@example.org',
351-
icon: '',
352-
// Example of how to show the user status within the option
353-
user: '0-john',
354-
preloadedUserStatus: {
355-
icon: '',
356-
status: 'online',
357-
message: 'I am online',
358-
},
359-
},
360-
{
361-
id: '0-emma',
362-
displayName: 'Emma',
363-
isNoUser: false,
364-
subname: 'emma@example.org',
365-
icon: '',
366-
},
367-
{
368-
id: '0-olivia',
369-
displayName: 'Olivia',
370-
isNoUser: false,
371-
subname: 'olivia@example.org',
372-
icon: '',
373-
},
374-
{
375-
id: '0-noah',
376-
displayName: 'Noah',
377-
isNoUser: false,
378-
subname: 'noah@example.org',
379-
icon: '',
380-
},
381-
{
382-
id: '0-oliver',
383-
displayName: 'Oliver',
384-
isNoUser: false,
385-
subname: 'oliver@example.org',
386-
icon: '',
387-
},
388-
{
389-
id: '1-admin',
390-
displayName: 'Admin',
391-
isNoUser: true,
392-
subname: null,
393-
iconSvg: AccountGroup,
394-
iconName: 'Group icon',
395-
},
396-
{
397-
id: '2-org@example.org',
398-
displayName: 'Organization',
399-
isNoUser: true,
400-
subname: 'org@example.org',
401-
iconSvg: Email,
402-
iconName: 'Email icon',
403-
},
404-
],
405-
},
406-
},
407-
408-
{
409-
props: {
410-
inputLabel: 'Multiple user select (stay open on select)',
411-
userSelect: true,
412-
multiple: true,
413-
closeOnSelect: false,
414-
options: [
415-
{
416-
id: '0-john',
417-
displayName: 'John',
418-
isNoUser: false,
419-
subname: 'john@example.org',
420-
icon: '',
421-
},
422-
{
423-
id: '0-emma',
424-
displayName: 'Emma',
425-
isNoUser: false,
426-
subname: 'emma@example.org',
427-
icon: '',
428-
},
429-
{
430-
id: '0-olivia',
431-
displayName: 'Olivia',
432-
isNoUser: false,
433-
subname: 'olivia@example.org',
434-
icon: '',
435-
},
436-
{
437-
id: '0-noah',
438-
displayName: 'Noah',
439-
isNoUser: false,
440-
subname: 'noah@example.org',
441-
icon: '',
442-
},
443-
{
444-
id: '0-oliver',
445-
displayName: 'Oliver',
446-
isNoUser: false,
447-
subname: 'oliver@example.org',
448-
icon: '',
449-
},
450-
{
451-
id: '1-admin',
452-
displayName: 'Admin',
453-
isNoUser: true,
454-
subname: null,
455-
iconSvg: AccountGroup,
456-
iconName: 'Group icon',
457-
},
458-
{
459-
id: '2-org@example.org',
460-
displayName: 'Organization',
461-
isNoUser: true,
462-
subname: 'org@example.org',
463-
iconSvg: Email,
464-
iconName: 'Email icon',
465-
},
466-
],
467-
},
468-
},
469-
]
470-
471-
export default {
472-
data() {
473-
return {
474-
selectArray,
475-
}
476-
},
477-
}
478-
</script>
479-
480-
<style>
481-
.grid {
482-
display: grid;
483-
grid-template-columns: repeat(1, 500px);
484-
gap: 10px;
485-
}
486-
487-
.container {
488-
display: flex;
489-
flex-direction: column;
490-
gap: 2px 0;
491-
}
492-
</style>
493-
```
494322
</docs>
495323

496324
<template>
@@ -525,25 +353,31 @@ export default {
525353
<!-- Set size to 26 to make up for the increased padding of this icon -->
526354
</template>
527355
<template #option="option">
528-
<NcListItemIcon v-if="userSelect"
529-
v-bind="option"
530-
:avatar-size="32"
531-
:name="option[localLabel]"
532-
:search="search" />
533-
<NcEllipsisedOption v-else
534-
:name="String(option[localLabel])"
535-
:search="search" />
356+
<!-- @slot Customize how a option is rendered. -->
357+
<slot name="option" v-bind="option">
358+
<NcListItemIcon v-if="userSelect"
359+
v-bind="option"
360+
:avatar-size="32"
361+
:name="option[localLabel]"
362+
:search="search" />
363+
<NcEllipsisedOption v-else
364+
:name="String(option[localLabel])"
365+
:search="search" />
366+
</slot>
536367
</template>
537368
<template #selected-option="selectedOption">
538-
<NcListItemIcon v-if="userSelect"
539-
v-bind="selectedOption"
540-
:avatar-size="avatarSize"
541-
:name="selectedOption[localLabel]"
542-
no-margin
543-
:search="search" />
544-
<NcEllipsisedOption v-else
545-
:name="String(selectedOption[localLabel])"
546-
:search="search" />
369+
<!-- @slot Customize how a selected option is rendered -->
370+
<slot name="selected-option" :v-bind="selectedOption">
371+
<NcListItemIcon v-if="userSelect"
372+
v-bind="selectedOption"
373+
:avatar-size="avatarSize"
374+
:name="selectedOption[localLabel]"
375+
no-margin
376+
:search="search" />
377+
<NcEllipsisedOption v-else
378+
:name="String(selectedOption[localLabel])"
379+
:search="search" />
380+
</slot>
547381
</template>
548382
<template #spinner="spinner">
549383
<NcLoadingIcon v-if="spinner.loading" />
@@ -667,15 +501,26 @@ export default {
667501
},
668502
669503
/**
670-
* Close the dropdown when selecting an option
504+
* Close the dropdown when selecting an option.
671505
*
672-
* @see https://vue-select.org/api/props.html#closeonselect
506+
* @deprecated Use the `keepOpen` prop instead
673507
*/
674508
closeOnSelect: {
675509
type: Boolean,
676510
default: true,
677511
},
678512
513+
/**
514+
* Keep the dropdown open after selecting an option.
515+
*
516+
* @default false
517+
* @since 8.25.0
518+
*/
519+
keepOpen: {
520+
type: Boolean,
521+
default: false,
522+
},
523+
679524
/**
680525
* Replace default vue-select components
681526
*
@@ -927,6 +772,8 @@ export default {
927772
* Objects must contain the data expected by the
928773
* [NcListItemIcon](#/Components/NcListItemIcon) and
929774
* [NcAvatar](#/Components/NcAvatar) components
775+
*
776+
* @deprecated Use the `NcSelectUsers` component instead
930777
*/
931778
userSelect: {
932779
type: Boolean,
@@ -1122,6 +969,7 @@ export default {
1122969
// Custom overrides of vue-select props
1123970
value: this.model,
1124971
calculatePosition: this.localCalculatePosition,
972+
closeOnSelect: this.closeOnSelect && !this.keepOpen,
1125973
filterBy: this.localFilterBy,
1126974
label: this.localLabel,
1127975
}

0 commit comments

Comments
 (0)