1 0
import './VGrid.sass'
2

3 0
import Vue, { PropOptions } from 'vue'
4 0
import mergeData from '../../util/mergeData'
5 0
import { upperFirst } from '../../util/helpers'
6

7
// no xs
8 0
const breakpoints = ['sm', 'md', 'lg', 'xl']
9

10 0
const ALIGNMENT = ['start', 'end', 'center']
11

12 0
function makeProps (prefix: string, def: () => PropOptions) {
13 0
  return breakpoints.reduce((props, val) => {
14 0
    props[prefix + upperFirst(val)] = def()
15 0
    return props
16
  }, {} as Dictionary<PropOptions>)
17
}
18

19 0
const alignValidator = (str: any) => [...ALIGNMENT, 'baseline', 'stretch'].includes(str)
20 0
const alignProps = makeProps('align', () => ({
21
  type: String,
22
  default: null,
23
  validator: alignValidator,
24
}))
25

26 0
const justifyValidator = (str: any) => [...ALIGNMENT, 'space-between', 'space-around'].includes(str)
27 0
const justifyProps = makeProps('justify', () => ({
28
  type: String,
29
  default: null,
30
  validator: justifyValidator,
31
}))
32

33 0
const alignContentValidator = (str: any) => [...ALIGNMENT, 'space-between', 'space-around', 'stretch'].includes(str)
34 0
const alignContentProps = makeProps('alignContent', () => ({
35
  type: String,
36
  default: null,
37
  validator: alignContentValidator,
38
}))
39

40 0
const propMap = {
41
  align: Object.keys(alignProps),
42
  justify: Object.keys(justifyProps),
43
  alignContent: Object.keys(alignContentProps),
44
}
45

46 0
const classMap = {
47
  align: 'align',
48
  justify: 'justify',
49
  alignContent: 'align-content',
50
}
51

52 0
function breakpointClass (type: keyof typeof propMap, prop: string, val: string) {
53 0
  let className = classMap[type]
54 1
  if (val == null) {
55 0
    return undefined
56
  }
57 1
  if (prop) {
58
    // alignSm -> Sm
59 0
    const breakpoint = prop.replace(type, '')
60 0
    className += `-${breakpoint}`
61
  }
62
  // .align-items-sm-center
63 0
  className += `-${val}`
64 0
  return className.toLowerCase()
65
}
66

67 0
const cache = new Map<string, any[]>()
68

69 0
export default Vue.extend({
70
  name: 'v-row',
71
  functional: true,
72
  props: {
73
    tag: {
74
      type: String,
75
      default: 'div',
76
    },
77
    dense: Boolean,
78
    noGutters: Boolean,
79
    align: {
80
      type: String,
81
      default: null,
82
      validator: alignValidator,
83
    },
84
    ...alignProps,
85
    justify: {
86
      type: String,
87
      default: null,
88
      validator: justifyValidator,
89
    },
90
    ...justifyProps,
91
    alignContent: {
92
      type: String,
93
      default: null,
94
      validator: alignContentValidator,
95
    },
96
    ...alignContentProps,
97
  },
98 0
  render (h, { props, data, children }) {
99
    // Super-fast memoization based on props, 5x faster than JSON.stringify
100 0
    let cacheKey = ''
101 0
    for (const prop in props) {
102 0
      cacheKey += String((props as any)[prop])
103
    }
104 0
    let classList = cache.get(cacheKey)
105

106 1
    if (!classList) {
107 0
      classList = []
108
      // Loop through `align`, `justify`, `alignContent` breakpoint props
109
      let type: keyof typeof propMap
110 0
      for (type in propMap) {
111 0
        propMap[type].forEach(prop => {
112 0
          const value: string = (props as any)[prop]
113 0
          const className = breakpointClass(type, prop, value)
114 1
          if (className) classList!.push(className)
115
        })
116
      }
117

118 0
      classList.push({
119
        'no-gutters': props.noGutters,
120
        'row--dense': props.dense,
121
        [`align-${props.align}`]: props.align,
122
        [`justify-${props.justify}`]: props.justify,
123
        [`align-content-${props.alignContent}`]: props.alignContent,
124
      })
125

126 0
      cache.set(cacheKey, classList)
127
    }
128

129 0
    return h(
130
      props.tag,
131
      mergeData(data, {
132
        staticClass: 'row',
133
        class: classList,
134
      }),
135
      children
136
    )
137
  },
138
})

Read our documentation on viewing source code .

Loading