feature/frontend-login #10
@@ -1,6 +1,7 @@
|
||||
import type { AnyFieldMeta } from '@tanstack/react-form';
|
||||
import { LucideEye, LucideEyeClosed } from 'lucide-react';
|
||||
import { useCallback, useId, useState } from 'react';
|
||||
import { InfoIcon, type InfoIconProps } from '../info';
|
||||
|
||||
export type TextFieldProps = {
|
||||
label?: string;
|
||||
@@ -8,12 +9,13 @@ export type TextFieldProps = {
|
||||
onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
||||
labelProps?: React.LabelHTMLAttributes<HTMLLabelElement>;
|
||||
labelDivProps?: React.HTMLAttributes<HTMLDivElement>;
|
||||
infoIconProps?: InfoIconProps;
|
||||
} & React.InputHTMLAttributes<HTMLInputElement> & {
|
||||
type?: 'password';
|
||||
showPasswordToggle?: boolean;
|
||||
};
|
||||
|
||||
export function TextField({ label, value, onChange, labelProps, labelDivProps, showPasswordToggle, ...rest }: TextFieldProps) {
|
||||
export function TextField({ label, value, onChange, labelProps, labelDivProps, showPasswordToggle, infoIconProps, ...rest }: TextFieldProps) {
|
||||
const id = useId();
|
||||
const [isPasswordVisible, setIsPasswordVisible] = useState(false);
|
||||
const handlePasswordVisibilitySet = useCallback(
|
||||
@@ -24,11 +26,13 @@ export function TextField({ label, value, onChange, labelProps, labelDivProps, s
|
||||
},
|
||||
[rest.type]
|
||||
);
|
||||
|
||||
return (
|
||||
<label htmlFor={id} style={{ display: 'block', marginBottom: 8 }} {...labelProps}>
|
||||
{label && (
|
||||
<div style={{ fontSize: 12, color: 'var(--gray-9)', marginBottom: 6 }} {...labelDivProps}>
|
||||
<div style={{ fontSize: 12, color: 'var(--gray-9)', marginBottom: 6, display: 'flex', alignItems: 'center' }} {...labelDivProps}>
|
||||
{label}
|
||||
{infoIconProps && <InfoIcon {...infoIconProps} style={{ marginLeft: 4, verticalAlign: 'middle' }} />}
|
||||
</div>
|
||||
)}
|
||||
<div style={{ position: 'relative', display: 'flex', alignItems: 'center', gap: 8 }}>
|
||||
|
||||
59
apps/frontend/app/components/info.tsx
Normal file
59
apps/frontend/app/components/info.tsx
Normal file
@@ -0,0 +1,59 @@
|
||||
import { Box } from '@radix-ui/themes';
|
||||
import { Info, type LucideProps } from 'lucide-react';
|
||||
import { Tooltip } from 'radix-ui';
|
||||
import type { PropsWithChildren } from 'react';
|
||||
|
||||
export type InfoIconProps = PropsWithChildren<
|
||||
{
|
||||
tooltipContainerProps?: Omit<Tooltip.TooltipContentProps & React.RefAttributes<HTMLDivElement>, 'children'>;
|
||||
} & Omit<LucideProps, 'ref'> &
|
||||
React.RefAttributes<SVGSVGElement>
|
||||
>;
|
||||
|
||||
export function InfoIcon({ tooltipContainerProps, children, ...iconProps }: InfoIconProps) {
|
||||
return (
|
||||
<Tooltip.Root>
|
||||
<Tooltip.Trigger asChild>
|
||||
<Info size={16} {...iconProps} />
|
||||
</Tooltip.Trigger>
|
||||
<Tooltip.Portal>
|
||||
<Tooltip.Content
|
||||
//
|
||||
side="top"
|
||||
align="center"
|
||||
sideOffset={5}
|
||||
alignOffset={0}
|
||||
avoidCollisions={true}
|
||||
style={{
|
||||
color: 'black',
|
||||
backgroundColor: 'white',
|
||||
fontSize: 12,
|
||||
boxShadow: '0 2px 10px rgba(0, 0, 0, 0.3)',
|
||||
border: '1px solid var(--gray-5)',
|
||||
}}
|
||||
{...tooltipContainerProps}
|
||||
>
|
||||
{children}
|
||||
<Tooltip.Arrow className="TooltipArrow" fill="white" />
|
||||
</Tooltip.Content>
|
||||
</Tooltip.Portal>
|
||||
</Tooltip.Root>
|
||||
);
|
||||
}
|
||||
|
||||
export function TooltipContentContainer({ children, ...props }: React.HTMLAttributes<HTMLDivElement>) {
|
||||
return (
|
||||
<Box
|
||||
style={{
|
||||
padding: '8px 12px',
|
||||
color: 'black',
|
||||
backgroundColor: 'white',
|
||||
borderRadius: 4,
|
||||
fontSize: 12,
|
||||
}}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
@@ -12,6 +12,7 @@
|
||||
"generate:openapi": "typed-openapi ../api/swagger.json --tanstack tanstack-client.ts -o ./app/generated/api-client/api-client.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@radix-ui/react-tooltip": "^1.2.8",
|
||||
"@radix-ui/themes": "^3.2.1",
|
||||
"@react-router/node": "^7.9.2",
|
||||
"@react-router/serve": "^7.9.2",
|
||||
|
||||
3
apps/frontend/pnpm-lock.yaml
generated
3
apps/frontend/pnpm-lock.yaml
generated
@@ -8,6 +8,9 @@ importers:
|
||||
|
||||
.:
|
||||
dependencies:
|
||||
'@radix-ui/react-tooltip':
|
||||
specifier: ^1.2.8
|
||||
version: 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
|
||||
'@radix-ui/themes':
|
||||
specifier: ^3.2.1
|
||||
version: 3.2.1(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
|
||||
|
||||
Reference in New Issue
Block a user