Move to useRender from BaseUI
Signed-off-by: Charles de Dreuille <charles.dedreuille@gmail.com>
This commit is contained in:
@@ -15,6 +15,7 @@ import { RefAttributes } from 'react';
|
||||
import type { RemixiconComponentType } from '@remixicon/react';
|
||||
import { ScrollArea as ScrollArea_2 } from '@base-ui-components/react/scroll-area';
|
||||
import { Tooltip as Tooltip_2 } from '@base-ui-components/react/tooltip';
|
||||
import type { useRender } from '@base-ui-components/react/use-render';
|
||||
|
||||
// @public (undocumented)
|
||||
export type AlignItems = 'stretch' | 'start' | 'center' | 'end';
|
||||
@@ -696,6 +697,32 @@ export type JustifyContent =
|
||||
| 'around'
|
||||
| 'between';
|
||||
|
||||
// @public (undocumented)
|
||||
export const Link: React_2.ForwardRefExoticComponent<
|
||||
Omit<LinkProps, 'ref'> & React_2.RefAttributes<HTMLElement>
|
||||
>;
|
||||
|
||||
// @public (undocumented)
|
||||
export interface LinkProps extends useRender.ComponentProps<'a'> {
|
||||
// (undocumented)
|
||||
children: ReactNode;
|
||||
// (undocumented)
|
||||
className?: string;
|
||||
// (undocumented)
|
||||
style?: CSSProperties;
|
||||
// (undocumented)
|
||||
to?: string;
|
||||
// (undocumented)
|
||||
variant?:
|
||||
| 'subtitle'
|
||||
| 'body'
|
||||
| 'caption'
|
||||
| 'label'
|
||||
| Partial<Record<Breakpoint, 'subtitle' | 'body' | 'caption' | 'label'>>;
|
||||
// (undocumented)
|
||||
weight?: 'regular' | 'bold' | Partial<Record<Breakpoint, 'regular' | 'bold'>>;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export const marginPropDefs: (spacingValues: string[]) => {
|
||||
m: {
|
||||
|
||||
@@ -19,6 +19,7 @@ import type { Meta, StoryObj } from '@storybook/react';
|
||||
import { Link } from './Link';
|
||||
import { Flex } from '../Flex';
|
||||
import { Text } from '../Text';
|
||||
import { Link as RouterLink, MemoryRouter } from 'react-router-dom';
|
||||
|
||||
const meta = {
|
||||
title: 'Components/Link',
|
||||
@@ -74,6 +75,23 @@ export const Responsive: Story = {
|
||||
},
|
||||
};
|
||||
|
||||
export const CustomRender: Story = {
|
||||
render: () => {
|
||||
return (
|
||||
<Flex gap="4" direction="column" align="start">
|
||||
<Link render={<RouterLink to="/catalog" />}>Go to Catalog</Link>
|
||||
</Flex>
|
||||
);
|
||||
},
|
||||
decorators: [
|
||||
Story => (
|
||||
<MemoryRouter>
|
||||
<Story />
|
||||
</MemoryRouter>
|
||||
),
|
||||
],
|
||||
};
|
||||
|
||||
export const Playground: Story = {
|
||||
args: {
|
||||
...Default.args,
|
||||
|
||||
@@ -14,59 +14,44 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { forwardRef, memo, ComponentType } from 'react';
|
||||
import React, { forwardRef } from 'react';
|
||||
import { useRender } from '@base-ui-components/react/use-render';
|
||||
import { useResponsiveValue } from '../../hooks/useResponsiveValue';
|
||||
import clsx from 'clsx';
|
||||
|
||||
import type { LinkProps, LinkRenderProps } from './types';
|
||||
import type { LinkProps } from './types';
|
||||
|
||||
/** @public */
|
||||
export const Link = memo(
|
||||
forwardRef<HTMLAnchorElement, LinkProps>((props, ref) => {
|
||||
const {
|
||||
children,
|
||||
variant = 'body',
|
||||
weight = 'regular',
|
||||
style,
|
||||
className,
|
||||
render,
|
||||
to,
|
||||
...restProps
|
||||
} = props;
|
||||
export const Link = forwardRef<HTMLElement, LinkProps>((props, ref) => {
|
||||
const {
|
||||
className,
|
||||
variant = 'body',
|
||||
weight = 'regular',
|
||||
render = <a />,
|
||||
...restProps
|
||||
} = props;
|
||||
|
||||
const responsiveVariant = useResponsiveValue(variant);
|
||||
const responsiveWeight = useResponsiveValue(weight);
|
||||
const responsiveVariant = useResponsiveValue(variant);
|
||||
const responsiveWeight = useResponsiveValue(weight);
|
||||
const internalRef = React.useRef<HTMLElement | null>(null);
|
||||
|
||||
const linkProps: LinkRenderProps = {
|
||||
const { renderElement } = useRender({
|
||||
render,
|
||||
props: {
|
||||
className: clsx(
|
||||
'canon-Link',
|
||||
responsiveVariant && `canon-Link--variant-${responsiveVariant}`,
|
||||
responsiveWeight && `canon-Link--weight-${responsiveWeight}`,
|
||||
className,
|
||||
),
|
||||
style,
|
||||
children,
|
||||
to,
|
||||
responsiveVariant,
|
||||
responsiveWeight,
|
||||
...restProps,
|
||||
};
|
||||
},
|
||||
refs: [ref, internalRef],
|
||||
});
|
||||
|
||||
if (render) {
|
||||
// If render is a component type, wrap it in memo to prevent unnecessary re-renders
|
||||
if (typeof render === 'function' && !render.length) {
|
||||
const MemoizedComponent = memo(
|
||||
render as ComponentType<LinkRenderProps>,
|
||||
);
|
||||
return <MemoizedComponent {...linkProps} />;
|
||||
}
|
||||
// If it's a render function, call it directly
|
||||
const RenderComponent = render as (
|
||||
props: LinkRenderProps,
|
||||
) => React.ReactNode;
|
||||
return <RenderComponent {...linkProps} />;
|
||||
}
|
||||
|
||||
return <a ref={ref} href={to} {...linkProps} />;
|
||||
}),
|
||||
);
|
||||
return renderElement();
|
||||
});
|
||||
|
||||
Link.displayName = 'Link';
|
||||
|
||||
@@ -14,14 +14,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import type { CSSProperties, ReactNode, ComponentType } from 'react';
|
||||
import type { CSSProperties, ReactNode } from 'react';
|
||||
import type { Breakpoint } from '../../types';
|
||||
import type { useRender } from '@base-ui-components/react/use-render';
|
||||
|
||||
/** @public */
|
||||
export interface LinkProps
|
||||
extends Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, 'to'> {
|
||||
export interface LinkProps extends useRender.ComponentProps<'a'> {
|
||||
children: ReactNode;
|
||||
to: string;
|
||||
to?: string;
|
||||
variant?:
|
||||
| 'subtitle'
|
||||
| 'body'
|
||||
@@ -31,10 +31,4 @@ export interface LinkProps
|
||||
weight?: 'regular' | 'bold' | Partial<Record<Breakpoint, 'regular' | 'bold'>>;
|
||||
className?: string;
|
||||
style?: CSSProperties;
|
||||
render?:
|
||||
| ((props: Omit<LinkProps, 'render'>) => ReactNode)
|
||||
| ComponentType<Omit<LinkProps, 'render'>>;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export type LinkRenderProps = Omit<LinkProps, 'render'>;
|
||||
|
||||
Reference in New Issue
Block a user