diff --git a/docs/presentation.md b/docs/presentation.md index 7f0b5f15..1a3b99c3 100644 --- a/docs/presentation.md +++ b/docs/presentation.md @@ -26,6 +26,10 @@ It's designed event-driven from bottom to top. It listens user events (from top) - [**`/postcss.config.js`**](./../postcss.config.js): PostCSS configurations used by Vue CLI internally. - [**`/babel.config.js`**](./../babel.config.js): Babel configurations for polyfills used by `@vue/cli-plugin-babel`. +## Visual design best-practices + +Add visual clues for clickable items. It should be as clear as possible that they're interactable at first look without hovering. They should also have different visual state when hovering/touching on them that indicates that they are being clicked, which helps with accessibility. + ## Application data Components (should) use [ApplicationFactory](./../src/application/ApplicationFactory.ts) singleton to reach the application domain to avoid [parsing and compiling](./application.md#parsing-and-compiling) the application again. diff --git a/src/presentation/assets/styles/_mixins.scss b/src/presentation/assets/styles/_mixins.scss index aedc9c7c..ffb0e8b4 100644 --- a/src/presentation/assets/styles/_mixins.scss +++ b/src/presentation/assets/styles/_mixins.scss @@ -14,3 +14,16 @@ } } } + +@mixin clickable($cursor: 'pointer') { + cursor: #{$cursor}; + user-select: none; + /* + It removes (blue) background during touch as seen in mobile webkit browsers (Chrome, Safari, Edge). + The default behavior is that any element (or containing element) that has cursor:pointer + explicitly set and is clicked will flash blue momentarily. + Removing it could have accessibility issue since that hides an interactive cue. But as we still provide + response to user actions through :active by `hover-or-touch` mixin. + */ + -webkit-tap-highlight-color: transparent; +} diff --git a/src/presentation/components/Code/CodeButtons/Code.vue b/src/presentation/components/Code/CodeButtons/Code.vue index 8d97476d..a1926c00 100644 --- a/src/presentation/components/Code/CodeButtons/Code.vue +++ b/src/presentation/components/Code/CodeButtons/Code.vue @@ -42,7 +42,7 @@ export default class Code extends Vue { } .copy-button { margin-left: 1rem; - cursor: pointer; + @include clickable; @include hover-or-touch { color: $color-primary; } diff --git a/src/presentation/components/Code/CodeButtons/IconButton.vue b/src/presentation/components/Code/CodeButtons/IconButton.vue index 5be2b8c9..284223be 100644 --- a/src/presentation/components/Code/CodeButtons/IconButton.vue +++ b/src/presentation/components/Code/CodeButtons/IconButton.vue @@ -42,7 +42,8 @@ export default class IconButton extends Vue { box-shadow: 0 3px 9px $color-primary-darkest; border-radius: 4px; - cursor: pointer; + @include clickable; + width: 10%; min-width: 90px; @include hover-or-touch { diff --git a/src/presentation/components/Scripts/Menu/MenuOptionListItem.vue b/src/presentation/components/Scripts/Menu/MenuOptionListItem.vue index 214b6896..ba81deb8 100644 --- a/src/presentation/components/Scripts/Menu/MenuOptionListItem.vue +++ b/src/presentation/components/Scripts/Menu/MenuOptionListItem.vue @@ -29,7 +29,7 @@ export default class MenuOptionListItem extends Vue { @use "@/presentation/assets/styles/main" as *; .enabled { - cursor: pointer; + @include clickable; @include hover-or-touch { font-weight:bold; text-decoration:underline; diff --git a/src/presentation/components/Scripts/Slider/Handle.vue b/src/presentation/components/Scripts/Slider/Handle.vue index d060d418..ac1ecb53 100644 --- a/src/presentation/components/Scripts/Slider/Handle.vue +++ b/src/presentation/components/Scripts/Slider/Handle.vue @@ -52,7 +52,7 @@ $color : $color-primary-dark; $color-hover : $color-primary; .handle { - user-select: none; + @include clickable($cursor: 'ew-resize'); display: flex; flex-direction: column; align-items: center; diff --git a/src/presentation/components/Scripts/View/Cards/CardListItem.vue b/src/presentation/components/Scripts/View/Cards/CardListItem.vue index 078b7e66..44b29f60 100644 --- a/src/presentation/components/Scripts/View/Cards/CardListItem.vue +++ b/src/presentation/components/Scripts/View/Cards/CardListItem.vue @@ -130,7 +130,7 @@ $card-horizontal-gap : $card-gap; padding-bottom: 0; padding-left: $card-inner-padding; position: relative; - cursor: pointer; + @include clickable; background-color: $color-primary; color: $color-on-primary; font-size: 1.5em; @@ -187,7 +187,7 @@ $card-horizontal-gap : $card-gap; font-size: 1.5em; align-self: flex-start; margin-right: 0.25em; - cursor: pointer; + @include clickable; color: $color-primary-light; @include hover-or-touch { color: $color-primary; diff --git a/src/presentation/components/Scripts/View/ScriptsTree/SelectableTree/Node/DocumentationUrls.vue b/src/presentation/components/Scripts/View/ScriptsTree/SelectableTree/Node/DocumentationUrls.vue index 8ea8f1d6..8f1623dd 100644 --- a/src/presentation/components/Scripts/View/ScriptsTree/SelectableTree/Node/DocumentationUrls.vue +++ b/src/presentation/components/Scripts/View/ScriptsTree/SelectableTree/Node/DocumentationUrls.vue @@ -33,8 +33,8 @@ export default class DocumentationUrls extends Vue { .documentationUrl { display: flex; color: $color-primary; - cursor: pointer; vertical-align: middle; + @include clickable; @include hover-or-touch { color: $color-primary-darker; } diff --git a/src/presentation/components/Scripts/View/ScriptsTree/SelectableTree/Node/RevertToggle.vue b/src/presentation/components/Scripts/View/ScriptsTree/SelectableTree/Node/RevertToggle.vue index 4287a0ae..56d8196b 100644 --- a/src/presentation/components/Scripts/View/ScriptsTree/SelectableTree/Node/RevertToggle.vue +++ b/src/presentation/components/Scripts/View/ScriptsTree/SelectableTree/Node/RevertToggle.vue @@ -65,7 +65,6 @@ $size-height : 30px; // https://www.designlabthemes.com/css-toggle-switch/ .checkbox-switch { - cursor: pointer; display: inline-block; overflow: hidden; position: relative; @@ -87,7 +86,7 @@ $size-height : 30px; margin: 0; opacity: 0; z-index: 2; - cursor: pointer; + @include clickable; } .checkbox-animate { diff --git a/src/presentation/components/Scripts/View/TheScriptsView.vue b/src/presentation/components/Scripts/View/TheScriptsView.vue index e5a0ce34..37263d48 100644 --- a/src/presentation/components/Scripts/View/TheScriptsView.vue +++ b/src/presentation/components/Scripts/View/TheScriptsView.vue @@ -137,7 +137,7 @@ $margin-inner: 4px; margin-top: 1em; color: $color-primary; &__close-button { - cursor: pointer; + @include clickable; font-size: 1.25em; margin-left: 0.25rem; @include hover-or-touch { diff --git a/src/presentation/components/Shared/Dialog.vue b/src/presentation/components/Shared/Dialog.vue index f8f01ab7..a5a7cfa5 100644 --- a/src/presentation/components/Shared/Dialog.vue +++ b/src/presentation/components/Shared/Dialog.vue @@ -52,7 +52,7 @@ export default class Dialog extends Vue { font-size: 1.5em; margin-right: 0.25em; align-self: flex-start; - cursor: pointer; + @include clickable; @include hover-or-touch { color: $color-primary; } diff --git a/src/presentation/components/TheFooter/DownloadUrlListItem.vue b/src/presentation/components/TheFooter/DownloadUrlListItem.vue index 6f1d9f3f..72135f50 100644 --- a/src/presentation/components/TheFooter/DownloadUrlListItem.vue +++ b/src/presentation/components/TheFooter/DownloadUrlListItem.vue @@ -69,12 +69,14 @@ function getOperatingSystemName(os: OperatingSystem): string {