Skip to content
This repository has been archived by the owner on Jan 3, 2024. It is now read-only.

Commit

Permalink
OcSelect: Add optionLabel prop which is passed as label to vue-select
Browse files Browse the repository at this point in the history
  • Loading branch information
dschmidt committed Sep 4, 2021
1 parent f889be9 commit 628e848
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 24 deletions.
8 changes: 8 additions & 0 deletions changelog/unreleased/change-ocselect-label
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Change: Label for OcSelect

We've added a configurable `<label>` for OcSelect accessible via the `label` property.
This shadows the `label` property of `vue-select`. Hence we introduced the `optionLabel`
property on OcSelect which maps to the `label` property of `vue-select`.

https://github.com/owncloud/owncloud-design-system/pull/1570/
https://github.com/owncloud/owncloud-design-system/issues/1503
5 changes: 0 additions & 5 deletions changelog/unreleased/enhancement-ocselect-label

This file was deleted.

117 changes: 98 additions & 19 deletions src/components/OcSelect.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
<template>
<div>
<label :for="this.$attrs['input-id']" v-text="setLabel" />
<label :for="id" v-text="label" />
<vue-select
ref="select"
:input-id="id"
:value="model"
class="oc-select"
v-bind="setCustomizedAttrs()"
v-bind="additionalAttributes"
v-on="$listeners"
>
<template v-for="(index, name) in $scopedSlots" #[name]="data">
Expand All @@ -17,6 +18,7 @@
</template>

<script>
import uniqueId from "../utils/uniqueId"
import VueSelect from "vue-select"
import "vue-select/dist/vue-select.css"
Expand All @@ -36,31 +38,59 @@ export default {
},
props: {
/**
* The ID of the element.
*/
id: {
type: String,
required: false,
default: () => uniqueId("oc-select-"),
},
/**
* The model of the select component. Provide it as value or bind it with v-model.
**/
model: {
type: [Array, String, Object],
required: false,
default: null,
},
/**
* Label of the select component
* ATTENTION: this shadows the vue-select prop `label`. If you need access to that use `optionLabel`.
*/
label: {
type: String,
default: null,
},
/**
* Key to use as label when option is an object
* NOTE: this maps to the vue-select prop `label`
*/
optionLabel: {
type: String,
default: null,
},
},
computed: {
setLabel() {
return this.$attrs["label"]
additionalAttributes() {
const additionalAttrs = {}
if (this.optionLabel) {
additionalAttrs["label"] = this.optionLabel
}
return { ...this.$attrs, ...additionalAttrs }
},
},
mounted() {
this.setComboBoxAriaLabel()
},
methods: {
setComboBoxAriaLabel() {
const comboBoxElement = this.$refs.select.$el.querySelector("div:first-child")
comboBoxElement.setAttribute("aria-label", this.$gettext("Search for option"))
},
setCustomizedAttrs() {
const customAttrs = this.$attrs
delete customAttrs.label
return customAttrs
},
},
}
</script>
Expand Down Expand Up @@ -117,7 +147,7 @@ For detailed documentation (props, slots, events, etc.), please visit https://vu
```js
<template>
<div class="oc-docs-width-medium">
<oc-select label="Custom label" input-id="my-custom-id" v-model="selected" :options="['Bannana', 'Orange', 'Pear']" />
<oc-select label="Custom label" v-model="selected" :options="['Bannana', 'Orange', 'Pear']" />
</div>
</template>
<script>
Expand Down Expand Up @@ -165,19 +195,68 @@ export default {
</script>
```

### Use objects as options
If we want to select from a list of option objects, we can use `option-label` to select the key of the object to use as label.

```js
<template>
<div class="oc-docs-width-medium">
<oc-select
label="Custom Label"
option-label="title"
:options="options"
v-model="selected"
class="oc-mb-m"
/>
</div>
</template>
<script>
const options = [
{
title: 'Apple',
desc: 'An apple is an edible fruit produced by an apple tree (Malus domestica)'
},
{
title: 'Bannana',
desc: 'Bannana is a genus of goblin spiders (family Oonopidae) native to Xishuangbanna prefecture, Yunnan Province, China, where it lives in the leaf-litter of tropical rainforest'
},
{
title: 'Orange',
desc: 'The orange is the fruit of various citrus species in the family Rutaceae'
},
]
export default {
data: () => ({
selected: options[1],
options
})
}
</script>
```




### Using slots to display complex options
Sometimes we need to display more complex options. This can include e.g. an option with a title and a description.
To still display all those values exactly as we want to, we need to use scoped slot called `option`.
We can then retrieve all the values that we want to display from the slots parametres.
It is important to use a `label` key inside the passed object since `oc-select` will look for it.
Sometimes we need to display more complex options. This can include e.g. an option with a title and a description. To
still display all those values exactly as we want to, we need to use scoped slots called `option` and `selected-option`.
We can then retrieve all the values that we want to display from the slot parameters.
It is important to specify the `option-label` prop on the `oc-select` to make filtering work.

```js
<template>
<div class="oc-docs-width-medium">
<oc-select v-model="selected" :options="options" class="oc-mb-m">
<oc-select
label="Custom Label"
option-label="title"
:options="options"
v-model="selected"
class="oc-mb-m"
>
<template v-slot:option="{ title, desc }">
<span class="option">
<strong v-text="label" />
<strong v-text="title" />
</span>
<span class="option" v-text="desc" />
</template>
Expand All @@ -193,15 +272,15 @@ It is important to use a `label` key inside the passed object since `oc-select`
<script>
const options = [
{
label: 'Apple',
title: 'Apple',
desc: 'An apple is an edible fruit produced by an apple tree (Malus domestica)'
},
{
label: 'Bannana',
title: 'Bannana',
desc: 'Bannana is a genus of goblin spiders (family Oonopidae) native to Xishuangbanna prefecture, Yunnan Province, China, where it lives in the leaf-litter of tropical rainforest'
},
{
label: 'Orange',
title: 'Orange',
desc: 'The orange is the fruit of various citrus species in the family Rutaceae'
},
]
Expand Down

0 comments on commit 628e848

Please sign in to comment.