Merge origin/master into alaister/tanstack-start

Conflicts:
  - apps/studio/components/interfaces/ConnectSheet/ConnectStepsSection.tsx:
    keep new Admonition block from master + ComponentType import from HEAD.
  - apps/studio/package.json: keep Vite-based scripts + extra radix deps +
    @tanstack/devtools-vite + @tailwindcss/container-queries from HEAD.
  - pnpm-workspace.yaml: keep React 19 / @types/react 19 catalog from HEAD,
    take master's Next 16.2.6 / Tailwind 4 / and other new catalog entries.
  - pnpm-lock.yaml: regenerated via pnpm install.
This commit is contained in:
Alaister Young committed 2026-05-08 13:39:03 +08:00
commit 3dcd653cec
2811 files changed
+192000 -132169

No files matched your search

+2
View File
@@ -31,6 +31,8 @@ pnpm typecheck # typecheck all packages
**Styling** — Tailwind only, semantic tokens (`bg-muted`, `text-foreground-light`), no hardcoded colors.
**Language** — Use U.S. English everywhere.
## Studio
Pages router. Co-locate sub-components with parent. Avoid barrel re-export files.
+1 -1
View File
@@ -34,7 +34,7 @@ Docs: `apps/design-system/content/docs/ui-patterns/forms.mdx`
- Use `react-hook-form` + `zod`
- Use `FormItemLayout` instead of manually composing `FormItem`/`FormLabel`/`FormMessage`/`FormDescription`
- Wrap inputs with `FormControl_Shadcn_`; use `_Shadcn_` imports from `ui` for primitives
- Wrap inputs with `FormControl`; use `_Shadcn_` imports from `ui` for primitives
Layout selection:
@@ -1,5 +1,5 @@
---
applyTo: "apps/studio/**,packages/common/telemetry*"
applyTo: 'apps/studio/**,packages/common/telemetry*'
---
# Studio Telemetry Review Rules
@@ -11,8 +11,8 @@ All comments are **advisory** — suggest, do not request changes.
Use judgment — not every PR needs telemetry. But **always flag** when:
1. **Changes to `packages/common/telemetry-constants.ts`** — validate event naming, property conventions, and JSDoc accuracy.
2. **PostHog feature flags without measurement.** If a PR uses `usePHFlag` or PostHog-backed hooks like `useDataApiGrantTogglesEnabled` to gate behavior, the flag state should be captured in a telemetry event so the rollout can be measured. Flag if the flag value isn't included in a relevant `track()` call. (Note: `useFlag` from `common` reads ConfigCat flags, not PostHog — different system, different guidance.)
3. **Feature-flagged rollouts without outcome tracking.** If a flag gates new behavior, there should be telemetry on both the flag state *and* how users respond to the new behavior (e.g., toggle clicks, opt-in actions).
2. **PostHog feature flags without measurement.** If a PR uses `usePHFlag` or PostHog-backed hooks like `useDataApiRevokeOnCreateDefaultEnabled` to gate behavior, the flag state should be captured in a telemetry event so the rollout can be measured. Flag if the flag value isn't included in a relevant `track()` call. (Note: `useFlag` from `common` reads ConfigCat flags, not PostHog — different system, different guidance.)
3. **Feature-flagged rollouts without outcome tracking.** If a flag gates new behavior, there should be telemetry on both the flag state _and_ how users respond to the new behavior (e.g., toggle clicks, opt-in actions).
4. **Growth-oriented components adding user interactions without tracking** — onboarding flows, setup wizards, upgrade CTAs, A/B experiment variants.
When tracking is missing, comment: _"This adds a user interaction (or feature flag) that may benefit from tracking."_ Then propose an event name and `useTrack()` call.
@@ -52,6 +52,7 @@ Flag: unapproved verbs (`saved`, `viewed`, `pressed`), wrong order (`click_produ
```typescript
import { useTrack } from 'lib/telemetry/track'
const track = useTrack()
track('product_card_clicked', { productType: 'database', planTier: 'pro' })
```
+1 -1
View File
@@ -31,4 +31,4 @@ jobs:
cd docker
cp .env.example .env
yq -i '.services.supavisor.environment.RLIMIT_NOFILE=1024' docker-compose.yml
docker compose up --wait --wait-timeout 180
docker compose up --quiet-pull --wait --wait-timeout 180
+14 -2
View File
@@ -83,18 +83,30 @@ jobs:
if: steps.filter.outputs.studio == 'true'
run: rm -rf supabase && pnpm exec supabase init && mkdir supabase/functions
- name: Pre-start diagnostics
run: |
docker ps -a
sudo ss -tlnp | grep 5432 || echo "5432 free"
- name: Start supabase
if: steps.filter.outputs.studio == 'true'
run: SKIP_ASSET_UPLOAD=1 pnpm run e2e:setup:cli
- name: Failure diagnostics
if: failure()
run: |
docker ps -a
sudo ss -tlnp | grep 5432
docker logs $(docker ps -aq) 2>&1 || true
- name: Build studio
if: steps.filter.outputs.studio == 'true'
run: SKIP_ASSET_UPLOAD=1 NODE_ENV=test NODE_OPTIONS="--max-old-space-size=4096" pnpm run build:studio
- name: 🚀 Run Playwright tests against Vercel Preview
- name: 🚀 Run Playwright tests against local studio build
if: steps.filter.outputs.studio == 'true'
id: playwright
run: pnpm e2e --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }}
run: PWTEST_SHARD_WEIGHTS=62:38 pnpm e2e --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }}
- name: Upload blob report to GitHub Actions Artifacts
if: always() && steps.filter.outputs.studio == 'true'
+3
View File
@@ -8,6 +8,9 @@ apps/**/out
**/supabase/migrations/*.sql
apps/www/schema.sql
apps/www/public/images/*
# Generated by apps/www/scripts/generateStaticContent.mjs (GitHub discussion bodies)
apps/www/public/changelog.md
apps/www/public/changelog/*.md
apps/www/.generated/*
apps/docs/**/generated/*
apps/docs/examples/*
+1 -1
View File
@@ -192,7 +192,7 @@ We support "federating" docs, meaning doc content can come directly from externa
Federated docs work using Next.js's build pipeline. We use `getStaticProps()` to fetch remote documentation (ie. markdown) at build time which is processed and passed to the respective page within the docs.
See the [Vecs Python source code](https://github.com/supabase/supabase/tree/master/apps/docs/app/guides/ai/python/%5Bslug%5D to see how we do this for [`supabase/vecs`](https://github.com/supabase/vecs). Use this as a starting point for federating other docs.
See the [Vecs Python source code](https://github.com/supabase/supabase/tree/master/apps/docs/app/guides/ai/python/%5Bslug%5D) to see how we do this for [`supabase/vecs`](https://github.com/supabase/vecs). Use this as a starting point for federating other docs.
Some things to consider:
@@ -71,7 +71,7 @@ export default function ChartComposedMetrics() {
</ChartHeader>
<ChartContent
className="p-0"
loadingState={<Skeleton className="w-full h-[6rem] rounded-none mt-4" />}
loadingState={<Skeleton className="w-full h-24 rounded-none mt-4" />}
>
<ChartSparkline data={data} dataKey="value" />
</ChartContent>
@@ -89,7 +89,7 @@ export default function ChartComposedMetrics() {
</ChartHeader>
<ChartContent
className="p-0"
loadingState={<Skeleton className="w-full h-[6rem] rounded-none mt-4" />}
loadingState={<Skeleton className="w-full h-24 rounded-none mt-4" />}
>
<ChartSparkline data={data} dataKey="value" />
</ChartContent>
+11
View File
@@ -2568,6 +2568,17 @@ export const Index: Record<string, any> = {
subcategory: "undefined",
chunks: []
},
"multi-select-in-dialog": {
name: "multi-select-in-dialog",
type: "components:example",
registryDependencies: undefined,
component: React.lazy(() => import("@/registry/default/example/multi-select-in-dialog")),
source: "",
files: ["registry/default/example/multi-select-in-dialog.tsx"],
category: "undefined",
subcategory: "undefined",
chunks: []
},
"tree-view-demo": {
name: "tree-view-demo",
type: "components:example",
+4 -5
View File
@@ -1,20 +1,19 @@
'use client'
import { ThemeProvider } from 'common'
import { Provider as JotaiProvider } from 'jotai'
import { ThemeProvider as NextThemesProvider } from 'next-themes'
import { ThemeProviderProps } from 'next-themes/dist/types'
import { TooltipProvider } from 'ui'
import { MobileSidebarProvider } from '@/context/mobile-sidebar-context'
export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
export function Providers({ children }: { children: React.ReactNode }) {
return (
<JotaiProvider>
<NextThemesProvider {...props}>
<ThemeProvider>
<TooltipProvider delayDuration={0}>
<MobileSidebarProvider>{children}</MobileSidebarProvider>
</TooltipProvider>
</NextThemesProvider>
</ThemeProvider>
</JotaiProvider>
)
}
-29
View File
@@ -1,29 +0,0 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
/* :root {
--foreground-rgb: 0, 0, 0;
--background-start-rgb: 214, 219, 220;
--background-end-rgb: 255, 255, 255;
}
@media (prefers-color-scheme: dark) {
:root {
--foreground-rgb: 255, 255, 255;
--background-start-rgb: 0, 0, 0;
--background-end-rgb: 0, 0, 0;
}
} */
body {
/* color: rgb(var(--foreground-rgb));
background: linear-gradient(to bottom, transparent, rgb(var(--background-end-rgb)))
rgb(var(--background-start-rgb)); */
}
/*
@layer utilities {
.text-balance {
text-wrap: balance;
}
} */
+4 -8
View File
@@ -1,10 +1,10 @@
import 'react-data-grid/lib/styles.css'
import '@/styles/globals.css'
import '../../studio/styles/typography.css'
import type { Metadata, Viewport } from 'next'
import { customFont, sourceCodePro } from './fonts'
import { ThemeProvider } from './Providers'
import { Providers } from './Providers'
import { Toaster } from './toaster'
const className = `${customFont.variable} ${sourceCodePro.variable}`
@@ -131,16 +131,12 @@ export default async function Layout({ children }: RootLayoutProps) {
/>
</head>
<body>
<ThemeProvider
themes={['dark', 'light', 'classic-dark']}
defaultTheme="system"
enableSystem
>
<Providers>
<div vaul-drawer-wrapper="">
<div className="relative flex min-h-screen flex-col bg-background">{children}</div>
</div>
<Toaster />
</ThemeProvider>
</Providers>
</body>
</html>
)
@@ -5,7 +5,7 @@ const ClassLabel = React.forwardRef<HTMLSpanElement, { children: React.ReactNode
return (
<span
ref={ref}
className="bg-surface-100 rounded-full border px-2 font-mono text-xs text-foreground-lighter group-data-[state=open]:text-foreground"
className="bg-surface-100 rounded-full border px-2 font-mono text-xs text-foreground-lighter group-data-open:text-foreground"
>
{children}
</span>
@@ -36,7 +36,7 @@ export function CodeBlockWrapper({
</CollapsibleContent>
<div
className={cn(
'absolute flex items-center justify-center bg-gradient-to-b from-zinc-700/30 to-zinc-950/90 p-2',
'absolute flex items-center justify-center bg-linear-to-b from-zinc-700/30 to-zinc-950/90 p-2',
isOpened ? 'inset-x-0 bottom-0 h-12' : 'inset-0'
)}
>
@@ -51,7 +51,7 @@ export function CodeFragment({
return (
<p className="text-sm text-muted-foreground">
Code fragment{' '}
<code className="relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm">
<code className="relative rounded-sm bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm">
{name}
</code>{' '}
not found in registry.
@@ -94,10 +94,10 @@ export function CodeFragment({
)}
>
{showGrid && (
<div className="pointer-events-none absolute h-full w-full bg-[linear-gradient(to_right,hsla(var(--foreground-default)/0.02)_1px,transparent_1px),linear-gradient(to_bottom,#80808012_1px,transparent_1px)] bg-[size:24px_24px]"></div>
<div className="pointer-events-none absolute h-full w-full bg-[linear-gradient(to_right,hsla(var(--foreground-default)/0.02)_1px,transparent_1px),linear-gradient(to_bottom,#80808012_1px,transparent_1px)] bg-size-[24px_24px]"></div>
)}
{showDottedGrid && (
<div className="z-0 pointer-events-none absolute h-full w-full bg-[radial-gradient(hsla(var(--foreground-default)/0.02)_1px,transparent_1px)] [background-size:16px_16px] [mask-image:radial-gradient(ellipse_50%_50%_at_50%_50%,#000_70%,transparent_100%)]"></div>
<div className="z-0 pointer-events-none absolute h-full w-full bg-[radial-gradient(hsla(var(--foreground-default)/0.02)_1px,transparent_1px)] bg-size-[16px_16px] mask-[radial-gradient(ellipse_50%_50%_at_50%_50%,#000_70%,transparent_100%)]"></div>
)}
<div className="z-10 relative">{ComponentPreview}</div>
</div>
+1 -1
View File
@@ -70,7 +70,7 @@ const Colors = ({
onClick={() => handleCopy(x, i)}
>
<Example x={x} />
<span className="bg-surface-100 rounded-full border px-2 font-mono text-xs text-foreground-lighter group-data-[state=open]:text-foreground text-center">
<span className="bg-surface-100 rounded-full border px-2 font-mono text-xs text-foreground-lighter group-data-open:text-foreground text-center">
{copiedIndex === i ? 'Copied!' : x}
</span>
</GridItem>
@@ -56,7 +56,7 @@ export function CommandMenu({ ...props }: DialogProps) {
<Button
type="outline"
className={cn(
`lg:flex hidden relative h-8 w-full justify-start rounded-[0.5rem] bg-background text-sm font-normal text-foreground-muted shadow-none sm:pr-12 md:w-40 lg:w-64 hover:border-foreground-muted hover:bg-surface-100 hover:text-foreground-lighter
`lg:flex hidden relative h-8 w-full justify-start rounded-lg bg-background text-sm font-normal text-foreground-muted shadow-none sm:pr-12 md:w-40 lg:w-64 hover:border-foreground-muted hover:bg-surface-100 hover:text-foreground-lighter
`
)}
onClick={() => setOpen(true)}
@@ -64,7 +64,7 @@ export function CommandMenu({ ...props }: DialogProps) {
>
<span className="hidden lg:inline-flex">Search Design System...</span>
<span className="inline-flex lg:hidden">Search...</span>
<kbd className="pointer-events-none absolute right-[0.3rem] top-[0.3rem] hidden h-5 select-none items-center gap-1 rounded border bg-surface-200 px-1.5 font-mono text-[10px] font-medium opacity-100 sm:flex text-foreground-light">
<kbd className="pointer-events-none absolute right-[0.3rem] top-[0.3rem] hidden h-5 select-none items-center gap-1 rounded-sm border bg-surface-200 px-1.5 font-mono text-[10px] font-medium opacity-100 sm:flex text-foreground-light">
<span className="text-sm">⌘</span>K
</kbd>
</Button>
@@ -55,7 +55,7 @@ export function ComponentPreview({
return (
<p className="text-sm text-muted-foreground">
Component{' '}
<code className="relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm">
<code className="relative rounded-sm bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm">
{name}
</code>{' '}
not found in registry.
@@ -99,10 +99,10 @@ export function ComponentPreview({
)}
>
{showGrid && (
<div className="pointer-events-none absolute h-full w-full bg-[linear-gradient(to_right,hsla(var(--foreground-default)/0.02)_1px,transparent_1px),linear-gradient(to_bottom,#80808012_1px,transparent_1px)] bg-[size:24px_24px]"></div>
<div className="pointer-events-none absolute h-full w-full bg-[linear-gradient(to_right,hsla(var(--foreground-default)/0.02)_1px,transparent_1px),linear-gradient(to_bottom,#80808012_1px,transparent_1px)] bg-size-[24px_24px]"></div>
)}
{showDottedGrid && (
<div className="z-0 pointer-events-none absolute h-full w-full bg-[radial-gradient(hsla(var(--foreground-default)/0.02)_1px,transparent_1px)] [background-size:16px_16px] [mask-image:radial-gradient(ellipse_50%_50%_at_50%_50%,#000_70%,transparent_100%)]"></div>
<div className="z-0 pointer-events-none absolute h-full w-full bg-[radial-gradient(hsla(var(--foreground-default)/0.02)_1px,transparent_1px)] bg-size-[16px_16px] mask-[radial-gradient(ellipse_50%_50%_at_50%_50%,#000_70%,transparent_100%)]"></div>
)}
<div className="z-10 relative">{ComponentPreview}</div>
{/* <div className="preview-grid-background"></div> */}
@@ -144,10 +144,10 @@ export function ComponentPreview({
})}
>
{showGrid && (
<div className="pointer-events-none absolute h-full w-full bg-[linear-gradient(to_right,hsla(var(--foreground-default)/0.02)_1px,transparent_1px),linear-gradient(to_bottom,#80808012_1px,transparent_1px)] bg-[size:24px_24px]"></div>
<div className="pointer-events-none absolute h-full w-full bg-[linear-gradient(to_right,hsla(var(--foreground-default)/0.02)_1px,transparent_1px),linear-gradient(to_bottom,#80808012_1px,transparent_1px)] bg-size-[24px_24px]"></div>
)}
{showDottedGrid && (
<div className="z-0 pointer-events-none absolute h-full w-full bg-[radial-gradient(hsla(var(--foreground-default)/0.02)_1px,transparent_1px)] [background-size:16px_16px] [mask-image:radial-gradient(ellipse_50%_50%_at_50%_50%,#000_70%,transparent_100%)]"></div>
<div className="z-0 pointer-events-none absolute h-full w-full bg-[radial-gradient(hsla(var(--foreground-default)/0.02)_1px,transparent_1px)] bg-size-[16px_16px] mask-[radial-gradient(ellipse_50%_50%_at_50%_50%,#000_70%,transparent_100%)]"></div>
)}
<div className="z-10 relative">{ComponentPreview}</div>
</div>
@@ -164,12 +164,12 @@ export function ComponentPreview({
px-4 py-4
border border-r
group
data-[state=closed]:rounded-bl-md data-[state=closed]:rounded-br-md
data-closed:rounded-bl-md data-closed:rounded-br-md
`}
>
<ChevronRight
className="transition-all group-data-[state=open]:rotate-90 text-foreground-lighter"
className="transition-all group-data-open:rotate-90 text-foreground-lighter"
size={14}
/>
View code
+2 -2
View File
@@ -47,8 +47,8 @@ const GridItem = forwardRef<HTMLDivElement, React.HTMLProps<HTMLDivElement>>(
transition
group-hover:border
group-hover:border-foreground-muted
group-data-[state=open]:border
group-data-[state=open]:border-foreground-muted
group-data-open:border
group-data-open:border-foreground-muted
"
></div>
{children}
+2 -5
View File
@@ -18,11 +18,8 @@ function Icons() {
<DropdownMenu key={i} modal={false}>
<DropdownMenuTrigger asChild>
<GridItem>
<icon.component
size={21}
className="group-data-[state=open]:scale-125 transition-all"
/>
<span className="bg-surface-100 rounded-full border px-2 font-mono text-xs text-foreground-lighter group-data-[state=open]:text-foreground">
<icon.component size={21} className="group-data-open:scale-125 transition-all" />
<span className="bg-surface-100 rounded-full border px-2 font-mono text-xs text-foreground-lighter group-data-open:text-foreground">
{icon.name}
</span>
</GridItem>
@@ -92,10 +92,7 @@ const components = {
/>
),
p: ({ className, ...props }: React.HTMLAttributes<HTMLParagraphElement>) => (
<p
className={cn('leading-7 [&:not(:first-child)]:mt-6 text-foreground-light', className)}
{...props}
/>
<p className={cn('leading-7 not-first:mt-6 text-foreground-light', className)} {...props} />
),
ul: ({ className, ...props }: React.HTMLAttributes<HTMLUListElement>) => (
<ul className={cn('my-6 ml-6 list-disc', className)} {...props} />
@@ -127,7 +124,7 @@ const components = {
th: ({ className, ...props }: React.HTMLAttributes<HTMLTableCellElement>) => (
<th
className={cn(
'border px-4 py-2 text-left font-normal [&[align=center]]:text-center [&[align=right]]:text-right',
'border px-4 py-2 text-left font-normal [[align=center]]:text-center [[align=right]]:text-right',
className
)}
{...props}
@@ -136,7 +133,7 @@ const components = {
td: ({ className, ...props }: React.HTMLAttributes<HTMLTableCellElement>) => (
<td
className={cn(
'border text-foreground-light px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right',
'border text-foreground-light px-4 py-2 text-left [[align=center]]:text-center [[align=right]]:text-right',
className
)}
{...props}
@@ -199,7 +196,7 @@ const components = {
code: ({ className, ...props }: React.HTMLAttributes<HTMLElement>) => (
<code
className={cn(
'relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm',
'relative rounded-sm bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm',
className
)}
{...props}
@@ -261,7 +258,7 @@ const components = {
LinkedCard: ({ className, ...props }: React.ComponentProps<typeof Link>) => (
<Link
className={cn(
'flex w-full flex-col items-center rounded-xl border bg-card p-6 text-card-foreground shadow transition-colors hover:bg-muted/50 sm:p-10',
'flex w-full flex-col items-center rounded-xl border bg-card p-6 text-card-foreground shadow-sm transition-colors hover:bg-muted/50 sm:p-10',
className
)}
{...props}
@@ -3,7 +3,7 @@
import { useTheme } from 'next-themes'
import { useEffect, useState } from 'react'
import SVG from 'react-inlinesvg'
import { RadioGroup_Shadcn_, RadioGroupLargeItem_Shadcn_, singleThemes, Theme } from 'ui'
import { RadioGroup, RadioGroupLargeItem, singleThemes, Theme } from 'ui'
const ThemeSettings = () => {
const [mounted, setMounted] = useState(false)
@@ -25,7 +25,7 @@ const ThemeSettings = () => {
function SingleThemeSelection() {
return (
<form className="py-8">
<RadioGroup_Shadcn_
<RadioGroup
name="theme"
onValueChange={setTheme}
aria-label="Choose a theme"
@@ -34,11 +34,11 @@ const ThemeSettings = () => {
className="flex flex-wrap gap-3"
>
{singleThemes.map((theme: Theme) => (
<RadioGroupLargeItem_Shadcn_ key={theme.value} value={theme.value} label={theme.name}>
<RadioGroupLargeItem key={theme.value} value={theme.value} label={theme.name}>
<SVG src={`${process.env.NEXT_PUBLIC_BASE_PATH}/img/themes/${theme.value}.svg`} />
</RadioGroupLargeItem_Shadcn_>
</RadioGroupLargeItem>
))}
</RadioGroup_Shadcn_>
</RadioGroup>
</form>
)
}
@@ -33,7 +33,7 @@ const ThemeSwitcherDropdown = () => {
return null
}
const iconClasses = 'text-foreground-lighter group-data-[state=open]:text-foreground'
const iconClasses = 'text-foreground-lighter group-data-open:text-foreground'
return (
<>
@@ -13,7 +13,7 @@ export const TopNavigation = () => {
const { toggle } = useMobileSidebar()
return (
<header className="sticky top-0 z-50 w-full bg-studio/95 backdrop-blur supports-[backdrop-filter]:bg-studio/60 border-b border-l border-r">
<header className="sticky top-0 z-50 w-full bg-studio/95 backdrop-blur-sm supports-backdrop-filter:bg-studio/60 border-b border-l border-r">
<nav className="py-3 w-full flex">
<div className="max-w-site w-full flex flex-row items-center gap-6 mx-auto md:px-6 px-4 justify-between">
<div className="flex items-center gap-2">
@@ -417,7 +417,7 @@ const chartData = [
#### Tailwind
```tsx
<LabelList className="fill-[--color-desktop]" />
<LabelList className="fill-(--color-desktop)" />
```
## Tooltip
@@ -108,47 +108,47 @@ See the [Form](/docs/forms) documentation for building forms with the `Field` co
### Input
<ComponentPreview name="field-input" className="!mb-4 [&_.preview]:p-6" />
<ComponentPreview name="field-input" className="mb-4! [&_.preview]:p-6" />
### Textarea
<ComponentPreview name="field-textarea" className="!mb-4 [&_.preview]:p-6" />
<ComponentPreview name="field-textarea" className="mb-4! [&_.preview]:p-6" />
### Select
<ComponentPreview name="field-select" className="!mb-4 [&_.preview]:p-6" />
<ComponentPreview name="field-select" className="mb-4! [&_.preview]:p-6" />
### Slider
<ComponentPreview name="field-slider" className="!mb-4 [&_.preview]:p-6" />
<ComponentPreview name="field-slider" className="mb-4! [&_.preview]:p-6" />
### Fieldset
<ComponentPreview name="field-fieldset" className="!mb-4 [&_.preview]:p-6" />
<ComponentPreview name="field-fieldset" className="mb-4! [&_.preview]:p-6" />
### Checkbox
<ComponentPreview name="field-checkbox" className="!mb-4 [&_.preview]:p-6" />
<ComponentPreview name="field-checkbox" className="mb-4! [&_.preview]:p-6" />
### Radio
<ComponentPreview name="field-radio" className="!mb-4 [&_.preview]:p-6" />
<ComponentPreview name="field-radio" className="mb-4! [&_.preview]:p-6" />
### Switch
<ComponentPreview name="field-switch" className="!mb-4 [&_.preview]:p-6" />
<ComponentPreview name="field-switch" className="mb-4! [&_.preview]:p-6" />
### Choice Card
Wrap `Field` components inside `FieldLabel` to create selectable field groups. This works with `RadioItem`, `Checkbox` and `Switch` components.
<ComponentPreview name="field-choice-card" className="!mb-4 [&_.preview]:p-6" />
<ComponentPreview name="field-choice-card" className="mb-4! [&_.preview]:p-6" />
### Field Group
Stack `Field` components with `FieldGroup`. Add `FieldSeparator` to divide them.
<ComponentPreview name="field-group" className="!mb-4 [&_.preview]:p-6" />
<ComponentPreview name="field-group" className="mb-4! [&_.preview]:p-6" />
## Responsive Layout
@@ -158,7 +158,7 @@ Stack `Field` components with `FieldGroup`. Add `FieldSeparator` to divide them.
<ComponentPreview
name="field-responsive"
className="!mb-4 [&_.preview]:h-[650px] [&_.preview]:p-6 [&_.preview]:md:h-[500px] [&_.preview]:md:p-10"
className="mb-4! [&_.preview]:h-[650px] [&_.preview]:p-6 [&_.preview]:md:h-[500px] [&_.preview]:md:p-10"
/>
## Validation and Errors
@@ -241,7 +241,7 @@ That's it. You now have a fully accessible form that is type-safe with client-si
<ComponentPreview
name="input-form"
className="[&_[role=tablist]]:hidden [&>div>div:first-child]:hidden"
className="**:[[role=tablist]]:hidden [&>div>div:first-child]:hidden"
/>
</Steps>
@@ -571,7 +571,7 @@ The following example adds a `<DropdownMenu>` to the `SidebarHeader`.
<ChevronDown className="ml-auto" />
</SidebarMenuButton>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-[--radix-popper-anchor-width]">
<DropdownMenuContent className="w-(--radix-popper-anchor-width)">
<DropdownMenuItem>
<span>Acme Inc</span>
</DropdownMenuItem>
@@ -622,7 +622,7 @@ export function AppSidebar() {
<ChevronUp className="ml-auto" />
</SidebarMenuButton>
</DropdownMenuTrigger>
<DropdownMenuContent side="top" className="w-[--radix-popper-anchor-width]">
<DropdownMenuContent side="top" className="w-(--radix-popper-anchor-width)">
<DropdownMenuItem>
<span>Account</span>
</DropdownMenuItem>
@@ -724,7 +724,7 @@ export function AppSidebar() {
<SidebarGroupLabel asChild>
<CollapsibleTrigger>
Help
<ChevronDown className="ml-auto transition-transform group-data-[state=open]/collapsible:rotate-180" />
<ChevronDown className="ml-auto transition-transform group-data-open/collapsible:rotate-180" />
</CollapsibleTrigger>
</SidebarGroupLabel>
<CollapsibleContent>
@@ -66,13 +66,13 @@ When using Switch in custom flex layouts (especially with height constraints lik
```tsx
<div className="relative">
<FormField_Shadcn_
<FormField
control={form.control}
name="enabled"
render={({ field }) => (
<FormControl_Shadcn_>
<FormControl>
<Switch checked={field.value} onCheckedChange={field.onChange} />
</FormControl_Shadcn_>
</FormControl>
)}
/>
</div>
@@ -6,7 +6,7 @@ source:
shadcn: true
---
<ComponentPreview name="typography-demo" className="[&>div.min-h-[350px]]:p-6" peekCode wide />
<ComponentPreview name="typography-demo" peekCode wide />
## h1
@@ -21,27 +21,27 @@ The styling and layout of these components can be customized by passing in the c
The components that can be replaced in `react-hook-form` atoms are highlighted below:
```tsx showLineNumbers {1-2,6-8}
<FormItem_Shadcn_>
<FormLabel_Shadcn_>Username</FormLabel_Shadcn_>
<FormControl_Shadcn_>
<FormItem>
<FormLabel>Username</FormLabel>
<FormControl>
<Input placeholder="shadcn" {...field} />
</FormControl_Shadcn_>
<FormDescription_Shadcn_>This is your public display name.</FormDescription_Shadcn_>
<FormMessage_Shadcn_ />
</FormItem_Shadcn_>
</FormControl>
<FormDescription>This is your public display name.</FormDescription>
<FormMessage />
</FormItem>
```
Using `FormItemLayout` it can look like this:
```tsx
<FormItemLayout label="Username" description="This is your public display name">
<FormControl_Shadcn_>
<FormControl>
<Input placeholder="mildtomato" {...field} />
</FormControl_Shadcn_>
</FormControl>
</FormItemLayout>
```
Please note that you must still use `FormControl_Shadcn_` to wrap input fields.
Please note that you must still use `FormControl` to wrap input fields.
## Examples
@@ -78,3 +78,9 @@ Add the `deletableBadge` prop on the `MultiSelectorTrigger` component to enable
Use `mode="inline-combobox"` on the `MultiSelectorTrigger` component to add an inline search input.
<ComponentPreview name="multi-select-inline-search-input" />
### Inside a dialog
Use `mode="inline-combobox"` on the `MultiSelectorTrigger` component to add an inline search input.
<ComponentPreview name="multi-select-in-dialog" />
@@ -51,7 +51,7 @@ Build a custom row when the cells are mixed controls, such as an input paired wi
- Use `layout="horizontal"` for side panels with more width
- Use `layout="vertical"` for side panels with limited width
3. **Wrap inputs in FormControl*Shadcn***: Always wrap form inputs with `FormControl_Shadcn_` to ensure proper form integration.
3. **Wrap inputs in FormControl*Shadcn***: Always wrap form inputs with `FormControl` to ensure proper form integration.
4. **Use Cards for grouping**: Wrap form sections in `Card` components with `CardContent` and `CardFooter` for actions.
+4 -4
View File
@@ -20,6 +20,7 @@
"@hookform/resolvers": "^3.1.1",
"@tanstack/react-table": "^8.21.3",
"contentlayer2": "0.4.6",
"common": "workspace:*",
"date-fns": "^2.30.0",
"dayjs": "1.11.13",
"eslint-config-supabase": "workspace:*",
@@ -29,7 +30,7 @@
"markdown-wasm": "^1.2.0",
"next": "catalog:",
"next-contentlayer2": "0.4.6",
"next-themes": "^0.3.0",
"next-themes": "catalog:",
"react": "catalog:",
"react-data-grid": "7.0.0-beta.47",
"react-day-picker": "^9.11.1",
@@ -53,14 +54,13 @@
},
"devDependencies": {
"@shikijs/compat": "^1.1.7",
"@tailwindcss/container-queries": "^0.1.1",
"@types/lodash.template": "4.5.0",
"@types/react": "catalog:",
"@types/react-dom": "catalog:",
"concurrently": "^8.2.2",
"config": "workspace:^",
"config": "workspace:*",
"mdast-util-toc": "^6.1.1",
"postcss": "^8.5.3",
"postcss": "catalog:",
"rimraf": "^4.1.3",
"shiki": "^1.1.7",
"tailwindcss": "catalog:",
@@ -71,7 +71,7 @@ export default function ChartComposedMetrics() {
</ChartHeader>
<ChartContent
className="p-0"
loadingState={<Skeleton className="w-full h-[6rem] rounded-none mt-4" />}
loadingState={<Skeleton className="w-full h-24 rounded-none mt-4" />}
>
<ChartSparkline data={data} dataKey="value" />
</ChartContent>
@@ -89,7 +89,7 @@ export default function ChartComposedMetrics() {
</ChartHeader>
<ChartContent
className="p-0"
loadingState={<Skeleton className="w-full h-[6rem] rounded-none mt-4" />}
loadingState={<Skeleton className="w-full h-24 rounded-none mt-4" />}
>
<ChartSparkline data={data} dataKey="value" />
</ChartContent>
@@ -46,7 +46,7 @@ export default function AssistantChatCommands() {
/>
</AssistantCommandsPopover>
<p className="text-xs mt-3 text-foreground-lighter">
Press <span className="bg-surface-300 px-[3px] py-[2px] border rounded">/</span> to open
Press <span className="bg-surface-300 px-[3px] py-[2px] border rounded-sm">/</span> to open
commands
</p>
</div>
@@ -8,13 +8,13 @@ import { toast } from 'sonner'
import {
Button,
Calendar,
Form_Shadcn_,
FormControl_Shadcn_,
FormDescription_Shadcn_,
FormField_Shadcn_,
FormItem_Shadcn_,
FormLabel_Shadcn_,
FormMessage_Shadcn_,
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
Popover_Shadcn_,
PopoverContent_Shadcn_,
PopoverTrigger_Shadcn_,
@@ -45,17 +45,17 @@ export default function CalendarForm() {
}
return (
<Form_Shadcn_ {...form}>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
<FormField_Shadcn_
<FormField
control={form.control}
name="dob"
render={({ field }) => (
<FormItem_Shadcn_ className="flex flex-col">
<FormLabel_Shadcn_>Date of birth</FormLabel_Shadcn_>
<FormItem className="flex flex-col">
<FormLabel>Date of birth</FormLabel>
<Popover_Shadcn_>
<PopoverTrigger_Shadcn_ asChild>
<FormControl_Shadcn_>
<FormControl>
<Button
type={'default'}
size="small"
@@ -67,7 +67,7 @@ export default function CalendarForm() {
>
{field.value ? format(field.value, 'PPP') : <span>Pick a date</span>}
</Button>
</FormControl_Shadcn_>
</FormControl>
</PopoverTrigger_Shadcn_>
<PopoverContent_Shadcn_ className="w-auto p-0" align="start" side="right">
<Calendar
@@ -79,15 +79,13 @@ export default function CalendarForm() {
/>
</PopoverContent_Shadcn_>
</Popover_Shadcn_>
<FormDescription_Shadcn_>
Your date of birth is used to calculate your age.
</FormDescription_Shadcn_>
<FormMessage_Shadcn_ />
</FormItem_Shadcn_>
<FormDescription>Your date of birth is used to calculate your age.</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<Button htmlType="submit">Submit</Button>
</form>
</Form_Shadcn_>
</Form>
)
}
@@ -8,13 +8,13 @@ import { toast } from 'sonner'
import {
Button,
Calendar,
Form_Shadcn_,
FormControl_Shadcn_,
FormDescription_Shadcn_,
FormField_Shadcn_,
FormItem_Shadcn_,
FormLabel_Shadcn_,
FormMessage_Shadcn_,
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
Popover_Shadcn_,
PopoverContent_Shadcn_,
PopoverTrigger_Shadcn_,
@@ -45,17 +45,17 @@ export default function CalendarForm() {
}
return (
<Form_Shadcn_ {...form}>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
<FormField_Shadcn_
<FormField
control={form.control}
name="dob"
render={({ field }) => (
<FormItem_Shadcn_ className="flex flex-col">
<FormLabel_Shadcn_>Date of birth</FormLabel_Shadcn_>
<FormItem className="flex flex-col">
<FormLabel>Date of birth</FormLabel>
<Popover_Shadcn_>
<PopoverTrigger_Shadcn_ asChild>
<FormControl_Shadcn_>
<FormControl>
<Button
type={'outline'}
className={cn(
@@ -66,7 +66,7 @@ export default function CalendarForm() {
{field.value ? format(field.value, 'PPP') : <span>Pick a date</span>}
<CalendarIcon className="ml-auto h-4 w-4 opacity-50" />
</Button>
</FormControl_Shadcn_>
</FormControl>
</PopoverTrigger_Shadcn_>
<PopoverContent_Shadcn_ className="w-auto p-0" align="start">
<Calendar
@@ -78,15 +78,13 @@ export default function CalendarForm() {
/>
</PopoverContent_Shadcn_>
</Popover_Shadcn_>
<FormDescription_Shadcn_>
Your date of birth is used to calculate your age.
</FormDescription_Shadcn_>
<FormMessage_Shadcn_ />
</FormItem_Shadcn_>
<FormDescription>Your date of birth is used to calculate your age.</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<Button htmlType="submit">Submit</Button>
</form>
</Form_Shadcn_>
</Form>
)
}
@@ -35,11 +35,11 @@ export default function Component() {
{ name: 'Desktop', value: 186, fill: 'hsl(var(--chart-1))' },
{ name: 'Mobile', value: 80, fill: 'hsl(var(--chart-2))' },
]}
className="w-[8rem]"
className="w-32"
/>
</div>
<div className="items-end">
<div className="absolute left-[122px] top-[0px] z-10 text-sm font-medium">Name</div>
<div className="absolute left-[122px] top-0 z-10 text-sm font-medium">Name</div>
<svg
xmlns="http://www.w3.org/2000/svg"
width="35"
@@ -68,25 +68,25 @@ export default function Component() {
{ name: 'Firefox', value: 1000, fill: 'hsl(var(--chart-4))' },
]}
indicator="dashed"
className="w-[8rem]"
className="w-32"
/>
</div>
<div className="!hidden md:!flex">
<div className="hidden! md:flex!">
<TooltipDemo
label="Page Views"
payload={[{ name: 'Desktop', value: 12486, fill: 'hsl(var(--chart-3))' }]}
className="w-[9rem]"
className="w-36"
indicator="line"
/>
</div>
<div className="!items-start !justify-start">
<div className="items-start! justify-start!">
<div className="absolute left-[50px] top-[60px] z-10 text-sm font-medium">Indicator</div>
<TooltipDemo
label="Browser"
hideLabel
payload={[{ name: 'Chrome', value: 1286, fill: 'hsl(var(--chart-1))' }]}
indicator="dot"
className="w-[8rem]"
className="w-32"
/>
<svg
xmlns="http://www.w3.org/2000/svg"
@@ -144,7 +144,7 @@ function TooltipDemo({
return (
<div
className={cn(
'grid min-w-[8rem] items-start gap-1.5 rounded-lg border border-border/50 bg-background px-2.5 py-1.5 text-xs shadow-xl transition-all ease-in-out hover:-translate-y-0.5',
'grid min-w-32 items-start gap-1.5 rounded-lg border border-border/50 bg-background px-2.5 py-1.5 text-xs shadow-xl transition-all ease-in-out hover:-translate-y-0.5',
className
)}
>
@@ -165,7 +165,7 @@ function TooltipDemo({
{!hideIndicator && (
<div
className={cn(
'shrink-0 rounded-[2px] border-[--color-border] bg-[--color-bg]',
'shrink-0 rounded-[2px] border-(--color-border) bg-(--color-bg)',
{
'h-2.5 w-2.5': indicator === 'dot',
'w-1': indicator === 'line',
@@ -1,11 +1,11 @@
'use client'
import { Checkbox_Shadcn_ } from 'ui'
import { Checkbox } from 'ui'
export default function CheckboxDemo() {
return (
<div className="flex items-center space-x-2">
<Checkbox_Shadcn_ id="terms" />
<Checkbox id="terms" />
<label
htmlFor="terms"
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
@@ -1,9 +1,9 @@
import { Checkbox_Shadcn_ } from 'ui'
import { Checkbox } from 'ui'
export default function CheckboxDisabled() {
return (
<div className="flex items-center space-x-2">
<Checkbox_Shadcn_ id="terms2" disabled />
<Checkbox id="terms2" disabled />
<label
htmlFor="terms2"
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
@@ -5,14 +5,14 @@ import { useForm } from 'react-hook-form'
import { toast } from 'sonner'
import {
Button,
Checkbox_Shadcn_,
Form_Shadcn_,
FormControl_Shadcn_,
FormDescription_Shadcn_,
FormField_Shadcn_,
FormItem_Shadcn_,
FormLabel_Shadcn_,
FormMessage_Shadcn_,
Checkbox,
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
} from 'ui'
import { z } from 'zod'
@@ -68,32 +68,32 @@ export default function CheckboxReactHookFormMultiple() {
}
return (
<Form_Shadcn_ {...form}>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
<FormField_Shadcn_
<FormField
control={form.control}
name="items"
render={() => (
<FormItem_Shadcn_>
<FormItem>
<div className="mb-4">
<FormLabel_Shadcn_ className="text-base">Sidebar</FormLabel_Shadcn_>
<FormDescription_Shadcn_>
<FormLabel className="text-base">Sidebar</FormLabel>
<FormDescription>
Select the items you want to display in the sidebar.
</FormDescription_Shadcn_>
</FormDescription>
</div>
{items.map((item) => (
<FormField_Shadcn_
<FormField
key={item.id}
control={form.control}
name="items"
render={({ field }) => {
return (
<FormItem_Shadcn_
<FormItem
key={item.id}
className="flex flex-row items-start space-x-3 space-y-0"
>
<FormControl_Shadcn_>
<Checkbox_Shadcn_
<FormControl>
<Checkbox
checked={field.value?.includes(item.id)}
onCheckedChange={(checked) => {
return checked
@@ -101,19 +101,19 @@ export default function CheckboxReactHookFormMultiple() {
: field.onChange(field.value?.filter((value) => value !== item.id))
}}
/>
</FormControl_Shadcn_>
<FormLabel_Shadcn_ className="font-normal">{item.label}</FormLabel_Shadcn_>
</FormItem_Shadcn_>
</FormControl>
<FormLabel className="font-normal">{item.label}</FormLabel>
</FormItem>
)
}}
/>
))}
<FormMessage_Shadcn_ />
</FormItem_Shadcn_>
<FormMessage />
</FormItem>
)}
/>
<Button htmlType="submit">Submit</Button>
</form>
</Form_Shadcn_>
</Form>
)
}
@@ -6,13 +6,13 @@ import { useForm } from 'react-hook-form'
import { toast } from 'sonner'
import {
Button,
Checkbox_Shadcn_,
Form_Shadcn_,
FormControl_Shadcn_,
FormDescription_Shadcn_,
FormField_Shadcn_,
FormItem_Shadcn_,
FormLabel_Shadcn_,
Checkbox,
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
} from 'ui'
import { z } from 'zod'
@@ -39,28 +39,28 @@ export default function CheckboxReactHookFormSingle() {
}
return (
<Form_Shadcn_ {...form}>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
<FormField_Shadcn_
<FormField
control={form.control}
name="mobile"
render={({ field }) => (
<FormItem_Shadcn_ className="flex flex-row items-start space-x-3 space-y-0 rounded-md border p-4">
<FormControl_Shadcn_>
<Checkbox_Shadcn_ checked={field.value} onCheckedChange={field.onChange} />
</FormControl_Shadcn_>
<FormItem className="flex flex-row items-start space-x-3 space-y-0 rounded-md border p-4">
<FormControl>
<Checkbox checked={field.value} onCheckedChange={field.onChange} />
</FormControl>
<div className="space-y-1 leading-none">
<FormLabel_Shadcn_>Use different settings for my mobile devices</FormLabel_Shadcn_>
<FormDescription_Shadcn_>
<FormLabel>Use different settings for my mobile devices</FormLabel>
<FormDescription>
You can manage your mobile notifications in the{' '}
<Link href="/examples/forms">mobile settings</Link> page.
</FormDescription_Shadcn_>
</FormDescription>
</div>
</FormItem_Shadcn_>
</FormItem>
)}
/>
<Button htmlType="submit">Submit</Button>
</form>
</Form_Shadcn_>
</Form>
)
}
@@ -1,11 +1,11 @@
'use client'
import { Checkbox_Shadcn_ } from 'ui'
import { Checkbox } from 'ui'
export default function CheckboxWithText() {
return (
<div className="items-top flex space-x-2">
<Checkbox_Shadcn_ id="terms1" />
<Checkbox id="terms1" />
<div className="grid gap-1.5 leading-none">
<label
htmlFor="terms1"
@@ -6,35 +6,35 @@ import { ExampleLabel } from '@/components/example-label'
export default function Demo() {
return (
<div className="bg-studio w-full h-[320px] flex flex-col items-center border border-dashed rounded-md overflow-hidden">
<div className="bg-surface-200 border h-12 w-full rounded-t-md flex justify-center gap-3 items-center shadow">
<div className="bg-surface-200 border h-12 w-full rounded-t-md flex justify-center gap-3 items-center shadow-sm">
<div className="flex gap-3">
<ExampleLabel>grid header</ExampleLabel>
<ClassLabel>bg-surface-200</ClassLabel>
<ClassLabel>border</ClassLabel>
</div>
</div>
<div className="bg-200 border-b border-r border-l border-secondary h-14 w-full flex justify-center gap-3 items-center shadow">
<div className="bg-200 border-b border-r border-l border-secondary h-14 w-full flex justify-center gap-3 items-center shadow-sm">
<div className="flex gap-3">
<ExampleLabel>content row</ExampleLabel>
<ClassLabel>bg-200</ClassLabel>
<ClassLabel>border-secondary</ClassLabel>
</div>
</div>
<div className="bg-200 border-b border-r border-l border-secondary h-14 w-full flex justify-center gap-3 items-center shadow">
<div className="bg-200 border-b border-r border-l border-secondary h-14 w-full flex justify-center gap-3 items-center shadow-sm">
<div className="flex gap-3">
<ExampleLabel>content row</ExampleLabel>
<ClassLabel>bg-200</ClassLabel>
<ClassLabel>border-secondary</ClassLabel>
</div>
</div>
<div className="bg-200 border-b border-r border-l border-secondary h-14 w-full flex justify-center gap-3 items-center shadow">
<div className="bg-200 border-b border-r border-l border-secondary h-14 w-full flex justify-center gap-3 items-center shadow-sm">
<div className="flex gap-3">
<ExampleLabel>content row</ExampleLabel>
<ClassLabel>bg-200</ClassLabel>
<ClassLabel>border-secondary</ClassLabel>
</div>
</div>
<div className="bg-200 border-b border-r border-l border-secondary h-14 w-full flex justify-center gap-3 items-center shadow">
<div className="bg-200 border-b border-r border-l border-secondary h-14 w-full flex justify-center gap-3 items-center shadow-sm">
<div className="flex gap-3">
<ExampleLabel>content row</ExampleLabel>
<ClassLabel>bg-200</ClassLabel>
@@ -12,13 +12,13 @@ import {
CommandInput_Shadcn_,
CommandItem_Shadcn_,
CommandList_Shadcn_,
Form_Shadcn_,
FormControl_Shadcn_,
FormDescription_Shadcn_,
FormField_Shadcn_,
FormItem_Shadcn_,
FormLabel_Shadcn_,
FormMessage_Shadcn_,
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
Popover_Shadcn_,
PopoverContent_Shadcn_,
PopoverTrigger_Shadcn_,
@@ -61,17 +61,17 @@ export default function ComboboxForm() {
}
return (
<Form_Shadcn_ {...form}>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
<FormField_Shadcn_
<FormField
control={form.control}
name="language"
render={({ field }) => (
<FormItem_Shadcn_ className="flex flex-col">
<FormLabel_Shadcn_>Language</FormLabel_Shadcn_>
<FormItem className="flex flex-col">
<FormLabel>Language</FormLabel>
<Popover_Shadcn_>
<PopoverTrigger_Shadcn_ asChild>
<FormControl_Shadcn_>
<FormControl>
<Button
type="default"
role="combobox"
@@ -91,7 +91,7 @@ export default function ComboboxForm() {
? languages.find((language) => language.value === field.value)?.label
: 'Select language'}
</Button>
</FormControl_Shadcn_>
</FormControl>
</PopoverTrigger_Shadcn_>
<PopoverContent_Shadcn_ className="w-[200px] p-0">
<Command_Shadcn_>
@@ -121,17 +121,17 @@ export default function ComboboxForm() {
</Command_Shadcn_>
</PopoverContent_Shadcn_>
</Popover_Shadcn_>
<FormDescription_Shadcn_>
<FormDescription>
This is the language that will be used in the dashboard.
</FormDescription_Shadcn_>
<FormMessage_Shadcn_ />
</FormItem_Shadcn_>
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<Button htmlType="submit" type="secondary" size="small">
Submit
</Button>
</form>
</Form_Shadcn_>
</Form>
)
}
@@ -32,7 +32,7 @@ export default function CommandDialogDemo() {
<>
<p className="text-sm text-muted-foreground">
Press{' '}
<kbd className="pointer-events-none inline-flex h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium text-muted-foreground opacity-100">
<kbd className="pointer-events-none inline-flex h-5 select-none items-center gap-1 rounded-sm border bg-muted px-1.5 font-mono text-[10px] font-medium text-muted-foreground opacity-100">
<span className="text-xs">⌘</span>J
</kbd>
</p>
@@ -2,9 +2,9 @@ import { useState } from 'react'
import { useForm } from 'react-hook-form'
import {
Button,
Form_Shadcn_,
FormControl_Shadcn_,
FormField_Shadcn_,
Form,
FormControl,
FormField,
Select_Shadcn_,
SelectContent_Shadcn_,
SelectItem_Shadcn_,
@@ -46,13 +46,13 @@ export default function ConfirmationModalDemo() {
</p>
{/* Dropdown for Postgres version */}
<div className="pt-4">
<Form_Shadcn_ {...form}>
<FormField_Shadcn_
<Form {...form}>
<FormField
control={form.control}
name="postgresVersion"
render={({ field }) => (
<FormItemLayout layout="vertical" label="Postgres version">
<FormControl_Shadcn_>
<FormControl>
<Select_Shadcn_ value={field.value} onValueChange={field.onChange}>
<SelectTrigger_Shadcn_>
<SelectValue_Shadcn_ />
@@ -62,11 +62,11 @@ export default function ConfirmationModalDemo() {
<SelectItem_Shadcn_ value="17.6.1.055">17.6.1.055</SelectItem_Shadcn_>
</SelectContent_Shadcn_>
</Select_Shadcn_>
</FormControl_Shadcn_>
</FormControl>
</FormItemLayout>
)}
/>
</Form_Shadcn_>
</Form>
</div>
</div>
</ConfirmationModal>
@@ -1,9 +1,6 @@
import { useState } from 'react'
import DataGrid, { Column, useRowSelection } from 'react-data-grid'
import 'react-data-grid/lib/styles.css'
import { Checkbox_Shadcn_, cn } from 'ui'
import { Checkbox, cn } from 'ui'
type User = {
id: string
@@ -37,7 +34,7 @@ export default function DataGridDemo() {
return (
<div className="flex items-center justify-center h-full">
<Checkbox_Shadcn_
<Checkbox
checked={isRowSelected}
onClick={(e) => {
e.stopPropagation()
@@ -141,7 +138,7 @@ export default function DataGridDemo() {
return (
<div className="h-full w-full flex flex-col relative min-h-[400px] rounded-md border overflow-hidden">
<DataGrid
className="flex-grow border-t-0 bg-dash-canvas"
className="grow border-t-0 bg-dash-canvas"
rowHeight={44}
headerRowHeight={36}
columns={columns}
@@ -153,7 +150,7 @@ export default function DataGridDemo() {
return cn(
'bg-surface-75',
isSelected && 'bg-surface-200',
'[&>.rdg-cell]:border-box [&>.rdg-cell]:outline-none [&>.rdg-cell]:shadow-none',
'[&>.rdg-cell]:border-box [&>.rdg-cell]:outline-hidden [&>.rdg-cell]:shadow-none',
'[&>.rdg-cell]:border-secondary [&>.rdg-cell:not(:last-child)]:border-r',
!isLastRow && '[&>.rdg-cell]:border-b',
'[&>.rdg-cell:nth-child(2)>div]:ml-8'
@@ -1,8 +1,5 @@
import { Users } from 'lucide-react'
import DataGrid, { Column } from 'react-data-grid'
import 'react-data-grid/lib/styles.css'
import { cn } from 'ui'
/**
@@ -24,7 +21,7 @@ export default function DataGridEmptyState() {
return (
<div className="h-full w-full flex flex-col relative min-h-[400px] rounded-md border overflow-hidden">
<DataGrid
className="flex-grow border-t-0 bg-dash-canvas"
className="grow border-t-0 bg-dash-canvas"
rowHeight={44}
headerRowHeight={36}
columns={columns}
@@ -33,7 +30,7 @@ export default function DataGridEmptyState() {
rowClass={() => {
return cn(
'bg-surface-200 cursor-pointer',
'[&>.rdg-cell]:border-box [&>.rdg-cell]:outline-none [&>.rdg-cell]:shadow-none',
'[&>.rdg-cell]:border-box [&>.rdg-cell]:outline-hidden [&>.rdg-cell]:shadow-none',
'[&>.rdg-cell:first-child>div]:ml-8'
)
}}
@@ -17,14 +17,14 @@ import * as React from 'react'
import {
Button,
Card,
Checkbox_Shadcn_,
Checkbox,
DropdownMenu,
DropdownMenuCheckboxItem,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
Input,
Input_Shadcn_ as Input,
Table,
TableBody,
TableCell,
@@ -78,7 +78,7 @@ export const columns: ColumnDef<Payment>[] = [
{
id: 'select',
header: ({ table }) => (
<Checkbox_Shadcn_
<Checkbox
checked={
table.getIsAllPageRowsSelected() ||
(table.getIsSomePageRowsSelected() ? 'indeterminate' : false)
@@ -88,7 +88,7 @@ export const columns: ColumnDef<Payment>[] = [
/>
),
cell: ({ row }) => (
<Checkbox_Shadcn_
<Checkbox
checked={row.getIsSelected()}
onCheckedChange={(value) => row.toggleSelected(!!value)}
aria-label="Select row"
@@ -196,7 +196,7 @@ export default function DataTableDemo() {
placeholder="Filter by email"
value={(table.getColumn('email')?.getFilterValue() as string) ?? ''}
onChange={(event) => table.getColumn('email')?.setFilterValue(event.target.value)}
className="max-w-sm"
className="max-w-xs"
/>
<DropdownMenu>
<DropdownMenuTrigger asChild>
@@ -8,13 +8,13 @@ import { toast } from 'sonner'
import {
Button,
Calendar,
Form_Shadcn_,
FormControl_Shadcn_,
FormDescription_Shadcn_,
FormField_Shadcn_,
FormItem_Shadcn_,
FormLabel_Shadcn_,
FormMessage_Shadcn_,
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
Popover_Shadcn_,
PopoverContent_Shadcn_,
PopoverTrigger_Shadcn_,
@@ -45,17 +45,17 @@ export default function DatePickerForm() {
}
return (
<Form_Shadcn_ {...form}>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
<FormField_Shadcn_
<FormField
control={form.control}
name="dob"
render={({ field }) => (
<FormItem_Shadcn_ className="flex flex-col">
<FormLabel_Shadcn_>Date of birth</FormLabel_Shadcn_>
<FormItem className="flex flex-col">
<FormLabel>Date of birth</FormLabel>
<Popover_Shadcn_>
<PopoverTrigger_Shadcn_ asChild>
<FormControl_Shadcn_>
<FormControl>
<Button
type={'outline'}
className={cn(
@@ -66,7 +66,7 @@ export default function DatePickerForm() {
>
{field.value ? format(field.value, 'PPP') : <span>Pick a date</span>}
</Button>
</FormControl_Shadcn_>
</FormControl>
</PopoverTrigger_Shadcn_>
<PopoverContent_Shadcn_ className="w-auto p-0" align="start">
<Calendar
@@ -78,15 +78,13 @@ export default function DatePickerForm() {
/>
</PopoverContent_Shadcn_>
</Popover_Shadcn_>
<FormDescription_Shadcn_>
Your date of birth is used to calculate your age.
</FormDescription_Shadcn_>
<FormMessage_Shadcn_ />
</FormItem_Shadcn_>
<FormDescription>Your date of birth is used to calculate your age.</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<Button htmlType="submit">Submit</Button>
</form>
</Form_Shadcn_>
</Form>
)
}
@@ -1,4 +1,4 @@
import { Checkbox_Shadcn_ as Checkbox } from 'ui'
import { Checkbox } from 'ui'
import {
Field,
FieldContent,
@@ -1,4 +1,4 @@
import { Button, Checkbox_Shadcn_ as Checkbox, Input, Textarea } from 'ui'
import { Button, Checkbox, Input_Shadcn_ as Input, Textarea } from 'ui'
import {
Field,
FieldDescription,
@@ -1,4 +1,4 @@
import { Input } from 'ui'
import { Input_Shadcn_ as Input } from 'ui'
import {
Field,
FieldDescription,
@@ -1,4 +1,4 @@
import { Checkbox_Shadcn_ as Checkbox } from 'ui'
import { Checkbox } from 'ui'
import {
Field,
FieldDescription,
@@ -1,4 +1,4 @@
import { Card, CardContent, Checkbox_Shadcn_ as Checkbox } from 'ui'
import { Card, CardContent, Checkbox } from 'ui'
import {
Field,
FieldDescription,
@@ -42,16 +42,16 @@ export function FieldHear() {
</FieldDescription>
<FieldGroup className="flex flex-row flex-wrap gap-2 [--radius:9999rem]">
{options.map((option) => (
<FieldLabel htmlFor={option.value} key={option.value} className="!w-fit">
<FieldLabel htmlFor={option.value} key={option.value} className="w-fit!">
<Field
orientation="horizontal"
className="gap-1.5 overflow-hidden !px-3 !py-1.5 transition-all duration-100 ease-linear group-has-data-[state=checked]/field-label:!px-2"
className="gap-1.5 overflow-hidden px-3! py-1.5! transition-all duration-100 ease-linear group-has-data-checked/field-label:px-2!"
>
<Checkbox
value={option.value}
id={option.value}
defaultChecked={option.value === 'social-media'}
className="-ml-6 -translate-x-1 rounded-full transition-all duration-100 ease-linear data-[state=checked]:ml-0 data-[state=checked]:translate-x-0"
className="-ml-6 -translate-x-1 rounded-full transition-all duration-100 ease-linear data-checked:ml-0 data-checked:translate-x-0"
/>
<FieldTitle>{option.label}</FieldTitle>
</Field>
@@ -1,4 +1,4 @@
import { Input } from 'ui'
import { Input_Shadcn_ as Input } from 'ui'
import {
Field,
FieldDescription,
@@ -1,4 +1,4 @@
import { Button, Input, Textarea } from 'ui'
import { Button, Input_Shadcn_ as Input, Textarea } from 'ui'
import {
Field,
FieldContent,
@@ -1,6 +1,6 @@
import { zodResolver } from '@hookform/resolvers/zod'
import { useForm } from 'react-hook-form'
import { Button, Form_Shadcn_, FormControl_Shadcn_, FormField_Shadcn_, Switch } from 'ui'
import { Button, Form, FormControl, FormField, Switch } from 'ui'
import { Input } from 'ui-patterns/DataInputs/Input'
import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
import { InfoTooltip } from 'ui-patterns/info-tooltip'
@@ -24,9 +24,9 @@ export default function FormItemLayoutDemo() {
// action('form form.handleSubmit(onSubmit)')(values)
}
return (
<Form_Shadcn_ {...form}>
<Form {...form}>
<form className="w-96 flex flex-col gap-3" onSubmit={form.handleSubmit(onSubmit)}>
<FormField_Shadcn_
<FormField
control={form.control}
name="functionName"
render={({ field }) => (
@@ -36,9 +36,9 @@ export default function FormItemLayoutDemo() {
labelOptional="Optional"
afterLabel={<InfoTooltip side="top">Added after the label</InfoTooltip>}
>
<FormControl_Shadcn_>
<FormControl>
<Input placeholder="Name of function" {...field} />
</FormControl_Shadcn_>
</FormControl>
</FormItemLayout>
)}
/>
@@ -46,6 +46,6 @@ export default function FormItemLayoutDemo() {
Submit
</Button>
</form>
</Form_Shadcn_>
</Form>
)
}
@@ -1,6 +1,6 @@
import { zodResolver } from '@hookform/resolvers/zod'
import { useForm } from 'react-hook-form'
import { Button, Form_Shadcn_, FormControl_Shadcn_, FormField_Shadcn_, Switch } from 'ui'
import { Button, Form, FormControl, FormField, Switch } from 'ui'
import { Input } from 'ui-patterns/DataInputs/Input'
import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
import { InfoTooltip } from 'ui-patterns/info-tooltip'
@@ -24,9 +24,9 @@ export default function FormItemLayoutDemo() {
// action('form form.handleSubmit(onSubmit)')(values)
}
return (
<Form_Shadcn_ {...form}>
<Form {...form}>
<form className="w-96 flex flex-col gap-3" onSubmit={form.handleSubmit(onSubmit)}>
<FormField_Shadcn_
<FormField
control={form.control}
name="functionName"
render={({ field }) => (
@@ -36,9 +36,9 @@ export default function FormItemLayoutDemo() {
labelOptional="Optional"
beforeLabel={<InfoTooltip side="top">Added before the label</InfoTooltip>}
>
<FormControl_Shadcn_>
<FormControl>
<Input placeholder="Name of function" {...field} />
</FormControl_Shadcn_>
</FormControl>
</FormItemLayout>
)}
/>
@@ -46,6 +46,6 @@ export default function FormItemLayoutDemo() {
Submit
</Button>
</form>
</Form_Shadcn_>
</Form>
)
}
@@ -1,6 +1,6 @@
import { zodResolver } from '@hookform/resolvers/zod'
import { useForm } from 'react-hook-form'
import { Button, Form_Shadcn_, FormControl_Shadcn_, FormField_Shadcn_ } from 'ui'
import { Button, Form, FormControl, FormField } from 'ui'
import { Input } from 'ui-patterns/DataInputs/Input'
import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
import { z } from 'zod'
@@ -28,9 +28,9 @@ export default function FormItemLayoutDemo() {
// action('form form.handleSubmit(onSubmit)')(values)
}
return (
<Form_Shadcn_ {...form}>
<Form {...form}>
<form className="w-96 flex flex-col gap-3" onSubmit={form.handleSubmit(onSubmit)}>
<FormField_Shadcn_
<FormField
name="username"
control={form.control}
render={({ field }) => (
@@ -39,9 +39,9 @@ export default function FormItemLayoutDemo() {
description="This is your public display name"
labelOptional="optional"
>
<FormControl_Shadcn_>
<FormControl>
<Input placeholder="mildtomato" {...field} />
</FormControl_Shadcn_>
</FormControl>
</FormItemLayout>
)}
/>
@@ -49,6 +49,6 @@ export default function FormItemLayoutDemo() {
Submit
</Button>
</form>
</Form_Shadcn_>
</Form>
)
}
@@ -1,6 +1,6 @@
import { zodResolver } from '@hookform/resolvers/zod'
import { useForm } from 'react-hook-form'
import { Button, Checkbox_Shadcn_, Form_Shadcn_, FormControl_Shadcn_, FormField_Shadcn_ } from 'ui'
import { Button, Checkbox, Form, FormControl, FormField } from 'ui'
import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
import { z } from 'zod'
@@ -51,9 +51,9 @@ export default function FormItemLayoutDemo() {
// action('form form.handleSubmit(onSubmit)')(values)
}
return (
<Form_Shadcn_ {...form}>
<Form {...form}>
<form className="w-96 flex flex-col gap-3" onSubmit={form.handleSubmit(onSubmit)}>
<FormField_Shadcn_
<FormField
control={form.control}
name="items"
render={() => (
@@ -63,7 +63,7 @@ export default function FormItemLayoutDemo() {
layout="horizontal"
>
{items.map((item) => (
<FormField_Shadcn_
<FormField
key={item.id}
control={form.control}
name="items"
@@ -76,8 +76,8 @@ export default function FormItemLayoutDemo() {
layout="flex"
hideMessage
>
<FormControl_Shadcn_>
<Checkbox_Shadcn_
<FormControl>
<Checkbox
checked={field.value?.includes(item.id)}
onCheckedChange={(checked) => {
return checked
@@ -85,7 +85,7 @@ export default function FormItemLayoutDemo() {
: field.onChange(field.value?.filter((value) => value !== item.id))
}}
/>
</FormControl_Shadcn_>
</FormControl>
</FormItemLayout>
)
}}
@@ -99,6 +99,6 @@ export default function FormItemLayoutDemo() {
Submit
</Button>
</form>
</Form_Shadcn_>
</Form>
)
}
@@ -1,13 +1,6 @@
import { zodResolver } from '@hookform/resolvers/zod'
import { useForm } from 'react-hook-form'
import {
Badge,
Button,
Checkbox_Shadcn_,
Form_Shadcn_,
FormControl_Shadcn_,
FormField_Shadcn_,
} from 'ui'
import { Badge, Button, Checkbox, Form, FormControl, FormField } from 'ui'
import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
import { z } from 'zod'
@@ -29,9 +22,9 @@ export default function FormItemLayoutDemo() {
// action('form form.handleSubmit(onSubmit)')(values)
}
return (
<Form_Shadcn_ {...form}>
<Form {...form}>
<form className="w-96 flex flex-col gap-3" onSubmit={form.handleSubmit(onSubmit)}>
<FormField_Shadcn_
<FormField
control={form.control}
name="consistent_settings"
render={({ field }) => (
@@ -40,9 +33,9 @@ export default function FormItemLayoutDemo() {
description="This is your public display name."
layout="flex"
>
<FormControl_Shadcn_>
<Checkbox_Shadcn_ checked={field.value} onCheckedChange={field.onChange} />
</FormControl_Shadcn_>
<FormControl>
<Checkbox checked={field.value} onCheckedChange={field.onChange} />
</FormControl>
</FormItemLayout>
)}
/>
@@ -50,6 +43,6 @@ export default function FormItemLayoutDemo() {
Submit
</Button>
</form>
</Form_Shadcn_>
</Form>
)
}
@@ -1,6 +1,6 @@
import { zodResolver } from '@hookform/resolvers/zod'
import { useForm } from 'react-hook-form'
import { Button, Form_Shadcn_, FormControl_Shadcn_, FormField_Shadcn_, Separator } from 'ui'
import { Button, Form, FormControl, FormField, Separator } from 'ui'
import { Input } from 'ui-patterns/DataInputs/Input'
import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
import { z } from 'zod'
@@ -28,9 +28,9 @@ export default function FormItemLayoutDemo() {
// action('form form.handleSubmit(onSubmit)')(values)
}
return (
<Form_Shadcn_ {...form}>
<Form {...form}>
<form className="w-[520px] flex flex-col gap-8" onSubmit={form.handleSubmit(onSubmit)}>
<FormField_Shadcn_
<FormField
name="username"
control={form.control}
render={({ field }) => (
@@ -40,9 +40,9 @@ export default function FormItemLayoutDemo() {
description="This is your public display name"
labelOptional="optional"
>
<FormControl_Shadcn_>
<FormControl>
<Input placeholder="mildtomato" {...field} />
</FormControl_Shadcn_>
</FormControl>
</FormItemLayout>
)}
/>
@@ -53,6 +53,6 @@ export default function FormItemLayoutDemo() {
</Button>
</div>
</form>
</Form_Shadcn_>
</Form>
)
}
@@ -2,9 +2,9 @@ import { zodResolver } from '@hookform/resolvers/zod'
import { useForm } from 'react-hook-form'
import {
Button,
Form_Shadcn_,
FormControl_Shadcn_,
FormField_Shadcn_,
Form,
FormControl,
FormField,
Select_Shadcn_,
SelectContent_Shadcn_,
SelectItem_Shadcn_,
@@ -36,9 +36,9 @@ export default function FormItemLayoutDemo() {
// action('form form.handleSubmit(onSubmit)')(values)
}
return (
<Form_Shadcn_ {...form}>
<Form {...form}>
<form className="w-96 flex flex-col gap-3" onSubmit={form.handleSubmit(onSubmit)}>
<FormField_Shadcn_
<FormField
name="email"
control={form.control}
render={({ field }) => (
@@ -48,11 +48,11 @@ export default function FormItemLayoutDemo() {
labelOptional="Optional"
>
<Select_Shadcn_ onValueChange={field.onChange} defaultValue={field.value}>
<FormControl_Shadcn_>
<FormControl>
<SelectTrigger_Shadcn_>
<SelectValue_Shadcn_ placeholder="Select a verified email to display" />
</SelectTrigger_Shadcn_>
</FormControl_Shadcn_>
</FormControl>
<SelectContent_Shadcn_>
<SelectItem_Shadcn_ value="m@example.com">m@example.com</SelectItem_Shadcn_>
<SelectItem_Shadcn_ value="m@google.com">m@google.com</SelectItem_Shadcn_>
@@ -66,6 +66,6 @@ export default function FormItemLayoutDemo() {
Submit
</Button>
</form>
</Form_Shadcn_>
</Form>
)
}
@@ -1,6 +1,6 @@
import { zodResolver } from '@hookform/resolvers/zod'
import { useForm } from 'react-hook-form'
import { Button, Form_Shadcn_, FormControl_Shadcn_, FormField_Shadcn_, Switch } from 'ui'
import { Button, Form, FormControl, FormField, Switch } from 'ui'
import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
import { z } from 'zod'
@@ -22,9 +22,9 @@ export default function FormItemLayoutDemo() {
// action('form form.handleSubmit(onSubmit)')(values)
}
return (
<Form_Shadcn_ {...form}>
<Form {...form}>
<form className="w-96 flex flex-col gap-3" onSubmit={form.handleSubmit(onSubmit)}>
<FormField_Shadcn_
<FormField
control={form.control}
name="switch_option"
render={({ field }) => (
@@ -34,9 +34,9 @@ export default function FormItemLayoutDemo() {
description="This is an explanation."
layout="flex"
>
<FormControl_Shadcn_>
<FormControl>
<Switch checked={field.value} onCheckedChange={field.onChange} />
</FormControl_Shadcn_>
</FormControl>
</FormItemLayout>
)}
/>
@@ -44,6 +44,6 @@ export default function FormItemLayoutDemo() {
Submit
</Button>
</form>
</Form_Shadcn_>
</Form>
)
}
@@ -9,10 +9,10 @@ import {
Card,
CardContent,
CardFooter,
Checkbox_Shadcn_,
Form_Shadcn_,
FormControl_Shadcn_,
FormField_Shadcn_,
Checkbox,
Form,
FormControl,
FormField,
FormInputGroupInput,
FormInputGroupTextArea,
Input_Shadcn_,
@@ -133,12 +133,12 @@ export default function FormPatternsPageLayout() {
</PageSectionSummary>
</PageSectionMeta>
<PageSectionContent>
<Form_Shadcn_ {...form}>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)}>
<Card>
{/* Text Input */}
<CardContent>
<FormField_Shadcn_
<FormField
control={form.control}
name="name"
render={({ field }) => (
@@ -147,9 +147,9 @@ export default function FormPatternsPageLayout() {
label="Text Input"
description="Single-line text entry for short values"
>
<FormControl_Shadcn_>
<FormControl>
<Input_Shadcn_ {...field} placeholder="Enter text" />
</FormControl_Shadcn_>
</FormControl>
</FormItemLayout>
)}
/>
@@ -157,7 +157,7 @@ export default function FormPatternsPageLayout() {
{/* Password Input */}
<CardContent>
<FormField_Shadcn_
<FormField
control={form.control}
name="password"
render={({ field }) => (
@@ -166,9 +166,9 @@ export default function FormPatternsPageLayout() {
label="Password Input"
description="Masked input for secure text entry"
>
<FormControl_Shadcn_>
<FormControl>
<Input_Shadcn_ {...field} type="password" placeholder="Enter password" />
</FormControl_Shadcn_>
</FormControl>
</FormItemLayout>
)}
/>
@@ -176,7 +176,7 @@ export default function FormPatternsPageLayout() {
{/* Copyable Input */}
<CardContent>
<FormField_Shadcn_
<FormField
control={form.control}
name="apiKey"
render={() => (
@@ -185,7 +185,7 @@ export default function FormPatternsPageLayout() {
label="Copyable Input"
description="Read-only input with copy-to-clipboard functionality"
>
<FormControl_Shadcn_>
<FormControl>
<Input
copy
readOnly
@@ -193,7 +193,7 @@ export default function FormPatternsPageLayout() {
onChange={() => {}}
onCopy={() => console.log('Copied to clipboard')}
/>
</FormControl_Shadcn_>
</FormControl>
</FormItemLayout>
)}
/>
@@ -201,7 +201,7 @@ export default function FormPatternsPageLayout() {
{/* Number Input */}
<CardContent>
<FormField_Shadcn_
<FormField
control={form.control}
name="maxConnections"
render={({ field }) => (
@@ -210,7 +210,7 @@ export default function FormPatternsPageLayout() {
label="Number Input"
description="Numeric input with min/max validation"
>
<FormControl_Shadcn_>
<FormControl>
<Input_Shadcn_
{...field}
type="number"
@@ -218,7 +218,7 @@ export default function FormPatternsPageLayout() {
max={1000}
onChange={(e) => field.onChange(Number(e.target.value))}
/>
</FormControl_Shadcn_>
</FormControl>
</FormItemLayout>
)}
/>
@@ -226,7 +226,7 @@ export default function FormPatternsPageLayout() {
{/* Input with Units */}
<CardContent>
<FormField_Shadcn_
<FormField
control={form.control}
name="duration"
render={({ field }) => (
@@ -235,7 +235,7 @@ export default function FormPatternsPageLayout() {
label="Input with Units"
description="Input with additional unit label"
>
<FormControl_Shadcn_>
<FormControl>
<InputGroup>
<FormInputGroupInput
{...field}
@@ -248,7 +248,7 @@ export default function FormPatternsPageLayout() {
<InputGroupText className="font-mono">MB</InputGroupText>
</InputGroupAddon>
</InputGroup>
</FormControl_Shadcn_>
</FormControl>
</FormItemLayout>
)}
/>
@@ -256,7 +256,7 @@ export default function FormPatternsPageLayout() {
{/* Textarea */}
<CardContent>
<FormField_Shadcn_
<FormField
control={form.control}
name="description"
render={({ field }) => (
@@ -265,14 +265,14 @@ export default function FormPatternsPageLayout() {
label="Textarea"
description="Multi-line text input for longer content"
>
<FormControl_Shadcn_>
<FormControl>
<Textarea
{...field}
rows={4}
placeholder="Enter multi-line text"
className="resize-none"
/>
</FormControl_Shadcn_>
</FormControl>
</FormItemLayout>
)}
/>
@@ -280,7 +280,7 @@ export default function FormPatternsPageLayout() {
{/* Textarea with addon */}
<CardContent>
<FormField_Shadcn_
<FormField
control={form.control}
name="description"
render={({ field }) => (
@@ -289,7 +289,7 @@ export default function FormPatternsPageLayout() {
label="Textarea"
description="Multi-line text input for longer content with addon"
>
<FormControl_Shadcn_>
<FormControl>
<InputGroup>
<FormInputGroupTextArea
{...field}
@@ -301,7 +301,7 @@ export default function FormPatternsPageLayout() {
<InputGroupText>120 characters left</InputGroupText>
</InputGroupAddon>
</InputGroup>
</FormControl_Shadcn_>
</FormControl>
</FormItemLayout>
)}
/>
@@ -309,7 +309,7 @@ export default function FormPatternsPageLayout() {
{/* Icon Upload */}
<CardContent>
<FormField_Shadcn_
<FormField
control={form.control}
name="description"
render={() => (
@@ -318,7 +318,7 @@ export default function FormPatternsPageLayout() {
label="Icon upload"
description="For icons, avatars, or small images with preview"
>
<FormControl_Shadcn_>
<FormControl>
<div className="flex gap-4 items-center">
<button
type="button"
@@ -367,7 +367,7 @@ export default function FormPatternsPageLayout() {
}}
/>
</div>
</FormControl_Shadcn_>
</FormControl>
</FormItemLayout>
)}
/>
@@ -375,7 +375,7 @@ export default function FormPatternsPageLayout() {
{/* File Upload */}
<CardContent>
<FormField_Shadcn_
<FormField
control={form.control}
name="description"
render={() => (
@@ -384,7 +384,7 @@ export default function FormPatternsPageLayout() {
label="File Upload"
description="Drag-and-drop or select files for upload"
>
<FormControl_Shadcn_>
<FormControl>
<div
className={`border-2 rounded-lg p-6 text-center bg-muted transition-colors duration-300 ${
isDragging
@@ -439,7 +439,7 @@ export default function FormPatternsPageLayout() {
{uploadedFiles.map((file, idx) => (
<div
key={`${file.name}-${idx}`}
className="flex items-center justify-between gap-2 p-2 bg rounded border"
className="flex items-center justify-between gap-2 p-2 bg rounded-sm border"
>
<span className="text-sm text-foreground-light truncate flex-1">
{file.name}
@@ -460,7 +460,7 @@ export default function FormPatternsPageLayout() {
)}
</div>
</div>
</FormControl_Shadcn_>
</FormControl>
</FormItemLayout>
)}
/>
@@ -468,7 +468,7 @@ export default function FormPatternsPageLayout() {
{/* Switch */}
<CardContent>
<FormField_Shadcn_
<FormField
control={form.control}
name="enableFeature"
render={({ field }) => (
@@ -477,9 +477,9 @@ export default function FormPatternsPageLayout() {
label="Switch"
description="Toggle for boolean on/off states"
>
<FormControl_Shadcn_>
<FormControl>
<Switch checked={field.value} onCheckedChange={field.onChange} />
</FormControl_Shadcn_>
</FormControl>
</FormItemLayout>
)}
/>
@@ -493,18 +493,18 @@ export default function FormPatternsPageLayout() {
description="Boolean values or multiple selections"
>
<div className="w-full flex flex-col gap-4">
<FormField_Shadcn_
<FormField
control={form.control}
name="enableRls"
render={({ field }) => (
<div className="flex items-center w-full justify-start space-x-2">
<FormControl_Shadcn_>
<Checkbox_Shadcn_
<FormControl>
<Checkbox
id="enable-rls"
checked={field.value}
onCheckedChange={field.onChange}
/>
</FormControl_Shadcn_>
</FormControl>
<label
htmlFor="enable-rls"
className="text-sm text-foreground-light leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 cursor-pointer"
@@ -514,18 +514,18 @@ export default function FormPatternsPageLayout() {
</div>
)}
/>
<FormField_Shadcn_
<FormField
control={form.control}
name="enableNotifications"
render={({ field }) => (
<div className="flex items-center w-full justify-start space-x-2">
<FormControl_Shadcn_>
<Checkbox_Shadcn_
<FormControl>
<Checkbox
id="enable-notifications"
checked={field.value}
onCheckedChange={field.onChange}
/>
</FormControl_Shadcn_>
</FormControl>
<label
htmlFor="enable-notifications"
className="text-sm text-foreground-light leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 cursor-pointer"
@@ -535,18 +535,18 @@ export default function FormPatternsPageLayout() {
</div>
)}
/>
<FormField_Shadcn_
<FormField
control={form.control}
name="enableAnalytics"
render={({ field }) => (
<div className="flex items-center w-full justify-start space-x-2">
<FormControl_Shadcn_>
<Checkbox_Shadcn_
<FormControl>
<Checkbox
id="enable-analytics"
checked={field.value}
onCheckedChange={field.onChange}
/>
</FormControl_Shadcn_>
</FormControl>
<label
htmlFor="enable-analytics"
className="text-sm text-foreground-light leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 cursor-pointer"
@@ -562,7 +562,7 @@ export default function FormPatternsPageLayout() {
{/* Select */}
<CardContent>
<FormField_Shadcn_
<FormField
control={form.control}
name="region"
render={({ field }) => (
@@ -571,7 +571,7 @@ export default function FormPatternsPageLayout() {
label="Select (Dropdown)"
description="Single selection from a list of options"
>
<FormControl_Shadcn_>
<FormControl>
<Select_Shadcn_ value={field.value} onValueChange={field.onChange}>
<SelectTrigger_Shadcn_>
<SelectValue_Shadcn_ placeholder="Select an option" />
@@ -588,7 +588,7 @@ export default function FormPatternsPageLayout() {
</SelectItem_Shadcn_>
</SelectContent_Shadcn_>
</Select_Shadcn_>
</FormControl_Shadcn_>
</FormControl>
</FormItemLayout>
)}
/>
@@ -596,7 +596,7 @@ export default function FormPatternsPageLayout() {
{/* Multi-Select */}
<CardContent>
<FormField_Shadcn_
<FormField
control={form.control}
name="schemas"
render={({ field }) => (
@@ -633,7 +633,7 @@ export default function FormPatternsPageLayout() {
{/* Radio Group */}
<CardContent>
<FormField_Shadcn_
<FormField
control={form.control}
name="queueType"
render={({ field }) => (
@@ -642,7 +642,7 @@ export default function FormPatternsPageLayout() {
label="Radio Group"
description="Single selection from multiple options"
>
<FormControl_Shadcn_>
<FormControl>
<RadioGroupStacked value={field.value} onValueChange={field.onChange}>
<RadioGroupStackedItem
value="basic"
@@ -655,7 +655,7 @@ export default function FormPatternsPageLayout() {
description="Second option description"
/>
</RadioGroupStacked>
</FormControl_Shadcn_>
</FormControl>
</FormItemLayout>
)}
/>
@@ -663,7 +663,7 @@ export default function FormPatternsPageLayout() {
{/* Date Picker */}
<CardContent>
<FormField_Shadcn_
<FormField
control={form.control}
name="expiryDate"
render={({ field }) => (
@@ -672,7 +672,7 @@ export default function FormPatternsPageLayout() {
label="Date Picker"
description="Date selection with calendar popover"
>
<FormControl_Shadcn_>
<FormControl>
<Popover_Shadcn_>
<PopoverTrigger_Shadcn_ asChild>
<Button
@@ -692,7 +692,7 @@ export default function FormPatternsPageLayout() {
/>
</PopoverContent_Shadcn_>
</Popover_Shadcn_>
</FormControl_Shadcn_>
</FormControl>
</FormItemLayout>
)}
/>
@@ -700,7 +700,7 @@ export default function FormPatternsPageLayout() {
{/* Field Array */}
<CardContent>
<FormField_Shadcn_
<FormField
control={form.control}
name="redirectUris"
render={() => (
@@ -725,7 +725,7 @@ export default function FormPatternsPageLayout() {
{/* Key/Value Field Array */}
<CardContent>
<FormField_Shadcn_
<FormField
control={form.control}
name="httpHeaders"
render={() => (
@@ -783,7 +783,7 @@ export default function FormPatternsPageLayout() {
</CardFooter>
</Card>
</form>
</Form_Shadcn_>
</Form>
</PageSectionContent>
</PageSection>
</div>
@@ -6,10 +6,10 @@ import { useForm } from 'react-hook-form'
import {
Button,
Calendar,
Checkbox_Shadcn_,
Form_Shadcn_,
FormControl_Shadcn_,
FormField_Shadcn_,
Checkbox,
Form,
FormControl,
FormField,
FormInputGroupInput,
Input_Shadcn_,
InputGroup,
@@ -135,15 +135,15 @@ export default function FormPatternsSidePanel() {
<SheetHeader>
<SheetTitle>Create Configuration</SheetTitle>
</SheetHeader>
<Form_Shadcn_ {...form}>
<Form {...form}>
<form
id={formId}
onSubmit={form.handleSubmit(onSubmit)}
className="overflow-auto flex-grow px-0"
className="overflow-auto grow px-0"
>
{/* Text Input */}
<SheetSection>
<FormField_Shadcn_
<FormField
control={form.control}
name="name"
render={({ field }) => (
@@ -152,9 +152,9 @@ export default function FormPatternsSidePanel() {
label="Text Input"
description="Single-line text entry for short values"
>
<FormControl_Shadcn_ className="col-span-6">
<FormControl className="col-span-6">
<Input_Shadcn_ {...field} placeholder="Enter text" />
</FormControl_Shadcn_>
</FormControl>
</FormItemLayout>
)}
/>
@@ -164,7 +164,7 @@ export default function FormPatternsSidePanel() {
{/* Password Input */}
<SheetSection>
<FormField_Shadcn_
<FormField
control={form.control}
name="password"
render={({ field }) => (
@@ -173,9 +173,9 @@ export default function FormPatternsSidePanel() {
label="Password Input"
description="Masked input for secure text entry"
>
<FormControl_Shadcn_ className="col-span-6">
<FormControl className="col-span-6">
<Input_Shadcn_ {...field} type="password" placeholder="Enter password" />
</FormControl_Shadcn_>
</FormControl>
</FormItemLayout>
)}
/>
@@ -185,7 +185,7 @@ export default function FormPatternsSidePanel() {
{/* Copyable Input */}
<SheetSection>
<FormField_Shadcn_
<FormField
control={form.control}
name="apiKey"
render={() => (
@@ -194,7 +194,7 @@ export default function FormPatternsSidePanel() {
label="Copyable Input"
description="Read-only input with copy-to-clipboard functionality"
>
<FormControl_Shadcn_ className="col-span-6">
<FormControl className="col-span-6">
<Input
copy
readOnly
@@ -203,7 +203,7 @@ export default function FormPatternsSidePanel() {
onChange={() => {}}
onCopy={() => console.log('Copied to clipboard')}
/>
</FormControl_Shadcn_>
</FormControl>
</FormItemLayout>
)}
/>
@@ -213,7 +213,7 @@ export default function FormPatternsSidePanel() {
{/* Number Input */}
<SheetSection>
<FormField_Shadcn_
<FormField
control={form.control}
name="maxConnections"
render={({ field }) => (
@@ -222,7 +222,7 @@ export default function FormPatternsSidePanel() {
label="Number Input"
description="Numeric input with min/max validation"
>
<FormControl_Shadcn_ className="col-span-6">
<FormControl className="col-span-6">
<Input_Shadcn_
{...field}
type="number"
@@ -230,7 +230,7 @@ export default function FormPatternsSidePanel() {
max={1000}
onChange={(e) => field.onChange(Number(e.target.value))}
/>
</FormControl_Shadcn_>
</FormControl>
</FormItemLayout>
)}
/>
@@ -240,7 +240,7 @@ export default function FormPatternsSidePanel() {
{/* Input with Units */}
<SheetSection>
<FormField_Shadcn_
<FormField
control={form.control}
name="duration"
render={({ field }) => (
@@ -249,14 +249,14 @@ export default function FormPatternsSidePanel() {
label="Input with Units"
description="Input with additional unit label"
>
<FormControl_Shadcn_ className="col-span-6">
<FormControl className="col-span-6">
<InputGroup>
<FormInputGroupInput {...field} type="number" min={5} max={30} />
<InputGroupAddon align="inline-end">
<InputGroupText>MB</InputGroupText>
</InputGroupAddon>
</InputGroup>
</FormControl_Shadcn_>
</FormControl>
</FormItemLayout>
)}
/>
@@ -266,7 +266,7 @@ export default function FormPatternsSidePanel() {
{/* Textarea */}
<SheetSection>
<FormField_Shadcn_
<FormField
control={form.control}
name="description"
render={({ field }) => (
@@ -275,14 +275,14 @@ export default function FormPatternsSidePanel() {
label="Textarea"
description="Multi-line text input for longer content"
>
<FormControl_Shadcn_ className="col-span-6">
<FormControl className="col-span-6">
<Textarea
{...field}
rows={3}
placeholder="Enter multi-line text"
className="resize-none"
/>
</FormControl_Shadcn_>
</FormControl>
</FormItemLayout>
)}
/>
@@ -292,7 +292,7 @@ export default function FormPatternsSidePanel() {
{/* Icon Upload */}
<SheetSection>
<FormField_Shadcn_
<FormField
control={form.control}
name="description"
render={() => (
@@ -301,7 +301,7 @@ export default function FormPatternsSidePanel() {
label="Icon upload"
description="For icons, avatars, or small images with preview"
>
<FormControl_Shadcn_ className="col-span-6">
<FormControl className="col-span-6">
<div className="flex gap-4 items-center">
<button
type="button"
@@ -350,7 +350,7 @@ export default function FormPatternsSidePanel() {
}}
/>
</div>
</FormControl_Shadcn_>
</FormControl>
</FormItemLayout>
)}
/>
@@ -360,7 +360,7 @@ export default function FormPatternsSidePanel() {
{/* File Upload */}
<SheetSection>
<FormField_Shadcn_
<FormField
control={form.control}
name="description"
render={() => (
@@ -369,7 +369,7 @@ export default function FormPatternsSidePanel() {
label="File Upload"
description="Drag-and-drop or select files for upload"
>
<FormControl_Shadcn_ className="col-span-6">
<FormControl className="col-span-6">
<div
className={`border-2 rounded-lg p-6 text-center bg-muted transition-colors duration-300 ${
isDragging
@@ -424,7 +424,7 @@ export default function FormPatternsSidePanel() {
{uploadedFiles.map((file, idx) => (
<div
key={`${file.name}-${idx}`}
className="flex items-center justify-between gap-2 p-2 bg rounded border"
className="flex items-center justify-between gap-2 p-2 bg rounded-sm border"
>
<span className="text-sm text-foreground-light truncate flex-1">
{file.name}
@@ -443,7 +443,7 @@ export default function FormPatternsSidePanel() {
)}
</div>
</div>
</FormControl_Shadcn_>
</FormControl>
</FormItemLayout>
)}
/>
@@ -453,7 +453,7 @@ export default function FormPatternsSidePanel() {
{/* Switch */}
<SheetSection>
<FormField_Shadcn_
<FormField
control={form.control}
name="enableFeature"
render={({ field }) => (
@@ -462,9 +462,9 @@ export default function FormPatternsSidePanel() {
label="Switch"
description="Toggle for boolean on/off states"
>
<FormControl_Shadcn_ className="col-span-6">
<FormControl className="col-span-6">
<Switch checked={field.value} onCheckedChange={field.onChange} />
</FormControl_Shadcn_>
</FormControl>
</FormItemLayout>
)}
/>
@@ -478,18 +478,18 @@ export default function FormPatternsSidePanel() {
description="Boolean values or multiple selections"
>
<div className="col-span-6 w-full flex flex-col gap-4">
<FormField_Shadcn_
<FormField
control={form.control}
name="enableRls"
render={({ field }) => (
<div className="flex items-center w-full justify-start space-x-2">
<FormControl_Shadcn_>
<Checkbox_Shadcn_
<FormControl>
<Checkbox
id="enable-rls"
checked={field.value}
onCheckedChange={field.onChange}
/>
</FormControl_Shadcn_>
</FormControl>
<label
htmlFor="enable-rls"
className="text-sm text-foreground-light leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 cursor-pointer"
@@ -499,18 +499,18 @@ export default function FormPatternsSidePanel() {
</div>
)}
/>
<FormField_Shadcn_
<FormField
control={form.control}
name="enableNotifications"
render={({ field }) => (
<div className="flex items-center w-full justify-start space-x-2">
<FormControl_Shadcn_>
<Checkbox_Shadcn_
<FormControl>
<Checkbox
id="enable-notifications"
checked={field.value}
onCheckedChange={field.onChange}
/>
</FormControl_Shadcn_>
</FormControl>
<label
htmlFor="enable-notifications"
className="text-sm text-foreground-light leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 cursor-pointer"
@@ -520,18 +520,18 @@ export default function FormPatternsSidePanel() {
</div>
)}
/>
<FormField_Shadcn_
<FormField
control={form.control}
name="enableAnalytics"
render={({ field }) => (
<div className="flex items-center w-full justify-start space-x-2">
<FormControl_Shadcn_>
<Checkbox_Shadcn_
<FormControl>
<Checkbox
id="enable-analytics"
checked={field.value}
onCheckedChange={field.onChange}
/>
</FormControl_Shadcn_>
</FormControl>
<label
htmlFor="enable-analytics"
className="text-sm text-foreground-light leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 cursor-pointer"
@@ -549,7 +549,7 @@ export default function FormPatternsSidePanel() {
{/* Select */}
<SheetSection>
<FormField_Shadcn_
<FormField
control={form.control}
name="region"
render={({ field }) => (
@@ -558,7 +558,7 @@ export default function FormPatternsSidePanel() {
label="Select (Dropdown)"
description="Single selection from a list of options"
>
<FormControl_Shadcn_ className="col-span-6">
<FormControl className="col-span-6">
<Select_Shadcn_ value={field.value} onValueChange={field.onChange}>
<SelectTrigger_Shadcn_>
<SelectValue_Shadcn_ placeholder="Select an option" />
@@ -575,7 +575,7 @@ export default function FormPatternsSidePanel() {
</SelectItem_Shadcn_>
</SelectContent_Shadcn_>
</Select_Shadcn_>
</FormControl_Shadcn_>
</FormControl>
</FormItemLayout>
)}
/>
@@ -585,7 +585,7 @@ export default function FormPatternsSidePanel() {
{/* Multi-Select */}
<SheetSection>
<FormField_Shadcn_
<FormField
control={form.control}
name="schemas"
render={({ field }) => (
@@ -607,7 +607,7 @@ export default function FormPatternsSidePanel() {
badgeLimit="wrap"
showIcon={false}
deletableBadge
className="w-full !min-w-lg"
className="w-full min-w-lg!"
/>
<MultiSelectorContent>
<MultiSelectorList>
@@ -627,7 +627,7 @@ export default function FormPatternsSidePanel() {
{/* Radio Group */}
<SheetSection>
<FormField_Shadcn_
<FormField
control={form.control}
name="queueType"
render={({ field }) => (
@@ -659,7 +659,7 @@ export default function FormPatternsSidePanel() {
{/* Date Picker */}
<SheetSection>
<FormField_Shadcn_
<FormField
control={form.control}
name="expiryDate"
render={({ field }) => (
@@ -668,7 +668,7 @@ export default function FormPatternsSidePanel() {
label="Date Picker"
description="Date selection with calendar popover"
>
<FormControl_Shadcn_ className="col-span-6">
<FormControl className="col-span-6">
<Popover_Shadcn_>
<PopoverTrigger_Shadcn_ asChild>
<Button
@@ -688,7 +688,7 @@ export default function FormPatternsSidePanel() {
/>
</PopoverContent_Shadcn_>
</Popover_Shadcn_>
</FormControl_Shadcn_>
</FormControl>
</FormItemLayout>
)}
/>
@@ -698,7 +698,7 @@ export default function FormPatternsSidePanel() {
{/* Field Array */}
<SheetSection>
<FormField_Shadcn_
<FormField
control={form.control}
name="redirectUris"
render={() => (
@@ -727,7 +727,7 @@ export default function FormPatternsSidePanel() {
{/* Key/Value Field Array */}
<SheetSection>
<FormField_Shadcn_
<FormField
control={form.control}
name="httpHeaders"
render={() => (
@@ -778,7 +778,7 @@ export default function FormPatternsSidePanel() {
</FormItemLayout>
</SheetSection>
</form>
</Form_Shadcn_>
</Form>
<SheetFooter>
<Button
type="default"
@@ -55,7 +55,7 @@ export default function InnerSideMenuEmpty() {
<Heart className="text-light" size={13} />
</div>
<Pointer
className="absolute -right-[6px] -bottom-2 text-lighter"
className="absolute right-[-6px] -bottom-2 text-lighter"
strokeWidth={1.5}
size={16}
/>
@@ -5,14 +5,14 @@ import { useForm } from 'react-hook-form'
import { toast } from 'sonner'
import {
Button,
Form_Shadcn_,
FormControl_Shadcn_,
FormDescription_Shadcn_,
FormField_Shadcn_,
FormItem_Shadcn_,
FormLabel_Shadcn_,
FormMessage_Shadcn_,
Input,
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
Input_Shadcn_ as Input,
} from 'ui'
import { z } from 'zod'
@@ -41,26 +41,26 @@ export default function InputForm() {
}
return (
<Form_Shadcn_ {...form}>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="w-2/3 space-y-6">
<FormField_Shadcn_
<FormField
control={form.control}
name="username"
render={({ field }) => (
<FormItem_Shadcn_>
<FormLabel_Shadcn_>Username</FormLabel_Shadcn_>
<FormControl_Shadcn_>
<FormItem>
<FormLabel>Username</FormLabel>
<FormControl>
<Input placeholder="shadcn" {...field} />
</FormControl_Shadcn_>
<FormDescription_Shadcn_>This is your public display name.</FormDescription_Shadcn_>
<FormMessage_Shadcn_ />
</FormItem_Shadcn_>
</FormControl>
<FormDescription>This is your public display name.</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<Button htmlType="submit" type="secondary">
Submit
</Button>
</form>
</Form_Shadcn_>
</Form>
)
}
@@ -5,13 +5,13 @@ import { useForm } from 'react-hook-form'
import { toast } from 'sonner'
import {
Button,
Form_Shadcn_,
FormControl_Shadcn_,
FormDescription_Shadcn_,
FormField_Shadcn_,
FormItem_Shadcn_,
FormLabel_Shadcn_,
FormMessage_Shadcn_,
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
InputOTP,
InputOTPGroup,
InputOTPSlot,
@@ -43,15 +43,15 @@ export default function InputOTPForm() {
}
return (
<Form_Shadcn_ {...form}>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="w-2/3 space-y-6">
<FormField_Shadcn_
<FormField
control={form.control}
name="pin"
render={({ field }) => (
<FormItem_Shadcn_>
<FormLabel_Shadcn_>One-Time Password</FormLabel_Shadcn_>
<FormControl_Shadcn_>
<FormItem>
<FormLabel>One-Time Password</FormLabel>
<FormControl>
<InputOTP maxLength={6} {...field}>
<InputOTPGroup>
<InputOTPSlot index={0} />
@@ -62,17 +62,17 @@ export default function InputOTPForm() {
<InputOTPSlot index={5} />
</InputOTPGroup>
</InputOTP>
</FormControl_Shadcn_>
<FormDescription_Shadcn_>
</FormControl>
<FormDescription>
Please enter the one-time password sent to your phone.
</FormDescription_Shadcn_>
<FormMessage_Shadcn_ />
</FormItem_Shadcn_>
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<Button htmlType="submit">Submit</Button>
</form>
</Form_Shadcn_>
</Form>
)
}
@@ -1,6 +1,6 @@
import { zodResolver } from '@hookform/resolvers/zod'
import { useForm } from 'react-hook-form'
import { Button, Form_Shadcn_ } from 'ui'
import { Button, Form } from 'ui'
import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
import { KeyValueFieldArray } from 'ui-patterns/form/KeyValueFieldArray/KeyValueFieldArray'
import { getKeyValueFieldArrayValidationIssues } from 'ui-patterns/form/KeyValueFieldArray/validation'
@@ -44,7 +44,7 @@ export default function KeyValueFieldArrayDemo() {
}
return (
<Form_Shadcn_ {...form}>
<Form {...form}>
<form className="w-full max-w-2xl" onSubmit={form.handleSubmit(onSubmit)}>
<FormItemLayout
label="HTTP headers"
@@ -69,6 +69,6 @@ export default function KeyValueFieldArrayDemo() {
</Button>
</div>
</form>
</Form_Shadcn_>
</Form>
)
}
@@ -1,10 +1,10 @@
import { Checkbox_Shadcn_, Label_Shadcn_ } from 'ui'
import { Checkbox, Label_Shadcn_ } from 'ui'
export default function LabelDemo() {
return (
<div>
<div className="flex items-center space-x-2">
<Checkbox_Shadcn_ id="terms" />
<Checkbox id="terms" />
<Label_Shadcn_ htmlFor="terms">Accept terms and conditions</Label_Shadcn_>
</div>
</div>
@@ -0,0 +1,71 @@
import { useState } from 'react'
import {
Button,
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogSection,
DialogSectionSeparator,
DialogTitle,
DialogTrigger,
Label_Shadcn_,
} from 'ui'
import {
MultiSelector,
MultiSelectorContent,
MultiSelectorItem,
MultiSelectorList,
MultiSelectorTrigger,
} from 'ui-patterns/multi-select'
export default function MultiSelectDemo() {
const [selectedValues, setSelectedValues] = useState<string[]>([])
const fruits = [
{ value: 'Apple', isDisabled: false },
{ value: 'Banana', isDisabled: false },
{ value: 'Cherry', isDisabled: false },
{ value: 'Date', isDisabled: false },
{ value: 'Elderberrie', isDisabled: false },
{ value: 'Fig', isDisabled: false },
{ value: 'Grape', isDisabled: false },
{ value: 'Kiwi', isDisabled: true },
{ value: 'Mango', isDisabled: false },
{ value: 'Strawberry', isDisabled: false },
]
return (
<Dialog>
<DialogTrigger>Open</DialogTrigger>
<DialogContent className="sm:max-w-[425px]">
<DialogHeader>
<DialogTitle>Choose your fruits</DialogTitle>
<DialogDescription>Select the fruits you like.</DialogDescription>
</DialogHeader>
<DialogSectionSeparator />
<DialogSection className="space-y-4">
<div>
<Label_Shadcn_ htmlFor="fruits">Fruits</Label_Shadcn_>
<MultiSelector id="fruits" values={selectedValues} onValuesChange={setSelectedValues}>
<MultiSelectorTrigger label="Select fruits" badgeLimit="wrap" showIcon={false} />
<MultiSelectorContent>
<MultiSelectorList>
{fruits.map(({ value, isDisabled }) => (
<MultiSelectorItem key={value} value={value} disabled={isDisabled}>
{value}
</MultiSelectorItem>
))}
</MultiSelectorList>
</MultiSelectorContent>
</MultiSelector>
</div>
</DialogSection>
<DialogFooter>
<Button>Save changes</Button>
</DialogFooter>
</DialogContent>
</Dialog>
)
}
@@ -65,7 +65,7 @@ export default function NavigationMenuDemo() {
<li className="row-span-3">
<NavigationMenuLink asChild>
<a
className="flex h-full w-full select-none flex-col justify-end rounded-md bg-gradient-to-b border from-background-surface-100/20 to-background-surface-100 p-6 no-underline outline-none focus:shadow-md"
className="flex h-full w-full select-none flex-col justify-end rounded-md bg-linear-to-b border from-background-surface-100/20 to-background-surface-100 p-6 no-underline outline-hidden focus:shadow-md"
href="/"
>
{/* <Icons.logo className="h-6 w-6" /> */}
@@ -125,7 +125,7 @@ const ListItem = React.forwardRef<React.ElementRef<'a'>, React.ComponentPropsWit
<a
ref={ref}
className={cn(
'block select-none space-y-1 rounded-md p-3 leading-none no-underline outline-none transition-colors hover:bg-surface-100/50 hover:text-foreground focus:bg-surface-100/50 focus:text-foreground',
'block select-none space-y-1 rounded-md p-3 leading-none no-underline outline-hidden transition-colors hover:bg-surface-100/50 hover:text-foreground focus:bg-surface-100/50 focus:text-foreground',
className
)}
{...props}
@@ -66,7 +66,7 @@ export default function NavigationMenuDemo() {
<li className="row-span-3">
<NavigationMenuLink asChild>
<a
className="flex h-full w-full select-none flex-col justify-end rounded-md bg-gradient-to-b from-muted/50 to-muted p-6 no-underline outline-none focus:shadow-md"
className="flex h-full w-full select-none flex-col justify-end rounded-md bg-linear-to-b from-muted/50 to-muted p-6 no-underline outline-hidden focus:shadow-md"
href="/"
>
{/* <Icons.logo className="h-6 w-6" /> */}
@@ -170,7 +170,7 @@ const ListItem = React.forwardRef<React.ElementRef<'a'>, React.ComponentPropsWit
<a
ref={ref}
className={cn(
'block select-none space-y-1 rounded-md p-3 leading-none no-underline outline-none transition-colors hover:bg-surface-100 hover:text-accent-foreground focus:bg-surface-100 focus:text-accent-foreground',
'block select-none space-y-1 rounded-md p-3 leading-none no-underline outline-hidden transition-colors hover:bg-surface-100 hover:text-accent-foreground focus:bg-surface-100 focus:text-accent-foreground',
className
)}
{...props}
@@ -8,7 +8,9 @@ import {
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
Input,
InputGroup,
InputGroupAddon,
InputGroupInput,
Table,
TableBody,
TableCell,
@@ -68,12 +70,16 @@ export default function PageLayoutList() {
<div className="w-full space-y-4">
<div className="flex flex-col lg:flex-row lg:items-center justify-between gap-2 flex-wrap">
<div className="flex flex-col lg:flex-row lg:items-center gap-2">
<Input
placeholder="Search for a function"
size="tiny"
icon={<Search />}
className="w-full lg:w-52"
/>
<InputGroup>
<InputGroupInput
placeholder="Search for a function"
size="tiny"
className="w-full lg:w-52"
/>
<InputGroupAddon>
<Search />
</InputGroupAddon>
</InputGroup>
</div>
<Button type="primary">Create a new function</Button>
</div>
@@ -5,9 +5,9 @@ import {
Card,
CardContent,
CardFooter,
Form_Shadcn_,
FormControl_Shadcn_,
FormField_Shadcn_,
Form,
FormControl,
FormField,
InputGroup,
InputGroupAddon,
InputGroupInput,
@@ -96,11 +96,11 @@ export default function PageLayoutSettings() {
</PageSectionSummary>
</PageSectionMeta>
<PageSectionContent>
<Form_Shadcn_ {...refreshTokenForm}>
<Form {...refreshTokenForm}>
<form className="space-y-4">
<Card>
<CardContent className="pt-6">
<FormField_Shadcn_
<FormField
control={refreshTokenForm.control}
name="REFRESH_TOKEN_ROTATION_ENABLED"
render={({ field }) => (
@@ -109,15 +109,15 @@ export default function PageLayoutSettings() {
label="Detect and revoke potentially compromised refresh tokens"
description="Prevent replay attacks from potentially compromised refresh tokens."
>
<FormControl_Shadcn_>
<FormControl>
<Switch checked={field.value} onCheckedChange={field.onChange} />
</FormControl_Shadcn_>
</FormControl>
</FormItemLayout>
)}
/>
</CardContent>
<CardContent>
<FormField_Shadcn_
<FormField
control={refreshTokenForm.control}
name="SECURITY_REFRESH_TOKEN_REUSE_INTERVAL"
render={({ field }) => (
@@ -126,14 +126,14 @@ export default function PageLayoutSettings() {
label="Refresh token reuse interval"
description="Time interval where the same refresh token can be used multiple times to request for an access token. Recommendation: 10 seconds."
>
<FormControl_Shadcn_>
<FormControl>
<InputGroup>
<InputGroupAddon align="inline-end">
<InputGroupText>seconds</InputGroupText>
</InputGroupAddon>
<InputGroupInput type="number" min={0} {...field} />
</InputGroup>
</FormControl_Shadcn_>
</FormControl>
</FormItemLayout>
)}
/>
@@ -154,7 +154,7 @@ export default function PageLayoutSettings() {
</CardFooter>
</Card>
</form>
</Form_Shadcn_>
</Form>
</PageSectionContent>
</PageSection>
@@ -168,11 +168,11 @@ export default function PageLayoutSettings() {
</PageSectionSummary>
</PageSectionMeta>
<PageSectionContent>
<Form_Shadcn_ {...userSessionsForm}>
<Form {...userSessionsForm}>
<form className="space-y-4">
<Card>
<CardContent>
<FormField_Shadcn_
<FormField
control={userSessionsForm.control}
name="SESSIONS_SINGLE_PER_USER"
render={({ field }) => (
@@ -181,16 +181,16 @@ export default function PageLayoutSettings() {
label="Enforce single session per user"
description="If enabled, all but a user's most recently active session will be terminated."
>
<FormControl_Shadcn_>
<FormControl>
<Switch checked={field.value} onCheckedChange={field.onChange} />
</FormControl_Shadcn_>
</FormControl>
</FormItemLayout>
)}
/>
</CardContent>
<CardContent>
<FormField_Shadcn_
<FormField
control={userSessionsForm.control}
name="SESSIONS_TIMEBOX"
render={({ field }) => (
@@ -200,7 +200,7 @@ export default function PageLayoutSettings() {
description="The amount of time before a user is forced to sign in again. Use 0 for never."
>
<div className="flex items-center">
<FormControl_Shadcn_>
<FormControl>
<InputGroup>
<InputGroupAddon align="inline-end">
<InputGroupText>
@@ -209,7 +209,7 @@ export default function PageLayoutSettings() {
</InputGroupAddon>
<InputGroupInput type="number" min={0} {...field} />
</InputGroup>
</FormControl_Shadcn_>
</FormControl>
</div>
</FormItemLayout>
)}
@@ -217,7 +217,7 @@ export default function PageLayoutSettings() {
</CardContent>
<CardContent>
<FormField_Shadcn_
<FormField
control={userSessionsForm.control}
name="SESSIONS_INACTIVITY_TIMEOUT"
render={({ field }) => (
@@ -227,7 +227,7 @@ export default function PageLayoutSettings() {
description="The amount of time a user needs to be inactive to be forced to sign in again. Use 0 for never."
>
<div className="flex items-center">
<FormControl_Shadcn_>
<FormControl>
<InputGroup>
<InputGroupAddon align="inline-end">
<InputGroupText>
@@ -236,7 +236,7 @@ export default function PageLayoutSettings() {
</InputGroupAddon>
<InputGroupInput type="number" {...field} />
</InputGroup>
</FormControl_Shadcn_>
</FormControl>
</div>
</FormItemLayout>
)}
@@ -259,7 +259,7 @@ export default function PageLayoutSettings() {
</CardFooter>
</Card>
</form>
</Form_Shadcn_>
</Form>
</PageSectionContent>
</PageSection>
</PageContainer>
@@ -5,12 +5,12 @@ import { useForm } from 'react-hook-form'
import { toast } from 'sonner'
import {
Button,
Form_Shadcn_,
FormControl_Shadcn_,
FormField_Shadcn_,
FormItem_Shadcn_,
FormLabel_Shadcn_,
FormMessage_Shadcn_,
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
RadioGroupCard,
RadioGroupCardItem,
} from 'ui'
@@ -39,45 +39,45 @@ export default function RadioGroupForm() {
}
return (
<Form_Shadcn_ {...form}>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="w-2/3 space-y-6">
<FormField_Shadcn_
<FormField
control={form.control}
name="type"
render={({ field }) => (
<FormItem_Shadcn_ className="space-y-4">
<FormLabel_Shadcn_>Notify me about...</FormLabel_Shadcn_>
<FormControl_Shadcn_>
<FormItem className="space-y-4">
<FormLabel>Notify me about...</FormLabel>
<FormControl>
<RadioGroupCard
onValueChange={field.onChange}
defaultValue={field.value}
className="flex flex-wrap gap-3"
>
<FormItem_Shadcn_ asChild>
<FormControl_Shadcn_>
<FormItem asChild>
<FormControl>
<RadioGroupCardItem value="all" label="All new messages" />
</FormControl_Shadcn_>
</FormItem_Shadcn_>
<FormItem_Shadcn_ asChild>
<FormControl_Shadcn_>
</FormControl>
</FormItem>
<FormItem asChild>
<FormControl>
<RadioGroupCardItem value="mentions" label="Direct messages and mentions" />
</FormControl_Shadcn_>
</FormItem_Shadcn_>
<FormItem_Shadcn_ asChild>
<FormControl_Shadcn_>
</FormControl>
</FormItem>
<FormItem asChild>
<FormControl>
<RadioGroupCardItem value="none" label="Nothing" />
</FormControl_Shadcn_>
</FormItem_Shadcn_>
</FormControl>
</FormItem>
</RadioGroupCard>
</FormControl_Shadcn_>
<FormMessage_Shadcn_ />
</FormItem_Shadcn_>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<Button htmlType="submit" type="secondary" size="small">
Submit
</Button>
</form>
</Form_Shadcn_>
</Form>
)
}
@@ -1,20 +1,20 @@
import { Label_Shadcn_, RadioGroup_Shadcn_, RadioGroupItem_Shadcn_ } from 'ui'
import { Label_Shadcn_, RadioGroup, RadioGroupItem } from 'ui'
export default function RadioGroupDemo() {
return (
<RadioGroup_Shadcn_ defaultValue="comfortable">
<RadioGroup defaultValue="comfortable">
<div className="flex items-center space-x-2">
<RadioGroupItem_Shadcn_ value="default" id="r1" />
<RadioGroupItem value="default" id="r1" />
<Label_Shadcn_ htmlFor="r1">Default</Label_Shadcn_>
</div>
<div className="flex items-center space-x-2">
<RadioGroupItem_Shadcn_ value="comfortable" id="r2" />
<RadioGroupItem value="comfortable" id="r2" />
<Label_Shadcn_ htmlFor="r2">Comfortable</Label_Shadcn_>
</div>
<div className="flex items-center space-x-2">
<RadioGroupItem_Shadcn_ value="compact" id="r3" />
<RadioGroupItem value="compact" id="r3" />
<Label_Shadcn_ htmlFor="r3">Compact</Label_Shadcn_>
</div>
</RadioGroup_Shadcn_>
</RadioGroup>
)
}
@@ -5,14 +5,14 @@ import { useForm } from 'react-hook-form'
import { toast } from 'sonner'
import {
Button,
Form_Shadcn_,
FormControl_Shadcn_,
FormField_Shadcn_,
FormItem_Shadcn_,
FormLabel_Shadcn_,
FormMessage_Shadcn_,
RadioGroup_Shadcn_,
RadioGroupItem_Shadcn_,
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
RadioGroup,
RadioGroupItem,
} from 'ui'
import { z } from 'zod'
@@ -38,48 +38,46 @@ export default function RadioGroupForm() {
}
return (
<Form_Shadcn_ {...form}>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="w-2/3 space-y-6">
<FormField_Shadcn_
<FormField
control={form.control}
name="type"
render={({ field }) => (
<FormItem_Shadcn_ className="space-y-3">
<FormLabel_Shadcn_>Notify me about...</FormLabel_Shadcn_>
<FormControl_Shadcn_>
<RadioGroup_Shadcn_
<FormItem className="space-y-3">
<FormLabel>Notify me about...</FormLabel>
<FormControl>
<RadioGroup
onValueChange={field.onChange}
defaultValue={field.value}
className="flex flex-col space-y-1"
>
<FormItem_Shadcn_ className="flex items-center space-x-3 space-y-0">
<FormControl_Shadcn_>
<RadioGroupItem_Shadcn_ value="all" />
</FormControl_Shadcn_>
<FormLabel_Shadcn_ className="font-normal">All new messages</FormLabel_Shadcn_>
</FormItem_Shadcn_>
<FormItem_Shadcn_ className="flex items-center space-x-3 space-y-0">
<FormControl_Shadcn_>
<RadioGroupItem_Shadcn_ value="mentions" />
</FormControl_Shadcn_>
<FormLabel_Shadcn_ className="font-normal">
Direct messages and mentions
</FormLabel_Shadcn_>
</FormItem_Shadcn_>
<FormItem_Shadcn_ className="flex items-center space-x-3 space-y-0">
<FormControl_Shadcn_>
<RadioGroupItem_Shadcn_ value="none" />
</FormControl_Shadcn_>
<FormLabel_Shadcn_ className="font-normal">Nothing</FormLabel_Shadcn_>
</FormItem_Shadcn_>
</RadioGroup_Shadcn_>
</FormControl_Shadcn_>
<FormMessage_Shadcn_ />
</FormItem_Shadcn_>
<FormItem className="flex items-center space-x-3 space-y-0">
<FormControl>
<RadioGroupItem value="all" />
</FormControl>
<FormLabel className="font-normal">All new messages</FormLabel>
</FormItem>
<FormItem className="flex items-center space-x-3 space-y-0">
<FormControl>
<RadioGroupItem value="mentions" />
</FormControl>
<FormLabel className="font-normal">Direct messages and mentions</FormLabel>
</FormItem>
<FormItem className="flex items-center space-x-3 space-y-0">
<FormControl>
<RadioGroupItem value="none" />
</FormControl>
<FormLabel className="font-normal">Nothing</FormLabel>
</FormItem>
</RadioGroup>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<Button htmlType="submit">Submit</Button>
</form>
</Form_Shadcn_>
</Form>
)
}
@@ -5,12 +5,12 @@ import { useForm } from 'react-hook-form'
import { toast } from 'sonner'
import {
Button,
Form_Shadcn_,
FormControl_Shadcn_,
FormField_Shadcn_,
FormItem_Shadcn_,
FormLabel_Shadcn_,
FormMessage_Shadcn_,
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
RadioGroupStacked,
RadioGroupStackedItem,
} from 'ui'
@@ -39,44 +39,44 @@ export default function RadioGroupForm() {
}
return (
<Form_Shadcn_ {...form}>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="w-2/3 space-y-6">
<FormField_Shadcn_
<FormField
control={form.control}
name="type"
render={({ field }) => (
<FormItem_Shadcn_ className="space-y-4">
<FormLabel_Shadcn_>Notify me about...</FormLabel_Shadcn_>
<FormControl_Shadcn_>
<FormItem className="space-y-4">
<FormLabel>Notify me about...</FormLabel>
<FormControl>
<RadioGroupStacked onValueChange={field.onChange} defaultValue={field.value}>
<FormItem_Shadcn_ asChild>
<FormControl_Shadcn_>
<FormItem asChild>
<FormControl>
<RadioGroupStackedItem value="all" label="All new messages" />
</FormControl_Shadcn_>
</FormItem_Shadcn_>
<FormItem_Shadcn_ asChild>
<FormControl_Shadcn_>
</FormControl>
</FormItem>
<FormItem asChild>
<FormControl>
<RadioGroupStackedItem
value="mentions"
label="Direct messages and mentions"
/>
</FormControl_Shadcn_>
</FormItem_Shadcn_>
<FormItem_Shadcn_ asChild>
<FormControl_Shadcn_>
</FormControl>
</FormItem>
<FormItem asChild>
<FormControl>
<RadioGroupStackedItem value="none" label="Nothing" />
</FormControl_Shadcn_>
</FormItem_Shadcn_>
</FormControl>
</FormItem>
</RadioGroupStacked>
</FormControl_Shadcn_>
<FormMessage_Shadcn_ />
</FormItem_Shadcn_>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<Button htmlType="submit" type="secondary" size="small">
Submit
</Button>
</form>
</Form_Shadcn_>
</Form>
)
}
@@ -32,7 +32,7 @@ export default function ScrollAreaHorizontalDemo() {
<Image
src={artwork.art}
alt={`Photo by ${artwork.artist}`}
className="aspect-[3/4] h-fit w-fit object-cover"
className="aspect-3/4 h-fit w-fit object-cover"
width={300}
height={400}
/>
@@ -6,13 +6,13 @@ import { useForm } from 'react-hook-form'
import { toast } from 'sonner'
import {
Button,
Form_Shadcn_,
FormControl_Shadcn_,
FormDescription_Shadcn_,
FormField_Shadcn_,
FormItem_Shadcn_,
FormLabel_Shadcn_,
FormMessage_Shadcn_,
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
Select_Shadcn_,
SelectContent_Shadcn_,
SelectItem_Shadcn_,
@@ -45,38 +45,38 @@ export default function SelectForm() {
}
return (
<Form_Shadcn_ {...form}>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="w-2/3 space-y-6">
<FormField_Shadcn_
<FormField
control={form.control}
name="email"
render={({ field }) => (
<FormItem_Shadcn_>
<FormLabel_Shadcn_>Email</FormLabel_Shadcn_>
<FormItem>
<FormLabel>Email</FormLabel>
<Select_Shadcn_ onValueChange={field.onChange} defaultValue={field.value}>
<FormControl_Shadcn_>
<FormControl>
<SelectTrigger_Shadcn_>
<SelectValue_Shadcn_ placeholder="Select a verified email to display" />
</SelectTrigger_Shadcn_>
</FormControl_Shadcn_>
</FormControl>
<SelectContent_Shadcn_>
<SelectItem_Shadcn_ value="m@example.com">m@example.com</SelectItem_Shadcn_>
<SelectItem_Shadcn_ value="m@google.com">m@google.com</SelectItem_Shadcn_>
<SelectItem_Shadcn_ value="m@support.com">m@support.com</SelectItem_Shadcn_>
</SelectContent_Shadcn_>
</Select_Shadcn_>
<FormDescription_Shadcn_>
<FormDescription>
You can manage email addresses in your{' '}
<Link href="/examples/forms">email settings</Link>.
</FormDescription_Shadcn_>
<FormMessage_Shadcn_ />
</FormItem_Shadcn_>
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<Button htmlType="submit" type="secondary">
Submit
</Button>
</form>
</Form_Shadcn_>
</Form>
)
}
@@ -24,7 +24,7 @@ export default function SheetDemo() {
<SheetTitle>Edit profile</SheetTitle>
<SheetDescription>Make changes to your profile here.</SheetDescription>
</SheetHeader>
<div className="overflow-auto flex-grow px-0">
<div className="overflow-auto grow px-0">
<SheetSection>
<div className="grid gap-4 py-4">
<div className="grid grid-cols-4 items-center gap-4">
@@ -20,7 +20,7 @@ export default function SheetNonmodal() {
<SheetHeader>
<SheetTitle>Log details</SheetTitle>
</SheetHeader>
<div className="overflow-auto flex-grow px-0">
<div className="overflow-auto grow px-0">
<SheetSection>
<p className="text-sm text-foreground-lighter">
This sheet does not block the underlying content, but it does overlap it.
@@ -1,6 +1,6 @@
import { zodResolver } from '@hookform/resolvers/zod'
import { useForm } from 'react-hook-form'
import { Button, Form_Shadcn_ } from 'ui'
import { Button, Form } from 'ui'
import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
import { SingleValueFieldArray } from 'ui-patterns/form/SingleValueFieldArray/SingleValueFieldArray'
import { z } from 'zod'
@@ -26,7 +26,7 @@ export default function SingleValueFieldArrayDemo() {
}
return (
<Form_Shadcn_ {...form}>
<Form {...form}>
<form className="w-full max-w-2xl" onSubmit={form.handleSubmit(onSubmit)}>
<FormItemLayout
label="Redirect URIs"
@@ -50,6 +50,6 @@ export default function SingleValueFieldArrayDemo() {
</Button>
</div>
</form>
</Form_Shadcn_>
</Form>
)
}
@@ -5,12 +5,12 @@ import { useForm } from 'react-hook-form'
import { toast } from 'sonner'
import {
Button,
Form_Shadcn_,
FormControl_Shadcn_,
FormDescription_Shadcn_,
FormField_Shadcn_,
FormItem_Shadcn_,
FormLabel_Shadcn_,
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
Switch,
} from 'ui'
import { z } from 'zod'
@@ -39,48 +39,46 @@ export default function SwitchForm() {
}
return (
<Form_Shadcn_ {...form}>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="w-full space-y-6">
<div>
<h3 className="mb-4 text-lg font-medium">Email Notifications</h3>
<div className="space-y-4">
<FormField_Shadcn_
<FormField
control={form.control}
name="marketing_emails"
render={({ field }) => (
<FormItem_Shadcn_ className="flex flex-row items-center justify-between rounded-lg border p-4">
<FormItem className="flex flex-row items-center justify-between rounded-lg border p-4">
<div className="space-y-0.5">
<FormLabel_Shadcn_ className="text-base">Marketing emails</FormLabel_Shadcn_>
<FormDescription_Shadcn_>
<FormLabel className="text-base">Marketing emails</FormLabel>
<FormDescription>
Receive emails about new products, features, and more.
</FormDescription_Shadcn_>
</FormDescription>
</div>
<FormControl_Shadcn_>
<FormControl>
<Switch checked={field.value} onCheckedChange={field.onChange} />
</FormControl_Shadcn_>
</FormItem_Shadcn_>
</FormControl>
</FormItem>
)}
/>
<FormField_Shadcn_
<FormField
control={form.control}
name="security_emails"
render={({ field }) => (
<FormItem_Shadcn_ className="flex flex-row items-center justify-between rounded-lg border p-4">
<FormItem className="flex flex-row items-center justify-between rounded-lg border p-4">
<div className="space-y-0.5">
<FormLabel_Shadcn_ className="text-base">Security emails</FormLabel_Shadcn_>
<FormDescription_Shadcn_>
Receive emails about your account security.
</FormDescription_Shadcn_>
<FormLabel className="text-base">Security emails</FormLabel>
<FormDescription>Receive emails about your account security.</FormDescription>
</div>
<FormControl_Shadcn_>
<FormControl>
<Switch
checked={field.value}
onCheckedChange={field.onChange}
disabled
aria-readonly
/>
</FormControl_Shadcn_>
</FormItem_Shadcn_>
</FormControl>
</FormItem>
)}
/>
</div>
@@ -89,6 +87,6 @@ export default function SwitchForm() {
Submit
</Button>
</form>
</Form_Shadcn_>
</Form>
)
}
@@ -5,13 +5,13 @@ import { useForm } from 'react-hook-form'
import { toast } from 'sonner'
import {
Button,
Form_Shadcn_,
FormControl_Shadcn_,
FormDescription_Shadcn_,
FormField_Shadcn_,
FormItem_Shadcn_,
FormLabel_Shadcn_,
FormMessage_Shadcn_,
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
Textarea,
} from 'ui'
import { z } from 'zod'
@@ -43,32 +43,32 @@ export default function TextareaForm() {
}
return (
<Form_Shadcn_ {...form}>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="w-2/3 space-y-6">
<FormField_Shadcn_
<FormField
control={form.control}
name="bio"
render={({ field }) => (
<FormItem_Shadcn_>
<FormLabel_Shadcn_>Bio</FormLabel_Shadcn_>
<FormControl_Shadcn_>
<FormItem>
<FormLabel>Bio</FormLabel>
<FormControl>
<Textarea
placeholder="Tell us a little bit about yourself"
className="resize-none"
{...field}
/>
</FormControl_Shadcn_>
<FormDescription_Shadcn_>
</FormControl>
<FormDescription>
You can <span>@mention</span> other users and organizations.
</FormDescription_Shadcn_>
<FormMessage_Shadcn_ />
</FormItem_Shadcn_>
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<Button htmlType="submit" type="alternative">
Submit
</Button>
</form>
</Form_Shadcn_>
</Form>
)
}
@@ -149,7 +149,7 @@ const TocComponent = () => {
<h3 className="inline-flex items-center gap-1.5 font-mono text-xs uppercase text-foreground pl-[calc(1.5rem+6px)]">
On this page
</h3>
<TOCScrollArea className="-ml-[2px]">
<TOCScrollArea className="ml-[-2px]">
<TOCItems items={toc} />
</TOCScrollArea>
</Toc>
@@ -149,7 +149,7 @@ const TocComponent = () => {
<h3 className="inline-flex items-center gap-1.5 font-mono text-xs uppercase text-foreground pl-[calc(1.5rem+6px)]">
On this page
</h3>
<TOCScrollArea className="-ml-[2px]">
<TOCScrollArea className="ml-[-2px]">
<TOCItems items={toc} />
</TOCScrollArea>
</Toc>
@@ -4,7 +4,7 @@ export default function TypographyDemo() {
<h1 className="scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl">
The Joke Tax Chronicles
</h1>
<p className="leading-7 [&:not(:first-child)]:mt-6">
<p className="leading-7 not-first:mt-6">
Once upon a time, in a far-off land, there was a very lazy king who spent all day lounging
on his throne. One day, his advisors came to him with a problem: the kingdom was running out
of money.
@@ -12,7 +12,7 @@ export default function TypographyDemo() {
<h2 className="mt-10 scroll-m-20 border-b pb-2 text-3xl font-semibold tracking-tight transition-colors first:mt-0">
The King&apos;s Plan
</h2>
<p className="leading-7 [&:not(:first-child)]:mt-6">
<p className="leading-7 not-first:mt-6">
The king thought long and hard, and finally came up with{' '}
<a href="#" className="font-medium text-primary underline underline-offset-4">
a brilliant plan
@@ -24,7 +24,7 @@ export default function TypographyDemo() {
that they should pay for the privilege.&quot;
</blockquote>
<h3 className="mt-8 scroll-m-20 text-2xl font-semibold tracking-tight">The Joke Tax</h3>
<p className="leading-7 [&:not(:first-child)]:mt-6">
<p className="leading-7 not-first:mt-6">
The king&apos;s subjects were not amused. They grumbled and complained, but the king was
firm:
</p>
@@ -33,7 +33,7 @@ export default function TypographyDemo() {
<li>2nd level of jokes: 10 gold coins</li>
<li>3rd level of one-liners : 20 gold coins</li>
</ul>
<p className="leading-7 [&:not(:first-child)]:mt-6">
<p className="leading-7 not-first:mt-6">
As a result, people stopped telling jokes, and the kingdom fell into a gloom. But there was
one person who refused to let the king&apos;s foolishness get him down: a court jester named
Jokester.
@@ -41,12 +41,12 @@ export default function TypographyDemo() {
<h3 className="mt-8 scroll-m-20 text-2xl font-semibold tracking-tight">
Jokester&apos;s Revolt
</h3>
<p className="leading-7 [&:not(:first-child)]:mt-6">
<p className="leading-7 not-first:mt-6">
Jokester began sneaking into the castle in the middle of the night and leaving jokes all
over the place: under the king&apos;s pillow, in his soup, even in the royal toilet. The
king was furious, but he couldn&apos;t seem to stop Jokester.
</p>
<p className="leading-7 [&:not(:first-child)]:mt-6">
<p className="leading-7 not-first:mt-6">
And then, one day, the people of the kingdom discovered that the jokes left by Jokester were
so funny that they couldn&apos;t help but laugh. And once they started laughing, they
couldn&apos;t stop.
@@ -54,7 +54,7 @@ export default function TypographyDemo() {
<h3 className="mt-8 scroll-m-20 text-2xl font-semibold tracking-tight">
The People&apos;s Rebellion
</h3>
<p className="leading-7 [&:not(:first-child)]:mt-6">
<p className="leading-7 not-first:mt-6">
The people of the kingdom, feeling uplifted by the laughter, started to tell jokes and puns
again, and soon the entire kingdom was in on the joke.
</p>
@@ -62,48 +62,48 @@ export default function TypographyDemo() {
<table className="w-full">
<thead>
<tr className="m-0 border-t p-0 even:bg-muted">
<th className="border px-4 py-2 text-left font-bold [&[align=center]]:text-center [&[align=right]]:text-right">
<th className="border px-4 py-2 text-left font-bold [[align=center]]:text-center [[align=right]]:text-right">
King&apos;s Treasury
</th>
<th className="border px-4 py-2 text-left font-bold [&[align=center]]:text-center [&[align=right]]:text-right">
<th className="border px-4 py-2 text-left font-bold [[align=center]]:text-center [[align=right]]:text-right">
People&apos;s happiness
</th>
</tr>
</thead>
<tbody>
<tr className="m-0 border-t p-0 even:bg-muted">
<td className="border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right">
<td className="border px-4 py-2 text-left [[align=center]]:text-center [[align=right]]:text-right">
Empty
</td>
<td className="border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right">
<td className="border px-4 py-2 text-left [[align=center]]:text-center [[align=right]]:text-right">
Overflowing
</td>
</tr>
<tr className="m-0 border-t p-0 even:bg-muted">
<td className="border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right">
<td className="border px-4 py-2 text-left [[align=center]]:text-center [[align=right]]:text-right">
Modest
</td>
<td className="border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right">
<td className="border px-4 py-2 text-left [[align=center]]:text-center [[align=right]]:text-right">
Satisfied
</td>
</tr>
<tr className="m-0 border-t p-0 even:bg-muted">
<td className="border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right">
<td className="border px-4 py-2 text-left [[align=center]]:text-center [[align=right]]:text-right">
Full
</td>
<td className="border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right">
<td className="border px-4 py-2 text-left [[align=center]]:text-center [[align=right]]:text-right">
Ecstatic
</td>
</tr>
</tbody>
</table>
</div>
<p className="leading-7 [&:not(:first-child)]:mt-6">
<p className="leading-7 not-first:mt-6">
The king, seeing how much happier his subjects were, realized the error of his ways and
repealed the joke tax. Jokester was declared a hero, and the kingdom lived happily ever
after.
</p>
<p className="leading-7 [&:not(:first-child)]:mt-6">
<p className="leading-7 not-first:mt-6">
The moral of the story is: never underestimate the power of a good laugh and always be
careful of bad ideas.
</p>
@@ -1,6 +1,6 @@
export default function TypographyInlineCode() {
return (
<code className="relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm font-semibold">
<code className="relative rounded-sm bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm font-semibold">
@radix-ui/react-alert-dialog
</code>
)
@@ -1,6 +1,6 @@
export default function TypographyP() {
return (
<p className="leading-7 [&:not(:first-child)]:mt-6">
<p className="leading-7 not-first:mt-6">
The king, seeing how much happier his subjects were, realized the error of his ways and
repealed the joke tax.
</p>
@@ -4,36 +4,36 @@ export default function TypographyTable() {
<table className="w-full">
<thead>
<tr className="m-0 border-t p-0 even:bg-muted">
<th className="border px-4 py-2 text-left font-bold [&[align=center]]:text-center [&[align=right]]:text-right">
<th className="border px-4 py-2 text-left font-bold [[align=center]]:text-center [[align=right]]:text-right">
King&apos;s Treasury
</th>
<th className="border px-4 py-2 text-left font-bold [&[align=center]]:text-center [&[align=right]]:text-right">
<th className="border px-4 py-2 text-left font-bold [[align=center]]:text-center [[align=right]]:text-right">
People&apos;s happiness
</th>
</tr>
</thead>
<tbody>
<tr className="m-0 border-t p-0 even:bg-muted">
<td className="border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right">
<td className="border px-4 py-2 text-left [[align=center]]:text-center [[align=right]]:text-right">
Empty
</td>
<td className="border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right">
<td className="border px-4 py-2 text-left [[align=center]]:text-center [[align=right]]:text-right">
Overflowing
</td>
</tr>
<tr className="m-0 border-t p-0 even:bg-muted">
<td className="border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right">
<td className="border px-4 py-2 text-left [[align=center]]:text-center [[align=right]]:text-right">
Modest
</td>
<td className="border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right">
<td className="border px-4 py-2 text-left [[align=center]]:text-center [[align=right]]:text-right">
Satisfied
</td>
</tr>
<tr className="m-0 border-t p-0 even:bg-muted">
<td className="border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right">
<td className="border px-4 py-2 text-left [[align=center]]:text-center [[align=right]]:text-right">
Full
</td>
<td className="border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right">
<td className="border px-4 py-2 text-left [[align=center]]:text-center [[align=right]]:text-right">
Ecstatic
</td>
</tr>
+5
View File
@@ -1418,6 +1418,11 @@ export const examples: Registry = [
type: 'components:example',
files: ['example/multi-select-inline-search-input.tsx'],
},
{
name: 'multi-select-in-dialog',
type: 'components:example',
files: ['example/multi-select-in-dialog.tsx'],
},
{
name: 'tree-view-demo',
type: 'components:example',
@@ -1,7 +1,5 @@
[data-theme='dark'],
[data-theme='deep-dark'],
.dark,
.deep-dark {
.dark {
--code-token-keyword: #bda4ff;
--code-foreground: #ffffff;
--code-token-constant: #3ecf8e;
+18 -7
View File
@@ -1,11 +1,18 @@
@import './../../../packages/ui/build/css/source/global.css';
@import './../../../packages/ui/build/css/themes/dark.css';
@import 'config/tailwind.config.css';
@import './../../../packages/ui/build/css/themes/classic-dark.css';
@import './../../../packages/ui/build/css/themes/light.css';
@import 'config/typography.css';
@tailwind base;
@tailwind components;
@tailwind utilities;
@source '../app/**/*.{js,ts,jsx,tsx}';
@source '../components/**/*.{js,ts,jsx,tsx}';
@source '../registry/**/*.{js,ts,jsx,tsx}';
@source '../content/**/*.mdx';
@source './../../../packages/ui/src/**/*.{tsx,ts,js}';
@source './../../../packages/ui-patterns/src/**/*.{tsx,ts,js}';
@theme {
/* added to get max-w-site */
--container-site: 128rem;
}
@layer base {
:root {
@@ -33,7 +40,7 @@
@apply scroll-smooth;
}
body {
@apply bg text-foreground;
@apply bg-default text-foreground;
/* font-feature-settings: "rlig" 1, "calt" 1; */
font-synthesis-weight: none;
text-rendering: optimizeLegibility;
@@ -68,3 +75,7 @@
@apply px-4;
}
}
.rdg-cell {
padding-inline: 0.5rem;
}
+2
View File
@@ -1,3 +1,5 @@
@reference './globals.css';
/* [data-theme="light"] {
display: block;
} */
Loaded 100 of 2811 files, more files were not shown because too many files have changed in this diff. Show more