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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@ packages/web/app/src/gql/*.json
# Changelog
packages/web/app/src/components/ui/changelog/generated-changelog.ts

# react-foundry
foundry-nav.gen.d.ts

_redirects

deployment/utils/opentelemetry-collector.types.ts
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"docker:build": "NODE_VERSION_TAG=\":$(< .node-version)-slim\" docker buildx bake -f docker/docker.hcl --load build",
"docker:override-up": "docker compose -f ./docker/docker-compose.override.yml up -d --remove-orphans",
"env:sync": "tsx scripts/sync-env-files.ts",
"foundry": "pnpm --filter @hive/app foundry",
"generate": "pnpm --filter @hive/storage db:generate && pnpm graphql:generate",
"graphql:generate": "VERBOSE=1 graphql-codegen --config codegen.mts",
"graphql:generate:watch": "pnpm graphql:generate --watch",
Expand Down
24 changes: 0 additions & 24 deletions packages/web/app/.ladle/components.tsx

This file was deleted.

5 changes: 0 additions & 5 deletions packages/web/app/.ladle/config.mjs

This file was deleted.

3 changes: 0 additions & 3 deletions packages/web/app/.ladle/ladle.css

This file was deleted.

15 changes: 0 additions & 15 deletions packages/web/app/.ladle/vite.config.ts

This file was deleted.

64 changes: 64 additions & 0 deletions packages/web/app/foundry.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { defineConfig } from 'react-foundry';
import tsconfigPaths from 'vite-tsconfig-paths';
import tailwindcss from '@tailwindcss/vite';

export default defineConfig({
previews: 'src/components/base/**/*.preview.tsx',
title: 'Hive Console Components',
// Declaration order is display order, so this groups the shelf by kind rather than
// alphabetically. It also narrows `NavPath` to these exact paths, which turns a typo in
// a preview's `nav` export into a type error instead of a stray top-level group.
nav: [
{
label: 'Base',
children: [
{
label: 'Primitives',
children: [
{ label: 'Accordion' },
{ label: 'Badge' },
{ label: 'Button' },
{ label: 'Card' },
{ label: 'Input' },
],
},
{
label: 'FormControls',
children: [
{ label: 'Checkbox' },
{ label: 'RadioGroup' },
{ label: 'Switch' },
{ label: 'Form' },
],
},
{
label: 'Floating',
children: [
{ label: 'Menu' },
{ label: 'Popover' },
{ label: 'Select' },
{ label: 'FilterDropdown' },
{ label: 'FilterMenu' },
{ label: 'Search' },
],
},
// Data and layout
{ label: 'DataTable' },
{ label: 'DescriptionList' },
{ label: 'PageLead' },
],
},
],
theme: {
colors: {
light: { canvas: 'var(--color-neutral-3)' },
dark: { canvas: 'var(--color-neutral-2)' },
},
},
viteConfig: {
// Foundry's vite root is inside node_modules and this config is bundled to a cache
// dir before it runs, so neither location can anchor tsconfig discovery. cwd is the
// app directory, which is where `foundry dev` is invoked from.
plugins: [tsconfigPaths({ root: process.cwd() }), tailwindcss()],
},
});
26 changes: 26 additions & 0 deletions packages/web/app/foundry.providers.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { useEffect } from 'react';
import type { FoundryProvider } from 'react-foundry';
import { ThemeProvider, useTheme } from './src/components/theme/theme-provider';
import './src/index.css';

/**
* Foundry's toolbar owns the light/dark/system choice and hands down an already-resolved
* mode, so we drive ThemeProvider to that explicit value rather than letting it follow
* the OS itself. Both would otherwise be resolving 'system' independently.
*/
function ThemeSynchronizer({ theme }: { theme: 'light' | 'dark' }) {
const { setTheme } = useTheme();

useEffect(() => {
setTheme(theme);
}, [theme, setTheme]);

return null;
}

export const Provider: FoundryProvider = ({ children, theme }) => (
<ThemeProvider>
<ThemeSynchronizer theme={theme} />
{children}
</ThemeProvider>
);
4 changes: 2 additions & 2 deletions packages/web/app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
"scripts": {
"build": "tsx ../../../scripts/runify.ts src/server/index.ts && NODE_OPTIONS='--max-old-space-size=8192' vite build",
"dev": "tsx watch --clear-screen=false --exclude \"./**/*.mjs\" src/server/dev.ts",
"foundry": "foundry dev",
"generate-changelog": "node ../../../scripts/generate-changelog.js",
"ladle": "ladle serve",
"postinstall": "pnpm generate-changelog",
"typecheck": "tsc --noEmit"
},
Expand All @@ -32,7 +32,6 @@
"@headlessui/react": "2.2.0",
"@hive/service-common": "workspace:*",
"@hookform/resolvers": "3.10.0",
"@ladle/react": "5.1.1",
"@monaco-editor/react": "4.8.0-rc.2",
"@pierre/diffs": "1.2.3",
"@radix-ui/react-accordion": "1.2.2",
Expand Down Expand Up @@ -126,6 +125,7 @@
"react": "18.3.1",
"react-day-picker": "8.10.1",
"react-dom": "18.3.1",
"react-foundry": "0.0.10",
"react-helmet-async": "2.0.5",
"react-highlight-words": "0.20.0",
"react-hook-form": "7.54.2",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { createPreview, type NavPath } from 'react-foundry';
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from './accordion';

export const nav: NavPath = 'Base/Primitives/Accordion';

export const Default = createPreview(() => (
<div className="w-96">
<Accordion>
<AccordionItem value={0}>
<AccordionTrigger label="Breaking changes" />
<AccordionContent>
<p className="text-neutral-11">
Field <code>User.email</code> was removed from type <code>User</code>.
</p>
</AccordionContent>
</AccordionItem>
<AccordionItem value={1}>
<AccordionTrigger label="Dangerous changes" />
<AccordionContent>
<p className="text-neutral-11">
Enum value <code>PENDING</code> was added to <code>Status</code>.
</p>
</AccordionContent>
</AccordionItem>
<AccordionItem value={2}>
<AccordionTrigger label="Safe changes" />
<AccordionContent>
<p className="text-neutral-11">Description on type Query has changed.</p>
</AccordionContent>
</AccordionItem>
</Accordion>
</div>
));

export const DefaultOpen = createPreview(() => (
<div className="w-96">
<Accordion defaultValue={[0]}>
<AccordionItem value={0}>
<AccordionTrigger label="Open on mount" />
<AccordionContent>
<p className="text-neutral-11">Driven by the `defaultValue` prop.</p>
</AccordionContent>
</AccordionItem>
<AccordionItem value={1}>
<AccordionTrigger label="Closed on mount" />
<AccordionContent>
<p className="text-neutral-11">Not listed in `defaultValue`.</p>
</AccordionContent>
</AccordionItem>
</Accordion>
</div>
));

export const AccentVariant = createPreview(() => (
<div className="w-96">
<Accordion defaultValue={[0]}>
<AccordionItem value={0}>
<AccordionTrigger label="Accent trigger" variant="accent" />
<AccordionContent>
<p className="text-neutral-11">Used where the section needs emphasis.</p>
</AccordionContent>
</AccordionItem>
<AccordionItem value={1}>
<AccordionTrigger label="Default trigger" />
<AccordionContent>
<p className="text-neutral-11">The standard neutral treatment.</p>
</AccordionContent>
</AccordionItem>
</Accordion>
</div>
));

This file was deleted.

48 changes: 48 additions & 0 deletions packages/web/app/src/components/base/badge/badge.preview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { createPreview, defineControls, type NavPath } from 'react-foundry';
import { Badge } from './badge';

export const nav: NavPath = 'Base/Primitives/Badge';

export const Variants = createPreview(() => (
<div className="flex items-center gap-3">
<Badge>Default</Badge>
<Badge variant="secondary">Secondary</Badge>
<Badge variant="destructive">Destructive</Badge>
<Badge variant="outline">Outline</Badge>
</div>
));

export const InContext = createPreview(() => (
<div className="flex flex-col gap-3 text-sm">
<div className="flex items-center gap-2">
<span className="text-neutral-11">production</span>
<Badge variant="secondary">3 subgraphs</Badge>
</div>
<div className="flex items-center gap-2">
<span className="text-neutral-11">checkout-service</span>
<Badge variant="destructive">breaking</Badge>
</div>
<div className="flex items-center gap-2">
<span className="text-neutral-11">v2.4.0</span>
<Badge variant="outline">latest</Badge>
</div>
</div>
));

export const Truncation = createPreview(() => (
<div className="w-48">
<Badge variant="secondary">a-very-long-badge-label-that-overflows</Badge>
</div>
));

export const Playground = createPreview({
controls: defineControls({
children: { type: 'text', default: 'Badge' },
variant: {
type: 'select',
options: ['default', 'secondary', 'destructive', 'outline'],
default: 'default',
},
}),
render: v => <Badge variant={v.variant}>{v.children}</Badge>,
});
Loading
Loading