Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[EuiFieldText][EuiFieldNumber] Various icon related fixes #7666

Merged
merged 7 commits into from
Apr 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading