Skip to content

Commit

Permalink
doc: integration guide for external libs
Browse files Browse the repository at this point in the history
  • Loading branch information
Desdaemon committed Jan 4, 2024
1 parent dfe0a3b commit c8be767
Show file tree
Hide file tree
Showing 9 changed files with 133 additions and 49 deletions.
4 changes: 2 additions & 2 deletions docs/docs/howto/intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Demo

```tsx twoslash
```jsx twoslash
// @errors: 2322

function MyComponent({ children }) {
Expand Down Expand Up @@ -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";
Expand Down
65 changes: 65 additions & 0 deletions docs/docs/howto/xternal.md
Original file line number Diff line number Diff line change
@@ -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. `<div />`, 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.
<div hx-boost="bogus" />
//^?
```

With this knowledge, we can now augment the type of `Hono.HTMLAttributes` assuming it is an interface:

```tsx twoslash
// @errors: 2322
// @jsxImportSource: hono/jsx
/// <reference types="typed-htmx" />

declare global {
namespace Hono {
interface HTMLAttributes extends HtmxAttributes {}
}
}

<div hx-boost="bogus"
style={{}}
/>
```

## 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 {}
}
}
```
16 changes: 6 additions & 10 deletions docs/docusaurus.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ const config = {
markdown: {
format: 'md'
},
onBrokenLinks: "throw",
onBrokenMarkdownLinks: "ignore",
onBrokenLinks: "warn",
onBrokenMarkdownLinks: "warn",

i18n: {
defaultLocale: "en",
Expand All @@ -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"],
}),
Expand Down Expand Up @@ -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,
}),
Expand Down
5 changes: 2 additions & 3 deletions docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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": [
Expand Down
8 changes: 8 additions & 0 deletions docs/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 11 additions & 1 deletion docs/typedoc.json
Original file line number Diff line number Diff line change
@@ -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
}
}
14 changes: 14 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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`
* <div hx-vals=${{ foo: 'bar' }} />
* `;
* assertEqual(template, `<div hx-vals='{"foo":"bar"}' />`);
* ```
*/
export const html: HtmlTemplator = (raw, ...values) => {
const values_ = values.map(htmlTransformChildren);
return String.raw(raw, ...values_);
Expand Down
56 changes: 24 additions & 32 deletions src/jsx.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
* }
* }
* }
*
* <div hx-ext="my-extension">
Expand Down Expand Up @@ -160,31 +160,24 @@ interface HtmxBuiltinExtensions {
morphdom: "morphdom";
}

/**
* Variants of attributes also recognized by htmx.
*/
type HtmxData<T> = {
[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<HtmxAttributes> {
interface HtmxAttributes {
/** @ignore For React compatibility only. */
children?: {};
/** @ignore For React compatibility only. */
key?: {};
/**
* 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;
/**
Expand All @@ -207,13 +200,13 @@ interface HtmxAttributes extends HtmxData<HtmxAttributes> {
* 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
Expand All @@ -232,26 +225,26 @@ interface HtmxAttributes extends HtmxData<HtmxAttributes> {
/**
* 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.
Expand All @@ -265,19 +258,19 @@ interface HtmxAttributes extends HtmxData<HtmxAttributes> {
/**
* 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<PropertyKey, unknown>;
/**
Expand Down Expand Up @@ -426,6 +419,5 @@ declare namespace JSX {
interface HtmlTag extends HtmxAttributes {}
}

// React (and other similar frameworks)
/** @ignore */
interface HTMLElement extends HtmxAttributes {}
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"include": ["./src/**/*"],
"include": ["src/**/*"],
"compilerOptions": {
"target": "es2022",
"module": "commonjs",
Expand Down

0 comments on commit c8be767

Please sign in to comment.