diff --git a/.changeset/mosaic-component-props.md b/.changeset/mosaic-component-props.md new file mode 100644 index 00000000000..a845151cc84 --- /dev/null +++ b/.changeset/mosaic-component-props.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/packages/ui/src/mosaic/components/badge/badge.tsx b/packages/ui/src/mosaic/components/badge/badge.tsx index fced1156e66..b689c778db2 100644 --- a/packages/ui/src/mosaic/components/badge/badge.tsx +++ b/packages/ui/src/mosaic/components/badge/badge.tsx @@ -1,13 +1,13 @@ -import { type ComponentProps, type RenderProp, useRender } from '@clerk/headless/utils'; +import { useRender } from '@clerk/headless/utils'; import * as stylex from '@stylexjs/stylex'; import React from 'react'; +import type { MosaicComponentProps } from '../../props'; import { mergeStyleProps, themeProps } from '../../props'; import { colors, styles } from './badge.styles'; -export type BadgeProps = Omit, 'render'> & { +export type BadgeProps = MosaicComponentProps<'span'> & { color?: 'primary' | 'neutral' | 'warning' | 'negative' | 'positive'; - render?: RenderProp> | React.ReactElement; }; /** diff --git a/packages/ui/src/mosaic/components/heading/heading.tsx b/packages/ui/src/mosaic/components/heading/heading.tsx index 5548b87636a..dfb97a4d299 100644 --- a/packages/ui/src/mosaic/components/heading/heading.tsx +++ b/packages/ui/src/mosaic/components/heading/heading.tsx @@ -1,19 +1,17 @@ -import type { RenderPropOrElement } from '@clerk/headless/utils'; import { useRender } from '@clerk/headless/utils'; import * as stylex from '@stylexjs/stylex'; import React from 'react'; +import type { MosaicComponentProps } from '../../props'; import { mergeStyleProps, themeProps } from '../../props'; import { useContextProps } from '../../utils/context'; import type { TypographyColor, TypographySize } from '../typography.styles'; import { colors, sizes } from '../typography.styles'; import { styles } from './heading.styles'; -// `color` replaces the legacy HTML `color` attribute, whose `string` type would widen the variant. -export interface HeadingProps extends Omit, 'color'> { +export interface HeadingProps extends MosaicComponentProps<'h2'> { size?: TypographySize; color?: TypographyColor; - render?: RenderPropOrElement<'h2'>; } export const HeadingContext = React.createContext | null>(null); diff --git a/packages/ui/src/mosaic/components/text/text.tsx b/packages/ui/src/mosaic/components/text/text.tsx index 516d3a4a53b..e43bb7204ec 100644 --- a/packages/ui/src/mosaic/components/text/text.tsx +++ b/packages/ui/src/mosaic/components/text/text.tsx @@ -1,18 +1,16 @@ -import type { RenderPropOrElement } from '@clerk/headless/utils'; import { useRender } from '@clerk/headless/utils'; import * as stylex from '@stylexjs/stylex'; import React from 'react'; +import type { MosaicComponentProps } from '../../props'; import { mergeStyleProps, themeProps } from '../../props'; import { useContextProps } from '../../utils/context'; import type { TypographyColor, TypographySize } from '../typography.styles'; import { colors, sizes } from '../typography.styles'; -// `color` replaces the legacy HTML `color` attribute, whose `string` type would widen the variant. -export interface TextProps extends Omit, 'color'> { +export interface TextProps extends MosaicComponentProps<'p'> { size?: TypographySize; color?: TypographyColor; - render?: RenderPropOrElement<'p'>; } export const TextContext = React.createContext | null>(null); diff --git a/packages/ui/src/mosaic/props.ts b/packages/ui/src/mosaic/props.ts index 16000abdb05..ff31214b8bb 100644 --- a/packages/ui/src/mosaic/props.ts +++ b/packages/ui/src/mosaic/props.ts @@ -1,5 +1,21 @@ +import type { RenderPropOrElement } from '@clerk/headless/utils'; import type React from 'react'; +/** + * The base props every Mosaic component accepts: the native props for its default + * tag, plus the `render` escape hatch that swaps the rendered element. + * + * `color` is omitted because it is a non-standard HTML attribute typed `string`, + * which would widen any component that exposes `color` as a variant. Omitting it + * here rather than per component means a new component inherits the narrowing. + */ +export type MosaicComponentProps = Omit< + React.ComponentPropsWithRef, + 'color' +> & { + render?: RenderPropOrElement; +}; + // The public styling contract, emitted onto a component's root element: // 1. `--cl-*` vars — from `tokens.stylex.ts` (`:root { --cl-color-primary: … }`) // 2. `.cl-` class — from `themeProps` (`.cl-button { … }`)