@ucd-lib/theme-elements 0.0.1 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{ucd-theme-alert → brand/ucd-theme-alert}/ucd-theme-alert.js +0 -0
- package/{ucd-theme-alert → brand/ucd-theme-alert}/ucd-theme-alert.tpl.js +0 -0
- package/{ucd-theme-collapse → brand/ucd-theme-collapse}/ucd-theme-collapse.js +20 -21
- package/{ucd-theme-collapse → brand/ucd-theme-collapse}/ucd-theme-collapse.tpl.js +1 -1
- package/brand/ucd-theme-header/ucd-theme-header.js +268 -0
- package/brand/ucd-theme-header/ucd-theme-header.tpl.js +146 -0
- package/{ucd-theme-image-gallery → brand/ucd-theme-image-gallery}/ucd-theme-image-gallery.js +0 -0
- package/{ucd-theme-image-gallery → brand/ucd-theme-image-gallery}/ucd-theme-image-gallery.tpl.js +0 -0
- package/{ucd-theme-list-accordion → brand/ucd-theme-list-accordion}/ucd-theme-list-accordion.js +47 -44
- package/{ucd-theme-list-accordion → brand/ucd-theme-list-accordion}/ucd-theme-list-accordion.tpl.js +2 -2
- package/{ucd-theme-message-area → brand/ucd-theme-message-area}/ucd-theme-message-area.js +0 -0
- package/{ucd-theme-message-area → brand/ucd-theme-message-area}/ucd-theme-message-area.tpl.js +0 -0
- package/brand/ucd-theme-pagination/ucd-theme-pagination.js +284 -0
- package/brand/ucd-theme-pagination/ucd-theme-pagination.tpl.js +93 -0
- package/brand/ucd-theme-primary-nav/ucd-theme-primary-nav.js +589 -0
- package/brand/ucd-theme-primary-nav/ucd-theme-primary-nav.tpl.js +106 -0
- package/brand/ucd-theme-quick-links/ucd-theme-quick-links.js +269 -0
- package/brand/ucd-theme-quick-links/ucd-theme-quick-links.tpl.js +114 -0
- package/{ucd-theme-form-search/ucd-theme-form-search.js → brand/ucd-theme-search-form/ucd-theme-search-form.js} +14 -15
- package/{ucd-theme-form-search/ucd-theme-form-search.tpl.js → brand/ucd-theme-search-form/ucd-theme-search-form.tpl.js} +0 -0
- package/brand/ucd-theme-search-popup/ucd-theme-search-popup.js +91 -0
- package/{ucd-theme-header-search-popup/ucd-theme-header-search-popup.tpl.js → brand/ucd-theme-search-popup/ucd-theme-search-popup.tpl.js} +8 -1
- package/brand/ucd-theme-slim-select/ucd-theme-slim-select.js +58 -0
- package/brand/ucd-theme-slim-select/ucd-theme-slim-select.tpl.js +26 -0
- package/brand/ucd-theme-subnav/ucd-theme-subnav.js +196 -0
- package/brand/ucd-theme-subnav/ucd-theme-subnav.tpl.js +60 -0
- package/package.json +6 -4
- package/ucdlib/ucdlib-branding-bar/book.js +4 -0
- package/ucdlib/ucdlib-branding-bar/logo.js +67 -0
- package/ucdlib/ucdlib-branding-bar/ucdlib-branding-bar.js +101 -0
- package/ucdlib/ucdlib-branding-bar/ucdlib-branding-bar.tpl.js +102 -0
- package/ucdlib/ucdlib-icon/ucdlib-icon.js +138 -0
- package/ucdlib/ucdlib-icon/ucdlib-icon.tpl.js +22 -0
- package/ucdlib/ucdlib-icons/academic.js +154 -0
- package/ucdlib/ucdlib-icons/ucdlib-icons.js +78 -0
- package/ucdlib/ucdlib-icons/utils.js +29 -0
- package/ucdlib/ucdlib-iconset/ucdlib-iconset.js +170 -0
- package/ucdlib/ucdlib-pages/ucdlib-pages.js +150 -0
- package/utils/controllers/break-points.js +26 -0
- package/utils/controllers/index.js +11 -0
- package/utils/controllers/intersection-observer.js +58 -0
- package/utils/controllers/mutation-observer.js +52 -0
- package/utils/controllers/wait.js +43 -0
- package/utils/directives/motion-collapse.js +1 -1
- package/utils/mixins/index.js +8 -0
- package/utils/mixins/main-dom-element.js +23 -0
- package/utils/mixins/mixin.js +21 -0
- package/utils/mixins/nav-element.js +103 -0
- package/ucd-theme-header-search-popup/ucd-theme-header-search-popup.js +0 -40
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { LitElement, html } from 'lit';
|
|
2
|
+
import {render, styles} from "./ucd-theme-subnav.tpl.js";
|
|
3
|
+
import { ifDefined } from 'lit/directives/if-defined.js';
|
|
4
|
+
|
|
5
|
+
import { styleMap } from 'lit/directives/style-map.js';
|
|
6
|
+
|
|
7
|
+
import {Mixin, NavElement} from "../../utils/mixins";
|
|
8
|
+
import { MutationObserverController, WaitController } from '../../utils/controllers';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @class UcdThemeSubnav
|
|
12
|
+
* @classdesc Component class for displaying a subnav
|
|
13
|
+
*
|
|
14
|
+
* Patternlab url:
|
|
15
|
+
* - http://dev.webstyleguide.ucdavis.edu/redesign/?p=molecules-sub-nav
|
|
16
|
+
* - http://dev.webstyleguide.ucdavis.edu/redesign/?p=molecules-sub-nav-linked-title
|
|
17
|
+
*
|
|
18
|
+
* @property {String} navTitle - Subnav header text
|
|
19
|
+
* @property {String} titleHref - Link for subnav header (optional)
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* <ucd-theme-subnav nav-title="A subnav">
|
|
23
|
+
* <li><a href="#">Link 1</a></li>
|
|
24
|
+
* <li><a href="#">Link 2</a></li>
|
|
25
|
+
* <ul link-text="Link with Children" href="#">
|
|
26
|
+
* <li><a href="#">Child 1</a></li>
|
|
27
|
+
* <li><a href="#">Child 2</a></li>
|
|
28
|
+
* <li><a href="#">Child 3</a></li>
|
|
29
|
+
* </ul>
|
|
30
|
+
* </ucd-theme-subnav>
|
|
31
|
+
*/
|
|
32
|
+
export default class UcdThemeSubnav extends Mixin(LitElement)
|
|
33
|
+
.with(NavElement) {
|
|
34
|
+
|
|
35
|
+
mutationObserver = new MutationObserverController(this, {subtree: true, childList: true});
|
|
36
|
+
wait = new WaitController(this);
|
|
37
|
+
|
|
38
|
+
static get properties() {
|
|
39
|
+
return {
|
|
40
|
+
navTitle: {type: String, attribute: "nav-title"},
|
|
41
|
+
titleHref: {type: String, attribute: "title-href"},
|
|
42
|
+
navItems: {type: Array},
|
|
43
|
+
animationDuration: {type: Number, attribute: "animation-duration"}
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
static get styles() {
|
|
48
|
+
return styles();
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
constructor() {
|
|
52
|
+
super();
|
|
53
|
+
this.render = render.bind(this);
|
|
54
|
+
|
|
55
|
+
this.navTitle = "";
|
|
56
|
+
this.titleHref = "";
|
|
57
|
+
this.animationDuration = 300;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* @method openNavItem
|
|
62
|
+
* @description Shows children of a nav item (if applicable)
|
|
63
|
+
* @param {Array} navLocation - Coordinates of the item in the 'navItems' array. i.e. [0, 1, 4].
|
|
64
|
+
* @returns {Boolean}
|
|
65
|
+
*/
|
|
66
|
+
async openNavItem(navLocation){
|
|
67
|
+
let navItem = this.getNavItem(navLocation);
|
|
68
|
+
if ( !navItem || navItem.isTransitioning ) return false;
|
|
69
|
+
|
|
70
|
+
let navEle = this.renderRoot.getElementById(`nav--${navLocation.join("-")}`);
|
|
71
|
+
if ( !navEle ) return false;
|
|
72
|
+
let navUL = navEle.querySelector('ul');
|
|
73
|
+
if ( !navUL ) return false;
|
|
74
|
+
navItem.isTransitioning = true;
|
|
75
|
+
|
|
76
|
+
// Get expanded height
|
|
77
|
+
navItem.inlineStyles.display = "block";
|
|
78
|
+
navItem.inlineStyles.height = "0px";
|
|
79
|
+
await this.wait.waitForUpdate();
|
|
80
|
+
const expandedHeight = navUL.scrollHeight + "px";
|
|
81
|
+
|
|
82
|
+
// Set expanded height
|
|
83
|
+
navItem.inlineStyles.height = expandedHeight;
|
|
84
|
+
await this.wait.waitForUpdate();
|
|
85
|
+
|
|
86
|
+
// Complete animation
|
|
87
|
+
await this.wait.wait(this.animationDuration);
|
|
88
|
+
navItem.inlineStyles = {};
|
|
89
|
+
navItem.isOpen = true;
|
|
90
|
+
navItem.isTransitioning = false;
|
|
91
|
+
this.requestUpdate();
|
|
92
|
+
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* @method closeNavItem
|
|
98
|
+
* @description Hides children of a nav item (if applicable)
|
|
99
|
+
* @param {Array} navLocation - Coordinates of the item in the 'navItems' array. i.e. [0, 1, 4].
|
|
100
|
+
* @returns {Boolean}
|
|
101
|
+
*/
|
|
102
|
+
async closeNavItem(navLocation){
|
|
103
|
+
let navItem = this.getNavItem(navLocation);
|
|
104
|
+
if ( !navItem || navItem.isTransitioning ) return false;
|
|
105
|
+
|
|
106
|
+
let navEle = this.renderRoot.getElementById(`nav--${navLocation.join("-")}`);
|
|
107
|
+
if ( !navEle ) return false;
|
|
108
|
+
let navUL = navEle.querySelector('ul');
|
|
109
|
+
if ( !navUL ) return false;
|
|
110
|
+
navItem.isTransitioning = true;
|
|
111
|
+
|
|
112
|
+
// Set expanded height
|
|
113
|
+
navItem.inlineStyles.height = navUL.scrollHeight + "px";
|
|
114
|
+
navItem.inlineStyles.display = "block";
|
|
115
|
+
await this.wait.waitForUpdate();
|
|
116
|
+
|
|
117
|
+
// Set height to zero
|
|
118
|
+
await this.wait.waitForFrames(2);
|
|
119
|
+
navItem.inlineStyles.height = "0px";
|
|
120
|
+
await this.wait.waitForUpdate();
|
|
121
|
+
|
|
122
|
+
// Complete animation
|
|
123
|
+
await this.wait.wait(this.animationDuration);
|
|
124
|
+
navItem.inlineStyles = {};
|
|
125
|
+
navItem.isOpen = false;
|
|
126
|
+
navItem.isTransitioning = false;
|
|
127
|
+
this.requestUpdate();
|
|
128
|
+
|
|
129
|
+
return true;
|
|
130
|
+
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* @method _onChildListMutation
|
|
135
|
+
* @private
|
|
136
|
+
* @description Fires when light dom child list changes. Injected by MutationObserverController.
|
|
137
|
+
* Sets the 'navItems' property.
|
|
138
|
+
*/
|
|
139
|
+
_onChildListMutation(){
|
|
140
|
+
let navItems = this.parseNavChildren();
|
|
141
|
+
if ( navItems.length ) this.navItems = navItems;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* @method _renderNavItem
|
|
146
|
+
* @private
|
|
147
|
+
* @description Renders a menu item and all its children to the specified max depth
|
|
148
|
+
* @param {Object} item - An item from the 'navItems' element property
|
|
149
|
+
* @param {Array} location - Coordinates of the item in the 'navItems' array. i.e. [0, 1, 4]
|
|
150
|
+
* @returns {TemplateResult}
|
|
151
|
+
*/
|
|
152
|
+
_renderNavItem(item, location){
|
|
153
|
+
const depth = location.length - 1;
|
|
154
|
+
|
|
155
|
+
if ( this.itemHasSubNav(item) && depth < this.maxDepth) {
|
|
156
|
+
return html`
|
|
157
|
+
<li id="nav--${location.join("-")}">
|
|
158
|
+
<div class="submenu-toggle__wrapper">
|
|
159
|
+
<a href=${ifDefined(item.href ? item.href : null)}>${item.linkText}</a>
|
|
160
|
+
<button
|
|
161
|
+
@click=${() => this._toggleItemMenu(location)}
|
|
162
|
+
class="submenu-toggle ${item.isOpen ? "submenu-toggle--open" : ""}"
|
|
163
|
+
?disabled=${item.isTransitioning}
|
|
164
|
+
aria-label="Toggle Submenu">
|
|
165
|
+
<span class="submenu-toggle__icon"></span>
|
|
166
|
+
</button>
|
|
167
|
+
</div>
|
|
168
|
+
<ul style=${styleMap(item.inlineStyles)} class="${item.isOpen ? "is-open": "" }">
|
|
169
|
+
${item.subItems.map((subItem, i) => this._renderNavItem(subItem, location.concat([i])))}
|
|
170
|
+
</ul>
|
|
171
|
+
</li>
|
|
172
|
+
`;
|
|
173
|
+
}
|
|
174
|
+
return html`
|
|
175
|
+
<li id="nav--${location.join("-")}"><a href=${item.href}>${item.linkText}</a></li>
|
|
176
|
+
`;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* @method _toggleItemMenu
|
|
181
|
+
* @private
|
|
182
|
+
* @description Attached to nav item button click. Shows/hides children.
|
|
183
|
+
* @param {Array} navLocation - Coordinates of the item in the 'navItems' array. i.e. [0, 1, 4]
|
|
184
|
+
*/
|
|
185
|
+
_toggleItemMenu(navLocation){
|
|
186
|
+
let navItem = this.getNavItem(navLocation);
|
|
187
|
+
if ( navItem.isOpen ) {
|
|
188
|
+
this.closeNavItem(navLocation);
|
|
189
|
+
} else {
|
|
190
|
+
this.openNavItem(navLocation);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
customElements.define('ucd-theme-subnav', UcdThemeSubnav);
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { html, css } from 'lit';
|
|
2
|
+
|
|
3
|
+
import normalizeStyles from "@ucd-lib/theme-sass/normalize.css.js";
|
|
4
|
+
import headerStyles from "@ucd-lib/theme-sass/1_base_html/_headings.css.js";
|
|
5
|
+
import formStyles from "@ucd-lib/theme-sass/1_base_html/_forms.css.js";
|
|
6
|
+
import menuStyles from "@ucd-lib/theme-sass/2_base_class/_misc.css.js";
|
|
7
|
+
import subNavStyles from "@ucd-lib/theme-sass/4_component/_nav-sub.css.js";
|
|
8
|
+
import subNavToggleStyles from "@ucd-lib/theme-sass/4_component/_submenu-toggle.css.js";
|
|
9
|
+
|
|
10
|
+
export function styles() {
|
|
11
|
+
const elementStyles = css`
|
|
12
|
+
:host {
|
|
13
|
+
display: block;
|
|
14
|
+
}
|
|
15
|
+
ul.sub-nav__menu ul {
|
|
16
|
+
display: none;
|
|
17
|
+
overflow-y: hidden;
|
|
18
|
+
visibility: visible;
|
|
19
|
+
height: auto;
|
|
20
|
+
border-top-width: 0px;
|
|
21
|
+
border-bottom-width: 0px;
|
|
22
|
+
padding-top: 0px;
|
|
23
|
+
padding-bottom: 0px;
|
|
24
|
+
}
|
|
25
|
+
ul.sub-nav__menu ul.is-open {
|
|
26
|
+
display: block;
|
|
27
|
+
}
|
|
28
|
+
`;
|
|
29
|
+
|
|
30
|
+
return [
|
|
31
|
+
normalizeStyles,
|
|
32
|
+
headerStyles,
|
|
33
|
+
formStyles,
|
|
34
|
+
menuStyles,
|
|
35
|
+
subNavStyles,
|
|
36
|
+
subNavToggleStyles,
|
|
37
|
+
elementStyles
|
|
38
|
+
];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function render() {
|
|
42
|
+
return html`
|
|
43
|
+
<style>
|
|
44
|
+
ul.sub-nav__menu ul {
|
|
45
|
+
transition: height ${this.animationDuration + "ms"};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
</style>
|
|
49
|
+
<nav class="sub-nav">
|
|
50
|
+
${this.navTitle ? html`
|
|
51
|
+
<h2 class="sub-nav__title${this.titleHref ? "-linked" : ""}">
|
|
52
|
+
${this.titleHref ? html`<a href=${this.titleHref}>${this.navTitle}</a>` : this.navTitle}
|
|
53
|
+
</h2>
|
|
54
|
+
` : html``}
|
|
55
|
+
<ul class="sub-nav__menu">
|
|
56
|
+
${this.navItems.map((item, i) => this._renderNavItem(item, [i]))}
|
|
57
|
+
</ul>
|
|
58
|
+
</nav>
|
|
59
|
+
|
|
60
|
+
`;}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ucd-lib/theme-elements",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "Custom elements for the UCD theme",
|
|
3
|
+
"version": "0.0.5",
|
|
4
|
+
"description": "Custom elements for the UCD brand theme",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
@@ -9,7 +9,9 @@
|
|
|
9
9
|
"author": "jrmerz@ucdavis.edu",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@ucd-lib/theme-sass": "^5.0.
|
|
13
|
-
"
|
|
12
|
+
"@ucd-lib/theme-sass": "^5.0.11",
|
|
13
|
+
"lit": "^2.0.2",
|
|
14
|
+
"photoswipe": "^4.1.3",
|
|
15
|
+
"slim-select": "^1.26.2"
|
|
14
16
|
}
|
|
15
17
|
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { svg } from "lit";
|
|
2
|
+
export default svg`
|
|
3
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 276.31 432.01"><path d="M102.37,337.79,148,325.38c13.66-3.71,24-17.44,24-31.94V121.15l-69.56-11Z" style="fill:#ffbf00"/><path d="M171.94,87.9V0L24.87,31.15C10.69,34.15,0,47.81,0,63v302.7l69.55-18.93v-275Z" style="fill:#ffbf00"/><path d="M250.56,100.25,171.94,87.9v33.26l71.49,11.24V393.6l-141-22.18V337.8l-32.84,8.94v25.48c0,15.3,11.3,29.06,25.72,31.33l181,28.46V131.58C276.27,116.28,265,102.52,250.56,100.25Z" style="fill:#022851"/></svg>
|
|
4
|
+
`;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { svg } from "lit";
|
|
2
|
+
export default svg`
|
|
3
|
+
|
|
4
|
+
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
5
|
+
viewBox="0 0 1512 436.8" style="enable-background:new 0 0 1512 436.8;" xml:space="preserve">
|
|
6
|
+
<style type="text/css">
|
|
7
|
+
.st0{fill:#DAAA00;}
|
|
8
|
+
.st1{fill:#002855;}
|
|
9
|
+
.st2{fill:none;}
|
|
10
|
+
</style>
|
|
11
|
+
<g>
|
|
12
|
+
<g>
|
|
13
|
+
<g>
|
|
14
|
+
<g>
|
|
15
|
+
<g>
|
|
16
|
+
<g>
|
|
17
|
+
<path class="st0" d="M1369.7,174.7l18.4-48.8l3.2,2.8c11.3,9.2,26.7,17.1,41.2,17.4c13,0.3,19.3-3.2,17.6-14.1
|
|
18
|
+
c-1.3-8.2-10.5-9.6-16.3-10.8l-12.7-2.5c-24.7-4.6-45.4-19.8-45.4-48.7c0-43.6,37.6-68.1,75.4-68.1c19.9,0,38.1,5.1,55.1,16.1
|
|
19
|
+
l-16,43.3c-8.8-6.3-22.1-15.2-38.9-15.8c-5.5-0.2-18.2,2.7-14.1,15.6c1.8,5.5,9.6,7.8,14.4,8.9l14.3,3.4
|
|
20
|
+
c26.7,6.2,46.1,21.5,46.1,52.6c0,43.8-37.8,65.5-75.4,65.5C1414.7,191.5,1389.3,185.3,1369.7,174.7"/>
|
|
21
|
+
<rect x="1291.7" y="4.9" class="st0" width="64.4" height="183.9"/>
|
|
22
|
+
<polygon class="st0" points="1219.1,4.9 1285.1,4.9 1217.8,188.8 1164.2,188.8 1097.1,4.9 1162.8,4.9 1191,115.8 "/>
|
|
23
|
+
<path class="st0" d="M941,188.8h66.9l5.1-23.1h47.7l6.3,23.1h66.9L1071.3,4.9h-70.2L941,188.8z M1036.9,57.9L1036.9,57.9
|
|
24
|
+
c1.2,7.8,12.7,64.1,12.7,64.1h-25.3L1036.9,57.9z"/>
|
|
25
|
+
<path class="st0" d="M840.4,135.9h4.3c21.2,0,37-12.7,37-36.7c0-25.8-13.9-40.3-37.2-40.3h-4V135.9z M775.6,4.9h65.9
|
|
26
|
+
c58.8,0,103.8,27,103.8,94.6c0,54.5-36.7,89.3-88.1,89.3l-81.6-0.1V4.9z"/>
|
|
27
|
+
<path class="st0" d="M737.1,10.6l3.4,30.2c0.8,7.2,4.9,24.4-0.2,22.1c-3.2-1.4-5.8-9.2-8.4-16.1c-1.3-3.5-7.6-20.1-9.2-21.4
|
|
28
|
+
c-7.9-5.9-27.7-12.6-41.1-12.7c-40.5-0.2-67.4,29.8-67.4,82.8c0,38.1,18.2,83.7,64.6,83.7c16.6,0,48.4-5.2,57.1-28.9
|
|
29
|
+
c3.9-10.7,7.5-20.2,10.1-17.3c1.9,2.1-0.6,10.7-1.7,15.3c-5.5,21.9-5.8,28.6-7.5,29.4c-20.9,10.5-47.8,14-71.3,14
|
|
30
|
+
c-74.8,0-100.6-43.6-100.6-87.2C565,28.9,611.5-3,683.6,0.2C701.8,0.9,720,4.2,737.1,10.6"/>
|
|
31
|
+
<path class="st0" d="M516.4,14l-12-4.2c-4-3.6,0.9-4.6,0.9-4.6s17.3,3.2,60.4-0.4c0,0,3.7,0.7,1.2,3.8l-14.1,6
|
|
32
|
+
c-9.2,4-9.2,1.7-9.2,11.8l-0.1,93.7c0,73.3-74.6,71.7-89.1,71.7c-6.9,0-75.3,0-75.3-58.9V33.7c0-17.3,1.8-16.8-3.9-18.9
|
|
33
|
+
l-17.3-6.5c0,0-2.9-4.2,2.3-3.9c14.1,0.7,34.6,3.8,82.7,0.3c0,0,4.2,1,1.4,4l-14.4,4c-11,4.9-9.5,1.2-9.8,12.4l0.3,97.8
|
|
34
|
+
c0,24,12.3,53.7,51.2,53.7c52.8,0,53.3-45.7,53.3-55.9l0.1-96.9C525.6,14.8,524.4,17.4,516.4,14"/>
|
|
35
|
+
</g>
|
|
36
|
+
</g>
|
|
37
|
+
<rect x="379.1" y="229.5" class="st0" width="1132.9" height="7.7"/>
|
|
38
|
+
</g>
|
|
39
|
+
</g>
|
|
40
|
+
</g>
|
|
41
|
+
<g>
|
|
42
|
+
<path class="st1" d="M419,403h48v33.9h-88V282.9h40V403z"/>
|
|
43
|
+
<path class="st1" d="M551.3,436.8h-40V282.9h40V436.8z"/>
|
|
44
|
+
<path class="st1" d="M601.9,436.8V282.9H659c27.4,0,45.7,10.6,45.7,40c0,13.9-4.5,25.1-16.9,31.4v0.4c22,2.9,31.4,17.8,31.4,39.2
|
|
45
|
+
c0,32.3-27.6,42.9-55.7,42.9H601.9z M641.9,343.3h4.5c10.6,0,21.6-1.8,21.6-14.9c0-14.1-12.5-14.9-23.3-14.9h-2.9V343.3z
|
|
46
|
+
M641.9,406.2h5.1c11.8,0,31.8,0.6,31.8-16.3c0-18.6-19.8-16.7-32.9-16.7h-4.1V406.2z"/>
|
|
47
|
+
<path class="st1" d="M886.7,436.8h-49.8l-37.8-59.2h-0.4v59.2h-40V282.9h59.8c30.4,0,53.5,14.5,53.5,47.4
|
|
48
|
+
c0,21.2-11.8,39.6-33.7,43.5L886.7,436.8z M798.7,351.9h3.9c13.1,0,27.8-2.4,27.8-19.2c0-16.7-14.7-19.2-27.8-19.2h-3.9V351.9z"/>
|
|
49
|
+
<path class="st1" d="M951.6,410.1L941,436.8h-42.5l59.2-153.9h43.7l58,153.9h-42.7l-10-26.7H951.6z M979.6,330.5h-0.4l-16.5,49
|
|
50
|
+
h33.3L979.6,330.5z"/>
|
|
51
|
+
<path class="st1" d="M1210.9,436.8h-49.8l-37.8-59.2h-0.4v59.2h-40V282.9h59.8c30.4,0,53.5,14.5,53.5,47.4
|
|
52
|
+
c0,21.2-11.8,39.6-33.7,43.5L1210.9,436.8z M1122.9,351.9h3.9c13.1,0,27.8-2.4,27.8-19.2c0-16.7-14.7-19.2-27.8-19.2h-3.9V351.9z"
|
|
53
|
+
/>
|
|
54
|
+
<path class="st1" d="M1216.4,282.9h48l28.8,41.8l28.8-41.8h48l-56.8,80v73.9h-40v-73.9L1216.4,282.9z"/>
|
|
55
|
+
</g>
|
|
56
|
+
</g>
|
|
57
|
+
<g>
|
|
58
|
+
<path class="st2" d="M148,330.2l-45.6,12.4v33.6l141,22.2V137.2L171.9,126v172.3C171.9,312.8,161.6,326.5,148,330.2z"/>
|
|
59
|
+
<path class="st0" d="M102.4,342.6l45.6-12.4c13.7-3.7,24-17.4,24-31.9V126L102.4,115V342.6z"/>
|
|
60
|
+
<path class="st0" d="M171.9,92.7V4.8L24.9,36C10.7,39,0,52.7,0,67.8v302.7l69.6-18.9V76.6L171.9,92.7z"/>
|
|
61
|
+
<path class="st1" d="M250.6,105.1l-78.6-12.4V126l71.5,11.2v261.2l-141-22.2v-33.6l-32.8,8.9v25.5c0,15.3,11.3,29.1,25.7,31.3
|
|
62
|
+
l181,28.5V136.4C276.3,121.1,265,107.4,250.6,105.1z"/>
|
|
63
|
+
</g>
|
|
64
|
+
<rect class="st2" width="1512" height="436.8"/>
|
|
65
|
+
<rect class="st2" width="1512" height="436.8"/>
|
|
66
|
+
</svg>
|
|
67
|
+
`;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { LitElement, svg } from 'lit';
|
|
2
|
+
import {render, styles} from "./ucdlib-branding-bar.tpl.js";
|
|
3
|
+
|
|
4
|
+
import {Mixin, NavElement} from "../../utils/mixins";
|
|
5
|
+
import { MutationObserverController } from '../../utils/controllers';
|
|
6
|
+
import logo from "./logo.js";
|
|
7
|
+
import bookLogo from "./book.js";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @class UcdlibBrandingBar
|
|
11
|
+
* @classdesc Component class for displaying a Library branding bar in a header
|
|
12
|
+
*
|
|
13
|
+
* @property {String} figure - Figure to display: 'book' or 'logo'
|
|
14
|
+
* @property {String} siteName - Name of website to display
|
|
15
|
+
* @property {String} slogan - Optional text to display below site name
|
|
16
|
+
* @property {String} siteUrl - Url to use for links around site name and figure
|
|
17
|
+
*
|
|
18
|
+
* @examples
|
|
19
|
+
* <ucdlib-branding-bar>
|
|
20
|
+
* <a href="#">My Account</a>
|
|
21
|
+
* <a href="#">Access VPN</a>
|
|
22
|
+
* <a href="#">Give</a>
|
|
23
|
+
* </ucdlib-branding-bar>
|
|
24
|
+
*/
|
|
25
|
+
export default class UcdlibBrandingBar extends Mixin(LitElement)
|
|
26
|
+
.with(NavElement) {
|
|
27
|
+
|
|
28
|
+
mutationObserver = new MutationObserverController(
|
|
29
|
+
this,
|
|
30
|
+
{childList: true, characterData: true, attributes: true}
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
static get properties() {
|
|
34
|
+
return {
|
|
35
|
+
figure: {type: String},
|
|
36
|
+
siteName: {type: String, attribute: "site-name"},
|
|
37
|
+
slogan: {type: String},
|
|
38
|
+
siteUrl: {type: String, attribute: "site-url"},
|
|
39
|
+
navItems: {type: Array}
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
static get styles() {
|
|
44
|
+
return styles();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
constructor() {
|
|
48
|
+
super();
|
|
49
|
+
this.render = render.bind(this);
|
|
50
|
+
|
|
51
|
+
this.figure = "book";
|
|
52
|
+
this.siteName = "UC Davis Library";
|
|
53
|
+
this.slogan = "";
|
|
54
|
+
this.siteUrl = "/";
|
|
55
|
+
this.navItems = [];
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* @method willUpdate
|
|
60
|
+
* @description Lit lifecycle method called before an update
|
|
61
|
+
* @private
|
|
62
|
+
* @param {Map} props - Properties that have changed
|
|
63
|
+
*/
|
|
64
|
+
willUpdate(props){
|
|
65
|
+
if ( props.has("figure") && props.get("figure") !== undefined ){
|
|
66
|
+
const allowedKeywords = ['book', 'logo'];
|
|
67
|
+
if ( !allowedKeywords.includes(props.get('figure')) ){
|
|
68
|
+
console.warn(`${props.get('figure')} is not a recognized "figure" keyword.
|
|
69
|
+
Allowed values: ${JSON.stringify(allowedKeywords)}
|
|
70
|
+
`);
|
|
71
|
+
this.figure = allowedKeywords[0];
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* @method _renderFigure
|
|
78
|
+
* @description Renders an svg logo
|
|
79
|
+
* @private
|
|
80
|
+
* @returns {TemplateResult}
|
|
81
|
+
*/
|
|
82
|
+
_renderFigure(){
|
|
83
|
+
if ( this.figure === 'logo') return logo;
|
|
84
|
+
if ( this.figure === 'book' ) return bookLogo;
|
|
85
|
+
return svg``;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* @method _onChildListMutation
|
|
90
|
+
* @private
|
|
91
|
+
* @description Fires when light dom child list changes. Called by MutationObserverController.
|
|
92
|
+
* Sets the 'navItems' property.
|
|
93
|
+
*/
|
|
94
|
+
_onChildListMutation(){
|
|
95
|
+
let navItems = this.parseNavChildren();
|
|
96
|
+
if ( navItems.length ) this.navItems = navItems;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
customElements.define('ucdlib-branding-bar', UcdlibBrandingBar);
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { html, css } from 'lit';
|
|
2
|
+
import { ifDefined } from 'lit/directives/if-defined.js';
|
|
3
|
+
|
|
4
|
+
import headingStyles from "@ucd-lib/theme-sass/1_base_html/_headings.css.js";
|
|
5
|
+
import linkStyles from "@ucd-lib/theme-sass/1_base_html/_links.css.js";
|
|
6
|
+
import brandingStyles from "@ucd-lib/theme-sass/4_component/_site-branding.css.js"
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
export function styles() {
|
|
10
|
+
const elementStyles = css`
|
|
11
|
+
:host {
|
|
12
|
+
display: block;
|
|
13
|
+
}
|
|
14
|
+
.container {
|
|
15
|
+
display: flex;
|
|
16
|
+
flex-direction: row;
|
|
17
|
+
flex-wrap: nowrap;
|
|
18
|
+
align-items: center;
|
|
19
|
+
justify-content: space-between;
|
|
20
|
+
}
|
|
21
|
+
.site-branding__figure svg {
|
|
22
|
+
max-height: 6.25rem;
|
|
23
|
+
max-width: 100%;
|
|
24
|
+
height: auto;
|
|
25
|
+
}
|
|
26
|
+
.figure--book svg {
|
|
27
|
+
width: 70px;
|
|
28
|
+
min-width: 70px;
|
|
29
|
+
}
|
|
30
|
+
.figure--logo svg {
|
|
31
|
+
width: 375px;
|
|
32
|
+
min-width: 375px;
|
|
33
|
+
}
|
|
34
|
+
[hidden] {
|
|
35
|
+
display: none !important;
|
|
36
|
+
}
|
|
37
|
+
.figure--logo .site-branding__body {
|
|
38
|
+
display: none;
|
|
39
|
+
}
|
|
40
|
+
.menu {
|
|
41
|
+
display: flex;
|
|
42
|
+
flex-direction: row;
|
|
43
|
+
flex-wrap: nowrap;
|
|
44
|
+
align-items: center;
|
|
45
|
+
}
|
|
46
|
+
.menu a {
|
|
47
|
+
text-decoration: none;
|
|
48
|
+
font-weight: 700;
|
|
49
|
+
margin-right: 1rem;
|
|
50
|
+
}
|
|
51
|
+
.menu a:last-child {
|
|
52
|
+
margin-right: 0;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
@media (max-width: 992px) {
|
|
56
|
+
.figure--logo svg {
|
|
57
|
+
width: 200px;
|
|
58
|
+
min-width: 200px;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.menu {
|
|
62
|
+
display: none;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
`;
|
|
67
|
+
|
|
68
|
+
return [
|
|
69
|
+
headingStyles,
|
|
70
|
+
brandingStyles,
|
|
71
|
+
linkStyles,
|
|
72
|
+
elementStyles];
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function render() {
|
|
76
|
+
return html`
|
|
77
|
+
<div class="container figure--${this.figure}">
|
|
78
|
+
<div class="site-branding">
|
|
79
|
+
<div class="site-branding__figure">
|
|
80
|
+
<a href="${this.siteUrl}" class="">${this._renderFigure()}</a>
|
|
81
|
+
</div>
|
|
82
|
+
<div class="site-branding__body">
|
|
83
|
+
<h1 class="site-branding__site-name" ?hidden=${!this.siteName}>
|
|
84
|
+
<a href=${this.siteUrl}>${this.siteName}</a>
|
|
85
|
+
</h1>
|
|
86
|
+
<div class="site-branding__slogan" ?hidden=${!this.slogan}>${this.slogan}</div>
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
${this.navItems.length ? html`
|
|
90
|
+
<nav class="menu">
|
|
91
|
+
${this.navItems.map(link => html`
|
|
92
|
+
<a
|
|
93
|
+
href=${ifDefined(link.href ? link.href : null)}
|
|
94
|
+
target=${ifDefined(link.newTab ? "_blank": null)}
|
|
95
|
+
>${link.linkText}</a>
|
|
96
|
+
`)}
|
|
97
|
+
</nav>
|
|
98
|
+
` : html``}
|
|
99
|
+
|
|
100
|
+
</div>
|
|
101
|
+
|
|
102
|
+
`;}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { LitElement } from 'lit';
|
|
2
|
+
import {render, styles} from "./ucdlib-icon.tpl.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @class UcdlibIcon
|
|
6
|
+
* @classdesc Component class for displaying an icon
|
|
7
|
+
* @property {String} icon - name of icon within a registered icon set.
|
|
8
|
+
* Format: ${iconset name}:${icon name}
|
|
9
|
+
* Or just the icon name if using the default ucdlib iconset.
|
|
10
|
+
* @property {String} src - If using ucdlib-icon without an iconset, you can set the src to be
|
|
11
|
+
* the URL of an individual icon image file. Note that this will take
|
|
12
|
+
* precedence over a given icon attribute.
|
|
13
|
+
*/
|
|
14
|
+
export default class UcdlibIcon extends LitElement {
|
|
15
|
+
|
|
16
|
+
static get properties() {
|
|
17
|
+
return {
|
|
18
|
+
icon: {type: String},
|
|
19
|
+
src: {type: String},
|
|
20
|
+
_iconName: {type: String, state: true},
|
|
21
|
+
_iconsetName: {type: String, state: true}
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
static get styles() {
|
|
26
|
+
return styles();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
constructor() {
|
|
30
|
+
super();
|
|
31
|
+
this.render = render.bind(this);
|
|
32
|
+
this.icon = "";
|
|
33
|
+
this.src = "";
|
|
34
|
+
|
|
35
|
+
this._iconName = "";
|
|
36
|
+
this._iconsetName = "";
|
|
37
|
+
this._default_iconset = "ucdlib";
|
|
38
|
+
this._onAddedIconset = this._onAddedIconset.bind(this);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @method disconnectedCallback
|
|
43
|
+
* @description native web component life cycle method
|
|
44
|
+
* @private
|
|
45
|
+
*/
|
|
46
|
+
disconnectedCallback() {
|
|
47
|
+
window.removeEventListener('ucdlib-iconset-added', this._onAddedIconset);
|
|
48
|
+
super.disconnectedCallback();
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* @method updated
|
|
53
|
+
* @description Lit lifecyle method called after element updates
|
|
54
|
+
* @param {Map} props - Updated properties
|
|
55
|
+
* @private
|
|
56
|
+
*/
|
|
57
|
+
updated(props){
|
|
58
|
+
if ( props.has('icon') || props.has('src') ){
|
|
59
|
+
if ( this.src ) {
|
|
60
|
+
this._updateIcon();
|
|
61
|
+
} else if ( this.icon ) {
|
|
62
|
+
let parts = this.icon.split(":");
|
|
63
|
+
this._iconName = parts.pop();
|
|
64
|
+
this._iconsetName = parts.pop() || this._default_iconset;
|
|
65
|
+
this._updateIcon();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* @method _onAddedIconset
|
|
72
|
+
* @description Attached to custom event fired by a ucdlib-iconset element
|
|
73
|
+
* @private
|
|
74
|
+
*/
|
|
75
|
+
_onAddedIconset(){
|
|
76
|
+
this._updateIcon();
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* @method _updateIcon
|
|
81
|
+
* @description Prepends a new svg or img icon to the shadowroot.
|
|
82
|
+
* Called on icon or src property change.
|
|
83
|
+
* @private
|
|
84
|
+
*/
|
|
85
|
+
_updateIcon(){
|
|
86
|
+
// using the icon attribute
|
|
87
|
+
if ( this._usesIconSet() ) {
|
|
88
|
+
if ( this._img && this._img.parentNode ) this.renderRoot.removeChild(this._img);
|
|
89
|
+
|
|
90
|
+
if ( this._iconName === '') {
|
|
91
|
+
if ( this._iconset ) this._iconset.removeIcon(this);
|
|
92
|
+
} else if ( this._iconsetName ){
|
|
93
|
+
this._iconset = this._getIconset();
|
|
94
|
+
if ( this._iconset ) {
|
|
95
|
+
this._iconset.applyIcon(this, this._iconName);
|
|
96
|
+
window.addEventListener('ucdlib-iconset-added', this._onAddedIconset);
|
|
97
|
+
} else {
|
|
98
|
+
window.removeEventListener('ucdlib-iconset-added', this._onAddedIconset);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// using the src attribute
|
|
103
|
+
} else {
|
|
104
|
+
if ( this._iconset ) this._iconset.removeIcon(this);
|
|
105
|
+
if ( !this._img ) {
|
|
106
|
+
this._img = document.createElement('img');
|
|
107
|
+
this._img.style.width = '100%';
|
|
108
|
+
this._img.style.height = '100%';
|
|
109
|
+
this._img.draggable = false;
|
|
110
|
+
}
|
|
111
|
+
this._img.src = this.src;
|
|
112
|
+
this.renderRoot.appendChild(this._img);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* @method _usesIconSet
|
|
119
|
+
* @description Element is using an icon set as opposed to an img src
|
|
120
|
+
* @returns {Boolean}
|
|
121
|
+
* @private
|
|
122
|
+
*/
|
|
123
|
+
_usesIconSet(){
|
|
124
|
+
return this.icon || !this.src;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* @method _getIconset
|
|
129
|
+
* @description Return the specified ucdlib-iconset element from the head
|
|
130
|
+
* @returns {Element}
|
|
131
|
+
* @private
|
|
132
|
+
*/
|
|
133
|
+
_getIconset(){
|
|
134
|
+
return document.head.querySelector(`ucdlib-iconset[name=${this._iconsetName}]`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
customElements.define('ucdlib-icon', UcdlibIcon);
|