@streamscloud/kit 0.55.0 → 0.56.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.
@@ -2,13 +2,14 @@ import { ContinuationToken, type CursorResult } from '..';
2
2
  import type { IDataLoader } from './data-loader';
3
3
  export declare class CursorDataLoaderWithSearch<T> implements IDataLoader<T> {
4
4
  items: T[];
5
- private continuationToken;
5
+ private _continuationToken;
6
6
  private _searchString;
7
- private loadPage;
8
- private pending;
9
- private generation;
10
- private searchStringMinLength;
7
+ private _loadPage;
8
+ private _pending;
9
+ private _generation;
10
+ private _searchStringMinLength;
11
11
  private _loading;
12
+ private _failed;
12
13
  constructor(init: {
13
14
  loadPage: (continuationToken: ContinuationToken, searchString: string) => Promise<CursorResult<T> | null>;
14
15
  searchStringMinLength?: number;
@@ -16,6 +17,7 @@ export declare class CursorDataLoaderWithSearch<T> implements IDataLoader<T> {
16
17
  get searchString(): string;
17
18
  get loading(): boolean;
18
19
  get initialLoading(): boolean;
20
+ get failed(): boolean;
19
21
  loadMore: () => Promise<T[]>;
20
22
  reset(): Promise<void>;
21
23
  updateSearchString: (searchString: string | null) => void;
@@ -2,17 +2,18 @@ import { ContinuationToken } from '..';
2
2
  import { Utils } from '../utils';
3
3
  export class CursorDataLoaderWithSearch {
4
4
  items = $state.raw([]);
5
- continuationToken = $state.raw(ContinuationToken.init());
5
+ _continuationToken = $state.raw(ContinuationToken.init());
6
6
  _searchString = $state.raw('');
7
- loadPage;
8
- pending = null;
9
- generation = 0;
10
- searchStringMinLength = 1;
7
+ _loadPage;
8
+ _pending = null;
9
+ _generation = 0;
10
+ _searchStringMinLength = 1;
11
11
  _loading = $state(false);
12
+ _failed = $state(false);
12
13
  constructor(init) {
13
- this.loadPage = init.loadPage;
14
+ this._loadPage = init.loadPage;
14
15
  if (init.searchStringMinLength !== undefined) {
15
- this.searchStringMinLength = init.searchStringMinLength;
16
+ this._searchStringMinLength = init.searchStringMinLength;
16
17
  }
17
18
  this.updateSearchString = Utils.debounce(this.updateSearchString, 400);
18
19
  }
@@ -25,33 +26,36 @@ export class CursorDataLoaderWithSearch {
25
26
  get initialLoading() {
26
27
  return this._loading && this.items.length === 0;
27
28
  }
29
+ get failed() {
30
+ return this._failed;
31
+ }
28
32
  loadMore = async () => {
29
- if (this.pending) {
30
- return this.pending;
33
+ if (this._pending) {
34
+ return this._pending;
31
35
  }
32
- if (!this.continuationToken.canLoadMore) {
36
+ if (!this._continuationToken.canLoadMore) {
33
37
  return [];
34
38
  }
35
39
  this._loading = true;
36
40
  const pending = this.runLoad();
37
- this.pending = pending;
41
+ this._pending = pending;
38
42
  try {
39
43
  return await pending;
40
44
  }
41
45
  finally {
42
46
  // a concurrent reset() may have installed a newer load — leave that one alone
43
- if (this.pending === pending) {
44
- this.pending = null;
47
+ if (this._pending === pending) {
48
+ this._pending = null;
45
49
  this._loading = false;
46
50
  }
47
51
  }
48
52
  };
49
53
  async reset() {
50
- this.generation++;
51
- this.pending = null;
54
+ this._generation++;
55
+ this._pending = null;
52
56
  this._loading = false;
53
57
  this.items = [];
54
- this.continuationToken = ContinuationToken.init();
58
+ this._continuationToken = ContinuationToken.init();
55
59
  await this.loadMore();
56
60
  }
57
61
  updateSearchString = (searchString) => {
@@ -67,22 +71,28 @@ export class CursorDataLoaderWithSearch {
67
71
  }
68
72
  };
69
73
  runLoad = async () => {
70
- const generation = this.generation;
74
+ const generation = this._generation;
71
75
  const search = this.isSearchStringEffective(this._searchString) ? this._searchString : '';
76
+ this._failed = false;
72
77
  try {
73
- const result = (await this.loadPage(this.continuationToken, search)) ?? { items: [], continuationToken: ContinuationToken.preventLoading() };
78
+ const page = await this._loadPage(this._continuationToken, search);
74
79
  // a reset() mid-load bumps the generation — drop the stale page instead of appending it to the cleared list
75
- if (generation !== this.generation) {
80
+ if (generation !== this._generation) {
76
81
  return [];
77
82
  }
78
- this.continuationToken = result.continuationToken;
83
+ const result = page ?? { items: [], continuationToken: ContinuationToken.preventLoading() };
84
+ this._failed = page === null;
85
+ this._continuationToken = result.continuationToken;
79
86
  this.items = [...this.items, ...result.items];
80
87
  return result.items;
81
88
  }
82
89
  catch (error) {
83
90
  console.error('CursorDataLoaderWithSearch: failed to load page', error);
91
+ if (generation === this._generation) {
92
+ this._failed = true;
93
+ }
84
94
  return [];
85
95
  }
86
96
  };
87
- isSearchStringEffective = (searchString) => searchString && searchString.length >= this.searchStringMinLength;
97
+ isSearchStringEffective = (searchString) => searchString && searchString.length >= this._searchStringMinLength;
88
98
  }
@@ -3,15 +3,17 @@ import type { IDataLoader } from './data-loader';
3
3
  export declare class CursorDataLoader<T> implements IDataLoader<T> {
4
4
  items: T[];
5
5
  continuationToken: ContinuationToken;
6
- private loadPage;
7
- private pending;
8
- private generation;
6
+ private _loadPage;
7
+ private _pending;
8
+ private _generation;
9
9
  private _loading;
10
+ private _failed;
10
11
  constructor(init: {
11
12
  loadPage: (continuationToken: ContinuationToken) => Promise<CursorResult<T> | null>;
12
13
  });
13
14
  get loading(): boolean;
14
15
  get initialLoading(): boolean;
16
+ get failed(): boolean;
15
17
  loadMore: () => Promise<T[]>;
16
18
  reset(): Promise<void>;
17
19
  private runLoad;
@@ -2,12 +2,13 @@ import { ContinuationToken } from '..';
2
2
  export class CursorDataLoader {
3
3
  items = $state.raw([]);
4
4
  continuationToken = $state.raw(ContinuationToken.init());
5
- loadPage;
6
- pending = null;
7
- generation = 0;
5
+ _loadPage;
6
+ _pending = null;
7
+ _generation = 0;
8
8
  _loading = $state(false);
9
+ _failed = $state(false);
9
10
  constructor(init) {
10
- this.loadPage = init.loadPage;
11
+ this._loadPage = init.loadPage;
11
12
  }
12
13
  get loading() {
13
14
  return this._loading;
@@ -15,49 +16,58 @@ export class CursorDataLoader {
15
16
  get initialLoading() {
16
17
  return this._loading && this.items.length === 0;
17
18
  }
19
+ get failed() {
20
+ return this._failed;
21
+ }
18
22
  loadMore = async () => {
19
- if (this.pending) {
20
- return this.pending;
23
+ if (this._pending) {
24
+ return this._pending;
21
25
  }
22
26
  if (!this.continuationToken.canLoadMore) {
23
27
  return [];
24
28
  }
25
29
  this._loading = true;
26
30
  const pending = this.runLoad();
27
- this.pending = pending;
31
+ this._pending = pending;
28
32
  try {
29
33
  return await pending;
30
34
  }
31
35
  finally {
32
36
  // a concurrent reset() may have installed a newer load — leave that one alone
33
- if (this.pending === pending) {
34
- this.pending = null;
37
+ if (this._pending === pending) {
38
+ this._pending = null;
35
39
  this._loading = false;
36
40
  }
37
41
  }
38
42
  };
39
43
  async reset() {
40
- this.generation++;
41
- this.pending = null;
44
+ this._generation++;
45
+ this._pending = null;
42
46
  this._loading = false;
43
47
  this.items = [];
44
48
  this.continuationToken = ContinuationToken.init();
45
49
  await this.loadMore();
46
50
  }
47
51
  runLoad = async () => {
48
- const generation = this.generation;
52
+ const generation = this._generation;
53
+ this._failed = false;
49
54
  try {
50
- const result = (await this.loadPage(this.continuationToken)) ?? { items: [], continuationToken: ContinuationToken.preventLoading() };
55
+ const page = await this._loadPage(this.continuationToken);
51
56
  // a reset() mid-load bumps the generation — drop the stale page instead of appending it to the cleared list
52
- if (generation !== this.generation) {
57
+ if (generation !== this._generation) {
53
58
  return [];
54
59
  }
60
+ const result = page ?? { items: [], continuationToken: ContinuationToken.preventLoading() };
61
+ this._failed = page === null;
55
62
  this.continuationToken = result.continuationToken;
56
63
  this.items = [...this.items, ...result.items];
57
64
  return result.items;
58
65
  }
59
66
  catch (error) {
60
67
  console.error('CursorDataLoader: failed to load page', error);
68
+ if (generation === this._generation) {
69
+ this._failed = true;
70
+ }
61
71
  return [];
62
72
  }
63
73
  };
@@ -3,5 +3,7 @@ export interface IDataLoader<T> {
3
3
  loading: boolean;
4
4
  /** Loading with nothing to show yet — first load, or a reload after the list was cleared by a reset. */
5
5
  initialLoading: boolean;
6
+ /** The last attempt did not deliver a page, whether it returned nothing or threw; cleared when the next attempt starts. */
7
+ failed: boolean;
6
8
  loadMore: () => Promise<T[]>;
7
9
  }
@@ -1,4 +1,5 @@
1
1
  export type { IDataLoader } from './data-loader';
2
2
  export { CursorDataLoader } from './cursor-data-loader.svelte';
3
3
  export { CursorDataLoaderWithSearch } from './cursor-data-loader-with-search.svelte';
4
+ export { KeyedCursorDataLoader } from './keyed-cursor-data-loader.svelte';
4
5
  export { PageDataLoader } from './page-data-loader.svelte';
@@ -1,4 +1,5 @@
1
1
  // Data loaders
2
2
  export { CursorDataLoader } from './cursor-data-loader.svelte';
3
3
  export { CursorDataLoaderWithSearch } from './cursor-data-loader-with-search.svelte';
4
+ export { KeyedCursorDataLoader } from './keyed-cursor-data-loader.svelte';
4
5
  export { PageDataLoader } from './page-data-loader.svelte';
@@ -0,0 +1,28 @@
1
+ import { ContinuationToken, type CursorResult } from '..';
2
+ export declare class KeyedCursorDataLoader<T> {
3
+ private _loaders;
4
+ private _loaded;
5
+ private _pending;
6
+ private _loadPage;
7
+ private _loadAlongside;
8
+ constructor(init: {
9
+ loadPage: (key: string, continuationToken: ContinuationToken) => Promise<CursorResult<T> | null>;
10
+ /** Started with the key's first page and awaited by `ensureLoaded`; its outcome never reaches `isLoaded`. */
11
+ loadAlongside?: (key: string) => Promise<void>;
12
+ });
13
+ items: (key?: string) => T[];
14
+ loading: (key?: string) => boolean;
15
+ initialLoading: (key?: string) => boolean;
16
+ canLoadMore: (key?: string) => boolean;
17
+ /** False until the key's first page loaded without failing, so a failed load can be retried; a later failed page never clears it. */
18
+ isLoaded: (key?: string) => boolean;
19
+ /** Loads the key's first page once; concurrent and repeat calls share that load's promise. */
20
+ ensureLoaded: (key?: string) => Promise<void>;
21
+ loadMore: (key?: string) => Promise<T[]>;
22
+ /** Drops the key's pages and loads them again from the first one. */
23
+ reload: (key?: string) => Promise<void>;
24
+ private startLoad;
25
+ private runLoad;
26
+ private runAlongside;
27
+ private loaderFor;
28
+ }
@@ -0,0 +1,66 @@
1
+ import { ContinuationToken } from '..';
2
+ import { CursorDataLoader } from './cursor-data-loader.svelte';
3
+ export class KeyedCursorDataLoader {
4
+ _loaders = {};
5
+ _loaded = $state.raw({});
6
+ _pending = {};
7
+ _loadPage;
8
+ _loadAlongside;
9
+ constructor(init) {
10
+ this._loadPage = init.loadPage;
11
+ this._loadAlongside = init.loadAlongside;
12
+ }
13
+ items = (key = '') => this.loaderFor(key).items;
14
+ loading = (key = '') => this.loaderFor(key).loading;
15
+ initialLoading = (key = '') => this.loaderFor(key).initialLoading;
16
+ canLoadMore = (key = '') => this.loaderFor(key).continuationToken.canLoadMore;
17
+ /** False until the key's first page loaded without failing, so a failed load can be retried; a later failed page never clears it. */
18
+ isLoaded = (key = '') => this._loaded[key] === true;
19
+ /** Loads the key's first page once; concurrent and repeat calls share that load's promise. */
20
+ ensureLoaded = (key = '') => {
21
+ if (this._loaded[key]) {
22
+ return Promise.resolve();
23
+ }
24
+ return this._pending[key] ?? this.startLoad(key);
25
+ };
26
+ loadMore = (key = '') => this.loaderFor(key).loadMore();
27
+ /** Drops the key's pages and loads them again from the first one. */
28
+ reload = (key = '') => {
29
+ this._loaded = { ...this._loaded, [key]: false };
30
+ return this.startLoad(key);
31
+ };
32
+ startLoad = async (key) => {
33
+ const pending = this.runLoad(key);
34
+ this._pending[key] = pending;
35
+ try {
36
+ await pending;
37
+ }
38
+ finally {
39
+ // a concurrent reload() may have installed a newer load — leave that one alone
40
+ if (this._pending[key] === pending) {
41
+ this._pending[key] = undefined;
42
+ }
43
+ }
44
+ };
45
+ runLoad = async (key) => {
46
+ const loader = this.loaderFor(key);
47
+ const alongside = this.runAlongside(key);
48
+ await loader.reset();
49
+ this._loaded = { ...this._loaded, [key]: !loader.failed };
50
+ await alongside;
51
+ };
52
+ runAlongside = async (key) => {
53
+ try {
54
+ await this._loadAlongside?.(key);
55
+ }
56
+ catch (error) {
57
+ console.error('KeyedCursorDataLoader: failed to load alongside the page', error);
58
+ }
59
+ };
60
+ loaderFor = (key) => {
61
+ if (!this._loaders[key]) {
62
+ this._loaders[key] = new CursorDataLoader({ loadPage: (continuationToken) => this._loadPage(key, continuationToken) });
63
+ }
64
+ return this._loaders[key];
65
+ };
66
+ }
@@ -2,11 +2,12 @@ import type { IDataLoader } from './data-loader';
2
2
  export declare class PageDataLoader<T> implements IDataLoader<T> {
3
3
  private _items;
4
4
  private _loading;
5
- private canLoadMore;
6
- private perPage;
7
- private loadPage;
8
- private pageNumber;
9
- private generation;
5
+ private _failed;
6
+ private _canLoadMore;
7
+ private _perPage;
8
+ private _loadPage;
9
+ private _pageNumber;
10
+ private _generation;
10
11
  constructor(init: {
11
12
  loadPage: (page: number, perPage: number) => Promise<T[]>;
12
13
  perPage?: number;
@@ -14,6 +15,7 @@ export declare class PageDataLoader<T> implements IDataLoader<T> {
14
15
  get items(): T[];
15
16
  get loading(): boolean;
16
17
  get initialLoading(): boolean;
18
+ get failed(): boolean;
17
19
  loadMore: () => Promise<T[]>;
18
20
  reset: () => Promise<void>;
19
21
  }
@@ -1,15 +1,16 @@
1
1
  export class PageDataLoader {
2
2
  _items = $state.raw([]);
3
3
  _loading = $state(false);
4
- canLoadMore = $state(true);
5
- perPage = 20;
6
- loadPage;
7
- pageNumber = 1;
8
- generation = 0;
4
+ _failed = $state(false);
5
+ _canLoadMore = $state(true);
6
+ _perPage = 20;
7
+ _loadPage;
8
+ _pageNumber = 1;
9
+ _generation = 0;
9
10
  constructor(init) {
10
- this.loadPage = init.loadPage;
11
+ this._loadPage = init.loadPage;
11
12
  if (init.perPage) {
12
- this.perPage = init.perPage;
13
+ this._perPage = init.perPage;
13
14
  }
14
15
  }
15
16
  get items() {
@@ -21,39 +22,46 @@ export class PageDataLoader {
21
22
  get initialLoading() {
22
23
  return this._loading && this._items.length === 0;
23
24
  }
25
+ get failed() {
26
+ return this._failed;
27
+ }
24
28
  loadMore = async () => {
25
- if (this._loading || !this.canLoadMore) {
29
+ if (this._loading || !this._canLoadMore) {
26
30
  return [];
27
31
  }
28
- const generation = this.generation;
32
+ const generation = this._generation;
29
33
  this._loading = true;
34
+ this._failed = false;
30
35
  try {
31
- const items = await this.loadPage(this.pageNumber, this.perPage);
36
+ const items = await this._loadPage(this._pageNumber, this._perPage);
32
37
  // a reset() mid-load bumps the generation — drop the stale page instead of appending it to the cleared list
33
- if (generation !== this.generation) {
38
+ if (generation !== this._generation) {
34
39
  return [];
35
40
  }
36
- this.pageNumber++;
37
- this.canLoadMore = items.length === this.perPage;
41
+ this._pageNumber++;
42
+ this._canLoadMore = items.length === this._perPage;
38
43
  this._items = [...this._items, ...items];
39
44
  return items;
40
45
  }
41
46
  catch (error) {
42
47
  console.error('PageDataLoader: failed to load page', error);
48
+ if (generation === this._generation) {
49
+ this._failed = true;
50
+ }
43
51
  return [];
44
52
  }
45
53
  finally {
46
- if (generation === this.generation) {
54
+ if (generation === this._generation) {
47
55
  this._loading = false;
48
56
  }
49
57
  }
50
58
  };
51
59
  reset = async () => {
52
- this.generation++;
60
+ this._generation++;
53
61
  this._loading = false;
54
- this.pageNumber = 1;
62
+ this._pageNumber = 1;
55
63
  this._items = [];
56
- this.canLoadMore = true;
64
+ this._canLoadMore = true;
57
65
  await this.loadMore();
58
66
  };
59
67
  }
@@ -12,11 +12,11 @@ $effect(() => {
12
12
  });
13
13
  </script>
14
14
 
15
- {#if visible}
16
- {#if blocking}
17
- <div class="spinner-overlay" class:spinner-overlay--fixed={position === 'fixed-center'}></div>
18
- {/if}
15
+ {#if blocking}
16
+ <div class="spinner-overlay" class:spinner-overlay--fixed={position === 'fixed-center'} class:spinner-overlay--dimmed={visible}></div>
17
+ {/if}
19
18
 
19
+ {#if visible}
20
20
  <span
21
21
  class="spinner spinner--{size}"
22
22
  class:spinner--accent={color === 'accent'}
@@ -41,7 +41,9 @@ $effect(() => {
41
41
  @component
42
42
  Spinner — indeterminate loading indicator. Single-arc circle rotating at a constant rate. Color preset (`accent` default) resolves to a semantic token; override the public CSS vars on any ancestor for global theming. Pass `label` to expose it to screen readers as a live status region.
43
43
 
44
- Convenience props for the common "load happens, show a centered spinner with optional dimmer" pattern: `position` centers it within the nearest positioned ancestor (`absolute-center`) or the viewport (`fixed-center`); `blocking` adds a semi-transparent overlay; `timeout` delays visibility to avoid flicker for fast operations.
44
+ Convenience props for the common "load happens, show a centered spinner with optional dimmer" pattern: `position` centers it within the nearest positioned ancestor (`absolute-center`) or the viewport (`fixed-center`); `blocking` adds an overlay; `timeout` delays visibility to avoid flicker for fast operations.
45
+
46
+ `blocking` and `timeout` are orthogonal. The overlay mounts with the component and swallows pointer input from the first millisecond regardless of `timeout`; once `timeout` elapses the spinner appears and the overlay fades to its dim background. Pointer input only — a focused control underneath still reacts to the keyboard; wrap the region in `inert` if that matters.
45
47
 
46
48
  For tight inline glyphs inside other kit cmps (Button loading state, async Select), use the internal `_internal/spinner` instead — that one fills its inline box and inherits `currentColor` for stroke.
47
49
 
@@ -58,7 +60,7 @@ For tight inline glyphs inside other kit cmps (Button loading state, async Selec
58
60
  | `--sc-kit--spinner--color-text` | Color for `text` preset | `--sc-kit--color--text--primary` |
59
61
  | `--sc-kit--spinner--color-on-accent` | Color for `on-accent` preset | `--sc-kit--color--text--on-accent` |
60
62
  | `--sc-kit--spinner--duration` | Rotation duration | `1.6s` |
61
- | `--sc-kit--spinner--overlay--background` | Backdrop color when `blocking` is true | `rgba(0, 0, 0, 0.3)` |
63
+ | `--sc-kit--spinner--overlay--background` | Backdrop color the `blocking` overlay fades to once the spinner shows | `rgba(0, 0, 0, 0.3)` |
62
64
  | `--sc-kit--spinner--overlay--z-index` | Backdrop stacking | `--sc-kit--z-index--popover` minus 1 |
63
65
 
64
66
  ### Size presets
@@ -74,12 +76,17 @@ For tight inline glyphs inside other kit cmps (Button loading state, async Selec
74
76
  --_overlay--z-index: var(--sc-kit--spinner--overlay--z-index, calc(var(--sc-kit--z-index--popover) - 1));
75
77
  position: absolute;
76
78
  inset: 0;
77
- background: var(--_overlay--background);
79
+ background-color: var(--_overlay--background);
80
+ opacity: 0;
78
81
  z-index: var(--_overlay--z-index);
82
+ transition: opacity var(--sc-kit--duration--base) var(--sc-kit--ease--default);
79
83
  }
80
84
  .spinner-overlay--fixed {
81
85
  position: fixed;
82
86
  }
87
+ .spinner-overlay--dimmed {
88
+ opacity: 1;
89
+ }
83
90
 
84
91
  .spinner {
85
92
  --_spinner--size: var(--sc-kit--spinner--size, 1.25rem);
@@ -7,15 +7,17 @@ type Props = {
7
7
  label?: string;
8
8
  /** Centering mode. `absolute-center` centers within the closest positioned ancestor; `fixed-center` centers in the viewport. Omit for an inline-flex glyph at the current position. */
9
9
  position?: 'absolute-center' | 'fixed-center';
10
- /** Renders a semi-transparent overlay behind the spinner. Pair with `position` for a full-area dimmer. */
10
+ /** Renders an overlay that swallows pointer input immediately, independent of `timeout`; it stays invisible until `timeout` elapses, then fades to its dim background. Pair with `position` for a full-area dimmer. */
11
11
  blocking?: boolean;
12
- /** Delay in ms before the spinner becomes visible (and the optional overlay renders). Prevents flicker for fast operations. @default 0 */
12
+ /** Delay in ms before the spinner becomes visible (and a `blocking` overlay dims). Prevents flicker for fast operations. @default 0 */
13
13
  timeout?: number;
14
14
  };
15
15
  /**
16
16
  * Spinner — indeterminate loading indicator. Single-arc circle rotating at a constant rate. Color preset (`accent` default) resolves to a semantic token; override the public CSS vars on any ancestor for global theming. Pass `label` to expose it to screen readers as a live status region.
17
17
  *
18
- * Convenience props for the common "load happens, show a centered spinner with optional dimmer" pattern: `position` centers it within the nearest positioned ancestor (`absolute-center`) or the viewport (`fixed-center`); `blocking` adds a semi-transparent overlay; `timeout` delays visibility to avoid flicker for fast operations.
18
+ * Convenience props for the common "load happens, show a centered spinner with optional dimmer" pattern: `position` centers it within the nearest positioned ancestor (`absolute-center`) or the viewport (`fixed-center`); `blocking` adds an overlay; `timeout` delays visibility to avoid flicker for fast operations.
19
+ *
20
+ * `blocking` and `timeout` are orthogonal. The overlay mounts with the component and swallows pointer input from the first millisecond regardless of `timeout`; once `timeout` elapses the spinner appears and the overlay fades to its dim background. Pointer input only — a focused control underneath still reacts to the keyboard; wrap the region in `inert` if that matters.
19
21
  *
20
22
  * For tight inline glyphs inside other kit cmps (Button loading state, async Select), use the internal `_internal/spinner` instead — that one fills its inline box and inherits `currentColor` for stroke.
21
23
  *
@@ -32,7 +34,7 @@ type Props = {
32
34
  * | `--sc-kit--spinner--color-text` | Color for `text` preset | `--sc-kit--color--text--primary` |
33
35
  * | `--sc-kit--spinner--color-on-accent` | Color for `on-accent` preset | `--sc-kit--color--text--on-accent` |
34
36
  * | `--sc-kit--spinner--duration` | Rotation duration | `1.6s` |
35
- * | `--sc-kit--spinner--overlay--background` | Backdrop color when `blocking` is true | `rgba(0, 0, 0, 0.3)` |
37
+ * | `--sc-kit--spinner--overlay--background` | Backdrop color the `blocking` overlay fades to once the spinner shows | `rgba(0, 0, 0, 0.3)` |
36
38
  * | `--sc-kit--spinner--overlay--z-index` | Backdrop stacking | `--sc-kit--z-index--popover` minus 1 |
37
39
  *
38
40
  * ### Size presets
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@streamscloud/kit",
3
- "version": "0.55.0",
3
+ "version": "0.56.0",
4
4
  "author": "StreamsCloud",
5
5
  "repository": {
6
6
  "type": "git",