diff --git a/docs/docs/howto/intro.md b/docs/docs/howto/intro.md
index 9dc1bf5..7b9e924 100644
--- a/docs/docs/howto/intro.md
+++ b/docs/docs/howto/intro.md
@@ -2,7 +2,7 @@
## Demo
-```tsx twoslash
+```jsx twoslash
// @errors: 2322
function MyComponent({ children }) {
@@ -103,7 +103,7 @@ Configure your `tsconfig.json` as follows:
If you don't have any other JSX runtimes like React or Preact set up, you can use
`typed-htmx/typed-html`, which will convert JSX into strings at runtime.
-You can configure the runtime using [`jsxConfig`](/typed-htmx/docs/api/module.index/Variables/variable.jsxConfig-1):
+You can configure the runtime using [`jsxConfig`](/typed-htmx/docs/api/index/variables/jsxConfig):
```js twoslash
import { jsxConfig } from "typed-htmx";
diff --git a/docs/docs/howto/xternal.md b/docs/docs/howto/xternal.md
new file mode 100644
index 0000000..38a3b80
--- /dev/null
+++ b/docs/docs/howto/xternal.md
@@ -0,0 +1,65 @@
+# Augmenting external JSX libraries
+
+typed-htmx is extremely minimal and requires the user to manually augment external JSX libraries that provide their own types.
+
+## Common guidance
+
+- Create a `types.d.ts` (any name is fine, as long as it ends in `.d.ts`) at the top of your src/ folder,
+ or anywhere within the configured `include` of your tsconfig.json
+- Write a JSX element, e.g. `
`, and inspect its type
+- If you see React-related types, you are good to go
+- If not, try to discover the common namespace under which all HTML attributes go.
+
+Let's use [Hono](https://hono.dev/top) as an example.
+
+```tsx twoslash
+// @jsxImportSource: hono/jsx
+// In tsconfig.json, jsxImportSource = "hono/jsx"
+
+// The type we are augmenting in this case is `Hono.HTMLAttributes`.
+// hx-boost is not recognized as a proper attribute yet.
+
+//^?
+```
+
+With this knowledge, we can now augment the type of `Hono.HTMLAttributes` assuming it is an interface:
+
+```tsx twoslash
+// @errors: 2322
+// @jsxImportSource: hono/jsx
+///
+
+declare global {
+ namespace Hono {
+ interface HTMLAttributes extends HtmxAttributes {}
+ }
+}
+
+
+```
+
+## Hono
+
+```ts twoslash
+import 'typed-htmx';
+
+declare global {
+ namespace Hono {
+ interface HTMLAttributes extends HtmxAttributes {}
+ }
+}
+```
+
+## Astro
+
+```ts twoslash
+import 'typed-htmx';
+
+declare global {
+ namespace astroHTML.JSX {
+ interface IntrinsicAttributes extends HtmxAttributes {}
+ }
+}
+```
diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js
index 94cd39d..dd93ad3 100644
--- a/docs/docusaurus.config.js
+++ b/docs/docusaurus.config.js
@@ -21,8 +21,8 @@ const config = {
markdown: {
format: 'md'
},
- onBrokenLinks: "throw",
- onBrokenMarkdownLinks: "ignore",
+ onBrokenLinks: "warn",
+ onBrokenMarkdownLinks: "warn",
i18n: {
defaultLocale: "en",
@@ -36,12 +36,10 @@ const config = {
({
entryPoints: ["../src/index.ts", "../src/jsx.d.ts"],
tsconfig: "../tsconfig.json",
- readme: "none",
hideInPageTOC: true,
+ readme: 'none',
watch: process.env.npm_lifecycle_event === "start",
- // cleanOutputDir: process.env.NODE_ENV !== 'production',
- cleanOutputDir: false,
- excludeExternals: true,
+ cleanOutputDir: true,
externalPattern: ["node_modules/**/*"],
plugin: ["typedoc-plugin-mdn-links"],
}),
@@ -70,19 +68,17 @@ const config = {
defaultOptions: {
noErrors: false,
},
- /** @type {import('typescript').CompilerOptions} */
defaultCompilerOptions: {
- types: ["typed-htmx"],
jsx: 4, // react-jsx
- jsxImportSource: "typed-htmx/typed-html",
+ jsxImportSource: 'typed-htmx/typed-html',
target: 99, // esnext,
strict: true,
+ checkJs: true,
noImplicitAny: false,
module: 199, // nodenext,
moduleResolution: 99, // nodenext
},
includeJSDocInHover: true,
- wrapFragments: true,
alwayRaiseForTwoslashExceptions: true,
disableImplicitReactImport: true,
}),
diff --git a/docs/package.json b/docs/package.json
index d5477de..e36992b 100644
--- a/docs/package.json
+++ b/docs/package.json
@@ -21,11 +21,11 @@
"clsx": "^1.2.1",
"docusaurus-plugin-typedoc": "next",
"docusaurus-preset-shiki-twoslash": "^1.1.41",
+ "hono": "^3.11.12",
"object-assign": "^4.1.1",
"prism-react-renderer": "^1.3.5",
"react": "^18.2.0",
"react-dom": "^18.2.0",
- "rehype-raw": "^7.0.0",
"typed-htmx": "link:..",
"typedoc": "^0.25.6",
"typedoc-plugin-markdown": "next",
@@ -34,8 +34,7 @@
},
"devDependencies": {
"@docusaurus/module-type-aliases": "3.0.1",
- "@docusaurus/types": "^3.0.1",
- "remark-shiki-twoslash": "^3.1.3"
+ "@docusaurus/types": "^3.0.1"
},
"browserslist": {
"production": [
diff --git a/docs/pnpm-lock.yaml b/docs/pnpm-lock.yaml
index ebabc29..aed7c7c 100644
--- a/docs/pnpm-lock.yaml
+++ b/docs/pnpm-lock.yaml
@@ -26,6 +26,9 @@ dependencies:
docusaurus-preset-shiki-twoslash:
specifier: ^1.1.41
version: 1.1.41
+ hono:
+ specifier: ^3.11.12
+ version: 3.11.12
object-assign:
specifier: ^4.1.1
version: 4.1.1
@@ -5189,6 +5192,11 @@ packages:
react-is: 16.13.1
dev: false
+ /hono@3.11.12:
+ resolution: {integrity: sha512-TrxH75bc0m2UbvrhaXkoo32A9OhkJtvICAYgYWtxqLDOxBjRqSikyp4K7HTbnWkPeg9Z+2Q3nv0dN4o8kL6yLg==}
+ engines: {node: '>=16.0.0'}
+ dev: false
+
/hpack.js@2.1.6:
resolution: {integrity: sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==}
dependencies:
diff --git a/docs/typedoc.json b/docs/typedoc.json
index 08c463a..9785dc3 100644
--- a/docs/typedoc.json
+++ b/docs/typedoc.json
@@ -1,3 +1,13 @@
{
- "categoryOrder": ["core", "*"]
+ "$schema": "https://typedoc.org/schema.json",
+ "categoryOrder": ["core", "*"],
+ "sourceLinkExternal": true,
+ "excludeExternals": true,
+ "externalPattern": [
+ "**/node_modules/**/*"
+ ],
+ "readme": "bogus",
+ "searchCategoryBoosts": {
+ "Core": 2
+ }
}
diff --git a/src/index.ts b/src/index.ts
index ff535f1..3e84f1a 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -95,6 +95,20 @@ function htmlTransformChildren(value: InterpValue): string {
return out.join(" ");
}
+/**
+ * A [tagged template](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#tagged_templates)
+ * that interprets different kinds of {@link InterpValue values} into escaped HTML.
+ *
+ * ```ts twoslash
+ * import { html } from 'typed-htmx';
+ * function assertEqual(left: any, right: any) {}
+ * // ---cut---
+ * const template = html`
+ *
+ * `;
+ * assertEqual(template, ``);
+ * ```
+ */
export const html: HtmlTemplator = (raw, ...values) => {
const values_ = values.map(htmlTransformChildren);
return String.raw(raw, ...values_);
diff --git a/src/jsx.d.ts b/src/jsx.d.ts
index 9f41109..6bfd6a7 100644
--- a/src/jsx.d.ts
+++ b/src/jsx.d.ts
@@ -49,22 +49,22 @@ type HxTriggerModifier =
/**
* An extensible directory of htmx extensions.
*
- * ## Declaring a new extension
+ * ### Declaring a new extension
*
* ```tsx twoslash
* // in foo.d.ts:
*
* declare global {
- * namespace JSX {
- * interface HtmxExtensions {
- * myExtension: "my-extension";
- * }
- * interface HtmlTag {
- * /** Describe your attribute *\/
- * ["my-extension-attr"]?: string;
- * // Add any other attributes your extension uses here
- * }
- * }
+ * namespace JSX {
+ * interface HtmxExtensions {
+ * myExtension: "my-extension";
+ * }
+ * interface HtmlTag {
+ * /** Describe your attribute *\/
+ * ["my-extension-attr"]?: string;
+ * // Add any other attributes your extension uses here
+ * }
+ * }
* }
*
*
@@ -160,17 +160,10 @@ interface HtmxBuiltinExtensions {
morphdom: "morphdom";
}
-/**
- * Variants of attributes also 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 extends HtmxData {
+interface HtmxAttributes {
/** @ignore For React compatibility only. */
children?: {};
/** @ignore For React compatibility only. */
@@ -178,13 +171,13 @@ interface HtmxAttributes extends HtmxData {
/**
* Issues a `GET` to the specified URL.
* @see https://htmx.org/attributes/hx-get/
- * @category core
+ * @category Core
*/
["hx-get"]?: string;
/**
* Issues a `POST` to the specified URL.
* @see https://htmx.org/attributes/hx-post/
- * @category core
+ * @category Core
*/
["hx-post"]?: string;
/**
@@ -207,13 +200,13 @@ interface HtmxAttributes extends HtmxData {
* for links and forms.
*
* @see https://htmx.org/attributes/hx-boost/
- * @category core
+ * @category Core
*/
["hx-boost"]?: BoolStr;
/**
* Handle any event with a script inline.
* @see https://htmx.org/attributes/hx-on/
- * @category core
+ * @category Core
* @remarks Event listeners on htmx-specific events need to be specified with a spread attribute, and
* are otherwise not supported in vanilla JSX.
* ```jsx
@@ -232,26 +225,26 @@ interface HtmxAttributes extends HtmxData {
/**
* Pushes the URL into the browser location bar, creating a new history entry.
* @see https://htmx.org/attributes/hx-push-url/
- * @category core
+ * @category Core
*/
["hx-push-url"]?: BoolStr | AnyStr;
/**
* Select content to swap in from a response.
* @see https://htmx.org/attributes/hx-select/
- * @category core
+ * @category Core
*/
["hx-select"]?: string;
/**
* Select content to swap in from a response, out of band (somewhere other than the target).
* @see https://htmx.org/attributes/hx-select-oob/
- * @category core
+ * @category Core
*/
["hx-select-oob"]?: string;
/**
* Controls how content is swapped in (`outerHTML`, `beforeend`, `afterend`, …).
* @see https://htmx.org/attributes/hx-swap/
- * @see {@linkcode InsertPosition} which is used in [{@linkcode Element.insertAdjacentHTML}](https://developer.mozilla.org/docs/Web/API/Element/insertAdjacentHTML)
- * @category core
+ * @see [`InsertPosition`](https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML#position) which is used in `Element.insertAdjacentHTML`.
+ * @category Core
* @remarks
* - `morph` swaps are part of the {@linkcode HtmxBuiltinExtensions.idiomorph idiomorph} extension.
* - `morphdom` swaps are part of the {@linkcode HtmxBuiltinExtensions.morphdom morphdom} extension.
@@ -265,19 +258,19 @@ interface HtmxAttributes extends HtmxData {
/**
* Specifies the target element to be swapped.
* @see https://htmx.org/attributes/hx-target/
- * @category core
+ * @category Core
*/
["hx-target"]?: HxTarget | AnyStr;
/**
* Specifies the event that triggers the request.
* @see https://htmx.org/attributes/hx-trigger/
- * @category core
+ * @category Core
*/
["hx-trigger"]?: "every " | HxTriggerModifier | AnyStr;
/**
* Adds values to the parameters to submit with the request (JSON-formatted).
* @see https://htmx.org/attributes/hx-params/
- * @category core
+ * @category Core
*/
["hx-vals"]?: AnyStr | "javascript:" | "js:" | Record;
/**
@@ -426,6 +419,5 @@ declare namespace JSX {
interface HtmlTag extends HtmxAttributes {}
}
-// React (and other similar frameworks)
/** @ignore */
interface HTMLElement extends HtmxAttributes {}
diff --git a/tsconfig.json b/tsconfig.json
index c9cea6c..dec6343 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,5 +1,5 @@
{
- "include": ["./src/**/*"],
+ "include": ["src/**/*"],
"compilerOptions": {
"target": "es2022",
"module": "commonjs",