Skip to content

Commit

Permalink
Merge pull request #71 from SySagar/dev
Browse files Browse the repository at this point in the history
feat(ui): chips
  • Loading branch information
SySagar authored Oct 23, 2024
2 parents 769f74f + 337914f commit 1431cb8
Show file tree
Hide file tree
Showing 8 changed files with 489 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/clever-sloths-hunt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@groovy-box/ui': patch
---

chip components
19 changes: 19 additions & 0 deletions apps/docs/app/ui/IndividialComp.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
'use client';
import React from 'react';
import { Chip } from '@groovy-box/ui';

const ChipEle = () => {
return (
<div className='grv-flex grv-flex-wrap grv-gap-4 grv-p-4'>
<Chip clickable onClick={() => alert('Clicked!')}>
Clickable
</Chip>
<Chip onDelete={() => alert('Delete clicked!')}>Deletable</Chip>
<Chip href='https://ui.soumyasagar.in' target='_blank'>
Link
</Chip>
</div>
);
};

export { ChipEle };
207 changes: 207 additions & 0 deletions apps/docs/content/docs/(components)/chips.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
---
title: Chip
description: Various types and configurations of Chip component.
---

## Default

import { Tab, Tabs } from 'fumadocs-ui/components/tabs';
import { Chip, Avatar, AvatarImage, AvatarFallback } from '@/app/ui';
import ComponenentWrapper from '@/app/ui/ComponenentWrapper';
import { Star, Mail } from 'lucide-react';
import { ChipEle } from '@/app/ui/IndividialComp';

<Tabs items={['Preview', 'Code']}>
<Tab value='Preview'>
<ComponenentWrapper>
<div className="grv-flex grv-flex-wrap grv-gap-4 grv-p-4">
<Chip>Default</Chip>
</div>
</ComponenentWrapper>
</Tab>

<Tab value='Code'>
```tsx
import { Chip } from "@groovy-box/ui";

export function ChipDefault() {
return (
<div className="grv-flex grv-flex-wrap grv-gap-4 grv-p-4">
<Chip>Default</Chip>
</div>
);
}
```

</Tab>
</Tabs>

## Variants

<Tabs items={['Preview', 'Code']}>
<Tab value='Preview'>
<ComponenentWrapper>
<div className="grv-flex grv-flex-wrap grv-gap-4 grv-p-4">
<Chip variant="filled">Filled</Chip>
<Chip variant="outlined">Outlined</Chip>
</div>
</ComponenentWrapper>
</Tab>

<Tab value='Code'>
```tsx
import { Chip } from "@groovy-box/ui";

export function ChipVariants() {
return (
<div className="grv-flex grv-flex-wrap grv-gap-4 grv-p-4">
<Chip variant="filled">Filled</Chip>
<Chip variant="outlined">Outlined</Chip>
</div>
);
}
```

</Tab>
</Tabs>

## Sizes

<Tabs items={['Preview', 'Code']}>
<Tab value='Preview'>
<ComponenentWrapper>
<div className="grv-flex grv-flex-wrap grv-gap-4 grv-p-4">
<Chip size="sm">Small</Chip>
<Chip size="md">Medium</Chip>
<Chip size="lg">Large</Chip>
</div>
</ComponenentWrapper>
</Tab>

<Tab value='Code'>
```tsx
import { Chip } from "@groovy-box/ui";

export function ChipSizes() {
return (
<div className="grv-flex grv-flex-wrap grv-gap-4 grv-p-4">
<Chip size="sm">Small</Chip>
<Chip size="md">Medium</Chip>
<Chip size="lg">Large</Chip>
</div>
);
}
```

</Tab>
</Tabs>

## With Icons

<Tabs items={['Preview', 'Code']}>
<Tab value='Preview'>
<ComponenentWrapper>
<div
supressHydrationWarning
className="grv-flex grv-flex-wrap grv-gap-4 grv-p-4">
<Chip
supressHydrationWarning
beforeChildren={
<Avatar>
<AvatarImage
src="https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?q=80&w=1887&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
alt="Avatar Image"
/>
<AvatarFallback>AB</AvatarFallback>
</Avatar>
}
>
User Chip
</Chip>
<Chip variant="outlined" afterChildren={<Star className="grv-h-4 grv-w-4" />}>
Starred
</Chip>
<Chip
beforeChildren={<Mail className="grv-h-4 grv-w-4" />}
afterChildren={
<span className="grv-bg-primary-foreground grv-text-primary grv-rounded-full grv-px-2 grv-text-sm">
99+
</span>
}
>
Inbox
</Chip>
</div>
</ComponenentWrapper>
</Tab>

<Tab value='Code'>
```tsx
import { Chip, Avatar, AvatarImage, AvatarFallback } from "@groovy-box/ui";
import { Star, Mail } from 'lucide-react';

export function ChipWithIcons() {
return (
<div
supressHydrationWarning
className="grv-flex grv-flex-wrap grv-gap-4 grv-p-4">
<Chip
beforeChildren={
<Avatar>
<AvatarImage
src="https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?q=80&w=1887&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
alt="Avatar Image"
/>
<AvatarFallback>AB</AvatarFallback>
</Avatar>
}
>
User Chip
</Chip>
<Chip variant="outlined" afterChildren={<Star className="grv-h-4 grv-w-4" />}>
Starred
</Chip>
<Chip
beforeChildren={<Mail className="grv-h-4 grv-w-4" />}
afterChildren={
<span className="grv-bg-primary-foreground grv-text-primary grv-rounded-full grv-px-2 grv-text-sm">
99+
</span>
}
>
Inbox
</Chip>
</div>
);
}
```

</Tab>
</Tabs>

## Interactions

<Tabs items={['Preview', 'Code']}>
<Tab value='Preview'>
<ComponenentWrapper>
<ChipEle/>
</ComponenentWrapper>
</Tab>

<Tab value='Code'>
```tsx
import { Chip } from "@groovy-box/ui";

export function ChipInteractions() {
return (
<div className="grv-flex grv-flex-wrap grv-gap-4 grv-p-4">
<Chip clickable onClick={() => alert('Clicked!')}>Clickable</Chip>
<Chip onDelete={() => alert('Delete clicked!')}>Deletable</Chip>
<Chip href="https://ui.soumyasagar.in" target="_blank">Link</Chip>
</div>
);
}
```

</Tab>
</Tabs>
141 changes: 141 additions & 0 deletions apps/ui/lib/components/Chip/Chip.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
'use client';
import * as React from 'react';
import { cva, type VariantProps } from 'class-variance-authority';
import { X as CloseIcon } from 'lucide-react';

import { cn } from '@utils/utils';

const chipVariants = cva(
'grv-inline-flex ui grv-items-center grv-rounded-full grv-text-sm grv-font-medium grv-transition-colors focus:grv-outline-none focus:grv-ring-2 grv-ring-ring grv-ring-offset-2',
{
variants: {
variant: {
filled: 'grv-bg-primary-500 ui',
outlined: 'grv-border-2 grv-border-solid grv-border-accent ui',
},
size: {
sm: 'grv-h-6 grv-px-3 ui',
md: 'grv-h-8 grv-px-4 ui',
lg: 'grv-h-10 grv-px-5 ui',
},
clickable: {
true: 'grv-cursor-pointer',
false: '',
},
},
defaultVariants: {
variant: 'filled',
size: 'md',
clickable: false,
},
}
);

export interface ChipDivProps
extends React.HTMLAttributes<HTMLDivElement>,
VariantProps<typeof chipVariants> {
onDelete?: () => void;
as?: React.ElementType;
href?: never;
beforeChildren?: React.ReactNode;
afterChildren?: React.ReactNode;
}

export interface ChipAnchorProps
extends React.HTMLAttributes<HTMLAnchorElement>,
VariantProps<typeof chipVariants> {
onDelete?: () => void;
href?: string;
target?: string;
as?: React.ElementType;
beforeChildren?: React.ReactNode;
afterChildren?: React.ReactNode;
}

export type ChipProps = ChipAnchorProps | ChipDivProps;

const Chip = React.forwardRef<HTMLDivElement | HTMLAnchorElement, ChipProps>(
(
{
className,
variant,
size,
clickable,
onDelete,
href,
as,
beforeChildren,
afterChildren,
children,
...props
},
ref
) => {
const Component = as || (href ? 'a' : 'div');
const isClickable = Boolean(clickable || href || props.onClick);

console.log(variant);
const textColor =
variant === 'outlined' ? 'grv-text-accent' : 'grv-text-text-primary';

console.log(size);

const textSize =
size === 'sm'
? 'grv-text-[10px]'
: size === 'md'
? 'grv-text-[12px]'
: 'grv-text-[14px]';

return (
<Component
ref={ref}
className={cn(
chipVariants({ variant, size, clickable: isClickable }),
'grv-decoration-primary-100 grv-underline-offset-2 grv-flex grv-overflow-hidden ui',
className
)}
{...(href && { href })}
{...props}
>
{beforeChildren && (
<div
className={cn(
'grv-flex grv-items-center grv-justify-center grv-text-text-primary grv-mr-2 grv-w-[20px] grv-h-[20px] ui grv-overflow-hidden grv-rounded-full grv-object-cover'
)}
>
{beforeChildren}
</div>
)}
<div className={cn(textColor, textSize)}>{children}</div>
{afterChildren && (
<div
className={cn(
`grv-flex grv-items-center grv-justify-center ${textColor} grv-ml-2 ui`
)}
>
{afterChildren}
</div>
)}
{onDelete && (
<div
className={cn(
'grv-ml-2 grv-rounded-full grv-bg-text-primary grv-cursor-pointer grv-py-[4px] grv-px-[4px] grv-transition-colors grv-text-primary grv-opacity-50 hover:grv-opacity-60',
textSize
)}
onClick={(e) => {
e.stopPropagation();
onDelete();
}}
>
<CloseIcon className={cn('grv-h-[10px] grv-w-[10px]')} />
</div>
)}
</Component>
);
}
);

Chip.displayName = 'Chip';

export { Chip };
1 change: 1 addition & 0 deletions apps/ui/lib/components/Chip/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './Chip';
1 change: 1 addition & 0 deletions apps/ui/lib/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ export * from './components/Navigation-menu';
export * from './components/Switch';
export * from './components/Toast';
export * from './components/Progress';
export * from './components/Chip';
Loading

0 comments on commit 1431cb8

Please sign in to comment.