@viamrobotics/prime-core
Advanced tools
@@ -12,3 +12,3 @@ import { beforeEach, describe, expect, it } from 'vitest'; | ||
| render(Subject); | ||
| const control = screen.getByRole('button', { name: /open/iu }); | ||
| const control = screen.getByRole('button', { name: /cool menu/iu }); | ||
| let menu = screen.queryByRole('menu'); | ||
@@ -31,3 +31,3 @@ let item = screen.queryByRole('menuitem'); | ||
| render(Subject); | ||
| const control = screen.getByRole('button', { name: /open/iu }); | ||
| const control = screen.getByRole('button', { name: /cool menu/iu }); | ||
| expect(control).toHaveAttribute('aria-haspopup', 'menu'); | ||
@@ -38,2 +38,3 @@ expect(control).toHaveAttribute('aria-expanded', 'false'); | ||
| expect(menu).toHaveAttribute('id', expect.any(String)); | ||
| expect(menu).toHaveAccessibleName(/cool menu/iu); | ||
| expect(control).toHaveAttribute('aria-controls', menu.id); | ||
@@ -44,3 +45,3 @@ expect(control).toHaveAttribute('aria-expanded', 'true'); | ||
| render(Subject); | ||
| const control = screen.getByRole('button', { name: /open/iu }); | ||
| const control = screen.getByRole('button', { name: /cool menu/iu }); | ||
| await user.click(control); | ||
@@ -53,3 +54,3 @@ await user.keyboard('{Escape}'); | ||
| render(Subject); | ||
| const control = screen.getByRole('button', { name: /open/iu }); | ||
| const control = screen.getByRole('button', { name: /cool menu/iu }); | ||
| const outside = screen.getByTestId('outside-element'); | ||
@@ -63,3 +64,3 @@ await user.click(control); | ||
| render(Subject); | ||
| const control = screen.getByRole('button', { name: /open/iu }); | ||
| const control = screen.getByRole('button', { name: /cool menu/iu }); | ||
| await user.click(control); | ||
@@ -66,0 +67,0 @@ const item = screen.getByRole('menuitem'); |
| <script>import FloatingMenu from "../floating-menu.svelte"; | ||
| import ContextMenuItem from "../context-menu-item.svelte"; | ||
| let isOpen = false; | ||
| const handleChange = (nextIsOpen) => isOpen = nextIsOpen; | ||
| </script> | ||
| <FloatingMenu> | ||
| <span | ||
| slot="control" | ||
| let:isOpen | ||
| > | ||
| <FloatingMenu | ||
| {isOpen} | ||
| label="cool menu" | ||
| onChange={handleChange} | ||
| > | ||
| <span slot="control"> | ||
| {isOpen ? 'close' : 'open'} | ||
| </span> | ||
| <svelte:fragment | ||
| slot="items" | ||
| let:closeMenu | ||
| > | ||
| <ContextMenuItem on:click={closeMenu}>item</ContextMenuItem> | ||
| <svelte:fragment slot="items"> | ||
| <ContextMenuItem on:click={() => (isOpen = false)}>item</ContextMenuItem> | ||
| </svelte:fragment> | ||
| </FloatingMenu> | ||
| <span data-testid="outside-element" /> |
@@ -16,2 +16,4 @@ <!-- | ||
| export let id; | ||
| export let label = void 0; | ||
| export let labelledBy = void 0; | ||
| let extraClasses = ""; | ||
@@ -23,2 +25,4 @@ export { extraClasses as cx }; | ||
| {id} | ||
| aria-label={label} | ||
| aria-labelledby={labelledBy} | ||
| role="menu" | ||
@@ -25,0 +29,0 @@ class={cx( |
@@ -6,2 +6,4 @@ import { SvelteComponent } from "svelte"; | ||
| /** ID attribute of the menu element. */ id: string; | ||
| /** Accessible label of the menu. */ label?: string | undefined; | ||
| /** ID of the element ID that labels the menu. */ labelledBy?: string | undefined; | ||
| /** Additional CSS classes to pass to the menu. */ cx?: cx.Argument; | ||
@@ -8,0 +10,0 @@ }; |
@@ -6,2 +6,5 @@ <script>import cx from "classnames"; | ||
| import ContextMenu from "./context-menu.svelte"; | ||
| export let isOpen; | ||
| export let label = void 0; | ||
| export let describedBy = void 0; | ||
| export let placement = "bottom-start"; | ||
@@ -11,9 +14,10 @@ export let offset = 0; | ||
| export let menuCX = ""; | ||
| export let onChange; | ||
| const buttonID = uniqueId("floating-menu-control"); | ||
| const menuID = uniqueId("floating-menu"); | ||
| const style = floatingStyle(); | ||
| let isOpen = false; | ||
| const openMenu = () => onChange(true); | ||
| const closeMenu = () => onChange(false); | ||
| let controlElement; | ||
| let menuElement; | ||
| const openMenu = () => isOpen = true; | ||
| const closeMenu = () => isOpen = false; | ||
| const handleClickOutside = (element) => { | ||
@@ -34,5 +38,6 @@ if (!controlElement?.contains(element)) { | ||
| <svelte:document on:keydown={isOpen ? handleEscape : undefined} /> | ||
| <svelte:window on:keydown={isOpen ? handleEscape : undefined} /> | ||
| <button | ||
| id={buttonID} | ||
| class={cx(buttonCX)} | ||
@@ -42,9 +47,8 @@ aria-haspopup="menu" | ||
| aria-expanded={isOpen} | ||
| aria-label={label} | ||
| aria-describedby={describedBy} | ||
| on:click={isOpen ? closeMenu : openMenu} | ||
| bind:this={controlElement} | ||
| > | ||
| <slot | ||
| name="control" | ||
| {isOpen} | ||
| /> | ||
| <slot name="control" /> | ||
| </button> | ||
@@ -63,10 +67,8 @@ | ||
| id={menuID} | ||
| labelledBy={buttonID} | ||
| cx={menuCX} | ||
| > | ||
| <slot | ||
| name="items" | ||
| {closeMenu} | ||
| /> | ||
| <slot name="items" /> | ||
| </ContextMenu> | ||
| </div> | ||
| {/if} |
@@ -6,2 +6,5 @@ import { SvelteComponent } from "svelte"; | ||
| props: { | ||
| isOpen: boolean; | ||
| label?: string | undefined; | ||
| describedBy?: string | undefined; | ||
| placement?: FloatingMenuPlacement; | ||
@@ -11,2 +14,3 @@ offset?: number; | ||
| menuCX?: cx.Argument; | ||
| onChange: (isOpen: boolean) => unknown; | ||
| }; | ||
@@ -17,8 +21,4 @@ events: { | ||
| slots: { | ||
| control: { | ||
| isOpen: boolean; | ||
| }; | ||
| items: { | ||
| closeMenu: () => boolean; | ||
| }; | ||
| control: {}; | ||
| items: {}; | ||
| }; | ||
@@ -25,0 +25,0 @@ }; |
+1
-1
| { | ||
| "name": "@viamrobotics/prime-core", | ||
| "version": "0.0.66", | ||
| "version": "0.0.67", | ||
| "publishConfig": { | ||
@@ -5,0 +5,0 @@ "access": "public" |
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
305999
0.23%5392
0.06%