diff --git a/.changeset/wild-phones-give.md b/.changeset/wild-phones-give.md new file mode 100644 index 0000000000..7c897a5d1e --- /dev/null +++ b/.changeset/wild-phones-give.md @@ -0,0 +1,7 @@ +--- +"shadcn": minor +--- + +add --pointer option to cli. + +npx shadcn init --pointer will enable cursor: pointer on buttons. diff --git a/apps/v4/app/(app)/create/components/design-system-provider.tsx b/apps/v4/app/(app)/create/components/design-system-provider.tsx index e7b2f22663..98374e1a27 100644 --- a/apps/v4/app/(app)/create/components/design-system-provider.tsx +++ b/apps/v4/app/(app)/create/components/design-system-provider.tsx @@ -5,6 +5,7 @@ import * as React from "react" import { buildRegistryTheme, DEFAULT_CONFIG, + POINTER_CURSOR_SELECTOR, type DesignSystemConfig, } from "@/registry/config" import { useIframeMessageListener } from "@/app/(app)/create/hooks/use-iframe-sync" @@ -16,6 +17,12 @@ import { const THEME_STYLE_ELEMENT_ID = "design-system-theme-vars" const MANAGED_BODY_CLASS_PREFIXES = ["style-", "base-color-"] as const +const POINTER_CURSOR_CSS = `@layer base { + ${POINTER_CURSOR_SELECTOR} { + cursor: pointer; + } +} +` type RegistryThemeCssVars = NonNullable< ReturnType["cssVars"] @@ -44,14 +51,17 @@ function buildCssRule(selector: string, cssVars?: Record) { return `${selector} {\n${declarations}\n}\n` } -function buildThemeCssText(cssVars: RegistryThemeCssVars) { +function buildThemeCssText(cssVars: RegistryThemeCssVars, pointer: boolean) { return [ buildCssRule(":root", { ...(cssVars.theme ?? {}), ...(cssVars.light ?? {}), }), buildCssRule(".dark", cssVars.dark), - ].join("\n") + pointer ? POINTER_CURSOR_CSS : "", + ] + .filter(Boolean) + .join("\n") } export function DesignSystemProvider({ @@ -73,6 +83,7 @@ export function DesignSystemProvider({ chartColor, menuAccent, menuColor, + pointer, radius, } = searchParams const effectiveRadius = style === "lyra" ? "none" : radius @@ -208,8 +219,8 @@ export function DesignSystemProvider({ document.head.appendChild(styleElement) } - styleElement.textContent = buildThemeCssText(registryTheme.cssVars) - }, [registryTheme]) + styleElement.textContent = buildThemeCssText(registryTheme.cssVars, pointer) + }, [registryTheme, pointer]) // Handle menu color inversion by adding/removing dark class to elements with cn-menu-target. // useLayoutEffect to apply classes synchronously before paint, avoiding flash. diff --git a/apps/v4/app/(app)/create/components/project-form.tsx b/apps/v4/app/(app)/create/components/project-form.tsx index 5d900ae107..18a5328714 100644 --- a/apps/v4/app/(app)/create/components/project-form.tsx +++ b/apps/v4/app/(app)/create/components/project-form.tsx @@ -1,7 +1,12 @@ "use client" import * as React from "react" -import { Copy01Icon, Globe02Icon, Tick02Icon } from "@hugeicons/core-free-icons" +import { + Copy01Icon, + Globe02Icon, + HandPointingRight04Icon, + Tick02Icon, +} from "@hugeicons/core-free-icons" import { HugeiconsIcon } from "@hugeicons/react" import { cn } from "@/lib/utils" @@ -85,7 +90,8 @@ export function ProjectForm({ const templateFlag = ` --template ${framework}` const monorepoFlag = isMonorepo ? " --monorepo" : "" const rtlFlag = params.rtl ? " --rtl" : "" - const flags = `${presetFlag}${baseFlag}${templateFlag}${monorepoFlag}${rtlFlag}` + const pointerFlag = params.pointer ? " --pointer" : "" + const flags = `${presetFlag}${baseFlag}${templateFlag}${monorepoFlag}${rtlFlag}${pointerFlag}` return IS_LOCAL_DEV ? { @@ -100,7 +106,14 @@ export function ProjectForm({ yarn: `yarn dlx shadcn${SHADCN_VERSION} init${flags}`, bun: `bunx --bun shadcn${SHADCN_VERSION} init${flags}`, } - }, [framework, isMonorepo, params.base, params.rtl, presetCode]) + }, [ + framework, + isMonorepo, + params.base, + params.pointer, + params.rtl, + presetCode, + ]) const command = commands[packageManager] @@ -154,6 +167,23 @@ export function ProjectForm({ Options + + + + Use pointer on buttons + + + setParams({ pointer: checked === true }) + } + /> + + { const origin = process.env.NEXT_PUBLIC_APP_URL || "http://localhost:3000" - return `${origin}/create?preset=${presetCode}&item=${params.item}` - }, [presetCode, params.item]) + const searchParams = new URLSearchParams({ + preset: presetCode, + item: params.item, + }) + + if (params.pointer) { + searchParams.set("pointer", "true") + } + + return `${origin}/create?${searchParams.toString()}` + }, [params.item, params.pointer, presetCode]) React.useEffect(() => { if (hasCopied) { diff --git a/apps/v4/app/(app)/create/lib/search-params.ts b/apps/v4/app/(app)/create/lib/search-params.ts index 4cacd6f935..e2a16a5226 100644 --- a/apps/v4/app/(app)/create/lib/search-params.ts +++ b/apps/v4/app/(app)/create/lib/search-params.ts @@ -91,6 +91,7 @@ const designSystemSearchParams = { "laravel", ] as const).withDefault("next"), rtl: parseAsBoolean.withDefault(false), + pointer: parseAsBoolean.withDefault(false), size: parseAsInteger.withDefault(100), custom: parseAsBoolean.withDefault(false), } @@ -126,6 +127,7 @@ const NON_DESIGN_SYSTEM_KEYS = [ "preset", "template", "rtl", + "pointer", "size", "custom", ] as const @@ -224,6 +226,7 @@ function resolvePresetParams( preset: rawParams.preset, template: rawParams.template, rtl: rawParams.rtl, + pointer: rawParams.pointer, size: rawParams.size, custom: rawParams.custom, }) diff --git a/apps/v4/app/(app)/docs/changelog/page.tsx b/apps/v4/app/(app)/docs/changelog/page.tsx index 4b5f26b716..3f7d37963e 100644 --- a/apps/v4/app/(app)/docs/changelog/page.tsx +++ b/apps/v4/app/(app)/docs/changelog/page.tsx @@ -10,7 +10,7 @@ import { Button } from "@/styles/radix-nova/ui/button" export const revalidate = false export const dynamic = "force-static" -const NUMBER_OF_LATEST_PAGES = 2 +const NUMBER_OF_LATEST_PAGES = 5 export function generateMetadata() { return { diff --git a/apps/v4/app/(create)/init/parse-config.test.ts b/apps/v4/app/(create)/init/parse-config.test.ts index 01a7051c6e..5be62f7f9c 100644 --- a/apps/v4/app/(create)/init/parse-config.test.ts +++ b/apps/v4/app/(create)/init/parse-config.test.ts @@ -3,6 +3,36 @@ import { describe, expect, it } from "vitest" import { parseDesignSystemConfig } from "./parse-config" describe("parseDesignSystemConfig", () => { + it("defaults pointer to false when omitted", () => { + const result = parseDesignSystemConfig( + new URLSearchParams( + "base=base&style=sera&baseColor=taupe&theme=taupe&iconLibrary=lucide&font=noto-sans&rtl=false&menuAccent=subtle&menuColor=default&radius=default&fontHeading=playfair-display&template=vite&track=1" + ) + ) + + expect(result.success).toBe(true) + if (!result.success) { + throw new Error(result.error) + } + + expect(result.data.pointer).toBe(false) + }) + + it("parses pointer=true", () => { + const result = parseDesignSystemConfig( + new URLSearchParams( + "base=base&style=sera&baseColor=taupe&theme=taupe&iconLibrary=lucide&font=noto-sans&rtl=false&pointer=true&menuAccent=subtle&menuColor=default&radius=default&fontHeading=playfair-display&template=vite&track=1" + ) + ) + + expect(result.success).toBe(true) + if (!result.success) { + throw new Error(result.error) + } + + expect(result.data.pointer).toBe(true) + }) + it("defaults missing chartColor from the selected theme", () => { const result = parseDesignSystemConfig( new URLSearchParams( @@ -33,4 +63,17 @@ describe("parseDesignSystemConfig", () => { expect(result.data.fontHeading).toBe("playfair-display") expect(result.data.chartColor).toBe("emerald") }) + + it("keeps pointer outside preset decoding", () => { + const result = parseDesignSystemConfig( + new URLSearchParams("preset=a0&pointer=true") + ) + + expect(result.success).toBe(true) + if (!result.success) { + throw new Error(result.error) + } + + expect(result.data.pointer).toBe(true) + }) }) diff --git a/apps/v4/app/(create)/init/parse-config.ts b/apps/v4/app/(create)/init/parse-config.ts index 5fdaa0c62e..88386b3222 100644 --- a/apps/v4/app/(create)/init/parse-config.ts +++ b/apps/v4/app/(create)/init/parse-config.ts @@ -23,6 +23,7 @@ export function parseDesignSystemConfig(searchParams: URLSearchParams) { base: searchParams.get("base") ?? "radix", template: searchParams.get("template") ?? undefined, rtl: searchParams.get("rtl") === "true", + pointer: searchParams.get("pointer") === "true", } } else { configInput = { @@ -39,6 +40,7 @@ export function parseDesignSystemConfig(searchParams: URLSearchParams) { radius: searchParams.get("radius"), template: searchParams.get("template") ?? undefined, rtl: searchParams.get("rtl") === "true", + pointer: searchParams.get("pointer") === "true", } } diff --git a/apps/v4/app/(create)/init/route.test.ts b/apps/v4/app/(create)/init/route.test.ts index efd76e62b1..0e04458726 100644 --- a/apps/v4/app/(create)/init/route.test.ts +++ b/apps/v4/app/(create)/init/route.test.ts @@ -1,6 +1,10 @@ import { describe, expect, it } from "vitest" -import { buildRegistryBase, DEFAULT_CONFIG } from "@/registry/config" +import { + buildRegistryBase, + DEFAULT_CONFIG, + POINTER_CURSOR_SELECTOR, +} from "@/registry/config" import { GET } from "./route" @@ -26,6 +30,17 @@ describe("GET /init", () => { expect(response.status).toBe(200) expect(json).toEqual(buildRegistryBase(DEFAULT_CONFIG)) + expect(json.css["@layer base"][POINTER_CURSOR_SELECTOR]).toBeUndefined() + }) + + it("returns pointer cursor css when pointer is enabled", async () => { + const response = await GET(createRequest("?pointer=true")) + const json = await response.json() + + expect(response.status).toBe(200) + expect(json.css["@layer base"][POINTER_CURSOR_SELECTOR]).toEqual({ + cursor: "pointer", + }) }) it("returns a sparse registry base when only is provided", async () => { diff --git a/apps/v4/content/docs/(root)/cli.mdx b/apps/v4/content/docs/(root)/cli.mdx index 43879a1603..86f283249e 100644 --- a/apps/v4/content/docs/(root)/cli.mdx +++ b/apps/v4/content/docs/(root)/cli.mdx @@ -39,6 +39,8 @@ Options: --no-monorepo skip the monorepo prompt. --rtl enable RTL support. --no-rtl disable RTL support. + --pointer enable pointer cursor for buttons. + --no-pointer disable pointer cursor for buttons. --reinstall re-install existing UI components. --no-reinstall do not re-install existing UI components. -h, --help display help for command diff --git a/apps/v4/content/docs/changelog/2026-04-pointer-cursor.mdx b/apps/v4/content/docs/changelog/2026-04-pointer-cursor.mdx new file mode 100644 index 0000000000..65ad7c9f75 --- /dev/null +++ b/apps/v4/content/docs/changelog/2026-04-pointer-cursor.mdx @@ -0,0 +1,24 @@ +--- +title: April 2026 - Pointer Cursor +description: Add cursor pointer behavior for buttons during project setup. +date: 2026-04-25 +--- + +You can now enable `cursor: pointer` for buttons when initializing a project. + +```bash +npx shadcn@latest init --pointer +``` + +This adds the following CSS to your global CSS file: + +```css title="globals.css" +@layer base { + button:not(:disabled), + [role="button"]:not(:disabled) { + cursor: pointer; + } +} +``` + +The `--pointer` option is not part of preset codes. It is applied as a project setup option, similar to `--rtl`. diff --git a/apps/v4/content/docs/components/base/button.mdx b/apps/v4/content/docs/components/base/button.mdx index fa2d83dcda..7b1779dc78 100644 --- a/apps/v4/content/docs/components/base/button.mdx +++ b/apps/v4/content/docs/components/base/button.mdx @@ -66,6 +66,8 @@ Tailwind v4 [switched](https://tailwindcss.com/docs/upgrade-guide#buttons-use-th If you want to keep the `cursor: pointer` behavior, add the following code to your CSS file: +You can also enable this during project setup with `npx shadcn@latest init --pointer`. + ```css showLineNumbers title="globals.css" @layer base { button:not(:disabled), diff --git a/apps/v4/content/docs/components/radix/button.mdx b/apps/v4/content/docs/components/radix/button.mdx index 263526b364..c9cb24965f 100644 --- a/apps/v4/content/docs/components/radix/button.mdx +++ b/apps/v4/content/docs/components/radix/button.mdx @@ -66,6 +66,8 @@ Tailwind v4 [switched](https://tailwindcss.com/docs/upgrade-guide#buttons-use-th If you want to keep the `cursor: pointer` behavior, add the following code to your CSS file: +You can also enable this during project setup with `npx shadcn@latest init --pointer`. + ```css showLineNumbers title="globals.css" @layer base { button:not(:disabled), diff --git a/apps/v4/registry/config.test.ts b/apps/v4/registry/config.test.ts index 6f4b1d13fb..6657a2e274 100644 --- a/apps/v4/registry/config.test.ts +++ b/apps/v4/registry/config.test.ts @@ -7,6 +7,7 @@ import { DEFAULT_CONFIG, designSystemConfigSchema, parseRegistryBaseParts, + POINTER_CURSOR_SELECTOR, PRESETS, } from "./config" @@ -71,6 +72,41 @@ describe("buildRegistryBase", () => { expect(result.chartColor).toBe("neutral") }) + it("defaults pointer to false when omitted", () => { + const result = designSystemConfigSchema.parse({ + base: "radix", + style: "nova", + iconLibrary: "lucide", + theme: "neutral", + font: "inter", + fontHeading: "inherit", + menuAccent: "subtle", + menuColor: "default", + radius: "default", + }) + + expect(result.pointer).toBe(false) + }) + + it("does not include pointer cursor css by default", () => { + const result = buildRegistryBase(DEFAULT_CONFIG) + + expect( + result.css?.["@layer base"]?.[POINTER_CURSOR_SELECTOR] + ).toBeUndefined() + }) + + it("includes pointer cursor css when pointer is enabled", () => { + const result = buildRegistryBase({ + ...DEFAULT_CONFIG, + pointer: true, + }) + + expect(result.css?.["@layer base"]?.[POINTER_CURSOR_SELECTOR]).toEqual({ + cursor: "pointer", + }) + }) + it("defaults chartColor to the selected theme when omitted", () => { const result = designSystemConfigSchema.parse({ base: "base", diff --git a/apps/v4/registry/config.ts b/apps/v4/registry/config.ts index b230806fcd..15077630a3 100644 --- a/apps/v4/registry/config.ts +++ b/apps/v4/registry/config.ts @@ -28,6 +28,8 @@ export type BaseColorName = BaseColor["name"] export type ChartColorName = Theme["name"] export const REGISTRY_BASE_PARTS = ["theme", "font"] as const export type RegistryBasePart = (typeof REGISTRY_BASE_PARTS)[number] +export const POINTER_CURSOR_SELECTOR = + 'button:not(:disabled), [role="button"]:not(:disabled)' // Derive font values from registry fonts (e.g., "font-inter" -> "inter"). const fontValues = bodyFonts.map((f) => f.name.replace("font-", "")) as [ @@ -106,6 +108,7 @@ export const designSystemConfigSchema = z fontHeading: z.enum(fontHeadingValues).default("inherit"), item: z.string().optional(), rtl: z.boolean().default(false), + pointer: z.boolean().default(false), menuAccent: z .enum( MENU_ACCENTS.map((a) => a.value) as [ @@ -177,6 +180,7 @@ export const DEFAULT_CONFIG: DesignSystemConfig = { fontHeading: "inherit", item: "Item", rtl: false, + pointer: false, menuAccent: "subtle", menuColor: "default", radius: "default", @@ -187,7 +191,7 @@ export type Preset = { name: string title: string description: string -} & DesignSystemConfig +} & Omit export const PRESETS: Preset[] = [ // Radix. @@ -639,6 +643,11 @@ export function buildRegistryBase(config: DesignSystemConfig) { "@layer base": { "*": { "@apply border-border outline-ring/50": {} }, body: { "@apply bg-background text-foreground": {} }, + ...(config.pointer && { + [POINTER_CURSOR_SELECTOR]: { + cursor: "pointer", + }, + }), }, }, ...(config.rtl && { diff --git a/packages/shadcn/src/commands/init.test.ts b/packages/shadcn/src/commands/init.test.ts index dfce4c17c5..4004ae1a53 100644 --- a/packages/shadcn/src/commands/init.test.ts +++ b/packages/shadcn/src/commands/init.test.ts @@ -14,7 +14,7 @@ import { import { ensureRegistriesInConfig } from "@/src/utils/registries" import { afterEach, beforeEach, describe, expect, it, vi } from "vitest" -import { runInit } from "./init" +import { applyInitUrlOptions, initOptionsSchema, runInit } from "./init" vi.mock("@/src/preflights/preflight-init", () => ({ preFlightInit: vi.fn(), @@ -252,3 +252,32 @@ describe("runInit", () => { expect(postInit).not.toHaveBeenCalled() }) }) + +describe("init options", () => { + it("parses pointer flags", () => { + const result = initOptionsSchema.parse({ + ...createInitOptions("/tmp/project"), + pointer: true, + }) + + expect(result.pointer).toBe(true) + }) + + it("applies pointer to raw init urls", () => { + const url = applyInitUrlOptions( + new URL("https://ui.shadcn.com/init?preset=a0"), + { pointer: true } + ) + + expect(url.searchParams.get("pointer")).toBe("true") + }) + + it("removes pointer from raw init urls when disabled", () => { + const url = applyInitUrlOptions( + new URL("https://ui.shadcn.com/init?preset=a0&pointer=true"), + { pointer: false } + ) + + expect(url.searchParams.has("pointer")).toBe(false) + }) +}) diff --git a/packages/shadcn/src/commands/init.ts b/packages/shadcn/src/commands/init.ts index 512be0380b..e0b6c1c3ab 100644 --- a/packages/shadcn/src/commands/init.ts +++ b/packages/shadcn/src/commands/init.ts @@ -76,6 +76,7 @@ export const initOptionsSchema = z.object({ isNewProject: z.boolean().default(false), cssVariables: z.boolean().default(true), rtl: z.boolean().optional(), + pointer: z.boolean().optional(), base: z.enum(["radix", "base"]).optional(), template: z.string().optional(), monorepo: z.boolean().optional(), @@ -94,6 +95,25 @@ export const initOptionsSchema = z.object({ iconLibrary: z.string().optional(), }) +export function applyInitUrlOptions( + url: URL, + options: Pick, "rtl" | "pointer"> +) { + if (options.rtl) { + url.searchParams.set("rtl", "true") + } else if (options.rtl === false) { + url.searchParams.delete("rtl") + } + + if (options.pointer) { + url.searchParams.set("pointer", "true") + } else if (options.pointer === false) { + url.searchParams.delete("pointer") + } + + return url +} + export const init = new Command() .name("init") .alias("create") @@ -125,6 +145,8 @@ export const init = new Command() .option("--no-css-variables", "do not use css variables for theming.") .option("--rtl", "enable RTL support.") .option("--no-rtl", "disable RTL support.") + .option("--pointer", "enable pointer cursor for buttons.") + .option("--no-pointer", "disable pointer cursor for buttons.") .option("--reinstall", "re-install existing UI components.") .option("--no-reinstall", "do not re-install existing UI components.") .action(async (components, opts) => { @@ -369,6 +391,7 @@ export const init = new Command() rtl: options.rtl ?? false, template: options.template, base: options.base!, + pointer: options.pointer, }) components = [result.url, ...components] presetBase = result.base @@ -379,11 +402,7 @@ export const init = new Command() if (isUrl(presetArg)) { const url = new URL(presetArg) - if (options.rtl) { - url.searchParams.set("rtl", "true") - } else if (options.rtl === false) { - url.searchParams.delete("rtl") - } + applyInitUrlOptions(url, options) if (url.pathname === "/init" && presetArg.startsWith(SHADCN_URL)) { url.searchParams.set("track", "1") } @@ -406,7 +425,11 @@ export const init = new Command() base: "radix", rtl: options.rtl ?? false, }, - { template: options.template, preset: presetArg } + { + template: options.template, + preset: presetArg, + pointer: options.pointer, + } ) presetBase = undefined } else { @@ -420,7 +443,7 @@ export const init = new Command() base: options.base ?? "radix", rtl: options.rtl ?? preset.rtl, }, - { template: options.template } + { template: options.template, pointer: options.pointer } ) presetBase = undefined } @@ -459,7 +482,7 @@ export const init = new Command() base: resolvedBase, rtl: options.rtl ?? false, }, - { template: options.template } + { template: options.template, pointer: options.pointer } ) components = [initUrl, ...components] } diff --git a/packages/shadcn/src/preset/presets.test.ts b/packages/shadcn/src/preset/presets.test.ts index c36b9797f3..937e6558be 100644 --- a/packages/shadcn/src/preset/presets.test.ts +++ b/packages/shadcn/src/preset/presets.test.ts @@ -31,9 +31,14 @@ describe("createPresetUrl", () => { }) it("should append search params when provided", () => { - const url = resolveCreateUrl({ rtl: true, template: "next" }) + const url = resolveCreateUrl({ + rtl: true, + pointer: true, + template: "next", + }) const parsed = new URL(url) expect(parsed.searchParams.get("rtl")).toBe("true") + expect(parsed.searchParams.get("pointer")).toBe("true") expect(parsed.searchParams.get("template")).toBe("next") }) }) @@ -117,4 +122,23 @@ describe("buildInitUrl", () => { const parsed = new URL(url) expect(parsed.searchParams.has("preset")).toBe(false) }) + + it("should include pointer when enabled", () => { + const url = resolveInitUrl(mockPreset, { pointer: true }) + const parsed = new URL(url) + expect(parsed.searchParams.get("pointer")).toBe("true") + }) + + it("should not include pointer when disabled", () => { + const url = resolveInitUrl(mockPreset, { pointer: false }) + const parsed = new URL(url) + expect(parsed.searchParams.has("pointer")).toBe(false) + }) + + it("should include pointer with preset codes", () => { + const url = resolveInitUrl(mockPreset, { preset: "a0", pointer: true }) + const parsed = new URL(url) + expect(parsed.searchParams.get("preset")).toBe("a0") + expect(parsed.searchParams.get("pointer")).toBe("true") + }) }) diff --git a/packages/shadcn/src/preset/presets.ts b/packages/shadcn/src/preset/presets.ts index 17861ce5ec..55ef8ddafa 100644 --- a/packages/shadcn/src/preset/presets.ts +++ b/packages/shadcn/src/preset/presets.ts @@ -132,11 +132,12 @@ export function resolveCreateUrl( command: "create" | "init" template: string rtl: boolean + pointer: boolean base: string }> ) { const url = new URL(`${SHADCN_URL}/create`) - const { rtl, ...params } = searchParams ?? {} + const { rtl, pointer, ...params } = searchParams ?? {} for (const [key, value] of Object.entries(params)) { if (value !== undefined) { @@ -149,6 +150,10 @@ export function resolveCreateUrl( url.searchParams.set("rtl", "true") } + if (pointer) { + url.searchParams.set("pointer", "true") + } + return url.toString() } @@ -195,7 +200,12 @@ export function resolveInitUrl( menuColor: string radius: string }, - options?: { template?: string; preset?: string; only?: string } + options?: { + template?: string + preset?: string + only?: string + pointer?: boolean + } ) { const params = new URLSearchParams({ base: preset.base, @@ -232,6 +242,10 @@ export function resolveInitUrl( params.set("only", options.only) } + if (options?.pointer) { + params.set("pointer", "true") + } + // Signal the server to record this init run. params.set("track", "1") @@ -256,6 +270,7 @@ export async function promptForPreset(options: { rtl: boolean base: string template?: string + pointer?: boolean }) { const presets = Object.entries(DEFAULT_PRESETS) @@ -285,6 +300,7 @@ export async function promptForPreset(options: { const createUrl = resolveCreateUrl({ command: "init", rtl: options.rtl, + pointer: options.pointer, base: options.base, ...(options.template && { template: options.template }), }) @@ -308,6 +324,7 @@ export async function promptForPreset(options: { { ...preset, base: options.base, rtl: options.rtl }, { template: options.template, + pointer: options.pointer, } ), base: options.base,