Skip to content
Skills Library
Programming · Building & coding

directives

/directives

Pre-built custom directives for json-render — formatting, math, string manipulation, and i18n. Use when working with @json-render/directives, defining custom directives with defineDirective, or adding $format, $math, $concat, $count, $truncate, $pluralize, $join, or $t to specs.

Repository
json-render ↗
Licence
Apache-2.0
Last repository change
23.10.2026

Assessment and security

100/ 100Class: good
Format25 / 25
Frontmatter with name and description, valid name, description up to 1,024 characters, name matching the folder.
Discoverability25 / 25
Description explains when to use the skill, has a reasonable length and uses third person.
Content35 / 35
At least 150 words and at most 500 lines, headings, step lists, examples or code.
Hygiene15 / 15
No placeholders such as TODO, no Windows paths, with a licence.
Riskno signals detected in the scan
Files in this package
1
Scripts
0
HTML comments
0
URLs in SKILL.md
0
Deprecation

No signals detected. Repository changed on 23.10.2026, without references to retired models or APIs.

Licence

Apache-2.0, otwarta: można używać i zmieniać, z zachowaniem licencji i informacji o zmianach.

What it does and when to use it

Pre-built custom directives for json-render — formatting, math, string manipulation, and i18n. Use when working with @json-render/directives, defining custom directives with defineDirective, or adding $format, $math, $concat, $count, $truncate, $pluralize, $join, or $t to specs.

Original author description

Pre-built custom directives for json-render — formatting, math, string manipulation, and i18n. Use when working with @json-render/directives, defining custom directives with defineDirective, or adding $format, $math, $concat, $count, $truncate, $pluralize, $join, or $t to specs.

How it works

  1. Quick Start
  2. Defining Custom Directives
  3. Built-in Directives
  4. Composition
  5. Wiring into Renderers
  6. Key Exports
Original SKILL.md headings · 202 lines, 792 words
SKILL.md preview
---
name: directives
description: Pre-built custom directives for json-render — formatting, math, string manipulation, and i18n. Use when working with @json-render/directives, defining custom directives with defineDirective, or adding $format, $math, $concat, $count, $truncate, $pluralize, $join, or $t to specs.
---

# @json-render/directives

Pre-built custom directives for `@json-render/core`. Drop them into your catalog and renderer to add formatting, math, string manipulation, and i18n.

## Quick Start

```typescript
import { standardDirectives } from '@json-render/directives';

// Wire into prompt generation
const prompt = catalog.prompt({ directives: standardDirectives });

// Wire into the renderer (React example)
import { JSONUIProvider, Renderer } from '@json-render/react';

<JSONUIProvider registry={registry} directives={standardDirectives}>
  <Renderer spec={spec} registry={registry} />
</JSONUIProvider>
```

To add factory directives like `createI18nDirective`, spread the array:

```typescript
import { standardDirectives, createI18nDirective } from '@json-render/directives';

const directives = [...standardDirectives, createI18nDirective(config)];
```

## Defining Custom Directives

Use `defineDirective` from `@json-render/core`:

```typescript
import { defineDirective, resolvePropValue } from '@json-render/core';
import { z } from 'zod';

const doubleDirective = defineDirective({
  name: '$double',
  description: 'Double a numeric value.',
  schema: z.object({
    $double: z.unknown(),
  }),
  resolve(value, ctx) {
    const resolved = resolvePropValue(value.$double, ctx);
    return (resolved as number) * 2;
  },
});
```

Rules:
- Name must start with `$`
- Name must not conflict with built-in keys (`$state`, `$cond`, `$computed`, `$template`, `$item`, `$index`, `$bindState`, `$bindItem`)
- Resolvers should call `resolvePropValue` on sub-values to support composition

## Built-in Directives

### `$format` — Locale-aware value formatting

Formats values using `Intl` formatters. Supports `date`, `currency`, `number`, and `percent`.

```json
{ "$format": "currency", "value": { "$state": "/cart/total" }, "currency": "USD" }
{ "$format": "date", "value": { "$state": "/user/createdAt" } }
{ "$format": "number", "value": 1234567, "notation": "compact" }
{ "$format": "percent", "value": 0.75 }
{ "$format": "date", "value": { "$state": "/post/createdAt" }, "style": "relative" }
```

Fields: `$format` (date | currency | number | percent), `value` (any expression), `locale?` (string), `currency?` (string, default "USD"), `notation?` (string), `style?` ("relative" for relative dates), `options?` (extra Intl options).

### `$math` — Arithmetic operations

```json
{ "$math": "add", "a": { "$state": "/subtotal" }, "b": { "$state": "/tax" } }
{ "$math": "round", "a": 3.7 }
```

Operations: `add`, `subtract`, `multiply`, `divide`, `mod`, `min`, `max`, `round`, `floor`, `ceil`, `abs`. Unary ops (`round`, `floor`, `ceil`, `abs`) only use `a`. Division by zero returns `0`.

Fields: `$math` (operation enum), `a?` (first operand, default 0), `b?` (second operand, default 0).

### `$concat` — String concatenation

```json
{ "$concat": [{ "$state": "/user/firstName" }, " ", { "$state": "/user/lastName" }] }
```

Fields: `$concat` (array of values to resolve and join into a string).

### `$count` — Array/string length

```json
{ "$count": { "$state": "/cart/items" } }
```

Returns `.length` of arrays or strings, `0` for other types.

Fields: `$count` (value to count).

### `$truncate` — Text truncation

```json
{ "$truncate": { "$state": "/post/body" }, "length": 140, "suffix": "..." }
```

Fields: `$truncate` (value to truncate), `length?` (max chars, default 100), `suffix?` (string, default "...").

### `$pluralize` — Singular/plural forms

```json
{ "$pluralize": { "$state": "/cart/itemCount" }, "one": "item", "other": "items", "zero": "no items" }
```

Output: `"3 items"`, `"1 item"`, or `"no items"`.

Fields: `$pluralize` (count value), `one` (singular label), `other` (plural label), `zero?` (zero label).

### `$join` — Join array elements

```json
{ "$join": { "$state": "/tags" }, "separator": ", " }
```

Fields: `$join` (array to join), `separator?` (string, default ", ").

### `createI18nDirective` — Internationalization factory

```typescript
import { createI18nDirective } from '@json-render/directives';

const tDirective = createI18nDirective({
  locale: 'en',
  messages: {
    en: { "greeting": "Hello, {{name}}!", "checkout.submit": "Place Order" },
    es: { "greeting": "Hola, {{name}}!", "checkout.submit": "Realizar Pedido" },
  },
  fallbackLocale: 'en',
});
```

Usage in specs:

```json
{ "$t": "checkout.submit" }
{ "$t": "greeting", "params": { "name": { "$state": "/user/name" } } }
```

Fields: `$t` (translation key), `params?` (interpolation parameters, values accept expressions).

Config: `locale` (current locale), `messages` (Record<locale, Record<key, string>>), `fallbackLocale?` (fallback when key missing).

## Composition

Directives compose naturally — each resolver calls `resolvePropValue` on its inputs, so directives can wrap other directives or built-in expressions:

```json
{
  "$format": "currency",
  "value": { "$math": "multiply", "a": { "$state": "/price" }, "b": { "$state": "/qty" } },
  "currency": "USD"
}
```

Resolves inside-out: `$state` reads from state, `$math` multiplies, `$format` formats as currency.

## Wiring into Renderers

All four renderers (React, Vue, Svelte, Solid) accept `directives` on their provider and `createRenderer` output:

```tsx
// Provider pattern
<JSONUIProvider registry={registry} directives={directives}>
  <Renderer spec={spec} registry={registry} />
</JSONUIProvider>

// createRenderer pattern
const MyRenderer = createRenderer(catalog, components);
<MyRenderer spec={spec} directives={directives} />
```

For prompt generation, pass the same array:

```typescript
const prompt = catalog.prompt({ directives });
```

## Key Exports

| Export | Purpose |
|--------|---------|
| `formatDirective` | `$format` directive definition |
| `mathDirective` | `$math` directive definition |
| `concatDirective` | `$concat` directive definition |
| `countDirective` | `$count` directive definition |
| `truncateDirective` | `$truncate` directive definition |
| `pluralizeDirective` | `$pluralize` directive definition |
| `joinDirective` | `$join` directive definition |
| `createI18nDirective` | Factory for `$t` i18n directive |
| `standardDirectives` | Array of all 7 non-factory directives |
| `I18nConfig` | Type for i18n configuration |

Versions

The database has no other skills named directives.

Database snapshot: 13.11.2026 · package version e5fa238c0bac (SHA-256 digest of the entire package)

Downloads in the last 30 days: 0 · ranking

Report a problem with this skill: harmful content, incorrect descriptions or an author’s removal request.

Similar skills

  • 100angular-directives-pipes
    Build custom Angular attribute directives, HostDirectives, and pure pipes. Use for Angular directive or pipe implementation, including custom attribute directives; defer React/CSS middleware and unrelated framework work.
  • 95vue
    Vue 3 renderer for json-render. Use when building Vue UIs from JSON specs, working with @json-render/vue, defining Vue component registries, or rendering AI-generated specs in Vue.
  • 95codegen
    Code generation utilities for json-render. Use when generating code from UI specs, building custom code exporters, traversing specs, or serializing props for @json-render/codegen.
  • 100directives-audit
    Audit or explicitly housekeep agent directives for authority, scope, safety, density, routing, drift, and consumed parity. Trigger on /directives-audit or "boil my directives". Not for skills or prose.
  • 90use-dart-helper-utils
    Use when writing or reviewing Dart/Flutter code that uses the dart_helper_utils package - deep map utilities (flatMap, unflatten, getPath, setPath, deepMerge), string casing/slugify/masking/parseDuration/truncate, MIME filename checks, iterable…
  • 95guarding-agent-directives
    Reviews agent directives for necessity, clarity, scope, and authority. Use when adding, revising, or auditing rules in AGENTS.md, CLAUDE.md, or referenced instruction files.

Feedback and reports

Your message goes to Bartosz Sokoliński. An email address is needed only for a reply. See the privacy policy.