@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,269 @@
|
|
|
1
|
+
import { LitElement, html } from 'lit';
|
|
2
|
+
import {render, styles} from "./ucd-theme-quick-links.tpl.js";
|
|
3
|
+
|
|
4
|
+
import { MutationObserverController, WaitController } from '../../utils/controllers';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @class UcdThemeQuickLinks
|
|
8
|
+
* @classdesc Component class for displaying a quick links nav
|
|
9
|
+
*
|
|
10
|
+
* Patternlab Url:
|
|
11
|
+
* - http://dev.webstyleguide.ucdavis.edu/redesign/?p=molecules-quick-links
|
|
12
|
+
* - http://dev.webstyleguide.ucdavis.edu/redesign/?p=molecules-quick-links-2-columns
|
|
13
|
+
* - http://dev.webstyleguide.ucdavis.edu/redesign/?p=molecules-quick-links-highlight
|
|
14
|
+
* - http://dev.webstyleguide.ucdavis.edu/redesign/?p=molecules-quick-links-home-site
|
|
15
|
+
* @property {String} title - Text to be displayed instead of "Quick Links"
|
|
16
|
+
* @property {String} styleModifiers - Apply alternate styles with a space-separated list.
|
|
17
|
+
* @property {Boolean} opened - Menu is open
|
|
18
|
+
* @property {Number} animationDuration - Length of animation when opening/closing menu
|
|
19
|
+
*/
|
|
20
|
+
export default class UcdThemeQuickLinks extends LitElement {
|
|
21
|
+
|
|
22
|
+
mutationObserver = new MutationObserverController(this);
|
|
23
|
+
wait = new WaitController(this);
|
|
24
|
+
|
|
25
|
+
static get properties() {
|
|
26
|
+
return {
|
|
27
|
+
title: {type: String},
|
|
28
|
+
styleModifiers: {type: String, attribute: "style-modifiers"},
|
|
29
|
+
opened: {type: Boolean},
|
|
30
|
+
animationDuration: {type: Number, attribute: "animation-duration"},
|
|
31
|
+
_links: {type: Array, state: true},
|
|
32
|
+
_hasCustomIcons: {type: Boolean, state: true},
|
|
33
|
+
_transitioning: {type: Boolean, state: true},
|
|
34
|
+
_openedHeight: {type: Number, state: true}
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
static get styles() {
|
|
39
|
+
return styles();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
constructor() {
|
|
43
|
+
super();
|
|
44
|
+
this.render = render.bind(this);
|
|
45
|
+
|
|
46
|
+
this.title = "Quick Links";
|
|
47
|
+
this.styleModifiers = "";
|
|
48
|
+
this.opened = false;
|
|
49
|
+
this.animationDuration = 300;
|
|
50
|
+
|
|
51
|
+
this._links = [];
|
|
52
|
+
this._classPrefix = "quick-links";
|
|
53
|
+
this._hasCustomIcons = false;
|
|
54
|
+
this._transitioning = false;
|
|
55
|
+
this._openedHeight = 0;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* @method open
|
|
60
|
+
* @description Opens the quick links menu if not already open or in a transition state.
|
|
61
|
+
* @returns {Promise} Returns true if successful
|
|
62
|
+
*/
|
|
63
|
+
async open(){
|
|
64
|
+
if ( this._transitioning || this.opened ) return false;
|
|
65
|
+
|
|
66
|
+
this._openedHeight = 0;
|
|
67
|
+
this._transitioning = true;
|
|
68
|
+
await this.updateComplete;
|
|
69
|
+
this._openedHeight = this.renderRoot.getElementById('menu').scrollHeight + "px";
|
|
70
|
+
await this.updateComplete;
|
|
71
|
+
|
|
72
|
+
await this.wait.wait(this.animationDuration);
|
|
73
|
+
this._transitioning = false;
|
|
74
|
+
this.opened = true;
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* @method close
|
|
80
|
+
* @description Closes the quick links menu if not already closed or in a transition state.
|
|
81
|
+
* @returns {Promise} Returns true if successful
|
|
82
|
+
*/
|
|
83
|
+
async close(){
|
|
84
|
+
if ( this._transitioning || !this.opened ) return false;
|
|
85
|
+
this._transitioning = true;
|
|
86
|
+
|
|
87
|
+
this._openedHeight = this.renderRoot.getElementById('menu').scrollHeight + "px";
|
|
88
|
+
await this.updateComplete;
|
|
89
|
+
await this.wait.waitForFrames(2);
|
|
90
|
+
this._openedHeight = 0;
|
|
91
|
+
await this.updateComplete;
|
|
92
|
+
|
|
93
|
+
await this.wait.wait(this.animationDuration);
|
|
94
|
+
|
|
95
|
+
this._transitioning = false;
|
|
96
|
+
this.opened = false;
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* @method ingestChildren
|
|
102
|
+
* @description Copies lightdom children into the shadowdom.
|
|
103
|
+
*/
|
|
104
|
+
ingestChildren(){
|
|
105
|
+
// remove any slotted icons created from a previous render
|
|
106
|
+
this.querySelectorAll('[slot]').forEach(ele => ele.remove());
|
|
107
|
+
this._hasCustomIcons = false;
|
|
108
|
+
|
|
109
|
+
let links = [];
|
|
110
|
+
this.querySelectorAll('a').forEach((child, index) => {
|
|
111
|
+
if (child.tagName !== "A") return;
|
|
112
|
+
let link = {};
|
|
113
|
+
|
|
114
|
+
// if first child exists, we assume it is an icon
|
|
115
|
+
if (
|
|
116
|
+
child.childElementCount > 0 &&
|
|
117
|
+
index < 3 &&
|
|
118
|
+
child.children[0].tagName !== 'A'
|
|
119
|
+
){
|
|
120
|
+
this._hasCustomIcons = true;
|
|
121
|
+
let icon = child.children[0].cloneNode(true);
|
|
122
|
+
let iconSlot = `icon-${index}`;
|
|
123
|
+
icon.setAttribute('slot', iconSlot);
|
|
124
|
+
this.appendChild(icon);
|
|
125
|
+
link.iconSlot = iconSlot;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if ( child.href ) link.href = child.href;
|
|
129
|
+
link.text = child.innerText;
|
|
130
|
+
link.ele = child;
|
|
131
|
+
|
|
132
|
+
links.push(link);
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
if ( links.length > 0 ) this._links = links;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* @method _onBtnClick
|
|
140
|
+
* @private
|
|
141
|
+
* @description Attached to menu open/close button
|
|
142
|
+
*/
|
|
143
|
+
async _onBtnClick(){
|
|
144
|
+
let didToggle;
|
|
145
|
+
if ( this.opened ) {
|
|
146
|
+
didToggle = await this.close();
|
|
147
|
+
} else {
|
|
148
|
+
didToggle = await this.open();
|
|
149
|
+
}
|
|
150
|
+
if ( didToggle ) {
|
|
151
|
+
this.dispatchEvent(new CustomEvent('toggle', {
|
|
152
|
+
detail : {open: this.opened}
|
|
153
|
+
}));
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* @method _onItemClick
|
|
159
|
+
* @private
|
|
160
|
+
* @description Attached to menu item links without an href
|
|
161
|
+
* @param {Event} e
|
|
162
|
+
*/
|
|
163
|
+
_onItemClick(e){
|
|
164
|
+
this._dispatchItemClick(e.target.index);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* @method _onItemKeyup
|
|
169
|
+
* @private
|
|
170
|
+
* @description Attached to menu item links without an href
|
|
171
|
+
* @param {Event} e
|
|
172
|
+
*/
|
|
173
|
+
_onItemKeyup(e){
|
|
174
|
+
if( e.which !== 13 ) return;
|
|
175
|
+
this._dispatchItemClick(e.target.index);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* @method _dispatchItemClick
|
|
180
|
+
* @private
|
|
181
|
+
* @description Fires the item-click event
|
|
182
|
+
* @param {Number} index - The array index of the selected menu item
|
|
183
|
+
*/
|
|
184
|
+
_dispatchItemClick(index){
|
|
185
|
+
this.dispatchEvent(new CustomEvent('item-click', {
|
|
186
|
+
detail : {
|
|
187
|
+
index: index,
|
|
188
|
+
item: this._links[index]
|
|
189
|
+
}
|
|
190
|
+
}));
|
|
191
|
+
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* @method _getNavClasses
|
|
196
|
+
* @private
|
|
197
|
+
* @description Get classes to be applied to the 'nav' element
|
|
198
|
+
* @returns {Object}
|
|
199
|
+
*/
|
|
200
|
+
_getNavClasses(){
|
|
201
|
+
let classes = {};
|
|
202
|
+
classes[`${this._classPrefix}__menu`] = true;
|
|
203
|
+
|
|
204
|
+
if ( this.styleModifiers ) {
|
|
205
|
+
this.styleModifiers.split(" ").forEach(mod => {
|
|
206
|
+
if (mod) classes[`${this._classPrefix}--${mod}`] = true;
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
classes['transitioning'] = this._transitioning;
|
|
211
|
+
classes['open'] = this.opened;
|
|
212
|
+
|
|
213
|
+
return classes;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* @method _getNavStyles
|
|
218
|
+
* @private
|
|
219
|
+
* @description Get styles to be applied to the 'nav' element
|
|
220
|
+
* @returns {Object}
|
|
221
|
+
*/
|
|
222
|
+
_getNavStyles(){
|
|
223
|
+
let styles = {};
|
|
224
|
+
if ( this._transitioning) {
|
|
225
|
+
styles['height'] = this._openedHeight;
|
|
226
|
+
}
|
|
227
|
+
return styles;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* @method _onChildListMutation
|
|
232
|
+
* @param {Array} mutationsList - List of mutation records
|
|
233
|
+
* @private
|
|
234
|
+
* @description Fires when light dom child list changes. Injected by MutationObserverController.
|
|
235
|
+
* Sets the '_links' property.
|
|
236
|
+
*/
|
|
237
|
+
_onChildListMutation(mutationsList){
|
|
238
|
+
|
|
239
|
+
// Check to see if this element triggered the mutation and avoid infinite loop.
|
|
240
|
+
if ( mutationsList ) {
|
|
241
|
+
for (const mutation of mutationsList) {
|
|
242
|
+
for (const n of Array.from(mutation.addedNodes)){
|
|
243
|
+
if ( n instanceof Element && n.hasAttribute('slot')) return;
|
|
244
|
+
}
|
|
245
|
+
for (const n of Array.from(mutation.removedNodes)){
|
|
246
|
+
if ( n instanceof Element && n.hasAttribute('slot')) return;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
this.ingestChildren();
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* @method _renderSlot
|
|
255
|
+
* @private
|
|
256
|
+
* @description Renders slot for an icon
|
|
257
|
+
* @param {Object} link - Member of the _links property.
|
|
258
|
+
* @returns {TemplateResult}
|
|
259
|
+
*/
|
|
260
|
+
_renderSlot(link) {
|
|
261
|
+
if ( link.iconSlot ) {
|
|
262
|
+
return html`<div class='slot-parent'><slot name=${link.iconSlot}></slot></div>`;
|
|
263
|
+
}
|
|
264
|
+
return html``;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
customElements.define('ucd-theme-quick-links', UcdThemeQuickLinks);
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { html, css } from 'lit';
|
|
2
|
+
import { classMap } from 'lit/directives/class-map.js';
|
|
3
|
+
import { styleMap } from 'lit/directives/style-map.js';
|
|
4
|
+
|
|
5
|
+
import normalizeStyles from "@ucd-lib/theme-sass/normalize.css.js";
|
|
6
|
+
import formStyles from "@ucd-lib/theme-sass/1_base_html/_forms.css.js";
|
|
7
|
+
import menuStyles from "@ucd-lib/theme-sass/2_base_class/_misc.css.js";
|
|
8
|
+
import subNavToggleStyles from "@ucd-lib/theme-sass/4_component/_submenu-toggle.css";
|
|
9
|
+
import quickLinkStyles from "@ucd-lib/theme-sass/4_component/_nav-quick.css.js";
|
|
10
|
+
|
|
11
|
+
export function styles() {
|
|
12
|
+
const elementStyles = css`
|
|
13
|
+
:host {
|
|
14
|
+
display: block;
|
|
15
|
+
}
|
|
16
|
+
.slot-parent {
|
|
17
|
+
display: none;
|
|
18
|
+
}
|
|
19
|
+
nav {
|
|
20
|
+
display: none;
|
|
21
|
+
overflow-y: hidden;
|
|
22
|
+
}
|
|
23
|
+
nav.open {
|
|
24
|
+
display: block;
|
|
25
|
+
}
|
|
26
|
+
nav.transitioning {
|
|
27
|
+
display: block;
|
|
28
|
+
}
|
|
29
|
+
.click-attached {
|
|
30
|
+
cursor: pointer;
|
|
31
|
+
}
|
|
32
|
+
@media (min-width: 992px) {
|
|
33
|
+
.slot-parent {
|
|
34
|
+
display: block;
|
|
35
|
+
}
|
|
36
|
+
::slotted(*) {
|
|
37
|
+
min-width: 1.1rem !important;
|
|
38
|
+
max-width: 1.1rem !important;
|
|
39
|
+
width: 1.1rem !important;
|
|
40
|
+
margin-right: .75rem;
|
|
41
|
+
color: #13639e;
|
|
42
|
+
font-size: .875em;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
`;
|
|
46
|
+
|
|
47
|
+
return [
|
|
48
|
+
//normalizeStyles,
|
|
49
|
+
//formStyles,
|
|
50
|
+
menuStyles,
|
|
51
|
+
subNavToggleStyles,
|
|
52
|
+
quickLinkStyles,
|
|
53
|
+
elementStyles
|
|
54
|
+
];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function render() {
|
|
58
|
+
return html`
|
|
59
|
+
${this._hasCustomIcons ? html`
|
|
60
|
+
<style>
|
|
61
|
+
.quick-links--home-site li:first-child a:before {
|
|
62
|
+
content: "";
|
|
63
|
+
display: none;
|
|
64
|
+
}
|
|
65
|
+
.quick-links--home-site li:nth-child(2) a:before {
|
|
66
|
+
content: "";
|
|
67
|
+
display: none;
|
|
68
|
+
}
|
|
69
|
+
.quick-links--home-site li:nth-child(3) a:before {
|
|
70
|
+
content: "";
|
|
71
|
+
display: none;
|
|
72
|
+
}
|
|
73
|
+
</style>
|
|
74
|
+
` : html``}
|
|
75
|
+
<style>
|
|
76
|
+
nav {
|
|
77
|
+
transition: height ${this.animationDuration + "ms"}
|
|
78
|
+
}
|
|
79
|
+
</style>
|
|
80
|
+
<div class="quick-links">
|
|
81
|
+
<button
|
|
82
|
+
class="quick-links__title"
|
|
83
|
+
@click=${this._onBtnClick}
|
|
84
|
+
aria-controls="quick-links"
|
|
85
|
+
aria-expanded="${this.opened}"
|
|
86
|
+
aria-label="Toggle ${this.title} Menu">
|
|
87
|
+
${this.title}<span class="submenu-toggle"><span class="submenu-toggle__icon">+</span></span>
|
|
88
|
+
</button>
|
|
89
|
+
<nav
|
|
90
|
+
id="quick-links"
|
|
91
|
+
class=${classMap(this._getNavClasses())}
|
|
92
|
+
style=${styleMap(this._getNavStyles())}
|
|
93
|
+
aria-label="Quick Links Menu">
|
|
94
|
+
<ul class="menu" id="menu">
|
|
95
|
+
${this._links.map((link, i) => html`
|
|
96
|
+
<li>
|
|
97
|
+
${link.href ? html`
|
|
98
|
+
<a href="${link.href}">${this._renderSlot(link)}${link.text}</a>
|
|
99
|
+
` : html`
|
|
100
|
+
<a
|
|
101
|
+
class="click-attached"
|
|
102
|
+
tabindex="0"
|
|
103
|
+
@click=${this._onItemClick}
|
|
104
|
+
@keyup=${this._onItemKeyup}
|
|
105
|
+
.index=${i}>${this._renderSlot(link)}${link.text}</a>
|
|
106
|
+
`}
|
|
107
|
+
</li>
|
|
108
|
+
`)}
|
|
109
|
+
</ul>
|
|
110
|
+
</nav>
|
|
111
|
+
|
|
112
|
+
</div>
|
|
113
|
+
|
|
114
|
+
`;}
|
|
@@ -1,26 +1,22 @@
|
|
|
1
1
|
import { LitElement } from 'lit';
|
|
2
|
-
import {render, styles } from "./ucd-theme-form
|
|
2
|
+
import {render, styles } from "./ucd-theme-search-form.tpl.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* @class
|
|
5
|
+
* @class UcdThemeSearchForm
|
|
6
6
|
* @classdesc Component class for rendering a basic search form.
|
|
7
|
-
* Pattern Lab Url: http://dev.webstyleguide.ucdavis.edu/redesign/?p=molecules-search-form
|
|
8
7
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
8
|
+
* Pattern Lab Url:
|
|
9
|
+
* - http://dev.webstyleguide.ucdavis.edu/redesign/?p=molecules-search-form
|
|
10
|
+
*
|
|
11
|
+
* @property {String} value - The search string
|
|
12
|
+
* @property {String} placeholder - The input placeholder
|
|
13
|
+
* @property {String} formAction - The action to be taken on form submit (optional)
|
|
12
14
|
*
|
|
13
15
|
* @example
|
|
14
|
-
*
|
|
15
|
-
* html`
|
|
16
|
-
* <ucd-theme-form-search form-action="/url/to/post/to"></ucd-theme-form-search>
|
|
17
|
-
* `
|
|
18
|
-
* // Use event listener:
|
|
19
|
-
* html`
|
|
16
|
+
* <ucd-theme-form-search form-action="/url/to/post/to"></ucd-theme-form-search>
|
|
20
17
|
* <ucd-theme-form-search @search="${this._onSearch}"></ucd-theme-form-search>
|
|
21
|
-
* `
|
|
22
18
|
*/
|
|
23
|
-
export default class
|
|
19
|
+
export default class UcdThemeSearchForm extends LitElement {
|
|
24
20
|
|
|
25
21
|
static get properties() {
|
|
26
22
|
return {
|
|
@@ -51,6 +47,7 @@ export default class UcdThemeFormSearch extends LitElement {
|
|
|
51
47
|
/**
|
|
52
48
|
* @method _onSubmit
|
|
53
49
|
* @description Attached to form submit
|
|
50
|
+
* @private
|
|
54
51
|
* @param {Event} e - submit event
|
|
55
52
|
*/
|
|
56
53
|
_onSubmit(e){
|
|
@@ -64,6 +61,7 @@ export default class UcdThemeFormSearch extends LitElement {
|
|
|
64
61
|
/**
|
|
65
62
|
* @method _onInput
|
|
66
63
|
* @description Attached to search input change
|
|
64
|
+
* @private
|
|
67
65
|
* @param {Event} e - input event
|
|
68
66
|
*/
|
|
69
67
|
_onInput(e){
|
|
@@ -73,6 +71,7 @@ export default class UcdThemeFormSearch extends LitElement {
|
|
|
73
71
|
/**
|
|
74
72
|
* @method _dispatchSearchEvent
|
|
75
73
|
* @description Fires 'search' custom event
|
|
74
|
+
* @private
|
|
76
75
|
*/
|
|
77
76
|
_dispatchSearchEvent() {
|
|
78
77
|
let e = new CustomEvent('search', {
|
|
@@ -88,4 +87,4 @@ export default class UcdThemeFormSearch extends LitElement {
|
|
|
88
87
|
|
|
89
88
|
}
|
|
90
89
|
|
|
91
|
-
customElements.define('ucd-theme-form
|
|
90
|
+
customElements.define('ucd-theme-search-form', UcdThemeSearchForm);
|
|
File without changes
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { LitElement } from 'lit';
|
|
2
|
+
import {render, styles} from "./ucd-theme-search-popup.tpl.js";
|
|
3
|
+
|
|
4
|
+
import { MutationObserverController } from '../../utils/controllers';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @class UcdThemeSearchPopup
|
|
8
|
+
* @classdesc UI component class for displaying a search popup to be used in the site header
|
|
9
|
+
*
|
|
10
|
+
* Patternlab URL:
|
|
11
|
+
* - http://dev.webstyleguide.ucdavis.edu/redesign/?p=molecules-search-popup
|
|
12
|
+
*
|
|
13
|
+
* @property {String} buttonText - The hidden innertext of the popup button.
|
|
14
|
+
* @property {Boolean} opened - Whether the popup is open or not.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* <ucd-theme-search-popup>
|
|
18
|
+
* <ucd-theme-search-form
|
|
19
|
+
* @search="${e => console.log(e.detail.searchTerm)}">
|
|
20
|
+
* </ucd-theme-search-form>
|
|
21
|
+
* </ucd-theme-search-popup>
|
|
22
|
+
*
|
|
23
|
+
* <ucd-theme-search-popup>
|
|
24
|
+
* <input placeholder="A custom search element">
|
|
25
|
+
* </ucd-theme-search-popup>
|
|
26
|
+
*/
|
|
27
|
+
export default class UcdThemeSearchPopup extends LitElement {
|
|
28
|
+
mutationObserver = new MutationObserverController(this);
|
|
29
|
+
|
|
30
|
+
static get properties() {
|
|
31
|
+
return {
|
|
32
|
+
buttonText: {type: String, attribute: "button-text"},
|
|
33
|
+
opened: {type: Boolean},
|
|
34
|
+
_defaultForm: {type: Boolean, state: true}
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
static get styles() {
|
|
39
|
+
return styles();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
constructor() {
|
|
43
|
+
super();
|
|
44
|
+
this.render = render.bind(this);
|
|
45
|
+
this.buttonText = "Toggle Search";
|
|
46
|
+
this.opened = false;
|
|
47
|
+
this._defaultForm = false;
|
|
48
|
+
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* @method open
|
|
53
|
+
* @description Displays the search input if in desktop view
|
|
54
|
+
*/
|
|
55
|
+
open(){
|
|
56
|
+
this.opened = true;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* @method close
|
|
61
|
+
* @description Hides the search input if in desktop view
|
|
62
|
+
*/
|
|
63
|
+
close(){
|
|
64
|
+
this.opened = false;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* @method _onBtnClick
|
|
69
|
+
* @description Attached to popup button
|
|
70
|
+
* @private
|
|
71
|
+
*/
|
|
72
|
+
_onBtnClick(){
|
|
73
|
+
this.opened = !this.opened;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* @method _onChildListMutation
|
|
78
|
+
* @description Fires when there are changes to this element's non-shadow DOM children
|
|
79
|
+
* @private
|
|
80
|
+
*/
|
|
81
|
+
_onChildListMutation(){
|
|
82
|
+
if ( this.querySelector('ucd-theme-search-form') ){
|
|
83
|
+
this._defaultForm = true;
|
|
84
|
+
} else {
|
|
85
|
+
this._defaultForm = false;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
customElements.define('ucd-theme-search-popup', UcdThemeSearchPopup);
|
|
@@ -24,7 +24,14 @@ return html`
|
|
|
24
24
|
<span class="search-popup__open-icon">${this.buttonText}</span>
|
|
25
25
|
</button>
|
|
26
26
|
<div class="search-popup ${this.opened ? 'is-open' : ''}">
|
|
27
|
-
|
|
27
|
+
${this._defaultForm ? html`
|
|
28
|
+
<div class="search-form">
|
|
29
|
+
<slot></slot>
|
|
30
|
+
</div>
|
|
31
|
+
` : html`
|
|
32
|
+
<slot></slot>
|
|
33
|
+
`}
|
|
34
|
+
|
|
28
35
|
</div>
|
|
29
36
|
|
|
30
37
|
`;}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { LitElement } from 'lit';
|
|
2
|
+
import {render, styles} from "./ucd-theme-slim-select.tpl.js";
|
|
3
|
+
|
|
4
|
+
import SlimSelect from 'slim-select';
|
|
5
|
+
|
|
6
|
+
import { MutationObserverController } from '../../utils/controllers';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @class UcdThemeSlimSelect
|
|
10
|
+
* @classdesc UI component class for displaying a fancy select. This is a wrapper element around the 'slim-select' package.
|
|
11
|
+
*
|
|
12
|
+
* Patternlab URL:
|
|
13
|
+
* - http://dev.webstyleguide.ucdavis.edu/redesign/?p=atoms-select-menu
|
|
14
|
+
*/
|
|
15
|
+
export default class UcdThemeSlimSelect extends LitElement {
|
|
16
|
+
mutationObserver = new MutationObserverController(
|
|
17
|
+
this,
|
|
18
|
+
{subtree: true, childList: true, attributes: true, characterData: true},
|
|
19
|
+
"_onLightDomMutation"
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
static get properties() {
|
|
23
|
+
return {
|
|
24
|
+
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
static get styles() {
|
|
29
|
+
return styles();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
constructor() {
|
|
33
|
+
super();
|
|
34
|
+
this.render = render.bind(this);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* @method _onLightDomMutation
|
|
39
|
+
* @private
|
|
40
|
+
* @description Fires when light dom child list changes. Called by MutationObserverController.
|
|
41
|
+
*/
|
|
42
|
+
_onLightDomMutation(){
|
|
43
|
+
const children = Array.from(this.children);
|
|
44
|
+
if (children.length == 0 || children[0].tagName != "SELECT") return;
|
|
45
|
+
const select = children[0].cloneNode(true);
|
|
46
|
+
this.renderRoot.innerHTML= "";
|
|
47
|
+
this.renderRoot.appendChild(select);
|
|
48
|
+
|
|
49
|
+
this.slimSelect = new SlimSelect({
|
|
50
|
+
select: select,
|
|
51
|
+
onChange: (info) => this.dispatchEvent(new CustomEvent("change", {detail: info}))
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
customElements.define('ucd-theme-slim-select', UcdThemeSlimSelect);
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { html, css } from 'lit';
|
|
2
|
+
|
|
3
|
+
import formStyles from "@ucd-lib/theme-sass/2_base_class/_forms.css.js";
|
|
4
|
+
import slimSelectStyles from "@ucd-lib/theme-sass/slim-select.css.js"
|
|
5
|
+
import selectStyles from "@ucd-lib/theme-sass/4_component/_slim-select.css.js";
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
export function styles() {
|
|
10
|
+
const elementStyles = css`
|
|
11
|
+
:host {
|
|
12
|
+
display: block;
|
|
13
|
+
}
|
|
14
|
+
`;
|
|
15
|
+
|
|
16
|
+
return [
|
|
17
|
+
formStyles,
|
|
18
|
+
slimSelectStyles,
|
|
19
|
+
selectStyles,
|
|
20
|
+
elementStyles];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function render() {
|
|
24
|
+
return html`
|
|
25
|
+
|
|
26
|
+
`;}
|