Skip to content

Commit

Permalink
Fix [Clockpicker, Timepicker]: Vue Compat: deprecation INSTANCE_ATTRS…
Browse files Browse the repository at this point in the history
…_CLASS_STYLE (#16) (#210)

* feat(lib): mix CompatFallthroughMixin in TimepickerMixin

- `TimepickerMixin` mixes in `CompatFallthroughMixin`, because both
  hosts `Clockpicker` and `Timepicker` provide fallthrough behavior.

* feat(lib): add compat fallthrough to Clockpicker

- `Clockpicker` introduces a new prop `compat-fallthrough`, which
  determines if the `class`, `style`, and `id` attributes are applied to
  the root `<div>` element or the underlying `BInput` component. Since
  Vue 3 changed the fallthrough behavior, `Clockpicker` became
  incompatible with that of Buefy for Vue 2. The default value of this
  prop is configured by the `defaultCompatFallthrough` config option,
  which is `true` by default (compatible with Buefy for Vue 2).

* test(lib): test compat-fallthrough prop of Clockpicker

- Tests the fallthrough behavior of `Clockpicker`

* feat(lib): add compat fallthrough to Timepicker

- `Timepicker` introduces a new prop `compat-fallthrough`, which
  determines if the `class`, `style`, and `id` attributes are applied to
  the root `<div>` element or the underlying `BInput` component. Since
  Vue 3 changed the fallthrough behavior, `Timepicker` became
  incompatible with that of Buefy for Vue 2. The default value for this
  prop is configured by the `defaultCompatFallthrough` config option,
  which is `true` by default (compatible with Buefy for Vue 2).

* test(lib): test fallthrough behavior of Timepicker

- Tests the fallthrough behavior of `Timepicker`

* chore(docs): explain compat-fallthrough of Clockpicker

* chore(docs): explain compat-fallthrough of Timepicker

* docs(CHANGELOG): explain compat-fallthrough of Clockpicker and Timepicker
  • Loading branch information
kikuomax authored Mar 31, 2024
1 parent 3cfc599 commit dc56cc1
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 11 deletions.
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

* `Clockpicker`:

TBD
If `compat-fallthrough` is `true`, the attributes fall through to the root `<div>` element, otherwise to the underlying `<b-input>`.

* `Datepicker`:

Expand Down Expand Up @@ -59,7 +59,7 @@

* `Timepicker`:

TBD
If `compat-fallthrough` is `true`, the attributes fall through to the root `<div>` element, otherwise to the underlying `<b-input>`.

* `Upload`:

Expand Down
53 changes: 53 additions & 0 deletions packages/buefy-next/src/components/clockpicker/Clockpicker.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,4 +103,57 @@ describe('BClockpicker', () => {
expect(wrapper.vm.meridienSelected).toBe(wrapper.vm.AM)
expect(wrapper.vm.onMeridienChange).toHaveBeenCalledWith(wrapper.vm.AM)
})

describe('with fallthrough behavior', () => {
const attrs = {
class: 'fallthrough-class',
style: 'font-size: 2rem;',
id: 'fallthrough-id'
}

it('should bind class, style, and id to the root div if compatFallthrough is true (default)', async () => {
const wrapper = shallowMount(BClockpicker, {
attrs,
global: {
stubs: {
'b-dropdown': false
}
}
})

const root = wrapper.find('div.b-clockpicker')
expect(root.classes(attrs.class)).toBe(true)
expect(root.attributes('style')).toBe(attrs.style)
expect(root.attributes('id')).toBe(attrs.id)

const input = wrapper.findComponent({ ref: 'input' })
expect(input.classes(attrs.class)).toBe(false)
expect(input.attributes('style')).toBeUndefined()
expect(input.attributes('id')).toBeUndefined()
})

it('should bind class, style, and id to the underlying input if compatFallthrough is false', async () => {
const wrapper = shallowMount(BClockpicker, {
attrs,
props: {
compatFallthrough: false
},
global: {
stubs: {
'b-dropdown': false
}
}
})

const root = wrapper.find('div.b-clockpicker')
expect(root.classes(attrs.class)).toBe(false)
expect(root.attributes('style')).toBeUndefined()
expect(root.attributes('id')).toBeUndefined()

const input = wrapper.findComponent({ ref: 'input' })
expect(input.classes(attrs.class)).toBe(true)
expect(input.attributes('style')).toBe(attrs.style)
expect(input.attributes('id')).toBe(attrs.id)
})
})
})
10 changes: 7 additions & 3 deletions packages/buefy-next/src/components/clockpicker/Clockpicker.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
<template>
<div class="b-clockpicker control" :class="[size, type, {'is-expanded': expanded}]">
<div
class="b-clockpicker control"
:class="[size, type, {'is-expanded': expanded}]"
v-bind="rootAttrs"
>
<b-dropdown
v-if="!isMobile || inline"
ref="dropdown"
Expand All @@ -25,7 +29,7 @@
:disabled="disabledOrUndefined"
:readonly="!editable"
:rounded="rounded"
v-bind="$attrs"
v-bind="fallthroughAttrs"
:use-html5-validation="useHtml5Validation"
@click="onInputClick"
@keyup.enter="toggle(true)"
Expand Down Expand Up @@ -152,7 +156,7 @@
:min="formatHHMMSS(minTime)"
:disabled="disabledOrUndefined"
:readonly="false"
v-bind="$attrs"
v-bind="fallthroughAttrs"
:use-html5-validation="useHtml5Validation"
@click.stop="toggle(true)"
@keyup.enter="toggle(true)"
Expand Down
53 changes: 53 additions & 0 deletions packages/buefy-next/src/components/timepicker/Timepicker.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,57 @@ describe('BTimepicker', () => {
expect(wrapper.find('option[value="11"]').attributes().disabled).toBe('')
expect(wrapper.find('option[value="12"]').attributes().disabled).toBeUndefined()
})

describe('with compat fallthrough', () => {
const attrs = {
class: 'fallthrough-class',
style: 'font-size: 2rem;',
id: 'fallthrough-id'
}

it('should bind class, style, and id to the root div if compatFallthrough is true (default)', async () => {
const wrapper = shallowMount(BTimepicker, {
attrs,
global: {
stubs: {
'b-dropdown': false
}
}
})

const root = wrapper.find('div.timepicker')
expect(root.classes(attrs.class)).toBe(true)
expect(root.attributes('style')).toBe(attrs.style)
expect(root.attributes('id')).toBe(attrs.id)

const input = wrapper.findComponent({ ref: 'input' })
expect(input.classes(attrs.class)).toBe(false)
expect(input.attributes('style')).toBeUndefined()
expect(input.attributes('id')).toBeUndefined()
})

it('should bind class, style, and id to the underlying input if compatFallthrough is false', async () => {
const wrapper = shallowMount(BTimepicker, {
attrs,
props: {
compatFallthrough: false
},
global: {
stubs: {
'b-dropdown': false
}
}
})

const root = wrapper.find('div.timepicker')
expect(root.classes(attrs.class)).toBe(false)
expect(root.attributes('style')).toBeUndefined()
expect(root.attributes('id')).toBeUndefined()

const input = wrapper.findComponent({ ref: 'input' })
expect(input.classes(attrs.class)).toBe(true)
expect(input.attributes('style')).toBe(attrs.style)
expect(input.attributes('id')).toBe(attrs.id)
})
})
})
11 changes: 7 additions & 4 deletions packages/buefy-next/src/components/timepicker/Timepicker.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
<template>
<div class="timepicker control" :class="[size, {'is-expanded': expanded}]">
<div
class="timepicker control"
:class="[size, {'is-expanded': expanded}]"
v-bind="rootAttrs"
>
<b-dropdown
v-if="!isMobile || inline"
ref="dropdown"
Expand All @@ -25,7 +29,7 @@
:disabled="disabledOrUndefined"
:readonly="!editable || undefined"
:rounded="rounded"
v-bind="$attrs"
v-bind="fallthroughAttrs"
:use-html5-validation="useHtml5Validation"
@keyup.enter="toggle(true)"
@change="onChange($event.target.value)"
Expand Down Expand Up @@ -132,7 +136,7 @@
:min="formatHHMMSS(minTime)"
:disabled="disabledOrUndefined"
:readonly="false"
v-bind="$attrs"
v-bind="fallthroughAttrs"
:use-html5-validation="useHtml5Validation"
@change="onChange($event.target.value)"
@focus="handleOnFocus"
Expand Down Expand Up @@ -161,7 +165,6 @@ export default {
[DropdownItem.name]: DropdownItem
},
mixins: [TimepickerMixin],
inheritAttrs: false,
data() {
return {
_isTimepicker: true
Expand Down
4 changes: 2 additions & 2 deletions packages/buefy-next/src/utils/TimepickerMixin.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import CompatFallthroughMixin from './CompatFallthroughMixin'
import FormElementMixin from './FormElementMixin'
import { isMobile, matchWithGroups } from './helpers'
import config from './config'
Expand Down Expand Up @@ -93,8 +94,7 @@ const defaultTimeParser = (timeString, vm) => {
}

export default {
mixins: [FormElementMixin],
inheritAttrs: false,
mixins: [CompatFallthroughMixin, FormElementMixin],
props: {
modelValue: Date,
inline: Boolean,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,13 @@ export default [
values: '—',
default: '<code>undefined</code>: default to browser locale.'
},
{
name: '<code>compat-fallthrough</code>',
description: 'Whether <code>class</code>, <code>style</code>, and <code>id</code> attributes are applied to the root &lt;div&gt; element or the underlying input component. If <code>true</code>, they are applied to the root &lt;div&gt; element, which is compatible with Vue 2.',
type: 'Boolean',
values: '-',
default: '<code>true</code>. Can be changed via <code>defaultCompatFallthrough</code> config option.'
},
{
name: 'Any native attribute',
description: '—',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,13 @@ export default [
values: '—',
default: '<code>false</code>'
},
{
name: '<code>compat-fallthrough</code>',
description: 'Whether <code>class</code>, <code>style</code>, and <code>id</code> attributes are applied to the root &lt;div&gt; element or the underlying input component. If <code>true</code>, they are applied to the root &lt;div&gt; element, which is compatible with Vue 2.',
type: 'Boolean',
values: '-',
default: '<code>true</code>. Can be changed via <code>defaultCompatFallthrough</code> config option.'
},
{
name: 'Any native attribute',
description: '—',
Expand Down

0 comments on commit dc56cc1

Please sign in to comment.