@oicl/openbridge-webcomponents-full-bundle 2.0.0-next.154 → 2.0.0-next.155

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.
Files changed (32) hide show
  1. package/bundle/openbridge-webcomponents.bundle.js +129 -6
  2. package/bundle/openbridge-webcomponents.bundle.js.map +1 -1
  3. package/custom-elements.json +43 -6
  4. package/dist/components/user-button/user-button.css.js +68 -1
  5. package/dist/components/user-button/user-button.css.js.map +1 -1
  6. package/dist/components/user-button/user-button.d.ts +8 -1
  7. package/dist/components/user-button/user-button.d.ts.map +1 -1
  8. package/dist/components/user-button/user-button.js +12 -3
  9. package/dist/components/user-button/user-button.js.map +1 -1
  10. package/dist/components/user-menu/user-menu.css.js +15 -0
  11. package/dist/components/user-menu/user-menu.css.js.map +1 -1
  12. package/dist/components/user-menu/user-menu.d.ts +22 -2
  13. package/dist/components/user-menu/user-menu.d.ts.map +1 -1
  14. package/dist/components/user-menu/user-menu.js +34 -2
  15. package/dist/components/user-menu/user-menu.js.map +1 -1
  16. package/dist/generated/locales/es-419.d.ts +1 -0
  17. package/dist/generated/locales/es-419.d.ts.map +1 -1
  18. package/dist/generated/locales/es-419.js +1 -0
  19. package/dist/generated/locales/es-419.js.map +1 -1
  20. package/dist/generated/locales/fi-FI.d.ts +1 -0
  21. package/dist/generated/locales/fi-FI.d.ts.map +1 -1
  22. package/dist/generated/locales/fi-FI.js +1 -0
  23. package/dist/generated/locales/fi-FI.js.map +1 -1
  24. package/package.json +1 -1
  25. package/src/components/user-button/user-button.css +27 -1
  26. package/src/components/user-button/user-button.stories.ts +29 -0
  27. package/src/components/user-button/user-button.ts +22 -3
  28. package/src/components/user-menu/user-menu.css +8 -0
  29. package/src/components/user-menu/user-menu.stories.ts +53 -0
  30. package/src/components/user-menu/user-menu.ts +55 -4
  31. package/src/generated/locales/es-419.ts +1 -0
  32. package/src/generated/locales/fi-FI.ts +1 -0
@@ -8548,7 +8548,7 @@
8548
8548
  {
8549
8549
  "kind": "variable",
8550
8550
  "name": "ObcUserButton",
8551
- "default": "class extends LitElement { constructor() { super(...arguments); this.variant = \"icon\"; this.size = \"regular\"; this.styleType = \"flat\"; this.static = false; this.disabled = false; this.initials = \"\"; } get formattedInitials() { if (!this.initials) return \"\"; const clean = this.initials.replace(/\\s+/g, \"\").toUpperCase(); const maxInitialsLength = this.size === \"large\" ? 3 : 2; if (clean.length > maxInitialsLength) { console.warn( `Initials \"${this.initials}\" are longer than ${maxInitialsLength} characters.` ); return clean.slice(0, maxInitialsLength); } return clean; } get shouldShowIcon() { return this.variant === \"icon\"; } render() { const styleType = this.size === \"large\" && this.styleType === \"flat\" ? \"normal\" : this.styleType; const wrapperClasses = { wrapper: true, \"wrapper-static\": this.static, [`style-${styleType}`]: true, \"mode-icon\": this.shouldShowIcon, \"mode-initials\": !this.shouldShowIcon, \"state-static\": this.static, [`size-${this.size}`]: true }; const tag = this.static ? literal`div` : literal`button`; const label = this.label && !this.static ? html`<span class=\"user-label\" part=\"label\">${this.label}</span>` : nothing; return html` <${tag} class=${classMap(wrapperClasses)} ?disabled=${this.disabled} aria-label=${this.initials || \"User button\"} > <div class=\"content-container\" part=\"content-container\"> <div class=\"user-button-circle\"> ${this.shouldShowIcon ? html` <div class=\"icon-container\"> <slot name=\"icon\"> <!-- Fallback to default icon if no slot content --> <obi-user></obi-user> </slot> </div> ` : html` <span class=\"user-initials\"> ${this.formattedInitials} </span> `} </div> ${label} </div> </${tag}> `; } }"
8551
+ "default": "class extends LitElement { constructor() { super(...arguments); this.variant = \"icon\"; this.size = \"regular\"; this.styleType = \"flat\"; this.static = false; this.disabled = false; this.initials = \"\"; } get formattedInitials() { if (!this.initials) return \"\"; const clean = this.initials.replace(/\\s+/g, \"\").toUpperCase(); const maxInitialsLength = this.size === \"large\" ? 3 : 2; if (clean.length > maxInitialsLength) { console.warn( `Initials \"${this.initials}\" are longer than ${maxInitialsLength} characters.` ); return clean.slice(0, maxInitialsLength); } return clean; } get shouldShowIcon() { return this.variant === \"icon\"; } render() { const styleType = this.size === \"large\" && this.styleType === \"flat\" ? \"normal\" : this.styleType; const wrapperClasses = { wrapper: true, \"wrapper-static\": this.static, [`style-${styleType}`]: true, \"mode-icon\": this.shouldShowIcon, \"mode-initials\": !this.shouldShowIcon, \"state-static\": this.static, [`size-${this.size}`]: true, \"has-sublabel\": Boolean(this.sublabel) && !this.static }; const tag = this.static ? literal`div` : literal`button`; const visibleText = [this.label, this.sublabel].filter(Boolean).join(\", \"); const accessibleName = !this.static && visibleText || this.initials || \"User button\"; const label = this.label && !this.static ? html`<span class=\"user-label\" part=\"label\">${this.label}</span>` : nothing; const sublabel = this.sublabel && !this.static ? html`<span class=\"user-sublabel\" part=\"sublabel\"> ${this.sublabel} </span>` : nothing; return html` <${tag} class=${classMap(wrapperClasses)} ?disabled=${this.disabled} aria-label=${accessibleName} > <div class=\"content-container\" part=\"content-container\"> <div class=\"user-button-circle\"> ${this.shouldShowIcon ? html` <div class=\"icon-container\"> <slot name=\"icon\"> <!-- Fallback to default icon if no slot content --> <obi-user></obi-user> </slot> </div> ` : html` <span class=\"user-initials\"> ${this.formattedInitials} </span> `} </div> ${label} ${sublabel} </div> </${tag}> `; } }"
8552
8552
  }
8553
8553
  ],
8554
8554
  "exports": [
@@ -8601,7 +8601,7 @@
8601
8601
  {
8602
8602
  "kind": "variable",
8603
8603
  "name": "ObcUserMenu",
8604
- "default": "class extends LitElement { constructor() { super(...arguments); this.type = \"sign-in\"; this.size = \"regular\"; this.hasRecentlySignedIn = false; this.showUsername = true; this.username = \"\"; this.showPassword = true; this.password = \"\"; this.usernameError = \"\"; this.passwordError = \"\"; this.recentUsers = []; this.signedInActions = []; } get showRecentUsers() { return this.hasRecentlySignedIn && this.recentUsers.length > 0; } renderTextInput(placeholder, type = HTMLInputTypeAttribute.Text, value = \"\", onInput, errorText = \"\") { const isPassword = type === HTMLInputTypeAttribute.Password; return html` <obc-text-input-field .placeholder=${placeholder} .type=${type} .textAlign=${ObcTextInputFieldTextAlign.Left} .value=${value} .error=${Boolean(errorText)} .errorText=${errorText} .required=${true} .hasClearButton=${!isPassword} @input=${onInput} > </obc-text-input-field> `; } renderUserButtons(count, isLarge) { const size = isLarge ? Size.large : Size.regular; const users = this.recentUsers.slice(0, count); return html` <div class=${classMap({ users: true, large: isLarge, single: users.length === 1 })} > ${users.map( (user) => html` <obc-user-button .variant=${Variant.initials} .styleType=${StyleType.normal} .size=${size} .initials=${user.initials} .label=${user.label} @click=${() => this.handleRecentUserClick(user)} ></obc-user-button> ` )} </div> `; } renderUserProfile(layout, size) { if (!this.userInitials && !this.userLabel) { return nothing; } const userButtonSize = size === \"large\" ? Size.large : Size.regular; return html` <div class=${classMap({ \"user-profile\": true, [layout]: true })} > <obc-user-button class=${classMap({ \"user-avatar\": true, [`size-${size}`]: true })} .variant=${Variant.initials} .styleType=${StyleType.normal} .size=${userButtonSize} .initials=${this.userInitials ?? \"\"} .label=${this.userLabel ?? \"\"} ></obc-user-button> </div> `; } getSignedInActionIcon(actionId) { switch (actionId) { case \"calendar\": return html`<obi-calendar-google></obi-calendar-google>`; case \"log\": return html`<obi-log-open-google></obi-log-open-google>`; case \"preferences\": return html`<obi-settings-iec></obi-settings-iec>`; case \"user-account\": return html`<obi-user></obi-user>`; default: return nothing; } } normalizeActionId(actionId) { return actionId.trim().toLowerCase().replace(/[^a-z0-9]+/g, \"-\"); } handleSignedInActionClick(action) { this.dispatchEvent( new CustomEvent(\"signed-in-action-click\", { detail: { id: action.id, label: action.label } }) ); } handleRecentUserClick(user) { this.dispatchEvent( new CustomEvent(\"recent-user-click\", { detail: { initials: user.initials, label: user.label } }) ); } handleUsernameInput(event) { const target = event.target; this.username = target.value ?? \"\"; if (this.username) { this.usernameError = \"\"; } } handlePasswordInput(event) { const target = event.target; this.password = target.value ?? \"\"; if (this.password) { this.passwordError = \"\"; } } validateSignIn() { let valid = true; const needsUsername = this.type === \"sign-in\" && this.showUsername; const needsPassword = this.showPassword; if (needsUsername && !this.username) { this.usernameError = msg(\"Username is required\"); valid = false; } if (needsPassword && !this.password) { this.passwordError = msg(\"Password is required\"); valid = false; } return valid; } handleSignInClick() { if (!this.validateSignIn()) { return; } this.dispatchEvent( new CustomEvent(\"sign-in-click\", { detail: { username: this.showUsername ? this.username : void 0, password: this.showPassword ? this.password : void 0 } }) ); } handleSignOutClick() { this.dispatchEvent(new CustomEvent(\"sign-out-click\")); } renderSignIn() { return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"Sign in\")}</h3> </div> <div class=${classMap({ \"login-container\": true, \"signin-only\": !this.showRecentUsers })} > ${this.showUsername ? this.renderTextInput( msg(\"Username\"), HTMLInputTypeAttribute.Text, this.username, this.handleUsernameInput.bind(this), this.usernameError ) : nothing} ${this.showPassword ? this.renderTextInput( msg(\"Password\"), HTMLInputTypeAttribute.Password, this.password, this.handlePasswordInput.bind(this), this.passwordError ) : nothing} <obc-button variant=${ButtonVariant.raised} fullWidth @click=${this.handleSignInClick} > ${msg(\"Sign in\")} </obc-button> </div> ${this.showRecentUsers ? html` <div class=\"recent-container\"> <div class=\"title-container\"> <div class=\"subtitle\">${msg(\"Recently signed in\")}</div> </div> <div class=\"actions-container\"> ${this.renderUserButtons(3, true)} </div> </div> ` : nothing} `; } renderSignInSmall() { return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"Sign in\")}</h3> </div> <div class=${classMap({ \"login-container\": true, \"signin-only\": !this.showRecentUsers })} > ${this.showUsername ? this.renderTextInput( msg(\"Username\"), HTMLInputTypeAttribute.Text, this.username, this.handleUsernameInput.bind(this), this.usernameError ) : nothing} ${this.showPassword ? this.renderTextInput( msg(\"Password\"), HTMLInputTypeAttribute.Password, this.password, this.handlePasswordInput.bind(this), this.passwordError ) : nothing} <obc-button variant=${ButtonVariant.raised} fullWidth @click=${this.handleSignInClick} > ${msg(\"Sign in\")} </obc-button> </div> ${this.showRecentUsers ? html` <div class=\"divider\" aria-hidden=\"true\"></div> <div class=\"recent-container recent\"> <div class=\"title-container\"> <div class=\"subtitle\">${msg(\"Recent\")}</div> </div> <div class=\"actions-container\"> ${this.renderUserButtons(3, false)} </div> </div> ` : nothing} `; } renderUserSignIn() { return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"Sign in\")}</h3> </div> <div class=${classMap({ \"login-container\": true, \"signin-only\": !this.showRecentUsers })} > <div class=\"user-primary\"> ${this.renderUserProfile(\"vertical\", \"large\")} </div> <div class=\"fields\"> ${this.showPassword ? this.renderTextInput( msg(\"Password\"), HTMLInputTypeAttribute.Password, this.password, this.handlePasswordInput.bind(this), this.passwordError ) : nothing} <obc-button variant=${ButtonVariant.raised} fullWidth @click=${this.handleSignInClick} > ${msg(\"Sign in\")} </obc-button> </div> </div> ${this.showRecentUsers ? html` <div class=\"recent-container\"> <div class=\"title-container\"> <div class=\"subtitle\">${msg(\"Recently signed in\")}</div> </div> <div class=\"actions-container\"> ${this.renderUserButtons(3, true)} </div> </div> ` : nothing} `; } renderUserSignInSmall() { return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"Sign in\")}</h3> </div> <div class=\"user-container\"> ${this.renderUserProfile(\"horizontal\", \"regular\")} </div> <div class=${classMap({ \"login-container\": true, \"signin-only\": !this.showRecentUsers })} > ${this.showPassword ? this.renderTextInput( msg(\"Password\"), HTMLInputTypeAttribute.Password, this.password, this.handlePasswordInput.bind(this), this.passwordError ) : nothing} <obc-button variant=${ButtonVariant.raised} fullWidth @click=${this.handleSignInClick} > ${msg(\"Sign in\")} </obc-button> </div> ${this.showRecentUsers ? html` <div class=\"divider\" aria-hidden=\"true\"></div> <div class=\"recent-container recent\"> <div class=\"title-container\"> <div class=\"subtitle\">${msg(\"Recent\")}</div> </div> <div class=\"actions-container\"> ${this.renderUserButtons(3, false)} </div> </div> ` : nothing} `; } renderLoadingSignIn() { return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"Sign in\")}</h3> </div> <div class=\"user-primary loading\"> ${this.renderUserProfile(\"vertical\", \"large\")} <obc-progress-bar class=\"progress\" type=${ProgressBarType.linear} mode=${ProgressBarMode.indeterminate} .showValue=${false} ></obc-progress-bar> </div> `; } renderLoadingSignInSmall() { return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"Sign in\")}</h3> </div> <div class=\"user-primary loading\"> ${this.renderUserProfile(\"horizontal\", \"regular\")} <obc-progress-bar class=\"progress\" type=${ProgressBarType.linear} mode=${ProgressBarMode.indeterminate} .showValue=${false} ></obc-progress-bar> </div> `; } renderSignedIn() { return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"User\")}</h3> </div> <div class=\"user-primary signed-in\"> ${this.renderUserProfile(\"vertical\", \"large\")} </div> <div class=\"divider\" aria-hidden=\"true\"></div> ${this.signedInActions.length ? html` <div class=\"nav-container\"> ${this.signedInActions.map((action) => { const normalizedId = this.normalizeActionId(action.id); return html` <obc-navigation-item .label=${action.label} hasIcon @click=${() => this.handleSignedInActionClick(action)} > <span slot=\"icon\"> <slot name=\"signed-in-action-icon-${normalizedId}\"> ${this.getSignedInActionIcon(normalizedId)} </slot> </span> </obc-navigation-item> `; })} </div> ` : nothing} <div class=\"button-container\"> <obc-button variant=${ButtonVariant.normal} fullWidth @click=${this.handleSignOutClick} > ${msg(\"Sign out\")} </obc-button> </div> `; } renderSignedInSmall() { const primaryAction = this.signedInActions.find( (action) => action.id === this.primaryActionId ); return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"User\")}</h3> </div> <div class=\"user-container\"> ${this.renderUserProfile(\"horizontal\", \"regular\")} </div> <div class=\"button-container\"> ${primaryAction ? html` <obc-button variant=${ButtonVariant.normal} fullWidth @click=${() => this.handleSignedInActionClick(primaryAction)} > ${primaryAction.label} </obc-button> ` : nothing} <obc-button variant=${ButtonVariant.normal} fullWidth @click=${this.handleSignOutClick} > ${msg(\"Sign out\")} </obc-button> </div> `; } render() { let content = nothing; if (this.type === \"sign-in\") { content = this.size === \"small\" ? this.renderSignInSmall() : this.renderSignIn(); } if (this.type === \"user-sign-in\") { content = this.size === \"small\" ? this.renderUserSignInSmall() : this.renderUserSignIn(); } if (this.type === \"loading-sign-in\") { content = this.size === \"small\" ? this.renderLoadingSignInSmall() : this.renderLoadingSignIn(); } if (this.type === \"signed-in\") { content = this.size === \"small\" ? this.renderSignedInSmall() : this.renderSignedIn(); } return html` <div class=${classMap({ card: true, [`size-${this.size}`]: true, [`type-${this.type}`]: true })} > ${content} </div> `; } }"
8604
+ "default": "class extends LitElement { constructor() { super(...arguments); this.type = \"sign-in\"; this.size = \"regular\"; this.hasRecentlySignedIn = false; this.showUsername = true; this.username = \"\"; this.showPassword = true; this.password = \"\"; this.usernameError = \"\"; this.passwordError = \"\"; this.recentUsers = []; this.signedInActions = []; this.showUseAnotherAccount = true; } get showRecentUsers() { return this.hasRecentlySignedIn && this.recentUsers.length > 0; } renderTextInput(placeholder, type = HTMLInputTypeAttribute.Text, value = \"\", onInput, errorText = \"\") { const isPassword = type === HTMLInputTypeAttribute.Password; return html` <obc-text-input-field .placeholder=${placeholder} .type=${type} .textAlign=${ObcTextInputFieldTextAlign.Left} .value=${value} .error=${Boolean(errorText)} .errorText=${errorText} .required=${true} .hasClearButton=${!isPassword} @input=${onInput} > </obc-text-input-field> `; } renderUserButtons(count, isLarge) { const size = isLarge ? Size.large : Size.regular; const users = this.recentUsers.slice(0, count); return html` <div class=${classMap({ users: true, large: isLarge, single: users.length === 1 })} > ${users.map( (user) => html` <obc-user-button .variant=${Variant.initials} .styleType=${StyleType.normal} .size=${size} .initials=${user.initials} .label=${user.label} .sublabel=${isLarge ? user.role : void 0} @click=${() => this.handleRecentUserClick(user)} ></obc-user-button> ` )} </div> `; } renderUserProfile(layout, size) { if (!this.userInitials && !this.userLabel) { return nothing; } const userButtonSize = size === \"large\" ? Size.large : Size.regular; const role = size === \"large\" ? this.userRole : void 0; return html` <div class=${classMap({ \"user-profile\": true, [layout]: true })} > <obc-user-button class=${classMap({ \"user-avatar\": true, [`size-${size}`]: true, \"has-role\": Boolean(role) })} .variant=${Variant.initials} .styleType=${StyleType.normal} .size=${userButtonSize} .initials=${this.userInitials ?? \"\"} .label=${this.userLabel ?? \"\"} .sublabel=${role} ></obc-user-button> </div> `; } getSignedInActionIcon(actionId) { switch (actionId) { case \"calendar\": return html`<obi-calendar-google></obi-calendar-google>`; case \"log\": return html`<obi-log-open-google></obi-log-open-google>`; case \"preferences\": return html`<obi-settings-iec></obi-settings-iec>`; case \"user-account\": return html`<obi-user></obi-user>`; default: return nothing; } } normalizeActionId(actionId) { return actionId.trim().toLowerCase().replace(/[^a-z0-9]+/g, \"-\"); } handleSignedInActionClick(action) { this.dispatchEvent( new CustomEvent(\"signed-in-action-click\", { detail: { id: action.id, label: action.label } }) ); } handleRecentUserClick(user) { this.dispatchEvent( new CustomEvent(\"recent-user-click\", { detail: { ...user } }) ); } handleUsernameInput(event) { const target = event.target; this.username = target.value ?? \"\"; if (this.username) { this.usernameError = \"\"; } } handlePasswordInput(event) { const target = event.target; this.password = target.value ?? \"\"; if (this.password) { this.passwordError = \"\"; } } validateSignIn() { let valid = true; const needsUsername = this.type === \"sign-in\" && this.showUsername; const needsPassword = this.showPassword; if (needsUsername && !this.username) { this.usernameError = msg(\"Username is required\"); valid = false; } if (needsPassword && !this.password) { this.passwordError = msg(\"Password is required\"); valid = false; } return valid; } handleSignInClick() { if (!this.validateSignIn()) { return; } this.dispatchEvent( new CustomEvent(\"sign-in-click\", { detail: { username: this.showUsername ? this.username : void 0, password: this.showPassword ? this.password : void 0 } }) ); } handleSignOutClick() { this.dispatchEvent(new CustomEvent(\"sign-out-click\")); } handleUseAnotherAccountClick() { this.dispatchEvent(new CustomEvent(\"use-another-account-click\")); } renderSignIn() { return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"Sign in\")}</h3> </div> <div class=${classMap({ \"login-container\": true, \"signin-only\": !this.showRecentUsers })} > ${this.showUsername ? this.renderTextInput( msg(\"Username\"), HTMLInputTypeAttribute.Text, this.username, this.handleUsernameInput.bind(this), this.usernameError ) : nothing} ${this.showPassword ? this.renderTextInput( msg(\"Password\"), HTMLInputTypeAttribute.Password, this.password, this.handlePasswordInput.bind(this), this.passwordError ) : nothing} <obc-button variant=${ButtonVariant.raised} fullWidth @click=${this.handleSignInClick} > ${msg(\"Sign in\")} </obc-button> </div> ${this.showRecentUsers ? html` <div class=\"recent-container\"> <div class=\"title-container\"> <div class=\"subtitle\">${msg(\"Recently signed in\")}</div> </div> <div class=\"actions-container\"> ${this.renderUserButtons(3, true)} </div> </div> ` : nothing} `; } renderSignInSmall() { return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"Sign in\")}</h3> </div> <div class=${classMap({ \"login-container\": true, \"signin-only\": !this.showRecentUsers })} > ${this.showUsername ? this.renderTextInput( msg(\"Username\"), HTMLInputTypeAttribute.Text, this.username, this.handleUsernameInput.bind(this), this.usernameError ) : nothing} ${this.showPassword ? this.renderTextInput( msg(\"Password\"), HTMLInputTypeAttribute.Password, this.password, this.handlePasswordInput.bind(this), this.passwordError ) : nothing} <obc-button variant=${ButtonVariant.raised} fullWidth @click=${this.handleSignInClick} > ${msg(\"Sign in\")} </obc-button> </div> ${this.showRecentUsers ? html` <div class=\"divider\" aria-hidden=\"true\"></div> <div class=\"recent-container recent\"> <div class=\"title-container\"> <div class=\"subtitle\">${msg(\"Recent\")}</div> </div> <div class=\"actions-container\"> ${this.renderUserButtons(3, false)} </div> </div> ` : nothing} `; } renderUserSignIn() { return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"Sign in\")}</h3> </div> <div class=${classMap({ \"login-container\": true, \"signin-only\": !this.showRecentUsers })} > <div class=\"user-primary\"> ${this.renderUserProfile(\"vertical\", \"large\")} </div> <div class=\"fields\"> ${this.showPassword ? this.renderTextInput( msg(\"Password\"), HTMLInputTypeAttribute.Password, this.password, this.handlePasswordInput.bind(this), this.passwordError ) : nothing} <obc-button variant=${ButtonVariant.raised} fullWidth @click=${this.handleSignInClick} > ${msg(\"Sign in\")} </obc-button> ${this.showUseAnotherAccount ? html` <obc-button variant=${ButtonVariant.normal} fullWidth @click=${this.handleUseAnotherAccountClick} > ${msg(\"Use another account\")} </obc-button> ` : nothing} </div> </div> ${this.showRecentUsers ? html` <div class=\"recent-container\"> <div class=\"title-container\"> <div class=\"subtitle\">${msg(\"Recently signed in\")}</div> </div> <div class=\"actions-container\"> ${this.renderUserButtons(3, true)} </div> </div> ` : nothing} `; } renderUserSignInSmall() { return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"Sign in\")}</h3> </div> <div class=\"user-container\"> ${this.renderUserProfile(\"horizontal\", \"regular\")} </div> <div class=${classMap({ \"login-container\": true, \"signin-only\": !this.showRecentUsers })} > ${this.showPassword ? this.renderTextInput( msg(\"Password\"), HTMLInputTypeAttribute.Password, this.password, this.handlePasswordInput.bind(this), this.passwordError ) : nothing} <obc-button variant=${ButtonVariant.raised} fullWidth @click=${this.handleSignInClick} > ${msg(\"Sign in\")} </obc-button> ${this.showUseAnotherAccount ? html` <obc-button variant=${ButtonVariant.normal} fullWidth @click=${this.handleUseAnotherAccountClick} > ${msg(\"Use another account\")} </obc-button> ` : nothing} </div> ${this.showRecentUsers ? html` <div class=\"divider\" aria-hidden=\"true\"></div> <div class=\"recent-container recent\"> <div class=\"title-container\"> <div class=\"subtitle\">${msg(\"Recent\")}</div> </div> <div class=\"actions-container\"> ${this.renderUserButtons(3, false)} </div> </div> ` : nothing} `; } renderLoadingSignIn() { return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"Sign in\")}</h3> </div> <div class=\"user-primary loading\"> ${this.renderUserProfile(\"vertical\", \"large\")} <obc-progress-bar class=\"progress\" type=${ProgressBarType.linear} mode=${ProgressBarMode.indeterminate} .showValue=${false} ></obc-progress-bar> </div> `; } renderLoadingSignInSmall() { return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"Sign in\")}</h3> </div> <div class=\"user-primary loading\"> ${this.renderUserProfile(\"horizontal\", \"regular\")} <obc-progress-bar class=\"progress\" type=${ProgressBarType.linear} mode=${ProgressBarMode.indeterminate} .showValue=${false} ></obc-progress-bar> </div> `; } renderSignedIn() { return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"User\")}</h3> </div> <div class=\"user-primary signed-in\"> ${this.renderUserProfile(\"vertical\", \"large\")} </div> <div class=\"divider\" aria-hidden=\"true\"></div> ${this.signedInActions.length ? html` <div class=\"nav-container\"> ${this.signedInActions.map((action) => { const normalizedId = this.normalizeActionId(action.id); return html` <obc-navigation-item .label=${action.label} hasIcon @click=${() => this.handleSignedInActionClick(action)} > <span slot=\"icon\"> <slot name=\"signed-in-action-icon-${normalizedId}\"> ${this.getSignedInActionIcon(normalizedId)} </slot> </span> </obc-navigation-item> `; })} </div> ` : nothing} <div class=\"button-container\"> <obc-button variant=${ButtonVariant.normal} fullWidth @click=${this.handleSignOutClick} > ${msg(\"Sign out\")} </obc-button> </div> `; } renderSignedInSmall() { const primaryAction = this.signedInActions.find( (action) => action.id === this.primaryActionId ); return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"User\")}</h3> </div> <div class=\"user-container\"> ${this.renderUserProfile(\"horizontal\", \"regular\")} </div> <div class=\"button-container\"> ${primaryAction ? html` <obc-button variant=${ButtonVariant.normal} fullWidth @click=${() => this.handleSignedInActionClick(primaryAction)} > ${primaryAction.label} </obc-button> ` : nothing} <obc-button variant=${ButtonVariant.normal} fullWidth @click=${this.handleSignOutClick} > ${msg(\"Sign out\")} </obc-button> </div> `; } render() { let content = nothing; if (this.type === \"sign-in\") { content = this.size === \"small\" ? this.renderSignInSmall() : this.renderSignIn(); } if (this.type === \"user-sign-in\") { content = this.size === \"small\" ? this.renderUserSignInSmall() : this.renderUserSignIn(); } if (this.type === \"loading-sign-in\") { content = this.size === \"small\" ? this.renderLoadingSignInSmall() : this.renderLoadingSignIn(); } if (this.type === \"signed-in\") { content = this.size === \"small\" ? this.renderSignedInSmall() : this.renderSignedIn(); } return html` <div class=${classMap({ card: true, [`size-${this.size}`]: true, [`type-${this.type}`]: true })} > ${content} </div> `; } }"
8605
8605
  }
8606
8606
  ],
8607
8607
  "exports": [
@@ -72180,7 +72180,7 @@
72180
72180
  "declarations": [
72181
72181
  {
72182
72182
  "kind": "class",
72183
- "description": "`obc-user-button` – A compact, circular button for representing a user via icon or initials.\n\nDisplays either a user icon or user initials inside a circular button, with optional label text. Commonly used for user profile access, account switching, or avatar actions in toolbars and navigation. The button supports multiple visual styles and can be rendered as a static (non-interactive) element.\n\nAppears as a button by default, but switches to a non-interactive div when the `static` property is set.\n\n## Features\n- **Variants:**\n - `icon`: Shows a user icon (default, fallback if initials are invalid or missing).\n - `initials`: Shows up to two uppercase initials (falls back to icon if input is empty or longer than two characters).\n- **Style Types:**\n - `flat`: Minimal, flat appearance (default).\n - `normal`: Outlined with background and border.\n - `selected`: Highlighted to indicate selection or active state.\n- **Static Mode:**\n - Set `static` to render as a non-interactive element for use in read-only or decorative contexts.\n- **Disabled State:**\n - Set `disabled` to visually and functionally disable the button.\n- **Custom Icon Slot:**\n - Provide a custom icon via the `icon` slot when using the `icon` variant.\n- **Label Support:**\n - Optional `label` property displays text next to the button (not shown in static mode).\n\n## Usage Guidelines\nUse `obc-user-button` to represent a user in navigation bars, toolbars, or menus where a compact, recognizable user indicator is needed. Ideal for profile menus, account switching, or user-related quick actions.\n- Use the `icon` variant for generic user representation, or when no initials are available.\n- Use the `initials` variant to personalize the button with user initials (max two characters).\n- Use `styleType=\"selected\"` to indicate the current user or active selection.\n- Use `static` for non-interactive displays, such as in lists or summaries.\n- Avoid using for critical actions or as a replacement for full user profile cards.\n\n**TODO(designer):** Confirm if there are recommended scenarios for when to use `flat`, `normal`, or `selected` style types, and if there are accessibility guidelines for initials fallback.\n\n## Slots\n\n| Slot Name | Renders When... | Purpose |\n|-----------|-----------------|---------|\n| `icon` | `variant=\"icon\"` | Custom icon to display instead of the default user icon. |\n\n## Best Practices & Constraints\n- Initials longer than two characters are truncated and a warning is logged.\n- If `initials` is empty or invalid, the button falls back to the user icon.\n- The `label` is only visible when the button is interactive (not static).\n- For accessibility, the button uses `aria-label` based on initials or a default.\n- Only use the `static` property for non-interactive contexts; otherwise, the button is clickable.\n\n## Example:\n```html\n<obc-user-button variant=\"initials\" initials=\"JD\" styleType=\"normal\" label=\"John Doe\"></obc-user-button>\n<obc-user-button variant=\"icon\" styleType=\"flat\">\n <obi-placeholder slot=\"icon\"></obi-placeholder>\n</obc-user-button>\n```",
72183
+ "description": "`obc-user-button` – A compact, circular button for representing a user via icon or initials.\n\nDisplays either a user icon or user initials inside a circular button, with optional label text. Commonly used for user profile access, account switching, or avatar actions in toolbars and navigation. The button supports multiple visual styles and can be rendered as a static (non-interactive) element.\n\nAppears as a button by default, but switches to a non-interactive div when the `static` property is set.\n\n## Features\n- **Variants:**\n - `icon`: Shows a user icon (default, fallback if initials are invalid or missing).\n - `initials`: Shows up to two uppercase initials (falls back to icon if input is empty or longer than two characters).\n- **Style Types:**\n - `flat`: Minimal, flat appearance (default).\n - `normal`: Outlined with background and border.\n - `selected`: Highlighted to indicate selection or active state.\n- **Static Mode:**\n - Set `static` to render as a non-interactive element for use in read-only or decorative contexts.\n- **Disabled State:**\n - Set `disabled` to visually and functionally disable the button.\n- **Custom Icon Slot:**\n - Provide a custom icon via the `icon` slot when using the `icon` variant.\n- **Label Support:**\n - Optional `label` property displays text next to the button (not shown in static mode).\n - Optional `sublabel` adds a second, lighter line under the label, for a\n secondary detail such as the user's role.\n\n## Usage Guidelines\nUse `obc-user-button` to represent a user in navigation bars, toolbars, or menus where a compact, recognizable user indicator is needed. Ideal for profile menus, account switching, or user-related quick actions.\n- Use the `icon` variant for generic user representation, or when no initials are available.\n- Use the `initials` variant to personalize the button with user initials (max two characters).\n- Use `styleType=\"selected\"` to indicate the current user or active selection.\n- Use `static` for non-interactive displays, such as in lists or summaries.\n- Avoid using for critical actions or as a replacement for full user profile cards.\n\n**TODO(designer):** Confirm if there are recommended scenarios for when to use `flat`, `normal`, or `selected` style types, and if there are accessibility guidelines for initials fallback.\n\n## Slots\n\n| Slot Name | Renders When... | Purpose |\n|-----------|-----------------|---------|\n| `icon` | `variant=\"icon\"` | Custom icon to display instead of the default user icon. |\n\n## Best Practices & Constraints\n- Initials longer than two characters are truncated and a warning is logged.\n- If `initials` is empty or invalid, the button falls back to the user icon.\n- The `label` is only visible when the button is interactive (not static).\n- For accessibility, the button is named after its visible text — `label` and\n `sublabel` falling back to the initials when it shows no text.\n- Only use the `static` property for non-interactive contexts; otherwise, the button is clickable.\n\n## Example:\n```html\n<obc-user-button variant=\"initials\" initials=\"JD\" styleType=\"normal\" label=\"John Doe\"></obc-user-button>\n<obc-user-button variant=\"icon\" styleType=\"flat\">\n <obi-placeholder slot=\"icon\"></obi-placeholder>\n</obc-user-button>\n```",
72184
72184
  "name": "ObcUserButton",
72185
72185
  "slots": [
72186
72186
  {
@@ -72247,6 +72247,14 @@
72247
72247
  },
72248
72248
  "description": "Optional label text to display next to the button (not shown in static mode)."
72249
72249
  },
72250
+ {
72251
+ "kind": "field",
72252
+ "name": "sublabel",
72253
+ "type": {
72254
+ "text": "string | undefined"
72255
+ },
72256
+ "description": "Optional second line under the label, for a secondary detail such as a role (not shown in static mode)."
72257
+ },
72250
72258
  {
72251
72259
  "kind": "field",
72252
72260
  "name": "formattedInitials",
@@ -72293,7 +72301,7 @@
72293
72301
  "declarations": [
72294
72302
  {
72295
72303
  "kind": "class",
72296
- "description": "`<obc-user-menu>` – A user menu component with sign-in and signed-in layouts.\n\nProvides multiple layouts for authentication and account access states, including\nsign-in forms, user-specific sign-in, loading states, and signed-in navigation.\n\n### Features\n- **Multiple States:** Supports sign-in, user sign-in, loading, and signed-in layouts.\n- **Size Options:** Regular and small sizes for compact layouts.\n- **Recent Users:** Optional \"Recently signed in\" section for quick access.\n- **Navigation Actions:** Signed-in state lists the actions it is given.\n\n### Variants\n- `type`: `sign-in`, `user-sign-in`, `loading-sign-in`, `signed-in`\n- `size`: `regular`, `small`\n\n### Usage Guidelines\nUse `obc-user-menu` in authentication or account panels where quick access to\nsign-in, profile, or account actions is needed. The `user-sign-in` type is\nbest for fast re-auth flows; `loading-sign-in` is for pending auth states.\n\n### Properties and Configuration\n- `type` (`ObcUserMenuType`): Controls the layout state. Defaults to `sign-in`.\n- `size` (`ObcUserMenuSize`): Controls the overall size. Defaults to `regular`.\n- `hasRecentlySignedIn` (`boolean`): Toggles the recent users section.\n Defaults to `false`.\n- `showUsername` (`boolean`): Toggles the username field. Defaults to `true`.\n- `showPassword` (`boolean`): Toggles the password field. Defaults to `true`.\n- `username` (`string`): Current username value for sign-in layouts.\n- `password` (`string`): Current password value for sign-in layouts.\n- `usernameError` (`string`): Error message for the username field.\n- `passwordError` (`string`): Error message for the password field.\n- `userInitials` (`string`): Initials for the primary user profile.\n- `userLabel` (`string`): Label for the primary user profile.\n- `recentUsers` (`ObcUserMenuUser[]`): List of recent users shown in the\n \"Recently signed in\" section. Empty renders no section.\n- `signedInActions` (`ObcUserMenuSignedInAction[]`): Actions shown in the\n signed-in navigation list. Empty renders no actions.\n- `primaryActionId` (`string`): Id of the action promoted to a button in the\n small signed-in layout.\n\n### Events\n- `sign-in-click` – Fired when a sign-in button is clicked.\n- `sign-out-click` – Fired when the sign-out button is clicked.\n- `signed-in-action-click` – Fired when a signed-in action is clicked.\n- `recent-user-click` – Fired when a recent user button is clicked.\n\n### Slots\n- `signed-in-action-icon-{id}`: Optional icon for a signed-in action. The\n `{id}` is the normalized action id.\n\n### Example\n```html\n<obc-user-menu\n type=\"user-sign-in\"\n size=\"small\"\n hasRecentlySignedIn=\"false\"\n userInitials=\"JD\"\n userLabel=\"John Doe\"\n></obc-user-menu>\n```",
72304
+ "description": "`<obc-user-menu>` – A user menu component with sign-in and signed-in layouts.\n\nProvides multiple layouts for authentication and account access states, including\nsign-in forms, user-specific sign-in, loading states, and signed-in navigation.\n\n### Features\n- **Multiple States:** Supports sign-in, user sign-in, loading, and signed-in layouts.\n- **Size Options:** Regular and small sizes for compact layouts.\n- **Recent Users:** Optional \"Recently signed in\" section for quick access.\n- **Navigation Actions:** Signed-in state lists the actions it is given.\n\n### Variants\n- `type`: `sign-in`, `user-sign-in`, `loading-sign-in`, `signed-in`\n- `size`: `regular`, `small`\n\n### Usage Guidelines\nUse `obc-user-menu` in authentication or account panels where quick access to\nsign-in, profile, or account actions is needed. The `user-sign-in` type is\nbest for fast re-auth flows; `loading-sign-in` is for pending auth states.\n\n### Properties and Configuration\n- `type` (`ObcUserMenuType`): Controls the layout state. Defaults to `sign-in`.\n- `size` (`ObcUserMenuSize`): Controls the overall size. Defaults to `regular`.\n- `hasRecentlySignedIn` (`boolean`): Toggles the recent users section.\n Defaults to `false`.\n- `showUsername` (`boolean`): Toggles the username field. Defaults to `true`.\n- `showPassword` (`boolean`): Toggles the password field. Defaults to `true`.\n- `username` (`string`): Current username value for sign-in layouts.\n- `password` (`string`): Current password value for sign-in layouts.\n- `usernameError` (`string`): Error message for the username field.\n- `passwordError` (`string`): Error message for the password field.\n- `userInitials` (`string`): Initials for the primary user profile.\n- `userLabel` (`string`): Label for the primary user profile.\n- `userRole` (`string`): Role shown under the primary user's label. Omit it\n to show no role; only the regular size draws one.\n- `recentUsers` (`ObcUserMenuUser[]`): List of recent users shown in the\n \"Recently signed in\" section. Empty renders no section. Each user may\n carry its own `role`.\n- `showUseAnotherAccount` (`boolean`): Toggles the \"Use another account\"\n button in the `user-sign-in` layouts, both sizes. Defaults to `true`.\n- `signedInActions` (`ObcUserMenuSignedInAction[]`): Actions shown in the\n signed-in navigation list. Empty renders no actions.\n- `primaryActionId` (`string`): Id of the action promoted to a button in the\n small signed-in layout.\n\n### Events\n- `sign-in-click` – Fired when a sign-in button is clicked.\n- `sign-out-click` – Fired when the sign-out button is clicked.\n- `use-another-account-click` – Fired when the \"Use another account\" button\n is clicked. The menu does not change its own type; set it to `sign-in` in\n the handler to show the full form.\n- `signed-in-action-click` – Fired when a signed-in action is clicked.\n- `recent-user-click` – Fired when a recent user button is clicked.\n\n### Slots\n- `signed-in-action-icon-{id}`: Optional icon for a signed-in action. The\n `{id}` is the normalized action id.\n\n### Example\n```html\n<obc-user-menu\n type=\"user-sign-in\"\n size=\"small\"\n hasRecentlySignedIn=\"false\"\n userInitials=\"JD\"\n userLabel=\"John Doe\"\n></obc-user-menu>\n```",
72297
72305
  "name": "ObcUserMenu",
72298
72306
  "slots": [
72299
72307
  {
@@ -72397,6 +72405,14 @@
72397
72405
  },
72398
72406
  "description": "Label for the primary user profile."
72399
72407
  },
72408
+ {
72409
+ "kind": "field",
72410
+ "name": "userRole",
72411
+ "type": {
72412
+ "text": "string | undefined"
72413
+ },
72414
+ "description": "Role shown under the primary user's label; omit it to show no role."
72415
+ },
72400
72416
  {
72401
72417
  "kind": "field",
72402
72418
  "name": "recentUsers",
@@ -72423,6 +72439,15 @@
72423
72439
  },
72424
72440
  "description": "Id of the action promoted to a button in the small signed-in layout."
72425
72441
  },
72442
+ {
72443
+ "kind": "field",
72444
+ "name": "showUseAnotherAccount",
72445
+ "type": {
72446
+ "text": "boolean"
72447
+ },
72448
+ "default": "true",
72449
+ "description": "Controls the visibility of the \"Use another account\" button."
72450
+ },
72426
72451
  {
72427
72452
  "kind": "field",
72428
72453
  "name": "showRecentUsers",
@@ -72595,6 +72620,11 @@
72595
72620
  "name": "handleSignOutClick",
72596
72621
  "privacy": "private"
72597
72622
  },
72623
+ {
72624
+ "kind": "method",
72625
+ "name": "handleUseAnotherAccountClick",
72626
+ "privacy": "private"
72627
+ },
72598
72628
  {
72599
72629
  "kind": "method",
72600
72630
  "name": "renderSignIn",
@@ -72656,9 +72686,9 @@
72656
72686
  {
72657
72687
  "name": "recent-user-click",
72658
72688
  "type": {
72659
- "text": "CustomEvent<{initials: string, label: string}>"
72689
+ "text": "ObcUserMenuRecentUserClickEvent"
72660
72690
  },
72661
- "description": "Fired when a recent user button is clicked."
72691
+ "description": "Fired when a recent user button is clicked, carrying that user's entry."
72662
72692
  },
72663
72693
  {
72664
72694
  "name": "sign-in-click",
@@ -72673,6 +72703,13 @@
72673
72703
  "text": "CustomEvent<void>"
72674
72704
  },
72675
72705
  "description": "Fired when the sign-out button is clicked."
72706
+ },
72707
+ {
72708
+ "name": "use-another-account-click",
72709
+ "type": {
72710
+ "text": "CustomEvent<void>"
72711
+ },
72712
+ "description": "Fired when the \"Use another account\" button is clicked."
72676
72713
  }
72677
72714
  ],
72678
72715
  "superclass": {
@@ -58,6 +58,39 @@ const compentStyle = css`* {
58
58
  "ss04" on;
59
59
  }
60
60
 
61
+ .wrapper.size-large .user-label {
62
+ font-family: var(--global-typography-font-family);
63
+ font-weight: var(--global-typography-ui-body-font-weight);
64
+ font-size: var(--global-typography-ui-body-font-size);
65
+ line-height: var(--global-typography-ui-body-line-height);
66
+ font-feature-settings:
67
+ "liga" off,
68
+ "clig" off,
69
+ "ss04" on;
70
+ }
71
+
72
+ .wrapper.size-large .user-sublabel {
73
+ font-family: var(--global-typography-font-family);
74
+ font-weight: var(--global-typography-ui-body-font-weight);
75
+ font-size: var(--global-typography-ui-body-font-size);
76
+ line-height: var(--global-typography-ui-body-line-height);
77
+ font-feature-settings:
78
+ "liga" off,
79
+ "clig" off,
80
+ "ss04" on;
81
+ }
82
+
83
+ .wrapper.size-large.has-sublabel .user-label {
84
+ font-family: var(--global-typography-font-family);
85
+ font-weight: var(--global-typography-ui-body-active-font-weight);
86
+ font-size: var(--global-typography-ui-body-active-font-size);
87
+ line-height: var(--global-typography-ui-body-active-line-height);
88
+ font-feature-settings:
89
+ "liga" off,
90
+ "clig" off,
91
+ "ss04" on;
92
+ }
93
+
61
94
  .wrapper.size-large.style-selected .user-initials {
62
95
  font-family: var(--global-typography-font-family);
63
96
  font-weight: var(--font-weight-bold);
@@ -70,6 +103,17 @@ const compentStyle = css`* {
70
103
  "ss04" on;
71
104
  }
72
105
 
106
+ .wrapper.size-large.style-selected .user-label {
107
+ font-family: var(--global-typography-font-family);
108
+ font-weight: var(--global-typography-ui-body-active-font-weight);
109
+ font-size: var(--global-typography-ui-body-active-font-size);
110
+ line-height: var(--global-typography-ui-body-active-line-height);
111
+ font-feature-settings:
112
+ "liga" off,
113
+ "clig" off,
114
+ "ss04" on;
115
+ }
116
+
73
117
  .wrapper.size-large.state-static {
74
118
  width: var(--ui-components-user-button-visual-size-enhanced);
75
119
  height: var(--ui-components-user-button-visual-size-enhanced);
@@ -91,7 +135,30 @@ const compentStyle = css`* {
91
135
  color: var(--element-active-color);
92
136
  }
93
137
 
94
- .wrapper:disabled .user-label {
138
+ .wrapper .user-sublabel {
139
+ font-family: var(--global-typography-font-family);
140
+ font-weight: var(--global-typography-ui-label-font-weight);
141
+ font-size: var(--global-typography-ui-label-font-size);
142
+ line-height: var(--global-typography-ui-label-line-height);
143
+ font-feature-settings:
144
+ "liga" off,
145
+ "clig" off,
146
+ "ss04" on;
147
+ color: var(--element-active-color);
148
+ }
149
+
150
+ .wrapper.has-sublabel .user-label {
151
+ font-family: var(--global-typography-font-family);
152
+ font-weight: var(--global-typography-ui-label-active-font-weight);
153
+ font-size: var(--global-typography-ui-label-active-font-size);
154
+ line-height: var(--global-typography-ui-label-active-line-height);
155
+ font-feature-settings:
156
+ "liga" off,
157
+ "clig" off,
158
+ "ss04" on;
159
+ }
160
+
161
+ .wrapper:disabled .user-label,.wrapper:disabled .user-sublabel {
95
162
  color: var(--element-disabled-color);
96
163
  }
97
164
 
@@ -1 +1 @@
1
- {"version":3,"file":"user-button.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"user-button.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -41,6 +41,8 @@ export declare enum Variant {
41
41
  * - Provide a custom icon via the `icon` slot when using the `icon` variant.
42
42
  * - **Label Support:**
43
43
  * - Optional `label` property displays text next to the button (not shown in static mode).
44
+ * - Optional `sublabel` adds a second, lighter line under the label, for a
45
+ * secondary detail such as the user's role.
44
46
  *
45
47
  * ## Usage Guidelines
46
48
  * Use `obc-user-button` to represent a user in navigation bars, toolbars, or menus where a compact, recognizable user indicator is needed. Ideal for profile menus, account switching, or user-related quick actions.
@@ -62,7 +64,8 @@ export declare enum Variant {
62
64
  * - Initials longer than two characters are truncated and a warning is logged.
63
65
  * - If `initials` is empty or invalid, the button falls back to the user icon.
64
66
  * - The `label` is only visible when the button is interactive (not static).
65
- * - For accessibility, the button uses `aria-label` based on initials or a default.
67
+ * - For accessibility, the button is named after its visible text `label` and
68
+ * `sublabel` — falling back to the initials when it shows no text.
66
69
  * - Only use the `static` property for non-interactive contexts; otherwise, the button is clickable.
67
70
  *
68
71
  * ## Example:
@@ -79,6 +82,8 @@ export declare enum Variant {
79
82
  * @availableWhen disabled static==false
80
83
  * @property label - Optional label text to display next to the button (not shown in static mode).
81
84
  * @availableWhen label static==false
85
+ * @property sublabel - Optional second line under the label, for a secondary detail such as a role (not shown in static mode).
86
+ * @availableWhen sublabel static==false
82
87
  * @slot icon - Custom icon for the user button (used only in `icon` variant; defaults to <obi-user> if not provided)
83
88
  * @stable
84
89
  */
@@ -109,6 +114,8 @@ export declare class ObcUserButton extends LitElement {
109
114
  initials: string;
110
115
  /** Optional label text to display next to the button (not shown in static mode). */
111
116
  label?: string;
117
+ /** Optional second line under the label, for a secondary detail such as a role (not shown in static mode). */
118
+ sublabel?: string;
112
119
  private get formattedInitials();
113
120
  private get shouldShowIcon();
114
121
  render(): import('lit-html').TemplateResult;
@@ -1 +1 @@
1
- {"version":3,"file":"user-button.d.ts","sourceRoot":"","sources":["../../../src/components/user-button/user-button.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAqB,MAAM,KAAK,CAAC;AAInD,OAAO,0BAA0B,CAAC;AAIlC,oBAAY,SAAS;IACnB,IAAI,SAAS;IACb,MAAM,WAAW;IACjB,QAAQ,aAAa;CACtB;AAED,oBAAY,IAAI;IACd,OAAO,YAAY;IACnB,KAAK,UAAU;CAChB;AAED;;;;GAIG;AACH,oBAAY,OAAO;IACjB,IAAI,SAAS;IACb,QAAQ,aAAa;CACtB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+DG;AACH,qBACa,aAAc,SAAQ,UAAU;IAC3C;;;;OAIG;IACuB,OAAO,EAAE,OAAO,CAAgB;IAChC,IAAI,EAAE,IAAI,CAAgB;IAEpD;;;;;OAKG;IACuB,SAAS,EAAE,SAAS,CAAkB;IAErC,MAAM,EAAE,OAAO,CAAS;IAExB,QAAQ,EAAE,OAAO,CAAS;IAErD;;;;OAIG;IACuB,QAAQ,EAAE,MAAM,CAAM;IAEtB,KAAK,CAAC,EAAE,MAAM,CAAC;IAEzC,OAAO,KAAK,iBAAiB,GAgB5B;IAED,OAAO,KAAK,cAAc,GAEzB;IAEQ,MAAM;IAsDf,OAAgB,MAAM,0BAA2B;CAClD;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,iBAAiB,EAAE,aAAa,CAAC;KAClC;CACF"}
1
+ {"version":3,"file":"user-button.d.ts","sourceRoot":"","sources":["../../../src/components/user-button/user-button.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAqB,MAAM,KAAK,CAAC;AAInD,OAAO,0BAA0B,CAAC;AAIlC,oBAAY,SAAS;IACnB,IAAI,SAAS;IACb,MAAM,WAAW;IACjB,QAAQ,aAAa;CACtB;AAED,oBAAY,IAAI;IACd,OAAO,YAAY;IACnB,KAAK,UAAU;CAChB;AAED;;;;GAIG;AACH,oBAAY,OAAO;IACjB,IAAI,SAAS;IACb,QAAQ,aAAa;CACtB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoEG;AACH,qBACa,aAAc,SAAQ,UAAU;IAC3C;;;;OAIG;IACuB,OAAO,EAAE,OAAO,CAAgB;IAChC,IAAI,EAAE,IAAI,CAAgB;IAEpD;;;;;OAKG;IACuB,SAAS,EAAE,SAAS,CAAkB;IAErC,MAAM,EAAE,OAAO,CAAS;IAExB,QAAQ,EAAE,OAAO,CAAS;IAErD;;;;OAIG;IACuB,QAAQ,EAAE,MAAM,CAAM;IAEtB,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAE5C,OAAO,KAAK,iBAAiB,GAgB5B;IAED,OAAO,KAAK,cAAc,GAEzB;IAEQ,MAAM;IAkEf,OAAgB,MAAM,0BAA2B;CAClD;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,iBAAiB,EAAE,aAAa,CAAC;KAClC;CACF"}
@@ -65,15 +65,21 @@ let ObcUserButton = class extends LitElement {
65
65
  "mode-icon": this.shouldShowIcon,
66
66
  "mode-initials": !this.shouldShowIcon,
67
67
  "state-static": this.static,
68
- [`size-${this.size}`]: true
68
+ [`size-${this.size}`]: true,
69
+ "has-sublabel": Boolean(this.sublabel) && !this.static
69
70
  };
70
71
  const tag = this.static ? literal`div` : literal`button`;
72
+ const visibleText = [this.label, this.sublabel].filter(Boolean).join(", ");
73
+ const accessibleName = !this.static && visibleText || this.initials || "User button";
71
74
  const label = this.label && !this.static ? html`<span class="user-label" part="label">${this.label}</span>` : nothing;
75
+ const sublabel = this.sublabel && !this.static ? html`<span class="user-sublabel" part="sublabel">
76
+ ${this.sublabel}
77
+ </span>` : nothing;
72
78
  return html`
73
79
  <${tag}
74
80
  class=${classMap(wrapperClasses)}
75
81
  ?disabled=${this.disabled}
76
- aria-label=${this.initials || "User button"}
82
+ aria-label=${accessibleName}
77
83
  >
78
84
  <div class="content-container" part="content-container">
79
85
  <div class="user-button-circle">
@@ -90,7 +96,7 @@ let ObcUserButton = class extends LitElement {
90
96
  </span>
91
97
  `}
92
98
  </div>
93
- ${label}
99
+ ${label} ${sublabel}
94
100
  </div>
95
101
  </${tag}>
96
102
  `;
@@ -118,6 +124,9 @@ __decorateClass([
118
124
  __decorateClass([
119
125
  property({ type: String })
120
126
  ], ObcUserButton.prototype, "label", 2);
127
+ __decorateClass([
128
+ property({ type: String })
129
+ ], ObcUserButton.prototype, "sublabel", 2);
121
130
  ObcUserButton = __decorateClass([
122
131
  customElement("obc-user-button")
123
132
  ], ObcUserButton);
@@ -1 +1 @@
1
- {"version":3,"file":"user-button.js","sources":["../../../src/components/user-button/user-button.ts"],"sourcesContent":["import {LitElement, nothing, unsafeCSS} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport {classMap} from 'lit/directives/class-map.js';\nimport compentStyle from './user-button.css?inline';\nimport '../../icons/icon-user.js';\nimport {html, literal} from 'lit/static-html.js';\nimport {customElement} from '../../decorator.js';\n\nexport enum StyleType {\n flat = 'flat',\n normal = 'normal',\n selected = 'selected',\n}\n\nexport enum Size {\n regular = 'regular',\n large = 'large',\n}\n\n/**\n * Defines the visual content of the user button.\n * - `icon`: Shows a user icon (default).\n * - `initials`: Shows up to two uppercase initials.\n */\nexport enum Variant {\n icon = 'icon',\n initials = 'initials',\n}\n\n/**\n * `obc-user-button` – A compact, circular button for representing a user via icon or initials.\n *\n * Displays either a user icon or user initials inside a circular button, with optional label text. Commonly used for user profile access, account switching, or avatar actions in toolbars and navigation. The button supports multiple visual styles and can be rendered as a static (non-interactive) element.\n *\n * Appears as a button by default, but switches to a non-interactive div when the `static` property is set.\n *\n * ## Features\n * - **Variants:**\n * - `icon`: Shows a user icon (default, fallback if initials are invalid or missing).\n * - `initials`: Shows up to two uppercase initials (falls back to icon if input is empty or longer than two characters).\n * - **Style Types:**\n * - `flat`: Minimal, flat appearance (default).\n * - `normal`: Outlined with background and border.\n * - `selected`: Highlighted to indicate selection or active state.\n * - **Static Mode:**\n * - Set `static` to render as a non-interactive element for use in read-only or decorative contexts.\n * - **Disabled State:**\n * - Set `disabled` to visually and functionally disable the button.\n * - **Custom Icon Slot:**\n * - Provide a custom icon via the `icon` slot when using the `icon` variant.\n * - **Label Support:**\n * - Optional `label` property displays text next to the button (not shown in static mode).\n *\n * ## Usage Guidelines\n * Use `obc-user-button` to represent a user in navigation bars, toolbars, or menus where a compact, recognizable user indicator is needed. Ideal for profile menus, account switching, or user-related quick actions.\n * - Use the `icon` variant for generic user representation, or when no initials are available.\n * - Use the `initials` variant to personalize the button with user initials (max two characters).\n * - Use `styleType=\"selected\"` to indicate the current user or active selection.\n * - Use `static` for non-interactive displays, such as in lists or summaries.\n * - Avoid using for critical actions or as a replacement for full user profile cards.\n *\n * **TODO(designer):** Confirm if there are recommended scenarios for when to use `flat`, `normal`, or `selected` style types, and if there are accessibility guidelines for initials fallback.\n *\n * ## Slots\n *\n * | Slot Name | Renders When... | Purpose |\n * |-----------|-----------------|---------|\n * | `icon` | `variant=\"icon\"` | Custom icon to display instead of the default user icon. |\n *\n * ## Best Practices & Constraints\n * - Initials longer than two characters are truncated and a warning is logged.\n * - If `initials` is empty or invalid, the button falls back to the user icon.\n * - The `label` is only visible when the button is interactive (not static).\n * - For accessibility, the button uses `aria-label` based on initials or a default.\n * - Only use the `static` property for non-interactive contexts; otherwise, the button is clickable.\n *\n * ## Example:\n * ```html\n * <obc-user-button variant=\"initials\" initials=\"JD\" styleType=\"normal\" label=\"John Doe\"></obc-user-button>\n * <obc-user-button variant=\"icon\" styleType=\"flat\">\n * <obi-placeholder slot=\"icon\"></obi-placeholder>\n * </obc-user-button>\n * ```\n *\n * @property static - If true, renders the button as a static (non-interactive) element using a `<div>`.\n * Use for decorative or read-only contexts where user interaction is not required.\n * @property disabled - Disables the button, preventing user interaction and applying a disabled style.\n * @availableWhen disabled static==false\n * @property label - Optional label text to display next to the button (not shown in static mode).\n * @availableWhen label static==false\n * @slot icon - Custom icon for the user button (used only in `icon` variant; defaults to <obi-user> if not provided)\n * @stable\n */\n@customElement('obc-user-button')\nexport class ObcUserButton extends LitElement {\n /**\n * Controls whether the button displays a user icon (`icon`) or user initials (`initials`).\n * - `icon`: Shows a user icon (default, or if initials are invalid).\n * - `initials`: Shows up to two uppercase initials (falls back to icon if empty or longer than two characters).\n */\n @property({type: String}) variant: Variant = Variant.icon;\n @property({type: String}) size: Size = Size.regular;\n\n /**\n * Sets the visual style of the button.\n * - `flat`: Minimal, flat appearance (default).\n * - `normal`: Outlined with background and border.\n * - `selected`: Highlighted to indicate selection or active state.\n */\n @property({type: String}) styleType: StyleType = StyleType.flat;\n\n @property({type: Boolean}) static: boolean = false;\n\n @property({type: Boolean}) disabled: boolean = false;\n\n /**\n * The initials to display when `variant=\"initials\"`.\n * - Only the first two non-whitespace characters are used and converted to uppercase.\n * - If empty or longer than two characters, falls back to the user icon.\n */\n @property({type: String}) initials: string = '';\n\n @property({type: String}) label?: string;\n\n private get formattedInitials() {\n if (!this.initials) return '';\n\n // Remove whitespace and convert to uppercase\n const clean = this.initials.replace(/\\s+/g, '').toUpperCase();\n\n // If longer than 2 characters, truncate to first 2\n const maxInitialsLength = this.size === Size.large ? 3 : 2;\n if (clean.length > maxInitialsLength) {\n console.warn(\n `Initials \"${this.initials}\" are longer than ${maxInitialsLength} characters.`\n );\n return clean.slice(0, maxInitialsLength);\n }\n\n return clean;\n }\n\n private get shouldShowIcon() {\n return this.variant === Variant.icon;\n }\n\n override render() {\n const styleType =\n this.size === Size.large && this.styleType === StyleType.flat\n ? StyleType.normal\n : this.styleType;\n const wrapperClasses = {\n wrapper: true,\n 'wrapper-static': this.static,\n [`style-${styleType}`]: true,\n 'mode-icon': this.shouldShowIcon,\n 'mode-initials': !this.shouldShowIcon,\n 'state-static': this.static,\n [`size-${this.size}`]: true,\n };\n\n // Use button element when clickable, div when static\n const tag = this.static ? literal`div` : literal`button`;\n\n const label =\n this.label && !this.static\n ? html`<span class=\"user-label\" part=\"label\">${this.label}</span>`\n : nothing;\n\n return html`\n <${tag}\n class=${classMap(wrapperClasses)}\n ?disabled=${this.disabled}\n aria-label=${this.initials || 'User button'}\n >\n <div class=\"content-container\" part=\"content-container\">\n <div class=\"user-button-circle\">\n ${\n this.shouldShowIcon\n ? html`\n <div class=\"icon-container\">\n <slot name=\"icon\">\n <!-- Fallback to default icon if no slot content -->\n <obi-user></obi-user>\n </slot>\n </div>\n `\n : html`\n <span class=\"user-initials\">\n ${this.formattedInitials}\n </span>\n `\n }\n </div>\n ${label}\n </div>\n </${tag}>\n `;\n }\n\n static override styles = unsafeCSS(compentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-user-button': ObcUserButton;\n }\n}\n"],"names":["StyleType","Size","Variant"],"mappings":";;;;;;;;;;;;;;;;;AAQO,IAAK,8BAAAA,eAAL;AACLA,aAAA,MAAA,IAAO;AACPA,aAAA,QAAA,IAAS;AACTA,aAAA,UAAA,IAAW;AAHD,SAAAA;AAAA,GAAA,aAAA,CAAA,CAAA;AAML,IAAK,yBAAAC,UAAL;AACLA,QAAA,SAAA,IAAU;AACVA,QAAA,OAAA,IAAQ;AAFE,SAAAA;AAAA,GAAA,QAAA,CAAA,CAAA;AAUL,IAAK,4BAAAC,aAAL;AACLA,WAAA,MAAA,IAAO;AACPA,WAAA,UAAA,IAAW;AAFD,SAAAA;AAAA,GAAA,WAAA,CAAA,CAAA;AAsEL,IAAM,gBAAN,cAA4B,WAAW;AAAA,EAAvC,cAAA;AAAA,UAAA,GAAA,SAAA;AAMqB,SAAA,UAAmB;AACnB,SAAA,OAAa;AAQb,SAAA,YAAuB;AAEtB,SAAA,SAAkB;AAElB,SAAA,WAAoB;AAOrB,SAAA,WAAmB;AAAA,EAAA;AAAA,EAI7C,IAAY,oBAAoB;AAC9B,QAAI,CAAC,KAAK,SAAU,QAAO;AAG3B,UAAM,QAAQ,KAAK,SAAS,QAAQ,QAAQ,EAAE,EAAE,YAAA;AAGhD,UAAM,oBAAoB,KAAK,SAAS,UAAa,IAAI;AACzD,QAAI,MAAM,SAAS,mBAAmB;AACpC,cAAQ;AAAA,QACN,aAAa,KAAK,QAAQ,qBAAqB,iBAAiB;AAAA,MAAA;AAElE,aAAO,MAAM,MAAM,GAAG,iBAAiB;AAAA,IACzC;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,IAAY,iBAAiB;AAC3B,WAAO,KAAK,YAAY;AAAA,EAC1B;AAAA,EAES,SAAS;AAChB,UAAM,YACJ,KAAK,SAAS,WAAc,KAAK,cAAc,SAC3C,WACA,KAAK;AACX,UAAM,iBAAiB;AAAA,MACrB,SAAS;AAAA,MACT,kBAAkB,KAAK;AAAA,MACvB,CAAC,SAAS,SAAS,EAAE,GAAG;AAAA,MACxB,aAAa,KAAK;AAAA,MAClB,iBAAiB,CAAC,KAAK;AAAA,MACvB,gBAAgB,KAAK;AAAA,MACrB,CAAC,QAAQ,KAAK,IAAI,EAAE,GAAG;AAAA,IAAA;AAIzB,UAAM,MAAM,KAAK,SAAS,eAAe;AAEzC,UAAM,QACJ,KAAK,SAAS,CAAC,KAAK,SAChB,6CAA6C,KAAK,KAAK,YACvD;AAEN,WAAO;AAAA,WACA,GAAG;AAAA,kBACI,SAAS,cAAc,CAAC;AAAA,sBACpB,KAAK,QAAQ;AAAA,uBACZ,KAAK,YAAY,aAAa;AAAA;AAAA;AAAA;AAAA,cAKvC,KAAK,iBACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sBAQA;AAAA;AAAA,wBAEM,KAAK,iBAAiB;AAAA;AAAA,mBAGlC;AAAA;AAAA,YAEA,KAAK;AAAA;AAAA,YAEL,GAAG;AAAA;AAAA,EAEb;AAGF;AA3Ga,cA0GK,SAAS,UAAU,YAAY;AApGrB,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GANb,cAMe,WAAA,WAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAPb,cAOe,WAAA,QAAA,CAAA;AAQA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAfb,cAee,WAAA,aAAA,CAAA;AAEC,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GAjBd,cAiBgB,WAAA,UAAA,CAAA;AAEA,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GAnBd,cAmBgB,WAAA,YAAA,CAAA;AAOD,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GA1Bb,cA0Be,WAAA,YAAA,CAAA;AAEA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GA5Bb,cA4Be,WAAA,SAAA,CAAA;AA5Bf,gBAAN,gBAAA;AAAA,EADN,cAAc,iBAAiB;AAAA,GACnB,aAAA;"}
1
+ {"version":3,"file":"user-button.js","sources":["../../../src/components/user-button/user-button.ts"],"sourcesContent":["import {LitElement, nothing, unsafeCSS} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport {classMap} from 'lit/directives/class-map.js';\nimport compentStyle from './user-button.css?inline';\nimport '../../icons/icon-user.js';\nimport {html, literal} from 'lit/static-html.js';\nimport {customElement} from '../../decorator.js';\n\nexport enum StyleType {\n flat = 'flat',\n normal = 'normal',\n selected = 'selected',\n}\n\nexport enum Size {\n regular = 'regular',\n large = 'large',\n}\n\n/**\n * Defines the visual content of the user button.\n * - `icon`: Shows a user icon (default).\n * - `initials`: Shows up to two uppercase initials.\n */\nexport enum Variant {\n icon = 'icon',\n initials = 'initials',\n}\n\n/**\n * `obc-user-button` – A compact, circular button for representing a user via icon or initials.\n *\n * Displays either a user icon or user initials inside a circular button, with optional label text. Commonly used for user profile access, account switching, or avatar actions in toolbars and navigation. The button supports multiple visual styles and can be rendered as a static (non-interactive) element.\n *\n * Appears as a button by default, but switches to a non-interactive div when the `static` property is set.\n *\n * ## Features\n * - **Variants:**\n * - `icon`: Shows a user icon (default, fallback if initials are invalid or missing).\n * - `initials`: Shows up to two uppercase initials (falls back to icon if input is empty or longer than two characters).\n * - **Style Types:**\n * - `flat`: Minimal, flat appearance (default).\n * - `normal`: Outlined with background and border.\n * - `selected`: Highlighted to indicate selection or active state.\n * - **Static Mode:**\n * - Set `static` to render as a non-interactive element for use in read-only or decorative contexts.\n * - **Disabled State:**\n * - Set `disabled` to visually and functionally disable the button.\n * - **Custom Icon Slot:**\n * - Provide a custom icon via the `icon` slot when using the `icon` variant.\n * - **Label Support:**\n * - Optional `label` property displays text next to the button (not shown in static mode).\n * - Optional `sublabel` adds a second, lighter line under the label, for a\n * secondary detail such as the user's role.\n *\n * ## Usage Guidelines\n * Use `obc-user-button` to represent a user in navigation bars, toolbars, or menus where a compact, recognizable user indicator is needed. Ideal for profile menus, account switching, or user-related quick actions.\n * - Use the `icon` variant for generic user representation, or when no initials are available.\n * - Use the `initials` variant to personalize the button with user initials (max two characters).\n * - Use `styleType=\"selected\"` to indicate the current user or active selection.\n * - Use `static` for non-interactive displays, such as in lists or summaries.\n * - Avoid using for critical actions or as a replacement for full user profile cards.\n *\n * **TODO(designer):** Confirm if there are recommended scenarios for when to use `flat`, `normal`, or `selected` style types, and if there are accessibility guidelines for initials fallback.\n *\n * ## Slots\n *\n * | Slot Name | Renders When... | Purpose |\n * |-----------|-----------------|---------|\n * | `icon` | `variant=\"icon\"` | Custom icon to display instead of the default user icon. |\n *\n * ## Best Practices & Constraints\n * - Initials longer than two characters are truncated and a warning is logged.\n * - If `initials` is empty or invalid, the button falls back to the user icon.\n * - The `label` is only visible when the button is interactive (not static).\n * - For accessibility, the button is named after its visible text — `label` and\n * `sublabel` — falling back to the initials when it shows no text.\n * - Only use the `static` property for non-interactive contexts; otherwise, the button is clickable.\n *\n * ## Example:\n * ```html\n * <obc-user-button variant=\"initials\" initials=\"JD\" styleType=\"normal\" label=\"John Doe\"></obc-user-button>\n * <obc-user-button variant=\"icon\" styleType=\"flat\">\n * <obi-placeholder slot=\"icon\"></obi-placeholder>\n * </obc-user-button>\n * ```\n *\n * @property static - If true, renders the button as a static (non-interactive) element using a `<div>`.\n * Use for decorative or read-only contexts where user interaction is not required.\n * @property disabled - Disables the button, preventing user interaction and applying a disabled style.\n * @availableWhen disabled static==false\n * @property label - Optional label text to display next to the button (not shown in static mode).\n * @availableWhen label static==false\n * @property sublabel - Optional second line under the label, for a secondary detail such as a role (not shown in static mode).\n * @availableWhen sublabel static==false\n * @slot icon - Custom icon for the user button (used only in `icon` variant; defaults to <obi-user> if not provided)\n * @stable\n */\n@customElement('obc-user-button')\nexport class ObcUserButton extends LitElement {\n /**\n * Controls whether the button displays a user icon (`icon`) or user initials (`initials`).\n * - `icon`: Shows a user icon (default, or if initials are invalid).\n * - `initials`: Shows up to two uppercase initials (falls back to icon if empty or longer than two characters).\n */\n @property({type: String}) variant: Variant = Variant.icon;\n @property({type: String}) size: Size = Size.regular;\n\n /**\n * Sets the visual style of the button.\n * - `flat`: Minimal, flat appearance (default).\n * - `normal`: Outlined with background and border.\n * - `selected`: Highlighted to indicate selection or active state.\n */\n @property({type: String}) styleType: StyleType = StyleType.flat;\n\n @property({type: Boolean}) static: boolean = false;\n\n @property({type: Boolean}) disabled: boolean = false;\n\n /**\n * The initials to display when `variant=\"initials\"`.\n * - Only the first two non-whitespace characters are used and converted to uppercase.\n * - If empty or longer than two characters, falls back to the user icon.\n */\n @property({type: String}) initials: string = '';\n\n @property({type: String}) label?: string;\n\n @property({type: String}) sublabel?: string;\n\n private get formattedInitials() {\n if (!this.initials) return '';\n\n // Remove whitespace and convert to uppercase\n const clean = this.initials.replace(/\\s+/g, '').toUpperCase();\n\n // If longer than 2 characters, truncate to first 2\n const maxInitialsLength = this.size === Size.large ? 3 : 2;\n if (clean.length > maxInitialsLength) {\n console.warn(\n `Initials \"${this.initials}\" are longer than ${maxInitialsLength} characters.`\n );\n return clean.slice(0, maxInitialsLength);\n }\n\n return clean;\n }\n\n private get shouldShowIcon() {\n return this.variant === Variant.icon;\n }\n\n override render() {\n const styleType =\n this.size === Size.large && this.styleType === StyleType.flat\n ? StyleType.normal\n : this.styleType;\n const wrapperClasses = {\n wrapper: true,\n 'wrapper-static': this.static,\n [`style-${styleType}`]: true,\n 'mode-icon': this.shouldShowIcon,\n 'mode-initials': !this.shouldShowIcon,\n 'state-static': this.static,\n [`size-${this.size}`]: true,\n 'has-sublabel': Boolean(this.sublabel) && !this.static,\n };\n\n // Use button element when clickable, div when static\n const tag = this.static ? literal`div` : literal`button`;\n\n const visibleText = [this.label, this.sublabel].filter(Boolean).join(', ');\n const accessibleName =\n (!this.static && visibleText) || this.initials || 'User button';\n\n const label =\n this.label && !this.static\n ? html`<span class=\"user-label\" part=\"label\">${this.label}</span>`\n : nothing;\n\n const sublabel =\n this.sublabel && !this.static\n ? html`<span class=\"user-sublabel\" part=\"sublabel\">\n ${this.sublabel}\n </span>`\n : nothing;\n\n return html`\n <${tag}\n class=${classMap(wrapperClasses)}\n ?disabled=${this.disabled}\n aria-label=${accessibleName}\n >\n <div class=\"content-container\" part=\"content-container\">\n <div class=\"user-button-circle\">\n ${\n this.shouldShowIcon\n ? html`\n <div class=\"icon-container\">\n <slot name=\"icon\">\n <!-- Fallback to default icon if no slot content -->\n <obi-user></obi-user>\n </slot>\n </div>\n `\n : html`\n <span class=\"user-initials\">\n ${this.formattedInitials}\n </span>\n `\n }\n </div>\n ${label} ${sublabel}\n </div>\n </${tag}>\n `;\n }\n\n static override styles = unsafeCSS(compentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-user-button': ObcUserButton;\n }\n}\n"],"names":["StyleType","Size","Variant"],"mappings":"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"}
@@ -167,6 +167,21 @@ const componentStyle = css`* {
167
167
  color: var(--element-neutral-color);
168
168
  }
169
169
 
170
+ :is(.card .user-profile) obc-user-button:not(.has-role)::part(label) {
171
+ font-weight: var(--font-weight-regular);
172
+ }
173
+
174
+ :is(.card .user-profile) obc-user-button::part(sublabel) {
175
+ font-family: var(--global-typography-font-family);
176
+ font-weight: var(--global-typography-ui-body-font-weight);
177
+ font-size: var(--global-typography-ui-body-font-size);
178
+ line-height: var(--global-typography-ui-body-line-height);
179
+ font-feature-settings:
180
+ "liga" off,
181
+ "clig" off,
182
+ "ss04" on;
183
+ }
184
+
170
185
  .card .user-primary {
171
186
  padding: 0;
172
187
  }
@@ -1 +1 @@
1
- {"version":3,"file":"user-menu.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"user-menu.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -21,7 +21,9 @@ export declare enum ObcUserMenuSize {
21
21
  export type ObcUserMenuUser = {
22
22
  initials: string;
23
23
  label: string;
24
+ role?: string;
24
25
  };
26
+ export type ObcUserMenuRecentUserClickEvent = CustomEvent<ObcUserMenuUser>;
25
27
  export type ObcUserMenuSignedInAction = {
26
28
  id: string;
27
29
  label: string;
@@ -60,8 +62,13 @@ export type ObcUserMenuSignedInAction = {
60
62
  * - `passwordError` (`string`): Error message for the password field.
61
63
  * - `userInitials` (`string`): Initials for the primary user profile.
62
64
  * - `userLabel` (`string`): Label for the primary user profile.
65
+ * - `userRole` (`string`): Role shown under the primary user's label. Omit it
66
+ * to show no role; only the regular size draws one.
63
67
  * - `recentUsers` (`ObcUserMenuUser[]`): List of recent users shown in the
64
- * "Recently signed in" section. Empty renders no section.
68
+ * "Recently signed in" section. Empty renders no section. Each user may
69
+ * carry its own `role`.
70
+ * - `showUseAnotherAccount` (`boolean`): Toggles the "Use another account"
71
+ * button in the `user-sign-in` layouts, both sizes. Defaults to `true`.
65
72
  * - `signedInActions` (`ObcUserMenuSignedInAction[]`): Actions shown in the
66
73
  * signed-in navigation list. Empty renders no actions.
67
74
  * - `primaryActionId` (`string`): Id of the action promoted to a button in the
@@ -70,6 +77,9 @@ export type ObcUserMenuSignedInAction = {
70
77
  * ### Events
71
78
  * - `sign-in-click` – Fired when a sign-in button is clicked.
72
79
  * - `sign-out-click` – Fired when the sign-out button is clicked.
80
+ * - `use-another-account-click` – Fired when the "Use another account" button
81
+ * is clicked. The menu does not change its own type; set it to `sign-in` in
82
+ * the handler to show the full form.
73
83
  * - `signed-in-action-click` – Fired when a signed-in action is clicked.
74
84
  * - `recent-user-click` – Fired when a recent user button is clicked.
75
85
  *
@@ -104,6 +114,8 @@ export type ObcUserMenuSignedInAction = {
104
114
  * @availableWhen userInitials type!=signIn
105
115
  * @property userLabel - Label for the primary user profile.
106
116
  * @availableWhen userLabel type!=signIn
117
+ * @property userRole - Role shown under the primary user's label; omit it to show no role.
118
+ * @availableWhen userRole type!=signIn && size==regular
107
119
  * @property recentUsers - Recent users for the "Recently signed in" section.
108
120
  * @property signedInActions - Actions shown in the signed-in navigation list.
109
121
  * @availableWhen signedInActions type==signedIn
@@ -113,11 +125,14 @@ export type ObcUserMenuSignedInAction = {
113
125
  * @availableWhen showPassword type in [signIn, userSignIn]
114
126
  * @property primaryActionId - Id of the action promoted to a button in the small signed-in layout.
115
127
  * @availableWhen primaryActionId type==signedIn && size==small
128
+ * @property showUseAnotherAccount - Controls the visibility of the "Use another account" button.
129
+ * @availableWhen showUseAnotherAccount type==userSignIn
116
130
  * @slot signed-in-action-icon-<id> - Optional icon for a signed-in action, one per action; `<id>` is the normalized action id (shown in the `signed-in` type).
117
131
  * @fires {CustomEvent<{username?: string, password?: string}>} sign-in-click - Fired when a sign-in button is clicked.
118
132
  * @fires {CustomEvent<void>} sign-out-click - Fired when the sign-out button is clicked.
133
+ * @fires {CustomEvent<void>} use-another-account-click - Fired when the "Use another account" button is clicked.
119
134
  * @fires {CustomEvent<{id: string, label: string}>} signed-in-action-click - Fired when a signed-in action is clicked.
120
- * @fires {CustomEvent<{initials: string, label: string}>} recent-user-click - Fired when a recent user button is clicked.
135
+ * @fires {ObcUserMenuRecentUserClickEvent} recent-user-click - Fired when a recent user button is clicked, carrying that user's entry.
121
136
  * @stable
122
137
  */
123
138
  export declare class ObcUserMenu extends LitElement {
@@ -143,12 +158,16 @@ export declare class ObcUserMenu extends LitElement {
143
158
  userInitials?: string;
144
159
  /** Label for the primary user profile. */
145
160
  userLabel?: string;
161
+ /** Role shown under the primary user's label; omit it to show no role. */
162
+ userRole?: string;
146
163
  /** Recent users for the "Recently signed in" section. */
147
164
  recentUsers: ObcUserMenuUser[];
148
165
  /** Actions shown in the signed-in navigation list. */
149
166
  signedInActions: ObcUserMenuSignedInAction[];
150
167
  /** Id of the action promoted to a button in the small signed-in layout. */
151
168
  primaryActionId?: string;
169
+ /** Controls the visibility of the "Use another account" button. */
170
+ showUseAnotherAccount: boolean;
152
171
  private get showRecentUsers();
153
172
  private renderTextInput;
154
173
  private renderUserButtons;
@@ -162,6 +181,7 @@ export declare class ObcUserMenu extends LitElement {
162
181
  private validateSignIn;
163
182
  private handleSignInClick;
164
183
  private handleSignOutClick;
184
+ private handleUseAnotherAccountClick;
165
185
  private renderSignIn;
166
186
  private renderSignInSmall;
167
187
  private renderUserSignIn;
@@ -1 +1 @@
1
- {"version":3,"file":"user-menu.d.ts","sourceRoot":"","sources":["../../../src/components/user-menu/user-menu.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,cAAc,EAA2B,MAAM,KAAK,CAAC;AAKzE,OAAO,yCAAyC,CAAC;AACjD,OAAO,qBAAqB,CAAC;AAC7B,OAAO,+BAA+B,CAAC;AACvC,OAAO,iCAAiC,CAAC;AACzC,OAAO,uCAAuC,CAAC;AAC/C,OAAO,qCAAqC,CAAC;AAC7C,OAAO,qCAAqC,CAAC;AAC7C,OAAO,kCAAkC,CAAC;AAC1C,OAAO,0BAA0B,CAAC;AAalC,oBAAY,eAAe;IACzB,MAAM,YAAY;IAClB,UAAU,iBAAiB;IAC3B,aAAa,oBAAoB;IACjC,QAAQ,cAAc;CACvB;AAED,oBAAY,eAAe;IACzB,OAAO,YAAY;IACnB,KAAK,UAAU;CAChB;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6FG;AACH,qBAEa,WAAY,SAAQ,UAAU;IACf,IAAI,EAAE,eAAe,CAA0B;IAE/C,IAAI,EAAE,eAAe,CAA2B;IAG1E,mBAAmB,UAAS;IAG5B,YAAY,UAAQ;IAEM,QAAQ,SAAM;IAGxC,YAAY,UAAQ;IAEM,QAAQ,SAAM;IAEd,aAAa,SAAM;IAEnB,aAAa,SAAM;IAEnB,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,SAAS,CAAC,EAAE,MAAM,CAAC;IAG7C,WAAW,EAAE,eAAe,EAAE,CAAM;IAGpC,eAAe,EAAE,yBAAyB,EAAE,CAAM;IAExB,eAAe,CAAC,EAAE,MAAM,CAAC;IAEnD,OAAO,KAAK,eAAe,GAE1B;IAED,OAAO,CAAC,eAAe;IAwBvB,OAAO,CAAC,iBAAiB;IA2BzB,OAAO,CAAC,iBAAiB;IA8BzB,OAAO,CAAC,qBAAqB;IAe7B,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,yBAAyB;IAQjC,OAAO,CAAC,qBAAqB;IAQ7B,OAAO,CAAC,mBAAmB;IAQ3B,OAAO,CAAC,mBAAmB;IAQ3B,OAAO,CAAC,cAAc;IAmBtB,OAAO,CAAC,iBAAiB;IAczB,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,YAAY;IAoDpB,OAAO,CAAC,iBAAiB;IAqDzB,OAAO,CAAC,gBAAgB;IAgDxB,OAAO,CAAC,qBAAqB;IA+C7B,OAAO,CAAC,mBAAmB;IAiB3B,OAAO,CAAC,wBAAwB;IAiBhC,OAAO,CAAC,cAAc;IA2CtB,OAAO,CAAC,mBAAmB;IAkClB,MAAM;IAwCf,OAAgB,MAAM,0BAA6B;CACpD;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,eAAe,EAAE,WAAW,CAAC;KAC9B;CACF"}
1
+ {"version":3,"file":"user-menu.d.ts","sourceRoot":"","sources":["../../../src/components/user-menu/user-menu.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,cAAc,EAA2B,MAAM,KAAK,CAAC;AAKzE,OAAO,yCAAyC,CAAC;AACjD,OAAO,qBAAqB,CAAC;AAC7B,OAAO,+BAA+B,CAAC;AACvC,OAAO,iCAAiC,CAAC;AACzC,OAAO,uCAAuC,CAAC;AAC/C,OAAO,qCAAqC,CAAC;AAC7C,OAAO,qCAAqC,CAAC;AAC7C,OAAO,kCAAkC,CAAC;AAC1C,OAAO,0BAA0B,CAAC;AAalC,oBAAY,eAAe;IACzB,MAAM,YAAY;IAClB,UAAU,iBAAiB;IAC3B,aAAa,oBAAoB;IACjC,QAAQ,cAAc;CACvB;AAED,oBAAY,eAAe;IACzB,OAAO,YAAY;IACnB,KAAK,UAAU;CAChB;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,+BAA+B,GAAG,WAAW,CAAC,eAAe,CAAC,CAAC;AAE3E,MAAM,MAAM,yBAAyB,GAAG;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0GG;AACH,qBAEa,WAAY,SAAQ,UAAU;IACf,IAAI,EAAE,eAAe,CAA0B;IAE/C,IAAI,EAAE,eAAe,CAA2B;IAG1E,mBAAmB,UAAS;IAG5B,YAAY,UAAQ;IAEM,QAAQ,SAAM;IAGxC,YAAY,UAAQ;IAEM,QAAQ,SAAM;IAEd,aAAa,SAAM;IAEnB,aAAa,SAAM;IAEnB,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAG5C,WAAW,EAAE,eAAe,EAAE,CAAM;IAGpC,eAAe,EAAE,yBAAyB,EAAE,CAAM;IAExB,eAAe,CAAC,EAAE,MAAM,CAAC;IAGnD,qBAAqB,UAAQ;IAE7B,OAAO,KAAK,eAAe,GAE1B;IAED,OAAO,CAAC,eAAe;IAwBvB,OAAO,CAAC,iBAAiB;IA4BzB,OAAO,CAAC,iBAAiB;IAiCzB,OAAO,CAAC,qBAAqB;IAe7B,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,yBAAyB;IAQjC,OAAO,CAAC,qBAAqB;IAQ7B,OAAO,CAAC,mBAAmB;IAQ3B,OAAO,CAAC,mBAAmB;IAQ3B,OAAO,CAAC,cAAc;IAmBtB,OAAO,CAAC,iBAAiB;IAczB,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,4BAA4B;IAIpC,OAAO,CAAC,YAAY;IAoDpB,OAAO,CAAC,iBAAiB;IAqDzB,OAAO,CAAC,gBAAgB;IA2DxB,OAAO,CAAC,qBAAqB;IA0D7B,OAAO,CAAC,mBAAmB;IAiB3B,OAAO,CAAC,wBAAwB;IAiBhC,OAAO,CAAC,cAAc;IA2CtB,OAAO,CAAC,mBAAmB;IAkClB,MAAM;IAwCf,OAAgB,MAAM,0BAA6B;CACpD;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,eAAe,EAAE,WAAW,CAAC;KAC9B;CACF"}