@navette-js/forms 0.0.0-stage → 1.0.0-beta.2
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/LICENSE +21 -0
- package/README.md +8 -2
- package/lib/builder.d.ts +128 -0
- package/lib/builder.js +306 -0
- package/lib/index.d.ts +866 -0
- package/lib/index.js +1947 -0
- package/package.json +61 -4
- package/views/asset.ejs +1 -0
- package/views/components/field-wrapper.ejs +39 -0
- package/views/components/rich-editor.ejs +471 -0
- package/views/components/text-input.ejs +32 -0
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,866 @@
|
|
|
1
|
+
import { HtmlString, type ColorManager, type Lazy } from '@navette-js/support';
|
|
2
|
+
import { Component, Schema, type ComponentContext } from '@navette-js/schemas';
|
|
3
|
+
import { Action } from '@navette-js/actions';
|
|
4
|
+
export declare const useColorManager: (manager: ColorManager) => void;
|
|
5
|
+
type Rule = {
|
|
6
|
+
name: string;
|
|
7
|
+
passes: (value: unknown, ctx: ComponentContext) => boolean | Promise<boolean>;
|
|
8
|
+
message: (attribute: string) => string;
|
|
9
|
+
};
|
|
10
|
+
export declare abstract class Field extends Component {
|
|
11
|
+
protected _label: Lazy<string | null, ComponentContext>;
|
|
12
|
+
protected _required: Lazy<boolean, ComponentContext>;
|
|
13
|
+
protected _disabled: Lazy<boolean, ComponentContext>;
|
|
14
|
+
protected _autofocus: boolean;
|
|
15
|
+
protected _default: unknown;
|
|
16
|
+
protected _rules: Rule[];
|
|
17
|
+
protected _afterStateUpdated: ((ctx: ComponentContext & {
|
|
18
|
+
set: (name: string, value: unknown) => void;
|
|
19
|
+
}) => unknown) | null;
|
|
20
|
+
protected _dehydrated: boolean | null;
|
|
21
|
+
protected _hiddenLabel: boolean;
|
|
22
|
+
protected _helperText: string | null;
|
|
23
|
+
constructor(name: string);
|
|
24
|
+
hasStatePath(): boolean;
|
|
25
|
+
getName(): string;
|
|
26
|
+
getId(): string;
|
|
27
|
+
label(label: Lazy<string | null, ComponentContext>): this;
|
|
28
|
+
required(condition?: Lazy<boolean, ComponentContext>): this;
|
|
29
|
+
disabled(condition?: Lazy<boolean, ComponentContext>): this;
|
|
30
|
+
autofocus(condition?: boolean): this;
|
|
31
|
+
default(value: unknown): this;
|
|
32
|
+
/** Helper text shown under the field. */
|
|
33
|
+
helperText(text: string | null): this;
|
|
34
|
+
/** Helper text id, linked to the control through `aria-describedby`. */
|
|
35
|
+
protected getHelperTextId(): string | null;
|
|
36
|
+
/** Keeps the label for screen readers only. */
|
|
37
|
+
hiddenLabel(condition?: boolean): this;
|
|
38
|
+
protected _hint: Lazy<string | HtmlString | null, ComponentContext>;
|
|
39
|
+
protected _hintColor: Lazy<string | null, ComponentContext>;
|
|
40
|
+
protected _hintIcon: Lazy<string | null, ComponentContext>;
|
|
41
|
+
protected _hintIconTooltip: Lazy<string | null, ComponentContext>;
|
|
42
|
+
protected _hintActions: Action[];
|
|
43
|
+
/**
|
|
44
|
+
* Hint shown to the right of the label (a `Text` component). The text is escaped; an `HtmlString` from `@navette-js/support`
|
|
45
|
+
* (`raw('<a href="…">…</a>')`) is inserted as is, so only put values escaped with `e()` in it.
|
|
46
|
+
*/
|
|
47
|
+
hint(hint: Lazy<string | HtmlString | null, ComponentContext>): this;
|
|
48
|
+
/** Color of the hint and its icon (by default `gray` for the text, `primary` for the icon). */
|
|
49
|
+
hintColor(color: Lazy<string | null, ComponentContext>): this;
|
|
50
|
+
/** Hint icon, with an optional tooltip (also used as its accessible name). */
|
|
51
|
+
hintIcon(name: Lazy<string | null, ComponentContext>, tooltip?: Lazy<string | null, ComponentContext>): this;
|
|
52
|
+
hintIconTooltip(tooltip: Lazy<string | null, ComponentContext>): this;
|
|
53
|
+
/** Action shown after the hint (small link), mounted on the field. */
|
|
54
|
+
hintAction(action: Action): this;
|
|
55
|
+
hintActions(actions: Action[]): this;
|
|
56
|
+
getHintActions(): Action[];
|
|
57
|
+
/** Actions the field exposes for mounting (`schemaComponent` = field key): its hint actions. */
|
|
58
|
+
getActions(): Action[];
|
|
59
|
+
/** Row after the label: hint, hint icon and hint actions. */
|
|
60
|
+
protected renderAfterLabel(): Promise<string>;
|
|
61
|
+
/** Runs on the server when the field state changes (`live()` field). `set(name, value)` changes another field of the same form. */
|
|
62
|
+
afterStateUpdated(callback: (ctx: ComponentContext & {
|
|
63
|
+
set: (name: string, value: unknown) => void;
|
|
64
|
+
}) => unknown): this;
|
|
65
|
+
hasAfterStateUpdated(): boolean;
|
|
66
|
+
callAfterStateUpdated(set: (name: string, value: unknown) => void): Promise<void>;
|
|
67
|
+
/** Forces the field into the submitted data, even when disabled (`.disabled().dehydrated()`). */
|
|
68
|
+
dehydrated(condition?: boolean): this;
|
|
69
|
+
/** By default, a disabled field is neither validated nor saved. */
|
|
70
|
+
isDehydrated(): Promise<boolean>;
|
|
71
|
+
getDefaultState(): unknown;
|
|
72
|
+
/** Shapes a record value as it enters the form (hydration). */
|
|
73
|
+
hydrateState(value: unknown): unknown;
|
|
74
|
+
rule(rule: Rule): this;
|
|
75
|
+
/** `unique` rule: the value must not exist in the column of the same name; `ignoreRecord` excludes the record being edited. */
|
|
76
|
+
unique(options?: {
|
|
77
|
+
ignoreRecord?: boolean;
|
|
78
|
+
column?: string;
|
|
79
|
+
}): this;
|
|
80
|
+
getLabel(): Promise<string>;
|
|
81
|
+
isRequired(): Promise<boolean>;
|
|
82
|
+
isDisabled(): Promise<boolean>;
|
|
83
|
+
getErrors(): string[];
|
|
84
|
+
hasError(): boolean;
|
|
85
|
+
/** Validation rules: `required` first, then the field's own. */
|
|
86
|
+
getValidationRules(): Promise<Rule[]>;
|
|
87
|
+
validate(): Promise<string[]>;
|
|
88
|
+
/** Value written to the data to save (composite fields only leave a skeleton, filled by their children). */
|
|
89
|
+
dehydrateState(state: unknown): unknown;
|
|
90
|
+
/** Final shaping of the saved value, once child fields are dehydrated (e.g. a Builder's item list). */
|
|
91
|
+
finalizeDehydratedState(state: unknown): unknown;
|
|
92
|
+
protected wrap(html: string, options?: {
|
|
93
|
+
labelPrefix?: string;
|
|
94
|
+
wrapperClass?: string;
|
|
95
|
+
after?: string;
|
|
96
|
+
labelAsDiv?: boolean;
|
|
97
|
+
focusable?: boolean;
|
|
98
|
+
}): Promise<string>;
|
|
99
|
+
}
|
|
100
|
+
export declare class TextInput extends Field {
|
|
101
|
+
private _type;
|
|
102
|
+
private _isPassword;
|
|
103
|
+
private _isRevealable;
|
|
104
|
+
private _autocomplete;
|
|
105
|
+
private _maxLength;
|
|
106
|
+
private _minLength;
|
|
107
|
+
private _placeholder;
|
|
108
|
+
private _numeric;
|
|
109
|
+
private _minValue;
|
|
110
|
+
private _maxValue;
|
|
111
|
+
private _prefix;
|
|
112
|
+
private _live;
|
|
113
|
+
static make(name: string): TextInput;
|
|
114
|
+
/** Decimal number: `type="number"`, `step="any"`. */
|
|
115
|
+
numeric(): this;
|
|
116
|
+
/** Integer: `type="number"`, `step="1"`. */
|
|
117
|
+
integer(): this;
|
|
118
|
+
private _step;
|
|
119
|
+
/** Input `step` of a numeric field, overriding the one implied by `numeric()` or `integer()`. */
|
|
120
|
+
step(step: number | 'any' | null): this;
|
|
121
|
+
minValue(value: number): this;
|
|
122
|
+
maxValue(value: number): this;
|
|
123
|
+
/** Label shown before the input (e.g. `$`). */
|
|
124
|
+
prefix(label: string | null): this;
|
|
125
|
+
private _suffix;
|
|
126
|
+
/** Label shown after the input ("hours", "kg"…). */
|
|
127
|
+
suffix(label: string | null): this;
|
|
128
|
+
/** Sends the state to the server on every keystroke, or on blur with `onBlur`. */
|
|
129
|
+
live(options?: {
|
|
130
|
+
onBlur?: boolean;
|
|
131
|
+
}): this;
|
|
132
|
+
type(type: string): this;
|
|
133
|
+
password(condition?: boolean): this;
|
|
134
|
+
revealable(condition?: boolean): this;
|
|
135
|
+
/** `true` → "on", `false` → "off", a string as is. */
|
|
136
|
+
autocomplete(value?: string | boolean): this;
|
|
137
|
+
placeholder(text: string | null): this;
|
|
138
|
+
private _mask;
|
|
139
|
+
/** Alpine input mask (`(999) 999-9999`): guides typing in the browser, with no validation value. */
|
|
140
|
+
mask(pattern: string | null): this;
|
|
141
|
+
/** Phone number: digits, spaces and common punctuation. */
|
|
142
|
+
tel(): this;
|
|
143
|
+
/** Web address: `url` input type, a valid http(s) value is required. */
|
|
144
|
+
url(): this;
|
|
145
|
+
maxLength(length: number): this;
|
|
146
|
+
minLength(length: number): this;
|
|
147
|
+
toHtml(): Promise<string>;
|
|
148
|
+
}
|
|
149
|
+
/** Native date picker (`<input type="date">`). */
|
|
150
|
+
export declare class DatePicker extends Field {
|
|
151
|
+
private _maxDate;
|
|
152
|
+
private _minDate;
|
|
153
|
+
private _live;
|
|
154
|
+
static make(name: string): DatePicker;
|
|
155
|
+
private _datePlaceholder;
|
|
156
|
+
/** Placeholder attribute (browsers do not display it on a native `date` input). */
|
|
157
|
+
placeholder(text: string | null): this;
|
|
158
|
+
/** Sends the state to the server as soon as it changes (`wire:model.live`). */
|
|
159
|
+
live(condition?: boolean): this;
|
|
160
|
+
/** The state is a `YYYY-MM-DD` date, whatever the stored precision. */
|
|
161
|
+
hydrateState(value: unknown): unknown;
|
|
162
|
+
private static resolve;
|
|
163
|
+
private bound;
|
|
164
|
+
/** Latest accepted date: `'today'`, a `YYYY-MM-DD` date, or a context function (`({ get }) => get('endDate') || 'today'`). */
|
|
165
|
+
maxDate(date: Lazy<string | null, ComponentContext>): this;
|
|
166
|
+
minDate(date: Lazy<string | null, ComponentContext>): this;
|
|
167
|
+
toHtml(): Promise<string>;
|
|
168
|
+
}
|
|
169
|
+
type Options = [string, string][] | Record<string, string>;
|
|
170
|
+
/**
|
|
171
|
+
* Dropdown. Native (`<select>`) by default; `searchable()` switches to the JavaScript select,
|
|
172
|
+
* which queries the server through the exposed methods (`getSearchResultsForJs`…).
|
|
173
|
+
*/
|
|
174
|
+
export declare class Select extends Field {
|
|
175
|
+
private _options;
|
|
176
|
+
private _placeholder;
|
|
177
|
+
private _searchable;
|
|
178
|
+
private _dynamic;
|
|
179
|
+
private _searchOnServer;
|
|
180
|
+
private _live;
|
|
181
|
+
private _hasNoInitialOptions;
|
|
182
|
+
private _multiple;
|
|
183
|
+
private _optionLabelsUsing;
|
|
184
|
+
private _disableOptionWhen;
|
|
185
|
+
private _searchResultsUsing;
|
|
186
|
+
private _optionLabelUsing;
|
|
187
|
+
static make(name: string): Select;
|
|
188
|
+
/** Search results computed by the server on every keystroke (no preloaded option list). */
|
|
189
|
+
getSearchResultsUsing(resolver: (search: string, ctx: ComponentContext) => Options | Promise<Options>): this;
|
|
190
|
+
/** Label of a value; also used to validate that a searched value exists. */
|
|
191
|
+
getOptionLabelUsing(resolver: (value: string, ctx: ComponentContext) => string | null | Promise<string | null>): this;
|
|
192
|
+
/**
|
|
193
|
+
* Fixed options, or a (possibly async) function evaluated on every request.
|
|
194
|
+
* `dynamic: false`: options come from a function but stay fixed for the page's lifetime (announced as static to the browser).
|
|
195
|
+
* `searchOnServer: false`: search runs in the browser, among the options already sent (for a complete list).
|
|
196
|
+
*/
|
|
197
|
+
options(options: Options | ((ctx: ComponentContext) => Options | Promise<Options>), config?: {
|
|
198
|
+
dynamic?: boolean;
|
|
199
|
+
searchOnServer?: boolean;
|
|
200
|
+
}): this;
|
|
201
|
+
/** Disables an option depending on the context (e.g. already picked in another row). */
|
|
202
|
+
disableOptionWhen(condition: (value: string, ctx: ComponentContext) => boolean): this;
|
|
203
|
+
/** Sends the state to the server as soon as it changes. */
|
|
204
|
+
live(condition?: boolean): this;
|
|
205
|
+
placeholder(label: string | null): this;
|
|
206
|
+
private _selectablePlaceholder;
|
|
207
|
+
/** `false`: the native select has no empty option. */
|
|
208
|
+
selectablePlaceholder(condition?: boolean): this;
|
|
209
|
+
searchable(condition?: boolean): this;
|
|
210
|
+
/** Multiple selection: the state is a list of values; always uses the JavaScript select. */
|
|
211
|
+
multiple(condition?: boolean): this;
|
|
212
|
+
isMultiple(): boolean;
|
|
213
|
+
/** Labels of several values at once (multiple selection with server search); also used to validate the values. */
|
|
214
|
+
getOptionLabelsUsing(resolver: (values: string[], ctx: ComponentContext) => Options | Promise<Options>): this;
|
|
215
|
+
getDefaultState(): unknown;
|
|
216
|
+
/** Sanitized selected values: unique strings. */
|
|
217
|
+
private selectedValues;
|
|
218
|
+
private labelsOf;
|
|
219
|
+
/** No-op: options are always loaded with the form. */
|
|
220
|
+
preload(): this;
|
|
221
|
+
hydrateState(value: unknown): unknown;
|
|
222
|
+
dehydrateState(state: unknown): unknown;
|
|
223
|
+
resolveOptions(): Promise<[string, string][]>;
|
|
224
|
+
getValidationRules(): Promise<Rule[]>;
|
|
225
|
+
getExposedMethods(): string[];
|
|
226
|
+
private static forJs;
|
|
227
|
+
getOptionsForJs(): Promise<{
|
|
228
|
+
label: string;
|
|
229
|
+
value: string;
|
|
230
|
+
isDisabled: boolean;
|
|
231
|
+
}[]>;
|
|
232
|
+
private withDisabled;
|
|
233
|
+
getSearchResultsForJs(search?: unknown): Promise<{
|
|
234
|
+
label: string;
|
|
235
|
+
value: string;
|
|
236
|
+
isDisabled: boolean;
|
|
237
|
+
}[]>;
|
|
238
|
+
getOptionLabel(): Promise<string | null>;
|
|
239
|
+
getOptionLabelsForJs(): Promise<unknown[]>;
|
|
240
|
+
private _createOptionForm;
|
|
241
|
+
private _createOptionUsing;
|
|
242
|
+
private _createOptionModalHeading;
|
|
243
|
+
private _modifyCreateOptionAction;
|
|
244
|
+
private _editOptionForm;
|
|
245
|
+
private _updateOptionUsing;
|
|
246
|
+
private _fillEditOptionForm;
|
|
247
|
+
private _editOptionModalHeading;
|
|
248
|
+
private _modifyEditOptionAction;
|
|
249
|
+
/**
|
|
250
|
+
* Form of the "Create" modal opened by the field's "+" button, validated on the server.
|
|
251
|
+
* `createOptionUsing()` saves the option and returns its value, which becomes the field state (appended for `multiple()`).
|
|
252
|
+
* Options must come from a function (`options(() => …)`, or server search) for the new value to appear.
|
|
253
|
+
*/
|
|
254
|
+
createOptionForm(schema: Component[] | ((schema: Schema) => Component[] | Schema) | null): this;
|
|
255
|
+
/** Saves the option from the validated modal data; returns the value (key) of the created option. */
|
|
256
|
+
createOptionUsing(callback: ((data: Record<string, unknown>, ctx: ComponentContext) => string | number | null | Promise<string | number | null>) | null): this;
|
|
257
|
+
createOptionModalHeading(heading: string | null): this;
|
|
258
|
+
/** Customizes the create action (label, icon, modal width…). */
|
|
259
|
+
createOptionAction(modify: ((action: Action) => Action | void) | null): this;
|
|
260
|
+
/**
|
|
261
|
+
* Form of the "Edit" modal for the selected option (single selection only). The field becomes `live()` so the button
|
|
262
|
+
* appears as soon as an option is picked. Filled by `fillEditOptionActionFormUsing()`, saved by `updateOptionUsing()`.
|
|
263
|
+
*/
|
|
264
|
+
editOptionForm(schema: Component[] | ((schema: Schema) => Component[] | Schema) | null): this;
|
|
265
|
+
updateOptionUsing(callback: ((data: Record<string, unknown>, ctx: ComponentContext) => unknown) | null): this;
|
|
266
|
+
/** Initial data of the "Edit" modal (the context carries the current field state in `state`). */
|
|
267
|
+
fillEditOptionActionFormUsing(callback: ((ctx: ComponentContext) => Record<string, unknown> | null | Promise<Record<string, unknown> | null>) | null): this;
|
|
268
|
+
editOptionModalHeading(heading: string | null): this;
|
|
269
|
+
editOptionAction(modify: ((action: Action) => Action | void) | null): this;
|
|
270
|
+
/** Same form for creating and editing. */
|
|
271
|
+
manageOptionForm(schema: Component[] | ((schema: Schema) => Component[] | Schema) | null): this;
|
|
272
|
+
private setState;
|
|
273
|
+
private getCreateOptionAction;
|
|
274
|
+
private getEditOptionAction;
|
|
275
|
+
/** Actions mounted on the field: hint, create option and edit option. */
|
|
276
|
+
getActions(): Action[];
|
|
277
|
+
/** "+" and "edit" buttons on the right of the field. */
|
|
278
|
+
private suffixHtml;
|
|
279
|
+
toHtml(): Promise<string>;
|
|
280
|
+
/** JavaScript select rendering. */
|
|
281
|
+
private toJsHtml;
|
|
282
|
+
}
|
|
283
|
+
/** Column of a table Repeater: label and width. */
|
|
284
|
+
export declare class TableColumn {
|
|
285
|
+
label: string;
|
|
286
|
+
private _width;
|
|
287
|
+
constructor(label: string);
|
|
288
|
+
static make(label: string): TableColumn;
|
|
289
|
+
width(width: number | string): this;
|
|
290
|
+
getWidth(): string | null;
|
|
291
|
+
}
|
|
292
|
+
type ItemLink = {
|
|
293
|
+
label: string;
|
|
294
|
+
icon: string;
|
|
295
|
+
url: string;
|
|
296
|
+
};
|
|
297
|
+
/**
|
|
298
|
+
* List of repeated items sharing the same fields, displayed as a table.
|
|
299
|
+
* The state is a map `item key → fields`; key order is display order.
|
|
300
|
+
* Add, delete and move are component actions, mounted with `schemaComponent`.
|
|
301
|
+
*/
|
|
302
|
+
export declare class Repeater extends Field {
|
|
303
|
+
private _schema;
|
|
304
|
+
private _columns;
|
|
305
|
+
private _defaultItems;
|
|
306
|
+
private _maxItems;
|
|
307
|
+
private _itemLinks;
|
|
308
|
+
static make(name: string): Repeater;
|
|
309
|
+
/** Item fields: a function called for each item. */
|
|
310
|
+
schema(factory: () => Field[]): this;
|
|
311
|
+
/** Table display, one column per field. */
|
|
312
|
+
table(columns: TableColumn[]): this;
|
|
313
|
+
defaultItems(count: number): this;
|
|
314
|
+
maxItems(count: number): this;
|
|
315
|
+
private _reorderable;
|
|
316
|
+
/** `false`: items keep their order (e.g. a relationship without an order column). */
|
|
317
|
+
reorderable(condition?: boolean): this;
|
|
318
|
+
/** Link shown on each row (an item action pointing to a URL). */
|
|
319
|
+
extraItemLink(resolver: (ctx: {
|
|
320
|
+
item: Record<string, unknown>;
|
|
321
|
+
key: string;
|
|
322
|
+
}) => ItemLink | null): this;
|
|
323
|
+
/** Well-formed items only: keys come from the browser, so only simple keys are kept. */
|
|
324
|
+
getItems(): Record<string, Record<string, unknown>>;
|
|
325
|
+
private setItems;
|
|
326
|
+
private itemDefaults;
|
|
327
|
+
getDefaultState(): unknown;
|
|
328
|
+
/** Relationship records → `record-<id>` items, limited to the declared fields. */
|
|
329
|
+
hydrateState(value: unknown): unknown;
|
|
330
|
+
dehydrateState(): unknown;
|
|
331
|
+
getChildSchemas(): Schema[];
|
|
332
|
+
getValidationRules(): Promise<Rule[]>;
|
|
333
|
+
getActions(): Action[];
|
|
334
|
+
toHtml(): Promise<string>;
|
|
335
|
+
}
|
|
336
|
+
/** Native time input: the state is `HH:MM` with `seconds(false)`, `HH:MM:SS` otherwise. */
|
|
337
|
+
export declare class TimePicker extends Field {
|
|
338
|
+
private _seconds;
|
|
339
|
+
static make(name: string): TimePicker;
|
|
340
|
+
seconds(condition?: boolean): this;
|
|
341
|
+
hydrateState(value: unknown): unknown;
|
|
342
|
+
toHtml(): Promise<string>;
|
|
343
|
+
}
|
|
344
|
+
/** Native `datetime-local` input: the saved state is `YYYY-MM-DD HH:MM:SS`. */
|
|
345
|
+
export declare class DateTimePicker extends Field {
|
|
346
|
+
private _seconds;
|
|
347
|
+
static make(name: string): DateTimePicker;
|
|
348
|
+
seconds(condition?: boolean): this;
|
|
349
|
+
dehydrateState(state: unknown): unknown;
|
|
350
|
+
toHtml(): Promise<string>;
|
|
351
|
+
}
|
|
352
|
+
/** Single choice as radio buttons. */
|
|
353
|
+
export declare class Radio extends Field {
|
|
354
|
+
private _options;
|
|
355
|
+
private _descriptions;
|
|
356
|
+
private _inline;
|
|
357
|
+
private _live;
|
|
358
|
+
static make(name: string): Radio;
|
|
359
|
+
options(options: Options): this;
|
|
360
|
+
/** Helper text per value, under the option label. */
|
|
361
|
+
descriptions(descriptions: Record<string, string>): this;
|
|
362
|
+
/** Options side by side. */
|
|
363
|
+
inline(condition?: boolean): this;
|
|
364
|
+
live(condition?: boolean): this;
|
|
365
|
+
getValidationRules(): Promise<Rule[]>;
|
|
366
|
+
toHtml(): Promise<string>;
|
|
367
|
+
}
|
|
368
|
+
export declare class Textarea extends Field {
|
|
369
|
+
private _rows;
|
|
370
|
+
private _maxLength;
|
|
371
|
+
static make(name: string): Textarea;
|
|
372
|
+
rows(rows: number): this;
|
|
373
|
+
maxLength(length: number): this;
|
|
374
|
+
toHtml(): Promise<string>;
|
|
375
|
+
}
|
|
376
|
+
/** Tag list input: the state is an array of strings. */
|
|
377
|
+
export declare class TagsInput extends Field {
|
|
378
|
+
private _placeholder;
|
|
379
|
+
private _suggestions;
|
|
380
|
+
private _splitKeys;
|
|
381
|
+
static make(name: string): TagsInput;
|
|
382
|
+
placeholder(text: string | null): this;
|
|
383
|
+
/** Values suggested while typing. */
|
|
384
|
+
suggestions(suggestions: string[]): this;
|
|
385
|
+
/** Keys that confirm the current tag, besides Enter (`['Tab', ',']`). */
|
|
386
|
+
splitKeys(keys: string[]): this;
|
|
387
|
+
getDefaultState(): unknown;
|
|
388
|
+
hydrateState(value: unknown): unknown;
|
|
389
|
+
/** Only non-empty strings are saved, whatever shape the browser sends. */
|
|
390
|
+
dehydrateState(state: unknown): unknown;
|
|
391
|
+
toHtml(): Promise<string>;
|
|
392
|
+
}
|
|
393
|
+
/** On/off switch. */
|
|
394
|
+
export declare class Toggle extends Field {
|
|
395
|
+
static make(name: string): Toggle;
|
|
396
|
+
getDefaultState(): unknown;
|
|
397
|
+
hydrateState(value: unknown): unknown;
|
|
398
|
+
toHtml(): Promise<string>;
|
|
399
|
+
}
|
|
400
|
+
/** Single choice shown as buttons. */
|
|
401
|
+
export declare class ToggleButtons extends Field {
|
|
402
|
+
private _options;
|
|
403
|
+
private _inline;
|
|
404
|
+
private _grouped;
|
|
405
|
+
private _colors;
|
|
406
|
+
private _icons;
|
|
407
|
+
static make(name: string): ToggleButtons;
|
|
408
|
+
private _live;
|
|
409
|
+
/** Sends the state to the server as soon as it changes. */
|
|
410
|
+
live(condition?: boolean): this;
|
|
411
|
+
/** Color per value (e.g. from an enum). */
|
|
412
|
+
colors(colors: Record<string, string>): this;
|
|
413
|
+
/** Icon per value. */
|
|
414
|
+
icons(icons: Record<string, string>): this;
|
|
415
|
+
options(options: Options): this;
|
|
416
|
+
/** Buttons side by side. */
|
|
417
|
+
inline(condition?: boolean): this;
|
|
418
|
+
/** Buttons joined into a single group. */
|
|
419
|
+
grouped(condition?: boolean): this;
|
|
420
|
+
getValidationRules(): Promise<Rule[]>;
|
|
421
|
+
toHtml(): Promise<string>;
|
|
422
|
+
}
|
|
423
|
+
type RichDocument = {
|
|
424
|
+
type: 'doc';
|
|
425
|
+
content?: unknown[];
|
|
426
|
+
};
|
|
427
|
+
/** Stored HTML → TipTap document. Parsing drops anything the schema does not know (scripts, event attributes, `javascript:` links). */
|
|
428
|
+
export declare function richHtmlToDocument(html: string | null | undefined): RichDocument;
|
|
429
|
+
/**
|
|
430
|
+
* TipTap document → HTML to save, or null if empty or invalid. The document comes from the browser,
|
|
431
|
+
* so it is rendered then re-parsed to keep only what the schema accepts.
|
|
432
|
+
*/
|
|
433
|
+
export declare function richDocumentToHtml(document: unknown): string | null;
|
|
434
|
+
/**
|
|
435
|
+
* Rich text editor: the browser works on a TipTap document, the database receives HTML.
|
|
436
|
+
* Not supported yet: attachments, custom blocks, mentions.
|
|
437
|
+
*/
|
|
438
|
+
export declare class RichEditor extends Field {
|
|
439
|
+
static make(name: string): RichEditor;
|
|
440
|
+
hydrateState(value: unknown): unknown;
|
|
441
|
+
getDefaultState(): unknown;
|
|
442
|
+
dehydrateState(state: unknown): unknown;
|
|
443
|
+
getValidationRules(): Promise<Rule[]>;
|
|
444
|
+
getExposedMethods(): string[];
|
|
445
|
+
getMentionSearchResultsForJs(): unknown[];
|
|
446
|
+
getMentionLabelsForJs(): unknown[];
|
|
447
|
+
getCustomBlockPreviewsForJs(): unknown[];
|
|
448
|
+
getUploadedFileAttachmentTemporaryUrl(): null;
|
|
449
|
+
saveUploadedFileAttachmentAndGetUrl(): null;
|
|
450
|
+
/** Toolbar "link" action: a modal (URL, new tab), then commands sent back to the browser editor. */
|
|
451
|
+
getActions(): Action[];
|
|
452
|
+
toHtml(): Promise<string>;
|
|
453
|
+
}
|
|
454
|
+
/** Color picker (hex format). */
|
|
455
|
+
export declare class ColorPicker extends Field {
|
|
456
|
+
static make(name: string): ColorPicker;
|
|
457
|
+
/** Hex format: the only one supported, kept for API compatibility. */
|
|
458
|
+
hex(): this;
|
|
459
|
+
constructor(name: string);
|
|
460
|
+
toHtml(): Promise<string>;
|
|
461
|
+
}
|
|
462
|
+
export declare class Checkbox extends Field {
|
|
463
|
+
static make(name: string): Checkbox;
|
|
464
|
+
getDefaultState(): unknown;
|
|
465
|
+
toHtml(): Promise<string>;
|
|
466
|
+
}
|
|
467
|
+
/** Checkboxes for a list of values (no search or "select all" yet). */
|
|
468
|
+
export declare class CheckboxList extends Field {
|
|
469
|
+
private _options;
|
|
470
|
+
private _optionColumns;
|
|
471
|
+
static make(name: string): CheckboxList;
|
|
472
|
+
options(options: Options): this;
|
|
473
|
+
/** Number of columns the options are spread over (from `lg`). */
|
|
474
|
+
columns(columns: number | null): this;
|
|
475
|
+
getDefaultState(): unknown;
|
|
476
|
+
hydrateState(value: unknown): unknown;
|
|
477
|
+
/** Only offered values are kept, without duplicates, in option order. */
|
|
478
|
+
dehydrateState(state: unknown): unknown;
|
|
479
|
+
getValidationRules(): Promise<Rule[]>;
|
|
480
|
+
toHtml(): Promise<string>;
|
|
481
|
+
}
|
|
482
|
+
/** Free-form key/value pairs, saved as an object. */
|
|
483
|
+
export declare class KeyValue extends Field {
|
|
484
|
+
private _keyLabel;
|
|
485
|
+
private _valueLabel;
|
|
486
|
+
private _reorderable;
|
|
487
|
+
static make(name: string): KeyValue;
|
|
488
|
+
keyLabel(label: string): this;
|
|
489
|
+
valueLabel(label: string): this;
|
|
490
|
+
reorderable(condition?: boolean): this;
|
|
491
|
+
getDefaultState(): unknown;
|
|
492
|
+
private static toPairs;
|
|
493
|
+
hydrateState(value: unknown): unknown;
|
|
494
|
+
/** Flat object of strings: empty keys, nested objects and dangerous keys are dropped; 200 pairs at most. */
|
|
495
|
+
dehydrateState(state: unknown): unknown;
|
|
496
|
+
toHtml(): Promise<string>;
|
|
497
|
+
}
|
|
498
|
+
/** Developer-written JavaScript expression (e.g. a Slider tooltip formatter), inserted as is: never put user data in it. */
|
|
499
|
+
export declare class RawJs {
|
|
500
|
+
readonly js: string;
|
|
501
|
+
constructor(js: string);
|
|
502
|
+
static make(js: string): RawJs;
|
|
503
|
+
toString(): string;
|
|
504
|
+
}
|
|
505
|
+
/**
|
|
506
|
+
* Markdown editor (EasyMDE). The state is raw Markdown text, to sanitize before any HTML display.
|
|
507
|
+
* Attachments are not supported (no `attachFiles` button by default); when read-only (`disabled()`),
|
|
508
|
+
* the text is shown escaped, without Markdown conversion.
|
|
509
|
+
*/
|
|
510
|
+
export declare class MarkdownEditor extends Field {
|
|
511
|
+
private _toolbarButtons;
|
|
512
|
+
private _minHeight;
|
|
513
|
+
private _maxHeight;
|
|
514
|
+
private _placeholder;
|
|
515
|
+
private _live;
|
|
516
|
+
static make(name: string): MarkdownEditor;
|
|
517
|
+
/** Toolbar buttons, grouped (`[['bold', 'italic'], ['undo', 'redo']]`) or flat. */
|
|
518
|
+
toolbarButtons(buttons: (string | string[])[]): this;
|
|
519
|
+
/** Removes buttons; with no argument, removes them all. */
|
|
520
|
+
disableToolbarButtons(names?: string[]): this;
|
|
521
|
+
disableAllToolbarButtons(condition?: boolean): this;
|
|
522
|
+
/** Adds buttons (in a separate group). */
|
|
523
|
+
enableToolbarButtons(names: string[]): this;
|
|
524
|
+
getToolbarButtons(): (string | string[])[];
|
|
525
|
+
hasToolbarButton(name: string): boolean;
|
|
526
|
+
/** Minimum height of the editing area (`10rem` by default). */
|
|
527
|
+
minHeight(height: string | null): this;
|
|
528
|
+
maxHeight(height: string | null): this;
|
|
529
|
+
placeholder(text: string | null): this;
|
|
530
|
+
/** Sends the state to the server while typing (`debounce` in milliseconds), or on blur with `onBlur`. */
|
|
531
|
+
live(options?: {
|
|
532
|
+
onBlur?: boolean;
|
|
533
|
+
debounce?: number | null;
|
|
534
|
+
}): this;
|
|
535
|
+
maxLength(length: number): this;
|
|
536
|
+
minLength(length: number): this;
|
|
537
|
+
hydrateState(value: unknown): unknown;
|
|
538
|
+
getValidationRules(): Promise<Rule[]>;
|
|
539
|
+
getExposedMethods(): string[];
|
|
540
|
+
getUploadedFileAttachmentTemporaryUrl(): null;
|
|
541
|
+
saveUploadedFileAttachmentAndGetUrl(): null;
|
|
542
|
+
toHtml(): Promise<string>;
|
|
543
|
+
}
|
|
544
|
+
/** Code editor (CodeMirror): highlighting from `language()`, line wrapping with `wrap()`. */
|
|
545
|
+
export declare class CodeEditor extends Field {
|
|
546
|
+
private _language;
|
|
547
|
+
private _canWrap;
|
|
548
|
+
private _live;
|
|
549
|
+
static make(name: string): CodeEditor;
|
|
550
|
+
/** Language: `cpp`, `css`, `go`, `html`, `java`, `javascript`, `json`, `markdown`, `php`, `python`, `sql`, `xml`, `yaml`. */
|
|
551
|
+
language(language: string | null): this;
|
|
552
|
+
getLanguage(): string | null;
|
|
553
|
+
/**
|
|
554
|
+
* Wraps long lines. Called with an HTML string, it is the inherited field wrapper,
|
|
555
|
+
* which the component's rendering uses.
|
|
556
|
+
*/
|
|
557
|
+
wrap(condition?: any, options?: any): any;
|
|
558
|
+
canWrap(): boolean;
|
|
559
|
+
live(options?: {
|
|
560
|
+
onBlur?: boolean;
|
|
561
|
+
debounce?: number | null;
|
|
562
|
+
}): this;
|
|
563
|
+
hydrateState(value: unknown): unknown;
|
|
564
|
+
getValidationRules(): Promise<Rule[]>;
|
|
565
|
+
toHtml(): Promise<string>;
|
|
566
|
+
}
|
|
567
|
+
/**
|
|
568
|
+
* Slider (noUiSlider): one value, or several handles when the state is a list (`default([20, 70])`).
|
|
569
|
+
* Required by default; bounds, step and numeric type are checked on the server.
|
|
570
|
+
*/
|
|
571
|
+
export declare class Slider extends Field {
|
|
572
|
+
private _minValue;
|
|
573
|
+
private _maxValue;
|
|
574
|
+
private _step;
|
|
575
|
+
private _minDifference;
|
|
576
|
+
private _maxDifference;
|
|
577
|
+
private _rangePadding;
|
|
578
|
+
private _fillTrack;
|
|
579
|
+
private _vertical;
|
|
580
|
+
private _rtl;
|
|
581
|
+
private _behavior;
|
|
582
|
+
private _tooltips;
|
|
583
|
+
private _pipsMode;
|
|
584
|
+
private _pipsDensity;
|
|
585
|
+
private _pipsFormatter;
|
|
586
|
+
private _pipsValues;
|
|
587
|
+
private _steppedPips;
|
|
588
|
+
private _pipsFilter;
|
|
589
|
+
private _nonLinearPoints;
|
|
590
|
+
private _decimalPlaces;
|
|
591
|
+
private _live;
|
|
592
|
+
constructor(name: string);
|
|
593
|
+
static make(name: string): Slider;
|
|
594
|
+
range(minValue: number, maxValue: number): this;
|
|
595
|
+
minValue(value: number): this;
|
|
596
|
+
maxValue(value: number): this;
|
|
597
|
+
/** Step between values; `1` requires an integer, otherwise the value must be a multiple of the step. */
|
|
598
|
+
step(step: number | null): this;
|
|
599
|
+
/** Minimum / maximum gap between two handles. */
|
|
600
|
+
minDifference(difference: number | null): this;
|
|
601
|
+
maxDifference(difference: number | null): this;
|
|
602
|
+
/** Forbidden margin at the ends: a number, or `[start, end]`. */
|
|
603
|
+
rangePadding(padding: number | [number, number] | null): this;
|
|
604
|
+
/** Colored track segments, one boolean per segment (`[true, false]` by default). */
|
|
605
|
+
fillTrack(fill?: boolean[] | null): this;
|
|
606
|
+
vertical(condition?: boolean): this;
|
|
607
|
+
/** Right to left (top to bottom for a vertical slider, the default when vertical). */
|
|
608
|
+
rtl(condition?: boolean | null): this;
|
|
609
|
+
/** Handle behavior (`tap`, `drag`, `fixed`, `snap`, `unconstrained`…); `null`: none. */
|
|
610
|
+
behavior(behavior?: string | string[] | null): this;
|
|
611
|
+
/** Handle tooltips: a boolean, one boolean per handle, or a `RawJs` formatting `$value`. */
|
|
612
|
+
tooltips(tooltips?: boolean | RawJs | (boolean | RawJs)[]): this;
|
|
613
|
+
/** Pips: `range` (default), `steps`, `positions`, `count`, `values`. */
|
|
614
|
+
pips(mode?: string | null, density?: number | null): this;
|
|
615
|
+
pipsMode(mode: string | null): this;
|
|
616
|
+
pipsDensity(density: number | null): this;
|
|
617
|
+
/** Pip formatter (a `RawJs` receiving `$value`). */
|
|
618
|
+
pipsFormatter(formatter: RawJs | null): this;
|
|
619
|
+
pipsValues(values: number | number[] | null): this;
|
|
620
|
+
steppedPips(condition?: boolean): this;
|
|
621
|
+
/** Pip filter (a `RawJs` receiving `$value`). */
|
|
622
|
+
pipsFilter(filter: RawJs | null): this;
|
|
623
|
+
/** Non-linear scale (`{ '10%': 500, '50%': 4000 }`). */
|
|
624
|
+
nonLinearPoints(points: Record<string, number | number[]> | null): this;
|
|
625
|
+
/** Decimal places of the saved value. */
|
|
626
|
+
decimalPlaces(places: number | null): this;
|
|
627
|
+
live(options?: {
|
|
628
|
+
onBlur?: boolean;
|
|
629
|
+
debounce?: number | null;
|
|
630
|
+
}): this;
|
|
631
|
+
getMinValueWithPadding(): number;
|
|
632
|
+
getMaxValueWithPadding(): number;
|
|
633
|
+
isMultiple(): boolean;
|
|
634
|
+
getDefaultState(): unknown;
|
|
635
|
+
private cast;
|
|
636
|
+
hydrateState(value: unknown): unknown;
|
|
637
|
+
dehydrateState(state: unknown): unknown;
|
|
638
|
+
getValidationRules(): Promise<Rule[]>;
|
|
639
|
+
/** A `RawJs` becomes a `{ to: ($value) => … }` formatter object. */
|
|
640
|
+
private static formatters;
|
|
641
|
+
toHtml(): Promise<string>;
|
|
642
|
+
}
|
|
643
|
+
/** Hidden field: an `<input type="hidden">` bound to the state, with no label or grid slot. */
|
|
644
|
+
export declare class Hidden extends Field {
|
|
645
|
+
constructor(name: string);
|
|
646
|
+
static make(name: string): Hidden;
|
|
647
|
+
toHtml(): Promise<string>;
|
|
648
|
+
}
|
|
649
|
+
/** One-time code: one box per digit; the state is a digit string of exactly `length()` characters. */
|
|
650
|
+
export declare class OneTimeCodeInput extends Field {
|
|
651
|
+
private _length;
|
|
652
|
+
private _submitOnCompletion;
|
|
653
|
+
private _readOnly;
|
|
654
|
+
constructor(name: string);
|
|
655
|
+
static make(name: string): OneTimeCodeInput;
|
|
656
|
+
/** Number of digits (6 by default). */
|
|
657
|
+
length(length: number): this;
|
|
658
|
+
getLength(): number;
|
|
659
|
+
/** Submits the form as soon as the last digit is typed. */
|
|
660
|
+
submitOnCompletion(condition?: boolean): this;
|
|
661
|
+
readOnly(condition?: boolean): this;
|
|
662
|
+
hydrateState(value: unknown): unknown;
|
|
663
|
+
toHtml(): Promise<string>;
|
|
664
|
+
}
|
|
665
|
+
/**
|
|
666
|
+
* Read-only text in a form. Nothing is saved. An `HtmlString` is inserted as is.
|
|
667
|
+
*/
|
|
668
|
+
export declare class Placeholder extends Component {
|
|
669
|
+
private _label;
|
|
670
|
+
private _content;
|
|
671
|
+
private _hiddenLabel;
|
|
672
|
+
constructor(name: string);
|
|
673
|
+
static make(name: string): Placeholder;
|
|
674
|
+
hasStatePath(): boolean;
|
|
675
|
+
label(label: Lazy<string | null, ComponentContext>): this;
|
|
676
|
+
hiddenLabel(condition?: boolean): this;
|
|
677
|
+
content(content: Lazy<string | number | HtmlString | null, ComponentContext>): this;
|
|
678
|
+
toHtml(): Promise<string>;
|
|
679
|
+
}
|
|
680
|
+
/** Fills the default state of every field in a schema. */
|
|
681
|
+
export declare function fillSchema(schema: Schema, target: Record<string, unknown>): void;
|
|
682
|
+
/** Fills the form state from a record, field by field. */
|
|
683
|
+
export declare function fillSchemaFromRecord(schema: Schema, target: Record<string, unknown>, record: Record<string, unknown>): void;
|
|
684
|
+
/** Validates every visible field of a schema; returns errors by state path. */
|
|
685
|
+
export declare function validateSchema(schema: Schema): Promise<Record<string, string[]>>;
|
|
686
|
+
/** State to save: only declared, visible, dehydrated fields; an empty string becomes `null`. */
|
|
687
|
+
export declare function getSchemaState(schema: Schema): Promise<Record<string, unknown>>;
|
|
688
|
+
type StepHook = (ctx: ComponentContext) => void | Promise<void>;
|
|
689
|
+
/** Throw from a step's `beforeValidation` / `afterValidation` to stay on the current step. */
|
|
690
|
+
export declare class Halt extends Error {
|
|
691
|
+
constructor();
|
|
692
|
+
}
|
|
693
|
+
/** A wizard step: a label, an optional description and icon, and its own schema. */
|
|
694
|
+
export declare class Step extends Component {
|
|
695
|
+
private children;
|
|
696
|
+
private _columns;
|
|
697
|
+
private label;
|
|
698
|
+
private _description;
|
|
699
|
+
private _icon;
|
|
700
|
+
private _completedIcon;
|
|
701
|
+
private _beforeValidation;
|
|
702
|
+
private _afterValidation;
|
|
703
|
+
constructor(label: string);
|
|
704
|
+
static make(label: string): Step;
|
|
705
|
+
schema(components: Component[]): this;
|
|
706
|
+
columns(columns?: Record<string, number> | number | null): this;
|
|
707
|
+
description(description: string | null): this;
|
|
708
|
+
icon(name: string | null): this;
|
|
709
|
+
completedIcon(name: string | null): this;
|
|
710
|
+
/** Runs before the step is validated, on "Next"; throw `Halt` to stay on the step. */
|
|
711
|
+
beforeValidation(callback: StepHook | null): this;
|
|
712
|
+
/** Runs after a successful validation, before moving to the next step; throw `Halt` to stay on the step. */
|
|
713
|
+
afterValidation(callback: StepHook | null): this;
|
|
714
|
+
getLabel(): string;
|
|
715
|
+
getDescription(): string | null;
|
|
716
|
+
getIcon(): string | null;
|
|
717
|
+
getCompletedIcon(): string | null;
|
|
718
|
+
callBeforeValidation(): Promise<void>;
|
|
719
|
+
callAfterValidation(): Promise<void>;
|
|
720
|
+
getChildSchemas(): Schema[];
|
|
721
|
+
toHtml(): Promise<string>;
|
|
722
|
+
/** Step panel: a `<form>` when the wizard has a submit handler (Enter goes to the next step, or saves on the last one). */
|
|
723
|
+
toStepHtml(submitHandler: string | null, hasHeader: boolean): Promise<string>;
|
|
724
|
+
}
|
|
725
|
+
/**
|
|
726
|
+
* Multi-step wizard: every step is rendered, the browser only shows the current one.
|
|
727
|
+
* "Next" validates the current step on the server before moving on, unless the wizard is `skippable()`.
|
|
728
|
+
*/
|
|
729
|
+
export declare class Wizard extends Component {
|
|
730
|
+
private steps;
|
|
731
|
+
private _label;
|
|
732
|
+
private _skippable;
|
|
733
|
+
private _startStep;
|
|
734
|
+
private _contained;
|
|
735
|
+
private _headerHidden;
|
|
736
|
+
private _cancelAction;
|
|
737
|
+
private _submitAction;
|
|
738
|
+
private _alpineSubmitHandler;
|
|
739
|
+
private _stepQueryStringKey;
|
|
740
|
+
private _modifyNext;
|
|
741
|
+
private _modifyPrevious;
|
|
742
|
+
constructor(steps?: Step[]);
|
|
743
|
+
static make(steps?: Step[]): Wizard;
|
|
744
|
+
schema(steps: Step[]): this;
|
|
745
|
+
label(label: string | null): this;
|
|
746
|
+
/** Steps can be visited in any order, without validation. */
|
|
747
|
+
skippable(condition?: boolean): this;
|
|
748
|
+
/** Step shown on open (1-based). */
|
|
749
|
+
startOnStep(step: number): this;
|
|
750
|
+
/** `false`: no card around the wizard (as on a resource page). */
|
|
751
|
+
contained(condition?: boolean): this;
|
|
752
|
+
hiddenHeader(condition?: boolean): this;
|
|
753
|
+
/** Action shown instead of "Back" on the first step. */
|
|
754
|
+
cancelAction(action: Action | null): this;
|
|
755
|
+
/** Action shown instead of "Next" on the last step. */
|
|
756
|
+
submitAction(action: Action | null): this;
|
|
757
|
+
/** Alpine expression run when the last step is submitted from the keyboard (e.g. `$wire.create()`). */
|
|
758
|
+
alpineSubmitHandler(handler: string | null): this;
|
|
759
|
+
/** Keeps the current step in the URL (`?step=…`). */
|
|
760
|
+
persistStepInQueryString(key?: string | null): this;
|
|
761
|
+
nextAction(modify: ((action: Action) => Action | void) | null): this;
|
|
762
|
+
previousAction(modify: ((action: Action) => Action | void) | null): this;
|
|
763
|
+
getKey(): string;
|
|
764
|
+
getExposedMethods(): string[];
|
|
765
|
+
/** "Next" re-renders the component so the step's validation errors show up. */
|
|
766
|
+
isRenderlessMethod(): boolean;
|
|
767
|
+
getChildSchemas(): Schema[];
|
|
768
|
+
private getSteps;
|
|
769
|
+
/** Called by the browser on "Next": validates the current step, then announces the next one. */
|
|
770
|
+
nextStep(currentStepIndex?: unknown, currentStepKey?: unknown): Promise<void>;
|
|
771
|
+
/** Going back happens in the browser; this exposed method is a no-op the front end still calls. */
|
|
772
|
+
previousStep(): void;
|
|
773
|
+
toHtml(): Promise<string>;
|
|
774
|
+
}
|
|
775
|
+
/** Temporary file received by the runtime (see @navette-js/wire). */
|
|
776
|
+
export type TemporaryUpload = {
|
|
777
|
+
id: string;
|
|
778
|
+
path: string;
|
|
779
|
+
name: string;
|
|
780
|
+
type: string;
|
|
781
|
+
size: number;
|
|
782
|
+
extension: string;
|
|
783
|
+
};
|
|
784
|
+
export type UploadedFileInfo = {
|
|
785
|
+
name: string;
|
|
786
|
+
size: number;
|
|
787
|
+
type: string;
|
|
788
|
+
url: string;
|
|
789
|
+
};
|
|
790
|
+
/** Saved state item when the field does not store files itself (`storeFiles(false)`): an already saved file, or a temporary file to process. */
|
|
791
|
+
export type FileUploadEntry = {
|
|
792
|
+
key: string;
|
|
793
|
+
} | {
|
|
794
|
+
file: TemporaryUpload;
|
|
795
|
+
};
|
|
796
|
+
/** Where files go once the form is saved. */
|
|
797
|
+
export interface FileStorage {
|
|
798
|
+
/** Stores a temporary file and returns its key (relative path). */
|
|
799
|
+
store(file: TemporaryUpload, directory: string | null): Promise<string>;
|
|
800
|
+
info(key: string): Promise<UploadedFileInfo | null>;
|
|
801
|
+
}
|
|
802
|
+
/** Local disk storage, served under a public URL. File names are random; the extension comes from the detected type. */
|
|
803
|
+
export declare class LocalFileStorage implements FileStorage {
|
|
804
|
+
private root;
|
|
805
|
+
private baseUrl;
|
|
806
|
+
constructor(root: string, baseUrl: string);
|
|
807
|
+
private resolve;
|
|
808
|
+
store(file: TemporaryUpload, directory: string | null): Promise<string>;
|
|
809
|
+
info(key: string): Promise<UploadedFileInfo | null>;
|
|
810
|
+
}
|
|
811
|
+
/**
|
|
812
|
+
* File upload (FilePond).
|
|
813
|
+
* State: `{ <file key>: <stored key> | 'livewire-file:<temporary id>' }`. A stored key from the browser is only accepted
|
|
814
|
+
* if the record being edited already has it, so nobody can claim someone else's file.
|
|
815
|
+
*/
|
|
816
|
+
export declare class FileUpload extends Field {
|
|
817
|
+
/** Application-wide default storage. */
|
|
818
|
+
static storage: FileStorage | null;
|
|
819
|
+
private _multiple;
|
|
820
|
+
private _maxFiles;
|
|
821
|
+
private _maxSize;
|
|
822
|
+
private _reorderable;
|
|
823
|
+
private _acceptedFileTypes;
|
|
824
|
+
private _directory;
|
|
825
|
+
private _storeFiles;
|
|
826
|
+
private _storage;
|
|
827
|
+
private _getUploadedFileUsing;
|
|
828
|
+
static make(name: string): FileUpload;
|
|
829
|
+
multiple(condition?: boolean): this;
|
|
830
|
+
maxFiles(count: number | null): this;
|
|
831
|
+
/** Maximum file size, in kilobytes. */
|
|
832
|
+
maxSize(kilobytes: number | null): this;
|
|
833
|
+
reorderable(condition?: boolean): this;
|
|
834
|
+
/** Accepted MIME types (`image/jpeg`, `image/*`…), checked against the received file's content. */
|
|
835
|
+
acceptedFileTypes(types: string[] | null): this;
|
|
836
|
+
image(): this;
|
|
837
|
+
directory(directory: string | null): this;
|
|
838
|
+
storage(storage: FileStorage): this;
|
|
839
|
+
/** `false`: the field stores nothing itself; the data receives `FileUploadEntry` items for the adapter to process (media). */
|
|
840
|
+
storeFiles(condition?: boolean): this;
|
|
841
|
+
/** Info about an already saved file (name, size, type, URL), when it does not come from the storage. */
|
|
842
|
+
getUploadedFileUsing(resolver: (key: string, ctx: ComponentContext) => UploadedFileInfo | null | Promise<UploadedFileInfo | null>): this;
|
|
843
|
+
getDefaultState(): unknown;
|
|
844
|
+
hydrateState(value: unknown): unknown;
|
|
845
|
+
private get uploads();
|
|
846
|
+
private getStorage;
|
|
847
|
+
/** Sanitized state entries: safe file key, string value. */
|
|
848
|
+
private entries;
|
|
849
|
+
/** Stored keys the current record already owns: the only ones accepted back from the browser. */
|
|
850
|
+
private originalKeys;
|
|
851
|
+
private isTemporary;
|
|
852
|
+
getExposedMethods(): string[];
|
|
853
|
+
getUploadedFiles(): Promise<Record<string, UploadedFileInfo | null>>;
|
|
854
|
+
private writeState;
|
|
855
|
+
/** Removes a file from the field. A stored file is only deleted by the application when the form is saved. */
|
|
856
|
+
removeUploadedFile(fileKey: unknown): void;
|
|
857
|
+
deleteUploadedFile(fileKey: unknown): void;
|
|
858
|
+
reorderUploadedFiles(fileKeys: unknown): void;
|
|
859
|
+
getValidationRules(): Promise<Rule[]>;
|
|
860
|
+
/** Validates the whole state, even when empty (a required field without files must fail). */
|
|
861
|
+
validate(): Promise<string[]>;
|
|
862
|
+
/** On save: temporary files are stored, unrecognized existing keys are dropped. */
|
|
863
|
+
dehydrateState(): Promise<unknown>;
|
|
864
|
+
toHtml(): Promise<string>;
|
|
865
|
+
}
|
|
866
|
+
export {};
|