From 42ee4ec05e958f69aaa79312e4f19944d77036b4 Mon Sep 17 00:00:00 2001 From: Diego Date: Thu, 17 Mar 2022 10:41:30 -0600 Subject: [PATCH 1/4] refactor: eui-accordion --- packages/core/addon/components/common.ts | 1 + .../addon/components/eui-accordion/index.hbs | 53 ++++++++++--------- .../addon/components/eui-accordion/index.ts | 45 +++++++++++++--- .../core/docs/layout/accordion-demo/demo1.md | 49 ++++++++++++++--- 4 files changed, 109 insertions(+), 39 deletions(-) diff --git a/packages/core/addon/components/common.ts b/packages/core/addon/components/common.ts index 42095f45..8ca465ce 100644 --- a/packages/core/addon/components/common.ts +++ b/packages/core/addon/components/common.ts @@ -12,6 +12,7 @@ export type OneOf = Omit & { [k in K]: Pick, k> & { [k1 in Exclude]?: never } }[K]; export interface CommonArgs { + className?: string; 'aria-label'?: string; 'data-test-subj'?: string; } diff --git a/packages/core/addon/components/eui-accordion/index.hbs b/packages/core/addon/components/eui-accordion/index.hbs index e55c0fac..6cf65808 100644 --- a/packages/core/addon/components/eui-accordion/index.hbs +++ b/packages/core/addon/components/eui-accordion/index.hbs @@ -7,32 +7,30 @@ ...attributes >
+ {{#if this.hasArrowDisplay}} + + {{/if}} @@ -53,7 +51,10 @@ tabIndex={{-1}} class={{concat "euiAccordion__iconWrapper " - (if this.hasIconButton "euiAccordion__iconButton ") + "euiAccordion__icon " + this.iconButtonClasses + (if this.hasIconButton " euiAccordion__iconButton ") + (if this.isOpen "euiAccordion__iconButton-isOpen") }} type="button" {{on "click" this.onToggle}} @@ -69,7 +70,11 @@ {{/if}}
-
+
-
+
\ No newline at end of file diff --git a/packages/core/addon/components/eui-accordion/index.ts b/packages/core/addon/components/eui-accordion/index.ts index d0d28ee7..baec1b83 100644 --- a/packages/core/addon/components/eui-accordion/index.ts +++ b/packages/core/addon/components/eui-accordion/index.ts @@ -1,19 +1,33 @@ import Component from '@glimmer/component'; import { action } from '@ember/object'; import { tracked } from '@glimmer/tracking'; -import { uniqueId } from '../../helpers/unique-id'; import { argOrDefaultDecorator as argOrDefault } from '../../helpers/arg-or-default'; import { paddingMapping } from '../../utils/css-mappings/eui-accordion'; import { htmlSafe } from '@ember/template'; +import { CommonArgs } from '../common'; type EuiAccordionPaddingSize = keyof typeof paddingMapping; type AccordionArgs = { id: string; + + element?: 'div' | 'fieldset'; /** * Class that will apply to the trigger for the accordion. */ buttonClassName?: string; + + buttonProps?: CommonArgs; + + /** + * Applied to the main button receiving the `onToggle` event. + * Anything other than the default `button` does not support removing the arrow display (for accessibility of focus). + */ + buttonElement?: 'div' | 'legend' | 'button'; + /** + * Extra props to pass to the EuiButtonIcon containing the arrow. + */ + arrowProps?: 'iconType' | 'onClick' | 'aria-labelledby'; /** * Class that will apply to the trigger content for the accordion. */ @@ -54,6 +68,8 @@ type AccordionArgs = { * Choose whether the loading message replaces the content. Customize the message by passing a node */ isLoadingMessage?: boolean | Component; + + isOpen?: boolean; }; export default class EuiAccordionAccordionComponent extends Component { @@ -66,8 +82,6 @@ export default class EuiAccordionAccordionComponent extends Component
-

+ Accordion with forceState -

+ The accordion is {{this.accordionState}}
@@ -39,12 +39,12 @@ The accordion is
-

+ Accordion with isLoading = true -

+ <:buttonContent> "You spin my head right round" @@ -62,12 +62,12 @@ The accordion is
-

+ Accordion with - arrowDisplay = left + arrowDisplay = right -

+ <:buttonContent> Clickable Title @@ -76,8 +76,41 @@ The accordion is My content +
+ + + Accordion with + + arrowDisplay = left + + + + <:buttonContent> + Clickable Title + + <:content> + My content + + +
+ + + Accordion with + + arrowDisplay = none + + + + <:buttonContent> + Clickable Title + + <:content> + My content + + +
-

Nested accordions

+Nested accordions <:buttonContent> Parent accordion From 1bbb552b46a0254e6a89867abd377680dfcb31f4 Mon Sep 17 00:00:00 2001 From: betocantu93 Date: Mon, 28 Mar 2022 20:07:48 -0600 Subject: [PATCH 2/4] fixes and updates --- .../addon/components/eui-accordion/index.hbs | 190 +++++++++--------- .../addon/components/eui-accordion/index.ts | 56 +++--- .../core/docs/layout/accordion-demo/demo1.md | 46 +++-- 3 files changed, 157 insertions(+), 135 deletions(-) diff --git a/packages/core/addon/components/eui-accordion/index.hbs b/packages/core/addon/components/eui-accordion/index.hbs index 6cf65808..7166a4e4 100644 --- a/packages/core/addon/components/eui-accordion/index.hbs +++ b/packages/core/addon/components/eui-accordion/index.hbs @@ -1,101 +1,109 @@ -
-
- {{#if this.hasArrowDisplay}} - - {{/if}} - - {{#if (and @extraAction (not this.isLoading))}} -
- {{@extraAction}} -
- {{else if this.isLoading}} -
- -
- {{/if}} - {{#if this.hasIconButton}} - - {{/if}} -
-
+ {{/if}} +
- {{#if (and this.isLoading this.isLoadingMessage)}} - - - {{#if this.hasLoadingMessage}} - {{this.isLoadingMessage}} - {{else}} - {{! }} - Loading... - {{/if}} - - {{else}} - {{yield to="content"}} - {{/if}} +
+ {{#if (and this.isLoading this.isLoadingMessage)}} + + + {{#if this.hasLoadingMessage}} + {{this.isLoadingMessage}} + {{else}} + {{! }} + Loading... + {{/if}} + + {{else}} + {{yield to="content"}} + {{/if}} +
-
- \ No newline at end of file + +{{/let}} \ No newline at end of file diff --git a/packages/core/addon/components/eui-accordion/index.ts b/packages/core/addon/components/eui-accordion/index.ts index baec1b83..d0b2f0ad 100644 --- a/packages/core/addon/components/eui-accordion/index.ts +++ b/packages/core/addon/components/eui-accordion/index.ts @@ -81,6 +81,8 @@ export default class EuiAccordionAccordionComponent extends Component { - return this.isOpen ? '' : htmlSafe(`height: 0px;`); + return this._opened ? '' : htmlSafe(`height: 0px;`); } + setChildContentHeight = () => { + const { forceState } = this.args; + requestAnimationFrame(() => { + const height = + this.childContent && (forceState ? forceState === 'open' : this._opened) + ? this.childContent.clientHeight + : 0; + this.childWrapper && + this.childWrapper.setAttribute('style', `height: ${height}px`); + }); + }; + @action onToggle(): void { if (this.args.forceState) { - this.args.onToggle && - this.args.onToggle(this.args.forceState === 'open' ? false : true); + this.args.onToggle?.(this.args.forceState === 'open' ? false : true); } else { this._opened = !this._opened; - this.args.onToggle && this.args.onToggle(this._opened); + if (this._opened && this.childWrapper) { + this.childWrapper.focus(); + } + this.args.onToggle?.(this._opened); } } } diff --git a/packages/core/docs/layout/accordion-demo/demo1.md b/packages/core/docs/layout/accordion-demo/demo1.md index ae1749a0..b8eeab05 100644 --- a/packages/core/docs/layout/accordion-demo/demo1.md +++ b/packages/core/docs/layout/accordion-demo/demo1.md @@ -8,7 +8,7 @@

- + Accordion with forceState @@ -17,18 +17,24 @@ The accordion is {{this.accordionState}}
- - + + + + Open + + + + + Close + + + <:buttonContent> @@ -39,7 +45,7 @@ The accordion is
- + Accordion with isLoading = true @@ -53,7 +59,7 @@ The accordion is My content - + <:buttonContent> You spin my head right round also in content @@ -62,13 +68,13 @@ The accordion is
- + Accordion with arrowDisplay = right - + <:buttonContent> Clickable Title @@ -78,13 +84,13 @@ The accordion is
- + Accordion with arrowDisplay = left - + <:buttonContent> Clickable Title @@ -94,13 +100,13 @@ The accordion is
- + Accordion with arrowDisplay = none - + <:buttonContent> Clickable Title @@ -110,7 +116,7 @@ The accordion is
-Nested accordions +Nested accordions <:buttonContent> Parent accordion @@ -142,6 +148,6 @@ import Component from '@glimmer/component'; import { tracked } from '@glimmer/tracking'; export default class AccordionDemo1Component extends Component { - @tracked accordionState = false; + @tracked accordionState = false; } ``` From 1223a560a489b042bd08592bc590524e4e19da39 Mon Sep 17 00:00:00 2001 From: betocantu93 Date: Mon, 28 Mar 2022 20:09:28 -0600 Subject: [PATCH 3/4] execute on did insert --- packages/core/addon/components/eui-accordion/index.hbs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/core/addon/components/eui-accordion/index.hbs b/packages/core/addon/components/eui-accordion/index.hbs index 7166a4e4..257c0e25 100644 --- a/packages/core/addon/components/eui-accordion/index.hbs +++ b/packages/core/addon/components/eui-accordion/index.hbs @@ -87,7 +87,9 @@ (if this.isLoading "euiAccordion__children-isLoading") @childClassName }} - {{did-insert (set this "childContent")}} + {{did-insert + (queue (set this "childContent") this.setChildContentHeight) + }} {{resize-observer onResize=this.setChildContentHeight}} > {{#if (and this.isLoading this.isLoadingMessage)}} From 76dc49afbdca1eae37ca722121ca22aa5e2cb5ce Mon Sep 17 00:00:00 2001 From: Diego Date: Tue, 29 Mar 2022 15:22:07 -0600 Subject: [PATCH 4/4] accordion docs --- .../addon/components/eui-accordion/index.hbs | 12 +- .../core/docs/layout/accordion-demo/demo1.md | 189 ++++-------------- .../core/docs/layout/accordion-demo/demo10.md | 113 +++++++++++ .../core/docs/layout/accordion-demo/demo2.md | 31 +++ .../core/docs/layout/accordion-demo/demo3.md | 77 +++++++ .../core/docs/layout/accordion-demo/demo4.md | 27 +++ .../core/docs/layout/accordion-demo/demo5.md | 28 +++ .../core/docs/layout/accordion-demo/demo6.md | 67 +++++++ .../core/docs/layout/accordion-demo/demo7.md | 80 ++++++++ .../core/docs/layout/accordion-demo/demo8.md | 68 +++++++ .../core/docs/layout/accordion-demo/demo9.md | 63 ++++++ 11 files changed, 602 insertions(+), 153 deletions(-) create mode 100644 packages/core/docs/layout/accordion-demo/demo10.md create mode 100644 packages/core/docs/layout/accordion-demo/demo2.md create mode 100644 packages/core/docs/layout/accordion-demo/demo3.md create mode 100644 packages/core/docs/layout/accordion-demo/demo4.md create mode 100644 packages/core/docs/layout/accordion-demo/demo5.md create mode 100644 packages/core/docs/layout/accordion-demo/demo6.md create mode 100644 packages/core/docs/layout/accordion-demo/demo7.md create mode 100644 packages/core/docs/layout/accordion-demo/demo8.md create mode 100644 packages/core/docs/layout/accordion-demo/demo9.md diff --git a/packages/core/addon/components/eui-accordion/index.hbs b/packages/core/addon/components/eui-accordion/index.hbs index 257c0e25..eafaf415 100644 --- a/packages/core/addon/components/eui-accordion/index.hbs +++ b/packages/core/addon/components/eui-accordion/index.hbs @@ -7,7 +7,6 @@ class={{class-names (if this.isOpen "euiAccordion-isOpen") componentName="EuiAccordion" - paddingSize=this.paddingSize }} ...attributes > @@ -15,7 +14,7 @@ {{#if (eq this._arrowDisplay "left")}} {{else}} - {{yield to="content"}} +
+ {{yield to="content"}} +
{{/if}} diff --git a/packages/core/docs/layout/accordion-demo/demo1.md b/packages/core/docs/layout/accordion-demo/demo1.md index b8eeab05..54ccfb5b 100644 --- a/packages/core/docs/layout/accordion-demo/demo1.md +++ b/packages/core/docs/layout/accordion-demo/demo1.md @@ -1,153 +1,42 @@ -```hbs template - - <:buttonContent> - Clickable title - - <:content> - My content - - -
- - Accordion with - - forceState - - -The accordion is -{{this.accordionState}} -
- - - - Open - - - - - Close - - - - - <:buttonContent> - Clickable title - - <:content> - My Content - - -
- - Accordion with - - isLoading = true - - - - <:buttonContent> - "You spin my head right round" - - <:content> - My content - - - - <:buttonContent> - You spin my head right round also in content - - <:content> - My content - - -
- - Accordion with - - arrowDisplay = right - - - - <:buttonContent> - Clickable Title - - <:content> - My content - - -
- - - Accordion with - - arrowDisplay = left - - - - <:buttonContent> - Clickable Title - - <:content> - My content - - -
+--- +order: 1 +--- - - Accordion with - - arrowDisplay = none - +```hbs template + + <:body> + + Take care when including flex group content within accordions
+ EuiFlexGroup's + negative margins can sometimes create scrollbars within + EuiAccordion + because of the overflow tricks used to hide content. If you run into this + issue make sure your paddingSize prop is large enough to account for the + gutterSize + of any nested flex groups. +
+ +
+ + + Simple and unstyled - - <:buttonContent> - Clickable Title - - <:content> - My content - - -
- -Nested accordions - - <:buttonContent> - Parent accordion - - <:content> - Parent content - - <:buttonContent> - Child accordion - - <:content> - Child content - - <:buttonContent> - Grandchild accordion - - <:content> - Grandchild content - - - - - - -``` - -```js component -import Component from '@glimmer/component'; -import { tracked } from '@glimmer/tracking'; - -export default class AccordionDemo1Component extends Component { - @tracked accordionState = false; -} + + + EuiAccordion + has been purposely designed with minimal styles, allowing you to visually + enhance it as needed (see the accordion form example). The only styling + enforced by EUI is the caret icon, which indicates to users that the item can + be opened.

+ A + buttonContent + prop defines the content of the clickable area. On click it will expose the + children and animate based on the height of those children.

+ For styling needs, classes can be individually applied with + className + (for the entire accordion), and + buttonClassName + (for the clickable area). +
+ ``` diff --git a/packages/core/docs/layout/accordion-demo/demo10.md b/packages/core/docs/layout/accordion-demo/demo10.md new file mode 100644 index 00000000..2eff97f6 --- /dev/null +++ b/packages/core/docs/layout/accordion-demo/demo10.md @@ -0,0 +1,113 @@ +--- +order: 10 +--- + +```hbs template + + Styled for forms + + + + Since accordions are unstyled by default, EUI also provides a few classes you + can add to parts of the EuiAccordion to give it more style, like when using + with forms. +
    +
  • .euiAccordionForm: Applied to the + className, adds top and bottom borders
  • +
  • .euiAccordionForm__button: Applied to the + buttonClassName, adds extra padding to the button for + better spacing
  • +
  • .euiAccordionForm__extraAction: Applied to the button + passed to + extraAction, will visually hide it until hover or focus
  • +
+ + We also recommend creating a fieldset/legend combination for better + accessibility and DOM structure by passing + element="fieldset". This will set the entire accordion as a + "fieldset" + and automatically change the buttonElement to a + "legend". +
+ + + <:buttonContent> + +
+ + + + + + + +

Webhook

+
+
+
+ + +

+ + Will send a POST request to www.example.com/some/path/ + +

+
+
+
+ + <:content> + + + + + + + + + + + + + + + + + + + + + + +
+``` + +```js component +import Component from '@glimmer/component'; +import { tracked } from '@glimmer/tracking'; +import { action } from '@ember/object'; + +export default class AccordionDemo8Component extends Component { + @action + onClick(e) { + e.stopPropagation(); + } +} +``` diff --git a/packages/core/docs/layout/accordion-demo/demo2.md b/packages/core/docs/layout/accordion-demo/demo2.md new file mode 100644 index 00000000..68d0c02c --- /dev/null +++ b/packages/core/docs/layout/accordion-demo/demo2.md @@ -0,0 +1,31 @@ +--- +order: 2 +--- + +```hbs template + + Arrow display + + + + The arrow helps indicate the current state of the accordion (open or not) and points to the main triggering button text. If you must hide or change the side in which the arrow appears, use arrowDisplay: 'right' or 'none' + + + + <:buttonContent> + This accordion has the arrow on the right + + <:content> + Any content inside of EuiAccordion will appear here. + + + + + <:buttonContent> + This one has it removed entirely + + <:content> + Any content inside of EuiAccordion will appear here. + + +``` diff --git a/packages/core/docs/layout/accordion-demo/demo3.md b/packages/core/docs/layout/accordion-demo/demo3.md new file mode 100644 index 00000000..3f963b95 --- /dev/null +++ b/packages/core/docs/layout/accordion-demo/demo3.md @@ -0,0 +1,77 @@ +--- +order: 3 +--- + +```hbs template + + Multiple accordions + + + + Use any number of + EuiAccordion + elements to visually display them as a group.

+ Due to the previously mentioned bare styles, it is recommended to place an + EuiSpacer + between accordion items. Padding within each accordion item can be applied via + the + paddingSize + prop. +
+ + + <:buttonContent> + An accordion with padding applied through props + + <:content> + +

The content inside can be of any height.

+

The content inside can be of any height.

+

The content inside can be of any height.

+
+ +
+ + + <:buttonContent> + A second accordion with padding and a very long title that should truncate + because of eui-textTruncate + + <:content> + +

The content inside can be of any height.

+

The content inside can be of any height.

+

The content inside can be of any height.

+

The content inside can be of any height.

+

The content inside can be of any height.

+

The content inside can be of any height.

+
+ +
+ + + <:buttonContent> + A third accordion with nested accordion + + <:content> + +

+ This content area will grow to accommodate when the accordion below + opens +

+
+ + <:buttonContent> + A fourth nested accordion + + <:content> + + Any content inside of + EuiAccordion + will appear here. + + + + +
+``` diff --git a/packages/core/docs/layout/accordion-demo/demo4.md b/packages/core/docs/layout/accordion-demo/demo4.md new file mode 100644 index 00000000..ac4e0a2e --- /dev/null +++ b/packages/core/docs/layout/accordion-demo/demo4.md @@ -0,0 +1,27 @@ +--- +order: 4 +--- + +```hbs template + + Extra actions + + + + Use the extraAction prop to pass an extra action displayed on the right of any accordion. Usually this is a delete or button, but can be anything. Note that this action is separate from the click state that expands the accordion. This is needed to make it accessible. + + + + <:buttonContent> + Click to open + + <:content> + + Opened content + + + <:extraAction> + Extra action! + + +``` \ No newline at end of file diff --git a/packages/core/docs/layout/accordion-demo/demo5.md b/packages/core/docs/layout/accordion-demo/demo5.md new file mode 100644 index 00000000..1e8ee477 --- /dev/null +++ b/packages/core/docs/layout/accordion-demo/demo5.md @@ -0,0 +1,28 @@ +--- +order: 5 +--- + +```hbs template + + Opened on initial render + + + + Use the + initialIsOpen + prop to open the accordion when first rendered. + + + + <:buttonContent> + I am opened by default. Click me to toggle close / open + + <:content> + + Any content inside of + EuiAccordion + will appear here. + + + +``` \ No newline at end of file diff --git a/packages/core/docs/layout/accordion-demo/demo6.md b/packages/core/docs/layout/accordion-demo/demo6.md new file mode 100644 index 00000000..5d1021c7 --- /dev/null +++ b/packages/core/docs/layout/accordion-demo/demo6.md @@ -0,0 +1,67 @@ +--- +order: 6 +--- + +```hbs template + + Controlling toggled state + + + + Typically, the open and closed state of + EuiAccordion + is maintained by the component's internal state. Though, you can manually + control it with: +
    +
  • forceState: Accepts either + 'open' + or + 'closed'.
  • +
  • onToggle: A callback function returning + true + if the accordion is open
  • +
+
+ + + + + Open + + + + + Close + + + + + + <:buttonContent> + I am a controlled accordion + + <:content> + + Any content inside of + EuiAccordion + will appear here. + + + +``` + +```js component +import Component from '@glimmer/component'; +import { tracked } from '@glimmer/tracking'; + +export default class AccordionDemo1Component extends Component { + @tracked accordionState = false; +} +``` diff --git a/packages/core/docs/layout/accordion-demo/demo7.md b/packages/core/docs/layout/accordion-demo/demo7.md new file mode 100644 index 00000000..2e5e9582 --- /dev/null +++ b/packages/core/docs/layout/accordion-demo/demo7.md @@ -0,0 +1,80 @@ +--- +order: 7 +--- + +```hbs template + + Loading state + + + + Use the + isLoading + prop when not all of the accordion's content is ready yet. When using + isLoading, the content of + extraAction + is replaced with a loading spinner.

+ Manage the content of the accordion using + isLoadingMessage. By default, it is set to + false + and the content will remain unaltered. Set it to + true + to show a default loading message or pass a node to show a custom loading + message. +
+ + + + + isLoadingMessage: + + + + + False + + + + + True + + + + + Custom + + + + + + <:buttonContent> + Accordion is loading, click to toggle + + <:content> + + Opened content + + + <:extraAction> + Extra action! + + +``` + +```js component +import Component from '@glimmer/component'; +import { tracked } from '@glimmer/tracking'; + +export default class AccordionDemo1Component extends Component { + @tracked isLoadingMessage = false; +} +``` diff --git a/packages/core/docs/layout/accordion-demo/demo8.md b/packages/core/docs/layout/accordion-demo/demo8.md new file mode 100644 index 00000000..36f767e1 --- /dev/null +++ b/packages/core/docs/layout/accordion-demo/demo8.md @@ -0,0 +1,68 @@ +--- +order: 8 +--- + +```hbs template + + When content changes dynamically + + + + If an accordion’s content changes height while the accordion is open, it will + resize dynamically. + + + + <:buttonContent> + Click me to toggle close / open + + <:content> + + Increase height to + {{add this.counter 1}} + items + + + Decrease height to + {{sub this.counter 1}} + items + + + +
    + {{#each (range 0 this.counter) as |row|}} +
  • Row {{row}}
  • + {{/each}} +
+
+ +
+``` + +```js component +import Component from '@glimmer/component'; +import { tracked } from '@glimmer/tracking'; +import { action } from '@ember/object'; + +export default class AccordionDemo8Component extends Component { + @tracked counter = 1; + + @action + incrementDecreaseRows(actionType) { + if (actionType == 'add') { + this.counter++; + } else { + this.counter--; + } + } +} +``` diff --git a/packages/core/docs/layout/accordion-demo/demo9.md b/packages/core/docs/layout/accordion-demo/demo9.md new file mode 100644 index 00000000..3400cbd8 --- /dev/null +++ b/packages/core/docs/layout/accordion-demo/demo9.md @@ -0,0 +1,63 @@ +--- +order: 9 +--- + +```hbs template + + Interactive content in the trigger + + + + Passing interactive content like links, buttons, or form elements as the + buttonContent, will cause issues with the wrapping button + element. To fix this, you can change this wrapping element to a div using + buttonElement="div".

+ + If you don't want the interactive content to trigger the accordion expansion, + you will have to apply + e.stopPropagation() + to your element manually. +
+ + + <:body> + + Accordions need a focusable button for accessibility, so changing the + element to anything other than a button will enforce the display of the + arrow. + + + + + + <:buttonContent> + + This is a nested link + + + <:content> + + Any content inside of + EuiAccordion + will appear here. + + + +``` + +```js component +import Component from '@glimmer/component'; +import { tracked } from '@glimmer/tracking'; +import { action } from '@ember/object'; + +export default class AccordionDemo8Component extends Component { + + @action + onClick(e) { + e.stopPropagation(); + } +} +```