@ilo-org/react 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +36 -0
- package/.storybook/main.js +28 -0
- package/.storybook/manager-head.html +7 -0
- package/.storybook/manager.js +6 -0
- package/.storybook/preview.tsx +33 -0
- package/.storybook/styles.scss +1 -0
- package/.storybook/theme.js +11 -0
- package/.turbo/turbo-build.log +513 -0
- package/.turbo/turbo-check.log +5 -0
- package/.turbo/turbo-test.log +1676 -0
- package/=6.4.0 +115 -0
- package/=7.21.4 +21 -0
- package/LICENSE +201 -0
- package/README.md +11 -0
- package/lib/index.esm.js +24 -0
- package/lib/index.esm.js.map +1 -0
- package/lib/index.js +24 -0
- package/lib/index.js.map +1 -0
- package/package.json +115 -0
- package/rollup.config.js +40 -0
- package/src/__tests__/Accordion.test.tsx +52 -0
- package/src/__tests__/Button.test.tsx +60 -0
- package/src/__tests__/Callout.test.tsx +41 -0
- package/src/__tests__/ContextMenu.test.tsx +19 -0
- package/src/__tests__/Dropdown.test.tsx +38 -0
- package/src/__tests__/Form.test.tsx +34 -0
- package/src/__tests__/Heading.test.tsx +51 -0
- package/src/__tests__/Hero.test.tsx +22 -0
- package/src/__tests__/Image.test.tsx +21 -0
- package/src/__tests__/LinkList.test.tsx +17 -0
- package/src/__tests__/List.test.tsx +37 -0
- package/src/__tests__/Loading.text.tsx +33 -0
- package/src/__tests__/Notification.test.tsx +39 -0
- package/src/__tests__/Pagination.test.tsx +58 -0
- package/src/__tests__/Profile.test.tsx +48 -0
- package/src/__tests__/ReadMore.test.tsx +42 -0
- package/src/__tests__/RichText.test.tsx +16 -0
- package/src/__tests__/SearchField.test.tsx +35 -0
- package/src/__tests__/TableOfContents.test.tsx +12 -0
- package/src/__tests__/Tag.test.tsx +10 -0
- package/src/components/Accordion/Accordion.args.ts +19 -0
- package/src/components/Accordion/Accordion.props.d.ts +39 -0
- package/src/components/Accordion/Accordion.tsx +70 -0
- package/src/components/Accordion/AccordionButton.props.d.ts +13 -0
- package/src/components/Accordion/AccordionButton.tsx +60 -0
- package/src/components/Accordion/AccordionItem.props.d.ts +25 -0
- package/src/components/Accordion/AccordionItem.tsx +33 -0
- package/src/components/Accordion/AccordionPanel.props.d.ts +20 -0
- package/src/components/Accordion/AccordionPanel.tsx +47 -0
- package/src/components/Accordion/index.ts +4 -0
- package/src/components/Button/Button.args.ts +353 -0
- package/src/components/Button/Button.props.d.ts +74 -0
- package/src/components/Button/Button.tsx +67 -0
- package/src/components/Button/index.ts +1 -0
- package/src/components/Callout/Callout.args.ts +64 -0
- package/src/components/Callout/Callout.props.d.ts +61 -0
- package/src/components/Callout/Callout.tsx +80 -0
- package/src/components/Callout/index.ts +1 -0
- package/src/components/Checkbox/Checkbox.args.ts +22 -0
- package/src/components/Checkbox/Checkbox.props.d.ts +61 -0
- package/src/components/Checkbox/Checkbox.tsx +92 -0
- package/src/components/Checkbox/index.ts +1 -0
- package/src/components/ChoiceGroup/ChoiceGroup.args.ts +90 -0
- package/src/components/ChoiceGroup/ChoiceGroup.props.d.ts +57 -0
- package/src/components/ChoiceGroup/ChoiceGroup.tsx +42 -0
- package/src/components/ChoiceGroup/index.ts +1 -0
- package/src/components/Collapse/Collapse.props.d.ts +92 -0
- package/src/components/Collapse/Collapse.tsx +130 -0
- package/src/components/Collapse/index.ts +1 -0
- package/src/components/ContextMenu/ContextMenu.args.ts +62 -0
- package/src/components/ContextMenu/ContextMenu.props.d.ts +28 -0
- package/src/components/ContextMenu/ContextMenu.tsx +32 -0
- package/src/components/ContextMenu/index.ts +1 -0
- package/src/components/Credit/Credit.args.ts +14 -0
- package/src/components/Credit/Credit.props.d.ts +11 -0
- package/src/components/Credit/Credit.tsx +41 -0
- package/src/components/Credit/index.ts +1 -0
- package/src/components/DatePicker/DatePicker.args.ts +82 -0
- package/src/components/DatePicker/DatePicker.props.d.ts +68 -0
- package/src/components/DatePicker/DatePicker.tsx +119 -0
- package/src/components/DatePicker/index.ts +1 -0
- package/src/components/Dropdown/Dropdown.args.ts +220 -0
- package/src/components/Dropdown/Dropdown.props.d.ts +84 -0
- package/src/components/Dropdown/Dropdown.tsx +82 -0
- package/src/components/Dropdown/index.ts +1 -0
- package/src/components/Empty/Empty.args.ts +14 -0
- package/src/components/Empty/Empty.props.d.ts +6 -0
- package/src/components/Empty/Empty.tsx +16 -0
- package/src/components/Empty/index.ts +1 -0
- package/src/components/Fieldset/Fieldset.props.d.ts +36 -0
- package/src/components/Fieldset/Fieldset.tsx +90 -0
- package/src/components/Fieldset/index.ts +1 -0
- package/src/components/FileUpload/FileUpload.args.ts +62 -0
- package/src/components/FileUpload/FileUpload.props.d.ts +63 -0
- package/src/components/FileUpload/FileUpload.tsx +82 -0
- package/src/components/FileUpload/index.ts +1 -0
- package/src/components/Form/Form.args.ts +265 -0
- package/src/components/Form/Form.props.d.ts +84 -0
- package/src/components/Form/Form.tsx +83 -0
- package/src/components/Form/index.ts +1 -0
- package/src/components/FormElement/FormElement.props.d.ts +53 -0
- package/src/components/FormElement/FormElement.tsx +26 -0
- package/src/components/FormElement/index.ts +1 -0
- package/src/components/FormGroup/FormGroup.args.ts +84 -0
- package/src/components/FormGroup/FormGroup.props.d.ts +71 -0
- package/src/components/FormGroup/FormGroup.tsx +73 -0
- package/src/components/FormGroup/index.ts +1 -0
- package/src/components/GlobalProvider/GlobalProvider.props.d.ts +15 -0
- package/src/components/GlobalProvider/GlobalProvider.tsx +27 -0
- package/src/components/GlobalProvider/index.js +4 -0
- package/src/components/Heading/Heading.args.ts +46 -0
- package/src/components/Heading/Heading.props.d.ts +24 -0
- package/src/components/Heading/Heading.tsx +28 -0
- package/src/components/Heading/index.ts +1 -0
- package/src/components/Hero/Hero.args.ts +296 -0
- package/src/components/Hero/Hero.props.d.ts +29 -0
- package/src/components/Hero/Hero.tsx +35 -0
- package/src/components/Hero/HeroCard.props.d.ts +65 -0
- package/src/components/Hero/HeroCard.tsx +53 -0
- package/src/components/Hero/index.ts +2 -0
- package/src/components/Icon/Icon.args.ts +15 -0
- package/src/components/Icon/Icon.props.d.ts +16 -0
- package/src/components/Icon/Icon.tsx +25 -0
- package/src/components/Icon/index.ts +1 -0
- package/src/components/Image/Image.args.ts +35 -0
- package/src/components/Image/Image.props.d.ts +38 -0
- package/src/components/Image/Image.tsx +51 -0
- package/src/components/Image/index.ts +1 -0
- package/src/components/Input/Input.args.ts +139 -0
- package/src/components/Input/Input.props.d.ts +63 -0
- package/src/components/Input/Input.tsx +63 -0
- package/src/components/Input/index.ts +1 -0
- package/src/components/Link/Link.args.ts +36 -0
- package/src/components/Link/Link.props.d.ts +34 -0
- package/src/components/Link/Link.tsx +49 -0
- package/src/components/Link/index.ts +1 -0
- package/src/components/LinkList/LinkList.args.ts +193 -0
- package/src/components/LinkList/LinkList.props.d.ts +52 -0
- package/src/components/LinkList/LinkList.tsx +59 -0
- package/src/components/LinkList/index.ts +1 -0
- package/src/components/List/List.args.ts +38 -0
- package/src/components/List/List.props.d.ts +36 -0
- package/src/components/List/List.tsx +47 -0
- package/src/components/List/ListItem.props.d.ts +25 -0
- package/src/components/List/ListItem.tsx +23 -0
- package/src/components/List/index.ts +2 -0
- package/src/components/Loading/Loading.args.ts +55 -0
- package/src/components/Loading/Loading.props.d.ts +23 -0
- package/src/components/Loading/Loading.tsx +24 -0
- package/src/components/Loading/index.ts +1 -0
- package/src/components/Notification/Notification.args.ts +157 -0
- package/src/components/Notification/Notification.props.d.ts +67 -0
- package/src/components/Notification/Notification.tsx +78 -0
- package/src/components/Notification/index.ts +1 -0
- package/src/components/NumberPicker/NumberPicker.args.ts +58 -0
- package/src/components/NumberPicker/NumberPicker.props.d.ts +56 -0
- package/src/components/NumberPicker/NumberPicker.tsx +65 -0
- package/src/components/NumberPicker/index.ts +1 -0
- package/src/components/Pagination/Pagination.args.ts +43 -0
- package/src/components/Pagination/Pagination.props.d.ts +66 -0
- package/src/components/Pagination/Pagination.tsx +114 -0
- package/src/components/Pagination/index.ts +1 -0
- package/src/components/Profile/Profile.args.ts +58 -0
- package/src/components/Profile/Profile.props.d.ts +43 -0
- package/src/components/Profile/Profile.tsx +43 -0
- package/src/components/Profile/index.ts +1 -0
- package/src/components/Radio/Radio.args.ts +22 -0
- package/src/components/Radio/Radio.props.d.ts +61 -0
- package/src/components/Radio/Radio.tsx +64 -0
- package/src/components/Radio/index.ts +1 -0
- package/src/components/ReadMore/ReadMore.props.d.ts +38 -0
- package/src/components/ReadMore/ReadMore.tsx +55 -0
- package/src/components/ReadMore/index.ts +1 -0
- package/src/components/ReadMore/readMore.args.ts +35 -0
- package/src/components/RichText/RichText.props.d.ts +11 -0
- package/src/components/RichText/RichText.tsx +22 -0
- package/src/components/RichText/index.ts +1 -0
- package/src/components/RichText/richText.args.ts +15 -0
- package/src/components/SearchField/SearchField.args.ts +73 -0
- package/src/components/SearchField/SearchField.props.d.ts +35 -0
- package/src/components/SearchField/SearchField.tsx +55 -0
- package/src/components/SearchField/index.ts +1 -0
- package/src/components/TableOfContents/TableOfContents.args.ts +35 -0
- package/src/components/TableOfContents/TableOfContents.props.d.ts +23 -0
- package/src/components/TableOfContents/TableOfContents.tsx +32 -0
- package/src/components/TableOfContents/index.ts +1 -0
- package/src/components/Tag/Tag.args.ts +15 -0
- package/src/components/Tag/Tag.props.d.ts +34 -0
- package/src/components/Tag/Tag.tsx +99 -0
- package/src/components/Tag/TagSet.args.ts +39 -0
- package/src/components/Tag/TagSet.props.d.ts +36 -0
- package/src/components/Tag/TagSet.tsx +71 -0
- package/src/components/Tag/index.ts +2 -0
- package/src/components/Textarea/Textarea.args.ts +62 -0
- package/src/components/Textarea/Textarea.props.d.ts +71 -0
- package/src/components/Textarea/Textarea.tsx +67 -0
- package/src/components/Textarea/index.ts +1 -0
- package/src/components/Tooltip/Tooltip.args.ts +43 -0
- package/src/components/Tooltip/Tooltip.props.d.ts +48 -0
- package/src/components/Tooltip/Tooltip.tsx +139 -0
- package/src/components/Tooltip/index.ts +1 -0
- package/src/components/Video/Video.args.ts +81 -0
- package/src/components/Video/Video.props.d.ts +82 -0
- package/src/components/Video/Video.tsx +29 -0
- package/src/components/Video/VideoPlayer.props.d.ts +80 -0
- package/src/components/Video/VideoPlayer.tsx +285 -0
- package/src/components/Video/index.ts +1 -0
- package/src/hooks/useGlobalSettings.ts +13 -0
- package/src/hooks/useVideoPlayer.ts +85 -0
- package/src/index.ts +19 -0
- package/src/public/favicon.ico +0 -0
- package/src/public/index.html +43 -0
- package/src/public/logo192.png +0 -0
- package/src/public/logo512.png +0 -0
- package/src/public/manifest.json +25 -0
- package/src/public/robots.txt +3 -0
- package/src/setup.ts +6 -0
- package/src/stories/Accordion.stories.tsx +94 -0
- package/src/stories/Button.stories.tsx +491 -0
- package/src/stories/Callout.stories.tsx +154 -0
- package/src/stories/ContextMenu.stories.tsx +72 -0
- package/src/stories/Dropdown.stories.tsx +85 -0
- package/src/stories/Empty.stories.tsx +48 -0
- package/src/stories/Form.stories.tsx +67 -0
- package/src/stories/Heading.stories.tsx +191 -0
- package/src/stories/Hero.stories.tsx +129 -0
- package/src/stories/Image.stories.tsx +71 -0
- package/src/stories/Introduction.stories.mdx +12 -0
- package/src/stories/Link.stories.tsx +99 -0
- package/src/stories/LinkList.stories.tsx +68 -0
- package/src/stories/List.stories.tsx +246 -0
- package/src/stories/Loading.stories.tsx +103 -0
- package/src/stories/Notification.stories.tsx +154 -0
- package/src/stories/Pagination.stories.tsx +63 -0
- package/src/stories/Profile.stories.tsx +84 -0
- package/src/stories/ReadMore.stories.tsx +80 -0
- package/src/stories/RichText.stories.tsx +59 -0
- package/src/stories/SearchField.stories.tsx +87 -0
- package/src/stories/TableOfContents.stories.tsx +50 -0
- package/src/stories/Tag.stories.tsx +194 -0
- package/src/stories/Tooltip.stories.tsx +83 -0
- package/src/stories/Video.stories.tsx +69 -0
- package/src/stories/assets/code-brackets.svg +1 -0
- package/src/stories/assets/colors.svg +1 -0
- package/src/stories/assets/comments.svg +1 -0
- package/src/stories/assets/direction.svg +1 -0
- package/src/stories/assets/flow.svg +1 -0
- package/src/stories/assets/plugin.svg +1 -0
- package/src/stories/assets/repo.svg +1 -0
- package/src/stories/assets/stackalt.svg +1 -0
- package/src/types/index.ts +49 -0
- package/src/types/temp.d.ts +9 -0
- package/src/utils/checkArrayDuplicates.ts +3 -0
- package/src/utils/createChainedFunction.ts +31 -0
- package/src/utils/getDefaultDimensionValue.ts +28 -0
- package/src/utils/hoursMinutesSeconds.ts +8 -0
- package/src/utils/transitionEndListener.ts +29 -0
- package/src/utils/triggerBrowserReflow.ts +4 -0
- package/storybook-static/0.f9bb25299a048d2bb825.manager.bundle.js +2 -0
- package/storybook-static/0.f9bb25299a048d2bb825.manager.bundle.js.LICENSE.txt +8 -0
- package/storybook-static/01daf23af61cc99e9d75.woff2 +0 -0
- package/storybook-static/06a2da828c8b6497ba7a.woff +0 -0
- package/storybook-static/0fa24adac56865ac7e5f.ttf +0 -0
- package/storybook-static/12ec02e7e66abaf38243.eot +0 -0
- package/storybook-static/164.8f6e5926.iframe.bundle.js +2 -0
- package/storybook-static/164.8f6e5926.iframe.bundle.js.LICENSE.txt +8 -0
- package/storybook-static/181.1d6d475b.iframe.bundle.js +1 -0
- package/storybook-static/1cc3364249fd0db446ad.ttf +0 -0
- package/storybook-static/1dbed2ef5cef8fcb4cbe.ttf +0 -0
- package/storybook-static/1fa1c16a4a45d13f0df8.ttf +0 -0
- package/storybook-static/23cdaa8575b5e003dcde.eot +0 -0
- package/storybook-static/248db78ddf1e3568728d.woff +0 -0
- package/storybook-static/27d33755a2b827666dc5.woff +0 -0
- package/storybook-static/29.8e0bc9a8.iframe.bundle.js +2 -0
- package/storybook-static/29.8e0bc9a8.iframe.bundle.js.LICENSE.txt +102 -0
- package/storybook-static/2ac1a95228cf06e17040.woff2 +0 -0
- package/storybook-static/337.b8defe66.iframe.bundle.js +2 -0
- package/storybook-static/337.b8defe66.iframe.bundle.js.LICENSE.txt +11 -0
- package/storybook-static/3579203659b1428de036.eot +0 -0
- package/storybook-static/36229f80a738c199462d.woff2 +0 -0
- package/storybook-static/409a9c398a28ee4d74ff.eot +0 -0
- package/storybook-static/431.8ab7c276.iframe.bundle.js +1 -0
- package/storybook-static/431.b32fed6077acc140df7c.manager.bundle.js +1 -0
- package/storybook-static/4bf5fc6f93ba10519c82.eot +0 -0
- package/storybook-static/51d7da3f5e58e3a24a84.woff +0 -0
- package/storybook-static/697.1f42ad69d33c2733c631.manager.bundle.js +1 -0
- package/storybook-static/697.9e56beef.iframe.bundle.js +1 -0
- package/storybook-static/6a159f0a2005668f1f78.woff +0 -0
- package/storybook-static/6f781753b674130d947a.ttf +0 -0
- package/storybook-static/70a240717e773fe567b3.woff2 +0 -0
- package/storybook-static/720.f44d4e1f5203b6083ae4.manager.bundle.js +1 -0
- package/storybook-static/730.1240c246.iframe.bundle.js +1 -0
- package/storybook-static/730.7223b772132e3e068755.manager.bundle.js +1 -0
- package/storybook-static/73ba1c910e0f7bfc6b18.woff2 +0 -0
- package/storybook-static/88739612501023fa15e3.woff +0 -0
- package/storybook-static/8a142c29a318c432117a.woff +0 -0
- package/storybook-static/914.8ddb80ae2badda1468b0.manager.bundle.js +2 -0
- package/storybook-static/914.8ddb80ae2badda1468b0.manager.bundle.js.LICENSE.txt +94 -0
- package/storybook-static/978.236a5d9d5736517b960e.manager.bundle.js +2 -0
- package/storybook-static/978.236a5d9d5736517b960e.manager.bundle.js.LICENSE.txt +12 -0
- package/storybook-static/978.32e8032b.iframe.bundle.js +2 -0
- package/storybook-static/978.32e8032b.iframe.bundle.js.LICENSE.txt +12 -0
- package/storybook-static/9db5d05810cb98f2831f.ttf +0 -0
- package/storybook-static/9ff97e342523931a4992.eot +0 -0
- package/storybook-static/a40d436619020fb67db5.woff +0 -0
- package/storybook-static/a41d7e330757fb4b2125.woff2 +0 -0
- package/storybook-static/ab3494afe25b712485ed.woff +0 -0
- package/storybook-static/b53d0e74edc5a5fbef0a.ttf +0 -0
- package/storybook-static/b70a9c0ad8e8b43f5e6c.ttf +0 -0
- package/storybook-static/c12a83f816844ff94375.ttf +0 -0
- package/storybook-static/c5116d16544f932eba4b.eot +0 -0
- package/storybook-static/c807e115c00aaffbac11.woff2 +0 -0
- package/storybook-static/cadb6b94d6b0ecc3a86a.woff2 +0 -0
- package/storybook-static/d0cff1b064bcd84324fe.eot +0 -0
- package/storybook-static/d3434771ad7e9030387e.ttf +0 -0
- package/storybook-static/d8610c2a4fe5c177f4f6.woff +0 -0
- package/storybook-static/d970f426740b938f39e1.woff +0 -0
- package/storybook-static/d9c7eba773ff1c8df5bb.eot +0 -0
- package/storybook-static/dd4645bdb2f1e1a47ed7.woff2 +0 -0
- package/storybook-static/e0a63577ac642885f067.eot +0 -0
- package/storybook-static/e2625b8a1277972c9240.ttf +0 -0
- package/storybook-static/f469ea3aa8aacf7ad83a.eot +0 -0
- package/storybook-static/f632ebfa0d7b7085d542.woff2 +0 -0
- package/storybook-static/f93e2252d7112c3bcca5.woff2 +0 -0
- package/storybook-static/favicon.ico +0 -0
- package/storybook-static/iframe.html +348 -0
- package/storybook-static/index.html +59 -0
- package/storybook-static/main.01e6a863.iframe.bundle.js +1 -0
- package/storybook-static/main.dc406261155f1ebb44ce.manager.bundle.js +1 -0
- package/storybook-static/reactPlayerDailyMotion.469cc00f.iframe.bundle.js +1 -0
- package/storybook-static/reactPlayerFacebook.1423bb15.iframe.bundle.js +1 -0
- package/storybook-static/reactPlayerFilePlayer.e19e24a0.iframe.bundle.js +1 -0
- package/storybook-static/reactPlayerKaltura.d1eb0868.iframe.bundle.js +1 -0
- package/storybook-static/reactPlayerMixcloud.9f1b1691.iframe.bundle.js +1 -0
- package/storybook-static/reactPlayerPreview.9295696b.iframe.bundle.js +1 -0
- package/storybook-static/reactPlayerSoundCloud.d420395c.iframe.bundle.js +1 -0
- package/storybook-static/reactPlayerStreamable.9b655bf3.iframe.bundle.js +1 -0
- package/storybook-static/reactPlayerTwitch.e90e6dea.iframe.bundle.js +1 -0
- package/storybook-static/reactPlayerVidyard.a37ae6b3.iframe.bundle.js +1 -0
- package/storybook-static/reactPlayerVimeo.a7f367ee.iframe.bundle.js +1 -0
- package/storybook-static/reactPlayerWistia.fb351944.iframe.bundle.js +1 -0
- package/storybook-static/reactPlayerYouTube.3514e11a.iframe.bundle.js +1 -0
- package/storybook-static/runtime~main.012769eac0433a7ec083.manager.bundle.js +1 -0
- package/storybook-static/runtime~main.f3168ed5.iframe.bundle.js +1 -0
- package/storybook-static/static/css/main.3d116812.css +3 -0
- package/storybook-static/static/css/main.3d116812.css.map +1 -0
- package/tsconfig.build.json +15 -0
- package/tsconfig.json +7 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { FC, useState, useRef } from "react";
|
|
2
|
+
import classNames from "classnames";
|
|
3
|
+
import useGlobalSettings from "../../hooks/useGlobalSettings";
|
|
4
|
+
import { TooltipProps } from "./Tooltip.props";
|
|
5
|
+
import ReactDOM from "react-dom";
|
|
6
|
+
|
|
7
|
+
const Tooltip: FC<TooltipProps> = ({
|
|
8
|
+
className,
|
|
9
|
+
children,
|
|
10
|
+
icon,
|
|
11
|
+
label,
|
|
12
|
+
theme,
|
|
13
|
+
}) => {
|
|
14
|
+
const { prefix } = useGlobalSettings();
|
|
15
|
+
const baseClass = `${prefix}--tooltip`;
|
|
16
|
+
const [isVisible, setIsVisible] = useState<boolean>(false);
|
|
17
|
+
const [position, setPosition] = useState<{ x: number; y: number }>({
|
|
18
|
+
x: 0,
|
|
19
|
+
y: 0,
|
|
20
|
+
});
|
|
21
|
+
const [arrowPlacement, setArrowPlacement] = useState<string>("center");
|
|
22
|
+
const [arrowAlignment, setArrowAlignment] = useState<string>("left");
|
|
23
|
+
|
|
24
|
+
const tooltipRef = useRef(null);
|
|
25
|
+
|
|
26
|
+
const tooltipClasses = classNames(className, {
|
|
27
|
+
[baseClass]: true,
|
|
28
|
+
[`${baseClass}--${theme}`]: theme,
|
|
29
|
+
[`${baseClass}--alignment-${arrowAlignment}`]: arrowAlignment,
|
|
30
|
+
[`${baseClass}--visible`]: isVisible,
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
const tooltipArrowClasses = classNames(className, {
|
|
34
|
+
[`${baseClass}--arrow`]: true,
|
|
35
|
+
[`${baseClass}--arrow--placement-${arrowPlacement}`]: arrowPlacement,
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const handleOnMouseOver = (e: any) => {
|
|
39
|
+
// get hovered element reference
|
|
40
|
+
const target = e.currentTarget;
|
|
41
|
+
|
|
42
|
+
if (target != null) {
|
|
43
|
+
const rect = target.getBoundingClientRect();
|
|
44
|
+
setIsVisible(true);
|
|
45
|
+
postMouseOver(rect);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const postMouseOver = (hoverRect: any) => {
|
|
50
|
+
// position the tooltip after showing it
|
|
51
|
+
let placement = "center";
|
|
52
|
+
let alignment = "left";
|
|
53
|
+
|
|
54
|
+
const ttNode = ReactDOM.findDOMNode(tooltipRef.current) as Element;
|
|
55
|
+
if (ttNode != null) {
|
|
56
|
+
let x = 0,
|
|
57
|
+
y = 0;
|
|
58
|
+
|
|
59
|
+
const docWidth = document.documentElement.clientWidth,
|
|
60
|
+
docHeight = document.documentElement.clientHeight;
|
|
61
|
+
|
|
62
|
+
const rx = hoverRect.x + hoverRect.width, // most right x
|
|
63
|
+
lx = hoverRect.x, // most left x
|
|
64
|
+
ty = hoverRect.y, // most top y
|
|
65
|
+
by = hoverRect.y + hoverRect.height; // most bottom y
|
|
66
|
+
|
|
67
|
+
// tool tip rectange
|
|
68
|
+
const ttRect = ttNode.getBoundingClientRect();
|
|
69
|
+
|
|
70
|
+
const bRight =
|
|
71
|
+
rx + ttRect.width <= window.scrollX + docWidth &&
|
|
72
|
+
ty + ttRect.height <= window.scrollY + docHeight;
|
|
73
|
+
const bLeft =
|
|
74
|
+
lx - ttRect.width >= 0 &&
|
|
75
|
+
ty + ttRect.height <= window.scrollY + docHeight;
|
|
76
|
+
const bAbove = ty - ttRect.height >= 0;
|
|
77
|
+
const bBellow = by + ttRect.height <= window.scrollY + docHeight;
|
|
78
|
+
|
|
79
|
+
// the tooltip doesn't fit to the left
|
|
80
|
+
if (bRight) {
|
|
81
|
+
x = hoverRect.width + 16;
|
|
82
|
+
y = icon ? -8 : 0;
|
|
83
|
+
placement = "negative";
|
|
84
|
+
alignment = "right";
|
|
85
|
+
} else if (bBellow) {
|
|
86
|
+
x = icon ? -8 : 0;
|
|
87
|
+
y = hoverRect.height + 16;
|
|
88
|
+
|
|
89
|
+
placement = "center";
|
|
90
|
+
alignment = "bottom";
|
|
91
|
+
} else if (bLeft) {
|
|
92
|
+
x = -ttRect.width - 16;
|
|
93
|
+
y = icon ? -8 : 0;
|
|
94
|
+
|
|
95
|
+
placement = "negative";
|
|
96
|
+
alignment = "left";
|
|
97
|
+
} else if (bAbove) {
|
|
98
|
+
x = icon ? -8 : 0;
|
|
99
|
+
y = -ttRect.height - 16;
|
|
100
|
+
|
|
101
|
+
placement = "center";
|
|
102
|
+
alignment = "top";
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
setPosition({ x: x, y: y });
|
|
106
|
+
setArrowPlacement(placement);
|
|
107
|
+
setArrowAlignment(alignment);
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
const handleOnMouseOut = () => {
|
|
112
|
+
setIsVisible(false);
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
const style = {
|
|
116
|
+
// left: ((position.x + window.scrollX) + 'px'),
|
|
117
|
+
// top: ((position.y + window.scrollY) + 'px')
|
|
118
|
+
left: position.x + "px",
|
|
119
|
+
top: position.y + "px",
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
return (
|
|
123
|
+
<div
|
|
124
|
+
className={`${baseClass}--wrapper ${icon && "has-icon"}`}
|
|
125
|
+
onMouseOver={handleOnMouseOver}
|
|
126
|
+
onFocus={handleOnMouseOver}
|
|
127
|
+
onMouseOut={handleOnMouseOut}
|
|
128
|
+
onBlur={handleOnMouseOut}
|
|
129
|
+
>
|
|
130
|
+
{!icon && <>{children}</>}
|
|
131
|
+
<span className={tooltipClasses} style={style} ref={tooltipRef}>
|
|
132
|
+
<span className={tooltipArrowClasses} role="presentation"></span>
|
|
133
|
+
{label}
|
|
134
|
+
</span>
|
|
135
|
+
</div>
|
|
136
|
+
);
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
export default Tooltip;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Tooltip } from "./Tooltip";
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { VideoProps } from "./Video.props";
|
|
2
|
+
|
|
3
|
+
const videofile: VideoProps = {
|
|
4
|
+
alt: "My alt text",
|
|
5
|
+
className: "image",
|
|
6
|
+
caption: "my video caption",
|
|
7
|
+
url: [
|
|
8
|
+
{
|
|
9
|
+
breakpoint: 0,
|
|
10
|
+
src: "https://placekitten.com/g/400/300",
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
breakpoint: 800,
|
|
14
|
+
src: "https://placekitten.com/g/800/600",
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
breakpoint: 1200,
|
|
18
|
+
src: "https://placekitten.com/g/1200/900",
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
breakpoint: 1440,
|
|
22
|
+
src: "https://placekitten.com/g/1600/1200",
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
video: {
|
|
26
|
+
controls: {
|
|
27
|
+
fullscreen: "Fullscreen",
|
|
28
|
+
play: "Play",
|
|
29
|
+
pause: "Pause",
|
|
30
|
+
volume: "Volume",
|
|
31
|
+
},
|
|
32
|
+
src: "https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4",
|
|
33
|
+
tracks: null,
|
|
34
|
+
youtube: false,
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const videoyt: VideoProps = {
|
|
39
|
+
alt: "My alt text",
|
|
40
|
+
caption: "my video caption",
|
|
41
|
+
className: "image",
|
|
42
|
+
url: [
|
|
43
|
+
{
|
|
44
|
+
breakpoint: 0,
|
|
45
|
+
src: "https://placekitten.com/400/300",
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
breakpoint: 800,
|
|
49
|
+
src: "https://placekitten.com/800/600",
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
breakpoint: 1200,
|
|
53
|
+
src: "https://placekitten.com/1200/900",
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
breakpoint: 1440,
|
|
57
|
+
src: "https://placekitten.com/1600/1200",
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
video: {
|
|
61
|
+
controls: {
|
|
62
|
+
fullscreen: "Fullscreen",
|
|
63
|
+
play: "Play",
|
|
64
|
+
pause: "Pause",
|
|
65
|
+
volume: "Volume",
|
|
66
|
+
},
|
|
67
|
+
src: "https://youtu.be/ombTwldE3Kw",
|
|
68
|
+
tracks: null,
|
|
69
|
+
youtube: true,
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Sample prop definitions for Video's enumerable properties (imported in stories and tests).
|
|
75
|
+
*/
|
|
76
|
+
const videoArgs = {
|
|
77
|
+
videofile,
|
|
78
|
+
videoyt,
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export default videoArgs;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
interface ImageUrl {
|
|
2
|
+
/**
|
|
3
|
+
* Specify the breakpoint at which this image src should be used
|
|
4
|
+
*/
|
|
5
|
+
breakpoint?: number;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Specify the url of this breakpoint's image src
|
|
9
|
+
*/
|
|
10
|
+
src?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
interface VideoPlayerControls {
|
|
14
|
+
/**
|
|
15
|
+
* Specify the label for the fullscreen button
|
|
16
|
+
*/
|
|
17
|
+
fullscreen?: Required<string>;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Specify the label for the play button
|
|
21
|
+
*/
|
|
22
|
+
play?: Required<string>;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Specify the label for the pause button
|
|
26
|
+
*/
|
|
27
|
+
pause?: Required<string>;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Specify the label for the volume button
|
|
31
|
+
*/
|
|
32
|
+
volume?: Required<string>;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
interface Video {
|
|
36
|
+
/**
|
|
37
|
+
* Specify the strings to be used as labels for the video controls
|
|
38
|
+
*/
|
|
39
|
+
controls?: Required<VideoPlayerControls | false>;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* if self-hosted, specify the url of this video
|
|
43
|
+
*/
|
|
44
|
+
src?: string | null;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* if there are closed-caption tracks,
|
|
48
|
+
*/
|
|
49
|
+
tracks?: Required<Array<TracksConfig>> | null;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* if YouTube, set to true
|
|
53
|
+
*/
|
|
54
|
+
youtube?: boolean;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface VideoProps {
|
|
58
|
+
/**
|
|
59
|
+
* Specify the alt for the image
|
|
60
|
+
*/
|
|
61
|
+
alt?: Required<string>;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Specify the caption for the image/video
|
|
65
|
+
*/
|
|
66
|
+
caption?: string;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Specify an optional className to be added to your Media.
|
|
70
|
+
*/
|
|
71
|
+
className?: string;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Specify the image src for the image
|
|
75
|
+
*/
|
|
76
|
+
url?: Required<ImgageUrl>;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Specify whether there is a video being shown
|
|
80
|
+
*/
|
|
81
|
+
video?: Required<Video>;
|
|
82
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { FC } from "react";
|
|
2
|
+
import classNames from "classnames";
|
|
3
|
+
import useGlobalSettings from "../../hooks/useGlobalSettings";
|
|
4
|
+
import { VideoProps } from "./Video.props";
|
|
5
|
+
import VideoPlayer from "./VideoPlayer";
|
|
6
|
+
|
|
7
|
+
const Video: FC<VideoProps> = ({ alt, className, caption, url, video }) => {
|
|
8
|
+
const { prefix } = useGlobalSettings();
|
|
9
|
+
const baseClass = `${prefix}--video`;
|
|
10
|
+
|
|
11
|
+
const videoClasses = classNames(className, {
|
|
12
|
+
[baseClass]: true,
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
const captionClasses = classNames("", {
|
|
16
|
+
[`${baseClass}--caption`]: true,
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
<figure className={videoClasses}>
|
|
21
|
+
<div className={`${videoClasses}--wrapper`}>
|
|
22
|
+
{video && <VideoPlayer {...video} poster={{ url: url, alt: alt }} />}
|
|
23
|
+
</div>
|
|
24
|
+
{caption && <figcaption className={captionClasses}>{caption}</figcaption>}
|
|
25
|
+
</figure>
|
|
26
|
+
);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export default Video;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
export interface VideoPlayerControls {
|
|
2
|
+
/**
|
|
3
|
+
* Specify the label for the fullscreen button
|
|
4
|
+
*/
|
|
5
|
+
fullscreen?: Required<string>;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Specify the label for the play button
|
|
9
|
+
*/
|
|
10
|
+
play?: Required<string>;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Specify the label for the pause button
|
|
14
|
+
*/
|
|
15
|
+
pause?: Required<string>;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Specify the label for the volume button
|
|
19
|
+
*/
|
|
20
|
+
volume?: Required<string>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface TracksConfig {
|
|
24
|
+
/**
|
|
25
|
+
* is this the default track?
|
|
26
|
+
*/
|
|
27
|
+
default?: boolean;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* What kind of track is it?
|
|
31
|
+
*/
|
|
32
|
+
kind?: string;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* url for the track
|
|
36
|
+
*/
|
|
37
|
+
src?: string;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* language of the track
|
|
41
|
+
*/
|
|
42
|
+
srcLang?: string;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface VideoPlayerProps {
|
|
46
|
+
/**
|
|
47
|
+
* Specify an optional className to be added to your Media.
|
|
48
|
+
*/
|
|
49
|
+
className?: string;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Specify the strings to be used as labels for the video controls
|
|
53
|
+
*/
|
|
54
|
+
controls?: Required<VideoPlayerControls | false>;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Specify whether a video is to be shown
|
|
58
|
+
*/
|
|
59
|
+
hasvideo?: Required<boolean>;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* poster image for video
|
|
63
|
+
*/
|
|
64
|
+
poster?: Required<Array>;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* if self-hosted, specify the url of this video
|
|
68
|
+
*/
|
|
69
|
+
src?: string | null;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* if there are closed-caption tracks,
|
|
73
|
+
*/
|
|
74
|
+
tracks?: Required<Array<TracksConfig>> | null;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* if YouTube, set to true
|
|
78
|
+
*/
|
|
79
|
+
youtube?: boolean;
|
|
80
|
+
}
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
import { FC, createRef, useState } from "react";
|
|
2
|
+
/* temporary way of importing ReactPlayer due to a known issue with ReactPlayer.
|
|
3
|
+
* Revert to standard method of importing once RP's dev has fixed.
|
|
4
|
+
*/
|
|
5
|
+
import { default as RP } from "react-player/lazy";
|
|
6
|
+
import { findDOMNode } from "react-dom";
|
|
7
|
+
import { ReactPlayerProps } from "react-player/types/lib";
|
|
8
|
+
const ReactPlayer = RP as unknown as FC<ReactPlayerProps>;
|
|
9
|
+
import classNames from "classnames";
|
|
10
|
+
import useGlobalSettings from "../../hooks/useGlobalSettings";
|
|
11
|
+
import { VideoPlayerProps } from "./VideoPlayer.props";
|
|
12
|
+
import hoursMinutesSeconds from "../../utils/hoursMinutesSeconds";
|
|
13
|
+
import screenfull from "screenfull";
|
|
14
|
+
|
|
15
|
+
const VideoPlayer: FC<VideoPlayerProps> = ({
|
|
16
|
+
controls,
|
|
17
|
+
src,
|
|
18
|
+
poster,
|
|
19
|
+
youtube,
|
|
20
|
+
tracks,
|
|
21
|
+
}) => {
|
|
22
|
+
const { prefix } = useGlobalSettings();
|
|
23
|
+
const baseClass = `${prefix}--video`;
|
|
24
|
+
|
|
25
|
+
const playerClasses = classNames("", {
|
|
26
|
+
[`${baseClass}--player`]: true,
|
|
27
|
+
[`youtube`]: youtube,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
const controlsClasses = classNames("", {
|
|
31
|
+
[`${baseClass}--controls`]: true,
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* State hooks for our player controls
|
|
36
|
+
*/
|
|
37
|
+
const [duration, setDuration] = useState("0:00");
|
|
38
|
+
const [playedtime, setPlayedtime] = useState("0:00");
|
|
39
|
+
const [buffer, setBuffer] = useState(0);
|
|
40
|
+
const [playing, setPlaying] = useState(false);
|
|
41
|
+
const [playhead, setPlayhead] = useState(0);
|
|
42
|
+
const [volume, setVolume] = useState(0.8);
|
|
43
|
+
const [muted, setMute] = useState(false);
|
|
44
|
+
const [showposter, showPoster] = useState(true);
|
|
45
|
+
const [showvolume, showVolume] = useState(false);
|
|
46
|
+
const [seeking, setSeeking] = useState(false);
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Ref for the video element
|
|
50
|
+
*/
|
|
51
|
+
const videoElement = createRef();
|
|
52
|
+
|
|
53
|
+
const youtubeparams = {
|
|
54
|
+
controls: 0,
|
|
55
|
+
modestbranding: 1,
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const playerconfig = {
|
|
59
|
+
file: {
|
|
60
|
+
tracks: tracks || [],
|
|
61
|
+
},
|
|
62
|
+
youtube: youtube ? { playerVars: youtubeparams } : {},
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Fullscreen functionality
|
|
67
|
+
*/
|
|
68
|
+
const toggleFullscreen = () => {
|
|
69
|
+
/* This is a known issue with ReactPlayer */
|
|
70
|
+
/* @ts-ignore */
|
|
71
|
+
screenfull.request(findDOMNode(videoElement.current));
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Play/pause functionality
|
|
76
|
+
*/
|
|
77
|
+
const togglePlay = () => {
|
|
78
|
+
setPlaying(!playing);
|
|
79
|
+
showPoster(false);
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Show volume slider
|
|
84
|
+
*/
|
|
85
|
+
const showVolumeSlider = () => {
|
|
86
|
+
showVolume(true);
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Hide volume slider
|
|
91
|
+
*/
|
|
92
|
+
const hideVolumeSlider = () => {
|
|
93
|
+
setTimeout(() => {
|
|
94
|
+
showVolume(false);
|
|
95
|
+
}, 2000);
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Mute/unmute
|
|
100
|
+
*/
|
|
101
|
+
const toggleMute = () => {
|
|
102
|
+
setMute(!muted);
|
|
103
|
+
hideVolumeSlider();
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Volume change
|
|
108
|
+
*/
|
|
109
|
+
const handleVolumeChange = (event: any) => {
|
|
110
|
+
console.log("handleVolumeChange", event.target.value);
|
|
111
|
+
setVolume(event.target.value * 0.1);
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Begin seek
|
|
116
|
+
*/
|
|
117
|
+
const handleSeekMouseDown = () => {
|
|
118
|
+
setSeeking(true);
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Seek
|
|
123
|
+
*/
|
|
124
|
+
const handleSeekChange = (event: any) => {
|
|
125
|
+
setPlayhead(parseFloat(event.target.value));
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* End seek
|
|
130
|
+
*/
|
|
131
|
+
const handleSeekMouseUp = (event: any) => {
|
|
132
|
+
setSeeking(false);
|
|
133
|
+
/* This is a known issue with ReactPlayer */
|
|
134
|
+
/* @ts-ignore */
|
|
135
|
+
videoElement.current.seekTo(parseFloat(event.target.value));
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* handle display of progress
|
|
140
|
+
*/
|
|
141
|
+
const handleProgress = (state: any) => {
|
|
142
|
+
if (!seeking) {
|
|
143
|
+
setPlayhead(state.played);
|
|
144
|
+
setBuffer(state.loaded);
|
|
145
|
+
setPlayedtime(hoursMinutesSeconds(state.playedSeconds));
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* get the duration to display
|
|
151
|
+
*/
|
|
152
|
+
const handleDuration = (duration: any) => {
|
|
153
|
+
setDuration(hoursMinutesSeconds(duration));
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* on video end
|
|
158
|
+
*/
|
|
159
|
+
const handleEnded = () => {
|
|
160
|
+
setPlaying(false);
|
|
161
|
+
setSeeking(false);
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
return (
|
|
165
|
+
<div className={`${baseClass}--container`}>
|
|
166
|
+
<ReactPlayer
|
|
167
|
+
className={playerClasses}
|
|
168
|
+
config={playerconfig as any}
|
|
169
|
+
loop={false}
|
|
170
|
+
muted={muted}
|
|
171
|
+
playing={playing}
|
|
172
|
+
ref={videoElement}
|
|
173
|
+
url={src as any}
|
|
174
|
+
width="100%"
|
|
175
|
+
height="100%"
|
|
176
|
+
volume={volume}
|
|
177
|
+
onProgress={handleProgress}
|
|
178
|
+
onDuration={handleDuration}
|
|
179
|
+
onEnded={handleEnded}
|
|
180
|
+
/>
|
|
181
|
+
<picture className={`${baseClass}--poster ${showposter ? "show" : ""}`}>
|
|
182
|
+
{poster.url &&
|
|
183
|
+
poster.url
|
|
184
|
+
.sort(
|
|
185
|
+
(a: any, b: any) =>
|
|
186
|
+
parseFloat(a.breakpoint) - parseFloat(b.breakpoint)
|
|
187
|
+
)
|
|
188
|
+
.slice(1)
|
|
189
|
+
.reverse()
|
|
190
|
+
.map((item: any, index: any) => (
|
|
191
|
+
<source
|
|
192
|
+
srcSet={item.src}
|
|
193
|
+
media={`(min-width: ${item.breakpoint}px)`}
|
|
194
|
+
key={index}
|
|
195
|
+
/>
|
|
196
|
+
))}
|
|
197
|
+
<img src={poster.url[0].src} alt={poster.alt} />
|
|
198
|
+
</picture>
|
|
199
|
+
<div className={`${controlsClasses} ${showposter ? "notplayed" : ""}`}>
|
|
200
|
+
<label
|
|
201
|
+
className={`${controlsClasses}--duration ${showposter ? "show" : ""}`}
|
|
202
|
+
>
|
|
203
|
+
{duration}
|
|
204
|
+
</label>
|
|
205
|
+
<button
|
|
206
|
+
className={`${controlsClasses}--${!playing ? "play" : "pause"}`}
|
|
207
|
+
onClick={togglePlay}
|
|
208
|
+
>
|
|
209
|
+
<span>
|
|
210
|
+
{!playing ? controls && controls.play : controls && controls.pause}
|
|
211
|
+
</span>
|
|
212
|
+
</button>
|
|
213
|
+
<div
|
|
214
|
+
className={`${controlsClasses}--progress ${showposter ? "" : "show"}`}
|
|
215
|
+
>
|
|
216
|
+
<input
|
|
217
|
+
type="range"
|
|
218
|
+
min={0}
|
|
219
|
+
max={0.999999}
|
|
220
|
+
step="any"
|
|
221
|
+
value={playhead}
|
|
222
|
+
onMouseDown={handleSeekMouseDown}
|
|
223
|
+
onChange={handleSeekChange}
|
|
224
|
+
onMouseUp={handleSeekMouseUp}
|
|
225
|
+
className={`${controlsClasses}--progress-playhead`}
|
|
226
|
+
/>
|
|
227
|
+
<progress
|
|
228
|
+
className={`${controlsClasses}--progress-current`}
|
|
229
|
+
max={1}
|
|
230
|
+
value={playhead}
|
|
231
|
+
/>
|
|
232
|
+
<progress
|
|
233
|
+
className={`${controlsClasses}--progress-loaded`}
|
|
234
|
+
max={1}
|
|
235
|
+
value={buffer}
|
|
236
|
+
/>
|
|
237
|
+
<div className={`${controlsClasses}--progress-played-container`}>
|
|
238
|
+
<label
|
|
239
|
+
className={`${controlsClasses}--progress-played`}
|
|
240
|
+
style={{ ["--playhead" as any]: `${playhead * 100}%` }}
|
|
241
|
+
>
|
|
242
|
+
{playedtime}
|
|
243
|
+
</label>
|
|
244
|
+
</div>
|
|
245
|
+
</div>
|
|
246
|
+
<div
|
|
247
|
+
className={`${controlsClasses}--volume ${showposter ? "" : "show"}`}
|
|
248
|
+
onMouseEnter={showVolumeSlider}
|
|
249
|
+
onMouseLeave={hideVolumeSlider}
|
|
250
|
+
>
|
|
251
|
+
<button
|
|
252
|
+
className={`${controlsClasses}--showvolume ${muted ? "muted" : ""}`}
|
|
253
|
+
onClick={toggleMute}
|
|
254
|
+
>
|
|
255
|
+
<span>{controls && controls.volume}</span>
|
|
256
|
+
</button>
|
|
257
|
+
<div className={`${controlsClasses}--setvolume-container`}>
|
|
258
|
+
<input
|
|
259
|
+
className={`${controlsClasses}--setvolume ${
|
|
260
|
+
showvolume ? "show" : ""
|
|
261
|
+
}`}
|
|
262
|
+
type="range"
|
|
263
|
+
step="0.5"
|
|
264
|
+
defaultValue={volume}
|
|
265
|
+
min="1"
|
|
266
|
+
max="10"
|
|
267
|
+
onChange={handleVolumeChange}
|
|
268
|
+
onMouseLeave={hideVolumeSlider}
|
|
269
|
+
/>
|
|
270
|
+
</div>
|
|
271
|
+
</div>
|
|
272
|
+
<button
|
|
273
|
+
className={`${controlsClasses}--fullscreen ${
|
|
274
|
+
showposter ? "" : "show"
|
|
275
|
+
}`}
|
|
276
|
+
onClick={toggleFullscreen}
|
|
277
|
+
>
|
|
278
|
+
<span>{controls && controls.fullscreen}</span>
|
|
279
|
+
</button>
|
|
280
|
+
</div>
|
|
281
|
+
</div>
|
|
282
|
+
);
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
export default VideoPlayer;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Video } from "./Video";
|