fix(ui/buttons): implement .disabled class (#10410)
Some checks are pending
/ release (push) Waiting to run
testing-integration / test-unit (push) Waiting to run
testing-integration / test-sqlite (push) Waiting to run
testing-integration / test-mariadb (v10.6) (push) Waiting to run
testing-integration / test-mariadb (v11.8) (push) Waiting to run
testing / backend-checks (push) Waiting to run
testing / frontend-checks (push) Waiting to run
testing / test-unit (push) Blocked by required conditions
testing / test-e2e (push) Blocked by required conditions
testing / test-remote-cacher (redis) (push) Blocked by required conditions
testing / test-remote-cacher (valkey) (push) Blocked by required conditions
testing / test-remote-cacher (garnet) (push) Blocked by required conditions
testing / test-remote-cacher (redict) (push) Blocked by required conditions
testing / test-mysql (push) Blocked by required conditions
testing / test-pgsql (push) Blocked by required conditions
testing / test-sqlite (push) Blocked by required conditions
testing / security-check (push) Blocked by required conditions

Followup to https://codeberg.org/forgejo/forgejo/pulls/9359. `templates/repo/issue/list.tmpl` had buttons changed which had `.disabled` on them conditionally.

* adjust devtest page to have such buttons
* implement `.disabled` for the newer buttons that does the same thing as the `.ui` buttons do: apply custom opacity, disable pointer events
    * this is the most boring way of implementing this

Reported-by: @Gusted
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10410
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
This commit is contained in:
0ko 2025-12-16 14:18:08 +01:00
parent 5862d930a1
commit 5088d3ab12
3 changed files with 39 additions and 18 deletions

View file

@ -19,7 +19,7 @@
<button class="primary button" type="button">
Follow
</button>
<a class="primary button" href="">
<a class="primary disabled button" href="">
{{svg "octicon-person"}}
{{ctx.Locale.Tr "user.follow"}}
</a>
@ -30,7 +30,7 @@
<button class="secondary button" type="button">
Follow
</button>
<a class="secondary button" href="">
<a class="secondary disabled button" href="">
{{svg "octicon-person"}}
{{ctx.Locale.Tr "user.unfollow"}}
</a>
@ -41,7 +41,7 @@
<button class="danger button" type="button">
Delete
</button>
<a class="danger button" href="">
<a class="danger disabled button" href="">
{{svg "octicon-trash"}}
Delete
</a>

View file

@ -33,7 +33,7 @@ test('Buttons and other controls have consistent height', async ({page}) => {
expect(buttonHeight).toBe(purgeButtonHeight);
});
test('Button visuals', async ({page}) => {
test('Button visuals', async ({browser}) => {
async function getButtonProperties(page, selector) {
return await page.locator(selector).evaluate((el) => {
// In Firefox getComputedStyle is undefined if returned from evaluate
@ -41,32 +41,48 @@ test('Button visuals', async ({page}) => {
return {
backgroundColor: s.backgroundColor,
fontWeight: s.fontWeight,
opacity: s.opacity,
pointerEvents: s.pointerEvents,
};
});
}
// const context = await browser.newContext({javaScriptEnabled: false});
// const page = await context.newPage();
const context = await browser.newContext({javaScriptEnabled: false});
const page = await context.newPage();
const response = await page.goto('/devtest/buttons');
expect(response?.status()).toBe(200);
const transparent = 'rgba(0, 0, 0, 0)';
const primary = await getButtonProperties(page, 'button.primary');
const secondary = await getButtonProperties(page, 'button.secondary');
const danger = await getButtonProperties(page, 'button.danger');
const primary = await getButtonProperties(page, 'button.primary:not(.disabled)');
const secondary = await getButtonProperties(page, 'button.secondary:not(.disabled)');
const danger = await getButtonProperties(page, 'button.danger:not(.disabled)');
// Evaluate that all buttons have background-color specified
expect(primary.backgroundColor).not.toBe(transparent);
expect(secondary.backgroundColor).not.toBe(transparent);
expect(danger.backgroundColor).not.toBe(transparent);
for (const item of [primary, secondary, danger]) {
// Evaluate that all buttons have background-color specified
expect(item.backgroundColor).not.toBe(transparent);
// Evaluate font weights
expect(item.fontWeight).toBe('500');
// Evaluate opacity
expect(item.opacity).toBe('1');
}
// Evaluate that their background-colors are different
// Evaluate that background-colors are different
expect(primary.backgroundColor).not.toBe(secondary.backgroundColor);
expect(primary.backgroundColor).not.toBe(danger.backgroundColor);
// Evaluate font weights
expect(primary.fontWeight).toBe('500');
expect(secondary.fontWeight).toBe('500');
expect(danger.fontWeight).toBe('500');
const primaryDisabled = await getButtonProperties(page, '.button.primary.disabled');
const secondaryDisabled = await getButtonProperties(page, '.button.secondary.disabled');
const dangerDisabled = await getButtonProperties(page, '.button.danger.disabled');
for (const item of [primaryDisabled, secondaryDisabled, dangerDisabled]) {
// Evaluate opacity
expect(item.opacity).toBe('0.55');
// Evaluate pointer-events
expect(item.pointerEvents).toBe('none');
// Evaluate other properties of non-disabled buttons
expect(item.backgroundColor).not.toBe(transparent);
expect(item.fontWeight).toBe('500');
}
});

View file

@ -36,6 +36,11 @@
&:focus {
text-decoration: none;
}
&.disabled {
opacity: var(--opacity-disabled);
pointer-events: none;
}
}
.button.primary {