增加app模板和代码生成

This commit is contained in:
xiangheng
2024-06-04 00:41:55 +08:00
parent 3ea0b9ad5d
commit 89eb9ccc72
916 changed files with 97550 additions and 9 deletions

View File

@@ -0,0 +1,132 @@
@import "./../common/abstracts/_mixin.scss";
@import "./../common/abstracts/variable.scss";
.wot-theme-dark {
@include b(input-number) {
@include e(action) {
color: $-dark-color;
@include when(disabled) {
color: $-dark-color-gray;
}
}
@include e(input) {
color: $-dark-color;
}
@include when(disabled) {
.wd-input-number__input {
color: $-dark-color-gray;
}
.wd-input-number__sub,
.wd-input-number__add {
color: $-dark-color-gray;
}
}
}
}
@include b(input-number) {
display: inline-block;
user-select: none;
line-height: 1.15;
@include e(action) {
position: relative;
display: inline-block;
width: $-input-number-btn-width;
height: $-input-number-height;
vertical-align: middle;
color: $-input-number-icon-color;
-webkit-tap-highlight-color: transparent;
box-sizing: border-box;
// 左右加减号的边框
&::after {
position: absolute;
content: "";
width: calc(200% - 2px);
height: calc(200% - 2px);
left: 0;
top: 0;
border: 1px solid $-input-number-border-color;
border-top-left-radius: calc($-input-number-radius * 2);
border-bottom-left-radius: calc($-input-number-radius * 2);
transform: scale(0.5);
transform-origin: left top;
}
&:last-child::after {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
border-top-right-radius: calc($-input-number-radius * 2);
border-bottom-right-radius: calc($-input-number-radius * 2);
}
@include when(disabled) {
color: $-input-number-disabled-color;
}
}
@include e(inner) {
position: relative;
display: inline-block;
vertical-align: middle;
}
@include e(input) {
position: relative;
display: block;
width: $-input-number-input-width;
height: $-input-number-height;
padding: 0 2px;
box-sizing: border-box;
z-index: 1;
background: transparent;
border: none;
outline: none;
text-align: center;
color: $-input-number-color;
font-size: $-input-number-fs;
-webkit-appearance: none;
-webkit-tap-highlight-color: transparent;
}
@include e(input-border) {
position: absolute;
width: 100%;
height: calc(200% - 2px);
left: 0;
top: 0;
border-top: 1px solid $-input-number-border-color;
border-bottom: 1px solid $-input-number-border-color;
transform: scaleY(0.5);
transform-origin: left top;
z-index: 0;
}
@include edeep(action-icon) {
position: absolute;
display: inline-block;
font-size: $-input-number-icon-size;
width: $-input-number-icon-size;
height: $-input-number-icon-size;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
@include when(disabled) {
.wd-input-number__input {
color: $-input-number-disabled-color;
z-index: inherit;
}
.wd-input-number__sub,
.wd-input-number__add {
color: $-input-number-disabled-color;
}
}
@include when(without-input) {
.wd-input-number__action:last-child::after {
border-left: none;
}
}
}

View File

@@ -0,0 +1,70 @@
/*
* @Author: weisheng
* @Date: 2024-03-15 20:40:34
* @LastEditTime: 2024-03-18 14:58:47
* @LastEditors: weisheng
* @Description:
* @FilePath: \wot-design-uni\src\uni_modules\wot-design-uni\components\wd-input-number\types.ts
* 记得注释
*/
import { baseProps, makeBooleanProp, makeNumberProp, makeNumericProp, makeRequiredProp, makeStringProp, numericProp } from '../common/props'
export const inputNumberProps = {
...baseProps,
/**
* 绑定值
*/
modelValue: makeRequiredProp(numericProp),
/**
* 最小值
*/
min: makeNumberProp(1),
/**
* 最大值
*/
max: makeNumberProp(Number.MAX_SAFE_INTEGER),
/**
* 步进值
*/
step: makeNumberProp(1),
/**
* 是否严格按照步进值递增或递减
*/
stepStrictly: makeBooleanProp(false),
/**
* 数值精度
*/
precision: makeNumberProp(0),
/**
* 是否禁用
*/
disabled: makeBooleanProp(false),
/**
* 是否禁用输入框
*/
disableInput: makeBooleanProp(false),
/**
* 是否禁用减号按钮
*/
disableMinus: makeBooleanProp(false),
/**
* 是否禁用加号按钮
*/
disablePlus: makeBooleanProp(false),
/**
* 是否不显示输入框
*/
withoutInput: makeBooleanProp(false),
/**
* 输入框宽度
*/
inputWidth: makeNumericProp(36),
/**
* 是否允许为空
*/
allowNull: makeBooleanProp(false),
/**
* 输入框占位符
*/
placeholder: makeStringProp('')
}

View File

@@ -0,0 +1,208 @@
<template>
<view :class="`wd-input-number ${customClass} ${disabled ? 'is-disabled' : ''} ${withoutInput ? 'is-without-input' : ''}`" :style="customStyle">
<view :class="`wd-input-number__action ${minDisabled || disableMinus ? 'is-disabled' : ''}`" @click="sub">
<wd-icon name="decrease" custom-class="wd-input-number__action-icon"></wd-icon>
</view>
<view v-if="!withoutInput" class="wd-input-number__inner" @click.stop="">
<input
class="wd-input-number__input"
:style="`${inputWidth ? 'width: ' + inputWidth : ''}`"
type="digit"
:disabled="disabled || disableInput"
v-model="inputValue"
:placeholder="placeholder"
@input="handleInput"
@focus="handleFocus"
@blur="handleBlur"
/>
<view class="wd-input-number__input-border"></view>
</view>
<view :class="`wd-input-number__action ${maxDisabled || disablePlus ? 'is-disabled' : ''}`" @click="add">
<wd-icon name="add" custom-class="wd-input-number__action-icon"></wd-icon>
</view>
</view>
</template>
<script lang="ts">
export default {
name: 'wd-input-number',
options: {
virtualHost: true,
addGlobalClass: true,
styleIsolation: 'shared'
}
}
</script>
<script lang="ts" setup>
import { ref, watch } from 'vue'
import { debounce, isDef, isEqual } from '../common/util'
import { inputNumberProps } from './types'
const props = defineProps(inputNumberProps)
const emit = defineEmits(['focus', 'blur', 'change', 'update:modelValue'])
const minDisabled = ref<boolean>(false)
const maxDisabled = ref<boolean>(false)
const inputValue = ref<string | number>('') // 输入框的值
watch(
() => props.modelValue,
(newValue) => {
inputValue.value = newValue
splitDisabled(newValue)
},
{ immediate: true, deep: true }
)
watch(
[() => props.max, () => props.min],
() => {
updateBoundary()
},
{ immediate: true, deep: true }
)
watch(
() => props.disabled,
(newValue) => {
minDisabled.value = newValue
maxDisabled.value = newValue
},
{ immediate: true, deep: true }
)
function updateBoundary() {
debounce(() => {
const value = formatValue(inputValue.value)
if (!isEqual(inputValue.value, value)) {
setValue(value)
}
splitDisabled(value)
}, 30)()
}
function splitDisabled(value: number | string) {
const { disabled, min, max, step } = props
minDisabled.value = disabled || Number(value) <= min || changeStep(value, -step) < min
maxDisabled.value = disabled || Number(value) >= max || changeStep(value, step) > max
}
function toPrecision(value: number) {
return Number(parseFloat(`${Math.round(value * Math.pow(10, props.precision)) / Math.pow(10, props.precision)}`).toFixed(props.precision))
}
function getPrecision(value?: number) {
if (value === undefined) return 0
const valueString = value.toString()
const dotPosition = valueString.indexOf('.')
let precision = 0
if (dotPosition !== -1) {
precision = valueString.length - dotPosition - 1
}
return precision
}
function toStrictlyStep(value: number | string) {
const stepPrecision = getPrecision(props.step)
const precisionFactory = Math.pow(10, stepPrecision)
return (Math.round(Number(value) / props.step) * precisionFactory * props.step) / precisionFactory
}
function setValue(value: string | number, change: boolean = true) {
if (props.allowNull && (!isDef(value) || value === '')) {
dispatchChangeEvent(value, change)
return
}
if (props.stepStrictly) {
value = toStrictlyStep(value)
}
if ((value || value === 0) && props.precision !== undefined) {
value = toPrecision(Number(value))
}
if (Number(value) > props.max) value = toPrecision(props.max)
if (Number(value) < props.min) value = toPrecision(props.min)
dispatchChangeEvent(value, change)
}
function changeStep(val: string | number, step: number) {
val = Number(val)
if (isNaN(val)) {
return props.min
}
const precisionFactory = Math.pow(10, props.precision)
return toPrecision((val * precisionFactory + step * precisionFactory) / precisionFactory)
}
function sub() {
if (minDisabled.value || props.disableMinus) return
const newValue = changeStep(inputValue.value, -props.step)
dispatchChangeEvent(newValue)
}
function add() {
if (maxDisabled.value || props.disablePlus) return
const newValue = changeStep(inputValue.value, props.step)
dispatchChangeEvent(newValue)
}
function handleInput(event: any) {
const value = event.detail.value || ''
dispatchChangeEvent(value)
}
function handleFocus(event: any) {
emit('focus', event.detail)
}
function handleBlur() {
const value = formatValue(inputValue.value)
if (!isEqual(inputValue.value, value)) {
setValue(value)
}
emit('blur', {
value
})
}
function dispatchChangeEvent(value: string | number, change: boolean = true) {
if (isEqual(inputValue.value, value)) {
return
}
inputValue.value = value
change && emit('update:modelValue', inputValue.value)
change && emit('change', { value })
}
function formatValue(value: string | number) {
if (props.allowNull && (!isDef(value) || value === '')) {
return ''
}
value = Number(value)
if (isNaN(value)) {
value = props.min
}
if (props.stepStrictly) {
value = toStrictlyStep(value)
}
if (props.precision !== undefined) {
value = value.toFixed(props.precision)
}
return Number(value)
}
</script>
<style lang="scss" scoped>
@import './index.scss';
</style>