Skip to content

Commit

Permalink
migrate patterns/icon
Browse files Browse the repository at this point in the history
  • Loading branch information
NgocNhi123 committed Jun 26, 2024
1 parent 23eda97 commit 346c705
Showing 1 changed file with 127 additions and 0 deletions.
127 changes: 127 additions & 0 deletions new-docs/pages/patterns/icon.stories.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import { Button } from '../../../core/src';
import { RiSearchLine } from "react-icons/ri";

# Icon

Moai doesn't have a built-in icon set. Instead, Moai's components work with any
SVG icons. This means you can use Moai with popular icon sets, like
[FontAwesome][1] and [Material Icons][2], or even with [your own icons][4].

This guide covers the usage of icons inside Moai's components (like in buttons
and inputs). To display an icon on its own, with the control of its size and
color, see the [Icon component][3].

[1]: https://fontawesome.com
[2]: https://fonts.google.com/icons
[3]: /components/icon
[4]: /patterns/icon/advanced

## Basic

Moai components that support icons usually have an \`icon\` prop. The
recommended way to set this prop is using an icon from the [react-icons][1]
package. It provides icons from many popular sets that can be used directly in
Moai:

~~~ts
import { RiSearchLine } from "react-icons/ri";
~~~

[1]: https://react-icons.github.io/react-icons/

<Button icon={RiSearchLine} children="Search" />

~~~tsx
(): JSX.Element => (
<Button icon={RiSearchLine} children="Search" />
)
~~~

## Icon Label

In most cases, [screen readers][1] will [skip the icon][2] and only announce
the text content of a component (e.g. the label of a button). When a component
has no content to be announced (e.g. an icon-only button), you'll often be
asked to provide an explicit icon label:

[1]: https://en.wikipedia.org/wiki/Screen_reader
[2]: https://www.sarasoueidan.com/blog/accessible-icon-buttons/#icon-sitting-next-to-text

<Button icon={RiSearchLine} iconLabel="Search" />

~~~tsx
(): JSX.Element => (
<Button icon={RiSearchLine} iconLabel="Search" />
)
~~~

## Color & Size

When using with a component, the color and size of an icon are usually
controlled by the component itself. For example, in a large, highlight button,
the icon is white and enlarged:

<Button
highlight
size={Button.sizes.large}
icon={RiSearchLine}
children="Search"
/>

~~~tsx
(): JSX.Element => (
<Button
highlight
size={Button.sizes.large}
icon={RiSearchLine}
children="Search"
/>
)
~~~

## Advanced

Technically, these \`icon\` props simply expect a [function component][1] that
returns an SVG element. The type definition looks like this:

~~~ts
interface Props {
style?: CSSProperties;
className?: string;
}

type Icon = (props: Props) => JSX.Element;
~~~

This means you can use Moai with your own custom icons (e.g. logos, product
icons), by creating components that return them as SVG elements. For a full
icon set, consider tools like [React SVGR][2] to programmatically generate
these components from SVG files.

[1]: https://reactjs.org/docs/components-and-props.html#function-and-class-components
[2]: https://react-svgr.com

<Button
icon={(props) => {
return (
<svg width="1em" height="1em" viewBox="0 0 48 1" {...props}>
<path d="M0 0h48v1H0z" fill="currentColor" fillRule="evenodd" />
</svg>
)
}}
children="Search"
/>

~~~tsx
(): JSX.Element => {
// In practice, this should be defined outside of your component, or even
// better, automatically generated by a tool like react-svgr.
const Icon = (props: SVGAttributes<SVGElement>) => (
<svg width="1em" height="1em" viewBox="0 0 48 1" {...props}>
{/* This is just a horizontal line */}
<path d="M0 0h48v1H0z" fill="currentColor" fillRule="evenodd" />
</svg>
);
return <Button icon={Icon} children="Search" />;
};
~~~

0 comments on commit 346c705

Please sign in to comment.