`;
diff --git a/packages/vuetify/src/components/VList/__tests__/__snapshots__/VListItemAction.spec.ts.snap b/packages/vuetify/src/components/VList/__tests__/__snapshots__/VListItemAction.spec.ts.snap
deleted file mode 100644
index 2b59049dff0..00000000000
--- a/packages/vuetify/src/components/VList/__tests__/__snapshots__/VListItemAction.spec.ts.snap
+++ /dev/null
@@ -1,29 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`VListItemAction.ts should render component and match snapshot 1`] = `
-
-`;
-
-exports[`VListItemAction.ts should render component with many children and match snapshot 1`] = `
-
-`;
-
-exports[`VListItemAction.ts should render component with one children and match snapshot 1`] = `
-
-`;
-
-exports[`VListItemAction.ts should render component with static class and match snapshot 1`] = `
-
-`;
diff --git a/packages/vuetify/src/components/VList/__tests__/__snapshots__/VListItemAvatar.spec.ts.snap b/packages/vuetify/src/components/VList/__tests__/__snapshots__/VListItemAvatar.spec.ts.snap
index 2ee76fe58dd..200112ec87e 100644
--- a/packages/vuetify/src/components/VList/__tests__/__snapshots__/VListItemAvatar.spec.ts.snap
+++ b/packages/vuetify/src/components/VList/__tests__/__snapshots__/VListItemAvatar.spec.ts.snap
@@ -1,8 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`VListItemAvatar.ts should render component and match snapshot 1`] = `
-
+exports[`VListItemAvatar should match a snapshot 1`] = `
+
`;
diff --git a/packages/vuetify/src/components/VList/__tests__/__snapshots__/VListItemMedia.spec.ts.snap b/packages/vuetify/src/components/VList/__tests__/__snapshots__/VListItemMedia.spec.ts.snap
new file mode 100644
index 00000000000..c61febfcbf4
--- /dev/null
+++ b/packages/vuetify/src/components/VList/__tests__/__snapshots__/VListItemMedia.spec.ts.snap
@@ -0,0 +1,6 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`VListItemMedia should match a snapshot 1`] = `
+
+
+`;
diff --git a/packages/vuetify/src/components/VList/_index.scss b/packages/vuetify/src/components/VList/_index.scss
new file mode 100644
index 00000000000..6f8b481aec9
--- /dev/null
+++ b/packages/vuetify/src/components/VList/_index.scss
@@ -0,0 +1,3 @@
+@import '../../styles/styles.sass';
+@import './variables';
+@import './mixins';
diff --git a/packages/vuetify/src/components/VList/_mixins.sass b/packages/vuetify/src/components/VList/_mixins.sass
deleted file mode 100644
index ed01d6195f1..00000000000
--- a/packages/vuetify/src/components/VList/_mixins.sass
+++ /dev/null
@@ -1,18 +0,0 @@
-@mixin list-shaped($size)
- .v-list-item
- &,
- &::before,
- > .v-ripple__container
- +ltr()
- border-bottom-right-radius: #{$size * 0.6666666666666667} !important
- border-top-right-radius: #{$size * 0.6666666666666667} !important
- +rtl()
- border-bottom-left-radius: #{$size * 0.6666666666666667} !important
- border-top-left-radius: #{$size * 0.6666666666666667} !important
-
-@mixin list-rounded($size)
- .v-list-item
- &,
- &::before,
- > .v-ripple__container
- border-radius: #{$size * 0.6666666666666667} !important
diff --git a/packages/vuetify/src/components/VList/_mixins.scss b/packages/vuetify/src/components/VList/_mixins.scss
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/packages/vuetify/src/components/VList/_variables.scss b/packages/vuetify/src/components/VList/_variables.scss
index 8779769cb5d..d4e9928a142 100644
--- a/packages/vuetify/src/components/VList/_variables.scss
+++ b/packages/vuetify/src/components/VList/_variables.scss
@@ -1,67 +1,126 @@
-@import '../../styles/styles.sass';
-
-$avatar-margin-x: 16px !default;
+// Defaults
+$list-background: rgba(var(--v-theme-surface)) !default;
+$list-border-color: $border-color-root !default;
$list-border-radius: 0 !default;
+$list-border-style: $border-style-root !default;
+$list-border-thin-width: thin !default;
+$list-border-width: 0 !default;
+$list-color: rgba(var(--v-theme-on-surface)) !default;
+$list-disabled-opacity: 0.6 !default;
$list-elevation: 0 !default;
-$list-dense-subheader-font-size: 0.75rem !default;
-$list-dense-subheader-height: 40px !default;
-// TODO: Resolve naming conflicts for
-// shaped style propagation to items
-$list-shaped-border-radius: 0 !default;
+$list-padding: 8px 0 !default;
+$list-positions: absolute fixed !default;
-$list-item-avatar-margin-y: 8px !default;
-$list-item-avatar-horizontal-margin-x: -16px !default;
+$list-nav-subheader-font-size: .75rem !default;
-$list-item-icon-margin-y: 16px !default;
+$list-subheader-font-size: .875rem !default;
+$list-subheader-font-weight: 500 !default;
+$list-subheader-inset-margin: 56px !default;
+$list-subheader-inset-padding-start: 72px !default;
+$list-subheader-line-height: 1.375rem !default;
+$list-subheader-min-height: 48px !default;
+$list-subheader-padding-end: 16px !default;
+$list-subheader-padding-start: 16px !default;
+$list-subheader-padding-top: 0 !default;
+$list-subheader-min-height-multiplier: 1 !default;
+$list-subheader-text-opacity: var(--v-medium-emphasis-opacity) !default;
+$list-subheader-transition: 0.2s min-height $standard-easing !default;
$list-item-min-height: 48px !default;
+$list-item-padding: 8px 16px !default;
+$list-item-transition: .2s $standard-easing !default;
$list-item-two-line-min-height: 64px !default;
+$list-item-two-line-padding: 12px 16px !default;
$list-item-three-line-min-height: 88px !default;
+$list-item-three-line-padding: 16px 16px !default;
-$list-item-title-font-size: map-deep-get($typography, 'subtitle-1', 'size') !default;
-$list-item-subtitle-font-size: map-deep-get($typography, 'subtitle-2', 'size') !default;
+$list-item-avatar-align-self: flex-start !default;
+$list-item-avatar-margin-end: 16px !default;
+$list-item-avatar-margin-start: 16px !default;
+$list-item-avatar-size: 40px !default;
+$list-item-avatar-size-multiplier: 1.5 !default;
+$list-item-avatar-margin-y: 4px !default;
-$list-item-dense-title-font-size: 0.8125rem !default;
-$list-item-dense-title-font-weight: 500 !default;
-$list-padding: 8px 0 !default;
-$list-dense-subheading-padding: 0 8px !default;
-$list-nav-border-radius: $border-radius-root !default;
-$list-nav-rounded-item-margin-bottom: 8px !default;
-$list-nav-rounded-item-dense-margin-bottom: 4px !default;
-$list-nav-padding-left: 8px !default;
-$list-nav-padding-right: 8px !default;
-$list-nav-item-padding: 0 8px !default;
-$list-shaped-padding: 8px !default;
-$list-subheader-padding-top: 0 !default;
-$list-group-header-icon-min-width: 48px !default;
-$list-group-sub-group-child-margin: 16px !default;
-$list-group-sub-group-header-margin: 32px !default;
-$list-group-items-item-padding: 40px !default;
-$list-group-no-action-item-padding: 72px !default;
-$list-dense-subheader-padding: 0 8px !default;
-$list-nav-rounded-dense-item-margin-bottom: 4px !default;
-$list-group-no-action-sub-group-item-padding: 88px !default;
-$list-group-dense-sub-group-header-padding: 24px !default;
-$list-group-nav-no-action-item-padding: 64px !default;
-$list-group-sub-group-item-padding: 80px !default;
-$list-item-padding: 0 16px !default;
-$list-item-action-margin: 12px 0 !default;
-$list-item-action-text-font-size: map-deep-get($typography, 'caption', 'size') !default;
-$list-item-avatar-horizontal-margin: 8px !default;
-$list-item-content-padding: 12px 0 !default;
-$list-item-content-children-margin-bottom: 2px !default;
-$list-item-icon-margin: 16px 0 !default;
-$list-item-child-last-type-margin: 16px !default;
-$list-item-child-min-width: 24px !default;
-$list-item-title-subtitle-line-height: 1.2 !default;
-$list-item-avatar-first-child-margin: 16px !default;
-$list-item-action-icon-margin: 32px !default;
-$list-dense-icon-height: 24px !default;
-$list-dense-icon-margin: 8px !default;
-$list-dense-min-height: 40px !default;
-$list-item-dense-title-line-height: 1rem !default;
-$list-item-dense-two-line-min-height: 60px !default;
-$list-item-dense-three-line-min-height: 76px !default;
-$list-dense-content-padding: 8px 0 !default;
-$list-item-two-line-icon-margin-bottom: 32px !default;
-$list-item-three-line-avatar-action-margin: 16px !default;
+$list-item-media-margin-bottom: 0 !default;
+$list-item-media-margin-end: 16px !default;
+$list-item-media-margin-start: 16px !default;
+$list-item-media-margin-top: 0 !default;
+$list-item-media-two-line-margin-bottom: -4px !default;
+$list-item-media-two-line-margin-top: -4px !default;
+$list-item-media-three-line-margin-bottom: 0 !default;
+$list-item-media-three-line-margin-top: 0 !default;
+
+$list-item-nav-title-font-size: .8125rem !default;
+$list-item-nav-title-font-weight: 500 !default;
+$list-item-nav-title-letter-spacing: normal !default;
+$list-item-nav-title-line-height: 1rem !default;
+$list-item-nav-subtitle-font-size: .75rem !default;
+$list-item-nav-subtitle-font-weight: map-deep-get($typography, 'body-2', 'weight') !default;
+$list-item-nav-subtitle-letter-spacing: map-deep-get($typography, 'body-2', 'letter-spacing') !default;
+$list-item-nav-subtitle-line-height: 1rem !default;
+
+$list-item-subtitle-opacity: var(--v-medium-emphasis-opacity) !default;
+$list-item-subtitle-font-size: map-deep-get($typography, 'body-2', 'size') !default;
+$list-item-subtitle-font-weight: map-deep-get($typography, 'body-2', 'weight') !default;
+$list-item-subtitle-letter-spacing: map-deep-get($typography, 'body-2', 'letter-spacing') !default;
+$list-item-subtitle-line-height: 1rem !default;
+$list-item-subtitle-padding: 0 !default;
+$list-item-subtitle-text-transform: none !default;
+
+$list-item-title-font-size: map-deep-get($typography, 'body-1', 'size') !default;
+$list-item-title-font-weight: map-deep-get($typography, 'body-1', 'weight') !default;
+$list-item-title-header-padding: 0 !default;
+$list-item-title-hyphens: auto !default;
+$list-item-title-letter-spacing: map-deep-get($typography, 'subtitle-1', 'letter-spacing') !default;
+$list-item-title-line-height: map-deep-get($typography, 'body-1', 'line-height') !default;
+$list-item-title-overflow-wrap: normal !default;
+$list-item-title-padding: 0 !default;
+$list-item-title-text-overflow: ellipsis;
+$list-item-title-text-transform: none !default;
+$list-item-title-word-break: normal !default;
+$list-item-title-word-wrap: break-word !default;
+
+$list-density: ('default': 0, 'comfortable': -1, 'compact': -2) !default;
+
+$list-border: (
+ $list-border-color,
+ $list-border-style,
+ $list-border-width
+);
+
+$list-theme: (
+ $list-background,
+ $list-color
+);
+
+$list-item-title-typography: (
+ $list-item-title-font-size,
+ $list-item-title-font-weight,
+ $list-item-title-letter-spacing,
+ $list-item-title-line-height,
+ $list-item-title-text-transform
+);
+
+$list-item-subtitle-typography: (
+ $list-item-subtitle-font-size,
+ $list-item-subtitle-font-weight,
+ $list-item-subtitle-letter-spacing,
+ $list-item-subtitle-line-height,
+ $list-item-subtitle-text-transform
+);
+
+$list-item-nav-title-typography: (
+ $list-item-nav-title-font-size,
+ $list-item-nav-title-font-weight,
+ $list-item-nav-title-letter-spacing,
+ $list-item-nav-title-line-height,
+ null
+);
+
+$list-item-nav-subtitle-typography: (
+ $list-item-nav-subtitle-font-size,
+ $list-item-nav-subtitle-font-weight,
+ $list-item-nav-subtitle-letter-spacing,
+ $list-item-nav-subtitle-line-height,
+ null
+);
diff --git a/packages/vuetify/src/components/VList/index.ts b/packages/vuetify/src/components/VList/index.ts
index 2dbdda8568e..bc4d7047c27 100644
--- a/packages/vuetify/src/components/VList/index.ts
+++ b/packages/vuetify/src/components/VList/index.ts
@@ -1,40 +1,9 @@
-import { createSimpleFunctional } from '@/util'
-
-import VList from './VList'
-import VListGroup from './VListGroup'
-import VListItem from './VListItem'
-import VListItemGroup from './VListItemGroup'
-import VListItemAction from './VListItemAction'
-import VListItemAvatar from './VListItemAvatar'
-import VListItemIcon from './VListItemIcon'
-
-export const VListItemActionText = createSimpleFunctional('v-list-item__action-text', 'span')
-export const VListItemContent = createSimpleFunctional('v-list-item__content', 'div')
-export const VListItemTitle = createSimpleFunctional('v-list-item__title', 'div')
-export const VListItemSubtitle = createSimpleFunctional('v-list-item__subtitle', 'div')
-
-export {
- VList,
- VListGroup,
- VListItem,
- VListItemAction,
- VListItemAvatar,
- VListItemIcon,
- VListItemGroup,
-}
-
-export default {
- $_vuetify_subcomponents: {
- VList,
- VListGroup,
- VListItem,
- VListItemAction,
- VListItemActionText,
- VListItemAvatar,
- VListItemContent,
- VListItemGroup,
- VListItemIcon,
- VListItemSubtitle,
- VListItemTitle,
- },
-}
+export { default as VList } from './VList'
+export { default as VListSubheader } from './VListSubheader'
+export { default as VListImg } from './VListImg'
+export { default as VListItem } from './VListItem'
+export { default as VListItemAvatar } from './VListItemAvatar'
+export { default as VListItemHeader } from './VListItemHeader'
+export { default as VListItemMedia } from './VListItemMedia'
+export { default as VListItemSubtitle } from './VListItemSubtitle'
+export { default as VListItemTitle } from './VListItemTitle'
diff --git a/packages/vuetify/src/components/VSubheader/VSubheader.sass b/packages/vuetify/src/components/VSubheader/VSubheader.sass
deleted file mode 100644
index 0b8ff1657dd..00000000000
--- a/packages/vuetify/src/components/VSubheader/VSubheader.sass
+++ /dev/null
@@ -1,15 +0,0 @@
-@import './_variables.scss'
-
-+theme(v-subheader) using ($material)
- color: map-deep-get($material, 'text', 'secondary')
-
-.v-subheader
- align-items: center
- display: flex
- height: $subheader-item-single-height
- font-size: map-deep-get($typography, 'body-2', 'size')
- font-weight: map-deep-get($typography, 'body-2', 'weight')
- padding: 0 $subheader-right-padding 0 $subheader-left-padding
-
- &--inset
- margin-left: $subheader-inset-margin
diff --git a/packages/vuetify/src/components/VSubheader/VSubheader.ts b/packages/vuetify/src/components/VSubheader/VSubheader.ts
deleted file mode 100644
index 57a0b8c1d45..00000000000
--- a/packages/vuetify/src/components/VSubheader/VSubheader.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-// @ts-nocheck
-/* eslint-disable */
-
-// Styles
-import './VSubheader.sass'
-
-// Mixins
-import Themeable from '../../mixins/themeable'
-import mixins from '../../util/mixins'
-
-// Types
-import { VNode } from 'vue'
-
-export default mixins(
- Themeable
- /* @vue/component */
-).extend({
- name: 'v-subheader',
-
- props: {
- inset: Boolean,
- },
-
- render (h): VNode {
- return h('div', {
- staticClass: 'v-subheader',
- class: {
- 'v-subheader--inset': this.inset,
- ...this.themeClasses,
- },
- attrs: this.$attrs,
- on: this.$listeners,
- }, this.$slots.default)
- },
-})
diff --git a/packages/vuetify/src/components/VSubheader/__tests__/VSubheader.spec.ts b/packages/vuetify/src/components/VSubheader/__tests__/VSubheader.spec.ts
deleted file mode 100644
index a0ae6ea49f5..00000000000
--- a/packages/vuetify/src/components/VSubheader/__tests__/VSubheader.spec.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-// @ts-nocheck
-/* eslint-disable */
-
-// Components
-// import VSubheader from '../VSubheader'
-
-// Utilities
-import {
- mount,
- Wrapper,
-} from '@vue/test-utils'
-
-describe.skip('VSubheader.ts', () => {
- type Instance = InstanceType
- let mountFunction: (options?: object) => Wrapper
-
- beforeEach(() => {
- mountFunction = (options = {}) => {
- return mount(VSubheader, {
- ...options,
- })
- }
- })
-
- it('should have custom class', () => {
- const wrapper = mount({
- render: h => h(VSubheader, { staticClass: 'foo' }),
- })
-
- expect(wrapper.element.classList.contains('foo')).toBe(true)
- expect(wrapper.html()).toMatchSnapshot()
- })
-
- it('should be light', () => {
- const wrapper = mountFunction({
- propsData: { light: true },
- })
-
- expect(wrapper.element.classList.contains('theme--light')).toBe(true)
- expect(wrapper.html()).toMatchSnapshot()
- })
-
- it('should be dark', () => {
- const wrapper = mountFunction({
- propsData: { dark: true },
- })
-
- expect(wrapper.element.classList.contains('theme--dark')).toBe(true)
- expect(wrapper.html()).toMatchSnapshot()
- })
-
- it('should be inset', () => {
- const wrapper = mountFunction({
- propsData: { inset: true },
- })
-
- expect(wrapper.element.classList.contains('v-subheader--inset')).toBe(true)
- expect(wrapper.html()).toMatchSnapshot()
- })
-})
diff --git a/packages/vuetify/src/components/VSubheader/__tests__/__snapshots__/VSubheader.spec.ts.snap b/packages/vuetify/src/components/VSubheader/__tests__/__snapshots__/VSubheader.spec.ts.snap
deleted file mode 100644
index 6c77695b574..00000000000
--- a/packages/vuetify/src/components/VSubheader/__tests__/__snapshots__/VSubheader.spec.ts.snap
+++ /dev/null
@@ -1,21 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`VSubheader.ts should be dark 1`] = `
-
-`;
-
-exports[`VSubheader.ts should be inset 1`] = `
-
-`;
-
-exports[`VSubheader.ts should be light 1`] = `
-
-`;
-
-exports[`VSubheader.ts should have custom class 1`] = `
-
-`;
diff --git a/packages/vuetify/src/components/VSubheader/_variables.scss b/packages/vuetify/src/components/VSubheader/_variables.scss
deleted file mode 100644
index 08cad2d9ebd..00000000000
--- a/packages/vuetify/src/components/VSubheader/_variables.scss
+++ /dev/null
@@ -1,6 +0,0 @@
-@import '../../styles/styles.sass';
-
-$subheader-inset-margin: 56px !default;
-$subheader-item-single-height: 48px !default;
-$subheader-left-padding: 16px !default;
-$subheader-right-padding: 16px !default;
diff --git a/packages/vuetify/src/components/VSubheader/index.ts b/packages/vuetify/src/components/VSubheader/index.ts
deleted file mode 100644
index e9d2f7f69e4..00000000000
--- a/packages/vuetify/src/components/VSubheader/index.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-import VSubheader from './VSubheader'
-
-export { VSubheader }
-export default VSubheader
diff --git a/packages/vuetify/src/components/index.ts b/packages/vuetify/src/components/index.ts
index dc8a1392255..a19b1c3b5db 100644
--- a/packages/vuetify/src/components/index.ts
+++ b/packages/vuetify/src/components/index.ts
@@ -44,8 +44,8 @@ export * from './VItemGroup'
// export * from './VLabel'
export * from './VLayout'
export * from './VLocaleProvider'
+export * from './VList'
export * from './VLazy'
-// export * from './VList'
export * from './VMain'
// export * from './VMenu'
// export * from './VMessages'
@@ -70,7 +70,6 @@ export * from './VResponsive'
// export * from './VSparkline'
// export * from './VSpeedDial'
// export * from './VStepper'
-// export * from './VSubheader'
// export * from './VSwitch'
export * from './VSystemBar'
// export * from './VTabs'
diff --git a/packages/vuetify/src/composables/density.ts b/packages/vuetify/src/composables/density.ts
index 88795984235..ca8521f7fe9 100644
--- a/packages/vuetify/src/composables/density.ts
+++ b/packages/vuetify/src/composables/density.ts
@@ -5,12 +5,12 @@ import { propsFactory } from '@/util'
// Types
import type { PropType } from 'vue'
-const allowedDensities = ['default', 'comfortable', 'compact'] as const
+const allowedDensities = [null, 'default', 'comfortable', 'compact'] as const
type Density = typeof allowedDensities[number]
export interface DensityProps {
- density: Density
+ density?: Density
}
// Composables
diff --git a/packages/vuetify/src/styles/tools/_density.sass b/packages/vuetify/src/styles/tools/_density.sass
index b6f93b64a65..fce1f4d93d2 100644
--- a/packages/vuetify/src/styles/tools/_density.sass
+++ b/packages/vuetify/src/styles/tools/_density.sass
@@ -1,10 +1,4 @@
-@mixin density($name, $properties, $densities)
+@mixin density($name, $densities)
@each $density, $multiplier in $densities
- $value: calc(var(--#{$name}-height) + #{$multiplier * $spacer})
-
- &.#{$name}--density-#{$density}
- @if type-of($properties) == 'list'
- @each $property in $properties
- #{$property}: $value
- @else
- #{$properties}: $value
+ .#{$name}--density-#{$density}
+ @content($multiplier * $spacer)
diff --git a/packages/vuetify/src/styles/tools/_index.sass b/packages/vuetify/src/styles/tools/_index.sass
index e3bfed62c33..b6539340519 100644
--- a/packages/vuetify/src/styles/tools/_index.sass
+++ b/packages/vuetify/src/styles/tools/_index.sass
@@ -10,6 +10,7 @@
@import './_sheet'
@import './_states'
@import './_theme'
+@import './_typography'
@import './_utilities'
@import './_display'
diff --git a/packages/vuetify/src/styles/tools/_typography.sass b/packages/vuetify/src/styles/tools/_typography.sass
new file mode 100644
index 00000000000..33ad03deae2
--- /dev/null
+++ b/packages/vuetify/src/styles/tools/_typography.sass
@@ -0,0 +1,6 @@
+@mixin typography ($font-size, $font-weight, $letter-spacing, $line-height, $text-transform)
+ font-size: $font-size
+ font-weight: $font-weight
+ letter-spacing: $letter-spacing
+ line-height: $line-height
+ text-transform: $text-transform