mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-07-30 02:23:47 +00:00
feat: Linear-style UI redesign with improved mobile experience
Major changes: - Redesign cabinet with Linear-style components and top navigation - Replace detail modals with dedicated pages (users, broadcasts, email templates) - Add email channel support for broadcasts - Remove pull-to-refresh, improve drag-and-drop on touch devices - Fix Telegram Mini App: fullscreen, back button, scroll restoration - Unify admin pages color scheme to design system - Mobile-first improvements: horizontal tabs for settings, better touch targets
This commit is contained in:
96
src/components/primitives/Popover/Popover.tsx
Normal file
96
src/components/primitives/Popover/Popover.tsx
Normal file
@@ -0,0 +1,96 @@
|
||||
import * as PopoverPrimitive from '@radix-ui/react-popover';
|
||||
import { motion } from 'framer-motion';
|
||||
import { forwardRef, type ComponentPropsWithoutRef } from 'react';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { dropdown, dropdownTransition } from '../../motion/transitions';
|
||||
|
||||
// Close icon
|
||||
const CloseIcon = () => (
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none">
|
||||
<path
|
||||
d="M12 4L4 12M4 4l8 8"
|
||||
stroke="currentColor"
|
||||
strokeWidth="1.5"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
|
||||
// Root
|
||||
export const Popover = PopoverPrimitive.Root;
|
||||
|
||||
// Trigger
|
||||
export const PopoverTrigger = PopoverPrimitive.Trigger;
|
||||
|
||||
// Anchor
|
||||
export const PopoverAnchor = PopoverPrimitive.Anchor;
|
||||
|
||||
// Close
|
||||
export const PopoverClose = PopoverPrimitive.Close;
|
||||
|
||||
// Content
|
||||
export interface PopoverContentProps extends ComponentPropsWithoutRef<
|
||||
typeof PopoverPrimitive.Content
|
||||
> {
|
||||
showCloseButton?: boolean;
|
||||
}
|
||||
|
||||
export const PopoverContent = forwardRef<HTMLDivElement, PopoverContentProps>(
|
||||
(
|
||||
{ className, children, align = 'center', sideOffset = 4, showCloseButton = false, ...props },
|
||||
ref,
|
||||
) => (
|
||||
<PopoverPrimitive.Portal>
|
||||
<PopoverPrimitive.Content
|
||||
ref={ref}
|
||||
align={align}
|
||||
sideOffset={sideOffset}
|
||||
className={cn(
|
||||
'z-50 w-72 overflow-hidden',
|
||||
'rounded-linear-lg border border-dark-700/50 bg-dark-900/95 backdrop-blur-linear',
|
||||
'p-4 text-dark-100 shadow-linear-lg outline-none',
|
||||
className,
|
||||
)}
|
||||
asChild
|
||||
{...props}
|
||||
>
|
||||
<motion.div
|
||||
variants={dropdown}
|
||||
initial="initial"
|
||||
animate="animate"
|
||||
exit="exit"
|
||||
transition={dropdownTransition}
|
||||
>
|
||||
{children}
|
||||
{showCloseButton && (
|
||||
<PopoverPrimitive.Close
|
||||
className={cn(
|
||||
'absolute right-2 top-2 rounded-linear p-1.5',
|
||||
'text-dark-400 opacity-70 transition-all',
|
||||
'hover:bg-dark-800/80 hover:opacity-100',
|
||||
'focus:outline-none focus:ring-2 focus:ring-accent-500/50',
|
||||
)}
|
||||
>
|
||||
<CloseIcon />
|
||||
<span className="sr-only">Close</span>
|
||||
</PopoverPrimitive.Close>
|
||||
)}
|
||||
</motion.div>
|
||||
</PopoverPrimitive.Content>
|
||||
</PopoverPrimitive.Portal>
|
||||
),
|
||||
);
|
||||
|
||||
PopoverContent.displayName = 'PopoverContent';
|
||||
|
||||
// Arrow
|
||||
export type PopoverArrowProps = ComponentPropsWithoutRef<typeof PopoverPrimitive.Arrow>;
|
||||
|
||||
export const PopoverArrow = forwardRef<SVGSVGElement, PopoverArrowProps>(
|
||||
({ className, ...props }, ref) => (
|
||||
<PopoverPrimitive.Arrow ref={ref} className={cn('fill-dark-800', className)} {...props} />
|
||||
),
|
||||
);
|
||||
|
||||
PopoverArrow.displayName = 'PopoverArrow';
|
||||
10
src/components/primitives/Popover/index.ts
Normal file
10
src/components/primitives/Popover/index.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
export {
|
||||
Popover,
|
||||
PopoverTrigger,
|
||||
PopoverAnchor,
|
||||
PopoverClose,
|
||||
PopoverContent,
|
||||
PopoverArrow,
|
||||
type PopoverContentProps,
|
||||
type PopoverArrowProps,
|
||||
} from './Popover';
|
||||
Reference in New Issue
Block a user