@jk2908/cxx 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +111 -0
  2. package/package.json +1 -1
package/README.md ADDED
@@ -0,0 +1,111 @@
1
+ # @jk2908/cxx
2
+
3
+ Build-time CSS template tag utilities for React 19.
4
+
5
+ ## Install
6
+
7
+ ```sh
8
+ npm install @jk2908/cxx lightningcss react react-dom
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```tsx
14
+ import { cxx } from '@jk2908/cxx'
15
+
16
+ const [css, styles, href] = cxx`
17
+ .header {
18
+ display: flex;
19
+ gap: 0.75rem;
20
+ }
21
+ `
22
+
23
+ export function Header() {
24
+ return (
25
+ <header className={styles.header}>
26
+ <style href={href} precedence="medium">
27
+ {css}
28
+ </style>
29
+ </header>
30
+ )
31
+ }
32
+ ```
33
+
34
+ The `cxx` tag is a build-time marker. Use the Vite plugin so the placeholders are replaced before runtime. String interpolation inside the template is not supported.
35
+
36
+ Named blocks can opt into generated class-key types:
37
+
38
+ ```tsx
39
+ import { cxx, type HeroClasses } from '@jk2908/cxx'
40
+
41
+ const [css, styles, href] = cxx.tag<HeroClasses>('hero')`
42
+ .hero {
43
+ display: flex;
44
+ }
45
+
46
+ .copy {
47
+ max-width: 60ch;
48
+ }
49
+ `
50
+
51
+ export function Hero() {
52
+ return (
53
+ <section className={styles.hero}>
54
+ <p className={styles.copy}>Type-safe class names.</p>
55
+ </section>
56
+ )
57
+ }
58
+
59
+ // `styles.coppy` is a type error
60
+ ```
61
+
62
+ The string passed to `cxx.tag(...)` is turned into the exported type name by appending `typeSuffix` and then normalising the whole result into Pascal Case. With the default suffix, `cxx.tag('hero')` becomes `HeroClasses`, and `cxx.tag('marketing-banner')` becomes `MarketingBannerClasses`. If `typeSuffix` is `false`, those become `Hero` and `MarketingBanner` instead.
63
+
64
+ Generated class-key types are imported from the root package, not a separate generated subpath.
65
+
66
+ Because `.cxx` is generated, it is recommended to add `.cxx` to your `.gitignore`.
67
+
68
+ ## Vite
69
+
70
+ ```ts
71
+ import { defineConfig } from 'vite'
72
+ import react from '@vitejs/plugin-react'
73
+ import cxx from '@jk2908/cxx/vite-plugin-cxx'
74
+
75
+ export default defineConfig({
76
+ plugins: [react(), cxx({ typeSuffix: 'Classes' })],
77
+ })
78
+ ```
79
+
80
+ The transform always emits minified CSS and CSS Modules class mappings.
81
+
82
+ `typeSuffix` controls the generated exported type name suffix. It defaults to `'Classes'`. Set it to `false` to omit the suffix.
83
+
84
+ ## Next
85
+
86
+ ```ts
87
+ import path from 'node:path'
88
+ import { fileURLToPath } from 'node:url'
89
+
90
+ import { withCxx } from '@jk2908/cxx/next'
91
+
92
+ const rootDir = path.dirname(fileURLToPath(import.meta.url))
93
+ const turbopackRoot = path.resolve(rootDir, '../..')
94
+
95
+ /** @type {import('next').NextConfig} */
96
+ const nextConfig = {
97
+ turbopack: {
98
+ root: turbopackRoot,
99
+ },
100
+ }
101
+
102
+ export default withCxx(nextConfig, { typeSuffix: 'Classes' })
103
+ ```
104
+
105
+ Use the Next integration when you want `cxx` transforms and generated class-key types inside a Next app. In a monorepo, set `turbopack.root` so the loader resolves the right workspace root.
106
+
107
+ See [CHANGELOG.md](./CHANGELOG.md) for release notes.
108
+
109
+ ## License
110
+
111
+ MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jk2908/cxx",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "type": "module",
5
5
  "author": "Jerome Kenway",
6
6
  "repository": {