@archytechtor/ui 0.0.0-stage → 0.1.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/LICENSE +21 -0
- package/README.md +105 -2
- package/dist/components/accordion/accordion.d.ts +25 -0
- package/dist/components/accordion/accordion.js +88 -0
- package/dist/components/accordion/index.d.ts +3 -0
- package/dist/components/accordion/index.js +1 -0
- package/dist/components/accordion/types.d.ts +39 -0
- package/dist/components/alert/alert.d.ts +25 -0
- package/dist/components/alert/alert.js +59 -0
- package/dist/components/alert/index.d.ts +3 -0
- package/dist/components/alert/index.js +3 -0
- package/dist/components/alert/types.d.ts +32 -0
- package/dist/components/alert/types.js +19 -0
- package/dist/components/alert-dialog/alert-dialog.d.ts +73 -0
- package/dist/components/alert-dialog/alert-dialog.js +170 -0
- package/dist/components/alert-dialog/index.d.ts +3 -0
- package/dist/components/alert-dialog/index.js +1 -0
- package/dist/components/alert-dialog/types.d.ts +80 -0
- package/dist/components/aspect-ratio/aspect-ratio.d.ts +8 -0
- package/dist/components/aspect-ratio/aspect-ratio.js +20 -0
- package/dist/components/aspect-ratio/index.d.ts +3 -0
- package/dist/components/aspect-ratio/index.js +1 -0
- package/dist/components/aspect-ratio/types.d.ts +8 -0
- package/dist/components/attachment/attachment.d.ts +57 -0
- package/dist/components/attachment/attachment.js +139 -0
- package/dist/components/attachment/index.d.ts +3 -0
- package/dist/components/attachment/index.js +3 -0
- package/dist/components/attachment/types.d.ts +79 -0
- package/dist/components/attachment/types.js +43 -0
- package/dist/components/avatar/avatar.d.ts +39 -0
- package/dist/components/avatar/avatar.js +88 -0
- package/dist/components/avatar/index.d.ts +3 -0
- package/dist/components/avatar/index.js +3 -0
- package/dist/components/avatar/types.d.ts +54 -0
- package/dist/components/avatar/types.js +21 -0
- package/dist/components/badge/badge.d.ts +7 -0
- package/dist/components/badge/badge.js +23 -0
- package/dist/components/badge/index.d.ts +3 -0
- package/dist/components/badge/index.js +3 -0
- package/dist/components/badge/types.d.ts +21 -0
- package/dist/components/badge/types.js +26 -0
- package/dist/components/breadcrumb/breadcrumb.d.ts +43 -0
- package/dist/components/breadcrumb/breadcrumb.js +115 -0
- package/dist/components/breadcrumb/index.d.ts +3 -0
- package/dist/components/breadcrumb/index.js +1 -0
- package/dist/components/breadcrumb/types.d.ts +36 -0
- package/dist/components/bubble/bubble.d.ts +25 -0
- package/dist/components/bubble/bubble.js +69 -0
- package/dist/components/bubble/index.d.ts +3 -0
- package/dist/components/bubble/index.js +3 -0
- package/dist/components/bubble/types.d.ts +51 -0
- package/dist/components/bubble/types.js +60 -0
- package/dist/components/button/button.d.ts +7 -0
- package/dist/components/button/button.js +155 -0
- package/dist/components/button/index.d.ts +4 -0
- package/dist/components/button/index.js +4 -0
- package/dist/components/button/types.d.ts +80 -0
- package/dist/components/button/types.js +99 -0
- package/dist/components/button/use-hold-to-confirm.d.ts +25 -0
- package/dist/components/button/use-hold-to-confirm.js +161 -0
- package/dist/components/button-group/button-group.d.ts +20 -0
- package/dist/components/button-group/button-group.js +62 -0
- package/dist/components/button-group/index.d.ts +3 -0
- package/dist/components/button-group/index.js +3 -0
- package/dist/components/button-group/types.d.ts +30 -0
- package/dist/components/button-group/types.js +19 -0
- package/dist/components/calendar/calendar.d.ts +15 -0
- package/dist/components/calendar/calendar.js +157 -0
- package/dist/components/calendar/index.d.ts +3 -0
- package/dist/components/calendar/index.js +1 -0
- package/dist/components/calendar/types.d.ts +21 -0
- package/dist/components/card/card.d.ts +43 -0
- package/dist/components/card/card.js +97 -0
- package/dist/components/card/index.d.ts +3 -0
- package/dist/components/card/index.js +3 -0
- package/dist/components/card/types.d.ts +44 -0
- package/dist/components/card/types.js +19 -0
- package/dist/components/carousel/carousel.d.ts +36 -0
- package/dist/components/carousel/carousel.js +190 -0
- package/dist/components/carousel/index.d.ts +3 -0
- package/dist/components/carousel/index.js +1 -0
- package/dist/components/carousel/types.d.ts +79 -0
- package/dist/components/chart/chart.d.ts +35 -0
- package/dist/components/chart/chart.js +212 -0
- package/dist/components/chart/index.d.ts +3 -0
- package/dist/components/chart/index.js +1 -0
- package/dist/components/chart/types.d.ts +89 -0
- package/dist/components/chart/types.js +7 -0
- package/dist/components/checkbox/checkbox.d.ts +7 -0
- package/dist/components/checkbox/checkbox.js +31 -0
- package/dist/components/checkbox/index.d.ts +3 -0
- package/dist/components/checkbox/index.js +1 -0
- package/dist/components/checkbox/types.d.ts +25 -0
- package/dist/components/code-block/code-block.d.ts +49 -0
- package/dist/components/code-block/code-block.js +188 -0
- package/dist/components/code-block/highlighter.d.ts +15 -0
- package/dist/components/code-block/highlighter.js +123 -0
- package/dist/components/code-block/index.d.ts +5 -0
- package/dist/components/code-block/index.js +5 -0
- package/dist/components/code-block/types.d.ts +94 -0
- package/dist/components/code-block/types.js +38 -0
- package/dist/components/code-block/use-highlighted-code.d.ts +9 -0
- package/dist/components/code-block/use-highlighted-code.js +67 -0
- package/dist/components/collapsible/collapsible.d.ts +19 -0
- package/dist/components/collapsible/collapsible.js +44 -0
- package/dist/components/collapsible/index.d.ts +3 -0
- package/dist/components/collapsible/index.js +1 -0
- package/dist/components/collapsible/types.d.ts +26 -0
- package/dist/components/combobox/combobox.d.ts +104 -0
- package/dist/components/combobox/combobox.js +365 -0
- package/dist/components/combobox/index.d.ts +3 -0
- package/dist/components/combobox/index.js +1 -0
- package/dist/components/combobox/types.d.ts +229 -0
- package/dist/components/command/command.d.ts +55 -0
- package/dist/components/command/command.js +179 -0
- package/dist/components/command/index.d.ts +3 -0
- package/dist/components/command/index.js +1 -0
- package/dist/components/command/types.d.ts +69 -0
- package/dist/components/context-menu/context-menu.d.ts +92 -0
- package/dist/components/context-menu/context-menu.js +270 -0
- package/dist/components/context-menu/index.d.ts +3 -0
- package/dist/components/context-menu/index.js +1 -0
- package/dist/components/context-menu/types.d.ts +138 -0
- package/dist/components/data-table/data-table-features.d.ts +21 -0
- package/dist/components/data-table/data-table-features.js +22 -0
- package/dist/components/data-table/data-table.d.ts +69 -0
- package/dist/components/data-table/data-table.js +283 -0
- package/dist/components/data-table/index.d.ts +4 -0
- package/dist/components/data-table/index.js +3 -0
- package/dist/components/data-table/types.d.ts +63 -0
- package/dist/components/date-input/date-input.d.ts +7 -0
- package/dist/components/date-input/date-input.js +147 -0
- package/dist/components/date-input/index.d.ts +3 -0
- package/dist/components/date-input/index.js +1 -0
- package/dist/components/date-input/types.d.ts +27 -0
- package/dist/components/date-picker/date-picker.d.ts +7 -0
- package/dist/components/date-picker/date-picker.js +74 -0
- package/dist/components/date-picker/index.d.ts +3 -0
- package/dist/components/date-picker/index.js +1 -0
- package/dist/components/date-picker/types.d.ts +38 -0
- package/dist/components/date-range-picker/date-range-picker.d.ts +7 -0
- package/dist/components/date-range-picker/date-range-picker.js +89 -0
- package/dist/components/date-range-picker/index.d.ts +3 -0
- package/dist/components/date-range-picker/index.js +1 -0
- package/dist/components/date-range-picker/types.d.ts +43 -0
- package/dist/components/dialog/dialog.d.ts +61 -0
- package/dist/components/dialog/dialog.js +160 -0
- package/dist/components/dialog/index.d.ts +3 -0
- package/dist/components/dialog/index.js +1 -0
- package/dist/components/dialog/types.d.ts +68 -0
- package/dist/components/drawer/drawer.d.ts +69 -0
- package/dist/components/drawer/drawer.js +245 -0
- package/dist/components/drawer/index.d.ts +3 -0
- package/dist/components/drawer/index.js +1 -0
- package/dist/components/drawer/types.d.ts +93 -0
- package/dist/components/dropdown-menu/dropdown-menu.d.ts +92 -0
- package/dist/components/dropdown-menu/dropdown-menu.js +268 -0
- package/dist/components/dropdown-menu/index.d.ts +3 -0
- package/dist/components/dropdown-menu/index.js +1 -0
- package/dist/components/dropdown-menu/types.d.ts +143 -0
- package/dist/components/empty/empty.d.ts +37 -0
- package/dist/components/empty/empty.js +84 -0
- package/dist/components/empty/index.d.ts +3 -0
- package/dist/components/empty/index.js +3 -0
- package/dist/components/empty/types.d.ts +39 -0
- package/dist/components/empty/types.js +13 -0
- package/dist/components/expanded-card/expanded-card.d.ts +43 -0
- package/dist/components/expanded-card/expanded-card.js +352 -0
- package/dist/components/expanded-card/index.d.ts +3 -0
- package/dist/components/expanded-card/index.js +1 -0
- package/dist/components/expanded-card/types.d.ts +52 -0
- package/dist/components/field/field.d.ts +62 -0
- package/dist/components/field/field.js +173 -0
- package/dist/components/field/index.d.ts +3 -0
- package/dist/components/field/index.js +3 -0
- package/dist/components/field/types.d.ts +81 -0
- package/dist/components/field/types.js +21 -0
- package/dist/components/form/form.d.ts +49 -0
- package/dist/components/form/form.js +136 -0
- package/dist/components/form/index.d.ts +3 -0
- package/dist/components/form/index.js +1 -0
- package/dist/components/form/types.d.ts +59 -0
- package/dist/components/hover-card/hover-card.d.ts +19 -0
- package/dist/components/hover-card/hover-card.js +63 -0
- package/dist/components/hover-card/index.d.ts +3 -0
- package/dist/components/hover-card/index.js +1 -0
- package/dist/components/hover-card/types.d.ts +27 -0
- package/dist/components/image-gallery/image-gallery.d.ts +8 -0
- package/dist/components/image-gallery/image-gallery.js +294 -0
- package/dist/components/image-gallery/index.d.ts +4 -0
- package/dist/components/image-gallery/index.js +3 -0
- package/dist/components/image-gallery/masonry.d.ts +11 -0
- package/dist/components/image-gallery/masonry.js +62 -0
- package/dist/components/image-gallery/types.d.ts +80 -0
- package/dist/components/input/index.d.ts +3 -0
- package/dist/components/input/index.js +1 -0
- package/dist/components/input/input.d.ts +7 -0
- package/dist/components/input/input.js +18 -0
- package/dist/components/input/types.d.ts +28 -0
- package/dist/components/input-group/index.d.ts +3 -0
- package/dist/components/input-group/index.js +3 -0
- package/dist/components/input-group/input-group.d.ts +37 -0
- package/dist/components/input-group/input-group.js +103 -0
- package/dist/components/input-group/types.d.ts +64 -0
- package/dist/components/input-group/types.js +31 -0
- package/dist/components/input-otp/index.d.ts +3 -0
- package/dist/components/input-otp/index.js +1 -0
- package/dist/components/input-otp/input-otp.d.ts +25 -0
- package/dist/components/input-otp/input-otp.js +76 -0
- package/dist/components/input-otp/types.d.ts +43 -0
- package/dist/components/item/index.d.ts +3 -0
- package/dist/components/item/index.js +3 -0
- package/dist/components/item/item.d.ts +61 -0
- package/dist/components/item/item.js +149 -0
- package/dist/components/item/types.d.ts +75 -0
- package/dist/components/item/types.js +48 -0
- package/dist/components/kbd/index.d.ts +3 -0
- package/dist/components/kbd/index.js +1 -0
- package/dist/components/kbd/kbd.d.ts +13 -0
- package/dist/components/kbd/kbd.js +30 -0
- package/dist/components/kbd/types.d.ts +9 -0
- package/dist/components/label/index.d.ts +3 -0
- package/dist/components/label/index.js +1 -0
- package/dist/components/label/label.d.ts +7 -0
- package/dist/components/label/label.js +17 -0
- package/dist/components/label/types.d.ts +8 -0
- package/dist/components/loader/index.d.ts +3 -0
- package/dist/components/loader/index.js +3 -0
- package/dist/components/loader/loader.d.ts +8 -0
- package/dist/components/loader/loader.js +386 -0
- package/dist/components/loader/types.d.ts +27 -0
- package/dist/components/loader/types.js +58 -0
- package/dist/components/marker/index.d.ts +3 -0
- package/dist/components/marker/index.js +3 -0
- package/dist/components/marker/marker.d.ts +19 -0
- package/dist/components/marker/marker.js +51 -0
- package/dist/components/marker/types.d.ts +30 -0
- package/dist/components/marker/types.js +16 -0
- package/dist/components/menubar/index.d.ts +3 -0
- package/dist/components/menubar/index.js +1 -0
- package/dist/components/menubar/menubar.d.ts +98 -0
- package/dist/components/menubar/menubar.js +284 -0
- package/dist/components/menubar/types.d.ts +146 -0
- package/dist/components/message/index.d.ts +3 -0
- package/dist/components/message/index.js +1 -0
- package/dist/components/message/message.d.ts +37 -0
- package/dist/components/message/message.js +83 -0
- package/dist/components/message/types.d.ts +32 -0
- package/dist/components/message-scroller/index.d.ts +4 -0
- package/dist/components/message-scroller/index.js +3 -0
- package/dist/components/message-scroller/message-scroller-primitive.d.ts +21 -0
- package/dist/components/message-scroller/message-scroller-primitive.js +1349 -0
- package/dist/components/message-scroller/message-scroller.d.ts +39 -0
- package/dist/components/message-scroller/message-scroller.js +103 -0
- package/dist/components/message-scroller/types.d.ts +107 -0
- package/dist/components/money-input/index.d.ts +3 -0
- package/dist/components/money-input/index.js +1 -0
- package/dist/components/money-input/money-input.d.ts +7 -0
- package/dist/components/money-input/money-input.js +143 -0
- package/dist/components/money-input/types.d.ts +20 -0
- package/dist/components/morph-image/index.d.ts +3 -0
- package/dist/components/morph-image/index.js +3 -0
- package/dist/components/morph-image/morph-image.d.ts +8 -0
- package/dist/components/morph-image/morph-image.js +155 -0
- package/dist/components/morph-image/types.d.ts +38 -0
- package/dist/components/morph-image/types.js +18 -0
- package/dist/components/native-select/index.d.ts +3 -0
- package/dist/components/native-select/index.js +3 -0
- package/dist/components/native-select/native-select.d.ts +20 -0
- package/dist/components/native-select/native-select.js +57 -0
- package/dist/components/native-select/types.d.ts +52 -0
- package/dist/components/native-select/types.js +23 -0
- package/dist/components/navigation-menu/index.d.ts +3 -0
- package/dist/components/navigation-menu/index.js +3 -0
- package/dist/components/navigation-menu/navigation-menu.d.ts +50 -0
- package/dist/components/navigation-menu/navigation-menu.js +145 -0
- package/dist/components/navigation-menu/types.d.ts +79 -0
- package/dist/components/navigation-menu/types.js +15 -0
- package/dist/components/number-stepper/index.d.ts +3 -0
- package/dist/components/number-stepper/index.js +3 -0
- package/dist/components/number-stepper/number-stepper.d.ts +9 -0
- package/dist/components/number-stepper/number-stepper.js +223 -0
- package/dist/components/number-stepper/types.d.ts +47 -0
- package/dist/components/number-stepper/types.js +174 -0
- package/dist/components/pagination/index.d.ts +3 -0
- package/dist/components/pagination/index.js +1 -0
- package/dist/components/pagination/pagination.d.ts +43 -0
- package/dist/components/pagination/pagination.js +121 -0
- package/dist/components/pagination/types.d.ts +37 -0
- package/dist/components/phone-input/index.d.ts +3 -0
- package/dist/components/phone-input/index.js +1 -0
- package/dist/components/phone-input/phone-input.d.ts +7 -0
- package/dist/components/phone-input/phone-input.js +54 -0
- package/dist/components/phone-input/types.d.ts +12 -0
- package/dist/components/popover/index.d.ts +3 -0
- package/dist/components/popover/index.js +1 -0
- package/dist/components/popover/popover.d.ts +37 -0
- package/dist/components/popover/popover.js +100 -0
- package/dist/components/popover/types.d.ts +51 -0
- package/dist/components/progress/index.d.ts +3 -0
- package/dist/components/progress/index.js +1 -0
- package/dist/components/progress/progress.d.ts +32 -0
- package/dist/components/progress/progress.js +100 -0
- package/dist/components/progress/types.d.ts +31 -0
- package/dist/components/questionnaire/index.d.ts +3 -0
- package/dist/components/questionnaire/index.js +1 -0
- package/dist/components/questionnaire/questionnaire-primitive.js +1563 -0
- package/dist/components/questionnaire/questionnaire.d.ts +91 -0
- package/dist/components/questionnaire/questionnaire.js +315 -0
- package/dist/components/questionnaire/types.d.ts +203 -0
- package/dist/components/radio-group/index.d.ts +3 -0
- package/dist/components/radio-group/index.js +1 -0
- package/dist/components/radio-group/radio-group.d.ts +13 -0
- package/dist/components/radio-group/radio-group.js +44 -0
- package/dist/components/radio-group/types.d.ts +33 -0
- package/dist/components/reorder-list/index.d.ts +3 -0
- package/dist/components/reorder-list/index.js +1 -0
- package/dist/components/reorder-list/reorder-list.d.ts +19 -0
- package/dist/components/reorder-list/reorder-list.js +279 -0
- package/dist/components/reorder-list/types.d.ts +65 -0
- package/dist/components/resizable/index.d.ts +3 -0
- package/dist/components/resizable/index.js +1 -0
- package/dist/components/resizable/resizable.d.ts +19 -0
- package/dist/components/resizable/resizable.js +44 -0
- package/dist/components/resizable/types.d.ts +89 -0
- package/dist/components/scroll-area/index.d.ts +3 -0
- package/dist/components/scroll-area/index.js +1 -0
- package/dist/components/scroll-area/scroll-area.d.ts +13 -0
- package/dist/components/scroll-area/scroll-area.js +47 -0
- package/dist/components/scroll-area/types.d.ts +19 -0
- package/dist/components/select/index.d.ts +3 -0
- package/dist/components/select/index.js +1 -0
- package/dist/components/select/select.d.ts +61 -0
- package/dist/components/select/select.js +183 -0
- package/dist/components/select/types.d.ts +100 -0
- package/dist/components/separator/index.d.ts +3 -0
- package/dist/components/separator/index.js +1 -0
- package/dist/components/separator/separator.d.ts +7 -0
- package/dist/components/separator/separator.js +20 -0
- package/dist/components/separator/types.d.ts +9 -0
- package/dist/components/sheet/index.d.ts +3 -0
- package/dist/components/sheet/index.js +1 -0
- package/dist/components/sheet/sheet.d.ts +61 -0
- package/dist/components/sheet/sheet.js +155 -0
- package/dist/components/sheet/types.d.ts +69 -0
- package/dist/components/sidebar/index.d.ts +3 -0
- package/dist/components/sidebar/index.js +3 -0
- package/dist/components/sidebar/sidebar.d.ts +145 -0
- package/dist/components/sidebar/sidebar.js +550 -0
- package/dist/components/sidebar/types.d.ts +186 -0
- package/dist/components/sidebar/types.js +42 -0
- package/dist/components/sidebar/use-mobile.js +21 -0
- package/dist/components/skeleton/index.d.ts +3 -0
- package/dist/components/skeleton/index.js +1 -0
- package/dist/components/skeleton/skeleton.d.ts +8 -0
- package/dist/components/skeleton/skeleton.js +18 -0
- package/dist/components/skeleton/types.d.ts +5 -0
- package/dist/components/slider/index.d.ts +3 -0
- package/dist/components/slider/index.js +1 -0
- package/dist/components/slider/slider.d.ts +7 -0
- package/dist/components/slider/slider.js +106 -0
- package/dist/components/slider/types.d.ts +39 -0
- package/dist/components/spinner/index.d.ts +3 -0
- package/dist/components/spinner/index.js +1 -0
- package/dist/components/spinner/spinner.d.ts +7 -0
- package/dist/components/spinner/spinner.js +21 -0
- package/dist/components/spinner/types.d.ts +8 -0
- package/dist/components/switch/index.d.ts +3 -0
- package/dist/components/switch/index.js +3 -0
- package/dist/components/switch/switch.d.ts +7 -0
- package/dist/components/switch/switch.js +32 -0
- package/dist/components/switch/types.d.ts +37 -0
- package/dist/components/switch/types.js +23 -0
- package/dist/components/table/index.d.ts +3 -0
- package/dist/components/table/index.js +1 -0
- package/dist/components/table/table.d.ts +49 -0
- package/dist/components/table/table.js +112 -0
- package/dist/components/table/types.d.ts +33 -0
- package/dist/components/tabs/index.d.ts +3 -0
- package/dist/components/tabs/index.js +3 -0
- package/dist/components/tabs/tabs.d.ts +25 -0
- package/dist/components/tabs/tabs.js +81 -0
- package/dist/components/tabs/types.d.ts +61 -0
- package/dist/components/tabs/types.js +18 -0
- package/dist/components/textarea/index.d.ts +3 -0
- package/dist/components/textarea/index.js +1 -0
- package/dist/components/textarea/textarea.d.ts +7 -0
- package/dist/components/textarea/textarea.js +17 -0
- package/dist/components/textarea/types.d.ts +26 -0
- package/dist/components/toast/index.d.ts +3 -0
- package/dist/components/toast/index.js +1 -0
- package/dist/components/toast/toast.d.ts +63 -0
- package/dist/components/toast/toast.js +321 -0
- package/dist/components/toast/types.d.ts +120 -0
- package/dist/components/toggle/index.d.ts +3 -0
- package/dist/components/toggle/index.js +3 -0
- package/dist/components/toggle/toggle.d.ts +7 -0
- package/dist/components/toggle/toggle.js +32 -0
- package/dist/components/toggle/types.d.ts +35 -0
- package/dist/components/toggle/types.js +37 -0
- package/dist/components/toggle-group/index.d.ts +3 -0
- package/dist/components/toggle-group/index.js +1 -0
- package/dist/components/toggle-group/toggle-group.d.ts +13 -0
- package/dist/components/toggle-group/toggle-group.js +88 -0
- package/dist/components/toggle-group/types.d.ts +52 -0
- package/dist/components/tooltip/index.d.ts +3 -0
- package/dist/components/tooltip/index.js +1 -0
- package/dist/components/tooltip/tooltip.d.ts +25 -0
- package/dist/components/tooltip/tooltip.js +79 -0
- package/dist/components/tooltip/types.d.ts +48 -0
- package/dist/components/trace/index.d.ts +3 -0
- package/dist/components/trace/index.js +1 -0
- package/dist/components/trace/trace.d.ts +52 -0
- package/dist/components/trace/trace.js +132 -0
- package/dist/components/trace/types.d.ts +54 -0
- package/dist/components/typography/index.d.ts +3 -0
- package/dist/components/typography/index.js +3 -0
- package/dist/components/typography/types.d.ts +29 -0
- package/dist/components/typography/types.js +25 -0
- package/dist/components/typography/typography.d.ts +7 -0
- package/dist/components/typography/typography.js +40 -0
- package/dist/components/video-player/index.d.ts +6 -0
- package/dist/components/video-player/index.js +5 -0
- package/dist/components/video-player/types.d.ts +143 -0
- package/dist/components/video-player/use-video-player.js +319 -0
- package/dist/components/video-player/video-player-context.d.ts +45 -0
- package/dist/components/video-player/video-player-context.js +15 -0
- package/dist/components/video-player/video-player-controls.d.ts +38 -0
- package/dist/components/video-player/video-player-controls.js +226 -0
- package/dist/components/video-player/video-player-overlay.d.ts +13 -0
- package/dist/components/video-player/video-player-overlay.js +113 -0
- package/dist/components/video-player/video-player.d.ts +8 -0
- package/dist/components/video-player/video-player.js +139 -0
- package/dist/index.d.ts +244 -0
- package/dist/index.js +114 -0
- package/dist/lib/floating.d.ts +44 -0
- package/dist/lib/focus-source.js +51 -0
- package/dist/lib/format.d.ts +67 -0
- package/dist/lib/format.js +130 -0
- package/dist/lib/locale.d.ts +104 -0
- package/dist/lib/locale.js +103 -0
- package/dist/lib/part-props.d.ts +15 -0
- package/dist/lib/use-controllable-state.js +22 -0
- package/dist/lib/utils.d.ts +9 -0
- package/dist/lib/utils.js +16 -0
- package/dist/styles/index.css +126 -0
- package/dist/styles/theme.css +80 -0
- package/dist/styles/utilities.css +553 -0
- package/package.json +89 -3
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../../lib/utils.js";
|
|
3
|
+
import { texts } from "../../lib/locale.js";
|
|
4
|
+
import { formatDuration } from "../../lib/format.js";
|
|
5
|
+
import { Button } from "../button/button.js";
|
|
6
|
+
import { Slider as Slider$1 } from "../slider/slider.js";
|
|
7
|
+
import { useVideoPlayerContext } from "./video-player-context.js";
|
|
8
|
+
import { MaximizeIcon, MinimizeIcon, PauseIcon, PlayIcon, Volume1Icon, Volume2Icon, VolumeOffIcon } from "lucide-react";
|
|
9
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
10
|
+
import { useRef } from "react";
|
|
11
|
+
import { Slider } from "@base-ui/react/slider";
|
|
12
|
+
// src/components/video-player/video-player-controls.tsx
|
|
13
|
+
/** Полупрозрачная круглая подложка элементов управления поверх видео */
|
|
14
|
+
const PILL_CLASSES = cn("shrink-0", "rounded-full", "bg-background/60", "text-foreground", "backdrop-blur-sm", "transition-colors", "duration-300", "hover:bg-background/80", "dark:hover:bg-background/80");
|
|
15
|
+
/**
|
|
16
|
+
* Панель управления: располагается внизу плеера и скрывается через пару секунд без движения
|
|
17
|
+
* мыши во время воспроизведения. Внутрь кладут кнопки, громкость, время и перемотку
|
|
18
|
+
* @param props - пропсы панели
|
|
19
|
+
* @returns контейнер элементов управления
|
|
20
|
+
*/
|
|
21
|
+
function VideoPlayerControls({ className, ...props }) {
|
|
22
|
+
const { isPlaying, isIdle } = useVideoPlayerContext();
|
|
23
|
+
const isHidden = isPlaying && isIdle;
|
|
24
|
+
const classes = cn("absolute", "inset-x-0", "bottom-0", "flex", "items-center", "gap-2", "p-3", "transition-opacity", "duration-300", "data-hidden:pointer-events-none", "data-hidden:opacity-0", className);
|
|
25
|
+
return /* @__PURE__ */ jsx("div", {
|
|
26
|
+
"data-slot": "video-player-controls",
|
|
27
|
+
"data-hidden": isHidden || void 0,
|
|
28
|
+
className: classes,
|
|
29
|
+
...props
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Кнопка воспроизведения и паузы
|
|
34
|
+
* @param props - пропсы кнопки
|
|
35
|
+
* @returns круглая кнопка с иконкой по состоянию
|
|
36
|
+
*/
|
|
37
|
+
function VideoPlayerPlayButton({ playLabel = "Воспроизвести", pauseLabel = "Пауза", className, ...props }) {
|
|
38
|
+
const { isPlaying, togglePlay } = useVideoPlayerContext();
|
|
39
|
+
const label = isPlaying ? pauseLabel : playLabel;
|
|
40
|
+
const icon = isPlaying ? /* @__PURE__ */ jsx(PauseIcon, {}) : /* @__PURE__ */ jsx(PlayIcon, {});
|
|
41
|
+
const classes = cn(PILL_CLASSES, "active:scale-90", "active:translate-y-0", className);
|
|
42
|
+
return /* @__PURE__ */ jsx(Button, {
|
|
43
|
+
"data-slot": "video-player-play-button",
|
|
44
|
+
variant: "ghost",
|
|
45
|
+
size: "icon-lg",
|
|
46
|
+
"aria-label": label,
|
|
47
|
+
className: classes,
|
|
48
|
+
onClick: togglePlay,
|
|
49
|
+
...props,
|
|
50
|
+
children: icon
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Блок громкости: кнопка звука и ползунок, который раскрывается при наведении или фокусе
|
|
55
|
+
* @param props - пропсы блока
|
|
56
|
+
* @returns кнопка и ползунок громкости
|
|
57
|
+
*/
|
|
58
|
+
function VideoPlayerVolume({ muteLabel = "Выключить звук", unmuteLabel = "Включить звук", label = "Громкость", className, ...props }) {
|
|
59
|
+
const { volume, isMuted, toggleMute, setVolume } = useVideoPlayerContext();
|
|
60
|
+
const isSilent = isMuted || volume === 0;
|
|
61
|
+
const buttonLabel = isSilent ? unmuteLabel : muteLabel;
|
|
62
|
+
const value = isSilent ? 0 : Math.round(volume * 100);
|
|
63
|
+
const classes = cn("group/volume", "flex", "items-center", "overflow-hidden", PILL_CLASSES, className);
|
|
64
|
+
const sliderWrapperClasses = cn("w-0", "transition-[width]", "duration-150", "ease-linear", "group-hover/volume:w-24", "group-focus-within/volume:w-24");
|
|
65
|
+
let icon = /* @__PURE__ */ jsx(Volume2Icon, {});
|
|
66
|
+
if (isSilent) icon = /* @__PURE__ */ jsx(VolumeOffIcon, {});
|
|
67
|
+
else if (volume < .5) icon = /* @__PURE__ */ jsx(Volume1Icon, {});
|
|
68
|
+
/**
|
|
69
|
+
* Ползунок двигают: громкость от 0 до 100 переводится в долю
|
|
70
|
+
* @param next - значение ползунка
|
|
71
|
+
*/
|
|
72
|
+
const handleChange = (next) => setVolume((next[0] ?? 0) / 100);
|
|
73
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
74
|
+
"data-slot": "video-player-volume",
|
|
75
|
+
className: classes,
|
|
76
|
+
...props,
|
|
77
|
+
children: [/* @__PURE__ */ jsx(Button, {
|
|
78
|
+
variant: "ghost",
|
|
79
|
+
size: "icon-lg",
|
|
80
|
+
"aria-label": buttonLabel,
|
|
81
|
+
className: "shrink-0 rounded-full hover:bg-transparent dark:hover:bg-transparent",
|
|
82
|
+
onClick: toggleMute,
|
|
83
|
+
children: icon
|
|
84
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
85
|
+
className: sliderWrapperClasses,
|
|
86
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
87
|
+
className: "flex h-9 w-24 items-center pr-4 pl-0.5",
|
|
88
|
+
children: /* @__PURE__ */ jsx(Slider$1, {
|
|
89
|
+
value: [value],
|
|
90
|
+
min: 0,
|
|
91
|
+
max: 100,
|
|
92
|
+
step: 1,
|
|
93
|
+
"aria-label": label,
|
|
94
|
+
onValueChange: handleChange
|
|
95
|
+
})
|
|
96
|
+
})
|
|
97
|
+
})]
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Время: текущее и общее, «0:12 / 3:45»
|
|
102
|
+
* @param props - пропсы времени
|
|
103
|
+
* @returns текст со временем
|
|
104
|
+
*/
|
|
105
|
+
function VideoPlayerTime({ formatTime = formatDuration, className, ...props }) {
|
|
106
|
+
const { currentTime, duration } = useVideoPlayerContext();
|
|
107
|
+
const current = formatTime(currentTime);
|
|
108
|
+
const total = formatTime(duration);
|
|
109
|
+
const classes = cn("rounded-full", "px-3", "py-1.5", "text-xs", "font-medium", "whitespace-nowrap", "tabular-nums", "bg-background/60", "text-foreground", "backdrop-blur-sm", className);
|
|
110
|
+
return /* @__PURE__ */ jsx("span", {
|
|
111
|
+
"data-slot": "video-player-time",
|
|
112
|
+
className: classes,
|
|
113
|
+
...props,
|
|
114
|
+
children: `${current} / ${total}`
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Полоса перемотки: показывает прогресс и загруженную часть, перетаскивание и клавиши меняют время
|
|
119
|
+
* @param props - пропсы полосы
|
|
120
|
+
* @returns слайдер времени
|
|
121
|
+
*/
|
|
122
|
+
function VideoPlayerProgress({ label = "Перемотка", getValueLabel, className, ...props }) {
|
|
123
|
+
const { currentTime, duration, bufferedEnd, seekStep, isPlaying, play, pause, seekTo } = useVideoPlayerContext();
|
|
124
|
+
const wasPlayingRef = useRef(false);
|
|
125
|
+
const hasDuration = duration > 0;
|
|
126
|
+
const loadedPercent = hasDuration ? Math.min(100, bufferedEnd / duration * 100) : 0;
|
|
127
|
+
const step = duration > 60 ? 1 : .25;
|
|
128
|
+
const rootClasses = cn("group/progress", "min-w-6", "flex-1", className);
|
|
129
|
+
const thumbClasses = cn("block", "size-3", "rounded-full", "bg-primary", "opacity-0", "ring-ring/50", "transition-[opacity,box-shadow]", "group-hover/progress:opacity-100", "focus-visible:opacity-100", "focus-visible:ring-3", "focus-visible:outline-hidden", "after:absolute", "after:-inset-2");
|
|
130
|
+
/**
|
|
131
|
+
* Текст значения для скринридера
|
|
132
|
+
* @param _formatted - значение в виде строки (не используется)
|
|
133
|
+
* @param time - секунды
|
|
134
|
+
* @returns «0:12 из 3:45» или текст из getValueLabel
|
|
135
|
+
*/
|
|
136
|
+
const getAriaValueText = (_formatted, time) => {
|
|
137
|
+
if (getValueLabel) return getValueLabel(time, duration);
|
|
138
|
+
const current = formatDuration(time);
|
|
139
|
+
const total = formatDuration(duration);
|
|
140
|
+
return `${current} ${texts.of} ${total}`;
|
|
141
|
+
};
|
|
142
|
+
/**
|
|
143
|
+
* Полосу двигают: перемотать видео
|
|
144
|
+
* @param next - секунды
|
|
145
|
+
*/
|
|
146
|
+
const handleChange = (next) => {
|
|
147
|
+
const time = typeof next === "number" ? next : next[0] ?? 0;
|
|
148
|
+
seekTo(time);
|
|
149
|
+
};
|
|
150
|
+
/**
|
|
151
|
+
* Полосу отпустили: продолжить воспроизведение, если видео играло до нажатия
|
|
152
|
+
*/
|
|
153
|
+
const handleRelease = () => {
|
|
154
|
+
document.removeEventListener("pointerup", handleRelease);
|
|
155
|
+
document.removeEventListener("pointercancel", handleRelease);
|
|
156
|
+
if (wasPlayingRef.current) play();
|
|
157
|
+
wasPlayingRef.current = false;
|
|
158
|
+
};
|
|
159
|
+
/**
|
|
160
|
+
* Нажатие на полосу: пауза на время перемотки, иначе видео уводит бегунок из-под курсора
|
|
161
|
+
*/
|
|
162
|
+
const handlePointerDown = () => {
|
|
163
|
+
wasPlayingRef.current = isPlaying;
|
|
164
|
+
if (isPlaying) pause();
|
|
165
|
+
document.addEventListener("pointerup", handleRelease);
|
|
166
|
+
document.addEventListener("pointercancel", handleRelease);
|
|
167
|
+
};
|
|
168
|
+
return /* @__PURE__ */ jsx(Slider.Root, {
|
|
169
|
+
"data-slot": "video-player-progress",
|
|
170
|
+
value: hasDuration ? currentTime : 0,
|
|
171
|
+
min: 0,
|
|
172
|
+
max: hasDuration ? duration : 1,
|
|
173
|
+
step,
|
|
174
|
+
largeStep: seekStep,
|
|
175
|
+
disabled: !hasDuration,
|
|
176
|
+
thumbAlignment: "edge",
|
|
177
|
+
"aria-label": label,
|
|
178
|
+
className: rootClasses,
|
|
179
|
+
onValueChange: handleChange,
|
|
180
|
+
...props,
|
|
181
|
+
children: /* @__PURE__ */ jsxs(Slider.Control, {
|
|
182
|
+
"data-slot": "video-player-progress-control",
|
|
183
|
+
className: "relative flex h-6 w-full cursor-pointer touch-none items-center select-none",
|
|
184
|
+
onPointerDown: handlePointerDown,
|
|
185
|
+
children: [/* @__PURE__ */ jsxs(Slider.Track, {
|
|
186
|
+
"data-slot": "video-player-progress-track",
|
|
187
|
+
className: "relative h-1.5 w-full grow overflow-hidden rounded-full bg-background/60 backdrop-blur-sm",
|
|
188
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
189
|
+
"data-slot": "video-player-progress-buffer",
|
|
190
|
+
className: "absolute inset-y-0 left-0 bg-foreground/30",
|
|
191
|
+
style: { width: `${loadedPercent}%` }
|
|
192
|
+
}), /* @__PURE__ */ jsx(Slider.Indicator, {
|
|
193
|
+
"data-slot": "video-player-progress-range",
|
|
194
|
+
className: "absolute h-full bg-primary"
|
|
195
|
+
})]
|
|
196
|
+
}), /* @__PURE__ */ jsx(Slider.Thumb, {
|
|
197
|
+
"data-slot": "video-player-progress-thumb",
|
|
198
|
+
"aria-label": label,
|
|
199
|
+
getAriaValueText,
|
|
200
|
+
className: thumbClasses
|
|
201
|
+
})]
|
|
202
|
+
})
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Кнопка входа в полноэкранный режим и выхода из него
|
|
207
|
+
* @param props - пропсы кнопки
|
|
208
|
+
* @returns круглая кнопка с иконкой по состоянию
|
|
209
|
+
*/
|
|
210
|
+
function VideoPlayerFullscreenButton({ enterLabel = "Полный экран", exitLabel = "Выйти из полноэкранного режима", className, ...props }) {
|
|
211
|
+
const { isFullscreen, toggleFullscreen } = useVideoPlayerContext();
|
|
212
|
+
const label = isFullscreen ? exitLabel : enterLabel;
|
|
213
|
+
const icon = isFullscreen ? /* @__PURE__ */ jsx(MinimizeIcon, {}) : /* @__PURE__ */ jsx(MaximizeIcon, {});
|
|
214
|
+
const classes = cn(PILL_CLASSES, "active:scale-90", "active:translate-y-0", className);
|
|
215
|
+
return /* @__PURE__ */ jsx(Button, {
|
|
216
|
+
"data-slot": "video-player-fullscreen-button",
|
|
217
|
+
variant: "ghost",
|
|
218
|
+
size: "icon-lg",
|
|
219
|
+
"aria-label": label,
|
|
220
|
+
className: classes,
|
|
221
|
+
onClick: toggleFullscreen,
|
|
222
|
+
...props,
|
|
223
|
+
children: icon
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
export { VideoPlayerControls, VideoPlayerFullscreenButton, VideoPlayerPlayButton, VideoPlayerProgress, VideoPlayerTime, VideoPlayerVolume };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { VideoPlayerBufferingPropsT, VideoPlayerIndicatorPropsT } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Индикатор загрузки: спиннер поверх видео, пока плеер ждёт данные
|
|
4
|
+
* @param props - пропсы индикатора
|
|
5
|
+
* @returns спиннер с плавным появлением
|
|
6
|
+
*/
|
|
7
|
+
export declare function VideoPlayerBuffering({ label, className, ...props }: VideoPlayerBufferingPropsT): import("react").JSX.Element;
|
|
8
|
+
/**
|
|
9
|
+
* Индикатор действия: ненадолго показывает пуск, паузу, громкость или перемотку
|
|
10
|
+
* @param props - пропсы индикатора
|
|
11
|
+
* @returns анимированная иконка по центру или у края
|
|
12
|
+
*/
|
|
13
|
+
export declare function VideoPlayerIndicator({ getSeekLabel, className, ...props }: VideoPlayerIndicatorPropsT): import("react").JSX.Element;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../../lib/utils.js";
|
|
3
|
+
import { Spinner } from "../spinner/spinner.js";
|
|
4
|
+
import { useVideoPlayerContext } from "./video-player-context.js";
|
|
5
|
+
import { ChevronsLeftIcon, ChevronsRightIcon, PauseIcon, PlayIcon, Volume1Icon, Volume2Icon, VolumeOffIcon } from "lucide-react";
|
|
6
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
+
import { AnimatePresence, motion } from "motion/react";
|
|
8
|
+
// src/components/video-player/video-player-overlay.tsx
|
|
9
|
+
/**
|
|
10
|
+
* Индикатор загрузки: спиннер поверх видео, пока плеер ждёт данные
|
|
11
|
+
* @param props - пропсы индикатора
|
|
12
|
+
* @returns спиннер с плавным появлением
|
|
13
|
+
*/
|
|
14
|
+
function VideoPlayerBuffering({ label = "Загрузка…", className, ...props }) {
|
|
15
|
+
const { isBuffering } = useVideoPlayerContext();
|
|
16
|
+
const classes = cn("pointer-events-none", "absolute", "inset-0", className);
|
|
17
|
+
return /* @__PURE__ */ jsx("div", {
|
|
18
|
+
"data-slot": "video-player-buffering",
|
|
19
|
+
className: classes,
|
|
20
|
+
...props,
|
|
21
|
+
children: /* @__PURE__ */ jsx(AnimatePresence, { children: isBuffering && /* @__PURE__ */ jsx(motion.div, {
|
|
22
|
+
className: "flex size-full items-center justify-center bg-background/20",
|
|
23
|
+
initial: { opacity: 0 },
|
|
24
|
+
animate: { opacity: 1 },
|
|
25
|
+
exit: { opacity: 0 },
|
|
26
|
+
transition: { duration: .2 },
|
|
27
|
+
children: /* @__PURE__ */ jsx(Spinner, {
|
|
28
|
+
"aria-label": label,
|
|
29
|
+
className: "size-12 text-foreground"
|
|
30
|
+
})
|
|
31
|
+
}) })
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Подпись перемотки по умолчанию
|
|
36
|
+
* @param seconds - секунды со знаком
|
|
37
|
+
* @returns «+5 с» или «−5 с»
|
|
38
|
+
*/
|
|
39
|
+
function getDefaultSeekLabel(seconds) {
|
|
40
|
+
return `${seconds > 0 ? "+" : "−"}${Math.abs(seconds)} с`;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Иконка действия для центра плеера
|
|
44
|
+
* @param type - действие
|
|
45
|
+
* @returns иконка
|
|
46
|
+
*/
|
|
47
|
+
function getCenterIcon(type) {
|
|
48
|
+
if (type === "play") return /* @__PURE__ */ jsx(PlayIcon, {});
|
|
49
|
+
if (type === "pause") return /* @__PURE__ */ jsx(PauseIcon, {});
|
|
50
|
+
if (type === "volume-up") return /* @__PURE__ */ jsx(Volume2Icon, {});
|
|
51
|
+
if (type === "volume-down") return /* @__PURE__ */ jsx(Volume1Icon, {});
|
|
52
|
+
return /* @__PURE__ */ jsx(VolumeOffIcon, {});
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Индикатор действия: ненадолго показывает пуск, паузу, громкость или перемотку
|
|
56
|
+
* @param props - пропсы индикатора
|
|
57
|
+
* @returns анимированная иконка по центру или у края
|
|
58
|
+
*/
|
|
59
|
+
function VideoPlayerIndicator({ getSeekLabel = getDefaultSeekLabel, className, ...props }) {
|
|
60
|
+
const { indicator, seekStep } = useVideoPlayerContext();
|
|
61
|
+
const isSeek = indicator?.type === "seek-forward" || indicator?.type === "seek-backward";
|
|
62
|
+
const isForward = indicator?.type === "seek-forward";
|
|
63
|
+
const alignClasses = isForward ? "justify-end pr-6" : "justify-start pl-6";
|
|
64
|
+
const classes = cn("pointer-events-none", "absolute", "inset-0", className);
|
|
65
|
+
const seconds = isForward ? seekStep : -seekStep;
|
|
66
|
+
const pillClasses = cn("flex", "items-center", "justify-center", "gap-1", "rounded-full", "bg-background/50", "text-foreground", "backdrop-blur-sm", "[&_svg]:size-10");
|
|
67
|
+
const seekRowClasses = cn("flex", "w-full", alignClasses);
|
|
68
|
+
const seekPillClasses = cn(pillClasses, "h-14", "px-3", "text-lg", "font-medium");
|
|
69
|
+
const centerPillClasses = cn(pillClasses, "size-20");
|
|
70
|
+
let content = null;
|
|
71
|
+
if (indicator && isSeek) content = /* @__PURE__ */ jsx("div", {
|
|
72
|
+
className: seekRowClasses,
|
|
73
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
74
|
+
className: seekPillClasses,
|
|
75
|
+
children: [
|
|
76
|
+
!isForward && /* @__PURE__ */ jsx(ChevronsLeftIcon, {}),
|
|
77
|
+
getSeekLabel(seconds),
|
|
78
|
+
isForward && /* @__PURE__ */ jsx(ChevronsRightIcon, {})
|
|
79
|
+
]
|
|
80
|
+
})
|
|
81
|
+
});
|
|
82
|
+
if (indicator && !isSeek) content = /* @__PURE__ */ jsx("div", {
|
|
83
|
+
className: "flex w-full justify-center",
|
|
84
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
85
|
+
className: centerPillClasses,
|
|
86
|
+
children: getCenterIcon(indicator.type)
|
|
87
|
+
})
|
|
88
|
+
});
|
|
89
|
+
return /* @__PURE__ */ jsx("div", {
|
|
90
|
+
"data-slot": "video-player-indicator",
|
|
91
|
+
"aria-hidden": true,
|
|
92
|
+
className: classes,
|
|
93
|
+
...props,
|
|
94
|
+
children: /* @__PURE__ */ jsx(AnimatePresence, { children: indicator && /* @__PURE__ */ jsx(motion.div, {
|
|
95
|
+
className: "absolute inset-0 flex items-center",
|
|
96
|
+
initial: {
|
|
97
|
+
opacity: 0,
|
|
98
|
+
scale: .8
|
|
99
|
+
},
|
|
100
|
+
animate: {
|
|
101
|
+
opacity: 1,
|
|
102
|
+
scale: 1
|
|
103
|
+
},
|
|
104
|
+
exit: {
|
|
105
|
+
opacity: 0,
|
|
106
|
+
scale: .8
|
|
107
|
+
},
|
|
108
|
+
transition: { duration: .25 },
|
|
109
|
+
children: content
|
|
110
|
+
}, indicator.id) })
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
export { VideoPlayerBuffering, VideoPlayerIndicator };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { VideoPlayerPropsT } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Видеоплеер со своими элементами управления. Клавиши при фокусе на плеере: пробел и K — пауза,
|
|
4
|
+
* ← → — перемотка, ↑ ↓ — громкость, M — звук, F — полный экран
|
|
5
|
+
* @param props - пропсы плеера
|
|
6
|
+
* @returns плеер с видео и частями управления
|
|
7
|
+
*/
|
|
8
|
+
export declare function VideoPlayer({ src, poster, autoPlay, loop, defaultVolume, defaultMuted, seekStep, preload, crossOrigin, subtitles, label, className, videoClassName, onPlay, onPause, onEnded, onKeyDown, onPointerMove, children, ...props }: VideoPlayerPropsT): import("react").JSX.Element;
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../../lib/utils.js";
|
|
3
|
+
import { VideoPlayerContext } from "./video-player-context.js";
|
|
4
|
+
import { VideoPlayerBuffering, VideoPlayerIndicator } from "./video-player-overlay.js";
|
|
5
|
+
import { useVideoPlayer } from "./use-video-player.js";
|
|
6
|
+
import { VideoPlayerControls, VideoPlayerFullscreenButton, VideoPlayerPlayButton, VideoPlayerProgress, VideoPlayerTime, VideoPlayerVolume } from "./video-player-controls.js";
|
|
7
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
+
// src/components/video-player/video-player.tsx
|
|
9
|
+
/** Качества от лучшего к худшему: из набора ссылок берётся первое доступное */
|
|
10
|
+
const QUALITY_ORDER = [
|
|
11
|
+
"2160p",
|
|
12
|
+
"1440p",
|
|
13
|
+
"1080p",
|
|
14
|
+
"720p",
|
|
15
|
+
"480p",
|
|
16
|
+
"360p",
|
|
17
|
+
"240p"
|
|
18
|
+
];
|
|
19
|
+
/**
|
|
20
|
+
* Выбрать ссылку на видео
|
|
21
|
+
* @param source - ссылка или ссылки по качеству
|
|
22
|
+
* @returns лучшая доступная ссылка или undefined
|
|
23
|
+
*/
|
|
24
|
+
function getVideoUrl(source) {
|
|
25
|
+
if (typeof source === "string") return source;
|
|
26
|
+
const quality = QUALITY_ORDER.find((item) => source[item]);
|
|
27
|
+
if (!quality) return;
|
|
28
|
+
return source[quality];
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Стандартный набор частей: загрузка, индикатор и панель управления
|
|
32
|
+
* @returns части плеера
|
|
33
|
+
*/
|
|
34
|
+
function VideoPlayerDefaultParts() {
|
|
35
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
36
|
+
/* @__PURE__ */ jsx(VideoPlayerBuffering, {}),
|
|
37
|
+
/* @__PURE__ */ jsx(VideoPlayerIndicator, {}),
|
|
38
|
+
/* @__PURE__ */ jsxs(VideoPlayerControls, { children: [
|
|
39
|
+
/* @__PURE__ */ jsx(VideoPlayerPlayButton, {}),
|
|
40
|
+
/* @__PURE__ */ jsx(VideoPlayerVolume, {}),
|
|
41
|
+
/* @__PURE__ */ jsx(VideoPlayerTime, {}),
|
|
42
|
+
/* @__PURE__ */ jsx(VideoPlayerProgress, {}),
|
|
43
|
+
/* @__PURE__ */ jsx(VideoPlayerFullscreenButton, {})
|
|
44
|
+
] })
|
|
45
|
+
] });
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Видеоплеер со своими элементами управления. Клавиши при фокусе на плеере: пробел и K — пауза,
|
|
49
|
+
* ← → — перемотка, ↑ ↓ — громкость, M — звук, F — полный экран
|
|
50
|
+
* @param props - пропсы плеера
|
|
51
|
+
* @returns плеер с видео и частями управления
|
|
52
|
+
*/
|
|
53
|
+
function VideoPlayer({ src, poster, autoPlay = false, loop = false, defaultVolume = 1, defaultMuted = false, seekStep = 5, preload = "metadata", crossOrigin, subtitles, label = "Видеоплеер", className, videoClassName, onPlay, onPause, onEnded, onKeyDown, onPointerMove, children, ...props }) {
|
|
54
|
+
const player = useVideoPlayer({
|
|
55
|
+
autoPlay,
|
|
56
|
+
loop,
|
|
57
|
+
defaultVolume,
|
|
58
|
+
defaultMuted,
|
|
59
|
+
seekStep,
|
|
60
|
+
onPlay,
|
|
61
|
+
onPause,
|
|
62
|
+
onEnded
|
|
63
|
+
});
|
|
64
|
+
const isIdle = player.isPlaying && player.isIdle;
|
|
65
|
+
const classes = cn("group/video-player", "relative", "aspect-video", "w-full", "overflow-hidden", "rounded-lg", "bg-muted", "outline-none", "focus-visible:ring-3", "focus-visible:ring-ring/50", "data-fullscreen:rounded-none", "data-idle:cursor-none", className);
|
|
66
|
+
const videoClasses = cn("size-full", "cursor-pointer", "object-contain", videoClassName);
|
|
67
|
+
const subtitlesClasses = cn("pointer-events-none", "absolute", "inset-x-0", "bottom-16", "flex", "justify-center", "px-4", "transition-[bottom]", "duration-300", "group-data-idle/video-player:bottom-4");
|
|
68
|
+
const subtitleClasses = cn("max-w-full", "rounded-md", "bg-background/70", "px-2", "py-1", "text-center", "text-sm", "whitespace-pre-line", "text-foreground", "backdrop-blur-sm", "sm:text-base");
|
|
69
|
+
const videoUrl = getVideoUrl(src);
|
|
70
|
+
const parts = children ?? /* @__PURE__ */ jsx(VideoPlayerDefaultParts, {});
|
|
71
|
+
const tracks = subtitles?.map((track) => /* @__PURE__ */ jsx("track", {
|
|
72
|
+
kind: "subtitles",
|
|
73
|
+
src: track.src,
|
|
74
|
+
srcLang: track.lang,
|
|
75
|
+
label: track.label,
|
|
76
|
+
default: track.default
|
|
77
|
+
}, `${track.lang}-${track.src}`));
|
|
78
|
+
/**
|
|
79
|
+
* Нажатие клавиши: горячие клавиши плеера, затем пользовательский обработчик
|
|
80
|
+
* @param event - нажатие клавиши
|
|
81
|
+
*/
|
|
82
|
+
const handleKeyDown = (event) => {
|
|
83
|
+
player.handleKeyDown(event);
|
|
84
|
+
onKeyDown?.(event);
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* Движение указателя: показать панель управления
|
|
88
|
+
* @param event - движение указателя
|
|
89
|
+
*/
|
|
90
|
+
const handlePointerMove = (event) => {
|
|
91
|
+
player.wake();
|
|
92
|
+
onPointerMove?.(event);
|
|
93
|
+
};
|
|
94
|
+
return /* @__PURE__ */ jsx(VideoPlayerContext.Provider, {
|
|
95
|
+
value: player,
|
|
96
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
97
|
+
"data-slot": "video-player",
|
|
98
|
+
"data-playing": player.isPlaying || void 0,
|
|
99
|
+
"data-fullscreen": player.isFullscreen || void 0,
|
|
100
|
+
"data-idle": isIdle || void 0,
|
|
101
|
+
ref: player.containerRef,
|
|
102
|
+
role: "region",
|
|
103
|
+
"aria-label": label,
|
|
104
|
+
"aria-roledescription": "видеоплеер",
|
|
105
|
+
tabIndex: 0,
|
|
106
|
+
className: classes,
|
|
107
|
+
onKeyDown: handleKeyDown,
|
|
108
|
+
onPointerMove: handlePointerMove,
|
|
109
|
+
...props,
|
|
110
|
+
children: [
|
|
111
|
+
/* @__PURE__ */ jsx("video", {
|
|
112
|
+
"data-slot": "video-player-video",
|
|
113
|
+
ref: player.videoRef,
|
|
114
|
+
src: videoUrl,
|
|
115
|
+
poster,
|
|
116
|
+
preload,
|
|
117
|
+
crossOrigin,
|
|
118
|
+
playsInline: true,
|
|
119
|
+
controls: false,
|
|
120
|
+
className: videoClasses,
|
|
121
|
+
onClick: player.togglePlay,
|
|
122
|
+
...player.videoHandlers,
|
|
123
|
+
children: tracks
|
|
124
|
+
}),
|
|
125
|
+
player.subtitleText && /* @__PURE__ */ jsx("div", {
|
|
126
|
+
"data-slot": "video-player-subtitles",
|
|
127
|
+
"aria-hidden": true,
|
|
128
|
+
className: subtitlesClasses,
|
|
129
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
130
|
+
className: subtitleClasses,
|
|
131
|
+
children: player.subtitleText
|
|
132
|
+
})
|
|
133
|
+
}),
|
|
134
|
+
parts
|
|
135
|
+
]
|
|
136
|
+
})
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
export { VideoPlayer };
|