Skip to content

Commit b479315

Browse files
committed
feat: migrate menu surface and menu to typescript
1 parent e012927 commit b479315

39 files changed

+214
-1268
lines changed

packages/common/Events.d.ts

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export interface SMUIEventDetail {}
2+
3+
export interface SMUIEvent<T extends SMUIEventDetail = SMUIEventDetail>
4+
extends Event {
5+
detail?: T;
6+
}

packages/common/dispatch.ts

+1-6
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,4 @@
1-
export interface SMUIEventDetail {}
2-
3-
export interface SMUIEvent<T extends SMUIEventDetail = SMUIEventDetail>
4-
extends Event {
5-
detail?: T;
6-
}
1+
import type { SMUIEventDetail, SMUIEvent } from './Events.d';
72

83
export function dispatch<T extends SMUIEventDetail = SMUIEventDetail>(
94
element: Element | { getElement: () => Element },

packages/common/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ export { Label, Icon };
55
export * from './SMUIComponent.d';
66
export * from './SMUIInputAccessors.d';
77
export * from './LayoutListener.d';
8+
export * from './Events.d';

packages/form-field/FormField.svelte

+1-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
</script>
2525

2626
<script lang="ts">
27-
import type { SMUIGenericInputAccessor } from '@smui/common';
27+
import type { SMUIEvent, SMUIGenericInputAccessor } from '@smui/common';
2828
import { MDCFormFieldFoundation } from '@material/form-field';
2929
import { onMount, setContext } from 'svelte';
3030
import { get_current_component } from 'svelte/internal';
@@ -35,7 +35,6 @@
3535
prefixFilter,
3636
useActions,
3737
ActionArray,
38-
SMUIEvent,
3938
} from '@smui/common/internal';
4039
4140
const forwardEvents = forwardEventsBuilder(get_current_component());

packages/list/Item.svelte

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
import type {
6666
SMUICheckboxInputAccessor,
6767
SMUIComponent,
68+
SMUIEvent,
6869
SMUIGenericInputAccessor,
6970
SMUIRadioInputAccessor,
7071
} from '@smui/common';
@@ -75,7 +76,6 @@
7576
classMap,
7677
dispatch,
7778
ActionArray,
78-
SMUIEvent,
7979
} from '@smui/common/internal';
8080
import Ripple from '@smui/ripple';
8181
import A from '@smui/common/A.svelte';

packages/list/List.svelte

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
AddLayoutListener,
4848
RemoveLayoutListener,
4949
SMUIComponent,
50+
SMUIEvent,
5051
} from '@smui/common';
5152
import { MDCListFoundation } from '@material/list';
5253
import { ponyfill } from '@material/dom';
@@ -57,7 +58,6 @@
5758
classMap,
5859
dispatch,
5960
ActionArray,
60-
SMUIEvent,
6161
} from '@smui/common/internal';
6262
import Ul from '@smui/common/Ul.svelte';
6363
import Nav from '@smui/common/Nav.svelte';

packages/menu-surface/Anchor.js renamed to packages/menu-surface/Anchor.ts

+7-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
1+
export type AnchorProps = {
2+
addClass?: (className: string) => void;
3+
removeClass?: (className: string) => void;
4+
};
5+
16
export default function Anchor(
2-
node,
7+
node: HTMLElement,
38
{
49
addClass = (className) => node.classList.add(className),
510
removeClass = (className) => node.classList.remove(className),
6-
} = {}
11+
}: AnchorProps = {}
712
) {
813
addClass('mdc-menu-surface--anchor');
914

packages/menu-surface/MenuSurface.svelte

+35-39
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,7 @@
2525
<slot />
2626
</div>
2727

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">
3529
import { MDCMenuSurfaceFoundation } from '@material/menu-surface';
3630
import { getCorrectPropertyName } from '@material/animation/util.js';
3731
import { onMount, onDestroy, setContext } from 'svelte';
@@ -41,11 +35,14 @@
4135
classMap,
4236
useActions,
4337
dispatch,
38+
ActionArray,
4439
} from '@smui/common/internal';
4540
41+
import { Corner, SMUIMenuSurfaceAccessor } from './MenuSurface.types';
42+
4643
const forwardEvents = forwardEventsBuilder(get_current_component());
4744
48-
export let use = [];
45+
export let use: ActionArray = [];
4946
let className = '';
5047
export { className as class };
5148
export let style = '';
@@ -56,28 +53,28 @@
5653
export let open = isStatic;
5754
export let fullWidth = false;
5855
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;
6158
export let anchorMargin = { top: 0, right: 0, bottom: 0, left: 0 };
6259
export let maxHeight = 0;
6360
export let horizontallyCenteredOnViewport = false;
6461
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;
7067
7168
setContext('SMUI:list:role', 'menu');
7269
setContext('SMUI:list:item:role', 'menuitem');
7370
7471
$: if (
7572
element &&
7673
anchor &&
77-
!element.parentNode.classList.contains('mdc-menu-surface--anchor')
74+
!element.parentElement?.classList.contains('mdc-menu-surface--anchor')
7875
) {
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;
8178
}
8279
8380
$: if (instance && instance.isOpen() !== open) {
@@ -107,12 +104,9 @@
107104
}
108105
109106
const iCorner = Corner;
110-
const iCornerBit = CornerBit;
111107
$: if (instance && anchorCorner != null) {
112-
if (iCorner.hasOwnProperty(anchorCorner)) {
108+
if (typeof anchorCorner === 'string') {
113109
instance.setAnchorCorner(iCorner[anchorCorner]);
114-
} else if (iCornerBit.hasOwnProperty(anchorCorner)) {
115-
instance.setAnchorCorner(iCornerBit[anchorCorner]);
116110
} else {
117111
instance.setAnchorCorner(anchorCorner);
118112
}
@@ -157,15 +151,15 @@
157151
158152
isFocused: () => document.activeElement === element,
159153
saveFocus: () => {
160-
previousFocus = document.activeElement;
154+
previousFocus = document.activeElement ?? undefined;
161155
},
162156
restoreFocus: () => {
163157
if (
164158
element.contains(document.activeElement) &&
165159
previousFocus &&
166-
previousFocus.focus
160+
'focus' in previousFocus
167161
) {
168-
previousFocus.focus();
162+
(previousFocus as HTMLInputElement).focus();
169163
}
170164
},
171165
@@ -201,53 +195,55 @@
201195
},
202196
});
203197
204-
dispatch(element, 'SMUI:menu-surface:mount', {
198+
const accessor: SMUIMenuSurfaceAccessor = {
205199
get open() {
206200
return open;
207201
},
208202
set open(value) {
209203
open = value;
210204
},
211205
closeProgrammatic,
212-
});
206+
};
207+
208+
dispatch(element, 'SMUI:menu-surface:mount', accessor);
213209
214210
instance.init();
215211
216212
return () => {
217-
const isHoisted = instance.isHoistedElement;
213+
const isHoisted = (instance as any).isHoistedElement;
218214
instance.destroy();
219215
if (isHoisted) {
220-
element.parentNode.removeChild(element);
216+
element.parentNode?.removeChild(element);
221217
}
222218
};
223219
});
224220
225221
onDestroy(() => {
226222
if (anchor) {
227223
element &&
228-
element.parentNode.classList.remove('mdc-menu-surface--anchor');
224+
element.parentElement?.classList.remove('mdc-menu-surface--anchor');
229225
}
230226
});
231227
232-
function hasClass(className) {
228+
function hasClass(className: string) {
233229
return className in internalClasses
234230
? internalClasses[className]
235231
: getElement().classList.contains(className);
236232
}
237233
238-
function addClass(className) {
234+
function addClass(className: string) {
239235
if (!internalClasses[className]) {
240236
internalClasses[className] = true;
241237
}
242238
}
243239
244-
function removeClass(className) {
240+
function removeClass(className: string) {
245241
if (!(className in internalClasses) || internalClasses[className]) {
246242
internalClasses[className] = false;
247243
}
248244
}
249245
250-
function closeProgrammatic(skipRestoreFocus) {
246+
function closeProgrammatic(skipRestoreFocus?: boolean) {
251247
instance.close(skipRestoreFocus);
252248
open = false;
253249
}
@@ -256,16 +252,16 @@
256252
return open;
257253
}
258254
259-
export function setOpen(value) {
255+
export function setOpen(value: boolean) {
260256
open = value;
261257
}
262258
263-
export function setAbsolutePosition(...args) {
264-
return instance.setAbsolutePosition(...args);
259+
export function setAbsolutePosition(x: number, y: number) {
260+
return instance.setAbsolutePosition(x, y);
265261
}
266262
267-
export function setIsHoisted(...args) {
268-
return instance.setIsHoisted(...args);
263+
export function setIsHoisted(isHoisted: boolean) {
264+
return instance.setIsHoisted(isHoisted);
269265
}
270266
271267
export function getElement() {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { Corner } from '@material/menu-surface';
2+
3+
export { Corner };
4+
5+
export interface SMUIMenuSurfaceAccessor {
6+
open: boolean;
7+
closeProgrammatic(skipRestoreFocus?: boolean): void;
8+
}

packages/menu-surface/bare.js

-2
This file was deleted.

packages/menu-surface/bare.ts

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from './index';
2+
export { default } from './index';

packages/menu-surface/index.js

-7
This file was deleted.

packages/menu-surface/index.ts

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import MenuSurface from './MenuSurface.svelte';
2+
export * from './MenuSurface.types';
3+
4+
import Anchor from './Anchor';
5+
export * from './Anchor';
6+
7+
export default MenuSurface;
8+
9+
export { Anchor };

0 commit comments

Comments
 (0)