Skip to content

Commit

Permalink
refactor: finalize 0.1
Browse files Browse the repository at this point in the history
  • Loading branch information
quantizor committed Sep 20, 2023
1 parent bc6daf7 commit 12fb8c8
Show file tree
Hide file tree
Showing 26 changed files with 1,293 additions and 509 deletions.
10 changes: 10 additions & 0 deletions .github/actions/setup/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
name: setup environment
description: bun setup
runs:
using: "composite"
steps:
- uses: oven-sh/setup-bun@v1
with:
bun-version: latest
- run: bun install --frozen-lockfile --ignore-scripts
shell: bash
24 changes: 24 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: ci

on:
push:
branches:
- "main"
pull_request:
pull_request_target:

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/setup
- run: bun compile
name: compile
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/setup
- run: bun test
name: test
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
# Logs
*.log

# macOS
.DS_Store

# Dependency directories
node_modules/

# TypeScript cache
# Cache
*.tsbuildinfo
.parcel-cache

# Output of 'npm pack'
*.tgz

# Generated files
**/generated.*
**/.generated
**/*.generated.*
12 changes: 12 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"recommendations": [
"esbenp.prettier-vscode",
"oven.bun-vscode",
"bradlc.vscode-tailwindcss",
"jaaxxx.bun-lockb",
"tamasfe.even-better-toml",
"me-dutour-mathieu.vscode-github-actions",
"christian-kohler.path-intellisense",
"redhat.vscode-yaml"
]
}
8 changes: 7 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
{
"editor.codeActionsOnSave": {
"source.organizeImports": true
}
},
"editor.quickSuggestions": {
"other": "on",
"comments": "off",
"strings": "on"
},
"tailwindCSS.colorDecorators": false
}
21 changes: 21 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# contributing to twyx

First, thank you! Contributors are what make open source go 'round, so your interest is very appreciated.

## installation

1. ensure `bun` [is installed](https://bun.sh/)
2. `bun install`

## adding a framework adapter

twyx is designed as both a core standalone library and with third-party framework adapters like `twyx/react`.

To add an adapter for a new framework:

1. create an appropriately-named file in the `src` directory and integrate `twyx` using the best practices of your framework.
2. try to limit installed packages to the bare minimum
3. add an entry to `package.json "exports"` for the new file
4. add the file to the `compile:lib` script target
5. add the file to `tsconfig.json "include"`
6. add a section to the README
84 changes: 82 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,23 @@
# twyx

an attempt to map xstyled's syntax to tailwind equivalents and expose this functionality as components
tailwind for css people

## install

```sh
bun install twyx
bun add twyx
```

If you are using one of the supported framework(s) below, any additional dependencies are listed.

| framework | install command |
| --------- | ----------------------------------------- |
| react | `bun add react; bun add -D @types/react;` |

### configure tailwind to use the twyx transformer

twyx is able to autogenerate tailwind classes at build time using a custom transformer. Follow the example below and hook up the transformer to any file types where twyx usage occurs.

```ts
// tailwind.config.ts

Expand All @@ -29,6 +39,46 @@ export default {

## usage

All the normal rules of tailwind still apply, namely templating class names is strictly forbidden.

<strong style="color: limegreen">do</strong>

```ts
twyx({
borderColor: condition ? "green-200" : "green-500",
color: "red-500",
});
```

<strong style="color: red">don't</strong>

```ts
twyx({
borderColor: `green-${condition ? 200 : 500}`,
});
```

> **Why?** Tailwind runs a simple scanner over files to determine if classes it knows about are in use. If you write
> conditional styles in such a way that the whole string is not present at build time, the scanner will not work and
> the class will not be generated unless you [manually safelist](https://tailwindcss.com/docs/content-configuration#safelisting-classes) it.
### standalone

```tsx
import { twyx } from "twyx";

const classes = twyx({
borderColor: "red-500",
borderStyle: { _: "solid", md: "dashed", dark: { _: "dashed", md: "solid" } },
borderWidth: 1,
})();

// out:
// classes === "border border-solid md:border-dashed dark:border-dashed md:dark:border-solid border-red-500"
```

### react

```tsx
import { x } from 'twyx/react'

Expand All @@ -38,3 +88,33 @@ import { x } from 'twyx/react'
// out
<p className="border border-solid md:border-dashed dark:border-dashed md:dark:border-solid border-red-500" />
```

### extending twyx

If you add additional tailwind utility classes in your project and want them to be picked up by twyx autocomplete, you'll need to do perform a module augmentation like so:

```ts
declare module 'twyx' {
export namespace Twyx {
type CustomColors = ColorProps<'indigo' | 'chartreuse'>;

export interface PropValues extends ColorProps<BaseColors | BaseColorTransparencies>, CustomColors {
aspectRatio: 'my-custom-value';
}
}
```
Custom values will be appended to the original type.
### todo
Community help on the below is very appreciated!
- [ ] figure out if it's possible to hook up Tailwind's nice VS Code extension autocomplete directly to twyx
- [ ] write some tests
- [ ] website using astro (just wanna try it and see what's up)
- [ ] set up ci & changesets
---
Thank you very much to the Tailwind team for creating a fantastic framework. This library is meant to act as a bridge for those that prefer the CSS-way of referring to things.
Binary file modified bun.lockb
Binary file not shown.
22 changes: 14 additions & 8 deletions demo/index.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,26 @@
import * as ReactDOM from "react-dom/client";
import { twyx, x } from "../src/react";

const foo = true;
const className = twyx({
display: { _: "block", md: "flex" },
bg: { _: "green-100", dark: { _: "green-900", hover: "green-800" } },
bg: { _: "gray-100", dark: { _: "gray-900" } },
color: { _: "gray-900", dark: { _: "gray-100" } },
h: "screen",
outlineColor: "amber-100/[.50]",
});

export default function HelloWorld() {
return (
<x.p
// TODO: remove need for square brackets
borderRadius={foo ? "[3px]" : "sm"}
// TODO: fix typing to allow for deep objects in JSX
color={{ _: "red-100", dark: { _: "red-900", hover: "red-800" } }}
>
You could say we were made for this.
<x.p className={className} fontSize="xl" p={7}>
<x.span color="yellow-500" fontWeight={700} mr={1}>
twyx
</x.span>{" "}
is tailwind for css people
</x.p>
);
}

const root = ReactDOM.createRoot(document.body);

root.render(<HelloWorld />);
5 changes: 3 additions & 2 deletions demo/public/index.html
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>twyx demo</title>
<link rel="stylesheet" href="/style.generated.css" />
<link rel="stylesheet" href="./style.generated.css" />
<script src="../index.tsx" type="module"></script>
</head>
<body></body>
</html>
7 changes: 5 additions & 2 deletions demo/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
"extends": "../tsconfig.json",
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "react"
}
"jsxImportSource": "react",
"lib": ["dom"],
"outDir": "./public"
},
"include": ["./index.tsx"]
}
68 changes: 58 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,36 +1,84 @@
{
"name": "twyx",
"author": "Evan Jacobs",
"version": "0.0.0",
"author": "Evan Jacobs <[email protected]> (https://probablyup.com)",
"version": "0.1.0",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/probablyup/twyx"
},
"module": ".generated/core.js",
"types": ".generated/src/core.d.ts",
"exports": {
".": "./.generated/core.js",
"./react": "./.generated/react.js",
"./transformer": "./.generated/transformer.js"
".": {
"types": "./.generated/src/core.d.ts",
"import": "./.generated/core.js"
},
"./react": {
"types": "./.generated/src/react.d.ts",
"import": "./.generated/react.js"
},
"./transformer": {
"types": "./.generated/transformer.d.ts",
"import": "./.generated/transformer.js"
}
},
"files": [
"dist",
".generated",
"README.md",
"LICENSE"
],
"sideEffects": false,
"dependencies": {
"clsx": "^2.0.0",
"csstype": "^3.1.2"
"csstype": "^3.1.2",
"tailwindcss": "^3.3.3"
},
"devDependencies": {
"@types/debug": "^4.1.8",
"@types/escodegen-jsx": "npm:@types/escodegen",
"@types/react": "^18.2.21",
"@types/react-dom": "^18.2.7",
"@types/react-test-renderer": "^18.0.2",
"ast-types": "^0.14.2",
"bun-types": "^1.0.1",
"bundlemon": "^2.0.2",
"concurrently": "^8.2.1",
"debug": "^4.3.4",
"escodegen-jsx": "^0.1.0-1.4.2dev",
"espree": "^9.6.1",
"prettier": "^3.0.3",
"react": "^18.2.0",
"tailwindcss": "^3.3.3",
"react-dom": "^18.2.0",
"react-test-renderer": "^18.2.0",
"typescript": "^5.2.2",
"unquote": "^1.1.1"
},
"scripts": {
"compile:tailwind": "tailwindcss -i demo/style.css -o demo/public/style.generated.css --minify"
"prepare": "bun compile:colors",
"prepublishOnly": "bun compile",
"check:unit": "bun test",
"check:size": "bundlemon",
"compile": "bun compile:colors && bun compile:lib && bun compile:transformer && bun compile:types && bun check:size",
"compile:colors": "bun scripts/generate-colors.ts",
"compile:lib": "bun build src/core.ts src/react.tsx --external=* --outdir=.generated --sourcemap=external --minify",
"postcompile:lib": "bun check:size",
"compile:demo:css": "tailwindcss -c tailwind.config.ts -i demo/style.css -o demo/public/style.generated.css --minify",
"compile:demo:js": "parcel build demo/public/index.html --dist-dir demo/public/.generated",
"compile:transformer": "bun build ./transformer.ts --outdir=.generated --sourcemap=external --minify",
"compile:types": "tsc -p tsconfig.build.json",
"dev": "concurrently 'bun --watch scripts/generate-colors.ts' 'parcel demo/public/index.html --dist-dir demo/public/.generated --open' 'bun compile:demo:css --watch'"
},
"bundlemon": {
"baseDir": ".generated",
"files": [
{
"path": "core.js",
"maxSize": "3 kB"
},
{
"path": "react.js",
"maxSize": "3 kB"
}
]
}
}
Loading

0 comments on commit 12fb8c8

Please sign in to comment.