From 8e032e7947a4dd39a700ab8d0e7516618e3aa552 Mon Sep 17 00:00:00 2001 From: Michael Cousins Date: Tue, 7 Nov 2023 16:58:36 -0500 Subject: [PATCH 1/5] Replace Modal.isOpen with controlled boolean --- packages/core/package.json | 2 +- packages/core/src/lib/__tests__/modal.spec.ts | 63 ++++++++------- packages/core/src/lib/modal.svelte | 28 +++---- packages/core/src/routes/+page.svelte | 77 ++++++++++--------- 4 files changed, 92 insertions(+), 78 deletions(-) diff --git a/packages/core/package.json b/packages/core/package.json index 3e2fc1cd..0115180e 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@viamrobotics/prime-core", - "version": "0.0.58", + "version": "0.0.59", "publishConfig": { "access": "public" }, diff --git a/packages/core/src/lib/__tests__/modal.spec.ts b/packages/core/src/lib/__tests__/modal.spec.ts index a73b62a6..b27cb4e3 100644 --- a/packages/core/src/lib/__tests__/modal.spec.ts +++ b/packages/core/src/lib/__tests__/modal.spec.ts @@ -1,63 +1,72 @@ -import { describe, it, expect, beforeEach } from 'vitest'; +import { describe, it, expect, vi } from 'vitest'; import { render, screen, within } from '@testing-library/svelte'; import userEvent from '@testing-library/user-event'; +import type { ComponentProps } from 'svelte'; import Modal from '../modal.svelte'; -import { writable, get } from 'svelte/store'; describe('Modal', () => { - let isOpen = writable(true); + const onClose = vi.fn(); - beforeEach(() => { - isOpen = writable(true); + const renderSubject = (props: ComponentProps) => { + const { component } = render(Modal, props); + component.$on('close', onClose); + }; + + it('should be visible if open is true ', () => { + renderSubject({ isOpen: true }); + + const modal = screen.queryByRole('dialog'); + + expect(modal).toBeInTheDocument(); + expect(modal).toHaveAttribute('aria-modal', 'true'); + expect(onClose).not.toHaveBeenCalled(); + }); + + it('should not be visible if open is false', () => { + renderSubject({ isOpen: false }); + + const modal = screen.queryByRole('dialog'); + + expect(modal).not.toBeInTheDocument(); + expect(onClose).not.toHaveBeenCalled(); }); it('should close modal when close icon button is clicked', async () => { - render(Modal, { isOpen }); const user = userEvent.setup(); + renderSubject({ isOpen: true }); const modal = screen.getByRole('dialog'); const closeButton = within(modal).getByRole('button', { name: /close/iu }); await user.click(closeButton); - - expect(get(isOpen)).toBe(false); + expect(onClose).toHaveBeenCalledOnce(); }); it('should close modal when clicked outside the modal', async () => { - render(Modal, { isOpen }); const user = userEvent.setup(); + renderSubject({ isOpen: true }); const modal = screen.getByRole('dialog'); await user.click(modal.parentElement!); - expect(get(isOpen)).toBe(false); - }); - - it('if open is true, modal should be visible', () => { - render(Modal, { isOpen }); - const modal = screen.queryByRole('dialog'); - expect(modal).toBeInTheDocument(); - expect(modal).toHaveAttribute('aria-modal', 'true'); - }); - - it('if open is false, modal should not be visible', () => { - isOpen.set(false); - render(Modal, { isOpen }); - const modal = screen.queryByRole('dialog'); - expect(modal).not.toBeInTheDocument(); + expect(onClose).toHaveBeenCalledOnce(); }); it('should close modal when escape key is pressed', async () => { - render(Modal, { isOpen }); const user = userEvent.setup(); + renderSubject({ isOpen: true }); + await user.keyboard('{Escape}'); - expect(get(isOpen)).toBe(false); + + expect(onClose).toHaveBeenCalledOnce(); }); it('should focus on heading element on mount', () => { - render(Modal, { isOpen }); + render(Modal, { isOpen: true }); + const modal = screen.getByRole('dialog'); const heading = within(modal).getByRole('heading'); + expect(heading).toHaveFocus(); }); }); diff --git a/packages/core/src/lib/modal.svelte b/packages/core/src/lib/modal.svelte index 047ff011..34200291 100644 --- a/packages/core/src/lib/modal.svelte +++ b/packages/core/src/lib/modal.svelte @@ -26,28 +26,24 @@ Creates a modal overlay. -{#if $isOpen} +{#if isOpen}