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', () => {