rechta-ds 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/.changeset/config.json +11 -0
  2. package/.github/workflows/release.yml +53 -0
  3. package/.github/workflows/storybook.yml +34 -0
  4. package/.storybook/main.ts +17 -0
  5. package/.storybook/preview.ts +35 -0
  6. package/CHANGELOG.md +65 -0
  7. package/CONTRIBUTING.md +106 -0
  8. package/README.md +206 -0
  9. package/package.json +30 -0
  10. package/packages/tokens/build.js +357 -0
  11. package/packages/tokens/package.json +44 -0
  12. package/packages/tokens/src/tokens.json +1538 -0
  13. package/packages/ui/.storybook/main.ts +17 -0
  14. package/packages/ui/.storybook/preview.tsx +37 -0
  15. package/packages/ui/package.json +109 -0
  16. package/packages/ui/postcss.config.js +6 -0
  17. package/packages/ui/src/components/atoms/Avatar.tsx +139 -0
  18. package/packages/ui/src/components/atoms/Badge.tsx +62 -0
  19. package/packages/ui/src/components/atoms/Button.tsx +125 -0
  20. package/packages/ui/src/components/atoms/Input.tsx +116 -0
  21. package/packages/ui/src/components/atoms/Misc.tsx +128 -0
  22. package/packages/ui/src/components/atoms/Toggle.tsx +191 -0
  23. package/packages/ui/src/components/atoms/Typography.tsx +178 -0
  24. package/packages/ui/src/components/atoms/index.ts +7 -0
  25. package/packages/ui/src/components/charts/Charts.tsx +380 -0
  26. package/packages/ui/src/components/charts/DataTable.tsx +222 -0
  27. package/packages/ui/src/components/charts/index.ts +19 -0
  28. package/packages/ui/src/components/molecules/Accordion.tsx +93 -0
  29. package/packages/ui/src/components/molecules/Card.tsx +100 -0
  30. package/packages/ui/src/components/molecules/PricingCard.tsx +196 -0
  31. package/packages/ui/src/components/molecules/TestimonialCard.tsx +85 -0
  32. package/packages/ui/src/components/molecules/Tooltip.tsx +71 -0
  33. package/packages/ui/src/components/molecules/index.ts +5 -0
  34. package/packages/ui/src/components/organisms/FeatureTabs.tsx +196 -0
  35. package/packages/ui/src/components/organisms/LogoMarquee.tsx +119 -0
  36. package/packages/ui/src/components/organisms/Navbar.tsx +194 -0
  37. package/packages/ui/src/components/organisms/index.ts +3 -0
  38. package/packages/ui/src/index.ts +15 -0
  39. package/packages/ui/src/lib/utils.ts +12 -0
  40. package/packages/ui/src/stories/atoms/Avatar.stories.tsx +49 -0
  41. package/packages/ui/src/stories/atoms/Badge.stories.tsx +68 -0
  42. package/packages/ui/src/stories/atoms/Button.stories.tsx +98 -0
  43. package/packages/ui/src/stories/atoms/Input.stories.tsx +66 -0
  44. package/packages/ui/src/stories/atoms/Toggle.stories.tsx +36 -0
  45. package/packages/ui/src/stories/molecules/Accordion.stories.tsx +47 -0
  46. package/packages/ui/src/stories/molecules/Card.stories.tsx +84 -0
  47. package/packages/ui/src/stories/molecules/PricingCard.stories.tsx +62 -0
  48. package/packages/ui/src/stories/molecules/TestimonialCard.stories.tsx +52 -0
  49. package/packages/ui/src/stories/molecules/Tooltip.stories.tsx +66 -0
  50. package/packages/ui/src/stories/organisms/LogoMarquee.stories.tsx +33 -0
  51. package/packages/ui/src/stories/organisms/Navbar.stories.tsx +37 -0
  52. package/packages/ui/src/styles/globals.css +220 -0
  53. package/packages/ui/tailwind.config.ts +68 -0
  54. package/packages/ui/tsconfig.json +23 -0
  55. package/packages/ui/tsup.config.ts +24 -0
  56. package/packages/ui/vite.config.ts +17 -0
  57. package/pnpm-workspace.yaml +2 -0
  58. package/turbo.json +33 -0
@@ -0,0 +1,98 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { Button } from '../../components/atoms/Button';
3
+ import { Plus, ArrowRight, Loader2, Trash2, ExternalLink } from 'lucide-react';
4
+
5
+ const meta: Meta<typeof Button> = {
6
+ title: 'Atoms/Button',
7
+ component: Button,
8
+ tags: ['autodocs'],
9
+ parameters: { layout: 'centered' },
10
+ argTypes: {
11
+ variant: {
12
+ control: 'select',
13
+ options: ['default','emerald','blue','porcelain','secondary','ghost','outline','destructive','link'],
14
+ },
15
+ size: {
16
+ control: 'select',
17
+ options: ['xs','sm','md','lg','xl','icon','icon-sm','icon-lg'],
18
+ },
19
+ loading: { control: 'boolean' },
20
+ disabled: { control: 'boolean' },
21
+ },
22
+ };
23
+
24
+ export default meta;
25
+ type Story = StoryObj<typeof Button>;
26
+
27
+ export const Default: Story = {
28
+ args: { children: 'Get started' },
29
+ };
30
+
31
+ export const Variants: Story = {
32
+ render: () => (
33
+ <div className="flex flex-wrap gap-3 items-center">
34
+ <Button variant="default">Brand</Button>
35
+ <Button variant="emerald">Emerald</Button>
36
+ <Button variant="blue">Blue</Button>
37
+ <Button variant="porcelain">Porcelain</Button>
38
+ <Button variant="secondary">Secondary</Button>
39
+ <Button variant="ghost">Ghost</Button>
40
+ <Button variant="outline">Outline</Button>
41
+ <Button variant="destructive">Destructive</Button>
42
+ <Button variant="link">Link</Button>
43
+ </div>
44
+ ),
45
+ };
46
+
47
+ export const Sizes: Story = {
48
+ render: () => (
49
+ <div className="flex flex-wrap gap-3 items-center">
50
+ <Button size="xs">Extra small</Button>
51
+ <Button size="sm">Small</Button>
52
+ <Button size="md">Medium</Button>
53
+ <Button size="lg">Large</Button>
54
+ <Button size="xl">Extra large</Button>
55
+ </div>
56
+ ),
57
+ };
58
+
59
+ export const WithIcons: Story = {
60
+ render: () => (
61
+ <div className="flex flex-wrap gap-3 items-center">
62
+ <Button leftIcon={<Plus />}>Create link</Button>
63
+ <Button rightIcon={<ArrowRight />}>Learn more</Button>
64
+ <Button variant="secondary" leftIcon={<ExternalLink />}>Open</Button>
65
+ <Button size="icon"><Plus /></Button>
66
+ <Button size="icon-sm" variant="ghost"><Plus /></Button>
67
+ <Button size="icon-lg" variant="outline"><Plus /></Button>
68
+ </div>
69
+ ),
70
+ };
71
+
72
+ export const Loading: Story = {
73
+ render: () => (
74
+ <div className="flex flex-wrap gap-3 items-center">
75
+ <Button loading>Saving…</Button>
76
+ <Button loading variant="secondary" loadingText="Processing…">Submit</Button>
77
+ <Button loading variant="outline">Loading</Button>
78
+ </div>
79
+ ),
80
+ };
81
+
82
+ export const Disabled: Story = {
83
+ render: () => (
84
+ <div className="flex flex-wrap gap-3 items-center">
85
+ <Button disabled>Disabled</Button>
86
+ <Button disabled variant="secondary">Disabled</Button>
87
+ <Button disabled variant="ghost">Disabled</Button>
88
+ </div>
89
+ ),
90
+ };
91
+
92
+ export const Destructive: Story = {
93
+ args: {
94
+ variant: 'destructive',
95
+ children: 'Delete workspace',
96
+ leftIcon: <Trash2 />,
97
+ },
98
+ };
@@ -0,0 +1,66 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { Input, Textarea } from '../../components/atoms/Input';
3
+ import { Search, Mail, Eye, Lock } from 'lucide-react';
4
+
5
+ const meta: Meta<typeof Input> = {
6
+ title: 'Atoms/Input',
7
+ component: Input,
8
+ tags: ['autodocs'],
9
+ parameters: { layout: 'centered' },
10
+ argTypes: {
11
+ size: { control: 'select', options: ['sm','md','lg'] },
12
+ state: { control: 'select', options: ['default','error','success','warning'] },
13
+ disabled: { control: 'boolean' },
14
+ },
15
+ };
16
+
17
+ export default meta;
18
+ type Story = StoryObj<typeof Input>;
19
+
20
+ export const Default: Story = {
21
+ args: { placeholder: 'https://example.com/long-path' },
22
+ };
23
+
24
+ export const AllSizes: Story = {
25
+ render: () => (
26
+ <div className="flex flex-col gap-3 w-72">
27
+ <Input size="sm" placeholder="Small input" />
28
+ <Input size="md" placeholder="Medium input" />
29
+ <Input size="lg" placeholder="Large input" />
30
+ </div>
31
+ ),
32
+ };
33
+
34
+ export const WithIcons: Story = {
35
+ render: () => (
36
+ <div className="flex flex-col gap-3 w-72">
37
+ <Input leftElement={<Search />} placeholder="Search links…" />
38
+ <Input leftElement={<Mail />} placeholder="email@company.com" type="email" />
39
+ <Input leftElement={<Lock />} rightElement={<Eye />} placeholder="Password" type="password" />
40
+ </div>
41
+ ),
42
+ };
43
+
44
+ export const States: Story = {
45
+ render: () => (
46
+ <div className="flex flex-col gap-3 w-72">
47
+ <Input state="default" placeholder="Default state" />
48
+ <Input state="success" placeholder="success@rechta.com" />
49
+ <Input state="warning" placeholder="Warning state" />
50
+ <Input state="error" placeholder="Error state" />
51
+ <Input disabled placeholder="Disabled input" />
52
+ <Input readOnly defaultValue="Read only value" />
53
+ </div>
54
+ ),
55
+ };
56
+
57
+ export const TextareaStory: Story = {
58
+ name: 'Textarea',
59
+ render: () => (
60
+ <div className="flex flex-col gap-3 w-80">
61
+ <Textarea placeholder="Write something…" />
62
+ <Textarea state="error" placeholder="Invalid content" />
63
+ <Textarea resize="none" placeholder="No resize" />
64
+ </div>
65
+ ),
66
+ };
@@ -0,0 +1,36 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { Toggle } from '../../components/atoms/Toggle';
3
+
4
+ const meta: Meta<typeof Toggle> = {
5
+ title: 'Atoms/Toggle',
6
+ component: Toggle,
7
+ tags: ['autodocs'],
8
+ parameters: { layout: 'centered' },
9
+ };
10
+
11
+ export default meta;
12
+ type Story = StoryObj<typeof Toggle>;
13
+
14
+ export const Default: Story = {
15
+ args: { label: 'Enable notifications' },
16
+ };
17
+
18
+ export const Controlled: Story = {
19
+ render: () => (
20
+ <div className="flex flex-col gap-4">
21
+ <Toggle label="Link cloaking" defaultChecked />
22
+ <Toggle label="Password protection" />
23
+ <Toggle label="Link expiration" defaultChecked />
24
+ <Toggle label="A/B testing" />
25
+ </div>
26
+ ),
27
+ };
28
+
29
+ export const WithoutLabel: Story = {
30
+ render: () => (
31
+ <div className="flex gap-4 items-center">
32
+ <Toggle />
33
+ <Toggle defaultChecked />
34
+ </div>
35
+ ),
36
+ };
@@ -0,0 +1,47 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { Accordion } from '../../components/molecules/Accordion';
3
+
4
+ const meta: Meta<typeof Accordion> = {
5
+ title: 'Molecules/Accordion',
6
+ component: Accordion,
7
+ tags: ['autodocs'],
8
+ parameters: { layout: 'centered' },
9
+ };
10
+
11
+ export default meta;
12
+ type Story = StoryObj<typeof Accordion>;
13
+
14
+ const faqItems = [
15
+ {
16
+ trigger: 'Which Rechta plan is right for me?',
17
+ content: 'If you\'re just getting started, the free plan gives you 1K events/mo. For small teams, Pro at $25/mo is perfect. Business at $75/mo includes conversion tracking and partner management.',
18
+ },
19
+ {
20
+ trigger: 'Do you offer a free trial?',
21
+ content: 'Yes — the free plan is forever-free. All paid plans include a 14-day free trial, no credit card required.',
22
+ },
23
+ {
24
+ trigger: 'Can I cancel my subscription at any time?',
25
+ content: 'Absolutely. Cancel anytime from your workspace settings. You\'ll retain access until the end of your billing period.',
26
+ },
27
+ {
28
+ trigger: 'What are your data privacy & security policies?',
29
+ content: 'We are SOC 2 Type II certified. All data is encrypted at rest and in transit. We never sell your data to third parties.',
30
+ },
31
+ ];
32
+
33
+ export const FAQ: Story = {
34
+ render: () => (
35
+ <div className="w-[520px]">
36
+ <Accordion items={faqItems} />
37
+ </div>
38
+ ),
39
+ };
40
+
41
+ export const SingleOpen: Story = {
42
+ render: () => (
43
+ <div className="w-[520px]">
44
+ <Accordion items={faqItems.slice(0, 2)} type="single" />
45
+ </div>
46
+ ),
47
+ };
@@ -0,0 +1,84 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from '../../components/molecules/Card';
3
+ import { Button } from '../../components/atoms/Button';
4
+ import { Badge } from '../../components/atoms/Badge';
5
+
6
+ const meta: Meta<typeof Card> = {
7
+ title: 'Molecules/Card',
8
+ component: Card,
9
+ tags: ['autodocs'],
10
+ parameters: { layout: 'centered' },
11
+ argTypes: {
12
+ variant: {
13
+ control: 'select',
14
+ options: ['default','raised','sunken','glass','brand','outline','ghost'],
15
+ },
16
+ padding: {
17
+ control: 'select',
18
+ options: ['none','sm','md','lg','xl'],
19
+ },
20
+ hover: { control: 'boolean' },
21
+ glow: { control: 'select', options: ['none','brand','accent'] },
22
+ },
23
+ };
24
+
25
+ export default meta;
26
+ type Story = StoryObj<typeof Card>;
27
+
28
+ export const Default: Story = {
29
+ render: () => (
30
+ <Card className="w-80">
31
+ <CardHeader>
32
+ <CardTitle>Short Links</CardTitle>
33
+ <CardDescription>Create and manage branded short links at scale.</CardDescription>
34
+ </CardHeader>
35
+ <CardContent className="mt-4">
36
+ <p className="text-sm text-[--c-text-3]">Manage your links with advanced features, folders, and RBAC.</p>
37
+ </CardContent>
38
+ <CardFooter>
39
+ <Button size="sm">Explore links</Button>
40
+ <Button size="sm" variant="ghost">Learn more</Button>
41
+ </CardFooter>
42
+ </Card>
43
+ ),
44
+ };
45
+
46
+ export const Variants: Story = {
47
+ render: () => (
48
+ <div className="grid grid-cols-2 gap-4">
49
+ {(['default','raised','sunken','glass','brand','outline'] as const).map((v) => (
50
+ <Card key={v} variant={v} className="w-56 h-28 flex items-center justify-center">
51
+ <span className="text-sm text-[--c-text-2] font-mono">{v}</span>
52
+ </Card>
53
+ ))}
54
+ </div>
55
+ ),
56
+ };
57
+
58
+ export const WithGlow: Story = {
59
+ render: () => (
60
+ <div className="flex gap-4">
61
+ <Card variant="default" glow="brand" className="w-56 h-28 flex items-center justify-center">
62
+ <Badge variant="brand" dot>Brand glow</Badge>
63
+ </Card>
64
+ <Card variant="default" glow="accent" className="w-56 h-28 flex items-center justify-center">
65
+ <Badge variant="blue" dot>Accent glow</Badge>
66
+ </Card>
67
+ </div>
68
+ ),
69
+ };
70
+
71
+ export const Hoverable: Story = {
72
+ render: () => (
73
+ <Card hover className="w-72 cursor-pointer">
74
+ <CardHeader>
75
+ <CardTitle>acme.link/homepage</CardTitle>
76
+ <CardDescription>acme.com/homepage</CardDescription>
77
+ </CardHeader>
78
+ <CardContent className="mt-3 flex items-center justify-between">
79
+ <span className="text-xs text-[--c-text-3]">15.6K clicks</span>
80
+ <Badge variant="success" dot>Verified</Badge>
81
+ </CardContent>
82
+ </Card>
83
+ ),
84
+ };
@@ -0,0 +1,62 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { PricingCard } from '../../components/molecules/PricingCard';
3
+
4
+ const meta: Meta<typeof PricingCard> = {
5
+ title: 'Molecules/PricingCard',
6
+ component: PricingCard,
7
+ tags: ['autodocs'],
8
+ parameters: { layout: 'centered' },
9
+ };
10
+
11
+ export default meta;
12
+ type Story = StoryObj<typeof PricingCard>;
13
+
14
+ export const Default: Story = {
15
+ args: {
16
+ name: 'Business',
17
+ price: '$75',
18
+ period: '/mo',
19
+ description: 'For fast-growing startups',
20
+ features: [
21
+ '250K tracked events/mo',
22
+ '10K new links/mo',
23
+ '3-year analytics retention',
24
+ 'Conversion tracking',
25
+ 'A/B testing',
26
+ 'Customer insights',
27
+ ],
28
+ popular: true,
29
+ cta: 'Get started',
30
+ },
31
+ };
32
+
33
+ export const PricingRow: Story = {
34
+ render: () => (
35
+ <div className="flex gap-4 items-start">
36
+ <PricingCard
37
+ name="Pro"
38
+ price="$25"
39
+ period="/mo"
40
+ description="For small teams"
41
+ features={['50K events/mo','1K links/mo','1-year retention','Free .link domain']}
42
+ cta="Get started"
43
+ />
44
+ <PricingCard
45
+ name="Business"
46
+ price="$75"
47
+ period="/mo"
48
+ description="For fast-growing startups"
49
+ features={['250K events/mo','10K links/mo','3-year retention','Conversion tracking']}
50
+ popular
51
+ cta="Get started"
52
+ />
53
+ <PricingCard
54
+ name="Enterprise"
55
+ price="Custom"
56
+ description="Tailored for large orgs"
57
+ features={['Unlimited events','SSO/SAML','Audit logs','Custom SLA']}
58
+ cta="Get a demo"
59
+ />
60
+ </div>
61
+ ),
62
+ };
@@ -0,0 +1,52 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { TestimonialCard } from '../../components/molecules/TestimonialCard';
3
+
4
+ const meta: Meta<typeof TestimonialCard> = {
5
+ title: 'Molecules/TestimonialCard',
6
+ component: TestimonialCard,
7
+ tags: ['autodocs'],
8
+ parameters: { layout: 'centered' },
9
+ };
10
+
11
+ export default meta;
12
+ type Story = StoryObj<typeof TestimonialCard>;
13
+
14
+ export const Default: Story = {
15
+ args: {
16
+ quote: 'What you all have built is fantastic. The best link attribution platform I\'ve used — by a wide margin.',
17
+ name: 'Ian Mackey',
18
+ role: 'Vice President, Scicomm Media',
19
+ avatarFallback: 'IM',
20
+ },
21
+ };
22
+
23
+ export const Grid: Story = {
24
+ render: () => (
25
+ <div className="grid grid-cols-2 gap-4 w-[700px]">
26
+ <TestimonialCard
27
+ quote="Dub is simply the best way to track links. Clean, fast, and just works."
28
+ name="Jorn van Dijk"
29
+ role="CEO, Framer"
30
+ avatarFallback="JD"
31
+ />
32
+ <TestimonialCard
33
+ quote="Stripe for payments, Vercel for deployments, Rechta for links."
34
+ name="Guillermo Rauch"
35
+ role="CEO, Vercel"
36
+ avatarFallback="GR"
37
+ />
38
+ <TestimonialCard
39
+ quote="Our links get tens of millions of clicks monthly — Rechta handles it flawlessly."
40
+ name="Johnny Ho"
41
+ role="Co-founder, Perplexity"
42
+ avatarFallback="JH"
43
+ />
44
+ <TestimonialCard
45
+ quote="A breath of fresh air in link management — everything we needed, no bloat."
46
+ name="Nick Parsons"
47
+ role="Director of Marketing, Clerk"
48
+ avatarFallback="NP"
49
+ />
50
+ </div>
51
+ ),
52
+ };
@@ -0,0 +1,66 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } from '../../components/molecules/Tooltip';
3
+ import { Button } from '../../components/atoms/Button';
4
+ import { Badge } from '../../components/atoms/Badge';
5
+ import { Copy, ExternalLink } from 'lucide-react';
6
+
7
+ const meta: Meta = {
8
+ title: 'Molecules/Tooltip',
9
+ tags: ['autodocs'],
10
+ parameters: { layout: 'centered' },
11
+ decorators: [(Story) => <TooltipProvider><Story /></TooltipProvider>],
12
+ };
13
+
14
+ export default meta;
15
+ type Story = StoryObj;
16
+
17
+ export const Default: Story = {
18
+ render: () => (
19
+ <Tooltip>
20
+ <TooltipTrigger asChild>
21
+ <Button variant="secondary">Hover me</Button>
22
+ </TooltipTrigger>
23
+ <TooltipContent>Copy short link</TooltipContent>
24
+ </Tooltip>
25
+ ),
26
+ };
27
+
28
+ export const WithIcons: Story = {
29
+ render: () => (
30
+ <div className="flex gap-4">
31
+ <Tooltip>
32
+ <TooltipTrigger asChild>
33
+ <Button size="icon" variant="ghost"><Copy /></Button>
34
+ </TooltipTrigger>
35
+ <TooltipContent>Copy to clipboard</TooltipContent>
36
+ </Tooltip>
37
+ <Tooltip>
38
+ <TooltipTrigger asChild>
39
+ <Button size="icon" variant="ghost"><ExternalLink /></Button>
40
+ </TooltipTrigger>
41
+ <TooltipContent>Open in new tab</TooltipContent>
42
+ </Tooltip>
43
+ <Tooltip>
44
+ <TooltipTrigger asChild>
45
+ <Badge variant="default">12.5K clicks</Badge>
46
+ </TooltipTrigger>
47
+ <TooltipContent>View analytics →</TooltipContent>
48
+ </Tooltip>
49
+ </div>
50
+ ),
51
+ };
52
+
53
+ export const Sides: Story = {
54
+ render: () => (
55
+ <div className="grid grid-cols-2 gap-8 p-16">
56
+ {(['top','right','bottom','left'] as const).map((side) => (
57
+ <Tooltip key={side}>
58
+ <TooltipTrigger asChild>
59
+ <Button variant="outline" size="sm">{side}</Button>
60
+ </TooltipTrigger>
61
+ <TooltipContent side={side}>Tooltip on {side}</TooltipContent>
62
+ </Tooltip>
63
+ ))}
64
+ </div>
65
+ ),
66
+ };
@@ -0,0 +1,33 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { LogoMarquee } from '../../components/organisms/LogoMarquee';
3
+
4
+ const meta: Meta<typeof LogoMarquee> = {
5
+ title: 'Organisms/LogoMarquee',
6
+ component: LogoMarquee,
7
+ tags: ['autodocs'],
8
+ parameters: { layout: 'fullscreen' },
9
+ };
10
+
11
+ export default meta;
12
+ type Story = StoryObj<typeof LogoMarquee>;
13
+
14
+ const logos = [
15
+ { name: 'Framer', src: 'https://assets.dub.co/companies/framer.svg' },
16
+ { name: 'Perplexity', src: 'https://assets.dub.co/companies/perplexity.svg' },
17
+ { name: 'Vercel', src: 'https://assets.dub.co/companies/vercel.svg' },
18
+ { name: 'Twilio', src: 'https://assets.dub.co/companies/twilio.svg' },
19
+ { name: 'Superhuman', src: 'https://assets.dub.co/companies/superhuman.svg' },
20
+ { name: 'Buffer', src: 'https://assets.dub.co/companies/buffer.svg' },
21
+ { name: 'Clerk', src: 'https://assets.dub.co/companies/clerk.svg' },
22
+ ];
23
+
24
+ export const Default: Story = {
25
+ args: { logos },
26
+ };
27
+
28
+ export const WithTitle: Story = {
29
+ args: {
30
+ logos,
31
+ title: 'Trusted by 100,000+ customers',
32
+ },
33
+ };
@@ -0,0 +1,37 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { Navbar } from '../../components/organisms/Navbar';
3
+
4
+ const meta: Meta<typeof Navbar> = {
5
+ title: 'Organisms/Navbar',
6
+ component: Navbar,
7
+ tags: ['autodocs'],
8
+ parameters: { layout: 'fullscreen' },
9
+ };
10
+
11
+ export default meta;
12
+ type Story = StoryObj<typeof Navbar>;
13
+
14
+ export const Default: Story = {
15
+ args: {
16
+ logo: 'rechta',
17
+ links: [
18
+ { label: 'Links', href: '#' },
19
+ { label: 'Analytics', href: '#' },
20
+ { label: 'Partners', href: '#' },
21
+ { label: 'Enterprise', href: '#' },
22
+ { label: 'Pricing', href: '#' },
23
+ ],
24
+ cta: { label: 'Get started', href: '#' },
25
+ },
26
+ };
27
+
28
+ export const WithAnnouncement: Story = {
29
+ args: {
30
+ ...Default.args,
31
+ announcement: {
32
+ label: 'New',
33
+ text: 'Staggered reward durations are now live',
34
+ href: '#',
35
+ },
36
+ },
37
+ };