Selaa lähdekoodia

feat(架构调整): 组件input迁移

gemercheung 2 vuotta sitten
vanhempi
commit
d8b1739e65

+ 3 - 2
docs/examples/input/auto-sizing-textarea.vue

@@ -1,12 +1,12 @@
 <template>
-  <el-input
+  <kk-input
     v-model="textarea1"
     autosize
     type="textarea"
     placeholder="Please input"
   />
   <div style="margin: 20px 0" />
-  <el-input
+  <kk-input
     v-model="textarea2"
     :autosize="{ minRows: 2, maxRows: 4 }"
     type="textarea"
@@ -16,6 +16,7 @@
 
 <script lang="ts" setup>
 import { ref } from 'vue'
+import { KkInput } from 'kankan-components'
 const textarea1 = ref('')
 const textarea2 = ref('')
 </script>

+ 2 - 1
docs/examples/input/basic.vue

@@ -1,8 +1,9 @@
 <template>
-  <el-input v-model="input" placeholder="Please input" />
+  <kk-input v-model="input" placeholder="Please input" />
 </template>
 
 <script lang="ts" setup>
 import { ref } from 'vue'
+import { KkInput } from 'kankan-components'
 const input = ref('')
 </script>

+ 2 - 1
docs/examples/input/clearable.vue

@@ -1,8 +1,9 @@
 <template>
-  <el-input v-model="input" placeholder="Please input" clearable />
+  <kk-input v-model="input" placeholder="Please input" clearable />
 </template>
 
 <script lang="ts" setup>
 import { ref } from 'vue'
+import { KkInput } from 'kankan-components'
 const input = ref('')
 </script>

+ 2 - 1
docs/examples/input/disabled.vue

@@ -1,8 +1,9 @@
 <template>
-  <el-input v-model="input" disabled placeholder="Please input" />
+  <kk-input v-model="input" disabled placeholder="Please input" />
 </template>
 
 <script lang="ts" setup>
 import { ref } from 'vue'
+import { KkInput } from 'kankan-components'
 const input = ref('')
 </script>

+ 2 - 1
docs/examples/input/formatter.vue

@@ -1,5 +1,5 @@
 <template>
-  <el-input
+  <kk-input
     v-model="input"
     placeholder="Please input"
     :formatter="(value) => `$ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')"
@@ -9,5 +9,6 @@
 
 <script lang="ts" setup>
 import { ref } from 'vue'
+import { KkInput } from 'kankan-components'
 const input = ref('')
 </script>

+ 3 - 2
docs/examples/input/length-limiting.vue

@@ -1,5 +1,5 @@
 <template>
-  <el-input
+  <kk-input
     v-model="text"
     maxlength="10"
     placeholder="Please input"
@@ -7,7 +7,7 @@
     type="text"
   />
   <div style="margin: 20px 0" />
-  <el-input
+  <kk-input
     v-model="textarea"
     maxlength="30"
     placeholder="Please input"
@@ -18,6 +18,7 @@
 
 <script lang="ts" setup>
 import { ref } from 'vue'
+import { KkInput } from 'kankan-components'
 const text = ref('')
 const textarea = ref('')
 </script>

+ 13 - 12
docs/examples/input/mixed-input.vue

@@ -1,16 +1,16 @@
 <template>
   <div>
-    <el-input v-model="input1" placeholder="Please input">
+    <kk-input v-model="input1" placeholder="Please input">
       <template #prepend>Http://</template>
-    </el-input>
+    </kk-input>
   </div>
   <div class="mt-4">
-    <el-input v-model="input2" placeholder="Please input">
+    <kk-input v-model="input2" placeholder="Please input">
       <template #append>.com</template>
-    </el-input>
+    </kk-input>
   </div>
   <div class="mt-4">
-    <el-input
+    <kk-input
       v-model="input3"
       placeholder="Please input"
       class="input-with-select"
@@ -23,18 +23,18 @@
         </el-select>
       </template>
       <template #append>
-        <el-button :icon="Search" />
+        <kk-button :icon="Search" />
       </template>
-    </el-input>
+    </kk-input>
   </div>
   <div class="mt-4">
-    <el-input
+    <kk-input
       v-model="input3"
       placeholder="Please input"
       class="input-with-select"
     >
       <template #prepend>
-        <el-button :icon="Search" />
+        <kk-button :icon="Search" />
       </template>
       <template #append>
         <el-select v-model="select" placeholder="Select" style="width: 115px">
@@ -43,13 +43,14 @@
           <el-option label="Tel" value="3" />
         </el-select>
       </template>
-    </el-input>
+    </kk-input>
   </div>
 </template>
 
 <script setup lang="ts">
 import { ref } from 'vue'
-import { Search } from '@element-plus/icons-vue'
+import { KkButton, KkInput } from 'kankan-components'
+import { Search } from '@kankan-components/icons-vue'
 const input1 = ref('')
 const input2 = ref('')
 const input3 = ref('')
@@ -57,7 +58,7 @@ const select = ref('')
 </script>
 
 <style>
-.input-with-select .el-input-group__prepend {
+.input-with-select .kk-input-group__prepend {
   background-color: var(--el-fill-color-blank);
 }
 </style>

+ 2 - 1
docs/examples/input/password.vue

@@ -1,5 +1,5 @@
 <template>
-  <el-input
+  <kk-input
     v-model="input"
     type="password"
     placeholder="Please input password"
@@ -9,5 +9,6 @@
 
 <script lang="ts" setup>
 import { ref } from 'vue'
+import { KkInput } from 'kankan-components'
 const input = ref('')
 </script>

+ 2 - 1
docs/examples/input/textarea.vue

@@ -1,5 +1,5 @@
 <template>
-  <el-input
+  <kk-input
     v-model="textarea"
     :rows="2"
     type="textarea"
@@ -9,5 +9,6 @@
 
 <script lang="ts" setup>
 import { ref } from 'vue'
+import { KkInput } from 'kankan-components'
 const textarea = ref('')
 </script>

+ 10 - 9
docs/examples/input/various-size.vue

@@ -1,13 +1,13 @@
 <template>
   <div class="demo-input-size">
-    <el-input
+    <kk-input
       v-model="input1"
       class="w-50 m-2"
       size="large"
       placeholder="Please Input"
     />
-    <el-input v-model="input2" class="w-50 m-2" placeholder="Please Input" />
-    <el-input
+    <kk-input v-model="input2" class="w-50 m-2" placeholder="Please Input" />
+    <kk-input
       v-model="input3"
       class="w-50 m-2"
       size="small"
@@ -15,20 +15,20 @@
     />
   </div>
   <div class="demo-input-size">
-    <el-input
+    <kk-input
       v-model="input1"
       class="w-50 m-2"
       size="large"
       placeholder="Please Input"
       :suffix-icon="Search"
     />
-    <el-input
+    <kk-input
       v-model="input2"
       class="w-50 m-2"
       placeholder="Please Input"
       :suffix-icon="Search"
     />
-    <el-input
+    <kk-input
       v-model="input3"
       class="w-50 m-2"
       size="small"
@@ -37,20 +37,20 @@
     />
   </div>
   <div class="demo-input-size">
-    <el-input
+    <kk-input
       v-model="input1"
       class="w-50 m-2"
       size="large"
       placeholder="Please Input"
       :prefix-icon="Search"
     />
-    <el-input
+    <kk-input
       v-model="input2"
       class="w-50 m-2"
       placeholder="Please Input"
       :prefix-icon="Search"
     />
-    <el-input
+    <kk-input
       v-model="input3"
       class="w-50 m-2"
       size="small"
@@ -62,6 +62,7 @@
 
 <script lang="ts" setup>
 import { ref } from 'vue'
+import { KkInput } from 'kankan-components'
 import { Search } from '@kankan-components/icons-vue'
 const input1 = ref('')
 const input2 = ref('')

+ 9 - 8
docs/examples/input/with-icon.vue

@@ -4,13 +4,13 @@
       <span class="ml-3 w-35 text-gray-600 inline-flex items-center"
         >Using attributes</span
       >
-      <el-input
+      <kk-input
         v-model="input1"
         class="w-50 m-2"
         placeholder="Pick a date"
         :suffix-icon="Calendar"
       />
-      <el-input
+      <kk-input
         v-model="input2"
         class="w-50 m-2"
         placeholder="Type something"
@@ -23,22 +23,23 @@
       <span class="ml-3 w-35 text-gray-600 inline-flex items-center"
         >Using slots</span
       >
-      <el-input v-model="input3" class="w-50 m-2" placeholder="Pick a date">
+      <kk-input v-model="input3" class="w-50 m-2" placeholder="Pick a date">
         <template #suffix>
-          <el-icon class="el-input__icon"><calendar /></el-icon>
+          <kk-icon class="el-input__icon"><calendar /></kk-icon>
         </template>
-      </el-input>
-      <el-input v-model="input4" class="w-50 m-2" placeholder="Type something">
+      </kk-input>
+      <kk-input v-model="input4" class="w-50 m-2" placeholder="Type something">
         <template #prefix>
-          <el-icon class="el-input__icon"><search /></el-icon>
+          <kk-icon class="el-input__icon"><search /></kk-icon>
         </template>
-      </el-input>
+      </kk-input>
     </el-row>
   </div>
 </template>
 
 <script setup lang="ts">
 import { ref } from 'vue'
+import { KkIcon, KkInput } from 'kankan-components'
 import { Calendar, Search } from '@kankan-components/icons-vue'
 const input1 = ref('')
 const input2 = ref('')

+ 98 - 96
docs/zh-CN/component/input.md

@@ -1,23 +1,23 @@
 ---
 title: Input
-lang: en-US
+lang: zh-CN
 ---
 
-# Input
+# Input 输入框
 
-Input data using mouse or keyboard.
+通过鼠标或键盘输入字符
 
 :::warning
 
-Input is a controlled component, it **always shows Vue binding value**.
+Input 为受控组件,它 总会显示 Vue 绑定值。
 
-Under normal circumstances, `input` event should be handled. Its handler should update component's binding value (or use `v-model`). Otherwise, input box's value will not change.
+在正常情况下,`input` 的输入事件应该被正常响应。 它的处理程序应该更新组件的绑定值 (或使用 `v-model`)。 否则,输入框的值将不会改变。
 
-Do not support `v-model` modifiers.
+不支持 `v-model` 修饰符。
 
 :::
 
-## Basic usage
+## 基础用法
 
 :::demo
 
@@ -25,25 +25,25 @@ input/basic
 
 :::
 
-## Disabled
+## 禁用状态
 
-:::demo Disable the Input with the `disabled` attribute.
+:::demo 通过 `disabled` 属性指定是否禁用 input 组件
 
 input/disabled
 
 :::
 
-## Clearable
+## 一键清空
 
-:::demo Make the Input clearable with the `clearable` attribute.
+:::demo 使用`clearable`属性即可得到一个可一键清空的输入框
 
 input/clearable
 
 :::
 
-## Formatter
+## 格式化
 
-Display value within it's situation with `formatter`, and we usually use `parser` at the same time.
+在 formatter 的情况下显示值,我们通常同时使用 `parser`
 
 :::demo
 
@@ -51,37 +51,37 @@ input/formatter
 
 :::
 
-## Password box
+## 密码框
 
-:::demo Make a toggle-able password Input with the `show-password` attribute.
+:::demo 使用 `show-password` 属性即可得到一个可切换显示隐藏的密码框
 
 input/password
 
 :::
 
-## Input with icon
+## 带图标的输入框
 
-Add an icon to indicate input type.
+带有图标标记输入类型
 
-:::demo To add icons in Input, you can simply use `prefix-icon` and `suffix-icon` attributes. Also, the `prefix` and `suffix` named slots works as well.
+:::demo 要在输入框中添加图标,你可以简单地使用 ` prefix-icon` 和 `suffix-icon` 属性。 另外, `prefix` 和 `suffix` 命名的插槽也能正常工作。
 
 input/with-icon
 
 :::
 
-## Textarea
+## 文本域
 
-Resizable for entering multiple lines of text information. Add attribute `type="textarea"` to change `input` into native `textarea`.
+用于输入多行文本信息可缩放的输入框。 添加 `type="textarea"` 属性来将 input 元素转换为原生的 `textarea` 元素。
 
-:::demo Control the height by setting the `rows` prop.
+:::demo 文本域高度可通过 rows 属性控制
 
 input/textarea
 
 :::
 
-## Autosize Textarea
+## 自适应文本域
 
-Setting the `autosize` prop for a textarea type of Input makes the height to automatically adjust based on the content. An options object can be provided to `autosize` to specify the minimum and maximum number of lines the textarea can automatically adjust.
+设置文字输入类型的 `autosize` 属性使得根据内容自动调整的高度。 你可以给 `autosize` 提供一个包含有最大和最小高度的对象,让输入框自动调整。
 
 :::demo
 
@@ -89,27 +89,27 @@ input/auto-sizing-textarea
 
 :::
 
-## Mixed input
+## 复合型输入框
 
-Prepend or append an element, generally a label or a button.
+可以在输入框中前置或后置一个元素,通常是标签或按钮。
 
-:::demo Use `slot` to distribute elements that prepend or append to Input.
+:::demo 可通过 `slot` 来指定在 Input 中分发的前置或者后置的内容。
 
 input/mixed-input
 
 :::
 
-## Sizes
+## 尺寸
 
-:::demo Add `size` attribute to change the size of Input. In addition to the default size, there are two other options: `large`, `small`.
+:::demo 使用 size 属性改变输入框大小。 除了默认大小外,还有另外两个选项: `large`, `small`。
 
 input/various-size
 
 :::
 
-## Limit length
+## 输入长度限制
 
-:::demo `maxlength` and `minlength` attributes of input, they declare a limit on the number of characters a user can input. The "number of characters" is measured using JavaScript string length.Setting the `maxlength` prop for a text or textarea type of Input can limit the length of input value, allows you to show word count by setting `show-word-limit` to `true` at the same time.
+:::demo 使用 `maxlength` 和 `minlength` 属性, 来控制输入内容的最大字数和最小字数。 "字符数"使用 JavaScript 字符串长度来衡量。 为文本或文本输入类型设置 `maxlength` prop 可以限制输入值的长度。 允许你通过设置 `show-word-limit` 到 `true` 来显示剩余字数。
 
 input/length-limiting
 
@@ -117,69 +117,71 @@ input/length-limiting
 
 ## API
 
-### Attributes
-
-| Name                  | Description                                                                                                                            | Type                                                                                                                                                | Default |
-| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
-| type                  | type of input                                                                                                                          | ^[string]`'text' \| 'textarea' \| ...` [native input types](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#Form_%3Cinput%3E_types) | text    |
-| model-value / v-model | binding value                                                                                                                          | ^[string] / ^[number]                                                                                                                               | —       |
-| maxlength             | the max length                                                                                                                         | ^[string] / ^[number]                                                                                                                               | —       |
-| minlength             | same as `minlength` in native input                                                                                                    | ^[number]                                                                                                                                           | —       |
-| show-word-limit       | whether show word count, only works when `type` is 'text' or 'textarea'                                                                | ^[boolean]                                                                                                                                          | false   |
-| placeholder           | placeholder of Input                                                                                                                   | ^[string]                                                                                                                                           | —       |
-| clearable             | whether to show clear button, only works when `type` is not 'textarea'                                                                 | ^[boolean]                                                                                                                                          | false   |
-| formatter             | specifies the format of the value presented input.(only works when `type` is 'text')                                                   | ^[Function]`(value: string \| number) => string`                                                                                                    | —       |
-| parser                | specifies the value extracted from formatter input.(only works when `type` is 'text')                                                  | ^[Function]`(value: string) => string`                                                                                                              | —       |
-| show-password         | whether to show toggleable password input                                                                                              | ^[boolean]                                                                                                                                          | false   |
-| disabled              | whether Input is disabled                                                                                                              | ^[boolean]                                                                                                                                          | false   |
-| size                  | size of Input, works when `type` is not 'textarea'                                                                                     | ^[enum]`'large' \| 'default' \| 'small'`                                                                                                            | —       |
-| prefix-icon           | prefix icon component                                                                                                                  | ^[string] / ^[Component]                                                                                                                            | —       |
-| suffix-icon           | suffix icon component                                                                                                                  | ^[string] / ^[Component]                                                                                                                            | —       |
-| rows                  | number of rows of textarea, only works when `type` is 'textarea'                                                                       | ^[number]                                                                                                                                           | 2       |
-| autosize              | whether textarea has an adaptive height, only works when `type` is 'textarea'. Can accept an object, e.g. `{ minRows: 2, maxRows: 6 }` | ^[boolean] / ^[object]`{ minRows?: number, maxRows?: number }`                                                                                      | false   |
-| autocomplete          | same as `autocomplete` in native input                                                                                                 | ^[string]                                                                                                                                           | off     |
-| name                  | same as `name` in native input                                                                                                         | ^[string]                                                                                                                                           | —       |
-| readonly              | same as `readonly` in native input                                                                                                     | ^[boolean]                                                                                                                                          | false   |
-| max                   | same as `max` in native input                                                                                                          | —                                                                                                                                                   | —       |
-| min                   | same as `min` in native input                                                                                                          | —                                                                                                                                                   | —       |
-| step                  | same as `step` in native input                                                                                                         | —                                                                                                                                                   | —       |
-| resize                | control the resizability                                                                                                               | ^[enum]`'none' \| 'both' \| 'horizontal' \| 'vertical'`                                                                                             | —       |
-| autofocus             | same as `autofocus` in native input                                                                                                    | ^[boolean]                                                                                                                                          | false   |
-| form                  | same as `form` in native input                                                                                                         | `string`                                                                                                                                            | —       |
-| label<A11yTag />      | same as `aria-label` in native input                                                                                                   | ^[string]                                                                                                                                           | —       |
-| tabindex              | input tabindex                                                                                                                         | ^[string] / ^[number]                                                                                                                               | —       |
-| validate-event        | whether to trigger form validation                                                                                                     | ^[boolean]                                                                                                                                          | true    |
-| input-style           | the style of the input element or textarea element                                                                                     | ^[string] / ^[object]`CSSProperties \| CSSProperties[] \| string[]`                                                                                 | {}      |
-
-### Events
-
-| Name   | Description                                                                                           | Type                                           |
-| ------ | ----------------------------------------------------------------------------------------------------- | ---------------------------------------------- |
-| blur   | triggers when Input blurs                                                                             | ^[Function]`(event: FocusEvent) => void`       |
-| focus  | triggers when Input focuses                                                                           | ^[Function]`(event: FocusEvent) => void`       |
-| change | triggers when the input box loses focus or the user presses Enter, only if the modelValue has changed | ^[Function]`(value: string \| number) => void` |
-| input  | triggers when the Input value change                                                                  | ^[Function]`(value: string \| number) => void` |
-| clear  | triggers when the Input is cleared by clicking the clear button                                       | ^[Function]`() => void`                        |
-
-### Slots
-
-| Name    | Description                                                               |
-| ------- | ------------------------------------------------------------------------- |
-| prefix  | content as Input prefix, only works when `type` is not 'textarea'         |
-| suffix  | content as Input suffix, only works when `type` is not 'textarea'         |
-| prepend | content to prepend before Input, only works when `type` is not 'textarea' |
-| append  | content to append after Input, only works when `type` is not 'textarea'   |
-
-### Exposes
-
-| Name           | Description                      | Type                                                    |
-| -------------- | -------------------------------- | ------------------------------------------------------- |
-| blur           | blur the input element           | ^[Function]`() => void`                                 |
-| clear          | clear input value                | ^[Function]`() => void`                                 |
-| focus          | focus the input element          | ^[Function]`() => void`                                 |
-| input          | HTML input element               | ^[object]`Ref<HTMLInputElement>`                        |
-| ref            | HTML element, input or textarea  | ^[object]`Ref<HTMLInputElement \| HTMLTextAreaElement>` |
-| resizeTextarea | resize textarea                  | ^[Function]`() => void`                                 |
-| select         | select the text in input element | ^[Function]`() => void`                                 |
-| textarea       | HTML textarea element            | ^[object]`Ref<HTMLTextAreaElement>`                     |
-| textareaStyle  | style of textarea                | ^[object]`Ref<StyleValue>`                              |
+### 属性
+
+| 属性名                                                              | 说明                                                                                                         | 类型                                                                                                                                                | 默认值 |
+| ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------- | ------ |
+| type                                                                | 类型                                                                                                         | ^[string]`'text' \| 'textarea' \| ...` [native input types](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#Form_%3Cinput%3E_types) | text   |
+| model-value / v-model                                               | 绑定值                                                                                                       | ^[string] / ^[number]                                                                                                                               | —      |
+| maxlength                                                           | 最大输入长度                                                                                                 | ^[string] / ^[number]                                                                                                                               | —      |
+| minlength                                                           | 原生属性,最小输入长度                                                                                       | ^[number]                                                                                                                                           | —      |
+| show-word-limit                                                     | 是否显示统计字数, 只在 `type` 为 'text' 或 'textarea' 的时候生效                                             | ^[boolean]                                                                                                                                          | false  |
+| placeholder                                                         | 输入框占位文本                                                                                               | ^[string]                                                                                                                                           | —      |
+| clearable                                                           | 是否显示清除按钮,只有当 `type` 不是 textarea 时生效                                                         | ^[boolean]                                                                                                                                          | false  |
+| formatter                                                           | 指定输入值的格式。(只有当 `type` 是"text"时才能工作)                                                         | ^[Function]`(value: string \| number) => string`                                                                                                    | —      |
+| parser                                                              | 指定从格式化器输入中提取的值。(仅当 `type` 是"text"时才起作用)                                               | ^[Function]`(value: string) => string`                                                                                                              | —      |
+| show-password                                                       | 是否显示切换密码图标                                                                                         | ^[boolean]                                                                                                                                          | false  |
+| disabled                                                            | 是否禁用                                                                                                     | ^[boolean]                                                                                                                                          | false  |
+| size                                                                | 输入框尺寸,只在 `type` 不为 'textarea' 时有效                                                               | ^[enum]`'large' \| 'default' \| 'small'`                                                                                                            | —      |
+| prefix-icon                                                         | 自定义前缀图标                                                                                               | ^[string] / ^[Component]                                                                                                                            | —      |
+| suffix-icon                                                         | 自定义后缀图标                                                                                               | ^[string] / ^[Component]                                                                                                                            | —      |
+| rows                                                                | 输入框行数,仅 `type` 为 'textarea' 时有效                                                                   | ^[number]                                                                                                                                           | 2      |
+| autosize                                                            | textarea 高度是否自适应,仅 type 为 'textarea' 时生效。 可以接受一个对象,比如: `{ minRows: 2, maxRows: 6 }` | ^[boolean] / ^[object]`{ minRows?: number, maxRows?: number }`                                                                                      | false  |
+| autocomplete                                                        | 原生 autocomplete 属性                                                                                       | ^[string]                                                                                                                                           | off    |
+| name                                                                | 等价于原生 `input` name 属性                                                                                 | ^[string]                                                                                                                                           | —      |
+| readonly                                                            | 原生 `readonly` 属性,是否只读                                                                               |
+| ^[boolean]                                                          | false                                                                                                        |
+| max                                                                 | 原生 `max` 属性,设置最大值 input                                                                            | —                                                                                                                                                   | —      |
+| min                                                                 | 原生属性,设置最小值 input                                                                                   | —                                                                                                                                                   | —      |
+| step                                                                | 原生属性,设置输入字段的合法数字间隔 input                                                                   | —                                                                                                                                                   | —      |
+| resize                                                              | 控制是否能被用户缩放                                                                                         | ^[enum]`'none' \| 'both' \| 'horizontal' \| 'vertical'`                                                                                             | —      |
+| autofocus                                                           | 原生属性,自动获取焦点 input                                                                                 | ^[boolean]                                                                                                                                          | false  |
+| form                                                                | 原生属性 input                                                                                               | `string`                                                                                                                                            | —      |
+| label<A11yTag />                                                    | 等价于原生 input `aria-label` 属性 input                                                                     | ^[string]                                                                                                                                           | —      |
+| tabindex                                                            | 输入框的 tabindex                                                                                            | ^[string] / ^[number]                                                                                                                               | —      |
+| validate-event                                                      | 输入时是否触发表单的校验                                                                                     | ^[boolean]                                                                                                                                          | true   |
+| input-style                                                         | input 元素或 textarea 元素的 style                                                                           |
+| ^[string] / ^[object]`CSSProperties \| CSSProperties[] \| string[]` | {}                                                                                                           |
+
+### 事件
+
+| 事件名 | 说明                                                          | 类型                                           |
+| ------ | ------------------------------------------------------------- | ---------------------------------------------- |
+| blur   | 当选择器的输入框失去焦点时触发 blurs                          | ^[Function]`(event: FocusEvent) => void`       |
+| focus  | 当选择器的输入框获得焦点时触发                                | ^[Function]`(event: FocusEvent) => void`       |
+| change | 仅当 modelValue 改变时,当输入框失去焦点或用户按 Enter 时触发 | ^[Function]`(value: string \| number) => void` |
+| input  | 在 Input 值改变时触发                                         | ^[Function]`(value: string \| number) => void` |
+| clear  | 在点击由 clearable 属性生成的清空按钮时触发                   | ^[Function]`() => void`                        |
+
+### 插槽
+
+| 插槽名  | 说明                                           |
+| ------- | ---------------------------------------------- |
+| prefix  | 输入框头部内容,只对非 `type="textarea"` 有效  |
+| suffix  | 输入框尾部内容,只对非 `type="textarea"` 有效  |
+| prepend | 输入框前置内容,只对非 `type="textarea"` 有效' |
+| append  | 输入框后置内容,只对非 `type="textarea"` 有效  |
+
+### 对外暴露的方法
+
+| 名称           | 说明                        | 类型                                                    |
+| -------------- | --------------------------- | ------------------------------------------------------- |
+| blur           | 使 input 失去焦点           | ^[Function]`() => void`                                 |
+| clear          | 清除 input 值               | ^[Function]`() => void`                                 |
+| focus          | 使 input 获取焦点           | ^[Function]`() => void`                                 |
+| input          | Input HTML 元素             | ^[object]`Ref<HTMLInputElement>`                        |
+| ref            | HTML 元素 input 或 textarea | ^[object]`Ref<HTMLInputElement \| HTMLTextAreaElement>` |
+| resizeTextarea | 改变 textarea 大小          | ^[Function]`() => void`                                 |
+| select         | 选中 input 中的文字         | ^[Function]`() => void`                                 |
+| textarea       | HTML textarea 元素          | ^[object]`Ref<HTMLTextAreaElement>`                     |
+| textareaStyle  | textarea 的样式             | ^[object]`Ref<StyleValue>`                              |

+ 25 - 22
packages/components/basic/input/src/input.vue

@@ -25,9 +25,8 @@
             </kk-icon>
           </span>
         </span>
-
+        <!-- :id="inputId" -->
         <input
-          :id="inputId"
           ref="input"
           :class="nsInput.e('inner')"
           v-bind="attrs"
@@ -105,8 +104,8 @@
 
     <!-- textarea -->
     <template v-else>
+      <!-- :id="inputId" -->
       <textarea
-        :id="inputId"
         ref="textarea"
         :class="nsTextarea.e('inner')"
         v-bind="attrs"
@@ -158,9 +157,10 @@ import {
   Hide as IconHide,
   View as IconView,
 } from '@kankan-components/icons-vue'
+
 import {
   NOOP,
-  ValidateComponentsMap,
+  // ValidateComponentsMap,
   debugWarn,
   isKorean,
   isObject,
@@ -169,8 +169,8 @@ import {
   useAttrs,
   useCursor,
   useDisabled,
-  useFormItem,
-  useFormItemInputId,
+  // useFormItem,
+  // useFormItemInputId,
   useNamespace,
   useSize,
 } from '@kankan-components/hooks'
@@ -229,10 +229,10 @@ const attrs = useAttrs({
     return Object.keys(containerAttrs.value)
   }),
 })
-const { form, formItem } = useFormItem()
-const { inputId } = useFormItemInputId(props, {
-  formItemContext: formItem,
-})
+// const { form, formItem } = useFormItem()
+// const { inputId } = useFormItemInputId(props, {
+//   formItemContext: formItem,
+// })
 const inputSize = useSize()
 const inputDisabled = useDisabled()
 const nsInput = useNamespace('input')
@@ -250,11 +250,14 @@ const textareaCalcStyle = shallowRef(props.inputStyle)
 
 const _ref = computed(() => input.value || textarea.value)
 
-const needStatusIcon = computed(() => form?.statusIcon ?? false)
-const validateState = computed(() => formItem?.validateState || '')
-const validateIcon = computed(
-  () => validateState.value && ValidateComponentsMap[validateState.value]
-)
+// const needStatusIcon = computed(() => form?.statusIcon ?? false)
+// const validateState = computed(() => formItem?.validateState || '')
+// const validateIcon = computed(
+//   () => validateState.value && ValidateComponentsMap[validateState.value]
+// )
+const needStatusIcon = computed(() => false)
+const validateState = computed(() => '')
+const validateIcon = computed(() => validateState.value)
 const passwordIcon = computed(() =>
   passwordVisible.value ? IconView : IconHide
 )
@@ -424,9 +427,9 @@ const handleFocus = (event: FocusEvent) => {
 const handleBlur = (event: FocusEvent) => {
   focused.value = false
   emit('blur', event)
-  if (props.validateEvent) {
-    formItem?.validate?.('blur').catch((err) => debugWarn(err))
-  }
+  // if (props.validateEvent) {
+  //   formItem?.validate?.('blur').catch((err) => debugWarn(err))
+  // }
 }
 
 const handleMouseLeave = (evt: MouseEvent) => {
@@ -458,9 +461,9 @@ watch(
   () => props.modelValue,
   () => {
     nextTick(() => resizeTextarea())
-    if (props.validateEvent) {
-      formItem?.validate?.('change').catch((err) => debugWarn(err))
-    }
+    // if (props.validateEvent) {
+    //   formItem?.validate?.('change').catch((err) => debugWarn(err))
+    // }
   }
 )
 
@@ -484,7 +487,7 @@ watch(
 onMounted(() => {
   if (!props.formatter && props.parser) {
     debugWarn(
-      'ElInput',
+      'KkInput',
       'If you set the parser, you also need to set the formatter.'
     )
   }

+ 2 - 0
packages/kankan-components/component.ts

@@ -2,6 +2,7 @@ import { KkIcon } from '@kankan-components/components/basic/icon'
 import { KkButton } from '@kankan-components/components/basic/button'
 import { KkAudio } from '@kankan-components/components/basic/audio'
 import { KkDialog } from '@kankan-components/components/basic/dialog'
+import { KkInput } from '@kankan-components/components/basic/input'
 
 import { KkTag } from '@kankan-components/components/advance/tag'
 import { KkDaikan } from '@kankan-components/components/advance/daikan'
@@ -12,6 +13,7 @@ export default [
   KkButton,
   KkAudio,
   KkDialog,
+  KkInput,
   KkTag,
   KkDaikan,
 ] as Plugin[]

+ 1 - 0
packages/theme-chalk/src/index.scss

@@ -5,5 +5,6 @@
 @use './audio.scss';
 @use './overlay.scss';
 @use './dialog.scss';
+@use './input.scss';
 // component adv styles
 @use './tag.scss';

+ 520 - 0
packages/theme-chalk/src/input.scss

@@ -0,0 +1,520 @@
+@use 'sass:map';
+
+@use 'mixins/mixins' as *;
+@use 'mixins/var' as *;
+@use 'common/var' as *;
+
+@mixin inset-prepend-border($color) {
+  box-shadow: 1px 0 0 0 $color inset, 0 1px 0 0 $color inset,
+    0 -1px 0 0 $color inset;
+}
+
+@mixin inset-append-border($color) {
+  box-shadow: 0 1px 0 0 $color inset, 0 -1px 0 0 $color inset,
+    -1px 0 0 0 $color inset;
+}
+
+@mixin inset-prepend-input-border($color) {
+  box-shadow: 1px 0 0 0 $color inset, 1px 0 0 0 $color, 0 1px 0 0 $color inset,
+    0 -1px 0 0 $color inset !important;
+}
+
+@mixin inset-append-input-border($color) {
+  box-shadow: -1px 0 0 0 $color, -1px 0 0 0 $color inset, 0 1px 0 0 $color inset,
+    0 -1px 0 0 $color inset !important;
+}
+
+@mixin mixed-input-border($color) {
+  box-shadow: 0 0 0 1px $color inset;
+}
+
+@include b(textarea) {
+  @include set-component-css-var('input', $input);
+}
+
+@include b(textarea) {
+  position: relative;
+  display: inline-block;
+  width: 100%;
+  vertical-align: bottom;
+  font-size: getCssVar('font-size', 'base');
+
+  @include e(inner) {
+    position: relative;
+    display: block;
+    resize: vertical;
+    padding: 5px map.get($input-padding-horizontal, 'default')-$border-width;
+    line-height: 1.5;
+    box-sizing: border-box;
+    width: 100%;
+    font-size: inherit;
+    font-family: inherit;
+    color: var(
+      #{getCssVarName('input-text-color')},
+      map.get($input, 'text-color')
+    );
+    background-color: var(
+      #{getCssVarName('input-bg-color')},
+      map.get($input, 'bg-color')
+    );
+    background-image: none;
+    -webkit-appearance: none;
+    @include inset-input-border(
+      var(
+        #{getCssVarName('input-border-color')},
+        map.get($input, 'border-color')
+      )
+    );
+    border-radius: getCssVarWithDefault(
+      'input-border-radius',
+      map.get($input, 'border-radius')
+    );
+    transition: getCssVar('transition-box-shadow');
+    border: none;
+
+    &::placeholder {
+      color: getCssVarWithDefault(
+        'input-placeholder-color',
+        map.get($input, 'placeholder-color')
+      );
+    }
+
+    &:hover {
+      @include inset-input-border(#{getCssVar('input', 'hover-border-color')});
+    }
+
+    &:focus {
+      outline: none;
+      @include inset-input-border(#{getCssVar('input', 'focus-border-color')});
+    }
+  }
+
+  & .#{$namespace}-input__count {
+    color: getCssVar('color-info');
+    background: getCssVar('fill-color', 'blank');
+    position: absolute;
+    font-size: 12px;
+    line-height: 14px;
+    bottom: 5px;
+    right: 10px;
+  }
+
+  @include when(disabled) {
+    .#{$namespace}-textarea__inner {
+      background-color: map.get($input-disabled, 'fill');
+      border-color: map.get($input-disabled, 'border');
+      color: map.get($input-disabled, 'text-color');
+      cursor: not-allowed;
+
+      &::placeholder {
+        color: map.get($input-disabled, 'placeholder-color');
+      }
+    }
+  }
+
+  @include when(exceed) {
+    .#{$namespace}-textarea__inner {
+      border-color: getCssVar('color-danger');
+    }
+
+    .#{$namespace}-input__count {
+      color: getCssVar('color-danger');
+    }
+  }
+}
+
+@include b(input) {
+  @include set-component-css-var('input', $input);
+}
+
+@include b(input) {
+  @include css-var-from-global('input-height', 'component-size');
+
+  position: relative;
+  font-size: getCssVar('font-size', 'base');
+  display: inline-flex;
+  width: 100%;
+  line-height: getCssVar('input-height');
+  box-sizing: border-box;
+  vertical-align: middle;
+  @include scroll-bar;
+
+  & .#{$namespace}-input__clear,
+  & .#{$namespace}-input__password {
+    color: getCssVar('input-icon-color');
+    font-size: map.get($input-font-size, 'default');
+    cursor: pointer;
+
+    &:hover {
+      color: getCssVar('input-clear-hover-color');
+    }
+  }
+
+  & .#{$namespace}-input__count {
+    height: 100%;
+    display: inline-flex;
+    align-items: center;
+    color: getCssVar('color-info');
+    font-size: 12px;
+
+    .#{$namespace}-input__count-inner {
+      background: getCssVar('fill-color', 'blank');
+      line-height: initial;
+      display: inline-block;
+      padding-left: 8px;
+    }
+  }
+
+  @include e(wrapper) {
+    display: inline-flex;
+    flex-grow: 1;
+    align-items: center;
+    justify-content: center;
+    padding: $border-width map.get($input-padding-horizontal, 'default')-$border-width;
+    background-color: var(
+      #{getCssVarName('input-bg-color')},
+      map.get($input, 'bg-color')
+    );
+    background-image: none;
+    border-radius: getCssVarWithDefault(
+      'input-border-radius',
+      map.get($input, 'border-radius')
+    );
+    transition: getCssVar('transition-box-shadow');
+    @include inset-input-border(
+      var(
+        #{getCssVarName('input-border-color')},
+        map.get($input, 'border-color')
+      )
+    );
+
+    &:hover {
+      @include inset-input-border(#{getCssVar('input', 'hover-border-color')});
+    }
+
+    @include when(focus) {
+      @include inset-input-border(#{getCssVar('input', 'focus-border-color')});
+    }
+  }
+
+  @include e(inner) {
+    // use map.get as default value for date picker range
+    @include set-css-var-value(
+      'input-inner-height',
+      calc(
+        var(
+            #{getCssVarName('input-height')},
+            #{map.get($input-height, 'default')}
+          ) - $border-width * 2
+      )
+    );
+
+    width: 100%;
+    flex-grow: 1;
+    -webkit-appearance: none;
+    color: var(
+      #{getCssVarName('input-text-color')},
+      map.get($input, 'text-color')
+    );
+    font-size: inherit;
+    height: getCssVar('input-inner-height');
+    line-height: getCssVar('input-inner-height');
+    padding: 0;
+    outline: none;
+    border: none;
+    background: none;
+    box-sizing: border-box;
+
+    &:focus {
+      outline: none;
+    }
+
+    &::placeholder {
+      color: getCssVarWithDefault(
+        'input-placeholder-color',
+        map.get($input, 'placeholder-color')
+      );
+    }
+
+    // override edge default style
+    &[type='password']::-ms-reveal {
+      display: none;
+    }
+  }
+
+  @each $slot in (prefix, suffix) {
+    @include e($slot) {
+      display: inline-flex;
+      white-space: nowrap;
+      flex-shrink: 0;
+      flex-wrap: nowrap;
+      height: 100%;
+      text-align: center;
+      color: var(
+        #{getCssVarName('input-icon-color')},
+        map.get($input, 'icon-color')
+      );
+      transition: all getCssVar('transition-duration');
+      pointer-events: none;
+    }
+
+    @include e(#{$slot}-inner) {
+      pointer-events: all;
+      display: inline-flex;
+      align-items: center;
+      justify-content: center;
+
+      @if $slot == prefix {
+        > :last-child {
+          margin-right: 8px;
+        }
+
+        > :first-child {
+          &,
+          &.#{$namespace}-input__icon {
+            margin-left: 0;
+          }
+        }
+      } @else {
+        > :first-child {
+          margin-left: 8px;
+        }
+      }
+    }
+  }
+
+  & .#{$namespace}-input__icon {
+    height: inherit;
+    line-height: inherit;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    transition: all getCssVar('transition-duration');
+    margin-left: 8px;
+  }
+
+  @include e(validateIcon) {
+    pointer-events: none;
+  }
+
+  @include when(active) {
+    .#{$namespace}-input__wrapper {
+      @include mixed-input-border(
+        var(
+          #{getCssVarName('input-focus-color')},
+          map.get($input, 'focus-color')
+        )
+      );
+    }
+  }
+
+  @include when(disabled) {
+    cursor: not-allowed;
+
+    .#{$namespace}-input__wrapper {
+      background-color: map.get($input-disabled, 'fill');
+      @include mixed-input-border(map.get($input-disabled, 'border'));
+    }
+
+    .#{$namespace}-input__inner {
+      color: map.get($input-disabled, 'text-color');
+      -webkit-text-fill-color: map.get($input-disabled, 'text-color');
+      cursor: not-allowed;
+
+      &::placeholder {
+        color: map.get($input-disabled, 'placeholder-color');
+      }
+    }
+
+    .#{$namespace}-input__icon {
+      cursor: not-allowed;
+    }
+  }
+
+  @include when(exceed) {
+    .#{$namespace}-input__wrapper {
+      @include mixed-input-border(#{getCssVar('color-danger')});
+    }
+
+    .#{$namespace}-input__suffix {
+      .#{$namespace}-input__count {
+        color: getCssVar('color-danger');
+      }
+    }
+  }
+
+  @each $size in (large, small) {
+    @include m($size) {
+      @include css-var-from-global('input-height', ('component-size', $size));
+
+      font-size: map.get($input-font-size, $size);
+
+      @include e(wrapper) {
+        padding: $border-width map.get($input-padding-horizontal, $size)-$border-width;
+      }
+
+      @include e(inner) {
+        @include set-css-var-value(
+          'input-inner-height',
+          calc(
+            var(
+                #{getCssVarName('input-height')},
+                #{map.get($input-height, $size)}
+              ) - $border-width * 2
+          )
+        );
+      }
+    }
+  }
+}
+
+@include b(input-group) {
+  display: inline-flex;
+  width: 100%;
+  align-items: stretch;
+
+  @include e((append, prepend)) {
+    background-color: getCssVar('fill-color', 'light');
+    color: getCssVar('color-info');
+    position: relative;
+    display: inline-flex;
+    align-items: center;
+    justify-content: center;
+    min-height: 100%;
+    border-radius: getCssVar('input-border-radius');
+    padding: 0 20px;
+    white-space: nowrap;
+
+    &:focus {
+      outline: none;
+    }
+
+    .#{$namespace}-select,
+    .#{$namespace}-button {
+      display: inline-block;
+      margin: 0 -20px;
+    }
+
+    button.#{$namespace}-button,
+    button.#{$namespace}-button:hover,
+    div.#{$namespace}-select .#{$namespace}-input__wrapper,
+    div.#{$namespace}-select:hover .#{$namespace}-input__wrapper {
+      border-color: transparent;
+      background-color: transparent;
+      color: inherit;
+    }
+
+    .#{$namespace}-button,
+    .#{$namespace}-input {
+      font-size: inherit;
+    }
+  }
+
+  @include e(prepend) {
+    border-right: 0;
+    border-top-right-radius: 0;
+    border-bottom-right-radius: 0;
+    @include inset-prepend-border(#{getCssVar('input-border-color')});
+  }
+
+  @include e(append) {
+    border-left: 0;
+    border-top-left-radius: 0;
+    border-bottom-left-radius: 0;
+    @include inset-append-border(#{getCssVar('input-border-color')});
+  }
+
+  @include m(prepend) {
+    > .#{$namespace}-input__wrapper {
+      border-top-left-radius: 0;
+      border-bottom-left-radius: 0;
+    }
+
+    @include e(prepend) {
+      .#{$namespace}-select {
+        .#{$namespace}-input {
+          .#{$namespace}-input__inner {
+            box-shadow: none !important;
+          }
+          .#{$namespace}-input__wrapper {
+            border-top-right-radius: 0;
+            border-bottom-right-radius: 0;
+            @include inset-prepend-border(#{getCssVar('input-border-color')});
+          }
+          &.is-focus {
+            .#{$namespace}-input__inner {
+              box-shadow: none !important;
+            }
+            .#{$namespace}-input__wrapper {
+              @include inset-prepend-input-border(
+                getCssVar('input-focus-border-color')
+              );
+              z-index: 2;
+              &:focus {
+                outline: none;
+                z-index: 2;
+                @include inset-prepend-input-border(
+                  getCssVar('input-focus-border-color')
+                );
+              }
+            }
+          }
+        }
+        &:hover {
+          .#{$namespace}-input__inner {
+            box-shadow: none !important;
+          }
+          .#{$namespace}-input__wrapper {
+            z-index: 1;
+            @include inset-prepend-input-border(
+              getCssVar('input-hover-border-color')
+            );
+          }
+        }
+      }
+    }
+  }
+
+  @include m(append) {
+    > .#{$namespace}-input__wrapper {
+      border-top-right-radius: 0;
+      border-bottom-right-radius: 0;
+    }
+    @include e(append) {
+      .#{$namespace}-select {
+        .#{$namespace}-input {
+          .#{$namespace}-input__inner {
+            box-shadow: none !important;
+          }
+          .#{$namespace}-input__wrapper {
+            border-top-left-radius: 0;
+            border-bottom-left-radius: 0;
+            @include inset-append-border(#{getCssVar('input-border-color')});
+          }
+          &.is-focus {
+            .#{$namespace}-input__inner {
+              box-shadow: none !important;
+            }
+            .#{$namespace}-input__wrapper {
+              z-index: 2;
+              @include inset-append-input-border(
+                getCssVar('input-focus-border-color')
+              );
+            }
+          }
+        }
+        &:hover {
+          .#{$namespace}-input__inner {
+            box-shadow: none !important;
+          }
+          .#{$namespace}-input__wrapper {
+            z-index: 1;
+            @include inset-append-input-border(
+              getCssVar('input-hover-border-color')
+            );
+          }
+        }
+      }
+    }
+  }
+}

+ 1 - 0
packages/tokens/index.ts

@@ -1,3 +1,4 @@
 export * from './config-provider'
 export * from './dialog'
 export * from './button'
+// export * from './form'

+ 1 - 0
packages/utils/functions.ts

@@ -0,0 +1 @@
+export { NOOP } from '@vue/shared'

+ 2 - 0
packages/utils/i18n.ts

@@ -0,0 +1,2 @@
+export const isKorean = (text: string) =>
+  /([(\uAC00-\uD7AF)|(\u3130-\u318F)])+/gi.test(text)

+ 2 - 0
packages/utils/index.ts

@@ -5,3 +5,5 @@ export * from './types'
 export * from './objects'
 export * from './error'
 export * from './typescript'
+export * from './functions'
+export * from './i18n'