Skip to content

Commit 1c6074b

Browse files
authored
v1 (#62)
1 parent 7777055 commit 1c6074b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+1578
-10644
lines changed

.github/workflows/deploy.yml

Lines changed: 0 additions & 39 deletions
This file was deleted.

.gitignore

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
node_modules
22
lib
3-
docs/.vitepress/cache
4-
docs/.vitepress/dist
53
.DS_Store
64
.idea

README.md

Lines changed: 233 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,262 @@
1-
# 💧 MistCSS
1+
# MistCSS
22

3-
[![Node.js CI](https://github.com/typicode/mistcss/actions/workflows/node.js.yml/badge.svg)](https://github.com/typicode/mistcss/actions/workflows/node.js.yml)
3+
> Simplicity is the ultimate sophistication
44
5-
> Create components with 50% less code
5+
MistCSS lets you create reusable visual components without JavaScript or TypeScript (_think about it for a second... no JS/TS needed_).
66

7-
MistCSS is a new, better and faster way to write visual components. ~~CSS-in-JS~~? Nope! JS-from-CSS 👍
7+
Leverage native HTML and CSS, get type safety and auto completion. Just clean and efficient styling.
88

9-
All major frameworks are supported.
9+
<img width="1116" alt="Screenshot 2024-11-01 at 03 47 44" src="https://github.com/user-attachments/assets/74aea071-be00-4d03-b43a-e46d6282e4b5">
1010

11-
## 1. Write your component in CSS only
11+
_What you see above is standard HTML ([data-attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/data-*)) and CSS ([nested CSS](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_nesting/Using_CSS_nesting)). MistCSS simply creates a `d.ts` file based on your CSS._
1212

13-
`./src/Button.mist.css`
13+
## Features
14+
15+
- 🥶 Below zero-runtime, it's zero JavaScript. Smaller bundles and faster code.
16+
- 💎 What you write is what you get. No transformations, easy debugging.
17+
- 🎒 Standards-based, reusable styles across frameworks, compatible with Tailwind or any CSS framework
18+
- ⚡️ Instantly productive, no learning curve, simple onboarding.
19+
- 💖 Back to basics with a modern twist: access the full power of HTML and CSS, enhanced with type safety and code completion (without the complexity).
20+
21+
## Usage
22+
23+
Traditional approaches require wrapping your markup/styles in JavaScript functions (`Button.tsx``<button/>`, `Input.tsx``<input/>`, ...), defining props with TypeScript types, and writing logic to manage class names.
24+
25+
With MistCSS, styling is straightforward and minimal. Here’s how it looks:
26+
27+
`mist.css`
1428

1529
```css
16-
@scope (button.custom-button) {
17-
:scope {
18-
background: black;
30+
button {
31+
border-radius: 1rem;
32+
padding: 1rem;
33+
background: lightgray;
34+
35+
&[data-variant='primary'] {
36+
background-color: black;
1937
color: white;
38+
}
39+
40+
&[data-variant='secondary'] {
41+
background-color: grey;
42+
color: white;
43+
}
44+
}
45+
```
2046

21-
/* 👇 Define component's props directly in your CSS */
22-
&[data-variant='primary'] {
23-
background: blue;
24-
}
47+
`Page.tsx`
2548

26-
&[data-variant='secondary'] {
27-
background: gray;
28-
}
49+
```jsx
50+
<>
51+
<button data-variant="primary">Save</button>
52+
<button data-variant="tertiary">Save</button> {/* TS error, tertiary isn't valid */}
53+
</>
54+
```
55+
56+
Output
57+
58+
```jsx
59+
<button data-variant="primary">Save</button> {/* Same as in Page.tsx */}
60+
```
61+
62+
_This example demonstrates enums, but MistCSS also supports boolean and string props. For more details, see the FAQ._
63+
64+
## How does it work?
65+
66+
MistCSS parses your `mist.css` file and generates `mist.d.ts` for type safety.
67+
68+
For instance, here’s the generated `mist.d.ts` for our button component:
69+
70+
```typescript
71+
interface Mist_button extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLButtonElement>, HTMLButtonElement> {
72+
'data-variant'?: 'primary' | 'secondary'
73+
}
74+
75+
declare namespace JSX {
76+
interface IntrinsicElements {
77+
button: Mist_button // ← <button/> is extended at JSX level to allow 'primary' and 'secondary' values
2978
}
3079
}
3180
```
3281

33-
## 2. Run MistCSS codegen
82+
That’s it! Simple yet powerful, built entirely on browser standards and TypeScript/JSX.
83+
84+
## Install
85+
86+
```sh
87+
npm install mistcss --save-dev
88+
```
89+
90+
`postcss.config.js`
91+
92+
```js
93+
module.exports = {
94+
plugins: {
95+
mistcss: {},
96+
},
97+
}
98+
```
99+
100+
`layout.tsx`
34101

35-
```shell
36-
mistcss ./src --target=react --watch
37-
# It will create ./src/Button.mist.tsx
102+
```ts
103+
import './mist.css'
38104
```
39105

40-
## 3. Get a type-safe component without writing TypeScript
106+
## FAQ
107+
108+
### Can I use CSS frameworks like Tailwind or Open Props?
109+
110+
Absolutely, MistCSS is pure HTML and CSS, generating only `mist.d.ts`, so there are no limitations. You can integrate any CSS framework seamlessly. Here are a few examples to get you started:
111+
112+
#### Tailwind v3 ([@apply](https://tailwindcss.com/docs/functions-and-directives#apply))
113+
114+
```css
115+
button {
116+
@apply bg-blue-500 text-white;
117+
/* ... */
118+
}
119+
```
120+
121+
#### Tailwind v3 ([theme](https://tailwindcss.com/docs/functions-and-directives#theme))
122+
123+
```css
124+
button {
125+
background: theme(colors.blue.500);
126+
/* ... */
127+
}
128+
```
129+
130+
#### Tailwind v4
131+
132+
Tailwind v4 will support CSS variables natively (see [blog post](https://tailwindcss.com/blog/tailwindcss-v4-alpha
133+
)).
41134

42-
`./src/App.tsx`
135+
#### Tailwind (inline style)
136+
137+
To override some styles, you can use `className`
138+
139+
```jsx
140+
<button data-variant="primary" className="p-12">
141+
Save
142+
</button>
143+
```
144+
145+
#### Open Props
146+
147+
```css
148+
button {
149+
background-color: var(--blue-6);
150+
/* ... */
151+
}
152+
```
153+
154+
### Can I do X without JavaScript?
155+
156+
CSS is more powerful than ever, before reaching for JS, explore if native CSS features can accomplish what you need.
157+
158+
### How to write enum, boolean, string props and conditions?
159+
160+
```css
161+
div[data-component='section']
162+
/* CSS variables */
163+
--color: ...;
164+
165+
/* Default styles */
166+
background: var(--color, green);
167+
margin: ...;
168+
padding: ...;
169+
170+
/* Enum props */
171+
&[data-size="sm"] { ... }
172+
&[data-size="lg"] { ... }
173+
174+
/* Boolean props */
175+
&[data-is-active] { ... }
176+
177+
/* Condition: size="lg" && is-active */
178+
&[data-size="lg"]&[data-is-active] { ... }
179+
180+
/* Condition: size="lg" && !is-active */
181+
&[data-size="lg"]:not([data-is-active]) { ... }
182+
}
183+
```
184+
185+
```jsx
186+
<div
187+
data-component="section"
188+
data-size="foo"
189+
data-is-active
190+
style={{ '--color': 'red' }}
191+
/>
192+
```
193+
194+
### How to re-use the same tag
195+
196+
If you want both basic links and button-styled links, here’s how you can do:
197+
198+
```css
199+
a { /* ... */ }
200+
201+
a[data-component='button'] { /* ... */
202+
&[data-variant='primary'] { /* ... */ }
203+
}
204+
```
43205

44206
```jsx
45-
import { CustomButton } from './Button.mist'
207+
<>
208+
<a href="/home">Home</a>
209+
<a href="/home" data-component="button">Home</a>
210+
<a href="/home" data-component="button" data-variant="primary">Home</a>
211+
<a href="/home" data-variant="primary">Home</a> {/* TS error, `data-variant` is only valid with `data-component="button"` */}
212+
</>
213+
```
214+
215+
> [!NOTE]
216+
> `data-component` is just a naming convention. Feel free to use any attribute, like `data-style='button'` or `data-button`. It’s simply a way to differentiate between components using the same tag.
217+
218+
219+
### How to build complex components?
46220

47-
export const App = () => (
48-
<>
49-
<CustomButton variant="primary">Save</CustomButton>
221+
`mist.css`
50222

51-
{/* TypeScript will catch the error */}
52-
<CustomButton variant="tertiary">Cancel</CustomButton>
53-
</>
54-
)
223+
```css
224+
article[data-component='card'] { /* ... */ }
225+
div[data-component='card-title'] { /* ... */ }
226+
div[data-component='card-content'] { /* ... */ }
227+
```
228+
229+
`Card.jsx`
230+
231+
```jsx
232+
export function Card({ title, children }) {
233+
return (
234+
<article data-component="card">
235+
<div data-component="card-title">{title}</div>
236+
<div data-component="card-content">{children}</div>
237+
</article>
238+
)
239+
}
55240
```
56241

57-
MistCSS can generate ⚛️ **React**, 💚 **Vue**, 🚀 **Astro**, 🧠**Svelte** and 🔥 **Hono** components. You can use 🍃 **Tailwind CSS** to style them.
242+
> [!TIP]
243+
> To indicate that these styles aren't meant to be used outside of `Card`, you can name them `data-p-component` (`p` for `private`) or use another naming convention.
58244
59-
## Documentation
245+
### How to define CSS variables
246+
247+
```css
248+
:root {
249+
--primary-color: #007bff;
250+
--secondary-color: #6c757d;
251+
}
252+
253+
button {
254+
background: var(--primary-color)
255+
/* ... */
256+
```
60257

61-
https://typicode.github.io/mistcss
258+
See also your CSS framework/tooling documentation for ways to define them in JS if you prefer.
62259

63-
## Supports
260+
### Origin of the project name?
64261

65-
- [Next.js](https://nextjs.org/)
66-
- [Remix](https://remix.run/)
67-
- [React](https://react.dev/)
68-
- [Vue](https://vuejs.org)
69-
- [Svelte](https://svelte.dev/)
70-
- [Astro](https://astro.build/)
71-
- [Hono](https://hono.dev/)
72-
- [Tailwind CSS](https://tailwindcss.com/)
262+
Mist is inspired by atomized water 💧 often seen near waterfalls. A nod to the _Cascading_ in CSS 🌊.

docs/.gitignore

Lines changed: 0 additions & 21 deletions
This file was deleted.

docs/.vscode/extensions.json

Lines changed: 0 additions & 4 deletions
This file was deleted.

docs/.vscode/launch.json

Lines changed: 0 additions & 11 deletions
This file was deleted.

0 commit comments

Comments
 (0)