Commit dfe23efe3d262c0e57943525db9e17171aab49d1
Committed by
GitHub
Merge pull request #2646 from lison16/layout
add layout component with header, content, sider and footer
Showing
18 changed files
with
482 additions
and
4 deletions
Show diff stats
examples/app.vue
| ... | ... | @@ -6,13 +6,14 @@ nav { margin-bottom: 40px; } |
| 6 | 6 | ul { display: flex; flex-wrap: wrap; } |
| 7 | 7 | li { display: inline-block; } |
| 8 | 8 | li + li { border-left: solid 1px #bbb; padding-left: 10px; margin-left: 10px; } |
| 9 | -.container{ padding: 10px 40px; } | |
| 9 | +.container{ padding: 10px 40px 0; } | |
| 10 | 10 | .v-link-active { color: #bbb; } |
| 11 | 11 | </style> |
| 12 | 12 | <template> |
| 13 | 13 | <div class="container"> |
| 14 | 14 | <nav> |
| 15 | 15 | <ul> |
| 16 | + <li><router-link to="/layout">Layout</router-link></li> | |
| 16 | 17 | <li><router-link to="/affix">Affix</router-link></li> |
| 17 | 18 | <li><router-link to="/grid">Grid</router-link></li> |
| 18 | 19 | <li><router-link to="/button">Button</router-link></li> | ... | ... |
examples/main.js
| 1 | +<template> | |
| 2 | + <div class="layout-demo-con"> | |
| 3 | + <Layout :style="{minHeight: '100vh'}"> | |
| 4 | + <Sider | |
| 5 | + v-model="isCollapsed" | |
| 6 | + collapsed-width="0" | |
| 7 | + collapsible | |
| 8 | + ref="side" | |
| 9 | + width="200"> | |
| 10 | + <Menu width="auto" theme="dark" active-name="1"> | |
| 11 | + <MenuGroup title="内容管理"> | |
| 12 | + <MenuItem name="1"> | |
| 13 | + <Icon type="document-text"></Icon> | |
| 14 | + 文章管理 | |
| 15 | + </MenuItem> | |
| 16 | + <MenuItem name="2"> | |
| 17 | + <Icon type="chatbubbles"></Icon> | |
| 18 | + 评论管理 | |
| 19 | + </MenuItem> | |
| 20 | + </MenuGroup> | |
| 21 | + <MenuGroup title="统计分析"> | |
| 22 | + <MenuItem name="3"> | |
| 23 | + <Icon type="heart"></Icon> | |
| 24 | + 用户留存 | |
| 25 | + </MenuItem> | |
| 26 | + <MenuItem name="4"> | |
| 27 | + <Icon type="heart-broken"></Icon> | |
| 28 | + 流失用户 | |
| 29 | + </MenuItem> | |
| 30 | + </MenuGroup> | |
| 31 | + </Menu> | |
| 32 | + </Sider> | |
| 33 | + <Layout class-name="test-class"> | |
| 34 | + <Header :style="{background: '#eee'}"><Button @click="toggleCollapse">菜单</Button></Header> | |
| 35 | + <Content :style="{background:'#FFCF9E'}"> | |
| 36 | + <p v-for="i in 100" :key="i">{{ i }}</p> | |
| 37 | + </Content> | |
| 38 | + <Footer>sdfsdsdfsdfs</Footer> | |
| 39 | + </Layout> | |
| 40 | + </Layout> | |
| 41 | + </div> | |
| 42 | +</template> | |
| 43 | +<script> | |
| 44 | +export default { | |
| 45 | + data () { | |
| 46 | + return { | |
| 47 | + isCollapsed: false | |
| 48 | + }; | |
| 49 | + }, | |
| 50 | + methods: { | |
| 51 | + toggleCollapse () { | |
| 52 | + this.$refs.side.toggleCollapse(); | |
| 53 | + } | |
| 54 | + } | |
| 55 | +}; | |
| 56 | +</script> | |
| 57 | +<style lang="less" scoped> | |
| 58 | + .layout-demo-con{ | |
| 59 | + height: 100%; | |
| 60 | + } | |
| 61 | +</style> | |
| 0 | 62 | \ No newline at end of file | ... | ... |
| 1 | +<template> | |
| 2 | + <div :class="wrapClasses"><slot></slot></div> | |
| 3 | +</template> | |
| 4 | +<script> | |
| 5 | + const prefixCls = 'ivu-layout'; | |
| 6 | + export default { | |
| 7 | + name: 'Content', | |
| 8 | + computed: { | |
| 9 | + wrapClasses () { | |
| 10 | + return `${prefixCls}-content`; | |
| 11 | + } | |
| 12 | + } | |
| 13 | + }; | |
| 14 | +</script> | |
| 0 | 15 | \ No newline at end of file | ... | ... |
| 1 | +<template> | |
| 2 | + <div :class="wrapClasses"><slot></slot></div> | |
| 3 | +</template> | |
| 4 | +<script> | |
| 5 | + const prefixCls = 'ivu-layout'; | |
| 6 | + export default { | |
| 7 | + name: 'Footer', | |
| 8 | + computed: { | |
| 9 | + wrapClasses () { | |
| 10 | + return `${prefixCls}-footer`; | |
| 11 | + } | |
| 12 | + } | |
| 13 | + }; | |
| 14 | +</script> | |
| 0 | 15 | \ No newline at end of file | ... | ... |
| 1 | +<template> | |
| 2 | + <div :class="wrapClasses"><slot></slot></div> | |
| 3 | +</template> | |
| 4 | +<script> | |
| 5 | + const prefixCls = 'ivu-layout'; | |
| 6 | + export default { | |
| 7 | + name: 'Header', | |
| 8 | + computed: { | |
| 9 | + wrapClasses () { | |
| 10 | + return `${prefixCls}-header`; | |
| 11 | + } | |
| 12 | + } | |
| 13 | + }; | |
| 14 | +</script> | |
| 0 | 15 | \ No newline at end of file | ... | ... |
| 1 | +import Layout from './layout.vue'; | |
| 2 | +import Header from './header.vue'; | |
| 3 | +import Sider from './sider.vue'; | |
| 4 | +import Content from './content.vue'; | |
| 5 | +import Footer from './footer.vue'; | |
| 6 | + | |
| 7 | +Layout.Header = Header; | |
| 8 | +Layout.Sider = Sider; | |
| 9 | +Layout.Content = Content; | |
| 10 | +Layout.Footer = Footer; | |
| 11 | + | |
| 12 | +export default Layout; | |
| 0 | 13 | \ No newline at end of file | ... | ... |
| 1 | +<template> | |
| 2 | + <div :class="wrapClasses"><slot></slot></div> | |
| 3 | +</template> | |
| 4 | +<script> | |
| 5 | + const prefixCls = 'ivu-layout'; | |
| 6 | + | |
| 7 | + export default { | |
| 8 | + name: 'Layout', | |
| 9 | + data () { | |
| 10 | + return { | |
| 11 | + hasSider: false | |
| 12 | + }; | |
| 13 | + }, | |
| 14 | + computed: { | |
| 15 | + wrapClasses () { | |
| 16 | + return [ | |
| 17 | + `${prefixCls}`, | |
| 18 | + { | |
| 19 | + [`${prefixCls}-has-sider`]: this.hasSider | |
| 20 | + } | |
| 21 | + ]; | |
| 22 | + } | |
| 23 | + }, | |
| 24 | + methods: { | |
| 25 | + findSider () { | |
| 26 | + return this.$children.some(child => { | |
| 27 | + return child.$options.name === 'Sider'; | |
| 28 | + }); | |
| 29 | + } | |
| 30 | + }, | |
| 31 | + mounted () { | |
| 32 | + this.hasSider = this.findSider(); | |
| 33 | + } | |
| 34 | + }; | |
| 35 | +</script> | |
| 0 | 36 | \ No newline at end of file | ... | ... |
| 1 | +<template> | |
| 2 | + <div | |
| 3 | + :class="wrapClasses" | |
| 4 | + :style="wrapStyles"> | |
| 5 | + <span v-show="showZeroTrigger" @click="toggleCollapse" :class="zeroWidthTriggerClasses"> | |
| 6 | + <i class="ivu-icon ivu-icon-navicon-round"></i> | |
| 7 | + </span> | |
| 8 | + <div :class="childClasses"> | |
| 9 | + <slot></slot> | |
| 10 | + </div> | |
| 11 | + <div v-show="showBottomTrigger" :class="triggerClasses" @click="toggleCollapse" :style="{width: siderWidth + 'px'}"> | |
| 12 | + <i :class="triggerIconClasses"></i> | |
| 13 | + </div> | |
| 14 | + </div> | |
| 15 | +</template> | |
| 16 | +<script> | |
| 17 | + import { on, off } from '../../utils/dom'; | |
| 18 | + import { oneOf, dimensionMap, setMatchMedia } from '../../utils/assist'; | |
| 19 | + const prefixCls = 'ivu-layout-sider'; | |
| 20 | + setMatchMedia(); | |
| 21 | + export default { | |
| 22 | + name: 'Sider', | |
| 23 | + props: { | |
| 24 | + value: { // if it's collpased now | |
| 25 | + type: Boolean, | |
| 26 | + default: false | |
| 27 | + }, | |
| 28 | + width: { | |
| 29 | + type: [Number, String], | |
| 30 | + default: 200 | |
| 31 | + }, | |
| 32 | + collapsedWidth: { | |
| 33 | + type: [Number, String], | |
| 34 | + default: 64 | |
| 35 | + }, | |
| 36 | + hideTrigger: { | |
| 37 | + type: Boolean, | |
| 38 | + default: false | |
| 39 | + }, | |
| 40 | + breakpoint: { | |
| 41 | + type: String, | |
| 42 | + default: 'md', | |
| 43 | + validator (val) { | |
| 44 | + return oneOf(val, ['xs', 'sm', 'md', 'lg', 'xl']); | |
| 45 | + } | |
| 46 | + }, | |
| 47 | + collapsible: { | |
| 48 | + type: Boolean, | |
| 49 | + default: false | |
| 50 | + }, | |
| 51 | + defaultCollapsed: { | |
| 52 | + type: Boolean, | |
| 53 | + default: false | |
| 54 | + }, | |
| 55 | + reverseArrow: { | |
| 56 | + type: Boolean, | |
| 57 | + default: false | |
| 58 | + } | |
| 59 | + }, | |
| 60 | + data () { | |
| 61 | + return { | |
| 62 | + prefixCls: prefixCls, | |
| 63 | + mediaMatched: false, | |
| 64 | + isCollapsed: false | |
| 65 | + }; | |
| 66 | + }, | |
| 67 | + computed: { | |
| 68 | + wrapClasses () { | |
| 69 | + return [ | |
| 70 | + `${prefixCls}`, | |
| 71 | + this.siderWidth ? '' : `${prefixCls}-zero-width`, | |
| 72 | + this.isCollapsed ? `${prefixCls}-collapsed` : '' | |
| 73 | + ]; | |
| 74 | + }, | |
| 75 | + wrapStyles () { | |
| 76 | + return { | |
| 77 | + width: `${this.siderWidth}px`, | |
| 78 | + minWidth: `${this.siderWidth}px`, | |
| 79 | + maxWidth: `${this.siderWidth}px`, | |
| 80 | + flex: `0 0 ${this.siderWidth}px` | |
| 81 | + }; | |
| 82 | + }, | |
| 83 | + triggerClasses () { | |
| 84 | + return [ | |
| 85 | + `${prefixCls}-trigger`, | |
| 86 | + this.isCollapsed ? `${prefixCls}-trigger-collapsed` : '', | |
| 87 | + ]; | |
| 88 | + }, | |
| 89 | + childClasses () { | |
| 90 | + return `${this.prefixCls}-children`; | |
| 91 | + }, | |
| 92 | + zeroWidthTriggerClasses () { | |
| 93 | + return [ | |
| 94 | + `${prefixCls}-zero-width-trigger`, | |
| 95 | + this.reverseArrow ? `${prefixCls}-zero-width-trigger-left` : '' | |
| 96 | + ]; | |
| 97 | + }, | |
| 98 | + triggerIconClasses () { | |
| 99 | + return [ | |
| 100 | + 'ivu-icon', | |
| 101 | + `ivu-icon-chevron-${this.reverseArrow ? 'right' : 'left'}`, | |
| 102 | + `${prefixCls}-trigger-icon`, | |
| 103 | + ]; | |
| 104 | + }, | |
| 105 | + siderWidth () { | |
| 106 | + return this.collapsible ? (this.isCollapsed ? (this.mediaMatched ? 0 : parseInt(this.collapsedWidth)) : parseInt(this.width)) : this.width; | |
| 107 | + }, | |
| 108 | + showZeroTrigger () { | |
| 109 | + return this.collapsible ? (this.mediaMatched && !this.hideTrigger || (parseInt(this.collapsedWidth) === 0) && this.isCollapsed && !this.hideTrigger) : false; | |
| 110 | + }, | |
| 111 | + showBottomTrigger () { | |
| 112 | + return this.collapsible ? !this.mediaMatched && !this.hideTrigger : false; | |
| 113 | + } | |
| 114 | + }, | |
| 115 | + methods: { | |
| 116 | + toggleCollapse () { | |
| 117 | + this.isCollapsed = this.collapsible ? !this.isCollapsed : false; | |
| 118 | + this.$emit('input', !this.isCollapsed); | |
| 119 | + this.$emit('on-collapse', !this.isCollapsed); | |
| 120 | + }, | |
| 121 | + matchMedia () { | |
| 122 | + let matchMedia; | |
| 123 | + if (window.matchMedia) { | |
| 124 | + matchMedia = window.matchMedia; | |
| 125 | + } | |
| 126 | + let mediaMatched = this.mediaMatched; | |
| 127 | + this.mediaMatched = matchMedia(`(max-width: ${dimensionMap[this.breakpoint]})`).matches; | |
| 128 | + | |
| 129 | + if (this.mediaMatched !== mediaMatched) { | |
| 130 | + this.isCollapsed = this.collapsible ? this.mediaMatched : false; | |
| 131 | + this.$emit('input', this.mediaMatched); | |
| 132 | + this.$emit('on-collapse', this.mediaMatched); | |
| 133 | + } | |
| 134 | + }, | |
| 135 | + onWindowResize () { | |
| 136 | + this.matchMedia(); | |
| 137 | + } | |
| 138 | + }, | |
| 139 | + mounted () { | |
| 140 | + on(window, 'resize', this.onWindowResize); | |
| 141 | + this.matchMedia(); | |
| 142 | + this.$emit('input', this.defaultCollapsed); | |
| 143 | + if (this.defaultCollapsed) { | |
| 144 | + this.isCollapsed = true; | |
| 145 | + } | |
| 146 | + }, | |
| 147 | + destroyed () { | |
| 148 | + off(window, 'resize', this.onWindowResize); | |
| 149 | + } | |
| 150 | + }; | |
| 151 | +</script> | |
| 0 | 152 | \ No newline at end of file | ... | ... |
src/index.js
| ... | ... | @@ -17,13 +17,17 @@ import Checkbox from './components/checkbox'; |
| 17 | 17 | import Circle from './components/circle'; |
| 18 | 18 | import Collapse from './components/collapse'; |
| 19 | 19 | import ColorPicker from './components/color-picker'; |
| 20 | +import Content from './components/content'; | |
| 20 | 21 | import DatePicker from './components/date-picker'; |
| 21 | 22 | import Dropdown from './components/dropdown'; |
| 23 | +import Footer from './components/footer'; | |
| 22 | 24 | import Form from './components/form'; |
| 25 | +import Header from './components/header'; | |
| 23 | 26 | import Icon from './components/icon'; |
| 24 | 27 | import Input from './components/input'; |
| 25 | 28 | import InputNumber from './components/input-number'; |
| 26 | 29 | import Scroll from './components/scroll'; |
| 30 | +import Layout from './components/layout'; | |
| 27 | 31 | import LoadingBar from './components/loading-bar'; |
| 28 | 32 | import Menu from './components/menu'; |
| 29 | 33 | import Message from './components/message'; |
| ... | ... | @@ -34,6 +38,7 @@ import Poptip from './components/poptip'; |
| 34 | 38 | import Progress from './components/progress'; |
| 35 | 39 | import Radio from './components/radio'; |
| 36 | 40 | import Rate from './components/rate'; |
| 41 | +import Sider from './components/sider'; | |
| 37 | 42 | import Slider from './components/slider'; |
| 38 | 43 | import Spin from './components/spin'; |
| 39 | 44 | import Steps from './components/steps'; |
| ... | ... | @@ -71,21 +76,26 @@ const components = { |
| 71 | 76 | Col, |
| 72 | 77 | Collapse, |
| 73 | 78 | ColorPicker, |
| 79 | + Content: Content, | |
| 74 | 80 | DatePicker, |
| 75 | 81 | Dropdown, |
| 76 | 82 | DropdownItem: Dropdown.Item, |
| 77 | 83 | DropdownMenu: Dropdown.Menu, |
| 84 | + Footer: Footer, | |
| 78 | 85 | Form, |
| 79 | 86 | FormItem: Form.Item, |
| 87 | + Header: Header, | |
| 80 | 88 | Icon, |
| 81 | 89 | Input, |
| 82 | 90 | InputNumber, |
| 83 | 91 | Scroll, |
| 92 | + Sider: Sider, | |
| 93 | + Submenu: Menu.Sub, | |
| 94 | + Layout: Layout, | |
| 84 | 95 | LoadingBar, |
| 85 | 96 | Menu, |
| 86 | 97 | MenuGroup: Menu.Group, |
| 87 | 98 | MenuItem: Menu.Item, |
| 88 | - Submenu: Menu.Sub, | |
| 89 | 99 | Message, |
| 90 | 100 | Modal, |
| 91 | 101 | Notice, |
| ... | ... | @@ -122,7 +132,10 @@ const iview = { |
| 122 | 132 | iButton: Button, |
| 123 | 133 | iCircle: Circle, |
| 124 | 134 | iCol: Col, |
| 135 | + iContent: Content, | |
| 125 | 136 | iForm: Form, |
| 137 | + iFooter: Footer, | |
| 138 | + iHeader: Header, | |
| 126 | 139 | iInput: Input, |
| 127 | 140 | iMenu: Menu, |
| 128 | 141 | iOption: Option, | ... | ... |
src/styles/components/index.less
| 1 | +@layout-prefix-cls: ~"@{css-prefix}layout"; | |
| 2 | + | |
| 3 | +.@{layout-prefix-cls} { | |
| 4 | + display: flex; | |
| 5 | + flex-direction: column; | |
| 6 | + flex: auto; | |
| 7 | + background: @layout-body-background; | |
| 8 | + | |
| 9 | + &&-has-sider { | |
| 10 | + flex-direction: row; | |
| 11 | + > .@{layout-prefix-cls}, | |
| 12 | + > .@{layout-prefix-cls}-content { | |
| 13 | + overflow-x: hidden; | |
| 14 | + } | |
| 15 | + } | |
| 16 | + | |
| 17 | + &-header, | |
| 18 | + &-footer { | |
| 19 | + flex: 0 0 auto; | |
| 20 | + } | |
| 21 | + | |
| 22 | + &-header { | |
| 23 | + background: @layout-header-background; | |
| 24 | + padding: @layout-header-padding; | |
| 25 | + height: @layout-header-height; | |
| 26 | + line-height: @layout-header-height; | |
| 27 | + } | |
| 28 | + | |
| 29 | + &-sider { | |
| 30 | + transition: all .2s @ease-in-out; | |
| 31 | + position: relative; | |
| 32 | + background: @layout-sider-background; | |
| 33 | + | |
| 34 | + min-width: 0; | |
| 35 | + | |
| 36 | + &-children { | |
| 37 | + height: 100%; | |
| 38 | + padding-top: 0.1px; | |
| 39 | + margin-top: -0.1px; | |
| 40 | + } | |
| 41 | + | |
| 42 | + &-has-trigger { | |
| 43 | + padding-bottom: @layout-trigger-height; | |
| 44 | + } | |
| 45 | + | |
| 46 | + &-trigger { | |
| 47 | + position: fixed; | |
| 48 | + bottom: 0; | |
| 49 | + text-align: center; | |
| 50 | + cursor: pointer; | |
| 51 | + height: @layout-trigger-height; | |
| 52 | + line-height: @layout-trigger-height; | |
| 53 | + color: @layout-trigger-color; | |
| 54 | + background: @layout-sider-background; | |
| 55 | + z-index: 1000; | |
| 56 | + transition: all .2s @ease-in-out; | |
| 57 | + .ivu-icon { | |
| 58 | + font-size: 16px; | |
| 59 | + } | |
| 60 | + >* { | |
| 61 | + transition: all .2s; | |
| 62 | + } | |
| 63 | + &-collapsed { | |
| 64 | + .@{layout-prefix-cls}-sider-trigger-icon { | |
| 65 | + transform: rotateZ(180deg); | |
| 66 | + } | |
| 67 | + } | |
| 68 | + } | |
| 69 | + | |
| 70 | + &-zero-width { | |
| 71 | + & > * { | |
| 72 | + overflow: hidden; | |
| 73 | + } | |
| 74 | + | |
| 75 | + &-trigger { | |
| 76 | + position: absolute; | |
| 77 | + top: @layout-header-height; | |
| 78 | + right: -@layout-zero-trigger-width; | |
| 79 | + text-align: center; | |
| 80 | + width: @layout-zero-trigger-width; | |
| 81 | + height: @layout-zero-trigger-height; | |
| 82 | + line-height: @layout-zero-trigger-height; | |
| 83 | + background: @layout-sider-background; | |
| 84 | + color: #fff; | |
| 85 | + font-size: @layout-zero-trigger-width / 2; | |
| 86 | + border-radius: 0 @border-radius-base @border-radius-base 0; | |
| 87 | + cursor: pointer; | |
| 88 | + transition: background .3s ease; | |
| 89 | + | |
| 90 | + &:hover { | |
| 91 | + background: tint(@layout-sider-background, 10%); | |
| 92 | + } | |
| 93 | + | |
| 94 | + &&-left { | |
| 95 | + right: 0; | |
| 96 | + left: -@layout-zero-trigger-width; | |
| 97 | + border-radius: @border-radius-base 0 0 @border-radius-base; | |
| 98 | + } | |
| 99 | + } | |
| 100 | + } | |
| 101 | + } | |
| 102 | + | |
| 103 | + &-footer { | |
| 104 | + background: @layout-footer-background; | |
| 105 | + padding: @layout-footer-padding; | |
| 106 | + color: @text-color; | |
| 107 | + font-size: @font-size-base; | |
| 108 | + } | |
| 109 | + | |
| 110 | + &-content { | |
| 111 | + flex: auto; | |
| 112 | + } | |
| 113 | +} | |
| 0 | 114 | \ No newline at end of file | ... | ... |
src/styles/custom.less
| ... | ... | @@ -89,8 +89,19 @@ |
| 89 | 89 | @btn-circle-size-small : 24px; |
| 90 | 90 | |
| 91 | 91 | // Layout and Grid |
| 92 | -@grid-columns : 24; | |
| 93 | -@grid-gutter-width : 0; | |
| 92 | +@grid-columns : 24; | |
| 93 | +@grid-gutter-width : 0; | |
| 94 | +@layout-body-background : #f5f7f9; | |
| 95 | +@layout-header-background : #495060; | |
| 96 | +@layout-header-height : 64px; | |
| 97 | +@layout-header-padding : 0 50px; | |
| 98 | +@layout-footer-padding : 24px 50px; | |
| 99 | +@layout-footer-background : @layout-body-background; | |
| 100 | +@layout-sider-background : @layout-header-background; | |
| 101 | +@layout-trigger-height : 48px; | |
| 102 | +@layout-trigger-color : #fff; | |
| 103 | +@layout-zero-trigger-width : 36px; | |
| 104 | +@layout-zero-trigger-height : 42px; | |
| 94 | 105 | |
| 95 | 106 | // Legend |
| 96 | 107 | @legend-color : #999; | ... | ... |
src/utils/assist.js
| ... | ... | @@ -278,3 +278,25 @@ export function removeClass(el, cls) { |
| 278 | 278 | el.className = trim(curClass); |
| 279 | 279 | } |
| 280 | 280 | } |
| 281 | + | |
| 282 | +export const dimensionMap = { | |
| 283 | + xs: '480px', | |
| 284 | + sm: '768px', | |
| 285 | + md: '992px', | |
| 286 | + lg: '1200px', | |
| 287 | + xl: '1600px', | |
| 288 | +}; | |
| 289 | + | |
| 290 | +export function setMatchMedia () { | |
| 291 | + if (typeof window !== 'undefined') { | |
| 292 | + const matchMediaPolyfill = mediaQuery => { | |
| 293 | + return { | |
| 294 | + media: mediaQuery, | |
| 295 | + matches: false, | |
| 296 | + on() {}, | |
| 297 | + off() {}, | |
| 298 | + }; | |
| 299 | + }; | |
| 300 | + window.matchMedia = window.matchMedia || matchMediaPolyfill; | |
| 301 | + } | |
| 302 | +} | |
| 281 | 303 | \ No newline at end of file | ... | ... |