@archytechtor/ui 0.0.0-stage → 0.2.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/bottom-nav/bottom-nav.d.ts +19 -0
- package/dist/components/bottom-nav/bottom-nav.js +59 -0
- package/dist/components/bottom-nav/index.d.ts +3 -0
- package/dist/components/bottom-nav/index.js +3 -0
- package/dist/components/bottom-nav/types.d.ts +45 -0
- package/dist/components/bottom-nav/types.js +44 -0
- package/dist/components/box/box.d.ts +7 -0
- package/dist/components/box/box.js +26 -0
- package/dist/components/box/index.d.ts +3 -0
- package/dist/components/box/index.js +3 -0
- package/dist/components/box/types.d.ts +23 -0
- package/dist/components/box/types.js +27 -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/grid/grid.d.ts +7 -0
- package/dist/components/grid/grid.js +36 -0
- package/dist/components/grid/index.d.ts +3 -0
- package/dist/components/grid/index.js +3 -0
- package/dist/components/grid/types.d.ts +35 -0
- package/dist/components/grid/types.js +102 -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/stack/index.d.ts +3 -0
- package/dist/components/stack/index.js +3 -0
- package/dist/components/stack/stack.d.ts +7 -0
- package/dist/components/stack/stack.js +29 -0
- package/dist/components/stack/types.d.ts +56 -0
- package/dist/components/stack/types.js +62 -0
- package/dist/components/statistics/index.d.ts +3 -0
- package/dist/components/statistics/index.js +3 -0
- package/dist/components/statistics/statistics.d.ts +31 -0
- package/dist/components/statistics/statistics.js +141 -0
- package/dist/components/statistics/types.d.ts +84 -0
- package/dist/components/statistics/types.js +27 -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 +259 -0
- package/dist/index.js +124 -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 +128 -0
- package/dist/styles/theme.css +84 -0
- package/dist/styles/utilities.css +553 -0
- package/package.json +89 -3
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { cn } from "../../lib/utils.js";
|
|
2
|
+
import { typographyVariants } from "./types.js";
|
|
3
|
+
import { mergeProps } from "@base-ui/react/merge-props";
|
|
4
|
+
import { createElement } from "react";
|
|
5
|
+
import { useRender } from "@base-ui/react/use-render";
|
|
6
|
+
// src/components/typography/typography.tsx
|
|
7
|
+
/** Элемент по умолчанию для каждого стиля */
|
|
8
|
+
const typographyTags = {
|
|
9
|
+
h1: "h1",
|
|
10
|
+
h2: "h2",
|
|
11
|
+
h3: "h3",
|
|
12
|
+
h4: "h4",
|
|
13
|
+
p: "p",
|
|
14
|
+
blockquote: "blockquote",
|
|
15
|
+
list: "ul",
|
|
16
|
+
code: "code",
|
|
17
|
+
lead: "p",
|
|
18
|
+
large: "div",
|
|
19
|
+
small: "small",
|
|
20
|
+
muted: "p",
|
|
21
|
+
link: "a"
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Текст в одном из стилей типографики: заголовок, абзац, цитата, список, код
|
|
25
|
+
* @param props - пропсы текста
|
|
26
|
+
* @returns элемент стиля или дочерний элемент в этом стиле (render)
|
|
27
|
+
*/
|
|
28
|
+
function Typography({ className, variant = "p", render, ...props }) {
|
|
29
|
+
const classes = cn(typographyVariants({ variant }), className);
|
|
30
|
+
const element = render ?? createElement(typographyTags[variant]);
|
|
31
|
+
return useRender({
|
|
32
|
+
render: element,
|
|
33
|
+
props: mergeProps({
|
|
34
|
+
"data-slot": "typography",
|
|
35
|
+
"data-variant": variant,
|
|
36
|
+
className: classes
|
|
37
|
+
}, props)
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
export { Typography };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { VideoPlayerBufferingPropsT, VideoPlayerControlsPropsT, VideoPlayerFullscreenButtonPropsT, VideoPlayerIndicatorPropsT, VideoPlayerPlayButtonPropsT, VideoPlayerProgressPropsT, VideoPlayerPropsT, VideoPlayerTimePropsT, VideoPlayerVolumePropsT, VideoQualityT, VideoSourceT, VideoSubtitleI } from "./types.js";
|
|
2
|
+
import { VideoPlayer } from "./video-player.js";
|
|
3
|
+
import { VideoPlayerControls, VideoPlayerFullscreenButton, VideoPlayerPlayButton, VideoPlayerProgress, VideoPlayerTime, VideoPlayerVolume } from "./video-player-controls.js";
|
|
4
|
+
import { VideoPlayerBuffering, VideoPlayerIndicator } from "./video-player-overlay.js";
|
|
5
|
+
import { useVideoPlayerContext } from "./video-player-context.js";
|
|
6
|
+
export { VideoPlayer, VideoPlayerBuffering, type VideoPlayerBufferingPropsT, VideoPlayerControls, type VideoPlayerControlsPropsT, VideoPlayerFullscreenButton, type VideoPlayerFullscreenButtonPropsT, VideoPlayerIndicator, type VideoPlayerIndicatorPropsT, VideoPlayerPlayButton, type VideoPlayerPlayButtonPropsT, VideoPlayerProgress, type VideoPlayerProgressPropsT, type VideoPlayerPropsT, VideoPlayerTime, type VideoPlayerTimePropsT, VideoPlayerVolume, type VideoPlayerVolumePropsT, type VideoQualityT, type VideoSourceT, type VideoSubtitleI, useVideoPlayerContext };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { useVideoPlayerContext } from "./video-player-context.js";
|
|
2
|
+
import { VideoPlayerBuffering, VideoPlayerIndicator } from "./video-player-overlay.js";
|
|
3
|
+
import { VideoPlayerControls, VideoPlayerFullscreenButton, VideoPlayerPlayButton, VideoPlayerProgress, VideoPlayerTime, VideoPlayerVolume } from "./video-player-controls.js";
|
|
4
|
+
import { VideoPlayer } from "./video-player.js";
|
|
5
|
+
export { VideoPlayer, VideoPlayerBuffering, VideoPlayerControls, VideoPlayerFullscreenButton, VideoPlayerIndicator, VideoPlayerPlayButton, VideoPlayerProgress, VideoPlayerTime, VideoPlayerVolume, useVideoPlayerContext };
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { PartPropsT } from "../../lib/part-props.js";
|
|
2
|
+
import { ButtonPropsT } from "../button/types.js";
|
|
3
|
+
import "../button/index.js";
|
|
4
|
+
import { ComponentProps, ReactNode } from "react";
|
|
5
|
+
import { Slider } from "@base-ui/react/slider";
|
|
6
|
+
/**
|
|
7
|
+
* Качество видео
|
|
8
|
+
*/
|
|
9
|
+
export type VideoQualityT = '2160p' | '1440p' | '1080p' | '720p' | '480p' | '360p' | '240p';
|
|
10
|
+
/**
|
|
11
|
+
* Источник видео: одна ссылка или ссылки по качеству
|
|
12
|
+
*/
|
|
13
|
+
export type VideoSourceT = string | Partial<Record<VideoQualityT, string>>;
|
|
14
|
+
/**
|
|
15
|
+
* Дорожка субтитров
|
|
16
|
+
* @property src - ссылка на файл WebVTT
|
|
17
|
+
* @property lang - код языка: ru, en
|
|
18
|
+
* @property label - название в меню субтитров браузера
|
|
19
|
+
* @property default - включить дорожку по умолчанию
|
|
20
|
+
*/
|
|
21
|
+
export interface VideoSubtitleI {
|
|
22
|
+
src: string;
|
|
23
|
+
lang: string;
|
|
24
|
+
label: string;
|
|
25
|
+
default?: boolean;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Пропсы видеоплеера
|
|
29
|
+
*/
|
|
30
|
+
export type VideoPlayerPropsT = Omit<ComponentProps<'div'>, 'onPlay' | 'onPause' | 'onEnded'> & {
|
|
31
|
+
/** Источник видео: ссылка или ссылки по качеству ({ '1080p': '…', '720p': '…' }); берётся лучшее доступное */
|
|
32
|
+
src: VideoSourceT;
|
|
33
|
+
/** Постер: картинка, пока видео не запущено */
|
|
34
|
+
poster?: string;
|
|
35
|
+
/** Начать воспроизведение сразу. Браузеры разрешают это только без звука */
|
|
36
|
+
autoPlay?: boolean;
|
|
37
|
+
/** Повторять видео после окончания */
|
|
38
|
+
loop?: boolean;
|
|
39
|
+
/** Начальная громкость от 0 до 1 */
|
|
40
|
+
defaultVolume?: number;
|
|
41
|
+
/** Начать без звука */
|
|
42
|
+
defaultMuted?: boolean;
|
|
43
|
+
/** Шаг перемотки стрелками, секунд */
|
|
44
|
+
seekStep?: number;
|
|
45
|
+
/** Что загружать заранее: ничего, метаданные или всё видео */
|
|
46
|
+
preload?: 'none' | 'metadata' | 'auto';
|
|
47
|
+
/** Откуда разрешена загрузка видео с другого домена: anonymous — без cookie, use-credentials — с ними */
|
|
48
|
+
crossOrigin?: 'anonymous' | 'use-credentials';
|
|
49
|
+
/** Дорожки субтитров */
|
|
50
|
+
subtitles?: VideoSubtitleI[];
|
|
51
|
+
/** Подпись плеера для скринридера, по умолчанию «Видеоплеер» */
|
|
52
|
+
label?: string;
|
|
53
|
+
/** Классы элемента video */
|
|
54
|
+
videoClassName?: string;
|
|
55
|
+
/** Воспроизведение началось */
|
|
56
|
+
onPlay?: () => void;
|
|
57
|
+
/** Воспроизведение остановлено */
|
|
58
|
+
onPause?: () => void;
|
|
59
|
+
/** Видео закончилось */
|
|
60
|
+
onEnded?: () => void;
|
|
61
|
+
/** Части плеера: VideoPlayerControls, VideoPlayerIndicator и другие. Без них — стандартный набор */
|
|
62
|
+
children?: ReactNode;
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Действие, о котором сообщает индикатор по центру плеера
|
|
66
|
+
*/
|
|
67
|
+
export type VideoIndicatorT = 'play' | 'pause' | 'volume-up' | 'volume-down' | 'volume-muted' | 'seek-forward' | 'seek-backward';
|
|
68
|
+
/**
|
|
69
|
+
* Показанный индикатор: id меняется при каждом показе, чтобы анимация запускалась заново
|
|
70
|
+
* @property type - действие
|
|
71
|
+
* @property id - номер показа
|
|
72
|
+
*/
|
|
73
|
+
export interface VideoIndicatorStateI {
|
|
74
|
+
type: VideoIndicatorT;
|
|
75
|
+
id: number;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Пропсы кнопок плеера: у них фиксированы оформление, размер и содержимое, нет удержания и загрузки
|
|
79
|
+
*/
|
|
80
|
+
export type ButtonBasePropsT = Omit<ButtonPropsT, 'children' | 'onClick' | 'size' | 'variant' | 'ref' | 'loading' | 'loadingLabel' | 'holdToConfirm' | 'holdDuration' | 'holdResetDelay' | 'onConfirm' | 'onHoldCancel' | 'confirmedContent' | 'holdLabel'>;
|
|
81
|
+
/**
|
|
82
|
+
* Пропсы панели управления
|
|
83
|
+
*/
|
|
84
|
+
export type VideoPlayerControlsPropsT = ComponentProps<'div'>;
|
|
85
|
+
/**
|
|
86
|
+
* Пропсы кнопки воспроизведения
|
|
87
|
+
*/
|
|
88
|
+
export type VideoPlayerPlayButtonPropsT = ButtonBasePropsT & {
|
|
89
|
+
/** Подпись, пока видео стоит, по умолчанию «Воспроизвести» */
|
|
90
|
+
playLabel?: string;
|
|
91
|
+
/** Подпись во время воспроизведения, по умолчанию «Пауза» */
|
|
92
|
+
pauseLabel?: string;
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* Пропсы блока громкости
|
|
96
|
+
*/
|
|
97
|
+
export type VideoPlayerVolumePropsT = Omit<ComponentProps<'div'>, 'children'> & {
|
|
98
|
+
/** Подпись кнопки, когда звук включён, по умолчанию «Выключить звук» */
|
|
99
|
+
muteLabel?: string;
|
|
100
|
+
/** Подпись кнопки, когда звук выключен, по умолчанию «Включить звук» */
|
|
101
|
+
unmuteLabel?: string;
|
|
102
|
+
/** Подпись ползунка громкости, по умолчанию «Громкость» */
|
|
103
|
+
label?: string;
|
|
104
|
+
};
|
|
105
|
+
/**
|
|
106
|
+
* Пропсы времени
|
|
107
|
+
*/
|
|
108
|
+
export type VideoPlayerTimePropsT = Omit<ComponentProps<'span'>, 'children'> & {
|
|
109
|
+
/** Как записать время; по умолчанию «3:05» или «1:03:05» */
|
|
110
|
+
formatTime?: (seconds: number) => string;
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* Пропсы полосы перемотки
|
|
114
|
+
*/
|
|
115
|
+
export type VideoPlayerProgressPropsT = PartPropsT<Omit<Slider.Root.Props, 'value' | 'defaultValue' | 'onValueChange' | 'onValueCommitted' | 'min' | 'max' | 'step' | 'largeStep' | 'orientation' | 'children' | 'aria-label' | 'disabled' | 'format' | 'locale'>> & {
|
|
116
|
+
/** Подпись полосы для скринридера, по умолчанию «Перемотка» */
|
|
117
|
+
label?: string;
|
|
118
|
+
/** Текст значения для скринридера; по умолчанию «0:12 из 3:45» */
|
|
119
|
+
getValueLabel?: (time: number, duration: number) => string;
|
|
120
|
+
};
|
|
121
|
+
/**
|
|
122
|
+
* Пропсы кнопки полного экрана
|
|
123
|
+
*/
|
|
124
|
+
export type VideoPlayerFullscreenButtonPropsT = ButtonBasePropsT & {
|
|
125
|
+
/** Подпись, пока плеер в обычном режиме, по умолчанию «Полный экран» */
|
|
126
|
+
enterLabel?: string;
|
|
127
|
+
/** Подпись в полноэкранном режиме, по умолчанию «Выйти из полноэкранного режима» */
|
|
128
|
+
exitLabel?: string;
|
|
129
|
+
};
|
|
130
|
+
/**
|
|
131
|
+
* Пропсы индикатора загрузки
|
|
132
|
+
*/
|
|
133
|
+
export type VideoPlayerBufferingPropsT = Omit<ComponentProps<'div'>, 'children'> & {
|
|
134
|
+
/** Подпись для скринридера, по умолчанию «Загрузка…» */
|
|
135
|
+
label?: string;
|
|
136
|
+
};
|
|
137
|
+
/**
|
|
138
|
+
* Пропсы индикатора действия
|
|
139
|
+
*/
|
|
140
|
+
export type VideoPlayerIndicatorPropsT = Omit<ComponentProps<'div'>, 'children'> & {
|
|
141
|
+
/** Подпись перемотки по числу секунд, по умолчанию «+5 с» / «−5 с» */
|
|
142
|
+
getSeekLabel?: (seconds: number) => string;
|
|
143
|
+
};
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
3
|
+
// src/components/video-player/use-video-player.ts
|
|
4
|
+
/** Через сколько мс без движения мыши панель управления скрывается во время воспроизведения */
|
|
5
|
+
const IDLE_DELAY = 2500;
|
|
6
|
+
/** Сколько мс показывается индикатор действия */
|
|
7
|
+
const INDICATOR_DELAY = 800;
|
|
8
|
+
/** Шаг громкости с клавиатуры */
|
|
9
|
+
const VOLUME_STEP = .1;
|
|
10
|
+
/**
|
|
11
|
+
* Ограничить число диапазоном
|
|
12
|
+
* @param value - число
|
|
13
|
+
* @param min - нижняя граница
|
|
14
|
+
* @param max - верхняя граница
|
|
15
|
+
* @returns число в диапазоне
|
|
16
|
+
*/
|
|
17
|
+
function clamp(value, min, max) {
|
|
18
|
+
return Math.min(max, Math.max(min, value));
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Состояние и действия плеера. Единственный источник правды — элемент video:
|
|
22
|
+
* состояние читается из его событий, действия вызывают его методы
|
|
23
|
+
* @param options - настройки плеера
|
|
24
|
+
* @returns состояние, действия, ref'ы и обработчики событий для video
|
|
25
|
+
*/
|
|
26
|
+
function useVideoPlayer(options) {
|
|
27
|
+
const { autoPlay, loop, defaultVolume, defaultMuted, seekStep, onPlay, onPause, onEnded } = options;
|
|
28
|
+
const videoRef = useRef(null);
|
|
29
|
+
const containerRef = useRef(null);
|
|
30
|
+
const indicatorTimer = useRef(void 0);
|
|
31
|
+
const idleTimer = useRef(void 0);
|
|
32
|
+
const indicatorCount = useRef(0);
|
|
33
|
+
const [isPlaying, setIsPlaying] = useState(false);
|
|
34
|
+
const [isBuffering, setIsBuffering] = useState(false);
|
|
35
|
+
const [isIdle, setIsIdle] = useState(false);
|
|
36
|
+
const [isFullscreen, setIsFullscreen] = useState(false);
|
|
37
|
+
const [currentTime, setCurrentTime] = useState(0);
|
|
38
|
+
const [duration, setDuration] = useState(0);
|
|
39
|
+
const [bufferedEnd, setBufferedEnd] = useState(0);
|
|
40
|
+
const [volume, setVolumeState] = useState(defaultVolume);
|
|
41
|
+
const [isMuted, setIsMuted] = useState(defaultMuted);
|
|
42
|
+
const [indicator, setIndicator] = useState(null);
|
|
43
|
+
const [subtitleText, setSubtitleText] = useState("");
|
|
44
|
+
/**
|
|
45
|
+
* Показать индикатор действия и скрыть через INDICATOR_DELAY
|
|
46
|
+
* @param type - действие
|
|
47
|
+
*/
|
|
48
|
+
const showIndicator = useCallback((type) => {
|
|
49
|
+
indicatorCount.current += 1;
|
|
50
|
+
setIndicator({
|
|
51
|
+
type,
|
|
52
|
+
id: indicatorCount.current
|
|
53
|
+
});
|
|
54
|
+
clearTimeout(indicatorTimer.current);
|
|
55
|
+
indicatorTimer.current = setTimeout(() => setIndicator(null), INDICATOR_DELAY);
|
|
56
|
+
}, []);
|
|
57
|
+
/**
|
|
58
|
+
* Пользователь активен: показать панель и запустить отсчёт до скрытия
|
|
59
|
+
*/
|
|
60
|
+
const wake = useCallback(() => {
|
|
61
|
+
setIsIdle(false);
|
|
62
|
+
clearTimeout(idleTimer.current);
|
|
63
|
+
idleTimer.current = setTimeout(() => setIsIdle(true), IDLE_DELAY);
|
|
64
|
+
}, []);
|
|
65
|
+
/**
|
|
66
|
+
* Начать воспроизведение
|
|
67
|
+
*/
|
|
68
|
+
const play = useCallback(() => {
|
|
69
|
+
videoRef.current?.play().catch(() => void 0);
|
|
70
|
+
}, []);
|
|
71
|
+
/**
|
|
72
|
+
* Поставить на паузу
|
|
73
|
+
*/
|
|
74
|
+
const pause = useCallback(() => {
|
|
75
|
+
videoRef.current?.pause();
|
|
76
|
+
}, []);
|
|
77
|
+
/**
|
|
78
|
+
* Переключить воспроизведение и показать индикатор
|
|
79
|
+
*/
|
|
80
|
+
const togglePlay = useCallback(() => {
|
|
81
|
+
const video = videoRef.current;
|
|
82
|
+
if (!video) return;
|
|
83
|
+
if (video.paused) {
|
|
84
|
+
showIndicator("play");
|
|
85
|
+
play();
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
showIndicator("pause");
|
|
89
|
+
pause();
|
|
90
|
+
}, [
|
|
91
|
+
pause,
|
|
92
|
+
play,
|
|
93
|
+
showIndicator
|
|
94
|
+
]);
|
|
95
|
+
/**
|
|
96
|
+
* Перемотать на время
|
|
97
|
+
* @param time - секунды от начала
|
|
98
|
+
*/
|
|
99
|
+
const seekTo = useCallback((time) => {
|
|
100
|
+
const video = videoRef.current;
|
|
101
|
+
if (!video || !Number.isFinite(video.duration)) return;
|
|
102
|
+
const next = clamp(time, 0, video.duration);
|
|
103
|
+
video.currentTime = next;
|
|
104
|
+
setCurrentTime(next);
|
|
105
|
+
}, []);
|
|
106
|
+
/**
|
|
107
|
+
* Перемотать относительно текущего места и показать индикатор
|
|
108
|
+
* @param delta - секунды, отрицательные — назад
|
|
109
|
+
*/
|
|
110
|
+
const seekBy = useCallback((delta) => {
|
|
111
|
+
const video = videoRef.current;
|
|
112
|
+
if (!video) return;
|
|
113
|
+
showIndicator(delta > 0 ? "seek-forward" : "seek-backward");
|
|
114
|
+
seekTo(video.currentTime + delta);
|
|
115
|
+
}, [seekTo, showIndicator]);
|
|
116
|
+
/**
|
|
117
|
+
* Задать громкость; нулевая выключает звук
|
|
118
|
+
* @param next - громкость от 0 до 1
|
|
119
|
+
* @param shouldShow - показать индикатор
|
|
120
|
+
*/
|
|
121
|
+
const setVolume = useCallback((next, shouldShow = false) => {
|
|
122
|
+
const video = videoRef.current;
|
|
123
|
+
if (!video) return;
|
|
124
|
+
const value = clamp(next, 0, 1);
|
|
125
|
+
if (shouldShow) {
|
|
126
|
+
const direction = value > video.volume ? "volume-up" : "volume-down";
|
|
127
|
+
showIndicator(value === 0 ? "volume-muted" : direction);
|
|
128
|
+
}
|
|
129
|
+
video.volume = value;
|
|
130
|
+
video.muted = value === 0;
|
|
131
|
+
}, [showIndicator]);
|
|
132
|
+
/**
|
|
133
|
+
* Включить или выключить звук; при включении на нулевой громкости вернуть половину
|
|
134
|
+
*/
|
|
135
|
+
const toggleMute = useCallback(() => {
|
|
136
|
+
const video = videoRef.current;
|
|
137
|
+
if (!video) return;
|
|
138
|
+
if (video.muted || video.volume === 0) {
|
|
139
|
+
video.muted = false;
|
|
140
|
+
if (video.volume === 0) video.volume = .5;
|
|
141
|
+
showIndicator("volume-up");
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
video.muted = true;
|
|
145
|
+
showIndicator("volume-muted");
|
|
146
|
+
}, [showIndicator]);
|
|
147
|
+
/**
|
|
148
|
+
* Войти в полноэкранный режим или выйти из него
|
|
149
|
+
*/
|
|
150
|
+
const toggleFullscreen = useCallback(() => {
|
|
151
|
+
const container = containerRef.current;
|
|
152
|
+
if (!container) return;
|
|
153
|
+
if (document.fullscreenElement) {
|
|
154
|
+
document.exitFullscreen().catch(() => void 0);
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
container.requestFullscreen().catch(() => void 0);
|
|
158
|
+
}, []);
|
|
159
|
+
/**
|
|
160
|
+
* Горячие клавиши на плеере: пробел и K — пауза, стрелки — перемотка и громкость,
|
|
161
|
+
* M — звук, F — полный экран. Клавиши сфокусированных кнопок и ползунков не перехватываются
|
|
162
|
+
* @param event - нажатие клавиши
|
|
163
|
+
*/
|
|
164
|
+
const handleKeyDown = useCallback((event) => {
|
|
165
|
+
wake();
|
|
166
|
+
const video = videoRef.current;
|
|
167
|
+
const hasModifier = event.altKey || event.ctrlKey || event.metaKey;
|
|
168
|
+
if (!video || event.target !== event.currentTarget || hasModifier) return;
|
|
169
|
+
const action = {
|
|
170
|
+
" ": togglePlay,
|
|
171
|
+
k: togglePlay,
|
|
172
|
+
ArrowRight: () => seekBy(seekStep),
|
|
173
|
+
ArrowLeft: () => seekBy(-seekStep),
|
|
174
|
+
ArrowUp: () => setVolume(video.volume + VOLUME_STEP, true),
|
|
175
|
+
ArrowDown: () => setVolume(video.volume - VOLUME_STEP, true),
|
|
176
|
+
m: toggleMute,
|
|
177
|
+
f: toggleFullscreen
|
|
178
|
+
}[event.key.length === 1 ? event.key.toLowerCase() : event.key];
|
|
179
|
+
if (!action) return;
|
|
180
|
+
event.preventDefault();
|
|
181
|
+
action();
|
|
182
|
+
}, [
|
|
183
|
+
seekBy,
|
|
184
|
+
seekStep,
|
|
185
|
+
setVolume,
|
|
186
|
+
toggleFullscreen,
|
|
187
|
+
toggleMute,
|
|
188
|
+
togglePlay,
|
|
189
|
+
wake
|
|
190
|
+
]);
|
|
191
|
+
/**
|
|
192
|
+
* Прочитать время, длительность и буфер из video
|
|
193
|
+
* @param video - элемент video
|
|
194
|
+
*/
|
|
195
|
+
const readTime = useCallback((video) => {
|
|
196
|
+
const ranges = video.buffered;
|
|
197
|
+
let end = 0;
|
|
198
|
+
for (let index = 0; index < ranges.length; index++) if (ranges.start(index) <= video.currentTime) end = Math.max(end, ranges.end(index));
|
|
199
|
+
setCurrentTime(video.currentTime);
|
|
200
|
+
setBufferedEnd(end);
|
|
201
|
+
if (Number.isFinite(video.duration)) setDuration(video.duration);
|
|
202
|
+
}, []);
|
|
203
|
+
/**
|
|
204
|
+
* Обработчики событий video: единственное место, где состояние плеера читается из элемента
|
|
205
|
+
*/
|
|
206
|
+
const videoHandlers = {
|
|
207
|
+
onPlay: () => {
|
|
208
|
+
setIsPlaying(true);
|
|
209
|
+
onPlay?.();
|
|
210
|
+
},
|
|
211
|
+
onPause: () => {
|
|
212
|
+
setIsPlaying(false);
|
|
213
|
+
onPause?.();
|
|
214
|
+
},
|
|
215
|
+
onEnded: () => {
|
|
216
|
+
setIsPlaying(false);
|
|
217
|
+
onEnded?.();
|
|
218
|
+
},
|
|
219
|
+
onTimeUpdate: (event) => readTime(event.currentTarget),
|
|
220
|
+
onProgress: (event) => readTime(event.currentTarget),
|
|
221
|
+
onLoadedMetadata: (event) => readTime(event.currentTarget),
|
|
222
|
+
onDurationChange: (event) => readTime(event.currentTarget),
|
|
223
|
+
onVolumeChange: (event) => {
|
|
224
|
+
setVolumeState(event.currentTarget.volume);
|
|
225
|
+
setIsMuted(event.currentTarget.muted);
|
|
226
|
+
},
|
|
227
|
+
onWaiting: () => setIsBuffering(true),
|
|
228
|
+
onPlaying: () => setIsBuffering(false),
|
|
229
|
+
onCanPlay: () => setIsBuffering(false),
|
|
230
|
+
onSeeked: () => setIsBuffering(false)
|
|
231
|
+
};
|
|
232
|
+
useEffect(() => {
|
|
233
|
+
const video = videoRef.current;
|
|
234
|
+
if (!video) return;
|
|
235
|
+
video.volume = defaultVolume;
|
|
236
|
+
video.muted = defaultMuted;
|
|
237
|
+
video.loop = loop;
|
|
238
|
+
setIsPlaying(!video.paused);
|
|
239
|
+
if (video.readyState > 0) readTime(video);
|
|
240
|
+
}, []);
|
|
241
|
+
useEffect(() => {
|
|
242
|
+
if (videoRef.current) videoRef.current.loop = loop;
|
|
243
|
+
}, [loop]);
|
|
244
|
+
useEffect(() => {
|
|
245
|
+
if (autoPlay) play();
|
|
246
|
+
}, [autoPlay, play]);
|
|
247
|
+
useEffect(() => {
|
|
248
|
+
const textTracks = videoRef.current?.textTracks;
|
|
249
|
+
if (!textTracks) return;
|
|
250
|
+
const shownTracks = /* @__PURE__ */ new Set();
|
|
251
|
+
/** Собрать текст активных реплик всех включённых дорожек */
|
|
252
|
+
const readCues = () => {
|
|
253
|
+
const lines = [];
|
|
254
|
+
for (const track of shownTracks) for (const cue of track.activeCues ?? []) if (cue instanceof VTTCue) lines.push(cue.getCueAsHTML().textContent ?? "");
|
|
255
|
+
setSubtitleText(lines.join("\n"));
|
|
256
|
+
};
|
|
257
|
+
/** Включённые дорожки субтитров — в скрытый режим и в показ, выключенные — убрать из показа */
|
|
258
|
+
const syncTracks = () => {
|
|
259
|
+
for (const track of textTracks) {
|
|
260
|
+
if (!(track.kind === "subtitles" || track.kind === "captions")) continue;
|
|
261
|
+
if (track.mode === "showing") track.mode = "hidden";
|
|
262
|
+
if (track.mode === "hidden" && !shownTracks.has(track)) {
|
|
263
|
+
shownTracks.add(track);
|
|
264
|
+
track.addEventListener("cuechange", readCues);
|
|
265
|
+
}
|
|
266
|
+
if (track.mode === "disabled" && shownTracks.has(track)) {
|
|
267
|
+
shownTracks.delete(track);
|
|
268
|
+
track.removeEventListener("cuechange", readCues);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
readCues();
|
|
272
|
+
};
|
|
273
|
+
syncTracks();
|
|
274
|
+
textTracks.addEventListener("change", syncTracks);
|
|
275
|
+
textTracks.addEventListener("addtrack", syncTracks);
|
|
276
|
+
return () => {
|
|
277
|
+
textTracks.removeEventListener("change", syncTracks);
|
|
278
|
+
textTracks.removeEventListener("addtrack", syncTracks);
|
|
279
|
+
for (const track of shownTracks) track.removeEventListener("cuechange", readCues);
|
|
280
|
+
};
|
|
281
|
+
}, []);
|
|
282
|
+
useEffect(() => {
|
|
283
|
+
const handleChange = () => setIsFullscreen(document.fullscreenElement === containerRef.current);
|
|
284
|
+
document.addEventListener("fullscreenchange", handleChange);
|
|
285
|
+
return () => document.removeEventListener("fullscreenchange", handleChange);
|
|
286
|
+
}, []);
|
|
287
|
+
useEffect(() => () => {
|
|
288
|
+
clearTimeout(indicatorTimer.current);
|
|
289
|
+
clearTimeout(idleTimer.current);
|
|
290
|
+
}, []);
|
|
291
|
+
return {
|
|
292
|
+
videoRef,
|
|
293
|
+
containerRef,
|
|
294
|
+
isPlaying,
|
|
295
|
+
isBuffering,
|
|
296
|
+
isIdle,
|
|
297
|
+
isFullscreen,
|
|
298
|
+
currentTime,
|
|
299
|
+
duration,
|
|
300
|
+
bufferedEnd,
|
|
301
|
+
volume,
|
|
302
|
+
isMuted,
|
|
303
|
+
indicator,
|
|
304
|
+
subtitleText,
|
|
305
|
+
seekStep,
|
|
306
|
+
play,
|
|
307
|
+
pause,
|
|
308
|
+
togglePlay,
|
|
309
|
+
seekTo,
|
|
310
|
+
seekBy,
|
|
311
|
+
setVolume,
|
|
312
|
+
toggleMute,
|
|
313
|
+
toggleFullscreen,
|
|
314
|
+
wake,
|
|
315
|
+
handleKeyDown,
|
|
316
|
+
videoHandlers
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
export { useVideoPlayer };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { VideoIndicatorStateI } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Состояние и действия ближайшего VideoPlayer: для своих частей управления
|
|
4
|
+
* @returns состояние плеера и методы управления
|
|
5
|
+
*/
|
|
6
|
+
export declare function useVideoPlayerContext(): {
|
|
7
|
+
videoRef: import("react").RefObject<HTMLVideoElement | null>;
|
|
8
|
+
containerRef: import("react").RefObject<HTMLDivElement | null>;
|
|
9
|
+
isPlaying: boolean;
|
|
10
|
+
isBuffering: boolean;
|
|
11
|
+
isIdle: boolean;
|
|
12
|
+
isFullscreen: boolean;
|
|
13
|
+
currentTime: number;
|
|
14
|
+
duration: number;
|
|
15
|
+
bufferedEnd: number;
|
|
16
|
+
volume: number;
|
|
17
|
+
isMuted: boolean;
|
|
18
|
+
indicator: VideoIndicatorStateI | null;
|
|
19
|
+
subtitleText: string;
|
|
20
|
+
seekStep: number;
|
|
21
|
+
play: () => void;
|
|
22
|
+
pause: () => void;
|
|
23
|
+
togglePlay: () => void;
|
|
24
|
+
seekTo: (time: number) => void;
|
|
25
|
+
seekBy: (delta: number) => void;
|
|
26
|
+
setVolume: (next: number, shouldShow?: boolean) => void;
|
|
27
|
+
toggleMute: () => void;
|
|
28
|
+
toggleFullscreen: () => void;
|
|
29
|
+
wake: () => void;
|
|
30
|
+
handleKeyDown: (event: React.KeyboardEvent<HTMLElement>) => void;
|
|
31
|
+
videoHandlers: {
|
|
32
|
+
onPlay: () => void;
|
|
33
|
+
onPause: () => void;
|
|
34
|
+
onEnded: () => void;
|
|
35
|
+
onTimeUpdate: (event: import("react").SyntheticEvent<HTMLVideoElement>) => void;
|
|
36
|
+
onProgress: (event: import("react").SyntheticEvent<HTMLVideoElement>) => void;
|
|
37
|
+
onLoadedMetadata: (event: import("react").SyntheticEvent<HTMLVideoElement>) => void;
|
|
38
|
+
onDurationChange: (event: import("react").SyntheticEvent<HTMLVideoElement>) => void;
|
|
39
|
+
onVolumeChange: (event: import("react").SyntheticEvent<HTMLVideoElement>) => void;
|
|
40
|
+
onWaiting: () => void;
|
|
41
|
+
onPlaying: () => void;
|
|
42
|
+
onCanPlay: () => void;
|
|
43
|
+
onSeeked: () => void;
|
|
44
|
+
};
|
|
45
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { createContext, useContext } from "react";
|
|
3
|
+
// src/components/video-player/video-player-context.ts
|
|
4
|
+
/** Контекст плеера: состояние и действия для частей */
|
|
5
|
+
const VideoPlayerContext = createContext(null);
|
|
6
|
+
/**
|
|
7
|
+
* Состояние и действия ближайшего VideoPlayer: для своих частей управления
|
|
8
|
+
* @returns состояние плеера и методы управления
|
|
9
|
+
*/
|
|
10
|
+
function useVideoPlayerContext() {
|
|
11
|
+
const context = useContext(VideoPlayerContext);
|
|
12
|
+
if (!context) throw new Error("Части плеера нужно использовать внутри VideoPlayer");
|
|
13
|
+
return context;
|
|
14
|
+
}
|
|
15
|
+
export { VideoPlayerContext, useVideoPlayerContext };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { VideoPlayerControlsPropsT, VideoPlayerFullscreenButtonPropsT, VideoPlayerPlayButtonPropsT, VideoPlayerProgressPropsT, VideoPlayerTimePropsT, VideoPlayerVolumePropsT } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Панель управления: располагается внизу плеера и скрывается через пару секунд без движения
|
|
4
|
+
* мыши во время воспроизведения. Внутрь кладут кнопки, громкость, время и перемотку
|
|
5
|
+
* @param props - пропсы панели
|
|
6
|
+
* @returns контейнер элементов управления
|
|
7
|
+
*/
|
|
8
|
+
export declare function VideoPlayerControls({ className, ...props }: VideoPlayerControlsPropsT): import("react").JSX.Element;
|
|
9
|
+
/**
|
|
10
|
+
* Кнопка воспроизведения и паузы
|
|
11
|
+
* @param props - пропсы кнопки
|
|
12
|
+
* @returns круглая кнопка с иконкой по состоянию
|
|
13
|
+
*/
|
|
14
|
+
export declare function VideoPlayerPlayButton({ playLabel, pauseLabel, className, ...props }: VideoPlayerPlayButtonPropsT): import("react").JSX.Element;
|
|
15
|
+
/**
|
|
16
|
+
* Блок громкости: кнопка звука и ползунок, который раскрывается при наведении или фокусе
|
|
17
|
+
* @param props - пропсы блока
|
|
18
|
+
* @returns кнопка и ползунок громкости
|
|
19
|
+
*/
|
|
20
|
+
export declare function VideoPlayerVolume({ muteLabel, unmuteLabel, label, className, ...props }: VideoPlayerVolumePropsT): import("react").JSX.Element;
|
|
21
|
+
/**
|
|
22
|
+
* Время: текущее и общее, «0:12 / 3:45»
|
|
23
|
+
* @param props - пропсы времени
|
|
24
|
+
* @returns текст со временем
|
|
25
|
+
*/
|
|
26
|
+
export declare function VideoPlayerTime({ formatTime, className, ...props }: VideoPlayerTimePropsT): import("react").JSX.Element;
|
|
27
|
+
/**
|
|
28
|
+
* Полоса перемотки: показывает прогресс и загруженную часть, перетаскивание и клавиши меняют время
|
|
29
|
+
* @param props - пропсы полосы
|
|
30
|
+
* @returns слайдер времени
|
|
31
|
+
*/
|
|
32
|
+
export declare function VideoPlayerProgress({ label, getValueLabel, className, ...props }: VideoPlayerProgressPropsT): import("react").JSX.Element;
|
|
33
|
+
/**
|
|
34
|
+
* Кнопка входа в полноэкранный режим и выхода из него
|
|
35
|
+
* @param props - пропсы кнопки
|
|
36
|
+
* @returns круглая кнопка с иконкой по состоянию
|
|
37
|
+
*/
|
|
38
|
+
export declare function VideoPlayerFullscreenButton({ enterLabel, exitLabel, className, ...props }: VideoPlayerFullscreenButtonPropsT): import("react").JSX.Element;
|