coral-spectrum/coral-component-shell/src/scripts/ShellUser.js
/**
* Copyright 2019 Adobe. All rights reserved.
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. You may obtain a copy
* of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
* OF ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
import {BaseComponent} from '../../../coral-base-component';
import user from '../templates/user';
const CLASSNAME = '_coral-Shell-user';
/**
Enumeration for {@link ShellUser} avatar options. Avatar assets should use one of those provided, when no asset is set
@typedef {Object} ShellUserAvatarEnum
@property {String} DEFAULT
Default avatar, show user icon from icon font.
*/
const avatar = {
DEFAULT: 'UserCircleColor_Light'
};
/**
@class Coral.Shell.User
@classdesc A Shell User component
@htmltag coral-shell-user
@extends {HTMLElement}
@extends {BaseComponent}
*/
class ShellUser extends BaseComponent(HTMLElement) {
/** @ignore */
constructor() {
super();
// Prepare templates
this._elements = {
// Fetch or create the content zone elements
name: this.querySelector('coral-shell-user-name') || document.createElement('coral-shell-user-name'),
heading: this.querySelector('coral-shell-user-heading') || document.createElement('coral-shell-user-heading'),
subheading: this.querySelector('coral-shell-user-subheading') || document.createElement('coral-shell-user-subheading'),
content: this.querySelector('coral-shell-user-content') || document.createElement('coral-shell-user-content'),
footer: this.querySelector('coral-shell-user-footer') || document.createElement('coral-shell-user-footer')
};
user.call(this._elements, {icon: avatar.DEFAULT});
}
/**
Specifies the asset used inside the avatar view.
See {@link Icon} for valid usage and icon names.
@type {String}
@default ShellUserAvatarEnum.DEFAULT
@htmlattribute avatar
*/
get avatar() {
return this._elements.avatar.icon;
}
set avatar(value) {
this._elements.avatar.icon = value;
}
/**
The name content zone of the user-menu.
@type {ShellUserName}
@contentzone
*/
get name() {
return this._getContentZone(this._elements.name);
}
set name(value) {
this._setContentZone('content', value, {
handle: 'name',
tagName: 'coral-shell-user-name',
insert: function (content) {
this._elements.container.appendChild(content);
}
});
}
/**
The heading content zone of the user-menu.
@type {ShellUserHeading}
@contentzone
*/
get heading() {
return this._getContentZone(this._elements.heading);
}
set heading(value) {
this._setContentZone('heading', value, {
handle: 'heading',
tagName: 'coral-shell-user-heading',
insert: function (content) {
this._elements.container.appendChild(content);
}
});
}
/**
The subheading content zone of the user-menu.
@type {ShellUserSubheading}
@contentzone
*/
get subheading() {
return this._getContentZone(this._elements.subheading);
}
set subheading(value) {
this._setContentZone('subheading', value, {
handle: 'subheading',
tagName: 'coral-shell-user-subheading',
insert: function (content) {
this._elements.container.appendChild(content);
}
});
}
/**
The main content zone of the user-menu.
@type {ShellUserContent}
@contentzone
*/
get content() {
return this._getContentZone(this._elements.content);
}
set content(value) {
this._setContentZone('content', value, {
handle: 'content',
tagName: 'coral-shell-user-content',
insert: function (content) {
// Empty content to hide it
if (content.innerHTML.trim() === '') {
content.innerHTML = '';
}
this.appendChild(content);
}
});
}
/**
The footer content zone of the user-menu.
@type {ShellUserFooter}
@contentzone
*/
get footer() {
return this._getContentZone(this._elements.footer);
}
set footer(value) {
this._setContentZone('footer', value, {
handle: 'footer',
tagName: 'coral-shell-user-footer',
insert: function (content) {
this.appendChild(content);
}
});
}
get _contentZones() {
return {
'coral-shell-user-name': 'name',
'coral-shell-user-heading': 'heading',
'coral-shell-user-subheading': 'subheading',
'coral-shell-user-content': 'content',
'coral-shell-user-footer': 'footer'
};
}
/** @ignore */
static get observedAttributes() {
return super.observedAttributes.concat(['avatar']);
}
/**
Returns {@link ShellUser} avatar options.
@return {ShellUserAvatarEnum}
*/
static get avatar() {
return avatar;
}
/** @ignore */
render() {
super.render();
this.classList.add(CLASSNAME);
const frag = document.createDocumentFragment();
// Render template
frag.appendChild(this._elements.container);
for (const contentZone in this._contentZones) {
const element = this._elements[this._contentZones[contentZone]];
// Remove it so we can process children
if (element.parentNode) {
element.parentNode.removeChild(element);
}
}
while (this.firstChild) {
const child = this.firstChild;
if (child.nodeType === Node.TEXT_NODE ||
child.nodeType === Node.ELEMENT_NODE && child.getAttribute('handle') !== 'container') {
// Add non-template elements to the content
this._elements.content.appendChild(child);
} else {
// Remove anything else element
this.removeChild(child);
}
}
this.appendChild(frag);
// Assign the content zones so the insert functions will be called
for (const contentZone in this._contentZones) {
const contentZoneName = this._contentZones[contentZone];
const element = this._elements[this._contentZones[contentZone]];
/** @ignore */
this[contentZoneName] = element;
}
}
}
export default ShellUser;