Skip to content

Commit 0e2b52d

Browse files
authored
Use side-drawer for settings menu (#125)
1 parent 5a45928 commit 0e2b52d

File tree

5 files changed

+139
-75
lines changed

5 files changed

+139
-75
lines changed

src/components/Menu/Menu.svelte

Lines changed: 68 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -15,52 +15,58 @@
1515
</script>
1616

1717
<div class="menu">
18+
<IconButton icon={"Menu"} label={"Menu"} onClick={handleClick("open")} />
1819
{#if $actions.help !== undefined}
1920
<IconButton icon="Help" label="Help" onClick={$actions.help} />
2021
{/if}
2122
{#if $actions.shuffle !== undefined}
2223
<IconButton icon="Shuffle" label="Shuffle" onClick={$actions.shuffle} />
2324
{/if}
24-
<IconButton icon={"Menu"} label={"Settings"} onClick={handleClick("open")} />
2525
{#if $actions.undo !== undefined}
2626
<IconButton icon="Undo" label="Undo" onClick={$actions.undo} />
2727
{/if}
2828
</div>
2929

3030
{#if open}
31-
<Modal on:close={handleClick("close")} title="Settings">
32-
<table>
33-
<tr>
34-
<th>Game:</th>
35-
<td
36-
><SettingToggle target="game" value="deck" /> / <SettingToggle
37-
target="game"
38-
value="pileon"
39-
/>
40-
</td>
41-
</tr>
42-
<tr>
43-
<th>Colors:</th>
44-
<td
45-
><SettingToggle target="colors" value="default" /> / <SettingToggle
46-
target="colors"
47-
value="standard"
48-
/> / <SettingToggle target="colors" value="four-color" /></td
49-
>
50-
</tr>
51-
<tr>
52-
<th>Size:</th>
53-
<td
54-
><SettingToggle target="size" value="default" /> / <SettingToggle
55-
target="size"
56-
value="bridge"
57-
/> / <SettingToggle target="size" value="poker" /> / <SettingToggle
58-
target="size"
59-
value="small"
60-
/></td
61-
>
62-
</tr>
63-
</table>
31+
<Modal on:close={handleClick("close")} position="left" title="Menu">
32+
<div class="drawer">
33+
<ul>
34+
<li>
35+
<SettingToggle target="game" value="pileon"
36+
>Pileon solitaire</SettingToggle
37+
>
38+
</li>
39+
<li>
40+
<SettingToggle target="game" value="deck">Deck of cards</SettingToggle
41+
>
42+
</li>
43+
</ul>
44+
<div class="whitespace"></div>
45+
<h3>Settings</h3>
46+
<table>
47+
<tr>
48+
<th>Colors:</th>
49+
<td
50+
><SettingToggle target="colors" value="default" /> / <SettingToggle
51+
target="colors"
52+
value="standard"
53+
/> / <SettingToggle target="colors" value="four-color" /></td
54+
>
55+
</tr>
56+
<tr>
57+
<th>Size:</th>
58+
<td
59+
><SettingToggle target="size" value="default" /> / <SettingToggle
60+
target="size"
61+
value="bridge"
62+
/> / <SettingToggle target="size" value="poker" /> / <SettingToggle
63+
target="size"
64+
value="small"
65+
/></td
66+
>
67+
</tr>
68+
</table>
69+
</div>
6470
</Modal>
6571
{/if}
6672

@@ -69,14 +75,34 @@
6975
margin-bottom: 0.25em
7076
text-align: center
7177
72-
table
73-
font-size: 1rem
74-
width: 100%
78+
.drawer
79+
display: flex
80+
height: 100%
81+
flex-direction: column
7582
76-
th,td
77-
padding: 0.5em 0
83+
ul
84+
list-style-type: none
85+
padding: 0
7886
79-
th
80-
padding-right: 1em
81-
text-align: left
87+
li
88+
padding: 1em 0
89+
border-top: 1px solid currentColor
90+
91+
&:last-of-type
92+
border-bottom: 1px solid currentColor
93+
94+
.whitespace
95+
flex: 1
96+
97+
table
98+
font-size: 1rem
99+
margin: 0 0 2em
100+
width: 100%
101+
102+
th,td
103+
padding: 0.5em 0
104+
105+
th
106+
padding-right: 1em
107+
text-align: left
82108
</style>

src/components/Menu/SettingToggle.svelte

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
disabled={pressed}
2121
on:click={onClick}
2222
>
23-
{value}
23+
<slot>{value}</slot>
2424
</button>
2525

2626
<style lang="sass">
@@ -29,6 +29,7 @@
2929
background: transparent
3030
border: none
3131
color: inherit
32+
font: inherit
3233
padding: 0
3334
text-decoration: underline
3435
cursor: pointer

src/components/Modal.svelte

Lines changed: 64 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@
77
import IconButton from "./Menu/IconButton.svelte";
88
99
export let title: string;
10+
export let position: "left" | "center" = "center";
1011
1112
const id = `modal-${randomString()}`;
1213
const titleId = `${id}-title`;
1314
15+
let open = false;
1416
onMount(() => {
1517
const trap = focusTrap.createFocusTrap(`#${id}`, {
1618
clickOutsideDeactivates: true,
@@ -20,6 +22,10 @@
2022
const bodyOverflow = document.body.style.overflow;
2123
document.body.style.overflow = "hidden";
2224
25+
setTimeout(() => {
26+
open = true;
27+
}, 0);
28+
2329
return () => {
2430
trap.deactivate();
2531
document.body.style.overflow = bodyOverflow;
@@ -28,12 +34,19 @@
2834
2935
const dispatch = createEventDispatcher();
3036
const onClose = () => {
31-
dispatch("close");
37+
open = false;
38+
setTimeout(() => dispatch("close"), 125);
3239
};
3340
</script>
3441

35-
<div class="backdrop" />
36-
<div class="modal" role="dialog" aria-labelledby={titleId} {id}>
42+
<div class="backdrop" class:open />
43+
<div
44+
class="modal {position}"
45+
class:open
46+
role="dialog"
47+
aria-labelledby={titleId}
48+
{id}
49+
>
3750
<div class="header">
3851
<h2 id={titleId}>{title}</h2>
3952
<IconButton icon="Close" label="Close" onClick={onClose} />
@@ -45,7 +58,6 @@
4558

4659
<style lang="sass">
4760
.backdrop
48-
animation: blur-background 125ms forwards
4961
position: fixed
5062
top: 0
5163
left: 0
@@ -55,47 +67,70 @@
5567
5668
z-index: 4
5769
58-
@keyframes blur-background
59-
from
60-
backdrop-filter: none
70+
backdrop-filter: none
71+
transition: backdrop-filter 125ms
6172
62-
to
63-
backdrop-filter: blur(4px)
73+
&.open
74+
backdrop-filter: blur(4px)
6475
6576
.modal
66-
animation: open-modal 125ms forwards
6777
display: flex
6878
flex-direction: column
6979
7080
position: fixed
71-
top: 50%
72-
left: 50%
7381
74-
background: white
75-
z-index: 4
82+
&.center
83+
top: 50%
84+
left: 50%
7685
77-
font-size: 1rem
78-
padding: 0 1em 2em
79-
overflow: hidden
86+
max-height: 90%
87+
width: 500px
88+
max-width: 100%
8089
81-
box-sizing: border-box
82-
max-height: 90%
83-
width: 500px
84-
max-width: 100%
90+
padding: 0 1em 2em
8591
86-
box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.75)
92+
box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.75)
8793
88-
@keyframes open-modal
89-
from
90-
opacity: 0
91-
transform: translate(-50%, -25%) scale(0.25)
94+
opacity: 0
95+
transform: translate(-50%, -25%) scale(0.25)
96+
transition: opacity 125ms, transform 125ms
9297
93-
to
98+
&.open
9499
opacity: 1
95100
transform: translate(-50%, -50%) scale(1)
96101
97-
@media (min-width: 501px)
98-
border-radius: 0.25em
102+
@media (min-width: 501px)
103+
border-radius: 0.25em
104+
105+
&.left
106+
top: -2vh
107+
left: 0
108+
109+
height: 104vh
110+
max-width: 95%
111+
112+
.content
113+
flex: 1
114+
115+
padding: 2vh 1em
116+
117+
box-shadow: 0.5rem 0 1rem rgba(0, 0, 0, 0.75)
118+
119+
opacity: 0
120+
transform: translateX(-50%)
121+
transition: opacity 125ms, transform 125ms
122+
123+
&.open
124+
opacity: 1
125+
transform: translateX(0)
126+
127+
background: white
128+
z-index: 4
129+
130+
font-size: 1rem
131+
overflow: hidden
132+
133+
box-sizing: border-box
99134
100135
.header
101136
display: flex

test/App.test.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,10 @@ it("allows shuffling the deck", async () => {
8585
render(App);
8686

8787
// Change game to deck
88-
await userEvent.click(await screen.findByLabelText("Settings"));
89-
await userEvent.click(await screen.findByRole("button", { name: "deck" }));
88+
await userEvent.click(await screen.findByLabelText("Menu"));
89+
await userEvent.click(
90+
await screen.findByRole("button", { name: "Deck of cards" }),
91+
);
9092
await userEvent.click(await screen.findByLabelText("Close"));
9193

9294
const deck = await waitShuffleAnimation();

test/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export const waitShuffleAnimation = async () => {
88

99
await waitFor(
1010
() => expect(deck).not.toHaveAttribute("aria-disabled", "true"),
11-
{ timeout: 1500 },
11+
{ timeout: 2000 },
1212
);
1313
return deck;
1414
};

0 commit comments

Comments
 (0)