diff --git a/.gitignore b/.gitignore index d424f6a89a81febefe10b78217d70eb6d84a453a..9c5f67e6d7e03aa92e9f114abf5840437d00b36d 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ dist dist-ssr *.local package-lock.json +.history diff --git a/devui/search/class-search.ts b/devui/search/class-search.ts new file mode 100644 index 0000000000000000000000000000000000000000..b75d4381b5f76fa9b2b6bff44c37313d0d7aa3c8 --- /dev/null +++ b/devui/search/class-search.ts @@ -0,0 +1,17 @@ +import { computed, ComputedRef } from 'vue'; +import { SearchProps } from './use-search' +const SIZE_CLASS = { + lg: 'lg', + sm: 'sm', +} as const +const ICON_POSITION = { + right: 'right', + left: 'left', +} +export const getRootClass = (props: SearchProps): ComputedRef => { + return computed(() => ({ + 'd-search': true, + [`d-search__${props.size}`]: SIZE_CLASS[props.size], + [`d-search__${props.iconPosition}`]: ICON_POSITION[props.iconPosition], + })) +} diff --git a/devui/search/demo/demo-basic.tsx b/devui/search/demo/demo-basic.tsx new file mode 100644 index 0000000000000000000000000000000000000000..c94830dfccde0c77b72150a0900fa32b54cc2885 --- /dev/null +++ b/devui/search/demo/demo-basic.tsx @@ -0,0 +1,35 @@ +import { defineComponent, ref } from 'vue' +import DSearch from '../search' + +export default defineComponent({ + setup() { + return () => ( +
+
+
{ 'Small' }
+ +
+
+
{ 'Middle' }
+ +
+
+
{ 'Large' }
+ +
+
+
{ 'Disabled' }
+ +
+
+ ) + }, +}) \ No newline at end of file diff --git a/devui/search/demo/search-demo.scss b/devui/search/demo/search-demo.scss new file mode 100644 index 0000000000000000000000000000000000000000..f03923e917aa1d66e96aa898fd8ef4a9736b2f81 --- /dev/null +++ b/devui/search/demo/search-demo.scss @@ -0,0 +1,3 @@ +.demo-d-search { + width: 200px; +} diff --git a/devui/search/demo/search-demo.tsx b/devui/search/demo/search-demo.tsx index 8ca5f9dbbd10ce2a8d12a1bbbdb14ef3d5f4f9dc..87f008d7ed9714f92761df74316a06b59e64ce82 100644 --- a/devui/search/demo/search-demo.tsx +++ b/devui/search/demo/search-demo.tsx @@ -1,12 +1,18 @@ import { defineComponent } from 'vue' +import { useDemo } from 'hooks/use-demo'; +import DemoBasic from './demo-basic'; +import DemoBasicCode from './demo-basic?raw'; +import './search-demo.scss'; export default defineComponent({ - name: 'd-search-demo', - props: { - }, - setup(props, ctx) { - return () => { - return
devui-search-demo
- } + render () { + return useDemo([ + { + id: 'demo-basic', + title: '基本用法', + code: DemoBasicCode, + content: + } + ]); } }) \ No newline at end of file diff --git a/devui/search/search.scss b/devui/search/search.scss new file mode 100644 index 0000000000000000000000000000000000000000..2794d35f36484b8e20378362939a198df330b05e --- /dev/null +++ b/devui/search/search.scss @@ -0,0 +1,38 @@ +@import '../style/mixins/size'; +@import '../style/mixins/flex'; + +.d-search { + position: relative; + @include flex; + + input { + padding-right: 30px; + } + + &__icon { + pointer-events: all; + cursor: pointer; + padding: 0 10px; + position: absolute; + right: 0; + top: 0; + @include size(36px, 28px); + @include flex; + } + + &__sm { + .d-search__icon { + @include size(34px, 26px); + } + } + + &__lg { + .d-search__icon { + @include size(46px, 46px); + } + + input { + padding-right: 36px; + } + } +} diff --git a/devui/search/search.tsx b/devui/search/search.tsx index 29717923663a07f291ff8eb9b31dccde19fae282..fca145f67fe8202becf5e40eadeae11cf78e3334 100644 --- a/devui/search/search.tsx +++ b/devui/search/search.tsx @@ -1,12 +1,52 @@ import { defineComponent } from 'vue' +import { SearchProps, searchProps } from './use-search' +import { getRootClass } from './class-search' +import DTextInput from '../text-input/src/text-input'; +import './search.scss' +const KEYS_MAP = { + enter: 'Enter' +} as const + export default defineComponent({ - name: 'd-search', - props: { - }, - setup(props, ctx) { + name: 'DSearch', + props: searchProps, + setup(props: SearchProps, ctx) { + const rootClasses = getRootClass(props) + const onInputKeydown = ($event: KeyboardEvent) => { + switch ($event.key) { + case KEYS_MAP.enter: + handleEnter($event); + break; + default: + break; + } + }; + const handleEnter = ($event: KeyboardEvent) => { + if ($event.target instanceof HTMLInputElement) { + console.log($event.target.value) + const value = $event.target.value + if (value.length > 0) { + ctx.emit('searchFn', value) + } + } + } return () => { - return
devui-search
+ return ( +
+ +
+ + + +
+
+ ) } } }) \ No newline at end of file diff --git a/devui/search/use-search.ts b/devui/search/use-search.ts new file mode 100644 index 0000000000000000000000000000000000000000..fa7703e39eb41e75c25dc325582803c5801c1826 --- /dev/null +++ b/devui/search/use-search.ts @@ -0,0 +1,47 @@ +import { PropType, ExtractPropTypes } from 'vue' +type Size = 'lg' | 'sm' +type IconPosition = 'right' | 'left' +export const searchProps = { + size: { + type: String as PropType, + default: '', + }, + placeholder: { + type: String, + default: '请输入关键字' + }, + maxLength: { + type: Number, + default: Number.MAX_SAFE_INTEGER, + }, + delay: { + type: Number, + default: 300, + }, + disabled: { + type: Boolean, + default: false + }, + autoFocus: { + type: Boolean, + default: false + }, + isKeyupSearch: { + type: Boolean, + default: false + }, + iconPosition: { + type: String as PropType, + default: 'right', + }, + noBorder: { + type: Boolean, + default: false + }, + cssClass: { + type: String, + default: '' + } +} + +export type SearchProps = ExtractPropTypes diff --git a/devui/style/mixins/_flex.scss b/devui/style/mixins/_flex.scss new file mode 100644 index 0000000000000000000000000000000000000000..506eac1d8340a08cb50d556c120023e55fb57b0b --- /dev/null +++ b/devui/style/mixins/_flex.scss @@ -0,0 +1,9 @@ +@mixin flex($justifyContent: center, $alignItem: center,) { + display: flex; + justify-content: $justifyContent; + align-items: $alignItem; +} + +@mixin flex-direction($direction: column) { + flex-direction: $direction; +}