diff --git a/components/atom/input/demo/articles/ArticleAddonAndIcon.js b/components/atom/input/demo/articles/ArticleAddonAndIcon.js index edb5d084fd..25567576c0 100644 --- a/components/atom/input/demo/articles/ArticleAddonAndIcon.js +++ b/components/atom/input/demo/articles/ArticleAddonAndIcon.js @@ -130,6 +130,86 @@ const ArticleAddonAndIcon = ({className}) => { /> +

Interactive Icons

+ + Icons can be made interactive by adding click handlers. This is useful for actions like search, clear input, or + triggering additional functionality. + + + + Left Icon Actions + + + + + } + ariaLabelLeftIcon="Show help information" + onClickLeftIcon={() => alert('Email format: example@domain.com')} + /> + + + + Right Icon Actions + + + + } + ariaLabelRightIcon="Clear input" + onClickRightIcon={() => { + document.getElementById('input-clear-action').value = '' + }} + /> + + + +

Button Customization

+ + Use leftIconButtonProps and rightIconButtonProps to customize the appearance and + behavior of icon buttons. + + + + + + Custom Button Designs + + + + + } + ariaLabelLeftIcon="Search" + onClickLeftIcon={() => alert('Searching...')} + leftIconButtonProps={{ + style: {backgroundColor: '#1890ff', color: '#fff'} + }} + /> + + + + + + + } + ariaLabelRightIcon="Apply filters" + onClickRightIcon={() => alert('Applying filters...')} + rightIconButtonProps={{ + style: {backgroundColor: 'red', color: '#fff'} + }} + /> + + ) } diff --git a/components/atom/input/src/Input/Wrappers/Icons/InputIcons.js b/components/atom/input/src/Input/Wrappers/Icons/InputIcons.js index dbc5617aa8..1cae700cad 100644 --- a/components/atom/input/src/Input/Wrappers/Icons/InputIcons.js +++ b/components/atom/input/src/Input/Wrappers/Icons/InputIcons.js @@ -3,15 +3,26 @@ import PropTypes from 'prop-types' import { BASE_CLASS_ICON, + BASE_CLASS_ICON_BUTTON, + BASE_CLASS_ICON_BUTTON_CONTAINER, BASE_CLASS_ICON_COMPONENT, - BASE_CLASS_ICON_COMPONENT_HANDLER, BASE_CLASS_ICON_COMPONENT_LEFT, BASE_CLASS_ICON_COMPONENT_RIGHT, BASE_CLASS_ICON_LEFT, BASE_CLASS_ICON_RIGHT } from './config.js' -const InputIcons = ({leftIcon, rightIcon, onClickLeftIcon, onClickRightIcon, children}) => { +const InputIcons = ({ + leftIcon, + rightIcon, + onClickLeftIcon, + onClickRightIcon, + ariaLabelLeftIcon, + ariaLabelRightIcon, + leftIconButtonProps, + rightIconButtonProps, + children +}) => { if (!(leftIcon || rightIcon)) { return children } @@ -23,6 +34,10 @@ const InputIcons = ({leftIcon, rightIcon, onClickLeftIcon, onClickRightIcon, chi onClickRightIcon && onClickRightIcon(event) } + const defaultButtonProps = { + type: 'button' + } + return (
{leftIcon && ( - - {leftIcon} - + <> + {onClickLeftIcon ? ( + + ) : ( + {leftIcon} + )} + )} {children} {rightIcon && ( - - {rightIcon} - + <> + {onClickRightIcon ? ( + + ) : ( + {rightIcon} + )} + )}
) @@ -69,7 +109,19 @@ InputIcons.propTypes = { onClickLeftIcon: PropTypes.func, /* Right icon click callback */ - onClickRightIcon: PropTypes.func + onClickRightIcon: PropTypes.func, + + /* Right icon aria-label */ + ariaLabelRightIcon: PropTypes.string, + + /* Left icon aria-label */ + ariaLabelLeftIcon: PropTypes.string, + + /* Left icon button props */ + leftIconButtonProps: PropTypes.object, + + /* Right icon button props */ + rightIconButtonProps: PropTypes.object } export default InputIcons diff --git a/components/atom/input/src/Input/Wrappers/Icons/config.js b/components/atom/input/src/Input/Wrappers/Icons/config.js index 4d415eb0d6..3989a116a1 100644 --- a/components/atom/input/src/Input/Wrappers/Icons/config.js +++ b/components/atom/input/src/Input/Wrappers/Icons/config.js @@ -9,6 +9,7 @@ export const BASE_CLASS_ICON = `${BASE}--withIcon` export const BASE_CLASS_ICON_LEFT = `${BASE_CLASS_ICON}--${ICON_TYPES.LEFT}` export const BASE_CLASS_ICON_RIGHT = `${BASE_CLASS_ICON}--${ICON_TYPES.RIGHT}` export const BASE_CLASS_ICON_COMPONENT = `${BASE_CLASS_ICON}-icon` -export const BASE_CLASS_ICON_COMPONENT_HANDLER = `${BASE_CLASS_ICON_COMPONENT}--withHandler` +export const BASE_CLASS_ICON_BUTTON = `${BASE_CLASS_ICON}-button` +export const BASE_CLASS_ICON_BUTTON_CONTAINER = `${BASE_CLASS_ICON}-button-container` export const BASE_CLASS_ICON_COMPONENT_LEFT = `${BASE_CLASS_ICON_COMPONENT}--${ICON_TYPES.LEFT}` export const BASE_CLASS_ICON_COMPONENT_RIGHT = `${BASE_CLASS_ICON_COMPONENT}--${ICON_TYPES.RIGHT}` diff --git a/components/atom/input/src/Input/Wrappers/Icons/index.scss b/components/atom/input/src/Input/Wrappers/Icons/index.scss index f493df3295..b699cafdcd 100644 --- a/components/atom/input/src/Input/Wrappers/Icons/index.scss +++ b/components/atom/input/src/Input/Wrappers/Icons/index.scss @@ -10,6 +10,33 @@ padding-right: $pr-atom-input-input; } + &-button { + @include reset-button; + position: relative; + padding: 0; + min-width: 0; + + // Expand clickable area + &::before { + content: ''; + position: absolute; + top: -$m-m; + bottom: -$m-m; + left: -$m-m; + right: -$m-m; + background: transparent; + } + + &-container { + width: $sz-icon-m; + } + + &:hover { + background-color: $c-gray-light-3; + border-radius: $p-xs; + } + } + &-icon { align-items: center; color: $c-atom-input-icon; @@ -21,12 +48,6 @@ top: $t-atom-input-icon; transform: translateY($trf-ty-atom-input-icon); width: $w-atom-input-icon; - pointer-events: none; - - &--withHandler { - cursor: pointer; - pointer-events: auto; - } &--left { left: $l-atom-input-icon; @@ -35,10 +56,5 @@ &--right { right: $r-atom-input-icon; } - - & > * { - height: 100%; - width: 100%; - } } } diff --git a/components/atom/input/src/Input/index.js b/components/atom/input/src/Input/index.js index 979558b829..2a03e1f6a1 100644 --- a/components/atom/input/src/Input/index.js +++ b/components/atom/input/src/Input/index.js @@ -19,6 +19,10 @@ const BaseInput = forwardRef( children, onClickLeftIcon, onClickRightIcon, + ariaLabelLeftIcon, + ariaLabelRightIcon, + leftIconButtonProps, + rightIconButtonProps, size = SIZES.MEDIUM, shape, ...inputProps @@ -33,6 +37,10 @@ const BaseInput = forwardRef( rightIcon={rightIcon} onClickLeftIcon={onClickLeftIcon} onClickRightIcon={onClickRightIcon} + ariaLabelLeftIcon={ariaLabelLeftIcon} + ariaLabelRightIcon={ariaLabelRightIcon} + leftIconButtonProps={leftIconButtonProps} + rightIconButtonProps={rightIconButtonProps} > {children} @@ -61,6 +69,14 @@ BaseInput.propTypes = { onClickLeftIcon: PropTypes.func, /* Right icon click callback */ onClickRightIcon: PropTypes.func, + /* Right icon aria-label */ + ariaLabelRightIcon: PropTypes.string, + /* Left icon aria-label */ + ariaLabelLeftIcon: PropTypes.string, + /* Left icon button props */ + leftIconButtonProps: PropTypes.object, + /* Right icon button props */ + rightIconButtonProps: PropTypes.object, /* Sets the size of the inputAddon */ size: PropTypes.oneOf(Object.values(SIZES)), /* Sets the shape of the input */