feat: Thêm các component Popover, Tooltip và refactor Switch sử dụng Radix UI, đồng thời cập nhật biến màu và dependencies.
This commit is contained in:
@@ -18,6 +18,9 @@
|
||||
"@radix-ui/react-avatar": "^1.0.4",
|
||||
"@radix-ui/react-dialog": "^1.0.5",
|
||||
"@radix-ui/react-dropdown-menu": "^2.0.6",
|
||||
"@radix-ui/react-popover": "^1.1.15",
|
||||
"@radix-ui/react-switch": "^1.2.6",
|
||||
"@radix-ui/react-tooltip": "^1.2.8",
|
||||
"@tanstack/react-query": "^5.17.0",
|
||||
"axios": "^1.6.5",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
|
||||
@@ -29,7 +29,8 @@
|
||||
background-color: var(--bg-primary);
|
||||
color: var(--text-primary);
|
||||
font-size: var(--text-base);
|
||||
line-height: 1.5;
|
||||
font-weight: var(--font-light);
|
||||
line-height: var(--leading-relaxed);
|
||||
transition: background-color var(--duration-normal) var(--ease-in-out),
|
||||
color var(--duration-normal) var(--ease-in-out);
|
||||
}
|
||||
@@ -89,55 +90,7 @@
|
||||
*/
|
||||
body {
|
||||
font-size: 16px;
|
||||
min-font-size: 16px;
|
||||
}
|
||||
|
||||
/**
|
||||
* EN: Support zoom up to 200% without breaking layout - WCAG 2.1 AA
|
||||
* VI: Hỗ trợ zoom lên đến 200% mà không làm vỡ layout - WCAG 2.1 AA
|
||||
*/
|
||||
html {
|
||||
zoom: 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* EN: Ensure all text is zoomable up to 200% - WCAG 2.1 AA
|
||||
* VI: Đảm bảo tất cả text có thể zoom lên đến 200% - WCAG 2.1 AA
|
||||
*/
|
||||
* {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
/**
|
||||
* EN: Prevent horizontal scroll on zoom - WCAG 2.1 AA
|
||||
* VI: Ngăn scroll ngang khi zoom - WCAG 2.1 AA
|
||||
*/
|
||||
body {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* EN: Typing Indicator Animation
|
||||
* VI: Animation cho Typing Indicator
|
||||
*/
|
||||
@keyframes typing-pulse {
|
||||
|
||||
0%,
|
||||
60%,
|
||||
100% {
|
||||
opacity: 0.3;
|
||||
transform: scale(0.8);
|
||||
}
|
||||
|
||||
30% {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
.typing-dot {
|
||||
/* EN: Animation properties are set inline to allow customization / VI: Các thuộc tính animation được set inline để cho phép tùy chỉnh */
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -159,8 +112,8 @@
|
||||
}
|
||||
|
||||
/**
|
||||
* EN: Floating Animation - Creates a weightless hovering effect
|
||||
* VI: Animation lơ lửng - Tạo hiệu ứng nhấp nhô không trọng lực
|
||||
* EN: Floating Animation
|
||||
* VI: Animation lơ lửng
|
||||
*/
|
||||
@keyframes float {
|
||||
0% {
|
||||
@@ -177,8 +130,8 @@
|
||||
}
|
||||
|
||||
/**
|
||||
* EN: Mesh Gradient Animation - Creates dynamic moving color spots
|
||||
* VI: Animation Mesh Gradient - Tạo các đốm màu di chuyển động
|
||||
* EN: Mesh Gradient Animation
|
||||
* VI: Animation Mesh Gradient
|
||||
*/
|
||||
@keyframes mesh-move {
|
||||
0% {
|
||||
@@ -199,8 +152,8 @@
|
||||
}
|
||||
|
||||
/**
|
||||
* EN: Shimmer animation for skeleton loaders
|
||||
* VI: Animation shimmer cho skeleton loaders
|
||||
* EN: Shimmer animation
|
||||
* VI: Animation shimmer
|
||||
*/
|
||||
@keyframes shimmer {
|
||||
0% {
|
||||
@@ -213,8 +166,8 @@
|
||||
}
|
||||
|
||||
/**
|
||||
* EN: Ensure smooth animations and prevent layout shift
|
||||
* VI: Đảm bảo animation mượt mà và ngăn layout shift
|
||||
* EN: Utilities Layer
|
||||
* VI: Layer Utilities
|
||||
*/
|
||||
@layer utilities {
|
||||
.animate-fadeIn {
|
||||
@@ -274,12 +227,6 @@
|
||||
animation: shimmer 2s infinite;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
EN: Responsive Layout Utilities
|
||||
VI: Utilities cho responsive layout
|
||||
============================================ */
|
||||
|
||||
/* Mobile-first container */
|
||||
.container-responsive {
|
||||
width: 100%;
|
||||
margin-left: auto;
|
||||
@@ -316,21 +263,17 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* Mobile-optimized text sizes */
|
||||
.text-responsive-hero {
|
||||
font-size: 2.5rem;
|
||||
/* 40px mobile */
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.text-responsive-hero {
|
||||
font-size: 3.75rem;
|
||||
/* 60px desktop */
|
||||
}
|
||||
}
|
||||
|
||||
/* Touch-friendly buttons on mobile */
|
||||
.btn-touch {
|
||||
min-height: 44px;
|
||||
min-width: 44px;
|
||||
|
||||
@@ -1,8 +1,18 @@
|
||||
import type { Metadata } from 'next';
|
||||
import { Inter } from 'next/font/google';
|
||||
import './globals.css';
|
||||
import { ThemeProvider } from '../contexts/theme-context';
|
||||
import { QueryProvider } from '../providers/query-provider';
|
||||
import { I18nProvider } from '../providers/i18n-provider';
|
||||
|
||||
// EN: Configure Inter font with subsets and variable name
|
||||
// VI: Cấu hình font Inter với các subsets và tên biến CSS
|
||||
const inter = Inter({
|
||||
subsets: ['latin', 'vietnamese'],
|
||||
display: 'swap',
|
||||
variable: '--font-inter',
|
||||
weight: ['100', '200', '300', '400', '500', '600', '700', '800', '900'],
|
||||
});
|
||||
import { SkipToContent } from '../components/accessibility/skip-to-content';
|
||||
|
||||
/**
|
||||
@@ -65,7 +75,7 @@ export default function RootLayout({
|
||||
return (
|
||||
// EN: Root HTML structure with dynamic language (will be updated by I18nProvider)
|
||||
// VI: Cấu trúc HTML gốc với ngôn ngữ động (sẽ được cập nhật bởi I18nProvider)
|
||||
<html lang="en" suppressHydrationWarning>
|
||||
<html lang="en" className={inter.variable} suppressHydrationWarning>
|
||||
<body>
|
||||
<SkipToContent />
|
||||
<I18nProvider>
|
||||
|
||||
39
apps/web-client/src/components/ui/popover.tsx
Normal file
39
apps/web-client/src/components/ui/popover.tsx
Normal file
@@ -0,0 +1,39 @@
|
||||
'use client';
|
||||
|
||||
import * as React from 'react';
|
||||
import * as PopoverPrimitive from '@radix-ui/react-popover';
|
||||
import { cn } from '@/lib/utils';
|
||||
|
||||
/**
|
||||
* EN: Popover component - Floating content triggered by an element
|
||||
* VI: Component Popover - Nội dung nổi được kích hoạt bởi một phần tử
|
||||
*/
|
||||
const Popover = PopoverPrimitive.Root;
|
||||
|
||||
const PopoverTrigger = PopoverPrimitive.Trigger;
|
||||
|
||||
const PopoverAnchor = PopoverPrimitive.Anchor;
|
||||
|
||||
const PopoverContent = React.forwardRef<
|
||||
React.ElementRef<typeof PopoverPrimitive.Content>,
|
||||
React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>
|
||||
>(({ className, align = 'center', sideOffset = 4, ...props }, ref) => (
|
||||
<PopoverPrimitive.Portal>
|
||||
<PopoverPrimitive.Content
|
||||
ref={ref}
|
||||
align={align}
|
||||
sideOffset={sideOffset}
|
||||
className={cn(
|
||||
// EN: Base styles for popover content / VI: Style cơ bản cho nội dung popover
|
||||
'z-50 w-72 rounded-xl border border-border-primary bg-bg-elevated p-4 text-text-primary shadow-xl outline-none',
|
||||
// EN: Animations / VI: Animation
|
||||
'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
</PopoverPrimitive.Portal>
|
||||
));
|
||||
PopoverContent.displayName = PopoverPrimitive.Content.displayName;
|
||||
|
||||
export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor };
|
||||
@@ -1,101 +1,40 @@
|
||||
'use client';
|
||||
|
||||
import * as React from 'react';
|
||||
|
||||
import * as SwitchPrimitives from '@radix-ui/react-switch';
|
||||
import { cn } from '@/lib/utils';
|
||||
|
||||
/**
|
||||
* EN: Switch component props interface
|
||||
* VI: Interface cho props của component Switch
|
||||
* EN: Switch component - A control that allows the user to toggle between checked and not checked
|
||||
* VI: Component Switch - Bộ điều khiển cho phép người dùng chuyển đổi giữa trạng thái checked và không checked
|
||||
*/
|
||||
export interface SwitchProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'onChange'> {
|
||||
/**
|
||||
* EN: Whether the switch is checked / VI: Switch có được bật hay không
|
||||
*/
|
||||
checked?: boolean;
|
||||
/**
|
||||
* EN: Default checked state (uncontrolled) / VI: Trạng thái checked mặc định (uncontrolled)
|
||||
*/
|
||||
defaultChecked?: boolean;
|
||||
/**
|
||||
* EN: Callback when checked state changes / VI: Callback khi trạng thái checked thay đổi
|
||||
*/
|
||||
onCheckedChange?: (checked: boolean) => void;
|
||||
/**
|
||||
* EN: Whether the switch is disabled / VI: Switch có bị vô hiệu hóa hay không
|
||||
*/
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* EN: Switch component - Toggle switch for binary settings
|
||||
* VI: Component Switch - Toggle switch cho các cài đặt nhị phân
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* <Switch checked={enabled} onCheckedChange={setEnabled} />
|
||||
* <Switch defaultChecked disabled />
|
||||
* ```
|
||||
*/
|
||||
const Switch = React.forwardRef<HTMLButtonElement, SwitchProps>(
|
||||
({ className, checked, defaultChecked, onCheckedChange, disabled, ...props }, ref) => {
|
||||
const [internalChecked, setInternalChecked] = React.useState(defaultChecked ?? false);
|
||||
const isControlled = checked !== undefined;
|
||||
const isChecked = isControlled ? checked : internalChecked;
|
||||
|
||||
const handleClick = () => {
|
||||
if (disabled) return;
|
||||
const newChecked = !isChecked;
|
||||
if (!isControlled) {
|
||||
setInternalChecked(newChecked);
|
||||
}
|
||||
onCheckedChange?.(newChecked);
|
||||
};
|
||||
|
||||
const handleKeyDown = (e: React.KeyboardEvent<HTMLButtonElement>) => {
|
||||
if (disabled) return;
|
||||
if (e.key === 'Enter' || e.key === ' ') {
|
||||
e.preventDefault();
|
||||
handleClick();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
role="switch"
|
||||
aria-checked={isChecked}
|
||||
ref={ref}
|
||||
disabled={disabled}
|
||||
onClick={handleClick}
|
||||
onKeyDown={handleKeyDown}
|
||||
className={cn(
|
||||
// EN: Base switch styles / VI: Styles cơ bản cho switch
|
||||
'peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent',
|
||||
'transition-colors duration-150 ease-in-out',
|
||||
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#3B82F6] focus-visible:ring-offset-2 focus-visible:ring-offset-[#0A0A0A]',
|
||||
'disabled:cursor-not-allowed disabled:opacity-50',
|
||||
// EN: Checked state - blue background / VI: Trạng thái checked - nền xanh
|
||||
isChecked ? 'bg-[#3B82F6]' : 'bg-[#374151]',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{/* EN: Switch thumb / VI: Thumb của switch */}
|
||||
<span
|
||||
className={cn(
|
||||
// EN: Base thumb styles / VI: Styles cơ bản cho thumb
|
||||
'pointer-events-none block h-5 w-5 rounded-full bg-white shadow-lg',
|
||||
'transform transition-transform duration-150 ease-in-out',
|
||||
// EN: Checked state - translate to right / VI: Trạng thái checked - dịch sang phải
|
||||
isChecked ? 'translate-x-5' : 'translate-x-0'
|
||||
)}
|
||||
/>
|
||||
</button>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
Switch.displayName = 'Switch';
|
||||
const Switch = React.forwardRef<
|
||||
React.ElementRef<typeof SwitchPrimitives.Root>,
|
||||
React.ComponentPropsWithoutRef<typeof SwitchPrimitives.Root>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<SwitchPrimitives.Root
|
||||
className={cn(
|
||||
// EN: Base track styles / VI: Style track cơ bản
|
||||
'peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors',
|
||||
// EN: Focus and disabled states / VI: Trạng thái focus và disabled
|
||||
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent-primary focus-visible:ring-offset-2 focus-visible:ring-offset-bg-primary',
|
||||
'disabled:cursor-not-allowed disabled:opacity-50',
|
||||
// EN: Color states / VI: Trạng thái màu sắc
|
||||
'data-[state=checked]:bg-brand-primary data-[state=unchecked]:bg-bg-tertiary',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
ref={ref}
|
||||
>
|
||||
<SwitchPrimitives.Thumb
|
||||
className={cn(
|
||||
// EN: Thumb styles / VI: Style thumb
|
||||
'pointer-events-none block h-5 w-5 rounded-full bg-white shadow-lg ring-0 transition-transform',
|
||||
'data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0'
|
||||
)}
|
||||
/>
|
||||
</SwitchPrimitives.Root>
|
||||
));
|
||||
Switch.displayName = SwitchPrimitives.Root.displayName;
|
||||
|
||||
export { Switch };
|
||||
|
||||
34
apps/web-client/src/components/ui/tooltip.tsx
Normal file
34
apps/web-client/src/components/ui/tooltip.tsx
Normal file
@@ -0,0 +1,34 @@
|
||||
'use client';
|
||||
|
||||
import * as React from 'react';
|
||||
import * as TooltipPrimitive from '@radix-ui/react-tooltip';
|
||||
import { cn } from '@/lib/utils';
|
||||
|
||||
/**
|
||||
* EN: Tooltip component - Informational text on hover or focus
|
||||
* VI: Component Tooltip - Văn bản thông tin khi hover hoặc focus
|
||||
*/
|
||||
const TooltipProvider = TooltipPrimitive.Provider;
|
||||
|
||||
const Tooltip = TooltipPrimitive.Root;
|
||||
|
||||
const TooltipTrigger = TooltipPrimitive.Trigger;
|
||||
|
||||
const TooltipContent = React.forwardRef<
|
||||
React.ElementRef<typeof TooltipPrimitive.Content>,
|
||||
React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>
|
||||
>(({ className, sideOffset = 4, ...props }, ref) => (
|
||||
<TooltipPrimitive.Content
|
||||
ref={ref}
|
||||
sideOffset={sideOffset}
|
||||
className={cn(
|
||||
// EN: Base styles for tooltip content / VI: Style cơ bản cho nội dung tooltip
|
||||
'z-50 overflow-hidden rounded-md bg-bg-elevated border border-border-primary px-3 py-1.5 text-xs text-text-primary shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
TooltipContent.displayName = TooltipPrimitive.Content.displayName;
|
||||
|
||||
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
|
||||
@@ -14,305 +14,310 @@
|
||||
*/
|
||||
|
||||
:root {
|
||||
/* ============================================
|
||||
/* ============================================
|
||||
EN: Color Palette - Dark Mode (Primary Theme)
|
||||
VI: Bảng màu - Dark Mode (Theme chính)
|
||||
============================================ */
|
||||
|
||||
/* Background Colors / Màu nền */
|
||||
--bg-primary: #000000;
|
||||
/* Pure black - Main background */
|
||||
--bg-secondary: #0A0A0A;
|
||||
/* Almost black - Card/Panel background */
|
||||
--bg-tertiary: #141414;
|
||||
/* Very dark grey - Hover states */
|
||||
--bg-elevated: #1A1A1A;
|
||||
/* Elevated surfaces (modals, dropdowns) */
|
||||
/* Background Colors / Màu nền */
|
||||
--bg-primary: #000000;
|
||||
/* Pure black - Main background */
|
||||
--bg-secondary: #0A0A0A;
|
||||
/* Almost black - Card/Panel background */
|
||||
--bg-tertiary: #141414;
|
||||
/* Very dark grey - Hover states */
|
||||
--bg-elevated: #1A1A1A;
|
||||
/* Elevated surfaces (modals, dropdowns) */
|
||||
|
||||
/* Text Colors (WCAG Compliant) / Màu chữ (tuân thủ WCAG) */
|
||||
--text-primary: #FFFFFF;
|
||||
/* Pure white - Primary text */
|
||||
--text-secondary: #B0B0B0;
|
||||
/* Lighter grey - Secondary text (Improved contrast) */
|
||||
--text-tertiary: #808080;
|
||||
/* Mid grey - Tertiary/disabled text (Improved contrast) */
|
||||
--text-muted: #505050;
|
||||
/* Dark grey - Muted elements */
|
||||
--text-inverse: #000000;
|
||||
/* Black - Text on light/white backgrounds */
|
||||
/* Text Colors (WCAG Compliant) / Màu chữ (tuân thủ WCAG) */
|
||||
--text-primary: #FFFFFF;
|
||||
/* Pure white - Primary text */
|
||||
--text-secondary: #B0B0B0;
|
||||
/* Lighter grey - Secondary text (Improved contrast) */
|
||||
--text-tertiary: #808080;
|
||||
/* Mid grey - Tertiary/disabled text (Improved contrast) */
|
||||
--text-muted: #505050;
|
||||
/* Dark grey - Muted elements */
|
||||
--text-inverse: #000000;
|
||||
/* Black - Text on light/white backgrounds */
|
||||
|
||||
/* Brand/Accent Colors / Màu thương hiệu/Accent */
|
||||
--accent-primary: #FFFFFF;
|
||||
/* White - Primary actions (High contrast) */
|
||||
--accent-secondary: #333333;
|
||||
/* Dark grey - Secondary actions */
|
||||
--accent-success: #10B981;
|
||||
/* Green - Success states */
|
||||
--accent-warning: #F59E0B;
|
||||
/* Amber - Warnings */
|
||||
--accent-error: #EF4444;
|
||||
/* Red - Errors */
|
||||
--accent-info: #06B6D4;
|
||||
/* Cyan - Info */
|
||||
/* Brand/Accent Colors / Màu thương hiệu/Accent */
|
||||
--accent-primary: #FFFFFF;
|
||||
/* White - Primary actions (High contrast) */
|
||||
--accent-secondary: #333333;
|
||||
/* Dark grey - Secondary actions */
|
||||
--accent-success: #10B981;
|
||||
/* Green - Success states */
|
||||
--accent-warning: #F59E0B;
|
||||
/* Amber - Warnings */
|
||||
--accent-error: #EF4444;
|
||||
/* Red - Errors */
|
||||
--accent-info: #06B6D4;
|
||||
/* Cyan - Info */
|
||||
|
||||
/* Chat Specific Colors / Màu riêng cho Chat */
|
||||
--chat-user-bubble: #1A1A1A;
|
||||
/* Dark grey - User message */
|
||||
--chat-ai-bubble: transparent;
|
||||
/* Transparent - AI message (Minimal) */
|
||||
--chat-user-text: #FFFFFF;
|
||||
/* White text */
|
||||
--chat-ai-text: #E5E5E5;
|
||||
/* Off-white text */
|
||||
--chat-timestamp: #555555;
|
||||
/* Dark grey timestamp */
|
||||
--chat-divider: #222222;
|
||||
/* Divider between messages */
|
||||
/* Chat Specific Colors / Màu riêng cho Chat */
|
||||
--chat-user-bubble: #1A1A1A;
|
||||
/* Dark grey - User message */
|
||||
--chat-ai-bubble: transparent;
|
||||
/* Transparent - AI message (Minimal) */
|
||||
--chat-user-text: #FFFFFF;
|
||||
/* White text */
|
||||
--chat-ai-text: #E5E5E5;
|
||||
/* Off-white text */
|
||||
--chat-timestamp: #555555;
|
||||
/* Dark grey timestamp */
|
||||
--chat-divider: #222222;
|
||||
/* Divider between messages */
|
||||
|
||||
/* Border Colors / Màu viền */
|
||||
--border-primary: #222222;
|
||||
/* Subtle borders */
|
||||
--border-secondary: #333333;
|
||||
/* Hover borders */
|
||||
--border-focus: #FFFFFF;
|
||||
/* Focus state - White */
|
||||
/* Border Colors / Màu viền */
|
||||
--border-primary: #222222;
|
||||
/* Subtle borders */
|
||||
--border-secondary: #333333;
|
||||
/* Hover borders */
|
||||
--border-focus: #FFFFFF;
|
||||
/* Focus state - White */
|
||||
|
||||
/* ============================================
|
||||
/* ============================================
|
||||
EN: Brand Colors (Primary Identity)
|
||||
VI: Màu thương hiệu (Nhận diện chính)
|
||||
============================================ */
|
||||
|
||||
/* Primary Brand Color - Main brand identity (Blue - Tech & Trust) */
|
||||
--brand-primary: #3B82F6;
|
||||
--brand-primary-light: #60A5FA;
|
||||
--brand-primary-dark: #2563EB;
|
||||
--brand-primary-contrast: #FFFFFF;
|
||||
/* Primary Brand Color - Main brand identity (Blue - Tech & Trust) */
|
||||
--brand-primary: #3B82F6;
|
||||
--brand-primary-light: #60A5FA;
|
||||
--brand-primary-dark: #2563EB;
|
||||
--brand-primary-contrast: #FFFFFF;
|
||||
|
||||
/* Secondary Brand Color - Supporting color (Purple - Innovation) */
|
||||
--brand-secondary: #8B5CF6;
|
||||
--brand-secondary-light: #A78BFA;
|
||||
--brand-secondary-dark: #7C3AED;
|
||||
/* Secondary Brand Color - Supporting color (Purple - Innovation) */
|
||||
--brand-secondary: #8B5CF6;
|
||||
--brand-secondary-light: #A78BFA;
|
||||
--brand-secondary-dark: #7C3AED;
|
||||
|
||||
/* Accent Color - Call-to-action (Cyan - Energy) */
|
||||
--brand-accent: #06B6D4;
|
||||
--brand-accent-light: #22D3EE;
|
||||
--brand-accent-dark: #0891B2;
|
||||
/* Accent Color - Call-to-action (Cyan - Energy) */
|
||||
--brand-accent: #06B6D4;
|
||||
--brand-accent-light: #22D3EE;
|
||||
--brand-accent-dark: #0891B2;
|
||||
|
||||
/* Brand Gradients - For backgrounds and special elements */
|
||||
--brand-gradient-primary: linear-gradient(135deg, var(--brand-primary) 0%, var(--brand-secondary) 100%);
|
||||
--brand-gradient-accent: linear-gradient(135deg, var(--brand-accent) 0%, var(--brand-primary) 100%);
|
||||
--brand-gradient-vertical: linear-gradient(180deg, var(--brand-primary) 0%, var(--brand-secondary) 100%);
|
||||
/* Brand Gradients - For backgrounds and special elements */
|
||||
--brand-gradient-primary: linear-gradient(135deg, var(--brand-primary) 0%, var(--brand-secondary) 100%);
|
||||
--brand-gradient-accent: linear-gradient(135deg, var(--brand-accent) 0%, var(--brand-primary) 100%);
|
||||
--brand-gradient-vertical: linear-gradient(180deg, var(--brand-primary) 0%, var(--brand-secondary) 100%);
|
||||
|
||||
/* ============================================
|
||||
/* ============================================
|
||||
EN: Glassmorphism Effects
|
||||
VI: Hiệu ứng Glassmorphism
|
||||
============================================ */
|
||||
|
||||
--glass-bg: rgba(255, 255, 255, 0.05);
|
||||
--glass-bg-hover: rgba(255, 255, 255, 0.1);
|
||||
--glass-border: rgba(255, 255, 255, 0.08);
|
||||
--glass-blur: 24px;
|
||||
--glass-bg: rgba(255, 255, 255, 0.05);
|
||||
--glass-bg-hover: rgba(255, 255, 255, 0.1);
|
||||
--glass-border: rgba(255, 255, 255, 0.08);
|
||||
--glass-blur: 24px;
|
||||
|
||||
/* ============================================
|
||||
/* ============================================
|
||||
EN: Extended Shadows & Effects
|
||||
VI: Shadows & Effects mở rộng
|
||||
============================================ */
|
||||
|
||||
--shadow-brand: 0 20px 50px rgba(59, 130, 246, 0.15);
|
||||
--shadow-brand-lg: 0 30px 70px rgba(59, 130, 246, 0.25);
|
||||
--shadow-colored: 0 10px 40px rgba(59, 130, 246, 0.3);
|
||||
--shadow-brand: 0 20px 50px rgba(59, 130, 246, 0.15);
|
||||
--shadow-brand-lg: 0 30px 70px rgba(59, 130, 246, 0.25);
|
||||
--shadow-colored: 0 10px 40px rgba(59, 130, 246, 0.3);
|
||||
|
||||
/* ============================================
|
||||
/* ============================================
|
||||
EN: Light Mode Colors (Secondary Theme)
|
||||
VI: Màu sắc cho Light Mode (Theme phụ)
|
||||
============================================ */
|
||||
--bg-primary-light: #FFFFFF;
|
||||
--bg-secondary-light: #F8FAFC;
|
||||
--bg-tertiary-light: #F1F5F9;
|
||||
--text-primary-light: #0F172A;
|
||||
--text-secondary-light: #475569;
|
||||
--border-primary-light: #E2E8F0;
|
||||
--bg-primary-light: #FFFFFF;
|
||||
--bg-secondary-light: #FBFBFD;
|
||||
/* Apple Gray */
|
||||
--bg-tertiary-light: #F5F5F7;
|
||||
--text-primary-light: #1D1D1F;
|
||||
/* Apple Black */
|
||||
--text-secondary-light: #86868B;
|
||||
/* Apple Gray Text */
|
||||
--border-primary-light: #D2D2D7;
|
||||
|
||||
/* ============================================
|
||||
/* ============================================
|
||||
EN: Typography
|
||||
VI: Kiểu chữ
|
||||
============================================ */
|
||||
|
||||
/* Font Stack / Bộ font */
|
||||
--font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
||||
--font-mono: "JetBrains Mono", "SF Mono", Consolas, "Liberation Mono", Menlo, monospace;
|
||||
/* Font Stack / Bộ font */
|
||||
--font-sans: var(--font-inter), -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
||||
--font-mono: "JetBrains Mono", "SF Mono", Consolas, "Liberation Mono", Menlo, monospace;
|
||||
|
||||
/* Display Font - For hero titles (48px+) */
|
||||
--font-display: "Inter Display", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
||||
/* Display Font - For hero titles (48px+) */
|
||||
--font-display: var(--font-inter), -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
||||
|
||||
/* Heading Font - For section headings (24-36px) */
|
||||
--font-heading: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
||||
/* Heading Font - For section headings (24-36px) */
|
||||
--font-heading: var(--font-inter), -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
||||
|
||||
/* Type Scale / Kích thước chữ */
|
||||
--text-6xl: 3.75rem;
|
||||
/* 60px - Hero titles */
|
||||
--text-5xl: 3rem;
|
||||
/* 48px - Page titles */
|
||||
--text-4xl: 2.25rem;
|
||||
/* 36px - Section headers */
|
||||
--text-3xl: 1.875rem;
|
||||
/* 30px - Card headers */
|
||||
--text-2xl: 1.5rem;
|
||||
/* 24px - Large body */
|
||||
--text-xl: 1.25rem;
|
||||
/* 20px - Emphasized text */
|
||||
--text-lg: 1.125rem;
|
||||
/* 18px - Large body */
|
||||
--text-base: 1rem;
|
||||
/* 16px - Default body */
|
||||
--text-sm: 0.875rem;
|
||||
/* 14px - Small text */
|
||||
--text-xs: 0.75rem;
|
||||
/* 12px - Captions */
|
||||
/* Type Scale / Kích thước chữ */
|
||||
--text-6xl: 3.75rem;
|
||||
/* 60px - Hero titles */
|
||||
--text-5xl: 3rem;
|
||||
/* 48px - Page titles */
|
||||
--text-4xl: 2.25rem;
|
||||
/* 36px - Section headers */
|
||||
--text-3xl: 1.875rem;
|
||||
/* 30px - Card headers */
|
||||
--text-2xl: 1.5rem;
|
||||
/* 24px - Large body */
|
||||
--text-xl: 1.25rem;
|
||||
/* 20px - Emphasized text */
|
||||
--text-lg: 1.125rem;
|
||||
/* 18px - Large body */
|
||||
--text-base: 1rem;
|
||||
/* 16px - Default body */
|
||||
--text-sm: 0.875rem;
|
||||
/* 14px - Small text */
|
||||
--text-xs: 0.75rem;
|
||||
/* 12px - Captions */
|
||||
|
||||
/* Line Heights / Chiều cao dòng */
|
||||
--leading-none: 1;
|
||||
--leading-tight: 1.1;
|
||||
--leading-snug: 1.2;
|
||||
--leading-normal: 1.5;
|
||||
--leading-relaxed: 1.625;
|
||||
--leading-loose: 2;
|
||||
/* Line Heights / Chiều cao dòng */
|
||||
--leading-none: 1;
|
||||
--leading-tight: 1.1;
|
||||
--leading-snug: 1.2;
|
||||
--leading-normal: 1.5;
|
||||
--leading-relaxed: 1.625;
|
||||
--leading-loose: 2;
|
||||
|
||||
/* Font Weights / Độ đậm chữ */
|
||||
--font-light: 300;
|
||||
/* Light text */
|
||||
--font-normal: 400;
|
||||
/* Body text */
|
||||
--font-medium: 500;
|
||||
/* Emphasized */
|
||||
--font-semibold: 600;
|
||||
/* Headings */
|
||||
--font-bold: 700;
|
||||
/* Strong emphasis */
|
||||
/* Font Weights / Độ đậm chữ */
|
||||
--font-thin: 100;
|
||||
--font-extralight: 200;
|
||||
--font-light: 300;
|
||||
/* Light text */
|
||||
--font-normal: 400;
|
||||
/* Body text */
|
||||
--font-medium: 500;
|
||||
/* Emphasized */
|
||||
--font-semibold: 600;
|
||||
/* Headings */
|
||||
--font-bold: 700;
|
||||
/* Strong emphasis */
|
||||
|
||||
/* ============================================
|
||||
/* ============================================
|
||||
EN: Spacing & Layout
|
||||
VI: Khoảng cách & Bố cục
|
||||
============================================ */
|
||||
|
||||
/* Base Unit: 4px (0.25rem) / Đơn vị cơ sở: 4px (0.25rem) */
|
||||
--space-0: 0;
|
||||
--space-1: 0.25rem;
|
||||
/* 4px */
|
||||
--space-2: 0.5rem;
|
||||
/* 8px */
|
||||
--space-3: 0.75rem;
|
||||
/* 12px */
|
||||
--space-4: 1rem;
|
||||
/* 16px */
|
||||
--space-5: 1.25rem;
|
||||
/* 20px */
|
||||
--space-6: 1.5rem;
|
||||
/* 24px */
|
||||
--space-8: 2rem;
|
||||
/* 32px */
|
||||
--space-10: 2.5rem;
|
||||
/* 40px */
|
||||
--space-12: 3rem;
|
||||
/* 48px */
|
||||
--space-16: 4rem;
|
||||
/* 64px */
|
||||
--space-20: 5rem;
|
||||
/* 80px */
|
||||
/* Base Unit: 4px (0.25rem) / Đơn vị cơ sở: 4px (0.25rem) */
|
||||
--space-0: 0;
|
||||
--space-1: 0.25rem;
|
||||
/* 4px */
|
||||
--space-2: 0.5rem;
|
||||
/* 8px */
|
||||
--space-3: 0.75rem;
|
||||
/* 12px */
|
||||
--space-4: 1rem;
|
||||
/* 16px */
|
||||
--space-5: 1.25rem;
|
||||
/* 20px */
|
||||
--space-6: 1.5rem;
|
||||
/* 24px */
|
||||
--space-8: 2rem;
|
||||
/* 32px */
|
||||
--space-10: 2.5rem;
|
||||
/* 40px */
|
||||
--space-12: 3rem;
|
||||
/* 48px */
|
||||
--space-16: 4rem;
|
||||
/* 64px */
|
||||
--space-20: 5rem;
|
||||
/* 80px */
|
||||
|
||||
/* Container Widths / Chiều rộng container */
|
||||
--container-sm: 640px;
|
||||
/* Small devices */
|
||||
--container-md: 768px;
|
||||
/* Medium devices */
|
||||
--container-lg: 1024px;
|
||||
/* Large devices */
|
||||
--container-xl: 1280px;
|
||||
/* Extra large */
|
||||
--container-2xl: 1536px;
|
||||
/* 2X large */
|
||||
--chat-max-width: 800px;
|
||||
/* Max width for chat messages */
|
||||
--sidebar-width: 280px;
|
||||
/* Conversation history sidebar */
|
||||
/* Container Widths / Chiều rộng container */
|
||||
--container-sm: 640px;
|
||||
/* Small devices */
|
||||
--container-md: 768px;
|
||||
/* Medium devices */
|
||||
--container-lg: 1024px;
|
||||
/* Large devices */
|
||||
--container-xl: 1280px;
|
||||
/* Extra large */
|
||||
--container-2xl: 1536px;
|
||||
/* 2X large */
|
||||
--chat-max-width: 800px;
|
||||
/* Max width for chat messages */
|
||||
--sidebar-width: 280px;
|
||||
/* Conversation history sidebar */
|
||||
|
||||
/* Border Radius / Bo góc */
|
||||
--radius-sm: 2px;
|
||||
/* Small elements - sharp */
|
||||
--radius-md: 4px;
|
||||
/* Buttons, inputs - sharp */
|
||||
--radius-lg: 8px;
|
||||
/* Cards - minimal roundness */
|
||||
--radius-xl: 12px;
|
||||
/* Large cards */
|
||||
--radius-2xl: 16px;
|
||||
/* Modals */
|
||||
--radius-full: 9999px;
|
||||
/* Full round - Avatars, pills */
|
||||
/* Border Radius / Bo góc */
|
||||
--radius-sm: 2px;
|
||||
/* Small elements - sharp */
|
||||
--radius-md: 4px;
|
||||
/* Buttons, inputs - sharp */
|
||||
--radius-lg: 8px;
|
||||
/* Cards - minimal roundness */
|
||||
--radius-xl: 12px;
|
||||
/* Large cards */
|
||||
--radius-2xl: 16px;
|
||||
/* Modals */
|
||||
--radius-full: 9999px;
|
||||
/* Full round - Avatars, pills */
|
||||
|
||||
/* ============================================
|
||||
/* ============================================
|
||||
EN: Shadows (Dark Mode Optimized)
|
||||
VI: Đổ bóng (Tối ưu cho Dark Mode)
|
||||
============================================ */
|
||||
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.8);
|
||||
--shadow-md: 0 4px 6px rgba(0, 0, 0, 0.8);
|
||||
--shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.9);
|
||||
--shadow-xl: 0 20px 25px rgba(0, 0, 0, 0.95);
|
||||
--shadow-glow: 0 0 20px rgba(255, 255, 255, 0.1);
|
||||
/* White glow for focus */
|
||||
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.8);
|
||||
--shadow-md: 0 4px 6px rgba(0, 0, 0, 0.8);
|
||||
--shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.9);
|
||||
--shadow-xl: 0 20px 25px rgba(0, 0, 0, 0.95);
|
||||
--shadow-glow: 0 0 20px rgba(255, 255, 255, 0.1);
|
||||
/* White glow for focus */
|
||||
|
||||
/* ============================================
|
||||
/* ============================================
|
||||
EN: Grid System & Breakpoints
|
||||
VI: Hệ thống lưới & Điểm ngắt
|
||||
============================================ */
|
||||
--screen-sm: 640px;
|
||||
/* Mobile landscape */
|
||||
--screen-md: 768px;
|
||||
/* Tablet */
|
||||
--screen-lg: 1024px;
|
||||
/* Desktop */
|
||||
--screen-xl: 1280px;
|
||||
/* Large desktop */
|
||||
--screen-2xl: 1536px;
|
||||
/* Extra large desktop */
|
||||
--screen-sm: 640px;
|
||||
/* Mobile landscape */
|
||||
--screen-md: 768px;
|
||||
/* Tablet */
|
||||
--screen-lg: 1024px;
|
||||
/* Desktop */
|
||||
--screen-xl: 1280px;
|
||||
/* Large desktop */
|
||||
--screen-2xl: 1536px;
|
||||
/* Extra large desktop */
|
||||
|
||||
/* ============================================
|
||||
/* ============================================
|
||||
EN: Animation & Transitions
|
||||
VI: Animation & Chuyển tiếp
|
||||
============================================ */
|
||||
|
||||
/* Timing Functions / Hàm thời gian */
|
||||
--ease-in: cubic-bezier(0.4, 0, 1, 1);
|
||||
--ease-out: cubic-bezier(0, 0, 0.2, 1);
|
||||
--ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
|
||||
--ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
|
||||
/* Timing Functions / Hàm thời gian */
|
||||
--ease-in: cubic-bezier(0.4, 0, 1, 1);
|
||||
--ease-out: cubic-bezier(0, 0, 0.2, 1);
|
||||
--ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
|
||||
--ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
|
||||
|
||||
/* Duration / Thời lượng */
|
||||
--duration-fast: 150ms;
|
||||
/* Hover effects */
|
||||
--duration-normal: 250ms;
|
||||
/* Default transitions */
|
||||
--duration-slow: 350ms;
|
||||
/* Complex animations */
|
||||
--duration-slower: 500ms;
|
||||
/* Page transitions */
|
||||
/* Duration / Thời lượng */
|
||||
--duration-fast: 150ms;
|
||||
/* Hover effects */
|
||||
--duration-normal: 250ms;
|
||||
/* Default transitions */
|
||||
--duration-slow: 350ms;
|
||||
/* Complex animations */
|
||||
--duration-slower: 500ms;
|
||||
/* Page transitions */
|
||||
|
||||
/* ============================================
|
||||
/* ============================================
|
||||
EN: Advanced Motion Tokens
|
||||
VI: Token chuyển động nâng cao
|
||||
============================================ */
|
||||
|
||||
/* Motion Ease Functions - For micro-interactions */
|
||||
--motion-ease-bounce: cubic-bezier(0.68, -0.55, 0.265, 1.55);
|
||||
--motion-ease-elastic: cubic-bezier(0.68, -0.6, 0.32, 1.6);
|
||||
/* Motion Ease Functions - For micro-interactions */
|
||||
--motion-ease-bounce: cubic-bezier(0.68, -0.55, 0.265, 1.55);
|
||||
--motion-ease-elastic: cubic-bezier(0.68, -0.6, 0.32, 1.6);
|
||||
|
||||
/* Hover Scale - For interactive elements */
|
||||
--hover-scale-sm: 1.02;
|
||||
--hover-scale-md: 1.05;
|
||||
--hover-scale-lg: 1.1;
|
||||
/* Hover Scale - For interactive elements */
|
||||
--hover-scale-sm: 1.02;
|
||||
--hover-scale-md: 1.05;
|
||||
--hover-scale-lg: 1.1;
|
||||
|
||||
/* Active Scale - For pressed states */
|
||||
--active-scale: 0.98;
|
||||
/* Active Scale - For pressed states */
|
||||
--active-scale: 0.98;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
@@ -320,14 +325,14 @@
|
||||
VI: Ghi đè theme cho Light Mode
|
||||
============================================ */
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
--bg-primary: var(--bg-primary-light);
|
||||
--bg-secondary: var(--bg-secondary-light);
|
||||
--bg-tertiary: var(--bg-tertiary-light);
|
||||
--text-primary: var(--text-primary-light);
|
||||
--text-secondary: var(--text-secondary-light);
|
||||
--border-primary: var(--border-primary-light);
|
||||
}
|
||||
:root {
|
||||
--bg-primary: var(--bg-primary-light);
|
||||
--bg-secondary: var(--bg-secondary-light);
|
||||
--bg-tertiary: var(--bg-tertiary-light);
|
||||
--text-primary: var(--text-primary-light);
|
||||
--text-secondary: var(--text-secondary-light);
|
||||
--border-primary: var(--border-primary-light);
|
||||
}
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
@@ -336,16 +341,16 @@
|
||||
============================================ */
|
||||
[data-theme="dark"],
|
||||
.dark {
|
||||
--bg-primary: #000000;
|
||||
--bg-secondary: #0A0A0A;
|
||||
--bg-tertiary: #141414;
|
||||
--bg-elevated: #1A1A1A;
|
||||
--text-primary: #FFFFFF;
|
||||
--text-secondary: #B0B0B0;
|
||||
--text-tertiary: #808080;
|
||||
--text-muted: #505050;
|
||||
--border-primary: #222222;
|
||||
--border-secondary: #333333;
|
||||
--bg-primary: #000000;
|
||||
--bg-secondary: #0A0A0A;
|
||||
--bg-tertiary: #141414;
|
||||
--bg-elevated: #1A1A1A;
|
||||
--text-primary: #FFFFFF;
|
||||
--text-secondary: #B0B0B0;
|
||||
--text-tertiary: #808080;
|
||||
--text-muted: #505050;
|
||||
--border-primary: #222222;
|
||||
--border-secondary: #333333;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
@@ -354,10 +359,10 @@
|
||||
============================================ */
|
||||
[data-theme="light"],
|
||||
.light {
|
||||
--bg-primary: var(--bg-primary-light);
|
||||
--bg-secondary: var(--bg-secondary-light);
|
||||
--bg-tertiary: var(--bg-tertiary-light);
|
||||
--text-primary: var(--text-primary-light);
|
||||
--text-secondary: var(--text-secondary-light);
|
||||
--border-primary: var(--border-primary-light);
|
||||
--bg-primary: var(--bg-primary-light);
|
||||
--bg-secondary: var(--bg-secondary-light);
|
||||
--bg-tertiary: var(--bg-tertiary-light);
|
||||
--text-primary: var(--text-primary-light);
|
||||
--text-secondary: var(--text-secondary-light);
|
||||
--border-primary: var(--border-primary-light);
|
||||
}
|
||||
133
pnpm-lock.yaml
generated
133
pnpm-lock.yaml
generated
@@ -144,6 +144,15 @@ importers:
|
||||
'@radix-ui/react-dropdown-menu':
|
||||
specifier: ^2.0.6
|
||||
version: 2.1.16(@types/react-dom@18.3.7)(@types/react@18.3.27)(react-dom@18.3.1)(react@18.3.1)
|
||||
'@radix-ui/react-popover':
|
||||
specifier: ^1.1.15
|
||||
version: 1.1.15(@types/react-dom@18.3.7)(@types/react@18.3.27)(react-dom@18.3.1)(react@18.3.1)
|
||||
'@radix-ui/react-switch':
|
||||
specifier: ^1.2.6
|
||||
version: 1.2.6(@types/react-dom@18.3.7)(@types/react@18.3.27)(react-dom@18.3.1)(react@18.3.1)
|
||||
'@radix-ui/react-tooltip':
|
||||
specifier: ^1.2.8
|
||||
version: 1.2.8(@types/react-dom@18.3.7)(@types/react@18.3.27)(react-dom@18.3.1)(react@18.3.1)
|
||||
'@tanstack/react-query':
|
||||
specifier: ^5.17.0
|
||||
version: 5.90.16(react@18.3.1)
|
||||
@@ -4078,6 +4087,40 @@ packages:
|
||||
react-remove-scroll: 2.7.2(@types/react@18.3.27)(react@18.3.1)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-popover@1.1.15(@types/react-dom@18.3.7)(@types/react@18.3.27)(react-dom@18.3.1)(react@18.3.1):
|
||||
resolution: {integrity: sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
'@types/react-dom': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
'@types/react-dom':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@radix-ui/primitive': 1.1.3
|
||||
'@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.27)(react@18.3.1)
|
||||
'@radix-ui/react-context': 1.1.2(@types/react@18.3.27)(react@18.3.1)
|
||||
'@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@18.3.7)(@types/react@18.3.27)(react-dom@18.3.1)(react@18.3.1)
|
||||
'@radix-ui/react-focus-guards': 1.1.3(@types/react@18.3.27)(react@18.3.1)
|
||||
'@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@18.3.7)(@types/react@18.3.27)(react-dom@18.3.1)(react@18.3.1)
|
||||
'@radix-ui/react-id': 1.1.1(@types/react@18.3.27)(react@18.3.1)
|
||||
'@radix-ui/react-popper': 1.2.8(@types/react-dom@18.3.7)(@types/react@18.3.27)(react-dom@18.3.1)(react@18.3.1)
|
||||
'@radix-ui/react-portal': 1.1.9(@types/react-dom@18.3.7)(@types/react@18.3.27)(react-dom@18.3.1)(react@18.3.1)
|
||||
'@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.7)(@types/react@18.3.27)(react-dom@18.3.1)(react@18.3.1)
|
||||
'@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7)(@types/react@18.3.27)(react-dom@18.3.1)(react@18.3.1)
|
||||
'@radix-ui/react-slot': 1.2.3(@types/react@18.3.27)(react@18.3.1)
|
||||
'@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.27)(react@18.3.1)
|
||||
'@types/react': 18.3.27
|
||||
'@types/react-dom': 18.3.7(@types/react@18.3.27)
|
||||
aria-hidden: 1.2.6
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
react-remove-scroll: 2.7.2(@types/react@18.3.27)(react@18.3.1)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-popper@1.2.8(@types/react-dom@18.3.7)(@types/react@18.3.27)(react-dom@18.3.1)(react@18.3.1):
|
||||
resolution: {integrity: sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==}
|
||||
peerDependencies:
|
||||
@@ -4245,6 +4288,32 @@ packages:
|
||||
react: 18.3.1
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-switch@1.2.6(@types/react-dom@18.3.7)(@types/react@18.3.27)(react-dom@18.3.1)(react@18.3.1):
|
||||
resolution: {integrity: sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
'@types/react-dom': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
'@types/react-dom':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@radix-ui/primitive': 1.1.3
|
||||
'@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.27)(react@18.3.1)
|
||||
'@radix-ui/react-context': 1.1.2(@types/react@18.3.27)(react@18.3.1)
|
||||
'@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7)(@types/react@18.3.27)(react-dom@18.3.1)(react@18.3.1)
|
||||
'@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.27)(react@18.3.1)
|
||||
'@radix-ui/react-use-previous': 1.1.1(@types/react@18.3.27)(react@18.3.1)
|
||||
'@radix-ui/react-use-size': 1.1.1(@types/react@18.3.27)(react@18.3.1)
|
||||
'@types/react': 18.3.27
|
||||
'@types/react-dom': 18.3.7(@types/react@18.3.27)
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-tabs@1.1.13(@types/react-dom@18.3.7)(@types/react@18.3.27)(react-dom@18.3.1)(react@18.3.1):
|
||||
resolution: {integrity: sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A==}
|
||||
peerDependencies:
|
||||
@@ -4272,6 +4341,37 @@ packages:
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-tooltip@1.2.8(@types/react-dom@18.3.7)(@types/react@18.3.27)(react-dom@18.3.1)(react@18.3.1):
|
||||
resolution: {integrity: sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
'@types/react-dom': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
'@types/react-dom':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@radix-ui/primitive': 1.1.3
|
||||
'@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.27)(react@18.3.1)
|
||||
'@radix-ui/react-context': 1.1.2(@types/react@18.3.27)(react@18.3.1)
|
||||
'@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@18.3.7)(@types/react@18.3.27)(react-dom@18.3.1)(react@18.3.1)
|
||||
'@radix-ui/react-id': 1.1.1(@types/react@18.3.27)(react@18.3.1)
|
||||
'@radix-ui/react-popper': 1.2.8(@types/react-dom@18.3.7)(@types/react@18.3.27)(react-dom@18.3.1)(react@18.3.1)
|
||||
'@radix-ui/react-portal': 1.1.9(@types/react-dom@18.3.7)(@types/react@18.3.27)(react-dom@18.3.1)(react@18.3.1)
|
||||
'@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.7)(@types/react@18.3.27)(react-dom@18.3.1)(react@18.3.1)
|
||||
'@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7)(@types/react@18.3.27)(react-dom@18.3.1)(react@18.3.1)
|
||||
'@radix-ui/react-slot': 1.2.3(@types/react@18.3.27)(react@18.3.1)
|
||||
'@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.27)(react@18.3.1)
|
||||
'@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@18.3.7)(@types/react@18.3.27)(react-dom@18.3.1)(react@18.3.1)
|
||||
'@types/react': 18.3.27
|
||||
'@types/react-dom': 18.3.7(@types/react@18.3.27)
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-use-callback-ref@1.1.1(@types/react@18.3.27)(react@18.3.1):
|
||||
resolution: {integrity: sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==}
|
||||
peerDependencies:
|
||||
@@ -4355,6 +4455,19 @@ packages:
|
||||
react: 18.3.1
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-use-previous@1.1.1(@types/react@18.3.27)(react@18.3.1):
|
||||
resolution: {integrity: sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@types/react': 18.3.27
|
||||
react: 18.3.1
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-use-rect@1.1.1(@types/react@18.3.27)(react@18.3.1):
|
||||
resolution: {integrity: sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==}
|
||||
peerDependencies:
|
||||
@@ -4383,6 +4496,26 @@ packages:
|
||||
react: 18.3.1
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-visually-hidden@1.2.3(@types/react-dom@18.3.7)(@types/react@18.3.27)(react-dom@18.3.1)(react@18.3.1):
|
||||
resolution: {integrity: sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
'@types/react-dom': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
'@types/react-dom':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7)(@types/react@18.3.27)(react-dom@18.3.1)(react@18.3.1)
|
||||
'@types/react': 18.3.27
|
||||
'@types/react-dom': 18.3.7(@types/react@18.3.27)
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/rect@1.1.1:
|
||||
resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==}
|
||||
dev: false
|
||||
|
||||
Reference in New Issue
Block a user