From 4d127a038bf768eded68aae3cfa5c1b12241bdac Mon Sep 17 00:00:00 2001 From: Maze Winther Date: Fri, 27 Mar 2026 00:55:15 +0100 Subject: chore: normalize line endings --- apps/web/src/components/section.tsx | 514 ++++++++++++++++++------------------ 1 file changed, 257 insertions(+), 257 deletions(-) (limited to 'apps/web/src/components/section.tsx') diff --git a/apps/web/src/components/section.tsx b/apps/web/src/components/section.tsx index e3fc96df..86f2f71f 100644 --- a/apps/web/src/components/section.tsx +++ b/apps/web/src/components/section.tsx @@ -1,257 +1,257 @@ -import { createContext, useContext, useEffect, useState } from "react"; -import { cn } from "@/utils/ui"; -import { HugeiconsIcon } from "@hugeicons/react"; -import { ArrowDownIcon } from "@hugeicons/core-free-icons"; -import { Label } from "@/components/ui/label"; -import { Button } from "@/components/ui/button"; - -const sectionExpandedCache = new Map(); -const mountedSectionKeys = new Set(); - -interface SectionContext { - isOpen: boolean; - toggle: () => void; - collapsible: boolean; -} - -const SectionCtx = createContext(null); - -function useSectionContext() { - return useContext(SectionCtx); -} - -interface SectionProps { - children: React.ReactNode; - collapsible?: boolean; - defaultOpen?: boolean; - sectionKey?: string; - className?: string; - showTopBorder?: boolean; - showBottomBorder?: boolean; -} - -export function Section({ - children, - collapsible = false, - defaultOpen = true, - sectionKey, - className, - showTopBorder = false, - showBottomBorder = true, -}: SectionProps) { - const cached = sectionKey ? sectionExpandedCache.get(sectionKey) : undefined; - const [isOpen, setIsOpen] = useState(cached ?? defaultOpen); - - useEffect(() => { - if (!sectionKey) return; - if ( - process.env.NODE_ENV !== "production" && - mountedSectionKeys.has(sectionKey) - ) { - console.error( - `[Section] duplicate sectionKey mounted simultaneously: "${sectionKey}"`, - ); - } - mountedSectionKeys.add(sectionKey); - return () => { - mountedSectionKeys.delete(sectionKey); - }; - }, [sectionKey]); - - const toggle = () => { - const next = !isOpen; - setIsOpen(next); - if (sectionKey) sectionExpandedCache.set(sectionKey, next); - }; - - return ( - -
- {children} -
-
- ); -} - -interface SectionHeaderProps { - children?: React.ReactNode; - trailing?: React.ReactNode; - leading?: React.ReactNode; - actions?: React.ReactNode; - onClick?: () => void; - className?: string; -} - -export function SectionHeader({ - children, - trailing, - leading, - actions, - onClick, - className, -}: SectionHeaderProps) { - const ctx = useSectionContext(); - const isCollapsible = ctx?.collapsible ?? false; - const isOpen = ctx?.isOpen ?? true; - const isInteractive = isCollapsible || !!onClick; - const handleClick = isCollapsible ? ctx?.toggle : onClick; - - const chevronIcon = ( - - ); - - const trailingArea = - trailing || isCollapsible ? ( -
- {trailing} - {isCollapsible && ( - - )} -
- ) : null; - - const innerContent = isInteractive ? ( - - ) : ( - <> - {leading} -
{children}
- - ); - - return ( -
- {innerContent} - {trailingArea} - {actions} -
- ); -} - -export function SectionTitle({ - children, - className, - onClick, -}: { - children: React.ReactNode; - className?: string; - onClick?: () => void; -}) { - const ctx = useSectionContext(); - const isCollapsible = ctx?.collapsible ?? false; - const isOpen = ctx?.isOpen ?? true; - - const titleClass = cn( - "text-sm font-medium", - isCollapsible && isOpen ? "text-foreground" : "text-muted-foreground", - className, - ); - - if (onClick) { - return ( - - ); - } - - return {children}; -} - -export function SectionFields({ - children, - className, -}: { - children: React.ReactNode; - className?: string; -}) { - return ( -
{children}
- ); -} - -export function SectionField({ - label, - beforeLabel, - children, - className, -}: { - label: string; - beforeLabel?: React.ReactNode; - children: React.ReactNode; - className?: string; -}) { - return ( -
-
- {beforeLabel} - -
- {children} -
- ); -} - -export function SectionContent({ - children, - className, -}: { - children: React.ReactNode; - className?: string; -}) { - const ctx = useSectionContext(); - const isCollapsible = ctx?.collapsible ?? false; - const isOpen = ctx?.isOpen ?? true; - - const content =
{children}
; - - if (isCollapsible) { - return ( -
-
{content}
-
- ); - } - - return content; -} +import { createContext, useContext, useEffect, useState } from "react"; +import { cn } from "@/utils/ui"; +import { HugeiconsIcon } from "@hugeicons/react"; +import { ArrowDownIcon } from "@hugeicons/core-free-icons"; +import { Label } from "@/components/ui/label"; +import { Button } from "@/components/ui/button"; + +const sectionExpandedCache = new Map(); +const mountedSectionKeys = new Set(); + +interface SectionContext { + isOpen: boolean; + toggle: () => void; + collapsible: boolean; +} + +const SectionCtx = createContext(null); + +function useSectionContext() { + return useContext(SectionCtx); +} + +interface SectionProps { + children: React.ReactNode; + collapsible?: boolean; + defaultOpen?: boolean; + sectionKey?: string; + className?: string; + showTopBorder?: boolean; + showBottomBorder?: boolean; +} + +export function Section({ + children, + collapsible = false, + defaultOpen = true, + sectionKey, + className, + showTopBorder = false, + showBottomBorder = true, +}: SectionProps) { + const cached = sectionKey ? sectionExpandedCache.get(sectionKey) : undefined; + const [isOpen, setIsOpen] = useState(cached ?? defaultOpen); + + useEffect(() => { + if (!sectionKey) return; + if ( + process.env.NODE_ENV !== "production" && + mountedSectionKeys.has(sectionKey) + ) { + console.error( + `[Section] duplicate sectionKey mounted simultaneously: "${sectionKey}"`, + ); + } + mountedSectionKeys.add(sectionKey); + return () => { + mountedSectionKeys.delete(sectionKey); + }; + }, [sectionKey]); + + const toggle = () => { + const next = !isOpen; + setIsOpen(next); + if (sectionKey) sectionExpandedCache.set(sectionKey, next); + }; + + return ( + +
+ {children} +
+
+ ); +} + +interface SectionHeaderProps { + children?: React.ReactNode; + trailing?: React.ReactNode; + leading?: React.ReactNode; + actions?: React.ReactNode; + onClick?: () => void; + className?: string; +} + +export function SectionHeader({ + children, + trailing, + leading, + actions, + onClick, + className, +}: SectionHeaderProps) { + const ctx = useSectionContext(); + const isCollapsible = ctx?.collapsible ?? false; + const isOpen = ctx?.isOpen ?? true; + const isInteractive = isCollapsible || !!onClick; + const handleClick = isCollapsible ? ctx?.toggle : onClick; + + const chevronIcon = ( + + ); + + const trailingArea = + trailing || isCollapsible ? ( +
+ {trailing} + {isCollapsible && ( + + )} +
+ ) : null; + + const innerContent = isInteractive ? ( + + ) : ( + <> + {leading} +
{children}
+ + ); + + return ( +
+ {innerContent} + {trailingArea} + {actions} +
+ ); +} + +export function SectionTitle({ + children, + className, + onClick, +}: { + children: React.ReactNode; + className?: string; + onClick?: () => void; +}) { + const ctx = useSectionContext(); + const isCollapsible = ctx?.collapsible ?? false; + const isOpen = ctx?.isOpen ?? true; + + const titleClass = cn( + "text-sm font-medium", + isCollapsible && isOpen ? "text-foreground" : "text-muted-foreground", + className, + ); + + if (onClick) { + return ( + + ); + } + + return {children}; +} + +export function SectionFields({ + children, + className, +}: { + children: React.ReactNode; + className?: string; +}) { + return ( +
{children}
+ ); +} + +export function SectionField({ + label, + beforeLabel, + children, + className, +}: { + label: string; + beforeLabel?: React.ReactNode; + children: React.ReactNode; + className?: string; +}) { + return ( +
+
+ {beforeLabel} + +
+ {children} +
+ ); +} + +export function SectionContent({ + children, + className, +}: { + children: React.ReactNode; + className?: string; +}) { + const ctx = useSectionContext(); + const isCollapsible = ctx?.collapsible ?? false; + const isOpen = ctx?.isOpen ?? true; + + const content =
{children}
; + + if (isCollapsible) { + return ( +
+
{content}
+
+ ); + } + + return content; +} -- cgit v1.3.1