Skip to content

Commit

Permalink
feat(NcCounterBubble): add count and limit props instead of slot
Browse files Browse the repository at this point in the history
Signed-off-by: Grigorii K. Shartsev <me@shgk.me>
  • Loading branch information
ShGKme authored and Antreesy committed Aug 5, 2024
1 parent be0ac7d commit ba97433
Show file tree
Hide file tree
Showing 2 changed files with 207 additions and 9 deletions.
148 changes: 139 additions & 9 deletions src/components/NcCounterBubble/NcCounterBubble.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,129 @@
### Normal Counter

```
<NcCounterBubble>314+</NcCounterBubble>
<NcCounterBubble count=314 />
```

### Outlined Counter (e.g team mentions)
### Limited

```
<NcCounterBubble type="outlined">314+</NcCounterBubble>
<template>
<table>
<tr>
<th>Limit</th>
<th>Count</th>
<th>NcCounterBubble</th>
</tr>
<tr>
<td>999 (default)</td>
<td>1000</td>
<td>
<NcCounterBubble count="1000" />
</td>
</tr>
<tr>
<td>12</td>
<td>9</td>
<td>
<NcCounterBubble count="12" limit="9" />
</td>
</tr>
<tr>
<td>0 (disabled)</td>
<td>1000</td>
<td>
<NcCounterBubble count="1000" limit="0" />
</td>
</tr>
</table>
</template>

<style scoped>
table {
border-collapse: collapse;
}

th,
td {
border: 1px solid var(--color-border);
padding: var(--default-grid-baseline) calc(var(--default-grid-baseline) * 2);
}

th {
color: var(--color-text-maxcontrast);
}
</style>
```

### Highlighted Counter (e.g direct mentions)
### Style type

```
<NcCounterBubble type="highlighted">314+</NcCounterBubble>
<template>
<table>
<tr>
<th>type</th>
<th>NcCounterBubble</th>
<th>Usage example</th>
</tr>
<tr>
<td>'' (default)</td>
<td>
<NcCounterBubble count="314" />
</td>
<td></td>
</tr>
<tr>
<td>outlined</td>
<td><NcCounterBubble type="outlined" count="314" /></td>
<td>Team mentions</td>
</tr>
<tr>
<td>highlighted</td>
<td>
<NcCounterBubble type="highlighted" count="314" />
</td>
<td>Direct mentions</td>
</tr>
</table>
</template>

<style scoped>
table {
border-collapse: collapse;
}

th,
td {
border: 1px solid var(--color-border);
padding: var(--default-grid-baseline) calc(var(--default-grid-baseline) * 2);
}

th {
color: var(--color-text-maxcontrast);
}
</style>
```

### Custom content

Deprecated. Use the `count` prop instead.

```
<NcCounterBubble>314+</NcCounterBubble>
````

</docs>

<template>
<div :class="counterClassObject"
class="counter-bubble__counter">
<slot />
<!--
@slot The content with the count number. Deprecated: use the `count` prop instead.
@deprecated
-->
<slot>
{{ countWithLimit }}
</slot>
</div>
</template>

Expand All @@ -42,7 +144,7 @@ export default {
type: String,
default: '',
validator(value) {
return ['highlighted', 'outlined', ''].indexOf(value) !== -1
return ['highlighted', 'outlined', ''].includes(value)
},
},

Expand All @@ -55,6 +157,28 @@ export default {
type: Boolean,
default: false,
},

/**
* The count to display in the counter bubble.
* Alternatively, you can pass any value to the default slot.
*/
count: {
type: Number,
required: false,
default: 0,
},

/**
* The maximal count number to be display. If the count is higher then "max+" is displayed.
* For example, with limit 999, 1000 will be displayed as "999+".
* Only works if the count is set via the `count` prop and not via the default slot.
* Set 0 to disable the limit.
*/
limit: {
type: Number,
required: false,
default: 999,
},
},

computed: {
Expand All @@ -65,6 +189,12 @@ export default {
active: this.active,
}
},

countWithLimit() {
return this.count && this.limit && this.count > this.limit
? `${this.limit}+`
: this.count
},
},
}

Expand All @@ -78,8 +208,7 @@ export default {
max-width: var(--default-clickable-area);
min-width: calc(1lh + 2 * var(--default-grid-baseline)); // Make it not narrower than a circle
text-align: center;
text-overflow: ellipsis;
line-height: 1em;
line-height: 1;
padding: var(--default-grid-baseline);
border-radius: var(--border-radius-pill);
background-color: var(--color-primary-element-light);
Expand All @@ -106,6 +235,7 @@ export default {
background: transparent;
box-shadow: inset 0 0 0 2px;
}

&--outlined.active {
color: var(--color-main-background);
box-shadow: inset 0 0 0 2px;
Expand Down
68 changes: 68 additions & 0 deletions tests/unit/components/NcCounterBubble/NcCounterBubble.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import { describe, it, expect } from '@jest/globals'
import { mount } from '@vue/test-utils'
import NcCounterBubble from '../../../../src/components/NcCounterBubble/NcCounterBubble.vue'

describe('NcCounterBubble', () => {
describe('displaying count', () => {
it('should render content', () => {
const wrapper = mount(NcCounterBubble, { slots: { default: '314+' } })
expect(wrapper.text()).toBe('314+')
})

it('should render count from prop', () => {
const wrapper = mount(NcCounterBubble, { propsData: { count: 314 } })
expect(wrapper.text()).toBe('314')
})
})

describe('using limit', () => {
it('should render count less than 999 as it is', () => {
const wrapper = mount(NcCounterBubble, { propsData: { count: 999 } })
expect(wrapper.text()).toBe('999')
})

it('should render count more than 999 as 999+ by default', () => {
const wrapper = mount(NcCounterBubble, { propsData: { count: 1000 } })
expect(wrapper.text()).toBe('999+')
})

it('should render count more than limit as limit+', () => {
const wrapper = mount(NcCounterBubble, { propsData: { count: 10, limit: 9 } })
expect(wrapper.text()).toBe('9+')
})

it('should render count without limit when limit is 0', () => {
const wrapper = mount(NcCounterBubble, { propsData: { count: 10000000000, limit: 0 } })
expect(wrapper.text()).toBe('10000000000')
})
})

describe('with styling', () => {
it('should not have any additional classes', () => {
const wrapper = mount(NcCounterBubble)
expect(wrapper.classes('counter-bubble__counter--highlighted')).toBeFalsy()
expect(wrapper.classes('counter-bubble__counter--outlined')).toBeFalsy()
expect(wrapper.classes('active')).toBeFalsy()
})

it('should have class "counter-bubble__counter--highlighted" when type="highlighted"', () => {
const wrapper = mount(NcCounterBubble, { propsData: { type: 'highlighted' } })
expect(wrapper.classes('counter-bubble__counter--highlighted')).toBeTruthy()
})

it('should have class "counter-bubble__counter--outlined" when type="outlined"', () => {
const wrapper = mount(NcCounterBubble, { propsData: { type: 'outlined' } })
expect(wrapper.classes('counter-bubble__counter--outlined')).toBeTruthy()
})

it('should have class "active" when active', () => {
const wrapper = mount(NcCounterBubble, { propsData: { active: true } })
expect(wrapper.classes('active')).toBeTruthy()
})
})
})

0 comments on commit ba97433

Please sign in to comment.