1 | import { abreElementoHtml } from "../abreElementoHtml.js" |
2 | import { cierraElementoHtmo } from "../cierraElementoHtmo.js" |
3 | import { querySelector } from "../querySelector.js" |
4 | |
5 | export class MdNavigationDrawer extends HTMLElement { |
6 | |
7 | |
8 | |
9 | |
10 | getHipervinculos() { throw new Error("abstract") } |
11 | |
12 | getContent() { |
13 | return ` |
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 | |
281 | this._nav = querySelector(shadow, "nav") |
282 | |
283 | |
284 | this._div = querySelector(this._nav, "div") |
285 | |
286 | |
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 | } |