open-consul/ui/packages/consul-ui/app/components/disclosure-menu
Michael Klein f58fca2048
ui: upgrade ember composable helper (#13394)
Upgrade ember-composable-helpers to version 5.x. This version contains the pick-helper which makes composition in the template layer easier with Octane.

{{!-- this is usually hard to do with Octane --}}
<input {{on "input" (pick "target.value" this.updateText)}} .../>
Version 5.x also fixes a regression with sort-by that according to @johncowen was the reason why the version was pinned to 4.0.0 at the moment.

Version 5 of ember-composable-helpers removes the contains-helper in favor of includes which I changed all occurences for.
2022-06-08 16:07:51 +01:00
..
action ui: Disclosure Component amends plus DisclosureMenu Component (#12304) 2022-02-11 14:11:16 +00:00
menu ui: upgrade ember composable helper (#13394) 2022-06-08 16:07:51 +01:00
index.hbs ui: PagedCollection component (#12404) 2022-02-25 10:01:08 +00:00
index.scss ui: PagedCollection component (#12404) 2022-02-25 10:01:08 +00:00
README.mdx ui: PagedCollection component (#12404) 2022-02-25 10:01:08 +00:00

# DisclosureMenu

A component to be used for making dropup/down/left/right menus i.e. Disclosure
Menus. Please see both Disclosure and Menu components for more details.

The component does not make any guesses around whether you want the panel to
be on another DOM layer/absolutely positioned so you should apply that layout
yourself, but it's root node is relatively positioned to help for the fairly
common usecase of having a floating menu.

```hbs preview-template
<figure>
  <figcaption>
    Non-floating Menu
  </figcaption>
  <DisclosureMenu as |disclosure|>
    <disclosure.Action
      {{on 'click' disclosure.toggle}}
    >
      {{if disclosure.expanded 'Close' 'Open'}}
    </disclosure.Action>
    <disclosure.Menu as |panel|>
      <panel.Menu as |menu|>
        <menu.Item>
          <menu.Action>Item 1</menu.Action>
        </menu.Item>
        <menu.Item>
          <menu.Action>Item 2</menu.Action>
        </menu.Item>
      </panel.Menu>
    </disclosure.Menu>
  </DisclosureMenu>
</figure>
<figure>
  <figcaption>
    Floating Menu
  </figcaption>
  <DisclosureMenu as |disclosure|>
    <disclosure.Action
      {{on 'click' disclosure.toggle}}
    >
      {{if disclosure.expanded 'Close' 'Open'}}
    </disclosure.Action>
    <disclosure.Menu
      style={{style-map
        (array 'position' 'absolute')
        (array 'background-color' 'rgb(var(--tone-gray-000))')
      }}
    as |panel|>
      <panel.Menu as |menu|>
        <menu.Item>
          <menu.Action>Item 1</menu.Action>
        </menu.Item>
        <menu.Item>
          <menu.Action>Item 2</menu.Action>
        </menu.Item>
      </panel.Menu>
    </disclosure.Menu>
  </DisclosureMenu>
</figure>
```

`DisclosureMenu` also supports virtually scrolling its menu items for when you have 1000s of items to display in the menu whilst avoiding DOM stuttering. The set up is a tinsy bit more involved. but eesnetially you provide the data items for the menu using the `@items` argument, and then you can loop through these in the menu to make/use your menu items. The `menu.items` property is automatically paged for you depending on the scroll position of the menu panel. Importantly, right now, you should provide a height value for each menu.item using the `--paged-row-height` CSS property, you can do this inline or within your CSS (preferred). If you don't do this the component is unable to calculate the size of the scroll track/thumb. In the future (when needed) we will provide a callback for each item so you can specify a function to calculate the size of each individual item to give us a little more flexibility on what we can do with this component.

```hbs preview-template
<DataSource
  @src={{uri
  '/${partition}/${nspace}/${dc}/nodes'
    (hash
      nspace=''
      partition=''
      dc='dc-1'
    )
  }}
as |source|>
  <DisclosureMenu
    @items={{source.data}}
  as |disclosure|>
    <disclosure.Action
      {{on 'click' disclosure.toggle}}
    >
      {{if disclosure.expanded 'Close' 'Open'}}
    </disclosure.Action>
    <disclosure.Menu
      style={{style-map
        (array 'position' 'absolute')
        (array 'max-height' '360' 'px')
        (array 'width' '560' 'px')
        (array '--paged-row-height' '42px')
      }}
    as |panel|>
      <panel.Menu as |menu|>
        {{#each menu.items as |item|}}
          <menu.Item>
            <menu.Action>{{item.Node}}</menu.Action>
          </menu.Item>
        {{/each}}
      </panel.Menu>
    </disclosure.Menu>
  </DisclosureMenu>
</DataSource>
```

## Arguments

| Argument | Type | Default | Description |
| --- | --- | --- | --- |
| `expanded` | `Boolean` | false | The _initial_ state of the disclosure. Please note: this is the _initial_ state only, please use the `disclosure.open` and `disclosure.close` for controling the state. |
| `items` | `object[]` |  | When using a paginated menu you should add all possible items to this arguments and then uses the disclosure.Panel.Menu.items property for `each`ing through, see above example |

## Exported API

| Name | Type | Description |
| --- | --- | --- |
| `Action` | `GlimmerComponent` | A contextual '<Action />' component with aria attributes correctly applied, please note you still need to add an 'on' modifier here so you can control whether it opens on click/hover etc |
| `Menu` | `MenuComponent` | A contextual '<Menu />' component already wrapped in a disclosure.Details component |
| `toggle` | `Function` | Toggle the open/close state of the disclosure |
| `expanded` | `Boolean` | Whether the disclosure is 'expanded' or not |
| `disclosure` | `DisclosureComponentAPI` | A reference to the full DisclosureComponentAPI |


### menu.Action

An `<Action />` component with the correct aria attributes added.

### menu.Menu

A `<Menu />` component with the correct aria attributes added.

## See

- [Template Source Code](./index.hbs)

---