Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Support for Material Symbols #1421

Open
ryanwalters opened this issue Jul 27, 2022 · 4 comments
Open

Add Support for Material Symbols #1421

ryanwalters opened this issue Jul 27, 2022 · 4 comments
Milestone

Comments

@ryanwalters
Copy link

Is your feature request related to a problem? Please describe.
The material icon "Savings" appears to be missing.

Describe the solution you'd like
It would be great if this icon was included in the @react-md/material-icons package.

Describe alternatives you've considered
Since this particular icon is required by the current project I'm working on, I would unfortunately need to find a different package to use if this can't be included.

Additional context
Not so much context as a thanks for your work on this project. It's nice to have a pared down, peer dependency-free alternative to packages like @mui/icons-material.

@mlaursen mlaursen added this to the v6.0.0 milestone Aug 3, 2022
@mlaursen
Copy link
Owner

mlaursen commented Aug 3, 2022

Thanks for reporting this issue! I didn't know they started supporting variable fonts for the icons so I'll need to make sure to include those in my v6 release that includes all the latest icons.

Since it's going to take a while before v6.0.0 is released, you should be able to use one of these components in the meantime:

import { forwardRef } from "react";

import type { SVGIconProps } from "@react-md/icon";
import { SVGIcon } from "@react-md/icon";

export const SavingsSVGIcon = forwardRef<SVGSVGElement, SVGIconProps>(
  function SavingsSVGIcon(props, ref) {
    return (
      <SVGIcon {...props} ref={ref}>
        <path d="M32 22q.85 0 1.425-.575Q34 20.85 34 20q0-.85-.575-1.425Q32.85 18 32 18q-.85 0-1.425.575Q30 19.15 30 20q0 .85.575 1.425Q31.15 22 32 22Zm-16-5h10v-3H16ZM9 42q-1.5-4.95-2.45-8.5-.95-3.55-1.525-6.175t-.8-4.575Q4 20.8 4 19q0-4.6 3.2-7.8T15 8h10q1.35-1.8 3.425-2.9Q30.5 4 33 4q1.25 0 2.125.875T36 7q0 .3-.075.6t-.175.55q-.2.55-.375 1.1t-.275 1.2L39.65 15H44v13.95l-5.65 1.85L35 42H24v-4h-4v4Zm2.25-3H17v-4h10v4h5.75l3.15-10.5 5.1-1.75V18h-2.6L32 11.6q.05-.85.275-2.075Q32.5 8.3 32.9 6.8q-2.15.55-3.8 1.65-1.65 1.1-2.4 2.55H15q-3.3 0-5.65 2.35Q7 15.7 7 19q0 2.1 1.1 7.325T11.25 39ZM24 22.9Z" />
      </SVGIcon>
    );
  }
);
import { forwardRef } from "react";

import type { FontIconProps } from "@react-md/icon";
import { FontIcon } from "@react-md/icon";

export const SavingsFontIcon = forwardRef<HTMLElement, FontIconProps>(
  function SavingsFontIcon(props, ref) {
    return (
      <FontIcon {...props} ref={ref}>
        savings
      </FontIcon>
    );
  }
);

If you run into any other missing icons in the meantime, you can download the .svg and copy/paste the everything within the svg tags into this template (also rename the component as needed):

import { forwardRef } from "react";

import type { SVGIconProps } from "@react-md/icon";
import { SVGIcon } from "@react-md/icon";

export const ICON_COMPONENT_NAME = forwardRef<SVGSVGElement, SVGIconProps>(
  function ICON_COMPONENT_NAME(props, ref) {
    return (
      <SVGIcon {...props} ref={ref}>
        {{PASTE_PATHS_HERE}}
      </SVGIcon>
    );
  }
);

@ryanwalters
Copy link
Author

This works for us for the time being, thanks! Looking forward to v6, particularly if there's a tree shakeable way to incorporate Material Symbols into the package.

@mlaursen
Copy link
Owner

I've started looking into implementing the material symbols components but running into a few issues since there are around 2500 symbols at this time. If you get some time, it would help me out if you could answer any of these questions so I can figure out the best way to implement them.

Do you need the ability to use the variable font behavior of customizing the "fill", "weight", "grade", and "optical size" for the icons?

If that is the case, I could generate icon components for each unique icon name and a mixin to apply the font-variation-settings required for your icons. The downside to this implementation is that you'd need to manually include the material symbols stylesheet yourself.

So an example implementation:

<link
  rel="stylesheet"
  href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200"
/>

<!-- OR -->
<link
  rel="stylesheet"
  href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200"
/>

<!-- OR -->
<link
  rel="stylesheet"
  href="https://fonts.googleapis.com/css2?family=Material+Symbols+Sharp:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200"
/>
@use "react-md" with (
  $material-symbols: (
    $fill: 0, // or 1
    $weight: 100, // or 200, 300, 400, 500, 600, 700
    $grade: 0, // or -25, 200
    $optical-size: 24px, // or 20px, 40px, 48px
  ),
);

@include react-md.styles;

// or manually generate the styles
@use "@react-md/material-symbols" as *;

@include material-symbols(
  $fill: 0, // or 1
  $weight: 100, // or 200, 300, 400, 500, 600, 700
  $grade: 0, // or -25, 200
  $optical-size: 24px, // or 20px, 40px, 48px
);
import SearchIcon from "@react-md/material-symbols/SearchIcon";
import SearchRoundedIcon from "@react-md/material-symbols/SearchRoundedIcon";
import SearchSharpIcon from "@react-md/material-symbols/SearchSharpIcon";

function Example() {
  return (
    <>
      <SearchIcon />
      <SearchRoundedIcon />
      <SearchSharpIcon />
    </>
  );
}

Is it preferred to provide components that don't rely on downloading the material symbols stylesheet through the Google Fonts api?

For example, I could generate icon components for all the 24px versions of the svgs just like the @react-md/material-icons package. The downside to this implementation is that you wouldn't be able to customize the fill, weight, grade, and optical size of these icons.

So for this one, you'd only need to do:

import SearchIcon from "@react-md/material-symbols/SearchIcon";
import SearchRoundedIcon from "@react-md/material-symbols/SearchRoundedIcon";
import SearchSharpIcon from "@react-md/material-symbols/SearchSharpIcon";

function Example() {
  return (
    <>
      <SearchIcon />
      <SearchRoundedIcon />
      <SearchSharpIcon />
    </>
  );
}

This one might have a smaller size than the variable font implementation since you can code split each icon instead of downloading the entire variable font stylesheet, but I think it'll be larger if you use a lot of icons.

@mlaursen mlaursen changed the title Add missing material icon: savings Add Support for Material Symbols Sep 12, 2022
@mlaursen
Copy link
Owner

I ended up going with creating MaterialSymbol and MaterialIcon components that rely on the stylesheet being loaded. All the material icons are also available as SVG components through the @react-md/material-icon package.

Material Symbol Usage

npm install @react-md/core@1.0.0-next.2
// setting the default custom properties and creating styles will be handled automatically when using the full core package once it's complete...
@use "@react-md/core" with (
  // these are the defaults and can be omitted if using these values
  $icon-symbol-fill: 0.
  $icon-symbol-weight: 400,
  $icon-symbol-grade: 0,
  $icon-symbol-optical-size: 48,
);

// initialize the default custom properties
:root {
  @include core.icon-set-var(symbol-fill, core.$icon-symbol-fill);
  @include core.icon-set-var(symbol-grade, core.$icon-symbol-grade);
  @include core.icon-set-var(symbol-weight, core.$icon-symbol-weight);
  @include core.icon-set-var(symbol-optical-size, core.$icon-symbol-optical-size);
}

// add the new symbol styles
.rmd-icon--symbol {
  font-variation-settings:
    "FILL" core.icon-get-var(symbol-fill),
    "wght" core.icon-get-var(symbol-weight),
    "GRAD" core.icon-get-var(symbol-grade),
    "opsz" core.icon-get-var(symbol-optical-size);
}
import { MaterialSymbol } from "@react-md/core";

<MaterialSymbol name="savings" />

Material Icons Font Usage

npm install @react-md/core@1.0.0-next.2
import { MaterialIcon } from "@react-md/core";

<MaterialIcon name="savings" />

Material Icons SVG Usage

npm install @react-md/material-icons@6.0.0-next.2
import SavingsOutlinedIcon from "@react-md/material-icons/SavingsOutlinedIcon"

<SavingsOutlinedIcon  />

I'll close this ticket once v6.0.0 has been released.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants