-
Notifications
You must be signed in to change notification settings - Fork 88
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(NcChip): Add NcChip component for a chip-linke element
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de> [skip ci]
- Loading branch information
1 parent
bf1c7fe
commit 2e5c909
Showing
2 changed files
with
275 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,270 @@ | ||
<!-- | ||
- SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors | ||
- SPDX-License-Identifier: AGPL-3.0-or-later | ||
--> | ||
<docs> | ||
### Basic usage | ||
|
||
```vue | ||
<template> | ||
<div style="display: flex; gap: 8px; flex-wrap: wrap;"> | ||
<NcChip text="Notes.txt" :icon-path="mdiFile" /> | ||
<NcChip text="Color" type="tertiary" :icon-path="mdiPalette" /> | ||
<NcChip text="Current time" type="primary" :icon-path="mdiClock" no-close /> | ||
</div> | ||
</template> | ||
<script> | ||
import { mdiClock, mdiFile, mdiPalette } from '@mdi/js' | ||
export default { | ||
setup() { | ||
return { | ||
mdiClock, | ||
mdiFile, | ||
mdiPalette, | ||
} | ||
} | ||
} | ||
</script> | ||
``` | ||
|
||
### Advanced usage | ||
|
||
It is also possible to use custom components for the icon by using the `icon` slot. | ||
In this example we are using the `NcAvatar` component to render the users avatar as the icon. | ||
|
||
*Hint: If you use round icons like avatars you should set their size to `24px` (or use CSS variable `--chip-size`) to make then fully fill and align with the the chip* | ||
|
||
Also it is possible to pass custom actions. | ||
|
||
```vue | ||
<template> | ||
<NcChip> | ||
<!-- The icon slot allow to use custom components as the chip icon --> | ||
<template #icon> | ||
<NcAvatar :size="24" user="jdoe" display-name="J. Doe" /> | ||
</template> | ||
<!-- The actions slot allows to add custom actions --> | ||
<template #actions> | ||
<NcActionButton> | ||
<template #icon> | ||
<ContactsIcon :size="20" /> | ||
</template> | ||
Add to contacts | ||
</NcActionButton> | ||
</template> | ||
<!-- The default slot can be used for add content, just like the `text` prop --> | ||
J. Doe | ||
</NcChip> | ||
</template> | ||
<script> | ||
import ContactsIcon from 'vue-material-design-icons/Contacts.vue' | ||
export default { | ||
components: { | ||
ContactsIcon, | ||
}, | ||
} | ||
</script> | ||
``` | ||
</docs> | ||
|
||
<template> | ||
<div class="nc-chip" :class="{ [`nc-chip--${type}`]: true, 'nc-chip--no-actions': !hasActions }"> | ||
<span class="nc-chip__icon"> | ||
<!-- @slot The icon slot can be used to set the chip icon. Make sure that the icon is not exceeding a height of `24px`. For round icons a exact size of `24px` is recommended. --> | ||
<slot name="icon"> | ||
<!-- The default icon wrapper uses a size of 18px to ensure the icon is not clipped by the round chip style --> | ||
<NcIconSvgWrapper v-if="iconPath || iconSvg" | ||
inline | ||
:path="iconPath" | ||
:svg="iconPath ? undefined : iconSvg" | ||
:size="18" /> | ||
</slot> | ||
</span> | ||
<span class="nc-chip__text"> | ||
<!-- @slot The default slot can be used to set the text that is shown --> | ||
<slot>{{ text }}</slot> | ||
</span> | ||
<NcActions v-if="hasActions" | ||
class="nc-chip__actions" | ||
:force-menu="!canClose" | ||
type="tertiary-no-background"> | ||
<NcActionButton v-if="canClose" | ||
close-after-click | ||
@click="onClose"> | ||
<template #icon> | ||
<NcIconSvgWrapper :path="mdiClose" :size="20" /> | ||
</template> | ||
{{ ariaLabelClose }} | ||
</NcActionButton> | ||
<!-- @slot The actions slot can be used to add custom actions to the chips actions --> | ||
<slot name="actions" /> | ||
</NcActions> | ||
</div> | ||
</template> | ||
|
||
<script> | ||
import { mdiClose } from '@mdi/js' | ||
import { defineComponent } from 'vue' | ||
import { t } from '../../l10n.js' | ||
import NcActions from '../NcActions/NcActions.vue' | ||
import NcActionButton from '../NcActionButton/NcActionButton.vue' | ||
import NcIconSvgWrapper from '../NcIconSvgWrapper/NcIconSvgWrapper.vue' | ||
export default defineComponent({ | ||
name: 'NcChip', | ||
components: { | ||
NcActions, | ||
NcActionButton, | ||
NcIconSvgWrapper, | ||
}, | ||
props: { | ||
/** | ||
* aria label to set on the close button | ||
* @default 'Close' | ||
*/ | ||
ariaLabelClose: { | ||
type: String, | ||
default: t('Close'), | ||
}, | ||
/** | ||
* Main text of the chip | ||
*/ | ||
text: { | ||
type: String, | ||
default: '', | ||
}, | ||
/** | ||
* Chip style | ||
* This sets the background style of the chip, similar to NcButton's `type` | ||
*/ | ||
type: { | ||
type: String, | ||
default: 'secondary', | ||
validator: (value) => ['primary', 'secondary', 'tertiary'].includes(value), | ||
}, | ||
/** | ||
* SVG path of the icon to use. | ||
* For example icon paths from `@mdi/js` can be used. | ||
*/ | ||
iconPath: { | ||
type: String, | ||
default: null, | ||
}, | ||
/** | ||
* Inline SVG to use as the icon | ||
*/ | ||
iconSvg: { | ||
type: String, | ||
default: null, | ||
}, | ||
/** | ||
* Set to true to prevent the close button to be shown | ||
*/ | ||
noClose: { | ||
type: Boolean, | ||
default: false, | ||
}, | ||
}, | ||
emits: ['close'], | ||
setup() { | ||
return { | ||
mdiClose, | ||
} | ||
}, | ||
computed: { | ||
canClose() { | ||
return !this.noClose | ||
}, | ||
hasActions() { | ||
return this.canClose || (this.$slots?.actions !== undefined) || (this.$scopedSlots.actions !== undefined) | ||
}, | ||
}, | ||
methods: { | ||
t, | ||
onClose() { | ||
/** | ||
* Emitted when the close button is clicked | ||
*/ | ||
this.$emit('close') | ||
}, | ||
}, | ||
}) | ||
</script> | ||
<style scoped lang="scss"> | ||
.nc-chip { | ||
--chip-size: 24px; | ||
--chip-radius: calc(var(--chip-size) / 2); | ||
// Setup size of wrapper | ||
height: var(--chip-size); | ||
max-width: fit-content; | ||
display: flex; | ||
flex-direction: row; | ||
align-items: center; | ||
gap: var(--default-grid-baseline); | ||
border-radius: var(--chip-radius); | ||
background-color: var(--color-background-hover); | ||
&--primary { | ||
background-color: var(--color-primary-element); | ||
color: var(--color-primary-text); | ||
} | ||
&--secondary { | ||
background-color: var(--color-primary-element-light); | ||
color: var(--color-primary-element-light-text); | ||
} | ||
&--no-actions &__text { | ||
// If there are no actions we need to add some padding to ensure the text is not cut-off | ||
padding-inline-end: calc(1.5 * var(--default-grid-baseline)); | ||
} | ||
&__text { | ||
// Allow to grow the text | ||
// this is only used if an app forces a width of the chip | ||
flex: 1 auto; | ||
overflow: hidden; | ||
text-overflow: ellipsis; | ||
} | ||
&__icon { | ||
// Do neither grow nor shrink, size is fixed | ||
flex: 0 0 var(--chip-size); | ||
line-height: 1; | ||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
// Force size | ||
overflow: hidden; | ||
height: var(--chip-size); | ||
width: var(--chip-size); | ||
} | ||
&__actions { | ||
// Do neither grow nor shrink, size is fixed | ||
flex: 0 0 var(--chip-size); | ||
// Adjust action size to match chip size | ||
--default-clickable-area: var(--chip-size); | ||
--border-radius-element: var(--chip-radius); | ||
} | ||
} | ||
</style> |
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 @@ | ||
/** | ||
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors | ||
* SPDX-License-Identifier: AGPL-3.0-or-later | ||
*/ | ||
export { default } from './NcChip.vue' |