{"id":19675529,"url":"https://github.com/notnite/nottheme","last_synced_at":"2025-04-29T02:30:39.568Z","repository":{"id":257800243,"uuid":"862564758","full_name":"NotNite/nottheme","owner":"NotNite","description":"Accessible theme switcher for Astro","archived":false,"fork":false,"pushed_at":"2025-03-30T18:32:27.000Z","size":208,"stargazers_count":10,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-23T21:16:16.140Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Astro","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/NotNite.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-09-24T20:12:33.000Z","updated_at":"2025-03-30T18:32:30.000Z","dependencies_parsed_at":null,"dependency_job_id":"2c63a586-7b2f-462c-bb7d-3c0831853d2e","html_url":"https://github.com/NotNite/nottheme","commit_stats":null,"previous_names":["notnite/nottheme"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NotNite%2Fnottheme","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NotNite%2Fnottheme/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NotNite%2Fnottheme/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NotNite%2Fnottheme/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/NotNite","download_url":"https://codeload.github.com/NotNite/nottheme/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251420886,"owners_count":21586697,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-11T17:24:37.924Z","updated_at":"2025-04-29T02:30:39.563Z","avatar_url":"https://github.com/NotNite.png","language":"Astro","funding_links":[],"categories":[],"sub_categories":[],"readme":"# nottheme\n\nAccessible theme switcher for Astro. Designed for static sites, and works without JavaScript.\n\n## Installation/usage\n\nnottheme targets modern web browsers (~2024) and uses modern CSS features (`:has()`, `:not()`, and `var()`). **If you aren't targeting modern browsers, don't use nottheme.**\n\n```shell\nnpm i nottheme\n```\n\nSee [the demo](https://github.com/NotNite/nottheme/blob/main/demo/ssg/src/layout.astro) for usage. TL;DR:\n\n- Create your settings using the `settings` and `options` helper functions. Keep it in another file so you can import it where you need it.\n  - If you're using TypeScript, defining your options as individual variables and then merging them into the `settings` object adds better type safety.\n- Add the `ThemeStyling` component to the bottom of your `head` element.\n- Add the `ThemeLoader` component to the top of your `body` element.\n- Put the `ThemeSelect` component somewhere on your site.\n- Use your theme settings as CSS variables with `var()`.\n\n**These components and classes must be present on every page.** If you have a layout file for your site, put these components there. `ThemeSelect` should be easily accessible from every page (e.g. in a header).\n\n## Styling with nottheme\n\nIf you define a \"theme\" option like this:\n\n```ts\nconst theme = option({\n  choices: [\"light\", \"dark\"],\n  values: {\n    light: {\n      \"--bg\": \"#fff\",\n      \"--fg\": \"#000\"\n    },\n    dark: {\n      \"--bg\": \"#000\",\n      \"--fg\": \"#fff\"\n    }\n  },\n  default: \"light\"\n});\n```\n\n...you can use those CSS variables like this:\n\n```css\nbody {\n  background-color: var(--bg);\n  color: var(--fg);\n}\n```\n\nAn option consists of the following:\n\n- A unique ID for the option (e.g. `theme` or `font`)\n- Unique IDs for each choice (e.g. `light` or `dark`)\n- CSS variables for each choice\n- (Optional) Human readable names for the option and choices\n- (Optional) The default choice to use (supports CSS media queries)\n\nYou can define the global JavaScript function `window.__nottheme_onChange` for when values change:\n\n```ts\nwindow.__nottheme_onChange = (option: string, choice: string) =\u003e {\n  console.log(option, choice);\n};\n```\n\nThis will also fire when the page loads, as it applies settings from localStorage.\n\n## Theme application\n\nThemes are applied differently depending on if JavaScript is enabled or not.\n\nWith JavaScript enabled, the selected theme is saved in `localStorage` and applied on page load. The `nottheme-js` class is applied to signal JavaScript being enabled. Choices are applied by adding custom class names (`nottheme__${option}__${choice}`).\n\nWith JavaScript disabled, the selected theme is temporary and resets on page load. A blank `option` element is present in the `ThemeSelect` component to not lock up the themes. Choices are applied by targeting the `:checked` pseudo-class selector on the `option` element.\n\n## nottheme selectors\n\n- `nottheme`: A custom element that contains the theme settings in its dataset\n- `.nottheme-js`: Applied if the page is loading themes with JavaScript\n- `.nottheme__${option}__${choice}`: Applied when the choice is selected with JavaScript\n\nThese selectors target `ThemeSelect`:\n\n- `.nottheme-select`: The root `div` of ThemeSelect\n- `.nottheme-select-entry`: The `div` for an option, containing the `label` and `select`\n- `.nottheme-select-entry-label`: The `label` element for an option\n- `#nottheme-select-entry__${option}`, `.nottheme-select-entry-choices`: The `select` element for an option\n- `#nottheme-choice-blank__${option}`: The blank `option` element for compatibility with zero JavaScript\n- `#nottheme-choice__${option}__${choice}`: The `option` element for a choice\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnotnite%2Fnottheme","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnotnite%2Fnottheme","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnotnite%2Fnottheme/lists"}