返回 presentation-ai
utils.ts
1 import { cva } from "class-variance-authority";
2
3 export type PresentationColumnSize = "sm" | "md" | "lg" | "xl";
4 export type IconListOrientation = "side" | "top";
5 export type IconListVariant = "icon" | "image";
6
7 const DEFAULT_ICON_LIST_MEDIA_SIZE = 40;
8 export const ICON_LIST_MEDIA_SIZE_BOUNDS = {
9 min: 24,
10 max: 160,
11 } as const;
12
13 export function getDefaultColumnSize(
14 childCount: number,
15 ): PresentationColumnSize {
16 return childCount >= 4 ? "lg" : "md";
17 }
18
19 export const columnSizeVariant = cva("flex flex-wrap *:shrink *:grow", {
20 variants: {
21 columnSize: {
22 sm: "*:flex-1",
23 md: "*:basis-[calc(33.33%-2rem)]",
24 lg: "*:basis-[calc(50%-2rem)]",
25 xl: "*:basis-full",
26 },
27 },
28 });
29
30 export const iconListColumnSizeVariant = cva(
31 "flex flex-wrap *:min-w-0 *:shrink *:grow",
32 {
33 variants: {
34 columnSize: {
35 sm: [
36 "*:basis-full",
37 "@[420px]/icon-list:*:basis-[calc(50%_-_0.75rem)]",
38 "@[720px]/icon-list:*:basis-[calc(33.333%_-_1rem)]",
39 "@[960px]/icon-list:*:basis-[calc(25%_-_1.125rem)]",
40 ],
41 md: [
42 "*:basis-full",
43 "@[420px]/icon-list:*:basis-[calc(50%_-_0.75rem)]",
44 "@[720px]/icon-list:*:basis-[calc(33.333%_-_1rem)]",
45 ],
46 lg: [
47 "*:basis-full",
48 "@[420px]/icon-list:*:basis-[calc(50%_-_0.75rem)]",
49 ],
50 xl: "*:basis-full",
51 },
52 },
53 },
54 );
55
56 export function getAlignmentClasses(
57 alignment: "left" | "center" | "right" = "left",
58 ) {
59 switch (alignment) {
60 case "left":
61 return "text-left";
62 case "right":
63 return "text-right";
64 case "center":
65 return "text-center";
66 default:
67 return "text-left";
68 }
69 }
70
71 export function getIconListMediaSize(value: unknown): number {
72 const parsedValue =
73 typeof value === "number"
74 ? value
75 : typeof value === "string"
76 ? Number.parseFloat(value)
77 : Number.NaN;
78
79 if (!Number.isFinite(parsedValue)) {
80 return DEFAULT_ICON_LIST_MEDIA_SIZE;
81 }
82
83 return Math.min(
84 ICON_LIST_MEDIA_SIZE_BOUNDS.max,
85 Math.max(ICON_LIST_MEDIA_SIZE_BOUNDS.min, parsedValue),
86 );
87 }
88
89 export function getIconListOrientation(
90 value: unknown,
91 childCount: number,
92 ): IconListOrientation {
93 if (childCount <= 1) {
94 return "side";
95 }
96
97 return value === "top" ? "top" : "side";
98 }
99
100 export function getIconListVariant(value: unknown): IconListVariant {
101 return value === "image" ? "image" : "icon";
102 }
103
103 lines TYPESCRIPT