@kodaris/krubble-app-components 1.0.127 → 1.0.129

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.
@@ -11511,17 +11511,31 @@
11511
11511
  * { id: 'activity', label: 'Activity', url: '/companies/123/activity' },
11512
11512
  * ]}
11513
11513
  * activeId="overview"
11514
+ * .actions=${[
11515
+ * { id: 'edit', label: 'Edit', variant: 'flat' },
11516
+ * { id: 'archive', label: 'Archive' },
11517
+ * { id: 'delete', label: 'Delete' },
11518
+ * { id: 'export', label: 'Export' },
11519
+ * ]}
11514
11520
  * >
11515
11521
  * <div>Screen content here</div>
11516
11522
  * </kr-screen-nav>
11517
11523
  * ```
11518
11524
  *
11525
+ * Actions render in a footer at the bottom of the nav column. With more than
11526
+ * `maxVisibleActions` (default 3), the overflow collapses into a "More" dropdown.
11527
+ * Listen for `action-click` to handle a click: `e.detail.action` is the action id.
11528
+ *
11519
11529
  * @slot - The main screen content
11520
11530
  *
11521
11531
  * @property {string} label - Main label (e.g., entity name like "Acme Corporation")
11522
11532
  * @property {string} subLabel - Sub label (e.g., entity type like "Company")
11523
11533
  * @property {KRScreenNavItem[]} items - Navigation items as JSON array
11524
11534
  * @property {string} activeId - Currently active item ID
11535
+ * @property {KRScreenNavAction[]} actions - Action buttons rendered in the nav footer
11536
+ * @property {number} maxVisibleActions - Max inline actions before collapsing into a "More" dropdown (default 3)
11537
+ *
11538
+ * @fires action-click - When an action button (inline or overflow) is clicked; detail is `{ action: id }`
11525
11539
  */
11526
11540
  class KRScreenNav extends i$3 {
11527
11541
  constructor() {
@@ -11543,6 +11557,17 @@
11543
11557
  * Can be set explicitly by the parent to override.
11544
11558
  */
11545
11559
  this.activeId = '';
11560
+ /**
11561
+ * Action buttons rendered in the nav footer.
11562
+ */
11563
+ this.actions = [];
11564
+ /**
11565
+ * Max number of inline action buttons before the overflow collapses into a
11566
+ * "More" dropdown. When actions exceed this count, the last visible slot is
11567
+ * used for the "More" button so the total footer button count never exceeds
11568
+ * this value.
11569
+ */
11570
+ this.maxVisibleActions = 3;
11546
11571
  this.handlePopstate = () => {
11547
11572
  this.syncActiveFromUrl();
11548
11573
  };
@@ -11603,7 +11628,35 @@
11603
11628
  this.activeId = match.id;
11604
11629
  }
11605
11630
  }
11631
+ handleActionClick(e, action) {
11632
+ this.dispatchEvent(new CustomEvent('action-click', {
11633
+ detail: { action: action.id },
11634
+ bubbles: true,
11635
+ composed: true,
11636
+ }));
11637
+ }
11638
+ // Fired by the "More" kr-button when an overflow option is chosen; detail is { id, label }.
11639
+ handleMoreSelect(e) {
11640
+ this.dispatchEvent(new CustomEvent('action-click', {
11641
+ detail: { action: e.detail.id },
11642
+ bubbles: true,
11643
+ composed: true,
11644
+ }));
11645
+ }
11606
11646
  render() {
11647
+ const hasOverflow = this.actions.length > this.maxVisibleActions;
11648
+ // When collapsing, the last visible slot is the "More" button, so only
11649
+ // show the first (maxVisibleActions - 1) actions inline.
11650
+ let inlineActions = this.actions;
11651
+ let overflowOptions = [];
11652
+ if (hasOverflow) {
11653
+ inlineActions = this.actions.slice(0, this.maxVisibleActions - 1);
11654
+ // Everything past the inline slots goes into the "More" dropdown.
11655
+ overflowOptions = this.actions.slice(this.maxVisibleActions - 1).map((action) => ({
11656
+ id: action.id,
11657
+ label: action.label,
11658
+ }));
11659
+ }
11607
11660
  return b `
11608
11661
  <nav class="nav">
11609
11662
  ${this.label ? b `
@@ -11630,6 +11683,31 @@
11630
11683
  `)}
11631
11684
  </div>
11632
11685
  </div>
11686
+ ${this.actions.length ? b `
11687
+ <div class="nav-actions">
11688
+ ${inlineActions.map((action) => b `
11689
+ <kr-button
11690
+ class="nav-actions__button"
11691
+ variant=${action.variant || 'outline'}
11692
+ size="small"
11693
+ @click=${(e) => this.handleActionClick(e, action)}
11694
+ >
11695
+ ${action.label}
11696
+ </kr-button>
11697
+ `)}
11698
+ ${hasOverflow ? b `
11699
+ <kr-button
11700
+ class="nav-actions__button"
11701
+ variant="outline"
11702
+ size="small"
11703
+ .options=${overflowOptions}
11704
+ @option-select=${this.handleMoreSelect}
11705
+ >
11706
+ More
11707
+ </kr-button>
11708
+ ` : A}
11709
+ </div>
11710
+ ` : A}
11633
11711
  </nav>
11634
11712
  <main class="content">
11635
11713
  <div class="content__main">
@@ -11718,6 +11796,19 @@
11718
11796
  font-weight: 700;
11719
11797
  }
11720
11798
 
11799
+ .nav-actions {
11800
+ display: flex;
11801
+ flex-direction: column;
11802
+ gap: 8px;
11803
+ padding: 12px 16px;
11804
+ border-top: 1px solid rgba(0, 0, 0, 0.08);
11805
+ flex-shrink: 0;
11806
+ }
11807
+
11808
+ .nav-actions__button {
11809
+ width: 100%;
11810
+ }
11811
+
11721
11812
  .content {
11722
11813
  flex: 1;
11723
11814
  min-width: 0;
@@ -11742,6 +11833,12 @@
11742
11833
  __decorate$2([
11743
11834
  n$1({ type: String })
11744
11835
  ], KRScreenNav.prototype, "activeId", void 0);
11836
+ __decorate$2([
11837
+ n$1({ type: Array })
11838
+ ], KRScreenNav.prototype, "actions", void 0);
11839
+ __decorate$2([
11840
+ n$1({ type: Number })
11841
+ ], KRScreenNav.prototype, "maxVisibleActions", void 0);
11745
11842
  // Guarded registration: no-op if the tag is already defined, so a second copy of krubble on
11746
11843
  // the page (e.g. the Operations shell loads krubble globally while an embedded app bundled its
11747
11844
  // own copy) doesn't throw. First definition wins.