Add dark mode
Signed-off-by: Bryan Frimin <bryan@getprobo.com> Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
committed by
Sacha Al Himdani
parent
faf1ce0eb9
commit
f9d1f033e0
@@ -1,4 +1,4 @@
|
||||
import { tv } from "tailwind-variants";
|
||||
import clsx from "clsx";
|
||||
|
||||
type Props = {
|
||||
name: string;
|
||||
@@ -6,28 +6,18 @@ type Props = {
|
||||
size?: "s" | "m" | "l" | "xl";
|
||||
};
|
||||
|
||||
const avatar = tv({
|
||||
base: "bg-txt-success text-txt-invert rounded-full font-semibold flex items-center justify-center",
|
||||
variants: {
|
||||
size: {
|
||||
s: "size-5 text-xss",
|
||||
m: "size-6 text-xxs",
|
||||
l: "size-8 text-sm",
|
||||
xl: "size-16 text-3xl",
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
size: "m",
|
||||
},
|
||||
});
|
||||
|
||||
export function Avatar({ name, src, size = "m" }: Props) {
|
||||
if (src) {
|
||||
return <img className={avatar({ size })} src={src} alt={name} />;
|
||||
}
|
||||
return (
|
||||
<div className={avatar({ size })}>{extractInitials(name ?? "")}</div>
|
||||
const className = clsx(
|
||||
"bg-txt-success text-txt-invert rounded-full font-semibold flex items-center justify-center",
|
||||
size === "s" && "size-5 text-xss",
|
||||
size === "m" && "size-6 text-xxs",
|
||||
size === "l" && "size-8 text-sm",
|
||||
size === "xl" && "size-16 text-3xl",
|
||||
);
|
||||
if (src) {
|
||||
return <img className={className} src={src} alt={name} />;
|
||||
}
|
||||
return <div className={className}>{extractInitials(name ?? "")}</div>;
|
||||
}
|
||||
|
||||
function extractInitials(name: string) {
|
||||
|
||||
@@ -9,7 +9,7 @@ type Props = PropsWithChildren<{
|
||||
}>;
|
||||
|
||||
const card = tv({
|
||||
base: "border border-border-low surface-1 rounded-2xl",
|
||||
base: "border border-border-low bg-level-1 rounded-2xl",
|
||||
variants: {
|
||||
padded: {
|
||||
true: "p-6",
|
||||
|
||||
@@ -74,6 +74,7 @@ export function ActionDropdown(
|
||||
{...props}
|
||||
toggle={
|
||||
<Button
|
||||
className="inline-flex"
|
||||
variant={props.variant ?? "tertiary"}
|
||||
icon={IconDotGrid1x3Horizontal}
|
||||
/>
|
||||
|
||||
@@ -13,7 +13,7 @@ export function Logo({ className }: Props) {
|
||||
viewBox="0 0 48 20"
|
||||
>
|
||||
<path
|
||||
fill="#141E12"
|
||||
fill="currentColor"
|
||||
d="M29.3 0v6.1c.06-.06.17-.13.3-.22.16-.1.46-.24.93-.4A4.7 4.7 0 0 1 32 5.26c1.36 0 2.5.46 3.42 1.4a4.59 4.59 0 0 1 1.38 3.38c0 1.34-.46 2.44-1.4 3.38a4.57 4.57 0 0 1-3.4 1.41 4.83 4.83 0 0 1-3.39-1.3 4.57 4.57 0 0 1-1.42-3.55V0h2.1ZM32 7.27a2.67 2.67 0 0 0-2.7 2.76c0 1.6 1.13 2.77 2.7 2.77 1.55 0 2.7-1.19 2.7-2.77A2.69 2.69 0 0 0 32 7.27ZM17.54 6.65a4.6 4.6 0 0 1 3.4-1.4c1.34 0 2.44.46 3.38 1.4a4.6 4.6 0 0 1 1.4 3.38c0 1.32-.46 2.46-1.4 3.4a4.66 4.66 0 0 1-3.38 1.4 4.7 4.7 0 0 1-3.4-1.4 4.6 4.6 0 0 1-1.41-3.4c0-1.34.46-2.43 1.4-3.38Zm.7 3.38c0 .82.26 1.48.77 2 .53.5 1.16.77 1.93.77.76 0 1.4-.26 1.9-.77a2.7 2.7 0 0 0 .8-2 2.6 2.6 0 0 0-.8-1.97 2.53 2.53 0 0 0-1.9-.8 2.68 2.68 0 0 0-2.7 2.77ZM39.67 6.65a4.6 4.6 0 0 1 3.4-1.4c1.34 0 2.44.46 3.38 1.4a4.6 4.6 0 0 1 1.4 3.38c0 1.32-.45 2.46-1.4 3.4a4.66 4.66 0 0 1-3.38 1.4 4.7 4.7 0 0 1-3.4-1.4 4.6 4.6 0 0 1-1.4-3.4c0-1.34.45-2.43 1.4-3.38Zm.7 3.38c0 .82.26 1.48.77 2 .53.5 1.16.77 1.93.77s1.4-.26 1.91-.77a2.7 2.7 0 0 0 .8-2 2.6 2.6 0 0 0-.8-1.97 2.53 2.53 0 0 0-1.9-.8 2.68 2.68 0 0 0-2.7 2.77ZM2.1 13.96V20H0v-9.9c0-1.52.48-2.7 1.43-3.56a4.9 4.9 0 0 1 3.38-1.3c1.3 0 2.48.47 3.4 1.41a4.6 4.6 0 0 1 1.4 3.39 4.71 4.71 0 0 1-4.8 4.78 4.53 4.53 0 0 1-2.39-.63l-.3-.22H2.1Zm2.7-6.7a2.66 2.66 0 0 0-2.7 2.77 2.69 2.69 0 0 0 2.7 2.77c1.52 0 2.7-1.17 2.7-2.77S6.33 7.27 4.8 7.27ZM13.08 14.7h-2.09V9.14c0-2.7 1.52-3.78 3.56-3.78h.5v2.03h-.4c-1.04 0-1.57.59-1.57 1.75v5.58Z"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -13,13 +13,7 @@ import * as ScrollArea from "@radix-ui/react-scroll-area";
|
||||
import { input } from "../Input/Input.tsx";
|
||||
import { IconChevronGrabberVertical } from "../Icons/IconChevronGrabberVertical.tsx";
|
||||
import { tv } from "tailwind-variants";
|
||||
import {
|
||||
Children,
|
||||
isValidElement,
|
||||
type ComponentProps,
|
||||
type PropsWithChildren,
|
||||
type ReactNode,
|
||||
} from "react";
|
||||
import { Children, type ComponentProps, type PropsWithChildren } from "react";
|
||||
|
||||
type Props = PropsWithChildren<
|
||||
{
|
||||
@@ -36,10 +30,10 @@ type Props = PropsWithChildren<
|
||||
const select = tv({
|
||||
slots: {
|
||||
trigger:
|
||||
"flex justify-between items-center data-placeholder:text-txt-tertiary whitespace-nowrap cursor-pointer",
|
||||
"flex justify-between items-center data-placeholder:text-txt-tertiary whitespace-nowrap cursor-pointer *:first:contents",
|
||||
content:
|
||||
"z-100 shadow-mid rounded-[10px] bg-level-1 p-1 animate-in fade-in slide-in-from-top-2 overflow-y-auto overflow-y-auto",
|
||||
option: "flex items-center h-8 text-sm font-medium text-txt-primary hover:bg-tertiary-hover active:bg-tertiary-pressed cursor-pointer px-[10px]",
|
||||
option: "flex gap-2 items-center h-8 text-sm font-medium text-txt-primary hover:bg-tertiary-hover active:bg-tertiary-pressed cursor-pointer px-[10px]",
|
||||
icon: "-mr-1",
|
||||
},
|
||||
variants: {
|
||||
@@ -79,23 +73,6 @@ const select = tv({
|
||||
|
||||
const { trigger, option, content, icon } = select();
|
||||
|
||||
/**
|
||||
* To display the selected value we need to find the selected option among children
|
||||
*/
|
||||
const findSelectedOption = (
|
||||
children: unknown[],
|
||||
condition: (c: { props: Record<string, unknown> }) => boolean,
|
||||
): ReactNode => {
|
||||
const selectedOptions = children.find(
|
||||
// @ts-expect-error We know that the children are ReactElements with props
|
||||
(c) => isValidElement(c) && condition(c),
|
||||
);
|
||||
if (!isValidElement(selectedOptions)) {
|
||||
return null;
|
||||
}
|
||||
return (selectedOptions.props as { children: ReactNode }).children;
|
||||
};
|
||||
|
||||
export function Select({
|
||||
placeholder,
|
||||
children,
|
||||
@@ -103,26 +80,10 @@ export function Select({
|
||||
value,
|
||||
...props
|
||||
}: Props) {
|
||||
const childrenArr = Children.toArray(children);
|
||||
const valueNode = value
|
||||
? findSelectedOption(
|
||||
childrenArr,
|
||||
(c) => c.props.value?.toString() === value?.toString(),
|
||||
)
|
||||
: undefined;
|
||||
|
||||
return (
|
||||
<Root onValueChange={onValueChange} value={value}>
|
||||
<Trigger {...props} className={trigger({ ...props })}>
|
||||
<div className="text-ellipsis overflow-hidden">
|
||||
<Value placeholder={placeholder}>
|
||||
{valueNode ? (
|
||||
<span className="flex items-center gap-2 overflow-hidden text-ellipsis w-full">
|
||||
{valueNode}
|
||||
</span>
|
||||
) : null}
|
||||
</Value>
|
||||
</div>
|
||||
<Value placeholder={placeholder} />
|
||||
<Icon className={icon()}>
|
||||
<IconChevronGrabberVertical size={16} />
|
||||
</Icon>
|
||||
@@ -152,10 +113,19 @@ export function Select({
|
||||
}
|
||||
|
||||
export function Option({ children, ...props }: ComponentProps<typeof Item>) {
|
||||
const hasSingleChildren = Children.count(children) <= 1;
|
||||
return (
|
||||
<Item {...props} className={option(props)}>
|
||||
<ItemText asChild>
|
||||
<span className="flex items-center gap-2">{children}</span>
|
||||
<span
|
||||
className={
|
||||
hasSingleChildren
|
||||
? "text-ellipsis overflow-hidden"
|
||||
: "flex gap-2 items-center"
|
||||
}
|
||||
>
|
||||
{children}
|
||||
</span>
|
||||
</ItemText>
|
||||
</Item>
|
||||
);
|
||||
|
||||
@@ -58,13 +58,23 @@ export function Tbody({ children }: PropsWithChildren) {
|
||||
export function Td({
|
||||
children,
|
||||
noLink,
|
||||
}: PropsWithChildren<{ noLink?: boolean }>) {
|
||||
className,
|
||||
}: PropsWithChildren<{ noLink?: boolean; className?: string }>) {
|
||||
const { to } = useContext(TrContext);
|
||||
if (!to || noLink) {
|
||||
return <td className="first:pl-6 last:pr-6 py-3">{children}</td>;
|
||||
return (
|
||||
<td className={clsx("first:pl-6 last:pr-6 py-3", className)}>
|
||||
{children}
|
||||
</td>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<td className="first:*:pl-6 *:block last:*:pr-6 py-3">
|
||||
<td
|
||||
className={clsx(
|
||||
"first:*:pl-6 *:block last:*:pr-6 *:py-3",
|
||||
className,
|
||||
)}
|
||||
>
|
||||
<Link to={to}>{children}</Link>
|
||||
</td>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user