├── .gitignore ├── .prettierrc ├── src ├── lib │ ├── index.js │ ├── index.d.ts │ └── ReactFullScreen.js └── dev │ ├── index.js │ ├── index.html │ └── App.js ├── assets └── browser-support.png ├── .vscode └── settings.json ├── .github └── workflows │ ├── nodejs.yml │ └── npmpublish.yml ├── LICENSE ├── package.json ├── .eslintrc.json └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | dist/ 3 | build/ -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true 3 | } 4 | -------------------------------------------------------------------------------- /src/lib/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './ReactFullScreen'; 2 | -------------------------------------------------------------------------------- /assets/browser-support.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrelmlins/react-fullscreen/HEAD/assets/browser-support.png -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.formatOnSave": true, 3 | "editor.codeActionsOnSave": { 4 | "source.fixAll.eslint": true 5 | } 6 | } -------------------------------------------------------------------------------- /src/dev/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | 5 | ReactDOM.render(, document.getElementById('root')); 6 | -------------------------------------------------------------------------------- /src/lib/index.d.ts: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | export interface IReactFullScreenChildrenProps { 4 | ref: React.MutableRefObject; 5 | isEnabled: boolean; 6 | onToggle: () => void; 7 | onRequest: () => void; 8 | onExit: () => void; 9 | } 10 | 11 | export interface ReactFullScreenComponentProps { 12 | children: (props: IReactFullScreenChildrenProps) => React.ReactNode; 13 | onChange?: () => void; 14 | onError?: () => void; 15 | } 16 | 17 | export default class ReactFullScreenComponent extends React.Component {} 18 | -------------------------------------------------------------------------------- /.github/workflows/nodejs.yml: -------------------------------------------------------------------------------- 1 | name: Node.js CI 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build_test: 7 | runs-on: ${{ matrix.os }} 8 | strategy: 9 | matrix: 10 | node-version: [10, 12, 14] 11 | os: [ubuntu-latest, windows-latest, macOS-latest] 12 | steps: 13 | - uses: actions/checkout@v2 14 | - name: Use Node.js ${{ matrix.node-version }} 15 | uses: actions/setup-node@v1 16 | with: 17 | node-version: ${{ matrix.node-version }} 18 | - name: Install dependencies 19 | run: yarn install --frozen-lockfile 20 | - name: Build 21 | run: yarn build 22 | -------------------------------------------------------------------------------- /.github/workflows/npmpublish.yml: -------------------------------------------------------------------------------- 1 | name: Node.js Package 2 | 3 | on: 4 | release: 5 | types: [created] 6 | 7 | jobs: 8 | npm-publish: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v2 12 | - uses: actions/setup-node@v1 13 | with: 14 | node-version: 12 15 | registry-url: https://registry.npmjs.org/ 16 | - name: Install dependencies 17 | run: yarn install --frozen-lockfile 18 | - name: Build 19 | run: yarn build 20 | - name: Npm publish 21 | run: npm publish --access public 22 | env: 23 | NODE_AUTH_TOKEN: ${{secrets.npm_token}} 24 | -------------------------------------------------------------------------------- /src/lib/ReactFullScreen.js: -------------------------------------------------------------------------------- 1 | import { useRef, useEffect, memo } from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import screenfull from 'screenfull'; 4 | 5 | export const FullScreenComponent = ({ children, onChange, onError }) => { 6 | const ref = useRef(); 7 | 8 | useEffect(() => { 9 | screenfull.onchange(() => { 10 | if (onChange) { 11 | onChange(); 12 | } 13 | }); 14 | screenfull.on('error', () => { 15 | if (onError) { 16 | onError(); 17 | } 18 | }); 19 | }, []); 20 | 21 | return children({ 22 | ref, 23 | isEnabled: screenfull.isEnabled, 24 | onToggle: () => { 25 | screenfull.toggle(ref.current); 26 | }, 27 | onRequest: () => { 28 | screenfull.request(ref.current); 29 | }, 30 | onExit: () => { 31 | screenfull.exit(ref.current); 32 | }, 33 | }); 34 | }; 35 | 36 | FullScreenComponent.propTypes = { 37 | children: PropTypes.func, 38 | onChange: PropTypes.func, 39 | onError: PropTypes.func, 40 | }; 41 | 42 | export default memo(FullScreenComponent); 43 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 N.A.D.A. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-easyfullscreen", 3 | "version": "1.1.2", 4 | "description": "Component that performs fullscreen in DOM Elements", 5 | "main": "dist/index.js", 6 | "module": "dist/index.js", 7 | "types": "dist/index.d.ts", 8 | "files": [ 9 | "dist", 10 | "README.md" 11 | ], 12 | "homepage": "https://react-fullscreen.netlify.com/", 13 | "contributors": [ 14 | "André Lins (https://andrelmlins.github.io/)", 15 | "Leandro Alexandrino (http://leandrino.me/)" 16 | ], 17 | "scripts": { 18 | "start": "react-dependency-scripts start", 19 | "build": "react-dependency-scripts build", 20 | "build:app": "react-dependency-scripts build-app", 21 | "test": "react-dependency-scripts test", 22 | "lint": "eslint src/**/*.js" 23 | }, 24 | "repository": { 25 | "type": "git", 26 | "url": "git+https://github.com/andrelmlins/react-fullscreen.git" 27 | }, 28 | "keywords": [ 29 | "react", 30 | "fullscreen" 31 | ], 32 | "license": "MIT", 33 | "bugs": { 34 | "url": "https://github.com/andrelmlins/react-fullscreen/issues" 35 | }, 36 | "devDependencies": { 37 | "babel-eslint": "^10.1.0", 38 | "eslint": "^7.8.0", 39 | "eslint-plugin-jest": "^24.0.0", 40 | "eslint-plugin-jsx-a11y": "^6.3.0", 41 | "eslint-plugin-prettier": "^3.1.0", 42 | "eslint-plugin-react": "^7.20.0", 43 | "prettier": "^2.2.1", 44 | "prop-types": "^15.7.2", 45 | "react": "^16.13.0", 46 | "react-dependency-scripts": "^1.0.0", 47 | "react-dom": "^16.13.0" 48 | }, 49 | "dependencies": { 50 | "screenfull": "^5.0.2" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "plugin:jest/recommended", 4 | "plugin:react/recommended", 5 | "plugin:jsx-a11y/recommended" 6 | ], 7 | "settings": { 8 | "react": { 9 | "pragma": "React", 10 | "version": "16.4.1" 11 | } 12 | }, 13 | "plugins": [ 14 | "jest", 15 | "react", 16 | "jsx-a11y", 17 | "prettier" 18 | ], 19 | "env": { 20 | "jest/globals": true, 21 | "browser": true 22 | }, 23 | "rules": { 24 | "curly": [ 25 | "error", 26 | "all" 27 | ], 28 | "react/jsx-curly-brace-presence": "error", 29 | "react/display-name": "off", 30 | "react/jsx-uses-react": "error", 31 | "react/jsx-uses-vars": "error", 32 | "react/no-deprecated": "off", 33 | "react/prop-types": "off", 34 | "react/no-unescaped-entities": "off", 35 | "jest/no-disabled-tests": "warn", 36 | "jest/no-focused-tests": "error", 37 | "jest/no-identical-title": "error", 38 | "jest/prefer-to-have-length": "warn", 39 | "jest/valid-expect": "error", 40 | "import/prop-types": "off", 41 | "import/no-extraneous-dependencies": "off", 42 | "import/prefer-default-export": "off", 43 | "import/no-unresolved": "off", 44 | "import/extensions": "off", 45 | "indent": [ 46 | "error", 47 | 2, 48 | { 49 | "SwitchCase": 1 50 | } 51 | ], 52 | "id-length": 0, 53 | "semi": [ 54 | "error", 55 | "always" 56 | ], 57 | "quotes": [ 58 | 1, 59 | "single" 60 | ], 61 | "object-curly-spacing": [ 62 | "error", 63 | "always" 64 | ], 65 | "jsx-quotes": [ 66 | "error", 67 | "prefer-double" 68 | ], 69 | "avoidEscape": "off", 70 | "prettier/prettier": "error" 71 | }, 72 | "parser": "babel-eslint", 73 | "parserOptions": { 74 | "ecmaFeatures": { 75 | "jsx": true 76 | } 77 | }, 78 | "globals": { 79 | "Event": true 80 | } 81 | } -------------------------------------------------------------------------------- /src/dev/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 24 | React FullScreen 25 | 26 | 27 | 38 | 39 | 45 | 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # React FullScreen 2 | 3 | [](https://www.npmjs.com/package/react-easyfullscreen) • [](https://github.com/andrelmlins/react-fullscreen/blob/master/LICENSE) • [](https://github.com/andrelmlins/react-fullscreen/actions/workflows/nodejs.yml) • [](https://app.netlify.com/sites/react-fullscreen/deploys) • [](https://lgtm.com/projects/g/andrelmlins/react-fullscreen/context:javascript) 4 | 5 | Component that performs fullscreen in DOM Elements 6 | 7 | ## Installation 8 | 9 | ``` 10 | npm i react-easyfullscreen 11 | // OR 12 | yarn add react-easyfullscreen 13 | ``` 14 | 15 | ## Demo [Link](https://react-fullscreen.netlify.com/) 16 | 17 | Local demo: 18 | 19 | ``` 20 | git clone https://github.com/andrelmlins/react-fullscreen.git 21 | cd react-fullscreen 22 | npm install && npm run start 23 | ``` 24 | 25 | ## Examples 26 | 27 | ```jsx 28 | import React from 'react'; 29 | import { render } from 'react-dom'; 30 | import ReactFullscreen from 'react-easyfullscreen'; 31 | 32 | const App = () => ( 33 | 34 | {({ ref, onRequest, onExit }) => ( 35 | 39 | onRequest()}>FullScreen 40 | onExit()}>Screen 41 | 42 | )} 43 | 44 | ); 45 | 46 | render(, document.getElementById('root')); 47 | ``` 48 | 49 | ## Properties 50 | 51 | Raw component props (before transform): 52 | 53 | | Prop | Type | Description | 54 | | -------- | ---- | -------------- | 55 | | onChange | func | Call in change | 56 | | onError | func | Call in error | 57 | 58 | ### Children Function Properties 59 | 60 | | Prop | Type | Description | 61 | | --------- | ------ | --------------------------- | 62 | | ref | object | Ref dom element | 63 | | isEnabled | bool | If it's possible fullscreen | 64 | | onToggle | func | Call for fullscreen toggle | 65 | | onExit | func | Call for fullscreen exit | 66 | | onRequest | func | Call for fullscreen enter | 67 | 68 | ## Browsers Support 69 | 70 | You can see the list of supported browsers [here](https://caniuse.com/fullscreen) 71 | 72 |  73 | 74 | ## NPM Statistics 75 | 76 | Download stats for this NPM package 77 | 78 | [](https://nodei.co/npm/react-easyfullscreen/) 79 | 80 | ## License 81 | 82 | React FullScreen is open source software [licensed as MIT](https://github.com/andrelmlins/react-fullscreen/blob/master/LICENSE). 83 | -------------------------------------------------------------------------------- /src/dev/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import FullScreenComponent from '../lib'; 3 | 4 | const App = () => ( 5 | 6 | React Fullscreen 7 | Component that performs fullscreen in DOM Elements 8 | 9 | 10 | 11 | console.log('Screen')} 13 | onError={() => console.log('Error')} 14 | > 15 | {({ ref, onRequest, onExit }) => ( 16 | 17 | onRequest()} style={style.button}> 18 | FullScreen 19 | 20 | onExit()} style={style.button}> 21 | Screen 22 | 23 | 24 | )} 25 | 26 | 27 | 28 | 29 | {({ ref, onToggle }) => ( 30 | onToggle()} 34 | aria-hidden="true" 35 | role="button" 36 | tabIndex="0" 37 | > 38 | Click Here 39 | 40 | )} 41 | 42 | 43 | 44 | 45 | ); 46 | 47 | const style = { 48 | container: { 49 | alignItems: 'center', 50 | display: 'flex', 51 | flexFlow: 'column wrap', 52 | justifyContent: 'center', 53 | width: '100%', 54 | minHeight: '100%', 55 | padding: 16, 56 | }, 57 | title: { marginBottom: 0, textAlign: 'center' }, 58 | root: { width: '100%', display: 'flex', justifyContent: 'center' }, 59 | card: { 60 | boxShadow: `0px 1px 3px 0px rgba(0, 0, 0, 0.2), 61 | 0px 1px 1px 0px rgba(0, 0, 0, 0.14), 0px 2px 1px -1px rgba(0, 0, 0, 0.12)`, 62 | borderRadius: 2, 63 | width: 400, 64 | minWidth: '40%', 65 | maxWidth: '40%', 66 | backgroundColor: 'white', 67 | height: 400, 68 | padding: 16, 69 | boxSizing: 'border-box', 70 | marginRight: 40, 71 | }, 72 | screen: { 73 | backgroundColor: '#01579b', 74 | width: '100%', 75 | height: '100%', 76 | display: 'flex', 77 | alignItems: 'center', 78 | justifyContent: 'center', 79 | gap: 12, 80 | }, 81 | button: { 82 | backgroundColor: '#FFF', 83 | border: 0, 84 | borderRadius: 2, 85 | color: '#37474f', 86 | minWidth: 120, 87 | padding: 5, 88 | minHeight: 50, 89 | fontSize: 14, 90 | fontWeight: 600, 91 | }, 92 | image: { 93 | backgroundImage: 94 | 'url("https://images.pexels.com/photos/34950/pexels-photo.jpg?auto=compress&cs=tinysrgb&dpr=2")', 95 | backgroundRepeat: 'no-repeat', 96 | backgroundPosition: 'center', 97 | backgroundSize: '100% auto', 98 | width: '100%', 99 | height: '100%', 100 | cursor: 'pointer', 101 | display: 'flex', 102 | alignItems: 'center', 103 | justifyContent: 'center', 104 | }, 105 | imageText: { color: 'white', textShadow: '1px 1px 2px black' }, 106 | }; 107 | 108 | export default App; 109 | --------------------------------------------------------------------------------