From 4bf7b0e0be0e6193ad7fa777b88a75466419fb66 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sat, 18 Oct 2025 18:30:01 +0000 Subject: [PATCH] docs: Add comprehensive documentation for Helium IDE Co-authored-by: mitchellmmarkgeorge --- docs/README.md | 10 ++++++++++ docs/api/README.md | 9 +++++++++ docs/api/app.md | 35 +++++++++++++++++++++++++++++++++++ docs/api/constants.md | 14 ++++++++++++++ docs/api/fs.md | 33 +++++++++++++++++++++++++++++++++ docs/api/shopify.md | 32 ++++++++++++++++++++++++++++++++ docs/api/utils.md | 15 +++++++++++++++ docs/components/Button.md | 21 +++++++++++++++++++++ docs/components/Checkbox.md | 16 ++++++++++++++++ docs/components/IconButton.md | 17 +++++++++++++++++ docs/components/Input.md | 16 ++++++++++++++++ docs/components/Modals.md | 31 +++++++++++++++++++++++++++++++ docs/components/README.md | 12 ++++++++++++ docs/components/Spinner.md | 15 +++++++++++++++ docs/components/Text.md | 18 ++++++++++++++++++ docs/components/Toast.md | 18 ++++++++++++++++++ docs/hooks/README.md | 4 ++++ docs/hooks/useFileIcon.md | 21 +++++++++++++++++++++ docs/hooks/useWorkspace.md | 25 +++++++++++++++++++++++++ docs/ipc/README.md | 17 +++++++++++++++++ docs/types/README.md | 4 ++++ docs/types/common.md | 21 +++++++++++++++++++++ docs/types/main.md | 7 +++++++ 23 files changed, 411 insertions(+) create mode 100644 docs/README.md create mode 100644 docs/api/README.md create mode 100644 docs/api/app.md create mode 100644 docs/api/constants.md create mode 100644 docs/api/fs.md create mode 100644 docs/api/shopify.md create mode 100644 docs/api/utils.md create mode 100644 docs/components/Button.md create mode 100644 docs/components/Checkbox.md create mode 100644 docs/components/IconButton.md create mode 100644 docs/components/Input.md create mode 100644 docs/components/Modals.md create mode 100644 docs/components/README.md create mode 100644 docs/components/Spinner.md create mode 100644 docs/components/Text.md create mode 100644 docs/components/Toast.md create mode 100644 docs/hooks/README.md create mode 100644 docs/hooks/useFileIcon.md create mode 100644 docs/hooks/useWorkspace.md create mode 100644 docs/ipc/README.md create mode 100644 docs/types/README.md create mode 100644 docs/types/common.md create mode 100644 docs/types/main.md diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..b2559b4 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,10 @@ +# Helium IDE Documentation + +- **Overview**: Electron + React (MobX) IDE for Shopify themes. +- **Global API**: `window.helium` exposed via Electron preload. +- **Sections**: + - [API](./api/README.md) + - [Hooks](./hooks/README.md) + - [Components](./components/README.md) + - [Types](./types/README.md) + - [IPC](./ipc/README.md) diff --git a/docs/api/README.md b/docs/api/README.md new file mode 100644 index 0000000..22547f0 --- /dev/null +++ b/docs/api/README.md @@ -0,0 +1,9 @@ +# API + +Public APIs exposed to the renderer via `window.helium`. + +- [App](./app.md) +- [File System](./fs.md) +- [Shopify](./shopify.md) +- [Utils](./utils.md) +- [Constants](./constants.md) diff --git a/docs/api/app.md b/docs/api/app.md new file mode 100644 index 0000000..6a5ba6f --- /dev/null +++ b/docs/api/app.md @@ -0,0 +1,35 @@ +# App API + +Global: `window.helium.app` + +## Methods + +- **closeWindow() => Promise**: Close the current window. +- **setWindowTitle(title: string) => Promise**: Set the Electron window title. +- **minimizeWindow() => Promise**: Minimize window. +- **maximizeWindow() => Promise**: Maximize window. +- **getWindowState() => Promise**: Returns `{ isMinimized, isMaximized, isFocused }`. +- **openFolderDialog() => Promise**: Show OS directory picker and return selected paths. +- **loadInitalState() => Promise**: Load persisted state when app starts. +- **openUrl(url: string) => Promise**: Open `url` in external browser. +- **on()(eventName: E, cb: (arg: any) => void) => void**: Subscribe to a custom event sent from main. +- **sendWorkspaceIsShowing() => void**: Notify main when workspace view is visible. +- **showNewFileContextMenu() => void**: Show context menu for creating a file at root. +- **showFileItemContextMenu(filePath: string) => void**: Show file item context menu. +- **showFolderItemContextMenu(folderPath: string) => void**: Show folder item context menu. +- **showEditorContextMenu() => void**: Show editor context menu (reserved). + +## Examples + +```ts +// Set title +window.helium.app.setWindowTitle("My Theme – Helium"); + +// Listen for a custom event from main +window.helium.app.on()("on-preview-state-change", (state) => { + console.log("Preview state:", state); +}); + +// Open a directory +const [themePath] = await window.helium.app.openFolderDialog(); +``` diff --git a/docs/api/constants.md b/docs/api/constants.md new file mode 100644 index 0000000..17b59c5 --- /dev/null +++ b/docs/api/constants.md @@ -0,0 +1,14 @@ +# Constants + +Global: `window.helium.constants` + +## Values +- **DEFAULT_WINOW_TITLE: string** +- **DEFAULT_PREVIEW_HOST: string** +- **DEFAULT_PREVIEW_PORT: string** +- **DEFAULT_INITAL_STATE: InitalState** + +## Example +```ts +const { DEFAULT_PREVIEW_HOST, DEFAULT_PREVIEW_PORT } = window.helium.constants; +``` diff --git a/docs/api/fs.md b/docs/api/fs.md new file mode 100644 index 0000000..6097e04 --- /dev/null +++ b/docs/api/fs.md @@ -0,0 +1,33 @@ +# File System API + +Global: `window.helium.fs` + +## Methods +- **readFile({ filePath, encoding }) => Promise** +- **writeFile({ filePath, content, encoding }) => Promise** +- **deleteFile(path: string) => Promise** +- **trashItem(path: string) => Promise** +- **deleteDirectory(path: string) => Promise** +- **createDirectory(path: string) => Promise** +- **createFile(path: string) => Promise** +- **readDirectory(path: string) => Promise** +- **pathExists(path: string) => Promise** +- **rename({ oldPath, newPath }) => Promise** +- **watchDirectory(path: string) => Promise** +- **stopWatchingDirectory(path: string) => Promise** +- **removeAllDirectoryWatchers() => Promise** +- **onDirectoryChange(cb: (change: ThemeDirectoryChange) => void) => void** +- **onFileChange(cb: (change: ThemeDirectoryChange) => void) => void** +- **detectFileType(path: string) => Promise** + +## Examples +```ts +// Read a file +const content = await window.helium.fs.readFile({ filePath, encoding: "utf8" }); + +// Write file +await window.helium.fs.writeFile({ filePath, content: "hello", encoding: "utf8" }); + +// List entries in a directory +const entries = await window.helium.fs.readDirectory(themePath); +``` diff --git a/docs/api/shopify.md b/docs/api/shopify.md new file mode 100644 index 0000000..c6e96b6 --- /dev/null +++ b/docs/api/shopify.md @@ -0,0 +1,32 @@ +# Shopify API + +Global: `window.helium.shopify` + +## Methods +- **openTheme(path: string) => Promise** +- **startThemePreview(options?: { host: string; port: string }) => Promise** +- **stopThemePreview() => Promise** +- **pullTheme(themeId: string) => Promise** +- **pushTheme() => Promise** +- **connectStore(options: { storeName: string; storeUrl: string; password: string }) => Promise** +- **disconnectStore() => Promise** +- **getConnectedStore() => Promise** + +## Events +- **onThemeInfoChange(cb: (info: ThemeInfo) => void) => void** +- **onPreviewStateChange(cb: (state: PreviewState) => void) => void** +- **onStoreChange(cb: (store: StoreInfo) => void) => void** + +## Examples +```ts +// Open a theme at a folder +const { themeInfo, files } = await window.helium.shopify.openTheme(themeFolder); + +// Start preview +await window.helium.shopify.startThemePreview({ host: "127.0.0.1", port: "9292" }); + +// Listen to preview state changes +window.helium.shopify.onPreviewStateChange((state) => { + console.log("Preview:", state); +}); +``` diff --git a/docs/api/utils.md b/docs/api/utils.md new file mode 100644 index 0000000..1ed751f --- /dev/null +++ b/docs/api/utils.md @@ -0,0 +1,15 @@ +# Utils + +Global: `window.helium.utils` + +## Properties +- **isMac: boolean** +- **isWindows: boolean** +- **isLinux: boolean** + +## Example +```ts +if (window.helium.utils.isMac) { + // mac-specific behavior +} +``` diff --git a/docs/components/Button.md b/docs/components/Button.md new file mode 100644 index 0000000..86b4838 --- /dev/null +++ b/docs/components/Button.md @@ -0,0 +1,21 @@ +# Button + +Source: `src/renderer/components/ui/Button/index.tsx` + +Headless UI-based button with variants and loading state. + +## Props +- **variant?**: `"primary" | "secondary" | "destructive"` (default: `"primary"`) +- **fullWidth?**: `boolean` — stretches to container width +- **loading?**: `boolean` — shows a spinner instead of children +- All native `button` attributes + +## Example +```tsx +import Button from "renderer/components/ui/Button"; + + + + + +``` diff --git a/docs/components/Checkbox.md b/docs/components/Checkbox.md new file mode 100644 index 0000000..957ef41 --- /dev/null +++ b/docs/components/Checkbox.md @@ -0,0 +1,16 @@ +# Checkbox + +Source: `src/renderer/components/ui/Checkbox/index.tsx` + +Headless UI checkbox with optional label. + +## Props +- Inherits `ComponentPropsWithoutRef` +- **label?**: `string` + +## Example +```tsx +import Checkbox from "renderer/components/ui/Checkbox"; + + +``` \ No newline at end of file diff --git a/docs/components/IconButton.md b/docs/components/IconButton.md new file mode 100644 index 0000000..7505dd0 --- /dev/null +++ b/docs/components/IconButton.md @@ -0,0 +1,17 @@ +# IconButton + +Source: `src/renderer/components/ui/IconButton/IconButton.tsx` + +Button that renders a `react-bootstrap-icons` icon. + +## Props +- Inherits `React.ButtonHTMLAttributes` +- **icon**: `Icon` (from `react-bootstrap-icons`) + +## Example +```tsx +import { XLg } from "react-bootstrap-icons"; +import IconButton from "renderer/components/ui/IconButton/IconButton"; + + +``` \ No newline at end of file diff --git a/docs/components/Input.md b/docs/components/Input.md new file mode 100644 index 0000000..4f26e16 --- /dev/null +++ b/docs/components/Input.md @@ -0,0 +1,16 @@ +# Input + +Source: `src/renderer/components/ui/Input/index.tsx` + +Text input with optional label. + +## Props +- Inherits `React.InputHTMLAttributes` +- **label?**: `string` + +## Example +```tsx +import Input from "renderer/components/ui/Input"; + + +``` \ No newline at end of file diff --git a/docs/components/Modals.md b/docs/components/Modals.md new file mode 100644 index 0000000..181ca44 --- /dev/null +++ b/docs/components/Modals.md @@ -0,0 +1,31 @@ +# Modals + +- `MessageModal` — confirm/info modal +- `InputModal` — form modal for simple inputs +- `ModalContainer` — layout wrapper + +## MessageModal +Source: `src/renderer/components/ui/Modals/MessageModal/index.tsx` + +Props: `{ options: MessageModalOptions }` + +Usage is managed by `Workspace.notifications.showMessageModal(options)`. + +## InputModal +Source: `src/renderer/components/ui/Modals/InputModal/index.tsx` + +Generic typed input modal. + +Props: `{ options: InputModalOptions }` + +Shown via `Workspace.notifications.showInputModal(options)` or `showPathInputModal(options)`. + +## Example +```tsx +workspace.notifications.showMessageModal({ + type: "warning", + message: "Delete file?", + primaryButtonText: "Delete", + secondaryButtonText: "Cancel", +}); +``` \ No newline at end of file diff --git a/docs/components/README.md b/docs/components/README.md new file mode 100644 index 0000000..5da4c41 --- /dev/null +++ b/docs/components/README.md @@ -0,0 +1,12 @@ +# Components + +Reusable UI and app components. + +- [Button](./Button.md) +- [Input](./Input.md) +- [Text](./Text.md) +- [IconButton](./IconButton.md) +- [Spinner](./Spinner.md) +- [Checkbox](./Checkbox.md) +- [Toast](./Toast.md) +- [Modals](./Modals.md) diff --git a/docs/components/Spinner.md b/docs/components/Spinner.md new file mode 100644 index 0000000..31c42d3 --- /dev/null +++ b/docs/components/Spinner.md @@ -0,0 +1,15 @@ +# Spinner + +Source: `src/renderer/components/ui/Spinner/index.tsx` + +Minimal spinner with configurable size. + +## Props +- **size**: `string | number` — width and height. + +## Example +```tsx +import Spinner from "renderer/components/ui/Spinner"; + + +``` \ No newline at end of file diff --git a/docs/components/Text.md b/docs/components/Text.md new file mode 100644 index 0000000..bc93734 --- /dev/null +++ b/docs/components/Text.md @@ -0,0 +1,18 @@ +# Text + +Source: `src/renderer/components/ui/Text/index.tsx` + +Utility component to set text size via class names. + +## Props +- **size?**: `"xs" | "sm" | "base" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "5xl"` +- **className?**: `string` +- Children are rendered inside a `div`. + +## Example +```tsx +import Text from "renderer/components/ui/Text"; + +Small text +Title +``` \ No newline at end of file diff --git a/docs/components/Toast.md b/docs/components/Toast.md new file mode 100644 index 0000000..c131b71 --- /dev/null +++ b/docs/components/Toast.md @@ -0,0 +1,18 @@ +# Toast + +Source: `src/renderer/components/ui/Toast/Toast.tsx` + +Notification UI. Controlled via `Workspace.notifications`. + +## Props +- **options**: `NotificationOptions` +- **close**: `() => void` + +## Example +```tsx +import Toast from "renderer/components/ui/Toast/Toast"; +import type { NotificationOptions } from "renderer/models/notification/types"; + +const opts: NotificationOptions = { type: "success", message: "Saved" }; + { /* ... */ }} /> +``` \ No newline at end of file diff --git a/docs/hooks/README.md b/docs/hooks/README.md new file mode 100644 index 0000000..2e1c4e1 --- /dev/null +++ b/docs/hooks/README.md @@ -0,0 +1,4 @@ +# Hooks + +- [useWorkspace](./useWorkspace.md) +- [useFileIcon](./useFileIcon.md) diff --git a/docs/hooks/useFileIcon.md b/docs/hooks/useFileIcon.md new file mode 100644 index 0000000..b915931 --- /dev/null +++ b/docs/hooks/useFileIcon.md @@ -0,0 +1,21 @@ +# useFileIcon + +Source: `src/renderer/hooks/useFileIcon.tsx` + +Maps a `FileType` to a small icon React element. + +## Signature +```ts +function useFileIcon(fileType: FileType | null): React.ReactElement | null +``` + +## Example +```tsx +import { FileTypeEnum } from "common/types"; +import { useFileIcon } from "renderer/hooks/useFileIcon"; + +function FileRow({ fileType }) { + const IconEl = useFileIcon(fileType); + return
{IconEl} README.md
; +} +``` diff --git a/docs/hooks/useWorkspace.md b/docs/hooks/useWorkspace.md new file mode 100644 index 0000000..a236c2a --- /dev/null +++ b/docs/hooks/useWorkspace.md @@ -0,0 +1,25 @@ +# useWorkspace + +Source: `src/renderer/hooks/useWorkspace.ts` + +Returns the current `Workspace` instance from React context. + +## Signature +```ts +const workspace = useWorkspace(): Workspace +``` + +Throws if used outside `WorkspaceContext.Provider`. + +## Example +```tsx +import { WorkspaceContext } from "renderer/contexts/Workspace"; +import { useWorkspace } from "renderer/hooks/useWorkspace"; + +function SaveButton() { + const workspace = useWorkspace(); + return ( + + ); +} +``` diff --git a/docs/ipc/README.md b/docs/ipc/README.md new file mode 100644 index 0000000..3e483f4 --- /dev/null +++ b/docs/ipc/README.md @@ -0,0 +1,17 @@ +# IPC Layer + +Helium wraps Electron IPC with typed helpers. + +- **Renderer helper**: `src/main/services/ipc/renderer.ts` + - `invoke(eventName)` -> `(arg: A) => Promise` + - `emit(eventName)` -> `(arg: A) => void` + - `listen(eventName)` -> `(cb: (arg: A) => void) => void` + - `on()` -> `(eventName: E, cb: (arg: T) => void) => void` + +- **Main helper**: `src/main/services/ipc/main.ts` + - `handle(eventName, (win, args) => R)` + - `listen(eventName, (win, args) => R)` + - `emitEventFromWindow(win, eventName, args?)` + - `triggerEvent(webContents, eventName, args)` + +Events are consumed by preload APIs (`src/main/preload/*.ts`) and exposed as `window.helium`. diff --git a/docs/types/README.md b/docs/types/README.md new file mode 100644 index 0000000..ec3530f --- /dev/null +++ b/docs/types/README.md @@ -0,0 +1,4 @@ +# Types + +- [Common Types](./common.md) +- [Main Types](./main.md) diff --git a/docs/types/common.md b/docs/types/common.md new file mode 100644 index 0000000..2ded674 --- /dev/null +++ b/docs/types/common.md @@ -0,0 +1,21 @@ +# Common Types + +Source: `src/common/types.ts` + +- **HeliumId**: Template string type `helium-${string}` +- **PreviewState**: `OFF | RUNNING | STARTING | STOPPING | ERROR | UNAVALIBLE` +- **ThemeInfo**: `{ shopifyId: number | null; path: string; name: string | null; version: string | null; author: string | null }` +- **StoreInfo**: `{ heliumId: HeliumId; themeAccessPassword: string; url: string; name: string }` +- **ConnectStoreOptions**: `{ storeName: string; storeUrl: string; password: string }` +- **HeliumGlobal**: shape of `window.helium` +- **InitalState**: `{ connectedStore: StoreInfo | null; currentTheme: ThemeInfo | null; themeFiles: ThemeFileSystemEntry[]; previewState: PreviewState }` +- **Language**: Union of supported text languages +- **BinaryFileType**: `IMAGE | BINARY` +- **FileType**: `Language | BinaryFileType` +- **ThemeFile**: `{ path; basename; type: "file"; fileType: FileType }` +- **ThemeDirectory**: `{ path; basename; type: "directory" }` +- **ThemeFileSystemEntry**: `ThemeFile | ThemeDirectory` +- **OpenThemeResult**: `{ themeInfo: ThemeInfo; files: ThemeFileSystemEntry[] }` +- **ThemeDirectoryChange**: `{ changedDirectory: string }` +- **ThemeDirectoryChangeType**: enum +- **StartThemePreviewOptions**: `{ host: string; port: string }` diff --git a/docs/types/main.md b/docs/types/main.md new file mode 100644 index 0000000..47201d8 --- /dev/null +++ b/docs/types/main.md @@ -0,0 +1,7 @@ +# Main Types + +Source: `src/main/types.ts` + +- **HeliumWindowOptions**: `{ themePathOrUrl?: string; connectedStore?: ConnectStoreOptions; previewOn?: boolean }` +- **HeliumLaunchOptions**: `{ themePath?: string }` +- **HeliumWindowState**: `{ isMinimized: boolean; isMaximized: boolean; isFocused: boolean }`