From 22e9ba466df49200c50fa95f39a5ac2486fad21d Mon Sep 17 00:00:00 2001 From: myusername Date: Thu, 14 May 2026 09:14:37 +0530 Subject: [PATCH 1/3] feat: Chip and ChipGroup components created --- src/Chip/Chip.stories.tsx | 105 +++++++++++++++++++++++++++ src/Chip/Chip.tsx | 147 ++++++++++++++++++++++++++++++++++++++ src/Chip/ChipGroup.tsx | 45 ++++++++++++ src/Chip/index.ts | 7 ++ src/LoginCard.tsx | 38 ++++++++++ src/index.css | 10 +++ 6 files changed, 352 insertions(+) create mode 100644 src/Chip/Chip.stories.tsx create mode 100644 src/Chip/Chip.tsx create mode 100644 src/Chip/ChipGroup.tsx create mode 100644 src/Chip/index.ts diff --git a/src/Chip/Chip.stories.tsx b/src/Chip/Chip.stories.tsx new file mode 100644 index 0000000..1e53516 --- /dev/null +++ b/src/Chip/Chip.stories.tsx @@ -0,0 +1,105 @@ +import type { Meta, StoryObj } from '@storybook/react-vite' + +import { Chip, ChipGroup } from '.' + +import { useState } from 'react' +import { fn } from 'storybook/test' + +const meta = { + title: 'Shared/Primitives/Chip', + + component: Chip, + + tags: ['autodocs'], +} satisfies Meta + +export default meta + +type Story = StoryObj + +export const Default: Story = { + args: { + label: 'Escalated', + onSelect: fn(), + }, +} + +export const Selected: Story = { + args: { + label: 'Escalated', + onSelect: fn(), + + isSelected: true, + }, +} + +export const WithCount: Story = { + args: { + label: 'Spam', + onSelect: fn(), + + count: 12, + }, +} + +export const Disabled: Story = { + args: { + label: 'Disabled', + onSelect: fn(), + + isDisabled: true, + }, +} + +export const Dismissible: Story = { + args: { + label: 'Active Filter', + onSelect: fn(), + + onDismiss: () => { + console.log('Dismiss clicked') + }, + }, +} + +export const Group: StoryObj = { + render: () => { + const [selected, setSelected] = useState('all') + + return ( +
+ +
+ ) + }, +} diff --git a/src/Chip/Chip.tsx b/src/Chip/Chip.tsx new file mode 100644 index 0000000..e00aaab --- /dev/null +++ b/src/Chip/Chip.tsx @@ -0,0 +1,147 @@ +import React from 'react' + +import { cva } from 'class-variance-authority' + +import { XMarkIcon } from '@heroicons/react/24/solid' + +const chipStyles = cva( + ` + inline-flex + items-center + gap-2 + rounded-full + border + px-4 + py-2 + text-sm + transition-colors + whitespace-nowrap + select-none + focus:outline-none + `, + { + variants: { + isSelected: { + true: ` + bg-text-tertiary/20 + text-text-primary + border-border-secondary + font-medium + `, + + false: ` + bg-transparent + text-text-secondary + border-border-tertiary + font-normal + hover:bg-bg-secondary + hover:text-text-primary + `, + }, + + isDisabled: { + true: ` + opacity-50 + pointer-events-none + `, + + false: ` + cursor-pointer + `, + }, + }, + + defaultVariants: { + isSelected: false, + isDisabled: false, + }, + } +) + +export interface ChipProps { + label: string + + isSelected?: boolean + + isDisabled?: boolean + + onSelect?: () => void + + onDismiss?: () => void + + count?: number + + className?: string +} + +export function Chip({ + label, + + isSelected = false, + + isDisabled = false, + + onSelect, + + onDismiss, + + count, + + className = '', +}: ChipProps) { + const handleKeyDown = (e: React.KeyboardEvent) => { + if (e.key === 'Enter' || e.key === ' ') { + e.preventDefault() + + onSelect?.() + } + } + + return ( + + ) +} + +export default Chip diff --git a/src/Chip/ChipGroup.tsx b/src/Chip/ChipGroup.tsx new file mode 100644 index 0000000..8c17c6f --- /dev/null +++ b/src/Chip/ChipGroup.tsx @@ -0,0 +1,45 @@ +import React from 'react' + +import { Chip } from './Chip' + +export interface ChipGroupOption { + label: string + + value: string + + count?: number +} + +export interface ChipGroupProps { + options: ChipGroupOption[] + + selected: string + + onChange: (value: string) => void +} + +export function ChipGroup({ + options, + + selected, + + onChange, +}: ChipGroupProps) { + return ( +
+ {options.map((option) => ( + { + onChange(option.value) + }} + /> + ))} +
+ ) +} + +export default ChipGroup diff --git a/src/Chip/index.ts b/src/Chip/index.ts new file mode 100644 index 0000000..6dafa86 --- /dev/null +++ b/src/Chip/index.ts @@ -0,0 +1,7 @@ +export { Chip } from './Chip' + +export type { ChipProps } from './Chip' + +export { ChipGroup } from './ChipGroup' + +export type { ChipGroupProps, ChipGroupOption } from './ChipGroup' diff --git a/src/LoginCard.tsx b/src/LoginCard.tsx index 23fde74..57104d8 100644 --- a/src/LoginCard.tsx +++ b/src/LoginCard.tsx @@ -1,3 +1,5 @@ +import { useState } from 'react' +import { ChipGroup } from './Chip' import { ProgressBar } from './shared/primitives/Progressbar' function LoginCard() { @@ -5,10 +7,46 @@ function LoginCard() { // Replace with your actual backend OAuth endpoint window.location.href = 'http://localhost:8080/oauth2/authorization/google' } + const [selected, setSelected] = useState('all') return (
+ { + setSelected(value) + + console.log('Selected:', value) + }} + options={[ + { + label: 'All', + value: 'all', + }, + + { + label: 'Escalated', + value: 'escalated', + count: 1, + }, + + { + label: 'Spam', + value: 'spam', + }, + + { + label: 'Hate speech', + value: 'hate-speech', + }, + + { + label: 'Misinformation', + value: 'misinformation', + }, + ]} + /> {/* Heading */}

Welcome

diff --git a/src/index.css b/src/index.css index 7573056..62e9e5a 100644 --- a/src/index.css +++ b/src/index.css @@ -117,6 +117,16 @@ html[data-theme-loaded='true'] * { box-shadow 0.25s ease; } +/* Hide scrollbar but preserve scrolling */ +.scrollbar-hide { + -ms-overflow-style: none; + scrollbar-width: none; +} + +.scrollbar-hide::-webkit-scrollbar { + display: none; +} + @keyframes shimmer { 0% { background-position: 200% 0; From ff883f99f08969d0621dbf16d14f59c73b9b6d2c Mon Sep 17 00:00:00 2001 From: myusername Date: Thu, 14 May 2026 09:23:58 +0530 Subject: [PATCH 2/3] feat: Commented out Chip and ProgressBar from the LoginCard which was added for just testing --- src/LoginCard.tsx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/LoginCard.tsx b/src/LoginCard.tsx index 57104d8..51c70ff 100644 --- a/src/LoginCard.tsx +++ b/src/LoginCard.tsx @@ -1,18 +1,18 @@ -import { useState } from 'react' -import { ChipGroup } from './Chip' -import { ProgressBar } from './shared/primitives/Progressbar' +// import { useState } from 'react' +// import { ChipGroup } from './Chip' +// import { ProgressBar } from './shared/primitives/Progressbar' function LoginCard() { const handleGoogleLogin = () => { // Replace with your actual backend OAuth endpoint window.location.href = 'http://localhost:8080/oauth2/authorization/google' } - const [selected, setSelected] = useState('all') + // const [selected, setSelected] = useState('all') return (
- { setSelected(value) @@ -46,7 +46,7 @@ function LoginCard() { value: 'misinformation', }, ]} - /> + /> */} {/* Heading */}

Welcome

@@ -94,7 +94,7 @@ function LoginCard() { Privacy Policy

- + {/* */}
) From 02af10b7aa83b25ad4402d698e0a2f76e2978c0b Mon Sep 17 00:00:00 2001 From: myusername Date: Thu, 14 May 2026 09:56:48 +0530 Subject: [PATCH 3/3] feat:Login Card chips added. --- README.md | 2 +- src/LoginCard.tsx | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index d3b9f8b..5e5e5fb 100644 --- a/README.md +++ b/README.md @@ -72,4 +72,4 @@ export default defineConfig([ ]) ``` - + diff --git a/src/LoginCard.tsx b/src/LoginCard.tsx index 51c70ff..60e010e 100644 --- a/src/LoginCard.tsx +++ b/src/LoginCard.tsx @@ -1,5 +1,5 @@ -// import { useState } from 'react' -// import { ChipGroup } from './Chip' +import { useState } from 'react' +import { ChipGroup } from './Chip' // import { ProgressBar } from './shared/primitives/Progressbar' function LoginCard() { @@ -7,12 +7,12 @@ function LoginCard() { // Replace with your actual backend OAuth endpoint window.location.href = 'http://localhost:8080/oauth2/authorization/google' } - // const [selected, setSelected] = useState('all') + const [selected, setSelected] = useState('all') return (
- {/* { setSelected(value) @@ -46,7 +46,7 @@ function LoginCard() { value: 'misinformation', }, ]} - /> */} + /> {/* Heading */}

Welcome