Skip to content

Commit

Permalink
[EuiRange][EuiDualRange] Add new inputPopoverProps prop (#7082)
Browse files Browse the repository at this point in the history
  • Loading branch information
cee-chen authored Aug 15, 2023
1 parent 9e60779 commit 513711a
Show file tree
Hide file tree
Showing 7 changed files with 169 additions and 28 deletions.
119 changes: 99 additions & 20 deletions src/components/form/range/__snapshots__/range.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -413,36 +413,115 @@ exports[`EuiRange props range should render 1`] = `
`;

exports[`EuiRange props slider should display in popover 1`] = `
<div
class="euiPopover euiInputPopover euiRange__popover emotion-euiPopover-EuiInputPopover"
>
<body>
<div>
<div
class="euiPopover euiInputPopover euiRange__popover emotion-euiPopover-EuiInputPopover"
>
<div
class="euiPopover__anchor css-zih94u-render"
>
<div>
<div
class="euiFormControlLayout"
>
<div
class="euiFormControlLayout__childrenWrapper"
>
<input
aria-label="aria-label"
class="euiFieldNumber euiRangeInput euiRangeInput--max emotion-euiRangeInput"
data-test-subj="test subject string"
id="id"
max="100"
min="0"
name="name"
step="1"
type="number"
value="8"
/>
</div>
</div>
</div>
</div>
</div>
</div>
<div
class="euiPopover__anchor css-zih94u-render"
data-euiportal="true"
>
<div>
<div
data-focus-guard="true"
style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;"
tabindex="-1"
/>
<div
data-focus-lock-disabled="disabled"
>
<div
class="euiFormControlLayout"
aria-describedby="generated-id"
aria-live="assertive"
aria-modal="true"
class="euiPanel euiPanel--plain euiPanel--paddingSmall euiPopover__panel emotion-euiPanel-grow-m-s-plain-euiPopover__panel-bottom"
data-popover-panel="true"
data-test-subj="test"
role="dialog"
style="top: 8px; left: -22px; will-change: transform, opacity; z-index: 2000;"
>
<div
class="euiFormControlLayout__childrenWrapper"
<p
class="emotion-euiScreenReaderOnly"
id="generated-id"
>
<input
aria-label="aria-label"
class="euiFieldNumber euiRangeInput euiRangeInput--max emotion-euiRangeInput"
data-test-subj="test subject string"
id="id"
max="100"
min="0"
name="name"
step="1"
type="number"
value="8"
You are in a custom range slider. Use the Up and Down arrow keys to change the value.
</p>
<div>
<div
data-focus-guard="true"
style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;"
tabindex="-1"
/>
<div
data-focus-lock-disabled="disabled"
>
<div>
<div
class="euiRangeWrapper euiRange testClass1 testClass2 emotion-euiRangeWrapper-regular-euiRange-hasInput-euiTestCss"
>
<div
aria-hidden="true"
class="euiRangeTrack emotion-euiRangeTrack"
>
<input
aria-hidden="true"
aria-label="aria-label"
class="euiRangeSlider emotion-euiRangeSlider"
data-test-subj="test subject string"
max="100"
min="0"
name="name"
step="1"
tabindex="-1"
type="range"
value="8"
/>
</div>
</div>
</div>
</div>
<div
data-focus-guard="true"
style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;"
tabindex="-1"
/>
</div>
</div>
</div>
<div
data-focus-guard="true"
style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;"
tabindex="-1"
/>
</div>
</div>
</body>
`;

exports[`EuiRange props ticks should render 1`] = `
Expand Down
16 changes: 16 additions & 0 deletions src/components/form/range/dual_range.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,20 @@ describe('EuiDualRange', () => {
targetSelector: '.euiRangeSlider',
skip: { className: true, css: true },
});
shouldRenderCustomStyles(
<EuiDualRange
{...props}
showInput="inputWithPopover"
minInputProps={{ 'data-test-subj': 'triggerPopover' }}
/>,
{
skip: { parentTest: true },
childProps: ['minInputProps', 'maxInputProps', 'inputPopoverProps'],
renderCallback: ({ getByTestSubject }) => {
fireEvent.focus(getByTestSubject('triggerPopover'));
},
}
);

it('renders', () => {
const { container } = render(
Expand Down Expand Up @@ -184,6 +198,7 @@ describe('EuiDualRange', () => {
id="id"
showInput="inputWithPopover"
minInputProps={{ 'aria-label': 'Min value' }}
inputPopoverProps={{ panelProps: { 'data-test-subj': 'test' } }}
/>
);

Expand All @@ -195,6 +210,7 @@ describe('EuiDualRange', () => {

expect(screen.getByRole('dialog')).toBeDefined();
expect(screen.getAllByRole('slider')).toHaveLength(2);
expect(screen.getByTestSubject('test')).toBeInTheDocument();
});
});

Expand Down
8 changes: 7 additions & 1 deletion src/components/form/range/dual_range.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@ export class EuiDualRangeClass extends Component<
this.setState({
rangeWidth: width,
});
this.props.inputPopoverProps?.onPanelResize?.(width);
};

getNearestStep = (value: number) => {
Expand Down Expand Up @@ -451,6 +452,7 @@ export class EuiDualRangeClass extends Component<
prepend,
minInputProps,
maxInputProps,
inputPopoverProps,
isDraggable,
theme,
...rest
Expand Down Expand Up @@ -786,7 +788,11 @@ export class EuiDualRangeClass extends Component<

const thePopover = showInputOnly ? (
<EuiInputPopover
className="euiRange__popover"
{...inputPopoverProps}
className={classNames(
'euiDualRange__popover',
inputPopoverProps?.className
)}
input={
<EuiFormControlLayoutDelimited
startControl={minInput!}
Expand Down
22 changes: 20 additions & 2 deletions src/components/form/range/range.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/

import React from 'react';
import { fireEvent } from '@testing-library/react';
import { shouldRenderCustomStyles } from '../../../test/internal';
import { requiredProps } from '../../../test/required_props';
import { render } from '../../../test/rtl';
Expand All @@ -29,6 +30,20 @@ describe('EuiRange', () => {
targetSelector: '.euiRangeSlider',
skip: { className: true, css: true },
});
shouldRenderCustomStyles(
<EuiRange
{...props}
showInput="inputWithPopover"
data-test-subj="triggerPopover"
/>,
{
skip: { parentTest: true },
childProps: ['inputPopoverProps'],
renderCallback: ({ getByTestSubject }) => {
fireEvent.focus(getByTestSubject('triggerPopover'));
},
}
);

test('is rendered', () => {
const { container } = render(
Expand Down Expand Up @@ -129,18 +144,21 @@ describe('EuiRange', () => {
});

test('slider should display in popover', () => {
const { container } = render(
const { container, baseElement, getByTestSubject } = render(
<EuiRange
name="name"
id="id"
onChange={() => {}}
showInput="inputWithPopover"
inputPopoverProps={{ panelProps: { 'data-test-subj': 'test' } }}
{...props}
{...requiredProps}
/>
);
fireEvent.focus(container.querySelector('input')!);

expect(container.firstChild).toMatchSnapshot();
expect(baseElement).toMatchSnapshot();
expect(getByTestSubject('test')).toBeInTheDocument();
});

test('loading should display when showInput="inputWithPopover"', () => {
Expand Down
7 changes: 6 additions & 1 deletion src/components/form/range/range.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ export class EuiRangeClass extends Component<
step,
showLabels,
showInput,
inputPopoverProps,
showTicks,
tickInterval,
ticks,
Expand Down Expand Up @@ -291,7 +292,11 @@ export class EuiRangeClass extends Component<

const thePopover = showInputOnly ? (
<EuiInputPopover
className="euiRange__popover"
{...inputPopoverProps}
className={classNames(
'euiRange__popover',
inputPopoverProps?.className
)}
input={theInput!} // `showInputOnly` confirms existence
fullWidth={fullWidth}
isOpen={this.state.isPopoverOpen}
Expand Down
24 changes: 20 additions & 4 deletions src/components/form/range/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@

import type { ReactNode, CSSProperties, InputHTMLAttributes } from 'react';
import type { CommonProps } from '../../common';
import type { EuiInputPopoverProps } from '../../popover/input_popover';
import type { EuiFormControlLayoutProps } from '../form_control_layout';
import type { EuiRangeLevelColor } from './range_levels_colors';
import { EuiRangeInputProps } from './range_input';
import type { EuiRangeInputProps } from './range_input';

/**
* Internal type atoms split up both for easier categorization
Expand Down Expand Up @@ -110,14 +111,29 @@ export interface _SharedRangeInputProps {
* @default false
*/
fullWidth?: boolean;
/**
* Only impacts inputs rendered by the `showInput` prop
*/
isInvalid?: boolean;
/**
* Only impacts inputs rendered when the `showInput` prop is set to `"inputWithPopover"`
*/
isLoading?: boolean;
/**
* Only impacts inputs rendered by the `showInput` prop
*/
isInvalid?: boolean;
* Only impacts input popovers rendered when the `showInput` prop is set to `"inputWithPopover"`
*
* Allows customizing the underlying [EuiInputPopover](/#/layout/popover#popover-attached-to-input-element),
* except for props controlled by the range component
*/
inputPopoverProps?: Omit<
EuiInputPopoverProps,
| 'input'
| 'isOpen'
| 'closePopover'
| 'disableFocusTrap'
| 'popoverScreenReaderText'
| 'fullWidth'
>;
}

export type _SharedRangeInputSide = {
Expand Down
1 change: 1 addition & 0 deletions upcoming_changelogs/7082.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Added a new `inputPopoverProps` prop for `EuiRange`s and `EuiDualRange`s with `showInput="inputWithPopover"` set

0 comments on commit 513711a

Please sign in to comment.