This repository has been archived by the owner on Jan 3, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1521 from owncloud/feat/oc-select-autocomplete
- Loading branch information
Showing
24 changed files
with
1,615 additions
and
1,808 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
Enhancement: deprecate OcAutocomplete | ||
|
||
We've deprecated the OcAutocomplete component. OcSelect with `:multiple="true"` prop can be used to achieve the same behaviour. | ||
|
||
https://github.com/owncloud/owncloud-design-system/pull/1521 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
Enhancement: add OcRecipient component | ||
|
||
We've added OcRecipient component. | ||
|
||
https://github.com/owncloud/owncloud-design-system/pull/1521 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
Enhancement: add `search:input` event to OcSelect | ||
|
||
We've added `search:input` event to the OcSelect component which is triggered when a search query is typed into the select. | ||
|
||
https://github.com/owncloud/owncloud-design-system/pull/1521 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
import { shallowMount } from "@vue/test-utils" | ||
|
||
import Recipient from "./OcRecipient.vue" | ||
|
||
describe("OcRecipient", () => { | ||
/** | ||
* @param {Object} props | ||
* @returns {Wrapper<Vue>} | ||
*/ | ||
function getWrapper(props, slot) { | ||
const slots = slot ? { append: slot } : {} | ||
|
||
return shallowMount(Recipient, { | ||
propsData: { | ||
recipient: { | ||
name: "alice", | ||
avatar: "avatar.jpg", | ||
hasAvatar: true, | ||
isLoadingAvatar: false, | ||
...props, | ||
}, | ||
}, | ||
slots, | ||
}) | ||
} | ||
|
||
it("displays recipient name", () => { | ||
const wrapper = getWrapper() | ||
|
||
expect(wrapper.find('[data-testid="recipient-name"]').text()).toEqual("alice") | ||
}) | ||
|
||
it("displays avatar", () => { | ||
const wrapper = getWrapper() | ||
|
||
expect(wrapper.find('[data-testid="recipient-avatar"]').attributes("src")).toEqual("avatar.jpg") | ||
}) | ||
|
||
it("displays a spinner if avatar has not been loaded yet", () => { | ||
const wrapper = getWrapper({ | ||
isLoadingAvatar: true, | ||
}) | ||
|
||
expect(wrapper.find('[data-testid="recipient-avatar-spinner"]').exists()).toBeTruthy() | ||
}) | ||
|
||
it("displays an icon if avatar is not enabled", () => { | ||
const wrapper = getWrapper({ | ||
icon: { | ||
name: "person", | ||
label: "User", | ||
}, | ||
hasAvatar: false, | ||
}) | ||
|
||
const icon = wrapper.find('[data-testid="recipient-icon"]') | ||
|
||
expect(icon.exists()).toBeTruthy() | ||
expect(icon.attributes().accessiblelabel).toEqual("User") | ||
}) | ||
|
||
it("display content in the append slot", () => { | ||
const wrapper = getWrapper({}, '<span id="test-slot">Hello world</span>') | ||
|
||
expect(wrapper.find("#test-slot").exists()).toBeTruthy() | ||
}) | ||
|
||
it.each([ | ||
["name is not defined", {}], | ||
[ | ||
"name is not a string", | ||
{ | ||
name: { | ||
first: "Alice", | ||
}, | ||
}, | ||
], | ||
[ | ||
"name is empty", | ||
{ | ||
name: "", | ||
}, | ||
], | ||
["icon name is not defined", { name: "Alice", icon: {} }], | ||
["icon name is not a string", { name: "Alice", icon: { name: { inverted: "inverted" } } }], | ||
["icon name is empty", { name: "Alice", icon: { name: "" } }], | ||
["icon label is not defined", { name: "Alice", icon: { name: "person" } }], | ||
[ | ||
"icon label is not a string", | ||
{ name: "Alice", icon: { name: "person", label: { long: "Long label" } } }, | ||
], | ||
["icon label is empty", { name: "Alice", icon: { name: "Alice", label: "" } }], | ||
])("throws an error if %s", (def, prop) => { | ||
expect(() => shallowMount(Recipient, { propsData: { recipient: prop } })).toThrow( | ||
`Recipient ${def}` | ||
) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
<template> | ||
<span class="oc-recipient"> | ||
<template v-if="recipient.hasAvatar"> | ||
<oc-spinner | ||
v-if="recipient.isLoadingAvatar" | ||
key="recipient-avatar-spinner" | ||
size="small" | ||
:aria-label="$gettext('Loading avatar')" | ||
data-testid="recipient-avatar-spinner" | ||
/> | ||
<oc-avatar | ||
v-else | ||
:key="recipient.avatar || recipient.name" | ||
data-testid="recipient-avatar" | ||
class="oc-recipient-avatar" | ||
:src="recipient.avatar" | ||
:user-name="recipient.name" | ||
:width="16.8" | ||
/> | ||
</template> | ||
<oc-icon | ||
v-else-if="recipient.icon && recipient.icon.name" | ||
class="oc-recipient-icon" | ||
size="small" | ||
:name="recipient.icon.name" | ||
:accessible-label="recipient.icon.label" | ||
data-testid="recipient-icon" | ||
/> | ||
<p class="oc-recipient-name" data-testid="recipient-name" v-text="recipient.name" /> | ||
<!-- @slot Append content (actions, additional info, etc.) --> | ||
<slot name="append" /> | ||
</span> | ||
</template> | ||
|
||
<script> | ||
import OcAvatar from "../avatars/OcAvatar.vue" | ||
import OcIcon from "../OcIcon.vue" | ||
import OcSpinner from "../OcSpinner.vue" | ||
export default { | ||
name: "OcRecipient", | ||
status: "review", | ||
release: "unreleased", | ||
components: { OcAvatar, OcIcon, OcSpinner }, | ||
props: { | ||
/** | ||
* Recipient object containing name (required), icon and avatar | ||
*/ | ||
recipient: { | ||
type: Object, | ||
required: true, | ||
validator: recipient => { | ||
if (!Object.prototype.hasOwnProperty.call(recipient, "name")) { | ||
throw new Error("Recipient name is not defined") | ||
} | ||
if (typeof recipient.name !== "string") { | ||
throw new Error("Recipient name is not a string") | ||
} | ||
if (recipient.name.length < 1) { | ||
throw new Error("Recipient name is empty") | ||
} | ||
if (Object.prototype.hasOwnProperty.call(recipient, "icon")) { | ||
if (!Object.prototype.hasOwnProperty.call(recipient.icon, "name")) { | ||
throw new Error("Recipient icon name is not defined") | ||
} | ||
if (typeof recipient.icon.name !== "string") { | ||
throw new Error("Recipient icon name is not a string") | ||
} | ||
if (recipient.icon.name.length < 1) { | ||
throw new Error("Recipient icon name is empty") | ||
} | ||
if (!Object.prototype.hasOwnProperty.call(recipient.icon, "label")) { | ||
throw new Error("Recipient icon label is not defined") | ||
} | ||
if (typeof recipient.icon.label !== "string") { | ||
throw new Error("Recipient icon label is not a string") | ||
} | ||
if (recipient.icon.label.length < 1) { | ||
throw new Error("Recipient icon label is empty") | ||
} | ||
} | ||
return true | ||
}, | ||
}, | ||
}, | ||
} | ||
</script> | ||
|
||
<style lang="scss"> | ||
.oc-recipient { | ||
align-items: center; | ||
background-color: var(--oc-color-swatch-inverse-default); | ||
border: 1px solid var(--oc-color-input-border); | ||
border-radius: 6px; | ||
display: flex; | ||
gap: var(--oc-space-xsmall); | ||
justify-content: flex-start; | ||
padding: var(--oc-space-xsmall); | ||
width: auto; | ||
&-icon > svg { | ||
fill: var(--oc-color-text-default); | ||
} | ||
&-name { | ||
color: var(--oc-color-text-default); | ||
margin: 0; | ||
padding: 0; | ||
} | ||
} | ||
</style> | ||
|
||
<docs> | ||
```js | ||
<div class="uk-flex uk-flex-column uk-flex-left uk-flex-top"> | ||
<oc-recipient :recipient="{ name: 'Alice', avatar: 'https://picsum.photos/24', hasAvatar: true, isAvatarLoading: false }" class="oc-mb-s" /> | ||
<oc-recipient :recipient="{ name: 'Alice', icon: { name: 'person', label: 'User' }, hasAvatar: false }" /> | ||
</div> | ||
``` | ||
</docs> |
Oops, something went wrong.