1 | import { ES_APPLE } from "../const/ES_APPLE.js" |
2 | import { getAttribute } from "../getAttribute.js" |
3 | import { querySelector } from "../querySelector.js" |
4 | |
5 | class MdTopAppBar extends HTMLElement { |
6 | |
7 | getContent() { |
8 | return ` |
9 | <style> |
10 | |
11 | :host { |
12 | display: flex; |
13 | box-sizing: border-box; |
14 | align-items: center; |
15 | padding: 0 0.25rem; |
16 | background-color: var(--md-sys-color-surface); |
17 | position: sticky; |
18 | z-index: 1; |
19 | left: env(titlebar-area-x, 0); |
20 | top: env(titlebar-area-y, 0); |
21 | height: env(titlebar-area-height, 4rem); |
22 | width: env(titlebar-area-width, 100%); |
23 | } |
24 | |
25 | :host(.apple) { |
26 | height: env(titlebar-area-height, 3rem); |
27 | } |
28 | |
29 | :host(.scroll) { |
30 | background-color: var(--md-sys-color-surface-container-low); |
31 | } |
32 | |
33 | #navigation { |
34 | flex: 0 0 auto; |
35 | overflow: hidden |
36 | } |
37 | |
38 | #navigation ::slotted(*) { |
39 | color: var(--md-sys-color-on-surface); |
40 | } |
41 | |
42 | #acciones { |
43 | margin-left: auto; |
44 | flex: 0 0 auto; |
45 | overflow: hidden |
46 | } |
47 | |
48 | :host(.centrado) #acciones, |
49 | :host(.center-aligned) #acciones { |
50 | flex: 0 0 3rem; |
51 | overflow: hidden |
52 | } |
53 | |
54 | #headline::slotted(*) { |
55 | -webkit-app-region: drag; |
56 | flex: 1 1 auto; |
57 | white-space: nowrap; |
58 | text-overflow: ellipsis; |
59 | overflow: hidden; |
60 | font-family: var(--md-sys-typescale-title-large-font); |
61 | font-weight: var(--md-sys-typescale-title-large-weight); |
62 | font-size: var(--md-sys-typescale-title-large-size); |
63 | font-style: var(--md-sys-typescale-title-large-font-style); |
64 | letter-spacing: var(--md-sys-typescale-title-large-tracking); |
65 | line-height: var(--md-sys-typescale-title-large-line-height); |
66 | text-transform: var(--md-sys-typescale-title-large-text-transform); |
67 | text-decoration: var(--md-sys-typescale-title-large-text-decoration); |
68 | color: var(--md-sys-color-on-surface); |
69 | } |
70 | |
71 | :host(.center-aligned) #headline::slotted(*) { |
72 | flex: 1 1 auto; |
73 | text-align: center |
74 | } |
75 | |
76 | </style> |
77 | |
78 | <span id="navigation"> |
79 | <slot name="navigation"></slot> |
80 | </span> |
81 | <slot id="headline"></slot> |
82 | <span id="acciones"> |
83 | <slot name="action"></slot> |
84 | </span>` |
85 | } |
86 | |
87 | constructor() { |
88 | super() |
89 | if (ES_APPLE) { |
90 | document.body.classList.add("apple") |
91 | document.body.classList.remove("material") |
92 | } else { |
93 | document.body.classList.add("material") |
94 | document.body.classList.remove("apple") |
95 | } |
96 | |
97 | |
98 | |
99 | |
100 | |
101 | const shadow = this.attachShadow({ mode: "open" }) |
102 | shadow.innerHTML = this.getContent() |
103 | this._configuraAction = this._configuraAction.bind(this) |
104 | |
105 | |
106 | |
107 | |
108 | this._posY = 0 |
109 | |
110 | |
111 | |
112 | |
113 | this._scrolling = false |
114 | |
115 | |
116 | |
117 | |
118 | this._navigation = querySelector(shadow, '[name="navigation"]') |
119 | |
120 | |
121 | |
122 | |
123 | this._action = querySelector(shadow, '[name="action"]') |
124 | |
125 | |
126 | |
127 | |
128 | this._headline = null |
129 | |
130 | |
131 | |
132 | |
133 | this._adicional = null |
134 | this._action.addEventListener("slotchange", this._configuraAction) |
135 | addEventListener("scroll", () => this._onScroll()) |
136 | addEventListener("load", () => this.configurOtros()) |
137 | } |
138 | |
139 | connectedCallback() { |
140 | this.role = "toolbar" |
141 | this._configuraAction() |
142 | } |
143 | |
144 | configurOtros() { |
145 | const idHeadline = getAttribute(this, "headline") |
146 | if (idHeadline !== "") { |
147 | const headline = document.getElementById(idHeadline) |
148 | if (headline instanceof HTMLHeadingElement) { |
149 | this._headline = headline |
150 | if (this.classList.contains("apple") || this.classList.contains("medium")) { |
151 | headline.classList.add("md-headline", "headline-small") |
152 | } else { |
153 | headline.classList.add("md-headline", "headline-medium") |
154 | } |
155 | } |
156 | } |
157 | const idAdicional = getAttribute(this, "adicional") |
158 | if (idAdicional !== "") { |
159 | this._adicional = document.getElementById(idAdicional) |
160 | if (this._adicional !== null) { |
161 | if (this.classList.contains("apple")) { |
162 | this._adicional.style.top = "env(titlebar-area-height, 3rem)" |
163 | } else { |
164 | this._adicional.style.top = "env(titlebar-area-height, 4rem)" |
165 | } |
166 | } |
167 | } |
168 | } |
169 | |
170 | _configuraAction() { |
171 | const assignedElements = this._action.assignedElements() |
172 | if (this.isConnected) { |
173 | if (ES_APPLE) { |
174 | this.classList.add("apple") |
175 | this.classList.remove("material") |
176 | } else { |
177 | this.classList.add("material") |
178 | this.classList.remove("apple") |
179 | } |
180 | if (this.classList.contains("center-aligned")) { |
181 | this.classList.remove("centrado") |
182 | this.classList.remove("justificado") |
183 | } else { |
184 | if (ES_APPLE && assignedElements.length <= 1) { |
185 | this.classList.add("centrado") |
186 | this.classList.remove("justificado") |
187 | } else { |
188 | this.classList.add("justificado") |
189 | this.classList.remove("centrado") |
190 | } |
191 | } |
192 | } |
193 | } |
194 | |
195 | |
196 | _onScroll() { |
197 | this._posY = scrollY |
198 | if (!this._scrolling) { |
199 | requestAnimationFrame(() => this._avanza()) |
200 | } |
201 | this._scrolling = true |
202 | } |
203 | |
204 | |
205 | _avanza() { |
206 | if (this._posY === 0) { |
207 | this.classList.remove("scroll") |
208 | if (this._headline !== null) { |
209 | if (this._adicional === null) { |
210 | this._headline.classList.remove("scroll") |
211 | } else { |
212 | this._headline.classList.remove("scroll-adicional") |
213 | } |
214 | } |
215 | if (this._adicional !== null) { |
216 | this._adicional.classList.remove("scroll") |
217 | } |
218 | } else { |
219 | this.classList.add("scroll") |
220 | if (this._headline !== null) { |
221 | if (this._adicional === null) { |
222 | this._headline.classList.add("scroll") |
223 | } else { |
224 | this._headline.classList.add("scroll-adicional") |
225 | } |
226 | } |
227 | if (this._adicional !== null) { |
228 | this._adicional.classList.add("scroll") |
229 | } |
230 | } |
231 | this._scrolling = false |
232 | } |
233 | |
234 | } |
235 | |
236 | customElements.define("md-top-app-bar", MdTopAppBar) |