|
25 | 25 | <slot />
|
26 | 26 | </div>
|
27 | 27 |
|
28 |
| -<script context="module"> |
29 |
| - import { Corner, CornerBit } from '@material/menu-surface'; |
30 |
| -
|
31 |
| - export { Corner, CornerBit }; |
32 |
| -</script> |
33 |
| - |
34 |
| -<script> |
| 28 | +<script lang="ts"> |
35 | 29 | import { MDCMenuSurfaceFoundation } from '@material/menu-surface';
|
36 | 30 | import { getCorrectPropertyName } from '@material/animation/util.js';
|
37 | 31 | import { onMount, onDestroy, setContext } from 'svelte';
|
|
41 | 35 | classMap,
|
42 | 36 | useActions,
|
43 | 37 | dispatch,
|
| 38 | + ActionArray, |
44 | 39 | } from '@smui/common/internal';
|
45 | 40 |
|
| 41 | + import { Corner, SMUIMenuSurfaceAccessor } from './MenuSurface.types'; |
| 42 | +
|
46 | 43 | const forwardEvents = forwardEventsBuilder(get_current_component());
|
47 | 44 |
|
48 |
| - export let use = []; |
| 45 | + export let use: ActionArray = []; |
49 | 46 | let className = '';
|
50 | 47 | export { className as class };
|
51 | 48 | export let style = '';
|
|
56 | 53 | export let open = isStatic;
|
57 | 54 | export let fullWidth = false;
|
58 | 55 | export let quickOpen = false;
|
59 |
| - export let anchorElement = null; |
60 |
| - export let anchorCorner = null; |
| 56 | + export let anchorElement: Element | undefined = undefined; |
| 57 | + export let anchorCorner: Corner | keyof typeof Corner | undefined = undefined; |
61 | 58 | export let anchorMargin = { top: 0, right: 0, bottom: 0, left: 0 };
|
62 | 59 | export let maxHeight = 0;
|
63 | 60 | export let horizontallyCenteredOnViewport = false;
|
64 | 61 |
|
65 |
| - let element; |
66 |
| - let instance; |
67 |
| - let internalClasses = {}; |
68 |
| - let internalStyles = {}; |
69 |
| - let previousFocus; |
| 62 | + let element: HTMLDivElement; |
| 63 | + let instance: MDCMenuSurfaceFoundation; |
| 64 | + let internalClasses: { [k: string]: boolean } = {}; |
| 65 | + let internalStyles: { [k: string]: string } = {}; |
| 66 | + let previousFocus: Element | undefined = undefined; |
70 | 67 |
|
71 | 68 | setContext('SMUI:list:role', 'menu');
|
72 | 69 | setContext('SMUI:list:item:role', 'menuitem');
|
73 | 70 |
|
74 | 71 | $: if (
|
75 | 72 | element &&
|
76 | 73 | anchor &&
|
77 |
| - !element.parentNode.classList.contains('mdc-menu-surface--anchor') |
| 74 | + !element.parentElement?.classList.contains('mdc-menu-surface--anchor') |
78 | 75 | ) {
|
79 |
| - element.parentNode.classList.add('mdc-menu-surface--anchor'); |
80 |
| - anchorElement = element.parentNode; |
| 76 | + element.parentElement?.classList.add('mdc-menu-surface--anchor'); |
| 77 | + anchorElement = element.parentElement ?? undefined; |
81 | 78 | }
|
82 | 79 |
|
83 | 80 | $: if (instance && instance.isOpen() !== open) {
|
|
107 | 104 | }
|
108 | 105 |
|
109 | 106 | const iCorner = Corner;
|
110 |
| - const iCornerBit = CornerBit; |
111 | 107 | $: if (instance && anchorCorner != null) {
|
112 |
| - if (iCorner.hasOwnProperty(anchorCorner)) { |
| 108 | + if (typeof anchorCorner === 'string') { |
113 | 109 | instance.setAnchorCorner(iCorner[anchorCorner]);
|
114 |
| - } else if (iCornerBit.hasOwnProperty(anchorCorner)) { |
115 |
| - instance.setAnchorCorner(iCornerBit[anchorCorner]); |
116 | 110 | } else {
|
117 | 111 | instance.setAnchorCorner(anchorCorner);
|
118 | 112 | }
|
|
157 | 151 |
|
158 | 152 | isFocused: () => document.activeElement === element,
|
159 | 153 | saveFocus: () => {
|
160 |
| - previousFocus = document.activeElement; |
| 154 | + previousFocus = document.activeElement ?? undefined; |
161 | 155 | },
|
162 | 156 | restoreFocus: () => {
|
163 | 157 | if (
|
164 | 158 | element.contains(document.activeElement) &&
|
165 | 159 | previousFocus &&
|
166 |
| - previousFocus.focus |
| 160 | + 'focus' in previousFocus |
167 | 161 | ) {
|
168 |
| - previousFocus.focus(); |
| 162 | + (previousFocus as HTMLInputElement).focus(); |
169 | 163 | }
|
170 | 164 | },
|
171 | 165 |
|
|
201 | 195 | },
|
202 | 196 | });
|
203 | 197 |
|
204 |
| - dispatch(element, 'SMUI:menu-surface:mount', { |
| 198 | + const accessor: SMUIMenuSurfaceAccessor = { |
205 | 199 | get open() {
|
206 | 200 | return open;
|
207 | 201 | },
|
208 | 202 | set open(value) {
|
209 | 203 | open = value;
|
210 | 204 | },
|
211 | 205 | closeProgrammatic,
|
212 |
| - }); |
| 206 | + }; |
| 207 | +
|
| 208 | + dispatch(element, 'SMUI:menu-surface:mount', accessor); |
213 | 209 |
|
214 | 210 | instance.init();
|
215 | 211 |
|
216 | 212 | return () => {
|
217 |
| - const isHoisted = instance.isHoistedElement; |
| 213 | + const isHoisted = (instance as any).isHoistedElement; |
218 | 214 | instance.destroy();
|
219 | 215 | if (isHoisted) {
|
220 |
| - element.parentNode.removeChild(element); |
| 216 | + element.parentNode?.removeChild(element); |
221 | 217 | }
|
222 | 218 | };
|
223 | 219 | });
|
224 | 220 |
|
225 | 221 | onDestroy(() => {
|
226 | 222 | if (anchor) {
|
227 | 223 | element &&
|
228 |
| - element.parentNode.classList.remove('mdc-menu-surface--anchor'); |
| 224 | + element.parentElement?.classList.remove('mdc-menu-surface--anchor'); |
229 | 225 | }
|
230 | 226 | });
|
231 | 227 |
|
232 |
| - function hasClass(className) { |
| 228 | + function hasClass(className: string) { |
233 | 229 | return className in internalClasses
|
234 | 230 | ? internalClasses[className]
|
235 | 231 | : getElement().classList.contains(className);
|
236 | 232 | }
|
237 | 233 |
|
238 |
| - function addClass(className) { |
| 234 | + function addClass(className: string) { |
239 | 235 | if (!internalClasses[className]) {
|
240 | 236 | internalClasses[className] = true;
|
241 | 237 | }
|
242 | 238 | }
|
243 | 239 |
|
244 |
| - function removeClass(className) { |
| 240 | + function removeClass(className: string) { |
245 | 241 | if (!(className in internalClasses) || internalClasses[className]) {
|
246 | 242 | internalClasses[className] = false;
|
247 | 243 | }
|
248 | 244 | }
|
249 | 245 |
|
250 |
| - function closeProgrammatic(skipRestoreFocus) { |
| 246 | + function closeProgrammatic(skipRestoreFocus?: boolean) { |
251 | 247 | instance.close(skipRestoreFocus);
|
252 | 248 | open = false;
|
253 | 249 | }
|
|
256 | 252 | return open;
|
257 | 253 | }
|
258 | 254 |
|
259 |
| - export function setOpen(value) { |
| 255 | + export function setOpen(value: boolean) { |
260 | 256 | open = value;
|
261 | 257 | }
|
262 | 258 |
|
263 |
| - export function setAbsolutePosition(...args) { |
264 |
| - return instance.setAbsolutePosition(...args); |
| 259 | + export function setAbsolutePosition(x: number, y: number) { |
| 260 | + return instance.setAbsolutePosition(x, y); |
265 | 261 | }
|
266 | 262 |
|
267 |
| - export function setIsHoisted(...args) { |
268 |
| - return instance.setIsHoisted(...args); |
| 263 | + export function setIsHoisted(isHoisted: boolean) { |
| 264 | + return instance.setIsHoisted(isHoisted); |
269 | 265 | }
|
270 | 266 |
|
271 | 267 | export function getElement() {
|
|
0 commit comments