diff --git a/packages/terra-core-docs/CHANGELOG.md b/packages/terra-core-docs/CHANGELOG.md index 207f9410262..6ba0475ff91 100644 --- a/packages/terra-core-docs/CHANGELOG.md +++ b/packages/terra-core-docs/CHANGELOG.md @@ -32,6 +32,7 @@ * Updated * Updated an example for `terra-dropdown-button`. * Updated email field validation for `terra-form-field`. + * Updated `terra-show-hide` examples for new focusRef prop, description for the new prop usage. * Added * Added documentation updates for `terra-form-input`. diff --git a/packages/terra-core-docs/src/terra-dev-site/doc/show-hide/About.1.doc.mdx b/packages/terra-core-docs/src/terra-dev-site/doc/show-hide/About.1.doc.mdx index 43959e371d1..f8441814950 100644 --- a/packages/terra-core-docs/src/terra-dev-site/doc/show-hide/About.1.doc.mdx +++ b/packages/terra-core-docs/src/terra-dev-site/doc/show-hide/About.1.doc.mdx @@ -1,19 +1,30 @@ import { Badge } from 'terra-show-hide/package.json?dev-site-package'; +import { Notice } from "@cerner/terra-docs"; import DefaultShowHide from './example/DefaultShowHide?dev-site-example'; import CustomButtonTextShowHide from './example/CustomButtonTextShowHide?dev-site-example'; +import LinkShowHide from './example/LinkShowHide?dev-site-example'; import InitiallyOpenShowHide from './example/InitiallyOpenShowHide?dev-site-example'; import ButtonAlignCenterShowHide from './example/ButtonAlignCenterShowHide?dev-site-example'; import ButtonAlignRightShowHide from './example/ButtonAlignRightShowHide?dev-site-example'; import NoPreviewShowHide from './example/NoPreviewShowHide?dev-site-example'; - +import NoFocusRefShowHide from './example/NoFocusRefShowHide?dev-site-example'; import ShowHidePropsTable from 'terra-show-hide/lib/ShowHide?dev-site-props-table'; +import ShowHideFocuserPropsTable from 'terra-show-hide/lib/ShowHideFocuser?dev-site-props-table'; # Terra Show Hide -Show Hide Component that will show a preview of content and then expand it with a Show More button. + Show Hide Component is a disclosure widget that enables content to be either collapsed (hidden) or expanded (visible). + It has two elements: a disclosure [button][1] and a section of content whose visibility is controlled by the button. + When the controlled content is hidden, the button is often styled as a typical push button with a down-pointing caret to hint that activating the button will display additional content. + When the content is visible, the content displays above the button and the caret points up. + +Another Terra component, [Toggle Button][2], is available and preferred to Show/Hide when possible because it better adheres to accessibility best practices for disclosure components. It differs from Show Hide by displaying the content below the button when it is activated. + +[1]: https://www.w3.org/WAI/ARIA/apg/patterns/button/ +[2]: https://engineering.cerner.com/terra-core/components/cerner-terra-core-docs/toggle-button/about ## Getting Started @@ -42,9 +53,133 @@ The Show-Hide component must be composed inside the [Base][1] component with a l ## Usage ```jsx -import ShowHide from 'terra-show-hide'; +import ShowHide, { ShowHideFocuser } from 'terra-show-hide'; ``` +## Accessibility + + + + To make the ShowHide component accessible, the `focusRef` prop must be used. + This prop allows assistive technologies such as screen readers to move user focus backward to hidden text and announce it when it is disclosed. + For backward compatibility, the `focusRef` prop is optional, but is required to meet accessibility requirements. + + + + + + This component is not recommended for use in Safari due to VoiceOver focus limitations with ShowHide. Consider using Terra Toggle Button instead. + + + +### Keyboard Interactions + When the disclosure control has focus: + - Enter key activates the disclosure control and toggles the visibility of the disclosure content. + - Space key activates the disclosure control and toggles the visibility of the disclosure content. + +### Truncating a paragraph of text + + To truncate a paragraph of text: + - At the top level of your component declare a `ref`, pass it as `focusRef` prop to `ShowHide` component. + - Pass a node with the preview portion of the text as a prop to `ShowHide` component. + - Use the `ShowHideFocuser` component inside `

` tag. A `ShowHideFocuser` component allows `ShowHide` component to set focus on the beginning of the focusable text upon opening. + - The text split in the prefix and focusable text portions must be passed as string props. The prefix prop should contain the portion of the text that was a part of the preview prop, passed to `ShowHide`. + - Forward `focusRef` to `ShowHideFocuser` component. + + ```jsx + import React, { useRef, useState } from 'react'; + import ShowHide, { ShowHideFocuser } from 'terra-show-hide'; + + const MyComponent = () => { + const focusRef = useRef(null); + const [isOpen, setIsOpen] = useState(false); + const toggleShowHide = () => setIsOpen(!isOpen); + + const prefix = 'Patients are requesting greater affordability and efficiency in healthcare. With procedures performed in an ambulatory surgery center costing up to 60% less compared to a hospital outpatient department (1), the demand for these facilities is increasing.'; + const focusableText = 'In fact, the U.S. ambulatory surgery center market is expected to see a 6.9 % compound annual growth rate, reaching $33 billion by 2028. (2) Cerner understands the urgency to grow in the ambulatory surgery center market while continuing to deliver excellent care. Healthcare IT products can help improve clinician efficiency and patient outcomes, as well as enhance communication and data exchange between ambulatory surgery center providers and patients.'; + + return ( + {prefix}

} isOpen={isOpen} onChange={toggleShowHide} > +

+ +

+ + ); + } + ``` + +### Multiple children + Even though the main purpose of the `ShowHide` component is to truncate long paragraphs of texts, the content of the `ShowHide` does not have to be one paragraph. + It can include links, lists, and any kind of HTML tags as long as the first line of the hidden text is passed as a string prop to `ShowHideFocuser` component rather than an HTML element. + +Please note: + - Links can be placed inside the `p` tag that wraps `ShowHideFocuser` both preceding and following it. The prop `prefix` can be omitted if content has been passed as an HTML element preceding `ShowHideFocuser`. + - Everything that precedes `ShowHideFocuser` must also be included into the `ShowHide` preview prop. + - Do not break lists by placing `ShowHideFocuser` inside `
  • ` elements as this may cause assistive technologies to read the content incorrectly. + + ```jsx + import React, { useState, useRef } from 'react'; + import ShowHide, { ShowHideFocuser } from 'terra-show-hide'; + + const MyComponent = () => { + const focusRef = useRef(null); + const [isOpen, setIsOpen] = useState(false); + const toggleShowHide = () => setIsOpen(!isOpen); + + const header = 'Bringing clarity to life sciences and healthcare decision-making '; + const prefix = 'When we accelerate the discovery, development and deployment of life-enhancing insights and therapies, clinicians and patients benefit.'; + const preview = [ +

    {header}

    , +

    {prefix}

    , + ]; + + return ( + +

    {header}

    + // This paragraph contains a link in hidden content. Explore a working example below under Examples, Custom Button Text ShowHide. +

    + + guide better care, including: +

    +
      +
    • Data-driven research solutions for commercial and real-world evidence collaborators and health providers
    • +
    • Support to move from simply accumulating and analyzing data to linking and generating deeper insights
    • +
    • Combined life sciences knowledge, healthcare innovation and collaborative research expertise
    • +
    +
    + ); + } + ``` + +### First hidden child is an interactive element (link, button, etc) + If the first hidden child is an interactive element: + - At the top level of your component declare a `ref`. + - In this case there is no need to use `ShowHideFocuser`. Forward `focusRef` to the interactive element directly. + + ```jsx + import React, { useState, useRef } from 'react'; + import ShowHide from 'terra-show-hide'; + + const MyComponent = () => { + const focusRef = useRef(null); + const [isOpen, setIsOpen] = useState(false); + const toggleShowHide = () => setIsOpen(!isOpen); + + const previewText = 'Although the process is complex and will vary greatly based on regional and economic factors, it’s clear that healthcare entities must start planning their transitions now.'; + const text = 'it expects all Medicare Parts A and B beneficiaries and most Medicaid beneficiaries to be in a value-based care relationship with accountability for quality and total cost of care by 2030.'; + + return ( + {previewText}

    } isOpen={isOpen} onChange={toggleShowHide} > +

    + {previewText} + CMS recently announced + {text} +

    +
    + ); + } + ``` + ## Component Features * [Cross-Browser Support](https://engineering.cerner.com/terra-ui/about/terra-ui/component-standards#cross-browser-support) @@ -57,10 +192,17 @@ import ShowHide from 'terra-show-hide'; ## Examples + + + + ## Show Hide Props + +## Show Hide Focuser Props + diff --git a/packages/terra-core-docs/src/terra-dev-site/doc/show-hide/example/ButtonAlignCenterShowHide.jsx b/packages/terra-core-docs/src/terra-dev-site/doc/show-hide/example/ButtonAlignCenterShowHide.jsx index b0d30b6869b..7d14175fa5d 100644 --- a/packages/terra-core-docs/src/terra-dev-site/doc/show-hide/example/ButtonAlignCenterShowHide.jsx +++ b/packages/terra-core-docs/src/terra-dev-site/doc/show-hide/example/ButtonAlignCenterShowHide.jsx @@ -1,8 +1,8 @@ import React from 'react'; -import ShowHide from 'terra-show-hide'; +import ShowHide, { ShowHideFocuser } from 'terra-show-hide'; -const fullText = 'According to the Journal of Healthcare Management/American College of Healthcare Executives, a 500-bed hospital loses over $4 million annually due to clinical communication inefficiencies. A unified clinical communication strategy can help health systems begin to close the gap and improve efficiency at every level. Enable your clinical care team with real-time health communication tools and workflows that help them to collaborate more effectively on the go and provide a quality patient care experience. A unified strategy and improved communication tools can help address many challenges including identification of patient care team members, mobile clinical workflows, secure and timely critical alerts, and more.'; -const previewText = fullText.substring(0, 280); +const prefix = 'According to the Journal of Healthcare Management/American College of Healthcare Executives, a 500-bed hospital loses over $4 million annually due to clinical communication inefficiencies. A unified clinical communication strategy can help health systems begin to close the gap'; +const focusableText = 'and improve efficiency at every level. Enable your clinical care team with real-time health communication tools and workflows that help them to collaborate more effectively on the go and provide a quality patient care experience. A unified strategy and improved communication tools can help address many challenges including identification of patient care team members, mobile clinical workflows, secure and timely critical alerts, and more.'; class ButtonAlignCenterShowHide extends React.Component { constructor(props) { @@ -10,6 +10,7 @@ class ButtonAlignCenterShowHide extends React.Component { this.state = { isOpen: false }; this.toggleShowHide = this.toggleShowHide.bind(this); + this.focusRef = React.createRef(); } toggleShowHide() { @@ -21,8 +22,8 @@ class ButtonAlignCenterShowHide extends React.Component { render() { return (
    - {previewText}

    } isOpen={this.state.isOpen} onChange={this.toggleShowHide}> -

    {fullText}

    + {prefix}

    } isOpen={this.state.isOpen} onChange={this.toggleShowHide}> +

    ); diff --git a/packages/terra-core-docs/src/terra-dev-site/doc/show-hide/example/ButtonAlignRightShowHide.jsx b/packages/terra-core-docs/src/terra-dev-site/doc/show-hide/example/ButtonAlignRightShowHide.jsx index 74bf0377d71..7fd4809084a 100644 --- a/packages/terra-core-docs/src/terra-dev-site/doc/show-hide/example/ButtonAlignRightShowHide.jsx +++ b/packages/terra-core-docs/src/terra-dev-site/doc/show-hide/example/ButtonAlignRightShowHide.jsx @@ -1,8 +1,8 @@ import React from 'react'; -import ShowHide from 'terra-show-hide'; +import ShowHide, { ShowHideFocuser } from 'terra-show-hide'; -const fullText = 'A connected care team starts with an integrated communication strategy. CareAware ConnectTM is a healthcare communication tool that leverages the use of intuitive technology to help associate the right care team members with the right patients and provides a way to effectively communicate and collaborate while on the go through a smart, mobile device. Integration with Cerner Millennium® enables care teams to streamline bedside workflows including medication administration, device association, and specimen collection.'; -const previewText = fullText.substring(0, 280); +const prefix = 'A connected care team starts with an integrated communication strategy. CareAware ConnectTM is a healthcare communication tool that leverages the use of intuitive technology to help associate the right care team members with the right patients and provides a way to effectively'; +const focusableText = 'communicate and collaborate while on the go through a smart, mobile device. Integration with Cerner Millennium® enables care teams to streamline bedside workflows including medication administration, device association, and specimen collection.'; class ButtonAlignRightShowHideTest extends React.Component { constructor(props) { @@ -10,6 +10,7 @@ class ButtonAlignRightShowHideTest extends React.Component { this.state = { isOpen: false }; this.toggleShowHide = this.toggleShowHide.bind(this); + this.focusRef = React.createRef(); } toggleShowHide() { @@ -21,8 +22,8 @@ class ButtonAlignRightShowHideTest extends React.Component { render() { return (
    - {previewText}

    } isOpen={this.state.isOpen} onChange={this.toggleShowHide}> -

    {fullText}

    + {prefix}

    } isOpen={this.state.isOpen} onChange={this.toggleShowHide}> +

    ); diff --git a/packages/terra-core-docs/src/terra-dev-site/doc/show-hide/example/CustomButtonTextShowHide.jsx b/packages/terra-core-docs/src/terra-dev-site/doc/show-hide/example/CustomButtonTextShowHide.jsx index c807a7934e6..2be3a78e6a1 100644 --- a/packages/terra-core-docs/src/terra-dev-site/doc/show-hide/example/CustomButtonTextShowHide.jsx +++ b/packages/terra-core-docs/src/terra-dev-site/doc/show-hide/example/CustomButtonTextShowHide.jsx @@ -1,16 +1,25 @@ +/* eslint-disable jsx-a11y/anchor-is-valid */ import React from 'react'; -import ShowHide from 'terra-show-hide'; - -const sentences = [ -

    Key Benefits of Cerner Cardiovascular Solutions

    , -

    Eliminates silos of information and the resulting inefficiencies with a unified EHR and cardiovascular system

    , -

    Creates efficient diagnostic workflows, image management and analysis

    , -

    Enhances clinical, financial and performance outcomes with comprehensive procedural documentation

    , -

    Promotes cardiac disease management through health maintenance protocols

    , - //

    Lorem ipsum dolor sit amet consectetur adipiscing elit.

    , - //

    Lorem ipsum dolor sit amet consectetur adipiscing elit.

    , - //

    Lorem ipsum dolor sit amet consectetur adipiscing elit.

    , - //

    Lorem ipsum dolor sit amet consectetur adipiscing elit.

    +import ShowHide, { ShowHideFocuser } from 'terra-show-hide'; + +const header = 'Bringing clarity to life sciences and healthcare decision-making '; +const text = [ + 'When we accelerate the discovery, development and deployment of life-enhancing insights and therapies, clinicians and patients benefit. Connecting data and breaking down silos', + 'across the healthcare innovation ecosystem must be our collective focus to help improve everyday health for all people. Several factors help bring clarity to life sciences, researchers and clinicians and', + 'guide better care,', + 'including:', +]; +const listItems = [ +
  • Data-driven research solutions for commercial and real-world evidence collaborators and health providers
  • , +
  • Support to move from simply accumulating and analyzing data to linking and generating deeper insights
  • , +
  • Combined life sciences knowledge, healthcare innovation and collaborative research expertise
  • , +
  • Access to an expansive network of diverse research-ready health systems; as well as de-identified, real-world data from the EHR that also includes patient-reported outcomes
  • , +]; +const conclusion = 'Through data and technology, we have the power to help life sciences, clinicians and researchers expand therapeutic areas of research and generate better evidence to solve healthcare challenges around the world. Together, we can accelerate groundbreaking research and trial opportunities that have the potential to transform everyday healthcare and improve people’s lives.'; + +const preview = [ +

    {header}

    , +

    {text[0]}

    , ]; class CustomButtonTextShowHide extends React.Component { @@ -19,6 +28,7 @@ class CustomButtonTextShowHide extends React.Component { this.state = { isOpen: false }; this.toggleShowHide = this.toggleShowHide.bind(this); + this.focusRef = React.createRef(); } toggleShowHide() { @@ -31,19 +41,29 @@ class CustomButtonTextShowHide extends React.Component { let customText = ''; if (this.state.isOpen) { - customText = `Hide ${sentences.length - 3} Sentences`; + customText = 'Hide Composite Content'; } else { - customText = `Show ${sentences.length - 3} More Sentences`; + customText = 'Show Composite Content'; } return ( - {sentences} +

    {header}

    +

    + + {' '} + {text[2]} + {' '} + {text[3]} +

    + +

    {conclusion}

    ); } diff --git a/packages/terra-core-docs/src/terra-dev-site/doc/show-hide/example/DefaultShowHide.jsx b/packages/terra-core-docs/src/terra-dev-site/doc/show-hide/example/DefaultShowHide.jsx index 15239982ea9..b26a5445328 100644 --- a/packages/terra-core-docs/src/terra-dev-site/doc/show-hide/example/DefaultShowHide.jsx +++ b/packages/terra-core-docs/src/terra-dev-site/doc/show-hide/example/DefaultShowHide.jsx @@ -1,8 +1,8 @@ import React from 'react'; -import ShowHide from 'terra-show-hide'; +import ShowHide, { ShowHideFocuser } from 'terra-show-hide'; -const fullText = 'Patients are requesting greater affordability and efficiency in healthcare. With procedures performed in an ambulatory surgery center costing up to 60% less compared to a hospital outpatient department (1), the demand for these facilities is increasing. In fact, the U.S. ambulatory surgery center market is expected to see a 6.9 % compound annual growth rate, reaching $33 billion by 2028. (2) Cerner understands the urgency to grow in the ambulatory surgery center market while continuing to deliver excellent care. Healthcare IT products can help improve clinician efficiency and patient outcomes, as well as enhance communication and data exchange between ambulatory surgery center providers and patients.'; -const previewText = fullText.substring(0, 280); +const prefix = 'Patients are requesting greater affordability and efficiency in healthcare. With procedures performed in an ambulatory surgery center costing up to 60% less compared to a hospital outpatient department (1), the demand for these facilities is increasing.'; +const focusableText = 'In fact, the U.S. ambulatory surgery center market is expected to see a 6.9 % compound annual growth rate, reaching $33 billion by 2028. (2) Cerner understands the urgency to grow in the ambulatory surgery center market while continuing to deliver excellent care. Healthcare IT products can help improve clinician efficiency and patient outcomes, as well as enhance communication and data exchange between ambulatory surgery center providers and patients.'; class DefaultShowHide extends React.Component { constructor(props) { @@ -10,6 +10,7 @@ class DefaultShowHide extends React.Component { this.state = { isOpen: false }; this.toggleShowHide = this.toggleShowHide.bind(this); + this.focusRef = React.createRef(); } toggleShowHide() { @@ -20,11 +21,11 @@ class DefaultShowHide extends React.Component { render() { return ( -
    - {previewText}

    } isOpen={this.state.isOpen} onChange={this.toggleShowHide}> -

    {fullText}

    -
    -
    + {prefix}

    } isOpen={this.state.isOpen} onChange={this.toggleShowHide}> +

    + +

    +
    ); } } diff --git a/packages/terra-core-docs/src/terra-dev-site/doc/show-hide/example/InitiallyOpenShowHide.jsx b/packages/terra-core-docs/src/terra-dev-site/doc/show-hide/example/InitiallyOpenShowHide.jsx index 8f0fd6bd81f..afeb4bd4d42 100644 --- a/packages/terra-core-docs/src/terra-dev-site/doc/show-hide/example/InitiallyOpenShowHide.jsx +++ b/packages/terra-core-docs/src/terra-dev-site/doc/show-hide/example/InitiallyOpenShowHide.jsx @@ -1,8 +1,8 @@ import React from 'react'; -import ShowHide from 'terra-show-hide'; +import ShowHide, { ShowHideFocuser } from 'terra-show-hide'; -const fullText = 'Cerner cardiovascular solutions are embedded within the EHR, allowing for a holistic patient record that includes: diagnostic activities, therapeutic interventions and follow-up regimens. Electrocardiogram (ECG) objects are digitized and accessed within the EHR providing physicians in your cardiology department the ability to receive and present ECG data in mere seconds after it is acquired. This eliminates the necessity for a separate ECG information system.'; -const previewText = fullText.substring(0, 280); +const prefix = 'Cerner cardiovascular solutions are embedded within the EHR, allowing for a holistic patient record that includes: diagnostic activities, therapeutic interventions and follow-up regimens. Electrocardiogram (ECG) objects are digitized and accessed within the EHR providing physicians'; +const focusableText = 'in your cardiology department the ability to receive and present ECG data in mere seconds after it is acquired. This eliminates the necessity for a separate ECG information system.'; class InitiallyOpenShowHide extends React.Component { constructor(props) { @@ -10,6 +10,7 @@ class InitiallyOpenShowHide extends React.Component { this.state = { isOpen: true }; this.toggleShowHide = this.toggleShowHide.bind(this); + this.focusRef = React.createRef(); } toggleShowHide() { @@ -20,8 +21,10 @@ class InitiallyOpenShowHide extends React.Component { render() { return ( - {previewText}

    } isOpen={this.state.isOpen} onChange={this.toggleShowHide}> -

    {fullText}

    + {prefix}

    } isOpen={this.state.isOpen} onChange={this.toggleShowHide}> +

    + +

    ); } diff --git a/packages/terra-core-docs/src/terra-dev-site/doc/show-hide/example/LinkShowHide.jsx b/packages/terra-core-docs/src/terra-dev-site/doc/show-hide/example/LinkShowHide.jsx new file mode 100644 index 00000000000..2ce84ca45d2 --- /dev/null +++ b/packages/terra-core-docs/src/terra-dev-site/doc/show-hide/example/LinkShowHide.jsx @@ -0,0 +1,35 @@ +import React from 'react'; +import ShowHide from 'terra-show-hide'; + +const previewText = 'Although the process is complex and will vary greatly based on regional and economic factors, it’s clear that healthcare entities must start planning their transitions now. '; +const text = ' it expects all Medicare Parts A and B beneficiaries and most Medicaid beneficiaries to be in a value-based care relationship with accountability for quality and total cost of care by 2030.'; + +class LinkShowHide extends React.Component { + constructor(props) { + super(props); + + this.state = { isOpen: false }; + this.toggleShowHide = this.toggleShowHide.bind(this); + this.focusRef = React.createRef(); + } + + toggleShowHide() { + this.setState(prevState => ({ + isOpen: !prevState.isOpen, + })); + } + + render() { + return ( + {previewText}

    } isOpen={this.state.isOpen} onChange={this.toggleShowHide}> +

    + {previewText} + CMS recently announced + {text} +

    +
    + ); + } +} + +export default LinkShowHide; diff --git a/packages/terra-core-docs/src/terra-dev-site/doc/show-hide/example/NoFocusRefShowHide.jsx b/packages/terra-core-docs/src/terra-dev-site/doc/show-hide/example/NoFocusRefShowHide.jsx new file mode 100644 index 00000000000..c1eb5135caf --- /dev/null +++ b/packages/terra-core-docs/src/terra-dev-site/doc/show-hide/example/NoFocusRefShowHide.jsx @@ -0,0 +1,30 @@ +import React from 'react'; +import ShowHide from 'terra-show-hide'; + +const fullText = 'Successful value-based care strategies must demonstrate proficiency in optimizing venues of care to improve health outcomes, lower costs and increase consumer access and satisfaction. They must be able to analyze and predict the unique needs of each individual and appropriately match them to the skills offered in their network.'; +const previewText = fullText.substring(0, 278); + +class NoFocusRefShowHide extends React.Component { + constructor(props) { + super(props); + + this.state = { isOpen: false }; + this.toggleShowHide = this.toggleShowHide.bind(this); + } + + toggleShowHide() { + this.setState(prevState => ({ + isOpen: !prevState.isOpen, + })); + } + + render() { + return ( + {previewText}

    } isOpen={this.state.isOpen} onChange={this.toggleShowHide}> +

    {fullText}

    +
    + ); + } +} + +export default NoFocusRefShowHide; diff --git a/packages/terra-core-docs/src/terra-dev-site/doc/show-hide/example/NoPreviewShowHide.jsx b/packages/terra-core-docs/src/terra-dev-site/doc/show-hide/example/NoPreviewShowHide.jsx index f688c09de28..82d97f0288c 100644 --- a/packages/terra-core-docs/src/terra-dev-site/doc/show-hide/example/NoPreviewShowHide.jsx +++ b/packages/terra-core-docs/src/terra-dev-site/doc/show-hide/example/NoPreviewShowHide.jsx @@ -1,7 +1,7 @@ import React from 'react'; -import ShowHide from 'terra-show-hide'; +import ShowHide, { ShowHideFocuser } from 'terra-show-hide'; -const fullText = 'CareAware is Cerners comprehensive enterprise-wide solution for device connectivity. CareAware® is a suite of solutions that enable any area of a hospital to create an environment where all devices are integrated and contextually aware to ensure the right data is presented in the right format at the right time.'; +const focusableText = 'CareAware is Cerners comprehensive enterprise-wide solution for device connectivity. CareAware® is a suite of solutions that enable any area of a hospital to create an environment where all devices are integrated and contextually aware to ensure the right data is presented in the right format at the right time.'; class NoPreviewShowHide extends React.Component { constructor(props) { @@ -9,6 +9,7 @@ class NoPreviewShowHide extends React.Component { this.state = { isOpen: false }; this.toggleShowHide = this.toggleShowHide.bind(this); + this.focusRef = React.createRef(); } toggleShowHide() { @@ -19,8 +20,8 @@ class NoPreviewShowHide extends React.Component { render() { return ( - -

    {fullText}

    + +

    ); } diff --git a/packages/terra-core-docs/src/terra-dev-site/test/show-hide/ButtonAlignCenterShowHide.test.jsx b/packages/terra-core-docs/src/terra-dev-site/test/show-hide/ButtonAlignCenterShowHide.test.jsx index d517fb34c7a..380638d8377 100644 --- a/packages/terra-core-docs/src/terra-dev-site/test/show-hide/ButtonAlignCenterShowHide.test.jsx +++ b/packages/terra-core-docs/src/terra-dev-site/test/show-hide/ButtonAlignCenterShowHide.test.jsx @@ -1,8 +1,8 @@ import React from 'react'; -import ShowHide from 'terra-show-hide'; +import ShowHide, { ShowHideFocuser } from 'terra-show-hide'; -const fullText = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut enim ante, porta sit amet sem vitae, pellentesque pharetra ex. Etiam odio purus, maximus eget mauris in, pulvinar euismod neque. Curabitur eu vulputate leo. Etiam tincidunt lectus ut metus interdum, sit amet porttitor leo ornare. Sed tincidunt rutrum odio, dignissim rhoncus nulla finibus et. Mauris mollis posuere dolor dignissim vulputate. Sed accumsan dignissim mi id pulvinar. Vivamus sapien nibh, dignissim id semper non, consectetur et felis. Duis mattis odio tortor, eu mattis lectus lobortis mattis. Ut sit amet risus pellentesque, imperdiet mi eu, sodales massa. Aenean quis lacus rutrum, lobortis urna vel, congue est. Vivamus viverra efficitur viverra. Integer sit amet metus dolor. Nullam imperdiet vehicula tincidunt. Duis consequat congue magna, eu imperdiet magna venenatis et. Quisque eget vulputate massa. Donec vel diam vel nulla gravida blandit sit amet sed quam. Donec sed feugiat magna, eget consequat mi. Ut quis arcu non libero tempus semper nec in sem. Nunc in quam leo. Donec risus eros, dapibus ut nisi vitae, ullamcorper faucibus nisl. Suspendisse finibus urna vel mi sodales, a pharetra nisl convallis. Phasellus sed turpis non ipsum scelerisque pellentesque at cursus lectus. Nunc ut velit nec odio ultrices sodales.'; -const previewText = fullText.substring(0, 280); +const prefix = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut enim ante, porta sit amet sem vitae, pellentesque pharetra ex. Etiam odio purus, maximus eget mauris in, pulvinar euismod neque. Curabitur eu vulputate leo. Etiam tincidunt lectus ut metus interdum, sit amet porttitor le'; +const focusableText = 'o ornare. Sed tincidunt rutrum odio, dignissim rhoncus nulla finibus et. Mauris mollis posuere dolor dignissim vulputate. Sed accumsan dignissim mi id pulvinar. Vivamus sapien nibh, dignissim id semper non, consectetur et felis. Duis mattis odio tortor, eu mattis lectus lobortis mattis. Ut sit amet risus pellentesque, imperdiet mi eu, sodales massa. Aenean quis lacus rutrum, lobortis urna vel, congue est. Vivamus viverra efficitur viverra. Integer sit amet metus dolor. Nullam imperdiet vehicula tincidunt. Duis consequat congue magna, eu imperdiet magna venenatis et. Quisque eget vulputate massa. Donec vel diam vel nulla gravida blandit sit amet sed quam. Donec sed feugiat magna, eget consequat mi. Ut quis arcu non libero tempus semper nec in sem. Nunc in quam leo. Donec risus eros, dapibus ut nisi vitae, ullamcorper faucibus nisl. Suspendisse finibus urna vel mi sodales, a pharetra nisl convallis. Phasellus sed turpis non ipsum scelerisque pellentesque at cursus lectus. Nunc ut velit nec odio ultrices sodales.'; class ButtonAlignCenterShowHide extends React.Component { constructor(props) { @@ -10,6 +10,7 @@ class ButtonAlignCenterShowHide extends React.Component { this.state = { isOpen: false }; this.toggleShowHide = this.toggleShowHide.bind(this); + this.focusRef = React.createRef(); } toggleShowHide() { @@ -21,8 +22,8 @@ class ButtonAlignCenterShowHide extends React.Component { render() { return (
    - {previewText}

    } isOpen={this.state.isOpen} onChange={this.toggleShowHide}> -

    {fullText}

    + {prefix}

    } isOpen={this.state.isOpen} onChange={this.toggleShowHide}> +

    ); diff --git a/packages/terra-core-docs/src/terra-dev-site/test/show-hide/ButtonAlignEndShowHide.test.jsx b/packages/terra-core-docs/src/terra-dev-site/test/show-hide/ButtonAlignEndShowHide.test.jsx index fdc3ce85923..46181b5dcd9 100644 --- a/packages/terra-core-docs/src/terra-dev-site/test/show-hide/ButtonAlignEndShowHide.test.jsx +++ b/packages/terra-core-docs/src/terra-dev-site/test/show-hide/ButtonAlignEndShowHide.test.jsx @@ -1,8 +1,8 @@ import React from 'react'; -import ShowHide from 'terra-show-hide'; +import ShowHide, { ShowHideFocuser } from 'terra-show-hide'; -const fullText = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut enim ante, porta sit amet sem vitae, pellentesque pharetra ex. Etiam odio purus, maximus eget mauris in, pulvinar euismod neque. Curabitur eu vulputate leo. Etiam tincidunt lectus ut metus interdum, sit amet porttitor leo ornare. Sed tincidunt rutrum odio, dignissim rhoncus nulla finibus et. Mauris mollis posuere dolor dignissim vulputate. Sed accumsan dignissim mi id pulvinar. Vivamus sapien nibh, dignissim id semper non, consectetur et felis. Duis mattis odio tortor, eu mattis lectus lobortis mattis. Ut sit amet risus pellentesque, imperdiet mi eu, sodales massa. Aenean quis lacus rutrum, lobortis urna vel, congue est. Vivamus viverra efficitur viverra. Integer sit amet metus dolor. Nullam imperdiet vehicula tincidunt. Duis consequat congue magna, eu imperdiet magna venenatis et. Quisque eget vulputate massa. Donec vel diam vel nulla gravida blandit sit amet sed quam. Donec sed feugiat magna, eget consequat mi. Ut quis arcu non libero tempus semper nec in sem. Nunc in quam leo. Donec risus eros, dapibus ut nisi vitae, ullamcorper faucibus nisl. Suspendisse finibus urna vel mi sodales, a pharetra nisl convallis. Phasellus sed turpis non ipsum scelerisque pellentesque at cursus lectus. Nunc ut velit nec odio ultrices sodales.'; -const previewText = fullText.substring(0, 280); +const prefix = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut enim ante, porta sit amet sem vitae, pellentesque pharetra ex. Etiam odio purus, maximus eget mauris in, pulvinar euismod neque. Curabitur eu vulputate leo. Etiam tincidunt lectus ut metus interdum, sit amet porttitor le'; +const focusableText = 'o ornare. Sed tincidunt rutrum odio, dignissim rhoncus nulla finibus et. Mauris mollis posuere dolor dignissim vulputate. Sed accumsan dignissim mi id pulvinar. Vivamus sapien nibh, dignissim id semper non, consectetur et felis. Duis mattis odio tortor, eu mattis lectus lobortis mattis. Ut sit amet risus pellentesque, imperdiet mi eu, sodales massa. Aenean quis lacus rutrum, lobortis urna vel, congue est. Vivamus viverra efficitur viverra. Integer sit amet metus dolor. Nullam imperdiet vehicula tincidunt. Duis consequat congue magna, eu imperdiet magna venenatis et. Quisque eget vulputate massa. Donec vel diam vel nulla gravida blandit sit amet sed quam. Donec sed feugiat magna, eget consequat mi. Ut quis arcu non libero tempus semper nec in sem. Nunc in quam leo. Donec risus eros, dapibus ut nisi vitae, ullamcorper faucibus nisl. Suspendisse finibus urna vel mi sodales, a pharetra nisl convallis. Phasellus sed turpis non ipsum scelerisque pellentesque at cursus lectus. Nunc ut velit nec odio ultrices sodales.'; class ButtonAlignRightShowHideTest extends React.Component { constructor(props) { @@ -10,6 +10,7 @@ class ButtonAlignRightShowHideTest extends React.Component { this.state = { isOpen: false }; this.toggleShowHide = this.toggleShowHide.bind(this); + this.focusRef = React.createRef(); } toggleShowHide() { @@ -21,8 +22,8 @@ class ButtonAlignRightShowHideTest extends React.Component { render() { return (
    - {previewText}

    } isOpen={this.state.isOpen} onChange={this.toggleShowHide}> -

    {fullText}

    + {prefix}

    } isOpen={this.state.isOpen} onChange={this.toggleShowHide}> +

    ); diff --git a/packages/terra-core-docs/src/terra-dev-site/test/show-hide/ButtonAlignStartShowHide.test.jsx b/packages/terra-core-docs/src/terra-dev-site/test/show-hide/ButtonAlignStartShowHide.test.jsx index 85e8547f159..9f29a6d5d93 100644 --- a/packages/terra-core-docs/src/terra-dev-site/test/show-hide/ButtonAlignStartShowHide.test.jsx +++ b/packages/terra-core-docs/src/terra-dev-site/test/show-hide/ButtonAlignStartShowHide.test.jsx @@ -1,8 +1,8 @@ import React from 'react'; -import ShowHide from 'terra-show-hide'; +import ShowHide, { ShowHideFocuser } from 'terra-show-hide'; -const fullText = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut enim ante, porta sit amet sem vitae, pellentesque pharetra ex. Etiam odio purus, maximus eget mauris in, pulvinar euismod neque. Curabitur eu vulputate leo. Etiam tincidunt lectus ut metus interdum, sit amet porttitor leo ornare. Sed tincidunt rutrum odio, dignissim rhoncus nulla finibus et. Mauris mollis posuere dolor dignissim vulputate. Sed accumsan dignissim mi id pulvinar. Vivamus sapien nibh, dignissim id semper non, consectetur et felis. Duis mattis odio tortor, eu mattis lectus lobortis mattis. Ut sit amet risus pellentesque, imperdiet mi eu, sodales massa. Aenean quis lacus rutrum, lobortis urna vel, congue est. Vivamus viverra efficitur viverra. Integer sit amet metus dolor. Nullam imperdiet vehicula tincidunt. Duis consequat congue magna, eu imperdiet magna venenatis et. Quisque eget vulputate massa. Donec vel diam vel nulla gravida blandit sit amet sed quam. Donec sed feugiat magna, eget consequat mi. Ut quis arcu non libero tempus semper nec in sem. Nunc in quam leo. Donec risus eros, dapibus ut nisi vitae, ullamcorper faucibus nisl. Suspendisse finibus urna vel mi sodales, a pharetra nisl convallis. Phasellus sed turpis non ipsum scelerisque pellentesque at cursus lectus. Nunc ut velit nec odio ultrices sodales.'; -const previewText = fullText.substring(0, 280); +const prefix = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut enim ante, porta sit amet sem vitae, pellentesque pharetra ex. Etiam odio purus, maximus eget mauris in, pulvinar euismod neque. Curabitur eu vulputate leo. Etiam tincidunt lectus ut metus interdum, sit amet porttitor le'; +const focusableText = 'o ornare. Sed tincidunt rutrum odio, dignissim rhoncus nulla finibus et. Mauris mollis posuere dolor dignissim vulputate. Sed accumsan dignissim mi id pulvinar. Vivamus sapien nibh, dignissim id semper non, consectetur et felis. Duis mattis odio tortor, eu mattis lectus lobortis mattis. Ut sit amet risus pellentesque, imperdiet mi eu, sodales massa. Aenean quis lacus rutrum, lobortis urna vel, congue est. Vivamus viverra efficitur viverra. Integer sit amet metus dolor. Nullam imperdiet vehicula tincidunt. Duis consequat congue magna, eu imperdiet magna venenatis et. Quisque eget vulputate massa. Donec vel diam vel nulla gravida blandit sit amet sed quam. Donec sed feugiat magna, eget consequat mi. Ut quis arcu non libero tempus semper nec in sem. Nunc in quam leo. Donec risus eros, dapibus ut nisi vitae, ullamcorper faucibus nisl. Suspendisse finibus urna vel mi sodales, a pharetra nisl convallis. Phasellus sed turpis non ipsum scelerisque pellentesque at cursus lectus. Nunc ut velit nec odio ultrices sodales.'; class ButtonAlignLeftShowHideTest extends React.Component { constructor(props) { @@ -10,6 +10,7 @@ class ButtonAlignLeftShowHideTest extends React.Component { this.state = { isOpen: false }; this.toggleShowHide = this.toggleShowHide.bind(this); + this.focusRef = React.createRef(); } toggleShowHide() { @@ -21,8 +22,8 @@ class ButtonAlignLeftShowHideTest extends React.Component { render() { return (
    - {previewText}

    } isOpen={this.state.isOpen} onChange={this.toggleShowHide}> -

    {fullText}

    + {prefix}

    } isOpen={this.state.isOpen} onChange={this.toggleShowHide}> +

    ); diff --git a/packages/terra-core-docs/src/terra-dev-site/test/show-hide/CustomButtonTextShowHide.test.jsx b/packages/terra-core-docs/src/terra-dev-site/test/show-hide/CustomButtonTextShowHide.test.jsx index ad79e373ef4..f995641731e 100644 --- a/packages/terra-core-docs/src/terra-dev-site/test/show-hide/CustomButtonTextShowHide.test.jsx +++ b/packages/terra-core-docs/src/terra-dev-site/test/show-hide/CustomButtonTextShowHide.test.jsx @@ -1,17 +1,14 @@ import React from 'react'; -import ShowHide from 'terra-show-hide'; - -const sentences = [ -

    Lorem ipsum dolor sit amet consectetur adipiscing elit.

    , -

    Lorem ipsum dolor sit amet consectetur adipiscing elit.

    , -

    Lorem ipsum dolor sit amet consectetur adipiscing elit.

    , -

    Lorem ipsum dolor sit amet consectetur adipiscing elit.

    , -

    Lorem ipsum dolor sit amet consectetur adipiscing elit.

    , -

    Lorem ipsum dolor sit amet consectetur adipiscing elit.

    , -

    Lorem ipsum dolor sit amet consectetur adipiscing elit.

    , -

    Lorem ipsum dolor sit amet consectetur adipiscing elit.

    , -

    Lorem ipsum dolor sit amet consectetur adipiscing elit.

    , -

    Lorem ipsum dolor sit amet consectetur adipiscing elit.

    , +import ShowHide, { ShowHideFocuser } from 'terra-show-hide'; + +const sentence = 'Lorem ipsum dolor sit amet consectetur adipiscing elit.'; + +const preview = [ +

    {`${sentence}`}

    , +
      +
    • {`${sentence}`}
    • +
    • {`${sentence}`}
    • +
    , ]; class CustomButtonTextShowHideTest extends React.Component { @@ -20,6 +17,7 @@ class CustomButtonTextShowHideTest extends React.Component { this.state = { isOpen: false }; this.toggleShowHide = this.toggleShowHide.bind(this); + this.focusRef = React.createRef(); } toggleShowHide() { @@ -32,19 +30,27 @@ class CustomButtonTextShowHideTest extends React.Component { let customText = ''; if (this.state.isOpen) { - customText = `Hide ${sentences.length - 3} Sentences`; + customText = 'Hide 3 Sentences'; } else { - customText = `Show ${sentences.length - 3} More Sentences`; + customText = 'Show 3 More Sentences'; } return ( - {sentences} +

    {`${sentence}`}

    +
      +
    • {`${sentence}`}
    • +
    • {`${sentence}`}
    • +
    • +
    • {`${sentence}`}
    • +
    • {`${sentence}`}
    • +
    ); } diff --git a/packages/terra-core-docs/src/terra-dev-site/test/show-hide/DefaultShowHide.test.jsx b/packages/terra-core-docs/src/terra-dev-site/test/show-hide/DefaultShowHide.test.jsx index c8902799dad..fee5c2a6ed9 100644 --- a/packages/terra-core-docs/src/terra-dev-site/test/show-hide/DefaultShowHide.test.jsx +++ b/packages/terra-core-docs/src/terra-dev-site/test/show-hide/DefaultShowHide.test.jsx @@ -1,8 +1,8 @@ import React from 'react'; -import ShowHide from 'terra-show-hide'; +import ShowHide, { ShowHideFocuser } from 'terra-show-hide'; -const fullText = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut enim ante, porta sit amet sem vitae, pellentesque pharetra ex. Etiam odio purus, maximus eget mauris in, pulvinar euismod neque. Curabitur eu vulputate leo. Etiam tincidunt lectus ut metus interdum, sit amet porttitor leo ornare. Sed tincidunt rutrum odio, dignissim rhoncus nulla finibus et. Mauris mollis posuere dolor dignissim vulputate. Sed accumsan dignissim mi id pulvinar. Vivamus sapien nibh, dignissim id semper non, consectetur et felis. Duis mattis odio tortor, eu mattis lectus lobortis mattis. Ut sit amet risus pellentesque, imperdiet mi eu, sodales massa. Aenean quis lacus rutrum, lobortis urna vel, congue est. Vivamus viverra efficitur viverra. Integer sit amet metus dolor. Nullam imperdiet vehicula tincidunt. Duis consequat congue magna, eu imperdiet magna venenatis et. Quisque eget vulputate massa. Donec vel diam vel nulla gravida blandit sit amet sed quam. Donec sed feugiat magna, eget consequat mi. Ut quis arcu non libero tempus semper nec in sem. Nunc in quam leo. Donec risus eros, dapibus ut nisi vitae, ullamcorper faucibus nisl. Suspendisse finibus urna vel mi sodales, a pharetra nisl convallis. Phasellus sed turpis non ipsum scelerisque pellentesque at cursus lectus. Nunc ut velit nec odio ultrices sodales.'; -const previewText = fullText.substring(0, 280); +const prefix = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut enim ante, porta sit amet sem vitae, pellentesque pharetra ex. Etiam odio purus, maximus eget mauris in, pulvinar euismod neque. Curabitur eu vulputate leo. Etiam tincidunt lectus ut metus interdum, sit amet porttitor le'; +const focusableText = 'o ornare. Sed tincidunt rutrum odio, dignissim rhoncus nulla finibus et. Mauris mollis posuere dolor dignissim vulputate. Sed accumsan dignissim mi id pulvinar. Vivamus sapien nibh, dignissim id semper non, consectetur et felis. Duis mattis odio tortor, eu mattis lectus lobortis mattis. Ut sit amet risus pellentesque, imperdiet mi eu, sodales massa. Aenean quis lacus rutrum, lobortis urna vel, congue est. Vivamus viverra efficitur viverra. Integer sit amet metus dolor. Nullam imperdiet vehicula tincidunt. Duis consequat congue magna, eu imperdiet magna venenatis et. Quisque eget vulputate massa. Donec vel diam vel nulla gravida blandit sit amet sed quam. Donec sed feugiat magna, eget consequat mi. Ut quis arcu non libero tempus semper nec in sem. Nunc in quam leo. Donec risus eros, dapibus ut nisi vitae, ullamcorper faucibus nisl. Suspendisse finibus urna vel mi sodales, a pharetra nisl convallis. Phasellus sed turpis non ipsum scelerisque pellentesque at cursus lectus. Nunc ut velit nec odio ultrices sodales.'; class DefaultShowHide extends React.Component { constructor(props) { @@ -10,6 +10,7 @@ class DefaultShowHide extends React.Component { this.state = { isOpen: false }; this.toggleShowHide = this.toggleShowHide.bind(this); + this.focusRef = React.createRef(); } toggleShowHide() { @@ -20,8 +21,8 @@ class DefaultShowHide extends React.Component { render() { return ( - - {fullText} + {prefix}

    } onChange={this.toggleShowHide}> +

    ); } diff --git a/packages/terra-core-docs/src/terra-dev-site/test/show-hide/InitiallyOpenShowHide.test.jsx b/packages/terra-core-docs/src/terra-dev-site/test/show-hide/InitiallyOpenShowHide.test.jsx index db8ddf9fb6b..60562b92a0f 100644 --- a/packages/terra-core-docs/src/terra-dev-site/test/show-hide/InitiallyOpenShowHide.test.jsx +++ b/packages/terra-core-docs/src/terra-dev-site/test/show-hide/InitiallyOpenShowHide.test.jsx @@ -1,8 +1,8 @@ import React from 'react'; -import ShowHide from 'terra-show-hide'; +import ShowHide, { ShowHideFocuser } from 'terra-show-hide'; -const fullText = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut enim ante, porta sit amet sem vitae, pellentesque pharetra ex. Etiam odio purus, maximus eget mauris in, pulvinar euismod neque. Curabitur eu vulputate leo. Etiam tincidunt lectus ut metus interdum, sit amet porttitor leo ornare. Sed tincidunt rutrum odio, dignissim rhoncus nulla finibus et. Mauris mollis posuere dolor dignissim vulputate. Sed accumsan dignissim mi id pulvinar. Vivamus sapien nibh, dignissim id semper non, consectetur et felis. Duis mattis odio tortor, eu mattis lectus lobortis mattis. Ut sit amet risus pellentesque, imperdiet mi eu, sodales massa. Aenean quis lacus rutrum, lobortis urna vel, congue est. Vivamus viverra efficitur viverra. Integer sit amet metus dolor. Nullam imperdiet vehicula tincidunt. Duis consequat congue magna, eu imperdiet magna venenatis et. Quisque eget vulputate massa. Donec vel diam vel nulla gravida blandit sit amet sed quam. Donec sed feugiat magna, eget consequat mi. Ut quis arcu non libero tempus semper nec in sem. Nunc in quam leo. Donec risus eros, dapibus ut nisi vitae, ullamcorper faucibus nisl. Suspendisse finibus urna vel mi sodales, a pharetra nisl convallis. Phasellus sed turpis non ipsum scelerisque pellentesque at cursus lectus. Nunc ut velit nec odio ultrices sodales.'; -const previewText = fullText.substring(0, 280); +const prefix = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut enim ante, porta sit amet sem vitae, pellentesque pharetra ex. Etiam odio purus, maximus eget mauris in, pulvinar euismod neque. Curabitur eu vulputate leo. Etiam tincidunt lectus ut metus interdum, sit amet porttitor le'; +const focusableText = 'o ornare. Sed tincidunt rutrum odio, dignissim rhoncus nulla finibus et. Mauris mollis posuere dolor dignissim vulputate. Sed accumsan dignissim mi id pulvinar. Vivamus sapien nibh, dignissim id semper non, consectetur et felis. Duis mattis odio tortor, eu mattis lectus lobortis mattis. Ut sit amet risus pellentesque, imperdiet mi eu, sodales massa. Aenean quis lacus rutrum, lobortis urna vel, congue est. Vivamus viverra efficitur viverra. Integer sit amet metus dolor. Nullam imperdiet vehicula tincidunt. Duis consequat congue magna, eu imperdiet magna venenatis et. Quisque eget vulputate massa. Donec vel diam vel nulla gravida blandit sit amet sed quam. Donec sed feugiat magna, eget consequat mi. Ut quis arcu non libero tempus semper nec in sem. Nunc in quam leo. Donec risus eros, dapibus ut nisi vitae, ullamcorper faucibus nisl. Suspendisse finibus urna vel mi sodales, a pharetra nisl convallis. Phasellus sed turpis non ipsum scelerisque pellentesque at cursus lectus. Nunc ut velit nec odio ultrices sodales.'; class InitiallyOpenShowHide extends React.Component { constructor(props) { @@ -10,6 +10,7 @@ class InitiallyOpenShowHide extends React.Component { this.state = { isOpen: true }; this.toggleShowHide = this.toggleShowHide.bind(this); + this.focusRef = React.createRef(); } toggleShowHide() { @@ -20,8 +21,8 @@ class InitiallyOpenShowHide extends React.Component { render() { return ( - - {fullText} + {prefix}

    } isOpen={this.state.isOpen} onChange={this.toggleShowHide}> +

    ); } diff --git a/packages/terra-core-docs/src/terra-dev-site/test/show-hide/InteractiveShowHide.test.jsx b/packages/terra-core-docs/src/terra-dev-site/test/show-hide/InteractiveShowHide.test.jsx new file mode 100644 index 00000000000..794303dddcc --- /dev/null +++ b/packages/terra-core-docs/src/terra-dev-site/test/show-hide/InteractiveShowHide.test.jsx @@ -0,0 +1,59 @@ +import React from 'react'; +import ShowHide, { ShowHideFocuser } from 'terra-show-hide'; + +const sentence = 'Lorem ipsum dolor sit amet consectetur adipiscing elit.'; + +const preview = [ +

    {sentence}

    , +

    {sentence}

    , +

    {sentence}

    , +]; + +const text = [ +

    {sentence}

    , +

    {sentence}

    , +

    {sentence}

    , +]; + +class InteractiveShowHideTest extends React.Component { + constructor(props) { + super(props); + + this.state = { isOpen: false }; + this.toggleShowHide = this.toggleShowHide.bind(this); + this.focusRef = React.createRef(); + } + + toggleShowHide() { + this.setState(prevState => ({ + isOpen: !prevState.isOpen, + })); + } + + render() { + let customText = ''; + + if (this.state.isOpen) { + customText = `Hide ${text.length + 2} Sentences`; + } else { + customText = `Show ${text.length + 2} More Sentences`; + } + + return ( + + {preview} +

    + Link + {text} +
    + ); + } +} + +export default InteractiveShowHideTest; diff --git a/packages/terra-core-docs/src/terra-dev-site/test/show-hide/LongButtonTextShowHide.test.jsx b/packages/terra-core-docs/src/terra-dev-site/test/show-hide/LongButtonTextShowHide.test.jsx index 12a80b7ce4b..6d249ed6937 100644 --- a/packages/terra-core-docs/src/terra-dev-site/test/show-hide/LongButtonTextShowHide.test.jsx +++ b/packages/terra-core-docs/src/terra-dev-site/test/show-hide/LongButtonTextShowHide.test.jsx @@ -1,8 +1,8 @@ import React from 'react'; -import ShowHide from 'terra-show-hide'; +import ShowHide, { ShowHideFocuser } from 'terra-show-hide'; -const fullText = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut enim ante, porta sit amet sem vitae, pellentesque pharetra ex. Etiam odio purus, maximus eget mauris in, pulvinar euismod neque. Curabitur eu vulputate leo. Etiam tincidunt lectus ut metus interdum, sit amet porttitor leo ornare. Sed tincidunt rutrum odio, dignissim rhoncus nulla finibus et. Mauris mollis posuere dolor dignissim vulputate. Sed accumsan dignissim mi id pulvinar. Vivamus sapien nibh, dignissim id semper non, consectetur et felis. Duis mattis odio tortor, eu mattis lectus lobortis mattis. Ut sit amet risus pellentesque, imperdiet mi eu, sodales massa. Aenean quis lacus rutrum, lobortis urna vel, congue est. Vivamus viverra efficitur viverra. Integer sit amet metus dolor. Nullam imperdiet vehicula tincidunt. Duis consequat congue magna, eu imperdiet magna venenatis et. Quisque eget vulputate massa. Donec vel diam vel nulla gravida blandit sit amet sed quam. Donec sed feugiat magna, eget consequat mi. Ut quis arcu non libero tempus semper nec in sem. Nunc in quam leo. Donec risus eros, dapibus ut nisi vitae, ullamcorper faucibus nisl. Suspendisse finibus urna vel mi sodales, a pharetra nisl convallis. Phasellus sed turpis non ipsum scelerisque pellentesque at cursus lectus. Nunc ut velit nec odio ultrices sodales.'; -const previewText = fullText.substring(0, 280); +const prefix = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut enim ante, porta sit amet sem vitae, pellentesque pharetra ex. Etiam odio purus, maximus eget mauris in, pulvinar euismod neque. Curabitur eu vulputate leo. Etiam tincidunt lectus ut metus interdum, sit amet porttitor le'; +const focusableText = 'o ornare. Sed tincidunt rutrum odio, dignissim rhoncus nulla finibus et. Mauris mollis posuere dolor dignissim vulputate. Sed accumsan dignissim mi id pulvinar. Vivamus sapien nibh, dignissim id semper non, consectetur et felis. Duis mattis odio tortor, eu mattis lectus lobortis mattis. Ut sit amet risus pellentesque, imperdiet mi eu, sodales massa. Aenean quis lacus rutrum, lobortis urna vel, congue est. Vivamus viverra efficitur viverra. Integer sit amet metus dolor. Nullam imperdiet vehicula tincidunt. Duis consequat congue magna, eu imperdiet magna venenatis et. Quisque eget vulputate massa. Donec vel diam vel nulla gravida blandit sit amet sed quam. Donec sed feugiat magna, eget consequat mi. Ut quis arcu non libero tempus semper nec in sem. Nunc in quam leo. Donec risus eros, dapibus ut nisi vitae, ullamcorper faucibus nisl. Suspendisse finibus urna vel mi sodales, a pharetra nisl convallis. Phasellus sed turpis non ipsum scelerisque pellentesque at cursus lectus. Nunc ut velit nec odio ultrices sodales.'; class DefaultShowHide extends React.Component { constructor(props) { @@ -10,6 +10,7 @@ class DefaultShowHide extends React.Component { this.state = { isOpen: false }; this.toggleShowHide = this.toggleShowHide.bind(this); + this.focusRef = React.createRef(); } toggleShowHide() { @@ -21,12 +22,13 @@ class DefaultShowHide extends React.Component { render() { return ( {prefix}

    } isOpen={this.state.isOpen} onChange={this.toggleShowHide} buttonText="Show Section Label that is way too long and has to wrap to multiple lines Show Section Label that is way too long and has to wrap to multiple lines" > - {fullText} +

    ); } diff --git a/packages/terra-core-docs/src/terra-dev-site/test/show-hide/NoFocusRefShowHide.test.jsx b/packages/terra-core-docs/src/terra-dev-site/test/show-hide/NoFocusRefShowHide.test.jsx new file mode 100644 index 00000000000..64d33a1f972 --- /dev/null +++ b/packages/terra-core-docs/src/terra-dev-site/test/show-hide/NoFocusRefShowHide.test.jsx @@ -0,0 +1,30 @@ +import React from 'react'; +import ShowHide from 'terra-show-hide'; + +const fullText = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut enim ante, porta sit amet sem vitae, pellentesque pharetra ex. Etiam odio purus, maximus eget mauris in, pulvinar euismod neque. Curabitur eu vulputate leo. Etiam tincidunt lectus ut metus interdum, sit amet porttitor leo ornare. Sed tincidunt rutrum odio, dignissim rhoncus nulla finibus et. Mauris mollis posuere dolor dignissim vulputate. Sed accumsan dignissim mi id pulvinar. Vivamus sapien nibh, dignissim id semper non, consectetur et felis. Duis mattis odio tortor, eu mattis lectus lobortis mattis. Ut sit amet risus pellentesque, imperdiet mi eu, sodales massa. Aenean quis lacus rutrum, lobortis urna vel, congue est. Vivamus viverra efficitur viverra. Integer sit amet metus dolor. Nullam imperdiet vehicula tincidunt. Duis consequat congue magna, eu imperdiet magna venenatis et. Quisque eget vulputate massa. Donec vel diam vel nulla gravida blandit sit amet sed quam. Donec sed feugiat magna, eget consequat mi. Ut quis arcu non libero tempus semper nec in sem. Nunc in quam leo. Donec risus eros, dapibus ut nisi vitae, ullamcorper faucibus nisl. Suspendisse finibus urna vel mi sodales, a pharetra nisl convallis. Phasellus sed turpis non ipsum scelerisque pellentesque at cursus lectus. Nunc ut velit nec odio ultrices sodales.'; +const previewText = fullText.substring(0, 280); + +class NoFocusRefShowHide extends React.Component { + constructor(props) { + super(props); + + this.state = { isOpen: false }; + this.toggleShowHide = this.toggleShowHide.bind(this); + } + + toggleShowHide() { + this.setState(prevState => ({ + isOpen: !prevState.isOpen, + })); + } + + render() { + return ( + {previewText}

    } isOpen={this.state.isOpen} onChange={this.toggleShowHide}> +

    {fullText}

    +
    + ); + } +} + +export default NoFocusRefShowHide; diff --git a/packages/terra-core-docs/src/terra-dev-site/test/show-hide/NoPreviewShowHide.test.jsx b/packages/terra-core-docs/src/terra-dev-site/test/show-hide/NoPreviewShowHide.test.jsx index ffb6bccda3c..a606621e212 100644 --- a/packages/terra-core-docs/src/terra-dev-site/test/show-hide/NoPreviewShowHide.test.jsx +++ b/packages/terra-core-docs/src/terra-dev-site/test/show-hide/NoPreviewShowHide.test.jsx @@ -1,7 +1,7 @@ import React from 'react'; -import ShowHide from 'terra-show-hide'; +import ShowHide, { ShowHideFocuser } from 'terra-show-hide'; -const fullText = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut enim ante, porta sit amet sem vitae, pellentesque pharetra ex. Etiam odio purus, maximus eget mauris in, pulvinar euismod neque. Curabitur eu vulputate leo. Etiam tincidunt lectus ut metus interdum, sit amet porttitor leo ornare. Sed tincidunt rutrum odio, dignissim rhoncus nulla finibus et. Mauris mollis posuere dolor dignissim vulputate. Sed accumsan dignissim mi id pulvinar. Vivamus sapien nibh, dignissim id semper non, consectetur et felis. Duis mattis odio tortor, eu mattis lectus lobortis mattis. Ut sit amet risus pellentesque, imperdiet mi eu, sodales massa. Aenean quis lacus rutrum, lobortis urna vel, congue est. Vivamus viverra efficitur viverra. Integer sit amet metus dolor. Nullam imperdiet vehicula tincidunt. Duis consequat congue magna, eu imperdiet magna venenatis et. Quisque eget vulputate massa. Donec vel diam vel nulla gravida blandit sit amet sed quam. Donec sed feugiat magna, eget consequat mi. Ut quis arcu non libero tempus semper nec in sem. Nunc in quam leo. Donec risus eros, dapibus ut nisi vitae, ullamcorper faucibus nisl. Suspendisse finibus urna vel mi sodales, a pharetra nisl convallis. Phasellus sed turpis non ipsum scelerisque pellentesque at cursus lectus. Nunc ut velit nec odio ultrices sodales.'; +const focusableText = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut enim ante, porta sit amet sem vitae, pellentesque pharetra ex. Etiam odio purus, maximus eget mauris in, pulvinar euismod neque. Curabitur eu vulputate leo. Etiam tincidunt lectus ut metus interdum, sit amet porttitor leo ornare. Sed tincidunt rutrum odio, dignissim rhoncus nulla finibus et. Mauris mollis posuere dolor dignissim vulputate. Sed accumsan dignissim mi id pulvinar. Vivamus sapien nibh, dignissim id semper non, consectetur et felis. Duis mattis odio tortor, eu mattis lectus lobortis mattis. Ut sit amet risus pellentesque, imperdiet mi eu, sodales massa. Aenean quis lacus rutrum, lobortis urna vel, congue est. Vivamus viverra efficitur viverra. Integer sit amet metus dolor. Nullam imperdiet vehicula tincidunt. Duis consequat congue magna, eu imperdiet magna venenatis et. Quisque eget vulputate massa. Donec vel diam vel nulla gravida blandit sit amet sed quam. Donec sed feugiat magna, eget consequat mi. Ut quis arcu non libero tempus semper nec in sem. Nunc in quam leo. Donec risus eros, dapibus ut nisi vitae, ullamcorper faucibus nisl. Suspendisse finibus urna vel mi sodales, a pharetra nisl convallis. Phasellus sed turpis non ipsum scelerisque pellentesque at cursus lectus. Nunc ut velit nec odio ultrices sodales.'; class NoPreviewShowHide extends React.Component { constructor(props) { @@ -9,6 +9,7 @@ class NoPreviewShowHide extends React.Component { this.state = { isOpen: false }; this.toggleShowHide = this.toggleShowHide.bind(this); + this.focusRef = React.createRef(); } toggleShowHide() { @@ -19,8 +20,8 @@ class NoPreviewShowHide extends React.Component { render() { return ( - -

    {fullText}

    + +

    ); } diff --git a/packages/terra-show-hide/CHANGELOG.md b/packages/terra-show-hide/CHANGELOG.md index 50fae1b1d3d..7f2625c29e3 100644 --- a/packages/terra-show-hide/CHANGELOG.md +++ b/packages/terra-show-hide/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Added + * Added `focusRef` prop to shift focus to the hidden content when it is revealed for screen-reader users. + ## 2.61.0 - (August 1, 2023) * Changed diff --git a/packages/terra-show-hide/package.json b/packages/terra-show-hide/package.json index f2fae679cf7..f9a1079d392 100644 --- a/packages/terra-show-hide/package.json +++ b/packages/terra-show-hide/package.json @@ -1,6 +1,6 @@ { "name": "terra-show-hide", - "main": "lib/ShowHide.js", + "main": "lib/index.js", "version": "2.61.0", "description": "Show/Hide component that previews a small section of content or shows the full content with the click of a button", "repository": { @@ -35,7 +35,8 @@ "prop-types": "^15.5.8", "terra-mixins": "^1.40.0", "terra-theme-context": "^1.0.0", - "terra-toggle": "^3.56.0" + "terra-toggle": "^3.56.0", + "uuid": "3.4.0" }, "scripts": { "compile": "babel --root-mode upward src --out-dir lib --copy-files", diff --git a/packages/terra-show-hide/src/ShowHide.jsx b/packages/terra-show-hide/src/ShowHide.jsx index 80ee10fa9d0..7d4336f145f 100644 --- a/packages/terra-show-hide/src/ShowHide.jsx +++ b/packages/terra-show-hide/src/ShowHide.jsx @@ -1,8 +1,12 @@ -import React from 'react'; +import React, { + useContext, useState, useRef, useEffect, +} from 'react'; import PropTypes from 'prop-types'; import Toggle from 'terra-toggle'; import { injectIntl } from 'react-intl'; +import { v4 as uuidv4 } from 'uuid'; import classNames from 'classnames/bind'; +import ThemeContext from 'terra-theme-context'; import styles from './ShowHide.module.scss'; import Button from './_ShowHideButton'; @@ -34,6 +38,12 @@ const propTypes = { * Allows parent to toggle the component. True for open and false for close. */ isOpen: PropTypes.bool, + /** + * Ref to the first hidden child element that will receive focus when the full content is revealed. This allows assistive technologies to start reading the hidden content from where it left off. + */ + focusRef: PropTypes.shape({ + current: PropTypes.instanceOf(Element), + }), /** * Elements(s) that will be visible to the user when component is collapsed */ @@ -43,7 +53,8 @@ const propTypes = { const defaultProps = { buttonAlign: 'start', isOpen: false, - preview: undefined, + preview: null, + focusRef: null, }; const ShowHide = (props) => { @@ -55,9 +66,37 @@ const ShowHide = (props) => { preview, intl, isOpen, + focusRef, ...customProps } = props; + const theme = useContext(ThemeContext); + const contentRef = useRef(null); + const [containerIsActive, setContainerIsActive] = useState(false); + + /** + * Upon showing hidden content, set activeElement to focusRef element if provided, othervise set it to content container. + */ + useEffect(() => { + if (!isOpen) { + return; + } + if (focusRef?.current) { + focusRef?.current.focus(); + } else if (contentRef?.current) { + setContainerIsActive(true); + } + }, [isOpen, focusRef, contentRef]); + + useEffect(() => { + if (containerIsActive && isOpen && contentRef?.current) { + contentRef?.current?.focus(); + } + }, [containerIsActive, isOpen]); + + const id = uuidv4(); + const contentId = `show-hide-content-${id}`; + const buttonClassName = cx([ 'show-hide', 'button', @@ -75,14 +114,31 @@ const ShowHide = (props) => { } } + const onBlur = () => { + if (containerIsActive) { + setContainerIsActive(false); + } + }; + return (
    {!isOpen && preview} - - {children} - +
    + + {children} + +