This commit is contained in:
darenhsu
2022-07-17 13:16:16 +08:00
parent 84759556ff
commit befd344ab0
28070 changed files with 4008428 additions and 1 deletions
+159
View File
@@ -0,0 +1,159 @@
@import './_variables.scss'
+theme('v-toolbar.v-sheet') using ($material)
background-color: map-get($material, 'toolbar')
// Sheet
+sheet(v-toolbar, $toolbar-elevation, $toolbar-border-radius, $toolbar-shaped-border-radius)
// Block
.v-toolbar
contain: layout
display: block
flex: 1 1 auto
max-width: 100%
transition: $toolbar-transition
+elevation(4)
.v-input
padding-top: 0
margin-top: 0
// Element
.v-toolbar__content,
.v-toolbar__extension
padding: $toolbar-content-padding-y $toolbar-content-padding-x
.v-btn.v-btn--icon.v-size--default
height: $toolbar-btn-icon-size
width: $toolbar-btn-icon-size
> .v-btn.v-btn--icon
&:first-child
+ltr()
margin-left: -#{$toolbar-btn-icon-size / 4}
+rtl()
margin-right: -#{$toolbar-btn-icon-size / 4}
+ .v-toolbar__title
+ltr()
padding-left: $toolbar-title-padding
+rtl()
padding-right: $toolbar-title-padding
&:last-child
+ltr()
margin-right: -#{$toolbar-btn-icon-size / 4}
+rtl()
margin-left: -#{$toolbar-btn-icon-size / 4}
> .v-tabs
height: inherit
margin-top: -#{$toolbar-content-padding-y}
margin-bottom: -#{$toolbar-content-padding-y}
> .v-slide-group.v-tabs-bar
background-color: inherit
height: inherit
&:first-child
margin-left: -#{$toolbar-content-padding-x}
&:last-child
margin-right: -#{$toolbar-content-padding-x}
.v-toolbar__content,
.v-toolbar__extension
align-items: center
display: flex
position: relative
z-index: 0
.v-toolbar__image
border-radius: inherit
position: absolute
top: 0
bottom: 0
width: 100%
z-index: 0
contain: strict
.v-image
border-radius: inherit
.v-toolbar__items
display: flex
height: inherit
> .v-btn
border-radius: 0
height: 100% !important
max-height: none
.v-toolbar__title
font-size: 1.25rem
line-height: 1.5
overflow: hidden
text-overflow: ellipsis
white-space: nowrap
// Modifier
.v-toolbar.v-toolbar--absolute
position: absolute
top: 0
z-index: 1
.v-toolbar.v-toolbar--bottom
top: initial
bottom: 0
.v-toolbar.v-toolbar--collapse
.v-toolbar__title
white-space: nowrap
.v-toolbar.v-toolbar--collapsed
max-width: $toolbar-collapsed-max-width
overflow: hidden
+ltr()
border-bottom-right-radius: $toolbar-collapsed-border-radius
+rtl()
border-bottom-left-radius: $toolbar-collapsed-border-radius
.v-toolbar__title,
.v-toolbar__extension
display: none
.v-toolbar--dense
.v-toolbar__content,
.v-toolbar__extension
padding-top: 0
padding-bottom: 0
// @deprecated
// TODO: Remove in v3
.v-toolbar--flat
+elevation(0, true)
.v-toolbar--floating
display: inline-flex
.v-toolbar--prominent
.v-toolbar__content
align-items: flex-start
.v-toolbar__title
font-size: 1.5rem
padding-top: $toolbar-promient-padding
&:not(.v-toolbar--bottom)
.v-toolbar__title
align-self: flex-end
padding-bottom: $toolbar-promient-padding
padding-top: 0
+166
View File
@@ -0,0 +1,166 @@
// Styles
import './VToolbar.sass'
// Extensions
import VSheet from '../VSheet/VSheet'
// Components
import VImg, { srcObject } from '../VImg/VImg'
// Utilities
import { convertToUnit, getSlot } from '../../util/helpers'
import { breaking } from '../../util/console'
// Types
import { VNode, PropType } from 'vue'
/* @vue/component */
export default VSheet.extend({
name: 'v-toolbar',
props: {
absolute: Boolean,
bottom: Boolean,
collapse: Boolean,
dense: Boolean,
extended: Boolean,
extensionHeight: {
default: 48,
type: [Number, String],
},
flat: Boolean,
floating: Boolean,
prominent: Boolean,
short: Boolean,
src: {
type: [String, Object] as PropType<string | srcObject>,
default: '',
},
tag: {
type: String,
default: 'header',
},
},
data: () => ({
isExtended: false,
}),
computed: {
computedHeight (): number {
const height = this.computedContentHeight
if (!this.isExtended) return height
const extensionHeight = parseInt(this.extensionHeight)
return this.isCollapsed
? height
: height + (!isNaN(extensionHeight) ? extensionHeight : 0)
},
computedContentHeight (): number {
if (this.height) return parseInt(this.height)
if (this.isProminent && this.dense) return 96
if (this.isProminent && this.short) return 112
if (this.isProminent) return 128
if (this.dense) return 48
if (this.short || this.$vuetify.breakpoint.smAndDown) return 56
return 64
},
classes (): object {
return {
...VSheet.options.computed.classes.call(this),
'v-toolbar': true,
'v-toolbar--absolute': this.absolute,
'v-toolbar--bottom': this.bottom,
'v-toolbar--collapse': this.collapse,
'v-toolbar--collapsed': this.isCollapsed,
'v-toolbar--dense': this.dense,
'v-toolbar--extended': this.isExtended,
'v-toolbar--flat': this.flat,
'v-toolbar--floating': this.floating,
'v-toolbar--prominent': this.isProminent,
}
},
isCollapsed (): boolean {
return this.collapse
},
isProminent (): boolean {
return this.prominent
},
styles (): object {
return {
...this.measurableStyles,
height: convertToUnit(this.computedHeight),
}
},
},
created () {
const breakingProps = [
['app', '<v-app-bar app>'],
['manual-scroll', '<v-app-bar :value="false">'],
['clipped-left', '<v-app-bar clipped-left>'],
['clipped-right', '<v-app-bar clipped-right>'],
['inverted-scroll', '<v-app-bar inverted-scroll>'],
['scroll-off-screen', '<v-app-bar scroll-off-screen>'],
['scroll-target', '<v-app-bar scroll-target>'],
['scroll-threshold', '<v-app-bar scroll-threshold>'],
['card', '<v-app-bar flat>'],
]
/* istanbul ignore next */
breakingProps.forEach(([original, replacement]) => {
if (this.$attrs.hasOwnProperty(original)) breaking(original, replacement, this)
})
},
methods: {
genBackground () {
const props = {
height: convertToUnit(this.computedHeight),
src: this.src,
}
const image = this.$scopedSlots.img
? this.$scopedSlots.img({ props })
: this.$createElement(VImg, { props })
return this.$createElement('div', {
staticClass: 'v-toolbar__image',
}, [image])
},
genContent () {
return this.$createElement('div', {
staticClass: 'v-toolbar__content',
style: {
height: convertToUnit(this.computedContentHeight),
},
}, getSlot(this))
},
genExtension () {
return this.$createElement('div', {
staticClass: 'v-toolbar__extension',
style: {
height: convertToUnit(this.extensionHeight),
},
}, getSlot(this, 'extension'))
},
},
render (h): VNode {
this.isExtended = this.extended || !!this.$scopedSlots.extension
const children = [this.genContent()]
const data = this.setBackgroundColor(this.color, {
class: this.classes,
style: this.styles,
on: this.$listeners,
})
if (this.isExtended) children.push(this.genExtension())
if (this.src || this.$scopedSlots.img) children.unshift(this.genBackground())
return h(this.tag, data, children)
},
})
+105
View File
@@ -0,0 +1,105 @@
// Libraries
import Vue from 'vue'
// Components
import VToolbar from '../VToolbar'
import { ExtractVue } from '../../../util/mixins'
// Utilities
import {
mount,
Wrapper,
} from '@vue/test-utils'
describe('VToolbar.ts', () => {
type Instance = ExtractVue<typeof VToolbar>
let mountFunction: (options?: object) => Wrapper<Instance>
beforeEach(() => {
mountFunction = (options = {}) => {
return mount(VToolbar, {
// https://github.com/vuejs/vue-test-utils/issues/1130
sync: false,
mocks: {
$vuetify: {
breakpoint: {},
},
},
...options,
})
}
})
it('should render an extended toolbar', () => {
const wrapper = mountFunction({
propsData: {
extended: true,
},
})
expect(wrapper.html()).toMatchSnapshot()
})
it('should render an extended toolbar with specific height', () => {
const wrapper = mountFunction({
propsData: {
extended: true,
extensionHeight: 42,
},
})
expect(wrapper.html()).toMatchSnapshot()
})
it('should properly calculate content height', () => {
const wrapper = mountFunction()
wrapper.setProps({
height: 999,
})
expect(wrapper.vm.computedContentHeight).toBe(999)
wrapper.setProps({
height: null,
dense: true,
})
expect(wrapper.vm.computedContentHeight).toBe(48)
wrapper.setProps({
height: null,
dense: false,
prominent: true,
})
expect(wrapper.vm.computedContentHeight).toBe(128)
wrapper.setProps({
height: null,
dense: false,
prominent: false,
})
Vue.set(wrapper.vm.$vuetify.breakpoint, 'smAndDown', true)
expect(wrapper.vm.computedContentHeight).toBe(56)
Vue.set(wrapper.vm.$vuetify.breakpoint, 'smAndDown', false)
expect(wrapper.vm.computedContentHeight).toBe(64)
})
it('should have a custom extension height', () => {
const wrapper = mountFunction({
propsData: { tabs: true },
})
expect(wrapper.vm.extensionHeight).toBe(48)
})
it('should set height equal to both height and extensionHeight', () => {
const wrapper = mountFunction({
propsData: {
height: 112,
extended: true,
extensionHeight: 64,
},
})
expect((wrapper.vm.styles as any).height).toBe('176px')
})
})
@@ -0,0 +1,31 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`VToolbar.ts should render an extended toolbar 1`] = `
<header class="v-sheet theme--light v-toolbar v-toolbar--extended"
style="height: 112px;"
>
<div class="v-toolbar__content"
style="height: 64px;"
>
</div>
<div class="v-toolbar__extension"
style="height: 48px;"
>
</div>
</header>
`;
exports[`VToolbar.ts should render an extended toolbar with specific height 1`] = `
<header class="v-sheet theme--light v-toolbar v-toolbar--extended"
style="height: 106px;"
>
<div class="v-toolbar__content"
style="height: 64px;"
>
</div>
<div class="v-toolbar__extension"
style="height: 42px;"
>
</div>
</header>
`;
+19
View File
@@ -0,0 +1,19 @@
@import '../../styles/styles.sass';
$toolbar-btn-icon-size: 48px !default;
$toolbar-content-padding-y: 4px !default;
$toolbar-content-padding-x: 16px !default;
$toolbar-elevation: 4 !default;
$toolbar-border-radius: 0 !default;
$toolbar-shaped-border-radius: map-get($rounded, 'xl') $toolbar-border-radius !default;
$toolbar-title-padding: 20px !default;
$toolbar-transition: 0.2s map-get($transition, 'fast-out-slow-in') transform,
0.2s map-get($transition, 'fast-out-slow-in') background-color,
0.2s map-get($transition, 'fast-out-slow-in') left,
0.2s map-get($transition, 'fast-out-slow-in') right,
280ms map-get($transition, 'fast-out-slow-in') box-shadow,
0.25s map-get($transition, 'fast-out-slow-in') max-width,
0.25s map-get($transition, 'fast-out-slow-in') width !default;
$toolbar-collapsed-max-width: 112px !default;
$toolbar-collapsed-border-radius: 24px !default;
$toolbar-promient-padding: 6px !default;
+22
View File
@@ -0,0 +1,22 @@
// Components
import VToolbar from './VToolbar'
// Utilities
import { createSimpleFunctional } from '../../util/helpers'
const VToolbarTitle = createSimpleFunctional('v-toolbar__title')
const VToolbarItems = createSimpleFunctional('v-toolbar__items')
export {
VToolbar,
VToolbarItems,
VToolbarTitle,
}
export default {
$_vuetify_subcomponents: {
VToolbar,
VToolbarItems,
VToolbarTitle,
},
}