Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(NcChip): Ensure chips without icon do not reserve empty space for icon #5859

Merged
merged 2 commits into from
Jul 29, 2024
Merged
Changes from all commits
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
165 changes: 76 additions & 89 deletions src/components/NcChip/NcChip.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
```vue
<template>
<div style="display: flex; gap: 8px; flex-wrap: wrap;">
<NcChip text="Notes.txt" :icon-path="mdiFile" />
<NcChip text="Notes.txt" />
<NcChip text="Files" :icon-path="mdiFile" />
<NcChip text="Color" type="tertiary" :icon-path="mdiPalette" />
<NcChip text="Current time" type="primary" :icon-path="mdiClock" no-close />
</div>
Expand All @@ -33,7 +34,7 @@ export default {
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*
*Hint: If you use round icons like avatars you should set their size to `24px` (or use CSS variable `--chip-size`) to make them fully fill and align with the the chip*

Also it is possible to pass custom actions.

Expand Down Expand Up @@ -69,8 +70,13 @@ export default {
</docs>

<template>
<div class="nc-chip" :class="{ [`nc-chip--${type}`]: true, 'nc-chip--no-actions': !hasActions }">
<span class="nc-chip__icon">
<div class="nc-chip"
:class="{
[`nc-chip--${type}`]: true,
'nc-chip--no-actions': noClose && !hasActions(),
'nc-chip--no-icon': !hasIcon(),
}">
<span v-if="hasIcon()" 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 -->
Expand All @@ -85,7 +91,7 @@ export default {
<!-- @slot The default slot can be used to set the text that is shown -->
<slot>{{ text }}</slot>
</span>
<NcActions v-if="hasActions"
<NcActions v-if="canClose || hasActions()"
class="nc-chip__actions"
:force-menu="!canClose"
type="tertiary-no-background">
Expand All @@ -103,107 +109,82 @@ export default {
</div>
</template>

<script>
<script setup>
import { mdiClose } from '@mdi/js'
import { defineComponent } from 'vue'
import { computed, useSlots } 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,
const props = defineProps({
/**
* aria label to set on the close button
* @default 'Close'
*/
ariaLabelClose: {
type: String,
default: t('Close'),
},

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,
},
/**
* Main text of the chip
*/
text: {
type: String,
default: '',
},

emits: ['close'],

setup() {
return {
mdiClose,
}
/**
* 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),
},

computed: {
canClose() {
return !this.noClose
},

hasActions() {
return this.canClose || (this.$slots?.actions !== undefined) || (this.$scopedSlots.actions !== undefined)
},
/**
* SVG path of the icon to use, this takes precedence over `iconSVG`.
* For example icon paths from `@mdi/js` can be used.
*/
iconPath: {
type: String,
default: null,
},

methods: {
t,
/**
* Inline SVG to use as the icon
*/
iconSvg: {
type: String,
default: null,
},

onClose() {
/**
* Emitted when the close button is clicked
*/
this.$emit('close')
},
/**
* Set to true to prevent the close button to be shown
*/
noClose: {
type: Boolean,
default: false,
},
})

const emit = defineEmits(['close'])
const slots = useSlots()

const canClose = computed(() => !props.noClose)
const hasActions = () => Boolean(slots.actions?.())
const hasIcon = () => Boolean(props.iconPath || props.iconSvg || !!slots.icon?.())

const onClose = () => {
/**
* Emitted when the close button is clicked
*/
emit('close')
}
</script>

<style scoped lang="scss">
Expand All @@ -216,7 +197,6 @@ export default defineComponent({
display: flex;
flex-direction: row;
align-items: center;
gap: var(--default-grid-baseline);
border-radius: var(--chip-radius);
background-color: var(--color-background-hover);

Expand All @@ -235,18 +215,25 @@ export default defineComponent({
padding-inline-end: calc(1.5 * var(--default-grid-baseline));
}

&--no-icon &__text {
// Add some more space to the border
padding-inline-start: 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;
text-wrap: nowrap;
}

&__icon {
// Do neither grow nor shrink, size is fixed
flex: 0 0 var(--chip-size);
margin-inline-end: var(--default-grid-baseline);

line-height: 1;
display: flex;
Expand Down
Loading