提交 97fc271f 编写于 作者: Q qiang

Merge branch 'dev' into alpha

# Conflicts:
#	packages/uni-h5/dist/index.css
#	packages/uni-h5/dist/index.umd.min.js
......@@ -162,7 +162,13 @@ const ui = [
'createSelectorQuery',
'createIntersectionObserver',
'createMediaQueryObserver',
'getMenuButtonBoundingClientRect'
'getMenuButtonBoundingClientRect',
'showTopWindow',
'showLeftWindow',
'showRightWindow',
'hideTopWindow',
'hideLeftWindow',
'hideRightWindow',
]
const event = [
......
......@@ -114,11 +114,12 @@
scan = new plus.barcode.Barcode('scan', webview.__uniapp_scan_type, {
frameColor: '#118CE9',
scanbarColor: '#118CE9'
});
scan.onmarked = function(type, code, file) {
}, webview.__uniapp_auto_decode_char_set);
scan.onmarked = function(type, code, file, charSet) {
var res = {
type: type,
code: code
code: code,
charSet: charSet
};
back()
plus.webview.postMessageToUniNView({
......
......@@ -114,11 +114,12 @@
scan = new plus.barcode.Barcode('scan', webview.__uniapp_scan_type, {
frameColor: '#118CE9',
scanbarColor: '#118CE9'
});
scan.onmarked = function(type, code, file) {
}, webview.__uniapp_auto_decode_char_set);
scan.onmarked = function(type, code, file, charSet) {
var res = {
type: type,
code: code
code: code,
charSet: charSet
};
back()
plus.webview.postMessageToUniNView({
......
此差异已折叠。
......@@ -741,6 +741,30 @@
]
]
],
"showTopWindow": [
"/platforms/h5/service/api/ui/windows.js",
[]
],
"showLeftWindow": [
"/platforms/h5/service/api/ui/windows.js",
[]
],
"showRightWindow": [
"/platforms/h5/service/api/ui/windows.js",
[]
],
"hideTopWindow": [
"/platforms/h5/service/api/ui/windows.js",
[]
],
"hideLeftWindow": [
"/platforms/h5/service/api/ui/windows.js",
[]
],
"hideRightWindow": [
"/platforms/h5/service/api/ui/windows.js",
[]
],
"$emit": [
"/platforms/h5/service/api/base/event-bus.js",
[
......
......@@ -339,6 +339,10 @@ module.exports = function (pagesJson, userManifestJson, isAppView) {
const nvuePages = (appJson.nvue && appJson.nvue.pages) || {}
for (const key in confusion.resources) {
if (path.extname(key) === '.js') { // 支持 js 混淆,过滤掉
// 静态 js 文件
if (key.indexOf('hybrid/html') === 0 || key.indexOf('static/') === 0 || key.indexOf('/static/') !== -1) {
resources[key] = confusion.resources[key]
}
continue
}
if (!/\.nvue$/.test(key)) {
......@@ -349,9 +353,10 @@ module.exports = function (pagesJson, userManifestJson, isAppView) {
if (!Object.keys(nvuePages).find(path => {
const subNVues = nvuePages[path].window.subNVues || []
// TODO
return (path.replace(/\.html$/, '.nvue') === key || path.replace(/\.html$/, '.nvue') + '.nvue' === key) || subNVues.find(({
path
}) => path === key.replace(/\.nvue$/, ''))
return (path.replace(/\.html$/, '.nvue') === key || path.replace(/\.html$/, '.nvue') + '.nvue' === key) ||
subNVues.find(({
path
}) => path === key.replace(/\.nvue$/, ''))
}) && !pagesJson.pages.find(({
style = {}
}) => {
......@@ -517,4 +522,4 @@ module.exports = function (pagesJson, userManifestJson, isAppView) {
}, isAppView)
}
return [app, manifest]
}
}
export const scanCode = {
onlyFromCamera: {
type: Boolean
},
scanType: {
type: Array
},
autoDecodeCharSet: {
type: Boolean
}
}
......@@ -330,12 +330,12 @@ export class CanvasContext {
measureText (text) {
const font = this.state.font
let width
let width = 0
if (__PLATFORM__ === 'h5') {
width = measureText(text, font)
} else {
const webview = plus.webview.getWebviewById(String(this.pageId))
width = webview.evalJSSync(`(${measureText.toString()})(${JSON.stringify(text)},${JSON.stringify(font)})`)
} else if (plus.os.name.toLowerCase() === 'ios') {
const webview = plus.webview.all().find(webview => webview.getURL().endsWith('www/__uniappview.html'))
width = Number(webview.evalJSSync(`(${measureText.toString()})(${JSON.stringify(text)},${JSON.stringify(font)})`))
}
return new TextMetrics(width)
}
......
......@@ -27,8 +27,12 @@ function getRootInfo (fields) {
info.height = document.documentElement.clientHeight
}
if (fields.scrollOffset) {
info.scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft || 0
info.scrollTop = document.documentElement.scrollTop || document.body.scrollTop || 0
const documentElement = document.documentElement
const body = document.body
info.scrollLeft = documentElement.scrollLeft || body.scrollLeft || 0
info.scrollTop = documentElement.scrollTop || body.scrollTop || 0
info.scrollHeight = documentElement.scrollHeight || body.scrollHeight || 0
info.scrollWidth = documentElement.scrollWidth || body.scrollWidth || 0
}
return info
}
......@@ -58,7 +62,7 @@ function getNodeInfo (el, fields) {
}
}
// TODO 组件 props
if (fields.properties) {
if (Array.isArray(fields.properties)) {
fields.properties.forEach(prop => {
prop = prop.replace(/-([a-z])/g, function (e, t) {
return t.toUpperCase()
......@@ -72,8 +76,16 @@ function getNodeInfo (el, fields) {
} else {
info.scrollLeft = 0
info.scrollTop = 0
info.scrollHeight = 0
info.scrollWidth = 0
}
}
if (Array.isArray(fields.computedStyle)) {
const sytle = getComputedStyle(el)
fields.computedStyle.forEach(name => {
info[name] = sytle[name]
})
}
if (fields.context) {
if (el.__vue__ && el.__vue__._getContextInfo) {
info.context = el.__vue__._getContextInfo()
......
......@@ -349,8 +349,8 @@ export default {
return
}
}
// Chrome85+ 本地路径
if (src.indexOf('file://') === 0 && navigator.vendor === 'Google Inc.' && Promise.any) {
// Chrome84+ 本地路径
if (src.indexOf('file://') === 0 && navigator.vendor === 'Google Inc.' && 'wakeLock' in navigator) {
image.crossOrigin = 'anonymous'
}
}
......
......@@ -286,15 +286,6 @@ export default {
transform: translateY(-50%);
}
.uni-picker-view-indicator,
.uni-picker-view-mask {
position: absolute;
left: 0;
width: 100%;
z-index: 3;
pointer-events: none;
}
.uni-picker-view-content {
position: absolute;
top: 0;
......
......@@ -6,9 +6,18 @@ import {
const TAGS = {
a: '',
abbr: '',
address: '',
article: '',
aside: '',
b: '',
bdi: '',
bdo: ['dir'],
big: '',
blockquote: '',
br: '',
caption: '',
center: '',
cite: '',
code: '',
col: ['span', 'width'],
colgroup: ['span', 'width'],
......@@ -19,12 +28,15 @@ const TAGS = {
dt: '',
em: '',
fieldset: '',
font: '',
footer: '',
h1: '',
h2: '',
h3: '',
h4: '',
h5: '',
h6: '',
header: '',
hr: '',
i: '',
img: ['alt', 'src', 'height', 'width'],
......@@ -32,20 +44,30 @@ const TAGS = {
label: '',
legend: '',
li: '',
mark: '',
nav: '',
ol: ['start', 'type'],
p: '',
pre: '',
q: '',
rt: '',
ruby: '',
s: '',
section: '',
small: '',
span: '',
strong: '',
sub: '',
sup: '',
table: ['width'],
tbody: '',
td: ['colspan', 'rowspan', 'height', 'width'],
td: ['colspan', 'height', 'rowspan', 'width'],
tfoot: '',
th: ['colspan', 'rowspan', 'height', 'width'],
th: ['colspan', 'height', 'rowspan', 'width'],
thead: '',
tr: '',
tr: ['colspan', 'height', 'rowspan', 'width'],
tt: '',
u: '',
ul: ''
}
const CHARS = {
......
......@@ -511,7 +511,9 @@ export default {
const main = this.$refs.main
return {
scrollLeft: main.scrollLeft,
scrollTop: main.scrollTop
scrollTop: main.scrollTop,
scrollHeight: main.scrollHeight,
scrollWidth: main.scrollWidth
}
}
}
......
......@@ -23,7 +23,8 @@ const MESSAGE_TYPE = 'scanCode'
export function scanCode ({
onlyFromCamera = false,
scanType
scanType,
autoDecodeCharSet
}, callbackId) {
const barcode = plus.barcode
const SCAN_TYPES = {
......@@ -95,18 +96,19 @@ export function scanCode ({
width: '60px',
onclick: function () {
plus.gallery.pick(file => {
barcode.scan(file, (type, code) => {
barcode.scan(file, (type, code, path, charSet) => {
if (isDark) {
plus.navigator.setStatusBarStyle('isDark')
}
result = {
type,
code
code,
charSet
}
webview.close('auto')
}, () => {
plus.nativeUI.toast('识别失败')
}, filters)
}, filters, autoDecodeCharSet)
}, err => {
if (err.code !== 12) {
plus.nativeUI.toast('选择失败')
......@@ -135,6 +137,7 @@ export function scanCode ({
__uniapp_type: 'scan',
__uniapp_dark: isDark,
__uniapp_scan_type: filters,
__uniapp_auto_decode_char_set: autoDecodeCharSet,
'uni-app': 'none'
})
const waiting = plus.nativeUI.showWaiting()
......@@ -148,7 +151,7 @@ export function scanCode ({
invoke(callbackId, {
result: result.code,
scanType: SCAN_MAPS[result.type] || '',
charSet: 'utf8',
charSet: result.charSet || 'utf8',
path: '',
errMsg: 'scanCode:ok'
})
......
......@@ -23,9 +23,7 @@ export function scanCode (options, callbackId) {
let result
const page = showPage({
url: '__uniappscan',
data: {
scanType: options.scanType
},
data: options,
style: {
animationType: options.animationType || 'pop-in',
titleNView: {
......
......@@ -20,12 +20,13 @@ function getSavedFileDir (success, fail) {
}, fail)
}
let index = 0
export function saveFile ({
tempFilePath
} = {}, callbackId) {
const errorCallback = warpPlusErrorCallback(callbackId, 'saveFile')
let fileName = getFileName(tempFilePath)
fileName = `${Date.now()}_${fileName}`
fileName = `${Date.now()}${index++}_${fileName}`
plus.io.resolveLocalFileSystemURL(tempFilePath, entry => { // 读取临时文件 FileEntry
getSavedFileDir(dir => {
......
<template>
<uni-app :class="{'uni-app--showtabbar':showTabBar}">
<layout
ref="layout"
:router-key="key"
:keep-alive-include="keepAliveInclude"
/>
......
<template>
<uni-layout
v-if="responsive"
:class="{'uni-app--showlayout':showLayout}"
:class="{'uni-app--showlayout':showLayout,'uni-app--showtopwindow':showTopWindow,'uni-app--showleftwindow':showLeftWindow,'uni-app--showrightwindow':showRightWindow}"
>
<uni-top-window
v-if="topWindow"
v-show="showTopWindow && topWindowMediaQuery"
v-show="showTopWindow || apiShowTopWindow"
>
<div
ref="topWindow"
......@@ -14,6 +14,8 @@
>
<v-uni-top-window
ref="top"
:navigation-bar-title-text="navigationBarTitleText"
v-bind="bindWindow"
@hook:mounted="onTopWindowInit"
/>
</div>
......@@ -30,25 +32,43 @@
</uni-main>
<uni-left-window
v-if="leftWindow"
v-show="showLeftWindow && leftWindowMediaQuery"
v-show="showLeftWindow || apiShowLeftWindow"
ref="leftWindow"
v-bind="bindWindow"
:data-show="apiShowLeftWindow"
:style="leftWindowStyle"
>
<v-uni-left-window
ref="left"
@hook:mounted="onLeftWindowInit"
<div
v-if="apiShowLeftWindow"
class="uni-mask"
@click="apiShowLeftWindow = false"
/>
<div class="uni-left-window">
<v-uni-left-window
ref="left"
@hook:mounted="onLeftWindowInit"
/>
</div>
</uni-left-window>
<uni-right-window
v-if="rightWindow"
v-show="showRightWindow && rightWindowMediaQuery"
v-show="showRightWindow || apiShowRightWindow"
ref="rightWindow"
v-bind="bindWindow"
:data-show="apiShowRightWindow"
:style="rightWindowStyle"
>
<v-uni-right-window
ref="right"
@hook:mounted="onRightWindowInit"
<div
v-if="apiShowRightWindow"
class="uni-mask"
@click="apiShowRightWindow = false"
/>
<div class="uni-right-window">
<v-uni-right-window
ref="right"
@hook:mounted="onRightWindowInit"
/>
</div>
</uni-right-window>
</uni-content>
<!--TODO footer-->
......@@ -64,6 +84,11 @@
<script>
import Vue from 'vue'
import {
hasOwn,
capitalize
} from 'uni-shared'
import {
RESPONSIVE_MIN_WIDTH
} from 'uni-helpers/constants'
......@@ -115,21 +140,38 @@ export default {
topWindowMediaQuery: false,
leftWindowMediaQuery: false,
rightWindowMediaQuery: false,
topWindowHeight: '0px'
topWindowHeight: '0px',
apiShowTopWindow: false,
apiShowLeftWindow: false,
apiShowRightWindow: false,
navigationBarTitleText: ''
}
},
computed: {
bindWindow () {
return {
matchTopWindow: this.topWindowMediaQuery,
showTopWindow: this.showTopWindow || this.apiShowTopWindow,
matchLeftWindow: this.leftWindowMediaQuery,
showLeftWindow: this.showLeftWindow || this.apiShowLeftWindow,
matchRightWindow: this.rightWindowMediaQuery,
showRightWindow: this.showRightWindow || this.apiShowRightWindow
}
},
showLayout () {
return this.showTopWindow || this.showLeftWindow || this.showRightWindow
},
showTopWindow () {
return this.$route.meta.topWindow !== false
this.resetApiShowWindow()
return this.$route.meta.topWindow !== false && this.topWindowMediaQuery
},
showLeftWindow () {
return this.$route.meta.leftWindow !== false
this.resetApiShowWindow()
return this.$route.meta.leftWindow !== false && this.leftWindowMediaQuery
},
showRightWindow () {
return this.$route.meta.rightWindow !== false
this.resetApiShowWindow()
return this.$route.meta.rightWindow !== false && this.rightWindowMediaQuery
}
},
watch: {
......@@ -182,20 +224,49 @@ export default {
this.rightWindowStyle = this.rightWindow.options.style
}
windowTypes.forEach(type => this.initMediaQuery(type))
UniServiceJSBridge.on('onNavigationBarChange', (navigationBar) => {
this.navigationBarTitleText = navigationBar.titleText
})
}
}
},
methods: {
resetApiShowWindow () {
// 仅对 left,right 重置
// this.apiShowTopWindow = false
this.apiShowLeftWindow = false
this.apiShowRightWindow = false
},
showWindow (type, show = true) {
if (!this[type + 'Window']) {
return type + 'Window not found'
}
const fType = capitalize(type)
if (!this['show' + fType + 'Window']) { // 小屏下
const apiShowName = 'apiShow' + fType + 'Window'
if (this[apiShowName] !== show) {
this[apiShowName] = show
if (type === 'top') { // 特殊处理 top
if (show) {
this.$nextTick(this.onTopWindowInit)
} else {
updateCssVar('--window-top', '0px')
}
}
}
}
},
initWindowMinWidth (type) {
const name = type + 'Window'
if (this[name]) {
const minWidthName = type + 'WindowMinWidth'
this[minWidthName] = RESPONSIVE_MIN_WIDTH
const windowOptions = __uniConfig[name]
if (windowOptions && windowOptions.matchMedia && windowOptions.matchMedia.minWidth) {
if (windowOptions && windowOptions.matchMedia && hasOwn(windowOptions.matchMedia, 'minWidth')) {
this[minWidthName] = windowOptions.matchMedia.minWidth
}
if (!this.minWidth || this.minWidth > this[minWidthName]) {
if (typeof this.minWidth === 'undefined' || this.minWidth > this[minWidthName]) {
this.minWidth = this[minWidthName]
}
}
......@@ -207,7 +278,7 @@ export default {
mediaQueryList.addListener((e) => {
this[name] = e.matches
this.$nextTick(() => {
this['on' + (type.substr(0, 1).toUpperCase() + type.substr(1)) + 'WindowInit']()
this['on' + capitalize(type) + 'WindowInit']()
})
})
this[name] = mediaQueryList.matches
......@@ -279,6 +350,26 @@ export default {
overflow-x: hidden;
}
uni-left-window[data-show],
uni-right-window[data-show] {
position: absolute;
}
uni-right-window[data-show] {
right: 0;
}
uni-content .uni-mask,
.uni-left-window,
.uni-right-window {
z-index: 997;
}
.uni-mask+.uni-left-window,
.uni-mask+.uni-right-window {
position: absolute;
}
.uni-app--showlayout+uni-tabbar {
display: none;
}
......
......@@ -9,7 +9,7 @@
</transition>
<div
:class="{ 'uni-actionsheet_toggle': visible }"
:style="actionSheetStyle.content"
:style="popupStyle.content"
class="uni-actionsheet"
>
<div class="uni-actionsheet__menu">
......@@ -38,13 +38,16 @@
取消
</div>
</div>
<div :style="actionSheetStyle.triangle" />
<div :style="popupStyle.triangle" />
</div>
</uni-actionsheet>
</template>
<script>
import popup from './mixins/popup'
export default {
name: 'ActionSheet',
mixins: [popup],
props: {
title: {
type: String,
......@@ -69,75 +72,6 @@ export default {
default: false
}
},
data () {
return {
width: 0,
height: 0,
top: top
}
},
computed: {
actionSheetStyle () {
const style = {}
const contentStyle = style.content = {}
const triangleStyle = style.triangle = {}
const popover = this.popover
function getNumber (value) {
return Number(value) || 0
}
if (this.width >= 500 && popover) {
Object.assign(triangleStyle, {
position: 'absolute',
width: '0',
height: '0',
'margin-left': '-6px',
'border-style': 'solid'
})
const popoverLeft = getNumber(popover.left)
const popoverWidth = getNumber(popover.width)
const popoverTop = getNumber(popover.top)
const popoverHeight = getNumber(popover.height)
const center = (popoverLeft + popoverWidth) / 2
contentStyle.transform = 'none !important'
const contentLeft = Math.max(0, center - 300 / 2)
contentStyle.left = `${contentLeft}px`
let triangleLeft = Math.max(12, center - contentLeft)
triangleLeft = Math.min(300 - 12, triangleLeft)
triangleStyle.left = `${triangleLeft}px`
const vcl = this.height / 2
if (popoverTop + popoverHeight - vcl > vcl - popoverTop) {
contentStyle.top = 'auto'
contentStyle.bottom = `${this.height - popoverTop + 6}px`
triangleStyle.bottom = '-6px'
triangleStyle['border-width'] = '6px 6px 0 6px'
triangleStyle['border-color'] = '#fcfcfd transparent transparent transparent'
} else {
contentStyle.top = `${popoverTop + popoverHeight + 6}px`
triangleStyle.top = '-6px'
triangleStyle['border-width'] = '0 6px 6px 6px'
triangleStyle['border-color'] = 'transparent transparent #fcfcfd transparent'
}
}
return style
}
},
mounted () {
const fixSize = () => {
const {
windowWidth,
windowHeight,
windowTop
} = uni.getSystemInfoSync()
this.width = windowWidth
this.height = windowHeight + windowTop
this.top = windowTop
}
this.$watch('visible', value => value && fixSize())
window.addEventListener('resize', fixSize)
this.$once('hook:beforeDestroy', () => {
window.removeEventListener('resize', fixSize)
})
},
methods: {
_close (tapIndex) {
this.$emit('close', tapIndex)
......@@ -190,6 +124,7 @@ uni-actionsheet .uni-actionsheet__title {
font-size: 18px;
text-overflow: ellipsis;
overflow: hidden;
cursor: pointer;
}
uni-actionsheet .uni-actionsheet__cell:before {
......
export default {
data () {
return {
popupWidth: 0,
popupHeight: 0
}
},
computed: {
popupStyle () {
const style = {}
const contentStyle = style.content = {}
const triangleStyle = style.triangle = {}
const popover = this.popover
function getNumber (value) {
return Number(value) || 0
}
if (this.popupWidth >= 500 && popover) {
Object.assign(triangleStyle, {
position: 'absolute',
width: '0',
height: '0',
'margin-left': '-6px',
'border-style': 'solid'
})
const popoverLeft = getNumber(popover.left)
const popoverWidth = getNumber(popover.width)
const popoverTop = getNumber(popover.top)
const popoverHeight = getNumber(popover.height)
const center = (popoverLeft + popoverWidth) / 2
contentStyle.transform = 'none !important'
const contentLeft = Math.max(0, center - 300 / 2)
contentStyle.left = `${contentLeft}px`
let triangleLeft = Math.max(12, center - contentLeft)
triangleLeft = Math.min(300 - 12, triangleLeft)
triangleStyle.left = `${triangleLeft}px`
const vcl = this.popupHeight / 2
if (popoverTop + popoverHeight - vcl > vcl - popoverTop) {
contentStyle.top = 'auto'
contentStyle.bottom = `${this.popupHeight - popoverTop + 6}px`
triangleStyle.bottom = '-6px'
triangleStyle['border-width'] = '6px 6px 0 6px'
triangleStyle['border-color'] = '#fcfcfd transparent transparent transparent'
} else {
contentStyle.top = `${popoverTop + popoverHeight + 6}px`
triangleStyle.top = '-6px'
triangleStyle['border-width'] = '0 6px 6px 6px'
triangleStyle['border-color'] = 'transparent transparent #fcfcfd transparent'
}
}
return style
}
},
mounted () {
const fixSize = () => {
const {
windowWidth,
windowHeight,
windowTop
} = uni.getSystemInfoSync()
this.popupWidth = windowWidth
this.popupHeight = windowHeight + windowTop
}
this.$watch('visible', value => value && fixSize())
window.addEventListener('resize', fixSize)
this.$once('hook:beforeDestroy', () => {
window.removeEventListener('resize', fixSize)
})
}
}
......@@ -10,9 +10,9 @@
v-if="title"
class="uni-modal__hd"
>
<strong
class="uni-modal__title"
v-text="title"
<strong
class="uni-modal__title"
v-text="title"
/>
</div>
<div
......@@ -174,6 +174,7 @@ export default {
text-decoration: none;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
position: relative;
cursor: pointer;
}
uni-modal .uni-modal__btn:active {
......
import {
capitalize
} from 'uni-shared'
function showWindow (type, show) {
const api = show ? 'show' : 'hide' + capitalize(type) + 'Window'
const app = getApp()
if (app) {
const msg = app.$children[0].$refs.layout.showWindow(type, show)
if (msg) {
return {
errMsg: `${api}:fail ${msg}`
}
}
return {}
}
return {
errMsg: `${api}:fail app not ready`
}
}
export function showTopWindow () {
return showWindow('top', true)
}
export function hideTopWindow () {
return showWindow('top', false)
}
export function showLeftWindow () {
return showWindow('left', true)
}
export function hideLeftWindow () {
return showWindow('left', false)
}
export function showRightWindow () {
return showWindow('right', true)
}
export function hideRightWindow () {
return showWindow('right', false)
}
......@@ -12,12 +12,13 @@
<transition name="uni-fade">
<div
v-show="visible"
class="uni-mask"
class="uni-mask uni-picker-mask"
@click="_cancel"
/>
</transition>
<div
:class="{'uni-picker-toggle':visible}"
:class="{ 'uni-picker-toggle': visible }"
:style="popupStyle.content"
class="uni-picker"
>
<div
......@@ -38,20 +39,21 @@
</div>
</div>
<v-uni-picker-view
v-if="visible"
v-if="contentVisible"
:value.sync="valueArray"
class="uni-picker-content"
>
<v-uni-picker-view-column
v-for="(rangeItem,index0) in rangeArray"
v-for="(rangeItem, index0) in rangeArray"
:key="index0"
>
<div
v-for="(item,index) in rangeItem"
v-for="(item, index) in rangeItem"
:key="index"
class="uni-picker-item"
>
{{ typeof item==='object'?item[rangeKey]||'':item }}{{ units[index0]||'' }}
{{ typeof item === "object" ? item[rangeKey] || "" : item
}}{{ units[index0] || "" }}
</div>
</v-uni-picker-view-column>
</v-uni-picker-view>
......@@ -59,6 +61,7 @@
<!-- <div v-if="units.length" class="uni-picker-units">
<div v-for="(item,index) in units" :key="index">{{item}}</div>
</div>-->
<div :style="popupStyle.triangle" />
</div>
</div>
<div>
......@@ -70,6 +73,7 @@
<script>
import { emitter } from 'uni-mixins'
import { formatDateTime } from 'uni-shared'
import popup from '../../../components/app/popup/mixins/popup'
function getDefaultStartValue () {
if (this.mode === mode.TIME) {
......@@ -122,7 +126,7 @@ const fields = {
}
export default {
name: 'Picker',
mixins: [emitter],
mixins: [emitter, popup],
props: {
name: {
type: String,
......@@ -173,6 +177,8 @@ export default {
return {
valueSync: null,
visible: false,
contentVisible: false,
popover: null,
valueChangeSource: '',
timeArray: [],
dateArray: [],
......@@ -221,8 +227,19 @@ export default {
return []
}
}
},
watch: {
visible (val) {
if (val) {
clearTimeout(this.__contentVisibleDelay)
this.contentVisible = val
} else {
this.__contentVisibleDelay = setTimeout(() => {
this.contentVisible = val
}, 300)
}
},
value () {
this._setValueSync()
},
......@@ -247,8 +264,7 @@ export default {
const max = dateArray[2].length
const day = Number(dateArray[2][valueArray[2]]) || 1
const realDay = new Date(
`${dateArray[0][valueArray[0]]}/${
dateArray[1][valueArray[1]]
`${dateArray[0][valueArray[0]]}/${dateArray[1][valueArray[1]]
}/${day}`
).getDate()
if (realDay < day) {
......@@ -292,7 +308,7 @@ export default {
})
},
methods: {
_show () {
_show (event) {
if (this.disabled) {
return
}
......@@ -301,6 +317,13 @@ export default {
$picker.remove();
(document.querySelector('uni-app') || document.body).appendChild($picker)
$picker.style.display = 'block'
const rect = event.currentTarget.getBoundingClientRect()
this.popover = {
top: rect.top,
left: rect.left,
width: rect.width,
height: rect.height
}
setTimeout(() => {
this.visible = true
}, 20)
......@@ -633,4 +656,35 @@ uni-picker[disabled] {
text-align: center;
transform: translateX(2em);
} */
@media screen and (min-width: 500px) {
.uni-mask.uni-picker-mask {
background: none;
}
.uni-picker-container .uni-picker {
width: 300px;
left: 50%;
right: auto;
top: 50%;
bottom: auto;
transform: translate(-50%, -50%);
opacity: 0;
border-radius: 5px;
transition: opacity 0.3s, visibility 0.3s;
box-shadow: 0px 0 20px 5px rgba(0, 0, 0, 0.3);
}
.uni-picker-container .uni-picker-header {
border-radius: 5px 5px 0 0;
}
.uni-picker-container .uni-picker-content {
/* transform 用于解决 Safari overflow 失效的问题 */
transform: translate(0 0);
overflow: hidden;
border-radius: 0 0 5px 5px;
}
.uni-picker-container .uni-picker.uni-picker-toggle {
opacity: 1;
transform: translate(-50%, -50%);
}
}
</style>
......@@ -49,6 +49,13 @@ const camelizeRE = /-(\w)/g
export const camelize = cached((str) => {
return str.replace(camelizeRE, (_, c) => c ? c.toUpperCase() : '')
})
/**
* Capitalize a string.
*/
export const capitalize = cached((str) => {
return str.charAt(0).toUpperCase() + str.slice(1)
})
export function setProperties (item, props, propsData) {
props.forEach(function (name) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册