├── .all-contributorsrc
├── .babelrc
├── .gitignore
├── .nvmrc
├── .travis.yml
├── CONTRIBUTING.md
├── HOW-CREATE-A-HOOK.md
├── LICENSE
├── README.md
├── config
├── jest.js
└── webpack.js
├── docs
├── getting-started.md
├── useSlider.md
└── useTabs.md
├── package-lock.json
├── package.json
├── scripts
├── boilerplates
│ ├── useHook.js.boilerplate
│ ├── useHook.md.boilerplate
│ └── useHook.test.js.boilerplate
├── generate-docs.js
├── generate-hook.js
├── generate-test.js
└── lib
│ ├── docs.js
│ ├── helpers.js
│ ├── hook.js
│ └── test.js
├── src
├── hooks
│ ├── useSlider.js
│ └── useTabs.js
└── index.js
├── tests
└── hooks
│ ├── useSlider.test.js
│ └── useTabs.test.js
└── website
├── .gitignore
├── README.md
├── blog
├── 2016-03-11-blog-post.md
├── 2017-04-10-blog-post-two.md
├── 2017-09-25-testing-rss.md
├── 2017-09-26-adding-rss.md
└── 2017-10-24-new-version-1.0.0.md
├── core
└── Footer.js
├── i18n
└── en.json
├── package.json
├── pages
└── en
│ ├── help.js
│ ├── index.js
│ └── users.js
├── sidebars.json
├── siteConfig.js
├── static
├── css
│ └── custom.css
└── img
│ ├── docusaurus.svg
│ ├── favicon.png
│ ├── favicon
│ └── favicon.ico
│ └── oss_logo.png
└── yarn.lock
/.all-contributorsrc:
--------------------------------------------------------------------------------
1 | {
2 | "projectName": "react-ui-hooks",
3 | "projectOwner": "devthiago",
4 | "repoType": "github",
5 | "repoHost": "https://github.com",
6 | "files": [
7 | "README.md"
8 | ],
9 | "imageSize": 100,
10 | "commit": false,
11 | "contributors": [
12 | {
13 | "login": "devthiago",
14 | "name": "Thiago Alves Luiz",
15 | "avatar_url": "https://avatars0.githubusercontent.com/u/5190217?v=4",
16 | "profile": "http://thiagoalv.es",
17 | "contributions": [
18 | "infra",
19 | "code"
20 | ]
21 | },
22 | {
23 | "login": "jprask",
24 | "name": "João Pedro Raskopf",
25 | "avatar_url": "https://avatars3.githubusercontent.com/u/28638133?v=4",
26 | "profile": "http://lattes.cnpq.br/4287615973321905",
27 | "contributions": [
28 | "infra",
29 | "code"
30 | ]
31 | },
32 | {
33 | "login": "Lukyhenson",
34 | "name": "Tauan Tathiell",
35 | "avatar_url": "https://avatars0.githubusercontent.com/u/16005211?v=4",
36 | "profile": "https://www.linkedin.com/in/tauan-tathiell/",
37 | "contributions": [
38 | "doc"
39 | ]
40 | },
41 | {
42 | "login": "elainemattos",
43 | "name": "Elaine Mattos",
44 | "avatar_url": "https://avatars1.githubusercontent.com/u/10763483?v=4",
45 | "profile": "https://github.com/elainemattos",
46 | "contributions": [
47 | "doc"
48 | ]
49 | },
50 | {
51 | "login": "faogustavo",
52 | "name": "Gustavo Fão Valvassori",
53 | "avatar_url": "https://avatars3.githubusercontent.com/u/7588480?v=4",
54 | "profile": "http://gustavofao.com/",
55 | "contributions": [
56 | "infra"
57 | ]
58 | },
59 | {
60 | "login": "gutofoletto",
61 | "name": "Guto Foletto",
62 | "avatar_url": "https://avatars2.githubusercontent.com/u/1004681?v=4",
63 | "profile": "http://about.me/gutofoletto",
64 | "contributions": [
65 | "review"
66 | ]
67 | },
68 | {
69 | "login": "felipelovato",
70 | "name": "Felipe Lovato Flores",
71 | "avatar_url": "https://avatars3.githubusercontent.com/u/2296173?v=4",
72 | "profile": "https://github.com/felipelovato",
73 | "contributions": [
74 | "review"
75 | ]
76 | }
77 | ],
78 | "contributorsPerLine": 7
79 | }
80 |
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | "@babel/preset-env",
4 | "@babel/preset-react"
5 | ]
6 | }
--------------------------------------------------------------------------------
/.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 | /demo/dist
14 |
15 | # misc
16 | .vscode
17 | .DS_Store
18 | .env.local
19 | .env.development.local
20 | .env.test.local
21 | .env.production.local
22 | /umd
23 |
24 | npm-debug.log*
25 | yarn-debug.log*
26 | yarn-error.log*
27 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | v10.15.0
2 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: false
2 | language: node_js
3 |
4 | cache:
5 | directories:
6 | - node_modules/
7 |
8 | install:
9 | - npm
10 |
11 | script:
12 | - npm test
13 |
14 | after_script:
15 | - cat coverage/lcov.info | coveralls
16 |
17 | branches:
18 | only:
19 | - master
20 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # CONTRIBUTING
2 |
3 | Contributions are always welcome and we appreciate.
4 |
5 | ### Prerequisites
6 |
7 | - Git.
8 | - Node: any 10.x version.
9 | - `npm`: See [Npm web site for installation instructions](https://www.npmjs.com/get-npm).
10 | - Fork [react-ui-hooks repo](https://github.com/devthiago/react-ui-hooks) (for any contributions).
11 | - Get the project on your local machine, following the example: `git clone https://github.com/YOUR-GITHUB-USERNAME/react-ui-hooks.git`.
12 |
13 | #### Create a branch
14 |
15 | - `cd react-ui-hooks`
16 | - `git checkout master` from any folder in your local `react-ui-hooks` repository.
17 | - `git pull origin master` to ensure you have the latest main code.
18 | - `git checkout -b name-of-my-branch` to create a branch.
19 |
20 | ### Create new approaches or make changes
21 |
22 | - Make the changes or create a new Hook (Detailed explanation can be found at [How to Create a Hook](HOW-CREATE-A-HOOK.md)).
23 | - Save the files and check in the browser.
24 | - Make the tests.
25 | - Check if the tests are all passing `npm test`.
26 |
27 | ### Push it
28 |
29 | - `git add .`
30 | - `git commit -m "My message"` (replacing `My message` with a commit message like `It creates a new amazing React ui hook`) to stage and commit your changes
31 | - `git push my-fork-name name-of-my-branch`
32 | - Go to the [react-ui-hooks repo](https://github.com/devthiago/react-ui-hooks) and you should see recently pushed branches.
33 | - Follow GitHub's instructions.
34 | - If possible, include screenshots of visual changes.
35 |
36 | After you have submitted your pull request, we'll try to get back to you as soon as possible. We may suggest some changes or improvements.
37 |
38 | Thank you for contributing!
39 |
--------------------------------------------------------------------------------
/HOW-CREATE-A-HOOK.md:
--------------------------------------------------------------------------------
1 | # How to Create a Hook
2 |
3 | The purpose of this guide is to help you to create your own UI Hooks.
4 |
5 | ------------
6 |
7 | ### Prerequisites
8 |
9 | - Node: any 10.x version.
10 | - `npm` installed.
11 | - Fork [react-ui-hooks repo](https://github.com/devthiago/react-ui-hooks) (for any contributions).
12 | - Get the project on your local machine, following the example: `git clone https://github.com/YOUR-GITHUB-USERNAME/react-ui-hooks.git`.
13 |
14 | ------------
15 |
16 | #### Creating a Hook
17 |
18 | - First things first, if you want to create a new hook, you have to give it a name that starts with `use` and then the name of the hook, such as useModal, useSlider, etc.
19 | - If you try to create a hook without this pattern, you'll get an error.
20 |
21 | ------------
22 |
23 | #### Create a Hook file
24 |
25 | The `npm run generate:hook` command create 3 files:
26 |
27 | - A hook file ***useExample.js***
28 | - The tests file ***useExample.test.js***
29 | - The documentation file ***useExample.md***
30 |
31 | The hook and its tests files must be updated manually, the documentation file can be updated all at once by using the `npm run generate:docs` command.
32 |
33 | ------------
34 |
35 | ### How to create a .js Hook file:
36 |
37 | - Open your shell and run the command:
38 |
39 | ```bash
40 | npm run generate:hook useExample
41 | ```
42 |
43 | - ##### **After you run the command, you'll get:**
44 |
45 | ***useExample.js*** on `src/hooks/`
46 |
47 | ***useExample.test.js*** on `src/tests/hooks`
48 |
49 | ***useExample.md*** on `docs/`
50 |
51 | ------------
52 |
53 | ### Create a new react hook unit test
54 |
55 | If you've created your hook manually you can generate its unit test file with the command:
56 |
57 | ```bash
58 | npm run generate:test useExample.js
59 | ```
60 |
61 | ------------
62 |
63 | ### Create a new react hook doc:
64 |
65 | You can get the doc file of your hook created automaticaly as well!
66 |
67 | ```bash
68 | npm run generate:docs useExample.js
69 | ```
70 |
71 | ------------
72 |
73 | ### Generate docs for all react hooks:
74 |
75 | As you update the hooks and tests frequently there's a need to update the documentation, so you can do it for all of the hooks with:
76 |
77 | ```bash
78 | npm run generate:docs
79 | ```
80 |
81 | This command scans your hooks and its tests to generate the documentation.
82 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Thiago Alves Luiz
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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
React UI Hooks
3 |
4 |
5 | [](#contributors)
6 | [](https://travis-ci.org/devthiago/react-ui-hooks)
7 | [](https://coveralls.io/github/devthiago/react-ui-hooks?branch=master)
8 |
9 | Simple repository of React hooks for building UI components
10 |
11 | ## The Problem
12 |
13 | Before we have React Hooks we had to separate components into logic and view ones, if we would like to share IU logic like a component for tabs. Another way to do that is using components built over CSS frameworks like Bootstrap or Materialize, but we have to change a bunch of style if we want to create our own style. What it means is that style should be unique, your product/application should have an unique design. However, the logic for creating UI components is basically the same.
14 |
15 | ## This Solution
16 |
17 | The `react-ui-hooks` is a repository of React Hooks for UI logic. The main idea on this approach is to share and collaborate hooks to became building UI components easier and to try not "reinventing the wheel" one more time (although be doing this 🧐). As well as writing less of the same logic as always, this project also aims to help teams write less CSS, since we can avoid too much use of unnecessary CSS that comes with components/UI third part libraries.
18 |
19 | ## Example
20 |
21 | ```javascript
22 | import React from 'react'
23 | import { useSlider } from 'react-ui-hooks'
24 | import './style.scss'
25 |
26 | const setSlideClassname = (isActive, type = 'slide') => {
27 | const className = `carousel__${type}`
28 | if (isActive) {
29 | return `${className} ${className}--active`
30 | }
31 | return className
32 | }
33 |
34 | const createSlides = activeSlide => (slide, index) => (
35 |
40 | )
41 |
42 | const createSlideIndicators = (activeSlide, goToSlide = () => null) => (
43 | (slide, index) => (
44 |
45 | goToSlide(index)}
49 | />
50 |
51 | )
52 | )
53 |
54 | const Carousel = ({ children, ...config }) => {
55 | const {
56 | activeSlide,
57 | nextSlide,
58 | prevSlide,
59 | goToSlide,
60 | goToNextSlide,
61 | goToPrevSlide
62 | } = useSlider(children.length, config)
63 |
64 | return (
65 |
91 | )
92 | }
93 |
94 | export default Carousel
95 | ```
96 |
97 | ## Contributing
98 |
99 | - [How to Start Contributing](CONTRIBUTING.md)
100 | - [How to Create a New Hook](HOW-CREATE-A-HOOK.md)
101 |
102 | ## Contributors
103 |
104 | Thanks goes to these wonderful people ([emoji key](https://github.com/all-contributors/all-contributors#emoji-key)):
105 |
106 |
107 |
108 |
119 |
120 |
121 |
122 | This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
123 |
--------------------------------------------------------------------------------
/config/jest.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 |
3 | module.exports = {
4 | rootDir: path.join(__dirname, '..'),
5 | collectCoverage: true,
6 | collectCoverageFrom: [
7 | "./src/**/*.{js,jsx}",
8 | "!./src/index.js"
9 | ],
10 | moduleNameMapper: {
11 | "^@hooks(.*)$": "/src/hooks$1"
12 | },
13 | coverageDirectory: 'coverage',
14 | verbose: true,
15 | testRegex: '(/tests/.*\\.(test|spec))\\.jsx?$',
16 | moduleFileExtensions: ['js', 'json', 'jsx', 'node'],
17 | coverageThreshold: {
18 | global: {
19 | branches: 30,
20 | functions: 90,
21 | lines: 90,
22 | statements: 90
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/config/webpack.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 |
3 | const config = {
4 | resolve: {
5 | alias: {
6 | ['@hooks']: path.resolve(__dirname, '../src/hooks')
7 | }
8 | },
9 | module: {
10 | rules: [
11 | {
12 | test: /\.(js|jsx)$/,
13 | exclude: /node_modules/,
14 | use: {
15 | loader: "babel-loader"
16 | }
17 | }
18 | ]
19 | }
20 | };
21 |
22 | module.exports = (env, argv) => config;
23 |
--------------------------------------------------------------------------------
/docs/getting-started.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: getting-started
3 | title: Getting Started
4 | sidebar_label: Getting Started
5 | ---
6 |
7 | Check the [documentation](https://docusaurus.io) for how to use Docusaurus.
8 |
9 | ## Lorem
10 |
11 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus elementum massa eget nulla aliquet sagittis. Proin odio tortor, vulputate ut odio in, ultrices ultricies augue. Cras ornare ultrices lorem malesuada iaculis. Etiam sit amet libero tempor, pulvinar mauris sed, sollicitudin sapien.
12 |
13 | ## Mauris In Code
14 |
15 | ```
16 | Mauris vestibulum ullamcorper nibh, ut semper purus pulvinar ut. Donec volutpat orci sit amet mauris malesuada, non pulvinar augue aliquam. Vestibulum ultricies at urna ut suscipit. Morbi iaculis, erat at imperdiet semper, ipsum nulla sodales erat, eget tincidunt justo dui quis justo. Pellentesque dictum bibendum diam at aliquet. Sed pulvinar, dolor quis finibus ornare, eros odio facilisis erat, eu rhoncus nunc dui sed ex. Nunc gravida dui massa, sed ornare arcu tincidunt sit amet. Maecenas efficitur sapien neque, a laoreet libero feugiat ut.
17 | ```
18 |
19 | ## Nulla
20 |
21 | Nulla facilisi. Maecenas sodales nec purus eget posuere. Sed sapien quam, pretium a risus in, porttitor dapibus erat. Sed sit amet fringilla ipsum, eget iaculis augue. Integer sollicitudin tortor quis ultricies aliquam. Suspendisse fringilla nunc in tellus cursus, at placerat tellus scelerisque. Sed tempus elit a sollicitudin rhoncus. Nulla facilisi. Morbi nec dolor dolor. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras et aliquet lectus. Pellentesque sit amet eros nisi. Quisque ac sapien in sapien congue accumsan. Nullam in posuere ante. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Proin lacinia leo a nibh fringilla pharetra.
22 |
23 | ## Orci
24 |
25 | Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Proin venenatis lectus dui, vel ultrices ante bibendum hendrerit. Aenean egestas feugiat dui id hendrerit. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur in tellus laoreet, eleifend nunc id, viverra leo. Proin vulputate non dolor vel vulputate. Curabitur pretium lobortis felis, sit amet finibus lorem suscipit ut. Sed non mollis risus. Duis sagittis, mi in euismod tincidunt, nunc mauris vestibulum urna, at euismod est elit quis erat. Phasellus accumsan vitae neque eu placerat. In elementum arcu nec tellus imperdiet, eget maximus nulla sodales. Curabitur eu sapien eget nisl sodales fermentum.
26 |
27 | ## Phasellus
28 |
29 | Phasellus pulvinar ex id commodo imperdiet. Praesent odio nibh, sollicitudin sit amet faucibus id, placerat at metus. Donec vitae eros vitae tortor hendrerit finibus. Interdum et malesuada fames ac ante ipsum primis in faucibus. Quisque vitae purus dolor. Duis suscipit ac nulla et finibus. Phasellus ac sem sed dui dictum gravida. Phasellus eleifend vestibulum facilisis. Integer pharetra nec enim vitae mattis. Duis auctor, lectus quis condimentum bibendum, nunc dolor aliquam massa, id bibendum orci velit quis magna. Ut volutpat nulla nunc, sed interdum magna condimentum non. Sed urna metus, scelerisque vitae consectetur a, feugiat quis magna. Donec dignissim ornare nisl, eget tempor risus malesuada quis.
30 |
--------------------------------------------------------------------------------
/docs/useSlider.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: use-slider
3 | title: useSlider
4 | sidebar_label: useSlider
5 | ---
6 |
7 | ## Lorem
8 |
9 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus elementum massa eget nulla aliquet sagittis. Proin odio tortor, vulputate ut odio in, ultrices ultricies augue. Cras ornare ultrices lorem malesuada iaculis. Etiam sit amet libero tempor, pulvinar mauris sed, sollicitudin sapien.
10 |
11 |
12 |
13 | ## HookResponse
14 |
15 | Type: [object][1]
16 |
17 | ### Properties
18 |
19 | - `activeSlide` **[number][2]** Array index referred to the current active slide.
20 | - `nextSlide` **([number][2] | null)** Array index referred to the next slide. If it's null, the active slide is the last. If it's smaller than the active slide, the Slider component is an infinite one.
21 | - `prevSlide` **([number][2] | null)** Array index referred to the previous slide. If it's null, the active slide is the first. If it's bigger than the active slide, the Slider component is an infinite one.
22 | - `goToSlide` **function ([number][2])** Function responsible for changing the slider state, moving to the desired slide. This function waits for the slide index number as argument.
23 | - `goToNextSlide` **function ()** Function to change the slider state, moving to the next slide.
24 | - `goToPrevSlide` **function ()** Function to change the slider state, moving to the previous slide.
25 |
26 | ## useSlider
27 |
28 | React hook to help on creation of slider/carousel components.
29 |
30 | ### Parameters
31 |
32 | - `length` **[number][2]** Slides/slider items amount.
33 | - `config` **[object][1]** Slider configuration object.
34 | - `config.initialSlide` **[number][2]** Which slide will be the first one. (optional, default `0`)
35 | - `config.infinite` **[boolean][3]** If it's true the slider will reach the first slide when try move forward after has been arrived to the last one. Same will happen if it's on the first slide and try move backward, it will reach the last one. (optional, default `true`)
36 | - `config.autoplay` **[boolean][3]** If it's true the slider will start swapping slides automatically. (optional, default `false`)
37 | - `config.autoplaySpeed` **[number][2]** Defines how fast (ms) the slides will be swapped when the autoplay is true. (optional, default `200`)
38 | - `config.slidesToShow` **[number][2]** How many slides will be shown at the same moment. (optional, default `1`)
39 | - `config.slidesToScroll` **[number][2]** How many slides will be swapped when the change action (go forward or backward) is triggered. (optional, default `1`)
40 |
41 | Returns **[HookResponse][4]** Hook response to be used within your component like props
42 |
43 | **Meta**
44 |
45 | - **author**: Thiago Alves <me@thiagoalv.es>
46 | - **license**: https://tldrlegal.com/license/mit-license MIT
47 |
48 | [1]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object
49 |
50 | [2]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number
51 |
52 | [3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean
53 |
54 | [4]: #hookresponse
55 |
--------------------------------------------------------------------------------
/docs/useTabs.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: use-tabs
3 | title: useTabs
4 | sidebar_label: useTabs
5 | ---
6 |
7 | ## Lorem
8 |
9 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus elementum massa eget nulla aliquet sagittis. Proin odio tortor, vulputate ut odio in, ultrices ultricies augue. Cras ornare ultrices lorem malesuada iaculis. Etiam sit amet libero tempor, pulvinar mauris sed, sollicitudin sapien.
10 |
11 |
12 |
13 | ## useTabs
14 |
15 | React hook to help create a tabs component. The hook will
16 | keep track of tab indexes that can be enabled or disabled.
17 |
18 | Type: [object][1]
19 |
20 | ### Parameters
21 |
22 | - `config` **[object][1]** A configuration object
23 | - `config.initialTab` **[number][2]** The initially selected tab index. (optional, default `0`)
24 | - `config.initialDisabledTabs` **[array][3]** An array with initially disabled tab indexes. (optional, default `[]`)
25 |
26 | ### Properties
27 |
28 | - `activeTab` **[number][2]** The index of the current active tab.
29 | - `selectTab` **function ()** Change the current active tab index.
30 | - `disabledTabs` **[array][3]** Includes indexes of all disabled tabs.
31 | - `isEnabled` **function ([number][2])** Returns true for enabled indexes.
32 | - `isDisabled` **function ([number][2])** Returns true for disabled indexes.
33 | - `enableTab` **function ([number][2])** For enabling a tab.
34 | - `disableTab` **function ([number][2])** For disabling a tab./\*\*
35 |
36 | Returns **HookResponse** Hook response to be used within your component like props.
37 |
38 | **Meta**
39 |
40 | - **author**: João Pedro R. D. Saldanha <jprasys@gmail.com>
41 | - **license**: https://tldrlegal.com/license/mit-license MIT
42 |
43 | [1]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object
44 |
45 | [2]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number
46 |
47 | [3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array
48 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-ui-hooks",
3 | "version": "0.1.0",
4 | "description": "React hooks for UI components building",
5 | "main": "build/index.js",
6 | "module": "build/index.js",
7 | "engines" : {
8 | "node" : ">=10.15.0"
9 | },
10 | "scripts": {
11 | "start": "",
12 | "test": "jest --config=./config/jest.js",
13 | "build": "webpack --mode=production --config=./config/webpack.js",
14 | "generate:hook": "node ./scripts/generate-hook.js",
15 | "generate:docs": "node ./scripts/generate-docs.js",
16 | "generate:test": "node ./scripts/generate-test.js"
17 | },
18 | "peerDependencies": {
19 | "react": "16.8.x"
20 | },
21 | "devDependencies": {
22 | "@babel/core": "^7.2.2",
23 | "@babel/preset-env": "^7.3.1",
24 | "@babel/preset-react": "^7.0.0",
25 | "babel-jest": "^24.1.0",
26 | "babel-loader": "^8.0.5",
27 | "coveralls": "^3.0.3",
28 | "documentation": "^9.1.1",
29 | "jest": "^24.1.0",
30 | "jest-dom": "^3.1.2",
31 | "react": "^16.8.0",
32 | "react-dom": "^16.8.0",
33 | "react-hooks-testing-library": "^0.3.6",
34 | "webpack": "^4.29.0",
35 | "webpack-cli": "^3.2.1"
36 | },
37 | "author": "Thiago Alves ",
38 | "license": "MIT",
39 | "homepage": "https://github.com/devthiago/react-ui-hooks",
40 | "repository": "https://github.com/devthiago/react-ui-hooks",
41 | "keywords": [
42 | "ui",
43 | "user",
44 | "interface",
45 | "react",
46 | "hook",
47 | "hooks",
48 | "react-hook",
49 | "react-hooks"
50 | ]
51 | }
52 |
--------------------------------------------------------------------------------
/scripts/boilerplates/useHook.js.boilerplate:
--------------------------------------------------------------------------------
1 | import { useState, useEffect } from 'react'
2 |
3 | /**
4 | * @typedef {object} HookResponse
5 | * @property {number} propNumber - [description]
6 | * @property {string} propString - [description]
7 | * @property {function(number)} propFunction - [Function with a number arg]
8 | */
9 |
10 | /**
11 | * @function
12 | * @name <%=HOOK_NAME%>
13 | * @description React hook description.
14 | * @author <%=HOOK_AUTHOR_NAME%> <<%=HOOK_AUTHOR_EMAIL%>>
15 | * @license https://tldrlegal.com/license/mit-license MIT
16 | *
17 | * @param {number} numberVar - [description]
18 | * @param {object} config - [description]
19 | * @param {number} [config.numberProp] - [description]
20 | * @param {boolean} [config.booleanProp] - [description]
21 | *
22 | * @return {HookResponse} Hook response to be used within your component like props
23 | */
24 | export default function <%=HOOK_NAME%>() {
25 | // state
26 | const [state, setState] = useState(null)
27 |
28 | useEffect(() => {
29 | // didMout and didUpdate
30 | return () => {
31 | //willUnmount
32 | }
33 | })
34 |
35 | return {
36 | foo: 'bar'
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/scripts/boilerplates/useHook.md.boilerplate:
--------------------------------------------------------------------------------
1 | ---
2 | id: <%=HOOK_ID%>
3 | title: <%=HOOK_NAME%>
4 | sidebar_label: <%=HOOK_NAME%>
5 | ---
6 |
7 | ## Lorem
8 |
9 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus elementum massa eget nulla aliquet sagittis. Proin odio tortor, vulputate ut odio in, ultrices ultricies augue. Cras ornare ultrices lorem malesuada iaculis. Etiam sit amet libero tempor, pulvinar mauris sed, sollicitudin sapien.
10 |
11 |
--------------------------------------------------------------------------------
/scripts/boilerplates/useHook.test.js.boilerplate:
--------------------------------------------------------------------------------
1 | import { renderHook } from 'react-hooks-testing-library'
2 | import <%=HOOK_NAME%> from '@hooks/<%=HOOK_NAME%>'
3 |
4 | describe('<%=HOOK_NAME%>()', () => {
5 | test('Describe what you are testing', () => {
6 | const { result } = renderHook(() => <%=HOOK_NAME%>())
7 | const { prop } = result.current
8 | expect(prop).toBeTruthy()
9 | })
10 | })
11 |
--------------------------------------------------------------------------------
/scripts/generate-docs.js:
--------------------------------------------------------------------------------
1 | require('./lib/docs.js')(process.argv[2]);
2 |
--------------------------------------------------------------------------------
/scripts/generate-hook.js:
--------------------------------------------------------------------------------
1 | require('./lib/hook.js')(process.argv[2]);
2 |
--------------------------------------------------------------------------------
/scripts/generate-test.js:
--------------------------------------------------------------------------------
1 | require('./lib/test.js')(process.argv[2]);
2 |
--------------------------------------------------------------------------------
/scripts/lib/docs.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const documentation = require('documentation');
3 | const {
4 | hookDir,
5 | docContentBreakPoint,
6 | boilerplateFile,
7 | createHookRefs,
8 | getHookInfo,
9 | isValidFile,
10 | replaceBoilerplateVariables
11 | } = require('./helpers.js');
12 |
13 | const editMarkdownFile = (file, content = '') => {
14 | let output = '';
15 | if (!fs.existsSync(file.md)) {
16 | console.log('\x1b[35m%s\x1b[0m', `✏️ Creating doc file for ${file.name} hook...`);
17 | const boilerplate = fs.readFileSync(boilerplateFile('useHook.md'), 'utf8');
18 | output = replaceBoilerplateVariables(boilerplate, getHookInfo(file));
19 | } else {
20 | console.log('\x1b[35m%s\x1b[0m', `✏️ Editing ${file.name} hook doc file...`);
21 | const current = fs.readFileSync(file.md, 'utf8');
22 | output = current.split(docContentBreakPoint)[0];
23 | }
24 | const newContent = `${output}${content}`;
25 | fs.writeFileSync(file.md, newContent);
26 | console.log('\x1b[32m%s\x1b[0m', `✅ DONE! ${file.md}`);
27 | return newContent;
28 | };
29 |
30 | const generateDoc = file => documentation.build([file.js], { shallow: false })
31 | .then(documentation.formats.md)
32 | .then(output => editMarkdownFile(file, output));
33 |
34 | const exec = (filename = null) => {
35 | if (filename) {
36 | const file = createHookRefs(filename);
37 | if (isValidFile(filename) && fs.existsSync(file.js)) {
38 | generateDoc(file);
39 | } else {
40 | console.error('\x1b[31m%s\x1b[0m', `🚫 ${filename} doesn't exist in ${hookDir}`);
41 | }
42 | } else {
43 | console.log('\x1b[33m%s\x1b[0m', `🔍 Looking for React hooks in ${hookDir}...`);
44 | fs.readdir(hookDir, (err, files) => {
45 | const hooks = files.reduce((acc, cur) => {
46 | if (isValidFile(cur)) {
47 | acc.push(createHookRefs(cur));
48 | }
49 | return acc;
50 | }, []);
51 |
52 | if (hooks.length > 0) {
53 | hooks.forEach(generateDoc);
54 | }
55 | });
56 | }
57 | };
58 |
59 | module.exports = exec;
60 |
--------------------------------------------------------------------------------
/scripts/lib/helpers.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 |
3 | const hookDir = path.join(__dirname, '../../src/hooks');
4 | const docsDir = path.join(__dirname, '../../docs');
5 | const testsDir = path.join(__dirname, '../../tests/hooks');
6 | const boilerplatesDir = path.join(__dirname, '../boilerplates');
7 |
8 | const docContentBreakPoint = '';
9 |
10 | const hookFile = file => `${hookDir}/${file}`;
11 | const docFile = file => `${docsDir}/${file}.md`;
12 | const testFile = file => `${testsDir}/${file}.test.js`;
13 | const boilerplateFile = file => `${boilerplatesDir}/${file}.boilerplate`;
14 |
15 | const removeExt = file => file.slice(0,-3);
16 | const createHookNameID = name => `use-${name.split('use')[1].toLowerCase()}`;
17 |
18 | const createHookRefs = file => ({
19 | name: removeExt(file),
20 | id: createHookNameID(removeExt(file)),
21 | js: hookFile(file),
22 | md: docFile(removeExt(file)),
23 | test: testFile(removeExt(file))
24 | });
25 |
26 | const getHookInfo = fileRef => ({
27 | ...fileRef,
28 | author: 'Thiago Alves',
29 | email: 'taltk9@gmail.com'
30 | });
31 |
32 | const isValidFile = file => file.indexOf('use') !== -1 && file.indexOf('.js') !== -1;
33 |
34 | const replaceBoilerplateVariables = (string = '', obj = {}) => {
35 | return string
36 | .replace(new RegExp('<%=HOOK_NAME%>', 'gi'), obj.name)
37 | .replace(new RegExp('<%=HOOK_ID%>', 'gi'), obj.id)
38 | .replace(new RegExp('<%=HOOK_AUTHOR_NAME%>', 'gi'), obj.author)
39 | .replace(new RegExp('<%=HOOK_AUTHOR_EMAIL%>', 'gi'), obj.email);
40 | };
41 |
42 | module.exports = {
43 | hookDir,
44 | docsDir,
45 | boilerplatesDir,
46 | docContentBreakPoint,
47 | hookFile,
48 | docFile,
49 | boilerplateFile,
50 | removeExt,
51 | createHookNameID,
52 | createHookRefs,
53 | getHookInfo,
54 | isValidFile,
55 | replaceBoilerplateVariables
56 | };
57 |
--------------------------------------------------------------------------------
/scripts/lib/hook.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const generateDoc = require('./docs.js');
3 | const generateTest = require('./test.js');
4 | const {
5 | boilerplateFile,
6 | createHookRefs,
7 | getHookInfo,
8 | isValidFile,
9 | replaceBoilerplateVariables
10 | } = require('./helpers.js');
11 |
12 | const generateHook = file => {
13 | if (fs.existsSync(file.js)) {
14 | console.error('\x1b[33m%s\x1b[0m', `⚠️ ${file.name}.js already exists`);
15 | return null;
16 | } else {
17 | console.log('\x1b[35m%s\x1b[0m', `✏️ Creating JavaScript file for ${file.name} hook...`);
18 | const boilerplate = fs.readFileSync(boilerplateFile('useHook.js'), 'utf8');
19 | const content = replaceBoilerplateVariables(boilerplate, getHookInfo(file));
20 | fs.writeFileSync(file.js, content);
21 | console.log('\x1b[32m%s\x1b[0m', `✅ DONE! ${file.js}`);
22 | return content;
23 | }
24 | };
25 |
26 | const exec = (filename = null) => {
27 | if (filename) {
28 | const jsFile = `${filename}.js`;
29 | if (isValidFile(jsFile)) {
30 | const file = createHookRefs(jsFile);
31 | if (generateHook(file)) {
32 | generateTest(jsFile);
33 | generateDoc(jsFile);
34 | }
35 | } else {
36 | console.error('\x1b[31m%s\x1b[0m', `🚫 ${filename} isn't a valid hook name`);
37 | }
38 | } else {
39 | console.log('\x1b[33m%s\x1b[0m', `⚠️ You have to say the desired hook name.`);
40 | }
41 | };
42 |
43 | module.exports = exec;
44 |
--------------------------------------------------------------------------------
/scripts/lib/test.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const {
3 | boilerplateFile,
4 | createHookRefs,
5 | getHookInfo,
6 | isValidFile,
7 | replaceBoilerplateVariables
8 | } = require('./helpers.js');
9 |
10 | const generateTest = file => {
11 | if (fs.existsSync(file.test)) {
12 | console.error('\x1b[33m%s\x1b[0m', `⚠️ ${file.test} already exists`);
13 | return null;
14 | } else {
15 | console.log('\x1b[35m%s\x1b[0m', `✏️ Creating JavaScript test file for ${file.name} hook...`);
16 | const boilerplate = fs.readFileSync(boilerplateFile('useHook.test.js'), 'utf8');
17 | const content = replaceBoilerplateVariables(boilerplate, getHookInfo(file));
18 | fs.writeFileSync(file.test, content);
19 | console.log('\x1b[32m%s\x1b[0m', `✅ DONE! ${file.test}`);
20 | return content;
21 | }
22 | };
23 |
24 | const exec = (filename = null) => {
25 | if (filename) {
26 | const file = createHookRefs(filename);
27 | if (isValidFile(filename) && fs.existsSync(file.js)) {
28 | generateTest(file);
29 | } else {
30 | console.error('\x1b[31m%s\x1b[0m', `🚫 ${filename} doesn't exist in ${hookDir}`);
31 | }
32 | } else {
33 | console.log('\x1b[33m%s\x1b[0m', `⚠️ You have to say the desired hook name.`);
34 | }
35 | };
36 |
37 | module.exports = exec;
38 |
--------------------------------------------------------------------------------
/src/hooks/useSlider.js:
--------------------------------------------------------------------------------
1 | import { useState, useEffect } from 'react'
2 |
3 | const defaultConfig = {
4 | initialSlide: 0,
5 | infinite: true,
6 | autoplay: false,
7 | autoplaySpeed: 2000,
8 | slidesToShow: 1,
9 | slidesToScroll: 1
10 | }
11 |
12 | /**
13 | * @typedef {object} HookResponse
14 | * @property {number} activeSlide - Array index referred to the current active slide.
15 | * @property {(number|null)} nextSlide - Array index referred to the next slide. If it's null, the active slide is the last. If it's smaller than the active slide, the Slider component is an infinite one.
16 | * @property {(number|null)} prevSlide - Array index referred to the previous slide. If it's null, the active slide is the first. If it's bigger than the active slide, the Slider component is an infinite one.
17 | * @property {function(number)} goToSlide - Function responsible for changing the slider state, moving to the desired slide. This function waits for the slide index number as argument.
18 | * @property {function()} goToNextSlide - Function to change the slider state, moving to the next slide.
19 | * @property {function()} goToPrevSlide - Function to change the slider state, moving to the previous slide.
20 | */
21 |
22 | /**
23 | * @function
24 | * @name useSlider
25 | * @description React hook to help on creation of slider/carousel components.
26 | * @author Thiago Alves
27 | * @license https://tldrlegal.com/license/mit-license MIT
28 | *
29 | * @param {number} length - Slides/slider items amount.
30 | * @param {object} config - Slider configuration object.
31 | * @param {number} [config.initialSlide=0] - Which slide will be the first one.
32 | * @param {boolean} [config.infinite=true] - If it's true the slider will reach the first slide when try move forward after has been arrived to the last one. Same will happen if it's on the first slide and try move backward, it will reach the last one.
33 | * @param {boolean} [config.autoplay=false] - If it's true the slider will start swapping slides automatically.
34 | * @param {number} [config.autoplaySpeed=200] - Defines how fast (ms) the slides will be swapped when the autoplay is true.
35 | * @param {number} [config.slidesToShow=1] - How many slides will be shown at the same moment.
36 | * @param {number} [config.slidesToScroll=1] - How many slides will be swapped when the change action (go forward or backward) is triggered.
37 | *
38 | * @return {HookResponse} Hook response to be used within your component like props
39 | */
40 | export default function useSlider(length = 0, config = {}) {
41 | const settings = { ...defaultConfig, ...config }
42 | const {
43 | initialSlide,
44 | infinite,
45 | slidesToScroll,
46 | autoplay,
47 | autoplaySpeed
48 | } = settings
49 |
50 | const [activeSlide, setActiveSlide] = useState(initialSlide)
51 |
52 | const lastSlide = length - 1
53 | const isRightLimit = activeSlide === lastSlide
54 | const isLeftLimit = activeSlide === 0
55 |
56 | let nextSlide = isRightLimit ? activeSlide : activeSlide + slidesToScroll
57 | let prevSlide = isLeftLimit ? activeSlide : activeSlide - slidesToScroll
58 |
59 | if (infinite && isRightLimit) {
60 | nextSlide = 0
61 | } else if (infinite && isLeftLimit) {
62 | prevSlide = lastSlide
63 | }
64 |
65 | const goToSlide = index => setActiveSlide(index)
66 | const goToNextSlide = () => setActiveSlide(nextSlide)
67 | const goToPrevSlide = () => setActiveSlide(prevSlide)
68 |
69 | let timeoutID = null
70 |
71 | useEffect(() => {
72 | if (autoplay && (infinite || !isRightLimit)) {
73 | timeoutID = setTimeout(goToNextSlide, autoplaySpeed)
74 | }
75 | return () => {
76 | if (timeoutID) {
77 | clearTimeout(timeoutID)
78 | }
79 | }
80 | })
81 |
82 | return {
83 | activeSlide,
84 | nextSlide,
85 | prevSlide,
86 | goToSlide,
87 | goToNextSlide,
88 | goToPrevSlide
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/src/hooks/useTabs.js:
--------------------------------------------------------------------------------
1 | import { useState } from "react"
2 |
3 | const defaultConfig = {
4 | initialTab: 0,
5 | initialDisabledTabs: []
6 | }
7 |
8 | /**
9 | * @typedef {object} HookResponse
10 | * @property {number} activeTab - The index of the current active tab.
11 | * @property {function()} selectTab - Change the current active tab index.
12 | * @property {array} disabledTabs - Includes indexes of all disabled tabs.
13 | * @property {function(number)} isEnabled - Returns true for enabled indexes.
14 | * @property {function(number)} isDisabled - Returns true for disabled indexes.
15 | * @property {function(number)} enableTab - For enabling a tab.
16 | * @property {function(number)} disableTab - For disabling a tab.
17 |
18 | /**
19 | * @function
20 | * @name useTabs
21 | * @description React hook to help create a tabs component. The hook will
22 | * keep track of tab indexes that can be enabled or disabled.
23 | * @author João Pedro R. D. Saldanha
24 | * @license https://tldrlegal.com/license/mit-license MIT
25 | *
26 | * @param {object} config - A configuration object
27 | * @param {number} [config.initialTab=0] - The initially selected tab index.
28 | * @param {array} [config.initialDisabledTabs=[]] - An array with initially disabled tab indexes.
29 | *
30 | * @return {HookResponse} Hook response to be used within your component like props.
31 | */
32 | export default function useTabs(config = {}) {
33 | const settings = { ...defaultConfig, ...config }
34 | const { initialTab, initialDisabledTabs } = settings
35 |
36 | const [activeTab, setActiveTab] = useState(initialTab)
37 | const [disabledTabs, setDisabledTabs] = useState(initialDisabledTabs)
38 |
39 | const isEnabled = index => !disabledTabs.includes(index)
40 | const isDisabled = index => !isEnabled(index)
41 |
42 | const selectTab = index => {
43 | if (index !== activeTab && isEnabled(index)) {
44 | setActiveTab(index)
45 | }
46 | }
47 |
48 | const disableTab = index => {
49 | if (index !== activeTab && isEnabled(index)) {
50 | setDisabledTabs(previousDisabledTabs => {
51 | return [...previousDisabledTabs, index]
52 | })
53 | }
54 | }
55 |
56 | const enableTab = index => {
57 | if (isDisabled(index)) {
58 | setDisabledTabs(previousDisabledTabs => (
59 | previousDisabledTabs.filter(tab => tab !== index)
60 | ))
61 | }
62 | }
63 |
64 | return {
65 | activeTab,
66 | selectTab,
67 | disabledTabs,
68 | isEnabled,
69 | isDisabled,
70 | enableTab,
71 | disableTab
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devthiago/react-ui-hooks/a6f7323a27c145adaadcd9f0227fb2f1159f68b6/src/index.js
--------------------------------------------------------------------------------
/tests/hooks/useSlider.test.js:
--------------------------------------------------------------------------------
1 | import { renderHook } from 'react-hooks-testing-library'
2 | import useSlider from '@hooks/useSlider'
3 |
4 | describe('useSlider()', () => {
5 | test('Describe what you are testing', () => {
6 | const { result } = renderHook(() => useSlider())
7 | const { activeSlide } = result.current
8 | expect(activeSlide).toBe(50)
9 | })
10 | })
11 |
--------------------------------------------------------------------------------
/tests/hooks/useTabs.test.js:
--------------------------------------------------------------------------------
1 | import { renderHook, cleanup, act } from 'react-hooks-testing-library'
2 | import useTabs from '@hooks/useTabs'
3 |
4 | describe('useTabs()', () => {
5 | beforeEach(cleanup)
6 |
7 | describe('activeTab integer response', () => {
8 | test('returns 0 when theres no default value', () => {
9 | const { result } = renderHook(() => useTabs())
10 | const { activeTab } = result.current
11 | expect(activeTab).toBe(0)
12 | })
13 |
14 | test('uses the initialTab config value if provided', () => {
15 | const config = { initialTab: 5 }
16 | const { result } = renderHook(() => useTabs(config))
17 | const { activeTab } = result.current
18 | expect(activeTab).toBe(5)
19 | })
20 | })
21 |
22 | describe('when selectTab function response is called', () => {
23 | test('activeTab is equal to the selectTab passed parameter', () => {
24 | const { result } = renderHook(() => useTabs())
25 | const { selectTab } = result.current
26 | act(() => selectTab(1))
27 | const { activeTab } = result.current
28 | expect(activeTab).toBe(1)
29 | })
30 |
31 | test('does not change activeTab if called with a disabled index', () => {
32 | const config = {initialDisabledTabs: [1]}
33 | const { result } = renderHook(() => useTabs(config))
34 | const { selectTab } = result.current
35 | act(() => selectTab(1))
36 | const { activeTab } = result.current
37 | expect(activeTab).toBe(0)
38 | })
39 | })
40 |
41 | describe('disabledTabs array', () => {
42 | test('starts at [] by default', () => {
43 | const { result } = renderHook(() => useTabs())
44 | const { disabledTabs } = result.current
45 | expect(disabledTabs).toEqual([])
46 | })
47 |
48 | test('uses the initialDisabledTabs config value if provided', () => {
49 | const config = { initialDisabledTabs: [3, 4, 5] }
50 | const { result } = renderHook(() => useTabs(config))
51 | const { disabledTabs } = result.current
52 | expect(disabledTabs).toEqual([3, 4, 5])
53 | })
54 | })
55 |
56 | describe('disableTab function', () => {
57 | test('disables a tab if it is enabled', () => {
58 | const { result } = renderHook(() => useTabs())
59 | const { disableTab } = result.current
60 | act(() => disableTab(1))
61 | const { disabledTabs } = result.current
62 | expect(disabledTabs).toEqual([1])
63 | })
64 |
65 | test('does not disable the current activeTab', () => {
66 | const { result } = renderHook(() => useTabs())
67 | const { disableTab } = result.current
68 | act(() => disableTab(0))
69 | const { disabledTabs } = result.current
70 | expect(disabledTabs).toEqual([])
71 | })
72 | })
73 |
74 | describe('enableTab function', () => {
75 | test('enables a tab if its disabled', () => {
76 | const config = {initialDisabledTabs: [1]}
77 | const { result } = renderHook(() => useTabs(config))
78 | const { enableTab } = result.current
79 | act(() => enableTab(1))
80 | const { disabledTabs } = result.current
81 | expect(disabledTabs).toEqual([])
82 | })
83 |
84 | test('does nothing when called with an already enabled tab as parameter', () => {
85 | const config = {initialDisabledTabs: [2]}
86 | const { result } = renderHook(() => useTabs(config))
87 | const { enableTab } = result.current
88 | act(() => enableTab(1))
89 | const { disabledTabs } = result.current
90 | expect(disabledTabs).toEqual([2])
91 | })
92 | })
93 |
94 | describe('isEnabled function response', () => {
95 | let current = null
96 |
97 | beforeAll(() => {
98 | const config = {initialDisabledTabs: [1]}
99 | const { result } = renderHook(() => useTabs(config))
100 | current = result.current
101 | })
102 |
103 | test('returns true if tab index is enabled', () => {
104 | const { isEnabled } = current
105 | expect(isEnabled(0)).toBe(true)
106 | })
107 |
108 | test('returns false if tab index is not enabled', () => {
109 | const { isEnabled } = current
110 | expect(isEnabled(1)).toBe(false)
111 | })
112 | })
113 | })
114 |
--------------------------------------------------------------------------------
/website/.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 | /demo/dist
14 |
15 | # misc
16 | .DS_Store
17 | .env.local
18 | .env.development.local
19 | .env.test.local
20 | .env.production.local
21 | /umd
22 |
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
--------------------------------------------------------------------------------
/website/README.md:
--------------------------------------------------------------------------------
1 | This website was created with [Docusaurus](https://docusaurus.io/).
2 |
3 | # What's In This Document
4 |
5 | * [Get Started in 5 Minutes](#get-started-in-5-minutes)
6 | * [Directory Structure](#directory-structure)
7 | * [Editing Content](#editing-content)
8 | * [Adding Content](#adding-content)
9 | * [Full Documentation](#full-documentation)
10 |
11 | # Get Started in 5 Minutes
12 |
13 | 1. Make sure all the dependencies for the website are installed:
14 |
15 | ```sh
16 | # Install dependencies
17 | $ yarn
18 | ```
19 | 2. Run your dev server:
20 |
21 | ```sh
22 | # Start the site
23 | $ yarn start
24 | ```
25 |
26 | ## Directory Structure
27 |
28 | Your project file structure should look something like this
29 |
30 | ```
31 | my-docusaurus/
32 | docs/
33 | doc-1.md
34 | doc-2.md
35 | doc-3.md
36 | website/
37 | blog/
38 | 2016-3-11-oldest-post.md
39 | 2017-10-24-newest-post.md
40 | core/
41 | node_modules/
42 | pages/
43 | static/
44 | css/
45 | img/
46 | package.json
47 | sidebar.json
48 | siteConfig.js
49 | ```
50 |
51 | # Editing Content
52 |
53 | ## Editing an existing docs page
54 |
55 | Edit docs by navigating to `docs/` and editing the corresponding document:
56 |
57 | `docs/doc-to-be-edited.md`
58 |
59 | ```markdown
60 | ---
61 | id: page-needs-edit
62 | title: This Doc Needs To Be Edited
63 | ---
64 |
65 | Edit me...
66 | ```
67 |
68 | For more information about docs, click [here](https://docusaurus.io/docs/en/navigation)
69 |
70 | ## Editing an existing blog post
71 |
72 | Edit blog posts by navigating to `website/blog` and editing the corresponding post:
73 |
74 | `website/blog/post-to-be-edited.md`
75 | ```markdown
76 | ---
77 | id: post-needs-edit
78 | title: This Blog Post Needs To Be Edited
79 | ---
80 |
81 | Edit me...
82 | ```
83 |
84 | For more information about blog posts, click [here](https://docusaurus.io/docs/en/adding-blog)
85 |
86 | # Adding Content
87 |
88 | ## Adding a new docs page to an existing sidebar
89 |
90 | 1. Create the doc as a new markdown file in `/docs`, example `docs/newly-created-doc.md`:
91 |
92 | ```md
93 | ---
94 | id: newly-created-doc
95 | title: This Doc Needs To Be Edited
96 | ---
97 |
98 | My new content here..
99 | ```
100 |
101 | 1. Refer to that doc's ID in an existing sidebar in `website/sidebar.json`:
102 |
103 | ```javascript
104 | // Add newly-created-doc to the Getting Started category of docs
105 | {
106 | "docs": {
107 | "Getting Started": [
108 | "quick-start",
109 | "newly-created-doc" // new doc here
110 | ],
111 | ...
112 | },
113 | ...
114 | }
115 | ```
116 |
117 | For more information about adding new docs, click [here](https://docusaurus.io/docs/en/navigation)
118 |
119 | ## Adding a new blog post
120 |
121 | 1. Make sure there is a header link to your blog in `website/siteConfig.js`:
122 |
123 | `website/siteConfig.js`
124 | ```javascript
125 | headerLinks: [
126 | ...
127 | { blog: true, label: 'Blog' },
128 | ...
129 | ]
130 | ```
131 |
132 | 2. Create the blog post with the format `YYYY-MM-DD-My-Blog-Post-Title.md` in `website/blog`:
133 |
134 | `website/blog/2018-05-21-New-Blog-Post.md`
135 |
136 | ```markdown
137 | ---
138 | author: Frank Li
139 | authorURL: https://twitter.com/foobarbaz
140 | authorFBID: 503283835
141 | title: New Blog Post
142 | ---
143 |
144 | Lorem Ipsum...
145 | ```
146 |
147 | For more information about blog posts, click [here](https://docusaurus.io/docs/en/adding-blog)
148 |
149 | ## Adding items to your site's top navigation bar
150 |
151 | 1. Add links to docs, custom pages or external links by editing the headerLinks field of `website/siteConfig.js`:
152 |
153 | `website/siteConfig.js`
154 | ```javascript
155 | {
156 | headerLinks: [
157 | ...
158 | /* you can add docs */
159 | { doc: 'my-examples', label: 'Examples' },
160 | /* you can add custom pages */
161 | { page: 'help', label: 'Help' },
162 | /* you can add external links */
163 | { href: 'https://github.com/facebook/Docusaurus', label: 'GitHub' },
164 | ...
165 | ],
166 | ...
167 | }
168 | ```
169 |
170 | For more information about the navigation bar, click [here](https://docusaurus.io/docs/en/navigation)
171 |
172 | ## Adding custom pages
173 |
174 | 1. Docusaurus uses React components to build pages. The components are saved as .js files in `website/pages/en`:
175 | 1. If you want your page to show up in your navigation header, you will need to update `website/siteConfig.js` to add to the `headerLinks` element:
176 |
177 | `website/siteConfig.js`
178 | ```javascript
179 | {
180 | headerLinks: [
181 | ...
182 | { page: 'my-new-custom-page', label: 'My New Custom Page' },
183 | ...
184 | ],
185 | ...
186 | }
187 | ```
188 |
189 | For more information about custom pages, click [here](https://docusaurus.io/docs/en/custom-pages).
190 |
191 | # Full Documentation
192 |
193 | Full documentation can be found on the [website](https://docusaurus.io/).
194 |
--------------------------------------------------------------------------------
/website/blog/2016-03-11-blog-post.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Blog Title
3 | author: Blog Author
4 | authorURL: http://twitter.com/
5 | authorFBID: 100002976521003
6 | ---
7 |
8 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus elementum massa eget nulla aliquet sagittis. Proin odio tortor, vulputate ut odio in, ultrices ultricies augue. Cras ornare ultrices lorem malesuada iaculis. Etiam sit amet libero tempor, pulvinar mauris sed, sollicitudin sapien.
9 |
10 |
11 |
12 | Mauris vestibulum ullamcorper nibh, ut semper purus pulvinar ut. Donec volutpat orci sit amet mauris malesuada, non pulvinar augue aliquam. Vestibulum ultricies at urna ut suscipit. Morbi iaculis, erat at imperdiet semper, ipsum nulla sodales erat, eget tincidunt justo dui quis justo. Pellentesque dictum bibendum diam at aliquet. Sed pulvinar, dolor quis finibus ornare, eros odio facilisis erat, eu rhoncus nunc dui sed ex. Nunc gravida dui massa, sed ornare arcu tincidunt sit amet. Maecenas efficitur sapien neque, a laoreet libero feugiat ut.
13 |
14 | Nulla facilisi. Maecenas sodales nec purus eget posuere. Sed sapien quam, pretium a risus in, porttitor dapibus erat. Sed sit amet fringilla ipsum, eget iaculis augue. Integer sollicitudin tortor quis ultricies aliquam. Suspendisse fringilla nunc in tellus cursus, at placerat tellus scelerisque. Sed tempus elit a sollicitudin rhoncus. Nulla facilisi. Morbi nec dolor dolor. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras et aliquet lectus. Pellentesque sit amet eros nisi. Quisque ac sapien in sapien congue accumsan. Nullam in posuere ante. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Proin lacinia leo a nibh fringilla pharetra.
15 |
16 | Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Proin venenatis lectus dui, vel ultrices ante bibendum hendrerit. Aenean egestas feugiat dui id hendrerit. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur in tellus laoreet, eleifend nunc id, viverra leo. Proin vulputate non dolor vel vulputate. Curabitur pretium lobortis felis, sit amet finibus lorem suscipit ut. Sed non mollis risus. Duis sagittis, mi in euismod tincidunt, nunc mauris vestibulum urna, at euismod est elit quis erat. Phasellus accumsan vitae neque eu placerat. In elementum arcu nec tellus imperdiet, eget maximus nulla sodales. Curabitur eu sapien eget nisl sodales fermentum.
17 |
18 | Phasellus pulvinar ex id commodo imperdiet. Praesent odio nibh, sollicitudin sit amet faucibus id, placerat at metus. Donec vitae eros vitae tortor hendrerit finibus. Interdum et malesuada fames ac ante ipsum primis in faucibus. Quisque vitae purus dolor. Duis suscipit ac nulla et finibus. Phasellus ac sem sed dui dictum gravida. Phasellus eleifend vestibulum facilisis. Integer pharetra nec enim vitae mattis. Duis auctor, lectus quis condimentum bibendum, nunc dolor aliquam massa, id bibendum orci velit quis magna. Ut volutpat nulla nunc, sed interdum magna condimentum non. Sed urna metus, scelerisque vitae consectetur a, feugiat quis magna. Donec dignissim ornare nisl, eget tempor risus malesuada quis.
19 |
--------------------------------------------------------------------------------
/website/blog/2017-04-10-blog-post-two.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: New Blog Post
3 | author: Blog Author
4 | authorURL: http://twitter.com/
5 | authorFBID: 100002976521003
6 | ---
7 |
8 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus elementum massa eget nulla aliquet sagittis. Proin odio tortor, vulputate ut odio in, ultrices ultricies augue. Cras ornare ultrices lorem malesuada iaculis. Etiam sit amet libero tempor, pulvinar mauris sed, sollicitudin sapien.
9 |
10 |
11 |
12 | Mauris vestibulum ullamcorper nibh, ut semper purus pulvinar ut. Donec volutpat orci sit amet mauris malesuada, non pulvinar augue aliquam. Vestibulum ultricies at urna ut suscipit. Morbi iaculis, erat at imperdiet semper, ipsum nulla sodales erat, eget tincidunt justo dui quis justo. Pellentesque dictum bibendum diam at aliquet. Sed pulvinar, dolor quis finibus ornare, eros odio facilisis erat, eu rhoncus nunc dui sed ex. Nunc gravida dui massa, sed ornare arcu tincidunt sit amet. Maecenas efficitur sapien neque, a laoreet libero feugiat ut.
13 |
14 | Nulla facilisi. Maecenas sodales nec purus eget posuere. Sed sapien quam, pretium a risus in, porttitor dapibus erat. Sed sit amet fringilla ipsum, eget iaculis augue. Integer sollicitudin tortor quis ultricies aliquam. Suspendisse fringilla nunc in tellus cursus, at placerat tellus scelerisque. Sed tempus elit a sollicitudin rhoncus. Nulla facilisi. Morbi nec dolor dolor. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras et aliquet lectus. Pellentesque sit amet eros nisi. Quisque ac sapien in sapien congue accumsan. Nullam in posuere ante. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Proin lacinia leo a nibh fringilla pharetra.
15 |
16 | Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Proin venenatis lectus dui, vel ultrices ante bibendum hendrerit. Aenean egestas feugiat dui id hendrerit. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur in tellus laoreet, eleifend nunc id, viverra leo. Proin vulputate non dolor vel vulputate. Curabitur pretium lobortis felis, sit amet finibus lorem suscipit ut. Sed non mollis risus. Duis sagittis, mi in euismod tincidunt, nunc mauris vestibulum urna, at euismod est elit quis erat. Phasellus accumsan vitae neque eu placerat. In elementum arcu nec tellus imperdiet, eget maximus nulla sodales. Curabitur eu sapien eget nisl sodales fermentum.
17 |
18 | Phasellus pulvinar ex id commodo imperdiet. Praesent odio nibh, sollicitudin sit amet faucibus id, placerat at metus. Donec vitae eros vitae tortor hendrerit finibus. Interdum et malesuada fames ac ante ipsum primis in faucibus. Quisque vitae purus dolor. Duis suscipit ac nulla et finibus. Phasellus ac sem sed dui dictum gravida. Phasellus eleifend vestibulum facilisis. Integer pharetra nec enim vitae mattis. Duis auctor, lectus quis condimentum bibendum, nunc dolor aliquam massa, id bibendum orci velit quis magna. Ut volutpat nulla nunc, sed interdum magna condimentum non. Sed urna metus, scelerisque vitae consectetur a, feugiat quis magna. Donec dignissim ornare nisl, eget tempor risus malesuada quis.
19 |
--------------------------------------------------------------------------------
/website/blog/2017-09-25-testing-rss.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Adding RSS Support - RSS Truncation Test
3 | author: Eric Nakagawa
4 | authorURL: http://twitter.com/ericnakagawa
5 | authorFBID: 661277173
6 | ---
7 | 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
8 |
9 | This should be truncated.
10 |
11 | This line should never render in XML.
12 |
--------------------------------------------------------------------------------
/website/blog/2017-09-26-adding-rss.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Adding RSS Support
3 | author: Eric Nakagawa
4 | authorURL: http://twitter.com/ericnakagawa
5 | authorFBID: 661277173
6 | ---
7 |
8 | This is a test post.
9 |
10 | A whole bunch of other information.
11 |
--------------------------------------------------------------------------------
/website/blog/2017-10-24-new-version-1.0.0.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: New Version 1.0.0
3 | author: Eric Nakagawa
4 | authorURL: http://twitter.com/ericnakagawa
5 | authorFBID: 661277173
6 | ---
7 |
8 | This blog post will test file name parsing issues when periods are present.
9 |
--------------------------------------------------------------------------------
/website/core/Footer.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2017-present, Facebook, Inc.
3 | *
4 | * This source code is licensed under the MIT license found in the
5 | * LICENSE file in the root directory of this source tree.
6 | */
7 |
8 | const React = require('react');
9 |
10 | class Footer extends React.Component {
11 | docUrl(doc, language) {
12 | const baseUrl = this.props.config.baseUrl;
13 | const docsUrl = this.props.config.docsUrl;
14 | const docsPart = `${docsUrl ? `${docsUrl}/` : ''}`;
15 | const langPart = `${language ? `${language}/` : ''}`;
16 | return `${baseUrl}${docsPart}${langPart}${doc}`;
17 | }
18 |
19 | pageUrl(doc, language) {
20 | const baseUrl = this.props.config.baseUrl;
21 | return baseUrl + (language ? `${language}/` : '') + doc;
22 | }
23 |
24 | render() {
25 | return (
26 |
100 | );
101 | }
102 | }
103 |
104 | module.exports = Footer;
105 |
--------------------------------------------------------------------------------
/website/i18n/en.json:
--------------------------------------------------------------------------------
1 | {
2 | "_comment": "This file is auto-generated by write-translations.js",
3 | "localized-strings": {
4 | "next": "Next",
5 | "previous": "Previous",
6 | "tagline": "Logic for React UI components",
7 | "docs": {
8 | "getting-started": {
9 | "title": "Getting Started",
10 | "sidebar_label": "Getting Started"
11 | },
12 | "use-slider": {
13 | "title": "useSlider",
14 | "sidebar_label": "useSlider"
15 | }
16 | },
17 | "links": {
18 | "Docs": "Docs",
19 | "API": "API"
20 | },
21 | "categories": {
22 | "Introduction": "Introduction",
23 | "API Reference": "API Reference"
24 | }
25 | },
26 | "pages-strings": {
27 | "Help Translate|recruit community translators for your project": "Help Translate",
28 | "Edit this Doc|recruitment message asking to edit the doc source": "Edit",
29 | "Translate this Doc|recruitment message asking to translate the docs": "Translate"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/website/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "scripts": {
3 | "examples": "docusaurus-examples",
4 | "start": "docusaurus-start",
5 | "build": "docusaurus-build",
6 | "publish-gh-pages": "docusaurus-publish",
7 | "write-translations": "docusaurus-write-translations",
8 | "version": "docusaurus-version",
9 | "rename-version": "docusaurus-rename-version"
10 | },
11 | "devDependencies": {
12 | "docusaurus": "^1.7.2"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/website/pages/en/help.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2017-present, Facebook, Inc.
3 | *
4 | * This source code is licensed under the MIT license found in the
5 | * LICENSE file in the root directory of this source tree.
6 | */
7 |
8 | const React = require('react');
9 |
10 | const CompLibrary = require('../../core/CompLibrary.js');
11 |
12 | const Container = CompLibrary.Container;
13 | const GridBlock = CompLibrary.GridBlock;
14 |
15 | function Help(props) {
16 | const {config: siteConfig, language = ''} = props;
17 | const {baseUrl, docsUrl} = siteConfig;
18 | const docsPart = `${docsUrl ? `${docsUrl}/` : ''}`;
19 | const langPart = `${language ? `${language}/` : ''}`;
20 | const docUrl = doc => `${baseUrl}${docsPart}${langPart}${doc}`;
21 |
22 | const supportLinks = [
23 | {
24 | content: `Learn more using the [documentation on this site.](${docUrl(
25 | 'doc1.html',
26 | )})`,
27 | title: 'Browse Docs',
28 | },
29 | {
30 | content: 'Ask questions about the documentation and project',
31 | title: 'Join the community',
32 | },
33 | {
34 | content: "Find out what's new with this project",
35 | title: 'Stay up to date',
36 | },
37 | ];
38 |
39 | return (
40 |
41 |
42 |
43 |
46 |
This project is maintained by a dedicated group of people.
47 |
48 |
49 |
50 |
51 | );
52 | }
53 |
54 | module.exports = Help;
55 |
--------------------------------------------------------------------------------
/website/pages/en/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2017-present, Facebook, Inc.
3 | *
4 | * This source code is licensed under the MIT license found in the
5 | * LICENSE file in the root directory of this source tree.
6 | */
7 |
8 | const React = require('react');
9 |
10 | const CompLibrary = require('../../core/CompLibrary.js');
11 |
12 | const MarkdownBlock = CompLibrary.MarkdownBlock; /* Used to read markdown */
13 | const Container = CompLibrary.Container;
14 | const GridBlock = CompLibrary.GridBlock;
15 |
16 | class HomeSplash extends React.Component {
17 | render() {
18 | const {siteConfig, language = ''} = this.props;
19 | const {baseUrl, docsUrl} = siteConfig;
20 | const docsPart = `${docsUrl ? `${docsUrl}/` : ''}`;
21 | const langPart = `${language ? `${language}/` : ''}`;
22 | const docUrl = doc => `${baseUrl}${docsPart}${langPart}${doc}`;
23 |
24 | const SplashContainer = props => (
25 |
26 |
27 |
{props.children}
28 |
29 |
30 | );
31 |
32 | const Logo = props => (
33 |
34 |
35 |
36 | );
37 |
38 | const ProjectTitle = () => (
39 |
40 | {siteConfig.title}
41 | {siteConfig.tagline}
42 |
43 | );
44 |
45 | const PromoSection = props => (
46 |
47 |
48 |
{props.children}
49 |
50 |
51 | );
52 |
53 | const Button = props => (
54 |
59 | );
60 |
61 | return (
62 |
63 |
64 |
65 |
66 |
67 | Try It Out
68 | Example Link
69 | Example Link 2
70 |
71 |
72 |
73 | );
74 | }
75 | }
76 |
77 | class Index extends React.Component {
78 | render() {
79 | const {config: siteConfig, language = ''} = this.props;
80 | const {baseUrl} = siteConfig;
81 |
82 | const Block = props => (
83 |
87 |
92 |
93 | );
94 |
95 | const FeatureCallout = () => (
96 |
99 |
Feature Callout
100 | These are features of this project
101 |
102 | );
103 |
104 | const TryOut = () => (
105 |
106 | {[
107 | {
108 | content: 'Talk about trying this out',
109 | image: `${baseUrl}img/docusaurus.svg`,
110 | imageAlign: 'left',
111 | title: 'Try it Out',
112 | },
113 | ]}
114 |
115 | );
116 |
117 | const Description = () => (
118 |
119 | {[
120 | {
121 | content:
122 | 'This is another description of how this project is useful',
123 | image: `${baseUrl}img/docusaurus.svg`,
124 | imageAlign: 'right',
125 | title: 'Description',
126 | },
127 | ]}
128 |
129 | );
130 |
131 | const LearnHow = () => (
132 |
133 | {[
134 | {
135 | content: 'Talk about learning how to use this',
136 | image: `${baseUrl}img/docusaurus.svg`,
137 | imageAlign: 'right',
138 | title: 'Learn How',
139 | },
140 | ]}
141 |
142 | );
143 |
144 | const Features = () => (
145 |
146 | {[
147 | {
148 | content: 'This is the content of my feature',
149 | image: `${baseUrl}img/docusaurus.svg`,
150 | imageAlign: 'top',
151 | title: 'Feature One',
152 | },
153 | {
154 | content: 'The content of my second feature',
155 | image: `${baseUrl}img/docusaurus.svg`,
156 | imageAlign: 'top',
157 | title: 'Feature Two',
158 | },
159 | ]}
160 |
161 | );
162 |
163 | const Showcase = () => {
164 | if ((siteConfig.users || []).length === 0) {
165 | return null;
166 | }
167 |
168 | const showcase = siteConfig.users
169 | .filter(user => user.pinned)
170 | .map(user => (
171 |
172 |
173 |
174 | ));
175 |
176 | const pageUrl = page => baseUrl + (language ? `${language}/` : '') + page;
177 |
178 | return (
179 |
180 |
Who is Using This?
181 |
This project is used by all these people
182 |
{showcase}
183 |
188 |
189 | );
190 | };
191 |
192 | return (
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 | );
205 | }
206 | }
207 |
208 | module.exports = Index;
209 |
--------------------------------------------------------------------------------
/website/pages/en/users.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2017-present, Facebook, Inc.
3 | *
4 | * This source code is licensed under the MIT license found in the
5 | * LICENSE file in the root directory of this source tree.
6 | */
7 |
8 | const React = require('react');
9 |
10 | const CompLibrary = require('../../core/CompLibrary.js');
11 |
12 | const Container = CompLibrary.Container;
13 |
14 | class Users extends React.Component {
15 | render() {
16 | const {config: siteConfig} = this.props;
17 | if ((siteConfig.users || []).length === 0) {
18 | return null;
19 | }
20 |
21 | const editUrl = `${siteConfig.repoUrl}/edit/master/website/siteConfig.js`;
22 | const showcase = siteConfig.users.map(user => (
23 |
24 |
25 |
26 | ));
27 |
28 | return (
29 |
30 |
31 |
32 |
33 |
Who is Using This?
34 |
This project is used by many folks
35 |
36 |
{showcase}
37 |
Are you using this project?
38 |
39 | Add your company
40 |
41 |
42 |
43 |
44 | );
45 | }
46 | }
47 |
48 | module.exports = Users;
49 |
--------------------------------------------------------------------------------
/website/sidebars.json:
--------------------------------------------------------------------------------
1 | {
2 | "docs": {
3 | "Introduction": ["getting-started"],
4 | "API Reference": ["use-slider"]
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/website/siteConfig.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2017-present, Facebook, Inc.
3 | *
4 | * This source code is licensed under the MIT license found in the
5 | * LICENSE file in the root directory of this source tree.
6 | */
7 |
8 | // See https://docusaurus.io/docs/site-config for all the possible
9 | // site configuration options.
10 |
11 | // List of projects/orgs using your project for the users page.
12 | const users = [
13 | {
14 | caption: 'User1',
15 | // You will need to prepend the image path with your baseUrl
16 | // if it is not '/', like: '/test-site/img/docusaurus.svg'.
17 | image: '/img/docusaurus.svg',
18 | infoLink: 'https://www.facebook.com',
19 | pinned: true,
20 | },
21 | ];
22 |
23 | const siteConfig = {
24 | title: 'React UI Hooks', // Title for your website.
25 | tagline: 'Logic for React UI components',
26 | url: 'https://your-docusaurus-test-site.com', // Your website URL
27 | baseUrl: '/', // Base URL for your project */
28 | // For github.io type URLs, you would set the url and baseUrl like:
29 | // url: 'https://facebook.github.io',
30 | // baseUrl: '/test-site/',
31 |
32 | // Used for publishing and more
33 | projectName: 'react-ui-hooks',
34 | organizationName: 'CodeMiner42',
35 | // For top-level user or org sites, the organization is still the same.
36 | // e.g., for the https://JoelMarcey.github.io site, it would be set like...
37 | // organizationName: 'JoelMarcey'
38 |
39 | // For no header links in the top nav bar -> headerLinks: [],
40 | headerLinks: [
41 | {doc: 'getting-started', label: 'Docs'},
42 | {doc: 'use-slider', label: 'API'},
43 | // {page: 'help', label: 'Help'},
44 | // {blog: true, label: 'Blog'},
45 | ],
46 |
47 | // If you have users set above, you add it here:
48 | users,
49 |
50 | /* path to images for header/footer */
51 | headerIcon: 'img/docusaurus.svg',
52 | footerIcon: 'img/docusaurus.svg',
53 | favicon: 'img/favicon.png',
54 |
55 | /* Colors for website */
56 | colors: {
57 | primaryColor: '#2E8555',
58 | secondaryColor: '#205C3B',
59 | },
60 |
61 | /* Custom fonts for website */
62 | /*
63 | fonts: {
64 | myFont: [
65 | "Times New Roman",
66 | "Serif"
67 | ],
68 | myOtherFont: [
69 | "-apple-system",
70 | "system-ui"
71 | ]
72 | },
73 | */
74 |
75 | // This copyright info is used in /core/Footer.js and blog RSS/Atom feeds.
76 | copyright: `Copyright © ${new Date().getFullYear()} CodeMiner42`,
77 |
78 | highlight: {
79 | // Highlight.js theme to use for syntax highlighting in code blocks.
80 | theme: 'default',
81 | },
82 |
83 | // Add custom scripts here that would be placed in