Yamada UIのfactoryをみていく
factory.ts
ネイティブのHTML要素やその集合体をYamada UIのコンポーネントとして昇格させるための処理がfactory.ts
に書かれている。
import type { UIFactory, DOMElements, StyledOptions, HTMLUIComponents, UIComponent} from './components'import { styled } from './styled'
const factory = () => { const cache = new Map<DOMElements, UIComponent<DOMElements>>()
return new Proxy(styled, { apply: (_target, _thisArg, [el, options]: [DOMElements, StyledOptions]) => { return styled(el, options) },
get: (_target, el: DOMElements) => { if (!cache.has(el)) cache.set(el, styled(el))
return cache.get(el) } }) as UIFactory & HTMLUIComponents}
/** * `ui` is an object of JSX elements enabled with Yamada UI's style system, * and can also be used as a function for custom components to receive Yamada UI's style system. * * @see Docs https://yamada-ui.com/styled-system/ui */export const ui = factory()
このソースコードがあるとこう言うことができる。
import type { HTMLUIProps, ThemeProps, CSSUIObject } from "@yamada-ui/core"import { ui, forwardRef, useComponentStyle, omitThemeProps,} from "@yamada-ui/core"import { cx } from "@yamada-ui/utils"
export type BadgeProps = HTMLUIProps<"span"> & ThemeProps<"Badge">
/** * `Badge` is a component that emphasizes the status of an item to make it immediately recognizable. * * @see Docs https://yamada-ui.com/components/data-display/badge */export const Badge = forwardRef<BadgeProps, "span">((props, ref) => { const [styles, mergedProps] = useComponentStyle("Badge", props) const { className, ...rest } = omitThemeProps(mergedProps)
const css: CSSUIObject = { display: "inline-block", whiteSpace: "nowrap", verticalAlign: "middle", ...styles, }
return ( <ui.span ref={ref} className={cx("ui-badge", className)} __css={css} {...rest} /> )})
このソースのここの部分。
<ui.span ref={ref} className={cx("ui-badge", className)} __css={css} {...rest}/>
これを実行すると、factory.ts
のここの部分が実行される。
get: (_target, el: DOMElements) => { if (!cache.has(el)) cache.set(el, styled(el))
return cache.get(el)},
その結果、ただの<span>
要素が、Yamada UIの機能(Styleとか)を追加した<span>
要素・改になる。
参考
Proxyの基本的な使い方を復習すべき





