
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.
158 lines
4.6 KiB
HTML
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>
|