From 62214ca68e005e8dd91aada778846803d65fe95e Mon Sep 17 00:00:00 2001
From: 07akioni <07akioni2@gmail.com>
Date: Thu, 25 Jul 2019 15:18:42 +0800
Subject: [PATCH] fix(nimbus-service-layout): items is not reactive
---
demo/components/datePickerDemo/index.vue | 5 +-
demo/components/datePickerDemo/range.demo.vue | 42 ++
demo/components/nimbusServiceLayoutDemo.vue | 85 +--
packages/common/DatePicker/src/main.vue | 91 +++-
packages/common/DatePicker/src/panel/date.vue | 1 +
.../common/DatePicker/src/panel/datetime.vue | 1 +
.../DatePicker/src/panel/datetimerange.vue | 492 ++++++++++++++++++
packages/mixins/placeable.js | 4 +-
packages/nimbus/ServiceLayout/src/main.vue | 6 +
packages/utils/dom/calcPlacementTransform.js | 12 +-
styles/DatePicker.scss | 109 ++--
styles/theme/default.scss | 2 +-
12 files changed, 719 insertions(+), 131 deletions(-)
create mode 100644 demo/components/datePickerDemo/range.demo.vue
diff --git a/demo/components/datePickerDemo/index.vue b/demo/components/datePickerDemo/index.vue
index 1cd7a2347..d0b0d0fe9 100644
--- a/demo/components/datePickerDemo/index.vue
+++ b/demo/components/datePickerDemo/index.vue
@@ -11,6 +11,7 @@
+
@@ -18,11 +19,13 @@
diff --git a/demo/components/nimbusServiceLayoutDemo.vue b/demo/components/nimbusServiceLayoutDemo.vue
index 07fd0fa69..c1112a29c 100644
--- a/demo/components/nimbusServiceLayoutDemo.vue
+++ b/demo/components/nimbusServiceLayoutDemo.vue
@@ -17,41 +17,7 @@
Take me to the place where you go
Where nobody knows if it's night or day
@@ -60,6 +26,11 @@
Who'll throw it all away
+
+
+ change items
+
+
@@ -52,6 +85,7 @@ import NIcon from '../../Icon'
import detachable from '../../../mixins/detachable'
import placeable from '../../../mixins/placeable'
import DatetimePanel from './panel/datetime'
+import DatetimerangePanel from './panel/datetimerange'
import DatePanel from './panel/date'
import clickoutside from '../../../directives/clickoutside'
@@ -78,7 +112,8 @@ export default {
components: {
NIcon,
DatetimePanel,
- DatePanel
+ DatePanel,
+ DatetimerangePanel
},
mixins: [
detachable,
@@ -106,12 +141,14 @@ export default {
* type can be 'date', 'datetime'
*/
type: {
- type: String,
+ validator (type) {
+ return ['date', 'datetime', 'daterange', 'datetimerange'].includes(type)
+ },
default: 'date'
},
- debug: {
- type: Boolean,
- default: false
+ placeholder: {
+ type: String,
+ default: null
}
},
data () {
@@ -124,12 +161,20 @@ export default {
active: false,
calendar: [],
rightCalendar: [],
+ isFocus: false,
...TIME_CONST
}
},
computed: {
- placeholder () {
- return PLACEHOLDER[this.type]
+ isRange () {
+ return ['daterange', 'datetimerange'].includes(this.type)
+ },
+ computedPlaceholder () {
+ if (this.placeholder === null) {
+ return PLACEHOLDER[this.type]
+ } else {
+ return this.placeholder
+ }
},
format () {
return DATE_FORMAT[this.type]
@@ -206,6 +251,7 @@ export default {
} else {
this.refreshSelectedDateTimeString()
}
+ this.isFocus = false
},
handleActivatorClick (e) {
if (this.active) {
@@ -237,6 +283,9 @@ export default {
if (newSelectedDateTime.isValid()) {
this.$emit('input', newSelectedDateTime.valueOf())
}
+ },
+ handleFocus () {
+ this.isFocus = true
}
}
}
diff --git a/packages/common/DatePicker/src/panel/date.vue b/packages/common/DatePicker/src/panel/date.vue
index 31dd11f4f..f45ded899 100644
--- a/packages/common/DatePicker/src/panel/date.vue
+++ b/packages/common/DatePicker/src/panel/date.vue
@@ -201,6 +201,7 @@ export default {
created () {
if (this.valueAsMoment !== null) {
this.displayDateString = this.valueAsMoment.format(DATE_FORMAT)
+ this.calendarDateTime = this.valueAsMoment
} else {
this.displayDateString = ''
}
diff --git a/packages/common/DatePicker/src/panel/datetime.vue b/packages/common/DatePicker/src/panel/datetime.vue
index 9f403c27d..f2cbea5dd 100644
--- a/packages/common/DatePicker/src/panel/datetime.vue
+++ b/packages/common/DatePicker/src/panel/datetime.vue
@@ -222,6 +222,7 @@ export default {
created () {
if (this.valueAsMoment !== null) {
this.displayDateString = this.valueAsMoment.format(DATE_FORMAT)
+ this.calendarDateTime = this.valueAsMoment
} else {
this.displayDateString = ''
}
diff --git a/packages/common/DatePicker/src/panel/datetimerange.vue b/packages/common/DatePicker/src/panel/datetimerange.vue
index e69de29bb..2249272b1 100644
--- a/packages/common/DatePicker/src/panel/datetimerange.vue
+++ b/packages/common/DatePicker/src/panel/datetimerange.vue
@@ -0,0 +1,492 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ startCalendarDateTime.format('MMMM') }} {{ startCalendarDateTime.year() }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ dateItem.date }}
+
+
+
+
+ Now
+
+
+ Confirm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ endCalendarDateTime.format('MMMM') }} {{ endCalendarDateTime.year() }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ dateItem.date }}
+
+
+
+
+ Now
+
+
+ Confirm
+
+
+
+
+
+
+
+
diff --git a/packages/mixins/placeable.js b/packages/mixins/placeable.js
index 533c3ceab..8627d8c91 100644
--- a/packages/mixins/placeable.js
+++ b/packages/mixins/placeable.js
@@ -78,7 +78,9 @@ export default {
// console.log(contentBoundingClientRect)
// debugger
// console.log('scroll', activatorBoundingClientRect, contentBoundingClientRect)
- this.$refs.content.style = 'position: absolute;' + calcPlacementTransfrom(this.placement, activatorBoundingClientRect, contentBoundingClientRect)
+ const [placementTransform, suggsetedTransformOrigin] = calcPlacementTransfrom(this.placement, activatorBoundingClientRect, contentBoundingClientRect)
+ this.$refs.content.style = 'position: absolute;' + placementTransform + `transform-origin: ${suggsetedTransformOrigin};`
+ this.$refs.content.setAttribute('n-suggested-transform-origin', suggsetedTransformOrigin)
if (this.widthMode === 'activator' && this.$refs.contentInner) {
this.$refs.contentInner.style.minWidth = activatorBoundingClientRect.width + 'px'
}
diff --git a/packages/nimbus/ServiceLayout/src/main.vue b/packages/nimbus/ServiceLayout/src/main.vue
index d21c407e8..6f6a27231 100644
--- a/packages/nimbus/ServiceLayout/src/main.vue
+++ b/packages/nimbus/ServiceLayout/src/main.vue
@@ -119,6 +119,12 @@ export default {
watch: {
$route (to, from) {
this.syncActiveItemWithPath(to.path)
+ },
+ items (newItems) {
+ this.itemsWithCollapseStatus = newItems.map(item => ({
+ ...item,
+ isCollapsed: false
+ }))
}
},
mounted () {
diff --git a/packages/utils/dom/calcPlacementTransform.js b/packages/utils/dom/calcPlacementTransform.js
index b9f278b7f..c57927d05 100644
--- a/packages/utils/dom/calcPlacementTransform.js
+++ b/packages/utils/dom/calcPlacementTransform.js
@@ -1,5 +1,6 @@
export default function calcPlacementTransform (placement, activatorRect, popoverRect) {
let contentLeft, contentTop
+ let suggesetedTransfromOrigin = 'none'
if (placement === 'top-start') {
contentTop = activatorRect.top - popoverRect.height
contentLeft = activatorRect.left
@@ -28,7 +29,14 @@ export default function calcPlacementTransform (placement, activatorRect, popove
contentTop = activatorRect.top + activatorRect.height - popoverRect.height
contentLeft = activatorRect.left + activatorRect.width
} else if (placement === 'bottom-start') {
- contentTop = activatorRect.top + activatorRect.height
+ const toWindowBottom = window.innerHeight - activatorRect.bottom
+ if (popoverRect.height > toWindowBottom) {
+ contentTop = activatorRect.top - popoverRect.height
+ suggesetedTransfromOrigin = 'bottom left'
+ } else {
+ contentTop = activatorRect.top + activatorRect.height
+ suggesetedTransfromOrigin = 'top left'
+ }
contentLeft = activatorRect.left
} else if (placement === 'bottom-end') {
contentTop = activatorRect.top + activatorRect.height
@@ -43,5 +51,5 @@ export default function calcPlacementTransform (placement, activatorRect, popove
* However, I found that the dom delay is very serious.
* So I decide to use left and top for now.
*/
- return `left: ${contentLeft}px; top: ${contentTop}px;`
+ return [`left: ${contentLeft}px; top: ${contentTop}px;`, suggesetedTransfromOrigin]
}
diff --git a/styles/DatePicker.scss b/styles/DatePicker.scss
index 04e7ad320..8d550e9c6 100644
--- a/styles/DatePicker.scss
+++ b/styles/DatePicker.scss
@@ -11,25 +11,24 @@
.n-date-picker__icon {
color: rgba(255, 255, 255, .2);
}
- .n-date-picker__input {
+ .n-date-picker__editor {
cursor: not-allowed;
background-color: rgba(255, 255, 255, .08);
- color: rgba(255, 255, 255, .2);
- &:focus:hover {
- box-shadow: none;
+ .n-date-picker__input {
+ cursor: not-allowed;
+ color: rgba(255, 255, 255, .2);
+ &::placeholder {
+ color: rgba(255, 255, 255, .2);
+ }
}
&:hover {
box-shadow: none;
}
- &:focus {
- box-shadow: none;
- background-color: rgba(255, 255, 255, .08);
- }
- &::placeholder {
- color: rgba(255, 255, 255, .2);
- }
}
}
+ &.n-date-picker--range {
+ width: 382px;
+ }
.n-date-picker__icon {
position: absolute;
right: 13px;
@@ -37,9 +36,9 @@
transform: translateY(-50%);
color: rgba(221, 238, 247, 0.3);
height: 20px;
+ transition: color .3s $default-cubic-bezier;
}
- .n-date-picker__input, .n-date-picker-calendar__date-input {
- -webkit-appearance: none;
+ .n-date-picker__editor {
box-sizing: border-box;
border: none;
border-radius: $input-border-radius;
@@ -54,19 +53,30 @@
transition: box-shadow .3s $default-cubic-bezier, background-color .3s $default-cubic-bezier;
padding: 0 14px;
font-size: 14px;
- &:focus:hover {
- box-shadow: inset 0 0 0px 1px $main-color, 0px 0px 10px 1px #366555;
+ .n-date-picker__input {
+ width: 100%;
+ -webkit-appearance: none;
+ outline: none;
+ background: none;
+ color: #fff;
+ border: none;
+ padding: 0;
+ transition: color .3s $default-cubic-bezier;
+ &::placeholder {
+ transition: color .3s $default-cubic-bezier;
+ color: $input-placeholder-color;
+ opacity: 1;
+ }
}
- &:hover {
- box-shadow: inset 0 0 0px 1px $main-color;
- }
- &:focus {
+ &.n-date-picker__editor--focus {
+ &:hover {
+ box-shadow: inset 0 0 0px 1px $main-color, 0px 0px 10px 1px #366555;
+ }
box-shadow: inset 0 0 0px 1px $main-color;
background-color: $focus-input-background-color;
}
- &::placeholder {
- color: $input-placeholder-color;
- opacity: 1;
+ &:hover {
+ box-shadow: inset 0 0 0px 1px $main-color;
}
}
&.n-date-picker--small-size {
@@ -95,11 +105,19 @@
@include b(date-picker-calendar) {
@include fade-in-transition(date-picker-calendar);
margin-top: 4px;
+ margin-bottom: 4px;
width: 351px;
background:rgba(75,81,106,1);
box-shadow:0px 2px 20px 0px rgba(0,0,0,0.16);
border-radius: 6px;
color:rgba(233,233,236,1);
+ &.n-date-picker-calendar--datetimerange {
+ width: 702px;
+ display: flex;
+ }
+ .n-date-picker-calendar__range-wrapper {
+ width: 351px;
+ }
.n-date-picker-calendar__date-time-input-wrapper {
padding: 14px 24px;
border-bottom: 1px solid rgba(255, 255, 255, .07);
@@ -213,51 +231,4 @@
margin-bottom: 0;
}
}
-}
-
-@include b(date-picker-time-selector) {
- z-index: 1;
- position: absolute;
- top: calc(100% + 4px);
- background-color: rgba(97, 104, 132, 1);
- box-shadow:0px 2px 20px 0px rgba(0,0,0,0.16);
- font-size: 12px;
- border-radius: 6px;
- width: 180px;
- .n-date-picker-time-selector__selection-wrapper {
- height: 244px;
- border-bottom: 1px solid rgba(255, 255, 255, .07);
- display: flex;
- }
- .n-date-picker-time-selector__hour, .n-date-picker-time-selector__minute, .n-date-picker-time-selector__second {
- @include scrollbar;
- width: 60px;
- height: 244px;
- flex-direction: column;
- overflow-y: scroll;
- .n-date-picker-time-selector__item {
- cursor: pointer;
- height: 35px;
- display: flex;
- align-items: center;
- justify-content: center;
- transition: background-color .2s $default-cubic-bezier, color .2s $default-cubic-bezier;
- background: transparent;
- &:hover {
- background-color: rgba(99,226,183,0.12);
- }
- &.n-date-picker-time-selector__item--active {
- background-color: rgba(99,226,183,0.12);
- color: rgba(99, 226, 183, 1);
- }
- }
- }
- .n-date-picker-time-selector__actions {
- margin: 10px 15px;
- display: flex;
- justify-content: space-between;
- .n-button {
- margin: 0;
- }
- }
}
\ No newline at end of file
diff --git a/styles/theme/default.scss b/styles/theme/default.scss
index 71277d4f1..ee8ca70e7 100644
--- a/styles/theme/default.scss
+++ b/styles/theme/default.scss
@@ -184,7 +184,7 @@ $default-font-family: 'Lato';
}
}
-@mixin fade-in-transition($block, $origin: left top) {
+@mixin fade-in-transition($block, $origin: inherit) {
&.#{$namespace}-#{$block}--transition-enter-active,
&.#{$namespace}-#{$block}--transition-leave-active {
transform: scale(1);