mirror of
https://github.com/nextui-org/nextui.git
synced 2025-12-08 19:26:11 +00:00
feat(root): RSC components added, packages modified, filter dom props function adapted (#1289)
* feat(root): rsc components added, packages modified, filter dom props function adapted * fix(root): eslint/prettier issues
This commit is contained in:
parent
2e4ce7bcee
commit
eefda8d6e2
22
.changeset/fresh-jobs-draw.md
Normal file
22
.changeset/fresh-jobs-draw.md
Normal file
@ -0,0 +1,22 @@
|
||||
---
|
||||
"@nextui-org/react-utils": patch
|
||||
"@nextui-org/accordion": patch
|
||||
"@nextui-org/dropdown": patch
|
||||
"@nextui-org/skeleton": patch
|
||||
"@nextui-org/divider": patch
|
||||
"@nextui-org/spinner": patch
|
||||
"@nextui-org/button": patch
|
||||
"@nextui-org/spacer": patch
|
||||
"@nextui-org/badge": patch
|
||||
"@nextui-org/input": patch
|
||||
"@nextui-org/table": patch
|
||||
"@nextui-org/card": patch
|
||||
"@nextui-org/code": patch
|
||||
"@nextui-org/tabs": patch
|
||||
"@nextui-org/kbd": patch
|
||||
"@nextui-org/system": patch
|
||||
---
|
||||
|
||||
- "use client" directive removed from components that didn't need it
|
||||
- packages adapted to support RSC imports
|
||||
- filterDomProps function was modified to enable/disabled it
|
||||
@ -1,4 +1,4 @@
|
||||
import {Spacer} from "@nextui-org/react";
|
||||
import {Spacer} from "@nextui-org/spacer";
|
||||
|
||||
import {Hero} from "@/components/marketing/hero";
|
||||
import {FeaturesGrid} from "@/components/marketing/features-grid";
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import {BlogPost} from "contentlayer/generated";
|
||||
import {Card, CardFooter, CardBody, CardHeader, Link, Avatar} from "@nextui-org/react";
|
||||
import {Card, CardFooter, CardBody, CardHeader, Link, Avatar, Image} from "@nextui-org/react";
|
||||
import Balancer from "react-wrap-balancer";
|
||||
import {format, parseISO} from "date-fns";
|
||||
import NextLink from "next/link";
|
||||
@ -39,10 +39,9 @@ const BlogPostCard = (post: BlogPost) => {
|
||||
<Balancer>{post.title}</Balancer>
|
||||
</Link>
|
||||
</CardHeader>
|
||||
<CardBody className="px-3 pt-0 pb-1">
|
||||
<p className="font-normal text-default-600">
|
||||
<Balancer>{post.description}</Balancer>
|
||||
</p>
|
||||
<CardBody className="pt-0 px-2 pb-1">
|
||||
<Image className="mb-3" src={post.image} />
|
||||
<p className="font-normal px-1 text-default-600">{post.description}</p>
|
||||
</CardBody>
|
||||
<CardFooter className="flex justify-between items-center">
|
||||
<time className="block text-small text-default-500" dateTime={post.date}>
|
||||
|
||||
@ -1,12 +1,15 @@
|
||||
import {Button, ButtonProps, Link} from "@nextui-org/react";
|
||||
import {Button, ButtonProps, Code, Link, Tooltip} from "@nextui-org/react";
|
||||
import {ReactNode} from "react";
|
||||
import Balancer from "react-wrap-balancer";
|
||||
|
||||
import {GithubIcon, NpmIcon, AdobeIcon, StorybookIcon} from "@/components/icons";
|
||||
import {GithubIcon, NpmIcon, AdobeIcon, StorybookIcon, NextJsIcon} from "@/components/icons";
|
||||
import {COMPONENT_PATH, COMPONENT_THEME_PATH} from "@/libs/github/constants";
|
||||
|
||||
export interface ComponentLinksProps {
|
||||
component: string;
|
||||
styles?: string;
|
||||
storybook?: string;
|
||||
rscCompatible?: boolean;
|
||||
reactAriaHook?: string;
|
||||
}
|
||||
|
||||
@ -14,27 +17,40 @@ const ButtonLink = ({
|
||||
children,
|
||||
href,
|
||||
startContent,
|
||||
tooltip,
|
||||
...props
|
||||
}: ButtonProps & {
|
||||
href: string;
|
||||
}) => (
|
||||
<Button
|
||||
isExternal
|
||||
as={Link}
|
||||
className="!text-small py-4 bg-default-100 dark:bg-default-50 text-default-700"
|
||||
href={href}
|
||||
size="sm"
|
||||
startContent={startContent}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</Button>
|
||||
);
|
||||
tooltip?: string | ReactNode;
|
||||
}) => {
|
||||
const button = (
|
||||
<Button
|
||||
isExternal
|
||||
as={Link}
|
||||
className="!text-small py-4 bg-default-100 dark:bg-default-50 text-default-700"
|
||||
href={href}
|
||||
size="sm"
|
||||
startContent={startContent}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</Button>
|
||||
);
|
||||
|
||||
return tooltip ? (
|
||||
<Tooltip className="max-w-[230px]" content={tooltip}>
|
||||
{button}
|
||||
</Tooltip>
|
||||
) : (
|
||||
button
|
||||
);
|
||||
};
|
||||
|
||||
export const ComponentLinks = ({
|
||||
component,
|
||||
storybook,
|
||||
styles,
|
||||
rscCompatible,
|
||||
reactAriaHook,
|
||||
}: ComponentLinksProps) => {
|
||||
if (!component) {
|
||||
@ -63,6 +79,26 @@ export const ComponentLinks = ({
|
||||
React Aria
|
||||
</ButtonLink>
|
||||
)}
|
||||
{rscCompatible && (
|
||||
<ButtonLink
|
||||
href="https://nextjs.org/docs/getting-started/react-essentials#server-components"
|
||||
startContent={<NextJsIcon size={18} />}
|
||||
tooltip={
|
||||
<p>
|
||||
<Balancer>
|
||||
This component doesn't use the
|
||||
<Code className="font-normal bg-transparent px-0 py-0 text-code-mdx">
|
||||
`use client;`
|
||||
</Code>
|
||||
directive making it compatible with RSC.
|
||||
</Balancer>
|
||||
</p>
|
||||
}
|
||||
>
|
||||
Server component
|
||||
</ButtonLink>
|
||||
)}
|
||||
|
||||
<ButtonLink href={`${COMPONENT_PATH}/${component}`} startContent={<GithubIcon size={20} />}>
|
||||
Source
|
||||
</ButtonLink>
|
||||
|
||||
@ -30,8 +30,7 @@ export const nextuiTheme: SandpackTheme = {
|
||||
},
|
||||
font: {
|
||||
body: "Inter var",
|
||||
mono:
|
||||
'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',
|
||||
mono: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',
|
||||
size: "14px",
|
||||
lineHeight: "1.5rem",
|
||||
},
|
||||
|
||||
@ -9,7 +9,7 @@ import {badgeContent} from "@/content/components/badge";
|
||||
|
||||
Badges are used as a small numerical value or status descriptor for UI elements.
|
||||
|
||||
<ComponentLinks component="badge" />
|
||||
<ComponentLinks component="badge" rscCompatible />
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@ import {codeContent} from "@/content/components/code";
|
||||
|
||||
Code is a component used to display inline code.
|
||||
|
||||
<ComponentLinks component="code" />
|
||||
<ComponentLinks component="code" rscCompatible />
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@ import {dividerContent} from "@/content/components/divider";
|
||||
|
||||
Divider is a component that separates content in a page.
|
||||
|
||||
<ComponentLinks component="divider" reactAriaHook="useSeparator" />
|
||||
<ComponentLinks component="divider" reactAriaHook="useSeparator" rscCompatible />
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@ import {kbdContent} from "@/content/components/kbd";
|
||||
|
||||
Keyboard key is a component to display which key or combination of keys performs a given action.
|
||||
|
||||
<ComponentLinks component="kbd" />
|
||||
<ComponentLinks component="kbd" rscCompatible />
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@ import {skeletonContent} from "@/content/components/skeleton";
|
||||
|
||||
Skeleton is a placeholder to show a loading state and the expected shape of a component.
|
||||
|
||||
<ComponentLinks component="skeleton" />
|
||||
<ComponentLinks component="skeleton" rscCompatible />
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@ import {spacerContent} from "@/content/components/spacer";
|
||||
|
||||
Spacer is a component used to add space between components.
|
||||
|
||||
<ComponentLinks component="spacer" />
|
||||
<ComponentLinks component="spacer" rscCompatible />
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@ import {spinnerContent} from "@/content/components/spinner";
|
||||
|
||||
Spinner express an unspecified wait time or display the length of a process.
|
||||
|
||||
<ComponentLinks component="spinner" />
|
||||
<ComponentLinks component="spinner" rscCompatible />
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -22,6 +22,13 @@
|
||||
"@nextui-org/shared-icons": "workspace:*",
|
||||
"@nextui-org/shared-utils": "workspace:*",
|
||||
"@nextui-org/theme": "workspace:*",
|
||||
"@nextui-org/spacer": "workspace:*",
|
||||
"@nextui-org/kbd": "workspace:*",
|
||||
"@nextui-org/code": "workspace:*",
|
||||
"@nextui-org/badge": "workspace:*",
|
||||
"@nextui-org/skeleton": "workspace:*",
|
||||
"@nextui-org/spinner": "workspace:*",
|
||||
"@nextui-org/divider": "workspace:*",
|
||||
"@nextui-org/use-clipboard": "workspace:*",
|
||||
"@nextui-org/use-infinite-scroll": "workspace:*",
|
||||
"@nextui-org/use-is-mobile": "workspace:*",
|
||||
|
||||
@ -67,6 +67,7 @@ export function useAccordionItem<T extends object = {}>(props: UseAccordionItemP
|
||||
} = props;
|
||||
|
||||
const Component = as || "div";
|
||||
const shouldFilterDOMProps = typeof Component === "string";
|
||||
|
||||
const domRef = useDOMRef<HTMLButtonElement>(ref);
|
||||
|
||||
@ -132,10 +133,15 @@ export function useAccordionItem<T extends object = {}>(props: UseAccordionItemP
|
||||
"data-open": dataAttr(isOpen),
|
||||
"data-disabled": dataAttr(isDisabled),
|
||||
className: slots.base({class: baseStyles}),
|
||||
...mergeProps(filterDOMProps(otherProps), props),
|
||||
...mergeProps(
|
||||
filterDOMProps(otherProps, {
|
||||
enabled: shouldFilterDOMProps,
|
||||
}),
|
||||
props,
|
||||
),
|
||||
};
|
||||
},
|
||||
[baseStyles, otherProps, slots, item.props, isOpen, isDisabled],
|
||||
[baseStyles, shouldFilterDOMProps, otherProps, slots, item.props, isOpen, isDisabled],
|
||||
);
|
||||
|
||||
const getButtonProps: PropGetter = (props = {}) => {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import type {ReactNode} from "react";
|
||||
|
||||
import {forwardRef} from "@nextui-org/system";
|
||||
import {forwardRef} from "@nextui-org/system/utils";
|
||||
|
||||
import {UseBadgeProps, useBadge} from "./use-badge";
|
||||
|
||||
@ -11,13 +11,14 @@ export interface BadgeProps extends UseBadgeProps {
|
||||
const Badge = forwardRef<"span", BadgeProps>((props, ref) => {
|
||||
const {Component, children, content, slots, classNames, getBadgeProps} = useBadge({
|
||||
...props,
|
||||
ref,
|
||||
});
|
||||
|
||||
return (
|
||||
<div className={slots.base({class: classNames?.base})}>
|
||||
{children}
|
||||
<Component {...getBadgeProps()}>{content}</Component>
|
||||
<Component ref={ref} {...getBadgeProps()}>
|
||||
{content}
|
||||
</Component>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
@ -2,8 +2,8 @@ import type {BadgeSlots, BadgeVariantProps, SlotsToClasses} from "@nextui-org/th
|
||||
import type {ReactNode} from "react";
|
||||
|
||||
import {badge} from "@nextui-org/theme";
|
||||
import {HTMLNextUIProps, mapPropsVariants, PropGetter} from "@nextui-org/system";
|
||||
import {useDOMRef} from "@nextui-org/react-utils";
|
||||
import {HTMLNextUIProps, PropGetter} from "@nextui-org/system/types";
|
||||
import {mapPropsVariants} from "@nextui-org/system/utils";
|
||||
import {clsx} from "@nextui-org/shared-utils";
|
||||
import {ReactRef} from "@nextui-org/react-utils";
|
||||
import {useMemo} from "react";
|
||||
@ -41,12 +41,10 @@ export type UseBadgeProps = Props & BadgeVariantProps;
|
||||
export function useBadge(originalProps: UseBadgeProps) {
|
||||
const [props, variantProps] = mapPropsVariants(originalProps, badge.variantKeys);
|
||||
|
||||
const {as, ref, children, className, content, classNames, ...otherProps} = props;
|
||||
const {as, children, className, content, classNames, ...otherProps} = props;
|
||||
|
||||
const Component = as || "span";
|
||||
|
||||
const domRef = useDOMRef(ref);
|
||||
|
||||
const isOneChar = useMemo(
|
||||
() => String(content)?.length === 1 || originalProps?.isOneChar,
|
||||
[content, originalProps?.isOneChar],
|
||||
@ -68,7 +66,6 @@ export function useBadge(originalProps: UseBadgeProps) {
|
||||
|
||||
const getBadgeProps: PropGetter = () => {
|
||||
return {
|
||||
ref: domRef,
|
||||
className: slots.badge({class: baseStyles}),
|
||||
"data-invisible": originalProps.isInvisible,
|
||||
...otherProps,
|
||||
|
||||
@ -4,5 +4,4 @@ export default defineConfig({
|
||||
clean: true,
|
||||
target: "es2019",
|
||||
format: ["cjs", "esm"],
|
||||
banner: {js: '"use client";'},
|
||||
});
|
||||
|
||||
@ -92,6 +92,7 @@ export function useButton(props: UseButtonProps) {
|
||||
} = props;
|
||||
|
||||
const Component = as || "button";
|
||||
const shouldFilterDOMProps = typeof Component === "string";
|
||||
|
||||
const domRef = useDOMRef(ref);
|
||||
|
||||
@ -164,7 +165,9 @@ export function useButton(props: UseButtonProps) {
|
||||
ariaButtonProps,
|
||||
focusProps,
|
||||
hoverProps,
|
||||
filterDOMProps(otherProps),
|
||||
filterDOMProps(otherProps, {
|
||||
enabled: shouldFilterDOMProps,
|
||||
}),
|
||||
filterDOMProps(props),
|
||||
),
|
||||
}),
|
||||
@ -173,6 +176,7 @@ export function useButton(props: UseButtonProps) {
|
||||
isDisabled,
|
||||
isFocused,
|
||||
isPressed,
|
||||
shouldFilterDOMProps,
|
||||
isFocusVisible,
|
||||
isHovered,
|
||||
ariaButtonProps,
|
||||
|
||||
@ -81,6 +81,7 @@ export function useCard(originalProps: UseCardProps) {
|
||||
|
||||
const domRef = useDOMRef<HTMLDivElement>(ref);
|
||||
const Component = as || (originalProps.isPressable ? "button" : "div");
|
||||
const shouldFilterDOMProps = typeof Component === "string";
|
||||
|
||||
const baseStyles = clsx(classNames?.base, className);
|
||||
|
||||
@ -154,7 +155,9 @@ export function useCard(originalProps: UseCardProps) {
|
||||
...mergeProps(
|
||||
originalProps.isPressable ? {...buttonProps, ...focusProps, role: "button"} : {},
|
||||
originalProps.isHoverable ? hoverProps : {},
|
||||
filterDOMProps(otherProps),
|
||||
filterDOMProps(otherProps, {
|
||||
enabled: shouldFilterDOMProps,
|
||||
}),
|
||||
filterDOMProps(props),
|
||||
),
|
||||
};
|
||||
@ -163,6 +166,7 @@ export function useCard(originalProps: UseCardProps) {
|
||||
domRef,
|
||||
slots,
|
||||
baseStyles,
|
||||
shouldFilterDOMProps,
|
||||
originalProps.isPressable,
|
||||
originalProps.isHoverable,
|
||||
originalProps.isDisabled,
|
||||
|
||||
@ -1,13 +1,17 @@
|
||||
import {forwardRef} from "@nextui-org/system";
|
||||
import {forwardRef} from "@nextui-org/system/utils";
|
||||
|
||||
import {useCode, UseCodeProps} from "./use-code";
|
||||
|
||||
export interface CodeProps extends UseCodeProps {}
|
||||
|
||||
const Code = forwardRef<"div", CodeProps>((props, ref) => {
|
||||
const {Component, children, getCodeProps} = useCode({...props, ref});
|
||||
const {Component, children, getCodeProps} = useCode({...props});
|
||||
|
||||
return <Component {...getCodeProps()}>{children}</Component>;
|
||||
return (
|
||||
<Component ref={ref} {...getCodeProps()}>
|
||||
{children}
|
||||
</Component>
|
||||
);
|
||||
});
|
||||
|
||||
Code.displayName = "NextUI.Code";
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import type {CodeVariantProps} from "@nextui-org/theme";
|
||||
|
||||
import {code} from "@nextui-org/theme";
|
||||
import {HTMLNextUIProps, PropGetter, mapPropsVariants} from "@nextui-org/system";
|
||||
import {useDOMRef} from "@nextui-org/react-utils";
|
||||
import {HTMLNextUIProps, PropGetter} from "@nextui-org/system/types";
|
||||
import {mapPropsVariants} from "@nextui-org/system/utils";
|
||||
import {ReactRef} from "@nextui-org/react-utils";
|
||||
import {useMemo} from "react";
|
||||
|
||||
@ -16,12 +16,10 @@ export interface UseCodeProps extends HTMLNextUIProps<"code">, CodeVariantProps
|
||||
export function useCode(originalProps: UseCodeProps) {
|
||||
const [props, variantProps] = mapPropsVariants(originalProps, code.variantKeys);
|
||||
|
||||
const {ref, as, children, className, ...otherProps} = props;
|
||||
const {as, children, className, ...otherProps} = props;
|
||||
|
||||
const Component = as || "code";
|
||||
|
||||
const domRef = useDOMRef(ref);
|
||||
|
||||
const classNames = useMemo(
|
||||
() =>
|
||||
code({
|
||||
@ -33,7 +31,6 @@ export function useCode(originalProps: UseCodeProps) {
|
||||
|
||||
const getCodeProps: PropGetter = () => {
|
||||
return {
|
||||
ref: domRef,
|
||||
className: classNames,
|
||||
...otherProps,
|
||||
};
|
||||
|
||||
@ -4,5 +4,4 @@ export default defineConfig({
|
||||
clean: true,
|
||||
target: "es2019",
|
||||
format: ["cjs", "esm"],
|
||||
banner: {js: '"use client";'},
|
||||
});
|
||||
|
||||
@ -38,11 +38,10 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@nextui-org/shared-utils": "workspace:*",
|
||||
"@nextui-org/react-utils": "workspace:*",
|
||||
"@nextui-org/react-rsc-utils": "workspace:*",
|
||||
"@nextui-org/system": "workspace:*",
|
||||
"@nextui-org/theme": "workspace:*",
|
||||
"@react-aria/separator": "^3.3.3",
|
||||
"@react-aria/utils": "^3.18.0"
|
||||
"@react-types/shared": "^3.18.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"clean-package": "2.2.0",
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
import {forwardRef} from "@nextui-org/system";
|
||||
import {forwardRef} from "@nextui-org/system/utils";
|
||||
|
||||
import {UseDividerProps, useDivider} from "./use-divider";
|
||||
|
||||
export interface DividerProps extends Omit<UseDividerProps, "children"> {}
|
||||
|
||||
const Divider = forwardRef<"div", DividerProps>((props, ref) => {
|
||||
const {Component, getDividerProps} = useDivider({ref, ...props});
|
||||
const {Component, getDividerProps} = useDivider({...props});
|
||||
|
||||
return <Component {...getDividerProps()} />;
|
||||
return <Component ref={ref} {...getDividerProps()} />;
|
||||
});
|
||||
|
||||
Divider.displayName = "NextUI.Divider";
|
||||
|
||||
@ -1,11 +1,10 @@
|
||||
import type {DividerVariantProps} from "@nextui-org/theme";
|
||||
|
||||
import {SeparatorProps as AriaSeparatorProps, useSeparator} from "@react-aria/separator";
|
||||
import {HTMLNextUIProps, PropGetter} from "@nextui-org/system";
|
||||
import {HTMLNextUIProps, PropGetter} from "@nextui-org/system/types";
|
||||
import {divider} from "@nextui-org/theme";
|
||||
import {useDOMRef} from "@nextui-org/react-utils";
|
||||
import {Ref, useCallback, useMemo} from "react";
|
||||
import {mergeProps} from "@react-aria/utils";
|
||||
|
||||
import {SeparatorProps as AriaSeparatorProps, useSeparator} from "./use-separator";
|
||||
|
||||
interface Props extends HTMLNextUIProps<"hr"> {
|
||||
/**
|
||||
@ -17,12 +16,10 @@ interface Props extends HTMLNextUIProps<"hr"> {
|
||||
export type UseDividerProps = Props & DividerVariantProps & Omit<AriaSeparatorProps, "elementType">;
|
||||
|
||||
export function useDivider(props: UseDividerProps) {
|
||||
const {ref, as, className, orientation, ...otherProps} = props;
|
||||
const {as, className, orientation, ...otherProps} = props;
|
||||
|
||||
let Component = as || "hr";
|
||||
|
||||
const domRef = useDOMRef(ref);
|
||||
|
||||
if (Component === "hr" && orientation === "vertical") {
|
||||
Component = "div";
|
||||
}
|
||||
@ -43,13 +40,14 @@ export function useDivider(props: UseDividerProps) {
|
||||
|
||||
const getDividerProps: PropGetter = useCallback(
|
||||
(props = {}) => ({
|
||||
ref: domRef,
|
||||
className: styles,
|
||||
role: "separator",
|
||||
"data-orientation": orientation,
|
||||
...mergeProps(separatorProps, otherProps, props),
|
||||
...separatorProps,
|
||||
...otherProps,
|
||||
...props,
|
||||
}),
|
||||
[domRef, styles, orientation, separatorProps, otherProps],
|
||||
[styles, orientation, separatorProps, otherProps],
|
||||
);
|
||||
|
||||
return {Component, getDividerProps};
|
||||
|
||||
53
packages/components/divider/src/use-separator.ts
Normal file
53
packages/components/divider/src/use-separator.ts
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Based on @react-aria/separator but with some changes to support RSC.
|
||||
*/
|
||||
|
||||
import type {AriaLabelingProps, DOMAttributes, DOMProps, Orientation} from "@react-types/shared";
|
||||
|
||||
import {filterDOMProps} from "@nextui-org/react-rsc-utils";
|
||||
|
||||
export interface SeparatorProps extends DOMProps, AriaLabelingProps {
|
||||
/**
|
||||
* The orientation of the separator.
|
||||
* @default 'horizontal'
|
||||
*/
|
||||
orientation?: Orientation;
|
||||
/** The HTML element type that will be used to render the separator. */
|
||||
elementType?: string;
|
||||
}
|
||||
|
||||
export interface SeparatorAria {
|
||||
/** Props for the separator element. */
|
||||
separatorProps: DOMAttributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the accessibility implementation for a separator.
|
||||
* A separator is a visual divider between two groups of content,
|
||||
* e.g. groups of menu items or sections of a page.
|
||||
*/
|
||||
export function useSeparator(props: SeparatorProps): SeparatorAria {
|
||||
let domProps = filterDOMProps(props, {
|
||||
enabled: typeof props.elementType === "string",
|
||||
});
|
||||
|
||||
let ariaOrientation: Orientation | undefined;
|
||||
|
||||
// if orientation is horizontal, aria-orientation default is horizontal, so we leave it undefined
|
||||
// if it's vertical, we need to specify it
|
||||
if (props.orientation === "vertical") {
|
||||
ariaOrientation = "vertical";
|
||||
}
|
||||
// hr elements implicitly have role = separator and a horizontal orientation
|
||||
if (props.elementType !== "hr") {
|
||||
return {
|
||||
separatorProps: {
|
||||
...domProps,
|
||||
role: "separator",
|
||||
"aria-orientation": ariaOrientation,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return {separatorProps: domProps};
|
||||
}
|
||||
@ -4,5 +4,4 @@ export default defineConfig({
|
||||
clean: true,
|
||||
target: "es2019",
|
||||
format: ["cjs", "esm"],
|
||||
banner: {js: '"use client";'},
|
||||
});
|
||||
|
||||
@ -59,6 +59,7 @@ export function useDropdownItem<T extends object>(originalProps: UseDropdownItem
|
||||
const domRef = useRef<HTMLLIElement>(null);
|
||||
|
||||
const Component = as || "li";
|
||||
const shouldFilterDOMProps = typeof Component === "string";
|
||||
|
||||
const {rendered, key} = item;
|
||||
|
||||
@ -127,7 +128,9 @@ export function useDropdownItem<T extends object>(originalProps: UseDropdownItem
|
||||
itemProps,
|
||||
isReadOnly ? {} : mergeProps(focusProps, pressProps),
|
||||
hoverProps,
|
||||
filterDOMProps(otherProps),
|
||||
filterDOMProps(otherProps, {
|
||||
enabled: shouldFilterDOMProps,
|
||||
}),
|
||||
props,
|
||||
),
|
||||
"data-focus": dataAttr(isFocused),
|
||||
|
||||
@ -93,6 +93,7 @@ export function useInput<T extends HTMLInputElement | HTMLTextAreaElement = HTML
|
||||
);
|
||||
|
||||
const Component = as || "div";
|
||||
|
||||
const baseStyles = clsx(classNames?.base, className, !!inputValue ? "is-filled" : "");
|
||||
const isMultiline = originalProps.isMultiline;
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import {useMemo} from "react";
|
||||
import {forwardRef} from "@nextui-org/system";
|
||||
import {forwardRef} from "@nextui-org/system/utils";
|
||||
|
||||
import {UseKbdProps, useKbd} from "./use-kbd";
|
||||
import {kbdKeysLabelMap, kbdKeysMap} from "./utils";
|
||||
@ -9,7 +9,6 @@ export interface KbdProps extends UseKbdProps {}
|
||||
const Kbd = forwardRef<"kbd", KbdProps>((props, ref) => {
|
||||
const {Component, children, slots, classNames, keysToRender, getKbdProps} = useKbd({
|
||||
...props,
|
||||
ref,
|
||||
});
|
||||
|
||||
const keysContent = useMemo(() => {
|
||||
@ -25,7 +24,7 @@ const Kbd = forwardRef<"kbd", KbdProps>((props, ref) => {
|
||||
}, [keysToRender]);
|
||||
|
||||
return (
|
||||
<Component {...getKbdProps()}>
|
||||
<Component ref={ref} {...getKbdProps()}>
|
||||
{keysContent}
|
||||
{children && <span className={slots.content({class: classNames?.content})}>{children}</span>}
|
||||
</Component>
|
||||
|
||||
@ -1,12 +1,11 @@
|
||||
import type {KbdVariantProps, KbdSlots, SlotsToClasses} from "@nextui-org/theme";
|
||||
|
||||
import {HTMLNextUIProps, mapPropsVariants, PropGetter} from "@nextui-org/system";
|
||||
import {HTMLNextUIProps, PropGetter} from "@nextui-org/system/types";
|
||||
import {mapPropsVariants} from "@nextui-org/system/utils";
|
||||
import {kbd} from "@nextui-org/theme";
|
||||
import {useDOMRef} from "@nextui-org/react-utils";
|
||||
import {clsx} from "@nextui-org/shared-utils";
|
||||
import {ReactRef} from "@nextui-org/react-utils";
|
||||
import {useMemo} from "react";
|
||||
import {mergeProps} from "@react-aria/utils";
|
||||
|
||||
import {KbdKey} from "./utils";
|
||||
|
||||
@ -40,12 +39,10 @@ export type UseKbdProps = Props & KbdVariantProps;
|
||||
export function useKbd(originalProps: UseKbdProps) {
|
||||
const [props, variantProps] = mapPropsVariants(originalProps, kbd.variantKeys);
|
||||
|
||||
const {ref, as, children, className, keys, title, classNames, ...otherProps} = props;
|
||||
const {as, children, className, keys, title, classNames, ...otherProps} = props;
|
||||
|
||||
const Component = as || "kbd";
|
||||
|
||||
const domRef = useDOMRef(ref);
|
||||
|
||||
const slots = useMemo(
|
||||
() =>
|
||||
kbd({
|
||||
@ -59,8 +56,8 @@ export function useKbd(originalProps: UseKbdProps) {
|
||||
const keysToRender = typeof keys === "string" ? [keys] : Array.isArray(keys) ? keys : [];
|
||||
|
||||
const getKbdProps: PropGetter = (props = {}) => ({
|
||||
ref: domRef,
|
||||
...mergeProps(otherProps, props),
|
||||
...otherProps,
|
||||
...props,
|
||||
className: clsx(slots.base({class: clsx(baseStyles, props.className)})),
|
||||
});
|
||||
|
||||
|
||||
@ -4,5 +4,4 @@ export default defineConfig({
|
||||
clean: true,
|
||||
target: "es2019",
|
||||
format: ["cjs", "esm"],
|
||||
banner: {js: '"use client";'},
|
||||
});
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
import {forwardRef} from "@nextui-org/system";
|
||||
import {forwardRef} from "@nextui-org/system/utils";
|
||||
|
||||
import {UseSkeletonProps, useSkeleton} from "./use-skeleton";
|
||||
|
||||
export interface SkeletonProps extends UseSkeletonProps {}
|
||||
|
||||
const Skeleton = forwardRef<"div", SkeletonProps>((props, ref) => {
|
||||
const {Component, children, getSkeletonProps, getContentProps} = useSkeleton({...props, ref});
|
||||
const {Component, children, getSkeletonProps, getContentProps} = useSkeleton({...props});
|
||||
|
||||
return (
|
||||
<Component {...getSkeletonProps()}>
|
||||
<Component ref={ref} {...getSkeletonProps()}>
|
||||
<div {...getContentProps()}>{children}</div>
|
||||
</Component>
|
||||
);
|
||||
|
||||
@ -1,17 +1,16 @@
|
||||
import type {SkeletonVariantProps, SkeletonSlots, SlotsToClasses} from "@nextui-org/theme";
|
||||
import type {HTMLNextUIProps, PropGetter} from "@nextui-org/system/types";
|
||||
|
||||
import {HTMLNextUIProps, mapPropsVariants, PropGetter} from "@nextui-org/system";
|
||||
import {mapPropsVariants} from "@nextui-org/system/utils";
|
||||
import {skeleton} from "@nextui-org/theme";
|
||||
import {useDOMRef} from "@nextui-org/react-utils";
|
||||
import {clsx, dataAttr} from "@nextui-org/shared-utils";
|
||||
import {ReactRef} from "@nextui-org/react-utils";
|
||||
import {useMemo} from "react";
|
||||
import {useMemo, Ref} from "react";
|
||||
|
||||
interface Props extends HTMLNextUIProps<"div"> {
|
||||
/**
|
||||
* Ref to the DOM node.
|
||||
*/
|
||||
ref?: ReactRef<HTMLElement | null>;
|
||||
ref?: Ref<HTMLElement | null>;
|
||||
/**
|
||||
* The skeleton will be visible while isLoading is `false`.
|
||||
* @default false
|
||||
@ -37,12 +36,10 @@ export type UseSkeletonProps = Props & SkeletonVariantProps;
|
||||
export function useSkeleton(originalProps: UseSkeletonProps) {
|
||||
const [props, variantProps] = mapPropsVariants(originalProps, skeleton.variantKeys);
|
||||
|
||||
const {ref, as, children, isLoaded = false, className, classNames, ...otherProps} = props;
|
||||
const {as, children, isLoaded = false, className, classNames, ...otherProps} = props;
|
||||
|
||||
const Component = as || "div";
|
||||
|
||||
const domRef = useDOMRef(ref);
|
||||
|
||||
const slots = useMemo(
|
||||
() =>
|
||||
skeleton({
|
||||
@ -55,7 +52,6 @@ export function useSkeleton(originalProps: UseSkeletonProps) {
|
||||
|
||||
const getSkeletonProps: PropGetter = (props = {}) => {
|
||||
return {
|
||||
ref: domRef,
|
||||
"data-loaded": dataAttr(isLoaded),
|
||||
className: slots.base({class: clsx(baseStyles, props?.className)}),
|
||||
...otherProps,
|
||||
@ -68,7 +64,7 @@ export function useSkeleton(originalProps: UseSkeletonProps) {
|
||||
};
|
||||
};
|
||||
|
||||
return {Component, domRef, children, slots, classNames, getSkeletonProps, getContentProps};
|
||||
return {Component, children, slots, classNames, getSkeletonProps, getContentProps};
|
||||
}
|
||||
|
||||
export type UseSkeletonReturn = ReturnType<typeof useSkeleton>;
|
||||
|
||||
@ -4,5 +4,4 @@ export default defineConfig({
|
||||
clean: true,
|
||||
target: "es2019",
|
||||
format: ["cjs", "esm"],
|
||||
banner: {js: '"use client";'},
|
||||
});
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
import {forwardRef} from "@nextui-org/system";
|
||||
import {forwardRef} from "@nextui-org/system/utils";
|
||||
|
||||
import {UseSpacerProps, useSpacer} from "./use-spacer";
|
||||
|
||||
export interface SpacerProps extends UseSpacerProps {}
|
||||
|
||||
const Spacer = forwardRef<"span", SpacerProps>((props, ref) => {
|
||||
const {Component, getSpacerProps} = useSpacer({...props, ref});
|
||||
const {Component, getSpacerProps} = useSpacer({...props});
|
||||
|
||||
return <Component {...getSpacerProps()} />;
|
||||
return <Component ref={ref} {...getSpacerProps()} />;
|
||||
});
|
||||
|
||||
Spacer.displayName = "NextUI.Spacer";
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import type {SpacerVariantProps} from "@nextui-org/theme";
|
||||
|
||||
import {HTMLNextUIProps, mapPropsVariants, PropGetter} from "@nextui-org/system";
|
||||
import {HTMLNextUIProps, PropGetter} from "@nextui-org/system/types";
|
||||
import {mapPropsVariants} from "@nextui-org/system/utils";
|
||||
import {spacer} from "@nextui-org/theme";
|
||||
import {useDOMRef} from "@nextui-org/react-utils";
|
||||
import {clsx, dataAttr} from "@nextui-org/shared-utils";
|
||||
import {ReactRef} from "@nextui-org/react-utils";
|
||||
import {useMemo} from "react";
|
||||
@ -39,12 +39,10 @@ export const getMargin = (value: Space) => {
|
||||
export function useSpacer(originalProps: UseSpacerProps) {
|
||||
const [props, variantProps] = mapPropsVariants(originalProps, spacer.variantKeys);
|
||||
|
||||
const {ref, as, className, x = 1, y = 1, ...otherProps} = props;
|
||||
const {as, className, x = 1, y = 1, ...otherProps} = props;
|
||||
|
||||
const Component = as || "span";
|
||||
|
||||
const domRef = useDOMRef(ref);
|
||||
|
||||
const styles = useMemo(
|
||||
() =>
|
||||
spacer({
|
||||
@ -58,7 +56,6 @@ export function useSpacer(originalProps: UseSpacerProps) {
|
||||
const marginTop = getMargin(y);
|
||||
|
||||
const getSpacerProps: PropGetter = (props = {}) => ({
|
||||
ref: domRef,
|
||||
...props,
|
||||
...otherProps,
|
||||
"aria-hidden": dataAttr(true),
|
||||
|
||||
@ -4,5 +4,4 @@ export default defineConfig({
|
||||
clean: true,
|
||||
target: "es2019",
|
||||
format: ["cjs", "esm"],
|
||||
banner: {js: '"use client";'},
|
||||
});
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
import {forwardRef} from "@nextui-org/system";
|
||||
import {forwardRef} from "@nextui-org/system/utils";
|
||||
|
||||
import {UseSpinnerProps, useSpinner} from "./use-spinner";
|
||||
|
||||
export interface SpinnerProps extends UseSpinnerProps {}
|
||||
|
||||
const Spinner = forwardRef<"div", SpinnerProps>((props, ref) => {
|
||||
const {domRef, slots, classNames, label, getSpinnerProps} = useSpinner({ref, ...props});
|
||||
const {slots, classNames, label, getSpinnerProps} = useSpinner({...props});
|
||||
|
||||
return (
|
||||
<div ref={domRef} {...getSpinnerProps()}>
|
||||
<div ref={ref} {...getSpinnerProps()}>
|
||||
<div className={slots.wrapper({class: classNames?.wrapper})}>
|
||||
<i className={slots.circle1({class: classNames?.circle1})} />
|
||||
<i className={slots.circle2({class: classNames?.circle2})} />
|
||||
|
||||
@ -1,17 +1,16 @@
|
||||
import type {SpinnerVariantProps, SpinnerSlots, SlotsToClasses} from "@nextui-org/theme";
|
||||
import type {HTMLNextUIProps, PropGetter} from "@nextui-org/system/types";
|
||||
|
||||
import {HTMLNextUIProps, mapPropsVariants, PropGetter} from "@nextui-org/system";
|
||||
import {mapPropsVariants} from "@nextui-org/system/utils";
|
||||
import {spinner} from "@nextui-org/theme";
|
||||
import {clsx} from "@nextui-org/shared-utils";
|
||||
import {ReactRef} from "@nextui-org/react-utils";
|
||||
import {useDOMRef} from "@nextui-org/react-utils";
|
||||
import {useMemo, useCallback} from "react";
|
||||
import {useMemo, useCallback, Ref} from "react";
|
||||
|
||||
interface Props extends HTMLNextUIProps<"div"> {
|
||||
/**
|
||||
* Ref to the DOM node.
|
||||
*/
|
||||
ref?: ReactRef<HTMLElement | null>;
|
||||
ref?: Ref<HTMLElement | null>;
|
||||
/**
|
||||
* Spinner label, in case you passed it will be used as `aria-label`.
|
||||
*/
|
||||
@ -39,9 +38,7 @@ export type UseSpinnerProps = Props & SpinnerVariantProps;
|
||||
export function useSpinner(originalProps: UseSpinnerProps) {
|
||||
const [props, variantProps] = mapPropsVariants(originalProps, spinner.variantKeys);
|
||||
|
||||
const {ref, children, className, classNames, label: labelProp, ...otherProps} = props;
|
||||
|
||||
const domRef = useDOMRef(ref);
|
||||
const {children, className, classNames, label: labelProp, ...otherProps} = props;
|
||||
|
||||
const slots = useMemo(() => spinner({...variantProps}), [...Object.values(variantProps)]);
|
||||
|
||||
@ -68,7 +65,7 @@ export function useSpinner(originalProps: UseSpinnerProps) {
|
||||
[ariaLabel, slots, baseStyles, otherProps],
|
||||
);
|
||||
|
||||
return {domRef, label, slots, classNames, getSpinnerProps};
|
||||
return {label, slots, classNames, getSpinnerProps};
|
||||
}
|
||||
|
||||
export type UseSpinnerReturn = ReturnType<typeof useSpinner>;
|
||||
|
||||
@ -4,5 +4,4 @@ export default defineConfig({
|
||||
clean: true,
|
||||
target: "es2019",
|
||||
format: ["cjs", "esm"],
|
||||
banner: {js: '"use client";'},
|
||||
});
|
||||
|
||||
@ -41,6 +41,8 @@ const TableBody = forwardRef<"tbody", TableBodyProps>((props, ref) => {
|
||||
} = props;
|
||||
|
||||
const Component = as || "tbody";
|
||||
const shouldFilterDOMProps = typeof Component === "string";
|
||||
|
||||
const domRef = useDOMRef(ref);
|
||||
|
||||
const {rowGroupProps} = useTableRowGroup();
|
||||
@ -126,7 +128,13 @@ const TableBody = forwardRef<"tbody", TableBodyProps>((props, ref) => {
|
||||
return (
|
||||
<Component
|
||||
ref={domRef}
|
||||
{...mergeProps(rowGroupProps, filterDOMProps(bodyProps), otherProps)}
|
||||
{...mergeProps(
|
||||
rowGroupProps,
|
||||
filterDOMProps(bodyProps, {
|
||||
enabled: shouldFilterDOMProps,
|
||||
}),
|
||||
otherProps,
|
||||
)}
|
||||
className={slots.tbody?.({class: tbodyStyles})}
|
||||
data-empty={dataAttr(collection.size === 0)}
|
||||
data-loading={dataAttr(isLoading)}
|
||||
|
||||
@ -29,6 +29,8 @@ const TableCell = forwardRef<"td", TableCellProps>((props, ref) => {
|
||||
const {as, className, node, rowKey, slots, state, classNames, ...otherProps} = props;
|
||||
|
||||
const Component = as || "td";
|
||||
const shouldFilterDOMProps = typeof Component === "string";
|
||||
|
||||
const domRef = useDOMRef(ref);
|
||||
|
||||
const {gridCellProps} = useTableCell({node}, state, domRef);
|
||||
@ -52,7 +54,14 @@ const TableCell = forwardRef<"td", TableCellProps>((props, ref) => {
|
||||
ref={domRef}
|
||||
data-focus-visible={dataAttr(isFocusVisible)}
|
||||
data-selected={dataAttr(isRowSelected)}
|
||||
{...mergeProps(gridCellProps, focusProps, filterDOMProps(node.props), otherProps)}
|
||||
{...mergeProps(
|
||||
gridCellProps,
|
||||
focusProps,
|
||||
filterDOMProps(node.props, {
|
||||
enabled: shouldFilterDOMProps,
|
||||
}),
|
||||
otherProps,
|
||||
)}
|
||||
className={slots.td?.({class: tdStyles})}
|
||||
>
|
||||
{cell}
|
||||
|
||||
@ -48,6 +48,8 @@ const TableCheckboxCell = forwardRef<"td", TableCheckboxCellProps>((props, ref)
|
||||
} = props;
|
||||
|
||||
const Component = as || "td";
|
||||
const shouldFilterDOMProps = typeof Component === "string";
|
||||
|
||||
const domRef = useDOMRef(ref);
|
||||
|
||||
const {gridCellProps} = useTableCell({node}, state, domRef);
|
||||
@ -67,7 +69,14 @@ const TableCheckboxCell = forwardRef<"td", TableCheckboxCellProps>((props, ref)
|
||||
ref={domRef}
|
||||
data-focus-visible={dataAttr(isFocusVisible)}
|
||||
data-selected={dataAttr(isRowSelected)}
|
||||
{...mergeProps(gridCellProps, focusProps, filterDOMProps(node.props), otherProps)}
|
||||
{...mergeProps(
|
||||
gridCellProps,
|
||||
focusProps,
|
||||
filterDOMProps(node.props, {
|
||||
enabled: shouldFilterDOMProps,
|
||||
}),
|
||||
otherProps,
|
||||
)}
|
||||
className={slots.td?.({class: tdStyles})}
|
||||
>
|
||||
{isSingleSelectionMode ? (
|
||||
|
||||
@ -27,6 +27,8 @@ const TableColumnHeader = forwardRef<"th", TableColumnHeaderProps>((props, ref)
|
||||
const {as, className, state, node, slots, classNames, ...otherProps} = props;
|
||||
|
||||
const Component = as || "th";
|
||||
const shouldFilterDOMProps = typeof Component === "string";
|
||||
|
||||
const domRef = useDOMRef(ref);
|
||||
|
||||
const {columnHeaderProps} = useTableColumnHeader({node}, state, domRef);
|
||||
@ -49,7 +51,9 @@ const TableColumnHeader = forwardRef<"th", TableColumnHeaderProps>((props, ref)
|
||||
{...mergeProps(
|
||||
columnHeaderProps,
|
||||
focusProps,
|
||||
filterDOMProps(columnProps),
|
||||
filterDOMProps(columnProps, {
|
||||
enabled: shouldFilterDOMProps,
|
||||
}),
|
||||
allowsSorting ? hoverProps : {},
|
||||
otherProps,
|
||||
)}
|
||||
|
||||
@ -23,6 +23,7 @@ const TableHeaderRow = forwardRef<"tr", TableHeaderRowProps>((props, ref) => {
|
||||
const {as, className, children, node, slots, classNames, state, ...otherProps} = props;
|
||||
|
||||
const Component = as || "tr";
|
||||
const shouldFilterDOMProps = typeof Component === "string";
|
||||
const domRef = useDOMRef(ref);
|
||||
|
||||
const {rowProps} = useTableHeaderRow({node}, state, domRef);
|
||||
@ -32,7 +33,13 @@ const TableHeaderRow = forwardRef<"tr", TableHeaderRowProps>((props, ref) => {
|
||||
return (
|
||||
<Component
|
||||
ref={domRef}
|
||||
{...mergeProps(rowProps, filterDOMProps(node.props), otherProps)}
|
||||
{...mergeProps(
|
||||
rowProps,
|
||||
filterDOMProps(node.props, {
|
||||
enabled: shouldFilterDOMProps,
|
||||
}),
|
||||
otherProps,
|
||||
)}
|
||||
className={slots.tr?.({class: trStyles})}
|
||||
>
|
||||
{children}
|
||||
|
||||
@ -28,6 +28,7 @@ const TableRow = forwardRef<"tr", TableRowProps>((props, ref) => {
|
||||
props;
|
||||
|
||||
const Component = as || "tr";
|
||||
const shouldFilterDOMProps = typeof Component === "string";
|
||||
|
||||
const domRef = useDOMRef(ref);
|
||||
|
||||
@ -70,7 +71,9 @@ const TableRow = forwardRef<"tr", TableRowProps>((props, ref) => {
|
||||
{...mergeProps(
|
||||
rowProps,
|
||||
isSelectable ? {...hoverProps, ...focusProps} : {},
|
||||
filterDOMProps(node.props),
|
||||
filterDOMProps(node.props, {
|
||||
enabled: shouldFilterDOMProps,
|
||||
}),
|
||||
otherProps,
|
||||
)}
|
||||
className={slots.tr?.({class: trStyles})}
|
||||
|
||||
@ -41,6 +41,8 @@ const TableSelectAllCheckbox = forwardRef<"th", TableSelectAllCheckboxProps>((pr
|
||||
} = props;
|
||||
|
||||
const Component = as || "th";
|
||||
const shouldFilterDOMProps = typeof Component === "string";
|
||||
|
||||
const domRef = useDOMRef(ref);
|
||||
|
||||
const {columnHeaderProps} = useTableColumnHeader({node}, state, domRef);
|
||||
@ -61,8 +63,12 @@ const TableSelectAllCheckbox = forwardRef<"th", TableSelectAllCheckboxProps>((pr
|
||||
{...mergeProps(
|
||||
columnHeaderProps,
|
||||
focusProps,
|
||||
filterDOMProps(node.props),
|
||||
filterDOMProps(otherProps),
|
||||
filterDOMProps(node.props, {
|
||||
enabled: shouldFilterDOMProps,
|
||||
}),
|
||||
filterDOMProps(otherProps, {
|
||||
enabled: shouldFilterDOMProps,
|
||||
}),
|
||||
)}
|
||||
className={slots.th?.({class: thStyles})}
|
||||
>
|
||||
|
||||
@ -162,6 +162,7 @@ export function useTable<T extends object>(originalProps: UseTableProps<T>) {
|
||||
} = props;
|
||||
|
||||
const Component = as || "table";
|
||||
const shouldFilterDOMProps = typeof Component === "string";
|
||||
|
||||
const domRef = useDOMRef(ref);
|
||||
const domBaseRef = useDOMRef(baseRef);
|
||||
@ -248,11 +249,17 @@ export function useTable<T extends object>(originalProps: UseTableProps<T>) {
|
||||
|
||||
const getTableProps: PropGetter = useCallback(
|
||||
(props) => ({
|
||||
...mergeProps(gridProps, filterDOMProps(otherProps), props),
|
||||
...mergeProps(
|
||||
gridProps,
|
||||
filterDOMProps(otherProps, {
|
||||
enabled: shouldFilterDOMProps,
|
||||
}),
|
||||
props,
|
||||
),
|
||||
ref: domRef,
|
||||
className: slots.table({class: clsx(classNames?.table, props?.className)}),
|
||||
}),
|
||||
[classNames?.table, slots, gridProps, otherProps],
|
||||
[classNames?.table, shouldFilterDOMProps, slots, gridProps, otherProps],
|
||||
);
|
||||
|
||||
return {
|
||||
|
||||
@ -49,6 +49,7 @@ const Tab = forwardRef<"button", TabItemProps>((props, ref) => {
|
||||
const domRef = useDOMRef(ref);
|
||||
|
||||
const Component = as || "button";
|
||||
const shouldFilterDOMProps = typeof Component === "string";
|
||||
|
||||
const {
|
||||
tabProps,
|
||||
@ -103,7 +104,9 @@ const Tab = forwardRef<"button", TabItemProps>((props, ref) => {
|
||||
...hoverProps,
|
||||
}
|
||||
: {},
|
||||
filterDOMProps(otherProps),
|
||||
filterDOMProps(otherProps, {
|
||||
enabled: shouldFilterDOMProps,
|
||||
}),
|
||||
)}
|
||||
className={slots.tab?.({class: tabStyles})}
|
||||
type={Component === "button" ? "button" : undefined}
|
||||
|
||||
@ -76,6 +76,7 @@ export function useTabs<T extends object>(originalProps: UseTabsProps<T>) {
|
||||
} = props;
|
||||
|
||||
const Component = as || "div";
|
||||
const shouldFilterDOMProps = typeof Component === "string";
|
||||
|
||||
const domRef = useDOMRef(ref);
|
||||
|
||||
@ -123,7 +124,12 @@ export function useTabs<T extends object>(originalProps: UseTabsProps<T>) {
|
||||
(props) => ({
|
||||
"data-slot": "base",
|
||||
className: slots.base({class: clsx(baseStyles, props?.className)}),
|
||||
...mergeProps(filterDOMProps(otherProps), props),
|
||||
...mergeProps(
|
||||
filterDOMProps(otherProps, {
|
||||
enabled: shouldFilterDOMProps,
|
||||
}),
|
||||
props,
|
||||
),
|
||||
}),
|
||||
[baseStyles, otherProps, slots],
|
||||
);
|
||||
|
||||
1
packages/core/system/extend-variants.d.ts
vendored
Normal file
1
packages/core/system/extend-variants.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
export * from "./dist/extend-variants";
|
||||
1
packages/core/system/extend-variants.js
Normal file
1
packages/core/system/extend-variants.js
Normal file
@ -0,0 +1 @@
|
||||
module.exports = require("./dist/extend-variants");
|
||||
@ -11,7 +11,13 @@
|
||||
"main": "src/index.ts",
|
||||
"sideEffects": false,
|
||||
"files": [
|
||||
"dist"
|
||||
"dist",
|
||||
"utils.js",
|
||||
"utils.d.ts",
|
||||
"types.js",
|
||||
"types.d.ts",
|
||||
"extend-variants.js",
|
||||
"extend-variants.d.ts"
|
||||
],
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
||||
1
packages/core/system/types.d.ts
vendored
Normal file
1
packages/core/system/types.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
export * from "./dist/types";
|
||||
1
packages/core/system/types.js
Normal file
1
packages/core/system/types.js
Normal file
@ -0,0 +1 @@
|
||||
module.exports = require("./dist/types");
|
||||
1
packages/core/system/utils.d.ts
vendored
Normal file
1
packages/core/system/utils.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
export * from "./dist/utils";
|
||||
1
packages/core/system/utils.js
Normal file
1
packages/core/system/utils.js
Normal file
@ -0,0 +1 @@
|
||||
module.exports = require("./dist/utils");
|
||||
24
packages/utilities/react-rsc-utils/README.md
Normal file
24
packages/utilities/react-rsc-utils/README.md
Normal file
@ -0,0 +1,24 @@
|
||||
# @nextui-org/react-rsc-utils
|
||||
|
||||
A Quick description of the component
|
||||
|
||||
> This is an internal utility, not intended for public usage.
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
yarn add @nextui-org/react-rsc-utils
|
||||
# or
|
||||
npm i @nextui-org/react-rsc-utils
|
||||
```
|
||||
|
||||
## Contribution
|
||||
|
||||
Yes please! See the
|
||||
[contributing guidelines](https://github.com/nextui-org/nextui/blob/master/CONTRIBUTING.md)
|
||||
for details.
|
||||
|
||||
## Licence
|
||||
|
||||
This project is licensed under the terms of the
|
||||
[MIT license](https://github.com/nextui-org/nextui/blob/master/LICENSE).
|
||||
1
packages/utilities/react-rsc-utils/children.d.ts
vendored
Normal file
1
packages/utilities/react-rsc-utils/children.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
export * from "./dist/children";
|
||||
1
packages/utilities/react-rsc-utils/children.js
vendored
Normal file
1
packages/utilities/react-rsc-utils/children.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
module.exports = require("./dist/children");
|
||||
1
packages/utilities/react-rsc-utils/filter-dom-props.d.ts
vendored
Normal file
1
packages/utilities/react-rsc-utils/filter-dom-props.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
export * from "./dist/filter-dom-props";
|
||||
1
packages/utilities/react-rsc-utils/filter-dom-props.js
vendored
Normal file
1
packages/utilities/react-rsc-utils/filter-dom-props.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
module.exports = require("./dist/filter-dom-props");
|
||||
52
packages/utilities/react-rsc-utils/package.json
Normal file
52
packages/utilities/react-rsc-utils/package.json
Normal file
@ -0,0 +1,52 @@
|
||||
{
|
||||
"name": "@nextui-org/react-rsc-utils",
|
||||
"version": "2.0.1",
|
||||
"description": "A set of utilities for react compatible with RSC",
|
||||
"keywords": [
|
||||
"react-rsc-utils"
|
||||
],
|
||||
"author": "Junior Garcia <jrgarciadev@gmail.com>",
|
||||
"homepage": "https://nextui.org",
|
||||
"license": "MIT",
|
||||
"main": "src/index.ts",
|
||||
"sideEffects": false,
|
||||
"files": [
|
||||
"dist",
|
||||
"children.d.ts",
|
||||
"children.js",
|
||||
"filter-dom-props.d.ts",
|
||||
"filter-dom-props.js"
|
||||
],
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/nextui-org/nextui.git",
|
||||
"directory": "packages/utilities/react-rsc-utils"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/nextui-org/nextui/issues"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsup src --dts",
|
||||
"build:fast": "tsup src",
|
||||
"dev": "yarn build:fast -- --watch",
|
||||
"clean": "rimraf dist .turbo",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"prepack": "clean-package",
|
||||
"postpack": "clean-package restore"
|
||||
},
|
||||
"devDependencies": {
|
||||
"clean-package": "2.2.0"
|
||||
},
|
||||
"clean-package": "../../../clean-package.config.json",
|
||||
"tsup": {
|
||||
"clean": true,
|
||||
"target": "es2019",
|
||||
"format": [
|
||||
"cjs",
|
||||
"esm"
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -14,6 +14,10 @@ const DOMPropNames = new Set([
|
||||
]);
|
||||
|
||||
interface Options {
|
||||
/**
|
||||
* If the filter should be enabled.
|
||||
*/
|
||||
enabled?: boolean;
|
||||
/**
|
||||
* If labelling associated aria properties should be included in the filter.
|
||||
*/
|
||||
@ -37,11 +41,16 @@ export function filterDOMProps(
|
||||
props: DOMProps & AriaLabelingProps,
|
||||
opts: Options = {
|
||||
labelable: true,
|
||||
enabled: true,
|
||||
},
|
||||
): DOMProps & AriaLabelingProps {
|
||||
let {labelable, propNames} = opts;
|
||||
let filteredProps = {};
|
||||
|
||||
if (!opts.enabled) {
|
||||
return props;
|
||||
}
|
||||
|
||||
for (const prop in props) {
|
||||
if (
|
||||
(Object.prototype.hasOwnProperty.call(props, prop) &&
|
||||
2
packages/utilities/react-rsc-utils/src/index.ts
Normal file
2
packages/utilities/react-rsc-utils/src/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export * from "./children";
|
||||
export * from "./filter-dom-props";
|
||||
4
packages/utilities/react-rsc-utils/tsconfig.json
Normal file
4
packages/utilities/react-rsc-utils/tsconfig.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"extends": "../../../tsconfig.json",
|
||||
"include": ["src", "index.ts"]
|
||||
}
|
||||
@ -38,7 +38,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@nextui-org/shared-utils": "workspace:*",
|
||||
"@react-aria/utils": "^3.18.0"
|
||||
"@nextui-org/react-rsc-utils": "workspace:*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"clean-package": "2.2.0",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
export * from "./context";
|
||||
export * from "./children";
|
||||
export * from "./refs";
|
||||
export * from "./dom";
|
||||
export * from "./dimensions";
|
||||
export * from "./filter-dom-props";
|
||||
|
||||
export * from "@nextui-org/react-rsc-utils";
|
||||
|
||||
@ -8,6 +8,7 @@ export function mockImage() {
|
||||
//@ts-expect-error
|
||||
window.Image = class Image {
|
||||
onload: VoidFunction = () => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log("called");
|
||||
};
|
||||
onerror: VoidFunction = () => {};
|
||||
|
||||
57
pnpm-lock.yaml
generated
57
pnpm-lock.yaml
generated
@ -273,6 +273,18 @@ importers:
|
||||
'@nextui-org/aria-utils':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/utilities/aria-utils
|
||||
'@nextui-org/badge':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/components/badge
|
||||
'@nextui-org/code':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/components/code
|
||||
'@nextui-org/divider':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/components/divider
|
||||
'@nextui-org/kbd':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/components/kbd
|
||||
'@nextui-org/react':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/core/react
|
||||
@ -282,6 +294,15 @@ importers:
|
||||
'@nextui-org/shared-utils':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/utilities/shared-utils
|
||||
'@nextui-org/skeleton':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/components/skeleton
|
||||
'@nextui-org/spacer':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/components/spacer
|
||||
'@nextui-org/spinner':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/components/spinner
|
||||
'@nextui-org/theme':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/core/theme
|
||||
@ -930,9 +951,9 @@ importers:
|
||||
|
||||
packages/components/divider:
|
||||
dependencies:
|
||||
'@nextui-org/react-utils':
|
||||
'@nextui-org/react-rsc-utils':
|
||||
specifier: workspace:*
|
||||
version: link:../../utilities/react-utils
|
||||
version: link:../../utilities/react-rsc-utils
|
||||
'@nextui-org/shared-utils':
|
||||
specifier: workspace:*
|
||||
version: link:../../utilities/shared-utils
|
||||
@ -942,12 +963,9 @@ importers:
|
||||
'@nextui-org/theme':
|
||||
specifier: workspace:*
|
||||
version: link:../../core/theme
|
||||
'@react-aria/separator':
|
||||
specifier: ^3.3.3
|
||||
version: 3.3.3(react@18.2.0)
|
||||
'@react-aria/utils':
|
||||
specifier: ^3.18.0
|
||||
version: 3.18.0(react@18.2.0)
|
||||
'@react-types/shared':
|
||||
specifier: ^3.18.1
|
||||
version: 3.18.1(react@18.2.0)
|
||||
devDependencies:
|
||||
clean-package:
|
||||
specifier: 2.2.0
|
||||
@ -2539,14 +2557,20 @@ importers:
|
||||
specifier: ^18.2.0
|
||||
version: 18.2.0
|
||||
|
||||
packages/utilities/react-rsc-utils:
|
||||
devDependencies:
|
||||
clean-package:
|
||||
specifier: 2.2.0
|
||||
version: 2.2.0
|
||||
|
||||
packages/utilities/react-utils:
|
||||
dependencies:
|
||||
'@nextui-org/react-rsc-utils':
|
||||
specifier: workspace:*
|
||||
version: link:../react-rsc-utils
|
||||
'@nextui-org/shared-utils':
|
||||
specifier: workspace:*
|
||||
version: link:../shared-utils
|
||||
'@react-aria/utils':
|
||||
specifier: ^3.18.0
|
||||
version: 3.18.0(react@18.2.0)
|
||||
devDependencies:
|
||||
clean-package:
|
||||
specifier: 2.2.0
|
||||
@ -7782,17 +7806,6 @@ packages:
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@react-aria/separator@3.3.3(react@18.2.0):
|
||||
resolution: {integrity: sha512-kBGEXSSUiJLPS9foS5/7jgzpdp3/Yb1aMvVuvRGuNxDUsPAmvaYUT3qZ44Zf3hoxKfRFb4452KcoZ03w3Jfcvg==}
|
||||
peerDependencies:
|
||||
react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0
|
||||
dependencies:
|
||||
'@react-aria/utils': 3.18.0(react@18.2.0)
|
||||
'@react-types/shared': 3.18.1(react@18.2.0)
|
||||
'@swc/helpers': 0.5.1
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@react-aria/ssr@3.6.0(react@18.2.0):
|
||||
resolution: {integrity: sha512-OFiYQdv+Yk7AO7IsQu/fAEPijbeTwrrEYvdNoJ3sblBBedD5j5fBTNWrUPNVlwC4XWWnWTCMaRIVsJujsFiWXg==}
|
||||
peerDependencies:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user