@duskmoon-dev/components 0.4.0 → 0.5.0
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 +84 -3
- package/dist/components/chat/Chat.types.d.ts +75 -1
- package/dist/components/chat/ChatComposer.d.ts +4 -0
- package/dist/components/chat/index.d.ts +1 -0
- package/dist/components/chat/index.js +1098 -25
- package/dist/components/dm-pro-table/index.js +12 -0
- package/dist/components/dm-query/index.js +12 -0
- package/dist/components/dm-search/index.js +12 -0
- package/dist/components/dm-table/index.js +12 -0
- package/dist/components/json-schema-form/JsonSchemaForm.d.ts +19 -0
- package/dist/components/json-schema-form/JsonSchemaWidget.d.ts +14 -0
- package/dist/components/json-schema-form/index.d.ts +8 -0
- package/dist/components/json-schema-form/index.js +7661 -0
- package/dist/components/json-schema-form/json-form-widgets.d.ts +26 -0
- package/dist/components/json-schema-form/json-schema-form.d.ts +50 -0
- package/dist/components/select/index.js +12 -0
- package/dist/generated/version.d.ts +1 -1
- package/dist/index.js +8105 -7665
- package/dist/infrastructure.js +1 -1
- package/dist/styles.css +312 -10
- package/package.json +9 -3
package/README.md
CHANGED
|
@@ -41,7 +41,7 @@ import { Button, DmTable, theme } from "@duskmoon-dev/components";
|
|
|
41
41
|
|
|
42
42
|
## Public Surface
|
|
43
43
|
|
|
44
|
-
-
|
|
44
|
+
- 79 standard components such as `Button`, `Chat`, `OtpInput`, `Swap`, `Fab`,
|
|
45
45
|
`Megamenu`, `ConsolePage`, `Table`, `Modal`, `Select`, and `Typography`.
|
|
46
46
|
- 21 DuskMoon workflow components such as `DmLayout`, `DmSearch`, `DmTable`,
|
|
47
47
|
`DmProTable`, and `DmToolbar`.
|
|
@@ -90,10 +90,14 @@ export function Conversation() {
|
|
|
90
90
|
<Chat.Bubble>The build passed.</Chat.Bubble>
|
|
91
91
|
<Chat.Status>
|
|
92
92
|
<Chat.StatusItem>Completed</Chat.StatusItem>
|
|
93
|
-
<Chat.StatusItem
|
|
93
|
+
<Chat.StatusItem>
|
|
94
|
+
<Chat.StatusValue>42</Chat.StatusValue> token/s
|
|
95
|
+
</Chat.StatusItem>
|
|
94
96
|
</Chat.Status>
|
|
95
97
|
<Chat.Actions hover>
|
|
96
|
-
<button type="button" onClick={copyReply}>
|
|
98
|
+
<button type="button" onClick={copyReply}>
|
|
99
|
+
Copy reply
|
|
100
|
+
</button>
|
|
97
101
|
</Chat.Actions>
|
|
98
102
|
</Chat>
|
|
99
103
|
</Chat.ScrollBody>
|
|
@@ -124,3 +128,80 @@ bun run typecheck
|
|
|
124
128
|
# Check parity manifest coverage
|
|
125
129
|
bun run parity:components
|
|
126
130
|
```
|
|
131
|
+
|
|
132
|
+
## JSON Schema forms
|
|
133
|
+
|
|
134
|
+
`@duskmoon-dev/components/json-schema-form` exports `JsonSchemaForm`,
|
|
135
|
+
`compileForm`, `JsonSchemaWidget`, and the `RenderableSchema`, `CompiledForm`,
|
|
136
|
+
`FormValue`, `JsonValue`, `FormErrors`, `FormValidationResult`,
|
|
137
|
+
`JsonSchemaFormProps`, `JsonSchemaWidgetProps`, and widget contract types.
|
|
138
|
+
Ajv and ajv-formats are installed as package runtime dependencies. The package
|
|
139
|
+
stylesheet includes the renderer layout. Import these APIs from the explicit
|
|
140
|
+
subpath; schema compilation is kept separate from the root component bundle.
|
|
141
|
+
|
|
142
|
+
```tsx
|
|
143
|
+
import { useState } from "react";
|
|
144
|
+
import "@duskmoon-dev/components/styles.css";
|
|
145
|
+
import {
|
|
146
|
+
JsonSchemaForm,
|
|
147
|
+
type FormErrors,
|
|
148
|
+
type FormValue,
|
|
149
|
+
type RenderableSchema,
|
|
150
|
+
} from "@duskmoon-dev/components/json-schema-form";
|
|
151
|
+
|
|
152
|
+
const schema: RenderableSchema = {
|
|
153
|
+
type: "object",
|
|
154
|
+
required: ["name"],
|
|
155
|
+
properties: {
|
|
156
|
+
name: { type: "string", title: "Name", minLength: 1 },
|
|
157
|
+
age: { type: "integer", title: "Age", minimum: 0 },
|
|
158
|
+
},
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
export function ProfileIsland({ send }: { send: (value: FormValue) => void }) {
|
|
162
|
+
const [value, setValue] = useState<FormValue>({ name: "Ada" });
|
|
163
|
+
const [errors, setErrors] = useState<FormErrors>({});
|
|
164
|
+
return (
|
|
165
|
+
<JsonSchemaForm
|
|
166
|
+
schema={schema}
|
|
167
|
+
value={value}
|
|
168
|
+
onChange={setValue}
|
|
169
|
+
errors={errors}
|
|
170
|
+
onErrorsChange={setErrors}
|
|
171
|
+
onSubmit={send}
|
|
172
|
+
/>
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Mount the React root inside a LiveView element with a stable `id` and
|
|
178
|
+
`phx-update="ignore"`. Parse the backend's schema JSON and call `compileForm`
|
|
179
|
+
when accepting untrusted input; catch compilation errors before rendering.
|
|
180
|
+
Pass the returned object as `compiled` instead of `schema` to compile once.
|
|
181
|
+
Send the validated object from `onSubmit` through the island's LiveView hook;
|
|
182
|
+
backend validation is still required. Use a new React `key` when replacing a
|
|
183
|
+
schema and starting a fresh form.
|
|
184
|
+
|
|
185
|
+
`value` and `onChange` control values. Omit `value` for internal state, optionally
|
|
186
|
+
seeded by `defaultValue`. Reset restores `defaultValue` or schema defaults,
|
|
187
|
+
notifies `onChange`, clears validation errors, and calls `onReset`. Backend
|
|
188
|
+
`errors` merge with local errors and use escaped JSON Pointer keys such as
|
|
189
|
+
`/address/email` (the empty key denotes a form error). Clear backend errors in
|
|
190
|
+
`onErrorsChange`, which receives an empty object on edits/reset and validation
|
|
191
|
+
errors on submission. `onSubmit` runs only for valid values and receives a
|
|
192
|
+
copied JSON object with numbers and booleans preserved.
|
|
193
|
+
|
|
194
|
+
The supported schema is a strict JSON Schema draft 2020-12 subset: object roots,
|
|
195
|
+
nested objects, homogeneous arrays, primitive fields/enums/defaults, required
|
|
196
|
+
fields, `additionalProperties: false`, string constraints/formats, numeric
|
|
197
|
+
constraints, and array/object size constraints. References, combinators,
|
|
198
|
+
nullable types, and arbitrary keywords are rejected. Validation does not coerce,
|
|
199
|
+
remove, or default submitted values.
|
|
200
|
+
|
|
201
|
+
Use `x-widget` for explicit component selection, `x-options` for typed option
|
|
202
|
+
labels/hierarchies, and `x-widget-options` for orientation, length, count,
|
|
203
|
+
allowHalf, min, max, and step where supported. `widgetNames`, `WidgetName`,
|
|
204
|
+
`WidgetOption`, `WidgetConfig`, and `OrientationWidgetConfig` expose this
|
|
205
|
+
contract; `compileForm` checks widget/type/config compatibility. Upload widgets
|
|
206
|
+
submit JSON file metadata (`name`, `size`, `type`, `lastModified`), with file
|
|
207
|
+
transfer owned by the application.
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { ComponentProps, ForwardRefExoticComponent, RefAttributes } from "react";
|
|
1
|
+
import type { ComponentProps, ForwardRefExoticComponent, RefAttributes, ReactNode } from "react";
|
|
2
|
+
import type { TextAreaProps } from "../input";
|
|
2
3
|
export type ChatPlacement = "start" | "end";
|
|
3
4
|
export type ChatTimeline = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24;
|
|
4
5
|
export type ChatBubbleColor = "primary" | "secondary" | "tertiary" | "accent" | "neutral" | "base" | "info" | "success" | "warning" | "error";
|
|
@@ -48,8 +49,81 @@ export type ChatToolStatusProps = ComponentProps<"span">;
|
|
|
48
49
|
export type ChatToolCallProps = ComponentProps<"div">;
|
|
49
50
|
export type ChatToolResultProps = ComponentProps<"div">;
|
|
50
51
|
export type ChatTypingProps = Omit<ComponentProps<"span">, "children">;
|
|
52
|
+
/** A snapshot of the controlled draft at submission time. */
|
|
53
|
+
export interface ChatComposerSubmission {
|
|
54
|
+
value: string;
|
|
55
|
+
files: File[];
|
|
56
|
+
}
|
|
57
|
+
export interface ChatComposerCompletion {
|
|
58
|
+
id: string;
|
|
59
|
+
label: string;
|
|
60
|
+
description?: ReactNode;
|
|
61
|
+
disabled?: boolean;
|
|
62
|
+
}
|
|
63
|
+
export interface ChatComposerCompletionContext {
|
|
64
|
+
value: string;
|
|
65
|
+
selectionStart: number;
|
|
66
|
+
selectionEnd: number;
|
|
67
|
+
}
|
|
68
|
+
/** The application supplies candidates and owns inserting the selected result. */
|
|
69
|
+
export interface ChatComposerCompletionConfig {
|
|
70
|
+
items: readonly ChatComposerCompletion[];
|
|
71
|
+
onSelect: (item: ChatComposerCompletion, context: ChatComposerCompletionContext) => void;
|
|
72
|
+
label?: string;
|
|
73
|
+
}
|
|
74
|
+
export interface ChatComposerActionContext {
|
|
75
|
+
submit: () => void;
|
|
76
|
+
submitting: boolean;
|
|
77
|
+
canSubmit: boolean;
|
|
78
|
+
disabled: boolean;
|
|
79
|
+
generating: boolean;
|
|
80
|
+
openAttachments: () => void;
|
|
81
|
+
}
|
|
82
|
+
export interface ChatComposerAttachmentContext {
|
|
83
|
+
remove: () => void;
|
|
84
|
+
disabled: boolean;
|
|
85
|
+
}
|
|
86
|
+
export interface ChatComposerProps extends Omit<ComponentProps<"div">, "children" | "onSubmit" | "onChange"> {
|
|
87
|
+
value: string;
|
|
88
|
+
onValueChange: (value: string) => void;
|
|
89
|
+
/** Return false to reject admission and retain the draft. */
|
|
90
|
+
onSubmit: (snapshot: ChatComposerSubmission) => boolean | void | Promise<boolean | void>;
|
|
91
|
+
attachments?: File[];
|
|
92
|
+
/** Enables the native file picker and attachment removal controls. */
|
|
93
|
+
onAttachmentsChange?: (files: File[]) => void;
|
|
94
|
+
accept?: string;
|
|
95
|
+
/** @default true */
|
|
96
|
+
multiple?: boolean;
|
|
97
|
+
/** Permit a draft containing only files. @default false */
|
|
98
|
+
allowAttachmentOnly?: boolean;
|
|
99
|
+
disabled?: boolean;
|
|
100
|
+
/** Gates submission while keeping the draft editable. */
|
|
101
|
+
busy?: boolean;
|
|
102
|
+
/** Shows Stop when onStop is supplied; does not prevent submission. */
|
|
103
|
+
generating?: boolean;
|
|
104
|
+
/** Application-controlled admission, including follow-ups. @default true */
|
|
105
|
+
canSubmit?: boolean;
|
|
106
|
+
onStop?: () => void;
|
|
107
|
+
error?: ReactNode;
|
|
108
|
+
onSubmitError?: (error: unknown) => void;
|
|
109
|
+
/** Clear unchanged admitted text and only admitted file entries. @default true */
|
|
110
|
+
clearOnSubmit?: boolean;
|
|
111
|
+
completion?: ChatComposerCompletionConfig;
|
|
112
|
+
/** @default 1 */
|
|
113
|
+
minRows?: number;
|
|
114
|
+
/** @default 6 */
|
|
115
|
+
maxRows?: number;
|
|
116
|
+
textareaProps?: Omit<TextAreaProps, "value" | "defaultValue" | "onChange" | "disabled" | "rows" | "autoSize" | "ref">;
|
|
117
|
+
attachLabel?: string;
|
|
118
|
+
sendLabel?: string;
|
|
119
|
+
stopLabel?: string;
|
|
120
|
+
renderAttachment?: (file: File, context: ChatComposerAttachmentContext) => ReactNode;
|
|
121
|
+
/** Extra application actions rendered alongside Attach, Stop, and Send. */
|
|
122
|
+
children?: ReactNode | ((context: ChatComposerActionContext) => ReactNode);
|
|
123
|
+
}
|
|
51
124
|
type ChatPartComponent<T extends HTMLElement, P> = ForwardRefExoticComponent<P & RefAttributes<T>>;
|
|
52
125
|
export type ChatComponent = ChatPartComponent<HTMLDivElement, ChatProps> & {
|
|
126
|
+
Composer: ChatPartComponent<HTMLDivElement, ChatComposerProps>;
|
|
53
127
|
Avatar: ChatPartComponent<HTMLDivElement, ChatAvatarProps>;
|
|
54
128
|
Header: ChatPartComponent<HTMLDivElement, ChatHeaderProps>;
|
|
55
129
|
Bubble: ChatPartComponent<HTMLDivElement, ChatBubbleProps>;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { ChatComposerProps } from "./Chat.types";
|
|
3
|
+
/** Controlled prompts, attachments, and application-supplied completions. */
|
|
4
|
+
export declare const ChatComposer: React.ForwardRefExoticComponent<Omit<ChatComposerProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
|