Skip to content

Commit

Permalink
feat: custom codegen for directives passing
Browse files Browse the repository at this point in the history
  • Loading branch information
insertish committed Jun 4, 2024
1 parent 479a0fc commit dda099e
Show file tree
Hide file tree
Showing 5 changed files with 260 additions and 19 deletions.
63 changes: 63 additions & 0 deletions packages/client/codegen.plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { readdirSync } from "node:fs";

const fileRegex = /\.tsx$/;
const codegenRegex = /\/\/ @codegen (.*)/g;

const DIRECTIVES = readdirSync("./components/ui/directives")
.filter((x) => x !== "index.ts")
.map((x) => x.substring(0, x.length - 3));

const directiveRegex = new RegExp("use:(" + DIRECTIVES.join("|") + ")");

export default function codegenPlugin() {
return {
name: "codegen",
enforce: "pre",
transform(src: string, id: string) {
if (fileRegex.test(id)) {
src = src.replace(codegenRegex, (substring, group1) => {
const rawArgs: string[] = group1.split(" ");
const type = rawArgs.shift();

const args = rawArgs.reduce(
(d, arg) => {
const [key, value] = arg.split("=");
return {
...d,
[key]: value,
};
},
{ type }
) as {
type: "directives";
props?: string;
include?: string;
};

switch (args.type) {
case "directives":
// Generate directives forwarding
const source = args.props ?? "props";
const permitted: string[] =
args.include?.split(",") ?? DIRECTIVES;
return DIRECTIVES.filter((d) => permitted.includes(d))
.map((d) => `use:${d}={${source}["use:${d}"]}`)
.join("\n");
default:
return substring;
}
});

if (directiveRegex.test(src)) {
if (!id.endsWith("client/components/ui/index.tsx"))
src =
`import { ${DIRECTIVES.join(
", "
)} } from "@revolt/ui/directives";\n` + src;
}

return src;
}
},
};
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { splitProps } from "solid-js";
import { JSX } from "solid-js/jsx-runtime";

import { AriaButtonProps, createButton } from "@solid-aria/button";
import { cva } from "styled-system/css/cva";
Expand Down Expand Up @@ -92,13 +93,22 @@ const button = cva({
},
});

export function Button(props: Parameters<typeof button>[0] & AriaButtonProps) {
export function Button(
props: Parameters<typeof button>[0] &
AriaButtonProps &
JSX.DirectiveAttributes
) {
const [style, rest] = splitProps(props, ["size", "variant"]);
let ref: HTMLButtonElement | undefined;

const { buttonProps } = createButton(rest, () => ref);
return (
<button {...buttonProps} class={button(style)} ref={ref}>
<button
{...buttonProps}
ref={ref}
class={button(style)}
// @codegen directives props=rest include=floating
>
{rest.children}
</button>
);
Expand Down
2 changes: 2 additions & 0 deletions packages/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,14 @@
"@types/lodash.defaultsdeep": "^4.6.9",
"@types/lodash.isequal": "^4.5.8",
"@types/unist": "^3.0.2",
"babel-plugin-codegen": "^4.1.5",
"jsdom": "^24.0.0",
"lnk": "^1.1.0",
"rehype-stringify": "^10.0.0",
"revolt.js": "workspace:^",
"typescript": "^5.4.2",
"vite": "^5.1.6",
"vite-plugin-inspect": "^0.8.3",
"vite-plugin-pwa": "^0.19.4",
"vite-plugin-solid": "^2.10.2",
"vite-plugin-solid-svg": "^0.8.0",
Expand Down
5 changes: 5 additions & 0 deletions packages/client/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,22 @@ import devtools from "@solid-devtools/transform";
import { readdirSync } from "node:fs";
import { resolve } from "node:path";
import { defineConfig } from "vite";
import Inspect from "vite-plugin-inspect";
import { VitePWA } from "vite-plugin-pwa";
import solidPlugin from "vite-plugin-solid";
// @ts-expect-error
import solidSvg from "vite-plugin-solid-svg";

import codegenPlugin from "./codegen.plugin";

const base = process.env.BASE_PATH ?? "/";

export default defineConfig({
base,
plugins: [
Inspect(),
devtools(),
codegenPlugin(),
solidPlugin(),
solidSvg({
defaultAsComponent: false,
Expand Down
Loading

0 comments on commit dda099e

Please sign in to comment.