scb-wc 0.1.1 → 0.1.2

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.
@@ -0,0 +1,1663 @@
1
+ /*
2
+ Bas-klass för Razor-komponenter som vill läsa state från SCB web components.
3
+ JS-bryggan (scb-blazor-bridge.js) samlar state från DOM:en och levererar det som ett ScbStateDto. Den här klassen mappar DTO:t till starkt typade C#-klasser
4
+ som kan användas direkt i Razor-vyer */
5
+
6
+ using System;
7
+ using System.Linq;
8
+ using System.Threading.Tasks;
9
+ using Microsoft.AspNetCore.Components;
10
+ using Microsoft.JSInterop;
11
+
12
+ namespace ScbBlazorDemo
13
+ {
14
+ public abstract class ScbBlazorInteropBase : ComponentBase, IAsyncDisposable
15
+ {
16
+ // JSRuntime används för att anropa SCBBlazor-objektet i scb-blazor-bridge.js
17
+ [Inject] protected IJSRuntime JS { get; set; } = default!;
18
+
19
+ // Håller en .NET-referens som JS kan använda för att ropa tillbaka på OnScbEvent
20
+ private DotNetObjectReference<ScbBlazorInteropBase>? _dotNetRef;
21
+
22
+ // Header (scb-header): aktiv flik, drawerstatus och eventuell söktext
23
+ protected HeaderState Header { get; private set; } = new();
24
+
25
+ // Drawer (scb-drawer): öppet/stängt och texter
26
+ protected DrawerState Drawer { get; private set; } = new();
27
+
28
+ // Meny (scb-menu): övergripande öppet/stängt-läge
29
+ protected MenuState Menu { get; private set; } = new();
30
+
31
+ // Alla submenyer (scb-sub-menu) på sidan
32
+ protected SubMenuState[] SubMenus { get; private set; } = Array.Empty<SubMenuState>();
33
+
34
+ // Breadcrumb (scb-breadcrumb): övergripande state
35
+ protected BreadcrumbState Breadcrumb { get; private set; } = new();
36
+
37
+ // Alla breadcrumb-länkar (scb-breadcrumb-item)
38
+ protected BreadcrumbItemState[] BreadcrumbItems { get; private set; } = Array.Empty<BreadcrumbItemState>();
39
+
40
+ // Alla accordions på sidan (scb-accordion) med sina items
41
+ protected AccordionListState[] Accordions { get; private set; } = Array.Empty<AccordionListState>();
42
+
43
+ // Lista som speglar checkboxarnas valda läge och metadata
44
+ protected CheckboxState[] Checkboxes { get; private set; } = Array.Empty<CheckboxState>();
45
+
46
+ // Lista som speglar switcharnas valda läge och metadata
47
+ protected SwitchState[] Switches { get; private set; } = Array.Empty<SwitchState>();
48
+
49
+ // App-bar (scb-app-bar)
50
+ protected AppBarState AppBar { get; private set; } = new();
51
+
52
+ // Segmented button (scb-segmented-button)
53
+ protected SegmentedState Segmented { get; private set; } = new();
54
+
55
+ // Alla tabbar (scb-tabs) på sidan
56
+ protected TabsState[] Tabs { get; private set; } = Array.Empty<TabsState>();
57
+
58
+ // Stepper (scb-stepper)
59
+ protected StepperState Stepper { get; private set; } = new();
60
+
61
+ // Cards (scb-card) om man vill läsa av state
62
+ protected CardState[] Cards { get; private set; } = Array.Empty<CardState>();
63
+
64
+ // Nyckeltalskort (scb-keyfigure-card)
65
+ protected KeyfigureState[] Keyfigures { get; private set; } = Array.Empty<KeyfigureState>();
66
+
67
+ // Enskild kalender (scb-calendar-card) för scenarion där man bara bryr sig om en
68
+ protected CalendarState Calendar { get; private set; } = new();
69
+
70
+ // Alla kalenderkort på sidan
71
+ protected CalendarState[] Calendars { get; private set; } = Array.Empty<CalendarState>();
72
+
73
+ // Dialog (scb-dialog)
74
+ protected DialogState Dialog { get; private set; } = new();
75
+
76
+ // Alla notification-kort (scb-notification-card) på sidan
77
+ protected NotificationState[] Notifications { get; private set; } = Array.Empty<NotificationState>();
78
+
79
+ // Alla snackbars (scb-snackbar) på sidan
80
+ protected SnackbarState[] Snackbars { get; private set; } = Array.Empty<SnackbarState>();
81
+
82
+ // Alla statuspiller (scb-status-pill) på sidan
83
+ protected StatusPillState[] StatusPills { get; private set; } = Array.Empty<StatusPillState>();
84
+
85
+ // Alla tooltips (scb-tooltip) på sidan
86
+ protected TooltipState[] Tooltips { get; private set; } = Array.Empty<TooltipState>();
87
+
88
+ // Alla pagination-komponenter (scb-pagination) på sidan
89
+ protected PaginationState[] Paginations { get; private set; } = Array.Empty<PaginationState>();
90
+
91
+ // Alla radio-grupper (scb-radio-group) på sidan
92
+ protected RadioGroupState[] RadioGroups { get; private set; } = Array.Empty<RadioGroupState>();
93
+
94
+ // Alla textfält (scb-textfield) på sidan
95
+ protected TextfieldState[] Textfields { get; private set; } = Array.Empty<TextfieldState>();
96
+
97
+ // Alla sökfält (fristående scb-search) på sidan
98
+ protected SearchState[] Searches { get; private set; } = Array.Empty<SearchState>();
99
+
100
+ // Alla listor (scb-list) med sina list-items (scb-list-item)
101
+ protected ListState[] Lists { get; private set; } = Array.Empty<ListState>();
102
+
103
+ // Alla länkar (scb-link) på sidan
104
+ protected LinkState[] Links { get; private set; } = Array.Empty<LinkState>();
105
+
106
+ // Alla innehållsförteckningar (scb-toc) på sidan
107
+ protected TocState[] Tocs { get; private set; } = Array.Empty<TocState>();
108
+
109
+ // Alla viz-komponenter (scb-viz) på sidan
110
+ protected VizState[] Viz { get; private set; } = Array.Empty<VizState>();
111
+
112
+ // Registrerar JS-interop vid första render och hämtar initialt state
113
+ protected override async Task OnAfterRenderAsync(bool firstRender)
114
+ {
115
+ if (firstRender)
116
+ {
117
+ // Skapar en .NET-referens så att JS kan anropa OnScbEvent på rätt instans
118
+ _dotNetRef = DotNetObjectReference.Create(this);
119
+
120
+ // Registrerar eventhanterare i JS (i scb-blazor-bridge.js)
121
+ await JS.InvokeVoidAsync("SCBBlazor.registerScbEventHandlers", _dotNetRef);
122
+
123
+ // Hämtar första snapshoten av state
124
+ await RefreshScbStateAsync();
125
+ }
126
+ }
127
+
128
+ // Läser in hela state-strukturen från JS och mappar till C#-klasserna ovan
129
+ public async Task RefreshScbStateAsync()
130
+ {
131
+ // Hämtar DTO från globala SCBBlazor.getState
132
+ var state = await JS.InvokeAsync<ScbStateDto>("SCBBlazor.getState");
133
+
134
+ // Header
135
+ Header.ActiveTab = state.Header.ActiveTab;
136
+ Header.DrawerOpen = state.Header.DrawerOpen;
137
+ Header.SearchText = state.Header.SearchText ?? string.Empty;
138
+
139
+ // Drawer
140
+ if (state.Drawer is not null)
141
+ {
142
+ Drawer.Open = state.Drawer.Open;
143
+ Drawer.Label = state.Drawer.Label ?? string.Empty;
144
+ Drawer.SubLabel = state.Drawer.SubLabel ?? string.Empty;
145
+ }
146
+ else
147
+ {
148
+ Drawer.Open = false;
149
+ Drawer.Label = string.Empty;
150
+ Drawer.SubLabel = string.Empty;
151
+ }
152
+
153
+ // Meny
154
+ if (state.Menu is not null)
155
+ {
156
+ Menu.Open = state.Menu.Open;
157
+ }
158
+ else
159
+ {
160
+ Menu.Open = false;
161
+ }
162
+
163
+ // Sub-menyer
164
+ if (state.SubMenus is not null && state.SubMenus.Length > 0)
165
+ {
166
+ var subMenus = new SubMenuState[state.SubMenus.Length];
167
+ for (var i = 0; i < state.SubMenus.Length; i++)
168
+ {
169
+ var dto = state.SubMenus[i];
170
+ subMenus[i] = new SubMenuState
171
+ {
172
+ Open = dto.Open,
173
+ OpenLeft = dto.OpenLeft
174
+ };
175
+ }
176
+
177
+ SubMenus = subMenus;
178
+ }
179
+ else
180
+ {
181
+ SubMenus = Array.Empty<SubMenuState>();
182
+ }
183
+
184
+ // Breadcrumb
185
+ if (state.Breadcrumb is not null)
186
+ {
187
+ Breadcrumb.ShowAll = state.Breadcrumb.ShowAll;
188
+ }
189
+ else
190
+ {
191
+ Breadcrumb.ShowAll = false;
192
+ }
193
+
194
+ // Breadcrumb-items
195
+ if (state.BreadcrumbItems is not null && state.BreadcrumbItems.Length > 0)
196
+ {
197
+ var items = new BreadcrumbItemState[state.BreadcrumbItems.Length];
198
+ for (var i = 0; i < state.BreadcrumbItems.Length; i++)
199
+ {
200
+ var dto = state.BreadcrumbItems[i];
201
+ items[i] = new BreadcrumbItemState
202
+ {
203
+ Label = dto.Label ?? string.Empty,
204
+ IsCurrent = dto.IsCurrent,
205
+ Href = dto.Href ?? string.Empty,
206
+ };
207
+ }
208
+
209
+ BreadcrumbItems = items;
210
+ }
211
+ else
212
+ {
213
+ BreadcrumbItems = Array.Empty<BreadcrumbItemState>();
214
+ }
215
+
216
+ // Accordions
217
+ if (state.Accordions is not null && state.Accordions.Length > 0)
218
+ {
219
+ var accordions = new AccordionListState[state.Accordions.Length];
220
+ for (var i = 0; i < state.Accordions.Length; i++)
221
+ {
222
+ var dto = state.Accordions[i];
223
+ var items = dto.Items ?? Array.Empty<AccordionItemDto>();
224
+ var itemStates = new AccordionItemState[items.Length];
225
+
226
+ for (var j = 0; j < items.Length; j++)
227
+ {
228
+ var itemDto = items[j];
229
+ itemStates[j] = new AccordionItemState
230
+ {
231
+ Open = itemDto.Open,
232
+ Title = itemDto.Title ?? string.Empty,
233
+ Overline = itemDto.Overline ?? string.Empty,
234
+ SupportingText = itemDto.SupportingText ?? string.Empty
235
+ };
236
+ }
237
+
238
+ accordions[i] = new AccordionListState
239
+ {
240
+ Detached = dto.Detached,
241
+ Items = itemStates
242
+ };
243
+ }
244
+
245
+ Accordions = accordions;
246
+ }
247
+ else
248
+ {
249
+ Accordions = Array.Empty<AccordionListState>();
250
+ }
251
+
252
+ // Checkboxar och switchar
253
+ Checkboxes = (state.Checkboxes ?? Array.Empty<CheckboxDto>())
254
+ .Select(dto => new CheckboxState
255
+ {
256
+ Checked = dto.Checked,
257
+ Name = dto.Name ?? string.Empty,
258
+ Value = dto.Value ?? string.Empty,
259
+ Label = dto.Label ?? string.Empty,
260
+ })
261
+ .ToArray();
262
+
263
+ Switches = (state.Switches ?? Array.Empty<SwitchDto>())
264
+ .Select(dto => new SwitchState
265
+ {
266
+ Selected = dto.Selected,
267
+ Name = dto.Name ?? string.Empty,
268
+ Value = dto.Value ?? string.Empty,
269
+ Label = dto.Label ?? string.Empty,
270
+ })
271
+ .ToArray();
272
+
273
+ // App-bar
274
+ AppBar.Title = state.AppBar.Title ?? string.Empty;
275
+ AppBar.Type = string.IsNullOrWhiteSpace(state.AppBar.Type) ? "default" : state.AppBar.Type!;
276
+ AppBar.Position = string.IsNullOrWhiteSpace(state.AppBar.Position) ? "default" : state.AppBar.Position!;
277
+ AppBar.SearchSupportingText = state.AppBar.SearchSupportingText ?? string.Empty;
278
+
279
+ // Segmented button
280
+ if (state.Segmented is not null)
281
+ {
282
+ Segmented.Value = state.Segmented.Value ?? string.Empty;
283
+ Segmented.Values = state.Segmented.Values ?? Array.Empty<string>();
284
+ }
285
+ else
286
+ {
287
+ Segmented.Value = string.Empty;
288
+ Segmented.Values = Array.Empty<string>();
289
+ }
290
+
291
+ // Tabs
292
+ if (state.Tabs is not null && state.Tabs.Length > 0)
293
+ {
294
+ var tabs = new TabsState[state.Tabs.Length];
295
+ for (var i = 0; i < state.Tabs.Length; i++)
296
+ {
297
+ var dto = state.Tabs[i];
298
+ tabs[i] = new TabsState
299
+ {
300
+ ActiveIndex = dto.ActiveIndex
301
+ };
302
+ }
303
+ Tabs = tabs;
304
+ }
305
+ else
306
+ {
307
+ Tabs = Array.Empty<TabsState>();
308
+ }
309
+
310
+ // Stepper
311
+ if (state.Stepper is not null)
312
+ {
313
+ Stepper.ActiveIndex = state.Stepper.ActiveIndex;
314
+ Stepper.TotalSteps = state.Stepper.TotalSteps;
315
+ }
316
+ else
317
+ {
318
+ Stepper.ActiveIndex = 0;
319
+ Stepper.TotalSteps = 0;
320
+ }
321
+
322
+ // Cards
323
+ if (state.Cards is not null && state.Cards.Length > 0)
324
+ {
325
+ var cards = new CardState[state.Cards.Length];
326
+ for (var i = 0; i < state.Cards.Length; i++)
327
+ {
328
+ var dto = state.Cards[i];
329
+ cards[i] = new CardState
330
+ {
331
+ Type = dto.Type ?? string.Empty,
332
+ Variant = dto.Variant ?? string.Empty,
333
+ Direction = dto.Direction ?? string.Empty,
334
+ Title = dto.Title ?? string.Empty,
335
+ Subtitle = dto.Subtitle ?? string.Empty,
336
+ SupportingText = dto.SupportingText ?? string.Empty,
337
+ CardHref = dto.CardHref ?? string.Empty
338
+ };
339
+ }
340
+ Cards = cards;
341
+ }
342
+ else
343
+ {
344
+ Cards = Array.Empty<CardState>();
345
+ }
346
+
347
+ // Keyfigure cards
348
+ if (state.Keyfigures is not null && state.Keyfigures.Length > 0)
349
+ {
350
+ var keyfigs = new KeyfigureState[state.Keyfigures.Length];
351
+ for (var i = 0; i < state.Keyfigures.Length; i++)
352
+ {
353
+ var dto = state.Keyfigures[i];
354
+ keyfigs[i] = new KeyfigureState
355
+ {
356
+ Keyfigure = dto.Keyfigure ?? string.Empty,
357
+ Subtitle = dto.Subtitle ?? string.Empty,
358
+ SupportingText = dto.SupportingText ?? string.Empty,
359
+ CardHref = dto.CardHref ?? string.Empty,
360
+ Icon = dto.Icon ?? string.Empty,
361
+ Size = dto.Size ?? string.Empty,
362
+ Unit = dto.Unit ?? string.Empty
363
+ };
364
+ }
365
+ Keyfigures = keyfigs;
366
+ }
367
+ else
368
+ {
369
+ Keyfigures = Array.Empty<KeyfigureState>();
370
+ }
371
+
372
+ // Enskild kalender: baseras på första kalendern om en lista finns, annars på state.Calendar
373
+ if (state.Calendars is not null && state.Calendars.Length > 0)
374
+ {
375
+ var dto = state.Calendars[0];
376
+ Calendar.Title = dto.Title ?? string.Empty;
377
+ Calendar.Subtitle = dto.Subtitle ?? string.Empty;
378
+ Calendar.SupportingText = dto.SupportingText ?? string.Empty;
379
+ Calendar.Variant = string.IsNullOrWhiteSpace(dto.Variant)
380
+ ? "default"
381
+ : dto.Variant!;
382
+ Calendar.ShowMedia = dto.ShowMedia;
383
+ }
384
+ else if (state.Calendar is not null)
385
+ {
386
+ Calendar.Title = state.Calendar.Title ?? string.Empty;
387
+ Calendar.Subtitle = state.Calendar.Subtitle ?? string.Empty;
388
+ Calendar.SupportingText = state.Calendar.SupportingText ?? string.Empty;
389
+ Calendar.Variant = string.IsNullOrWhiteSpace(state.Calendar.Variant)
390
+ ? "default"
391
+ : state.Calendar.Variant!;
392
+ Calendar.ShowMedia = state.Calendar.ShowMedia;
393
+ }
394
+ else
395
+ {
396
+ Calendar.Title = string.Empty;
397
+ Calendar.Subtitle = string.Empty;
398
+ Calendar.SupportingText = string.Empty;
399
+ Calendar.Variant = "default";
400
+ Calendar.ShowMedia = false;
401
+ }
402
+
403
+ // Lista med alla calendar cards
404
+ if (state.Calendars is not null && state.Calendars.Length > 0)
405
+ {
406
+ var calendars = new CalendarState[state.Calendars.Length];
407
+ for (var i = 0; i < state.Calendars.Length; i++)
408
+ {
409
+ var dto = state.Calendars[i];
410
+ calendars[i] = new CalendarState
411
+ {
412
+ Title = dto.Title ?? string.Empty,
413
+ Subtitle = dto.Subtitle ?? string.Empty,
414
+ SupportingText = dto.SupportingText ?? string.Empty,
415
+ Variant = string.IsNullOrWhiteSpace(dto.Variant)
416
+ ? "default"
417
+ : dto.Variant!,
418
+ ShowMedia = dto.ShowMedia
419
+ };
420
+ }
421
+
422
+ Calendars = calendars;
423
+ }
424
+ else
425
+ {
426
+ Calendars = Array.Empty<CalendarState>();
427
+ }
428
+
429
+ // Dialog
430
+ if (state.Dialog is not null)
431
+ {
432
+ Dialog.Open = state.Dialog.Open;
433
+ Dialog.Variant = state.Dialog.Variant ?? string.Empty;
434
+ Dialog.Label = state.Dialog.Label ?? string.Empty;
435
+ }
436
+ else
437
+ {
438
+ Dialog.Open = false;
439
+ Dialog.Variant = string.Empty;
440
+ Dialog.Label = string.Empty;
441
+ }
442
+
443
+ // Notification cards
444
+ if (state.Notifications is not null && state.Notifications.Length > 0)
445
+ {
446
+ var notifications = new NotificationState[state.Notifications.Length];
447
+ for (var i = 0; i < state.Notifications.Length; i++)
448
+ {
449
+ var dto = state.Notifications[i];
450
+ notifications[i] = new NotificationState
451
+ {
452
+ Open = dto.Open,
453
+ Variant = dto.Variant ?? string.Empty,
454
+ Title = dto.Title ?? string.Empty,
455
+ Subtitle = dto.Subtitle ?? string.Empty,
456
+ SupportingText = dto.SupportingText ?? string.Empty,
457
+ LinkText = dto.LinkText ?? string.Empty,
458
+ LinkHref = dto.LinkHref ?? string.Empty,
459
+ ShowIcon = dto.ShowIcon,
460
+ ShowCloseButton = dto.ShowCloseButton,
461
+ FullHeight = dto.FullHeight,
462
+ FullWidth = dto.FullWidth,
463
+ Direction = dto.Direction ?? string.Empty
464
+ };
465
+ }
466
+ Notifications = notifications;
467
+ }
468
+ else
469
+ {
470
+ Notifications = Array.Empty<NotificationState>();
471
+ }
472
+
473
+ // Snackbars
474
+ if (state.Snackbars is not null && state.Snackbars.Length > 0)
475
+ {
476
+ var snackbars = new SnackbarState[state.Snackbars.Length];
477
+ for (var i = 0; i < state.Snackbars.Length; i++)
478
+ {
479
+ var dto = state.Snackbars[i];
480
+ snackbars[i] = new SnackbarState
481
+ {
482
+ Open = dto.Open,
483
+ Message = dto.Message ?? string.Empty,
484
+ ActionText = dto.ActionText ?? string.Empty,
485
+ ShowClose = dto.ShowClose,
486
+ Fixed = dto.Fixed,
487
+ Fadeout = dto.Fadeout,
488
+ WithLongerAction = dto.WithLongerAction
489
+ };
490
+ }
491
+ Snackbars = snackbars;
492
+ }
493
+ else
494
+ {
495
+ Snackbars = Array.Empty<SnackbarState>();
496
+ }
497
+
498
+ // Status pills
499
+ if (state.StatusPills is not null && state.StatusPills.Length > 0)
500
+ {
501
+ var pills = new StatusPillState[state.StatusPills.Length];
502
+ for (var i = 0; i < state.StatusPills.Length; i++)
503
+ {
504
+ var dto = state.StatusPills[i];
505
+ pills[i] = new StatusPillState
506
+ {
507
+ Status = dto.Status ?? string.Empty,
508
+ Label = dto.Label ?? string.Empty,
509
+ ShowIcon = dto.ShowIcon
510
+ };
511
+ }
512
+ StatusPills = pills;
513
+ }
514
+ else
515
+ {
516
+ StatusPills = Array.Empty<StatusPillState>();
517
+ }
518
+
519
+ // Tooltips
520
+ if (state.Tooltips is not null && state.Tooltips.Length > 0)
521
+ {
522
+ var tips = new TooltipState[state.Tooltips.Length];
523
+ for (var i = 0; i < state.Tooltips.Length; i++)
524
+ {
525
+ var dto = state.Tooltips[i];
526
+ tips[i] = new TooltipState
527
+ {
528
+ Open = dto.Open,
529
+ Variant = dto.Variant ?? string.Empty,
530
+ Position = dto.Position ?? string.Empty,
531
+ Trigger = dto.Trigger ?? string.Empty,
532
+ Delay = dto.Delay,
533
+ Offset = dto.Offset,
534
+ Label = dto.Label ?? string.Empty,
535
+ SupportingText = dto.SupportingText ?? string.Empty
536
+ };
537
+ }
538
+ Tooltips = tips;
539
+ }
540
+ else
541
+ {
542
+ Tooltips = Array.Empty<TooltipState>();
543
+ }
544
+
545
+ // Pagination
546
+ if (state.Paginations is not null && state.Paginations.Length > 0)
547
+ {
548
+ var paginations = new PaginationState[state.Paginations.Length];
549
+ for (var i = 0; i < state.Paginations.Length; i++)
550
+ {
551
+ var dto = state.Paginations[i];
552
+ paginations[i] = new PaginationState
553
+ {
554
+ Page = dto.Page,
555
+ TotalPages = dto.TotalPages
556
+ };
557
+ }
558
+
559
+ Paginations = paginations;
560
+ }
561
+ else
562
+ {
563
+ Paginations = Array.Empty<PaginationState>();
564
+ }
565
+
566
+ // Radio groups
567
+ if (state.RadioGroups is not null && state.RadioGroups.Length > 0)
568
+ {
569
+ var groups = new RadioGroupState[state.RadioGroups.Length];
570
+ for (var i = 0; i < state.RadioGroups.Length; i++)
571
+ {
572
+ var dto = state.RadioGroups[i];
573
+ groups[i] = new RadioGroupState
574
+ {
575
+ Name = dto.Name ?? string.Empty,
576
+ Value = dto.Value ?? string.Empty
577
+ };
578
+ }
579
+ RadioGroups = groups;
580
+ }
581
+ else
582
+ {
583
+ RadioGroups = Array.Empty<RadioGroupState>();
584
+ }
585
+
586
+ // Textfield
587
+ if (state.Textfields is not null && state.Textfields.Length > 0)
588
+ {
589
+ var fields = new TextfieldState[state.Textfields.Length];
590
+ for (var i = 0; i < state.Textfields.Length; i++)
591
+ {
592
+ var dto = state.Textfields[i];
593
+ fields[i] = new TextfieldState
594
+ {
595
+ Value = dto.Value ?? string.Empty,
596
+ Label = dto.Label ?? string.Empty,
597
+ SupportingText = dto.SupportingText ?? string.Empty,
598
+ Error = dto.Error,
599
+ Name = dto.Name ?? string.Empty,
600
+ Id = dto.Id ?? string.Empty
601
+ };
602
+ }
603
+ Textfields = fields;
604
+ }
605
+ else
606
+ {
607
+ Textfields = Array.Empty<TextfieldState>();
608
+ }
609
+
610
+ // Search
611
+ if (state.Searches is not null && state.Searches.Length > 0)
612
+ {
613
+ var searches = new SearchState[state.Searches.Length];
614
+ for (var i = 0; i < state.Searches.Length; i++)
615
+ {
616
+ var dto = state.Searches[i];
617
+ searches[i] = new SearchState
618
+ {
619
+ Value = dto.Value ?? string.Empty,
620
+ SupportingText = dto.SupportingText ?? string.Empty,
621
+ FullScreen = dto.FullScreen,
622
+ Size = dto.Size ?? string.Empty,
623
+ Name = dto.Name ?? string.Empty,
624
+ Id = dto.Id ?? string.Empty
625
+ };
626
+ }
627
+ Searches = searches;
628
+ }
629
+ else
630
+ {
631
+ Searches = Array.Empty<SearchState>();
632
+ }
633
+
634
+ // Listor
635
+ if (state.Lists is not null && state.Lists.Length > 0)
636
+ {
637
+ var lists = new ListState[state.Lists.Length];
638
+ for (var i = 0; i < state.Lists.Length; i++)
639
+ {
640
+ var listDto = state.Lists[i];
641
+ var itemsDto = listDto.Items ?? Array.Empty<ListItemDto>();
642
+ var itemStates = new ListItemState[itemsDto.Length];
643
+
644
+ for (var j = 0; j < itemsDto.Length; j++)
645
+ {
646
+ var itemDto = itemsDto[j];
647
+ itemStates[j] = new ListItemState
648
+ {
649
+ Type = itemDto.Type ?? string.Empty,
650
+ Label = itemDto.Label ?? string.Empty,
651
+ SupportingText = itemDto.SupportingText ?? string.Empty,
652
+ Overline = itemDto.Overline ?? string.Empty,
653
+ Leading = itemDto.Leading,
654
+ LeadingVariant = itemDto.LeadingVariant ?? string.Empty,
655
+ LeadingIcon = itemDto.LeadingIcon ?? string.Empty,
656
+ Trailing = itemDto.Trailing,
657
+ TrailingVariant = itemDto.TrailingVariant ?? string.Empty,
658
+ TrailingIcon = itemDto.TrailingIcon ?? string.Empty,
659
+ Disabled = itemDto.Disabled,
660
+ Href = itemDto.Href ?? string.Empty,
661
+ ItemHref = itemDto.ItemHref ?? string.Empty,
662
+ Target = itemDto.Target ?? string.Empty,
663
+ Density = itemDto.Density,
664
+ NoDivider = itemDto.NoDivider,
665
+ ImgHrefImage = itemDto.ImgHrefImage ?? string.Empty,
666
+ AvatarLabel = itemDto.AvatarLabel ?? string.Empty,
667
+ AvatarAlt = itemDto.AvatarAlt ?? string.Empty,
668
+ AvatarVariant = itemDto.AvatarVariant ?? string.Empty,
669
+ AvatarSrc = itemDto.AvatarSrc ?? string.Empty
670
+ };
671
+ }
672
+
673
+ lists[i] = new ListState
674
+ {
675
+ NoDivider = listDto.NoDivider,
676
+ Items = itemStates
677
+ };
678
+ }
679
+
680
+ Lists = lists;
681
+ }
682
+ else
683
+ {
684
+ Lists = Array.Empty<ListState>();
685
+ }
686
+
687
+ // Links
688
+ if (state.Links is not null && state.Links.Length > 0)
689
+ {
690
+ var links = new LinkState[state.Links.Length];
691
+ for (var i = 0; i < state.Links.Length; i++)
692
+ {
693
+ var dto = state.Links[i];
694
+ links[i] = new LinkState
695
+ {
696
+ Href = dto.Href ?? string.Empty,
697
+ Target = dto.Target ?? string.Empty,
698
+ Rel = dto.Rel ?? string.Empty,
699
+ Download = dto.Download ?? string.Empty,
700
+ Disabled = dto.Disabled,
701
+ AriaLabel = dto.AriaLabel ?? string.Empty,
702
+ Text = dto.Text ?? string.Empty
703
+ };
704
+ }
705
+
706
+ Links = links;
707
+ }
708
+ else
709
+ {
710
+ Links = Array.Empty<LinkState>();
711
+ }
712
+
713
+ // TOC
714
+ if (state.Tocs is not null && state.Tocs.Length > 0)
715
+ {
716
+ var tocs = new TocState[state.Tocs.Length];
717
+ for (var i = 0; i < state.Tocs.Length; i++)
718
+ {
719
+ var dto = state.Tocs[i];
720
+ var itemsDto = dto.Items ?? Array.Empty<TocItemDto>();
721
+ var itemStates = new TocItemState[itemsDto.Length];
722
+
723
+ for (var j = 0; j < itemsDto.Length; j++)
724
+ {
725
+ var itemDto = itemsDto[j];
726
+ itemStates[j] = new TocItemState
727
+ {
728
+ Expanded = itemDto.Expanded,
729
+ Label = itemDto.Label ?? string.Empty,
730
+ SupportingText = itemDto.SupportingText ?? string.Empty,
731
+ ItemHref = itemDto.ItemHref ?? string.Empty,
732
+ Divider = itemDto.Divider
733
+ };
734
+ }
735
+
736
+ tocs[i] = new TocState
737
+ {
738
+ Detached = dto.Detached,
739
+ Items = itemStates
740
+ };
741
+ }
742
+
743
+ Tocs = tocs;
744
+ }
745
+ else
746
+ {
747
+ Tocs = Array.Empty<TocState>();
748
+ }
749
+
750
+ // Viz
751
+ if (state.Viz is not null && state.Viz.Length > 0)
752
+ {
753
+ var vizStates = new VizState[state.Viz.Length];
754
+ for (var i = 0; i < state.Viz.Length; i++)
755
+ {
756
+ var dto = state.Viz[i];
757
+ vizStates[i] = new VizState
758
+ {
759
+ Variant = dto.Variant ?? string.Empty,
760
+ Title = dto.Title ?? string.Empty,
761
+ Subtitle = dto.Subtitle ?? string.Empty,
762
+ Description = dto.Description ?? string.Empty,
763
+ Comment = dto.Comment ?? string.Empty,
764
+ Source = dto.Source ?? string.Empty,
765
+ Footnote = dto.Footnote ?? string.Empty,
766
+ Lang = dto.Lang ?? string.Empty,
767
+ ImageHref = dto.ImageHref ?? string.Empty,
768
+ SelectedChip = dto.SelectedChip ?? string.Empty
769
+ };
770
+ }
771
+
772
+ Viz = vizStates;
773
+ }
774
+ else
775
+ {
776
+ Viz = Array.Empty<VizState>();
777
+ }
778
+
779
+ // Hook för arvklasser som vill reagera när state uppdateras
780
+ await OnScbStateChangedAsync();
781
+
782
+ // Talar om för Blazor att state har ändrats
783
+ StateHasChanged();
784
+ }
785
+
786
+ // JS anropar denna metod när något normaliserat event inträffar
787
+ [JSInvokable]
788
+ public Task OnScbEvent(string eventName)
789
+ {
790
+ return RefreshScbStateAsync();
791
+ }
792
+
793
+ // Kan overridas i arvklasser för att reagera på stateändringar
794
+ protected virtual Task OnScbStateChangedAsync() => Task.CompletedTask;
795
+
796
+ public ValueTask DisposeAsync()
797
+ {
798
+ _dotNetRef?.Dispose();
799
+ return ValueTask.CompletedTask;
800
+ }
801
+
802
+
803
+
804
+ // Styrkommandon som skickar anrop från Blazor till SCB web components via SCBBlazor-objektet i JS.
805
+ // Dessa metoder uppdaterar DOM:ens state och triggar samma normaliserade events som vid användarinteraktion.
806
+ // Id- och name-baserade varianter rekommenderas för mer robust adressering än ren index-baserad styrning.
807
+
808
+ // Header (scb-header)
809
+ protected Task SetHeaderActiveTabAsync(int activeTab)
810
+ {
811
+ return JS.InvokeVoidAsync("SCBBlazor.setHeaderActiveTab", activeTab).AsTask();
812
+ }
813
+
814
+ protected Task SetHeaderDrawerOpenAsync(bool open)
815
+ {
816
+ return JS.InvokeVoidAsync("SCBBlazor.setHeaderDrawerOpen", open).AsTask();
817
+ }
818
+
819
+ protected Task SetHeaderSearchTextAsync(string searchText)
820
+ {
821
+ return JS.InvokeVoidAsync("SCBBlazor.setHeaderSearchText", searchText ?? string.Empty).AsTask();
822
+ }
823
+
824
+ // Drawer och meny
825
+ protected Task SetDrawerOpenAsync(bool open)
826
+ {
827
+ return JS.InvokeVoidAsync("SCBBlazor.setDrawerOpen", open).AsTask();
828
+ }
829
+
830
+ protected Task SetDrawerTextAsync(string label, string subLabel)
831
+ {
832
+ return JS.InvokeVoidAsync(
833
+ "SCBBlazor.setDrawerText",
834
+ label ?? string.Empty,
835
+ subLabel ?? string.Empty).AsTask();
836
+ }
837
+
838
+ protected Task SetMenuOpenAsync(bool open)
839
+ {
840
+ return JS.InvokeVoidAsync("SCBBlazor.setMenuOpen", open).AsTask();
841
+ }
842
+
843
+ // Sub-menyer: index-baserad och id-baserad variant
844
+ protected Task SetSubMenuOpenAsync(int index, bool open)
845
+ {
846
+ return JS.InvokeVoidAsync("SCBBlazor.setSubMenuOpen", index, open).AsTask();
847
+ }
848
+
849
+ protected Task SetSubMenuOpenByIdAsync(string id, bool open)
850
+ {
851
+ return JS.InvokeVoidAsync("SCBBlazor.setSubMenuOpenById", id ?? string.Empty, open).AsTask();
852
+ }
853
+
854
+ // Breadcrumb
855
+ protected Task SetBreadcrumbShowAllAsync(bool showAll)
856
+ {
857
+ return JS.InvokeVoidAsync("SCBBlazor.setBreadcrumbShowAll", showAll).AsTask();
858
+ }
859
+
860
+ // Accordions: index-baserad och id-baserad variant för items
861
+ protected Task SetAccordionItemOpenAsync(int accordionIndex, int itemIndex, bool open)
862
+ {
863
+ return JS.InvokeVoidAsync("SCBBlazor.setAccordionItemOpen", accordionIndex, itemIndex, open).AsTask();
864
+ }
865
+
866
+ protected Task SetAccordionItemOpenByIdAsync(string itemId, bool open)
867
+ {
868
+ return JS.InvokeVoidAsync("SCBBlazor.setAccordionItemOpenById", itemId ?? string.Empty, open).AsTask();
869
+ }
870
+
871
+ // Checkboxar: index-baserad och id-baserad variant
872
+ protected Task SetCheckboxCheckedAsync(int index, bool isChecked)
873
+ {
874
+ return JS.InvokeVoidAsync("SCBBlazor.setCheckboxChecked", index, isChecked).AsTask();
875
+ }
876
+
877
+ protected Task SetCheckboxCheckedByIdAsync(string id, bool isChecked)
878
+ {
879
+ return JS.InvokeVoidAsync("SCBBlazor.setCheckboxCheckedById", id ?? string.Empty, isChecked).AsTask();
880
+ }
881
+
882
+ // Switchar: index-baserad och id-baserad variant
883
+ protected Task SetSwitchSelectedAsync(int index, bool selected)
884
+ {
885
+ return JS.InvokeVoidAsync("SCBBlazor.setSwitchSelected", index, selected).AsTask();
886
+ }
887
+
888
+ protected Task SetSwitchSelectedByIdAsync(string id, bool selected)
889
+ {
890
+ return JS.InvokeVoidAsync("SCBBlazor.setSwitchSelectedById", id ?? string.Empty, selected).AsTask();
891
+ }
892
+
893
+ // Segmented button: global och id-baserad variant
894
+ protected Task SetSegmentedValueAsync(string value)
895
+ {
896
+ return JS.InvokeVoidAsync("SCBBlazor.setSegmentedValue", value ?? string.Empty).AsTask();
897
+ }
898
+
899
+ protected Task SetSegmentedValuesAsync(string[] values)
900
+ {
901
+ return JS.InvokeVoidAsync("SCBBlazor.setSegmentedValues", values ?? Array.Empty<string>()).AsTask();
902
+ }
903
+
904
+ protected Task SetSegmentedValueByIdAsync(string id, string value)
905
+ {
906
+ return JS.InvokeVoidAsync("SCBBlazor.setSegmentedValueById", id ?? string.Empty, value ?? string.Empty).AsTask();
907
+ }
908
+
909
+ protected Task SetSegmentedValuesByIdAsync(string id, string[] values)
910
+ {
911
+ return JS.InvokeVoidAsync("SCBBlazor.setSegmentedValuesById", id ?? string.Empty, values ?? Array.Empty<string>()).AsTask();
912
+ }
913
+
914
+ // Tabs: index-baserad och id-baserad variant
915
+ protected Task SetTabsActiveIndexAsync(int tabsIndex, int activeIndex)
916
+ {
917
+ return JS.InvokeVoidAsync("SCBBlazor.setTabsActiveIndex", tabsIndex, activeIndex).AsTask();
918
+ }
919
+
920
+ protected Task SetTabsActiveIndexByIdAsync(string id, int activeIndex)
921
+ {
922
+ return JS.InvokeVoidAsync("SCBBlazor.setTabsActiveIndexById", id ?? string.Empty, activeIndex).AsTask();
923
+ }
924
+
925
+ // Dialog
926
+ protected Task SetDialogOpenAsync(bool open)
927
+ {
928
+ return JS.InvokeVoidAsync("SCBBlazor.setDialogOpen", open).AsTask();
929
+ }
930
+
931
+ // Notification: index-baserad och id-baserad variant
932
+ protected Task SetNotificationOpenAsync(int index, bool open)
933
+ {
934
+ return JS.InvokeVoidAsync("SCBBlazor.setNotificationOpen", index, open).AsTask();
935
+ }
936
+
937
+ protected Task SetNotificationOpenByIdAsync(string id, bool open)
938
+ {
939
+ return JS.InvokeVoidAsync("SCBBlazor.setNotificationOpenById", id ?? string.Empty, open).AsTask();
940
+ }
941
+
942
+ // Snackbar: index-baserad och id-baserad variant
943
+ protected Task SetSnackbarOpenAsync(int index, bool open)
944
+ {
945
+ return JS.InvokeVoidAsync("SCBBlazor.setSnackbarOpen", index, open).AsTask();
946
+ }
947
+
948
+ protected Task SetSnackbarOpenByIdAsync(string id, bool open)
949
+ {
950
+ return JS.InvokeVoidAsync("SCBBlazor.setSnackbarOpenById", id ?? string.Empty, open).AsTask();
951
+ }
952
+
953
+ // Stepper: global och id-baserad variant
954
+ protected Task SetStepperActiveIndexAsync(int activeIndex)
955
+ {
956
+ return JS.InvokeVoidAsync("SCBBlazor.setStepperActiveIndex", activeIndex).AsTask();
957
+ }
958
+
959
+ protected Task SetStepperActiveIndexByIdAsync(string id, int activeIndex)
960
+ {
961
+ return JS.InvokeVoidAsync("SCBBlazor.setStepperActiveIndexById", id ?? string.Empty, activeIndex).AsTask();
962
+ }
963
+
964
+ // Pagination: index-baserad och id-baserad variant
965
+ protected Task SetPaginationPageAsync(int paginationIndex, int page)
966
+ {
967
+ return JS.InvokeVoidAsync("SCBBlazor.setPaginationPage", paginationIndex, page).AsTask();
968
+ }
969
+
970
+ protected Task SetPaginationPageByIdAsync(string id, int page)
971
+ {
972
+ return JS.InvokeVoidAsync("SCBBlazor.setPaginationPageById", id ?? string.Empty, page).AsTask();
973
+ }
974
+
975
+ // Radio-group: index-, name- och id-baserad variant
976
+ protected Task SetRadioGroupValueByIndexAsync(int index, string value)
977
+ {
978
+ return JS.InvokeVoidAsync("SCBBlazor.setRadioGroupValueByIndex", index, value ?? string.Empty).AsTask();
979
+ }
980
+
981
+ protected Task SetRadioGroupValueByNameAsync(string name, string value)
982
+ {
983
+ return JS.InvokeVoidAsync(
984
+ "SCBBlazor.setRadioGroupValueByName",
985
+ name ?? string.Empty,
986
+ value ?? string.Empty).AsTask();
987
+ }
988
+
989
+ protected Task SetRadioGroupValueByIdAsync(string id, string value)
990
+ {
991
+ return JS.InvokeVoidAsync(
992
+ "SCBBlazor.setRadioGroupValueById",
993
+ id ?? string.Empty,
994
+ value ?? string.Empty).AsTask();
995
+ }
996
+
997
+ // Textfield: index- och id-baserad variant
998
+ protected Task SetTextfieldValueAsync(int index, string value)
999
+ {
1000
+ return JS.InvokeVoidAsync("SCBBlazor.setTextfieldValue", index, value ?? string.Empty).AsTask();
1001
+ }
1002
+
1003
+ protected Task SetTextfieldValueByIdAsync(string id, string value)
1004
+ {
1005
+ return JS.InvokeVoidAsync("SCBBlazor.setTextfieldValueById", id ?? string.Empty, value ?? string.Empty).AsTask();
1006
+ }
1007
+
1008
+ // Search: index- och id-baserad variant
1009
+ protected Task SetSearchValueAsync(int index, string value)
1010
+ {
1011
+ return JS.InvokeVoidAsync("SCBBlazor.setSearchValue", index, value ?? string.Empty).AsTask();
1012
+ }
1013
+
1014
+ protected Task SetSearchValueByIdAsync(string id, string value)
1015
+ {
1016
+ return JS.InvokeVoidAsync("SCBBlazor.setSearchValueById", id ?? string.Empty, value ?? string.Empty).AsTask();
1017
+ }
1018
+
1019
+ // TOC: index-baserad och id-baserad variant för items
1020
+ protected Task SetTocItemExpandedAsync(int tocIndex, int itemIndex, bool expanded)
1021
+ {
1022
+ return JS.InvokeVoidAsync("SCBBlazor.setTocItemExpanded", tocIndex, itemIndex, expanded).AsTask();
1023
+ }
1024
+
1025
+ protected Task SetTocItemExpandedByIdAsync(string itemId, bool expanded)
1026
+ {
1027
+ return JS.InvokeVoidAsync("SCBBlazor.setTocItemExpandedById", itemId ?? string.Empty, expanded).AsTask();
1028
+ }
1029
+
1030
+ // Viz: index- och id-baserad variant
1031
+ protected Task SetVizSelectedChipAsync(int index, string selectedChip)
1032
+ {
1033
+ return JS.InvokeVoidAsync("SCBBlazor.setVizSelectedChip", index, selectedChip ?? string.Empty).AsTask();
1034
+ }
1035
+
1036
+ protected Task SetVizSelectedChipByIdAsync(string id, string selectedChip)
1037
+ {
1038
+ return JS.InvokeVoidAsync("SCBBlazor.setVizSelectedChipById", id ?? string.Empty, selectedChip ?? string.Empty).AsTask();
1039
+ }
1040
+
1041
+ // Nedan följer alla state-klasser som används i Razor views
1042
+
1043
+ protected sealed class HeaderState
1044
+ {
1045
+ public int ActiveTab { get; set; }
1046
+ public bool DrawerOpen { get; set; }
1047
+ public string SearchText { get; set; } = string.Empty;
1048
+ }
1049
+
1050
+ protected sealed class DrawerState
1051
+ {
1052
+ public bool Open { get; set; }
1053
+ public string Label { get; set; } = string.Empty;
1054
+ public string SubLabel { get; set; } = string.Empty;
1055
+ }
1056
+
1057
+ protected sealed class MenuState
1058
+ {
1059
+ public bool Open { get; set; }
1060
+ }
1061
+
1062
+ protected sealed class SubMenuState
1063
+ {
1064
+ public bool Open { get; set; }
1065
+ public bool OpenLeft { get; set; }
1066
+ }
1067
+
1068
+ protected sealed class BreadcrumbState
1069
+ {
1070
+ public bool ShowAll { get; set; }
1071
+ }
1072
+
1073
+ protected sealed class BreadcrumbItemState
1074
+ {
1075
+ public string Label { get; set; } = string.Empty;
1076
+ public bool IsCurrent { get; set; }
1077
+ public string Href { get; set; } = string.Empty;
1078
+ }
1079
+
1080
+ protected sealed class AccordionListState
1081
+ {
1082
+ public bool Detached { get; set; }
1083
+ public AccordionItemState[] Items { get; set; } = Array.Empty<AccordionItemState>();
1084
+ }
1085
+
1086
+ protected sealed class AccordionItemState
1087
+ {
1088
+ public bool Open { get; set; }
1089
+ public string Title { get; set; } = string.Empty;
1090
+ public string Overline { get; set; } = string.Empty;
1091
+ public string SupportingText { get; set; } = string.Empty;
1092
+ }
1093
+
1094
+ protected sealed class CheckboxState
1095
+ {
1096
+ public bool Checked { get; set; }
1097
+ public string Name { get; set; } = string.Empty;
1098
+ public string Value { get; set; } = string.Empty;
1099
+ public string Label { get; set; } = string.Empty;
1100
+ }
1101
+
1102
+ protected sealed class SwitchState
1103
+ {
1104
+ public bool Selected { get; set; }
1105
+ public string Name { get; set; } = string.Empty;
1106
+ public string Value { get; set; } = string.Empty;
1107
+ public string Label { get; set; } = string.Empty;
1108
+ }
1109
+
1110
+ protected sealed class AppBarState
1111
+ {
1112
+ public string Title { get; set; } = string.Empty;
1113
+ public string Type { get; set; } = "default";
1114
+ public string Position { get; set; } = "default";
1115
+ public string SearchSupportingText { get; set; } = string.Empty;
1116
+ }
1117
+
1118
+ protected sealed class SegmentedState
1119
+ {
1120
+ public string Value { get; set; } = string.Empty;
1121
+ public string[] Values { get; set; } = Array.Empty<string>();
1122
+ }
1123
+
1124
+ protected sealed class TabsState
1125
+ {
1126
+ public int ActiveIndex { get; set; }
1127
+ }
1128
+
1129
+ protected sealed class StepperState
1130
+ {
1131
+ public int ActiveIndex { get; set; }
1132
+ public int TotalSteps { get; set; }
1133
+ }
1134
+
1135
+ protected sealed class CardState
1136
+ {
1137
+ public string Type { get; set; } = string.Empty;
1138
+ public string Variant { get; set; } = string.Empty;
1139
+ public string Direction { get; set; } = string.Empty;
1140
+ public string Title { get; set; } = string.Empty;
1141
+ public string Subtitle { get; set; } = string.Empty;
1142
+ public string SupportingText { get; set; } = string.Empty;
1143
+ public string CardHref { get; set; } = string.Empty;
1144
+ }
1145
+
1146
+ protected sealed class KeyfigureState
1147
+ {
1148
+ public string Keyfigure { get; set; } = string.Empty;
1149
+ public string Subtitle { get; set; } = string.Empty;
1150
+ public string SupportingText { get; set; } = string.Empty;
1151
+ public string CardHref { get; set; } = string.Empty;
1152
+ public string Icon { get; set; } = string.Empty;
1153
+ public string Size { get; set; } = string.Empty;
1154
+ public string Unit { get; set; } = string.Empty;
1155
+ }
1156
+
1157
+ protected sealed class CalendarState
1158
+ {
1159
+ public string Title { get; set; } = string.Empty;
1160
+ public string Subtitle { get; set; } = string.Empty;
1161
+ public string SupportingText { get; set; } = string.Empty;
1162
+ public string Variant { get; set; } = "default";
1163
+ public bool ShowMedia { get; set; }
1164
+ }
1165
+
1166
+ protected sealed class DialogState
1167
+ {
1168
+ public bool Open { get; set; }
1169
+ public string Variant { get; set; } = string.Empty;
1170
+ public string Label { get; set; } = string.Empty;
1171
+ }
1172
+
1173
+ protected sealed class NotificationState
1174
+ {
1175
+ public bool Open { get; set; }
1176
+ public string Variant { get; set; } = string.Empty;
1177
+ public string Title { get; set; } = string.Empty;
1178
+ public string Subtitle { get; set; } = string.Empty;
1179
+ public string SupportingText { get; set; } = string.Empty;
1180
+ public string LinkText { get; set; } = string.Empty;
1181
+ public string LinkHref { get; set; } = string.Empty;
1182
+ public bool ShowIcon { get; set; }
1183
+ public bool ShowCloseButton { get; set; }
1184
+ public bool FullHeight { get; set; }
1185
+ public bool FullWidth { get; set; }
1186
+ public string Direction { get; set; } = string.Empty;
1187
+ }
1188
+
1189
+ protected sealed class SnackbarState
1190
+ {
1191
+ public bool Open { get; set; }
1192
+ public string Message { get; set; } = string.Empty;
1193
+ public string ActionText { get; set; } = string.Empty;
1194
+ public bool ShowClose { get; set; }
1195
+ public bool Fixed { get; set; }
1196
+ public bool Fadeout { get; set; }
1197
+ public bool WithLongerAction { get; set; }
1198
+ }
1199
+
1200
+ protected sealed class StatusPillState
1201
+ {
1202
+ public string Status { get; set; } = string.Empty;
1203
+ public string Label { get; set; } = string.Empty;
1204
+ public bool ShowIcon { get; set; }
1205
+ }
1206
+
1207
+ protected sealed class TooltipState
1208
+ {
1209
+ public bool Open { get; set; }
1210
+ public string Variant { get; set; } = string.Empty;
1211
+ public string Position { get; set; } = string.Empty;
1212
+ public string Trigger { get; set; } = string.Empty;
1213
+ public double Delay { get; set; }
1214
+ public double Offset { get; set; }
1215
+ public string Label { get; set; } = string.Empty;
1216
+ public string SupportingText { get; set; } = string.Empty;
1217
+ }
1218
+
1219
+ protected sealed class PaginationState
1220
+ {
1221
+ public int Page { get; set; }
1222
+ public int TotalPages { get; set; }
1223
+ }
1224
+
1225
+ protected sealed class RadioGroupState
1226
+ {
1227
+ public string Name { get; set; } = string.Empty;
1228
+ public string Value { get; set; } = string.Empty;
1229
+ }
1230
+
1231
+ protected sealed class TextfieldState
1232
+ {
1233
+ public string Value { get; set; } = string.Empty;
1234
+ public string Label { get; set; } = string.Empty;
1235
+ public string SupportingText { get; set; } = string.Empty;
1236
+ public bool Error { get; set; }
1237
+ public string Name { get; set; } = string.Empty;
1238
+ public string Id { get; set; } = string.Empty;
1239
+ }
1240
+
1241
+ protected sealed class SearchState
1242
+ {
1243
+ public string Value { get; set; } = string.Empty;
1244
+ public string SupportingText { get; set; } = string.Empty;
1245
+ public bool FullScreen { get; set; }
1246
+ public string Size { get; set; } = string.Empty;
1247
+ public string Name { get; set; } = string.Empty;
1248
+ public string Id { get; set; } = string.Empty;
1249
+ }
1250
+
1251
+ protected sealed class ListState
1252
+ {
1253
+ public bool NoDivider { get; set; }
1254
+ public ListItemState[] Items { get; set; } = Array.Empty<ListItemState>();
1255
+ }
1256
+
1257
+ protected sealed class ListItemState
1258
+ {
1259
+ public string Type { get; set; } = string.Empty;
1260
+ public string Label { get; set; } = string.Empty;
1261
+ public string SupportingText { get; set; } = string.Empty;
1262
+ public string Overline { get; set; } = string.Empty;
1263
+ public bool Leading { get; set; }
1264
+ public string LeadingVariant { get; set; } = string.Empty;
1265
+ public string LeadingIcon { get; set; } = string.Empty;
1266
+ public bool Trailing { get; set; }
1267
+ public string TrailingVariant { get; set; } = string.Empty;
1268
+ public string TrailingIcon { get; set; } = string.Empty;
1269
+ public bool Disabled { get; set; }
1270
+ public string Href { get; set; } = string.Empty;
1271
+ public string ItemHref { get; set; } = string.Empty;
1272
+ public string Target { get; set; } = string.Empty;
1273
+ public int Density { get; set; }
1274
+ public bool NoDivider { get; set; }
1275
+ public string ImgHrefImage { get; set; } = string.Empty;
1276
+ public string AvatarLabel { get; set; } = string.Empty;
1277
+ public string AvatarAlt { get; set; } = string.Empty;
1278
+ public string AvatarVariant { get; set; } = string.Empty;
1279
+ public string AvatarSrc { get; set; } = string.Empty;
1280
+ }
1281
+
1282
+ protected sealed class LinkState
1283
+ {
1284
+ public string Href { get; set; } = string.Empty;
1285
+ public string Target { get; set; } = string.Empty;
1286
+ public string Rel { get; set; } = string.Empty;
1287
+ public string Download { get; set; } = string.Empty;
1288
+ public bool Disabled { get; set; }
1289
+ public string AriaLabel { get; set; } = string.Empty;
1290
+ public string Text { get; set; } = string.Empty;
1291
+ }
1292
+
1293
+ protected sealed class TocState
1294
+ {
1295
+ public bool Detached { get; set; }
1296
+ public TocItemState[] Items { get; set; } = Array.Empty<TocItemState>();
1297
+ }
1298
+
1299
+ protected sealed class TocItemState
1300
+ {
1301
+ public bool Expanded { get; set; }
1302
+ public string Label { get; set; } = string.Empty;
1303
+ public string SupportingText { get; set; } = string.Empty;
1304
+ public string ItemHref { get; set; } = string.Empty;
1305
+ public bool Divider { get; set; }
1306
+ }
1307
+
1308
+ protected sealed class VizState
1309
+ {
1310
+ public string Variant { get; set; } = string.Empty;
1311
+ public string Title { get; set; } = string.Empty;
1312
+ public string Subtitle { get; set; } = string.Empty;
1313
+ public string Description { get; set; } = string.Empty;
1314
+ public string Comment { get; set; } = string.Empty;
1315
+ public string Source { get; set; } = string.Empty;
1316
+ public string Footnote { get; set; } = string.Empty;
1317
+ public string Lang { get; set; } = string.Empty;
1318
+ public string ImageHref { get; set; } = string.Empty;
1319
+ public string SelectedChip { get; set; } = string.Empty;
1320
+ }
1321
+
1322
+ // DTO-klasserna nedan speglar exakt vad JS-bryggan skickar tillbaka
1323
+
1324
+ private sealed class ScbStateDto
1325
+ {
1326
+ public HeaderDto Header { get; set; } = new();
1327
+
1328
+ public DrawerDto Drawer { get; set; } = new();
1329
+
1330
+ public MenuDto Menu { get; set; } = new();
1331
+
1332
+ public SubMenuDto[] SubMenus { get; set; } = Array.Empty<SubMenuDto>();
1333
+
1334
+ public BreadcrumbDto Breadcrumb { get; set; } = new();
1335
+
1336
+ public BreadcrumbItemDto[] BreadcrumbItems { get; set; } = Array.Empty<BreadcrumbItemDto>();
1337
+
1338
+ public AccordionListDto[] Accordions { get; set; } = Array.Empty<AccordionListDto>();
1339
+
1340
+ public CheckboxDto[] Checkboxes { get; set; } = Array.Empty<CheckboxDto>();
1341
+ public SwitchDto[] Switches { get; set; } = Array.Empty<SwitchDto>();
1342
+ public AppBarDto AppBar { get; set; } = new();
1343
+ public SegmentedDto Segmented { get; set; } = new();
1344
+
1345
+ public TabsDto[] Tabs { get; set; } = Array.Empty<TabsDto>();
1346
+
1347
+ public StepperDto Stepper { get; set; } = new();
1348
+
1349
+ public CardDto[] Cards { get; set; } = Array.Empty<CardDto>();
1350
+
1351
+ public KeyfigureDto[] Keyfigures { get; set; } = Array.Empty<KeyfigureDto>();
1352
+
1353
+ public CalendarDto Calendar { get; set; } = new();
1354
+
1355
+ public CalendarDto[] Calendars { get; set; } = Array.Empty<CalendarDto>();
1356
+
1357
+ public DialogDto Dialog { get; set; } = new();
1358
+
1359
+ public NotificationDto[] Notifications { get; set; } = Array.Empty<NotificationDto>();
1360
+
1361
+ public SnackbarDto[] Snackbars { get; set; } = Array.Empty<SnackbarDto>();
1362
+
1363
+ public StatusPillDto[] StatusPills { get; set; } = Array.Empty<StatusPillDto>();
1364
+
1365
+ public TooltipDto[] Tooltips { get; set; } = Array.Empty<TooltipDto>();
1366
+
1367
+ public PaginationDto[] Paginations { get; set; } = Array.Empty<PaginationDto>();
1368
+
1369
+ public RadioGroupDto[] RadioGroups { get; set; } = Array.Empty<RadioGroupDto>();
1370
+
1371
+ public TextfieldDto[] Textfields { get; set; } = Array.Empty<TextfieldDto>();
1372
+
1373
+ public SearchDto[] Searches { get; set; } = Array.Empty<SearchDto>();
1374
+
1375
+ public ListDto[] Lists { get; set; } = Array.Empty<ListDto>();
1376
+
1377
+ public LinkDto[] Links { get; set; } = Array.Empty<LinkDto>();
1378
+
1379
+ public TocDto[] Tocs { get; set; } = Array.Empty<TocDto>();
1380
+
1381
+ public VizDto[] Viz { get; set; } = Array.Empty<VizDto>();
1382
+ }
1383
+
1384
+ private sealed class HeaderDto
1385
+ {
1386
+ public int ActiveTab { get; set; }
1387
+ public bool DrawerOpen { get; set; }
1388
+ public string? SearchText { get; set; }
1389
+ }
1390
+
1391
+ private sealed class DrawerDto
1392
+ {
1393
+ public bool Open { get; set; }
1394
+ public string? Label { get; set; }
1395
+ public string? SubLabel { get; set; }
1396
+ }
1397
+
1398
+ private sealed class MenuDto
1399
+ {
1400
+ public bool Open { get; set; }
1401
+ }
1402
+
1403
+ private sealed class SubMenuDto
1404
+ {
1405
+ public bool Open { get; set; }
1406
+ public bool OpenLeft { get; set; }
1407
+ }
1408
+
1409
+ private sealed class BreadcrumbDto
1410
+ {
1411
+ public bool ShowAll { get; set; }
1412
+ }
1413
+
1414
+ private sealed class BreadcrumbItemDto
1415
+ {
1416
+ public string? Label { get; set; }
1417
+ public bool IsCurrent { get; set; }
1418
+ public string? Href { get; set; }
1419
+ }
1420
+
1421
+ private sealed class AccordionListDto
1422
+ {
1423
+ public bool Detached { get; set; }
1424
+ public AccordionItemDto[] Items { get; set; } = Array.Empty<AccordionItemDto>();
1425
+ }
1426
+
1427
+ private sealed class AccordionItemDto
1428
+ {
1429
+ public bool Open { get; set; }
1430
+ public string? Title { get; set; }
1431
+ public string? Overline { get; set; }
1432
+ public string? SupportingText { get; set; }
1433
+ }
1434
+
1435
+ private sealed class CheckboxDto
1436
+ {
1437
+ public bool Checked { get; set; }
1438
+ public string? Name { get; set; }
1439
+ public string? Value { get; set; }
1440
+ public string? Label { get; set; }
1441
+ }
1442
+
1443
+ private sealed class SwitchDto
1444
+ {
1445
+ public bool Selected { get; set; }
1446
+ public string? Name { get; set; }
1447
+ public string? Value { get; set; }
1448
+ public string? Label { get; set; }
1449
+ }
1450
+
1451
+ private sealed class AppBarDto
1452
+ {
1453
+ public string? Title { get; set; }
1454
+ public string? Type { get; set; }
1455
+ public string? Position { get; set; }
1456
+ public string? SearchSupportingText { get; set; }
1457
+ }
1458
+
1459
+ private sealed class SegmentedDto
1460
+ {
1461
+ public string? Value { get; set; }
1462
+ public string[]? Values { get; set; }
1463
+ }
1464
+
1465
+ private sealed class TabsDto
1466
+ {
1467
+ public int ActiveIndex { get; set; }
1468
+ }
1469
+
1470
+ private sealed class StepperDto
1471
+ {
1472
+ public int ActiveIndex { get; set; }
1473
+ public int TotalSteps { get; set; }
1474
+ }
1475
+
1476
+ private sealed class CardDto
1477
+ {
1478
+ public string? Type { get; set; }
1479
+ public string? Variant { get; set; }
1480
+ public string? Direction { get; set; }
1481
+ public string? Title { get; set; }
1482
+ public string? Subtitle { get; set; }
1483
+ public string? SupportingText { get; set; }
1484
+ public string? CardHref { get; set; }
1485
+ }
1486
+
1487
+ private sealed class KeyfigureDto
1488
+ {
1489
+ public string? Keyfigure { get; set; }
1490
+ public string? Subtitle { get; set; }
1491
+ public string? SupportingText { get; set; }
1492
+ public string? CardHref { get; set; }
1493
+ public string? Icon { get; set; }
1494
+ public string? Size { get; set; }
1495
+ public string? Unit { get; set; }
1496
+ }
1497
+
1498
+ private sealed class CalendarDto
1499
+ {
1500
+ public string? Title { get; set; }
1501
+ public string? Subtitle { get; set; }
1502
+ public string? SupportingText { get; set; }
1503
+ public string? Variant { get; set; }
1504
+ public bool ShowMedia { get; set; }
1505
+ }
1506
+
1507
+ private sealed class DialogDto
1508
+ {
1509
+ public bool Open { get; set; }
1510
+ public string? Variant { get; set; }
1511
+ public string? Label { get; set; }
1512
+ }
1513
+
1514
+ private sealed class NotificationDto
1515
+ {
1516
+ public bool Open { get; set; }
1517
+ public string? Variant { get; set; }
1518
+ public string? Title { get; set; }
1519
+ public string? Subtitle { get; set; }
1520
+ public string? SupportingText { get; set; }
1521
+ public string? LinkText { get; set; }
1522
+ public string? LinkHref { get; set; }
1523
+ public bool ShowIcon { get; set; }
1524
+ public bool ShowCloseButton { get; set; }
1525
+ public bool FullHeight { get; set; }
1526
+ public bool FullWidth { get; set; }
1527
+ public string? Direction { get; set; }
1528
+ }
1529
+
1530
+ private sealed class SnackbarDto
1531
+ {
1532
+ public bool Open { get; set; }
1533
+ public string? Message { get; set; }
1534
+ public string? ActionText { get; set; }
1535
+ public bool ShowClose { get; set; }
1536
+ public bool Fixed { get; set; }
1537
+ public bool Fadeout { get; set; }
1538
+ public bool WithLongerAction { get; set; }
1539
+ }
1540
+
1541
+ private sealed class StatusPillDto
1542
+ {
1543
+ public string? Status { get; set; }
1544
+ public string? Label { get; set; }
1545
+ public bool ShowIcon { get; set; }
1546
+ }
1547
+
1548
+ private sealed class TooltipDto
1549
+ {
1550
+ public bool Open { get; set; }
1551
+ public string? Variant { get; set; }
1552
+ public string? Position { get; set; }
1553
+ public string? Trigger { get; set; }
1554
+ public double Delay { get; set; }
1555
+ public double Offset { get; set; }
1556
+ public string? Label { get; set; }
1557
+ public string? SupportingText { get; set; }
1558
+ }
1559
+
1560
+ private sealed class PaginationDto
1561
+ {
1562
+ public int Page { get; set; }
1563
+ public int TotalPages { get; set; }
1564
+ }
1565
+
1566
+ private sealed class RadioGroupDto
1567
+ {
1568
+ public string? Name { get; set; }
1569
+ public string? Value { get; set; }
1570
+ }
1571
+
1572
+ private sealed class TextfieldDto
1573
+ {
1574
+ public string? Value { get; set; }
1575
+ public string? Label { get; set; }
1576
+ public string? SupportingText { get; set; }
1577
+ public bool Error { get; set; }
1578
+ public string? Name { get; set; }
1579
+ public string? Id { get; set; }
1580
+ }
1581
+
1582
+ private sealed class SearchDto
1583
+ {
1584
+ public string? Value { get; set; }
1585
+ public string? SupportingText { get; set; }
1586
+ public bool FullScreen { get; set; }
1587
+ public string? Size { get; set; }
1588
+ public string? Name { get; set; }
1589
+ public string? Id { get; set; }
1590
+ }
1591
+
1592
+ private sealed class ListDto
1593
+ {
1594
+ public bool NoDivider { get; set; }
1595
+ public ListItemDto[] Items { get; set; } = Array.Empty<ListItemDto>();
1596
+ }
1597
+
1598
+ private sealed class ListItemDto
1599
+ {
1600
+ public string? Type { get; set; }
1601
+ public string? Label { get; set; }
1602
+ public string? SupportingText { get; set; }
1603
+ public string? Overline { get; set; }
1604
+ public bool Leading { get; set; }
1605
+ public string? LeadingVariant { get; set; }
1606
+ public string? LeadingIcon { get; set; }
1607
+ public bool Trailing { get; set; }
1608
+ public string? TrailingVariant { get; set; }
1609
+ public string? TrailingIcon { get; set; }
1610
+ public bool Disabled { get; set; }
1611
+ public string? Href { get; set; }
1612
+ public string? ItemHref { get; set; }
1613
+ public string? Target { get; set; }
1614
+ public int Density { get; set; }
1615
+ public bool NoDivider { get; set; }
1616
+ public string? ImgHrefImage { get; set; }
1617
+ public string? AvatarLabel { get; set; }
1618
+ public string? AvatarAlt { get; set; }
1619
+ public string? AvatarVariant { get; set; }
1620
+ public string? AvatarSrc { get; set; }
1621
+ }
1622
+
1623
+ private sealed class LinkDto
1624
+ {
1625
+ public string? Href { get; set; }
1626
+ public string? Target { get; set; }
1627
+ public string? Rel { get; set; }
1628
+ public string? Download { get; set; }
1629
+ public bool Disabled { get; set; }
1630
+ public string? AriaLabel { get; set; }
1631
+ public string? Text { get; set; }
1632
+ }
1633
+
1634
+ private sealed class TocDto
1635
+ {
1636
+ public bool Detached { get; set; }
1637
+ public TocItemDto[] Items { get; set; } = Array.Empty<TocItemDto>();
1638
+ }
1639
+
1640
+ private sealed class TocItemDto
1641
+ {
1642
+ public bool Expanded { get; set; }
1643
+ public string? Label { get; set; }
1644
+ public string? SupportingText { get; set; }
1645
+ public string? ItemHref { get; set; }
1646
+ public bool Divider { get; set; }
1647
+ }
1648
+
1649
+ private sealed class VizDto
1650
+ {
1651
+ public string? Variant { get; set; }
1652
+ public string? Title { get; set; }
1653
+ public string? Subtitle { get; set; }
1654
+ public string? Description { get; set; }
1655
+ public string? Comment { get; set; }
1656
+ public string? Source { get; set; }
1657
+ public string? Footnote { get; set; }
1658
+ public string? Lang { get; set; }
1659
+ public string? ImageHref { get; set; }
1660
+ public string? SelectedChip { get; set; }
1661
+ }
1662
+ }
1663
+ }