@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
@@ -1,41 +1,29 @@
1
1
  <template>
2
- <VueDatepicker
3
- :value="value"
4
- :name="name"
5
- :id="id"
6
- :format="format"
7
- :language="language"
8
- :open-date="openDate"
9
- :day-cell-content="dayCellContent"
10
- :full-month-name="fullMonthName"
11
- :disabled-dates="disabledDates"
12
- :highlighted="highlighted"
2
+ <VueDatePicker
3
+ :model-value="computedValue"
4
+ :formats="computedFormats"
5
+ :locale="computedLocale"
6
+ :start-date="openDate"
7
+ :disabled-dates="computedDisabledDates"
8
+ :highlight="computedHighlight"
13
9
  :placeholder="placeholder"
14
10
  :inline="inline"
15
- :calendar-class="computedCalendarClass"
16
- :input-class="inputClass"
17
- :wrapper-class="wrapperClass"
18
- :monday-first="mondayFirst"
19
- :clear-button="clearButton"
20
- :clear-button-icon="clearButtonIcon"
21
- :calendar-button="calendarButton"
22
- :calendar-button-icon="calendarButtonIcon"
23
- :calendar-button-icon-content="calendarButtonIconContent"
24
- :initial-view="initialView"
11
+ :input-attrs="computedInputAttrs"
12
+ :ui="computedUi"
13
+ :class="computedWrapperClass"
14
+ :week-start="mondayFirst ? 1 : undefined"
15
+ :auto-apply="true"
16
+ :enable-time-picker="false"
17
+ :time-config="{ enableTimePicker: false }"
25
18
  :disabled="disabled"
26
- :required="required"
27
- :typeable="typeable"
28
- :use-utc="useUtc"
29
- :minimum-view="minimumView"
30
- :maximum-view="maximumView"
31
- v-on="$listeners">
32
- <slot name="beforeCalendarHeader" slot="beforeCalendarHeader" />
33
- <slot name="afterDateInput" slot="afterDateInput" />
34
- </VueDatepicker>
19
+ :text-input="typeable"
20
+ v-bind="$attrs"
21
+ @update:model-value="handleUpdate" />
35
22
  </template>
36
23
 
37
24
  <script>
38
- import VueDatepicker from 'vuejs-datepicker'
25
+ import { VueDatePicker } from '@vuepic/vue-datepicker'
26
+ import '@vuepic/vue-datepicker/dist/main.css'
39
27
 
40
28
  // Validator function that checks the date props.
41
29
  const _datePropValidator = (v) => {
@@ -45,13 +33,64 @@ const _datePropValidator = (v) => {
45
33
  || typeof v === 'number'
46
34
  }
47
35
 
36
+ const _normalizeClass = (value) => {
37
+ if (!value) {
38
+ return []
39
+ }
40
+
41
+ if (typeof value === 'string') {
42
+ return value.split(/\s+/).filter(Boolean)
43
+ }
44
+
45
+ if (Array.isArray(value)) {
46
+ return value.flatMap(_normalizeClass)
47
+ }
48
+
49
+ if (typeof value === 'object') {
50
+ return Object.keys(value).filter(key => value[key])
51
+ }
52
+
53
+ return []
54
+ }
55
+
56
+ const _mergeClasses = (...values) => {
57
+ return [...new Set(values.flatMap(_normalizeClass))]
58
+ }
59
+
60
+ const _normalizeDate = (value) => {
61
+ if (value === null || typeof value === 'undefined') {
62
+ return null
63
+ }
64
+
65
+ const date = value instanceof Date ? value : new Date(value)
66
+
67
+ return Number.isNaN(date.getTime()) ? null : date
68
+ }
69
+
70
+ const _isSameDay = (left, right) => {
71
+ return left.getFullYear() === right.getFullYear()
72
+ && left.getMonth() === right.getMonth()
73
+ && left.getDate() === right.getDate()
74
+ }
75
+
76
+ const _isInRange = (value, range) => {
77
+ const from = _normalizeDate(range && range.from)
78
+ const to = _normalizeDate(range && range.to)
79
+
80
+ return Boolean(from && to && value >= from && value <= to)
81
+ }
82
+
48
83
  export default {
49
84
  name: 'd-datepicker',
50
- components: { VueDatepicker },
85
+ components: { VueDatePicker },
86
+ emits: ['update:modelValue', 'input'],
51
87
  props: {
52
88
  /**
53
89
  * The datepicker's value.
54
90
  */
91
+ modelValue: {
92
+ validator: v => typeof v === 'undefined' || _datePropValidator(v)
93
+ },
55
94
  value: {
56
95
  validator: _datePropValidator
57
96
  },
@@ -192,13 +231,143 @@ export default {
192
231
  small: {
193
232
  type: Boolean,
194
233
  default: false
234
+ },
235
+ /**
236
+ * Advanced UI class configuration passed to @vuepic/vue-datepicker.
237
+ */
238
+ ui: {
239
+ type: Object,
240
+ default: () => ({})
241
+ },
242
+ /**
243
+ * Advanced input attributes passed to @vuepic/vue-datepicker.
244
+ */
245
+ inputAttrs: {
246
+ type: Object,
247
+ default: () => ({})
195
248
  }
196
249
  },
197
250
  computed: {
198
- computedCalendarClass() {
199
- let _calendarClass = this.small ? 'vdp-datepicker__small' : ''
251
+ computedValue() {
252
+ return this.modelValue !== undefined ? this.modelValue : this.value
253
+ },
254
+ computedLocale() {
255
+ if (typeof this.language === 'string') {
256
+ return this.language
257
+ }
258
+
259
+ return this.language && (this.language.language || this.language.lang || this.language.id)
260
+ },
261
+ computedFormats() {
262
+ return {
263
+ input: this.format,
264
+ month: this.fullMonthName ? 'MMMM' : 'LLL'
265
+ }
266
+ },
267
+ computedDisabledDates() {
268
+ if (!this.disabledDates || Array.isArray(this.disabledDates) || typeof this.disabledDates === 'function') {
269
+ return this.disabledDates
270
+ }
271
+
272
+ const disabledDates = this.disabledDates
273
+ const to = _normalizeDate(disabledDates.to)
274
+ const from = _normalizeDate(disabledDates.from)
275
+ const dates = Array.isArray(disabledDates.dates)
276
+ ? disabledDates.dates.map(_normalizeDate).filter(Boolean)
277
+ : []
278
+ const ranges = Array.isArray(disabledDates.ranges) ? disabledDates.ranges : []
279
+
280
+ return (date) => {
281
+ const value = _normalizeDate(date)
200
282
 
201
- return _calendarClass += this.calendarClass
283
+ if (!value) {
284
+ return false
285
+ }
286
+
287
+ return Boolean(
288
+ (to && value <= to)
289
+ || (from && value >= from)
290
+ || (Array.isArray(disabledDates.days) && disabledDates.days.includes(value.getDay()))
291
+ || (Array.isArray(disabledDates.daysOfMonth) && disabledDates.daysOfMonth.includes(value.getDate()))
292
+ || dates.some(disabledDate => _isSameDay(value, disabledDate))
293
+ || ranges.some(range => _isInRange(value, range))
294
+ || (disabledDates.customPredictor && disabledDates.customPredictor(value))
295
+ )
296
+ }
297
+ },
298
+ computedHighlight() {
299
+ if (!this.highlighted || typeof this.highlighted === 'function') {
300
+ return this.highlighted
301
+ }
302
+
303
+ const highlighted = this.highlighted
304
+ const from = _normalizeDate(highlighted.from)
305
+ const to = _normalizeDate(highlighted.to)
306
+ const dates = Array.isArray(highlighted.dates)
307
+ ? highlighted.dates.map(_normalizeDate).filter(Boolean)
308
+ : []
309
+
310
+ const hasRange = Boolean(from && to)
311
+
312
+ if (!hasRange && !dates.length && !highlighted.customPredictor) {
313
+ return highlighted
314
+ }
315
+
316
+ return (date) => {
317
+ const value = _normalizeDate(date)
318
+
319
+ if (!value) {
320
+ return false
321
+ }
322
+
323
+ if (hasRange) {
324
+ return value >= from && value <= to
325
+ }
326
+
327
+ if (dates.some(highlightedDate => _isSameDay(value, highlightedDate))) {
328
+ return true
329
+ }
330
+
331
+ return highlighted.customPredictor ? highlighted.customPredictor(value) : false
332
+ }
333
+ },
334
+ computedWrapperClass() {
335
+ return [
336
+ 'vdp-datepicker',
337
+ this.wrapperClass
338
+ ]
339
+ },
340
+ computedInputAttrs() {
341
+ return {
342
+ ...this.inputAttrs,
343
+ name: this.name || this.inputAttrs.name,
344
+ id: this.id || this.inputAttrs.id,
345
+ required: this.required || Boolean(this.inputAttrs.required),
346
+ clearable: this.clearButton,
347
+ hideInputIcon: !this.calendarButton
348
+ }
349
+ },
350
+ computedUi() {
351
+ return {
352
+ ...this.ui,
353
+ input: _mergeClasses('vdp-datepicker__input', this.inputClass, this.ui.input),
354
+ menu: _mergeClasses(
355
+ 'vdp-datepicker__calendar',
356
+ this.small ? 'vdp-datepicker__small' : '',
357
+ this.calendarClass,
358
+ this.ui.menu
359
+ ),
360
+ calendar: _mergeClasses('vdp-datepicker__calendar-grid', this.ui.calendar),
361
+ calendarCell: _mergeClasses('vdp-datepicker__cell', this.ui.calendarCell),
362
+ navBtnPrev: _mergeClasses('vdp-datepicker__nav-button', this.ui.navBtnPrev),
363
+ navBtnNext: _mergeClasses('vdp-datepicker__nav-button', this.ui.navBtnNext)
364
+ }
365
+ }
366
+ },
367
+ methods: {
368
+ handleUpdate(value) {
369
+ this.$emit('update:modelValue', value)
370
+ this.$emit('input', value)
202
371
  }
203
372
  }
204
373
  }
@@ -253,6 +422,43 @@ export default {
253
422
  $datepicker-small-day-header-font-size: 100%;
254
423
 
255
424
  div.vdp-datepicker {
425
+ --dp-font-family: #{$font-system};
426
+ --dp-font-size: #{$datepicker-font-size};
427
+ --dp-border-radius: #{$datepicker-border-radius};
428
+ --dp-cell-border-radius: #{$datepicker-border-radius};
429
+ --dp-cell-size: #{$datepicker-cell-width};
430
+ --dp-primary-color: #{$color-primary};
431
+ --dp-primary-text-color: #{$white};
432
+ --dp-background-color: #{$datepicker-background-color};
433
+ --dp-text-color: #{$datepicker-color};
434
+ --dp-hover-color: #{$datepicker-cell-hover-color};
435
+ --dp-hover-text-color: #{$datepicker-color};
436
+ --dp-hover-icon-color: #{$datepicker-color};
437
+ --dp-icon-color: #{$color-silver-sand};
438
+ --dp-border-color: rgba(0, 0, 0, .15);
439
+ --dp-menu-border-color: rgba(0, 0, 0, .15);
440
+ --dp-border-color-hover: #{$color-silver-sand};
441
+ --dp-border-color-focus: #{$color-primary};
442
+ --dp-highlight-color: #{$color-primary};
443
+ --dp-range-between-dates-background-color: #{$color-primary};
444
+ --dp-range-between-dates-text-color: #{$white};
445
+ --dp-range-between-border-color: #{$color-primary};
446
+ --dp-input-padding: .4375rem .75rem;
447
+ --dp-input-icon-padding: 2.25rem;
448
+ --dp-menu-padding: 0;
449
+ --dp-menu-min-width: #{$datepicker-min-width};
450
+
451
+ display: inline-block;
452
+ width: 100%;
453
+
454
+ .dp--input-wrap {
455
+ width: 100%;
456
+ }
457
+
458
+ .vdp-datepicker__input.dp--input {
459
+ background-color: $white;
460
+ }
461
+
256
462
  &__calendar {
257
463
  color: $datepicker-color;
258
464
  padding: $datepicker-padding-y $datepicker-padding-x;
@@ -266,6 +472,84 @@ export default {
266
472
  box-shadow: $datepicker-drop-shadows;
267
473
  border: 1px solid rgba($black,.15) !important;
268
474
 
475
+ .dp--menu-inner {
476
+ padding: 0;
477
+ }
478
+
479
+ .dp--month-year-row {
480
+ padding-bottom: 10px;
481
+ }
482
+
483
+ .dp--calendar-header {
484
+ font-weight: 500;
485
+ }
486
+
487
+ .dp--calendar-header-separator {
488
+ display: none;
489
+ }
490
+
491
+ .dp--month-year-select-base,
492
+ .dp--inner-nav,
493
+ .dp--cell-inner {
494
+ transition: $transition-default;
495
+ border-radius: $border-radius-default;
496
+ }
497
+
498
+ .dp--inner-nav {
499
+ color: $color-silver-sand;
500
+ }
501
+
502
+ .dp--month-year-select-base {
503
+ font-weight: 500;
504
+ }
505
+
506
+ .dp--calendar-header-item,
507
+ .dp--cell-inner {
508
+ width: $datepicker-cell-width;
509
+ height: $datepicker-cell-height;
510
+ padding: 0;
511
+ font-size: $datepicker-cell-font-size;
512
+ }
513
+
514
+ .dp--cell-inner {
515
+ line-height: $datepicker-cell-line-height;
516
+ border-color: $border-color;
517
+ }
518
+
519
+ .dp--calendar-row {
520
+ margin: 0;
521
+ }
522
+
523
+ .dp--date-hoverable:hover,
524
+ .dp--month-year-select-base:hover,
525
+ .dp--inner-nav:hover {
526
+ background-color: $datepicker-cell-hover-color;
527
+ border-color: $border-color !important;
528
+ }
529
+
530
+ .dp--active,
531
+ .dp--range-border-start,
532
+ .dp--range-border-end,
533
+ .dp--cell-highlight,
534
+ .dp--cell-highlight-active {
535
+ background: $color-primary !important;
536
+ color: $white;
537
+ }
538
+
539
+ .dp--active:hover,
540
+ .dp--cell-highlight:hover,
541
+ .dp--cell-highlight-active:hover {
542
+ background: color.adjust($color-primary, $lightness: -5%) !important;
543
+ border-color: $border-color !important;
544
+ }
545
+
546
+ .dp--range-between {
547
+ background: $color-primary;
548
+ border-color: $color-primary;
549
+ color: $white;
550
+ border-radius: 0;
551
+ }
552
+
269
553
  // Header
270
554
  header {
271
555
  display: flex;
@@ -363,10 +647,26 @@ export default {
363
647
 
364
648
  // Small Datepicker modifier.
365
649
  &__small {
650
+ --dp-font-size: #{$datepicker-small-font-size};
651
+ --dp-cell-size: #{$datepicker-small-day-width};
652
+
366
653
  padding: $datepicker-small-padding-y $datepicker-small-padding-x;
367
654
  font-size: $datepicker-small-font-size;
368
655
  max-width: $datepicker-small-max-width;
369
656
 
657
+ .dp--calendar-header-item,
658
+ .dp--cell-inner {
659
+ width: $datepicker-small-day-width;
660
+ height: $datepicker-small-day-height;
661
+ line-height: $datepicker-small-day-line-height;
662
+ font-size: $datepicker-small-day-font-size;
663
+ font-weight: $datepicker-small-day-font-weight;
664
+ }
665
+
666
+ .dp--calendar-header-item {
667
+ font-size: $datepicker-small-day-header-font-size;
668
+ }
669
+
370
670
  .cell {
371
671
  &.day {
372
672
  width: $datepicker-small-day-width;
@@ -388,4 +688,3 @@ export default {
388
688
  }
389
689
  }
390
690
  </style>
391
-
@@ -1,6 +1,6 @@
1
1
  # Datepickers
2
2
 
3
- Datepickers in Shards Vue are wrappers over the `vuejs-datepicker` component. You can learn more about the component in [the official component's GitHub repository](https://github.com/charliekassel/vuejs-datepicker), or follow the short guide below for an overview of how to use datepickers in Shards Vue.
3
+ Datepickers in Shards Vue are wrappers over the `@vuepic/vue-datepicker` component. You can learn more about the component in [the official documentation](https://vue3datepicker.com/), or follow the short guide below for an overview of how to use datepickers in Shards Vue.
4
4
 
5
5
  ## Basic Example
6
6
 
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <component :is="computedTag" :id="computedID"
3
- v-on-clickaway="away"
3
+ v-click-away="away"
4
4
  :class="[
5
5
  'dropdown',
6
6
  'd-dropdown',
@@ -64,19 +64,18 @@ import Popper from 'popper.js'
64
64
  import { guid, closest } from '../../utils'
65
65
  import { THEMECOLORS, DROPDOWN_EVENTS, KEYCODES, LINK_EVENTS } from '../../utils/constants'
66
66
  import { CancelableEvent } from '../../utils/events'
67
- import { mixin as clickAwayMixin } from 'vue-clickaway';
67
+ import clickAway from '../../directives/click-away'
68
68
  import rootListenerMixin from '../../mixins/root-listener.mixin'
69
69
 
70
70
  export default {
71
71
  name: 'd-dropdown',
72
- mixins: [
73
- rootListenerMixin,
74
- clickAwayMixin
75
- ],
72
+ directives: { clickAway },
73
+ mixins: [rootListenerMixin],
74
+ emits: ['show', 'shown', 'hide', 'hidden', 'toggle', 'click'],
76
75
  data() {
77
76
  return {
78
77
  visible: false,
79
- isNavbar: null,
78
+ inNavbar: null,
80
79
  visibleChangePrevented: false
81
80
  }
82
81
  },
@@ -378,8 +377,8 @@ export default {
378
377
  )
379
378
  },
380
379
  removePopper() {
381
- if (this._popper) {
382
- this._popper.destroy()
380
+ if (this._popperInstance) {
381
+ this._popperInstance.destroy()
383
382
  }
384
383
  this._popperInstance = null
385
384
  },
@@ -428,7 +427,7 @@ export default {
428
427
  this.visible = false
429
428
  this.removePopper()
430
429
  },
431
- beforeDestroy() {
430
+ beforeUnmount() {
432
431
  this.visible = false
433
432
  this.removePopper()
434
433
  }
@@ -32,13 +32,10 @@ import { guid } from '../../utils'
32
32
 
33
33
  export default {
34
34
  name: 'd-form-checkbox',
35
- model: {
36
- prop: 'checked',
37
- event: 'input'
38
- },
35
+ emits: ['update:modelValue', 'update:checked', 'update:indeterminate', 'input', 'change'],
39
36
  data() {
40
37
  return {
41
- localState: this.checked
38
+ localState: this.modelValue !== undefined ? this.modelValue : this.checked
42
39
  }
43
40
  },
44
41
  props: {
@@ -83,6 +80,10 @@ export default {
83
80
  /**
84
81
  * The checked state.
85
82
  */
83
+ modelValue: {
84
+ type: [Boolean, String, Array],
85
+ default: undefined
86
+ },
86
87
  checked: {
87
88
  type: [Boolean, String, Array]
88
89
  },
@@ -122,6 +123,49 @@ export default {
122
123
  default: false
123
124
  }
124
125
  },
126
+ watch: {
127
+ computedChecked(newVal, oldVal) {
128
+ if (newVal == oldVal) {
129
+ return
130
+ }
131
+
132
+ this.computedLocalState = newVal
133
+ },
134
+
135
+ computedLocalState(newVal, oldVal) {
136
+ if (newVal == oldVal) {
137
+ return
138
+ }
139
+
140
+ this.$emit('update:modelValue', newVal)
141
+ this.$emit('update:checked', newVal)
142
+ this.$emit('input', newVal)
143
+ if (this.$refs.check) {
144
+ this.$emit('update:indeterminate', this.$refs.check.indeterminate)
145
+ }
146
+ },
147
+
148
+ indeterminate(newVal) {
149
+ this.setIndeterminate(newVal)
150
+ }
151
+ },
152
+
153
+ methods: {
154
+ handleChange(e) {
155
+ this.$emit('change', e.target.checked ? this.value : this.uncheckedValue)
156
+ this.$emit('update:indeterminate', this.$refs.check.indeterminate)
157
+ },
158
+
159
+ setIndeterminate(state) {
160
+ if (!this.$refs.check) {
161
+ return
162
+ }
163
+
164
+ this.$refs.check.indeterminate = state
165
+ this.$emit('update:indeterminate', this.$refs.check.indeterminate)
166
+ }
167
+ },
168
+
125
169
  computed: {
126
170
  computedLocalState: {
127
171
  get() {
@@ -132,6 +176,9 @@ export default {
132
176
  this.localState = val
133
177
  }
134
178
  },
179
+ computedChecked() {
180
+ return this.modelValue !== undefined ? this.modelValue : this.checked
181
+ },
135
182
  computedID() {
136
183
  return this.id || `dr-checkbox-${guid()}`
137
184
  },
@@ -158,40 +205,6 @@ export default {
158
205
  return null
159
206
  }
160
207
  },
161
- watch: {
162
- computedLocalState(newVal, oldVal) {
163
- if (newVal == oldVal) {
164
- return
165
- }
166
-
167
- this.$emit('input', newVal)
168
- this.$emit('update:indeterminate', this.$refs.check.indeterminate)
169
- },
170
-
171
- checked(newVal, oldVal) {
172
- if (newVal == oldVal) {
173
- return
174
- }
175
-
176
- this.computedLocalState = newVal
177
- },
178
-
179
- indeterminate(newVal) {
180
- this.setIndeterminate(newVal)
181
- }
182
- },
183
-
184
- methods: {
185
- handleChange(e) {
186
- this.$emit('change', e.target.checked ? this.value : this.uncheckedValue)
187
- this.$emit('update:indeterminate', this.$refs.check.indeterminate)
188
- },
189
-
190
- setIndeterminate(state) {
191
- this.$refs.check.indeterminate = state
192
- this.$emit('update:indeterminate', this.$refs.check.indeterminate)
193
- }
194
- },
195
208
 
196
209
  mounted() {
197
210
  this.setIndeterminate(this.indeterminate)
@@ -10,7 +10,7 @@
10
10
  :autocomplete="autocomplete"
11
11
  :aria-required="required ? true : null"
12
12
  :aria-invalid="computedAriaInvalid"
13
- :value="value"
13
+ :value="inputValue"
14
14
  :class="[
15
15
  plaintext ? 'form-control-plaintext' : 'form-control',
16
16
  plaintext ? 'w-100' : '',
@@ -28,6 +28,7 @@ import { INPUT_TYPES } from './../../utils/constants'
28
28
 
29
29
  export default {
30
30
  name: 'd-form-input',
31
+ emits: ['update:modelValue', 'input', 'change'],
31
32
  props: {
32
33
  /**
33
34
  * Input type.
@@ -40,6 +41,10 @@ export default {
40
41
  /**
41
42
  * Input value.
42
43
  */
44
+ modelValue: {
45
+ type: [String, Number],
46
+ default: undefined
47
+ },
43
48
  value: {
44
49
  type: [String, Number],
45
50
  default: ''
@@ -116,16 +121,19 @@ export default {
116
121
  }
117
122
  },
118
123
  watch: {
119
- value (newVal) {
124
+ inputValue (newVal) {
120
125
  this.setValue(newVal)
121
126
  }
122
127
  },
123
128
  mounted() {
124
- if (this.value) {
125
- this.setValue(this.value)
129
+ if (this.inputValue) {
130
+ this.setValue(this.inputValue)
126
131
  }
127
132
  },
128
133
  computed: {
134
+ inputValue() {
135
+ return this.modelValue !== undefined ? this.modelValue : this.value
136
+ },
129
137
  computedID() {
130
138
  return `dr-input-${guid()}`
131
139
  },
@@ -162,6 +170,7 @@ export default {
162
170
  methods: {
163
171
  setValue(value) {
164
172
  this.$refs.input.value = value
173
+ this.$emit('update:modelValue', value)
165
174
  this.$emit('input', value)
166
175
  },
167
176
  onInput(e) {