Skip to content

Commit

Permalink
Add spinner support
Browse files Browse the repository at this point in the history
  • Loading branch information
junjizhi committed Jun 11, 2021
1 parent c9de983 commit cd8da97
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 55 deletions.
14 changes: 6 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,19 +47,16 @@ export default Vue.extend({
{
timestamp: Date.parse('2021-05-29T20:20:46.444Z'),
title: 'Dolore ullamco exercitation commodo',
content: 'Esse dolore consectetur aliqua laboris sunt aliqua do non.',
link: 'https://example1.com'
content: 'Esse dolore consectetur aliqua laboris sunt aliqua do non.'
},
{
timestamp: Date.parse('2021-05-28T20:20:46.444Z'),
title: 'Voluptate pariatur dolore laborum eu',
link: '#'
title: 'Voluptate pariatur dolore laborum eu'
},
{
timestamp: Date.parse('2021-01-28T20:20:46.444Z'),
title: 'Mollit aliqua velit nostrud ipsum',
content: 'Magna officia est fugiat sit esse consectetur labore elit nulla duis consectetur. Et sit velit ad ipsum officia.',
link: '#'
content: 'Magna officia est fugiat sit esse consectetur labore elit nulla duis consectetur. Et sit velit ad ipsum officia.'
}
]
}
Expand All @@ -74,15 +71,16 @@ export default Vue.extend({
>
<b-timeline
:items="timelineItems"
:reverse="false"
:reverse="true"
:loading="true"
/>
</b-card>
</div>
</template>
```

## Features
- [ ] Loading spinner
- [x] Loading spinner
- [ ] Support item head color variants
- [x] Support `reverse` props
- [ ] Support custom icons
Expand Down
2 changes: 1 addition & 1 deletion babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ const buildPresets = [
],
];
module.exports = {
presets: (process.env.NODE_ENV === 'development' ? devPresets : buildPresets),
presets: buildPresets,
};
3 changes: 2 additions & 1 deletion dev/serve.vue
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ export default Vue.extend({
>
<bootstrap-vue-timeline
:items="timelineItems"
:reverse="true"
:reverse="false"
:loading="true"
/>
</b-card>
</div>
Expand Down
70 changes: 36 additions & 34 deletions src/__tests__/bootstrap-vue-timeline.spec.js
Original file line number Diff line number Diff line change
@@ -1,56 +1,58 @@
import { createLocalVue, mount } from '@vue/test-utils'
import { BootstrapVue } from 'bootstrap-vue'
import { createLocalVue, shallowMount } from '@vue/test-utils'
import { BootstrapVue, BSpinner } from 'bootstrap-vue'
import BootstrapVueTimeline from '../bootstrap-vue-timeline.vue'

const sampleItems = [
{
timestamp: Date.parse('2021-01-28T20:20:46.123Z'),
title: 'title 1',
content: 'content 1',
link: 'link 1'
content: 'content 1'
},
{
timestamp: Date.parse('2021-01-28T20:20:46.456Z'),
title: 'title 2',
content: 'content 2',
link: 'link 1'
content: 'content 2'
},
{
timestamp: Date.parse('2021-01-28T20:20:46.444Z'),
title: 'title 3',
content: 'content 3',
link: 'link 3'
content: 'content 3'
}
]

test('renders a timeline with items', () => {
const localVue = createLocalVue()
localVue.use(BootstrapVue)
describe('bootstrap vue timeline component', () => {
let localVue

const wrapper = mount(BootstrapVueTimeline, {
localVue,
attachTo: document.body,
propsData: {
items: sampleItems,
reverse: false
}
beforeEach(() => {
localVue = createLocalVue()
localVue.use(BootstrapVue)
})
const text = wrapper.text()
expect(text).toMatch(/content 1[\s\S]*content 2[\s\S]*content 3/)
})

test('renders a timeline with items in reversed order', () => {
const localVue = createLocalVue()
localVue.use(BootstrapVue)
test('renders a timeline with items in reversed order', () => {
const wrapper = shallowMount(BootstrapVueTimeline, {
localVue,
propsData: {
items: sampleItems,
reverse: true
}
})
const text = wrapper.text()
expect(text).toMatch(/content 3[\s\S]*content 2[\s\S]*content 1/)
})

test('renders a timeline with items with a spinner', () => {
const wrapper = shallowMount(BootstrapVueTimeline, {
localVue,
propsData: {
items: sampleItems,
reverse: false,
loading: true
}
})
const text = wrapper.text()
expect(text).toMatch(/content 1[\s\S]*content 2[\s\S]*content 3/)

const wrapper = mount(BootstrapVueTimeline, {
localVue,
attachTo: document.body,
propsData: {
items: sampleItems,
reverse: true
}
const spinner = wrapper.findComponent(BSpinner)
expect(spinner.exists()).toBe(true)
})
const text = wrapper.text()
expect(text).toMatch(/content 3[\s\S]*content 2[\s\S]*content 1/)
})
})
41 changes: 30 additions & 11 deletions src/bootstrap-vue-timeline.vue
Original file line number Diff line number Diff line change
@@ -1,29 +1,40 @@
<script>
import Vue from 'vue'
import { BListGroup, BListGroupItem, BTooltip } from 'bootstrap-vue'
import { BListGroup, BListGroupItem, BSpinner, BTooltip } from 'bootstrap-vue'
import { format, formatDistanceToNow } from 'date-fns'
Vue.component('b-list-group', BListGroup)
Vue.component('b-list-group-item', BListGroupItem)
Vue.component('b-tooltip', BTooltip)
Vue.component('b-spinner', BSpinner)
export default /*#__PURE__*/{
name: 'BootstrapVueTimeline',
props: {
items: Array,
reverse: Boolean
reverse: Boolean,
loading: Boolean
},
computed: {
methods: {
orderedItems() {
const items = this.items
let items = this.items
if (this.loading) {
items = [...items, {spinner: true, timestamp: "time", title: "loading"}]
}
if (this.reverse) {
items.reverse()
}
return items
}
},
methods: {
},
itemsCount() {
if (this.loading) {
return this.items.length + 1
}
return this.items.length
},
formatAgo(timestamp) {
return formatDistanceToNow(timestamp, { addSuffix: true })
},
Expand All @@ -40,18 +51,26 @@ export default /*#__PURE__*/{
<template>
<b-list-group>
<b-list-group-item
v-for="(item, index) in orderedItems"
v-for="(item, index) in orderedItems()"
:key="item.timestamp + item.title"
:href="item.link"
class="flex-column align-items-start"
>
<div class="item-head" />
<div
v-if="index !== items.length - 1"
v-if="index !== itemsCount() - 1"
class="item-tail"
/>

<div class="item-content">
<b-spinner
v-if="item.spinner"
variant="primary"
class="ml-4"
/>

<div
v-if="!item.spinner"
class="item-content"
>
<div class="d-flex w-100 justify-content-between">
<h5 class="mt-2 mb-1">
{{ item.title }}
Expand Down

0 comments on commit cd8da97

Please sign in to comment.