diff --git a/src-docs/src/views/inline_edit/inline_edit_example.js b/src-docs/src/views/inline_edit/inline_edit_example.js index 5c57e1ca5ae..ebe59fa12f2 100644 --- a/src-docs/src/views/inline_edit/inline_edit_example.js +++ b/src-docs/src/views/inline_edit/inline_edit_example.js @@ -30,6 +30,14 @@ const inlineEditTitleSnippet = ``; +import InlineEditPlaceholder from './inline_edit_placeholder'; +const inlineEditPlaceholderSource = require('!!raw-loader!./inline_edit_placeholder'); +const inlineEditPlaceholderSnippet = ``; + import InlineEditSave from './inline_edit_save'; const inlineEditSaveSource = require('!!raw-loader!././inline_edit_save'); const inlineEditModeSaveSnippet = `, }, + { + title: 'Setting placeholder instructions', + text: ( + <> +

+ The placeholder property will display in both + read and edit mode whenever the EuiInlineEdit's + value is empty. Use placeholder text to provide guidance or + instructions to consumers as to what they're editing. +

+ + ), + source: [ + { + type: GuideSectionTypes.TSX, + code: inlineEditPlaceholderSource, + }, + ], + demo: , + snippet: inlineEditPlaceholderSnippet, + }, { title: 'Start in edit mode', text: ( diff --git a/src-docs/src/views/inline_edit/inline_edit_placeholder.tsx b/src-docs/src/views/inline_edit/inline_edit_placeholder.tsx new file mode 100644 index 00000000000..936f8d581f6 --- /dev/null +++ b/src-docs/src/views/inline_edit/inline_edit_placeholder.tsx @@ -0,0 +1,28 @@ +import React from 'react'; + +import { + EuiInlineEditText, + EuiInlineEditTitle, + EuiSpacer, +} from '../../../../src'; + +export default () => { + return ( + <> + + + + + + + ); +}; diff --git a/src/components/inline_edit/__snapshots__/inline_edit_form.test.tsx.snap b/src/components/inline_edit/__snapshots__/inline_edit_form.test.tsx.snap index 752a477a9ae..73a68b09310 100644 --- a/src/components/inline_edit/__snapshots__/inline_edit_form.test.tsx.snap +++ b/src/components/inline_edit/__snapshots__/inline_edit_form.test.tsx.snap @@ -557,6 +557,93 @@ exports[`EuiInlineEditForm edit mode isLoading 1`] = ` `; +exports[`EuiInlineEditForm edit mode placeholder 1`] = ` +
+
+
+
+
+
+
+ +
+
+
+
+ +
+
+
+
+ + +
+
+
+
+
+`; + exports[`EuiInlineEditForm edit mode renders 1`] = `
`; +exports[`EuiInlineEditForm read mode placeholder 1`] = ` +
+ + +
+`; + exports[`EuiInlineEditForm read mode readModeProps 1`] = `
{ return { @@ -21,5 +21,12 @@ export const euiInlineEditReadModeStyles = ({ euiTheme }: UseEuiTheme) => { user-select: text; } `, + + hasPlaceholder: css` + .euiText, + .euiTitle { + color: ${tint(euiTheme.colors.subduedText, 0.08)}; + } + `, }; }; diff --git a/src/components/inline_edit/inline_edit_form.test.tsx b/src/components/inline_edit/inline_edit_form.test.tsx index 8d51e56c50d..c79d58bd728 100644 --- a/src/components/inline_edit/inline_edit_form.test.tsx +++ b/src/components/inline_edit/inline_edit_form.test.tsx @@ -75,6 +75,19 @@ describe('EuiInlineEditForm', () => { expect(container.firstChild).toMatchSnapshot(); }); + + test('placeholder', () => { + const { container, getByText } = render( + + ); + + expect(container.firstChild).toMatchSnapshot(); + expect(getByText('This is a placeholder.')).toBeTruthy(); + }); }); describe('edit mode', () => { @@ -202,6 +215,25 @@ describe('EuiInlineEditForm', () => { getByTestSubject('euiInlineEditModeInput').hasAttribute('aria-invalid') ).toBeTruthy(); }); + + test('placeholder', () => { + const { container, getByTestSubject } = render( + + ); + + expect(container.firstChild).toMatchSnapshot(); + expect( + getByTestSubject('euiInlineEditModeInput').getAttribute('placeholder') + ).toBeTruthy(); + expect( + getByTestSubject('euiInlineEditModeInput').getAttribute('value') + ).toBeFalsy(); + }); }); describe('toggling between read mode and edit mode', () => { @@ -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( + + ); + + expect( + getByTestSubject('euiInlineEditModeInput').getAttribute('placeholder') + ).toEqual('The real placeholder!'); + }); }); }); }); diff --git a/src/components/inline_edit/inline_edit_form.tsx b/src/components/inline_edit/inline_edit_form.tsx index 3793f5e5213..90feb3c86a7 100644 --- a/src/components/inline_edit/inline_edit_form.tsx +++ b/src/components/inline_edit/inline_edit_form.tsx @@ -40,6 +40,7 @@ import { euiInlineEditReadModeStyles } from './inline_edit_form.styles'; export type EuiInlineEditCommonProps = HTMLAttributes & CommonProps & { defaultValue: string; + placeholder?: string; /** * Callback that fires when a user clicks the save button. * Passes the current edited text value as an argument. @@ -121,6 +122,7 @@ export const EuiInlineEditForm: FunctionComponent = ({ children, sizes, defaultValue, + placeholder, inputAriaLabel, startWithEditOpen, readModeProps, @@ -134,12 +136,6 @@ export const EuiInlineEditForm: FunctionComponent = ({ const euiTheme = useEuiTheme(); - const readModeStyles = euiInlineEditReadModeStyles(euiTheme); - const readModeCssStyles = [ - readModeStyles.euiInlineEditReadMode, - isReadOnly && readModeStyles.isReadOnly, - ]; - const { controlHeight, controlCompressedHeight } = euiFormVariables(euiTheme); const loadingSkeletonSize = sizes.compressed ? controlCompressedHeight @@ -172,6 +168,13 @@ export const EuiInlineEditForm: FunctionComponent = ({ 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 @@ -234,6 +237,7 @@ export const EuiInlineEditForm: FunctionComponent = ({ isInvalid={isInvalid} isLoading={isLoading} data-test-subj="euiInlineEditModeInput" + placeholder={placeholder} {...editModeProps?.inputProps} inputRef={setEditModeRefs} onChange={(e) => { @@ -337,7 +341,7 @@ export const EuiInlineEditForm: FunctionComponent = ({ readModeProps?.onClick?.(e); }} > - {children(readModeValue)} + {children(readModeValue || placeholder)}