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

OcSelect: add support for showing default values #1634

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions changelog/unreleased/enhancement-ocselect-default-value
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Enhancement: Add support for showing default values in OcSelect

We've added a `defaultValue` prop to OcSelect.

The value provided as `defaultValue` is selected when the actual `value` is `null`.
When the default value is shown the clear button is hidden because you can't clear the default.

https://github.com/owncloud/owncloud-design-system/pull/1634
103 changes: 93 additions & 10 deletions src/components/OcSelect.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@
<label :for="id" v-text="label" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<label :for="id" v-text="label" />
<label :for="id" class="oc-label" v-text="label" />

Just checked how the update journey in web would look like and we seem to give all labels this class, which doesn't style anything initially but sometimes is used to target the label for styling

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense but possibly belongs into the original pr

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, but that one is merged already (and I somehow ended here without understanding this is not the original ;D my bad, could you include it either way?

<vue-select
ref="select"
:clearable="showClearButton"
:disabled="disabled"
:filter="filter"
:input-id="id"
class="oc-select"
:value="displayValue"
@input="onInput"
@option:selecting="onOptionSelecting"
v-bind="additionalAttributes"
v-on="$listeners"
v-on="listeners"
>
<template #search="{ attributes, events }">
<input class="vs__search" v-bind="attributes" @input="userInput" v-on="events" />
Expand Down Expand Up @@ -51,6 +55,31 @@ export default {
required: false,
default: () => uniqueId("oc-select-"),
},
/**
* Whether or not the select component should have a dedicated button for clearing the selection.
*/
clearButtonEnabled: {
type: Boolean,
required: false,
default: true,
},
/**
* Value to preselect when no value is provided
* This does not set `value` automatically.
* The user needs to explicitly select the value to set it.
*/
defaultValue: {
required: false,
default: null,
},
/**
* Disable the select component
*/
disabled: {
type: Boolean,
required: false,
default: false,
},
/**
* Function to filter items when searching
*/
Expand All @@ -75,14 +104,6 @@ export default {
return search.length ? fuse.search(search).map(({ item }) => item) : fuse.list
},
},
/**
* Disable the select component
*/
disabled: {
type: Boolean,
required: false,
default: false,
},
/**
* Label of the select component
* ATTENTION: this shadows the vue-select prop `label`. If you need access to that use `optionLabel`.
Expand All @@ -99,6 +120,12 @@ export default {
type: String,
default: null,
},
/**
* Current value of the select component.
*/
value: {
default: null,
},
},

computed: {
Expand All @@ -107,7 +134,24 @@ export default {
if (this.optionLabel) {
additionalAttrs["label"] = this.optionLabel
}
return { ...this.$attrs, ...additionalAttrs }
const attrs = { ...this.$attrs, ...additionalAttrs }
delete attrs.clearable
return attrs
},
displayValue() {
return this.value || this.defaultValue
},
listeners() {
const listeners = this.$listeners

// Delete listeners for events which are emitted via methods
delete listeners["input"]
delete listeners["change"]

return listeners
},
showClearButton() {
return this.clearButtonEnabled && this.value !== null
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this.disabled needs to be taken into account.

},
},

Expand All @@ -128,6 +172,23 @@ export default {
*/
this.$emit("search:input", event.target.value)
},
onInput(value) {
// selecting a value is handled via onOptionSelecting, we just nead to handle clear events here
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

*need

if (value !== null) {
return
}

this.onOptionSelecting(null)
},
/**
* We use the option:selecting event as it's the only one that fires when an option is reselected
* When we are showing a `defaultValue` we need to allow the user to explicitly set that value
* to override the default because a default might change one day
*/
onOptionSelecting(value) {
this.$emit("input", value)
this.$emit("change", value)
},
},
}
</script>
Expand Down Expand Up @@ -240,6 +301,28 @@ prevent clearing the selected value by hitting `delete`.
</script>
```

### Providing a default value
We can provide a `defaultValue` to `oc-select` that is preselected when `value` is `null`.
When the `defaultValue` is displayed the clear button is automatically disabled.

```js
<template>
<div class="oc-docs-width-medium">
<oc-select v-model="selected" :options="['Apple', 'Bannana', 'Orange', 'Pear']" default-value="Orange" />
<p>
Selected: {{ selected === null ? "null" : selected }}
Copy link
Member Author

@dschmidt dschmidt Sep 5, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Selected: {{ selected === null ? "null" : selected }}
Selected: {{ selected || "null" }}

</p>
</div>
</template>
<script>
export default {
data: () => ({
selected: null
})
};
</script>
```

### Multiple selection
```js
<template>
Expand Down