mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-03-21 08:59:22 +01:00
Add body type to request and tab dropdown
This commit is contained in:
@@ -21,6 +21,7 @@ export type ButtonProps = HTMLAttributes<HTMLElement> & {
|
||||
justify?: 'start' | 'center';
|
||||
type?: 'button' | 'submit';
|
||||
forDropdown?: boolean;
|
||||
disabled?: boolean;
|
||||
};
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
|
||||
@@ -2,18 +2,20 @@ import * as D from '@radix-ui/react-dropdown-menu';
|
||||
import { CheckIcon } from '@radix-ui/react-icons';
|
||||
import classnames from 'classnames';
|
||||
import { motion } from 'framer-motion';
|
||||
import type { ReactNode, ForwardedRef } from 'react';
|
||||
import type { ForwardedRef, ReactElement, ReactNode } from 'react';
|
||||
import { forwardRef, useImperativeHandle, useLayoutEffect, useState } from 'react';
|
||||
|
||||
interface DropdownMenuRadioProps {
|
||||
children: ReactNode;
|
||||
onValueChange: ((v: { label: string; value: string }) => void) | null;
|
||||
export interface DropdownMenuRadioItem {
|
||||
label: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface DropdownMenuRadioProps {
|
||||
children: ReactElement<typeof DropdownMenuTrigger>;
|
||||
onValueChange: ((v: DropdownMenuRadioItem) => void) | null;
|
||||
value: string;
|
||||
label?: string;
|
||||
items: {
|
||||
label: string;
|
||||
value: string;
|
||||
}[];
|
||||
items: DropdownMenuRadioItem[];
|
||||
}
|
||||
|
||||
export function DropdownMenuRadio({
|
||||
@@ -32,7 +34,7 @@ export function DropdownMenuRadio({
|
||||
|
||||
return (
|
||||
<D.Root>
|
||||
<DropdownMenuTrigger>{children}</DropdownMenuTrigger>
|
||||
{children}
|
||||
<DropdownMenuPortal>
|
||||
<DropdownMenuContent>
|
||||
{label && <DropdownMenuLabel>{label}</DropdownMenuLabel>}
|
||||
@@ -50,7 +52,7 @@ export function DropdownMenuRadio({
|
||||
}
|
||||
|
||||
export interface DropdownProps {
|
||||
children: ReactNode;
|
||||
children: ReactElement<typeof DropdownMenuTrigger>;
|
||||
items: (
|
||||
| {
|
||||
label: string;
|
||||
@@ -65,7 +67,7 @@ export interface DropdownProps {
|
||||
export function Dropdown({ children, items }: DropdownProps) {
|
||||
return (
|
||||
<D.Root>
|
||||
<DropdownMenuTrigger>{children}</DropdownMenuTrigger>
|
||||
{children}
|
||||
<DropdownMenuPortal>
|
||||
<DropdownMenuContent>
|
||||
{items.map((item, i) => {
|
||||
@@ -268,7 +270,7 @@ type DropdownMenuTriggerProps = D.DropdownMenuTriggerProps & {
|
||||
className?: string;
|
||||
};
|
||||
|
||||
function DropdownMenuTrigger({ children, className, ...props }: DropdownMenuTriggerProps) {
|
||||
export function DropdownMenuTrigger({ children, className, ...props }: DropdownMenuTriggerProps) {
|
||||
return (
|
||||
<D.Trigger asChild className={classnames(className)} {...props}>
|
||||
{children}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import * as T from '@radix-ui/react-tabs';
|
||||
import classnames from 'classnames';
|
||||
import type { ReactNode } from 'react';
|
||||
import type { ReactElement, ReactNode } from 'react';
|
||||
import { useState } from 'react';
|
||||
import { Button } from '../Button';
|
||||
import { ScrollArea } from '../ScrollArea';
|
||||
import type { DropdownMenuRadioItem, DropdownMenuRadioProps } from '../Dropdown';
|
||||
import { DropdownMenuRadio, DropdownMenuTrigger } from '../Dropdown';
|
||||
import { Icon } from '../Icon';
|
||||
import { HStack } from '../Stacks';
|
||||
|
||||
import './Tabs.css';
|
||||
@@ -11,7 +13,15 @@ import './Tabs.css';
|
||||
interface Props {
|
||||
defaultValue?: string;
|
||||
label: string;
|
||||
tabs: { value: string; label: ReactNode }[];
|
||||
tabs: {
|
||||
value: string;
|
||||
label: string;
|
||||
options?: {
|
||||
onValueChange: DropdownMenuRadioProps['onValueChange'];
|
||||
value: string;
|
||||
items: DropdownMenuRadioItem[];
|
||||
};
|
||||
}[];
|
||||
tabListClassName?: string;
|
||||
className?: string;
|
||||
children: ReactNode;
|
||||
@@ -32,43 +42,72 @@ export function Tabs({ defaultValue, label, children, tabs, className, tabListCl
|
||||
'h-auto flex items-center overflow-x-auto mb-1 pb-1',
|
||||
)}
|
||||
>
|
||||
{/*<ScrollArea className="w-full pb-2">*/}
|
||||
<HStack space={1}>
|
||||
{tabs.map((t) => (
|
||||
<TabTrigger key={t.value} value={t.value} active={t.value === value}>
|
||||
{t.label}
|
||||
</TabTrigger>
|
||||
))}
|
||||
{tabs.map((t) => {
|
||||
const isActive = t.value === value;
|
||||
if (t.options && isActive) {
|
||||
return (
|
||||
<DropdownMenuRadio
|
||||
key={t.value}
|
||||
items={t.options.items}
|
||||
value={t.options.value}
|
||||
onValueChange={t.options.onValueChange}
|
||||
>
|
||||
<DropdownMenuTrigger>
|
||||
<Button
|
||||
color="custom"
|
||||
size="sm"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
className={classnames(
|
||||
isActive
|
||||
? 'bg-gray-100 text-gray-900'
|
||||
: 'text-gray-600 hover:text-gray-900',
|
||||
)}
|
||||
>
|
||||
{t.options.items.find((i) => i.value === t.options?.value)?.label ?? ''}
|
||||
<Icon icon="triangleDown" className="-mr-1.5" />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
</DropdownMenuRadio>
|
||||
);
|
||||
} else if (t.options && !isActive) {
|
||||
return (
|
||||
<T.Trigger asChild key={t.value} value={t.value}>
|
||||
<Button
|
||||
color="custom"
|
||||
size="sm"
|
||||
className={classnames(
|
||||
isActive ? 'bg-gray-100 text-gray-900' : 'text-gray-600 hover:text-gray-900',
|
||||
)}
|
||||
>
|
||||
{t.options.items.find((i) => i.value === t.options?.value)?.label ?? ''}
|
||||
<Icon icon="triangleDown" className="-mr-1.5" />
|
||||
</Button>
|
||||
</T.Trigger>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<T.Trigger asChild key={t.value} value={t.value}>
|
||||
<Button
|
||||
color="custom"
|
||||
size="sm"
|
||||
className={classnames(
|
||||
isActive ? 'bg-gray-100 text-gray-900' : 'text-gray-600 hover:text-gray-900',
|
||||
)}
|
||||
>
|
||||
{t.label}
|
||||
</Button>
|
||||
</T.Trigger>
|
||||
);
|
||||
}
|
||||
})}
|
||||
</HStack>
|
||||
{/*</ScrollArea>*/}
|
||||
</T.List>
|
||||
{children}
|
||||
</T.Root>
|
||||
);
|
||||
}
|
||||
|
||||
interface TabTriggerProps {
|
||||
value: string;
|
||||
children: ReactNode;
|
||||
active?: boolean;
|
||||
}
|
||||
|
||||
export function TabTrigger({ value, children, active }: TabTriggerProps) {
|
||||
return (
|
||||
<T.Trigger value={value} asChild>
|
||||
<Button
|
||||
color="custom"
|
||||
size="sm"
|
||||
className={classnames(
|
||||
active ? 'bg-gray-100 text-gray-900' : 'text-gray-600 hover:text-gray-900',
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</Button>
|
||||
</T.Trigger>
|
||||
);
|
||||
}
|
||||
|
||||
interface TabContentProps {
|
||||
value: string;
|
||||
children: ReactNode;
|
||||
|
||||
Reference in New Issue
Block a user