Skip to content

Commit

Permalink
Fix button inconsistencies and macOS layout shifts
Browse files Browse the repository at this point in the history
This commit fixes layout shifts experienced in macOS Safari when
hovering over top menu items. Instead of making text bold — which was
causing layout shifts — the hover effect now changes the text color.
This ensures a consistent UI across different browsers and platforms.

Additionally, this commit fixes the styling of the privacy button
located in the bottom right corner. Previously styled as an `<a>`
element, it is now correctly represented as a `<button>`.

Furthermore, the commit enhances HTML conformity and accessibility by
correctly using `<button>` and `<a>` tags instead of relying on click
interactions on `<span>` elements.

This commit introduces `FlatButton` Vue component and a new
`flat-button` mixin. These centralize button usage and link styles,
aligning the hover/touch reactions of buttons across the application,
thereby creating a more consistent user interface.
  • Loading branch information
undergroundwires committed Dec 29, 2023
1 parent 2f06043 commit 86fde6d
Show file tree
Hide file tree
Showing 19 changed files with 364 additions and 107 deletions.
9 changes: 5 additions & 4 deletions docs/presentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,15 @@ To add a new dependency:

## Shared UI components

Shared UI components promote consistency and simplifies the creation of the front-end.
Shared UI components ensure consistency and streamline front-end development.

In order to maintain portability and easy maintainability, the preference is towards using homegrown components over third-party ones or comprehensive UI frameworks like Quasar.
We use homegrown components over third-party solutions or comprehensive UI frameworks like Quasar to maintain portability and easy maintenance.

Shared components include:

- [ModalDialog.vue](./../src/presentation/components/Shared/Modal/ModalDialog.vue) is utilized for rendering modal windows.
- [TooltipWrapper.vue](./../src/presentation/components/Shared/TooltipWrapper.vue) acts as a wrapper for rendering tooltips.
- [ModalDialog.vue](./../src/presentation/components/Shared/Modal/ModalDialog.vue): Renders modal windows.
- [TooltipWrapper.vue](./../src/presentation/components/Shared/TooltipWrapper.vue): Provides tooltip functionality for improved information accessibility.
- [FlatButton.vue](./../src/presentation/components/Shared/FlatButton.vue): Creates flat-style buttons for a unified and consistent user interface.

## Desktop builds

Expand Down
2 changes: 1 addition & 1 deletion src/presentation/assets/styles/_colors.scss
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ $color-on-surface : #4d5156;
// Background | Appears behind scrollable content.
$color-background : #e6ecf4;


/*
Application-specific colors:
These are tailored to the specific needs of the application and derived from the above theme colors.
Use these colors to ensure consistent styling across components. When adding new colors, reference existing theme colors.
This approach maintains a cohesive look and feel and simplifies theme adjustments.
*/
$color-scripts-bg: $color-primary-darker;
$color-highlight: $color-primary;
8 changes: 2 additions & 6 deletions src/presentation/assets/styles/_globals.scss
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,10 @@
box-sizing: border-box;
}

$globals-color-hover: $color-primary;
a {
color:inherit;
text-decoration: underline;
color: inherit;
cursor: pointer;
@include hover-or-touch {
color: $globals-color-hover;
}
@include flat-button($disabled: false);
}

body {
Expand Down
46 changes: 46 additions & 0 deletions src/presentation/assets/styles/_mixins.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@use "@/presentation/assets/styles/colors" as *;

@mixin hover-or-touch($selector-suffix: '', $selector-prefix: '&') {
@media (hover: hover) {
/*
Expand Down Expand Up @@ -65,3 +67,47 @@
padding: 0;
list-style: none;
}

@mixin reset-button {
margin: 0;
padding-block: 0;
padding-inline: 0;
font: unset;
border: unset;
background: unset;
align-items: unset;
text-align: unset;
text-shadow: unset;
text-rendering: unset;
color: inherit;
writing-mode: unset;
letter-spacing: unset;
word-spacing: unset;
line-height: unset;
text-transform: unset;
text-indent: unset;
appearance: unset;
cursor: unset;
}

@mixin flat-button($disabled: false) {
@include reset-button;

@if $disabled {
color: $color-primary-light;
} @else {
color: inherit;
@include clickable;
@include hover-or-touch {
text-decoration: underline;
color: $color-highlight;
/*
Using color change and underlining and as hover cues instead of bold text,
due to inconsistent bold rendering in macOS browsers:
- Safari: Renders bold, causes layout shift.
- Firefox: Renders bold correctly, no layout shift.
- Chromium-based browsers (including Electron app): Do not render bold, no layout shift.
*/
}
}
}
6 changes: 4 additions & 2 deletions src/presentation/components/Code/CodeButtons/IconButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ export default defineComponent({
}
.button {
@include reset-button;
display: flex;
align-items: center;
justify-content: center;
Expand All @@ -72,13 +74,13 @@ export default defineComponent({
color: $color-on-secondary;
border: none;
padding:20px;
padding: 20px;
transition-duration: 0.4s;
overflow: hidden;
box-shadow: 0 3px 9px $color-primary-darkest;
border-radius: 4px;
&__icon {
.button__icon {
font-size: 2em;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,7 @@
<code ref="codeElement"><slot /></code>
<div class="copy-action-container">
<TooltipWrapper>
<AppIcon
icon="copy"
class="copy-button"
@click="copyCode"
/>
<FlatButton icon="copy" @click="copyCode" />
<template #tooltip>
Copy
</template>
Expand All @@ -20,13 +16,13 @@
<script lang="ts">
import { defineComponent, shallowRef } from 'vue';
import TooltipWrapper from '@/presentation/components/Shared/TooltipWrapper.vue';
import AppIcon from '@/presentation/components/Shared/Icon/AppIcon.vue';
import { injectKey } from '@/presentation/injectionSymbols';
import FlatButton from '@/presentation/components/Shared/FlatButton.vue';
export default defineComponent({
components: {
TooltipWrapper,
AppIcon,
FlatButton,
},
setup() {
const { copyText } = injectKey((keys) => keys.useClipboard);
Expand Down Expand Up @@ -73,12 +69,6 @@ export default defineComponent({
.copy-action-container {
margin-left: 1rem;
}
.copy-button {
@include clickable;
@include hover-or-touch {
color: $color-primary;
}
}
code {
font-size: 1rem;
}
Expand Down
32 changes: 15 additions & 17 deletions src/presentation/components/DevToolkit/DevToolkit.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@
<div class="title">
Tools
</div>
<button type="button" class="close-button" @click="close">
<AppIcon icon="xmark" />
</button>
<FlatButton icon="xmark" class="close-button" @click="close" />
</div>
<hr />
<div class="action-buttons">
Expand All @@ -28,12 +26,12 @@
<script lang="ts">
import { defineComponent, ref } from 'vue';
import { injectKey } from '@/presentation/injectionSymbols';
import AppIcon from '@/presentation/components/Shared/Icon/AppIcon.vue';
import FlatButton from '@/presentation/components/Shared/FlatButton.vue';
import { dumpNames } from './DumpNames';
export default defineComponent({
components: {
AppIcon,
FlatButton,
},
setup() {
const { log } = injectKey((keys) => keys.useLogger);
Expand Down Expand Up @@ -118,19 +116,19 @@ interface DevAction {
display: flex;
flex-direction: column;
gap: 10px;
}
button {
display: block;
padding: 5px 10px;
background-color: $color-primary;
color: $color-on-primary;
border: none;
cursor: pointer;
@include hover-or-touch {
background-color: $color-secondary;
color: $color-on-secondary;
button {
display: block;
padding: 5px 10px;
background-color: $color-primary;
color: $color-on-primary;
border: none;
cursor: pointer;
@include hover-or-touch {
background-color: $color-secondary;
color: $color-on-secondary;
}
}
}
}
Expand Down
29 changes: 7 additions & 22 deletions src/presentation/components/Scripts/Menu/MenuOptionListItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,23 @@
Parent wrapper allows `MenuOptionList` to safely add content inside
such as adding content in `::before` block without making it clickable.
-->
<span
v-non-collapsing
:class="{
disabled: !enabled,
enabled: enabled,
}"
<FlatButton
:disabled="!enabled"
:label="label"
flat
@click="onClicked()"
>{{ label }}</span>
/>
</span>
</template>

<script lang="ts">
import { defineComponent } from 'vue';
import { NonCollapsing } from '@/presentation/components/Scripts/View/Cards/NonCollapsingDirective';
import FlatButton from '@/presentation/components/Shared/FlatButton.vue';
export default defineComponent({
directives: { NonCollapsing },
components: { FlatButton },
props: {
enabled: {
type: Boolean,
Expand Down Expand Up @@ -48,18 +48,3 @@ export default defineComponent({
},
});
</script>

<style scoped lang="scss">
@use "@/presentation/assets/styles/main" as *;
.enabled {
@include clickable;
@include hover-or-touch {
font-weight:bold;
text-decoration:underline;
}
}
.disabled {
color: $color-primary-light;
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
</div>
<div class="card__expander" @click.stop>
<div class="card__expander__close-button">
<AppIcon
<FlatButton
icon="xmark"
@click="collapse()"
/>
Expand All @@ -51,6 +51,7 @@ import {
defineComponent, computed, shallowRef,
} from 'vue';
import AppIcon from '@/presentation/components/Shared/Icon/AppIcon.vue';
import FlatButton from '@/presentation/components/Shared/FlatButton.vue';
import { injectKey } from '@/presentation/injectionSymbols';
import ScriptsTree from '@/presentation/components/Scripts/View/Tree/ScriptsTree.vue';
import { sleep } from '@/infrastructure/Threading/AsyncSleep';
Expand All @@ -61,6 +62,7 @@ export default defineComponent({
ScriptsTree,
AppIcon,
CardSelectionIndicator,
FlatButton,
},
props: {
categoryId: {
Expand Down
12 changes: 4 additions & 8 deletions src/presentation/components/Scripts/View/TheScriptsView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
class="search__query__close-button"
@click="clearSearchQuery()"
>
<AppIcon icon="xmark" />
<FlatButton icon="xmark" />
</div>
</div>
<div v-if="!searchHasMatches" class="search-no-matches">
Expand All @@ -39,19 +39,19 @@
import {
defineComponent, PropType, ref, computed,
} from 'vue';
import AppIcon from '@/presentation/components/Shared/Icon/AppIcon.vue';
import { injectKey } from '@/presentation/injectionSymbols';
import ScriptsTree from '@/presentation/components/Scripts/View/Tree/ScriptsTree.vue';
import CardList from '@/presentation/components/Scripts/View/Cards/CardList.vue';
import { ViewType } from '@/presentation/components/Scripts/Menu/View/ViewType';
import { IReadOnlyUserFilter } from '@/application/Context/State/Filter/IUserFilter';
import { IFilterResult } from '@/application/Context/State/Filter/IFilterResult';
import FlatButton from '@/presentation/components/Shared/FlatButton.vue';
export default defineComponent({
components: {
ScriptsTree,
CardList,
AppIcon,
FlatButton,
},
props: {
currentView: {
Expand Down Expand Up @@ -149,14 +149,10 @@ $margin-inner: 4px;
flex-direction: row;
align-items: center;
margin-top: 1em;
color: $color-primary;
color: $color-primary-light;
.search__query__close-button {
@include clickable;
font-size: 1.25em;
margin-left: 0.25rem;
@include hover-or-touch {
color: $color-primary-dark;
}
}
}
.search-no-matches {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ $base-spacing: $text-size;
*/
@include hover-or-touch {
&::after{
background-color: $globals-color-hover;
background-color: $color-highlight;
}
}
}
Expand Down

0 comments on commit 86fde6d

Please sign in to comment.