@navette-js/forms 0.0.0-stage → 1.0.0-beta.1

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/lib/index.d.ts ADDED
@@ -0,0 +1,871 @@
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
+ /** Texte d'aide affiché sous le champ. */
33
+ helperText(text: string | null): this;
34
+ /** Identifiant du texte d'aide, à lier au contrôle par `aria-describedby`. */
35
+ protected getHelperTextId(): string | null;
36
+ /** Libellé réservé aux lecteurs d'écran. */
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
+ * Indication affichée à droite du libellé (un composant `Text`). Le texte est échappé ; une `HtmlString` de `@navette-js/support`
45
+ * (`raw('<a href="…">…</a>')`) est insérée telle quelle : n'y placez que des valeurs échappées avec `e()`.
46
+ */
47
+ hint(hint: Lazy<string | HtmlString | null, ComponentContext>): this;
48
+ /** Couleur de l'indication et de son icône (`gray` pour le texte, `primary` pour l'icône par défaut). */
49
+ hintColor(color: Lazy<string | null, ComponentContext>): this;
50
+ /** Icône d'indication, avec une infobulle facultative (qui sert aussi de nom accessible). */
51
+ hintIcon(name: Lazy<string | null, ComponentContext>, tooltip?: Lazy<string | null, ComponentContext>): this;
52
+ hintIconTooltip(tooltip: Lazy<string | null, ComponentContext>): this;
53
+ /** Action affichée après l'indication (en lien, petite taille), montée sur le champ. */
54
+ hintAction(action: Action): this;
55
+ hintActions(actions: Action[]): this;
56
+ getHintActions(): Action[];
57
+ /** Actions que le champ expose au montage (`schemaComponent` = clé du champ) : ici, ses actions d'indication. */
58
+ getActions(): Action[];
59
+ /** Rangée « après le libellé » : indication, icône d'indication et actions d'indication. */
60
+ protected renderAfterLabel(): Promise<string>;
61
+ /** Exécuté côté serveur quand l'état du champ change (champ `live()`). `set(nom, valeur)` modifie un autre champ du même formulaire. */
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
+ /** Force l'inclusion du champ dans les données envoyées, même désactivé (`->disabled()->dehydrated()`). */
68
+ dehydrated(condition?: boolean): this;
69
+ /** Par défaut, un champ désactivé n'est ni validé ni enregistré. */
70
+ isDehydrated(): Promise<boolean>;
71
+ getDefaultState(): unknown;
72
+ /** Mise en forme de la valeur d'un enregistrement quand elle entre dans le formulaire (hydratation). */
73
+ hydrateState(value: unknown): unknown;
74
+ rule(rule: Rule): this;
75
+ /** Règle `unique` : la valeur ne doit pas exister dans la colonne du même nom ; `ignoreRecord` exclut l'enregistrement en cours d'édition. */
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
+ /** Règles de validation : `required` d'abord, puis celles du champ. Les messages sont ceux de Laravel (en). */
86
+ getValidationRules(): Promise<Rule[]>;
87
+ validate(): Promise<string[]>;
88
+ /** Port de Field::wrapEmbeddedHtml (enveloppe par défaut). */
89
+ /** Valeur écrite dans les données à enregistrer (les champs composés n'y laissent qu'une ossature, remplie par leurs enfants). */
90
+ dehydrateState(state: unknown): unknown;
91
+ /** Dernière mise en forme de la valeur enregistrée, une fois les champs enfants dé-hydratés (liste d'éléments d'un Builder). */
92
+ finalizeDehydratedState(state: unknown): unknown;
93
+ protected wrap(html: string, options?: {
94
+ labelPrefix?: string;
95
+ wrapperClass?: string;
96
+ after?: string;
97
+ labelAsDiv?: boolean;
98
+ focusable?: boolean;
99
+ }): Promise<string>;
100
+ }
101
+ export declare class TextInput extends Field {
102
+ private _type;
103
+ private _isPassword;
104
+ private _isRevealable;
105
+ private _autocomplete;
106
+ private _maxLength;
107
+ private _minLength;
108
+ private _placeholder;
109
+ private _numeric;
110
+ private _minValue;
111
+ private _maxValue;
112
+ private _prefix;
113
+ private _live;
114
+ static make(name: string): TextInput;
115
+ /** Nombre décimal : `type="number"`, `step="any"`. */
116
+ numeric(): this;
117
+ /** Nombre entier : `type="number"`, `step="1"`. */
118
+ integer(): this;
119
+ private _step;
120
+ /** Pas de saisie d'un champ numérique (`step`), à la place de celui déduit de `numeric()` ou `integer()`. */
121
+ step(step: number | 'any' | null): this;
122
+ minValue(value: number): this;
123
+ maxValue(value: number): this;
124
+ /** Libellé affiché avant la zone de saisie (ex. `$`). */
125
+ prefix(label: string | null): this;
126
+ private _suffix;
127
+ /** Libellé affiché après la saisie (« hours », « kg »…). */
128
+ suffix(label: string | null): this;
129
+ /** L'état est envoyé au serveur à chaque frappe, ou à la perte de focus avec `onBlur`. */
130
+ live(options?: {
131
+ onBlur?: boolean;
132
+ }): this;
133
+ type(type: string): this;
134
+ password(condition?: boolean): this;
135
+ revealable(condition?: boolean): this;
136
+ /** `true` → "on", `false` → "off", chaîne → telle quelle (comme CanBeAutocompleted). */
137
+ autocomplete(value?: string | boolean): this;
138
+ placeholder(text: string | null): this;
139
+ /** Adresse web : champ de type `url`, valeur http(s) valide exigée. */
140
+ private _mask;
141
+ /** Masque de saisie Alpine (`(999) 999-9999`) : guide la frappe dans le navigateur, sans valeur de validation. */
142
+ mask(pattern: string | null): this;
143
+ /** Numéro de téléphone : chiffres, espaces et ponctuation usuelle. */
144
+ tel(): this;
145
+ url(): this;
146
+ maxLength(length: number): this;
147
+ minLength(length: number): this;
148
+ /** Port de TextInput::toEmbeddedHtml (sans affixes libres, masque ni datalist pour l'instant). */
149
+ toHtml(): Promise<string>;
150
+ }
151
+ /** Sélecteur de date natif (`<input type="date">`). Le sélecteur JavaScript de Filament n'est pas encore porté. */
152
+ export declare class DatePicker extends Field {
153
+ private _maxDate;
154
+ private _minDate;
155
+ private _live;
156
+ static make(name: string): DatePicker;
157
+ private _datePlaceholder;
158
+ /** Texte indicatif (les navigateurs ne l'affichent pas sur un champ `date` natif ; l'attribut est posé comme dans Filament). */
159
+ placeholder(text: string | null): this;
160
+ /** Envoie l'état au serveur dès qu'il change (`wire:model.live`). */
161
+ live(condition?: boolean): this;
162
+ /** Comme Filament : l'état d'un DatePicker est une date `AAAA-MM-JJ`, quelle que soit la précision stockée. */
163
+ hydrateState(value: unknown): unknown;
164
+ private static resolve;
165
+ private bound;
166
+ /** Date la plus tardive acceptée : `'today'`, une date `AAAA-MM-JJ`, ou une fonction du contexte (`({ get }) => get('endDate') || 'today'`). */
167
+ maxDate(date: Lazy<string | null, ComponentContext>): this;
168
+ minDate(date: Lazy<string | null, ComponentContext>): this;
169
+ toHtml(): Promise<string>;
170
+ }
171
+ type Options = [string, string][] | Record<string, string>;
172
+ /**
173
+ * Liste déroulante. Native (`<select>`) par défaut ; `searchable()` active le sélecteur JavaScript de Filament,
174
+ * qui interroge le serveur par les méthodes exposées (`getSearchResultsForJs`…).
175
+ */
176
+ export declare class Select extends Field {
177
+ private _options;
178
+ private _placeholder;
179
+ private _searchable;
180
+ private _dynamic;
181
+ private _searchOnServer;
182
+ private _live;
183
+ private _hasNoInitialOptions;
184
+ private _multiple;
185
+ private _optionLabelsUsing;
186
+ private _disableOptionWhen;
187
+ private _searchResultsUsing;
188
+ private _optionLabelUsing;
189
+ static make(name: string): Select;
190
+ /** Résultats de recherche calculés par le serveur à chaque frappe (sans liste d'options préchargée). */
191
+ getSearchResultsUsing(resolver: (search: string, ctx: ComponentContext) => Options | Promise<Options>): this;
192
+ /** Libellé d'une valeur ; sert aussi à valider qu'une valeur choisie par recherche existe bien. */
193
+ getOptionLabelUsing(resolver: (value: string, ctx: ComponentContext) => string | null | Promise<string | null>): this;
194
+ /** Options fixes, ou fonction (éventuellement asynchrone) évaluée à chaque requête. */
195
+ /** `dynamic: false` : options fournies par une fonction mais fixes pour la durée de la page (annoncées comme statiques au navigateur). */
196
+ /**
197
+ * `dynamic: false` : options fournies par une fonction mais fixes pour la durée de la page.
198
+ * `searchOnServer: false` : la recherche se fait dans le navigateur, parmi les options déjà envoyées (cas d'une liste complète).
199
+ */
200
+ options(options: Options | ((ctx: ComponentContext) => Options | Promise<Options>), config?: {
201
+ dynamic?: boolean;
202
+ searchOnServer?: boolean;
203
+ }): this;
204
+ /** Option non sélectionnable selon le contexte (par exemple déjà choisie dans une autre ligne). */
205
+ disableOptionWhen(condition: (value: string, ctx: ComponentContext) => boolean): this;
206
+ /** L'état est envoyé au serveur dès qu'il change. */
207
+ live(condition?: boolean): this;
208
+ placeholder(label: string | null): this;
209
+ private _selectablePlaceholder;
210
+ /** `false` : le sélecteur natif n'a pas d'option vide (port de `selectablePlaceholder()`). */
211
+ selectablePlaceholder(condition?: boolean): this;
212
+ searchable(condition?: boolean): this;
213
+ /** Sélection multiple : l'état est une liste de valeurs ; le sélecteur JavaScript est toujours utilisé. */
214
+ multiple(condition?: boolean): this;
215
+ isMultiple(): boolean;
216
+ /** Libellés de plusieurs valeurs d'un coup (sélection multiple avec recherche serveur) ; sert aussi à valider les valeurs. */
217
+ getOptionLabelsUsing(resolver: (values: string[], ctx: ComponentContext) => Options | Promise<Options>): this;
218
+ getDefaultState(): unknown;
219
+ /** Valeurs sélectionnées, nettoyées : des chaînes, sans doublon. */
220
+ private selectedValues;
221
+ private labelsOf;
222
+ /** Sans effet ici : les options sont toujours chargées avec le formulaire. */
223
+ preload(): this;
224
+ hydrateState(value: unknown): unknown;
225
+ dehydrateState(state: unknown): unknown;
226
+ resolveOptions(): Promise<[string, string][]>;
227
+ getValidationRules(): Promise<Rule[]>;
228
+ getExposedMethods(): string[];
229
+ private static forJs;
230
+ getOptionsForJs(): Promise<{
231
+ label: string;
232
+ value: string;
233
+ isDisabled: boolean;
234
+ }[]>;
235
+ private withDisabled;
236
+ getSearchResultsForJs(search?: unknown): Promise<{
237
+ label: string;
238
+ value: string;
239
+ isDisabled: boolean;
240
+ }[]>;
241
+ getOptionLabel(): Promise<string | null>;
242
+ getOptionLabelsForJs(): Promise<unknown[]>;
243
+ private _createOptionForm;
244
+ private _createOptionUsing;
245
+ private _createOptionModalHeading;
246
+ private _modifyCreateOptionAction;
247
+ private _editOptionForm;
248
+ private _updateOptionUsing;
249
+ private _fillEditOptionForm;
250
+ private _editOptionModalHeading;
251
+ private _modifyEditOptionAction;
252
+ /**
253
+ * Formulaire de la modale « Create » ouverte par le bouton « + » du champ. Sa validation est faite côté serveur ;
254
+ * `createOptionUsing()` enregistre l'option et rend sa valeur, qui devient l'état du champ (ajoutée à la liste pour un `multiple()`).
255
+ * Les options doivent être fournies par une fonction (`options(() => …)`, ou une recherche serveur) pour que la nouvelle valeur y figure.
256
+ */
257
+ createOptionForm(schema: Component[] | ((schema: Schema) => Component[] | Schema) | null): this;
258
+ /** Enregistre l'option à partir des données validées de la modale ; rend la valeur (clé) de l'option créée. */
259
+ createOptionUsing(callback: ((data: Record<string, unknown>, ctx: ComponentContext) => string | number | null | Promise<string | number | null>) | null): this;
260
+ createOptionModalHeading(heading: string | null): this;
261
+ /** Personnalise l'action de création (libellé, icône, largeur de modale…). */
262
+ createOptionAction(modify: ((action: Action) => Action | void) | null): this;
263
+ /**
264
+ * Formulaire de la modale « Edit » de l'option sélectionnée (sélection simple seulement). Le champ devient `live()` pour que le bouton
265
+ * apparaisse dès qu'une option est choisie. Préremplissage par `fillEditOptionActionFormUsing()`, enregistrement par `updateOptionUsing()`.
266
+ */
267
+ editOptionForm(schema: Component[] | ((schema: Schema) => Component[] | Schema) | null): this;
268
+ updateOptionUsing(callback: ((data: Record<string, unknown>, ctx: ComponentContext) => unknown) | null): this;
269
+ /** Données initiales de la modale « Edit » (le contexte donne l'état courant du champ dans `state`). */
270
+ fillEditOptionActionFormUsing(callback: ((ctx: ComponentContext) => Record<string, unknown> | null | Promise<Record<string, unknown> | null>) | null): this;
271
+ editOptionModalHeading(heading: string | null): this;
272
+ editOptionAction(modify: ((action: Action) => Action | void) | null): this;
273
+ /** Même formulaire pour la création et la modification. */
274
+ manageOptionForm(schema: Component[] | ((schema: Schema) => Component[] | Schema) | null): this;
275
+ private setState;
276
+ private getCreateOptionAction;
277
+ private getEditOptionAction;
278
+ /** Actions montées sur le champ : indication, création et modification d'option. */
279
+ getActions(): Action[];
280
+ /** Boutons « + » et « modifier » à droite du champ (port des suffixActions de Select). */
281
+ private suffixHtml;
282
+ toHtml(): Promise<string>;
283
+ /** Port du rendu JavaScript de Select::toEmbeddedHtml (sélection simple). */
284
+ private toJsHtml;
285
+ }
286
+ /** Colonne d'un Repeater en table : intitulé et largeur. */
287
+ export declare class TableColumn {
288
+ label: string;
289
+ private _width;
290
+ constructor(label: string);
291
+ static make(label: string): TableColumn;
292
+ width(width: number | string): this;
293
+ getWidth(): string | null;
294
+ }
295
+ type ItemLink = {
296
+ label: string;
297
+ icon: string;
298
+ url: string;
299
+ };
300
+ /**
301
+ * Liste d'éléments répétés, chacun avec les mêmes champs (port de Repeater, affichage en table).
302
+ * L'état est une table `clé d'élément → champs` ; l'ordre des clés est l'ordre d'affichage.
303
+ * Ajout, suppression et déplacement sont des actions du composant, montées avec `schemaComponent`.
304
+ */
305
+ export declare class Repeater extends Field {
306
+ private _schema;
307
+ private _columns;
308
+ private _defaultItems;
309
+ private _maxItems;
310
+ private _itemLinks;
311
+ static make(name: string): Repeater;
312
+ /** Champs d'un élément : une fonction, appelée pour chaque élément. */
313
+ schema(factory: () => Field[]): this;
314
+ /** Affichage en table, une colonne par champ. */
315
+ table(columns: TableColumn[]): this;
316
+ defaultItems(count: number): this;
317
+ maxItems(count: number): this;
318
+ private _reorderable;
319
+ /** Faux : les éléments gardent leur ordre (cas d'une relation sans colonne d'ordre dans Filament). */
320
+ reorderable(condition?: boolean): this;
321
+ /** Lien affiché sur chaque ligne (équivalent d'une action d'élément à URL). */
322
+ extraItemLink(resolver: (ctx: {
323
+ item: Record<string, unknown>;
324
+ key: string;
325
+ }) => ItemLink | null): this;
326
+ /** Éléments bien formés : les clés viennent du navigateur, seules les clés simples sont retenues. */
327
+ getItems(): Record<string, Record<string, unknown>>;
328
+ private setItems;
329
+ private itemDefaults;
330
+ getDefaultState(): unknown;
331
+ /** Enregistrements d'une relation → éléments `record-<id>`, réduits aux champs déclarés. */
332
+ hydrateState(value: unknown): unknown;
333
+ dehydrateState(): unknown;
334
+ getChildSchemas(): Schema[];
335
+ getValidationRules(): Promise<Rule[]>;
336
+ getActions(): Action[];
337
+ toHtml(): Promise<string>;
338
+ }
339
+ /** Zone de texte multiligne (port de Textarea, sans redimensionnement automatique). */
340
+ /** Heure (port de TimePicker, saisie native) : l'état est `HH:MM` avec `seconds(false)`, `HH:MM:SS` sinon. */
341
+ export declare class TimePicker extends Field {
342
+ private _seconds;
343
+ static make(name: string): TimePicker;
344
+ seconds(condition?: boolean): this;
345
+ hydrateState(value: unknown): unknown;
346
+ toHtml(): Promise<string>;
347
+ }
348
+ /** Date et heure (port de DateTimePicker, saisie native `datetime-local`) : l'état enregistré est `AAAA-MM-JJ HH:MM:SS`. */
349
+ export declare class DateTimePicker extends Field {
350
+ private _seconds;
351
+ static make(name: string): DateTimePicker;
352
+ seconds(condition?: boolean): this;
353
+ dehydrateState(state: unknown): unknown;
354
+ toHtml(): Promise<string>;
355
+ }
356
+ /** Choix unique en boutons radio (port de Radio). */
357
+ export declare class Radio extends Field {
358
+ private _options;
359
+ private _descriptions;
360
+ private _inline;
361
+ private _live;
362
+ static make(name: string): Radio;
363
+ options(options: Options): this;
364
+ /** Texte d'aide par valeur, sous le libellé de l'option. */
365
+ descriptions(descriptions: Record<string, string>): this;
366
+ /** Options côte à côte. */
367
+ inline(condition?: boolean): this;
368
+ live(condition?: boolean): this;
369
+ getValidationRules(): Promise<Rule[]>;
370
+ toHtml(): Promise<string>;
371
+ }
372
+ export declare class Textarea extends Field {
373
+ private _rows;
374
+ private _maxLength;
375
+ static make(name: string): Textarea;
376
+ rows(rows: number): this;
377
+ maxLength(length: number): this;
378
+ toHtml(): Promise<string>;
379
+ }
380
+ /** Saisie d'une liste de mots-clés (port de TagsInput) : l'état est un tableau de chaînes. */
381
+ export declare class TagsInput extends Field {
382
+ private _placeholder;
383
+ private _suggestions;
384
+ private _splitKeys;
385
+ static make(name: string): TagsInput;
386
+ placeholder(text: string | null): this;
387
+ /** Valeurs proposées à la saisie. */
388
+ suggestions(suggestions: string[]): this;
389
+ /** Touches qui valident le mot en cours, en plus d'Entrée (`['Tab', ',']`). */
390
+ splitKeys(keys: string[]): this;
391
+ getDefaultState(): unknown;
392
+ hydrateState(value: unknown): unknown;
393
+ /** Seules des chaînes non vides sont enregistrées, quelle que soit la forme reçue du navigateur. */
394
+ dehydrateState(state: unknown): unknown;
395
+ toHtml(): Promise<string>;
396
+ }
397
+ /** Interrupteur (port de Toggle). */
398
+ export declare class Toggle extends Field {
399
+ static make(name: string): Toggle;
400
+ getDefaultState(): unknown;
401
+ hydrateState(value: unknown): unknown;
402
+ toHtml(): Promise<string>;
403
+ }
404
+ /** Choix unique présenté en boutons (port de ToggleButtons, sélection simple). */
405
+ export declare class ToggleButtons extends Field {
406
+ private _options;
407
+ private _inline;
408
+ private _grouped;
409
+ private _colors;
410
+ private _icons;
411
+ static make(name: string): ToggleButtons;
412
+ private _live;
413
+ /** L'état est envoyé au serveur dès qu'il change. */
414
+ live(condition?: boolean): this;
415
+ /** Couleur par valeur (ex. celle d'une énumération). */
416
+ colors(colors: Record<string, string>): this;
417
+ /** Icône par valeur. */
418
+ icons(icons: Record<string, string>): this;
419
+ options(options: Options): this;
420
+ /** Boutons côte à côte. */
421
+ inline(condition?: boolean): this;
422
+ /** Boutons accolés en un seul groupe. */
423
+ grouped(condition?: boolean): this;
424
+ getValidationRules(): Promise<Rule[]>;
425
+ toHtml(): Promise<string>;
426
+ }
427
+ type RichDocument = {
428
+ type: 'doc';
429
+ content?: unknown[];
430
+ };
431
+ /** HTML enregistré → document TipTap. L'analyse écarte ce que le schéma ne connaît pas (scripts, attributs d'événement, liens `javascript:`). */
432
+ export declare function richHtmlToDocument(html: string | null | undefined): RichDocument;
433
+ /**
434
+ * Document TipTap → HTML à enregistrer, ou null s'il est vide ou invalide. Le document vient du navigateur :
435
+ * il est rendu puis ré-analysé, pour que seul ce que le schéma accepte soit conservé.
436
+ */
437
+ export declare function richDocumentToHtml(document: unknown): string | null;
438
+ /**
439
+ * Éditeur de texte riche (port de RichEditor) : le navigateur travaille sur un document TipTap, la base reçoit du HTML.
440
+ * Le balisage est celui de Filament, repris de l'oracle (vue générée). Non portés : pièces jointes, blocs personnalisés, mentions.
441
+ */
442
+ export declare class RichEditor extends Field {
443
+ static make(name: string): RichEditor;
444
+ hydrateState(value: unknown): unknown;
445
+ getDefaultState(): unknown;
446
+ dehydrateState(state: unknown): unknown;
447
+ getValidationRules(): Promise<Rule[]>;
448
+ getExposedMethods(): string[];
449
+ getMentionSearchResultsForJs(): unknown[];
450
+ getMentionLabelsForJs(): unknown[];
451
+ getCustomBlockPreviewsForJs(): unknown[];
452
+ getUploadedFileAttachmentTemporaryUrl(): null;
453
+ saveUploadedFileAttachmentAndGetUrl(): null;
454
+ /** Action « lien » de la barre d'outils : une modale (URL, nouvel onglet), puis des commandes renvoyées à l'éditeur du navigateur. */
455
+ getActions(): Action[];
456
+ toHtml(): Promise<string>;
457
+ }
458
+ /** Sélecteur de couleur (port de ColorPicker, format hexadécimal). */
459
+ export declare class ColorPicker extends Field {
460
+ static make(name: string): ColorPicker;
461
+ /** Format hexadécimal (le seul pris en charge ; présent pour la compatibilité d'API). */
462
+ hex(): this;
463
+ constructor(name: string);
464
+ toHtml(): Promise<string>;
465
+ }
466
+ export declare class Checkbox extends Field {
467
+ static make(name: string): Checkbox;
468
+ getDefaultState(): unknown;
469
+ toHtml(): Promise<string>;
470
+ }
471
+ /** Plusieurs cases à cocher pour une liste de valeurs (port de CheckboxList, sans recherche ni « tout cocher »). */
472
+ export declare class CheckboxList extends Field {
473
+ private _options;
474
+ private _optionColumns;
475
+ static make(name: string): CheckboxList;
476
+ options(options: Options): this;
477
+ /** Nombre de colonnes sur lesquelles les options se répartissent (à partir de `lg`). */
478
+ columns(columns: number | null): this;
479
+ getDefaultState(): unknown;
480
+ hydrateState(value: unknown): unknown;
481
+ /** Seules les valeurs proposées sont retenues, sans doublon, dans l'ordre des options. */
482
+ dehydrateState(state: unknown): unknown;
483
+ getValidationRules(): Promise<Rule[]>;
484
+ toHtml(): Promise<string>;
485
+ }
486
+ /** Paires clé / valeur libres, enregistrées comme un objet (port de KeyValue). */
487
+ export declare class KeyValue extends Field {
488
+ private _keyLabel;
489
+ private _valueLabel;
490
+ private _reorderable;
491
+ static make(name: string): KeyValue;
492
+ keyLabel(label: string): this;
493
+ valueLabel(label: string): this;
494
+ reorderable(condition?: boolean): this;
495
+ getDefaultState(): unknown;
496
+ private static toPairs;
497
+ hydrateState(value: unknown): unknown;
498
+ /** Objet plat de chaînes : clés vides, objets imbriqués et clés dangereuses sont écartés ; 200 paires au plus. */
499
+ dehydrateState(state: unknown): unknown;
500
+ toHtml(): Promise<string>;
501
+ }
502
+ /** Expression JavaScript écrite par le développeur (formateur d'infobulle d'un Slider…), insérée telle quelle : jamais de donnée utilisateur. */
503
+ export declare class RawJs {
504
+ readonly js: string;
505
+ constructor(js: string);
506
+ static make(js: string): RawJs;
507
+ toString(): string;
508
+ }
509
+ /**
510
+ * Éditeur Markdown (port de MarkdownEditor, éditeur EasyMDE de Filament). L'état est le texte Markdown brut, à nettoyer avant tout
511
+ * affichage en HTML. Non portés : pièces jointes (le bouton `attachFiles` est absent par défaut) ; en lecture seule (`disabled()`),
512
+ * le texte est affiché échappé, sans conversion Markdown.
513
+ */
514
+ export declare class MarkdownEditor extends Field {
515
+ private _toolbarButtons;
516
+ private _minHeight;
517
+ private _maxHeight;
518
+ private _placeholder;
519
+ private _live;
520
+ static make(name: string): MarkdownEditor;
521
+ /** Boutons de la barre d'outils, en groupes (`[['bold', 'italic'], ['undo', 'redo']]`) ou à plat. */
522
+ toolbarButtons(buttons: (string | string[])[]): this;
523
+ /** Retire des boutons ; sans argument, les retire tous. */
524
+ disableToolbarButtons(names?: string[]): this;
525
+ disableAllToolbarButtons(condition?: boolean): this;
526
+ /** Ajoute des boutons (dans un groupe à part). */
527
+ enableToolbarButtons(names: string[]): this;
528
+ getToolbarButtons(): (string | string[])[];
529
+ hasToolbarButton(name: string): boolean;
530
+ /** Hauteur minimale de la zone d'édition (`10rem` par défaut). */
531
+ minHeight(height: string | null): this;
532
+ maxHeight(height: string | null): this;
533
+ placeholder(text: string | null): this;
534
+ /** L'état est envoyé au serveur au fil de la frappe (`debounce` en millisecondes), ou à la perte de focus avec `onBlur`. */
535
+ live(options?: {
536
+ onBlur?: boolean;
537
+ debounce?: number | null;
538
+ }): this;
539
+ maxLength(length: number): this;
540
+ minLength(length: number): this;
541
+ hydrateState(value: unknown): unknown;
542
+ getValidationRules(): Promise<Rule[]>;
543
+ getExposedMethods(): string[];
544
+ getUploadedFileAttachmentTemporaryUrl(): null;
545
+ saveUploadedFileAttachmentAndGetUrl(): null;
546
+ toHtml(): Promise<string>;
547
+ }
548
+ /** Éditeur de code (port de CodeEditor, CodeMirror de Filament) : coloration selon `language()`, retour à la ligne avec `wrap()`. */
549
+ export declare class CodeEditor extends Field {
550
+ private _language;
551
+ private _canWrap;
552
+ private _live;
553
+ static make(name: string): CodeEditor;
554
+ /** Langage : `cpp`, `css`, `go`, `html`, `java`, `javascript`, `json`, `markdown`, `php`, `python`, `sql`, `xml`, `yaml`. */
555
+ language(language: string | null): this;
556
+ getLanguage(): string | null;
557
+ /**
558
+ * Retour à la ligne des lignes longues (port de `wrap()`). Appelée avec du HTML, c'est l'enveloppe de champ héritée,
559
+ * que le rendu du composant utilise.
560
+ */
561
+ wrap(condition?: any, options?: any): any;
562
+ canWrap(): boolean;
563
+ live(options?: {
564
+ onBlur?: boolean;
565
+ debounce?: number | null;
566
+ }): this;
567
+ hydrateState(value: unknown): unknown;
568
+ getValidationRules(): Promise<Rule[]>;
569
+ toHtml(): Promise<string>;
570
+ }
571
+ /**
572
+ * Curseur (port de Slider, noUiSlider de Filament) : une valeur, ou plusieurs poignées quand l'état est une liste (`default([20, 70])`).
573
+ * Obligatoire par défaut, comme dans Filament ; les bornes, le pas et le type numérique sont vérifiés côté serveur.
574
+ */
575
+ export declare class Slider extends Field {
576
+ private _minValue;
577
+ private _maxValue;
578
+ private _step;
579
+ private _minDifference;
580
+ private _maxDifference;
581
+ private _rangePadding;
582
+ private _fillTrack;
583
+ private _vertical;
584
+ private _rtl;
585
+ private _behavior;
586
+ private _tooltips;
587
+ private _pipsMode;
588
+ private _pipsDensity;
589
+ private _pipsFormatter;
590
+ private _pipsValues;
591
+ private _steppedPips;
592
+ private _pipsFilter;
593
+ private _nonLinearPoints;
594
+ private _decimalPlaces;
595
+ private _live;
596
+ constructor(name: string);
597
+ static make(name: string): Slider;
598
+ range(minValue: number, maxValue: number): this;
599
+ minValue(value: number): this;
600
+ maxValue(value: number): this;
601
+ /** Pas entre deux valeurs ; `1` impose un entier, sinon la valeur doit être un multiple du pas. */
602
+ step(step: number | null): this;
603
+ /** Écart minimal / maximal entre deux poignées. */
604
+ minDifference(difference: number | null): this;
605
+ maxDifference(difference: number | null): this;
606
+ /** Marge interdite aux extrémités : un nombre, ou `[début, fin]`. */
607
+ rangePadding(padding: number | [number, number] | null): this;
608
+ /** Segments colorés de la piste, un booléen par segment (`[true, false]` par défaut). */
609
+ fillTrack(fill?: boolean[] | null): this;
610
+ vertical(condition?: boolean): this;
611
+ /** De droite à gauche (de haut en bas pour un curseur vertical, ce qui est le réglage par défaut en vertical). */
612
+ rtl(condition?: boolean | null): this;
613
+ /** Comportement de la poignée (`tap`, `drag`, `fixed`, `snap`, `unconstrained`…) ; `null` : aucun. */
614
+ behavior(behavior?: string | string[] | null): this;
615
+ /** Infobulles sur les poignées : booléen, un booléen par poignée, ou `RawJs` qui formate `$value`. */
616
+ tooltips(tooltips?: boolean | RawJs | (boolean | RawJs)[]): this;
617
+ /** Graduations : `range` (par défaut), `steps`, `positions`, `count`, `values`. */
618
+ pips(mode?: string | null, density?: number | null): this;
619
+ pipsMode(mode: string | null): this;
620
+ pipsDensity(density: number | null): this;
621
+ /** Formatage des graduations (`RawJs` qui reçoit `$value`). */
622
+ pipsFormatter(formatter: RawJs | null): this;
623
+ pipsValues(values: number | number[] | null): this;
624
+ steppedPips(condition?: boolean): this;
625
+ /** Filtre des graduations (`RawJs` qui reçoit `$value`). */
626
+ pipsFilter(filter: RawJs | null): this;
627
+ /** Échelle non linéaire (`{ '10%': 500, '50%': 4000 }`). */
628
+ nonLinearPoints(points: Record<string, number | number[]> | null): this;
629
+ /** Nombre de décimales de la valeur enregistrée. */
630
+ decimalPlaces(places: number | null): this;
631
+ live(options?: {
632
+ onBlur?: boolean;
633
+ debounce?: number | null;
634
+ }): this;
635
+ getMinValueWithPadding(): number;
636
+ getMaxValueWithPadding(): number;
637
+ isMultiple(): boolean;
638
+ getDefaultState(): unknown;
639
+ private cast;
640
+ hydrateState(value: unknown): unknown;
641
+ dehydrateState(state: unknown): unknown;
642
+ getValidationRules(): Promise<Rule[]>;
643
+ /** Port de convertRawJsExpressionsToFormatterObjects : un `RawJs` devient `{ to: ($value) => … }`. */
644
+ private static formatters;
645
+ toHtml(): Promise<string>;
646
+ }
647
+ /** Champ caché (port de Hidden) : un `<input type="hidden">` lié à l'état, sans libellé ni place dans la grille. */
648
+ export declare class Hidden extends Field {
649
+ constructor(name: string);
650
+ static make(name: string): Hidden;
651
+ toHtml(): Promise<string>;
652
+ }
653
+ /** Code à usage unique (port de OneTimeCodeInput) : une case par chiffre ; l'état est la chaîne de chiffres, de longueur `length()` exactement. */
654
+ export declare class OneTimeCodeInput extends Field {
655
+ private _length;
656
+ private _submitOnCompletion;
657
+ private _readOnly;
658
+ constructor(name: string);
659
+ static make(name: string): OneTimeCodeInput;
660
+ /** Nombre de chiffres (6 par défaut). */
661
+ length(length: number): this;
662
+ getLength(): number;
663
+ /** Soumet le formulaire dès que le dernier chiffre est saisi. */
664
+ submitOnCompletion(condition?: boolean): this;
665
+ readOnly(condition?: boolean): this;
666
+ hydrateState(value: unknown): unknown;
667
+ toHtml(): Promise<string>;
668
+ }
669
+ /**
670
+ * Texte en lecture seule dans un formulaire (port de Placeholder, déprécié dans Filament au profit de TextEntry avec `state()`).
671
+ * Rien n'est enregistré. Une `HtmlString` est insérée telle quelle.
672
+ */
673
+ export declare class Placeholder extends Component {
674
+ private _label;
675
+ private _content;
676
+ private _hiddenLabel;
677
+ constructor(name: string);
678
+ static make(name: string): Placeholder;
679
+ hasStatePath(): boolean;
680
+ label(label: Lazy<string | null, ComponentContext>): this;
681
+ hiddenLabel(condition?: boolean): this;
682
+ content(content: Lazy<string | number | HtmlString | null, ComponentContext>): this;
683
+ toHtml(): Promise<string>;
684
+ }
685
+ /** Remplit l'état par défaut de tous les champs d'un schéma (équivalent de `$this->form->fill()`). */
686
+ export declare function fillSchema(schema: Schema, target: Record<string, unknown>): void;
687
+ /** Remplit l'état du formulaire à partir d'un enregistrement, champ par champ (équivalent de `$this->form->fill($record->attributesToArray())`). */
688
+ export declare function fillSchemaFromRecord(schema: Schema, target: Record<string, unknown>, record: Record<string, unknown>): void;
689
+ /** Valide tous les champs visibles d'un schéma ; retourne les erreurs par chemin d'état. */
690
+ export declare function validateSchema(schema: Schema): Promise<Record<string, string[]>>;
691
+ /** État à enregistrer : seulement les champs déclarés, visibles et « déshydratés » ; une chaîne vide vaut `null` (comme Laravel). */
692
+ export declare function getSchemaState(schema: Schema): Promise<Record<string, unknown>>;
693
+ type StepHook = (ctx: ComponentContext) => void | Promise<void>;
694
+ /** Lancée depuis `beforeValidation` / `afterValidation` d'une étape pour rester sur l'étape courante (équivalent de l'exception `Halt` de Filament). */
695
+ export declare class Halt extends Error {
696
+ constructor();
697
+ }
698
+ /** Une étape d'un assistant : un titre, une description et une icône facultatives, son propre schéma (port de Wizard\Step). */
699
+ export declare class Step extends Component {
700
+ private children;
701
+ private _columns;
702
+ private label;
703
+ private _description;
704
+ private _icon;
705
+ private _completedIcon;
706
+ private _beforeValidation;
707
+ private _afterValidation;
708
+ constructor(label: string);
709
+ static make(label: string): Step;
710
+ schema(components: Component[]): this;
711
+ columns(columns?: Record<string, number> | number | null): this;
712
+ description(description: string | null): this;
713
+ icon(name: string | null): this;
714
+ completedIcon(name: string | null): this;
715
+ /** Avant la validation de l'étape, au clic sur « Next » ; lever `Halt` pour rester sur l'étape. */
716
+ beforeValidation(callback: StepHook | null): this;
717
+ /** Après une validation réussie, avant de passer à l'étape suivante ; lever `Halt` pour rester sur l'étape. */
718
+ afterValidation(callback: StepHook | null): this;
719
+ getLabel(): string;
720
+ getDescription(): string | null;
721
+ getIcon(): string | null;
722
+ getCompletedIcon(): string | null;
723
+ callBeforeValidation(): Promise<void>;
724
+ callAfterValidation(): Promise<void>;
725
+ getChildSchemas(): Schema[];
726
+ toHtml(): Promise<string>;
727
+ /** Panneau de l'étape : un `<form>` quand l'assistant sait quoi soumettre (Entrée passe à l'étape suivante, ou enregistre à la dernière). */
728
+ toStepHtml(submitHandler: string | null, hasHeader: boolean): Promise<string>;
729
+ }
730
+ /**
731
+ * Assistant par étapes (port de Wizard) : toutes les étapes sont rendues, le navigateur n'affiche que l'étape courante.
732
+ * « Next » valide l'étape courante côté serveur avant d'avancer, sauf si l'assistant est `skippable()`.
733
+ */
734
+ export declare class Wizard extends Component {
735
+ private steps;
736
+ private _label;
737
+ private _skippable;
738
+ private _startStep;
739
+ private _contained;
740
+ private _headerHidden;
741
+ private _cancelAction;
742
+ private _submitAction;
743
+ private _alpineSubmitHandler;
744
+ private _stepQueryStringKey;
745
+ private _modifyNext;
746
+ private _modifyPrevious;
747
+ constructor(steps?: Step[]);
748
+ static make(steps?: Step[]): Wizard;
749
+ schema(steps: Step[]): this;
750
+ label(label: string | null): this;
751
+ /** Étapes accessibles dans n'importe quel ordre, sans validation au passage. */
752
+ skippable(condition?: boolean): this;
753
+ /** Étape affichée à l'ouverture (à partir de 1). */
754
+ startOnStep(step: number): this;
755
+ /** Faux : sans carte autour de l'assistant (c'est le cas sur une page de resource). */
756
+ contained(condition?: boolean): this;
757
+ hiddenHeader(condition?: boolean): this;
758
+ /** Action affichée à la place de « Back » sur la première étape. */
759
+ cancelAction(action: Action | null): this;
760
+ /** Action affichée à la place de « Next » sur la dernière étape. */
761
+ submitAction(action: Action | null): this;
762
+ /** Expression Alpine exécutée quand la dernière étape est soumise au clavier (ex. `$wire.create()`). */
763
+ alpineSubmitHandler(handler: string | null): this;
764
+ /** Garde l'étape courante dans l'adresse (`?step=…`). */
765
+ persistStepInQueryString(key?: string | null): this;
766
+ nextAction(modify: ((action: Action) => Action | void) | null): this;
767
+ previousAction(modify: ((action: Action) => Action | void) | null): this;
768
+ getKey(): string;
769
+ getExposedMethods(): string[];
770
+ /** « Next » redessine le composant : les erreurs de validation de l'étape doivent apparaître. */
771
+ isRenderlessMethod(): boolean;
772
+ getChildSchemas(): Schema[];
773
+ private getSteps;
774
+ /** Appelée par le navigateur au clic sur « Next » : valide l'étape courante, puis annonce l'étape suivante. */
775
+ nextStep(currentStepIndex?: unknown, currentStepKey?: unknown): Promise<void>;
776
+ /** Le retour en arrière se fait dans le navigateur ; la méthode existe pour le contrat de Filament. */
777
+ previousStep(): void;
778
+ toHtml(): Promise<string>;
779
+ }
780
+ /** Fichier temporaire reçu par le runtime (voir @navette-js/wire). */
781
+ export type TemporaryUpload = {
782
+ id: string;
783
+ path: string;
784
+ name: string;
785
+ type: string;
786
+ size: number;
787
+ extension: string;
788
+ };
789
+ export type UploadedFileInfo = {
790
+ name: string;
791
+ size: number;
792
+ type: string;
793
+ url: string;
794
+ };
795
+ /** Élément de l'état enregistré quand le champ ne stocke pas lui-même (`storeFiles(false)`) : fichier déjà enregistré, ou fichier temporaire à traiter. */
796
+ export type FileUploadEntry = {
797
+ key: string;
798
+ } | {
799
+ file: TemporaryUpload;
800
+ };
801
+ /** Où vont les fichiers une fois le formulaire enregistré. */
802
+ export interface FileStorage {
803
+ /** Enregistre un fichier temporaire et rend sa clé (chemin relatif). */
804
+ store(file: TemporaryUpload, directory: string | null): Promise<string>;
805
+ info(key: string): Promise<UploadedFileInfo | null>;
806
+ }
807
+ /** Stockage sur le disque local, servi sous une adresse publique. Le nom du fichier est aléatoire, son extension vient du type détecté. */
808
+ export declare class LocalFileStorage implements FileStorage {
809
+ private root;
810
+ private baseUrl;
811
+ constructor(root: string, baseUrl: string);
812
+ private resolve;
813
+ store(file: TemporaryUpload, directory: string | null): Promise<string>;
814
+ info(key: string): Promise<UploadedFileInfo | null>;
815
+ }
816
+ /**
817
+ * Téléversement de fichiers (port de FileUpload, rendu FilePond de Filament).
818
+ * État : `{ <clé de fichier>: <clé enregistrée> | 'livewire-file:<id temporaire>' }`. Une clé enregistrée n'est acceptée du navigateur
819
+ * que si elle figure déjà dans l'enregistrement en cours d'édition : on ne peut pas s'attribuer le fichier d'un autre.
820
+ */
821
+ export declare class FileUpload extends Field {
822
+ /** Stockage par défaut de l'application. */
823
+ static storage: FileStorage | null;
824
+ private _multiple;
825
+ private _maxFiles;
826
+ private _maxSize;
827
+ private _reorderable;
828
+ private _acceptedFileTypes;
829
+ private _directory;
830
+ private _storeFiles;
831
+ private _storage;
832
+ private _getUploadedFileUsing;
833
+ static make(name: string): FileUpload;
834
+ multiple(condition?: boolean): this;
835
+ maxFiles(count: number | null): this;
836
+ /** Taille maximale d'un fichier, en kilo-octets. */
837
+ maxSize(kilobytes: number | null): this;
838
+ reorderable(condition?: boolean): this;
839
+ /** Types MIME acceptés (`image/jpeg`, `image/*`…), vérifiés sur le contenu du fichier reçu. */
840
+ acceptedFileTypes(types: string[] | null): this;
841
+ image(): this;
842
+ directory(directory: string | null): this;
843
+ storage(storage: FileStorage): this;
844
+ /** `false` : le champ n'enregistre rien lui-même ; les données reçoivent des `FileUploadEntry`, à traiter par l'adaptateur (médias). */
845
+ storeFiles(condition?: boolean): this;
846
+ /** Informations d'un fichier déjà enregistré (nom, taille, type, adresse), quand elles ne viennent pas du stockage. */
847
+ getUploadedFileUsing(resolver: (key: string, ctx: ComponentContext) => UploadedFileInfo | null | Promise<UploadedFileInfo | null>): this;
848
+ getDefaultState(): unknown;
849
+ hydrateState(value: unknown): unknown;
850
+ private get uploads();
851
+ private getStorage;
852
+ /** Entrées de l'état, nettoyées : clé de fichier sûre, valeur chaîne. */
853
+ private entries;
854
+ /** Clés enregistrées que l'enregistrement en cours possède déjà : les seules qu'on accepte de relire depuis le navigateur. */
855
+ private originalKeys;
856
+ private isTemporary;
857
+ getExposedMethods(): string[];
858
+ getUploadedFiles(): Promise<Record<string, UploadedFileInfo | null>>;
859
+ private writeState;
860
+ /** Retire un fichier du champ. Le fichier enregistré n'est supprimé qu'à l'enregistrement du formulaire, par l'application. */
861
+ removeUploadedFile(fileKey: unknown): void;
862
+ deleteUploadedFile(fileKey: unknown): void;
863
+ reorderUploadedFiles(fileKeys: unknown): void;
864
+ getValidationRules(): Promise<Rule[]>;
865
+ /** La validation porte sur l'état entier, même vide (un champ obligatoire sans fichier doit échouer). */
866
+ validate(): Promise<string[]>;
867
+ /** À l'enregistrement : les fichiers temporaires sont stockés, les clés existantes non reconnues sont écartées. */
868
+ dehydrateState(): Promise<unknown>;
869
+ toHtml(): Promise<string>;
870
+ }
871
+ export {};