From 2fb133f98ad5eeb27c33129068a0d646d7a7592a Mon Sep 17 00:00:00 2001 From: myusername Date: Tue, 12 May 2026 10:34:42 +0530 Subject: [PATCH 1/2] feat: SidebarNavItem component completed --- .../SidebarNavItem/SidebarNavItem.stories.tsx | 67 ++++++++++++++ src/shared/SidebarNavItem/SidebarNavItem.tsx | 92 +++++++++++++++++++ src/shared/SidebarNavItem/index.ts | 2 + 3 files changed, 161 insertions(+) create mode 100644 src/shared/SidebarNavItem/SidebarNavItem.stories.tsx create mode 100644 src/shared/SidebarNavItem/SidebarNavItem.tsx create mode 100644 src/shared/SidebarNavItem/index.ts diff --git a/src/shared/SidebarNavItem/SidebarNavItem.stories.tsx b/src/shared/SidebarNavItem/SidebarNavItem.stories.tsx new file mode 100644 index 0000000..d6ef4ef --- /dev/null +++ b/src/shared/SidebarNavItem/SidebarNavItem.stories.tsx @@ -0,0 +1,67 @@ +import type { Meta, StoryObj } from '@storybook/react-vite' + +import { + QueueListIcon, + ExclamationTriangleIcon, + CheckCircleIcon, + // UsersIcon, + // PresentationChartLineIcon +} from '@heroicons/react/24/outline' + +import { SidebarNavItem } from './SidebarNavItem' + +const meta = { + title: 'Shared/Composites/SidebarNavItem', + + component: SidebarNavItem, + + tags: ['autodocs'], + + argTypes: { + onClick: { + action: 'clicked', + }, + }, +} satisfies Meta + +export default meta + +type Story = StoryObj + +export const Default: Story = { + args: { + label: 'Reports', + icon: , + isActive: true, + }, +} + +export const Active: Story = { + args: { + label: 'Reports', + icon: , + isActive: true, + }, +} + +export const WithDangerBadge: Story = { + args: { + label: 'Escalated', + icon: , + + badge: 12, + + badgeVariant: 'danger', + }, +} + +export const WithInfoBadge: Story = { + args: { + label: 'Resolved', + icon: , + + badge: 4, + + badgeVariant: 'info', + }, +} diff --git a/src/shared/SidebarNavItem/SidebarNavItem.tsx b/src/shared/SidebarNavItem/SidebarNavItem.tsx new file mode 100644 index 0000000..838fa02 --- /dev/null +++ b/src/shared/SidebarNavItem/SidebarNavItem.tsx @@ -0,0 +1,92 @@ +import React from 'react' +import { cva } from 'class-variance-authority' +import { Badge } from '../Badge' + +const sidebarNavItem = cva( + [ + 'w-full', + 'flex items-center justify-between', + 'gap-3', + + 'rounded-lg', + + 'px-3 py-2', + + 'transition-colors duration-150', + + 'cursor-pointer', + 'select-none', + + 'focus-visible:outline-none', + 'focus-visible:ring-2', + 'focus-visible:ring-border-info', + + 'active:scale-[0.99]', + ], + { + variants: { + isActive: { + true: ['bg-bg-secondary', 'text-text-primary', 'font-medium'], + + false: ['text-text-tertiary', 'hover:bg-bg-secondary', 'hover:text-text-primary'], + }, + }, + + defaultVariants: { + isActive: false, + }, + } +) + +export interface SidebarNavItemProps { + label: string + + icon: React.ReactNode + + isActive?: boolean + + badge?: number | string + + badgeVariant?: 'danger' | 'info' + + onClick?: () => void + + className?: string +} + +export function SidebarNavItem({ + label, + icon, + isActive = false, + badge, + badgeVariant = 'info', + onClick, + className, +}: SidebarNavItemProps) { + return ( + + ) +} + +export default SidebarNavItem diff --git a/src/shared/SidebarNavItem/index.ts b/src/shared/SidebarNavItem/index.ts new file mode 100644 index 0000000..cc9c9ce --- /dev/null +++ b/src/shared/SidebarNavItem/index.ts @@ -0,0 +1,2 @@ +export { SidebarNavItem } from './SidebarNavItem' +export type { SidebarNavItemProps } from './SidebarNavItem' From d48e8a995629a7fc69d9854030246c7727055a9d Mon Sep 17 00:00:00 2001 From: myusername Date: Tue, 12 May 2026 12:04:25 +0530 Subject: [PATCH 2/2] feat: Fixed link so that it renders properly in Storybook --- .../SidebarNavItem/SidebarNavItem.stories.tsx | 11 +++++------ src/shared/SidebarNavItem/SidebarNavItem.tsx | 14 +++++++------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/shared/SidebarNavItem/SidebarNavItem.stories.tsx b/src/shared/SidebarNavItem/SidebarNavItem.stories.tsx index d6ef4ef..03649a2 100644 --- a/src/shared/SidebarNavItem/SidebarNavItem.stories.tsx +++ b/src/shared/SidebarNavItem/SidebarNavItem.stories.tsx @@ -17,11 +17,7 @@ const meta = { tags: ['autodocs'], - argTypes: { - onClick: { - action: 'clicked', - }, - }, + argTypes: {}, } satisfies Meta export default meta @@ -30,14 +26,15 @@ type Story = StoryObj export const Default: Story = { args: { + link: '/reports', label: 'Reports', icon: , - isActive: true, }, } export const Active: Story = { args: { + link: '/reports', label: 'Reports', icon: , isActive: true, @@ -46,6 +43,7 @@ export const Active: Story = { export const WithDangerBadge: Story = { args: { + link: '/escalated', label: 'Escalated', icon: , @@ -57,6 +55,7 @@ export const WithDangerBadge: Story = { export const WithInfoBadge: Story = { args: { + link: '/resolved', label: 'Resolved', icon: , diff --git a/src/shared/SidebarNavItem/SidebarNavItem.tsx b/src/shared/SidebarNavItem/SidebarNavItem.tsx index 838fa02..1527b78 100644 --- a/src/shared/SidebarNavItem/SidebarNavItem.tsx +++ b/src/shared/SidebarNavItem/SidebarNavItem.tsx @@ -1,6 +1,7 @@ import React from 'react' import { cva } from 'class-variance-authority' import { Badge } from '../Badge' +// import { NavLink } from 'react-router-dom' const sidebarNavItem = cva( [ @@ -39,6 +40,8 @@ const sidebarNavItem = cva( ) export interface SidebarNavItemProps { + link?: string + label: string icon: React.ReactNode @@ -49,24 +52,21 @@ export interface SidebarNavItemProps { badgeVariant?: 'danger' | 'info' - onClick?: () => void - className?: string } export function SidebarNavItem({ + // link, label, icon, isActive = false, badge, badgeVariant = 'info', - onClick, className, }: SidebarNavItemProps) { return ( - + ) }