Skip to content

Commit

Permalink
Feat/chip v1 (#195)
Browse files Browse the repository at this point in the history
* feat: initial chip implementation

* feat: initial chip implementation

* style: add css classes

* style: add css for base badge

* chore: import sorted

* style: add css variables

* feat: add dismiss and other props

* chore: add usage in assets

* docs: add initial docs

* style: add more css vars

* chore: fix docs and add new badge

* fix: css and svg

* docs: mdx

* feat: add accessibility properties
  • Loading branch information
paanSinghCoder authored Dec 9, 2024
1 parent 1033b90 commit 87e0506
Show file tree
Hide file tree
Showing 8 changed files with 512 additions and 5 deletions.
240 changes: 240 additions & 0 deletions apps/www/content/primitives/components/chip.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
---
title: Chip
description: A compact element for representing an input, attribute, or action.
---

## Preview

<Preview>
<Flex direction="row" gap="medium">
<Chip variant="outline">Default</Chip>

<Chip variant="filled" size="small" style="accent">Accent</Chip>

<Chip variant="outline" size="small" leadingIcon={"O"}>With Icon</Chip>

<Chip
variant="filled"
size="small"
style="accent"
isDismissible
onDismiss={() => alert("Dismiss clicked")}
>Dismissible</Chip>

</Flex>
</Preview>

## Usage

The Chip component is used to represent attributes, tags, or actions in a compact form. It supports various styles, sizes, and can include leading/trailing icons or a dismiss button.

## Installation

Install the component from your command line.

<LiveProvider>
<LiveEditor code={`npm install @raystack/apsara`} border language="shell" />
</LiveProvider>

<LiveProvider>
<LiveEditor code={`import { Chip } from '@raystack/apsara/v1'
<Chip variant="outline" size="small">Label</Chip>`} border/>
</LiveProvider>

## Chip Props

The `Chip` component accepts the following props:

- `variant`: Visual style variant (`"outline"` | `"filled"`, default: "outline")
- `size`: Size of the chip (`"small"` | `"large"`, default: "small")
- `style`: Color style (`"neutral"` | `"accent"`, default: "neutral")
- `leadingIcon`: ReactNode to display as an icon before the label
- `trailingIcon`: ReactNode to display as an icon after the label
- `isDismissible`: Boolean to show a dismiss button (replaces trailingIcon)
- `onDismiss`: Callback function when dismiss button is clicked
- `children`: Content to display inside the chip
- `className`: Additional CSS class names
- `role`: ARIA role for the chip (default: "status")
- `ariaLabel`: Custom accessibility label for the chip


## Variants

Choose between outline and filled variants to match your design needs.

<Playground
scope={{ Chip }}
tabs={[
{
name: "Outline",
code: `
<div style={{ display: 'flex', gap: '10px' }}>
<Chip variant="outline">Default</Chip>
<Chip variant="outline" style="accent">Accent</Chip>
<Chip variant="outline" leadingIcon={'O'}>With Icon</Chip>
<Chip variant="outline" isDismissible>Dismissible</Chip>
</div>`,
},
{
name: "Filled",
code: `
<div style={{ display: 'flex', gap: '10px' }}>
<Chip variant="filled">Default</Chip>
<Chip variant="filled" style="accent">Accent</Chip>
<Chip variant="filled" leadingIcon={'O'}>With Icon</Chip>
<Chip variant="filled" isDismissible>Dismissible</Chip>
</div>`,
},
]}
/>

## Sizes

The Chip component comes in two sizes:
- `small`: Compact size with less padding
- `large`: More spacious with increased padding

<Playground
scope={{ Chip }}
tabs={[
{
name: "Small",
code: `
<div style={{ display: 'flex', gap: '10px' }}>
<Chip size="small">Small Chip</Chip>
<Chip size="small" variant="filled">Small Filled</Chip>
<Chip size="small" leadingIcon={'O'}>With Icon</Chip>
<Chip size="small" isDismissible>Dismissible</Chip>
</div>`,
},
{
name: "Large",
code: `
<div style={{ display: 'flex', gap: '10px' }}>
<Chip size="large">Large Chip</Chip>
<Chip size="large" variant="filled">Large Filled</Chip>
<Chip size="large" leadingIcon={'O'}>With Icon</Chip>
<Chip size="large" isDismissible>Dismissible</Chip>
</div>`,
},
]}
/>

## Styles

Choose between neutral and accent styles to control the visual emphasis.

<Playground
scope={{ Chip }}
tabs={[
{
name: "Neutral",
code: `
<div style={{ display: 'flex', gap: '10px' }}>
<Chip style="neutral" variant="outline">Outline</Chip>
<Chip style="neutral" variant="filled">Filled</Chip>
<Chip style="neutral" leadingIcon={'O'}>With Icon</Chip>
<Chip style="neutral" isDismissible>Dismissible</Chip>
</div>`,
},
{
name: "Accent",
code: `
<div style={{ display: 'flex', gap: '10px' }}>
<Chip style="accent" variant="outline">Outline</Chip>
<Chip style="accent" variant="filled">Filled</Chip>
<Chip style="accent" leadingIcon={'O'}>With Icon</Chip>
<Chip style="accent" isDismissible>Dismissible</Chip>
</div>`,
},
]}
/>

## With Icons

Chips can include leading and trailing icons to provide additional context or actions.

<Playground
scope={{ Chip }}
tabs={[
{
name: "Leading Icon",
code: `
<div style={{ display: 'flex', gap: '10px' }}>
<Chip leadingIcon={'O'}>Add Item</Chip>
<Chip variant="filled" leadingIcon={'O'}>Selected</Chip>
</div>`,
},
{
name: "Trailing Icon",
code: `
<div style={{ display: 'flex', gap: '10px' }}>
<Chip trailingIcon={'O'}>Next</Chip>
<Chip variant="filled" trailingIcon={'O'}>Open</Chip>
</div>`,
},
{
name: "Both Icons",
code: `
<div style={{ display: 'flex', gap: '10px' }}>
<Chip leadingIcon={'O'} trailingIcon={'O'}>Download</Chip>
<Chip variant="filled" leadingIcon={'O'} trailingIcon={'O'}>Edit Profile</Chip>
</div>`,
},
]}
/>

## Dismissible

Chips can be made dismissible by adding the isDismissible prop and an onDismiss handler.

<Playground
scope={{ Chip }}
tabs={[
{
name: "Basic",
code: `
<Chip
isDismissible
onDismiss={() => console.log('dismissed')}
ariaLabel="Dismissible chip"
>
Click to Dismiss
</Chip>`,
},
{
name: "With Styles",
code: `
<div style={{ display: 'flex', gap: '10px' }}>
<Chip
variant="outline"
style="accent"
isDismissible
onDismiss={() => console.log('dismissed')}
>
Accent Outline
</Chip>
<Chip
variant="filled"
style="accent"
isDismissible
onDismiss={() => console.log('dismissed')}
>
Accent Filled
</Chip>
</div>`,
},
]}
/>


## Accessibility

The Chip component has some accessibility features:

- Uses semantic HTML elements
- Includes proper ARIA roles and labels
- Provides keyboard navigation support
- Makes decorative elements hidden from screen readers
- Ensures proper contrast ratios in all variants and states
46 changes: 42 additions & 4 deletions apps/www/examples/shield-ts/assets.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import React, { useState, useCallback, useEffect } from "react";
import dayjs from "dayjs";
import { HomeIcon } from "@radix-ui/react-icons";
import { HomeIcon, Cross1Icon, PlusIcon, CheckIcon } from "@radix-ui/react-icons";
import {
DataTable,
Title,
useTable
} from "@raystack/apsara";

import { toast, ToastContainer, Avatar, AvatarGroup, Button, Spinner, DropdownMenu, Breadcrumb, Flex, Text, Checkbox, InputField, Badge } from "@raystack/apsara/v1";
import { toast, ToastContainer, Avatar, AvatarGroup, Button, Spinner, DropdownMenu, Breadcrumb, Chip, Flex, Text, Checkbox, InputField, Badge } from "@raystack/apsara/v1";

import { getData, Payment } from "./data";
import { ApsaraColumnDef } from "@raystack/apsara/table/datatables.types";
const TOTAL_PAGES = 100;
Expand Down Expand Up @@ -265,13 +266,50 @@ const AssetsHeader = () => {
/>
</AvatarGroup> */}

{/* Add Chip examples */}
<Flex gap="small" align="center">
<Chip isDismissible variant="filled" size="small" style="accent" leadingIcon={<HomeIcon />} trailingIcon={<CheckIcon />}>Default</Chip>

{/* <Chip
variant="filled"
size="large"
style="accent"
leadingIcon={<PlusIcon />}
>
Large Accent
</Chip>
<Chip
variant="filled"
trailingIcon={<CheckIcon />}
>
With Icon
</Chip>
<Chip
variant="outline"
isDismissible
onDismiss={() => console.log('dismissed')}
>
Dismissible
</Chip>
<Chip
style="accent"
leadingIcon={<CheckIcon />}
trailingIcon={<Cross1Icon />}
>
Both Icons
</Chip> */}
</Flex>

</Flex>
<Flex gap="small">
{/* <Flex gap="small">
<AssetsFooter />
{isFiltered ? <DataTable.ClearFilter /> : <DataTable.FilterOptions />}
<DataTable.ViewOptions />
<DataTable.GloabalSearch placeholder="Search assets..." />
</Flex>
</Flex> */}
</Flex>
);
};
Expand Down
1 change: 1 addition & 0 deletions apps/www/utils/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export const primitivesRoutes = [
{ title: "Calendar", slug: "docs/primitives/components/calendar" },
{ title: "Command", slug: "docs/primitives/components/command" },
{ title: "Checkbox", slug: "docs/primitives/components/checkbox", newBadge: true },
{ title: "Chip", slug: "docs/primitives/components/chip", newBadge: true },
{ title: "Container", slug: "docs/primitives/components/container" },
{ title: "Datatable", slug: "docs/primitives/components/datatable" },
{ title: "Dialog", slug: "docs/primitives/components/dialog" },
Expand Down
Loading

0 comments on commit 87e0506

Please sign in to comment.