@krizaka/ui 3.3.0 → 3.5.0
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/activity-feed.d.ts +199 -0
- package/dist/activity-feed.js +155 -0
- package/dist/activity-feed.js.map +1 -0
- package/dist/chat.d.ts +187 -0
- package/dist/chat.js +132 -0
- package/dist/chat.js.map +1 -0
- package/dist/chunk-7Z4KHPFC.js +42 -0
- package/dist/chunk-7Z4KHPFC.js.map +1 -0
- package/dist/chunk-ECSCA3CN.js +128 -0
- package/dist/chunk-ECSCA3CN.js.map +1 -0
- package/dist/chunk-F2GKFIYK.js +47 -0
- package/dist/chunk-F2GKFIYK.js.map +1 -0
- package/dist/data-table.js +84 -231
- package/dist/data-table.js.map +1 -1
- package/dist/description-list.d.ts +105 -0
- package/dist/description-list.js +49 -0
- package/dist/description-list.js.map +1 -0
- package/dist/index.js +13 -66
- package/dist/index.js.map +1 -1
- package/dist/kanban.d.ts +132 -0
- package/dist/kanban.js +187 -0
- package/dist/kanban.js.map +1 -0
- package/dist/list.d.ts +153 -0
- package/dist/list.js +130 -0
- package/dist/list.js.map +1 -0
- package/dist/map.d.ts +463 -0
- package/dist/map.js +952 -0
- package/dist/map.js.map +1 -0
- package/dist/match-dialog.d.ts +30 -0
- package/dist/match-dialog.js +146 -0
- package/dist/match-dialog.js.map +1 -0
- package/dist/motion.css +12 -1
- package/dist/native/map.d.ts +200 -0
- package/dist/native/map.js +673 -0
- package/dist/native/map.js.map +1 -0
- package/dist/native/media-picker.d.ts +58 -0
- package/dist/native/media-picker.js +63 -0
- package/dist/native/media-picker.js.map +1 -0
- package/dist/native.d.ts +952 -75
- package/dist/native.js +2572 -889
- package/dist/native.js.map +1 -1
- package/dist/photo-grid.d.ts +122 -0
- package/dist/photo-grid.js +94 -0
- package/dist/photo-grid.js.map +1 -0
- package/dist/stat.d.ts +31 -2
- package/dist/stat.js +21 -4
- package/dist/stat.js.map +1 -1
- package/dist/step-progress.d.ts +20 -0
- package/dist/step-progress.js +17 -0
- package/dist/step-progress.js.map +1 -0
- package/dist/swipe-deck.d.ts +183 -0
- package/dist/swipe-deck.js +144 -0
- package/dist/swipe-deck.js.map +1 -0
- package/dist/tag-selector.d.ts +26 -0
- package/dist/tag-selector.js +21 -0
- package/dist/tag-selector.js.map +1 -0
- package/dist/tree-view.d.ts +111 -0
- package/dist/tree-view.js +154 -0
- package/dist/tree-view.js.map +1 -0
- package/dist/verified-badge.d.ts +16 -0
- package/dist/verified-badge.js +23 -0
- package/dist/verified-badge.js.map +1 -0
- package/package.json +245 -10
- package/registry/achievement.json +1 -1
- package/registry/action-bar.json +1 -1
- package/registry/action-sheet.json +121 -0
- package/registry/activity-feed.json +468 -0
- package/registry/alert.json +1 -1
- package/registry/app-shell.json +1 -1
- package/registry/argument-card.json +1 -1
- package/registry/audio-player.json +1 -1
- package/registry/auth-layout.json +1 -1
- package/registry/avatar.json +58 -3
- package/registry/badge.json +1 -1
- package/registry/button.json +1 -1
- package/registry/card-grid.json +1 -1
- package/registry/card.json +1 -1
- package/registry/catalogue-page.json +1 -1
- package/registry/changelog-page.json +1 -1
- package/registry/chat.json +917 -0
- package/registry/checkbox.json +1 -1
- package/registry/chip-link.json +1 -1
- package/registry/chip.json +1 -1
- package/registry/choice-grid.json +1 -1
- package/registry/code-block.json +1 -1
- package/registry/combobox.json +1 -1
- package/registry/command.json +1 -1
- package/registry/component-page.json +1 -1
- package/registry/confirm-button.json +1 -1
- package/registry/contact-page.json +1 -1
- package/registry/continue-prompt.json +1 -1
- package/registry/countdown.json +1 -1
- package/registry/cta-panel.json +1 -1
- package/registry/dashboard-layout.json +1 -1
- package/registry/data-table.json +1 -1
- package/registry/date-picker.json +2 -2
- package/registry/decision-list.json +1 -1
- package/registry/description-list.json +232 -0
- package/registry/detail-layout.json +1 -1
- package/registry/dialog.json +1 -1
- package/registry/docs-article-page.json +1 -1
- package/registry/docs-hub-page.json +1 -1
- package/registry/docs-layout.json +1 -1
- package/registry/dropdown-menu.json +1 -1
- package/registry/empty-state.json +1 -1
- package/registry/error-page.json +1 -1
- package/registry/examples/action-sheet/native/video-actions.d.ts +4 -0
- package/registry/examples/action-sheet/native/video-actions.dark.png +0 -0
- package/registry/examples/action-sheet/native/video-actions.js +30 -0
- package/registry/examples/action-sheet/native/video-actions.light.png +0 -0
- package/registry/examples/action-sheet/native/video-actions.tsx +24 -0
- package/registry/examples/activity-feed/job-activity.d.ts +4 -0
- package/registry/examples/activity-feed/job-activity.js +21 -0
- package/registry/examples/activity-feed/job-activity.tsx +17 -0
- package/registry/examples/activity-feed/live.d.ts +4 -0
- package/registry/examples/activity-feed/live.js +23 -0
- package/registry/examples/activity-feed/live.tsx +24 -0
- package/registry/examples/activity-feed/native/notifications.d.ts +4 -0
- package/registry/examples/activity-feed/native/notifications.dark.png +0 -0
- package/registry/examples/activity-feed/native/notifications.js +18 -0
- package/registry/examples/activity-feed/native/notifications.light.png +0 -0
- package/registry/examples/activity-feed/native/notifications.tsx +18 -0
- package/registry/examples/activity-feed/timeline.d.ts +4 -0
- package/registry/examples/activity-feed/timeline.js +25 -0
- package/registry/examples/activity-feed/timeline.tsx +19 -0
- package/registry/examples/avatar/native/presence.d.ts +4 -0
- package/registry/examples/avatar/native/presence.dark.png +0 -0
- package/registry/examples/avatar/native/presence.js +18 -0
- package/registry/examples/avatar/native/presence.light.png +0 -0
- package/registry/examples/avatar/native/presence.tsx +15 -0
- package/registry/examples/chat/conversation.d.ts +4 -0
- package/registry/examples/chat/conversation.js +22 -0
- package/registry/examples/chat/conversation.tsx +21 -0
- package/registry/examples/chat/inbox.d.ts +4 -0
- package/registry/examples/chat/inbox.js +15 -0
- package/registry/examples/chat/inbox.tsx +12 -0
- package/registry/examples/chat/native/conversation.d.ts +4 -0
- package/registry/examples/chat/native/conversation.dark.png +0 -0
- package/registry/examples/chat/native/conversation.js +23 -0
- package/registry/examples/chat/native/conversation.light.png +0 -0
- package/registry/examples/chat/native/conversation.tsx +20 -0
- package/registry/examples/chat/native/inbox.d.ts +4 -0
- package/registry/examples/chat/native/inbox.dark.png +0 -0
- package/registry/examples/chat/native/inbox.js +16 -0
- package/registry/examples/chat/native/inbox.light.png +0 -0
- package/registry/examples/chat/native/inbox.tsx +13 -0
- package/registry/examples/description-list/job-details.d.ts +4 -0
- package/registry/examples/description-list/job-details.js +23 -0
- package/registry/examples/description-list/job-details.tsx +17 -0
- package/registry/examples/description-list/key-value-grid.d.ts +4 -0
- package/registry/examples/description-list/key-value-grid.js +22 -0
- package/registry/examples/description-list/key-value-grid.tsx +16 -0
- package/registry/examples/description-list/native/job-details.d.ts +4 -0
- package/registry/examples/description-list/native/job-details.dark.png +0 -0
- package/registry/examples/description-list/native/job-details.js +33 -0
- package/registry/examples/description-list/native/job-details.light.png +0 -0
- package/registry/examples/description-list/native/job-details.tsx +24 -0
- package/registry/examples/description-list/receipt.d.ts +4 -0
- package/registry/examples/description-list/receipt.js +23 -0
- package/registry/examples/description-list/receipt.tsx +17 -0
- package/registry/examples/fab/native/extended.d.ts +4 -0
- package/registry/examples/fab/native/extended.dark.png +0 -0
- package/registry/examples/fab/native/extended.js +18 -0
- package/registry/examples/fab/native/extended.light.png +0 -0
- package/registry/examples/fab/native/extended.tsx +23 -0
- package/registry/examples/header/native/large-title.d.ts +4 -0
- package/registry/examples/header/native/large-title.dark.png +0 -0
- package/registry/examples/header/native/large-title.js +23 -0
- package/registry/examples/header/native/large-title.light.png +0 -0
- package/registry/examples/header/native/large-title.tsx +31 -0
- package/registry/examples/image-viewer/native/gallery.d.ts +4 -0
- package/registry/examples/image-viewer/native/gallery.dark.png +0 -0
- package/registry/examples/image-viewer/native/gallery.js +22 -0
- package/registry/examples/image-viewer/native/gallery.light.png +0 -0
- package/registry/examples/image-viewer/native/gallery.tsx +21 -0
- package/registry/examples/kanban/moderation.d.ts +4 -0
- package/registry/examples/kanban/moderation.js +35 -0
- package/registry/examples/kanban/moderation.tsx +37 -0
- package/registry/examples/list/jobs.d.ts +4 -0
- package/registry/examples/list/jobs.js +35 -0
- package/registry/examples/list/jobs.tsx +33 -0
- package/registry/examples/list/selectable.d.ts +4 -0
- package/registry/examples/list/selectable.js +33 -0
- package/registry/examples/list/selectable.tsx +30 -0
- package/registry/examples/list/virtualized.d.ts +4 -0
- package/registry/examples/list/virtualized.js +22 -0
- package/registry/examples/list/virtualized.tsx +17 -0
- package/registry/examples/loader/native/block.d.ts +4 -0
- package/registry/examples/loader/native/block.dark.png +0 -0
- package/registry/examples/loader/native/block.js +12 -0
- package/registry/examples/loader/native/block.light.png +0 -0
- package/registry/examples/loader/native/block.tsx +11 -0
- package/registry/examples/loader/native/job-wait.d.ts +4 -0
- package/registry/examples/loader/native/job-wait.dark.png +0 -0
- package/registry/examples/loader/native/job-wait.js +17 -0
- package/registry/examples/loader/native/job-wait.light.png +0 -0
- package/registry/examples/loader/native/job-wait.tsx +14 -0
- package/registry/examples/map/cluster.d.ts +4 -0
- package/registry/examples/map/cluster.js +16 -0
- package/registry/examples/map/cluster.tsx +18 -0
- package/registry/examples/map/location-picker.d.ts +4 -0
- package/registry/examples/map/location-picker.js +24 -0
- package/registry/examples/map/location-picker.tsx +22 -0
- package/registry/examples/map/native/location-picker.d.ts +4 -0
- package/registry/examples/map/native/location-picker.dark.png +0 -0
- package/registry/examples/map/native/location-picker.js +14 -0
- package/registry/examples/map/native/location-picker.light.png +0 -0
- package/registry/examples/map/native/location-picker.tsx +13 -0
- package/registry/examples/map/native/places.d.ts +4 -0
- package/registry/examples/map/native/places.dark.png +0 -0
- package/registry/examples/map/native/places.js +25 -0
- package/registry/examples/map/native/places.light.png +0 -0
- package/registry/examples/map/native/places.tsx +27 -0
- package/registry/examples/map/places.d.ts +4 -0
- package/registry/examples/map/places.js +28 -0
- package/registry/examples/map/places.tsx +28 -0
- package/registry/examples/map/static.d.ts +4 -0
- package/registry/examples/map/static.js +22 -0
- package/registry/examples/map/static.tsx +18 -0
- package/registry/examples/match-dialog/its-a-match.d.ts +4 -0
- package/registry/examples/match-dialog/its-a-match.js +29 -0
- package/registry/examples/match-dialog/its-a-match.tsx +25 -0
- package/registry/examples/match-dialog/native/its-a-match.d.ts +4 -0
- package/registry/examples/match-dialog/native/its-a-match.dark.png +0 -0
- package/registry/examples/match-dialog/native/its-a-match.js +28 -0
- package/registry/examples/match-dialog/native/its-a-match.light.png +0 -0
- package/registry/examples/match-dialog/native/its-a-match.tsx +22 -0
- package/registry/examples/media-picker/native/story.d.ts +4 -0
- package/registry/examples/media-picker/native/story.dark.png +0 -0
- package/registry/examples/media-picker/native/story.js +30 -0
- package/registry/examples/media-picker/native/story.light.png +0 -0
- package/registry/examples/media-picker/native/story.tsx +26 -0
- package/registry/examples/meter/native/credits.d.ts +4 -0
- package/registry/examples/meter/native/credits.dark.png +0 -0
- package/registry/examples/meter/native/credits.js +15 -0
- package/registry/examples/meter/native/credits.light.png +0 -0
- package/registry/examples/meter/native/credits.tsx +12 -0
- package/registry/examples/meter/native/split-ring.d.ts +4 -0
- package/registry/examples/meter/native/split-ring.dark.png +0 -0
- package/registry/examples/meter/native/split-ring.js +24 -0
- package/registry/examples/meter/native/split-ring.light.png +0 -0
- package/registry/examples/meter/native/split-ring.tsx +19 -0
- package/registry/examples/number-ticker/native/balance.d.ts +4 -0
- package/registry/examples/number-ticker/native/balance.dark.png +0 -0
- package/registry/examples/number-ticker/native/balance.js +18 -0
- package/registry/examples/number-ticker/native/balance.light.png +0 -0
- package/registry/examples/number-ticker/native/balance.tsx +17 -0
- package/registry/examples/onboarding/native/first-launch.d.ts +4 -0
- package/registry/examples/onboarding/native/first-launch.dark.png +0 -0
- package/registry/examples/onboarding/native/first-launch.js +23 -0
- package/registry/examples/onboarding/native/first-launch.light.png +0 -0
- package/registry/examples/onboarding/native/first-launch.tsx +19 -0
- package/registry/examples/otp-input/native/invalid.d.ts +4 -0
- package/registry/examples/otp-input/native/invalid.dark.png +0 -0
- package/registry/examples/otp-input/native/invalid.js +15 -0
- package/registry/examples/otp-input/native/invalid.light.png +0 -0
- package/registry/examples/otp-input/native/invalid.tsx +14 -0
- package/registry/examples/otp-input/native/verify.d.ts +4 -0
- package/registry/examples/otp-input/native/verify.dark.png +0 -0
- package/registry/examples/otp-input/native/verify.js +17 -0
- package/registry/examples/otp-input/native/verify.light.png +0 -0
- package/registry/examples/otp-input/native/verify.tsx +14 -0
- package/registry/examples/permission-prompt/native/blocked.d.ts +4 -0
- package/registry/examples/permission-prompt/native/blocked.dark.png +0 -0
- package/registry/examples/permission-prompt/native/blocked.js +25 -0
- package/registry/examples/permission-prompt/native/blocked.light.png +0 -0
- package/registry/examples/permission-prompt/native/blocked.tsx +21 -0
- package/registry/examples/permission-prompt/native/camera.d.ts +4 -0
- package/registry/examples/permission-prompt/native/camera.dark.png +0 -0
- package/registry/examples/permission-prompt/native/camera.js +25 -0
- package/registry/examples/permission-prompt/native/camera.light.png +0 -0
- package/registry/examples/permission-prompt/native/camera.tsx +21 -0
- package/registry/examples/photo-grid/native/profile-photos.d.ts +4 -0
- package/registry/examples/photo-grid/native/profile-photos.dark.png +0 -0
- package/registry/examples/photo-grid/native/profile-photos.js +27 -0
- package/registry/examples/photo-grid/native/profile-photos.light.png +0 -0
- package/registry/examples/photo-grid/native/profile-photos.tsx +24 -0
- package/registry/examples/photo-grid/profile-photos.d.ts +4 -0
- package/registry/examples/photo-grid/profile-photos.js +28 -0
- package/registry/examples/photo-grid/profile-photos.tsx +25 -0
- package/registry/examples/pull-to-refresh/native/feed.d.ts +4 -0
- package/registry/examples/pull-to-refresh/native/feed.dark.png +0 -0
- package/registry/examples/pull-to-refresh/native/feed.js +14 -0
- package/registry/examples/pull-to-refresh/native/feed.light.png +0 -0
- package/registry/examples/pull-to-refresh/native/feed.tsx +19 -0
- package/registry/examples/screen/native/app-shell.d.ts +4 -0
- package/registry/examples/screen/native/app-shell.dark.png +0 -0
- package/registry/examples/screen/native/app-shell.js +25 -0
- package/registry/examples/screen/native/app-shell.light.png +0 -0
- package/registry/examples/screen/native/app-shell.tsx +33 -0
- package/registry/examples/screen/native/auth.d.ts +4 -0
- package/registry/examples/screen/native/auth.dark.png +0 -0
- package/registry/examples/screen/native/auth.js +24 -0
- package/registry/examples/screen/native/auth.light.png +0 -0
- package/registry/examples/screen/native/auth.tsx +20 -0
- package/registry/examples/screen/native/chat.d.ts +4 -0
- package/registry/examples/screen/native/chat.dark.png +0 -0
- package/registry/examples/screen/native/chat.js +27 -0
- package/registry/examples/screen/native/chat.light.png +0 -0
- package/registry/examples/screen/native/chat.tsx +22 -0
- package/registry/examples/screen/native/feed.d.ts +4 -0
- package/registry/examples/screen/native/feed.dark.png +0 -0
- package/registry/examples/screen/native/feed.js +24 -0
- package/registry/examples/screen/native/feed.light.png +0 -0
- package/registry/examples/screen/native/feed.tsx +34 -0
- package/registry/examples/screen/native/profile.d.ts +4 -0
- package/registry/examples/screen/native/profile.dark.png +0 -0
- package/registry/examples/screen/native/profile.js +29 -0
- package/registry/examples/screen/native/profile.light.png +0 -0
- package/registry/examples/screen/native/profile.tsx +27 -0
- package/registry/examples/screen/native/settings.d.ts +4 -0
- package/registry/examples/screen/native/settings.dark.png +0 -0
- package/registry/examples/screen/native/settings.js +20 -0
- package/registry/examples/screen/native/settings.light.png +0 -0
- package/registry/examples/screen/native/settings.tsx +19 -0
- package/registry/examples/search-field/native/cancel.d.ts +4 -0
- package/registry/examples/search-field/native/cancel.dark.png +0 -0
- package/registry/examples/search-field/native/cancel.js +14 -0
- package/registry/examples/search-field/native/cancel.light.png +0 -0
- package/registry/examples/search-field/native/cancel.tsx +13 -0
- package/registry/examples/stat/grid.d.ts +4 -0
- package/registry/examples/stat/grid.js +17 -0
- package/registry/examples/stat/grid.tsx +14 -0
- package/registry/examples/step-progress/native/sign-up.d.ts +4 -0
- package/registry/examples/step-progress/native/sign-up.dark.png +0 -0
- package/registry/examples/step-progress/native/sign-up.js +12 -0
- package/registry/examples/step-progress/native/sign-up.light.png +0 -0
- package/registry/examples/step-progress/native/sign-up.tsx +11 -0
- package/registry/examples/step-progress/sign-up.d.ts +4 -0
- package/registry/examples/step-progress/sign-up.js +22 -0
- package/registry/examples/step-progress/sign-up.tsx +16 -0
- package/registry/examples/stepper/native/run.d.ts +4 -0
- package/registry/examples/stepper/native/run.dark.png +0 -0
- package/registry/examples/stepper/native/run.js +24 -0
- package/registry/examples/stepper/native/run.light.png +0 -0
- package/registry/examples/stepper/native/run.tsx +20 -0
- package/registry/examples/swipe-deck/discover.d.ts +4 -0
- package/registry/examples/swipe-deck/discover.js +41 -0
- package/registry/examples/swipe-deck/discover.tsx +37 -0
- package/registry/examples/swipe-deck/native/discover.d.ts +4 -0
- package/registry/examples/swipe-deck/native/discover.dark.png +0 -0
- package/registry/examples/swipe-deck/native/discover.js +39 -0
- package/registry/examples/swipe-deck/native/discover.light.png +0 -0
- package/registry/examples/swipe-deck/native/discover.tsx +35 -0
- package/registry/examples/swipeable-row/native/conversation.d.ts +4 -0
- package/registry/examples/swipeable-row/native/conversation.dark.png +0 -0
- package/registry/examples/swipeable-row/native/conversation.js +30 -0
- package/registry/examples/swipeable-row/native/conversation.light.png +0 -0
- package/registry/examples/swipeable-row/native/conversation.tsx +27 -0
- package/registry/examples/tab-bar/native/main-sections.d.ts +4 -0
- package/registry/examples/tab-bar/native/main-sections.dark.png +0 -0
- package/registry/examples/tab-bar/native/main-sections.js +29 -0
- package/registry/examples/tab-bar/native/main-sections.light.png +0 -0
- package/registry/examples/tab-bar/native/main-sections.tsx +30 -0
- package/registry/examples/tabs/native/sections.d.ts +4 -0
- package/registry/examples/tabs/native/sections.dark.png +0 -0
- package/registry/examples/tabs/native/sections.js +23 -0
- package/registry/examples/tabs/native/sections.light.png +0 -0
- package/registry/examples/tabs/native/sections.tsx +19 -0
- package/registry/examples/tabs/native/segmented.d.ts +4 -0
- package/registry/examples/tabs/native/segmented.dark.png +0 -0
- package/registry/examples/tabs/native/segmented.js +22 -0
- package/registry/examples/tabs/native/segmented.light.png +0 -0
- package/registry/examples/tabs/native/segmented.tsx +18 -0
- package/registry/examples/tag-selector/interests.d.ts +4 -0
- package/registry/examples/tag-selector/interests.js +14 -0
- package/registry/examples/tag-selector/interests.tsx +12 -0
- package/registry/examples/tag-selector/native/interests.d.ts +4 -0
- package/registry/examples/tag-selector/native/interests.dark.png +0 -0
- package/registry/examples/tag-selector/native/interests.js +15 -0
- package/registry/examples/tag-selector/native/interests.light.png +0 -0
- package/registry/examples/tag-selector/native/interests.tsx +15 -0
- package/registry/examples/toast/native/snackbar.d.ts +4 -0
- package/registry/examples/toast/native/snackbar.dark.png +0 -0
- package/registry/examples/toast/native/snackbar.js +23 -0
- package/registry/examples/toast/native/snackbar.light.png +0 -0
- package/registry/examples/toast/native/snackbar.tsx +21 -0
- package/registry/examples/tree-view/docs.d.ts +4 -0
- package/registry/examples/tree-view/docs.js +24 -0
- package/registry/examples/tree-view/docs.tsx +22 -0
- package/registry/examples/tree-view/lazy.d.ts +4 -0
- package/registry/examples/tree-view/lazy.js +21 -0
- package/registry/examples/tree-view/lazy.tsx +19 -0
- package/registry/examples/verified-badge/native/verified.d.ts +4 -0
- package/registry/examples/verified-badge/native/verified.dark.png +0 -0
- package/registry/examples/verified-badge/native/verified.js +18 -0
- package/registry/examples/verified-badge/native/verified.light.png +0 -0
- package/registry/examples/verified-badge/native/verified.tsx +15 -0
- package/registry/examples/verified-badge/verified.d.ts +4 -0
- package/registry/examples/verified-badge/verified.js +17 -0
- package/registry/examples/verified-badge/verified.tsx +13 -0
- package/registry/fab.json +122 -0
- package/registry/field.json +1 -1
- package/registry/file-upload.json +2 -2
- package/registry/filter-bar.json +1 -1
- package/registry/form.json +2 -2
- package/registry/gallery-page.json +1 -1
- package/registry/glow-card.json +1 -1
- package/registry/goal-gauge.json +1 -1
- package/registry/header.json +137 -0
- package/registry/how-it-works-page.json +1 -1
- package/registry/image-cropper.json +1 -1
- package/registry/image-viewer.json +107 -0
- package/registry/index.json +441 -25
- package/registry/iso.json +1 -1
- package/registry/kanban.json +253 -0
- package/registry/kbd.json +1 -1
- package/registry/landing-page.json +1 -1
- package/registry/landscape.json +1 -1
- package/registry/legal-page.json +1 -1
- package/registry/link-card.json +1 -1
- package/registry/list.json +367 -30
- package/registry/loader.json +157 -4
- package/registry/longform-page.json +1 -1
- package/registry/map.json +1368 -0
- package/registry/marketing-layout.json +1 -1
- package/registry/marquee.json +1 -1
- package/registry/mascot-quote.json +1 -1
- package/registry/mascot-state.json +1 -1
- package/registry/mascots.json +1 -1
- package/registry/match-dialog.json +300 -0
- package/registry/media-capture.json +1 -1
- package/registry/media-picker.json +129 -0
- package/registry/meter.json +136 -4
- package/registry/nav-bar.json +1 -1
- package/registry/number-ticker.json +96 -4
- package/registry/onboarding.json +95 -0
- package/registry/otp-input.json +150 -0
- package/registry/page-header.json +1 -1
- package/registry/page-hero.json +1 -1
- package/registry/page.json +1 -1
- package/registry/pagination.json +1 -1
- package/registry/permission-prompt.json +172 -0
- package/registry/photo-grid.json +302 -0
- package/registry/pointer-light.json +1 -1
- package/registry/popover.json +1 -1
- package/registry/pricing-page.json +1 -1
- package/registry/product-page.json +1 -1
- package/registry/profile-card.json +1 -1
- package/registry/progress.json +2 -2
- package/registry/promise-card.json +1 -1
- package/registry/pull-to-refresh.json +74 -0
- package/registry/radio-group.json +1 -1
- package/registry/screen.json +184 -0
- package/registry/scroll-stage.json +1 -1
- package/registry/search-field.json +30 -3
- package/registry/section-backdrop.json +1 -1
- package/registry/separator.json +1 -1
- package/registry/settings-layout.json +1 -1
- package/registry/skeleton.json +1 -1
- package/registry/slider.json +1 -1
- package/registry/slot.json +1 -1
- package/registry/spinner.json +1 -1
- package/registry/split-view.json +1 -1
- package/registry/stage-banner.json +1 -1
- package/registry/stat.json +68 -5
- package/registry/status-page.json +1 -1
- package/registry/step-progress.json +255 -0
- package/registry/stepper.json +75 -4
- package/registry/swipe-deck.json +512 -0
- package/registry/swipeable-row.json +124 -0
- package/registry/switch.json +1 -1
- package/registry/tab-bar.json +115 -0
- package/registry/tabs.json +94 -4
- package/registry/tag-input.json +1 -1
- package/registry/tag-selector.json +276 -0
- package/registry/terminal-replay.json +1 -1
- package/registry/theme.json +8 -1
- package/registry/toast.json +17 -3
- package/registry/toc.json +1 -1
- package/registry/tooltip.json +1 -1
- package/registry/tree-view.json +291 -0
- package/registry/verified-badge.json +202 -0
- package/registry/video-player.json +1 -1
- package/registry/video-trimmer.json +1 -1
- package/registry/virtual.json +1 -1
- package/skills/map/SKILL.md +35 -0
package/dist/kanban.d.ts
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import * as tailwind_variants from 'tailwind-variants';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
|
|
4
|
+
declare const kanban: tailwind_variants.TVReturnType<{
|
|
5
|
+
[key: string]: {
|
|
6
|
+
[key: string]: tailwind_variants.ClassValue | {
|
|
7
|
+
root?: tailwind_variants.ClassValue;
|
|
8
|
+
column?: tailwind_variants.ClassValue;
|
|
9
|
+
header?: tailwind_variants.ClassValue;
|
|
10
|
+
title?: tailwind_variants.ClassValue;
|
|
11
|
+
count?: tailwind_variants.ClassValue;
|
|
12
|
+
list?: tailwind_variants.ClassValue;
|
|
13
|
+
empty?: tailwind_variants.ClassValue;
|
|
14
|
+
card?: tailwind_variants.ClassValue;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
} | {
|
|
18
|
+
[x: string]: {
|
|
19
|
+
[x: string]: tailwind_variants.ClassValue | {
|
|
20
|
+
root?: tailwind_variants.ClassValue;
|
|
21
|
+
column?: tailwind_variants.ClassValue;
|
|
22
|
+
header?: tailwind_variants.ClassValue;
|
|
23
|
+
title?: tailwind_variants.ClassValue;
|
|
24
|
+
count?: tailwind_variants.ClassValue;
|
|
25
|
+
list?: tailwind_variants.ClassValue;
|
|
26
|
+
empty?: tailwind_variants.ClassValue;
|
|
27
|
+
card?: tailwind_variants.ClassValue;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
} | {}, {
|
|
31
|
+
root: string;
|
|
32
|
+
column: string;
|
|
33
|
+
header: string;
|
|
34
|
+
title: string;
|
|
35
|
+
count: string;
|
|
36
|
+
list: string;
|
|
37
|
+
card: string;
|
|
38
|
+
empty: string;
|
|
39
|
+
}, undefined, {
|
|
40
|
+
[key: string]: {
|
|
41
|
+
[key: string]: tailwind_variants.ClassValue | {
|
|
42
|
+
root?: tailwind_variants.ClassValue;
|
|
43
|
+
column?: tailwind_variants.ClassValue;
|
|
44
|
+
header?: tailwind_variants.ClassValue;
|
|
45
|
+
title?: tailwind_variants.ClassValue;
|
|
46
|
+
count?: tailwind_variants.ClassValue;
|
|
47
|
+
list?: tailwind_variants.ClassValue;
|
|
48
|
+
empty?: tailwind_variants.ClassValue;
|
|
49
|
+
card?: tailwind_variants.ClassValue;
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
} | {}, {
|
|
53
|
+
root: string;
|
|
54
|
+
column: string;
|
|
55
|
+
header: string;
|
|
56
|
+
title: string;
|
|
57
|
+
count: string;
|
|
58
|
+
list: string;
|
|
59
|
+
card: string;
|
|
60
|
+
empty: string;
|
|
61
|
+
}, tailwind_variants.TVReturnTypeLike<unknown, {
|
|
62
|
+
root: string;
|
|
63
|
+
column: string;
|
|
64
|
+
header: string;
|
|
65
|
+
title: string;
|
|
66
|
+
count: string;
|
|
67
|
+
list: string;
|
|
68
|
+
card: string;
|
|
69
|
+
empty: string;
|
|
70
|
+
}>>;
|
|
71
|
+
type KanbanColumn = {
|
|
72
|
+
/** A stable id. */
|
|
73
|
+
id: string;
|
|
74
|
+
/** Its name — passed translated (“To review”). */
|
|
75
|
+
title: string;
|
|
76
|
+
/** The most cards it should hold: the count turns to danger past it. */
|
|
77
|
+
limit?: number;
|
|
78
|
+
};
|
|
79
|
+
type KanbanMove = {
|
|
80
|
+
/** The card moved. */
|
|
81
|
+
cardId: string;
|
|
82
|
+
/** Where it came from. */
|
|
83
|
+
from: string;
|
|
84
|
+
/** The column it went to. */
|
|
85
|
+
to: string;
|
|
86
|
+
/** Its position in that column (0 = top). */
|
|
87
|
+
index: number;
|
|
88
|
+
};
|
|
89
|
+
type KanbanLabels = {
|
|
90
|
+
/** The hint read on a card: how to move it with the keyboard. */
|
|
91
|
+
instructions: string;
|
|
92
|
+
/** Announced when a card is picked up: `(card, column) => …`. */
|
|
93
|
+
grabbed: (card: string, column: string) => string;
|
|
94
|
+
/** Announced as it moves: `(card, column, position, total) => …`. */
|
|
95
|
+
moved: (card: string, column: string, position: number, total: number) => string;
|
|
96
|
+
/** Announced when it is dropped. */
|
|
97
|
+
dropped: (card: string, column: string, position: number) => string;
|
|
98
|
+
/** Announced when the move is cancelled. */
|
|
99
|
+
cancelled: (card: string) => string;
|
|
100
|
+
/** A column without card (“No card”). */
|
|
101
|
+
empty: string;
|
|
102
|
+
};
|
|
103
|
+
declare const kanbanLabels: KanbanLabels;
|
|
104
|
+
type KanbanProps<T> = {
|
|
105
|
+
/** The columns, in order. */
|
|
106
|
+
columns: readonly KanbanColumn[];
|
|
107
|
+
/** The cards, in their order within each column. */
|
|
108
|
+
cards: readonly T[];
|
|
109
|
+
/** A card's id. */
|
|
110
|
+
getId: (card: T) => string;
|
|
111
|
+
/** A card's column. */
|
|
112
|
+
getColumn: (card: T) => string;
|
|
113
|
+
/** A card's name, for the announcements. */
|
|
114
|
+
getTitle: (card: T) => string;
|
|
115
|
+
/** What a card shows. */
|
|
116
|
+
renderCard: (card: T) => React.ReactNode;
|
|
117
|
+
/** Called when a card is dropped somewhere new: update the data here. */
|
|
118
|
+
onMove: (move: KanbanMove) => void;
|
|
119
|
+
/** The board's accessible name (“Moderation queue”). */
|
|
120
|
+
"aria-label": string;
|
|
121
|
+
/** The words, passed translated; English by default. */
|
|
122
|
+
labels?: Partial<KanbanLabels>;
|
|
123
|
+
/** Classes merged on the root. */
|
|
124
|
+
className?: string;
|
|
125
|
+
};
|
|
126
|
+
/**
|
|
127
|
+
* A board of cards in columns — a moderation queue, a release plan: drag and drop with the pointer, or Space and the
|
|
128
|
+
* arrow keys, every step announced. Column limits show in the counts.
|
|
129
|
+
*/
|
|
130
|
+
declare function Kanban<T>({ columns, cards, getId, getColumn, getTitle, renderCard, onMove, "aria-label": label, labels: words, className }: KanbanProps<T>): React.JSX.Element;
|
|
131
|
+
|
|
132
|
+
export { Kanban, type KanbanColumn, type KanbanLabels, type KanbanMove, type KanbanProps, kanban, kanbanLabels };
|
package/dist/kanban.js
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// src/kanban/kanban.tsx
|
|
4
|
+
import * as React from "react";
|
|
5
|
+
import { tv } from "tailwind-variants";
|
|
6
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
+
var kanban = tv({
|
|
8
|
+
slots: {
|
|
9
|
+
root: "flex w-full gap-3 overflow-x-auto pb-2",
|
|
10
|
+
column: "flex w-72 shrink-0 flex-col rounded-xl border border-border-default bg-surface-1 data-[over]:border-accent data-[over]:bg-accent-soft/40",
|
|
11
|
+
header: "flex items-center gap-2 px-3 pb-2 pt-3",
|
|
12
|
+
title: "min-w-0 flex-1 truncate text-sm font-semibold text-fg",
|
|
13
|
+
count: "rounded-full bg-surface-3 px-2 text-xs font-semibold tabular-nums text-fg-secondary data-[over-limit]:bg-danger data-[over-limit]:text-on-accent",
|
|
14
|
+
list: "m-0 flex min-h-16 list-none flex-col gap-2 p-2 pt-0",
|
|
15
|
+
card: "cursor-grab rounded-lg border border-border-default bg-surface-0 p-3 text-sm text-fg shadow-xs outline-hidden transition-shadow focus-visible:ring-2 focus-visible:ring-ring active:cursor-grabbing data-[grabbed]:ring-2 data-[grabbed]:ring-accent data-[grabbed]:shadow-lg data-[dragging]:opacity-40",
|
|
16
|
+
empty: "rounded-lg border border-dashed border-border-default px-3 py-4 text-center text-xs text-fg-secondary"
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
var kanbanLabels = {
|
|
20
|
+
instructions: "Press Space to pick it up, the arrow keys to move it, Space to drop it, Escape to cancel.",
|
|
21
|
+
grabbed: (card, column) => `${card} picked up, in ${column}.`,
|
|
22
|
+
moved: (card, column, position, total) => `${card}: ${column}, position ${position} of ${total}.`,
|
|
23
|
+
dropped: (card, column, position) => `${card} dropped in ${column}, position ${position}.`,
|
|
24
|
+
cancelled: (card) => `Move of ${card} cancelled.`,
|
|
25
|
+
empty: "No card"
|
|
26
|
+
};
|
|
27
|
+
function Kanban({ columns, cards, getId, getColumn, getTitle, renderCard, onMove, "aria-label": label, labels: words, className }) {
|
|
28
|
+
const labels = { ...kanbanLabels, ...words };
|
|
29
|
+
const s = kanban();
|
|
30
|
+
const instructionsId = React.useId();
|
|
31
|
+
const [grab, setGrab] = React.useState(null);
|
|
32
|
+
const [dragging, setDragging] = React.useState(null);
|
|
33
|
+
const [over, setOver] = React.useState(null);
|
|
34
|
+
const [message, setMessage] = React.useState("");
|
|
35
|
+
const refs = React.useRef(/* @__PURE__ */ new Map());
|
|
36
|
+
const byColumn = (column, without) => cards.filter((c) => getColumn(c) === column && getId(c) !== without);
|
|
37
|
+
const titleOf = (id) => {
|
|
38
|
+
const card = cards.find((c) => getId(c) === id);
|
|
39
|
+
return card ? getTitle(card) : id;
|
|
40
|
+
};
|
|
41
|
+
const columnTitle = (id) => columns.find((c) => c.id === id)?.title ?? id;
|
|
42
|
+
const placementOf = (id) => {
|
|
43
|
+
const card = cards.find((c) => getId(c) === id);
|
|
44
|
+
const column = getColumn(card);
|
|
45
|
+
return { column, index: byColumn(column).findIndex((c) => getId(c) === id) };
|
|
46
|
+
};
|
|
47
|
+
const commit = (id, from, to) => {
|
|
48
|
+
if (from.column !== to.column || from.index !== to.index) onMove({ cardId: id, from: from.column, to: to.column, index: to.index });
|
|
49
|
+
};
|
|
50
|
+
const shown = (column) => {
|
|
51
|
+
const list = byColumn(column, grab?.id);
|
|
52
|
+
if (grab && grab.at.column === column) {
|
|
53
|
+
const card = cards.find((c) => getId(c) === grab.id);
|
|
54
|
+
if (card) list.splice(grab.at.index, 0, card);
|
|
55
|
+
}
|
|
56
|
+
return list;
|
|
57
|
+
};
|
|
58
|
+
React.useEffect(() => {
|
|
59
|
+
if (grab) refs.current.get(grab.id)?.focus();
|
|
60
|
+
}, [grab]);
|
|
61
|
+
const onKeyDown = (event, id) => {
|
|
62
|
+
const title = titleOf(id);
|
|
63
|
+
if (!grab) {
|
|
64
|
+
if (event.key === " " || event.key === "Enter") {
|
|
65
|
+
event.preventDefault();
|
|
66
|
+
const origin2 = placementOf(id);
|
|
67
|
+
setGrab({ id, origin: origin2, at: origin2 });
|
|
68
|
+
setMessage(labels.grabbed(title, columnTitle(origin2.column)));
|
|
69
|
+
}
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const { at, origin } = grab;
|
|
73
|
+
const columnIndex = columns.findIndex((c) => c.id === at.column);
|
|
74
|
+
let next = null;
|
|
75
|
+
if (event.key === "ArrowLeft" && columnIndex > 0) next = { column: columns[columnIndex - 1].id, index: Math.min(at.index, byColumn(columns[columnIndex - 1].id, id).length) };
|
|
76
|
+
if (event.key === "ArrowRight" && columnIndex < columns.length - 1) next = { column: columns[columnIndex + 1].id, index: Math.min(at.index, byColumn(columns[columnIndex + 1].id, id).length) };
|
|
77
|
+
if (event.key === "ArrowUp" && at.index > 0) next = { ...at, index: at.index - 1 };
|
|
78
|
+
if (event.key === "ArrowDown" && at.index < byColumn(at.column, id).length) next = { ...at, index: at.index + 1 };
|
|
79
|
+
if (next) {
|
|
80
|
+
event.preventDefault();
|
|
81
|
+
setGrab({ ...grab, at: next });
|
|
82
|
+
setMessage(labels.moved(title, columnTitle(next.column), next.index + 1, byColumn(next.column, id).length + 1));
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
if (event.key === " " || event.key === "Enter") {
|
|
86
|
+
event.preventDefault();
|
|
87
|
+
setGrab(null);
|
|
88
|
+
commit(id, origin, at);
|
|
89
|
+
setMessage(labels.dropped(title, columnTitle(at.column), at.index + 1));
|
|
90
|
+
} else if (event.key === "Escape") {
|
|
91
|
+
event.preventDefault();
|
|
92
|
+
setGrab(null);
|
|
93
|
+
setMessage(labels.cancelled(title));
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
const indexAt = (column, y) => {
|
|
97
|
+
const list = byColumn(column, dragging ?? void 0);
|
|
98
|
+
const i = list.findIndex((c) => {
|
|
99
|
+
const box = refs.current.get(getId(c))?.getBoundingClientRect();
|
|
100
|
+
return box ? y < box.top + box.height / 2 : false;
|
|
101
|
+
});
|
|
102
|
+
return i === -1 ? list.length : i;
|
|
103
|
+
};
|
|
104
|
+
return /* @__PURE__ */ jsxs("div", { role: "group", "aria-label": label, className: s.root({ className }), children: [
|
|
105
|
+
/* @__PURE__ */ jsx("p", { id: instructionsId, className: "sr-only", children: labels.instructions }),
|
|
106
|
+
/* @__PURE__ */ jsx("p", { className: "sr-only", "aria-live": "assertive", children: message }),
|
|
107
|
+
columns.map((column) => {
|
|
108
|
+
const list = shown(column.id);
|
|
109
|
+
const overLimit = column.limit !== void 0 && list.length > column.limit;
|
|
110
|
+
return /* @__PURE__ */ jsxs(
|
|
111
|
+
"section",
|
|
112
|
+
{
|
|
113
|
+
"aria-label": column.title,
|
|
114
|
+
"data-over": over?.column === column.id || void 0,
|
|
115
|
+
className: s.column(),
|
|
116
|
+
onDragOver: (e) => {
|
|
117
|
+
if (!dragging) return;
|
|
118
|
+
e.preventDefault();
|
|
119
|
+
setOver({ column: column.id, index: indexAt(column.id, e.clientY) });
|
|
120
|
+
},
|
|
121
|
+
onDragLeave: (e) => {
|
|
122
|
+
if (!e.currentTarget.contains(e.relatedTarget)) setOver(null);
|
|
123
|
+
},
|
|
124
|
+
onDrop: (e) => {
|
|
125
|
+
e.preventDefault();
|
|
126
|
+
if (dragging) commit(dragging, placementOf(dragging), { column: column.id, index: indexAt(column.id, e.clientY) });
|
|
127
|
+
setDragging(null);
|
|
128
|
+
setOver(null);
|
|
129
|
+
},
|
|
130
|
+
children: [
|
|
131
|
+
/* @__PURE__ */ jsxs("header", { className: s.header(), children: [
|
|
132
|
+
/* @__PURE__ */ jsx("h3", { className: s.title(), children: column.title }),
|
|
133
|
+
/* @__PURE__ */ jsx("span", { className: s.count(), "data-over-limit": overLimit || void 0, children: column.limit !== void 0 ? `${list.length}/${column.limit}` : list.length })
|
|
134
|
+
] }),
|
|
135
|
+
/* @__PURE__ */ jsxs("ul", { className: s.list(), children: [
|
|
136
|
+
list.length === 0 ? /* @__PURE__ */ jsx("li", { className: s.empty(), children: labels.empty }) : null,
|
|
137
|
+
list.map((card) => {
|
|
138
|
+
const id = getId(card);
|
|
139
|
+
return /* @__PURE__ */ jsx(
|
|
140
|
+
"li",
|
|
141
|
+
{
|
|
142
|
+
ref: (el) => {
|
|
143
|
+
if (el) refs.current.set(id, el);
|
|
144
|
+
else refs.current.delete(id);
|
|
145
|
+
},
|
|
146
|
+
tabIndex: 0,
|
|
147
|
+
draggable: true,
|
|
148
|
+
"aria-describedby": instructionsId,
|
|
149
|
+
"aria-roledescription": "card",
|
|
150
|
+
"data-grabbed": grab?.id === id || void 0,
|
|
151
|
+
"data-dragging": dragging === id || void 0,
|
|
152
|
+
className: s.card(),
|
|
153
|
+
onKeyDown: (e) => onKeyDown(e, id),
|
|
154
|
+
onFocus: () => {
|
|
155
|
+
if (grab && grab.id !== id) {
|
|
156
|
+
setMessage(labels.cancelled(titleOf(grab.id)));
|
|
157
|
+
setGrab(null);
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
onDragStart: (e) => {
|
|
161
|
+
e.dataTransfer.effectAllowed = "move";
|
|
162
|
+
e.dataTransfer.setData("text/plain", id);
|
|
163
|
+
setDragging(id);
|
|
164
|
+
},
|
|
165
|
+
onDragEnd: () => {
|
|
166
|
+
setDragging(null);
|
|
167
|
+
setOver(null);
|
|
168
|
+
},
|
|
169
|
+
children: renderCard(card)
|
|
170
|
+
},
|
|
171
|
+
id
|
|
172
|
+
);
|
|
173
|
+
})
|
|
174
|
+
] })
|
|
175
|
+
]
|
|
176
|
+
},
|
|
177
|
+
column.id
|
|
178
|
+
);
|
|
179
|
+
})
|
|
180
|
+
] });
|
|
181
|
+
}
|
|
182
|
+
export {
|
|
183
|
+
Kanban,
|
|
184
|
+
kanban,
|
|
185
|
+
kanbanLabels
|
|
186
|
+
};
|
|
187
|
+
//# sourceMappingURL=kanban.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/kanban/kanban.tsx"],"sourcesContent":["// Client (the drag, the keyboard move, the announcements). Cards in columns that move by drag and drop — and by the\n// keyboard: Space picks a card up, the arrows carry it (← → between columns, ↑ ↓ within one), Space drops it, Esc puts it\n// back. Every move is announced in words. The app owns the data: `onMove` says where a card went.\nimport * as React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nexport const kanban = tv({\n slots: {\n root: \"flex w-full gap-3 overflow-x-auto pb-2\",\n column: \"flex w-72 shrink-0 flex-col rounded-xl border border-border-default bg-surface-1 data-[over]:border-accent data-[over]:bg-accent-soft/40\",\n header: \"flex items-center gap-2 px-3 pb-2 pt-3\",\n title: \"min-w-0 flex-1 truncate text-sm font-semibold text-fg\",\n count: \"rounded-full bg-surface-3 px-2 text-xs font-semibold tabular-nums text-fg-secondary data-[over-limit]:bg-danger data-[over-limit]:text-on-accent\",\n list: \"m-0 flex min-h-16 list-none flex-col gap-2 p-2 pt-0\",\n card:\n \"cursor-grab rounded-lg border border-border-default bg-surface-0 p-3 text-sm text-fg shadow-xs outline-hidden transition-shadow \" +\n \"focus-visible:ring-2 focus-visible:ring-ring active:cursor-grabbing data-[grabbed]:ring-2 data-[grabbed]:ring-accent data-[grabbed]:shadow-lg data-[dragging]:opacity-40\",\n empty: \"rounded-lg border border-dashed border-border-default px-3 py-4 text-center text-xs text-fg-secondary\",\n },\n});\n\nexport type KanbanColumn = {\n /** A stable id. */\n id: string;\n /** Its name — passed translated (“To review”). */\n title: string;\n /** The most cards it should hold: the count turns to danger past it. */\n limit?: number;\n};\n\nexport type KanbanMove = {\n /** The card moved. */\n cardId: string;\n /** Where it came from. */\n from: string;\n /** The column it went to. */\n to: string;\n /** Its position in that column (0 = top). */\n index: number;\n};\n\nexport type KanbanLabels = {\n /** The hint read on a card: how to move it with the keyboard. */\n instructions: string;\n /** Announced when a card is picked up: `(card, column) => …`. */\n grabbed: (card: string, column: string) => string;\n /** Announced as it moves: `(card, column, position, total) => …`. */\n moved: (card: string, column: string, position: number, total: number) => string;\n /** Announced when it is dropped. */\n dropped: (card: string, column: string, position: number) => string;\n /** Announced when the move is cancelled. */\n cancelled: (card: string) => string;\n /** A column without card (“No card”). */\n empty: string;\n};\n\nexport const kanbanLabels: KanbanLabels = {\n instructions: \"Press Space to pick it up, the arrow keys to move it, Space to drop it, Escape to cancel.\",\n grabbed: (card, column) => `${card} picked up, in ${column}.`,\n moved: (card, column, position, total) => `${card}: ${column}, position ${position} of ${total}.`,\n dropped: (card, column, position) => `${card} dropped in ${column}, position ${position}.`,\n cancelled: (card) => `Move of ${card} cancelled.`,\n empty: \"No card\",\n};\n\nexport type KanbanProps<T> = {\n /** The columns, in order. */\n columns: readonly KanbanColumn[];\n /** The cards, in their order within each column. */\n cards: readonly T[];\n /** A card's id. */\n getId: (card: T) => string;\n /** A card's column. */\n getColumn: (card: T) => string;\n /** A card's name, for the announcements. */\n getTitle: (card: T) => string;\n /** What a card shows. */\n renderCard: (card: T) => React.ReactNode;\n /** Called when a card is dropped somewhere new: update the data here. */\n onMove: (move: KanbanMove) => void;\n /** The board's accessible name (“Moderation queue”). */\n \"aria-label\": string;\n /** The words, passed translated; English by default. */\n labels?: Partial<KanbanLabels>;\n /** Classes merged on the root. */\n className?: string;\n};\n\ntype Placement = { column: string; index: number };\n\n/**\n * A board of cards in columns — a moderation queue, a release plan: drag and drop with the pointer, or Space and the\n * arrow keys, every step announced. Column limits show in the counts.\n */\nexport function Kanban<T>({ columns, cards, getId, getColumn, getTitle, renderCard, onMove, \"aria-label\": label, labels: words, className }: KanbanProps<T>) {\n const labels = { ...kanbanLabels, ...words };\n const s = kanban();\n const instructionsId = React.useId();\n const [grab, setGrab] = React.useState<{ id: string; origin: Placement; at: Placement } | null>(null);\n const [dragging, setDragging] = React.useState<string | null>(null);\n const [over, setOver] = React.useState<Placement | null>(null);\n const [message, setMessage] = React.useState(\"\");\n const refs = React.useRef(new Map<string, HTMLLIElement>());\n const byColumn = (column: string, without?: string) => cards.filter((c) => getColumn(c) === column && getId(c) !== without);\n const titleOf = (id: string) => {\n const card = cards.find((c) => getId(c) === id);\n return card ? getTitle(card) : id;\n };\n const columnTitle = (id: string) => columns.find((c) => c.id === id)?.title ?? id;\n const placementOf = (id: string): Placement => {\n const card = cards.find((c) => getId(c) === id)!;\n const column = getColumn(card);\n return { column, index: byColumn(column).findIndex((c) => getId(c) === id) };\n };\n const commit = (id: string, from: Placement, to: Placement) => {\n if (from.column !== to.column || from.index !== to.index) onMove({ cardId: id, from: from.column, to: to.column, index: to.index });\n };\n // The cards of a column as shown, with the grabbed card at its keyboard position.\n const shown = (column: string) => {\n const list = byColumn(column, grab?.id);\n if (grab && grab.at.column === column) {\n const card = cards.find((c) => getId(c) === grab.id);\n if (card) list.splice(grab.at.index, 0, card);\n }\n return list;\n };\n React.useEffect(() => {\n if (grab) refs.current.get(grab.id)?.focus();\n }, [grab]);\n\n const onKeyDown = (event: React.KeyboardEvent, id: string) => {\n const title = titleOf(id);\n if (!grab) {\n if (event.key === \" \" || event.key === \"Enter\") {\n event.preventDefault();\n const origin = placementOf(id);\n setGrab({ id, origin, at: origin });\n setMessage(labels.grabbed(title, columnTitle(origin.column)));\n }\n return;\n }\n const { at, origin } = grab;\n const columnIndex = columns.findIndex((c) => c.id === at.column);\n let next: Placement | null = null;\n if (event.key === \"ArrowLeft\" && columnIndex > 0) next = { column: columns[columnIndex - 1]!.id, index: Math.min(at.index, byColumn(columns[columnIndex - 1]!.id, id).length) };\n if (event.key === \"ArrowRight\" && columnIndex < columns.length - 1) next = { column: columns[columnIndex + 1]!.id, index: Math.min(at.index, byColumn(columns[columnIndex + 1]!.id, id).length) };\n if (event.key === \"ArrowUp\" && at.index > 0) next = { ...at, index: at.index - 1 };\n if (event.key === \"ArrowDown\" && at.index < byColumn(at.column, id).length) next = { ...at, index: at.index + 1 };\n if (next) {\n event.preventDefault();\n setGrab({ ...grab, at: next });\n setMessage(labels.moved(title, columnTitle(next.column), next.index + 1, byColumn(next.column, id).length + 1));\n return;\n }\n if (event.key === \" \" || event.key === \"Enter\") {\n event.preventDefault();\n setGrab(null);\n commit(id, origin, at);\n setMessage(labels.dropped(title, columnTitle(at.column), at.index + 1));\n } else if (event.key === \"Escape\") {\n event.preventDefault();\n setGrab(null);\n setMessage(labels.cancelled(title));\n }\n };\n\n const indexAt = (column: string, y: number) => {\n const list = byColumn(column, dragging ?? undefined);\n const i = list.findIndex((c) => {\n const box = refs.current.get(getId(c))?.getBoundingClientRect();\n return box ? y < box.top + box.height / 2 : false;\n });\n return i === -1 ? list.length : i;\n };\n\n return (\n <div role=\"group\" aria-label={label} className={s.root({ className })}>\n <p id={instructionsId} className=\"sr-only\">\n {labels.instructions}\n </p>\n <p className=\"sr-only\" aria-live=\"assertive\">\n {message}\n </p>\n {columns.map((column) => {\n const list = shown(column.id);\n const overLimit = column.limit !== undefined && list.length > column.limit;\n return (\n <section\n key={column.id}\n aria-label={column.title}\n data-over={over?.column === column.id || undefined}\n className={s.column()}\n onDragOver={(e) => {\n if (!dragging) return;\n e.preventDefault();\n setOver({ column: column.id, index: indexAt(column.id, e.clientY) });\n }}\n onDragLeave={(e) => {\n if (!e.currentTarget.contains(e.relatedTarget as Node | null)) setOver(null);\n }}\n onDrop={(e) => {\n e.preventDefault();\n if (dragging) commit(dragging, placementOf(dragging), { column: column.id, index: indexAt(column.id, e.clientY) });\n setDragging(null);\n setOver(null);\n }}\n >\n <header className={s.header()}>\n <h3 className={s.title()}>{column.title}</h3>\n <span className={s.count()} data-over-limit={overLimit || undefined}>\n {column.limit !== undefined ? `${list.length}/${column.limit}` : list.length}\n </span>\n </header>\n <ul className={s.list()}>\n {list.length === 0 ? <li className={s.empty()}>{labels.empty}</li> : null}\n {list.map((card) => {\n const id = getId(card);\n return (\n <li\n key={id}\n ref={(el) => {\n if (el) refs.current.set(id, el);\n else refs.current.delete(id);\n }}\n tabIndex={0}\n draggable\n aria-describedby={instructionsId}\n aria-roledescription=\"card\"\n data-grabbed={grab?.id === id || undefined}\n data-dragging={dragging === id || undefined}\n className={s.card()}\n onKeyDown={(e) => onKeyDown(e, id)}\n onFocus={() => {\n // Tab to another card while one is carried: the carried one goes back.\n if (grab && grab.id !== id) {\n setMessage(labels.cancelled(titleOf(grab.id)));\n setGrab(null);\n }\n }}\n onDragStart={(e) => {\n e.dataTransfer.effectAllowed = \"move\";\n e.dataTransfer.setData(\"text/plain\", id);\n setDragging(id);\n }}\n onDragEnd={() => {\n setDragging(null);\n setOver(null);\n }}\n >\n {renderCard(card)}\n </li>\n );\n })}\n </ul>\n </section>\n );\n })}\n </div>\n );\n}\n"],"mappings":"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","names":["origin"]}
|
package/dist/list.d.ts
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import * as tailwind_variants from 'tailwind-variants';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
|
|
4
|
+
declare const list: tailwind_variants.TVReturnType<{
|
|
5
|
+
density: {
|
|
6
|
+
comfortable: {
|
|
7
|
+
item: string;
|
|
8
|
+
};
|
|
9
|
+
compact: {
|
|
10
|
+
item: string;
|
|
11
|
+
description: string;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
}, {
|
|
15
|
+
root: string;
|
|
16
|
+
scroller: string;
|
|
17
|
+
ul: string;
|
|
18
|
+
item: string;
|
|
19
|
+
main: string;
|
|
20
|
+
leading: string;
|
|
21
|
+
text: string;
|
|
22
|
+
title: string;
|
|
23
|
+
description: string;
|
|
24
|
+
meta: string;
|
|
25
|
+
actions: string;
|
|
26
|
+
chevron: string;
|
|
27
|
+
message: string;
|
|
28
|
+
skeleton: string;
|
|
29
|
+
footer: string;
|
|
30
|
+
}, undefined, {
|
|
31
|
+
density: {
|
|
32
|
+
comfortable: {
|
|
33
|
+
item: string;
|
|
34
|
+
};
|
|
35
|
+
compact: {
|
|
36
|
+
item: string;
|
|
37
|
+
description: string;
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
}, {
|
|
41
|
+
root: string;
|
|
42
|
+
scroller: string;
|
|
43
|
+
ul: string;
|
|
44
|
+
item: string;
|
|
45
|
+
main: string;
|
|
46
|
+
leading: string;
|
|
47
|
+
text: string;
|
|
48
|
+
title: string;
|
|
49
|
+
description: string;
|
|
50
|
+
meta: string;
|
|
51
|
+
actions: string;
|
|
52
|
+
chevron: string;
|
|
53
|
+
message: string;
|
|
54
|
+
skeleton: string;
|
|
55
|
+
footer: string;
|
|
56
|
+
}, tailwind_variants.TVReturnTypeLike<{
|
|
57
|
+
density: {
|
|
58
|
+
comfortable: {
|
|
59
|
+
item: string;
|
|
60
|
+
};
|
|
61
|
+
compact: {
|
|
62
|
+
item: string;
|
|
63
|
+
description: string;
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
}, {
|
|
67
|
+
root: string;
|
|
68
|
+
scroller: string;
|
|
69
|
+
ul: string;
|
|
70
|
+
item: string;
|
|
71
|
+
main: string;
|
|
72
|
+
leading: string;
|
|
73
|
+
text: string;
|
|
74
|
+
title: string;
|
|
75
|
+
description: string;
|
|
76
|
+
meta: string;
|
|
77
|
+
actions: string;
|
|
78
|
+
chevron: string;
|
|
79
|
+
message: string;
|
|
80
|
+
skeleton: string;
|
|
81
|
+
footer: string;
|
|
82
|
+
}>>;
|
|
83
|
+
type ListLabels = {
|
|
84
|
+
/** The checkbox of a row: `(title) => "Select " + title`. */
|
|
85
|
+
selectRow: (title: string) => string;
|
|
86
|
+
/** Read while the rows load (“Loading”). */
|
|
87
|
+
loading: string;
|
|
88
|
+
/** The default empty state (“Nothing to show”). */
|
|
89
|
+
empty: string;
|
|
90
|
+
};
|
|
91
|
+
declare const listLabels: ListLabels;
|
|
92
|
+
type ListRow = {
|
|
93
|
+
/** The row's main line — passed translated. */
|
|
94
|
+
title: string;
|
|
95
|
+
/** A second line (a detail, a status in words). */
|
|
96
|
+
description?: React.ReactNode;
|
|
97
|
+
/** Before the text: an `Avatar`, an icon, a thumbnail. */
|
|
98
|
+
leading?: React.ReactNode;
|
|
99
|
+
/** After the text: a time, an amount, a `Badge`. */
|
|
100
|
+
meta?: React.ReactNode;
|
|
101
|
+
/** Secondary actions beside the row (icon buttons, a menu) — outside the main action. */
|
|
102
|
+
actions?: React.ReactNode;
|
|
103
|
+
/** The row opens this address (its main action is a link). */
|
|
104
|
+
href?: string;
|
|
105
|
+
/** The row's main action (a button), when it is not a link. */
|
|
106
|
+
onSelect?: () => void;
|
|
107
|
+
};
|
|
108
|
+
type ListProps<T> = {
|
|
109
|
+
/** The records, in order. */
|
|
110
|
+
items: readonly T[];
|
|
111
|
+
/** A stable id per record: the React key and the selection's value. */
|
|
112
|
+
getId: (item: T) => string;
|
|
113
|
+
/** What a record shows: its title, line, visuals, details, actions and where it leads. */
|
|
114
|
+
row: (item: T) => ListRow;
|
|
115
|
+
/** The list's accessible name (“Jobs”). */
|
|
116
|
+
"aria-label": string;
|
|
117
|
+
/** comfortable (default: 64 px rows with a line) · compact (44 px: dense admin lists). */
|
|
118
|
+
density?: "comfortable" | "compact";
|
|
119
|
+
/** A checkbox per row. */
|
|
120
|
+
selectable?: boolean;
|
|
121
|
+
/** The ids selected (controlled). */
|
|
122
|
+
selected?: readonly string[];
|
|
123
|
+
/** The ids selected at first, uncontrolled. */
|
|
124
|
+
defaultSelected?: readonly string[];
|
|
125
|
+
/** Called with the new selection. */
|
|
126
|
+
onSelectedChange?: (selected: string[]) => void;
|
|
127
|
+
/** Shows a chevron on the rows that lead somewhere. */
|
|
128
|
+
chevrons?: boolean;
|
|
129
|
+
/** Loading: `loadingRows` skeleton rows and `aria-busy`. */
|
|
130
|
+
loading?: boolean;
|
|
131
|
+
/** How many skeleton rows. Default 5. */
|
|
132
|
+
loadingRows?: number;
|
|
133
|
+
/** A failure in place of the rows (an `Alert` with a retry); announced. */
|
|
134
|
+
error?: React.ReactNode;
|
|
135
|
+
/** Shown when there is no record (an `EmptyState`). */
|
|
136
|
+
empty?: React.ReactNode;
|
|
137
|
+
/** Renders only the rows in view: fixed `rowHeight`, a scrolling region of `height` px. */
|
|
138
|
+
virtualize?: {
|
|
139
|
+
rowHeight: number;
|
|
140
|
+
height: number;
|
|
141
|
+
overscan?: number;
|
|
142
|
+
};
|
|
143
|
+
/** Under the list: a `Pagination`, a “Load more” button, a total. */
|
|
144
|
+
footer?: React.ReactNode;
|
|
145
|
+
/** The words, passed translated; English by default. */
|
|
146
|
+
labels?: Partial<ListLabels>;
|
|
147
|
+
/** Classes merged on the root. */
|
|
148
|
+
className?: string;
|
|
149
|
+
};
|
|
150
|
+
/** A list of records: dense or comfortable, selectable, actions beside each row, windowed when long, with its states. */
|
|
151
|
+
declare function List<T>({ items, getId, row, "aria-label": label, density, selectable, selected: selectedProp, defaultSelected, onSelectedChange, chevrons, loading, loadingRows, error, empty, virtualize, footer, labels: given, className, }: ListProps<T>): React.JSX.Element;
|
|
152
|
+
|
|
153
|
+
export { List, type ListLabels, type ListProps, type ListRow, list, listLabels };
|
package/dist/list.js
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import {
|
|
3
|
+
Checkbox
|
|
4
|
+
} from "./chunk-7Z4KHPFC.js";
|
|
5
|
+
import {
|
|
6
|
+
useControllable
|
|
7
|
+
} from "./chunk-BRKMQ6JV.js";
|
|
8
|
+
import {
|
|
9
|
+
ChevronGlyph
|
|
10
|
+
} from "./chunk-CPA5CF35.js";
|
|
11
|
+
|
|
12
|
+
// src/list/list.tsx
|
|
13
|
+
import * as React from "react";
|
|
14
|
+
import { tv } from "tailwind-variants";
|
|
15
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
16
|
+
var list = tv({
|
|
17
|
+
slots: {
|
|
18
|
+
root: "w-full overflow-hidden rounded-xl border border-border-default bg-surface-1",
|
|
19
|
+
scroller: "overflow-y-auto focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring",
|
|
20
|
+
ul: "m-0 list-none divide-y divide-border-subtle p-0",
|
|
21
|
+
item: "relative flex items-center gap-3 px-4 transition-colors data-[state=selected]:bg-accent-soft has-[[data-main]:hover]:bg-surface-2/60",
|
|
22
|
+
main: "flex min-w-0 flex-1 items-center gap-3 self-stretch text-left text-fg outline-hidden focus-visible:after:absolute focus-visible:after:inset-0.5 focus-visible:after:rounded-lg focus-visible:after:ring-2 focus-visible:after:ring-ring",
|
|
23
|
+
leading: "flex shrink-0 items-center justify-center text-fg-secondary",
|
|
24
|
+
text: "flex min-w-0 flex-1 flex-col",
|
|
25
|
+
title: "truncate text-sm font-semibold text-fg",
|
|
26
|
+
description: "line-clamp-2 text-xs text-fg-secondary",
|
|
27
|
+
meta: "flex shrink-0 flex-col items-end gap-1 text-xs tabular-nums text-fg-secondary",
|
|
28
|
+
actions: "relative z-10 flex shrink-0 items-center gap-1",
|
|
29
|
+
chevron: "h-4 w-4 shrink-0 text-fg-muted",
|
|
30
|
+
message: "px-4 py-10 text-center text-sm text-fg-secondary",
|
|
31
|
+
skeleton: "animate-pulse rounded bg-surface-3 motion-reduce:animate-none",
|
|
32
|
+
footer: "border-t border-border-default px-4 py-3"
|
|
33
|
+
},
|
|
34
|
+
variants: {
|
|
35
|
+
density: {
|
|
36
|
+
comfortable: { item: "min-h-16 py-2.5" },
|
|
37
|
+
compact: { item: "min-h-11 py-1.5", description: "line-clamp-1" }
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
defaultVariants: { density: "comfortable" }
|
|
41
|
+
});
|
|
42
|
+
var listLabels = { selectRow: (title) => `Select ${title}`, loading: "Loading", empty: "Nothing to show" };
|
|
43
|
+
function List({
|
|
44
|
+
items,
|
|
45
|
+
getId,
|
|
46
|
+
row,
|
|
47
|
+
"aria-label": label,
|
|
48
|
+
density,
|
|
49
|
+
selectable,
|
|
50
|
+
selected: selectedProp,
|
|
51
|
+
defaultSelected = [],
|
|
52
|
+
onSelectedChange,
|
|
53
|
+
chevrons,
|
|
54
|
+
loading,
|
|
55
|
+
loadingRows = 5,
|
|
56
|
+
error,
|
|
57
|
+
empty,
|
|
58
|
+
virtualize,
|
|
59
|
+
footer,
|
|
60
|
+
labels: given,
|
|
61
|
+
className
|
|
62
|
+
}) {
|
|
63
|
+
const labels = { ...listLabels, ...given };
|
|
64
|
+
const s = list({ density });
|
|
65
|
+
const [selected, setSelected] = useControllable(selectedProp, defaultSelected, onSelectedChange);
|
|
66
|
+
const [scrollTop, setScrollTop] = React.useState(0);
|
|
67
|
+
const chosen = new Set(selected);
|
|
68
|
+
const toggle = (id) => setSelected(chosen.has(id) ? selected.filter((x) => x !== id) : [...selected, id]);
|
|
69
|
+
let shown = items;
|
|
70
|
+
let before = 0;
|
|
71
|
+
let after = 0;
|
|
72
|
+
if (virtualize && !loading) {
|
|
73
|
+
const overscan = virtualize.overscan ?? 6;
|
|
74
|
+
const start = Math.max(0, Math.floor(scrollTop / virtualize.rowHeight) - overscan);
|
|
75
|
+
const end = Math.min(items.length, Math.ceil((scrollTop + virtualize.height) / virtualize.rowHeight) + overscan);
|
|
76
|
+
shown = items.slice(start, end);
|
|
77
|
+
before = start * virtualize.rowHeight;
|
|
78
|
+
after = (items.length - end) * virtualize.rowHeight;
|
|
79
|
+
}
|
|
80
|
+
let body;
|
|
81
|
+
if (loading) {
|
|
82
|
+
body = Array.from({ length: loadingRows }, (_, i) => /* @__PURE__ */ jsxs("li", { "aria-hidden": true, className: s.item(), children: [
|
|
83
|
+
/* @__PURE__ */ jsx("div", { className: s.skeleton({ className: "h-9 w-9 rounded-full" }) }),
|
|
84
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col gap-2", children: [
|
|
85
|
+
/* @__PURE__ */ jsx("div", { className: s.skeleton({ className: "h-3.5 w-2/5" }) }),
|
|
86
|
+
/* @__PURE__ */ jsx("div", { className: s.skeleton({ className: "h-3 w-3/5" }) })
|
|
87
|
+
] })
|
|
88
|
+
] }, `loading-${i}`));
|
|
89
|
+
} else if (error) {
|
|
90
|
+
body = /* @__PURE__ */ jsx("li", { className: s.message(), children: /* @__PURE__ */ jsx("div", { role: "alert", children: error }) });
|
|
91
|
+
} else if (items.length === 0) {
|
|
92
|
+
body = /* @__PURE__ */ jsx("li", { className: s.message(), children: empty ?? labels.empty });
|
|
93
|
+
} else {
|
|
94
|
+
body = shown.map((item) => {
|
|
95
|
+
const id = getId(item);
|
|
96
|
+
const r = row(item);
|
|
97
|
+
const isChosen = chosen.has(id);
|
|
98
|
+
const content = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
99
|
+
r.leading ? /* @__PURE__ */ jsx("span", { className: s.leading(), children: r.leading }) : null,
|
|
100
|
+
/* @__PURE__ */ jsxs("span", { className: s.text(), children: [
|
|
101
|
+
/* @__PURE__ */ jsx("span", { className: s.title(), children: r.title }),
|
|
102
|
+
r.description ? /* @__PURE__ */ jsx("span", { className: s.description(), children: r.description }) : null
|
|
103
|
+
] }),
|
|
104
|
+
r.meta ? /* @__PURE__ */ jsx("span", { className: s.meta(), children: r.meta }) : null,
|
|
105
|
+
chevrons && (r.href || r.onSelect) ? /* @__PURE__ */ jsx(ChevronGlyph, { direction: "right", className: s.chevron() }) : null
|
|
106
|
+
] });
|
|
107
|
+
return /* @__PURE__ */ jsxs("li", { "data-state": isChosen ? "selected" : void 0, className: s.item(), style: virtualize ? { height: virtualize.rowHeight } : void 0, children: [
|
|
108
|
+
selectable ? /* @__PURE__ */ jsx(Checkbox, { checked: isChosen, onCheckedChange: () => toggle(id), "aria-label": labels.selectRow(r.title), className: "relative z-10" }) : null,
|
|
109
|
+
r.href ? /* @__PURE__ */ jsx("a", { href: r.href, "data-main": "", className: s.main(), children: content }) : r.onSelect ? /* @__PURE__ */ jsx("button", { type: "button", "data-main": "", onClick: r.onSelect, className: s.main(), children: content }) : /* @__PURE__ */ jsx("div", { className: s.main(), children: content }),
|
|
110
|
+
r.actions ? /* @__PURE__ */ jsx("div", { className: s.actions(), children: r.actions }) : null
|
|
111
|
+
] }, id);
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
const ul = /* @__PURE__ */ jsxs("ul", { "aria-label": label, "aria-busy": loading || void 0, className: s.ul(), children: [
|
|
115
|
+
before > 0 ? /* @__PURE__ */ jsx("li", { "aria-hidden": true, style: { height: before } }) : null,
|
|
116
|
+
body,
|
|
117
|
+
after > 0 ? /* @__PURE__ */ jsx("li", { "aria-hidden": true, style: { height: after } }) : null
|
|
118
|
+
] });
|
|
119
|
+
return /* @__PURE__ */ jsxs("div", { className: s.root({ className }), children: [
|
|
120
|
+
loading ? /* @__PURE__ */ jsx("span", { className: "sr-only", role: "status", children: labels.loading }) : null,
|
|
121
|
+
virtualize ? /* @__PURE__ */ jsx("div", { tabIndex: 0, role: "region", "aria-label": label, className: s.scroller(), style: { height: virtualize.height }, onScroll: (e) => setScrollTop(e.currentTarget.scrollTop), children: ul }) : ul,
|
|
122
|
+
footer ? /* @__PURE__ */ jsx("div", { className: s.footer(), children: footer }) : null
|
|
123
|
+
] });
|
|
124
|
+
}
|
|
125
|
+
export {
|
|
126
|
+
List,
|
|
127
|
+
list,
|
|
128
|
+
listLabels
|
|
129
|
+
};
|
|
130
|
+
//# sourceMappingURL=list.js.map
|