import { Meta } from "@storybook/react/types-6-0" ; import { SVGAttributes } from "react" ; import { RiSearchLine } from "react-icons/ri" ; import { Button } from "../../../core/src" ; import { Utils } from "../utils/utils" ; const meta = { title : "Patterns/Icon" , } ; Utils . page . pattern ( meta , { desc : `
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]: /docs/components-icon--primary
[4]: #advanced
` , } ) ; export default meta ; export const Primary = ( ) : JSX . Element => < div > Skipped < /div>; export const Basic = ( ) : JSX . Element => ( < Button icon = { RiSearchLine } children = "Search" / > ) ; Utils . story ( Basic , { desc : `
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/
` , } ) ; export const IconLabel = ( ) : JSX . Element => ( < Button icon = { RiSearchLine } iconLabel = "Search" / > ) ; Utils . story ( IconLabel , { desc : `
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
` , } ) ; export const ColorSize = ( ) : JSX . Element => ( < Button highlight size = { Button . sizes . large } icon = { RiSearchLine } children = "Search" / > ) ; Utils . story ( ColorSize , { name : "Color & Size" , desc : `
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:
` , } ) ; export const Advanced = ( ) : JSX . Element => { const Icon = ( props ) => ( < svg width = "1em" height = "1em" viewBox = "0 0 48 1" { ... props } > { } < path d = "M0 0h48v1H0z" fill = "currentColor" fillRule = "evenodd" / > < /svg>); return < Button icon = { Icon } children = "Search" / > ; } ; Utils . story ( Advanced , { desc : `
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
` , } ) ;