WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Commit 312b92a

Browse files
committed
chore: Manage text direction and motion disabled via URL query params
1 parent 801da94 commit 312b92a

File tree

2 files changed

+83
-14
lines changed

2 files changed

+83
-14
lines changed

pages/app/page.tsx

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,38 @@
11
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
// SPDX-License-Identifier: Apache-2.0
33
import { Suspense } from "react";
4-
import { useEffect, useState } from "react";
54

65
import { SpaceBetween, Toggle } from "@cloudscape-design/components";
7-
import { applyDensity, applyMode, Density, Mode } from "@cloudscape-design/global-styles";
6+
import { Density, Mode } from "@cloudscape-design/global-styles";
87

98
import { pagesMap } from "../pages";
109
import PageLayout from "./page-layout";
10+
import useModes from "./use-modes";
1111

1212
export interface PageProps {
1313
pageId: string;
1414
}
1515

1616
export default function Page({ pageId }: PageProps) {
1717
const Component = pagesMap[pageId];
18-
const [dark, setDark] = useState(false);
19-
const [compact, setCompact] = useState(false);
20-
21-
useEffect(() => {
22-
applyMode(dark ? Mode.Dark : Mode.Light, document.documentElement);
23-
}, [dark]);
24-
25-
useEffect(() => {
26-
applyDensity(compact ? Density.Compact : Density.Comfortable, document.documentElement);
27-
}, [compact]);
18+
const { mode, density, setParams } = useModes();
2819

2920
return (
3021
<PageLayout>
3122
<Suspense fallback="Loading">
3223
<SpaceBetween direction="vertical" size="m">
3324
<a href="/index.html#">Back to all pages</a>
3425
<SpaceBetween direction="horizontal" size="m">
35-
<Toggle checked={dark} onChange={(event) => setDark(event.detail.checked)}>
26+
<Toggle
27+
checked={mode === Mode.Dark}
28+
onChange={(event) => setParams({ mode: event.detail.checked ? Mode.Dark : Mode.Light })}
29+
>
3630
Dark mode
3731
</Toggle>
38-
<Toggle checked={compact} onChange={(event) => setCompact(event.detail.checked)}>
32+
<Toggle
33+
checked={density == Density.Compact}
34+
onChange={(event) => setParams({ density: event.detail.checked ? Density.Compact : Density.Comfortable })}
35+
>
3936
Compact mode
4037
</Toggle>
4138
</SpaceBetween>

pages/app/use-modes.tsx

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
import { useEffect } from "react";
4+
import { useSearchParams } from "react-router-dom";
5+
6+
import { applyDensity, applyMode, Density, disableMotion, Mode } from "@cloudscape-design/global-styles";
7+
8+
export interface AppUrlParams {
9+
mode: Mode;
10+
density: Density;
11+
direction: "ltr" | "rtl";
12+
motionDisabled: boolean;
13+
}
14+
15+
export const defaults: AppUrlParams = {
16+
mode: Mode.Light,
17+
density: Density.Comfortable,
18+
direction: "ltr",
19+
motionDisabled: false,
20+
};
21+
22+
function castToBoolean(s: string) {
23+
if (s === "true" || s === "false") {
24+
return s === "true";
25+
}
26+
return s;
27+
}
28+
29+
export function parseQuery(urlParams: URLSearchParams) {
30+
const queryParams: Record<string, any> = { ...defaults };
31+
urlParams.forEach((value, key) => (queryParams[key] = castToBoolean(value)));
32+
return queryParams as AppUrlParams;
33+
}
34+
35+
export function formatQuery(params: AppUrlParams) {
36+
const query: Record<string, string> = {};
37+
for (const [key, value] of Object.entries(params)) {
38+
if (value === defaults[key as keyof AppUrlParams]) {
39+
continue;
40+
}
41+
query[key] = String(value);
42+
}
43+
return query;
44+
}
45+
46+
export default function useModes() {
47+
const [searchParams, setSearchParams] = useSearchParams();
48+
const urlParams = parseQuery(searchParams);
49+
const { density, direction, mode, motionDisabled } = urlParams;
50+
51+
function setParams(newParams: Partial<AppUrlParams>) {
52+
setSearchParams(formatQuery({ ...urlParams, ...newParams }));
53+
}
54+
55+
useEffect(() => {
56+
applyMode(mode);
57+
}, [mode]);
58+
59+
useEffect(() => {
60+
applyDensity(density);
61+
}, [density]);
62+
63+
useEffect(() => {
64+
disableMotion(motionDisabled);
65+
}, [motionDisabled]);
66+
67+
useEffect(() => {
68+
document.documentElement.setAttribute("dir", direction);
69+
}, [direction]);
70+
71+
return { density, direction, mode, motionDisabled, setParams };
72+
}

0 commit comments

Comments
 (0)