diff --git a/docs/components/apidoc.astro b/docs/components/apidoc.astro
new file mode 100644
index 0000000..59e8fbb
--- /dev/null
+++ b/docs/components/apidoc.astro
@@ -0,0 +1,59 @@
+---
+import { apiModules, getDoc } from "../utils";
+import StarlightPage from "@astrojs/starlight/components/StarlightPage.astro";
+import Value from "./value.astro";
+import Type from "./type.astro";
+
+const { moduleName, filePath, link } = Astro.props;
+
+const { types, typesInOwnModule, typeHeadings, values, valueHeadings } =
+ await getDoc(filePath);
+
+const frontmatter = {
+ title: moduleName,
+};
+
+const headings = [];
+if (types.length > 0) {
+ headings.push({
+ depth: 2,
+ slug: "types",
+ text: "Types",
+ });
+ headings.push(...typeHeadings);
+}
+
+if (values.length > 0) {
+ headings.push({
+ depth: 2,
+ slug: "values",
+ text: "Values",
+ });
+ headings.push(...valueHeadings);
+}
+---
+
+ {
+ types.length > 0 && (
+ <>
+ Types
+ {types.map((type) => (
+
+ ))}
+ >
+ )
+ }
+ {
+ values.length > 0 && (
+ <>
+ Values
+ {values.map((value) => )}
+ >
+ )
+ }
+
diff --git a/docs/components/record.astro b/docs/components/record.astro
index 366e3a7..a6f50e6 100644
--- a/docs/components/record.astro
+++ b/docs/components/record.astro
@@ -40,6 +40,7 @@ const { name, items, typesInOwnModule } = Astro.props;
}
& .doc {
+ margin-top: 0;
padding-bottom: 0.5rem;
grid-column: 1 / -1;
grid-row: 2;
diff --git a/docs/components/type.astro b/docs/components/type.astro
new file mode 100644
index 0000000..4aa5ff5
--- /dev/null
+++ b/docs/components/type.astro
@@ -0,0 +1,67 @@
+---
+import * as path from "node:path";
+import { existsSync } from "node:fs";
+import { Code } from "@astrojs/starlight/components";
+import Record from "./record.astro";
+import { createTypeModuleLink } from "../utils";
+
+const { type, typesInOwnModule, filePath, link } = Astro.props;
+
+function showRecord(details) {
+ return details && details.kind === "record" && details.items.length > 0;
+}
+
+function getModuleFileName(typeName) {
+ return `${typeName[0].toUpperCase()}${typeName.slice(1)}`;
+}
+
+/**
+ * Check if there is a file representing the module for the type.
+ * The location to be checked is a sub directory with the same name as the current file type.
+ * @param {string} typeName
+ * @param {string} filePath
+ * @returns {boolean}
+ */
+function showModule(typeName, filePath) {
+ const moduleFileName = `${getModuleFileName(typeName)}.res`;
+ const potentialPath = path.join(filePath.replace(".res", ""), moduleFileName);
+ return existsSync(potentialPath);
+}
+---
+
+
-
Parameters
+
+
{value.name}
+
+
{
- parameters.map((p) => (
-
- ))
+ showValue(value.detail) && (
+
+
Parameters
+ {details.parameters.map((p) => (
+
+ ))}
+ Return type
+
+
+ )
}
-
Return type
-
+
+
diff --git a/docs/pages/apidocs/[API]/[Module].astro b/docs/pages/apidocs/[API]/[Module].astro
index e6a5590..286b09a 100644
--- a/docs/pages/apidocs/[API]/[Module].astro
+++ b/docs/pages/apidocs/[API]/[Module].astro
@@ -1,9 +1,6 @@
---
import { apiModules, getDoc } from "../../../utils";
-import StarlightPage from "@astrojs/starlight/components/StarlightPage.astro";
-import { Code } from "@astrojs/starlight/components";
-import { micromark } from "micromark";
-import Value from "../../../components/value.astro";
+import APIDoc from "../../../components/apidoc.astro";
export async function getStaticPaths() {
return apiModules.flatMap((apiModule) => {
@@ -19,68 +16,7 @@ export async function getStaticPaths() {
});
}
-function showValue(detail) {
- return (
- detail?.kind === "signature" && detail?.details?.parameters?.length > 0
- );
-}
-
-const { filePath, moduleName } = Astro.props.currentModule;
-const docInfo = await getDoc(filePath);
-
-const values = docInfo.items
- .filter((item) => item.kind === "value")
- .sort((a, b) => a.name.localeCompare(b.name))
- .map((value) => {
- const documentation =
- value.docstrings && micromark(value.docstrings.join("\n"));
- return {
- name: value.name,
- documentation,
- signature: value.signature,
- detail: value.detail,
- };
- });
-
-const valueHeadings = values.map((value) => ({
- depth: 3,
- slug: value.name,
- text: value.name,
-}));
-
-const frontmatter = {
- title: moduleName,
-};
-
-const headings = [
- {
- depth: 2,
- slug: "values",
- text: "Values",
- },
- ...valueHeadings,
-];
+const { filePath, moduleName, link } = Astro.props.currentModule;
---
-
- Values
- {
- values.map((value) => (
-
-
{value.name}
-
-
- {showValue(value.detail) &&
}
-
- ))
- }
-
-{JSON.stringify(docInfo, null, 4)}
-
-
-
+
diff --git a/docs/styles/theme.css b/docs/styles/theme.css
index 8915d1f..ef4a208 100644
--- a/docs/styles/theme.css
+++ b/docs/styles/theme.css
@@ -2,6 +2,8 @@
::backdrop {
--sl-font: "Inter", "Roboto Mono";
--sl-sidebar-width: 23rem;
+ --sl-text-3xl: 1.5rem;
+ --sl-text-2xl: 1.3rem;
}
/*
diff --git a/docs/utils.js b/docs/utils.js
index a34e781..4bdf816 100644
--- a/docs/utils.js
+++ b/docs/utils.js
@@ -2,6 +2,7 @@ import * as path from "node:path";
import { exec } from "node:child_process";
import { promisify } from "node:util";
import { readdirSync, existsSync } from "fs";
+import { micromark } from "micromark";
const execAsync = promisify(exec);
@@ -73,7 +74,7 @@ function mapRescriptFile(srcDir, file) {
const srcDir = path.resolve(process.cwd(), "src");
export const apiModules = readdirSync(srcDir).filter(f => f.endsWith(".res")).map(r => mapRescriptFile(srcDir, r));
-export async function getDoc(absoluteFilePath) {
+async function getRescriptDoc(absoluteFilePath) {
const { stdout, stderr } = await execAsync(
`rescript-tools doc ${absoluteFilePath}`,
{
@@ -85,3 +86,58 @@ export async function getDoc(absoluteFilePath) {
}
return JSON.parse(stdout);
}
+
+export async function getDoc(absoluteFilePath) {
+ const docInfo = await getRescriptDoc(absoluteFilePath);
+
+ const types = docInfo.items
+ .filter((item) => item.kind === "type")
+ .sort((a, b) => a.name.localeCompare(b.name))
+ .map((type) => {
+ const documentation =
+ type.docstrings && micromark(type.docstrings.join("\n"));
+ return {
+ name: type.name,
+ documentation,
+ signature: type.signature,
+ detail: type.detail,
+ };
+ });
+
+ const typesInOwnModule = new Set(types.map((t) => t.name));
+
+ const typeHeadings = types.map((type) => ({
+ depth: 3,
+ slug: type.name,
+ text: type.name,
+ }));
+
+ const values = docInfo.items
+ .filter((item) => item.kind === "value")
+ .sort((a, b) => a.name.localeCompare(b.name))
+ .map((value) => {
+ const documentation =
+ value.docstrings && micromark(value.docstrings.join("\n"));
+ return {
+ name: value.name,
+ documentation,
+ signature: value.signature,
+ detail: value.detail,
+ };
+ });
+
+ const valueHeadings = values.map((value) => ({
+ depth: 3,
+ slug: value.name,
+ text: value.name,
+ }));
+
+ return {
+ docInfo,
+ types,
+ typesInOwnModule,
+ typeHeadings,
+ values,
+ valueHeadings,
+ };
+}
\ No newline at end of file
diff --git a/src/DOMAPI/FillStyle.res b/src/DOMAPI/FillStyle.res
index 312f477..fdf4be2 100644
--- a/src/DOMAPI/FillStyle.res
+++ b/src/DOMAPI/FillStyle.res
@@ -6,6 +6,9 @@ external fromString: string => fillStyle = "%identity"
external fromCanvasGradient: canvasGradient => fillStyle = "%identity"
external fromCanvasPattern: canvasGradient => fillStyle = "%identity"
+/**
+Represents a decoded version of the abstract `fillStyle` type, used in Context2D.
+ */
type decoded =
| String(string)
| CanvasGradient(canvasGradient)
diff --git a/tests/DOMAPI/Location__test.res b/tests/DOMAPI/Location__test.res
index 7e89162..fa2d12f 100644
--- a/tests/DOMAPI/Location__test.res
+++ b/tests/DOMAPI/Location__test.res
@@ -9,4 +9,4 @@ let href = location.href
// Invoke methods using the `->TypeModule`
location->Location.reload
-let a = 0
\ No newline at end of file
+let a = 0