@djangocfg/ui-tools 2.1.402 → 2.1.404
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.
- package/README.md +14 -0
- package/package.json +6 -6
- package/src/tools/JsonForm/JsonSchemaForm.tsx +3 -1
- package/src/tools/JsonForm/README.md +12 -2
- package/src/tools/JsonForm/widgets/TextareaWidget.tsx +25 -0
- package/src/tools/JsonForm/widgets/index.ts +1 -0
- package/src/tools/JsonTree/README.md +12 -0
- package/src/tools/PrettyCode/README.md +81 -0
package/README.md
CHANGED
|
@@ -79,9 +79,21 @@ Subpaths come in three flavors:
|
|
|
79
79
|
| `@djangocfg/ui-tools/map` | `LazyMapContainer`, `LazyMapView`, plus light primitives (`MapMarker`, `MapPopup`, `MapCluster`, `MapSource`, `MapLayer`, `MapControls`, `MapProvider`, types) | The heavy MapLibre GL chunk (~800 KB) only loads when `LazyMapContainer` actually mounts. Markers and popups are thin `react-map-gl` wrappers — exported synchronously. |
|
|
80
80
|
| `@djangocfg/ui-tools/markdown-message` | `MarkdownMessage`, `ChatMessageRow`, `ActionRow`, `extractTextFromChildren`, types | **SSR-safe.** The component itself is `'use client'`, but rendering produces plain HTML — Next.js will pre-render it on the server when imported from a Client Component. Use this when you want the markdown renderer without dragging in the full chat. |
|
|
81
81
|
| `@djangocfg/ui-tools/<tool-name>` | One tool | `mermaid`, `speech-recognition`, `json-tree`, `pretty-code`, `openapi-viewer`, `json-form`, `lottie-player`, `video-player`, `image-viewer`, `cron-scheduler`, `gallery`, `tour`, `tree`, `file-icon`, `upload` |
|
|
82
|
+
| `@djangocfg/ui-tools/json-form/full` | `JsonSchemaForm`, `ObjectFieldTemplate`, `evaluateDisabledWhen`, all widgets / templates / utils | Eager bundle. Use only for storybook / internal tooling that needs the template + util APIs at module scope. Production code should import `LazyJsonSchemaForm` from `/json-form` instead. |
|
|
82
83
|
| `@djangocfg/ui-tools/styles` | Tailwind source CSS | |
|
|
83
84
|
| `@djangocfg/ui-tools/dist.css` | Pre-compiled CSS | |
|
|
84
85
|
|
|
86
|
+
### Code & data inspectors are always-dark by design
|
|
87
|
+
|
|
88
|
+
`PrettyCode` and `JsonTree` render on a fixed dark surface (`#0d1117`)
|
|
89
|
+
regardless of the host UI theme. Same convention as GitHub, VSCode,
|
|
90
|
+
ChatGPT, Chrome DevTools. Syntax highlighting / typed-value coloring
|
|
91
|
+
ship their own contrast model — mixing them with light UI surfaces
|
|
92
|
+
flattens everything into low-contrast pastels.
|
|
93
|
+
|
|
94
|
+
The chrome (border, padding, toolbars) still uses semantic UI tokens.
|
|
95
|
+
Only the *content surface* is fixed. See per-tool READMEs for details.
|
|
96
|
+
|
|
85
97
|
---
|
|
86
98
|
|
|
87
99
|
## Lazy loading
|
|
@@ -146,6 +158,8 @@ function Chat() {
|
|
|
146
158
|
|
|
147
159
|
**What's wired by default:** desktop side-mode toggle (auto-hides on narrow screens), persisted dock prefs, two-step Escape, click-to-focus composer, mobile fullscreen with `dvh` heights, push-preview bubble for inbound messages while closed, **ChatGPT-style autoscroll** (sticky-to-bottom within 120 px, every user-send re-anchors the viewport), **bundled chat notification sounds** (sent/received/start/error/mention/notification, ~136KB inlined as `data:`-URLs inside the lazy chat chunk — zero host setup). Native hosts (cmdop_go / Tauri) pass `audio={{ silenced: true, onSoundEvent }}` to keep web silent while routing triggers to the backend.
|
|
148
160
|
|
|
161
|
+
Need a fully custom input row (e.g. mention autocomplete via `MarkdownEditor`)? Pass `renderComposer={({ composer }) => <YourComposer composer={composer} />}` to `<ChatRoot>` — it replaces the default `<Composer>` while keeping autoscroll, JumpToLatest, and history behaviour. Story: `UI Tools / Chat / Mentions / Machine Mentions`.
|
|
162
|
+
|
|
149
163
|
Drop `<VoiceComposerSlot />` from `@djangocfg/ui-tools/speech-recognition` into `composerToolbarEnd` for live mic-to-text — **zero props**, reads / writes the composer through `ComposerHandle` registered in chat context. Set `headerSlots={{ languagePicker: true }}` on `<ChatLauncher>` for a flag-button language picker (66 BCP-47 tags). Both auto-hide on Firefox / in-app browsers / missing `getUserMedia`. See [`SpeechRecognition`](#speech-recognition--quick-start) below.
|
|
150
164
|
|
|
151
165
|
Full docs: [`Chat/README.md`](src/tools/Chat/README.md). Stories: `Tools/Chat/{Basic,Bubbles,ToolCalls,Personas,Launcher,Header,Audio & Actions,Voice composer}`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@djangocfg/ui-tools",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.404",
|
|
4
4
|
"description": "Heavy React tools with lazy loading - for Electron, Vite, CRA, Next.js apps",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ui-tools",
|
|
@@ -159,8 +159,8 @@
|
|
|
159
159
|
"test:watch": "vitest"
|
|
160
160
|
},
|
|
161
161
|
"peerDependencies": {
|
|
162
|
-
"@djangocfg/i18n": "^2.1.
|
|
163
|
-
"@djangocfg/ui-core": "^2.1.
|
|
162
|
+
"@djangocfg/i18n": "^2.1.404",
|
|
163
|
+
"@djangocfg/ui-core": "^2.1.404",
|
|
164
164
|
"consola": "^3.4.2",
|
|
165
165
|
"lodash-es": "^4.18.1",
|
|
166
166
|
"lucide-react": "^0.545.0",
|
|
@@ -214,9 +214,9 @@
|
|
|
214
214
|
"material-file-icons": "^2.4.0"
|
|
215
215
|
},
|
|
216
216
|
"devDependencies": {
|
|
217
|
-
"@djangocfg/i18n": "^2.1.
|
|
218
|
-
"@djangocfg/typescript-config": "^2.1.
|
|
219
|
-
"@djangocfg/ui-core": "^2.1.
|
|
217
|
+
"@djangocfg/i18n": "^2.1.404",
|
|
218
|
+
"@djangocfg/typescript-config": "^2.1.404",
|
|
219
|
+
"@djangocfg/ui-core": "^2.1.404",
|
|
220
220
|
"@types/lodash-es": "^4.17.12",
|
|
221
221
|
"@types/mapbox__mapbox-gl-draw": "^1.4.8",
|
|
222
222
|
"@types/node": "^24.7.2",
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
import { JsonFormContext, JsonSchemaFormProps } from './types';
|
|
18
18
|
import { normalizeFormData, validateSchema } from './utils';
|
|
19
19
|
import {
|
|
20
|
-
CheckboxWidget, ColorWidget, NumberWidget, SelectWidget, SliderWidget, SwitchWidget, TextWidget
|
|
20
|
+
CheckboxWidget, ColorWidget, NumberWidget, SelectWidget, SliderWidget, SwitchWidget, TextareaWidget, TextWidget
|
|
21
21
|
} from './widgets';
|
|
22
22
|
|
|
23
23
|
/**
|
|
@@ -104,6 +104,7 @@ export function JsonSchemaForm<T = any>(props: JsonSchemaFormProps<T>) {
|
|
|
104
104
|
const widgets: RegistryWidgetsType = useMemo(() => ({
|
|
105
105
|
// Standard widget names (PascalCase) - used by RJSF internally
|
|
106
106
|
TextWidget,
|
|
107
|
+
TextareaWidget,
|
|
107
108
|
NumberWidget,
|
|
108
109
|
CheckboxWidget,
|
|
109
110
|
SelectWidget,
|
|
@@ -112,6 +113,7 @@ export function JsonSchemaForm<T = any>(props: JsonSchemaFormProps<T>) {
|
|
|
112
113
|
SliderWidget,
|
|
113
114
|
// Lowercase aliases - for uiSchema 'ui:widget' references
|
|
114
115
|
text: TextWidget,
|
|
116
|
+
textarea: TextareaWidget,
|
|
115
117
|
number: NumberWidget,
|
|
116
118
|
checkbox: CheckboxWidget,
|
|
117
119
|
select: SelectWidget,
|
|
@@ -3,10 +3,20 @@
|
|
|
3
3
|
Schema-driven forms on top of [react-jsonschema-form](https://github.com/rjsf-team/react-jsonschema-form) (RJSF) with `@djangocfg/ui` widgets, AJV8 validation, and a few custom extensions for compact playground-style UIs.
|
|
4
4
|
|
|
5
5
|
```tsx
|
|
6
|
-
|
|
7
|
-
//
|
|
6
|
+
// Lazy entry — what production code should import. Ships only the
|
|
7
|
+
// component reference + a Suspense fallback; the ~300KB RJSF bundle
|
|
8
|
+
// loads on first mount.
|
|
8
9
|
import { LazyJsonSchemaForm } from '@djangocfg/ui-tools/json-form';
|
|
9
10
|
|
|
11
|
+
// Full entry — eager bundle. Use only for storybook / internal
|
|
12
|
+
// tooling that needs templates, widgets, or `evaluateDisabledWhen`
|
|
13
|
+
// at module scope. Pulls RJSF synchronously, no code-splitting.
|
|
14
|
+
import {
|
|
15
|
+
JsonSchemaForm,
|
|
16
|
+
ObjectFieldTemplate,
|
|
17
|
+
evaluateDisabledWhen,
|
|
18
|
+
} from '@djangocfg/ui-tools/json-form/full';
|
|
19
|
+
|
|
10
20
|
const schema = {
|
|
11
21
|
type: 'object',
|
|
12
22
|
properties: {
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import React from 'react';
|
|
4
|
+
|
|
5
|
+
import type { WidgetProps } from '@rjsf/utils';
|
|
6
|
+
|
|
7
|
+
import { TextWidget } from './TextWidget';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Multiline text widget for JSON Schema Form. Thin wrapper around
|
|
11
|
+
* `TextWidget` that pins `options.widget = 'textarea'` so the
|
|
12
|
+
* underlying renderer reaches the `<textarea>` branch.
|
|
13
|
+
*
|
|
14
|
+
* Registered under the `textarea` ui:widget alias — schemas can opt
|
|
15
|
+
* into multiline editing without setting `ui:options.widget`:
|
|
16
|
+
*
|
|
17
|
+
* uiSchema = { description: { 'ui:widget': 'textarea' } }
|
|
18
|
+
*
|
|
19
|
+
* Honors all the same `ui:options` as `TextWidget` — most usefully
|
|
20
|
+
* `rows` (default `3`).
|
|
21
|
+
*/
|
|
22
|
+
export function TextareaWidget(props: WidgetProps) {
|
|
23
|
+
const options = { ...(props.options ?? {}), widget: 'textarea' };
|
|
24
|
+
return <TextWidget {...props} options={options} />;
|
|
25
|
+
}
|
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
Interactive JSON tree viewer with expand/collapse, copy, and download.
|
|
4
4
|
|
|
5
|
+
## Why dark by default
|
|
6
|
+
|
|
7
|
+
JsonTree renders on a fixed dark surface (`#0d1117`) regardless of
|
|
8
|
+
the host UI theme — same convention as Chrome DevTools, Insomnia,
|
|
9
|
+
Bruno, Postman. JSON inspectors carry their own data-typed palette
|
|
10
|
+
(blue keys, green strings, orange numbers, red null) tuned for dark
|
|
11
|
+
backgrounds; mixing it with light UI tokens flattens values into
|
|
12
|
+
unreadable pastels.
|
|
13
|
+
|
|
14
|
+
The palette is intentionally **not** a semantic token. See PrettyCode
|
|
15
|
+
README for the same rationale.
|
|
16
|
+
|
|
5
17
|
## Structure
|
|
6
18
|
|
|
7
19
|
```
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# PrettyCode
|
|
2
|
+
|
|
3
|
+
Syntax-highlighted code block. Prism-powered, dark-by-default surface.
|
|
4
|
+
|
|
5
|
+
## Why dark by default
|
|
6
|
+
|
|
7
|
+
PrettyCode renders on a fixed dark surface (`#0d1117` + `vsDark` palette)
|
|
8
|
+
regardless of the host theme — the same convention as GitHub, VSCode,
|
|
9
|
+
ChatGPT, Slack. Syntax highlighting ships its own contrast model
|
|
10
|
+
(keyword / string / number / comment) that flattens to low-contrast
|
|
11
|
+
pastels when forced onto a light UI surface.
|
|
12
|
+
|
|
13
|
+
The surface is intentionally **not** a semantic token. Semantic tokens
|
|
14
|
+
(`--primary`, `--accent`, `--card`) describe UI affordances; code
|
|
15
|
+
display is data, not UI.
|
|
16
|
+
|
|
17
|
+
## Structure
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
PrettyCode/
|
|
21
|
+
├── PrettyCode.client.tsx # Main component (Highlight + dark surface)
|
|
22
|
+
├── registerPrismLanguages.ts # Lazy-load extra grammars (bash, ruby, java, php)
|
|
23
|
+
├── index.tsx # Public re-export
|
|
24
|
+
└── lazy.tsx # Lazy-loaded export
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Usage
|
|
28
|
+
|
|
29
|
+
```tsx
|
|
30
|
+
import { PrettyCode } from '@djangocfg/ui-tools/code';
|
|
31
|
+
|
|
32
|
+
<PrettyCode data={sourceCode} language="typescript" />
|
|
33
|
+
|
|
34
|
+
// Inline snippet (used in markdown rendering)
|
|
35
|
+
<PrettyCode data={`const x = 1`} language="ts" inline />
|
|
36
|
+
|
|
37
|
+
// Capped at 50 visible lines, scrolls if longer
|
|
38
|
+
<PrettyCode data={longBlob} language="json" maxLines={50} />
|
|
39
|
+
|
|
40
|
+
// Chrome-less variant — embed inside another scroll container
|
|
41
|
+
<PrettyCode data={src} language="bash" variant="plain" />
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Props
|
|
45
|
+
|
|
46
|
+
| Prop | Type | Default | Description |
|
|
47
|
+
|------|------|---------|-------------|
|
|
48
|
+
| `data` | `string \| object` | — | Code string. Objects are `JSON.stringify`d. |
|
|
49
|
+
| `language` | `Language` | — | Prism language id. Unknown → plain text. |
|
|
50
|
+
| `mode` | `'dark' \| 'light'` | `'dark'` | Palette override. Default is always dark (see "Why dark"). |
|
|
51
|
+
| `inline` | `boolean` | `false` | Render as inline `<code>` (no card / toolbar). |
|
|
52
|
+
| `variant` | `'card' \| 'plain'` | `'card'` | `plain` strips border, background, and toolbar. |
|
|
53
|
+
| `isCompact` | `boolean` | `false` | 12px font instead of 14px. |
|
|
54
|
+
| `maxLines` | `number` | `undefined` | When set, block scrolls past this many lines. |
|
|
55
|
+
| `customBg` | `string` | — | Tailwind class to override the dark surface. |
|
|
56
|
+
| `scrollIsolation` | `boolean` | `true` | Block scroll capture until clicked (long snippets). |
|
|
57
|
+
| `className` | `string` | — | Extra classes on the wrapper. |
|
|
58
|
+
|
|
59
|
+
## When to override `mode`
|
|
60
|
+
|
|
61
|
+
Almost never. The dark default is correct for ~all cases. Pass
|
|
62
|
+
`mode="light"` only for deliberate light-on-light renders (e.g. PDF
|
|
63
|
+
export targeting a printed page). The surface falls back to
|
|
64
|
+
`bg-card` semantic token in that mode.
|
|
65
|
+
|
|
66
|
+
## Supported languages
|
|
67
|
+
|
|
68
|
+
Out of the box: `javascript`, `typescript`, `python`, `json`, `css`,
|
|
69
|
+
`markup` (html/xml), `sql`, `yaml`, `markdown`, `go`.
|
|
70
|
+
|
|
71
|
+
Lazy-loaded on first use: `bash`/`shell`, `ruby`, `java`, `php`.
|
|
72
|
+
Lazy load is tracked through `useEnsurePrismLanguages()` — the
|
|
73
|
+
component re-renders once the grammar resolves.
|
|
74
|
+
|
|
75
|
+
Unknown languages fall back to plain text (no highlighting, no error).
|
|
76
|
+
|
|
77
|
+
## Storybook
|
|
78
|
+
|
|
79
|
+
`UI Tools / Code / PrettyCode` — `Playground`, `TypeScript`, `Json`,
|
|
80
|
+
`Python`, `Bash`, `Sql`, `Yaml`, `LongFileWithScroll`, `Inline`,
|
|
81
|
+
`Compact`, `LightMode`, `PlainVariant`.
|