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)} - onChange(e.target.value)} + id={id} + label={t(label)} + labelId={`label-${id}`} + {...rest} + > + {choices.map((p) => ( {tName(t, p)} diff --git a/src/Footer.jsx b/src/Footer.jsx index 517851b..dd9ab63 100644 --- a/src/Footer.jsx +++ b/src/Footer.jsx @@ -1,4 +1,4 @@ -import {Grid, Typography} from "@mui/material"; +import { Grid, Typography } from "@mui/material"; import { GitHub, Twitter } from "@mui/icons-material"; import LanguageSelect from "./LanguageSelect"; @@ -8,18 +8,19 @@ const Footer = () => { - Created with React - {" and "} - Mobx while thinking about my mom, a - teacher.
- Bugs? Suggestions? -
- - -   - - - + Created with React + {" and "} + Mobx while thinking about my mom, a teacher. +
+ Bugs? Suggestions? +
+ + + +   + + +
diff --git a/src/Header.jsx b/src/Header.jsx index 2cc4d50..22864f4 100644 --- a/src/Header.jsx +++ b/src/Header.jsx @@ -14,16 +14,15 @@ import HeaderButtons from "./HeaderButtons"; import LineSetDebug from "./LineSetDebug"; import LineSettings from "./LineSettings"; - function tabProps(index) { return { id: `tab-${index}`, value: index, "aria-controls": `tabpanel-${index}`, sx: { - '&.Mui-selected': { - color: '#ffffff', - } + "&.Mui-selected": { + color: "#ffffff", + }, }, }; } @@ -49,10 +48,7 @@ function Header({ store }) { - setActive(v)} - value={active} - > + setActive(v)} value={active}> @@ -63,10 +59,14 @@ function Header({ store }) { - (line.color = v)} - /> + (line.color = v)} /> (line.dash = v)} + onChange={(v) => (line.dash = v)} disabled={line.color === "transparent"} /> @@ -34,7 +30,7 @@ const LineSetting = ({ label, line }) => { value={line.thickness} min={0.1} step={0.1} - onChange={v => (line.thickness = v)} + onChange={(v) => (line.thickness = v)} disabled={line.color === "transparent"} />
@@ -46,7 +42,7 @@ const LineSettings = ({ hidden, role, store }) => { const lineNames = ["ascender", "midline", "baseline", "descender"]; return (