Skip to content

Commit 1dd438f

Browse files
committed
chore: material symbols setup
1 parent a4b744a commit 1dd438f

12 files changed

Lines changed: 147 additions & 188 deletions

File tree

apps/docs/src/app/(main)/(markdown)/(demos)/components/icon/layout.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1-
import type { Metadata } from "next";
1+
import { type Metadata } from "next";
22
import Script from "next/script.js";
33
import { type PropsWithChildren, type ReactElement } from "react";
44

5+
import { EVERY_ICON_AND_SYMBOL_GOOGLE_FONT_URL } from "@/constants/googleFontsApi.js";
6+
57
export const metadata: Metadata = {
68
icons: {
79
other: [
810
{
911
rel: "stylesheet",
10-
url: "https://fonts.googleapis.com/css2?family=Material+Icons&family=Material+Icons+Outlined&family=Material+Icons+Round&family=Material+Icons+Sharp&family=Material+Icons+Two+Tone&family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200&family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200&family=Material+Symbols+Sharp:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200&display=block",
12+
url: EVERY_ICON_AND_SYMBOL_GOOGLE_FONT_URL,
1113
},
1214
],
1315
},

apps/docs/src/app/(main)/(markdown)/customization/material-symbols/page.mdx

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,47 @@ keywords: [icon, symbol, material, fonts, google]
1616
1717
## Usage with [next.js]
1818

19+
The easiest way to use Material Symbols with next.js is to create a list of
20+
used symbol names and add it to a layout's metadata:
21+
22+
```diff src/app/layout.tsx
23+
import { RootHtml } from "@react-md/core/RootHtml";
24+
+import { getMaterialSymbolsUrl } from "@react-md/core/icon/getMaterialSymbolsUrl";
25+
+import { type MaterialSymbolName } from "@react-md/core/icon/material";
26+
+import { DEFAULT_MATERIAL_SYMBOL_NAMES } from "@react-md/core/icon/symbols";
27+
import { type Metadata } from "next";
28+
import { Roboto_Flex } from "next/font/google";
29+
import { type ReactElement, type ReactNode } from "react";
30+
31+
import { RootProviders } from "@/components/RootProviders.js";
32+
33+
+const names = [
34+
+ ...DEFAULT_MATERIAL_SYMBOL_NAMES,
35+
+ "more_vert",
36+
+ "light_mode",
37+
+ "dark_mode",
38+
+ "devices",
39+
+ "code_off",
40+
+ "deployed_code",
41+
+ "code_blocks",
42+
+ "markdown",
43+
+ "content_copy",
44+
+] satisfies readonly MaterialSymbolName[];
45+
46+
export const metadata: Metadata = {
47+
title: "Your App Name",
48+
+ icons: {
49+
+ other: [
50+
+ {
51+
+ rel: "stylesheet",
52+
+ url: getMaterialSymbolsUrl({ names }),
53+
+ },
54+
+ ],
55+
+ },
56+
};
57+
58+
```
59+
1960
## Usage with [vite]
2061

2162
A simple vite plugin can be installed and added to the `vite.config.ts` that

apps/docs/src/app/(main)/components/material-icons-and-symbols/MaterialSymbolStylesheets.tsx

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,38 @@
1+
import { getMaterialSymbolsUrl } from "@react-md/core/icon/getMaterialSymbolsUrl";
2+
import {
3+
type MaterialIconFamily,
4+
type MaterialSymbolFamily,
5+
} from "@react-md/core/icon/material";
16
import { Typography } from "@react-md/core/typography/Typography";
27
import { type ReactElement } from "react";
38

49
import { CopyCode } from "./CopyCode.js";
510
import { useMaterialIconsAndSymbols } from "./MaterialIconsAndSymbolsProvider.js";
6-
import { getFontStylesheet } from "./utils.js";
11+
12+
function assertSymbol(
13+
iconFamily: MaterialIconFamily
14+
): asserts iconFamily is MaterialSymbolFamily {
15+
if (iconFamily === "filled" || iconFamily === "two-tone") {
16+
throw new Error("Invalid MaterialSymbol family");
17+
}
18+
}
719

820
export function MaterialSymbolStylesheets(): ReactElement {
921
const { iconFamily, fill, grade, weight, opticalSize } =
1022
useMaterialIconsAndSymbols();
1123

12-
const variableHref = getFontStylesheet({
13-
iconType: "symbol",
14-
iconFamily,
24+
assertSymbol(iconFamily);
25+
const variableHref = getMaterialSymbolsUrl({
26+
names: [],
27+
family: iconFamily,
28+
fill: { min: 0, max: 1 },
29+
grade: { min: -25, max: 200 },
30+
opticalSize: { min: 20, max: 48 },
31+
weight: { min: 100, max: 700 },
1532
});
16-
const staticHref = getFontStylesheet({
17-
iconType: "symbol",
18-
iconFamily,
33+
const staticHref = getMaterialSymbolsUrl({
34+
names: [],
35+
family: iconFamily,
1936
fill,
2037
weight,
2138
grade,

apps/docs/src/app/(main)/components/material-icons-and-symbols/layout.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { type Metadata } from "next";
22
import { type PropsWithChildren, type ReactElement } from "react";
33

4+
import { EVERY_ICON_AND_SYMBOL_GOOGLE_FONT_URL } from "@/constants/googleFontsApi.js";
5+
46
const title = "Material icons and Symbols - react-md";
57
const description =
68
"This page is used to help find icons available in react-md using Material Symbols or Material Icons svg components. Icons can be filtered by type, group, or name.";
@@ -22,7 +24,7 @@ export const metadata: Metadata = {
2224
other: [
2325
{
2426
rel: "stylesheet",
25-
url: "https://fonts.googleapis.com/css2?family=Material+Icons&family=Material+Icons+Outlined&family=Material+Icons+Round&family=Material+Icons+Sharp&family=Material+Icons+Two+Tone&family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200&family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200&family=Material+Symbols+Sharp:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200",
27+
url: EVERY_ICON_AND_SYMBOL_GOOGLE_FONT_URL,
2628
},
2729
],
2830
},

apps/docs/src/app/(main)/components/material-icons-and-symbols/utils.ts

Lines changed: 8 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -101,47 +101,27 @@ export function getMaterialIconComponentName(
101101
return pascalCase(`${iconName}${suffix}`);
102102
}
103103

104-
type DefinedSpecs = Omit<MaterialSymbolConfiguration, "family">;
105-
106104
interface FontStylesheetOptions {
107105
iconType: IconType;
108106
iconFamily: MaterialIconFamily;
109107
}
110108

111-
export function getFontStylesheet(options: FontStylesheetOptions): string;
112-
export function getFontStylesheet(
113-
options: FontStylesheetOptions & DefinedSpecs
114-
): string;
115-
export function getFontStylesheet(
116-
options: FontStylesheetOptions & Partial<DefinedSpecs>
117-
): string {
118-
const {
119-
iconType,
120-
iconFamily,
121-
opticalSize = "20..48",
122-
weight = "100..700",
123-
fill = "0..1",
124-
grade = "-50..200",
125-
} = options;
126-
127-
let specs = "";
109+
export function getFontStylesheet(options: FontStylesheetOptions): string {
110+
const { iconType, iconFamily } = options;
111+
128112
let familyName = iconFamily
129113
.split("-")
130114
.map((part) => upperFirst(part))
131115
.join("+");
132116

133-
if (isMaterialIconType(iconType)) {
134-
if (familyName === "Rounded") {
135-
familyName = "Round";
136-
} else if (familyName === "Filled") {
137-
familyName = "";
138-
}
139-
} else {
140-
specs = `:opsz,wght,FILL,GRAD@${opticalSize},${weight},${fill},${grade}`;
117+
if (familyName === "Rounded") {
118+
familyName = "Round";
119+
} else if (familyName === "Filled") {
120+
familyName = "";
141121
}
142122

143123
const name = upperFirst(iconType.split("-")[0]);
144-
const suffix = `${name}s${familyName ? `+${familyName}` : ""}${specs}`;
124+
const suffix = `${name}s${familyName ? `+${familyName}` : ""}`;
145125

146126
return `https://fonts.googleapis.com/css2?family=Material+${suffix}`;
147127
}

apps/docs/src/components/CustomMdxComponents.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,12 @@ export const CUSTOM_MDX_COMPONENTS: CustomMDXComponents = {
103103
tbody: TableBody,
104104
tfoot: TableFooter,
105105
tr: TableRow,
106-
td: TableCell,
107-
th: TableCell,
106+
td: function Td(props) {
107+
return <TableCell lineWrap padding="vertical" {...props} />;
108+
},
109+
th: function Th(props) {
110+
return <TableCell lineWrap padding="vertical" {...props} />;
111+
},
108112
// table: ({ children }) => (
109113
// <div className={tableContainer()}>
110114
// <table className={table({ fullWidth: true })}>{children}</table>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { getMaterialSymbolsUrl } from "@react-md/core/icon/getMaterialSymbolsUrl";
2+
3+
const families = [
4+
"Material+Icons",
5+
"Material+Icons+Outlined",
6+
"Material+Icons+Round",
7+
"Material+Icons+Sharp",
8+
"Material+Icons+Two+Tone",
9+
]
10+
.map((name) => `family=${name}`)
11+
.join("&");
12+
13+
export const EVERY_ICON_AND_SYMBOL_GOOGLE_FONT_URL = getMaterialSymbolsUrl({
14+
names: [],
15+
family: ["outlined", "rounded", "sharp"],
16+
fill: { min: 0, max: 1 },
17+
grade: { min: -25, max: 200 },
18+
opticalSize: { min: 20, max: 48 },
19+
weight: { min: 100, max: 700 },
20+
}).replace("?family", `?${families}&family`);

apps/next-playground/src/app/layout.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { RootHtml } from "@react-md/core/RootHtml";
2-
import { MaterialSymbolsLinks } from "@react-md/core/icon/MaterialSymbolsLinks";
2+
import { getMaterialSymbolsUrl } from "@react-md/core/icon/getMaterialSymbolsUrl";
33
import { type MaterialSymbolName } from "@react-md/core/icon/material";
44
import { DEFAULT_MATERIAL_SYMBOL_NAMES } from "@react-md/core/icon/symbols";
55
import { type Metadata } from "next";
@@ -34,6 +34,14 @@ const names = [
3434

3535
export const metadata: Metadata = {
3636
title: "Next Playground - react-md",
37+
icons: {
38+
other: [
39+
{
40+
rel: "stylesheet",
41+
url: getMaterialSymbolsUrl({ names }),
42+
},
43+
],
44+
},
3745
};
3846

3947
// TODO: Add this to main docs and maybe some components to automate it. should
@@ -59,7 +67,6 @@ export default function Layout({ children }: LayoutProps): ReactElement {
5967
beforeBodyChildren={
6068
<head>
6169
<script dangerouslySetInnerHTML={{ __html: THEME_SCRIPT }} />
62-
<MaterialSymbolsLinks names={names} />
6370
</head>
6471
}
6572
>

packages/core/src/icon/MaterialSymbolsLinks.tsx

Lines changed: 0 additions & 102 deletions
This file was deleted.

packages/core/src/icon/__tests__/MaterialSymbolsLinks.tsx

Lines changed: 0 additions & 37 deletions
This file was deleted.

0 commit comments

Comments
 (0)