mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-09 09:06:36 +08:00
refactor(repo): consolidate openflare-server to root and move subprojects to internal/apps
- Merge all files inside openflare-server to the repository root directory. - Relocate agent, relay, and flared subprojects from internal/ to internal/apps/. - Combine docker-compose files and update build context paths to root. - Update GitHub workflows and Dockerfiles to refer to new directories and package names. - Rewrite Go package imports across all files. - Resolve database renew test race condition and clean up docs.
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
'use client';
|
||||
|
||||
import * as React from 'react';
|
||||
import {Collapsible as CollapsiblePrimitive} from 'radix-ui';
|
||||
import {AnimatePresence, type HTMLMotionProps, motion} from 'motion/react';
|
||||
|
||||
import {getStrictContext} from '@/lib/utils/get-strict-context';
|
||||
import {useControlledState} from '@/hooks/use-controlled-state';
|
||||
|
||||
type CollapsibleContextType = {
|
||||
isOpen: boolean;
|
||||
setIsOpen: (isOpen: boolean) => void;
|
||||
};
|
||||
|
||||
const [CollapsibleProvider, useCollapsible] =
|
||||
getStrictContext<CollapsibleContextType>('CollapsibleContext');
|
||||
|
||||
type CollapsibleProps = React.ComponentProps<typeof CollapsiblePrimitive.Root>;
|
||||
|
||||
function Collapsible(props: CollapsibleProps) {
|
||||
const [isOpen, setIsOpen] = useControlledState({
|
||||
value: props?.open,
|
||||
defaultValue: props?.defaultOpen,
|
||||
onChange: props?.onOpenChange,
|
||||
});
|
||||
|
||||
return (
|
||||
<CollapsibleProvider value={{ isOpen, setIsOpen }}>
|
||||
<CollapsiblePrimitive.Root
|
||||
data-slot="collapsible"
|
||||
{...props}
|
||||
onOpenChange={setIsOpen}
|
||||
/>
|
||||
</CollapsibleProvider>
|
||||
);
|
||||
}
|
||||
|
||||
type CollapsibleTriggerProps = React.ComponentProps<
|
||||
typeof CollapsiblePrimitive.Trigger
|
||||
>;
|
||||
|
||||
function CollapsibleTrigger(props: CollapsibleTriggerProps) {
|
||||
return (
|
||||
<CollapsiblePrimitive.Trigger data-slot="collapsible-trigger" {...props} />
|
||||
);
|
||||
}
|
||||
|
||||
type CollapsibleContentProps = Omit<
|
||||
React.ComponentProps<typeof CollapsiblePrimitive.Content>,
|
||||
'asChild' | 'forceMount'
|
||||
> &
|
||||
HTMLMotionProps<'div'> & {
|
||||
keepRendered?: boolean;
|
||||
};
|
||||
|
||||
function CollapsibleContent({
|
||||
keepRendered = false,
|
||||
transition = { duration: 0.35, ease: 'easeInOut' },
|
||||
...props
|
||||
}: CollapsibleContentProps) {
|
||||
const { isOpen } = useCollapsible();
|
||||
|
||||
return (
|
||||
<AnimatePresence>
|
||||
{keepRendered ? (
|
||||
<CollapsiblePrimitive.Content asChild forceMount>
|
||||
<motion.div
|
||||
key="collapsible-content"
|
||||
data-slot="collapsible-content"
|
||||
layout
|
||||
initial={{ opacity: 0, height: 0, overflow: 'hidden', y: 20 }}
|
||||
animate={
|
||||
isOpen
|
||||
? { opacity: 1, height: 'auto', overflow: 'hidden', y: 0 }
|
||||
: { opacity: 0, height: 0, overflow: 'hidden', y: 20 }
|
||||
}
|
||||
transition={transition}
|
||||
{...props}
|
||||
/>
|
||||
</CollapsiblePrimitive.Content>
|
||||
) : (
|
||||
isOpen && (
|
||||
<CollapsiblePrimitive.Content asChild forceMount>
|
||||
<motion.div
|
||||
key="collapsible-content"
|
||||
data-slot="collapsible-content"
|
||||
layout
|
||||
initial={{ opacity: 0, height: 0, overflow: 'hidden', y: 20 }}
|
||||
animate={{ opacity: 1, height: 'auto', overflow: 'hidden', y: 0 }}
|
||||
exit={{ opacity: 0, height: 0, overflow: 'hidden', y: 20 }}
|
||||
transition={transition}
|
||||
{...props}
|
||||
/>
|
||||
</CollapsiblePrimitive.Content>
|
||||
)
|
||||
)}
|
||||
</AnimatePresence>
|
||||
);
|
||||
}
|
||||
|
||||
export {
|
||||
Collapsible,
|
||||
CollapsibleTrigger,
|
||||
CollapsibleContent,
|
||||
useCollapsible,
|
||||
type CollapsibleProps,
|
||||
type CollapsibleTriggerProps,
|
||||
type CollapsibleContentProps,
|
||||
type CollapsibleContextType,
|
||||
};
|
||||
Reference in New Issue
Block a user