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

feat(VDivider): port to v3 #12993

Merged
merged 14 commits into from
Jan 26, 2021
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
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
johnleider marked this conversation as resolved.
Show resolved Hide resolved
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"
johnleider marked this conversation as resolved.
Show resolved Hide resolved
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