diff --git a/.claude/settings.local.json b/.claude/settings.local.json deleted file mode 100644 index 8a57bc3b4a..0000000000 --- a/.claude/settings.local.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "permissions": { - "allow": [ - "Bash(gh issue *)" - ] - } -} diff --git a/.github/actions/build-electron/action.yml b/.github/actions/build-electron/action.yml index d4dfc5b570..1e84179595 100644 --- a/.github/actions/build-electron/action.yml +++ b/.github/actions/build-electron/action.yml @@ -21,7 +21,7 @@ runs: # Certificate setup - name: Import Apple certificates if: inputs.os == 'macos' - uses: apple-actions/import-codesign-certs@v6 + uses: apple-actions/import-codesign-certs@v7 with: p12-file-base64: ${{ env.APPLE_APP_CERTIFICATE_BASE64 }} p12-password: ${{ env.APPLE_APP_CERTIFICATE_PASSWORD }} @@ -30,7 +30,7 @@ runs: - name: Install Installer certificate if: inputs.os == 'macos' - uses: apple-actions/import-codesign-certs@v6 + uses: apple-actions/import-codesign-certs@v7 with: p12-file-base64: ${{ env.APPLE_INSTALLER_CERTIFICATE_BASE64 }} p12-password: ${{ env.APPLE_INSTALLER_CERTIFICATE_PASSWORD }} diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 06c5df5481..c0b20c72c4 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -118,14 +118,23 @@ class MyNoteWidget extends NoteContextAwareWidget { **Important**: Widgets use jQuery (`this.$widget`) for DOM manipulation. Don't mix React patterns here. ### Reusable Preact Components -Common UI components are available in `apps/client/src/widgets/react/` — prefer reusing these over creating custom implementations: +Common UI components are available in `apps/client/src/widgets/react/` — **always** reuse these instead of writing raw HTML elements or custom implementations: - `NoItems` - Empty state placeholder with icon and message (use for "no results", "too many items", error states) - `ActionButton` - Consistent button styling with icon support -- `FormTextBox` - Text input with validation and controlled input handling +- `FormTextBox` - Text input with validation and controlled input handling; `FormTextBoxWithUnit` for inputs with a unit suffix (e.g. "mm", "px") +- `FormSelect` - Dropdown/combobox taking an object array as data - `Slider` - Range slider with label - `Checkbox`, `RadioButton` - Form controls - `CollapsibleSection` - Expandable content sections +**Do not use Bootstrap utility classes** (e.g. `form-control-sm`, `form-select-sm`, `input-group`) on these components — they manage their own styling internally. If you need to adjust sizing or layout, use props provided by the component or CSS custom properties, not Bootstrap overrides. + +#### Component Styling +- **Avoid inline styles** — do not use the `style` attribute/prop on JSX elements unless absolutely necessary (e.g. a truly dynamic, computed value that cannot be expressed in CSS). Static layout, sizing, spacing, and visual properties must go in CSS. +- **Per-component CSS files**: each component should have a matching `.css` file (e.g. `my_dialog.tsx` → `my_dialog.css`), imported at the top of the component file. +- **CSS nesting for scoping**: since CSS modules are not available, scope styles using a root class and native CSS nesting. For example, a dialog with `className="my-dialog"` should have its styles nested under `.modal.my-dialog { … }`. +- **Reuse existing components** instead of building custom markup — prefer `FormTextBox`, `FormTextBoxWithUnit`, `FormSelect`, `Slider`, `Button`, etc. over hand-rolled ``, ``, ` setPageSize((e.target as HTMLSelectElement).value)} + ({ key: size, title: size }))} + keyProperty="key" + titleProperty="title" + currentValue={pageSize} + onChange={setPageSize} disabled={loading} - > - {PAGE_SIZES.map((size) => ( - - ))} - + /> @@ -379,17 +374,19 @@ export default function PrintPreviewDialog() { - + /> {marginPreset === "custom" && ( @@ -401,26 +398,24 @@ export default function PrintPreviewDialog() { label={t("print_preview.page_ranges")} description={!pageRangesValid ? t("print_preview.page_ranges_invalid") : t("print_preview.page_ranges_hint")} > - setPageRanges((e.target as HTMLInputElement).value)} + onChange={(value) => setPageRanges(value)} disabled={loading} - style={{ width: "140px" }} /> -
+