Skip to content

Commit

Permalink
splitting out
Browse files Browse the repository at this point in the history
  • Loading branch information
AlfieJones committed Apr 28, 2024
1 parent 318ee0f commit 63246e9
Show file tree
Hide file tree
Showing 67 changed files with 7,271 additions and 436 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,3 @@ build
.sass-cache
./index.html
.vscode
css
28 changes: 16 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
<img width="100%" src="./banner-dark.gif#gh-dark-mode-only" />
<img width="100%" src="./banner-light.gif#gh-light-mode-only" />


<div align="center">
<br />
<img alt="NPM version" src="https://img.shields.io/npm/v/theme-toggles?style=for-the-badge">


<!-- PROJECT LOGO -->
<br />
<h1 >Theme Toggles</h1>
Expand All @@ -17,7 +15,7 @@
</h2>
</div>

> This is the v5 branch. The current release version can be found [here](https://github.com/alfiejones/theme-toggles/tree/v4). Version 5 is a complete refactor of the library
> This is the v5 branch. The current release version can be found [here](https://github.com/alfiejones/theme-toggles/tree/v4). Version 5 is a complete refactor of the library
### Installing the latest version

Expand All @@ -28,23 +26,22 @@ You can install the latest version by using:

## Packages

| Name | Version |
| :------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------: |
| [`theme-toggles`](https://github.com/alfiejones/theme-toggles/tree/main/) | [![npm version](https://img.shields.io/npm/v/theme-toggles.svg)](https://www.npmjs.com/package/theme-toggles) |
| [`@theme-toggles/react`](https://github.com/alfiejones/theme-toggles/tree/main/packages/react) | [![npm version](https://img.shields.io/npm/v/@theme-toggles/react.svg)](https://www.npmjs.com/package/@theme-toggles/react) |
| Name | Version |
| :--------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------: |
| [`theme-toggles`](https://github.com/alfiejones/theme-toggles/tree/main/) | [![npm version](https://img.shields.io/npm/v/theme-toggles.svg)](https://www.npmjs.com/package/theme-toggles) |
| [`@theme-toggles/react`](https://github.com/alfiejones/theme-toggles/tree/main/packages/react) | [![npm version](https://img.shields.io/npm/v/@theme-toggles/react.svg)](https://www.npmjs.com/package/@theme-toggles/react) |

## About

Our project provides you with a quick and effortless way to implement well designed toggles. With more websites supporting both light and dark themes, it's important to ensure sites also have a clean and accessible toggle.

We use SVG’s for each of our toggles, animating them with CSS. Using SVG’s instead of html elements like div’s enables us to have minimal markup whilst maintaining a high quality and scalable icon.

### Features
* Tiny ~1.5kb (min and gzip)
* Accessible
* Customizable

## Roadmap
New development is currently happening on the v5 branch
- Tiny ~1.5kb (min and gzip)
- Accessible
- Customizable

## Contributing

Expand All @@ -56,6 +53,13 @@ Contributions are what make the open source community such an amazing place to b
4. Push to the Branch (`git push origin feature/AmazingFeature`)
5. Open a Pull Request

### Adding a new Toggle

Got an idea for a new toggle? We'd love to see it!

You'll need to create a new file in the `./css/src/toggles` directory. More info can be found in the [CSS README](./css/README.md).

You'll also need to create a new file in the `./svgs/files` directory.

## License

Expand Down
28 changes: 28 additions & 0 deletions configs/eslint-config/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
module.exports = {
extends: ['turbo', 'prettier', 'plugin:astro/recommended'],
ignorePatterns: ['node_modules', 'dist'],
parserOptions: {
babelOptions: {
presets: [require.resolve('next/babel')],
},
},
overrides: [
{
// Define the configuration for `.astro` file.
files: ["*.astro"],
// Allows Astro components to be parsed.
parser: "astro/client-side-ts",
// Parse the script in `.astro` as TypeScript by adding the following configuration.
// It's the setting you need when using TypeScript.
parserOptions: {
parser: "@typescript-eslint/parser",
extraFileExtensions: [".astro"],
},
rules: {
// override/add rules settings here, such as:
// "astro/no-set-html-directive": "error"
},
},
// ...
],
};
14 changes: 14 additions & 0 deletions configs/eslint-config/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "@theme-toggles/eslint-config",
"version": "0.0.0",
"private": true,
"main": "index.js",
"dependencies": {
"@typescript-eslint/parser": "^7.7.1",
"eslint-config-prettier": "^9.1.0",
"eslint-config-turbo": "^1.13.2",
"eslint-plugin-astro": "^1.0.3",
"eslint-plugin-jsx-a11y": "^6.8.0",
"eslint-plugin-react": "7.34.1"
}
}
28 changes: 28 additions & 0 deletions configs/tsconfig/base.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"display": "Default",
"compilerOptions": {
"composite": false,
"declaration": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"inlineSources": false,
"isolatedModules": false,
"moduleResolution": "node",
"module": "ESNext",
"target": "ES2021",
"lib": [
"ESNext"
],
"outDir": "dist",
"preserveWatchOutput": true,
"skipLibCheck": true,
"strict": true,
"baseUrl": "."
},
"exclude": [
"node_modules",
"dist",
"bin"
]
}
5 changes: 5 additions & 0 deletions configs/tsconfig/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "@theme-toggles/tsconfig",
"version": "0.0.0",
"private": true
}
14 changes: 14 additions & 0 deletions configs/tsconfig/react.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"display": "React Library",
"extends": "./base.json",
"compilerOptions": {
"jsx": "react-jsx",
"lib": [
"ESNext",
"DOM"
],
"module": "ESNext",
"moduleResolution": "Node"
}
}
1 change: 1 addition & 0 deletions css/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dist
34 changes: 34 additions & 0 deletions css/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# @theme-toggles/css

This package contains the SCSS files for the theme toggles.

## Adding a new toggle

To add a new toggle, just create a new SCSS file under `./src/toggles`.

We provide some helper SCSS functions to make it easier to create new toggles. A good starting template for a new toggle is the following:

```scss
@import "./../variables.scss";
@import "./../utils.scss";

// Creates our css variables
$variable: #{getVar(TOGGLE_NAME)};

// Allows people to flip the toggle. This isn't always needed / works properly depending on the toggle
@include generic(TOGGLE_NAME, flip-x);

.theme-toggle__TOGGLE_NAME {
// Add the styles for the default state here
}

@include toggledSelector(TOGGLE_NAME) {
// Add the styles for the toggled state here
}
```

## Building

We have a build script `build.ts` that bundles up our SCSS files into our different variants. To run this script, you can use the following command:

`pnpm build`
151 changes: 151 additions & 0 deletions css/build.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
import { mkdir, readFile, readdir, rm, writeFile } from "node:fs/promises";
import { compileString } from "sass";
import { transform } from "lightningcss";
import { join } from "node:path";
import { format } from "prettier";
import { build } from "esbuild";
import { execSync } from "node:child_process";

function kebabToCamel(kebab: string) {
return kebab.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
}

function formatTS(content: string) {
return format(content, {
parser: "typescript",
});
}

const files = (await readdir("./src/toggles")).map((file) =>
file.replace(".scss", "")
);

const variants = (await readdir("./src/variants")).map((file) =>
file.replace(".scss", "")
);

async function generateToggleVariantCSS(toggle: string, variant: string) {
const combinedCSS = await Promise.all([
readFile(`./src/variants/${variant}.scss`, "utf-8"),
readFile(`./src/global/shared.scss`, "utf-8"),
readFile(`./src/toggles/${toggle}.scss`, "utf-8"),
]).then((values) => values.join("\n"));

const variables = await readFile(`./src/variables.scss`, "utf-8");
const utils = await readFile(`./src/utils.scss`, "utf-8");

const { css } = compileString(combinedCSS, {
importers: [
{
canonicalize(url) {
if (url.endsWith("variables.scss") || url.endsWith("utils.scss")) {
return new URL(url, import.meta.url);
}
return null;
},
load(url) {
if (url.pathname.endsWith("variables.scss")) {
return { syntax: "scss", contents: variables };
} else if (url.pathname.endsWith("utils.scss")) {
return { syntax: "scss", contents: utils };
}
return null;
},
},
],
});

return new TextDecoder().decode(
transform({
code: new TextEncoder().encode(css),
filename: `${variant}/${toggle}.css`,
minify: true,
}).code
);
}

async function generateTSExport(name: string, variant: string, css: string) {
const filename =
kebabToCamel(name) + variant.charAt(0).toUpperCase() + variant.slice(1);

const contents = `export const ${filename}: string = \`${css}\`;`;

await writeFile(join("./temp", `${filename}.ts`), await formatTS(contents));
}

async function generateIndexTs() {
const imports = variants
.flatMap((variant) =>
files.map(
(file) =>
kebabToCamel(file) +
variant.charAt(0).toUpperCase() +
variant.slice(1)
)
)
.map((name) => `import { ${name} } from "./${name}";`)
.join("\n");

const exports = variants.flatMap((variant) =>
files.map(
(file) =>
kebabToCamel(file) + variant.charAt(0).toUpperCase() + variant.slice(1)
)
);

const contents = `${imports}
export {
${exports.join(",\n ")}
};
`;
await writeFile(join("./temp", `index.ts`), await formatTS(contents));
}

async function generateCSS() {
for (const variant of variants) {
await mkdir(`./dist/${variant}`, { recursive: true });
for (const toggle of files) {
const css = await generateToggleVariantCSS(toggle, variant);
await writeFile(`./dist/${variant}/${toggle}.css`, css);
await generateTSExport(toggle, variant, css);
}
}

await generateIndexTs();
}

async function generateTypescriptDist() {
const distDir = "./dist";
await mkdir(distDir, { recursive: true });

await build({
entryPoints: [join("./temp", "index.ts")],
outdir: distDir,
bundle: true,
format: "esm",
});
}

async function init() {
await rm("./dist", { recursive: true }).catch(() => {});
await rm("./temp", { recursive: true }).catch(() => {});

await mkdir("./temp", { recursive: true });
}

async function cleanUp() {
await rm("./temp", { recursive: true });
}

function generateTypes() {
execSync(
"pnpm tsc ./temp/index.ts --emitDeclarationOnly --outDir ./dist --declaration"
);
}

await init();
await generateCSS();
await generateTypescriptDist();
generateTypes();
await cleanUp();
25 changes: 25 additions & 0 deletions css/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "@theme-toggles/css",
"version": "0.0.0",
"type": "module",
"scripts": {
"build": "tsx ./build.ts"
},
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"files": [
"dist"
],
"devDependencies": {
"@theme-toggles/tsconfig": "workspace:*",
"@types/node": "^20.12.7",
"esbuild": "^0.20.2",
"lightningcss": "^1.24.1",
"node-sass": "^9.0.0",
"prettier": "^3.2.5",
"sass": "^1.57.1",
"ts-node": "^10.9.2",
"tsx": "^4.7.3"
},
"dependencies": {}
}
Loading

0 comments on commit 63246e9

Please sign in to comment.