Skip to content

Commit

Permalink
[EuiFieldText][EuiFieldNumber] Various icon related fixes (#7666)
Browse files Browse the repository at this point in the history
  • Loading branch information
cee-chen authored Apr 11, 2024
1 parent a65c0ac commit 9b0e1da
Show file tree
Hide file tree
Showing 11 changed files with 224 additions and 45 deletions.
6 changes: 6 additions & 0 deletions changelogs/upcoming/7666.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
**Bug fixes**

- Fixed `EuiFieldNumber`'s typing to accept an icon configuration shape
- Fixed `EuiFieldText` and `EuiFieldNumber` to render the correct paddings for icon shapes set to `side: 'right'`
- Fixed `EuiFieldText` and `EuiFieldNumber` to fully ignore `icon`/`prepend`/`append` when `controlOnly` is set to true
- Fixed `EuiColorPicker`'s input not setting the correct right padding for the number of icons displayed
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ exports[`renders EuiColorPicker 1`] = `
<input
aria-label="Press the down key to open a popover containing color options"
autocomplete="off"
class="euiFieldText euiColorPicker__input euiFieldText--withIcon"
class="euiFieldText euiColorPicker__input euiFieldText--withIcon euiFormControlLayout--1icons"
data-test-subj="euiColorPickerAnchor test subject string"
type="text"
value="#FFEEDD"
Expand Down Expand Up @@ -77,7 +77,7 @@ exports[`renders EuiColorPicker with a clearable input 1`] = `
<input
aria-label="Press the down key to open a popover containing color options"
autocomplete="off"
class="euiFieldText euiColorPicker__input euiFieldText--withIcon"
class="euiFieldText euiColorPicker__input euiFieldText--withIcon euiFormControlLayout--2icons"
data-test-subj="euiColorPickerAnchor test subject string"
type="text"
value="#FFEEDD"
Expand Down Expand Up @@ -137,7 +137,7 @@ exports[`renders EuiColorPicker with a color swatch when color is defined 1`] =
<input
aria-label="Press the down key to open a popover containing color options"
autocomplete="off"
class="euiFieldText euiColorPicker__input euiFieldText--withIcon"
class="euiFieldText euiColorPicker__input euiFieldText--withIcon euiFormControlLayout--1icons"
data-test-subj="euiColorPickerAnchor test subject string"
type="text"
value="#FFFFFF"
Expand Down Expand Up @@ -187,7 +187,7 @@ exports[`renders EuiColorPicker with a custom placeholder 1`] = `
<input
aria-label="Press the down key to open a popover containing color options"
autocomplete="off"
class="euiFieldText euiColorPicker__input euiFieldText--withIcon"
class="euiFieldText euiColorPicker__input euiFieldText--withIcon euiFormControlLayout--1icons"
data-test-subj="euiColorPickerAnchor test subject string"
placeholder="Auto"
type="text"
Expand Down Expand Up @@ -238,7 +238,7 @@ exports[`renders EuiColorPicker with an empty swatch when color is "" 1`] = `
<input
aria-label="Press the down key to open a popover containing color options"
autocomplete="off"
class="euiFieldText euiColorPicker__input euiFieldText--withIcon"
class="euiFieldText euiColorPicker__input euiFieldText--withIcon euiFormControlLayout--1icons"
data-test-subj="euiColorPickerAnchor test subject string"
placeholder="Transparent"
type="text"
Expand Down Expand Up @@ -289,7 +289,7 @@ exports[`renders EuiColorPicker with an empty swatch when color is null 1`] = `
<input
aria-label="Press the down key to open a popover containing color options"
autocomplete="off"
class="euiFieldText euiColorPicker__input euiFieldText--withIcon"
class="euiFieldText euiColorPicker__input euiFieldText--withIcon euiFormControlLayout--1icons"
data-test-subj="euiColorPickerAnchor test subject string"
placeholder="Transparent"
type="text"
Expand Down Expand Up @@ -345,7 +345,7 @@ exports[`renders a EuiColorPicker with a prepend and append 1`] = `
<input
aria-label="Press the down key to open a popover containing color options"
autocomplete="off"
class="euiFieldText euiColorPicker__input euiColorPicker__input--inGroup euiFieldText--withIcon"
class="euiFieldText euiColorPicker__input euiColorPicker__input--inGroup euiFieldText--withIcon euiFormControlLayout--1icons"
data-test-subj="euiColorPickerAnchor test subject string"
type="text"
value="#FFEEDD"
Expand Down Expand Up @@ -400,7 +400,7 @@ exports[`renders a EuiColorPicker with an alpha range selector 1`] = `
<input
aria-label="Press the down key to open a popover containing color options"
autocomplete="off"
class="euiFieldText euiColorPicker__input euiFieldText--withIcon"
class="euiFieldText euiColorPicker__input euiFieldText--withIcon euiFormControlLayout--1icons"
data-test-subj="euiColorPickerAnchor test subject string"
type="text"
value="#FFEEDD"
Expand Down Expand Up @@ -450,7 +450,7 @@ exports[`renders compressed EuiColorPicker 1`] = `
<input
aria-label="Press the down key to open a popover containing color options"
autocomplete="off"
class="euiFieldText euiColorPicker__input euiFieldText--withIcon euiFieldText--compressed"
class="euiFieldText euiColorPicker__input euiFieldText--withIcon euiFormControlLayout--1icons euiFieldText--compressed"
data-test-subj="euiColorPickerAnchor test subject string"
type="text"
value="#FFEEDD"
Expand Down Expand Up @@ -500,7 +500,7 @@ exports[`renders disabled EuiColorPicker 1`] = `
<input
aria-label="Press the down key to open a popover containing color options"
autocomplete="off"
class="euiFieldText euiColorPicker__input euiFieldText--withIcon"
class="euiFieldText euiColorPicker__input euiFieldText--withIcon euiFormControlLayout--1icons"
data-test-subj="euiColorPickerAnchor test subject string"
disabled=""
type="text"
Expand Down Expand Up @@ -538,7 +538,7 @@ exports[`renders fullWidth EuiColorPicker 1`] = `
<input
aria-label="Press the down key to open a popover containing color options"
autocomplete="off"
class="euiFieldText euiColorPicker__input euiFieldText--withIcon euiFieldText--fullWidth"
class="euiFieldText euiColorPicker__input euiFieldText--withIcon euiFormControlLayout--1icons euiFieldText--fullWidth"
data-test-subj="euiColorPickerAnchor test subject string"
type="text"
value="#FFEEDD"
Expand Down Expand Up @@ -760,7 +760,7 @@ exports[`renders readOnly EuiColorPicker 1`] = `
<input
aria-label="Press the down key to open a popover containing color options"
autocomplete="off"
class="euiFieldText euiColorPicker__input euiFieldText--withIcon"
class="euiFieldText euiColorPicker__input euiFieldText--withIcon euiFormControlLayout--1icons"
data-test-subj="euiColorPickerAnchor test subject string"
readonly=""
type="text"
Expand Down
16 changes: 0 additions & 16 deletions src/components/color_picker/_color_picker.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,6 @@
width: $euiColorPickerWidth;
}

.euiColorPicker__popoverAnchor {
// Nested needed for specificity of overriding .euiFieldText
.euiColorPicker__input {
@include euiFormControlWithIcon($isIconOptional: false, $side: 'right');

&[class*='--compressed'] {
@include euiFormControlWithIcon($isIconOptional: false, $side: 'right', $compressed: true);
}

+ .euiFormControlLayoutIcons {
// Override :disabled state, which obscures the selected color
color: inherit;
}
}
}

.euiColorPicker__swatches {
display: flex;
flex-wrap: wrap;
Expand Down
15 changes: 13 additions & 2 deletions src/components/color_picker/color_picker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
EuiRange,
EuiRangeProps,
} from '../form';
import { getFormControlClassNameForIconCount } from '../form/form_control_layout/_num_icons';
import { useEuiI18n } from '../i18n';
import { EuiPopover } from '../popover';
import { EuiSpacer } from '../spacer';
Expand Down Expand Up @@ -286,9 +287,19 @@ export const EuiColorPicker: FunctionComponent<EuiColorPickerProps> = ({
'euiColorPicker__popoverPanel--customButton': button,
});
const swatchClass = 'euiColorPicker__swatchSelect';
const inputClasses = classNames('euiColorPicker__input', {
'euiColorPicker__input--inGroup': prepend || append,

const numIconsClass = getFormControlClassNameForIconCount({
isDropdown: true,
clear: isClearable,
isInvalid,
});
const inputClasses = classNames(
'euiColorPicker__input',
{ 'euiColorPicker__input--inGroup': prepend || append },
// Manually account for input padding, since `controlOnly` disables that logic
'euiFieldText--withIcon',
numIconsClass
);

const handleOnChange = (text: string) => {
const output = getOutput(text, showAlpha);
Expand Down
62 changes: 62 additions & 0 deletions src/components/form/field_number/field_number.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
*/

import type { Meta, StoryObj } from '@storybook/react';
import {
disableStorybookControls,
hideStorybookControls,
moveStorybookControlsToCategory,
} from '../../../../.storybook/utils';

import { EuiFieldNumber, EuiFieldNumberProps } from './field_number';

Expand All @@ -15,11 +20,28 @@ const meta: Meta<EuiFieldNumberProps> = {
component: EuiFieldNumber,
argTypes: {
step: { control: 'number' },
// For quicker/easier QA
icon: { control: 'text' },
prepend: { control: 'text' },
append: { control: 'text' },
},
args: {
// Component defaults
compressed: false,
fullWidth: false,
isInvalid: false,
isLoading: false,
disabled: false,
readOnly: false,
controlOnly: false,
// Added for easier testing
placeholder: '0',
},
};

export default meta;
type Story = StoryObj<EuiFieldNumberProps>;
disableStorybookControls(meta, ['inputRef']);

export const Playground: Story = {};

Expand All @@ -32,3 +54,43 @@ export const ControlledComponent: Story = {
onChange: () => {},
},
};
// Hide props that don't impact this story
hideStorybookControls(ControlledComponent, [
'controlOnly',
'inputRef',
'compressed',
'fullWidth',
'icon',
'isInvalid',
'isLoading',
'disabled',
'readOnly',
'placeholder',
'prepend',
'append',
]);

export const IconShape: Story = {
argTypes: { icon: { control: 'object' } },
args: { icon: { type: 'warning', color: 'warning', side: 'left' } },
};
// Move other props below the icon prop
moveStorybookControlsToCategory(IconShape, [
'compressed',
'fullWidth',
'isInvalid',
'isLoading',
'disabled',
'readOnly',
'placeholder',
'prepend',
'append',
]);
// Hide props that remove or won't affect the icon or its positioning
hideStorybookControls(IconShape, [
'controlOnly',
'inputRef',
'min',
'max',
'step',
]);
16 changes: 11 additions & 5 deletions src/components/form/field_number/field_number.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,24 @@ import classNames from 'classnames';

import { useCombinedRefs } from '../../../services';
import { CommonProps } from '../../common';
import { IconType } from '../../icon';

import { EuiValidatableControl } from '../validatable_control';
import {
EuiFormControlLayout,
EuiFormControlLayoutProps,
} from '../form_control_layout';
import { getFormControlClassNameForIconCount } from '../form_control_layout/_num_icons';
import {
getFormControlClassNameForIconCount,
isRightSideIcon,
} from '../form_control_layout/_num_icons';
import { useFormContext } from '../eui_form_context';

export type EuiFieldNumberProps = Omit<
InputHTMLAttributes<HTMLInputElement>,
'min' | 'max' | 'readOnly' | 'step'
> &
CommonProps & {
icon?: IconType;
icon?: EuiFormControlLayoutProps['icon'];
isInvalid?: boolean;
/**
* Expand to fill 100% of the parent.
Expand Down Expand Up @@ -134,18 +136,22 @@ export const EuiFieldNumber: FunctionComponent<EuiFieldNumberProps> = (
}
}, [value, min, max, step, checkNativeValidity]);

const hasRightSideIcon = isRightSideIcon(icon);
const numIconsClass = controlOnly
? false
: getFormControlClassNameForIconCount({
isInvalid: isInvalid || isNativelyInvalid,
isLoading,
icon: hasRightSideIcon,
});

const classes = classNames('euiFieldNumber', className, numIconsClass, {
'euiFieldNumber--withIcon': icon,
'euiFieldNumber--fullWidth': fullWidth,
'euiFieldNumber--compressed': compressed,
'euiFieldNumber--inGroup': prepend || append,
...(!controlOnly && {
'euiFieldNumber--inGroup': prepend || append,
'euiFieldNumber--withIcon': icon && !hasRightSideIcon,
}),
'euiFieldNumber-isLoading': isLoading,
});

Expand Down
64 changes: 64 additions & 0 deletions src/components/form/field_text/field_text.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import type { Meta, StoryObj } from '@storybook/react';
import {
disableStorybookControls,
hideStorybookControls,
moveStorybookControlsToCategory,
} from '../../../../.storybook/utils';

import { EuiFieldText, EuiFieldTextProps } from './field_text';

const meta: Meta<EuiFieldTextProps> = {
title: 'Forms/EuiFieldText',
component: EuiFieldText,
argTypes: {
// For quicker/easier QA
icon: { control: 'text' },
prepend: { control: 'text' },
append: { control: 'text' },
},
args: {
// Component defaults
compressed: false,
fullWidth: false,
isInvalid: false,
isLoading: false,
disabled: false,
readOnly: false,
controlOnly: false,
// Added for easier testing
placeholder: 'EuiFieldText',
},
};

export default meta;
type Story = StoryObj<EuiFieldTextProps>;
disableStorybookControls(meta, ['inputRef']);

export const Playground: Story = {};

export const IconShape: Story = {
argTypes: { icon: { control: 'object' } },
args: { icon: { type: 'warning', color: 'warning', side: 'left' } },
};
// Move other props below the icon prop
moveStorybookControlsToCategory(IconShape, [
'compressed',
'fullWidth',
'isInvalid',
'isLoading',
'disabled',
'readOnly',
'placeholder',
'prepend',
'append',
]);
// Hide props that remove or won't affect the icon or its positioning
hideStorybookControls(IconShape, ['controlOnly', 'inputRef']);
Loading

0 comments on commit 9b0e1da

Please sign in to comment.