u
This commit is contained in:
1 parent
c0ff3ce883
commit
69d03709ba
41 files changed
+5352
-67
No files matched your search
@@ -0,0 +1,242 @@
|
||||
'use client';
|
||||
import React from 'react';
|
||||
import { createCheckbox } from '@gluestack-ui/core/checkbox/creator';
|
||||
import { View, Pressable, Text, Platform } from 'react-native';
|
||||
import type { TextProps, ViewProps } from 'react-native';
|
||||
import { tva } from '@gluestack-ui/utils/nativewind-utils';
|
||||
import {
|
||||
PrimitiveIcon,
|
||||
IPrimitiveIcon,
|
||||
UIIcon,
|
||||
} from '@gluestack-ui/core/icon/creator';
|
||||
import {
|
||||
withStyleContext,
|
||||
useStyleContext,
|
||||
} from '@gluestack-ui/utils/nativewind-utils';
|
||||
import { cssInterop } from 'nativewind';
|
||||
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils';
|
||||
|
||||
const IndicatorWrapper = React.forwardRef<
|
||||
React.ComponentRef<typeof View>,
|
||||
ViewProps
|
||||
>(function IndicatorWrapper({ ...props }, ref) {
|
||||
return <View {...props} ref={ref} />;
|
||||
});
|
||||
|
||||
const LabelWrapper = React.forwardRef<
|
||||
React.ComponentRef<typeof Text>,
|
||||
TextProps
|
||||
>(function LabelWrapper({ ...props }, ref) {
|
||||
return <Text {...props} ref={ref} />;
|
||||
});
|
||||
|
||||
const IconWrapper = React.forwardRef<
|
||||
React.ComponentRef<typeof PrimitiveIcon>,
|
||||
IPrimitiveIcon
|
||||
>(function IconWrapper({ ...props }, ref) {
|
||||
return <UIIcon {...props} ref={ref} />;
|
||||
});
|
||||
|
||||
const SCOPE = 'CHECKBOX';
|
||||
const UICheckbox = createCheckbox({
|
||||
// @ts-expect-error : internal implementation for r-19/react-native-web
|
||||
Root:
|
||||
Platform.OS === 'web'
|
||||
? withStyleContext(View, SCOPE)
|
||||
: withStyleContext(Pressable, SCOPE),
|
||||
Group: View,
|
||||
Icon: IconWrapper,
|
||||
Label: LabelWrapper,
|
||||
Indicator: IndicatorWrapper,
|
||||
});
|
||||
|
||||
cssInterop(PrimitiveIcon, {
|
||||
className: {
|
||||
target: 'style',
|
||||
nativeStyleToProp: {
|
||||
height: true,
|
||||
width: true,
|
||||
fill: true,
|
||||
color: 'classNameColor',
|
||||
stroke: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const checkboxStyle = tva({
|
||||
base: 'group/checkbox flex-row items-center justify-start web:cursor-pointer data-[disabled=true]:cursor-not-allowed',
|
||||
variants: {
|
||||
size: {
|
||||
lg: 'gap-2',
|
||||
md: 'gap-2',
|
||||
sm: 'gap-1.5',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const checkboxIndicatorStyle = tva({
|
||||
base: 'justify-center items-center border-outline-400 bg-transparent rounded web:data-[focus-visible=true]:outline-none web:data-[focus-visible=true]:ring-2 web:data-[focus-visible=true]:ring-indicator-primary data-[checked=true]:bg-primary-600 data-[checked=true]:border-primary-600 data-[hover=true]:data-[checked=false]:border-outline-500 data-[hover=true]:bg-transparent data-[hover=true]:data-[invalid=true]:border-error-700 data-[hover=true]:data-[checked=true]:bg-primary-700 data-[hover=true]:data-[checked=true]:border-primary-700 data-[hover=true]:data-[checked=true]:data-[disabled=true]:border-primary-600 data-[hover=true]:data-[checked=true]:data-[disabled=true]:bg-primary-600 data-[hover=true]:data-[checked=true]:data-[disabled=true]:opacity-40 data-[hover=true]:data-[checked=true]:data-[disabled=true]:data-[invalid=true]:border-error-700 data-[hover=true]:data-[disabled=true]:border-outline-400 data-[hover=true]:data-[disabled=true]:data-[invalid=true]:border-error-700 data-[active=true]:data-[checked=true]:bg-primary-800 data-[active=true]:data-[checked=true]:border-primary-800 data-[invalid=true]:border-error-700 data-[disabled=true]:opacity-40',
|
||||
parentVariants: {
|
||||
size: {
|
||||
lg: 'w-6 h-6 border-[3px]',
|
||||
md: 'w-5 h-5 border-2',
|
||||
sm: 'w-4 h-4 border-2',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const checkboxLabelStyle = tva({
|
||||
base: 'text-typography-600 data-[checked=true]:text-typography-900 data-[hover=true]:text-typography-900 data-[hover=true]:data-[checked=true]:text-typography-900 data-[hover=true]:data-[checked=true]:data-[disabled=true]:text-typography-900 data-[hover=true]:data-[disabled=true]:text-typography-400 data-[active=true]:text-typography-900 data-[active=true]:data-[checked=true]:text-typography-900 data-[disabled=true]:opacity-40 web:select-none',
|
||||
parentVariants: {
|
||||
size: {
|
||||
lg: 'text-lg',
|
||||
md: 'text-base',
|
||||
sm: 'text-sm',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const checkboxIconStyle = tva({
|
||||
base: 'text-typography-50 fill-none',
|
||||
|
||||
parentVariants: {
|
||||
size: {
|
||||
sm: 'h-3 w-3',
|
||||
md: 'h-4 w-4',
|
||||
lg: 'h-5 w-5',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const CheckboxGroup = UICheckbox.Group;
|
||||
|
||||
type ICheckboxProps = React.ComponentPropsWithoutRef<typeof UICheckbox> &
|
||||
VariantProps<typeof checkboxStyle>;
|
||||
|
||||
const Checkbox = React.forwardRef<
|
||||
React.ComponentRef<typeof UICheckbox>,
|
||||
ICheckboxProps
|
||||
>(function Checkbox({ className, size = 'md', ...props }, ref) {
|
||||
return (
|
||||
<UICheckbox
|
||||
className={checkboxStyle({
|
||||
class: className,
|
||||
size,
|
||||
})}
|
||||
{...props}
|
||||
context={{
|
||||
size,
|
||||
}}
|
||||
ref={ref}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
type ICheckboxIndicatorProps = React.ComponentPropsWithoutRef<
|
||||
typeof UICheckbox.Indicator
|
||||
> &
|
||||
VariantProps<typeof checkboxIndicatorStyle>;
|
||||
|
||||
const CheckboxIndicator = React.forwardRef<
|
||||
React.ComponentRef<typeof UICheckbox.Indicator>,
|
||||
ICheckboxIndicatorProps
|
||||
>(function CheckboxIndicator({ className, ...props }, ref) {
|
||||
const { size: parentSize } = useStyleContext(SCOPE);
|
||||
|
||||
return (
|
||||
<UICheckbox.Indicator
|
||||
className={checkboxIndicatorStyle({
|
||||
parentVariants: {
|
||||
size: parentSize,
|
||||
},
|
||||
class: className,
|
||||
})}
|
||||
{...props}
|
||||
ref={ref}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
type ICheckboxLabelProps = React.ComponentPropsWithoutRef<
|
||||
typeof UICheckbox.Label
|
||||
> &
|
||||
VariantProps<typeof checkboxLabelStyle>;
|
||||
const CheckboxLabel = React.forwardRef<
|
||||
React.ComponentRef<typeof UICheckbox.Label>,
|
||||
ICheckboxLabelProps
|
||||
>(function CheckboxLabel({ className, ...props }, ref) {
|
||||
const { size: parentSize } = useStyleContext(SCOPE);
|
||||
return (
|
||||
<UICheckbox.Label
|
||||
className={checkboxLabelStyle({
|
||||
parentVariants: {
|
||||
size: parentSize,
|
||||
},
|
||||
class: className,
|
||||
})}
|
||||
{...props}
|
||||
ref={ref}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
type ICheckboxIconProps = React.ComponentPropsWithoutRef<
|
||||
typeof UICheckbox.Icon
|
||||
> &
|
||||
VariantProps<typeof checkboxIconStyle>;
|
||||
|
||||
const CheckboxIcon = React.forwardRef<
|
||||
React.ComponentRef<typeof UICheckbox.Icon>,
|
||||
ICheckboxIconProps
|
||||
>(function CheckboxIcon({ className, size, ...props }, ref) {
|
||||
const { size: parentSize } = useStyleContext(SCOPE);
|
||||
|
||||
if (typeof size === 'number') {
|
||||
return (
|
||||
<UICheckbox.Icon
|
||||
ref={ref}
|
||||
{...props}
|
||||
className={checkboxIconStyle({ class: className })}
|
||||
size={size}
|
||||
/>
|
||||
);
|
||||
} else if (
|
||||
(props.height !== undefined || props.width !== undefined) &&
|
||||
size === undefined
|
||||
) {
|
||||
return (
|
||||
<UICheckbox.Icon
|
||||
ref={ref}
|
||||
{...props}
|
||||
className={checkboxIconStyle({ class: className })}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<UICheckbox.Icon
|
||||
className={checkboxIconStyle({
|
||||
parentVariants: {
|
||||
size: parentSize,
|
||||
},
|
||||
size,
|
||||
class: className,
|
||||
})}
|
||||
{...props}
|
||||
ref={ref}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
Checkbox.displayName = 'Checkbox';
|
||||
CheckboxIndicator.displayName = 'CheckboxIndicator';
|
||||
CheckboxLabel.displayName = 'CheckboxLabel';
|
||||
CheckboxIcon.displayName = 'CheckboxIcon';
|
||||
|
||||
export {
|
||||
Checkbox,
|
||||
CheckboxIndicator,
|
||||
CheckboxLabel,
|
||||
CheckboxIcon,
|
||||
CheckboxGroup,
|
||||
};
|
||||
@@ -0,0 +1,40 @@
|
||||
'use client';
|
||||
import React from 'react';
|
||||
import { tva } from '@gluestack-ui/utils/nativewind-utils';
|
||||
import { Platform, View } from 'react-native';
|
||||
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils';
|
||||
|
||||
const dividerStyle = tva({
|
||||
base: 'bg-background-200',
|
||||
variants: {
|
||||
orientation: {
|
||||
vertical: 'w-px h-full',
|
||||
horizontal: 'h-px w-full',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
type IUIDividerProps = React.ComponentPropsWithoutRef<typeof View> &
|
||||
VariantProps<typeof dividerStyle>;
|
||||
|
||||
const Divider = React.forwardRef<
|
||||
React.ComponentRef<typeof View>,
|
||||
IUIDividerProps
|
||||
>(function Divider({ className, orientation = 'horizontal', ...props }, ref) {
|
||||
return (
|
||||
<View
|
||||
ref={ref}
|
||||
{...props}
|
||||
aria-orientation={orientation}
|
||||
role={Platform.OS === 'web' ? 'separator' : undefined}
|
||||
className={dividerStyle({
|
||||
orientation,
|
||||
class: className,
|
||||
})}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
Divider.displayName = 'Divider';
|
||||
|
||||
export { Divider };
|
||||
@@ -0,0 +1,468 @@
|
||||
'use client';
|
||||
import { Text, View } from 'react-native';
|
||||
import React from 'react';
|
||||
import { createFormControl } from '@gluestack-ui/core/form-control/creator';
|
||||
import { tva } from '@gluestack-ui/utils/nativewind-utils';
|
||||
import {
|
||||
withStyleContext,
|
||||
useStyleContext,
|
||||
} from '@gluestack-ui/utils/nativewind-utils';
|
||||
import { cssInterop } from 'nativewind';
|
||||
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils';
|
||||
import { PrimitiveIcon, UIIcon } from '@gluestack-ui/core/icon/creator';
|
||||
|
||||
const SCOPE = 'FORM_CONTROL';
|
||||
|
||||
const formControlStyle = tva({
|
||||
base: 'flex flex-col',
|
||||
variants: {
|
||||
size: {
|
||||
sm: '',
|
||||
md: '',
|
||||
lg: '',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const formControlErrorIconStyle = tva({
|
||||
base: 'text-error-700 fill-none',
|
||||
variants: {
|
||||
size: {
|
||||
'2xs': 'h-3 w-3',
|
||||
'xs': 'h-3.5 w-3.5',
|
||||
'sm': 'h-4 w-4',
|
||||
'md': 'h-[18px] w-[18px]',
|
||||
'lg': 'h-5 w-5',
|
||||
'xl': 'h-6 w-6',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const formControlErrorStyle = tva({
|
||||
base: 'flex flex-row justify-start items-center mt-1 gap-1',
|
||||
});
|
||||
|
||||
const formControlErrorTextStyle = tva({
|
||||
base: 'text-error-700',
|
||||
variants: {
|
||||
isTruncated: {
|
||||
true: 'web:truncate',
|
||||
},
|
||||
bold: {
|
||||
true: 'font-bold',
|
||||
},
|
||||
underline: {
|
||||
true: 'underline',
|
||||
},
|
||||
strikeThrough: {
|
||||
true: 'line-through',
|
||||
},
|
||||
size: {
|
||||
'2xs': 'text-2xs',
|
||||
'xs': 'text-xs',
|
||||
'sm': 'text-sm',
|
||||
'md': 'text-base',
|
||||
'lg': 'text-lg',
|
||||
'xl': 'text-xl',
|
||||
'2xl': 'text-2xl',
|
||||
'3xl': 'text-3xl',
|
||||
'4xl': 'text-4xl',
|
||||
'5xl': 'text-5xl',
|
||||
'6xl': 'text-6xl',
|
||||
},
|
||||
sub: {
|
||||
true: 'text-xs',
|
||||
},
|
||||
italic: {
|
||||
true: 'italic',
|
||||
},
|
||||
highlight: {
|
||||
true: 'bg-yellow-500',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const formControlHelperStyle = tva({
|
||||
base: 'flex flex-row justify-start items-center mt-1',
|
||||
});
|
||||
|
||||
const formControlHelperTextStyle = tva({
|
||||
base: 'text-typography-500',
|
||||
variants: {
|
||||
isTruncated: {
|
||||
true: 'web:truncate',
|
||||
},
|
||||
bold: {
|
||||
true: 'font-bold',
|
||||
},
|
||||
underline: {
|
||||
true: 'underline',
|
||||
},
|
||||
strikeThrough: {
|
||||
true: 'line-through',
|
||||
},
|
||||
size: {
|
||||
'2xs': 'text-2xs',
|
||||
'xs': 'text-xs',
|
||||
'sm': 'text-xs',
|
||||
'md': 'text-sm',
|
||||
'lg': 'text-base',
|
||||
'xl': 'text-xl',
|
||||
'2xl': 'text-2xl',
|
||||
'3xl': 'text-3xl',
|
||||
'4xl': 'text-4xl',
|
||||
'5xl': 'text-5xl',
|
||||
'6xl': 'text-6xl',
|
||||
},
|
||||
sub: {
|
||||
true: 'text-xs',
|
||||
},
|
||||
italic: {
|
||||
true: 'italic',
|
||||
},
|
||||
highlight: {
|
||||
true: 'bg-yellow-500',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const formControlLabelStyle = tva({
|
||||
base: 'flex flex-row justify-start items-center mb-1',
|
||||
});
|
||||
|
||||
const formControlLabelTextStyle = tva({
|
||||
base: 'font-medium text-typography-900',
|
||||
variants: {
|
||||
isTruncated: {
|
||||
true: 'web:truncate',
|
||||
},
|
||||
bold: {
|
||||
true: 'font-bold',
|
||||
},
|
||||
underline: {
|
||||
true: 'underline',
|
||||
},
|
||||
strikeThrough: {
|
||||
true: 'line-through',
|
||||
},
|
||||
size: {
|
||||
'2xs': 'text-2xs',
|
||||
'xs': 'text-xs',
|
||||
'sm': 'text-sm',
|
||||
'md': 'text-base',
|
||||
'lg': 'text-lg',
|
||||
'xl': 'text-xl',
|
||||
'2xl': 'text-2xl',
|
||||
'3xl': 'text-3xl',
|
||||
'4xl': 'text-4xl',
|
||||
'5xl': 'text-5xl',
|
||||
'6xl': 'text-6xl',
|
||||
},
|
||||
sub: {
|
||||
true: 'text-xs',
|
||||
},
|
||||
italic: {
|
||||
true: 'italic',
|
||||
},
|
||||
highlight: {
|
||||
true: 'bg-yellow-500',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const formControlLabelAstrickStyle = tva({
|
||||
base: 'font-medium text-typography-900',
|
||||
variants: {
|
||||
isTruncated: {
|
||||
true: 'web:truncate',
|
||||
},
|
||||
bold: {
|
||||
true: 'font-bold',
|
||||
},
|
||||
underline: {
|
||||
true: 'underline',
|
||||
},
|
||||
strikeThrough: {
|
||||
true: 'line-through',
|
||||
},
|
||||
size: {
|
||||
'2xs': 'text-2xs',
|
||||
'xs': 'text-xs',
|
||||
'sm': 'text-sm',
|
||||
'md': 'text-base',
|
||||
'lg': 'text-lg',
|
||||
'xl': 'text-xl',
|
||||
'2xl': 'text-2xl',
|
||||
'3xl': 'text-3xl',
|
||||
'4xl': 'text-4xl',
|
||||
'5xl': 'text-5xl',
|
||||
'6xl': 'text-6xl',
|
||||
},
|
||||
sub: {
|
||||
true: 'text-xs',
|
||||
},
|
||||
italic: {
|
||||
true: 'italic',
|
||||
},
|
||||
highlight: {
|
||||
true: 'bg-yellow-500',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
type IFormControlLabelAstrickProps = React.ComponentPropsWithoutRef<
|
||||
typeof Text
|
||||
> &
|
||||
VariantProps<typeof formControlLabelAstrickStyle>;
|
||||
|
||||
const FormControlLabelAstrick = React.forwardRef<
|
||||
React.ComponentRef<typeof Text>,
|
||||
IFormControlLabelAstrickProps
|
||||
>(function FormControlLabelAstrick({ className, ...props }, ref) {
|
||||
const { size: parentSize } = useStyleContext(SCOPE);
|
||||
|
||||
return (
|
||||
<Text
|
||||
ref={ref}
|
||||
className={formControlLabelAstrickStyle({
|
||||
parentVariants: { size: parentSize },
|
||||
class: className,
|
||||
})}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
export const UIFormControl = createFormControl({
|
||||
Root: withStyleContext(View, SCOPE),
|
||||
Error: View,
|
||||
ErrorText: Text,
|
||||
ErrorIcon: UIIcon,
|
||||
Label: View,
|
||||
LabelText: Text,
|
||||
LabelAstrick: FormControlLabelAstrick,
|
||||
Helper: View,
|
||||
HelperText: Text,
|
||||
});
|
||||
|
||||
cssInterop(PrimitiveIcon, {
|
||||
className: {
|
||||
target: 'style',
|
||||
nativeStyleToProp: {
|
||||
height: true,
|
||||
width: true,
|
||||
fill: true,
|
||||
color: true,
|
||||
stroke: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
type IFormControlProps = React.ComponentProps<typeof UIFormControl> &
|
||||
VariantProps<typeof formControlStyle>;
|
||||
|
||||
const FormControl = React.forwardRef<
|
||||
React.ComponentRef<typeof UIFormControl>,
|
||||
IFormControlProps
|
||||
>(function FormControl({ className, size = 'md', ...props }, ref) {
|
||||
return (
|
||||
<UIFormControl
|
||||
ref={ref}
|
||||
className={formControlStyle({ size, class: className })}
|
||||
{...props}
|
||||
context={{ size }}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
type IFormControlErrorProps = React.ComponentProps<typeof UIFormControl.Error> &
|
||||
VariantProps<typeof formControlErrorStyle>;
|
||||
|
||||
const FormControlError = React.forwardRef<
|
||||
React.ComponentRef<typeof UIFormControl.Error>,
|
||||
IFormControlErrorProps
|
||||
>(function FormControlError({ className, ...props }, ref) {
|
||||
return (
|
||||
<UIFormControl.Error
|
||||
ref={ref}
|
||||
className={formControlErrorStyle({ class: className })}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
type IFormControlErrorTextProps = React.ComponentProps<
|
||||
typeof UIFormControl.Error.Text
|
||||
> &
|
||||
VariantProps<typeof formControlErrorTextStyle>;
|
||||
|
||||
const FormControlErrorText = React.forwardRef<
|
||||
React.ComponentRef<typeof UIFormControl.Error.Text>,
|
||||
IFormControlErrorTextProps
|
||||
>(function FormControlErrorText({ className, size, ...props }, ref) {
|
||||
const { size: parentSize } = useStyleContext(SCOPE);
|
||||
return (
|
||||
<UIFormControl.Error.Text
|
||||
className={formControlErrorTextStyle({
|
||||
parentVariants: { size: parentSize },
|
||||
size,
|
||||
class: className,
|
||||
})}
|
||||
ref={ref}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
type IFormControlErrorIconProps = React.ComponentProps<
|
||||
typeof UIFormControl.Error.Icon
|
||||
> &
|
||||
VariantProps<typeof formControlErrorIconStyle> & {
|
||||
height?: number;
|
||||
width?: number;
|
||||
};
|
||||
|
||||
const FormControlErrorIcon = React.forwardRef<
|
||||
React.ComponentRef<typeof UIFormControl.Error.Icon>,
|
||||
IFormControlErrorIconProps
|
||||
>(function FormControlErrorIcon({ className, size, ...props }, ref) {
|
||||
const { size: parentSize } = useStyleContext(SCOPE);
|
||||
|
||||
if (typeof size === 'number') {
|
||||
return (
|
||||
<UIFormControl.Error.Icon
|
||||
ref={ref}
|
||||
{...props}
|
||||
className={formControlErrorIconStyle({ class: className })}
|
||||
size={size}
|
||||
/>
|
||||
);
|
||||
} else if (
|
||||
(props.height !== undefined || props.width !== undefined) &&
|
||||
size === undefined
|
||||
) {
|
||||
return (
|
||||
<UIFormControl.Error.Icon
|
||||
ref={ref}
|
||||
{...props}
|
||||
className={formControlErrorIconStyle({ class: className })}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<UIFormControl.Error.Icon
|
||||
className={formControlErrorIconStyle({
|
||||
parentVariants: { size: parentSize },
|
||||
size,
|
||||
class: className,
|
||||
})}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
type IFormControlLabelProps = React.ComponentProps<typeof UIFormControl.Label> &
|
||||
VariantProps<typeof formControlLabelStyle>;
|
||||
|
||||
const FormControlLabel = React.forwardRef<
|
||||
React.ComponentRef<typeof UIFormControl.Label>,
|
||||
IFormControlLabelProps
|
||||
>(function FormControlLabel({ className, ...props }, ref) {
|
||||
return (
|
||||
<UIFormControl.Label
|
||||
ref={ref}
|
||||
className={formControlLabelStyle({ class: className })}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
type IFormControlLabelTextProps = React.ComponentProps<
|
||||
typeof UIFormControl.Label.Text
|
||||
> &
|
||||
VariantProps<typeof formControlLabelTextStyle>;
|
||||
|
||||
const FormControlLabelText = React.forwardRef<
|
||||
React.ComponentRef<typeof UIFormControl.Label.Text>,
|
||||
IFormControlLabelTextProps
|
||||
>(function FormControlLabelText({ className, size, ...props }, ref) {
|
||||
const { size: parentSize } = useStyleContext(SCOPE);
|
||||
|
||||
return (
|
||||
<UIFormControl.Label.Text
|
||||
className={formControlLabelTextStyle({
|
||||
parentVariants: { size: parentSize },
|
||||
size,
|
||||
class: className,
|
||||
})}
|
||||
ref={ref}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
type IFormControlHelperProps = React.ComponentProps<
|
||||
typeof UIFormControl.Helper
|
||||
> &
|
||||
VariantProps<typeof formControlHelperStyle>;
|
||||
|
||||
const FormControlHelper = React.forwardRef<
|
||||
React.ComponentRef<typeof UIFormControl.Helper>,
|
||||
IFormControlHelperProps
|
||||
>(function FormControlHelper({ className, ...props }, ref) {
|
||||
return (
|
||||
<UIFormControl.Helper
|
||||
ref={ref}
|
||||
className={formControlHelperStyle({
|
||||
class: className,
|
||||
})}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
type IFormControlHelperTextProps = React.ComponentProps<
|
||||
typeof UIFormControl.Helper.Text
|
||||
> &
|
||||
VariantProps<typeof formControlHelperTextStyle>;
|
||||
|
||||
const FormControlHelperText = React.forwardRef<
|
||||
React.ComponentRef<typeof UIFormControl.Helper.Text>,
|
||||
IFormControlHelperTextProps
|
||||
>(function FormControlHelperText({ className, size, ...props }, ref) {
|
||||
const { size: parentSize } = useStyleContext(SCOPE);
|
||||
|
||||
return (
|
||||
<UIFormControl.Helper.Text
|
||||
className={formControlHelperTextStyle({
|
||||
parentVariants: { size: parentSize },
|
||||
size,
|
||||
class: className,
|
||||
})}
|
||||
ref={ref}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
FormControl.displayName = 'FormControl';
|
||||
FormControlError.displayName = 'FormControlError';
|
||||
FormControlErrorText.displayName = 'FormControlErrorText';
|
||||
FormControlErrorIcon.displayName = 'FormControlErrorIcon';
|
||||
FormControlLabel.displayName = 'FormControlLabel';
|
||||
FormControlLabelText.displayName = 'FormControlLabelText';
|
||||
FormControlLabelAstrick.displayName = 'FormControlLabelAstrick';
|
||||
FormControlHelper.displayName = 'FormControlHelper';
|
||||
FormControlHelperText.displayName = 'FormControlHelperText';
|
||||
|
||||
export {
|
||||
FormControl,
|
||||
FormControlError,
|
||||
FormControlErrorText,
|
||||
FormControlErrorIcon,
|
||||
FormControlLabel,
|
||||
FormControlLabelText,
|
||||
FormControlLabelAstrick,
|
||||
FormControlHelper,
|
||||
FormControlHelperText,
|
||||
};
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,217 @@
|
||||
'use client';
|
||||
import React from 'react';
|
||||
import { createInput } from '@gluestack-ui/core/input/creator';
|
||||
import { View, Pressable, TextInput } from 'react-native';
|
||||
import { tva } from '@gluestack-ui/utils/nativewind-utils';
|
||||
import {
|
||||
withStyleContext,
|
||||
useStyleContext,
|
||||
} from '@gluestack-ui/utils/nativewind-utils';
|
||||
import { cssInterop } from 'nativewind';
|
||||
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils';
|
||||
import { PrimitiveIcon, UIIcon } from '@gluestack-ui/core/icon/creator';
|
||||
|
||||
const SCOPE = 'INPUT';
|
||||
|
||||
const UIInput = createInput({
|
||||
Root: withStyleContext(View, SCOPE),
|
||||
Icon: UIIcon,
|
||||
Slot: Pressable,
|
||||
Input: TextInput,
|
||||
});
|
||||
|
||||
cssInterop(PrimitiveIcon, {
|
||||
className: {
|
||||
target: 'style',
|
||||
nativeStyleToProp: {
|
||||
height: true,
|
||||
width: true,
|
||||
fill: true,
|
||||
color: 'classNameColor',
|
||||
stroke: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const inputStyle = tva({
|
||||
base: 'border-background-300 flex-row overflow-hidden content-center data-[hover=true]:border-outline-400 data-[focus=true]:border-primary-700 data-[focus=true]:hover:border-primary-700 data-[disabled=true]:opacity-40 data-[disabled=true]:hover:border-background-300 items-center',
|
||||
|
||||
variants: {
|
||||
size: {
|
||||
xl: 'h-12',
|
||||
lg: 'h-11',
|
||||
md: 'h-10',
|
||||
sm: 'h-9',
|
||||
},
|
||||
|
||||
variant: {
|
||||
underlined:
|
||||
'rounded-none border-b data-[invalid=true]:border-b-2 data-[invalid=true]:border-error-700 data-[invalid=true]:hover:border-error-700 data-[invalid=true]:data-[focus=true]:border-error-700 data-[invalid=true]:data-[focus=true]:hover:border-error-700 data-[invalid=true]:data-[disabled=true]:hover:border-error-700',
|
||||
|
||||
outline:
|
||||
'rounded border data-[invalid=true]:border-error-700 data-[invalid=true]:hover:border-error-700 data-[invalid=true]:data-[focus=true]:border-error-700 data-[invalid=true]:data-[focus=true]:hover:border-error-700 data-[invalid=true]:data-[disabled=true]:hover:border-error-700 data-[focus=true]:web:ring-1 data-[focus=true]:web:ring-inset data-[focus=true]:web:ring-indicator-primary data-[invalid=true]:web:ring-1 data-[invalid=true]:web:ring-inset data-[invalid=true]:web:ring-indicator-error data-[invalid=true]:data-[focus=true]:hover:web:ring-1 data-[invalid=true]:data-[focus=true]:hover:web:ring-inset data-[invalid=true]:data-[focus=true]:hover:web:ring-indicator-error data-[invalid=true]:data-[disabled=true]:hover:web:ring-1 data-[invalid=true]:data-[disabled=true]:hover:web:ring-inset data-[invalid=true]:data-[disabled=true]:hover:web:ring-indicator-error',
|
||||
|
||||
rounded:
|
||||
'rounded-full border data-[invalid=true]:border-error-700 data-[invalid=true]:hover:border-error-700 data-[invalid=true]:data-[focus=true]:border-error-700 data-[invalid=true]:data-[focus=true]:hover:border-error-700 data-[invalid=true]:data-[disabled=true]:hover:border-error-700 data-[focus=true]:web:ring-1 data-[focus=true]:web:ring-inset data-[focus=true]:web:ring-indicator-primary data-[invalid=true]:web:ring-1 data-[invalid=true]:web:ring-inset data-[invalid=true]:web:ring-indicator-error data-[invalid=true]:data-[focus=true]:hover:web:ring-1 data-[invalid=true]:data-[focus=true]:hover:web:ring-inset data-[invalid=true]:data-[focus=true]:hover:web:ring-indicator-error data-[invalid=true]:data-[disabled=true]:hover:web:ring-1 data-[invalid=true]:data-[disabled=true]:hover:web:ring-inset data-[invalid=true]:data-[disabled=true]:hover:web:ring-indicator-error',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const inputIconStyle = tva({
|
||||
base: 'justify-center items-center text-typography-400 fill-none',
|
||||
parentVariants: {
|
||||
size: {
|
||||
'2xs': 'h-3 w-3',
|
||||
'xs': 'h-3.5 w-3.5',
|
||||
'sm': 'h-4 w-4',
|
||||
'md': 'h-[18px] w-[18px]',
|
||||
'lg': 'h-5 w-5',
|
||||
'xl': 'h-6 w-6',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const inputSlotStyle = tva({
|
||||
base: 'justify-center items-center web:disabled:cursor-not-allowed',
|
||||
});
|
||||
|
||||
const inputFieldStyle = tva({
|
||||
base: 'flex-1 text-typography-900 py-0 px-3 placeholder:text-typography-500 h-full ios:leading-[0px] web:cursor-text web:data-[disabled=true]:cursor-not-allowed',
|
||||
|
||||
parentVariants: {
|
||||
variant: {
|
||||
underlined: 'web:outline-0 web:outline-none px-0',
|
||||
outline: 'web:outline-0 web:outline-none',
|
||||
rounded: 'web:outline-0 web:outline-none px-4',
|
||||
},
|
||||
|
||||
size: {
|
||||
'2xs': 'text-2xs',
|
||||
'xs': 'text-xs',
|
||||
'sm': 'text-sm',
|
||||
'md': 'text-base',
|
||||
'lg': 'text-lg',
|
||||
'xl': 'text-xl',
|
||||
'2xl': 'text-2xl',
|
||||
'3xl': 'text-3xl',
|
||||
'4xl': 'text-4xl',
|
||||
'5xl': 'text-5xl',
|
||||
'6xl': 'text-6xl',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
type IInputProps = React.ComponentProps<typeof UIInput> &
|
||||
VariantProps<typeof inputStyle> & { className?: string };
|
||||
const Input = React.forwardRef<React.ComponentRef<typeof UIInput>, IInputProps>(
|
||||
function Input(
|
||||
{ className, variant = 'outline', size = 'md', ...props },
|
||||
ref
|
||||
) {
|
||||
return (
|
||||
<UIInput
|
||||
ref={ref}
|
||||
{...props}
|
||||
className={inputStyle({ variant, size, class: className })}
|
||||
context={{ variant, size }}
|
||||
/>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
type IInputIconProps = React.ComponentProps<typeof UIInput.Icon> &
|
||||
VariantProps<typeof inputIconStyle> & {
|
||||
className?: string;
|
||||
height?: number;
|
||||
width?: number;
|
||||
};
|
||||
|
||||
const InputIcon = React.forwardRef<
|
||||
React.ComponentRef<typeof UIInput.Icon>,
|
||||
IInputIconProps
|
||||
>(function InputIcon({ className, size, ...props }, ref) {
|
||||
const { size: parentSize } = useStyleContext(SCOPE);
|
||||
|
||||
if (typeof size === 'number') {
|
||||
return (
|
||||
<UIInput.Icon
|
||||
ref={ref}
|
||||
{...props}
|
||||
className={inputIconStyle({ class: className })}
|
||||
size={size}
|
||||
/>
|
||||
);
|
||||
} else if (
|
||||
(props.height !== undefined || props.width !== undefined) &&
|
||||
size === undefined
|
||||
) {
|
||||
return (
|
||||
<UIInput.Icon
|
||||
ref={ref}
|
||||
{...props}
|
||||
className={inputIconStyle({ class: className })}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<UIInput.Icon
|
||||
ref={ref}
|
||||
{...props}
|
||||
className={inputIconStyle({
|
||||
parentVariants: {
|
||||
size: parentSize,
|
||||
},
|
||||
class: className,
|
||||
})}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
type IInputSlotProps = React.ComponentProps<typeof UIInput.Slot> &
|
||||
VariantProps<typeof inputSlotStyle> & { className?: string };
|
||||
|
||||
const InputSlot = React.forwardRef<
|
||||
React.ComponentRef<typeof UIInput.Slot>,
|
||||
IInputSlotProps
|
||||
>(function InputSlot({ className, ...props }, ref) {
|
||||
return (
|
||||
<UIInput.Slot
|
||||
ref={ref}
|
||||
{...props}
|
||||
className={inputSlotStyle({
|
||||
class: className,
|
||||
})}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
type IInputFieldProps = React.ComponentProps<typeof UIInput.Input> &
|
||||
VariantProps<typeof inputFieldStyle> & { className?: string };
|
||||
|
||||
const InputField = React.forwardRef<
|
||||
React.ComponentRef<typeof UIInput.Input>,
|
||||
IInputFieldProps
|
||||
>(function InputField({ className, ...props }, ref) {
|
||||
const { variant: parentVariant, size: parentSize } = useStyleContext(SCOPE);
|
||||
|
||||
return (
|
||||
<UIInput.Input
|
||||
ref={ref}
|
||||
{...props}
|
||||
className={inputFieldStyle({
|
||||
parentVariants: {
|
||||
variant: parentVariant,
|
||||
size: parentSize,
|
||||
},
|
||||
class: className,
|
||||
})}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
Input.displayName = 'Input';
|
||||
InputIcon.displayName = 'InputIcon';
|
||||
InputSlot.displayName = 'InputSlot';
|
||||
InputField.displayName = 'InputField';
|
||||
|
||||
export { Input, InputField, InputIcon, InputSlot };
|
||||
@@ -0,0 +1,102 @@
|
||||
'use client';
|
||||
import { createLink } from '@gluestack-ui/core/link/creator';
|
||||
import { Pressable } from 'react-native';
|
||||
import { Text } from 'react-native';
|
||||
|
||||
import { tva } from '@gluestack-ui/utils/nativewind-utils';
|
||||
import { withStyleContext } from '@gluestack-ui/utils/nativewind-utils';
|
||||
import { cssInterop } from 'nativewind';
|
||||
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils';
|
||||
|
||||
import React from 'react';
|
||||
export const UILink = createLink({
|
||||
Root: withStyleContext(Pressable),
|
||||
Text: Text,
|
||||
});
|
||||
|
||||
cssInterop(UILink, { className: 'style' });
|
||||
cssInterop(UILink.Text, { className: 'style' });
|
||||
|
||||
const linkStyle = tva({
|
||||
base: 'group/link web:outline-0 data-[disabled=true]:web:cursor-not-allowed data-[focus-visible=true]:web:ring-2 data-[focus-visible=true]:web:ring-indicator-primary data-[focus-visible=true]:web:outline-0 data-[disabled=true]:opacity-4 ',
|
||||
});
|
||||
|
||||
const linkTextStyle = tva({
|
||||
base: 'underline text-info-700 data-[hover=true]:text-info-600 data-[hover=true]:no-underline data-[active=true]:text-info-700 font-normal font-body web:font-sans web:tracking-sm web:my-0 web:bg-transparent web:border-0 web:box-border web:display-inline web:list-none web:margin-0 web:padding-0 web:position-relative web:text-start web:whitespace-pre-wrap web:word-wrap-break-word',
|
||||
|
||||
variants: {
|
||||
isTruncated: {
|
||||
true: 'web:truncate',
|
||||
},
|
||||
bold: {
|
||||
true: 'font-bold',
|
||||
},
|
||||
underline: {
|
||||
true: 'underline',
|
||||
},
|
||||
strikeThrough: {
|
||||
true: 'line-through',
|
||||
},
|
||||
size: {
|
||||
'2xs': 'text-2xs',
|
||||
'xs': 'text-xs',
|
||||
'sm': 'text-sm',
|
||||
'md': 'text-base',
|
||||
'lg': 'text-lg',
|
||||
'xl': 'text-xl',
|
||||
'2xl': 'text-2xl',
|
||||
'3xl': 'text-3xl',
|
||||
'4xl': 'text-4xl',
|
||||
'5xl': 'text-5xl',
|
||||
'6xl': 'text-6xl',
|
||||
},
|
||||
sub: {
|
||||
true: 'text-xs',
|
||||
},
|
||||
italic: {
|
||||
true: 'italic',
|
||||
},
|
||||
highlight: {
|
||||
true: 'bg-yellow-500',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
type ILinkProps = React.ComponentProps<typeof UILink> &
|
||||
VariantProps<typeof linkStyle> & { className?: string };
|
||||
|
||||
const Link = React.forwardRef<React.ComponentRef<typeof UILink>, ILinkProps>(
|
||||
function Link({ className, ...props }, ref) {
|
||||
return (
|
||||
<UILink
|
||||
ref={ref}
|
||||
{...props}
|
||||
className={linkStyle({ class: className })}
|
||||
/>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
type ILinkTextProps = React.ComponentProps<typeof UILink.Text> &
|
||||
VariantProps<typeof linkTextStyle> & { className?: string };
|
||||
|
||||
const LinkText = React.forwardRef<
|
||||
React.ComponentRef<typeof UILink.Text>,
|
||||
ILinkTextProps
|
||||
>(function LinkText({ className, size = 'md', ...props }, ref) {
|
||||
return (
|
||||
<UILink.Text
|
||||
ref={ref}
|
||||
{...props}
|
||||
className={linkTextStyle({
|
||||
class: className,
|
||||
size,
|
||||
})}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
Link.displayName = 'Link';
|
||||
LinkText.displayName = 'LinkText';
|
||||
|
||||
export { Link, LinkText };
|
||||
Reference in new issue
Block a user