提交 ef4f45a7 编写于 作者: fxy060608's avatar fxy060608

feat: add useHover,useFormField,useBooleanAttr

上级 21a0729d
import { defineComponent } from 'vue'
// TODO
// import { hover, emitter, listeners } from '../../mixins'
import { defineComponent, inject } from 'vue'
import { useI18n } from '@dcloudio/uni-core'
import { useHover } from '../../helpers/useHover'
import { useBooleanAttr } from '../../helpers/useBooleanAttr'
import { UniFormCtx, uniFormKey } from '../form'
export default defineComponent({
name: 'Button',
// mixins: [hover, emitter, listeners],
props: {
hoverClass: {
type: String,
default: 'button-hover',
},
disabled: {
type: [Boolean, String],
default: false,
},
id: {
type: String,
default: '',
},
hoverStopPropagation: {
type: Boolean,
default: false,
hoverClass: {
type: String,
default: 'button-hover',
},
hoverStartTime: {
type: [Number, String],
......@@ -29,138 +23,99 @@ export default defineComponent({
type: [Number, String],
default: 70,
},
hoverStopPropagation: {
type: Boolean,
default: false,
},
disabled: {
type: [Boolean, String],
default: false,
},
formType: {
type: String,
default: '',
validator(value: string) {
// 只有这几个可取值,其它都是非法的。
return !!~['', 'submit', 'reset'].indexOf(value)
},
},
openType: {
type: String,
default: '',
},
},
data() {
return {
clickFunction: null,
}
},
setup(props, { slots }) {
// TODO
return () => <uni-button>{slots.default && slots.default()}</uni-button>
},
methods: {
// _onClick($event: unknown, isLabelClick: boolean) {
// if (this.disabled) {
// return
// }
// if (isLabelClick) {
// this.$el.click()
// }
// // TODO 通知父表单执行相应的行为
// if (this.formType) {
// this.$dispatch(
// 'Form',
// this.formType === 'submit' ? 'uni-form-submit' : 'uni-form-reset',
// {
// type: this.formType,
// }
// )
// return
// }
// if (this.openType === 'feedback') {
// const feedback = plus.webview.create(
// 'https://service.dcloud.net.cn/uniapp/feedback.html',
// 'feedback',
// {
// titleNView: {
// titleText: '问题反馈',
// autoBackButton: true,
// backgroundColor: '#F7F7F7',
// titleColor: '#007aff',
// buttons: [
// {
// text: '发送',
// color: '#007aff',
// fontSize: '16px',
// fontWeight: 'bold',
// onclick: function (e) {
// feedback.evalJS(
// 'mui&&mui.trigger(document.getElementById("submit"),"tap")'
// )
// },
// },
// ],
// },
// }
// )
// feedback.show('slide-in-right')
// }
// },
// _bindObjectListeners(data, value) {
// if (value) {
// for (const key in value) {
// const existing = data.on[key]
// const ours = value[key]
// data.on[key] = existing ? [].concat(existing, ours) : ours
// }
// }
// return data
// },
},
// render(createElement) {
// const $listeners = Object.create(null)
// if (this.$listeners) {
// Object.keys(this.$listeners).forEach((e) => {
// if (this.disabled && (e === 'click' || e === 'tap')) {
// return
// }
// $listeners[e] = this.$listeners[e]
// })
// }
// if (this.hoverClass && this.hoverClass !== 'none') {
// return createElement(
// 'uni-button',
// this._bindObjectListeners(
// {
// class: [this.hovering ? this.hoverClass : ''],
// attrs: {
// disabled: this.disabled,
// },
// on: {
// touchstart: this._hoverTouchStart,
// touchend: this._hoverTouchEnd,
// touchcancel: this._hoverTouchCancel,
// click: this._onClick,
// },
// },
// $listeners
// ),
// this.$slots.default
// )
// } else {
// return createElement(
// 'uni-button',
// this._bindObjectListeners(
// {
// class: [this.hovering ? this.hoverClass : ''],
// attrs: {
// disabled: this.disabled,
// },
// on: {
// click: this._onClick,
// },
// },
// $listeners
// ),
// this.$slots.default
// )
// }
// },
listeners: {
'label-click': '_onClick',
'@label-click': '_onClick',
const uniForm = inject<UniFormCtx>(uniFormKey)
const { hovering, binding } = useHover(props)
const { t } = useI18n()
function onClick() {
if (props.disabled) {
return
}
const formType = props.formType
if (formType) {
if (!uniForm) {
return
}
if (formType === 'submit') {
uniForm.submit()
} else if (formType === 'reset') {
uniForm.reset()
}
return
}
if (__PLATFORM__ === 'app-plus' && props.openType === 'feedback') {
openFeedback(
t('uni.button.feedback.title'),
t('uni.button.feedback.send')
)
}
}
return () => {
const hoverClass = props.hoverClass
const booleanAttrs = useBooleanAttr(props, 'disabled')
if (hoverClass && hoverClass !== 'none') {
return (
<uni-button
onClick={onClick}
class={hovering.value ? hoverClass : ''}
{...binding}
{...booleanAttrs}
>
{slots.default && slots.default()}
</uni-button>
)
}
return (
<uni-button onClick={onClick} {...booleanAttrs}>
{slots.default && slots.default()}
</uni-button>
)
}
},
})
function openFeedback(titleText: string, sendText: string) {
const feedback = plus.webview.create(
'https://service.dcloud.net.cn/uniapp/feedback.html',
'feedback',
{
titleNView: {
titleText,
autoBackButton: true,
backgroundColor: '#F7F7F7',
titleColor: '#007aff',
buttons: [
{
text: sendText,
color: '#007aff',
fontSize: '16px',
fontWeight: 'bold',
onclick: function () {
feedback.evalJS(
'mui&&mui.trigger(document.getElementById("submit"),"tap")'
)
},
},
],
},
}
)
feedback.show('slide-in-right')
}
import { PolySymbol } from '@dcloudio/uni-core'
import { defineComponent, provide, SetupContext } from 'vue'
export const uniFormKey = PolySymbol(__DEV__ ? 'uniForm' : 'uf')
export interface UniFormCtx {
addField: (field: UniFormFieldCtx) => void
removeField: (field: UniFormFieldCtx) => void
submit: () => void
reset: () => void
}
interface UniFormFieldCtx {
submit: () => [string, any]
reset: () => void
}
export default defineComponent({
name: 'Form',
setup(props, { slots, emit }) {
provideForm(emit)
return () => (
<uni-form>
<span>{slots.default && slots.default()}</span>
</uni-form>
)
},
})
function provideForm(emit: SetupContext['emit']) {
const fields: UniFormFieldCtx[] = []
provide<UniFormCtx>(uniFormKey, {
addField(field: UniFormFieldCtx) {
fields.push(field)
},
removeField(field: UniFormFieldCtx) {
fields.splice(fields.indexOf(field), 1)
},
submit() {
emit('submit', {
detail: {
value: fields.reduce((res, field) => {
const [name, value] = field.submit()
name && (res[name] = value)
return res
}, Object.create(null)),
},
})
},
reset() {
fields.forEach((field) => field.reset())
emit('reset')
},
})
return fields
}
<template>
<uni-form v-bind="$attrs">
<span>
<slot />
</span>
</uni-form>
</template>
<script>
import {
listeners
} from '../../mixins'
export default {
name: 'Form',
mixins: [listeners],
data () {
return {
childrenList: []
}
},
listeners: {
'@form-submit': '_onSubmit',
'@form-reset': '_onReset',
'@form-group-update': '_formGroupUpdateHandler'
},
methods: {
_onSubmit ($event) {
const data = {}
this.childrenList.forEach(vm => {
if (vm._getFormData && vm._getFormData().key) {
data[vm._getFormData().key] = vm._getFormData().value
}
})
this.$trigger('submit', $event, {
value: data
})
},
_onReset ($event) {
this.$trigger('reset', $event, {})
this.childrenList.forEach(vm => {
vm._resetFormData && vm._resetFormData()
})
},
_formGroupUpdateHandler ($event) {
if ($event.type === 'add') {
this.childrenList.push($event.vm)
} else {
const index = this.childrenList.indexOf($event.vm)
this.childrenList.splice(index, 1)
}
}
}
}
</script>
<style>
</style>
......@@ -4,7 +4,7 @@ import Canvas from './canvas/index.vue'
import Checkbox from './checkbox/index.vue'
import CheckboxGroup from './checkbox-group/index.vue'
import Editor from './editor/index.vue'
import Form from './form/index.vue'
import Form from './form/index'
import Icon from './icon/index'
import Image from './image/index.vue'
import Input from './input/index.vue'
......@@ -26,7 +26,7 @@ import SwiperItem from './swiper-item/index.vue'
import Switch from './switch/index.vue'
import Text from './text/index'
import Textarea from './textarea/index.vue'
import View from './view/index.vue'
import View from './view/index'
export {
Audio,
Button,
......
<template>
<uni-input
@change.stop
v-bind="$attrs"
>
<div
ref="wrapper"
class="uni-input-wrapper"
>
<uni-input @change.stop v-bind="$attrs">
<div ref="wrapper" class="uni-input-wrapper">
<div
v-show="!(composing || valueSync.length)"
ref="placeholder"
......@@ -31,11 +25,13 @@
@compositionstart="_onComposition"
@compositionend="_onComposition"
@keyup.stop="_onKeyup"
>
/>
</div>
</uni-input>
</template>
<script>
import { getCurrentInstance } from 'vue'
import { useFormField } from '../../helpers/useFormField'
import {
baseInput
} from '../../mixins'
......@@ -86,7 +82,7 @@ export default {
default: 'done'
}
},
data () {
data() {
return {
composing: false,
wrapperHeight: 0,
......@@ -94,7 +90,7 @@ export default {
}
},
computed: {
inputType: function () {
inputType: function() {
let type = ''
switch (this.type) {
case 'text':
......@@ -113,31 +109,28 @@ export default {
}
return this.password ? 'password' : type
},
step () {
step() {
// 处理部分设备中无法输入小数点的问题
return ~NUMBER_TYPES.indexOf(this.type) ? '0.000000000000000001' : ''
}
},
watch: {
focus (val) {
focus(val) {
this.$refs.input && this.$refs.input[val ? 'focus' : 'blur']()
},
maxlength (value) {
maxlength(value) {
const realValue = this.valueSync.slice(0, parseInt(value, 10))
realValue !== this.valueSync && (this.valueSync = realValue)
}
},
created () {
this.$dispatch('Form', 'uni-form-group-update', {
type: 'add',
vm: this
})
setup() {
useFormField('name', 'valueSync')
},
mounted () {
mounted() {
if (this.confirmType === 'search') {
const formElem = document.createElement('form')
formElem.action = ''
formElem.onsubmit = function () {
formElem.onsubmit = function() {
return false
}
formElem.className = 'uni-input-form'
......@@ -145,32 +138,30 @@ export default {
this.$refs.wrapper.appendChild(formElem)
}
let $vm = this
while ($vm) {
const scopeId = $vm.$options._scopeId
if (scopeId) {
this.$refs.placeholder.setAttribute(scopeId, '')
}
$vm = $vm.$parent
const instance = getCurrentInstance()
if (instance && instance.vnode.scopeId) {
this.$refs.placeholder.setAttribute(instance.vnode.scopeId, '')
}
// let $vm = this
// while ($vm) {
// const scopeId = $vm.$options._scopeId
// if (scopeId) {
// this.$refs.placeholder.setAttribute(scopeId, '')
// }
// $vm = $vm.$parent
// }
this.initKeyboard(this.$refs.input)
},
beforeDestroy () {
this.$dispatch('Form', 'uni-form-group-update', {
type: 'remove',
vm: this
})
},
methods: {
_onKeyup ($event) {
_onKeyup($event) {
if ($event.keyCode === 13) {
this.$trigger('confirm', $event, {
value: $event.target.value
})
}
},
_onInput ($event) {
_onInput($event) {
if (this.composing) {
return
}
......@@ -201,27 +192,27 @@ export default {
value: this.valueSync
})
},
_onFocus ($event) {
_onFocus($event) {
this.$trigger('focus', $event, {
value: $event.target.value
})
},
_onBlur ($event) {
_onBlur($event) {
this.$trigger('blur', $event, {
value: $event.target.value
})
},
_onComposition ($event) {
_onComposition($event) {
if ($event.type === 'compositionstart') {
this.composing = true
} else {
this.composing = false
}
},
_resetFormData () {
_resetFormData() {
this.valueSync = ''
},
_getFormData () {
_getFormData() {
return this.name ? {
value: this.valueSync,
key: this.name
......
import { extend } from '@vue/shared'
import { defineComponent } from 'vue'
import { hoverProps, useHover } from '../../helpers/useHover'
export default defineComponent({
name: 'View',
props: extend({}, hoverProps),
setup(props, { slots }) {
const { hovering, binding } = useHover(props)
return () => {
const hoverClass = props.hoverClass
if (hoverClass && hoverClass !== 'none') {
return (
<uni-view class={hovering.value ? hoverClass : ''} {...binding}>
{slots.default && slots.default()}
</uni-view>
)
}
return <uni-view>{slots.default && slots.default()}</uni-view>
}
},
})
<template>
<uni-view
v-if="hoverClass && hoverClass !== 'none'"
:class="[hovering ? hoverClass : '']"
@touchstart="_hoverTouchStart"
@touchend="_hoverTouchEnd"
@touchcancel="_hoverTouchCancel"
>
<slot />
</uni-view>
<uni-view v-else>
<slot />
</uni-view>
</template>
<script>
import hover from '../../mixins/hover'
export default {
name: 'View',
mixins: [hover],
listeners: {
'label-click': 'clickHandler',
},
}
</script>
import { isString } from '@vue/shared'
export function useBooleanAttr(
props: Record<string, any>,
keys: string | string[]
) {
if (isString(keys)) {
keys = [keys]
}
return keys.reduce<Record<string, boolean>>((res, key) => {
if (props[key]) {
res[key] = true
}
return res
}, Object.create(null))
}
import { getCurrentInstance, inject, onBeforeUnmount, withScopeId } from 'vue'
import { UniFormCtx, uniFormKey } from '../components/form'
export function useFormField(nameKey: string, valueKey: string) {
const uniForm = inject<UniFormCtx>(uniFormKey)
if (!uniForm) {
return
}
const instance = getCurrentInstance()!
const ctx = {
submit(): [string, any] {
const proxy = instance.proxy
return [(proxy as any)[nameKey], (proxy as any)[valueKey]]
},
reset() {
;(instance.proxy as any)[valueKey] = ''
},
}
uniForm.addField(ctx)
onBeforeUnmount(() => {
uniForm.removeField(ctx)
})
}
import { ref } from 'vue'
interface UseHoverOptions {
disabled?: string | boolean
hoverClass: string
hoverStopPropagation: boolean
hoverStartTime: string | number
hoverStayTime: string | number
}
export const hoverProps = {
hoverClass: {
type: String,
default: 'none',
},
hoverStopPropagation: {
type: Boolean,
default: false,
},
hoverStartTime: {
type: [Number, String],
default: 50,
},
hoverStayTime: {
type: [Number, String],
default: 400,
},
}
export function useHover(props: UseHoverOptions) {
const hovering = ref(false)
let hoverTouch: boolean = false
let hoverStartTimer: number
let hoverStayTimer: number
function hoverReset() {
requestAnimationFrame(() => {
clearTimeout(hoverStayTimer)
hoverStayTimer = setTimeout(() => {
hovering.value = false
}, parseInt(props.hoverStayTime as string))
})
}
function onTouchstart(evt: TouchEvent) {
// TODO detect scrolling
if ((evt as any)._hoverPropagationStopped) {
return
}
if (!props.hoverClass || props.hoverClass === 'none' || props.disabled) {
return
}
if (evt.touches.length > 1) {
return
}
if (props.hoverStopPropagation) {
;(evt as any)._hoverPropagationStopped = true
}
hoverTouch = true
hoverStartTimer = setTimeout(() => {
hovering.value = true
if (!hoverTouch) {
// 防止在hoverStartTime时间内触发了 touchend 或 touchcancel
hoverReset()
}
}, parseInt(props.hoverStartTime as string))
}
function onTouchend() {
hoverTouch = false
if (hovering.value) {
hoverReset()
}
}
function onTouchcancel() {
hoverTouch = false
hovering.value = false
clearTimeout(hoverStartTimer)
}
return {
hovering,
binding: {
onTouchstart,
onTouchend,
onTouchcancel,
},
}
}
uni-canvas {
width: 300px;
height: 150px;
display: block;
position: relative;
}
uni-canvas > canvas {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
uni-checkbox-group[hidden] {
display: none;
}
.ql-container {
display: block;
position: relative;
box-sizing: border-box;
-webkit-user-select: text;
user-select: text;
outline: none;
overflow: hidden;
width: 100%;
height: 200px;
min-height: 200px;
}
.ql-container[hidden] {
display: none;
}
.ql-container .ql-editor {
position: relative;
font-size: inherit;
line-height: inherit;
font-family: inherit;
min-height: inherit;
width: 100%;
height: 100%;
padding: 0;
overflow-x: hidden;
overflow-y: auto;
-webkit-tap-highlight-color: transparent;
-webkit-touch-callout: none;
-webkit-overflow-scrolling: touch;
}
.ql-container .ql-editor::-webkit-scrollbar {
width: 0 !important;
}
.ql-container .ql-editor.scroll-disabled {
overflow: hidden;
}
.ql-container .ql-image-overlay {
display: flex;
position: absolute;
box-sizing: border-box;
border: 1px dashed #ccc;
justify-content: center;
align-items: center;
-webkit-user-select: none;
user-select: none;
}
.ql-container .ql-image-overlay .ql-image-size {
position: absolute;
padding: 4px 8px;
text-align: center;
background-color: #fff;
color: #888;
border: 1px solid #ccc;
box-sizing: border-box;
opacity: 0.8;
right: 4px;
top: 4px;
font-size: 12px;
display: inline-block;
width: auto;
}
.ql-container .ql-image-overlay .ql-image-toolbar {
position: relative;
text-align: center;
box-sizing: border-box;
background: #000;
border-radius: 5px;
color: #fff;
font-size: 0;
min-height: 24px;
z-index: 100;
}
.ql-container .ql-image-overlay .ql-image-toolbar span {
display: inline-block;
cursor: pointer;
padding: 5px;
font-size: 12px;
border-right: 1px solid #fff;
}
.ql-container .ql-image-overlay .ql-image-toolbar span:last-child {
border-right: 0;
}
.ql-container .ql-image-overlay .ql-image-toolbar span.triangle-up {
padding: 0;
position: absolute;
top: -12px;
left: 50%;
transform: translatex(-50%);
width: 0;
height: 0;
border-width: 6px;
border-style: solid;
border-color: transparent transparent black transparent;
}
.ql-container .ql-image-overlay .ql-image-handle {
position: absolute;
height: 12px;
width: 12px;
border-radius: 50%;
border: 1px solid #ccc;
box-sizing: border-box;
background: #fff;
}
.ql-container img {
display: inline-block;
max-width: 100%;
}
.ql-clipboard p {
margin: 0;
padding: 0;
}
.ql-editor {
box-sizing: border-box;
height: 100%;
outline: none;
overflow-y: auto;
tab-size: 4;
-moz-tab-size: 4;
text-align: left;
white-space: pre-wrap;
word-wrap: break-word;
}
.ql-editor > * {
cursor: text;
}
.ql-editor p,
.ql-editor ol,
.ql-editor ul,
.ql-editor pre,
.ql-editor blockquote,
.ql-editor h1,
.ql-editor h2,
.ql-editor h3,
.ql-editor h4,
.ql-editor h5,
.ql-editor h6 {
margin: 0;
padding: 0;
counter-reset: list-1 list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9;
}
.ql-editor ol > li,
.ql-editor ul > li {
list-style-type: none;
}
.ql-editor ul > li::before {
content: '\2022';
}
.ql-editor ul[data-checked=true],
.ql-editor ul[data-checked=false] {
pointer-events: none;
}
.ql-editor ul[data-checked=true] > li *,
.ql-editor ul[data-checked=false] > li * {
pointer-events: all;
}
.ql-editor ul[data-checked=true] > li::before,
.ql-editor ul[data-checked=false] > li::before {
color: #777;
cursor: pointer;
pointer-events: all;
}
.ql-editor ul[data-checked=true] > li::before {
content: '\2611';
}
.ql-editor ul[data-checked=false] > li::before {
content: '\2610';
}
.ql-editor li::before {
display: inline-block;
white-space: nowrap;
width: 2em;
}
.ql-editor ol li {
counter-reset: list-1 list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9;
counter-increment: list-0;
}
.ql-editor ol li:before {
content: counter(list-0, decimal) '. ';
}
.ql-editor ol li.ql-indent-1 {
counter-increment: list-1;
}
.ql-editor ol li.ql-indent-1:before {
content: counter(list-1, lower-alpha) '. ';
}
.ql-editor ol li.ql-indent-1 {
counter-reset: list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9;
}
.ql-editor ol li.ql-indent-2 {
counter-increment: list-2;
}
.ql-editor ol li.ql-indent-2:before {
content: counter(list-2, lower-roman) '. ';
}
.ql-editor ol li.ql-indent-2 {
counter-reset: list-3 list-4 list-5 list-6 list-7 list-8 list-9;
}
.ql-editor ol li.ql-indent-3 {
counter-increment: list-3;
}
.ql-editor ol li.ql-indent-3:before {
content: counter(list-3, decimal) '. ';
}
.ql-editor ol li.ql-indent-3 {
counter-reset: list-4 list-5 list-6 list-7 list-8 list-9;
}
.ql-editor ol li.ql-indent-4 {
counter-increment: list-4;
}
.ql-editor ol li.ql-indent-4:before {
content: counter(list-4, lower-alpha) '. ';
}
.ql-editor ol li.ql-indent-4 {
counter-reset: list-5 list-6 list-7 list-8 list-9;
}
.ql-editor ol li.ql-indent-5 {
counter-increment: list-5;
}
.ql-editor ol li.ql-indent-5:before {
content: counter(list-5, lower-roman) '. ';
}
.ql-editor ol li.ql-indent-5 {
counter-reset: list-6 list-7 list-8 list-9;
}
.ql-editor ol li.ql-indent-6 {
counter-increment: list-6;
}
.ql-editor ol li.ql-indent-6:before {
content: counter(list-6, decimal) '. ';
}
.ql-editor ol li.ql-indent-6 {
counter-reset: list-7 list-8 list-9;
}
.ql-editor ol li.ql-indent-7 {
counter-increment: list-7;
}
.ql-editor ol li.ql-indent-7:before {
content: counter(list-7, lower-alpha) '. ';
}
.ql-editor ol li.ql-indent-7 {
counter-reset: list-8 list-9;
}
.ql-editor ol li.ql-indent-8 {
counter-increment: list-8;
}
.ql-editor ol li.ql-indent-8:before {
content: counter(list-8, lower-roman) '. ';
}
.ql-editor ol li.ql-indent-8 {
counter-reset: list-9;
}
.ql-editor ol li.ql-indent-9 {
counter-increment: list-9;
}
.ql-editor ol li.ql-indent-9:before {
content: counter(list-9, decimal) '. ';
}
.ql-editor .ql-indent-1:not(.ql-direction-rtl) {
padding-left: 2em;
}
.ql-editor li.ql-indent-1:not(.ql-direction-rtl) {
padding-left: 2em;
}
.ql-editor .ql-indent-1.ql-direction-rtl.ql-align-right {
padding-right: 2em;
}
.ql-editor li.ql-indent-1.ql-direction-rtl.ql-align-right {
padding-right: 2em;
}
.ql-editor .ql-indent-2:not(.ql-direction-rtl) {
padding-left: 4em;
}
.ql-editor li.ql-indent-2:not(.ql-direction-rtl) {
padding-left: 4em;
}
.ql-editor .ql-indent-2.ql-direction-rtl.ql-align-right {
padding-right: 4em;
}
.ql-editor li.ql-indent-2.ql-direction-rtl.ql-align-right {
padding-right: 4em;
}
.ql-editor .ql-indent-3:not(.ql-direction-rtl) {
padding-left: 6em;
}
.ql-editor li.ql-indent-3:not(.ql-direction-rtl) {
padding-left: 6em;
}
.ql-editor .ql-indent-3.ql-direction-rtl.ql-align-right {
padding-right: 6em;
}
.ql-editor li.ql-indent-3.ql-direction-rtl.ql-align-right {
padding-right: 6em;
}
.ql-editor .ql-indent-4:not(.ql-direction-rtl) {
padding-left: 8em;
}
.ql-editor li.ql-indent-4:not(.ql-direction-rtl) {
padding-left: 8em;
}
.ql-editor .ql-indent-4.ql-direction-rtl.ql-align-right {
padding-right: 8em;
}
.ql-editor li.ql-indent-4.ql-direction-rtl.ql-align-right {
padding-right: 8em;
}
.ql-editor .ql-indent-5:not(.ql-direction-rtl) {
padding-left: 10em;
}
.ql-editor li.ql-indent-5:not(.ql-direction-rtl) {
padding-left: 10em;
}
.ql-editor .ql-indent-5.ql-direction-rtl.ql-align-right {
padding-right: 10em;
}
.ql-editor li.ql-indent-5.ql-direction-rtl.ql-align-right {
padding-right: 10em;
}
.ql-editor .ql-indent-6:not(.ql-direction-rtl) {
padding-left: 12em;
}
.ql-editor li.ql-indent-6:not(.ql-direction-rtl) {
padding-left: 12em;
}
.ql-editor .ql-indent-6.ql-direction-rtl.ql-align-right {
padding-right: 12em;
}
.ql-editor li.ql-indent-6.ql-direction-rtl.ql-align-right {
padding-right: 12em;
}
.ql-editor .ql-indent-7:not(.ql-direction-rtl) {
padding-left: 14em;
}
.ql-editor li.ql-indent-7:not(.ql-direction-rtl) {
padding-left: 14em;
}
.ql-editor .ql-indent-7.ql-direction-rtl.ql-align-right {
padding-right: 14em;
}
.ql-editor li.ql-indent-7.ql-direction-rtl.ql-align-right {
padding-right: 14em;
}
.ql-editor .ql-indent-8:not(.ql-direction-rtl) {
padding-left: 16em;
}
.ql-editor li.ql-indent-8:not(.ql-direction-rtl) {
padding-left: 16em;
}
.ql-editor .ql-indent-8.ql-direction-rtl.ql-align-right {
padding-right: 16em;
}
.ql-editor li.ql-indent-8.ql-direction-rtl.ql-align-right {
padding-right: 16em;
}
.ql-editor .ql-indent-9:not(.ql-direction-rtl) {
padding-left: 18em;
}
.ql-editor li.ql-indent-9:not(.ql-direction-rtl) {
padding-left: 18em;
}
.ql-editor .ql-indent-9.ql-direction-rtl.ql-align-right {
padding-right: 18em;
}
.ql-editor li.ql-indent-9.ql-direction-rtl.ql-align-right {
padding-right: 18em;
}
.ql-editor .ql-direction-rtl {
direction: rtl;
text-align: inherit;
}
.ql-editor .ql-align-center {
text-align: center;
}
.ql-editor .ql-align-justify {
text-align: justify;
}
.ql-editor .ql-align-right {
text-align: right;
}
.ql-editor.ql-blank::before {
color: rgba(0, 0, 0, 0.6);
content: attr(data-placeholder);
font-style: italic;
pointer-events: none;
position: absolute;
}
.ql-container.ql-disabled .ql-editor ul[data-checked] > li::before {
pointer-events: none;
}
.ql-clipboard {
left: -100000px;
height: 1px;
overflow-y: hidden;
position: absolute;
top: 50%;
}
@keyframes once-show {
from {
top: 0;
}
}
uni-resize-sensor,
uni-resize-sensor > div {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
overflow: hidden;
}
uni-resize-sensor {
display: block;
z-index: -1;
visibility: hidden;
animation: once-show 1ms;
}
uni-resize-sensor > div > div {
position: absolute;
left: 0;
top: 0;
}
uni-resize-sensor > div:first-child > div {
width: 100000px;
height: 100000px;
}
uni-resize-sensor > div:last-child > div {
width: 200%;
height: 200%;
}
.uni-label-pointer {
cursor: pointer;
}
uni-movable-view {
display: inline-block;
width: 10px;
height: 10px;
top: 0px;
left: 0px;
position: absolute;
cursor: grab;
}
uni-movable-view[hidden] {
display: none;
}
uni-radio {
-webkit-tap-highlight-color: transparent;
display: inline-block;
cursor: pointer;
}
uni-radio[hidden] {
display: none;
}
uni-radio[disabled] {
cursor: not-allowed;
}
uni-radio .uni-radio-wrapper {
display: -webkit-inline-flex;
display: inline-flex;
-webkit-align-items: center;
align-items: center;
vertical-align: middle;
}
uni-radio .uni-radio-input {
-webkit-appearance: none;
appearance: none;
margin-right: 5px;
outline: 0;
border: 1px solid #D1D1D1;
background-color: #ffffff;
border-radius: 50%;
width: 22px;
height: 22px;
position: relative;
}
uni-radio:not([disabled]) .uni-radio-input:hover {
border-color: #007aff;
}
uni-radio .uni-radio-input.uni-radio-input-checked:before {
font: normal normal normal 14px/1 "uni";
content: "\EA08";
color: #ffffff;
font-size: 18px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -48%) scale(0.73);
-webkit-transform: translate(-50%, -48%) scale(0.73);
}
uni-radio .uni-radio-input.uni-radio-input-disabled {
background-color: #E1E1E1;
border-color: #D1D1D1;
}
uni-radio .uni-radio-input.uni-radio-input-disabled:before {
color: #ADADAD;
}
uni-radio-group {
display: block;
}
uni-radio-group[hidden] {
display: none;
}
uni-swiper-item {
display: block;
overflow: hidden;
will-change: transform;
position: absolute;
width: 100%;
height: 100%;
cursor: grab;
}
uni-swiper-item[hidden] {
display: none;
}
uni-switch {
-webkit-tap-highlight-color: transparent;
display: inline-block;
cursor: pointer;
}
uni-switch[hidden] {
display: none;
}
uni-switch[disabled] {
cursor: not-allowed;
}
uni-switch .uni-switch-wrapper {
display: -webkit-inline-flex;
display: inline-flex;
-webkit-align-items: center;
align-items: center;
vertical-align: middle;
}
uni-switch .uni-switch-input {
-webkit-appearance: none;
appearance: none;
position: relative;
width: 52px;
height: 32px;
margin-right: 5px;
border: 1px solid #DFDFDF;
outline: 0;
border-radius: 16px;
box-sizing: border-box;
background-color: #DFDFDF;
transition: background-color 0.1s, border 0.1s;
}
uni-switch[disabled] .uni-switch-input {
opacity: .7;
}
uni-switch .uni-switch-input:before {
content: " ";
position: absolute;
top: 0;
left: 0;
width: 50px;
height: 30px;
border-radius: 15px;
background-color: #FDFDFD;
transition: -webkit-transform 0.3s;
transition: transform 0.3s;
transition: transform 0.3s, -webkit-transform 0.3s;
}
uni-switch .uni-switch-input:after {
content: " ";
position: absolute;
top: 0;
left: 0;
width: 30px;
height: 30px;
border-radius: 15px;
background-color: #FFFFFF;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
transition: -webkit-transform 0.3s;
transition: transform 0.3s;
transition: transform 0.3s, -webkit-transform 0.3s;
}
uni-switch .uni-switch-input.uni-switch-input-checked {
border-color: #007aff;
background-color: #007aff;
}
uni-switch .uni-switch-input.uni-switch-input-checked:before {
-webkit-transform: scale(0);
transform: scale(0);
}
uni-switch .uni-switch-input.uni-switch-input-checked:after {
-webkit-transform: translateX(20px);
transform: translateX(20px);
}
uni-switch .uni-checkbox-input {
margin-right: 5px;
-webkit-appearance: none;
appearance: none;
outline: 0;
border: 1px solid #D1D1D1;
background-color: #FFFFFF;
border-radius: 3px;
width: 22px;
height: 22px;
position: relative;
color: #007aff;
}
uni-switch:not([disabled]) .uni-checkbox-input:hover {
border-color: #007aff;
}
uni-switch .uni-checkbox-input.uni-checkbox-input-checked:before {
font: normal normal normal 14px/1 "uni";
content: "\EA08";
color: inherit;
font-size: 22px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -48%) scale(0.73);
-webkit-transform: translate(-50%, -48%) scale(0.73);
}
uni-switch .uni-checkbox-input.uni-checkbox-input-disabled {
background-color: #E1E1E1;
}
uni-switch .uni-checkbox-input.uni-checkbox-input-disabled:before {
color: #ADADAD;
}
uni-textarea {
width: 300px;
height: 150px;
display: block;
position: relative;
font-size: 16px;
line-height: normal;
white-space: pre-wrap;
word-break: break-all;
}
uni-textarea[hidden] {
display: none;
}
.uni-textarea-wrapper,
.uni-textarea-placeholder,
.uni-textarea-line,
.uni-textarea-compute,
.uni-textarea-textarea {
outline: none;
border: none;
padding: 0;
margin: 0;
text-decoration: inherit;
}
.uni-textarea-wrapper {
display: block;
position: relative;
width: 100%;
height: 100%;
}
.uni-textarea-placeholder,
.uni-textarea-line,
.uni-textarea-compute,
.uni-textarea-textarea {
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
white-space: inherit;
word-break: inherit;
}
.uni-textarea-placeholder {
color: grey;
overflow: hidden;
}
.uni-textarea-line,
.uni-textarea-compute {
visibility: hidden;
height: auto;
}
.uni-textarea-line {
width: 1em;
}
.uni-textarea-textarea {
resize: none;
background: none;
color: inherit;
opacity: 1;
-webkit-text-fill-color: currentcolor;
font: inherit;
line-height: inherit;
letter-spacing: inherit;
text-align: inherit;
text-indent: inherit;
text-transform: inherit;
text-shadow: inherit;
}
/* 用于解决 iOS textarea 内部默认边距 */
.uni-textarea-textarea-fix-margin {
width: auto;
right: 0;
margin: 0 -3px;
}
.uni-async-error {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
color: #999;
padding: 100px 10px;
text-align: center;
}
.uni-async-loading {
box-sizing: border-box;
width: 100%;
padding: 50px;
text-align: center;
}
.uni-async-loading .uni-loading {
width: 30px;
height: 30px;
}
此差异已折叠。
......@@ -80,10 +80,11 @@ export default defineConfig({
plugins: [
replace({
values: {
createOnApi: `/*#__PURE__*/ createOnApi`,
createTaskApi: `/*#__PURE__*/ createTaskApi`,
createSyncApi: `/*#__PURE__*/ createSyncApi`,
createAsyncApi: `/*#__PURE__*/ createAsyncApi`,
defineOnApi: `/*#__PURE__*/ defineOnApi`,
defineOffApi: `/*#__PURE__*/ defineOffApi`,
defineTaskApi: `/*#__PURE__*/ defineTaskApi`,
defineSyncApi: `/*#__PURE__*/ defineSyncApi`,
defineAsyncApi: `/*#__PURE__*/ defineAsyncApi`,
},
preventAssignment: true,
}),
......
......@@ -7,6 +7,7 @@ export function createResolve(
return {
alias: {
'@': options.inputDir,
'~@': options.inputDir, // src: url('~@/static/uni.ttf') format('truetype');
vue: '@dcloudio/uni-h5-vue',
},
}
......
......@@ -7,6 +7,16 @@ import { EXTNAME_VUE, parseVueRequest } from '@dcloudio/uni-cli-shared'
import { UniPluginFilterOptions } from '.'
const debugScoped = debug('uni:scoped')
const SCOPED_RE = /<style\s[^>]*scoped[^>]*>/gi
function addScoped(code: string) {
if (SCOPED_RE.test(code)) {
return code
}
return code.replace(/(<style\b[^><]*)>/gi, '$1 scoped>')
}
export function uniCssScopedPlugin(options: UniPluginFilterOptions): Plugin {
const filter = createFilter(options.include, options.exclude)
return {
......@@ -22,10 +32,21 @@ export function uniCssScopedPlugin(options: UniPluginFilterOptions): Plugin {
if (EXTNAME_VUE.includes(path.extname(filename))) {
debugScoped(id)
return {
code: code.replace(/(<style\b[^><]*)>/gi, '$1 scoped>'),
code: addScoped(code),
map: this.getCombinedSourcemap(),
}
}
},
handleHotUpdate(ctx) {
if (!EXTNAME_VUE.includes(path.extname(ctx.file))) {
return
}
debugScoped('hmr', ctx.file)
const oldRead = ctx.read
ctx.read = async () => {
const code = await oldRead()
return addScoped(code)
}
},
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册