Fixed Issue Of No/Incorrect Displayable Tooltips
- Single byte edit modes now have tooltips attached to their elements.
- Icon only buttons have permanent tooltip displays.
- Tooltips now detect off-window display.
Closes #815
diff --git a/src/svelte/src/components/DataDisplays/CustomByteDisplay/DataLineFeed.svelte b/src/svelte/src/components/DataDisplays/CustomByteDisplay/DataLineFeed.svelte
index ebfe8b7..f7d75cf 100644
--- a/src/svelte/src/components/DataDisplays/CustomByteDisplay/DataLineFeed.svelte
+++ b/src/svelte/src/components/DataDisplays/CustomByteDisplay/DataLineFeed.svelte
@@ -533,6 +533,7 @@
disabledBy={disableIncrement}
width="30pt"
description="Navigate to EOF"
+ tooltipAlwaysEnabled={true}
>
<span slot="left" class="btn-icon material-symbols-outlined"
>stat_minus_3</span
@@ -544,6 +545,7 @@
width="30pt"
description="Increment offset by {NUM_LINES_DISPLAYED *
bytesPerRow} bytes"
+ tooltipAlwaysEnabled={true}
>
<span slot="left" class="btn-icon material-symbols-outlined"
>keyboard_double_arrow_down</span
@@ -554,6 +556,7 @@
disabledBy={disableIncrement}
width="30pt"
description="Increment offset by {bytesPerRow} bytes"
+ tooltipAlwaysEnabled={true}
>
<span slot="left" class="btn-icon material-symbols-outlined"
>keyboard_arrow_down</span
@@ -564,6 +567,7 @@
disabledBy={disableDecrement}
width="30pt"
description="Decrement offset by {bytesPerRow} bytes"
+ tooltipAlwaysEnabled={true}
>
<span slot="left" class="btn-icon material-symbols-outlined"
>keyboard_arrow_up</span
@@ -575,6 +579,7 @@
width="30pt"
description="Decrement offset by {NUM_LINES_DISPLAYED *
bytesPerRow} bytes"
+ tooltipAlwaysEnabled={true}
>
<span slot="left" class="btn-icon material-symbols-outlined"
>keyboard_double_arrow_up</span
@@ -585,6 +590,7 @@
disabledBy={disableDecrement}
width="30pt"
description="Navigate to offset 0"
+ tooltipAlwaysEnabled={true}
>
<span slot="left" class="btn-icon material-symbols-outlined"
>stat_3</span
diff --git a/src/svelte/src/components/DataDisplays/CustomByteDisplay/SelectedByteEdit.svelte b/src/svelte/src/components/DataDisplays/CustomByteDisplay/SelectedByteEdit.svelte
index f78424d..08cb500 100644
--- a/src/svelte/src/components/DataDisplays/CustomByteDisplay/SelectedByteEdit.svelte
+++ b/src/svelte/src/components/DataDisplays/CustomByteDisplay/SelectedByteEdit.svelte
@@ -42,6 +42,7 @@
type CSSThemeClass,
} from '../../../utilities/colorScheme'
import { EditActionRestrictions } from '../../../stores/configuration'
+ import Tooltip from '../../layouts/Tooltip.svelte'
const eventDispatcher = createEventDispatcher()
@@ -290,7 +291,7 @@
}
function send_insert(event: Event) {
- const target = event.target as HTMLElement
+ const target = event.currentTarget as HTMLElement
switch (target.id) {
case actionElements['insert-after'].id:
applyChanges('insert-after')
@@ -324,31 +325,6 @@
</script>
{#if $editorActionsAllowed == EditActionRestrictions.None}
- <!-- svelte-ignore a11y-click-events-have-key-events -->
- <!-- svelte-ignore a11y-no-static-element-interactions -->
- {#if actionElements['insert-before'].render}
- <div
- class="insert-before {themeClass}"
- id={actionElements['insert-before'].id}
- style:width={elementDivWidth}
- on:click={send_insert}
- >
- ⇤
- </div>
- {/if}
- <!-- svelte-ignore a11y-click-events-have-key-events -->
- <!-- svelte-ignore a11y-no-static-element-interactions -->
- {#if actionElements['insert-after'].render}
- <div
- class="insert-after {themeClass}"
- id={actionElements['insert-after'].id}
- style:width={elementDivWidth}
- on:click={send_insert}
- >
- ⇥
- </div>
- {/if}
-
<span>
<input
class="insert {themeClass}"
@@ -369,9 +345,40 @@
style:width={elementDivWidth}
on:click={send_delete}
>
- ✖
+ <Tooltip alwaysEnabled={true} description={'Delete byte'}>
+ ✖
+ </Tooltip>
</div>
</span>
+ <!-- svelte-ignore a11y-click-events-have-key-events -->
+ <!-- svelte-ignore a11y-no-static-element-interactions -->
+
+ {#if actionElements['insert-before'].render}
+ <div
+ class="insert-before {themeClass}"
+ id={actionElements['insert-before'].id}
+ style:width={elementDivWidth}
+ on:click={send_insert}
+ >
+ <Tooltip alwaysEnabled={true} description={'Insert as preceding byte'}>
+ ⇤
+ </Tooltip>
+ </div>
+ {/if}
+ <!-- svelte-ignore a11y-click-events-have-key-events -->
+ <!-- svelte-ignore a11y-no-static-element-interactions -->
+ {#if actionElements['insert-after'].render}
+ <div
+ class="insert-after {themeClass}"
+ id={actionElements['insert-after'].id}
+ style:width={elementDivWidth}
+ on:click={send_insert}
+ >
+ <Tooltip alwaysEnabled={true} description={'Insert as following byte'}>
+ ⇥
+ </Tooltip>
+ </div>
+ {/if}
{:else}
<span>
<input
@@ -436,7 +443,6 @@
div.delete {
font-size: 20px;
line-height: 1;
- z-index: 1;
}
div.insert-before,
div.insert-after {
diff --git a/src/svelte/src/components/Header/Header.svelte b/src/svelte/src/components/Header/Header.svelte
index e04cbfd..1ad330a 100644
--- a/src/svelte/src/components/Header/Header.svelte
+++ b/src/svelte/src/components/Header/Header.svelte
@@ -21,6 +21,7 @@
import FlexContainer from '../layouts/FlexContainer.svelte'
import { UIThemeCSSClass } from '../../utilities/colorScheme'
import { fileMetrics } from '../../stores'
+ import Tooltip from '../layouts/Tooltip.svelte'
let hideChildren = false
</script>
@@ -29,12 +30,14 @@
<FlexContainer>
<FlexContainer --justify-content="space-between" --align-items="center">
<div class="filename-display"><b>File:</b> {$fileMetrics.name}</div>
- <button
- class={$UIThemeCSSClass + ' minmax-icon'}
- on:click={() => {
- hideChildren = hideChildren ? false : true
- }}><span class="material-symbols-outlined">expand_all</span></button
- >
+ <Tooltip alwaysEnabled={true} description={'Maximize header'}>
+ <button
+ class={$UIThemeCSSClass + ' minmax-icon'}
+ on:click={() => {
+ hideChildren = hideChildren ? false : true
+ }}><span class="material-symbols-outlined">expand_all</span></button
+ >
+ </Tooltip>
</FlexContainer>
</FlexContainer>
{:else}
@@ -47,20 +50,22 @@
</FlexContainer>
</header>
<div class="display-icons">
- <button
- class={$UIThemeCSSClass + ' minmax-icon'}
- on:click={() => {
- hideChildren = !hideChildren
- }}
- >
- <span class="material-symbols-outlined">
- {#if hideChildren}
- expand_all
- {:else}
- expand_less
- {/if}
- </span>
- </button>
+ <Tooltip alwaysEnabled={true} description={'Minimize header'}>
+ <button
+ class={$UIThemeCSSClass + ' minmax-icon'}
+ on:click={() => {
+ hideChildren = !hideChildren
+ }}
+ >
+ <span class="material-symbols-outlined">
+ {#if hideChildren}
+ expand_all
+ {:else}
+ expand_less
+ {/if}
+ </span>
+ </button>
+ </Tooltip>
</div>
</FlexContainer>
{/if}
diff --git a/src/svelte/src/components/Inputs/Buttons/Button.svelte b/src/svelte/src/components/Inputs/Buttons/Button.svelte
index 29d1cf7..bfa5929 100644
--- a/src/svelte/src/components/Inputs/Buttons/Button.svelte
+++ b/src/svelte/src/components/Inputs/Buttons/Button.svelte
@@ -30,6 +30,7 @@
})
export let description = ''
+ export let tooltipAlwaysEnabled = false
let collapseContentFn: NodeJS.Timeout
let collapseContent = false
@@ -44,8 +45,8 @@
})
</script>
-{#if collapseContent}
- <Tooltip {description}>
+<Tooltip alwaysEnabled={tooltipAlwaysEnabled} {description}>
+ {#if collapseContent}
<button
class={$UIThemeCSSClass + ' collapsed'}
disabled={disabledBy}
@@ -62,27 +63,27 @@
</svelte:fragment>
</FlexContainer>
</button>
- </Tooltip>
-{:else}
- <button
- class={$UIThemeCSSClass}
- disabled={disabledBy}
- on:click={!disabledBy ? fn : () => {}}
- style:width
- >
- <FlexContainer
- --dir="row"
- --align-items="center"
- --justify-content="center"
+ {:else}
+ <button
+ class={$UIThemeCSSClass}
+ disabled={disabledBy}
+ on:click={!disabledBy ? fn : () => {}}
+ style:width
>
- <svelte:fragment>
- <slot name="left" />
- <slot />
- <slot name="right" />
- </svelte:fragment>
- </FlexContainer>
- </button>
-{/if}
+ <FlexContainer
+ --dir="row"
+ --align-items="center"
+ --justify-content="center"
+ >
+ <svelte:fragment>
+ <slot name="left" />
+ <slot />
+ <slot name="right" />
+ </svelte:fragment>
+ </FlexContainer>
+ </button>
+ {/if}
+</Tooltip>
<style lang="scss">
button {
diff --git a/src/svelte/src/components/layouts/Tooltip.svelte b/src/svelte/src/components/layouts/Tooltip.svelte
index dc54251..29fc0bf 100644
--- a/src/svelte/src/components/layouts/Tooltip.svelte
+++ b/src/svelte/src/components/layouts/Tooltip.svelte
@@ -18,7 +18,8 @@
import { tooltipsEnabled } from '../../stores'
const NULL = () => {}
-
+ const TOOLTIP_MIN_WIDTH = 50
+ const TOOLTIP_MIN_HEIGHT = 25
export let description: string
export let alwaysEnabled = false
let showTooltip = false
@@ -30,8 +31,23 @@
switch (event.type) {
case 'mouseenter':
- left = targetElement.offsetLeft
- top = targetElement.offsetTop + targetElement.offsetHeight + 5
+ const clientWidth = document.body.clientWidth
+ const targetOffsetLeft = targetElement.offsetLeft
+ const clientHeight = window.innerHeight
+ const targetOffsetTop = targetElement.offsetTop
+ const targetHeight = targetElement.offsetHeight
+
+ left =
+ clientWidth - targetOffsetLeft + TOOLTIP_MIN_WIDTH > targetOffsetLeft
+ ? targetOffsetLeft
+ : targetOffsetLeft - TOOLTIP_MIN_WIDTH
+
+ top =
+ targetOffsetTop + targetHeight + TOOLTIP_MIN_HEIGHT <
+ clientHeight - TOOLTIP_MIN_HEIGHT
+ ? targetOffsetTop + targetHeight + 5
+ : targetOffsetTop - TOOLTIP_MIN_HEIGHT
+
showTooltip = true
break
case 'mouseleave':
@@ -51,13 +67,13 @@
</span>
{#if showTooltip}
- <span
+ <div
class="tooltip"
style:left={left.toString() + 'px'}
style:top={top.toString() + 'px'}
>
{description}
- </span>
+ </div>
{/if}
{:else}
<span><slot /></span>
@@ -66,8 +82,13 @@
<style lang="scss">
.tooltip {
position: absolute;
+ display: flex;
+ align-content: center;
+ align-items: center;
max-width: 150px;
+ min-width: 50px;
max-height: 50px;
+ min-height: 25px;
font-size: 12px;
text-align: center;
background-color: var(--color-secondary-darkest);