@satellatickets/core 0.1.0 → 0.2.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/dist/index.d.ts CHANGED
@@ -1,56 +1,24 @@
1
- import { ReactNode } from "react";
1
+
2
+ import { $ as useFormFieldControl, A as LinkUnderline, B as textVariants, C as UIProviderProps, D as useLink, E as UseLinkResult, F as TextVariant, G as useButton, H as useControllableState, I as TextVariantStyle, J as FormFieldControlOptions, K as FormFieldContext, L as textAligns, M as TextAlign, N as TextColorToken, O as LinkPressEvent, P as TextProps, Q as resolveFormFieldControl, R as textColors, S as ThemeMode, T as UseLinkOptions, U as UseButtonOptions, V as UseControllableStateOptions, W as UseButtonResult, X as FormFieldValueOptions, Y as FormFieldValue, Z as createFormFieldValue, _ as useBrand, a as ToastStore, b as useUIContext, c as ToastApi, d as FeedbackTone, f as feedbackTones, g as createUIContextValue, h as UIContextValue, i as TOAST_MAX_VISIBLE, j as linkUnderlines, k as LinkProps, l as ToastItem, m as UIContext, n as useToast, o as createToastStore, p as isFeedbackTone, q as FormFieldControl, r as TOAST_DEFAULT_DURATION, s as ToastAction, t as ToastContext, u as ToastOptions, v as useColorScheme, w as themeModes, x as ColorScheme, y as useTheme, z as textVariantStyles } from "./client-DpHlKasm.js";
2
3
  import { BrandName, Theme, ThemeName, ThemeOverrides } from "@satellatickets/tokens";
3
- //#region src/hooks/use-button.d.ts
4
- export interface UseButtonOptions {
4
+ import { ReactNode } from "react";
5
+ //#region src/tabs/navigation.d.ts
6
+ /** Lo mínimo que hace falta saber de una pestaña para moverse entre ellas. */
7
+ export interface NavigableTab {
8
+ value: string;
5
9
  disabled?: boolean | undefined;
6
- loading?: boolean | undefined;
7
- onPress?: (() => void) | undefined;
8
- }
9
- export interface UseButtonResult {
10
- disabled: boolean;
11
- loading: boolean;
12
- /** `false` si está deshabilitado o cargando: el botón no responde a la pulsación. */
13
- interactive: boolean;
14
- /** Llama a `onPress` solo si el botón es interactivo. */
15
- press: () => void;
16
- }
17
- /**
18
- * Comportamiento de `Button` común a web y nativo: un botón deshabilitado o que
19
- * está cargando no dispara `onPress`. Cada vista añade su accesibilidad
20
- * (`disabled`/`aria-busy` en web, `accessibilityState` en nativo).
21
- */
22
- export declare function useButton({ disabled, loading, onPress }: UseButtonOptions): UseButtonResult;
23
- //#endregion
24
- //#region src/types/ui-provider.d.ts
25
- /** Modo de tema que acepta `UIProvider` (ADR-010). */
26
- export declare const themeModes: readonly ["light", "dark", "system"];
27
- export type ThemeMode = (typeof themeModes)[number];
28
- /** Esquema resuelto: siempre uno de los temas definidos en tokens. */
29
- export type ColorScheme = ThemeName;
30
- export interface UIProviderProps {
31
- /** Tema claro, oscuro o el del sistema (por defecto `system`). */
32
- theme?: ThemeMode | undefined;
33
- /** Marca registrada en tokens. Sin marca se usa la identidad por defecto. */
34
- brand?: BrandName | undefined;
35
- children: ReactNode;
36
- }
37
- //#endregion
38
- //#region src/theme/context.d.ts
39
- interface UIContextValue {
40
- theme: Theme;
41
- colorScheme: ColorScheme;
42
- mode: ThemeMode;
43
- brand: BrandName | undefined;
44
10
  }
45
- export declare function createUIContextValue(mode: ThemeMode, systemScheme: ColorScheme, brand?: BrandName): UIContextValue;
46
- /** Sin `UIProvider` se usa el tema claro por defecto, para que los componentes funcionen aislados. */
47
- export declare const UIContext: import("react").Context<UIContextValue>;
48
- export declare function useUIContext(): UIContextValue;
49
- /** Tema resuelto (tokens con la marca aplicada). Imprescindible en las vistas nativas (ADR-008). */
50
- export declare function useTheme(): Theme;
51
- /** `'light' | 'dark'` ya resuelto, también con `theme="system"`. */
52
- export declare function useColorScheme(): ColorScheme;
53
- export declare function useBrand(): BrandName | undefined;
11
+ /** Hacia dónde mueve el foco una tecla: flechas, Inicio y Fin. */
12
+ export declare const tabDirections: readonly ["next", "previous", "first", "last"];
13
+ export type TabDirection = (typeof tabDirections)[number];
14
+ /** La primera pestaña habilitada: la elegida por defecto. `undefined` si no hay ninguna. */
15
+ export declare function firstEnabledTab(items: readonly NavigableTab[]): string | undefined;
16
+ /**
17
+ * La pestaña a la que lleva una tecla desde la actual, saltando las deshabilitadas.
18
+ * `next` y `previous` dan la vuelta al llegar al final. Si no hay otra a la que ir,
19
+ * devuelve la actual.
20
+ */
21
+ export declare function getTabInDirection(items: readonly NavigableTab[], current: string, direction: TabDirection): string;
54
22
  //#endregion
55
23
  //#region src/theme/resolve-theme.d.ts
56
24
  /** Combina los overrides de una marca sobre un tema (ADR-010). Los arrays (sombras) se sustituyen enteros. */
@@ -59,6 +27,37 @@ export declare function mergeTheme(base: Theme, overrides: ThemeOverrides): Them
59
27
  export declare function resolveTheme(scheme: ThemeName, brand?: BrandName): Theme;
60
28
  export declare function resolveColorScheme(mode: ThemeMode, systemScheme: ColorScheme): ColorScheme;
61
29
  //#endregion
30
+ //#region src/types/alert.d.ts
31
+ interface AlertBaseProps {
32
+ /** Qué comunica (por defecto `info`). Fija el color y el icono. */
33
+ tone?: FeedbackTone | undefined;
34
+ /** Resumen en una línea. */
35
+ title?: string | undefined;
36
+ /** Explicación o siguiente paso. */
37
+ children?: ReactNode;
38
+ /** `data-testid` en web, `testID` en nativo. */
39
+ testID?: string | undefined;
40
+ }
41
+ interface AlertStaticProps extends AlertBaseProps {
42
+ onClose?: undefined;
43
+ closeLabel?: undefined;
44
+ }
45
+ interface AlertClosableProps extends AlertBaseProps {
46
+ /** Si existe, el aviso muestra un botón para cerrarlo y la llama al pulsarlo. */
47
+ onClose: () => void;
48
+ /**
49
+ * Nombre accesible del botón de cierre ("Cerrar aviso"). Es obligatorio con
50
+ * `onClose`: la librería no trae textos propios.
51
+ */
52
+ closeLabel: string;
53
+ }
54
+ /**
55
+ * Contrato de `Alert`: un mensaje dentro de la página que no desaparece solo. `danger`
56
+ * y `warning` se anuncian de inmediato a los lectores de pantalla; `success` e `info`,
57
+ * cuando terminan lo que estén leyendo.
58
+ */
59
+ export type AlertProps = AlertStaticProps | AlertClosableProps;
60
+ //#endregion
62
61
  //#region src/types/badge.d.ts
63
62
  /**
64
63
  * Variantes de `Badge` (ADR-009): una por cada color de `color.feedback`. Las historias
@@ -146,46 +145,123 @@ export interface ButtonProps<IconName extends string = string> {
146
145
  children: ReactNode;
147
146
  }
148
147
  //#endregion
149
- //#region src/types/text.d.ts
150
- export declare const textVariants: readonly ["hero", "display", "title", "heading", "subheading", "body", "bodySmall", "label", "caption", "code"];
151
- export type TextVariant = (typeof textVariants)[number];
152
- export type TextColorToken = keyof Theme['color']['text'];
153
- export declare const textColors: TextColorToken[];
154
- export declare const textAligns: readonly ["left", "center", "right"];
155
- export type TextAlign = (typeof textAligns)[number];
156
- /** Tokens que componen una variante tipográfica; ambas vistas los leen del tema. */
157
- export interface TextVariantStyle {
158
- family: keyof Theme['font']['family'];
159
- /** Tamaño; `font.lineHeight` comparte las mismas claves (lo comprueba el typecheck de las vistas). */
160
- size: keyof Theme['font']['size'];
161
- weight: keyof Theme['font']['weight'];
162
- uppercase?: boolean;
163
- /** Espaciado entre letras en px. */
164
- letterSpacing?: number;
165
- /** Nivel de encabezado semántico (h1–h4) si la variante es un título. */
166
- headingLevel?: 1 | 2 | 3 | 4;
167
- }
168
- /** Escala tipográfica de Satella: Unbounded para titulares, Hanken Grotesk para texto, IBM Plex Mono para etiquetas. */
169
- export declare const textVariantStyles: Readonly<Record<TextVariant, TextVariantStyle>>;
170
- export interface TextProps {
171
- variant?: TextVariant | undefined;
172
- color?: TextColorToken | undefined;
173
- align?: TextAlign | undefined;
174
- /** Una sola línea con puntos suspensivos. */
175
- truncate?: boolean | undefined;
148
+ //#region src/types/card.d.ts
149
+ /**
150
+ * Variantes de `Card` (ADR-009): `outlined` se apoya en el borde; `elevated` añade
151
+ * sombra para separarse de lo que tiene debajo.
152
+ */
153
+ export declare const cardVariants: readonly ["outlined", "elevated"];
154
+ export type CardVariant = (typeof cardVariants)[number];
155
+ /**
156
+ * Contrato de `Card`: una superficie que agrupa contenido relacionado. Con `onPress`
157
+ * toda la tarjeta es pulsable; en ese caso no debe contener otros controles.
158
+ */
159
+ export interface CardProps {
160
+ variant?: CardVariant | undefined;
161
+ /** Relleno interior (por defecto 4). Con `0`, el contenido llega hasta el borde, por ejemplo una imagen. */
162
+ padding?: SpaceToken | undefined;
163
+ /** Hace pulsable toda la tarjeta, con ratón, teclado o toque. */
164
+ onPress?: (() => void) | undefined;
165
+ /**
166
+ * Nombre accesible de una tarjeta pulsable. Sin él, es su contenido, que suele ser lo
167
+ * correcto. Si se indica, tiene que incluir el texto visible: quien navega por voz
168
+ * dice lo que ve.
169
+ */
170
+ accessibilityLabel?: string | undefined;
171
+ /** `data-testid` en web, `testID` en nativo. */
172
+ testID?: string | undefined;
173
+ children?: ReactNode;
174
+ }
175
+ //#endregion
176
+ //#region src/types/checkbox.d.ts
177
+ /** Contrato de `Checkbox`: una opción que se marca o no, con su etiqueta como `children`. */
178
+ export interface CheckboxProps {
179
+ /** Estado controlado por la app. Sin él, guarda su propio estado (ADR-037). */
180
+ checked?: boolean | undefined;
181
+ /** Estado inicial cuando guarda su propio estado. */
182
+ defaultChecked?: boolean | undefined;
183
+ /**
184
+ * Ni marcado ni sin marcar: representa a un grupo donde solo algunas opciones lo
185
+ * están. Es solo visual; al pulsarlo pasa a marcado o sin marcar según `checked`.
186
+ */
187
+ indeterminate?: boolean | undefined;
188
+ /** Se llama con el estado nuevo al pulsarlo. */
189
+ onCheckedChange?: ((checked: boolean) => void) | undefined;
190
+ /** No se puede pulsar ni enfocar. */
191
+ disabled?: boolean | undefined;
192
+ /** El estado no es válido, por ejemplo unas condiciones sin aceptar. */
193
+ invalid?: boolean | undefined;
194
+ required?: boolean | undefined;
195
+ /** Nombre accesible cuando no hay etiqueta visible. */
196
+ accessibilityLabel?: string | undefined;
197
+ /** `data-testid` en web, `testID` en nativo. */
176
198
  testID?: string | undefined;
199
+ /** Etiqueta. Pulsarla también marca la casilla. */
177
200
  children?: ReactNode;
178
201
  }
179
202
  //#endregion
203
+ //#region src/types/control.d.ts
204
+ /**
205
+ * Alturas de los controles interactivos de una línea (`Input`, `Select`). Coinciden
206
+ * con `size.control` de los tokens y con los tamaños de `Button`, para que un campo y
207
+ * un botón del mismo tamaño queden alineados en una fila.
208
+ */
209
+ export declare const controlSizes: readonly ["sm", "md", "lg"];
210
+ export type ControlSize = (typeof controlSizes)[number];
211
+ //#endregion
212
+ //#region src/types/divider.d.ts
213
+ /** Orientación de `Divider` (ADR-009). */
214
+ export declare const dividerOrientations: readonly ["horizontal", "vertical"];
215
+ export type DividerOrientation = (typeof dividerOrientations)[number];
216
+ /** Contrato de `Divider`: una línea fina que separa dos bloques de contenido. */
217
+ export interface DividerProps {
218
+ /**
219
+ * `horizontal` (por defecto) separa bloques apilados. `vertical` separa elementos de
220
+ * una fila y ocupa su altura.
221
+ */
222
+ orientation?: DividerOrientation | undefined;
223
+ /** `data-testid` en web, `testID` en nativo. */
224
+ testID?: string | undefined;
225
+ }
226
+ //#endregion
227
+ //#region src/types/form-field.d.ts
228
+ /**
229
+ * Contrato de `FormField`: la etiqueta, la ayuda y el error de un control, enlazados
230
+ * con él para los lectores de pantalla (ADR-037). Envuelve un `Input`, un `TextArea`
231
+ * o un `Select`.
232
+ */
233
+ export interface FormFieldProps {
234
+ /** Etiqueta visible. Es texto porque en nativo hace de nombre accesible del control. */
235
+ label: string;
236
+ /** Ayuda bajo el control: formato esperado, para qué se usa el dato. */
237
+ help?: string | undefined;
238
+ /** Mensaje de error. Si existe, el control se marca como inválido. */
239
+ error?: string | undefined;
240
+ /** Marca la etiqueta como obligatoria y lo comunica al control. */
241
+ required?: boolean | undefined;
242
+ /** Deshabilita el control. */
243
+ disabled?: boolean | undefined;
244
+ /** `data-testid` en web, `testID` en nativo. */
245
+ testID?: string | undefined;
246
+ /** El control. */
247
+ children: ReactNode;
248
+ }
249
+ //#endregion
180
250
  //#region src/types/icon.d.ts
181
- export declare const iconSizes: readonly ["sm", "md", "lg"];
251
+ export declare const iconSizes: readonly ["sm", "md", "lg", "xl"];
182
252
  export type IconSize = (typeof iconSizes)[number];
183
253
  /** Tamaño en px/puntos de cada icono. */
184
254
  export declare const iconSizePx: {
185
255
  sm: number;
186
256
  md: number;
187
257
  lg: number;
258
+ xl: number;
188
259
  };
260
+ /**
261
+ * Color de un icono: un color de texto o el de un estado de feedback (`success`,
262
+ * `warning`, `danger`, `info`), que usa el token `color.feedback.<estado>.icon`.
263
+ */
264
+ export type IconColor = TextColorToken | FeedbackTone;
189
265
  /**
190
266
  * Contrato de `Icon`. El conjunto de nombres lo aporta `@satellatickets/icons`,
191
267
  * que está fuera de `core` (ADR-002), por eso el nombre es un parámetro de tipo.
@@ -193,24 +269,214 @@ export declare const iconSizePx: {
193
269
  export interface IconProps<Name extends string = string> {
194
270
  name: Name;
195
271
  size?: IconSize | undefined;
196
- color?: TextColorToken | undefined;
272
+ color?: IconColor | undefined;
197
273
  /** Texto alternativo. Sin él, el icono es decorativo y se oculta a los lectores de pantalla. */
198
274
  label?: string | undefined;
199
275
  testID?: string | undefined;
200
276
  }
201
277
  //#endregion
278
+ //#region src/types/icon-button.d.ts
279
+ /**
280
+ * Tamaño del icono para cada tamaño de `IconButton`. Es un paso mayor que en
281
+ * `Button`, porque aquí el icono es todo el contenido.
282
+ */
283
+ export declare const iconButtonIconSize: {
284
+ readonly sm: "sm";
285
+ readonly md: "md";
286
+ readonly lg: "lg";
287
+ };
288
+ /**
289
+ * Contrato de `IconButton`: un `Button` cuadrado cuyo único contenido es un icono.
290
+ * Comparte variantes y tamaños con `Button` (`buttonVariants`). El conjunto de iconos
291
+ * lo aporta `@satellatickets/icons`, que está fuera de `core` (ADR-002), por eso el
292
+ * nombre es un parámetro de tipo.
293
+ */
294
+ export interface IconButtonProps<IconName extends string = string> {
295
+ icon: IconName;
296
+ /**
297
+ * Nombre accesible. Es obligatorio porque no hay texto visible: describe la
298
+ * acción ("Cerrar"), no el dibujo ("Aspa").
299
+ */
300
+ label: string;
301
+ /** Jerarquía visual de la acción (por defecto `ghost`). */
302
+ variant?: ButtonVariant | undefined;
303
+ size?: ButtonSize | undefined;
304
+ /** No se puede pulsar ni enfocar. */
305
+ disabled?: boolean | undefined;
306
+ /** Acción en curso: sustituye el icono por un spinner y no dispara `onPress`, pero conserva el foco. */
307
+ loading?: boolean | undefined;
308
+ /** Se pulsa con ratón, teclado o toque. Nombre neutral: la vista web lo mapea a `click`. */
309
+ onPress?: (() => void) | undefined;
310
+ /** `data-testid` en web, `testID` en nativo. */
311
+ testID?: string | undefined;
312
+ }
313
+ //#endregion
314
+ //#region src/types/input.d.ts
315
+ /**
316
+ * Qué se escribe en un `Input` (ADR-009). Cada vista lo traduce a su plataforma:
317
+ * el atributo `type` y el teclado en web, y el teclado, las mayúsculas automáticas
318
+ * y el autocompletado en nativo.
319
+ */
320
+ export declare const inputTypes: readonly ["text", "email", "password", "search", "tel", "url", "number"];
321
+ export type InputType = (typeof inputTypes)[number];
322
+ /** Tamaño de los iconos de un `Input` para cada tamaño de campo. */
323
+ export declare const inputIconSize: {
324
+ readonly sm: "sm";
325
+ readonly md: "md";
326
+ readonly lg: "md";
327
+ };
328
+ /**
329
+ * Contrato de `Input`: un campo de texto de una línea. El conjunto de iconos lo aporta
330
+ * `@satellatickets/icons`, que está fuera de `core` (ADR-002), por eso el nombre es
331
+ * un parámetro de tipo.
332
+ */
333
+ export interface InputProps<IconName extends string = string> {
334
+ /** Texto controlado por la app. Sin él, el campo guarda su propio estado (ADR-037). */
335
+ value?: string | undefined;
336
+ /** Texto inicial cuando el campo guarda su propio estado. */
337
+ defaultValue?: string | undefined;
338
+ /** Se llama con el texto nuevo en cada cambio. */
339
+ onChangeText?: ((text: string) => void) | undefined;
340
+ placeholder?: string | undefined;
341
+ /** Qué se escribe (por defecto `text`). */
342
+ type?: InputType | undefined;
343
+ size?: ControlSize | undefined;
344
+ /** No se puede editar ni enfocar. */
345
+ disabled?: boolean | undefined;
346
+ /** Se puede enfocar y copiar, pero no editar. */
347
+ readOnly?: boolean | undefined;
348
+ /** El valor no es válido. Dentro de un `FormField` con `error` se activa solo. */
349
+ invalid?: boolean | undefined;
350
+ required?: boolean | undefined;
351
+ /** Icono decorativo delante del texto. */
352
+ iconStart?: IconName | undefined;
353
+ /** Icono decorativo detrás del texto. */
354
+ iconEnd?: IconName | undefined;
355
+ maxLength?: number | undefined;
356
+ onFocus?: (() => void) | undefined;
357
+ onBlur?: (() => void) | undefined;
358
+ /** Se pulsa Intro, o la tecla de envío del teclado en pantalla. */
359
+ onSubmit?: (() => void) | undefined;
360
+ /** Nombre accesible cuando no hay un `FormField` que lo etiquete. */
361
+ accessibilityLabel?: string | undefined;
362
+ /** `data-testid` en web, `testID` en nativo. */
363
+ testID?: string | undefined;
364
+ }
365
+ //#endregion
366
+ //#region src/types/modal.d.ts
367
+ /**
368
+ * Contrato de `Modal` y de `Sheet` (ADR-040): un diálogo que interrumpe lo que hay
369
+ * debajo. `Modal` se centra; `Sheet` se ancla al borde inferior.
370
+ */
371
+ export interface ModalProps {
372
+ /** Si está abierto. Lo decide la app. */
373
+ open: boolean;
374
+ /**
375
+ * El diálogo pide cerrarse: Escape, pulsar fuera, el botón atrás de Android o su
376
+ * botón de cierre. La app responde poniendo `open` a `false`.
377
+ */
378
+ onClose: () => void;
379
+ /** Título visible. Es también su nombre accesible. */
380
+ title: string;
381
+ /** Texto bajo el título. Los lectores de pantalla lo leen al abrirse. */
382
+ description?: string | undefined;
383
+ /**
384
+ * Si existe, muestra un botón de cierre con este nombre accesible ("Cerrar"). La
385
+ * librería no trae textos propios.
386
+ */
387
+ closeLabel?: string | undefined;
388
+ /**
389
+ * Con `false`, ni Escape, ni pulsar fuera, ni el botón atrás lo cierran: es para una
390
+ * pregunta que exige respuesta. Por defecto `true`.
391
+ */
392
+ dismissible?: boolean | undefined;
393
+ /** Acciones al pie, normalmente botones. */
394
+ footer?: ReactNode;
395
+ /** `data-testid` en web, `testID` en nativo. */
396
+ testID?: string | undefined;
397
+ children?: ReactNode;
398
+ }
399
+ /** `Sheet` tiene el mismo contrato que `Modal`: solo cambia dónde se coloca. */
400
+ export type SheetProps = ModalProps;
401
+ /** Las dos presentaciones de un diálogo. */
402
+ export declare const modalPresentations: readonly ["dialog", "sheet"];
403
+ export type ModalPresentation = (typeof modalPresentations)[number];
404
+ //#endregion
405
+ //#region src/types/select.d.ts
406
+ /** Una opción de `Select`. */
407
+ export interface SelectOption {
408
+ /** Lo que recibe `onValueChange`. No puede ser una cadena vacía: eso es "sin elegir". */
409
+ value: string;
410
+ /** Lo que se muestra. */
411
+ label: string;
412
+ disabled?: boolean | undefined;
413
+ }
414
+ /** Contrato de `Select`: elegir una opción de una lista (ADR-038). */
415
+ export interface SelectProps {
416
+ options: readonly SelectOption[];
417
+ /** Opción elegida, controlada por la app. Sin ella, guarda su propio estado (ADR-037). */
418
+ value?: string | undefined;
419
+ /** Opción inicial cuando guarda su propio estado. */
420
+ defaultValue?: string | undefined;
421
+ /** Se llama con el `value` de la opción elegida. */
422
+ onValueChange?: ((value: string) => void) | undefined;
423
+ /** Texto que se muestra mientras no hay ninguna opción elegida. */
424
+ placeholder?: string | undefined;
425
+ size?: ControlSize | undefined;
426
+ /** No se puede abrir ni enfocar. */
427
+ disabled?: boolean | undefined;
428
+ /** El valor no es válido. Dentro de un `FormField` con `error` se activa solo. */
429
+ invalid?: boolean | undefined;
430
+ required?: boolean | undefined;
431
+ /** Nombre accesible cuando no hay un `FormField` que lo etiquete. */
432
+ accessibilityLabel?: string | undefined;
433
+ /** `data-testid` en web, `testID` en nativo. */
434
+ testID?: string | undefined;
435
+ }
436
+ //#endregion
437
+ //#region src/types/skeleton.d.ts
438
+ /**
439
+ * Formas de `Skeleton` (ADR-009): `text` ocupa el hueco de una línea de `Text`,
440
+ * `rectangle` el de una imagen o un control, y `circle` el de un avatar.
441
+ */
442
+ export declare const skeletonShapes: readonly ["text", "rectangle", "circle"];
443
+ export type SkeletonShape = (typeof skeletonShapes)[number];
444
+ /**
445
+ * Contrato de `Skeleton`: el hueco de un contenido que todavía se está cargando. Es
446
+ * decorativo; que la zona está cargando lo comunica quien lo contiene.
447
+ */
448
+ export interface SkeletonProps {
449
+ /** Forma (por defecto `text`). */
450
+ shape?: SkeletonShape | undefined;
451
+ /**
452
+ * Ancho, en puntos o como porcentaje del contenedor (`'60%'`). Por defecto ocupa
453
+ * todo el ancho; en `circle`, mide lo mismo que de alto.
454
+ */
455
+ width?: number | `${number}%` | undefined;
456
+ /** Alto en puntos. En `text` no se usa: lo fija `variant`. */
457
+ height?: number | undefined;
458
+ /** Con `text`: la variante de `Text` cuyo hueco ocupa (por defecto `body`). */
459
+ variant?: TextVariant | undefined;
460
+ /** Con `text`: número de líneas (por defecto 1). Si hay varias, la última es más corta. */
461
+ lines?: number | undefined;
462
+ /** `data-testid` en web, `testID` en nativo. */
463
+ testID?: string | undefined;
464
+ }
465
+ //#endregion
202
466
  //#region src/types/spinner.d.ts
203
467
  /**
204
468
  * `Spinner` comparte la escala de `Icon`: así puede ocupar el sitio de un icono
205
469
  * (por ejemplo, dentro de un botón que carga) sin mover el resto del contenido.
470
+ * `xl` es para la carga de una página o de una sección entera.
206
471
  */
207
- export declare const spinnerSizes: readonly ["sm", "md", "lg"];
472
+ export declare const spinnerSizes: readonly ["sm", "md", "lg", "xl"];
208
473
  export type SpinnerSize = IconSize;
209
474
  /** Tamaño en px/puntos de cada spinner. */
210
475
  export declare const spinnerSizePx: {
211
476
  sm: number;
212
477
  md: number;
213
478
  lg: number;
479
+ xl: number;
214
480
  };
215
481
  export interface SpinnerProps {
216
482
  size?: SpinnerSize | undefined;
@@ -239,4 +505,89 @@ export interface StackProps extends BoxProps {
239
505
  wrap?: boolean | undefined;
240
506
  }
241
507
  //#endregion
242
- export type { UIContextValue };
508
+ //#region src/types/switch.d.ts
509
+ /**
510
+ * Contrato de `Switch`: un ajuste que se activa o desactiva con efecto inmediato.
511
+ * Para una opción que se confirma al enviar un formulario, usa `Checkbox`.
512
+ */
513
+ export interface SwitchProps {
514
+ /** Estado controlado por la app. Sin él, guarda su propio estado (ADR-037). */
515
+ checked?: boolean | undefined;
516
+ /** Estado inicial cuando guarda su propio estado. */
517
+ defaultChecked?: boolean | undefined;
518
+ /** Se llama con el estado nuevo al pulsarlo. */
519
+ onCheckedChange?: ((checked: boolean) => void) | undefined;
520
+ /** No se puede pulsar ni enfocar. */
521
+ disabled?: boolean | undefined;
522
+ /** Nombre accesible cuando no hay etiqueta visible. */
523
+ accessibilityLabel?: string | undefined;
524
+ /** `data-testid` en web, `testID` en nativo. */
525
+ testID?: string | undefined;
526
+ /** Etiqueta. Pulsarla también cambia el interruptor. */
527
+ children?: ReactNode;
528
+ }
529
+ //#endregion
530
+ //#region src/types/tabs.d.ts
531
+ /** Una pestaña de `Tabs`. */
532
+ export interface TabItem<IconName extends string = string> {
533
+ /** Lo que recibe `onValueChange`. */
534
+ value: string;
535
+ /** Texto de la pestaña. */
536
+ label: string;
537
+ /** Icono decorativo delante del texto. */
538
+ icon?: IconName | undefined;
539
+ disabled?: boolean | undefined;
540
+ /**
541
+ * Contenido de su panel. Sin él, `Tabs` solo pinta las pestañas y la app decide qué
542
+ * mostrar con `value`, por ejemplo para filtrar una lista.
543
+ */
544
+ content?: ReactNode;
545
+ }
546
+ /**
547
+ * Contrato de `Tabs`: varias vistas del mismo nivel entre las que se cambia sin salir de
548
+ * la página. El conjunto de iconos lo aporta `@satellatickets/icons`, que está fuera de
549
+ * `core` (ADR-002), por eso el nombre es un parámetro de tipo.
550
+ */
551
+ export interface TabsProps<IconName extends string = string> {
552
+ items: readonly TabItem<IconName>[];
553
+ /** Pestaña elegida, controlada por la app. Sin ella, guarda su propio estado (ADR-037). */
554
+ value?: string | undefined;
555
+ /** Pestaña inicial cuando guarda su propio estado. Por defecto, la primera habilitada. */
556
+ defaultValue?: string | undefined;
557
+ /** Se llama con el `value` de la pestaña elegida. */
558
+ onValueChange?: ((value: string) => void) | undefined;
559
+ /** Nombre accesible del grupo de pestañas ("Mis entradas"). */
560
+ accessibilityLabel?: string | undefined;
561
+ /** `data-testid` en web, `testID` en nativo. */
562
+ testID?: string | undefined;
563
+ }
564
+ //#endregion
565
+ //#region src/types/text-area.d.ts
566
+ /** Contrato de `TextArea`: un campo de texto de varias líneas. */
567
+ export interface TextAreaProps {
568
+ /** Texto controlado por la app. Sin él, el campo guarda su propio estado (ADR-037). */
569
+ value?: string | undefined;
570
+ /** Texto inicial cuando el campo guarda su propio estado. */
571
+ defaultValue?: string | undefined;
572
+ /** Se llama con el texto nuevo en cada cambio. */
573
+ onChangeText?: ((text: string) => void) | undefined;
574
+ placeholder?: string | undefined;
575
+ /** Líneas visibles sin desplazarse (por defecto 3). Fija la altura mínima. */
576
+ rows?: number | undefined;
577
+ /** No se puede editar ni enfocar. */
578
+ disabled?: boolean | undefined;
579
+ /** Se puede enfocar y copiar, pero no editar. */
580
+ readOnly?: boolean | undefined;
581
+ /** El valor no es válido. Dentro de un `FormField` con `error` se activa solo. */
582
+ invalid?: boolean | undefined;
583
+ required?: boolean | undefined;
584
+ maxLength?: number | undefined;
585
+ onFocus?: (() => void) | undefined;
586
+ onBlur?: (() => void) | undefined;
587
+ /** Nombre accesible cuando no hay un `FormField` que lo etiquete. */
588
+ accessibilityLabel?: string | undefined;
589
+ /** `data-testid` en web, `testID` en nativo. */
590
+ testID?: string | undefined;
591
+ }
592
+ //#endregion
593
+ export { ColorScheme, FeedbackTone, FormFieldContext, FormFieldControl, FormFieldControlOptions, FormFieldValue, FormFieldValueOptions, LinkPressEvent, LinkProps, LinkUnderline, TOAST_DEFAULT_DURATION, TOAST_MAX_VISIBLE, TextAlign, TextColorToken, TextProps, TextVariant, TextVariantStyle, ThemeMode, ToastAction, ToastApi, ToastContext, ToastItem, ToastOptions, type ToastStore, UIContext, type UIContextValue, UIProviderProps, UseButtonOptions, UseButtonResult, UseControllableStateOptions, UseLinkOptions, UseLinkResult, createFormFieldValue, createToastStore, createUIContextValue, feedbackTones, isFeedbackTone, linkUnderlines, resolveFormFieldControl, textAligns, textColors, textVariantStyles, textVariants, themeModes, useBrand, useButton, useColorScheme, useControllableState, useFormFieldControl, useLink, useTheme, useToast, useUIContext };