Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • adi-ia/enrollment-profile
  • SABERG3/enrollment-profile
2 results
Show changes
Commits on Source (35)
# myuw-profile versions
## 1.3.2
### Fixed
* Check for valid references before messing with DOM elements/variables
## 1.3.0
### Added
* Component listens for a CustomEvent called "myuw-login" and sets up its appearance accordingly. See the README usage guide.
## 1.2.2
### Added
* Polyfills included in demo page
### Fixed
* Fixed appearance in Firefox
## 1.2.1
### Changed
* Set standard top-bar button margin on containing element
* Removed left-only margin to better support usage outside of myuw-app-bar
* Add use of a CSS variable for menu link color (myuw-menu-color)
* Adjust circle button appearance to be centered better
* Add font weight CSS variable
\ No newline at end of file
...@@ -9,35 +9,78 @@ Add the following import to your page's `<head>`: ...@@ -9,35 +9,78 @@ Add the following import to your page's `<head>`:
<script nomodule src="https://unpkg.com/@myuw-web-components/myuw-profile@^1"></script> <script nomodule src="https://unpkg.com/@myuw-web-components/myuw-profile@^1"></script>
``` ```
*Note: You may want to specify a specific version of the component to ensure stability. See [the change log](CHANGELOG.md) or the [npm entry](https://www.npmjs.com/package/@myuw-web-components/myuw-profile) for version information.*
Use the component's HTML tag wherever you want: Use the component's HTML tag wherever you want:
```HTML ```HTML
<myuw-profile <myuw-profile
login-url="" login-url=""
logout-url="" logout-url=""
session-endpoint=""
background-color="" background-color=""
open-right
> >
</myuw-profile> </myuw-profile>
``` ```
#### Configurable properties
### Displaying the component
Because it has multiple states depending on whether there is an active session, all elements of the profile component are hidden by default. The component listens for a CustomEvent called "myuw-login" and its state is dependent on the data you pass when you dispatch that event:
```js
/*
Notes about configuring the event:
- The event MUST contain a "detail" object. The contents of the detail object determine what the component will display:
- An empty "detail" object ( detail: {} ) will result in the login button being displayed
- An empty "person" object ( person: {} ) will result in a generic session being displayed (using the person icon). This should only be used when the session doesn't provide a user's name, username, email, etc.
- A person object containing a "firstName" ( person: {firstName: "Name"} ) will result in the full session display
- The "bubbles" property is optional unless you're dispatching the event from an element/scope other than "document"
*/
var customEvent = new CustomEvent('myuw-login', {
bubbles: true, // optional
detail: { // required always
person: { // required for generic session display
"firstName": "User" // required for full session display
}
}
});
// Dispatch the event
document.dispatchEvent(customEvent);
```
#### Initial page load
If you want the component to show something on the initial page load (and not be hidden), make sure to dispatch the "myuw-login" event **after** all web components are loaded and upgraded (i.e. ready to be interacted with). The webcomponentsjs polyfill provides and event you can hook into:
```js
document.addEventListener('WebComponentsReady', function() {
var customEvent = new CustomEvent('myuw-login', {
// Configure the event data to display what you want
});
// Dispatch the event
document.dispatchEvent(customEvent);
});
```
### Configurable properties
- **Login URL (login-url):** The URL to redirect users to on login - **Login URL (login-url):** The URL to redirect users to on login
- **Logout URL (logout-url):** The Logout URL to redirect users to on logout - **Logout URL (logout-url):** The Logout URL to redirect users to on logout
- **Session Endpoint (session-endpoint):** The endpoint URL for session info
- **Background color (background-color):** Use this to dynamically set the background color of the profile menu button - **Background color (background-color):** Use this to dynamically set the background color of the profile menu button
- **Open Menu Right (open-right):** Include this attribute if you would like the profile menu to open to the right, instead of left
#### Slots ### Slots
- **Profile Navigation Item (nav-item):** Add a custom item to the profile button's navigation menu, this slot expects an `<a>` tag - **Profile Navigation Item (nav-item):** Add a custom item to the profile button's navigation menu, this slot expects an `<a>` tag
#### CSS Variables ### CSS Variables
- `--myuw-profile-font`: Set the font stack for this component - `--myuw-profile-font`: Set the font stack for this component
- `--myuw-profile-login-color`: Set the font color of the "Login" button - `--myuw-profile-login-color`: Set the font color of the "Login" button
- `--myuw-profile-background-color`: Set the background color of the circular menu button - `--myuw-profile-background-color`: Set the background color of the circular menu button
- `--myuw-menu-color`: The text color of links/buttons in the profile menu
For more information about CSS variables and how they work with MyUW Web Components, [reference the styles component](https://github.com/myuw-web-components/myuw-app-styles "reference the styles component") For more information about CSS variables and how they work with MyUW Web Components, [reference the styles component](https://github.com/myuw-web-components/myuw-app-styles "reference the styles component")
Cross-browser testing provided by:<br/>
<a href="https://www.browserstack.com/"><img width="160" src="https://myuw-web-components.github.io/img/Browserstack-logo.svg" alt="BrowserStack"/></a>
...@@ -48,6 +48,14 @@ ...@@ -48,6 +48,14 @@
cursor: pointer; cursor: pointer;
} }
</style> </style>
<script src="https://unpkg.com/css-vars-ponyfill@1"></script>
<script>
cssVars({shadowDOM: true,watch: true});
</script>
<!-- Web component polyfill loader -->
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@2.1.3/webcomponents-loader.js"></script>
<script type="module" src="https://unpkg.com/@myuw-web-components/myuw-app-styles@^1?module"></script> <script type="module" src="https://unpkg.com/@myuw-web-components/myuw-app-styles@^1?module"></script>
<script nomodule src="https://unpkg.com/@myuw-web-components/myuw-app-styles@^1"></script> <script nomodule src="https://unpkg.com/@myuw-web-components/myuw-app-styles@^1"></script>
...@@ -56,25 +64,22 @@ ...@@ -56,25 +64,22 @@
<script type="module" src="./dist/myuw-profile.mjs"></script> <script type="module" src="./dist/myuw-profile.mjs"></script>
<script nomodule src="./dist/myuw-profile.mjs"></script> <script nomodule src="./dist/myuw-profile.mjs"></script>
</head> </head>
<body> <body>
<!-- App bar with profile button --> <!-- App bar with profile button -->
<myuw-app-bar <myuw-app-bar
theme-name="MyUW" theme-name="MyUW"
theme-url=""
app-name="Profile Demo" app-name="Profile Demo"
app-url="" app-url=""
background="rgb(197, 5, 12)" background="rgb(197, 5, 12)"
color="white"> color="white">
<myuw-profile <myuw-profile
slot="myuw-profile" slot="myuw-profile"
login-url="https://wisc.edu/" login-url="https://wisc.edu/"
logout-url="https://wisc.edu/" logout-url="https://wisc.edu/">
session-endpoint="./test/session.json"> <a href="#" slot="nav-item">UW Madison Home</a>
<a href="#" slot="nav-item">UW Madison Home</a> <a href="#" slot="nav-item">STAR</a>
<a href="#" slot="nav-item">STAR</a> </myuw-profile>
</myuw-profile>
</myuw-app-bar> </myuw-app-bar>
<!-- Demo content --> <!-- Demo content -->
...@@ -88,47 +93,102 @@ ...@@ -88,47 +93,102 @@
<button aria-label="set profile button color" onclick="setColor(newColor.value)">Set profile color</button> <button aria-label="set profile button color" onclick="setColor(newColor.value)">Set profile color</button>
</div> </div>
<div class="demo-item"> <div class="demo-item">
<button aria-label="set no session" onclick="setSession('jargon')">No session</button> <button aria-label="set no session" onclick="logout()">No session</button>
</div> </div>
<div class="demo-item"> <div class="demo-item">
<button aria-label="restore demo session" onclick="setSession('./test/session.json')">Restore demo session</button> <button aria-label="restore demo session" onclick="setPortalSession()">Set portal session</button>
</div> </div>
<div class="demo-item"> <div class="demo-item">
<button aria-label="set missing session-endpoint" onclick="setSession(null)">Set missing session endpoint</button> <button aria-label="set a session without user info" onclick="setNonstandardSession()">Set session without person info</button>
</div>
<div class="demo-item">
<button aria-label="log in with other data" onclick="customLogin()">Set custom session</button>
</div> </div>
</div> </div>
<!-- Functions for demo content --> <!-- Functions for demo content -->
<script> <script>
// Add event listener to profile component
function customLogin(event) {
var customEvent = new CustomEvent('myuw-login', {
bubbles: true,
detail: {
person: {
"firstName": "Shibboleth"
}
}
});
document.dispatchEvent(customEvent);
};
function logout() {
var customEvent = new CustomEvent('myuw-login', {
bubbles: true,
detail: {
person: null
}
});
document.dispatchEvent(customEvent);
}
function setNonstandardSession() {
var customEvent = new CustomEvent('myuw-login', {
bubbles: true,
detail: {
person: {
"someOtherAttribute": "What is this"
}
}
});
document.dispatchEvent(customEvent);
}
function setPortalSession() {
fetch('./test/session.json')
.then(res => {
// Check if the request was valid
if(res.status === 200){
res.json()
.then( data => {
// If data.person is not set, return.
if(!data.person) { return; }
// Set user data to the component
var customEvent = new CustomEvent('myuw-login', {
bubbles: true,
detail: {
person: data.person
}
});
document.dispatchEvent(customEvent);
})
} else {
var customEvent = new CustomEvent('myuw-login', {
bubbles: true,
detail: {
person: null
}
});
document.dispatchEvent(customEvent);
}
})
.catch( e => {
var customEvent = new CustomEvent('myuw-login', {
bubbles: true,
detail: {
person: null
}
});
document.dispatchEvent(customEvent);
} );
}
function setColor(newColor) { function setColor(newColor) {
if (newColor.indexOf('#') < 0) { if (newColor.indexOf('#') < 0) {
newColor = '#' + newColor; newColor = '#' + newColor;
} }
document.getElementsByTagName('myuw-profile')[0].setAttribute('background-color', newColor); document.getElementsByTagName('myuw-profile')[0].setAttribute('background-color', newColor);
} }
function setSession(session) {
// Remove profile from DOM
document.getElementsByTagName('myuw-profile')[0].remove();
// Construct new profile template
var newProfileTemplate = document.createElement('myuw-profile');
newProfileTemplate.setAttribute('slot', 'myuw-profile');
newProfileTemplate.setAttribute('login-url', 'https://wisc.edu/');
newProfileTemplate.setAttribute('logout-url', 'https://wisc.edu/');
newProfileTemplate.setAttribute('color', '#fb686d');
newProfileTemplate.innerHTML = `
<a href="https://wisc.edu" slot="nav-item">UW Madison Home</a>
<a href="https://wisc.edu" slot="nav-item">STAR</a>
`;
if (session) {
newProfileTemplate.setAttribute('session-endpoint', session);
}
// Reinsert into DOM
document.getElementsByTagName('myuw-app-bar')[0].appendChild(newProfileTemplate);
}
</script> </script>
<!-- Accessibility tester -->
<script src="./node_modules/tota11y/build/tota11y.min.js"></script>
</body> </body>
</html> </html>
This diff is collapsed.
{ {
"name": "@myuw-web-components/myuw-profile", "name": "enrollment-profile",
"version": "1.1.0", "version": "1.3.1",
"description": "Web component that provides an avatar button and profile menu", "description": "Web component that provides an avatar button and profile menu",
"module": "dist/myuw-profile.min.mjs", "module": "dist/myuw-profile.min.mjs",
"browser": "dist/myuw-profile.min.js", "browser": "dist/myuw-profile.min.js",
"scripts": { "scripts": {
"build": "rollup -c", "build": "rollup -c",
"watch": "rollup -c -w", "watch": "rollup -c -w",
"serve": "live-server", "serve": "live-server --port=4200",
"start": "run-p watch serve", "start": "run-p watch serve",
"prepare": "npm run build", "prepare": "npm run build",
"pages": "mkdir -p demo && cp -r dist demo/dist && cp index.html demo/index.html && gh-pages -d demo", "pages": "rm -rf demo && mkdir -p demo && cp -r dist demo/ && cp -r test demo/ && cp index.html demo/ && gh-pages -d demo --repo git@github.com:myuw-web-components/myuw-profile.git",
"postpublish": "npm run pages" "postpublish": "npm run pages"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git+https://github.com/myuw-web-components/myuw-profile.git" "url": "git+https://git.doit.wisc.edu/adi-ia/enrollment-profile.git"
}, },
"author": "", "author": "",
"license": "Apache-2.0", "license": "Apache-2.0",
"bugs": {
"url": "https://github.com/myuw-web-components/myuw-profile/issues"
},
"homepage": "https://github.com/myuw-web-components/myuw-profile#readme",
"devDependencies": { "devDependencies": {
"rollup": "^0.63.4", "@babel/core": "^7.1.2",
"rollup-plugin-html": "^0.2.1", "@babel/preset-env": "^7.1.0",
"rollup-plugin-minify-es": "^1.1.1",
"gh-pages": "^1.2.0", "gh-pages": "^1.2.0",
"live-server": "^1.2.0", "live-server": "^1.2.0",
"npm-run-all": "^4.1.3", "npm-run-all": "^4.1.3",
"rollup": "^0.63.4",
"rollup-plugin-babel": "^4.0.3",
"rollup-plugin-html": "^0.2.1",
"rollup-plugin-minify-es": "^1.1.1",
"tota11y": "^0.1.6" "tota11y": "^0.1.6"
}, },
"files": [ "files": [
......
import { rollup } from 'rollup'; import { rollup } from 'rollup';
import html from 'rollup-plugin-html'; import html from 'rollup-plugin-html';
import minify from 'rollup-plugin-minify-es'; import minify from 'rollup-plugin-minify-es';
import babel from 'rollup-plugin-babel';
let fileName = 'myuw-profile'; let fileName = 'myuw-profile';
let objName = 'MyUWProfile'; let objName = 'MyUWProfile';
...@@ -38,7 +39,7 @@ let plugins = { ...@@ -38,7 +39,7 @@ let plugins = {
export default [ export default [
{ {
input: `src/${fileName}.js`, input: `src/${fileName}.js`,
plugins: plugins.full, plugins: plugins.full.concat([babel({exclude: 'node_modules/**'})]),
output: { output: {
file: `dist/${fileName}.js`, file: `dist/${fileName}.js`,
name: objName, name: objName,
...@@ -47,7 +48,7 @@ export default [ ...@@ -47,7 +48,7 @@ export default [
}, },
{ {
input: `src/${fileName}.js`, input: `src/${fileName}.js`,
plugins: plugins.min, plugins: plugins.min.concat([babel({exclude: 'node_modules/**'})]),
output: { output: {
file: `dist/${fileName}.min.js`, file: `dist/${fileName}.min.js`,
name: objName, name: objName,
......
{
"presets": [
["@babel/env", {
"modules": false
}]
],
}
<style> <style>
@import url(https://fonts.googleapis.com/icon?family=Material+Icons);
:host([hidden]) { :host([hidden]) {
display: none; display: none;
} }
...@@ -9,7 +11,7 @@ ...@@ -9,7 +11,7 @@
text-decoration: none; text-decoration: none;
color: var( --myuw-profile-login-color, var(--myuw-primary-color, white) ); color: var( --myuw-profile-login-color, var(--myuw-primary-color, white) );
padding: 10px 13px; padding: 10px 13px;
font-weight: bold; font-weight: var(--myuw-profile-font-weight, 600);
letter-spacing: 0px; letter-spacing: 0px;
font-size: 14px; font-size: 14px;
position: relative; position: relative;
...@@ -22,14 +24,16 @@ ...@@ -22,14 +24,16 @@
} }
#myuw-profile-circle { #myuw-profile-circle {
display: inline-block; display: flex;
justify-content: center;
align-items: center;
align-content: center;
align-self: center;
outline: none; outline: none;
border-radius: 50%; border-radius: 50%;
height: 42px; height: 42px;
width: 42px; width: 42px;
min-width: initial; min-width: initial;
margin-left: 8px;
padding: 4px;
text-transform: uppercase; text-transform: uppercase;
text-align: center; text-align: center;
background: transparent; background: transparent;
...@@ -44,30 +48,34 @@ ...@@ -44,30 +48,34 @@
} }
#myuw-profile-circle-initial { #myuw-profile-circle-initial {
display: flex;
justify-content: center;
align-items: center;
align-content: center;
align-self: center;
padding: 0; padding: 0;
margin: 0; margin: 0;
font-weight: 500; font-weight: var(--myuw-profile-font-weight, 300);
font-size: 18px; font-size: 18px;
font-family: var( --myuw-profile-font, var(--myuw-font, 'Montserrat', 'Roboto', Arial, sans-serif) ); font-family: var( --myuw-profile-font, var(--myuw-font, 'Roboto', Arial, sans-serif) );
background-color: var( --myuw-profile-background-color, #fb686d); background-color: var( --myuw-profile-background-color, #fb686d);
user-select: none; user-select: none;
color: white; color: white;
text-transform: capitalize; text-transform: capitalize;
border-radius: 50%; border-radius: 50%;
display: block;
margin: 0; margin: 0;
overflow: hidden; overflow: hidden;
position: relative; position: relative;
height: 33px; height: 34px;
width: 33px; width: 34px;
line-height: 33px; min-width: 34px;
font-size: 18px; font-size: 18px;
font-weight: 400;
} }
#myuw-profile-wrapper { #myuw-profile-wrapper {
position: relative; position: relative;
display: inline-block; display: inline-block;
margin: 0 6px;
} }
#myuw-profile-wrapper.hidden { #myuw-profile-wrapper.hidden {
...@@ -97,12 +105,6 @@ ...@@ -97,12 +105,6 @@
box-shadow: 0 2px 4px -1px rgba(0,0,0,0.2), 0 4px 5px 0 rgba(0,0,0,0.14), 0 1px 10px 0 rgba(0,0,0,0.12); box-shadow: 0 2px 4px -1px rgba(0,0,0,0.2), 0 4px 5px 0 rgba(0,0,0,0.14), 0 1px 10px 0 rgba(0,0,0,0.12);
} }
#myuw-profile-nav.open-right {
left: 0;
right: inherit;
transform-origin: top left;
}
#myuw-profile-nav.visible { #myuw-profile-nav.visible {
transform: scale(1); transform: scale(1);
opacity: 1; opacity: 1;
...@@ -114,35 +116,66 @@ ...@@ -114,35 +116,66 @@
margin: 0; margin: 0;
} }
#myuw-profile-nav a,
#myuw-profile-nav p,
::slotted(a), ::slotted(a),
::slotted(p) { ::slotted(p) {
transition: all .3s ease; transition: all .3s ease;
position: relative; position: relative;
font-size: 15px; font-size: 15px;
font-family: var( --myuw-profile-font, var(--myuw-font, 'Montserrat', 'Roboto', Arial, sans-serif) ); font-family: var( --myuw-profile-font, var(--myuw-font, 'Montserrat', 'Roboto', Arial, sans-serif) );
padding: 3px 16px; padding: 3px 16px;
color: rgba(0,0,0,0.87); color: var(--myuw-menu-color, rgba(0,0,0,0.87));
text-decoration: none; text-decoration: none;
background-color: #f5f5f5; background-color: #f5f5f5;
border-bottom: 1px solid #e5e5e5; border-bottom: 1px solid #e5e5e5;
user-select: none; user-select: none;
outline: none; outline: none;
display: flex; display: flex;
-webkit-box-orient: horizontal; -webkit-box-orient: horizontal;
-webkit-box-direction: normal; -webkit-box-direction: normal;
-webkit-flex-direction: row; -webkit-flex-direction: row;
flex-direction: row; flex-direction: row;
min-height: 48px; min-height: 48px;
height: 48px; height: 48px;
-webkit-align-content: center; -webkit-align-content: center;
align-content: center; align-content: center;
-webkit-align-items: center; -webkit-align-items: center;
align-items: center; align-items: center;
-webkit-box-pack: start; -webkit-box-pack: start;
-webkit-justify-content: flex-start; -webkit-justify-content: flex-start;
justify-content: flex-start; justify-content: flex-start;
}
/*
Styles need to be duplicated separate from ::slotted in order for
Firefox to do it's job
*/
#myuw-profile-nav a,
#myuw-profile-nav p {
transition: all .3s ease;
position: relative;
font-size: 15px;
font-family: var( --myuw-profile-font, var(--myuw-font, 'Montserrat', 'Roboto', Arial, sans-serif) );
padding: 3px 16px;
color: var(--myuw-menu-color, rgba(0,0,0,0.87));
text-decoration: none;
background-color: #f5f5f5;
border-bottom: 1px solid #e5e5e5;
user-select: none;
outline: none;
display: flex;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-webkit-flex-direction: row;
flex-direction: row;
min-height: 48px;
height: 48px;
-webkit-align-content: center;
align-content: center;
-webkit-align-items: center;
align-items: center;
-webkit-box-pack: start;
-webkit-justify-content: flex-start;
justify-content: flex-start;
} }
#myuw-profile-nav #myuw-profile-nav-user { #myuw-profile-nav #myuw-profile-nav-user {
...@@ -152,20 +185,27 @@ ...@@ -152,20 +185,27 @@
border-bottom: none; border-bottom: none;
} }
#myuw-profile-nav #myuw-profile-nav-user.hidden {
display: none;
}
#myuw-profile-nav #myuw-profile-nav-user:hover { #myuw-profile-nav #myuw-profile-nav-user:hover {
background-color: rgb(255,255,255); background-color: rgb(255,255,255);
} }
#myuw-profile-nav a:hover,
#myuw-profile-nav a:focus,
#myuw-profile-nav p:hover,
#myuw-profile-nav p:focus,
::slotted(a:hover), ::slotted(a:hover),
::slotted(a:focus), ::slotted(a:focus),
::slotted(p:hover), ::slotted(p:hover),
::slotted(p:focus) { ::slotted(p:focus) {
background-color: #ececec; background-color: #ececec;
} }
#myuw-profile-nav a:hover,
#myuw-profile-nav a:focus,
#myuw-profile-nav p:hover,
#myuw-profile-nav p:focus {
background-color: #ececec;
}
</style> </style>
<a href="#" id="myuw-profile-login" class="hidden">Login</a> <a href="#" id="myuw-profile-login" class="hidden">Login</a>
...@@ -176,7 +216,7 @@ ...@@ -176,7 +216,7 @@
aria-haspopup="true" aria-haspopup="true"
aria-controls="myuw-profile-nav" aria-controls="myuw-profile-nav"
aria-expanded="false"> aria-expanded="false">
<p id="myuw-profile-circle-initial">B</p> <p id="myuw-profile-circle-initial"><i class="material-icons">person</i></p>
</button> </button>
<ul id="myuw-profile-nav" <ul id="myuw-profile-nav"
......
...@@ -4,8 +4,6 @@ class MyUWProfile extends HTMLElement { ...@@ -4,8 +4,6 @@ class MyUWProfile extends HTMLElement {
constructor() { constructor() {
super(); super();
this['open-right'] = false;
// Create a shadowroot for this element // Create a shadowroot for this element
this.attachShadow({mode: 'open'}); this.attachShadow({mode: 'open'});
...@@ -17,60 +15,50 @@ class MyUWProfile extends HTMLElement { ...@@ -17,60 +15,50 @@ class MyUWProfile extends HTMLElement {
return [ return [
'login-url', 'login-url',
'logout-url', 'logout-url',
'open-right',
'background-color' 'background-color'
]; ];
} }
attributeChangedCallback(name, oldValue, newValue){ attributeChangedCallback(name, oldValue, newValue) {
if (typeof this.$circle !== 'undefined') {
// Update the attribute internally // Update the attribute internally
this[name] = newValue; this[name] = newValue;
// Update the component with new att value // Update the component with new att value
this.updateAttribute(name); this.updateAttribute(name);
}
} }
connectedCallback(){ connectedCallback(){
// Get all attributes // Get all attributes
this['login-url'] = this.getAttribute('login-url'); this['login-url'] = this.getAttribute('login-url');
this['logout-url'] = this.getAttribute('logout-url'); this['logout-url'] = this.getAttribute('logout-url');
this['session-endpoint'] = this.getAttribute('session-endpoint');
this['background-color'] = this.getAttribute('background-color'); this['background-color'] = this.getAttribute('background-color');
this['user'] = false;
if (this.getAttribute('open-right') !== null) {
this['open-right'] = true;
}
// If the session endpoint is set, fetch session info
if (this['session-endpoint']) {
fetch(this['session-endpoint'])
.then(res => {
// Check if the request was valid
if(res.status === 200){
res.json()
.then( data => {
// If data.person is not set, return.
if(!data.person){ return; }
// Set user data to the component
this.user = data.person;
this.componentReady();
})
} else {
this.componentReady();
}
})
.catch( e => {
console.log(e);
// Show login button if we couldn't get session info
this.componentReady();
} );
} else { this.$login = this.shadowRoot.getElementById('myuw-profile-login');
throw Error('No session endpoint has been defiend. Please set the "session-endpoint" attribute URL into the myuw-profile element!'); this.$logout = this.shadowRoot.getElementById('myuw-profile-logout');
} this.$button = this.shadowRoot.getElementById('myuw-profile-circle');
this.$circle = this.shadowRoot.getElementById('myuw-profile-circle-initial');
this.$nav = this.shadowRoot.getElementById('myuw-profile-nav');
this.$displayName = this.shadowRoot.getElementById('myuw-profile-nav-user');
this.$wrapper = this.shadowRoot.getElementById('myuw-profile-wrapper');
/**
* @typedef {Object} person
* @property {String} firstName
*/
/**
* Listen for custom event to receive session information
* @param {CustomEvent} event Event that should pass "person" information to display
*/
document.addEventListener('myuw-login', (event) => {
// Process data passed with event
if (event.detail.person) {
this.componentReady(event.detail.person);
} else {
this.componentReady();
}
}, false);
/* /*
Add an on click event to the window. Add an on click event to the window.
...@@ -78,11 +66,9 @@ class MyUWProfile extends HTMLElement { ...@@ -78,11 +66,9 @@ class MyUWProfile extends HTMLElement {
clicks anywhere but on the menu. clicks anywhere but on the menu.
*/ */
window.addEventListener('click', e => { window.addEventListener('click', e => {
let nav = this.shadowRoot.getElementById('myuw-profile-nav'); if (this.$nav.classList.contains('visible')) {
this.$nav.classList.remove('visible');
if (nav.classList.contains('visible')) { this.$button.setAttribute('aria-expanded', 'false');
nav.classList.remove('visible');
this.shadowRoot.getElementById('myuw-profile-circle').setAttribute('aria-expanded', 'false');
} }
}); });
...@@ -94,7 +80,7 @@ class MyUWProfile extends HTMLElement { ...@@ -94,7 +80,7 @@ class MyUWProfile extends HTMLElement {
If a user clicks on the nav menu, the window on click If a user clicks on the nav menu, the window on click
event will not fire, and it will not close the nav menu event will not fire, and it will not close the nav menu
*/ */
this.shadowRoot.getElementById('myuw-profile-nav').addEventListener('click', e => { this.$nav.addEventListener('click', e => {
e.stopPropagation(); e.stopPropagation();
}); });
...@@ -105,93 +91,82 @@ class MyUWProfile extends HTMLElement { ...@@ -105,93 +91,82 @@ class MyUWProfile extends HTMLElement {
this event or else the window on click will always fire this event or else the window on click will always fire
and the menu will never open. and the menu will never open.
*/ */
this.shadowRoot.getElementById('myuw-profile-circle').addEventListener('click', e => { this.$button.addEventListener('click', e => {
// Find menu button and the first nav list item
let nav = this.shadowRoot.getElementById('myuw-profile-nav');
let menuButton = this.shadowRoot.getElementById('myuw-profile-circle');
e.stopPropagation(); e.stopPropagation();
nav.classList.toggle('visible'); this.$nav.classList.toggle('visible');
// Focus the menu upon opening, blur on close // Focus the menu upon opening, blur on close
if (nav.classList.contains('visible')) { if (this.$nav.classList.contains('visible')) {
nav.focus(); this.$nav.focus();
menuButton.setAttribute('aria-expanded', 'true'); this.$button.setAttribute('aria-expanded', 'true');
} else { } else {
nav.blur(); this.$nav.blur();
menuButton.setAttribute('aria-expanded', 'false'); this.$button.setAttribute('aria-expanded', 'false');
} }
}); });
// this.componentReady();
// Update the component to use the new attributes // Update the component to use the new attributes
this.updateAttribute('login-url'); this.updateAttribute('login-url');
this.updateAttribute('logout-url'); this.updateAttribute('logout-url');
this.updateAttribute('session-endpoint');
this.updateAttribute('open-right');
this.updateAttribute('background-color'); this.updateAttribute('background-color');
} }
// Update the component with attribute values // Update the component with attribute values
updateAttribute(att) { updateAttribute(att) {
switch(att){ switch(att){
case 'login-url': case 'login-url':
this.shadowRoot.getElementById('myuw-profile-login').setAttribute('href', this['login-url']); this.shadowRoot.getElementById('myuw-profile-login').setAttribute('href', this['login-url']);
break; break;
case 'logout-url': case 'logout-url':
this.shadowRoot.getElementById('myuw-profile-logout').setAttribute('href', this['logout-url']); this.shadowRoot.getElementById('myuw-profile-logout').setAttribute('href', this['logout-url']);
break; break;
case 'open-right': case 'background-color':
if(this['open-right']){ this.$circle.style.backgroundColor = this['background-color'];
this.shadowRoot.getElementById('myuw-profile-nav').classList.add('open-right'); break;
} }
break;
case 'background-color':
this.shadowRoot.getElementById('myuw-profile-circle-initial').style.backgroundColor = this['background-color'];
break;
}
} }
/* /**
Function to run after the session endpoint * Runs after component detects the 'myuw-login' event and receives
has been hit and the component has all the * the required parameter
data that it needs to render. * @param {*} person
If user data was returned from the endpoint,
the profile bubble will show.
If not, the login button will show.
*/ */
componentReady() { componentReady(person) {
if (this.user) { if (person) {
// Add user's name to first menu item if (person.firstName) {
this.shadowRoot.getElementById('myuw-profile-nav-user').innerHTML = this.user.firstName; // Add user's name to first menu item
// Change the letter in the profile circle this.$displayName.classList.remove('hidden');
this.shadowRoot.getElementById('myuw-profile-circle-initial').innerHTML = this.user.firstName.substring(0,1); this.$displayName.innerHTML = person.firstName;
// Show the profile bubble // Change the letter in the profile circle
this.showProfileBubble(); this.$circle.innerHTML = person.firstName.substring(0,1);
// Show the profile bubble
this.showProfileBubble();
} else { } else {
if (this['login-url'] !== null) { this.$displayName.classList.add('hidden');
this.showLoginButton(); this.$circle.innerHTML = '<i class="material-icons">person</i>';
} else { this.showProfileBubble();
this.hidden = true;
}
} }
} else {
this.showLoginButton();
}
} }
showLoginButton() { showLoginButton() {
// Show Login Button // Show Login Button
this.shadowRoot.getElementById('myuw-profile-login').classList.remove('hidden'); this.$login.classList.remove('hidden');
// Hide profile Circle // Hide profile Circle
this.shadowRoot.getElementById('myuw-profile-wrapper').classList.add('hidden'); this.$wrapper.classList.add('hidden');
} }
showProfileBubble() { showProfileBubble() {
// Hide login button // Hide login button
this.shadowRoot.getElementById('myuw-profile-login').classList.add('hidden'); this.$login.classList.add('hidden');
// Show Profile circle // Show Profile circle
this.shadowRoot.getElementById('myuw-profile-wrapper').classList.remove('hidden'); this.$wrapper.classList.remove('hidden');
} }
} }
...@@ -200,4 +175,24 @@ MyUWProfile.template = (function template(src) { ...@@ -200,4 +175,24 @@ MyUWProfile.template = (function template(src) {
template.innerHTML = src; template.innerHTML = src;
return template; return template;
})(tpl); })(tpl);
/**
* Polyfill for supporting the CustomEvent constructor in IE9+
* From: https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent#Polyfill
*/
(function () {
if (typeof window.CustomEvent === 'function') {
return false;
}
function CustomEvent (event, params) {
params = params || { bubbles: false, cancelable: false, detail: undefined };
var evt = document.createEvent( 'CustomEvent' );
evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
return evt;
}
CustomEvent.prototype = window.Event.prototype;
window.CustomEvent = CustomEvent;
})();
window.customElements.define('myuw-profile', MyUWProfile); window.customElements.define('myuw-profile', MyUWProfile);