forked from viamrobotics/prime
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Update tabs component in PRIME (viamrobotics#551)
- Loading branch information
Showing
10 changed files
with
218 additions
and
153 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
20 changes: 20 additions & 0 deletions
20
packages/core/src/lib/__tests__/tabs-bar-with-slots.svelte
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<script lang="ts"> | ||
import TabsBar from '$lib/tabs-bar.svelte'; | ||
import Tab from '$lib/tab.svelte'; | ||
</script> | ||
|
||
<TabsBar aria-label="Tab example one"> | ||
<Tab | ||
title="The first tab" | ||
href="#first" | ||
selected | ||
></Tab> | ||
<Tab | ||
title="The second tab" | ||
href="#second" | ||
></Tab> | ||
<Tab | ||
title="The third tab" | ||
href="#third" | ||
></Tab> | ||
</TabsBar> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,47 +1,43 @@ | ||
import { describe, it, expect, vi } from 'vitest'; | ||
import { render, screen, fireEvent } from '@testing-library/svelte'; | ||
import { Tabs } from '$lib'; | ||
import { cxTestArguments, cxTestResults } from './cx-test'; | ||
import { describe, it, expect } from 'vitest'; | ||
import { render, screen } from '@testing-library/svelte'; | ||
import { TabsBar } from '$lib'; | ||
import TabsBarWithSlots from './tabs-bar-with-slots.svelte'; | ||
|
||
describe('Tabs', () => { | ||
it('Renders tabs correctly', () => { | ||
render(Tabs, { tabs: ['Tab 1', 'Tab 2', 'Tab 3'], selected: 'Tab 1' }); | ||
expect(screen.getByText('Tab 1')).toBeVisible(); | ||
expect(screen.getByText('Tab 2')).toBeVisible(); | ||
expect(screen.getByText('Tab 3')).toBeVisible(); | ||
describe('TabsBar renders correctly', () => { | ||
it('Renders rest props and default variant', () => { | ||
render(TabsBar, { 'aria-label': 'Tab example one' }); | ||
expect(screen.getByRole('navigation')).toHaveAccessibleName( | ||
'Tab example one' | ||
); | ||
expect(screen.getByRole('navigation')).toHaveClass( | ||
'h-10 bg-medium tracking-wide sm:px-2 flex items-center font-roboto-mono' | ||
); | ||
}); | ||
|
||
it('Marks the selected tab correctly', () => { | ||
render(Tabs, { tabs: ['Tab 1', 'Tab 2', 'Tab 3'], selected: 'Tab 1' }); | ||
expect(screen.getByRole('button', { name: 'Tab 1' })).toHaveClass( | ||
'bg-white border border-x-border-2 border-t-border-2 border-b-white font-semibold' | ||
it('Renders secondary variant', () => { | ||
render(TabsBar, { variant: 'secondary' }); | ||
expect(screen.getByRole('navigation')).toHaveClass( | ||
'flex items-center font-roboto-mono' | ||
); | ||
}); | ||
|
||
it('Switches to another tab on click', async () => { | ||
const { component } = render(Tabs, { | ||
tabs: ['Tab 1', 'Tab 2', 'Tab 3'], | ||
selected: 'Tab 1', | ||
}); | ||
const onInput = vi.fn(); | ||
component.$on('input', onInput); | ||
it('Renders TabsBar with Tab components in slots', () => { | ||
render(TabsBarWithSlots); | ||
|
||
await fireEvent.click(screen.getByText('Tab 2')); | ||
expect(onInput).toHaveBeenCalledOnce(); | ||
await fireEvent.click(screen.getByText('Tab 2')); | ||
expect(onInput).toHaveBeenCalledWith( | ||
expect.objectContaining({ detail: { value: 'Tab 2' } }) | ||
); | ||
}); | ||
expect(screen.getByText('The first tab')).toBeInTheDocument(); | ||
expect(screen.getByText('The second tab')).toBeInTheDocument(); | ||
expect(screen.getByText('The third tab')).toBeInTheDocument(); | ||
|
||
it('Renders with the passed cx classes', () => { | ||
render(Tabs, { | ||
tabs: ['Tab 1', 'Tab 2', 'Tab 3'], | ||
selected: 'Tab 1', | ||
cx: cxTestArguments, | ||
}); | ||
expect(screen.getByText('Tab 1').parentElement?.parentElement).toHaveClass( | ||
cxTestResults | ||
); | ||
const firstTab = screen.getByText('The first tab'); | ||
const secondTab = screen.getByText('The second tab'); | ||
const thirdTab = screen.getByText('The third tab'); | ||
|
||
expect(firstTab.closest('a')).toHaveAttribute('href', '#first'); | ||
expect(secondTab.closest('a')).toHaveAttribute('href', '#second'); | ||
expect(thirdTab.closest('a')).toHaveAttribute('href', '#third'); | ||
|
||
expect(firstTab).toHaveAttribute('aria-current', 'page'); | ||
expect(secondTab).toHaveAttribute('aria-current', 'false'); | ||
expect(thirdTab).toHaveAttribute('aria-current', 'false'); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
<!-- | ||
@component | ||
A clickable element that allows the user to navigate to another page or area. | ||
```svelte | ||
<Tab | ||
title='The first tab' | ||
href="#first" | ||
selected | ||
/> | ||
``` | ||
--> | ||
<svelte:options immutable /> | ||
|
||
<script lang="ts"> | ||
import cx from 'classnames'; | ||
import type { HTMLAttributes } from 'svelte/elements'; | ||
import { CONTEXT_KEY } from './tabs-bar.svelte'; | ||
import { getContext } from 'svelte'; | ||
import type { Writable } from 'svelte/store'; | ||
interface $$Props extends HTMLAttributes<HTMLElement> { | ||
href: string; | ||
title: string; | ||
selected?: boolean; | ||
class?: string; | ||
} | ||
/** The tab's href. */ | ||
export let href: $$Props['href']; | ||
/** The tab's title. */ | ||
export let title: $$Props['title']; | ||
//* The tab's state */ | ||
export let selected: $$Props['selected'] = false; | ||
const variant = getContext<Writable<'primary' | 'secondary'>>(CONTEXT_KEY); | ||
let className = ''; | ||
export { className as class }; | ||
</script> | ||
|
||
<a | ||
{href} | ||
aria-current={selected ? 'page' : false} | ||
class={cx( | ||
'flex h-8 px-4 text-sm leading-8 text-default hover:bg-ghost-light hover:text-default focus:bg-ghost-light focus:text-default active:bg-ghost-medium', | ||
{ | ||
'font-semibold': selected, | ||
uppercase: $variant === 'primary', | ||
'border-b border-gray-3 first-letter:capitalize': | ||
$variant === 'secondary', | ||
'border-b-black': selected && $variant === 'secondary', | ||
}, | ||
className | ||
)} | ||
> | ||
{title} | ||
</a> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
<!-- | ||
@component | ||
A nav container with optional variant: 'primary' | 'secondary' | ||
```svelte | ||
<TabsBar variant='secondary'> | ||
<Tab | ||
title='The first tab' | ||
href="#first" | ||
isSelected='true' | ||
/> | ||
<Tab | ||
title='The second tab' | ||
href="#second" | ||
isSelected='false' | ||
/> | ||
<Tab | ||
title='The third tab' | ||
href="#third" | ||
isSelected='false' | ||
/> | ||
</TabsBar> | ||
``` | ||
--> | ||
<svelte:options immutable /> | ||
|
||
<script context="module"> | ||
export const CONTEXT_KEY = Symbol('tabs-bar-context'); | ||
</script> | ||
|
||
<script lang="ts"> | ||
import { setContext } from 'svelte'; | ||
import cx from 'classnames'; | ||
import type { HTMLAttributes } from 'svelte/elements'; | ||
import { writable } from 'svelte/store'; | ||
interface $$Props extends HTMLAttributes<HTMLElement> { | ||
variant?: 'primary' | 'secondary'; | ||
class?: string; | ||
} | ||
/** The tab style variant */ | ||
export let variant: $$Props['variant'] = 'primary'; | ||
const context = writable<$$Props['variant']>(variant); | ||
$: context.set(variant); | ||
setContext(CONTEXT_KEY, context); | ||
let className = ''; | ||
export { className as class }; | ||
</script> | ||
|
||
<nav | ||
{...$$restProps} | ||
class={cx( | ||
{ | ||
'h-10 bg-medium tracking-wide sm:px-2': variant === 'primary', | ||
}, | ||
className, | ||
'flex items-center font-roboto-mono' | ||
)} | ||
> | ||
<slot /> | ||
</nav> |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.