File size: 2,711 Bytes
2409829
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
<script lang="ts">
	import type { MenuDirection } from "@graphite/messages";
	import { type IconName, type PopoverButtonStyle } from "@graphite/utility-functions/icons";

	import FloatingMenu from "@graphite/components/layout/FloatingMenu.svelte";
	import LayoutRow from "@graphite/components/layout/LayoutRow.svelte";
	import IconButton from "@graphite/components/widgets/buttons/IconButton.svelte";
	import IconLabel from "@graphite/components/widgets/labels/IconLabel.svelte";

	export let style: PopoverButtonStyle = "DropdownArrow";
	export let menuDirection: MenuDirection = "Bottom";
	export let icon: IconName | undefined = undefined;
	export let tooltip: string | undefined = undefined;
	export let disabled = false;
	export let popoverMinWidth = 1;

	// Callbacks
	export let action: (() => void) | undefined = undefined;

	let open = false;

	function onClick() {
		open = true;
		action?.();
	}
</script>

<LayoutRow class="popover-button" classes={{ "has-icon": icon !== undefined, "direction-top": menuDirection === "Top" }}>
	<IconButton class="dropdown-icon" classes={{ open }} {disabled} action={() => onClick()} icon={style || "DropdownArrow"} size={16} {tooltip} data-floating-menu-spawner />
	{#if icon !== undefined}
		<IconLabel class="descriptive-icon" classes={{ open }} {disabled} {icon} {tooltip} />
	{/if}

	<FloatingMenu {open} on:open={({ detail }) => (open = detail)} minWidth={popoverMinWidth} type="Popover" direction={menuDirection || "Bottom"}>
		<slot />
	</FloatingMenu>
</LayoutRow>

<style lang="scss" global>
	.popover-button {
		position: relative;
		width: 16px;
		height: 24px;
		flex: 0 0 auto;

		&.has-icon {
			width: 36px;

			.dropdown-icon {
				padding-left: calc(36px - 16px);
				box-sizing: content-box;
			}

			&.direction-top .dropdown-icon .icon-label {
				transform: rotate(180deg);
			}
		}

		.dropdown-icon {
			width: 16px;
			height: 100%;
			padding: 0;
			border: none;
			border-radius: 2px;
			fill: var(--color-e-nearwhite);

			&:hover:not(.disabled),
			&.open:not(.disabled) {
				background: var(--color-5-dullgray);
			}
		}

		.descriptive-icon {
			width: 16px;
			height: 16px;
			margin: auto 0;
			margin-left: calc(-16px - 16px);
			pointer-events: none;
		}

		.floating-menu {
			left: 50%;
			bottom: 0;

			.floating-menu-content > :first-child:not(:has(:not(.text-label))),
			.floating-menu-content > :first-child:not(:has(:not(.checkbox-input))) {
				margin-top: -8px;
			}

			.floating-menu-content > :last-child:not(:has(:not(.text-label))),
			.floating-menu-content > :last-child:not(:has(:not(.checkbox-input))) {
				margin-bottom: -8px;
			}
		}

		&.direction-top .floating-menu {
			bottom: 100%;
		}
	}
</style>