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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/gold-snails-care.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@clerk/clerk-react': patch
---

[Experimental] Fix issue with property access for state proxy
3 changes: 2 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,8 @@ jobs:
'nuxt',
'react-router',
'billing',
'machine'
'machine',
'custom',
]
Comment on lines +296 to 298
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Ensure turbo task and script exist for the new matrix target.

Verify turbo has a matching task (test:integration:custom) and the script is present (it is in package.json).


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Check package script:"
rg -n "^\\s*\"test:integration:custom\"\\s*:" package.json -C1

echo "Locate turbo config:"
fd -a -HI '^turbo\\.(json|jsonc)$'

echo "Check turbo task definition:"
for f in $(fd -a -HI '^turbo\\.(json|jsonc)$'); do
  echo "--- $f"
  rg -n "\"test:integration:custom\"" "$f" -C3 || true
done

Length of output: 637


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Search for turbo.json or turbo.jsonc:"
fd -HI 'turbo.json' 'turbo.jsonc' || true

echo "List any other turbo.* config files:"
fd -HI 'turbo.config.*' || true

echo "Search for turbo configuration in package.json:"
rg -n '"turbo"' -C3 package.json || true

Length of output: 717


Add test:integration:custom to Turbo pipeline config
The script exists in package.json (line 38), but no Turbo config file (turbo.json, turbo.jsonc, or turbo.config.*) defines this task—add it under your pipeline tasks so the new matrix target runs.

🤖 Prompt for AI Agents
In .github/workflows/ci.yml around lines 296 to 298, the Turbo pipeline lacks a
task entry for "test:integration:custom" which prevents the new matrix target
from running; add a "test:integration:custom" entry to your Turbo config
(turbo.json / turbo.jsonc / turbo.config.*) under the pipeline tasks, mirroring
the existing integration-test task settings (e.g., command, dependsOn, outputs,
cache behavior) so the CI matrix target is picked up and runs like the other
integration test tasks.

⚠️ Potential issue

Remove trailing comma to avoid YAML parse issues.

The flow-style array can choke on a trailing comma in some parsers.

-            'custom',
+            'custom'
🤖 Prompt for AI Agents
In .github/workflows/ci.yml around lines 296 to 298 the flow-style array ends
with a trailing comma after 'custom' which can cause YAML parsers to fail;
remove the comma after 'custom' so the array reads ['machine', 'custom'] (i.e.,
delete the trailing comma and ensure closing bracket aligns with YAML
indentation).

test-project: ['chrome']
include:
Expand Down
19 changes: 19 additions & 0 deletions integration/presets/custom-flows.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { constants } from '../constants';
import { applicationConfig } from '../models/applicationConfig';
import { templates } from '../templates';
import { linkPackage } from './utils';

const reactVite = applicationConfig()
.setName('custom-flows-react-vite')
.useTemplate(templates['custom-flows-react-vite'])
.setEnvFormatter('public', key => `VITE_${key}`)
.addScript('setup', 'pnpm install')
.addScript('dev', 'pnpm dev')
.addScript('build', 'pnpm build')
.addScript('serve', 'pnpm preview')
.addDependency('@clerk/clerk-react', constants.E2E_CLERK_VERSION || linkPackage('react'))
.addDependency('@clerk/themes', constants.E2E_CLERK_VERSION || linkPackage('themes'));
Comment on lines +6 to +15

This comment was marked as off-topic.


export const customFlows = {
reactVite,
} as const;
2 changes: 2 additions & 0 deletions integration/presets/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { astro } from './astro';
import { customFlows } from './custom-flows';
import { elements } from './elements';
import { envs, instanceKeys } from './envs';
import { expo } from './expo';
Expand All @@ -12,6 +13,7 @@ import { tanstack } from './tanstack';
import { vue } from './vue';

export const appConfigs = {
customFlows,
envs,
express,
longRunningApps: createLongRunningApps(),
Expand Down
24 changes: 24 additions & 0 deletions integration/templates/custom-flows-react-vite/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
Comment on lines +10 to +16

This comment was marked as off-topic.

!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
21 changes: 21 additions & 0 deletions integration/templates/custom-flows-react-vite/components.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": false,
"tsx": true,
"tailwind": {
"config": "",

This comment was marked as off-topic.

"css": "src/index.css",
"baseColor": "neutral",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
},
"iconLibrary": "lucide"
}
23 changes: 23 additions & 0 deletions integration/templates/custom-flows-react-vite/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import js from '@eslint/js';
import globals from 'globals';
import reactHooks from 'eslint-plugin-react-hooks';
import reactRefresh from 'eslint-plugin-react-refresh';
import tseslint from 'typescript-eslint';
import { globalIgnores } from 'eslint/config';

export default tseslint.config([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
js.configs.recommended,
tseslint.configs.recommended,
reactHooks.configs['recommended-latest'],
reactRefresh.configs.vite,
],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
},
},
]);
13 changes: 13 additions & 0 deletions integration/templates/custom-flows-react-vite/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React + TS</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
40 changes: 40 additions & 0 deletions integration/templates/custom-flows-react-vite/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"name": "hooks-revamp-vite-react",
"version": "0.0.0",
"private": true,
"type": "module",
"scripts": {
"build": "tsc -b && vite build",
"dev": "vite --port $PORT --no-open",
"lint": "eslint .",
"preview": "vite preview"
},
"dependencies": {
"@radix-ui/react-label": "^2.1.7",
"@radix-ui/react-slot": "^1.2.3",
"@tailwindcss/vite": "^4.1.11",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"lucide-react": "^0.539.0",
"react": "^19.1.1",
"react-dom": "^19.1.1",
"react-router": "^7.8.1",
"tailwind-merge": "^3.3.1",
"tailwindcss": "^4.1.11"
},
"devDependencies": {
"@eslint/js": "^9.30.1",
"@types/node": "^24.2.1",
"@types/react": "^19.1.8",
"@types/react-dom": "^19.1.6",
"@vitejs/plugin-react": "^4.6.0",
"eslint": "^9.30.1",
"eslint-plugin-react-hooks": "^5.2.0",
"eslint-plugin-react-refresh": "^0.4.20",
"globals": "^16.3.0",
"tw-animate-css": "^1.3.6",
"typescript": "~5.8.3",
"typescript-eslint": "^8.35.1",
"vite": "^7.0.4"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import * as React from 'react';
import { Slot } from '@radix-ui/react-slot';
import { cva, type VariantProps } from 'class-variance-authority';

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

const buttonVariants = cva(
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
{
variants: {
variant: {
default: 'bg-primary text-primary-foreground shadow-xs hover:bg-primary/90',
destructive:
'bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60',
outline:
'border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50',
secondary: 'bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80',
ghost: 'hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50',
link: 'text-primary underline-offset-4 hover:underline',
},
size: {
default: 'h-9 px-4 py-2 has-[>svg]:px-3',
sm: 'h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5',
lg: 'h-10 rounded-md px-6 has-[>svg]:px-4',
icon: 'size-9',
},
},
defaultVariants: {
variant: 'default',
size: 'default',
},
},
);

function Button({
className,
variant,
size,
asChild = false,
...props
}: React.ComponentProps<'button'> &
VariantProps<typeof buttonVariants> & {
asChild?: boolean;
}) {
const Comp = asChild ? Slot : 'button';

return (
<Comp
data-slot='button'
className={cn(buttonVariants({ variant, size, className }))}
{...props}
/>
);
}

export { Button, buttonVariants };
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import * as React from 'react';

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

function Card({ className, ...props }: React.ComponentProps<'div'>) {
return (
<div
data-slot='card'
className={cn('bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm', className)}
{...props}
/>
);
}

function CardHeader({ className, ...props }: React.ComponentProps<'div'>) {
return (
<div
data-slot='card-header'
className={cn(
'@container/card-header has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6 grid auto-rows-min grid-rows-[auto_auto] items-start gap-1.5 px-6',
className,
)}
{...props}
/>
);
}

function CardTitle({ className, ...props }: React.ComponentProps<'div'>) {
return (
<div
data-slot='card-title'
className={cn('font-semibold leading-none', className)}
{...props}
/>
);
}

function CardDescription({ className, ...props }: React.ComponentProps<'div'>) {
return (
<div
data-slot='card-description'
className={cn('text-muted-foreground text-sm', className)}
{...props}
/>
);
}

function CardAction({ className, ...props }: React.ComponentProps<'div'>) {
return (
<div
data-slot='card-action'
className={cn('col-start-2 row-span-2 row-start-1 self-start justify-self-end', className)}
{...props}
/>
);
}

function CardContent({ className, ...props }: React.ComponentProps<'div'>) {
return (
<div
data-slot='card-content'
className={cn('px-6', className)}
{...props}
/>
);
}

function CardFooter({ className, ...props }: React.ComponentProps<'div'>) {
return (
<div
data-slot='card-footer'
className={cn('[.border-t]:pt-6 flex items-center px-6', className)}
{...props}
/>
);
}

export { Card, CardHeader, CardFooter, CardTitle, CardAction, CardDescription, CardContent };
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import * as React from 'react';

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

function Input({ className, type, ...props }: React.ComponentProps<'input'>) {
return (
<input
type={type}
data-slot='input'
className={cn(
'file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input shadow-xs flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base outline-none transition-[color,box-shadow] file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',
'focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]',
'aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive',
className,
)}
{...props}
/>
);
}

export { Input };
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import * as React from 'react';
import * as LabelPrimitive from '@radix-ui/react-label';

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

function Label({ className, ...props }: React.ComponentProps<typeof LabelPrimitive.Root>) {
return (
<LabelPrimitive.Root
data-slot='label'
className={cn(
'flex select-none items-center gap-2 text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-50 group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50',
className,
)}
{...props}
/>
);
}

export { Label };
Loading
Loading