pinafore/src/routes/_components/IconButton.html
Nolan Lawson 006f0deee8
fix: fix tappable area between toolbar buttons (#1893)
fixes #1884

If "disable entire toot area" is on, then the cursor becomes default between the buttons, and clicking does nothing. If it is off (default), then the cursor is always pointer and clicking between the buttons clicks the whole toot.
2020-11-14 17:22:12 -08:00

158 lines
4.6 KiB
HTML

<!-- Normally "pressable" icons would be toggle buttons, but to avoid having the titles and labels mismatched
due to guidelines from http://w3c.github.io/aria-practices/#button , we just use normal buttons and change
the aria-label instead. See discussion in: https://github.com/nolanlawson/pinafore/issues/1633 -->
<button id={elementId}
type="button"
title={ariaLabel}
aria-label={ariaLabel}
aria-hidden={ariaHidden ? 'true' : undefined}
tabindex={ariaHidden ? '-1' : '0'}
class={computedClass}
{disabled}
ref:node
>
<SvgIcon className="icon-button-svg {svgClassName || ''}" ref:svg {href} />
</button>
<style>
.icon-button {
padding: 6px 10px;
background: none;
border: none;
display: flex;
align-items: center;
justify-content: center;
pointer-events: auto;
}
:global(.icon-button-svg) {
width: 24px;
height: 24px;
fill: var(--action-button-fill-color);
pointer-events: none; /* hack for Edge */
}
:global(.icon-button.big-icon .icon-button-svg) {
width: 32px;
height: 32px;
}
/*
* regular styles
*/
:global(.icon-button:hover .icon-button-svg) {
fill: var(--action-button-fill-color-hover);
}
:global(.icon-button.not-pressable:active .icon-button-svg,
.icon-button.same-pressed:active .icon-button-svg) {
fill: var(--action-button-fill-color-active);
}
:global(.icon-button.pressed.not-same-pressed .icon-button-svg) {
fill: var(--action-button-fill-color-pressed);
}
:global(.icon-button.pressed.not-same-pressed:hover .icon-button-svg) {
fill: var(--action-button-fill-color-pressed-hover);
}
:global(.icon-button.pressed.not-same-pressed:active .icon-button-svg) {
fill: var(--action-button-fill-color-pressed-active);
}
/*
* muted
*/
:global(.icon-button.muted-style .icon-button-svg) {
fill: var(--action-button-deemphasized-fill-color);
}
:global(.icon-button.muted-style:hover .icon-button-svg) {
fill: var(--action-button-deemphasized-fill-color-hover);
}
:global(.icon-button.muted-style.not-pressable:active .icon-button-svg,
.icon-button.muted-style.same-pressed:active .icon-button-svg) {
fill: var(--action-button-deemphasized-fill-color-active);
}
:global(.icon-button.muted-style.pressed.not-same-pressed .icon-button-svg) {
fill: var(--action-button-deemphasized-fill-color-pressed);
}
:global(.icon-button.muted-style.pressed.not-same-pressed:hover .icon-button-svg) {
fill: var(--action-button-deemphasized-fill-color-pressed-hover);
}
:global(.icon-button.muted-style.pressed.not-same-pressed:active .icon-button-svg) {
fill: var(--action-button-deemphasized-fill-color-pressed-active);
}
</style>
<script>
import { classname } from '../_utils/classname'
import { store } from '../_store/store'
import SvgIcon from './SvgIcon.html'
export default {
oncreate () {
const { clickListener } = this.get()
if (clickListener) {
this.onClick = this.onClick.bind(this)
this.refs.node.addEventListener('click', this.onClick)
}
if (process.env.NODE_ENV !== 'production') {
const { pressable, pressedLabel, label } = this.get()
if (pressable && ((!pressedLabel || !label) || pressedLabel === label)) {
throw new Error('pressable buttons should have a label and a pressedLabel different from each other')
}
}
},
ondestroy () {
const { clickListener } = this.get()
if (clickListener) {
this.refs.node.removeEventListener('click', this.onClick)
}
},
data: () => ({
big: false,
muted: false,
disabled: false,
svgClassName: undefined,
elementId: '',
pressable: false,
pressed: false,
pressedLabel: undefined,
className: undefined,
sameColorWhenPressed: false,
ariaHidden: false,
clickListener: true
}),
store: () => store,
computed: {
computedClass: ({ pressable, pressed, big, muted, sameColorWhenPressed, className }) => (classname(
'icon-button',
!pressable && 'not-pressable',
pressed && 'pressed',
big && 'big-icon',
muted && 'muted-style',
sameColorWhenPressed ? 'same-pressed' : 'not-same-pressed',
className
)),
ariaLabel: ({ pressable, pressed, label, pressedLabel }) => ((pressable && pressed) ? pressedLabel : label)
},
methods: {
animate (animation) {
this.refs.svg.animate(animation)
},
onClick (e) {
this.fire('click', e)
}
},
components: {
SvgIcon
}
}
</script>