caspian-utils 0.0.19 → 0.0.20

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.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: Components
3
- description: Use this page when the task mentions `@component`, reusable UI, HTML-first `x-*` component tags, component imports, same-name `.html` templates, or where shared components belong in a Caspian project.
3
+ description: Use this page when the task mentions `@component`, reusable UI, HTML-first `x-*` component tags, component imports, same-name `.html` templates, `merge_classes(...)`, `twMerge(...)`, or where shared components belong in a Caspian project.
4
4
  related:
5
5
  title: Related docs
6
6
  description: Use the structure guide for file placement, the routing guide for route templates, the PulsePoint guide for browser-side scripts, and the data guide for component-owned RPC flows.
@@ -31,7 +31,7 @@ As the app grows, treat `src/components/` as the default home for reusable appli
31
31
 
32
32
  ## Basic Component
33
33
 
34
- This is the simplest pattern: accept props, merge classes or attributes, and return HTML.
34
+ This is the simplest pattern: accept props, assemble the final class value, and return HTML.
35
35
 
36
36
  ```python
37
37
  from casp.component_decorator import component
@@ -53,7 +53,44 @@ Notes:
53
53
 
54
54
  - `children` receives the inner content passed between opening and closing tags.
55
55
  - `**props` lets the component accept additional HTML attributes such as `id`, `data-*`, and `aria-*`.
56
- - The runtime normalizes `class`, `className`, and `class_name` into a merged `class` value before the component is called.
56
+ - The runtime normalizes `class`, `className`, and `class_name` into one `class` value before the component is called.
57
+ - Pass the `merge_classes(...)` result straight into `get_attributes(...)` or the rendered `class` attribute; do not wrap it in another helper.
58
+
59
+ ## Tailwind Merge Contract
60
+
61
+ When `caspian.config.json` has `tailwindcss: true`, Caspian uses a frontend-first Tailwind merge contract.
62
+
63
+ - In Python components, use `merge_classes(...)` to assemble class defaults plus incoming class props.
64
+ - `merge_classes(...)` emits a frontend-ready `{twMerge(...)}` expression instead of doing Python-side Tailwind conflict resolution.
65
+ - In authored PulsePoint markup and scripts, use global `twMerge(...)` directly for attribute expressions and script-local derived values.
66
+
67
+ Python example:
68
+
69
+ ```python
70
+ from casp.component_decorator import component
71
+ from casp.html_attrs import get_attributes, merge_classes
72
+
73
+ @component
74
+ def IconButton(**props) -> str:
75
+ incoming_class = props.pop("class", "")
76
+ final_class = merge_classes("size-4 rounded-md", incoming_class)
77
+
78
+ attributes = get_attributes({
79
+ "class": final_class,
80
+ }, props)
81
+
82
+ return f'<button {attributes}></button>'
83
+ ```
84
+
85
+ Authored PulsePoint examples:
86
+
87
+ ```html
88
+ <p class="{twMerge(baseClass, inputClass)}">Merged badge preview</p>
89
+
90
+ <script>
91
+ const merged = twMerge(baseClass, inputClass);
92
+ </script>
93
+ ```
57
94
 
58
95
  ## Import And Use Components
59
96
 
@@ -26,6 +26,7 @@ Before making feature, tooling, or file-placement decisions in a Caspian project
26
26
  When generating or editing a Caspian app, treat these as the default choices unless the task explicitly requires something else:
27
27
 
28
28
  - Use PulsePoint for reactive frontend behavior.
29
+ - When `caspian.config.json` has `tailwindcss: true`, use Python `merge_classes(...)` plus browser `twMerge(...)` as the only supported Tailwind class-merging path.
29
30
  - Use `@rpc()` plus `pp.rpc()` for browser-triggered reads, writes, streaming, and uploads.
30
31
  - Use `Validate` and `Rule` from `casp.validate` for server-side input validation and sanitization.
31
32
 
@@ -42,8 +43,8 @@ The packaged Caspian docs referenced by this index live here:
42
43
  - `mcp.md` - MCP-specific layout, launch flow, and AI routing rules for projects where `caspian.config.json` enables MCP
43
44
  - `database.md` - Prisma schema, migration, seed, and client-generation workflow for projects where `caspian.config.json` enables Prisma, plus Python-side helper caveats
44
45
  - `auth.md` - Session-backed authentication with `casp.auth`, centralized `auth_config.py`, public-vs-private route mode guidance, RPC-first signout guidance, RBAC, and OAuth provider helpers
45
- - `components.md` - Create reusable Python components, template-backed UI, HTML-first `x-*` component tags, and the single-parent root rule for component HTML files
46
- - `pulsepoint.md` - Default reactive frontend runtime contract for component scripts, state, effects, directives, and client-side behaviors
46
+ - `components.md` - Create reusable Python components, template-backed UI, HTML-first `x-*` component tags, the single-parent root rule for component HTML files, and the Python-side `merge_classes(...)` contract when Tailwind CSS is enabled
47
+ - `pulsepoint.md` - Default reactive frontend runtime contract for component scripts, state, effects, directives, client-side behaviors, and direct browser `twMerge(...)` usage when Tailwind CSS is enabled
47
48
  - `fetch-data.md` - Initial server-side data loading and browser-triggered RPC flows with `pp.rpc()`, streaming, uploads, and auth-aware actions
48
49
  - `file-uploads.md` - Route-local file uploads and file-manager flows with `@rpc()`, `pp.rpc()`, Prisma metadata, public asset storage, and BrowserSync ignore rules
49
50
  - `state.md` - Request-scoped server state with `StateManager`, session-backed JSON persistence, and listener callbacks for transient flows
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "caspian-utils",
3
- "version": "0.0.19",
3
+ "version": "0.0.20",
4
4
  "description": "Caspian tooling",
5
5
  "main": "index.js",
6
6
  "scripts": {