Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(v-b-toggle): support specifying target ID via directive argument, and array of target IDs via directive value (closes #4834) #5336

Merged
merged 96 commits into from May 11, 2020
Merged
Show file tree
Hide file tree
Changes from 92 commits
Commits
Show all changes
96 commits
Select commit Hold shift + click to select a range
0d184bf
feat(v-b-toggle): support target as argument, and value as array of t…
tmorehouse May 9, 2020
782b214
Update target.js
tmorehouse May 9, 2020
11efa1a
Update toggle.spec.js
tmorehouse May 9, 2020
a53dbb9
Update target.js
tmorehouse May 9, 2020
2d49234
Update target.js
tmorehouse May 9, 2020
d7409eb
Only run handler if default not prevented
tmorehouse May 9, 2020
4557148
Update navbar-toggle.js
tmorehouse May 9, 2020
1a09ab4
Update navbar-toggle.js
tmorehouse May 9, 2020
12d5e94
Update package.json
tmorehouse May 9, 2020
14f1d6e
Update package.json
tmorehouse May 9, 2020
e9a905d
Update package.json
tmorehouse May 9, 2020
c21f261
Merge branch 'dev' into feat-toggle-targets
jacobmllr95 May 9, 2020
43e7809
Merge branch 'dev' into feat-toggle-targets
jacobmllr95 May 9, 2020
72a0a2c
Update target.js
tmorehouse May 9, 2020
f966d07
Update target.js
tmorehouse May 9, 2020
1354140
Update target.js
tmorehouse May 9, 2020
4a62f94
add class `not-collapsed` to trigger element when not collapsed
tmorehouse May 9, 2020
bde92c0
Update toggle.js
tmorehouse May 9, 2020
3552922
Update toggle.js
tmorehouse May 9, 2020
28447ed
Update toggle.spec.js
tmorehouse May 9, 2020
6e3c61f
Update toggle.js
tmorehouse May 9, 2020
a7a0ee7
Update toggle.spec.js
tmorehouse May 9, 2020
43c383a
Update toggle.spec.js
tmorehouse May 9, 2020
8f3306b
Update toggle.spec.js
tmorehouse May 10, 2020
7cfb681
Update toggle.js
tmorehouse May 10, 2020
534e90f
Update toggle.spec.js
tmorehouse May 10, 2020
fecef1e
Update toggle.spec.js
tmorehouse May 10, 2020
fe8868d
Update navbar-toggle.spec.js
tmorehouse May 10, 2020
bfdfeaa
Update toggle.js
tmorehouse May 10, 2020
aaf0993
Update toggle.js
tmorehouse May 10, 2020
5f8f4ea
Update README.md
tmorehouse May 10, 2020
0e847ef
Update README.md
tmorehouse May 10, 2020
2488f37
Update README.md
tmorehouse May 10, 2020
427310d
Update README.md
tmorehouse May 10, 2020
70da884
Update README.md
tmorehouse May 10, 2020
1c53d80
Update README.md
tmorehouse May 10, 2020
fbc1441
Update README.md
tmorehouse May 10, 2020
2683aee
Update target.js
tmorehouse May 10, 2020
92d6701
Update toggle.js
tmorehouse May 10, 2020
1c30343
Update README.md
tmorehouse May 10, 2020
75bfcee
Update README.md
tmorehouse May 10, 2020
002c6b1
Update target.js
tmorehouse May 10, 2020
a869643
Update target.js
tmorehouse May 10, 2020
d1d8d6a
Update target.js
tmorehouse May 10, 2020
7796e0e
Update target.js
tmorehouse May 10, 2020
bf2c59a
Update target.js
tmorehouse May 10, 2020
2eccec6
Update target.js
tmorehouse May 10, 2020
bb1686e
lint
tmorehouse May 10, 2020
11af90b
Update target.js
tmorehouse May 10, 2020
5fadd38
Update target.js
tmorehouse May 10, 2020
90a9c7c
Update toggle.spec.js
tmorehouse May 10, 2020
327ad12
Update target.js
tmorehouse May 10, 2020
e444102
Update README.md
jacobmllr95 May 10, 2020
63f734d
Update README.md
tmorehouse May 10, 2020
ec75471
Update README.md
jacobmllr95 May 10, 2020
99e6db7
Update README.md
jacobmllr95 May 10, 2020
530186b
Update README.md
jacobmllr95 May 10, 2020
d3f9de0
Update README.md
jacobmllr95 May 10, 2020
69e9377
Merge branch 'feat-toggle-targets' of https://github.com/bootstrap-vu…
jacobmllr95 May 10, 2020
32abb45
Update toggle.js
tmorehouse May 10, 2020
a19c28c
Update toggle.js
tmorehouse May 10, 2020
de1c0d2
Update toggle.js
jacobmllr95 May 10, 2020
47b375c
Delete target.js
jacobmllr95 May 10, 2020
f927547
Merge branch 'feat-toggle-targets' of https://github.com/bootstrap-vu…
jacobmllr95 May 10, 2020
4524a96
Update toggle.js
tmorehouse May 10, 2020
43d09ff
lint
tmorehouse May 10, 2020
bd11384
Update toggle.js
tmorehouse May 10, 2020
9e859d3
Update toggle.js
tmorehouse May 10, 2020
4077b5f
Update toggle.js
tmorehouse May 10, 2020
1f0315c
lint
tmorehouse May 10, 2020
f91878b
Update toggle.js
tmorehouse May 10, 2020
73fe658
Update toggle.js
tmorehouse May 10, 2020
29398a0
Update toggle.js
tmorehouse May 10, 2020
c3dc7e0
Update toggle.js
tmorehouse May 10, 2020
c23f1ee
Update toggle.js
tmorehouse May 10, 2020
1165bbe
Update toggle.js
tmorehouse May 10, 2020
6e72848
Update toggle.js
tmorehouse May 10, 2020
93dd781
Update toggle.js
tmorehouse May 10, 2020
8673b74
Merge branch 'dev' into feat-toggle-targets
tmorehouse May 10, 2020
89373a6
Update toggle.js
tmorehouse May 10, 2020
6874096
Update toggle.js
tmorehouse May 10, 2020
2514130
Update toggle.js
tmorehouse May 10, 2020
e7b4e2d
lint
tmorehouse May 10, 2020
3410c32
Update toggle.js
tmorehouse May 10, 2020
74c1b31
Update toggle.js
tmorehouse May 10, 2020
e7e6c23
Update toggle.js
tmorehouse May 10, 2020
1a4d9fb
Update toggle.spec.js
tmorehouse May 10, 2020
a6af713
Update toggle.spec.js
tmorehouse May 10, 2020
4322b11
Update toggle.spec.js
tmorehouse May 10, 2020
6fda136
Update toggle.js
tmorehouse May 10, 2020
687b1db
Update toggle.spec.js
tmorehouse May 10, 2020
d42b571
Update toggle.js
jacobmllr95 May 11, 2020
1bea3ec
Update toggle.js
tmorehouse May 11, 2020
a6ffcfa
Update toggle.spec.js
tmorehouse May 11, 2020
d2e4b91
Update toggle.spec.js
tmorehouse May 11, 2020
aa41484
Update toggle.spec.js
tmorehouse May 11, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
33 changes: 23 additions & 10 deletions src/components/collapse/README.md
@@ -1,7 +1,8 @@
# Collapse

> Easily toggle visibility of almost any content on your pages. Includes support for making
> accordions.
> Easily toggle visibility of almost any content on your pages in a vertically collapsing container.
> Includes support for making accordions. Visibility can be easily toggled with our
> [`v-b-toggle` directive](/docs/directives/toggle), or via `v-model`.

```html
<div>
Expand Down Expand Up @@ -42,6 +43,9 @@ Other elements can easily toggle `<b-collapse>` components using the
<!-- b-collapse-usage.vue -->
```

See the [`v-b-toggle` directive documentation](/docs/directives/toggle) for detailed usage
information.

## Initial visibility (start expanded)

To make the `<b-collapse>` show initially, set the `visible` prop:
Expand Down Expand Up @@ -104,12 +108,20 @@ support.
## Trigger multiple collapse elements

You can even collapse multiple `<b-collapse>` components via a single `v-b-toggle` by providing
multiple target IDs using modifiers:
multiple target IDs using _modifiers_.

You can also pass multiple target IDs via the directive _value_ in BootstrapVue release v2.14.0+.

```html
<div>
<!-- Single button triggers two "<b-collapse>" components -->
<b-button v-b-toggle.collapse-a.collapse-b>Toggle Both Collapse A and B</b-button>
<!-- Via multiple directive modifiers -->
<b-button v-b-toggle.collapse-a.collapse-b>Toggle Collapse A and B</b-button>

<!-- Via space separated string of IDs passed to directive value -->
<b-button v-b-toggle="'collapse-a collapse-b'">Toggle Collapse A and B</b-button>

<!-- Via array of string IDs passed to directive value -->
<b-button v-b-toggle="['collapse-a', 'collapse-b']">Toggle Collapse A and B</b-button>

<!-- Elements to collapse -->
<b-collapse id="collapse-a" class="mt-2">
Expand Down Expand Up @@ -205,14 +217,15 @@ at a time.

When using the `v-b-toggle` directive, the class `collapsed` will automatically be placed on the
trigger element when the collapse is closed, and removed when open. You can use this class to
display or hide content within the toggle via custom CSS:
display or hide content within the toggle via custom CSS. As of BootstrapVue 2.14.0, the class
`not-collapsed` will be applied when the target(s) are not closed.

**Example HTML markup:**

```html
<div>
<b-button v-b-toggle.my-collapse>
<span class="when-opened">Close</span> <span class="when-closed">Open</span> My Collapse
<b-button v-b-toggle:my-collapse>
<span class="when-open">Close</span><span class="when-closed">Open</span> My Collapse
</b-button>
<b-collapse id="my-collapse">
<!-- Content here -->
Expand All @@ -223,8 +236,8 @@ display or hide content within the toggle via custom CSS:
**Example Custom CSS:**

```css
.collapsed > .when-opened,
:not(.collapsed) > .when-closed {
.collapsed > .when-open,
.not-collapsed > .when-closed {
display: none;
}
```
Expand Down
5 changes: 5 additions & 0 deletions src/components/modal/package.json
Expand Up @@ -12,6 +12,11 @@
"directive": "VBModal",
"description": "Directive for opening a modal by ID",
"expression": "String",
"arg": {
"pattern": "[a-zA-Z][a-zA-Z0-9_\\-]*",
"description": "Modal ID to open",
"required": false
},
"modifiers": [
{
"name": "{modalId}",
Expand Down
14 changes: 12 additions & 2 deletions src/components/navbar/README.md
Expand Up @@ -281,6 +281,12 @@ will reverse the placement of the toggler.
See the first example on this page for reference, and also refer to
[`<b-collapse>`](/docs/components/collapse) for details on the collapse component.

Besides being used to control a collapse, the `<b-navbar-toggle>` can also be used to toggle
visibility of the [`<b-sidebar>`](/docs/components/sidebar) component. Just specify the ID of the
`<b-sidebar>` via the `target` prop.

Internally, `<b-navbar-toggle>` uses the [`v-b-toggle` directive](/docs/directives/toggle).

#### Custom navbar toggle

`<b-navbar-toggle>` renders the default Bootstrap v4 _hamburger_ (which is a background SVG image).
Expand Down Expand Up @@ -320,9 +326,13 @@ Navbars are hidden by default when printing. Force them to be printed by setting

## See also

- [`<b-collapse>` component](/docs/components/collapse)
- [`<b-sidebar>` component](/docs/components/sidebar)
- [`v-b-toggle` directive](/docs/directives/toggle)
- [`<b-nav>` documentation](/docs/components/nav) for additional components and sub-component
aliases

Refer to the [Router support](/docs/reference/router-links) reference page for router-link specific
props.

Also see [`<b-nav>`](/docs/components/nav) for additional components and sub-component aliases.

<!-- Component reference added automatically from component package.json -->
24 changes: 7 additions & 17 deletions src/components/navbar/navbar-toggle.js
@@ -1,15 +1,8 @@
import Vue from '../../utils/vue'
import { getComponentConfig } from '../../utils/config'
import { toString } from '../../utils/string'
import listenOnRootMixin from '../../mixins/listen-on-root'
import normalizeSlotMixin from '../../mixins/normalize-slot'
import { EVENT_TOGGLE, EVENT_STATE, EVENT_STATE_SYNC } from '../../directives/toggle/toggle'

// TODO:
// Switch to using `VBToggle` directive, will reduce code footprint
// Although the `click` event will no longer be cancellable
// Instead add `disabled` prop, and have `VBToggle` check element
// disabled state
import { VBToggle, EVENT_STATE, EVENT_STATE_SYNC } from '../../directives/toggle/toggle'

// --- Constants ---

Expand All @@ -20,6 +13,7 @@ const CLASS_NAME = 'navbar-toggler'
// @vue/component
export const BNavbarToggle = /*#__PURE__*/ Vue.extend({
name: NAME,
directives: { BToggle: VBToggle },
mixins: [listenOnRootMixin, normalizeSlotMixin],
props: {
label: {
Expand All @@ -42,12 +36,12 @@ export const BNavbarToggle = /*#__PURE__*/ Vue.extend({
},
methods: {
onClick(evt) {
// Emit courtesy `click` event
this.$emit('click', evt)
if (!evt.defaultPrevented) {
this.emitOnRoot(EVENT_TOGGLE, this.target)
}
},
handleStateEvt(id, state) {
// We listen for state events so that we can pass the
// boolean expanded state to the default scoped slot
if (id === this.target) {
this.toggleState = state
}
Expand All @@ -59,12 +53,8 @@ export const BNavbarToggle = /*#__PURE__*/ Vue.extend({
'button',
{
staticClass: CLASS_NAME,
attrs: {
type: 'button',
'aria-label': this.label,
'aria-controls': this.target,
'aria-expanded': toString(expanded)
},
directives: [{ name: 'BToggle', value: this.target }],
attrs: { type: 'button', 'aria-label': this.label },
on: { click: this.onClick }
},
[
Expand Down
4 changes: 3 additions & 1 deletion src/components/navbar/navbar-toggle.spec.js
Expand Up @@ -23,7 +23,9 @@ describe('navbar-toggle', () => {
})

expect(wrapper.classes()).toContain('navbar-toggler')
expect(wrapper.classes().length).toBe(1)
// Class added by v-b-toggle
expect(wrapper.classes()).toContain('collapsed')
expect(wrapper.classes().length).toBe(2)

wrapper.destroy()
})
Expand Down
10 changes: 6 additions & 4 deletions src/components/sidebar/README.md
Expand Up @@ -12,7 +12,8 @@ You can place almost any content inside the `<b-sidebar>`
[vertical navs](/docs/components/nav#vertical-variation).

The component supports a header and built in close button, of which you can optionally disable and
provide your own header (if needed), and can be easily toggled with our `v-b-toggle` directive.
provide your own header (if needed), and can be easily toggled with our
[`v-b-toggle` directive](/docs/directives/toggle).

The component has minimal default styling, which provides you with great flexibility in laying out
the content of the sidebar.
Expand Down Expand Up @@ -302,9 +303,9 @@ elements outside of the sidebar.

### `v-b-toggle` directive

Using the `v-b-toggle` directive is the preferred method for _opening_ the sidebar, as it
automatically handles applying the `aria-controls` and `aria-expanded` accessibility attributes on
the trigger element.
Using the [`v-b-toggle` directive](/docs/directive/toggle) is the preferred method for _opening_ the
sidebar, as it automatically handles applying the `aria-controls` and `aria-expanded` accessibility
attributes on the trigger element.

The majority of examples on this page use the `v-b-toggle` directive.

Expand Down Expand Up @@ -369,5 +370,6 @@ to the [theming documentation](/docs/reference/theming) for additional details.

## See also

- [`v-b-toggle` directive](/docs/directives/toggle)
- [`<b-collapse>` component](/docs/components/collapse)
- [`<b-button-close>` component](/docs/components/button#comp-ref-b-button-close)
78 changes: 60 additions & 18 deletions src/directives/toggle/README.md
@@ -1,7 +1,7 @@
# Toggle

> `v-b-toggle` is a light-weight directive for toggling the visibility of collapses and sidebars,
> and includes automated accessibility handling.
> and includes automated [WAI-ARIA accessibility](/docs/reference/accessibility) attribute handling.

## Overview

Expand All @@ -12,18 +12,27 @@ visibility state of the [`<b-collapse>`](/docs/components/collapse) and
Besides toggling the visibility of the target component, the directive automatically updates ARIA
accessibility attributes on the element it is applied to so that they reflect the visibility state
of the target component. Refer to the [Accessibility section](#accessibility) below for additional
details.
details and caveats.

## Directive syntax and usage

The directive is applied to the element or component that triggers the visibility of hte target. The
target component can be specified (via ID) as either a directive modifier(s) or as a string passed
to as the directive value:

- `v-b-toggle.my-collapse` - the directive modifier (multiple targets allowed)
- `v-b-toggle="'my-collapse'"` - the directive value (as a String, single target only)

Modifiers and the value can be used at the same time.
target component can be specified (via its ID) as either a directive modifier(s), the directive
argument, or as a string/array passed to as the directive value:

- `v-b-toggle.my-collapse` - the directive modifier (multiple targets allowed, each modifier is a
target ID)
- `v-b-toggle:my-collapse` - the directive argument
([Vue dynamic argument](https://vuejs.org/v2/guide/syntax.html#Dynamic-Arguments) is supported)
<span class="badge badge-info small" aria-label="Available in BootstrapVue v2.14.0+">v2.14.0+</span>
- `v-b-toggle="'my-collapse'"` - the directive value as a string ID
- `v-b-toggle="'my-collapse1 my-collapse2'"` - the directive value as a space separated string of
IDs
<span class="badge badge-info small" aria-label="Available in BootstrapVue v2.14.0+">v2.14.0+</span>
- `v-b-toggle="['my-collapse1', 'my-collapse2']"` - the directive value as an array of string IDs
<span class="badge badge-info small" aria-label="Available in BootstrapVue v2.14.0+">v2.14.0+</span>

Modifiers, argument, and the value can be used at the same time when targeting multiple components.

### Example usage

Expand Down Expand Up @@ -53,26 +62,59 @@ Modifiers and the value can be used at the same time.
<!-- v-b-toggle-directive.vue -->
```

## Hiding and showing content in the toggle trigger element

When using the `v-b-toggle` directive, the class `collapsed` will automatically be placed on the
trigger element when the target component is closed, and removed when open. As of BootstrapVue
`2.14.0`, the class `not-collapsed` will be applied when the target is _not_ closed.

**Example HTML markup:**

```html
<div>
<b-button v-b-toggle:my-collapse>
<span class="when-open">Close</span><span class="when-closed">Open</span> My Collapse
</b-button>
<b-collapse id="my-collapse">
<!-- Content here -->
</b-collapse>
</div>
```

**Example Custom CSS:**

```css
.collapsed > .when-open,
.not-collapsed > .when-closed {
display: none;
}
```

## Accessibility

The directive, for accessibility reasons, should be placed on an clickable interactive element such
as a `<button>` or `<b-button>`, which can easily be accessed by keyboard-only users and screen
reader users. Elements that do not natively have an accessibility role of `button` will have the
attributes `role="button"` and `tabindex="0"` applied, and will have the appropriate click and
keyboard handlers instantiated. Therefore it is _highly recommended_ to _not_ place the directive on
form controls other than buttons.
reader users. Elements that do not natively have an accessibility role of `button` (or `link`) will
have the attributes `role="button"` and `tabindex="0"` applied, and will have the appropriate click
handler instantiated. Therefore it is _highly recommended_ to _not_ place the directive on form
controls other than buttons.

The directive applies, and dynamically updates, the following ARIA attributes on the trigger
element:

- `aria-controls` - the ID of the collapse or sidebar component(s) being toggled
- `aria-expanded` - the visibility state of the collapse or sidebar
- `aria-controls` - the ID(s) of the collapse or sidebar component(s) being toggled
- `aria-expanded` - the visibility state of the collapse or sidebar (see the
[caveats section](#caveats-with-multiple-targets) below)

### Caveats with multiple targets

When the target component is _not_ expanded, the trigger element will have the class `collapsed`
applied. When the target component is expanded, the `collapsed` class will be removed from the
trigger element.
When multiple targets are specified, the value of the `aria-expanded` attribute may not be correct
if the individual target components can have their collapsed state controlled independently (either
via `v-model`, other controls with `v-b-toggle` directive, or CSS visibility).

## See also

- [`<b-collapse>`](/docs/components/collapse) Collapsible content with accordion support
- [`<b-sidebar>`](/docs/components/sidebar) Off-canvas sidebar
- [`<b-navbar-toggle>`](/docs/components/navbar#b-navbar-toggle-and-b-collapse-is-nav) Navbar
hamburger toggle button (based on `v-b-toggle` directive)
11 changes: 10 additions & 1 deletion src/directives/toggle/package.json
Expand Up @@ -5,7 +5,16 @@
"title": "Toggle",
"description": "A light-weight directive for toggling visibility state for collapses and sidebars by ID. It automatically handles the accessibility attributes on the trigger element.",
"directive": "VBToggle",
"expression": "String",
"expression": [
"String",
"Array"
],
"arg": {
"version": "2.14.0",
"pattern": "[a-zA-Z][a-zA-Z0-9_\\-]*",
"description": "ID of component to toggle",
"required": false
},
"modifiers": [
{
"name": "{componentId}",
Expand Down