Browse Source

refactor(组件): 将dailog移植与input各小组件整理

gemercheung 2 years ago
parent
commit
4b534a28fc
37 changed files with 946 additions and 370 deletions
  1. 31 0
      packages/components/basic/bubble/index.vue
  2. 20 4
      packages/components/basic/button/src/button.ts
  3. 0 23
      packages/components/basic/button/src/props.ts
  4. 0 0
      packages/components/basic/dialog/index.ts
  5. 52 0
      packages/components/basic/dialog/src/alert.vue
  6. 63 0
      packages/components/basic/dialog/src/confirm.vue
  7. 17 0
      packages/components/basic/dialog/src/dialog-content.vue
  8. 93 0
      packages/components/basic/dialog/src/dialog.ts
  9. 27 0
      packages/components/basic/dialog/src/dialog.vue
  10. 71 0
      packages/components/basic/dialog/src/toast.vue
  11. 67 0
      packages/components/basic/dialog/src/window.vue
  12. 23 1
      packages/components/basic/icon/src/icon.ts
  13. 1 1
      packages/components/basic/icon/src/icon.vue
  14. 0 23
      packages/components/basic/icon/src/props.ts
  15. 50 0
      packages/components/basic/input/src/checkRadio/checkRadio.ts
  16. 4 4
      packages/components/basic/input/src/checkRadio/checkRadio.vue
  17. 3 2
      packages/components/basic/input/src/checkbox/checkbox.ts
  18. 9 4
      packages/components/basic/input/src/checkbox/checkbox.vue
  19. 44 0
      packages/components/basic/input/src/file/file.ts
  20. 3 5
      packages/components/basic/input/src/file/file.vue
  21. 0 4
      packages/components/basic/input/src/index.vue
  22. 77 0
      packages/components/basic/input/src/number/number.ts
  23. 2 2
      packages/components/basic/input/src/number.vue
  24. 0 256
      packages/components/basic/input/src/props.ts
  25. 56 0
      packages/components/basic/input/src/radio/radio.ts
  26. 1 1
      packages/components/basic/input/src/radio.vue
  27. 56 0
      packages/components/basic/input/src/range/range.ts
  28. 2 2
      packages/components/basic/input/src/range.vue
  29. 0 0
      packages/components/basic/input/src/richtext/richtext.vue
  30. 2 2
      packages/components/basic/input/src/search.vue
  31. 57 0
      packages/components/basic/input/src/select/select.ts
  32. 4 21
      packages/components/basic/input/src/select.vue
  33. 56 0
      packages/components/basic/input/src/switch/switch.ts
  34. 8 4
      packages/components/basic/input/src/switch.vue
  35. 3 3
      packages/components/basic/input/src/text/text.ts
  36. 42 0
      packages/components/basic/input/src/textarea/textarea.ts
  37. 2 8
      packages/components/basic/input/src/textarea.vue

+ 31 - 0
packages/components/basic/bubble/index.vue

@@ -0,0 +1,31 @@
+<template>
+    <transition name="fade">
+        <div class="bubble" :class="{ [type]: true, [level]: true }" v-if="show" @click.stop>
+            <div class="bubble-layer">
+                <div class="bubble-arr"></div>
+                <slot></slot>
+            </div>
+        </div>
+    </transition>
+</template>
+
+<script setup>
+defineProps({
+    type: {
+        type: String,
+        default: 'right',
+    },
+    show: {
+        type: Boolean,
+        default: true,
+    },
+    level: {
+        type: String,
+        require: false,
+    },
+})
+</script>
+
+<script>
+export default { name: 'UiBubble' }
+</script>

+ 20 - 4
packages/components/basic/button/src/button.ts

@@ -1,7 +1,23 @@
 import type { ExtractPropTypes } from 'vue'
-import type Icon from './icon.vue'
-import { iconProps } from './props'
+import { buildProps, definePropType } from '@kankan/utils'
+import type button from './button.vue'
 
-export type IconProps = ExtractPropTypes<typeof iconProps>
+export const buttonProps = buildProps({
+    type: {
+        type: String,
+        default: 'normal',
+    },
+    color: {
+        type: String,
+    },
+    width: {
+        type: definePropType<number | string>([Number, String]),
+    },
+    icon: {
+        type: String,
+    },
+})
 
-export type IconInstance = InstanceType<typeof Icon>
+export type ButtonProps = ExtractPropTypes<typeof buttonProps>
+
+export type ButtonInstance = InstanceType<typeof button>

+ 0 - 23
packages/components/basic/button/src/props.ts

@@ -1,23 +0,0 @@
-import { buildProps, definePropType } from '@kankan/utils'
-
-export const iconProps = buildProps({
-    type: { type: String },
-    size: {
-        type: definePropType<number | string>([Number, String]),
-    },
-    color: { type: String },
-    small: { type: Boolean },
-    ctrl: { type: Boolean },
-    medium: { type: Boolean },
-    big: { type: Boolean },
-    disabled: { type: Boolean },
-    tip: { type: String },
-    tipH: {
-        type: String,
-        default: 'center',
-    },
-    tipV: {
-        type: String,
-        default: 'bottom',
-    },
-})

+ 0 - 0
packages/components/basic/dialog/index.ts


+ 52 - 0
packages/components/basic/dialog/src/alert.vue

@@ -0,0 +1,52 @@
+<template>
+    <ui-dialog>
+        <template #header>
+            <span>{{ title }}</span>
+            <i v-if="showCloseIcon" class="iconfont icon-close" @click="close"></i>
+        </template>
+        <div v-html="content"></div>
+        <template #footer v-if="showFooter">
+            <ui-button type="submit" @click="close">{{ okText }}</ui-button>
+        </template>
+    </ui-dialog>
+</template>
+<script>
+import { defineComponent } from 'vue'
+import { isFunction, omit } from '../../utils'
+export default defineComponent({
+    name: 'UiAlert',
+    props: {
+        showCloseIcon: {
+            type: Boolean,
+            default: true,
+        },
+        showFooter: {
+            type: Boolean,
+            default: true,
+        },
+        title: {
+            type: String,
+            default: '提示',
+        },
+        okText: {
+            type: String,
+            default: '确定',
+        },
+        func: Function,
+        content: String,
+        destroy: Function,
+    },
+    setup: function (props) {
+        const close = () => {
+            if (isFunction(props.func) && props.func() === false) {
+                return
+            }
+            isFunction(props.destroy) && props.destroy()
+        }
+        return {
+            ...omit(props, 'destroy', 'func'),
+            close,
+        }
+    },
+})
+</script>

+ 63 - 0
packages/components/basic/dialog/src/confirm.vue

@@ -0,0 +1,63 @@
+<template>
+    <ui-dialog>
+        <template #header>
+            <span>{{ title }}</span>
+            <i class="iconfont icon-close" @click="close('no')"></i>
+        </template>
+        <template v-if="$slots.content">
+            <slot name="content"></slot>
+        </template>
+        <template v-else>
+            <div class="message" v-html="content"></div>
+        </template>
+        <template #footer v-if="!hideFoot">
+            <ui-button v-if="!single" type="cancel" @click="close('no')">{{ noText }}</ui-button>
+            <ui-button type="primary" @click="close('ok')">{{ okText }}</ui-button>
+        </template>
+    </ui-dialog>
+</template>
+<script>
+import { defineComponent } from 'vue'
+import { isFunction, omit } from '../../utils'
+
+export default defineComponent({
+    name: 'UiConfirm',
+    props: {
+        title: {
+            type: String,
+            default: '提示',
+        },
+        okText: {
+            type: String,
+            default: '确定',
+        },
+        noText: {
+            type: String,
+            default: '取消',
+        },
+        single: {
+            type: Boolean,
+            default: false,
+        },
+        hideFoot: {
+            type: Boolean,
+            default: false,
+        },
+        func: Function,
+        content: String,
+        destroy: Function,
+    },
+    setup: function (props) {
+        const close = result => {
+            if (isFunction(props.func) && props.func(result) === false) {
+                return
+            }
+            isFunction(props.destroy) && props.destroy()
+        }
+        return {
+            ...omit(props, 'destroy', 'func'),
+            close,
+        }
+    },
+})
+</script>

+ 17 - 0
packages/components/basic/dialog/src/dialog-content.vue

@@ -0,0 +1,17 @@
+<template>
+    <div class="ui-dialog__box">
+        <header v-if="$slots.header">
+            <slot name="header"></slot>
+        </header>
+        <section>
+            <slot></slot>
+        </section>
+        <footer v-if="$slots.footer">
+            <slot name="footer"></slot>
+        </footer>
+    </div>
+</template>
+
+<script>
+export default { name: 'UiDialogContent' }
+</script>

+ 93 - 0
packages/components/basic/dialog/src/dialog.ts

@@ -0,0 +1,93 @@
+import Dialog from './Dialog'
+import Window from './Window'
+import Toast from './Toast'
+import Alert from './Alert'
+import Confirm from './Confirm'
+import DialogContent from './Dialog-content'
+import { mount } from '../../utils/componentHelper'
+
+Dialog.use = function use(app) {
+    Dialog.toast = function (options) {
+        if (typeof options == 'string') {
+            options = {
+                content: options,
+            }
+        }
+        // const { destroy, vNode, el }
+        const { destroy } = mount(Toast, {
+            app,
+            props: {
+                ...options,
+                destroy,
+            },
+        })
+
+        if (!Dialog.toast._destroys) {
+            Dialog.toast._destroys = []
+        }
+        Dialog.toast._destroys.push(destroy)
+
+        return {
+            hide: function () {
+                let destroy = null
+                while ((destroy = Dialog.toast._destroys.shift()) && destroy) {
+                    destroy()
+                }
+            }.bind(this),
+        }
+    }
+    Dialog.toast.hide = function () {
+        if (Dialog.toast._destroys && Dialog.toast._destroys.length) {
+            const destroy = Dialog.toast._destroys.pop()
+            destroy && destroy()
+        }
+    }
+    Dialog.alert = function (options) {
+        if (typeof options == 'string') {
+            options = {
+                content: options,
+            }
+        }
+
+        const { destroy } = mount(Alert, {
+            app,
+            props: { ...options, destroy: () => destroy() },
+        })
+
+        this.alert.hide = function () {
+            destroy()
+        }
+
+        return this.alert
+    }
+
+    Dialog.confirm = function (options) {
+        if (typeof options == 'string') {
+            options = {
+                content: options,
+            }
+        }
+
+        let promise
+        if (!options.func) {
+            promise = new Promise(resolve => {
+                options.func = result => resolve(result === 'ok')
+            })
+        }
+
+        const { destroy } = mount(Confirm, {
+            app,
+            props: { ...options, destroy: () => destroy() },
+        })
+
+        this.confirm.hide = function () {
+            destroy()
+        }
+
+        return promise || this.confirm
+    }
+}
+
+export { Window, Toast, Alert, Confirm, DialogContent }
+
+export default Dialog

+ 27 - 0
packages/components/basic/dialog/src/dialog.vue

@@ -0,0 +1,27 @@
+<template>
+    <teleport to="body">
+        <div class="ui-dialog" :style="{ zIndex: zIndex }" v-if="show">
+            <dialog-content>
+                <template v-for="(slot, name) in $slots" #[name]="raw">
+                    <slot :name="name" v-bind="raw"></slot>
+                </template>
+            </dialog-content>
+        </div>
+    </teleport>
+</template>
+<script>
+import { defineComponent, ref } from 'vue'
+import zindex from '../../utils/zindex'
+import DialogContent from './Dialog-content.vue'
+export default defineComponent({
+    name: 'UiDialog',
+    components: { DialogContent },
+    setup: function () {
+        const show = ref(true)
+        return {
+            show,
+            zIndex: zindex(),
+        }
+    },
+})
+</script>

+ 71 - 0
packages/components/basic/dialog/src/toast.vue

@@ -0,0 +1,71 @@
+<template>
+    <teleport to="body">
+        <transition name="slide-down" mode="out-in" appear>
+            <div class="ui-toast" :style="{ zIndex: zIndex }" v-if="show">
+                <div class="ui-toast__box" :class="[type]">
+                    <i v-if="type !== 'fixed' && type" class="icon"></i>
+                    <div class="ui-toast__msg" v-html="content"></div>
+                    <i class="iconfont icon-close close" @click="close" v-if="showClose"></i>
+                </div>
+            </div>
+        </transition>
+    </teleport>
+</template>
+<script>
+import { defineComponent, nextTick, ref } from 'vue'
+import zindex from '../../utils/zindex'
+
+export default defineComponent({
+    name: 'UiToast',
+    props: {
+        type: String,
+        delay: Number,
+        content: String,
+        destroy: Function,
+        close: Function,
+        showClose: Boolean,
+    },
+    setup: function (props, _) {
+        const show = ref(true)
+        const close = () => {
+            show.value = false
+            nextTick(() => {
+                if (typeof props.close == 'function') {
+                    props.close()
+                }
+                typeof props.destroy === 'function' && props.destroy()
+            })
+        }
+
+        if (props.type !== 'fixed') {
+            setTimeout(() => close(), props.delay || 3000)
+        }
+        return {
+            show,
+            // type: props.type,
+            // close,
+            // content: props.content,
+            zIndex: zindex(),
+        }
+    },
+})
+</script>
+<style lang="scss" scoped>
+.slide-down-enter-active,
+.slide-down-leave-active {
+    will-change: transform;
+    transition: all 0.35s ease-in-out;
+}
+.slide-down-enter-from {
+    opacity: 0;
+    transform: translate3d(0, -100%, 0);
+}
+.slide-down-enter {
+    opacity: 1;
+    transform: translate3d(-50%, 100%, 0);
+}
+.slide-down-leave-active {
+    opacity: 0;
+    transform: translate3d(0, -100%, 0);
+}
+</style>

+ 67 - 0
packages/components/basic/dialog/src/window.vue

@@ -0,0 +1,67 @@
+<template>
+    <ui-dialog>
+        <template #header>
+            <span style="font-size: 16px">{{ title }}</span>
+            <i class="iconfont icon-close" @click="onNo('close')" v-if="showCloseIcon"></i>
+        </template>
+        <template v-if="$slots.content">
+            <slot name="content"></slot>
+        </template>
+        <template v-else>
+            <div class="message" v-html="content"></div>
+        </template>
+        <template #footer>
+            <ui-button type="cancel" @click="onNo" v-if="showCancelButton">{{ noText }}</ui-button>
+            <ui-button :class="{ disabled: !canSubmit }" type="submit primary" @click="onOk">{{ okText }}</ui-button>
+        </template>
+    </ui-dialog>
+</template>
+<script>
+import { defineComponent } from 'vue'
+export default defineComponent({
+    name: 'UiWindow',
+    props: {
+        title: {
+            type: String,
+            default: '提示',
+        },
+        content: {
+            type: String,
+            default: '',
+        },
+        okText: {
+            type: String,
+            default: '确定',
+        },
+        noText: {
+            type: String,
+            default: '取消',
+        },
+        showCloseIcon: {
+            type: Boolean,
+            default: true,
+        },
+        showCancelButton: {
+            type: Boolean,
+            default: true,
+        },
+        canSubmit: {
+            type: Boolean,
+            default: true,
+        },
+    },
+    emits: ['ok', 'no'],
+    setup: function (props, ctx) {
+        const onNo = name => {
+            ctx.emit('no', name)
+        }
+        const onOk = () => {
+            ctx.emit('ok')
+        }
+        return {
+            onNo,
+            onOk,
+        }
+    },
+})
+</script>

+ 23 - 1
packages/components/basic/icon/src/icon.ts

@@ -1,6 +1,28 @@
 import type { ExtractPropTypes } from 'vue'
+import { buildProps, definePropType } from '@kankan/utils'
 import type Icon from './icon.vue'
-import { iconProps } from './props'
+
+export const iconProps = buildProps({
+    type: { type: String },
+    size: {
+        type: definePropType<number | string>([Number, String]),
+    },
+    color: { type: String },
+    small: { type: Boolean },
+    ctrl: { type: Boolean },
+    medium: { type: Boolean },
+    big: { type: Boolean },
+    disabled: { type: Boolean },
+    tip: { type: String },
+    tipH: {
+        type: String,
+        default: 'center',
+    },
+    tipV: {
+        type: String,
+        default: 'bottom',
+    },
+})
 
 export type IconProps = ExtractPropTypes<typeof iconProps>
 

+ 1 - 1
packages/components/basic/icon/src/icon.vue

@@ -9,7 +9,7 @@
 <script lang="ts" setup>
 import { defineProps, computed, defineEmits } from 'vue'
 import { normalizeUnitToStyle, os } from '@kankan/utils'
-import { iconProps } from './props'
+import { iconProps } from './icon'
 const props = defineProps(iconProps)
 
 const style = computed(() => ({

+ 0 - 23
packages/components/basic/icon/src/props.ts

@@ -1,23 +0,0 @@
-import { buildProps, definePropType } from '@kankan/utils'
-
-export const iconProps = buildProps({
-    type: { type: String },
-    size: {
-        type: definePropType<number | string>([Number, String]),
-    },
-    color: { type: String },
-    small: { type: Boolean },
-    ctrl: { type: Boolean },
-    medium: { type: Boolean },
-    big: { type: Boolean },
-    disabled: { type: Boolean },
-    tip: { type: String },
-    tipH: {
-        type: String,
-        default: 'center',
-    },
-    tipV: {
-        type: String,
-        default: 'bottom',
-    },
-})

+ 50 - 0
packages/components/basic/input/src/checkRadio/checkRadio.ts

@@ -0,0 +1,50 @@
+import { buildProps, definePropType } from '@kankan/utils'
+import type { ExtractPropTypes } from 'vue'
+
+export const checkRadioProps = buildProps({
+    type: {
+        type: String,
+    },
+    name: {
+        type: String,
+    },
+    disabled: {
+        type: Boolean,
+        default: false,
+    },
+    modelValue: {
+        type: Boolean,
+        default: false,
+    },
+    placeholder: {
+        type: String,
+        default: '请输入',
+    },
+    maxlength: {
+        type: definePropType<number | string>([Number, String]),
+    },
+    readonly: {
+        type: Boolean,
+        default: false,
+    },
+    other: {
+        type: Object,
+        default: () => ({}),
+    },
+    right: {
+        type: Boolean,
+    },
+    width: {
+        type: definePropType<number | string>([Number, String]),
+        default: '',
+    },
+    height: {
+        type: definePropType<number | string>([Number, String]),
+        default: '',
+    },
+    label: {
+        type: String,
+    },
+})
+
+export type CheckRadioProps = ExtractPropTypes<typeof checkRadioProps>

+ 4 - 4
packages/components/basic/input/src/checkRadio/checkRadio.vue

@@ -1,6 +1,6 @@
 <template>
     <div class="input radio" :style="{ width, height }">
-        <input :disabled="disabled" :id="id" type="checkbox" :checked="props.modelValue" @input="ev => emit('update:modelValue', ev.target.checked)" />
+        <input :disabled="disabled" :id="id" type="checkbox" :checked="props.modelValue" @input="ev => emit('update:modelValue', (ev.target as HTMLInputElement).checked)" />
         <span class="replace">
             <icon type="checkbox" :size="width > height ? height : width" />
         </span>
@@ -11,11 +11,11 @@
 </template>
 
 <script setup lang="ts">
-import icon from '../icon'
-import { checkboxPropsDesc } from '../state'
+import icon from '../../../icon/src/icon.vue'
+import { checkRadioProps } from './checkRadio'
 import { randomId } from '@kankan/utils'
 import { defineProps, defineEmits } from 'vue'
-const props = defineProps(checkboxPropsDesc)
+const props = defineProps(checkRadioProps)
 const emit = defineEmits(['update:modelValue'])
 const id = randomId(4)
 </script>

+ 3 - 2
packages/components/basic/input/src/checkbox/checkbox.ts

@@ -1,4 +1,5 @@
-import { buildProps, definePropType, ExtractPropType } from '@kankan/utils'
+import { buildProps, definePropType } from '@kankan/utils'
+import type { ExtractPropTypes } from 'vue'
 
 export const CheckboxInputProps = buildProps({
     type: {
@@ -46,4 +47,4 @@ export const CheckboxInputProps = buildProps({
     },
 })
 
-export type CheckboxInputProps = ExtractPropType<typeof CheckboxInputProps>
+export type CheckboxInputProps = ExtractPropTypes<typeof CheckboxInputProps>

+ 9 - 4
packages/components/basic/input/src/checkbox/checkbox.vue

@@ -1,6 +1,13 @@
 <template>
-    <div class="input checkbox" :style="{ width: props.width, height: props.width }" :class="{ disabled }">
-        <input :disabled="disabled" :id="id" type="checkbox" class="replace-input" :checked="props.modelValue" @input="(ev:InputEvent) => emit('update:modelValue', ev.target.checked)" />
+    <div class="input checkbox" :style="{ width, height }" :class="{ disabled }">
+        <input
+            :disabled="disabled"
+            :id="id"
+            type="checkbox"
+            class="replace-input"
+            :checked="props.modelValue"
+            @input="(ev:Event) => emit('update:modelValue', (ev.target as HTMLInputElement).checked)"
+        />
         <span class="replace">
             <UIIcon :type="props.modelValue ? 'checkbox' : 'nor'" :size="props.width > props.height ? props.height : props.width" />
         </span>
@@ -18,6 +25,4 @@ import { defineProps, defineEmits } from 'vue'
 const props = defineProps(CheckboxInputProps)
 const emit = defineEmits(['update:modelValue'])
 const id = randomId(4)
-
-const
 </script>

+ 44 - 0
packages/components/basic/input/src/file/file.ts

@@ -0,0 +1,44 @@
+import { buildProps } from '@kankan/utils'
+import type { ExtractPropTypes } from 'vue'
+
+export const fileProps = buildProps({
+    name: {
+        type: String,
+    },
+    disabled: {
+        type: [Boolean],
+    },
+    modelValue: {
+        type: String,
+        default: '',
+    },
+    placeholder: {
+        type: String,
+        default: '请输入',
+    },
+    othPlaceholder: {
+        type: String,
+        require: false,
+        default: '',
+    },
+    accept: {
+        type: String,
+    },
+    scale: {
+        type: String,
+    },
+    multiple: {
+        type: Boolean,
+    },
+    preview: {
+        type: Boolean,
+    },
+    maxSize: {
+        type: Number,
+    },
+    maxLen: {
+        type: Number,
+    },
+})
+
+export type FileProps = ExtractPropTypes<typeof fileProps>

+ 3 - 5
packages/components/basic/input/src/file/file.vue

@@ -37,16 +37,14 @@
 </template>
 
 <script setup lang="ts">
-import { filePropsDesc } from './state'
-import { toRawType } from '../../utils'
+import { fileProps } from './file'
+import { toRawType } from '@kankan/utils'
 // import Message from '../message';
 import Dialog from '../dialog'
 import { defineProps, defineEmits, defineExpose, ref, computed } from 'vue'
 import { useI18n } from '@/i18n'
 const { t } = useI18n({ useScope: 'global' })
-const props = defineProps({
-    ...filePropsDesc,
-})
+const props = defineProps(fileProps)
 const emit = defineEmits(['update:modelValue'])
 const inputRef = ref(null)
 const normalizeScale = computed(() => {

+ 0 - 4
packages/components/basic/input/src/index.vue

@@ -119,7 +119,3 @@ const style = computed(() => {
     return style
 })
 </script>
-
-<script>
-export default { name: 'UiInput' }
-</script>

+ 77 - 0
packages/components/basic/input/src/number/number.ts

@@ -0,0 +1,77 @@
+import { buildProps, definePropType } from '@kankan/utils'
+import type { ExtractPropTypes } from 'vue'
+
+export const numberProps = buildProps({
+    type: {
+        type: String,
+    },
+    name: {
+        type: String,
+    },
+    disabled: {
+        type: Boolean,
+        default: false,
+    },
+    modelValue: {
+        type: String,
+        required: false,
+        default: '',
+    },
+    placeholder: {
+        type: String,
+        default: '请输入',
+    },
+    maxlength: {
+        type: definePropType<number | string>([Number, String]),
+    },
+    readonly: {
+        type: Boolean,
+        default: false,
+    },
+    other: {
+        type: Object,
+        default: () => ({}),
+    },
+    right: {
+        type: Boolean,
+    },
+    inInput: {
+        type: Boolean,
+        default: true,
+    },
+    ctrl: {
+        type: Boolean,
+        default: true,
+    },
+    step: {
+        type: Number,
+        require: true,
+        default: 1,
+    },
+    min: {
+        type: definePropType<number | string>([Number, String]),
+        require: false,
+    },
+    max: {
+        type: definePropType<number | string>([Number, String]),
+        require: false,
+    },
+    limit: {
+        type: Number,
+        default: 0,
+    },
+    inch: {
+        type: definePropType<boolean | string>([Boolean, String]),
+        default: false,
+    },
+    rangeInput: {
+        type: Boolean,
+        default: true,
+    },
+    rangeTips: {
+        type: Boolean,
+        default: false,
+    },
+})
+
+export type NumberProps = ExtractPropTypes<typeof numberProps>

+ 2 - 2
packages/components/basic/input/src/number.vue

@@ -25,13 +25,13 @@
 
 <script setup lang="ts">
 import UIText from './text.vue'
-import { numberPropsDesc } from './state'
+import { numberProps } from './number'
 import { defineProps, defineEmits, watchEffect, ref } from 'vue'
 import { toRawType } from '@kankan/utils'
 import UIIcon from '../../icon/src/icon.vue'
 
 const emit = defineEmits(['update:modelValue'])
-const props = defineProps(numberPropsDesc)
+const props = defineProps(numberProps)
 
 const isNumber = raw => !(toRawType(raw) === 'Number' ? isNaN(raw) : isNaN(Number(raw)))
 const tempValue = ref(props.modelValue)

+ 0 - 256
packages/components/basic/input/src/props.ts

@@ -1,256 +0,0 @@
-// import { buildProps, definePropType } from '@kankan/utils'
-
-// export const InputProps = buildProps({
-//     name: {
-//         type: String,
-//     },
-//     disabled: {
-//         type: Boolean,
-//         default: false,
-//     },
-//     modelValue: {
-//         required: false,
-//         default: '',
-//     },
-//     placeholder: {
-//         require: false,
-//         default: '请输入',
-//     },
-// })
-
-// export const colorPropsDesc = {
-//     ...InputProps,
-//     width: {
-//         type: String,
-//         default: '100px',
-//     },
-//     height: {
-//         type: String,
-//         default: '34px',
-//     },
-// }
-
-// export const filePropsDesc = {
-//     ...instalcePublic,
-//     placeholder: {
-//         require: false,
-//         default: '请选择',
-//     },
-//     othPlaceholder: {
-//         require: false,
-//         default: '',
-//     },
-//     accept: {
-//         type: String,
-//     },
-//     scale: {
-//         type: String,
-//     },
-//     multiple: {
-//         type: Boolean,
-//     },
-//     preview: {
-//         type: Boolean,
-//     },
-//     maxSize: {
-//         type: Number,
-//     },
-//     maxLen: {
-//         type: Number,
-//     },
-// }
-
-// export const switchPropsDesc = {
-//     ...instalcePublic,
-//     width: {
-//         type: [Number, String],
-//     },
-//     height: {
-//         type: [Number, String],
-//     },
-// }
-
-// export const checkboxPropsDesc = {
-//     ...switchPropsDesc,
-//     label: {
-//         type: String,
-//         required: false,
-//     },
-// }
-
-// export const radioPropsDesc = {
-//     ...checkboxPropsDesc,
-//     icon: {
-//         type: String,
-//     },
-//     tip: {
-//         type: String,
-//     },
-// }
-
-// export const textPropsDesc = {
-//     ...instalcePublic,
-//     maxlength: {
-//         type: [String, Number],
-//     },
-//     placeholder: {
-//         type: String,
-//         default: '请输入',
-//     },
-//     readonly: {
-//         type: Boolean,
-//         default: false,
-//     },
-//     other: {
-//         type: Object,
-//         default: () => ({}),
-//     },
-//     right: {
-//         type: Boolean,
-//     },
-// }
-
-// export const textEmitsDesc = ['update:modelValue', 'focus', 'blur', 'click', 'keydown']
-
-// export const textareaPropsDesc = {
-//     ...textPropsDesc,
-//     rich: {
-//         type: Boolean,
-//     },
-// }
-
-// export const richtextPropsDesc = {
-//     ...textareaPropsDesc,
-//     onUpdatePos: Function,
-// }
-
-// export const selectPropsDesc = {
-//     ...textPropsDesc,
-//     stopEl: {
-//         type: String,
-//         require: false,
-//     },
-//     floatingClass: {
-//         type: String,
-//         require: false,
-//     },
-//     showOptions: {
-//         type: Boolean,
-//         require: false,
-//     },
-//     placeholder: { ...textPropsDesc.placeholder, default: '请选择' },
-//     unplaceholder: { ...textPropsDesc.placeholder, default: '暂无选项' },
-//     hideScroll: {
-//         type: Boolean,
-//         default: false,
-//     },
-//     options: {
-//         type: Array,
-//         default: () => [],
-//     },
-//     dire: {
-//         type: String,
-//         default: 'bottom',
-//     },
-// }
-
-// export const searchPropsDesc = {
-//     ...selectPropsDesc,
-//     unplaceholder: { ...textPropsDesc.placeholder, default: '无搜索结果' },
-// }
-
-// export const numberPropsDesc = {
-//     ...textPropsDesc,
-//     inInput: {
-//         type: Boolean,
-//         default: true,
-//     },
-//     ctrl: {
-//         type: Boolean,
-//         default: true,
-//     },
-//     step: {
-//         type: Number,
-//         require: true,
-//         default: 1,
-//     },
-//     min: {
-//         type: [Number, String],
-//         require: false,
-//     },
-//     max: {
-//         type: [Number, String],
-//         require: false,
-//     },
-//     limit: {
-//         type: Number,
-//         default: 0,
-//     },
-//     inch: {
-//         type: [Boolean, String],
-//         default: false,
-//     },
-//     rangeInput: {
-//         type: Boolean,
-//         default: true,
-//     },
-//     rangeTips: {
-//         type: Boolean,
-//         default: false,
-//     },
-// }
-
-// export const rangePropsDesc = {
-//     ...numberPropsDesc,
-//     min: { ...numberPropsDesc.min, require: true },
-//     min: { ...numberPropsDesc.min, require: true },
-// }
-
-// const summary = {
-//     ...checkboxPropsDesc,
-//     ...radioPropsDesc,
-//     ...selectPropsDesc,
-//     ...textPropsDesc,
-//     ...rangePropsDesc,
-//     ...numberPropsDesc,
-//     ...switchPropsDesc,
-//     ...textareaPropsDesc,
-//     ...filePropsDesc,
-//     ...searchPropsDesc,
-//     ...richtextPropsDesc,
-//     ...colorPropsDesc,
-// }
-// for (const key in summary) {
-//     summary[key] = {
-//         ...summary[key],
-//         default: undefined,
-//     }
-// }
-
-// export const inputEmitDesc = {
-//     text: textEmitsDesc,
-// }
-
-// export const inputPropsDesc = {
-//     ...summary,
-//     type: {
-//         type: String,
-//         required: true,
-//         default: 'text',
-//     },
-//     width: {
-//         type: [Number, String],
-//     },
-//     height: {
-//         type: [Number, String],
-//     },
-//     require: {
-//         type: Boolean,
-//     },
-//     error: {
-//         type: String,
-//     },
-//     disabled: {
-//         type: Boolean,
-//     },
-// }

+ 56 - 0
packages/components/basic/input/src/radio/radio.ts

@@ -0,0 +1,56 @@
+import { buildProps, definePropType } from '@kankan/utils'
+import type { ExtractPropTypes } from 'vue'
+
+export const switchProps = buildProps({
+    type: {
+        type: String,
+    },
+    name: {
+        type: String,
+    },
+    width: {
+        type: definePropType<number | string>([Number, String]),
+    },
+    height: {
+        type: definePropType<number | string>([Number, String]),
+    },
+    disabled: {
+        type: Boolean,
+        default: false,
+    },
+    modelValue: {
+        type: Boolean,
+        default: false,
+    },
+    placeholder: {
+        type: String,
+        default: '请输入',
+    },
+    maxlength: {
+        type: definePropType<number | string>([Number, String]),
+    },
+    readonly: {
+        type: Boolean,
+        default: true,
+    },
+    other: {
+        type: Object,
+        default: () => ({}),
+    },
+    right: {
+        type: Boolean,
+    },
+    className: {
+        type: String,
+    },
+    labelValue: {
+        type: String,
+        require: false,
+    },
+    dbhide: {
+        type: Boolean,
+        default: true,
+    },
+})
+
+export type SelectProps = ExtractPropTypes<typeof selectProps>

+ 1 - 1
packages/components/basic/input/src/radio.vue

@@ -11,7 +11,7 @@
 
 <script setup lang="ts">
 import Icon from '../icon'
-import { radioPropsDesc } from './state'
+import { radioPropsDesc } from '../state'
 import { randomId } from '../../utils'
 import { defineProps, defineEmits } from 'vue'
 const props = defineProps(radioPropsDesc)

+ 56 - 0
packages/components/basic/input/src/range/range.ts

@@ -0,0 +1,56 @@
+import { buildProps, definePropType } from '@kankan/utils'
+import type { ExtractPropTypes } from 'vue'
+
+export const switchProps = buildProps({
+    type: {
+        type: String,
+    },
+    name: {
+        type: String,
+    },
+    width: {
+        type: definePropType<number | string>([Number, String]),
+    },
+    height: {
+        type: definePropType<number | string>([Number, String]),
+    },
+    disabled: {
+        type: Boolean,
+        default: false,
+    },
+    modelValue: {
+        type: Boolean,
+        default: false,
+    },
+    placeholder: {
+        type: String,
+        default: '请输入',
+    },
+    maxlength: {
+        type: definePropType<number | string>([Number, String]),
+    },
+    readonly: {
+        type: Boolean,
+        default: true,
+    },
+    other: {
+        type: Object,
+        default: () => ({}),
+    },
+    right: {
+        type: Boolean,
+    },
+    className: {
+        type: String,
+    },
+    labelValue: {
+        type: String,
+        require: false,
+    },
+    dbhide: {
+        type: Boolean,
+        default: true,
+    },
+})
+
+export type SelectProps = ExtractPropTypes<typeof selectProps>

+ 2 - 2
packages/components/basic/input/src/range.vue

@@ -17,8 +17,8 @@
 <script setup lang="ts">
 import { ref, computed, onMounted, defineProps, nextTick } from 'vue'
 import { rangePropsDesc } from './state'
-import UInumber from './number.vue'
-import UItext from './text.vue'
+import UInumber from '../number/number.vue'
+import UItext from '../text/text.vue'
 const props = defineProps(rangePropsDesc)
 const emit = defineEmits(['update:modelValue'])
 const getValue = value => {

packages/components/basic/input/src/richtext.vue → packages/components/basic/input/src/richtext/richtext.vue


+ 2 - 2
packages/components/basic/input/src/search.vue

@@ -14,8 +14,8 @@
 
 <script setup lang="ts">
 import { ref, watchEffect, defineEmits, onUnmounted } from 'vue'
-import { searchPropsDesc } from './state'
-import UISelect from './select.vue'
+import { searchPropsDesc } from '../state'
+import UISelect from '../select/select.vue'
 
 const props = defineProps(searchPropsDesc)
 const labelValue = ref('')

+ 57 - 0
packages/components/basic/input/src/select/select.ts

@@ -0,0 +1,57 @@
+import { buildProps, definePropType } from '@kankan/utils'
+import type { ExtractPropTypes } from 'vue'
+
+export const selectProps = buildProps({
+    type: {
+        type: String,
+    },
+    name: {
+        type: String,
+    },
+    width: {
+        type: definePropType<number | string>([Number, String]),
+    },
+    height: {
+        type: definePropType<number | string>([Number, String]),
+    },
+    disabled: {
+        type: Boolean,
+        default: false,
+    },
+    modelValue: {
+        type: String,
+        required: false,
+        default: '',
+    },
+    placeholder: {
+        type: String,
+        default: '请输入',
+    },
+    maxlength: {
+        type: definePropType<number | string>([Number, String]),
+    },
+    readonly: {
+        type: Boolean,
+        default: true,
+    },
+    other: {
+        type: Object,
+        default: () => ({}),
+    },
+    right: {
+        type: Boolean,
+    },
+    className: {
+        type: String,
+    },
+    labelValue: {
+        type: String,
+        require: false,
+    },
+    dbhide: {
+        type: Boolean,
+        default: true,
+    },
+})
+
+export type SelectProps = ExtractPropTypes<typeof selectProps>

+ 4 - 21
packages/components/basic/input/src/select.vue

@@ -56,30 +56,13 @@
 </template>
 
 <script setup lang="ts">
-import UItext from './text.vue'
+import icon from '../icon'
+import UItext from '../text/text.vue'
 import UIFloating from '../floating/index.vue'
 import { ref, computed, defineExpose } from 'vue'
-import { selectPropsDesc } from './state'
-import icon from '../icon'
+import { selectProps } from './select'
 
-const props = defineProps({
-    ...selectPropsDesc,
-    readonly: {
-        type: Boolean,
-        default: true,
-    },
-    className: {
-        type: String,
-    },
-    labelValue: {
-        type: String,
-        require: false,
-    },
-    dbhide: {
-        type: Boolean,
-        default: true,
-    },
-})
+const props = defineProps(selectProps)
 const emit = defineEmits(['update:modelValue'])
 const vmRef = ref(null)
 const showOption = ref(false)

+ 56 - 0
packages/components/basic/input/src/switch/switch.ts

@@ -0,0 +1,56 @@
+import { buildProps, definePropType } from '@kankan/utils'
+import type { ExtractPropTypes } from 'vue'
+
+export const switchProps = buildProps({
+    type: {
+        type: String,
+    },
+    name: {
+        type: String,
+    },
+    width: {
+        type: definePropType<number | string>([Number, String]),
+    },
+    height: {
+        type: definePropType<number | string>([Number, String]),
+    },
+    disabled: {
+        type: Boolean,
+        default: false,
+    },
+    modelValue: {
+        type: Boolean,
+        default: false,
+    },
+    placeholder: {
+        type: String,
+        default: '请输入',
+    },
+    maxlength: {
+        type: definePropType<number | string>([Number, String]),
+    },
+    readonly: {
+        type: Boolean,
+        default: true,
+    },
+    other: {
+        type: Object,
+        default: () => ({}),
+    },
+    right: {
+        type: Boolean,
+    },
+    className: {
+        type: String,
+    },
+    labelValue: {
+        type: String,
+        require: false,
+    },
+    dbhide: {
+        type: Boolean,
+        default: true,
+    },
+})
+
+export type SelectProps = ExtractPropTypes<typeof selectProps>

+ 8 - 4
packages/components/basic/input/src/switch.vue

@@ -1,15 +1,19 @@
 <template>
     <div class="input switch" :style="{ width, height }" :class="{ disabled }">
-        <input class="replace-input" :disabled="disabled" :id="id" type="checkbox" :checked="props.modelValue" @input="ev => emit('update:modelValue', ev.target.checked)" />
+        <input class="replace-input" :disabled="disabled" :id="id" type="checkbox" :checked="props.modelValue" @input="handleInput" />
         <span class="replace"></span>
     </div>
 </template>
 
 <script setup lang="ts">
-import { switchPropsDesc } from './state'
-import { randomId } from '../../utils'
+import { switchProps } from './switch'
+import { randomId } from '@kankan/utils'
 import { defineProps, defineEmits } from 'vue'
-const props = defineProps(switchPropsDesc)
+const props = defineProps(switchProps)
 const emit = defineEmits(['update:modelValue'])
 const id = randomId(4)
+
+const handleInput = (event: Event) => {
+    emit('update:modelValue', (event.target as HTMLInputElement).checked)
+}
 </script>

+ 3 - 3
packages/components/basic/input/src/text/text.ts

@@ -1,5 +1,5 @@
-import { buildProps, definePropType, ExtractPropType } from '@kankan/utils'
-
+import { buildProps, definePropType } from '@kankan/utils'
+import type { ExtractPropTypes } from 'vue'
 export const TextInputProps = buildProps({
     type: {
         type: String,
@@ -36,4 +36,4 @@ export const TextInputProps = buildProps({
     },
 })
 
-export type TextInputProps = ExtractPropType<typeof TextInputProps>
+export type TextInputProps = ExtractPropTypes<typeof TextInputProps>

+ 42 - 0
packages/components/basic/input/src/textarea/textarea.ts

@@ -0,0 +1,42 @@
+import { buildProps, definePropType } from '@kankan/utils'
+import type { ExtractPropTypes } from 'vue'
+export const textareaProps = buildProps({
+    type: {
+        type: String,
+    },
+    name: {
+        type: String,
+    },
+    disabled: {
+        type: Boolean,
+        default: false,
+    },
+    modelValue: {
+        type: String,
+        required: false,
+        default: '',
+    },
+    placeholder: {
+        type: String,
+        default: '请输入',
+    },
+    maxlength: {
+        type: definePropType<number | string>([Number, String]),
+    },
+    readonly: {
+        type: Boolean,
+        default: false,
+    },
+    other: {
+        type: Object,
+        default: () => ({}),
+    },
+    right: {
+        type: Boolean,
+    },
+    rich: {
+        type: Boolean,
+    },
+})
+
+export type TextareaProps = ExtractPropTypes<typeof textareaProps>

+ 2 - 8
packages/components/basic/input/src/textarea.vue

@@ -25,15 +25,9 @@
 </template>
 
 <script setup lang="ts">
-import { textareaPropsDesc } from './state'
+import { textareaProps } from './textarea'
 import { defineProps, defineEmits, defineExpose, nextTick, ref } from 'vue'
-const props = defineProps({
-    type: {
-        type: String,
-        default: 'text',
-    },
-    ...textareaPropsDesc,
-})
+const props = defineProps(textareaProps)
 
 console.log(props)
 const emit = defineEmits(['update:modelValue', 'focus', 'blur', 'click'])