@getmicdrop/svelte-components 5.5.4 → 5.5.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/calendar/AboutShow/AboutShow.spec.d.ts +2 -0
- package/dist/calendar/AboutShow/AboutShow.spec.d.ts.map +1 -0
- package/dist/calendar/AboutShow/AboutShow.spec.js +791 -0
- package/dist/calendar/Calendar/MiniMonthCalendar.spec.d.ts +2 -0
- package/dist/calendar/Calendar/MiniMonthCalendar.spec.d.ts.map +1 -0
- package/dist/calendar/Calendar/MiniMonthCalendar.spec.js +1191 -0
- package/dist/calendar/FAQs/FAQs.spec.d.ts +2 -0
- package/dist/calendar/FAQs/FAQs.spec.d.ts.map +1 -0
- package/dist/calendar/FAQs/FAQs.spec.js +238 -0
- package/dist/calendar/MonthSwitcher/MonthSwitcher.spec.d.ts +2 -0
- package/dist/calendar/MonthSwitcher/MonthSwitcher.spec.d.ts.map +1 -0
- package/dist/calendar/MonthSwitcher/MonthSwitcher.spec.js +420 -0
- package/dist/calendar/OrderSummary/OrderSummary.spec.d.ts +2 -0
- package/dist/calendar/OrderSummary/OrderSummary.spec.d.ts.map +1 -0
- package/dist/calendar/OrderSummary/OrderSummary.spec.js +808 -0
- package/dist/calendar/PublicCard/PublicCard.spec.d.ts +2 -0
- package/dist/calendar/PublicCard/PublicCard.spec.d.ts.map +1 -0
- package/dist/calendar/PublicCard/PublicCard.spec.js +301 -0
- package/dist/calendar/ShowCard/ShowCard.spec.d.ts +2 -0
- package/dist/calendar/ShowCard/ShowCard.spec.d.ts.map +1 -0
- package/dist/calendar/ShowCard/ShowCard.spec.js +714 -0
- package/dist/calendar/ShowTimeCard/ShowTimeCard.spec.d.ts +2 -0
- package/dist/calendar/ShowTimeCard/ShowTimeCard.spec.d.ts.map +1 -0
- package/dist/calendar/ShowTimeCard/ShowTimeCard.spec.js +241 -0
- package/dist/components/Layout/Section.spec.d.ts +2 -0
- package/dist/components/Layout/Section.spec.d.ts.map +1 -0
- package/dist/components/Layout/Section.spec.js +149 -0
- package/dist/components/Layout/Sidebar.spec.d.ts +2 -0
- package/dist/components/Layout/Sidebar.spec.d.ts.map +1 -0
- package/dist/components/Layout/Sidebar.spec.js +186 -0
- package/dist/components/Layout/Stack.spec.js +3 -3
- package/dist/constants/formOptions.spec.js +9 -5
- package/dist/datetime/__tests__/format.test.js +1 -1
- package/dist/datetime/__tests__/parse.test.js +1 -1
- package/dist/datetime/__tests__/timezone.test.js +124 -2
- package/dist/datetime/parse.js +1 -1
- package/dist/forms/createFieldTracker.spec.d.ts +2 -0
- package/dist/forms/createFieldTracker.spec.d.ts.map +1 -0
- package/dist/forms/createFieldTracker.spec.js +343 -0
- package/dist/forms/createFormStore.spec.d.ts +2 -0
- package/dist/forms/createFormStore.spec.d.ts.map +1 -0
- package/dist/forms/createFormStore.spec.js +689 -0
- package/dist/forms/createFormStore.svelte.js +0 -1
- package/dist/index.d.ts +4 -112
- package/dist/index.js +4 -190
- package/dist/patterns/data/DataGrid.spec.d.ts +2 -0
- package/dist/patterns/data/DataGrid.spec.d.ts.map +1 -0
- package/dist/patterns/data/DataGrid.spec.js +159 -0
- package/dist/patterns/data/DataList.spec.d.ts +2 -0
- package/dist/patterns/data/DataList.spec.d.ts.map +1 -0
- package/dist/patterns/data/DataList.spec.js +158 -0
- package/dist/patterns/data/DataTable.spec.d.ts +2 -0
- package/dist/patterns/data/DataTable.spec.d.ts.map +1 -0
- package/dist/patterns/data/DataTable.spec.js +196 -0
- package/dist/patterns/forms/FormActions.spec.js +10 -3
- package/dist/patterns/forms/FormGrid.spec.d.ts +2 -0
- package/dist/patterns/forms/FormGrid.spec.d.ts.map +1 -0
- package/dist/patterns/forms/FormGrid.spec.js +125 -0
- package/dist/patterns/forms/FormSection.spec.d.ts +2 -0
- package/dist/patterns/forms/FormSection.spec.d.ts.map +1 -0
- package/dist/patterns/forms/FormSection.spec.js +153 -0
- package/dist/patterns/layout/Sidebar.spec.d.ts +2 -0
- package/dist/patterns/layout/Sidebar.spec.d.ts.map +1 -0
- package/dist/patterns/layout/Sidebar.spec.js +159 -0
- package/dist/patterns/navigation/BottomNav.svelte +4 -4
- package/dist/patterns/navigation/Header.spec.js +33 -24
- package/dist/patterns/page/PageHeader.spec.d.ts +2 -0
- package/dist/patterns/page/PageHeader.spec.d.ts.map +1 -0
- package/dist/patterns/page/PageHeader.spec.js +167 -0
- package/dist/patterns/page/PageLayout.spec.d.ts +2 -0
- package/dist/patterns/page/PageLayout.spec.d.ts.map +1 -0
- package/dist/patterns/page/PageLayout.spec.js +145 -0
- package/dist/patterns/page/PageLoader.spec.js +5 -2
- package/dist/patterns/page/SectionHeader.spec.d.ts +2 -0
- package/dist/patterns/page/SectionHeader.spec.d.ts.map +1 -0
- package/dist/patterns/page/SectionHeader.spec.js +197 -0
- package/dist/presets/badges.spec.d.ts +2 -0
- package/dist/presets/badges.spec.d.ts.map +1 -0
- package/dist/presets/badges.spec.js +172 -0
- package/dist/presets/buttons.spec.d.ts +2 -0
- package/dist/presets/buttons.spec.d.ts.map +1 -0
- package/dist/presets/buttons.spec.js +135 -0
- package/dist/primitives/Accordion/Accordion.spec.d.ts +2 -0
- package/dist/primitives/Accordion/Accordion.spec.d.ts.map +1 -0
- package/dist/primitives/Accordion/Accordion.spec.js +83 -0
- package/dist/primitives/Accordion/AccordionItem.spec.d.ts +2 -0
- package/dist/primitives/Accordion/AccordionItem.spec.d.ts.map +1 -0
- package/dist/primitives/Accordion/AccordionItem.spec.js +661 -0
- package/dist/primitives/Accordion/AccordionItemWrapper.test.svelte +107 -0
- package/dist/primitives/Accordion/AccordionItemWrapper.test.svelte.d.ts +35 -0
- package/dist/primitives/Accordion/AccordionItemWrapper.test.svelte.d.ts.map +1 -0
- package/dist/primitives/Alert/Alert.spec.js +5 -2
- package/dist/primitives/Avatar/Avatar.spec.d.ts +2 -0
- package/dist/primitives/Avatar/Avatar.spec.d.ts.map +1 -0
- package/dist/primitives/Avatar/Avatar.spec.js +211 -0
- package/dist/primitives/Badges/Badge.spec.js +109 -68
- package/dist/primitives/BottomSheet/BottomSheet.spec.js +36 -27
- package/dist/primitives/BottomSheet/BottomSheetWrapper.test.svelte +13 -0
- package/dist/primitives/BottomSheet/BottomSheetWrapper.test.svelte.d.ts +7 -0
- package/dist/primitives/BottomSheet/BottomSheetWrapper.test.svelte.d.ts.map +1 -0
- package/dist/primitives/Breadcrumb/Breadcrumb.spec.js +15 -13
- package/dist/primitives/Breadcrumb/Breadcrumb.svelte +5 -5
- package/dist/primitives/Button/Button.spec.js +83 -71
- package/dist/primitives/Button/ButtonSaveDemo.spec.js +100 -2
- package/dist/primitives/Button/ButtonVariantShowcase.spec.d.ts +2 -0
- package/dist/primitives/Button/ButtonVariantShowcase.spec.d.ts.map +1 -0
- package/dist/primitives/Button/ButtonVariantShowcase.spec.js +202 -0
- package/dist/primitives/Card.spec.js +1 -1
- package/dist/primitives/Checkbox/Checkbox.spec.d.ts +2 -0
- package/dist/primitives/Checkbox/Checkbox.spec.d.ts.map +1 -0
- package/dist/primitives/Checkbox/Checkbox.spec.js +252 -0
- package/dist/primitives/DarkModeToggle.spec.js +84 -51
- package/dist/primitives/Drawer/Drawer.spec.d.ts +2 -0
- package/dist/primitives/Drawer/Drawer.spec.d.ts.map +1 -0
- package/dist/primitives/Drawer/Drawer.spec.js +212 -0
- package/dist/primitives/Dropdown/Dropdown.spec.d.ts +2 -0
- package/dist/primitives/Dropdown/Dropdown.spec.d.ts.map +1 -0
- package/dist/primitives/Dropdown/Dropdown.spec.js +366 -0
- package/dist/primitives/Dropdown/DropdownItem.spec.d.ts +2 -0
- package/dist/primitives/Dropdown/DropdownItem.spec.d.ts.map +1 -0
- package/dist/primitives/Dropdown/DropdownItem.spec.js +182 -0
- package/dist/primitives/Icons/iconTestUtils.spec.d.ts +2 -0
- package/dist/primitives/Icons/iconTestUtils.spec.d.ts.map +1 -0
- package/dist/primitives/Icons/iconTestUtils.spec.js +235 -0
- package/dist/primitives/Input/Input.spec.js +14 -14
- package/dist/primitives/Input/Input.svelte +1 -14
- package/dist/primitives/Input/Input.svelte.d.ts.map +1 -1
- package/dist/primitives/Input/Select.spec.js +11 -17
- package/dist/primitives/Input/Textarea.spec.d.ts +2 -0
- package/dist/primitives/Input/Textarea.spec.d.ts.map +1 -0
- package/dist/primitives/Input/Textarea.spec.js +255 -0
- package/dist/primitives/Label/Label.spec.d.ts +2 -0
- package/dist/primitives/Label/Label.spec.d.ts.map +1 -0
- package/dist/primitives/Label/Label.spec.js +157 -0
- package/dist/primitives/Modal/Modal.spec.js +29 -25
- package/dist/primitives/Modal/ModalTestWrapper.svelte +65 -0
- package/dist/primitives/Modal/ModalTestWrapper.svelte.d.ts +23 -0
- package/dist/primitives/Modal/ModalTestWrapper.svelte.d.ts.map +1 -0
- package/dist/primitives/NumberInput/NumberInput.spec.d.ts +2 -0
- package/dist/primitives/NumberInput/NumberInput.spec.d.ts.map +1 -0
- package/dist/primitives/NumberInput/NumberInput.spec.js +235 -0
- package/dist/primitives/Pagination/Pagination.spec.d.ts +2 -0
- package/dist/primitives/Pagination/Pagination.spec.d.ts.map +1 -0
- package/dist/primitives/Pagination/Pagination.spec.js +266 -0
- package/dist/primitives/Radio/Radio.spec.d.ts +2 -0
- package/dist/primitives/Radio/Radio.spec.d.ts.map +1 -0
- package/dist/primitives/Radio/Radio.spec.js +206 -0
- package/dist/primitives/Skeleton/CardPlaceholder.spec.d.ts +2 -0
- package/dist/primitives/Skeleton/CardPlaceholder.spec.d.ts.map +1 -0
- package/dist/primitives/Skeleton/CardPlaceholder.spec.js +156 -0
- package/dist/primitives/Skeleton/ImagePlaceholder.spec.d.ts +2 -0
- package/dist/primitives/Skeleton/ImagePlaceholder.spec.d.ts.map +1 -0
- package/dist/primitives/Skeleton/ImagePlaceholder.spec.js +120 -0
- package/dist/primitives/Skeleton/ListPlaceholder.spec.d.ts +2 -0
- package/dist/primitives/Skeleton/ListPlaceholder.spec.d.ts.map +1 -0
- package/dist/primitives/Skeleton/ListPlaceholder.spec.js +220 -0
- package/dist/primitives/Skeleton/Skeleton.spec.d.ts +2 -0
- package/dist/primitives/Skeleton/Skeleton.spec.d.ts.map +1 -0
- package/dist/primitives/Skeleton/Skeleton.spec.js +173 -0
- package/dist/primitives/Spinner/Spinner.spec.js +25 -29
- package/dist/primitives/Tabs/TabItem.spec.d.ts +2 -0
- package/dist/primitives/Tabs/TabItem.spec.d.ts.map +1 -0
- package/dist/primitives/Tabs/TabItem.spec.js +130 -0
- package/dist/primitives/Tabs/Tabs.spec.d.ts +2 -0
- package/dist/primitives/Tabs/Tabs.spec.d.ts.map +1 -0
- package/dist/primitives/Tabs/Tabs.spec.js +295 -0
- package/dist/primitives/Tabs/TabsWithItems.test.svelte +18 -0
- package/dist/primitives/Tabs/TabsWithItems.test.svelte.d.ts +16 -0
- package/dist/primitives/Tabs/TabsWithItems.test.svelte.d.ts.map +1 -0
- package/dist/primitives/Toggle.spec.js +93 -77
- package/dist/primitives/Typography/Typography.spec.d.ts +2 -0
- package/dist/primitives/Typography/Typography.spec.d.ts.map +1 -0
- package/dist/primitives/Typography/Typography.spec.js +183 -0
- package/dist/primitives/ValidationError.spec.js +1 -1
- package/dist/primitives/index.d.ts +1 -0
- package/dist/primitives/index.js +3 -0
- package/dist/recipes/CropImage/CropImage.spec.js +1 -9
- package/dist/recipes/ImageUploader/ImageUploader.spec.d.ts +2 -0
- package/dist/recipes/ImageUploader/ImageUploader.spec.d.ts.map +1 -0
- package/dist/recipes/ImageUploader/ImageUploader.spec.js +1351 -0
- package/dist/recipes/SuperLogin/SuperLogin.spec.d.ts +2 -0
- package/dist/recipes/SuperLogin/SuperLogin.spec.d.ts.map +1 -0
- package/dist/recipes/SuperLogin/SuperLogin.spec.js +1436 -0
- package/dist/recipes/feedback/EmptyState/EmptyState.spec.d.ts +2 -0
- package/dist/recipes/feedback/EmptyState/EmptyState.spec.d.ts.map +1 -0
- package/dist/recipes/feedback/EmptyState/EmptyState.spec.js +202 -0
- package/dist/recipes/feedback/ErrorDisplay.spec.js +6 -6
- package/dist/recipes/feedback/StatusIndicator/StatusIndicator.spec.js +21 -17
- package/dist/recipes/fields/CheckboxField.spec.d.ts +2 -0
- package/dist/recipes/fields/CheckboxField.spec.d.ts.map +1 -0
- package/dist/recipes/fields/CheckboxField.spec.js +135 -0
- package/dist/recipes/fields/FormField.spec.d.ts +2 -0
- package/dist/recipes/fields/FormField.spec.d.ts.map +1 -0
- package/dist/recipes/fields/FormField.spec.js +159 -0
- package/dist/recipes/fields/RadioGroup.spec.d.ts +2 -0
- package/dist/recipes/fields/RadioGroup.spec.d.ts.map +1 -0
- package/dist/recipes/fields/RadioGroup.spec.js +199 -0
- package/dist/recipes/fields/SelectField.spec.d.ts +2 -0
- package/dist/recipes/fields/SelectField.spec.d.ts.map +1 -0
- package/dist/recipes/fields/SelectField.spec.js +188 -0
- package/dist/recipes/fields/TextareaField.spec.d.ts +2 -0
- package/dist/recipes/fields/TextareaField.spec.d.ts.map +1 -0
- package/dist/recipes/fields/TextareaField.spec.js +205 -0
- package/dist/recipes/fields/ToggleField.spec.d.ts +2 -0
- package/dist/recipes/fields/ToggleField.spec.d.ts.map +1 -0
- package/dist/recipes/fields/ToggleField.spec.js +153 -0
- package/dist/recipes/inputs/MultiSelect.spec.js +4 -3
- package/dist/recipes/inputs/MultiSelect.svelte +10 -3
- package/dist/recipes/inputs/MultiSelect.svelte.d.ts +2 -0
- package/dist/recipes/inputs/MultiSelect.svelte.d.ts.map +1 -1
- package/dist/recipes/inputs/OTPInput.spec.js +52 -39
- package/dist/recipes/inputs/PasswordInput.spec.d.ts +2 -0
- package/dist/recipes/inputs/PasswordInput.spec.d.ts.map +1 -0
- package/dist/recipes/inputs/PasswordInput.spec.js +410 -0
- package/dist/recipes/inputs/PasswordStrengthIndicator/PasswordStrengthIndicator.spec.js +253 -173
- package/dist/recipes/inputs/PasswordStrengthIndicator/TestWrapper.svelte +71 -0
- package/dist/recipes/inputs/PasswordStrengthIndicator/TestWrapper.svelte.d.ts +9 -0
- package/dist/recipes/inputs/PasswordStrengthIndicator/TestWrapper.svelte.d.ts.map +1 -0
- package/dist/recipes/inputs/PlaceAutocomplete/PlaceAutocomplete.spec.js +1246 -300
- package/dist/recipes/inputs/Search.spec.d.ts +2 -0
- package/dist/recipes/inputs/Search.spec.d.ts.map +1 -0
- package/dist/recipes/inputs/Search.spec.js +177 -0
- package/dist/recipes/inputs/SelectDropdown.spec.d.ts +2 -0
- package/dist/recipes/inputs/SelectDropdown.spec.d.ts.map +1 -0
- package/dist/recipes/inputs/SelectDropdown.spec.js +512 -0
- package/dist/recipes/modals/AlertModal.spec.d.ts +2 -0
- package/dist/recipes/modals/AlertModal.spec.d.ts.map +1 -0
- package/dist/recipes/modals/AlertModal.spec.js +432 -0
- package/dist/recipes/modals/ConfirmationModal.spec.js +36 -21
- package/dist/recipes/modals/InputModal.spec.d.ts +2 -0
- package/dist/recipes/modals/InputModal.spec.d.ts.map +1 -0
- package/dist/recipes/modals/InputModal.spec.js +872 -0
- package/dist/recipes/modals/ModalTestWrapper.spec.d.ts +2 -0
- package/dist/recipes/modals/ModalTestWrapper.spec.d.ts.map +1 -0
- package/dist/recipes/modals/ModalTestWrapper.spec.js +502 -0
- package/dist/recipes/modals/StatusModal.spec.d.ts +2 -0
- package/dist/recipes/modals/StatusModal.spec.d.ts.map +1 -0
- package/dist/recipes/modals/StatusModal.spec.js +599 -0
- package/dist/services/ShowService.spec.js +18 -15
- package/dist/stories/ButtonAuditDashboard.spec.d.ts +2 -0
- package/dist/stories/ButtonAuditDashboard.spec.d.ts.map +1 -0
- package/dist/stories/ButtonAuditDashboard.spec.js +913 -0
- package/dist/stories/ButtonAuditReview.spec.d.ts +2 -0
- package/dist/stories/ButtonAuditReview.spec.d.ts.map +1 -0
- package/dist/stories/ButtonAuditReview.spec.js +422 -0
- package/dist/stories/ButtonGridView.spec.d.ts +2 -0
- package/dist/stories/ButtonGridView.spec.d.ts.map +1 -0
- package/dist/stories/ButtonGridView.spec.js +667 -0
- package/dist/stories/ButtonShowcase.spec.d.ts +2 -0
- package/dist/stories/ButtonShowcase.spec.d.ts.map +1 -0
- package/dist/stories/ButtonShowcase.spec.js +499 -0
- package/dist/stories/PatternsGallery.spec.d.ts +2 -0
- package/dist/stories/PatternsGallery.spec.d.ts.map +1 -0
- package/dist/stories/PatternsGallery.spec.js +514 -0
- package/dist/stories/PrimitivesGallery.spec.d.ts +2 -0
- package/dist/stories/PrimitivesGallery.spec.d.ts.map +1 -0
- package/dist/stories/PrimitivesGallery.spec.js +813 -0
- package/dist/stories/RecipesGallery.spec.d.ts +2 -0
- package/dist/stories/RecipesGallery.spec.d.ts.map +1 -0
- package/dist/stories/RecipesGallery.spec.js +299 -0
- package/dist/stripe/useStripeTheme.spec.d.ts +2 -0
- package/dist/stripe/useStripeTheme.spec.d.ts.map +1 -0
- package/dist/stripe/useStripeTheme.spec.js +793 -0
- package/dist/telemetry.d.ts.map +1 -1
- package/dist/telemetry.js +6 -5
- package/dist/telemetry.spec.js +495 -12
- package/dist/tokens/__tests__/colors.test.d.ts +2 -0
- package/dist/tokens/__tests__/colors.test.d.ts.map +1 -0
- package/dist/tokens/__tests__/colors.test.js +152 -0
- package/dist/tokens/__tests__/radius.test.d.ts +2 -0
- package/dist/tokens/__tests__/radius.test.d.ts.map +1 -0
- package/dist/tokens/__tests__/radius.test.js +118 -0
- package/dist/tokens/__tests__/shadows.test.d.ts +2 -0
- package/dist/tokens/__tests__/shadows.test.d.ts.map +1 -0
- package/dist/tokens/__tests__/shadows.test.js +105 -0
- package/dist/tokens/__tests__/spacing.test.js +11 -8
- package/dist/tokens/__tests__/typography.test.d.ts +2 -0
- package/dist/tokens/__tests__/typography.test.d.ts.map +1 -0
- package/dist/tokens/__tests__/typography.test.js +156 -0
- package/dist/tokens/__tests__/z-index.test.d.ts +2 -0
- package/dist/tokens/__tests__/z-index.test.d.ts.map +1 -0
- package/dist/tokens/__tests__/z-index.test.js +121 -0
- package/dist/utils/apiConfig.spec.js +102 -1
- package/dist/utils/formatters.spec.d.ts +2 -0
- package/dist/utils/formatters.spec.d.ts.map +1 -0
- package/dist/utils/formatters.spec.js +82 -0
- package/dist/utils/transitions.spec.d.ts +2 -0
- package/dist/utils/transitions.spec.d.ts.map +1 -0
- package/dist/utils/transitions.spec.js +130 -0
- package/package.json +8 -3
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/svelte';
|
|
2
|
+
import { expect, describe, test } from 'vitest';
|
|
3
|
+
import ListPlaceholder from './ListPlaceholder.svelte';
|
|
4
|
+
|
|
5
|
+
describe('ListPlaceholder Component', () => {
|
|
6
|
+
test('renders a wrapper div', () => {
|
|
7
|
+
const { container } = render(ListPlaceholder);
|
|
8
|
+
expect(container.querySelector('div')).toBeInTheDocument();
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
test('has role status', () => {
|
|
12
|
+
const { container } = render(ListPlaceholder);
|
|
13
|
+
const wrapper = container.querySelector('[role="status"]');
|
|
14
|
+
expect(wrapper).toBeInTheDocument();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
test('has aria-label for accessibility', () => {
|
|
18
|
+
const { container } = render(ListPlaceholder);
|
|
19
|
+
const wrapper = container.querySelector('[aria-label="Loading list"]');
|
|
20
|
+
expect(wrapper).toBeInTheDocument();
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
test('has sr-only loading text', () => {
|
|
24
|
+
render(ListPlaceholder);
|
|
25
|
+
expect(screen.getByText('Loading...')).toBeInTheDocument();
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test('applies custom className', () => {
|
|
29
|
+
const { container } = render(ListPlaceholder, { props: { class: 'custom-list' } });
|
|
30
|
+
const wrapper = container.querySelector('[role="status"]');
|
|
31
|
+
expect(wrapper).toHaveClass('custom-list');
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
describe('ListPlaceholder Items', () => {
|
|
36
|
+
test('default items is 5', () => {
|
|
37
|
+
const { container } = render(ListPlaceholder);
|
|
38
|
+
const listItems = container.querySelectorAll('.flex.items-center.justify-between');
|
|
39
|
+
expect(listItems.length).toBe(5);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test('custom items count', () => {
|
|
43
|
+
const { container } = render(ListPlaceholder, { props: { items: 3 } });
|
|
44
|
+
const listItems = container.querySelectorAll('.flex.items-center.justify-between');
|
|
45
|
+
expect(listItems.length).toBe(3);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
test('items can be 1', () => {
|
|
49
|
+
const { container } = render(ListPlaceholder, { props: { items: 1 } });
|
|
50
|
+
const listItems = container.querySelectorAll('.flex.items-center.justify-between');
|
|
51
|
+
expect(listItems.length).toBe(1);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test('items can be 10', () => {
|
|
55
|
+
const { container } = render(ListPlaceholder, { props: { items: 10 } });
|
|
56
|
+
const listItems = container.querySelectorAll('.flex.items-center.justify-between');
|
|
57
|
+
expect(listItems.length).toBe(10);
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
describe('ListPlaceholder Animation', () => {
|
|
62
|
+
test('animate is true by default', () => {
|
|
63
|
+
const { container } = render(ListPlaceholder);
|
|
64
|
+
const wrapper = container.querySelector('[role="status"]');
|
|
65
|
+
expect(wrapper).toHaveClass('animate-pulse');
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
test('animate false removes pulse', () => {
|
|
69
|
+
const { container } = render(ListPlaceholder, { props: { animate: false } });
|
|
70
|
+
const wrapper = container.querySelector('[role="status"]');
|
|
71
|
+
expect(wrapper).not.toHaveClass('animate-pulse');
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
describe('ListPlaceholder Size', () => {
|
|
76
|
+
test('default size is md (max-w-sm)', () => {
|
|
77
|
+
const { container } = render(ListPlaceholder);
|
|
78
|
+
const wrapper = container.querySelector('[role="status"]');
|
|
79
|
+
expect(wrapper).toHaveClass('max-w-sm');
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
test('size sm applies max-w-xs', () => {
|
|
83
|
+
const { container } = render(ListPlaceholder, { props: { size: 'sm' } });
|
|
84
|
+
const wrapper = container.querySelector('[role="status"]');
|
|
85
|
+
expect(wrapper).toHaveClass('max-w-xs');
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
test('size lg applies max-w-md', () => {
|
|
89
|
+
const { container } = render(ListPlaceholder, { props: { size: 'lg' } });
|
|
90
|
+
const wrapper = container.querySelector('[role="status"]');
|
|
91
|
+
expect(wrapper).toHaveClass('max-w-md');
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
test('size xl applies max-w-lg', () => {
|
|
95
|
+
const { container } = render(ListPlaceholder, { props: { size: 'xl' } });
|
|
96
|
+
const wrapper = container.querySelector('[role="status"]');
|
|
97
|
+
expect(wrapper).toHaveClass('max-w-lg');
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
test('size 2xl applies max-w-xl', () => {
|
|
101
|
+
const { container } = render(ListPlaceholder, { props: { size: '2xl' } });
|
|
102
|
+
const wrapper = container.querySelector('[role="status"]');
|
|
103
|
+
expect(wrapper).toHaveClass('max-w-xl');
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
describe('ListPlaceholder ShowIcon', () => {
|
|
108
|
+
test('showIcon is true by default', () => {
|
|
109
|
+
const { container } = render(ListPlaceholder);
|
|
110
|
+
const svgs = container.querySelectorAll('svg');
|
|
111
|
+
// Should have 5 icons (one per item)
|
|
112
|
+
expect(svgs.length).toBe(5);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
test('showIcon false hides icons', () => {
|
|
116
|
+
const { container } = render(ListPlaceholder, { props: { showIcon: false } });
|
|
117
|
+
const svgs = container.querySelectorAll('svg');
|
|
118
|
+
expect(svgs.length).toBe(0);
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
describe('ListPlaceholder ShowAction', () => {
|
|
123
|
+
test('showAction is true by default', () => {
|
|
124
|
+
const { container } = render(ListPlaceholder);
|
|
125
|
+
// Action buttons have w-12 class
|
|
126
|
+
const actions = container.querySelectorAll('.w-12');
|
|
127
|
+
expect(actions.length).toBe(5);
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
test('showAction false hides action buttons', () => {
|
|
131
|
+
const { container } = render(ListPlaceholder, { props: { showAction: false } });
|
|
132
|
+
const actions = container.querySelectorAll('.w-12');
|
|
133
|
+
expect(actions.length).toBe(0);
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
describe('ListPlaceholder Icon Size', () => {
|
|
138
|
+
test('default icon size is md (w-10 h-10)', () => {
|
|
139
|
+
const { container } = render(ListPlaceholder);
|
|
140
|
+
const icon = container.querySelector('svg');
|
|
141
|
+
expect(icon).toHaveClass('w-10');
|
|
142
|
+
expect(icon).toHaveClass('h-10');
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
test('size sm applies w-8 h-8 to icons', () => {
|
|
146
|
+
const { container } = render(ListPlaceholder, { props: { size: 'sm' } });
|
|
147
|
+
const icon = container.querySelector('svg');
|
|
148
|
+
expect(icon).toHaveClass('w-8');
|
|
149
|
+
expect(icon).toHaveClass('h-8');
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
test('size lg applies w-12 h-12 to icons', () => {
|
|
153
|
+
const { container } = render(ListPlaceholder, { props: { size: 'lg' } });
|
|
154
|
+
const icon = container.querySelector('svg');
|
|
155
|
+
expect(icon).toHaveClass('w-12');
|
|
156
|
+
expect(icon).toHaveClass('h-12');
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
describe('ListPlaceholder Styling', () => {
|
|
161
|
+
test('has padding', () => {
|
|
162
|
+
const { container } = render(ListPlaceholder);
|
|
163
|
+
const wrapper = container.querySelector('[role="status"]');
|
|
164
|
+
expect(wrapper).toHaveClass('p-4');
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
test('has border', () => {
|
|
168
|
+
const { container } = render(ListPlaceholder);
|
|
169
|
+
const wrapper = container.querySelector('[role="status"]');
|
|
170
|
+
expect(wrapper).toHaveClass('border');
|
|
171
|
+
expect(wrapper).toHaveClass('border-gray-200');
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
test('has dividers between items', () => {
|
|
175
|
+
const { container } = render(ListPlaceholder);
|
|
176
|
+
const wrapper = container.querySelector('[role="status"]');
|
|
177
|
+
expect(wrapper).toHaveClass('divide-y');
|
|
178
|
+
expect(wrapper).toHaveClass('divide-gray-200');
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
test('has rounded corners', () => {
|
|
182
|
+
const { container } = render(ListPlaceholder);
|
|
183
|
+
const wrapper = container.querySelector('[role="status"]');
|
|
184
|
+
expect(wrapper).toHaveClass('rounded-lg');
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
test('has shadow', () => {
|
|
188
|
+
const { container } = render(ListPlaceholder);
|
|
189
|
+
const wrapper = container.querySelector('[role="status"]');
|
|
190
|
+
expect(wrapper).toHaveClass('shadow');
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
describe('ListPlaceholder Combinations', () => {
|
|
195
|
+
test('all props together', () => {
|
|
196
|
+
const { container } = render(ListPlaceholder, {
|
|
197
|
+
props: {
|
|
198
|
+
size: 'xl',
|
|
199
|
+
items: 3,
|
|
200
|
+
animate: false,
|
|
201
|
+
showIcon: false,
|
|
202
|
+
showAction: false,
|
|
203
|
+
class: 'my-list'
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
const wrapper = container.querySelector('[role="status"]');
|
|
207
|
+
expect(wrapper).toHaveClass('max-w-lg');
|
|
208
|
+
expect(wrapper).toHaveClass('my-list');
|
|
209
|
+
expect(wrapper).not.toHaveClass('animate-pulse');
|
|
210
|
+
|
|
211
|
+
const listItems = container.querySelectorAll('.flex.items-center.justify-between');
|
|
212
|
+
expect(listItems.length).toBe(3);
|
|
213
|
+
|
|
214
|
+
const svgs = container.querySelectorAll('svg');
|
|
215
|
+
expect(svgs.length).toBe(0);
|
|
216
|
+
|
|
217
|
+
const actions = container.querySelectorAll('.w-12');
|
|
218
|
+
expect(actions.length).toBe(0);
|
|
219
|
+
});
|
|
220
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Skeleton.spec.d.ts","sourceRoot":"","sources":["../../../src/lib/primitives/Skeleton/Skeleton.spec.js"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/svelte';
|
|
2
|
+
import { expect, describe, test } from 'vitest';
|
|
3
|
+
import Skeleton from './Skeleton.svelte';
|
|
4
|
+
|
|
5
|
+
describe('Skeleton Component', () => {
|
|
6
|
+
test('renders a status container', () => {
|
|
7
|
+
const { container } = render(Skeleton);
|
|
8
|
+
expect(container.querySelector('[role="status"]')).toBeInTheDocument();
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
test('has role="status" for accessibility', () => {
|
|
12
|
+
const { container } = render(Skeleton);
|
|
13
|
+
const skeleton = container.querySelector('div');
|
|
14
|
+
expect(skeleton).toHaveAttribute('role', 'status');
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
test('has aria-label for screen readers', () => {
|
|
18
|
+
const { container } = render(Skeleton);
|
|
19
|
+
const skeleton = container.querySelector('[role="status"]');
|
|
20
|
+
expect(skeleton).toHaveAttribute('aria-label', 'Loading content');
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
test('applies custom className', () => {
|
|
24
|
+
const { container } = render(Skeleton, { props: { class: 'custom-skeleton' } });
|
|
25
|
+
const skeleton = container.querySelector('[role="status"]');
|
|
26
|
+
expect(skeleton).toHaveClass('custom-skeleton');
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
test('passes through additional props', () => {
|
|
30
|
+
const { container } = render(Skeleton, { props: { 'data-testid': 'my-skeleton' } });
|
|
31
|
+
expect(container.querySelector('[data-testid="my-skeleton"]')).toBeInTheDocument();
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
describe('Skeleton Lines', () => {
|
|
36
|
+
test('defaults to 3 lines', () => {
|
|
37
|
+
const { container } = render(Skeleton);
|
|
38
|
+
const lines = container.querySelectorAll('.rounded-full.bg-gray-200');
|
|
39
|
+
expect(lines.length).toBe(3);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test('renders custom number of lines', () => {
|
|
43
|
+
const { container } = render(Skeleton, { props: { lines: 5 } });
|
|
44
|
+
const lineElements = container.querySelectorAll('.rounded-full.bg-gray-200');
|
|
45
|
+
expect(lineElements.length).toBe(5);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
test('renders 1 line when lines=1', () => {
|
|
49
|
+
const { container } = render(Skeleton, { props: { lines: 1 } });
|
|
50
|
+
const lineElements = container.querySelectorAll('.rounded-full.bg-gray-200');
|
|
51
|
+
expect(lineElements.length).toBe(1);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test('lines have rounded-full class', () => {
|
|
55
|
+
const { container } = render(Skeleton);
|
|
56
|
+
const lines = container.querySelectorAll('[role="status"] > div');
|
|
57
|
+
lines.forEach(line => {
|
|
58
|
+
expect(line).toHaveClass('rounded-full');
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
test('lines have bg-gray-200 background', () => {
|
|
63
|
+
const { container } = render(Skeleton);
|
|
64
|
+
const lines = container.querySelectorAll('[role="status"] > div');
|
|
65
|
+
lines.forEach(line => {
|
|
66
|
+
expect(line).toHaveClass('bg-gray-200');
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
test('lines have dark mode background', () => {
|
|
71
|
+
const { container } = render(Skeleton);
|
|
72
|
+
const lines = container.querySelectorAll('[role="status"] > div');
|
|
73
|
+
lines.forEach(line => {
|
|
74
|
+
expect(line).toHaveClass('dark:bg-gray-700');
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
test('lines (except last) have mb-2.5 margin', () => {
|
|
79
|
+
const { container } = render(Skeleton, { props: { lines: 3 } });
|
|
80
|
+
const lines = container.querySelectorAll('[role="status"] > div');
|
|
81
|
+
// First two should have margin, last should not
|
|
82
|
+
expect(lines[0]).toHaveClass('mb-2.5');
|
|
83
|
+
expect(lines[1]).toHaveClass('mb-2.5');
|
|
84
|
+
expect(lines[2]).not.toHaveClass('mb-2.5');
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
describe('Skeleton Width Patterns', () => {
|
|
89
|
+
test('first line has w-full', () => {
|
|
90
|
+
const { container } = render(Skeleton, { props: { lines: 7 } });
|
|
91
|
+
const lines = container.querySelectorAll('[role="status"] > div');
|
|
92
|
+
expect(lines[0]).toHaveClass('w-full');
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
test('second line has max-w-sm', () => {
|
|
96
|
+
const { container } = render(Skeleton, { props: { lines: 7 } });
|
|
97
|
+
const lines = container.querySelectorAll('[role="status"] > div');
|
|
98
|
+
expect(lines[1]).toHaveClass('max-w-sm');
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
test('third line has w-full', () => {
|
|
102
|
+
const { container } = render(Skeleton, { props: { lines: 7 } });
|
|
103
|
+
const lines = container.querySelectorAll('[role="status"] > div');
|
|
104
|
+
expect(lines[2]).toHaveClass('w-full');
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
test('fourth line has max-w-80', () => {
|
|
108
|
+
const { container } = render(Skeleton, { props: { lines: 7 } });
|
|
109
|
+
const lines = container.querySelectorAll('[role="status"] > div');
|
|
110
|
+
expect(lines[3]).toHaveClass('max-w-80');
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
test('fifth line has max-w-72', () => {
|
|
114
|
+
const { container } = render(Skeleton, { props: { lines: 7 } });
|
|
115
|
+
const lines = container.querySelectorAll('[role="status"] > div');
|
|
116
|
+
expect(lines[4]).toHaveClass('max-w-72');
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
test('width pattern repeats after 7 lines', () => {
|
|
120
|
+
const { container } = render(Skeleton, { props: { lines: 8 } });
|
|
121
|
+
const lines = container.querySelectorAll('[role="status"] > div');
|
|
122
|
+
// 8th line (index 7) should have same width as 1st line (index 0)
|
|
123
|
+
expect(lines[7]).toHaveClass('w-full');
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
describe('Skeleton Animation', () => {
|
|
128
|
+
test('animate is true by default', () => {
|
|
129
|
+
const { container } = render(Skeleton);
|
|
130
|
+
const skeleton = container.querySelector('[role="status"]');
|
|
131
|
+
expect(skeleton).toHaveClass('animate-pulse');
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
test('animate=true adds animate-pulse class', () => {
|
|
135
|
+
const { container } = render(Skeleton, { props: { animate: true } });
|
|
136
|
+
const skeleton = container.querySelector('[role="status"]');
|
|
137
|
+
expect(skeleton).toHaveClass('animate-pulse');
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
test('animate=false removes animate-pulse class', () => {
|
|
141
|
+
const { container } = render(Skeleton, { props: { animate: false } });
|
|
142
|
+
const skeleton = container.querySelector('[role="status"]');
|
|
143
|
+
expect(skeleton).not.toHaveClass('animate-pulse');
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
describe('Skeleton Screen Reader', () => {
|
|
148
|
+
test('has sr-only loading text', () => {
|
|
149
|
+
const { container } = render(Skeleton);
|
|
150
|
+
const srOnly = container.querySelector('.sr-only');
|
|
151
|
+
expect(srOnly).toBeInTheDocument();
|
|
152
|
+
expect(srOnly).toHaveTextContent('Loading...');
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
describe('Skeleton Sizes', () => {
|
|
157
|
+
test('default size is md', () => {
|
|
158
|
+
// The actual height class depends on skeletonSizes token
|
|
159
|
+
// Just verify component renders without error
|
|
160
|
+
const { container } = render(Skeleton);
|
|
161
|
+
expect(container.querySelector('[role="status"]')).toBeInTheDocument();
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
test('accepts size prop', () => {
|
|
165
|
+
const { container } = render(Skeleton, { props: { size: 'sm' } });
|
|
166
|
+
expect(container.querySelector('[role="status"]')).toBeInTheDocument();
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
test('accepts lg size', () => {
|
|
170
|
+
const { container } = render(Skeleton, { props: { size: 'lg' } });
|
|
171
|
+
expect(container.querySelector('[role="status"]')).toBeInTheDocument();
|
|
172
|
+
});
|
|
173
|
+
});
|
|
@@ -3,10 +3,16 @@ import { expect, describe, test } from "vitest";
|
|
|
3
3
|
import Spinner from "./Spinner.svelte";
|
|
4
4
|
|
|
5
5
|
describe("Spinner Component Tests", () => {
|
|
6
|
-
test("Renders spinner with
|
|
7
|
-
render(Spinner);
|
|
8
|
-
const
|
|
9
|
-
expect(
|
|
6
|
+
test("Renders spinner with SVG element", () => {
|
|
7
|
+
const { container } = render(Spinner);
|
|
8
|
+
const svg = container.querySelector("svg");
|
|
9
|
+
expect(svg).toBeInTheDocument();
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
test("SVG has role status for accessibility", () => {
|
|
13
|
+
const { container } = render(Spinner);
|
|
14
|
+
const svg = container.querySelector("svg");
|
|
15
|
+
expect(svg).toHaveAttribute("role", "status");
|
|
10
16
|
});
|
|
11
17
|
|
|
12
18
|
test("Has loading text for screen readers", () => {
|
|
@@ -20,12 +26,6 @@ describe("Spinner Component Tests", () => {
|
|
|
20
26
|
expect(loadingText).toHaveClass("sr-only");
|
|
21
27
|
});
|
|
22
28
|
|
|
23
|
-
test("Contains SVG element", () => {
|
|
24
|
-
const { container } = render(Spinner);
|
|
25
|
-
const svg = container.querySelector("svg");
|
|
26
|
-
expect(svg).toBeInTheDocument();
|
|
27
|
-
});
|
|
28
|
-
|
|
29
29
|
test("SVG is hidden from accessibility tree", () => {
|
|
30
30
|
const { container } = render(Spinner);
|
|
31
31
|
const svg = container.querySelector("svg");
|
|
@@ -38,26 +38,10 @@ describe("Spinner Component Tests", () => {
|
|
|
38
38
|
expect(svg).toHaveClass("animate-spin");
|
|
39
39
|
});
|
|
40
40
|
|
|
41
|
-
test("
|
|
42
|
-
render(Spinner);
|
|
43
|
-
const status = screen.getByRole("status");
|
|
44
|
-
expect(status).toHaveClass("flex");
|
|
45
|
-
expect(status).toHaveClass("flex-col");
|
|
46
|
-
expect(status).toHaveClass("justify-center");
|
|
47
|
-
expect(status).toHaveClass("items-center");
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
test("Has correct height", () => {
|
|
51
|
-
render(Spinner);
|
|
52
|
-
const status = screen.getByRole("status");
|
|
53
|
-
expect(status).toHaveClass("h-10");
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
test("SVG has correct dimensions", () => {
|
|
41
|
+
test("SVG has correct viewBox", () => {
|
|
57
42
|
const { container } = render(Spinner);
|
|
58
43
|
const svg = container.querySelector("svg");
|
|
59
|
-
expect(svg).
|
|
60
|
-
expect(svg).toHaveClass("h-8");
|
|
44
|
+
expect(svg).toHaveAttribute("viewBox", "0 0 100 101");
|
|
61
45
|
});
|
|
62
46
|
|
|
63
47
|
test("Has dark mode text color classes", () => {
|
|
@@ -67,9 +51,21 @@ describe("Spinner Component Tests", () => {
|
|
|
67
51
|
expect(svg).toHaveClass("dark:text-gray-600");
|
|
68
52
|
});
|
|
69
53
|
|
|
70
|
-
test("Has blue fill color", () => {
|
|
54
|
+
test("Has default blue fill color", () => {
|
|
71
55
|
const { container } = render(Spinner);
|
|
72
56
|
const svg = container.querySelector("svg");
|
|
73
57
|
expect(svg).toHaveClass("fill-blue-600");
|
|
74
58
|
});
|
|
59
|
+
|
|
60
|
+
test("Accepts custom class", () => {
|
|
61
|
+
const { container } = render(Spinner, { class: "custom-class" });
|
|
62
|
+
const svg = container.querySelector("svg");
|
|
63
|
+
expect(svg).toHaveClass("custom-class");
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test("Contains two path elements", () => {
|
|
67
|
+
const { container } = render(Spinner);
|
|
68
|
+
const paths = container.querySelectorAll("path");
|
|
69
|
+
expect(paths.length).toBe(2);
|
|
70
|
+
});
|
|
75
71
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TabItem.spec.d.ts","sourceRoot":"","sources":["../../../src/lib/primitives/Tabs/TabItem.spec.js"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/svelte';
|
|
2
|
+
import { expect, describe, test } from 'vitest';
|
|
3
|
+
import TabItem from './TabItem.svelte';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* TabItem Component Tests
|
|
7
|
+
*
|
|
8
|
+
* TabItem is designed to work within a Tabs parent that provides context.
|
|
9
|
+
* Testing in isolation requires mocking the context.
|
|
10
|
+
*
|
|
11
|
+
* Component behavior:
|
|
12
|
+
* - Gets activeTab and registerTab from Tabs context
|
|
13
|
+
* - Generates unique tabId from value prop or random ID
|
|
14
|
+
* - Only renders content when isActive (activeTab === tabId)
|
|
15
|
+
* - Has role="tabpanel" for accessibility
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
describe('TabItem Component - Context Requirements', () => {
|
|
19
|
+
test('requires Tabs context to function', () => {
|
|
20
|
+
// TabItem relies on getContext("tabs") to get activeTab and registerTab
|
|
21
|
+
// This documents the expected context interface
|
|
22
|
+
const expectedContext = {
|
|
23
|
+
activeTab: 'Writable<string | number | undefined>',
|
|
24
|
+
registerTab: '(id: string | number, title: string, open: boolean) => string | number'
|
|
25
|
+
};
|
|
26
|
+
expect(expectedContext.activeTab).toBeDefined();
|
|
27
|
+
expect(expectedContext.registerTab).toBeDefined();
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
describe('TabItem Props Interface', () => {
|
|
32
|
+
test('accepts title prop', () => {
|
|
33
|
+
// TabItem expects these props
|
|
34
|
+
const props = {
|
|
35
|
+
title: 'Tab Title',
|
|
36
|
+
open: false,
|
|
37
|
+
value: 'tab-1',
|
|
38
|
+
disabled: false,
|
|
39
|
+
class: 'custom-class',
|
|
40
|
+
onclick: () => {}
|
|
41
|
+
};
|
|
42
|
+
expect(props.title).toBe('Tab Title');
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test('accepts open prop for initial state', () => {
|
|
46
|
+
const props = { open: true };
|
|
47
|
+
expect(props.open).toBe(true);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
test('accepts value prop for unique tab ID', () => {
|
|
51
|
+
const props = { value: 'unique-tab-id' };
|
|
52
|
+
expect(props.value).toBe('unique-tab-id');
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
test('accepts disabled prop', () => {
|
|
56
|
+
const props = { disabled: true };
|
|
57
|
+
expect(props.disabled).toBe(true);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test('accepts className prop', () => {
|
|
61
|
+
const props = { class: 'my-tab-item' };
|
|
62
|
+
expect(props.class).toBe('my-tab-item');
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
test('accepts onclick callback', () => {
|
|
66
|
+
const onclick = () => {};
|
|
67
|
+
expect(typeof onclick).toBe('function');
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
describe('TabItem Expected Behavior', () => {
|
|
72
|
+
test('renders role="tabpanel" when active', () => {
|
|
73
|
+
// When isActive is true, TabItem renders:
|
|
74
|
+
// <div class={className} role="tabpanel" ...>
|
|
75
|
+
const expectedRole = 'tabpanel';
|
|
76
|
+
expect(expectedRole).toBe('tabpanel');
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
test('does not render when inactive', () => {
|
|
80
|
+
// When isActive is false ({#if isActive} fails), nothing renders
|
|
81
|
+
// This ensures only one tab content is visible at a time
|
|
82
|
+
const isActive = false;
|
|
83
|
+
expect(isActive).toBe(false);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
test('calls registerTab on mount', () => {
|
|
87
|
+
// onMount calls registerTab(tabId, title, open)
|
|
88
|
+
// This registers the tab with the parent Tabs component
|
|
89
|
+
const registerTabArgs = ['tabId', 'title', false];
|
|
90
|
+
expect(registerTabArgs.length).toBe(3);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
test('uses value prop as tabId when provided', () => {
|
|
94
|
+
// tabId = $derived(value ?? generatedId)
|
|
95
|
+
const value = 'my-tab-value';
|
|
96
|
+
const tabId = value ?? 'generated-id';
|
|
97
|
+
expect(tabId).toBe('my-tab-value');
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
test('generates random ID when value not provided', () => {
|
|
101
|
+
// When value is undefined, generates: `tab-${Math.random()...}`
|
|
102
|
+
const value = undefined;
|
|
103
|
+
const generatedId = `tab-${Math.random().toString(36).substring(2, 9)}`;
|
|
104
|
+
const tabId = value ?? generatedId;
|
|
105
|
+
expect(tabId).toMatch(/^tab-[a-z0-9]+$/);
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
describe('TabItem Accessibility', () => {
|
|
110
|
+
test('uses role="tabpanel" for screen readers', () => {
|
|
111
|
+
// The tabpanel role indicates this is a tab panel
|
|
112
|
+
// Associated with a tab in the tablist
|
|
113
|
+
const role = 'tabpanel';
|
|
114
|
+
expect(role).toBe('tabpanel');
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
describe('TabItem Integration Notes', () => {
|
|
119
|
+
test('works with Tabs parent component', () => {
|
|
120
|
+
// TabItem must be used inside Tabs component
|
|
121
|
+
// Tabs provides context with activeTab and registerTab
|
|
122
|
+
// Multiple TabItems can be used to create tabbed interfaces
|
|
123
|
+
const integrationNotes = {
|
|
124
|
+
parent: 'Tabs',
|
|
125
|
+
context: ['activeTab', 'registerTab'],
|
|
126
|
+
usage: '<Tabs><TabItem title="Tab 1">Content 1</TabItem></Tabs>'
|
|
127
|
+
};
|
|
128
|
+
expect(integrationNotes.parent).toBe('Tabs');
|
|
129
|
+
});
|
|
130
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tabs.spec.d.ts","sourceRoot":"","sources":["../../../src/lib/primitives/Tabs/Tabs.spec.js"],"names":[],"mappings":""}
|