@bluevolt-tech/lumen 1.3.2 → 1.4.1

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.
@@ -1,5 +1,5 @@
1
1
  // css-inline:/home/runner/work/BV_lumen/BV_lumen/components/bv-filter-panel/bv-filter-panel.css
2
- var bv_filter_panel_default = ":host {\n display: block;\n background: var(--bv-color-neutral-0);\n border: 1px solid var(--bv-color-neutral-200);\n}\n\n.panel-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: var(--bv-spacing-md) var(--bv-spacing-lg);\n border-bottom: 1px solid var(--bv-color-neutral-200);\n}\n\n.panel-title {\n margin: 0;\n font-family: var(--bv-font-family-base);\n font-size: var(--bv-font-size-2xl);\n font-weight: var(--bv-font-weight-medium);\n color: var(--bv-color-neutral-900);\n}\n\n.clear-btn {\n background: none;\n border: none;\n padding: 0;\n font-family: var(--bv-font-family-base);\n font-size: var(--bv-font-size-sm);\n font-weight: var(--bv-font-weight-medium);\n color: var(--bv-color-primary);\n cursor: pointer;\n}\n\n.clear-btn:hover {\n text-decoration: underline;\n}\n\n.groups {\n display: flex;\n flex-direction: column;\n gap: var(--bv-spacing-lg);\n padding: var(--bv-spacing-md) var(--bv-spacing-lg);\n}\n\n.group {\n}\n\n.group-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n cursor: pointer;\n padding-bottom: var(--bv-spacing-sm);\n}\n\n.group-label {\n font-family: var(--bv-font-family-base);\n font-size: var(--bv-font-size-lg);\n font-weight: var(--bv-font-weight-medium);\n color: var(--bv-color-neutral-900);\n}\n\n.group-chevron {\n width: 20px;\n height: 20px;\n color: var(--bv-color-neutral-500);\n transition: transform var(--bv-transition-fast);\n}\n\n.group-chevron.collapsed {\n transform: rotate(180deg);\n}\n\n.group-options {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.group-options.hidden {\n display: none;\n}\n\n.option {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--bv-spacing-xs);\n}\n\n.option bv-checkbox {\n flex: 1;\n min-width: 0;\n}\n\n.option-count {\n display: inline-flex;\n align-items: center;\n padding: 2px var(--bv-spacing-sm);\n background: var(--bv-color-neutral-200);\n border-radius: var(--bv-radius-full);\n font-family: var(--bv-font-family-base);\n font-size: var(--bv-font-size-sm);\n font-weight: var(--bv-font-weight-regular);\n color: var(--bv-color-neutral-600);\n white-space: nowrap;\n flex-shrink: 0;\n}\n";
2
+ var bv_filter_panel_default = ":host {\n display: block;\n background: var(--bv-color-neutral-0);\n border: 1px solid var(--bv-color-neutral-200);\n}\n\n/* Self-hide when there are no groups to show. */\n:host([empty]) {\n display: none;\n}\n\n.panel-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: var(--bv-spacing-md) var(--bv-spacing-lg);\n border-bottom: 1px solid var(--bv-color-neutral-200);\n}\n\n.panel-title {\n margin: 0;\n font-family: var(--bv-font-family-base);\n font-size: var(--bv-font-size-2xl);\n font-weight: var(--bv-font-weight-medium);\n color: var(--bv-color-neutral-900);\n}\n\n.clear-btn {\n background: none;\n border: none;\n padding: 0;\n font-family: var(--bv-font-family-base);\n font-size: var(--bv-font-size-sm);\n font-weight: var(--bv-font-weight-medium);\n color: var(--bv-color-primary);\n cursor: pointer;\n}\n\n.clear-btn:hover {\n text-decoration: underline;\n}\n\n.groups {\n display: flex;\n flex-direction: column;\n gap: var(--bv-spacing-lg);\n padding: var(--bv-spacing-md) var(--bv-spacing-lg);\n}\n\n.group {\n}\n\n.group-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n cursor: pointer;\n padding-bottom: var(--bv-spacing-sm);\n}\n\n.group-label {\n font-family: var(--bv-font-family-base);\n font-size: var(--bv-font-size-lg);\n font-weight: var(--bv-font-weight-medium);\n color: var(--bv-color-neutral-900);\n}\n\n.group-chevron {\n width: 20px;\n height: 20px;\n color: var(--bv-color-neutral-500);\n transition: transform var(--bv-transition-fast);\n}\n\n.group-chevron.collapsed {\n transform: rotate(180deg);\n}\n\n.group-options {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.group-options.hidden {\n display: none;\n}\n\n.option {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--bv-spacing-xs);\n}\n\n.option bv-checkbox {\n flex: 1;\n min-width: 0;\n}\n\n.option-count {\n display: inline-flex;\n align-items: center;\n padding: 2px var(--bv-spacing-sm);\n background: var(--bv-color-neutral-200);\n border-radius: var(--bv-radius-full);\n font-family: var(--bv-font-family-base);\n font-size: var(--bv-font-size-sm);\n font-weight: var(--bv-font-weight-regular);\n color: var(--bv-color-neutral-600);\n white-space: nowrap;\n flex-shrink: 0;\n}\n\n/* Loading skeleton */\n.skeleton {\n display: none;\n flex-direction: column;\n gap: var(--bv-spacing-lg);\n padding: var(--bv-spacing-md) var(--bv-spacing-lg);\n}\n\n:host([loading]) .groups {\n display: none;\n}\n\n:host([loading]) .skeleton {\n display: flex;\n}\n\n.skeleton-group {\n display: flex;\n flex-direction: column;\n gap: var(--bv-spacing-sm);\n}\n\n.skeleton-line {\n height: 14px;\n border-radius: var(--bv-radius-sm);\n background: var(--bv-color-neutral-200);\n animation: bv-skeleton-shimmer 1.5s ease-in-out infinite;\n}\n\n.skeleton-heading {\n height: 20px;\n width: 55%;\n margin-bottom: 4px;\n}\n\n.skeleton-short-line {\n width: 70%;\n}\n\n@keyframes bv-skeleton-shimmer {\n 0%,\n 100% {\n opacity: 1;\n }\n 50% {\n opacity: 0.5;\n }\n}\n";
3
3
 
4
4
  // css-inline:/home/runner/work/BV_lumen/BV_lumen/components/bv-checkbox/bv-checkbox.css
5
5
  var bv_checkbox_default = ":host {\n display: inline-flex;\n font-family: var(--bv-font-family-base);\n}\n\n/* \u2500\u2500 Size tokens \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n:host,\n:host([size='sm']) {\n --_box-size: 16px;\n --_box-radius: 4px;\n --_gap: 8px;\n --_check-size: 10px;\n --_label-size: var(--bv-font-size-sm);\n --_label-lh: 20px;\n}\n\n:host([size='md']) {\n --_box-size: 20px;\n --_box-radius: 6px;\n --_gap: 12px;\n --_check-size: 12px;\n --_label-size: var(--bv-font-size-md);\n --_label-lh: 24px;\n}\n\n/* \u2500\u2500 Layout \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.wrap {\n display: inline-flex;\n align-items: flex-start;\n gap: var(--_gap);\n cursor: pointer;\n user-select: none;\n}\n\n:host([disabled]) .wrap {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n/* \u2500\u2500 Box \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.box {\n width: var(--_box-size);\n height: var(--_box-size);\n border-radius: var(--_box-radius);\n border: 1px solid var(--bv-color-neutral-300);\n background: var(--bv-color-neutral-0);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n margin-top: 2px;\n transition:\n background var(--bv-transition-fast),\n border-color var(--bv-transition-fast);\n}\n\n:host([checked]) .box,\n:host([indeterminate]) .box {\n background: var(--bv-color-primary-50);\n border-color: var(--bv-color-primary);\n}\n\n/* \u2500\u2500 Check icon \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.check {\n display: none;\n width: var(--_check-size);\n height: var(--_check-size);\n color: var(--bv-color-primary);\n line-height: 0;\n}\n\n.check svg {\n width: 100%;\n height: 100%;\n display: block;\n}\n\n:host([checked]) .check,\n:host([indeterminate]) .check {\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n/* \u2500\u2500 Label \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.label {\n font-size: var(--_label-size);\n font-weight: var(--bv-font-weight-medium);\n color: var(--bv-color-secondary-foreground);\n line-height: var(--_label-lh);\n}\n";
@@ -93,10 +93,18 @@ var CHEVRON = `<svg class="group-chevron" viewBox="0 0 20 20" fill="none" xmlns=
93
93
  <path d="M5 12.5l5-5 5 5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
94
94
  </svg>`;
95
95
  var BvFilterPanel = class extends HTMLElement {
96
- static observedAttributes = ["groups"];
96
+ static observedAttributes = ["groups", "loading"];
97
+ get loading() {
98
+ return this.hasAttribute("loading");
99
+ }
100
+ set loading(v) {
101
+ if (v) this.setAttribute("loading", "");
102
+ else this.removeAttribute("loading");
103
+ }
97
104
  _rendered = false;
98
105
  _groups = [];
99
106
  _groupsEl = null;
107
+ _skeletonEl = null;
100
108
  constructor() {
101
109
  super();
102
110
  this.attachShadow({ mode: "open" });
@@ -115,6 +123,9 @@ var BvFilterPanel = class extends HTMLElement {
115
123
  this._parseGroups();
116
124
  if (this._rendered) this._buildGroups();
117
125
  }
126
+ if (name === "loading" && this._rendered) {
127
+ this._syncLoading();
128
+ }
118
129
  }
119
130
  _parseGroups() {
120
131
  try {
@@ -153,12 +164,26 @@ var BvFilterPanel = class extends HTMLElement {
153
164
  this._groupsEl = document.createElement("div");
154
165
  this._groupsEl.className = "groups";
155
166
  this._buildGroups();
156
- shadow.append(header, this._groupsEl);
167
+ this._skeletonEl = document.createElement("div");
168
+ this._skeletonEl.className = "skeleton";
169
+ this._skeletonEl.setAttribute("aria-hidden", "true");
170
+ this._skeletonEl.innerHTML = Array.from({ length: 3 }).map(
171
+ () => '<div class="skeleton-group"><div class="skeleton-line skeleton-heading"></div><div class="skeleton-line"></div><div class="skeleton-line"></div><div class="skeleton-line skeleton-short-line"></div></div>'
172
+ ).join("");
173
+ shadow.append(header, this._groupsEl, this._skeletonEl);
174
+ this._syncLoading();
175
+ }
176
+ _syncLoading() {
177
+ const loading = this.loading;
178
+ this.setAttribute("aria-busy", loading ? "true" : "false");
157
179
  }
158
180
  _buildGroups() {
159
181
  if (!this._groupsEl) return;
160
182
  this._groupsEl.innerHTML = "";
183
+ let rendered = 0;
161
184
  for (const group of this._groups) {
185
+ if (!group.options || group.options.length === 0) continue;
186
+ rendered++;
162
187
  const expanded = group.expanded !== false;
163
188
  const groupEl = document.createElement("div");
164
189
  groupEl.className = "group";
@@ -212,6 +237,8 @@ var BvFilterPanel = class extends HTMLElement {
212
237
  groupEl.append(groupHeader, optionsEl);
213
238
  this._groupsEl.appendChild(groupEl);
214
239
  }
240
+ if (rendered === 0) this.setAttribute("empty", "");
241
+ else this.removeAttribute("empty");
215
242
  }
216
243
  };
217
244
  if (!customElements.get("bv-filter-panel")) {
@@ -8,5 +8,6 @@ export declare class BvPortalHeader extends HTMLElement {
8
8
  constructor();
9
9
  connectedCallback(): void;
10
10
  attributeChangedCallback(name: string, _old: string | null, val: string | null): void;
11
+ private _propagate;
11
12
  private _render;
12
13
  }
@@ -2,7 +2,7 @@
2
2
  var bv_portal_header_default = ":host {\n display: block;\n background: var(--bv-color-neutral-0);\n border: 1px solid var(--bv-color-neutral-200);\n}\n\n.header {\n display: flex;\n flex-direction: column;\n}\n\n.title-bar {\n padding: var(--bv-spacing-md) var(--bv-spacing-lg);\n border-bottom: 1px solid var(--bv-color-neutral-200);\n}\n\n.title {\n margin: 0;\n font-family: var(--bv-font-family-base);\n font-size: var(--bv-font-size-2xl);\n font-weight: var(--bv-font-weight-medium);\n color: var(--bv-color-neutral-900);\n line-height: 32px;\n}\n\n.body {\n display: flex;\n flex-direction: column;\n gap: var(--bv-spacing-sm);\n padding: var(--bv-spacing-md) var(--bv-spacing-lg);\n}\n\nbv-promo-banner {\n align-self: flex-start;\n}\n";
3
3
 
4
4
  // css-inline:/home/runner/work/BV_lumen/BV_lumen/components/bv-user-row/bv-user-row.css
5
- var bv_user_row_default = ":host {\n display: inline-block;\n}\n\n.row {\n display: inline-flex;\n align-items: center;\n gap: var(--bv-spacing-lg);\n}\n\n/* User info */\n.user-info {\n display: flex;\n align-items: center;\n gap: var(--bv-spacing-md);\n min-width: 0;\n}\n\nbv-avatar {\n --bv-avatar-size: 56px;\n flex-shrink: 0;\n}\n\n.text-col {\n display: flex;\n flex-direction: column;\n min-width: 0;\n}\n\n.user-name {\n font-family: var(--bv-font-family-base);\n font-size: var(--bv-font-size-lg);\n font-weight: var(--bv-font-weight-semibold);\n color: var(--bv-color-secondary-foreground);\n line-height: 28px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.user-org {\n font-family: var(--bv-font-family-base);\n font-size: var(--bv-font-size-md);\n font-weight: var(--bv-font-weight-regular);\n color: var(--bv-color-neutral-600);\n line-height: 24px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* Edit button \u2014 white bg, neutral border */\n.edit-btn {\n --bv-button-bg: var(--bv-color-neutral-0);\n --bv-button-bg-hover: var(--bv-color-neutral-100);\n --bv-button-color: var(--bv-color-secondary-foreground);\n --bv-button-border-color: var(--bv-color-neutral-300);\n --bv-button-border-color-hover: var(--bv-color-neutral-400);\n flex-shrink: 0;\n}\n";
5
+ var bv_user_row_default = ":host {\n display: inline-block;\n}\n\n.row {\n display: inline-flex;\n align-items: center;\n gap: var(--bv-spacing-lg);\n}\n\n/* User info */\n.user-info {\n display: flex;\n align-items: center;\n gap: var(--bv-spacing-md);\n min-width: 0;\n}\n\nbv-avatar {\n --bv-avatar-size: 56px;\n flex-shrink: 0;\n}\n\n.text-col {\n display: flex;\n flex-direction: column;\n min-width: 0;\n}\n\n.user-name {\n font-family: var(--bv-font-family-base);\n font-size: var(--bv-font-size-lg);\n font-weight: var(--bv-font-weight-semibold);\n color: var(--bv-color-secondary-foreground);\n line-height: 28px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.user-org {\n font-family: var(--bv-font-family-base);\n font-size: var(--bv-font-size-md);\n font-weight: var(--bv-font-weight-regular);\n color: var(--bv-color-neutral-600);\n line-height: 24px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* Edit action host \u2014 flex to keep either <bv-button> or <a> aligned */\n.edit-action {\n flex-shrink: 0;\n display: inline-flex;\n}\n\n/* Edit button \u2014 white bg, neutral border */\n.edit-btn {\n --bv-button-bg: var(--bv-color-neutral-0);\n --bv-button-bg-hover: var(--bv-color-neutral-100);\n --bv-button-color: var(--bv-color-secondary-foreground);\n --bv-button-border-color: var(--bv-color-neutral-300);\n --bv-button-border-color-hover: var(--bv-color-neutral-400);\n flex-shrink: 0;\n}\n\n/* Edit link \u2014 same visual as .edit-btn, but a real anchor */\n.edit-link {\n display: inline-flex;\n align-items: center;\n gap: var(--bv-spacing-sm);\n padding: 8px 16px;\n background: var(--bv-color-neutral-0);\n color: var(--bv-color-secondary-foreground);\n border: 1px solid var(--bv-color-neutral-300);\n border-radius: var(--bv-radius-md);\n font-family: var(--bv-font-family-base);\n font-size: var(--bv-font-size-sm);\n font-weight: var(--bv-font-weight-medium);\n text-decoration: none;\n cursor: pointer;\n transition:\n background var(--bv-transition-fast),\n border-color var(--bv-transition-fast);\n}\n\n.edit-link:hover {\n background: var(--bv-color-neutral-100);\n border-color: var(--bv-color-neutral-400);\n}\n\n.edit-link:focus-visible {\n outline: 2px solid var(--bv-color-primary);\n outline-offset: 2px;\n}\n";
6
6
 
7
7
  // css-inline:/home/runner/work/BV_lumen/BV_lumen/components/bv-avatar/bv-avatar.css
8
8
  var bv_avatar_default = ":host {\n --bv-avatar-size: 40px;\n --bv-avatar-bg: var(--bv-color-primary-light);\n --bv-avatar-color: var(--bv-color-primary);\n --bv-avatar-radius: var(--bv-radius-full);\n display: inline-flex;\n}\n\n:host([size='xs']) {\n --bv-avatar-size: 24px;\n}\n:host([size='sm']) {\n --bv-avatar-size: 32px;\n}\n:host([size='md']) {\n --bv-avatar-size: 40px;\n}\n:host([size='lg']) {\n --bv-avatar-size: 48px;\n}\n:host([size='xl']) {\n --bv-avatar-size: 64px;\n}\n\n.avatar {\n width: var(--bv-avatar-size);\n height: var(--bv-avatar-size);\n border-radius: var(--bv-avatar-radius);\n background: var(--bv-avatar-bg);\n color: var(--bv-avatar-color);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n flex-shrink: 0;\n font-family: var(--bv-font-family-base);\n font-weight: var(--bv-font-weight-semibold);\n font-size: calc(var(--bv-avatar-size) * 0.38);\n user-select: none;\n}\n\n.avatar img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n display: block;\n}\n";
@@ -84,187 +84,7 @@ if (!customElements.get("bv-avatar")) {
84
84
  }
85
85
 
86
86
  // css-inline:/home/runner/work/BV_lumen/BV_lumen/components/bv-button/bv-button.css
87
- var bv_button_default = `/* \u2500\u2500 Public theming API \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
88
- Apps can override these three properties per-instance:
89
-
90
- HTML: <bv-button style="--bv-button-bg: #e53e3e;">
91
- Angular: <bv-button [style.--bv-button-bg]="brandColor">
92
- JavaScript: btn.style.setProperty('--bv-button-bg', value)
93
-
94
- Hover is auto-computed from the base colors via color-mix().
95
- Override --bv-button-bg-hover / --bv-button-border-color-hover
96
- if you need explicit control over the hovered state.
97
- \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
98
- :host {
99
- /* Default values \u2014 map to global tokens (primary variant) */
100
- --bv-button-bg: var(--bv-color-primary);
101
- --bv-button-bg-hover: color-mix(in srgb, var(--bv-button-bg) 82%, black);
102
- --bv-button-color: var(--bv-color-neutral-0);
103
- --bv-button-border-color: var(--bv-color-primary);
104
- --bv-button-border-color-hover: color-mix(in srgb, var(--bv-button-border-color) 82%, black);
105
- --bv-button-font-family: var(--bv-font-family-base);
106
- --bv-button-font-size: var(--bv-font-size-sm);
107
-
108
- display: inline-block;
109
- font-family: var(--bv-font-family-base);
110
- }
111
-
112
- :host([hidden]) {
113
- display: none;
114
- }
115
-
116
- :host([full-width]) {
117
- display: block;
118
- width: 100%;
119
- }
120
-
121
- /* \u2500\u2500 Variant tokens \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
122
- Each variant re-points the component tokens to different global
123
- tokens. Apps can still override with inline styles \u2014 inline style
124
- always wins due to higher specificity.
125
- \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
126
-
127
- :host([variant='secondary']) {
128
- --bv-button-bg: var(--bv-color-secondary);
129
- --bv-button-border-color: var(--bv-color-secondary);
130
- --bv-button-color: var(--bv-color-secondary-foreground);
131
- }
132
-
133
- :host([variant='tertiary']) {
134
- --bv-button-bg: var(--bv-color-tertiary);
135
- --bv-button-border-color: var(--bv-color-tertiary);
136
- }
137
-
138
- :host([variant='danger']) {
139
- --bv-button-bg: var(--bv-color-danger);
140
- --bv-button-border-color: var(--bv-color-danger);
141
- }
142
-
143
- :host([variant='ghost']) {
144
- --bv-button-bg: transparent;
145
- --bv-button-bg-hover: var(--bv-color-primary-light);
146
- --bv-button-color: var(--bv-color-primary);
147
- --bv-button-border-color: transparent;
148
- --bv-button-border-color-hover: transparent;
149
- }
150
-
151
- :host([variant='outline']) {
152
- --bv-button-bg: transparent;
153
- --bv-button-bg-hover: var(--bv-color-primary-light);
154
- --bv-button-color: var(--bv-color-primary);
155
- --bv-button-border-color: var(--bv-color-primary);
156
- --bv-button-border-color-hover: var(--bv-color-primary);
157
- }
158
-
159
- /* \u2500\u2500 Base button \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
160
- All visual properties read from the component-level tokens above.
161
- \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
162
-
163
- .btn {
164
- display: inline-flex;
165
- align-items: center;
166
- justify-content: center;
167
- gap: var(--bv-spacing-xs);
168
- padding: 10px var(--bv-spacing-md);
169
- min-height: 40px;
170
- width: auto;
171
- font-family: var(--bv-button-font-family);
172
- font-size: var(--bv-button-font-size);
173
- font-style: normal;
174
- font-weight: var(--bv-font-weight-semibold);
175
- line-height: 20px;
176
- border: 1px solid var(--bv-button-border-color);
177
- border-radius: var(--bv-radius-lg);
178
- cursor: pointer;
179
- transition:
180
- background var(--bv-transition-fast),
181
- color var(--bv-transition-fast),
182
- border-color var(--bv-transition-fast),
183
- box-shadow var(--bv-transition-fast),
184
- opacity var(--bv-transition-fast);
185
- white-space: nowrap;
186
- user-select: none;
187
- text-decoration: none;
188
- outline: none;
189
- box-sizing: border-box;
190
- background: var(--bv-button-bg);
191
- color: var(--bv-button-color);
192
- box-shadow: var(--bv-shadow-sm);
193
- }
194
-
195
- :host([full-width]) .btn {
196
- width: 100%;
197
- }
198
-
199
- .btn:hover:not(:disabled) {
200
- background: var(--bv-button-bg-hover);
201
- border-color: var(--bv-button-border-color-hover);
202
- }
203
-
204
- .btn:active:not(:disabled) {
205
- transform: translateY(1px);
206
- }
207
-
208
- .btn:focus-visible {
209
- outline: 2px solid var(--bv-button-border-color);
210
- outline-offset: 2px;
211
- }
212
-
213
- .btn:disabled {
214
- opacity: 0.5;
215
- cursor: not-allowed;
216
- pointer-events: none;
217
- }
218
-
219
- /* \u2500\u2500 Sizes \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500*/
220
-
221
- :host([size='sm']) .btn {
222
- padding: 6px 12px;
223
- min-height: 32px;
224
- font-size: var(--bv-font-size-sm);
225
- }
226
-
227
- :host([size='lg']) .btn {
228
- padding: 12px var(--bv-spacing-lg);
229
- min-height: 48px;
230
- font-size: var(--bv-font-size-md);
231
- }
232
-
233
- /* \u2500\u2500 Icon \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500*/
234
-
235
- .btn-icon {
236
- display: inline-flex;
237
- align-items: center;
238
- flex-shrink: 0;
239
- line-height: 0;
240
- }
241
-
242
- /* \u2500\u2500 Count badge \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500*/
243
-
244
- .btn-count {
245
- opacity: 0.8;
246
- font-weight: var(--bv-font-weight-regular);
247
- }
248
-
249
- /* \u2500\u2500 Loading spinner \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500*/
250
-
251
- .spinner {
252
- display: inline-block;
253
- width: 1em;
254
- height: 1em;
255
- border: 2px solid currentColor;
256
- border-top-color: transparent;
257
- border-radius: 50%;
258
- flex-shrink: 0;
259
- animation: bv-spin 700ms linear infinite;
260
- }
261
-
262
- @keyframes bv-spin {
263
- to {
264
- transform: rotate(360deg);
265
- }
266
- }
267
- `;
87
+ var bv_button_default = "/* \u2500\u2500 Public theming API \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n Apps can override these three properties per-instance:\n\n HTML: <bv-button style=\"--bv-button-bg: #e53e3e;\">\n Angular: <bv-button [style.--bv-button-bg]=\"brandColor\">\n JavaScript: btn.style.setProperty('--bv-button-bg', value)\n\n Hover is auto-computed from the base colors via color-mix().\n Override --bv-button-bg-hover / --bv-button-border-color-hover\n if you need explicit control over the hovered state.\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n:host {\n /* Default values \u2014 map to global tokens (primary variant) */\n --bv-button-bg: var(--bv-color-primary);\n --bv-button-bg-hover: color-mix(in srgb, var(--bv-button-bg) 82%, black);\n --bv-button-color: var(--bv-color-neutral-0);\n --bv-button-border-color: var(--bv-color-primary);\n --bv-button-border-color-hover: color-mix(in srgb, var(--bv-button-border-color) 82%, black);\n --bv-button-font-family: var(--bv-font-family-base);\n --bv-button-font-size: var(--bv-font-size-sm);\n\n display: inline-block;\n font-family: var(--bv-font-family-base);\n}\n\n:host([hidden]) {\n /* `!important` so `hidden` always wins over :host([full-width]) / other display rules. */\n display: none !important;\n}\n\n:host([full-width]) {\n display: block;\n width: 100%;\n}\n\n/* \u2500\u2500 Variant tokens \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n Each variant re-points the component tokens to different global\n tokens. Apps can still override with inline styles \u2014 inline style\n always wins due to higher specificity.\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n:host([variant='secondary']) {\n --bv-button-bg: var(--bv-color-secondary);\n --bv-button-border-color: var(--bv-color-secondary);\n --bv-button-color: var(--bv-color-secondary-foreground);\n}\n\n:host([variant='tertiary']) {\n --bv-button-bg: var(--bv-color-tertiary);\n --bv-button-border-color: var(--bv-color-tertiary);\n}\n\n:host([variant='danger']) {\n --bv-button-bg: var(--bv-color-danger);\n --bv-button-border-color: var(--bv-color-danger);\n}\n\n:host([variant='ghost']) {\n --bv-button-bg: transparent;\n --bv-button-bg-hover: var(--bv-color-primary-light);\n --bv-button-color: var(--bv-color-primary);\n --bv-button-border-color: transparent;\n --bv-button-border-color-hover: transparent;\n}\n\n:host([variant='outline']) {\n --bv-button-bg: transparent;\n --bv-button-bg-hover: var(--bv-color-primary-light);\n --bv-button-color: var(--bv-color-primary);\n --bv-button-border-color: var(--bv-color-primary);\n --bv-button-border-color-hover: var(--bv-color-primary);\n}\n\n/* \u2500\u2500 Base button \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n All visual properties read from the component-level tokens above.\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--bv-spacing-xs);\n padding: 10px var(--bv-spacing-md);\n min-height: 40px;\n width: auto;\n font-family: var(--bv-button-font-family);\n font-size: var(--bv-button-font-size);\n font-style: normal;\n font-weight: var(--bv-font-weight-semibold);\n line-height: 20px;\n border: 1px solid var(--bv-button-border-color);\n border-radius: var(--bv-radius-lg);\n cursor: pointer;\n transition:\n background var(--bv-transition-fast),\n color var(--bv-transition-fast),\n border-color var(--bv-transition-fast),\n box-shadow var(--bv-transition-fast),\n opacity var(--bv-transition-fast);\n white-space: nowrap;\n user-select: none;\n text-decoration: none;\n outline: none;\n box-sizing: border-box;\n background: var(--bv-button-bg);\n color: var(--bv-button-color);\n box-shadow: var(--bv-shadow-sm);\n}\n\n:host([full-width]) .btn {\n width: 100%;\n}\n\n.btn:hover:not(:disabled) {\n background: var(--bv-button-bg-hover);\n border-color: var(--bv-button-border-color-hover);\n}\n\n.btn:active:not(:disabled) {\n transform: translateY(1px);\n}\n\n.btn:focus-visible {\n outline: 2px solid var(--bv-button-border-color);\n outline-offset: 2px;\n}\n\n.btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n}\n\n/* \u2500\u2500 Sizes \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500*/\n\n:host([size='sm']) .btn {\n padding: 6px 12px;\n min-height: 32px;\n font-size: var(--bv-font-size-sm);\n}\n\n:host([size='lg']) .btn {\n padding: 12px var(--bv-spacing-lg);\n min-height: 48px;\n font-size: var(--bv-font-size-md);\n}\n\n/* \u2500\u2500 Icon \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500*/\n\n.btn-icon {\n display: inline-flex;\n align-items: center;\n flex-shrink: 0;\n line-height: 0;\n}\n\n/* \u2500\u2500 Count badge \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500*/\n\n.btn-count {\n opacity: 0.8;\n font-weight: var(--bv-font-weight-regular);\n}\n\n/* \u2500\u2500 Loading spinner \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500*/\n\n.spinner {\n display: inline-block;\n width: 1em;\n height: 1em;\n border: 2px solid currentColor;\n border-top-color: transparent;\n border-radius: 50%;\n flex-shrink: 0;\n animation: bv-spin 700ms linear infinite;\n}\n\n@keyframes bv-spin {\n to {\n transform: rotate(360deg);\n }\n}\n";
268
88
 
269
89
  // components/bv-icon/icons.ts
270
90
  var icons = {
@@ -483,8 +303,24 @@ var BvUserRow = class extends HTMLElement {
483
303
  "user-org",
484
304
  "avatar-src",
485
305
  "avatar-initials",
486
- "greeting"
306
+ "greeting",
307
+ "edit-profile-href",
308
+ "edit-profile-target"
487
309
  ];
310
+ get editProfileHref() {
311
+ return this.getAttribute("edit-profile-href") ?? "";
312
+ }
313
+ set editProfileHref(v) {
314
+ if (v) this.setAttribute("edit-profile-href", v);
315
+ else this.removeAttribute("edit-profile-href");
316
+ }
317
+ get editProfileTarget() {
318
+ return this.getAttribute("edit-profile-target") ?? "";
319
+ }
320
+ set editProfileTarget(v) {
321
+ if (v) this.setAttribute("edit-profile-target", v);
322
+ else this.removeAttribute("edit-profile-target");
323
+ }
488
324
  _rendered = false;
489
325
  _els = {};
490
326
  constructor() {
@@ -520,6 +356,12 @@ var BvUserRow = class extends HTMLElement {
520
356
  greeting: () => {
521
357
  if (this._els.name)
522
358
  this._els.name.textContent = this._greeting() + (this.getAttribute("user-name") ?? "");
359
+ },
360
+ "edit-profile-href": () => {
361
+ this._syncEditAction();
362
+ },
363
+ "edit-profile-target": () => {
364
+ this._syncEditAction();
523
365
  }
524
366
  };
525
367
  (_a = map[name]) == null ? void 0 : _a.call(map);
@@ -557,16 +399,40 @@ var BvUserRow = class extends HTMLElement {
557
399
  this._els.org = org;
558
400
  textCol.append(name, org);
559
401
  userInfo.append(avatar, textCol);
560
- const editBtn = document.createElement("bv-button");
561
- editBtn.className = "edit-btn";
562
- editBtn.setAttribute("icon", "edit");
563
- editBtn.textContent = "Edit Profile";
564
- editBtn.addEventListener("click", () => {
565
- this.dispatchEvent(new CustomEvent("bv-edit-profile", { bubbles: true, composed: true }));
566
- });
567
- this._els.editBtn = editBtn;
568
- row.append(userInfo, editBtn);
402
+ const actionHost = document.createElement("div");
403
+ actionHost.className = "edit-action";
404
+ this._els.actionHost = actionHost;
405
+ row.append(userInfo, actionHost);
569
406
  shadow.appendChild(row);
407
+ this._syncEditAction();
408
+ }
409
+ _syncEditAction() {
410
+ const host = this._els.actionHost;
411
+ if (!host) return;
412
+ const href = this.getAttribute("edit-profile-href") ?? "";
413
+ const target = this.getAttribute("edit-profile-target") ?? "";
414
+ host.innerHTML = "";
415
+ if (href) {
416
+ const link = document.createElement("a");
417
+ link.className = "edit-link";
418
+ link.href = href;
419
+ link.rel = "noopener noreferrer";
420
+ if (target) link.setAttribute("target", target);
421
+ link.textContent = "Edit Profile";
422
+ link.addEventListener("click", () => {
423
+ this.dispatchEvent(new CustomEvent("bv-edit-profile", { bubbles: true, composed: true }));
424
+ });
425
+ host.appendChild(link);
426
+ } else {
427
+ const btn = document.createElement("bv-button");
428
+ btn.className = "edit-btn";
429
+ btn.setAttribute("icon", "edit");
430
+ btn.textContent = "Edit Profile";
431
+ btn.addEventListener("click", () => {
432
+ this.dispatchEvent(new CustomEvent("bv-edit-profile", { bubbles: true, composed: true }));
433
+ });
434
+ host.appendChild(btn);
435
+ }
570
436
  }
571
437
  };
572
438
  if (!customElements.get("bv-user-row")) {
@@ -581,7 +447,14 @@ var CHEVRON = `<svg class="chevron" viewBox="0 0 16 16" fill="none" xmlns="http:
581
447
  <path d="M6 4l4 4-4 4" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
582
448
  </svg>`;
583
449
  var BvPromoBanner = class extends HTMLElement {
584
- static observedAttributes = ["message", "badge-label", "badge-logo", "href"];
450
+ static observedAttributes = ["message", "badge-label", "badge-logo", "href", "target"];
451
+ get target() {
452
+ return this.getAttribute("target") ?? "";
453
+ }
454
+ set target(v) {
455
+ if (v) this.setAttribute("target", v);
456
+ else this.removeAttribute("target");
457
+ }
585
458
  _rendered = false;
586
459
  _messageEl = null;
587
460
  _badgeLabelEl = null;
@@ -608,6 +481,13 @@ var BvPromoBanner = class extends HTMLElement {
608
481
  this._badgeLogoEl.hidden = !val;
609
482
  }
610
483
  if (name === "href" && this._anchor) this._anchor.href = val ?? "";
484
+ if (name === "target" && this._anchor) this._syncTarget();
485
+ }
486
+ _syncTarget() {
487
+ if (!this._anchor) return;
488
+ const t = this.getAttribute("target");
489
+ if (t) this._anchor.setAttribute("target", t);
490
+ else this._anchor.removeAttribute("target");
611
491
  }
612
492
  _render() {
613
493
  if (this._rendered) return;
@@ -623,6 +503,7 @@ var BvPromoBanner = class extends HTMLElement {
623
503
  anchor.href = this.getAttribute("href") ?? "";
624
504
  anchor.rel = "noopener noreferrer";
625
505
  this._anchor = anchor;
506
+ this._syncTarget();
626
507
  const badge = document.createElement("span");
627
508
  badge.className = "badge";
628
509
  const badgeLabel = document.createElement("span");
@@ -728,7 +609,10 @@ var BvPortalHeader = class extends HTMLElement {
728
609
  "promo-message",
729
610
  "promo-badge-label",
730
611
  "promo-badge-logo",
731
- "promo-href"
612
+ "promo-href",
613
+ "promo-target",
614
+ "edit-profile-href",
615
+ "edit-profile-target"
732
616
  ];
733
617
  _rendered = false;
734
618
  _els = {};
@@ -786,10 +670,24 @@ var BvPortalHeader = class extends HTMLElement {
786
670
  "promo-href": () => {
787
671
  var _a2;
788
672
  (_a2 = this._els.promo) == null ? void 0 : _a2.setAttribute("href", val ?? "");
673
+ },
674
+ "promo-target": () => {
675
+ this._propagate(this._els.promo, "target", val);
676
+ },
677
+ "edit-profile-href": () => {
678
+ this._propagate(this._els.userRow, "edit-profile-href", val);
679
+ },
680
+ "edit-profile-target": () => {
681
+ this._propagate(this._els.userRow, "edit-profile-target", val);
789
682
  }
790
683
  };
791
684
  (_a = map[name]) == null ? void 0 : _a.call(map);
792
685
  }
686
+ _propagate(target, attr, val) {
687
+ if (!target) return;
688
+ if (val) target.setAttribute(attr, val);
689
+ else target.removeAttribute(attr);
690
+ }
793
691
  _render() {
794
692
  if (this._rendered) return;
795
693
  this._rendered = true;
@@ -815,6 +713,10 @@ var BvPortalHeader = class extends HTMLElement {
815
713
  userRow.setAttribute("user-org", this.getAttribute("user-org") ?? "");
816
714
  userRow.setAttribute("avatar-src", this.getAttribute("avatar-src") ?? "");
817
715
  userRow.setAttribute("avatar-initials", this.getAttribute("avatar-initials") ?? "");
716
+ const editHref = this.getAttribute("edit-profile-href");
717
+ if (editHref) userRow.setAttribute("edit-profile-href", editHref);
718
+ const editTarget = this.getAttribute("edit-profile-target");
719
+ if (editTarget) userRow.setAttribute("edit-profile-target", editTarget);
818
720
  userRow.addEventListener("bv-edit-profile", () => {
819
721
  this.dispatchEvent(new CustomEvent("bv-edit-profile", { bubbles: true, composed: true }));
820
722
  });
@@ -824,6 +726,8 @@ var BvPortalHeader = class extends HTMLElement {
824
726
  promo.setAttribute("badge-label", this.getAttribute("promo-badge-label") ?? "");
825
727
  promo.setAttribute("badge-logo", this.getAttribute("promo-badge-logo") ?? "");
826
728
  promo.setAttribute("href", this.getAttribute("promo-href") ?? "");
729
+ const promoTarget = this.getAttribute("promo-target");
730
+ if (promoTarget) promo.setAttribute("target", promoTarget);
827
731
  this._els.promo = promo;
828
732
  const search = document.createElement("bv-searchbox");
829
733
  search.setAttribute("size", "lg");
@@ -1,5 +1,8 @@
1
+ export type PromoBannerTarget = '_self' | '_blank' | '_parent' | '_top' | '';
1
2
  export declare class BvPromoBanner extends HTMLElement {
2
3
  static readonly observedAttributes: string[];
4
+ get target(): PromoBannerTarget;
5
+ set target(v: PromoBannerTarget);
3
6
  private _rendered;
4
7
  private _messageEl;
5
8
  private _badgeLabelEl;
@@ -8,5 +11,6 @@ export declare class BvPromoBanner extends HTMLElement {
8
11
  constructor();
9
12
  connectedCallback(): void;
10
13
  attributeChangedCallback(name: string, _old: string | null, val: string | null): void;
14
+ private _syncTarget;
11
15
  private _render;
12
16
  }
@@ -6,7 +6,14 @@ var CHEVRON = `<svg class="chevron" viewBox="0 0 16 16" fill="none" xmlns="http:
6
6
  <path d="M6 4l4 4-4 4" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
7
7
  </svg>`;
8
8
  var BvPromoBanner = class extends HTMLElement {
9
- static observedAttributes = ["message", "badge-label", "badge-logo", "href"];
9
+ static observedAttributes = ["message", "badge-label", "badge-logo", "href", "target"];
10
+ get target() {
11
+ return this.getAttribute("target") ?? "";
12
+ }
13
+ set target(v) {
14
+ if (v) this.setAttribute("target", v);
15
+ else this.removeAttribute("target");
16
+ }
10
17
  _rendered = false;
11
18
  _messageEl = null;
12
19
  _badgeLabelEl = null;
@@ -33,6 +40,13 @@ var BvPromoBanner = class extends HTMLElement {
33
40
  this._badgeLogoEl.hidden = !val;
34
41
  }
35
42
  if (name === "href" && this._anchor) this._anchor.href = val ?? "";
43
+ if (name === "target" && this._anchor) this._syncTarget();
44
+ }
45
+ _syncTarget() {
46
+ if (!this._anchor) return;
47
+ const t = this.getAttribute("target");
48
+ if (t) this._anchor.setAttribute("target", t);
49
+ else this._anchor.removeAttribute("target");
36
50
  }
37
51
  _render() {
38
52
  if (this._rendered) return;
@@ -48,6 +62,7 @@ var BvPromoBanner = class extends HTMLElement {
48
62
  anchor.href = this.getAttribute("href") ?? "";
49
63
  anchor.rel = "noopener noreferrer";
50
64
  this._anchor = anchor;
65
+ this._syncTarget();
51
66
  const badge = document.createElement("span");
52
67
  badge.className = "badge";
53
68
  const badgeLabel = document.createElement("span");
@@ -1,7 +1,12 @@
1
1
  import '../bv-avatar/bv-avatar.ts';
2
2
  import '../bv-button/bv-button.ts';
3
+ export type UserRowEditProfileTarget = '_self' | '_blank' | '_parent' | '_top' | '';
3
4
  export declare class BvUserRow extends HTMLElement {
4
5
  static readonly observedAttributes: string[];
6
+ get editProfileHref(): string;
7
+ set editProfileHref(v: string);
8
+ get editProfileTarget(): UserRowEditProfileTarget;
9
+ set editProfileTarget(v: UserRowEditProfileTarget);
5
10
  private _rendered;
6
11
  private _els;
7
12
  constructor();
@@ -9,4 +14,5 @@ export declare class BvUserRow extends HTMLElement {
9
14
  attributeChangedCallback(name: string, _old: string | null, val: string | null): void;
10
15
  private _greeting;
11
16
  private _render;
17
+ private _syncEditAction;
12
18
  }