@kodaris/krubble-app-components 1.0.37 → 1.0.38

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.
package/dist/shell.js DELETED
@@ -1,961 +0,0 @@
1
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
- return c > 3 && r && Object.defineProperty(target, key, r), r;
6
- };
7
- import { LitElement, html, css, nothing } from 'lit';
8
- import { customElement, property, state } from 'lit/decorators.js';
9
- import { classMap } from 'lit/directives/class-map.js';
10
- import { unsafeHTML } from 'lit/directives/unsafe-html.js';
11
- /**
12
- * Global shell component with app bar for app switching.
13
- *
14
- * The shell provides a horizontal app bar across the top of the viewport containing:
15
- * - Logo/home link on the left
16
- * - App switcher icons in the middle
17
- * - User avatar/menu on the right
18
- *
19
- * This allows individual apps (using kr-scaffold) to utilize the full width
20
- * of the browser window while maintaining consistent global navigation.
21
- *
22
- * @slot - The main content (typically kr-scaffold with the app)
23
- *
24
- * @property {string} logo - URL for the logo image
25
- * @property {KRApp[]} apps - Available applications for the switcher
26
- * @property {string} activeAppId - ID of the currently active app
27
- * @property {KRShellUser} user - User profile data
28
- * @property {KRShellMenuItem[]} menuItems - Custom menu items for user menu
29
- *
30
- * @fires app-click - When an app icon is clicked. Detail: { app: KRApp }
31
- * @fires menu-item-click - When a menu item is clicked. Detail: { item: KRShellMenuItem }
32
- * @fires logout - When logout is clicked
33
- */
34
- let KRShell = class KRShell extends LitElement {
35
- constructor() {
36
- super(...arguments);
37
- this.logo = 'https://s3.amazonaws.com/kodariscom/kodariscom/content/website/kodaris-logo-icon-light-53.png';
38
- this.apps = [];
39
- this.activeAppId = '';
40
- this.user = null;
41
- this.menuItems = [];
42
- this.isUserMenuOpen = false;
43
- this.isAppsMenuOpen = false;
44
- this.pendingRequests = 0;
45
- this.originalFetch = null;
46
- this.originalXhrOpen = null;
47
- // Default icons
48
- this.defaultLogoutIcon = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M17 7l-1.41 1.41L18.17 11H8v2h10.17l-2.58 2.58L17 17l5-5zM4 5h8V3H4c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h8v-2H4V5z"/></svg>';
49
- this.appsGridIcon = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M4 8h4V4H4v4zm6 12h4v-4h-4v4zm-6 0h4v-4H4v4zm0-6h4v-4H4v4zm6 0h4v-4h-4v4zm6-10v4h4V4h-4zm-6 4h4V4h-4v4zm6 6h4v-4h-4v4zm0 6h4v-4h-4v4z"/></svg>';
50
- this.closeIcon = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>';
51
- }
52
- connectedCallback() {
53
- super.connectedCallback();
54
- this.installFetchInterceptor();
55
- // Hide the default Chatlio close button (we use our own custom button)
56
- if (!document.getElementById('chatlio-widget-styles')) {
57
- const style = document.createElement('style');
58
- style.id = 'chatlio-widget-styles';
59
- style.textContent = `
60
- .chatlio-title-bar {
61
- display: none !important;
62
- }
63
-
64
- .chatlio-widget-body {
65
- bottom: 36px !important;
66
- }
67
- `;
68
- document.head.appendChild(style);
69
- }
70
- }
71
- disconnectedCallback() {
72
- super.disconnectedCallback();
73
- this.uninstallFetchInterceptor();
74
- }
75
- /**
76
- * Installs global interceptors for fetch and XMLHttpRequest to track pending HTTP requests.
77
- * Updates `pendingRequests` state when requests start/complete.
78
- */
79
- installFetchInterceptor() {
80
- if (this.originalFetch)
81
- return;
82
- const shell = this;
83
- // Intercept fetch
84
- this.originalFetch = window.fetch.bind(window);
85
- const originalFetch = this.originalFetch;
86
- window.fetch = function (...args) {
87
- shell.pendingRequests++;
88
- return originalFetch(...args).finally(() => {
89
- shell.pendingRequests--;
90
- });
91
- };
92
- // Intercept XMLHttpRequest
93
- this.originalXhrOpen = XMLHttpRequest.prototype.open;
94
- const originalXhrOpen = this.originalXhrOpen;
95
- XMLHttpRequest.prototype.open = function (method, url, async = true, username, password) {
96
- shell.pendingRequests++;
97
- this.addEventListener('loadend', () => {
98
- shell.pendingRequests--;
99
- }, { once: true });
100
- return originalXhrOpen.call(this, method, url, async, username, password);
101
- };
102
- }
103
- /**
104
- * Restores the original fetch and XMLHttpRequest functions.
105
- */
106
- uninstallFetchInterceptor() {
107
- if (this.originalFetch) {
108
- window.fetch = this.originalFetch;
109
- this.originalFetch = null;
110
- }
111
- if (this.originalXhrOpen) {
112
- XMLHttpRequest.prototype.open = this.originalXhrOpen;
113
- this.originalXhrOpen = null;
114
- }
115
- }
116
- handleLogoClick() {
117
- this.dispatchEvent(new CustomEvent('logo-click', {
118
- bubbles: true,
119
- composed: true,
120
- }));
121
- }
122
- toggleUserMenu() {
123
- this.isUserMenuOpen = !this.isUserMenuOpen;
124
- this.isAppsMenuOpen = false;
125
- }
126
- closeUserMenu() {
127
- this.isUserMenuOpen = false;
128
- }
129
- toggleAppsMenu() {
130
- this.isAppsMenuOpen = !this.isAppsMenuOpen;
131
- this.isUserMenuOpen = false;
132
- }
133
- closeAppsMenu() {
134
- this.isAppsMenuOpen = false;
135
- }
136
- handleMenuItemClick(item) {
137
- this.closeUserMenu();
138
- this.dispatchEvent(new CustomEvent('menu-item-click', {
139
- detail: { item },
140
- bubbles: true,
141
- composed: true,
142
- }));
143
- }
144
- handleLogout() {
145
- this.closeUserMenu();
146
- this.dispatchEvent(new CustomEvent('logout', {
147
- bubbles: true,
148
- composed: true,
149
- }));
150
- }
151
- handleChatClick() {
152
- // Toggle Chatlio widget
153
- if (typeof window._chatlio !== 'undefined') {
154
- window._chatlio.showOrHide();
155
- }
156
- }
157
- renderAppsMenu() {
158
- return html `
159
- <div class="appbar-apps">
160
- ${this.isAppsMenuOpen ? html `
161
- <div class="menu-backdrop" @click=${this.closeAppsMenu}></div>
162
- ` : nothing}
163
-
164
- <button
165
- class=${classMap({
166
- 'appbar-apps-btn': true,
167
- 'appbar-apps-btn--open': this.isAppsMenuOpen,
168
- })}
169
- @click=${this.toggleAppsMenu}
170
- >
171
- <span class="appbar-apps-btn__icon">${unsafeHTML(this.appsGridIcon)}</span>
172
- </button>
173
-
174
- <div class=${classMap({
175
- 'appbar-apps-menu': true,
176
- 'appbar-apps-menu--open': this.isAppsMenuOpen,
177
- })}>
178
- <div class="appbar-apps-menu__header">
179
- <h2 class="appbar-apps-menu__title">Applications</h2>
180
- <button class="appbar-apps-menu__close" @click=${this.closeAppsMenu}>
181
- ${unsafeHTML(this.closeIcon)}
182
- </button>
183
- </div>
184
- <div class="appbar-apps-menu__content">
185
- <div class="appbar-apps-menu__list">
186
- ${this.apps.map((app) => html `
187
- <a
188
- class="appbar-apps-menu__item"
189
- href=${app.url}
190
- @click=${(e) => {
191
- this.closeAppsMenu();
192
- const event = new CustomEvent('app-click', {
193
- detail: { app },
194
- bubbles: true,
195
- composed: true,
196
- cancelable: true,
197
- });
198
- this.dispatchEvent(event);
199
- if (event.defaultPrevented) {
200
- e.preventDefault();
201
- }
202
- }}
203
- >
204
- ${app.name}
205
- </a>
206
- `)}
207
- </div>
208
- </div>
209
- </div>
210
- </div>
211
- `;
212
- }
213
- renderUserMenu() {
214
- if (!this.user)
215
- return nothing;
216
- const initials = this.user.name
217
- .split(' ')
218
- .map((part) => part[0])
219
- .join('')
220
- .toUpperCase()
221
- .slice(0, 2);
222
- return html `
223
- <div class="appbar-user">
224
- ${this.isUserMenuOpen ? html `
225
- <div class="menu-backdrop" @click=${this.closeUserMenu}></div>
226
- ` : nothing}
227
-
228
- <div
229
- class="appbar-user__avatar"
230
- @click=${this.toggleUserMenu}
231
- >
232
- ${this.user.avatar
233
- ? html `<img src=${this.user.avatar} alt=${this.user.name} />`
234
- : initials}
235
- </div>
236
-
237
- <div class=${classMap({
238
- 'appbar-user__menu': true,
239
- 'appbar-user__menu--open': this.isUserMenuOpen,
240
- })}>
241
- <div class="appbar-user__header">
242
- <p class="appbar-user__name">${this.user.name}</p>
243
- ${this.user.email ? html `
244
- <p class="appbar-user__email">${this.user.email}</p>
245
- ` : nothing}
246
- </div>
247
-
248
- ${this.menuItems.map((item) => item.divider
249
- ? html `<div class="appbar-user__menu-divider"></div>`
250
- : html `
251
- <button
252
- class="appbar-user__menu-item"
253
- @click=${() => this.handleMenuItemClick(item)}
254
- >
255
- ${item.icon ? html `
256
- <span class="appbar-user__menu-item__icon">${unsafeHTML(item.icon)}</span>
257
- ` : nothing}
258
- ${item.label}
259
- </button>
260
- `)}
261
-
262
- ${this.menuItems.length > 0 ? html `
263
- <div class="appbar-user__menu-divider"></div>
264
- ` : nothing}
265
-
266
- <button
267
- class="appbar-user__menu-item appbar-user__menu-item--danger"
268
- @click=${this.handleLogout}
269
- >
270
- <span class="appbar-user__menu-item__icon">${unsafeHTML(this.defaultLogoutIcon)}</span>
271
- Sign Out
272
- </button>
273
- </div>
274
- </div>
275
- `;
276
- }
277
- render() {
278
- return html `
279
- <div class=${classMap({
280
- 'progress': true,
281
- 'progress--loading': this.pendingRequests > 0,
282
- })}>
283
- <div class="progress__track"></div>
284
- <div class="progress__bar progress__bar--primary">
285
- <span class="progress__bar-inner"></span>
286
- </div>
287
- <div class="progress__bar progress__bar--secondary">
288
- <span class="progress__bar-inner"></span>
289
- </div>
290
- </div>
291
-
292
- <header class="appbar">
293
- <!-- Logo -->
294
- ${this.logo ? html `
295
- <div class="appbar-logo" @click=${this.handleLogoClick}>
296
- <img src=${this.logo} alt="Home" />
297
- </div>
298
- <div class="appbar-divider"></div>
299
- ` : nothing}
300
-
301
- <!-- App Switcher -->
302
- ${this.renderAppsMenu()}
303
-
304
- <div class="appbar-spacer"></div>
305
-
306
- <!-- User -->
307
- ${this.renderUserMenu()}
308
- </header>
309
-
310
- <!-- <div class="subbar">-->
311
- <!-- <nav class="breadcrumbs">-->
312
- <!-- <a href="#">Home</a>-->
313
- <!-- <span class="breadcrumbs__separator">/</span>-->
314
- <!-- <a href="#">Companies</a>-->
315
- <!-- <span class="breadcrumbs__separator">/</span>-->
316
- <!-- <span>Acme Corp</span>-->
317
- <!-- </nav>-->
318
- <!-- </div>-->
319
-
320
- <main class="main">
321
- <slot></slot>
322
- </main>
323
-
324
- <footer class="footer">
325
- <div class="footer-content">
326
- <div class="footer-info">
327
- <span>© ${new Date().getFullYear()} Kodaris. All Rights Reserved.</span>
328
- </div>
329
- <a class="footer-link" target="_blank" href="https://www.kodaris.com/content/privacy-policy">Privacy</a>
330
- <a class="footer-link" target="_blank" href="https://www.kodaris.com/content/terms-use">Terms</a>
331
- <button class="footer-chat" data-chatlio-widget-button @click=${this.handleChatClick}>
332
- <span class="footer-chat__icon">
333
- <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-messages-square-icon lucide-messages-square">
334
- <path d="M16 10a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 14.286V4a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z"/><path d="M20 9a2 2 0 0 1 2 2v10.286a.71.71 0 0 1-1.212.502l-2.202-2.202A2 2 0 0 0 17.172 19H10a2 2 0 0 1-2-2v-1"/>
335
- </svg>
336
- </span>
337
- Chat with us
338
- </button>
339
- </div>
340
- </footer>
341
- `;
342
- }
343
- };
344
- KRShell.styles = css `
345
- :host {
346
- display: flex;
347
- flex-direction: column;
348
- height: 100vh;
349
- width: 100vw;
350
- --kr-shell-bar-height: 48px;
351
- --kr-shell-bar-bg: #10172a; /* matches scaffold nav-bg */
352
- /* --kr-shell-bar-bg: #0a0f1a; */ /* original darker bg */
353
- --kr-shell-bar-border: rgba(255, 255, 255, 0.08);
354
- --kr-shell-icon-size: 36px;
355
- --kr-shell-icon-color: rgba(255, 255, 255, 0.7);
356
- --kr-shell-icon-color-hover: rgba(255, 255, 255, 1);
357
- --kr-shell-icon-color-active: #beea4e;
358
- --kr-shell-icon-bg-hover: rgba(255, 255, 255, 0.08);
359
- --kr-shell-icon-bg-active: rgba(190, 234, 78, 0.15);
360
- --kr-shell-tooltip-bg: #1a2332;
361
- --kr-shell-tooltip-color: #ffffff;
362
- --kr-shell-menu-bg: #1a2332;
363
- --kr-shell-menu-border: rgba(255, 255, 255, 0.1);
364
- --kr-shell-menu-hover: rgba(255, 255, 255, 0.08);
365
- }
366
-
367
- *,
368
- *::before,
369
- *::after {
370
- box-sizing: border-box;
371
- }
372
-
373
- /* App Bar */
374
- .appbar {
375
- height: var(--kr-shell-bar-height);
376
- background: var(--kr-shell-bar-bg);
377
- border-bottom: 1px solid var(--kr-shell-bar-border);
378
- display: flex;
379
- align-items: center;
380
- padding: 0 16px;
381
- flex-shrink: 0;
382
- z-index: 100;
383
- }
384
-
385
- /* Logo */
386
- .appbar-logo {
387
- cursor: pointer;
388
- margin-right: 8px;
389
- }
390
-
391
- .appbar-logo img {
392
- display: block;
393
- max-width: 24px;
394
- max-height: 24px;
395
- object-fit: contain;
396
- }
397
-
398
- /* Divider */
399
- .appbar-divider {
400
- width: 1px;
401
- height: 24px;
402
- background: #ffffff4f;
403
- margin: 0 10px;
404
- }
405
-
406
- /* Apps Button */
407
- .appbar-apps {
408
- position: relative;
409
- }
410
-
411
- .appbar-apps-btn {
412
- width: var(--kr-shell-icon-size);
413
- height: var(--kr-shell-icon-size);
414
- display: flex;
415
- align-items: center;
416
- justify-content: center;
417
- border-radius: 6px;
418
- cursor: pointer;
419
- color: var(--kr-shell-icon-color);
420
- background: transparent;
421
- border: none;
422
- padding: 0;
423
- transition: all 0.15s ease;
424
- }
425
-
426
- .appbar-apps-btn:hover {
427
- color: var(--kr-shell-icon-color-hover);
428
- background: var(--kr-shell-icon-bg-hover);
429
- }
430
-
431
- .appbar-apps-btn--open {
432
- color: var(--kr-shell-icon-color-hover);
433
- background: var(--kr-shell-icon-bg-hover);
434
- }
435
-
436
- .appbar-apps-btn__icon {
437
- width: 24px;
438
- height: 24px;
439
- display: flex;
440
- align-items: center;
441
- justify-content: center;
442
- color: #ffffff;
443
- }
444
-
445
- .appbar-apps-btn__icon svg {
446
- width: 100%;
447
- height: 100%;
448
- fill: currentColor;
449
- }
450
-
451
- /* Apps Megamenu */
452
- .appbar-apps-menu {
453
- position: absolute;
454
- left: 0;
455
- top: 100%;
456
- margin-top: 6px;
457
- min-width: 320px;
458
- min-height: 90vh;
459
- max-height: calc(100vh - var(--kr-shell-bar-height));
460
- background: #10172a;
461
- border: 1px solid var(--kr-shell-menu-border);
462
- border-top: none;
463
- border-radius: 0 0 8px 8px;
464
- box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
465
- z-index: 1000;
466
- opacity: 0;
467
- visibility: hidden;
468
- transform: translateY(-10px);
469
- transition: all 0.15s ease;
470
- overflow-y: auto;
471
- }
472
-
473
- .appbar-apps-menu--open {
474
- opacity: 1;
475
- visibility: visible;
476
- transform: translateY(0);
477
- }
478
-
479
- .appbar-apps-menu__header {
480
- display: flex;
481
- align-items: center;
482
- justify-content: space-between;
483
- padding: 16px 16px 16px 24px;
484
- border-bottom: 1px solid var(--kr-shell-menu-border);
485
- }
486
-
487
- .appbar-apps-menu__title {
488
- font-size: 16px;
489
- font-weight: 500;
490
- color: #ffffff;
491
- margin: 0;
492
- }
493
-
494
- .appbar-apps-menu__close {
495
- width: 32px;
496
- height: 32px;
497
- display: flex;
498
- align-items: center;
499
- justify-content: center;
500
- background: none;
501
- border: none;
502
- color: rgba(255, 255, 255, 0.6);
503
- cursor: pointer;
504
- border-radius: 6px;
505
- transition: all 0.15s ease;
506
- }
507
-
508
- .appbar-apps-menu__close:hover {
509
- background: var(--kr-shell-menu-hover);
510
- color: #ffffff;
511
- }
512
-
513
- .appbar-apps-menu__close svg {
514
- width: 24px;
515
- height: 24px;
516
- fill: #ffffff;
517
- }
518
-
519
- .appbar-apps-menu__content {
520
- padding: 16px 8px;
521
- }
522
-
523
- .appbar-apps-menu__list {
524
- display: flex;
525
- flex-direction: column;
526
- gap: 2px;
527
- max-width: 320px;
528
- }
529
-
530
- .appbar-apps-menu__item {
531
- display: block;
532
- width: 100%;
533
- padding: 12px 16px;
534
- background: none;
535
- border: none;
536
- color: #ffffff;
537
- font-size: 14px;
538
- font-family: inherit;
539
- text-align: left;
540
- text-decoration: none;
541
- cursor: pointer;
542
- border-radius: 6px;
543
- transition: all 0.15s ease;
544
- }
545
-
546
- .appbar-apps-menu__item:hover {
547
- background: var(--kr-shell-menu-hover);
548
- }
549
-
550
- .appbar-apps-menu__item--active,
551
- .appbar-apps-menu__item--active:hover {
552
- color: var(--kr-shell-icon-color-active);
553
- }
554
-
555
- /* Spacer to push user to the right */
556
- .appbar-spacer {
557
- flex: 1;
558
- }
559
-
560
- /* User Section */
561
- .appbar-user {
562
- position: relative;
563
- margin-left: 8px;
564
- }
565
-
566
- .appbar-user__avatar {
567
- width: 32px;
568
- height: 32px;
569
- border-radius: 50%;
570
- background: #beea4e;
571
- color: #0a0f1a;
572
- display: flex;
573
- align-items: center;
574
- justify-content: center;
575
- font-size: 12px;
576
- font-weight: 600;
577
- cursor: pointer;
578
- overflow: hidden;
579
- border: 2px solid transparent;
580
- transition: border-color 0.15s ease;
581
- }
582
-
583
- .appbar-user__avatar:hover {
584
- border-color: rgba(255, 255, 255, 0.3);
585
- }
586
-
587
- .appbar-user__avatar img {
588
- width: 100%;
589
- height: 100%;
590
- object-fit: cover;
591
- }
592
-
593
- /* User Menu */
594
- .appbar-user__menu {
595
- position: absolute;
596
- right: 0;
597
- top: calc(100% + 8px);
598
- min-width: 200px;
599
- background: var(--kr-shell-menu-bg);
600
- border: 1px solid var(--kr-shell-menu-border);
601
- border-radius: 8px;
602
- padding: 8px;
603
- box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
604
- z-index: 1000;
605
- opacity: 0;
606
- visibility: hidden;
607
- transform: translateY(-8px);
608
- transition: all 0.15s ease;
609
- }
610
-
611
- .appbar-user__menu--open {
612
- opacity: 1;
613
- visibility: visible;
614
- transform: translateY(0);
615
- }
616
-
617
- .appbar-user__header {
618
- padding: 8px 12px 12px;
619
- border-bottom: 1px solid var(--kr-shell-menu-border);
620
- margin-bottom: 8px;
621
- }
622
-
623
- .appbar-user__name {
624
- font-size: 14px;
625
- font-weight: 600;
626
- color: #ffffff;
627
- margin: 0 0 2px;
628
- }
629
-
630
- .appbar-user__email {
631
- font-size: 12px;
632
- color: rgba(255, 255, 255, 0.6);
633
- margin: 0;
634
- }
635
-
636
- .appbar-user__menu-item {
637
- display: flex;
638
- align-items: center;
639
- gap: 10px;
640
- width: 100%;
641
- padding: 10px 12px;
642
- background: none;
643
- border: none;
644
- color: rgba(255, 255, 255, 0.8);
645
- font-size: 13px;
646
- font-family: inherit;
647
- text-align: left;
648
- cursor: pointer;
649
- border-radius: 6px;
650
- transition: all 0.15s ease;
651
- }
652
-
653
- .appbar-user__menu-item:hover {
654
- background: var(--kr-shell-menu-hover);
655
- color: #ffffff;
656
- }
657
-
658
- .appbar-user__menu-item--danger {
659
- color: #f87171;
660
- }
661
-
662
- .appbar-user__menu-item--danger:hover {
663
- background: rgba(248, 113, 113, 0.1);
664
- color: #f87171;
665
- }
666
-
667
- .appbar-user__menu-item__icon {
668
- width: 16px;
669
- height: 16px;
670
- display: flex;
671
- align-items: center;
672
- justify-content: center;
673
- flex-shrink: 0;
674
- }
675
-
676
- .appbar-user__menu-item__icon svg {
677
- width: 100%;
678
- height: 100%;
679
- fill: currentColor;
680
- }
681
-
682
- .appbar-user__menu-divider {
683
- height: 1px;
684
- background: var(--kr-shell-menu-border);
685
- margin: 8px 0;
686
- }
687
-
688
- /* Secondary App Bar */
689
- .subbar {
690
- height: 30px;
691
- background: #364365;
692
- border-bottom: 1px solid rgba(255, 255, 255, 0.08);
693
- display: flex;
694
- align-items: center;
695
- padding: 0 16px;
696
- flex-shrink: 0;
697
- }
698
-
699
- .breadcrumbs {
700
- display: flex;
701
- align-items: center;
702
- gap: 8px;
703
- font-size: 12px;
704
- color: #ffffff;
705
- }
706
-
707
- .breadcrumbs a {
708
- color: #ffffff;
709
- text-decoration: none;
710
- }
711
-
712
- .breadcrumbs a:hover {
713
- text-decoration: underline;
714
- }
715
-
716
- .breadcrumbs__separator {
717
- color: #ffffff;
718
- }
719
-
720
- /* Main Content */
721
- .main {
722
- flex: 1;
723
- min-height: 0;
724
- display: flex;
725
- flex-direction: column;
726
- overflow: hidden;
727
- position: relative;
728
- }
729
-
730
- /* Click outside overlay */
731
- .menu-backdrop {
732
- position: fixed;
733
- inset: 0;
734
- z-index: 999;
735
- }
736
-
737
- /* Progress bar */
738
- .progress {
739
- position: fixed;
740
- top: 0;
741
- left: 0;
742
- right: 0;
743
- height: 4px;
744
- overflow-x: hidden;
745
- z-index: 1000;
746
- display: none;
747
- }
748
-
749
- .progress--loading {
750
- display: block;
751
- }
752
-
753
- .progress__track {
754
- position: absolute;
755
- top: 0;
756
- bottom: 0;
757
- width: 100%;
758
- background: rgb(190 234 78 / 50%); // rgba(190, 234, 78, 0.3);
759
- }
760
-
761
- .progress__bar {
762
- position: absolute;
763
- top: 0;
764
- bottom: 0;
765
- width: 100%;
766
- transform-origin: left center;
767
- }
768
-
769
- .progress__bar-inner {
770
- display: inline-block;
771
- position: absolute;
772
- width: 100%;
773
- height: 100%;
774
- background: #beea4e;
775
- }
776
-
777
- .progress__bar--primary {
778
- left: -145.166611%;
779
- }
780
-
781
- .progress--loading .progress__bar--primary {
782
- animation: progress-primary-translate 2s infinite linear;
783
- }
784
-
785
- .progress--loading .progress__bar--primary .progress__bar-inner {
786
- animation: progress-primary-scale 2s infinite linear;
787
- }
788
-
789
- .progress__bar--secondary {
790
- left: -54.888891%;
791
- }
792
-
793
- .progress--loading .progress__bar--secondary {
794
- animation: progress-secondary-translate 2s infinite linear;
795
- }
796
-
797
- .progress--loading .progress__bar--secondary .progress__bar-inner {
798
- animation: progress-secondary-scale 2s infinite linear;
799
- }
800
-
801
- @keyframes progress-primary-translate {
802
- 0% {
803
- transform: translateX(0);
804
- }
805
- 20% {
806
- animation-timing-function: cubic-bezier(0.5, 0, 0.701732, 0.495819);
807
- transform: translateX(0);
808
- }
809
- 59.15% {
810
- animation-timing-function: cubic-bezier(0.302435, 0.381352, 0.55, 0.956352);
811
- transform: translateX(83.67142%);
812
- }
813
- 100% {
814
- transform: translateX(200.611057%);
815
- }
816
- }
817
-
818
- @keyframes progress-primary-scale {
819
- 0% {
820
- transform: scaleX(0.08);
821
- }
822
- 36.65% {
823
- animation-timing-function: cubic-bezier(0.334731, 0.12482, 0.785844, 1);
824
- transform: scaleX(0.08);
825
- }
826
- 69.15% {
827
- animation-timing-function: cubic-bezier(0.06, 0.11, 0.6, 1);
828
- transform: scaleX(0.661479);
829
- }
830
- 100% {
831
- transform: scaleX(0.08);
832
- }
833
- }
834
-
835
- @keyframes progress-secondary-translate {
836
- 0% {
837
- animation-timing-function: cubic-bezier(0.15, 0, 0.515058, 0.409685);
838
- transform: translateX(0);
839
- }
840
- 25% {
841
- animation-timing-function: cubic-bezier(0.31033, 0.284058, 0.8, 0.733712);
842
- transform: translateX(37.651913%);
843
- }
844
- 48.35% {
845
- animation-timing-function: cubic-bezier(0.4, 0.627035, 0.6, 0.902026);
846
- transform: translateX(84.386165%);
847
- }
848
- 100% {
849
- transform: translateX(160.277782%);
850
- }
851
- }
852
-
853
- @keyframes progress-secondary-scale {
854
- 0% {
855
- animation-timing-function: cubic-bezier(0.205028, 0.057051, 0.57661, 0.453971);
856
- transform: scaleX(0.08);
857
- }
858
- 19.15% {
859
- animation-timing-function: cubic-bezier(0.152313, 0.196432, 0.648374, 1.004315);
860
- transform: scaleX(0.457104);
861
- }
862
- 44.15% {
863
- animation-timing-function: cubic-bezier(0.257759, -0.003163, 0.211762, 1.38179);
864
- transform: scaleX(0.72796);
865
- }
866
- 100% {
867
- transform: scaleX(0.08);
868
- }
869
- }
870
-
871
- .footer {
872
- background: var(--kr-shell-bar-bg);
873
- border-top: 1px solid var(--kr-shell-bar-border);
874
- padding: 8px 16px;
875
- flex-shrink: 0;
876
- }
877
-
878
- .footer-content {
879
- display: flex;
880
- justify-content: flex-end;
881
- align-items: center;
882
- gap: 36px;
883
- }
884
-
885
- .footer-info {
886
- font-size: 12px;
887
- color: rgba(255, 255, 255, 0.7);
888
- }
889
-
890
- .footer-link {
891
- color: rgba(255, 255, 255, 0.7);
892
- text-decoration: none;
893
- font-size: 12px;
894
- }
895
-
896
- .footer-link:hover {
897
- color: #ffffff;
898
- text-decoration: underline;
899
- }
900
-
901
- .footer-chat {
902
- display: flex;
903
- align-items: center;
904
- gap: 6px;
905
- font-size: 14px;
906
- color: #beea4e;
907
- cursor: pointer;
908
- background: none;
909
- border: none;
910
- border-radius: 4px;
911
- font-family: inherit;
912
- transition: background 0.15s ease;
913
- }
914
-
915
- .footer-chat:hover {
916
- background: rgba(255, 255, 255, 0.08);
917
- }
918
-
919
- .footer-chat__icon {
920
- width: 16px;
921
- height: 16px;
922
- display: flex;
923
- align-items: center;
924
- justify-content: center;
925
- }
926
-
927
- .footer-chat__icon svg {
928
- width: 100%;
929
- height: 100%;
930
- stroke: currentColor;
931
- }
932
- `;
933
- __decorate([
934
- property({ type: String })
935
- ], KRShell.prototype, "logo", void 0);
936
- __decorate([
937
- property({ type: Array })
938
- ], KRShell.prototype, "apps", void 0);
939
- __decorate([
940
- property({ type: String, attribute: 'active-app-id' })
941
- ], KRShell.prototype, "activeAppId", void 0);
942
- __decorate([
943
- property({ type: Object })
944
- ], KRShell.prototype, "user", void 0);
945
- __decorate([
946
- property({ type: Array, attribute: 'menu-items' })
947
- ], KRShell.prototype, "menuItems", void 0);
948
- __decorate([
949
- state()
950
- ], KRShell.prototype, "isUserMenuOpen", void 0);
951
- __decorate([
952
- state()
953
- ], KRShell.prototype, "isAppsMenuOpen", void 0);
954
- __decorate([
955
- state()
956
- ], KRShell.prototype, "pendingRequests", void 0);
957
- KRShell = __decorate([
958
- customElement('kr-shell')
959
- ], KRShell);
960
- export { KRShell };
961
- //# sourceMappingURL=shell.js.map