Skip to content

Commit

Permalink
fix: adds menu component #107
Browse files Browse the repository at this point in the history
  • Loading branch information
KovaCro committed Jan 2, 2024
1 parent 27966d5 commit fcb9877
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 0 deletions.
34 changes: 34 additions & 0 deletions docs/docs/menu.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Menu

### Description

`<jp-menu>` is a floating panel with options.

### Attributes

| **Name** | **Required** | **Type** | **Description** |
| :----: | :----: | :----: | :---: |
| label | | `string` (HTML) | main button content |

### Slots

Default slot is list of options (content of menu).


### Methods

This component does not have any methods.


### Events

This component does not have any events.


### Demo

<jp-menu>
<button style="width: 200px;" onClick={() => alert('first')}>First item</button>
<button style="width: 200px;" onClick={() => alert('second')}>Second item</button>
<button style="width: 200px;" onClick={() => alert('third')}>Third item</button>
</jp-menu>
1 change: 1 addition & 0 deletions packages/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export default () => {
import('./src/tree/node.wc.svelte');
import('./src/tree/node-draggable.wc.svelte');
import('./src/tree/structure');
import('./src/menu/menu.wc.svelte');
import('./src/tooltip/tooltip.wc.svelte');
import('./src/form-fields/slider.wc.svelte');
import('./src/form-fields/file-list.wc.svelte');
Expand Down
73 changes: 73 additions & 0 deletions packages/lib/src/menu/menu.wc.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<svelte:options
customElement={{
tag: 'jp-menu',
shadow: 'open'
}}
/>

<script lang="ts">
export let label = 'Menu';
// Default needs to be invisible rather than unrendered because of .offsetHeight
// It's pushed left by default so it doesn't expand the document size when not open
let menuStyle = 'opacity: 0; left: -100vw;';
let menuEl;
let bindingEl;
let open = false;
function toggleMenu() {
open = !open;
if (!open) {
menuStyle = 'opacity: 0; left: -100vw;';
} else {
const rect = bindingEl.getBoundingClientRect();
const availableSpaceBelow = window.innerHeight - rect.bottom;
const dropdownHeight = menuEl.offsetHeight;
const availableSpaceRight = window.innerWidth - rect.left;
const dropleftWidth = menuEl.offsetWidth;
menuStyle = `
top: ${availableSpaceBelow < dropdownHeight ? -menuEl.offsetHeight : rect.height}px;
left: ${availableSpaceRight < dropleftWidth ? -menuEl.offsetWidth + rect.width : '0'}px;
`;
}
}
</script>

<div class="wrapper">
<button class="menu-button" on:click={() => toggleMenu()} bind:this={bindingEl}>
{@html label}
</button>

<div class="menu" bind:this={menuEl} style={menuStyle}>
<slot />
</div>
</div>

<style>
.wrapper {
display: inline-block;
position: relative;
}
.menu-button {
cursor: pointer;
background-color: transparent;
border: none;
padding: 10px;
font-weight: 600;
}
.menu-button:hover {
background-color: var(--background-tertiary);
}
.menu {
background-color: var(--background-primary);
position: absolute;
display: flex;
flex-direction: column;
overflow: hidden;
z-index: 100;
max-width: 280px;
padding: 8px 0;
}
</style>

0 comments on commit fcb9877

Please sign in to comment.