Skip to content

Commit b1e69ee

Browse files
eyevanadiwanshikylebuch8starryeyez024
authored
feat: pfe-dropdown (#668)
* Create element * Undo accidental deletion * Add basic toggle feature * Dispatch custom event when item selected * Fix path to src code in test * Populate list options dynamically * Add named slots for toggle and list/items * Update reference to slot names * Update test with new template * Add aria-expanded dynamically * Add slot for toggle text and icon, in addition to initial aria roles & attributes * Implement menu btn a11y pattern * Create dropdown item sub component * Refactor/add accessbility * Pull list into shadow DOM * Add toggle icon * Add toggle styling * Add local vars for toggle * set tabindex to -1 to links and action container * set id for pfe-dropdown items * implement keyboard accessibility * add event listener for change event on action * set tabindexx to -1 for pfe-dropdown-item * fixx: merge conflict in pfelement.scss * fix: remove tabindex from li * feat: add clickoutside event handler * add: id to container * fixing merge conflict * Fix build errors * Fix formatting error in color map * Fix color map for real * Add vars for menu * Set box sizing on menu * Add vars for menu items * Remove comments from scss file * Add seperator styling * Add a11y role for seperator * Only select non-seperator items * Add disabled state a11y * Patch bug in items selector * Add disabled styles * Add disabled attr & style to dropdown * Apply previous formatting to _colors map * Inherit font-family * Remove tabindex logic from disabled state * Moving pfelement test where it belongs * Update markup in test file * Remove pfelement tests from dropdown suite * Add test cases to suite * Test toggle functionality * (chore): removed tabindex from dropdown item * (fix): fix tabindex for dropdown items * (feat): add outsideClickHandler * (feat): modify DOM if custom dropdown options are provided * (chore): add exaxmple for custom dropdown options * (fix): add a check for pfe-dropdown-item container and items * (chore): add test cases for custom dropdown and outside click handler * (chore): removed tofo item from index.html * fixing the separator misspelling * using emitEvent to broadcast the change event * Switch to pfe-item-type * Add JSON schema * Fix typos in test * Create intial storybook script * Add additional item examples to storybook * Add readme * Change condition since item will be null for separator * Add polyfill for closest * Add polyfil for matches * Add array includes polyfill * Use indexOf vs. includes * Use is_disabled vs. disabled (causing issues in IE11) * Use non-disabled example in readme * Select the next enabled item on toggle keypress * Close the dropdown on tab * Update elements/pfe-dropdown/src/pfe-dropdown.scss Co-authored-by: Kendall Totten <[email protected]> * Update elements/pfe-dropdown/src/pfe-dropdown.scss Co-authored-by: Kendall Totten <[email protected]> * Update elements/pfe-dropdown/src/pfe-dropdown.scss Co-authored-by: Kendall Totten <[email protected]> * (fix): Update CSS vars after review * Update elements/pfe-dropdown/src/pfe-dropdown-item.scss Co-authored-by: Kendall Totten <[email protected]> * Update elements/pfe-dropdown/src/pfe-dropdown-item.scss Co-authored-by: Kendall Totten <[email protected]> * (fix): Style updates from review * (feat): Add function to check if all items disabled * (fix): Refactor get next item function (accounts for direction & disabled) * (fix): If all disabled, toggle dropdown * (fix): Use new get next item function * (chore): Cleanup! :) * (fix): Not returning result/calling function correctly * (fix): Don't forget to open the dropdown * (fix): Apply focus to item's container * (fix): Apply hover state styles to active & focus too * (chore): Add all disabled example for testing * (fix): Use color var & refactor variables * (fix): Update variable name for disabled state * (chore): Create shared variables * Update elements/pfe-dropdown/src/_shared-assets.scss Co-authored-by: Kendall Totten <[email protected]> * Update elements/pfe-dropdown/src/_shared-assets.scss Co-authored-by: Kendall Totten <[email protected]> * Update elements/pfe-dropdown/src/pfe-dropdown-item.scss Co-authored-by: Kendall Totten <[email protected]> * Update elements/pfe-dropdown/src/pfe-dropdown-item.scss Co-authored-by: Kendall Totten <[email protected]> * Update elements/pfe-dropdown/src/pfe-dropdown-item.scss Co-authored-by: Kendall Totten <[email protected]> * Update elements/pfe-dropdown/src/pfe-dropdown-item.scss Co-authored-by: Kendall Totten <[email protected]> * Update elements/pfe-dropdown/src/pfe-dropdown.scss Co-authored-by: Kendall Totten <[email protected]> * fix: 🎨 revert change to feedback colors (red is reserved for critcal warnings) * fix: 🐛 fix typos in variables map * fix: 🐛 remove ids from dropdown containers No need for ids here...it's also problematic, as ids should be unique * fix: 🐛 interpolate the new crayon colors * Update elements/pfe-dropdown/src/pfe-dropdown-item.scss Co-authored-by: Kendall Totten <[email protected]> * feat: add cursor point & update disabled property name Co-authored-by: Diwanshi Pandey <[email protected]> Co-authored-by: Kyle Buchanan <[email protected]> Co-authored-by: Kendall Totten <[email protected]>
1 parent 7fe6014 commit b1e69ee

29 files changed

+1401
-5
lines changed

elements/pfe-dropdown/.babelrc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"presets": [["env", { "modules": false }]],
3+
"plugins": ["external-helpers"]
4+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# EditorConfig: http://EditorConfig.org
2+
3+
# Top-most EditorConfig file
4+
root = true
5+
6+
# Rules for JavaScript files:
7+
8+
[*.{js,py,json,sh,html}]
9+
# 4 space indentation
10+
indent_style = space
11+
indent_size = 2
12+
# No trailing spaces
13+
trim_trailing_whitespace = true
14+
# Unix-style newlines
15+
end_of_line = lf
16+
# Newline ending every file
17+
insert_final_newline = true

elements/pfe-dropdown/.npmignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules

elements/pfe-dropdown/.travis.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
language: node_js
2+
dist: trusty
3+
sudo: required
4+
addons:
5+
firefox: "latest"
6+
apt:
7+
sources:
8+
- google-chrome
9+
packages:
10+
- google-chrome-stable
11+
node_js: stable
12+
before_install:
13+
- npm install -g web-component-tester
14+
install:
15+
- npm install
16+
before_script:
17+
script:
18+
- xvfb-run npm run test

elements/pfe-dropdown/LICENSE.txt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Copyright 2020 Red Hat, Inc.
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy
4+
of this software and associated documentation files (the "Software"), to deal
5+
in the Software without restriction, including without limitation the rights
6+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
copies of the Software, and to permit persons to whom the Software is
8+
furnished to do so, subject to the following conditions:
9+
10+
The above copyright notice and this permission notice shall be included in
11+
all copies or substantial portions of the Software.
12+
13+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19+
SOFTWARE.

elements/pfe-dropdown/README.md

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
# PatternFly Element | Dropdown Element
2+
3+
This element will provide a dropdown menu of links and/or actions. It's comprised of one sub-component, `pfe-dropdown-item` , which denotes an item in the dropdown menu.
4+
5+
## Usage
6+
7+
``` html
8+
<pfe-dropdown pfe-label="Dropdown">
9+
<pfe-dropdown-item pfe-item-type="link">
10+
<a href="https://bit.ly/3b9wvWg">Link 1</a>
11+
</pfe-dropdown-item>
12+
<pfe-dropdown-item pfe-item-type="link">
13+
<a href="https://bit.ly/3b9wvWg">Link 2</a>
14+
</pfe-dropdown-item>
15+
<pfe-dropdown-item pfe-item-type="link" is_disabled>
16+
<a href="https://bit.ly/3b9wvWg">Link 2</a>
17+
</pfe-dropdown-item>
18+
<pfe-dropdown-item pfe-item-type="separator"></pfe-dropdown-item>
19+
<pfe-dropdown-item pfe-item-type="action">
20+
<button>Action 1</button>
21+
</pfe-dropdown-item>
22+
</pfe-dropdown>
23+
```
24+
25+
You can also provide a list of dropdown items dynamically:
26+
27+
``` js
28+
let dropdown = document.querySelector("pfe-dropdown");
29+
```
30+
31+
When pfe-dropdown is defined, via the `whenDefined` method. Pass an array of pfe-dropdown-item objects to `pfeDropdownOptions`.
32+
33+
``` js
34+
customElements.whenDefined("pfe-dropdown").then(function() {
35+
dropdown.pfeDropdownOptions = [
36+
{
37+
href: "https://bit.ly/3b9wvWg",
38+
text: "Link 1",
39+
type: "link",
40+
is_disabled: false
41+
},
42+
{
43+
href: "https://bit.ly/3b9wvWg",
44+
text: "Link 2",
45+
type: "link",
46+
is_disabled: false
47+
},
48+
{
49+
href: "https://bit.ly/3b9wvWg",
50+
text: "Link 3",
51+
type: "link",
52+
is_disabled: true
53+
},
54+
{
55+
type: "separator"
56+
},
57+
{
58+
text: "Action 1",
59+
type: "action",
60+
is_disabled: false
61+
},
62+
{
63+
text: "Action 2",
64+
type: "action",
65+
is_disabled: true
66+
}
67+
];
68+
});
69+
```
70+
71+
Or you can add individual dropdown items with the `addDropdownOptions` method. Pass an array of pfe-dropdown-item objects to `addDropdownOptions` .
72+
73+
``` js
74+
customElements.whenDefined("pfe-dropdown").then(function() {
75+
dropdown.addDropdownOptions(
76+
[{
77+
href: "https://bit.ly/3b9wvWg",
78+
text: "Link 4",
79+
type: "link",
80+
is_disabled: false
81+
}]
82+
);
83+
});
84+
```
85+
86+
## Slots
87+
88+
### Default slot
89+
90+
The default slot should contain at least one link or action `pfe-dropdown-item` .
91+
92+
## Attributes
93+
94+
### pfe-dropdown
95+
96+
* `pfe-label` : This is an optional attribute string that you can provide to describe your dropdown, which appears in the dropdown toggle.
97+
* `is_disabled` : This is an optional attribute that you can provide to disable your dropdown. Visually the dropdown will look disabled and mouse or keyboard events will have no impact on it.
98+
99+
### pfe-dropdown-item
100+
101+
* `pfe-item-type` : This is an optional attribute string that you should provide to indicate the type of dropdown item. This drives the appropriate assignment of accessibility attributes for each type of item.
102+
103+
- `link` : an HTML link
104+
- `action` : a button that triggers some sort of action
105+
- `separator` : a visual separator for items in the list
106+
107+
## API
108+
109+
### open
110+
Manually opens the dropdown menu.
111+
`document.querySelector("pfe-dropdown").open()` ;
112+
113+
### close
114+
115+
Manually closes the dropdown menu.
116+
`document.querySelector("pfe-dropdown").close()` ;
117+
118+
## Events
119+
120+
* `pfe-dropdown:change` : When an item is selected, this event is fired. It includes the inner text of the item that was selected.
121+
122+
## Test
123+
124+
npm run test
125+
126+
## Build
127+
128+
npm run build
129+
130+
## Demo
131+
132+
From the PFElements root directory, run:
133+
134+
npm start
135+
136+
## Code style
137+
138+
Dropdown (and all PFElements) use [Prettier][prettier] to auto-format JS and JSON. The style rules get applied when you commit a change. If you choose to, you can [integrate your editor][prettier-ed] with Prettier to have the style rules applied on every save.
139+
140+
[prettier]: https://github.com/prettier/prettier/
141+
[prettier-ed]: https://prettier.io/docs/en/editors.html
142+
[web-component-tester]: https://github.com/Polymer/web-component-tester
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8" />
5+
<title>PatternFly Element | pfe-dropdown Demo</title>
6+
7+
<noscript>
8+
<link
9+
href="../../pfelement/pfelement-noscript.min.css"
10+
rel="stylesheet"
11+
/>
12+
</noscript>
13+
14+
<!-- uncomment the es5-adapter if you're using the umd version -->
15+
<script src="https://cdnjs.cloudflare.com/ajax/libs/webcomponentsjs/2.2.10/custom-elements-es5-adapter.js"></script>
16+
<script src="https://cdnjs.cloudflare.com/ajax/libs/webcomponentsjs/2.2.10/webcomponents-bundle.js"></script>
17+
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.5/require.min.js"></script>
18+
<script>
19+
require(["../dist/pfe-dropdown.umd.js"]);
20+
</script>
21+
</head>
22+
<style>
23+
body {
24+
font-family: "Red Hat Text", Overpass, Helvetica, sans-serif;
25+
position: relative;
26+
}
27+
</style>
28+
29+
<body unresolved>
30+
<h1>&lt;pfe-dropdown&gt;</h1>
31+
32+
<h2>Expandable dropdown</h2>
33+
34+
<pfe-dropdown pfe-label="Dropdown">
35+
<pfe-dropdown-item pfe-item-type="link">
36+
<a href="https://bit.ly/3b9wvWg">Link 1</a>
37+
</pfe-dropdown-item>
38+
<pfe-dropdown-item pfe-item-type="link">
39+
<a href="https://bit.ly/3b9wvWg">Link 2</a>
40+
</pfe-dropdown-item>
41+
<pfe-dropdown-item pfe-item-type="link" is_disabled>
42+
<a href="https://bit.ly/3b9wvWg">Link 3</a>
43+
</pfe-dropdown-item>
44+
<pfe-dropdown-item pfe-item-type="separator"></pfe-dropdown-item>
45+
<pfe-dropdown-item pfe-item-type="action">
46+
<button>Action 1</button>
47+
</pfe-dropdown-item>
48+
<pfe-dropdown-item pfe-item-type="action" is_disabled>
49+
<button>Action 2</button>
50+
</pfe-dropdown-item>
51+
<pfe-dropdown-item pfe-item-type="link">
52+
<a href="https://bit.ly/3b9wvWg">Link 4</a>
53+
</pfe-dropdown-item>
54+
</pfe-dropdown>
55+
<p id="example-dropdown-1">Selected Action: <span id="example-action-1"></span></p>
56+
57+
<h2>Dropdown with custom dropdown options</h2>
58+
<pfe-dropdown pfe-label="Dropdown" id="dropdown-with-custom-options">
59+
</pfe-dropdown>
60+
<p id="example-dropdown-2">Selected Action: <span id="example-action-2"></span></p>
61+
62+
<h2>Disabled dropdown</h2>
63+
64+
<pfe-dropdown pfe-label="Disabled" is_disabled>
65+
<pfe-dropdown-item pfe-item-type="link">
66+
<a href="https://bit.ly/3b9wvWg">Link 1</a>
67+
</pfe-dropdown-item>
68+
<pfe-dropdown-item pfe-item-type="link">
69+
<a href="https://bit.ly/3b9wvWg">Link 2</a>
70+
</pfe-dropdown-item>
71+
<pfe-dropdown-item pfe-item-type="link" is_disabled>
72+
<a href="https://bit.ly/3b9wvWg">Link 2</a>
73+
</pfe-dropdown-item>
74+
<pfe-dropdown-item pfe-item-type="separator"></pfe-dropdown-item>
75+
<pfe-dropdown-item pfe-item-type="action">
76+
<button>Action 1</button>
77+
</pfe-dropdown-item>
78+
</pfe-dropdown>
79+
80+
<h2>Expandable dropdown with all disabled options</h2>
81+
82+
<pfe-dropdown pfe-label="Dropdown">
83+
<pfe-dropdown-item pfe-item-type="link" is_disabled>
84+
<a href="https://bit.ly/3b9wvWg">Link 1</a>
85+
</pfe-dropdown-item>
86+
<pfe-dropdown-item pfe-item-type="link" is_disabled>
87+
<a href="https://bit.ly/3b9wvWg">Link 2</a>
88+
</pfe-dropdown-item>
89+
<pfe-dropdown-item pfe-item-type="link" is_disabled>
90+
<a href="https://bit.ly/3b9wvWg">Link 3</a>
91+
</pfe-dropdown-item>
92+
</pfe-dropdown>
93+
94+
<script>
95+
let dropdown = document.querySelector("pfe-dropdown");
96+
document.querySelector("#example-dropdown-1").style.display = "none";
97+
dropdown.addEventListener("pfe-dropdown:change", function(event) {
98+
document.querySelector("#example-action-1").textContent =
99+
event.detail.action;
100+
document.querySelector("#example-dropdown-1").style.display = "block";
101+
});
102+
103+
let dropdownWithCustomOptions = document.querySelector("#dropdown-with-custom-options");
104+
customElements.whenDefined("pfe-dropdown").then(function() {
105+
// Default Options
106+
dropdownWithCustomOptions.pfeDropdownOptions = [
107+
{ href: "https://bit.ly/3b9wvWg", text: "Link 1", type: "link", is_disabled: false },
108+
{ href: "https://bit.ly/3b9wvWg", text: "Link 2", type: "link", is_disabled: false },
109+
{ href: "https://bit.ly/3b9wvWg", text: "Link 3", type: "link", is_disabled: true },
110+
{ type: "separator" },
111+
{ text: "Action 1", type: "action", is_disabled: false },
112+
{ text: "Action 2", type: "action", is_disabled: true }
113+
];
114+
// Options passed via addDropdownOptions() method
115+
dropdownWithCustomOptions.addDropdownOptions(
116+
[
117+
{ href: "https://bit.ly/3b9wvWg", text: "Link 4", type: "link", is_disabled: false }
118+
]
119+
);
120+
});
121+
document.querySelector("#example-dropdown-2").style.display = "none";
122+
dropdownWithCustomOptions.addEventListener("pfe-dropdown:change", function(event) {
123+
document.querySelector("#example-action-2").textContent =
124+
event.detail.action;
125+
document.querySelector("#example-dropdown-2").style.display = "block";
126+
});
127+
</script>
128+
</body>
129+
</html>

0 commit comments

Comments
 (0)