@ox-content/vite-plugin 2.89.0 → 3.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/jsx-html.cjs CHANGED
@@ -49,13 +49,33 @@ function escapeHtml(str) {
49
49
  return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#x27;");
50
50
  }
51
51
  /**
52
- * Converts a camelCase attribute name to kebab-case for HTML.
53
- * Special handling for data-* and aria-* attributes.
52
+ * React prop names whose HTML spelling is not the lowercased identifier.
53
+ */
54
+ const ATTR_ALIASES = {
55
+ className: "class",
56
+ htmlFor: "for",
57
+ httpEquiv: "http-equiv",
58
+ acceptCharset: "accept-charset"
59
+ };
60
+ /** SVG attributes that stay camelCase in HTML (they are case-sensitive). */
61
+ const SVG_CAMEL_CASE = /* @__PURE__ */ new Set(["viewBox"]);
62
+ /**
63
+ * Converts a JSX/React prop name to the HTML attribute the runtime emits.
64
+ *
65
+ * HTML attributes are case-insensitive and conventionally lowercase
66
+ * (`charSet` → `charset`, `tabIndex` → `tabindex`). A few React names are
67
+ * not a lowercase of themselves (`className`, `httpEquiv`), and SVG names
68
+ * like `viewBox` must keep their case.
54
69
  */
55
70
  function toHtmlAttr(name) {
56
- if (name === "className") return "class";
57
- if (name === "htmlFor") return "for";
71
+ const aliased = ATTR_ALIASES[name];
72
+ if (aliased !== void 0) return aliased;
73
+ if (SVG_CAMEL_CASE.has(name)) return name;
58
74
  if (name.startsWith("data") || name.startsWith("aria")) return name.replace(/([A-Z])/g, "-$1").toLowerCase();
75
+ if (/[A-Z]/.test(name)) {
76
+ if (name.startsWith("stroke") || name === "clipPath") return name.replace(/([A-Z])/g, "-$1").toLowerCase();
77
+ return name.toLowerCase();
78
+ }
59
79
  return name;
60
80
  }
61
81
  /**
@@ -94,10 +114,12 @@ function jsx(type, props, _key) {
94
114
  });
95
115
  const tag = type;
96
116
  let html = `<${tag}`;
117
+ const attrs = /* @__PURE__ */ new Map();
97
118
  for (const [name, value] of Object.entries(restProps)) {
98
119
  if (name === "key" || name === "ref") continue;
99
- html += renderAttr(name, value);
120
+ attrs.set(toHtmlAttr(name), value);
100
121
  }
122
+ for (const [name, value] of attrs) html += renderAttr(name, value);
101
123
  if (VOID_ELEMENTS.has(tag)) {
102
124
  html += " />";
103
125
  return { __html: html };
@@ -1 +1 @@
1
- {"version":3,"file":"jsx-html.cjs","names":[],"sources":["../src/jsx-html.ts"],"sourcesContent":["/**\n * Custom JSX Runtime for Static HTML Generation\n *\n * This module provides a JSX runtime that outputs static HTML strings.\n * No React, no hydration, no client-side JavaScript - just pure HTML.\n *\n * This is the implementation. The JSX transform imports it through the\n * ./jsx-runtime and ./jsx-dev-runtime entry points, which are the subpaths\n * `jsxImportSource` resolves. Keeping the implementation under its own name\n * keeps those two entries from colliding with the shared bundle chunk.\n *\n * @example\n * ```tsx\n * // tsconfig.json or vite.config.ts\n * {\n * \"compilerOptions\": {\n * \"jsx\": \"react-jsx\",\n * \"jsxImportSource\": \"@ox-content/vite-plugin\"\n * }\n * }\n *\n * // MyComponent.tsx\n * export function Hero({ title }: { title: string }) {\n * return (\n * <section class=\"hero\">\n * <h1>{title}</h1>\n * </section>\n * );\n * }\n * ```\n */\n\n// `jsxImportSource` makes TypeScript look for the element types in\n// `<source>/jsx-runtime` itself, so the namespace has to travel with the\n// runtime exports and not only be declared globally in ./jsx.d.ts.\nexport type { JSX } from \"./jsx\";\n\n// Self-closing tags that don't need closing tags\nconst VOID_ELEMENTS = new Set([\n \"area\",\n \"base\",\n \"br\",\n \"col\",\n \"embed\",\n \"hr\",\n \"img\",\n \"input\",\n \"link\",\n \"meta\",\n \"param\",\n \"source\",\n \"track\",\n \"wbr\",\n]);\n\n// Attributes that should be rendered as boolean\nconst BOOLEAN_ATTRS = new Set([\n \"allowfullscreen\",\n \"async\",\n \"autofocus\",\n \"autoplay\",\n \"checked\",\n \"controls\",\n \"default\",\n \"defer\",\n \"disabled\",\n \"formnovalidate\",\n \"hidden\",\n \"inert\",\n \"ismap\",\n \"itemscope\",\n \"loop\",\n \"multiple\",\n \"muted\",\n \"nomodule\",\n \"novalidate\",\n \"open\",\n \"playsinline\",\n \"readonly\",\n \"required\",\n \"reversed\",\n \"selected\",\n]);\n\n/**\n * Escapes HTML special characters to prevent XSS.\n */\nfunction escapeHtml(str: string): string {\n return str\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#x27;\");\n}\n\n/**\n * Converts a camelCase attribute name to kebab-case for HTML.\n * Special handling for data-* and aria-* attributes.\n */\nfunction toHtmlAttr(name: string): string {\n // className -> class\n if (name === \"className\") return \"class\";\n // htmlFor -> for\n if (name === \"htmlFor\") return \"for\";\n // Keep data-* and aria-* as-is\n if (name.startsWith(\"data\") || name.startsWith(\"aria\")) {\n return name.replace(/([A-Z])/g, \"-$1\").toLowerCase();\n }\n return name;\n}\n\n/**\n * Renders an attribute value to a string.\n */\nfunction renderAttr(name: string, value: unknown): string {\n const htmlName = toHtmlAttr(name);\n\n // Skip undefined, null, and false values\n if (value === undefined || value === null || value === false) {\n return \"\";\n }\n\n // Boolean attributes\n if (BOOLEAN_ATTRS.has(htmlName)) {\n return value ? ` ${htmlName}` : \"\";\n }\n\n // Style object to string\n if (name === \"style\" && typeof value === \"object\") {\n const styleStr = Object.entries(value as Record<string, string | number>)\n .map(([k, v]) => {\n const prop = k.replace(/([A-Z])/g, \"-$1\").toLowerCase();\n return `${prop}:${v}`;\n })\n .join(\";\");\n return ` style=\"${escapeHtml(styleStr)}\"`;\n }\n\n // Regular attribute\n return ` ${htmlName}=\"${escapeHtml(String(value as string | number | boolean))}\"`;\n}\n\n/**\n * JSX element type - either a string (intrinsic) or a function component.\n */\nexport type JSXElementType = string | ((props: Record<string, unknown>) => JSXNode);\n\n/**\n * Valid JSX child types.\n */\nexport type JSXChild = string | number | boolean | null | undefined | JSXNode | JSXChild[];\n\n/**\n * JSX node - the result of JSX expressions.\n */\nexport interface JSXNode {\n __html: string;\n}\n\n/**\n * Props with children.\n */\nexport interface JSXProps {\n children?: JSXChild;\n [key: string]: unknown;\n}\n\n/**\n * Renders children to HTML string.\n */\nfunction renderChildren(children: JSXChild): string {\n if (children === null || children === undefined || children === false) {\n return \"\";\n }\n\n if (children === true) {\n return \"\";\n }\n\n if (typeof children === \"string\") {\n return escapeHtml(children);\n }\n\n if (typeof children === \"number\") {\n return String(children);\n }\n\n if (Array.isArray(children)) {\n return children.map(renderChildren).join(\"\");\n }\n\n if (typeof children === \"object\" && \"__html\" in children) {\n return children.__html;\n }\n\n return \"\";\n}\n\n/**\n * Creates a JSX element.\n * This is the core function called by the JSX transform.\n */\nexport function jsx(type: JSXElementType, props: JSXProps, _key?: string): JSXNode {\n const { children, ...restProps } = props;\n\n // Function component\n if (typeof type === \"function\") {\n return type({ ...restProps, children });\n }\n\n // Intrinsic element (HTML tag)\n const tag = type;\n let html = `<${tag}`;\n\n // Render attributes\n for (const [name, value] of Object.entries(restProps)) {\n // Skip internal props\n if (name === \"key\" || name === \"ref\") continue;\n html += renderAttr(name, value);\n }\n\n // Self-closing tags\n if (VOID_ELEMENTS.has(tag)) {\n html += \" />\";\n return { __html: html };\n }\n\n html += \">\";\n\n // Render children\n if (children !== undefined) {\n html += renderChildren(children);\n }\n\n html += `</${tag}>`;\n\n return { __html: html };\n}\n\n/**\n * Creates a JSX element with static children.\n * Called by the JSX transform for elements with multiple children.\n */\nexport function jsxs(type: JSXElementType, props: JSXProps, key?: string): JSXNode {\n return jsx(type, props, key);\n}\n\n/**\n * Fragment component - renders children without a wrapper element.\n */\nexport function Fragment({ children }: { children?: JSXChild }): JSXNode {\n return { __html: renderChildren(children) };\n}\n\n/**\n * Renders a JSX node to an HTML string.\n */\nexport function renderToString(node: JSXNode): string {\n return node.__html;\n}\n\n/**\n * Creates raw HTML without escaping.\n * Use with caution - only for trusted content.\n *\n * @example\n * ```tsx\n * <div>{raw('<strong>Bold</strong>')}</div>\n * ```\n */\nexport function raw(html: string): JSXNode {\n return { __html: html };\n}\n\n/**\n * Conditionally renders content.\n *\n * @example\n * ```tsx\n * {when(isLoggedIn, <UserMenu />)}\n * ```\n */\nexport function when(condition: boolean, content: JSXNode): JSXNode {\n return condition ? content : { __html: \"\" };\n}\n\n/**\n * Maps over an array and renders each item.\n *\n * @example\n * ```tsx\n * {each(items, (item) => <li>{item.name}</li>)}\n * ```\n */\nexport function each<T>(items: T[], render: (item: T, index: number) => JSXNode): JSXNode {\n const html = items.map((item, i) => render(item, i).__html).join(\"\");\n return { __html: html };\n}\n\n// Default export for convenience\nexport default {\n jsx,\n jsxs,\n Fragment,\n renderToString,\n raw,\n when,\n each,\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"jsx-html.cjs","names":[],"sources":["../src/jsx-html.ts"],"sourcesContent":["/**\n * Custom JSX Runtime for Static HTML Generation\n *\n * This module provides a JSX runtime that outputs static HTML strings.\n * No React, no hydration, no client-side JavaScript - just pure HTML.\n *\n * This is the implementation. The JSX transform imports it through the\n * ./jsx-runtime and ./jsx-dev-runtime entry points, which are the subpaths\n * `jsxImportSource` resolves. Keeping the implementation under its own name\n * keeps those two entries from colliding with the shared bundle chunk.\n *\n * @example\n * ```tsx\n * // tsconfig.json or vite.config.ts\n * {\n * \"compilerOptions\": {\n * \"jsx\": \"react-jsx\",\n * \"jsxImportSource\": \"@ox-content/vite-plugin\"\n * }\n * }\n *\n * // MyComponent.tsx\n * export function Hero({ title }: { title: string }) {\n * return (\n * <section class=\"hero\">\n * <h1>{title}</h1>\n * </section>\n * );\n * }\n * ```\n */\n\n// `jsxImportSource` makes TypeScript look for the element types in\n// `<source>/jsx-runtime` itself, so the namespace has to travel with the\n// runtime exports and not only be declared globally in ./jsx.d.ts.\nexport type { JSX } from \"./jsx\";\n\n// Self-closing tags that don't need closing tags\nconst VOID_ELEMENTS = new Set([\n \"area\",\n \"base\",\n \"br\",\n \"col\",\n \"embed\",\n \"hr\",\n \"img\",\n \"input\",\n \"link\",\n \"meta\",\n \"param\",\n \"source\",\n \"track\",\n \"wbr\",\n]);\n\n// Attributes that should be rendered as boolean\nconst BOOLEAN_ATTRS = new Set([\n \"allowfullscreen\",\n \"async\",\n \"autofocus\",\n \"autoplay\",\n \"checked\",\n \"controls\",\n \"default\",\n \"defer\",\n \"disabled\",\n \"formnovalidate\",\n \"hidden\",\n \"inert\",\n \"ismap\",\n \"itemscope\",\n \"loop\",\n \"multiple\",\n \"muted\",\n \"nomodule\",\n \"novalidate\",\n \"open\",\n \"playsinline\",\n \"readonly\",\n \"required\",\n \"reversed\",\n \"selected\",\n]);\n\n/**\n * Escapes HTML special characters to prevent XSS.\n */\nfunction escapeHtml(str: string): string {\n return str\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#x27;\");\n}\n\n/**\n * React prop names whose HTML spelling is not the lowercased identifier.\n */\nconst ATTR_ALIASES: Record<string, string> = {\n className: \"class\",\n htmlFor: \"for\",\n httpEquiv: \"http-equiv\",\n acceptCharset: \"accept-charset\",\n};\n\n/** SVG attributes that stay camelCase in HTML (they are case-sensitive). */\nconst SVG_CAMEL_CASE = new Set([\"viewBox\"]);\n\n/**\n * Converts a JSX/React prop name to the HTML attribute the runtime emits.\n *\n * HTML attributes are case-insensitive and conventionally lowercase\n * (`charSet` → `charset`, `tabIndex` → `tabindex`). A few React names are\n * not a lowercase of themselves (`className`, `httpEquiv`), and SVG names\n * like `viewBox` must keep their case.\n */\nfunction toHtmlAttr(name: string): string {\n const aliased = ATTR_ALIASES[name];\n if (aliased !== undefined) return aliased;\n if (SVG_CAMEL_CASE.has(name)) return name;\n if (name.startsWith(\"data\") || name.startsWith(\"aria\")) {\n return name.replace(/([A-Z])/g, \"-$1\").toLowerCase();\n }\n if (/[A-Z]/.test(name)) {\n // SVG presentation attributes are kebab-case; remaining HTML names are\n // just the lowercased identifier (`charSet` → `charset`).\n if (name.startsWith(\"stroke\") || name === \"clipPath\") {\n return name.replace(/([A-Z])/g, \"-$1\").toLowerCase();\n }\n return name.toLowerCase();\n }\n return name;\n}\n\n/**\n * Renders an attribute value to a string.\n */\nfunction renderAttr(name: string, value: unknown): string {\n const htmlName = toHtmlAttr(name);\n\n // Skip undefined, null, and false values\n if (value === undefined || value === null || value === false) {\n return \"\";\n }\n\n // Boolean attributes\n if (BOOLEAN_ATTRS.has(htmlName)) {\n return value ? ` ${htmlName}` : \"\";\n }\n\n // Style object to string\n if (name === \"style\" && typeof value === \"object\") {\n const styleStr = Object.entries(value as Record<string, string | number>)\n .map(([k, v]) => {\n const prop = k.replace(/([A-Z])/g, \"-$1\").toLowerCase();\n return `${prop}:${v}`;\n })\n .join(\";\");\n return ` style=\"${escapeHtml(styleStr)}\"`;\n }\n\n // Regular attribute\n return ` ${htmlName}=\"${escapeHtml(String(value as string | number | boolean))}\"`;\n}\n\n/**\n * JSX element type - either a string (intrinsic) or a function component.\n */\nexport type JSXElementType = string | ((props: Record<string, unknown>) => JSXNode);\n\n/**\n * Valid JSX child types.\n */\nexport type JSXChild = string | number | boolean | null | undefined | JSXNode | JSXChild[];\n\n/**\n * JSX node - the result of JSX expressions.\n */\nexport interface JSXNode {\n __html: string;\n}\n\n/**\n * Props with children.\n */\nexport interface JSXProps {\n children?: JSXChild;\n [key: string]: unknown;\n}\n\n/**\n * Renders children to HTML string.\n */\nfunction renderChildren(children: JSXChild): string {\n if (children === null || children === undefined || children === false) {\n return \"\";\n }\n\n if (children === true) {\n return \"\";\n }\n\n if (typeof children === \"string\") {\n return escapeHtml(children);\n }\n\n if (typeof children === \"number\") {\n return String(children);\n }\n\n if (Array.isArray(children)) {\n return children.map(renderChildren).join(\"\");\n }\n\n if (typeof children === \"object\" && \"__html\" in children) {\n return children.__html;\n }\n\n return \"\";\n}\n\n/**\n * Creates a JSX element.\n * This is the core function called by the JSX transform.\n */\nexport function jsx(type: JSXElementType, props: JSXProps, _key?: string): JSXNode {\n const { children, ...restProps } = props;\n\n // Function component\n if (typeof type === \"function\") {\n return type({ ...restProps, children });\n }\n\n // Intrinsic element (HTML tag)\n const tag = type;\n let html = `<${tag}`;\n\n // Normalize React aliases first so `class` + `className` become one attribute\n // (last write wins) instead of emitting `class` twice.\n const attrs = new Map<string, unknown>();\n for (const [name, value] of Object.entries(restProps)) {\n if (name === \"key\" || name === \"ref\") continue;\n attrs.set(toHtmlAttr(name), value);\n }\n for (const [name, value] of attrs) {\n html += renderAttr(name, value);\n }\n\n // Self-closing tags\n if (VOID_ELEMENTS.has(tag)) {\n html += \" />\";\n return { __html: html };\n }\n\n html += \">\";\n\n // Render children\n if (children !== undefined) {\n html += renderChildren(children);\n }\n\n html += `</${tag}>`;\n\n return { __html: html };\n}\n\n/**\n * Creates a JSX element with static children.\n * Called by the JSX transform for elements with multiple children.\n */\nexport function jsxs(type: JSXElementType, props: JSXProps, key?: string): JSXNode {\n return jsx(type, props, key);\n}\n\n/**\n * Fragment component - renders children without a wrapper element.\n */\nexport function Fragment({ children }: { children?: JSXChild }): JSXNode {\n return { __html: renderChildren(children) };\n}\n\n/**\n * Renders a JSX node to an HTML string.\n */\nexport function renderToString(node: JSXNode): string {\n return node.__html;\n}\n\n/**\n * Creates raw HTML without escaping.\n * Use with caution - only for trusted content.\n *\n * @example\n * ```tsx\n * <div>{raw('<strong>Bold</strong>')}</div>\n * ```\n */\nexport function raw(html: string): JSXNode {\n return { __html: html };\n}\n\n/**\n * Conditionally renders content.\n *\n * @example\n * ```tsx\n * {when(isLoggedIn, <UserMenu />)}\n * ```\n */\nexport function when(condition: boolean, content: JSXNode): JSXNode {\n return condition ? content : { __html: \"\" };\n}\n\n/**\n * Maps over an array and renders each item.\n *\n * @example\n * ```tsx\n * {each(items, (item) => <li>{item.name}</li>)}\n * ```\n */\nexport function each<T>(items: T[], render: (item: T, index: number) => JSXNode): JSXNode {\n const html = items.map((item, i) => render(item, i).__html).join(\"\");\n return { __html: html };\n}\n\n// Default export for convenience\nexport default {\n jsx,\n jsxs,\n Fragment,\n renderToString,\n raw,\n when,\n each,\n};\n"],"mappings":"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"}
@@ -299,8 +299,10 @@ declare namespace JSX {
299
299
  type?: string;
300
300
  }
301
301
  export interface MetaHTMLAttributes extends HTMLAttributes {
302
+ charset?: string;
302
303
  charSet?: string;
303
304
  content?: string;
305
+ "http-equiv"?: string;
304
306
  httpEquiv?: string;
305
307
  name?: string;
306
308
  property?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"jsx-html.d.cts","names":[],"sources":["../src/jsx.d.ts","../src/jsx-html.ts"],"mappings":";kBAQiB;;;;cAIH,UAAU;;;;;;;mBAQL;IACf;;;;;mBAMe;;IAEf,MAAM;IACN,MAAM;IACN,OAAO;IACP,MAAM;IACN,MAAM;IACN,MAAM;IACN,OAAO;;IAGP,MAAM;IACN,SAAS;IACT,SAAS;IACT,KAAK;IACL,OAAO;IACP,QAAQ;IACR,QAAQ;IACR,MAAM;IACN,SAAS;;IAGT,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,QAAQ;;IAGR,GAAG;IACH,IAAI;IACJ,KAAK;IACL,YAAY;IACZ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,QAAQ;IACR,YAAY;IACZ,KAAK;;IAGL,GAAG;IACH,IAAI;IACJ,QAAQ;IACR,OAAO;IACP,GAAG;IACH,MAAM;IACN,GAAG;IACH,KAAK;IACL,MAAM;IACN,MAAM;IACN,IAAI;IACJ,IAAI;IACJ,MAAM;IACN,MAAM;IACN,MAAM;IACN,KAAK;IACL,MAAM;IACN,KAAK;IACL,KAAK;IACL,KAAK;IACL,GAAG;IACH,GAAG;IACH,GAAG;IACH,MAAM;IACN,KAAK;IACL,KAAK;IACL,MAAM;IACN,IAAI;IACJ,KAAK;;IAGL,KAAK;IACL,KAAK;;IAGL,SAAS;IACT,QAAQ;IACR,KAAK;IACL,QAAQ;IACR,OAAO;IACP,QAAQ;IACR,OAAO;IACP,OAAO;IACP,OAAO;IACP,OAAO;IACP,KAAK;IACL,MAAM;;IAGN,KAAK;IACL,MAAM;IACN,QAAQ;IACR,SAAS;IACT,MAAM;IACN,SAAS;IACT,UAAU;IACV,MAAM;IACN,GAAG;IACH,MAAM;IACN,QAAQ;IACR,KAAK;IACL,MAAM;IACN,OAAO;IACP,OAAO;IACP,UAAU;IACV,MAAM;IACN,SAAS;IACT,gBAAgB;IAChB,gBAAgB;IAChB,MAAM;IACN,QAAQ;IACR,SAAS;IACT,eAAe;IACf,qBAAqB;IACrB,aAAa;IACb,kBAAkB;IAClB,mBAAmB;IACnB,mBAAmB;IACnB,SAAS;IACT,gBAAgB;IAChB,SAAS;IACT,SAAS;IACT,aAAa;IACb,cAAc;IACd,UAAU;IACV,oBAAoB;IACpB,QAAQ;IACR,cAAc;;IAGd,OAAO;IACP,SAAS;IACT,UAAU;IACV,KAAK;IACL,OAAO;IACP,OAAO;IACP,OAAO;IACP,IAAI;IACJ,IAAI;IACJ,IAAI;;IAGJ,MAAM;IACN,OAAO;IACP,OAAO;IACP,QAAQ;IACR,QAAQ;IACR,UAAU;IACV,UAAU;IACV,QAAQ;IACR,UAAU;IACV,QAAQ;IACR,UAAU;IACV,OAAO;IACP,UAAU;IACV,QAAQ;;IAGR,SAAS;IACT,SAAS;IACT,QAAQ;IACR,MAAM;;IAGN,QAAQ;IACR,UAAU;IACV,UAAU;IACV,MAAM;IACN,QAAQ;;;;;mBAMO;;;;;;;IAOf;;IAGA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA,iBAAiB;IACjB;IACA;IACA;;KAGC;;IAGD;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IAWA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;IAGA,WAAW;;;mBAII,2BAA2B;IAC1C;;mBAGe,2BAA2B;IAC1C;IACA;;mBAGe,2BAA2B;IAC1C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,2BAA2B;IAC1C;IACA;IACA;IACA;IACA;;mBAGe,4BAA4B;IAC3C;IACA;IACA;;mBAGe,iCAAiC;IAChD;;mBAGe,yBAAyB;IACxC;IACA;IACA;;mBAGe,yBAAyB;IACxC;;mBAGe,6BAA6B;IAC5C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,4BAA4B;IAC3C;;mBAGe,2BAA2B;IAC1C;;mBAGe,2BAA2B;IAC1C;;mBAGe,0BAA0B;IACzC;IACA;;mBAGe,0BAA0B;IACzC;IACA;;mBAGe,6BAA6B;IAC5C;IACA;IACA;IACA;IACA;;mBAGe,0BAA0B;IACzC;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,6BAA6B;IAC5C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,4BAA4B;IAC3C;IACA;IACA;IACA;;mBAGe,6BAA6B;IAC5C;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,4BAA4B;IAC3C;IACA;;mBAGe,4BAA4B;IAC3C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,4BAA4B;IAC3C;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,4BAA4B;IAC3C;IACA;IACA;IACA;IACA;;mBAGe,0BAA0B;IACzC;;mBAGe,2BAA2B;IAC1C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,4BAA4B;IAC3C;IACA;;mBAGe,+BAA+B;IAC9C;;mBAGe,0BAA0B;IACzC;;mBAGe,yBAAyB;IACxC;IACA;IACA;;mBAGe,yBAAyB;IACxC;IACA;IACA;IACA;IACA;;mBAGe,2BAA2B;IAC1C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,4BAA4B;IAC3C;IACA;;mBAGe,4BAA4B;IAC3C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,6BAA6B;IAC5C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,6BAA6B;IAC5C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,+BAA+B;IAC9C;IACA;;mBAGe,6BAA6B;IAC5C;IACA;IACA;IACA;;mBAGe,+BAA+B;IAC9C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,6BAA6B;IAC5C;IACA;IACA;;mBAGe,+BAA+B;IAC9C;IACA;;mBAGe,4BAA4B;IAC3C;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,+BAA+B;IAC9C;IACA;IACA;;mBAGe,8BAA8B;IAC7C;;mBAGe,6BAA6B;IAC5C;;mBAGe,2BAA2B;IAC1C;;mBAGe,6BAA6B;IAC5C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,2BAA2B;IAC1C;;mBAGe,6BAA6B;IAC5C;IACA;;mBAGe,sBAAsB;;IAErC;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;;;;cAMU,6BAA6B;;;;cAK7B,sBAAsB,UAAU,wBAAwB,kBAAkB;;KAGnF,8BAAA,IAAuD;KACvD,gCAAA,IAAyD;QAEtD;YACI;SACH,UAA+B;cAC1B,0BAA0B;cAC1B,4BAA4B;;;;;;;;KCplB9B,4BAA4B,OAAO,4BAA4B;;;;KAK/D,0DAA0D,UAAU;;;;UAK/D;EACf;;;;;UAMe;EACf,WAAW;GACV;;;;;;iBAsCa,IAAI,MAAM,gBAAgB,OAAO,UAAU,gBAAgB;;;;;iBAyC3D,KAAK,MAAM,gBAAgB,OAAO,UAAU,eAAe;;;;iBAO3D,WAAW;EAAc,WAAW;IAAa;;;;iBAOjD,eAAe,MAAM;;;;;;;;;;iBAarB,IAAI,eAAe;;;;;;;;;iBAYnB,KAAK,oBAAoB,SAAS,UAAU;;;;;;;;;iBAY5C,KAAK,GAAG,OAAO,KAAK,SAAS,MAAM,GAAG,kBAAkB,UAAU"}
1
+ {"version":3,"file":"jsx-html.d.cts","names":[],"sources":["../src/jsx.d.ts","../src/jsx-html.ts"],"mappings":";kBAQiB;;;;cAIH,UAAU;;;;;;;mBAQL;IACf;;;;;mBAMe;;IAEf,MAAM;IACN,MAAM;IACN,OAAO;IACP,MAAM;IACN,MAAM;IACN,MAAM;IACN,OAAO;;IAGP,MAAM;IACN,SAAS;IACT,SAAS;IACT,KAAK;IACL,OAAO;IACP,QAAQ;IACR,QAAQ;IACR,MAAM;IACN,SAAS;;IAGT,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,QAAQ;;IAGR,GAAG;IACH,IAAI;IACJ,KAAK;IACL,YAAY;IACZ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,QAAQ;IACR,YAAY;IACZ,KAAK;;IAGL,GAAG;IACH,IAAI;IACJ,QAAQ;IACR,OAAO;IACP,GAAG;IACH,MAAM;IACN,GAAG;IACH,KAAK;IACL,MAAM;IACN,MAAM;IACN,IAAI;IACJ,IAAI;IACJ,MAAM;IACN,MAAM;IACN,MAAM;IACN,KAAK;IACL,MAAM;IACN,KAAK;IACL,KAAK;IACL,KAAK;IACL,GAAG;IACH,GAAG;IACH,GAAG;IACH,MAAM;IACN,KAAK;IACL,KAAK;IACL,MAAM;IACN,IAAI;IACJ,KAAK;;IAGL,KAAK;IACL,KAAK;;IAGL,SAAS;IACT,QAAQ;IACR,KAAK;IACL,QAAQ;IACR,OAAO;IACP,QAAQ;IACR,OAAO;IACP,OAAO;IACP,OAAO;IACP,OAAO;IACP,KAAK;IACL,MAAM;;IAGN,KAAK;IACL,MAAM;IACN,QAAQ;IACR,SAAS;IACT,MAAM;IACN,SAAS;IACT,UAAU;IACV,MAAM;IACN,GAAG;IACH,MAAM;IACN,QAAQ;IACR,KAAK;IACL,MAAM;IACN,OAAO;IACP,OAAO;IACP,UAAU;IACV,MAAM;IACN,SAAS;IACT,gBAAgB;IAChB,gBAAgB;IAChB,MAAM;IACN,QAAQ;IACR,SAAS;IACT,eAAe;IACf,qBAAqB;IACrB,aAAa;IACb,kBAAkB;IAClB,mBAAmB;IACnB,mBAAmB;IACnB,SAAS;IACT,gBAAgB;IAChB,SAAS;IACT,SAAS;IACT,aAAa;IACb,cAAc;IACd,UAAU;IACV,oBAAoB;IACpB,QAAQ;IACR,cAAc;;IAGd,OAAO;IACP,SAAS;IACT,UAAU;IACV,KAAK;IACL,OAAO;IACP,OAAO;IACP,OAAO;IACP,IAAI;IACJ,IAAI;IACJ,IAAI;;IAGJ,MAAM;IACN,OAAO;IACP,OAAO;IACP,QAAQ;IACR,QAAQ;IACR,UAAU;IACV,UAAU;IACV,QAAQ;IACR,UAAU;IACV,QAAQ;IACR,UAAU;IACV,OAAO;IACP,UAAU;IACV,QAAQ;;IAGR,SAAS;IACT,SAAS;IACT,QAAQ;IACR,MAAM;;IAGN,QAAQ;IACR,UAAU;IACV,UAAU;IACV,MAAM;IACN,QAAQ;;;;;mBAMO;;;;;;;IAOf;;IAGA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA,iBAAiB;IACjB;IACA;IACA;;KAGC;;IAGD;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IAWA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;IAGA,WAAW;;;mBAII,2BAA2B;IAC1C;;mBAGe,2BAA2B;IAC1C;IACA;;mBAGe,2BAA2B;IAC1C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,2BAA2B;IAC1C;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,4BAA4B;IAC3C;IACA;IACA;;mBAGe,iCAAiC;IAChD;;mBAGe,yBAAyB;IACxC;IACA;IACA;;mBAGe,yBAAyB;IACxC;;mBAGe,6BAA6B;IAC5C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,4BAA4B;IAC3C;;mBAGe,2BAA2B;IAC1C;;mBAGe,2BAA2B;IAC1C;;mBAGe,0BAA0B;IACzC;IACA;;mBAGe,0BAA0B;IACzC;IACA;;mBAGe,6BAA6B;IAC5C;IACA;IACA;IACA;IACA;;mBAGe,0BAA0B;IACzC;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,6BAA6B;IAC5C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,4BAA4B;IAC3C;IACA;IACA;IACA;;mBAGe,6BAA6B;IAC5C;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,4BAA4B;IAC3C;IACA;;mBAGe,4BAA4B;IAC3C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,4BAA4B;IAC3C;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,4BAA4B;IAC3C;IACA;IACA;IACA;IACA;;mBAGe,0BAA0B;IACzC;;mBAGe,2BAA2B;IAC1C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,4BAA4B;IAC3C;IACA;;mBAGe,+BAA+B;IAC9C;;mBAGe,0BAA0B;IACzC;;mBAGe,yBAAyB;IACxC;IACA;IACA;;mBAGe,yBAAyB;IACxC;IACA;IACA;IACA;IACA;;mBAGe,2BAA2B;IAC1C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,4BAA4B;IAC3C;IACA;;mBAGe,4BAA4B;IAC3C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,6BAA6B;IAC5C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,6BAA6B;IAC5C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,+BAA+B;IAC9C;IACA;;mBAGe,6BAA6B;IAC5C;IACA;IACA;IACA;;mBAGe,+BAA+B;IAC9C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,6BAA6B;IAC5C;IACA;IACA;;mBAGe,+BAA+B;IAC9C;IACA;;mBAGe,4BAA4B;IAC3C;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,+BAA+B;IAC9C;IACA;IACA;;mBAGe,8BAA8B;IAC7C;;mBAGe,6BAA6B;IAC5C;;mBAGe,2BAA2B;IAC1C;;mBAGe,6BAA6B;IAC5C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,2BAA2B;IAC1C;;mBAGe,6BAA6B;IAC5C;IACA;;mBAGe,sBAAsB;;IAErC;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;;;;cAMU,6BAA6B;;;;cAK7B,sBAAsB,UAAU,wBAAwB,kBAAkB;;KAGnF,8BAAA,IAAuD;KACvD,gCAAA,IAAyD;QAEtD;YACI;SACH,UAA+B;cAC1B,0BAA0B;cAC1B,4BAA4B;;;;;;;;KC/jB9B,4BAA4B,OAAO,4BAA4B;;;;KAK/D,0DAA0D,UAAU;;;;UAK/D;EACf;;;;;UAMe;EACf,WAAW;GACV;;;;;;iBAsCa,IAAI,MAAM,gBAAgB,OAAO,UAAU,gBAAgB;;;;;iBA6C3D,KAAK,MAAM,gBAAgB,OAAO,UAAU,eAAe;;;;iBAO3D,WAAW;EAAc,WAAW;IAAa;;;;iBAOjD,eAAe,MAAM;;;;;;;;;;iBAarB,IAAI,eAAe;;;;;;;;;iBAYnB,KAAK,oBAAoB,SAAS,UAAU;;;;;;;;;iBAY5C,KAAK,GAAG,OAAO,KAAK,SAAS,MAAM,GAAG,kBAAkB,UAAU"}
@@ -299,8 +299,10 @@ declare namespace JSX {
299
299
  type?: string;
300
300
  }
301
301
  export interface MetaHTMLAttributes extends HTMLAttributes {
302
+ charset?: string;
302
303
  charSet?: string;
303
304
  content?: string;
305
+ "http-equiv"?: string;
304
306
  httpEquiv?: string;
305
307
  name?: string;
306
308
  property?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"jsx-html.d.mts","names":[],"sources":["../src/jsx.d.ts","../src/jsx-html.ts"],"mappings":";kBAQiB;;;;cAIH,UAAU;;;;;;;mBAQL;IACf;;;;;mBAMe;;IAEf,MAAM;IACN,MAAM;IACN,OAAO;IACP,MAAM;IACN,MAAM;IACN,MAAM;IACN,OAAO;;IAGP,MAAM;IACN,SAAS;IACT,SAAS;IACT,KAAK;IACL,OAAO;IACP,QAAQ;IACR,QAAQ;IACR,MAAM;IACN,SAAS;;IAGT,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,QAAQ;;IAGR,GAAG;IACH,IAAI;IACJ,KAAK;IACL,YAAY;IACZ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,QAAQ;IACR,YAAY;IACZ,KAAK;;IAGL,GAAG;IACH,IAAI;IACJ,QAAQ;IACR,OAAO;IACP,GAAG;IACH,MAAM;IACN,GAAG;IACH,KAAK;IACL,MAAM;IACN,MAAM;IACN,IAAI;IACJ,IAAI;IACJ,MAAM;IACN,MAAM;IACN,MAAM;IACN,KAAK;IACL,MAAM;IACN,KAAK;IACL,KAAK;IACL,KAAK;IACL,GAAG;IACH,GAAG;IACH,GAAG;IACH,MAAM;IACN,KAAK;IACL,KAAK;IACL,MAAM;IACN,IAAI;IACJ,KAAK;;IAGL,KAAK;IACL,KAAK;;IAGL,SAAS;IACT,QAAQ;IACR,KAAK;IACL,QAAQ;IACR,OAAO;IACP,QAAQ;IACR,OAAO;IACP,OAAO;IACP,OAAO;IACP,OAAO;IACP,KAAK;IACL,MAAM;;IAGN,KAAK;IACL,MAAM;IACN,QAAQ;IACR,SAAS;IACT,MAAM;IACN,SAAS;IACT,UAAU;IACV,MAAM;IACN,GAAG;IACH,MAAM;IACN,QAAQ;IACR,KAAK;IACL,MAAM;IACN,OAAO;IACP,OAAO;IACP,UAAU;IACV,MAAM;IACN,SAAS;IACT,gBAAgB;IAChB,gBAAgB;IAChB,MAAM;IACN,QAAQ;IACR,SAAS;IACT,eAAe;IACf,qBAAqB;IACrB,aAAa;IACb,kBAAkB;IAClB,mBAAmB;IACnB,mBAAmB;IACnB,SAAS;IACT,gBAAgB;IAChB,SAAS;IACT,SAAS;IACT,aAAa;IACb,cAAc;IACd,UAAU;IACV,oBAAoB;IACpB,QAAQ;IACR,cAAc;;IAGd,OAAO;IACP,SAAS;IACT,UAAU;IACV,KAAK;IACL,OAAO;IACP,OAAO;IACP,OAAO;IACP,IAAI;IACJ,IAAI;IACJ,IAAI;;IAGJ,MAAM;IACN,OAAO;IACP,OAAO;IACP,QAAQ;IACR,QAAQ;IACR,UAAU;IACV,UAAU;IACV,QAAQ;IACR,UAAU;IACV,QAAQ;IACR,UAAU;IACV,OAAO;IACP,UAAU;IACV,QAAQ;;IAGR,SAAS;IACT,SAAS;IACT,QAAQ;IACR,MAAM;;IAGN,QAAQ;IACR,UAAU;IACV,UAAU;IACV,MAAM;IACN,QAAQ;;;;;mBAMO;;;;;;;IAOf;;IAGA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA,iBAAiB;IACjB;IACA;IACA;;KAGC;;IAGD;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IAWA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;IAGA,WAAW;;;mBAII,2BAA2B;IAC1C;;mBAGe,2BAA2B;IAC1C;IACA;;mBAGe,2BAA2B;IAC1C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,2BAA2B;IAC1C;IACA;IACA;IACA;IACA;;mBAGe,4BAA4B;IAC3C;IACA;IACA;;mBAGe,iCAAiC;IAChD;;mBAGe,yBAAyB;IACxC;IACA;IACA;;mBAGe,yBAAyB;IACxC;;mBAGe,6BAA6B;IAC5C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,4BAA4B;IAC3C;;mBAGe,2BAA2B;IAC1C;;mBAGe,2BAA2B;IAC1C;;mBAGe,0BAA0B;IACzC;IACA;;mBAGe,0BAA0B;IACzC;IACA;;mBAGe,6BAA6B;IAC5C;IACA;IACA;IACA;IACA;;mBAGe,0BAA0B;IACzC;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,6BAA6B;IAC5C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,4BAA4B;IAC3C;IACA;IACA;IACA;;mBAGe,6BAA6B;IAC5C;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,4BAA4B;IAC3C;IACA;;mBAGe,4BAA4B;IAC3C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,4BAA4B;IAC3C;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,4BAA4B;IAC3C;IACA;IACA;IACA;IACA;;mBAGe,0BAA0B;IACzC;;mBAGe,2BAA2B;IAC1C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,4BAA4B;IAC3C;IACA;;mBAGe,+BAA+B;IAC9C;;mBAGe,0BAA0B;IACzC;;mBAGe,yBAAyB;IACxC;IACA;IACA;;mBAGe,yBAAyB;IACxC;IACA;IACA;IACA;IACA;;mBAGe,2BAA2B;IAC1C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,4BAA4B;IAC3C;IACA;;mBAGe,4BAA4B;IAC3C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,6BAA6B;IAC5C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,6BAA6B;IAC5C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,+BAA+B;IAC9C;IACA;;mBAGe,6BAA6B;IAC5C;IACA;IACA;IACA;;mBAGe,+BAA+B;IAC9C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,6BAA6B;IAC5C;IACA;IACA;;mBAGe,+BAA+B;IAC9C;IACA;;mBAGe,4BAA4B;IAC3C;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,+BAA+B;IAC9C;IACA;IACA;;mBAGe,8BAA8B;IAC7C;;mBAGe,6BAA6B;IAC5C;;mBAGe,2BAA2B;IAC1C;;mBAGe,6BAA6B;IAC5C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,2BAA2B;IAC1C;;mBAGe,6BAA6B;IAC5C;IACA;;mBAGe,sBAAsB;;IAErC;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;;;;cAMU,6BAA6B;;;;cAK7B,sBAAsB,UAAU,wBAAwB,kBAAkB;;KAGnF,8BAAA,IAAuD;KACvD,gCAAA,IAAyD;QAEtD;YACI;SACH,UAA+B;cAC1B,0BAA0B;cAC1B,4BAA4B;;;;;;;;KCplB9B,4BAA4B,OAAO,4BAA4B;;;;KAK/D,0DAA0D,UAAU;;;;UAK/D;EACf;;;;;UAMe;EACf,WAAW;GACV;;;;;;iBAsCa,IAAI,MAAM,gBAAgB,OAAO,UAAU,gBAAgB;;;;;iBAyC3D,KAAK,MAAM,gBAAgB,OAAO,UAAU,eAAe;;;;iBAO3D,WAAW;EAAc,WAAW;IAAa;;;;iBAOjD,eAAe,MAAM;;;;;;;;;;iBAarB,IAAI,eAAe;;;;;;;;;iBAYnB,KAAK,oBAAoB,SAAS,UAAU;;;;;;;;;iBAY5C,KAAK,GAAG,OAAO,KAAK,SAAS,MAAM,GAAG,kBAAkB,UAAU"}
1
+ {"version":3,"file":"jsx-html.d.mts","names":[],"sources":["../src/jsx.d.ts","../src/jsx-html.ts"],"mappings":";kBAQiB;;;;cAIH,UAAU;;;;;;;mBAQL;IACf;;;;;mBAMe;;IAEf,MAAM;IACN,MAAM;IACN,OAAO;IACP,MAAM;IACN,MAAM;IACN,MAAM;IACN,OAAO;;IAGP,MAAM;IACN,SAAS;IACT,SAAS;IACT,KAAK;IACL,OAAO;IACP,QAAQ;IACR,QAAQ;IACR,MAAM;IACN,SAAS;;IAGT,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,QAAQ;;IAGR,GAAG;IACH,IAAI;IACJ,KAAK;IACL,YAAY;IACZ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,QAAQ;IACR,YAAY;IACZ,KAAK;;IAGL,GAAG;IACH,IAAI;IACJ,QAAQ;IACR,OAAO;IACP,GAAG;IACH,MAAM;IACN,GAAG;IACH,KAAK;IACL,MAAM;IACN,MAAM;IACN,IAAI;IACJ,IAAI;IACJ,MAAM;IACN,MAAM;IACN,MAAM;IACN,KAAK;IACL,MAAM;IACN,KAAK;IACL,KAAK;IACL,KAAK;IACL,GAAG;IACH,GAAG;IACH,GAAG;IACH,MAAM;IACN,KAAK;IACL,KAAK;IACL,MAAM;IACN,IAAI;IACJ,KAAK;;IAGL,KAAK;IACL,KAAK;;IAGL,SAAS;IACT,QAAQ;IACR,KAAK;IACL,QAAQ;IACR,OAAO;IACP,QAAQ;IACR,OAAO;IACP,OAAO;IACP,OAAO;IACP,OAAO;IACP,KAAK;IACL,MAAM;;IAGN,KAAK;IACL,MAAM;IACN,QAAQ;IACR,SAAS;IACT,MAAM;IACN,SAAS;IACT,UAAU;IACV,MAAM;IACN,GAAG;IACH,MAAM;IACN,QAAQ;IACR,KAAK;IACL,MAAM;IACN,OAAO;IACP,OAAO;IACP,UAAU;IACV,MAAM;IACN,SAAS;IACT,gBAAgB;IAChB,gBAAgB;IAChB,MAAM;IACN,QAAQ;IACR,SAAS;IACT,eAAe;IACf,qBAAqB;IACrB,aAAa;IACb,kBAAkB;IAClB,mBAAmB;IACnB,mBAAmB;IACnB,SAAS;IACT,gBAAgB;IAChB,SAAS;IACT,SAAS;IACT,aAAa;IACb,cAAc;IACd,UAAU;IACV,oBAAoB;IACpB,QAAQ;IACR,cAAc;;IAGd,OAAO;IACP,SAAS;IACT,UAAU;IACV,KAAK;IACL,OAAO;IACP,OAAO;IACP,OAAO;IACP,IAAI;IACJ,IAAI;IACJ,IAAI;;IAGJ,MAAM;IACN,OAAO;IACP,OAAO;IACP,QAAQ;IACR,QAAQ;IACR,UAAU;IACV,UAAU;IACV,QAAQ;IACR,UAAU;IACV,QAAQ;IACR,UAAU;IACV,OAAO;IACP,UAAU;IACV,QAAQ;;IAGR,SAAS;IACT,SAAS;IACT,QAAQ;IACR,MAAM;;IAGN,QAAQ;IACR,UAAU;IACV,UAAU;IACV,MAAM;IACN,QAAQ;;;;;mBAMO;;;;;;;IAOf;;IAGA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA,iBAAiB;IACjB;IACA;IACA;;KAGC;;IAGD;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IAWA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;IAGA,WAAW;;;mBAII,2BAA2B;IAC1C;;mBAGe,2BAA2B;IAC1C;IACA;;mBAGe,2BAA2B;IAC1C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,2BAA2B;IAC1C;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,4BAA4B;IAC3C;IACA;IACA;;mBAGe,iCAAiC;IAChD;;mBAGe,yBAAyB;IACxC;IACA;IACA;;mBAGe,yBAAyB;IACxC;;mBAGe,6BAA6B;IAC5C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,4BAA4B;IAC3C;;mBAGe,2BAA2B;IAC1C;;mBAGe,2BAA2B;IAC1C;;mBAGe,0BAA0B;IACzC;IACA;;mBAGe,0BAA0B;IACzC;IACA;;mBAGe,6BAA6B;IAC5C;IACA;IACA;IACA;IACA;;mBAGe,0BAA0B;IACzC;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,6BAA6B;IAC5C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,4BAA4B;IAC3C;IACA;IACA;IACA;;mBAGe,6BAA6B;IAC5C;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,4BAA4B;IAC3C;IACA;;mBAGe,4BAA4B;IAC3C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,4BAA4B;IAC3C;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,4BAA4B;IAC3C;IACA;IACA;IACA;IACA;;mBAGe,0BAA0B;IACzC;;mBAGe,2BAA2B;IAC1C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,4BAA4B;IAC3C;IACA;;mBAGe,+BAA+B;IAC9C;;mBAGe,0BAA0B;IACzC;;mBAGe,yBAAyB;IACxC;IACA;IACA;;mBAGe,yBAAyB;IACxC;IACA;IACA;IACA;IACA;;mBAGe,2BAA2B;IAC1C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,4BAA4B;IAC3C;IACA;;mBAGe,4BAA4B;IAC3C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,6BAA6B;IAC5C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,6BAA6B;IAC5C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,+BAA+B;IAC9C;IACA;;mBAGe,6BAA6B;IAC5C;IACA;IACA;IACA;;mBAGe,+BAA+B;IAC9C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,6BAA6B;IAC5C;IACA;IACA;;mBAGe,+BAA+B;IAC9C;IACA;;mBAGe,4BAA4B;IAC3C;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,+BAA+B;IAC9C;IACA;IACA;;mBAGe,8BAA8B;IAC7C;;mBAGe,6BAA6B;IAC5C;;mBAGe,2BAA2B;IAC1C;;mBAGe,6BAA6B;IAC5C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;mBAGe,2BAA2B;IAC1C;;mBAGe,6BAA6B;IAC5C;IACA;;mBAGe,sBAAsB;;IAErC;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;;;;cAMU,6BAA6B;;;;cAK7B,sBAAsB,UAAU,wBAAwB,kBAAkB;;KAGnF,8BAAA,IAAuD;KACvD,gCAAA,IAAyD;QAEtD;YACI;SACH,UAA+B;cAC1B,0BAA0B;cAC1B,4BAA4B;;;;;;;;KC/jB9B,4BAA4B,OAAO,4BAA4B;;;;KAK/D,0DAA0D,UAAU;;;;UAK/D;EACf;;;;;UAMe;EACf,WAAW;GACV;;;;;;iBAsCa,IAAI,MAAM,gBAAgB,OAAO,UAAU,gBAAgB;;;;;iBA6C3D,KAAK,MAAM,gBAAgB,OAAO,UAAU,eAAe;;;;iBAO3D,WAAW;EAAc,WAAW;IAAa;;;;iBAOjD,eAAe,MAAM;;;;;;;;;;iBAarB,IAAI,eAAe;;;;;;;;;iBAYnB,KAAK,oBAAoB,SAAS,UAAU;;;;;;;;;iBAY5C,KAAK,GAAG,OAAO,KAAK,SAAS,MAAM,GAAG,kBAAkB,UAAU"}
package/dist/jsx-html.mjs CHANGED
@@ -49,13 +49,33 @@ function escapeHtml(str) {
49
49
  return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#x27;");
50
50
  }
51
51
  /**
52
- * Converts a camelCase attribute name to kebab-case for HTML.
53
- * Special handling for data-* and aria-* attributes.
52
+ * React prop names whose HTML spelling is not the lowercased identifier.
53
+ */
54
+ const ATTR_ALIASES = {
55
+ className: "class",
56
+ htmlFor: "for",
57
+ httpEquiv: "http-equiv",
58
+ acceptCharset: "accept-charset"
59
+ };
60
+ /** SVG attributes that stay camelCase in HTML (they are case-sensitive). */
61
+ const SVG_CAMEL_CASE = /* @__PURE__ */ new Set(["viewBox"]);
62
+ /**
63
+ * Converts a JSX/React prop name to the HTML attribute the runtime emits.
64
+ *
65
+ * HTML attributes are case-insensitive and conventionally lowercase
66
+ * (`charSet` → `charset`, `tabIndex` → `tabindex`). A few React names are
67
+ * not a lowercase of themselves (`className`, `httpEquiv`), and SVG names
68
+ * like `viewBox` must keep their case.
54
69
  */
55
70
  function toHtmlAttr(name) {
56
- if (name === "className") return "class";
57
- if (name === "htmlFor") return "for";
71
+ const aliased = ATTR_ALIASES[name];
72
+ if (aliased !== void 0) return aliased;
73
+ if (SVG_CAMEL_CASE.has(name)) return name;
58
74
  if (name.startsWith("data") || name.startsWith("aria")) return name.replace(/([A-Z])/g, "-$1").toLowerCase();
75
+ if (/[A-Z]/.test(name)) {
76
+ if (name.startsWith("stroke") || name === "clipPath") return name.replace(/([A-Z])/g, "-$1").toLowerCase();
77
+ return name.toLowerCase();
78
+ }
59
79
  return name;
60
80
  }
61
81
  /**
@@ -94,10 +114,12 @@ function jsx(type, props, _key) {
94
114
  });
95
115
  const tag = type;
96
116
  let html = `<${tag}`;
117
+ const attrs = /* @__PURE__ */ new Map();
97
118
  for (const [name, value] of Object.entries(restProps)) {
98
119
  if (name === "key" || name === "ref") continue;
99
- html += renderAttr(name, value);
120
+ attrs.set(toHtmlAttr(name), value);
100
121
  }
122
+ for (const [name, value] of attrs) html += renderAttr(name, value);
101
123
  if (VOID_ELEMENTS.has(tag)) {
102
124
  html += " />";
103
125
  return { __html: html };
@@ -1 +1 @@
1
- {"version":3,"file":"jsx-html.mjs","names":[],"sources":["../src/jsx-html.ts"],"sourcesContent":["/**\n * Custom JSX Runtime for Static HTML Generation\n *\n * This module provides a JSX runtime that outputs static HTML strings.\n * No React, no hydration, no client-side JavaScript - just pure HTML.\n *\n * This is the implementation. The JSX transform imports it through the\n * ./jsx-runtime and ./jsx-dev-runtime entry points, which are the subpaths\n * `jsxImportSource` resolves. Keeping the implementation under its own name\n * keeps those two entries from colliding with the shared bundle chunk.\n *\n * @example\n * ```tsx\n * // tsconfig.json or vite.config.ts\n * {\n * \"compilerOptions\": {\n * \"jsx\": \"react-jsx\",\n * \"jsxImportSource\": \"@ox-content/vite-plugin\"\n * }\n * }\n *\n * // MyComponent.tsx\n * export function Hero({ title }: { title: string }) {\n * return (\n * <section class=\"hero\">\n * <h1>{title}</h1>\n * </section>\n * );\n * }\n * ```\n */\n\n// `jsxImportSource` makes TypeScript look for the element types in\n// `<source>/jsx-runtime` itself, so the namespace has to travel with the\n// runtime exports and not only be declared globally in ./jsx.d.ts.\nexport type { JSX } from \"./jsx\";\n\n// Self-closing tags that don't need closing tags\nconst VOID_ELEMENTS = new Set([\n \"area\",\n \"base\",\n \"br\",\n \"col\",\n \"embed\",\n \"hr\",\n \"img\",\n \"input\",\n \"link\",\n \"meta\",\n \"param\",\n \"source\",\n \"track\",\n \"wbr\",\n]);\n\n// Attributes that should be rendered as boolean\nconst BOOLEAN_ATTRS = new Set([\n \"allowfullscreen\",\n \"async\",\n \"autofocus\",\n \"autoplay\",\n \"checked\",\n \"controls\",\n \"default\",\n \"defer\",\n \"disabled\",\n \"formnovalidate\",\n \"hidden\",\n \"inert\",\n \"ismap\",\n \"itemscope\",\n \"loop\",\n \"multiple\",\n \"muted\",\n \"nomodule\",\n \"novalidate\",\n \"open\",\n \"playsinline\",\n \"readonly\",\n \"required\",\n \"reversed\",\n \"selected\",\n]);\n\n/**\n * Escapes HTML special characters to prevent XSS.\n */\nfunction escapeHtml(str: string): string {\n return str\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#x27;\");\n}\n\n/**\n * Converts a camelCase attribute name to kebab-case for HTML.\n * Special handling for data-* and aria-* attributes.\n */\nfunction toHtmlAttr(name: string): string {\n // className -> class\n if (name === \"className\") return \"class\";\n // htmlFor -> for\n if (name === \"htmlFor\") return \"for\";\n // Keep data-* and aria-* as-is\n if (name.startsWith(\"data\") || name.startsWith(\"aria\")) {\n return name.replace(/([A-Z])/g, \"-$1\").toLowerCase();\n }\n return name;\n}\n\n/**\n * Renders an attribute value to a string.\n */\nfunction renderAttr(name: string, value: unknown): string {\n const htmlName = toHtmlAttr(name);\n\n // Skip undefined, null, and false values\n if (value === undefined || value === null || value === false) {\n return \"\";\n }\n\n // Boolean attributes\n if (BOOLEAN_ATTRS.has(htmlName)) {\n return value ? ` ${htmlName}` : \"\";\n }\n\n // Style object to string\n if (name === \"style\" && typeof value === \"object\") {\n const styleStr = Object.entries(value as Record<string, string | number>)\n .map(([k, v]) => {\n const prop = k.replace(/([A-Z])/g, \"-$1\").toLowerCase();\n return `${prop}:${v}`;\n })\n .join(\";\");\n return ` style=\"${escapeHtml(styleStr)}\"`;\n }\n\n // Regular attribute\n return ` ${htmlName}=\"${escapeHtml(String(value as string | number | boolean))}\"`;\n}\n\n/**\n * JSX element type - either a string (intrinsic) or a function component.\n */\nexport type JSXElementType = string | ((props: Record<string, unknown>) => JSXNode);\n\n/**\n * Valid JSX child types.\n */\nexport type JSXChild = string | number | boolean | null | undefined | JSXNode | JSXChild[];\n\n/**\n * JSX node - the result of JSX expressions.\n */\nexport interface JSXNode {\n __html: string;\n}\n\n/**\n * Props with children.\n */\nexport interface JSXProps {\n children?: JSXChild;\n [key: string]: unknown;\n}\n\n/**\n * Renders children to HTML string.\n */\nfunction renderChildren(children: JSXChild): string {\n if (children === null || children === undefined || children === false) {\n return \"\";\n }\n\n if (children === true) {\n return \"\";\n }\n\n if (typeof children === \"string\") {\n return escapeHtml(children);\n }\n\n if (typeof children === \"number\") {\n return String(children);\n }\n\n if (Array.isArray(children)) {\n return children.map(renderChildren).join(\"\");\n }\n\n if (typeof children === \"object\" && \"__html\" in children) {\n return children.__html;\n }\n\n return \"\";\n}\n\n/**\n * Creates a JSX element.\n * This is the core function called by the JSX transform.\n */\nexport function jsx(type: JSXElementType, props: JSXProps, _key?: string): JSXNode {\n const { children, ...restProps } = props;\n\n // Function component\n if (typeof type === \"function\") {\n return type({ ...restProps, children });\n }\n\n // Intrinsic element (HTML tag)\n const tag = type;\n let html = `<${tag}`;\n\n // Render attributes\n for (const [name, value] of Object.entries(restProps)) {\n // Skip internal props\n if (name === \"key\" || name === \"ref\") continue;\n html += renderAttr(name, value);\n }\n\n // Self-closing tags\n if (VOID_ELEMENTS.has(tag)) {\n html += \" />\";\n return { __html: html };\n }\n\n html += \">\";\n\n // Render children\n if (children !== undefined) {\n html += renderChildren(children);\n }\n\n html += `</${tag}>`;\n\n return { __html: html };\n}\n\n/**\n * Creates a JSX element with static children.\n * Called by the JSX transform for elements with multiple children.\n */\nexport function jsxs(type: JSXElementType, props: JSXProps, key?: string): JSXNode {\n return jsx(type, props, key);\n}\n\n/**\n * Fragment component - renders children without a wrapper element.\n */\nexport function Fragment({ children }: { children?: JSXChild }): JSXNode {\n return { __html: renderChildren(children) };\n}\n\n/**\n * Renders a JSX node to an HTML string.\n */\nexport function renderToString(node: JSXNode): string {\n return node.__html;\n}\n\n/**\n * Creates raw HTML without escaping.\n * Use with caution - only for trusted content.\n *\n * @example\n * ```tsx\n * <div>{raw('<strong>Bold</strong>')}</div>\n * ```\n */\nexport function raw(html: string): JSXNode {\n return { __html: html };\n}\n\n/**\n * Conditionally renders content.\n *\n * @example\n * ```tsx\n * {when(isLoggedIn, <UserMenu />)}\n * ```\n */\nexport function when(condition: boolean, content: JSXNode): JSXNode {\n return condition ? content : { __html: \"\" };\n}\n\n/**\n * Maps over an array and renders each item.\n *\n * @example\n * ```tsx\n * {each(items, (item) => <li>{item.name}</li>)}\n * ```\n */\nexport function each<T>(items: T[], render: (item: T, index: number) => JSXNode): JSXNode {\n const html = items.map((item, i) => render(item, i).__html).join(\"\");\n return { __html: html };\n}\n\n// Default export for convenience\nexport default {\n jsx,\n jsxs,\n Fragment,\n renderToString,\n raw,\n when,\n each,\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"jsx-html.mjs","names":[],"sources":["../src/jsx-html.ts"],"sourcesContent":["/**\n * Custom JSX Runtime for Static HTML Generation\n *\n * This module provides a JSX runtime that outputs static HTML strings.\n * No React, no hydration, no client-side JavaScript - just pure HTML.\n *\n * This is the implementation. The JSX transform imports it through the\n * ./jsx-runtime and ./jsx-dev-runtime entry points, which are the subpaths\n * `jsxImportSource` resolves. Keeping the implementation under its own name\n * keeps those two entries from colliding with the shared bundle chunk.\n *\n * @example\n * ```tsx\n * // tsconfig.json or vite.config.ts\n * {\n * \"compilerOptions\": {\n * \"jsx\": \"react-jsx\",\n * \"jsxImportSource\": \"@ox-content/vite-plugin\"\n * }\n * }\n *\n * // MyComponent.tsx\n * export function Hero({ title }: { title: string }) {\n * return (\n * <section class=\"hero\">\n * <h1>{title}</h1>\n * </section>\n * );\n * }\n * ```\n */\n\n// `jsxImportSource` makes TypeScript look for the element types in\n// `<source>/jsx-runtime` itself, so the namespace has to travel with the\n// runtime exports and not only be declared globally in ./jsx.d.ts.\nexport type { JSX } from \"./jsx\";\n\n// Self-closing tags that don't need closing tags\nconst VOID_ELEMENTS = new Set([\n \"area\",\n \"base\",\n \"br\",\n \"col\",\n \"embed\",\n \"hr\",\n \"img\",\n \"input\",\n \"link\",\n \"meta\",\n \"param\",\n \"source\",\n \"track\",\n \"wbr\",\n]);\n\n// Attributes that should be rendered as boolean\nconst BOOLEAN_ATTRS = new Set([\n \"allowfullscreen\",\n \"async\",\n \"autofocus\",\n \"autoplay\",\n \"checked\",\n \"controls\",\n \"default\",\n \"defer\",\n \"disabled\",\n \"formnovalidate\",\n \"hidden\",\n \"inert\",\n \"ismap\",\n \"itemscope\",\n \"loop\",\n \"multiple\",\n \"muted\",\n \"nomodule\",\n \"novalidate\",\n \"open\",\n \"playsinline\",\n \"readonly\",\n \"required\",\n \"reversed\",\n \"selected\",\n]);\n\n/**\n * Escapes HTML special characters to prevent XSS.\n */\nfunction escapeHtml(str: string): string {\n return str\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#x27;\");\n}\n\n/**\n * React prop names whose HTML spelling is not the lowercased identifier.\n */\nconst ATTR_ALIASES: Record<string, string> = {\n className: \"class\",\n htmlFor: \"for\",\n httpEquiv: \"http-equiv\",\n acceptCharset: \"accept-charset\",\n};\n\n/** SVG attributes that stay camelCase in HTML (they are case-sensitive). */\nconst SVG_CAMEL_CASE = new Set([\"viewBox\"]);\n\n/**\n * Converts a JSX/React prop name to the HTML attribute the runtime emits.\n *\n * HTML attributes are case-insensitive and conventionally lowercase\n * (`charSet` → `charset`, `tabIndex` → `tabindex`). A few React names are\n * not a lowercase of themselves (`className`, `httpEquiv`), and SVG names\n * like `viewBox` must keep their case.\n */\nfunction toHtmlAttr(name: string): string {\n const aliased = ATTR_ALIASES[name];\n if (aliased !== undefined) return aliased;\n if (SVG_CAMEL_CASE.has(name)) return name;\n if (name.startsWith(\"data\") || name.startsWith(\"aria\")) {\n return name.replace(/([A-Z])/g, \"-$1\").toLowerCase();\n }\n if (/[A-Z]/.test(name)) {\n // SVG presentation attributes are kebab-case; remaining HTML names are\n // just the lowercased identifier (`charSet` → `charset`).\n if (name.startsWith(\"stroke\") || name === \"clipPath\") {\n return name.replace(/([A-Z])/g, \"-$1\").toLowerCase();\n }\n return name.toLowerCase();\n }\n return name;\n}\n\n/**\n * Renders an attribute value to a string.\n */\nfunction renderAttr(name: string, value: unknown): string {\n const htmlName = toHtmlAttr(name);\n\n // Skip undefined, null, and false values\n if (value === undefined || value === null || value === false) {\n return \"\";\n }\n\n // Boolean attributes\n if (BOOLEAN_ATTRS.has(htmlName)) {\n return value ? ` ${htmlName}` : \"\";\n }\n\n // Style object to string\n if (name === \"style\" && typeof value === \"object\") {\n const styleStr = Object.entries(value as Record<string, string | number>)\n .map(([k, v]) => {\n const prop = k.replace(/([A-Z])/g, \"-$1\").toLowerCase();\n return `${prop}:${v}`;\n })\n .join(\";\");\n return ` style=\"${escapeHtml(styleStr)}\"`;\n }\n\n // Regular attribute\n return ` ${htmlName}=\"${escapeHtml(String(value as string | number | boolean))}\"`;\n}\n\n/**\n * JSX element type - either a string (intrinsic) or a function component.\n */\nexport type JSXElementType = string | ((props: Record<string, unknown>) => JSXNode);\n\n/**\n * Valid JSX child types.\n */\nexport type JSXChild = string | number | boolean | null | undefined | JSXNode | JSXChild[];\n\n/**\n * JSX node - the result of JSX expressions.\n */\nexport interface JSXNode {\n __html: string;\n}\n\n/**\n * Props with children.\n */\nexport interface JSXProps {\n children?: JSXChild;\n [key: string]: unknown;\n}\n\n/**\n * Renders children to HTML string.\n */\nfunction renderChildren(children: JSXChild): string {\n if (children === null || children === undefined || children === false) {\n return \"\";\n }\n\n if (children === true) {\n return \"\";\n }\n\n if (typeof children === \"string\") {\n return escapeHtml(children);\n }\n\n if (typeof children === \"number\") {\n return String(children);\n }\n\n if (Array.isArray(children)) {\n return children.map(renderChildren).join(\"\");\n }\n\n if (typeof children === \"object\" && \"__html\" in children) {\n return children.__html;\n }\n\n return \"\";\n}\n\n/**\n * Creates a JSX element.\n * This is the core function called by the JSX transform.\n */\nexport function jsx(type: JSXElementType, props: JSXProps, _key?: string): JSXNode {\n const { children, ...restProps } = props;\n\n // Function component\n if (typeof type === \"function\") {\n return type({ ...restProps, children });\n }\n\n // Intrinsic element (HTML tag)\n const tag = type;\n let html = `<${tag}`;\n\n // Normalize React aliases first so `class` + `className` become one attribute\n // (last write wins) instead of emitting `class` twice.\n const attrs = new Map<string, unknown>();\n for (const [name, value] of Object.entries(restProps)) {\n if (name === \"key\" || name === \"ref\") continue;\n attrs.set(toHtmlAttr(name), value);\n }\n for (const [name, value] of attrs) {\n html += renderAttr(name, value);\n }\n\n // Self-closing tags\n if (VOID_ELEMENTS.has(tag)) {\n html += \" />\";\n return { __html: html };\n }\n\n html += \">\";\n\n // Render children\n if (children !== undefined) {\n html += renderChildren(children);\n }\n\n html += `</${tag}>`;\n\n return { __html: html };\n}\n\n/**\n * Creates a JSX element with static children.\n * Called by the JSX transform for elements with multiple children.\n */\nexport function jsxs(type: JSXElementType, props: JSXProps, key?: string): JSXNode {\n return jsx(type, props, key);\n}\n\n/**\n * Fragment component - renders children without a wrapper element.\n */\nexport function Fragment({ children }: { children?: JSXChild }): JSXNode {\n return { __html: renderChildren(children) };\n}\n\n/**\n * Renders a JSX node to an HTML string.\n */\nexport function renderToString(node: JSXNode): string {\n return node.__html;\n}\n\n/**\n * Creates raw HTML without escaping.\n * Use with caution - only for trusted content.\n *\n * @example\n * ```tsx\n * <div>{raw('<strong>Bold</strong>')}</div>\n * ```\n */\nexport function raw(html: string): JSXNode {\n return { __html: html };\n}\n\n/**\n * Conditionally renders content.\n *\n * @example\n * ```tsx\n * {when(isLoggedIn, <UserMenu />)}\n * ```\n */\nexport function when(condition: boolean, content: JSXNode): JSXNode {\n return condition ? content : { __html: \"\" };\n}\n\n/**\n * Maps over an array and renders each item.\n *\n * @example\n * ```tsx\n * {each(items, (item) => <li>{item.name}</li>)}\n * ```\n */\nexport function each<T>(items: T[], render: (item: T, index: number) => JSXNode): JSXNode {\n const html = items.map((item, i) => render(item, i).__html).join(\"\");\n return { __html: html };\n}\n\n// Default export for convenience\nexport default {\n jsx,\n jsxs,\n Fragment,\n renderToString,\n raw,\n when,\n each,\n};\n"],"mappings":"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"}
package/dist/tabs.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { d as importNapiModule } from "./vitepress.mjs";
1
+ import { h as importNapiModule } from "./vitepress.mjs";
2
2
  import { createRequire } from "node:module";
3
3
  //#region \0rolldown/runtime.js
4
4
  var __defProp = Object.defineProperty;
@@ -67,6 +67,56 @@ function importNapiModuleSync() {
67
67
  }
68
68
  }
69
69
  //#endregion
70
+ //#region src/header-chrome.ts
71
+ /** `false` or omitted stays off. `true` or `{}` enables default flag reading. */
72
+ function resolvePageChromeOption(value) {
73
+ return value === true || typeof value === "object" && value !== null;
74
+ }
75
+ /** Reads hide flags from frontmatter. Non-boolean values are ignored. */
76
+ function parsePageChromeFlags(frontmatter) {
77
+ return {
78
+ sidebar: readBool(frontmatter.sidebar),
79
+ outline: readBool(frontmatter.outline),
80
+ aside: readBool(frontmatter.aside),
81
+ footer: readBool(frontmatter.footer),
82
+ navbar: readBool(frontmatter.navbar),
83
+ lastUpdated: readBool(frontmatter.lastUpdated),
84
+ editLink: readBool(frontmatter.editLink)
85
+ };
86
+ }
87
+ function readBool(value) {
88
+ return typeof value === "boolean" ? value : void 0;
89
+ }
90
+ /**
91
+ * Picks the exact locale, its language, the default locale, then the first
92
+ * non-empty own string in declaration order.
93
+ */
94
+ function resolveLocaleLabel(text, locale, defaultLocale) {
95
+ if (typeof text === "string") return text;
96
+ const candidates = [
97
+ locale,
98
+ locale?.split("-")[0],
99
+ defaultLocale,
100
+ defaultLocale?.split("-")[0]
101
+ ];
102
+ for (const candidate of candidates) {
103
+ if (!candidate || !Object.hasOwn(text, candidate)) continue;
104
+ const value = text[candidate];
105
+ if (typeof value === "string" && value.length > 0) return value;
106
+ }
107
+ for (const value of Object.values(text)) if (typeof value === "string" && value.length > 0) return value;
108
+ return "";
109
+ }
110
+ /** Resolves locale maps so NAPI always receives string labels. */
111
+ function resolveHeaderNavItems(items, locale, defaultLocale) {
112
+ if (!items?.length) return;
113
+ return items.map((item) => ({
114
+ text: resolveLocaleLabel(item.text, locale, defaultLocale),
115
+ link: item.link,
116
+ items: resolveHeaderNavItems(item.items, locale, defaultLocale)
117
+ }));
118
+ }
119
+ //#endregion
70
120
  //#region src/theme-tokens.ts
71
121
  const TOKEN_PREFIX = "--octc-";
72
122
  const TOKEN_NAME_PATTERN = /^[a-z][a-z0-9-]*$/;
@@ -99,16 +149,14 @@ function assertTokenName(name) {
99
149
  //#endregion
100
150
  //#region src/theme.ts
101
151
  /**
102
- * Theme API for ox-content SSG
103
- *
104
- * Provides VitePress-like theming with default theme + customization.
105
- */
106
- /**
107
152
  * Default theme configuration.
108
153
  * Based on the current ox-content SSG styles.
109
154
  */
110
155
  const defaultTheme = {
111
156
  name: "default",
157
+ viewTransitions: true,
158
+ aside: false,
159
+ breadcrumbs: false,
112
160
  colors: {
113
161
  primary: "#4f6fae",
114
162
  primaryHover: "#425f96",
@@ -246,12 +294,17 @@ function resolveTheme(config) {
246
294
  const merged = mergeThemes(...chain.map(withDerivedCodeBackgroundTop));
247
295
  return {
248
296
  name: merged.name ?? "custom",
297
+ viewTransitions: merged.viewTransitions ?? defaultTheme.viewTransitions ?? true,
298
+ aside: merged.aside ?? defaultTheme.aside ?? false,
299
+ breadcrumbs: resolveThemeFlag(merged.breadcrumbs),
249
300
  colors: merged.colors ?? defaultTheme.colors,
250
301
  darkColors: merged.darkColors ?? defaultTheme.darkColors,
251
302
  fonts: merged.fonts ?? defaultTheme.fonts,
252
303
  entryPage: merged.entryPage ?? defaultTheme.entryPage,
253
304
  layout: merged.layout ?? defaultTheme.layout,
254
305
  header: merged.header ?? defaultTheme.header,
306
+ nav: merged.nav,
307
+ announcement: merged.announcement,
255
308
  footer: merged.footer ?? defaultTheme.footer,
256
309
  socialLinks: merged.socialLinks ?? defaultTheme.socialLinks,
257
310
  sidebar: merged.sidebar ?? [],
@@ -296,9 +349,12 @@ function withDerivedCodeBackgroundTop(theme) {
296
349
  /**
297
350
  * Converts resolved theme to the format expected by Rust NAPI.
298
351
  */
299
- function themeToNapi(theme) {
352
+ function themeToNapi(theme, locale) {
300
353
  const socialLinks = socialLinksToNapi(theme.socialLinks);
301
354
  return {
355
+ viewTransitions: theme.viewTransitions,
356
+ aside: theme.aside,
357
+ breadcrumbs: theme.breadcrumbs,
302
358
  colors: theme.colors.primary ? {
303
359
  primary: theme.colors.primary,
304
360
  primaryHover: theme.colors.primaryHover,
@@ -341,6 +397,8 @@ function themeToNapi(theme) {
341
397
  logoWidth: theme.header.logoWidth,
342
398
  logoHeight: theme.header.logoHeight
343
399
  } : void 0,
400
+ nav: resolveHeaderNavItems(theme.nav, locale),
401
+ announcement: theme.announcement?.text ? theme.announcement : void 0,
344
402
  footer: theme.footer.message || theme.footer.copyright ? {
345
403
  message: theme.footer.message,
346
404
  copyright: theme.footer.copyright
@@ -378,6 +436,9 @@ function socialLinksToNapi(links) {
378
436
  discord: links.discord
379
437
  } : void 0;
380
438
  }
439
+ function resolveThemeFlag(value) {
440
+ return value === true || typeof value === "object" && value !== null;
441
+ }
381
442
  //#endregion
382
443
  //#region src/vitepress.ts
383
444
  function isRecord(value) {
@@ -717,6 +778,30 @@ Object.defineProperty(exports, "normalizeVitePressFrontmatter", {
717
778
  return normalizeVitePressFrontmatter;
718
779
  }
719
780
  });
781
+ Object.defineProperty(exports, "parsePageChromeFlags", {
782
+ enumerable: true,
783
+ get: function() {
784
+ return parsePageChromeFlags;
785
+ }
786
+ });
787
+ Object.defineProperty(exports, "resolveHeaderNavItems", {
788
+ enumerable: true,
789
+ get: function() {
790
+ return resolveHeaderNavItems;
791
+ }
792
+ });
793
+ Object.defineProperty(exports, "resolveLocaleLabel", {
794
+ enumerable: true,
795
+ get: function() {
796
+ return resolveLocaleLabel;
797
+ }
798
+ });
799
+ Object.defineProperty(exports, "resolvePageChromeOption", {
800
+ enumerable: true,
801
+ get: function() {
802
+ return resolvePageChromeOption;
803
+ }
804
+ });
720
805
  Object.defineProperty(exports, "resolveTheme", {
721
806
  enumerable: true,
722
807
  get: function() {