@getmicdrop/svelte-components 5.17.1 → 5.17.4
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/Calendar/MiniMonthCalendar.svelte +5 -7
- package/dist/calendar/Calendar/MiniMonthCalendar.svelte.d.ts.map +1 -1
- package/dist/calendar/MonthSwitcher/MonthSwitcher.svelte +2 -3
- package/dist/calendar/MonthSwitcher/MonthSwitcher.svelte.d.ts.map +1 -1
- package/dist/calendar/PublicCard/PublicCard.svelte +23 -14
- package/dist/calendar/PublicCard/PublicCard.svelte.d.ts.map +1 -1
- package/dist/calendar/ShowCard/ShowCard.spec.js +1 -7
- package/dist/calendar/ShowCard/ShowCard.svelte +10 -1
- package/dist/calendar/ShowCard/ShowCard.svelte.d.ts.map +1 -1
- package/dist/calendar/ShowTimeCard/ShowTimeCard.svelte +11 -0
- package/dist/calendar/ShowTimeCard/ShowTimeCard.svelte.d.ts +2 -0
- package/dist/calendar/ShowTimeCard/ShowTimeCard.svelte.d.ts.map +1 -1
- package/dist/components/Heading.spec.d.ts +2 -0
- package/dist/components/Heading.spec.d.ts.map +1 -0
- package/dist/components/Heading.spec.js +89 -0
- package/dist/components/Layout/__tests__/AppShell.test.js +140 -0
- package/dist/components/Text.spec.d.ts +2 -0
- package/dist/components/Text.spec.d.ts.map +1 -0
- package/dist/components/Text.spec.js +89 -0
- package/dist/config.d.ts +102 -0
- package/dist/config.js +147 -1
- package/dist/datetime/README.md +323 -0
- package/dist/forms/createFormStore.svelte.spec.d.ts +2 -0
- package/dist/forms/createFormStore.svelte.spec.d.ts.map +1 -0
- package/dist/forms/createFormStore.svelte.spec.js +387 -0
- package/dist/messages.d.ts +43 -0
- package/dist/messages.d.ts.map +1 -0
- package/dist/messages.js +57 -0
- package/dist/patterns/chat/ChatActivityNotice.spec.d.ts +2 -0
- package/dist/patterns/chat/ChatActivityNotice.spec.d.ts.map +1 -0
- package/dist/patterns/chat/ChatActivityNotice.spec.js +59 -0
- package/dist/patterns/chat/ChatBubble.spec.d.ts +2 -0
- package/dist/patterns/chat/ChatBubble.spec.d.ts.map +1 -0
- package/dist/patterns/chat/ChatBubble.spec.js +91 -0
- package/dist/patterns/chat/ChatContainer.spec.d.ts +2 -0
- package/dist/patterns/chat/ChatContainer.spec.d.ts.map +1 -0
- package/dist/patterns/chat/ChatContainer.spec.js +30 -0
- package/dist/patterns/chat/ChatDateDivider.spec.d.ts +2 -0
- package/dist/patterns/chat/ChatDateDivider.spec.d.ts.map +1 -0
- package/dist/patterns/chat/ChatDateDivider.spec.js +30 -0
- package/dist/patterns/chat/ChatInvitationBubble.spec.d.ts +2 -0
- package/dist/patterns/chat/ChatInvitationBubble.spec.d.ts.map +1 -0
- package/dist/patterns/chat/ChatInvitationBubble.spec.js +46 -0
- package/dist/patterns/chat/ChatInvitationNotice.spec.d.ts +2 -0
- package/dist/patterns/chat/ChatInvitationNotice.spec.d.ts.map +1 -0
- package/dist/patterns/chat/ChatInvitationNotice.spec.js +32 -0
- package/dist/patterns/chat/ChatMessageGroup.spec.d.ts +2 -0
- package/dist/patterns/chat/ChatMessageGroup.spec.d.ts.map +1 -0
- package/dist/patterns/chat/ChatMessageGroup.spec.js +58 -0
- package/dist/patterns/chat/ChatSlotUpdate.spec.d.ts +2 -0
- package/dist/patterns/chat/ChatSlotUpdate.spec.d.ts.map +1 -0
- package/dist/patterns/chat/ChatSlotUpdate.spec.js +65 -0
- package/dist/patterns/chat/ChatStatusBadge.spec.d.ts +2 -0
- package/dist/patterns/chat/ChatStatusBadge.spec.d.ts.map +1 -0
- package/dist/patterns/chat/ChatStatusBadge.spec.js +79 -0
- package/dist/patterns/chat/ChatStatusTransition.spec.d.ts +2 -0
- package/dist/patterns/chat/ChatStatusTransition.spec.d.ts.map +1 -0
- package/dist/patterns/chat/ChatStatusTransition.spec.js +81 -0
- package/dist/patterns/chat/ChatTextBubble.spec.d.ts +2 -0
- package/dist/patterns/chat/ChatTextBubble.spec.d.ts.map +1 -0
- package/dist/patterns/chat/ChatTextBubble.spec.js +35 -0
- package/dist/patterns/data/DataTable.spec.js +61 -0
- package/dist/patterns/forms/FormGrid.spec.js +34 -0
- package/dist/patterns/layout/Sidebar.spec.js +240 -1
- package/dist/patterns/layout/SidebarTestWrapper.svelte +34 -0
- package/dist/patterns/layout/SidebarTestWrapper.svelte.d.ts +23 -0
- package/dist/patterns/layout/SidebarTestWrapper.svelte.d.ts.map +1 -0
- package/dist/patterns/navigation/Header.spec.js +123 -0
- package/dist/primitives/Accordion/Accordion.spec.js +112 -2
- package/dist/primitives/Accordion/AccordionToggleWrapper.test.svelte +28 -0
- package/dist/primitives/Accordion/AccordionToggleWrapper.test.svelte.d.ts +7 -0
- package/dist/primitives/Accordion/AccordionToggleWrapper.test.svelte.d.ts.map +1 -0
- package/dist/primitives/Avatar/Avatar.spec.js +23 -0
- package/dist/primitives/BottomSheet/BottomSheet.spec.js +102 -0
- package/dist/primitives/BottomSheet/BottomSheetWithActions.test.svelte +20 -0
- package/dist/primitives/BottomSheet/BottomSheetWithActions.test.svelte.d.ts +10 -0
- package/dist/primitives/BottomSheet/BottomSheetWithActions.test.svelte.d.ts.map +1 -0
- package/dist/primitives/Button/ButtonGroup.spec.d.ts +2 -0
- package/dist/primitives/Button/ButtonGroup.spec.d.ts.map +1 -0
- package/dist/primitives/Button/ButtonGroup.spec.js +44 -0
- package/dist/primitives/Checkbox/Checkbox.spec.js +32 -0
- package/dist/primitives/Drawer/Drawer.spec.js +437 -0
- package/dist/primitives/Drawer/DrawerTestWrapper.svelte +86 -0
- package/dist/primitives/Drawer/DrawerTestWrapper.svelte.d.ts +26 -0
- package/dist/primitives/Drawer/DrawerTestWrapper.svelte.d.ts.map +1 -0
- package/dist/primitives/Dropdown/Dropdown.spec.js +116 -0
- package/dist/primitives/Dropdown/DropdownDivider.spec.d.ts +2 -0
- package/dist/primitives/Dropdown/DropdownDivider.spec.d.ts.map +1 -0
- package/dist/primitives/Dropdown/DropdownDivider.spec.js +30 -0
- package/dist/primitives/Dropdown/DropdownItem.spec.js +155 -1
- package/dist/primitives/Dropdown/DropdownItemTestWrapper.svelte +43 -0
- package/dist/primitives/Dropdown/DropdownItemTestWrapper.svelte.d.ts +17 -0
- package/dist/primitives/Dropdown/DropdownItemTestWrapper.svelte.d.ts.map +1 -0
- package/dist/primitives/Helper/Helper.spec.d.ts +2 -0
- package/dist/primitives/Helper/Helper.spec.d.ts.map +1 -0
- package/dist/primitives/Helper/Helper.spec.js +57 -0
- package/dist/primitives/Input/Input.spec.js +664 -0
- package/dist/primitives/Input/Input.svelte +18 -10
- package/dist/primitives/Input/Input.svelte.d.ts.map +1 -1
- package/dist/primitives/Input/Select.spec.js +414 -0
- package/dist/primitives/Label/Label.spec.js +9 -0
- package/dist/primitives/LandingButton/LandingButton.spec.d.ts +2 -0
- package/dist/primitives/LandingButton/LandingButton.spec.d.ts.map +1 -0
- package/dist/primitives/LandingButton/LandingButton.spec.js +61 -0
- package/dist/primitives/MenuItem/MenuItem.spec.d.ts +2 -0
- package/dist/primitives/MenuItem/MenuItem.spec.d.ts.map +1 -0
- package/dist/primitives/MenuItem/MenuItem.spec.js +130 -0
- package/dist/primitives/Modal/Modal.spec.js +215 -0
- package/dist/primitives/NavItem/NavItem.spec.d.ts +2 -0
- package/dist/primitives/NavItem/NavItem.spec.d.ts.map +1 -0
- package/dist/primitives/NavItem/NavItem.spec.js +97 -0
- package/dist/primitives/SearchResultItem/SearchResultItem.spec.d.ts +2 -0
- package/dist/primitives/SearchResultItem/SearchResultItem.spec.d.ts.map +1 -0
- package/dist/primitives/SearchResultItem/SearchResultItem.spec.js +78 -0
- package/dist/primitives/SidebarToggle/SidebarToggle.spec.d.ts +2 -0
- package/dist/primitives/SidebarToggle/SidebarToggle.spec.d.ts.map +1 -0
- package/dist/primitives/SidebarToggle/SidebarToggle.spec.js +61 -0
- package/dist/primitives/Spinner/Spinner.spec.js +13 -0
- package/dist/primitives/Toggle.spec.js +75 -0
- package/dist/primitives/ToggleTestWrapper.svelte +30 -0
- package/dist/primitives/ToggleTestWrapper.svelte.d.ts +29 -0
- package/dist/primitives/ToggleTestWrapper.svelte.d.ts.map +1 -0
- package/dist/primitives/Tooltip/Tooltip.spec.d.ts +2 -0
- package/dist/primitives/Tooltip/Tooltip.spec.d.ts.map +1 -0
- package/dist/primitives/Tooltip/Tooltip.spec.js +126 -0
- package/dist/recipes/inputs/Search.spec.js +66 -2
- package/dist/recipes/modals/ConfirmationModal.spec.js +190 -0
- package/dist/schemas/__tests__/auth.test.d.ts +2 -0
- package/dist/schemas/__tests__/auth.test.d.ts.map +1 -0
- package/dist/schemas/__tests__/auth.test.js +210 -0
- package/dist/schemas/__tests__/common.test.d.ts +2 -0
- package/dist/schemas/__tests__/common.test.d.ts.map +1 -0
- package/dist/schemas/__tests__/common.test.js +340 -0
- package/dist/schemas/__tests__/domain.test.d.ts +2 -0
- package/dist/schemas/__tests__/domain.test.d.ts.map +1 -0
- package/dist/schemas/__tests__/domain.test.js +293 -0
- package/dist/schemas/__tests__/order.test.d.ts +2 -0
- package/dist/schemas/__tests__/order.test.d.ts.map +1 -0
- package/dist/schemas/__tests__/order.test.js +349 -0
- package/dist/schemas/__tests__/user.test.d.ts +2 -0
- package/dist/schemas/__tests__/user.test.d.ts.map +1 -0
- package/dist/schemas/__tests__/user.test.js +325 -0
- package/dist/schemas/auth.d.ts +41 -0
- package/dist/schemas/auth.d.ts.map +1 -0
- package/dist/schemas/auth.js +69 -0
- package/dist/schemas/common.d.ts +43 -0
- package/dist/schemas/common.d.ts.map +1 -0
- package/dist/schemas/common.js +157 -0
- package/dist/schemas/event.d.ts +82 -0
- package/dist/schemas/event.d.ts.map +1 -0
- package/dist/schemas/event.js +58 -0
- package/dist/schemas/index.d.ts +10 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +9 -0
- package/dist/schemas/order.d.ts +111 -0
- package/dist/schemas/order.d.ts.map +1 -0
- package/dist/schemas/order.js +73 -0
- package/dist/schemas/performer.d.ts +133 -0
- package/dist/schemas/performer.d.ts.map +1 -0
- package/dist/schemas/performer.js +73 -0
- package/dist/schemas/promo.d.ts +87 -0
- package/dist/schemas/promo.d.ts.map +1 -0
- package/dist/schemas/promo.js +98 -0
- package/dist/schemas/ticket.d.ts +104 -0
- package/dist/schemas/ticket.d.ts.map +1 -0
- package/dist/schemas/ticket.js +82 -0
- package/dist/schemas/user.d.ts +92 -0
- package/dist/schemas/user.d.ts.map +1 -0
- package/dist/schemas/user.js +53 -0
- package/dist/schemas/venue.d.ts +95 -0
- package/dist/schemas/venue.d.ts.map +1 -0
- package/dist/schemas/venue.js +52 -0
- package/dist/stores/auth.svelte.spec.d.ts +2 -0
- package/dist/stores/auth.svelte.spec.d.ts.map +1 -0
- package/dist/stores/auth.svelte.spec.js +112 -0
- package/dist/stores/formDataStore.svelte.spec.d.ts +2 -0
- package/dist/stores/formDataStore.svelte.spec.d.ts.map +1 -0
- package/dist/stores/formDataStore.svelte.spec.js +150 -0
- package/dist/stores/formSave.svelte.spec.d.ts +2 -0
- package/dist/stores/formSave.svelte.spec.d.ts.map +1 -0
- package/dist/stores/formSave.svelte.spec.js +196 -0
- package/dist/stores/navigation.spec.d.ts +2 -0
- package/dist/stores/navigation.spec.d.ts.map +1 -0
- package/dist/stores/navigation.spec.js +53 -0
- package/dist/telemetry.spec.js +5 -0
- package/dist/tokens/__tests__/sizing.test.js +2 -2
- package/dist/tokens/sizing.d.ts +5 -0
- package/dist/tokens/sizing.d.ts.map +1 -1
- package/dist/tokens/sizing.js +6 -0
- package/dist/utils/haptic.spec.d.ts +2 -0
- package/dist/utils/haptic.spec.d.ts.map +1 -0
- package/dist/utils/haptic.spec.js +153 -0
- package/dist/utils/imageOptimizer.spec.d.ts +2 -0
- package/dist/utils/imageOptimizer.spec.d.ts.map +1 -0
- package/dist/utils/imageOptimizer.spec.js +201 -0
- package/dist/utils/logger.spec.d.ts +2 -0
- package/dist/utils/logger.spec.d.ts.map +1 -0
- package/dist/utils/logger.spec.js +95 -0
- package/package.json +1 -2
|
@@ -138,8 +138,6 @@
|
|
|
138
138
|
if (inputElement && inputElement.value !== inputValue) {
|
|
139
139
|
inputValue = inputElement.value;
|
|
140
140
|
value = inputValue;
|
|
141
|
-
// Also call oninputchange so parent components can react
|
|
142
|
-
oninputchange?.(inputValue);
|
|
143
141
|
}
|
|
144
142
|
}
|
|
145
143
|
|
|
@@ -293,7 +291,7 @@
|
|
|
293
291
|
onfocus={handleFocus}
|
|
294
292
|
{maxlength}
|
|
295
293
|
{minlength}
|
|
296
|
-
class="{typography.sm} w-full px-3 py-2 bg-gray-50 dark:bg-gray-800 border rounded-lg font-medium placeholder-gray-500 dark:placeholder-gray-400 transition-all focus:outline-
|
|
294
|
+
class="{typography.sm} w-full px-3 py-2 bg-gray-50 dark:bg-gray-800 border rounded-lg font-medium placeholder-gray-500 dark:placeholder-gray-400 transition-all focus:outline-none focus:ring-4 focus:ring-blue-300 dark:focus:ring-blue-800 resize-y {hasError ? 'border-red-500' : 'border-gray-300 dark:border-gray-600 hover:border-blue-500 focus:border-blue-500'} {getContentFloatClass()} {getTextareaSizeClass()} {shouldAnimate ? 'focus:scale-[1.01]' : ''}"
|
|
297
295
|
required={false}
|
|
298
296
|
{disabled}
|
|
299
297
|
{readonly}
|
|
@@ -301,7 +299,7 @@
|
|
|
301
299
|
aria-required={required}
|
|
302
300
|
></textarea>
|
|
303
301
|
{:else if type === "password" && showPasswordToggle}
|
|
304
|
-
<div class="
|
|
302
|
+
<div class="flex items-center w-full bg-gray-50 dark:bg-gray-800 border rounded-lg transition-all outline-none focus-within:ring-4 focus-within:ring-blue-300 dark:focus-within:ring-blue-800 {hasError ? 'border-red-500' : 'border-gray-300 dark:border-gray-600 hover:border-blue-500 focus-within:border-blue-500'} {shouldAnimate ? 'focus-within:scale-[1.01]' : ''} {disabled ? 'opacity-50 cursor-not-allowed' : ''}">
|
|
305
303
|
<!-- svelte-ignore a11y_autofocus -->
|
|
306
304
|
<input
|
|
307
305
|
bind:this={inputElement}
|
|
@@ -316,7 +314,7 @@
|
|
|
316
314
|
onfocus={handleFocus}
|
|
317
315
|
{maxlength}
|
|
318
316
|
{minlength}
|
|
319
|
-
class="{typography.
|
|
317
|
+
class="password-input-inner {typography.sm} flex-1 w-full {sizeClass} bg-transparent border-0 font-medium placeholder-gray-500 dark:placeholder-gray-400 focus:outline-none focus:ring-0 {getContentFloatClass()}"
|
|
320
318
|
required={false}
|
|
321
319
|
{disabled}
|
|
322
320
|
{readonly}
|
|
@@ -328,7 +326,7 @@
|
|
|
328
326
|
<button
|
|
329
327
|
type="button"
|
|
330
328
|
onclick={togglePasswordVisibility}
|
|
331
|
-
class="
|
|
329
|
+
class="flex items-center justify-center px-3 text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-200 focus:outline-none"
|
|
332
330
|
tabindex="-1"
|
|
333
331
|
aria-label={isPasswordVisible ? "Hide password" : "Show password"}
|
|
334
332
|
>
|
|
@@ -342,7 +340,7 @@
|
|
|
342
340
|
{:else}
|
|
343
341
|
<div class="relative flex items-center w-full">
|
|
344
342
|
{#if leftIcon}
|
|
345
|
-
<div class="absolute left-3
|
|
343
|
+
<div class="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 z-10 pointer-events-none">
|
|
346
344
|
{@render leftIcon()}
|
|
347
345
|
</div>
|
|
348
346
|
{/if}
|
|
@@ -361,7 +359,7 @@
|
|
|
361
359
|
onkeydown={handleSearchKeyDown}
|
|
362
360
|
{maxlength}
|
|
363
361
|
{minlength}
|
|
364
|
-
class="{typography.body} w-full {sizeClass} bg-gray-50 dark:bg-gray-800 border rounded-lg font-medium placeholder-gray-500 dark:placeholder-gray-400 transition-all focus:outline-
|
|
362
|
+
class="{typography.body} w-full {sizeClass} bg-gray-50 dark:bg-gray-800 border rounded-lg font-medium placeholder-gray-500 dark:placeholder-gray-400 transition-all focus:outline-none focus:ring-4 focus:ring-blue-300 dark:focus:ring-blue-800 {hasError ? 'border-red-500' : 'border-gray-300 dark:border-gray-600 hover:border-blue-500 focus:border-blue-500'} {icon || (showClearButton && inputValue) ? 'pr-10' : ''} {leftIcon ? 'pl-10' : ''} {getContentFloatClass()} {shouldAnimate ? 'focus:scale-[1.01]' : ''} {disabled ? 'opacity-50 cursor-not-allowed' : ''}"
|
|
365
363
|
required={false}
|
|
366
364
|
{disabled}
|
|
367
365
|
{readonly}
|
|
@@ -374,7 +372,7 @@
|
|
|
374
372
|
<button
|
|
375
373
|
type="button"
|
|
376
374
|
onclick={clearInput}
|
|
377
|
-
class="absolute right-
|
|
375
|
+
class="absolute right-2 top-1/2 -translate-y-1/2 flex items-center justify-center p-1 text-gray-400 hover:text-gray-600 dark:hover:text-gray-200"
|
|
378
376
|
aria-label="Clear input"
|
|
379
377
|
tabindex="-1"
|
|
380
378
|
>
|
|
@@ -419,5 +417,15 @@
|
|
|
419
417
|
</div>
|
|
420
418
|
|
|
421
419
|
<style>
|
|
422
|
-
/*
|
|
420
|
+
/*
|
|
421
|
+
* Override Tailwind v4 preflight which sets input { border: 1px solid currentColor }
|
|
422
|
+
* in @layer base. The base layer's element selector has higher specificity than
|
|
423
|
+
* utility class selectors like border-0 or border-none, so we need scoped overrides.
|
|
424
|
+
*
|
|
425
|
+
* This affects the password input which is wrapped in a container div that provides
|
|
426
|
+
* the visible border - the inner input should have no border.
|
|
427
|
+
*/
|
|
428
|
+
:global(.password-input-inner) {
|
|
429
|
+
border: none !important;
|
|
430
|
+
}
|
|
423
431
|
</style>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Input.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/primitives/Input/Input.svelte.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"Input.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/primitives/Input/Input.svelte.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmZA;eA7Ce,OAAO;eACP,OAAO;eACP,OAAO;WACX,MAAM,GAAG,IAAI;iBACP,MAAM,GAAG,IAAI;iBACb,MAAM,GAAG,IAAI;gBACd,MAAM,GAAG,IAAI;gBACb,MAAM,GAAG,IAAI;WAClB,MAAM;kBACC,MAAM;YACZ,MAAM;SACT,MAAM;WACJ,MAAM;gBACD,MAAM;WACX,IAAI,GAAG,IAAI,GAAG,IAAI;mBACV,MAAM;gBACT,MAAM;YACV,MAAM,GAAG,KAAK;iBACT,MAAM;iBACN,MAAM;eACR,MAAM;eACN,MAAM;mBACF,MAAM;eACV,OAAO;iBACL,OAAO;oBACJ,CAAC,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,IAAI;YACxC,MAAM,GAAG,MAAM,GAAG,IAAI;mBACf,MAAM,GAAG,IAAI;gBAChB,OAAO;yBACE,OAAO;mBACb,OAAO;iBACT,MAAM;iBACN,MAAM;qBACF,OAAO;gBACZ,MAAM,GAAG,IAAI;oBACT,OAAO;iBACV,MAAM;qBACF,MAAM;sBACL,OAAO;eACd,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI;cACpC,MAAM,IAAI;aACX,MAAM,IAAI;oBACH,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI;eAC5B,OAAO,QAAQ,EAAE,OAAO;gBAEa"}
|
|
@@ -216,3 +216,417 @@ describe("Select Component Tests", () => {
|
|
|
216
216
|
expect(trigger).toHaveAttribute("aria-expanded", "false");
|
|
217
217
|
});
|
|
218
218
|
});
|
|
219
|
+
|
|
220
|
+
describe("Keyboard Navigation - ArrowUp", () => {
|
|
221
|
+
test("ArrowUp moves focus index up within bounds", async () => {
|
|
222
|
+
const changeSpy = vi.fn();
|
|
223
|
+
const { user } = setupTest({ onchange: changeSpy });
|
|
224
|
+
const trigger = screen.getByRole("button");
|
|
225
|
+
|
|
226
|
+
await user.click(trigger);
|
|
227
|
+
// Navigate down twice then up once
|
|
228
|
+
await user.keyboard("{ArrowDown}");
|
|
229
|
+
await user.keyboard("{ArrowDown}");
|
|
230
|
+
await user.keyboard("{ArrowUp}");
|
|
231
|
+
await user.keyboard("{Enter}");
|
|
232
|
+
|
|
233
|
+
// Started at index from click (items.findIndex matching value, or -1 => ArrowDown goes to 0, then 1, ArrowUp to 0)
|
|
234
|
+
expect(changeSpy).toHaveBeenCalled();
|
|
235
|
+
// After open: focusedIndex = -1 (no value), ArrowDown -> 0, ArrowDown -> 1, ArrowUp -> 0, Enter selects opt1
|
|
236
|
+
expect(changeSpy.mock.calls[0][0]).toEqual({
|
|
237
|
+
value: "opt1",
|
|
238
|
+
item: { name: "Option 1", value: "opt1" },
|
|
239
|
+
});
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
test("ArrowUp does not go below index 0", async () => {
|
|
243
|
+
const changeSpy = vi.fn();
|
|
244
|
+
const { user } = setupTest({ onchange: changeSpy });
|
|
245
|
+
const trigger = screen.getByRole("button");
|
|
246
|
+
|
|
247
|
+
await user.click(trigger);
|
|
248
|
+
// ArrowDown to index 0, then ArrowUp should stay at 0
|
|
249
|
+
await user.keyboard("{ArrowDown}");
|
|
250
|
+
await user.keyboard("{ArrowUp}");
|
|
251
|
+
await user.keyboard("{Enter}");
|
|
252
|
+
|
|
253
|
+
expect(changeSpy.mock.calls[0][0]).toEqual({
|
|
254
|
+
value: "opt1",
|
|
255
|
+
item: { name: "Option 1", value: "opt1" },
|
|
256
|
+
});
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
test("ArrowUp does nothing when dropdown is closed", async () => {
|
|
260
|
+
const { user } = setupTest();
|
|
261
|
+
const trigger = screen.getByRole("button");
|
|
262
|
+
|
|
263
|
+
trigger.focus();
|
|
264
|
+
await user.keyboard("{ArrowUp}");
|
|
265
|
+
// Dropdown should still be closed
|
|
266
|
+
expect(screen.queryByRole("listbox")).not.toBeInTheDocument();
|
|
267
|
+
});
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
describe("Keyboard Navigation - Tab", () => {
|
|
271
|
+
test("Tab key closes the dropdown", async () => {
|
|
272
|
+
const { user } = setupTest();
|
|
273
|
+
const trigger = screen.getByRole("button");
|
|
274
|
+
|
|
275
|
+
await user.click(trigger);
|
|
276
|
+
expect(screen.getByRole("listbox")).toBeInTheDocument();
|
|
277
|
+
|
|
278
|
+
await user.keyboard("{Tab}");
|
|
279
|
+
expect(screen.queryByRole("listbox")).not.toBeInTheDocument();
|
|
280
|
+
});
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
describe("Keyboard Navigation - ArrowDown when closed", () => {
|
|
284
|
+
test("ArrowDown opens dropdown and focuses first item", async () => {
|
|
285
|
+
const changeSpy = vi.fn();
|
|
286
|
+
const { user } = setupTest({ onchange: changeSpy });
|
|
287
|
+
const trigger = screen.getByRole("button");
|
|
288
|
+
|
|
289
|
+
trigger.focus();
|
|
290
|
+
await user.keyboard("{ArrowDown}");
|
|
291
|
+
// Should open the dropdown
|
|
292
|
+
expect(screen.getByRole("listbox")).toBeInTheDocument();
|
|
293
|
+
|
|
294
|
+
// Enter should select the first item (focusedIndex = 0)
|
|
295
|
+
await user.keyboard("{Enter}");
|
|
296
|
+
expect(changeSpy.mock.calls[0][0]).toEqual({
|
|
297
|
+
value: "opt1",
|
|
298
|
+
item: { name: "Option 1", value: "opt1" },
|
|
299
|
+
});
|
|
300
|
+
});
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
describe("Keyboard Navigation - ArrowDown bounds at end", () => {
|
|
304
|
+
test("ArrowDown does not exceed items length", async () => {
|
|
305
|
+
const changeSpy = vi.fn();
|
|
306
|
+
const { user } = setupTest({ onchange: changeSpy });
|
|
307
|
+
const trigger = screen.getByRole("button");
|
|
308
|
+
|
|
309
|
+
await user.click(trigger);
|
|
310
|
+
// Navigate down many times past end
|
|
311
|
+
await user.keyboard("{ArrowDown}");
|
|
312
|
+
await user.keyboard("{ArrowDown}");
|
|
313
|
+
await user.keyboard("{ArrowDown}");
|
|
314
|
+
await user.keyboard("{ArrowDown}");
|
|
315
|
+
await user.keyboard("{ArrowDown}");
|
|
316
|
+
await user.keyboard("{Enter}");
|
|
317
|
+
|
|
318
|
+
// Should be clamped to last item (index 2)
|
|
319
|
+
expect(changeSpy.mock.calls[0][0]).toEqual({
|
|
320
|
+
value: "opt3",
|
|
321
|
+
item: { name: "Option 3", value: "opt3" },
|
|
322
|
+
});
|
|
323
|
+
});
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
describe("Keyboard - disabled state", () => {
|
|
327
|
+
test("Keyboard events are ignored when disabled", async () => {
|
|
328
|
+
const { user } = setupTest({ disabled: true });
|
|
329
|
+
const trigger = screen.getByRole("button");
|
|
330
|
+
|
|
331
|
+
trigger.focus();
|
|
332
|
+
await user.keyboard("{Enter}");
|
|
333
|
+
expect(screen.queryByRole("listbox")).not.toBeInTheDocument();
|
|
334
|
+
|
|
335
|
+
await user.keyboard("{ArrowDown}");
|
|
336
|
+
expect(screen.queryByRole("listbox")).not.toBeInTheDocument();
|
|
337
|
+
|
|
338
|
+
await user.keyboard(" ");
|
|
339
|
+
expect(screen.queryByRole("listbox")).not.toBeInTheDocument();
|
|
340
|
+
});
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
describe("Select - no label rendering", () => {
|
|
344
|
+
test("Does not render label element when label is empty", () => {
|
|
345
|
+
const { user } = setupTest({
|
|
346
|
+
label: "",
|
|
347
|
+
});
|
|
348
|
+
expect(screen.queryByRole("label")).not.toBeInTheDocument();
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
test("Renders label without required asterisk when not required", () => {
|
|
352
|
+
setupTest({
|
|
353
|
+
label: "My Label",
|
|
354
|
+
required: false,
|
|
355
|
+
});
|
|
356
|
+
expect(screen.getByText("My Label")).toBeInTheDocument();
|
|
357
|
+
expect(screen.queryByText("*")).not.toBeInTheDocument();
|
|
358
|
+
});
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
describe("Select - error border styling", () => {
|
|
362
|
+
test("Trigger has error border when error is set", () => {
|
|
363
|
+
setupTest({ error: "Required" });
|
|
364
|
+
const trigger = screen.getByRole("button");
|
|
365
|
+
expect(trigger).toHaveClass("border-red-500");
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
test("Trigger has normal border when no error", () => {
|
|
369
|
+
setupTest({ error: "" });
|
|
370
|
+
const trigger = screen.getByRole("button");
|
|
371
|
+
expect(trigger).toHaveClass("border-gray-300");
|
|
372
|
+
});
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
describe("Select - disabled styling", () => {
|
|
376
|
+
test("Disabled trigger has opacity and cursor classes", () => {
|
|
377
|
+
setupTest({ disabled: true });
|
|
378
|
+
const trigger = screen.getByRole("button");
|
|
379
|
+
expect(trigger).toHaveClass("opacity-50");
|
|
380
|
+
expect(trigger).toHaveClass("cursor-not-allowed");
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
test("Enabled trigger does not have disabled classes", () => {
|
|
384
|
+
setupTest({ disabled: false });
|
|
385
|
+
const trigger = screen.getByRole("button");
|
|
386
|
+
expect(trigger).not.toHaveClass("opacity-50");
|
|
387
|
+
expect(trigger).not.toHaveClass("cursor-not-allowed");
|
|
388
|
+
});
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
describe("Select - size variants", () => {
|
|
392
|
+
test("Applies small size class", () => {
|
|
393
|
+
setupTest({ size: "sm" });
|
|
394
|
+
const trigger = screen.getByRole("button");
|
|
395
|
+
expect(trigger).toHaveClass("h-9");
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
test("Applies medium size class (default)", () => {
|
|
399
|
+
setupTest({ size: "md" });
|
|
400
|
+
const trigger = screen.getByRole("button");
|
|
401
|
+
expect(trigger).toHaveClass("h-10");
|
|
402
|
+
});
|
|
403
|
+
|
|
404
|
+
test("Applies large size class", () => {
|
|
405
|
+
setupTest({ size: "lg" });
|
|
406
|
+
const trigger = screen.getByRole("button");
|
|
407
|
+
expect(trigger).toHaveClass("h-12");
|
|
408
|
+
});
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
describe("Select - dropdown chevron rotation", () => {
|
|
412
|
+
test("Chevron rotates when dropdown is open", async () => {
|
|
413
|
+
const { user } = setupTest();
|
|
414
|
+
const trigger = screen.getByRole("button");
|
|
415
|
+
|
|
416
|
+
// When closed, chevron should not have rotate-180
|
|
417
|
+
const chevron = trigger.querySelector('svg');
|
|
418
|
+
expect(chevron).not.toHaveClass("rotate-180");
|
|
419
|
+
|
|
420
|
+
await user.click(trigger);
|
|
421
|
+
// When open, chevron should have rotate-180
|
|
422
|
+
expect(chevron).toHaveClass("rotate-180");
|
|
423
|
+
});
|
|
424
|
+
});
|
|
425
|
+
|
|
426
|
+
describe("Select - option hover highlight", () => {
|
|
427
|
+
test("Mouseenter on option updates focused index styling", async () => {
|
|
428
|
+
const { user } = setupTest();
|
|
429
|
+
const trigger = screen.getByRole("button");
|
|
430
|
+
|
|
431
|
+
await user.click(trigger);
|
|
432
|
+
const options = screen.getAllByRole("option");
|
|
433
|
+
|
|
434
|
+
// Hover over the third option
|
|
435
|
+
await fireEvent.mouseEnter(options[2]);
|
|
436
|
+
|
|
437
|
+
// The hovered option should have the focused styling
|
|
438
|
+
expect(options[2]).toHaveClass("bg-gray-100");
|
|
439
|
+
});
|
|
440
|
+
});
|
|
441
|
+
|
|
442
|
+
describe("Select - trigger refocuses after selection", () => {
|
|
443
|
+
test("Trigger element receives focus after item selection", async () => {
|
|
444
|
+
const { user } = setupTest();
|
|
445
|
+
const trigger = screen.getByRole("button");
|
|
446
|
+
|
|
447
|
+
await user.click(trigger);
|
|
448
|
+
await user.click(screen.getByText("Option 2"));
|
|
449
|
+
|
|
450
|
+
expect(trigger).toHaveFocus();
|
|
451
|
+
});
|
|
452
|
+
});
|
|
453
|
+
|
|
454
|
+
describe("Select - click outside when already closed", () => {
|
|
455
|
+
test("Does not error when clicking outside while dropdown is closed", async () => {
|
|
456
|
+
const { user } = setupTest();
|
|
457
|
+
// Just clicking body when dropdown is closed should be fine
|
|
458
|
+
await user.click(document.body);
|
|
459
|
+
expect(screen.queryByRole("listbox")).not.toBeInTheDocument();
|
|
460
|
+
});
|
|
461
|
+
});
|
|
462
|
+
|
|
463
|
+
describe("Select - opening focuses current selected value", () => {
|
|
464
|
+
test("Opens with currently selected item focused", async () => {
|
|
465
|
+
const { user } = setupTest({ value: "opt2" });
|
|
466
|
+
const trigger = screen.getByRole("button");
|
|
467
|
+
|
|
468
|
+
await user.click(trigger);
|
|
469
|
+
const options = screen.getAllByRole("option");
|
|
470
|
+
|
|
471
|
+
// opt2 is at index 1, so the focused option should have bg-gray-100
|
|
472
|
+
expect(options[1]).toHaveClass("bg-gray-100");
|
|
473
|
+
});
|
|
474
|
+
});
|
|
475
|
+
|
|
476
|
+
describe("Select - Enter/Space to select focused item", () => {
|
|
477
|
+
test("Enter key selects the currently focused item", async () => {
|
|
478
|
+
const changeSpy = vi.fn();
|
|
479
|
+
const { user } = setupTest({ onchange: changeSpy });
|
|
480
|
+
const trigger = screen.getByRole("button");
|
|
481
|
+
|
|
482
|
+
// Open with Enter
|
|
483
|
+
trigger.focus();
|
|
484
|
+
await user.keyboard("{Enter}");
|
|
485
|
+
expect(screen.getByRole("listbox")).toBeInTheDocument();
|
|
486
|
+
|
|
487
|
+
// Move down and select
|
|
488
|
+
await user.keyboard("{ArrowDown}");
|
|
489
|
+
await user.keyboard("{ArrowDown}");
|
|
490
|
+
await user.keyboard("{Enter}");
|
|
491
|
+
|
|
492
|
+
expect(changeSpy).toHaveBeenCalledWith({
|
|
493
|
+
value: "opt2",
|
|
494
|
+
item: { name: "Option 2", value: "opt2" },
|
|
495
|
+
});
|
|
496
|
+
});
|
|
497
|
+
|
|
498
|
+
test("Space key selects the currently focused item", async () => {
|
|
499
|
+
const changeSpy = vi.fn();
|
|
500
|
+
const { user } = setupTest({ onchange: changeSpy });
|
|
501
|
+
const trigger = screen.getByRole("button");
|
|
502
|
+
|
|
503
|
+
// Open
|
|
504
|
+
trigger.focus();
|
|
505
|
+
await user.keyboard(" ");
|
|
506
|
+
expect(screen.getByRole("listbox")).toBeInTheDocument();
|
|
507
|
+
|
|
508
|
+
// Navigate to index 0, then select with Space
|
|
509
|
+
await user.keyboard("{ArrowDown}");
|
|
510
|
+
await user.keyboard(" ");
|
|
511
|
+
|
|
512
|
+
expect(changeSpy).toHaveBeenCalled();
|
|
513
|
+
});
|
|
514
|
+
});
|
|
515
|
+
|
|
516
|
+
describe("Select - other select instance closing", () => {
|
|
517
|
+
test("Closes when another select instance opens", async () => {
|
|
518
|
+
const { user } = setupTest({ id: "select-1" });
|
|
519
|
+
const trigger1 = screen.getByRole("button");
|
|
520
|
+
|
|
521
|
+
await user.click(trigger1);
|
|
522
|
+
expect(screen.getByRole("listbox")).toBeInTheDocument();
|
|
523
|
+
|
|
524
|
+
// Simulate another select opening by dispatching the custom event
|
|
525
|
+
window.dispatchEvent(new CustomEvent('select-opened', { detail: { instanceId: 'other-instance' } }));
|
|
526
|
+
|
|
527
|
+
// The Svelte reactive update may need a tick; use waitFor
|
|
528
|
+
const { waitFor } = await import("@testing-library/svelte");
|
|
529
|
+
await waitFor(() => {
|
|
530
|
+
expect(screen.queryByRole("listbox")).not.toBeInTheDocument();
|
|
531
|
+
});
|
|
532
|
+
});
|
|
533
|
+
|
|
534
|
+
test("Does not close when the same instance dispatches select-opened", async () => {
|
|
535
|
+
// We cannot easily test this from the outside since instanceId is internal,
|
|
536
|
+
// but we can verify the dropdown stays open after its own click
|
|
537
|
+
const { user } = setupTest();
|
|
538
|
+
const trigger = screen.getByRole("button");
|
|
539
|
+
|
|
540
|
+
await user.click(trigger);
|
|
541
|
+
expect(screen.getByRole("listbox")).toBeInTheDocument();
|
|
542
|
+
|
|
543
|
+
// Clicking the same trigger toggles it closed and open
|
|
544
|
+
await user.click(trigger);
|
|
545
|
+
expect(screen.queryByRole("listbox")).not.toBeInTheDocument();
|
|
546
|
+
});
|
|
547
|
+
});
|
|
548
|
+
|
|
549
|
+
describe("Select - no error text", () => {
|
|
550
|
+
test("Does not render error paragraph when error is empty", () => {
|
|
551
|
+
setupTest({ error: "" });
|
|
552
|
+
// The trigger should be present with normal border
|
|
553
|
+
const trigger = screen.getByRole("button");
|
|
554
|
+
expect(trigger).toHaveClass("border-gray-300");
|
|
555
|
+
// There should be no error paragraph element
|
|
556
|
+
const errorParagraph = document.querySelector('p');
|
|
557
|
+
expect(errorParagraph).not.toBeInTheDocument();
|
|
558
|
+
});
|
|
559
|
+
});
|
|
560
|
+
|
|
561
|
+
describe("Select - portal mode", () => {
|
|
562
|
+
test("Portal mode renders dropdown via portal when open", async () => {
|
|
563
|
+
const { user } = setupTest({ portal: true });
|
|
564
|
+
const trigger = screen.getByRole("button");
|
|
565
|
+
|
|
566
|
+
await user.click(trigger);
|
|
567
|
+
|
|
568
|
+
// Portal dropdown should be rendered (it uses use:portalAction to move to body)
|
|
569
|
+
const listbox = screen.getByRole("listbox");
|
|
570
|
+
expect(listbox).toBeInTheDocument();
|
|
571
|
+
// Portal dropdown has 'fixed' class instead of 'absolute'
|
|
572
|
+
expect(listbox).toHaveClass("fixed");
|
|
573
|
+
});
|
|
574
|
+
|
|
575
|
+
test("Portal mode renders items correctly", async () => {
|
|
576
|
+
const changeSpy = vi.fn();
|
|
577
|
+
const { user } = setupTest({ portal: true, onchange: changeSpy });
|
|
578
|
+
const trigger = screen.getByRole("button");
|
|
579
|
+
|
|
580
|
+
await user.click(trigger);
|
|
581
|
+
|
|
582
|
+
const options = screen.getAllByRole("option");
|
|
583
|
+
expect(options).toHaveLength(3);
|
|
584
|
+
|
|
585
|
+
// Select an item in portal mode
|
|
586
|
+
await user.click(screen.getByText("Option 3"));
|
|
587
|
+
expect(changeSpy).toHaveBeenCalledWith({
|
|
588
|
+
value: "opt3",
|
|
589
|
+
item: { name: "Option 3", value: "opt3" },
|
|
590
|
+
});
|
|
591
|
+
});
|
|
592
|
+
|
|
593
|
+
test("Portal dropdown is not rendered when closed", () => {
|
|
594
|
+
setupTest({ portal: true });
|
|
595
|
+
expect(screen.queryByRole("listbox")).not.toBeInTheDocument();
|
|
596
|
+
});
|
|
597
|
+
|
|
598
|
+
test("Non-portal dropdown has absolute positioning", async () => {
|
|
599
|
+
const { user } = setupTest({ portal: false });
|
|
600
|
+
const trigger = screen.getByRole("button");
|
|
601
|
+
|
|
602
|
+
await user.click(trigger);
|
|
603
|
+
|
|
604
|
+
const listbox = screen.getByRole("listbox");
|
|
605
|
+
expect(listbox).toHaveClass("absolute");
|
|
606
|
+
expect(listbox).not.toHaveClass("fixed");
|
|
607
|
+
});
|
|
608
|
+
});
|
|
609
|
+
|
|
610
|
+
describe("Select - option id attributes", () => {
|
|
611
|
+
test("Options have correct id attributes based on select id", async () => {
|
|
612
|
+
const { user } = setupTest({ id: "my-select" });
|
|
613
|
+
const trigger = screen.getByRole("button");
|
|
614
|
+
|
|
615
|
+
await user.click(trigger);
|
|
616
|
+
|
|
617
|
+
const options = screen.getAllByRole("option");
|
|
618
|
+
expect(options[0]).toHaveAttribute("id", "my-select-option-0");
|
|
619
|
+
expect(options[1]).toHaveAttribute("id", "my-select-option-1");
|
|
620
|
+
expect(options[2]).toHaveAttribute("id", "my-select-option-2");
|
|
621
|
+
});
|
|
622
|
+
|
|
623
|
+
test("Options use name for id when id is not provided", async () => {
|
|
624
|
+
const { user } = setupTest({ name: "my-field", id: "" });
|
|
625
|
+
const trigger = screen.getByRole("button");
|
|
626
|
+
|
|
627
|
+
await user.click(trigger);
|
|
628
|
+
|
|
629
|
+
const options = screen.getAllByRole("option");
|
|
630
|
+
expect(options[0]).toHaveAttribute("id", "my-field-option-0");
|
|
631
|
+
});
|
|
632
|
+
});
|
|
@@ -144,6 +144,15 @@ describe('Label Custom Default Class', () => {
|
|
|
144
144
|
});
|
|
145
145
|
});
|
|
146
146
|
|
|
147
|
+
describe('Label Color Fallback', () => {
|
|
148
|
+
test('falls back to gray when an invalid color is provided', () => {
|
|
149
|
+
const { container } = render(Label, { props: { color: 'invalid-color' } });
|
|
150
|
+
const label = container.querySelector('label');
|
|
151
|
+
expect(label).toHaveClass('text-gray-900');
|
|
152
|
+
expect(label).toHaveClass('dark:text-gray-300');
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
|
|
147
156
|
describe('Label Class Composition', () => {
|
|
148
157
|
test('combines defaultClass, color class, and custom class', () => {
|
|
149
158
|
const { container } = render(Label, {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LandingButton.spec.d.ts","sourceRoot":"","sources":["../../../src/lib/primitives/LandingButton/LandingButton.spec.js"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { render } from '@testing-library/svelte';
|
|
2
|
+
import { expect, describe, test, vi } from 'vitest';
|
|
3
|
+
import LandingButton from './LandingButton.svelte';
|
|
4
|
+
|
|
5
|
+
describe('LandingButton', () => {
|
|
6
|
+
test('renders a button by default', () => {
|
|
7
|
+
const { container } = render(LandingButton);
|
|
8
|
+
expect(container.querySelector('button')).toBeInTheDocument();
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
test('button has type="button"', () => {
|
|
12
|
+
const { container } = render(LandingButton);
|
|
13
|
+
expect(container.querySelector('button')).toHaveAttribute('type', 'button');
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
test('renders an anchor when href is provided', () => {
|
|
17
|
+
const { container } = render(LandingButton, { props: { href: '/page' } });
|
|
18
|
+
expect(container.querySelector('a')).toBeInTheDocument();
|
|
19
|
+
expect(container.querySelector('a')).toHaveAttribute('href', '/page');
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
test('no button when href is provided', () => {
|
|
23
|
+
const { container } = render(LandingButton, { props: { href: '/page' } });
|
|
24
|
+
expect(container.querySelector('button')).not.toBeInTheDocument();
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test('disabled state', () => {
|
|
28
|
+
const { container } = render(LandingButton, { props: { disabled: true } });
|
|
29
|
+
const btn = container.querySelector('button');
|
|
30
|
+
expect(btn).toBeDisabled();
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
test('loading state disables button', () => {
|
|
34
|
+
const { container } = render(LandingButton, { props: { loading: true } });
|
|
35
|
+
const btn = container.querySelector('button');
|
|
36
|
+
expect(btn).toBeDisabled();
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
test('primary variant is default', () => {
|
|
40
|
+
const { container } = render(LandingButton);
|
|
41
|
+
// Should render without issues
|
|
42
|
+
expect(container.querySelector('button')).toBeInTheDocument();
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test('secondary variant renders', () => {
|
|
46
|
+
const { container } = render(LandingButton, { props: { variant: 'secondary' } });
|
|
47
|
+
expect(container.querySelector('button')).toBeInTheDocument();
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
test('applies custom className', () => {
|
|
51
|
+
const { container } = render(LandingButton, { props: { class: 'my-landing-btn' } });
|
|
52
|
+
const btn = container.querySelector('button');
|
|
53
|
+
expect(btn).toHaveClass('my-landing-btn');
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
test('anchor with disabled state', () => {
|
|
57
|
+
const { container } = render(LandingButton, { props: { href: '/page', disabled: true } });
|
|
58
|
+
const a = container.querySelector('a');
|
|
59
|
+
expect(a).toBeInTheDocument();
|
|
60
|
+
});
|
|
61
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MenuItem.spec.d.ts","sourceRoot":"","sources":["../../../src/lib/primitives/MenuItem/MenuItem.spec.js"],"names":[],"mappings":""}
|