@rio-cloud/uikit-mcp 1.1.9 → 1.1.11

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.
Files changed (211) hide show
  1. package/README.md +2 -1
  2. package/dist/doc-metadata.json +334 -94
  3. package/dist/docs/components/accentBar.md +110 -116
  4. package/dist/docs/components/activity.md +1 -1
  5. package/dist/docs/components/analyticsAnalysisOverlay.md +630 -0
  6. package/dist/docs/components/animatedNumber.md +2 -2
  7. package/dist/docs/components/animatedTextReveal.md +53 -55
  8. package/dist/docs/components/animations.md +21 -21
  9. package/dist/docs/components/appHeader.md +27 -38
  10. package/dist/docs/components/appLayout.md +23 -77
  11. package/dist/docs/components/appNavigationBar.md +1 -1
  12. package/dist/docs/components/areaCharts.md +57 -61
  13. package/dist/docs/components/aspectRatioPlaceholder.md +1 -1
  14. package/dist/docs/components/assetTree.md +429 -342
  15. package/dist/docs/components/autosuggests.md +1 -1
  16. package/dist/docs/components/avatar.md +1 -1
  17. package/dist/docs/components/banner.md +2 -2
  18. package/dist/docs/components/barCharts.md +530 -414
  19. package/dist/docs/components/barList.md +10 -10
  20. package/dist/docs/components/basicMap.md +104 -39
  21. package/dist/docs/components/bottomSheet.md +2 -2
  22. package/dist/docs/components/button.md +8 -2
  23. package/dist/docs/components/buttonToolbar.md +1 -1
  24. package/dist/docs/components/calendarStripe.md +59 -63
  25. package/dist/docs/components/card.md +1 -1
  26. package/dist/docs/components/carousel.md +1 -1
  27. package/dist/docs/components/chartColors.md +1 -1
  28. package/dist/docs/components/chartsGettingStarted.md +1 -1
  29. package/dist/docs/components/chat.md +2 -2
  30. package/dist/docs/components/checkbox.md +15 -10
  31. package/dist/docs/components/circularProgress.md +6 -6
  32. package/dist/docs/components/clearableInput.md +1 -1
  33. package/dist/docs/components/collapse.md +2 -2
  34. package/dist/docs/components/composedCharts.md +63 -51
  35. package/dist/docs/components/contentLoader.md +1 -1
  36. package/dist/docs/components/dataTabs.md +33 -33
  37. package/dist/docs/components/datepickers.md +693 -685
  38. package/dist/docs/components/dayPicker.md +5624 -0
  39. package/dist/docs/components/dayPickerCalendar.md +5289 -0
  40. package/dist/docs/components/dialogs.md +17 -19
  41. package/dist/docs/components/divider.md +1 -1
  42. package/dist/docs/components/dropdowns.md +3264 -3276
  43. package/dist/docs/components/editableContent.md +91 -91
  44. package/dist/docs/components/expander.md +4 -1
  45. package/dist/docs/components/fade.md +1 -1
  46. package/dist/docs/components/fadeExpander.md +1 -1
  47. package/dist/docs/components/fadeUp.md +32 -36
  48. package/dist/docs/components/feedback.md +1 -1
  49. package/dist/docs/components/filePickers.md +1 -1
  50. package/dist/docs/components/formLabel.md +29 -31
  51. package/dist/docs/components/groupedItemList.md +3 -7
  52. package/dist/docs/components/htmlTable.md +5074 -0
  53. package/dist/docs/components/iconList.md +4 -4
  54. package/dist/docs/components/imagePreloader.md +1 -1
  55. package/dist/docs/components/labeledElement.md +1 -1
  56. package/dist/docs/components/licensePlate.md +1 -1
  57. package/dist/docs/components/lineCharts.md +172 -170
  58. package/dist/docs/components/listMenu.md +15 -12
  59. package/dist/docs/components/loadMore.md +4 -2
  60. package/dist/docs/components/mainNavigation.md +1 -1
  61. package/dist/docs/components/mapCircle.md +10 -1
  62. package/dist/docs/components/mapCluster.md +25 -1
  63. package/dist/docs/components/mapContext.md +12 -4
  64. package/dist/docs/components/mapDraggableMarker.md +12 -1
  65. package/dist/docs/components/mapGettingStarted.md +39 -1
  66. package/dist/docs/components/mapInfoBubble.md +129 -2
  67. package/dist/docs/components/mapLayerGroup.md +10 -1
  68. package/dist/docs/components/mapMarker.md +10 -1
  69. package/dist/docs/components/mapPolygon.md +288 -85
  70. package/dist/docs/components/mapRoute.md +262 -172
  71. package/dist/docs/components/mapSettings.md +28 -1
  72. package/dist/docs/components/mapUtils.md +1 -1
  73. package/dist/docs/components/mapViewportHistory.md +287 -0
  74. package/dist/docs/components/multiselects.md +217 -18
  75. package/dist/docs/components/noData.md +1 -1
  76. package/dist/docs/components/notifications.md +2 -2
  77. package/dist/docs/components/numbercontrol.md +15 -15
  78. package/dist/docs/components/onboarding.md +1 -1
  79. package/dist/docs/components/page.md +1 -1
  80. package/dist/docs/components/pager.md +1 -1
  81. package/dist/docs/components/pieCharts.md +237 -211
  82. package/dist/docs/components/popover.md +1 -1
  83. package/dist/docs/components/position.md +1 -1
  84. package/dist/docs/components/radialBarCharts.md +446 -398
  85. package/dist/docs/components/radioCardGroup.md +1 -1
  86. package/dist/docs/components/radiobutton.md +98 -98
  87. package/dist/docs/components/releaseNotes.md +1 -1
  88. package/dist/docs/components/resizer.md +1 -1
  89. package/dist/docs/components/responsiveColumnStripe.md +1 -1
  90. package/dist/docs/components/responsiveVideo.md +1 -1
  91. package/dist/docs/components/rioglyph.md +1 -1
  92. package/dist/docs/components/rules.md +41 -47
  93. package/dist/docs/components/saveableInput.md +252 -252
  94. package/dist/docs/components/selects.md +332 -161
  95. package/dist/docs/components/sidebar.md +1 -1
  96. package/dist/docs/components/sliders.md +1 -1
  97. package/dist/docs/components/smoothScrollbars.md +19 -13
  98. package/dist/docs/components/spinners.md +1 -1
  99. package/dist/docs/components/states.md +15 -1
  100. package/dist/docs/components/statsWidgets.md +1 -1
  101. package/dist/docs/components/statusBar.md +3 -1
  102. package/dist/docs/components/stepButton.md +1 -1
  103. package/dist/docs/components/steppedProgressBars.md +9 -11
  104. package/dist/docs/components/subNavigation.md +1 -1
  105. package/dist/docs/components/supportMarker.md +1 -1
  106. package/dist/docs/components/svgImage.md +1 -1
  107. package/dist/docs/components/switch.md +5 -1
  108. package/dist/docs/components/table.md +21361 -0
  109. package/dist/docs/components/tableControls.md +982 -0
  110. package/dist/docs/components/tagManager.md +1 -1
  111. package/dist/docs/components/tags.md +1 -1
  112. package/dist/docs/components/teaser.md +1 -1
  113. package/dist/docs/components/textTruncateMiddle.md +1 -1
  114. package/dist/docs/components/timeline.md +1 -1
  115. package/dist/docs/components/timepicker.md +3 -1
  116. package/dist/docs/components/toggleButton.md +3 -1
  117. package/dist/docs/components/tooltip.md +8 -2
  118. package/dist/docs/components/tracker.md +1 -1
  119. package/dist/docs/components/virtualList.md +60 -60
  120. package/dist/docs/foundations.md +761 -3077
  121. package/dist/docs/start/changelog.md +73 -3
  122. package/dist/docs/start/goodtoknow.md +5 -1
  123. package/dist/docs/start/guidelines/color-combinations.md +5 -1
  124. package/dist/docs/start/guidelines/custom-css.md +26 -2
  125. package/dist/docs/start/guidelines/custom-rioglyph.md +20 -2
  126. package/dist/docs/start/guidelines/formatting.md +2254 -249
  127. package/dist/docs/start/guidelines/iframe.md +53 -19
  128. package/dist/docs/start/guidelines/obfuscate-data.md +24 -2
  129. package/dist/docs/start/guidelines/print-css.md +16 -2
  130. package/dist/docs/start/guidelines/spinner.md +1 -1
  131. package/dist/docs/start/guidelines/state-in-url.md +1138 -11
  132. package/dist/docs/start/guidelines/supported-browsers.md +9 -2
  133. package/dist/docs/start/guidelines/writing.md +228 -2
  134. package/dist/docs/start/howto.md +155 -13
  135. package/dist/docs/start/intro.md +40 -2
  136. package/dist/docs/start/responsiveness.md +27 -1
  137. package/dist/docs/templates/ai-assistant.md +311 -0
  138. package/dist/docs/templates/common-table.md +814 -0
  139. package/dist/docs/templates/detail-views.md +846 -0
  140. package/dist/docs/templates/expandable-details.md +214 -0
  141. package/dist/docs/templates/feature-cards.md +479 -0
  142. package/dist/docs/templates/form-summary.md +179 -0
  143. package/dist/docs/templates/form-toggle.md +329 -0
  144. package/dist/docs/templates/list-blocks.md +872 -0
  145. package/dist/docs/templates/loading-progress.md +100 -0
  146. package/dist/docs/templates/options-panel.md +132 -0
  147. package/dist/docs/templates/panel-variants.md +137 -0
  148. package/dist/docs/templates/progress-cards.md +541 -0
  149. package/dist/docs/templates/progress-success.md +125 -0
  150. package/dist/docs/templates/settings-form.md +401 -0
  151. package/dist/docs/templates/stats-blocks.md +1245 -0
  152. package/dist/docs/templates/table-panel.md +310 -0
  153. package/dist/docs/templates/usage-cards.md +199 -0
  154. package/dist/docs/utilities/classNames.md +89 -1
  155. package/dist/docs/utilities/deviceUtils.md +2 -2
  156. package/dist/docs/utilities/featureToggles.md +182 -2
  157. package/dist/docs/utilities/fuelTypeUtils.md +27 -29
  158. package/dist/docs/utilities/getTrackingAttributes.md +322 -0
  159. package/dist/docs/utilities/routeUtils.md +211 -3
  160. package/dist/docs/utilities/useAfterMount.md +1 -1
  161. package/dist/docs/utilities/useAutoAnimate.md +1 -1
  162. package/dist/docs/utilities/useAverage.md +1 -1
  163. package/dist/docs/utilities/useClickOutside.md +1 -1
  164. package/dist/docs/utilities/useClipboard.md +2 -2
  165. package/dist/docs/utilities/useCookies.md +1 -1
  166. package/dist/docs/utilities/useCount.md +1 -1
  167. package/dist/docs/utilities/useDarkMode.md +5 -4
  168. package/dist/docs/utilities/useDebugInfo.md +3 -3
  169. package/dist/docs/utilities/useDraggableElement.md +281 -0
  170. package/dist/docs/utilities/useEffectOnce.md +1 -1
  171. package/dist/docs/utilities/useElapsedTime.md +1 -1
  172. package/dist/docs/utilities/useElementSize.md +1 -1
  173. package/dist/docs/utilities/useEsc.md +1 -1
  174. package/dist/docs/utilities/useEvent.md +1 -1
  175. package/dist/docs/utilities/useFocusTrap.md +1 -1
  176. package/dist/docs/utilities/useFullscreen.md +1 -1
  177. package/dist/docs/utilities/useHover.md +1 -1
  178. package/dist/docs/utilities/useIncomingPostMessages.md +1 -1
  179. package/dist/docs/utilities/useInterval.md +1 -1
  180. package/dist/docs/utilities/useIsFocusWithin.md +1 -1
  181. package/dist/docs/utilities/useKey.md +8 -10
  182. package/dist/docs/utilities/useLocalStorage.md +1 -1
  183. package/dist/docs/utilities/useLocationSuggestions.md +1 -1
  184. package/dist/docs/utilities/useMax.md +1 -1
  185. package/dist/docs/utilities/useMin.md +1 -1
  186. package/dist/docs/utilities/useMutationObserver.md +1 -1
  187. package/dist/docs/utilities/useOnScreen.md +1 -1
  188. package/dist/docs/utilities/useOnlineStatus.md +1 -1
  189. package/dist/docs/utilities/usePostMessage.md +2 -2
  190. package/dist/docs/utilities/usePostMessageSender.md +1 -1
  191. package/dist/docs/utilities/usePrevious.md +110 -2
  192. package/dist/docs/utilities/useResizeObserver.md +35 -15
  193. package/dist/docs/utilities/useRioCookieConsent.md +1 -1
  194. package/dist/docs/utilities/useScrollPosition.md +3 -6
  195. package/dist/docs/utilities/useSearch.md +1 -3
  196. package/dist/docs/utilities/useSearchHighlight.md +1 -1
  197. package/dist/docs/utilities/useSorting.md +370 -239
  198. package/dist/docs/utilities/useStateWithValidation.md +1 -1
  199. package/dist/docs/utilities/useSum.md +1 -1
  200. package/dist/docs/utilities/useTableExport.md +364 -288
  201. package/dist/docs/utilities/useTableSelection.md +88 -92
  202. package/dist/docs/utilities/useTimeout.md +1 -1
  203. package/dist/docs/utilities/useToggle.md +1 -1
  204. package/dist/docs/utilities/useUrlState.md +1 -1
  205. package/dist/docs/utilities/useWindowResize.md +1 -1
  206. package/dist/index.mjs +173 -69
  207. package/dist/search-synonyms.json +214 -76
  208. package/dist/version.json +2 -2
  209. package/package.json +4 -5
  210. package/dist/docs/components/mapRouteGenerator.md +0 -6
  211. package/dist/docs/components/tables.md +0 -8
@@ -3,7 +3,7 @@
3
3
  *Category:* Getting started
4
4
  *Section:* Guidelines
5
5
  *Source:* https://uikit.developers.rio.cloud/#/start/guidelines/state-in-url
6
- *Captured:* 2026-03-06T10:39:53.019Z
6
+ *Captured:* 2026-04-27T14:57:05.030Z
7
7
 
8
8
  Every service frontend should support deep linking and reflect meaningful UI state in the URL. This enables restoring state when links are shared, when they are stored as bookmarks, when users navigate with browser history, or when a service is opened from another app.
9
9
 
@@ -35,6 +35,20 @@ Before putting something in the URL, ask:
35
35
  - UI configuration that affects content (e.g. grouping, expanded views)
36
36
  - Feature variants (only if stable and safe to share)
37
37
 
38
+ Search queries and filters
39
+
40
+ Sorting and column visibility (when it changes what users see)
41
+
42
+ View modes (list/grid/table/map)
43
+
44
+ Date ranges and time periods
45
+
46
+ Selected items or active tabs (focus)
47
+
48
+ UI configuration that affects content (e.g. grouping, expanded views)
49
+
50
+ Feature variants (only if stable and safe to share)
51
+
38
52
  ## Poor candidates
39
53
 
40
54
  - Sensitive information (passwords, tokens, PII) - NEVER!
@@ -44,6 +58,18 @@ Before putting something in the URL, ask:
44
58
  - Base64 encoded data
45
59
  - High-frequency transient state (mouse position, scroll)
46
60
 
61
+ Sensitive information (passwords, tokens, PII) - NEVER!
62
+
63
+ Temporary UI states (e.g. dropdown expanded, tooltip open)
64
+
65
+ Form input in progress (unsaved changes)
66
+
67
+ Very large or complex nested data
68
+
69
+ Base64 encoded data
70
+
71
+ High-frequency transient state (mouse position, scroll)
72
+
47
73
  ## Example deep links
48
74
 
49
75
  Prefer readable, self-describing URLs. Use consistent naming across services to make deep links easier to share and reason about.
@@ -70,6 +96,17 @@ Treat the URL as user input. Invalid or unknown params should not break renderin
70
96
 
71
97
  Use consistent, concise camelCase param names across services whenever possible. If URLs become verbose, prefer a well-known short form (e.g. q, lat / lng) and document it so other teams can align.
72
98
 
99
+ | Name | Description |
100
+ | --- | --- |
101
+ | assetIds | Comma-separated list of selected assets (stable IDs). |
102
+ | q | Search query (encode with encodeURIComponent). This short form is common in many search engines. No need to use verbose keys here. |
103
+ | sort | Sort key; use key / -key for direction. Prefer stable keys over display labels. |
104
+ | lat / lng | Latitude / longitude in decimal degrees. Avoid unnecessary precision. |
105
+ | z | Zoom level (integer). |
106
+ | startDate / endDate | Start and end timestamps. Prefer ISO formats and document timezone expectations (recommend UTC). |
107
+ | selectedAssetId / selectedIssue | Focused item in list/detail context. Prefer explicit names over generic placeholders. |
108
+ | viewType | Display mode (table/grid/map). Use a limited set of values. |
109
+
73
110
  ## URLs as contracts
74
111
 
75
112
  Well-designed URLs are more than a storage place for state. They become a contract between your app and its consumers, setting expectations for humans, developers, and machines.
@@ -131,6 +168,470 @@ onNavigate: (search, mode) => navigate({ search }, { replace: mode === 'replace'
131
168
  });
132
169
  ```
133
170
 
171
+ import
172
+
173
+ {
174
+
175
+ ,
176
+
177
+ ,
178
+
179
+ }
180
+
181
+ from
182
+
183
+ 'react-router-dom'
184
+
185
+ ;
186
+
187
+ import
188
+
189
+ from
190
+
191
+ '@rio-cloud/rio-uikit/useUrlState'
192
+
193
+ ;
194
+
195
+ import
196
+
197
+ type
198
+
199
+ {
200
+
201
+ }
202
+
203
+ from
204
+
205
+ '@rio-cloud/rio-uikit/routeUtils'
206
+
207
+ ;
208
+
209
+ type
210
+
211
+ ViewType
212
+
213
+ =
214
+
215
+ 'list'
216
+
217
+ |
218
+
219
+ 'grid'
220
+
221
+ ;
222
+
223
+ type
224
+
225
+ AppState
226
+
227
+ =
228
+
229
+ {
230
+
231
+ :
232
+
233
+ string
234
+
235
+ ;
236
+
237
+ :
238
+
239
+ ;
240
+
241
+ :
242
+
243
+ string
244
+
245
+ [
246
+
247
+ ]
248
+
249
+ }
250
+
251
+ ;
252
+
253
+ const
254
+
255
+ =
256
+
257
+ {
258
+
259
+ setQuery
260
+
261
+ :
262
+
263
+ (
264
+
265
+ :
266
+
267
+ string
268
+
269
+ )
270
+
271
+ =>
272
+
273
+ (
274
+
275
+ {
276
+
277
+ :
278
+
279
+ 'setQuery'
280
+
281
+ as
282
+
283
+ const
284
+
285
+ ,
286
+
287
+ :
288
+
289
+ }
290
+
291
+ )
292
+
293
+ ,
294
+
295
+ setViewType
296
+
297
+ :
298
+
299
+ (
300
+
301
+ :
302
+
303
+ )
304
+
305
+ =>
306
+
307
+ (
308
+
309
+ {
310
+
311
+ :
312
+
313
+ 'setViewType'
314
+
315
+ as
316
+
317
+ const
318
+
319
+ ,
320
+
321
+ :
322
+
323
+ }
324
+
325
+ )
326
+
327
+ ,
328
+
329
+ setTags
330
+
331
+ :
332
+
333
+ (
334
+
335
+ :
336
+
337
+ string
338
+
339
+ [
340
+
341
+ ]
342
+
343
+ )
344
+
345
+ =>
346
+
347
+ (
348
+
349
+ {
350
+
351
+ :
352
+
353
+ 'setTags'
354
+
355
+ as
356
+
357
+ const
358
+
359
+ ,
360
+
361
+ :
362
+
363
+ }
364
+
365
+ )
366
+
367
+ ,
368
+
369
+ }
370
+
371
+ ;
372
+
373
+ const
374
+
375
+ :
376
+
377
+ readonly
378
+
379
+ <
380
+
381
+ ,
382
+
383
+ unknown
384
+
385
+ >
386
+
387
+ [
388
+
389
+ ]
390
+
391
+ =
392
+
393
+ [
394
+
395
+ {
396
+
397
+ :
398
+
399
+ 'q'
400
+
401
+ ,
402
+
403
+ selector
404
+
405
+ :
406
+
407
+ =>
408
+
409
+ .
410
+
411
+ ,
412
+
413
+ :
414
+
415
+ .
416
+
417
+ ,
418
+
419
+ :
420
+
421
+ ''
422
+
423
+ }
424
+
425
+ ,
426
+
427
+ {
428
+
429
+ :
430
+
431
+ 'viewType'
432
+
433
+ ,
434
+
435
+ selector
436
+
437
+ :
438
+
439
+ =>
440
+
441
+ .
442
+
443
+ ,
444
+
445
+ :
446
+
447
+ .
448
+
449
+ ,
450
+
451
+ :
452
+
453
+ 'list'
454
+
455
+ }
456
+
457
+ ,
458
+
459
+ {
460
+
461
+ :
462
+
463
+ 'tags'
464
+
465
+ ,
466
+
467
+ selector
468
+
469
+ :
470
+
471
+ =>
472
+
473
+ .
474
+
475
+ ,
476
+
477
+ :
478
+
479
+ .
480
+
481
+ ,
482
+
483
+ :
484
+
485
+ 'array'
486
+
487
+ ,
488
+
489
+ :
490
+
491
+ [
492
+
493
+ ]
494
+
495
+ }
496
+
497
+ ,
498
+
499
+ ]
500
+
501
+ ;
502
+
503
+ const
504
+
505
+ =
506
+
507
+ useLocation
508
+
509
+ (
510
+
511
+ )
512
+
513
+ ;
514
+
515
+ const
516
+
517
+ =
518
+
519
+ useNavigate
520
+
521
+ (
522
+
523
+ )
524
+
525
+ ;
526
+
527
+ const
528
+
529
+ =
530
+
531
+ useNavigationType
532
+
533
+ (
534
+
535
+ )
536
+
537
+ ;
538
+
539
+ useUrlState
540
+
541
+ (
542
+
543
+ {
544
+
545
+ ,
546
+
547
+ :
548
+
549
+ .
550
+
551
+ ,
552
+
553
+ :
554
+
555
+ {
556
+
557
+ :
558
+
559
+ .
560
+
561
+ ,
562
+
563
+ :
564
+
565
+ .
566
+
567
+ ,
568
+
569
+ :
570
+
571
+ .
572
+
573
+ }
574
+
575
+ ,
576
+
577
+ ,
578
+
579
+ onUpdateStore
580
+
581
+ :
582
+
583
+ =>
584
+
585
+ dispatch
586
+
587
+ (
588
+
589
+ )
590
+
591
+ ,
592
+
593
+ onNavigate
594
+
595
+ :
596
+
597
+ (
598
+
599
+ ,
600
+
601
+ )
602
+
603
+ =>
604
+
605
+ navigate
606
+
607
+ (
608
+
609
+ {
610
+
611
+ }
612
+
613
+ ,
614
+
615
+ {
616
+
617
+ :
618
+
619
+ ===
620
+
621
+ 'replace'
622
+
623
+ }
624
+
625
+ )
626
+
627
+ ,
628
+
629
+ }
630
+
631
+ )
632
+
633
+ ;
634
+
134
635
  > Implementation details: See useUrlState and route utils for details.
135
636
 
136
637
  ## Best practices
@@ -206,19 +707,387 @@ const onSearchChange = (q: string) => setUrlState({ q }, 'replace'); // typing/s
206
707
  const onViewTypeChange = (viewType: ViewType) => setUrlState({ viewType }, 'push'); // meaningful step
207
708
  ```
208
709
 
209
- **Redux as source of truth (more complex but recommend for more complex SPAs)**
710
+ import
210
711
 
211
- - Parse the URL once to seed initial Redux state.
212
- - Subscribe to Redux and update the URL (debounced).
213
- - Listen for URL changes and dispatch to Redux with guards to avoid loops and no-op updates.
712
+ {
214
713
 
215
- ```ts
216
- import useUrlState from '@rio-cloud/rio-uikit/useUrlState';
217
- import { useDispatch, useSelector } from 'react-redux';
218
- import { useLocation, useNavigate, useNavigationType } from 'react-router-dom';
219
- import type { AppDispatch } from '../../../../setup/store';
714
+ }
220
715
 
221
- // Redux as source of truth (recommended for larger SPAs)
716
+ from
717
+
718
+ 'react'
719
+
720
+ ;
721
+
722
+ import
723
+
724
+ {
725
+
726
+ }
727
+
728
+ from
729
+
730
+ 'react-router-dom'
731
+
732
+ ;
733
+
734
+ type
735
+
736
+ ViewType
737
+
738
+ =
739
+
740
+ 'list'
741
+
742
+ |
743
+
744
+ 'grid'
745
+
746
+ ;
747
+
748
+ // URL as source of truth (simple screens, no centralized store sync)
749
+
750
+ const
751
+
752
+ [
753
+
754
+ ,
755
+
756
+ ]
757
+
758
+ =
759
+
760
+ useSearchParams
761
+
762
+ (
763
+
764
+ )
765
+
766
+ ;
767
+
768
+ const
769
+
770
+ =
771
+
772
+ useMemo
773
+
774
+ (
775
+
776
+ (
777
+
778
+ )
779
+
780
+ =>
781
+
782
+ (
783
+
784
+ {
785
+
786
+ :
787
+
788
+ .
789
+
790
+ get
791
+
792
+ (
793
+
794
+ 'q'
795
+
796
+ )
797
+
798
+ ??
799
+
800
+ ''
801
+
802
+ ,
803
+
804
+ :
805
+
806
+ (
807
+
808
+ .
809
+
810
+ get
811
+
812
+ (
813
+
814
+ 'viewType'
815
+
816
+ )
817
+
818
+ as
819
+
820
+ )
821
+
822
+ ??
823
+
824
+ 'list'
825
+
826
+ ,
827
+
828
+ }
829
+
830
+ )
831
+
832
+ ,
833
+
834
+ [
835
+
836
+ ]
837
+
838
+ )
839
+
840
+ ;
841
+
842
+ const
843
+
844
+ =
845
+
846
+ (
847
+
848
+ :
849
+
850
+ <
851
+
852
+ typeof
853
+
854
+ >
855
+
856
+ ,
857
+
858
+ :
859
+
860
+ 'push'
861
+
862
+ |
863
+
864
+ 'replace'
865
+
866
+ =
867
+
868
+ 'push'
869
+
870
+ )
871
+
872
+ =>
873
+
874
+ {
875
+
876
+ const
877
+
878
+ =
879
+
880
+ new
881
+
882
+ URLSearchParams
883
+
884
+ (
885
+
886
+ )
887
+
888
+ ;
889
+
890
+ const
891
+
892
+ =
893
+
894
+ {
895
+
896
+ ...
897
+
898
+ ,
899
+
900
+ ...
901
+
902
+ }
903
+
904
+ ;
905
+
906
+ if
907
+
908
+ (
909
+
910
+ .
911
+
912
+ )
913
+
914
+ .
915
+
916
+ set
917
+
918
+ (
919
+
920
+ 'q'
921
+
922
+ ,
923
+
924
+ .
925
+
926
+ )
927
+
928
+ ;
929
+
930
+ else
931
+
932
+ .
933
+
934
+ delete
935
+
936
+ (
937
+
938
+ 'q'
939
+
940
+ )
941
+
942
+ ;
943
+
944
+ if
945
+
946
+ (
947
+
948
+ .
949
+
950
+ ===
951
+
952
+ 'list'
953
+
954
+ )
955
+
956
+ .
957
+
958
+ delete
959
+
960
+ (
961
+
962
+ 'viewType'
963
+
964
+ )
965
+
966
+ ;
967
+
968
+ else
969
+
970
+ .
971
+
972
+ set
973
+
974
+ (
975
+
976
+ 'viewType'
977
+
978
+ ,
979
+
980
+ .
981
+
982
+ )
983
+
984
+ ;
985
+
986
+ setSearchParams
987
+
988
+ (
989
+
990
+ ,
991
+
992
+ {
993
+
994
+ :
995
+
996
+ ===
997
+
998
+ 'replace'
999
+
1000
+ }
1001
+
1002
+ )
1003
+
1004
+ ;
1005
+
1006
+ }
1007
+
1008
+ ;
1009
+
1010
+ // Typical usage:
1011
+
1012
+ const
1013
+
1014
+ onSearchChange
1015
+
1016
+ =
1017
+
1018
+ (
1019
+
1020
+ :
1021
+
1022
+ string
1023
+
1024
+ )
1025
+
1026
+ =>
1027
+
1028
+ setUrlState
1029
+
1030
+ (
1031
+
1032
+ {
1033
+
1034
+ }
1035
+
1036
+ ,
1037
+
1038
+ 'replace'
1039
+
1040
+ )
1041
+
1042
+ ;
1043
+
1044
+ // typing/search refinement
1045
+
1046
+ const
1047
+
1048
+ onViewTypeChange
1049
+
1050
+ =
1051
+
1052
+ (
1053
+
1054
+ :
1055
+
1056
+ )
1057
+
1058
+ =>
1059
+
1060
+ setUrlState
1061
+
1062
+ (
1063
+
1064
+ {
1065
+
1066
+ }
1067
+
1068
+ ,
1069
+
1070
+ 'push'
1071
+
1072
+ )
1073
+
1074
+ ;
1075
+
1076
+ // meaningful step
1077
+
1078
+ **Redux as source of truth (more complex but recommend for more complex SPAs)**
1079
+
1080
+ - Parse the URL once to seed initial Redux state.
1081
+ - Subscribe to Redux and update the URL (debounced).
1082
+ - Listen for URL changes and dispatch to Redux with guards to avoid loops and no-op updates.
1083
+
1084
+ ```ts
1085
+ import useUrlState from '@rio-cloud/rio-uikit/useUrlState';
1086
+ import { useDispatch, useSelector } from 'react-redux';
1087
+ import { useLocation, useNavigate, useNavigationType } from 'react-router-dom';
1088
+ import type { AppDispatch } from '../../../../setup/store';
1089
+
1090
+ // Redux as source of truth (recommended for larger SPAs)
222
1091
  // 1) Parse URL and dispatch updates on URL changes (including browser POP).
223
1092
  // 2) Observe store values and write URL changes via push/replace rules.
224
1093
  // 3) Keep this logic centralized in one component near the router.
@@ -245,6 +1114,264 @@ onNavigate: (search, mode) => navigate({ search }, { replace: mode === 'replace'
245
1114
  });
246
1115
  ```
247
1116
 
1117
+ import
1118
+
1119
+ from
1120
+
1121
+ '@rio-cloud/rio-uikit/useUrlState'
1122
+
1123
+ ;
1124
+
1125
+ import
1126
+
1127
+ {
1128
+
1129
+ ,
1130
+
1131
+ }
1132
+
1133
+ from
1134
+
1135
+ 'react-redux'
1136
+
1137
+ ;
1138
+
1139
+ import
1140
+
1141
+ {
1142
+
1143
+ ,
1144
+
1145
+ ,
1146
+
1147
+ }
1148
+
1149
+ from
1150
+
1151
+ 'react-router-dom'
1152
+
1153
+ ;
1154
+
1155
+ import
1156
+
1157
+ type
1158
+
1159
+ {
1160
+
1161
+ }
1162
+
1163
+ from
1164
+
1165
+ '../../../../setup/store'
1166
+
1167
+ ;
1168
+
1169
+ // Redux as source of truth (recommended for larger SPAs)
1170
+
1171
+ // 1) Parse URL and dispatch updates on URL changes (including browser POP).
1172
+
1173
+ // 2) Observe store values and write URL changes via push/replace rules.
1174
+
1175
+ // 3) Keep this logic centralized in one component near the router.
1176
+
1177
+ const
1178
+
1179
+ =
1180
+
1181
+ useDispatch<AppDispatch>
1182
+
1183
+ (
1184
+
1185
+ )
1186
+
1187
+ ;
1188
+
1189
+ const
1190
+
1191
+ =
1192
+
1193
+ useLocation
1194
+
1195
+ (
1196
+
1197
+ )
1198
+
1199
+ ;
1200
+
1201
+ const
1202
+
1203
+ =
1204
+
1205
+ useNavigate
1206
+
1207
+ (
1208
+
1209
+ )
1210
+
1211
+ ;
1212
+
1213
+ const
1214
+
1215
+ =
1216
+
1217
+ useNavigationType
1218
+
1219
+ (
1220
+
1221
+ )
1222
+
1223
+ ;
1224
+
1225
+ const
1226
+
1227
+ =
1228
+
1229
+ useSelector
1230
+
1231
+ (
1232
+
1233
+ =>
1234
+
1235
+ (
1236
+
1237
+ {
1238
+
1239
+ :
1240
+
1241
+ getSearchValue
1242
+
1243
+ (
1244
+
1245
+ )
1246
+
1247
+ ,
1248
+
1249
+ :
1250
+
1251
+ {
1252
+
1253
+ :
1254
+
1255
+ getSortBy
1256
+
1257
+ (
1258
+
1259
+ )
1260
+
1261
+ ,
1262
+
1263
+ :
1264
+
1265
+ getSortDir
1266
+
1267
+ (
1268
+
1269
+ )
1270
+
1271
+ }
1272
+
1273
+ ,
1274
+
1275
+ :
1276
+
1277
+ getActivityFilter
1278
+
1279
+ (
1280
+
1281
+ )
1282
+
1283
+ ,
1284
+
1285
+ }
1286
+
1287
+ )
1288
+
1289
+ )
1290
+
1291
+ ;
1292
+
1293
+ useUrlState
1294
+
1295
+ (
1296
+
1297
+ {
1298
+
1299
+ :
1300
+
1301
+ ,
1302
+
1303
+ :
1304
+
1305
+ .
1306
+
1307
+ ,
1308
+
1309
+ ,
1310
+
1311
+ :
1312
+
1313
+ 'service.ui.state'
1314
+
1315
+ ,
1316
+
1317
+ ,
1318
+
1319
+ onUpdateStore
1320
+
1321
+ :
1322
+
1323
+ =>
1324
+
1325
+ dispatch
1326
+
1327
+ (
1328
+
1329
+ )
1330
+
1331
+ ,
1332
+
1333
+ onNavigate
1334
+
1335
+ :
1336
+
1337
+ (
1338
+
1339
+ ,
1340
+
1341
+ )
1342
+
1343
+ =>
1344
+
1345
+ navigate
1346
+
1347
+ (
1348
+
1349
+ {
1350
+
1351
+ }
1352
+
1353
+ ,
1354
+
1355
+ {
1356
+
1357
+ :
1358
+
1359
+ ===
1360
+
1361
+ 'replace'
1362
+
1363
+ }
1364
+
1365
+ )
1366
+
1367
+ ,
1368
+
1369
+ }
1370
+
1371
+ )
1372
+
1373
+ ;
1374
+
248
1375
  useUrlState supports this second model: centralized store-url synchronization. If you still use template helpers like routeHelper with qs, replace them with a centralized config + useUrlState synchronizer and define per-field history behavior with history: 'push' | 'replace'.
249
1376
 
250
1377
  ## Things to consider