@gorse/shards-vue 1.0.8 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/README.md +8 -5
  2. package/build/optimize.js +27 -15
  3. package/build/rollup.config.js +28 -38
  4. package/dist/shards-vue.common.js +3639 -6083
  5. package/dist/shards-vue.common.js.map +1 -1
  6. package/dist/shards-vue.common.min.js +27 -1
  7. package/dist/shards-vue.common.min.map +1 -1
  8. package/dist/shards-vue.esm.js +3637 -6081
  9. package/dist/shards-vue.esm.js.map +1 -1
  10. package/dist/shards-vue.esm.min.js +27 -1
  11. package/dist/shards-vue.esm.min.map +1 -1
  12. package/dist/shards-vue.umd.js +3641 -6086
  13. package/dist/shards-vue.umd.js.map +1 -1
  14. package/dist/shards-vue.umd.min.js +27 -1
  15. package/dist/shards-vue.umd.min.map +1 -1
  16. package/package.json +24 -25
  17. package/sandbox/Sandbox.vue +1 -17
  18. package/sandbox/index.html +12 -0
  19. package/sandbox/main.js +7 -0
  20. package/sandbox/vite.config.js +6 -0
  21. package/src/components/alert/Alert.vue +20 -11
  22. package/src/components/button/Button.vue +1 -0
  23. package/src/components/button/ButtonClose.vue +1 -0
  24. package/src/components/collapse/Collapse.vue +17 -9
  25. package/src/components/datepicker/Datepicker.vue +335 -36
  26. package/src/components/datepicker/README.md +1 -1
  27. package/src/components/dropdown/Dropdown.vue +9 -10
  28. package/src/components/form-checkbox/FormCheckbox.vue +52 -39
  29. package/src/components/form-input/FormInput.vue +13 -4
  30. package/src/components/form-radio/FormRadio.vue +15 -9
  31. package/src/components/form-select/FormSelect.vue +11 -2
  32. package/src/components/form-textarea/FormTextarea.vue +50 -22
  33. package/src/components/input-group/README.md +24 -12
  34. package/src/components/link/Link.vue +4 -8
  35. package/src/components/modal/Modal.vue +6 -4
  36. package/src/components/modal/README.md +2 -2
  37. package/src/components/navbar/NavbarToggle.vue +1 -1
  38. package/src/components/navbar/README.md +5 -3
  39. package/src/components/popover/Popover.vue +3 -2
  40. package/src/components/popover/README.md +3 -3
  41. package/src/components/slider/Slider.vue +13 -4
  42. package/src/components/tabs/Tab.vue +19 -2
  43. package/src/components/tabs/Tabs.vue +42 -6
  44. package/src/components/tabs/_TabButton.vue +1 -0
  45. package/src/components/tooltip/Tooltip.vue +3 -1
  46. package/src/directives/click-away.js +39 -0
  47. package/src/directives/toggle/toggle.js +12 -7
  48. package/src/directives/tooltip/tooltip.js +6 -11
  49. package/src/index.js +8 -6
  50. package/src/markdown/getting-started/README.md +6 -4
  51. package/src/mixins/checkbox-radio.mixin.js +5 -6
  52. package/src/mixins/root-listener.mixin.js +12 -6
  53. package/src/mixins/tooltip-popover.mixin.js +1 -1
  54. package/src/utils/events.js +66 -0
  55. package/src/utils/index.js +20 -18
  56. package/src/utils/target.js +23 -9
@@ -29,13 +29,10 @@ import { guid } from '../../utils'
29
29
 
30
30
  export default {
31
31
  name: 'd-form-radio',
32
- model: {
33
- prop: 'checked',
34
- event: 'input'
35
- },
32
+ emits: ['update:modelValue', 'update:checked', 'input', 'change'],
36
33
  data() {
37
34
  return {
38
- localChecked: this.checked
35
+ localChecked: this.modelValue !== undefined ? this.modelValue : this.checked
39
36
  }
40
37
  },
41
38
  props: {
@@ -74,6 +71,10 @@ export default {
74
71
  /**
75
72
  * The checked state.
76
73
  */
74
+ modelValue: {
75
+ type: [Boolean, String, Array],
76
+ default: undefined
77
+ },
77
78
  checked: {
78
79
  type: [Boolean, String, Array]
79
80
  },
@@ -102,6 +103,9 @@ export default {
102
103
  this.localChecked = val
103
104
  }
104
105
  },
106
+ computedChecked() {
107
+ return this.modelValue !== undefined ? this.modelValue : this.checked
108
+ },
105
109
  computedID() {
106
110
  return this.id || `dr-radio-${guid()}`
107
111
  },
@@ -129,20 +133,22 @@ export default {
129
133
  }
130
134
  },
131
135
  watch: {
132
- computedLocalChecked(newVal, oldVal) {
136
+ computedChecked(newVal, oldVal) {
133
137
  if (newVal == oldVal) {
134
138
  return
135
139
  }
136
140
 
137
- this.$emit('input', newVal)
141
+ this.computedLocalChecked = newVal
138
142
  },
139
143
 
140
- checked(newVal, oldVal) {
144
+ computedLocalChecked(newVal, oldVal) {
141
145
  if (newVal == oldVal) {
142
146
  return
143
147
  }
144
148
 
145
- this.computedLocalChecked = newVal
149
+ this.$emit('update:modelValue', newVal)
150
+ this.$emit('update:checked', newVal)
151
+ this.$emit('input', newVal)
146
152
  },
147
153
  },
148
154
 
@@ -31,6 +31,7 @@ import { guid } from '../../utils'
31
31
 
32
32
  export default {
33
33
  name: 'd-form-select',
34
+ emits: ['update:modelValue', 'input', 'change'],
34
35
  props: {
35
36
  /**
36
37
  * The element ID.
@@ -57,6 +58,9 @@ export default {
57
58
  /**
58
59
  * The select value.
59
60
  */
61
+ modelValue: {
62
+ default: undefined
63
+ },
60
64
  value: {},
61
65
  /**
62
66
  * Whether it should allow multiple selections, or not.
@@ -133,19 +137,24 @@ export default {
133
137
  },
134
138
  data() {
135
139
  return {
136
- localValue: this.value
140
+ localValue: this.computedValue
137
141
  }
138
142
  },
139
143
  watch: {
140
- value(newVal) {
144
+ computedValue(newVal) {
141
145
  this.localValue = newVal
142
146
  },
143
147
 
144
148
  localValue() {
149
+ this.$emit('update:modelValue', this.localValue)
145
150
  this.$emit('input', this.localValue)
146
151
  }
147
152
  },
148
153
  computed: {
154
+ computedValue() {
155
+ return this.modelValue !== undefined ? this.modelValue : this.value
156
+ },
157
+
149
158
  computedID() {
150
159
  return this.id || `dr-select-${guid()}`
151
160
  },
@@ -19,6 +19,7 @@
19
19
  :wrap="wrap"
20
20
  :aria-required="required ? 'true' : null"
21
21
  :aria-invalid="computedAriaInvalid"
22
+ :value="localValue"
22
23
  @input="handleInput"
23
24
  ></textarea>
24
25
  </template>
@@ -28,12 +29,27 @@ import { guid, getComputedStyles, isVisible } from "../../utils";
28
29
 
29
30
  export default {
30
31
  name: "d-form-textarea",
32
+ emits: ["update:modelValue", "input"],
31
33
  data() {
32
34
  return {
33
- localValue: this.value
35
+ localValue: this.modelValue !== undefined ? this.modelValue : this.value
34
36
  };
35
37
  },
36
38
  props: {
39
+ /**
40
+ * The textarea value.
41
+ */
42
+ modelValue: {
43
+ type: [String, Number],
44
+ default: undefined
45
+ },
46
+ /**
47
+ * The textarea value.
48
+ */
49
+ value: {
50
+ type: [String, Number],
51
+ default: ""
52
+ },
37
53
  /**
38
54
  * The element name.
39
55
  */
@@ -106,6 +122,13 @@ export default {
106
122
  type: Boolean,
107
123
  default: false
108
124
  },
125
+ /**
126
+ * The textarea `aria-invalid` attribute.
127
+ */
128
+ ariaInvalid: {
129
+ type: [Boolean, String],
130
+ default: false
131
+ },
109
132
  /**
110
133
  * The number of text rows.
111
134
  */
@@ -139,7 +162,23 @@ export default {
139
162
  mounted() {
140
163
  this.el = this.$el;
141
164
  },
165
+ watch: {
166
+ computedValue(newVal, oldVal) {
167
+ if (newVal !== oldVal) {
168
+ this.localValue = newVal;
169
+ }
170
+ },
171
+ localValue(newVal, oldVal) {
172
+ if (newVal !== oldVal) {
173
+ this.$emit("update:modelValue", newVal);
174
+ this.$emit("input", newVal);
175
+ }
176
+ }
177
+ },
142
178
  computed: {
179
+ computedValue() {
180
+ return this.modelValue !== undefined ? this.modelValue : this.value;
181
+ },
143
182
  computedID() {
144
183
  return this.id || `dr-textarea-${guid()}`;
145
184
  },
@@ -154,7 +193,8 @@ export default {
154
193
  return Math.max(parseInt(this.rows, 10) || 2, 2);
155
194
  },
156
195
  computedMaxRows() {
157
- return Math.max(this.computedMinRows, parseInt(this.maxRows, 10) || 0);
196
+ const maxRows = parseInt(this.maxRows, 10);
197
+ return maxRows ? Math.max(this.computedMinRows, maxRows) : null;
158
198
  },
159
199
  computedHeight() {
160
200
  if (this.localValue === null || !isVisible(this.el)) {
@@ -167,10 +207,10 @@ export default {
167
207
  this.el.style.height = "inherit";
168
208
 
169
209
  const computed = getComputedStyles(this.el);
210
+ const lineHeight = parseFloat(computed.lineHeight);
170
211
  const minHeight =
171
212
  parseInt(computed.height, 10) || lineHeight * this.computedMinRows;
172
213
 
173
- const lineHeight = parseFloat(computed.lineHeight);
174
214
  const offset =
175
215
  parseInt(computed.borderTopWidth, 10) +
176
216
  parseInt(computed.paddingTop, 10) +
@@ -180,15 +220,15 @@ export default {
180
220
  // eslint-disable-next-line vue/no-side-effects-in-computed-properties
181
221
  this.el.style.height = _height;
182
222
 
183
- const rows = Math.min(
184
- Math.max(
185
- (this.el.scrollHeight - offset) / lineHeight,
186
- this.computedMinRows
187
- ),
188
- this.computedMaxRows - 1
223
+ const calculatedRows = Math.max(
224
+ (this.el.scrollHeight - offset) / lineHeight,
225
+ this.computedMinRows
189
226
  );
227
+ const rows = this.computedMaxRows
228
+ ? Math.min(calculatedRows, this.computedMaxRows)
229
+ : calculatedRows;
190
230
 
191
- if (!this.localValue.trim()) {
231
+ if (!String(this.localValue || "").trim()) {
192
232
  return `${minHeight}px`;
193
233
  }
194
234
 
@@ -229,18 +269,6 @@ export default {
229
269
  return null;
230
270
  }
231
271
  },
232
- watch: {
233
- value(newVal, oldVal) {
234
- if (newVal !== oldVal) {
235
- this.localValue = newVal;
236
- }
237
- },
238
- localValue(newVal, oldVal) {
239
- if (newVal !== oldVal) {
240
- this.$emit("input", newVal);
241
- }
242
- }
243
- },
244
272
  methods: {
245
273
  handleInput(e) {
246
274
  this.localValue = e.target.value;
@@ -16,7 +16,9 @@ Using the `<d-input-group>` component you can easily extend form controls by add
16
16
  <!-- Using Slots -->
17
17
  <d-input-group class="mb-2">
18
18
  <d-input placeholder="Total Amount"/>
19
- <d-input-group-text slot="append">$</d-input-group-text>
19
+ <template #append>
20
+ <d-input-group-text>$</d-input-group-text>
21
+ </template>
20
22
  </d-input-group>
21
23
 
22
24
  <!-- Using Components -->
@@ -55,9 +57,13 @@ If you'd like better control over your input group's contents, you can also use
55
57
  ```html
56
58
 
57
59
  <d-input-group>
58
- <d-input-group-text slot="prepend">Total Amount</d-input-group-text>
60
+ <template #prepend>
61
+ <d-input-group-text>Total Amount</d-input-group-text>
62
+ </template>
59
63
  <d-input placeholder="Total Amount"/>
60
- <d-input-group-text slot="append">$</d-input-group-text>
64
+ <template #append>
65
+ <d-input-group-text>$</d-input-group-text>
66
+ </template>
61
67
  </d-input-group>
62
68
 
63
69
  <!-- input-group-3.vue -->
@@ -119,18 +125,22 @@ You can also use the `<d-input-group-addon>` component with the `append` or `pre
119
125
  <d-row>
120
126
  <d-col lg="6">
121
127
  <d-input-group>
122
- <d-input-group-text slot="prepend">
123
- <input type="checkbox" aria-label="Checkbox for following text input">
124
- </d-input-group-text>
128
+ <template #prepend>
129
+ <d-input-group-text>
130
+ <input type="checkbox" aria-label="Checkbox for following text input">
131
+ </d-input-group-text>
132
+ </template>
125
133
  <d-form-input type="text" aria-label="Text input with checkbox" />
126
134
  </d-input-group>
127
135
  </d-col>
128
136
 
129
137
  <d-col lg="6">
130
138
  <d-input-group>
131
- <d-input-group-text slot="prepend">
132
- <input type="radio" aria-label="Radio for following text input">
133
- </d-input-group-text>
139
+ <template #prepend>
140
+ <d-input-group-text>
141
+ <input type="radio" aria-label="Radio for following text input">
142
+ </d-input-group-text>
143
+ </template>
134
144
  <d-form-input type="text" aria-label="Text input with radio button" />
135
145
  </d-input-group>
136
146
  </d-col>
@@ -177,9 +187,11 @@ You can create seamless input groups using the `seamless` prop.
177
187
  ```html
178
188
 
179
189
  <d-input-group seamless>
180
- <d-input-group-text slot="prepend">
181
- <fa :icon="['fas', 'dollar-sign']" />
182
- </d-input-group-text>
190
+ <template #prepend>
191
+ <d-input-group-text>
192
+ <fa :icon="['fas', 'dollar-sign']" />
193
+ </d-input-group-text>
194
+ </template>
183
195
  <d-input placeholder="Total Amount"/>
184
196
  </d-input-group>
185
197
 
@@ -11,7 +11,7 @@
11
11
  disabled ? 'disabled' : ''
12
12
  ]"
13
13
  :aria-disabled="computedAriaDisabled"
14
- @click.native="handleClick">
14
+ @click="handleClick">
15
15
  <slot>Link</slot>
16
16
  </component>
17
17
  </template>
@@ -22,6 +22,7 @@ import rootListenerMixin from '../../mixins/root-listener.mixin'
22
22
 
23
23
  export default {
24
24
  name: 'd-link',
25
+ emits: ['click'],
25
26
  mixins: [ rootListenerMixin ],
26
27
  props: {
27
28
  /**
@@ -97,7 +98,7 @@ export default {
97
98
  computedTag() {
98
99
  return this.to
99
100
  && !this.disabled
100
- && Boolean(this.$parent.$router) ? 'router-link' : 'a'
101
+ && Boolean(this.$router) ? 'router-link' : 'a'
101
102
  },
102
103
  computedRel() {
103
104
  return this.target === '_blank'
@@ -139,12 +140,7 @@ export default {
139
140
  event.stopPropagation();
140
141
  event.stopImmediatePropagation();
141
142
  } else {
142
- if (isRouterLink && event.target.__vue__) {
143
- event.target.__vue__.$emit('click', event);
144
- } else {
145
- this.$emit('click', event);
146
- }
147
-
143
+ this.$emit('click', event);
148
144
  this.emitOnRoot(LINK_EVENTS.CLICKED, event);
149
145
  }
150
146
 
@@ -11,7 +11,7 @@
11
11
  centered ? `modal-dialog-centered` : '',
12
12
  ]"
13
13
  role="document"
14
- v-on-clickaway="away">
14
+ v-click-away="away">
15
15
  <div class="modal-content">
16
16
  <slot />
17
17
  </div>
@@ -21,12 +21,14 @@
21
21
  </template>
22
22
 
23
23
  <script>
24
- import { mixin as clickAwayMixin } from 'vue-clickaway';
24
+ import clickAway from '../../directives/click-away'
25
25
  import { MODAL_EVENTS } from '../../utils/constants';
26
+ import { getEventBus } from '../../utils/events';
26
27
 
27
28
  export default {
28
29
  name: 'd-modal',
29
- mixins: [clickAwayMixin],
30
+ directives: { clickAway },
31
+ emits: ['close'],
30
32
  props: {
31
33
  /**
32
34
  * The component tag.
@@ -76,7 +78,7 @@ export default {
76
78
  *
77
79
  * Triggered when the modal is hidden.
78
80
  */
79
- this.$root.$emit(MODAL_EVENTS.HIDDEN)
81
+ getEventBus(this).$emit(MODAL_EVENTS.HIDDEN)
80
82
  }
81
83
  },
82
84
  };
@@ -8,7 +8,7 @@ Creating flexible modal dialogs can be achieved using the `<d-modal>` component.
8
8
  ```html
9
9
  <template>
10
10
  <div>Modal opened: <span :class="[showModal ? 'text-success' : 'text-danger']">{{ showModal }}</span></div>
11
- <d-btn @click.native="handleClick">Click Me</d-btn>
11
+ <d-btn @click="handleClick">Click Me</d-btn>
12
12
  <d-modal v-if="showModal" @close="handleClose">
13
13
  <d-modal-header>
14
14
  <d-modal-title>Header</d-modal-title>
@@ -46,7 +46,7 @@ Using the `size` prop on the `<d-modal>` component, you can control the size of
46
46
  :::demo
47
47
  ```html
48
48
  <template>
49
- <d-btn @click.native="showModal = true">Click Me</d-btn>
49
+ <d-btn @click="showModal = true">Click Me</d-btn>
50
50
  <d-modal v-if="showModal" size="sm" @close="showModal = false" :size="modalSize">
51
51
  <d-modal-header>
52
52
  <d-modal-title>Hello</d-modal-title>
@@ -40,7 +40,7 @@ export default {
40
40
  },
41
41
  methods: {
42
42
  onClick() {
43
- this.$root.$emit(COLLAPSE_EVENTS.TOGGLE, this.target)
43
+ this.emitOnRoot(COLLAPSE_EVENTS.TOGGLE, this.target)
44
44
  },
45
45
  handleStateEvent(id, state) {
46
46
  if (id === this.target) {
@@ -28,9 +28,11 @@ Using the `<d-navbar>` component you can create powerful and responsive navigati
28
28
 
29
29
  <d-navbar-nav class="ml-auto">
30
30
  <d-input-group seamless>
31
- <d-input-group-text slot="prepend">
32
- <fa :icon="['fas', 'search']" />
33
- </d-input-group-text>
31
+ <template #prepend>
32
+ <d-input-group-text>
33
+ <fa :icon="['fas', 'search']" />
34
+ </d-input-group-text>
35
+ </template>
34
36
  <d-input size="sm" placeholder="Search..."/>
35
37
  </d-input-group>
36
38
  </d-navbar-nav>
@@ -13,10 +13,12 @@
13
13
  import Popover from '../../utils/popover.class'
14
14
  import TooltipPopoverMixin from '../../mixins/tooltip-popover.mixin'
15
15
  import { TP_PLACEMENTS } from '../../utils/constants';
16
+ import { getEventBus } from '../../utils/events'
16
17
 
17
18
  export default {
18
19
  name: 'd-popover',
19
20
  mixins: [ TooltipPopoverMixin ],
21
+ emits: ['show', 'shown', 'hide', 'hidden', 'update:show', 'update:disabled', 'enabled', 'disabled'],
20
22
  props: {
21
23
  /**
22
24
  * Title
@@ -114,7 +116,7 @@ export default {
114
116
  this._TPInstance = new Popover(
115
117
  target,
116
118
  this.getUpdatedConfig(),
117
- this.$root
119
+ getEventBus(this)
118
120
  )
119
121
  }
120
122
 
@@ -123,4 +125,3 @@ export default {
123
125
  }
124
126
  }
125
127
  </script>
126
-
@@ -14,7 +14,7 @@ Popovers can be created using the `<d-popover>` component.
14
14
  <div>
15
15
  <d-btn id="popover-example-1">Click Me</d-btn>
16
16
  <d-popover target="popover-example-1" container=".shards-demo--example--popover-01">
17
- <template slot="title">
17
+ <template #title>
18
18
  Title Here
19
19
  </template>
20
20
  Content Here
@@ -37,7 +37,7 @@ The `<d-popover>` component, by default is triggered by the `click` event. Howev
37
37
  <d-popover target="popover-example-2"
38
38
  container=".shards-demo--example--popover-02"
39
39
  :triggers="['hover']">
40
- <template slot="title">
40
+ <template #title>
41
41
  Title Here
42
42
  </template>
43
43
  Content Here
@@ -61,7 +61,7 @@ Using the `placement` prop you can adjust where your popover will be displayed.
61
61
  <d-popover target="popover-example-3"
62
62
  :placement="'rightbottom'"
63
63
  container=".shards-demo--example--popover-03">
64
- <template slot="title">
64
+ <template #title>
65
65
  Title Here
66
66
  </template>
67
67
  Content Here
@@ -8,6 +8,7 @@ import { guid } from '../../utils'
8
8
 
9
9
  export default {
10
10
  name: 'd-slider',
11
+ emits: ['update:modelValue', 'input'],
11
12
  props: {
12
13
  /**
13
14
  * The element ID.
@@ -28,9 +29,13 @@ export default {
28
29
  /**
29
30
  * Slider value.
30
31
  */
32
+ modelValue: {
33
+ type: [String, Array, Number],
34
+ default: undefined
35
+ },
31
36
  value: {
32
37
  type: [String, Array, Number],
33
- required: true
38
+ default: undefined
34
39
  },
35
40
  /**
36
41
  * Start value.
@@ -59,7 +64,7 @@ export default {
59
64
  }
60
65
  },
61
66
  watch: {
62
- value(newVal, oldVal) {
67
+ computedValue(newVal, oldVal) {
63
68
  const sliderInstance = this.$el.noUiSlider
64
69
  const sliderValue = sliderInstance.get()
65
70
 
@@ -78,13 +83,16 @@ export default {
78
83
  }
79
84
  },
80
85
  computed: {
86
+ computedValue() {
87
+ return this.modelValue !== undefined ? this.modelValue : this.value
88
+ },
81
89
  computedID() {
82
90
  return this.id || `dr-slider-${guid()}`
83
91
  }
84
92
  },
85
93
  mounted() {
86
94
  const config = {
87
- start: this.value || this.start,
95
+ start: this.computedValue || this.start,
88
96
  connect: this.connect,
89
97
  range: this.range,
90
98
  ...this.options
@@ -94,7 +102,8 @@ export default {
94
102
 
95
103
  this.$el.noUiSlider.on('slide', () => {
96
104
  const value = this.$el.noUiSlider.get()
97
- if (value !== this.value) {
105
+ if (value !== this.computedValue) {
106
+ this.$emit('update:modelValue', value)
98
107
  this.$emit('input', value)
99
108
  }
100
109
  })
@@ -13,7 +13,7 @@
13
13
  :aria-labelledby="controlledBy || null"
14
14
  :class="[
15
15
  'tab-pane',
16
- ($parent && $parent.card && !noBody) ? 'card-body' : '',
16
+ (tabsParent && tabsParent.card && !noBody) ? 'card-body' : '',
17
17
  show ? 'show' : '',
18
18
  disabled ? 'disabled' : '',
19
19
  localActiveState ? 'active' : ''
@@ -28,6 +28,12 @@ import { guid } from '../../utils';
28
28
 
29
29
  export default {
30
30
  name: 'd-tab',
31
+ emits: ['click'],
32
+ inject: {
33
+ dTabs: {
34
+ default: null
35
+ }
36
+ },
31
37
  data() {
32
38
  return {
33
39
  localActiveState: this.active && !this.disabled,
@@ -93,10 +99,13 @@ export default {
93
99
  return this.buttonId || `dr-tab-button-${guid()}`
94
100
  },
95
101
  computedFade() {
96
- return this.$parent.fade
102
+ return this.tabsParent && this.tabsParent.fade
97
103
  },
98
104
  _isTab() {
99
105
  return true
106
+ },
107
+ tabsParent() {
108
+ return this.dTabs && this.dTabs.parent
100
109
  }
101
110
  },
102
111
  methods: {
@@ -112,6 +121,14 @@ export default {
112
121
  },
113
122
  mounted() {
114
123
  this.show = this.localActiveState
124
+ if (this.dTabs) {
125
+ this.dTabs.registerTab(this)
126
+ }
127
+ },
128
+ beforeUnmount() {
129
+ if (this.dTabs) {
130
+ this.dTabs.unregisterTab(this)
131
+ }
115
132
  }
116
133
  }
117
134
  </script>