@kodaris/krubble-app-components 1.0.13 → 1.0.14
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/krubble-app.bundled.js +69 -15
- package/dist/krubble-app.bundled.js.map +1 -1
- package/dist/krubble-app.bundled.min.js +35 -41
- package/dist/krubble-app.bundled.min.js.map +1 -1
- package/dist/krubble-app.umd.js +69 -15
- package/dist/krubble-app.umd.js.map +1 -1
- package/dist/krubble-app.umd.min.js +38 -44
- package/dist/krubble-app.umd.min.js.map +1 -1
- package/dist/scaffold.d.ts +16 -0
- package/dist/scaffold.d.ts.map +1 -1
- package/dist/scaffold.js +40 -14
- package/dist/scaffold.js.map +1 -1
- package/dist/subbar.d.ts +15 -0
- package/dist/subbar.d.ts.map +1 -1
- package/dist/subbar.js +29 -1
- package/dist/subbar.js.map +1 -1
- package/package.json +1 -1
|
@@ -1400,6 +1400,34 @@ let KRScaffold = class KRScaffold extends i$1 {
|
|
|
1400
1400
|
this.originalXhrOpen = null;
|
|
1401
1401
|
}
|
|
1402
1402
|
}
|
|
1403
|
+
/**
|
|
1404
|
+
* Resolves a navigation URL by prepending the base href.
|
|
1405
|
+
*
|
|
1406
|
+
* This method is used for:
|
|
1407
|
+
* 1. Setting href attributes on anchor elements (so Cmd/Ctrl+click opens correct URL in new tab)
|
|
1408
|
+
* 2. Comparing URLs with window.location.pathname in updateActiveNavItem()
|
|
1409
|
+
*
|
|
1410
|
+
* The original item.url is kept intact (without base href) and passed to Angular
|
|
1411
|
+
* via the nav-item-click event. Angular Router expects paths relative to base,
|
|
1412
|
+
* so it handles the base href internally.
|
|
1413
|
+
*
|
|
1414
|
+
* Example with base href "/operations/":
|
|
1415
|
+
* - item.url = "/settings" (used for Angular routing)
|
|
1416
|
+
* - resolveUrl(item) = "/operations/settings" (used for href and URL comparison)
|
|
1417
|
+
*/
|
|
1418
|
+
resolveUrl(item) {
|
|
1419
|
+
if (!item.url)
|
|
1420
|
+
return '#';
|
|
1421
|
+
// External URLs - return as-is
|
|
1422
|
+
if (item.external) {
|
|
1423
|
+
return item.url;
|
|
1424
|
+
}
|
|
1425
|
+
// Remove leading slash from url if present, then combine with base
|
|
1426
|
+
const path = item.url.startsWith('/') ? item.url.slice(1) : item.url;
|
|
1427
|
+
const baseHref = document.querySelector('base')?.getAttribute('href') || '/';
|
|
1428
|
+
const base = baseHref.endsWith('/') ? baseHref : (baseHref + '/');
|
|
1429
|
+
return base + path;
|
|
1430
|
+
}
|
|
1403
1431
|
// =========================================================================
|
|
1404
1432
|
// Navigation Data
|
|
1405
1433
|
// =========================================================================
|
|
@@ -1533,7 +1561,7 @@ let KRScaffold = class KRScaffold extends i$1 {
|
|
|
1533
1561
|
* Handles click on the nav header (logo/title) to navigate home.
|
|
1534
1562
|
* Dispatches a nav-item-click event so Angular can intercept and route.
|
|
1535
1563
|
*/
|
|
1536
|
-
handleNavHeaderClick(
|
|
1564
|
+
handleNavHeaderClick() {
|
|
1537
1565
|
// Clear active state since we're going home
|
|
1538
1566
|
this.activeNavItemId = null;
|
|
1539
1567
|
const navEvent = new CustomEvent('nav-item-click', {
|
|
@@ -1609,6 +1637,10 @@ let KRScaffold = class KRScaffold extends i$1 {
|
|
|
1609
1637
|
this.toggleNavItem(item.id);
|
|
1610
1638
|
}
|
|
1611
1639
|
else {
|
|
1640
|
+
// Allow Ctrl/Cmd+click and middle-click to open in new tab without SPA navigation
|
|
1641
|
+
if (e.ctrlKey || e.metaKey || e.button === 1) {
|
|
1642
|
+
return;
|
|
1643
|
+
}
|
|
1612
1644
|
// Set active item immediately on click for instant visual feedback
|
|
1613
1645
|
this.activeNavItemId = item.id;
|
|
1614
1646
|
const navEvent = new CustomEvent('nav-item-click', {
|
|
@@ -1641,7 +1673,8 @@ let KRScaffold = class KRScaffold extends i$1 {
|
|
|
1641
1673
|
let activeItem = null;
|
|
1642
1674
|
let longestMatch = 0;
|
|
1643
1675
|
for (const item of allItems) {
|
|
1644
|
-
|
|
1676
|
+
// Use resolveUrl because currentPath includes base href
|
|
1677
|
+
const url = this.resolveUrl(item);
|
|
1645
1678
|
if (currentPath.startsWith(url) && url.length > longestMatch) {
|
|
1646
1679
|
activeItem = item;
|
|
1647
1680
|
longestMatch = url.length;
|
|
@@ -2216,7 +2249,7 @@ let KRScaffold = class KRScaffold extends i$1 {
|
|
|
2216
2249
|
'nav-item--drop-below': this.navItemDropTargetId === item.id && this.navItemDropPosition === 'below',
|
|
2217
2250
|
})}
|
|
2218
2251
|
data-id="${item.id}"
|
|
2219
|
-
href=${item
|
|
2252
|
+
href=${this.resolveUrl(item)}
|
|
2220
2253
|
target=${item.external ? '_blank' : A}
|
|
2221
2254
|
@mousedown=${(e) => this.handleNavItemMouseDown(e, item)}
|
|
2222
2255
|
@click=${(e) => this.handleNavItemClick(e, item)}
|
|
@@ -2325,9 +2358,8 @@ KRScaffold.styles = i$4 `
|
|
|
2325
2358
|
--kr-scaffold-nav-active-bg: #e5e7eb;
|
|
2326
2359
|
--kr-scaffold-nav-border: rgb(229, 229, 228);
|
|
2327
2360
|
--kr-scaffold-nav-divider: #e5e7eb;
|
|
2328
|
-
--kr-scaffold-nav-search-bg: #
|
|
2329
|
-
--kr-scaffold-nav-search-
|
|
2330
|
-
--kr-scaffold-nav-search-focus-border: #d1d5db;
|
|
2361
|
+
--kr-scaffold-nav-search-bg: #ffffff;
|
|
2362
|
+
--kr-scaffold-nav-search-border: #d1d5db;
|
|
2331
2363
|
}
|
|
2332
2364
|
|
|
2333
2365
|
/* Dark scheme */
|
|
@@ -2340,8 +2372,7 @@ KRScaffold.styles = i$4 `
|
|
|
2340
2372
|
--kr-scaffold-nav-border: transparent;
|
|
2341
2373
|
--kr-scaffold-nav-divider: rgba(255, 255, 255, 0.06);
|
|
2342
2374
|
--kr-scaffold-nav-search-bg: rgba(255, 255, 255, 0.15);
|
|
2343
|
-
--kr-scaffold-nav-search-
|
|
2344
|
-
--kr-scaffold-nav-search-focus-border: rgba(255, 255, 255, 0.3);
|
|
2375
|
+
--kr-scaffold-nav-search-border: rgba(255, 255, 255, 0.3);
|
|
2345
2376
|
}
|
|
2346
2377
|
|
|
2347
2378
|
*,
|
|
@@ -2419,15 +2450,10 @@ KRScaffold.styles = i$4 `
|
|
|
2419
2450
|
padding: 0 12px;
|
|
2420
2451
|
height: 40px;
|
|
2421
2452
|
gap: 8px;
|
|
2422
|
-
border: 1px solid
|
|
2453
|
+
border: 1px solid var(--kr-scaffold-nav-search-border);
|
|
2423
2454
|
transition: all 0.15s ease;
|
|
2424
2455
|
}
|
|
2425
2456
|
|
|
2426
|
-
.nav-search__wrapper:focus-within {
|
|
2427
|
-
background: var(--kr-scaffold-nav-search-focus-bg);
|
|
2428
|
-
border-color: var(--kr-scaffold-nav-search-focus-border);
|
|
2429
|
-
}
|
|
2430
|
-
|
|
2431
2457
|
.nav-search__icon {
|
|
2432
2458
|
width: 18px;
|
|
2433
2459
|
height: 18px;
|
|
@@ -3536,6 +3562,29 @@ let KRSubbar = class KRSubbar extends i$1 {
|
|
|
3536
3562
|
_handleMenuClick() {
|
|
3537
3563
|
this.dispatchEvent(new CustomEvent('menu-click', { bubbles: true, composed: true }));
|
|
3538
3564
|
}
|
|
3565
|
+
/**
|
|
3566
|
+
* Resolves a breadcrumb URL by prepending the base href.
|
|
3567
|
+
*
|
|
3568
|
+
* This method is used for setting href attributes on anchor elements
|
|
3569
|
+
* (so Cmd/Ctrl+click opens correct URL in new tab).
|
|
3570
|
+
*
|
|
3571
|
+
* The original crumb.url is kept intact (without base href) and passed to Angular
|
|
3572
|
+
* via the breadcrumb-click event. Angular Router expects paths relative to base,
|
|
3573
|
+
* so it handles the base href internally.
|
|
3574
|
+
*
|
|
3575
|
+
* Example with base href "/operations/":
|
|
3576
|
+
* - crumb.url = "/settings" (used for Angular routing)
|
|
3577
|
+
* - resolveUrl(crumb) = "/operations/settings" (used for href)
|
|
3578
|
+
*/
|
|
3579
|
+
resolveUrl(crumb) {
|
|
3580
|
+
if (!crumb.url)
|
|
3581
|
+
return '#';
|
|
3582
|
+
// Remove leading slash from url if present, then combine with base
|
|
3583
|
+
const path = crumb.url.startsWith('/') ? crumb.url.slice(1) : crumb.url;
|
|
3584
|
+
const baseHref = document.querySelector('base')?.getAttribute('href') || '/';
|
|
3585
|
+
const base = baseHref.endsWith('/') ? baseHref : (baseHref + '/');
|
|
3586
|
+
return base + path;
|
|
3587
|
+
}
|
|
3539
3588
|
/**
|
|
3540
3589
|
* Handles click on a breadcrumb link.
|
|
3541
3590
|
* Dispatches a cancelable event so SPA routers can intercept.
|
|
@@ -3546,6 +3595,10 @@ let KRSubbar = class KRSubbar extends i$1 {
|
|
|
3546
3595
|
e.preventDefault();
|
|
3547
3596
|
return;
|
|
3548
3597
|
}
|
|
3598
|
+
// Allow Ctrl/Cmd+click and middle-click to open in new tab without SPA navigation
|
|
3599
|
+
if (e.ctrlKey || e.metaKey || e.button === 1) {
|
|
3600
|
+
return;
|
|
3601
|
+
}
|
|
3549
3602
|
const breadcrumbEvent = new CustomEvent('breadcrumb-click', {
|
|
3550
3603
|
detail: { breadcrumb: crumb },
|
|
3551
3604
|
bubbles: true,
|
|
@@ -3576,7 +3629,7 @@ let KRSubbar = class KRSubbar extends i$1 {
|
|
|
3576
3629
|
${index > 0 ? b `<span class="breadcrumb-separator">/</span>` : ''}
|
|
3577
3630
|
<a
|
|
3578
3631
|
class=${e$1({ 'breadcrumb': true, 'breadcrumb--current': isCurrent })}
|
|
3579
|
-
href=${crumb
|
|
3632
|
+
href=${this.resolveUrl(crumb)}
|
|
3580
3633
|
@click=${(e) => this._handleBreadcrumbClick(e, crumb, isCurrent)}
|
|
3581
3634
|
>${crumb.label}</a>
|
|
3582
3635
|
`;
|
|
@@ -3600,6 +3653,7 @@ KRSubbar.styles = i$4 `
|
|
|
3600
3653
|
align-items: center;
|
|
3601
3654
|
padding: 0 16px;
|
|
3602
3655
|
width: 100%;
|
|
3656
|
+
flex-shrink: 0;
|
|
3603
3657
|
}
|
|
3604
3658
|
|
|
3605
3659
|
.breadcrumbs {
|