H. lib / js / custom / MdNavigationDrawer.js

1import { abreElementoHtml } from "../abreElementoHtml.js"
2import { cierraElementoHtmo } from "../cierraElementoHtmo.js"
3import { querySelector } from "../querySelector.js"
4
5export class MdNavigationDrawer extends HTMLElement {
6
7 /**
8 * @returns {string}
9 */
10 getHipervinculos() { throw new Error("abstract") }
11
12 getContent() {
13 return /* HTML */`
14
15 <link rel="stylesheet" href="/lib/css/material-symbols-outlined.css">
16 <link rel="stylesheet" href="/lib/css/shape.css">
17 <link rel="stylesheet" href="/lib/css/md-ripple.css">
18
19 <style>
20
21 :host {
22 display: block;
23 }
24
25 :host([hidden]) {
26 display: none;
27 }
28
29 nav {
30 display: none;
31 flex-direction: column;
32 position: fixed;
33 z-index: 4;
34 box-sizing: border-box;
35 top: 0;
36 left: 0;
37 bottom: 0;
38 width: var(--anchoNav);
39 max-width: 80vw;
40 overflow: hidden;
41 overscroll-behavior: contain;
42 background-color: var(--md-sys-color-surface-container-low);
43 transform: translateX(-100%);
44 transition-timing-function:
45 cubic-bezier(var(--md-sys-motion-easing-standard-x0),
46 var(--md-sys-motion-easing-standard-y0),
47 var(--md-sys-motion-easing-standard-x1),
48 var(--md-sys-motion-easing-standard-y1)
49 );
50 transition-property: display, transform;
51 transition-behavior: allow-discrete;
52 transition-duration: var(--md-sys-motion-duration-700);
53 }
54
55 nav.open {
56 display: flex;
57 transform: translateX(0);
58 }
59
60 nav>div {
61 flex-grow: 1;
62 overflow: auto;
63 padding: 0.75rem 1rem;
64 }
65
66 h1 {
67 margin: 0;
68 height: 3.5rem;
69 line-height: 3.5rem;
70 padding: 0 0 0 0.75rem;
71 white-space: nowrap;
72 text-overflow: ellipsis;
73 overflow: hidden;
74 color: var(--md-sys-color-on-surface-variant);
75 font-family: var(--md-sys-typescale-title-small-font);
76 font-weight: var(--md-sys-typescale-title-small-weight);
77 font-size: var(--md-sys-typescale-title-small-size);
78 font-style: var(--md-sys-typescale-title-small-font-style);
79 letter-spacing: var(--md-sys-typescale-title-small-tracking);
80 text-transform: var(--md-sys-typescale-title-small-text-transform);
81 text-decoration: var(--md-sys-typescale-title-small-text-decoration);
82 }
83
84 a::after { /* container inactive */
85 content: "";
86 position: absolute;
87 z-index: -2;
88 top: 0;
89 right: 0;
90 left: 0;
91 bottom: 0;
92 }
93
94 a.active::after { /* container */
95 background-color: var(--md-sys-color-secondary-container);
96 }
97
98 a { /* label, shape inactive */
99 position: relative;
100 display: block;
101 box-sizing: border-box;
102 height: 3.5rem;
103 line-height: 3.5rem;
104 padding: 0 0.75rem;
105 border-radius: 1.75rem;
106 color: var(--md-sys-color-on-surface-variant);
107 font-family: var(--md-sys-typescale-label-large-font);
108 font-weight: var(--md-sys-typescale-label-large-weight);
109 font-size: var(--md-sys-typescale-label-large-size);
110 font-style: var(--md-sys-typescale-label-large-font-style);
111 letter-spacing: var(--md-sys-typescale-label-large-tracking);
112 text-transform: var(--md-sys-typescale-label-large-text-transform);
113 text-decoration: var(--md-sys-typescale-label-large-text-decoration);
114 overflow: hidden;
115 white-space: nowrap;
116 text-overflow: ellipsis;
117 }
118
119 a.active { /* label, shape */
120 font-weight: var(--md-sys-typescale-label-large-weight-prominent);
121 color: var(--md-sys-color-on-secondary-container);
122 }
123
124 a::before { /* state layer */
125 content: "";
126 position: absolute;
127 z-index: -1;
128 top: 0;
129 right: 0;
130 left: 0;
131 bottom: 0;
132 }
133
134 a span { /* inactive icon */
135 position: relative;
136 margin-right: 0.75rem;
137 vertical-align: middle;
138 color: var(--md-sys-color-on-surface-variant);
139 font-size: 1.5rem;
140 width: 1.5rem;
141 height: 1.5rem;
142 }
143
144 a.active span { /* icon */
145 color: var(--md-sys-color-on-secondary-container);
146 }
147
148 #scrim {
149 display: none;
150 position: fixed;
151 z-index: 3;
152 top: 0;
153 left: 0;
154 bottom: 0;
155 right: 0;
156 opacity: 0.4;
157 background-color: var(--md-ref-palette-neutral-variant20);
158 transform: translateX(-100%);
159 transition-timing-function:
160 cubic-bezier(var(--md-sys-motion-easing-standard-x0),
161 var(--md-sys-motion-easing-standard-y0),
162 var(--md-sys-motion-easing-standard-x1),
163 var(--md-sys-motion-easing-standard-y1)
164 );
165 transition-property: display, transform;
166 transition-behavior: allow-discrete;
167 transition-duration: var(--md-sys-motion-duration-700);
168 }
169
170 #scrim.open {
171 display: block;
172 transform: translateX(0);
173 }
174
175 @starting-style {
176 nav.open{
177 display: flex;
178 transform: translateX(-100%);
179 }
180 #scrim.open {
181 display: block;
182 transform: translateX(-100%);
183 }
184 }
185
186 a:hover { /* inactive label, shape */
187 color: var(--md-sys-color-on-surface);
188 }
189
190 a.active:hover { /* active label, shape */
191 color: var(--md-sys-color-on-secondary-container);
192 }
193
194 a:hover::before { /* inactive state layer */
195 background-color: var(--md-sys-color-on-surface);
196 opacity: var(--md-sys-state-hover-state-layer-opacity);
197 }
198
199 a.active:hover::before { /* state layer */
200 background-color: var(--md-sys-color-on-secondary-container);
201 }
202
203 a:hover span { /* inactive icon */
204 color: var(--md-sys-color-on-surface);
205 }
206
207 a.active:hover span { /* icon */
208 color: var(--md-sys-color-on-secondary-container);
209 }
210
211 a:focus { /* inactive label, shape */
212 outline: none;
213 color: var(--md-sys-color-on-surface);
214 }
215
216 a.active:focus { /* label, shape */
217 color: var(--md-sys-color-on-secondary-container);
218 }
219
220 a:focus::before { /* inactive state layer */
221 background-color: var(--md-sys-color-on-surface);
222 opacity: var(--md-sys-state-focus-state-layer-opacity);
223 }
224
225 a.active:focus::before { /* state layer */
226 background-color: var(--md-sys-color-on-secondary-container);
227 }
228
229 a:focus span { /* inactive icon */
230 color: var(--md-sys-color-on-surface);
231 }
232
233 a.active:focus span { /* icon */
234 color: var(--md-sys-color-on-secondary-container);
235 }
236
237 a:active { /* inactive pressed label, shape */
238 background-position: center;
239 background-image:
240 radial-gradient(circle, var(--md-riple-color) 1%, transparent 1%);
241 background-size: 100%;
242 animation-name: md-ripple;
243 animation-duration: var(--md-sys-motion-duration-500);
244 color: var(--md-sys-color-on-surface);
245 }
246
247 a.active:active { /* active pressed label, shape */
248 color: var(--md-sys-color-on-secondary-container);
249 }
250
251 a:active::before { /* inactive pressed state layer */
252 background-color: var(--md-sys-color-on-surface);
253 opacity: var(--md-sys-state-pressed-state-layer-opacity);
254 }
255
256 a.active:active::before { /* active pressed state layer */
257 background-color: var(--md-sys-color-on-secondary-container);
258 }
259
260 a:active span { /* inactive pressed icon */
261 color: var(--md-sys-color-on-surface);
262 }
263
264 a.active:focus span { /* active pressed icon */
265 color: var(--md-sys-color-on-secondary-container);
266 }
267
268 </style>
269
270 <div id="scrim"></div>
271 <nav class="large-end"><div></div></nav>`
272 }
273
274 constructor() {
275 super()
276 const shadow = this.attachShadow({ mode: "open", delegatesFocus: true })
277 shadow.innerHTML = this.getContent()
278 this.cierra = this.cierra.bind(this)
279
280 /** @type {HTMLElement} */
281 this._nav = querySelector(shadow, "nav")
282
283 /** @type {HTMLUListElement} */
284 this._div = querySelector(this._nav, "div")
285
286 /** @type {HTMLUListElement} */
287 this._scrim = querySelector(shadow, "#scrim")
288 this._scrim.addEventListener("click", this.cierra)
289 }
290
291 connectedCallback() {
292 this.classList.add("drawer")
293 this._div.innerHTML = this.getHipervinculos()
294 }
295
296 abre() {
297 abreElementoHtml(this._nav)
298 abreElementoHtml(this._scrim)
299 }
300
301 cierra() {
302 cierraElementoHtmo(this._nav)
303 cierraElementoHtmo(this._scrim)
304 }
305
306}
skip_previous skip_next