Skip to content

Commit

Permalink
feat(VDivider): port to v3 (#12993)
Browse files Browse the repository at this point in the history
Co-authored-by: Albert Kaaman <albert@kaaman.nu>
Co-authored-by: John Leider <john.j.leider@gmail.com>
  • Loading branch information
3 people committed Jan 26, 2021
1 parent f2b5efc commit cc033c6
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 150 deletions.
43 changes: 20 additions & 23 deletions packages/vuetify/src/components/VDivider/VDivider.sass
Original file line number Diff line number Diff line change
@@ -1,39 +1,36 @@
@import './_variables.scss'

+theme(v-divider) using ($material)
border-color: map-get($material, 'dividers')

.v-divider
@include border($divider-query)

display: block
flex: 1 1 0px
max-width: 100%
flex: $divider-flex
height: 0px
max-height: 0px
border: solid
border-width: thin 0 0 0
transition: inherit

&--inset:not(.v-divider--vertical)
max-width: calc(100% - #{$divider-inset-margin})
+ltr()
margin-left: $divider-inset-margin

+rtl()
margin-right: $divider-inset-margin

&--vertical
align-self: stretch
border: solid
border-width: 0 thin 0 0
border-width: $divider-vertical-border-width
display: inline-flex
height: inherit
min-height: 100%
margin-left: $divider-vertical-margin-left
max-height: 100%
max-width: 0px
width: 0px
vertical-align: text-bottom
width: 0px

&--inset
&:not(.v-divider--vertical)
max-width: $divider-inset-max-width

@include ltr()
margin-left: $divider-inset-margin

@include rtl()
margin-right: $divider-inset-margin

&.v-divider--inset
margin-top: $divider-inset-margin-top
min-height: 0
max-height: $divider-inset-max-height
&.v-divider--vertical
margin-bottom: $divider-vertical-inset-margin-bottom
margin-top: $divider-vertical-inset-margin-top
max-height: $divider-vertical-inset-max-height
82 changes: 52 additions & 30 deletions packages/vuetify/src/components/VDivider/VDivider.ts
Original file line number Diff line number Diff line change
@@ -1,42 +1,64 @@
// @ts-nocheck
/* eslint-disable */

// Styles
import './VDivider.sass'

// Types
import { VNode } from 'vue'
// Utilities
import { computed, defineComponent, h } from 'vue'
import { convertToUnit } from '@/util/helpers'
import makeProps from '@/util/makeProps'

// Mixins
import Themeable from '../../mixins/themeable'
// Composables
import { useTheme } from '@/composables'

// Types
type DividerKey = 'borderRightWidth' | 'borderTopWidth' | 'maxHeight' | 'maxWidth'
type DividerStyles = Partial<Record<DividerKey, string>>

export default Themeable.extend({
name: 'v-divider',
export default defineComponent({
name: 'VDivider',

props: {
inset: Boolean,
vertical: Boolean,
...makeProps({
inset: Boolean,
length: [Number, String],
thickness: [Number, String],
vertical: Boolean,
}),
},

render (h): VNode {
// WAI-ARIA attributes
let orientation
if (!this.$attrs.role || this.$attrs.role === 'separator') {
orientation = this.vertical ? 'vertical' : 'horizontal'
}
return h('hr', {
class: {
'v-divider': true,
'v-divider--inset': this.inset,
'v-divider--vertical': this.vertical,
...this.themeClasses,
},
attrs: {
role: 'separator',
'aria-orientation': orientation,
...this.$attrs,
},
on: this.$listeners,
setup (props, { attrs }) {
const { themeClasses } = useTheme()
const dividerStyles = computed(() => {
const styles: DividerStyles = {}

if (props.length) {
styles[props.vertical ? 'maxHeight' : 'maxWidth'] = convertToUnit(props.length)
}

if (props.thickness) {
styles[props.vertical ? 'borderRightWidth' : 'borderTopWidth'] = convertToUnit(props.thickness)
}

return styles
})

return () => (
h('hr', {
class: [
'v-divider',
{
'v-divider--inset': props.inset,
'v-divider--vertical': props.vertical,
},
themeClasses.value,
],
style: [
dividerStyles.value,
],
ariaOrientation: !attrs.role || attrs.role === 'separator'
? props.vertical ? 'vertical' : 'horizontal'
: undefined,
role: attrs.role || 'separator',
})
)
},
})
125 changes: 35 additions & 90 deletions packages/vuetify/src/components/VDivider/__tests__/VDivider.spec.ts
Original file line number Diff line number Diff line change
@@ -1,105 +1,50 @@
// @ts-nocheck
/* eslint-disable */

// Libraries
// import Vue from 'vue'

// Components
// import VDivider from '../VDivider'
import VDivider from '../VDivider'

// Utilities
import {
createLocalVue,
mount,
Wrapper,
} from '@vue/test-utils'

describe.skip('VDivider', () => {
let mountFunction: (options?: object) => Wrapper<Vue>
let localVue: typeof Vue

beforeEach(() => {
localVue = createLocalVue()

mountFunction = (options = {}) => {
return mount(VDivider, {
localVue,
...options,
})
}
})

it('should render component and match snapshot', () => {
const wrapper = mountFunction()

expect(wrapper.html()).toMatchSnapshot()
})

it('should render an inset component', () => {
const wrapper = mountFunction({
propsData: { inset: true },
import { createTheme, VuetifyThemeSymbol } from '@/composables'
import { mount } from '@vue/test-utils'
import { VuetifySymbol } from '@/framework'

describe('VDivider', () => {
function mountFunction (options = {}) {
return mount(VDivider, {
global: {
provide: {
[VuetifySymbol as symbol]: { defaults: { global: {} } },
[VuetifyThemeSymbol as symbol]: createTheme(),
},
},
...options,
})
}

expect(wrapper.classes('v-divider--inset')).toBe(true)
})

it('should render a light component', () => {
const wrapper = mountFunction({
propsData: { light: true },
})

expect(wrapper.classes('theme--light')).toBe(true)
})

it('should render a dark component', () => {
const wrapper = mountFunction({
propsData: { dark: true },
})

expect(wrapper.classes('theme--dark')).toBe(true)
})

it('should render a vertical component', () => {
const wrapper = mountFunction({
propsData: { vertical: true },
})

expect(wrapper.classes('v-divider--vertical')).toBe(true)
})

it('should have separator role by default', () => {
const wrapper = mountFunction()

expect(wrapper.attributes('role')).toBe('separator')
})

it('should have aria-orientation horizontal by default', () => {
it('should match a snapshot', () => {
const wrapper = mountFunction()

expect(wrapper.attributes('aria-orientation')).toBe('horizontal')
})

it('should have aria-orientation vertical if vertical prop is set', () => {
const wrapper = mountFunction({
propsData: { vertical: true },
})

expect(wrapper.attributes('aria-orientation')).toBe('vertical')
expect(wrapper.html()).toMatchSnapshot()
})

it('should have presentation role if set in attrs', () => {
const wrapper = mountFunction({
attrs: { role: 'presentation' },
})
it.each([
[{ length: 256 }, 'max-width: 256px;'],
[{ length: '128', vertical: true }, 'max-height: 128px;'],
[{ thickness: 2 }, 'border-top-width: 2px;'],
[{ thickness: '5', vertical: true }, 'border-right-width: 5px;'],
])('should have correct styles for %s', (propsData, expected) => {
const wrapper = mountFunction({ propsData })

expect(wrapper.attributes('role')).toBe('presentation')
expect(wrapper.attributes('style')).toEqual(expected)
})

it('should have no aria-orientation if presentation role is set in attrs', () => {
const wrapper = mountFunction({
attrs: { role: 'presentation' },
})
it.each([
[{}, ['horizontal', 'separator']],
[{ vertical: true }, ['vertical', 'separator']],
[{ role: 'foo' }, [undefined, 'foo']],
])('should have correct attributes for %s', (propsData, expected) => {
const wrapper = mountFunction({ propsData })
const [ariaorientation, role] = expected

expect(wrapper.attributes('aria-orientation')).toBeUndefined()
expect(wrapper.attributes().ariaorientation).toBe(ariaorientation)
expect(wrapper.attributes().role).toBe(role)
})
})
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`VDivider should render component and match snapshot 1`] = `
<hr role="separator"
aria-orientation="horizontal"
class="v-divider theme--light"
exports[`VDivider should match a snapshot 1`] = `
<hr class="v-divider v-theme--light"
ariaorientation="horizontal"
role="separator"
>
`;
30 changes: 28 additions & 2 deletions packages/vuetify/src/components/VDivider/_variables.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,31 @@
@import '../../styles/styles.sass';

// Defaults
$divider-border-color: rgba(var(--v-border-color), var(--v-border-opacity)) !default;
$divider-border-style: solid !default;
$divider-border-width: thin 0 0 0 !default;
$divider-flex: 1 1 100% !default;
$divider-margin: 8px !default;

$divider-query: () !default;
$divider-query: map-deep-merge(
(
'border-color': $divider-border-color,
'border-style': $divider-border-style,
'border-width': $divider-border-width
),
$divider-query
);

// Inset
$divider-inset-margin: 72px !default;
$divider-inset-margin-top: 8px !default;
$divider-inset-max-height: calc(100% - 16px) !default;
$divider-inset-max-width: calc(100% - #{$divider-inset-margin}) !default;

// Vertical
$divider-vertical-border-width: 0 thin 0 0 !default;
$divider-vertical-margin-left: -1px !default;

// Vertical & Inset
$divider-vertical-inset-margin-bottom: $divider-margin !default;
$divider-vertical-inset-margin-top: $divider-margin !default;
$divider-vertical-inset-max-height: calc(100% - #{$divider-margin * 2}) !default;
2 changes: 1 addition & 1 deletion packages/vuetify/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export * from './VApp'
// export * from './VDataTable'
// export * from './VDatePicker'
// export * from './VDialog'
// export * from './VDivider'
export * from './VDivider'
// export * from './VExpansionPanel'
// export * from './VFileInput'
// export * from './VFooter'
Expand Down

0 comments on commit cc033c6

Please sign in to comment.