diff --git a/.changeset/lemon-yaks-show.md b/.changeset/lemon-yaks-show.md new file mode 100644 index 000000000..3c3460da9 --- /dev/null +++ b/.changeset/lemon-yaks-show.md @@ -0,0 +1,25 @@ +--- +'@tszhong0411/utils': minor +'@tszhong0411/ui': minor +--- + +- Updated the image in aspect ratio demo +- Updated to latest styles of shadcn/ui +- Updated to `cva` beta +- Updated introduction in docs +- Updated code style from `? : null` to `&& ` +- Updated to use oklch colors. +- Updated to divide long tailwindcss classes into multiple lines +- Added `oklab` and `oklch` to known word list. +- Added Ark UI badges +- Added `Chart`, `Calendar` +- Replaced `` with `` +- Replaced `` with `sr-only` +- Removed `` and `` +- Removed unnecessary `size-4` classes. +- Removed `` which is using `@ark-ui/react` +- Removed `` which is using `@ark-ui/react` +- Removed `` which is using `@ark-ui/react` +- Removed `` +- Renamed `toaster` to `sonner` +- Renamed `getAvatarAbbreviation()` to `getAbbreviation()` diff --git a/.cspell.json b/.cspell.json index 3ae035ddb..1434e1e18 100644 --- a/.cspell.json +++ b/.cspell.json @@ -11,6 +11,7 @@ "aceternity", "airpods", "anishde", + "beamer", "benoit", "bentogrids", "bradlc", @@ -60,6 +61,8 @@ "nums", "nuqs", "nuxt", + "oklab", + "oklch", "oliveira", "orbstack", "paralleldrive", diff --git a/apps/docs/next.config.ts b/apps/docs/next.config.ts index cf9541c04..329244e4a 100644 --- a/apps/docs/next.config.ts +++ b/apps/docs/next.config.ts @@ -44,8 +44,8 @@ const config: NextConfig = { async redirects() { return [ { - source: '/ui/components', - destination: '/ui/components/accordion', + source: '/ui', + destination: '/ui/accordion', permanent: true } ] diff --git a/apps/docs/package.json b/apps/docs/package.json index e74f6c1ab..22b82ce46 100644 --- a/apps/docs/package.json +++ b/apps/docs/package.json @@ -18,16 +18,17 @@ }, "dependencies": { "@hookform/resolvers": "^5.0.1", - "@tanstack/react-table": "^8.21.2", "@tszhong0411/ui": "workspace:*", "@tszhong0411/utils": "workspace:*", - "class-variance-authority": "^0.7.1", + "cva": "^1.0.0-beta.3", + "date-fns": "^4.1.0", "geist": "^1.3.1", "hast-util-to-jsx-runtime": "^2.3.6", "lucide-react": "^0.487.0", "next": "^15.3.0", "next-themes": "^0.4.6", "react": "^19.1.0", + "react-day-picker": "8.10.1", "react-dom": "^19.1.0", "react-hook-form": "^7.55.0", "recharts": "^2.15.2", diff --git a/apps/docs/src/app/(main)/[[...slug]]/link-badges.tsx b/apps/docs/src/app/(main)/[[...slug]]/link-badges.tsx index 637a9c920..e92e84510 100644 --- a/apps/docs/src/app/(main)/[[...slug]]/link-badges.tsx +++ b/apps/docs/src/app/(main)/[[...slug]]/link-badges.tsx @@ -11,18 +11,18 @@ const LinkBadges = (props: Doc['link'] = {}) => { return (
- {doc ? ( + {doc && ( Docs - ) : null} - {api ? ( + )} + {api && ( API Reference - ) : null} + )}
) } diff --git a/apps/docs/src/app/(main)/[[...slug]]/page.tsx b/apps/docs/src/app/(main)/[[...slug]]/page.tsx index 13970e8f0..fd5c8adce 100644 --- a/apps/docs/src/app/(main)/[[...slug]]/page.tsx +++ b/apps/docs/src/app/(main)/[[...slug]]/page.tsx @@ -85,7 +85,7 @@ const Page = async (props: PageProps) => {

{title}

{description}

- {hasLinks ? : null} + {hasLinks && }
diff --git a/apps/docs/src/components/demos/alert/alert.tsx b/apps/docs/src/components/demos/alert/alert.tsx new file mode 100644 index 000000000..21bfadb85 --- /dev/null +++ b/apps/docs/src/components/demos/alert/alert.tsx @@ -0,0 +1,14 @@ +import { Alert, AlertDescription, AlertTitle } from '@tszhong0411/ui' +import { CheckCircle2Icon } from 'lucide-react' + +const AlertDemo = () => { + return ( + + + Success! Your changes have been saved + This is an alert with icon, title and description. + + ) +} + +export default AlertDemo diff --git a/apps/docs/src/components/demos/alert/destructive.tsx b/apps/docs/src/components/demos/alert/destructive.tsx new file mode 100644 index 000000000..9e6cc454b --- /dev/null +++ b/apps/docs/src/components/demos/alert/destructive.tsx @@ -0,0 +1,14 @@ +import { Alert, AlertDescription, AlertTitle } from '@tszhong0411/ui' +import { AlertCircleIcon } from 'lucide-react' + +const AlertDestructiveDemo = () => { + return ( + + + Something went wrong! + Your session has expired. Please log in again. + + ) +} + +export default AlertDestructiveDemo diff --git a/apps/docs/src/components/demos/aspect-ratio/aspect-ratio.tsx b/apps/docs/src/components/demos/aspect-ratio/aspect-ratio.tsx index 932593462..2f5808883 100644 --- a/apps/docs/src/components/demos/aspect-ratio/aspect-ratio.tsx +++ b/apps/docs/src/components/demos/aspect-ratio/aspect-ratio.tsx @@ -5,9 +5,9 @@ const AspectRatioDemo = () => { return ( A smooth, minimalist white background with subtle diagonal light-gray gradients by Drew Beamer diff --git a/apps/docs/src/components/demos/blur-fade/blur-fade.tsx b/apps/docs/src/components/demos/blur-fade/blur-fade.tsx deleted file mode 100644 index 8902815e2..000000000 --- a/apps/docs/src/components/demos/blur-fade/blur-fade.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import { BlurFade } from '@tszhong0411/ui' - -const BlurFadeDemo = () => { - return ( -
- Hello, World! - This is a demo of the BlurFade component. -
- ) -} - -export default BlurFadeDemo diff --git a/apps/docs/src/components/demos/blur-image/blur-image.tsx b/apps/docs/src/components/demos/blur-image/blur-image.tsx deleted file mode 100644 index a606d0833..000000000 --- a/apps/docs/src/components/demos/blur-image/blur-image.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { BlurImage } from '@tszhong0411/ui' - -const BlurImageDemo = () => { - return ( - - ) -} - -export default BlurImageDemo diff --git a/apps/docs/src/components/demos/breadcrumb/breadcrumb.tsx b/apps/docs/src/components/demos/breadcrumb/breadcrumb.tsx index 3abe64b5f..1a9ca5696 100644 --- a/apps/docs/src/components/demos/breadcrumb/breadcrumb.tsx +++ b/apps/docs/src/components/demos/breadcrumb/breadcrumb.tsx @@ -34,7 +34,7 @@ const BreadcrumbDemo = () => { - Components + Components diff --git a/apps/docs/src/components/demos/button/icon.tsx b/apps/docs/src/components/demos/button/icon.tsx index fe91e671b..709b344ad 100644 --- a/apps/docs/src/components/demos/button/icon.tsx +++ b/apps/docs/src/components/demos/button/icon.tsx @@ -4,7 +4,7 @@ import { CopyIcon } from 'lucide-react' const ButtonIconDemo = () => { return ( ) } diff --git a/apps/docs/src/components/demos/button/pending.tsx b/apps/docs/src/components/demos/button/pending.tsx index bf10bee95..b7c1b69cd 100644 --- a/apps/docs/src/components/demos/button/pending.tsx +++ b/apps/docs/src/components/demos/button/pending.tsx @@ -1,7 +1,13 @@ import { Button } from '@tszhong0411/ui' +import { LoaderIcon } from 'lucide-react' const ButtonPendingDemo = () => { - return + return ( + + ) } export default ButtonPendingDemo diff --git a/apps/docs/src/components/demos/calendar/calendar.tsx b/apps/docs/src/components/demos/calendar/calendar.tsx new file mode 100644 index 000000000..d56d865e1 --- /dev/null +++ b/apps/docs/src/components/demos/calendar/calendar.tsx @@ -0,0 +1,19 @@ +'use client' + +import { Calendar } from '@tszhong0411/ui' +import { useState } from 'react' + +const CalendarDemo = () => { + const [date, setDate] = useState(() => new Date()) + + return ( + + ) +} + +export default CalendarDemo diff --git a/apps/docs/src/components/demos/calendar/range.tsx b/apps/docs/src/components/demos/calendar/range.tsx new file mode 100644 index 000000000..37b7972cf --- /dev/null +++ b/apps/docs/src/components/demos/calendar/range.tsx @@ -0,0 +1,42 @@ +'use client' + +import type { DateRange } from 'react-day-picker' + +import { Calendar } from '@tszhong0411/ui' +import { addDays } from 'date-fns' +import { useState } from 'react' + +const CalendarRangeDemo = () => { + const [dateRange, setDateRange] = useState(() => ({ + from: new Date(new Date().getFullYear(), 0, 12), + to: addDays(new Date(new Date().getFullYear(), 0, 12), 30) + })) + const [range, setRange] = useState(() => ({ + from: new Date(new Date().getFullYear(), 0, 12), + to: addDays(new Date(new Date().getFullYear(), 0, 12), 50) + })) + + return ( +
+ d > new Date() || d < new Date('1900-01-01')} + className='rounded-md border shadow-sm' + /> + +
+ ) +} + +export default CalendarRangeDemo diff --git a/apps/docs/src/components/demos/callout/callout.tsx b/apps/docs/src/components/demos/callout/callout.tsx deleted file mode 100644 index b945d151a..000000000 --- a/apps/docs/src/components/demos/callout/callout.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { Callout } from '@tszhong0411/ui' - -const CalloutDemo = () => { - return ( - - This is a callout. - - ) -} - -export default CalloutDemo diff --git a/apps/docs/src/components/demos/callout/error.tsx b/apps/docs/src/components/demos/callout/error.tsx deleted file mode 100644 index f7927a9e4..000000000 --- a/apps/docs/src/components/demos/callout/error.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { Callout } from '@tszhong0411/ui' - -const CalloutErrorDemo = () => { - return ( - - This is a error callout. - - ) -} - -export default CalloutErrorDemo diff --git a/apps/docs/src/components/demos/callout/warning.tsx b/apps/docs/src/components/demos/callout/warning.tsx deleted file mode 100644 index 95f2b9f07..000000000 --- a/apps/docs/src/components/demos/callout/warning.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { Callout } from '@tszhong0411/ui' - -const CalloutWarningDemo = () => { - return ( - - This is a warning callout. - - ) -} - -export default CalloutWarningDemo diff --git a/apps/docs/src/components/demos/chart/chart.tsx b/apps/docs/src/components/demos/chart/chart.tsx new file mode 100644 index 000000000..3e3759dea --- /dev/null +++ b/apps/docs/src/components/demos/chart/chart.tsx @@ -0,0 +1,88 @@ +'use client' + +import { + Card, + CardContent, + CardDescription, + CardFooter, + CardHeader, + CardTitle +} from '@tszhong0411/ui' +import { + type ChartConfig, + ChartContainer, + ChartTooltip, + ChartTooltipContent +} from '@tszhong0411/ui' +import { TrendingUpIcon } from 'lucide-react' +import { Area, AreaChart, CartesianGrid, XAxis } from 'recharts' + +const chartData = [ + { month: 'January', desktop: 186 }, + { month: 'February', desktop: 305 }, + { month: 'March', desktop: 237 }, + { month: 'April', desktop: 73 }, + { month: 'May', desktop: 209 }, + { month: 'June', desktop: 214 } +] + +const chartConfig = { + desktop: { + label: 'Desktop', + color: 'var(--chart-1)' + } +} satisfies ChartConfig + +const ChartDemo = () => { + return ( + + + Area Chart + Showing total visitors for the last 6 months + + + + + + value.slice(0, 3)} + /> + } /> + + + + + +
+
+
+ Trending up by 5.2% this month +
+
+ January - June 2024 +
+
+
+
+
+ ) +} + +export default ChartDemo diff --git a/apps/docs/src/components/demos/combobox/combobox.tsx b/apps/docs/src/components/demos/combobox/combobox.tsx index 883ffa0e8..443f73c39 100644 --- a/apps/docs/src/components/demos/combobox/combobox.tsx +++ b/apps/docs/src/components/demos/combobox/combobox.tsx @@ -1,26 +1,20 @@ 'use client' import { - type ComboboxInputValueChangeDetails, - ComboboxLabel, - ComboboxPortal, - ComboboxPositioner, - createListCollection -} from '@tszhong0411/ui' -import { - Combobox, - ComboboxContent, - ComboboxControl, - ComboboxInput, - ComboboxItem, - ComboboxItemGroup, - ComboboxItemGroupLabel, - ComboboxItemIndicator, - ComboboxItemText, - ComboboxTrigger + Button, + Command, + CommandEmpty, + CommandGroup, + CommandInput, + CommandItem, + CommandList, + Popover, + PopoverContent, + PopoverTrigger } from '@tszhong0411/ui' +import { cn } from '@tszhong0411/utils' import { CheckIcon, ChevronsUpDownIcon } from 'lucide-react' -import { useState } from 'react' +import { useId, useState } from 'react' const frameworks = [ { @@ -29,8 +23,7 @@ const frameworks = [ }, { value: 'sveltekit', - label: 'SvelteKit', - disabled: true + label: 'SvelteKit' }, { value: 'nuxt.js', @@ -46,55 +39,56 @@ const frameworks = [ } ] -const initialCollection = createListCollection({ items: frameworks }) - const ComboboxDemo = () => { - const [collection, setCollection] = useState(initialCollection) - const handleInputChange = (details: ComboboxInputValueChangeDetails) => { - const filtered = frameworks.filter((item) => - item.label.toLowerCase().includes(details.inputValue.toLowerCase()) - ) - if (filtered.length > 0) setCollection(createListCollection({ items: filtered })) - } - - const handleOpenChange = () => { - setCollection(initialCollection) - } + const [open, setOpen] = useState(false) + const [value, setValue] = useState('') + const id = useId() return ( - - Framework - - - - - - - - - - - Frameworks - {collection.items.map((item) => ( - - - - - - - {item.label} - + + + + + + + + + No framework found. + + {frameworks.map((framework) => ( + { + setValue(currentValue === value ? '' : currentValue) + setOpen(false) + }} + > + {framework.label} + + ))} - - - - - + + + + + ) } diff --git a/apps/docs/src/components/demos/command/command.tsx b/apps/docs/src/components/demos/command/command.tsx index b94af8f8b..6522e5c57 100644 --- a/apps/docs/src/components/demos/command/command.tsx +++ b/apps/docs/src/components/demos/command/command.tsx @@ -1,15 +1,12 @@ import { Command, CommandEmpty, - CommandFooter, - CommandFooterTrigger, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, - Kbd, - Logo + CommandShortcut } from '@tszhong0411/ui' import { CalculatorIcon, @@ -45,26 +42,20 @@ const CommandDemo = () => { Profile - P + ⌘ P Billing - B + ⌘ B Settings - S + ⌘ S - - - }> - Open Command - - ) } diff --git a/apps/docs/src/components/demos/data-table/data-table.tsx b/apps/docs/src/components/demos/data-table/data-table.tsx deleted file mode 100644 index 90f0000f9..000000000 --- a/apps/docs/src/components/demos/data-table/data-table.tsx +++ /dev/null @@ -1,997 +0,0 @@ -'use client' - -import { - type ColumnDef, - getCoreRowModel, - getFilteredRowModel, - getPaginationRowModel, - getSortedRowModel, - useReactTable -} from '@tanstack/react-table' -import { - Badge, - Button, - Checkbox, - DataTable, - DataTableColumnHeader, - type DataTableFilterField, - DataTableToolbar, - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuRadioGroup, - DropdownMenuRadioItem, - DropdownMenuSeparator, - DropdownMenuShortcut, - DropdownMenuSub, - DropdownMenuSubContent, - DropdownMenuSubTrigger, - DropdownMenuTrigger -} from '@tszhong0411/ui' -import { - ArrowDownIcon, - ArrowRightIcon, - ArrowUpIcon, - CheckCircleIcon, - CircleIcon, - CircleOffIcon, - HelpCircleIcon, - MoreHorizontalIcon, - TimerIcon -} from 'lucide-react' - -type Task = { - id: string - title: string - status: string - label: string - priority: string -} - -const data: Task[] = [ - { - id: 'TASK-8782', - title: "You can't compress the program without quantifying the open-source SSD pixel!", - status: 'in progress', - label: 'documentation', - priority: 'medium' - }, - { - id: 'TASK-7878', - title: 'Try to calculate the EXE feed, maybe it will index the multi-byte pixel!', - status: 'backlog', - label: 'documentation', - priority: 'medium' - }, - { - id: 'TASK-7839', - title: 'We need to bypass the neural TCP card!', - status: 'todo', - label: 'bug', - priority: 'high' - }, - { - id: 'TASK-5562', - title: - 'The SAS interface is down, bypass the open-source pixel so we can back up the PNG bandwidth!', - status: 'backlog', - label: 'feature', - priority: 'medium' - }, - { - id: 'TASK-8686', - title: "I'll parse the wireless SSL protocol, that should driver the API panel!", - status: 'canceled', - label: 'feature', - priority: 'medium' - }, - { - id: 'TASK-1280', - title: 'Use the digital TLS panel, then you can transmit the haptic system!', - status: 'done', - label: 'bug', - priority: 'high' - }, - { - id: 'TASK-7262', - title: - 'The UTF8 application is down, parse the neural bandwidth so we can back up the PNG firewall!', - status: 'done', - label: 'feature', - priority: 'high' - }, - { - id: 'TASK-1138', - title: "Generating the driver won't do anything, we need to quantify the 1080p SMTP bandwidth!", - status: 'in progress', - label: 'feature', - priority: 'medium' - }, - { - id: 'TASK-7184', - title: 'We need to program the back-end THX pixel!', - status: 'todo', - label: 'feature', - priority: 'low' - }, - { - id: 'TASK-5160', - title: "Calculating the bus won't do anything, we need to navigate the back-end JSON protocol!", - status: 'in progress', - label: 'documentation', - priority: 'high' - }, - { - id: 'TASK-5618', - title: "Generating the driver won't do anything, we need to index the online SSL application!", - status: 'done', - label: 'documentation', - priority: 'medium' - }, - { - id: 'TASK-6699', - title: - 'If we index the program, we can get to the IB interface through the bluetooth JSON bus!', - status: 'backlog', - label: 'documentation', - priority: 'medium' - }, - { - id: 'TASK-2858', - title: 'We need to override the online UDP bus!', - status: 'backlog', - label: 'bug', - priority: 'medium' - }, - { - id: 'TASK-9864', - title: "I'll reboot the 1080p FTP panel, that should matrix the HEX hard drive!", - status: 'done', - label: 'bug', - priority: 'high' - }, - { - id: 'TASK-8404', - title: 'We need to generate the virtual HEX alarm!', - status: 'in progress', - label: 'bug', - priority: 'low' - }, - { - id: 'TASK-5365', - title: "Backing up the pixel won't do anything, we need to transmit the primary IB array!", - status: 'in progress', - label: 'documentation', - priority: 'low' - }, - { - id: 'TASK-1780', - title: - 'The CSS feed is down, index the bluetooth transmitter so we can compress the CLI protocol!', - status: 'todo', - label: 'documentation', - priority: 'high' - }, - { - id: 'TASK-6938', - title: 'Use the redundant SCSI application, then you can hack the optical alarm!', - status: 'todo', - label: 'documentation', - priority: 'high' - }, - { - id: 'TASK-9885', - title: 'We need to compress the auxiliary VGA driver!', - status: 'backlog', - label: 'bug', - priority: 'high' - }, - { - id: 'TASK-3216', - title: - "Transmitting the transmitter won't do anything, we need to compress the virtual HDD sensor!", - status: 'backlog', - label: 'documentation', - priority: 'medium' - }, - { - id: 'TASK-9285', - title: 'The IP monitor is down, copy the haptic alarm so we can generate the HTTP transmitter!', - status: 'todo', - label: 'bug', - priority: 'high' - }, - { - id: 'TASK-1024', - title: - "Overriding the microchip won't do anything, we need to transmit the digital OCR transmitter!", - status: 'in progress', - label: 'documentation', - priority: 'low' - }, - { - id: 'TASK-7068', - title: "You can't generate the capacitor without indexing the wireless HEX pixel!", - status: 'canceled', - label: 'bug', - priority: 'low' - }, - { - id: 'TASK-6502', - title: "Navigating the microchip won't do anything, we need to bypass the back-end SQL bus!", - status: 'todo', - label: 'bug', - priority: 'high' - }, - { - id: 'TASK-5326', - title: 'We need to hack the redundant UTF8 transmitter!', - status: 'todo', - label: 'bug', - priority: 'low' - }, - { - id: 'TASK-6274', - title: 'Use the virtual PCI circuit, then you can parse the bluetooth alarm!', - status: 'canceled', - label: 'documentation', - priority: 'low' - }, - { - id: 'TASK-1571', - title: "I'll input the neural DRAM circuit, that should protocol the SMTP interface!", - status: 'in progress', - label: 'feature', - priority: 'medium' - }, - { - id: 'TASK-9518', - title: - "Compressing the interface won't do anything, we need to compress the online SDD matrix!", - status: 'canceled', - label: 'documentation', - priority: 'medium' - }, - { - id: 'TASK-5581', - title: "I'll synthesize the digital COM pixel, that should transmitter the UTF8 protocol!", - status: 'backlog', - label: 'documentation', - priority: 'high' - }, - { - id: 'TASK-2197', - title: "Parsing the feed won't do anything, we need to copy the bluetooth DRAM bus!", - status: 'todo', - label: 'documentation', - priority: 'low' - }, - { - id: 'TASK-8484', - title: 'We need to parse the solid state UDP firewall!', - status: 'in progress', - label: 'bug', - priority: 'low' - }, - { - id: 'TASK-9892', - title: - 'If we back up the application, we can get to the UDP application through the multi-byte THX capacitor!', - status: 'done', - label: 'documentation', - priority: 'high' - }, - { - id: 'TASK-9616', - title: 'We need to synthesize the cross-platform ASCII pixel!', - status: 'in progress', - label: 'feature', - priority: 'medium' - }, - { - id: 'TASK-9744', - title: 'Use the back-end IP card, then you can input the solid state hard drive!', - status: 'done', - label: 'documentation', - priority: 'low' - }, - { - id: 'TASK-1376', - title: "Generating the alarm won't do anything, we need to generate the mobile IP capacitor!", - status: 'backlog', - label: 'documentation', - priority: 'low' - }, - { - id: 'TASK-7382', - title: - 'If we back up the firewall, we can get to the RAM alarm through the primary UTF8 pixel!', - status: 'todo', - label: 'feature', - priority: 'low' - }, - { - id: 'TASK-2290', - title: "I'll compress the virtual JSON panel, that should application the UTF8 bus!", - status: 'canceled', - label: 'documentation', - priority: 'high' - }, - { - id: 'TASK-1533', - title: "You can't input the firewall without overriding the wireless TCP firewall!", - status: 'done', - label: 'bug', - priority: 'high' - }, - { - id: 'TASK-4920', - title: - "Bypassing the hard drive won't do anything, we need to input the bluetooth JSON program!", - status: 'in progress', - label: 'bug', - priority: 'high' - }, - { - id: 'TASK-5168', - title: 'If we synthesize the bus, we can get to the IP panel through the virtual TLS array!', - status: 'in progress', - label: 'feature', - priority: 'low' - }, - { - id: 'TASK-7103', - title: 'We need to parse the multi-byte EXE bandwidth!', - status: 'canceled', - label: 'feature', - priority: 'low' - }, - { - id: 'TASK-4314', - title: - 'If we compress the program, we can get to the XML alarm through the multi-byte COM matrix!', - status: 'in progress', - label: 'bug', - priority: 'high' - }, - { - id: 'TASK-3415', - title: 'Use the cross-platform XML application, then you can quantify the solid state feed!', - status: 'todo', - label: 'feature', - priority: 'high' - }, - { - id: 'TASK-8339', - title: 'Try to calculate the DNS interface, maybe it will input the bluetooth capacitor!', - status: 'in progress', - label: 'feature', - priority: 'low' - }, - { - id: 'TASK-6995', - title: 'Try to hack the XSS bandwidth, maybe it will override the bluetooth matrix!', - status: 'todo', - label: 'feature', - priority: 'high' - }, - { - id: 'TASK-8053', - title: - 'If we connect the program, we can get to the UTF8 matrix through the digital UDP protocol!', - status: 'todo', - label: 'feature', - priority: 'medium' - }, - { - id: 'TASK-4336', - title: - 'If we synthesize the microchip, we can get to the SAS sensor through the optical UDP program!', - status: 'todo', - label: 'documentation', - priority: 'low' - }, - { - id: 'TASK-8790', - title: "I'll back up the optical COM alarm, that should alarm the RSS capacitor!", - status: 'done', - label: 'bug', - priority: 'medium' - }, - { - id: 'TASK-8980', - title: 'Try to navigate the SQL transmitter, maybe it will back up the virtual firewall!', - status: 'canceled', - label: 'bug', - priority: 'low' - }, - { - id: 'TASK-7342', - title: 'Use the neural CLI card, then you can parse the online port!', - status: 'backlog', - label: 'documentation', - priority: 'low' - }, - { - id: 'TASK-5608', - title: "I'll hack the haptic SSL program, that should bus the UDP transmitter!", - status: 'canceled', - label: 'documentation', - priority: 'low' - }, - { - id: 'TASK-1606', - title: "I'll generate the bluetooth PNG firewall, that should pixel the SSL driver!", - status: 'done', - label: 'feature', - priority: 'medium' - }, - { - id: 'TASK-7872', - title: "Transmitting the circuit won't do anything, we need to reboot the 1080p RSS monitor!", - status: 'canceled', - label: 'feature', - priority: 'medium' - }, - { - id: 'TASK-4167', - title: 'Use the cross-platform SMS circuit, then you can synthesize the optical feed!', - status: 'canceled', - label: 'bug', - priority: 'medium' - }, - { - id: 'TASK-9581', - title: "You can't index the port without hacking the cross-platform XSS monitor!", - status: 'backlog', - label: 'documentation', - priority: 'low' - }, - { - id: 'TASK-8806', - title: 'We need to bypass the back-end SSL panel!', - status: 'done', - label: 'bug', - priority: 'medium' - }, - { - id: 'TASK-6542', - title: 'Try to quantify the RSS firewall, maybe it will quantify the open-source system!', - status: 'done', - label: 'feature', - priority: 'low' - }, - { - id: 'TASK-6806', - title: 'The VGA protocol is down, reboot the back-end matrix so we can parse the CSS panel!', - status: 'canceled', - label: 'documentation', - priority: 'low' - }, - { - id: 'TASK-9549', - title: 'Use the 1080p UDP hard drive, then you can bypass the back-end program!', - status: 'todo', - label: 'feature', - priority: 'high' - }, - { - id: 'TASK-1075', - title: "Backing up the driver won't do anything, we need to parse the redundant RAM pixel!", - status: 'done', - label: 'feature', - priority: 'medium' - }, - { - id: 'TASK-1427', - title: 'Use the auxiliary PCI circuit, then you can calculate the cross-platform interface!', - status: 'done', - label: 'documentation', - priority: 'high' - }, - { - id: 'TASK-1907', - title: "Hacking the circuit won't do anything, we need to back up the online DRAM system!", - status: 'todo', - label: 'documentation', - priority: 'high' - }, - { - id: 'TASK-4309', - title: 'If we generate the system, we can get to the TCP sensor through the optical GB pixel!', - status: 'backlog', - label: 'bug', - priority: 'medium' - }, - { - id: 'TASK-3973', - title: "I'll parse the back-end ADP array, that should bandwidth the RSS bandwidth!", - status: 'todo', - label: 'feature', - priority: 'medium' - }, - { - id: 'TASK-7962', - title: 'Use the wireless RAM program, then you can hack the cross-platform feed!', - status: 'canceled', - label: 'bug', - priority: 'low' - }, - { - id: 'TASK-3360', - title: "You can't quantify the program without synthesizing the neural OCR interface!", - status: 'done', - label: 'feature', - priority: 'medium' - }, - { - id: 'TASK-9887', - title: 'Use the auxiliary ASCII sensor, then you can connect the solid state port!', - status: 'backlog', - label: 'bug', - priority: 'medium' - }, - { - id: 'TASK-3649', - title: "I'll input the virtual USB system, that should circuit the DNS monitor!", - status: 'in progress', - label: 'feature', - priority: 'medium' - }, - { - id: 'TASK-3586', - title: - 'If we quantify the circuit, we can get to the CLI feed through the mobile SMS hard drive!', - status: 'in progress', - label: 'bug', - priority: 'low' - }, - { - id: 'TASK-5150', - title: "I'll hack the wireless XSS port, that should transmitter the IP interface!", - status: 'canceled', - label: 'feature', - priority: 'medium' - }, - { - id: 'TASK-3652', - title: - 'The SQL interface is down, override the optical bus so we can program the ASCII interface!', - status: 'backlog', - label: 'feature', - priority: 'low' - }, - { - id: 'TASK-6884', - title: 'Use the digital PCI circuit, then you can synthesize the multi-byte microchip!', - status: 'canceled', - label: 'feature', - priority: 'high' - }, - { - id: 'TASK-1591', - title: 'We need to connect the mobile XSS driver!', - status: 'in progress', - label: 'feature', - priority: 'high' - }, - { - id: 'TASK-3802', - title: 'Try to override the ASCII protocol, maybe it will parse the virtual matrix!', - status: 'in progress', - label: 'feature', - priority: 'low' - }, - { - id: 'TASK-7253', - title: - "Programming the capacitor won't do anything, we need to bypass the neural IB hard drive!", - status: 'backlog', - label: 'bug', - priority: 'high' - }, - { - id: 'TASK-9739', - title: 'We need to hack the multi-byte HDD bus!', - status: 'done', - label: 'documentation', - priority: 'medium' - }, - { - id: 'TASK-4424', - title: 'Try to hack the HEX alarm, maybe it will connect the optical pixel!', - status: 'in progress', - label: 'documentation', - priority: 'medium' - }, - { - id: 'TASK-3922', - title: "You can't back up the capacitor without generating the wireless PCI program!", - status: 'backlog', - label: 'bug', - priority: 'low' - }, - { - id: 'TASK-4921', - title: "I'll index the open-source IP feed, that should system the GB application!", - status: 'canceled', - label: 'bug', - priority: 'low' - }, - { - id: 'TASK-5814', - title: 'We need to calculate the 1080p AGP feed!', - status: 'backlog', - label: 'bug', - priority: 'high' - }, - { - id: 'TASK-2645', - title: - "Synthesizing the system won't do anything, we need to navigate the multi-byte HDD firewall!", - status: 'todo', - label: 'documentation', - priority: 'medium' - }, - { - id: 'TASK-4535', - title: 'Try to copy the JSON circuit, maybe it will connect the wireless feed!', - status: 'in progress', - label: 'feature', - priority: 'low' - }, - { - id: 'TASK-4463', - title: 'We need to copy the solid state AGP monitor!', - status: 'done', - label: 'documentation', - priority: 'low' - }, - { - id: 'TASK-9745', - title: - 'If we connect the protocol, we can get to the GB system through the bluetooth PCI microchip!', - status: 'canceled', - label: 'feature', - priority: 'high' - }, - { - id: 'TASK-2080', - title: 'If we input the bus, we can get to the RAM matrix through the auxiliary RAM card!', - status: 'todo', - label: 'bug', - priority: 'medium' - }, - { - id: 'TASK-3838', - title: "I'll bypass the online TCP application, that should panel the AGP system!", - status: 'backlog', - label: 'bug', - priority: 'high' - }, - { - id: 'TASK-1340', - title: 'We need to navigate the virtual PNG circuit!', - status: 'todo', - label: 'bug', - priority: 'medium' - }, - { - id: 'TASK-6665', - title: - 'If we parse the monitor, we can get to the SSD hard drive through the cross-platform AGP alarm!', - status: 'canceled', - label: 'feature', - priority: 'low' - }, - { - id: 'TASK-7585', - title: - 'If we calculate the hard drive, we can get to the SSL program through the multi-byte CSS microchip!', - status: 'backlog', - label: 'feature', - priority: 'low' - }, - { - id: 'TASK-6319', - title: 'We need to copy the multi-byte SCSI program!', - status: 'backlog', - label: 'bug', - priority: 'high' - }, - { - id: 'TASK-4369', - title: 'Try to input the SCSI bus, maybe it will generate the 1080p pixel!', - status: 'backlog', - label: 'bug', - priority: 'high' - }, - { - id: 'TASK-9035', - title: 'We need to override the solid state PNG array!', - status: 'canceled', - label: 'documentation', - priority: 'low' - }, - { - id: 'TASK-3970', - title: "You can't index the transmitter without quantifying the haptic ASCII card!", - status: 'todo', - label: 'documentation', - priority: 'medium' - }, - { - id: 'TASK-4473', - title: "You can't bypass the protocol without overriding the neural RSS program!", - status: 'todo', - label: 'documentation', - priority: 'low' - }, - { - id: 'TASK-4136', - title: "You can't hack the hard drive without hacking the primary JSON program!", - status: 'canceled', - label: 'bug', - priority: 'medium' - }, - { - id: 'TASK-3939', - title: 'Use the back-end SQL firewall, then you can connect the neural hard drive!', - status: 'done', - label: 'feature', - priority: 'low' - }, - { - id: 'TASK-2007', - title: "I'll input the back-end USB protocol, that should bandwidth the PCI system!", - status: 'backlog', - label: 'bug', - priority: 'high' - }, - { - id: 'TASK-7516', - title: 'Use the primary SQL program, then you can generate the auxiliary transmitter!', - status: 'done', - label: 'documentation', - priority: 'medium' - }, - { - id: 'TASK-6906', - title: 'Try to back up the DRAM system, maybe it will reboot the online transmitter!', - status: 'done', - label: 'feature', - priority: 'high' - }, - { - id: 'TASK-5207', - title: 'The SMS interface is down, copy the bluetooth bus so we can quantify the VGA card!', - status: 'in progress', - label: 'bug', - priority: 'low' - } -] - -const labels = [ - { - value: 'bug', - label: 'Bug' - }, - { - value: 'feature', - label: 'Feature' - }, - { - value: 'documentation', - label: 'Documentation' - } -] - -const statuses = [ - { - value: 'backlog', - label: 'Backlog', - icon: HelpCircleIcon - }, - { - value: 'todo', - label: 'Todo', - icon: CircleIcon - }, - { - value: 'in progress', - label: 'In Progress', - icon: TimerIcon - }, - { - value: 'done', - label: 'Done', - icon: CheckCircleIcon - }, - { - value: 'canceled', - label: 'Canceled', - icon: CircleOffIcon - } -] - -const priorities = [ - { - label: 'Low', - value: 'low', - icon: ArrowDownIcon - }, - { - label: 'Medium', - value: 'medium', - icon: ArrowRightIcon - }, - { - label: 'High', - value: 'high', - icon: ArrowUpIcon - } -] - -const columns: Array> = [ - { - id: 'select', - header: ({ table }) => ( - { - table.toggleAllPageRowsSelected(!!value) - }} - aria-label='Select all' - className='translate-y-[2px]' - /> - ), - cell: ({ row }) => ( - { - row.toggleSelected(!!value) - }} - aria-label='Select row' - className='translate-y-[2px]' - /> - ), - enableSorting: false, - enableHiding: false - }, - { - accessorKey: 'id', - header: ({ column }) => , - cell: ({ row }) =>
{row.getValue('id')}
, - enableSorting: false, - enableHiding: false - }, - { - accessorKey: 'title', - header: ({ column }) => , - cell: ({ row }) => { - const label = labels.find((l) => l.value === row.original.label) - - return ( -
- {label && {label.label}} - {row.getValue('title')} -
- ) - } - }, - { - accessorKey: 'status', - header: ({ column }) => , - cell: ({ row }) => { - const status = statuses.find((s) => s.value === row.getValue('status')) - - if (!status) return null - - return ( -
- - {status.label} -
- ) - }, - filterFn: (row, id, value: string) => value.includes(row.getValue(id)) - }, - { - accessorKey: 'priority', - header: ({ column }) => , - cell: ({ row }) => { - const priority = priorities.find((p) => p.value === row.getValue('priority')) - - if (!priority) { - return null - } - - return ( -
- - {priority.label} -
- ) - }, - filterFn: (row, id, value: string) => value.includes(row.getValue(id)) - }, - { - id: 'actions', - cell: ({ row }) => ( - - - - - - Edit - Make a copy - Favorite - - - Labels - - - {labels.map((label) => ( - - {label.label} - - ))} - - - - - - Delete - ⌘⌫ - - - - ) - } -] - -const filterFields: Array> = [ - { - id: 'title', - label: 'Title', - placeholder: 'Filter titles...' - }, - { - id: 'status', - label: 'Status', - options: statuses - }, - { - id: 'priority', - label: 'Priority', - options: priorities - } -] - -const DataTableDemo = () => { - const table = useReactTable({ - data, - columns, - enableRowSelection: true, - getCoreRowModel: getCoreRowModel(), - getPaginationRowModel: getPaginationRowModel(), - getSortedRowModel: getSortedRowModel(), - getFilteredRowModel: getFilteredRowModel() - }) - - return ( - - - - ) -} - -export default DataTableDemo diff --git a/apps/docs/src/components/demos/drawer/drawer.tsx b/apps/docs/src/components/demos/drawer/drawer.tsx index 156d6f118..67fbf8c7b 100644 --- a/apps/docs/src/components/demos/drawer/drawer.tsx +++ b/apps/docs/src/components/demos/drawer/drawer.tsx @@ -109,7 +109,7 @@ const DrawerDemo = () => { dataKey='goal' style={ { - fill: 'hsl(var(--foreground))', + fill: 'var(--primary)', opacity: 0.9 } as React.CSSProperties } diff --git a/apps/docs/src/components/demos/dropdown-menu/dropdown-menu.tsx b/apps/docs/src/components/demos/dropdown-menu/dropdown-menu.tsx index d174f57e0..b50279425 100644 --- a/apps/docs/src/components/demos/dropdown-menu/dropdown-menu.tsx +++ b/apps/docs/src/components/demos/dropdown-menu/dropdown-menu.tsx @@ -40,22 +40,22 @@ const DropdownMenuDemo = () => { - + Profile ⇧⌘P - + Billing ⌘B - + Settings ⌘S - + Keyboard shortcuts ⌘K @@ -63,50 +63,50 @@ const DropdownMenuDemo = () => { - + Team - + Invite users - + Email - + Message - + More... - + New Team ⌘+T - + Support - + API - + Log out ⇧⌘Q diff --git a/apps/docs/src/components/demos/form/form.tsx b/apps/docs/src/components/demos/form/form.tsx index b893ba6a9..9d86302ff 100644 --- a/apps/docs/src/components/demos/form/form.tsx +++ b/apps/docs/src/components/demos/form/form.tsx @@ -35,7 +35,7 @@ const FormDemo = () => { return (
- + { - const [value, setValue] = useState('John Doe') - - return ( -
- { - setValue(e.target.value) - }} - placeholder='Enter a name...' - className='input' - /> -

- Abbreviation: {getAvatarAbbreviation(value)} -

-
- ) -} - -export default GetAvatarAbbreviationDemo diff --git a/apps/docs/src/components/demos/hover-card/hover-card.tsx b/apps/docs/src/components/demos/hover-card/hover-card.tsx index d8acce8f8..d95b7b43b 100644 --- a/apps/docs/src/components/demos/hover-card/hover-card.tsx +++ b/apps/docs/src/components/demos/hover-card/hover-card.tsx @@ -25,7 +25,7 @@ const HoverCardDemo = () => {

@nextjs

The React Framework – created and maintained by @vercel.

- {' '} + Joined December 2021
diff --git a/apps/docs/src/components/demos/kbd/kbd.tsx b/apps/docs/src/components/demos/kbd/kbd.tsx index fad47b7d3..2a5741b3a 100644 --- a/apps/docs/src/components/demos/kbd/kbd.tsx +++ b/apps/docs/src/components/demos/kbd/kbd.tsx @@ -3,9 +3,9 @@ import { Kbd } from '@tszhong0411/ui' const KbdDemo = () => { return (
- K - N - P + K + ⌘ ⇧ N + ⌥ ⌘ P
) } diff --git a/apps/docs/src/components/demos/link/link.tsx b/apps/docs/src/components/demos/link/link.tsx index 7f7976ee6..48d55c72a 100644 --- a/apps/docs/src/components/demos/link/link.tsx +++ b/apps/docs/src/components/demos/link/link.tsx @@ -1,7 +1,7 @@ import { Link } from '@tszhong0411/ui' const LinkDemo = () => { - return Link + return Link } export default LinkDemo diff --git a/apps/docs/src/components/demos/link/muted.tsx b/apps/docs/src/components/demos/link/muted.tsx index 725d15818..fe7d177a4 100644 --- a/apps/docs/src/components/demos/link/muted.tsx +++ b/apps/docs/src/components/demos/link/muted.tsx @@ -2,7 +2,7 @@ import { Link } from '@tszhong0411/ui' const LinkMutedDemo = () => { return ( - + Link ) diff --git a/apps/docs/src/components/demos/navigation-menu/navigation-menu.tsx b/apps/docs/src/components/demos/navigation-menu/navigation-menu.tsx index 01670d052..45bf2ffa9 100644 --- a/apps/docs/src/components/demos/navigation-menu/navigation-menu.tsx +++ b/apps/docs/src/components/demos/navigation-menu/navigation-menu.tsx @@ -16,35 +16,35 @@ import Link from 'next/link' const components: Array<{ title: string; href: string; description: string }> = [ { title: 'Alert Dialog', - href: '/ui/components/alert-dialog', + href: '/ui/alert-dialog', description: 'A modal dialog that interrupts the user with important content and expects a response.' }, { title: 'Hover Card', - href: '/ui/components/hover-card', + href: '/ui/hover-card', description: 'For sighted users to preview content available behind a link.' }, { title: 'Progress', - href: '/ui/components/progress', + href: '/ui/progress', description: 'Displays an indicator showing the completion progress of a task, typically displayed as a progress bar.' }, { title: 'Scroll-area', - href: '/ui/components/scroll-area', + href: '/ui/scroll-area', description: 'Visually or semantically separates content.' }, { title: 'Tabs', - href: '/ui/components/tabs', + href: '/ui/tabs', description: 'A set of layered sections of content—known as tab panels—that are displayed one at a time.' }, { title: 'Tooltip', - href: '/ui/components/tooltip', + href: '/ui/tooltip', description: 'A popup that displays information related to an element when the element receives keyboard focus or the mouse hovers over it.' } diff --git a/apps/docs/src/components/demos/progress/circular.tsx b/apps/docs/src/components/demos/progress/circular.tsx deleted file mode 100644 index 3e78f6d6b..000000000 --- a/apps/docs/src/components/demos/progress/circular.tsx +++ /dev/null @@ -1,33 +0,0 @@ -'use client' - -import { - Progress, - ProgressCircle, - ProgressCircleRange, - ProgressCircleTrack, - ProgressLabel, - ProgressValueText -} from '@tszhong0411/ui' -import { useEffect, useState } from 'react' - -const ProgressCircularDemo = () => { - const [progress, setProgress] = useState(13) - - useEffect(() => { - const timer = setTimeout(() => setProgress(66), 500) - - return () => clearTimeout(timer) - }, []) - return ( - - Label - - - - - - - ) -} - -export default ProgressCircularDemo diff --git a/apps/docs/src/components/demos/progress/progress.tsx b/apps/docs/src/components/demos/progress/progress.tsx index d6a0da337..e8bf018ad 100644 --- a/apps/docs/src/components/demos/progress/progress.tsx +++ b/apps/docs/src/components/demos/progress/progress.tsx @@ -1,6 +1,6 @@ 'use client' -import { Progress, ProgressRange, ProgressTrack, ProgressValueText } from '@tszhong0411/ui' +import { Progress } from '@tszhong0411/ui' import { useEffect, useState } from 'react' const ProgressDemo = () => { @@ -15,16 +15,7 @@ const ProgressDemo = () => { return () => clearInterval(interval) }, []) - return ( - - - - -
- -
-
- ) + return } export default ProgressDemo diff --git a/apps/docs/src/components/demos/progress/with-label.tsx b/apps/docs/src/components/demos/progress/with-label.tsx deleted file mode 100644 index 5bec90d53..000000000 --- a/apps/docs/src/components/demos/progress/with-label.tsx +++ /dev/null @@ -1,25 +0,0 @@ -'use client' - -import { Progress, ProgressLabel, ProgressRange, ProgressTrack } from '@tszhong0411/ui' -import { useEffect, useState } from 'react' - -const ProgressWithLabelDemo = () => { - const [progress, setProgress] = useState(13) - - useEffect(() => { - const timer = setTimeout(() => setProgress(66), 500) - - return () => clearTimeout(timer) - }, []) - - return ( - - Label - - - - - ) -} - -export default ProgressWithLabelDemo diff --git a/apps/docs/src/components/demos/progress/with-value.tsx b/apps/docs/src/components/demos/progress/with-value.tsx deleted file mode 100644 index 92c3fc098..000000000 --- a/apps/docs/src/components/demos/progress/with-value.tsx +++ /dev/null @@ -1,25 +0,0 @@ -'use client' - -import { Progress, ProgressRange, ProgressTrack, ProgressValueText } from '@tszhong0411/ui' -import { useEffect, useState } from 'react' - -const ProgressWithValueDemo = () => { - const [progress, setProgress] = useState(13) - - useEffect(() => { - const timer = setTimeout(() => setProgress(66), 500) - - return () => clearTimeout(timer) - }, []) - - return ( - - - - - - - ) -} - -export default ProgressWithValueDemo diff --git a/apps/docs/src/components/demos/sheet/sheet.tsx b/apps/docs/src/components/demos/sheet/sheet.tsx index cf6741aca..4879982d3 100644 --- a/apps/docs/src/components/demos/sheet/sheet.tsx +++ b/apps/docs/src/components/demos/sheet/sheet.tsx @@ -25,18 +25,14 @@ const SheetDemo = () => { Make changes to your profile here. Click save when you're done. -
-
- - +
+
+ +
-
- - +
+ +
diff --git a/apps/docs/src/components/demos/sidebar/components/team-switcher.tsx b/apps/docs/src/components/demos/sidebar/components/team-switcher.tsx index a25bb839e..3dc2bde98 100644 --- a/apps/docs/src/components/demos/sidebar/components/team-switcher.tsx +++ b/apps/docs/src/components/demos/sidebar/components/team-switcher.tsx @@ -89,7 +89,7 @@ const TeamSwitcher = () => { className='gap-2 p-2' >
- +
{team.name} ⌘{index + 1} @@ -98,7 +98,7 @@ const TeamSwitcher = () => {
- +
Add team
diff --git a/apps/docs/src/components/demos/slider/marker.tsx b/apps/docs/src/components/demos/slider/marker.tsx deleted file mode 100644 index 3ffa41263..000000000 --- a/apps/docs/src/components/demos/slider/marker.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import { - Slider, - SliderControl, - SliderMarker, - SliderMarkerGroup, - SliderRange, - SliderThumb, - SliderTrack -} from '@tszhong0411/ui' - -const SliderDemo = () => { - return ( - - - - - - - - - 25 - 50 - 75 - - - ) -} - -export default SliderDemo diff --git a/apps/docs/src/components/demos/slider/range.tsx b/apps/docs/src/components/demos/slider/range.tsx index 8dc4e2906..b897d94ae 100644 --- a/apps/docs/src/components/demos/slider/range.tsx +++ b/apps/docs/src/components/demos/slider/range.tsx @@ -1,25 +1,27 @@ -import { - Slider, - SliderControl, - SliderRange, - SliderThumb, - SliderTrack, - SliderValueText -} from '@tszhong0411/ui' +'use client' + +import { Label, Slider } from '@tszhong0411/ui' +import { useState } from 'react' + +const SliderRangeDemo = () => { + const [value, setValue] = useState([0.3, 0.7]) -const SliderDemo = () => { return ( - - - - - - - - - - +
+
+ + {value.join(', ')} +
+ +
) } -export default SliderDemo +export default SliderRangeDemo diff --git a/apps/docs/src/components/demos/slider/slider.tsx b/apps/docs/src/components/demos/slider/slider.tsx index 4f4eea5da..f5e4764f5 100644 --- a/apps/docs/src/components/demos/slider/slider.tsx +++ b/apps/docs/src/components/demos/slider/slider.tsx @@ -1,16 +1,7 @@ -import { Slider, SliderControl, SliderRange, SliderThumb, SliderTrack } from '@tszhong0411/ui' +import { Slider } from '@tszhong0411/ui' const SliderDemo = () => { - return ( - - - - - - - - - ) + return } export default SliderDemo diff --git a/apps/docs/src/components/demos/slider/with-label.tsx b/apps/docs/src/components/demos/slider/with-label.tsx deleted file mode 100644 index 460ee494b..000000000 --- a/apps/docs/src/components/demos/slider/with-label.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import { - Slider, - SliderControl, - SliderLabel, - SliderRange, - SliderThumb, - SliderTrack -} from '@tszhong0411/ui' - -const SliderWithLabelDemo = () => { - return ( - - Label - - - - - - - - ) -} - -export default SliderWithLabelDemo diff --git a/apps/docs/src/components/demos/slider/with-value.tsx b/apps/docs/src/components/demos/slider/with-value.tsx deleted file mode 100644 index 6aebc3e12..000000000 --- a/apps/docs/src/components/demos/slider/with-value.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import { - Slider, - SliderControl, - SliderRange, - SliderThumb, - SliderTrack, - SliderValueText -} from '@tszhong0411/ui' - -const SliderDemo = () => { - return ( - - - - - - - - - - ) -} - -export default SliderDemo diff --git a/apps/docs/src/components/demos/toaster/toaster.tsx b/apps/docs/src/components/demos/sonner/sonner.tsx similarity index 88% rename from apps/docs/src/components/demos/toaster/toaster.tsx rename to apps/docs/src/components/demos/sonner/sonner.tsx index 95e9ea1a5..c2c6de790 100644 --- a/apps/docs/src/components/demos/toaster/toaster.tsx +++ b/apps/docs/src/components/demos/sonner/sonner.tsx @@ -2,7 +2,7 @@ import { Button, toast } from '@tszhong0411/ui' -const ToasterDemo = () => { +const SonnerDemo = () => { return ( - - + + Navigation menu Navigation menu of the documentation site - - + + @tszhong0411/docs - + {SIDEBAR_LINKS.map((section) => (
{section.title}
@@ -46,12 +49,12 @@ const MobileNav = () => { { - router.push(link.href) - setIsOpen(false) - }} + onClick={closeSheet} > {link.text} + {'isArkUI' in link && link.isArkUI && ( + Ark UI + )} ))} diff --git a/apps/docs/src/components/layout/search.tsx b/apps/docs/src/components/layout/search.tsx index 12d493a5f..1264a6b6b 100644 --- a/apps/docs/src/components/layout/search.tsx +++ b/apps/docs/src/components/layout/search.tsx @@ -1,18 +1,15 @@ 'use client' import { + Badge, Button, CommandDialog, CommandEmpty, - CommandFooter, - CommandFooterTrigger, CommandGroup, CommandInput, CommandItem, CommandList, - CommandSeparator, - Kbd, - Logo + CommandSeparator } from '@tszhong0411/ui' import { cn } from '@tszhong0411/utils' import { ComponentIcon, MoonIcon, SearchIcon, SunIcon } from 'lucide-react' @@ -24,7 +21,6 @@ import { SIDEBAR_LINKS } from '@/config/links' const Search = () => { const [isOpen, setIsOpen] = useState(false) - const [value, setValue] = useState('') const { setTheme } = useTheme() const router = useRouter() @@ -46,8 +42,6 @@ const Search = () => { return () => document.removeEventListener('keydown', down) }, []) - const isSelectingTheme = value === 'Light' || value === 'Dark' - return ( <> - + No results found. @@ -87,6 +81,9 @@ const Search = () => { > {link.text} + {'isArkUI' in link && link.isArkUI && ( + Ark UI + )} ))} @@ -104,12 +101,6 @@ const Search = () => { - - - }> - {isSelectingTheme ? 'Switch Theme' : 'Open Link'} - - ) diff --git a/apps/docs/src/components/layout/sidebar.tsx b/apps/docs/src/components/layout/sidebar.tsx index 7c816a02d..69378643e 100644 --- a/apps/docs/src/components/layout/sidebar.tsx +++ b/apps/docs/src/components/layout/sidebar.tsx @@ -1,12 +1,13 @@ 'use client' -import { Link, ScrollArea } from '@tszhong0411/ui' -import { cva } from 'class-variance-authority' +import { Badge, Link, ScrollArea } from '@tszhong0411/ui' +import { cva } from 'cva' import { usePathname } from 'next/navigation' import { SIDEBAR_LINKS } from '../../config/links' -const sidebarLinkVariants = cva('block rounded-lg px-4 py-2', { +const sidebarLinkVariants = cva({ + base: 'block rounded-lg px-4 py-2', variants: { active: { true: 'bg-red-500/10 font-semibold text-red-500', @@ -34,6 +35,9 @@ const Sidebar = () => { })} > {link.text} + {'isArkUI' in link && link.isArkUI && ( + Ark UI + )} ))} diff --git a/apps/docs/src/components/mdx/component-preview-wrapper.tsx b/apps/docs/src/components/mdx/component-preview-wrapper.tsx index 2f6e0800a..c4fd3f5a3 100644 --- a/apps/docs/src/components/mdx/component-preview-wrapper.tsx +++ b/apps/docs/src/components/mdx/component-preview-wrapper.tsx @@ -27,7 +27,7 @@ const ComponentPreviewWrapper = (props: ComponentPreviewWrapperProps) => { onClick={() => setKey((prev) => prev + 1)} aria-label='Reload preview' > - +
{Component} diff --git a/apps/docs/src/components/mdx/mdx.tsx b/apps/docs/src/components/mdx/mdx.tsx index 2384587d2..23f05930c 100644 --- a/apps/docs/src/components/mdx/mdx.tsx +++ b/apps/docs/src/components/mdx/mdx.tsx @@ -1,6 +1,7 @@ import { useMDXComponent } from '@content-collections/mdx/react' -import * as uiComponents from '@tszhong0411/ui' +import { Alert, AlertDescription, AlertTitle, CodeBlock, Link } from '@tszhong0411/ui' import { cn } from '@tszhong0411/utils' +import { InfoIcon } from 'lucide-react' import ComponentPreview from './component-preview' import EmbedComponentPreview from './embed-component-preview' @@ -22,19 +23,30 @@ const components = { if (!href) throw new Error('Link must have an href') - return + // eslint-disable-next-line jsx-a11y/anchor-has-content -- it's a custom component + return }, // Custom components - ...uiComponents, - Callout: (props: React.ComponentProps) => ( - + Alert: (props: React.ComponentProps) => { + const { className, children, ...rest } = props + + return ( + + + {children} + + ) + }, + AlertTitle: (props: React.ComponentProps) => , + AlertDescription: (props: React.ComponentProps) => ( + ), ComponentPreview, EmbedComponentPreview, TreeView, - pre: uiComponents.CodeBlock + pre: CodeBlock } const Mdx = (props: MdxProps) => { diff --git a/apps/docs/src/config/links.ts b/apps/docs/src/config/links.ts index 1014780de..59a8821c3 100644 --- a/apps/docs/src/config/links.ts +++ b/apps/docs/src/config/links.ts @@ -3,11 +3,15 @@ type BaseLink = { text: string } +type ComponentLink = BaseLink & { + isArkUI?: boolean +} + type HeaderLinks = BaseLink[] type SidebarLinks = Array<{ title: string - links: BaseLink[] + links: Array }> export const HEADER_LINKS: HeaderLinks = [ @@ -19,220 +23,223 @@ export const HEADER_LINKS: HeaderLinks = [ const COMPONENT_LINKS = [ { - href: '/ui/components/accordion', + href: '/ui/accordion', text: 'Accordion' }, { - href: '/ui/components/alert-dialog', + href: '/ui/alert-dialog', text: 'Alert Dialog' }, { - href: '/ui/components/aspect-ratio', + href: '/ui/alert', + text: 'Alert' + }, + { + href: '/ui/aspect-ratio', text: 'Aspect Ratio' }, { - href: '/ui/components/avatar', + href: '/ui/avatar', text: 'Avatar' }, { - href: '/ui/components/badge', + href: '/ui/badge', text: 'Badge' }, { - href: '/ui/components/blur-fade', - text: 'Blur Fade' - }, - { - href: '/ui/components/blur-image', - text: 'Blur Image' - }, - { - href: '/ui/components/breadcrumb', + href: '/ui/breadcrumb', text: 'Breadcrumb' }, { - href: '/ui/components/button', + href: '/ui/button', text: 'Button' }, { - href: '/ui/components/callout', - text: 'Callout' + href: '/ui/calendar', + text: 'Calendar' }, { - href: '/ui/components/card', + href: '/ui/card', text: 'Card' }, { - href: '/ui/components/carousel', + href: '/ui/carousel', text: 'Carousel' }, { - href: '/ui/components/checkbox', + href: '/ui/chart', + text: 'Chart' + }, + { + href: '/ui/checkbox', text: 'Checkbox' }, { - href: '/ui/components/code-block', + href: '/ui/code-block', text: 'Code Block' }, { - href: '/ui/components/collapsible', + href: '/ui/collapsible', text: 'Collapsible' }, { - href: '/ui/components/combobox', + href: '/ui/combobox', text: 'Combobox' }, { - href: '/ui/components/command', + href: '/ui/command', text: 'Command' }, { - href: '/ui/components/context-menu', + href: '/ui/context-menu', text: 'Context Menu' }, { - href: '/ui/components/data-table', + href: '/ui/data-table', text: 'Data Table' }, { - href: '/ui/components/dialog', + href: '/ui/dialog', text: 'Dialog' }, { - href: '/ui/components/drawer', + href: '/ui/drawer', text: 'Drawer' }, { - href: '/ui/components/dropdown-menu', + href: '/ui/dropdown-menu', text: 'Dropdown Menu' }, { - href: '/ui/components/form', + href: '/ui/form', text: 'Form' }, { - href: '/ui/components/hover-card', + href: '/ui/hover-card', text: 'Hover Card' }, { - href: '/ui/components/input-otp', + href: '/ui/input-otp', text: 'Input OTP' }, { - href: '/ui/components/input', + href: '/ui/input', text: 'Input' }, { - href: '/ui/components/kbd', + href: '/ui/kbd', text: 'Kbd' }, { - href: '/ui/components/label', + href: '/ui/label', text: 'Label' }, { - href: '/ui/components/link', + href: '/ui/link', text: 'Link' }, { - href: '/ui/components/marquee', + href: '/ui/marquee', text: 'Marquee' }, { - href: '/ui/components/menubar', + href: '/ui/menubar', text: 'Menubar' }, { - href: '/ui/components/navigation-menu', + href: '/ui/navigation-menu', text: 'Navigation Menu' }, { - href: '/ui/components/pagination', - text: 'Pagination' + href: '/ui/pagination', + text: 'Pagination', + isArkUI: true }, { - href: '/ui/components/popover', + href: '/ui/popover', text: 'Popover' }, { - href: '/ui/components/progress', + href: '/ui/progress', text: 'Progress' }, { - href: '/ui/components/radio-group', + href: '/ui/radio-group', text: 'Radio Group' }, { - href: '/ui/components/resizable', + href: '/ui/resizable', text: 'Resizable' }, { - href: '/ui/components/scroll-area', + href: '/ui/scroll-area', text: 'Scroll Area' }, { - href: '/ui/components/segment-group', - text: 'Segment Group' + href: '/ui/segment-group', + text: 'Segment Group', + isArkUI: true }, { - href: '/ui/components/select', + href: '/ui/select', text: 'Select' }, { - href: '/ui/components/separator', + href: '/ui/separator', text: 'Separator' }, { - href: '/ui/components/sheet', + href: '/ui/sheet', text: 'Sheet' }, { - href: '/ui/components/sidebar', + href: '/ui/sidebar', text: 'Sidebar' }, { - href: '/ui/components/skeleton', + href: '/ui/skeleton', text: 'Skeleton' }, { - href: '/ui/components/slider', + href: '/ui/slider', text: 'Slider' }, { - href: '/ui/components/switch', + href: '/ui/sonner', + text: 'Sonner' + }, + { + href: '/ui/switch', text: 'Switch' }, { - href: '/ui/components/table', + href: '/ui/table', text: 'Table' }, { - href: '/ui/components/tabs', + href: '/ui/tabs', text: 'Tabs' }, { - href: '/ui/components/textarea', + href: '/ui/textarea', text: 'Textarea' }, { - href: '/ui/components/toaster', - text: 'Toaster' - }, - { - href: '/ui/components/toggle-group', + href: '/ui/toggle-group', text: 'Toggle Group' }, { - href: '/ui/components/toggle', + href: '/ui/toggle', text: 'Toggle' }, { - href: '/ui/components/tooltip', + href: '/ui/tooltip', text: 'Tooltip' }, { - href: '/ui/components/tree-view', - text: 'Tree View' + href: '/ui/tree-view', + text: 'Tree View', + isArkUI: true } ] @@ -243,6 +250,10 @@ export const SIDEBAR_LINKS: SidebarLinks = [ { href: '/', text: 'Introduction' + }, + { + href: '/getting-started/ui', + text: 'UI' } ] }, @@ -260,16 +271,28 @@ export const SIDEBAR_LINKS: SidebarLinks = [ ] }, { - title: 'UI / Components', - links: COMPONENT_LINKS - }, - { - title: 'UI / Utilities', + title: 'Utilities', links: [ { - href: '/ui/utilities/get-avatar-abbreviation', - text: 'getAvatarAbbreviation' + href: '/utilities/cn', + text: 'cn' + }, + { + href: '/utilities/get-abbreviation', + text: 'getAbbreviation' + }, + { + href: '/utilities/get-error-message', + text: 'getErrorMessage' + }, + { + href: '/utilities/range', + text: 'range' } ] + }, + { + title: 'UI / Components', + links: COMPONENT_LINKS } ] diff --git a/apps/docs/src/content/getting-started/ui.mdx b/apps/docs/src/content/getting-started/ui.mdx new file mode 100644 index 000000000..5abcde21f --- /dev/null +++ b/apps/docs/src/content/getting-started/ui.mdx @@ -0,0 +1,42 @@ +--- +title: UI +description: A collection of UI components. +--- + +## Prerequisites + +- React 19 +- Next.js 15 +- Tailwind CSS +- TypeScript + +## Installation + +```bash +npm i @tszhong0411/ui @tszhong0411/utils +# or +pnpm add @tszhong0411/ui @tszhong0411/utils +# or +yarn add @tszhong0411/ui @tszhong0411/utils +# or +bun add @tszhong0411/ui @tszhong0411/utils +``` + +```css title='globals.css' +@import 'tailwindcss'; +@import '@tszhong0411/ui/styles/preset.css'; +@import '@tszhong0411/ui/styles/shiki.css'; /* Optional */ +@import '@tszhong0411/ui/styles/typography.css'; /* Optional */ +/* Make sure it's pointing to the ROOT node_modules folder */ +@source '../../node_modules/@tszhong0411/ui/dist/**/*.js'; +``` + +## Usage + +```tsx +import { Button } from '@tszhong0411/ui' +``` + +```tsx + +``` diff --git a/apps/docs/src/content/index.mdx b/apps/docs/src/content/index.mdx index 01fc2e77c..039796e79 100644 --- a/apps/docs/src/content/index.mdx +++ b/apps/docs/src/content/index.mdx @@ -3,26 +3,16 @@ title: Introduction description: Welcome to the @tszhong0411/docs. --- -## UI - -`@tszhong0411/ui` is a modern component library built with [shadcn/ui](https://github.com/shadcn-ui/ui). It provides a collection of reusable, accessible and customizable components to streamline your web development workflow. +## Recipes -### Installation +I've collected some recipes that I've used in my projects. E.g. how to setup Drizzle and t3-env. -```bash -pnpm add @tszhong0411/ui -``` +## UI -### Usage +This is a collection of components that are built using the [shadcn/ui](https://ui.shadcn.com/) library. +The main difference between this and the original library is the code style. +I've changed to use arrow functions, and not to destructure the `props` in the function parameters. Write separate props type for each component. Long Tailwind CSS classes are divided into multiple lines for better readability. -```css -@import 'tailwindcss'; -@import '@tszhong0411/ui/styles/preset.css'; -@import '@tszhong0411/ui/styles/shiki.css'; /* Optional */ -@import '@tszhong0411/ui/styles/typography.css'; /* Optional */ -@source '../../node_modules/@tszhong0411/ui/dist/**/*.js'; -``` +Also, I've used [Ark UI](https://ark-ui.com/) for the components that are not yet available in the [shadcn/ui](https://ui.shadcn.com/)/[Radix UI](https://www.radix-ui.com/primitives) library. E.g. SegmentGroup and TreeView. -```tsx -import { Button } from '@tszhong0411/ui' -``` +Pagination is also rewritten using the [Ark UI](https://ark-ui.com/) library for better accessibility. diff --git a/apps/docs/src/content/recipes/drizzle.mdx b/apps/docs/src/content/recipes/drizzle.mdx index 8c3c8c377..6fade15c3 100644 --- a/apps/docs/src/content/recipes/drizzle.mdx +++ b/apps/docs/src/content/recipes/drizzle.mdx @@ -3,7 +3,12 @@ title: Drizzle description: Initialize Drizzle in your app --- -You may need to initialize the [`env.ts`](/recipes/env) first. + + Note + + You may need to initialize the [`env.ts`](/recipes/env) first. + + ## 1. Install dependencies @@ -138,9 +143,12 @@ networks: driver: bridge ``` - - Remember to replace `` with the name of your project. - + + Note + + Remember to replace `` with the name of your project. + + ## 5. Start Database diff --git a/apps/docs/src/content/ui/components/accordion.mdx b/apps/docs/src/content/ui/accordion.mdx similarity index 100% rename from apps/docs/src/content/ui/components/accordion.mdx rename to apps/docs/src/content/ui/accordion.mdx diff --git a/apps/docs/src/content/ui/components/alert-dialog.mdx b/apps/docs/src/content/ui/alert-dialog.mdx similarity index 97% rename from apps/docs/src/content/ui/components/alert-dialog.mdx rename to apps/docs/src/content/ui/alert-dialog.mdx index 3f354d342..8dec0e7b6 100644 --- a/apps/docs/src/content/ui/components/alert-dialog.mdx +++ b/apps/docs/src/content/ui/alert-dialog.mdx @@ -20,8 +20,7 @@ import { AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, - AlertDialogTrigger, - Button + AlertDialogTrigger } from '@tszhong0411/ui' ``` diff --git a/apps/docs/src/content/ui/alert.mdx b/apps/docs/src/content/ui/alert.mdx new file mode 100644 index 000000000..45400d2c0 --- /dev/null +++ b/apps/docs/src/content/ui/alert.mdx @@ -0,0 +1,29 @@ +--- +title: Alert +description: Displays a callout for user attention. +--- + + + +## Usage + +```tsx +import { Alert, AlertTitle, AlertDescription } from '@tszhong0411/ui' +``` + +```tsx + + Title + content + +``` + +## Examples + +### Info + + + +### Destructive + + diff --git a/apps/docs/src/content/ui/components/aspect-ratio.mdx b/apps/docs/src/content/ui/aspect-ratio.mdx similarity index 100% rename from apps/docs/src/content/ui/components/aspect-ratio.mdx rename to apps/docs/src/content/ui/aspect-ratio.mdx diff --git a/apps/docs/src/content/ui/components/avatar.mdx b/apps/docs/src/content/ui/avatar.mdx similarity index 69% rename from apps/docs/src/content/ui/components/avatar.mdx rename to apps/docs/src/content/ui/avatar.mdx index 85996445c..339ff3b31 100644 --- a/apps/docs/src/content/ui/components/avatar.mdx +++ b/apps/docs/src/content/ui/avatar.mdx @@ -8,9 +8,12 @@ link: - - You can use `getAvatarAbbreviation{:.entity.name.function}` to get the abbreviation of a name to be used in an `{:tsx}`. - + + Note + + You can use `getAbbreviation{:.entity.name.function}` to get the abbreviation of a name to be used in an `{:tsx}`. + + ## Usage diff --git a/apps/docs/src/content/ui/components/badge.mdx b/apps/docs/src/content/ui/badge.mdx similarity index 100% rename from apps/docs/src/content/ui/components/badge.mdx rename to apps/docs/src/content/ui/badge.mdx diff --git a/apps/docs/src/content/ui/components/breadcrumb.mdx b/apps/docs/src/content/ui/breadcrumb.mdx similarity index 82% rename from apps/docs/src/content/ui/components/breadcrumb.mdx rename to apps/docs/src/content/ui/breadcrumb.mdx index ff9b89df9..e75aba38d 100644 --- a/apps/docs/src/content/ui/components/breadcrumb.mdx +++ b/apps/docs/src/content/ui/breadcrumb.mdx @@ -35,3 +35,7 @@ import { ``` + +## Notes + +- The `BreadcrumbLink` is using anchor tag by default. If needed, you can use the `asChild` prop to wrap it with a `Link` component from `next/link`. diff --git a/apps/docs/src/content/ui/components/button.mdx b/apps/docs/src/content/ui/button.mdx similarity index 100% rename from apps/docs/src/content/ui/components/button.mdx rename to apps/docs/src/content/ui/button.mdx diff --git a/apps/docs/src/content/ui/calendar.mdx b/apps/docs/src/content/ui/calendar.mdx new file mode 100644 index 000000000..8f9467275 --- /dev/null +++ b/apps/docs/src/content/ui/calendar.mdx @@ -0,0 +1,42 @@ +--- +title: Calendar +description: A date field component that allows users to enter and edit date. +--- + + + +## Installation + +```bash +npm install react-day-picker +# or +pnpm install react-day-picker +# or +yarn add react-day-picker +# or +bun add react-day-picker +``` + +## Usage + +```tsx +import { Calendar } from '@tszhong0411/ui' +``` + +```tsx + +``` + +## Examples + +### Single + + + +### Range + + + +## Notes + +- Currently, the calendar component is using `react-day-picker@8.10.1`. v9 is not yet supported. diff --git a/apps/docs/src/content/ui/components/card.mdx b/apps/docs/src/content/ui/card.mdx similarity index 100% rename from apps/docs/src/content/ui/components/card.mdx rename to apps/docs/src/content/ui/card.mdx diff --git a/apps/docs/src/content/ui/components/carousel.mdx b/apps/docs/src/content/ui/carousel.mdx similarity index 100% rename from apps/docs/src/content/ui/components/carousel.mdx rename to apps/docs/src/content/ui/carousel.mdx diff --git a/apps/docs/src/content/ui/chart.mdx b/apps/docs/src/content/ui/chart.mdx new file mode 100644 index 000000000..b62e0c550 --- /dev/null +++ b/apps/docs/src/content/ui/chart.mdx @@ -0,0 +1,22 @@ +--- +title: Chart +description: Beautiful charts. Built using Recharts. Copy and paste into your apps. +--- + + + +## Installation + +```bash +npm install recharts +# or +pnpm install recharts +# or +yarn add recharts +# or +bun add recharts +``` + +## Usage + +See [shadcn/ui chart](https://ui.shadcn.com/docs/components/chart) for more information. diff --git a/apps/docs/src/content/ui/components/checkbox.mdx b/apps/docs/src/content/ui/checkbox.mdx similarity index 100% rename from apps/docs/src/content/ui/components/checkbox.mdx rename to apps/docs/src/content/ui/checkbox.mdx diff --git a/apps/docs/src/content/ui/components/code-block.mdx b/apps/docs/src/content/ui/code-block.mdx similarity index 64% rename from apps/docs/src/content/ui/components/code-block.mdx rename to apps/docs/src/content/ui/code-block.mdx index 1bc589e4c..d84d45d9f 100644 --- a/apps/docs/src/content/ui/components/code-block.mdx +++ b/apps/docs/src/content/ui/code-block.mdx @@ -5,7 +5,12 @@ description: A block of code that can be copied. -You may use [shiki](https://shiki.style/) to highlight code blocks. + + Note + + You may use [shiki](https://shiki.style/) to highlight code blocks. + + ## Usage diff --git a/apps/docs/src/content/ui/components/collapsible.mdx b/apps/docs/src/content/ui/collapsible.mdx similarity index 100% rename from apps/docs/src/content/ui/components/collapsible.mdx rename to apps/docs/src/content/ui/collapsible.mdx diff --git a/apps/docs/src/content/ui/combobox.mdx b/apps/docs/src/content/ui/combobox.mdx new file mode 100644 index 000000000..ca27d5b46 --- /dev/null +++ b/apps/docs/src/content/ui/combobox.mdx @@ -0,0 +1,85 @@ +--- +title: Combobox +description: Autocomplete input and command palette with a list of suggestions. +--- + + + +## Installation + +The Combobox is built using a composition of the `` and the `` components. + +See installation instructions for the [Popover](/ui/popover#installation) and the [Command](/ui/command#installation) components. + +## Usage + +```tsx +const frameworks = [ + { + value: 'next.js', + label: 'Next.js' + }, + { + value: 'sveltekit', + label: 'SvelteKit' + }, + { + value: 'nuxt.js', + label: 'Nuxt.js' + }, + { + value: 'remix', + label: 'Remix' + }, + { + value: 'astro', + label: 'Astro' + } +] + + + + + + + + + + No framework found. + + {frameworks.map((framework) => ( + { + setValue(currentValue === value ? '' : currentValue) + setOpen(false) + }} + > + {framework.label} + + + ))} + + + + + +``` + +## Accessibility + +Don't forget to add the `aria-controls={id}{:tsx}` prop to the `{:tsx}` component. Also, make sure to pass the `aria-labelledby={id}{:tsx}` prop to the `{:tsx}` component. diff --git a/apps/docs/src/content/ui/components/command.mdx b/apps/docs/src/content/ui/command.mdx similarity index 100% rename from apps/docs/src/content/ui/components/command.mdx rename to apps/docs/src/content/ui/command.mdx diff --git a/apps/docs/src/content/ui/components/blur-fade.mdx b/apps/docs/src/content/ui/components/blur-fade.mdx deleted file mode 100644 index b1a5b3c30..000000000 --- a/apps/docs/src/content/ui/components/blur-fade.mdx +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: Blur Fade -description: Blur fade in and out animation. Used to smoothly fade in and out content. ---- - - - -## Usage - -```tsx -import { BlurFade } from '@tszhong0411/ui' -``` - -```tsx -Hello, World! -``` diff --git a/apps/docs/src/content/ui/components/blur-image.mdx b/apps/docs/src/content/ui/components/blur-image.mdx deleted file mode 100644 index 0bdcac5ca..000000000 --- a/apps/docs/src/content/ui/components/blur-image.mdx +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: Blur Image -description: Displays an image with a blur effect while loading. ---- - - - -## Usage - -```tsx -import { BlurImage } from '@tszhong0411/ui' -``` - -```tsx - -``` diff --git a/apps/docs/src/content/ui/components/callout.mdx b/apps/docs/src/content/ui/components/callout.mdx deleted file mode 100644 index 6cc423ccb..000000000 --- a/apps/docs/src/content/ui/components/callout.mdx +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: Callout -description: A styled alert box component that displays different icons and styles based on the type of message. ---- - - - -## Usage - -```tsx -import { Callout } from '@tszhong0411/ui' -``` - -```tsx -content -``` - -## Examples - -### Info - - - -### Error - - - -### Warning - - diff --git a/apps/docs/src/content/ui/components/combobox.mdx b/apps/docs/src/content/ui/components/combobox.mdx deleted file mode 100644 index 536278725..000000000 --- a/apps/docs/src/content/ui/components/combobox.mdx +++ /dev/null @@ -1,51 +0,0 @@ ---- -title: Combobox -description: Autocomplete input and command palette with a list of suggestions. -link: - doc: https://ark-ui.com/react/docs/components/combobox - api: https://ark-ui.com/react/docs/components/combobox#api-reference ---- - - - -## Usage - -```tsx -import { - Combobox, - ComboboxContent, - ComboboxControl, - ComboboxInput, - ComboboxItem, - ComboboxItemGroup, - ComboboxItemGroupLabel, - ComboboxItemIndicator, - ComboboxItemText, - ComboboxTrigger -} from '@tszhong0411/ui' -``` - -```tsx - - Framework - - - - - - - - - Frameworks - {collection.map((item) => ( - - - - - {item} - - ))} - - - -``` diff --git a/apps/docs/src/content/ui/components/data-table.mdx b/apps/docs/src/content/ui/components/data-table.mdx deleted file mode 100644 index 38976f559..000000000 --- a/apps/docs/src/content/ui/components/data-table.mdx +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Data Table -description: Powerful table and datagrids built using TanStack Table. -doc: https://tanstack.com/table/v8/docs/introduction ---- - - diff --git a/apps/docs/src/content/ui/components/marquee.mdx b/apps/docs/src/content/ui/components/marquee.mdx deleted file mode 100644 index 6bab4076a..000000000 --- a/apps/docs/src/content/ui/components/marquee.mdx +++ /dev/null @@ -1,22 +0,0 @@ ---- -title: Marquee -description: A scrolling text or image display that moves across the screen. ---- - - - -## Usage - -```tsx -import { Marquee } from '@tszhong0411/ui' -``` - -```tsx -content -``` - -## Examples - -### Vertical - - diff --git a/apps/docs/src/content/ui/components/slider.mdx b/apps/docs/src/content/ui/components/slider.mdx deleted file mode 100644 index 92a4b3b1c..000000000 --- a/apps/docs/src/content/ui/components/slider.mdx +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: Slider -description: An input where the user selects a value from within a given range. -link: - doc: https://ark-ui.com/react/docs/components/slider - api: https://ark-ui.com/react/docs/components/slider#api-reference ---- - - - -## Usage - -```tsx -import { Slider } from '@tszhong0411/ui' -``` - -```tsx - -``` - -## Examples - -### With Label - - - -### With Value - - - -### Range - - - -### Marker - - diff --git a/apps/docs/src/content/ui/components/context-menu.mdx b/apps/docs/src/content/ui/context-menu.mdx similarity index 100% rename from apps/docs/src/content/ui/components/context-menu.mdx rename to apps/docs/src/content/ui/context-menu.mdx diff --git a/apps/docs/src/content/ui/data-table.mdx b/apps/docs/src/content/ui/data-table.mdx new file mode 100644 index 000000000..7a52fd854 --- /dev/null +++ b/apps/docs/src/content/ui/data-table.mdx @@ -0,0 +1,8 @@ +--- +title: Data Table +description: Powerful table and datagrids built using TanStack Table. +--- + +## Usage + +See [shadcn/ui data table](https://ui.shadcn.com/docs/components/data-table) for more information. diff --git a/apps/docs/src/content/ui/components/dialog.mdx b/apps/docs/src/content/ui/dialog.mdx similarity index 100% rename from apps/docs/src/content/ui/components/dialog.mdx rename to apps/docs/src/content/ui/dialog.mdx diff --git a/apps/docs/src/content/ui/components/drawer.mdx b/apps/docs/src/content/ui/drawer.mdx similarity index 100% rename from apps/docs/src/content/ui/components/drawer.mdx rename to apps/docs/src/content/ui/drawer.mdx diff --git a/apps/docs/src/content/ui/components/dropdown-menu.mdx b/apps/docs/src/content/ui/dropdown-menu.mdx similarity index 100% rename from apps/docs/src/content/ui/components/dropdown-menu.mdx rename to apps/docs/src/content/ui/dropdown-menu.mdx diff --git a/apps/docs/src/content/ui/components/form.mdx b/apps/docs/src/content/ui/form.mdx similarity index 100% rename from apps/docs/src/content/ui/components/form.mdx rename to apps/docs/src/content/ui/form.mdx diff --git a/apps/docs/src/content/ui/components/hover-card.mdx b/apps/docs/src/content/ui/hover-card.mdx similarity index 100% rename from apps/docs/src/content/ui/components/hover-card.mdx rename to apps/docs/src/content/ui/hover-card.mdx diff --git a/apps/docs/src/content/ui/components/input-otp.mdx b/apps/docs/src/content/ui/input-otp.mdx similarity index 77% rename from apps/docs/src/content/ui/components/input-otp.mdx rename to apps/docs/src/content/ui/input-otp.mdx index 4d31c8b7b..f8449bf4c 100644 --- a/apps/docs/src/content/ui/components/input-otp.mdx +++ b/apps/docs/src/content/ui/input-otp.mdx @@ -5,6 +5,26 @@ description: Accessible one-time password component with copy paste functionalit +## Installation + +```css title='app/globals.css' +@theme { + --animate-caret-blink: caret-blink 1.25s ease-out infinite; + + @keyframes caret-blink { + 0%, + 70%, + 100% { + opacity: 1; + } + 20%, + 50% { + opacity: 0; + } + } +} +``` + ## Usage ```tsx diff --git a/apps/docs/src/content/ui/components/input.mdx b/apps/docs/src/content/ui/input.mdx similarity index 100% rename from apps/docs/src/content/ui/components/input.mdx rename to apps/docs/src/content/ui/input.mdx diff --git a/apps/docs/src/content/ui/components/kbd.mdx b/apps/docs/src/content/ui/kbd.mdx similarity index 100% rename from apps/docs/src/content/ui/components/kbd.mdx rename to apps/docs/src/content/ui/kbd.mdx diff --git a/apps/docs/src/content/ui/components/label.mdx b/apps/docs/src/content/ui/label.mdx similarity index 100% rename from apps/docs/src/content/ui/components/label.mdx rename to apps/docs/src/content/ui/label.mdx diff --git a/apps/docs/src/content/ui/components/link.mdx b/apps/docs/src/content/ui/link.mdx similarity index 100% rename from apps/docs/src/content/ui/components/link.mdx rename to apps/docs/src/content/ui/link.mdx diff --git a/apps/docs/src/content/ui/marquee.mdx b/apps/docs/src/content/ui/marquee.mdx new file mode 100644 index 000000000..cde7463b5 --- /dev/null +++ b/apps/docs/src/content/ui/marquee.mdx @@ -0,0 +1,49 @@ +--- +title: Marquee +description: A scrolling text or image display that moves across the screen. +--- + + + +## Installation + +```css title='app/globals.css' +@theme { + --animate-marquee-left: marquee-left var(--duration, 30s) linear infinite; + --animate-marquee-up: marquee-up var(--duration, 30s) linear infinite; + + @keyframes marquee-left { + from { + transform: translateX(0); + } + to { + transform: translateX(calc(-100% - var(--gap))); + } + } + + @keyframes marquee-up { + from { + transform: translateY(0); + } + to { + transform: translateY(calc(-100% - var(--gap))); + } + } +} +``` + +## Usage + +```tsx +import { Marquee } from '@tszhong0411/ui' +``` + +```tsx +content +``` + +## Examples + +### Vertical + + diff --git a/apps/docs/src/content/ui/components/menubar.mdx b/apps/docs/src/content/ui/menubar.mdx similarity index 100% rename from apps/docs/src/content/ui/components/menubar.mdx rename to apps/docs/src/content/ui/menubar.mdx diff --git a/apps/docs/src/content/ui/components/navigation-menu.mdx b/apps/docs/src/content/ui/navigation-menu.mdx similarity index 100% rename from apps/docs/src/content/ui/components/navigation-menu.mdx rename to apps/docs/src/content/ui/navigation-menu.mdx diff --git a/apps/docs/src/content/ui/components/pagination.mdx b/apps/docs/src/content/ui/pagination.mdx similarity index 100% rename from apps/docs/src/content/ui/components/pagination.mdx rename to apps/docs/src/content/ui/pagination.mdx diff --git a/apps/docs/src/content/ui/components/popover.mdx b/apps/docs/src/content/ui/popover.mdx similarity index 100% rename from apps/docs/src/content/ui/components/popover.mdx rename to apps/docs/src/content/ui/popover.mdx diff --git a/apps/docs/src/content/ui/components/progress.mdx b/apps/docs/src/content/ui/progress.mdx similarity index 53% rename from apps/docs/src/content/ui/components/progress.mdx rename to apps/docs/src/content/ui/progress.mdx index 20b58aa96..0b4488484 100644 --- a/apps/docs/src/content/ui/components/progress.mdx +++ b/apps/docs/src/content/ui/progress.mdx @@ -2,8 +2,8 @@ title: Progress description: Displays an indicator showing the completion progress of a task, typically displayed as a progress bar. link: - doc: https://ark-ui.com/react/docs/components/progress-linear - api: https://ark-ui.com/react/docs/components/progress-linear#api-reference + doc: https://www.radix-ui.com/primitives/docs/components/progress + api: https://www.radix-ui.com/primitives/docs/components/progress#api-reference --- @@ -21,17 +21,3 @@ import { Progress, ProgressRange, ProgressTrack } from '@tszhong0411/ui' ``` - -## Examples - -### With Label - - - -### With Value - - - -### Circular - - diff --git a/apps/docs/src/content/ui/components/radio-group.mdx b/apps/docs/src/content/ui/radio-group.mdx similarity index 100% rename from apps/docs/src/content/ui/components/radio-group.mdx rename to apps/docs/src/content/ui/radio-group.mdx diff --git a/apps/docs/src/content/ui/components/resizable.mdx b/apps/docs/src/content/ui/resizable.mdx similarity index 100% rename from apps/docs/src/content/ui/components/resizable.mdx rename to apps/docs/src/content/ui/resizable.mdx diff --git a/apps/docs/src/content/ui/components/scroll-area.mdx b/apps/docs/src/content/ui/scroll-area.mdx similarity index 100% rename from apps/docs/src/content/ui/components/scroll-area.mdx rename to apps/docs/src/content/ui/scroll-area.mdx diff --git a/apps/docs/src/content/ui/components/segment-group.mdx b/apps/docs/src/content/ui/segment-group.mdx similarity index 100% rename from apps/docs/src/content/ui/components/segment-group.mdx rename to apps/docs/src/content/ui/segment-group.mdx diff --git a/apps/docs/src/content/ui/components/select.mdx b/apps/docs/src/content/ui/select.mdx similarity index 100% rename from apps/docs/src/content/ui/components/select.mdx rename to apps/docs/src/content/ui/select.mdx diff --git a/apps/docs/src/content/ui/components/separator.mdx b/apps/docs/src/content/ui/separator.mdx similarity index 100% rename from apps/docs/src/content/ui/components/separator.mdx rename to apps/docs/src/content/ui/separator.mdx diff --git a/apps/docs/src/content/ui/components/sheet.mdx b/apps/docs/src/content/ui/sheet.mdx similarity index 100% rename from apps/docs/src/content/ui/components/sheet.mdx rename to apps/docs/src/content/ui/sheet.mdx diff --git a/apps/docs/src/content/ui/components/sidebar.mdx b/apps/docs/src/content/ui/sidebar.mdx similarity index 100% rename from apps/docs/src/content/ui/components/sidebar.mdx rename to apps/docs/src/content/ui/sidebar.mdx diff --git a/apps/docs/src/content/ui/components/skeleton.mdx b/apps/docs/src/content/ui/skeleton.mdx similarity index 100% rename from apps/docs/src/content/ui/components/skeleton.mdx rename to apps/docs/src/content/ui/skeleton.mdx diff --git a/apps/docs/src/content/ui/slider.mdx b/apps/docs/src/content/ui/slider.mdx new file mode 100644 index 000000000..e6eafe228 --- /dev/null +++ b/apps/docs/src/content/ui/slider.mdx @@ -0,0 +1,25 @@ +--- +title: Slider +description: An input where the user selects a value from within a given range. +link: + doc: https://www.radix-ui.com/primitives/docs/components/slider + api: https://www.radix-ui.com/primitives/docs/components/slider#api-reference +--- + + + +## Usage + +```tsx +import { Slider } from '@tszhong0411/ui' +``` + +```tsx + +``` + +## Examples + +### Range + + diff --git a/apps/docs/src/content/ui/components/toaster.mdx b/apps/docs/src/content/ui/sonner.mdx similarity index 74% rename from apps/docs/src/content/ui/components/toaster.mdx rename to apps/docs/src/content/ui/sonner.mdx index 267ba5bfd..338352ef4 100644 --- a/apps/docs/src/content/ui/components/toaster.mdx +++ b/apps/docs/src/content/ui/sonner.mdx @@ -1,12 +1,24 @@ --- -title: Toaster +title: Sonner description: A notification component for displaying brief, non-intrusive messages to the user. link: doc: https://sonner.emilkowal.ski/getting-started api: https://sonner.emilkowal.ski/toast --- - + + +## Installation + +```bash +npm install next-themes +# or +pnpm install next-themes +# or +yarn add next-themes +# or +bun add next-themes +``` ## Usage diff --git a/apps/docs/src/content/ui/components/switch.mdx b/apps/docs/src/content/ui/switch.mdx similarity index 100% rename from apps/docs/src/content/ui/components/switch.mdx rename to apps/docs/src/content/ui/switch.mdx diff --git a/apps/docs/src/content/ui/components/table.mdx b/apps/docs/src/content/ui/table.mdx similarity index 100% rename from apps/docs/src/content/ui/components/table.mdx rename to apps/docs/src/content/ui/table.mdx diff --git a/apps/docs/src/content/ui/components/tabs.mdx b/apps/docs/src/content/ui/tabs.mdx similarity index 100% rename from apps/docs/src/content/ui/components/tabs.mdx rename to apps/docs/src/content/ui/tabs.mdx diff --git a/apps/docs/src/content/ui/components/textarea.mdx b/apps/docs/src/content/ui/textarea.mdx similarity index 66% rename from apps/docs/src/content/ui/components/textarea.mdx rename to apps/docs/src/content/ui/textarea.mdx index 500dd4e9c..2187c2348 100644 --- a/apps/docs/src/content/ui/components/textarea.mdx +++ b/apps/docs/src/content/ui/textarea.mdx @@ -5,6 +5,13 @@ description: A multiline text input field for entering or editing larger amounts + + Note + + This component is using `react-textarea-autosize` under the hood. So it supports auto-sizing. + + + ## Usage ```tsx diff --git a/apps/docs/src/content/ui/components/toggle-group.mdx b/apps/docs/src/content/ui/toggle-group.mdx similarity index 100% rename from apps/docs/src/content/ui/components/toggle-group.mdx rename to apps/docs/src/content/ui/toggle-group.mdx diff --git a/apps/docs/src/content/ui/components/toggle.mdx b/apps/docs/src/content/ui/toggle.mdx similarity index 100% rename from apps/docs/src/content/ui/components/toggle.mdx rename to apps/docs/src/content/ui/toggle.mdx diff --git a/apps/docs/src/content/ui/components/tooltip.mdx b/apps/docs/src/content/ui/tooltip.mdx similarity index 100% rename from apps/docs/src/content/ui/components/tooltip.mdx rename to apps/docs/src/content/ui/tooltip.mdx diff --git a/apps/docs/src/content/ui/components/tree-view.mdx b/apps/docs/src/content/ui/tree-view.mdx similarity index 53% rename from apps/docs/src/content/ui/components/tree-view.mdx rename to apps/docs/src/content/ui/tree-view.mdx index 3adc40c18..c026fd0ac 100644 --- a/apps/docs/src/content/ui/components/tree-view.mdx +++ b/apps/docs/src/content/ui/tree-view.mdx @@ -8,6 +8,33 @@ link: +## Installation + +```css title='app/globals.css' +@theme { + --animate-tree-view-content-down: tree-view-content-down 0.2s ease-out; + --animate-tree-view-content-up: tree-view-content-up 0.2s ease-out; + + @keyframes tree-view-content-down { + from { + height: 0; + } + to { + height: var(--height); + } + } + + @keyframes tree-view-content-up { + from { + height: var(--height); + } + to { + height: 0; + } + } +} +``` + ## Usage ```tsx diff --git a/apps/docs/src/content/ui/utilities/get-avatar-abbreviation.mdx b/apps/docs/src/content/ui/utilities/get-avatar-abbreviation.mdx deleted file mode 100644 index 058c43403..000000000 --- a/apps/docs/src/content/ui/utilities/get-avatar-abbreviation.mdx +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: getAvatarAbbreviation -description: Get the abbreviation of a name to be used in an . ---- - - - -## Usage - -```tsx -import { getAvatarAbbreviation } from '@tszhong0411/ui' -``` - -```tsx -getAvatarAbbreviation('John Doe') -``` diff --git a/apps/docs/src/content/utilities/cn.mdx b/apps/docs/src/content/utilities/cn.mdx new file mode 100644 index 000000000..bbeaf5539 --- /dev/null +++ b/apps/docs/src/content/utilities/cn.mdx @@ -0,0 +1,25 @@ +--- +title: cn Utility +description: A utility function for conditionally joining CSS class names together. +--- + +The `cn` function is a helper utility that simplifies the process of conditionally applying CSS class names. It combines the power of `clsx` for conditional class joining and `tailwind-merge` for intelligently merging Tailwind CSS classes without style conflicts. + +## Usage + +```typescript +import { cn } from '@tszhong0411/utils' + +const className = cn('text-blue-500', 'font-bold', false && 'hidden', 'mt-4') +// className will be "text-blue-500 font-bold mt-4" +``` + +## API + +### `cn(...inputs: ClassValue[]): string` + +Joins CSS class names together. + +- `...inputs`: A variable number of arguments, which can be strings, arrays of strings, or objects where keys are class names and values are booleans. + +**Returns:** `string` - A string of joined and merged CSS class names. diff --git a/apps/docs/src/content/utilities/get-abbreviation.mdx b/apps/docs/src/content/utilities/get-abbreviation.mdx new file mode 100644 index 000000000..2f6b5e287 --- /dev/null +++ b/apps/docs/src/content/utilities/get-abbreviation.mdx @@ -0,0 +1,31 @@ +--- +title: getAbbreviation Utility +description: Generates an abbreviation from a given string, typically a name. +--- + +The `getAbbreviation` function takes a string, splits it into words, and returns a string composed of the first letter of each word. If the resulting abbreviation is longer than two characters, it is truncated to the first two characters. + +## Usage + +```typescript +import { getAbbreviation } from '@tszhong0411/utils' + +const abbreviation1 = getAbbreviation('John Doe') +// abbreviation1 will be "JD" + +const abbreviation2 = getAbbreviation('Pedro Duarte') +// abbreviation2 will be "PD" + +const abbreviation3 = getAbbreviation('Colm Tuite') +// abbreviation3 will be "CT" +``` + +## API + +### `getAbbreviation(name: string): string` + +Generates an abbreviation from a string. + +- `name`: The input string, typically a name. + +**Returns:** `string` - The generated abbreviation. diff --git a/apps/docs/src/content/utilities/get-error-message.mdx b/apps/docs/src/content/utilities/get-error-message.mdx new file mode 100644 index 000000000..321b8f64a --- /dev/null +++ b/apps/docs/src/content/utilities/get-error-message.mdx @@ -0,0 +1,54 @@ +--- +title: getErrorMessage Utility +description: Extracts a user-friendly error message from various error types. +--- + +The `getErrorMessage` function is a utility designed to safely extract a string message from an unknown error type. It handles instances of `Error`, objects with a `message` property, and string types, providing a fallback message for all other cases. + +## Usage + +```typescript +import { getErrorMessage } from '@tszhong0411/utils' + +try { + // Some operation that might throw an error + throw new Error('Something went wrong!') +} catch (error) { + const message = getErrorMessage(error) + // message will be "Something went wrong!" +} + +try { + // Some operation that might throw a string + throw 'An error occurred.' +} catch (error) { + const message = getErrorMessage(error) + // message will be "An error occurred." +} + +try { + // Some operation that might throw an object with a message property + throw { message: 'Operation failed.' } +} catch (error) { + const message = getErrorMessage(error) + // message will be "Operation failed." +} + +try { + // Some operation that might throw an unknown type + throw 123 +} catch (error) { + const message = getErrorMessage(error) + // message will be "Something went wrong" +} +``` + +## API + +### `getErrorMessage(error: unknown): string` + +Extracts a user-friendly error message from an unknown error type. + +- `error`: The unknown error value. + +**Returns:** `string` - The extracted error message or a default fallback message. diff --git a/apps/docs/src/content/utilities/range.mdx b/apps/docs/src/content/utilities/range.mdx new file mode 100644 index 000000000..89f765896 --- /dev/null +++ b/apps/docs/src/content/utilities/range.mdx @@ -0,0 +1,25 @@ +--- +title: range Utility +description: Creates an array of numbers from 0 up to (but not including) the specified length. +--- + +The `range` function is a simple utility that creates an array of numbers starting from 0 up to, but not including, the specified `length`. + +## Usage + +```typescript +import { range } from '@tszhong0411/utils' + +const numbers = range(5) +// numbers will be [0, 1, 2, 3, 4] +``` + +## API + +### `range(length: number): number[]` + +Creates an array of numbers. + +- `length`: The number of elements in the array. The array will contain numbers from 0 up to `length - 1`. + +**Returns:** `number[]` - An array of numbers. diff --git a/apps/web/package.json b/apps/web/package.json index 28dbc1c18..2b913cc49 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -42,8 +42,8 @@ "better-auth": "^1.2.5", "better-call": "^1.0.7", "canvas-confetti": "^1.9.3", - "class-variance-authority": "^0.7.1", "cobe": "^0.6.3", + "cva": "^1.0.0-beta.3", "dayjs": "^1.11.13", "fast-xml-parser": "^5.2.0", "geist": "^1.3.1", diff --git a/apps/web/src/app/[locale]/(admin)/admin/comments/page.tsx b/apps/web/src/app/[locale]/(admin)/admin/comments/page.tsx index 12ee6e280..8c610b1f0 100644 --- a/apps/web/src/app/[locale]/(admin)/admin/comments/page.tsx +++ b/apps/web/src/app/[locale]/(admin)/admin/comments/page.tsx @@ -2,7 +2,7 @@ import { useQuery } from '@tanstack/react-query' import { useTranslations } from '@tszhong0411/i18n/client' -import { DataTableSkeleton } from '@tszhong0411/ui' +import { Skeleton } from '@tszhong0411/ui' import AdminPageHeader from '@/components/admin/admin-page-header' import CommentsTable from '@/components/admin/comments-table' @@ -23,9 +23,9 @@ const Page = () => { title={t('admin.page-header.comments.title')} description={t('admin.page-header.comments.description')} /> - {isLoading ? : null} - {isError ?
{t('admin.table.comments.failed-to-fetch-comments-data')}
: null} - {isSuccess ? : null} + {isLoading && } + {isError &&
{t('admin.table.comments.failed-to-fetch-comments-data')}
} + {isSuccess && }
) } diff --git a/apps/web/src/app/[locale]/(admin)/admin/users/page.tsx b/apps/web/src/app/[locale]/(admin)/admin/users/page.tsx index b9d662a75..2b28ac5d0 100644 --- a/apps/web/src/app/[locale]/(admin)/admin/users/page.tsx +++ b/apps/web/src/app/[locale]/(admin)/admin/users/page.tsx @@ -2,7 +2,7 @@ import { useQuery } from '@tanstack/react-query' import { useTranslations } from '@tszhong0411/i18n/client' -import { DataTableSkeleton } from '@tszhong0411/ui' +import { Skeleton } from '@tszhong0411/ui' import AdminPageHeader from '@/components/admin/admin-page-header' import UsersTable from '@/components/admin/users-table' @@ -23,11 +23,9 @@ const Page = () => { title={t('admin.page-header.users.title')} description={t('admin.page-header.users.description')} /> - {isLoading ? ( - - ) : null} - {isError ?
{t('admin.table.users.failed-to-fetch-users-data')}
: null} - {isSuccess ? : null} + {isLoading && } + {isError &&
{t('admin.table.users.failed-to-fetch-users-data')}
} + {isSuccess && }
) } diff --git a/apps/web/src/app/[locale]/(main)/blog/[slug]/header.tsx b/apps/web/src/app/[locale]/(main)/blog/[slug]/header.tsx index 117ff18f2..bd19b4c19 100644 --- a/apps/web/src/app/[locale]/(main)/blog/[slug]/header.tsx +++ b/apps/web/src/app/[locale]/(main)/blog/[slug]/header.tsx @@ -3,11 +3,11 @@ import NumberFlow from '@number-flow/react' import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query' import { useTranslations } from '@tszhong0411/i18n/client' -import { BlurImage } from '@tszhong0411/ui' import { useEffect, useRef } from 'react' import ImageZoom from '@/components/image-zoom' import Link from '@/components/link' +import { BlurImage } from '@/components/ui/blur-image' import { usePostContext } from '@/contexts/post' import { useFormattedDate } from '@/hooks/use-formatted-date' import { useTRPC } from '@/trpc/client' @@ -66,19 +66,19 @@ const Header = () => {
{t('blog.header.views')}
- {viewsCountQuery.status === 'pending' ? '--' : null} - {viewsCountQuery.status === 'error' ? t('common.error') : null} - {viewsCountQuery.status === 'success' ? ( + {viewsCountQuery.status === 'pending' && '--'} + {viewsCountQuery.status === 'error' && t('common.error')} + {viewsCountQuery.status === 'success' && ( - ) : null} + )}
{t('blog.header.comments')}
- {commentsCountQuery.status === 'pending' ? '--' : null} - {commentsCountQuery.status === 'error' ? t('common.error') : null} - {commentsCountQuery.status === 'success' ? ( + {commentsCountQuery.status === 'pending' && '--'} + {commentsCountQuery.status === 'error' && t('common.error')} + {commentsCountQuery.status === 'success' && ( - ) : null} + )}
diff --git a/apps/web/src/app/[locale]/(main)/blog/[slug]/like-button.tsx b/apps/web/src/app/[locale]/(main)/blog/[slug]/like-button.tsx index 70e7a77ba..e46635bc5 100644 --- a/apps/web/src/app/[locale]/(main)/blog/[slug]/like-button.tsx +++ b/apps/web/src/app/[locale]/(main)/blog/[slug]/like-button.tsx @@ -151,11 +151,11 @@ const LikeButton = (props: LikeButtonProps) => { {t('blog.like')} - {status === 'pending' ?
--
: null} - {status === 'error' ?
{t('common.error')}
: null} - {status === 'success' ? ( + {status === 'pending' &&
--
} + {status === 'error' &&
{t('common.error')}
} + {status === 'success' && ( - ) : null} + )} ) diff --git a/apps/web/src/app/[locale]/(main)/blog/[slug]/mobile-table-of-contents.tsx b/apps/web/src/app/[locale]/(main)/blog/[slug]/mobile-table-of-contents.tsx index a43cab6c6..0cc880ae7 100644 --- a/apps/web/src/app/[locale]/(main)/blog/[slug]/mobile-table-of-contents.tsx +++ b/apps/web/src/app/[locale]/(main)/blog/[slug]/mobile-table-of-contents.tsx @@ -24,7 +24,7 @@ const MobileTableOfContents = (props: MobileTableOfContentsProps) => { diff --git a/apps/web/src/app/[locale]/(main)/blog/[slug]/page.tsx b/apps/web/src/app/[locale]/(main)/blog/[slug]/page.tsx index d2c138ff1..9f8947f06 100644 --- a/apps/web/src/app/[locale]/(main)/blog/[slug]/page.tsx +++ b/apps/web/src/app/[locale]/(main)/blog/[slug]/page.tsx @@ -146,22 +146,22 @@ const Page = async (props: PageProps) => { - {toc.length > 0 ? : null} + {toc.length > 0 && }