mirror of
https://github.com/khairul169/code-share.git
synced 2026-10-24 11:53:58 +07:00
feat: update layout
This commit is contained in:
@@ -18,7 +18,7 @@ const BaseInput = forwardRef<HTMLInputElement, BaseInputProps>(
|
||||
type={type}
|
||||
className={cn(
|
||||
"flex h-10 w-full rounded-md border border-slate-200 px-3 py-2 text-sm ring-offset-white file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-slate-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-slate-950 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:border-white/40 bg-transparent dark:ring-offset-slate-950 dark:placeholder:text-slate-400 dark:focus-visible:ring-slate-300",
|
||||
inputClassName
|
||||
label || error ? inputClassName : className
|
||||
)}
|
||||
ref={ref}
|
||||
{...props}
|
||||
|
||||
+22
-20
@@ -58,26 +58,28 @@ const ResizablePanel = forwardRef((props: ResizablePanelProps, ref: any) => {
|
||||
);
|
||||
});
|
||||
|
||||
const ResizableHandle = ({
|
||||
withHandle,
|
||||
className,
|
||||
...props
|
||||
}: React.ComponentProps<typeof ResizablePrimitive.PanelResizeHandle> & {
|
||||
type ResizableHandleProps = React.ComponentProps<
|
||||
typeof ResizablePrimitive.PanelResizeHandle
|
||||
> & {
|
||||
withHandle?: boolean;
|
||||
}) => (
|
||||
<ResizablePrimitive.PanelResizeHandle
|
||||
className={cn(
|
||||
"relative flex w-px items-center justify-center after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full data-[panel-group-direction=vertical]:after:left-0 data-[panel-group-direction=vertical]:after:h-1 data-[panel-group-direction=vertical]:after:w-full data-[panel-group-direction=vertical]:after:-translate-y-1/2 data-[panel-group-direction=vertical]:after:translate-x-0 [&[data-panel-group-direction=vertical]>div]:rotate-90",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{withHandle && (
|
||||
<div className="z-10 flex h-4 w-3 items-center justify-center rounded-sm border border-slate-200 bg-slate-200 dark:border-slate-800 dark:bg-slate-800">
|
||||
<GripVertical className="h-2.5 w-2.5" />
|
||||
</div>
|
||||
)}
|
||||
</ResizablePrimitive.PanelResizeHandle>
|
||||
);
|
||||
};
|
||||
|
||||
const ResizableHandle = (props: ResizableHandleProps) => {
|
||||
const { withHandle, className, ...restProps } = props;
|
||||
return (
|
||||
<ResizablePrimitive.PanelResizeHandle
|
||||
className={cn(
|
||||
"relative flex w-px items-center justify-center after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full data-[panel-group-direction=vertical]:after:left-0 data-[panel-group-direction=vertical]:after:h-1 data-[panel-group-direction=vertical]:after:w-full data-[panel-group-direction=vertical]:after:-translate-y-1/2 data-[panel-group-direction=vertical]:after:translate-x-0 [&[data-panel-group-direction=vertical]>div]:rotate-90",
|
||||
withHandle && "w-3 bg-black group",
|
||||
className
|
||||
)}
|
||||
{...restProps}
|
||||
>
|
||||
{withHandle && (
|
||||
<div className="z-10 flex h-full max-h-[100px] w-1.5 items-center justify-center rounded-full bg-white/30 group-hover:bg-white/40"></div>
|
||||
)}
|
||||
</ResizablePrimitive.PanelResizeHandle>
|
||||
);
|
||||
};
|
||||
|
||||
export { ResizablePanelGroup, ResizablePanel, ResizableHandle };
|
||||
|
||||
+36
-43
@@ -16,17 +16,9 @@ type Props = {
|
||||
onChange?: (idx: number) => void;
|
||||
onClose?: (idx: number) => void;
|
||||
className?: string;
|
||||
containerClassName?: string;
|
||||
};
|
||||
|
||||
const Tabs = ({
|
||||
tabs,
|
||||
current = 0,
|
||||
onChange,
|
||||
onClose,
|
||||
className,
|
||||
containerClassName,
|
||||
}: Props) => {
|
||||
const Tabs = ({ tabs, current = 0, onChange, onClose, className }: Props) => {
|
||||
const tabContainerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const onWheel = (e: WheelEvent) => {
|
||||
@@ -64,43 +56,44 @@ const Tabs = ({
|
||||
container.scrollTo({ left: scrollX, behavior: "smooth" });
|
||||
}, [tabs, current]);
|
||||
|
||||
const tabView = useMemo(() => {
|
||||
const tab = tabs[current];
|
||||
const element = tab?.render ? tab.render() : null;
|
||||
return element;
|
||||
}, [tabs, current]);
|
||||
|
||||
return (
|
||||
<div
|
||||
return tabs.length > 0 ? (
|
||||
<nav
|
||||
ref={tabContainerRef}
|
||||
className={cn(
|
||||
"w-full flex flex-col items-stretch bg-slate-800",
|
||||
"flex items-stretch overflow-x-auto h-10 gap-1 hide-scrollbar",
|
||||
className
|
||||
)}
|
||||
>
|
||||
{tabs.length > 0 ? (
|
||||
<nav
|
||||
ref={tabContainerRef}
|
||||
className="flex items-stretch overflow-x-auto w-full h-10 min-h-10 hide-scrollbar"
|
||||
>
|
||||
{tabs.map((tab, idx) => (
|
||||
<TabItem
|
||||
key={idx}
|
||||
index={idx}
|
||||
title={tab.title}
|
||||
icon={tab.icon}
|
||||
isActive={idx === current}
|
||||
onSelect={() => onChange && onChange(idx)}
|
||||
onClose={!tab.locked && onClose ? () => onClose(idx) : null}
|
||||
/>
|
||||
))}
|
||||
</nav>
|
||||
) : null}
|
||||
{tabs.map((tab, idx) => (
|
||||
<TabItem
|
||||
key={idx}
|
||||
index={idx}
|
||||
title={tab.title}
|
||||
icon={tab.icon}
|
||||
isActive={idx === current}
|
||||
onSelect={() => onChange && onChange(idx)}
|
||||
onClose={!tab.locked && onClose ? () => onClose(idx) : null}
|
||||
/>
|
||||
))}
|
||||
</nav>
|
||||
) : null;
|
||||
};
|
||||
|
||||
<main className={cn("flex-1 overflow-hidden", containerClassName)}>
|
||||
{tabView}
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
type TabViewProps = {
|
||||
tabs: Tab[];
|
||||
current: number;
|
||||
className?: string;
|
||||
};
|
||||
|
||||
export const TabView = ({ tabs, current, className }: TabViewProps) => {
|
||||
const tabView = useMemo(() => {
|
||||
const tab = tabs[current];
|
||||
const element = tab?.render ? tab.render() : null;
|
||||
|
||||
return element;
|
||||
}, [tabs, current]);
|
||||
|
||||
return <main className={cn("overflow-hidden", className)}>{tabView}</main>;
|
||||
};
|
||||
|
||||
type TabItemProps = {
|
||||
@@ -128,8 +121,8 @@ const TabItem = ({
|
||||
<div
|
||||
data-idx={index}
|
||||
className={cn(
|
||||
"group border-b-2 border-transparent truncate flex-shrink-0 text-white/70 transition-all hover:text-white text-center max-w-[140px] md:max-w-[180px] text-sm flex items-center gap-0 relative z-[1]",
|
||||
isActive ? "border-slate-500 text-white" : ""
|
||||
"group truncate flex-shrink-0 h-full bg-white/10 rounded-lg text-white/70 transition-all hover:text-white text-center max-w-[140px] md:max-w-[180px] text-sm flex items-center gap-0 relative z-[1]",
|
||||
isActive ? "bg-white/20 text-white" : ""
|
||||
)}
|
||||
onClick={onSelect}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user