本文へ移動
cccskills
無料GitHub で公開

jx

Use this skill for anything Jx — the Python/Jinja2 component library. Covers BOTH (a) library mechanics and integration AND (b) authoring production-ready UI components. Trigger this skill on any mention of Jx, `.jx` files, "Jinja components" in a Python web app context, or requests to build/create UI components for such an app.

インストール方法を見る

含まれるファイル(9)

  • SKILL.md6.0 KB
  • reference/assets.md4.6 KB
  • reference/attrs.md5.7 KB
  • reference/authoring.md9.0 KB
  • reference/catalog.md6.2 KB
  • reference/components.md5.0 KB
  • reference/frameworks.md7.2 KB
  • reference/patterns.md9.6 KB
  • reference/tools.md4.9 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Jx — Jinja2 component library

Jx is a Python package that lets you build server-rendered UIs from reusable component files (.jx). A Catalog loads components from one or more folders and renders them with explicit imports, typed props, an attrs pass-through, and a per-component CSS/JS asset system.

Mental model

Catalog("components/")  ──►  loads .jx files
       │
       ├── catalog.render("page.jx", **kwargs)  ──►  HTML string
       │       └── walks the imported component tree
       │           └── collects assets (CSS/JS) automatically
       │
       └── catalog.add_folder(path, prefix="ui")  ──►  more component sources

A component file has up to four parts (all optional except the template):

{#import "./icon.jx" as Icon #}     {# imports — PascalCase aliases #}
{#css card.css #}                    {# per-component assets #}
{#js card.js #}
{#def title, subtitle="" #}          {# typed props with defaults #}

<div {{ attrs.render(class="card") }}>
  <Icon name="star" />
  <h3>{{ title }}</h3>
  {{ content }}                      {# main slot #}
</div>

Quick reference

Install: uv add jx (or pip install jx).

Create a catalog:

from jx import Catalog
catalog = Catalog("components/", auto_reload=app.debug)
html = catalog.render("page.jx", user=user, title="Home")

Component file:

  • {#def name, count=0, items: list = [] #} — required props have no default; types are runtime-checked for primitives.
  • {#import "path.jx" as Name #} — alias must be PascalCase. Three flavors: absolute ("button.jx"), relative ("./sibling.jx"), prefixed ("@ui/button.jx").
  • {#css ... #} / {#js ... #} — comma-separated list of files (relative URLs, absolute paths, or full URLs).

Using a component: HTML-tag syntax, PascalCase, props with key="literal" or key={{ expr }}. Booleans support shorthand: <Input required /> is required={{ true }}.

attrs collects every attribute not declared in {#def}. Render onto the root element with {{ attrs.render(class="default") }} — class merges, other attrs override.

Slots for multiple content areas:

{% slot header %}default{% endslot %}   {# in component #}
{% fill header %}custom{% endfill %}    {# at call site #}

Assets are collected from the whole tree, deduplicated, in import order. Render with {{ assets.render() }} or split via assets.render_css() / assets.render_js(module=True, defer=True).

Validate: jx check myapp.setup:catalog (or path/to/file.py:catalog). Catches missing imports, used-but-not-imported tags, typos with "did you mean".

When to load which reference

The compact summary above is enough for many tasks. Pull a reference file when the user's question is squarely in that area — don't preload them.

If the user is asking about…Read
Building a UI component (button, card, modal, dropdown, form, table, layout, navigation, accordion, toast, etc.) — design choices, accessibility, native-HTML-first, color mode, when to use JS, the authoring checklistreference/authoring.md (always pair with reference/patterns.md if the user asks for a specific category we already have a recipe for)
Copy-paste recipes for buttons, modals (<dialog>), dropdowns (Popover API), form inputs, data tables, sidebar layoutsreference/patterns.md
Catalog options (jinja_env, extensions, filters, globals, asset_resolver), add_folder prefixes, render vs render_string, introspection (get_signature, list_components), collect_assetsreference/catalog.md
Component anatomy in depth, prop types and defaults, slot vs content vs prop tradeoffs, naming conventions, the dash-to-underscore rulereference/components.md
attrs.render / set / setdefault / add_class / prepend_class / remove_class, class merging rules, forwarding attrs to a child component, conditional attributesreference/attrs.md
Declaring CSS/JS, asset URL strategies (relative, absolute, build-tool), collection order, deduplication, asset_resolver for installable packagesreference/assets.md
Wiring Jx into Flask / Django / FastAPI / htmx, sharing a Jinja env, passing request, CSRF, URL helpers, partial responses for htmxreference/frameworks.md
Running jx check, JSON output, programmatic check_all, the VSCode extension (Go-to-Definition, diagnostics, snippets)reference/tools.md

Idioms worth remembering

  • Component classes first. When you call attrs.render(class="Card"), the component's own classes are emitted before anything the caller passed. Callers extend; they don't replace.
  • attrs is for HTML elements, not component tags. <Button attrs={{ attrs }} /> is the way to forward a parent's attrs into a child component — <Button {{ attrs.render() }} /> does NOT work because component tags are preprocessed.
  • Underscores in attribute names become dashes at render time: data_user_id → data-user-id, aria_label → aria-label, hx_get → hx-get. Useful for data-*, aria-*, htmx, Alpine, etc.
  • Boolean attrs: True renders the attribute name alone (disabled); False removes it entirely.
  • Auto-reload off in production. Catalog(auto_reload=False) skips the file-mtime check on every render.
  • _get_random_id(prefix) is a built-in global — useful for components that need stable-but-unique IDs (popovers, label-for, etc.) without forcing the caller to pass one.
  • Components are fragments. Don't emit <!DOCTYPE> / <html> / <body> from a leaf component — that belongs to a single layout.jx.

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

このスキルの問題を報告する