廓形仪rn版本-技术调研
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

214 lines
4.6 KiB

'use client';
import React from 'react';
import { Text, View } from 'react-native';
import { PrimitiveIcon, UIIcon } from '@gluestack-ui/icon';
import { tva } from '@gluestack-ui/nativewind-utils/tva';
import {
withStyleContext,
useStyleContext,
} from '@gluestack-ui/nativewind-utils/withStyleContext';
import { cssInterop } from 'nativewind';
import type { VariantProps } from '@gluestack-ui/nativewind-utils';
import { Svg } from 'react-native-svg';
const SCOPE = 'BADGE';
const badgeStyle = tva({
base: 'flex-row items-center rounded-sm data-[disabled=true]:opacity-50 px-2 py-1',
variants: {
action: {
error: 'bg-background-error border-error-300',
warning: 'bg-background-warning border-warning-300',
success: 'bg-background-success border-success-300',
info: 'bg-background-info border-info-300',
muted: 'bg-background-muted border-background-300',
},
variant: {
solid: '',
outline: 'border',
},
size: {
sm: '',
md: '',
lg: '',
},
},
});
const badgeTextStyle = tva({
base: 'text-typography-700 font-body font-normal tracking-normal uppercase',
parentVariants: {
action: {
error: 'text-error-600',
warning: 'text-warning-600',
success: 'text-success-600',
info: 'text-info-600',
muted: 'text-background-800',
},
size: {
sm: 'text-2xs',
md: 'text-xs',
lg: 'text-sm',
},
},
variants: {
isTruncated: {
true: 'web:truncate',
},
bold: {
true: 'font-bold',
},
underline: {
true: 'underline',
},
strikeThrough: {
true: 'line-through',
},
sub: {
true: 'text-xs',
},
italic: {
true: 'italic',
},
highlight: {
true: 'bg-yellow-500',
},
},
});
const badgeIconStyle = tva({
base: 'fill-none',
parentVariants: {
action: {
error: 'text-error-600',
warning: 'text-warning-600',
success: 'text-success-600',
info: 'text-info-600',
muted: 'text-background-800',
},
size: {
sm: 'h-3 w-3',
md: 'h-3.5 w-3.5',
lg: 'h-4 w-4',
},
},
});
const ContextView = withStyleContext(View, SCOPE);
cssInterop(PrimitiveIcon, {
className: {
target: 'style',
nativeStyleToProp: {
height: true,
width: true,
fill: true,
color: 'classNameColor',
stroke: true,
},
},
});
type IBadgeProps = React.ComponentPropsWithoutRef<typeof ContextView> &
VariantProps<typeof badgeStyle>;
function Badge({
children,
action = 'muted',
variant = 'solid',
size = 'md',
className,
...props
}: { className?: string } & IBadgeProps) {
return (
<ContextView
className={badgeStyle({ action, variant, class: className })}
{...props}
context={{
action,
variant,
size,
}}
>
{children}
</ContextView>
);
}
type IBadgeTextProps = React.ComponentPropsWithoutRef<typeof Text> &
VariantProps<typeof badgeTextStyle>;
const BadgeText = React.forwardRef<
React.ComponentRef<typeof Text>,
IBadgeTextProps
>(function BadgeText({ children, className, size, ...props }, ref) {
const { size: parentSize, action: parentAction } = useStyleContext(SCOPE);
return (
<Text
ref={ref}
className={badgeTextStyle({
parentVariants: {
size: parentSize,
action: parentAction,
},
size,
class: className,
})}
{...props}
>
{children}
</Text>
);
});
type IBadgeIconProps = React.ComponentPropsWithoutRef<typeof PrimitiveIcon> &
VariantProps<typeof badgeIconStyle>;
const BadgeIcon = React.forwardRef<
React.ComponentRef<typeof Svg>,
IBadgeIconProps
>(function BadgeIcon({ className, size, ...props }, ref) {
const { size: parentSize, action: parentAction } = useStyleContext(SCOPE);
if (typeof size === 'number') {
return (
<UIIcon
ref={ref}
{...props}
className={badgeIconStyle({ class: className })}
size={size}
/>
);
} else if (
(props?.height !== undefined || props?.width !== undefined) &&
size === undefined
) {
return (
<UIIcon
ref={ref}
{...props}
className={badgeIconStyle({ class: className })}
/>
);
}
return (
<UIIcon
className={badgeIconStyle({
parentVariants: {
size: parentSize,
action: parentAction,
},
size,
class: className,
})}
{...props}
ref={ref}
/>
);
});
Badge.displayName = 'Badge';
BadgeText.displayName = 'BadgeText';
BadgeIcon.displayName = 'BadgeIcon';
export { Badge, BadgeIcon, BadgeText };