diff --git a/packages/devui-vue/devui/input-icon/index.ts b/packages/devui-vue/devui/input-icon/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..01e76773fb264b7cf268b1750c52304e46707c3a --- /dev/null +++ b/packages/devui-vue/devui/input-icon/index.ts @@ -0,0 +1,17 @@ +import type { App } from 'vue' +import InputIcon from './src/input-icon' + +InputIcon.install = function(app: App) { + app.component(InputIcon.name, InputIcon) +} + +export { InputIcon } + +export default { + title: 'InputIcon输入框', + category: '数据录入', + status: '75%', + install(app: App): void { + app.use(InputIcon as any) + } +} diff --git a/packages/devui-vue/devui/input-icon/src/input-icon.scss b/packages/devui-vue/devui/input-icon/src/input-icon.scss new file mode 100644 index 0000000000000000000000000000000000000000..8a38b1d1450f91eafa9803af5735c8d15c30cba2 --- /dev/null +++ b/packages/devui-vue/devui/input-icon/src/input-icon.scss @@ -0,0 +1,27 @@ +$icon-size: 26px; +$icon-offset: 1px; +$icon-left: 2px; +.d-input-icon-container { + display: flex; + flex-direction: row; + align-items: center; + position: relative; + label { + flex: 1; + background-color: #ccc; + input { + padding-right: $icon-size + $icon-offset + $icon-left; + } + } + span { + position: absolute; + top: 1px; + bottom: 1px; + right: $icon-offset; + width: $icon-size; + display: flex; + justify-content: center; + align-items: center; + box-sizing: border-box; + } +} \ No newline at end of file diff --git a/packages/devui-vue/devui/input-icon/src/input-icon.tsx b/packages/devui-vue/devui/input-icon/src/input-icon.tsx new file mode 100644 index 0000000000000000000000000000000000000000..34a9b34c011e6e207e3cb464619ae362c0edbde9 --- /dev/null +++ b/packages/devui-vue/devui/input-icon/src/input-icon.tsx @@ -0,0 +1,55 @@ +import { defineComponent, reactive, PropType } from 'vue' +import Input from '../../input/src/input' +import { inputProps } from '../../input/src/use-input' +import Icon from '../../icon/src/icon' + +import './input-icon.scss' + +const inputIconProps = { + ...inputProps, + name: { + type: String, + value: 'calendar', + required: false, + }, + onIconclick: { + type: Function as PropType<(e: MouseEvent) => void>, + required: false, + }, + iconBgColor: { + type: String, + value: 'transparent', + }, + iconColor: { + type: String, + value: '#000000', + } +} + +export default defineComponent({ + name: 'DInputIcon', + props: inputIconProps, + setup(props, ctx) { + const { name, onIconclick, onChange, iconBgColor, iconColor, ...inputProps } = props + const state = reactive({ value: '' }) + const onInputChange = (v: string) => { + state.value = v + typeof onChange === 'function' && onChange(state.value) + } + const onIconClick = (e: MouseEvent) => { + typeof onIconclick === 'function' && onIconclick(state.value, e) + } + return () => { + return ( +
+ + + + +
+ ) + } + }, +}) diff --git a/packages/devui-vue/docs/components/input-icon/index.md b/packages/devui-vue/docs/components/input-icon/index.md new file mode 100644 index 0000000000000000000000000000000000000000..97067f550d7a3cf6a3ac06dd2d9700808f9a5636 --- /dev/null +++ b/packages/devui-vue/docs/components/input-icon/index.md @@ -0,0 +1,132 @@ +# InputIcon 输入框 + +文本输入框。 + +### 何时使用 + +需要手动输入文字使用。 + + + +### 属性 name + +使用`name`属性定义`icon`类型,取值与`icon`组件一致。详细列表[https://devui.design/icon/ruleResource](https://devui.design/icon/ruleResource) + +```vue + +``` + +
+ + + + + + +
+ +### 属性 `icon-color` `icon-bg-color` + +- `icon-color` 定义`icon`颜色。 +- `icon-bg-color` 定义`icon`区域的背景色。 + +由于字体图标本身有点布局偏移,加上背景可以有效抑制这种视觉偏移影响。 + +```vue + +``` + +
+ + + + + + +
+ +### 事件 `onIconclick` + +响应图标区域的点击。 + +```vue + +``` + +
+ +
+ +### 传递原始`Input`组件属性 + +`InputIcon`组件的属性定义,沿用`Input`组件的属性定义对象并进行扩展: + +```js +import { inputProps } from '../../input/src/use-input' +const inputIconProps = { + ...inputProps, + name: { + type: String, + value: 'calendar', + required: false, + }, + onIconclick: { + type: Function as PropType<(e: MouseEvent) => void>, + required: false, + }, + iconBgColor: { + type: String, + value: 'transparent', + }, + iconColor: { + type: String, + value: '#000000', + } +} +``` + +在使用组件时,剔除`InputIcon`自身的几个额外属性,其余的属性全部直接传递给内置的`Input`组件。这样做的好处,是`Input`组件和`InputIcon`组件之间可以无缝替换。 + +```js +setup(props, ctx) { + // Rest剩余属性到inputProps对象 + const { name, onIconclick, onChange, iconBgColor, iconColor, ...inputProps } = props + // ... + const onInputChange = (v: string) => { + state.value = v + typeof onChange === 'function' && onChange(state.value) + } + // ... + return () => { + return ( +
+ + + + +
+ ) + } +}, +``` + +其中`onInputChange`的二次封装,是为了从`Input`组件中同步状态到本地。 \ No newline at end of file