diff --git a/README.md b/README.md
index 67e6c3d..bca3ad1 100644
--- a/README.md
+++ b/README.md
@@ -39,6 +39,10 @@ function MyComponent({ children }) {
}
```
+If your frontend library injects its own JSX types, you'll need to augment it.
+See the [example project](https://github.com/Desdaemon/typed-htmx/tree/main/example)
+for a demo. typed-html and React are supported out of the box.
+
### As a JSX templating engine
If you prefer to use JSX only for its templating capabilities in the vein of
diff --git a/example/README.md b/example/README.md
new file mode 100644
index 0000000..0e18658
--- /dev/null
+++ b/example/README.md
@@ -0,0 +1,5 @@
+# Example
+
+A demo of library-agnostic type augmentation by typed-htmx.
+
+Try swapping out different `tsconfig.json`s to see the types of different libraries.
diff --git a/example/package.json b/example/package.json
index ef86d38..df5a598 100644
--- a/example/package.json
+++ b/example/package.json
@@ -13,6 +13,6 @@
"typed-htmx": "link:.."
},
"devDependencies": {
- "@types/react": "^18.2.15"
+ "hono": "^3.11.12"
}
}
diff --git a/example/pnpm-lock.yaml b/example/pnpm-lock.yaml
index 06a1e37..d48a021 100644
--- a/example/pnpm-lock.yaml
+++ b/example/pnpm-lock.yaml
@@ -10,28 +10,13 @@ dependencies:
version: link:..
devDependencies:
- '@types/react':
- specifier: ^18.2.15
- version: 18.2.15
+ hono:
+ specifier: ^3.11.12
+ version: 3.11.12
packages:
- /@types/prop-types@15.7.5:
- resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==}
- dev: true
-
- /@types/react@18.2.15:
- resolution: {integrity: sha512-oEjE7TQt1fFTFSbf8kkNuc798ahTUzn3Le67/PWjE8MAfYAD/qB7O8hSTcromLFqHCt9bcdOg5GXMokzTjJ5SA==}
- dependencies:
- '@types/prop-types': 15.7.5
- '@types/scheduler': 0.16.3
- csstype: 3.1.2
- dev: true
-
- /@types/scheduler@0.16.3:
- resolution: {integrity: sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==}
- dev: true
-
- /csstype@3.1.2:
- resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==}
+ /hono@3.11.12:
+ resolution: {integrity: sha512-TrxH75bc0m2UbvrhaXkoo32A9OhkJtvICAYgYWtxqLDOxBjRqSikyp4K7HTbnWkPeg9Z+2Q3nv0dN4o8kL6yLg==}
+ engines: {node: '>=16.0.0'}
dev: true
diff --git a/example/index.jsx b/example/src/index.jsx
similarity index 100%
rename from example/index.jsx
rename to example/src/index.jsx
diff --git a/example/src/types.d.ts b/example/src/types.d.ts
new file mode 100644
index 0000000..6240ea6
--- /dev/null
+++ b/example/src/types.d.ts
@@ -0,0 +1,11 @@
+// typed-htmx declares mostly ambient types so this is all you need.
+import 'typed-htmx';
+
+// A demo of how to augment foreign types with htmx attributes.
+// In this case, Hono sources its types from its own namespace, so we do the same
+// and directly extend its namespace.
+declare global {
+ namespace Hono {
+ interface HTMLAttributes extends HtmxAttributes {}
+ }
+}
diff --git a/example/tsconfig.hono.json b/example/tsconfig.hono.json
new file mode 100644
index 0000000..9990edd
--- /dev/null
+++ b/example/tsconfig.hono.json
@@ -0,0 +1,7 @@
+{
+ "extends": "./tsconfig.json",
+ "compilerOptions": {
+ // This is (usually) the only setting to change when swapping renderers.
+ "jsxImportSource": "hono/jsx"
+ }
+}
diff --git a/example/tsconfig.json b/example/tsconfig.json
index 81eb727..4aef383 100644
--- a/example/tsconfig.json
+++ b/example/tsconfig.json
@@ -1,20 +1,25 @@
{
- "files": ["index.jsx"],
"compilerOptions": {
"target": "es6" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
- // "jsx": "react", /* Specify what JSX code is generated. */
- "jsx": "react-jsx" /* Specify what JSX code is generated. */,
+ // "jsx": "react",
+ "jsx": "react-jsx", /* Specify what JSX code is generated. */
+ // If your frontend framework prescribes a JSX source, change it here.
+ // In this example, we will use typed-htmx's own text renderer based on typed-html.
"jsxImportSource": "typed-htmx/typed-html",
- "module": "commonjs",
+ "module": "node16",
"moduleResolution": "node16" /* Specify how TypeScript looks up a file from a given module specifier. */,
- "types": ["typed-htmx"],
"allowJs": true /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */,
"checkJs": true /* Enable error reporting in type-checked JavaScript files. */,
+ "noEmit": true,
+ "rootDir": ".",
"outDir": "./dist",
"esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */,
"forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
"strict": true /* Enable all strict type-checking options. */,
"skipDefaultLibCheck": true /* Skip type checking .d.ts files that are included with TypeScript. */,
"skipLibCheck": true /* Skip type checking all .d.ts files. */
- }
+ },
+ "include": [
+ "src/**/*",
+ ]
}
diff --git a/src/jsx.d.ts b/src/jsx.d.ts
index 3ac510c..d1dfdae 100644
--- a/src/jsx.d.ts
+++ b/src/jsx.d.ts
@@ -1,5 +1,3 @@
-///
-
/**
* Provides type definitions in JSX for htmx attributes.
* @module
@@ -54,6 +52,8 @@ type HxTriggerModifier =
* ## Declaring a new extension
*
* ```tsx twoslash
+ * // in foo.d.ts:
+ *
* declare global {
* namespace JSX {
* interface HtmxExtensions {
@@ -160,10 +160,17 @@ interface HtmxBuiltinExtensions {
morphdom: "morphdom";
}
+/**
+ * Alternative attribute variants recognized by htmx.
+ */
+type HtmxData = {
+ [K in keyof T as K extends `hx-${string}` ? `data-${K}` : never]: T[K]
+}
+
/**
* Definitions for htmx attributes up to 1.9.3.
*/
-interface HtmxAttributes {
+interface HtmxAttributes extends HtmxData {
/** @ignore For React compatibility only. */
children?: {};
/** @ignore For React compatibility only. */
@@ -403,8 +410,11 @@ interface HtmxAttributes {
/** @ignore */
declare namespace JSX {
interface HtmxExtensions extends HtmxBuiltinExtensions {}
+
+ // typed-html
interface HtmlTag extends HtmxAttributes {}
}
+// React (and other similar frameworks)
/** @ignore */
-interface HTMLElement extends JSX.HtmlTag {}
+interface HTMLElement extends HtmxAttributes {}
diff --git a/src/typed-html/jsx-runtime.ts b/src/typed-html/jsx-runtime.ts
index 75192e7..33950c2 100644
--- a/src/typed-html/jsx-runtime.ts
+++ b/src/typed-html/jsx-runtime.ts
@@ -1,4 +1,5 @@
///
+///
import { createElement } from "typed-html";
import { jsxConfig } from "../index";