From b2c8b62ae8a1c46062a3e783dc82aaa6676fedb2 Mon Sep 17 00:00:00 2001 From: spelkey-ucd Date: Fri, 1 Oct 2021 17:04:10 -0400 Subject: [PATCH] #37 --- .../ucd-theme-header/ucd-theme-header.js | 29 ++--- .../ucd-theme-header/ucd-theme-header.tpl.js | 3 + elements/package.json | 2 +- elements/ucdlib/ucdlib-branding-bar/book.js | 4 + elements/ucdlib/ucdlib-branding-bar/logo.js | 67 ++++++++++++ .../ucdlib-branding-bar.js | 95 ++++++++++++++++ .../ucdlib-branding-bar.tpl.js | 102 ++++++++++++++++++ elements/utils/mutation-observer.js | 4 + elements/utils/nav-element.js | 5 +- test-app/index.js | 1 + test-app/pages/page-ucd-theme-header.js | 1 + test-app/pages/page-ucd-theme-header.tpl.js | 35 ++++-- test-app/pages/page-ucdlib-branding-bar.js | 30 ++++++ .../pages/page-ucdlib-branding-bar.tpl.js | 31 ++++++ test-app/pages/ucd-theme-slim-select.md | 2 +- test-app/pages/ucdlib-branding-bar.md | 20 ++++ test-app/ucdlib-theme-test-app.tpl.js | 1 + 17 files changed, 399 insertions(+), 33 deletions(-) create mode 100644 elements/ucdlib/ucdlib-branding-bar/book.js create mode 100644 elements/ucdlib/ucdlib-branding-bar/logo.js create mode 100644 elements/ucdlib/ucdlib-branding-bar/ucdlib-branding-bar.js create mode 100644 elements/ucdlib/ucdlib-branding-bar/ucdlib-branding-bar.tpl.js create mode 100644 test-app/pages/page-ucdlib-branding-bar.js create mode 100644 test-app/pages/page-ucdlib-branding-bar.tpl.js create mode 100644 test-app/pages/ucdlib-branding-bar.md diff --git a/elements/brand/ucd-theme-header/ucd-theme-header.js b/elements/brand/ucd-theme-header/ucd-theme-header.js index cb97716..1ea5d78 100644 --- a/elements/brand/ucd-theme-header/ucd-theme-header.js +++ b/elements/brand/ucd-theme-header/ucd-theme-header.js @@ -76,25 +76,6 @@ export default class UcdThemeHeader extends Mixin(LitElement) } - /** - * @method updated - * @description Lit lifecycle method called after element has updated. - * @param {Map} props - Properties updated in cycle - * @private - */ - updated( props ){ - - // Check if we're using the default branding div - const brandProps = ['siteName', 'slogan', 'figureSrc']; - if ( brandProps.map(p => props.has(p)).filter(Boolean).length ) { - if ( brandProps.map(p => this[p]).filter(Boolean).length ) { - this._hasSlottedBranding = false; - } else { - this._hasSlottedBranding = true; - } - } - } - /** * @method open * @description Opens header menu in mobile @@ -213,6 +194,16 @@ export default class UcdThemeHeader extends Mixin(LitElement) } else { this._hasSearch = false; } + + let UcdlibBrandingBar = this.querySelector('ucdlib-branding-bar'); + if ( UcdlibBrandingBar ) { + UcdlibBrandingBar.setAttribute('slot', 'branding-bar'); + this._hasSlottedBranding = true; + } else if ( this.querySelector("*[slot='branding-bar']") ){ + this._hasSlottedBranding = true; + } else { + this._hasSlottedBranding = false; + } } } diff --git a/elements/brand/ucd-theme-header/ucd-theme-header.tpl.js b/elements/brand/ucd-theme-header/ucd-theme-header.tpl.js index 4949810..c8c98c9 100644 --- a/elements/brand/ucd-theme-header/ucd-theme-header.tpl.js +++ b/elements/brand/ucd-theme-header/ucd-theme-header.tpl.js @@ -20,6 +20,9 @@ export function styles() { button { cursor: pointer; } + ::slotted(ucdlib-branding-bar){ + width: 100%; + } `; return [ diff --git a/elements/package.json b/elements/package.json index a404ef8..56351cf 100644 --- a/elements/package.json +++ b/elements/package.json @@ -1,6 +1,6 @@ { "name": "@ucd-lib/theme-elements", - "version": "0.0.3", + "version": "0.0.4", "description": "Custom elements for the UCD brand theme", "main": "index.js", "scripts": { diff --git a/elements/ucdlib/ucdlib-branding-bar/book.js b/elements/ucdlib/ucdlib-branding-bar/book.js new file mode 100644 index 0000000..935fa8a --- /dev/null +++ b/elements/ucdlib/ucdlib-branding-bar/book.js @@ -0,0 +1,4 @@ +import { svg } from "lit"; +export default svg` + +`; \ No newline at end of file diff --git a/elements/ucdlib/ucdlib-branding-bar/logo.js b/elements/ucdlib/ucdlib-branding-bar/logo.js new file mode 100644 index 0000000..3beb988 --- /dev/null +++ b/elements/ucdlib/ucdlib-branding-bar/logo.js @@ -0,0 +1,67 @@ +import { svg } from "lit"; +export default svg` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +`; \ No newline at end of file diff --git a/elements/ucdlib/ucdlib-branding-bar/ucdlib-branding-bar.js b/elements/ucdlib/ucdlib-branding-bar/ucdlib-branding-bar.js new file mode 100644 index 0000000..27a0b9a --- /dev/null +++ b/elements/ucdlib/ucdlib-branding-bar/ucdlib-branding-bar.js @@ -0,0 +1,95 @@ +import { LitElement, svg } from 'lit'; +import {render, styles} from "./ucdlib-branding-bar.tpl.js"; + +import {Mixin, MutationObserverElement, NavElement} from "../../utils"; +import logo from "./logo.js"; +import bookLogo from "./book.js"; + +/** + * @class UcdlibBrandingBar + * @classdesc Component class for displaying a Library branding bar in a header + * + * @property {String} figure - Figure to display: 'book' or 'logo' + * @property {String} siteName - Name of website to display + * @property {String} slogan - Optional text to display below site name + * @property {String} siteUrl - Url to use for links around site name and figure + * + * @examples + * + * My Account + * Access VPN + * Give + * + */ +export default class UcdlibBrandingBar extends Mixin(LitElement) + .with(NavElement, MutationObserverElement) { + + static get properties() { + return { + figure: {type: String}, + siteName: {type: String, attribute: "site-name"}, + slogan: {type: String}, + siteUrl: {type: String, attribute: "site-url"}, + navItems: {type: Array} + }; + } + + static get styles() { + return styles(); + } + + constructor() { + super(); + this.render = render.bind(this); + + this.figure = "book"; + this.siteName = "UC Davis Library"; + this.slogan = ""; + this.siteUrl = "/"; + this.navItems = []; + } + + /** + * @method willUpdate + * @description Lit lifecycle method called before an update + * @private + * @param {Map} props - Properties that have changed + */ + willUpdate(props){ + if ( props.has("figure") && props.get("figure") !== undefined ){ + const allowedKeywords = ['book', 'logo']; + if ( !allowedKeywords.includes(props.get('figure')) ){ + console.warn(`${props.get('figure')} is not a recognized "figure" keyword. + Allowed values: ${JSON.stringify(allowedKeywords)} + `); + this.figure = allowedKeywords[0]; + } + } + } + + /** + * @method _renderFigure + * @description Renders an svg logo + * @private + * @returns {TemplateResult} + */ + _renderFigure(){ + if ( this.figure === 'logo') return logo; + if ( this.figure === 'book' ) return bookLogo; + return svg``; + } + + /** + * @method _onChildListMutation + * @private + * @description Fires when light dom child list changes. Injected by MutationObserverElement mixin. + * Sets the 'navItems' property. + */ + _onChildListMutation(){ + let navItems = this.parseNavChildren(); + if ( navItems.length ) this.navItems = navItems; + } + +} + +customElements.define('ucdlib-branding-bar', UcdlibBrandingBar); \ No newline at end of file diff --git a/elements/ucdlib/ucdlib-branding-bar/ucdlib-branding-bar.tpl.js b/elements/ucdlib/ucdlib-branding-bar/ucdlib-branding-bar.tpl.js new file mode 100644 index 0000000..5607fc2 --- /dev/null +++ b/elements/ucdlib/ucdlib-branding-bar/ucdlib-branding-bar.tpl.js @@ -0,0 +1,102 @@ +import { html, css } from 'lit'; +import { ifDefined } from 'lit/directives/if-defined.js'; + +import headingStyles from "@ucd-lib/theme-sass/1_base_html/_headings.css.js"; +import linkStyles from "@ucd-lib/theme-sass/1_base_html/_links.css.js"; +import brandingStyles from "@ucd-lib/theme-sass/4_component/_site-branding.css.js" + + +export function styles() { + const elementStyles = css` + :host { + display: block; + } + .container { + display: flex; + flex-direction: row; + flex-wrap: nowrap; + align-items: center; + justify-content: space-between; + } + .site-branding__figure svg { + max-height: 6.25rem; + max-width: 100%; + height: auto; + } + .figure--book svg { + width: 70px; + min-width: 70px; + } + .figure--logo svg { + width: 375px; + min-width: 375px; + } + [hidden] { + display: none !important; + } + .figure--logo .site-branding__body { + display: none; + } + .menu { + display: flex; + flex-direction: row; + flex-wrap: nowrap; + align-items: center; + } + .menu a { + text-decoration: none; + font-weight: 700; + margin-right: 1rem; + } + .menu a:last-child { + margin-right: 0; + } + + @media (max-width: 992px) { + .figure--logo svg { + width: 200px; + min-width: 200px; + } + + .menu { + display: none; + } + } + + `; + + return [ + headingStyles, + brandingStyles, + linkStyles, + elementStyles]; +} + +export function render() { +return html` +
+
+ +
+

+ ${this.siteName} +

+
${this.slogan}
+
+
+ ${this.navItems.length ? html` + + ` : html``} + +
+ +`;} \ No newline at end of file diff --git a/elements/utils/mutation-observer.js b/elements/utils/mutation-observer.js index 9c8c3ab..f0b6e4a 100644 --- a/elements/utils/mutation-observer.js +++ b/elements/utils/mutation-observer.js @@ -42,6 +42,10 @@ const MutationObserverElement = (superClass) => class extends superClass { this._childListObserver.disconnect(); super.disconnectedCallback(); } + + _onChildListMutation(){ + console.warn("You must create a '_onChildListMutation' method in your element to use the MutationObserverElement mixin"); + } }; export {MutationObserverElement}; \ No newline at end of file diff --git a/elements/utils/nav-element.js b/elements/utils/nav-element.js index 7c5b81d..d19ce4b 100644 --- a/elements/utils/nav-element.js +++ b/elements/utils/nav-element.js @@ -34,7 +34,7 @@ const NavElement = (superClass) => class extends superClass { * @returns {Object} Formatted object describing the menu item and its children */ _makeNavItemTree(ele){ - let linkText, href, subItems = [], isOpen=false, inlineStyles={}; + let linkText, href, subItems = [], isOpen=false, inlineStyles={}, newTab=false; if ( ele.tagName === 'LI' && ele.children.length > 0) ele = ele.children[0]; if ( ele.tagName === 'A' ) { @@ -51,9 +51,10 @@ const NavElement = (superClass) => class extends superClass { if ( childItem.linkText ) subItems.push(childItem); } } + if (ele.getAttribute('target') == '_blank') newTab = true; if ( linkText ) linkText = linkText.trim(); - return {linkText, href, subItems, isOpen, inlineStyles}; + return {linkText, href, subItems, isOpen, inlineStyles, newTab}; } /** diff --git a/test-app/index.js b/test-app/index.js index 4ed1788..60bf414 100644 --- a/test-app/index.js +++ b/test-app/index.js @@ -23,3 +23,4 @@ import "./pages/page-ucdlib-icon"; import "./pages/page-ucdlib-icons"; import "./pages/page-ucdlib-iconset"; import "./pages/page-ucdlib-pages"; +import "./pages/page-ucdlib-branding-bar"; diff --git a/test-app/pages/page-ucd-theme-header.js b/test-app/pages/page-ucd-theme-header.js index 21cc5ea..199d2ef 100644 --- a/test-app/pages/page-ucd-theme-header.js +++ b/test-app/pages/page-ucd-theme-header.js @@ -9,6 +9,7 @@ import "../../elements/brand/ucd-theme-primary-nav/ucd-theme-primary-nav.js"; import "../../elements/brand/ucd-theme-quick-links/ucd-theme-quick-links.js"; import "../../elements/brand/ucd-theme-search-popup/ucd-theme-search-popup.js"; import "../../elements/brand/ucd-theme-search-form/ucd-theme-search-form.js"; +import "../../elements/ucdlib/ucdlib-branding-bar/ucdlib-branding-bar.js"; export default class PageUcdThemeHeader extends Mixin(LitElement) .with(MainDomElement, BrandedPageElement, MdElement) { diff --git a/test-app/pages/page-ucd-theme-header.tpl.js b/test-app/pages/page-ucd-theme-header.tpl.js index 88335e5..4e4bb77 100644 --- a/test-app/pages/page-ucd-theme-header.tpl.js +++ b/test-app/pages/page-ucd-theme-header.tpl.js @@ -66,17 +66,31 @@ return html` It should not be used otherwise. -

The branding bar can be completely overwritten with your own styles by using the branding-bar slot:

+

Customizing the Branding Bar

+

You can quickly apply Library styles by using the ucdlib-branding-bar component:

+ ${this.examplePanel(html` + + + My Account + Access VPN + Give + + + + Books + Magazines + Journals + + + + `)} + +

The branding bar can also be completely overwritten with your own styles by using the branding-bar slot:

${this.examplePanel(html`
- - +

No power in the 'verse can stop me

Books @@ -90,10 +104,11 @@ return html` width: 100%; display: flex; align-items: center; - justify-content: space-between; + justify-content: center; + background-color: black; } - .custom-branding img { - max-width: 15rem; + .custom-branding p { + color: yellow; } `)} diff --git a/test-app/pages/page-ucdlib-branding-bar.js b/test-app/pages/page-ucdlib-branding-bar.js new file mode 100644 index 0000000..ba60683 --- /dev/null +++ b/test-app/pages/page-ucdlib-branding-bar.js @@ -0,0 +1,30 @@ +import { LitElement } from 'lit'; +import {render, styles} from "./page-ucdlib-branding-bar.tpl.js"; + +import {Mixin, MainDomElement} from '../../elements/utils/index.js'; +import {BrandedPageElement, MdElement} from "../utils/index.js"; + +import "../../elements/ucdlib/ucdlib-branding-bar/ucdlib-branding-bar"; + + +export default class PageUcdlibBrandingBar extends Mixin(LitElement) + .with(MainDomElement, BrandedPageElement, MdElement) { + + static get properties() { + return { + + }; + } + + static get styles() { + return styles(); + } + + constructor() { + super(); + this.render = render.bind(this); + } + +} + +customElements.define('page-ucdlib-branding-bar', PageUcdlibBrandingBar); \ No newline at end of file diff --git a/test-app/pages/page-ucdlib-branding-bar.tpl.js b/test-app/pages/page-ucdlib-branding-bar.tpl.js new file mode 100644 index 0000000..c3bcbda --- /dev/null +++ b/test-app/pages/page-ucdlib-branding-bar.tpl.js @@ -0,0 +1,31 @@ +import { html, css } from 'lit'; + +export function styles() { + const elementStyles = css` + :host { + display: block; + } + `; + + return [elementStyles]; +} + +export function render() { +return html` + ${this.pageTitle("UC Davs Library Branding Bar")} + ${this.importPanel("ucdlib/ucdlib-branding-bar/ucdlib-branding-bar.js")} + +

The ucdlib-branding-bar component can be used in the header controller component + to quickly apply the Library's preferred styling to the masthead portion of the header. +

+ + ${this.examplePanel(html` + + My Account + Access VPN + Give + + `)} + + +`;} \ No newline at end of file diff --git a/test-app/pages/ucd-theme-slim-select.md b/test-app/pages/ucd-theme-slim-select.md index 931811c..ad323f7 100644 --- a/test-app/pages/ucd-theme-slim-select.md +++ b/test-app/pages/ucd-theme-slim-select.md @@ -1,7 +1,7 @@ ### UcdThemeSlimSelect -UI component class for displaying a fancy select. Wrapper element around the 'slim-select' package. +UI component class for displaying a fancy select. This is a wrapper element around the 'slim-select' package. Patternlab URL: - http://dev.webstyleguide.ucdavis.edu/redesign/?p=atoms-select-menu diff --git a/test-app/pages/ucdlib-branding-bar.md b/test-app/pages/ucdlib-branding-bar.md new file mode 100644 index 0000000..62e2ee1 --- /dev/null +++ b/test-app/pages/ucdlib-branding-bar.md @@ -0,0 +1,20 @@ + + +### UcdlibBrandingBar +Component class for displaying a Library branding bar in a header + +**Kind**: global class +**Examples**: + My Account + Access VPN + Give + +**Properties** + +| Name | Type | Description | +| --- | --- | --- | +| figure | String | Figure to display: 'book' or 'logo' | +| siteName | String | Name of website to display | +| slogan | String | Optional text to display below site name | +| siteUrl | String | Url to use for links around site name and figure | + diff --git a/test-app/ucdlib-theme-test-app.tpl.js b/test-app/ucdlib-theme-test-app.tpl.js index cb669bd..e41aa54 100644 --- a/test-app/ucdlib-theme-test-app.tpl.js +++ b/test-app/ucdlib-theme-test-app.tpl.js @@ -56,6 +56,7 @@ return html`
  • Search Popup
  • Search Form
  • Quick Links
  • +
  • UC Davis Library Branding Bar