diff --git a/.changeset/five-masks-shave.md b/.changeset/five-masks-shave.md new file mode 100644 index 000000000..0261468c9 --- /dev/null +++ b/.changeset/five-masks-shave.md @@ -0,0 +1,6 @@ +--- +"@hi-ui/input": minor +"@hi-ui/select": minor +--- + +feat: add prefix api diff --git a/.changeset/hip-dryers-beam.md b/.changeset/hip-dryers-beam.md new file mode 100644 index 000000000..c66140270 --- /dev/null +++ b/.changeset/hip-dryers-beam.md @@ -0,0 +1,5 @@ +--- +"@hi-ui/hiui": patch +--- + +feat(input&select): add prefix api diff --git a/packages/ui/input/src/MockInput.tsx b/packages/ui/input/src/MockInput.tsx index 52768a8e1..759ebc820 100644 --- a/packages/ui/input/src/MockInput.tsx +++ b/packages/ui/input/src/MockInput.tsx @@ -4,6 +4,7 @@ import { __DEV__ } from '@hi-ui/env' import { useUncontrolledState } from '@hi-ui/use-uncontrolled-state' import { CloseCircleFilled } from '@hi-ui/icons' import type { HiBaseAppearanceEnum, HiBaseDataItem, HiBaseHTMLFieldProps } from '@hi-ui/core' +import { isArray } from '@hi-ui/type-assertion' const _role = 'mock-input' const _prefix = getPrefixCls(_role) @@ -34,7 +35,8 @@ export const MockInput = forwardRef( appearance = 'line', clearableTrigger = 'hover', displayRender, - suffix, + prefix, + suffix: suffixProp, onMouseOver, onMouseLeave, ...rest @@ -82,6 +84,7 @@ export const MockInput = forwardRef( ) const hasValue = !!displayValue + const suffix = isArray(suffixProp) ? suffixProp : [suffixProp] // 在开启 clearable 下展示 清除内容按钮,可点击进行内容清除 const showClearableIcon = useMemo(() => { @@ -114,12 +117,14 @@ export const MockInput = forwardRef( }} {...rest} > + {prefix ? {prefix} : null} {hasValue ? ( {displayValue} ) : ( {placeholder} )} - {suffix || showClearableIcon ? ( + {suffix[1] ? {suffix[1]} : null} + {suffix[0] || showClearableIcon ? ( {showClearableIcon ? ( ( ) : ( - suffix + suffix[0] )} ) : null} @@ -186,10 +191,14 @@ export type MockInputProps = HiBaseHTMLFieldProps< * 输入框占位符 */ placeholder?: string + /** + * 输入框前置内容 + */ + prefix?: React.ReactNode /** * 输入框后置内容 */ - suffix?: React.ReactNode + suffix?: React.ReactNode | React.ReactNode[] /** * 点击 Input 时触发回调 */ diff --git a/packages/ui/input/src/styles/mock-input.scss b/packages/ui/input/src/styles/mock-input.scss index 49e6e624d..793f0de98 100644 --- a/packages/ui/input/src/styles/mock-input.scss +++ b/packages/ui/input/src/styles/mock-input.scss @@ -13,7 +13,6 @@ $mock-input-prefix: '#{$component-prefix}-mock-input' !default; overflow: hidden; display: inline-flex; align-items: center; - justify-content: space-between; flex: 1; transition-property: all; transition-duration: use-motion-duration('normal'); @@ -48,6 +47,11 @@ $mock-input-prefix: '#{$component-prefix}-mock-input' !default; } } + &__placeholder, + &__value { + flex: 1; + } + &__placeholder { width: auto; overflow: hidden; @@ -82,16 +86,25 @@ $mock-input-prefix: '#{$component-prefix}-mock-input' !default; } } - &__suffix { + &__prefix, + &__suffix, + &__secondary-suffix { display: inline-flex; align-items: center; flex-shrink: 0; color: use-color('gray', 400); font-size: use-text-size('lg'); - padding-left: use-spacing(4); text-align: center; } + &__prefix { + margin-right: use-spacing(4); + } + + &__suffix { + padding-left: use-spacing(4); + } + &__value { box-sizing: border-box; display: inline-block; diff --git a/packages/ui/input/stories/index.stories.tsx b/packages/ui/input/stories/index.stories.tsx index b4194ef97..8ad17621d 100644 --- a/packages/ui/input/stories/index.stories.tsx +++ b/packages/ui/input/stories/index.stories.tsx @@ -14,7 +14,7 @@ export * from './auto-focus.stories' export * from './focus.stories' export * from './trim.stories' export * from './type.stories' -export * from './format.stories' +// export * from './format.stories' export * from './with-tooltip.stories' // export * from './mock.stories' diff --git a/packages/ui/select/src/Select.tsx b/packages/ui/select/src/Select.tsx index ebe34d8d7..8c62d8b74 100644 --- a/packages/ui/select/src/Select.tsx +++ b/packages/ui/select/src/Select.tsx @@ -72,6 +72,8 @@ export const Select = forwardRef( data: dataProp, fieldNames, size = 'md', + prefix, + suffix, onSelect: onSelectProp, onSearch: onSearchProp, onKeyDown: onKeyDownProp, @@ -249,7 +251,8 @@ export const Select = forwardRef( } : undefined } - suffix={menuVisible ? : } + prefix={prefix} + suffix={[menuVisible ? : , suffix]} focused={menuVisible} value={value} onChange={(value, item) => { @@ -369,6 +372,14 @@ export interface SelectProps * 设置大小 */ size?: HiBaseSizeEnum + /** + * 选择框前置内容 + */ + prefix?: React.ReactNode + /** + * 选择框后置内容 + */ + suffix?: React.ReactNode } ;(Select as any).HiName = 'Select' diff --git a/packages/ui/select/stories/addon.stories.tsx b/packages/ui/select/stories/addon.stories.tsx new file mode 100644 index 000000000..3f987a6c3 --- /dev/null +++ b/packages/ui/select/stories/addon.stories.tsx @@ -0,0 +1,37 @@ +import React from 'react' +import Select from '../src' +import { AppStoreOutlined, InfoCircleOutlined } from '@hi-ui/icons' + +/** + * @title 前后内置元素 + * @desc 将选择框与内置的其他元素组合使用 + */ +export const Addon = () => { + const [data] = React.useState([ + { title: '电视', id: '3', disabled: false }, + { title: '手机', id: '2' }, + { title: '笔记本', id: '4', disabled: false }, + { + title: '生活周边超长文案展示超长文案展示', + id: '5', + }, + { title: '办公', id: '6' }, + { title: '生活周边7', id: '7' }, + { title: '办公8', id: '8' }, + ]) + + return ( + <> +

Addon

+
+