vite-plugin-entry-shaking-debugger
Version:
Debugger for vite-plugin-entry-shaking
97 lines (85 loc) • 3.1 kB
text/typescript
import type { Ref } from 'vue';
import { computed, reactive, useAttrs, useSlots } from 'vue';
import { randomId } from '#utils';
import type { Booleanish, ShortEmits } from '#uitypes';
import type Tooltip from '@components/Tooltip/Tooltip.vue';
import type Popover from '@components/Popover/Popover.vue';
import { useTooltip } from '@components/Tooltip/useTooltip';
import { usePopover } from '@components/Popover/usePopover';
import { useTeleport } from '@composables/useTeleport';
import type { UseFloatingReturn } from '@composables/useFloating';
import type { ButtonEvents, ButtonProps } from './Button.types';
export function useButton(
props: ButtonProps,
emit: ShortEmits<ButtonEvents>,
className: string,
reference: Ref<HTMLButtonElement | null>,
tooltipRef: Ref<InstanceType<typeof Tooltip> | null>,
popoverRef: Ref<InstanceType<typeof Popover> | null>,
) {
const tooltipOptions = computed(() => ({
placement: props.tooltipOptions?.placement ?? 'top',
...(!props.tooltipOptions?.autoupdatePosition ? { whileElementsMounted: undefined } : {}),
}));
const tooltip = useTooltip(reference, tooltipRef, tooltipOptions.value);
const popover = usePopover(reference, popoverRef);
const teleport = useTeleport();
const attributes = useButtonAttributes(props, className, popover);
const handlers = useButtonHandlers(emit, tooltip, popover);
return {
/** HTML Attributes. */
attributes,
/** Special handlers to be attached to the button. */
handlers,
/** Teleport parameters for tooltip. */
teleport,
/** Tooltip. */
tooltip: reactive(tooltip),
/** Popover. */
popover: reactive(popover),
};
}
function useButtonAttributes(props: ButtonProps, className: string, popover: UseFloatingReturn) {
const attrs = useAttrs();
const slots = useSlots();
const id = computed(() => (attrs['id'] as string | undefined) ?? randomId('btn'));
const ariaLabel = computed(() => attrs['aria-label'] as string | undefined);
const tabindex = computed(() => attrs['tabindex'] as number | undefined);
const popoverId = computed(() => `${id.value}-popover`);
const classes = computed(() => [attrs.class ?? '', className, { 'icon-only': props.iconOnly }]);
const ariaControls = computed(() =>
slots.popover ? popoverId.value : (attrs['aria-controls'] as string),
);
const ariaExpanded = computed(
() => (slots.popover ? popover.isOpen : attrs['aria-expanded']) as Booleanish,
);
return reactive({
id,
ariaLabel,
ariaControls,
ariaExpanded,
tabindex,
popoverId,
title: props.disabled && typeof props.disabled === 'string' ? props.disabled : undefined,
class: classes,
});
}
function useButtonHandlers(
emit: ShortEmits<ButtonEvents>,
tooltip: UseFloatingReturn,
popover: UseFloatingReturn,
) {
const handleClick = () => {
emit('click');
popover.toggle();
};
const handleEscape = ($event: KeyboardEvent) => {
emit('escape', $event);
popover.close();
};
return {
handleClick,
handleEscape,
tooltipHandlers: tooltip.handlers,
};
}