diff --git a/packages/core/package.json b/packages/core/package.json
index 5a35cb8b..7b302bef 100644
--- a/packages/core/package.json
+++ b/packages/core/package.json
@@ -1,6 +1,6 @@
{
"name": "@viamrobotics/prime-core",
- "version": "0.0.139",
+ "version": "0.0.140",
"publishConfig": {
"access": "public"
},
diff --git a/packages/core/src/lib/__tests__/tabs-bar-with-slots.svelte b/packages/core/src/lib/__tests__/tabs-bar-with-slots.svelte
new file mode 100644
index 00000000..1f75cfb2
--- /dev/null
+++ b/packages/core/src/lib/__tests__/tabs-bar-with-slots.svelte
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
diff --git a/packages/core/src/lib/__tests__/tabs.spec.ts b/packages/core/src/lib/__tests__/tabs.spec.ts
index 47b76352..dfd28cf6 100644
--- a/packages/core/src/lib/__tests__/tabs.spec.ts
+++ b/packages/core/src/lib/__tests__/tabs.spec.ts
@@ -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');
});
});
diff --git a/packages/core/src/lib/index.ts b/packages/core/src/lib/index.ts
index 21d61a32..c9694658 100644
--- a/packages/core/src/lib/index.ts
+++ b/packages/core/src/lib/index.ts
@@ -64,7 +64,8 @@ export { default as TableHeaderCell } from './table/table-header-cell.svelte';
export { default as TableBody } from './table/table-body.svelte';
export { default as TableRow } from './table/table-row.svelte';
export { default as TableCell } from './table/table-cell.svelte';
-export { default as Tabs } from './tabs.svelte';
+export { default as TabsBar } from './tabs-bar.svelte';
+export { default as Tab } from './tab.svelte';
export { default as ToggleButtons } from './toggle-buttons.svelte';
export {
diff --git a/packages/core/src/lib/tab.svelte b/packages/core/src/lib/tab.svelte
new file mode 100644
index 00000000..65e14fac
--- /dev/null
+++ b/packages/core/src/lib/tab.svelte
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+ {title}
+
diff --git a/packages/core/src/lib/tabs-bar.svelte b/packages/core/src/lib/tabs-bar.svelte
new file mode 100644
index 00000000..f56cd711
--- /dev/null
+++ b/packages/core/src/lib/tabs-bar.svelte
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
diff --git a/packages/core/src/lib/tabs.svelte b/packages/core/src/lib/tabs.svelte
deleted file mode 100644
index 48ea3ea5..00000000
--- a/packages/core/src/lib/tabs.svelte
+++ /dev/null
@@ -1,64 +0,0 @@
-
-
-
-
-
-
- {#each tabs as tab, index (tab)}
-
- {/each}
-
diff --git a/packages/core/src/routes/+page.svelte b/packages/core/src/routes/+page.svelte
index 03f57a24..56c7ac99 100644
--- a/packages/core/src/routes/+page.svelte
+++ b/packages/core/src/routes/+page.svelte
@@ -15,7 +15,8 @@ import {
Pill,
Switch,
Radio,
- Tabs,
+ TabsBar,
+ Tab,
Tooltip,
TooltipContainer,
TooltipTarget,
@@ -1601,21 +1602,41 @@ const onHoverDelayMsInput = (event: Event) => {
Tabs
-
-
-
-
+
+
+
+
+
+
-
+
+
+
+
+
diff --git a/packages/storybook/src/stories/tabs.mdx b/packages/storybook/src/stories/tabs.mdx
deleted file mode 100644
index cf0296b0..00000000
--- a/packages/storybook/src/stories/tabs.mdx
+++ /dev/null
@@ -1,16 +0,0 @@
-import { Canvas, Meta, Story } from '@storybook/addon-docs';
-import * as TabsStories from './tabs.stories.svelte';
-
-
-
-# Tabs
-
-A clickable element that allows the user to navigate to another page or area.
-
-```ts
-import { Tabs } from '@viamrobotics/prime-core';
-```
-
-
diff --git a/packages/storybook/src/stories/tabs.stories.svelte b/packages/storybook/src/stories/tabs.stories.svelte
deleted file mode 100644
index 9549758e..00000000
--- a/packages/storybook/src/stories/tabs.stories.svelte
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
-
- {
- tab = event.detail.value;
- }}
- />
- Selected {tab}
-