From d35ec750437a03f9e87cc6859e8c29a03aa13120 Mon Sep 17 00:00:00 2001 From: charlesLoder Date: Wed, 29 Jul 2026 16:43:01 -0400 Subject: [PATCH 01/13] add dropdown component --- package-lock.json | 8 +-- package.json | 2 +- .../dropdown-menu-checkbox-group.svelte | 16 ++++++ .../dropdown-menu-checkbox-item.svelte | 44 +++++++++++++++ .../dropdown-menu-content.svelte | 31 +++++++++++ .../dropdown-menu-group-heading.svelte | 22 ++++++++ .../dropdown-menu/dropdown-menu-group.svelte | 7 +++ .../dropdown-menu/dropdown-menu-item.svelte | 27 ++++++++++ .../dropdown-menu/dropdown-menu-label.svelte | 27 ++++++++++ .../dropdown-menu/dropdown-menu-portal.svelte | 7 +++ .../dropdown-menu-radio-group.svelte | 16 ++++++ .../dropdown-menu-radio-item.svelte | 34 ++++++++++++ .../dropdown-menu-separator.svelte | 17 ++++++ .../dropdown-menu-shortcut.svelte | 23 ++++++++ .../dropdown-menu-sub-content.svelte | 20 +++++++ .../dropdown-menu-sub-trigger.svelte | 29 ++++++++++ .../ui/dropdown-menu/dropdown-menu-sub.svelte | 7 +++ .../dropdown-menu-trigger.svelte | 7 +++ .../ui/dropdown-menu/dropdown-menu.svelte | 7 +++ src/lib/components/ui/dropdown-menu/index.ts | 54 +++++++++++++++++++ 20 files changed, 400 insertions(+), 5 deletions(-) create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-group.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-portal.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-sub.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu.svelte create mode 100644 src/lib/components/ui/dropdown-menu/index.ts diff --git a/package-lock.json b/package-lock.json index 22e375e..02e1de2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,7 +26,7 @@ "devDependencies": { "@eslint/js": "^10.0.1", "@internationalized/date": "^3.12.2", - "@lucide/svelte": "^1.21.0", + "@lucide/svelte": "^1.27.0", "@netlify/functions": "^5.3.0", "@playwright/test": "^1.61.0", "@types/node": "^26.0.0", @@ -2539,9 +2539,9 @@ } }, "node_modules/@lucide/svelte": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/@lucide/svelte/-/svelte-1.21.0.tgz", - "integrity": "sha512-MEv//A7Jv3kHukZowv/DWp1MAtUzJKYwtJsmnQ7X98lCgtac3z3NbaToDl3Q6jO3gS9sougFpcD+t+YuxOkRMw==", + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/@lucide/svelte/-/svelte-1.27.0.tgz", + "integrity": "sha512-qzNBHdqy/MKp2qxuy/DcYELuep6h19fjo+4ech8fZsS4GtZeBtg5jgCTRQvLvwhppt0mhRN6qt8Nt8rPb/J4Ag==", "dev": true, "license": "ISC", "peerDependencies": { diff --git a/package.json b/package.json index 8d3f30b..5efc751 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "devDependencies": { "@eslint/js": "^10.0.1", "@internationalized/date": "^3.12.2", - "@lucide/svelte": "^1.21.0", + "@lucide/svelte": "^1.27.0", "@netlify/functions": "^5.3.0", "@playwright/test": "^1.61.0", "@types/node": "^26.0.0", diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-group.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-group.svelte new file mode 100644 index 0000000..442ee4f --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-group.svelte @@ -0,0 +1,16 @@ + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte new file mode 100644 index 0000000..3039589 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte @@ -0,0 +1,44 @@ + + + + {#snippet children({ checked, indeterminate })} + + {#if indeterminate} + + {:else if checked} + + {/if} + + {@render childrenProp?.()} + {/snippet} + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte new file mode 100644 index 0000000..810eb1e --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte @@ -0,0 +1,31 @@ + + + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte new file mode 100644 index 0000000..6300ce4 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte @@ -0,0 +1,22 @@ + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte new file mode 100644 index 0000000..2172000 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte @@ -0,0 +1,7 @@ + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte new file mode 100644 index 0000000..abb24be --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte @@ -0,0 +1,27 @@ + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte new file mode 100644 index 0000000..83c3072 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte @@ -0,0 +1,27 @@ + + +
+ {@render children?.()} +
diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-portal.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-portal.svelte new file mode 100644 index 0000000..f9e1e2a --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-portal.svelte @@ -0,0 +1,7 @@ + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte new file mode 100644 index 0000000..d4bbe25 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte @@ -0,0 +1,16 @@ + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte new file mode 100644 index 0000000..79e6974 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte @@ -0,0 +1,34 @@ + + + + {#snippet children({ checked })} + + {#if checked} + + {/if} + + {@render childrenProp?.({ checked })} + {/snippet} + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte new file mode 100644 index 0000000..7f2b04c --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte @@ -0,0 +1,17 @@ + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte new file mode 100644 index 0000000..3c568e6 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte @@ -0,0 +1,23 @@ + + + + {@render children?.()} + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte new file mode 100644 index 0000000..db056c3 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte @@ -0,0 +1,20 @@ + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte new file mode 100644 index 0000000..95c152e --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte @@ -0,0 +1,29 @@ + + + + {@render children?.()} + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-sub.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub.svelte new file mode 100644 index 0000000..35d8094 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub.svelte @@ -0,0 +1,7 @@ + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte new file mode 100644 index 0000000..bb88efd --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte @@ -0,0 +1,7 @@ + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu.svelte new file mode 100644 index 0000000..dc3ecf8 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu.svelte @@ -0,0 +1,7 @@ + + + diff --git a/src/lib/components/ui/dropdown-menu/index.ts b/src/lib/components/ui/dropdown-menu/index.ts new file mode 100644 index 0000000..5c4fe0c --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/index.ts @@ -0,0 +1,54 @@ +import Root from "./dropdown-menu.svelte"; +import Sub from "./dropdown-menu-sub.svelte"; +import CheckboxGroup from "./dropdown-menu-checkbox-group.svelte"; +import CheckboxItem from "./dropdown-menu-checkbox-item.svelte"; +import Content from "./dropdown-menu-content.svelte"; +import Group from "./dropdown-menu-group.svelte"; +import Item from "./dropdown-menu-item.svelte"; +import Label from "./dropdown-menu-label.svelte"; +import RadioGroup from "./dropdown-menu-radio-group.svelte"; +import RadioItem from "./dropdown-menu-radio-item.svelte"; +import Separator from "./dropdown-menu-separator.svelte"; +import Shortcut from "./dropdown-menu-shortcut.svelte"; +import Trigger from "./dropdown-menu-trigger.svelte"; +import SubContent from "./dropdown-menu-sub-content.svelte"; +import SubTrigger from "./dropdown-menu-sub-trigger.svelte"; +import GroupHeading from "./dropdown-menu-group-heading.svelte"; +import Portal from "./dropdown-menu-portal.svelte"; + +export { + CheckboxGroup, + CheckboxItem, + Content, + Portal, + Root as DropdownMenu, + CheckboxGroup as DropdownMenuCheckboxGroup, + CheckboxItem as DropdownMenuCheckboxItem, + Content as DropdownMenuContent, + Portal as DropdownMenuPortal, + Group as DropdownMenuGroup, + Item as DropdownMenuItem, + Label as DropdownMenuLabel, + RadioGroup as DropdownMenuRadioGroup, + RadioItem as DropdownMenuRadioItem, + Separator as DropdownMenuSeparator, + Shortcut as DropdownMenuShortcut, + Sub as DropdownMenuSub, + SubContent as DropdownMenuSubContent, + SubTrigger as DropdownMenuSubTrigger, + Trigger as DropdownMenuTrigger, + GroupHeading as DropdownMenuGroupHeading, + Group, + GroupHeading, + Item, + Label, + RadioGroup, + RadioItem, + Root, + Separator, + Shortcut, + Sub, + SubContent, + SubTrigger, + Trigger, +}; From 4670a63b24ece06d876ad375c41899b1f2e15547 Mon Sep 17 00:00:00 2001 From: charlesLoder Date: Wed, 29 Jul 2026 17:01:14 -0400 Subject: [PATCH 02/13] rename primary page components --- src/components/remove/{index.svelte => Remove.svelte} | 6 +++--- .../structure/{index.svelte => Structure.svelte} | 6 +++--- .../transliterate/{index.svelte => Transliterate.svelte} | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) rename src/components/remove/{index.svelte => Remove.svelte} (97%) rename src/components/structure/{index.svelte => Structure.svelte} (96%) rename src/components/transliterate/{index.svelte => Transliterate.svelte} (97%) diff --git a/src/components/remove/index.svelte b/src/components/remove/Remove.svelte similarity index 97% rename from src/components/remove/index.svelte rename to src/components/remove/Remove.svelte index f507bee..44a87af 100644 --- a/src/components/remove/index.svelte +++ b/src/components/remove/Remove.svelte @@ -10,9 +10,9 @@ import { performRemoval } from "../../services/removalService"; import type { AppStatus, Context, RemoveState } from "../../types/index"; import { default_remove_options } from "../../utils/defaults"; - import Card from "../shared/Card.svelte"; - import Input from "../shared/Input.svelte"; - import Output from "../shared/Output.svelte"; + import Card from "../Card/Card.svelte"; + import Input from "../Input/Input.svelte"; + import Output from "../Output/Output.svelte"; import Settings from "./Settings.svelte"; const saved_options = deserialize_object( diff --git a/src/components/structure/index.svelte b/src/components/structure/Structure.svelte similarity index 96% rename from src/components/structure/index.svelte rename to src/components/structure/Structure.svelte index 707c2fc..07aa66e 100644 --- a/src/components/structure/index.svelte +++ b/src/components/structure/Structure.svelte @@ -8,9 +8,9 @@ import { performStructure } from "../../services/structureService"; import type { AppStatus, Context, StructureState } from "../../types/index"; import { default_structure_options } from "../../utils/defaults"; - import Card from "../shared/Card.svelte"; - import Input from "../shared/Input.svelte"; - import Output from "../shared/Output.svelte"; + import Card from "../Card/Card.svelte"; + import Input from "../Input/Input.svelte"; + import Output from "../Output/Output.svelte"; import Settings from "./Settings.svelte"; const saved_options = load_settings(STORAGE_KEYS.structure, default_structure_options); diff --git a/src/components/transliterate/index.svelte b/src/components/transliterate/Transliterate.svelte similarity index 97% rename from src/components/transliterate/index.svelte rename to src/components/transliterate/Transliterate.svelte index 2337b9f..8621d43 100644 --- a/src/components/transliterate/index.svelte +++ b/src/components/transliterate/Transliterate.svelte @@ -9,10 +9,10 @@ import { performTransliteration as perform_transliteration } from "../../services/transliterationService"; import type { AppStatus, Context, TransliterationState } from "../../types/index"; import { get_default_SBL_schema } from "../../utils/schemaDefaults"; - import Card from "../shared/Card.svelte"; - import ErrorBoundary from "../shared/ErrorBoundary.svelte"; - import Input from "../shared/Input.svelte"; - import Output from "../shared/Output.svelte"; + import Card from "../Card/Card.svelte"; + import ErrorBoundary from "../ErrorBoundary/ErrorBoundary.svelte"; + import Input from "../Input/Input.svelte"; + import Output from "../Output/Output.svelte"; import NiqqudModal from "./NiqqudModal.svelte"; import Settings from "./SettingsDialog.svelte"; From 5df5a0e9a89459c3ae1ac013ba7a1c4e44726924 Mon Sep 17 00:00:00 2001 From: charlesLoder Date: Wed, 29 Jul 2026 17:02:38 -0400 Subject: [PATCH 03/13] rename components --- src/components/{shared => Card}/Card.svelte | 2 +- src/components/{shared => Dialog}/Dialog.svelte | 0 src/components/{shared => ErrorBoundary}/ErrorBoundary.svelte | 0 src/components/{shared => FeedbackModal}/FeedbackModal.svelte | 0 src/components/{shared => Input}/Input.svelte | 0 src/{layouts => components/Navigation}/Navigation.astro | 2 +- src/{layouts => components/NavigationLink}/NavigationLink.astro | 0 src/components/{shared => Output}/Output.svelte | 0 src/{layouts => components/SchemaOrg}/SchemaOrg.astro | 0 9 files changed, 2 insertions(+), 2 deletions(-) rename src/components/{shared => Card}/Card.svelte (95%) rename src/components/{shared => Dialog}/Dialog.svelte (100%) rename src/components/{shared => ErrorBoundary}/ErrorBoundary.svelte (100%) rename src/components/{shared => FeedbackModal}/FeedbackModal.svelte (100%) rename src/components/{shared => Input}/Input.svelte (100%) rename src/{layouts => components/Navigation}/Navigation.astro (97%) rename src/{layouts => components/NavigationLink}/NavigationLink.astro (100%) rename src/components/{shared => Output}/Output.svelte (100%) rename src/{layouts => components/SchemaOrg}/SchemaOrg.astro (100%) diff --git a/src/components/shared/Card.svelte b/src/components/Card/Card.svelte similarity index 95% rename from src/components/shared/Card.svelte rename to src/components/Card/Card.svelte index f51d824..77c98b7 100644 --- a/src/components/shared/Card.svelte +++ b/src/components/Card/Card.svelte @@ -3,7 +3,7 @@ import { Separator } from "$lib/components/ui/separator/index.js"; import { version } from "hebrew-transliteration/package.json"; import type { Snippet } from "svelte"; - import FeedbackModal from "./FeedbackModal.svelte"; + import FeedbackModal from "../FeedbackModal/FeedbackModal.svelte"; interface Props { aria_busy: boolean; diff --git a/src/components/shared/Dialog.svelte b/src/components/Dialog/Dialog.svelte similarity index 100% rename from src/components/shared/Dialog.svelte rename to src/components/Dialog/Dialog.svelte diff --git a/src/components/shared/ErrorBoundary.svelte b/src/components/ErrorBoundary/ErrorBoundary.svelte similarity index 100% rename from src/components/shared/ErrorBoundary.svelte rename to src/components/ErrorBoundary/ErrorBoundary.svelte diff --git a/src/components/shared/FeedbackModal.svelte b/src/components/FeedbackModal/FeedbackModal.svelte similarity index 100% rename from src/components/shared/FeedbackModal.svelte rename to src/components/FeedbackModal/FeedbackModal.svelte diff --git a/src/components/shared/Input.svelte b/src/components/Input/Input.svelte similarity index 100% rename from src/components/shared/Input.svelte rename to src/components/Input/Input.svelte diff --git a/src/layouts/Navigation.astro b/src/components/Navigation/Navigation.astro similarity index 97% rename from src/layouts/Navigation.astro rename to src/components/Navigation/Navigation.astro index 81820ef..8a472c7 100644 --- a/src/layouts/Navigation.astro +++ b/src/components/Navigation/Navigation.astro @@ -1,5 +1,5 @@ --- -import NavigationLink from "./NavigationLink.astro"; +import NavigationLink from "../NavigationLink/NavigationLink.astro"; const links = [ { label: "Transliterate", href: "/" }, diff --git a/src/layouts/NavigationLink.astro b/src/components/NavigationLink/NavigationLink.astro similarity index 100% rename from src/layouts/NavigationLink.astro rename to src/components/NavigationLink/NavigationLink.astro diff --git a/src/components/shared/Output.svelte b/src/components/Output/Output.svelte similarity index 100% rename from src/components/shared/Output.svelte rename to src/components/Output/Output.svelte diff --git a/src/layouts/SchemaOrg.astro b/src/components/SchemaOrg/SchemaOrg.astro similarity index 100% rename from src/layouts/SchemaOrg.astro rename to src/components/SchemaOrg/SchemaOrg.astro From fff1e63863ef0aa80ec3b433cfdb25fc1804ee70 Mon Sep 17 00:00:00 2001 From: charlesLoder Date: Wed, 29 Jul 2026 17:04:17 -0400 Subject: [PATCH 04/13] update imports --- src/components/remove/Settings.svelte | 2 +- src/components/structure/Settings.svelte | 2 +- src/components/transliterate/SettingsDialog.svelte | 2 +- src/pages/about.astro | 4 ++-- src/pages/index.astro | 4 ++-- src/pages/remove.astro | 4 ++-- src/pages/structure.astro | 4 ++-- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/components/remove/Settings.svelte b/src/components/remove/Settings.svelte index 0ca134e..4cad8f1 100644 --- a/src/components/remove/Settings.svelte +++ b/src/components/remove/Settings.svelte @@ -14,7 +14,7 @@ import CodeMirror from "svelte-codemirror-editor"; import type { Context, RemoveState } from "../../types/index"; import { format_doc_url } from "../../utils/documentation"; - import Dialog from "../shared/Dialog.svelte"; + import Dialog from "../Dialog/Dialog.svelte"; const remove_state = getContext>("remove_state"); diff --git a/src/components/structure/Settings.svelte b/src/components/structure/Settings.svelte index 8ff64ac..a4e26b9 100644 --- a/src/components/structure/Settings.svelte +++ b/src/components/structure/Settings.svelte @@ -8,7 +8,7 @@ import { getContext } from "svelte"; import type { WhitespaceOption } from "../../services/structureService"; import type { Context, StructureState } from "../../types/index"; - import Dialog from "../shared/Dialog.svelte"; + import Dialog from "../Dialog/Dialog.svelte"; const structure_state = getContext>("structure_state"); diff --git a/src/components/transliterate/SettingsDialog.svelte b/src/components/transliterate/SettingsDialog.svelte index 4d8beff..9100eb9 100644 --- a/src/components/transliterate/SettingsDialog.svelte +++ b/src/components/transliterate/SettingsDialog.svelte @@ -37,7 +37,7 @@ import type { Context, TransliterationState, VisibilityState } from "../../types/index"; import { format_doc_url, format_label } from "../../utils/documentation"; import { get_default_SBL_schema } from "../../utils/schemaDefaults"; - import Dialog from "../shared/Dialog.svelte"; + import Dialog from "../Dialog/Dialog.svelte"; import FeatureEditor from "./FeatureEditor.svelte"; import KetivQereEditor from "./KetivQereEditor.svelte"; diff --git a/src/pages/about.astro b/src/pages/about.astro index 065ea29..5ccd87f 100644 --- a/src/pages/about.astro +++ b/src/pages/about.astro @@ -5,8 +5,8 @@ import BrandLinkedIn from "node_modules/@tabler/icons-svelte/dist/icons/brand-li import BrandX from "node_modules/@tabler/icons-svelte/dist/icons/brand-x.svelte"; import CircleA from "node_modules/@tabler/icons-svelte/dist/icons/circle-letter-a.svelte"; import MainLayout from "src/layouts/MainLayout.astro"; -import Card from "../components/shared/Card.svelte"; -import SchemaOrg from "../layouts/SchemaOrg.astro"; +import Card from "../components/Card/Card.svelte"; +import SchemaOrg from "../components/SchemaOrg/SchemaOrg.astro"; import "../styles/global.css"; const title = "About"; diff --git a/src/pages/index.astro b/src/pages/index.astro index 583d582..3efe981 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -1,7 +1,7 @@ --- -import Transliterate from "../components/transliterate/index.svelte"; +import SchemaOrg from "../components/SchemaOrg/SchemaOrg.astro"; +import Transliterate from "../components/Transliterate/Transliterate.svelte"; import MainLayout from "../layouts/MainLayout.astro"; -import SchemaOrg from "../layouts/SchemaOrg.astro"; import "../styles/global.css"; const title = "Hebrew Transliteration App"; diff --git a/src/pages/remove.astro b/src/pages/remove.astro index 88ec8ce..12bae11 100644 --- a/src/pages/remove.astro +++ b/src/pages/remove.astro @@ -1,7 +1,7 @@ --- -import RemoveComponent from "../components/remove/index.svelte"; +import RemoveComponent from "../components/Remove/Remove.svelte"; import MainLayout from "../layouts/MainLayout.astro"; -import SchemaOrg from "../layouts/SchemaOrg.astro"; +import SchemaOrg from "../components/SchemaOrg/SchemaOrg.astro"; import "../styles/global.css"; const title = "Remove"; diff --git a/src/pages/structure.astro b/src/pages/structure.astro index 2783e75..a0e586a 100644 --- a/src/pages/structure.astro +++ b/src/pages/structure.astro @@ -1,7 +1,7 @@ --- -import StructureComponent from "../components/structure/index.svelte"; +import SchemaOrg from "../components/SchemaOrg/SchemaOrg.astro"; +import StructureComponent from "../components/Structure/Structure.svelte"; import MainLayout from "../layouts/MainLayout.astro"; -import SchemaOrg from "../layouts/SchemaOrg.astro"; import "../styles/global.css"; const title = "Structure"; From 88201db97da21279adb4dfb919ad7abc556901b5 Mon Sep 17 00:00:00 2001 From: charlesLoder Date: Wed, 29 Jul 2026 17:04:23 -0400 Subject: [PATCH 05/13] update agents --- AGENTS.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 1a16e0c..d20ad7c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -99,14 +99,14 @@ Configuration in `netlify.toml`. ``` src/ -├── components/ # Svelte components -├── layouts/ # Astro layouts -├── lib/ # Utilities, UI components -├── pages/ # Astro routes (*.astro) -├── services/ # Business logic -└── types/ # TypeScript types -tests/ # Playwright e2e specs -netlify/functions/ # Netlify serverless functions +├── components/ # Svelte components, each in [Name]/[Name].svelte +├── layouts/ # Astro layouts (MainLayout.astro) +├── lib/ # Utilities, UI components +├── pages/ # Astro routes (*.astro) +├── services/ # Business logic +└── types/ # TypeScript types +tests/ # Playwright e2e specs +netlify/functions/ # Netlify serverless functions ``` ## State Management @@ -123,7 +123,7 @@ Uses Svelte 5's `$state` runes with context-based sharing. ### Architecture Pattern -1. **Root component** (`transliterate/index.svelte`) creates state with `$state()` and exposes it via Svelte context using `setContext>("state_key", ...)` +1. **Root component** (e.g. `Transliterate/Transliterate.svelte`) creates state with `$state()` and exposes it via Svelte context using `setContext>("state_key", ...)` 2. **Consumer components** access state via `getContext>("state_key")` and mutate directly via `.value` property From 59a709c1899f9375ff40dc25df93dc75707f2382 Mon Sep 17 00:00:00 2001 From: charlesLoder Date: Wed, 29 Jul 2026 22:37:35 -0400 Subject: [PATCH 06/13] uninstall mode-watcher --- package-lock.json | 68 ---------------------- package.json | 1 - src/lib/components/ui/sonner/sonner.svelte | 8 +-- 3 files changed, 3 insertions(+), 74 deletions(-) diff --git a/package-lock.json b/package-lock.json index 02e1de2..efa439b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -35,7 +35,6 @@ "eslint": "^10.5.0", "eslint-plugin-svelte": "^3.19.0", "globals": "^17.7.0", - "mode-watcher": "^1.1.0", "npm-check-updates": "^22.2.7", "prettier": "^3.8.4", "prettier-plugin-astro": "^0.14.1", @@ -10907,73 +10906,6 @@ "ufo": "^1.6.3" } }, - "node_modules/mode-watcher": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mode-watcher/-/mode-watcher-1.1.0.tgz", - "integrity": "sha512-mUT9RRGPDYenk59qJauN1rhsIMKBmWA3xMF+uRwE8MW/tjhaDSCCARqkSuDTq8vr4/2KcAxIGVjACxTjdk5C3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "runed": "^0.25.0", - "svelte-toolbelt": "^0.7.1" - }, - "peerDependencies": { - "svelte": "^5.27.0" - } - }, - "node_modules/mode-watcher/node_modules/runed": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/runed/-/runed-0.25.0.tgz", - "integrity": "sha512-7+ma4AG9FT2sWQEA0Egf6mb7PBT2vHyuHail1ie8ropfSjvZGtEAx8YTmUjv/APCsdRRxEVvArNjALk9zFSOrg==", - "dev": true, - "funding": [ - "https://github.com/sponsors/huntabyte", - "https://github.com/sponsors/tglide" - ], - "dependencies": { - "esm-env": "^1.0.0" - }, - "peerDependencies": { - "svelte": "^5.7.0" - } - }, - "node_modules/mode-watcher/node_modules/svelte-toolbelt": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/svelte-toolbelt/-/svelte-toolbelt-0.7.1.tgz", - "integrity": "sha512-HcBOcR17Vx9bjaOceUvxkY3nGmbBmCBBbuWLLEWO6jtmWH8f/QoWmbyUfQZrpDINH39en1b8mptfPQT9VKQ1xQ==", - "dev": true, - "funding": [ - "https://github.com/sponsors/huntabyte" - ], - "dependencies": { - "clsx": "^2.1.1", - "runed": "^0.23.2", - "style-to-object": "^1.0.8" - }, - "engines": { - "node": ">=18", - "pnpm": ">=8.7.0" - }, - "peerDependencies": { - "svelte": "^5.0.0" - } - }, - "node_modules/mode-watcher/node_modules/svelte-toolbelt/node_modules/runed": { - "version": "0.23.4", - "resolved": "https://registry.npmjs.org/runed/-/runed-0.23.4.tgz", - "integrity": "sha512-9q8oUiBYeXIDLWNK5DfCWlkL0EW3oGbk845VdKlPeia28l751VpfesaB/+7pI6rnbx1I6rqoZ2fZxptOJLxILA==", - "dev": true, - "funding": [ - "https://github.com/sponsors/huntabyte", - "https://github.com/sponsors/tglide" - ], - "dependencies": { - "esm-env": "^1.0.0" - }, - "peerDependencies": { - "svelte": "^5.7.0" - } - }, "node_modules/module-definition": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/module-definition/-/module-definition-6.0.2.tgz", diff --git a/package.json b/package.json index 5efc751..91c19d5 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,6 @@ "eslint": "^10.5.0", "eslint-plugin-svelte": "^3.19.0", "globals": "^17.7.0", - "mode-watcher": "^1.1.0", "npm-check-updates": "^22.2.7", "prettier": "^3.8.4", "prettier-plugin-astro": "^0.14.1", diff --git a/src/lib/components/ui/sonner/sonner.svelte b/src/lib/components/ui/sonner/sonner.svelte index 0437784..aca84a1 100644 --- a/src/lib/components/ui/sonner/sonner.svelte +++ b/src/lib/components/ui/sonner/sonner.svelte @@ -1,17 +1,15 @@ Date: Fri, 31 Jul 2026 18:28:06 -0400 Subject: [PATCH 07/13] add theme selector --- netlify.toml | 11 ++ netlify/edge-functions/check-theme.ts | 29 +++++ .../ThemeSelector/ThemeSelector.svelte | 83 +++++++++++++ src/layouts/MainLayout.astro | 30 +++-- src/styles/global.css | 111 ++++++++---------- 5 files changed, 190 insertions(+), 74 deletions(-) create mode 100644 netlify/edge-functions/check-theme.ts create mode 100644 src/components/ThemeSelector/ThemeSelector.svelte diff --git a/netlify.toml b/netlify.toml index e67f173..ab8bc8c 100644 --- a/netlify.toml +++ b/netlify.toml @@ -14,3 +14,14 @@ for = "/schemas/*" [headers.values] Cache-Control = "public, max-age=31536000, immutable" + +[[headers]] + for = "/*" + [headers.values] + Accept-CH = "Sec-CH-Prefers-Color-Scheme" + Critical-CH = "Sec-CH-Prefers-Color-Scheme" + Vary = "Sec-CH-Prefers-Color-Scheme" + +[[edge_functions]] + function = "check-theme" + path = "/*" diff --git a/netlify/edge-functions/check-theme.ts b/netlify/edge-functions/check-theme.ts new file mode 100644 index 0000000..a16659c --- /dev/null +++ b/netlify/edge-functions/check-theme.ts @@ -0,0 +1,29 @@ +import type { Config, Context } from "@netlify/edge-functions"; + +export default async (request: Request, context: Context) => { + const response = await context.next(); + + const contentType = response.headers.get("content-type"); + if (!contentType || !contentType.includes("text/html")) { + return response; + } + + let html = await response.text(); + + console.log(`1. cookie: ${context.cookies.get("theme")} `); + console.log(`2. header: ${request.headers.get("sec-ch-prefers-color-scheme")}`); + console.log(`3. mode: ${context.cookies.get("theme-mode")}`); + + const theme = context.cookies.get("theme") || request.headers.get("sec-ch-prefers-color-scheme"); + html = html.replace("{{ USER_THEME }}", theme || ""); + html = html.replace("{{ USER_THEME_MODE }}", context.cookies.get("theme-mode") || "system"); + + return new Response(html, { + status: response.status, + headers: response.headers, + }); +}; + +export const config: Config = { + path: "/*", +}; diff --git a/src/components/ThemeSelector/ThemeSelector.svelte b/src/components/ThemeSelector/ThemeSelector.svelte new file mode 100644 index 0000000..8325ebe --- /dev/null +++ b/src/components/ThemeSelector/ThemeSelector.svelte @@ -0,0 +1,83 @@ + + + + + {#if mode === "user"} + + + {:else} + + {/if} + Toggle theme + + + set_display("light")}>Light + set_display("dark")}>Dark + set_display("system")}>System + + diff --git a/src/layouts/MainLayout.astro b/src/layouts/MainLayout.astro index 8d8aaa1..1782ff5 100644 --- a/src/layouts/MainLayout.astro +++ b/src/layouts/MainLayout.astro @@ -1,7 +1,8 @@ --- import { Toaster } from "$lib/components/ui/sonner/index.js"; import "../styles/global.css"; -import Navigation from "./Navigation.astro"; +import Navigation from "../components/Navigation/Navigation.astro"; +import ThemeSelector from "../components/ThemeSelector/ThemeSelector.svelte"; interface Props { title: string; @@ -22,11 +23,12 @@ const canonicalUrl = new URL( --- - + + @@ -46,6 +48,7 @@ const canonicalUrl = new URL( + - {#if mode === "user"} - - - {:else} - - {/if} + diff --git a/src/layouts/MainLayout.astro b/src/layouts/MainLayout.astro index 1782ff5..b0f79c2 100644 --- a/src/layouts/MainLayout.astro +++ b/src/layouts/MainLayout.astro @@ -23,7 +23,7 @@ const canonicalUrl = new URL( --- - + diff --git a/src/styles/global.css b/src/styles/global.css index ccfcf82..5b640fd 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -2,11 +2,12 @@ @import "tw-animate-css"; -@custom-variant dark (&:where([data-theme=dark], [data-theme=dark] *)); +@custom-variant dark (@container style(--theme: dark)); :root { --radius: 0.625rem; color-scheme: light dark; + --theme: light; --background: light-dark(oklch(1 0 0), oklch(0.145 0 0)); --foreground: light-dark(oklch(0.145 0 0), oklch(0.985 0 0)); --card: light-dark(oklch(1 0 0), oklch(0.205 0 0)); @@ -40,24 +41,20 @@ --sidebar-ring: light-dark(oklch(0.708 0 0), oklch(0.556 0 0)); } -@media (prefers-color-scheme: light) { - :root { - color-scheme: light; - } -} - -@media (prefers-color-scheme: dark) { - :root { - color-scheme: dark; - } -} - :root[data-theme="light"] { color-scheme: light; + --theme: light; } :root[data-theme="dark"] { color-scheme: dark; + --theme: dark; +} + +:root[data-theme="system"] { + @media (prefers-color-scheme: dark) { + --theme: dark; + } } @theme inline { From a46d3822dcc6972b1f0269e0e86954fee2728e4a Mon Sep 17 00:00:00 2001 From: charlesLoder Date: Sat, 1 Aug 2026 15:01:15 -0400 Subject: [PATCH 11/13] updates the about page --- package-lock.json | 27 +++++++++++ package.json | 1 + src/pages/about.astro | 109 +++++++++++++++++++++++------------------- tsconfig.json | 2 + 4 files changed, 90 insertions(+), 49 deletions(-) diff --git a/package-lock.json b/package-lock.json index 56dc1f7..2889906 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@astrojs/netlify": "^8.0.0", "@astrojs/svelte": "^9.0.0", "@codemirror/lang-javascript": "^6.2.5", + "@tabler/icons-astro": "^3.46.0", "@tabler/icons-svelte": "^3.44.0", "@tailwindcss/vite": "^4.3.1", "astro": "^7.0.0", @@ -4536,6 +4537,32 @@ "url": "https://github.com/sponsors/codecalm" } }, + "node_modules/@tabler/icons-astro": { + "version": "3.46.0", + "resolved": "https://registry.npmjs.org/@tabler/icons-astro/-/icons-astro-3.46.0.tgz", + "integrity": "sha512-hLbPYqiVOAe6SPNRnXyMCmeVJpcqoIiXDqlMjb2deMdhZXZU6FSOtUVUG08T6zBYXqP0CieZZAkvrFgIFHfeCg==", + "license": "MIT", + "dependencies": { + "@tabler/icons": "3.46.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/codecalm" + }, + "peerDependencies": { + "astro": ">=4.0.0" + } + }, + "node_modules/@tabler/icons-astro/node_modules/@tabler/icons": { + "version": "3.46.0", + "resolved": "https://registry.npmjs.org/@tabler/icons/-/icons-3.46.0.tgz", + "integrity": "sha512-f2RYFl3fzPwj5WO82x6en0dmkjefxEfOm16D1ByM6cj/McNiwOkL4VaPUoP9VVIrXAD9WnTSVFr70px703b//A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/codecalm" + } + }, "node_modules/@tabler/icons-svelte": { "version": "3.44.0", "resolved": "https://registry.npmjs.org/@tabler/icons-svelte/-/icons-svelte-3.44.0.tgz", diff --git a/package.json b/package.json index bc9a0fe..197ba8f 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "@astrojs/netlify": "^8.0.0", "@astrojs/svelte": "^9.0.0", "@codemirror/lang-javascript": "^6.2.5", + "@tabler/icons-astro": "^3.46.0", "@tabler/icons-svelte": "^3.44.0", "@tailwindcss/vite": "^4.3.1", "astro": "^7.0.0", diff --git a/src/pages/about.astro b/src/pages/about.astro index 5ccd87f..722d2b6 100644 --- a/src/pages/about.astro +++ b/src/pages/about.astro @@ -1,12 +1,14 @@ --- import { Separator } from "$lib/components/ui/separator/index.js"; -import BrandBlueSky from "node_modules/@tabler/icons-svelte/dist/icons/brand-bluesky.svelte"; -import BrandLinkedIn from "node_modules/@tabler/icons-svelte/dist/icons/brand-linkedin.svelte"; -import BrandX from "node_modules/@tabler/icons-svelte/dist/icons/brand-x.svelte"; -import CircleA from "node_modules/@tabler/icons-svelte/dist/icons/circle-letter-a.svelte"; -import MainLayout from "src/layouts/MainLayout.astro"; +import { + IconBrandBluesky, + IconBrandLinkedin, + IconBrandX, + IconCircleLetterA, +} from "@tabler/icons-astro/"; import Card from "../components/Card/Card.svelte"; import SchemaOrg from "../components/SchemaOrg/SchemaOrg.astro"; +import MainLayout from "../layouts/MainLayout.astro"; import "../styles/global.css"; const title = "About"; @@ -27,14 +29,15 @@ const keywords = [

Hebrew Transliteration

- This web app transliterates Hebrew text into any output. It's powered by the open-source + This web app transliterates Hebrew text into any output. It's powered by the open-source{ + " " + } hebrew-transliteration + rel="noopener noreferrer">hebrew-transliteration{" "} JavaScript package and supports multiple transliteration schemas — including SBL academic style, Brill, and fully custom mappings.

@@ -47,7 +50,7 @@ const keywords = [

Transliteration converts texts from one script to another, making the text readable to those unfamiliar with the Hebrew script. It's widely used in biblical scholarship, - liturgy, linguistics, and language education. + liturgy, linguistics, and language education.{" "} -

+
diff --git a/tsconfig.json b/tsconfig.json index 1dc7c5a..1660885 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,6 +4,8 @@ "exclude": ["dist"], "compilerOptions": { "paths": { + // A new catch-all that replaces the baseUrl: + "*": ["./src/*"], "$lib": ["./src/lib"], "$lib/*": ["./src/lib/*"] } From 33a054d21bbe3a5dd7911ffceb02fc4a9ce4642e Mon Sep 17 00:00:00 2001 From: charlesLoder Date: Sat, 1 Aug 2026 22:29:28 -0400 Subject: [PATCH 12/13] fix(components): capitalize component directory names for case-sensitive CI --- src/components/{remove => Remove}/Remove.svelte | 0 src/components/{remove => Remove}/Settings.svelte | 0 src/components/{structure => Structure}/Settings.svelte | 0 src/components/{structure => Structure}/Structure.svelte | 0 .../{transliterate => Transliterate}/FeatureEditor.svelte | 0 .../{transliterate => Transliterate}/KetivQereEditor.svelte | 0 .../{transliterate => Transliterate}/NiqqudModal.svelte | 0 .../{transliterate => Transliterate}/SettingsDialog.svelte | 0 .../{transliterate => Transliterate}/Transliterate.svelte | 0 .../{transliterate => Transliterate}/utils/schemaCompletion.ts | 0 10 files changed, 0 insertions(+), 0 deletions(-) rename src/components/{remove => Remove}/Remove.svelte (100%) rename src/components/{remove => Remove}/Settings.svelte (100%) rename src/components/{structure => Structure}/Settings.svelte (100%) rename src/components/{structure => Structure}/Structure.svelte (100%) rename src/components/{transliterate => Transliterate}/FeatureEditor.svelte (100%) rename src/components/{transliterate => Transliterate}/KetivQereEditor.svelte (100%) rename src/components/{transliterate => Transliterate}/NiqqudModal.svelte (100%) rename src/components/{transliterate => Transliterate}/SettingsDialog.svelte (100%) rename src/components/{transliterate => Transliterate}/Transliterate.svelte (100%) rename src/components/{transliterate => Transliterate}/utils/schemaCompletion.ts (100%) diff --git a/src/components/remove/Remove.svelte b/src/components/Remove/Remove.svelte similarity index 100% rename from src/components/remove/Remove.svelte rename to src/components/Remove/Remove.svelte diff --git a/src/components/remove/Settings.svelte b/src/components/Remove/Settings.svelte similarity index 100% rename from src/components/remove/Settings.svelte rename to src/components/Remove/Settings.svelte diff --git a/src/components/structure/Settings.svelte b/src/components/Structure/Settings.svelte similarity index 100% rename from src/components/structure/Settings.svelte rename to src/components/Structure/Settings.svelte diff --git a/src/components/structure/Structure.svelte b/src/components/Structure/Structure.svelte similarity index 100% rename from src/components/structure/Structure.svelte rename to src/components/Structure/Structure.svelte diff --git a/src/components/transliterate/FeatureEditor.svelte b/src/components/Transliterate/FeatureEditor.svelte similarity index 100% rename from src/components/transliterate/FeatureEditor.svelte rename to src/components/Transliterate/FeatureEditor.svelte diff --git a/src/components/transliterate/KetivQereEditor.svelte b/src/components/Transliterate/KetivQereEditor.svelte similarity index 100% rename from src/components/transliterate/KetivQereEditor.svelte rename to src/components/Transliterate/KetivQereEditor.svelte diff --git a/src/components/transliterate/NiqqudModal.svelte b/src/components/Transliterate/NiqqudModal.svelte similarity index 100% rename from src/components/transliterate/NiqqudModal.svelte rename to src/components/Transliterate/NiqqudModal.svelte diff --git a/src/components/transliterate/SettingsDialog.svelte b/src/components/Transliterate/SettingsDialog.svelte similarity index 100% rename from src/components/transliterate/SettingsDialog.svelte rename to src/components/Transliterate/SettingsDialog.svelte diff --git a/src/components/transliterate/Transliterate.svelte b/src/components/Transliterate/Transliterate.svelte similarity index 100% rename from src/components/transliterate/Transliterate.svelte rename to src/components/Transliterate/Transliterate.svelte diff --git a/src/components/transliterate/utils/schemaCompletion.ts b/src/components/Transliterate/utils/schemaCompletion.ts similarity index 100% rename from src/components/transliterate/utils/schemaCompletion.ts rename to src/components/Transliterate/utils/schemaCompletion.ts From bfae7bf4d2cb312b2af0e6e9125f4838dec96221 Mon Sep 17 00:00:00 2001 From: charlesLoder Date: Tue, 4 Aug 2026 16:05:42 -0400 Subject: [PATCH 13/13] fix: tests failing from netlify edge functions --- playwright.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/playwright.config.ts b/playwright.config.ts index c0b8e84..3654f71 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -9,7 +9,7 @@ export default defineConfig({ timeout: 10000, }, webServer: { - command: "npm run dev", + command: "NETLIFY_DEV=1 npm run dev", port: 4321, reuseExistingServer: false, timeout: 120 * 1000,