@warkypublic/svelix 0.1.31 → 0.1.32

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.
@@ -6,6 +6,7 @@ type GlobalStateStoreApi = {
6
6
  setState: (partial: PartialUpdater, replace?: boolean) => void;
7
7
  subscribe: (run: (value: GlobalStateStoreType) => void) => () => void;
8
8
  };
9
+ declare const createGlobalStateStore: () => GlobalStateStoreApi;
9
10
  declare const GlobalStateStore: GlobalStateStoreApi;
10
11
  declare const languageStore: Readable<SupportedLanguage>;
11
12
  declare function useGlobalStateStore(): Readable<GlobalStateStoreType>;
@@ -18,4 +19,4 @@ declare const setAuthToken: (token: string) => void;
18
19
  declare const GetGlobalState: () => GlobalStateStoreType;
19
20
  declare const setLanguage: (lang: SupportedLanguage) => void;
20
21
  export type { GlobalStateStoreApi };
21
- export { getApiURL, getAuthToken, GetGlobalState, GlobalStateStore, isLoggedIn, languageStore, setApiURL, setAuthToken, setLanguage, useGlobalStateStore, };
22
+ export { createGlobalStateStore, getApiURL, getAuthToken, GetGlobalState, GlobalStateStore, isLoggedIn, languageStore, setApiURL, setAuthToken, setLanguage, useGlobalStateStore, };
@@ -30,6 +30,7 @@ const createInitialState = () => ({
30
30
  connected: true,
31
31
  loading: false,
32
32
  loggedIn: false,
33
+ validated: true,
33
34
  },
34
35
  user: {
35
36
  guid: "",
@@ -45,6 +46,62 @@ const toPersistedState = (state) => ({
45
46
  session: state.session,
46
47
  user: state.user,
47
48
  });
49
+ const isSessionExpired = (session) => {
50
+ if (!session?.expiryDate) {
51
+ return false;
52
+ }
53
+ return new Date(session.expiryDate) < new Date();
54
+ };
55
+ const hasSessionCredentials = (session) => {
56
+ return Boolean(session?.authToken || session?.loggedIn);
57
+ };
58
+ const createClearedAuthenticatedState = (state, options) => {
59
+ const initialState = createInitialState();
60
+ return {
61
+ owner: initialState.owner,
62
+ program: initialState.program,
63
+ session: {
64
+ ...initialState.session,
65
+ apiURL: state.session.apiURL,
66
+ connected: options?.connected ?? true,
67
+ error: options?.error,
68
+ loading: options?.loading ?? false,
69
+ validated: true,
70
+ },
71
+ user: {
72
+ ...initialState.user,
73
+ language: state.user.language ?? initialState.user.language,
74
+ },
75
+ };
76
+ };
77
+ const getSessionValidationMismatch = ({ fetchedSession, fetchedUser, previousState, }) => {
78
+ const previousAuthToken = previousState.session.authToken ?? "";
79
+ const previousGuid = previousState.user.guid ?? "";
80
+ const previousUsername = previousState.user.username ?? "";
81
+ if (fetchedSession?.loggedIn === false) {
82
+ return true;
83
+ }
84
+ if (previousAuthToken &&
85
+ fetchedSession?.authToken &&
86
+ fetchedSession.authToken !== previousAuthToken) {
87
+ return true;
88
+ }
89
+ if (previousGuid && fetchedUser?.guid && fetchedUser.guid !== previousGuid) {
90
+ return true;
91
+ }
92
+ if (previousUsername &&
93
+ fetchedUser?.username &&
94
+ fetchedUser.username !== previousUsername) {
95
+ return true;
96
+ }
97
+ return false;
98
+ };
99
+ const hasSessionValidationSignal = (session, user) => {
100
+ return Boolean(session?.loggedIn === true ||
101
+ session?.authToken ||
102
+ user?.guid ||
103
+ user?.username);
104
+ };
48
105
  const createGlobalStateStore = () => {
49
106
  const initialState = createInitialState();
50
107
  let isStorageInitialized = false;
@@ -96,6 +153,59 @@ const createGlobalStateStore = () => {
96
153
  try {
97
154
  const currentState = getState();
98
155
  const result = await currentState.onFetchSession?.(currentState);
156
+ const hasExistingSession = hasSessionCredentials(currentState.session);
157
+ const nextUser = { ...currentState.user, ...result?.user };
158
+ const nextSession = {
159
+ ...currentState.session,
160
+ ...result?.session,
161
+ apiURL: url || currentState.session.apiURL,
162
+ connected: true,
163
+ loading: false,
164
+ };
165
+ const serverConfirmsSession = result?.session?.loggedIn === true || Boolean(result?.session?.authToken);
166
+ const serverConfirmsUser = Boolean(result?.user?.guid || result?.user?.username);
167
+ const alreadyValidated = currentState.session.validated === true;
168
+ const requiresValidation = (hasExistingSession && !alreadyValidated) || serverConfirmsSession;
169
+ const hasValidationSignal = serverConfirmsSession || serverConfirmsUser || alreadyValidated;
170
+ const hasValidationMismatch = getSessionValidationMismatch({
171
+ fetchedSession: result?.session,
172
+ fetchedUser: result?.user,
173
+ previousState: currentState,
174
+ });
175
+ const resolvedLoggedIn = result?.session?.loggedIn ??
176
+ (hasValidationSignal && Boolean(nextSession.authToken));
177
+ const resolvedSession = {
178
+ ...nextSession,
179
+ loggedIn: resolvedLoggedIn,
180
+ validated: !requiresValidation || hasValidationSignal,
181
+ };
182
+ const isInvalidSession = hasValidationMismatch ||
183
+ isSessionExpired(resolvedSession) ||
184
+ (requiresValidation &&
185
+ (!hasValidationSignal ||
186
+ !resolvedSession.loggedIn ||
187
+ !resolvedSession.authToken));
188
+ if (isInvalidSession) {
189
+ const clearedState = createClearedAuthenticatedState(currentState);
190
+ setGlobalState((state) => ({
191
+ ...state,
192
+ ...result,
193
+ layout: { ...state.layout, ...result?.layout },
194
+ navigation: { ...state.navigation, ...result?.navigation },
195
+ owner: { ...clearedState.owner, ...result?.owner },
196
+ program: {
197
+ ...clearedState.program,
198
+ ...result?.program,
199
+ updatedAt: new Date().toISOString(),
200
+ },
201
+ session: {
202
+ ...clearedState.session,
203
+ apiURL: url || state.session.apiURL,
204
+ },
205
+ user: clearedState.user,
206
+ }));
207
+ return;
208
+ }
99
209
  setGlobalState((state) => ({
100
210
  ...state,
101
211
  ...result,
@@ -107,21 +217,17 @@ const createGlobalStateStore = () => {
107
217
  ...result?.program,
108
218
  updatedAt: new Date().toISOString(),
109
219
  },
110
- session: {
111
- ...state.session,
112
- ...result?.session,
113
- connected: true,
114
- loading: false,
115
- },
116
- user: { ...state.user, ...result?.user },
220
+ session: resolvedSession,
221
+ user: nextUser,
117
222
  }));
118
223
  }
119
224
  catch (e) {
225
+ const error = `Load Exception: ${String(e)}`;
120
226
  setGlobalState((state) => ({
121
227
  session: {
122
228
  ...state.session,
123
229
  connected: false,
124
- error: `Load Exception: ${String(e)}`,
230
+ error,
125
231
  loading: false,
126
232
  },
127
233
  }));
@@ -134,10 +240,10 @@ const createGlobalStateStore = () => {
134
240
  },
135
241
  isLoggedIn: () => {
136
242
  const session = getState().session;
137
- if (!session.loggedIn || !session.authToken) {
243
+ if (!session.validated || !session.loggedIn || !session.authToken) {
138
244
  return false;
139
245
  }
140
- if (session.expiryDate && new Date(session.expiryDate) < new Date()) {
246
+ if (isSessionExpired(session)) {
141
247
  return false;
142
248
  }
143
249
  return true;
@@ -152,7 +258,8 @@ const createGlobalStateStore = () => {
152
258
  authToken: authToken ?? "",
153
259
  expiryDate: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(),
154
260
  loading: true,
155
- loggedIn: true,
261
+ loggedIn: false,
262
+ validated: false,
156
263
  },
157
264
  user: {
158
265
  ...state.user,
@@ -162,6 +269,7 @@ const createGlobalStateStore = () => {
162
269
  const currentState = getState();
163
270
  const result = await currentState.onLogin?.(currentState);
164
271
  if (result) {
272
+ const loginValidated = hasSessionValidationSignal(result.session, result.user);
165
273
  setGlobalState((state) => ({
166
274
  owner: result.owner
167
275
  ? { ...state.owner, ...result.owner }
@@ -169,9 +277,13 @@ const createGlobalStateStore = () => {
169
277
  program: result.program
170
278
  ? { ...state.program, ...result.program }
171
279
  : state.program,
172
- session: result.session
173
- ? { ...state.session, ...result.session }
174
- : state.session,
280
+ session: {
281
+ ...state.session,
282
+ ...result.session,
283
+ loggedIn: result.session?.loggedIn ??
284
+ (loginValidated && Boolean(result.session?.authToken ?? state.session.authToken)),
285
+ validated: loginValidated ? true : state.session.validated,
286
+ },
175
287
  user: result.user
176
288
  ? { ...state.user, ...result.user }
177
289
  : state.user,
@@ -180,14 +292,14 @@ const createGlobalStateStore = () => {
180
292
  await fetchDataInternal();
181
293
  }
182
294
  catch (e) {
295
+ const currentState = getState();
296
+ const clearedState = createClearedAuthenticatedState(currentState, {
297
+ connected: false,
298
+ error: `Login Exception: ${String(e)}`,
299
+ });
183
300
  setGlobalState((state) => ({
184
- session: {
185
- ...state.session,
186
- connected: false,
187
- error: `Login Exception: ${String(e)}`,
188
- loading: false,
189
- loggedIn: false,
190
- },
301
+ ...state,
302
+ ...clearedState,
191
303
  }));
192
304
  }
193
305
  finally {
@@ -203,6 +315,7 @@ const createGlobalStateStore = () => {
203
315
  logout: async () => {
204
316
  await waitForInitialization();
205
317
  return withOperationLock(async () => {
318
+ const previousState = getState();
206
319
  try {
207
320
  setGlobalState((state) => ({
208
321
  ...createInitialState(),
@@ -215,7 +328,7 @@ const createGlobalStateStore = () => {
215
328
  },
216
329
  }));
217
330
  const currentState = getState();
218
- const result = await currentState.onLogout?.(currentState);
331
+ const result = await currentState.onLogout?.(previousState);
219
332
  if (result) {
220
333
  setGlobalState((state) => ({
221
334
  owner: result.owner
@@ -235,13 +348,14 @@ const createGlobalStateStore = () => {
235
348
  await fetchDataInternal();
236
349
  }
237
350
  catch (e) {
351
+ const currentState = getState();
352
+ const clearedState = createClearedAuthenticatedState(currentState, {
353
+ connected: false,
354
+ error: `Logout Exception: ${String(e)}`,
355
+ });
238
356
  setGlobalState((state) => ({
239
- session: {
240
- ...state.session,
241
- connected: false,
242
- error: `Logout Exception: ${String(e)}`,
243
- loading: false,
244
- },
357
+ ...state,
358
+ ...clearedState,
245
359
  }));
246
360
  }
247
361
  finally {
@@ -319,6 +433,7 @@ const createGlobalStateStore = () => {
319
433
  store.set(initialStoreState);
320
434
  initializationPromise = loadStorage()
321
435
  .then((loadedState) => {
436
+ const hasPersistedSession = hasSessionCredentials(loadedState.session);
322
437
  setGlobalState((current) => ({
323
438
  ...current,
324
439
  ...loadedState,
@@ -328,6 +443,12 @@ const createGlobalStateStore = () => {
328
443
  ...loadedState.session,
329
444
  connected: true,
330
445
  loading: false,
446
+ loggedIn: hasPersistedSession
447
+ ? false
448
+ : loadedState.session?.loggedIn ?? current.session.loggedIn,
449
+ validated: hasPersistedSession
450
+ ? false
451
+ : loadedState.session?.validated ?? current.session.validated,
331
452
  },
332
453
  }));
333
454
  })
@@ -386,4 +507,4 @@ const GetGlobalState = () => {
386
507
  const setLanguage = (lang) => {
387
508
  GlobalStateStore.getState().setLanguage(lang);
388
509
  };
389
- export { getApiURL, getAuthToken, GetGlobalState, GlobalStateStore, isLoggedIn, languageStore, setApiURL, setAuthToken, setLanguage, useGlobalStateStore, };
510
+ export { createGlobalStateStore, getApiURL, getAuthToken, GetGlobalState, GlobalStateStore, isLoggedIn, languageStore, setApiURL, setAuthToken, setLanguage, useGlobalStateStore, };
@@ -107,6 +107,7 @@ interface SessionState {
107
107
  loggedIn?: boolean;
108
108
  meta?: Record<string, any>;
109
109
  parameters?: Record<string, any>;
110
+ validated?: boolean;
110
111
  }
111
112
  type SupportedLanguage = 'af' | 'en';
112
113
  interface ThemeSettings {
@@ -3,7 +3,8 @@ const SKIP_PATHS = new Set([
3
3
  'app.controls',
4
4
  'session.connected',
5
5
  'session.error',
6
- 'session.loading'
6
+ 'session.loading',
7
+ 'session.validated'
7
8
  ]);
8
9
  const PERSIST_KEYS = [
9
10
  'layout',
@@ -28,6 +28,8 @@
28
28
  item?: Record<string, unknown>;
29
29
  column?: GridlerColumn;
30
30
  }) => void;
31
+ onRowClick?: (row: number) => void;
32
+ onRowContextMenu?: (row: number) => void;
31
33
  /** Resolve raw row data by row index for populating onCellEvent. */
32
34
  getRowData?: (row: number) => Record<string, unknown> | undefined;
33
35
  children?: Snippet;
@@ -59,6 +61,8 @@
59
61
  onHeaderContextMenu,
60
62
  onMenuClick,
61
63
  onGridMenuOpen,
64
+ onRowClick,
65
+ onRowContextMenu,
62
66
  theme = {},
63
67
  selection = { type: "none" } as Selection,
64
68
  onSelectionChange,
@@ -434,6 +438,9 @@
434
438
  onCellEvent?.("dblclick", getRowData?.(item[1]) ?? {}, columns[item[0]] ?? { id: "", title: "" });
435
439
  onGridEvent?.("dblclick", getRowData?.(item[1]) ?? {}, columns[item[0]] ?? { id: "", title: "" });
436
440
  }}
441
+ onRowClick={(row) => {
442
+ onRowClick?.(row);
443
+ }}
437
444
  onCellClick={(item) => {
438
445
  onCellEvent?.("click", getRowData?.(item[1]) ?? {}, columns[item[0]] ?? { id: "", title: "" });
439
446
  onGridEvent?.("click", getRowData?.(item[1]) ?? {}, columns[item[0]] ?? { id: "", title: "" });
@@ -450,6 +457,9 @@
450
457
  onCellEvent?.("contextmenu", getRowData?.(item[1]) ?? {}, columns[item[0]] ?? { id: "", title: "" }, { x, y });
451
458
  onGridEvent?.("contextmenu", getRowData?.(item[1]) ?? {}, columns[item[0]] ?? { id: "", title: "" }, { x, y });
452
459
  }}
460
+ onRowContextMenu={(row) => {
461
+ onRowContextMenu?.(row);
462
+ }}
453
463
  onColumnResized={(col, width) => {
454
464
  onGridEvent?.("column_resized", undefined, columns[col], undefined, { width });
455
465
  }}
@@ -13,6 +13,8 @@ export interface Props extends Partial<GridlerProps> {
13
13
  item?: Record<string, unknown>;
14
14
  column?: GridlerColumn;
15
15
  }) => void;
16
+ onRowClick?: (row: number) => void;
17
+ onRowContextMenu?: (row: number) => void;
16
18
  /** Resolve raw row data by row index for populating onCellEvent. */
17
19
  getRowData?: (row: number) => Record<string, unknown> | undefined;
18
20
  children?: Snippet;
@@ -56,6 +56,8 @@
56
56
  onVisibleRangeChange?: (range: VisibleRange) => void;
57
57
  onSelectionChange?: (sel: Selection) => void;
58
58
  onCellDblClick?: (item: Item, cell: GridlerCell) => void;
59
+ onRowClick?: (row: number) => void;
60
+ onRowContextMenu?: (row: number) => void;
59
61
  onColumnMoved?: (from: number, to: number) => void;
60
62
  onCellEdited?: (item: Item, cell: GridlerCell) => void;
61
63
  onDelete?: (sel: Selection) => void;
@@ -107,6 +109,8 @@
107
109
  onVisibleRangeChange,
108
110
  onSelectionChange,
109
111
  onCellDblClick,
112
+ onRowClick,
113
+ onRowContextMenu,
110
114
  onColumnMoved,
111
115
  onCellEdited: _onCellEdited,
112
116
  onDelete: _onDelete,
@@ -484,7 +488,7 @@
484
488
  // ── Header context menu ───────────────────────────────────────────────────────
485
489
 
486
490
  function handleContextMenu(e: MouseEvent) {
487
- if (e.offsetX < rowMarkerWidth) return;
491
+ if (e.offsetY < headerHeight && e.offsetX < rowMarkerWidth) return;
488
492
  const fixedBoundaryX =
489
493
  fixedColumns > 0
490
494
  ? getColumnX(effectiveColumns, Math.min(fixedColumns, columns.length))
@@ -503,6 +507,14 @@
503
507
  return;
504
508
  }
505
509
 
510
+ const row = getRowFromOffsetY(e.offsetY);
511
+ if (row !== null) {
512
+ e.preventDefault();
513
+ onRowContextMenu?.(row);
514
+ }
515
+
516
+ if (e.offsetX < rowMarkerWidth) return;
517
+
506
518
  if (onCellContextMenu) {
507
519
  const cell = getCellFromPoint(
508
520
  localX,
@@ -537,6 +549,12 @@
537
549
 
538
550
  // ── Mouse handlers ────────────────────────────────────────────────────────────
539
551
 
552
+ function getRowFromOffsetY(offsetY: number): number | null {
553
+ if (offsetY < headerHeight) return null;
554
+ const row = Math.floor((offsetY - headerHeight + scrollY) / rowHeight);
555
+ return row >= 0 && row < rows ? row : null;
556
+ }
557
+
540
558
  function handleMouseDown(e: MouseEvent) {
541
559
  if (e.button !== 0) return;
542
560
  pendingGridMenuOpen = false;
@@ -630,6 +648,11 @@
630
648
  return;
631
649
  }
632
650
 
651
+ const row = getRowFromOffsetY(e.offsetY);
652
+ if (row !== null) {
653
+ onRowClick?.(row);
654
+ }
655
+
633
656
  if (readonly) return;
634
657
 
635
658
  const cell = getCellFromPoint(
@@ -1055,7 +1078,7 @@
1055
1078
  }
1056
1079
 
1057
1080
  if (rowMarkers !== "none" && offsetX < rowMarkerWidth) {
1058
- const row = Math.floor((offsetY - headerHeight + scrollY) / rowHeight);
1081
+ const row = getRowFromOffsetY(offsetY);
1059
1082
  if (row >= 0 && row < rows) {
1060
1083
  onRowToggle?.(row);
1061
1084
  }
@@ -25,6 +25,8 @@ interface Props {
25
25
  onVisibleRangeChange?: (range: VisibleRange) => void;
26
26
  onSelectionChange?: (sel: Selection) => void;
27
27
  onCellDblClick?: (item: Item, cell: GridlerCell) => void;
28
+ onRowClick?: (row: number) => void;
29
+ onRowContextMenu?: (row: number) => void;
28
30
  onColumnMoved?: (from: number, to: number) => void;
29
31
  onCellEdited?: (item: Item, cell: GridlerCell) => void;
30
32
  onDelete?: (sel: Selection) => void;
@@ -38,6 +38,8 @@
38
38
  | "onSearchValueChange"
39
39
  | "onVisibleRangeChange"
40
40
  | "onCellDblClick"
41
+ | "onRowClick"
42
+ | "onRowContextMenu"
41
43
  > {
42
44
  columns: GridlerColumn[];
43
45
 
@@ -81,6 +83,16 @@
81
83
  row: number,
82
84
  rowData: Record<string, unknown> | undefined,
83
85
  ) => void;
86
+ /** Called on row click with the row index and resolved row data. */
87
+ onRowClick?: (
88
+ row: number,
89
+ rowData: Record<string, unknown> | undefined,
90
+ ) => void;
91
+ /** Called on row context-menu with the row index and resolved row data. */
92
+ onRowContextMenu?: (
93
+ row: number,
94
+ rowData: Record<string, unknown> | undefined,
95
+ ) => void;
84
96
 
85
97
  // ── Server-side fetching ──────────────────────────────────────────────────
86
98
  // Use dataSource + dataSourceOptions (from GridCommonProps) for server config.
@@ -157,6 +169,8 @@
157
169
  onCellEdited,
158
170
  onCellDblClick,
159
171
  onRowDblClick,
172
+ onRowClick,
173
+ onRowContextMenu,
160
174
  onMenuClick,
161
175
  onSelectionChange,
162
176
  onCellEvent,
@@ -656,6 +670,14 @@
656
670
  onRowDblClick?.(item[1], rowData);
657
671
  }
658
672
 
673
+ function handleRowClick(row: number) {
674
+ onRowClick?.(row, resolveRowData(row));
675
+ }
676
+
677
+ function handleRowContextMenu(row: number) {
678
+ onRowContextMenu?.(row, resolveRowData(row));
679
+ }
680
+
659
681
  // ── Selection → selectedItems bridge ──────────────────────────────────────
660
682
 
661
683
  let internalSelectedItems = $state<Record<string, unknown>[]>([]);
@@ -777,6 +799,8 @@
777
799
  onCellEdited?.(item, value);
778
800
  }}
779
801
  onCellDblClick={handleCellDblClick}
802
+ onRowClick={handleRowClick}
803
+ onRowContextMenu={handleRowContextMenu}
780
804
  selectedItems={internalSelectedItems}
781
805
  getRowData={resolveRowData}
782
806
  onSelectionChange={handleSelectionChange}
@@ -1,6 +1,6 @@
1
1
  import type { Snippet } from "svelte";
2
2
  import type { GridlerCell, GridlerColumn, GridlerContextMenuItem, GridlerProps, Item } from "../types";
3
- export interface Props extends Omit<Partial<GridlerProps>, "columns" | "rows" | "getCellContent" | "searchValue" | "onSearchValueChange" | "onVisibleRangeChange" | "onCellDblClick"> {
3
+ export interface Props extends Omit<Partial<GridlerProps>, "columns" | "rows" | "getCellContent" | "searchValue" | "onSearchValueChange" | "onVisibleRangeChange" | "onCellDblClick" | "onRowClick" | "onRowContextMenu"> {
4
4
  columns: GridlerColumn[];
5
5
  /**
6
6
  * Optional row data. When provided (and `getCellContent` is omitted), the default
@@ -28,6 +28,10 @@ export interface Props extends Omit<Partial<GridlerProps>, "columns" | "rows" |
28
28
  onCellDblClick?: (item: Item, cell: GridlerCell, rowData: Record<string, unknown> | undefined) => void;
29
29
  /** Called on row double-click with the row index and resolved row data. */
30
30
  onRowDblClick?: (row: number, rowData: Record<string, unknown> | undefined) => void;
31
+ /** Called on row click with the row index and resolved row data. */
32
+ onRowClick?: (row: number, rowData: Record<string, unknown> | undefined) => void;
33
+ /** Called on row context-menu with the row index and resolved row data. */
34
+ onRowContextMenu?: (row: number, rowData: Record<string, unknown> | undefined) => void;
31
35
  /** Rows per cursor-forward page. Defaults to 200. */
32
36
  pageSize?: number;
33
37
  /**
@@ -103,6 +103,10 @@ export interface GridlerProps extends GridCommonProps<Record<string, unknown>> {
103
103
  onCellEdited?: (item: Item, value: GridlerCell) => void;
104
104
  /** Called on cell double-click (low-level; GridlerFull enriches with row data). */
105
105
  onCellDblClick?: (item: Item, cell: GridlerCell) => void;
106
+ /** Called when a body row is clicked. */
107
+ onRowClick?: (row: number) => void;
108
+ /** Called when a body row receives a context-menu event. */
109
+ onRowContextMenu?: (row: number) => void;
106
110
  /** Called when Tab moves past the last column of the last row. */
107
111
  onRowAppended?: () => void;
108
112
  /** Called when Delete/Backspace is pressed with a selection. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@warkypublic/svelix",
3
- "version": "0.1.31",
3
+ "version": "0.1.32",
4
4
  "description": "Svelte 5 component library with Skeleton UI and Tailwind CSS",
5
5
  "license": "Apache-2.0",
6
6
  "exports": {