From 4993c40ce6c052381e6b9ef4d919bde95cd4ae5b Mon Sep 17 00:00:00 2001 From: MrWook Date: Fri, 21 Aug 2020 15:42:13 +0200 Subject: [PATCH 1/7] refactor(calendar): move calendar in own component --- src/components/Calendar.vue | 357 ++++++++++++++++++++++++++ src/components/DateInput.vue | 5 +- src/components/Datepicker.vue | 464 ++++++---------------------------- src/mixins/calendarProps.vue | 73 ++++++ src/mixins/inputProps.vue | 21 -- src/mixins/sharedProps.vue | 26 ++ src/styles/calendar.scss | 155 ++++++++++++ src/styles/style.scss | 157 ------------ src/utils/calendarSlots.js | 10 + 9 files changed, 702 insertions(+), 566 deletions(-) create mode 100644 src/components/Calendar.vue create mode 100644 src/mixins/calendarProps.vue create mode 100644 src/mixins/sharedProps.vue create mode 100644 src/styles/calendar.scss create mode 100755 src/utils/calendarSlots.js diff --git a/src/components/Calendar.vue b/src/components/Calendar.vue new file mode 100644 index 00000000..252ee774 --- /dev/null +++ b/src/components/Calendar.vue @@ -0,0 +1,357 @@ + + + + diff --git a/src/components/DateInput.vue b/src/components/DateInput.vue index 00b057db..da81e69e 100644 --- a/src/components/DateInput.vue +++ b/src/components/DateInput.vue @@ -4,8 +4,7 @@ @@ -63,11 +62,13 @@ + diff --git a/src/mixins/calendarProps.vue b/src/mixins/calendarProps.vue new file mode 100644 index 00000000..092af836 --- /dev/null +++ b/src/mixins/calendarProps.vue @@ -0,0 +1,73 @@ + diff --git a/src/mixins/inputProps.vue b/src/mixins/inputProps.vue index 64253691..e7062d91 100644 --- a/src/mixins/inputProps.vue +++ b/src/mixins/inputProps.vue @@ -24,19 +24,6 @@ export default ({ type: String, default: '', }, - openDate: { - type: [ - String, - Date, - Number, - ], - default: null, - validator: - (val) => val === null - || val instanceof Date - || typeof val === 'string' - || typeof val === 'number', - }, placeholder: { type: String, default: null, @@ -48,10 +35,6 @@ export default ({ ], default: null, }, - inline: { - type: Boolean, - default: false, - }, inputClass: { type: [ String, @@ -96,10 +79,6 @@ export default ({ type: Boolean, default: false, }, - useUtc: { - type: Boolean, - default: false, - }, showCalendarOnFocus: { type: Boolean, default: false, diff --git a/src/mixins/sharedProps.vue b/src/mixins/sharedProps.vue new file mode 100644 index 00000000..027826a7 --- /dev/null +++ b/src/mixins/sharedProps.vue @@ -0,0 +1,26 @@ + diff --git a/src/styles/calendar.scss b/src/styles/calendar.scss new file mode 100644 index 00000000..42bebcdf --- /dev/null +++ b/src/styles/calendar.scss @@ -0,0 +1,155 @@ +.vdp-datepicker__calendar { + position: absolute; + z-index: 10000; + background: #fff; + width: 300px; + border: 1px solid #ccc; + + header { + display: block; + line-height: 40px; + + span { + display: inline-block; + text-align: center; + width: 71.42857142857143%; + float: left; + } + + .prev, + .next { + max-height: 40px; + width: 14.285714285714286%; + float: left; + position: relative; + + .default { + text-indent: -10000px; + + &:after { + content: ''; + position: absolute; + left: 50%; + top: 50%; + transform: translateX(-50%) translateY(-50%); + border: 6px solid transparent; + } + } + } + + .prev { + .default { + &:after { + border-right: 10px solid #000; + margin-left: -5px; + } + + &.disabled:after { + border-right: 10px solid #ddd; + } + } + } + + .next { + .default { + &:after { + border-left: 10px solid #000; + margin-left: 5px; + } + + &.disabled:after { + border-left: 10px solid #ddd; + } + } + } + + .prev:not(.disabled), + .next:not(.disabled), + .up:not(.disabled) { + cursor: pointer; + + &:hover { + background: #eee; + } + } + } + + .disabled { + color: #ddd; + cursor: default; + } + + .flex-rtl { + display: flex; + width: inherit; + flex-wrap: wrap; + } + + .cell { + display: inline-block; + padding: 0 5px; + width: 14.285714285714286%; + height: 40px; + line-height: 40px; + text-align: center; + vertical-align: middle; + border: 1px solid transparent; + + &:not(.blank):not(.disabled).day, + &:not(.blank):not(.disabled).month, + &:not(.blank):not(.disabled).year { + cursor: pointer; + + &:hover { + border: 1px solid #4bd; + } + } + + &.selected { + background: #4bd; + + &:hover { + background: #4bd; + } + + &.highlighted { + background: #4bd; + } + } + + &.highlighted { + background: #cae5ed; + + &.disabled { + color: #a3a3a3; + } + } + + &.grey { + color: #888; + + &:hover { + background: inherit; + } + } + + &.day-header { + font-size: 75%; + white-space: nowrap; + cursor: inherit; + + &:hover { + background: inherit; + } + } + } + + .month, + .year { + width: 33.333%; + } + + .picker-view { + width: inherit; + } +} diff --git a/src/styles/style.scss b/src/styles/style.scss index 6a8bf7c0..ecc781da 100755 --- a/src/styles/style.scss +++ b/src/styles/style.scss @@ -11,163 +11,6 @@ } } -.vdp-datepicker__calendar { - position: absolute; - z-index: 10000; - background: #fff; - width: 300px; - border: 1px solid #ccc; - - header { - display: block; - line-height: 40px; - - span { - display: inline-block; - text-align: center; - width: 71.42857142857143%; - float: left; - } - - .prev, - .next { - max-height: 40px; - width: 14.285714285714286%; - float: left; - position: relative; - - .default { - text-indent: -10000px; - - &:after { - content: ''; - position: absolute; - left: 50%; - top: 50%; - transform: translateX(-50%) translateY(-50%); - border: 6px solid transparent; - } - } - } - - .prev { - .default { - &:after { - border-right: 10px solid #000; - margin-left: -5px; - } - - &.disabled:after { - border-right: 10px solid #ddd; - } - } - } - - .next { - .default { - &:after { - border-left: 10px solid #000; - margin-left: 5px; - } - - &.disabled:after { - border-left: 10px solid #ddd; - } - } - } - - .prev:not(.disabled), - .next:not(.disabled), - .up:not(.disabled) { - cursor: pointer; - - &:hover { - background: #eee; - } - } - } - - .disabled { - color: #ddd; - cursor: default; - } - - .flex-rtl { - display: flex; - width: inherit; - flex-wrap: wrap; - } - - .cell { - display: inline-block; - padding: 0 5px; - width: 14.285714285714286%; - height: 40px; - line-height: 40px; - text-align: center; - vertical-align: middle; - border: 1px solid transparent; - - &:not(.blank):not(.disabled).day, - &:not(.blank):not(.disabled).month, - &:not(.blank):not(.disabled).year { - cursor: pointer; - - &:hover { - border: 1px solid #4bd; - } - } - - &.selected { - background: #4bd; - - &:hover { - background: #4bd; - } - - &.highlighted { - background: #4bd; - } - } - - &.highlighted { - background: #cae5ed; - - &.disabled { - color: #a3a3a3; - } - } - - &.grey { - color: #888; - - &:hover { - background: inherit; - } - } - - &.day-header { - font-size: 75%; - white-space: nowrap; - cursor: inherit; - - &:hover { - background: inherit; - } - } - } - - .month, - .year { - width: 33.333%; - } - - .picker-view { - width: inherit; - } -} - - .vdp-datepicker__clear-button, .vdp-datepicker__calendar-button { cursor: pointer; diff --git a/src/utils/calendarSlots.js b/src/utils/calendarSlots.js new file mode 100755 index 00000000..0383cf83 --- /dev/null +++ b/src/utils/calendarSlots.js @@ -0,0 +1,10 @@ +export default [ + 'beforeCalendarHeaderDay', + 'calendarFooterDay', + 'beforeCalendarHeaderMonth', + 'calendarFooterMonth', + 'beforeCalendarHeaderYear', + 'calendarFooterYear', + 'nextIntervalBtn', + 'prevIntervalBtn', +] From 51b97909f31b075878bfe7d8ba521f3c83569500 Mon Sep 17 00:00:00 2001 From: MrWook Date: Mon, 31 Aug 2020 15:52:35 +0200 Subject: [PATCH 2/7] feat(calendar): add props to add calendar to body --- docs/guide/Props/README.md | 1 + example/Demo.vue | 21 ++++++- src/components/Calendar.vue | 45 --------------- src/components/Datepicker.vue | 80 +++++++++++++++++--------- src/components/Popup.vue | 82 +++++++++++++++++++++++++++ src/mixins/calendarProps.vue | 11 ---- src/utils/dom.js | 102 ++++++++++++++++++++++++++++++++++ 7 files changed, 258 insertions(+), 84 deletions(-) create mode 100644 src/components/Popup.vue create mode 100644 src/utils/dom.js diff --git a/docs/guide/Props/README.md b/docs/guide/Props/README.md index 4c7031c5..f0e0fe16 100755 --- a/docs/guide/Props/README.md +++ b/docs/guide/Props/README.md @@ -3,6 +3,7 @@ | Prop | Type | Default | Description | | ----------------------------- | -----------------| ----------- | ----------------------------------------------- | +| append-to-body | Boolean | | Append datepicker calendar to body | | autofocus | String | | Sets html `autofocus` attribute on input | | bootstrap-styling | Boolean | false | Use bootstrap v4 styling classes. | | calendar-button | Boolean | false | Show an icon that that can be clicked | diff --git a/example/Demo.vue b/example/Demo.vue index 9d5d4cbd..05b25e03 100755 --- a/example/Demo.vue +++ b/example/Demo.vue @@ -3,7 +3,10 @@

Datepicker Examples

Default datepicker...

- + <datepicker placeholder="Select Date"></datepicker> @@ -37,6 +40,7 @@ <datepicker placeholder="Select Date" v-model="vmodelexample"></datepicker> @@ -45,6 +49,18 @@

{{ vModelExample }}

+
+

Append datepicker to body

+ +

Don't append datepicker to body

+ + + <datepicker :append-to-body="true"></datepicker> + +
+

Format datepicker

@@ -499,4 +515,7 @@ h5 { font-size: 80%; display: block; } +.overflow-scroll{ + overflow:scroll +} diff --git a/src/components/Calendar.vue b/src/components/Calendar.vue index 252ee774..e5410cff 100644 --- a/src/components/Calendar.vue +++ b/src/components/Calendar.vue @@ -149,51 +149,6 @@ export default { */ init() { this.setInitialView() - if (!this.isInline) { - this.setPickerPosition() - } - }, - setPickerPosition() { - this.$nextTick(() => { - const calendar = this.$refs.datepicker - if (calendar) { - if (this.currentPicker) { - const parent = calendar.parentElement - const calendarBounding = calendar.getBoundingClientRect() - const outOfBoundsRight = calendarBounding.right > window.innerWidth - const outOfBoundsBottom = calendarBounding.bottom > window.innerHeight - const parentHeight = `${parent.getBoundingClientRect().height}px` - - if (this.fixedPosition === '') { - if (outOfBoundsRight) { - calendar.style.right = 0 - } else { - calendar.style.right = 'unset' - } - - if (outOfBoundsBottom) { - calendar.style.bottom = parentHeight - } else { - calendar.style.bottom = 'unset' - } - } else { - if (this.fixedPosition.indexOf('right') !== -1) { - calendar.style.right = 0 - } else { - calendar.style.right = 'unset' - } - if (this.fixedPosition.indexOf('top') !== -1) { - calendar.style.bottom = parentHeight - } else { - calendar.style.bottom = 'unset' - } - } - } else { - calendar.style.right = 'unset' - calendar.style.bottom = 'unset' - } - } - }) }, /** * @param {Object} date diff --git a/src/components/Datepicker.vue b/src/components/Datepicker.vue index f28ae35a..17c5696b 100644 --- a/src/components/Datepicker.vue +++ b/src/components/Datepicker.vue @@ -24,38 +24,45 @@ name="afterDateInput" /> - + - - - - + + + +
diff --git a/src/mixins/calendarProps.vue b/src/mixins/calendarProps.vue index 092af836..e8e506a6 100644 --- a/src/mixins/calendarProps.vue +++ b/src/mixins/calendarProps.vue @@ -21,17 +21,6 @@ export default ({ }, }, - fixedPosition: { - type: String, - default: '', - validator: (val) => val === '' - || val === 'bottom' - || val === 'bottom-left' - || val === 'bottom-right' - || val === 'top' - || val === 'top-left' - || val === 'top-right', - }, fullMonthName: { type: Boolean, default: false, diff --git a/src/utils/dom.js b/src/utils/dom.js new file mode 100644 index 00000000..237db871 --- /dev/null +++ b/src/utils/dom.js @@ -0,0 +1,102 @@ +/* eslint no-param-reassign: 0 */ +/** + * get the hidden element width, height + * @param {HTMLElement} element dom + */ +export function getPopupElementSize(element) { + const originalDisplay = element.style.display + const originalVisibility = element.style.visibility + element.style.display = 'block' + element.style.visibility = 'hidden' + const styles = window.getComputedStyle(element) + const width = element.offsetWidth + parseInt(styles.marginLeft, 10) + parseInt( + styles.marginRight, + 10, + ) + const height = element.offsetHeight + parseInt( + styles.marginTop, + 10, + ) + parseInt(styles.marginBottom, 10) + element.style.display = originalDisplay + element.style.visibility = originalVisibility + + return { + width, + height, + } +} + +/** + * get the popup position + * @param {Element} el relative element + * @param {Number} targetWidth target element's width + * @param {Number} targetHeight target element's height + * @param {Boolean} fixed + */ +export function getRelativePosition(el, targetWidth, targetHeight, fixed) { + let left = 0 + let top = 0 + let offsetX = 0 + let offsetY = 0 + const relativeRect = el.getBoundingClientRect() + const dw = document.documentElement.clientWidth + const dh = document.documentElement.clientHeight + if (fixed) { + offsetX = window.pageXOffset + relativeRect.left + offsetY = window.pageYOffset + relativeRect.top + } + if (dw - relativeRect.left < targetWidth && relativeRect.right < targetWidth) { + left = offsetX - relativeRect.left + 1 + } else if (relativeRect.left + relativeRect.width / 2 <= dw / 2) { + left = offsetX + } else { + left = offsetX + relativeRect.width - targetWidth + } + if (relativeRect.top <= targetHeight && dh - relativeRect.bottom <= targetHeight) { + top = offsetY + dh - relativeRect.top - targetHeight + } else if (relativeRect.top + relativeRect.height / 2 <= dh / 2) { + top = offsetY + relativeRect.height + } else { + top = offsetY - targetHeight + } + return { + left: `${left}px`, + top: `${top}px`, + } +} + +export const setPickerPosition = ({ + element, + relativeElement, + fixedPosition, +}) => { + const calendarBounding = element.getBoundingClientRect() + const outOfBoundsRight = calendarBounding.right > window.innerWidth + const outOfBoundsBottom = calendarBounding.bottom > window.innerHeight + const relativeElementHeight = `${relativeElement.getBoundingClientRect().height}px` + + if (fixedPosition === '') { + if (outOfBoundsRight) { + element.style.right = 0 + } else { + element.style.right = 'unset' + } + + if (outOfBoundsBottom) { + element.style.bottom = relativeElementHeight + } else { + element.style.bottom = 'unset' + } + } else { + if (fixedPosition.indexOf('right') !== -1) { + element.style.right = 0 + } else { + element.style.right = 'unset' + } + if (fixedPosition.indexOf('top') !== -1) { + element.style.bottom = relativeElementHeight + } else { + element.style.bottom = 'unset' + } + } +} From 651bd2cc2d744bad39279a50c85dc039ee672f6a Mon Sep 17 00:00:00 2001 From: MrWook Date: Sat, 19 Sep 2020 14:42:39 +0200 Subject: [PATCH 3/7] chore(popup): set fixed position for relativ position --- src/components/Popup.vue | 8 +++++++- src/utils/dom.js | 10 +++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/components/Popup.vue b/src/components/Popup.vue index ed66efc0..a5c29cad 100644 --- a/src/components/Popup.vue +++ b/src/components/Popup.vue @@ -69,7 +69,13 @@ export default { this.popupRect = getPopupElementSize(popup) } const { width, height } = this.popupRect - const { left, top } = getRelativePosition(relativeElement, width, height, this.appendToBody) + const { left, top } = getRelativePosition({ + el: relativeElement, + targetWidth: width, + targetHeight: height, + fixed: this.appendToBody, + fixedPosition: this.fixedPosition, + }) this.$el.style.left = left this.$el.style.top = top diff --git a/src/utils/dom.js b/src/utils/dom.js index 237db871..97127deb 100644 --- a/src/utils/dom.js +++ b/src/utils/dom.js @@ -32,8 +32,16 @@ export function getPopupElementSize(element) { * @param {Number} targetWidth target element's width * @param {Number} targetHeight target element's height * @param {Boolean} fixed + * @param {String} fixedPosition */ -export function getRelativePosition(el, targetWidth, targetHeight, fixed) { +export function getRelativePosition({ + el, + targetWidth, + targetHeight, + fixed, + // eslint-disable-next-line no-unused-vars + fixedPosition, +}) { let left = 0 let top = 0 let offsetX = 0 From 847ddb1fae854c2905c546e4f8e53c0a75bc58b8 Mon Sep 17 00:00:00 2001 From: MrWook Date: Mon, 5 Oct 2020 14:22:39 +0200 Subject: [PATCH 4/7] chore(project): small fine tuning --- docs/guide/Props/README.md | 2 +- example/Demo.vue | 2 +- src/components/Popup.vue | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/guide/Props/README.md b/docs/guide/Props/README.md index f0e0fe16..ab4f6067 100755 --- a/docs/guide/Props/README.md +++ b/docs/guide/Props/README.md @@ -3,7 +3,7 @@ | Prop | Type | Default | Description | | ----------------------------- | -----------------| ----------- | ----------------------------------------------- | -| append-to-body | Boolean | | Append datepicker calendar to body | +| append-to-body | Boolean | false | Append datepicker calendar to body | | autofocus | String | | Sets html `autofocus` attribute on input | | bootstrap-styling | Boolean | false | Use bootstrap v4 styling classes. | | calendar-button | Boolean | false | Show an icon that that can be clicked | diff --git a/example/Demo.vue b/example/Demo.vue index 05b25e03..88ecaf3b 100755 --- a/example/Demo.vue +++ b/example/Demo.vue @@ -515,7 +515,7 @@ h5 { font-size: 80%; display: block; } -.overflow-scroll{ +.overflow-scroll { overflow:scroll } diff --git a/src/components/Popup.vue b/src/components/Popup.vue index a5c29cad..e3a6b25e 100644 --- a/src/components/Popup.vue +++ b/src/components/Popup.vue @@ -2,7 +2,7 @@ import { getPopupElementSize, getRelativePosition, -} from '../utils/dom' +} from '~/utils/dom' export default { name: 'Popup', From 139b71abd3ad43b5a015fbb72dbb2cb891a0666c Mon Sep 17 00:00:00 2001 From: MrWook Date: Wed, 7 Oct 2020 07:46:27 +0200 Subject: [PATCH 5/7] feat(position): make fixedPosition workable again --- src/utils/dom.js | 80 ++++++++++++++++++++++-------------------------- 1 file changed, 37 insertions(+), 43 deletions(-) diff --git a/src/utils/dom.js b/src/utils/dom.js index 97127deb..8eaca418 100644 --- a/src/utils/dom.js +++ b/src/utils/dom.js @@ -47,23 +47,53 @@ export function getRelativePosition({ let offsetX = 0 let offsetY = 0 const relativeRect = el.getBoundingClientRect() - const dw = document.documentElement.clientWidth - const dh = document.documentElement.clientHeight + const documentWidth = document.documentElement.clientWidth + const documentHeight = document.documentElement.clientHeight if (fixed) { offsetX = window.pageXOffset + relativeRect.left offsetY = window.pageYOffset + relativeRect.top } - if (dw - relativeRect.left < targetWidth && relativeRect.right < targetWidth) { + + const fixedPositionLeft = fixedPosition.indexOf('left') !== -1 + const fixedPositionBottom = fixedPosition.indexOf('bottom') !== -1 + const fixedPositionRight = fixedPosition.indexOf('right') !== -1 + const fixedPositionTop = fixedPosition.indexOf('top') !== -1 + + const isLeft = ( + relativeRect.left + relativeRect.width / 2 <= documentWidth / 2 + || fixedPositionLeft + ) && !fixedPositionRight + + const hasRelativWidth = documentWidth - relativeRect.left < targetWidth + && relativeRect.right < targetWidth + && !fixedPositionLeft + && !fixedPositionRight + + if (hasRelativWidth) { left = offsetX - relativeRect.left + 1 - } else if (relativeRect.left + relativeRect.width / 2 <= dw / 2) { + } else if (isLeft) { left = offsetX + // else is right } else { left = offsetX + relativeRect.width - targetWidth } - if (relativeRect.top <= targetHeight && dh - relativeRect.bottom <= targetHeight) { - top = offsetY + dh - relativeRect.top - targetHeight - } else if (relativeRect.top + relativeRect.height / 2 <= dh / 2) { + + const isBottom = ( + relativeRect.top + relativeRect.height / 2 <= documentHeight / 2 + || fixedPositionBottom + ) + && !fixedPositionTop + + const hasRelativHeight = relativeRect.top <= targetHeight + && documentHeight - relativeRect.bottom <= targetHeight + && !fixedPositionBottom + && !fixedPositionTop + + if (hasRelativHeight) { + top = offsetY + documentHeight - relativeRect.top - targetHeight + } else if (isBottom) { top = offsetY + relativeRect.height + // else is top } else { top = offsetY - targetHeight } @@ -72,39 +102,3 @@ export function getRelativePosition({ top: `${top}px`, } } - -export const setPickerPosition = ({ - element, - relativeElement, - fixedPosition, -}) => { - const calendarBounding = element.getBoundingClientRect() - const outOfBoundsRight = calendarBounding.right > window.innerWidth - const outOfBoundsBottom = calendarBounding.bottom > window.innerHeight - const relativeElementHeight = `${relativeElement.getBoundingClientRect().height}px` - - if (fixedPosition === '') { - if (outOfBoundsRight) { - element.style.right = 0 - } else { - element.style.right = 'unset' - } - - if (outOfBoundsBottom) { - element.style.bottom = relativeElementHeight - } else { - element.style.bottom = 'unset' - } - } else { - if (fixedPosition.indexOf('right') !== -1) { - element.style.right = 0 - } else { - element.style.right = 'unset' - } - if (fixedPosition.indexOf('top') !== -1) { - element.style.bottom = relativeElementHeight - } else { - element.style.bottom = 'unset' - } - } -} From 9dfa77b7c60d1e11ae197ac25b36783325fa501c Mon Sep 17 00:00:00 2001 From: MrWook Date: Wed, 7 Oct 2020 08:48:10 +0200 Subject: [PATCH 6/7] fix(position): resolve position on right sided inputs --- src/components/Datepicker.vue | 1 + src/components/Popup.vue | 8 ++- src/utils/dom.js | 91 +++++++++++++++++++++-------------- 3 files changed, 63 insertions(+), 37 deletions(-) diff --git a/src/components/Datepicker.vue b/src/components/Datepicker.vue index 17c5696b..4bdd9ffe 100644 --- a/src/components/Datepicker.vue +++ b/src/components/Datepicker.vue @@ -29,6 +29,7 @@ :visible="isOpen" :inline="inline" :fixed-position="fixedPosition" + :rtl="isRtl" > window.innerWidth + const outOfBoundsBottom = calendarBounding.bottom > window.innerHeight - const isLeft = ( - relativeRect.left + relativeRect.width / 2 <= documentWidth / 2 - || fixedPositionLeft - ) && !fixedPositionRight + const fixedPositionRight = fixedPosition && fixedPosition.indexOf('right') !== -1 + const fixedPositionTop = fixedPosition && fixedPosition.indexOf('top') !== -1 - const hasRelativWidth = documentWidth - relativeRect.left < targetWidth - && relativeRect.right < targetWidth - && !fixedPositionLeft - && !fixedPositionRight - - if (hasRelativWidth) { - left = offsetX - relativeRect.left + 1 - } else if (isLeft) { + const setLeft = () => { left = offsetX - // else is right - } else { + } + const setRight = () => { left = offsetX + relativeRect.width - targetWidth } + const setBottom = () => { + top = offsetY + relativeRect.height + } + const setTop = () => { + top = offsetY - targetHeight + } - const isBottom = ( - relativeRect.top + relativeRect.height / 2 <= documentHeight / 2 - || fixedPositionBottom - ) - && !fixedPositionTop + if (fixedPosition === '') { + if (outOfBoundsRight || rtl) { + setRight() + } else { + setLeft() + } - const hasRelativHeight = relativeRect.top <= targetHeight - && documentHeight - relativeRect.bottom <= targetHeight - && !fixedPositionBottom - && !fixedPositionTop + if (outOfBoundsBottom) { + setTop() + } else { + setBottom() + } + const hasRelativWidth = documentWidth - relativeRect.left < targetWidth + && relativeRect.right < targetWidth - if (hasRelativHeight) { - top = offsetY + documentHeight - relativeRect.top - targetHeight - } else if (isBottom) { - top = offsetY + relativeRect.height - // else is top + const hasRelativHeight = relativeRect.top <= targetHeight + && documentHeight - relativeRect.bottom <= targetHeight + + if (hasRelativWidth) { + left = offsetX - relativeRect.left + 1 + } + + if (hasRelativHeight) { + top = offsetY + documentHeight - relativeRect.top - targetHeight + } } else { - top = offsetY - targetHeight + if (fixedPositionRight) { + setRight() + } else { + setLeft() + } + + if (fixedPositionTop) { + setTop() + } else { + setBottom() + } } + return { left: `${left}px`, top: `${top}px`, From ea9bc2234168d045ebf0b17fd585d956fb88e929 Mon Sep 17 00:00:00 2001 From: MrWook Date: Wed, 7 Oct 2020 08:48:47 +0200 Subject: [PATCH 7/7] docs(project): adjust docs for fixedPosition prop --- docs/.vuepress/components/Demo.vue | 43 +++++++++++++++++++++++++++++ docs/.vuepress/components/style.css | 4 +++ docs/guide/README.md | 2 +- example/Demo.vue | 32 +++++++++++++++++++++ 4 files changed, 80 insertions(+), 1 deletion(-) diff --git a/docs/.vuepress/components/Demo.vue b/docs/.vuepress/components/Demo.vue index 8d123f61..84b9cfee 100755 --- a/docs/.vuepress/components/Demo.vue +++ b/docs/.vuepress/components/Demo.vue @@ -134,6 +134,40 @@ <datepicker :calendar-button="true" :show-calendar-on-button-click="true"></datepicker>
+ +
+

Append datepicker to body

+ +

Don't append datepicker to body

+ + + <datepicker :append-to-body="true"></datepicker> + +
+ +
+

Fixed positions

+ + + <datepicker :fixed-position="fixedPosition"></datepicker> + +
+
Settings
+ +
+
@@ -146,6 +180,15 @@ export default { format: 'd MMMM yyyy', openDate: null, vModelExample: null, + fixedPositions: [ + 'bottom', + 'bottom-left', + 'bottom-right', + 'top', + 'top-left', + 'top-right', + ], + fixedPosition: 'bottom', } }, } diff --git a/docs/.vuepress/components/style.css b/docs/.vuepress/components/style.css index df8d89d8..b8d27ca3 100644 --- a/docs/.vuepress/components/style.css +++ b/docs/.vuepress/components/style.css @@ -38,3 +38,7 @@ .error { color: red; } + +.overflow-scroll { + overflow:scroll +} diff --git a/docs/guide/README.md b/docs/guide/README.md index be7e9f2e..1f4ea15f 100644 --- a/docs/guide/README.md +++ b/docs/guide/README.md @@ -55,6 +55,6 @@ If you use [SASS](https://sass-lang.com/) you can directly import the src file. ```vue ``` diff --git a/example/Demo.vue b/example/Demo.vue index 88ecaf3b..bdb83a78 100755 --- a/example/Demo.vue +++ b/example/Demo.vue @@ -310,6 +310,29 @@ :initialView="'year'"></datepicker> + +
+

Fixed positions

+ + + <datepicker :fixed-position="fixedPosition"></datepicker> + +
+
Settings
+ +
+
@@ -385,6 +408,15 @@ export default { vModelExample: null, languages: lang, language: 'en', + fixedPositions: [ + 'bottom', + 'bottom-left', + 'bottom-right', + 'top', + 'top-left', + 'top-right', + ], + fixedPosition: 'bottom', } }, computed: {