@satellatickets/core 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -2,6 +2,36 @@
2
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";
3
3
  import { BrandName, Theme, ThemeName, ThemeOverrides } from "@satellatickets/tokens";
4
4
  import { ReactNode } from "react";
5
+ //#region src/select/navigation.d.ts
6
+ /** Lo mínimo que hace falta saber de una opción para moverse entre ellas y buscarla. */
7
+ export interface NavigableOption {
8
+ value: string;
9
+ label: string;
10
+ disabled?: boolean | undefined;
11
+ }
12
+ /** Hacia dónde mueve el resaltado una tecla: flechas, Inicio, Fin, AvPág y RePág. */
13
+ export declare const optionDirections: readonly ["next", "previous", "first", "last", "nextPage", "previousPage"];
14
+ export type OptionDirection = (typeof optionDirections)[number];
15
+ /** Cuántas opciones salta AvPág o RePág. */
16
+ export declare const OPTION_PAGE_SIZE = 10;
17
+ /**
18
+ * La opción a la que lleva una tecla desde la actual, saltando las deshabilitadas. No da
19
+ * la vuelta: al llegar a un extremo se queda en él (ADR-042). Si no hay ninguna a la
20
+ * que ir, devuelve la actual.
21
+ */
22
+ export declare function getOptionInDirection(options: readonly NavigableOption[], current: string | undefined, direction: OptionDirection): string | undefined;
23
+ /**
24
+ * La opción habilitada cuyo texto empieza por lo que el usuario ha escrito, o `undefined`
25
+ * si no hay ninguna.
26
+ *
27
+ * - Una sola letra busca a partir de la siguiente a la actual, así que pulsarla varias
28
+ * veces recorre las que empiezan por ella.
29
+ * - Un texto más largo se queda en la actual mientras siga coincidiendo.
30
+ * - La misma letra repetida ("bb") que no es el principio de ninguna opción vale como
31
+ * pulsarla otra vez.
32
+ */
33
+ export declare function findOptionByText(options: readonly NavigableOption[], text: string, current?: string): string | undefined;
34
+ //#endregion
5
35
  //#region src/tabs/navigation.d.ts
6
36
  /** Lo mínimo que hace falta saber de una pestaña para moverse entre ellas. */
7
37
  export interface NavigableTab {
@@ -411,7 +441,7 @@ export interface SelectOption {
411
441
  label: string;
412
442
  disabled?: boolean | undefined;
413
443
  }
414
- /** Contrato de `Select`: elegir una opción de una lista (ADR-038). */
444
+ /** Contrato de `Select`: elegir una opción de una lista (ADR-042). */
415
445
  export interface SelectProps {
416
446
  options: readonly SelectOption[];
417
447
  /** Opción elegida, controlada por la app. Sin ella, guarda su propio estado (ADR-037). */
package/dist/index.js CHANGED
@@ -2,6 +2,68 @@
2
2
  import { n as resolveColorScheme, r as resolveTheme, t as mergeTheme } from "./resolve-theme-DbIlzBBD.js";
3
3
  import { themes } from "@satellatickets/tokens";
4
4
  export * from "./client.js";
5
+ //#region src/select/navigation.ts
6
+ /** Hacia dónde mueve el resaltado una tecla: flechas, Inicio, Fin, AvPág y RePág. */
7
+ const optionDirections = [
8
+ "next",
9
+ "previous",
10
+ "first",
11
+ "last",
12
+ "nextPage",
13
+ "previousPage"
14
+ ];
15
+ /** Cuántas opciones salta AvPág o RePág. */
16
+ const OPTION_PAGE_SIZE = 10;
17
+ const steps = {
18
+ next: 1,
19
+ previous: -1,
20
+ nextPage: 10,
21
+ previousPage: -10
22
+ };
23
+ /**
24
+ * La opción a la que lleva una tecla desde la actual, saltando las deshabilitadas. No da
25
+ * la vuelta: al llegar a un extremo se queda en él (ADR-042). Si no hay ninguna a la
26
+ * que ir, devuelve la actual.
27
+ */
28
+ function getOptionInDirection(options, current, direction) {
29
+ const enabled = options.filter((option) => option.disabled !== true).map(({ value }) => value);
30
+ const [first] = enabled;
31
+ const last = enabled[enabled.length - 1];
32
+ if (first === void 0 || last === void 0) return current;
33
+ if (direction === "first") return first;
34
+ if (direction === "last") return last;
35
+ const step = steps[direction];
36
+ const index = current === void 0 ? -1 : enabled.indexOf(current);
37
+ if (index === -1) return step > 0 ? first : last;
38
+ return enabled[Math.min(Math.max(index + step, 0), enabled.length - 1)] ?? current;
39
+ }
40
+ /** Sin mayúsculas ni acentos: al escribir "avila" se encuentra "Ávila". */
41
+ function normalize(text) {
42
+ return text.normalize("NFD").replace(/\p{Diacritic}/gu, "").toLocaleLowerCase();
43
+ }
44
+ /**
45
+ * La opción habilitada cuyo texto empieza por lo que el usuario ha escrito, o `undefined`
46
+ * si no hay ninguna.
47
+ *
48
+ * - Una sola letra busca a partir de la siguiente a la actual, así que pulsarla varias
49
+ * veces recorre las que empiezan por ella.
50
+ * - Un texto más largo se queda en la actual mientras siga coincidiendo.
51
+ * - La misma letra repetida ("bb") que no es el principio de ninguna opción vale como
52
+ * pulsarla otra vez.
53
+ */
54
+ function findOptionByText(options, text, current) {
55
+ const query = normalize(text);
56
+ const [letter] = query;
57
+ if (letter === void 0) return void 0;
58
+ const enabled = options.filter((option) => option.disabled !== true);
59
+ const index = enabled.findIndex((option) => option.value === current);
60
+ const startingWith = (prefix, from) => [...enabled.slice(from), ...enabled.slice(0, from)].find((option) => normalize(option.label).startsWith(prefix))?.value;
61
+ if (query.length === 1) return startingWith(letter, index + 1);
62
+ const match = startingWith(query, Math.max(index, 0));
63
+ if (match !== void 0) return match;
64
+ return [...query].every((char) => char === letter) ? startingWith(letter, index + 1) : void 0;
65
+ }
66
+ //#endregion
5
67
  //#region src/tabs/navigation.ts
6
68
  /** Hacia dónde mueve el foco una tecla: flechas, Inicio y Fin. */
7
69
  const tabDirections = [
@@ -388,4 +450,4 @@ const themeModes = [
388
450
  "system"
389
451
  ];
390
452
  //#endregion
391
- export { TOAST_DEFAULT_DURATION, TOAST_MAX_VISIBLE, backgroundTokens, badgeVariants, borderColorTokens, buttonIconSize, buttonVariants, cardVariants, controlSizes, createToastStore, dividerOrientations, feedbackTones, firstEnabledTab, getTabInDirection, iconButtonIconSize, iconSizePx, iconSizes, inputIconSize, inputTypes, isFeedbackTone, linkUnderlines, mergeTheme, modalPresentations, radiusTokens, resolveColorScheme, resolveTheme, shadowTokens, skeletonShapes, spaceTokens, spinnerSizePx, spinnerSizes, stackAligns, stackDirections, stackJustifies, tabDirections, textAligns, textColors, textVariantStyles, textVariants, themeModes };
453
+ export { OPTION_PAGE_SIZE, TOAST_DEFAULT_DURATION, TOAST_MAX_VISIBLE, backgroundTokens, badgeVariants, borderColorTokens, buttonIconSize, buttonVariants, cardVariants, controlSizes, createToastStore, dividerOrientations, feedbackTones, findOptionByText, firstEnabledTab, getOptionInDirection, getTabInDirection, iconButtonIconSize, iconSizePx, iconSizes, inputIconSize, inputTypes, isFeedbackTone, linkUnderlines, mergeTheme, modalPresentations, optionDirections, radiusTokens, resolveColorScheme, resolveTheme, shadowTokens, skeletonShapes, spaceTokens, spinnerSizePx, spinnerSizes, stackAligns, stackDirections, stackJustifies, tabDirections, textAligns, textColors, textVariantStyles, textVariants, themeModes };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@satellatickets/core",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "Lógica headless de satella-ui: contratos de props, constantes de variantes, contexto de tema y hooks compartidos por React y React Native",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -40,8 +40,8 @@
40
40
  "tsdown": "^0.23.0",
41
41
  "typescript": "^5.9.3",
42
42
  "vitest": "^5.0.3",
43
- "@satellatickets/eslint-config": "0.0.0",
44
- "@satellatickets/tsconfig": "0.0.0"
43
+ "@satellatickets/tsconfig": "0.0.0",
44
+ "@satellatickets/eslint-config": "0.0.0"
45
45
  },
46
46
  "scripts": {
47
47
  "build": "tsdown",