-
Notifications
You must be signed in to change notification settings - Fork 887
[EuiInlineEdit] Create isReadOnly Prop for Read Mode
#6777
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
Changes from 7 commits
004831e
8c08bc3
0cdc03b
8a7b117
da47079
e41cd89
f7cad78
fd36545
cf3a1c9
5dd01b0
c5930d8
c46e6ed
531be08
13a0a02
4375522
1940f35
070d008
30c2e11
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| import React, { useState } from 'react'; | ||
|
|
||
| import { | ||
| EuiInlineEditText, | ||
| EuiInlineEditTitle, | ||
| EuiSpacer, | ||
| EuiSwitch, | ||
| } from '../../../../src'; | ||
|
|
||
| export default () => { | ||
| const [isReadOnly, setIsReadOnly] = useState(true); | ||
|
|
||
| return ( | ||
| <> | ||
| <EuiSwitch | ||
| label="Toggle isReadOnly" | ||
|
breehall marked this conversation as resolved.
Outdated
|
||
| checked={isReadOnly} | ||
| onChange={(e) => setIsReadOnly(e.target.checked)} | ||
| /> | ||
|
|
||
| <EuiSpacer /> | ||
|
|
||
| <EuiInlineEditText | ||
| inputAriaLabel="Edit text inline" | ||
| defaultValue="This is read only text!" | ||
| isReadOnly={isReadOnly} | ||
| /> | ||
|
|
||
| <EuiSpacer /> | ||
|
|
||
| <EuiInlineEditTitle | ||
| inputAriaLabel="Edit title inline" | ||
| defaultValue="This is a read only title!" | ||
| heading="h3" | ||
| isReadOnly={isReadOnly} | ||
| /> | ||
| </> | ||
| ); | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| /* | ||
| * 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 { css } from '@emotion/react'; | ||
| import { UseEuiTheme } from '../../services'; | ||
|
|
||
| export const euiInlineEditFormStyles = ({ euiTheme }: UseEuiTheme) => { | ||
| return { | ||
| euiInlineEditButton: css``, | ||
|
|
||
| // Override the cursor and allow users to highlight text when read mode is in the read only state | ||
| isReadOnly: css` | ||
| &.euiButtonEmpty:disabled { | ||
|
cee-chen marked this conversation as resolved.
|
||
| cursor: default; | ||
|
breehall marked this conversation as resolved.
Outdated
|
||
| color: ${euiTheme.colors.text}; | ||
| user-select: text; | ||
|
breehall marked this conversation as resolved.
|
||
| } | ||
| `, | ||
| }; | ||
| }; | ||
|
cee-chen marked this conversation as resolved.
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -33,6 +33,7 @@ import { EuiSkeletonLoading, EuiSkeletonRectangle } from '../skeleton'; | |
| import { useEuiTheme, useCombinedRefs, keys } from '../../services'; | ||
| import { EuiI18n, useEuiI18n } from '../i18n'; | ||
| import { useGeneratedHtmlId } from '../../services/accessibility'; | ||
| import { euiInlineEditFormStyles } from './inline_edit_form.styles'; | ||
|
|
||
| // Props shared between the internal form component as well as consumer-facing components | ||
| export type EuiInlineEditCommonProps = HTMLAttributes<HTMLDivElement> & | ||
|
|
@@ -80,6 +81,10 @@ export type EuiInlineEditCommonProps = HTMLAttributes<HTMLDivElement> & | |
| * Invalid state - only displayed edit mode | ||
| */ | ||
| isInvalid?: boolean; | ||
| /** | ||
| * Locks inline edit in read mode and displays the text value | ||
| */ | ||
| isReadOnly?: boolean; | ||
| }; | ||
|
|
||
| // Internal-only props, passed by the consumer-facing components | ||
|
|
@@ -122,10 +127,18 @@ export const EuiInlineEditForm: FunctionComponent<EuiInlineEditFormProps> = ({ | |
| isLoading = false, | ||
| isInvalid, | ||
| onSave, | ||
| isReadOnly, | ||
| }) => { | ||
| const classes = classNames('euiInlineEdit', className); | ||
|
|
||
| const euiTheme = useEuiTheme(); | ||
|
|
||
| const styles = euiInlineEditFormStyles(euiTheme); | ||
| const readOnlyStyles = [ | ||
| styles.euiInlineEditButton, | ||
| isReadOnly && styles.isReadOnly, | ||
| ]; | ||
|
|
||
| const { controlHeight, controlCompressedHeight } = euiFormVariables(euiTheme); | ||
| const loadingSkeletonSize = sizes.compressed | ||
| ? controlCompressedHeight | ||
|
|
@@ -228,12 +241,14 @@ export const EuiInlineEditForm: FunctionComponent<EuiInlineEditFormProps> = ({ | |
| )} | ||
| /> | ||
| </EuiFormRow> | ||
| <span id={editModeDescribedById} hidden> | ||
| <EuiI18n | ||
| token="euiInlineEditForm.inputKeyboardInstructions" | ||
| default="Press Enter to save your edited text. Press Escape to cancel your edit." | ||
| /> | ||
| </span> | ||
| {!isReadOnly && ( | ||
| <span id={editModeDescribedById} hidden> | ||
| <EuiI18n | ||
| token="euiInlineEditForm.inputKeyboardInstructions" | ||
| default="Press Enter to save your edited text. Press Escape to cancel your edit." | ||
| /> | ||
| </span> | ||
| )} | ||
|
cee-chen marked this conversation as resolved.
Outdated
|
||
| </EuiFlexItem> | ||
|
|
||
| <EuiFlexItem grow={false}> | ||
|
|
@@ -296,12 +311,14 @@ export const EuiInlineEditForm: FunctionComponent<EuiInlineEditFormProps> = ({ | |
| <> | ||
| <EuiButtonEmpty | ||
| color="text" | ||
| iconType="pencil" | ||
| iconType={isReadOnly ? undefined : 'pencil'} | ||
| iconSide="right" | ||
| flush="both" | ||
| iconSize={sizes.iconSize} | ||
| size={sizes.buttonSize} | ||
| data-test-subj="euiInlineReadModeButton" | ||
| disabled={isReadOnly} | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @1Copenut I'd super appreciate your thoughts on this, I'm not totally convinced just the I could be wrong, but I think we want the semantic meaning of the text or title to revert to how it would be when it's not in a button, which in this case means adding manual EuiText example: EuiTitle example: Thoughts? Honestly, if I could I'd get rid of the button wrapper entirely, but I don't think there's an easy way to accomplish that and still retain the correct styles / sizing.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This was honestly the first thing I tried, but it was no easy feat. The There's a mismatch in
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Haha woof. Yeah, I totally get that. Unfortunately You can set those props conditionally from the parent
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just update this branch with a potential solution for this. I'll wait to hear what y'all think!
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you're onto something here. I'm experimenting with ways to get the disabled buttons to stop announcing as "dimmed" but haven't hit on the right combination yet. I'll update tomorrow if I find something more useful.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sadly on VO, I couldn't get passed the We could maybe add an if we can't get away from using
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @1Copenut separately, I'm curious what you think about potentially adding the
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Cee, you read my mind. I was experimenting with adding a conditional // src/components/inline_edit/inline_edit_title.tsx#L99
<H role={isReadOnly ? 'presentation' : 'heading'}>{titleReadModeValue}</H>I'm going from memory what I was noodling with last night, so it might take a couple of experiments, but I did find a way to get the heading announcing in Safari + VO, so hopefully Firefox + VO follows suit. NVDA did a better job announcing the heading and treating it as a heading "stop" in Chrome and Firefox. |
||
| css={readOnlyStyles} | ||
| {...readModeProps} | ||
| buttonRef={setReadModeRefs} | ||
| aria-describedby={classNames( | ||
|
cee-chen marked this conversation as resolved.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The ! src/components/inline_edit/inline_edit_form.tsx#343
{!isReadOnly && (
+ <>
<span id={readModeDescribedById} hidden>
<EuiI18n
token="euiInlineEditForm.activateEditModeDescription"
default="Click this button to edit this text inline."
/>
</span>
+ </>
)}
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @1Copenut that's super bizarre - is NVDA caching the text somehow? Won't axe throw an error since the aria-describedby is still pointing to an ID that no longer exists? Do we need to modify
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Cee is right. We'll need to unset the |
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.