diff --git a/packages/ui-form-field/src/FormFieldLayout/index.tsx b/packages/ui-form-field/src/FormFieldLayout/index.tsx index cf7c810c6c..13de6eaa07 100644 --- a/packages/ui-form-field/src/FormFieldLayout/index.tsx +++ b/packages/ui-form-field/src/FormFieldLayout/index.tsx @@ -28,7 +28,6 @@ import { Component } from 'react' import { hasVisibleChildren } from '@instructure/ui-a11y-utils' import { ScreenReaderContent } from '@instructure/ui-a11y-content' import { Grid } from '@instructure/ui-grid' -import { logError as error } from '@instructure/console' import { omitProps, pickProps, @@ -67,16 +66,7 @@ class FormFieldLayout extends Component { constructor(props: FormFieldLayoutProps) { super(props) - this._messagesId = props.messagesId || props.deterministicId!() - - error( - typeof props.width !== 'undefined' || - !props.inline || - props.layout !== 'inline', - `[FormFieldLayout] The 'inline' prop is true, and the 'layout' is set to 'inline'. - This will cause a layout issue in Internet Explorer 11 unless you also add a value for the 'width' prop.` - ) } private _messagesId: string @@ -212,7 +202,9 @@ class FormFieldLayout extends Component { elementRef={this.handleInputContainerRef} > {hasNewErrorMsg && ( -
{this.renderVisibleMessages()}
+
+ {this.renderVisibleMessages()} +
)} {children} diff --git a/packages/ui-react-utils/src/omitProps.ts b/packages/ui-react-utils/src/omitProps.ts index 173b2ffc82..8b519687a8 100644 --- a/packages/ui-react-utils/src/omitProps.ts +++ b/packages/ui-react-utils/src/omitProps.ts @@ -29,7 +29,8 @@ * Return an object with the remaining props after the given props are omitted. * * Automatically excludes the following props: - * 'theme', 'children', 'className', 'style', 'styles', 'makeStyles', 'themeOverride', 'deterministicId' + * `theme`, `children`, `className`, `style`, `styles`, `makeStyles`, + * `themeOverride`, `deterministicId` * @module omitProps * @param props The object to process * @param propsToOmit list disallowed prop keys or an object whose diff --git a/packages/ui-select/src/Select/README.md b/packages/ui-select/src/Select/README.md index b8cd55dd90..2ff16e3060 100644 --- a/packages/ui-select/src/Select/README.md +++ b/packages/ui-select/src/Select/README.md @@ -850,7 +850,9 @@ To mark an option as "highlighted", use the option's `isHighlighted` prop. Note {this.getOptionById(id).label} } - margin={index > 0 ? 'xxx-small 0 xxx-small xx-small' : 'xxx-small 0'} + margin={ + index > 0 ? 'xxx-small xx-small xxx-small 0' : '0 xx-small 0 0' + } onClick={(e) => this.dismissTag(e, id)} /> )) @@ -1079,7 +1081,9 @@ To mark an option as "highlighted", use the option's `isHighlighted` prop. Note {this.getOptionById(id).label} } - margin={index > 0 ? 'xxx-small 0 xxx-small xx-small' : 'xxx-small 0'} + margin={ + index > 0 ? 'xxx-small xx-small xxx-small 0' : '0 xx-small 0 0' + } onClick={(e) => dismissTag(e, id)} /> )) diff --git a/packages/ui-text-input/src/TextInput/README.md b/packages/ui-text-input/src/TextInput/README.md index e7b26c3e62..3e1330f702 100644 --- a/packages/ui-text-input/src/TextInput/README.md +++ b/packages/ui-text-input/src/TextInput/README.md @@ -205,7 +205,7 @@ Focusable content will be focused separately from the input itself. value={this.state.value} onChange={this.handleChange} renderBeforeInput={ - + <> {this.state.value !== '' && ( console.log('Strawberry')} /> - + } renderAfterInput={() => ( @@ -260,7 +260,7 @@ Focusable content will be focused separately from the input itself. value={value} onChange={handleChange} renderBeforeInput={ - + <> {value !== '' && ( console.log('Strawberry')} /> - + } renderAfterInput={() => ( @@ -346,7 +346,7 @@ type: example + <> - + } renderAfterInput={} /> @@ -374,6 +374,7 @@ type: embed Left align text (exceptions may apply) Place labels on top or to the left (inline) Make placeholder text different than the label + Use React fragments for renderBeforeInput. This will nicely float the text input box to the remaining space
Place labels to the right of the input diff --git a/packages/ui-text-input/src/TextInput/index.tsx b/packages/ui-text-input/src/TextInput/index.tsx index 137484dc0a..5a208d45b3 100644 --- a/packages/ui-text-input/src/TextInput/index.tsx +++ b/packages/ui-text-input/src/TextInput/index.tsx @@ -77,7 +77,6 @@ class TextInput extends Component { super(props) this.state = { hasFocus: false, - beforeElementHasWidth: undefined, afterElementHasWidth: undefined } this._defaultId = props.deterministicId!() @@ -87,7 +86,6 @@ class TextInput extends Component { ref: Element | null = null private _input: HTMLInputElement | null = null - private _beforeElement: HTMLSpanElement | null = null private _afterElement: HTMLSpanElement | null = null private readonly _defaultId: string @@ -112,13 +110,10 @@ class TextInput extends Component { 'focus', this.handleFocus ) - this.setState({ - beforeElementHasWidth: this.getElementHasWidth(this._beforeElement), afterElementHasWidth: this.getElementHasWidth(this._afterElement) }) } - this.props.makeStyles?.(this.makeStyleProps()) } @@ -129,11 +124,6 @@ class TextInput extends Component { } componentDidUpdate(prevProps: TextInputProps) { - if (prevProps.renderBeforeInput !== this.props.renderBeforeInput) { - this.setState({ - beforeElementHasWidth: this.getElementHasWidth(this._beforeElement) - }) - } if (prevProps.renderAfterInput !== this.props.renderAfterInput) { this.setState({ afterElementHasWidth: this.getElementHasWidth(this._afterElement) @@ -154,13 +144,13 @@ class TextInput extends Component { makeStyleProps = (): TextInputStyleProps => { const { interaction } = this - const { hasFocus, beforeElementHasWidth, afterElementHasWidth } = this.state + const { hasFocus, afterElementHasWidth } = this.state return { disabled: interaction === 'disabled', invalid: this.invalid, focused: hasFocus, - beforeElementHasWidth, - afterElementHasWidth + afterElementHasWidth: afterElementHasWidth, + beforeElementExists: this.props.renderBeforeInput != undefined } } @@ -282,7 +272,7 @@ class TextInput extends Component { ) } - getElementHasWidth(element: HTMLSpanElement | null) { + getElementHasWidth(element: Element | null) { if (!element) { return undefined } @@ -360,39 +350,24 @@ class TextInput extends Component { > {renderBeforeOrAfter ? ( -
- - {beforeElement && ( + + {beforeElement} + {/* The input and content after input should not wrap, + so they're in their own flex container */} + + {this.renderInput()} + {afterElement && ( { - this._beforeElement = e + this._afterElement = e }} > - {beforeElement} + {afterElement} )} - - {/* - The input and content after input should not wrap, - so they're in their own flex container - */} - - {this.renderInput()} - {afterElement && ( - { - this._afterElement = e - }} - > - {afterElement} - - )} - - -
+
) : ( /* If no prepended or appended content, don't render Flex layout */ this.renderInput() diff --git a/packages/ui-text-input/src/TextInput/props.ts b/packages/ui-text-input/src/TextInput/props.ts index ab3c64ba03..781accdf85 100644 --- a/packages/ui-text-input/src/TextInput/props.ts +++ b/packages/ui-text-input/src/TextInput/props.ts @@ -193,11 +193,9 @@ type TextInputStyle = ComponentStyle< | 'textInput' | 'facade' | 'layout' - | 'beforeElement' - | 'innerWrapper' - | 'inputLayout' | 'afterElement' | 'requiredInvalid' + | 'inputLayout' > const propTypes: PropValidators = { @@ -254,7 +252,6 @@ const allowedProps: AllowedPropKeys = [ type TextInputState = { hasFocus: boolean - beforeElementHasWidth?: boolean afterElementHasWidth?: boolean } @@ -262,8 +259,8 @@ type TextInputStyleProps = { disabled: boolean invalid: boolean focused: TextInputState['hasFocus'] - beforeElementHasWidth: TextInputState['beforeElementHasWidth'] afterElementHasWidth: TextInputState['afterElementHasWidth'] + beforeElementExists: boolean } export type { diff --git a/packages/ui-text-input/src/TextInput/styles.ts b/packages/ui-text-input/src/TextInput/styles.ts index db011516d0..7437b1542a 100644 --- a/packages/ui-text-input/src/TextInput/styles.ts +++ b/packages/ui-text-input/src/TextInput/styles.ts @@ -49,8 +49,8 @@ const generateStyle = ( disabled, invalid, focused, - beforeElementHasWidth, - afterElementHasWidth + afterElementHasWidth, + beforeElementExists } = state const sizeVariants = { @@ -103,15 +103,14 @@ const generateStyle = ( const inputStyle = { all: 'initial', - '&::-ms-clear': { display: 'none' }, + width: '100%', WebkitFontSmoothing: 'antialiased', MozOsxFontSmoothing: 'grayscale', appearance: 'none', margin: 0, - width: '100%', display: 'block', boxSizing: 'border-box', outline: 'none', @@ -151,11 +150,6 @@ const generateStyle = ( flexDirection: 'row' } - const flexItemBase = { - ...viewBase, - flexShrink: 0 - } - return { requiredInvalid: { color: componentTheme.requiredInvalidColor @@ -198,30 +192,17 @@ const generateStyle = ( }, layout: { label: 'textInput__layout', - ...flexBase, - ...(!shouldNotWrap && { flexWrap: 'wrap' }) - }, - beforeElement: { - display: 'inline-flex', + ...viewBase, + display: 'flex', alignItems: 'center', - label: 'textInput__beforeElement', - ...flexItemBase, - paddingInlineStart: componentTheme.padding, - // we only override the padding once the width is calculated, - // it needs the padding on render - ...(beforeElementHasWidth === false && { - paddingInlineStart: 0 - }) - }, - innerWrapper: { - label: 'textInput__innerWrapper', - ...flexItemBase, - minWidth: '0.0625rem', - flexShrink: 1, - flexGrow: 1 + justifyContent: 'flex-start', + flexDirection: 'row', + ...(!shouldNotWrap && { flexWrap: 'wrap' }), + ...(beforeElementExists && { paddingInlineStart: componentTheme.padding }) }, inputLayout: { label: 'textInput__inputLayout', + flexGrow: 1, ...flexBase }, afterElement: { @@ -231,7 +212,8 @@ const generateStyle = ( marginTop: '-1px', marginBottom: '-1px', label: 'textInput__afterElement', - ...flexItemBase, + ...viewBase, + flexShrink: 0, paddingInlineEnd: componentTheme.padding, // we only override the padding once the width is calculated, // it needs the padding on render