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

[EuiInlineEdit] Create placeholder prop for Inline Edit & Friends #6883

Merged
merged 12 commits into from
Jun 30, 2023
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
29 changes: 29 additions & 0 deletions src-docs/src/views/inline_edit/inline_edit_example.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@ const inlineEditTitleSnippet = `<EuiInlineEditTitle
size="m"
/>`;

import InlineEditPlaceholder from './inline_edit_placeholder';
const inlineEditPlaceholderSource = require('!!raw-loader!./inline_edit_placeholder');
const inlineEditPlaceholderSnippet = `<EuiInlineEditText
inputAriaLabel="Edit text inline"
defaultValue=""
placeholder="This is placeholder text!"
/>`;

import InlineEditSave from './inline_edit_save';
const inlineEditSaveSource = require('!!raw-loader!././inline_edit_save');
const inlineEditModeSaveSnippet = `<EuiInlineEditText
Expand Down Expand Up @@ -194,6 +202,27 @@ export const InlineEditExample = {
],
demo: <InlineEditValidation />,
},
{
title: 'Setting placeholder instructions',
text: (
<>
<p>
The <EuiCode>placeholder</EuiCode> property will display in both
read and edit mode whenever the <strong>EuiInlineEdit</strong>'s
value is empty. Use placeholder text to provide guidance or
instructions to consumers as to what they're editing.
</p>
</>
),
source: [
{
type: GuideSectionTypes.TSX,
code: inlineEditPlaceholderSource,
},
],
demo: <InlineEditPlaceholder />,
snippet: inlineEditPlaceholderSnippet,
},
{
title: 'Start in edit mode',
text: (
Expand Down
28 changes: 28 additions & 0 deletions src-docs/src/views/inline_edit/inline_edit_placeholder.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from 'react';

import {
EuiInlineEditText,
EuiInlineEditTitle,
EuiSpacer,
} from '../../../../src';

export default () => {
return (
<>
<EuiInlineEditText
inputAriaLabel="Placeholder text example"
defaultValue=""
placeholder="Add a description"
/>

<EuiSpacer />

<EuiInlineEditTitle
heading="h3"
inputAriaLabel="Placeholder title example"
defaultValue=""
placeholder="Set your username"
/>
</>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,93 @@ exports[`EuiInlineEditForm edit mode isLoading 1`] = `
</div>
`;

exports[`EuiInlineEditForm edit mode placeholder 1`] = `
<div
class="euiInlineEdit testClass1 testClass2"
>
<div
class="euiFlexGroup emotion-euiFlexGroup-s-flexStart-stretch-row"
>
<div
class="euiFlexItem emotion-euiFlexItem-grow-1"
>
<div
class="euiFormRow euiFormRow--fullWidth"
id="generated-id-row"
>
<div
class="euiFormRow__fieldWrapper"
>
<div
class="euiFormControlLayout euiFormControlLayout--fullWidth"
>
<div
class="euiFormControlLayout__childrenWrapper"
>
<input
aria-describedby="inlineEdit_generated-id"
aria-label="Edit inline"
class="euiFieldText euiFieldText--fullWidth"
data-test-subj="euiInlineEditModeInput"
id="generated-id"
placeholder="This is a placeholder."
type="text"
value=""
/>
</div>
</div>
</div>
</div>
<span
hidden=""
id="inlineEdit_generated-id"
>
Press Enter to save your edited text. Press Escape to cancel your edit.
</span>
</div>
<div
class="euiFlexItem emotion-euiFlexItem-growZero"
>
<div
aria-busy="false"
data-test-subj="euiSkeletonLoadingAriaWrapper"
>
<div
class="euiFlexGroup emotion-euiFlexGroup-responsive-s-flexStart-stretch-row"
>
<button
aria-label="Save edit"
class="euiButtonIcon emotion-euiButtonIcon-m-base-success"
data-test-subj="euiInlineEditModeSaveButton"
type="button"
>
<span
aria-hidden="true"
class="euiButtonIcon__icon"
color="inherit"
data-euiicon-type="check"
/>
</button>
<button
aria-label="Cancel edit"
class="euiButtonIcon emotion-euiButtonIcon-m-base-danger"
data-test-subj="euiInlineEditModeCancelButton"
type="button"
>
<span
aria-hidden="true"
class="euiButtonIcon__icon"
color="inherit"
data-euiicon-type="cross"
/>
</button>
</div>
</div>
</div>
</div>
</div>
`;

exports[`EuiInlineEditForm edit mode renders 1`] = `
<div
class="euiInlineEdit testClass1 testClass2"
Expand Down Expand Up @@ -671,6 +758,39 @@ exports[`EuiInlineEditForm read mode isReadOnly 1`] = `
</div>
`;

exports[`EuiInlineEditForm read mode placeholder 1`] = `
<div
class="euiInlineEdit testClass1 testClass2"
>
<button
aria-describedby="inlineEdit_generated-id"
class="euiButtonEmpty emotion-euiButtonDisplay-euiButtonEmpty-m-empty-text-flush-both-euiInlineEditReadMode-hasPlaceholder"
data-test-subj="euiInlineReadModeButton"
type="button"
>
<span
class="euiButtonEmpty__content emotion-euiButtonDisplayContent"
>
<span
class="eui-textTruncate euiButtonEmpty__text"
>
This is a placeholder.
</span>
<span
color="inherit"
data-euiicon-type="pencil"
/>
</span>
</button>
<span
hidden=""
id="inlineEdit_generated-id"
>
Click to edit this text inline.
</span>
</div>
`;

exports[`EuiInlineEditForm read mode readModeProps 1`] = `
<div
class="euiInlineEdit testClass1 testClass2"
Expand Down
9 changes: 8 additions & 1 deletion src/components/inline_edit/inline_edit_form.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*/

import { css } from '@emotion/react';
import { UseEuiTheme } from '../../services';
import { UseEuiTheme, tint } from '../../services';

export const euiInlineEditReadModeStyles = ({ euiTheme }: UseEuiTheme) => {
return {
Expand All @@ -21,5 +21,12 @@ export const euiInlineEditReadModeStyles = ({ euiTheme }: UseEuiTheme) => {
user-select: text;
}
`,

hasPlaceholder: css`
.euiText,
.euiTitle {
color: ${tint(euiTheme.colors.subduedText, 0.08)};
}
`,
};
};
52 changes: 52 additions & 0 deletions src/components/inline_edit/inline_edit_form.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,19 @@ describe('EuiInlineEditForm', () => {

expect(container.firstChild).toMatchSnapshot();
});

test('placeholder', () => {
const { container, getByText } = render(
<EuiInlineEditForm
{...commonInlineEditFormProps}
defaultValue=""
placeholder="This is a placeholder."
/>
);

expect(container.firstChild).toMatchSnapshot();
expect(getByText('This is a placeholder.')).toBeTruthy();
});
});

describe('edit mode', () => {
Expand Down Expand Up @@ -202,6 +215,25 @@ describe('EuiInlineEditForm', () => {
getByTestSubject('euiInlineEditModeInput').hasAttribute('aria-invalid')
).toBeTruthy();
});

test('placeholder', () => {
const { container, getByTestSubject } = render(
<EuiInlineEditForm
{...commonInlineEditFormProps}
startWithEditOpen={true}
defaultValue=""
placeholder="This is a placeholder."
/>
);

expect(container.firstChild).toMatchSnapshot();
expect(
getByTestSubject('euiInlineEditModeInput').getAttribute('placeholder')
).toBeTruthy();
expect(
getByTestSubject('euiInlineEditModeInput').getAttribute('value')
).toBeFalsy();
});
});

describe('toggling between read mode and edit mode', () => {
Expand Down Expand Up @@ -448,6 +480,26 @@ describe('EuiInlineEditForm', () => {
expect(getByTestSubject('euiInlineReadModeButton')).toBeTruthy();
expect(getByText('New message!')).toBeTruthy();
});

it('allows overriding `placeholder` with `inputModeProps.placeholder`', () => {
const { getByTestSubject } = render(
<EuiInlineEditForm
{...commonInlineEditFormProps}
startWithEditOpen={true}
defaultValue=""
placeholder="This is A!"
editModeProps={{
inputProps: {
placeholder: 'The real placeholder!',
},
}}
/>
);

expect(
getByTestSubject('euiInlineEditModeInput').getAttribute('placeholder')
).toEqual('The real placeholder!');
});
});
});
});
18 changes: 11 additions & 7 deletions src/components/inline_edit/inline_edit_form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import { euiInlineEditReadModeStyles } from './inline_edit_form.styles';
export type EuiInlineEditCommonProps = HTMLAttributes<HTMLDivElement> &
CommonProps & {
defaultValue: string;
placeholder?: string;
/**
* Callback that fires when a user clicks the save button.
* Passes the current edited text value as an argument.
Expand Down Expand Up @@ -121,6 +122,7 @@ export const EuiInlineEditForm: FunctionComponent<EuiInlineEditFormProps> = ({
children,
sizes,
defaultValue,
placeholder,
inputAriaLabel,
startWithEditOpen,
readModeProps,
Expand All @@ -134,12 +136,6 @@ export const EuiInlineEditForm: FunctionComponent<EuiInlineEditFormProps> = ({

const euiTheme = useEuiTheme();

const readModeStyles = euiInlineEditReadModeStyles(euiTheme);
const readModeCssStyles = [
readModeStyles.euiInlineEditReadMode,
isReadOnly && readModeStyles.isReadOnly,
];

const { controlHeight, controlCompressedHeight } = euiFormVariables(euiTheme);
const loadingSkeletonSize = sizes.compressed
? controlCompressedHeight
Expand Down Expand Up @@ -172,6 +168,13 @@ export const EuiInlineEditForm: FunctionComponent<EuiInlineEditFormProps> = ({
const [editModeValue, setEditModeValue] = useState(defaultValue);
const [readModeValue, setReadModeValue] = useState(defaultValue);

const readModeStyles = euiInlineEditReadModeStyles(euiTheme);
const readModeCssStyles = [
readModeStyles.euiInlineEditReadMode,
isReadOnly && readModeStyles.isReadOnly,
placeholder && !readModeValue && readModeStyles.hasPlaceholder,
];

const activateEditMode = () => {
setIsEditing(true);
// Waits a tick for state to settle and the focus target to render
Expand Down Expand Up @@ -234,6 +237,7 @@ export const EuiInlineEditForm: FunctionComponent<EuiInlineEditFormProps> = ({
isInvalid={isInvalid}
isLoading={isLoading}
data-test-subj="euiInlineEditModeInput"
placeholder={placeholder}
{...editModeProps?.inputProps}
inputRef={setEditModeRefs}
onChange={(e) => {
Expand Down Expand Up @@ -337,7 +341,7 @@ export const EuiInlineEditForm: FunctionComponent<EuiInlineEditFormProps> = ({
readModeProps?.onClick?.(e);
}}
>
{children(readModeValue)}
{children(readModeValue || placeholder)}
</EuiButtonEmpty>
<span id={readModeDescribedById} hidden>
{!isReadOnly && (
Expand Down
2 changes: 2 additions & 0 deletions src/components/inline_edit/inline_edit_text.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export const EuiInlineEditText: FunctionComponent<EuiInlineEditTextProps> = ({
className,
size = 'm',
defaultValue,
placeholder,
inputAriaLabel,
startWithEditOpen,
readModeProps: _readModeProps,
Expand Down Expand Up @@ -62,6 +63,7 @@ export const EuiInlineEditText: FunctionComponent<EuiInlineEditTextProps> = ({
const formProps = {
sizes,
defaultValue,
placeholder,
inputAriaLabel,
startWithEditOpen,
readModeProps,
Expand Down
2 changes: 2 additions & 0 deletions src/components/inline_edit/inline_edit_title.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export const EuiInlineEditTitle: FunctionComponent<EuiInlineEditTitleProps> = ({
size = 'm',
heading,
defaultValue,
placeholder,
inputAriaLabel,
startWithEditOpen,
readModeProps: _readModeProps,
Expand Down Expand Up @@ -78,6 +79,7 @@ export const EuiInlineEditTitle: FunctionComponent<EuiInlineEditTitleProps> = ({
const formProps = {
sizes,
defaultValue,
placeholder,
inputAriaLabel,
startWithEditOpen,
readModeProps,
Expand Down
1 change: 1 addition & 0 deletions upcoming_changelogs/6883.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Added `placeholder` prop to `EuiInlineEdit`