diff --git a/packages/cli/src/utils/templates.ts b/packages/cli/src/utils/templates.ts index 351f5fbfb..5cfd2a8c7 100644 --- a/packages/cli/src/utils/templates.ts +++ b/packages/cli/src/utils/templates.ts @@ -8,7 +8,6 @@ export function cn(...inputs: ClassValue[]) { export const UTILS_JS = `import { clsx } from "clsx"; import { twMerge } from "tailwind-merge"; -import tailwindcssAnimate from "tailwindcss-animate"; export function cn(...inputs) { return twMerge(clsx(inputs)); @@ -16,6 +15,7 @@ export function cn(...inputs) { `; const TAILWIND_JS = `import { fontFamily } from "tailwindcss/defaultTheme"; +import tailwindcssAnimate from "tailwindcss-animate"; /** @type {import('tailwindcss').Config} */ const config = {`; @@ -96,10 +96,10 @@ const TAILWIND_WITH_VARIABLES = ` keyframes: { "accordion-down": { from: { height: "0" }, - to: { height: "var(--radix-accordion-content-height)" }, + to: { height: "var(--bits-accordion-content-height)" }, }, "accordion-up": { - from: { height: "var(--radix-accordion-content-height)" }, + from: { height: "var(--bits-accordion-content-height)" }, to: { height: "0" }, }, "caret-blink": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 76c4e40c0..f8f860968 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -16,7 +16,7 @@ importers: version: 9.12.0 '@huntabyte/eslint-config': specifier: ^0.3.2 - version: 0.3.2(@vue/compiler-sfc@3.5.12)(eslint-plugin-svelte@2.44.1(eslint@9.7.0)(svelte@5.0.4))(eslint@9.7.0)(svelte-eslint-parser@0.42.0(svelte@5.0.4))(svelte@5.0.4)(typescript@5.6.3)(vitest@2.1.3) + version: 0.3.2(@vue/compiler-sfc@3.5.12)(eslint-plugin-svelte@2.44.1(eslint@9.7.0)(svelte@5.0.4))(eslint@9.7.0)(svelte-eslint-parser@0.42.0(svelte@5.0.4))(svelte@5.0.4)(typescript@5.6.3)(vitest@2.1.3(@types/node@20.16.14)(terser@5.36.0)) '@typescript-eslint/eslint-plugin': specifier: ^8.10.0 version: 8.10.0(@typescript-eslint/parser@8.10.0(eslint@9.7.0)(typescript@5.6.3))(eslint@9.7.0)(typescript@5.6.3) @@ -282,6 +282,9 @@ importers: tailwindcss-animate: specifier: ^1.0.7 version: 1.0.7(tailwindcss@3.4.14) + ts-blank-space: + specifier: ^0.4.1 + version: 0.4.1 tslib: specifier: ^2.6.3 version: 2.8.0 @@ -5488,6 +5491,10 @@ packages: peerDependencies: typescript: '>=4.2.0' + ts-blank-space@0.4.1: + resolution: {integrity: sha512-i0JvTvFaZcXCj+tcs67G0K3zXgUr1ebGvhmuB3ov0ByFrbuvTOgUwtFEOP8dN+B+ou0wkhosJ8Q4RPfi8mHFQQ==} + engines: {node: '>=18.0.0'} + ts-deepmerge@7.0.1: resolution: {integrity: sha512-JBFCmNenZdUCc+TRNCtXVM6N8y/nDQHAcpj5BlwXG/gnogjam1NunulB9ia68mnqYI446giMfpqeBFFkOleh+g==} engines: {node: '>=14.13.1'} @@ -6019,7 +6026,7 @@ snapshots: '@jridgewell/gen-mapping': 0.3.5 '@jridgewell/trace-mapping': 0.3.25 - '@antfu/eslint-config@2.22.0(@vue/compiler-sfc@3.5.12)(eslint-plugin-svelte@2.44.1(eslint@9.7.0)(svelte@5.0.4))(eslint@9.7.0)(svelte-eslint-parser@0.42.0(svelte@5.0.4))(svelte@5.0.4)(typescript@5.6.3)(vitest@2.1.3)': + '@antfu/eslint-config@2.22.0(@vue/compiler-sfc@3.5.12)(eslint-plugin-svelte@2.44.1(eslint@9.7.0)(svelte@5.0.4))(eslint@9.7.0)(svelte-eslint-parser@0.42.0(svelte@5.0.4))(svelte@5.0.4)(typescript@5.6.3)(vitest@2.1.3(@types/node@20.16.14)(terser@5.36.0))': dependencies: '@antfu/install-pkg': 0.3.3 '@clack/prompts': 0.7.0 @@ -6044,7 +6051,7 @@ snapshots: eslint-plugin-toml: 0.11.1(eslint@9.7.0) eslint-plugin-unicorn: 54.0.0(eslint@9.7.0) eslint-plugin-unused-imports: 4.0.0(@typescript-eslint/eslint-plugin@8.0.0-alpha.40(@typescript-eslint/parser@8.0.0-alpha.40(eslint@9.7.0)(typescript@5.6.3))(eslint@9.7.0)(typescript@5.6.3))(eslint@9.7.0) - eslint-plugin-vitest: 0.5.4(@typescript-eslint/eslint-plugin@8.0.0-alpha.40(@typescript-eslint/parser@8.0.0-alpha.40(eslint@9.7.0)(typescript@5.6.3))(eslint@9.7.0)(typescript@5.6.3))(eslint@9.7.0)(typescript@5.6.3)(vitest@2.1.3) + eslint-plugin-vitest: 0.5.4(@typescript-eslint/eslint-plugin@8.0.0-alpha.40(@typescript-eslint/parser@8.0.0-alpha.40(eslint@9.7.0)(typescript@5.6.3))(eslint@9.7.0)(typescript@5.6.3))(eslint@9.7.0)(typescript@5.6.3)(vitest@2.1.3(@types/node@20.16.14)(terser@5.36.0)) eslint-plugin-vue: 9.27.0(eslint@9.7.0) eslint-plugin-yml: 1.14.0(eslint@9.7.0) eslint-processor-vue-blocks: 0.1.2(@vue/compiler-sfc@3.5.12)(eslint@9.7.0) @@ -6731,9 +6738,9 @@ snapshots: '@humanwhocodes/retry@0.3.0': {} - '@huntabyte/eslint-config@0.3.2(@vue/compiler-sfc@3.5.12)(eslint-plugin-svelte@2.44.1(eslint@9.7.0)(svelte@5.0.4))(eslint@9.7.0)(svelte-eslint-parser@0.42.0(svelte@5.0.4))(svelte@5.0.4)(typescript@5.6.3)(vitest@2.1.3)': + '@huntabyte/eslint-config@0.3.2(@vue/compiler-sfc@3.5.12)(eslint-plugin-svelte@2.44.1(eslint@9.7.0)(svelte@5.0.4))(eslint@9.7.0)(svelte-eslint-parser@0.42.0(svelte@5.0.4))(svelte@5.0.4)(typescript@5.6.3)(vitest@2.1.3(@types/node@20.16.14)(terser@5.36.0))': dependencies: - '@antfu/eslint-config': 2.22.0(@vue/compiler-sfc@3.5.12)(eslint-plugin-svelte@2.44.1(eslint@9.7.0)(svelte@5.0.4))(eslint@9.7.0)(svelte-eslint-parser@0.42.0(svelte@5.0.4))(svelte@5.0.4)(typescript@5.6.3)(vitest@2.1.3) + '@antfu/eslint-config': 2.22.0(@vue/compiler-sfc@3.5.12)(eslint-plugin-svelte@2.44.1(eslint@9.7.0)(svelte@5.0.4))(eslint@9.7.0)(svelte-eslint-parser@0.42.0(svelte@5.0.4))(svelte@5.0.4)(typescript@5.6.3)(vitest@2.1.3(@types/node@20.16.14)(terser@5.36.0)) '@antfu/install-pkg': 0.3.3 '@clack/prompts': 0.7.0 '@huntabyte/eslint-plugin': 0.1.0(eslint@9.7.0) @@ -7791,7 +7798,7 @@ snapshots: chai: 5.1.1 tinyrainbow: 1.2.0 - '@vitest/mocker@2.1.3(@vitest/spy@2.1.3)(vite@5.4.9)': + '@vitest/mocker@2.1.3(@vitest/spy@2.1.3)(vite@5.4.9(@types/node@20.16.14)(terser@5.36.0))': dependencies: '@vitest/spy': 2.1.3 estree-walker: 3.0.3 @@ -9077,7 +9084,7 @@ snapshots: optionalDependencies: '@typescript-eslint/eslint-plugin': 8.0.0-alpha.40(@typescript-eslint/parser@8.0.0-alpha.40(eslint@9.7.0)(typescript@5.6.3))(eslint@9.7.0)(typescript@5.6.3) - eslint-plugin-vitest@0.5.4(@typescript-eslint/eslint-plugin@8.0.0-alpha.40(@typescript-eslint/parser@8.0.0-alpha.40(eslint@9.7.0)(typescript@5.6.3))(eslint@9.7.0)(typescript@5.6.3))(eslint@9.7.0)(typescript@5.6.3)(vitest@2.1.3): + eslint-plugin-vitest@0.5.4(@typescript-eslint/eslint-plugin@8.0.0-alpha.40(@typescript-eslint/parser@8.0.0-alpha.40(eslint@9.7.0)(typescript@5.6.3))(eslint@9.7.0)(typescript@5.6.3))(eslint@9.7.0)(typescript@5.6.3)(vitest@2.1.3(@types/node@20.16.14)(terser@5.36.0)): dependencies: '@typescript-eslint/utils': 7.16.0(eslint@9.7.0)(typescript@5.6.3) eslint: 9.7.0 @@ -11917,6 +11924,10 @@ snapshots: dependencies: typescript: 5.6.3 + ts-blank-space@0.4.1: + dependencies: + typescript: 5.6.3 + ts-deepmerge@7.0.1: {} ts-interface-checker@0.1.13: {} @@ -12300,7 +12311,7 @@ snapshots: vitest@2.1.3(@types/node@20.16.14)(terser@5.36.0): dependencies: '@vitest/expect': 2.1.3 - '@vitest/mocker': 2.1.3(@vitest/spy@2.1.3)(vite@5.4.9) + '@vitest/mocker': 2.1.3(@vitest/spy@2.1.3)(vite@5.4.9(@types/node@20.16.14)(terser@5.36.0)) '@vitest/pretty-format': 2.1.3 '@vitest/runner': 2.1.3 '@vitest/snapshot': 2.1.3 diff --git a/sites/docs/package.json b/sites/docs/package.json index 0a5eec6b2..ad4bb7ee9 100644 --- a/sites/docs/package.json +++ b/sites/docs/package.json @@ -80,6 +80,7 @@ "tailwind-variants": "^0.2.1", "tailwindcss": "^3.4.4", "tailwindcss-animate": "^1.0.7", + "ts-blank-space": "^0.4.1", "tslib": "^2.6.3", "tsx": "^4.16.2", "typescript": "~5.5.3", diff --git a/sites/docs/scripts/build-registry.ts b/sites/docs/scripts/build-registry.ts index ca0f08017..0ec0ce540 100644 --- a/sites/docs/scripts/build-registry.ts +++ b/sites/docs/scripts/build-registry.ts @@ -11,10 +11,19 @@ import { buildRegistry } from "./registry"; import { BASE_STYLES, BASE_STYLES_WITH_VARIABLES, THEME_STYLES_WITH_VARIABLES } from "./templates"; import { getChunks } from "./transform-chunks"; import { transformContent } from "./transformers"; +import prettier from "prettier"; +import prettierPluginSvelte from "prettier-plugin-svelte"; const REGISTRY_PATH = path.resolve("static", "registry"); const REGISTRY_IGNORE = ["super-form"]; +const prettierConfig: prettier.Config = { + useTabs: true, + singleQuote: false, + trailingComma: "es5", + printWidth: 100, +}; + function writeFileWithDirs( filePath: string, data: string, @@ -178,11 +187,15 @@ export const Index = { const jsFiles = await Promise.all( files.map(async (file) => { - const content = (await transformContent(file.content, file.name)).replaceAll( - " ", - "\t" - ); + let content = await transformContent(file.content, file.name); const fileName = file.name.replace(".ts", ".js"); + // format + content = await prettier.format(content, { + ...prettierConfig, + filepath: fileName, + plugins: [prettierPluginSvelte], + overrides: [{ files: "*.svelte", options: { parser: "svelte" } }], + }); return { name: fileName, content, diff --git a/sites/docs/scripts/transformers.ts b/sites/docs/scripts/transformers.ts index 14e2bca2d..01e59a3a1 100644 --- a/sites/docs/scripts/transformers.ts +++ b/sites/docs/scripts/transformers.ts @@ -1,6 +1,7 @@ -import { vitePreprocess } from "@sveltejs/vite-plugin-svelte"; -import { preprocess } from "svelte/compiler"; -import ts from "typescript"; +import { walk } from "estree-walker"; +import { preprocess, parse, type PreprocessorGroup } from "svelte/compiler"; +import tsBlankSpace from "ts-blank-space"; +import MagicString from "magic-string"; export type TransformOpts = { filename: string; @@ -8,29 +9,6 @@ export type TransformOpts = { // baseColor?: z.infer; - will use later }; -// const sharedPrettierConfig = { -// useTabs: true, -// tabWidth: 4, -// singleQuote: false, -// trailingComma: "es5" as const, -// printWidth: 100, -// endOfLine: "lf" as const, -// bracketSameLine: false, -// }; - -// const registrySveltePrettierConfig = { -// ...sharedPrettierConfig, -// pluginSearchDirs: ["./node_modules/prettier-plugin-svelte"], -// parser: "svelte", -// svelteStrictMode: false, -// plugins: ["prettier-plugin-svelte"], -// }; - -// const registryJSPrettierConfig = { -// ...sharedPrettierConfig, -// parser: "babel", -// }; - export async function transformContent(content: string, filename: string) { if (filename.endsWith(".svelte")) { return transformSvelteTStoJS(content, filename); @@ -38,42 +16,104 @@ export async function transformContent(content: string, filename: string) { return transformTStoJS(content, filename); } } - async function transformSvelteTStoJS(content: string, filename: string) { try { - const { code } = await preprocess(content, [vitePreprocess()]); - let s = code.replaceAll(/", "").trimStart(); } catch (e) { throw new Error(`Error preprocessing Svelte file: ${filename} \n ${e}`); } } -const compilerOptions: ts.CompilerOptions = { - target: ts.ScriptTarget.ESNext, - module: ts.ModuleKind.ESNext, - isolatedModules: true, - preserveValueImports: true, - lib: ["esnext", "DOM", "DOM.Iterable"], - moduleResolution: ts.ModuleResolutionKind.Bundler, - esModuleInterop: true, - ignoreDeprecations: "5.0", -}; - function transformTStoJS(content: string, filename: string) { - const { outputText, diagnostics } = ts.transpileModule(content, { - compilerOptions, - reportDiagnostics: true, - }); - - // Check for compilation errors - if (diagnostics && diagnostics.length > 0) { - // Throw the errors so the user can see them/create an issue about them. + const output = tsBlankSpace(content, (node) => { throw new Error( - `Error compiling TypeScript to JavaScript for file: ${filename} \n ${diagnostics}` + `Error compiling TypeScript to JavaScript for file: ${filename} \n ${node.pos}` ); - } else { - return outputText; - } + }); + + return output; +} + +function stripScriptTypes(): PreprocessorGroup { + return { + // strip the `lang="ts"` attribute + script: ({ content, attributes, filename }) => { + if (attributes["lang"] !== "ts") return; + delete attributes["lang"]; + delete attributes["generics"]; + return { code: transformTStoJS(content, filename!).trim(), attributes }; + }, + }; +} + +function stripMarkupTypes(): PreprocessorGroup { + return { + markup: ({ content, filename }) => { + const ms = new MagicString(content); + const ast = parse(content, { filename, modern: true }); + + // @ts-expect-error simmer down + walk(ast.fragment, { + enter(node: (typeof ast)["fragment"]["nodes"][number]) { + // ignore typescript specific nodes + if (node.type.startsWith("TS")) return; + + if (node.type === "SnippetBlock") { + if (node.parameters.length === 0) return; + // @ts-expect-error relax buddy + const start = node.parameters.at(0)!.start; + const end = + // @ts-expect-error you too + node.parameters.at(-1)!.typeAnnotation?.end ?? + // @ts-expect-error and you + node.parameters.at(-1)!.end; + + const params = content.substring(start, end); + // temporarily wraps the params in an arrow function so that it's parsable + const arrow = " => {}"; + const wrapped = `(${params})${arrow}`; + const stripped = transformTStoJS(wrapped, filename!) + .replace(arrow, "") + .slice(1, -1); + ms.update(start, end, stripped); + } else if (node.type === "ConstTag") { + // @ts-expect-error hush + const { start, end } = node.declaration; + const expression = content.substring(start, end); + const wrapped = `(${expression})`; + const stripped = transformTStoJS(wrapped, filename!).slice(1, -1); + ms.update(start, end, stripped); + + this.skip(); + } else if (node.type === "RenderTag" || node.type === "ExpressionTag") { + // @ts-expect-error take a breather + const { start, end } = node.expression; + const expression = content.substring(start, end); + const wrapped = `(${expression})`; + const stripped = transformTStoJS(wrapped, filename!).slice(1, -1); + ms.update(start, end, stripped); + + this.skip(); + } else if ("expression" in node) { + // @ts-expect-error trust me + const { start, end } = node.expression; + + const expression = content.substring(start, end); + const wrapped = `(${expression})`; + + // removes the `()` + const stripped = transformTStoJS(wrapped, filename!).slice(1, -1); + + ms.update(start, end, stripped); + } + }, + }); + + return { code: ms.toString() }; + }, + }; } diff --git a/sites/docs/src/__registry__/index.js b/sites/docs/src/__registry__/index.js index 7e09a00d7..abe2f098a 100644 --- a/sites/docs/src/__registry__/index.js +++ b/sites/docs/src/__registry__/index.js @@ -670,7 +670,7 @@ export const Index = { "select-demo": { name: "select-demo", type: "registry:example", - registryDependencies: ["select","label"], + registryDependencies: ["select"], component: () => import("../lib/registry/default/example/select-demo.svelte").then((m) => m.default), files: ["../lib/registry/default/example/select-demo.svelte"], raw: () => import("../lib/registry/default/example/select-demo.svelte?raw").then((m) => m.default), @@ -1703,7 +1703,7 @@ export const Index = { "select-demo": { name: "select-demo", type: "registry:example", - registryDependencies: ["select","label"], + registryDependencies: ["select"], component: () => import("../lib/registry/new-york/example/select-demo.svelte").then((m) => m.default), files: ["../lib/registry/new-york/example/select-demo.svelte"], raw: () => import("../lib/registry/new-york/example/select-demo.svelte?raw").then((m) => m.default), diff --git a/sites/docs/src/lib/registry/default/ui/data-table/flex-render.svelte b/sites/docs/src/lib/registry/default/ui/data-table/flex-render.svelte index 8e0ed0f19..ef1a240dd 100644 --- a/sites/docs/src/lib/registry/default/ui/data-table/flex-render.svelte +++ b/sites/docs/src/lib/registry/default/ui/data-table/flex-render.svelte @@ -1,9 +1,6 @@