Skip to content

feat(list-group): support horizontal layout #2536

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

Merged
merged 12 commits into from
Feb 12, 2019
Merged
Show file tree
Hide file tree
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
38 changes: 38 additions & 0 deletions src/components/list-group/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,44 @@ prop when using cards with `no-body` to make the sides of the list group flush w
<!-- b-list-group-card.vue -->
```

## Horizontal list groups

Set the prop `horizontal` to `true` to change the layout of list group items from vertical to
horizontal across all breakpoints. Alternatively, set `horizontal` to a responsive breakpoint
(`sm`, `md`, `lg` or `xl`) to make a list group horizontal starting at that breakpoint’s min-width.
Currently horizontal list groups cannot be combined with `flush` list groups.

**ProTip:** Want equal-width list group items when horizontal? Add the class `flex-fill` to each
list group item.

**Always horizontal:**

```html
<div>
<b-list-group horizontal>
<b-list-group-item>Cras justo odio</b-list-group-item>
<b-list-group-item>Dapibus ac facilisis in</b-list-group-item>
<b-list-group-item>Morbi leo risus</b-list-group-item>
</b-list-group>
</div>

<!-- b-list-group-horizontal.vue -->
```

**Horizontal at breakpoint md and above:**

```html
<div>
<b-list-group horizontal="md">
<b-list-group-item>Cras justo odio</b-list-group-item>
<b-list-group-item>Dapibus ac facilisis in</b-list-group-item>
<b-list-group-item>Morbi leo risus</b-list-group-item>
</b-list-group>
</div>

<!-- b-list-group-horizontal-md.vue -->
```

## Custom content

Add nearly any HTML or component within, even for linked list groups like the one below, with the
Expand Down
39 changes: 0 additions & 39 deletions src/components/list-group/fixtures/list-group.html

This file was deleted.

3 changes: 0 additions & 3 deletions src/components/list-group/fixtures/list-group.js

This file was deleted.

10 changes: 9 additions & 1 deletion src/components/list-group/list-group.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ export const props = {
flush: {
type: Boolean,
default: false
},
horizontal: {
type: [Boolean, String],
default: false
}
}

Expand All @@ -17,10 +21,14 @@ export default {
functional: true,
props,
render(h, { props, data, children }) {
let horizontal = props.horizontal === '' ? true : props.horizontal
horizontal = props.flush ? false : horizontal
const componentData = {
staticClass: 'list-group',
class: {
'list-group-flush': props.flush
'list-group-flush': props.flush,
'list-group-horizontal': horizontal === true,
[`list-group-horizontal-${horizontal}`]: typeof horizontal === 'string'
}
}
return h(props.tag, mergeData(data, componentData), children)
Expand Down
105 changes: 102 additions & 3 deletions src/components/list-group/list-group.spec.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,105 @@
import { loadFixture, testVM } from '../../../tests/utils'
import ListGroup from './list-group'
import { mount } from '@vue/test-utils'

describe('list-group', async () => {
beforeEach(loadFixture(__dirname, 'list-group'))
testVM()
it('default should have tag div', async () => {
const wrapper = mount(ListGroup)
expect(wrapper.is('div')).toBe(true)
})

it('default should contain only single class of list-group', async () => {
const wrapper = mount(ListGroup)
expect(wrapper.classes().length).toBe(1)
expect(wrapper.classes()).toContain('list-group')
expect(wrapper.classes()).not.toContain('list-group-flush')
expect(wrapper.classes()).not.toContain('list-group-horizontal')
})

it('should have tag ul then prop tag=ul', async () => {
const wrapper = mount(ListGroup, {
context: {
props: { tag: 'ul' }
}
})
expect(wrapper.is('ul')).toBe(true)
})

it('should have class list-group-flush when prop flush=true', async () => {
const wrapper = mount(ListGroup, {
context: {
props: { flush: true }
}
})
expect(wrapper.classes().length).toBe(2)
expect(wrapper.classes()).toContain('list-group')
expect(wrapper.classes()).toContain('list-group-flush')
expect(wrapper.classes()).not.toContain('list-group-horizontal')
})

it('should have class list-group-horizontal when prop horizontal=true', async () => {
const wrapper = mount(ListGroup, {
context: {
props: { horizontal: true }
}
})
expect(wrapper.classes().length).toBe(2)
expect(wrapper.classes()).not.toContain('list-group-flush')
expect(wrapper.classes()).toContain('list-group')
expect(wrapper.classes()).toContain('list-group-horizontal')
})

it('should have class list-group-horizontal-md when prop horizontal=md', async () => {
const wrapper = mount(ListGroup, {
context: {
props: { horizontal: 'md' }
}
})
expect(wrapper.classes().length).toBe(2)
expect(wrapper.classes()).not.toContain('list-group-flush')
expect(wrapper.classes()).not.toContain('list-group-horizontal')
expect(wrapper.classes()).toContain('list-group')
expect(wrapper.classes()).toContain('list-group-horizontal-md')
})

it('should not have class list-group-horizontal when prop horizontal=true and flush=true', async () => {
const wrapper = mount(ListGroup, {
context: {
props: {
horizontal: true,
flush: true
}
}
})
expect(wrapper.classes().length).toBe(2)
expect(wrapper.classes()).not.toContain('list-group-horizontal')
expect(wrapper.classes()).toContain('list-group')
expect(wrapper.classes()).toContain('list-group-flush')
})

it('should not have class list-group-horizontal-lg when prop horizontal=lg and flush=true', async () => {
const wrapper = mount(ListGroup, {
context: {
props: {
horizontal: 'lg',
flush: true
}
}
})
expect(wrapper.classes().length).toBe(2)
expect(wrapper.classes()).not.toContain('list-group-horizontal-lg')
expect(wrapper.classes()).not.toContain('list-group-horizontal')
expect(wrapper.classes()).toContain('list-group')
expect(wrapper.classes()).toContain('list-group-flush')
})

it('should accept custom classes', async () => {
const wrapper = mount(ListGroup, {
context: {
class: 'foobar'
}
})
expect(wrapper.classes().length).toBe(2)
expect(wrapper.classes()).toContain('list-group')
expect(wrapper.classes()).toContain('foobar')
})
})