diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index 779e4f3..2418c26 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -1,22 +1,22 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/typescript-node
{
- "name": "Node.js & TypeScript",
- // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
- "image": "mcr.microsoft.com/devcontainers/typescript-node:1-22-bookworm",
+ "name": "Node.js & TypeScript",
+ // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
+ "image": "mcr.microsoft.com/devcontainers/typescript-node:1-22-bookworm",
- // Features to add to the dev container. More info: https://containers.dev/features.
- "features": {"ghcr.io/devcontainers-extra/features/ripgrep:1": {}},
+ // Features to add to the dev container. More info: https://containers.dev/features.
+ "features": { "ghcr.io/devcontainers-extra/features/ripgrep:1": {} },
- // Use 'forwardPorts' to make a list of ports inside the container available locally.
- // "forwardPorts": [5173],
+ // Use 'forwardPorts' to make a list of ports inside the container available locally.
+ // "forwardPorts": [5173],
- // Use 'postCreateCommand' to run commands after the container is created.
- "postCreateCommand": "npm install"
+ // Use 'postCreateCommand' to run commands after the container is created.
+ "postCreateCommand": "npm install"
- // Configure tool-specific properties.
- // "customizations": {},
+ // Configure tool-specific properties.
+ // "customizations": {},
- // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
- // "remoteUser": "root"
+ // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
+ // "remoteUser": "root"
}
diff --git a/.github/workflows/deployment.yml b/.github/workflows/deployment.yml
index f45592a..f9205c0 100644
--- a/.github/workflows/deployment.yml
+++ b/.github/workflows/deployment.yml
@@ -2,11 +2,11 @@ name: Deploy to GitHub Pages
on:
push:
- branches: [ main ]
+ branches: [main]
workflow_dispatch:
concurrency:
- group: 'pages'
+ group: "pages"
cancel-in-progress: true
permissions:
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index bb58fa5..8590164 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -3,7 +3,7 @@ name: Test
on:
pull_request:
push:
- branches: [ main ]
+ branches: [main]
jobs:
test:
diff --git a/eslint.config.js b/eslint.config.js
index e0d34c6..79245ef 100644
--- a/eslint.config.js
+++ b/eslint.config.js
@@ -1,29 +1,29 @@
-import js from '@eslint/js'
-import globals from 'globals'
-import reactHooks from 'eslint-plugin-react-hooks'
-import reactRefresh from 'eslint-plugin-react-refresh'
-import { defineConfig, globalIgnores } from 'eslint/config'
+import js from "@eslint/js";
+import globals from "globals";
+import reactHooks from "eslint-plugin-react-hooks";
+import reactRefresh from "eslint-plugin-react-refresh";
+import { defineConfig, globalIgnores } from "eslint/config";
export default defineConfig([
- globalIgnores(['dist', 'tmp']),
+ globalIgnores(["dist", "tmp"]),
{
- files: ['**/*.{js,jsx}'],
+ files: ["**/*.{js,jsx}"],
extends: [
js.configs.recommended,
- reactHooks.configs['recommended-latest'],
+ reactHooks.configs["recommended-latest"],
reactRefresh.configs.vite,
],
languageOptions: {
ecmaVersion: "latest",
globals: globals.browser,
parserOptions: {
- ecmaVersion: 'latest',
+ ecmaVersion: "latest",
ecmaFeatures: { jsx: true },
- sourceType: 'module',
+ sourceType: "module",
},
},
rules: {
- 'no-unused-vars': ['error', { varsIgnorePattern: '^[A-Z_]' }],
+ "no-unused-vars": ["error", { varsIgnorePattern: "^[A-Z_]" }],
},
},
-])
+]);
diff --git a/index.html b/index.html
index d8cfa5b..1cd1a16 100644
--- a/index.html
+++ b/index.html
@@ -1,50 +1,56 @@
-
+
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
- Calligraphy Practice Sheets
-
-
-
-
-
-
+ Calligraphy Practice Sheets
+
+
+
+
+
+
diff --git a/package.json b/package.json
index 3a2c3fc..18c04eb 100644
--- a/package.json
+++ b/package.json
@@ -2,6 +2,7 @@
"name": "penpage",
"version": "2.0.3",
"private": true,
+ "type": "module",
"homepage": "https://kylev.github.io/pen/",
"dependencies": {
"@emotion/react": "^11.14.0",
diff --git a/prettier.config.js b/prettier.config.js
new file mode 100644
index 0000000..fe71d19
--- /dev/null
+++ b/prettier.config.js
@@ -0,0 +1,3 @@
+export default {
+ printWidth: 100,
+};
diff --git a/src/App.jsx b/src/App.jsx
index ebe00e4..b508fa0 100644
--- a/src/App.jsx
+++ b/src/App.jsx
@@ -1,7 +1,7 @@
import React from "react";
import { I18nextProvider } from "react-i18next";
-import { ThemeProvider, createTheme } from '@mui/material/styles';
+import { ThemeProvider, createTheme } from "@mui/material/styles";
import "./App.css";
@@ -17,7 +17,7 @@ gaWatchStore(store);
i18n.on("languageChanged", (lng) => {
gaLangChange(lng);
- window.document.documentElement.setAttribute('lang', lng);
+ window.document.documentElement.setAttribute("lang", lng);
});
const theme = createTheme({
diff --git a/src/App.test.jsx b/src/App.test.jsx
index f155cd5..be57132 100644
--- a/src/App.test.jsx
+++ b/src/App.test.jsx
@@ -1,5 +1,5 @@
-import { render, screen } from '@testing-library/react';
-import { expect, it } from 'vitest';
+import { render, screen } from "@testing-library/react";
+import { expect, it } from "vitest";
import App from "./App";
diff --git a/src/BasicSettings.jsx b/src/BasicSettings.jsx
index d9441e0..9dde6f4 100644
--- a/src/BasicSettings.jsx
+++ b/src/BasicSettings.jsx
@@ -17,7 +17,7 @@ function BasicSettings({ hidden, role, store }) {
id="presets-field"
label={"presets"}
value={store.ratio}
- onChange={v => store.setRatioPreset(v)}
+ onChange={(v) => store.setRatioPreset(v)}
choices={store.ratioChoices}
/>
@@ -31,11 +31,11 @@ function BasicSettings({ hidden, role, store }) {
type="number"
value={store.guideline.angle}
disabled={store.ratio !== "custom"}
- onChange={e => store.setGuidelineAngle(e.target.value)}
+ onChange={(e) => store.setGuidelineAngle(e.target.value)}
slotProps={{
input: {
- endAdornment: °
- }
+ endAdornment: °,
+ },
}}
/>
@@ -47,7 +47,7 @@ function BasicSettings({ hidden, role, store }) {
min={2}
step={0.1}
value={store.xHeight}
- onChange={v => (store.xHeight = v)}
+ onChange={(v) => (store.xHeight = v)}
/>
@@ -55,7 +55,7 @@ function BasicSettings({ hidden, role, store }) {
id="size-field"
label={"pagesize"}
value={store.pageSize}
- onChange={v => (store.pageSize = v)}
+ onChange={(v) => (store.pageSize = v)}
choices={store.pageSizes}
/>
@@ -64,13 +64,13 @@ function BasicSettings({ hidden, role, store }) {
id="orientation-field"
label={"pageorientation"}
value={store.orientation}
- onChange={v => (store.orientation = v)}
+ onChange={(v) => (store.orientation = v)}
choices={store.orientations}
/>
);
-};
+}
export default BasicSettings;
diff --git a/src/ColorDropDownField.jsx b/src/ColorDropDownField.jsx
index 6a760eb..b05ab57 100644
--- a/src/ColorDropDownField.jsx
+++ b/src/ColorDropDownField.jsx
@@ -7,11 +7,11 @@ const colors = [
{ key: "transparent" },
{ key: "black" },
{ key: "gray" },
- ...range(1, 10).map(v => ({
+ ...range(1, 10).map((v) => ({
key: Color.rgb(255, 255, 255)
.darken(v / 10.0)
.string(),
- name: ["colorNames.graypct", { pct: v * 10 }]
+ name: ["colorNames.graypct", { pct: v * 10 }],
})),
{ key: "blue" },
{ key: Color.rgb(164, 221, 237).string(), name: "colorNames.nonphotoblue" },
@@ -22,10 +22,10 @@ const colors = [
{ key: "pink" },
{ key: "red" },
{ key: "white" },
- { key: "yellow" }
-].map(c => (c.name ? c : { ...c, name: `colorNames.${c.key}` }));
+ { key: "yellow" },
+].map((c) => (c.name ? c : { ...c, name: `colorNames.${c.key}` }));
-const ColorDropDownField = props => {
+const ColorDropDownField = (props) => {
return ;
};
diff --git a/src/CustomSettings.jsx b/src/CustomSettings.jsx
index 2ea8282..dc5076d 100644
--- a/src/CustomSettings.jsx
+++ b/src/CustomSettings.jsx
@@ -12,7 +12,7 @@ const CustomSettings = ({ hidden, role, store }) => {
id="guide-spacing-field"
label="guidespacing"
value={store.guideline.spacing}
- onChange={v => (store.guideline.spacing = v)}
+ onChange={(v) => (store.guideline.spacing = v)}
/>
@@ -20,7 +20,7 @@ const CustomSettings = ({ hidden, role, store }) => {
(store.gapColor = v)}
+ onChange={(v) => (store.gapColor = v)}
value={store.gapColor}
/>
@@ -28,7 +28,7 @@ const CustomSettings = ({ hidden, role, store }) => {
(store.xColor = v)}
+ onChange={(v) => (store.xColor = v)}
value={store.xColor}
/>
@@ -36,7 +36,7 @@ const CustomSettings = ({ hidden, role, store }) => {
(store.watermarkColor = v)}
+ onChange={(v) => (store.watermarkColor = v)}
value={store.watermarkColor}
/>
@@ -44,7 +44,7 @@ const CustomSettings = ({ hidden, role, store }) => {
(store.printGap = v)}
+ onChange={(v) => (store.printGap = v)}
value={store.printGap}
/>
diff --git a/src/DashDropDownField.jsx b/src/DashDropDownField.jsx
index 5df37e8..5a74a0b 100644
--- a/src/DashDropDownField.jsx
+++ b/src/DashDropDownField.jsx
@@ -4,10 +4,10 @@ const dashes = [
{ key: "none", value: "none" },
{ key: "1cm", value: "1, 1" },
{ key: "2cm", value: "2, 2" },
- { key: "42vary", value: "4, 2" }
-].map(c => (c.name ? c : { ...c, name: `dashNames.${c.key}` }));
+ { key: "42vary", value: "4, 2" },
+].map((c) => (c.name ? c : { ...c, name: `dashNames.${c.key}` }));
-const DashDropDownField = props => {
+const DashDropDownField = (props) => {
return ;
};
diff --git a/src/DropDownField.jsx b/src/DropDownField.jsx
index e0e6115..5dbe18c 100644
--- a/src/DropDownField.jsx
+++ b/src/DropDownField.jsx
@@ -10,22 +10,22 @@ const tName = (t, p) => {
else return t(p.name[0], p.name[1]);
};
-const DropDownField = ({
- label,
- onChange,
- choices,
- id,
- ...rest
-}) => {
+const DropDownField = ({ label, onChange, choices, id, ...rest }) => {
const { t } = useTranslation();
return (
-
+
{t(label)}
-