Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 6 additions & 9 deletions apps/dashboard/.storybook/preview.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import type { Preview } from "@storybook/nextjs";
import "../src/global.css";
import "@workspace/ui/global.css";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { Button } from "@workspace/ui/components/button";
import { MoonIcon, SunIcon } from "lucide-react";
import { ThemeProvider, useTheme } from "next-themes";
import { Inter as interFont } from "next/font/google";
// biome-ignore lint/style/useImportType: <explanation>
import React from "react";
import { useEffect } from "react";
import { ThemeProvider, useTheme } from "next-themes";
// biome-ignore lint/style/useImportType: ok
import React, { useEffect } from "react";
import { Toaster } from "sonner";
import { Button } from "../src/@/components/ui/button";

const queryClient = new QueryClient();

Expand Down Expand Up @@ -69,9 +68,7 @@ const preview: Preview = {

export default preview;

function StoryLayout(props: {
children: React.ReactNode;
}) {
function StoryLayout(props: { children: React.ReactNode }) {
const { setTheme, theme } = useTheme();

useEffect(() => {
Expand Down
41 changes: 2 additions & 39 deletions apps/dashboard/src/@/components/ui/badge.tsx
Original file line number Diff line number Diff line change
@@ -1,39 +1,2 @@
import { cva, type VariantProps } from "class-variance-authority";
import type * as React from "react";

import { cn } from "@/lib/utils";

const badgeVariants = cva(
"inline-flex items-center rounded-full border border-border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 leading-4",
{
defaultVariants: {
variant: "default",
},
variants: {
variant: {
default: "border-transparent bg-primary/20 text-primary",
destructive:
"border-transparent dark:bg-red-950 dark:text-red-400 bg-red-500/20 text-red-800",
outline: "text-foreground",
secondary:
"border-transparent bg-accent text-accent-foreground hover:bg-accent/80",
success:
"border-transparent dark:bg-green-950/50 dark:text-green-400 bg-green-200 text-green-950",
warning:
"border-transparent dark:bg-yellow-600/20 dark:text-yellow-500 bg-yellow-500/20 text-yellow-900",
},
},
},
);

export interface BadgeProps
extends React.HTMLAttributes<HTMLDivElement>,
VariantProps<typeof badgeVariants> {}

function Badge({ className, variant, ...props }: BadgeProps) {
return (
<div className={cn(badgeVariants({ variant }), className)} {...props} />
);
}

export { Badge, badgeVariants };
export type { BadgeProps } from "@workspace/ui/components/badge";
export { Badge, badgeVariants } from "@workspace/ui/components/badge";
26 changes: 1 addition & 25 deletions apps/dashboard/src/@/components/ui/input.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1 @@
import * as React from "react";

import { cn } from "@/lib/utils";

export interface InputProps
extends React.InputHTMLAttributes<HTMLInputElement> {}

const Input = React.forwardRef<HTMLInputElement, InputProps>(
({ className, type, ...props }, ref) => {
return (
<input
className={cn(
"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background selection:bg-inverted selection:text-inverted-foreground file:border-0 file:bg-transparent file:font-medium file:text-sm placeholder:text-muted-foreground placeholder:text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
className,
)}
ref={ref}
type={type}
{...props}
/>
);
},
);
Input.displayName = "Input";

export { Input };
export { Input } from "@workspace/ui/components/input";
41 changes: 2 additions & 39 deletions apps/playground-web/src/components/ui/badge.tsx
Original file line number Diff line number Diff line change
@@ -1,39 +1,2 @@
import { cva, type VariantProps } from "class-variance-authority";
import type * as React from "react";

import { cn } from "@/lib/utils";

const badgeVariants = cva(
"inline-flex items-center rounded-full border border-border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 leading-4",
{
defaultVariants: {
variant: "default",
},
variants: {
variant: {
default: "border-transparent bg-primary/20 text-primary",
destructive:
"border-transparent dark:bg-red-950 dark:text-red-400 bg-red-500/20 text-red-800",
outline: "text-foreground",
secondary:
"border-transparent bg-accent text-accent-foreground hover:bg-accent/80",
success:
"border-transparent dark:bg-green-950/50 dark:text-green-400 bg-green-200 text-green-950",
warning:
"border-transparent dark:bg-yellow-600/20 dark:text-yellow-500 bg-yellow-500/20 text-yellow-900",
},
},
},
);

export interface BadgeProps
extends React.HTMLAttributes<HTMLDivElement>,
VariantProps<typeof badgeVariants> {}

function Badge({ className, variant, ...props }: BadgeProps) {
return (
<div className={cn(badgeVariants({ variant }), className)} {...props} />
);
}

export { Badge, badgeVariants };
export type { BadgeProps } from "@workspace/ui/components/badge";
export { Badge, badgeVariants } from "@workspace/ui/components/badge";
26 changes: 1 addition & 25 deletions apps/playground-web/src/components/ui/input.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1 @@
import * as React from "react";

import { cn } from "@/lib/utils";

export interface InputProps
extends React.InputHTMLAttributes<HTMLInputElement> {}

const Input = React.forwardRef<HTMLInputElement, InputProps>(
({ className, type, ...props }, ref) => {
return (
<input
className={cn(
"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background file:border-0 file:bg-transparent file:font-medium file:text-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
className,
)}
ref={ref}
type={type}
{...props}
/>
);
},
);
Input.displayName = "Input";

export { Input };
export { Input } from "@workspace/ui/components/input";
3 changes: 2 additions & 1 deletion apps/portal/knip.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
"@workspace/ui",
"@types/flexsearch",
"@radix-ui/react-slot",
"tailwindcss-animate"
"tailwindcss-animate",
"class-variance-authority"
],
"next": true,
"project": ["src/**"]
Expand Down
41 changes: 2 additions & 39 deletions apps/portal/src/components/ui/badge.tsx
Original file line number Diff line number Diff line change
@@ -1,39 +1,2 @@
import { cva, type VariantProps } from "class-variance-authority";
import type * as React from "react";

import { cn } from "@/lib/utils";

const badgeVariants = cva(
"inline-flex items-center rounded-full border border-border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 leading-4",
{
defaultVariants: {
variant: "default",
},
variants: {
variant: {
default: "border-transparent bg-primary/20 text-primary",
destructive:
"border-transparent dark:bg-red-950 dark:text-red-400 bg-red-500/20 text-red-800",
outline: "text-foreground",
secondary:
"border-transparent bg-accent text-accent-foreground hover:bg-accent/80",
success:
"border-transparent dark:bg-green-950/50 dark:text-green-400 bg-green-200 text-green-950",
warning:
"border-transparent dark:bg-yellow-600/20 dark:text-yellow-500 bg-yellow-500/20 text-yellow-900",
},
},
},
);

export interface BadgeProps
extends React.HTMLAttributes<HTMLDivElement>,
VariantProps<typeof badgeVariants> {}

function Badge({ className, variant, ...props }: BadgeProps) {
return (
<div className={cn(badgeVariants({ variant }), className)} {...props} />
);
}

export { Badge, badgeVariants };
export type { BadgeProps } from "@workspace/ui/components/badge";
export { Badge, badgeVariants } from "@workspace/ui/components/badge";
26 changes: 1 addition & 25 deletions apps/portal/src/components/ui/input.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1 @@
import * as React from "react";

import { cn } from "@/lib/utils";

export interface InputProps
extends React.InputHTMLAttributes<HTMLInputElement> {}

const Input = React.forwardRef<HTMLInputElement, InputProps>(
({ className, type, ...props }, ref) => {
return (
<input
className={cn(
"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background selection:bg-foreground selection:text-background file:border-0 file:bg-transparent file:font-medium file:text-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
className,
)}
ref={ref}
type={type}
{...props}
/>
);
},
);
Input.displayName = "Input";

export { Input };
export { Input } from "@workspace/ui/components/input";
28 changes: 28 additions & 0 deletions packages/ui/.storybook/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { dirname, join } from "node:path";
import type { StorybookConfig } from "@storybook/nextjs";

/**
* This function is used to resolve the absolute path of a package.
* It is needed in projects that use Yarn PnP or are set up within a monorepo.
*/
function getAbsolutePath(value: string): string {
return dirname(require.resolve(join(value, "package.json")));
}

const config: StorybookConfig = {
stories: ["../src/**/*.stories.tsx"],
addons: [
getAbsolutePath("@storybook/addon-onboarding"),
getAbsolutePath("@storybook/addon-links"),
getAbsolutePath("@chromatic-com/storybook"),
getAbsolutePath("@storybook/addon-docs"),
],
framework: {
name: getAbsolutePath("@storybook/nextjs"),
options: {},
},
features: {
experimentalRSC: true,
},
};
export default config;
106 changes: 106 additions & 0 deletions packages/ui/.storybook/preview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import type { Preview } from "@storybook/nextjs";
import "../src/global.css";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { MoonIcon, SunIcon } from "lucide-react";
import { Inter as interFont } from "next/font/google";
import { ThemeProvider, useTheme } from "next-themes";
// biome-ignore lint/style/useImportType: ok
import React, { useEffect } from "react";
import { Toaster } from "sonner";
import { Button } from "../src/components/button";

const queryClient = new QueryClient();

const fontSans = interFont({
display: "swap",
subsets: ["latin"],
variable: "--font-sans",
});

const customViewports = {
xs: {
// Regular sized phones (iphone 15 / 15 pro)
name: "iPhone",
styles: {
width: "390px",
height: "844px",
},
},
sm: {
// Larger phones (iphone 15 plus / 15 pro max)
name: "iPhone Plus",
styles: {
width: "430px",
height: "932px",
},
},
};

const preview: Preview = {
parameters: {
viewport: {
viewports: customViewports,
},
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/i,
},
},
},
decorators: [
(Story) => {
return (
<ThemeProvider
attribute="class"
disableTransitionOnChange
enableSystem={false}
defaultTheme="dark"
>
<StoryLayout>
<Story />
</StoryLayout>
</ThemeProvider>
);
},
],
};

export default preview;

function StoryLayout(props: { children: React.ReactNode }) {
const { setTheme, theme } = useTheme();

useEffect(() => {
document.body.className = `font-sans antialiased ${fontSans.variable}`;
}, []);

return (
<QueryClientProvider client={queryClient}>
<div className="flex min-h-dvh min-w-0 flex-col bg-background text-foreground">
<div className="fixed right-0 bottom-0 z-50 flex justify-end gap-2 p-4">
<Button
onClick={() => setTheme(theme === "dark" ? "light" : "dark")}
size="sm"
variant="outline"
className="h-auto w-auto shrink-0 rounded-full p-2"
>
{theme === "dark" ? (
<MoonIcon className="size-4" />
) : (
<SunIcon className="size-4" />
)}
</Button>
</div>

<div className="flex min-w-0 grow flex-col">{props.children}</div>
<ToasterSetup />
</div>
</QueryClientProvider>
);
}

function ToasterSetup() {
const { theme } = useTheme();
return <Toaster richColors theme={theme === "light" ? "light" : "dark"} />;
}
Loading
Loading