@ssa-ui-kit/utils 3.21.2 → 3.22.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.
@@ -1,3 +1,30 @@
1
1
  import { GenerateRangeFn } from './types';
2
+ /**
3
+ * Builds the list of page numbers a paginator should display.
4
+ *
5
+ * Always includes the first and last page, plus one page either side of the
6
+ * selection, and collapses the rest.
7
+ *
8
+ * ### `-1` marks a gap, it is not a page
9
+ * Skipped stretches are represented by `-1`, which the caller renders as an
10
+ * ellipsis. Render the array directly and a `-1` button appears — check for it:
11
+ * `range.map((page) => (page === -1 ? <Ellipsis /> : <PageButton page={page} />))`.
12
+ *
13
+ * ### It throws on bad input rather than clamping
14
+ * A non-integer `pagesCount` or `selectedPage`, or a selection outside
15
+ * `1…pagesCount`, raises an `Error`. Only `pagesCount <= 0` is tolerated,
16
+ * returning `[]`. Note pages are **1-based**, so `selectedPage: 0` throws.
17
+ *
18
+ * @param pagesCount - Total pages. `<= 0` yields an empty array.
19
+ * @param selectedPage - Current page, 1-based. Omit for the unselected layout.
20
+ *
21
+ * @example
22
+ * generateRange(5); // [1, 2, 3, 4, 5] — short enough to show in full
23
+ * generateRange(10); // [1, 2, 3, -1, 10]
24
+ *
25
+ * @example
26
+ * generateRange(10, 5); // [1, -1, 4, 5, 6, -1, 10] — gaps on both sides
27
+ * generateRange(10, 10); // [1, -1, 9, 10]
28
+ */
2
29
  declare const generateRange: GenerateRangeFn;
3
30
  export default generateRange;
@@ -1 +1,7 @@
1
+ /**
2
+ * Signature of `generateRange`.
3
+ *
4
+ * The returned array mixes page numbers with `-1` sentinels marking collapsed
5
+ * stretches, so it is not a plain list of pages.
6
+ */
1
7
  export type GenerateRangeFn = (pagesCount: number, selectedPage?: number) => Array<number>;
@@ -1 +1,17 @@
1
+ /**
2
+ * A deterministic stand-in for `Math.random`, for generating fixture data.
3
+ *
4
+ * Returns a generator function; calling it yields the next value in `[0, 1)`.
5
+ * The same seed always produces the same sequence, which is the point — chart
6
+ * and table stories keep identical data between renders, so visual diffs show
7
+ * real changes rather than new noise.
8
+ *
9
+ * Linear congruential, so it is fine for demo data and unfit for anything
10
+ * needing statistical quality or unpredictability.
11
+ *
12
+ * @example
13
+ * const random = seededRandom(42);
14
+ * const series = Array.from({ length: 30 }, () => Math.round(random() * 100));
15
+ * // identical on every run
16
+ */
1
17
  export declare const seededRandom: (seed: number) => () => number;
@@ -1 +1,28 @@
1
+ /**
2
+ * Rate-limits a function to at most one call per interval.
3
+ *
4
+ * ### Returns a `[throttled, cancel]` tuple
5
+ * Not a callable function with a `.cancel()` method as in lodash — destructure
6
+ * it: `const [onScroll, cancelScroll] = throttle(fn, 100)`.
7
+ *
8
+ * Leading **and** trailing: the first call runs immediately, calls during the
9
+ * cooling-off window are dropped except the last, and that one runs when the
10
+ * window closes. So a burst produces a call at the start and a call at the end,
11
+ * never a silent gap — unlike `debounce`, which only fires at the end.
12
+ *
13
+ * Call `cancel` on unmount to clear a pending trailing invocation.
14
+ *
15
+ * @param delayMs - Minimum gap between invocations, in ms.
16
+ *
17
+ * @example
18
+ * const [onScroll, cancel] = throttle(() => setOffset(window.scrollY), 100);
19
+ *
20
+ * useEffect(() => {
21
+ * window.addEventListener('scroll', onScroll);
22
+ * return () => {
23
+ * window.removeEventListener('scroll', onScroll);
24
+ * cancel();
25
+ * };
26
+ * }, [onScroll, cancel]);
27
+ */
1
28
  export declare const throttle: <T extends unknown[]>(fn: (...args: T) => unknown, delayMs: number) => readonly [(...args: T) => void, () => void];
@@ -1,6 +1,46 @@
1
+ /** A JSON-representable leaf value. Note `undefined` is not one — see `PathObject`. */
1
2
  export type PathValue = string | number | boolean | null;
3
+ /**
4
+ * An arbitrarily nested, JSON-shaped object.
5
+ *
6
+ * Deliberately excludes `Date`, `Map`, `Set` and `undefined`, because the
7
+ * helpers typed with it round-trip through JSON and would corrupt those.
8
+ */
2
9
  export interface PathObject {
3
10
  [key: string | number]: PathValue | PathObject;
4
11
  }
12
+ /**
13
+ * `true` when the string union `T` covers every member of `U`.
14
+ *
15
+ * A type-level check, not a runtime one — used to make the compiler prove a
16
+ * list is exhaustive. See `MustInclude`.
17
+ */
5
18
  export type Has<T extends string, U extends string> = Exclude<U, T> extends never ? true : false;
19
+ /**
20
+ * Resolves to `T` when the array type `T` contains every member of `I`, and to
21
+ * `never` when it does not — so an incomplete list has no assignable value.
22
+ *
23
+ * ### It only bites on a concrete tuple type
24
+ * The check reads `T[number]`, which means `T` has to be a literal tuple for
25
+ * there to be anything to check. Applied to a **generic parameter that must be
26
+ * inferred from the value**, TypeScript cannot infer through the conditional,
27
+ * so the parameter falls back to its constraint — usually `string[]` — and
28
+ * `MustInclude` then accepts any array at all.
29
+ *
30
+ * In other words `features: MustInclude<T, 'x'>` on a `<T extends string[]>`
31
+ * component prop does **not** enforce anything at the call site. Pass the tuple
32
+ * type explicitly, or add `as const`, if you want the guarantee.
33
+ *
34
+ * @example
35
+ * // Enforced — the tuple type is given explicitly
36
+ * type Ok = MustInclude<['fullscreenMode', 'legend'], 'fullscreenMode'>;
37
+ * type No = MustInclude<['legend'], 'fullscreenMode'>; // never
38
+ *
39
+ * @example
40
+ * // NOT enforced — `F` is inferred, so it widens to string[] and this compiles
41
+ * declare const Header: <F extends string[]>(
42
+ * props: { features: MustInclude<F, 'fullscreenMode'> },
43
+ * ) => null;
44
+ * Header({ features: ['legend'] });
45
+ */
6
46
  export type MustInclude<T extends readonly string[], I extends string> = Has<T[number], I> extends true ? T : never;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ssa-ui-kit/utils",
3
- "version": "3.21.2",
3
+ "version": "3.22.0",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "exports": {
@@ -37,7 +37,7 @@
37
37
  "module": "dist/index.mjs",
38
38
  "scripts": {
39
39
  "clean": "node ../../scripts/clean.mjs",
40
- "build": "node ../../scripts/clean.mjs && webpack --mode=production --node-env=production && node ../../scripts/verify-esm-bundle.mjs && tsc --build ./tsconfig.build.json && resolve-tspaths -p ./tsconfig.build.json",
40
+ "build": "node ../../scripts/clean.mjs && webpack --mode=production --node-env=production && node ../../scripts/verify-esm-bundle.mjs && tsc --build ./tsconfig.build.json && resolve-tspaths -p ./tsconfig.build.json && node ../../scripts/ai-source-map.mjs .",
41
41
  "ts-show-config": "tsc --showConfig -p ./tsconfig.json",
42
42
  "ts-show-config-build": "tsc --showConfig -p ./tsconfig.build.json",
43
43
  "ts-check": "tsc -p ./tsconfig.json",