web: remove native fieldset borders from action groups (#21334)

* web: remove native fieldset borders from action groups

Refs:\n- https://authentiksecurity.slack.com/archives/C08C0SCU2JV/p1775085687040019\n- https://authentiksecurity.slack.com/archives/C08C0SCU2JV/p1774988472501059

* Use consistent naming.

* Fix up styles, selector specifics, compatibility mode.

* Fix field autocapitalization, keyboard behavior.

* Fix default height.

* Fix for mid-size tablet viewports.

- Helped with debugging on mobile.

* Fix linter warning.

---------

Co-authored-by: Teffen Ellis <592134+GirlBossRush@users.noreply.github.com>
This commit is contained in:
Dominic R
2026-05-05 00:17:23 -04:00
committed by GitHub
parent 9f17d6df96
commit c75eed630a
46 changed files with 289 additions and 171 deletions
-4
View File
@@ -52,10 +52,6 @@ export class AboutModal extends WithLicenseSummary(WithBrandConfig(AKModal)) {
...AKModal.styles,
PFAbout,
css`
:host {
height: 100%;
}
.pf-c-about-modal-box {
--pf-c-about-modal-box--BackgroundColor: var(--ak-c-dialog--BackgroundColor);
width: unset;
+1 -1
View File
@@ -135,7 +135,7 @@ export class AdminInterface extends WithCapabilitiesConfig(
WebsocketClient.connect();
this.#sidebarMatcher = window.matchMedia("(width >= 1200px)");
this.#sidebarMatcher = window.matchMedia("(width > 1210px)");
this.sidebarOpen = this.#sidebarMatcher.matches;
}
@@ -381,7 +381,7 @@ export class ApplicationWizardSubmitStep extends CustomEmitterElement(Applicatio
return html`<h2 class="pf-c-wizard__main-title">
${msg("Review the Application and Provider")}
</h2>
<fieldset>
<fieldset class="ak-c-fieldset" name="application-details">
<legend>${msg("Application Details")}</legend>
<dl class="pf-c-description-list">
<div class="pf-c-description-list__group">
@@ -419,7 +419,7 @@ export class ApplicationWizardSubmitStep extends CustomEmitterElement(Applicatio
${
renderer
? html`<fieldset>
? html`<fieldset class="ak-c-fieldset" name="provider-details">
<legend>${msg("Provider Details")}</legend>
${renderer(provider)}
</fieldset>`
@@ -86,7 +86,7 @@ export class ConfigModal extends ModalButton {
></ak-codemirror>
</ak-expand>
</div>
<fieldset class="pf-c-modal-box__footer">
<fieldset class="ak-c-fieldset pf-c-modal-box__footer">
<legend class="sr-only">${msg("Form actions")}</legend>
<button
class="pf-c-button pf-m-plain"
@@ -65,7 +65,7 @@ export class DeviceAddHowTo extends ModalButton {
})}
</ak-tabs>`}
</div>
<fieldset class="pf-c-modal-box__footer">
<fieldset class="ak-c-fieldset pf-c-modal-box__footer">
<legend class="sr-only">${msg("Form actions")}</legend>
<button
class="pf-c-button pf-m-primary"
@@ -159,7 +159,7 @@ export class UserBulkRevokeSessionsForm extends ModalButton {
>
</ak-user-bulk-revoke-sessions-table>
</section>
<fieldset class="pf-c-modal-box__footer">
<fieldset class="ak-c-fieldset pf-c-modal-box__footer">
<legend class="sr-only">${msg("Form actions")}</legend>
<ak-spinner-button
.callAction=${async () => {
+3 -3
View File
@@ -48,7 +48,7 @@
width: 100%;
}
@media (width < 1200px) {
@media (width <= 1210px) {
column-gap: calc(var(--pf-global--spacer--md) / 2);
}
}
@@ -137,7 +137,7 @@
display: none;
}
@media (width < 1200px) {
@media (width <= 1210px) {
display: none;
}
}
@@ -164,7 +164,7 @@
grid-area: toggle;
}
@media (width >= 1200px) {
@media (width > 1210px) {
slot[name="toggle"] {
display: none;
}
@@ -22,11 +22,12 @@ function resolvePath(...args: string[]): string {
* - Intercepts local links and scrolls to the target element.
*/
export const MDXAnchor = ({
href,
href: initialHref,
children,
...props
}: React.AnchorHTMLAttributes<HTMLAnchorElement>) => {
const { publicDirectory } = useMDXModule();
let href = initialHref;
if (href?.startsWith(".") && publicDirectory) {
const nextPathname = resolvePath(publicDirectory, href);
@@ -12,7 +12,7 @@
);
--ak-c-command-palette__group--Color: var(--pf-global--palette--purple-100);
--ak-fieldset--BorderColor: transparent;
--ak-c-fieldset--BorderColor: transparent;
--ak-c-command-palette__item--BackgroundColor: transparent;
--ak-c-command-palette__item--Color: var(--pf-global--palette--purple-50);
@@ -37,7 +37,7 @@
transform: translate3d(0, 0, 0); /* Fixes rendering artifacts. */
@media (prefers-contrast: more) {
--ak-fieldset--BorderColor: var(--pf-global--palette--purple-500);
--ak-c-fieldset--BorderColor: var(--pf-global--palette--purple-500);
}
}
@@ -109,7 +109,7 @@
transition-duration: 0.2s;
legend {
--ak-fieldset__legend--PaddingInlineBase: var(--pf-global--spacer--md);
--ak-c-fieldset__legend--PaddingInlineBase: var(--pf-global--spacer--md);
cursor: pointer;
color: var(--ak-c-command-palette__group--Color);
@@ -524,7 +524,7 @@ export class AKCommandPaletteModal extends AKModal {
Object.entries(grouped),
(_group, groupIdx) => `group-${groupIdx}`,
([groupLabel, commands], groupIdx) => html`
<fieldset part="results-group">
<fieldset class="ak-c-fieldset" part="results-group">
<legend
class="${!groupLabel ? "sr-only more-contrast-only" : ""}"
data-label=${ifPresent(groupLabel)}
+2 -2
View File
@@ -115,8 +115,8 @@
/* #region Footer */
fieldset.ak-c-dialog__footer {
--ak-fieldset__legend--PaddingInlineBase: var(--pf-global--spacer--md);
padding-block: calc(var(--ak-fieldset__legend--PaddingInlineBase) / 2);
--ak-c-fieldset__legend--PaddingInlineBase: var(--pf-global--spacer--md);
padding-block: calc(var(--ak-c-fieldset__legend--PaddingInlineBase) / 2);
border-inline: none;
border-block-end: none;
+1 -1
View File
@@ -77,7 +77,7 @@ export class ConfirmationForm extends ModalButton {
<slot class="pf-c-content" name="body"></slot>
</form>
</section>
<fieldset class="pf-c-modal-box__footer">
<fieldset class="ak-c-fieldset pf-c-modal-box__footer">
<legend class="sr-only">${msg("Form actions")}</legend>
<ak-spinner-button
.callAction=${async () => {
+1 -1
View File
@@ -119,7 +119,7 @@ export class DeleteBulkForm<T> extends ModalButton {
>
</ak-used-by-table>
</section>
<fieldset class="pf-c-modal-box__footer">
<fieldset class="ak-c-fieldset pf-c-modal-box__footer">
<legend class="sr-only">${msg("Form actions")}</legend>
<ak-spinner-button
.callAction=${async () => {
+1 -1
View File
@@ -218,7 +218,7 @@ export class ModalForm extends ModalButton {
}
protected renderActions(): SlottedTemplateResult {
return html`<fieldset class="pf-c-modal-box__footer">
return html`<fieldset class="ak-c-fieldset pf-c-modal-box__footer">
<legend class="sr-only">${msg("Form actions")}</legend>
<button
type="button"
+4 -4
View File
@@ -126,7 +126,7 @@ export class FlowInspector extends AKElement {
protected renderNextStage({ currentPlan, isCompleted }: FlowInspection): TemplateResult {
return html`<div class="pf-c-card">
<fieldset>
<fieldset class="ak-c-fieldset">
<legend class="pf-c-card__title">${msg("Next stage")}</legend>
<div class="pf-c-card__body">
<dl class="pf-c-description-list">
@@ -184,7 +184,7 @@ ${stringify(this.getStage(currentPlan?.nextPlannedStage?.stageObj))}</pre
currentPlan,
}: FlowInspection): TemplateResult {
return html`<div class="pf-c-card">
<fieldset>
<fieldset class="ak-c-fieldset">
<legend class="pf-c-card__title">${msg("Plan history")}</legend>
<div class="pf-c-card__body">
<ol class="pf-c-progress-stepper pf-m-vertical">
@@ -248,7 +248,7 @@ ${stringify(this.getStage(currentPlan?.nextPlannedStage?.stageObj))}</pre
protected renderCurrentPlan({ currentPlan }: FlowInspection): TemplateResult {
return html`<div class="pf-c-card">
<fieldset>
<fieldset class="ak-c-fieldset">
<legend class="pf-c-card__title">${msg("Current plan context")}</legend>
<pre class="pf-c-card__body"><code>${stringify(
currentPlan?.planContext,
@@ -259,7 +259,7 @@ ${stringify(this.getStage(currentPlan?.nextPlannedStage?.stageObj))}</pre
protected renderSession({ currentPlan }: FlowInspection): TemplateResult {
return html`<div class="pf-c-card">
<fieldset>
<fieldset class="ak-c-fieldset">
<legend class="pf-c-card__title">${msg("Session ID")}</legend>
<div class="pf-c-card__body">
<code class="break"> ${currentPlan?.sessionId} </code>
+1 -1
View File
@@ -118,7 +118,7 @@ export class RedirectStage extends BaseStage<RedirectChallenge, FlowChallengeRes
<p>${msg("You're about to be redirected to the following URL.")}</p>
<code>${this.getURL()}</code>
</div>
<fieldset class="pf-c-form__group pf-m-action">
<fieldset class="ak-c-fieldset pf-c-form__group pf-m-action">
<legend class="sr-only">${msg("Form actions")}</legend>
<a
type="submit"
@@ -38,7 +38,7 @@ export class AccessDeniedStage extends BaseStage<
: nothing}
</ak-empty-state>
${this.challenge?.flowInfo?.cancelUrl
? html`<fieldset class="pf-c-form__group pf-m-action">
? html`<fieldset class="ak-c-fieldset pf-c-form__group pf-m-action">
<legend class="sr-only">${msg("Form actions")}</legend>
<a
class="pf-c-button pf-m-primary pf-m-block"
@@ -87,7 +87,7 @@ export class AuthenticatorDuoStage extends BaseStage<
</p>
<a href=${this.challenge.activationCode}>${msg("Duo activation")}</a>
<fieldset class="pf-c-form__group pf-m-action">
<fieldset class="ak-c-fieldset pf-c-form__group pf-m-action">
<legend class="sr-only">${msg("Form actions")}</legend>
<button
type="button"
@@ -64,7 +64,7 @@ export class AuthenticatorEmailStage extends BaseStage<
${AKFormErrors({ errors: this.challenge?.responseErrors?.email })}
</div>
${this.renderNonFieldErrors()}
<fieldset class="pf-c-form__group pf-m-action">
<fieldset class="ak-c-fieldset pf-c-form__group pf-m-action">
<legend class="sr-only">${msg("Form actions")}</legend>
<button
name="continue"
@@ -120,7 +120,7 @@ export class AuthenticatorEmailStage extends BaseStage<
${AKFormErrors({ errors: this.challenge.responseErrors?.code })}
</div>
${this.renderNonFieldErrors()}
<fieldset class="pf-c-form__group pf-m-action">
<fieldset class="ak-c-fieldset pf-c-form__group pf-m-action">
<legend class="sr-only">${msg("Form actions")}</legend>
<button
name="continue"
@@ -67,7 +67,7 @@ export class AuthenticatorSMSStage extends BaseStage<
${AKFormErrors({ errors: this.challenge.responseErrors?.phone_number })}
</div>
${this.renderNonFieldErrors()}
<fieldset class="pf-c-form__group pf-m-action">
<fieldset class="ak-c-fieldset pf-c-form__group pf-m-action">
<legend class="sr-only">${msg("Form actions")}</legend>
<button
name="continue"
@@ -106,7 +106,7 @@ export class AuthenticatorSMSStage extends BaseStage<
${AKFormErrors({ errors: this.challenge.responseErrors?.code })}
</div>
${this.renderNonFieldErrors()}
<fieldset class="pf-c-form__group pf-m-action">
<fieldset class="ak-c-fieldset pf-c-form__group pf-m-action">
<legend class="sr-only">${msg("Form actions")}</legend>
<button
name="continue"
@@ -66,7 +66,7 @@ export class AuthenticatorStaticStage extends BaseStage<
</ul>
<p>${msg("Make sure to keep these tokens in a safe place.")}</p>
<fieldset class="pf-c-form__group pf-m-action">
<fieldset class="ak-c-fieldset pf-c-form__group pf-m-action">
<legend class="sr-only">${msg("Form actions")}</legend>
<button
name="continue"
@@ -175,7 +175,7 @@ export class AuthenticatorTOTPStage extends BaseStage<
${AKFormErrors({ errors: this.challenge.responseErrors?.code })}
</div>
<fieldset class="pf-c-form__group pf-m-action">
<fieldset class="ak-c-fieldset pf-c-form__group pf-m-action">
<legend class="sr-only">${msg("Form actions")}</legend>
<button
name="continue"
@@ -1,3 +1,13 @@
.ak-c-fieldset.ak-c-fieldset.pf-c-form__group.pf-m-action[name="device-challenges"] {
--ak-c-fieldset--BorderWidth: thin;
--ak-c-fieldset__legend--MarginInlineBase: var(--pf-global--spacer--sm);
--ak-c-fieldset__legend--PaddingInlineBase: var(--pf-global--spacer--sm);
--ak-c-fieldset--RowGap: 0;
--ak-c-fieldset--ColumnGap: var(--pf-global--spacer--sm);
}
.authenticator-button,
ak-stage-authenticator-validate.style-scope .authenticator-button {
align-items: center;
@@ -5,6 +15,7 @@ ak-stage-authenticator-validate.style-scope .authenticator-button {
display: grid;
grid-template-columns: minmax(auto, 2rem) minmax(33%, max-content);
gap: var(--pf-global--spacer--lg);
padding-block: calc(var(--pf-global--spacer--form-element) * 2);
&:hover {
background-color: var(--pf-global--BackgroundColor--200);
@@ -267,7 +267,10 @@ export class AuthenticatorValidateStage
},
);
return html`<fieldset class="pf-c-form__group pf-m-action" name="device-challenges">
return html`<fieldset
class="ak-c-fieldset pf-c-form__group pf-m-action"
name="device-challenges"
>
<legend class="pf-c-title">${msg("Select an authentication method")}</legend>
${deviceChallengeButtons}
</fieldset>`;
@@ -300,7 +303,7 @@ export class AuthenticatorValidateStage
},
);
return html`<fieldset class="pf-c-form__group pf-m-action" name="stages">
return html`<fieldset class="ak-c-fieldset pf-c-form__group pf-m-action" name="stages">
<legend class="sr-only">${msg("Select a configuration stage")}</legend>
${stageButtons}
</fieldset>`;
@@ -30,7 +30,7 @@ export class AuthenticatorValidateStageWebCode extends BaseDeviceStage<
return html`<form class="pf-c-form" @submit=${this.submitForm}>
${this.renderUserInfo()}
<fieldset class="pf-c-form__group">
<fieldset class="ak-c-fieldset pf-c-form__group">
<legend class="sr-only">${msg("Authentication code")}</legend>
${AKLabel(
{
@@ -62,7 +62,7 @@ export class AuthenticatorValidateStageWebCode extends BaseDeviceStage<
${AKFormErrors({ errors: this.challenge?.responseErrors?.code })}
</fieldset>
<fieldset class="pf-c-form__group pf-m-action">
<fieldset class="ak-c-fieldset pf-c-form__group pf-m-action">
<legend class="sr-only">${msg("Form actions")}</legend>
<button name="continue" type="submit" class="pf-c-button pf-m-primary pf-m-block">
${msg("Continue")}
@@ -63,7 +63,7 @@ export class AuthenticatorValidateStageWebDuo extends BaseDeviceStage<
>
</ak-empty-state>
${this.showBackButton
? html`<fieldset class="pf-c-form__group pf-m-action">
? html`<fieldset class="ak-c-fieldset pf-c-form__group pf-m-action">
<legend class="sr-only">${msg("Form actions")}</legend>
${this.renderReturnToDevicePicker()}
</fieldset>`
@@ -133,7 +133,7 @@ export class AuthenticatorValidateStageWebAuthn extends BaseDeviceStage<
>
</ak-empty-state>
${!this.authenticating || this.showBackButton
? html`<fieldset class="pf-c-form__group pf-m-action">
? html`<fieldset class="ak-c-fieldset pf-c-form__group pf-m-action">
<legend class="sr-only">${msg("Form actions")}</legend>
${!this.authenticating
? html`<button
@@ -153,7 +153,7 @@ export class WebAuthnAuthenticatorRegisterStage extends BaseStage<
${this.challenge?.responseErrors
? html`<p>${this.challenge.responseErrors.response[0].string}</p>`
: nothing}
<fieldset class="pf-c-form__group pf-m-action">
<fieldset class="ak-c-fieldset pf-c-form__group pf-m-action">
<legend class="sr-only">${msg("Form actions")}</legend>
${!this.registerRunning
? html` <button
+1 -1
View File
@@ -126,7 +126,7 @@ export class ConsentStage extends BaseStage<ConsentChallenge, ConsentChallengeRe
? this.renderAdditional()
: this.renderNoPrevious()}
<fieldset class="pf-c-form__group pf-m-action">
<fieldset class="ak-c-fieldset pf-c-form__group pf-m-action">
<legend class="sr-only">${msg("Form actions")}</legend>
<button
name="continue"
+1 -1
View File
@@ -23,7 +23,7 @@ export class DummyStage extends BaseStage<DummyChallenge, DummyChallengeResponse
return html`<ak-flow-card .challenge=${this.challenge}>
<form class="pf-c-form" @submit=${this.submitForm}>
<p>${msg(str`Stage name: ${this.challenge?.name}`)}</p>
<fieldset class="pf-c-form__group pf-m-action">
<fieldset class="ak-c-fieldset pf-c-form__group pf-m-action">
<legend class="sr-only">${msg("Form actions")}</legend>
<button
name="continue"
+1 -1
View File
@@ -25,7 +25,7 @@ export class EmailStage extends BaseStage<EmailChallenge, EmailChallengeResponse
<p>${msg("Check your Inbox for a verification email.")}</p>
</div>
<fieldset class="pf-c-form__group pf-m-action">
<fieldset class="ak-c-fieldset pf-c-form__group pf-m-action">
<legend class="sr-only">${msg("Form actions")}</legend>
<button
name="continue"
@@ -296,8 +296,15 @@ export class IdentificationStage extends BaseStage<
type: string,
label: string,
initialUserIdentification: string | null,
autocomplete: string,
passwordFields?: boolean,
) {
// When webauthn is enabled, add "webauthn" to autocomplete to enable passkey autofill
let autocomplete: AutoFill = type === "email" ? "email" : "username";
if (this.#webauthn.live) {
autocomplete = `${autocomplete} webauthn`;
}
return html`<input
${ref(this.autofocusTarget.reference)}
id=${id}
@@ -307,6 +314,9 @@ export class IdentificationStage extends BaseStage<
autofocus
autocomplete=${autocomplete}
spellcheck="false"
inputmode=${type === "email" ? "email" : "text"}
autocapitalize="none"
enterkeyhint=${passwordFields ? "next" : "go"}
class="pf-c-form-control"
value=${initialUserIdentification ?? ""}
required
@@ -345,19 +355,11 @@ export class IdentificationStage extends BaseStage<
const type = fields.length === 1 && fields[0] === UserFieldsEnum.Email ? "email" : "text";
const label = OR_LIST_FORMATTERS.format(fields.map((f) => UI_FIELDS[f]));
// When webauthn is enabled, add "webauthn" to autocomplete to enable passkey autofill
const autocomplete: AutoFill = this.#webauthn.live ? "username webauthn" : "username";
console.debug(
"Rendering identification stage with fields:",
fields,
initialUserIdentification,
);
// prettier-ignore
return html`${offerRecovery ? this.renderRecoveryMessage() : nothing}
<div class="pf-c-form__group">
${AKLabel({ required: true, htmlFor: inputID }, label)}
${this.renderUidField(inputID, type, label, initialUserIdentification, autocomplete)}
${this.renderUidField(inputID, type, label, initialUserIdentification, passwordFields)}
${rememberMeController?.renderToggleInput() ?? null}
${AKFormErrors({ errors: challenge.responseErrors?.uid_field })}
</div>
@@ -433,9 +435,8 @@ export class IdentificationStage extends BaseStage<
return html`<fieldset
slot="footer"
part="source-list"
role="group"
name="login-sources"
class="pf-c-form__group"
class="ak-c-fieldset pf-c-form__group"
>
<legend class="sr-only">${msg("Login sources")}</legend>
${repeat(
@@ -467,7 +468,8 @@ export class IdentificationStage extends BaseStage<
return html`<fieldset
slot="footer-band"
part="additional-actions"
class="pf-c-login__main-footer-band"
name="additional-actions"
class="ak-c-fieldset pf-c-login__main-footer-band"
>
<legend class="sr-only">${msg("Additional actions")}</legend>
${enrollUrl
@@ -52,7 +52,7 @@ export class PasswordStage extends BaseStage<PasswordChallenge, PasswordChalleng
?allow-show-password=${!!this.challenge?.allowShowPassword}
prefill=${PasswordManagerPrefill.password ?? ""}
></ak-flow-input-password>
<fieldset class="pf-c-form__group pf-m-action">
<fieldset class="ak-c-fieldset pf-c-form__group pf-m-action">
<legend class="sr-only">${msg("Form actions")}</legend>
<button
name="continue"
@@ -67,7 +67,8 @@ export class PasswordStage extends BaseStage<PasswordChallenge, PasswordChalleng
? html`<fieldset
slot="footer-band"
part="additional-actions"
class="pf-c-login__main-footer-band"
name="additional-actions"
class="ak-c-fieldset pf-c-login__main-footer-band"
>
<legend class="sr-only">${msg("Additional actions")}</legend>
<div class="pf-c-login__main-footer-band-item">
+1 -1
View File
@@ -322,7 +322,7 @@ ${prompt.initialValue}</textarea
}
protected renderContinue(): SlottedTemplateResult {
return html`<fieldset class="pf-c-form__group pf-m-action">
return html`<fieldset class="ak-c-fieldset pf-c-form__group pf-m-action">
<legend class="sr-only">${msg("Form actions")}</legend>
<button name="continue" type="submit" class="pf-c-button pf-m-primary pf-m-block">
${msg("Continue")}
@@ -50,7 +50,7 @@ export class PasswordStage extends BaseStage<
</p>
</div>
<fieldset class="pf-c-form__group pf-m-action">
<fieldset class="ak-c-fieldset pf-c-form__group pf-m-action">
<legend class="sr-only">${msg("Form actions")}</legend>
<button name="remember-me" type="submit" class="pf-c-button pf-m-primary">
${msg("Yes")}
+1
View File
@@ -13,6 +13,7 @@
@import "./components/Content/content.css";
@import "./components/Table/table.css";
@import "./components/Form/form.css";
@import "./components/Fieldset/fieldset.css";
@import "./components/Switch/switch.css";
@import "./components/Select/select.css";
@import "./components/Modal/modal.css";
+91
View File
@@ -245,3 +245,94 @@ html[data-theme="dark"],
);
}
}
.ak-c-fieldset {
--ak-c-fieldset--BorderWidth: thin;
--ak-c-fieldset__legend--MarginInlineBase: var(--pf-global--spacer--sm);
--ak-c-fieldset__legend--PaddingInlineBase: var(--pf-global--spacer--sm);
border-color: var(--ak-c-fieldset--BorderColor, var(--pf-global--BackgroundColor--light-100));
@media (prefers-contrast: more) {
border-color: var(--ak-c-fieldset--BorderColor, var(--pf-global--BorderColor--200));
}
@media (prefers-contrast: less) {
border-color: var(--ak-c-fieldset--BorderColor, transparent);
}
border-width: var(--ak-c-fieldset--BorderWidth);
padding: var(--ak-c-fieldset__legend--PaddingInlineBase) !important;
& > legend {
line-height: 1;
padding: var(--ak-c-fieldset__legend--PaddingInlineBase) !important;
margin-inline-start: var(
--ak-c-fieldset__legend--MarginInlineStart,
var(--ak-c-fieldset__legend--MarginInlineBase)
) !important;
margin-inline-end: var(
--ak-legend-margin-inline-end,
var(--ak-c-fieldset__legend--MarginInlineBase)
) !important;
}
&:has(legend.sr-only:not(.more-contrast-only)) {
border-width: 0;
&:not(.pf-c-modal-box__footer) {
--ak-c-fieldset__legend--PaddingInlineBase: 0;
--ak-c-fieldset__legend--MarginInlineBase: 0;
}
}
&.pf-c-form__group {
border-radius: var(--pf-global--BorderRadius--sm);
}
&.pf-c-form__group {
display: flex;
flex-wrap: wrap;
&.pf-m-action {
gap: var(--pf-global--spacer--md) var(--pf-global--spacer--sm);
margin-block-start: 0;
/* Fallback for action-only fieldsets when :has() does not suppress
* the browser's native groove border. Keep the device picker
* bordered because it has a visible legend.
*/
&:not([name="device-challenges"]) {
border-width: 0;
--ak-c-fieldset__legend--PaddingInlineBase: 0;
--ak-c-fieldset__legend--MarginInlineBase: 0;
}
}
}
&.pf-c-login__main-footer-band {
& > *:last-child {
padding-block-end: var(--pf-c-login__main-footer-band-item--PaddingTop);
}
}
&.pf-c-modal-box__footer {
--ak-c-fieldset__legend--PaddingInlineBase: var(--pf-global--spacer--lg);
--pf-c-modal-box__footer--c-button--MarginRight: 0;
gap: var(--pf-global--spacer--sm);
justify-content: end;
padding-block: calc(var(--ak-c-fieldset__legend--PaddingInlineBase) / 2);
border-inline: none;
border-block-end: none;
--pf-c-modal-box__footer--c-button--sm--MarginRight: var(
--pf-c-modal-box__footer--c-button--MarginRight
);
& > ak-spinner-button:not(:last-child) {
margin-right: var(--pf-c-modal-box__footer--c-button--MarginRight);
}
}
}
@@ -1,13 +1,13 @@
.pf-c-card > fieldset {
.pf-c-card > .ak-c-fieldset {
margin-inline: var(--pf-global--spacer--md);
margin-block-end: var(--pf-global--spacer--md);
@media not (prefers-contrast: more) {
--ak-fieldset__legend--MarginInlineStart: calc(
var(--pf-c-card--child--PaddingLeft) - var(--ak-fieldset__legend--PaddingInlineBase)
--ak-c-fieldset__legend--MarginInlineStart: calc(
var(--pf-c-card--child--PaddingLeft) - var(--ak-c-fieldset__legend--PaddingInlineBase)
);
--ak-legend-margin-inline-end: calc(
var(--pf-c-card--child--PaddingRight) - var(--ak-fieldset__legend--PaddingInlineBase)
var(--pf-c-card--child--PaddingRight) - var(--ak-c-fieldset__legend--PaddingInlineBase)
);
border-width: 0;
@@ -0,0 +1,102 @@
.ak-c-fieldset {
--ak-c-fieldset--BorderWidth: thin;
--ak-c-fieldset--RowGap: var(--pf-global--spacer--md);
--ak-c-fieldset--ColumnGap: var(--pf-global--spacer--sm);
--ak-c-fieldset__legend--MarginInlineBase: var(--pf-global--spacer--sm);
--ak-c-fieldset__legend--PaddingInlineBase: var(--pf-global--spacer--sm);
border-color: var(--ak-c-fieldset--BorderColor, var(--pf-global--BackgroundColor--light-100));
border-width: var(--ak-c-fieldset--BorderWidth);
padding: var(--ak-c-fieldset__legend--PaddingInlineBase) !important;
@media (prefers-contrast: more) {
border-color: var(--ak-c-fieldset--BorderColor, var(--pf-global--BorderColor--200));
}
@media (prefers-contrast: less) {
border-color: var(--ak-c-fieldset--BorderColor, transparent);
}
}
.ak-c-fieldset > legend {
line-height: 1;
padding: var(--ak-c-fieldset__legend--PaddingInlineBase) !important;
margin-inline-start: var(
--ak-c-fieldset__legend--MarginInlineStart,
var(--ak-c-fieldset__legend--MarginInlineBase)
) !important;
margin-inline-end: var(
--ak-legend-margin-inline-end,
var(--ak-c-fieldset__legend--MarginInlineBase)
) !important;
}
.ak-c-fieldset:has(legend.sr-only:not(.more-contrast-only)) {
border-width: 0;
&:not(.pf-c-modal-box__footer) {
--ak-c-fieldset__legend--PaddingInlineBase: 0;
--ak-c-fieldset__legend--MarginInlineBase: 0;
}
}
.ak-c-fieldset.pf-c-form__group {
border-radius: var(--pf-global--BorderRadius--sm);
}
.ak-c-fieldset.pf-c-form__group {
display: flex;
flex-wrap: wrap;
&.pf-m-action {
--ak-c-fieldset__legend--PaddingInlineBase: 0;
--ak-c-fieldset__legend--MarginInlineBase: 0;
--ak-c-fieldset--BorderWidth: 0;
row-gap: var(--ak-c-fieldset--RowGap);
column-gap: var(--ak-c-fieldset--ColumnGap);
margin-block-start: 0;
}
}
.ak-c-fieldset.pf-c-login__main-footer-band > *:last-child {
padding-block-end: var(--pf-c-login__main-footer-band-item--PaddingTop);
}
/* TODO: Remove after ak-modal migration. */
.ak-c-fieldset.pf-c-modal-box__footer {
--ak-c-fieldset__legend--PaddingInlineBase: var(--pf-global--spacer--lg);
--pf-c-modal-box__footer--c-button--MarginRight: 0;
--pf-c-modal-box__footer--c-button--sm--MarginRight: var(
--pf-c-modal-box__footer--c-button--MarginRight
);
gap: var(--pf-global--spacer--sm);
justify-content: end;
padding-block: calc(var(--ak-c-fieldset__legend--PaddingInlineBase) / 2);
border-inline: none;
border-block-end: none;
& > ak-spinner-button:not(:last-child) {
margin-right: var(--pf-c-modal-box__footer--c-button--MarginRight);
}
}
[data-theme="dark"] .ak-c-fieldset,
:host([theme="dark"]) .ak-c-fieldset {
border-color: var(
--ak-c-fieldset--BorderColor,
var(--pf-global--BackgroundColor--dark-transparent-200)
);
@media (prefers-contrast: more) {
border-color: var(--ak-c-fieldset--BorderColor, var(--pf-global--BorderColor--300));
}
@media (prefers-contrast: less) {
border-color: var(--ak-c-fieldset--BorderColor, transparent);
}
}
@@ -20,6 +20,11 @@
);
}
.pf-c-form__alert {
display: grid;
gap: var(--pf-global--spacer--form-element);
}
.pf-c-form.ak-m-content-center {
--pf-c-form--GridGap: var(--pf-global--spacer--sm);
@@ -90,91 +95,6 @@ ak-form-element-horizontal:has(.pf-c-form__helper-text + ak-checkbox-group) {
}
}
/* #region Fields */
fieldset {
--ak-fieldset--BorderWidth: thin;
--ak-fieldset__legend--MarginInlineBase: var(--pf-global--spacer--sm);
--ak-fieldset__legend--PaddingInlineBase: var(--pf-global--spacer--sm);
border-color: var(--ak-fieldset--BorderColor, var(--pf-global--BackgroundColor--light-100));
@media (prefers-contrast: more) {
border-color: var(--ak-fieldset--BorderColor, var(--pf-global--BorderColor--200));
}
@media (prefers-contrast: less) {
border-color: var(--ak-fieldset--BorderColor, transparent);
}
border-width: var(--ak-fieldset--BorderWidth);
padding: var(--ak-fieldset__legend--PaddingInlineBase) !important;
& > legend {
line-height: 1;
padding: var(--ak-fieldset__legend--PaddingInlineBase) !important;
margin-inline-start: var(
--ak-fieldset__legend--MarginInlineStart,
var(--ak-fieldset__legend--MarginInlineBase)
) !important;
margin-inline-end: var(
--ak-legend-margin-inline-end,
var(--ak-fieldset__legend--MarginInlineBase)
) !important;
}
&:has(legend.sr-only:not(.more-contrast-only)) {
border-width: 0;
&:not(.pf-c-modal-box__footer) {
--ak-fieldset__legend--PaddingInlineBase: 0;
--ak-fieldset__legend--MarginInlineBase: 0;
}
}
&.pf-c-form__group {
border-radius: var(--pf-global--BorderRadius--sm);
}
&.pf-c-form__group {
display: flex;
flex-wrap: wrap;
&.pf-m-action {
gap: var(--pf-global--spacer--md) var(--pf-global--spacer--sm);
margin-block-start: 0;
}
}
&.pf-c-login__main-footer-band {
& > *:last-child {
padding-block-end: var(--pf-c-login__main-footer-band-item--PaddingTop);
}
}
&.pf-c-modal-box__footer {
--ak-fieldset__legend--PaddingInlineBase: var(--pf-global--spacer--lg);
--pf-c-modal-box__footer--c-button--MarginRight: 0;
gap: var(--pf-global--spacer--sm);
justify-content: end;
padding-block: calc(var(--ak-fieldset__legend--PaddingInlineBase) / 2);
border-inline: none;
border-block-end: none;
--pf-c-modal-box__footer--c-button--sm--MarginRight: var(
--pf-c-modal-box__footer--c-button--MarginRight
);
& > ak-spinner-button:not(:last-child) {
margin-right: var(--pf-c-modal-box__footer--c-button--MarginRight);
}
}
}
/* #endregion */
/* #region Radio */
.pf-c-radio {
@@ -402,21 +322,6 @@ ak-switch-input {
border-bottom: 0;
}
fieldset {
border-color: var(
--ak-fieldset--BorderColor,
var(--pf-global--BackgroundColor--dark-transparent-200)
);
@media (prefers-contrast: more) {
border-color: var(--ak-fieldset--BorderColor, var(--pf-global--BorderColor--300));
}
@media (prefers-contrast: less) {
border-color: var(--ak-fieldset--BorderColor, transparent);
}
}
/* #endregion */
/* #region Radio */
@@ -16,13 +16,13 @@
position: relative;
}
@media (width >= 1200px) {
@media (width > 1210px) {
.pf-c-page__sidebar.pf-m-expanded {
--pf-c-page__sidebar--BoxShadow: var(--pf-global--BoxShadow--sm-right);
}
}
@media (width < 1200px) {
@media (width <= 1210px) {
.pf-c-page__sidebar.pf-m-expanded ~ .pf-c-page__drawer .pf-c-page__sidebar-backdrop::after {
background-color: var(--pf-global--BackgroundColor--dark-transparent-100);
content: "";
@@ -17,7 +17,7 @@
}
.pf-c-wizard__main-body {
--ak-fieldset--BorderColor: var(--pf-global--BackgroundColor--150);
--ak-c-fieldset--BorderColor: var(--pf-global--BackgroundColor--150);
gap: var(--pf-global--spacer--lg);
@@ -44,6 +44,8 @@
.pf-c-wizard__footer {
justify-content: end;
align-items: center;
/** Approximation of the height of navigation buttons to avoid excessive layout shifts when they are added or removed. */
min-height: calc(var(--pf-global--spacer--3xl) + (var(--pf-global--spacer--form-element) * 2));
}
.pf-c-wizard__nav-link {
@@ -9,6 +9,7 @@
@import "@patternfly/patternfly/utilities/Text/text.css";
@import "./components/Drawer/drawer.css";
@import "./components/Form/form.css";
@import "./components/Fieldset/fieldset.css";
@import "./components/Login/login.css";
@import "./components/Icon/icon.css";
@import "#elements/locale/ak-locale-select.css";
+1 -1
View File
@@ -132,7 +132,7 @@ ak-app-icon {
[part="app-group-header"] {
@media not (prefers-contrast: more) {
--ak-fieldset__legend--PaddingInlineBase: 1rem;
--ak-c-fieldset__legend--PaddingInlineBase: 1rem;
padding-block-start: 0 !important;
padding-inline: 0 !important;
margin-inline: 0 !important;
@@ -63,6 +63,7 @@ export const AKLibraryApplicationList: LitFC<AKLibraryApplicationListProps> = ({
const groupID = kebabCase(groupLabel);
return html`<fieldset
class="ak-c-fieldset"
data-group-id=${ifPresent(groupID)}
part="app-group"
data-group-index=${groupIndex}
+1
View File
@@ -39,6 +39,7 @@
"aria-description",
"inert",
"enterkeyhint",
//#endregion