@krizaka/ui 3.53.0 → 3.55.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/README.md +1 -0
- package/dist/account-menu.d.ts +6 -2
- package/dist/account-menu.js +8 -1
- package/dist/account-menu.js.map +1 -1
- package/dist/account-settings.js +28 -88
- package/dist/account-settings.js.map +1 -1
- package/dist/anatomy-plate.d.ts +4 -1
- package/dist/anatomy-plate.js +4 -0
- package/dist/anatomy-plate.js.map +1 -1
- package/dist/app-header/search.d.ts +63 -0
- package/dist/app-header/search.js +70 -0
- package/dist/app-header/search.js.map +1 -0
- package/dist/app-header.d.ts +88 -4
- package/dist/app-header.js +63 -5
- package/dist/app-header.js.map +1 -1
- package/dist/app-shell.js +31 -40
- package/dist/app-shell.js.map +1 -1
- package/dist/argument-card.js +3 -3
- package/dist/bird-plate.d.ts +3 -1
- package/dist/bird-plate.js +2 -2
- package/dist/bird-plate.js.map +1 -1
- package/dist/blocks.css +202 -27
- package/dist/chapter.d.ts +20 -3
- package/dist/chapter.js +82 -31
- package/dist/chapter.js.map +1 -1
- package/dist/chat.js +2 -2
- package/dist/chat.js.map +1 -1
- package/dist/checkbox.js +1 -1
- package/dist/checkbox.js.map +1 -1
- package/dist/chip.js +5 -98
- package/dist/chip.js.map +1 -1
- package/dist/choice-grid.js +28 -88
- package/dist/choice-grid.js.map +1 -1
- package/dist/{chunk-YGIN2YIY.js → chunk-3X3OF4TI.js} +2 -2
- package/dist/chunk-3X3OF4TI.js.map +1 -0
- package/dist/chunk-5VEVYDVC.js +11 -0
- package/dist/chunk-5VEVYDVC.js.map +1 -0
- package/dist/chunk-7U5TXA5Q.js +105 -0
- package/dist/chunk-7U5TXA5Q.js.map +1 -0
- package/dist/{chunk-KBQD6HE3.js → chunk-AEP3K4YD.js} +3 -3
- package/dist/{chunk-KBQD6HE3.js.map → chunk-AEP3K4YD.js.map} +1 -1
- package/dist/chunk-BDIU5LZB.js +18 -0
- package/dist/chunk-BDIU5LZB.js.map +1 -0
- package/dist/chunk-CSRKYZ53.js +39 -0
- package/dist/chunk-CSRKYZ53.js.map +1 -0
- package/dist/chunk-HEKDKM5Y.js +128 -0
- package/dist/chunk-HEKDKM5Y.js.map +1 -0
- package/dist/chunk-KGLRZMCY.js +16 -0
- package/dist/chunk-KGLRZMCY.js.map +1 -0
- package/dist/chunk-KID32IRJ.js +18 -0
- package/dist/chunk-KID32IRJ.js.map +1 -0
- package/dist/{chunk-ZQW7LF4Y.js → chunk-OIMXKRXF.js} +2 -2
- package/dist/{chunk-YHKTYFOQ.js → chunk-QWKCNSPF.js} +271 -47
- package/dist/chunk-QWKCNSPF.js.map +1 -0
- package/dist/{chunk-4LYKBSOG.js → chunk-USPOIQV5.js} +2 -2
- package/dist/chunk-USPOIQV5.js.map +1 -0
- package/dist/{chunk-7NRSPHAF.js → chunk-VB7MWE2N.js} +2 -2
- package/dist/{chunk-7NRSPHAF.js.map → chunk-VB7MWE2N.js.map} +1 -1
- package/dist/chunk-VIPSZXO4.js +103 -0
- package/dist/chunk-VIPSZXO4.js.map +1 -0
- package/dist/chunk-YCZ7N6Q6.js +385 -0
- package/dist/chunk-YCZ7N6Q6.js.map +1 -0
- package/dist/code-block.js +81 -98
- package/dist/code-block.js.map +1 -1
- package/dist/combobox.js +2 -2
- package/dist/component-page.d.ts +4 -1
- package/dist/component-page.js +5 -0
- package/dist/component-page.js.map +1 -1
- package/dist/continue-prompt.d.ts +4 -1
- package/dist/continue-prompt.js +4 -0
- package/dist/continue-prompt.js.map +1 -1
- package/dist/data-table.d.ts +60 -4
- package/dist/data-table.js +19 -7
- package/dist/date-picker.js +2 -2
- package/dist/date-picker.js.map +1 -1
- package/dist/detail-layout.d.ts +28 -17
- package/dist/detail-layout.js +73 -16
- package/dist/detail-layout.js.map +1 -1
- package/dist/doodle.d.ts +21 -0
- package/dist/doodle.js +39 -0
- package/dist/doodle.js.map +1 -0
- package/dist/drop-overlay.d.ts +12 -4
- package/dist/drop-overlay.js +16 -6
- package/dist/drop-overlay.js.map +1 -1
- package/dist/elephant.d.ts +2 -0
- package/dist/elephant.js +4 -0
- package/dist/elephant.js.map +1 -1
- package/dist/field.js +1 -1
- package/dist/field.js.map +1 -1
- package/dist/filter-bar.js +2 -2
- package/dist/force-update-screen.d.ts +5 -1
- package/dist/force-update-screen.js +4 -0
- package/dist/force-update-screen.js.map +1 -1
- package/dist/gallery-page.d.ts +4 -1
- package/dist/gallery-page.js +4 -0
- package/dist/gallery-page.js.map +1 -1
- package/dist/genui.js +5 -5
- package/dist/image-cropper.d.ts +10 -2
- package/dist/image-cropper.js +4 -0
- package/dist/image-cropper.js.map +1 -1
- package/dist/kanban.d.ts +3 -0
- package/dist/kanban.js +4 -0
- package/dist/kanban.js.map +1 -1
- package/dist/landscape.d.ts +4 -1
- package/dist/landscape.js +4 -0
- package/dist/landscape.js.map +1 -1
- package/dist/list.js +1 -1
- package/dist/maintenance-screen.d.ts +5 -1
- package/dist/maintenance-screen.js +4 -0
- package/dist/maintenance-screen.js.map +1 -1
- package/dist/map.js +6 -0
- package/dist/map.js.map +1 -1
- package/dist/markdown.d.ts +5 -1
- package/dist/markdown.js +12 -5
- package/dist/markdown.js.map +1 -1
- package/dist/match-dialog.d.ts +4 -1
- package/dist/match-dialog.js +4 -0
- package/dist/match-dialog.js.map +1 -1
- package/dist/media-capture.d.ts +6 -1
- package/dist/media-capture.js +4 -0
- package/dist/media-capture.js.map +1 -1
- package/dist/meter.js +5 -121
- package/dist/meter.js.map +1 -1
- package/dist/native/map.js +6 -0
- package/dist/native/map.js.map +1 -1
- package/dist/native/markdown.d.ts +9 -2
- package/dist/native/markdown.js +46 -7
- package/dist/native/markdown.js.map +1 -1
- package/dist/native/media-capture.d.ts +1 -0
- package/dist/native/media-capture.js +5 -0
- package/dist/native/media-capture.js.map +1 -1
- package/dist/native/vertical-video.d.ts +8 -2
- package/dist/native/vertical-video.js +6 -0
- package/dist/native/vertical-video.js.map +1 -1
- package/dist/native.d.ts +94 -4
- package/dist/native.js +1236 -1110
- package/dist/native.js.map +1 -1
- package/dist/nav-bar/me.d.ts +32 -0
- package/dist/nav-bar/me.js +23 -0
- package/dist/nav-bar/me.js.map +1 -0
- package/dist/nav-bar.d.ts +60 -2
- package/dist/nav-bar.js +92 -48
- package/dist/nav-bar.js.map +1 -1
- package/dist/notification-preferences.d.ts +151 -0
- package/dist/notification-preferences.js +77 -0
- package/dist/notification-preferences.js.map +1 -0
- package/dist/page-header.js +1 -1
- package/dist/page-header.js.map +1 -1
- package/dist/pointer-light.js +5 -0
- package/dist/pointer-light.js.map +1 -1
- package/dist/product-page.d.ts +4 -1
- package/dist/product-page.js +4 -0
- package/dist/product-page.js.map +1 -1
- package/dist/profile-card.d.ts +119 -1
- package/dist/profile-card.js +68 -21
- package/dist/profile-card.js.map +1 -1
- package/dist/promise-card.d.ts +4 -1
- package/dist/promise-card.js +4 -0
- package/dist/promise-card.js.map +1 -1
- package/dist/quota-meter.d.ts +113 -0
- package/dist/quota-meter.js +58 -0
- package/dist/quota-meter.js.map +1 -0
- package/dist/radio-group.js +6 -8
- package/dist/radio-group.js.map +1 -1
- package/dist/rail-nav.d.ts +18 -2
- package/dist/rail-nav.js +25 -2
- package/dist/rail-nav.js.map +1 -1
- package/dist/retro-tv.d.ts +30 -0
- package/dist/retro-tv.js +124 -0
- package/dist/retro-tv.js.map +1 -0
- package/dist/router.d.ts +12 -1
- package/dist/router.js +85 -8
- package/dist/router.js.map +1 -1
- package/dist/scroll-stage.d.ts +5 -1
- package/dist/scroll-stage.js +5 -0
- package/dist/scroll-stage.js.map +1 -1
- package/dist/search-field.js +1 -1
- package/dist/showcase.d.ts +9 -2
- package/dist/showcase.js +5 -0
- package/dist/showcase.js.map +1 -1
- package/dist/signature.d.ts +19 -0
- package/dist/signature.js +39 -0
- package/dist/signature.js.map +1 -0
- package/dist/site-footer.js +1 -1
- package/dist/sites.js +1 -1
- package/dist/sites.js.map +1 -1
- package/dist/slot.d.ts +1 -1
- package/dist/stat.js +1 -1
- package/dist/stat.js.map +1 -1
- package/dist/status-page.d.ts +4 -1
- package/dist/status-page.js +5 -0
- package/dist/status-page.js.map +1 -1
- package/dist/stuck.d.ts +27 -0
- package/dist/stuck.js +26 -0
- package/dist/stuck.js.map +1 -0
- package/dist/swipe-deck.d.ts +9 -2
- package/dist/swipe-deck.js +5 -0
- package/dist/swipe-deck.js.map +1 -1
- package/dist/switch.js +4 -32
- package/dist/switch.js.map +1 -1
- package/dist/tabs.d.ts +47 -8
- package/dist/tabs.js +62 -12
- package/dist/tabs.js.map +1 -1
- package/dist/tag-input.js +2 -2
- package/dist/tag-selector.js +1 -1
- package/dist/terminal-replay.d.ts +4 -1
- package/dist/terminal-replay.js +4 -0
- package/dist/terminal-replay.js.map +1 -1
- package/dist/tree-view.js +4 -0
- package/dist/tree-view.js.map +1 -1
- package/dist/update-prompt.d.ts +5 -1
- package/dist/update-prompt.js +4 -0
- package/dist/update-prompt.js.map +1 -1
- package/dist/video-player.js +7 -376
- package/dist/video-player.js.map +1 -1
- package/dist/video-trimmer.d.ts +6 -1
- package/dist/video-trimmer.js +4 -0
- package/dist/video-trimmer.js.map +1 -1
- package/package.json +143 -31
- package/registry/account-menu.json +9 -8
- package/registry/account-settings.json +2 -2
- package/registry/achievement.json +3 -4
- package/registry/action-bar.json +3 -3
- package/registry/action-sheet.json +1 -0
- package/registry/activity-feed.json +2 -1
- package/registry/agenda.json +1 -1
- package/registry/alert.json +1 -1
- package/registry/anatomy-plate.json +13 -5
- package/registry/app-header.json +470 -23
- package/registry/app-shell.json +2 -2
- 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 +3 -2
- package/registry/badge.json +2 -1
- package/registry/bird-plate.json +16 -2
- package/registry/button.json +7 -6
- package/registry/captcha.json +1 -1
- package/registry/card-grid.json +1 -1
- package/registry/card.json +7 -6
- package/registry/catalogue-page.json +3 -4
- package/registry/changelog-page.json +3 -5
- package/registry/chapter.json +46 -10
- package/registry/chat.json +3 -2
- package/registry/checkbox.json +4 -3
- package/registry/chip-link.json +2 -2
- package/registry/chip-row.json +2 -2
- package/registry/chip.json +3 -2
- package/registry/choice-grid.json +3 -4
- package/registry/code-block.json +1 -1
- package/registry/combobox.json +3 -2
- package/registry/command.json +2 -2
- package/registry/comparison-table.json +1 -1
- package/registry/component-page.json +14 -5
- package/registry/confirm-button.json +4 -4
- package/registry/contact-page.json +1 -1
- package/registry/continue-prompt.json +13 -5
- package/registry/countdown.json +4 -3
- package/registry/cover-hero.json +3 -4
- package/registry/cta-panel.json +1 -1
- package/registry/dashboard-layout.json +1 -1
- package/registry/data-table.json +63 -7
- package/registry/date-picker.json +5 -4
- package/registry/decision-list.json +1 -1
- package/registry/description-list.json +2 -1
- package/registry/detail-layout.json +30 -6
- package/registry/dialog.json +7 -6
- package/registry/docs-article-page.json +3 -4
- package/registry/docs-hub-page.json +1 -1
- package/registry/docs-layout.json +1 -1
- package/registry/docs-nav.json +1 -1
- package/registry/document-viewer.json +3 -5
- package/registry/doodle.json +209 -0
- package/registry/drop-overlay.json +30 -16
- package/registry/dropdown-menu.json +2 -2
- package/registry/elephant.json +15 -7
- package/registry/empty-state.json +2 -1
- package/registry/engine-flow.json +1 -1
- package/registry/error-page.json +3 -5
- package/registry/examples/app-header/family.d.ts +4 -0
- package/registry/examples/app-header/family.js +41 -0
- package/registry/examples/app-header/family.tsx +37 -0
- package/registry/examples/app-header/native/family.d.ts +4 -0
- package/registry/examples/app-header/native/family.dark.png +0 -0
- package/registry/examples/app-header/native/family.js +25 -0
- package/registry/examples/app-header/native/family.light.png +0 -0
- package/registry/examples/app-header/native/family.tsx +33 -0
- package/registry/examples/chapter/album.d.ts +4 -0
- package/registry/examples/chapter/album.js +34 -0
- package/registry/examples/chapter/album.tsx +30 -0
- package/registry/examples/chapter/in-ruled-page.d.ts +4 -0
- package/registry/examples/chapter/in-ruled-page.js +23 -0
- package/registry/examples/chapter/in-ruled-page.tsx +19 -0
- package/registry/examples/data-table/applicant-files.d.ts +4 -0
- package/registry/examples/data-table/applicant-files.js +24 -0
- package/registry/examples/data-table/applicant-files.tsx +23 -0
- package/registry/examples/data-table/checks.d.ts +4 -0
- package/registry/examples/data-table/checks.js +25 -0
- package/registry/examples/data-table/checks.tsx +24 -0
- package/registry/examples/detail-layout/profile.d.ts +4 -0
- package/registry/examples/detail-layout/profile.js +26 -0
- package/registry/examples/detail-layout/profile.tsx +21 -0
- package/registry/examples/doodle/kinds.d.ts +4 -0
- package/registry/examples/doodle/kinds.js +17 -0
- package/registry/examples/doodle/kinds.tsx +14 -0
- package/registry/examples/doodle/margin.d.ts +4 -0
- package/registry/examples/doodle/margin.js +17 -0
- package/registry/examples/doodle/margin.tsx +17 -0
- package/registry/examples/markdown/native/basic.dark.png +0 -0
- package/registry/examples/markdown/native/basic.light.png +0 -0
- package/registry/examples/markdown/native/wide-table.d.ts +4 -0
- package/registry/examples/markdown/native/wide-table.dark.png +0 -0
- package/registry/examples/markdown/native/wide-table.js +23 -0
- package/registry/examples/markdown/native/wide-table.light.png +0 -0
- package/registry/examples/markdown/native/wide-table.tsx +22 -0
- package/registry/examples/markdown/wide-table.d.ts +4 -0
- package/registry/examples/markdown/wide-table.js +28 -0
- package/registry/examples/markdown/wide-table.tsx +23 -0
- package/registry/examples/nav-bar/family-product.js +2 -4
- package/registry/examples/nav-bar/family-product.tsx +3 -5
- package/registry/examples/notification-preferences/default.d.ts +4 -0
- package/registry/examples/notification-preferences/default.js +29 -0
- package/registry/examples/notification-preferences/default.tsx +28 -0
- package/registry/examples/profile-card/banner.d.ts +4 -0
- package/registry/examples/profile-card/banner.js +28 -0
- package/registry/examples/profile-card/banner.tsx +24 -0
- package/registry/examples/profile-card/native/banner.d.ts +4 -0
- package/registry/examples/profile-card/native/banner.dark.png +0 -0
- package/registry/examples/profile-card/native/banner.js +22 -0
- package/registry/examples/profile-card/native/banner.light.png +0 -0
- package/registry/examples/profile-card/native/banner.tsx +18 -0
- package/registry/examples/quota-meter/default.d.ts +4 -0
- package/registry/examples/quota-meter/default.js +26 -0
- package/registry/examples/quota-meter/default.tsx +20 -0
- package/registry/examples/quota-meter/full.d.ts +4 -0
- package/registry/examples/quota-meter/full.js +25 -0
- package/registry/examples/quota-meter/full.tsx +18 -0
- package/registry/examples/rail-nav/shortcuts.d.ts +4 -0
- package/registry/examples/rail-nav/shortcuts.js +49 -0
- package/registry/examples/rail-nav/shortcuts.tsx +40 -0
- package/registry/examples/retro-tv/cabinet.d.ts +4 -0
- package/registry/examples/retro-tv/cabinet.js +12 -0
- package/registry/examples/retro-tv/cabinet.tsx +7 -0
- package/registry/examples/retro-tv/portable.d.ts +4 -0
- package/registry/examples/retro-tv/portable.js +12 -0
- package/registry/examples/retro-tv/portable.tsx +7 -0
- package/registry/examples/signature/both.d.ts +4 -0
- package/registry/examples/signature/both.js +11 -0
- package/registry/examples/signature/both.tsx +6 -0
- package/registry/examples/signature/variants.d.ts +4 -0
- package/registry/examples/signature/variants.js +14 -0
- package/registry/examples/signature/variants.tsx +11 -0
- package/registry/examples/stuck/card.d.ts +4 -0
- package/registry/examples/stuck/card.js +13 -0
- package/registry/examples/stuck/card.tsx +14 -0
- package/registry/examples/stuck/holds.d.ts +4 -0
- package/registry/examples/stuck/holds.js +12 -0
- package/registry/examples/stuck/holds.tsx +16 -0
- package/registry/examples/stuck/tag.d.ts +4 -0
- package/registry/examples/stuck/tag.js +12 -0
- package/registry/examples/stuck/tag.tsx +13 -0
- package/registry/examples/tabs/binder.d.ts +4 -0
- package/registry/examples/tabs/binder.js +22 -0
- package/registry/examples/tabs/binder.tsx +20 -0
- package/registry/examples/tabs/native/binder.d.ts +4 -0
- package/registry/examples/tabs/native/binder.dark.png +0 -0
- package/registry/examples/tabs/native/binder.js +26 -0
- package/registry/examples/tabs/native/binder.light.png +0 -0
- package/registry/examples/tabs/native/binder.tsx +22 -0
- package/registry/fab.json +1 -0
- package/registry/field.json +3 -2
- package/registry/file-upload.json +6 -11
- package/registry/filter-bar.json +2 -2
- package/registry/flock.json +3 -4
- package/registry/footnote.json +2 -3
- package/registry/force-update-screen.json +14 -5
- package/registry/form.json +5 -4
- package/registry/gallery-page.json +14 -5
- package/registry/genui.json +2 -2
- package/registry/glossary-term.json +1 -1
- package/registry/glossary.json +1 -1
- package/registry/glow-card.json +2 -2
- package/registry/goal-gauge.json +2 -1
- package/registry/header.json +1 -0
- package/registry/how-it-works-page.json +3 -5
- package/registry/image-cropper.json +13 -5
- package/registry/image-viewer.json +3 -4
- package/registry/index.json +306 -91
- package/registry/iso.json +1 -1
- package/registry/kanban.json +13 -5
- package/registry/kbd.json +1 -1
- package/registry/kpi-explained.json +2 -2
- package/registry/landing-page.json +3 -5
- package/registry/landscape.json +13 -5
- package/registry/language-switch.json +1 -1
- package/registry/legal-page.json +1 -1
- package/registry/link-card.json +1 -1
- package/registry/list.json +2 -1
- package/registry/loader.json +2 -1
- package/registry/longform-page.json +1 -1
- package/registry/maintenance-screen.json +14 -5
- package/registry/map.json +3 -2
- package/registry/markdown.json +86 -9
- 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 +12 -11
- package/registry/mascots.json +2 -1
- package/registry/match-dialog.json +14 -5
- package/registry/media-capture.json +14 -5
- package/registry/media-gallery.json +3 -5
- package/registry/media-grid.json +1 -1
- package/registry/media-picker.json +2 -3
- package/registry/meta-row.json +2 -1
- package/registry/meter.json +4 -3
- package/registry/nav-bar.json +100 -9
- package/registry/next-actions.json +1 -1
- package/registry/notification-preferences.json +250 -0
- package/registry/number-ticker.json +2 -1
- package/registry/onboarding.json +1 -0
- package/registry/opening-hours.json +1 -1
- package/registry/otp-input.json +1 -0
- package/registry/page-header.json +2 -2
- package/registry/page-hero.json +1 -1
- package/registry/page-index.json +1 -1
- package/registry/page.json +3 -3
- package/registry/pagination.json +2 -1
- package/registry/permission-prompt.json +2 -2
- package/registry/photo-grid.json +4 -4
- package/registry/pointer-light.json +6 -2
- package/registry/popover.json +2 -2
- package/registry/pricing-page.json +4 -6
- package/registry/product-page.json +14 -5
- package/registry/profile-card.json +232 -8
- package/registry/progress.json +4 -3
- package/registry/promise-card.json +13 -5
- package/registry/pull-to-refresh.json +1 -0
- package/registry/quota-meter.json +308 -0
- package/registry/radio-group.json +4 -3
- package/registry/rail-nav.json +48 -10
- package/registry/recipes.json +1 -1
- package/registry/retro-tv.json +478 -0
- package/registry/router.json +3 -3
- package/registry/screen.json +1 -0
- package/registry/scroll-stage.json +14 -5
- package/registry/search-field.json +3 -2
- package/registry/section-backdrop.json +1 -1
- package/registry/segmented.json +1 -0
- package/registry/separator.json +2 -2
- package/registry/service-card.json +1 -1
- package/registry/settings-layout.json +2 -1
- package/registry/showcase.json +14 -5
- package/registry/signature.json +185 -0
- package/registry/site-footer.json +3 -3
- package/registry/sites.json +2 -2
- package/registry/skeleton.json +2 -1
- package/registry/skip-link.json +1 -1
- package/registry/slider.json +5 -4
- package/registry/slot-picker.json +1 -1
- package/registry/slot.json +2 -2
- package/registry/specimen-tag.json +1 -1
- package/registry/spinner.json +4 -3
- package/registry/splash-handoff.json +1 -0
- package/registry/split-view.json +1 -1
- package/registry/stage-banner.json +2 -3
- package/registry/stat.json +2 -2
- package/registry/status-page.json +13 -5
- package/registry/step-progress.json +2 -1
- package/registry/step-showcase.json +3 -5
- package/registry/stepper.json +2 -1
- package/registry/sticky-action.json +1 -1
- package/registry/stuck.json +219 -0
- package/registry/swipe-deck.json +14 -5
- package/registry/swipeable-row.json +1 -0
- package/registry/switch.json +3 -2
- package/registry/tab-bar.json +1 -0
- package/registry/tabs.json +154 -22
- package/registry/tag-input.json +1 -1
- package/registry/tag-selector.json +2 -1
- package/registry/taped-photo.json +1 -1
- package/registry/terminal-replay.json +14 -5
- package/registry/text-style.json +5 -5
- package/registry/theme.json +2 -1
- package/registry/toast.json +2 -1
- package/registry/toc.json +1 -1
- package/registry/tooltip.json +2 -2
- package/registry/tree-view.json +6 -2
- package/registry/txt.json +1 -0
- package/registry/update-prompt.json +14 -5
- package/registry/upload-queue.json +1 -1
- package/registry/verified-badge.json +6 -6
- package/registry/vertical-video.json +8 -3
- package/registry/video-player.json +5 -6
- package/registry/video-trimmer.json +13 -5
- package/registry/virtual.json +2 -2
- package/registry/waveform.json +4 -3
- package/dist/chunk-4LYKBSOG.js.map +0 -1
- package/dist/chunk-HHFWK2HH.js +0 -163
- package/dist/chunk-HHFWK2HH.js.map +0 -1
- package/dist/chunk-R3LTSMS5.js +0 -75
- package/dist/chunk-R3LTSMS5.js.map +0 -1
- package/dist/chunk-YGIN2YIY.js.map +0 -1
- package/dist/chunk-YHKTYFOQ.js.map +0 -1
- /package/dist/{chunk-ZQW7LF4Y.js.map → chunk-OIMXKRXF.js.map} +0 -0
package/dist/video-player.js
CHANGED
|
@@ -1,383 +1,14 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
VideoPlayer,
|
|
4
|
+
videoPlayer,
|
|
5
|
+
videoPlayerLabels
|
|
6
|
+
} from "./chunk-YCZ7N6Q6.js";
|
|
7
|
+
import "./chunk-ADRUEPYC.js";
|
|
5
8
|
import "./chunk-HJFRHYCI.js";
|
|
6
9
|
import "./chunk-NSLXEDIS.js";
|
|
7
|
-
import
|
|
8
|
-
|
|
9
|
-
formatClock,
|
|
10
|
-
playSafely,
|
|
11
|
-
useInView,
|
|
12
|
-
usePrefersReducedMotion
|
|
13
|
-
} from "./chunk-FZBWEDQI.js";
|
|
14
|
-
import {
|
|
15
|
-
CaptionsGlyph,
|
|
16
|
-
FullscreenGlyph,
|
|
17
|
-
PauseGlyph,
|
|
18
|
-
PipGlyph,
|
|
19
|
-
PlayGlyph,
|
|
20
|
-
RetryGlyph,
|
|
21
|
-
VolumeGlyph
|
|
22
|
-
} from "./chunk-CPA5CF35.js";
|
|
23
|
-
|
|
24
|
-
// src/video-player/video-player.tsx
|
|
25
|
-
import * as React from "react";
|
|
26
|
-
import { tv } from "tailwind-variants";
|
|
27
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
28
|
-
var videoPlayer = tv({
|
|
29
|
-
slots: {
|
|
30
|
-
root: "theme-dark group/player relative isolate w-full overflow-hidden rounded-xl bg-media text-fg-on-media focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring data-[idle]:cursor-none",
|
|
31
|
-
video: "absolute inset-0 h-full w-full object-contain",
|
|
32
|
-
poster: "pointer-events-none absolute inset-0 h-full w-full object-contain",
|
|
33
|
-
big: "absolute left-1/2 top-1/2 z-10 inline-flex h-16 w-16 -translate-x-1/2 -translate-y-1/2 items-center justify-center rounded-full bg-scrim-strong text-fg-on-media shadow-lg backdrop-blur-sm transition-colors hover:bg-scrim motion-reduce:transition-none focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring",
|
|
34
|
-
bar: "absolute inset-x-0 bottom-0 z-20 flex flex-col gap-1 bg-linear-to-t from-scrim-strong via-scrim to-transparent px-3 pb-2 pt-10 transition-opacity duration-300 motion-reduce:transition-none group-data-[idle]/player:opacity-0 group-focus-within/player:opacity-100",
|
|
35
|
-
row: "flex items-center gap-1",
|
|
36
|
-
button: "inline-flex h-9 min-w-9 shrink-0 items-center justify-center gap-1 rounded-md px-1.5 text-xs font-semibold text-fg-on-media transition-colors hover:bg-fg-on-media/15 focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring aria-pressed:bg-fg-on-media/20",
|
|
37
|
-
time: "px-1.5 font-mono text-[11px] tabular-nums text-fg-on-media",
|
|
38
|
-
volume: "hidden w-20 items-center sm:flex",
|
|
39
|
-
status: "absolute inset-0 z-30 flex flex-col items-center justify-center gap-3 bg-scrim-strong p-6 text-center text-sm",
|
|
40
|
-
spinner: "h-10 w-10 animate-spin rounded-full border-2 border-fg-on-media/30 border-t-fg-on-media motion-reduce:animate-none",
|
|
41
|
-
overlay: "absolute inset-0 z-30"
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
var videoPlayerLabels = {
|
|
45
|
-
play: "Play",
|
|
46
|
-
pause: "Pause",
|
|
47
|
-
mute: "Mute",
|
|
48
|
-
unmute: "Unmute",
|
|
49
|
-
volume: "Volume",
|
|
50
|
-
seek: "Seek",
|
|
51
|
-
speed: (rate) => `Speed ${rate}\xD7`,
|
|
52
|
-
captions: (track) => `Subtitles: ${track ?? "off"}`,
|
|
53
|
-
fullscreen: "Full screen",
|
|
54
|
-
exitFullscreen: "Exit full screen",
|
|
55
|
-
pictureInPicture: "Picture in picture",
|
|
56
|
-
loading: "Loading",
|
|
57
|
-
error: "This video cannot be played.",
|
|
58
|
-
retry: "Try again",
|
|
59
|
-
time: (time, duration) => `${time} of ${duration}`
|
|
60
|
-
};
|
|
61
|
-
var RATES = [0.5, 1, 1.25, 1.5, 2];
|
|
62
|
-
var isHls = (url, type) => type === "hls" || type !== "file" && /\.m3u8(\?|#|$)/i.test(url);
|
|
63
|
-
function showTrack(element, index) {
|
|
64
|
-
const list = element.textTracks;
|
|
65
|
-
for (let i = 0; i < list.length; i += 1) list[i].mode = i === index ? "showing" : "disabled";
|
|
66
|
-
}
|
|
67
|
-
function VideoPlayer({
|
|
68
|
-
src,
|
|
69
|
-
type = "auto",
|
|
70
|
-
loadHls,
|
|
71
|
-
title,
|
|
72
|
-
poster,
|
|
73
|
-
autoPlay,
|
|
74
|
-
muted: initiallyMuted = false,
|
|
75
|
-
loop,
|
|
76
|
-
preload = "metadata",
|
|
77
|
-
tracks = [],
|
|
78
|
-
playbackRates = RATES,
|
|
79
|
-
pauseWhenHidden = true,
|
|
80
|
-
controls = true,
|
|
81
|
-
overlay,
|
|
82
|
-
aspectRatio = "16 / 9",
|
|
83
|
-
onPlay,
|
|
84
|
-
onPause,
|
|
85
|
-
onEnded,
|
|
86
|
-
onTimeUpdate,
|
|
87
|
-
onError,
|
|
88
|
-
labels: given,
|
|
89
|
-
className
|
|
90
|
-
}) {
|
|
91
|
-
const labels = { ...videoPlayerLabels, ...given };
|
|
92
|
-
const s = videoPlayer();
|
|
93
|
-
const root = React.useRef(null);
|
|
94
|
-
const video = React.useRef(null);
|
|
95
|
-
const reduce = usePrefersReducedMotion();
|
|
96
|
-
const [resolved, setResolved] = React.useState(null);
|
|
97
|
-
const [attempt, setAttempt] = React.useState(0);
|
|
98
|
-
const [wanted, setWanted] = React.useState(false);
|
|
99
|
-
const [playing, setPlaying] = React.useState(false);
|
|
100
|
-
const [time, setTime] = React.useState(0);
|
|
101
|
-
const [duration, setDuration] = React.useState(0);
|
|
102
|
-
const [volume, setVolume] = React.useState(1);
|
|
103
|
-
const [muted, setMuted] = React.useState(initiallyMuted || Boolean(autoPlay));
|
|
104
|
-
const [rate, setRate] = React.useState(1);
|
|
105
|
-
const [caption, setCaption] = React.useState(() => tracks.findIndex((t) => t.default));
|
|
106
|
-
const [fullscreen, setFullscreen] = React.useState(false);
|
|
107
|
-
const [waiting, setWaiting] = React.useState(false);
|
|
108
|
-
const [failed, setFailed] = React.useState(false);
|
|
109
|
-
const [idle, setIdle] = React.useState(false);
|
|
110
|
-
const [started, setStarted] = React.useState(false);
|
|
111
|
-
const idleTimer = React.useRef(void 0);
|
|
112
|
-
const url = typeof src === "string" ? src : resolved?.attempt === attempt ? resolved.url : null;
|
|
113
|
-
const needSource = typeof src === "function" && (preload !== "none" || wanted || autoPlay && !reduce);
|
|
114
|
-
React.useEffect(() => {
|
|
115
|
-
if (typeof src !== "function" || !needSource) return;
|
|
116
|
-
let live = true;
|
|
117
|
-
src().then(
|
|
118
|
-
(next) => live && setResolved({ attempt, url: next }),
|
|
119
|
-
(error) => {
|
|
120
|
-
if (!live) return;
|
|
121
|
-
setFailed(true);
|
|
122
|
-
onError?.(error);
|
|
123
|
-
}
|
|
124
|
-
);
|
|
125
|
-
return () => {
|
|
126
|
-
live = false;
|
|
127
|
-
};
|
|
128
|
-
}, [src, needSource, attempt]);
|
|
129
|
-
React.useEffect(() => {
|
|
130
|
-
const element = video.current;
|
|
131
|
-
if (!element || !url) return;
|
|
132
|
-
let hls = null;
|
|
133
|
-
let live = true;
|
|
134
|
-
const fail = (error) => {
|
|
135
|
-
if (!live) return;
|
|
136
|
-
setFailed(true);
|
|
137
|
-
onError?.(error);
|
|
138
|
-
};
|
|
139
|
-
if (isHls(url, type) && !element.canPlayType("application/vnd.apple.mpegurl")) {
|
|
140
|
-
if (!loadHls) fail(new Error("VideoPlayer: HLS needs `loadHls` in this browser."));
|
|
141
|
-
else
|
|
142
|
-
loadHls().then(({ default: Hls }) => {
|
|
143
|
-
if (!live) return;
|
|
144
|
-
if (!Hls.isSupported()) return fail(new Error("VideoPlayer: HLS is not supported here."));
|
|
145
|
-
hls = new Hls({ enableWorker: true, backBufferLength: 60 });
|
|
146
|
-
hls.on(Hls.Events.ERROR, (_event, data) => {
|
|
147
|
-
if (!data.fatal) return;
|
|
148
|
-
if (data.type === Hls.ErrorTypes.NETWORK_ERROR) hls?.startLoad();
|
|
149
|
-
else if (data.type === Hls.ErrorTypes.MEDIA_ERROR) hls?.recoverMediaError();
|
|
150
|
-
else fail(data);
|
|
151
|
-
});
|
|
152
|
-
hls.loadSource(url);
|
|
153
|
-
hls.attachMedia(element);
|
|
154
|
-
}, fail);
|
|
155
|
-
} else element.src = url;
|
|
156
|
-
return () => {
|
|
157
|
-
live = false;
|
|
158
|
-
hls?.destroy();
|
|
159
|
-
};
|
|
160
|
-
}, [url, type]);
|
|
161
|
-
const [inView, setInView] = React.useState(() => !pauseWhenHidden || typeof IntersectionObserver === "undefined");
|
|
162
|
-
React.useEffect(() => {
|
|
163
|
-
const element = video.current;
|
|
164
|
-
if (!element || !url || !wanted) return;
|
|
165
|
-
playSafely(element);
|
|
166
|
-
}, [url, wanted]);
|
|
167
|
-
React.useEffect(() => {
|
|
168
|
-
const element = video.current;
|
|
169
|
-
if (!element || !url || !autoPlay || reduce || !inView) return;
|
|
170
|
-
playSafely(element);
|
|
171
|
-
}, [url, autoPlay, reduce, inView]);
|
|
172
|
-
React.useEffect(() => {
|
|
173
|
-
if (video.current) showTrack(video.current, caption);
|
|
174
|
-
}, [caption, tracks.length]);
|
|
175
|
-
React.useEffect(() => {
|
|
176
|
-
const change = () => setFullscreen(document.fullscreenElement === root.current);
|
|
177
|
-
document.addEventListener("fullscreenchange", change);
|
|
178
|
-
return () => document.removeEventListener("fullscreenchange", change);
|
|
179
|
-
}, []);
|
|
180
|
-
React.useEffect(() => () => clearTimeout(idleTimer.current), []);
|
|
181
|
-
useInView(
|
|
182
|
-
root,
|
|
183
|
-
(visible) => {
|
|
184
|
-
setInView(visible);
|
|
185
|
-
if (!visible && video.current && !video.current.paused) video.current.pause();
|
|
186
|
-
},
|
|
187
|
-
pauseWhenHidden
|
|
188
|
-
);
|
|
189
|
-
const play = () => {
|
|
190
|
-
setWanted(true);
|
|
191
|
-
setFailed(false);
|
|
192
|
-
playSafely(video.current);
|
|
193
|
-
};
|
|
194
|
-
const toggle = () => playing ? video.current?.pause() : play();
|
|
195
|
-
const seek = (to) => {
|
|
196
|
-
if (!video.current) return;
|
|
197
|
-
video.current.currentTime = clamp(to, 0, duration || video.current.duration || 0);
|
|
198
|
-
setTime(video.current.currentTime);
|
|
199
|
-
};
|
|
200
|
-
const changeVolume = (to) => {
|
|
201
|
-
if (!video.current) return;
|
|
202
|
-
const next = clamp(to, 0, 1);
|
|
203
|
-
video.current.volume = next;
|
|
204
|
-
video.current.muted = next === 0;
|
|
205
|
-
setVolume(next);
|
|
206
|
-
setMuted(next === 0);
|
|
207
|
-
};
|
|
208
|
-
const toggleMute = () => {
|
|
209
|
-
if (!video.current) return;
|
|
210
|
-
if (muted && volume === 0) changeVolume(0.5);
|
|
211
|
-
video.current.muted = !muted;
|
|
212
|
-
setMuted(!muted);
|
|
213
|
-
};
|
|
214
|
-
const cycleRate = () => {
|
|
215
|
-
const next = playbackRates[(playbackRates.indexOf(rate) + 1) % playbackRates.length] ?? 1;
|
|
216
|
-
if (video.current) video.current.playbackRate = next;
|
|
217
|
-
setRate(next);
|
|
218
|
-
};
|
|
219
|
-
const cycleCaption = () => tracks.length > 0 && setCaption((c) => (c + 2) % (tracks.length + 1) - 1);
|
|
220
|
-
const toggleFullscreen = () => {
|
|
221
|
-
const element = root.current;
|
|
222
|
-
if (!element) return;
|
|
223
|
-
if (document.fullscreenElement) void document.exitFullscreen();
|
|
224
|
-
else if (element.requestFullscreen) void element.requestFullscreen();
|
|
225
|
-
else video.current?.webkitEnterFullscreen?.();
|
|
226
|
-
};
|
|
227
|
-
const pip = () => {
|
|
228
|
-
if (document.pictureInPictureElement) void document.exitPictureInPicture();
|
|
229
|
-
else void video.current?.requestPictureInPicture?.();
|
|
230
|
-
};
|
|
231
|
-
const wake = () => {
|
|
232
|
-
setIdle(false);
|
|
233
|
-
clearTimeout(idleTimer.current);
|
|
234
|
-
if (playing) idleTimer.current = setTimeout(() => setIdle(true), 2500);
|
|
235
|
-
};
|
|
236
|
-
const onKeyDown = (event) => {
|
|
237
|
-
const target = event.target;
|
|
238
|
-
const inControl = target.getAttribute("role") === "slider";
|
|
239
|
-
const key = event.key.length === 1 ? event.key.toLowerCase() : event.key;
|
|
240
|
-
const now = video.current?.currentTime ?? 0;
|
|
241
|
-
const actions = {
|
|
242
|
-
" ": target.tagName === "BUTTON" ? void 0 : toggle,
|
|
243
|
-
k: toggle,
|
|
244
|
-
j: () => seek(now - 10),
|
|
245
|
-
l: () => seek(now + 10),
|
|
246
|
-
m: toggleMute,
|
|
247
|
-
f: toggleFullscreen,
|
|
248
|
-
c: tracks.length ? cycleCaption : void 0,
|
|
249
|
-
ArrowLeft: inControl ? void 0 : () => seek(now - 5),
|
|
250
|
-
ArrowRight: inControl ? void 0 : () => seek(now + 5),
|
|
251
|
-
ArrowUp: inControl ? void 0 : () => changeVolume(volume + 0.1),
|
|
252
|
-
ArrowDown: inControl ? void 0 : () => changeVolume(volume - 0.1),
|
|
253
|
-
Home: inControl ? void 0 : () => seek(0),
|
|
254
|
-
End: inControl ? void 0 : () => seek(duration)
|
|
255
|
-
};
|
|
256
|
-
const action = /^[0-9]$/.test(key) && !inControl ? () => seek(Number(key) / 10 * duration) : actions[key];
|
|
257
|
-
if (!action || event.metaKey || event.ctrlKey || event.altKey) return;
|
|
258
|
-
event.preventDefault();
|
|
259
|
-
action();
|
|
260
|
-
wake();
|
|
261
|
-
};
|
|
262
|
-
const showControls = controls && !overlay;
|
|
263
|
-
const pipSupported = typeof document !== "undefined" && "pictureInPictureEnabled" in document && document.pictureInPictureEnabled;
|
|
264
|
-
return /* @__PURE__ */ jsxs(
|
|
265
|
-
"div",
|
|
266
|
-
{
|
|
267
|
-
ref: root,
|
|
268
|
-
role: "region",
|
|
269
|
-
"aria-label": title,
|
|
270
|
-
tabIndex: showControls ? 0 : void 0,
|
|
271
|
-
"data-idle": idle && playing ? "" : void 0,
|
|
272
|
-
"data-state": playing ? "playing" : "paused",
|
|
273
|
-
className: s.root({ className }),
|
|
274
|
-
style: { aspectRatio },
|
|
275
|
-
onKeyDown: showControls ? onKeyDown : void 0,
|
|
276
|
-
onPointerMove: showControls ? wake : void 0,
|
|
277
|
-
onPointerLeave: () => playing && setIdle(true),
|
|
278
|
-
children: [
|
|
279
|
-
/* @__PURE__ */ jsx(
|
|
280
|
-
"video",
|
|
281
|
-
{
|
|
282
|
-
ref: video,
|
|
283
|
-
className: s.video(),
|
|
284
|
-
preload,
|
|
285
|
-
loop,
|
|
286
|
-
muted,
|
|
287
|
-
playsInline: true,
|
|
288
|
-
crossOrigin: tracks.length ? "anonymous" : void 0,
|
|
289
|
-
onClick: showControls ? toggle : void 0,
|
|
290
|
-
onPlay: () => {
|
|
291
|
-
setStarted(true);
|
|
292
|
-
setPlaying(true);
|
|
293
|
-
wake();
|
|
294
|
-
onPlay?.();
|
|
295
|
-
},
|
|
296
|
-
onPause: () => {
|
|
297
|
-
setPlaying(false);
|
|
298
|
-
setIdle(false);
|
|
299
|
-
onPause?.();
|
|
300
|
-
},
|
|
301
|
-
onEnded: () => onEnded?.(),
|
|
302
|
-
onTimeUpdate: (event) => {
|
|
303
|
-
setTime(event.currentTarget.currentTime);
|
|
304
|
-
onTimeUpdate?.(event.currentTarget.currentTime);
|
|
305
|
-
},
|
|
306
|
-
onDurationChange: (event) => setDuration(Number.isFinite(event.currentTarget.duration) ? event.currentTarget.duration : 0),
|
|
307
|
-
onWaiting: () => setWaiting(true),
|
|
308
|
-
onPlaying: () => setWaiting(false),
|
|
309
|
-
onCanPlay: () => setWaiting(false),
|
|
310
|
-
onError: (event) => {
|
|
311
|
-
setFailed(true);
|
|
312
|
-
onError?.(event.currentTarget.error);
|
|
313
|
-
},
|
|
314
|
-
children: tracks.map((track) => /* @__PURE__ */ jsx("track", { src: track.src, srcLang: track.srcLang, label: track.label, kind: track.kind ?? "subtitles", default: track.default }, track.src))
|
|
315
|
-
}
|
|
316
|
-
),
|
|
317
|
-
poster && !started ? /* @__PURE__ */ jsx("img", { src: poster, alt: "", "aria-hidden": true, decoding: "async", className: s.poster() }) : null,
|
|
318
|
-
showControls && !playing && !failed && !waiting && /* @__PURE__ */ jsx("button", { type: "button", className: s.big(), "aria-label": labels.play, onClick: play, children: /* @__PURE__ */ jsx(PlayGlyph, { className: "ml-1 h-7 w-7" }) }),
|
|
319
|
-
waiting && !failed && /* @__PURE__ */ jsxs("div", { className: "pointer-events-none absolute inset-0 z-10 flex items-center justify-center", children: [
|
|
320
|
-
/* @__PURE__ */ jsx("span", { className: s.spinner(), "aria-hidden": true }),
|
|
321
|
-
/* @__PURE__ */ jsx("span", { role: "status", className: "sr-only", children: labels.loading })
|
|
322
|
-
] }),
|
|
323
|
-
failed && /* @__PURE__ */ jsxs("div", { role: "alert", className: s.status(), children: [
|
|
324
|
-
/* @__PURE__ */ jsx("p", { children: labels.error }),
|
|
325
|
-
/* @__PURE__ */ jsxs(
|
|
326
|
-
"button",
|
|
327
|
-
{
|
|
328
|
-
type: "button",
|
|
329
|
-
className: s.button({ className: "border border-fg-on-media/40 px-3" }),
|
|
330
|
-
onClick: () => {
|
|
331
|
-
setFailed(false);
|
|
332
|
-
setAttempt((a) => a + 1);
|
|
333
|
-
video.current?.load();
|
|
334
|
-
},
|
|
335
|
-
children: [
|
|
336
|
-
/* @__PURE__ */ jsx(RetryGlyph, { className: "h-4 w-4" }),
|
|
337
|
-
labels.retry
|
|
338
|
-
]
|
|
339
|
-
}
|
|
340
|
-
)
|
|
341
|
-
] }),
|
|
342
|
-
overlay ? /* @__PURE__ */ jsx("div", { className: s.overlay(), children: overlay }) : null,
|
|
343
|
-
showControls && /* @__PURE__ */ jsxs("div", { className: s.bar(), children: [
|
|
344
|
-
/* @__PURE__ */ jsx(
|
|
345
|
-
Slider,
|
|
346
|
-
{
|
|
347
|
-
label: labels.seek,
|
|
348
|
-
min: 0,
|
|
349
|
-
max: duration || 1,
|
|
350
|
-
step: 0.1,
|
|
351
|
-
value: Math.min(time, duration || 1),
|
|
352
|
-
onValueChange: seek,
|
|
353
|
-
formatValue: (v) => labels.time(formatClock(v), formatClock(duration)),
|
|
354
|
-
disabled: !duration,
|
|
355
|
-
className: "[&_[role=slider]]:h-4 [&_[role=slider]]:w-4"
|
|
356
|
-
}
|
|
357
|
-
),
|
|
358
|
-
/* @__PURE__ */ jsxs("div", { className: s.row(), children: [
|
|
359
|
-
/* @__PURE__ */ jsx("button", { type: "button", className: s.button(), "aria-label": playing ? labels.pause : labels.play, onClick: toggle, children: playing ? /* @__PURE__ */ jsx(PauseGlyph, { className: "h-5 w-5" }) : /* @__PURE__ */ jsx(PlayGlyph, { className: "h-5 w-5" }) }),
|
|
360
|
-
/* @__PURE__ */ jsx("button", { type: "button", className: s.button(), "aria-label": muted ? labels.unmute : labels.mute, onClick: toggleMute, children: /* @__PURE__ */ jsx(VolumeGlyph, { muted, className: "h-5 w-5" }) }),
|
|
361
|
-
/* @__PURE__ */ jsx("div", { className: s.volume(), children: /* @__PURE__ */ jsx(Slider, { label: labels.volume, min: 0, max: 1, step: 0.05, value: muted ? 0 : volume, onValueChange: changeVolume, formatValue: (v) => `${Math.round(v * 100)} %`, className: "w-full" }) }),
|
|
362
|
-
/* @__PURE__ */ jsxs("span", { className: s.time(), "aria-hidden": true, children: [
|
|
363
|
-
formatClock(time),
|
|
364
|
-
" / ",
|
|
365
|
-
formatClock(duration)
|
|
366
|
-
] }),
|
|
367
|
-
/* @__PURE__ */ jsx("span", { className: "flex-1" }),
|
|
368
|
-
playbackRates.length > 1 && /* @__PURE__ */ jsxs("button", { type: "button", className: s.button(), "aria-label": labels.speed(rate), onClick: cycleRate, children: [
|
|
369
|
-
rate,
|
|
370
|
-
"\xD7"
|
|
371
|
-
] }),
|
|
372
|
-
tracks.length > 0 && /* @__PURE__ */ jsx("button", { type: "button", className: s.button(), "aria-pressed": caption >= 0, "aria-label": labels.captions(caption >= 0 ? tracks[caption]?.label ?? null : null), onClick: cycleCaption, children: /* @__PURE__ */ jsx(CaptionsGlyph, { className: "h-5 w-5" }) }),
|
|
373
|
-
pipSupported && /* @__PURE__ */ jsx("button", { type: "button", className: s.button(), "aria-label": labels.pictureInPicture, onClick: pip, children: /* @__PURE__ */ jsx(PipGlyph, { className: "h-5 w-5" }) }),
|
|
374
|
-
/* @__PURE__ */ jsx("button", { type: "button", className: s.button(), "aria-label": fullscreen ? labels.exitFullscreen : labels.fullscreen, onClick: toggleFullscreen, children: /* @__PURE__ */ jsx(FullscreenGlyph, { exit: fullscreen, className: "h-5 w-5" }) })
|
|
375
|
-
] })
|
|
376
|
-
] })
|
|
377
|
-
]
|
|
378
|
-
}
|
|
379
|
-
);
|
|
380
|
-
}
|
|
10
|
+
import "./chunk-FZBWEDQI.js";
|
|
11
|
+
import "./chunk-CPA5CF35.js";
|
|
381
12
|
export {
|
|
382
13
|
VideoPlayer,
|
|
383
14
|
videoPlayer,
|
package/dist/video-player.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/video-player/video-player.tsx"],"sourcesContent":["// Client. A `<video>` with its own controls, accessible from end to end: a named region the keyboard reaches (Space /\n// K, arrows, J / L, M, F, C, Home / End, 0–9), every button named by a prop, the seek and volume sliders of\n// `@krizaka/ui/slider` with the time read aloud. HLS plays natively where the browser can (Safari, iOS) and through\n// hls.js elsewhere — loaded only then, by the app's `loadHls` (`() => import(\"hls.js\")`): an optional peer, never in\n// the bundle of a page that does not play HLS. A signed address can be resolved at the last moment (`src` as a\n// function), again after an error; the video pauses when it leaves the screen; autoplay waits under reduced motion.\nimport * as React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nimport { CaptionsGlyph, FullscreenGlyph, PauseGlyph, PipGlyph, PlayGlyph, RetryGlyph, VolumeGlyph } from \"../glyphs\";\nimport { clamp, formatClock, playSafely, useInView, usePrefersReducedMotion } from \"../media\";\nimport { Slider } from \"../slider\";\n\nexport const videoPlayer = tv({\n slots: {\n root:\n \"theme-dark group/player relative isolate w-full overflow-hidden rounded-xl bg-media text-fg-on-media \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring data-[idle]:cursor-none\",\n video: \"absolute inset-0 h-full w-full object-contain\",\n poster: \"pointer-events-none absolute inset-0 h-full w-full object-contain\",\n big:\n \"absolute left-1/2 top-1/2 z-10 inline-flex h-16 w-16 -translate-x-1/2 -translate-y-1/2 items-center justify-center rounded-full \" +\n \"bg-scrim-strong text-fg-on-media shadow-lg backdrop-blur-sm transition-colors hover:bg-scrim motion-reduce:transition-none \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring\",\n bar:\n \"absolute inset-x-0 bottom-0 z-20 flex flex-col gap-1 bg-linear-to-t from-scrim-strong via-scrim to-transparent px-3 pb-2 pt-10 \" +\n \"transition-opacity duration-300 motion-reduce:transition-none group-data-[idle]/player:opacity-0 group-focus-within/player:opacity-100\",\n row: \"flex items-center gap-1\",\n button:\n \"inline-flex h-9 min-w-9 shrink-0 items-center justify-center gap-1 rounded-md px-1.5 text-xs font-semibold text-fg-on-media \" +\n \"transition-colors hover:bg-fg-on-media/15 focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring aria-pressed:bg-fg-on-media/20\",\n time: \"px-1.5 font-mono text-[11px] tabular-nums text-fg-on-media\",\n volume: \"hidden w-20 items-center sm:flex\",\n status: \"absolute inset-0 z-30 flex flex-col items-center justify-center gap-3 bg-scrim-strong p-6 text-center text-sm\",\n spinner: \"h-10 w-10 animate-spin rounded-full border-2 border-fg-on-media/30 border-t-fg-on-media motion-reduce:animate-none\",\n overlay: \"absolute inset-0 z-30\",\n },\n});\n\n/** What `loadHls` resolves to: the module of hls.js (only the members the player uses are typed). */\nexport type HlsModule = {\n default: {\n new (config?: Record<string, unknown>): {\n loadSource(url: string): void;\n attachMedia(media: HTMLMediaElement): void;\n destroy(): void;\n startLoad(): void;\n recoverMediaError(): void;\n on(event: string, listener: (event: string, data: { fatal?: boolean; type?: string }) => void): void;\n };\n isSupported(): boolean;\n Events: { ERROR: string };\n ErrorTypes: { NETWORK_ERROR: string; MEDIA_ERROR: string };\n };\n};\n\nexport type VideoTrack = {\n /** The WebVTT file. */\n src: string;\n /** Its language, BCP 47 (`\"fr\"`). */\n srcLang: string;\n /** Its name in the menu (\"Français\"), passed translated. */\n label: string;\n /** `subtitles` (default) or `captions` (with the sounds, for deaf viewers). */\n kind?: \"subtitles\" | \"captions\";\n /** Shown from the start. */\n default?: boolean;\n};\n\nexport type VideoPlayerLabels = {\n play: string;\n pause: string;\n mute: string;\n unmute: string;\n volume: string;\n seek: string;\n /** The speed button: `(rate) => \"Speed \" + rate + \"×\"`. */\n speed: (rate: number) => string;\n /** The captions button: `(track) => \"Subtitles: \" + (track ?? \"off\")`, the track's label or `null` when off. */\n captions: (track: string | null) => string;\n fullscreen: string;\n exitFullscreen: string;\n pictureInPicture: string;\n /** Read while the video waits for data. */\n loading: string;\n /** The video cannot play. */\n error: string;\n /** Tries again (resolves a signed `src` again). */\n retry: string;\n /** The seek slider's value: `(time, duration) => \"1:05 of 3:20\"`. */\n time: (time: string, duration: string) => string;\n};\n\nexport const videoPlayerLabels: VideoPlayerLabels = {\n play: \"Play\",\n pause: \"Pause\",\n mute: \"Mute\",\n unmute: \"Unmute\",\n volume: \"Volume\",\n seek: \"Seek\",\n speed: (rate) => `Speed ${rate}×`,\n captions: (track) => `Subtitles: ${track ?? \"off\"}`,\n fullscreen: \"Full screen\",\n exitFullscreen: \"Exit full screen\",\n pictureInPicture: \"Picture in picture\",\n loading: \"Loading\",\n error: \"This video cannot be played.\",\n retry: \"Try again\",\n time: (time, duration) => `${time} of ${duration}`,\n};\n\nexport type VideoPlayerProps = {\n /** The address of the video (MP4, WebM, or an HLS `.m3u8`), or a function that resolves a signed one when needed. */\n src: string | (() => Promise<string>);\n /** `auto` (default): HLS when the address ends in `.m3u8`. */\n type?: \"auto\" | \"hls\" | \"file\";\n /** Loads hls.js when the browser cannot play HLS itself: `() => import(\"hls.js\")`. Without it, HLS needs Safari. */\n loadHls?: () => Promise<HlsModule>;\n /** The accessible name of the player (\"Video: Sunset over Montréal\"), passed translated. */\n title: string;\n /** The picture shown before playback. */\n poster?: string;\n /** Starts playing, muted (browsers refuse sound without a gesture), once on screen and again each time it comes back — not under reduced motion. */\n autoPlay?: boolean;\n /** Starts muted. */\n muted?: boolean;\n /** Plays again from the start at the end. */\n loop?: boolean;\n /** How much to fetch before playback: `none` (a list of many videos), `metadata` (default), `auto`. */\n preload?: \"none\" | \"metadata\" | \"auto\";\n /** Subtitles or captions (WebVTT): the C key and a button cycle through them. */\n tracks?: readonly VideoTrack[];\n /** The speeds offered by the speed button. Default `[0.5, 1, 1.25, 1.5, 2]`. */\n playbackRates?: readonly number[];\n /** Pauses when less than a quarter of the player is on screen. Default `true`. */\n pauseWhenHidden?: boolean;\n /** Shows the controls (default). `false`: a bare video (a background loop) — give it no sound. */\n controls?: boolean;\n /** Covers the video and hides the controls: a gate (sign in, unlock, age check) drawn by the app. */\n overlay?: React.ReactNode;\n /** The width / height ratio of the frame. Default `\"16 / 9\"`; `\"9 / 16\"` for a vertical video. */\n aspectRatio?: string;\n /** Called when playback starts. */\n onPlay?: () => void;\n /** Called when playback pauses. */\n onPause?: () => void;\n /** Called at the end. */\n onEnded?: () => void;\n /** Called as the time moves, in seconds (a few times a second). */\n onTimeUpdate?: (time: number) => void;\n /** Called when the video cannot play (a network failure, an expired address). */\n onError?: (error: unknown) => void;\n /** The words, passed translated; English by default. */\n labels?: Partial<VideoPlayerLabels>;\n /** Classes merged on the root. */\n className?: string;\n};\n\nconst RATES = [0.5, 1, 1.25, 1.5, 2] as const;\nconst isHls = (url: string, type: VideoPlayerProps[\"type\"]) => type === \"hls\" || (type !== \"file\" && /\\.m3u8(\\?|#|$)/i.test(url));\n\n/** Shows the text track `index` of a video (and hides the others); -1 hides them all. */\nfunction showTrack(element: HTMLVideoElement, index: number) {\n const list = element.textTracks;\n for (let i = 0; i < list.length; i += 1) list[i]!.mode = i === index ? \"showing\" : \"disabled\";\n}\n\n/** A video player with accessible controls, HLS on demand, signed sources, subtitles, speed, full screen. */\nexport function VideoPlayer({\n src,\n type = \"auto\",\n loadHls,\n title,\n poster,\n autoPlay,\n muted: initiallyMuted = false,\n loop,\n preload = \"metadata\",\n tracks = [],\n playbackRates = RATES,\n pauseWhenHidden = true,\n controls = true,\n overlay,\n aspectRatio = \"16 / 9\",\n onPlay,\n onPause,\n onEnded,\n onTimeUpdate,\n onError,\n labels: given,\n className,\n}: VideoPlayerProps) {\n const labels = { ...videoPlayerLabels, ...given };\n const s = videoPlayer();\n const root = React.useRef<HTMLDivElement>(null);\n const video = React.useRef<HTMLVideoElement>(null);\n const reduce = usePrefersReducedMotion();\n const [resolved, setResolved] = React.useState<{ attempt: number; url: string } | null>(null);\n const [attempt, setAttempt] = React.useState(0);\n const [wanted, setWanted] = React.useState(false);\n const [playing, setPlaying] = React.useState(false);\n const [time, setTime] = React.useState(0);\n const [duration, setDuration] = React.useState(0);\n const [volume, setVolume] = React.useState(1);\n const [muted, setMuted] = React.useState(initiallyMuted || Boolean(autoPlay));\n const [rate, setRate] = React.useState(1);\n const [caption, setCaption] = React.useState(() => tracks.findIndex((t) => t.default));\n const [fullscreen, setFullscreen] = React.useState(false);\n const [waiting, setWaiting] = React.useState(false);\n const [failed, setFailed] = React.useState(false);\n const [idle, setIdle] = React.useState(false);\n // The poster is an image over the video until the first play: it loads like any image (lazy, decoded once), the\n // same in every browser — the `poster` attribute is painted late and differently.\n const [started, setStarted] = React.useState(false);\n const idleTimer = React.useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n\n const url = typeof src === \"string\" ? src : resolved?.attempt === attempt ? resolved.url : null;\n const needSource = typeof src === \"function\" && (preload !== \"none\" || wanted || (autoPlay && !reduce));\n\n // A signed source is resolved when it is needed, and again on \"Try again\".\n React.useEffect(() => {\n if (typeof src !== \"function\" || !needSource) return;\n let live = true;\n src().then(\n (next) => live && setResolved({ attempt, url: next }),\n (error: unknown) => {\n if (!live) return;\n setFailed(true);\n onError?.(error);\n },\n );\n return () => {\n live = false;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps -- `onError` is a callback, not a reason to resolve again\n }, [src, needSource, attempt]);\n\n // Attaches the source: natively, or through hls.js when the browser needs it.\n React.useEffect(() => {\n const element = video.current;\n if (!element || !url) return;\n let hls: InstanceType<HlsModule[\"default\"]> | null = null;\n let live = true;\n const fail = (error: unknown) => {\n if (!live) return;\n setFailed(true);\n onError?.(error);\n };\n if (isHls(url, type) && !element.canPlayType(\"application/vnd.apple.mpegurl\")) {\n if (!loadHls) fail(new Error(\"VideoPlayer: HLS needs `loadHls` in this browser.\"));\n else\n loadHls().then(({ default: Hls }) => {\n if (!live) return;\n if (!Hls.isSupported()) return fail(new Error(\"VideoPlayer: HLS is not supported here.\"));\n hls = new Hls({ enableWorker: true, backBufferLength: 60 });\n hls.on(Hls.Events.ERROR, (_event, data) => {\n if (!data.fatal) return;\n if (data.type === Hls.ErrorTypes.NETWORK_ERROR) hls?.startLoad();\n else if (data.type === Hls.ErrorTypes.MEDIA_ERROR) hls?.recoverMediaError();\n else fail(data);\n });\n hls.loadSource(url);\n hls.attachMedia(element);\n }, fail);\n } else element.src = url;\n return () => {\n live = false;\n hls?.destroy();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps -- `onError` and `loadHls` are callbacks\n }, [url, type]);\n\n // An autoplay waits for the player to be on screen (nothing is fetched before, with `preload=\"none\"`), and plays\n // again each time it comes back: a page of loops costs only the ones in view.\n const [inView, setInView] = React.useState(() => !pauseWhenHidden || typeof IntersectionObserver === \"undefined\");\n\n // Plays once the source is there, when it was asked for (a click before a signed source resolved).\n React.useEffect(() => {\n const element = video.current;\n if (!element || !url || !wanted) return;\n playSafely(element);\n }, [url, wanted]);\n\n // An autoplay: while in view, never under reduced motion.\n React.useEffect(() => {\n const element = video.current;\n if (!element || !url || !autoPlay || reduce || !inView) return;\n playSafely(element);\n }, [url, autoPlay, reduce, inView]);\n\n React.useEffect(() => {\n if (video.current) showTrack(video.current, caption);\n }, [caption, tracks.length]);\n\n React.useEffect(() => {\n const change = () => setFullscreen(document.fullscreenElement === root.current);\n document.addEventListener(\"fullscreenchange\", change);\n return () => document.removeEventListener(\"fullscreenchange\", change);\n }, []);\n React.useEffect(() => () => clearTimeout(idleTimer.current), []);\n\n useInView(\n root,\n (visible) => {\n setInView(visible);\n if (!visible && video.current && !video.current.paused) video.current.pause();\n },\n pauseWhenHidden,\n );\n\n const play = () => {\n setWanted(true);\n setFailed(false);\n playSafely(video.current);\n };\n const toggle = () => (playing ? video.current?.pause() : play());\n const seek = (to: number) => {\n if (!video.current) return;\n video.current.currentTime = clamp(to, 0, duration || video.current.duration || 0);\n setTime(video.current.currentTime);\n };\n const changeVolume = (to: number) => {\n if (!video.current) return;\n const next = clamp(to, 0, 1);\n video.current.volume = next;\n video.current.muted = next === 0;\n setVolume(next);\n setMuted(next === 0);\n };\n const toggleMute = () => {\n if (!video.current) return;\n if (muted && volume === 0) changeVolume(0.5);\n video.current.muted = !muted;\n setMuted(!muted);\n };\n const cycleRate = () => {\n const next = playbackRates[(playbackRates.indexOf(rate) + 1) % playbackRates.length] ?? 1;\n if (video.current) video.current.playbackRate = next;\n setRate(next);\n };\n const cycleCaption = () => tracks.length > 0 && setCaption((c) => (c + 2) % (tracks.length + 1) - 1);\n const toggleFullscreen = () => {\n const element = root.current;\n if (!element) return;\n if (document.fullscreenElement) void document.exitFullscreen();\n else if (element.requestFullscreen) void element.requestFullscreen();\n else (video.current as HTMLVideoElement & { webkitEnterFullscreen?: () => void })?.webkitEnterFullscreen?.();\n };\n const pip = () => {\n if (document.pictureInPictureElement) void document.exitPictureInPicture();\n else void video.current?.requestPictureInPicture?.();\n };\n const wake = () => {\n setIdle(false);\n clearTimeout(idleTimer.current);\n if (playing) idleTimer.current = setTimeout(() => setIdle(true), 2500);\n };\n\n const onKeyDown = (event: React.KeyboardEvent) => {\n const target = event.target as HTMLElement;\n const inControl = target.getAttribute(\"role\") === \"slider\";\n const key = event.key.length === 1 ? event.key.toLowerCase() : event.key;\n const now = video.current?.currentTime ?? 0;\n const actions: Record<string, (() => void) | undefined> = {\n \" \": target.tagName === \"BUTTON\" ? undefined : toggle,\n k: toggle,\n j: () => seek(now - 10),\n l: () => seek(now + 10),\n m: toggleMute,\n f: toggleFullscreen,\n c: tracks.length ? cycleCaption : undefined,\n ArrowLeft: inControl ? undefined : () => seek(now - 5),\n ArrowRight: inControl ? undefined : () => seek(now + 5),\n ArrowUp: inControl ? undefined : () => changeVolume(volume + 0.1),\n ArrowDown: inControl ? undefined : () => changeVolume(volume - 0.1),\n Home: inControl ? undefined : () => seek(0),\n End: inControl ? undefined : () => seek(duration),\n };\n const action = /^[0-9]$/.test(key) && !inControl ? () => seek((Number(key) / 10) * duration) : actions[key];\n if (!action || event.metaKey || event.ctrlKey || event.altKey) return;\n event.preventDefault();\n action();\n wake();\n };\n\n const showControls = controls && !overlay;\n const pipSupported = typeof document !== \"undefined\" && \"pictureInPictureEnabled\" in document && document.pictureInPictureEnabled;\n\n return (\n <div\n ref={root}\n role=\"region\"\n aria-label={title}\n tabIndex={showControls ? 0 : undefined}\n data-idle={idle && playing ? \"\" : undefined}\n data-state={playing ? \"playing\" : \"paused\"}\n className={s.root({ className })}\n style={{ aspectRatio }}\n onKeyDown={showControls ? onKeyDown : undefined}\n onPointerMove={showControls ? wake : undefined}\n onPointerLeave={() => playing && setIdle(true)}\n >\n <video\n ref={video}\n className={s.video()}\n preload={preload}\n loop={loop}\n muted={muted}\n playsInline\n crossOrigin={tracks.length ? \"anonymous\" : undefined}\n onClick={showControls ? toggle : undefined}\n onPlay={() => {\n setStarted(true);\n setPlaying(true);\n wake();\n onPlay?.();\n }}\n onPause={() => {\n setPlaying(false);\n setIdle(false);\n onPause?.();\n }}\n onEnded={() => onEnded?.()}\n onTimeUpdate={(event) => {\n setTime(event.currentTarget.currentTime);\n onTimeUpdate?.(event.currentTarget.currentTime);\n }}\n onDurationChange={(event) => setDuration(Number.isFinite(event.currentTarget.duration) ? event.currentTarget.duration : 0)}\n onWaiting={() => setWaiting(true)}\n onPlaying={() => setWaiting(false)}\n onCanPlay={() => setWaiting(false)}\n onError={(event) => {\n setFailed(true);\n onError?.(event.currentTarget.error);\n }}\n >\n {tracks.map((track) => (\n <track key={track.src} src={track.src} srcLang={track.srcLang} label={track.label} kind={track.kind ?? \"subtitles\"} default={track.default} />\n ))}\n </video>\n\n {poster && !started ? <img src={poster} alt=\"\" aria-hidden decoding=\"async\" className={s.poster()} /> : null}\n\n {showControls && !playing && !failed && !waiting && (\n <button type=\"button\" className={s.big()} aria-label={labels.play} onClick={play}>\n <PlayGlyph className=\"ml-1 h-7 w-7\" />\n </button>\n )}\n\n {waiting && !failed && (\n <div className=\"pointer-events-none absolute inset-0 z-10 flex items-center justify-center\">\n <span className={s.spinner()} aria-hidden />\n <span role=\"status\" className=\"sr-only\">\n {labels.loading}\n </span>\n </div>\n )}\n\n {failed && (\n <div role=\"alert\" className={s.status()}>\n <p>{labels.error}</p>\n <button\n type=\"button\"\n className={s.button({ className: \"border border-fg-on-media/40 px-3\" })}\n onClick={() => {\n setFailed(false);\n setAttempt((a) => a + 1);\n video.current?.load();\n }}\n >\n <RetryGlyph className=\"h-4 w-4\" />\n {labels.retry}\n </button>\n </div>\n )}\n\n {overlay ? <div className={s.overlay()}>{overlay}</div> : null}\n\n {showControls && (\n <div className={s.bar()}>\n <Slider\n label={labels.seek}\n min={0}\n max={duration || 1}\n step={0.1}\n value={Math.min(time, duration || 1)}\n onValueChange={seek}\n formatValue={(v) => labels.time(formatClock(v), formatClock(duration))}\n disabled={!duration}\n className=\"[&_[role=slider]]:h-4 [&_[role=slider]]:w-4\"\n />\n <div className={s.row()}>\n <button type=\"button\" className={s.button()} aria-label={playing ? labels.pause : labels.play} onClick={toggle}>\n {playing ? <PauseGlyph className=\"h-5 w-5\" /> : <PlayGlyph className=\"h-5 w-5\" />}\n </button>\n <button type=\"button\" className={s.button()} aria-label={muted ? labels.unmute : labels.mute} onClick={toggleMute}>\n <VolumeGlyph muted={muted} className=\"h-5 w-5\" />\n </button>\n <div className={s.volume()}>\n <Slider label={labels.volume} min={0} max={1} step={0.05} value={muted ? 0 : volume} onValueChange={changeVolume} formatValue={(v) => `${Math.round(v * 100)} %`} className=\"w-full\" />\n </div>\n <span className={s.time()} aria-hidden>\n {formatClock(time)} / {formatClock(duration)}\n </span>\n <span className=\"flex-1\" />\n {playbackRates.length > 1 && (\n <button type=\"button\" className={s.button()} aria-label={labels.speed(rate)} onClick={cycleRate}>\n {rate}×\n </button>\n )}\n {tracks.length > 0 && (\n <button type=\"button\" className={s.button()} aria-pressed={caption >= 0} aria-label={labels.captions(caption >= 0 ? (tracks[caption]?.label ?? null) : null)} onClick={cycleCaption}>\n <CaptionsGlyph className=\"h-5 w-5\" />\n </button>\n )}\n {pipSupported && (\n <button type=\"button\" className={s.button()} aria-label={labels.pictureInPicture} onClick={pip}>\n <PipGlyph className=\"h-5 w-5\" />\n </button>\n )}\n <button type=\"button\" className={s.button()} aria-label={fullscreen ? labels.exitFullscreen : labels.fullscreen} onClick={toggleFullscreen}>\n <FullscreenGlyph exit={fullscreen} className=\"h-5 w-5\" />\n </button>\n </div>\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/video-trimmer.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as tailwind_variants from 'tailwind-variants';
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
|
|
4
|
+
/** @deprecated Since 3.55 (ADR-006, krizaka-ui#674): no product uses it. Removed in 4.0. */
|
|
4
5
|
declare const videoTrimmer: tailwind_variants.TVReturnType<{
|
|
5
6
|
[key: string]: {
|
|
6
7
|
[key: string]: tailwind_variants.ClassValue | {
|
|
@@ -97,6 +98,7 @@ type VideoTrimmerLabels = {
|
|
|
97
98
|
/** The length kept, above the track: `(length) => length + " kept"` (the length already formatted). */
|
|
98
99
|
kept: (length: string) => string;
|
|
99
100
|
};
|
|
101
|
+
/** @deprecated Since 3.55 (ADR-006, krizaka-ui#674): no product uses it. Removed in 4.0. */
|
|
100
102
|
declare const videoTrimmerLabels: VideoTrimmerLabels;
|
|
101
103
|
type VideoTrimmerProps = {
|
|
102
104
|
/** The length of the clip, in seconds. */
|
|
@@ -136,7 +138,10 @@ type VideoTrimmerProps = {
|
|
|
136
138
|
/** The words, passed translated; English by default. */
|
|
137
139
|
labels?: Partial<VideoTrimmerLabels>;
|
|
138
140
|
};
|
|
139
|
-
/**
|
|
141
|
+
/**
|
|
142
|
+
* Keeps a part of a clip between two handles over its filmstrip, with a playhead to scrub — the keyboard included.
|
|
143
|
+
* @deprecated Since 3.55 (ADR-006, krizaka-ui#674): no product uses it. Removed in 4.0.
|
|
144
|
+
*/
|
|
140
145
|
declare function VideoTrimmer({ duration, value: valueProp, defaultValue, onValueChange, onValueCommit, time, onSeek, minLength, step, largeStep, frames, children, formatTime, showHeader, disabled, classNames, renderHandle, labels: given, }: VideoTrimmerProps): React.JSX.Element;
|
|
141
146
|
|
|
142
147
|
export { VideoTrimmer, type VideoTrimmerLabels, type VideoTrimmerProps, videoTrimmer, videoTrimmerLabels };
|
package/dist/video-trimmer.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
|
+
import {
|
|
3
|
+
warnDeprecated
|
|
4
|
+
} from "./chunk-BDIU5LZB.js";
|
|
2
5
|
import {
|
|
3
6
|
clamp,
|
|
4
7
|
formatClock
|
|
@@ -50,6 +53,7 @@ function VideoTrimmer({
|
|
|
50
53
|
renderHandle,
|
|
51
54
|
labels: given
|
|
52
55
|
}) {
|
|
56
|
+
warnDeprecated("video-trimmer");
|
|
53
57
|
const labels = { ...videoTrimmerLabels, ...given };
|
|
54
58
|
const s = videoTrimmer();
|
|
55
59
|
const track = React.useRef(null);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/video-trimmer/video-trimmer.tsx"],"sourcesContent":["// Client. The trim timeline of a video editor: the clip as a filmstrip (or any track content), the part kept framed\n// between two edge handles — each a `slider` named by a prop, its value read as a time, never past the other one —\n// the outside dimmed, and a playhead to scrub. The handles sit on their value by their outer edge (the start handle\n// to the right of its value, the end handle to its left), so the frame encloses exactly what is kept. Every part\n// takes its own classes (`classNames`) and the handles their own content (`renderHandle`).\nimport * as React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nimport { clamp, formatClock } from \"../media\";\n\nexport const videoTrimmer = tv({\n slots: {\n root: \"w-full select-none\",\n header: \"mb-2 flex items-center justify-between font-mono text-[11px] tabular-nums text-fg-secondary\",\n kept: \"rounded-sm bg-accent-soft px-2.5 py-0.5 font-sans text-xs font-semibold text-fg\",\n track: \"relative h-16 touch-none rounded-xl bg-surface-2 data-[disabled]:opacity-50\",\n strip: \"pointer-events-none absolute inset-0 flex overflow-hidden rounded-xl\",\n frame: \"h-full min-w-0 flex-1 object-cover\",\n shade: \"pointer-events-none absolute inset-y-0 bg-scrim-strong\",\n range: \"pointer-events-none absolute inset-y-0 border-y-[3px] border-accent\",\n handle:\n \"absolute inset-y-0 z-10 flex w-6 cursor-ew-resize items-center justify-center bg-accent text-on-accent shadow-md \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-surface-0 \" +\n \"data-[edge=start]:rounded-l-xl data-[edge=end]:-translate-x-full data-[edge=end]:rounded-r-xl\",\n grip: \"flex gap-[3px] [&>span]:h-5 [&>span]:w-[2px] [&>span]:rounded-sm [&>span]:bg-on-accent/70\",\n playhead:\n \"absolute -inset-y-1.5 z-20 w-[3px] -translate-x-1/2 cursor-ew-resize rounded-full bg-fg shadow-md \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring\",\n },\n});\n\ntype Part = keyof ReturnType<typeof videoTrimmer>;\n\nexport type VideoTrimmerLabels = {\n /** The start handle (\"Start\"). */\n start: string;\n /** The end handle (\"End\"). */\n end: string;\n /** The playhead (\"Playhead\"). */\n playhead: string;\n /** The length kept, above the track: `(length) => length + \" kept\"` (the length already formatted). */\n kept: (length: string) => string;\n};\n\nexport const videoTrimmerLabels: VideoTrimmerLabels = {\n start: \"Start\",\n end: \"End\",\n playhead: \"Playhead\",\n kept: (length) => `${length} kept`,\n};\n\nexport type VideoTrimmerProps = {\n /** The length of the clip, in seconds. */\n duration: number;\n /** The part kept, `[start, end]` in seconds (controlled). */\n value?: readonly [number, number];\n /** The part kept at first, uncontrolled. Default: the whole clip. */\n defaultValue?: readonly [number, number];\n /** Called on every move of a handle. */\n onValueChange?: (value: [number, number]) => void;\n /** Called once a drag or a key press ends: render a preview, save. */\n onValueCommit?: (value: [number, number]) => void;\n /** The time played, in seconds: shows the playhead. */\n time?: number;\n /** Called when the playhead is moved (a drag on the track, the arrows on the playhead). */\n onSeek?: (time: number) => void;\n /** The shortest part that can be kept, in seconds. Default 0.5. */\n minLength?: number;\n /** One arrow press, in seconds. Default 0.1. */\n step?: number;\n /** Shift + arrow, Page Up / Page Down, in seconds. Default 1. */\n largeStep?: number;\n /** Pictures of the clip, in order: the filmstrip. */\n frames?: readonly string[];\n /** Track content instead of the filmstrip (a waveform, a coloured band). */\n children?: React.ReactNode;\n /** A time as read and shown. Default `m:ss` with tenths. */\n formatTime?: (seconds: number) => string;\n /** Shows the times and the length kept above the track. Default `true`. */\n showHeader?: boolean;\n /** Not available (a render is running). */\n disabled?: boolean;\n /** Classes per part: `root`, `header`, `kept`, `track`, `strip`, `frame`, `shade`, `range`, `handle`, `grip`, `playhead`. */\n classNames?: Partial<Record<Part, string>>;\n /** The content of a handle (default: two grip lines). */\n renderHandle?: (edge: \"start\" | \"end\") => React.ReactNode;\n /** The words, passed translated; English by default. */\n labels?: Partial<VideoTrimmerLabels>;\n};\n\nconst tenths = (seconds: number) => `${formatClock(seconds)}.${Math.floor((Math.max(0, seconds) % 1) * 10)}`;\n\ntype Grip = \"start\" | \"end\" | \"playhead\";\n\n/** Keeps a part of a clip between two handles over its filmstrip, with a playhead to scrub — the keyboard included. */\nexport function VideoTrimmer({\n duration,\n value: valueProp,\n defaultValue,\n onValueChange,\n onValueCommit,\n time,\n onSeek,\n minLength = 0.5,\n step = 0.1,\n largeStep = 1,\n frames,\n children,\n formatTime = tenths,\n showHeader = true,\n disabled,\n classNames = {},\n renderHandle,\n labels: given,\n}: VideoTrimmerProps) {\n const labels = { ...videoTrimmerLabels, ...given };\n const s = videoTrimmer();\n const track = React.useRef<HTMLDivElement>(null);\n const grip = React.useRef<Grip | null>(null);\n const [inner, setInner] = React.useState<[number, number]>(() => [defaultValue?.[0] ?? 0, defaultValue?.[1] ?? duration]);\n const [start, end] = valueProp ?? inner;\n const total = duration > 0 ? duration : 1;\n const pct = (seconds: number) => (clamp(seconds, 0, total) / total) * 100;\n\n const set = (next: [number, number], commit = false) => {\n if (!valueProp) setInner(next);\n onValueChange?.(next);\n if (commit) onValueCommit?.(next);\n };\n const move = (edge: \"start\" | \"end\", to: number, commit = false) => {\n const next: [number, number] =\n edge === \"start\" ? [clamp(to, 0, end - minLength), end] : [start, clamp(to, start + minLength, duration)];\n set([Math.round(next[0] * 1000) / 1000, Math.round(next[1] * 1000) / 1000], commit);\n };\n const seek = (to: number) => onSeek?.(clamp(to, start, Math.max(start, end - 0.05)));\n\n const at = (clientX: number) => {\n const box = track.current?.getBoundingClientRect();\n if (!box || box.width === 0) return 0;\n return clamp(((clientX - box.left) / box.width) * duration, 0, duration);\n };\n\n const keys = (which: Grip) => (event: React.KeyboardEvent) => {\n const current = which === \"start\" ? start : which === \"end\" ? end : (time ?? start);\n const big = largeStep;\n const small = event.shiftKey ? largeStep : step;\n const target: Record<string, number> = {\n ArrowLeft: current - small,\n ArrowDown: current - small,\n ArrowRight: current + small,\n ArrowUp: current + small,\n PageDown: current - big,\n PageUp: current + big,\n Home: 0,\n End: duration,\n };\n const to = target[event.key];\n if (to === undefined || disabled) return;\n event.preventDefault();\n if (which === \"playhead\") seek(to);\n else move(which, to, true);\n };\n\n const handle = (edge: \"start\" | \"end\") => {\n const own = edge === \"start\" ? start : end;\n return (\n <div\n key={edge}\n role=\"slider\"\n tabIndex={disabled ? -1 : 0}\n aria-label={edge === \"start\" ? labels.start : labels.end}\n aria-valuemin={edge === \"start\" ? 0 : Math.round((start + minLength) * 10) / 10}\n aria-valuemax={edge === \"start\" ? Math.round((end - minLength) * 10) / 10 : Math.round(duration * 10) / 10}\n aria-valuenow={Math.round(own * 10) / 10}\n aria-valuetext={formatTime(own)}\n aria-disabled={disabled || undefined}\n data-edge={edge}\n className={s.handle({ className: classNames.handle })}\n style={{ left: `${pct(own)}%` }}\n onPointerDown={(event) => {\n if (disabled) return;\n event.stopPropagation();\n track.current?.setPointerCapture?.(event.pointerId);\n grip.current = edge;\n }}\n onKeyDown={keys(edge)}\n >\n {renderHandle ? (\n renderHandle(edge)\n ) : (\n <span className={s.grip({ className: classNames.grip })}>\n <span />\n <span />\n </span>\n )}\n </div>\n );\n };\n\n return (\n <div className={s.root({ className: classNames.root })}>\n {showHeader && (\n <div className={s.header({ className: classNames.header })}>\n <span>{formatTime(start)}</span>\n <span className={s.kept({ className: classNames.kept })}>{labels.kept(formatTime(end - start))}</span>\n <span>{formatTime(end)}</span>\n </div>\n )}\n <div\n ref={track}\n className={s.track({ className: classNames.track })}\n data-disabled={disabled ? \"\" : undefined}\n onPointerDown={(event) => {\n if (disabled) return;\n track.current?.setPointerCapture?.(event.pointerId);\n const t = at(event.clientX);\n grip.current = onSeek ? \"playhead\" : Math.abs(t - start) < Math.abs(t - end) ? \"start\" : \"end\";\n if (grip.current === \"playhead\") seek(t);\n else move(grip.current, t);\n }}\n onPointerMove={(event) => {\n if (!grip.current) return;\n const t = at(event.clientX);\n if (grip.current === \"playhead\") seek(t);\n else move(grip.current, t);\n }}\n onPointerUp={() => {\n if (grip.current && grip.current !== \"playhead\") onValueCommit?.([start, end]);\n grip.current = null;\n }}\n onPointerCancel={() => {\n grip.current = null;\n }}\n >\n <div className={s.strip({ className: classNames.strip })}>\n {children ?? frames?.map((src, i) => <img key={`${i}-${src}`} src={src} alt=\"\" draggable={false} className={s.frame({ className: classNames.frame })} />)}\n </div>\n <div className={s.shade({ className: classNames.shade })} style={{ left: 0, width: `${pct(start)}%`, borderRadius: \"0.75rem 0 0 0.75rem\" }} />\n <div className={s.shade({ className: classNames.shade })} style={{ right: 0, width: `${100 - pct(end)}%`, borderRadius: \"0 0.75rem 0.75rem 0\" }} />\n <div className={s.range({ className: classNames.range })} style={{ left: `${pct(start)}%`, right: `${100 - pct(end)}%` }} />\n {time !== undefined && (\n <div\n role=\"slider\"\n tabIndex={disabled || !onSeek ? -1 : 0}\n aria-label={labels.playhead}\n aria-valuemin={Math.round(start * 10) / 10}\n aria-valuemax={Math.round(end * 10) / 10}\n aria-valuenow={Math.round(time * 10) / 10}\n aria-valuetext={formatTime(time)}\n aria-readonly={!onSeek || undefined}\n className={s.playhead({ className: classNames.playhead })}\n style={{ left: `${pct(time)}%` }}\n onKeyDown={onSeek ? keys(\"playhead\") : undefined}\n />\n )}\n {handle(\"start\")}\n {handle(\"end\")}\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/video-trimmer/video-trimmer.tsx"],"sourcesContent":["// Client. The trim timeline of a video editor: the clip as a filmstrip (or any track content), the part kept framed\n// between two edge handles — each a `slider` named by a prop, its value read as a time, never past the other one —\n// the outside dimmed, and a playhead to scrub. The handles sit on their value by their outer edge (the start handle\n// to the right of its value, the end handle to its left), so the frame encloses exactly what is kept. Every part\n// takes its own classes (`classNames`) and the handles their own content (`renderHandle`).\nimport * as React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nimport { warnDeprecated } from \"../deprecated\";\nimport { clamp, formatClock } from \"../media\";\n\n/** @deprecated Since 3.55 (ADR-006, krizaka-ui#674): no product uses it. Removed in 4.0. */\nexport const videoTrimmer = tv({\n slots: {\n root: \"w-full select-none\",\n header: \"mb-2 flex items-center justify-between font-mono text-[11px] tabular-nums text-fg-secondary\",\n kept: \"rounded-sm bg-accent-soft px-2.5 py-0.5 font-sans text-xs font-semibold text-fg\",\n track: \"relative h-16 touch-none rounded-xl bg-surface-2 data-[disabled]:opacity-50\",\n strip: \"pointer-events-none absolute inset-0 flex overflow-hidden rounded-xl\",\n frame: \"h-full min-w-0 flex-1 object-cover\",\n shade: \"pointer-events-none absolute inset-y-0 bg-scrim-strong\",\n range: \"pointer-events-none absolute inset-y-0 border-y-[3px] border-accent\",\n handle:\n \"absolute inset-y-0 z-10 flex w-6 cursor-ew-resize items-center justify-center bg-accent text-on-accent shadow-md \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-surface-0 \" +\n \"data-[edge=start]:rounded-l-xl data-[edge=end]:-translate-x-full data-[edge=end]:rounded-r-xl\",\n grip: \"flex gap-[3px] [&>span]:h-5 [&>span]:w-[2px] [&>span]:rounded-sm [&>span]:bg-on-accent/70\",\n playhead:\n \"absolute -inset-y-1.5 z-20 w-[3px] -translate-x-1/2 cursor-ew-resize rounded-full bg-fg shadow-md \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring\",\n },\n});\n\ntype Part = keyof ReturnType<typeof videoTrimmer>;\n\nexport type VideoTrimmerLabels = {\n /** The start handle (\"Start\"). */\n start: string;\n /** The end handle (\"End\"). */\n end: string;\n /** The playhead (\"Playhead\"). */\n playhead: string;\n /** The length kept, above the track: `(length) => length + \" kept\"` (the length already formatted). */\n kept: (length: string) => string;\n};\n\n/** @deprecated Since 3.55 (ADR-006, krizaka-ui#674): no product uses it. Removed in 4.0. */\nexport const videoTrimmerLabels: VideoTrimmerLabels = {\n start: \"Start\",\n end: \"End\",\n playhead: \"Playhead\",\n kept: (length) => `${length} kept`,\n};\n\nexport type VideoTrimmerProps = {\n /** The length of the clip, in seconds. */\n duration: number;\n /** The part kept, `[start, end]` in seconds (controlled). */\n value?: readonly [number, number];\n /** The part kept at first, uncontrolled. Default: the whole clip. */\n defaultValue?: readonly [number, number];\n /** Called on every move of a handle. */\n onValueChange?: (value: [number, number]) => void;\n /** Called once a drag or a key press ends: render a preview, save. */\n onValueCommit?: (value: [number, number]) => void;\n /** The time played, in seconds: shows the playhead. */\n time?: number;\n /** Called when the playhead is moved (a drag on the track, the arrows on the playhead). */\n onSeek?: (time: number) => void;\n /** The shortest part that can be kept, in seconds. Default 0.5. */\n minLength?: number;\n /** One arrow press, in seconds. Default 0.1. */\n step?: number;\n /** Shift + arrow, Page Up / Page Down, in seconds. Default 1. */\n largeStep?: number;\n /** Pictures of the clip, in order: the filmstrip. */\n frames?: readonly string[];\n /** Track content instead of the filmstrip (a waveform, a coloured band). */\n children?: React.ReactNode;\n /** A time as read and shown. Default `m:ss` with tenths. */\n formatTime?: (seconds: number) => string;\n /** Shows the times and the length kept above the track. Default `true`. */\n showHeader?: boolean;\n /** Not available (a render is running). */\n disabled?: boolean;\n /** Classes per part: `root`, `header`, `kept`, `track`, `strip`, `frame`, `shade`, `range`, `handle`, `grip`, `playhead`. */\n classNames?: Partial<Record<Part, string>>;\n /** The content of a handle (default: two grip lines). */\n renderHandle?: (edge: \"start\" | \"end\") => React.ReactNode;\n /** The words, passed translated; English by default. */\n labels?: Partial<VideoTrimmerLabels>;\n};\n\nconst tenths = (seconds: number) => `${formatClock(seconds)}.${Math.floor((Math.max(0, seconds) % 1) * 10)}`;\n\ntype Grip = \"start\" | \"end\" | \"playhead\";\n\n/**\n * Keeps a part of a clip between two handles over its filmstrip, with a playhead to scrub — the keyboard included.\n * @deprecated Since 3.55 (ADR-006, krizaka-ui#674): no product uses it. Removed in 4.0.\n */\nexport function VideoTrimmer({\n duration,\n value: valueProp,\n defaultValue,\n onValueChange,\n onValueCommit,\n time,\n onSeek,\n minLength = 0.5,\n step = 0.1,\n largeStep = 1,\n frames,\n children,\n formatTime = tenths,\n showHeader = true,\n disabled,\n classNames = {},\n renderHandle,\n labels: given,\n}: VideoTrimmerProps) {\n warnDeprecated(\"video-trimmer\");\n const labels = { ...videoTrimmerLabels, ...given };\n const s = videoTrimmer();\n const track = React.useRef<HTMLDivElement>(null);\n const grip = React.useRef<Grip | null>(null);\n const [inner, setInner] = React.useState<[number, number]>(() => [defaultValue?.[0] ?? 0, defaultValue?.[1] ?? duration]);\n const [start, end] = valueProp ?? inner;\n const total = duration > 0 ? duration : 1;\n const pct = (seconds: number) => (clamp(seconds, 0, total) / total) * 100;\n\n const set = (next: [number, number], commit = false) => {\n if (!valueProp) setInner(next);\n onValueChange?.(next);\n if (commit) onValueCommit?.(next);\n };\n const move = (edge: \"start\" | \"end\", to: number, commit = false) => {\n const next: [number, number] =\n edge === \"start\" ? [clamp(to, 0, end - minLength), end] : [start, clamp(to, start + minLength, duration)];\n set([Math.round(next[0] * 1000) / 1000, Math.round(next[1] * 1000) / 1000], commit);\n };\n const seek = (to: number) => onSeek?.(clamp(to, start, Math.max(start, end - 0.05)));\n\n const at = (clientX: number) => {\n const box = track.current?.getBoundingClientRect();\n if (!box || box.width === 0) return 0;\n return clamp(((clientX - box.left) / box.width) * duration, 0, duration);\n };\n\n const keys = (which: Grip) => (event: React.KeyboardEvent) => {\n const current = which === \"start\" ? start : which === \"end\" ? end : (time ?? start);\n const big = largeStep;\n const small = event.shiftKey ? largeStep : step;\n const target: Record<string, number> = {\n ArrowLeft: current - small,\n ArrowDown: current - small,\n ArrowRight: current + small,\n ArrowUp: current + small,\n PageDown: current - big,\n PageUp: current + big,\n Home: 0,\n End: duration,\n };\n const to = target[event.key];\n if (to === undefined || disabled) return;\n event.preventDefault();\n if (which === \"playhead\") seek(to);\n else move(which, to, true);\n };\n\n const handle = (edge: \"start\" | \"end\") => {\n const own = edge === \"start\" ? start : end;\n return (\n <div\n key={edge}\n role=\"slider\"\n tabIndex={disabled ? -1 : 0}\n aria-label={edge === \"start\" ? labels.start : labels.end}\n aria-valuemin={edge === \"start\" ? 0 : Math.round((start + minLength) * 10) / 10}\n aria-valuemax={edge === \"start\" ? Math.round((end - minLength) * 10) / 10 : Math.round(duration * 10) / 10}\n aria-valuenow={Math.round(own * 10) / 10}\n aria-valuetext={formatTime(own)}\n aria-disabled={disabled || undefined}\n data-edge={edge}\n className={s.handle({ className: classNames.handle })}\n style={{ left: `${pct(own)}%` }}\n onPointerDown={(event) => {\n if (disabled) return;\n event.stopPropagation();\n track.current?.setPointerCapture?.(event.pointerId);\n grip.current = edge;\n }}\n onKeyDown={keys(edge)}\n >\n {renderHandle ? (\n renderHandle(edge)\n ) : (\n <span className={s.grip({ className: classNames.grip })}>\n <span />\n <span />\n </span>\n )}\n </div>\n );\n };\n\n return (\n <div className={s.root({ className: classNames.root })}>\n {showHeader && (\n <div className={s.header({ className: classNames.header })}>\n <span>{formatTime(start)}</span>\n <span className={s.kept({ className: classNames.kept })}>{labels.kept(formatTime(end - start))}</span>\n <span>{formatTime(end)}</span>\n </div>\n )}\n <div\n ref={track}\n className={s.track({ className: classNames.track })}\n data-disabled={disabled ? \"\" : undefined}\n onPointerDown={(event) => {\n if (disabled) return;\n track.current?.setPointerCapture?.(event.pointerId);\n const t = at(event.clientX);\n grip.current = onSeek ? \"playhead\" : Math.abs(t - start) < Math.abs(t - end) ? \"start\" : \"end\";\n if (grip.current === \"playhead\") seek(t);\n else move(grip.current, t);\n }}\n onPointerMove={(event) => {\n if (!grip.current) return;\n const t = at(event.clientX);\n if (grip.current === \"playhead\") seek(t);\n else move(grip.current, t);\n }}\n onPointerUp={() => {\n if (grip.current && grip.current !== \"playhead\") onValueCommit?.([start, end]);\n grip.current = null;\n }}\n onPointerCancel={() => {\n grip.current = null;\n }}\n >\n <div className={s.strip({ className: classNames.strip })}>\n {children ?? frames?.map((src, i) => <img key={`${i}-${src}`} src={src} alt=\"\" draggable={false} className={s.frame({ className: classNames.frame })} />)}\n </div>\n <div className={s.shade({ className: classNames.shade })} style={{ left: 0, width: `${pct(start)}%`, borderRadius: \"0.75rem 0 0 0.75rem\" }} />\n <div className={s.shade({ className: classNames.shade })} style={{ right: 0, width: `${100 - pct(end)}%`, borderRadius: \"0 0.75rem 0.75rem 0\" }} />\n <div className={s.range({ className: classNames.range })} style={{ left: `${pct(start)}%`, right: `${100 - pct(end)}%` }} />\n {time !== undefined && (\n <div\n role=\"slider\"\n tabIndex={disabled || !onSeek ? -1 : 0}\n aria-label={labels.playhead}\n aria-valuemin={Math.round(start * 10) / 10}\n aria-valuemax={Math.round(end * 10) / 10}\n aria-valuenow={Math.round(time * 10) / 10}\n aria-valuetext={formatTime(time)}\n aria-readonly={!onSeek || undefined}\n className={s.playhead({ className: classNames.playhead })}\n style={{ left: `${pct(time)}%` }}\n onKeyDown={onSeek ? keys(\"playhead\") : undefined}\n />\n )}\n {handle(\"start\")}\n {handle(\"end\")}\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|