sveltacular 0.0.77 → 1.0.1
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/README.md +142 -15
- package/dist/forms/base-input-wrapper.svelte +99 -0
- package/dist/forms/base-input-wrapper.svelte.d.ts +15 -0
- package/dist/forms/bool-box/bool-box.svelte +30 -16
- package/dist/forms/bool-box/bool-box.svelte.d.ts +9 -23
- package/dist/forms/button/button.svelte +153 -89
- package/dist/forms/button/button.svelte.d.ts +25 -31
- package/dist/forms/check-box/check-box-group.svelte +69 -31
- package/dist/forms/check-box/check-box-group.svelte.d.ts +11 -29
- package/dist/forms/check-box/check-box.svelte +57 -33
- package/dist/forms/check-box/check-box.svelte.d.ts +15 -27
- package/dist/forms/check-box/index.d.ts +2 -0
- package/dist/forms/check-box/index.js +2 -0
- package/dist/forms/combo/new-or-existing-combo.svelte +37 -18
- package/dist/forms/combo/new-or-existing-combo.svelte.d.ts +15 -27
- package/dist/forms/combo-box/combo-box.svelte +643 -0
- package/dist/forms/combo-box/combo-box.svelte.d.ts +42 -0
- package/dist/forms/combo-box/index.d.ts +1 -0
- package/dist/forms/combo-box/index.js +1 -0
- package/dist/forms/date-box/date-box.svelte +82 -53
- package/dist/forms/date-box/date-box.svelte.d.ts +21 -34
- package/dist/forms/file-area/file-area.svelte +109 -57
- package/dist/forms/file-area/file-area.svelte.d.ts +12 -24
- package/dist/forms/file-box/file-box.svelte +38 -23
- package/dist/forms/file-box/file-box.svelte.d.ts +14 -27
- package/dist/forms/form-field.svelte +76 -13
- package/dist/forms/form-field.svelte.d.ts +15 -20
- package/dist/forms/form-footer.svelte +6 -3
- package/dist/forms/form-footer.svelte.d.ts +6 -28
- package/dist/forms/form-header.svelte +15 -4
- package/dist/forms/form-header.svelte.d.ts +8 -20
- package/dist/forms/form-label.svelte +15 -6
- package/dist/forms/form-label.svelte.d.ts +8 -21
- package/dist/forms/form-row.svelte +29 -0
- package/dist/forms/form-row.svelte.d.ts +7 -0
- package/dist/forms/form-section.svelte +15 -4
- package/dist/forms/form-section.svelte.d.ts +8 -20
- package/dist/forms/form.svelte +36 -13
- package/dist/forms/form.svelte.d.ts +11 -24
- package/dist/forms/index.d.ts +26 -0
- package/dist/forms/index.js +31 -0
- package/dist/forms/info-box/info-box.svelte +17 -10
- package/dist/forms/info-box/info-box.svelte.d.ts +8 -21
- package/dist/forms/list-box/index.d.ts +2 -0
- package/dist/forms/list-box/index.js +1 -0
- package/dist/forms/list-box/list-box.svelte +188 -111
- package/dist/forms/list-box/list-box.svelte.d.ts +16 -28
- package/dist/forms/money-box/money-box.svelte +224 -178
- package/dist/forms/money-box/money-box.svelte.d.ts +16 -30
- package/dist/forms/number-box/number-box.svelte +82 -62
- package/dist/forms/number-box/number-box.svelte.d.ts +17 -30
- package/dist/forms/phone-box/index.d.ts +1 -0
- package/dist/forms/phone-box/index.js +1 -0
- package/dist/forms/phone-box/phone-box.svelte +156 -116
- package/dist/forms/phone-box/phone-box.svelte.d.ts +8 -22
- package/dist/forms/radio-group/index.d.ts +2 -0
- package/dist/forms/radio-group/index.js +2 -0
- package/dist/forms/radio-group/radio-box.svelte +23 -8
- package/dist/forms/radio-group/radio-box.svelte.d.ts +10 -21
- package/dist/forms/radio-group/radio-group.svelte +25 -15
- package/dist/forms/radio-group/radio-group.svelte.d.ts +10 -23
- package/dist/forms/slider/slider.svelte +206 -0
- package/dist/forms/slider/slider.svelte.d.ts +17 -0
- package/dist/forms/switch-box/switch-box.svelte +35 -21
- package/dist/forms/switch-box/switch-box.svelte.d.ts +9 -22
- package/dist/forms/text-area/text-area.svelte +94 -17
- package/dist/forms/text-area/text-area.svelte.d.ts +15 -25
- package/dist/forms/text-box/text-box.svelte +244 -79
- package/dist/forms/text-box/text-box.svelte.d.ts +28 -38
- package/dist/forms/time-box/time-box.svelte +63 -0
- package/dist/forms/time-box/time-box.svelte.d.ts +12 -0
- package/dist/forms/url-box/url-box.svelte +32 -18
- package/dist/forms/url-box/url-box.svelte.d.ts +9 -22
- package/dist/forms/validation.d.ts +60 -0
- package/dist/forms/validation.js +123 -0
- package/dist/generic/address/address.svelte +22 -11
- package/dist/generic/address/address.svelte.d.ts +9 -21
- package/dist/generic/avatar/avatar.svelte +87 -0
- package/dist/generic/avatar/avatar.svelte.d.ts +10 -0
- package/dist/generic/badge/badge.svelte +82 -0
- package/dist/generic/badge/badge.svelte.d.ts +11 -0
- package/dist/generic/card/card-container.svelte +41 -12
- package/dist/generic/card/card-container.svelte.d.ts +8 -20
- package/dist/generic/card/card.svelte +47 -27
- package/dist/generic/card/card.svelte.d.ts +9 -21
- package/dist/generic/card/index.d.ts +3 -0
- package/dist/generic/card/index.js +2 -0
- package/dist/generic/chip/chip.svelte +91 -0
- package/dist/generic/chip/chip.svelte.d.ts +11 -0
- package/dist/generic/date/date-time.svelte +86 -58
- package/dist/generic/date/date-time.svelte.d.ts +10 -22
- package/dist/generic/divider/divider.svelte.d.ts +22 -21
- package/dist/generic/dot/dot.svelte +13 -4
- package/dist/generic/dot/dot.svelte.d.ts +7 -19
- package/dist/generic/dropdown-item/dropdown-item.svelte +24 -12
- package/dist/generic/dropdown-item/dropdown-item.svelte.d.ts +10 -23
- package/dist/generic/email/email.svelte +6 -4
- package/dist/generic/email/email.svelte.d.ts +5 -17
- package/dist/generic/empty/empty.svelte +57 -26
- package/dist/generic/empty/empty.svelte.d.ts +11 -23
- package/dist/generic/header/header.svelte +26 -10
- package/dist/generic/header/header.svelte.d.ts +10 -22
- package/dist/generic/index.d.ts +28 -0
- package/dist/generic/index.js +31 -0
- package/dist/generic/link/link.svelte +20 -7
- package/dist/generic/link/link.svelte.d.ts +11 -23
- package/dist/generic/list/index.d.ts +4 -0
- package/dist/generic/list/index.js +3 -0
- package/dist/generic/list/list-item.svelte +17 -13
- package/dist/generic/list/list-item.svelte.d.ts +6 -17
- package/dist/generic/list/list.d.ts +2 -2
- package/dist/generic/list/list.svelte +28 -15
- package/dist/generic/list/list.svelte.d.ts +9 -21
- package/dist/generic/menu/menu.svelte +163 -54
- package/dist/generic/menu/menu.svelte.d.ts +16 -26
- package/dist/generic/notice/notice.svelte +119 -80
- package/dist/generic/notice/notice.svelte.d.ts +17 -28
- package/dist/generic/overlay.svelte +40 -14
- package/dist/generic/overlay.svelte.d.ts +9 -21
- package/dist/generic/panel/panel.svelte +16 -6
- package/dist/generic/panel/panel.svelte.d.ts +8 -20
- package/dist/generic/phone/phone.svelte +30 -20
- package/dist/generic/phone/phone.svelte.d.ts +6 -18
- package/dist/generic/pill/pill.svelte +47 -33
- package/dist/generic/pill/pill.svelte.d.ts +10 -23
- package/dist/generic/popover/popover.svelte +226 -0
- package/dist/generic/popover/popover.svelte.d.ts +15 -0
- package/dist/generic/rating/rating.svelte +85 -0
- package/dist/generic/rating/rating.svelte.d.ts +11 -0
- package/dist/generic/scorecard/scorecard.svelte +34 -18
- package/dist/generic/scorecard/scorecard.svelte.d.ts +9 -21
- package/dist/generic/section/section.svelte +28 -9
- package/dist/generic/section/section.svelte.d.ts +11 -23
- package/dist/generic/spinner/spinner.svelte +64 -0
- package/dist/generic/spinner/spinner.svelte.d.ts +8 -0
- package/dist/generic/theme-provider/index.d.ts +1 -0
- package/dist/generic/theme-provider/index.js +1 -0
- package/dist/generic/theme-provider/theme-provider-demo.svelte +182 -0
- package/dist/generic/theme-provider/theme-provider-demo.svelte.d.ts +3 -0
- package/dist/generic/theme-provider/theme-provider.svelte +83 -0
- package/dist/generic/theme-provider/theme-provider.svelte.d.ts +44 -0
- package/dist/generic/toaster/toaster.svelte +31 -6
- package/dist/generic/toaster/toaster.svelte.d.ts +7 -17
- package/dist/generic/tooltip/tooltip.svelte +389 -0
- package/dist/generic/tooltip/tooltip.svelte.d.ts +21 -0
- package/dist/helpers/ago.d.ts +6 -0
- package/dist/helpers/ago.js +6 -0
- package/dist/helpers/animation-actions.d.ts +124 -0
- package/dist/helpers/animation-actions.js +299 -0
- package/dist/helpers/animations.d.ts +198 -0
- package/dist/helpers/animations.js +280 -0
- package/dist/helpers/announcer.d.ts +118 -0
- package/dist/helpers/announcer.js +250 -0
- package/dist/helpers/copy-to-clipboard.svelte.d.ts +5 -0
- package/dist/helpers/copy-to-clipboard.svelte.js +28 -0
- package/dist/helpers/debounce.d.ts +7 -0
- package/dist/helpers/debounce.js +7 -0
- package/dist/helpers/focus.d.ts +123 -0
- package/dist/helpers/focus.js +335 -0
- package/dist/helpers/fuzzy-search.d.ts +41 -0
- package/dist/helpers/fuzzy-search.js +114 -0
- package/dist/helpers/index.d.ts +24 -0
- package/dist/helpers/index.js +24 -0
- package/dist/helpers/navigate-to.d.ts +4 -0
- package/dist/helpers/navigate-to.js +4 -0
- package/dist/helpers/positioning.d.ts +97 -0
- package/dist/helpers/positioning.js +230 -0
- package/dist/helpers/round-to-decimals.d.ts +7 -5
- package/dist/helpers/round-to-decimals.js +7 -5
- package/dist/helpers/spring.svelte.d.ts +97 -0
- package/dist/helpers/spring.svelte.js +216 -0
- package/dist/helpers/subscribable.d.ts +1 -1
- package/dist/helpers/theme.svelte.d.ts +63 -0
- package/dist/helpers/theme.svelte.js +123 -0
- package/dist/helpers/unique-id.d.ts +4 -0
- package/dist/helpers/unique-id.js +4 -0
- package/dist/helpers/use-position.svelte.d.ts +96 -0
- package/dist/helpers/use-position.svelte.js +189 -0
- package/dist/helpers/use-virtual-list.svelte.d.ts +121 -0
- package/dist/helpers/use-virtual-list.svelte.js +239 -0
- package/dist/icons/angle-right-icon.svelte +2 -1
- package/dist/icons/angle-right-icon.svelte.d.ts +16 -14
- package/dist/icons/angle-up-icon.svelte.d.ts +22 -21
- package/dist/icons/check-icon.svelte.d.ts +22 -21
- package/dist/icons/copy-icon.svelte +46 -0
- package/dist/icons/copy-icon.svelte.d.ts +6 -0
- package/dist/icons/envelope-icon.svelte.d.ts +22 -21
- package/dist/icons/folder-open-icon.svelte.d.ts +22 -21
- package/dist/icons/hamburger-icon.svelte.d.ts +22 -21
- package/dist/icons/home-icon.svelte +2 -1
- package/dist/icons/home-icon.svelte.d.ts +16 -14
- package/dist/icons/index.d.ts +13 -0
- package/dist/icons/index.js +13 -0
- package/dist/icons/link-icon.svelte.d.ts +22 -21
- package/dist/icons/mobile-phone-icon.svelte.d.ts +22 -21
- package/dist/icons/phone-icon.svelte.d.ts +22 -21
- package/dist/icons/svg-icon.svelte +46 -10
- package/dist/icons/svg-icon.svelte.d.ts +13 -25
- package/dist/icons/upload-icon.svelte.d.ts +22 -21
- package/dist/images/icon.svelte +9 -3
- package/dist/images/icon.svelte.d.ts +6 -18
- package/dist/images/image.svelte +28 -8
- package/dist/images/image.svelte.d.ts +14 -28
- package/dist/images/index.d.ts +2 -0
- package/dist/images/index.js +2 -0
- package/dist/index.d.ts +13 -122
- package/dist/index.js +27 -135
- package/dist/layout/flex-col.svelte +65 -16
- package/dist/layout/flex-col.svelte.d.ts +12 -24
- package/dist/layout/flex-item.svelte +13 -3
- package/dist/layout/flex-item.svelte.d.ts +8 -20
- package/dist/layout/flex-row.svelte +70 -15
- package/dist/layout/flex-row.svelte.d.ts +14 -26
- package/dist/layout/grid.svelte +7 -1
- package/dist/layout/grid.svelte.d.ts +6 -28
- package/dist/layout/index.d.ts +4 -0
- package/dist/layout/index.js +4 -0
- package/dist/modals/alert.svelte +42 -28
- package/dist/modals/alert.svelte.d.ts +13 -26
- package/dist/modals/confirm.svelte +54 -37
- package/dist/modals/confirm.svelte.d.ts +16 -29
- package/dist/modals/dialog-body.svelte +10 -4
- package/dist/modals/dialog-body.svelte.d.ts +6 -28
- package/dist/modals/dialog-close-button.svelte +15 -9
- package/dist/modals/dialog-close-button.svelte.d.ts +6 -19
- package/dist/modals/dialog-footer.svelte +6 -3
- package/dist/modals/dialog-footer.svelte.d.ts +6 -28
- package/dist/modals/dialog-header.svelte +13 -1
- package/dist/modals/dialog-header.svelte.d.ts +7 -28
- package/dist/modals/dialog-window.svelte +42 -14
- package/dist/modals/dialog-window.svelte.d.ts +9 -19
- package/dist/modals/index.d.ts +9 -0
- package/dist/modals/index.js +9 -0
- package/dist/modals/modal.svelte +88 -23
- package/dist/modals/modal.svelte.d.ts +14 -24
- package/dist/modals/prompt.svelte +71 -49
- package/dist/modals/prompt.svelte.d.ts +19 -32
- package/dist/navigation/accordion/accordion.svelte +104 -0
- package/dist/navigation/accordion/accordion.svelte.d.ts +9 -0
- package/dist/navigation/app-bar/app-bar.svelte +26 -12
- package/dist/navigation/app-bar/app-bar.svelte.d.ts +10 -22
- package/dist/navigation/app-bar/app-branding.svelte +10 -5
- package/dist/navigation/app-bar/app-branding.svelte.d.ts +6 -17
- package/dist/navigation/app-bar/app-logo.svelte +20 -5
- package/dist/navigation/app-bar/app-logo.svelte.d.ts +9 -21
- package/dist/navigation/app-bar/app-nav-item.svelte +26 -13
- package/dist/navigation/app-bar/app-nav-item.svelte.d.ts +9 -22
- package/dist/navigation/app-bar/app-nav.svelte +39 -12
- package/dist/navigation/app-bar/app-nav.svelte.d.ts +8 -20
- package/dist/navigation/app-bar/index.d.ts +5 -0
- package/dist/navigation/app-bar/index.js +5 -0
- package/dist/navigation/breadcrumbs/breadcrumbs.svelte +54 -27
- package/dist/navigation/breadcrumbs/breadcrumbs.svelte.d.ts +12 -23
- package/dist/navigation/command-palette/command-palette.svelte +758 -0
- package/dist/navigation/command-palette/command-palette.svelte.d.ts +65 -0
- package/dist/navigation/command-palette/index.d.ts +2 -0
- package/dist/navigation/command-palette/index.js +1 -0
- package/dist/navigation/context-menu/README.md +147 -0
- package/dist/navigation/context-menu/context-menu-divider.svelte +22 -0
- package/dist/navigation/context-menu/context-menu-divider.svelte.d.ts +18 -0
- package/dist/navigation/context-menu/context-menu-item.svelte +268 -0
- package/dist/navigation/context-menu/context-menu-item.svelte.d.ts +19 -0
- package/dist/navigation/context-menu/context-menu.svelte +226 -0
- package/dist/navigation/context-menu/context-menu.svelte.d.ts +38 -0
- package/dist/navigation/context-menu/index.d.ts +3 -0
- package/dist/navigation/context-menu/index.js +3 -0
- package/dist/navigation/drawer/drawer.svelte +137 -0
- package/dist/navigation/drawer/drawer.svelte.d.ts +11 -0
- package/dist/navigation/dropdown-button/dropdown-button.svelte +58 -19
- package/dist/navigation/dropdown-button/dropdown-button.svelte.d.ts +10 -22
- package/dist/navigation/index.d.ts +11 -0
- package/dist/navigation/index.js +14 -0
- package/dist/navigation/pagination/pagination.svelte +55 -37
- package/dist/navigation/pagination/pagination.svelte.d.ts +10 -23
- package/dist/navigation/side-bar/side-bar.svelte +18 -9
- package/dist/navigation/side-bar/side-bar.svelte.d.ts +7 -19
- package/dist/navigation/tabs/index.d.ts +4 -0
- package/dist/navigation/tabs/index.js +3 -0
- package/dist/navigation/tabs/tab-context.d.ts +12 -6
- package/dist/navigation/tabs/tab-group.svelte +268 -52
- package/dist/navigation/tabs/tab-group.svelte.d.ts +9 -22
- package/dist/navigation/tabs/tab.svelte +64 -33
- package/dist/navigation/tabs/tab.svelte.d.ts +11 -24
- package/dist/navigation/wizard/index.d.ts +3 -0
- package/dist/navigation/wizard/index.js +2 -0
- package/dist/navigation/wizard/wizard-context.d.ts +13 -8
- package/dist/navigation/wizard/wizard-step.svelte +38 -13
- package/dist/navigation/wizard/wizard-step.svelte.d.ts +8 -20
- package/dist/navigation/wizard/wizard.svelte +123 -81
- package/dist/navigation/wizard/wizard.svelte.d.ts +15 -28
- package/dist/placeholders/index.d.ts +6 -0
- package/dist/placeholders/index.js +6 -0
- package/dist/placeholders/loading.svelte +39 -23
- package/dist/placeholders/loading.svelte.d.ts +10 -19
- package/dist/placeholders/progress.svelte +7 -6
- package/dist/placeholders/progress.svelte.d.ts +5 -17
- package/dist/placeholders/skeleton-input.svelte +66 -38
- package/dist/placeholders/skeleton-input.svelte.d.ts +5 -17
- package/dist/placeholders/skeleton-paragraph.svelte +25 -0
- package/dist/placeholders/skeleton-paragraph.svelte.d.ts +8 -0
- package/dist/placeholders/skeleton-table.svelte +75 -0
- package/dist/placeholders/skeleton-table.svelte.d.ts +8 -0
- package/dist/placeholders/skeleton-text.svelte +46 -15
- package/dist/placeholders/skeleton-text.svelte.d.ts +7 -19
- package/dist/tables/cell-renderers.d.ts +24 -0
- package/dist/tables/cell-renderers.js +228 -0
- package/dist/tables/data-grid.svelte +332 -118
- package/dist/tables/data-grid.svelte.d.ts +34 -35
- package/dist/tables/index.d.ts +10 -0
- package/dist/tables/index.js +12 -0
- package/dist/tables/table-caption.svelte +13 -4
- package/dist/tables/table-caption.svelte.d.ts +8 -20
- package/dist/tables/table-cell.svelte +45 -14
- package/dist/tables/table-cell.svelte.d.ts +10 -21
- package/dist/tables/table-context.svelte.d.ts +32 -0
- package/dist/tables/table-context.svelte.js +160 -0
- package/dist/tables/table-header-cell.svelte +158 -18
- package/dist/tables/table-header-cell.svelte.d.ts +15 -21
- package/dist/tables/table-header.svelte +31 -6
- package/dist/tables/table-header.svelte.d.ts +7 -28
- package/dist/tables/table-row.svelte +87 -7
- package/dist/tables/table-row.svelte.d.ts +10 -28
- package/dist/tables/table.svelte +61 -2
- package/dist/tables/table.svelte.d.ts +13 -28
- package/dist/test-utils/accessibility-helpers.d.ts +80 -0
- package/dist/test-utils/accessibility-helpers.js +220 -0
- package/dist/test-utils/index.d.ts +8 -0
- package/dist/test-utils/index.js +8 -0
- package/dist/test-utils/mock-helpers.d.ts +68 -0
- package/dist/test-utils/mock-helpers.js +165 -0
- package/dist/test-utils/render-helpers.d.ts +55 -0
- package/dist/test-utils/render-helpers.js +114 -0
- package/dist/test-utils/setup.d.ts +5 -0
- package/dist/test-utils/setup.js +91 -0
- package/dist/test-utils/test-data.d.ts +102 -0
- package/dist/test-utils/test-data.js +99 -0
- package/dist/timeline/index.d.ts +2 -0
- package/dist/timeline/index.js +2 -0
- package/dist/timeline/timeline-item.svelte +26 -9
- package/dist/timeline/timeline-item.svelte.d.ts +13 -25
- package/dist/timeline/timeline.svelte +12 -6
- package/dist/timeline/timeline.svelte.d.ts +6 -28
- package/dist/types/data.d.ts +61 -0
- package/dist/types/date.d.ts +1 -1
- package/dist/types/form.d.ts +20 -2
- package/dist/types/index.d.ts +5 -0
- package/dist/types/index.js +5 -0
- package/dist/types/size.d.ts +22 -0
- package/dist/types/size.js +22 -0
- package/dist/typography/code-block.svelte +89 -10
- package/dist/typography/code-block.svelte.d.ts +7 -19
- package/dist/typography/code.svelte +89 -0
- package/dist/typography/code.svelte.d.ts +7 -0
- package/dist/typography/headline.svelte +29 -9
- package/dist/typography/headline.svelte.d.ts +8 -20
- package/dist/typography/index.d.ts +6 -0
- package/dist/typography/index.js +6 -0
- package/dist/typography/paragraph.svelte +18 -10
- package/dist/typography/paragraph.svelte.d.ts +6 -28
- package/dist/typography/subtitle.svelte +18 -4
- package/dist/typography/subtitle.svelte.d.ts +8 -20
- package/dist/typography/text.svelte +20 -5
- package/dist/typography/text.svelte.d.ts +9 -21
- package/package.json +31 -21
- package/dist/navigation/accordian/accordian.svelte +0 -62
- package/dist/navigation/accordian/accordian.svelte.d.ts +0 -21
- package/dist/tables/table-body.svelte +0 -3
- package/dist/tables/table-body.svelte.d.ts +0 -29
- package/dist/tables/table-footer-cell.svelte +0 -22
- package/dist/tables/table-footer-cell.svelte.d.ts +0 -20
- package/dist/tables/table-footer-row.svelte +0 -3
- package/dist/tables/table-footer-row.svelte.d.ts +0 -29
- package/dist/tables/table-footer.svelte +0 -13
- package/dist/tables/table-footer.svelte.d.ts +0 -29
- package/dist/tables/table-header-row.svelte +0 -4
- package/dist/tables/table-header-row.svelte.d.ts +0 -29
|
@@ -1,16 +1,96 @@
|
|
|
1
|
-
<
|
|
2
|
-
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import type { JsonObject } from '../types/data.js';
|
|
4
|
+
import { getTableContext } from './table-context.svelte.js';
|
|
5
|
+
|
|
6
|
+
let {
|
|
7
|
+
children,
|
|
8
|
+
row = undefined,
|
|
9
|
+
rowIndex = undefined,
|
|
10
|
+
selectable = false
|
|
11
|
+
}: {
|
|
12
|
+
children?: Snippet;
|
|
13
|
+
row?: JsonObject;
|
|
14
|
+
rowIndex?: number;
|
|
15
|
+
selectable?: boolean;
|
|
16
|
+
} = $props();
|
|
17
|
+
|
|
18
|
+
const context = getTableContext();
|
|
19
|
+
|
|
20
|
+
// Get row ID for selection
|
|
21
|
+
let rowId = $derived(
|
|
22
|
+
row && context?.config.rowIdKey
|
|
23
|
+
? (row[context.config.rowIdKey] as string | number)
|
|
24
|
+
: undefined
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
let isSelected = $derived(
|
|
28
|
+
rowId !== undefined && context ? context.isRowSelected(rowId) : false
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
let canSelect = $derived(selectable && context?.config.enableSelection && rowId !== undefined);
|
|
32
|
+
|
|
33
|
+
function handleClick(event: MouseEvent) {
|
|
34
|
+
if (canSelect && rowId !== undefined && rowIndex !== undefined) {
|
|
35
|
+
const shiftKey = event.shiftKey;
|
|
36
|
+
context?.toggleRow(rowId, rowIndex, shiftKey);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function handleKeyDown(event: KeyboardEvent) {
|
|
41
|
+
if (canSelect && (event.key === 'Enter' || event.key === ' ')) {
|
|
42
|
+
event.preventDefault();
|
|
43
|
+
if (rowId !== undefined && rowIndex !== undefined) {
|
|
44
|
+
context?.toggleRow(rowId, rowIndex, event.shiftKey);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
</script>
|
|
49
|
+
|
|
50
|
+
<tr
|
|
51
|
+
class:selectable={canSelect}
|
|
52
|
+
class:selected={isSelected}
|
|
53
|
+
aria-selected={canSelect ? isSelected : undefined}
|
|
54
|
+
tabindex={canSelect ? 0 : undefined}
|
|
55
|
+
onclick={handleClick}
|
|
56
|
+
onkeydown={handleKeyDown}
|
|
57
|
+
role={canSelect ? 'row' : undefined}
|
|
58
|
+
>
|
|
59
|
+
{@render children?.()}
|
|
3
60
|
</tr>
|
|
4
61
|
|
|
5
62
|
<style>
|
|
6
63
|
tr {
|
|
7
|
-
background-color: var(--table-row-bg, #fff);
|
|
8
|
-
color: var(--table-row-fg, #000);
|
|
9
|
-
border-bottom: solid 1px var(--table-row-border, #
|
|
64
|
+
background-color: var(--table-row-even-bg, #fff);
|
|
65
|
+
color: var(--table-row-even-fg, #000);
|
|
66
|
+
border-bottom: solid 1px var(--table-row-even-border, #ddd);
|
|
67
|
+
transition: background-color 0.15s ease;
|
|
10
68
|
}
|
|
11
69
|
|
|
12
70
|
tr:nth-of-type(odd) {
|
|
13
|
-
background-color: var(--table-row-
|
|
14
|
-
color: var(--table-row-
|
|
71
|
+
background-color: var(--table-row-odd-bg, #f9f9f9);
|
|
72
|
+
color: var(--table-row-odd-fg, #000);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
tr.selectable {
|
|
76
|
+
cursor: pointer;
|
|
77
|
+
|
|
78
|
+
&:hover {
|
|
79
|
+
background-color: var(--table-row-hover-bg, rgba(0, 0, 0, 0.05));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
&:focus {
|
|
83
|
+
outline: 2px solid var(--focus-color, #0066cc);
|
|
84
|
+
outline-offset: -2px;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
tr.selected {
|
|
89
|
+
background-color: var(--table-row-selected-bg, rgba(0, 102, 204, 0.1)) !important;
|
|
90
|
+
border-color: var(--table-row-selected-border, #0066cc);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
tr.selected.selectable:hover {
|
|
94
|
+
background-color: var(--table-row-selected-hover-bg, rgba(0, 102, 204, 0.15)) !important;
|
|
15
95
|
}
|
|
16
96
|
</style>
|
|
@@ -1,29 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}, {
|
|
9
|
-
default: {};
|
|
10
|
-
}> {
|
|
11
|
-
}
|
|
12
|
-
export type TableRowProps = typeof __propDef.props;
|
|
13
|
-
export type TableRowEvents = typeof __propDef.events;
|
|
14
|
-
export type TableRowSlots = typeof __propDef.slots;
|
|
15
|
-
import { SvelteComponent } from "svelte";
|
|
16
|
-
declare const __propDef: {
|
|
17
|
-
props: {
|
|
18
|
-
[x: string]: never;
|
|
19
|
-
};
|
|
20
|
-
events: {
|
|
21
|
-
[evt: string]: CustomEvent<any>;
|
|
22
|
-
};
|
|
23
|
-
slots: {
|
|
24
|
-
default: {};
|
|
25
|
-
};
|
|
26
|
-
exports?: undefined;
|
|
27
|
-
bindings?: undefined;
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { JsonObject } from '../types/data.js';
|
|
3
|
+
type $$ComponentProps = {
|
|
4
|
+
children?: Snippet;
|
|
5
|
+
row?: JsonObject;
|
|
6
|
+
rowIndex?: number;
|
|
7
|
+
selectable?: boolean;
|
|
28
8
|
};
|
|
29
|
-
|
|
9
|
+
declare const TableRow: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
10
|
+
type TableRow = ReturnType<typeof TableRow>;
|
|
11
|
+
export default TableRow;
|
package/dist/tables/table.svelte
CHANGED
|
@@ -1,5 +1,50 @@
|
|
|
1
|
-
<
|
|
2
|
-
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import type { JsonObject } from '../types/data.js';
|
|
4
|
+
import { createTableContext, type TableContextConfig } from './table-context.svelte.js';
|
|
5
|
+
import { untrack } from 'svelte';
|
|
6
|
+
|
|
7
|
+
let {
|
|
8
|
+
children,
|
|
9
|
+
enableSorting = true,
|
|
10
|
+
enableSelection = false,
|
|
11
|
+
selectionMode = 'multi',
|
|
12
|
+
rowIdKey = 'id',
|
|
13
|
+
stickyHeader = false,
|
|
14
|
+
onSort = undefined,
|
|
15
|
+
onSelectionChange = undefined
|
|
16
|
+
}: {
|
|
17
|
+
children?: Snippet;
|
|
18
|
+
enableSorting?: boolean;
|
|
19
|
+
enableSelection?: boolean;
|
|
20
|
+
selectionMode?: 'single' | 'multi';
|
|
21
|
+
rowIdKey?: string;
|
|
22
|
+
stickyHeader?: boolean;
|
|
23
|
+
onSort?: (column: string, direction: 'asc' | 'desc') => void;
|
|
24
|
+
onSelectionChange?: (selectedIds: Set<string | number>) => void;
|
|
25
|
+
} = $props();
|
|
26
|
+
|
|
27
|
+
// Create table context for child components
|
|
28
|
+
// Using untrack() to indicate we intentionally want non-reactive initial values
|
|
29
|
+
const config: TableContextConfig<JsonObject> = {
|
|
30
|
+
enableSorting: untrack(() => enableSorting),
|
|
31
|
+
enableSelection: untrack(() => enableSelection),
|
|
32
|
+
selectionMode: untrack(() => selectionMode),
|
|
33
|
+
rowIdKey: untrack(() => rowIdKey),
|
|
34
|
+
onSort: untrack(() => onSort),
|
|
35
|
+
onSelectionChange: untrack(() => onSelectionChange)
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
createTableContext(config);
|
|
39
|
+
</script>
|
|
40
|
+
|
|
41
|
+
<table
|
|
42
|
+
class:sticky-header={stickyHeader}
|
|
43
|
+
role="grid"
|
|
44
|
+
aria-rowcount={enableSelection ? undefined : undefined}
|
|
45
|
+
aria-colcount={undefined}
|
|
46
|
+
>
|
|
47
|
+
{@render children?.()}
|
|
3
48
|
</table>
|
|
4
49
|
|
|
5
50
|
<style>
|
|
@@ -7,5 +52,19 @@
|
|
|
7
52
|
width: 100%;
|
|
8
53
|
border-collapse: collapse;
|
|
9
54
|
font-family: var(--base-font-family, sans-serif);
|
|
55
|
+
position: relative;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
table.sticky-header :global(thead) {
|
|
59
|
+
position: sticky;
|
|
60
|
+
top: 0;
|
|
61
|
+
z-index: 10;
|
|
62
|
+
background: var(--table-header-bg);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
table.sticky-header :global(thead th) {
|
|
66
|
+
position: sticky;
|
|
67
|
+
top: 0;
|
|
68
|
+
background: var(--table-header-bg);
|
|
10
69
|
}
|
|
11
70
|
</style>
|
|
@@ -1,29 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}
|
|
12
|
-
export type TableProps = typeof __propDef.props;
|
|
13
|
-
export type TableEvents = typeof __propDef.events;
|
|
14
|
-
export type TableSlots = typeof __propDef.slots;
|
|
15
|
-
import { SvelteComponent } from "svelte";
|
|
16
|
-
declare const __propDef: {
|
|
17
|
-
props: {
|
|
18
|
-
[x: string]: never;
|
|
19
|
-
};
|
|
20
|
-
events: {
|
|
21
|
-
[evt: string]: CustomEvent<any>;
|
|
22
|
-
};
|
|
23
|
-
slots: {
|
|
24
|
-
default: {};
|
|
25
|
-
};
|
|
26
|
-
exports?: undefined;
|
|
27
|
-
bindings?: undefined;
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
children?: Snippet;
|
|
4
|
+
enableSorting?: boolean;
|
|
5
|
+
enableSelection?: boolean;
|
|
6
|
+
selectionMode?: 'single' | 'multi';
|
|
7
|
+
rowIdKey?: string;
|
|
8
|
+
stickyHeader?: boolean;
|
|
9
|
+
onSort?: (column: string, direction: 'asc' | 'desc') => void;
|
|
10
|
+
onSelectionChange?: (selectedIds: Set<string | number>) => void;
|
|
28
11
|
};
|
|
29
|
-
|
|
12
|
+
declare const Table: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
13
|
+
type Table = ReturnType<typeof Table>;
|
|
14
|
+
export default Table;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Accessibility testing helpers
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Check if element has proper ARIA label
|
|
6
|
+
*/
|
|
7
|
+
export declare function hasAccessibleName(element: Element): boolean;
|
|
8
|
+
/**
|
|
9
|
+
* Get accessible name of element
|
|
10
|
+
*/
|
|
11
|
+
export declare function getAccessibleName(element: Element): string;
|
|
12
|
+
/**
|
|
13
|
+
* Check if element is keyboard accessible
|
|
14
|
+
*/
|
|
15
|
+
export declare function isKeyboardAccessible(element: Element): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Check if element has proper role
|
|
18
|
+
*/
|
|
19
|
+
export declare function hasRole(element: Element, expectedRole: string): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Check if element is properly described
|
|
22
|
+
*/
|
|
23
|
+
export declare function hasDescription(element: Element): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Get description text
|
|
26
|
+
*/
|
|
27
|
+
export declare function getDescription(element: Element): string;
|
|
28
|
+
/**
|
|
29
|
+
* Check if element is marked as invalid
|
|
30
|
+
*/
|
|
31
|
+
export declare function isInvalid(element: Element): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Check if element is marked as required
|
|
34
|
+
*/
|
|
35
|
+
export declare function isRequired(element: Element): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Check if element is expanded (for collapsible elements)
|
|
38
|
+
*/
|
|
39
|
+
export declare function isExpanded(element: Element): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Check if element is pressed (for toggle buttons)
|
|
42
|
+
*/
|
|
43
|
+
export declare function isPressed(element: Element): boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Check if element is checked (for checkboxes/radios)
|
|
46
|
+
*/
|
|
47
|
+
export declare function isChecked(element: Element): boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Check if element is selected (for options)
|
|
50
|
+
*/
|
|
51
|
+
export declare function isSelected(element: Element): boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Get all focusable elements within a container
|
|
54
|
+
*/
|
|
55
|
+
export declare function getFocusableElements(container?: Element): Element[];
|
|
56
|
+
/**
|
|
57
|
+
* Check if focus is trapped within container
|
|
58
|
+
*/
|
|
59
|
+
export declare function isFocusTrapped(container: Element): boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Check if element has live region attributes
|
|
62
|
+
*/
|
|
63
|
+
export declare function hasLiveRegion(element: Element): boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Get live region politeness level
|
|
66
|
+
*/
|
|
67
|
+
export declare function getLiveRegionPoliteness(element: Element): 'polite' | 'assertive' | 'off' | null;
|
|
68
|
+
/**
|
|
69
|
+
* Check contrast ratio (simplified check)
|
|
70
|
+
* Note: This is a basic check. For comprehensive contrast testing, use axe-core
|
|
71
|
+
*/
|
|
72
|
+
export declare function hasGoodContrast(element: HTMLElement): boolean;
|
|
73
|
+
/**
|
|
74
|
+
* Check if element has sufficient size for touch targets (44x44px minimum)
|
|
75
|
+
*/
|
|
76
|
+
export declare function hasSufficientTouchTargetSize(element: HTMLElement): boolean;
|
|
77
|
+
/**
|
|
78
|
+
* Verify keyboard navigation order
|
|
79
|
+
*/
|
|
80
|
+
export declare function getTabOrder(container?: Element): Element[];
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Accessibility testing helpers
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Check if element has proper ARIA label
|
|
6
|
+
*/
|
|
7
|
+
export function hasAccessibleName(element) {
|
|
8
|
+
const ariaLabel = element.getAttribute('aria-label');
|
|
9
|
+
const ariaLabelledBy = element.getAttribute('aria-labelledby');
|
|
10
|
+
const title = element.getAttribute('title');
|
|
11
|
+
if (ariaLabel || title)
|
|
12
|
+
return true;
|
|
13
|
+
if (ariaLabelledBy) {
|
|
14
|
+
const labelElement = document.getElementById(ariaLabelledBy);
|
|
15
|
+
return !!labelElement?.textContent?.trim();
|
|
16
|
+
}
|
|
17
|
+
// Check for label element
|
|
18
|
+
if (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement) {
|
|
19
|
+
const id = element.id;
|
|
20
|
+
if (id) {
|
|
21
|
+
const label = document.querySelector(`label[for="${id}"]`);
|
|
22
|
+
return !!label?.textContent?.trim();
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Get accessible name of element
|
|
29
|
+
*/
|
|
30
|
+
export function getAccessibleName(element) {
|
|
31
|
+
const ariaLabel = element.getAttribute('aria-label');
|
|
32
|
+
if (ariaLabel)
|
|
33
|
+
return ariaLabel;
|
|
34
|
+
const ariaLabelledBy = element.getAttribute('aria-labelledby');
|
|
35
|
+
if (ariaLabelledBy) {
|
|
36
|
+
const labelElement = document.getElementById(ariaLabelledBy);
|
|
37
|
+
return labelElement?.textContent?.trim() || '';
|
|
38
|
+
}
|
|
39
|
+
const title = element.getAttribute('title');
|
|
40
|
+
if (title)
|
|
41
|
+
return title;
|
|
42
|
+
// Check for label element
|
|
43
|
+
if (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement) {
|
|
44
|
+
const id = element.id;
|
|
45
|
+
if (id) {
|
|
46
|
+
const label = document.querySelector(`label[for="${id}"]`);
|
|
47
|
+
return label?.textContent?.trim() || '';
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return element.textContent?.trim() || '';
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Check if element is keyboard accessible
|
|
54
|
+
*/
|
|
55
|
+
export function isKeyboardAccessible(element) {
|
|
56
|
+
const tabindex = element.getAttribute('tabindex');
|
|
57
|
+
// Elements with tabindex="-1" are programmatically focusable but not keyboard accessible
|
|
58
|
+
if (tabindex === '-1')
|
|
59
|
+
return false;
|
|
60
|
+
// Interactive elements are keyboard accessible by default
|
|
61
|
+
const interactiveElements = ['A', 'BUTTON', 'INPUT', 'SELECT', 'TEXTAREA'];
|
|
62
|
+
if (interactiveElements.includes(element.tagName)) {
|
|
63
|
+
return !element.hasAttribute('disabled');
|
|
64
|
+
}
|
|
65
|
+
// Elements with positive or zero tabindex are keyboard accessible
|
|
66
|
+
return tabindex !== null && parseInt(tabindex) >= 0;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Check if element has proper role
|
|
70
|
+
*/
|
|
71
|
+
export function hasRole(element, expectedRole) {
|
|
72
|
+
const role = element.getAttribute('role');
|
|
73
|
+
return role === expectedRole;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Check if element is properly described
|
|
77
|
+
*/
|
|
78
|
+
export function hasDescription(element) {
|
|
79
|
+
const ariaDescribedBy = element.getAttribute('aria-describedby');
|
|
80
|
+
if (!ariaDescribedBy)
|
|
81
|
+
return false;
|
|
82
|
+
const descriptionElement = document.getElementById(ariaDescribedBy);
|
|
83
|
+
return !!descriptionElement?.textContent?.trim();
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Get description text
|
|
87
|
+
*/
|
|
88
|
+
export function getDescription(element) {
|
|
89
|
+
const ariaDescribedBy = element.getAttribute('aria-describedby');
|
|
90
|
+
if (!ariaDescribedBy)
|
|
91
|
+
return '';
|
|
92
|
+
const descriptionElement = document.getElementById(ariaDescribedBy);
|
|
93
|
+
return descriptionElement?.textContent?.trim() || '';
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Check if element is marked as invalid
|
|
97
|
+
*/
|
|
98
|
+
export function isInvalid(element) {
|
|
99
|
+
return element.getAttribute('aria-invalid') === 'true';
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Check if element is marked as required
|
|
103
|
+
*/
|
|
104
|
+
export function isRequired(element) {
|
|
105
|
+
return (element.hasAttribute('required') ||
|
|
106
|
+
element.getAttribute('aria-required') === 'true');
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Check if element is expanded (for collapsible elements)
|
|
110
|
+
*/
|
|
111
|
+
export function isExpanded(element) {
|
|
112
|
+
return element.getAttribute('aria-expanded') === 'true';
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Check if element is pressed (for toggle buttons)
|
|
116
|
+
*/
|
|
117
|
+
export function isPressed(element) {
|
|
118
|
+
return element.getAttribute('aria-pressed') === 'true';
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Check if element is checked (for checkboxes/radios)
|
|
122
|
+
*/
|
|
123
|
+
export function isChecked(element) {
|
|
124
|
+
if (element instanceof HTMLInputElement) {
|
|
125
|
+
return element.checked;
|
|
126
|
+
}
|
|
127
|
+
return element.getAttribute('aria-checked') === 'true';
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Check if element is selected (for options)
|
|
131
|
+
*/
|
|
132
|
+
export function isSelected(element) {
|
|
133
|
+
if (element instanceof HTMLOptionElement) {
|
|
134
|
+
return element.selected;
|
|
135
|
+
}
|
|
136
|
+
return element.getAttribute('aria-selected') === 'true';
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Get all focusable elements within a container
|
|
140
|
+
*/
|
|
141
|
+
export function getFocusableElements(container = document.body) {
|
|
142
|
+
const selector = [
|
|
143
|
+
'a[href]',
|
|
144
|
+
'button:not([disabled])',
|
|
145
|
+
'input:not([disabled])',
|
|
146
|
+
'select:not([disabled])',
|
|
147
|
+
'textarea:not([disabled])',
|
|
148
|
+
'[tabindex]:not([tabindex="-1"])'
|
|
149
|
+
].join(',');
|
|
150
|
+
return Array.from(container.querySelectorAll(selector));
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Check if focus is trapped within container
|
|
154
|
+
*/
|
|
155
|
+
export function isFocusTrapped(container) {
|
|
156
|
+
const focusableElements = getFocusableElements(container);
|
|
157
|
+
const activeElement = document.activeElement;
|
|
158
|
+
if (!activeElement)
|
|
159
|
+
return false;
|
|
160
|
+
return focusableElements.some(el => el === activeElement || el.contains(activeElement));
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Check if element has live region attributes
|
|
164
|
+
*/
|
|
165
|
+
export function hasLiveRegion(element) {
|
|
166
|
+
return element.hasAttribute('aria-live');
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Get live region politeness level
|
|
170
|
+
*/
|
|
171
|
+
export function getLiveRegionPoliteness(element) {
|
|
172
|
+
const value = element.getAttribute('aria-live');
|
|
173
|
+
if (value === 'polite' || value === 'assertive' || value === 'off') {
|
|
174
|
+
return value;
|
|
175
|
+
}
|
|
176
|
+
return null;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Check contrast ratio (simplified check)
|
|
180
|
+
* Note: This is a basic check. For comprehensive contrast testing, use axe-core
|
|
181
|
+
*/
|
|
182
|
+
export function hasGoodContrast(element) {
|
|
183
|
+
const style = window.getComputedStyle(element);
|
|
184
|
+
const color = style.color;
|
|
185
|
+
const backgroundColor = style.backgroundColor;
|
|
186
|
+
// If no background color is set, we can't determine contrast
|
|
187
|
+
if (!backgroundColor || backgroundColor === 'rgba(0, 0, 0, 0)') {
|
|
188
|
+
return true; // Assume parent has proper contrast
|
|
189
|
+
}
|
|
190
|
+
// This is a simplified check - real contrast calculation is complex
|
|
191
|
+
// For production, use axe-core or similar tools
|
|
192
|
+
return color !== backgroundColor;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Check if element has sufficient size for touch targets (44x44px minimum)
|
|
196
|
+
*/
|
|
197
|
+
export function hasSufficientTouchTargetSize(element) {
|
|
198
|
+
const rect = element.getBoundingClientRect();
|
|
199
|
+
return rect.width >= 44 && rect.height >= 44;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Verify keyboard navigation order
|
|
203
|
+
*/
|
|
204
|
+
export function getTabOrder(container = document.body) {
|
|
205
|
+
const focusableElements = getFocusableElements(container);
|
|
206
|
+
return focusableElements.sort((a, b) => {
|
|
207
|
+
const aTabIndex = parseInt(a.getAttribute('tabindex') || '0');
|
|
208
|
+
const bTabIndex = parseInt(b.getAttribute('tabindex') || '0');
|
|
209
|
+
// Elements with tabindex > 0 come first, in order
|
|
210
|
+
if (aTabIndex > 0 && bTabIndex > 0) {
|
|
211
|
+
return aTabIndex - bTabIndex;
|
|
212
|
+
}
|
|
213
|
+
if (aTabIndex > 0)
|
|
214
|
+
return -1;
|
|
215
|
+
if (bTabIndex > 0)
|
|
216
|
+
return 1;
|
|
217
|
+
// Otherwise, use DOM order
|
|
218
|
+
return 0;
|
|
219
|
+
});
|
|
220
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mock helpers for testing
|
|
3
|
+
*/
|
|
4
|
+
import { vi } from 'vitest';
|
|
5
|
+
/**
|
|
6
|
+
* Mock a function with optional implementation
|
|
7
|
+
*/
|
|
8
|
+
export declare function mockFunction<T extends (...args: any[]) => any>(implementation?: T): ReturnType<typeof vi.fn>;
|
|
9
|
+
/**
|
|
10
|
+
* Mock console methods to suppress output during tests
|
|
11
|
+
*/
|
|
12
|
+
export declare function mockConsole(): void;
|
|
13
|
+
/**
|
|
14
|
+
* Mock fetch API
|
|
15
|
+
*/
|
|
16
|
+
export declare function mockFetch(response: any, options?: {
|
|
17
|
+
ok?: boolean;
|
|
18
|
+
status?: number;
|
|
19
|
+
}): typeof fetch;
|
|
20
|
+
/**
|
|
21
|
+
* Mock setTimeout/setInterval for testing
|
|
22
|
+
*/
|
|
23
|
+
export declare function mockTimers(): void;
|
|
24
|
+
/**
|
|
25
|
+
* Mock Date.now() for consistent timestamps
|
|
26
|
+
*/
|
|
27
|
+
export declare function mockDateNow(timestamp?: number): void;
|
|
28
|
+
/**
|
|
29
|
+
* Mock window.location
|
|
30
|
+
*/
|
|
31
|
+
export declare function mockLocation(url?: string): void;
|
|
32
|
+
/**
|
|
33
|
+
* Mock clipboard API
|
|
34
|
+
*/
|
|
35
|
+
export declare function mockClipboard(): {
|
|
36
|
+
writeText: import("vitest").Mock<(...args: any[]) => any>;
|
|
37
|
+
readText: import("vitest").Mock<(...args: any[]) => any>;
|
|
38
|
+
write: import("vitest").Mock<(...args: any[]) => any>;
|
|
39
|
+
read: import("vitest").Mock<(...args: any[]) => any>;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Mock getBoundingClientRect for positioning tests
|
|
43
|
+
*/
|
|
44
|
+
export declare function mockGetBoundingClientRect(element: Element, rect: Partial<DOMRect>): void;
|
|
45
|
+
/**
|
|
46
|
+
* Mock viewport size
|
|
47
|
+
*/
|
|
48
|
+
export declare function mockViewport(width?: number, height?: number): void;
|
|
49
|
+
/**
|
|
50
|
+
* Mock media query
|
|
51
|
+
*/
|
|
52
|
+
export declare function mockMediaQuery(query: string, matches?: boolean): import("vitest").Mock<(...args: any[]) => any>;
|
|
53
|
+
/**
|
|
54
|
+
* Mock prefers-reduced-motion
|
|
55
|
+
*/
|
|
56
|
+
export declare function mockPrefersReducedMotion(enabled?: boolean): void;
|
|
57
|
+
/**
|
|
58
|
+
* Mock prefers-color-scheme
|
|
59
|
+
*/
|
|
60
|
+
export declare function mockPrefersColorScheme(scheme?: 'light' | 'dark'): void;
|
|
61
|
+
/**
|
|
62
|
+
* Create a mock file for file input testing
|
|
63
|
+
*/
|
|
64
|
+
export declare function createMockFile(name?: string, content?: string, type?: string): File;
|
|
65
|
+
/**
|
|
66
|
+
* Create multiple mock files
|
|
67
|
+
*/
|
|
68
|
+
export declare function createMockFiles(count?: number): File[];
|