@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.
Files changed (49) hide show
  1. package/{ucd-theme-alert → brand/ucd-theme-alert}/ucd-theme-alert.js +0 -0
  2. package/{ucd-theme-alert → brand/ucd-theme-alert}/ucd-theme-alert.tpl.js +0 -0
  3. package/{ucd-theme-collapse → brand/ucd-theme-collapse}/ucd-theme-collapse.js +20 -21
  4. package/{ucd-theme-collapse → brand/ucd-theme-collapse}/ucd-theme-collapse.tpl.js +1 -1
  5. package/brand/ucd-theme-header/ucd-theme-header.js +268 -0
  6. package/brand/ucd-theme-header/ucd-theme-header.tpl.js +146 -0
  7. package/{ucd-theme-image-gallery → brand/ucd-theme-image-gallery}/ucd-theme-image-gallery.js +0 -0
  8. package/{ucd-theme-image-gallery → brand/ucd-theme-image-gallery}/ucd-theme-image-gallery.tpl.js +0 -0
  9. package/{ucd-theme-list-accordion → brand/ucd-theme-list-accordion}/ucd-theme-list-accordion.js +47 -44
  10. package/{ucd-theme-list-accordion → brand/ucd-theme-list-accordion}/ucd-theme-list-accordion.tpl.js +2 -2
  11. package/{ucd-theme-message-area → brand/ucd-theme-message-area}/ucd-theme-message-area.js +0 -0
  12. package/{ucd-theme-message-area → brand/ucd-theme-message-area}/ucd-theme-message-area.tpl.js +0 -0
  13. package/brand/ucd-theme-pagination/ucd-theme-pagination.js +284 -0
  14. package/brand/ucd-theme-pagination/ucd-theme-pagination.tpl.js +93 -0
  15. package/brand/ucd-theme-primary-nav/ucd-theme-primary-nav.js +589 -0
  16. package/brand/ucd-theme-primary-nav/ucd-theme-primary-nav.tpl.js +106 -0
  17. package/brand/ucd-theme-quick-links/ucd-theme-quick-links.js +269 -0
  18. package/brand/ucd-theme-quick-links/ucd-theme-quick-links.tpl.js +114 -0
  19. package/{ucd-theme-form-search/ucd-theme-form-search.js → brand/ucd-theme-search-form/ucd-theme-search-form.js} +14 -15
  20. package/{ucd-theme-form-search/ucd-theme-form-search.tpl.js → brand/ucd-theme-search-form/ucd-theme-search-form.tpl.js} +0 -0
  21. package/brand/ucd-theme-search-popup/ucd-theme-search-popup.js +91 -0
  22. 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
  23. package/brand/ucd-theme-slim-select/ucd-theme-slim-select.js +58 -0
  24. package/brand/ucd-theme-slim-select/ucd-theme-slim-select.tpl.js +26 -0
  25. package/brand/ucd-theme-subnav/ucd-theme-subnav.js +196 -0
  26. package/brand/ucd-theme-subnav/ucd-theme-subnav.tpl.js +60 -0
  27. package/package.json +6 -4
  28. package/ucdlib/ucdlib-branding-bar/book.js +4 -0
  29. package/ucdlib/ucdlib-branding-bar/logo.js +67 -0
  30. package/ucdlib/ucdlib-branding-bar/ucdlib-branding-bar.js +101 -0
  31. package/ucdlib/ucdlib-branding-bar/ucdlib-branding-bar.tpl.js +102 -0
  32. package/ucdlib/ucdlib-icon/ucdlib-icon.js +138 -0
  33. package/ucdlib/ucdlib-icon/ucdlib-icon.tpl.js +22 -0
  34. package/ucdlib/ucdlib-icons/academic.js +154 -0
  35. package/ucdlib/ucdlib-icons/ucdlib-icons.js +78 -0
  36. package/ucdlib/ucdlib-icons/utils.js +29 -0
  37. package/ucdlib/ucdlib-iconset/ucdlib-iconset.js +170 -0
  38. package/ucdlib/ucdlib-pages/ucdlib-pages.js +150 -0
  39. package/utils/controllers/break-points.js +26 -0
  40. package/utils/controllers/index.js +11 -0
  41. package/utils/controllers/intersection-observer.js +58 -0
  42. package/utils/controllers/mutation-observer.js +52 -0
  43. package/utils/controllers/wait.js +43 -0
  44. package/utils/directives/motion-collapse.js +1 -1
  45. package/utils/mixins/index.js +8 -0
  46. package/utils/mixins/main-dom-element.js +23 -0
  47. package/utils/mixins/mixin.js +21 -0
  48. package/utils/mixins/nav-element.js +103 -0
  49. 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.1",
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.3",
13
- "photoswipe": "^4.1.3"
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);