diff --git a/packages/docs/src/lang/en-US/framework/Grid.json b/packages/docs/src/lang/en-US/framework/Grid.json
index faa966d5f32..b502d865f8d 100644
--- a/packages/docs/src/lang/en-US/framework/Grid.json
+++ b/packages/docs/src/lang/en-US/framework/Grid.json
@@ -6,7 +6,7 @@
],
"examples": {
"usage": {
- "desc": "The `v-container` can be used for a center focused page, or given the `fluid` prop to extend its full width. `v-layout` is used for separating sections and contains the `v-flex`. The structure of your layout will be as follows, **v-container** » **v-layout** » **v-flex**. Each part of the grid chain is a flex-box element. The final, `v-flex`, automatically sets its children to have flex: 1 1 auto.",
+ "desc": "The `v-container` can be used for a center focused page, or given the `fluid` prop to extend its full width. `v-layout` is used for separating sections and contains the `v-flex`. The structure of your layout will be as follows, **v-container** » **v-layout** » **v-flex**. Each part of the grid chain is a flex-box element. The final, `v-flex`, automatically sets its children to have flex: 1 1 auto.
For convenience reasons, these components automatically transform attributes into classes. Allowing you to write `` instead of ``. The only exception are [data attributes](https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes) which are left as-is.",
"uninverted": true
},
"playground": {
diff --git a/packages/vuetify/src/components/VGrid/grid.js b/packages/vuetify/src/components/VGrid/grid.js
index 051385dc2d7..a0ce939d521 100644
--- a/packages/vuetify/src/components/VGrid/grid.js
+++ b/packages/vuetify/src/components/VGrid/grid.js
@@ -16,18 +16,28 @@ export default function Grid (name) {
render: (h, { props, data, children }) => {
data.staticClass = (`${name} ${data.staticClass || ''}`).trim()
- if (data.attrs) {
- const classes = Object.keys(data.attrs).filter(key => {
+ const { attrs } = data
+ if (attrs) {
+ // reset attrs to extract utility clases like pa-3
+ data.attrs = {}
+ const classes = Object.keys(attrs).filter(key => {
// TODO: Remove once resolved
// https://github.com/vuejs/vue/issues/7841
if (key === 'slot') return false
- const value = data.attrs[key]
+ const value = attrs[key]
+
+ // add back data attributes like data-test="foo" but do not
+ // add them as classes
+ if (key.startsWith('data-')) {
+ data.attrs[key] = value
+ return false
+ }
+
return value || typeof value === 'string'
})
if (classes.length) data.staticClass += ` ${classes.join(' ')}`
- delete data.attrs
}
if (props.id) {
diff --git a/packages/vuetify/test/unit/components/VGrid/VGrid.spec.js b/packages/vuetify/test/unit/components/VGrid/VGrid.spec.js
index 6e8e664248b..8ddde970953 100644
--- a/packages/vuetify/test/unit/components/VGrid/VGrid.spec.js
+++ b/packages/vuetify/test/unit/components/VGrid/VGrid.spec.js
@@ -26,6 +26,22 @@ test('VFlex', ({ mount, functionalContext }) => {
expect(wrapper.find('#test')).toHaveLength(1)
})
+ it('should not pass data-* attrs as classes', () => {
+ const wrapper = mount(
+ VFlex,
+ functionalContext({
+ attrs: {
+ foo: 'bar',
+ 'data-test': 'foo'
+ }
+ })
+ )
+
+ expect(wrapper.hasClass('foo')).toBe(true)
+ expect(wrapper.hasClass('data-test')).toBe(false)
+ expect(wrapper.getAttribute('data-test')).toBe('foo')
+ })
+
// TODO: Remove once resolved
// https://github.com/vuejs/vue/issues/7841
it('should filter the slot attr', () => {