Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -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)
9 changes: 9 additions & 0 deletions docs/api/README.md
Original file line number Diff line number Diff line change
@@ -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)
35 changes: 35 additions & 0 deletions docs/api/app.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# App API

Global: `window.helium.app`

## Methods

- **closeWindow() => Promise<void>**: Close the current window.
- **setWindowTitle(title: string) => Promise<void>**: Set the Electron window title.
- **minimizeWindow() => Promise<void>**: Minimize window.
- **maximizeWindow() => Promise<void>**: Maximize window.
- **getWindowState() => Promise<HeliumWindowState>**: Returns `{ isMinimized, isMaximized, isFocused }`.
- **openFolderDialog() => Promise<string[]>**: Show OS directory picker and return selected paths.
- **loadInitalState() => Promise<InitalState>**: Load persisted state when app starts.
- **openUrl(url: string) => Promise<void>**: Open `url` in external browser.
- **on<E extends string>()(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();
```
14 changes: 14 additions & 0 deletions docs/api/constants.md
Original file line number Diff line number Diff line change
@@ -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;
```
33 changes: 33 additions & 0 deletions docs/api/fs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# File System API

Global: `window.helium.fs`

## Methods
- **readFile({ filePath, encoding }) => Promise<string>**
- **writeFile({ filePath, content, encoding }) => Promise<void>**
- **deleteFile(path: string) => Promise<void>**
- **trashItem(path: string) => Promise<void>**
- **deleteDirectory(path: string) => Promise<void>**
- **createDirectory(path: string) => Promise<void>**
- **createFile(path: string) => Promise<void>**
- **readDirectory(path: string) => Promise<ThemeFileSystemEntry[]>**
- **pathExists(path: string) => Promise<boolean>**
- **rename({ oldPath, newPath }) => Promise<void>**
- **watchDirectory(path: string) => Promise<void>**
- **stopWatchingDirectory(path: string) => Promise<void>**
- **removeAllDirectoryWatchers() => Promise<void>**
- **onDirectoryChange(cb: (change: ThemeDirectoryChange) => void) => void**
- **onFileChange(cb: (change: ThemeDirectoryChange) => void) => void**
- **detectFileType(path: string) => Promise<FileType>**

## 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);
```
32 changes: 32 additions & 0 deletions docs/api/shopify.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Shopify API

Global: `window.helium.shopify`

## Methods
- **openTheme(path: string) => Promise<OpenThemeResult>**
- **startThemePreview(options?: { host: string; port: string }) => Promise<string | null | undefined>**
- **stopThemePreview() => Promise<void>**
- **pullTheme(themeId: string) => Promise<void>**
- **pushTheme() => Promise<void>**
- **connectStore(options: { storeName: string; storeUrl: string; password: string }) => Promise<void>**
- **disconnectStore() => Promise<void>**
- **getConnectedStore() => Promise<StoreInfo>**

## 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);
});
```
15 changes: 15 additions & 0 deletions docs/api/utils.md
Original file line number Diff line number Diff line change
@@ -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
}
```
21 changes: 21 additions & 0 deletions docs/components/Button.md
Original file line number Diff line number Diff line change
@@ -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";

<Button onClick={save}>Save</Button>
<Button variant="secondary">Cancel</Button>
<Button variant="destructive" loading>Delete</Button>
<Button fullWidth>Full width</Button>
```
16 changes: 16 additions & 0 deletions docs/components/Checkbox.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Checkbox

Source: `src/renderer/components/ui/Checkbox/index.tsx`

Headless UI checkbox with optional label.

## Props
- Inherits `ComponentPropsWithoutRef<typeof HeadlessCheckbox>`
- **label?**: `string`

## Example
```tsx
import Checkbox from "renderer/components/ui/Checkbox";

<Checkbox checked={value} onChange={setValue} label="Remember me" />
```
17 changes: 17 additions & 0 deletions docs/components/IconButton.md
Original file line number Diff line number Diff line change
@@ -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<HTMLButtonElement>`
- **icon**: `Icon` (from `react-bootstrap-icons`)

## Example
```tsx
import { XLg } from "react-bootstrap-icons";
import IconButton from "renderer/components/ui/IconButton/IconButton";

<IconButton icon={XLg} aria-label="Close" onClick={onClose} />
```
16 changes: 16 additions & 0 deletions docs/components/Input.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Input

Source: `src/renderer/components/ui/Input/index.tsx`

Text input with optional label.

## Props
- Inherits `React.InputHTMLAttributes<HTMLInputElement>`
- **label?**: `string`

## Example
```tsx
import Input from "renderer/components/ui/Input";

<Input id="themeName" label="Theme Name" placeholder="Dawn" />
```
31 changes: 31 additions & 0 deletions docs/components/Modals.md
Original file line number Diff line number Diff line change
@@ -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<T> }`

Shown via `Workspace.notifications.showInputModal(options)` or `showPathInputModal(options)`.

## Example
```tsx
workspace.notifications.showMessageModal({
type: "warning",
message: "Delete file?",
primaryButtonText: "Delete",
secondaryButtonText: "Cancel",
});
```
12 changes: 12 additions & 0 deletions docs/components/README.md
Original file line number Diff line number Diff line change
@@ -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)
15 changes: 15 additions & 0 deletions docs/components/Spinner.md
Original file line number Diff line number Diff line change
@@ -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";

<Spinner size={16} />
```
18 changes: 18 additions & 0 deletions docs/components/Text.md
Original file line number Diff line number Diff line change
@@ -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";

<Text size="sm">Small text</Text>
<Text size="xl" className="muted">Title</Text>
```
18 changes: 18 additions & 0 deletions docs/components/Toast.md
Original file line number Diff line number Diff line change
@@ -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" };
<Toast options={opts} close={() => { /* ... */ }} />
```
4 changes: 4 additions & 0 deletions docs/hooks/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Hooks

- [useWorkspace](./useWorkspace.md)
- [useFileIcon](./useFileIcon.md)
21 changes: 21 additions & 0 deletions docs/hooks/useFileIcon.md
Original file line number Diff line number Diff line change
@@ -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 <div className="file-row">{IconEl} README.md</div>;
}
```
25 changes: 25 additions & 0 deletions docs/hooks/useWorkspace.md
Original file line number Diff line number Diff line change
@@ -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 (
<button onClick={() => workspace.saveCurrentFile()}>Save</button>
);
}
```
Loading