@olwiba/cn 0.1.24 → 0.1.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +13 -3
- package/dist/index.js +181 -39
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -120,7 +120,7 @@ declare const badgeVariants: (props?: ({
|
|
|
120
120
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
121
121
|
interface BadgeProps extends React$1.HTMLAttributes<HTMLDivElement>, VariantProps<typeof badgeVariants> {
|
|
122
122
|
disabled?: boolean;
|
|
123
|
-
mode?: "playful"
|
|
123
|
+
mode?: "playful";
|
|
124
124
|
}
|
|
125
125
|
declare function Badge({ className, variant, size, disabled, mode: modeProp, ...props }: BadgeProps): react_jsx_runtime.JSX.Element;
|
|
126
126
|
|
|
@@ -945,10 +945,16 @@ declare const ToggleGroupItem: React$1.ForwardRefExoticComponent<Omit<ToggleGrou
|
|
|
945
945
|
interface AsciiTextProps {
|
|
946
946
|
text?: string;
|
|
947
947
|
accent?: string;
|
|
948
|
+
accents?: Array<{
|
|
949
|
+
text: string;
|
|
950
|
+
color: string;
|
|
951
|
+
}>;
|
|
952
|
+
shine?: string;
|
|
953
|
+
shineColor?: string;
|
|
948
954
|
color?: string;
|
|
949
955
|
accentColor?: string;
|
|
950
956
|
}
|
|
951
|
-
declare function AsciiText({ text, accent, color, accentColor, }: AsciiTextProps): react_jsx_runtime.JSX.Element;
|
|
957
|
+
declare function AsciiText({ text, accent, accents, shine, shineColor, color, accentColor, }: AsciiTextProps): react_jsx_runtime.JSX.Element;
|
|
952
958
|
|
|
953
959
|
declare function useIsMobile(): boolean;
|
|
954
960
|
|
|
@@ -986,7 +992,11 @@ declare function ThemeScript(): react_jsx_runtime.JSX.Element;
|
|
|
986
992
|
|
|
987
993
|
interface EnchantedProps extends React$1.HTMLAttributes<HTMLDivElement> {
|
|
988
994
|
children: React$1.ReactNode;
|
|
995
|
+
/** Only show the glints while the wrapper is hovered. */
|
|
996
|
+
hoverOnly?: boolean;
|
|
997
|
+
/** Overrides the glint colour (defaults to text-primary). */
|
|
998
|
+
glintClassName?: string;
|
|
989
999
|
}
|
|
990
|
-
declare function Enchanted({ children, className, ...props }: EnchantedProps): react_jsx_runtime.JSX.Element;
|
|
1000
|
+
declare function Enchanted({ children, className, hoverOnly, glintClassName, ...props }: EnchantedProps): react_jsx_runtime.JSX.Element;
|
|
991
1001
|
|
|
992
1002
|
export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AsciiText, type AsciiTextProps, AspectRatio, Avatar, AvatarFallback, AvatarImage, Badge, type BadgeProps, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, ButtonGroup, ButtonGroupSeparator, ButtonGroupText, type ButtonProps, Calendar, CalendarDayButton, Card, CardContent, CardDescription, CardFooter, CardHeader, type CardProps, CardTitle, Carousel, type CarouselApi, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious, type ChartConfig, ChartContainer, ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip, ChartTooltipContent, Checkbox, type CheckboxProps, Collapsible, CollapsibleContent, CollapsibleTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, type ConfettiOptions, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle, Enchanted, type EnchantedProps, Field, FieldContent, FieldDescription, FieldError, FieldGroup, FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTitle, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, HoverCard, HoverCardContent, HoverCardTrigger, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea, InputOTP, InputOTPGroup, type InputOTPProps, InputOTPSeparator, InputOTPSlot, type InputProps, Item, ItemActions, ItemContent, ItemDescription, ItemFooter, ItemGroup, ItemHeader, ItemMedia, ItemSeparator, ItemTitle, Kbd, KbdGroup, Label, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarPortal, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, Progress, RadioGroup, RadioGroupItem, ResizableHandle, ResizablePanel, ResizablePanelGroup, ScrollArea, ScrollBar, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, Skeleton, Slider, type SliderProps, Spinner, StatusIndicator, type StatusIndicatorProps, Switch, type SwitchProps, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, type TextareaProps, ThemeScript, Toaster, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, type UIVariant, UIVariantProvider, badgeVariants, buttonGroupVariants, buttonVariants, cn, fireConfetti, navigationMenuTriggerStyle, statusIndicatorDotVariants, toggleVariants, useCopyToClipboard, useFormField, useIsMobile, useSidebar, useUIVariant };
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { clsx } from 'clsx';
|
|
2
2
|
import { twMerge } from 'tailwind-merge';
|
|
3
3
|
import * as React37 from 'react';
|
|
4
|
-
import { useMemo, useRef, useState,
|
|
4
|
+
import { useMemo, useCallback, useRef, useState, useEffect } from 'react';
|
|
5
5
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
6
6
|
import * as AccordionPrimitive from '@radix-ui/react-accordion';
|
|
7
7
|
import { ChevronDown, ArrowLeft, ArrowRight, Check, X, Search, ChevronRight, Circle, Dot, ChevronUp, PanelLeft, MoreHorizontal, ChevronLeftIcon, ChevronRightIcon, ChevronDownIcon, ChevronLeft, GripVertical, LoaderCircle, OctagonX, TriangleAlert, Info, CircleCheck, Loader2Icon } from 'lucide-react';
|
|
@@ -475,16 +475,50 @@ var badgeVariants = cva(
|
|
|
475
475
|
}
|
|
476
476
|
}
|
|
477
477
|
);
|
|
478
|
+
var playfulBackdrop = {
|
|
479
|
+
default: "bg-primary/30 dark:bg-primary/20",
|
|
480
|
+
destructive: "bg-destructive/30 dark:bg-destructive/20",
|
|
481
|
+
secondary: "bg-foreground/10 dark:bg-foreground/10",
|
|
482
|
+
outline: "bg-foreground/10 dark:bg-foreground/10"
|
|
483
|
+
};
|
|
478
484
|
function Badge({ className, variant, size, disabled = false, mode: modeProp, ...props }) {
|
|
479
485
|
const mode = modeProp ?? useUIVariant();
|
|
486
|
+
if (mode === "playful") {
|
|
487
|
+
return /* @__PURE__ */ jsxs(
|
|
488
|
+
"span",
|
|
489
|
+
{
|
|
490
|
+
className: cn(
|
|
491
|
+
"group/playful relative inline-flex",
|
|
492
|
+
disabled && "opacity-50 pointer-events-none"
|
|
493
|
+
),
|
|
494
|
+
children: [
|
|
495
|
+
/* @__PURE__ */ jsx(
|
|
496
|
+
"span",
|
|
497
|
+
{
|
|
498
|
+
"aria-hidden": "true",
|
|
499
|
+
className: cn(
|
|
500
|
+
"absolute inset-0 rounded-full transition-transform duration-200 translate-x-[3px] translate-y-[3px] -rotate-[0.5deg] group-hover/playful:-rotate-[1.5deg] group-hover/playful:scale-[1.01]",
|
|
501
|
+
playfulBackdrop[variant ?? "default"]
|
|
502
|
+
)
|
|
503
|
+
}
|
|
504
|
+
),
|
|
505
|
+
/* @__PURE__ */ jsx(
|
|
506
|
+
"div",
|
|
507
|
+
{
|
|
508
|
+
className: cn(badgeVariants({ variant, size }), "relative rotate-[0.3deg]", className),
|
|
509
|
+
...props
|
|
510
|
+
}
|
|
511
|
+
)
|
|
512
|
+
]
|
|
513
|
+
}
|
|
514
|
+
);
|
|
515
|
+
}
|
|
480
516
|
return /* @__PURE__ */ jsx(
|
|
481
517
|
"div",
|
|
482
518
|
{
|
|
483
519
|
className: cn(
|
|
484
520
|
badgeVariants({ variant, size }),
|
|
485
521
|
disabled && "opacity-50 pointer-events-none",
|
|
486
|
-
mode === "smooth" && "shadow-sm",
|
|
487
|
-
mode === "playful" && "rotate-[0.5deg] [box-shadow:2px_2px_0px_0px_color-mix(in_srgb,currentColor_15%,transparent)]",
|
|
488
522
|
className
|
|
489
523
|
),
|
|
490
524
|
...props
|
|
@@ -2603,20 +2637,33 @@ HoverCardContent.displayName = HoverCardPrimitive.Content.displayName;
|
|
|
2603
2637
|
var Input = React37.forwardRef(
|
|
2604
2638
|
({ className, type, mode: modeProp, ...props }, ref) => {
|
|
2605
2639
|
const mode = modeProp ?? useUIVariant();
|
|
2606
|
-
|
|
2640
|
+
const input = /* @__PURE__ */ jsx(
|
|
2607
2641
|
"input",
|
|
2608
2642
|
{
|
|
2609
2643
|
type,
|
|
2610
2644
|
className: cn(
|
|
2611
2645
|
"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm aria-invalid:border-destructive aria-invalid:focus-visible:ring-destructive/20",
|
|
2612
2646
|
mode === "smooth" && "rounded-full",
|
|
2613
|
-
mode === "playful" && "
|
|
2647
|
+
mode === "playful" && "relative z-10",
|
|
2614
2648
|
className
|
|
2615
2649
|
),
|
|
2616
2650
|
ref,
|
|
2617
2651
|
...props
|
|
2618
2652
|
}
|
|
2619
2653
|
);
|
|
2654
|
+
if (mode === "playful") {
|
|
2655
|
+
return /* @__PURE__ */ jsxs("span", { className: "group/playful relative inline-flex w-full", children: [
|
|
2656
|
+
/* @__PURE__ */ jsx(
|
|
2657
|
+
"span",
|
|
2658
|
+
{
|
|
2659
|
+
"aria-hidden": "true",
|
|
2660
|
+
className: "absolute inset-0 z-0 translate-x-[3px] translate-y-[3px] -rotate-[0.4deg] rounded-md bg-foreground/8 transition-transform duration-200 group-hover/playful:-rotate-[1deg] group-focus-within/playful:-rotate-[1deg] dark:bg-foreground/10"
|
|
2661
|
+
}
|
|
2662
|
+
),
|
|
2663
|
+
input
|
|
2664
|
+
] });
|
|
2665
|
+
}
|
|
2666
|
+
return input;
|
|
2620
2667
|
}
|
|
2621
2668
|
);
|
|
2622
2669
|
Input.displayName = "Input";
|
|
@@ -5260,16 +5307,30 @@ function composeAsciiText(font, text) {
|
|
|
5260
5307
|
function getAsciiAccentColumns(font, text, accent) {
|
|
5261
5308
|
if (!accent) return /* @__PURE__ */ new Set();
|
|
5262
5309
|
const columns = /* @__PURE__ */ new Set();
|
|
5310
|
+
const accentRanges = [];
|
|
5311
|
+
let searchFrom = 0;
|
|
5312
|
+
while (true) {
|
|
5313
|
+
const idx = text.indexOf(accent, searchFrom);
|
|
5314
|
+
if (idx === -1) break;
|
|
5315
|
+
accentRanges.push({ start: idx, end: idx + accent.length });
|
|
5316
|
+
searchFrom = idx + 1;
|
|
5317
|
+
}
|
|
5318
|
+
if (accentRanges.length === 0) return columns;
|
|
5263
5319
|
let offsetX = 0;
|
|
5320
|
+
let charIndex = 0;
|
|
5264
5321
|
for (const ch of text) {
|
|
5265
5322
|
const code = ch.charCodeAt(0);
|
|
5266
5323
|
const glyph = font.chars.get(code) ?? font.chars.get(32);
|
|
5267
|
-
if (!glyph)
|
|
5324
|
+
if (!glyph) {
|
|
5325
|
+
charIndex++;
|
|
5326
|
+
continue;
|
|
5327
|
+
}
|
|
5268
5328
|
const width = Math.max(...glyph.map((line) => line.length));
|
|
5269
|
-
if (
|
|
5329
|
+
if (accentRanges.some((r) => charIndex >= r.start && charIndex < r.end)) {
|
|
5270
5330
|
for (let col = 0; col < width; col++) columns.add(offsetX + col);
|
|
5271
5331
|
}
|
|
5272
5332
|
offsetX += width;
|
|
5333
|
+
charIndex++;
|
|
5273
5334
|
}
|
|
5274
5335
|
return columns;
|
|
5275
5336
|
}
|
|
@@ -6526,6 +6587,9 @@ $$$@@
|
|
|
6526
6587
|
function AsciiText({
|
|
6527
6588
|
text = "olwibaCN",
|
|
6528
6589
|
accent = "",
|
|
6590
|
+
accents,
|
|
6591
|
+
shine = "",
|
|
6592
|
+
shineColor = "rgba(255,255,255,0.92)",
|
|
6529
6593
|
color,
|
|
6530
6594
|
accentColor
|
|
6531
6595
|
}) {
|
|
@@ -6534,6 +6598,26 @@ function AsciiText({
|
|
|
6534
6598
|
const accentCols = useMemo(() => {
|
|
6535
6599
|
return getAsciiAccentColumns(font, text, accent);
|
|
6536
6600
|
}, [font, text, accent]);
|
|
6601
|
+
const multiAccentCols = useMemo(() => {
|
|
6602
|
+
if (!accents?.length) return null;
|
|
6603
|
+
const map = /* @__PURE__ */ new Map();
|
|
6604
|
+
for (const item of accents) {
|
|
6605
|
+
const cols2 = getAsciiAccentColumns(font, text, item.text);
|
|
6606
|
+
for (const col of cols2) map.set(col, item.color);
|
|
6607
|
+
}
|
|
6608
|
+
return map;
|
|
6609
|
+
}, [accents, font, text]);
|
|
6610
|
+
const getCellColor = useCallback((col, baseColor, highlightColor) => {
|
|
6611
|
+
return multiAccentCols?.get(col) ?? (accentCols.has(col) ? highlightColor : baseColor);
|
|
6612
|
+
}, [accentCols, multiAccentCols]);
|
|
6613
|
+
const shineCols = useMemo(() => {
|
|
6614
|
+
return getAsciiAccentColumns(font, text, shine);
|
|
6615
|
+
}, [font, shine, text]);
|
|
6616
|
+
const shineBounds = useMemo(() => {
|
|
6617
|
+
if (!shineCols.size) return null;
|
|
6618
|
+
const cols2 = Array.from(shineCols);
|
|
6619
|
+
return { min: Math.min(...cols2), max: Math.max(...cols2) };
|
|
6620
|
+
}, [shineCols]);
|
|
6537
6621
|
const canvasRef = useRef(null);
|
|
6538
6622
|
const animRef = useRef(0);
|
|
6539
6623
|
const timeRef = useRef(0);
|
|
@@ -6584,24 +6668,46 @@ function AsciiText({
|
|
|
6584
6668
|
const time = timeRef.current;
|
|
6585
6669
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
6586
6670
|
const { base: baseColor, accent: highlightColor } = colorsRef.current;
|
|
6587
|
-
|
|
6588
|
-
|
|
6589
|
-
|
|
6590
|
-
|
|
6591
|
-
|
|
6592
|
-
|
|
6593
|
-
|
|
6594
|
-
|
|
6671
|
+
if (multiAccentCols || shineCols.size) {
|
|
6672
|
+
for (const cell of cells) {
|
|
6673
|
+
const intensity = getAsciiCellIntensity(cell, {
|
|
6674
|
+
time,
|
|
6675
|
+
pointer: mouseRef.current,
|
|
6676
|
+
waves: wavesRef.current
|
|
6677
|
+
});
|
|
6678
|
+
ctx.globalAlpha = intensity;
|
|
6679
|
+
ctx.fillStyle = getCellColor(cell.col, baseColor, highlightColor);
|
|
6680
|
+
ctx.fillRect(cell.col * ASCII_CHAR_WIDTH, cell.row * ASCII_CHAR_HEIGHT, ASCII_CHAR_WIDTH, ASCII_CHAR_HEIGHT);
|
|
6681
|
+
if (shineBounds && shineCols.has(cell.col)) {
|
|
6682
|
+
const alpha = getShineAlpha(cell.col, cell.row, time, shineBounds) * (cell.ch === "\u2591" ? 0.55 : 1);
|
|
6683
|
+
if (alpha > 0) {
|
|
6684
|
+
ctx.globalAlpha = intensity * alpha;
|
|
6685
|
+
ctx.fillStyle = shineColor;
|
|
6686
|
+
ctx.fillRect(cell.col * ASCII_CHAR_WIDTH, cell.row * ASCII_CHAR_HEIGHT, ASCII_CHAR_WIDTH, ASCII_CHAR_HEIGHT);
|
|
6687
|
+
}
|
|
6688
|
+
}
|
|
6689
|
+
}
|
|
6690
|
+
ctx.globalAlpha = 1;
|
|
6691
|
+
} else {
|
|
6692
|
+
renderAsciiFrameToContext(ctx, { cells, cols, rows }, {
|
|
6693
|
+
accentColumns: accentCols,
|
|
6694
|
+
color: baseColor,
|
|
6695
|
+
accentColor: highlightColor,
|
|
6696
|
+
time,
|
|
6697
|
+
pointer: mouseRef.current,
|
|
6698
|
+
waves: wavesRef.current
|
|
6699
|
+
});
|
|
6700
|
+
}
|
|
6595
6701
|
if (!hasPaintedRef.current) {
|
|
6596
6702
|
hasPaintedRef.current = true;
|
|
6597
6703
|
setIsCanvasReady(true);
|
|
6598
6704
|
}
|
|
6599
6705
|
wavesRef.current = wavesRef.current.filter((w) => time - w.t < 3);
|
|
6600
|
-
}, [
|
|
6706
|
+
}, [accentCols, cells, cols, getCellColor, multiAccentCols, rows, shineBounds, shineColor, shineCols]);
|
|
6601
6707
|
useEffect(() => {
|
|
6602
6708
|
hasPaintedRef.current = false;
|
|
6603
6709
|
setIsCanvasReady(false);
|
|
6604
|
-
}, [text, accent, color, accentColor]);
|
|
6710
|
+
}, [text, accent, accents, shine, shineColor, color, accentColor]);
|
|
6605
6711
|
useEffect(() => {
|
|
6606
6712
|
let running = true;
|
|
6607
6713
|
const loop = () => {
|
|
@@ -6666,18 +6772,32 @@ function AsciiText({
|
|
|
6666
6772
|
preserveAspectRatio: "xMidYMid meet",
|
|
6667
6773
|
children: cells.map((cell) => {
|
|
6668
6774
|
const isAccent = accentCols.has(cell.col);
|
|
6669
|
-
|
|
6670
|
-
|
|
6671
|
-
|
|
6672
|
-
|
|
6673
|
-
|
|
6674
|
-
|
|
6675
|
-
|
|
6676
|
-
|
|
6677
|
-
|
|
6678
|
-
|
|
6679
|
-
|
|
6680
|
-
|
|
6775
|
+
const multiAccentColor = multiAccentCols?.get(cell.col);
|
|
6776
|
+
const shineAlpha = shineBounds && shineCols.has(cell.col) ? getShineAlpha(cell.col, cell.row, 0.2, shineBounds) * (cell.ch === "\u2591" ? 0.55 : 1) : 0;
|
|
6777
|
+
return /* @__PURE__ */ jsxs(React37.Fragment, { children: [
|
|
6778
|
+
/* @__PURE__ */ jsx(
|
|
6779
|
+
"rect",
|
|
6780
|
+
{
|
|
6781
|
+
x: cell.col * ASCII_CHAR_WIDTH,
|
|
6782
|
+
y: cell.row * ASCII_CHAR_HEIGHT,
|
|
6783
|
+
width: ASCII_CHAR_WIDTH,
|
|
6784
|
+
height: ASCII_CHAR_HEIGHT,
|
|
6785
|
+
fill: multiAccentColor ?? (isAccent ? fallbackAccentColor : "currentColor"),
|
|
6786
|
+
opacity: cell.ch === "\u2591" ? 0.15 : 0.78
|
|
6787
|
+
}
|
|
6788
|
+
),
|
|
6789
|
+
shineAlpha > 0 && /* @__PURE__ */ jsx(
|
|
6790
|
+
"rect",
|
|
6791
|
+
{
|
|
6792
|
+
x: cell.col * ASCII_CHAR_WIDTH,
|
|
6793
|
+
y: cell.row * ASCII_CHAR_HEIGHT,
|
|
6794
|
+
width: ASCII_CHAR_WIDTH,
|
|
6795
|
+
height: ASCII_CHAR_HEIGHT,
|
|
6796
|
+
fill: shineColor,
|
|
6797
|
+
opacity: shineAlpha
|
|
6798
|
+
}
|
|
6799
|
+
)
|
|
6800
|
+
] }, `${cell.col}-${cell.row}`);
|
|
6681
6801
|
})
|
|
6682
6802
|
}
|
|
6683
6803
|
),
|
|
@@ -6698,6 +6818,20 @@ function AsciiText({
|
|
|
6698
6818
|
}
|
|
6699
6819
|
) });
|
|
6700
6820
|
}
|
|
6821
|
+
function getShineAlpha(col, row, time, bounds) {
|
|
6822
|
+
const span = bounds.max - bounds.min + 1;
|
|
6823
|
+
const travel = span + 6;
|
|
6824
|
+
const diagonalCol = col + row * 0.62;
|
|
6825
|
+
const primarySweep = bounds.max + 3 - time * 1.35 % 1 * travel;
|
|
6826
|
+
const secondarySweep = bounds.max + 3 - (time * 1.35 + 0.5) % 1 * travel;
|
|
6827
|
+
const primary = getShineBandAlpha(diagonalCol, primarySweep);
|
|
6828
|
+
const secondary = getShineBandAlpha(diagonalCol, secondarySweep);
|
|
6829
|
+
return Math.min(0.86, primary + secondary * 0.82);
|
|
6830
|
+
}
|
|
6831
|
+
function getShineBandAlpha(diagonalCol, sweep) {
|
|
6832
|
+
const distance = Math.abs(diagonalCol - sweep);
|
|
6833
|
+
return Math.max(0, 1 - distance / 2.7) ** 2 * 0.78;
|
|
6834
|
+
}
|
|
6701
6835
|
function useCopyToClipboard(timeout = 2e3) {
|
|
6702
6836
|
const [isCopied, setIsCopied] = useState(false);
|
|
6703
6837
|
const copyToClipboard = useCallback(
|
|
@@ -6812,25 +6946,33 @@ function ThemeScript() {
|
|
|
6812
6946
|
}
|
|
6813
6947
|
var GLINTS = [
|
|
6814
6948
|
// perimeter
|
|
6815
|
-
{ top: "-
|
|
6816
|
-
{ top: "2px", right: "-
|
|
6817
|
-
{ bottom: "-
|
|
6818
|
-
{ top: "3px", left: "-
|
|
6949
|
+
{ top: "-8px", left: "10%", size: 9, delay: "0s", duration: "2.1s" },
|
|
6950
|
+
{ top: "2px", right: "-8px", size: 8, delay: "0.3s", duration: "3.4s" },
|
|
6951
|
+
{ bottom: "-7px", right: "15%", size: 8, delay: "1.1s", duration: "1.7s" },
|
|
6952
|
+
{ top: "3px", left: "-7px", size: 7, delay: "0.7s", duration: "2.9s" },
|
|
6953
|
+
{ bottom: "-6px", left: "40%", size: 6, delay: "2.2s", duration: "2.6s" },
|
|
6954
|
+
{ top: "-6px", right: "35%", size: 6, delay: "1.4s", duration: "2.2s" },
|
|
6819
6955
|
// inside / overlapping the child
|
|
6820
|
-
{ top: "20%", left: "38%", size:
|
|
6821
|
-
{ top: "15%", right: "22%", size:
|
|
6822
|
-
{ bottom: "15%", left: "22%", size:
|
|
6956
|
+
{ top: "20%", left: "38%", size: 6, delay: "1.5s", duration: "2.3s" },
|
|
6957
|
+
{ top: "15%", right: "22%", size: 5, delay: "0.5s", duration: "3.1s" },
|
|
6958
|
+
{ bottom: "15%", left: "22%", size: 5, delay: "1.9s", duration: "1.8s" }
|
|
6823
6959
|
];
|
|
6824
6960
|
function GlintIcon({ size }) {
|
|
6825
6961
|
return /* @__PURE__ */ jsx("svg", { width: size, height: size, viewBox: "0 0 8 8", fill: "currentColor", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { d: "M4 0.5 L4.6 3.4 L7.5 4 L4.6 4.6 L4 7.5 L3.4 4.6 L0.5 4 L3.4 3.4 Z" }) });
|
|
6826
6962
|
}
|
|
6827
|
-
function Enchanted({ children, className, ...props }) {
|
|
6828
|
-
return /* @__PURE__ */ jsxs("div", { className: cn("relative", className), ...props, children: [
|
|
6963
|
+
function Enchanted({ children, className, hoverOnly = false, glintClassName, ...props }) {
|
|
6964
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("relative", hoverOnly && "group/enchanted", className), ...props, children: [
|
|
6829
6965
|
children,
|
|
6830
6966
|
GLINTS.map((g, i) => /* @__PURE__ */ jsx(
|
|
6831
6967
|
"span",
|
|
6832
6968
|
{
|
|
6833
|
-
className:
|
|
6969
|
+
className: cn(
|
|
6970
|
+
"pointer-events-none absolute z-10 animate-enchanted drop-shadow-[0_0_3px_currentColor]",
|
|
6971
|
+
glintClassName ?? "text-primary",
|
|
6972
|
+
// Display toggle (not opacity) - the keyframes own opacity, and
|
|
6973
|
+
// re-mounting restarts the glint timeline on each hover.
|
|
6974
|
+
hoverOnly && "hidden group-hover/enchanted:block"
|
|
6975
|
+
),
|
|
6834
6976
|
style: { top: g.top, bottom: g.bottom, left: g.left, right: g.right, animationDelay: g.delay, animationDuration: g.duration },
|
|
6835
6977
|
children: /* @__PURE__ */ jsx(GlintIcon, { size: g.size })
|
|
6836
6978
|
},
|