From 723ba8b31d1b7d0c7d901b2466a364b2a3616a76 Mon Sep 17 00:00:00 2001 From: DMoon Date: Mon, 8 Apr 2024 16:26:37 +0800 Subject: [PATCH 1/2] fix: pass down disabled prop in the rowComp Hoc --- .../core/src/mixins/__tests__/rowComp.test.js | 13 +- packages/core/src/mixins/rowComp.js | 366 +++++++++--------- 2 files changed, 195 insertions(+), 184 deletions(-) diff --git a/packages/core/src/mixins/__tests__/rowComp.test.js b/packages/core/src/mixins/__tests__/rowComp.test.js index 78089bd8..593d928a 100644 --- a/packages/core/src/mixins/__tests__/rowComp.test.js +++ b/packages/core/src/mixins/__tests__/rowComp.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { render } from '@testing-library/react'; +import { render, screen } from '@testing-library/react'; import { shallow } from 'enzyme'; import Icon from 'src/Icon'; @@ -146,3 +146,14 @@ it('takes defaults to its wrapper-component', () => { expect(Comp.defaultProps.align).toBe('center'); expect(Comp.defaultProps.minified).toBeTruthy(); }); + +it('pass down disabled prop to wrapped component', () => { + const Input = ({ children, ...props }) => ; + const RowInput = rowComp()(Input); + + render(); + + const wrapper = screen.getByRole('textbox'); + + expect(wrapper).toHaveAttribute('disabled'); +}); diff --git a/packages/core/src/mixins/rowComp.js b/packages/core/src/mixins/rowComp.js index 4162bb80..36eb8dc4 100644 --- a/packages/core/src/mixins/rowComp.js +++ b/packages/core/src/mixins/rowComp.js @@ -112,195 +112,195 @@ const rowComp = ({ const componentName = getComponentName(WrappedComponent); class RowComp extends PureComponent { - static displayName = `rowComp(${componentName})`; - - static propTypes = { - minified: PropTypes.bool, - - // Text label props - align: PropTypes.oneOf([ - ROW_COMP_ALIGN.LEFT, - ROW_COMP_ALIGN.CENTER, - ROW_COMP_ALIGN.RIGHT, - ROW_COMP_ALIGN.REVERSE, - ]), - verticalOrder: PropTypes.oneOf([ - VERTICAL_ORDER.NORMAL, - VERTICAL_ORDER.REVERSE, - ]), - icon: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.element, - ]), - basic: PropTypes.node, - avatar: PropTypes.node, - aside: PropTypes.node, - tag: PropTypes.node, - bold: PropTypes.bool, - asideControlClickableOnDisabled: PropTypes.bool, - - // State props - active: PropTypes.bool, - highlight: PropTypes.bool, - disabled: PropTypes.bool, - muted: PropTypes.bool, - - // status props - status: statusPropTypes.status, - statusOptions: statusPropTypes.statusOptions, - errorMsg: statusPropTypes.errorMsg, + static displayName = `rowComp(${componentName})`; + + static propTypes = { + minified: PropTypes.bool, + + // Text label props + align: PropTypes.oneOf([ + ROW_COMP_ALIGN.LEFT, + ROW_COMP_ALIGN.CENTER, + ROW_COMP_ALIGN.RIGHT, + ROW_COMP_ALIGN.REVERSE, + ]), + verticalOrder: PropTypes.oneOf([ + VERTICAL_ORDER.NORMAL, + VERTICAL_ORDER.REVERSE, + ]), + icon: PropTypes.oneOfType([ + PropTypes.string, + PropTypes.element, + ]), + basic: PropTypes.node, + avatar: PropTypes.node, + aside: PropTypes.node, + tag: PropTypes.node, + bold: PropTypes.bool, + asideControlClickableOnDisabled: PropTypes.bool, + + // State props + active: PropTypes.bool, + highlight: PropTypes.bool, + disabled: PropTypes.bool, + muted: PropTypes.bool, + + // status props + status: statusPropTypes.status, + statusOptions: statusPropTypes.statusOptions, + errorMsg: statusPropTypes.errorMsg, + }; + + static defaultProps = { + minified: defaultMinified, + + align: defaultAlign, + verticalOrder: defaultVerticalOrder, + icon: null, + basic: null, + avatar: null, + aside: null, + tag: null, + bold: false, + asideControlClickableOnDisabled: false, + + active: false, + highlight: false, + disabled: false, + muted: false, + + status: undefined, + statusOptions: undefined, + errorMsg: undefined, + }; + + static childContextTypes = { + textProps: PropTypes.shape(textPropTypes), + ...statusPropTypes, + // status, + // statusOptions, + // errorMsg, + }; + + getChildContext() { + const { status, statusOptions, errorMsg } = this.props; + const textProps = this.getTextProps(); + + return { + status, + statusOptions, + errorMsg, + // for + textProps, }; - - static defaultProps = { - minified: defaultMinified, - - align: defaultAlign, - verticalOrder: defaultVerticalOrder, - icon: null, - basic: null, - avatar: null, - aside: null, - tag: null, - bold: false, - asideControlClickableOnDisabled: false, - - active: false, - highlight: false, - disabled: false, - muted: false, - - status: undefined, - statusOptions: undefined, - errorMsg: undefined, - }; - - static childContextTypes = { - textProps: PropTypes.shape(textPropTypes), - ...statusPropTypes, - // status, - // statusOptions, - // errorMsg, + } + + getTextProps() { + const { + align, + verticalOrder, + icon, + basic, + aside, + tag, + bold, + asideControlClickableOnDisabled, + disabled, + } = this.props; + + const textLayoutProps = getTextLayoutProps(align, !!icon); + const asideControlClickableProps = ( + (asideControlClickableOnDisabled && disabled) + ? { + onClick: (event) => { event.stopPropagation(); }, + } + : undefined + ); + + return { + verticalOrder, + basic, + aside, + tag, + bold, + ...asideControlClickableProps, + ...textLayoutProps, }; + } - getChildContext() { - const { status, statusOptions, errorMsg } = this.props; - const textProps = this.getTextProps(); - - return { - status, - statusOptions, - errorMsg, - // for - textProps, - }; - } - - getTextProps() { - const { - align, - verticalOrder, - icon, - basic, - aside, - tag, - bold, - asideControlClickableOnDisabled, - disabled, - } = this.props; - - const textLayoutProps = getTextLayoutProps(align, !!icon); - const asideControlClickableProps = ( - (asideControlClickableOnDisabled && disabled) - ? { - onClick: (event) => { event.stopPropagation(); }, - } - : undefined - ); - - return { - verticalOrder, - basic, - aside, - tag, - bold, - ...asideControlClickableProps, - ...textLayoutProps, - }; - } - - renderIconElement() { - const { icon } = this.props; - - if (!icon) { - return null; - } - - return isValidElement(icon) - ? cloneElement(icon, { key: 'comp-icon' }) - : ; - } - - renderContent() { - const iconElement = this.renderIconElement(); - const textProps = this.getTextProps(); + renderIconElement() { + const { icon } = this.props; - return [ - iconElement, - , - ]; + if (!icon) { + return null; } - render() { - const { - minified, - avatar, - align, - verticalOrder, - icon, - basic, - aside, - tag, - bold, - asideControlClickableOnDisabled, - - active, - highlight, - disabled, - muted, - - status, - statusOptions, - errorMsg, - - // React props - className, - children, - - ...otherProps - } = this.props; - - const bemClass = ROOT_BEM - .modifier('minified', minified) - .modifier(align) - .modifier('aside-control-clickable', asideControlClickableOnDisabled); - - const stateClassNames = getStateClassnames({ - active, - highlight, - disabled, - muted, - error: status === STATUS_CODE.ERROR, - untouchable: status === STATUS_CODE.LOADING, - }); - const wrapperClassName = classNames(className, stateClassNames, `${bemClass}`); - - return ( - - {avatar} - {children || this.renderContent()} - - ); - } + return isValidElement(icon) + ? cloneElement(icon, { key: 'comp-icon' }) + : ; + } + + renderContent() { + const iconElement = this.renderIconElement(); + const textProps = this.getTextProps(); + + return [ + iconElement, + , + ]; + } + + render() { + const { + minified, + avatar, + align, + verticalOrder, + icon, + basic, + aside, + tag, + bold, + asideControlClickableOnDisabled, + + active, + highlight, + disabled, + muted, + + status, + statusOptions, + errorMsg, + + // React props + className, + children, + + ...otherProps + } = this.props; + + const bemClass = ROOT_BEM + .modifier('minified', minified) + .modifier(align) + .modifier('aside-control-clickable', asideControlClickableOnDisabled); + + const stateClassNames = getStateClassnames({ + active, + highlight, + disabled, + muted, + error: status === STATUS_CODE.ERROR, + untouchable: status === STATUS_CODE.LOADING, + }); + const wrapperClassName = classNames(className, stateClassNames, `${bemClass}`); + + return ( + + {avatar} + {children || this.renderContent()} + + ); + } } return RowComp; From c96eb64447514efc79bcd0a33e9a3729fc854de3 Mon Sep 17 00:00:00 2001 From: DMoon Date: Wed, 10 Apr 2024 14:01:31 +0800 Subject: [PATCH 2/2] feat: remove opacity style of disabled html attribute --- packages/core/src/styles/_states.scss | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/core/src/styles/_states.scss b/packages/core/src/styles/_states.scss index a7e27348..e6721aaf 100644 --- a/packages/core/src/styles/_states.scss +++ b/packages/core/src/styles/_states.scss @@ -14,7 +14,11 @@ pointer-events: none !important; } -[disabled], +// only disable pointer events, but not apply opacity to prevent nested opacity +[disabled] { + pointer-events: none !important; +} + .#{$prefix-state}-disabled { opacity: .3 !important; pointer-events: none !important;