diff --git a/docz/docs/03-demos/02-frontend/01-kaioken.md b/docz/docs/03-demos/02-frontend/01-kaioken.md
new file mode 100644
index 0000000..9b5d8d6
--- /dev/null
+++ b/docz/docs/03-demos/02-frontend/01-kaioken.md
@@ -0,0 +1,576 @@
+---
+title: Super Saiyan Sheets with Kaioken
+sidebar_label: Kaioken
+description: Build interactive websites with Kaioken. Seamlessly integrate spreadsheets into your app using SheetJS. Bring Excel-powered workflows and data to the modern web.
+pagination_prev: demos/index
+pagination_next: demos/grid/index
+sidebar_position: 1
+---
+
+import current from '/version.js';
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+import CodeBlock from '@theme/CodeBlock';
+
+[Kaioken](https://kaioken.dev/) is a JavaScript library for building user
+interfaces.
+
+[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing
+data from spreadsheets.
+
+This demo uses Kaioken and SheetJS to process and generate spreadsheets. We'll
+explore how to load SheetJS in "Kaioponents" (Kaioken components) and compare
+common state models and data flow strategies.
+
+:::note pass
+
+This demo focuses on Kaioken concepts. Other demos cover general deployments:
+
+- [Desktop application powered by Tauri](/docs/demos/desktop/tauri)
+
+:::
+
+## Installation
+
+[The "Frameworks" section](/docs/getting-started/installation/frameworks) covers
+installation with Yarn and other package managers.
+
+The library can be imported directly from JS or JSX code with:
+
+```js
+import { read, utils, writeFile } from 'xlsx';
+```
+
+
+## Internal State
+
+The various SheetJS APIs work with various data shapes. The preferred state
+depends on the application.
+
+### Array of Objects
+
+Typically, some users will create a spreadsheet with source data that should be
+loaded into the site. This sheet will have known columns.
+
+#### State
+
+The example [presidents sheet](https://sheetjs.com/pres.xlsx) has one header row
+with "Name" and "Index" columns. The natural JS representation is an object for
+each row, using the values in the first rows as keys:
+
+
+
+The Kaioken `useState`[^1] hook can configure the state:
+
+
+
+
+```ts
+import { useState } from 'kaioken';
+
+/* the kaioponent state is an array of objects */
+const [pres, setPres] = useState([]);
+```
+
+
+
+
+```ts
+import { useState } from 'kaioken';
+
+/* the kaioponent state is an array of objects */
+const [pres, setPres] = useState([]);
+```
+
+When the spreadsheet header row is known ahead of time, row typing is possible:
+
+```ts
+import { useState } from 'kaioken';
+
+interface President {
+ Name: string;
+ Index: number;
+}
+
+/* the kaioponent state is an array of presidents */
+const [pres, setPres] = useState([]);
+```
+
+:::caution pass
+
+The types are informative. They do not enforce that worksheets include the named
+columns. A runtime data validation library should be used to verify the dataset.
+
+When the file header is not known in advance, `any` should be used.
+
+:::
+
+
+
+
+#### Updating State
+
+The SheetJS [`read`](/docs/api/parse-options) and [`sheet_to_json`](/docs/api/utilities/array#array-output)
+functions simplify state updates. They are best used in the function bodies of
+`useEffect`[^2] and `useCallback`[^3] hooks.
+
+A `useEffect` hook can download and update state when a person loads the site:
+
+```mermaid
+flowchart LR
+ url[(Remote\nFile)]
+ ab[(Data\nArrayBuffer)]
+ wb(SheetJS\nWorkbook)
+ ws(SheetJS\nWorksheet)
+ aoo(array of\nobjects)
+ state((Kaioponent\nstate))
+ url --> |fetch\n\n| ab
+ ab --> |read\n\n| wb
+ wb --> |wb.Sheets\nselect sheet| ws
+ ws --> |sheet_to_json\n\n| aoo
+ aoo --> |setPres\nfrom `setState`| state
+```
+
+
+
+
+```js
+import { useEffect } from 'kaioken';
+import { read, utils } from 'xlsx';
+
+/* Fetch and update the state once */
+useEffect(() => { (async() => {
+ /* Download from https://sheetjs.com/pres.numbers */
+ const f = await fetch("https://sheetjs.com/pres.numbers");
+ const ab = await f.arrayBuffer();
+
+ // highlight-start
+ /* parse */
+ const wb = read(ab);
+
+ /* generate array of objects from first worksheet */
+ const ws = wb.Sheets[wb.SheetNames[0]]; // get the first worksheet
+ const data = utils.sheet_to_json(ws); // generate objects
+
+ /* update state */
+ setPres(data); // update state
+ // highlight-end
+})(); }, []);
+```
+
+
+
+
+```ts
+import { useEffect } from 'kaioken';
+import { read, utils } from 'xlsx';
+
+/* Fetch and update the state once */
+useEffect(() => { (async() => {
+ /* Download from https://sheetjs.com/pres.numbers */
+ const f = await fetch("https://sheetjs.com/pres.numbers");
+ const ab = await f.arrayBuffer();
+
+ // highlight-start
+ /* parse */
+ const wb = read(ab);
+
+ /* generate array of presidents from the first worksheet */
+ const ws = wb.Sheets[wb.SheetNames[0]]; // get the first worksheet
+ const data: President[] = utils.sheet_to_json(ws); // generate objects
+
+ /* update state */
+ setPres(data); // update state
+ // highlight-end
+})(); }, []);
+```
+
+
+
+
+#### Rendering Data
+
+Kaioponents typically render HTML tables from arrays of objects. The `TR` table
+row elements are typically generated by mapping over the state array, as shown
+in the example JSX code:
+
+```jsx title="Example JSX for displaying arrays of objects"
+
+ {/* The `thead` section includes the table header row */}
+
Name
Index
+ {/* The `tbody` section includes the data rows */}
+
+ {/* generate row (TR) for each president */}
+// highlight-start
+ {pres.map(row => (
+
+ {/* Generate cell (TD) for name / index */}
+
{row.Name}
+
{row.Index}
+
+ ))}
+// highlight-end
+
+
+```
+
+#### Exporting Data
+
+The [`writeFile`](/docs/api/write-options) and [`json_to_sheet`](/docs/api/utilities/array#array-of-objects-input)
+functions simplify exporting data. They are best used in the function bodies of
+`useCallback`[^4] hooks attached to button or other elements.
+
+A callback can generate a local file when a user clicks a button:
+
+```mermaid
+flowchart LR
+ state((Kaioponent\nstate))
+ ws(SheetJS\nWorksheet)
+ wb(SheetJS\nWorkbook)
+ file[(XLSX\nexport)]
+ state --> |json_to_sheet\n\n| ws
+ ws --> |book_new\nbook_append_sheet| wb
+ wb --> |writeFile\n\n| file
+```
+
+```ts
+import { useCallback } from 'kaioken';
+import { utils, writeFile } from 'xlsx';
+
+/* get state data and export to XLSX */
+const exportFile = useCallback(() => {
+ /* generate worksheet from state */
+ // highlight-next-line
+ const ws = utils.json_to_sheet(pres);
+ /* create workbook and append worksheet */
+ const wb = utils.book_new();
+ utils.book_append_sheet(wb, ws, "Data");
+ /* export to XLSX */
+ writeFile(wb, "SheetJSKaiokenAoO.xlsx");
+}, [pres]);
+```
+
+#### Complete Kaioponent
+
+This complete Kaioponent example fetches a test file and displays the data in a
+HTML table. When the export button is clicked, a callback will export a file:
+
+```tsx title="src/SheetJSKaiokenAoO.tsx"
+import { useCallback, useEffect, useState } from "kaioken";
+import { read, utils, writeFileXLSX } from 'xlsx';
+
+interface President {
+ Name: string;
+ Index: number;
+}
+
+export default function SheetJSKaiokenAoO() {
+ /* the kaioponent state is an array of presidents */
+ const [pres, setPres] = useState([]);
+
+ /* Fetch and update the state once */
+ useEffect(() => { (async() => {
+ const f = await (await fetch("https://sheetjs.com/pres.xlsx")).arrayBuffer();
+ const wb = read(f); // parse the array buffer
+ const ws = wb.Sheets[wb.SheetNames[0]]; // get the first worksheet
+ const data = utils.sheet_to_json(ws); // generate objects
+ setPres(data); // update state
+ })(); }, []);
+
+ /* get state data and export to XLSX */
+ const exportFile = useCallback(() => {
+ const ws = utils.json_to_sheet(pres);
+ const wb = utils.book_new();
+ utils.book_append_sheet(wb, ws, "Data");
+ writeFileXLSX(wb, "SheetJSKaiokenAoO.xlsx");
+ }, [pres]);
+
+ return (
Name
Index
+ { /* generate row for each president */
+ pres.map(pres => (
+
{pres.Name}
+
{pres.Index}
+
))
+ }
+
+
+
);
+}
+```
+
+How to run the example (click to hide)
+
+
+
+
+:::note Tested Deployments
+
+This demo was tested in the following environments:
+
+| Kaioken | ViteJS | Date |
+|:---------|:--------|:-----------|
+| `0.11.2` | `5.2.6` | 2024-03-24 |
+
+:::
+
+1) Create a new site.
+
+```bash
+npm create vite@latest sheetjs-kaioken -- --template vanilla-ts
+cd sheetjs-kaioken
+pnpm add --save kaioken
+pnpm add --save vite-plugin-kaioken -D
+```
+
+2) Create a new file `vite.config.ts` with the following content:
+
+```ts title="vite.config.ts (create new file)"
+import { defineConfig } from "vite"
+import kaioken from "vite-plugin-kaioken"
+
+export default defineConfig({
+ esbuild: {
+ jsxInject: `import * as kaioken from "kaioken"`,
+ jsx: "transform",
+ jsxFactory: "kaioken.createElement",
+ jsxFragment: "kaioken.fragment",
+ loader: "tsx",
+ include: ["**/*.tsx", "**/*.ts", "**/*.jsx", "**/*.js"],
+ },
+ plugins: [kaioken()],
+})
+```
+
+3) Edit `tsconfig.json` and add `"jsx": "preserve"` within `compilerOptions`:
+
+```js title="tsconfig.json (add highlighted line)"
+{
+ "compilerOptions": {
+// highlight-next-line
+ "jsx": "preserve",
+```
+
+4) Replace `src/main.ts` with the following codeblock:
+
+```ts title="src/main.ts (replace contents)"
+import { mount } from "kaioken";
+import App from "./SheetJSKaiokenAoO";
+
+const root = document.getElementById("app");
+mount(App, root!);
+```
+
+5) Create a new file `src/SheetJSKaiokenAoO.tsx` using the original code example.
+
+6) Install the SheetJS dependency and start the dev server:
+
+{`\
+pnpm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz
+pnpm run dev`}
+
+
+7) Open a web browser and access the displayed URL (`http://localhost:5173`)
+
+The page will refresh and show a table with an Export button. Click the button
+and the page will attempt to download `SheetJSKaiokenAoO.xlsx`.
+
+8) Build the site:
+
+```bash
+pnpm run build
+```
+
+The generated site will be placed in the `dist` folder.
+
+9) Start a local web server:
+
+```bash
+npx http-server dist
+```
+
+Access the displayed URL (typically `http://localhost:8080`) with a web browser
+and test the page.
+
+
+
+
+When the page loads, the app will fetch and
+display the data from the first worksheet in a TABLE. The "Export XLSX" button
+will generate a workbook that can be opened in a spreadsheet editor.
+
+
+
+### HTML
+
+The main disadvantage of the Array of Objects approach is the specific nature
+of the columns. For more general use, passing around an Array of Arrays works.
+However, this does not handle merge cells well!
+
+The [`sheet_to_html`](/docs/api/utilities/html#html-table-output) function
+generates HTML that is aware of merges and other worksheet features. To add the
+table to the page, the current recommendation involves setting the `innerHTML`
+attribute of a `ref`.
+
+In this example, the kaioponent attaches a `ref` to the `DIV` container. During
+export, the first `TABLE` child element can be parsed with [`table_to_book`](/docs/api/utilities/html#html-table-input) to
+generate a workbook object.
+
+```tsx title="src/SheetJSKaiokenHTML.tsx"
+import { useCallback, useEffect, useRef } from "kaioken";
+import { read, utils, writeFileXLSX } from 'xlsx';
+
+export default function SheetJSKaiokenHTML() {
+ /* the ref is used in export */
+ const tbl = useRef(null);
+
+ /* Fetch and update the state once */
+ useEffect(() => { (async() => {
+ const f = await (await fetch("https://sheetjs.com/pres.xlsx")).arrayBuffer();
+ const wb = read(f); // parse the array buffer
+ const ws = wb.Sheets[wb.SheetNames[0]]; // get the first worksheet
+ // highlight-start
+ const data = utils.sheet_to_html(ws); // generate HTML
+ if(tbl.current == null) return;
+ tbl.current.innerHTML = data;
+ // highlight-end
+ })(); }, []);
+
+ /* get live table and export to XLSX */
+ const exportFile = useCallback(() => {
+ // highlight-start
+ const elt = tbl.current!.getElementsByTagName("TABLE")[0];
+ const wb = utils.table_to_book(elt);
+ // highlight-end
+ writeFileXLSX(wb, "SheetJSKaiokenHTML.xlsx");
+ }, [tbl]);
+
+ return ( <>
+
+ // highlight-next-line
+
+ > );
+}
+```
+
+How to run the example (click to hide)
+
+
+
+
+:::note Tested Deployments
+
+This demo was tested in the following environments:
+
+| Kaioken | ViteJS | Date |
+|:---------|:--------|:-----------|
+| `0.11.2` | `5.2.6` | 2024-03-24 |
+
+:::
+
+1) Create a new site.
+
+```bash
+npm create vite@latest sheetjs-kaioken -- --template vanilla-ts
+cd sheetjs-kaioken
+pnpm add --save kaioken
+pnpm add --save vite-plugin-kaioken -D
+```
+
+2) Create a new file `vite.config.ts` with the following content:
+
+```ts title="vite.config.ts (create new file)"
+import { defineConfig } from "vite"
+import kaioken from "vite-plugin-kaioken"
+
+export default defineConfig({
+ esbuild: {
+ jsxInject: `import * as kaioken from "kaioken"`,
+ jsx: "transform",
+ jsxFactory: "kaioken.createElement",
+ jsxFragment: "kaioken.fragment",
+ loader: "tsx",
+ include: ["**/*.tsx", "**/*.ts", "**/*.jsx", "**/*.js"],
+ },
+ plugins: [kaioken()],
+})
+```
+
+3) Edit `tsconfig.json` and add `"jsx": "preserve"` within `compilerOptions`:
+
+```js title="tsconfig.json (add highlighted line)"
+{
+ "compilerOptions": {
+// highlight-next-line
+ "jsx": "preserve",
+```
+
+4) Replace `src/main.ts` with the following codeblock:
+
+```ts title="src/main.ts (replace contents)"
+import { mount } from "kaioken";
+import App from "./SheetJSKaiokenHTML";
+
+const root = document.getElementById("app");
+mount(App, root!);
+```
+
+5) Create a new file `src/SheetJSKaiokenHTML.tsx` using the original code example.
+
+6) Install the SheetJS dependency and start the dev server:
+
+{`\
+pnpm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz
+pnpm run dev`}
+
+
+7) Open a web browser and access the displayed URL (`http://localhost:5173`)
+
+The page will refresh and show a table with an Export button. Click the button
+and the page will attempt to download `SheetJSKaiokenHTML.xlsx`.
+
+8) Build the site:
+
+```bash
+pnpm run build
+```
+
+The generated site will be placed in the `dist` folder.
+
+9) Start a local web server:
+
+```bash
+npx http-server dist
+```
+
+Access the displayed URL (typically `http://localhost:8080`) with a web browser
+and test the page.
+
+
+
+
+When the page loads, the app will fetch and
+display the data from the first worksheet in a TABLE. The "Export XLSX" button
+will generate a workbook that can be opened in a spreadsheet editor.
+
+
+
+[^1]: See [`useState`](https://kaioken.dev/docs/hooks/usestate) in the Kaioken documentation.
+[^2]: See [`useEffect`](https://kaioken.dev/docs/hooks/useeffect) in the Kaioken documentation.
+[^3]: See [`useCallback`](https://kaioken.dev/docs/hooks/usecallback) in the Kaioken documentation.
+[^4]: See [`useCallback`](https://kaioken.dev/docs/hooks/usecallback) in the Kaioken documentation.
diff --git a/docz/docs/03-demos/02-frontend/01-react.md b/docz/docs/03-demos/02-frontend/02-react.md
similarity index 99%
rename from docz/docs/03-demos/02-frontend/01-react.md
rename to docz/docs/03-demos/02-frontend/02-react.md
index cd1212d..6212982 100644
--- a/docz/docs/03-demos/02-frontend/01-react.md
+++ b/docz/docs/03-demos/02-frontend/02-react.md
@@ -4,7 +4,7 @@ sidebar_label: ReactJS
description: Build interactive websites with ReactJS. Seamlessly integrate spreadsheets into your app using SheetJS. Bring Excel-powered workflows and data to the modern web.
pagination_prev: demos/index
pagination_next: demos/grid/index
-sidebar_position: 1
+sidebar_position: 2
---
import current from '/version.js';
diff --git a/docz/docs/03-demos/02-frontend/02-vue.md b/docz/docs/03-demos/02-frontend/04-vue.md
similarity index 99%
rename from docz/docs/03-demos/02-frontend/02-vue.md
rename to docz/docs/03-demos/02-frontend/04-vue.md
index 5b7f76f..20ad5d9 100644
--- a/docz/docs/03-demos/02-frontend/02-vue.md
+++ b/docz/docs/03-demos/02-frontend/04-vue.md
@@ -4,7 +4,7 @@ sidebar_label: VueJS
description: Build interactive websites with VueJS. Seamlessly integrate spreadsheets into your app using SheetJS. Bring Excel-powered workflows and data to the modern web.
pagination_prev: demos/index
pagination_next: demos/grid/index
-sidebar_position: 2
+sidebar_position: 4
---
import current from '/version.js';
diff --git a/docz/docs/03-demos/02-frontend/04-svelte.md b/docz/docs/03-demos/02-frontend/05-svelte.md
similarity index 99%
rename from docz/docs/03-demos/02-frontend/04-svelte.md
rename to docz/docs/03-demos/02-frontend/05-svelte.md
index c4e00fc..f34437f 100644
--- a/docz/docs/03-demos/02-frontend/04-svelte.md
+++ b/docz/docs/03-demos/02-frontend/05-svelte.md
@@ -4,7 +4,7 @@ sidebar_label: Svelte
description: Build interactive websites with Svelte. Seamlessly integrate spreadsheets into your app using SheetJS. Bring Excel-powered workflows and data to the modern web.
pagination_prev: demos/index
pagination_next: demos/grid/index
-sidebar_position: 4
+sidebar_position: 5
---
import current from '/version.js';
diff --git a/docz/docs/03-demos/03-net/08-headless.md b/docz/docs/03-demos/03-net/08-headless.md
index 054f03e..69f7d1b 100644
--- a/docz/docs/03-demos/03-net/08-headless.md
+++ b/docz/docs/03-demos/03-net/08-headless.md
@@ -405,7 +405,7 @@ This demo was tested in the following environments:
| Architecture | PhantomJS | Date |
|:-------------|:----------|:-----------|
| `darwin-x64` | `2.1.1` | 2024-03-15 |
-| `win10-x64` | `2.1.1` | 2024-02-23 |
+| `win10-x64` | `2.1.1` | 2024-03-24 |
:::
diff --git a/docz/docs/03-demos/19-desktop/03-wails.md b/docz/docs/03-demos/19-desktop/03-wails.md
index 0066636..d63e629 100644
--- a/docz/docs/03-demos/19-desktop/03-wails.md
+++ b/docz/docs/03-demos/19-desktop/03-wails.md
@@ -299,7 +299,7 @@ This demo was tested in the following environments:
|:---------------|:-------------|:---------|:-----------|
| macOS 14.4 | `darwin-x64` | `v2.8.0` | 2024-03-15 |
| macOS 14.1.2 | `darwin-arm` | `v2.6.0` | 2023-12-01 |
-| Windows 10 | `win10-x64` | `v2.8.0` | 2024-03-10 |
+| Windows 10 | `win10-x64` | `v2.8.0` | 2024-03-24 |
| Windows 11 | `win11-arm` | `v2.6.0` | 2023-12-01 |
| Linux (HoloOS) | `linux-x64` | `v2.8.0` | 2024-03-21 |
| Linux (Debian) | `linux-arm` | `v2.6.0` | 2023-12-01 |
diff --git a/docz/docs/03-demos/19-desktop/04-tauri.md b/docz/docs/03-demos/19-desktop/04-tauri.md
index 710f9dd..bd7f845 100644
--- a/docz/docs/03-demos/19-desktop/04-tauri.md
+++ b/docz/docs/03-demos/19-desktop/04-tauri.md
@@ -150,10 +150,14 @@ async function openFile() {
At this point, standard SheetJS utility functions[^8] can extract data from the
workbook object. The demo includes a button that calls `sheet_to_json`[^9] to
-generate an array of arrays of data. The following snippet uses VueJS framework
-but the same logic works with ReactJS and other front-end frameworks:
+generate an array of arrays of data.
-```js
+
+
+
+The following snippet uses the VueJS framework:
+
+```js title="VueJS sample"
import { utils } from 'xlsx';
import { shallowRef } from 'vue';
const data = shallowRef([[]]); // update data by setting `data.value`
@@ -174,6 +178,45 @@ const open_button_callback = async() => {
};
```
+
+
+
+The following snippet shows a simple Kaioponent:
+
+```tsx title="Kaioponent for importing data"
+import { utils } from 'xlsx';
+import { useState } from 'kaioken';
+
+function SheetJSImportKaioponent() {
+ const [data, setData] = useState([]);
+
+ const open_callback = async() => {
+ const wb = await openFile();
+
+ /* get the first worksheet */
+ // highlight-start
+ const ws = wb.Sheets[wb.SheetNames[0]];
+ // highlight-end
+
+ /* get data from the first worksheet */
+ // highlight-start
+ const array = utils.sheet_to_json(ws, { header: 1 });
+ // highlight-end
+ setData(array);
+ };
+
+ return ( <>
+
+
{data.map((row) =>
+
{row.map((cell) =>
{cell}
)}
+ )}
+ >);
+}
+```
+
+
+
+
### Writing Files
There are three steps to writing files:
@@ -221,10 +264,14 @@ async function saveFile(wb) {
The demo includes a button that calls `aoa_to_sheet`[^14] to generate a sheet
from array of arrays of data. A workbook is constructed using `book_new` and
-`book_append_sheet`[^15]. The following snippet uses VueJS framework but the
-same logic works with ReactJS and other front-end frameworks:
+`book_append_sheet`[^15].
-```js
+
+
+
+The following snippet uses the VueJS framework:
+
+```js title="VueJS sample"
import { utils } from 'xlsx';
import { shallowRef } from 'vue';
const data = shallowRef([[]]); // `data.value` is an array of arrays
@@ -249,6 +296,45 @@ const save_button_callback = async() => {
}
```
+
+
+
+The following snippet shows a simple Kaioponent:
+
+```js title="Kaioponent for exporting data"
+import { utils } from 'xlsx';
+import { useState } from 'kaioken';
+
+function SheetJSExportKaioponent() {
+ const [data, setData] = useState(["SheetJS".split(""), "Kaioken".split("")]);
+
+ const save_callback = async() => {
+ /* generate worksheet from the data */
+ // highlight-start
+ const ws = utils.aoa_to_sheet(data);
+ // highlight-end
+
+ /* create a new workbook object */
+ // highlight-start
+ const wb = utils.book_new();
+ // highlight-end
+
+ /* append the worksheet to the workbook using the sheet name "SheetJSTauri" */
+ // highlight-start
+ utils.book_append_sheet(wb, ws, "SheetJSTauri");
+ // highlight-end
+
+ await saveFile(wb);
+ }
+
+ return ( );
+}
+
+```
+
+
+
+
## Complete Example
:::note Tested Deployments
@@ -259,7 +345,7 @@ This demo was tested in the following environments:
|:---------------|:-------------|:----------|:-----------|
| macOS 14.4 | `darwin-x64` | `v1.5.11` | 2024-03-15 |
| macOS 14.0 | `darwin-arm` | `v1.5.2` | 2023-10-18 |
-| Windows 10 | `win10-x64` | `v1.5.0` | 2023-10-01 |
+| Windows 10 | `win10-x64` | `v1.5.11` | 2024-03-24 |
| Windows 11 | `win11-arm` | `v1.5.7` | 2023-12-01 |
| Linux (HoloOS) | `linux-x64` | `v1.5.11` | 2024-03-21 |
| Linux (Debian) | `linux-arm` | `v1.5.7` | 2023-12-01 |
@@ -309,10 +395,30 @@ build step will correctly detect the platform architecture.
1) Create a new Tauri app:
+
+
+
```bash
npm create tauri-app@latest -- -m npm -t vue-ts SheetJSTauri -y
```
+
+
+
+:::note pass
+
+There is no official Tauri Kaioken template. This demo starts from the vanilla
+TypeScript template and manually wires Kaioken
+
+:::
+
+```bash
+npm create tauri-app@latest -- -m npm -t vanilla-ts SheetJSTauri -y
+```
+
+
+
+
2) Enter the directory and install dependencies:
{`\
@@ -322,6 +428,20 @@ npm i --save @tauri-apps/api
npm i --save-dev @tauri-apps/cli`}
+
+
+
+
+
+
+```bash
+npm add kaioken --save
+npm add vite-plugin-kaioken -D --save
+```
+
+
+
+
3) Add the highlighted lines to `src-tauri/tauri.conf.json` in the
`tauri.allowlist` section:
@@ -353,6 +473,8 @@ In the same file, look for the `"identifier"` key and replace the value with `co
"longDescription": "",
```
+
+
4) Download [`App.vue`](pathname:///tauri/App.vue) and replace `src/App.vue`
with the downloaded script.
@@ -361,6 +483,99 @@ In the same file, look for the `"identifier"` key and replace the value with `co
curl -o src/App.vue https://docs.sheetjs.com/tauri/App.vue
```
+
+
+
+4) Wire up Kaioken to the Tauri app:
+
+- Add the highlighted lines to `vite.config.ts`:
+
+```ts title="vite.config.ts (add highlighted lines)"
+import { defineConfig } from "vite";
+// highlight-next-line
+import kaioken from "vite-plugin-kaioken"
+
+// https://vitejs.dev/config/
+export default defineConfig(async () => ({
+// highlight-start
+ esbuild: {
+ jsxInject: `import * as kaioken from "kaioken"`,
+ jsx: "transform",
+ jsxFactory: "kaioken.createElement",
+ jsxFragment: "kaioken.fragment",
+ loader: "tsx",
+ include: ["**/*.tsx", "**/*.ts", "**/*.jsx", "**/*.js"],
+ },
+ plugins: [kaioken()],
+// highlight-end
+```
+
+- Add the highlighted line to `tsconfig.json`:
+
+```js title="tsconfig.json (add highlighted line)"
+{
+ "compilerOptions": {
+// highlight-next-line
+ "jsx": "preserve",
+ "target": "ES2020",
+```
+
+- Replace `index.html` with the following codeblock:
+
+```html title="index.html"
+
+
+
+
+
+
+ SheetJS x Tauri
+
+
+
+
+
+
+
+```
+
+- Add the following lines to `src/styles.css`:
+
+```css title="src/styles.css (add to end)"
+.logo {
+ padding: 0px;
+ height: 64px; width: 64px;
+ vertical-align: middle;
+}
+.logo:hover {
+ filter: drop-shadow(0 0 2em #646cffaa);
+}
+.centre { text-align: center; }
+table.center {
+ margin-left: auto;
+ margin-right: auto;
+}
+```
+
+- Replace `src/main.ts` with the following codeblock:
+
+```ts title="src/main.ts"
+import { mount } from "kaioken";
+import App from "./App";
+
+const root = document.getElementById("container");
+mount(App, root!);
+```
+
+- Download [`App.tsx`](pathname:///tauri/App.tsx) and save to `src/App.tsx`:
+
+```bash
+curl -o src/App.tsx https://docs.sheetjs.com/tauri/App.tsx
+```
+
+
+
+
5) Build the app with
```bash
diff --git a/docz/docs/03-demos/19-desktop/05-neutralino.md b/docz/docs/03-demos/19-desktop/05-neutralino.md
index d04cb1d..cde5e5f 100644
--- a/docz/docs/03-demos/19-desktop/05-neutralino.md
+++ b/docz/docs/03-demos/19-desktop/05-neutralino.md
@@ -194,7 +194,7 @@ This demo was tested in the following environments:
|:---------------|:-------------|:---------|:---------|:-----------|
| macOS 14.4 | `darwin-x64` | `5.0.0` | `5.0.1` | 2024-03-15 |
| macOS 14.0 | `darwin-arm` | `4.14.1` | `3.12.0` | 2023-10-18 |
-| Windows 10 | `win10-x64` | `4.14.1` | `3.12.0` | 2023-12-09 |
+| Windows 10 | `win10-x64` | `5.1.0` | `5.1.0` | 2024-03-24 |
| Windows 11 | `win11-arm` | `4.14.1` | `3.12.0` | 2023-12-01 |
| Linux (HoloOS) | `linux-x64` | `5.0.0` | `5.0.1` | 2024-03-21 |
| Linux (Debian) | `linux-arm` | `4.14.1` | `3.12.0` | 2023-12-01 |
diff --git a/docz/docs/03-demos/19-desktop/06-reactnative.md b/docz/docs/03-demos/19-desktop/06-reactnative.md
index 047eb9b..bae9a78 100644
--- a/docz/docs/03-demos/19-desktop/06-reactnative.md
+++ b/docz/docs/03-demos/19-desktop/06-reactnative.md
@@ -46,10 +46,10 @@ This demo was tested in the following environments:
| OS and Version | Architecture | RN Platform | Date |
|:---------------|:-------------|:------------|:-----------|
-| Windows 10 | `win10-x64` | `v0.72.16` | 2023-10-27 |
+| Windows 10 | `win10-x64` | `v0.73.11` | 2024-03-24 |
| Windows 11 | `win11-x64` | `v0.72.12` | 2023-10-14 |
| Windows 11 | `win11-arm` | `v0.72.20` | 2023-12-01 |
-| MacOS 14.4 | `darwin-x64` | `v0.73.21` | 2024-03-15 |
+| MacOS 14.4 | `darwin-x64` | `v0.73.22` | 2024-03-24 |
| MacOS 14.1.2 | `darwin-arm` | `v0.72.11` | 2023-12-01 |
:::
@@ -420,10 +420,10 @@ setup instructions" to find instructions for manual installation.
### Project Setup
-1) Create a new project using React Native `0.72.7`:
+1) Create a new project using React Native `0.73.6`:
```bash
-npx react-native init SheetJSWin --template react-native@0.72.7
+npx react-native init SheetJSWin --template react-native@0.73.6
cd SheetJSWin
```
@@ -527,7 +527,7 @@ curl -Lo windows/SheetJSWin/DocumentPicker.cs https://docs.sheetjs.com/reactnati
Search for `ReactPackageProvider.cs` in the file. There will be one instance.
Add the highlighted line just before that instance:
-```xml title="windows\SheetJSWin\SheetJSWin.csproj"
+```xml title="windows\SheetJSWin\SheetJSWin.csproj (add highlighted line)"
diff --git a/docz/docs/03-demos/20-cli/23-deno.md b/docz/docs/03-demos/20-cli/23-deno.md
index 179edca..e3a82b9 100644
--- a/docz/docs/03-demos/20-cli/23-deno.md
+++ b/docz/docs/03-demos/20-cli/23-deno.md
@@ -101,7 +101,7 @@ This demo was last tested in the following deployments:
|:-------------|:---------|:-----------|
| `darwin-x64` | `1.41.3` | 2024-03-15 |
| `darwin-arm` | `1.37.2` | 2023-10-18 |
-| `win10-x64` | `1.37.1` | 2023-10-09 |
+| `win10-x64` | `1.41.3` | 2024-03-24 |
| `win11-x64` | `1.37.2` | 2023-10-14 |
| `win11-arm` | `1.38.4` | 2023-12-01 |
| `linux-x64` | `1.41.3` | 2024-03-18 |
@@ -114,7 +114,7 @@ This demo was last tested in the following deployments:
1) Download the test file :
```bash
-curl -LO https://sheetjs.com/pres.numbers
+curl -o pres.numbers https://sheetjs.com/pres.numbers
```
2) Test the script with `deno run`:
diff --git a/docz/docs/03-demos/20-cli/index.md b/docz/docs/03-demos/20-cli/index.md
index ae7a3f1..470ade6 100644
--- a/docz/docs/03-demos/20-cli/index.md
+++ b/docz/docs/03-demos/20-cli/index.md
@@ -103,7 +103,7 @@ This demo was tested in the following deployments:
|:-------------|:--------|:---------|:-----------|
| `darwin-x64` | `5.8.1` | `18.5.0` | 2024-03-15 |
| `darwin-arm` | `5.8.1` | `18.5.0` | 2023-12-01 |
-| `win10-x64` | `5.8.1` | `18.5.0` | 2023-10-09 |
+| `win10-x64` | `5.8.1` | `18.5.0` | 2024-03-24 |
| `win11-arm` | `5.8.1` | `18.5.0` | 2023-12-01 |
| `linux-x64` | `5.8.1` | `18.5.0` | 2024-03-21 |
| `linux-arm` | `5.8.1` | `18.5.0` | 2023-12-01 |
@@ -115,7 +115,7 @@ This demo was tested in the following deployments:
|:-------------|:--------|:----------|:-----------|
| `darwin-x64` | `2.4.0` | `21.7.1` | 2024-03-15 |
| `darwin-arm` | `2.3.0` | `21.3.0` | 2023-12-01 |
-| `win10-x64` | `2.1.2` | `16.20.2` | 2023-10-09 |
+| `win10-x64` | `2.4.0` | `16.20.2` | 2024-03-24 |
| `linux-x64` | `2.4.0` | `21.7.1` | 2024-03-21 |
| `linux-arm` | `2.3.0` | `21.3.0` | 2023-12-01 |
@@ -127,13 +127,13 @@ This demo was tested in the following deployments:
0) Download the test file :
```bash
-curl -LO https://sheetjs.com/pres.numbers
+curl -o pres.numbers https://sheetjs.com/pres.numbers
```
1) Download [`xlsx-cli.js`](pathname:///cli/xlsx-cli.js)
```bash
-curl -LO https://docs.sheetjs.com/cli/xlsx-cli.js
+curl -o xlsx-cli.js https://docs.sheetjs.com/cli/xlsx-cli.js
```
2) Install the dependencies:
@@ -279,9 +279,35 @@ npx boxednode@2.4.0 -s xlsx-cli.js -t xlsx-cli.exe -n 16.20.2
:::info pass
The Windows 10 build requires Visual Studio with "Desktop development with C++"
-workload, Python 3, and NASM[^1].
+workload, Python 3.11, and NASM[^1].
-The build command should be run in "x64 Native Tools Command Prompt"
+**The build command must be run in "x64 Native Tools Command Prompt"**
+
+:::
+
+:::caution pass
+
+When the demo was last tested, the build failed:
+
+```
+Not an executable Python program
+Could not find Python.
+```
+
+By default, Windows aliases `python` to a Microsoft Store installer. If the
+official installer was used, the alias should be disabled manually:
+
+1) Open Start menu and type "app alias". Click "Manage app execution aliases".
+
+2) Disable the App Installer for all items with `python` in the name.
+
+Using Python 3.12, the build fails with an error:
+
+```
+Please use python3.11 or python3.10 or python3.9 or python3.8 or python3.7 or python3.6.
+```
+
+In the most recent test, Python 3.11.8 was installed from the official site.
:::
@@ -345,7 +371,7 @@ This demo was last tested in the following deployments:
|:-------------|:--------------|:---------|:-----------|
| `darwin-x64` | `12.3.219.9` | `0.88.0` | 2024-03-15 |
| `darwin-arm` | `11.8.172.13` | `0.79.2` | 2023-10-18 |
-| `win10-x64` | `11.8.172.13` | `0.79.2` | 2023-10-09 |
+| `win10-x64` | `12.3.219.9` | `0.88.0` | 2024-03-24 |
| `win11-x64` | `11.8.172.13` | `0.79.2` | 2023-10-14 |
| `linux-x64` | `12.3.219.9` | `0.88.0` | 2024-03-18 |
| `linux-arm` | `12.0.267.8` | `0.82.0` | 2023-12-01 |
@@ -366,9 +392,9 @@ cd sheetjs2csv
- [`sheet2csv.rs`](pathname:///cli/sheet2csv.rs)
```bash
-curl -LO https://docs.sheetjs.com/cli/Cargo.toml
-curl -LO https://docs.sheetjs.com/cli/snapshot.rs
-curl -LO https://docs.sheetjs.com/cli/sheet2csv.rs
+curl -o Cargo.toml https://docs.sheetjs.com/cli/Cargo.toml
+curl -o snapshot.rs https://docs.sheetjs.com/cli/snapshot.rs
+curl -o sheet2csv.rs https://docs.sheetjs.com/cli/sheet2csv.rs
```
2) Download the SheetJS Standalone script and move to the project directory:
@@ -378,7 +404,7 @@ curl -LO https://docs.sheetjs.com/cli/sheet2csv.rs
{`\
-curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js`}
+curl -o xlsx.full.min.js https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js`}
3) Build the V8 snapshot:
@@ -414,7 +440,7 @@ cargo build --release --bin sheet2csv
5) Download the test file :
```bash
-curl -LO https://sheetjs.com/pres.numbers
+curl -o pres.numbers https://sheetjs.com/pres.numbers
```
6) Test the application:
diff --git a/docz/docs/03-demos/42-engines/01-duktape.md b/docz/docs/03-demos/42-engines/01-duktape.md
index 158b7fc..af22292 100644
--- a/docz/docs/03-demos/42-engines/01-duktape.md
+++ b/docz/docs/03-demos/42-engines/01-duktape.md
@@ -132,7 +132,7 @@ This demo was tested in the following deployments:
|:-------------|:--------|:-----------|
| `darwin-x64` | `2.7.0` | 2024-03-15 |
| `darwin-arm` | `2.7.0` | 2023-10-18 |
-| `win10-x64` | `2.7.0` | 2023-10-27 |
+| `win10-x64` | `2.7.0` | 2024-03-27 |
| `win11-arm` | `2.7.0` | 2023-12-01 |
| `linux-x64` | `2.7.0` | 2024-03-21 |
| `linux-arm` | `2.7.0` | 2023-12-01 |
diff --git a/docz/docs/03-demos/42-engines/02-v8.md b/docz/docs/03-demos/42-engines/02-v8.md
index 52647ab..5b5bfd7 100644
--- a/docz/docs/03-demos/42-engines/02-v8.md
+++ b/docz/docs/03-demos/42-engines/02-v8.md
@@ -126,7 +126,7 @@ This demo was tested in the following deployments:
|:--------------|:-------------|:--------------|:-----------------|:-----------|
| `12.4.253` | `darwin-x64` | macOS 14.4 | `clang 15.0.0` | 2024-03-15 |
| `12.1.283` | `darwin-arm` | macOS 14.1.2 | `clang 15.0.0` | 2023-12-01 |
-| `12.0.265` | `win10-x64` | Windows 10 | `CL 19.37.32822` | 2023-10-28 |
+| `12.5.48` | `win10-x64` | Windows 10 | `CL 19.39.33523` | 2024-03-24 |
| `12.5.48` | `linux-x64` | HoloOS 3.5.17 | `gcc 13.1.1` | 2024-03-21 |
| `11.8.82` | `linux-arm` | Debian 12 | `gcc 12.2.0` | 2023-12-01 |
@@ -865,7 +865,7 @@ This demo was last tested in the following deployments:
|:-------------|:---------|:-----------|
| `darwin-x64` | `0.88.0` | 2024-03-15 |
| `darwin-arm` | `0.82.0` | 2023-12-01 |
-| `win10-x64` | `0.81.0` | 2023-11-14 |
+| `win10-x64` | `0.89.0` | 2024-03-24 |
| `linux-x64` | `0.89.0` | 2024-03-21 |
| `linux-arm` | `0.82.0` | 2023-12-01 |
diff --git a/docz/docs/03-demos/42-engines/06-goja.md b/docz/docs/03-demos/42-engines/06-goja.md
index ad6628d..f5d3fc3 100644
--- a/docz/docs/03-demos/42-engines/06-goja.md
+++ b/docz/docs/03-demos/42-engines/06-goja.md
@@ -96,7 +96,7 @@ This demo was tested in the following deployments:
|:-------------|:-----------|:-----------|:-----------|
| `darwin-x64` | `e401ed4` | `1.22.1` | 2024-03-15 |
| `darwin-arm` | `873a149` | `1.21.3` | 2023-10-18 |
-| `win10-x64` | `b396bb4` | `1.21.3` | 2023-10-28 |
+| `win10-x64` | `e401ed4` | `1.22.1` | 2024-03-24 |
| `win11-arm` | `b396bb4` | `1.21.1` | 2023-12-01 |
| `linux-x64` | `e401ed4` | `1.22.1` | 2024-03-21 |
| `linux-arm` | `b396bb4` | `1.21.4` | 2023-12-01 |
diff --git a/docz/docs/03-demos/42-engines/09-hermes.md b/docz/docs/03-demos/42-engines/09-hermes.md
index c972582..668097c 100644
--- a/docz/docs/03-demos/42-engines/09-hermes.md
+++ b/docz/docs/03-demos/42-engines/09-hermes.md
@@ -374,7 +374,7 @@ fork, which powers React Native for Windows, does have built-in support[^5]
| Architecture | Git Commit | Date |
|:-------------|:-----------|:-----------|
-| `win10-x64` | `930456b` | 2023-10-28 |
+| `win10-x64` | `240573e` | 2024-03-24 |
The ["Windows Example"](#windows-example) covers `hermes-windows`.
@@ -544,12 +544,15 @@ contents of the first sheet as CSV rows.
Installation Notes (click to show)
-CMake and Visual Studio with "Desktop development with C++" workload must be
-installed. In addition, the following Spectre-mitigated libs must be added:
+The build sequence requires Python, which can be installed from the official
+Windows installer[^7].
-- MSVC C++ Spectre-mitigated libs (Latest)
-- C++ ATL for latest build tools with Spectre Mitigations
-- C++ MFC for latest build tools with Spectre Mitigations
+Visual Studio with "Desktop development with C++" workload and Cmake must be
+installed[^8]. In addition, the following Spectre-mitigated libs must be added:
+
+- MSVC C++ x64/x86 Spectre-mitigated libs (Latest)
+- C++ ATL for latest build tools with Spectre Mitigations (x86 & x64)
+- C++ MFC for latest build tools with Spectre Mitigations (x86 & x64)
The easiest way to install is to select "Individual components" and search for
"spectre latest" (no quotation marks). Pick each option for the relevant CPU.
@@ -604,7 +607,7 @@ cd sheetjs-hermes
```bash
git clone https://github.com/microsoft/hermes-windows
cd hermes-windows
-git checkout 930456b
+git checkout 240573e
cd ..
```
@@ -645,7 +648,7 @@ Set-ExecutionPolicy -ExecutionPolicy RemoteSigned
:::info pass
-In the most recent test, the command failed when trying to copy `hermes.exe`:
+In some test runs, the command failed when trying to copy `hermes.exe`:
```
Copy-Item: C:\Users\Me\Documents\hermes-windows\.ado\scripts\cibuild.ps1:331
@@ -671,7 +674,7 @@ dir -r -Path .\hermes-windows\workspace\build\win32-x64-debug\ -Filter "*.lib" |
7) Download [`sheetjs-hermes.cpp`](pathname:///hermes/sheetjs-hermesw.cpp):
```bash
-curl -LO https://docs.sheetjs.com/hermes/sheetjs-hermesw.cpp
+curl -o sheetjs-hermesw.cpp https://docs.sheetjs.com/hermes/sheetjs-hermesw.cpp
```
8) Build the application:
@@ -695,8 +698,8 @@ the project directory:
{`\
-curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js
-curl -LO https://sheetjs.com/pres.numbers`}
+curl -o xlsx.full.min.js https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js
+curl -o pres.numbers https://sheetjs.com/pres.numbers`}
10) Run the application:
@@ -822,4 +825,6 @@ If successful, the script will print CSV data from the test file.
[^3]: See ["Workbook Object"](/docs/csf/book)
[^4]: See [`sheet_to_csv` in "Utilities"](/docs/api/utilities/csv#csv-output)
[^5]: See [`microsoft/hermes-windows`](https://github.com/microsoft/hermes-windows) on GitHub
-[^6]: See ["Dependencies" in "Building and Running"](https://hermesengine.dev/docs/building-and-running/#dependencies) in the Hermes Documentation
\ No newline at end of file
+[^6]: See ["Dependencies" in "Building and Running"](https://hermesengine.dev/docs/building-and-running/#dependencies) in the Hermes Documentation
+[^7]: See ["Download Python"](https://www.python.org/downloads/) in the Python website.
+[^8]: See [the Visual Studio website](https://visualstudio.microsoft.com/#vs-section) for download links.
diff --git a/docz/static/reactnative/rnm.png b/docz/static/reactnative/rnm.png
index b5a357e..a8a0bfb 100644
Binary files a/docz/static/reactnative/rnm.png and b/docz/static/reactnative/rnm.png differ
diff --git a/docz/static/reactnative/rnw.png b/docz/static/reactnative/rnw.png
index 85951d3..01a7226 100644
Binary files a/docz/static/reactnative/rnw.png and b/docz/static/reactnative/rnw.png differ
diff --git a/docz/static/tauri/App.tsx b/docz/static/tauri/App.tsx
new file mode 100644
index 0000000..b462ce3
--- /dev/null
+++ b/docz/static/tauri/App.tsx
@@ -0,0 +1,86 @@
+import { useEffect, useState } from 'kaioken'
+import { read, write, utils, version, WorkBook } from 'xlsx';
+import { DialogFilter, message, open, save } from '@tauri-apps/api/dialog';
+import { fetch, ResponseType } from '@tauri-apps/api/http';
+import { readBinaryFile, writeBinaryFile } from '@tauri-apps/api/fs';
+
+const filters: DialogFilter[] = [
+ {name: "Excel Binary Workbook", extensions: ["xlsb"]},
+ {name: "Excel Workbook", extensions: ["xlsx"]},
+ {name: "Excel 97-2004 Workbook", extensions: ["xls"]},
+ {name: "Excel 2003 XML Spreadsheet", extensions: ["xml"]},
+ {name: "Symbolic Link", extensions: ["slk"]},
+ {name: "Flat OpenDocument Spreadsheet", extensions: ["fods"]},
+ {name: "OpenDocument Spreadsheet", extensions: ["fods"]},
+ // ...
+];
+
+export default function SheetJSTauriKaioken() {
+ const [data, setData] = useState([[]])
+ const [origin, setOrigin] = useState("");
+
+ const update = (wb: WorkBook) => {
+ const ws = wb.Sheets[wb.SheetNames[0]];
+ const d = utils.sheet_to_json(ws, { header: 1})
+ setData(d);
+ };
+
+ /* Load from File */
+ const openFile = async() => {
+ try {
+ const selected = await open({
+ title: "Open Spreadsheet",
+ multiple: false,
+ directory: false,
+ filters
+ }) as string;
+ const d = await readBinaryFile(selected);
+ const wb = read(d);
+ update(wb);
+ setOrigin(selected);
+ } catch(e) { await message((e as Error).message || (e as string), { title: "Load Error", type: "error"}); }
+ };
+
+ /* Save to File */
+ const saveFile = async() => {
+ try {
+ const selected = await save({
+ title: "Save to Spreadsheet",
+ filters
+ });
+ if(!selected) throw new Error("No file selected");
+ const ws = utils.aoa_to_sheet(data);
+ const wb = utils.book_new();
+ utils.book_append_sheet(wb, ws, "SheetJSTauri");
+ const d = write(wb, {type: "buffer", bookType: selected.slice(selected.lastIndexOf(".") + 1) as any}) as Uint8Array;
+ await writeBinaryFile(selected, d);
+ await message(`File saved to ${selected}`);
+ } catch(e) { await message((e as Error).message || (e as string), { title: "Save Error", type: "error"}); }
+ };
+
+ /* Download from https://sheetjs.com/pres.numbers */
+ useEffect(() => {(async() => {
+ try {
+ setOrigin("https://sheetjs.com/pres.numbers");
+ const response = await fetch("https://sheetjs.com/pres.numbers", { method: "GET", responseType: ResponseType.Binary });
+ const wb = read(new Uint8Array(response.data));
+ update(wb);
+ } catch(e) { await message((e as Error).message || (e as string), { title: "Fetch Error", type: "error"}); }
+ })(); }, []);
+
+ return (
+ );
+}
\ No newline at end of file
diff --git a/docz/static/tauri/win10.png b/docz/static/tauri/win10.png
index 4d411f0..278552a 100644
Binary files a/docz/static/tauri/win10.png and b/docz/static/tauri/win10.png differ
diff --git a/docz/static/wails/win10.png b/docz/static/wails/win10.png
index 645cd41..f8d8632 100644
Binary files a/docz/static/wails/win10.png and b/docz/static/wails/win10.png differ