mirror of
https://github.com/nextui-org/nextui.git
synced 2025-12-08 19:26:11 +00:00
feat: mapPropsVariants implemented
This commit is contained in:
parent
67a3f7af60
commit
c1095c708a
@ -114,10 +114,12 @@ export function useAvatar(props: UseAvatarProps) {
|
||||
...otherProps
|
||||
} = props;
|
||||
|
||||
const Component = as || "span";
|
||||
|
||||
const domRef = useDOMRef(ref);
|
||||
const imgRef = useDOMRef(imgRefProp);
|
||||
|
||||
const Component = as || "span";
|
||||
const {isFocusVisible, focusProps} = useFocusRing();
|
||||
|
||||
const imageStatus = useImage({src, onError, ignoreFallback});
|
||||
const isImgLoaded = imageStatus === "loaded";
|
||||
@ -131,15 +133,6 @@ export function useAvatar(props: UseAvatarProps) {
|
||||
*/
|
||||
const showFallback = (!src || !isImgLoaded) && showFallbackProp;
|
||||
|
||||
const buttonStyles = useMemo(() => {
|
||||
if (as !== "button") return "";
|
||||
|
||||
// reset button styles
|
||||
return "appearance-none outline-none border-none cursor-pointer";
|
||||
}, [as]);
|
||||
|
||||
const {isFocusVisible, focusProps} = useFocusRing();
|
||||
|
||||
const slots = avatar({
|
||||
color,
|
||||
radius,
|
||||
@ -151,6 +144,13 @@ export function useAvatar(props: UseAvatarProps) {
|
||||
isInGridGroup: groupContext?.isGrid ?? false,
|
||||
});
|
||||
|
||||
const buttonStyles = useMemo(() => {
|
||||
if (as !== "button") return "";
|
||||
|
||||
// reset button styles
|
||||
return "appearance-none outline-none border-none cursor-pointer";
|
||||
}, [as]);
|
||||
|
||||
const imgStyles = clsx(
|
||||
"transition-opacity !duration-500 opacity-0 data-[loaded=true]:opacity-100",
|
||||
styles?.img,
|
||||
|
||||
@ -3,10 +3,9 @@ import type {LinkVariantProps} from "@nextui-org/theme";
|
||||
|
||||
import {link} from "@nextui-org/theme";
|
||||
import {useLink as useAriaLink} from "@react-aria/link";
|
||||
import {HTMLNextUIProps} from "@nextui-org/system";
|
||||
import {HTMLNextUIProps, mapPropsVariants} from "@nextui-org/system";
|
||||
import {useDOMRef} from "@nextui-org/dom-utils";
|
||||
import {ReactRef} from "@nextui-org/shared-utils";
|
||||
import {useMemo} from "react";
|
||||
|
||||
interface Props extends HTMLNextUIProps<"a">, LinkVariantProps {
|
||||
/**
|
||||
@ -32,24 +31,14 @@ interface Props extends HTMLNextUIProps<"a">, LinkVariantProps {
|
||||
|
||||
export type UseLinkProps = Props & AriaLinkProps;
|
||||
|
||||
export function useLink(props: UseLinkProps) {
|
||||
const {
|
||||
ref,
|
||||
as = "a",
|
||||
color,
|
||||
size,
|
||||
isUnderline,
|
||||
isBlock,
|
||||
disableAnimation,
|
||||
isExternal = false,
|
||||
showAnchorIcon = false,
|
||||
isDisabled = false,
|
||||
className,
|
||||
...otherProps
|
||||
} = props;
|
||||
export function useLink(originalProps: UseLinkProps) {
|
||||
const [props, variantProps] = mapPropsVariants(originalProps, link.variantKeys);
|
||||
|
||||
const {ref, as, isExternal = false, showAnchorIcon = false, className, ...otherProps} = props;
|
||||
|
||||
const Component = as || "a";
|
||||
|
||||
const domRef = useDOMRef(ref);
|
||||
const Component = as || "a";
|
||||
|
||||
const {linkProps} = useAriaLink({...otherProps, elementType: `${as}`}, domRef);
|
||||
|
||||
@ -62,19 +51,10 @@ export function useLink(props: UseLinkProps) {
|
||||
otherProps.role = "link";
|
||||
}
|
||||
|
||||
const styles = useMemo(
|
||||
() =>
|
||||
link({
|
||||
color,
|
||||
size,
|
||||
isUnderline,
|
||||
isBlock,
|
||||
isDisabled,
|
||||
disableAnimation,
|
||||
className,
|
||||
}),
|
||||
[color, size, isUnderline, isBlock, isDisabled, disableAnimation, className],
|
||||
);
|
||||
const styles = link({
|
||||
...variantProps,
|
||||
className,
|
||||
});
|
||||
|
||||
return {Component, as, styles, domRef, linkProps, showAnchorIcon, ...otherProps};
|
||||
}
|
||||
|
||||
@ -66,12 +66,12 @@ export function useUser(props: UseUserProps) {
|
||||
...otherProps
|
||||
} = props;
|
||||
|
||||
const Component = as || "div";
|
||||
|
||||
const domRef = useDOMRef(ref);
|
||||
|
||||
const {isFocusVisible, focusProps} = useFocusRing();
|
||||
|
||||
const Component = as || "div";
|
||||
|
||||
const canBeFocused = useMemo(() => {
|
||||
return isFocusable || as === "button";
|
||||
}, [isFocusable, as]);
|
||||
|
||||
@ -100,3 +100,20 @@ export function rootStyled<T extends As, P = {}>(component: T) {
|
||||
|
||||
return Component as NextUIComponent<T, P>;
|
||||
}
|
||||
|
||||
export const mapPropsVariants = <T extends Record<string, any>, K extends keyof T>(
|
||||
props: T,
|
||||
variantKeys?: K[],
|
||||
): readonly [Omit<T, K>, Pick<T, K> | {}] => {
|
||||
if (!variantKeys) {
|
||||
return [props, {}];
|
||||
}
|
||||
|
||||
const omitted = Object.keys(props)
|
||||
.filter((key) => !variantKeys.includes(key as K))
|
||||
.reduce((acc, key) => ({...acc, [key]: props[key as keyof T]}), {});
|
||||
|
||||
const picked = variantKeys.reduce((acc, key) => ({...acc, [key]: props[key]}), {});
|
||||
|
||||
return [omitted, picked] as [Omit<T, K>, Pick<T, K>];
|
||||
};
|
||||
|
||||
@ -78,6 +78,7 @@ const link = tv({
|
||||
size: "md",
|
||||
isBlock: false,
|
||||
isUnderline: false,
|
||||
isDisabled: false,
|
||||
disableAnimation: false,
|
||||
},
|
||||
});
|
||||
|
||||
50
pnpm-lock.yaml
generated
50
pnpm-lock.yaml
generated
@ -915,6 +915,17 @@ importers:
|
||||
clean-package: 2.1.1
|
||||
react: 17.0.2
|
||||
|
||||
packages/hooks/use-tv:
|
||||
specifiers:
|
||||
'@nextui-org/system': workspace:*
|
||||
clean-package: 2.1.1
|
||||
react: ^17.0.2
|
||||
dependencies:
|
||||
'@nextui-org/system': link:../../core/system
|
||||
devDependencies:
|
||||
clean-package: 2.1.1
|
||||
react: 17.0.2
|
||||
|
||||
packages/utilities/aria-utils:
|
||||
specifiers:
|
||||
'@nextui-org/system': workspace:*
|
||||
@ -5281,7 +5292,7 @@ packages:
|
||||
react-refresh: 0.11.0
|
||||
schema-utils: 3.1.1
|
||||
source-map: 0.7.4
|
||||
webpack: 5.75.0_igc2o5duttbeim43y2d2sdpxx4
|
||||
webpack: 5.75.0
|
||||
dev: true
|
||||
|
||||
/@polka/url/1.0.0-next.21:
|
||||
@ -10364,7 +10375,7 @@ packages:
|
||||
loader-utils: 2.0.4
|
||||
make-dir: 3.1.0
|
||||
schema-utils: 2.7.1
|
||||
webpack: 4.46.0_webpack-cli@3.3.12
|
||||
webpack: 4.46.0
|
||||
dev: true
|
||||
|
||||
/babel-plugin-add-module-exports/1.0.4:
|
||||
@ -10952,7 +10963,7 @@ packages:
|
||||
mississippi: 3.0.0
|
||||
mkdirp: 0.5.6
|
||||
move-concurrently: 1.0.1
|
||||
promise-inflight: 1.0.1_bluebird@3.7.2
|
||||
promise-inflight: 1.0.1
|
||||
rimraf: 2.7.1
|
||||
ssri: 6.0.2
|
||||
unique-filename: 1.1.1
|
||||
@ -11959,7 +11970,7 @@ packages:
|
||||
postcss-value-parser: 4.2.0
|
||||
schema-utils: 2.7.1
|
||||
semver: 6.3.0
|
||||
webpack: 4.46.0_webpack-cli@3.3.12
|
||||
webpack: 4.46.0
|
||||
dev: true
|
||||
|
||||
/css-loader/5.2.7_webpack@5.75.0:
|
||||
@ -14182,7 +14193,7 @@ packages:
|
||||
dependencies:
|
||||
loader-utils: 2.0.4
|
||||
schema-utils: 3.1.1
|
||||
webpack: 4.46.0_webpack-cli@3.3.12
|
||||
webpack: 4.46.0
|
||||
dev: true
|
||||
|
||||
/file-system-cache/1.1.0:
|
||||
@ -15401,7 +15412,7 @@ packages:
|
||||
pretty-error: 2.1.2
|
||||
tapable: 1.1.3
|
||||
util.promisify: 1.0.0
|
||||
webpack: 4.46.0_webpack-cli@3.3.12
|
||||
webpack: 4.46.0
|
||||
dev: true
|
||||
|
||||
/html-webpack-plugin/5.5.0_webpack@5.75.0:
|
||||
@ -19470,7 +19481,7 @@ packages:
|
||||
postcss: 7.0.39
|
||||
schema-utils: 3.1.1
|
||||
semver: 7.3.8
|
||||
webpack: 4.46.0_webpack-cli@3.3.12
|
||||
webpack: 4.46.0
|
||||
dev: true
|
||||
|
||||
/postcss-loader/4.3.0_postcss@7.0.39:
|
||||
@ -19847,17 +19858,6 @@ packages:
|
||||
optional: true
|
||||
dev: true
|
||||
|
||||
/promise-inflight/1.0.1_bluebird@3.7.2:
|
||||
resolution: {integrity: sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==}
|
||||
peerDependencies:
|
||||
bluebird: '*'
|
||||
peerDependenciesMeta:
|
||||
bluebird:
|
||||
optional: true
|
||||
dependencies:
|
||||
bluebird: 3.7.2
|
||||
dev: true
|
||||
|
||||
/promise.allsettled/1.0.6:
|
||||
resolution: {integrity: sha512-22wJUOD3zswWFqgwjNHa1965LvqTX87WPu/lreY2KSd7SVcERfuZ4GfUaOnJNnvtoIv2yXT/W00YIGMetXtFXg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@ -20059,7 +20059,7 @@ packages:
|
||||
dependencies:
|
||||
loader-utils: 2.0.4
|
||||
schema-utils: 3.1.1
|
||||
webpack: 4.46.0_webpack-cli@3.3.12
|
||||
webpack: 4.46.0
|
||||
dev: true
|
||||
|
||||
/react-autosuggest/10.1.0_react@17.0.2:
|
||||
@ -21920,7 +21920,7 @@ packages:
|
||||
dependencies:
|
||||
loader-utils: 2.0.4
|
||||
schema-utils: 2.7.1
|
||||
webpack: 4.46.0_webpack-cli@3.3.12
|
||||
webpack: 4.46.0
|
||||
dev: true
|
||||
|
||||
/style-loader/2.0.0_webpack@5.75.0:
|
||||
@ -22249,7 +22249,7 @@ packages:
|
||||
serialize-javascript: 4.0.0
|
||||
source-map: 0.6.1
|
||||
terser: 4.8.1
|
||||
webpack: 4.46.0_webpack-cli@3.3.12
|
||||
webpack: 4.46.0
|
||||
webpack-sources: 1.4.3
|
||||
worker-farm: 1.7.0
|
||||
dev: true
|
||||
@ -22268,7 +22268,7 @@ packages:
|
||||
serialize-javascript: 5.0.1
|
||||
source-map: 0.6.1
|
||||
terser: 5.16.3
|
||||
webpack: 4.46.0_webpack-cli@3.3.12
|
||||
webpack: 4.46.0
|
||||
webpack-sources: 1.4.3
|
||||
transitivePeerDependencies:
|
||||
- bluebird
|
||||
@ -23096,7 +23096,7 @@ packages:
|
||||
loader-utils: 2.0.4
|
||||
mime-types: 2.1.35
|
||||
schema-utils: 3.1.1
|
||||
webpack: 4.46.0_webpack-cli@3.3.12
|
||||
webpack: 4.46.0
|
||||
dev: true
|
||||
|
||||
/url-parse/1.5.10:
|
||||
@ -23442,7 +23442,7 @@ packages:
|
||||
mime: 2.6.0
|
||||
mkdirp: 0.5.6
|
||||
range-parser: 1.2.1
|
||||
webpack: 4.46.0_webpack-cli@3.3.12
|
||||
webpack: 4.46.0
|
||||
webpack-log: 2.0.0
|
||||
dev: true
|
||||
|
||||
@ -23467,7 +23467,7 @@ packages:
|
||||
peerDependencies:
|
||||
webpack: ^2.0.0 || ^3.0.0 || ^4.0.0
|
||||
dependencies:
|
||||
webpack: 4.46.0_webpack-cli@3.3.12
|
||||
webpack: 4.46.0
|
||||
dev: true
|
||||
|
||||
/webpack-hot-middleware/2.25.3:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user