├── .commitlintrc.json ├── .editorconfig ├── .eslintignore ├── .eslintrc.json ├── .github └── workflows │ ├── ci.yml │ ├── codeql-analysis.yml │ ├── deploy.yml │ └── lint.yml ├── .gitignore ├── .husky ├── pre-commit ├── pre-push └── skip.js ├── .prettierignore ├── .prettierrc.json ├── .reuse └── dep5 ├── LICENSE.txt ├── LICENSES └── Apache-2.0.txt ├── README.md ├── docs └── images │ └── UI5_logo_wide.png ├── package-lock.json ├── package.json ├── public ├── favicon.ico ├── index.html └── manifest.json ├── src ├── App.css ├── App.test.tsx ├── App.tsx ├── components │ ├── TodoItem.tsx │ └── TodoList.tsx ├── index.css ├── index.tsx ├── logo.png ├── react-app-env.d.ts ├── reportWebVitals.ts ├── setupTests.ts └── types │ └── index.ts └── tsconfig.json /.commitlintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["@commitlint/config-conventional"] 3 | } 4 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | [*] 8 | # We recommend you to keep these unchanged 9 | end_of_line = lf 10 | charset = utf-8 11 | trim_trailing_whitespace = true 12 | insert_final_newline = true 13 | 14 | # Change these settings to your own preference 15 | indent_style = tab 16 | 17 | [*.{yaml,yml,md,json,xml,properties}] 18 | indent_size = 2 19 | indent_style = space 20 | 21 | [*.md] 22 | trim_trailing_whitespace = false 23 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | # Ignore files by extension 2 | /**/*.svg 3 | /**/*.png 4 | /**/*.md 5 | 6 | # Additionally ignore files for linting 7 | /**/*.html 8 | /**/*.css 9 | /**/*.json 10 | /**/*.xml 11 | /**/*.properties 12 | /**/*.yaml 13 | /**/*.yml -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es6": true, 5 | "node": true 6 | }, 7 | "extends": "react-app" 8 | } 9 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | push: 4 | branches: 5 | - main 6 | pull_request: 7 | branches: 8 | - main 9 | jobs: 10 | check: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event." 14 | - run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!" 15 | - run: echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}." 16 | - name: Check out repository code 17 | uses: actions/checkout@v2.4.0 18 | - run: echo "💡 The ${{ github.repository }} repository has been cloned to the runner." 19 | - name: Setup Node.js environment 20 | uses: actions/setup-node@v2.4.1 21 | with: 22 | node-version: 16.x 23 | - name: Build 24 | run: | 25 | npm install 26 | npm run build 27 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL" 13 | 14 | on: 15 | push: 16 | branches: ["main"] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: ["main"] 20 | schedule: 21 | - cron: "41 12 * * 0" 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ubuntu-latest 27 | permissions: 28 | actions: read 29 | contents: read 30 | security-events: write 31 | 32 | strategy: 33 | fail-fast: false 34 | matrix: 35 | language: ["javascript"] 36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] 37 | # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support 38 | 39 | steps: 40 | - name: Checkout repository 41 | uses: actions/checkout@v3 42 | 43 | # Initializes the CodeQL tools for scanning. 44 | - name: Initialize CodeQL 45 | uses: github/codeql-action/init@v2 46 | with: 47 | languages: ${{ matrix.language }} 48 | # If you wish to specify custom queries, you can do so here or in a config file. 49 | # By default, queries listed here will override any specified in a config file. 50 | # Prefix the list here with "+" to use these queries and those in the config file. 51 | 52 | # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs 53 | # queries: security-extended,security-and-quality 54 | 55 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 56 | # If this step fails, then you should remove it and run the build manually (see below) 57 | - name: Autobuild 58 | uses: github/codeql-action/autobuild@v2 59 | 60 | # ℹ️ Command-line programs to run using the OS shell. 61 | # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun 62 | 63 | # If the Autobuild fails above, remove it and uncomment the following three lines. 64 | # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. 65 | 66 | # - run: | 67 | # echo "Run, Build Application using script" 68 | # ./location_of_script_within_repo/buildscript.sh 69 | 70 | - name: Perform CodeQL Analysis 71 | uses: github/codeql-action/analyze@v2 72 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: Deploy 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | jobs: 7 | deploy: 8 | runs-on: ubuntu-latest 9 | 10 | steps: 11 | - uses: actions/checkout@v3 12 | - uses: actions/setup-node@v3 13 | with: 14 | node-version: 16 15 | cache: "npm" 16 | 17 | - name: Build 18 | run: | 19 | npm install 20 | npm run build 21 | 22 | - name: Deploy 23 | uses: JamesIves/github-pages-deploy-action@v4.3.3 24 | with: 25 | branch: gh-pages # The branch the action should deploy to. 26 | folder: build # The folder the action should deploy. 27 | target-folder: ./ 28 | clean: true 29 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: Lint 2 | on: 3 | push: 4 | branches: 5 | - main 6 | pull_request: 7 | branches: 8 | - main 9 | jobs: 10 | check: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event." 14 | - run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!" 15 | - run: echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}." 16 | - name: Check out repository code 17 | uses: actions/checkout@v2.4.0 18 | - run: echo "💡 The ${{ github.repository }} repository has been cloned to the runner." 19 | - name: Setup Node.js environment 20 | uses: actions/setup-node@v2.4.1 21 | with: 22 | node-version: 16.x 23 | - name: Lint 24 | run: | 25 | npm install 26 | npm run lint 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | .idea 22 | npm-debug.log* 23 | yarn-debug.log* 24 | yarn-error.log* 25 | 26 | # Don't include private SSH key for deployment via Travis CI 27 | deploy_key 28 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npm run hooks:pre-commit -------------------------------------------------------------------------------- /.husky/pre-push: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npm run hooks:pre-push -------------------------------------------------------------------------------- /.husky/skip.js: -------------------------------------------------------------------------------- 1 | if (process.env.HUSKY_SKIP) { 2 | process.exit(0); 3 | } else { 4 | process.exit(1); 5 | } 6 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # Ignore files 2 | package-lock.json 3 | 4 | # Ignore files by extension 5 | /**/*.svg 6 | /**/*.png 7 | /**/*.md -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": false, 3 | "printWidth": 200, 4 | "endOfLine": "lf", 5 | "tabWidth": 4, 6 | "useTabs": true, 7 | "overrides": [ 8 | { 9 | "files": ["*.yaml", "*.yml", "*.md", "*.json", "*.xml", "*.properties"], 10 | "options": { 11 | "useTabs": false, 12 | "tabWidth": 2 13 | } 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /.reuse/dep5: -------------------------------------------------------------------------------- 1 | Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Upstream-Name: UI5 Webcomponents Sample with React 3 | Upstream-Contact: SAP OpenUI5 4 | Source: https://github.com/SAP-samples/ui5-webcomponents-sample-react 5 | Disclaimer: The code in this project may include calls to APIs (“API Calls”) of 6 | SAP or third-party products or services developed outside of this project 7 | (“External Products”). 8 | “APIs” means application programming interfaces, as well as their respective 9 | specifications and implementing code that allows software to communicate with 10 | other software. 11 | API Calls to External Products are not licensed under the open source license 12 | that governs this project. The use of such API Calls and related External 13 | Products are subject to applicable additional agreements with the relevant 14 | provider of the External Products. In no event shall the open source license 15 | that governs this project grant any rights in or to any External Products,or 16 | alter, expand or supersede any terms of the applicable additional agreements. 17 | If you have a valid license agreement with SAP for the use of a particular SAP 18 | External Product, then you may make use of any API Calls included in this 19 | project’s code for that SAP External Product, subject to the terms of such 20 | license agreement. If you do not have a valid license agreement for the use of 21 | a particular SAP External Product, then you may only make use of any API Calls 22 | in this project for that SAP External Product for your internal, non-productive 23 | and non-commercial test and evaluation of such API Calls. Nothing herein grants 24 | you any rights to use or access any SAP External Product, or provide any third 25 | parties the right to use of access any SAP External Product, through API Calls. 26 | 27 | 28 | Files: * 29 | Copyright: 2020 SAP SE or an SAP affiliate company and OpenUI5 contributors 30 | License: Apache-2.0 31 | 32 | Files: /deploy/deploy.sh 33 | Copyright: 2018 Domenic Denicola 34 | License: MIT -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | -------------------------------------------------------------------------------- /LICENSES/Apache-2.0.txt: -------------------------------------------------------------------------------- 1 | Apache License 2 | 3 | Version 2.0, January 2004 4 | 5 | http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, 6 | AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | 11 | 12 | "License" shall mean the terms and conditions for use, reproduction, and distribution 13 | as defined by Sections 1 through 9 of this document. 14 | 15 | 16 | 17 | "Licensor" shall mean the copyright owner or entity authorized by the copyright 18 | owner that is granting the License. 19 | 20 | 21 | 22 | "Legal Entity" shall mean the union of the acting entity and all other entities 23 | that control, are controlled by, or are under common control with that entity. 24 | For the purposes of this definition, "control" means (i) the power, direct 25 | or indirect, to cause the direction or management of such entity, whether 26 | by contract or otherwise, or (ii) ownership of fifty percent (50%) or more 27 | of the outstanding shares, or (iii) beneficial ownership of such entity. 28 | 29 | 30 | 31 | "You" (or "Your") shall mean an individual or Legal Entity exercising permissions 32 | granted by this License. 33 | 34 | 35 | 36 | "Source" form shall mean the preferred form for making modifications, including 37 | but not limited to software source code, documentation source, and configuration 38 | files. 39 | 40 | 41 | 42 | "Object" form shall mean any form resulting from mechanical transformation 43 | or translation of a Source form, including but not limited to compiled object 44 | code, generated documentation, and conversions to other media types. 45 | 46 | 47 | 48 | "Work" shall mean the work of authorship, whether in Source or Object form, 49 | made available under the License, as indicated by a copyright notice that 50 | is included in or attached to the work (an example is provided in the Appendix 51 | below). 52 | 53 | 54 | 55 | "Derivative Works" shall mean any work, whether in Source or Object form, 56 | that is based on (or derived from) the Work and for which the editorial revisions, 57 | annotations, elaborations, or other modifications represent, as a whole, an 58 | original work of authorship. For the purposes of this License, Derivative 59 | Works shall not include works that remain separable from, or merely link (or 60 | bind by name) to the interfaces of, the Work and Derivative Works thereof. 61 | 62 | 63 | 64 | "Contribution" shall mean any work of authorship, including the original version 65 | of the Work and any modifications or additions to that Work or Derivative 66 | Works thereof, that is intentionally submitted to Licensor for inclusion in 67 | the Work by the copyright owner or by an individual or Legal Entity authorized 68 | to submit on behalf of the copyright owner. For the purposes of this definition, 69 | "submitted" means any form of electronic, verbal, or written communication 70 | sent to the Licensor or its representatives, including but not limited to 71 | communication on electronic mailing lists, source code control systems, and 72 | issue tracking systems that are managed by, or on behalf of, the Licensor 73 | for the purpose of discussing and improving the Work, but excluding communication 74 | that is conspicuously marked or otherwise designated in writing by the copyright 75 | owner as "Not a Contribution." 76 | 77 | 78 | 79 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf 80 | of whom a Contribution has been received by Licensor and subsequently incorporated 81 | within the Work. 82 | 83 | 2. Grant of Copyright License. Subject to the terms and conditions of this 84 | License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, 85 | no-charge, royalty-free, irrevocable copyright license to reproduce, prepare 86 | Derivative Works of, publicly display, publicly perform, sublicense, and distribute 87 | the Work and such Derivative Works in Source or Object form. 88 | 89 | 3. Grant of Patent License. Subject to the terms and conditions of this License, 90 | each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, 91 | no-charge, royalty-free, irrevocable (except as stated in this section) patent 92 | license to make, have made, use, offer to sell, sell, import, and otherwise 93 | transfer the Work, where such license applies only to those patent claims 94 | licensable by such Contributor that are necessarily infringed by their Contribution(s) 95 | alone or by combination of their Contribution(s) with the Work to which such 96 | Contribution(s) was submitted. If You institute patent litigation against 97 | any entity (including a cross-claim or counterclaim in a lawsuit) alleging 98 | that the Work or a Contribution incorporated within the Work constitutes direct 99 | or contributory patent infringement, then any patent licenses granted to You 100 | under this License for that Work shall terminate as of the date such litigation 101 | is filed. 102 | 103 | 4. Redistribution. You may reproduce and distribute copies of the Work or 104 | Derivative Works thereof in any medium, with or without modifications, and 105 | in Source or Object form, provided that You meet the following conditions: 106 | 107 | (a) You must give any other recipients of the Work or Derivative Works a copy 108 | of this License; and 109 | 110 | (b) You must cause any modified files to carry prominent notices stating that 111 | You changed the files; and 112 | 113 | (c) You must retain, in the Source form of any Derivative Works that You distribute, 114 | all copyright, patent, trademark, and attribution notices from the Source 115 | form of the Work, excluding those notices that do not pertain to any part 116 | of the Derivative Works; and 117 | 118 | (d) If the Work includes a "NOTICE" text file as part of its distribution, 119 | then any Derivative Works that You distribute must include a readable copy 120 | of the attribution notices contained within such NOTICE file, excluding those 121 | notices that do not pertain to any part of the Derivative Works, in at least 122 | one of the following places: within a NOTICE text file distributed as part 123 | of the Derivative Works; within the Source form or documentation, if provided 124 | along with the Derivative Works; or, within a display generated by the Derivative 125 | Works, if and wherever such third-party notices normally appear. The contents 126 | of the NOTICE file are for informational purposes only and do not modify the 127 | License. You may add Your own attribution notices within Derivative Works 128 | that You distribute, alongside or as an addendum to the NOTICE text from the 129 | Work, provided that such additional attribution notices cannot be construed 130 | as modifying the License. 131 | 132 | You may add Your own copyright statement to Your modifications and may provide 133 | additional or different license terms and conditions for use, reproduction, 134 | or distribution of Your modifications, or for any such Derivative Works as 135 | a whole, provided Your use, reproduction, and distribution of the Work otherwise 136 | complies with the conditions stated in this License. 137 | 138 | 5. Submission of Contributions. Unless You explicitly state otherwise, any 139 | Contribution intentionally submitted for inclusion in the Work by You to the 140 | Licensor shall be under the terms and conditions of this License, without 141 | any additional terms or conditions. Notwithstanding the above, nothing herein 142 | shall supersede or modify the terms of any separate license agreement you 143 | may have executed with Licensor regarding such Contributions. 144 | 145 | 6. Trademarks. This License does not grant permission to use the trade names, 146 | trademarks, service marks, or product names of the Licensor, except as required 147 | for reasonable and customary use in describing the origin of the Work and 148 | reproducing the content of the NOTICE file. 149 | 150 | 7. Disclaimer of Warranty. Unless required by applicable law or agreed to 151 | in writing, Licensor provides the Work (and each Contributor provides its 152 | Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 153 | KIND, either express or implied, including, without limitation, any warranties 154 | or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR 155 | A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness 156 | of using or redistributing the Work and assume any risks associated with Your 157 | exercise of permissions under this License. 158 | 159 | 8. Limitation of Liability. In no event and under no legal theory, whether 160 | in tort (including negligence), contract, or otherwise, unless required by 161 | applicable law (such as deliberate and grossly negligent acts) or agreed to 162 | in writing, shall any Contributor be liable to You for damages, including 163 | any direct, indirect, special, incidental, or consequential damages of any 164 | character arising as a result of this License or out of the use or inability 165 | to use the Work (including but not limited to damages for loss of goodwill, 166 | work stoppage, computer failure or malfunction, or any and all other commercial 167 | damages or losses), even if such Contributor has been advised of the possibility 168 | of such damages. 169 | 170 | 9. Accepting Warranty or Additional Liability. While redistributing the Work 171 | or Derivative Works thereof, You may choose to offer, and charge a fee for, 172 | acceptance of support, warranty, indemnity, or other liability obligations 173 | and/or rights consistent with this License. However, in accepting such obligations, 174 | You may act only on Your own behalf and on Your sole responsibility, not on 175 | behalf of any other Contributor, and only if You agree to indemnify, defend, 176 | and hold each Contributor harmless for any liability incurred by, or claims 177 | asserted against, such Contributor by reason of your accepting any such warranty 178 | or additional liability. END OF TERMS AND CONDITIONS 179 | 180 | APPENDIX: How to apply the Apache License to your work. 181 | 182 | To apply the Apache License to your work, attach the following boilerplate 183 | notice, with the fields enclosed by brackets "[]" replaced with your own identifying 184 | information. (Don't include the brackets!) The text should be enclosed in 185 | the appropriate comment syntax for the file format. We also recommend that 186 | a file or class name and description of purpose be included on the same "printed 187 | page" as the copyright notice for easier identification within third-party 188 | archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | 194 | you may not use this file except in compliance with the License. 195 | 196 | You may obtain a copy of the License at 197 | 198 | http://www.apache.org/licenses/LICENSE-2.0 199 | 200 | Unless required by applicable law or agreed to in writing, software 201 | 202 | distributed under the License is distributed on an "AS IS" BASIS, 203 | 204 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 205 | 206 | See the License for the specific language governing permissions and 207 | 208 | limitations under the License. 209 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![UI5 logo](/docs/images/UI5_logo_wide.png) 2 | [![CI](https://github.com/SAP-samples/ui5-webcomponents-sample-react/actions/workflows/ci.yml/badge.svg)](https://github.com/SAP-samples/ui5-webcomponents-sample-react/actions/workflows/ci.yml) 3 | [![REUSE status](https://api.reuse.software/badge/github.com/SAP-samples/ui5-webcomponents-sample-react)](https://api.reuse.software/info/github.com/SAP-samples/ui5-webcomponents-sample-react) 4 | 5 | # UI5 Web Components React Sample Application 6 | 7 | 8 | [React](https://reactjs.org/) sample application to demonstrate the usage of the [UI5 Web Components](https://github.com/SAP/ui5-webcomponents). It shows how to bind properties, to subscribe to events, using nested components and the bootstrapped React build. 9 | 10 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 11 | 12 | ## Prerequisites 13 | - [Node.js](https://nodejs.org/) (**version 8.5 or higher** ⚠️) 14 | - [Yarn](https://yarnpkg.com/en/) (Optional usage of yarn) 15 | 16 | ## Getting started 17 | 1. [Clone this repository](https://help.github.com/articles/cloning-a-repository/) using the [GitHub Command line tool](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) and navigate into the downloaded directory. 18 | ```sh 19 | git clone https://github.com/SAP-samples/ui5-webcomponents-sample-react.git 20 | cd ui5-webcomponents-sample-react 21 | ``` 22 | 2. Install all dependencies 23 | ```sh 24 | npm install 25 | ``` 26 | 27 | 3. Start a local server and run the application. (The running application can be found here: http://localhost:3000) 28 | ```sh 29 | npm start 30 | ``` 31 | 32 | ## Noteworthy 33 | 34 | ### Consume UI5 Web Components 35 | Import the desired component(s) in your app to define the UI5 Web Component. 36 | 37 | For example, to use ```ui5-button``` you need to import it: 38 | 39 | ```js 40 | import "@ui5/webcomponents/dist/Button"; // loads ui5-button 41 | ``` 42 | 43 | Then, you can use the custom element in an HTML page: 44 | 45 | ```html 46 | Hello world! 47 | ``` 48 | 49 | ## Browser support 50 | 51 | Currently Chrome, Safari, Firefox and Edge (Chromium-based) support Web Components natively. 52 | 53 | 54 | ## Configure React Build 55 | When UI5 Web Components are used they include all of their translation files and CLDR data files in the application bundle. 56 | In order to decrease the bundle size of the application a custom Webpack configuration should be provided. 57 | (This configuration is already done for this project, so you will NOT be able to run ``` npm run eject```, because it is 58 | one time operation, which can NOT be reverted.) 59 | 60 | 1. Eject the react build with ```npm run eject``` 61 | 2. Open ```config/webpack.config.js``` file and add the following lines before the last loader: 62 | ```js 63 | { 64 | test: [/cldr\/.*\.json$/, /i18n\/.*\.json$/], 65 | loader: 'file-loader', 66 | options: { 67 | name: 'static/media/[name].[hash:8].[ext]', 68 | }, 69 | type: 'javascript/auto' 70 | }, 71 | // "file" loader makes sure those assets get served by WebpackDevServer. 72 | // When you `import` an asset, you get its (virtual) filename. 73 | // In production, they would get copied to the `build` folder. 74 | // This loader doesn't use a "test" so it will catch all modules 75 | // that fall through the other loaders. 76 | ``` 77 | 78 | ### Where is the npm package? 79 | - [UI5 Web Components](https://www.npmjs.com/package/@ui5/webcomponents) 80 | 81 | ## Limitations 82 | No limitations known. 83 | 84 | ## Known Issues 85 | No major bugs known. 86 | 87 | ## Support 88 | We welcome all comments, suggestions, questions, and bug reports. Please follow our [Support Guidelines](https://github.com/SAP/ui5-webcomponents/blob/main/SUPPORT.md#-content) on how to report an issue, or chat with us in the `#webcomponents` channel of the [OpenUI5 Community Slack](https://ui5-slack-invite.cfapps.eu10.hana.ondemand.com/). 89 | 90 | ## Contribute to UI5 Web Components 91 | Please check our [Contribution Guidelines](https://github.com/SAP/ui5-webcomponents/blob/main/CONTRIBUTING.md). 92 | -------------------------------------------------------------------------------- /docs/images/UI5_logo_wide.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-samples/ui5-webcomponents-sample-react/fe39fa7cd36aa05a2fbffd30db5c1b8d51bbbb40/docs/images/UI5_logo_wide.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ui5-webcomponents-sample-react", 3 | "version": "0.7.0", 4 | "homepage": "./", 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.17.0", 7 | "@testing-library/react": "^13.4.0", 8 | "@testing-library/user-event": "^13.5.0", 9 | "@types/jest": "^27.5.2", 10 | "@types/node": "^16.18.108", 11 | "@types/react": "^18.3.5", 12 | "@types/react-dom": "^18.3.0", 13 | "@ui5/webcomponents": "^2.2.0", 14 | "@ui5/webcomponents-base": "^2.2.0", 15 | "@ui5/webcomponents-fiori": "^2.2.0", 16 | "@ui5/webcomponents-icons": "^2.2.0", 17 | "eslint": "^8.57.0", 18 | "react": "^18.3.1", 19 | "react-dom": "^18.3.1", 20 | "react-scripts": "5.0.1", 21 | "typescript": "^4.9.5", 22 | "web-vitals": "^2.1.4" 23 | }, 24 | "scripts": { 25 | "start": "react-scripts start", 26 | "build": "react-scripts build", 27 | "test": "react-scripts test", 28 | "eject": "react-scripts eject", 29 | "lint": "eslint src", 30 | "lint:staged": "lint-staged", 31 | "lint:commit": "commitlint -e", 32 | "prettier": "prettier --write .", 33 | "prettier:staged": "pretty-quick --staged --verbose", 34 | "prepare": "node ./.husky/skip.js || husky install", 35 | "hooks:pre-commit": "run-s prettier:staged lint:staged", 36 | "hooks:pre-push": "run-s lint:commit" 37 | }, 38 | "eslintConfig": { 39 | "extends": [ 40 | "react-app", 41 | "react-app/jest" 42 | ] 43 | }, 44 | "browserslist": { 45 | "production": [ 46 | ">0.2%", 47 | "not dead", 48 | "not op_mini all" 49 | ], 50 | "development": [ 51 | "last 1 chrome version", 52 | "last 1 firefox version", 53 | "last 1 safari version" 54 | ] 55 | }, 56 | "devDependencies": { 57 | "@babel/plugin-proposal-private-property-in-object": "^7.21.11", 58 | "@commitlint/cli": "^17.0.2", 59 | "@commitlint/config-conventional": "^17.0.2", 60 | "husky": "^8.0.1", 61 | "lint-staged": "^13.0.0", 62 | "npm-run-all": "^4.1.5", 63 | "prettier": "^2.6.2", 64 | "pretty-quick": "^3.1.3" 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-samples/ui5-webcomponents-sample-react/fe39fa7cd36aa05a2fbffd30db5c1b8d51bbbb40/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 22 | UI5 Web Components React Sample Application 23 | 24 | 25 | 26 |
27 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": ".", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | height: 100%; 4 | } 5 | 6 | .app { 7 | height: 100%; 8 | background-color: var(--sapBackgroundColor); 9 | } 10 | 11 | .app-bar-theming-popover { 12 | width: 250px; 13 | } 14 | 15 | .app-bar-profile-popover { 16 | width: 250px; 17 | } 18 | 19 | .header-toolbar { 20 | position: sticky; 21 | z-index: 42; 22 | background-color: rgba(255, 255, 255, 0.6); 23 | box-shadow: 0 4px 5px -5px #0a6ed1; 24 | } 25 | 26 | .app-header-logo { 27 | height: 2rem; 28 | } 29 | 30 | .app-title { 31 | margin-inline-start: 1rem; 32 | } 33 | 34 | .app-content { 35 | height: calc(100% - 3rem); 36 | padding: 0 1rem; 37 | width: calc(100% - 2rem); 38 | } 39 | 40 | .create-todo-wrapper { 41 | display: flex; 42 | align-items: center; 43 | justify-content: center; 44 | padding: 2rem 1rem; 45 | margin: 2rem 0; 46 | box-sizing: border-box; 47 | background-color: var(--sapObjectHeader_Background); 48 | } 49 | 50 | .list-todos-wrapper { 51 | margin: 2rem 0; 52 | } 53 | 54 | .list-todos-panel { 55 | margin: 2rem 0; 56 | } 57 | 58 | .li-content-actions { 59 | display: flex; 60 | } 61 | 62 | .add-todo-element-width { 63 | width: auto; 64 | } 65 | 66 | #add-input { 67 | flex: auto; 68 | } 69 | 70 | #date-picker { 71 | margin: 0 0.5rem 0 0.5rem; 72 | } 73 | 74 | .li-content { 75 | display: flex; 76 | width: 100%; 77 | justify-content: space-between; 78 | align-items: center; 79 | } 80 | 81 | .li-content-text { 82 | overflow: hidden; 83 | text-overflow: ellipsis; 84 | white-space: nowrap; 85 | } 86 | 87 | .edit-btn { 88 | margin-inline-end: 1rem; 89 | } 90 | 91 | .dialog-content { 92 | max-width: 320px; 93 | padding: 2rem 2rem; 94 | } 95 | 96 | .date-edit-fields { 97 | display: flex; 98 | flex-direction: column; 99 | } 100 | 101 | #settings-dialog { 102 | max-width: 300px; 103 | } 104 | 105 | .dialog-footer { 106 | display: flex; 107 | justify-content: flex-end; 108 | padding: 0.25rem 0.25rem 0 0.25rem; 109 | border-top: 1px solid #d9d9d9; 110 | } 111 | 112 | .dialog-button { 113 | display: flex; 114 | justify-content: flex-end; 115 | margin-top: 0.625rem; 116 | margin-bottom: -0.425rem; 117 | } 118 | 119 | .dialog-footer-btn--cancel { 120 | margin-inline-end: 0.25rem; 121 | } 122 | 123 | .title-textarea { 124 | height: 100px; 125 | display: inline-block; 126 | width: 100%; 127 | } 128 | 129 | .date-edit-fields { 130 | margin-top: 1rem; 131 | } 132 | 133 | @media (max-width: 600px) { 134 | .create-todo-wrapper { 135 | flex-direction: column; 136 | } 137 | 138 | .add-todo-element-width { 139 | width: 100%; 140 | } 141 | 142 | #date-picker { 143 | margin: 0.25rem 0 0.25rem 0; 144 | width: 100%; 145 | } 146 | 147 | #add-input { 148 | margin-bottom: 0.25rem; 149 | width: 100%; 150 | } 151 | 152 | #add-button { 153 | margin-top: 0.25rem; 154 | width: 100%; 155 | } 156 | } 157 | 158 | .profile-settings, 159 | .help-header { 160 | display: flex; 161 | flex-direction: row; 162 | justify-content: flex-start; 163 | } 164 | 165 | .help-header { 166 | margin-inline-end: 2.5rem; 167 | } 168 | 169 | .profile-text { 170 | display: flex; 171 | flex-direction: column; 172 | justify-content: center; 173 | margin-inline-start: 1rem; 174 | margin-inline-end: 2rem; 175 | } 176 | 177 | .profile-settings-list { 178 | margin-top: 1.25rem; 179 | } 180 | 181 | .aligned { 182 | align-items: center; 183 | gap: 0.725rem; 184 | } 185 | 186 | .help-dialog-text { 187 | font-size: 0.875rem; 188 | } 189 | 190 | .profile-rtl-switch { 191 | width: 100%; 192 | display: flex; 193 | align-items: center; 194 | justify-content: space-between; 195 | } 196 | 197 | #header-title-align { 198 | margin: 1rem 0; 199 | gap: 0.225rem; 200 | } 201 | 202 | #header-logo-align { 203 | margin: 0.225rem 3.225rem 0.225rem 0; 204 | align-items: center; 205 | gap: 0.435rem; 206 | } 207 | 208 | #help-dialog::part(header) { 209 | justify-content: flex-start; 210 | } 211 | 212 | #completed-tasks { 213 | margin-top: 2rem; 214 | } 215 | 216 | hr { 217 | margin: 0.75rem 0; 218 | } 219 | -------------------------------------------------------------------------------- /src/App.test.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { render, screen } from "@testing-library/react"; 3 | import App from "./App"; 4 | 5 | test("renders learn react link", () => { 6 | render(); 7 | const linkElement = screen.getByText(/learn react/i); 8 | expect(linkElement).toBeInTheDocument(); 9 | }); 10 | -------------------------------------------------------------------------------- /src/App.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState, useRef, useEffect, useCallback } from "react"; 2 | import logo from "./logo.png"; 3 | import "./App.css"; 4 | import TodoList from "./components/TodoList"; 5 | 6 | import { TodoItem, EditingTodoItem } from "./types"; 7 | 8 | import applyDirection from "@ui5/webcomponents-base/dist/locale/applyDirection.js"; 9 | import { setTheme } from "@ui5/webcomponents-base/dist/config/Theme"; 10 | import "@ui5/webcomponents-base/dist/features/F6Navigation"; 11 | import "@ui5/webcomponents/dist/Button"; 12 | import "@ui5/webcomponents/dist/Title"; 13 | import "@ui5/webcomponents/dist/Input"; 14 | import "@ui5/webcomponents/dist/DatePicker"; 15 | import "@ui5/webcomponents/dist/List"; 16 | import "@ui5/webcomponents/dist/Link"; 17 | import "@ui5/webcomponents/dist/Label"; 18 | import "@ui5/webcomponents/dist/Panel"; 19 | import "@ui5/webcomponents/dist/Dialog"; 20 | import "@ui5/webcomponents/dist/Popover"; 21 | import "@ui5/webcomponents/dist/Tab"; 22 | import "@ui5/webcomponents/dist/TabContainer"; 23 | import "@ui5/webcomponents/dist/TextArea"; 24 | import "@ui5/webcomponents/dist/Switch"; 25 | import "@ui5/webcomponents-fiori/dist/ShellBar"; 26 | import "@ui5/webcomponents-fiori/dist/ShellBarItem"; 27 | import "@ui5/webcomponents-fiori/dist/Assets"; 28 | import "@ui5/webcomponents-icons/dist/palette.js"; 29 | import "@ui5/webcomponents-icons/dist/settings.js"; 30 | import "@ui5/webcomponents-icons/dist/sys-help.js"; 31 | import "@ui5/webcomponents-icons/dist/log.js"; 32 | import "@ui5/webcomponents-icons/dist/account.js"; 33 | import "@ui5/webcomponents-icons/dist/private.js"; 34 | import "@ui5/webcomponents-icons/dist/loan.js"; 35 | import "@ui5/webcomponents-icons/dist/globe.js"; 36 | 37 | import type Button from "@ui5/webcomponents/dist/Button"; 38 | import type Input from "@ui5/webcomponents/dist/Input"; 39 | import type DatePicker from "@ui5/webcomponents/dist/DatePicker"; 40 | import type TextArea from "@ui5/webcomponents/dist/TextArea"; 41 | import type List from "@ui5/webcomponents/dist/List"; 42 | import type ShellBar from "@ui5/webcomponents-fiori/dist/ShellBar"; 43 | import type Switch from "@ui5/webcomponents/dist/Switch"; 44 | import type ShellBarItem from "@ui5/webcomponents-fiori/dist/ShellBarItem"; 45 | import { ListItemClickEventDetail, ListSelectionChangeEventDetail } from "@ui5/webcomponents/dist/List"; 46 | import { ShellBarItemClickEventDetail } from "@ui5/webcomponents-fiori/dist/ShellBarItem"; 47 | import { ShellBarProfileClickEventDetail } from "@ui5/webcomponents-fiori/dist/ShellBar"; 48 | 49 | setTheme("sap_horizon"); 50 | 51 | function App() { 52 | const [todos, setTodos] = useState([ 53 | { 54 | text: "Get some carrots", 55 | id: 1, 56 | deadline: "27/7/2018", 57 | done: false, 58 | }, 59 | { 60 | text: "Do some magic", 61 | id: 2, 62 | deadline: "22/7/2018", 63 | done: false, 64 | }, 65 | { 66 | text: "Go to the gym", 67 | id: 3, 68 | deadline: "24/7/2018", 69 | done: false, 70 | }, 71 | { 72 | text: "Buy milk", 73 | id: 4, 74 | deadline: "30/7/2018", 75 | done: false, 76 | }, 77 | { 78 | text: "Eat some fruits", 79 | id: 5, 80 | deadline: "29/7/2018", 81 | done: true, 82 | }, 83 | ]); 84 | const [todoBeingEditted, setTodoBeingEditted] = useState({ 85 | id: -1, 86 | text: "", 87 | deadline: "", 88 | }); 89 | const [settingsDialogOpen, setSettingsDialogOpen] = useState(false); 90 | const [helpDialogOpen, setHelpDialogOpen] = useState(false); 91 | const [editDialogOpen, setEditDialogOpen] = useState(false); 92 | const [profilePopoverOpen, setProfilePopoverOpen] = useState(false); 93 | const [profilePopoverOpener, setProfilePopoverOpener] = useState(); 94 | const [themeSettingsPopoverOpen, setThemeSettingsPopoverOpen] = useState(false); 95 | const [themeSettingsPopoverOpener, setThemeSettingsPopoverOpener] = useState(); 96 | 97 | const themeChangeItem = useRef(), 98 | addButton = useRef