diff --git a/.changeset/unlucky-dingos-listen.md b/.changeset/unlucky-dingos-listen.md
new file mode 100644
index 00000000000..6fe967b4ba9
--- /dev/null
+++ b/.changeset/unlucky-dingos-listen.md
@@ -0,0 +1,13 @@
+---
+"@chakra-ui/system": minor
+---
+
+Allow all `JSX.IntrinsicElements` for the chakra factory. This allows to use
+[every DOM element](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/30a2f70db2f9ac223fd923ff1f8bcc175c082fd0/types/react/index.d.ts#L3111-L3288)
+with the shorthand version:
+
+```jsx live=false
+Header
+Main
+Many more
+```
diff --git a/packages/system/src/factory.ts b/packages/system/src/factory.ts
new file mode 100644
index 00000000000..5d09c9543c7
--- /dev/null
+++ b/packages/system/src/factory.ts
@@ -0,0 +1,37 @@
+import { DOMElements } from "./system.utils"
+import { ChakraStyledOptions, HTMLChakraComponents, styled } from "./system"
+import { As, ChakraComponent } from "./system.types"
+
+type ChakraFactory = {
+ (
+ component: T,
+ options?: ChakraStyledOptions,
+ ): ChakraComponent
+}
+
+function factory() {
+ const cache = new Map>()
+
+ return new Proxy(styled, {
+ /**
+ * @example
+ * const Div = chakra("div")
+ * const WithChakra = chakra(AnotherComponent)
+ */
+ apply(target, thisArg, argArray: [DOMElements, ChakraStyledOptions]) {
+ return styled(...argArray)
+ },
+ /**
+ * @example
+ *
+ */
+ get(_, element: DOMElements) {
+ if (!cache.has(element)) {
+ cache.set(element, styled(element))
+ }
+ return cache.get(element)
+ },
+ }) as ChakraFactory & HTMLChakraComponents
+}
+
+export const chakra = factory()
diff --git a/packages/system/src/index.ts b/packages/system/src/index.ts
index 3649148dd0e..73ef44fc50f 100644
--- a/packages/system/src/index.ts
+++ b/packages/system/src/index.ts
@@ -9,4 +9,5 @@ export { omitThemingProps } from "./system.utils"
export * from "./system"
export * from "./forward-ref"
export * from "./use-style-config"
+export * from "./factory"
export { shouldForwardProp } from "./should-forward-prop"
diff --git a/packages/system/src/system.ts b/packages/system/src/system.ts
index 7136e94805e..adab906ad2f 100644
--- a/packages/system/src/system.ts
+++ b/packages/system/src/system.ts
@@ -4,11 +4,11 @@ import {
StyleProps,
SystemStyleObject,
} from "@chakra-ui/styled-system"
-import { filterUndefined, objectFilter, runIfFn } from "@chakra-ui/utils"
+import { Dict, filterUndefined, objectFilter, runIfFn } from "@chakra-ui/utils"
import _styled, { CSSObject, FunctionInterpolation } from "@emotion/styled"
import { shouldForwardProp } from "./should-forward-prop"
import { As, ChakraComponent, ChakraProps, PropsOf } from "./system.types"
-import { domElements, DOMElements } from "./system.utils"
+import { DOMElements } from "./system.utils"
type StyleResolverProps = SystemStyleObject & {
__css?: SystemStyleObject
@@ -38,22 +38,24 @@ interface GetStyleObject {
* behaviors. Right now, the `sx` prop has the highest priority so the resolved
* fontSize will be `40px`
*/
-export const toCSSObject: GetStyleObject = ({ baseStyle }) => (props) => {
- const { theme, css: cssProp, __css, sx, ...rest } = props
- const styleProps = objectFilter(rest, (_, prop) => isStyleProp(prop))
- const finalBaseStyle = runIfFn(baseStyle, props)
- const finalStyles = Object.assign(
- {},
- __css,
- finalBaseStyle,
- filterUndefined(styleProps),
- sx,
- )
- const computedCSS = css(finalStyles)(props.theme)
- return cssProp ? [computedCSS, cssProp] : computedCSS
-}
+export const toCSSObject: GetStyleObject =
+ ({ baseStyle }) =>
+ (props) => {
+ const { theme, css: cssProp, __css, sx, ...rest } = props
+ const styleProps = objectFilter(rest, (_, prop) => isStyleProp(prop))
+ const finalBaseStyle = runIfFn(baseStyle, props)
+ const finalStyles = Object.assign(
+ {},
+ __css,
+ finalBaseStyle,
+ filterUndefined(styleProps),
+ sx,
+ )
+ const computedCSS = css(finalStyles)(props.theme)
+ return cssProp ? [computedCSS, cssProp] : computedCSS
+ }
-interface StyledOptions {
+export interface ChakraStyledOptions extends Dict {
shouldForwardProp?(prop: string): boolean
label?: string
baseStyle?:
@@ -63,7 +65,7 @@ interface StyledOptions {
export function styled(
component: T,
- options?: StyledOptions,
+ options?: ChakraStyledOptions,
) {
const { baseStyle, ...styledOptions } = options ?? {}
@@ -89,17 +91,3 @@ export type HTMLChakraProps = Omit<
: "ref" | keyof StyleProps
> &
ChakraProps & { as?: As }
-
-type ChakraFactory = {
- (
- component: T,
- options?: StyledOptions,
- ): ChakraComponent
-}
-
-export const chakra = (styled as unknown) as ChakraFactory &
- HTMLChakraComponents
-
-domElements.forEach((tag) => {
- chakra[tag] = chakra(tag)
-})
diff --git a/packages/system/src/system.utils.ts b/packages/system/src/system.utils.ts
index f55e303763e..ca08cef4100 100644
--- a/packages/system/src/system.utils.ts
+++ b/packages/system/src/system.utils.ts
@@ -1,74 +1,12 @@
-import { isString, omit, UnionStringArray, __DEV__ } from "@chakra-ui/utils"
+import { isString, omit, __DEV__ } from "@chakra-ui/utils"
import * as React from "react"
import { ThemingProps } from "./system.types"
/**
- * Carefully selected html elements for chakra components.
+ * All html and svg elements for chakra components.
* This is mostly for `chakra.` syntax.
*/
-export const domElements = [
- "a",
- "b",
- "article",
- "aside",
- "blockquote",
- "button",
- "caption",
- "cite",
- "circle",
- "code",
- "dd",
- "div",
- "dl",
- "dt",
- "fieldset",
- "figcaption",
- "figure",
- "footer",
- "form",
- "h1",
- "h2",
- "h3",
- "h4",
- "h5",
- "h6",
- "header",
- "hr",
- "img",
- "input",
- "kbd",
- "label",
- "li",
- "main",
- "mark",
- "nav",
- "ol",
- "p",
- "path",
- "pre",
- "q",
- "rect",
- "s",
- "svg",
- "section",
- "select",
- "strong",
- "small",
- "span",
- "sub",
- "sup",
- "table",
- "tbody",
- "td",
- "textarea",
- "tfoot",
- "th",
- "thead",
- "tr",
- "ul",
-] as const
-
-export type DOMElements = UnionStringArray
+export type DOMElements = keyof JSX.IntrinsicElements
export function omitThemingProps(props: T) {
return omit(props, ["styleConfig", "size", "variant", "colorScheme"])