Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 77 additions & 75 deletions packages/ui/package.json
Original file line number Diff line number Diff line change
@@ -1,77 +1,79 @@
{
"name": "@o2s/ui",
"version": "1.4.0",
"private": true,
"license": "MIT",
"exports": {
"./globals": "./src/globals.css",
"./theme": "./src/theme.css",
"./postcss.config": "./postcss.config.mjs",
"./lib/*": "./src/lib/*.ts",
"./hooks/*": "./src/hooks/*.ts",
"./providers/*": "./src/providers/*/index.ts",
"./elements/*": "./src/elements/*.tsx",
"./components/*": "./src/components/*/index.ts"
},
"scripts": {
"lint": "tsc --noEmit && eslint . --max-warnings 0",
"format": "prettier --write \"src/**/*.{js,jsx,ts,tsx,css,scss,json}\"",
"generate:component": "turbo gen react-component",
"generate:component:shadcn": "npx shadcn@latest add"
},
"devDependencies": {
"@o2s/eslint-config": "*",
"@o2s/prettier-config": "*",
"@o2s/typescript-config": "*",
"@tailwindcss/postcss": "^4.1.14",
"@trivago/prettier-plugin-sort-imports": "^5.2.2",
"@turbo/gen": "^2.5.8",
"@types/eslint": "^9.6.1",
"@types/node": "^24.7.2",
"eslint": "^9.37.0",
"prettier": "^3.6.2",
"sass": "^1.93.2",
"tw-animate-css": "^1.4.0",
"typescript": "^5.9.3"
},
"dependencies": {
"@o2s/framework": "*",
"@radix-ui/react-accordion": "^1.2.12",
"@radix-ui/react-avatar": "^1.1.10",
"@radix-ui/react-checkbox": "^1.3.3",
"@radix-ui/react-collapsible": "^1.1.12",
"@radix-ui/react-dialog": "^1.1.15",
"@radix-ui/react-dropdown-menu": "^2.1.16",
"@radix-ui/react-label": "^2.1.7",
"@radix-ui/react-navigation-menu": "^1.2.14",
"@radix-ui/react-popover": "^1.1.15",
"@radix-ui/react-progress": "^1.1.7",
"@radix-ui/react-radio-group": "^1.3.8",
"@radix-ui/react-select": "^2.2.6",
"@radix-ui/react-separator": "^1.1.7",
"@radix-ui/react-slot": "^1.2.3",
"@radix-ui/react-switch": "^1.2.6",
"@radix-ui/react-toast": "^1.2.15",
"@radix-ui/react-toggle": "^1.1.10",
"@radix-ui/react-toggle-group": "^1.1.11",
"@radix-ui/react-tooltip": "^1.2.8",
"class-variance-authority": "^0.7.1",
"classnames": "^2.5.1",
"clsx": "^2.1.1",
"cmdk": "^1.1.1",
"date-fns": "^4.1.0",
"lucide-react": "^0.545.0",
"react-day-picker": "^9.11.1",
"markdown-to-jsx": "^7.7.15",
"recharts": "^2.15.4",
"tailwind-merge": "^3.3.1",
"tailwindcss-animate": "^1.0.7"
},
"peerDependencies": {
"@types/react": "^19",
"@types/react-dom": "^19",
"react": "^19",
"react-dom": "^19",
"tailwindcss": "^4"
}
"name": "@o2s/ui",
"version": "1.4.0",
"private": true,
"license": "MIT",
"exports": {
"./globals": "./src/globals.css",
"./theme": "./src/theme.css",
"./postcss.config": "./postcss.config.mjs",
"./lib/*": "./src/lib/*.ts",
"./hooks/*": "./src/hooks/*.ts",
"./providers/*": "./src/providers/*/index.ts",
"./elements/*": "./src/elements/*.tsx",
"./components/*": "./src/components/*/index.ts"
},
"scripts": {
"lint": "tsc --noEmit && eslint . --max-warnings 0",
"format": "prettier --write \"src/**/*.{js,jsx,ts,tsx,css,scss,json}\"",
"generate:component": "turbo gen react-component",
"generate:component:shadcn": "npx shadcn@latest add"
},
"devDependencies": {
"@o2s/eslint-config": "*",
"@o2s/prettier-config": "*",
"@o2s/typescript-config": "*",
"@tailwindcss/postcss": "^4.1.14",
"@trivago/prettier-plugin-sort-imports": "^5.2.2",
"@turbo/gen": "^2.5.8",
"@types/eslint": "^9.6.1",
"@types/node": "^24.7.2",
"eslint": "^9.37.0",
"prettier": "^3.6.2",
"sass": "^1.93.2",
"tw-animate-css": "^1.4.0",
"typescript": "^5.9.3"
},
"dependencies": {
"@o2s/framework": "*",
"@radix-ui/react-accordion": "^1.2.12",
"@radix-ui/react-avatar": "^1.1.10",
"@radix-ui/react-checkbox": "^1.3.3",
"@radix-ui/react-collapsible": "^1.1.12",
"@radix-ui/react-dialog": "^1.1.15",
"@radix-ui/react-dropdown-menu": "^2.1.16",
"@radix-ui/react-label": "^2.1.7",
"@radix-ui/react-navigation-menu": "^1.2.14",
"@radix-ui/react-popover": "^1.1.15",
"@radix-ui/react-progress": "^1.1.7",
"@radix-ui/react-radio-group": "^1.3.8",
"@radix-ui/react-select": "^2.2.6",
"@radix-ui/react-separator": "^1.1.7",
"@radix-ui/react-slot": "^1.2.3",
"@radix-ui/react-switch": "^1.2.6",
"@radix-ui/react-toast": "^1.2.15",
"@radix-ui/react-toggle": "^1.1.10",
"@radix-ui/react-toggle-group": "^1.1.11",
"@radix-ui/react-tooltip": "^1.2.8",
"class-variance-authority": "^0.7.1",
"classnames": "^2.5.1",
"clsx": "^2.1.1",
"cmdk": "^1.1.1",
"date-fns": "^4.1.0",
"lucide-react": "^0.545.0",
"react-day-picker": "^9.11.1",
"markdown-to-jsx": "^7.7.15",
"recharts": "^2.15.4",
"tailwind-merge": "^3.3.1",
"tailwindcss-animate": "^1.0.7",
"libphonenumber-js": "^1.11.18",
"input-format": "^0.3.14"
},
"peerDependencies": {
"@types/react": "^19",
"@types/react-dom": "^19",
"react": "^19",
"react-dom": "^19",
"tailwindcss": "^4"
}
}
4 changes: 4 additions & 0 deletions packages/ui/src/components/PhoneInput/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export { default as PhoneInput } from '../../elements/phone-input';
export type { PhoneInputProps, PhoneInputChangePayload } from '../../elements/phone-input';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

placing this in the components folder is not necessary - this is still a rather simple component, and, like a regular Input, it's enough to have this one in elements as well



33 changes: 15 additions & 18 deletions packages/ui/src/elements/accordion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,21 @@ import { cn } from '@o2s/ui/lib/utils';

const Accordion = AccordionPrimitive.Root;

const AccordionItem = React.forwardRef<
React.ElementRef<typeof AccordionPrimitive.Item>,
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Item>
>(({ className, ...props }, ref) => (
type AccordionItemProps = React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Item> & {
ref?: React.Ref<React.ElementRef<typeof AccordionPrimitive.Item>>;
};
const AccordionItem = ({ className, ref, ...props }: AccordionItemProps) => (
<AccordionPrimitive.Item ref={ref} className={cn('border-b', className)} {...props} />
));
AccordionItem.displayName = 'AccordionItem';
);

export interface AccordionTriggerProps extends React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger> {
tag?: keyof JSX.IntrinsicElements;
}

const AccordionTrigger = React.forwardRef<React.ElementRef<typeof AccordionPrimitive.Trigger>, AccordionTriggerProps>(
({ className, tag = 'h3', children, ...props }, ref) => {
type AccordionTriggerOwnProps = AccordionTriggerProps & {
ref?: React.Ref<React.ElementRef<typeof AccordionPrimitive.Trigger>>;
};
const AccordionTrigger = ({ className, tag = 'h3', children, ref, ...props }: AccordionTriggerOwnProps) => {
const Comp = tag;

return (
Expand All @@ -40,23 +41,19 @@ const AccordionTrigger = React.forwardRef<React.ElementRef<typeof AccordionPrimi
</Comp>
</AccordionPrimitive.Header>
);
},
);
AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName;
};

const AccordionContent = React.forwardRef<
React.ElementRef<typeof AccordionPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Content>
>(({ className, children, ...props }, ref) => (
type AccordionContentProps = React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Content> & {
ref?: React.Ref<React.ElementRef<typeof AccordionPrimitive.Content>>;
};
const AccordionContent = ({ className, children, ref, ...props }: AccordionContentProps) => (
<AccordionPrimitive.Content
ref={ref}
className="overflow-hidden text-sm transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down"
{...props}
>
<div className={cn('pb-4 pt-0', className)}>{children}</div>
</AccordionPrimitive.Content>
));

AccordionContent.displayName = AccordionPrimitive.Content.displayName;
);

export { Accordion, AccordionItem, AccordionTrigger, AccordionContent };
27 changes: 11 additions & 16 deletions packages/ui/src/elements/alert.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,21 @@ const alertVariants = cva(
},
);

const Alert = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof alertVariants>
>(({ className, variant, ...props }, ref) => (
type AlertProps = React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof alertVariants> & {
ref?: React.Ref<HTMLDivElement>;
};
const Alert = ({ className, variant, ref, ...props }: AlertProps) => (
<div ref={ref} role="alert" className={cn(alertVariants({ variant }), className)} {...props} />
));
Alert.displayName = 'Alert';
);

const AlertTitle = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLHeadingElement>>(
({ className, ...props }, ref) => (
<h5 ref={ref} className={cn('mb-1 font-medium leading-none tracking-tight', className)} {...props} />
),
type AlertTitleProps = React.HTMLAttributes<HTMLHeadingElement> & { ref?: React.Ref<HTMLHeadingElement> };
const AlertTitle = ({ className, ref, ...props }: AlertTitleProps) => (
<h5 ref={ref} className={cn('mb-1 font-medium leading-none tracking-tight', className)} {...props} />
);
AlertTitle.displayName = 'AlertTitle';

const AlertDescription = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>(
({ className, ...props }, ref) => (
<div ref={ref} className={cn('text-sm [&_p]:leading-relaxed', className)} {...props} />
),
type AlertDescriptionProps = React.HTMLAttributes<HTMLParagraphElement> & { ref?: React.Ref<HTMLDivElement> };
const AlertDescription = ({ className, ref, ...props }: AlertDescriptionProps) => (
<div ref={ref} className={cn('text-sm [&_p]:leading-relaxed', className)} {...props} />
);
AlertDescription.displayName = 'AlertDescription';

export { Alert, AlertTitle, AlertDescription };
43 changes: 20 additions & 23 deletions packages/ui/src/elements/avatar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,36 +23,35 @@ type AvatarProps = {
email?: string;
} & React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>;

const Avatar = React.forwardRef<React.ElementRef<typeof AvatarPrimitive.Root>, AvatarProps>(
({ name, email, className, ...props }, ref) => (
<div className="flex items-center gap-2">
<AvatarPrimitive.Root
ref={ref}
className={cn('relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full', className)}
{...props}
/>
{name && <AvatarUser name={name} email={email} />}
</div>
),
type AvatarOwnProps = AvatarProps & { ref?: React.Ref<React.ElementRef<typeof AvatarPrimitive.Root>> };
const Avatar = ({ name, email, className, ref, ...props }: AvatarOwnProps) => (
<div className="flex items-center gap-2">
<AvatarPrimitive.Root
ref={ref}
className={cn('relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full', className)}
{...props}
/>
{name && <AvatarUser name={name} email={email} />}
</div>
);
Avatar.displayName = AvatarPrimitive.Root.displayName;

const AvatarImage = React.forwardRef<
React.ElementRef<typeof AvatarPrimitive.Image>,
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>
>(({ className, alt = '', ...props }, ref) => (
type AvatarImageProps = React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image> & {
ref?: React.Ref<React.ElementRef<typeof AvatarPrimitive.Image>>;
};
const AvatarImage = ({ className, alt = '', ref, ...props }: AvatarImageProps) => (
<AvatarPrimitive.Image ref={ref} className={cn('aspect-square h-full w-full', className)} alt={alt} {...props} />
));
AvatarImage.displayName = AvatarPrimitive.Image.displayName;
);

export interface AvatarFallbackProps
extends React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>,
VariantProps<typeof avatarVariants> {
name: string;
}

const AvatarFallback = React.forwardRef<React.ElementRef<typeof AvatarPrimitive.Fallback>, AvatarFallbackProps>(
({ variant, className, name, ...props }, ref) => {
type AvatarFallbackOwnProps = AvatarFallbackProps & {
ref?: React.Ref<React.ElementRef<typeof AvatarPrimitive.Fallback>>;
};
const AvatarFallback = ({ variant, className, name, ref, ...props }: AvatarFallbackOwnProps) => {
const initials = name
.split(' ')
.map((name) => name[0])
Expand All @@ -64,9 +63,7 @@ const AvatarFallback = React.forwardRef<React.ElementRef<typeof AvatarPrimitive.
{initials}
</AvatarPrimitive.Fallback>
);
},
);
AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
};

type AvatarUserProps = {
name: string;
Expand Down
Loading
Loading