Skip to content

Commit 8e52f62

Browse files
nikkimkbennypowers
andauthored
fix(dropdown): trigger button should never be disabled (#2671)
* fix(dropdown): trigger button should never be disabled * fix(dropdown): made disabled content accessible by keyboard users * test(dropdown): updated tests for disabled dropdown * fix(dropdown): allow disabled menu to be visible * fix(dropdown): removed focus, active, and focer styles from disabled * fix(dropdown): disabled state available to SR * fix(dropdown): updated disabled css * fix(dropdown): updated disabled css * fix(dropdown): adds disabled context * fix(dropdown): updated disabled css * fix(dropdown): update elements/pf-dropdown/pf-dropdown.ts Co-authored-by: Benny Powers - עם ישראל חי! <[email protected]> * fix(dropdown): minimize public APIs * chore: fix commitlint comment script * docs(dropdown): changeset * style: whitespace and formatting * fix(dropdown): prevent clicks on disabled menu items from falling through * chore: fix wireit script order * fix(dropdown): remove aria from dropdown-item host * fix(button): show slotted icon * fix(dropdown)!: change `trigger` slot to `toggle`, etc - move disabled context to pf-dropdown element - use pfv4 css tokens - correct toggle styling for variants, in particular the layout * fix(dropdown): prevent default on disabled item * fix(dropdown): decruft menu's aria-disabled state is set on internals * style(button): import order * fix(dropdown): cursor for disabled link items --------- Co-authored-by: Benny Powers <[email protected]> Co-authored-by: Benny Powers - עם ישראל חי! <[email protected]>
1 parent 91c8c77 commit 8e52f62

24 files changed

+583
-194
lines changed

.changeset/cruel-taxes-accept.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@patternfly/elements": patch
3+
---
4+
`<pf-dropdown>`: ensure that dropdown menu contents are accessible to keyboard
5+
and screen-reader users even when the dropdown or its toggle is disabled.

.changeset/odd-swans-trade.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
"@patternfly/elements": patch
3+
---
4+
`<pf-button>`: show slotted icon when it is present

.changeset/pf-dropdown.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44

55
✨ Added `<pf-dropdown>`
66

7-
A **dropdown** presents a menu of actions or links in a constrained space that will trigger a process or navigate to a new location.
7+
A **dropdown** presents a menu of actions or links in a constrained space that
8+
will trigger a process or navigate to a new location.
89

910
```html
1011
<pf-dropdown>

docs/_includes/_nav.njk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
</a>
1717
</div>
1818
<pf-dropdown id="docs-versions-dropdown">
19-
<pf-button slot="trigger"
19+
<pf-button slot="toggle"
2020
variant="control"
2121
icon="caret-down"
2222
icon-set="fas">Versions</pf-button>

elements/pf-button/pf-button.css

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@
4747
pf-icon,
4848
::slotted(pf-icon) {
4949
color: currentcolor;
50+
padding-inline-start: var(--_button-icon-padding-inline-start);
51+
padding-inline-end: var(--_button-icon-padding-inline-end);
52+
vertical-align: var(--_button-icon-vertical-align);
5053
}
5154

5255
#button {
@@ -141,10 +144,6 @@ pf-icon,
141144
--pf-c-button--m-link--BackgroundColor: var(--pf-c-button--m-link--active--BackgroundColor, transparent);
142145
}
143146

144-
.hasIcon [part=icon] {
145-
cursor: pointer;
146-
}
147-
148147
.disabled,
149148
:host(:disabled),
150149
:host([danger]:disabled),
@@ -154,6 +153,7 @@ pf-icon,
154153
}
155154

156155
[part=icon] {
156+
--pf-icon--size: 16px;
157157
display: inline-flex;
158158
align-items: center;
159159
position: absolute;
@@ -165,6 +165,10 @@ pf-icon,
165165
}
166166
}
167167

168+
.hasIcon [part=icon] {
169+
cursor: pointer;
170+
}
171+
168172
.hasIcon #button {
169173
position: absolute;
170174
inset: 0;
@@ -209,7 +213,6 @@ pf-icon,
209213
}
210214

211215
.hasIcon:not(.plain) [part=icon] {
212-
--pf-icon--size: 16px;
213216
position: relative;
214217
}
215218

elements/pf-button/pf-button.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { ifDefined } from 'lit/directives/if-defined.js';
55
import { classMap } from 'lit/directives/class-map.js';
66

77
import { InternalsController } from '@patternfly/pfe-core/controllers/internals-controller.js';
8+
import { SlotController } from '@patternfly/pfe-core/controllers/slot-controller.js';
89

910
import '@patternfly/elements/pf-icon/pf-icon.js';
1011
import '@patternfly/elements/pf-spinner/pf-spinner.js';
@@ -219,6 +220,8 @@ export class PfButton extends LitElement {
219220

220221
#internals = InternalsController.of(this, { role: 'button' });
221222

223+
#slots = new SlotController(this, 'icon', null);
224+
222225
get #disabled() {
223226
return this.disabled || this.#internals.formDisabled;
224227
}
@@ -236,7 +239,7 @@ export class PfButton extends LitElement {
236239
}
237240

238241
protected override render() {
239-
const hasIcon = !!this.icon || !!this.loading;
242+
const hasIcon = !!this.icon || !!this.loading || this.#slots.hasSlotted('icon');
240243
const { warning, variant, danger, loading, plain, inline, block, size } = this;
241244
const disabled = this.#disabled;
242245
return html`

elements/pf-dropdown/README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
# Dropdown
22

3-
A dropdown presents a menu of actions or links in a constrained space that will trigger a process or navigate to a new location.
3+
A dropdown presents a menu of actions or links in a constrained space that will
4+
trigger a process or navigate to a new location.
45

5-
Read more about dropdown in the [PatternFly Elements Dropdown documentation](https://patternflyelements.org/components/dropdown)
6+
Read more about dropdown in the [PatternFly Elements Dropdown
7+
documentation](https://patternflyelements.org/components/dropdown)
68

79
## Installation
810

@@ -41,4 +43,4 @@ import '@patternfly/elements/pf-dropdown/pf-dropdown.js';
4143
<pf-dropdown-item >item2</pf-dropdown-item>
4244
</pf-dropdown-group>
4345
</pf-dropdown>
44-
```
46+
```

elements/pf-dropdown/context.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { createContextWithRoot } from '@patternfly/pfe-core/functions/context.js';
2+
3+
export interface PfDropdownContext {
4+
disabled: boolean;
5+
}
6+
7+
export const context =
8+
createContextWithRoot<PfDropdownContext >(Symbol('pf-dropdown-menu-context'));
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
<p>
2+
<small>
3+
<em>Note:</em> When using a custom toggle, you must slot in a <code>pf-dropdown-menu</code>.
4+
</small>
5+
<span id="switch-group">
6+
<pf-switch id="disable-all"></pf-switch>
7+
<label for="disable-all"><span data-state="on">Enable</span><span data-state="off">Disable</span> all dropdowns</label>
8+
</span>
9+
</p>
10+
11+
<pf-dropdown id="control">
12+
<pf-button variant="control" slot="toggle">
13+
Control toggle
14+
<pf-icon size="md" icon="caret-down"></pf-icon>
15+
</pf-button>
16+
<pf-dropdown-menu slot="menu">
17+
<pf-dropdown-item>item4</pf-dropdown-item>
18+
<hr>
19+
<pf-dropdown-group label="Group 1">
20+
<pf-dropdown-item>item1</pf-dropdown-item>
21+
<pf-dropdown-item>item2</pf-dropdown-item>
22+
<hr>
23+
<pf-dropdown-item>item3</pf-dropdown-item>
24+
</pf-dropdown-group>
25+
<pf-dropdown-group label="Group 2">
26+
<pf-dropdown-item>item1</pf-dropdown-item>
27+
<pf-dropdown-item>item2</pf-dropdown-item>
28+
<pf-dropdown-item>item3</pf-dropdown-item>
29+
<pf-dropdown-item disabled>disabled</pf-dropdown-item>
30+
</pf-dropdown-group>
31+
</pf-dropdown-menu>
32+
</pf-dropdown>
33+
34+
<pf-dropdown id="primary">
35+
<pf-button variant="primary" slot="toggle">Primary toggle</pf-button>
36+
<pf-dropdown-menu slot="menu">
37+
<pf-dropdown-item>item4</pf-dropdown-item>
38+
<hr>
39+
<pf-dropdown-group label="Group 1">
40+
<pf-dropdown-item>item1</pf-dropdown-item>
41+
<pf-dropdown-item>item2</pf-dropdown-item>
42+
<hr>
43+
<pf-dropdown-item>item3</pf-dropdown-item>
44+
</pf-dropdown-group>
45+
<pf-dropdown-group label="Group 2">
46+
<pf-dropdown-item>item1</pf-dropdown-item>
47+
<pf-dropdown-item>item2</pf-dropdown-item>
48+
<pf-dropdown-item>item3</pf-dropdown-item>
49+
<pf-dropdown-item disabled>disabled</pf-dropdown-item>
50+
</pf-dropdown-group>
51+
</pf-dropdown-menu>
52+
</pf-dropdown>
53+
54+
<pf-dropdown id="secondary">
55+
<pf-button variant="secondary" slot="toggle">Secondary toggle</pf-button>
56+
<pf-dropdown-menu slot="menu">
57+
<pf-dropdown-item>item4</pf-dropdown-item>
58+
<hr>
59+
<pf-dropdown-group label="Group 1">
60+
<pf-dropdown-item>item1</pf-dropdown-item>
61+
<pf-dropdown-item>item2</pf-dropdown-item>
62+
<hr>
63+
<pf-dropdown-item>item3</pf-dropdown-item>
64+
</pf-dropdown-group>
65+
<pf-dropdown-group label="Group 2">
66+
<pf-dropdown-item>item1</pf-dropdown-item>
67+
<pf-dropdown-item>item2</pf-dropdown-item>
68+
<pf-dropdown-item>item3</pf-dropdown-item>
69+
<pf-dropdown-item disabled>disabled</pf-dropdown-item>
70+
</pf-dropdown-group>
71+
</pf-dropdown-menu>
72+
</pf-dropdown>
73+
74+
<pf-dropdown id="plain">
75+
<pf-button plain slot="toggle">Plain toggle</pf-button>
76+
<pf-dropdown-menu slot="menu">
77+
<pf-dropdown-item>item4</pf-dropdown-item>
78+
<hr>
79+
<pf-dropdown-group label="Group 1">
80+
<pf-dropdown-item>item1</pf-dropdown-item>
81+
<pf-dropdown-item>item2</pf-dropdown-item>
82+
<hr>
83+
<pf-dropdown-item>item3</pf-dropdown-item>
84+
</pf-dropdown-group>
85+
<pf-dropdown-group label="Group 2">
86+
<pf-dropdown-item>item1</pf-dropdown-item>
87+
<pf-dropdown-item>item2</pf-dropdown-item>
88+
<pf-dropdown-item>item3</pf-dropdown-item>
89+
<pf-dropdown-item disabled>disabled</pf-dropdown-item>
90+
</pf-dropdown-group>
91+
</pf-dropdown-menu>
92+
</pf-dropdown>
93+
94+
<pf-dropdown id="icon">
95+
<pf-button plain slot="toggle" icon="ellipsis-v" label="Icon toggle"></pf-button>
96+
<pf-dropdown-menu slot="menu">
97+
<pf-dropdown-item>item4</pf-dropdown-item>
98+
<hr>
99+
<pf-dropdown-group label="Group 1">
100+
<pf-dropdown-item>item1</pf-dropdown-item>
101+
<pf-dropdown-item>item2</pf-dropdown-item>
102+
<hr>
103+
<pf-dropdown-item>item3</pf-dropdown-item>
104+
</pf-dropdown-group>
105+
<pf-dropdown-group label="Group 2">
106+
<pf-dropdown-item>item1</pf-dropdown-item>
107+
<pf-dropdown-item>item2</pf-dropdown-item>
108+
<pf-dropdown-item>item3</pf-dropdown-item>
109+
<pf-dropdown-item disabled>disabled</pf-dropdown-item>
110+
</pf-dropdown-group>
111+
</pf-dropdown-menu>
112+
</pf-dropdown>
113+
114+
<script type="module">
115+
import '@patternfly/elements/pf-dropdown/pf-dropdown.js';
116+
import '@patternfly/elements/pf-switch/pf-switch.js';
117+
const sw = document.getElementById('disable-all')
118+
sw.addEventListener('click', function() {
119+
document.querySelectorAll('main pf-dropdown').forEach(x => x.disabled = sw.checked);
120+
})
121+
</script>
122+
123+
124+
<style>
125+
#switch-group {
126+
display: inline-flex;
127+
justify-content: center;
128+
vertical-align: middle;
129+
gap: 8px;
130+
}
131+
</style>

elements/pf-dropdown/demo/custom-trigger.html

Lines changed: 0 additions & 30 deletions
This file was deleted.

0 commit comments

Comments
 (0)