update usage (icons + size-)
This commit is contained in:
parent
c6deceaa89
commit
cd0a8d020e
|
|
@ -1665,18 +1665,18 @@ create-icon.tsx
|
|||
export function createIcon({ definition }: CreateIconParams)
|
||||
|
||||
index.tsx
|
||||
export const GoogleIcon
|
||||
export const GithubIcon
|
||||
export const VercelIcon
|
||||
export const DataBuddyIcon
|
||||
export const MarbleIcon
|
||||
export const BackgroundIcon
|
||||
export const SocialsIcon
|
||||
export const TransitionUpIcon
|
||||
export const MenuIcon
|
||||
export const PencilIcon
|
||||
export const LeftArrowIcon
|
||||
export const TrashIcon
|
||||
export const OcGoogleIcon
|
||||
export const OcGithubIcon
|
||||
export const OcVercelIcon
|
||||
export const OcDataBuddyIcon
|
||||
export const OcMarbleIcon
|
||||
export const OcBackgroundIcon
|
||||
export const OcSocialsIcon
|
||||
export const OcTransitionUpIcon
|
||||
export const OcMenuIcon
|
||||
export const OcPencilIcon
|
||||
export const OcLeftArrowIcon
|
||||
export const OcTrashIcon
|
||||
|
||||
types.ts
|
||||
export type IconProps = Omit<
|
||||
|
|
@ -1694,25 +1694,14 @@ types.ts
|
|||
nodes: IconNode;
|
||||
}
|
||||
|
||||
## packages/ui/src/icons/collections
|
||||
|
||||
brand.ts
|
||||
export const BRAND_COLLECTION
|
||||
|
||||
editor.ts
|
||||
export const EDITOR_COLLECTION
|
||||
|
||||
index.ts
|
||||
export const ICON_COLLECTIONS
|
||||
|
||||
ui.ts
|
||||
export const UI_COLLECTION
|
||||
|
||||
## packages/ui/src/icons/registry
|
||||
|
||||
brand.ts
|
||||
export const BRAND_ICONS
|
||||
|
||||
editor.ts
|
||||
export const EDITOR_ICONS
|
||||
|
||||
index.ts
|
||||
export const ICON_DEFINITIONS
|
||||
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ function AuthorList({ authors }: { authors: Author[] }) {
|
|||
<div className="flex items-center gap-2">
|
||||
{authors.map((author) => (
|
||||
<div key={author.id} className="flex items-center gap-2">
|
||||
<Avatar className="h-6 w-6 shadow-sm">
|
||||
<Avatar className="size-6 shadow-sm">
|
||||
<AvatarImage src={author.image} alt={author.name} />
|
||||
<AvatarFallback className="text-xs">
|
||||
{author.name.charAt(0).toUpperCase()}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { GithubIcon } from "@opencut/ui/icons";
|
||||
import { OcGithubIcon } from "@opencut/ui/icons";
|
||||
import { ExternalLink } from "lucide-react";
|
||||
import type { Metadata } from "next";
|
||||
import Link from "next/link";
|
||||
|
|
@ -101,7 +101,7 @@ export default async function ContributorsPage() {
|
|||
function StatItem({ value, label }: { value: number; label: string }) {
|
||||
return (
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="bg-foreground h-2 w-2 rounded-full" />
|
||||
<div className="bg-foreground size-2 rounded-full" />
|
||||
<span className="font-medium">{value}</span>
|
||||
<span className="text-muted-foreground">{label}</span>
|
||||
</div>
|
||||
|
|
@ -187,7 +187,7 @@ function AllContributorsSection({
|
|||
className="opacity-100 transition-opacity hover:opacity-70"
|
||||
>
|
||||
<div className="flex flex-col items-center gap-2 p-2">
|
||||
<Avatar className="h-16 w-16">
|
||||
<Avatar className="size-16">
|
||||
<AvatarImage
|
||||
src={contributor.avatar_url}
|
||||
alt={`${contributor.login}'s avatar`}
|
||||
|
|
@ -214,8 +214,8 @@ function EmptyState() {
|
|||
return (
|
||||
<div className="flex flex-col gap-8 py-20 text-center">
|
||||
<div className="flex flex-col gap-6">
|
||||
<div className="bg-muted/50 mx-auto flex h-20 w-20 items-center justify-center rounded-full">
|
||||
<GithubIcon className="text-muted-foreground h-8 w-8" />
|
||||
<div className="bg-muted/50 mx-auto flex size-20 items-center justify-center rounded-full">
|
||||
<OcGithubIcon className="text-muted-foreground size-8" />
|
||||
</div>
|
||||
<div className="flex flex-col gap-3">
|
||||
<h3 className="text-xl font-medium">No contributors found</h3>
|
||||
|
|
@ -231,9 +231,9 @@ function EmptyState() {
|
|||
rel="noopener noreferrer"
|
||||
>
|
||||
<Button variant="outline" className="gap-2">
|
||||
<GithubIcon className="h-4 w-4" />
|
||||
<OcGithubIcon />
|
||||
View on GitHub
|
||||
<ExternalLink className="h-4 w-4" />
|
||||
<ExternalLink />
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
|
|
@ -259,8 +259,8 @@ function ExternalToolsSection() {
|
|||
>
|
||||
<Card className="h-full">
|
||||
<CardContent className="flex h-full flex-col gap-4 p-6 text-center">
|
||||
<div className="bg-muted/50 mx-auto flex h-12 w-12 items-center justify-center rounded-full">
|
||||
<tool.icon className="h-6 w-6" />
|
||||
<div className="bg-muted/50 mx-auto flex size-12 items-center justify-center rounded-full">
|
||||
<tool.icon className="size-6" />
|
||||
</div>
|
||||
<div className="flex flex-1 flex-col gap-2">
|
||||
<h3 className="text-lg font-semibold">{tool.name}</h3>
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ function EditorLayout() {
|
|||
return (
|
||||
<ResizablePanelGroup
|
||||
direction="vertical"
|
||||
className="h-full w-full gap-[0.18rem]"
|
||||
className="size-full gap-[0.18rem]"
|
||||
onLayout={(sizes) => {
|
||||
setPanel("mainContent", sizes[0] ?? panels.mainContent);
|
||||
setPanel("timeline", sizes[1] ?? panels.timeline);
|
||||
|
|
@ -54,7 +54,7 @@ function EditorLayout() {
|
|||
>
|
||||
<ResizablePanelGroup
|
||||
direction="horizontal"
|
||||
className="h-full w-full gap-[0.19rem] px-3"
|
||||
className="size-full gap-[0.19rem] px-3"
|
||||
onLayout={(sizes) => {
|
||||
setPanel("tools", sizes[0] ?? panels.tools);
|
||||
setPanel("preview", sizes[1] ?? panels.preview);
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ export default function ProjectsPage() {
|
|||
size="sm"
|
||||
onClick={handleCancelSelection}
|
||||
>
|
||||
<X className="size-4!" />
|
||||
<X />
|
||||
Cancel
|
||||
</Button>
|
||||
{selectedProjects.size > 0 && (
|
||||
|
|
@ -180,7 +180,7 @@ export default function ProjectsPage() {
|
|||
size="sm"
|
||||
onClick={() => setIsBulkDeleteDialogOpen(true)}
|
||||
>
|
||||
<Trash2 className="size-4!" />
|
||||
<Trash2 />
|
||||
Delete ({selectedProjects.size})
|
||||
</Button>
|
||||
)}
|
||||
|
|
@ -210,7 +210,7 @@ export default function ProjectsPage() {
|
|||
{isSelectionMode ? (
|
||||
<div className="flex items-center gap-2">
|
||||
<Button variant="outline" onClick={handleCancelSelection}>
|
||||
<X className="size-4!" />
|
||||
<X />
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
|
|
@ -218,7 +218,7 @@ export default function ProjectsPage() {
|
|||
disabled={selectedProjects.size === 0}
|
||||
onClick={() => setIsBulkDeleteDialogOpen(true)}
|
||||
>
|
||||
<Trash2 className="size-4!" />
|
||||
<Trash2 />
|
||||
Delete {selectedProjects.size} projects
|
||||
</Button>
|
||||
</div>
|
||||
|
|
@ -429,7 +429,7 @@ function ProjectCard({
|
|||
className="object-cover"
|
||||
/>
|
||||
) : (
|
||||
<div className="bg-muted/50 flex h-full w-full items-center justify-center">
|
||||
<div className="bg-muted/50 flex size-full items-center justify-center">
|
||||
<Video className="text-muted-foreground size-12 shrink-0" />
|
||||
</div>
|
||||
)}
|
||||
|
|
@ -562,7 +562,7 @@ function ProjectsLoader() {
|
|||
<div className="flex flex-col gap-1.5 px-0 pt-5">
|
||||
<Skeleton className="bg-muted/50 h-4 w-3/4" />
|
||||
<div className="flex items-center gap-1.5">
|
||||
<Skeleton className="bg-muted/50 h-4 w-4" />
|
||||
<Skeleton className="bg-muted/50 size-4" />
|
||||
<Skeleton className="bg-muted/50 h-4 w-24" />
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -575,7 +575,7 @@ function ProjectsLoader() {
|
|||
function CreateButton({ onClick }: { onClick?: () => void }) {
|
||||
return (
|
||||
<Button className="flex" onClick={onClick}>
|
||||
<Plus className="size-4!" />
|
||||
<Plus />
|
||||
<span className="text-sm font-medium">New project</span>
|
||||
</Button>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ export default function ProjectsPage() {
|
|||
href="/projects"
|
||||
className="flex items-center gap-3 rounded-2xl bg-blue-50/50 px-4 py-3 text-sm font-medium text-[#00A3FF]"
|
||||
>
|
||||
<LayoutGrid className="h-5 w-5" />
|
||||
<LayoutGrid className="size-5" />
|
||||
Projects
|
||||
</a>
|
||||
<div className="px-4 pt-6 pb-2">
|
||||
|
|
@ -122,14 +122,14 @@ export default function ProjectsPage() {
|
|||
href="/projects"
|
||||
className="flex items-center gap-3 rounded-2xl px-4 py-3 text-sm font-medium text-slate-500 hover:bg-slate-50 hover:text-slate-900"
|
||||
>
|
||||
<Folder className="h-5 w-5 text-slate-400" />
|
||||
<Folder className="size-5 text-slate-400" />
|
||||
Marketing
|
||||
</a>
|
||||
<a
|
||||
href="/projects"
|
||||
className="flex items-center gap-3 rounded-2xl px-4 py-3 text-sm font-medium text-slate-500 hover:bg-slate-50 hover:text-slate-900"
|
||||
>
|
||||
<Folder className="h-5 w-5 text-slate-400" />
|
||||
<Folder className="size-5 text-slate-400" />
|
||||
Social media
|
||||
</a>
|
||||
</nav>
|
||||
|
|
@ -143,7 +143,7 @@ export default function ProjectsPage() {
|
|||
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="group relative">
|
||||
<Search className="absolute top-1/2 left-3.5 h-4 w-4 -translate-y-1/2 text-slate-400" />
|
||||
<Search className="absolute top-1/2 left-3.5 size-4 -translate-y-1/2 text-slate-400" />
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Search..."
|
||||
|
|
@ -157,7 +157,7 @@ export default function ProjectsPage() {
|
|||
className="rounded-full bg-slate-100 p-2 text-slate-900"
|
||||
aria-label="Grid view"
|
||||
>
|
||||
<LayoutGrid className="h-4 w-4" aria-hidden="true">
|
||||
<LayoutGrid className="size-4" aria-hidden="true">
|
||||
<title>Grid view</title>
|
||||
</LayoutGrid>
|
||||
</button>
|
||||
|
|
@ -166,7 +166,7 @@ export default function ProjectsPage() {
|
|||
className="rounded-full p-2 text-slate-400 hover:text-slate-600"
|
||||
aria-label="List view"
|
||||
>
|
||||
<List className="h-4 w-4" aria-hidden="true">
|
||||
<List className="size-4" aria-hidden="true">
|
||||
<title>List view</title>
|
||||
</List>
|
||||
</button>
|
||||
|
|
@ -176,7 +176,7 @@ export default function ProjectsPage() {
|
|||
type="button"
|
||||
className="flex items-center gap-2 rounded-full bg-[#00A3FF] px-5 py-2.5 text-sm font-semibold text-white hover:bg-[#008BE0] active:scale-95"
|
||||
>
|
||||
<Plus className="h-4 w-4" />
|
||||
<Plus className="size-4" />
|
||||
New project
|
||||
</button>
|
||||
</div>
|
||||
|
|
@ -226,7 +226,7 @@ export default function ProjectsPage() {
|
|||
<div className="project-select-wrapper absolute top-4 left-4 z-20">
|
||||
<input
|
||||
type="checkbox"
|
||||
className="custom-checkbox project-select h-6 w-6 cursor-pointer shadow-md"
|
||||
className="custom-checkbox project-select size-6 cursor-pointer shadow-md"
|
||||
checked={isSelected}
|
||||
onChange={({ currentTarget }) => {
|
||||
toggleProjectSelection({
|
||||
|
|
@ -243,7 +243,7 @@ export default function ProjectsPage() {
|
|||
className="rounded-full bg-white/90 p-2 text-slate-600 backdrop-blur-sm hover:bg-white hover:text-[#00A3FF]"
|
||||
aria-label="Project menu"
|
||||
>
|
||||
<MoreHorizontal className="h-4 w-4" aria-hidden="true">
|
||||
<MoreHorizontal className="size-4" aria-hidden="true">
|
||||
<title>Project menu</title>
|
||||
</MoreHorizontal>
|
||||
</button>
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ function SponsorCard({ sponsor }: { sponsor: Sponsor }) {
|
|||
href={sponsor.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="h-full w-full"
|
||||
className="size-full"
|
||||
>
|
||||
<Card className="h-full">
|
||||
<CardContent className="flex h-full flex-col justify-center gap-8 p-8">
|
||||
|
|
@ -67,7 +67,7 @@ function SponsorCard({ sponsor }: { sponsor: Sponsor }) {
|
|||
<h3 className="text-xl font-semibold group-hover:underline">
|
||||
{sponsor.name}
|
||||
</h3>
|
||||
<ExternalLink className="text-muted-foreground h-4 w-4" />
|
||||
<ExternalLink className="text-muted-foreground size-4" />
|
||||
</div>
|
||||
<p className="text-muted-foreground">{sponsor.description}</p>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ export function MediaDragOverlay({
|
|||
|
||||
return (
|
||||
<button
|
||||
className="bg-foreground/5 hover:bg-foreground/10 flex h-full w-full flex-col items-center justify-center gap-4 rounded-lg p-8 text-center transition-all duration-200"
|
||||
className="bg-foreground/5 hover:bg-foreground/10 flex size-full flex-col items-center justify-center gap-4 rounded-lg p-8 text-center transition-all duration-200"
|
||||
type="button"
|
||||
disabled={isProcessing || !onClick}
|
||||
onClick={(event) => handleClick({ event })}
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ export function TabBar() {
|
|||
<div className="relative flex">
|
||||
<div
|
||||
ref={scrollRef}
|
||||
className="scrollbar-hidden relative flex h-full w-full flex-col items-center justify-start gap-5 overflow-y-auto px-4 py-4"
|
||||
className="scrollbar-hidden relative flex size-full flex-col items-center justify-start gap-5 overflow-y-auto px-4 py-4"
|
||||
>
|
||||
{TAB_KEYS.map((tabKey) => {
|
||||
const tab = tabs[tabKey];
|
||||
|
|
|
|||
|
|
@ -342,7 +342,7 @@ export function MediaView() {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div className="scrollbar-thin h-full w-full overflow-y-auto pt-1">
|
||||
<div className="scrollbar-thin size-full overflow-y-auto pt-1">
|
||||
<div className="w-full flex-1 p-3 pt-0">
|
||||
{isDragOver || filteredMediaItems.length === 0 ? (
|
||||
<MediaDragOverlay
|
||||
|
|
|
|||
|
|
@ -407,7 +407,7 @@ function SavedSoundsView() {
|
|||
return (
|
||||
<div className="bg-panel flex h-full flex-col items-center justify-center gap-3 p-4">
|
||||
<HeartIcon
|
||||
className="text-muted-foreground h-10 w-10"
|
||||
className="text-muted-foreground size-10"
|
||||
strokeWidth={1.5}
|
||||
/>
|
||||
<div className="flex flex-col gap-2 text-center">
|
||||
|
|
@ -524,7 +524,7 @@ function AudioItem({ sound, isPlaying, onPlay }: AudioItemProps) {
|
|||
className="flex min-w-0 flex-1 items-center gap-3 text-left"
|
||||
onClick={handleClick}
|
||||
>
|
||||
<div className="bg-accent relative flex h-12 w-12 shrink-0 items-center justify-center overflow-hidden rounded-md">
|
||||
<div className="bg-accent relative flex size-12 shrink-0 items-center justify-center overflow-hidden rounded-md">
|
||||
<div className="from-primary/20 absolute inset-0 bg-gradient-to-br to-transparent" />
|
||||
{isPlaying ? (
|
||||
<PauseIcon className="size-5" />
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ function EmptyView({ message }: { message: string }) {
|
|||
return (
|
||||
<div className="bg-panel flex h-full flex-col items-center justify-center gap-3 p-4">
|
||||
<StickerIcon
|
||||
className="text-muted-foreground h-10 w-10"
|
||||
className="text-muted-foreground size-10"
|
||||
strokeWidth={1.5}
|
||||
/>
|
||||
<div className="flex flex-col gap-2 text-center">
|
||||
|
|
@ -342,7 +342,7 @@ function StickersContentView({ category }: { category: StickerCategory }) {
|
|||
<button
|
||||
type="button"
|
||||
onClick={clearRecentStickers}
|
||||
className="hover:bg-accent ml-auto flex h-5 w-5 items-center justify-center rounded p-0"
|
||||
className="hover:bg-accent ml-auto flex size-5 items-center justify-center rounded p-0"
|
||||
>
|
||||
<X className="text-muted-foreground size-3" />
|
||||
</button>
|
||||
|
|
@ -376,7 +376,7 @@ function StickersContentView({ category }: { category: StickerCategory }) {
|
|||
/>
|
||||
) : (
|
||||
<div className="flex items-center justify-center py-8">
|
||||
<Loader2 className="text-muted-foreground h-6 w-6 animate-spin" />
|
||||
<Loader2 className="text-muted-foreground size-6 animate-spin" />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
|
@ -489,7 +489,7 @@ function CollectionItem({ title, subtitle, onClick }: CollectionItemProps) {
|
|||
<p className="font-medium">{title}</p>
|
||||
<p className="text-muted-foreground text-xs">{subtitle}</p>
|
||||
</div>
|
||||
<ArrowRight className="size-4" />
|
||||
<ArrowRight />
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
|
@ -522,13 +522,13 @@ function StickerItem({
|
|||
const collectionPrefix = iconName.split(":")[0];
|
||||
|
||||
const preview = imageError ? (
|
||||
<div className="flex h-full w-full items-center justify-center p-2">
|
||||
<div className="flex size-full items-center justify-center p-2">
|
||||
<span className="text-muted-foreground text-center text-xs break-all">
|
||||
{displayName}
|
||||
</span>
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex h-full w-full items-center justify-center p-4">
|
||||
<div className="flex size-full items-center justify-center p-4">
|
||||
<Image
|
||||
src={
|
||||
hostIndex === 0
|
||||
|
|
@ -542,7 +542,7 @@ function StickerItem({
|
|||
alt={displayName}
|
||||
width={64}
|
||||
height={64}
|
||||
className="h-full w-full object-contain"
|
||||
className="size-full object-contain"
|
||||
style={
|
||||
capSize
|
||||
? {
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ export function DraggableItem({
|
|||
ratio={1}
|
||||
className="ring-primary relative overflow-hidden rounded-md shadow-2xl ring-3"
|
||||
>
|
||||
<div className="h-full w-full [&_img]:h-full [&_img]:w-full [&_img]:rounded-none [&_img]:object-cover">
|
||||
<div className="size-full [&_img]:size-full [&_img]:rounded-none [&_img]:object-cover">
|
||||
{preview}
|
||||
</div>
|
||||
{shouldShowPlusOnDrag && (
|
||||
|
|
@ -222,7 +222,7 @@ function PlusButton({
|
|||
}}
|
||||
title={tooltipText}
|
||||
>
|
||||
<Plus className="size-4!" />
|
||||
<Plus />
|
||||
</Button>
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,7 @@
|
|||
"use client";
|
||||
|
||||
import { Button } from "../ui/button";
|
||||
import {
|
||||
ChevronDown,
|
||||
ArrowLeft,
|
||||
SquarePen,
|
||||
Trash,
|
||||
Loader2,
|
||||
} from "lucide-react";
|
||||
import { ChevronDown } from "lucide-react";
|
||||
import { KeyboardShortcutsHelp } from "../keyboard-shortcuts-help";
|
||||
import { useState } from "react";
|
||||
import {
|
||||
|
|
@ -27,7 +21,7 @@ import { ThemeToggle } from "../theme-toggle";
|
|||
import { SOCIAL_LINKS } from "@/constants/site-constants";
|
||||
import { toast } from "sonner";
|
||||
import { useEditor } from "@/hooks/use-editor";
|
||||
import { PencilIcon } from "@opencut/ui/icons";
|
||||
import { OcLeftArrowIcon, OcPencilIcon, OcTrashIcon } from "@opencut/ui/icons";
|
||||
|
||||
export function EditorHeader() {
|
||||
return (
|
||||
|
|
@ -125,18 +119,14 @@ function ProjectDropdown() {
|
|||
onClick={handleExit}
|
||||
disabled={isExiting}
|
||||
>
|
||||
{isExiting ? (
|
||||
<Loader2 className="h-4 w-4 animate-spin" />
|
||||
) : (
|
||||
<ArrowLeft className="h-4 w-4" />
|
||||
)}
|
||||
<OcLeftArrowIcon className="size-4" />
|
||||
Projects
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
className="flex items-center gap-1.5"
|
||||
onClick={() => setIsRenameDialogOpen(true)}
|
||||
>
|
||||
<PencilIcon className="h-4 w-4" />
|
||||
<OcPencilIcon className="size-4" />
|
||||
Rename project
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
|
|
@ -144,7 +134,7 @@ function ProjectDropdown() {
|
|||
className="flex items-center gap-1.5"
|
||||
onClick={() => setIsDeleteDialogOpen(true)}
|
||||
>
|
||||
<Trash className="h-4 w-4" />
|
||||
<OcTrashIcon className="size-4" />
|
||||
Delete Project
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuSeparator />
|
||||
|
|
@ -155,7 +145,7 @@ function ProjectDropdown() {
|
|||
rel="noopener noreferrer"
|
||||
className="flex items-center gap-1.5"
|
||||
>
|
||||
<FaDiscord className="h-4 w-4" />
|
||||
<FaDiscord className="size-4" />
|
||||
Discord
|
||||
</Link>
|
||||
</DropdownMenuItem>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { TransitionUpIcon } from "@opencut/ui/icons";
|
||||
import { OcTransitionUpIcon } from "@opencut/ui/icons";
|
||||
import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover";
|
||||
import { Button } from "../ui/button";
|
||||
import { Label } from "../ui/label";
|
||||
|
|
@ -53,9 +53,9 @@ export function ExportButton() {
|
|||
}}
|
||||
>
|
||||
<div className="relative flex items-center gap-1.5 rounded-[0.8rem] bg-linear-270 from-[#2567EC] to-[#37B6F7] px-4 py-1 shadow-[0_1px_3px_0px_rgba(0,0,0,0.65)]">
|
||||
<TransitionUpIcon className="z-50" />
|
||||
<OcTransitionUpIcon className="z-50" />
|
||||
<span className="z-50 text-[0.875rem]">Export</span>
|
||||
<div className="absolute top-0 left-0 z-10 flex h-full w-full items-center justify-center rounded-[0.8rem] bg-linear-to-t from-white/0 to-white/50">
|
||||
<div className="absolute top-0 left-0 z-10 flex size-full items-center justify-center rounded-[0.8rem] bg-linear-to-t from-white/0 to-white/50">
|
||||
<div className="absolute top-[0.08rem] z-50 h-[calc(100%-2px)] w-[calc(100%-2px)] rounded-[0.8rem] bg-linear-270 from-[#2567EC] to-[#37B6F7]"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -240,7 +240,7 @@ function ExportPopover({
|
|||
</div>
|
||||
|
||||
<Button onClick={handleExport} className="w-full gap-2">
|
||||
<Download className="h-4 w-4" />
|
||||
<Download className="size-4" />
|
||||
Export
|
||||
</Button>
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ function TikTokGuide() {
|
|||
<Image
|
||||
src="/platform-guides/tiktok-blueprint.png"
|
||||
alt="TikTok layout guide"
|
||||
className="absolute inset-0 h-full w-full object-contain"
|
||||
className="absolute inset-0 size-full object-contain"
|
||||
draggable={false}
|
||||
fill
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ export function MigrationDialog() {
|
|||
</DialogHeader>
|
||||
|
||||
<div className="flex items-center justify-center py-4">
|
||||
<Loader2 className="text-muted-foreground h-8 w-8 animate-spin" />
|
||||
<Loader2 className="text-muted-foreground size-8 animate-spin" />
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ function NextButton({
|
|||
return (
|
||||
<Button onClick={onClick} variant="default" className="w-full">
|
||||
{children}
|
||||
<ArrowRightIcon className="h-4 w-4" />
|
||||
<ArrowRightIcon className="size-4" />
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ function EmptyView() {
|
|||
return (
|
||||
<div className="bg-panel flex h-full flex-col items-center justify-center gap-3 p-4">
|
||||
<SquareSlashIcon
|
||||
className="text-muted-foreground h-10 w-10"
|
||||
className="text-muted-foreground size-10"
|
||||
strokeWidth={1.5}
|
||||
/>
|
||||
<div className="flex flex-col gap-2 text-center">
|
||||
|
|
|
|||
|
|
@ -159,7 +159,7 @@ export function ScenesView({ children }: { children: React.ReactNode }) {
|
|||
<div className="flex items-center gap-2">
|
||||
{((isSelectMode && selectedScenes.has(scene.id)) ||
|
||||
(!isSelectMode && currentScene?.id === scene.id)) && (
|
||||
<Check className="h-4 w-4" />
|
||||
<Check className="size-4" />
|
||||
)}
|
||||
</div>
|
||||
</Button>
|
||||
|
|
|
|||
|
|
@ -260,7 +260,7 @@ export function Timeline() {
|
|||
className="bg-panel z-100 w-28 shrink-0 overflow-y-auto border-r"
|
||||
style={{ paddingTop: TIMELINE_CONSTANTS.PADDING_TOP }}
|
||||
>
|
||||
<ScrollArea className="h-full w-full" ref={trackLabelsScrollRef}>
|
||||
<ScrollArea className="size-full" ref={trackLabelsScrollRef}>
|
||||
<div className="flex flex-col gap-1">
|
||||
{tracks.map((track) => (
|
||||
<div
|
||||
|
|
@ -344,7 +344,7 @@ export function Timeline() {
|
|||
/>
|
||||
|
||||
<ScrollArea
|
||||
className="h-full w-full"
|
||||
className="size-full"
|
||||
ref={tracksScrollRef}
|
||||
onMouseDown={(event) => {
|
||||
const isDirectTarget = event.target === event.currentTarget;
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ export function Footer() {
|
|||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<FaGithub className="h-5 w-5" />
|
||||
<FaGithub className="size-5" />
|
||||
</Link>
|
||||
<Link
|
||||
href={SOCIAL_LINKS.x}
|
||||
|
|
@ -64,7 +64,7 @@ export function Footer() {
|
|||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<RiTwitterXLine className="h-5 w-5" />
|
||||
<RiTwitterXLine className="size-5" />
|
||||
</Link>
|
||||
<Link
|
||||
href={SOCIAL_LINKS.discord}
|
||||
|
|
@ -72,7 +72,7 @@ export function Footer() {
|
|||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<RiDiscordFill className="h-5 w-5" />
|
||||
<RiDiscordFill className="size-5" />
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { Button } from "./ui/button";
|
||||
import { GithubIcon } from "@opencut/ui/icons";
|
||||
import { OcGithubIcon } from "@opencut/ui/icons";
|
||||
import { ExternalLink } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
import { SOCIAL_LINKS } from "@/constants/site-constants";
|
||||
|
|
@ -24,7 +24,7 @@ export function GitHubContributeSection({
|
|||
rel="noopener noreferrer"
|
||||
>
|
||||
<Button className="w-full" size="lg">
|
||||
<GithubIcon className="h-4 w-4" />
|
||||
<OcGithubIcon className="size-4" />
|
||||
Start contributing
|
||||
</Button>
|
||||
</Link>
|
||||
|
|
@ -34,7 +34,7 @@ export function GitHubContributeSection({
|
|||
rel="noopener noreferrer"
|
||||
>
|
||||
<Button variant="outline" className="w-full" size="lg">
|
||||
<ExternalLink className="h-4 w-4" />
|
||||
<ExternalLink className="size-4" />
|
||||
Report issues
|
||||
</Button>
|
||||
</Link>
|
||||
|
|
|
|||
|
|
@ -7,12 +7,13 @@ import { Button } from "./ui/button";
|
|||
import { ArrowRight } from "lucide-react";
|
||||
import Image from "next/image";
|
||||
import { ThemeToggle } from "./theme-toggle";
|
||||
import { GithubIcon, MenuIcon } from "@opencut/ui/icons";
|
||||
import { OcGithubIcon, OcMenuIcon } from "@opencut/ui/icons";
|
||||
import { cn } from "@/utils/ui";
|
||||
import { DEFAULT_LOGO_URL, SOCIAL_LINKS } from "@/constants/site-constants";
|
||||
|
||||
export function Header() {
|
||||
const [isMenuOpen, setIsMenuOpen] = useState(false);
|
||||
const closeMenu = () => setIsMenuOpen(false);
|
||||
|
||||
const links = [
|
||||
{
|
||||
|
|
@ -61,20 +62,20 @@ export function Header() {
|
|||
className="flex items-center justify-center p-0"
|
||||
onClick={() => setIsMenuOpen(!isMenuOpen)}
|
||||
>
|
||||
<MenuIcon size={30} />
|
||||
<OcMenuIcon size={30} />
|
||||
</Button>
|
||||
</div>
|
||||
<div className="hidden items-center gap-3 md:flex">
|
||||
<Link href={SOCIAL_LINKS.github}>
|
||||
<Button className="bg-background text-sm" variant="outline">
|
||||
<GithubIcon className="h-4 w-4" />
|
||||
<OcGithubIcon className="size-4" />
|
||||
31k+
|
||||
</Button>
|
||||
</Link>
|
||||
<Link href="/projects">
|
||||
<Button className="text-sm">
|
||||
Projects
|
||||
<ArrowRight className="h-4 w-4" />
|
||||
<ArrowRight className="size-4" />
|
||||
</Button>
|
||||
</Link>
|
||||
<ThemeToggle />
|
||||
|
|
@ -86,9 +87,24 @@ export function Header() {
|
|||
"transition-opacity duration-150",
|
||||
isMenuOpen && "pointer-events-auto opacity-100",
|
||||
)}
|
||||
onClick={() => setIsMenuOpen(false)}
|
||||
>
|
||||
<div className="relative h-full">
|
||||
<button
|
||||
type="button"
|
||||
aria-label="Close menu"
|
||||
className="absolute inset-0"
|
||||
onClick={closeMenu}
|
||||
onKeyDown={(event) => {
|
||||
if (
|
||||
event.key === "Enter" ||
|
||||
event.key === " " ||
|
||||
event.key === "Escape"
|
||||
) {
|
||||
event.preventDefault();
|
||||
closeMenu();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<nav className="flex flex-col gap-3 px-6 pt-[5rem]">
|
||||
{links.map((link, index) => (
|
||||
<motion.div
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ export function KeyboardShortcutsHelp() {
|
|||
<DialogContent className="flex max-h-[80vh] max-w-2xl flex-col p-0">
|
||||
<DialogHeader className="flex-shrink-0 p-6 pb-0">
|
||||
<DialogTitle className="flex items-center gap-2">
|
||||
<Keyboard className="h-5 w-5" />
|
||||
<Keyboard className="size-5" />
|
||||
Keyboard Shortcuts
|
||||
</DialogTitle>
|
||||
<DialogDescription>
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ export function Handlebars({ children }: HandlebarsProps) {
|
|||
return (
|
||||
<div className="flex justify-center gap-4 leading-16">
|
||||
<div ref={containerRef} className="relative mt-0.5 -rotate-[2.76deg]">
|
||||
<div className="absolute inset-0 z-10 flex h-full w-full justify-between rounded-2xl border border-yellow-500">
|
||||
<div className="absolute inset-0 z-10 flex size-full justify-between rounded-2xl border border-yellow-500">
|
||||
<div
|
||||
ref={leftHandleRef}
|
||||
className="bg-background absolute left-0 z-20 flex h-full w-7 cursor-ew-resize touch-none items-center justify-center rounded-full border border-yellow-500 select-none"
|
||||
|
|
@ -154,7 +154,7 @@ export function Handlebars({ children }: HandlebarsProps) {
|
|||
</div>
|
||||
|
||||
<span
|
||||
className="relative z-0 inline-flex h-full w-full items-center justify-center rounded-2xl px-9 will-change-auto"
|
||||
className="relative z-0 inline-flex size-full items-center justify-center rounded-2xl px-9 will-change-auto"
|
||||
style={{
|
||||
mask: `linear-gradient(90deg,
|
||||
rgba(255, 255, 255, 0) 0%,
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ export function EditorProvider({ projectId, children }: EditorProviderProps) {
|
|||
return (
|
||||
<div className="bg-background flex h-screen w-screen items-center justify-center">
|
||||
<div className="flex flex-col items-center gap-4">
|
||||
<Loader2 className="text-muted-foreground h-8 w-8 animate-spin" />
|
||||
<Loader2 className="text-muted-foreground size-8 animate-spin" />
|
||||
<p className="text-muted-foreground text-sm">Loading project...</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -101,7 +101,7 @@ export function EditorProvider({ projectId, children }: EditorProviderProps) {
|
|||
return (
|
||||
<div className="bg-background flex h-screen w-screen items-center justify-center">
|
||||
<div className="flex flex-col items-center gap-4">
|
||||
<Loader2 className="text-muted-foreground h-8 w-8 animate-spin" />
|
||||
<Loader2 className="text-muted-foreground size-8 animate-spin" />
|
||||
<p className="text-muted-foreground text-sm">Exiting project...</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ const AccordionTrigger = React.forwardRef<
|
|||
{...props}
|
||||
>
|
||||
{children}
|
||||
<ChevronDown className="text-muted-foreground h-4 w-4 shrink-0 transition-transform duration-200" />
|
||||
<ChevronDown className="text-muted-foreground size-4 shrink-0 transition-transform duration-200" />
|
||||
</AccordionPrimitive.Trigger>
|
||||
</AccordionPrimitive.Header>
|
||||
));
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ const Avatar = React.forwardRef<
|
|||
<AvatarPrimitive.Root
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full",
|
||||
"relative flex size-10 shrink-0 overflow-hidden rounded-full",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
|
@ -26,7 +26,7 @@ const AvatarImage = React.forwardRef<
|
|||
>(({ className, ...props }, ref) => (
|
||||
<AvatarPrimitive.Image
|
||||
ref={ref}
|
||||
className={cn("aspect-square h-full w-full", className)}
|
||||
className={cn("aspect-square size-full", className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
|
|
@ -38,10 +38,10 @@ const AvatarFallback = React.forwardRef<
|
|||
>(({ className, ...props }, ref) => (
|
||||
<AvatarPrimitive.Fallback
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"bg-muted flex h-full w-full items-center justify-center rounded-full",
|
||||
className,
|
||||
)}
|
||||
className={cn(
|
||||
"bg-muted flex size-full items-center justify-center rounded-full",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ const BreadcrumbSeparator = ({
|
|||
<li
|
||||
role="presentation"
|
||||
aria-hidden="true"
|
||||
className={cn("[&>svg]:h-3.5 [&>svg]:w-3.5", className)}
|
||||
className={cn("[&>svg]:size-3.5", className)}
|
||||
{...props}
|
||||
>
|
||||
{children ?? <ChevronRight />}
|
||||
|
|
@ -95,10 +95,10 @@ const BreadcrumbEllipsis = ({
|
|||
<span
|
||||
role="presentation"
|
||||
aria-hidden="true"
|
||||
className={cn("flex h-9 w-9 items-center justify-center", className)}
|
||||
className={cn("flex size-9 items-center justify-center", className)}
|
||||
{...props}
|
||||
>
|
||||
<MoreHorizontal className="h-4 w-4" />
|
||||
<MoreHorizontal className="size-4" />
|
||||
<span className="sr-only">More</span>
|
||||
</span>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ const buttonVariants = cva(
|
|||
default: "h-9 px-4 py-2",
|
||||
sm: "h-8 rounded-full px-3 text-xs",
|
||||
lg: "h-10 rounded-full p-5",
|
||||
icon: "h-7 w-7",
|
||||
icon: "size-7",
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ function Calendar({
|
|||
nav: "space-x-1 flex items-center",
|
||||
nav_button: cn(
|
||||
buttonVariants({ variant: "outline" }),
|
||||
"h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100",
|
||||
"size-7 bg-transparent p-0 opacity-50 hover:opacity-100",
|
||||
),
|
||||
nav_button_previous: "absolute left-1",
|
||||
nav_button_next: "absolute right-1",
|
||||
|
|
@ -44,7 +44,7 @@ function Calendar({
|
|||
),
|
||||
day: cn(
|
||||
buttonVariants({ variant: "text" }),
|
||||
"h-8 w-8 p-0 font-normal aria-selected:opacity-100",
|
||||
"size-8 p-0 font-normal aria-selected:opacity-100",
|
||||
),
|
||||
day_range_start: "day-range-start",
|
||||
day_range_end: "day-range-end",
|
||||
|
|
@ -60,8 +60,8 @@ function Calendar({
|
|||
...classNames,
|
||||
}}
|
||||
components={{
|
||||
IconLeft: ({ ...props }) => <ChevronLeft className="h-4 w-4" />,
|
||||
IconRight: ({ ...props }) => <ChevronRight className="h-4 w-4" />,
|
||||
IconLeft: ({ ...props }) => <ChevronLeft className="size-4" />,
|
||||
IconRight: ({ ...props }) => <ChevronRight className="size-4" />,
|
||||
}}
|
||||
{...props}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -206,7 +206,7 @@ const CarouselPrevious = React.forwardRef<
|
|||
variant={variant}
|
||||
size={size}
|
||||
className={cn(
|
||||
"absolute h-8 w-8 rounded-full",
|
||||
"absolute size-8 rounded-full",
|
||||
orientation === "horizontal"
|
||||
? "top-1/2 -left-12 -translate-y-1/2"
|
||||
: "-top-12 left-1/2 -translate-x-1/2 rotate-90",
|
||||
|
|
@ -216,7 +216,7 @@ const CarouselPrevious = React.forwardRef<
|
|||
onClick={scrollPrev}
|
||||
{...props}
|
||||
>
|
||||
<ArrowLeft className="h-4 w-4" />
|
||||
<ArrowLeft className="size-4" />
|
||||
<span className="sr-only">Previous slide</span>
|
||||
</Button>
|
||||
);
|
||||
|
|
@ -235,7 +235,7 @@ const CarouselNext = React.forwardRef<
|
|||
variant={variant}
|
||||
size={size}
|
||||
className={cn(
|
||||
"absolute h-8 w-8 rounded-full",
|
||||
"absolute size-8 rounded-full",
|
||||
orientation === "horizontal"
|
||||
? "top-1/2 -right-12 -translate-y-1/2"
|
||||
: "-bottom-12 left-1/2 -translate-x-1/2 rotate-90",
|
||||
|
|
@ -245,7 +245,7 @@ const CarouselNext = React.forwardRef<
|
|||
onClick={scrollNext}
|
||||
{...props}
|
||||
>
|
||||
<ArrowRight className="h-4 w-4" />
|
||||
<ArrowRight className="size-4" />
|
||||
<span className="sr-only">Next slide</span>
|
||||
</Button>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -199,7 +199,7 @@ const ChartTooltipContent = React.forwardRef<
|
|||
<div
|
||||
key={item.dataKey}
|
||||
className={cn(
|
||||
"[&>svg]:text-muted-foreground flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5",
|
||||
"[&>svg]:text-muted-foreground flex w-full flex-wrap items-stretch gap-2 [&>svg]:size-2.5",
|
||||
indicator === "dot" && "items-center",
|
||||
)}
|
||||
>
|
||||
|
|
@ -215,7 +215,7 @@ const ChartTooltipContent = React.forwardRef<
|
|||
className={cn(
|
||||
"shrink-0 rounded-[2px] border-(--color-border) bg-(--color-bg)",
|
||||
{
|
||||
"h-2.5 w-2.5": indicator === "dot",
|
||||
"size-2.5": indicator === "dot",
|
||||
"w-1": indicator === "line",
|
||||
"w-0 border-[1.5px] border-dashed bg-transparent":
|
||||
indicator === "dashed",
|
||||
|
|
@ -298,14 +298,14 @@ const ChartLegendContent = React.forwardRef<
|
|||
<div
|
||||
key={item.value}
|
||||
className={cn(
|
||||
"[&>svg]:text-muted-foreground flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3",
|
||||
"[&>svg]:text-muted-foreground flex items-center gap-1.5 [&>svg]:size-3",
|
||||
)}
|
||||
>
|
||||
{itemConfig?.icon && !hideIcon ? (
|
||||
<itemConfig.icon />
|
||||
) : (
|
||||
<div
|
||||
className="h-2 w-2 shrink-0 rounded-[2px]"
|
||||
className="size-2 shrink-0 rounded-[2px]"
|
||||
style={{
|
||||
backgroundColor: item.color,
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ const Checkbox = React.forwardRef<
|
|||
<CheckboxPrimitive.Root
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"peer border-primary focus-visible:ring-ring data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground h-4 w-4 shrink-0 rounded-sm border shadow-sm focus-visible:ring-1 focus-visible:outline-hidden disabled:cursor-not-allowed disabled:opacity-50",
|
||||
"peer border-primary focus-visible:ring-ring data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground size-4 shrink-0 rounded-sm border shadow-sm focus-visible:ring-1 focus-visible:outline-hidden disabled:cursor-not-allowed disabled:opacity-50",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
|
@ -21,7 +21,7 @@ const Checkbox = React.forwardRef<
|
|||
<CheckboxPrimitive.Indicator
|
||||
className={cn("flex items-center justify-center text-current")}
|
||||
>
|
||||
<Check className="h-4 w-4" />
|
||||
<Check className="size-4" />
|
||||
</CheckboxPrimitive.Indicator>
|
||||
</CheckboxPrimitive.Root>
|
||||
));
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ const Command = React.forwardRef<
|
|||
<CommandPrimitive
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden rounded-md",
|
||||
"bg-popover text-popover-foreground flex size-full flex-col overflow-hidden rounded-md",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
|
@ -26,7 +26,7 @@ const CommandDialog = ({ children, ...props }: DialogProps) => {
|
|||
return (
|
||||
<Dialog {...props}>
|
||||
<DialogContent className="overflow-hidden p-0">
|
||||
<Command className="[&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group]]:px-2 [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5">
|
||||
<Command className="[&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group]]:px-2 [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-input-wrapper]_svg]:size-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:size-5">
|
||||
{children}
|
||||
</Command>
|
||||
</DialogContent>
|
||||
|
|
@ -39,7 +39,7 @@ const CommandInput = React.forwardRef<
|
|||
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<div className="flex items-center border-b px-3" cmdk-input-wrapper="">
|
||||
<Search className="mr-2 h-4 w-4 shrink-0 opacity-50" />
|
||||
<Search className="mr-2 size-4 shrink-0 opacity-50" />
|
||||
<CommandPrimitive.Input
|
||||
ref={ref}
|
||||
className={cn(
|
||||
|
|
|
|||
|
|
@ -121,9 +121,9 @@ const ContextMenuCheckboxItem = React.forwardRef<
|
|||
checked={checked}
|
||||
{...props}
|
||||
>
|
||||
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
||||
<span className="absolute left-2 flex size-3.5 items-center justify-center">
|
||||
<ContextMenuPrimitive.ItemIndicator>
|
||||
<Check className="h-4 w-4" />
|
||||
<Check className="size-4" />
|
||||
</ContextMenuPrimitive.ItemIndicator>
|
||||
</span>
|
||||
{children}
|
||||
|
|
@ -143,9 +143,9 @@ const ContextMenuRadioItem = React.forwardRef<
|
|||
className={cn(contextMenuItemVariants({ variant }), "pr-2 pl-8", className)}
|
||||
{...props}
|
||||
>
|
||||
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
||||
<span className="absolute left-2 flex size-3.5 items-center justify-center">
|
||||
<ContextMenuPrimitive.ItemIndicator>
|
||||
<Circle className="h-2 w-2 fill-current" />
|
||||
<Circle className="size-2 fill-current" />
|
||||
</ContextMenuPrimitive.ItemIndicator>
|
||||
</span>
|
||||
{children}
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ const DialogContent = React.forwardRef<
|
|||
>
|
||||
{children}
|
||||
<DialogPrimitive.Close className="ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 cursor-pointer opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none">
|
||||
<X className="h-4 w-4" />
|
||||
<X className="size-4" />
|
||||
<span className="sr-only">Close</span>
|
||||
</DialogPrimitive.Close>
|
||||
</DialogPrimitive.Content>
|
||||
|
|
|
|||
|
|
@ -136,9 +136,9 @@ const DropdownMenuCheckboxItem = React.forwardRef<
|
|||
{...props}
|
||||
>
|
||||
{children}
|
||||
<span className="absolute right-2 flex h-3.5 w-3.5 items-center justify-center">
|
||||
<span className="absolute right-2 flex size-3.5 items-center justify-center">
|
||||
<DropdownMenuPrimitive.ItemIndicator>
|
||||
<Check className="h-4 w-4" />
|
||||
<Check className="size-4" />
|
||||
</DropdownMenuPrimitive.ItemIndicator>
|
||||
</span>
|
||||
</DropdownMenuPrimitive.CheckboxItem>
|
||||
|
|
@ -162,9 +162,9 @@ const DropdownMenuRadioItem = React.forwardRef<
|
|||
)}
|
||||
{...props}
|
||||
>
|
||||
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
||||
<span className="absolute left-2 flex size-3.5 items-center justify-center">
|
||||
<DropdownMenuPrimitive.ItemIndicator>
|
||||
<Circle className="h-2 w-2 fill-current" />
|
||||
<Circle className="size-2 fill-current" />
|
||||
</DropdownMenuPrimitive.ItemIndicator>
|
||||
</span>
|
||||
{children}
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ export function InputWithBack({
|
|||
}}
|
||||
transition={smoothTransition}
|
||||
>
|
||||
<Search className="text-muted-foreground absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2" />
|
||||
<Search className="text-muted-foreground absolute top-1/2 left-3 size-4 -translate-y-1/2" />
|
||||
<Input
|
||||
placeholder={placeholder}
|
||||
className="bg-panel-accent w-full pl-9"
|
||||
|
|
|
|||
|
|
@ -101,9 +101,9 @@ const Input = forwardRef<HTMLInputElement, InputProps>(
|
|||
aria-label={showPassword ? "Hide password" : "Show password"}
|
||||
>
|
||||
{showPassword ? (
|
||||
<Eye className="h-4 w-4" />
|
||||
<Eye className="size-4" />
|
||||
) : (
|
||||
<EyeOff className="h-4 w-4" />
|
||||
<EyeOff className="size-4" />
|
||||
)}
|
||||
</Button>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ const MenubarSubTrigger = React.forwardRef<
|
|||
{...props}
|
||||
>
|
||||
{children}
|
||||
<ChevronRight className="ml-auto h-4 w-4" />
|
||||
<ChevronRight className="ml-auto size-4" />
|
||||
</MenubarPrimitive.SubTrigger>
|
||||
));
|
||||
MenubarSubTrigger.displayName = MenubarPrimitive.SubTrigger.displayName;
|
||||
|
|
@ -138,9 +138,9 @@ const MenubarCheckboxItem = React.forwardRef<
|
|||
checked={checked}
|
||||
{...props}
|
||||
>
|
||||
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
||||
<span className="absolute left-2 flex size-3.5 items-center justify-center">
|
||||
<MenubarPrimitive.ItemIndicator>
|
||||
<Check className="h-4 w-4" />
|
||||
<Check className="size-4" />
|
||||
</MenubarPrimitive.ItemIndicator>
|
||||
</span>
|
||||
{children}
|
||||
|
|
@ -160,9 +160,9 @@ const MenubarRadioItem = React.forwardRef<
|
|||
)}
|
||||
{...props}
|
||||
>
|
||||
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
||||
<span className="absolute left-2 flex size-3.5 items-center justify-center">
|
||||
<MenubarPrimitive.ItemIndicator>
|
||||
<Circle className="h-4 w-4 fill-current" />
|
||||
<Circle className="size-4 fill-current" />
|
||||
</MenubarPrimitive.ItemIndicator>
|
||||
</span>
|
||||
{children}
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ const NavigationMenuIndicator = React.forwardRef<
|
|||
)}
|
||||
{...props}
|
||||
>
|
||||
<div className="bg-border relative top-[60%] h-2 w-2 rotate-45 rounded-tl-sm shadow-md" />
|
||||
<div className="bg-border relative top-[60%] size-2 rotate-45 rounded-tl-sm shadow-md" />
|
||||
</NavigationMenuPrimitive.Indicator>
|
||||
));
|
||||
NavigationMenuIndicator.displayName =
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ const PaginationPrevious = ({
|
|||
className={cn("gap-1 pl-2.5", className)}
|
||||
{...props}
|
||||
>
|
||||
<ChevronLeft className="h-4 w-4" />
|
||||
<ChevronLeft className="size-4" />
|
||||
<span>Previous</span>
|
||||
</PaginationLink>
|
||||
);
|
||||
|
|
@ -86,7 +86,7 @@ const PaginationNext = ({
|
|||
{...props}
|
||||
>
|
||||
<span>Next</span>
|
||||
<ChevronRight className="h-4 w-4" />
|
||||
<ChevronRight className="size-4" />
|
||||
</PaginationLink>
|
||||
);
|
||||
PaginationNext.displayName = "PaginationNext";
|
||||
|
|
@ -97,10 +97,10 @@ const PaginationEllipsis = ({
|
|||
}: React.ComponentProps<"span">) => (
|
||||
<span
|
||||
aria-hidden
|
||||
className={cn("flex h-9 w-9 items-center justify-center", className)}
|
||||
className={cn("flex size-9 items-center justify-center", className)}
|
||||
{...props}
|
||||
>
|
||||
<MoreHorizontal className="h-4 w-4" />
|
||||
<MoreHorizontal className="size-4" />
|
||||
<span className="sr-only">More pages</span>
|
||||
</span>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ const CountrySelect = ({
|
|||
/>
|
||||
<ChevronsUpDown
|
||||
className={cn(
|
||||
"-mr-2 size-4 opacity-50",
|
||||
"-mr-2 opacity-50",
|
||||
disabled ? "hidden" : "opacity-100",
|
||||
)}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ const Progress = React.forwardRef<
|
|||
{...props}
|
||||
>
|
||||
<ProgressPrimitive.Indicator
|
||||
className="bg-foreground h-full w-full flex-1 transition-all"
|
||||
className="bg-foreground size-full flex-1 transition-all"
|
||||
style={{ transform: `translateX(-${100 - (value || 0)}%)` }}
|
||||
/>
|
||||
</ProgressPrimitive.Root>
|
||||
|
|
|
|||
|
|
@ -28,13 +28,13 @@ const RadioGroupItem = React.forwardRef<
|
|||
<RadioGroupPrimitive.Item
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"border-primary text-primary focus-visible:ring-ring aspect-square h-4 w-4 rounded-full border shadow-sm focus:outline-hidden focus-visible:ring-1 disabled:cursor-not-allowed disabled:opacity-50",
|
||||
"border-primary text-primary focus-visible:ring-ring aspect-square size-4 rounded-full border shadow-sm focus:outline-hidden focus-visible:ring-1 disabled:cursor-not-allowed disabled:opacity-50",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<RadioGroupPrimitive.Indicator className="flex items-center justify-center">
|
||||
<Circle className="fill-primary h-3.5 w-3.5" />
|
||||
<Circle className="fill-primary size-3.5" />
|
||||
</RadioGroupPrimitive.Indicator>
|
||||
</RadioGroupPrimitive.Item>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ const ResizablePanelGroup = ({
|
|||
}: React.ComponentProps<typeof ResizablePrimitive.PanelGroup>) => (
|
||||
<ResizablePrimitive.PanelGroup
|
||||
className={cn(
|
||||
"flex h-full w-full data-[panel-group-direction=vertical]:flex-col",
|
||||
"flex size-full data-[panel-group-direction=vertical]:flex-col",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ const SelectScrollUpButton = React.forwardRef<
|
|||
)}
|
||||
{...props}
|
||||
>
|
||||
<ChevronUp className="h-4 w-4" />
|
||||
<ChevronUp className="size-4" />
|
||||
</SelectPrimitive.ScrollUpButton>
|
||||
));
|
||||
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
|
||||
|
|
@ -77,7 +77,7 @@ const SelectScrollDownButton = React.forwardRef<
|
|||
)}
|
||||
{...props}
|
||||
>
|
||||
<ChevronDown className="h-4 w-4" />
|
||||
<ChevronDown className="size-4" />
|
||||
</SelectPrimitive.ScrollDownButton>
|
||||
));
|
||||
SelectScrollDownButton.displayName =
|
||||
|
|
@ -142,9 +142,9 @@ const SelectItem = React.forwardRef<
|
|||
className={cn(selectItemVariants({ variant }), className)}
|
||||
{...props}
|
||||
>
|
||||
<span className="absolute right-2 flex h-3.5 w-3.5 items-center justify-center">
|
||||
<span className="absolute right-2 flex size-3.5 items-center justify-center">
|
||||
<SelectPrimitive.ItemIndicator>
|
||||
<Check className="h-4 w-4" />
|
||||
<Check className="size-4" />
|
||||
</SelectPrimitive.ItemIndicator>
|
||||
</span>
|
||||
<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
|
||||
|
|
|
|||
|
|
@ -198,7 +198,7 @@ function Sidebar({
|
|||
<SheetTitle>Sidebar</SheetTitle>
|
||||
<SheetDescription>Displays the mobile sidebar.</SheetDescription>
|
||||
</SheetHeader>
|
||||
<div className="flex h-full w-full flex-col">{children}</div>
|
||||
<div className="flex size-full flex-col">{children}</div>
|
||||
</SheetContent>
|
||||
</Sheet>
|
||||
);
|
||||
|
|
@ -243,7 +243,7 @@ function Sidebar({
|
|||
<div
|
||||
data-sidebar="sidebar"
|
||||
data-slot="sidebar-inner"
|
||||
className="bg-sidebar group-data-[variant=floating]:border-sidebar-border flex h-full w-full flex-col group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:shadow-sm"
|
||||
className="bg-sidebar group-data-[variant=floating]:border-sidebar-border flex size-full flex-col group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:shadow-sm"
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ const Slider = React.forwardRef<
|
|||
<SliderPrimitive.Track className="bg-primary/20 relative h-1.5 w-full grow overflow-hidden rounded-full">
|
||||
<SliderPrimitive.Range className="bg-primary absolute h-full" />
|
||||
</SliderPrimitive.Track>
|
||||
<SliderPrimitive.Thumb className="border-primary/50 bg-background focus-visible:ring-ring block h-4 w-4 rounded-full border shadow-sm transition-colors focus-visible:ring-1 focus-visible:outline-hidden disabled:pointer-events-none disabled:opacity-50" />
|
||||
<SliderPrimitive.Thumb className="border-primary/50 bg-background focus-visible:ring-ring block size-4 rounded-full border shadow-sm transition-colors focus-visible:ring-1 focus-visible:outline-hidden disabled:pointer-events-none disabled:opacity-50" />
|
||||
</SliderPrimitive.Root>
|
||||
));
|
||||
Slider.displayName = SliderPrimitive.Root.displayName;
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ const Switch = React.forwardRef<
|
|||
>
|
||||
<SwitchPrimitives.Thumb
|
||||
className={cn(
|
||||
"bg-background pointer-events-none block h-4 w-4 rounded-full shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-4 data-[state=unchecked]:translate-x-0",
|
||||
"bg-background pointer-events-none block size-4 rounded-full shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-4 data-[state=unchecked]:translate-x-0",
|
||||
)}
|
||||
/>
|
||||
</SwitchPrimitives.Root>
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ const ToastClose = React.forwardRef<
|
|||
toast-close=""
|
||||
{...props}
|
||||
>
|
||||
<X className="h-4 w-4" />
|
||||
<X className="size-4" />
|
||||
</ToastPrimitives.Close>
|
||||
));
|
||||
ToastClose.displayName = ToastPrimitives.Close.displayName;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { DataBuddyIcon, MarbleIcon, VercelIcon } from "@opencut/ui/icons";
|
||||
import { OcDataBuddyIcon, OcMarbleIcon, OcVercelIcon } from "@opencut/ui/icons";
|
||||
|
||||
export const SITE_URL = "https://opencut.app";
|
||||
|
||||
|
|
@ -25,19 +25,19 @@ export const EXTERNAL_TOOLS: ExternalTool[] = [
|
|||
description:
|
||||
"Modern headless CMS for content management and the blog for OpenCut",
|
||||
url: "https://marblecms.com?utm_source=opencut",
|
||||
icon: MarbleIcon,
|
||||
icon: OcMarbleIcon,
|
||||
},
|
||||
{
|
||||
name: "Vercel",
|
||||
description: "Platform where we deploy and host OpenCut",
|
||||
url: "https://vercel.com?utm_source=opencut",
|
||||
icon: VercelIcon,
|
||||
icon: OcVercelIcon,
|
||||
},
|
||||
{
|
||||
name: "Databuddy",
|
||||
description: "GDPR compliant analytics and user insights for OpenCut",
|
||||
url: "https://databuddy.cc?utm_source=opencut",
|
||||
icon: DataBuddyIcon,
|
||||
icon: OcDataBuddyIcon,
|
||||
},
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -37,8 +37,8 @@ export const TIMELINE_CONSTANTS = {
|
|||
} as const;
|
||||
|
||||
export const TRACK_ICONS: Record<TrackType, React.ReactNode> = {
|
||||
video: <Video className="text-muted-foreground h-4 w-4 shrink-0" />,
|
||||
text: <TypeIcon className="text-muted-foreground h-4 w-4 shrink-0" />,
|
||||
audio: <Music className="text-muted-foreground h-4 w-4 shrink-0" />,
|
||||
sticker: <Sticker className="text-muted-foreground h-4 w-4 shrink-0" />,
|
||||
video: <Video className="text-muted-foreground size-4 shrink-0" />,
|
||||
text: <TypeIcon className="text-muted-foreground size-4 shrink-0" />,
|
||||
audio: <Music className="text-muted-foreground size-4 shrink-0" />,
|
||||
sticker: <Sticker className="text-muted-foreground size-4 shrink-0" />,
|
||||
} as const;
|
||||
|
|
|
|||
|
|
@ -1,51 +1,51 @@
|
|||
import { createIcon } from "./create-icon";
|
||||
import { ICON_DEFINITIONS } from "./registry";
|
||||
|
||||
export const GoogleIcon = createIcon({
|
||||
export const OcGoogleIcon = createIcon({
|
||||
definition: ICON_DEFINITIONS.google,
|
||||
});
|
||||
|
||||
export const GithubIcon = createIcon({
|
||||
export const OcGithubIcon = createIcon({
|
||||
definition: ICON_DEFINITIONS.github,
|
||||
});
|
||||
|
||||
export const VercelIcon = createIcon({
|
||||
export const OcVercelIcon = createIcon({
|
||||
definition: ICON_DEFINITIONS.vercel,
|
||||
});
|
||||
|
||||
export const DataBuddyIcon = createIcon({
|
||||
export const OcDataBuddyIcon = createIcon({
|
||||
definition: ICON_DEFINITIONS.databuddy,
|
||||
});
|
||||
|
||||
export const MarbleIcon = createIcon({
|
||||
export const OcMarbleIcon = createIcon({
|
||||
definition: ICON_DEFINITIONS.marble,
|
||||
});
|
||||
|
||||
export const BackgroundIcon = createIcon({
|
||||
export const OcBackgroundIcon = createIcon({
|
||||
definition: ICON_DEFINITIONS.background,
|
||||
});
|
||||
|
||||
export const SocialsIcon = createIcon({
|
||||
export const OcSocialsIcon = createIcon({
|
||||
definition: ICON_DEFINITIONS.socials,
|
||||
});
|
||||
|
||||
export const TransitionUpIcon = createIcon({
|
||||
export const OcTransitionUpIcon = createIcon({
|
||||
definition: ICON_DEFINITIONS.transitionUp,
|
||||
});
|
||||
|
||||
export const MenuIcon = createIcon({
|
||||
export const OcMenuIcon = createIcon({
|
||||
definition: ICON_DEFINITIONS.menu,
|
||||
});
|
||||
|
||||
export const PencilIcon = createIcon({
|
||||
export const OcPencilIcon = createIcon({
|
||||
definition: ICON_DEFINITIONS.pencil,
|
||||
});
|
||||
|
||||
export const LeftArrowIcon = createIcon({
|
||||
export const OcLeftArrowIcon = createIcon({
|
||||
definition: ICON_DEFINITIONS.leftArrow,
|
||||
});
|
||||
|
||||
export const TrashIcon = createIcon({
|
||||
export const OcTrashIcon = createIcon({
|
||||
definition: ICON_DEFINITIONS.trash,
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
import type { IconDefinition } from "../types";
|
||||
import { BRAND_ICONS } from "./brand";
|
||||
import { UI_ICONS } from "./ui";
|
||||
import { EDITOR_ICONS } from "./editor";
|
||||
|
||||
export const ICON_DEFINITIONS = {
|
||||
...BRAND_ICONS,
|
||||
...UI_ICONS,
|
||||
...EDITOR_ICONS,
|
||||
} satisfies Record<string, IconDefinition>;
|
||||
|
|
|
|||
18
rules.md
18
rules.md
|
|
@ -15,8 +15,20 @@ Review every point below carefully for files to ensure they follow consistent co
|
|||
13. Booleans must be named like `isSomething` or `hasSomething` or `shouldSomething`. Not `something` or `somethingIs`.
|
||||
14. No text in docs or UI ever uses title case. Example: `Hello World` is wrong. It should be `Hello world`.
|
||||
15. Use `size-10` instead of `h-10 w-10` when the width and height are the same.
|
||||
16. For components that need to subscribe to data from the editor api (`src/core`, `src/managers`), use the `useEditor` hook.
|
||||
17. In react components: store/manager methods should not be passed as props to sub-components. If a sub-component can access the same methods, it should do so. Example:
|
||||
|
||||
16. When using `size-` on an SVG (lucide, react-icons, @opencut/ui/icons, etc.) inside of a <Button> (not <buttom>), make sure to use the `!` modifier to ensure the size is applied correctly. This is becuase the <Button> component has a default size of `size-4` that can only be overridden with the `!` modifier. That also means, don't do `!size-4` since that's the default size.
|
||||
- Example:
|
||||
```tsx
|
||||
<Button>
|
||||
<PlusIcon className="!size-6" /> // This is correct ✅
|
||||
<PlusIcon className="size-6" /> // This is wrong ❌
|
||||
<PlusIcon className="!size-4" /> // This is wrong ❌
|
||||
<span>Add</span>
|
||||
</Button>
|
||||
```
|
||||
|
||||
17. For components that need to subscribe to data from the editor api (`src/core`, `src/managers`), use the `useEditor` hook.
|
||||
18. In react components: store/manager methods should not be passed as props to sub-components. If a sub-component can access the same methods, it should do so. Example:
|
||||
|
||||
```tsx
|
||||
import { useTimelineStore } from "@/stores/timeline-store";
|
||||
|
|
@ -41,7 +53,7 @@ Review every point below carefully for files to ensure they follow consistent co
|
|||
```
|
||||
|
||||
```
|
||||
18. Components render UI. Domain logic (data transformations, business rules, state mutations) lives in hooks, utilities, or managers. Simple interaction logic (gesture detection, modifier keys) can stay in components if not too many lines of code/complex.
|
||||
19. Components render UI. Domain logic (data transformations, business rules, state mutations) lives in hooks, utilities, or managers. Simple interaction logic (gesture detection, modifier keys) can stay in components if not too many lines of code/complex.
|
||||
|
||||
19. Readability matters more than short names in the age of AI coding. Do not shorten names for the sake of "typing less". Nobody is typing code these days. AI agents are. Hence, clarity and readability are the most important things. Example: "element" is better than "el".
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue