├── .env.dist ├── .github └── workflows │ └── ci.yml ├── .gitignore ├── LICENSE ├── README.md ├── bin └── build ├── composer.json ├── composer.lock ├── config ├── berti.config.php ├── webpack-dev-server.config.js └── webpack.config.js ├── data ├── articles.php ├── built_with.php ├── components.php └── talks.php ├── package-lock.json ├── package.json ├── pages ├── changelog.md └── index.md ├── src ├── Twig │ └── Extension.php ├── berti.php └── data.php ├── static-files ├── CNAME ├── android-chrome-192x192.png ├── android-chrome-512x512.png ├── apple-touch-icon.png ├── assets │ ├── 139.3ced3f7b.css │ ├── 139.820be3d5.js │ ├── 261.bd162b4a.js │ ├── 261.bd162b4a.js.LICENSE.txt │ ├── 553.90d4e0e8.css │ ├── 553.da065a6b.js │ ├── 67.4ae9feba.css │ ├── 67.ab055693.js │ ├── icons.b4abbede.svg │ ├── icons.cf61dfff.woff │ ├── icons.f41c5641.ttf │ ├── main.09dbcb8e.css │ ├── main.93d54642.js │ ├── manifest.json │ ├── runtime.124568e7.js │ ├── search.17d09555.svg │ ├── sourcesanspro-bold.cb7d3610.woff │ └── sourcesanspro-regular.f84b2bd4.woff ├── browserconfig.xml ├── favicon-32x32.png ├── favicon.ico ├── manifest.json ├── mstile-150x150.png ├── og-image.png ├── robots.txt └── safari-pinned-tab.svg └── theme ├── assets ├── components │ ├── component-info │ │ ├── index.js │ │ └── style.css │ ├── docsearch │ │ ├── algolia-autocomplete.css │ │ ├── algolia-autocomplete.js │ │ └── index.js │ ├── off-canvas-menu │ │ ├── index.css │ │ ├── index.js │ │ ├── menu.css │ │ └── menu.js │ └── version-selector │ │ ├── index.css │ │ ├── index.js │ │ ├── selector.css │ │ └── selector.js ├── fonts │ ├── fonts.css │ ├── sourcesanspro-bold.woff │ └── sourcesanspro-regular.woff ├── icons │ ├── fonts │ │ ├── icons.svg │ │ ├── icons.ttf │ │ └── icons.woff │ ├── icons.css │ ├── selection.json │ └── style.css ├── img │ ├── search.png │ └── search.svg ├── index.js ├── styles │ ├── alert.css │ ├── anchor.css │ ├── base.css │ ├── box.css │ ├── center.css │ ├── code.css │ ├── footer.css │ ├── grid.css │ ├── hamburger.css │ ├── header.css │ ├── highlight.css │ ├── iframe.css │ ├── links.css │ ├── searchbox.css │ ├── styles.css │ ├── toc.css │ ├── variables.css │ └── welcome.css └── webpack-public-path.js ├── changelog.html.twig ├── component-changelog.html.twig ├── component-license.html.twig ├── component.html.twig ├── default.html.twig ├── homepage.html.twig └── partials ├── changelog.html.twig └── header_menu.html.twig /.env.dist: -------------------------------------------------------------------------------- 1 | GITHUB_TOKEN="" 2 | DEPLOY_REPO="reactphp/reactphp.github.io" 3 | DEPLOY_TARGET_BRANCH="master" 4 | DEPLOY_URL="https://reactphp.org" 5 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: Deploy 2 | 3 | on: 4 | push: 5 | pull_request: 6 | workflow_dispatch: 7 | 8 | jobs: 9 | Deploy: 10 | runs-on: ubuntu-22.04 11 | steps: 12 | - uses: actions/checkout@v4 13 | - uses: shivammathur/setup-php@v2 14 | with: 15 | php-version: 7.1 16 | - run: composer install 17 | - run: mkdir ~/.ssh && echo "${{ secrets.DEPLOY_KEY }}" > ~/.ssh/id_rsa && chmod 400 ~/.ssh/id_rsa 18 | - run: echo 'GITHUB_TOKEN="${{ secrets.PAT || secrets.GITHUB_TOKEN }}"' > .env && cat .env.dist >> .env 19 | - run: git config --global user.name "GitHub Actions" && git config --global user.email "actions@github.com" 20 | - run: bin/build 21 | - run: bin/build --deploy --no-component-update 22 | if: ${{ github.ref == 'refs/heads/main' }} 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /tmp 3 | /vendor 4 | /.env 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017 Jan Sorgalla 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is furnished 8 | to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Website 2 | 3 | [](https://github.com/reactphp/website/actions) 4 | [](https://github.com/reactphp/reactphp.github.io) 5 | 6 | Source code of reactphp.org. 7 | 8 | ## Setup 9 | 10 | 1. Copy `.env.dist` to `.env` and add a 11 | [personal access token](https://github.com/settings/tokens) to the 12 | `GITHUB_TOKEN` entry. 13 | 14 | You don't need to check any of the scopes, `public access` is enough. The 15 | build script uses the GitHub API to render markdown files and fetch 16 | repository data and using the access token ensures that you don't run into 17 | API rate limits. 18 | 19 | 2. Install dependencies with `composer install`. 20 | 21 | ## Build 22 | 23 | Once set up, you can build the website by executing this: 24 | 25 | ```bash 26 | bin/build 27 | ``` 28 | 29 | This script will fetch all project repositories and then rebuild the entire website. 30 | The resulting static website will be built into the `tmp/build` directory. 31 | 32 | If you're working on the website source code, you may want to skip fetching all 33 | components on every build like this: 34 | 35 | ```bash 36 | bin/build --no-component-update 37 | ``` 38 | 39 | If you're working on the website CSS or Javascript code, you will have to 40 | rebuild the static assets like this: 41 | 42 | ```bash 43 | npm run-script build 44 | ``` 45 | 46 | > Note that compiled assets are expected to change much less frequently and are 47 | under version control. Run `npm install` to install and later commit any changes 48 | in `static-files/assets/`. 49 | 50 | ## Deploy 51 | 52 | Once built (see previous chapter), deployment is as simple as hosting the static 53 | website contents of the `tmp/build` directory behind a webserver of your choice. 54 | 55 | We use GitHub Pages to deploy this to the live site. This is done by pushing the 56 | contents of the `tmp/build` directory to the repository hosted in 57 | [reactphp/reactphp.github.io](https://github.com/reactphp/reactphp.github.io). 58 | 59 | This deployment can be started by executing this: 60 | 61 | ```bash 62 | bin/build --deploy 63 | ``` 64 | 65 | Note that this will publish any changes you've made to your local repository, 66 | including any uncommitted ones. There should usually be no need to do this 67 | manually, see next chapter for auto-deployment. 68 | 69 | ## Auto-Deployment 70 | 71 | The website can be automatically deployed via the GitHub Pages feature. 72 | 73 | Any time a commit is merged (such as when a PR is merged), GitHub actions will 74 | automatically build and deploy the website. This is done by running the above 75 | deployment script (see previous chapter). 76 | 77 | > Repository setup: 78 | > We're using a SSH deploy key for pushing to this target repository. 79 | > Make sure the required `DEPLOY_KEY` secret is set in the repository settings on GitHub. 80 | > See [action documentation](https://github.com/JamesIves/github-pages-deploy-action#using-an-ssh-deploy-key-) 81 | > for more details. 82 | > On top of this, you're recommended to add a [personal access token](https://github.com/settings/tokens) 83 | > as a repository secret with the name `PAT` to avoid running into secondary rate limits. 84 | > If this secret is not found, it will fall back to the automatic `GITHUB_TOKEN` 85 | > secret, which may cause the build to fail occasionally. 86 | 87 | ## License 88 | 89 | Released under the [MIT](LICENSE) license. 90 | 91 | **Note:** The logo and the brand name are not MIT licensed. 92 | Please check their [LICENSE](https://github.com/reactphp/branding/blob/master/LICENSE) 93 | for usage guidelines. 94 | -------------------------------------------------------------------------------- /bin/build: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | mustRun(function ($type, $buffer) { 21 | echo $buffer; 22 | }); 23 | } 24 | 25 | function checkout($dir, $gitUrl, ?string $tag) 26 | { 27 | if (!is_dir($dir)) { 28 | run('git clone ' . $gitUrl . ' "' . $dir . '"'); 29 | } 30 | 31 | run('git fetch', $dir); 32 | 33 | if ($tag !== null) { 34 | run('git checkout -f ' . $tag, $dir); 35 | } 36 | } 37 | 38 | function component(Symfony\Component\Console\Output\ConsoleOutput $output, $componentsDir, $name, $gitUrl, ?string $latestVersion) 39 | { 40 | $componentDir = $componentsDir . DIRECTORY_SEPARATOR . $name; 41 | 42 | $output->writeln('Latest version: ' . $latestVersion); 43 | 44 | checkout($componentDir, $gitUrl, $latestVersion); 45 | } 46 | 47 | $input = new Symfony\Component\Console\Input\ArgvInput(); 48 | $output = new Symfony\Component\Console\Output\ConsoleOutput(); 49 | 50 | if ($input->hasParameterOption('--use-asset-dev-server')) { 51 | putenv('USE_ASSET_DEV_SERVER=true'); 52 | } 53 | 54 | if (!$input->hasParameterOption('--no-component-update')) { 55 | foreach ($container['data.components'] as $component) { 56 | $output->writeln(sprintf( 57 | 'Updating component %s...', 58 | $component['repository'] 59 | )); 60 | 61 | component( 62 | $output, 63 | $componentsDir, 64 | $component['name'], 65 | $component['clone_url'], 66 | $component['releases'] ? $component['releases'][0]['tag'] : null 67 | ); 68 | 69 | $output->writeln('Done.'); 70 | } 71 | } 72 | 73 | if ($input->hasParameterOption('--dev-server')) { 74 | $address = $input->getParameterOption( 75 | '--dev-server-address', 76 | '127.0.0.1:8000' 77 | ); 78 | 79 | putenv('DEPLOY_URL=http://' . $address); 80 | 81 | call_user_func( 82 | $container['server'], 83 | getcwd(), 84 | $staticDir, 85 | $output, 86 | $address 87 | ); 88 | 89 | exit; 90 | } 91 | 92 | (new Symfony\Component\Filesystem\Filesystem())->remove($buildDir); 93 | (new Symfony\Component\Filesystem\Filesystem())->mkdir($buildDir); 94 | 95 | (function (Symfony\Component\Console\Output\OutputInterface $output, string $buildDir, array $components): void { 96 | $output->write('Generating changelog.atom...'); 97 | 98 | $releases = array_slice(React\Website\Data\releases($components), 0, 10); 99 | 100 | $feed = new Zend\Feed\Writer\Feed(); 101 | 102 | $feed->setId(getenv('DEPLOY_URL') . '/changelog.html'); 103 | $feed->setLink(getenv('DEPLOY_URL') . '/changelog.html'); 104 | $feed->setFeedLink(getenv('DEPLOY_URL') . '/changelog.atom', 'atom'); 105 | 106 | $feed->setLanguage('en'); 107 | $feed->setTitle('The combined changelog for all ReactPHP components.'); 108 | $feed->setDateModified((int) $releases[0]['date']->format('U')); 109 | 110 | foreach ($releases as $release) { 111 | $entry = $feed->createEntry(); 112 | 113 | $entry->setTitle($release['component'] . ' ' . $release['version']); 114 | $entry->setLink($release['url']); 115 | $entry->setDateModified((int) $release['date']->format('U')); 116 | $entry->setDescription($release['html']); 117 | $entry->addAuthor($release['author']); 118 | 119 | $feed->addEntry($entry); 120 | } 121 | 122 | file_put_contents( 123 | $buildDir . '/changelog.atom', 124 | $feed->export('atom') 125 | ); 126 | 127 | $output->writeln('Done'); 128 | })($output, $buildDir, $container['data.components']); 129 | 130 | call_user_func( 131 | $container['generator'], 132 | getcwd(), 133 | $buildDir, 134 | $output 135 | ); 136 | 137 | if ($input->hasParameterOption('--deploy')) { 138 | (function (Symfony\Component\Console\Output\OutputInterface $output, $buildDir, $deployDir) { 139 | $deployRepository = getenv('DEPLOY_REPO'); 140 | 141 | if (!$deployRepository) { 142 | $output->writeln('No deploy repository configured via the DEPLOY_REPO env variable, skipping deployment.'); 143 | return; 144 | } 145 | 146 | $deployRepositoryUrl = sprintf( 147 | 'git@github.com:%s', 148 | $deployRepository 149 | ); 150 | 151 | $output->writeln('Starting deployment to ' . $deployRepositoryUrl . '.'); 152 | 153 | $filesystem = new Symfony\Component\Filesystem\Filesystem(); 154 | 155 | $filesystem->remove($deployDir); 156 | $filesystem->mkdir($deployDir); 157 | 158 | run('git clone ' . $deployRepositoryUrl . ' "' . $deployDir . '"'); 159 | 160 | $deployBranch = getenv('DEPLOY_TARGET_BRANCH'); 161 | 162 | if (!$deployBranch) { 163 | $deployBranch = 'gh-pages'; 164 | $output->writeln('No deploy branch configured via the DEPLOY_TARGET_BRANCH env variable, using default "gh-pages" branch.'); 165 | } 166 | 167 | try { 168 | run('git checkout ' . $deployBranch, $deployDir); 169 | } catch (Symfony\Component\Process\Exception\ProcessFailedException $e) { 170 | run('git checkout --orphan ' . $deployBranch, $deployDir); 171 | } 172 | 173 | $output->write('Copying generated website...'); 174 | 175 | $finder = new Symfony\Component\Finder\Finder(); 176 | $finder 177 | ->files() 178 | ->in($deployDir) 179 | ->ignoreDotFiles(false) 180 | ->ignoreVCS(true); 181 | 182 | $filesystem->remove($finder); 183 | $filesystem->mirror($buildDir, $deployDir); 184 | 185 | $output->writeln('Done.'); 186 | 187 | try { 188 | run('git add --all . && git commit -m "Update website build"', $deployDir); 189 | } catch (Symfony\Component\Process\Exception\ProcessFailedException $e) { 190 | $output->writeln('No changes in this build, skipping deployment.'); 191 | return; 192 | } 193 | 194 | run('git push origin ' . $deployBranch, $deployDir); 195 | 196 | $output->writeln('Deployment finished.'); 197 | })($output, $buildDir, $deployDir); 198 | } 199 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react/website", 3 | "description": "Source code of reactphp.org", 4 | "license": "MIT", 5 | "authors": [ 6 | { 7 | "name": "Jan Sorgalla", 8 | "email": "jsorgalla@gmail.com" 9 | } 10 | ], 11 | "autoload": { 12 | "psr-4": { 13 | "React\\Website\\": "src/" 14 | }, 15 | "files": [ 16 | "src/berti.php", 17 | "src/data.php" 18 | ] 19 | }, 20 | "require-dev": { 21 | "jsor/berti": "^4.1", 22 | "symfony/cache": "^3.4", 23 | "symfony/filesystem": "^3.4", 24 | "symfony/process": "^3.4", 25 | "vlucas/phpdotenv": "^2.6", 26 | "elvanto/litemoji": "^1.4", 27 | "zendframework/zend-feed": "^2.12", 28 | "igorw/retry": "^1.0@dev" 29 | }, 30 | "config": { 31 | "platform": { 32 | "php": "7.1.99" 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /config/berti.config.php: -------------------------------------------------------------------------------- 1 | load(); 5 | } catch (Dotenv\Exception\InvalidPathException $e) { 6 | // Ignore missing .env 7 | } 8 | 9 | // use UTC timezone for all dates on website (release dates in changelogs) 10 | date_default_timezone_set('UTC'); 11 | 12 | return function (Pimple\Container $container) { 13 | $container['markdown.cache'] = function () { 14 | return new Symfony\Component\Cache\Adapter\FilesystemAdapter( 15 | 'markdown', 16 | 0, 17 | __DIR__ . '/../tmp/cache' 18 | ); 19 | }; 20 | 21 | $container['data.components'] = function (Pimple\Container $container) { 22 | return React\Website\Data\components( 23 | $container['github.client'], 24 | $container['markdown.cache'] 25 | ); 26 | }; 27 | 28 | $container['data.components_by_category'] = function (Pimple\Container $container) { 29 | return React\Website\Data\components_by_category($container['data.components']); 30 | }; 31 | 32 | $container['data.releases'] = function (Pimple\Container $container) { 33 | return React\Website\Data\releases($container['data.components']); 34 | }; 35 | 36 | $container['data.releases_by_year'] = function (Pimple\Container $container) { 37 | return React\Website\Data\releases_by_year($container['data.releases']); 38 | }; 39 | 40 | $container['data.built_with'] = function (Pimple\Container $container) { 41 | return React\Website\Data\built_with($container['github.client']); 42 | }; 43 | 44 | $container['data.articles'] = function () { 45 | return React\Website\Data\articles(); 46 | }; 47 | 48 | $container['data.talks'] = function () { 49 | return React\Website\Data\talks(); 50 | }; 51 | 52 | $container['template.theme'] = __DIR__ . '/../theme'; 53 | 54 | $container['template.map'] = [ 55 | 'index.html' => 'homepage.html.twig' 56 | ]; 57 | 58 | $container['github.client'] = $container->extend('github.client', function (Github\Client $client) { 59 | $client->addCache( 60 | new Symfony\Component\Cache\Adapter\FilesystemAdapter( 61 | 'github.client', 62 | 0, 63 | __DIR__ . '/../tmp/cache' 64 | ) 65 | ); 66 | 67 | return $client; 68 | }); 69 | 70 | $container['github.url_generator'] = $container->extend('github.url_generator', function (callable $urlGenerator) { 71 | return function (string $repository, string $url, string $cwd = null) use ($urlGenerator) { 72 | return React\Website\Berti\github_url_generator( 73 | $urlGenerator, 74 | $repository, 75 | $url, 76 | $cwd 77 | ); 78 | }; 79 | }); 80 | 81 | $container['github.markdown.filter'] = $container->extend('github.markdown.filter', function (callable $filter, Pimple\Container $container) { 82 | return function ( 83 | string $repository, 84 | string $html, 85 | Berti\Document $document, 86 | array $documentCollection, 87 | array $assetCollection 88 | ) use ($filter, $container) { 89 | return React\Website\Berti\github_markdown_filter( 90 | $container['data.components'], 91 | $container['input.directory_index'], 92 | $container['output.directory_index'], 93 | $filter, 94 | $repository, 95 | $html, 96 | $document, 97 | $documentCollection, 98 | $assetCollection 99 | ); 100 | }; 101 | }); 102 | 103 | $container['markdown.renderer'] = $container->extend('markdown.renderer', function (callable $renderer, Pimple\Container $container) { 104 | return function ( 105 | string $content, 106 | Berti\Document $document, 107 | array $documentCollection, 108 | array $assetCollection 109 | ) use ($renderer, $container) { 110 | /** @var \Psr\Cache\CacheItemPoolInterface $cache */ 111 | $cache = $container['markdown.cache']; 112 | 113 | $repository = $container['github.repository_detector'](dirname($document->input->getRealPath())) ?: null; 114 | 115 | $cacheKey = 'markdown' . md5($repository . $content); 116 | 117 | $cacheItem = $cache->getItem($cacheKey); 118 | 119 | if ($cacheItem->isHit()) { 120 | return $cacheItem->get(); 121 | } 122 | 123 | try { 124 | $html = $renderer( 125 | $content, 126 | $document, 127 | $documentCollection, 128 | $assetCollection 129 | ); 130 | } catch (\Exception $e) { 131 | echo 'Temporary error, will retry in 60s: ' . $e->getMessage() . PHP_EOL; 132 | sleep(60); 133 | $html = $renderer( 134 | $content, 135 | $document, 136 | $documentCollection, 137 | $assetCollection 138 | ); 139 | } 140 | 141 | $cacheItem->set($html); 142 | $cache->save($cacheItem); 143 | 144 | return $html; 145 | }; 146 | }); 147 | 148 | $container['template.renderer'] = $container->extend('template.renderer', function (callable $renderer, Pimple\Container $container) { 149 | return function (string $name, array $context = []) use ($renderer, $container) { 150 | return React\Website\Berti\template_renderer( 151 | $container['data.components'], 152 | $container['github.repository_detector'], 153 | $renderer, 154 | $name, 155 | $context 156 | ); 157 | }; 158 | }); 159 | 160 | $container['twig'] = $container->extend('twig', function (\Twig_Environment $twig, Pimple\Container $container) { 161 | $twig->addExtension(new React\Website\Twig\Extension()); 162 | 163 | $twig->addGlobal( 164 | 'components', 165 | $container['data.components'] 166 | ); 167 | 168 | $twig->addGlobal( 169 | 'components_by_category', 170 | $container['data.components_by_category'] 171 | ); 172 | 173 | $twig->addGlobal( 174 | 'releases', 175 | $container['data.releases'] 176 | ); 177 | 178 | $twig->addGlobal( 179 | 'releases_by_year', 180 | $container['data.releases_by_year'] 181 | ); 182 | 183 | $twig->addGlobal( 184 | 'built_with', 185 | $container['data.built_with'] 186 | ); 187 | 188 | $twig->addGlobal( 189 | 'articles', 190 | $container['data.articles'] 191 | ); 192 | 193 | $twig->addGlobal( 194 | 'talks', 195 | $container['data.talks'] 196 | ); 197 | 198 | $twig->addGlobal( 199 | 'asset_manifest', 200 | json_decode( 201 | file_get_contents(__DIR__ . '/../static-files/assets/manifest.json'), 202 | true 203 | ) 204 | ); 205 | 206 | $twig->addGlobal( 207 | 'use_asset_dev_server', 208 | 'true' === getenv('USE_ASSET_DEV_SERVER') 209 | ); 210 | 211 | $twig->addGlobal( 212 | 'base_url', 213 | rtrim(getenv('DEPLOY_URL'), '/') 214 | ); 215 | 216 | return $twig; 217 | }); 218 | 219 | $container['asset.finder'] = $container->protect(function ($path) { 220 | return (new Symfony\Component\Finder\Finder()) 221 | ->files() 222 | ->ignoreDotFiles(false) 223 | ->notName('.DS_Store') 224 | ->in($path . '/static-files'); 225 | }); 226 | 227 | $container['document.finder'] = $container->protect(function ($path) { 228 | return (new Symfony\Component\Finder\Finder()) 229 | ->name('/\.md$/') 230 | ->name('LICENSE') 231 | ->files() 232 | ->in($path . '/tmp/components') 233 | ->in($path . '/pages'); 234 | }); 235 | }; 236 | -------------------------------------------------------------------------------- /config/webpack-dev-server.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | mode: 'development', 5 | entry: [ 6 | path.resolve(process.cwd(), 'theme/assets/index.js') 7 | ], 8 | output: { 9 | publicPath: 'http://localhost:8080/_assets/', 10 | filename: '[name].js', 11 | chunkFilename: '[id].js' 12 | }, 13 | resolve: { 14 | extensions: ['.js', '.css', '.json'] 15 | }, 16 | module: { 17 | strictExportPresence: true, 18 | rules: [ 19 | { 20 | test: /\.js$/, 21 | use: [ 22 | { 23 | loader: 'babel-loader', 24 | options: { 25 | cacheDirectory: true, 26 | babelrc: false, 27 | presets: [ 28 | [ 29 | '@babel/preset-env', 30 | { 31 | useBuiltIns: 'entry', 32 | corejs: 3, 33 | modules: false, 34 | debug: false, 35 | } 36 | ] 37 | ], 38 | plugins: [ 39 | '@babel/plugin-syntax-dynamic-import', 40 | ] 41 | }, 42 | }, 43 | ], 44 | }, 45 | { 46 | test: /\.css$/, 47 | use: [ 48 | 'style-loader', 49 | { 50 | loader: 'css-loader', 51 | options: { 52 | importLoaders: 1, 53 | } 54 | }, 55 | { 56 | loader: 'postcss-loader', 57 | options: { 58 | postcssOptions: { 59 | plugins: [ 60 | require('postcss-import')(), 61 | require('postcss-flexbugs-fixes')(), 62 | require('postcss-preset-env')({ 63 | stage: 0, 64 | autoprefixer: { 65 | flexbox: 'no-2009', 66 | grid: true, 67 | } 68 | }), 69 | ] 70 | } 71 | } 72 | } 73 | ], 74 | }, 75 | { 76 | test: /\.(gif|png|jpe?g|svg)$/i, 77 | type: 'asset/resource', 78 | }, 79 | { 80 | test: /\.(woff|woff2|eot|ttf|otf)$/, 81 | type: 'asset/resource', 82 | }, 83 | ], 84 | }, 85 | devtool: 'eval', 86 | devServer: { 87 | static: './static-files/', 88 | headers: { 89 | 'Access-Control-Allow-Origin': '*' 90 | } 91 | } 92 | }; 93 | -------------------------------------------------------------------------------- /config/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const MiniCssExtractPlugin = require('mini-css-extract-plugin'); 3 | const { CleanWebpackPlugin } = require('clean-webpack-plugin'); 4 | const PostCSSAssetsPlugin = require('postcss-assets-webpack-plugin'); 5 | const { WebpackManifestPlugin } = require('webpack-manifest-plugin'); 6 | 7 | module.exports = () => { 8 | const mode = 'production'; 9 | const targetPath = path.resolve(process.cwd(), 'static-files/assets'); 10 | 11 | return { 12 | mode: mode, 13 | entry: { 14 | 'main': [ 15 | path.resolve(process.cwd(), 'theme/assets/webpack-public-path.js'), 16 | path.resolve(process.cwd(), 'theme/assets/index.js'), 17 | ], 18 | }, 19 | output: { 20 | path: path.resolve(process.cwd(), targetPath), 21 | publicPath: '', // see https://github.com/shellscape/webpack-manifest-plugin/issues/229#issuecomment-737617994 22 | filename: '[name].[contenthash:8].js', 23 | chunkFilename: '[name].[contenthash:8].js', 24 | assetModuleFilename: '[name].[contenthash:8][ext][query]' 25 | }, 26 | optimization: { 27 | runtimeChunk: 'single' 28 | }, 29 | resolve: { 30 | extensions: ['.js', '.css', '.json'] 31 | }, 32 | module: { 33 | strictExportPresence: true, 34 | rules: [ 35 | { 36 | test: /\.js$/, 37 | use: [ 38 | { 39 | loader: 'babel-loader', 40 | options: { 41 | cacheDirectory: true, 42 | babelrc: false, 43 | presets: [ 44 | [ 45 | '@babel/preset-env', 46 | { 47 | useBuiltIns: 'entry', 48 | corejs: 3, 49 | modules: false, 50 | debug: false, 51 | } 52 | ] 53 | ], 54 | plugins: [ 55 | '@babel/plugin-syntax-dynamic-import', 56 | ] 57 | }, 58 | }, 59 | ], 60 | }, 61 | { 62 | test: /\.css$/, 63 | use: [ 64 | mode !== 'production' ? 'style-loader' : MiniCssExtractPlugin.loader, 65 | { 66 | loader: 'css-loader', 67 | options: { 68 | importLoaders: 1, 69 | } 70 | }, 71 | { 72 | loader: 'postcss-loader', 73 | options: { 74 | postcssOptions: { 75 | plugins: [ 76 | require('postcss-import')(), 77 | require('postcss-flexbugs-fixes')(), 78 | require('postcss-preset-env')({ 79 | stage: 0, 80 | autoprefixer: { 81 | flexbox: 'no-2009', 82 | grid: true, 83 | } 84 | }), 85 | ] 86 | } 87 | } 88 | } 89 | ], 90 | }, 91 | { 92 | test: /\.(gif|png|jpe?g|svg)$/i, 93 | type: 'asset/resource', 94 | }, 95 | { 96 | test: /\.(woff|woff2|eot|ttf|otf)$/, 97 | type: 'asset/resource', 98 | }, 99 | ], 100 | }, 101 | plugins: [ 102 | new CleanWebpackPlugin(), 103 | new MiniCssExtractPlugin({ 104 | filename: '[name].[contenthash:8].css', 105 | chunkFilename: '[name].[contenthash:8].css', 106 | }), 107 | new PostCSSAssetsPlugin({ 108 | plugins: [ 109 | require('cssnano')({ 110 | preset: ['default', { 111 | discardComments: { 112 | removeAll: true, 113 | }, 114 | }] 115 | }), 116 | ], 117 | }), 118 | new WebpackManifestPlugin({}), 119 | ] 120 | }; 121 | }; 122 | -------------------------------------------------------------------------------- /data/articles.php: -------------------------------------------------------------------------------- 1 | 'Sergey Zhuk', 6 | 'description' => 'A series of articles covering ReactPHP: from the basics to the real application examples.', 7 | 'link' => 'http://sergeyzhuk.me/reactphp-series', 8 | ], 9 | [ 10 | 'title' => 'Cees-Jan Kiewiet', 11 | 'description' => 'Blog series about several ReactPHP components and how they work.', 12 | 'link' => 'http://blog.wyrihaximus.net/categories/reactphp-series/', 13 | ], 14 | [ 15 | 'title' => 'Loïc Faugeron', 16 | 'description' => 'Super Speed Symfony - ReactPHP.', 17 | 'link' => 'https://gnugat.github.io/2016/04/13/super-speed-sf-react-php.html', 18 | ], 19 | [ 20 | 'title' => 'Marc J. Schmidt', 21 | 'description' => 'Bring High Performance Into Your PHP App (with ReactPHP).', 22 | 'link' => 'http://marcjschmidt.de/blog/2014/02/08/php-high-performance.html', 23 | ], 24 | ]; 25 | -------------------------------------------------------------------------------- /data/built_with.php: -------------------------------------------------------------------------------- 1 | 'Thruway', 6 | 'repository' => 'voryx/Thruway' 7 | ], 8 | [ 9 | 'title' => 'PPM - PHP Process Manager', 10 | 'repository' => 'php-pm/php-pm' 11 | ], 12 | [ 13 | 'title' => 'php-ar-drone', 14 | 'repository' => 'jolicode/php-ar-drone' 15 | ], 16 | [ 17 | 'title' => 'Ratchet', 18 | 'repository' => 'ratchetphp/Ratchet' 19 | ], 20 | [ 21 | 'title' => 'Predis\Async', 22 | 'repository' => 'nrk/predis-async' 23 | ], 24 | [ 25 | 'title' => 'clue/redis-server', 26 | 'repository' => 'clue/redis-server' 27 | ], 28 | ]; 29 | -------------------------------------------------------------------------------- /data/components.php: -------------------------------------------------------------------------------- 1 | 'EventLoop', 6 | 'repository' => 'reactphp/event-loop', 7 | 'category' => 'Core Components' 8 | ], 9 | [ 10 | 'title' => 'Stream', 11 | 'repository' => 'reactphp/stream', 12 | 'category' => 'Core Components' 13 | ], 14 | [ 15 | 'title' => 'Promise', 16 | 'repository' => 'reactphp/promise', 17 | 'category' => 'Core Components' 18 | ], 19 | [ 20 | 'title' => 'Async', 21 | 'repository' => 'reactphp/async', 22 | 'category' => 'Core Components' 23 | ], 24 | [ 25 | 'title' => 'Socket', 26 | 'repository' => 'reactphp/socket', 27 | 'category' => 'Network Components' 28 | ], 29 | [ 30 | 'title' => 'Datagram', 31 | 'repository' => 'reactphp/datagram', 32 | 'category' => 'Network Components' 33 | ], 34 | [ 35 | 'title' => 'HTTP', 36 | 'repository' => 'reactphp/http', 37 | 'category' => 'Network Components' 38 | ], 39 | [ 40 | 'title' => 'DNS', 41 | 'repository' => 'reactphp/dns', 42 | 'category' => 'Network Components' 43 | ], 44 | [ 45 | 'title' => 'Cache', 46 | 'repository' => 'reactphp/cache', 47 | 'category' => 'Utility Components' 48 | ], 49 | [ 50 | 'title' => 'ChildProcess', 51 | 'repository' => 'reactphp/child-process', 52 | 'category' => 'Utility Components' 53 | ], 54 | [ 55 | 'title' => 'PromiseTimer', 56 | 'repository' => 'reactphp/promise-timer', 57 | 'category' => 'Utility Components' 58 | ], 59 | [ 60 | 'title' => 'PromiseStream', 61 | 'repository' => 'reactphp/promise-stream', 62 | 'category' => 'Utility Components' 63 | ], 64 | [ 65 | 'title' => 'HttpClient', 66 | 'repository' => 'reactphp/http-client', 67 | 'category' => 'Legacy Components' 68 | ], 69 | [ 70 | 'title' => 'SocketClient', 71 | 'repository' => 'reactphp/socket-client', 72 | 'category' => 'Legacy Components' 73 | ], 74 | ]; 75 | -------------------------------------------------------------------------------- /data/talks.php: -------------------------------------------------------------------------------- 1 | 'https://www.youtube.com/watch?v=-5ZdGUvOqx4', 6 | 'embed_url' => 'https://www.youtube-nocookie.com/embed/-5ZdGUvOqx4' 7 | ], 8 | [ 9 | 'link' => 'https://www.youtube.com/watch?v=s6xrnYae1FU', 10 | 'embed_url' => 'https://www.youtube-nocookie.com/embed/s6xrnYae1FU' 11 | ], 12 | [ 13 | 'link' => 'https://www.youtube.com/watch?v=MWNcItWuKpI', 14 | 'embed_url' => 'https://www.youtube-nocookie.com/embed/MWNcItWuKpI' 15 | ], 16 | ]; 17 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "reactphp-website", 3 | "version": "2.0.0", 4 | "description": "Source code of reactphp.org", 5 | "repository": "git@github.com:reactphp/website.git", 6 | "author": "Jan Sorgalla ", 7 | "license": "MIT", 8 | "scripts": { 9 | "build": "webpack --config ./config/webpack.config.js --progress", 10 | "watch": "webpack --config ./config/webpack.config.js --progress --watch", 11 | "dev-server": "webpack-dev-server --config ./config/webpack-dev-server.config.js --hot" 12 | }, 13 | "browserslist": [ 14 | "> 1%", 15 | "last 4 versions", 16 | "Firefox ESR", 17 | "not ie < 10" 18 | ], 19 | "dependencies": { 20 | "core-js": "^3.21.0", 21 | "ctrly": "^0.7.0", 22 | "docsearch.js": "^2.6.3", 23 | "domestique": "^1.7.0" 24 | }, 25 | "devDependencies": { 26 | "@babel/core": "^7.17.0", 27 | "@babel/plugin-syntax-dynamic-import": "^7.8.3", 28 | "@babel/preset-env": "^7.16.11", 29 | "babel-loader": "^8.2.3", 30 | "clean-webpack-plugin": "^4.0.0", 31 | "css-loader": "^6.6.0", 32 | "cssnano": "^5.0.16", 33 | "mini-css-extract-plugin": "^2.5.3", 34 | "postcss-assets-webpack-plugin": "^4.1.2", 35 | "postcss-flexbugs-fixes": "^5.0.2", 36 | "postcss-import": "^14.0.2", 37 | "postcss-loader": "^6.2.1", 38 | "postcss-preset-env": "^7.3.1", 39 | "style-loader": "^3.3.1", 40 | "webpack": "^5.68.0", 41 | "webpack-cli": "^4.9.2", 42 | "webpack-dev-server": "^4.7.4", 43 | "webpack-manifest-plugin": "^4.1.1" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /pages/changelog.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | The combined changelog for all ReactPHP components. 4 | -------------------------------------------------------------------------------- /pages/index.md: -------------------------------------------------------------------------------- 1 | Placeholder markdown file for the homepage. 2 | -------------------------------------------------------------------------------- /src/Twig/Extension.php: -------------------------------------------------------------------------------- 1 | .*?)(\\1)\)/', $rewriteUrl, $content); 58 | $content = preg_replace_callback('/@import (?!url\()(\'|"|)(?[^\'"\)\n\r]*)\1;?/', $rewriteUrl, $content); 59 | // Handle 'src' values (used in e.g. calls to AlphaImageLoader, which is a proprietary IE filter) 60 | $content = preg_replace_callback('/\bsrc\s*=\s*(["\']?)(?.*?)(\\1)/i', $rewriteUrl, $content); 61 | } 62 | 63 | return $content; 64 | } 65 | 66 | public function participationSvg(string $repo, array $participation): string 67 | { 68 | $width = 320; 69 | $height = 40; 70 | 71 | $prefix = str_replace('/', '-', $repo); 72 | 73 | $x = 0; 74 | $offset = floor($width / count($participation['all'])); 75 | 76 | $points = array_map(function ($value) use (&$x, $offset) { 77 | $currX = $x; 78 | $x += $offset; 79 | 80 | return $currX . ',' . ($value + 1); 81 | }, $participation['all']); 82 | 83 | $pointString = implode(' ', $points); 84 | $rectHeight = $height + 2; 85 | 86 | return << 88 | 89 | 90 | 91 | 92 | 93 | 94 | 101 | 102 | 103 | 104 | 105 | 112 | 113 | 114 | EOF; 115 | } 116 | 117 | public function displayUrl(string $url): string 118 | { 119 | $host = parse_url($url, PHP_URL_HOST); 120 | 121 | if (!$host) { 122 | return $url; 123 | } 124 | 125 | return str_ireplace('www.', '', $host); 126 | } 127 | 128 | public function stripTitle(string $string): string 129 | { 130 | return preg_replace('/^]*?>.*?<\/h1>/si', '', trim($string)); 131 | } 132 | 133 | public function emoji(string $string): string 134 | { 135 | return LitEmoji::encodeUnicode($string); 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /src/berti.php: -------------------------------------------------------------------------------- 1 | run(); 33 | 34 | // Might return HEAD if not in a tag checkout 35 | $version = trim($process->getOutput()); 36 | 37 | if ($version && 'HEAD' !== $version) { 38 | // Always use ../blob/.. because GitHub redirects to ../tree/.. for directories 39 | return 'https://github.com/' . $repository . '/blob/' . $version . '/' . ltrim($url, '/'); 40 | } 41 | 42 | return $bertiUrlGenerator($repository, $url, $cwd); 43 | } 44 | 45 | /** 46 | * This function extends the `Berti\twig_renderer()` to dynamically switch 47 | * templates, eg. if a component repository is detected. 48 | * 49 | * It also passes additional component context data when rendering the template. 50 | */ 51 | function template_renderer( 52 | array $components, 53 | callable $repositoryDetector, 54 | callable $bertiRenderer, 55 | string $name, 56 | array $context = [] 57 | ): string 58 | { 59 | /** @var \Symfony\Component\Finder\SplFileInfo $documentInput */ 60 | $documentInput = $context['berti']['document']->input; 61 | 62 | if ('changelog.md' === $documentInput->getRelativePathname()) { 63 | return $bertiRenderer('changelog.html.twig', $context); 64 | } 65 | 66 | $repo = $repositoryDetector(dirname($documentInput->getRealPath())); 67 | 68 | if (!$repo) { 69 | return $bertiRenderer($name, $context); 70 | } 71 | 72 | $components = array_filter( 73 | $components, 74 | function ($component) use ($repo) { 75 | return $component['full_name'] === $repo; 76 | } 77 | ); 78 | 79 | $component = reset($components); 80 | 81 | if (!$component) { 82 | return $bertiRenderer($name, $context); 83 | } 84 | 85 | $context['component'] = $component; 86 | 87 | $context['component_releases_by_year'] = releases_by_year($component['releases']); 88 | 89 | switch ($documentInput->getFilename()) { 90 | case 'LICENSE': 91 | $name = 'component-license.html.twig'; 92 | break; 93 | case 'CHANGELOG.md': 94 | $name = 'component-changelog.html.twig'; 95 | break; 96 | default: 97 | $name = 'component.html.twig'; 98 | break; 99 | } 100 | 101 | return $bertiRenderer($name, $context); 102 | } 103 | 104 | /** 105 | * Additional markdown filter which replaces links to other components with 106 | * internal relative links. 107 | * 108 | * For example, if there's a markdown link like 109 | * `[Event Loop](https://github.com/reactphp/event-loop)`, the URL is replaced 110 | * with `../event-loop/`. 111 | */ 112 | function github_markdown_filter( 113 | array $components, 114 | string $inputDirectoryIndex, 115 | string $outputDirectoryIndex, 116 | callable $bertiFilter, 117 | string $repository, 118 | string $html, 119 | Document $document, 120 | array $documentCollection, 121 | array $assetCollection 122 | ): string 123 | { 124 | $html = $bertiFilter( 125 | $repository, 126 | $html, 127 | $document, 128 | $documentCollection, 129 | $assetCollection 130 | ); 131 | 132 | $map = []; 133 | 134 | foreach ($documentCollection as $doc) { 135 | $inputPath = $doc->input->getRelativePathname(); 136 | $outputPath = $doc->output->getRelativePathname(); 137 | 138 | if (basename($inputPath) === $inputDirectoryIndex) { 139 | $inputPath = dirname($inputPath); 140 | } 141 | 142 | if (basename($outputPath) === $outputDirectoryIndex) { 143 | $outputPath = rtrim(dirname($outputPath), '/') . '/'; 144 | } 145 | 146 | $map[$inputPath] = uri_rewriter( 147 | $outputPath, 148 | '/', 149 | $document->output->getRelativePathname() 150 | ); 151 | } 152 | 153 | $repos = array_map( 154 | function ($component) { 155 | return $component['name']; 156 | }, 157 | $components 158 | ); 159 | 160 | $callback = function ($matches) use ($map) { 161 | $url = $matches[2] . ($matches[3] ?? ''); 162 | 163 | $hash = ''; 164 | 165 | if (false !== strpos($url, '#')) { 166 | [$url, $hash] = explode('#', $url); 167 | } 168 | 169 | if (!isset($map[$url])) { 170 | return $matches[0]; 171 | } 172 | 173 | if ('' !== $hash) { 174 | $hash = '#' . $hash; 175 | } 176 | 177 | return 'href="' . $map[$url] . $hash . '"'; 178 | }; 179 | 180 | $html = preg_replace_callback( 181 | '/href=(["\']?)https:\/\/github.com\/reactphp\/+([' . preg_quote(implode('|', $repos), '/') . ']+)([^"\']+)?\\1/i', 182 | $callback, 183 | $html 184 | ); 185 | 186 | return $html; 187 | } 188 | -------------------------------------------------------------------------------- /src/data.php: -------------------------------------------------------------------------------- 1 | repo()->contributors($username, $repository); 16 | 17 | $component['participation'] = retry(3, function () use ($client, $username, $repository){ 18 | $participation = $client->repo()->participation($username, $repository); 19 | 20 | if (!isset($participation['all'])) { 21 | throw new \RuntimeException( 22 | "Could not fetch participation for $username/$repository from the Github API" 23 | ); 24 | } 25 | 26 | return $participation; 27 | }); 28 | 29 | $apiReleases = (new ResultPager($client)) 30 | ->fetchAll( 31 | $client->repo()->releases(), 32 | 'all', 33 | [$username, $repository, ['per_page' => 100]] 34 | ); 35 | 36 | $releases = []; 37 | 38 | foreach ($apiReleases as $release) { 39 | $cacheKey = 'gfm' . md5($component['repository'] . $release['body']); 40 | 41 | $cacheItem = $markdownCache->getItem($cacheKey); 42 | 43 | if ($cacheItem->isHit()) { 44 | $html = $cacheItem->get(); 45 | } else { 46 | try{ 47 | $html = $client->markdown()->render( 48 | $release['body'], 49 | 'gfm', 50 | $component['repository'] 51 | ); 52 | } catch (\Exception $e) { 53 | echo 'Temporary error, will retry in 60s: ' . $e->getMessage() . PHP_EOL; 54 | sleep(60); 55 | $html = $client->markdown()->render( 56 | $release['body'], 57 | 'gfm', 58 | $component['repository'] 59 | ); 60 | } 61 | 62 | $cacheItem->set($html); 63 | $markdownCache->save($cacheItem); 64 | } 65 | 66 | $date = new \DateTimeImmutable($release['created_at']); 67 | 68 | $releases[(int) $date->format('U')] = [ 69 | 'version' => ltrim($release['tag_name'], 'v'), 70 | 'tag' => $release['tag_name'], 71 | 'date' => $date, 72 | 'html' => $html, 73 | 'url' => $release['html_url'], 74 | 'component' => $component['title'], 75 | 'repository' => $component['repository'], 76 | 'author' => [ 77 | 'name' => $release['author']['login'], 78 | 'uri' => $release['author']['html_url'], 79 | 'avatar' => $release['author']['avatar_url'], 80 | ] 81 | ]; 82 | } 83 | 84 | krsort($releases, SORT_NATURAL); 85 | 86 | $component['releases'] = array_values($releases); 87 | 88 | return array_merge( 89 | $client->repo()->show($username, $repository), 90 | $component 91 | ); 92 | }, include __DIR__ . '/../data/components.php'); 93 | } 94 | 95 | function components_by_category(array $components): array 96 | { 97 | $byCategory = []; 98 | 99 | foreach ($components as $component) { 100 | if (!isset($byCategory[$component['category']])) { 101 | $byCategory[$component['category']] = []; 102 | } 103 | 104 | $byCategory[$component['category']][] = $component; 105 | } 106 | 107 | return $byCategory; 108 | } 109 | 110 | function releases(array $components): array 111 | { 112 | $releases = []; 113 | 114 | foreach ($components as $component) { 115 | foreach ($component['releases'] as $release) { 116 | $time = (int) $release['date']->format('U'); 117 | 118 | $releases[$time . '-' . $component['repository']] = $release; 119 | } 120 | } 121 | 122 | krsort($releases, SORT_NATURAL); 123 | 124 | return array_values($releases); 125 | } 126 | 127 | function releases_by_year(array $releases): array 128 | { 129 | $byYear = []; 130 | 131 | foreach ($releases as $release) { 132 | $year = (int) $release['date']->format('Y'); 133 | 134 | if (!isset($byYear[$year])) { 135 | $byYear[$year] = []; 136 | } 137 | 138 | $byYear[$year][] = $release; 139 | } 140 | 141 | return $byYear; 142 | } 143 | 144 | function built_with(Client $client): array 145 | { 146 | return array_map(function ($component) use ($client) { 147 | [$username, $repository] = explode('/', $component['repository']); 148 | 149 | return array_merge( 150 | $client->repo()->show($username, $repository), 151 | $component 152 | ); 153 | }, include __DIR__ . '/../data/built_with.php'); 154 | } 155 | 156 | function articles(): array 157 | { 158 | return include __DIR__ . '/../data/articles.php'; 159 | } 160 | 161 | function talks(): array 162 | { 163 | return include __DIR__ . '/../data/talks.php'; 164 | } 165 | -------------------------------------------------------------------------------- /static-files/CNAME: -------------------------------------------------------------------------------- 1 | reactphp.org 2 | -------------------------------------------------------------------------------- /static-files/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactphp/website/c2482860b9334add7909db0840a2d793afca45e3/static-files/android-chrome-192x192.png -------------------------------------------------------------------------------- /static-files/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactphp/website/c2482860b9334add7909db0840a2d793afca45e3/static-files/android-chrome-512x512.png -------------------------------------------------------------------------------- /static-files/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactphp/website/c2482860b9334add7909db0840a2d793afca45e3/static-files/apple-touch-icon.png -------------------------------------------------------------------------------- /static-files/assets/139.3ced3f7b.css: -------------------------------------------------------------------------------- 1 | .algolia-autocomplete{display:block;height:100%;width:100%}.algolia-autocomplete.algolia-autocomplete-right .ds-dropdown-menu{left:inherit!important;right:0!important}.algolia-autocomplete.algolia-autocomplete-right .ds-dropdown-menu:before{right:48px}.algolia-autocomplete.algolia-autocomplete-left .ds-dropdown-menu{left:0!important;right:inherit!important}.algolia-autocomplete.algolia-autocomplete-left .ds-dropdown-menu:before{left:48px}.algolia-autocomplete .ds-dropdown-menu{background:transparent;border:none;border-radius:4px;-webkit-box-shadow:0 1px 0 0 rgba(0,0,0,.2),0 2px 3px 0 rgba(0,0,0,.1);box-shadow:0 1px 0 0 rgba(0,0,0,.2),0 2px 3px 0 rgba(0,0,0,.1);height:auto;margin:6px 0 0;max-width:600px;min-width:500px;padding:0;position:relative;text-align:left;top:-6px;z-index:999}.algolia-autocomplete .ds-dropdown-menu:before{background:#fff;border-radius:2px;border-right:1px solid #d9d9d9;border-top:1px solid #d9d9d9;content:"";display:block;height:14px;position:absolute;top:-7px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);width:14px;z-index:1000}.algolia-autocomplete .ds-dropdown-menu .ds-suggestions{margin-top:8px;position:relative;z-index:1000}.algolia-autocomplete .ds-dropdown-menu .ds-suggestion{cursor:pointer}.algolia-autocomplete .ds-dropdown-menu .ds-suggestion.ds-cursor .algolia-docsearch-suggestion.suggestion-layout-simple,.algolia-autocomplete .ds-dropdown-menu .ds-suggestion.ds-cursor .algolia-docsearch-suggestion:not(.suggestion-layout-simple) .algolia-docsearch-suggestion--content{background-color:rgba(69,142,225,.05)}.algolia-autocomplete .ds-dropdown-menu [class^=ds-dataset-]{background:#fff;border:1px solid #d9d9d9;border-radius:4px;overflow:auto;padding:0 8px 8px;position:relative}.algolia-autocomplete .ds-dropdown-menu *{-webkit-box-sizing:border-box;box-sizing:border-box}.algolia-autocomplete .algolia-docsearch-suggestion{background:#fff;color:#02060c;overflow:hidden;padding:0 8px;position:relative}.algolia-autocomplete .algolia-docsearch-suggestion--highlight{background:rgba(143,187,237,.1);color:#174d8c;padding:.1em .05em}.algolia-autocomplete .algolia-docsearch-suggestion--category-header .algolia-docsearch-suggestion--category-header-lvl0 .algolia-docsearch-suggestion--highlight,.algolia-autocomplete .algolia-docsearch-suggestion--category-header .algolia-docsearch-suggestion--category-header-lvl1 .algolia-docsearch-suggestion--highlight{background:inherit;color:inherit}.algolia-autocomplete .algolia-docsearch-suggestion--text .algolia-docsearch-suggestion--highlight{background:inherit;-webkit-box-shadow:inset 0 -2px 0 0 rgba(69,142,225,.8);box-shadow:inset 0 -2px 0 0 rgba(69,142,225,.8);color:inherit;padding:0 0 1px}.algolia-autocomplete .algolia-docsearch-suggestion--content{cursor:pointer;display:block;float:right;padding:5.33333px 0 5.33333px 10.66667px;position:relative;width:70%}.algolia-autocomplete .algolia-docsearch-suggestion--content:before{background:#ddd;content:"";display:block;height:100%;left:-1px;position:absolute;top:0;width:1px}.algolia-autocomplete .algolia-docsearch-suggestion--category-header{border-bottom:1px solid #ddd;color:#33363d;display:none;font-size:1em;margin-top:8px;padding:4px 0;position:relative}.algolia-autocomplete .algolia-docsearch-suggestion--wrapper{float:left;padding:8px 0 0;width:100%}.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-column{word-wrap:break-word;color:#a4a7ae;display:none;float:left;font-size:.9em;padding:5.33333px 10.66667px;position:relative;text-align:right;width:30%}.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-column:before{background:#ddd;content:"";display:block;height:100%;position:absolute;right:0;top:0;width:1px}.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-column .algolia-docsearch-suggestion--highlight{background-color:inherit;color:inherit}.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-inline{display:none}.algolia-autocomplete .algolia-docsearch-suggestion--title{color:#02060c;font-size:.9em;font-weight:700;margin-bottom:4px}.algolia-autocomplete .algolia-docsearch-suggestion--text{color:#63676d;display:block;font-size:.85em;line-height:1.2em}.algolia-autocomplete .algolia-docsearch-suggestion--no-results{font-size:1.2em;padding:8px 0;text-align:center;width:100%}.algolia-autocomplete .algolia-docsearch-suggestion--no-results:before{display:none}.algolia-autocomplete .algolia-docsearch-suggestion code{background-color:#ebebeb;border:none;border-radius:3px;color:#222;font-family:Menlo,Monaco,Consolas,Courier New,monospace;font-size:90%;padding:1px 5px}.algolia-autocomplete .algolia-docsearch-suggestion code .algolia-docsearch-suggestion--highlight{background:none}.algolia-autocomplete .algolia-docsearch-suggestion.algolia-docsearch-suggestion__main .algolia-docsearch-suggestion--category-header,.algolia-autocomplete .algolia-docsearch-suggestion.algolia-docsearch-suggestion__secondary .algolia-docsearch-suggestion--subcategory-column{display:block}.algolia-autocomplete .suggestion-layout-simple.algolia-docsearch-suggestion{border-bottom:1px solid #eee;margin:0;padding:8px}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--content{padding:0;width:100%}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--content:before{display:none}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--category-header{border:none;display:block;margin:0;padding:0;width:100%}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--category-header-lvl0,.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--category-header-lvl1{font-size:.85em;opacity:.6}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--category-header-lvl1:before{background-image:url('data:image/svg+xml;utf8,');content:"";display:inline-block;height:10px;width:10px}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--wrapper{float:left;margin:0;padding:0;width:100%}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--duplicate-content,.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--subcategory-column,.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--subcategory-inline{display:none!important}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--title{color:#458ee1;font-size:.9em;font-weight:400;margin:0}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--title:before{color:#458ee1;content:"#";display:inline-block;font-weight:700}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--text{background:#f8f8f8;display:block;font-size:.85em;line-height:1.4em;margin:4px 0 0;opacity:.8;padding:5.33333px 8px}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--text .algolia-docsearch-suggestion--highlight{-webkit-box-shadow:none;box-shadow:none;color:#3f4145;font-weight:700}.algolia-autocomplete .algolia-docsearch-footer{float:right;font-size:0;height:20px;line-height:0;margin-top:10.66667px;width:110px;z-index:2000}.algolia-autocomplete .algolia-docsearch-footer--logo{background-image:url("data:image/svg+xml;utf8,");background-position:50%;background-repeat:no-repeat;background-size:100%;display:block;height:100%;overflow:hidden;padding:0!important;text-indent:-9000px;width:100%} -------------------------------------------------------------------------------- /static-files/assets/139.820be3d5.js: -------------------------------------------------------------------------------- 1 | (self.webpackChunkreactphp_website=self.webpackChunkreactphp_website||[]).push([[139],{7399:function(e,t,i){"use strict";i.r(t),i.d(t,{init:function(){return n}});var a=i(261),c=i.n(a),r=0;function n(e){var t=e.getAttribute("id");t||(t="docsearch-"+r++,e.setAttribute("id",t)),c()({apiKey:"4c440463ddff54a35b4d7dc24afb010b",indexName:"reactphp",inputSelector:"#"+t,debug:"true"===e.getAttribute("data-docsearch-debug"),algoliaOptions:{hitsPerPage:5}})}},5525:function(){}}]); -------------------------------------------------------------------------------- /static-files/assets/261.bd162b4a.js.LICENSE.txt: -------------------------------------------------------------------------------- 1 | /*! 2 | * @overview es6-promise - a tiny implementation of Promises/A+. 3 | * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald) 4 | * @license Licensed under MIT license 5 | * See https://raw.githubusercontent.com/stefanpenner/es6-promise/master/LICENSE 6 | * @version v4.2.8+1e68dce6 7 | */ 8 | -------------------------------------------------------------------------------- /static-files/assets/553.90d4e0e8.css: -------------------------------------------------------------------------------- 1 | :root{--color-key:#4f5b93;--color-key-light:#a2aacd;--color-base:#584b4f;--color-base-light:#afa1a5;--color-green:#40a977;--color-green-light:#9ad8bb;--color-red:#ba3525;--color-red-light:#e79187;--color-background:#d6d1c8;--color-background-light:#eae8e3;--color-background-lighter:#f4f3f1;--color-background-lightest:#f9f9f8;--box-shadow-light:0 1px 0 0 rgba(0,0,0,.15);--box-shadow-lighter:0 1px 0 0 rgba(0,0,0,.1);--box-shadow-lightest:0 1px 0 0 rgba(0,0,0,.08)}.off-canvas-menu{height:100%;outline:none;overflow-x:hidden;overflow-y:auto;width:300px;z-index:1000}.off-canvas-menu[aria-hidden=false]{pointer-events:auto}.off-canvas-menu__content{-webkit-overflow-scrolling:touch;background:#f9f9f8;background:var(--color-background-lightest);-webkit-box-shadow:0 0 15px rgba(0,0,0,.33);box-shadow:0 0 15px rgba(0,0,0,.33);height:100%;overflow-x:hidden;overflow-y:auto;position:absolute;right:0;-webkit-transition:all .35s cubic-bezier(.23,1,.32,1);-o-transition:all .35s cubic-bezier(.23,1,.32,1);transition:all .35s cubic-bezier(.23,1,.32,1);width:285px}.off-canvas-menu[aria-hidden=false] .off-canvas-menu__content{-webkit-transform:translateZ(0);transform:translateZ(0)}.off-canvas-menu__close{-ms-flex-pack:center;-ms-flex-align:center;align-items:center;-webkit-appearance:none;background:none;border:0;color:#584b4f;color:var(--color-base);cursor:pointer;display:-ms-flexbox;display:flex;font-size:20px;height:48px;justify-content:center;margin:0;outline:none;overflow:visible;padding:0;position:absolute;right:0;text-decoration:none;text-shadow:none;text-transform:none;top:0;width:48px;z-index:1001}.off-canvas-menu__close:hover{color:#40a977;color:var(--color-green)}.off-canvas-menu__section{border-top:1px solid #eae8e3;border-top:1px solid var(--color-background-light);padding:8px 0}.off-canvas-menu__list{list-style:none;margin:0;padding:0}.off-canvas-menu__link{-ms-flex-pack:justify;color:#584b4f;color:var(--color-base);display:-ms-flexbox;display:flex;font-size:.9rem;justify-content:space-between;line-height:1;padding:8px 16px;text-decoration:none}.off-canvas-menu__link:hover{color:#40a977;color:var(--color-green);text-decoration:none}.off-canvas-menu__version{border:1px solid #d6d1c8;border:1px solid var(--color-background);border-radius:4px;color:#afa1a5;color:var(--color-base-light);display:inline-block;font-size:.65rem;line-height:1;padding:.25rem;text-decoration:none}.off-canvas-menu__link:hover .off-canvas-menu__version{border-color:#40a977;border-color:var(--color-green);color:#40a977;color:var(--color-green)}.off-canvas-menu__section-header,.off-canvas-menu__section-top{color:#afa1a5;color:var(--color-base-light);font-size:.9rem!important;font-weight:700;letter-spacing:.1rem;margin:0;padding:8px 16px 16px;text-transform:uppercase}.off-canvas-menu__section-top{color:#584b4f;color:var(--color-base);display:block;font-size:.9rem;line-height:1rem;padding:8px 16px;text-decoration:none}.off-canvas-menu__section-top:hover{color:#40a977;color:var(--color-green);text-decoration:none} -------------------------------------------------------------------------------- /static-files/assets/553.da065a6b.js: -------------------------------------------------------------------------------- 1 | "use strict";(self.webpackChunkreactphp_website=self.webpackChunkreactphp_website||[]).push([[553],{7788:function(t,e,n){n.d(e,{Z:function(){return d}});var r=n(9264),o={selector:"[data-ctrly]",context:null,focusTarget:!0,closeOnBlur:!0,closeOnEsc:!0,closeOnOutsideClick:!0,closeOnScroll:!1,trapFocus:!1,allowMultiple:!1,on:null,autoInit:!0};function i(t){var e={};return[o,t].forEach((function(t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])})),e}function a(t){return"which"in t?t.which:t.keyCode}function u(t){return(0,r.sE)('[aria-controls="'.concat(t.id,'"]'))}function c(t){return document.getElementById(t.getAttribute("aria-controls")||t.getAttribute("data-ctrly"))}function s(t){t.removeAttribute("aria-pressed"),t.removeAttribute("aria-controls"),t.removeAttribute("aria-expanded")}var l=0;function d(){var t,e,n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},o=i(n),d=o.selector,f=o.on||{},p={};function b(t){return o.context?(0,r.oq)(t,o.context):document}function v(t,e){return("function"!=typeof f[e]||!1!==f[e](t))&&!1!==(0,r.WI)(t,"ctrly:".concat(e),{bubbles:!0,cancelable:!0})}function h(t){for(var e=t;e;){if(e.id&&p[e.id])return e;e=e.parentElement}}function A(t){var e=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];if(!t)return!1;if(!t.hasAttribute("data-ctrly-opened"))return!1;if(!v(t,"close"))return!1;var n=(0,r.AW)(),o=p[t.id]||{},i=o.lastActiveElement,a=o.destroy;return delete p[t.id],a&&a(),u(t).forEach((function(t){"button"!==t.tagName.toLowerCase()&&t.setAttribute("aria-pressed","false"),t.setAttribute("aria-expanded","false")})),t.removeAttribute("data-ctrly-opened"),t.setAttribute("aria-hidden","true"),t.removeAttribute("tabindex"),t.blur(),e&&i&&t.contains(n)&&(0,r.T_)(i,{restoreScrollPosition:!0}),v(t,"closed"),t}function m(t){(0,r.sE)(d,b(t)).forEach((function(e){var n=c(e);n&&n.id!==t.id&&A(n,!1)}))}function y(t,e){var n=[];if(o.closeOnBlur&&!o.trapFocus&&n.push((0,r.on)(document,"focusin",(function(t){e.contains(t.target)||setTimeout((function(){A(e,!1)}),0)}),{capture:!0,passive:!0})),o.closeOnEsc&&n.push((0,r.on)(document,"keydown",(function(t){27===a(t)&&A(e)&&t.preventDefault()}))),o.closeOnOutsideClick&&n.push((0,r.on)(document,"click",(function(t){1!==a(t)||e.contains(t.target)||(0,r.oq)(t.target,d)||A(e)}),{passive:!0})),o.closeOnScroll){var i=!1,u=function(){i=!0},c=function(){i=!1};n.push((0,r.on)(e,"mouseenter",u,{passive:!0})),n.push((0,r.on)(e,"mouseleave",c,{passive:!0})),n.push((0,r.on)(e,"touchstart",u,{passive:!0})),n.push((0,r.on)(e,"touchend",c,{passive:!0})),n.push((0,r.on)(window,"scroll",(function(){i||A(e)}),{passive:!0}))}return o.trapFocus&&n.push((0,r.on)(document,"keydown",(function(t){if(9===a(t)){var n=(0,r.ht)(e);if(!n[0])return t.preventDefault(),void(0,r.T_)(e);var o=(0,r.AW)(),i=n[0],u=n[n.length-1];if(t.shiftKey&&o===i)return t.preventDefault(),void(0,r.T_)(u);t.shiftKey||o!==u||((0,r.T_)(i),t.preventDefault())}}))),function(){for(;n.length;)n.shift().call()}}function g(t){var e=c(t);return e?!e.hasAttribute("data-ctrly-opened")&&!!v(e,"open")&&(p[e.id]={lastActiveElement:(0,r.AW)(),destroy:y(0,e)},u(e).forEach((function(t){"button"!==t.tagName.toLowerCase()&&t.setAttribute("aria-pressed","true"),t.setAttribute("aria-expanded","true")})),e.setAttribute("data-ctrly-opened",""),e.setAttribute("aria-hidden","false"),e.setAttribute("tabindex","-1"),v(e,"opened"),e):(s(t),!1)}function w(t,e){var n=c(e);n?"true"!==e.getAttribute("aria-expanded")?(o.allowMultiple||m(n),g(e),n&&(t.preventDefault(),o.focusTarget&&(0,r.T_)((0,r.ht)(n)[0]||n),n.scrollTop=0,n.scrollLeft=0)):A(n)&&t.preventDefault():A(h(e))&&t.preventDefault()}function E(){t||(t=(0,r.cl)(document,"click",d,(function(t,e){1===a(t)&&w(t,e)})),e=(0,r.cl)(document,"keydown",d,(function(t,e){13!==a(t)&&32!==a(t)||w(t,e)}))),(0,r.sE)(d).forEach((function(t){var e=c(t);if(e){"button"!==t.tagName.toLowerCase()&&(t.hasAttribute("role")||t.setAttribute("role","button"),(0,r.Wq)(t)||t.setAttribute("tabindex","0")),t.setAttribute("aria-controls",e.id);var n=u(e).map((function(t){return t.id||t.setAttribute("id","ctrly-control-"+ ++l),t.id})),o=(e.getAttribute("aria-labelledby")||"").split(" ").concat(n).filter((function(t,e,n){return""!==t&&n.indexOf(t)===e}));e.setAttribute("aria-labelledby",o.join(" ")),"true"===t.getAttribute("aria-expanded")||t.hasAttribute("data-ctrly-open")?g(t):("button"!==t.tagName.toLowerCase()&&t.setAttribute("aria-pressed","false"),t.setAttribute("aria-expanded","false"),e.setAttribute("aria-hidden","true"),e.removeAttribute("tabindex"))}else s(t)}))}function O(n){for(var o in n&&t&&(t(),t=null,e(),e=null),(0,r.sE)(d).forEach((function(t){n&&s(t);var e=c(t);e&&(A(e,!1),n&&e.removeAttribute("aria-hidden"))})),p)Object.prototype.hasOwnProperty.call(p,o)&&(p[o].destroy(),delete p[o])}function x(){O(!1)}function k(){O(!0)}return o.autoInit&&(0,r.Cd)(E),{closeAll:x,destroy:k,init:E}}},553:function(t,e,n){n.r(e),(0,n(7788).Z)({selector:"[data-off-canvas-menu-control]",closeOnScroll:!0})}}]); -------------------------------------------------------------------------------- /static-files/assets/67.4ae9feba.css: -------------------------------------------------------------------------------- 1 | :root{--color-key:#4f5b93;--color-key-light:#a2aacd;--color-base:#584b4f;--color-base-light:#afa1a5;--color-green:#40a977;--color-green-light:#9ad8bb;--color-red:#ba3525;--color-red-light:#e79187;--color-background:#d6d1c8;--color-background-light:#eae8e3;--color-background-lighter:#f4f3f1;--color-background-lightest:#f9f9f8;--box-shadow-light:0 1px 0 0 rgba(0,0,0,.15);--box-shadow-lighter:0 1px 0 0 rgba(0,0,0,.1);--box-shadow-lightest:0 1px 0 0 rgba(0,0,0,.08)}.version-selector__button[aria-expanded=true]{background:#584b4f!important;background:var(--color-base)!important;border-bottom-left-radius:0;border-bottom-right-radius:0;-webkit-box-shadow:none;box-shadow:none;z-index:999}.version-selector__button[aria-expanded=true] [class=icon-chevron-down]{display:none}.version-selector__button[aria-expanded=true] [class=icon-chevron-up]{display:inline-block}.version-selector__panel{background:#584b4f;background:var(--color-base);border-radius:4px;-webkit-box-shadow:0 0 8px rgba(0,0,0,.33);box-shadow:0 0 8px rgba(0,0,0,.33);font-weight:400;left:-115px;outline:none;padding:1rem;width:300px;z-index:998}.version-selector__panel[aria-hidden=false]{position:absolute;top:auto;visibility:visible}.version-selector__list{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;list-style:none;margin-left:-4px;padding:0}.version-selector__list li{margin:4px;width:calc(25% - 8px)}.version-selector__list a{display:block;text-align:center} -------------------------------------------------------------------------------- /static-files/assets/67.ab055693.js: -------------------------------------------------------------------------------- 1 | "use strict";(self.webpackChunkreactphp_website=self.webpackChunkreactphp_website||[]).push([[67],{7788:function(t,e,n){n.d(e,{Z:function(){return d}});var r=n(9264),o={selector:"[data-ctrly]",context:null,focusTarget:!0,closeOnBlur:!0,closeOnEsc:!0,closeOnOutsideClick:!0,closeOnScroll:!1,trapFocus:!1,allowMultiple:!1,on:null,autoInit:!0};function i(t){var e={};return[o,t].forEach((function(t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])})),e}function a(t){return"which"in t?t.which:t.keyCode}function u(t){return(0,r.sE)('[aria-controls="'.concat(t.id,'"]'))}function c(t){return document.getElementById(t.getAttribute("aria-controls")||t.getAttribute("data-ctrly"))}function s(t){t.removeAttribute("aria-pressed"),t.removeAttribute("aria-controls"),t.removeAttribute("aria-expanded")}var l=0;function d(){var t,e,n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},o=i(n),d=o.selector,f=o.on||{},p={};function b(t){return o.context?(0,r.oq)(t,o.context):document}function v(t,e){return("function"!=typeof f[e]||!1!==f[e](t))&&!1!==(0,r.WI)(t,"ctrly:".concat(e),{bubbles:!0,cancelable:!0})}function h(t){for(var e=t;e;){if(e.id&&p[e.id])return e;e=e.parentElement}}function A(t){var e=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];if(!t)return!1;if(!t.hasAttribute("data-ctrly-opened"))return!1;if(!v(t,"close"))return!1;var n=(0,r.AW)(),o=p[t.id]||{},i=o.lastActiveElement,a=o.destroy;return delete p[t.id],a&&a(),u(t).forEach((function(t){"button"!==t.tagName.toLowerCase()&&t.setAttribute("aria-pressed","false"),t.setAttribute("aria-expanded","false")})),t.removeAttribute("data-ctrly-opened"),t.setAttribute("aria-hidden","true"),t.removeAttribute("tabindex"),t.blur(),e&&i&&t.contains(n)&&(0,r.T_)(i,{restoreScrollPosition:!0}),v(t,"closed"),t}function m(t){(0,r.sE)(d,b(t)).forEach((function(e){var n=c(e);n&&n.id!==t.id&&A(n,!1)}))}function y(t,e){var n=[];if(o.closeOnBlur&&!o.trapFocus&&n.push((0,r.on)(document,"focusin",(function(t){e.contains(t.target)||setTimeout((function(){A(e,!1)}),0)}),{capture:!0,passive:!0})),o.closeOnEsc&&n.push((0,r.on)(document,"keydown",(function(t){27===a(t)&&A(e)&&t.preventDefault()}))),o.closeOnOutsideClick&&n.push((0,r.on)(document,"click",(function(t){1!==a(t)||e.contains(t.target)||(0,r.oq)(t.target,d)||A(e)}),{passive:!0})),o.closeOnScroll){var i=!1,u=function(){i=!0},c=function(){i=!1};n.push((0,r.on)(e,"mouseenter",u,{passive:!0})),n.push((0,r.on)(e,"mouseleave",c,{passive:!0})),n.push((0,r.on)(e,"touchstart",u,{passive:!0})),n.push((0,r.on)(e,"touchend",c,{passive:!0})),n.push((0,r.on)(window,"scroll",(function(){i||A(e)}),{passive:!0}))}return o.trapFocus&&n.push((0,r.on)(document,"keydown",(function(t){if(9===a(t)){var n=(0,r.ht)(e);if(!n[0])return t.preventDefault(),void(0,r.T_)(e);var o=(0,r.AW)(),i=n[0],u=n[n.length-1];if(t.shiftKey&&o===i)return t.preventDefault(),void(0,r.T_)(u);t.shiftKey||o!==u||((0,r.T_)(i),t.preventDefault())}}))),function(){for(;n.length;)n.shift().call()}}function g(t){var e=c(t);return e?!e.hasAttribute("data-ctrly-opened")&&!!v(e,"open")&&(p[e.id]={lastActiveElement:(0,r.AW)(),destroy:y(0,e)},u(e).forEach((function(t){"button"!==t.tagName.toLowerCase()&&t.setAttribute("aria-pressed","true"),t.setAttribute("aria-expanded","true")})),e.setAttribute("data-ctrly-opened",""),e.setAttribute("aria-hidden","false"),e.setAttribute("tabindex","-1"),v(e,"opened"),e):(s(t),!1)}function w(t,e){var n=c(e);n?"true"!==e.getAttribute("aria-expanded")?(o.allowMultiple||m(n),g(e),n&&(t.preventDefault(),o.focusTarget&&(0,r.T_)((0,r.ht)(n)[0]||n),n.scrollTop=0,n.scrollLeft=0)):A(n)&&t.preventDefault():A(h(e))&&t.preventDefault()}function E(){t||(t=(0,r.cl)(document,"click",d,(function(t,e){1===a(t)&&w(t,e)})),e=(0,r.cl)(document,"keydown",d,(function(t,e){13!==a(t)&&32!==a(t)||w(t,e)}))),(0,r.sE)(d).forEach((function(t){var e=c(t);if(e){"button"!==t.tagName.toLowerCase()&&(t.hasAttribute("role")||t.setAttribute("role","button"),(0,r.Wq)(t)||t.setAttribute("tabindex","0")),t.setAttribute("aria-controls",e.id);var n=u(e).map((function(t){return t.id||t.setAttribute("id","ctrly-control-"+ ++l),t.id})),o=(e.getAttribute("aria-labelledby")||"").split(" ").concat(n).filter((function(t,e,n){return""!==t&&n.indexOf(t)===e}));e.setAttribute("aria-labelledby",o.join(" ")),"true"===t.getAttribute("aria-expanded")||t.hasAttribute("data-ctrly-open")?g(t):("button"!==t.tagName.toLowerCase()&&t.setAttribute("aria-pressed","false"),t.setAttribute("aria-expanded","false"),e.setAttribute("aria-hidden","true"),e.removeAttribute("tabindex"))}else s(t)}))}function O(n){for(var o in n&&t&&(t(),t=null,e(),e=null),(0,r.sE)(d).forEach((function(t){n&&s(t);var e=c(t);e&&(A(e,!1),n&&e.removeAttribute("aria-hidden"))})),p)Object.prototype.hasOwnProperty.call(p,o)&&(p[o].destroy(),delete p[o])}function x(){O(!1)}function k(){O(!0)}return o.autoInit&&(0,r.Cd)(E),{closeAll:x,destroy:k,init:E}}},4067:function(t,e,n){n.r(e),(0,n(7788).Z)({selector:"[data-version-selector-control]"})}}]); -------------------------------------------------------------------------------- /static-files/assets/icons.b4abbede.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Generated by IcoMoon 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /static-files/assets/icons.cf61dfff.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactphp/website/c2482860b9334add7909db0840a2d793afca45e3/static-files/assets/icons.cf61dfff.woff -------------------------------------------------------------------------------- /static-files/assets/icons.f41c5641.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactphp/website/c2482860b9334add7909db0840a2d793afca45e3/static-files/assets/icons.f41c5641.ttf -------------------------------------------------------------------------------- /static-files/assets/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "main.css": "main.09dbcb8e.css", 3 | "main.js": "main.93d54642.js", 4 | "runtime.js": "runtime.124568e7.js", 5 | "553.90d4e0e8.css": "553.90d4e0e8.css", 6 | "553.da065a6b.js": "553.da065a6b.js", 7 | "139.3ced3f7b.css": "139.3ced3f7b.css", 8 | "139.820be3d5.js": "139.820be3d5.js", 9 | "67.4ae9feba.css": "67.4ae9feba.css", 10 | "67.ab055693.js": "67.ab055693.js", 11 | "261.bd162b4a.js": "261.bd162b4a.js", 12 | "sourcesanspro-regular.woff": "sourcesanspro-regular.f84b2bd4.woff", 13 | "sourcesanspro-bold.woff": "sourcesanspro-bold.cb7d3610.woff", 14 | "icons.svg?ae19fi": "icons.b4abbede.svg?ae19fi", 15 | "icons.woff?ae19fi": "icons.cf61dfff.woff?ae19fi", 16 | "icons.ttf?ae19fi": "icons.f41c5641.ttf?ae19fi", 17 | "search.svg": "search.17d09555.svg" 18 | } -------------------------------------------------------------------------------- /static-files/assets/runtime.124568e7.js: -------------------------------------------------------------------------------- 1 | !function(){"use strict";var e,t,n,r,o,i={},u={};function a(e){var t=u[e];if(void 0!==t)return t.exports;var n=u[e]={exports:{}};return i[e].call(n.exports,n,n.exports,a),n.exports}a.m=i,e=[],a.O=function(t,n,r,o){if(!n){var i=1/0;for(l=0;l=o)&&Object.keys(a.O).every((function(e){return a.O[e](n[f])}))?n.splice(f--,1):(u=!1,o0&&e[l-1][2]>o;l--)e[l]=e[l-1];e[l]=[n,r,o]},a.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(t,{a:t}),t},a.d=function(e,t){for(var n in t)a.o(t,n)&&!a.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},a.f={},a.e=function(e){return Promise.all(Object.keys(a.f).reduce((function(t,n){return a.f[n](e,t),t}),[]))},a.u=function(e){return e+"."+{67:"ab055693",139:"820be3d5",261:"bd162b4a",553:"da065a6b"}[e]+".js"},a.miniCssF=function(e){return e+"."+{67:"4ae9feba",139:"3ced3f7b",553:"90d4e0e8"}[e]+".css"},a.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),a.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t={},n="reactphp-website:",a.l=function(e,r,o,i){if(t[e])t[e].push(r);else{var u,f;if(void 0!==o)for(var c=document.getElementsByTagName("script"),l=0;lsearch 2 | -------------------------------------------------------------------------------- /static-files/assets/sourcesanspro-bold.cb7d3610.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactphp/website/c2482860b9334add7909db0840a2d793afca45e3/static-files/assets/sourcesanspro-bold.cb7d3610.woff -------------------------------------------------------------------------------- /static-files/assets/sourcesanspro-regular.f84b2bd4.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactphp/website/c2482860b9334add7909db0840a2d793afca45e3/static-files/assets/sourcesanspro-regular.f84b2bd4.woff -------------------------------------------------------------------------------- /static-files/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | #f4f3f1 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /static-files/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactphp/website/c2482860b9334add7909db0840a2d793afca45e3/static-files/favicon-32x32.png -------------------------------------------------------------------------------- /static-files/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactphp/website/c2482860b9334add7909db0840a2d793afca45e3/static-files/favicon.ico -------------------------------------------------------------------------------- /static-files/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ReactPHP", 3 | "icons": [ 4 | { 5 | "src": "android-chrome-192x192.png", 6 | "sizes": "192x192", 7 | "type": "image/png" 8 | }, 9 | { 10 | "src": "android-chrome-512x512.png", 11 | "sizes": "512x512", 12 | "type": "image/png" 13 | } 14 | ], 15 | "theme_color": "#f4f3f1", 16 | "background_color": "#f4f3f1", 17 | "display": "standalone" 18 | } -------------------------------------------------------------------------------- /static-files/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactphp/website/c2482860b9334add7909db0840a2d793afca45e3/static-files/mstile-150x150.png -------------------------------------------------------------------------------- /static-files/og-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactphp/website/c2482860b9334add7909db0840a2d793afca45e3/static-files/og-image.png -------------------------------------------------------------------------------- /static-files/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /static-files/safari-pinned-tab.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /theme/assets/components/component-info/index.js: -------------------------------------------------------------------------------- 1 | import './style.css'; 2 | -------------------------------------------------------------------------------- /theme/assets/components/component-info/style.css: -------------------------------------------------------------------------------- 1 | @import "../../styles/variables.css"; 2 | 3 | .component-info { 4 | position: sticky; 5 | top: 16px; 6 | bottom: 16px; 7 | padding: 24px; 8 | background-color: var(--color-background-lighter); 9 | box-shadow: var(--box-shadow-lighter); 10 | border-radius: 4px; 11 | color: var(--color-base); 12 | 13 | font-size: .875rem; 14 | 15 | & a, 16 | & a [class*="icon"] { 17 | color: var(--color-base); 18 | } 19 | 20 | & a:hover { 21 | color: var(--color-base-light); 22 | text-decoration: none; 23 | } 24 | 25 | & pre { 26 | line-height: 1; 27 | font-size: .75rem; 28 | } 29 | } 30 | 31 | .component-info__title { 32 | display: flex; 33 | font-size: 1.5rem; 34 | line-height: 1rem; 35 | margin-bottom: 1rem; 36 | color: var(--color-base); 37 | align-items: center; 38 | 39 | & a { 40 | text-decoration: none; 41 | } 42 | 43 | & > *:not(:last-child) { 44 | margin-right: 8px; 45 | } 46 | } 47 | 48 | .component-info__subtitle { 49 | font-size: .875rem; 50 | line-height: .875rem; 51 | font-weight: bold; 52 | text-transform: uppercase; 53 | letter-spacing: .1em; 54 | margin-bottom: .875rem; 55 | color: var(--color-base-light); 56 | } 57 | 58 | .component-info__info { 59 | padding: 0; 60 | list-style: none; 61 | display: flex; 62 | flex-flow: row; 63 | justify-content: flex-start; 64 | 65 | & li { 66 | margin-right: 16px; 67 | 68 | &:last-child { 69 | margin-right: 0; 70 | } 71 | } 72 | 73 | & a { 74 | font-size: .75rem; 75 | text-decoration: none; 76 | white-space: nowrap; 77 | text-overflow: ellipsis; 78 | } 79 | } 80 | 81 | .component-info__contributors { 82 | display: flex; 83 | flex-wrap: wrap; 84 | padding: 0; 85 | list-style: none; 86 | 87 | & li { 88 | padding: 0 4px 4px 0; 89 | margin: 0; 90 | } 91 | 92 | & img { 93 | display: block; 94 | width: 40px; 95 | height: auto; 96 | border-radius: 2px; 97 | box-shadow: var(--box-shadow-lighter); 98 | } 99 | } 100 | 101 | .component-info__participation { 102 | background-color: var(--color-background-lightest); 103 | box-shadow: var(--box-shadow-lighter); 104 | padding: 8px; 105 | border-radius: 4px; 106 | text-align: center; 107 | 108 | & svg { 109 | display: block; 110 | margin: auto; 111 | max-width: 100%; 112 | height: auto !important; 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /theme/assets/components/docsearch/algolia-autocomplete.css: -------------------------------------------------------------------------------- 1 | .algolia-autocomplete { 2 | display: block; 3 | width: 100%; 4 | height: 100%; 5 | } 6 | 7 | .algolia-autocomplete.algolia-autocomplete-right .ds-dropdown-menu { 8 | right: 0 !important; 9 | left: inherit !important; 10 | } 11 | 12 | .algolia-autocomplete.algolia-autocomplete-right .ds-dropdown-menu:before { 13 | right: 48px; 14 | } 15 | 16 | .algolia-autocomplete.algolia-autocomplete-left .ds-dropdown-menu { 17 | left: 0 !important; 18 | right: inherit !important; 19 | } 20 | 21 | .algolia-autocomplete.algolia-autocomplete-left .ds-dropdown-menu:before { 22 | left: 48px; 23 | } 24 | 25 | .algolia-autocomplete .ds-dropdown-menu { 26 | position: relative; 27 | top: -6px; 28 | border-radius: 4px; 29 | margin: 6px 0 0; 30 | padding: 0; 31 | text-align: left; 32 | height: auto; 33 | position: relative; 34 | background: transparent; 35 | border: none; 36 | z-index: 999; 37 | max-width: 600px; 38 | min-width: 500px; 39 | box-shadow: 0 1px 0 0 rgba(0, 0, 0, 0.2), 0 2px 3px 0 rgba(0, 0, 0, 0.1); 40 | } 41 | 42 | .algolia-autocomplete .ds-dropdown-menu:before { 43 | display: block; 44 | position: absolute; 45 | content: ''; 46 | width: 14px; 47 | height: 14px; 48 | background: #fff; 49 | z-index: 1000; 50 | top: -7px; 51 | border-top: 1px solid #d9d9d9; 52 | border-right: 1px solid #d9d9d9; 53 | -webkit-transform: rotate(-45deg); 54 | transform: rotate(-45deg); 55 | border-radius: 2px; 56 | } 57 | 58 | .algolia-autocomplete .ds-dropdown-menu .ds-suggestions { 59 | position: relative; 60 | z-index: 1000; 61 | margin-top: 8px; 62 | } 63 | 64 | .algolia-autocomplete .ds-dropdown-menu .ds-suggestion { 65 | cursor: pointer; 66 | } 67 | 68 | .algolia-autocomplete .ds-dropdown-menu .ds-suggestion.ds-cursor .algolia-docsearch-suggestion.suggestion-layout-simple { 69 | background-color: rgba(69, 142, 225, 0.05); 70 | } 71 | 72 | .algolia-autocomplete .ds-dropdown-menu .ds-suggestion.ds-cursor .algolia-docsearch-suggestion:not(.suggestion-layout-simple) .algolia-docsearch-suggestion--content { 73 | background-color: rgba(69, 142, 225, 0.05); 74 | } 75 | 76 | .algolia-autocomplete .ds-dropdown-menu [class^="ds-dataset-"] { 77 | position: relative; 78 | border: solid 1px #d9d9d9; 79 | background: #fff; 80 | border-radius: 4px; 81 | overflow: auto; 82 | padding: 0 8px 8px; 83 | } 84 | 85 | .algolia-autocomplete .ds-dropdown-menu * { 86 | box-sizing: border-box; 87 | } 88 | 89 | .algolia-autocomplete .algolia-docsearch-suggestion { 90 | position: relative; 91 | padding: 0 8px; 92 | background: #fff; 93 | color: #02060C; 94 | overflow: hidden; 95 | } 96 | 97 | .algolia-autocomplete .algolia-docsearch-suggestion--highlight { 98 | color: #174d8c; 99 | background: rgba(143, 187, 237, 0.1); 100 | padding: 0.1em 0.05em; 101 | } 102 | 103 | .algolia-autocomplete .algolia-docsearch-suggestion--category-header .algolia-docsearch-suggestion--category-header-lvl0 .algolia-docsearch-suggestion--highlight, 104 | .algolia-autocomplete .algolia-docsearch-suggestion--category-header .algolia-docsearch-suggestion--category-header-lvl1 .algolia-docsearch-suggestion--highlight { 105 | color: inherit; 106 | background: inherit; 107 | } 108 | 109 | .algolia-autocomplete .algolia-docsearch-suggestion--text .algolia-docsearch-suggestion--highlight { 110 | padding: 0 0 1px; 111 | background: inherit; 112 | box-shadow: inset 0 -2px 0 0 rgba(69, 142, 225, 0.8); 113 | color: inherit; 114 | } 115 | 116 | .algolia-autocomplete .algolia-docsearch-suggestion--content { 117 | display: block; 118 | float: right; 119 | width: 70%; 120 | position: relative; 121 | padding: 5.33333px 0 5.33333px 10.66667px; 122 | cursor: pointer; 123 | } 124 | 125 | .algolia-autocomplete .algolia-docsearch-suggestion--content:before { 126 | content: ''; 127 | position: absolute; 128 | display: block; 129 | top: 0; 130 | height: 100%; 131 | width: 1px; 132 | background: #ddd; 133 | left: -1px; 134 | } 135 | 136 | .algolia-autocomplete .algolia-docsearch-suggestion--category-header { 137 | position: relative; 138 | border-bottom: 1px solid #ddd; 139 | display: none; 140 | margin-top: 8px; 141 | padding: 4px 0; 142 | font-size: 1em; 143 | color: #33363D; 144 | } 145 | 146 | .algolia-autocomplete .algolia-docsearch-suggestion--wrapper { 147 | width: 100%; 148 | float: left; 149 | padding: 8px 0 0 0; 150 | } 151 | 152 | .algolia-autocomplete .algolia-docsearch-suggestion--subcategory-column { 153 | float: left; 154 | width: 30%; 155 | display: none; 156 | padding-left: 0; 157 | text-align: right; 158 | position: relative; 159 | padding: 5.33333px 10.66667px; 160 | color: #A4A7AE; 161 | font-size: 0.9em; 162 | word-wrap: break-word; 163 | } 164 | 165 | .algolia-autocomplete .algolia-docsearch-suggestion--subcategory-column:before { 166 | content: ''; 167 | position: absolute; 168 | display: block; 169 | top: 0; 170 | height: 100%; 171 | width: 1px; 172 | background: #ddd; 173 | right: 0; 174 | } 175 | 176 | .algolia-autocomplete .algolia-docsearch-suggestion--subcategory-column .algolia-docsearch-suggestion--highlight { 177 | background-color: inherit; 178 | color: inherit; 179 | } 180 | 181 | .algolia-autocomplete .algolia-docsearch-suggestion--subcategory-inline { 182 | display: none; 183 | } 184 | 185 | .algolia-autocomplete .algolia-docsearch-suggestion--title { 186 | margin-bottom: 4px; 187 | color: #02060C; 188 | font-size: 0.9em; 189 | font-weight: bold; 190 | } 191 | 192 | .algolia-autocomplete .algolia-docsearch-suggestion--text { 193 | display: block; 194 | line-height: 1.2em; 195 | font-size: 0.85em; 196 | color: #63676D; 197 | } 198 | 199 | .algolia-autocomplete .algolia-docsearch-suggestion--no-results { 200 | width: 100%; 201 | padding: 8px 0; 202 | text-align: center; 203 | font-size: 1.2em; 204 | } 205 | 206 | .algolia-autocomplete .algolia-docsearch-suggestion--no-results::before { 207 | display: none; 208 | } 209 | 210 | .algolia-autocomplete .algolia-docsearch-suggestion code { 211 | padding: 1px 5px; 212 | font-size: 90%; 213 | border: none; 214 | color: #222222; 215 | background-color: #EBEBEB; 216 | border-radius: 3px; 217 | font-family: Menlo,Monaco,Consolas,"Courier New",monospace; 218 | } 219 | 220 | .algolia-autocomplete .algolia-docsearch-suggestion code .algolia-docsearch-suggestion--highlight { 221 | background: none; 222 | } 223 | 224 | .algolia-autocomplete .algolia-docsearch-suggestion.algolia-docsearch-suggestion__main .algolia-docsearch-suggestion--category-header { 225 | display: block; 226 | } 227 | 228 | .algolia-autocomplete .algolia-docsearch-suggestion.algolia-docsearch-suggestion__secondary .algolia-docsearch-suggestion--subcategory-column { 229 | display: block; 230 | } 231 | 232 | .algolia-autocomplete .suggestion-layout-simple.algolia-docsearch-suggestion { 233 | border-bottom: solid 1px #eee; 234 | padding: 8px; 235 | margin: 0; 236 | } 237 | 238 | .algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--content { 239 | width: 100%; 240 | padding: 0; 241 | } 242 | 243 | .algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--content::before { 244 | display: none; 245 | } 246 | 247 | .algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--category-header { 248 | margin: 0; 249 | padding: 0; 250 | display: block; 251 | width: 100%; 252 | border: none; 253 | } 254 | 255 | .algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--category-header-lvl0 { 256 | opacity: .6; 257 | font-size: 0.85em; 258 | } 259 | 260 | .algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--category-header-lvl1 { 261 | opacity: .6; 262 | font-size: 0.85em; 263 | } 264 | 265 | .algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--category-header-lvl1::before { 266 | background-image: url('data:image/svg+xml;utf8,'); 267 | content: ''; 268 | width: 10px; 269 | height: 10px; 270 | display: inline-block; 271 | } 272 | 273 | .algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--wrapper { 274 | width: 100%; 275 | float: left; 276 | margin: 0; 277 | padding: 0; 278 | } 279 | 280 | .algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--subcategory-column, .algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--duplicate-content, .algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--subcategory-inline { 281 | display: none !important; 282 | } 283 | 284 | .algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--title { 285 | margin: 0; 286 | color: #458EE1; 287 | font-size: 0.9em; 288 | font-weight: normal; 289 | } 290 | 291 | .algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--title::before { 292 | content: "#"; 293 | font-weight: bold; 294 | color: #458EE1; 295 | display: inline-block; 296 | } 297 | 298 | .algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--text { 299 | margin: 4px 0 0; 300 | display: block; 301 | line-height: 1.4em; 302 | padding: 5.33333px 8px; 303 | background: #f8f8f8; 304 | font-size: 0.85em; 305 | opacity: .8; 306 | } 307 | 308 | .algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--text .algolia-docsearch-suggestion--highlight { 309 | color: #3f4145; 310 | font-weight: bold; 311 | box-shadow: none; 312 | } 313 | 314 | .algolia-autocomplete .algolia-docsearch-footer { 315 | width: 110px; 316 | height: 20px; 317 | z-index: 2000; 318 | margin-top: 10.66667px; 319 | float: right; 320 | font-size: 0; 321 | line-height: 0; 322 | } 323 | 324 | .algolia-autocomplete .algolia-docsearch-footer--logo { 325 | background-image: url("data:image/svg+xml;utf8,"); 326 | background-repeat: no-repeat; 327 | background-position: center; 328 | background-size: 100%; 329 | overflow: hidden; 330 | text-indent: -9000px; 331 | padding: 0 !important; 332 | width: 100%; 333 | height: 100%; 334 | display: block; 335 | } 336 | -------------------------------------------------------------------------------- /theme/assets/components/docsearch/algolia-autocomplete.js: -------------------------------------------------------------------------------- 1 | import docsearch from 'docsearch.js'; 2 | 3 | import './algolia-autocomplete.css'; 4 | 5 | let idCounter = 0; 6 | 7 | export function init(input) { 8 | let id = input.getAttribute('id'); 9 | 10 | if (!id) { 11 | id = 'docsearch-' + idCounter++; 12 | input.setAttribute('id', id); 13 | } 14 | 15 | docsearch({ 16 | apiKey: '4c440463ddff54a35b4d7dc24afb010b', 17 | indexName: 'reactphp', 18 | inputSelector: '#' + id, 19 | debug: 'true' === input.getAttribute('data-docsearch-debug'), 20 | algoliaOptions: { 21 | hitsPerPage: 5 22 | } 23 | }); 24 | } 25 | -------------------------------------------------------------------------------- /theme/assets/components/docsearch/index.js: -------------------------------------------------------------------------------- 1 | import {ready, find} from 'domestique'; 2 | 3 | // Workaround for https://github.com/algolia/algoliasearch-client-javascript/issues/691 4 | window.process = { 5 | env: { DEBUG: undefined } 6 | }; 7 | 8 | ready(() => { 9 | find('[data-docsearch]:not([data-docsearch-initialized])').forEach(element => { 10 | element.setAttribute('data-docsearch-initialized', true); 11 | 12 | import('./algolia-autocomplete.js').then(module => { 13 | module.init(element); 14 | }); 15 | }) 16 | }); 17 | -------------------------------------------------------------------------------- /theme/assets/components/off-canvas-menu/index.css: -------------------------------------------------------------------------------- 1 | @import "../../styles/variables.css"; 2 | 3 | .off-canvas-menu { 4 | position: fixed; 5 | top: 0; 6 | right: 0; 7 | pointer-events: none; 8 | } 9 | 10 | .off-canvas-menu__content { 11 | transform: translate3d(105%, 0, 0); 12 | } 13 | -------------------------------------------------------------------------------- /theme/assets/components/off-canvas-menu/index.js: -------------------------------------------------------------------------------- 1 | import './index.css'; 2 | 3 | import('./menu.js'); 4 | -------------------------------------------------------------------------------- /theme/assets/components/off-canvas-menu/menu.css: -------------------------------------------------------------------------------- 1 | @import "../../styles/variables.css"; 2 | 3 | .off-canvas-menu { 4 | width: 300px; 5 | height: 100%; 6 | z-index: 1000; 7 | overflow-y: auto; 8 | overflow-x: hidden; 9 | outline: none; 10 | 11 | &[aria-hidden="false"] { 12 | pointer-events: auto; 13 | } 14 | } 15 | 16 | .off-canvas-menu__content { 17 | position: absolute; 18 | right: 0; 19 | width: 285px; 20 | height: 100%; 21 | overflow-y: auto; 22 | overflow-x: hidden; 23 | background: var(--color-background-lightest); 24 | box-shadow: 0 0 15px rgba(0, 0, 0, 0.33); 25 | 26 | -webkit-overflow-scrolling: touch; 27 | transition: all .35s cubic-bezier(0.23, 1, 0.32, 1); 28 | } 29 | 30 | .off-canvas-menu[aria-hidden="false"] { 31 | & .off-canvas-menu__content { 32 | transform: translate3D(0, 0, 0); 33 | } 34 | } 35 | 36 | .off-canvas-menu__close { 37 | /* reset */ 38 | -webkit-appearance: none; 39 | background: none; 40 | border: 0; 41 | margin: 0; 42 | padding: 0; 43 | text-shadow: none; 44 | text-decoration: none; 45 | text-transform: none; 46 | overflow: visible; 47 | cursor: pointer; 48 | outline: none; 49 | 50 | position: absolute; 51 | right: 0; 52 | top: 0; 53 | width: 48px; 54 | height: 48px; 55 | z-index: 1001; 56 | display: flex; 57 | justify-content: center; 58 | align-items: center; 59 | 60 | color: var(--color-base); 61 | font-size: 20px; 62 | 63 | &:hover { 64 | color: var(--color-green); 65 | } 66 | } 67 | 68 | .off-canvas-menu__section { 69 | padding: 8px 0; 70 | border-top: 1px solid var(--color-background-light); 71 | } 72 | 73 | .off-canvas-menu__list { 74 | margin: 0; 75 | padding: 0; 76 | list-style: none; 77 | } 78 | 79 | .off-canvas-menu__link { 80 | display: flex; 81 | justify-content: space-between; 82 | text-decoration: none; 83 | padding: 8px 16px; 84 | font-size: .9rem; 85 | line-height: 1; 86 | color: var(--color-base); 87 | 88 | &:hover { 89 | color: var(--color-green); 90 | text-decoration: none; 91 | } 92 | } 93 | 94 | .off-canvas-menu__version { 95 | display: inline-block; 96 | line-height: 1; 97 | padding: .25rem; 98 | border-radius: 4px; 99 | border: 1px solid var(--color-background); 100 | color: var(--color-base-light); 101 | font-size: .65rem; 102 | text-decoration: none; 103 | 104 | @nest .off-canvas-menu__link:hover & { 105 | border-color: var(--color-green); 106 | color: var(--color-green); 107 | } 108 | } 109 | 110 | .off-canvas-menu__section-top, 111 | .off-canvas-menu__section-header { 112 | text-transform: uppercase; 113 | letter-spacing: .1rem; 114 | color: var(--color-base-light); 115 | padding: 8px 16px 16px 16px; 116 | margin: 0; 117 | font-weight: bold; 118 | font-size: .9rem !important; 119 | } 120 | 121 | .off-canvas-menu__section-top { 122 | display: block; 123 | color: var(--color-base); 124 | padding: 8px 16px; 125 | font-size: .9rem; 126 | line-height: 1rem; 127 | text-decoration: none; 128 | 129 | &:hover { 130 | color: var(--color-green); 131 | text-decoration: none; 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /theme/assets/components/off-canvas-menu/menu.js: -------------------------------------------------------------------------------- 1 | import ctrly from 'ctrly/src/ctrly'; 2 | 3 | import './menu.css'; 4 | 5 | ctrly({selector: '[data-off-canvas-menu-control]', closeOnScroll: true}); 6 | -------------------------------------------------------------------------------- /theme/assets/components/version-selector/index.css: -------------------------------------------------------------------------------- 1 | @import "../../styles/variables.css"; 2 | 3 | .version-selector { 4 | position: relative; 5 | font-size: .875rem; 6 | color: #fff; 7 | 8 | & :last-child { 9 | margin-bottom: 0; 10 | } 11 | } 12 | 13 | .version-selector__button, 14 | .version-selector__version { 15 | /* reset */ 16 | -webkit-appearance: none; 17 | border: 0; 18 | margin: 0; 19 | text-shadow: none; 20 | box-shadow: none; 21 | text-decoration: none; 22 | text-transform: none; 23 | overflow: visible; 24 | cursor: pointer; 25 | outline: none; 26 | 27 | display: flex; 28 | background-color: var(--color-base); 29 | box-shadow: var(--box-shadow-lighter); 30 | color: #fff; 31 | font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace; 32 | font-size: .75rem; 33 | font-weight: bolder; 34 | letter-spacing: normal; 35 | padding: .25rem .4rem .2rem .4rem; 36 | border-radius: 4px; 37 | } 38 | 39 | .version-selector__button { 40 | position: relative; 41 | 42 | & [class="icon-chevron-down"] { 43 | display: inline-block; 44 | margin-left: 4px; 45 | } 46 | & [class="icon-chevron-up"] { 47 | display: none; 48 | margin-left: 4px; 49 | } 50 | } 51 | .version-selector__version { 52 | background-color: rgba(255, 255, 255, .33); 53 | border: 1px solid transparent; 54 | text-decoration: none; 55 | color: #fff !important; 56 | 57 | &:hover { 58 | background-color: rgba(255, 255, 255, .11); 59 | border: 1px solid rgba(255, 255, 255, .22); 60 | } 61 | } 62 | 63 | .version-selector__button--dev, 64 | .version-selector__version--dev { 65 | background-color: var(--color-red); 66 | } 67 | 68 | .version-selector__version--dev { 69 | &:hover { 70 | background-color: var(--color-red); 71 | } 72 | } 73 | 74 | .version-selector__button--latest, 75 | .version-selector__version--latest { 76 | background-color: var(--color-green); 77 | } 78 | 79 | .version-selector__version--latest { 80 | &:hover { 81 | background-color: var(--color-green); 82 | } 83 | } 84 | 85 | .version-selector__panel { 86 | position: fixed; 87 | top: -20000em; 88 | visibility: hidden; 89 | } 90 | -------------------------------------------------------------------------------- /theme/assets/components/version-selector/index.js: -------------------------------------------------------------------------------- 1 | import './index.css'; 2 | 3 | import('./selector.js'); 4 | -------------------------------------------------------------------------------- /theme/assets/components/version-selector/selector.css: -------------------------------------------------------------------------------- 1 | @import "../../styles/variables.css"; 2 | 3 | .version-selector__button { 4 | &[aria-expanded="true"] { 5 | z-index: 999; 6 | background: var(--color-base) !important; 7 | border-bottom-left-radius: 0; 8 | border-bottom-right-radius: 0; 9 | box-shadow: none; 10 | 11 | & [class="icon-chevron-down"] { 12 | display: none; 13 | } 14 | & [class="icon-chevron-up"] { 15 | display: inline-block; 16 | } 17 | } 18 | } 19 | 20 | .version-selector__panel { 21 | z-index: 998; 22 | left: -115px; 23 | 24 | background: var(--color-base); 25 | padding: 1rem; 26 | width: 300px; 27 | border-radius: 4px; 28 | outline: none; 29 | box-shadow: 0 0 8px rgba(0, 0, 0, .33); 30 | 31 | font-weight: normal; 32 | 33 | &[aria-hidden="false"] { 34 | position: absolute; 35 | visibility: visible; 36 | top: auto; 37 | } 38 | } 39 | 40 | .version-selector__list { 41 | display: flex; 42 | flex-wrap: wrap; 43 | padding: 0; 44 | list-style: none; 45 | margin-left: -4px; 46 | 47 | & li { 48 | margin: 4px; 49 | width: calc(25% - 8px); 50 | } 51 | 52 | & a { 53 | display: block; 54 | text-align: center; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /theme/assets/components/version-selector/selector.js: -------------------------------------------------------------------------------- 1 | import ctrly from 'ctrly/src/ctrly'; 2 | 3 | import './selector.css'; 4 | 5 | ctrly({selector: '[data-version-selector-control]'}); 6 | -------------------------------------------------------------------------------- /theme/assets/fonts/fonts.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'Source Sans Pro'; 3 | font-style: normal; 4 | font-weight: 400; 5 | font-display: swap; 6 | src: local("Source Sans Pro Regular"), 7 | local("SourceSansPro-Regular"), 8 | url("sourcesanspro-regular.woff") format("woff"); 9 | } 10 | 11 | @font-face { 12 | font-family: 'Source Sans Pro'; 13 | font-style: normal; 14 | font-weight: 700; 15 | font-display: swap; 16 | src: local("Source Sans Pro Bold"), 17 | local("SourceSansPro-Bold"), 18 | url("sourcesanspro-bold.woff") format("woff"); 19 | } 20 | 21 | -------------------------------------------------------------------------------- /theme/assets/fonts/sourcesanspro-bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactphp/website/c2482860b9334add7909db0840a2d793afca45e3/theme/assets/fonts/sourcesanspro-bold.woff -------------------------------------------------------------------------------- /theme/assets/fonts/sourcesanspro-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactphp/website/c2482860b9334add7909db0840a2d793afca45e3/theme/assets/fonts/sourcesanspro-regular.woff -------------------------------------------------------------------------------- /theme/assets/icons/fonts/icons.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Generated by IcoMoon 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /theme/assets/icons/fonts/icons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactphp/website/c2482860b9334add7909db0840a2d793afca45e3/theme/assets/icons/fonts/icons.ttf -------------------------------------------------------------------------------- /theme/assets/icons/fonts/icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactphp/website/c2482860b9334add7909db0840a2d793afca45e3/theme/assets/icons/fonts/icons.woff -------------------------------------------------------------------------------- /theme/assets/icons/icons.css: -------------------------------------------------------------------------------- 1 | @import "./style.css"; 2 | 3 | [class^="icon-"], [class*=" icon-"] { 4 | vertical-align: -8%; 5 | } 6 | -------------------------------------------------------------------------------- /theme/assets/icons/selection.json: -------------------------------------------------------------------------------- 1 | { 2 | "IcoMoonType": "selection", 3 | "icons": [ 4 | { 5 | "icon": { 6 | "paths": [ 7 | "M896 384v-128h-160.128l32-256h-128l-32 256h-255.936l32-256h-128l-32 256h-223.936v128h207.936l-31.936 256h-176v128h160l-32 256h128l32-256h255.936l-32 256h128.064l32-256h224v-128h-208l31.872-256h176.128zM559.936 640h-255.936l31.936-256h255.936l-31.936 256z" 8 | ], 9 | "width": 896, 10 | "attrs": [ 11 | {} 12 | ], 13 | "isMulticolor": false, 14 | "isMulticolor2": false, 15 | "tags": [ 16 | "hash", 17 | "number" 18 | ], 19 | "grid": 16 20 | }, 21 | "attrs": [ 22 | {} 23 | ], 24 | "properties": { 25 | "order": 1, 26 | "id": 0, 27 | "prevSize": 32, 28 | "name": "hash", 29 | "code": 59648 30 | }, 31 | "setIdx": 0, 32 | "setId": 3, 33 | "iconIdx": 0 34 | }, 35 | { 36 | "icon": { 37 | "paths": [ 38 | "M1024 194.418c-37.676 16.708-78.164 28.002-120.66 33.080 43.372-26 76.686-67.17 92.372-116.23-40.596 24.078-85.556 41.56-133.41 50.98-38.32-40.83-92.922-66.34-153.346-66.34-116.022 0-210.088 94.058-210.088 210.078 0 16.466 1.858 32.5 5.44 47.878-174.6-8.764-329.402-92.4-433.018-219.506-18.084 31.028-28.446 67.116-28.446 105.618 0 72.888 37.088 137.192 93.46 174.866-34.438-1.092-66.832-10.542-95.154-26.278-0.020 0.876-0.020 1.756-0.020 2.642 0 101.788 72.418 186.696 168.522 206-17.626 4.8-36.188 7.372-55.348 7.372-13.538 0-26.698-1.32-39.528-3.772 26.736 83.46 104.32 144.206 196.252 145.896-71.9 56.35-162.486 89.934-260.916 89.934-16.958 0-33.68-0.994-50.116-2.94 92.972 59.61 203.402 94.394 322.042 94.394 386.422 0 597.736-320.124 597.736-597.744 0-9.108-0.206-18.168-0.61-27.18 41.056-29.62 76.672-66.62 104.836-108.748z" 39 | ], 40 | "attrs": [], 41 | "isMulticolor": false, 42 | "isMulticolor2": false, 43 | "tags": [ 44 | "twitter", 45 | "brand", 46 | "tweet", 47 | "social" 48 | ], 49 | "grid": 16 50 | }, 51 | "attrs": [], 52 | "properties": { 53 | "id": 1, 54 | "order": 22, 55 | "prevSize": 32, 56 | "ligatures": "twitter, brand11", 57 | "name": "twitter", 58 | "code": 59649 59 | }, 60 | "setIdx": 0, 61 | "setId": 3, 62 | "iconIdx": 1 63 | }, 64 | { 65 | "icon": { 66 | "paths": [ 67 | "M512.008 12.642c-282.738 0-512.008 229.218-512.008 511.998 0 226.214 146.704 418.132 350.136 485.836 25.586 4.738 34.992-11.11 34.992-24.632 0-12.204-0.48-52.542-0.696-95.324-142.448 30.976-172.504-60.41-172.504-60.41-23.282-59.176-56.848-74.916-56.848-74.916-46.452-31.778 3.51-31.124 3.51-31.124 51.4 3.61 78.476 52.766 78.476 52.766 45.672 78.27 119.776 55.64 149.004 42.558 4.588-33.086 17.852-55.68 32.506-68.464-113.73-12.942-233.276-56.85-233.276-253.032 0-55.898 20.004-101.574 52.76-137.428-5.316-12.9-22.854-64.972 4.952-135.5 0 0 43.006-13.752 140.84 52.49 40.836-11.348 84.636-17.036 128.154-17.234 43.502 0.198 87.336 5.886 128.256 17.234 97.734-66.244 140.656-52.49 140.656-52.49 27.872 70.528 10.35 122.6 5.036 135.5 32.82 35.856 52.694 81.532 52.694 137.428 0 196.654-119.778 239.95-233.79 252.624 18.364 15.89 34.724 47.046 34.724 94.812 0 68.508-0.596 123.644-0.596 140.508 0 13.628 9.222 29.594 35.172 24.566 203.322-67.776 349.842-259.626 349.842-485.768 0-282.78-229.234-511.998-511.992-511.998z" 68 | ], 69 | "attrs": [], 70 | "isMulticolor": false, 71 | "isMulticolor2": false, 72 | "tags": [ 73 | "github", 74 | "brand", 75 | "octacat", 76 | "social" 77 | ], 78 | "grid": 16 79 | }, 80 | "attrs": [], 81 | "properties": { 82 | "order": 21, 83 | "id": 2, 84 | "prevSize": 32, 85 | "ligatures": "github, brand40", 86 | "name": "github", 87 | "code": 59650 88 | }, 89 | "setIdx": 0, 90 | "setId": 3, 91 | "iconIdx": 2 92 | }, 93 | { 94 | "icon": { 95 | "paths": [ 96 | "M384 0v96c73.482 0 144.712 14.37 211.716 42.71 64.768 27.394 122.958 66.632 172.948 116.624s89.228 108.18 116.624 172.948c28.342 67.004 42.712 138.238 42.712 211.718h96c0-353.46-286.54-640-640-640z", 97 | "M384 192v96c94.022 0 182.418 36.614 248.9 103.098 66.486 66.484 103.1 154.878 103.1 248.902h96c0-247.422-200.576-448-448-448z", 98 | "M480 384l-64 64-224 64-192 416 25.374 25.374 232.804-232.804c-1.412-5.286-2.178-10.84-2.178-16.57 0-35.346 28.654-64 64-64s64 28.654 64 64-28.654 64-64 64c-5.732 0-11.282-0.764-16.568-2.178l-232.804 232.804 25.372 25.374 416-192 64-224 64-64-160-160z" 99 | ], 100 | "attrs": [], 101 | "isMulticolor": false, 102 | "isMulticolor2": false, 103 | "tags": [ 104 | "blog", 105 | "pen", 106 | "feed", 107 | "publish", 108 | "broadcast", 109 | "write" 110 | ], 111 | "grid": 16 112 | }, 113 | "attrs": [], 114 | "properties": { 115 | "id": 3, 116 | "order": 4, 117 | "prevSize": 32, 118 | "ligatures": "blog, pen2", 119 | "name": "blog", 120 | "code": 59653 121 | }, 122 | "setIdx": 0, 123 | "setId": 3, 124 | "iconIdx": 3 125 | }, 126 | { 127 | "icon": { 128 | "paths": [ 129 | "M512 0c-282.77 0-512 229.23-512 512s229.23 512 512 512 512-229.23 512-512-229.23-512-512-512zM512 960.002c-62.958 0-122.872-13.012-177.23-36.452l233.148-262.29c5.206-5.858 8.082-13.422 8.082-21.26v-96c0-17.674-14.326-32-32-32-112.99 0-232.204-117.462-233.374-118.626-6-6.002-14.14-9.374-22.626-9.374h-128c-17.672 0-32 14.328-32 32v192c0 12.122 6.848 23.202 17.69 28.622l110.31 55.156v187.886c-116.052-80.956-192-215.432-192-367.664 0-68.714 15.49-133.806 43.138-192h116.862c8.488 0 16.626-3.372 22.628-9.372l128-128c6-6.002 9.372-14.14 9.372-22.628v-77.412c40.562-12.074 83.518-18.588 128-18.588 70.406 0 137.004 16.26 196.282 45.2-4.144 3.502-8.176 7.164-12.046 11.036-36.266 36.264-56.236 84.478-56.236 135.764s19.97 99.5 56.236 135.764c36.434 36.432 85.218 56.264 135.634 56.26 3.166 0 6.342-0.080 9.518-0.236 13.814 51.802 38.752 186.656-8.404 372.334-0.444 1.744-0.696 3.488-0.842 5.224-81.324 83.080-194.7 134.656-320.142 134.656z" 130 | ], 131 | "attrs": [], 132 | "isMulticolor": false, 133 | "isMulticolor2": false, 134 | "tags": [ 135 | "earth", 136 | "globe", 137 | "language", 138 | "web", 139 | "internet", 140 | "sphere", 141 | "planet" 142 | ], 143 | "grid": 16 144 | }, 145 | "attrs": [], 146 | "properties": { 147 | "order": 2, 148 | "id": 4, 149 | "prevSize": 32, 150 | "ligatures": "earth, globe2", 151 | "name": "earth", 152 | "code": 59651 153 | }, 154 | "setIdx": 0, 155 | "setId": 3, 156 | "iconIdx": 4 157 | }, 158 | { 159 | "icon": { 160 | "paths": [ 161 | "M440.236 635.766c-13.31 0-26.616-5.076-36.77-15.23-95.134-95.136-95.134-249.934 0-345.070l192-192c46.088-46.086 107.36-71.466 172.534-71.466s126.448 25.38 172.536 71.464c95.132 95.136 95.132 249.934 0 345.070l-87.766 87.766c-20.308 20.308-53.23 20.308-73.54 0-20.306-20.306-20.306-53.232 0-73.54l87.766-87.766c54.584-54.586 54.584-143.404 0-197.99-26.442-26.442-61.6-41.004-98.996-41.004s-72.552 14.562-98.996 41.006l-192 191.998c-54.586 54.586-54.586 143.406 0 197.992 20.308 20.306 20.306 53.232 0 73.54-10.15 10.152-23.462 15.23-36.768 15.23z", 162 | "M256 1012c-65.176 0-126.45-25.38-172.534-71.464-95.134-95.136-95.134-249.934 0-345.070l87.764-87.764c20.308-20.306 53.234-20.306 73.54 0 20.308 20.306 20.308 53.232 0 73.54l-87.764 87.764c-54.586 54.586-54.586 143.406 0 197.992 26.44 26.44 61.598 41.002 98.994 41.002s72.552-14.562 98.998-41.006l192-191.998c54.584-54.586 54.584-143.406 0-197.992-20.308-20.308-20.306-53.232 0-73.54 20.306-20.306 53.232-20.306 73.54 0.002 95.132 95.134 95.132 249.932 0.002 345.068l-192.002 192c-46.090 46.088-107.364 71.466-172.538 71.466z" 163 | ], 164 | "attrs": [], 165 | "isMulticolor": false, 166 | "isMulticolor2": false, 167 | "tags": [ 168 | "link", 169 | "chain", 170 | "url", 171 | "uri", 172 | "anchor" 173 | ], 174 | "grid": 16 175 | }, 176 | "attrs": [], 177 | "properties": { 178 | "order": 23, 179 | "id": 5, 180 | "prevSize": 32, 181 | "ligatures": "link, chain", 182 | "name": "link", 183 | "code": 59654 184 | }, 185 | "setIdx": 0, 186 | "setId": 3, 187 | "iconIdx": 5 188 | }, 189 | { 190 | "icon": { 191 | "paths": [ 192 | "M832 128h-640c-105.6 0-192 86.4-192 192v384c0 105.6 86.4 192 192 192h640c105.6 0 192-86.4 192-192v-384c0-105.6-86.4-192-192-192zM384 768v-512l320 256-320 256z" 193 | ], 194 | "attrs": [], 195 | "isMulticolor": false, 196 | "isMulticolor2": false, 197 | "tags": [ 198 | "youtube", 199 | "brand", 200 | "social" 201 | ], 202 | "grid": 16 203 | }, 204 | "attrs": [], 205 | "properties": { 206 | "id": 6, 207 | "order": 3, 208 | "prevSize": 32, 209 | "ligatures": "youtube, brand14", 210 | "name": "youtube", 211 | "code": 59652 212 | }, 213 | "setIdx": 0, 214 | "setId": 3, 215 | "iconIdx": 6 216 | }, 217 | { 218 | "icon": { 219 | "paths": [ 220 | "M768 576h-128c-34 0-64 32-64 64h256c0-34-32-64-64-64zM713 160c-167 0-209 32-233 56-24-24-66-56-233-56s-247 46-247 78v586c29-16 119-48 214-56 115-9 234 9 234 32 0 16 8 31 31 32 0 0 0 0 1 0 0 0 0 0 1 0 23-1 31-16 31-32 0-23 119-41 234-32 94 7 185 40 214 56v-586c0-32-80-78-247-78zM448 732c-30-16-103-28-192-28s-170 12-192 27c0 0 0-411 0-443s64-59 192-59 192 27 192 59 0 444 0 444zM896 731c-22-15-103-27-192-27s-162 12-192 28c0 0 0-412 0-444s64-59 192-59 192 27 192 59 0 443 0 443zM768 448h-128c-34 0-64 32-64 64h256c0-34-32-64-64-64zM768 320h-128c-34 0-64 32-64 64h256c0-34-32-64-64-64zM320 448h-128c-32 0-64 30-64 64h256c0-32-30-64-64-64zM320 576h-128c-32 0-64 30-64 64h256c0-32-30-64-64-64zM320 320h-128c-32 0-64 30-64 64h256c0-32-30-64-64-64z" 221 | ], 222 | "attrs": [], 223 | "isMulticolor": false, 224 | "isMulticolor2": false, 225 | "tags": [ 226 | "book" 227 | ], 228 | "defaultCode": 61447, 229 | "grid": 16 230 | }, 231 | "attrs": [], 232 | "properties": { 233 | "id": 7, 234 | "order": 35, 235 | "prevSize": 32, 236 | "code": 61447, 237 | "name": "book" 238 | }, 239 | "setIdx": 0, 240 | "setId": 3, 241 | "iconIdx": 7 242 | }, 243 | { 244 | "icon": { 245 | "paths": [ 246 | "M704 512h-64v128h64v-128zM576 512h-64v128h64v-128zM704 320h-64v128h64v-128zM832 512h-64v128h64v-128zM576 704h-64v128h64v-128zM768 0h-64v128h64v-128zM256 0h-64v128h64v-128zM832 320h-64v128h64v-128zM576 320h-64v128h64v-128zM320 704h-64v128h64v-128zM192 512h-64v128h64v-128zM320 512h-64v128h64v-128zM832 64v128h-192v-128h-320v128h-192v-128h-128v896h960v-896h-128zM896 896h-832v-640h832v640zM192 704h-64v128h64v-128zM448 320h-64v128h64v-128zM448 704h-64v128h64v-128zM320 320h-64v128h64v-128zM448 512h-64v128h64v-128zM704 704h-64v128h64v-128z" 247 | ], 248 | "attrs": [], 249 | "isMulticolor": false, 250 | "isMulticolor2": false, 251 | "tags": [ 252 | "calendar" 253 | ], 254 | "defaultCode": 61544, 255 | "grid": 16 256 | }, 257 | "attrs": [], 258 | "properties": { 259 | "id": 8, 260 | "order": 40, 261 | "prevSize": 32, 262 | "code": 61544, 263 | "name": "calendar" 264 | }, 265 | "setIdx": 0, 266 | "setId": 3, 267 | "iconIdx": 8 268 | }, 269 | { 270 | "icon": { 271 | "paths": [ 272 | "M512 320l-192 192-192-192-128 128 320 320 320-320-128-128z" 273 | ], 274 | "width": 640, 275 | "attrs": [], 276 | "isMulticolor": false, 277 | "isMulticolor2": false, 278 | "tags": [ 279 | "chevron-down" 280 | ], 281 | "defaultCode": 61603, 282 | "grid": 16 283 | }, 284 | "attrs": [], 285 | "properties": { 286 | "id": 9, 287 | "order": 31, 288 | "prevSize": 32, 289 | "code": 61603, 290 | "name": "chevron-down" 291 | }, 292 | "setIdx": 0, 293 | "setId": 3, 294 | "iconIdx": 9 295 | }, 296 | { 297 | "icon": { 298 | "paths": [ 299 | "M320 256l-320 320 128 128 192-192 192 192 128-128-320-320z" 300 | ], 301 | "width": 640, 302 | "attrs": [], 303 | "isMulticolor": false, 304 | "isMulticolor2": false, 305 | "tags": [ 306 | "chevron-up" 307 | ], 308 | "defaultCode": 61602, 309 | "grid": 16 310 | }, 311 | "attrs": [], 312 | "properties": { 313 | "id": 10, 314 | "order": 32, 315 | "prevSize": 32, 316 | "code": 61602, 317 | "name": "chevron-up" 318 | }, 319 | "setIdx": 0, 320 | "setId": 3, 321 | "iconIdx": 10 322 | }, 323 | { 324 | "icon": { 325 | "paths": [ 326 | "M514 192c34-1 61-28 62-62 1-37-29-67-66-66-34 1-61 28-62 62-1 37 29 67 66 66zM978 576h-18l-127-246c18-2 36-9 52-16 24-11 29-43 11-62l-1-1c-11-11-28-15-43-8-14 6-34 13-53 13-56 0-81-64-287-64s-231 64-287 64c-20 0-39-6-53-13-15-6-32-3-43 8l-1 1c-18 19-13 50 11 62 16 8 34 14 52 16l-127 246h-18c-8 0-14 7-13 15 11 64 92 113 191 113s180-49 191-113c1-8-5-15-13-15h-18l-127-245c83-7 127-49 191-49v486c-35 0-64 29-64 64h-71c-28 0-57 29-57 64h512c0-35-29-64-71-64h-57c0-35-29-64-64-64v-486c64 0 108 42 191 49l-127 245h-18c-8 0-14 7-13 15 11 64 92 113 191 113s180-49 191-113c1-8-5-15-13-15zM320 576h-192l96-180 96 180zM704 576l96-180 96 180h-192z" 327 | ], 328 | "attrs": [], 329 | "isMulticolor": false, 330 | "isMulticolor2": false, 331 | "tags": [ 332 | "law" 333 | ], 334 | "defaultCode": 61656, 335 | "grid": 16 336 | }, 337 | "attrs": [], 338 | "properties": { 339 | "id": 11, 340 | "order": 30, 341 | "prevSize": 32, 342 | "code": 61656, 343 | "name": "law" 344 | }, 345 | "setIdx": 0, 346 | "setId": 3, 347 | "iconIdx": 11 348 | }, 349 | { 350 | "icon": { 351 | "paths": [ 352 | "M960 832l-249.125-249.125c35.563-58.063 57.125-125.719 57.125-198.875 0-212.031-172-384-384-384-212.031 0-384 171.969-384 384 0 212 171.969 384 384 384 73.156 0 140.812-21.562 198.875-57l249.125 249c17.5 17.5 46.5 17.375 64 0l64-64c17.5-17.5 17.5-46.5 0-64zM384 640c-141.375 0-256-114.625-256-256s114.625-256 256-256 256 114.625 256 256-114.625 256-256 256z" 353 | ], 354 | "width": 973, 355 | "attrs": [], 356 | "isMulticolor": false, 357 | "isMulticolor2": false, 358 | "tags": [ 359 | "search" 360 | ], 361 | "defaultCode": 61486, 362 | "grid": 16 363 | }, 364 | "attrs": [], 365 | "properties": { 366 | "id": 12, 367 | "order": 38, 368 | "prevSize": 32, 369 | "name": "search", 370 | "code": 61486 371 | }, 372 | "setIdx": 0, 373 | "setId": 3, 374 | "iconIdx": 12 375 | }, 376 | { 377 | "icon": { 378 | "paths": [ 379 | "M640 320l-128-128-192 192-192-192-128 128 192 192-192 192 128 128 192-192 192 192 128-128-192-192 192-192z" 380 | ], 381 | "width": 640, 382 | "attrs": [], 383 | "isMulticolor": false, 384 | "isMulticolor2": false, 385 | "tags": [ 386 | "x" 387 | ], 388 | "defaultCode": 61569, 389 | "grid": 16 390 | }, 391 | "attrs": [], 392 | "properties": { 393 | "id": 13, 394 | "order": 39, 395 | "prevSize": 32, 396 | "code": 61569, 397 | "name": "x" 398 | }, 399 | "setIdx": 0, 400 | "setId": 3, 401 | "iconIdx": 13 402 | }, 403 | { 404 | "icon": { 405 | "paths": [ 406 | "M136.294 750.93c-75.196 0-136.292 61.334-136.292 136.076 0 75.154 61.1 135.802 136.292 135.802 75.466 0 136.494-60.648 136.494-135.802-0.002-74.742-61.024-136.076-136.494-136.076zM0.156 347.93v196.258c127.784 0 247.958 49.972 338.458 140.512 90.384 90.318 140.282 211.036 140.282 339.3h197.122c-0.002-372.82-303.282-676.070-675.862-676.070zM0.388 0v196.356c455.782 0 826.756 371.334 826.756 827.644h196.856c0-564.47-459.254-1024-1023.612-1024z" 407 | ], 408 | "tags": [ 409 | "feed", 410 | "rss", 411 | "social" 412 | ], 413 | "defaultCode": 60059, 414 | "grid": 16, 415 | "attrs": [] 416 | }, 417 | "attrs": [], 418 | "properties": { 419 | "ligatures": "feed2, rss", 420 | "name": "feed", 421 | "order": 41, 422 | "id": 412, 423 | "prevSize": 32, 424 | "code": 60059 425 | }, 426 | "setIdx": 2, 427 | "setId": 1, 428 | "iconIdx": 411 429 | } 430 | ], 431 | "height": 1024, 432 | "metadata": { 433 | "name": "icons" 434 | }, 435 | "preferences": { 436 | "showGlyphs": true, 437 | "showQuickUse": true, 438 | "showQuickUse2": true, 439 | "showSVGs": true, 440 | "fontPref": { 441 | "prefix": "icon-", 442 | "metadata": { 443 | "fontFamily": "icons", 444 | "majorVersion": 1, 445 | "minorVersion": 0 446 | }, 447 | "metrics": { 448 | "emSize": 512, 449 | "baseline": 6.25, 450 | "whitespace": 50 451 | }, 452 | "embed": false, 453 | "showMetrics": false, 454 | "showMetadata": false, 455 | "noie8": true, 456 | "ie7": false, 457 | "showSelector": true 458 | }, 459 | "imagePref": { 460 | "prefix": "icon-", 461 | "png": false, 462 | "useClassSelector": true, 463 | "color": 4473924, 464 | "bgColor": 16777215, 465 | "classSelector": ".icon", 466 | "autoHost": false, 467 | "height": 32, 468 | "columns": 16, 469 | "margin": 16 470 | }, 471 | "historySize": 100, 472 | "showCodes": false, 473 | "quickUsageToken": { 474 | "ReactPHP": "N2NhOGYwZDQwNjE5MDQ4MmUzZmVmZjgxYTliNTdiNjQjMSMxNDg2ODA4NjczIyMj" 475 | } 476 | } 477 | } -------------------------------------------------------------------------------- /theme/assets/icons/style.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'icons'; 3 | src: 4 | url('fonts/icons.ttf?ae19fi') format('truetype'), 5 | url('fonts/icons.woff?ae19fi') format('woff'), 6 | url('fonts/icons.svg?ae19fi#icons') format('svg'); 7 | font-weight: normal; 8 | font-style: normal; 9 | } 10 | 11 | [class^="icon-"], [class*=" icon-"] { 12 | /* use !important to prevent issues with browser extensions that change fonts */ 13 | font-family: 'icons' !important; 14 | speak: none; 15 | font-style: normal; 16 | font-weight: normal; 17 | font-variant: normal; 18 | text-transform: none; 19 | line-height: 1; 20 | 21 | /* Better Font Rendering =========== */ 22 | -webkit-font-smoothing: antialiased; 23 | -moz-osx-font-smoothing: grayscale; 24 | } 25 | 26 | .icon-hash:before { 27 | content: "\e900"; 28 | } 29 | .icon-twitter:before { 30 | content: "\e901"; 31 | } 32 | .icon-github:before { 33 | content: "\e902"; 34 | } 35 | .icon-blog:before { 36 | content: "\e905"; 37 | } 38 | .icon-earth:before { 39 | content: "\e903"; 40 | } 41 | .icon-link:before { 42 | content: "\e906"; 43 | } 44 | .icon-youtube:before { 45 | content: "\e904"; 46 | } 47 | .icon-book:before { 48 | content: "\f007"; 49 | } 50 | .icon-calendar:before { 51 | content: "\f068"; 52 | } 53 | .icon-chevron-down:before { 54 | content: "\f0a3"; 55 | } 56 | .icon-chevron-up:before { 57 | content: "\f0a2"; 58 | } 59 | .icon-law:before { 60 | content: "\f0d8"; 61 | } 62 | .icon-search:before { 63 | content: "\f02e"; 64 | } 65 | .icon-x:before { 66 | content: "\f081"; 67 | } 68 | .icon-feed:before { 69 | content: "\ea9b"; 70 | } 71 | -------------------------------------------------------------------------------- /theme/assets/img/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactphp/website/c2482860b9334add7909db0840a2d793afca45e3/theme/assets/img/search.png -------------------------------------------------------------------------------- /theme/assets/img/search.svg: -------------------------------------------------------------------------------- 1 | search 2 | -------------------------------------------------------------------------------- /theme/assets/index.js: -------------------------------------------------------------------------------- 1 | import 'core-js/stable'; 2 | 3 | import './fonts/fonts.css'; 4 | import './icons/icons.css'; 5 | 6 | import './styles/styles.css'; 7 | 8 | import './components/off-canvas-menu'; 9 | import './components/docsearch'; 10 | import './components/component-info'; 11 | import './components/version-selector'; 12 | -------------------------------------------------------------------------------- /theme/assets/styles/alert.css: -------------------------------------------------------------------------------- 1 | .alert { 2 | padding: 16px 16px 16px 24px; 3 | border-left: 4px solid var(--color-red); 4 | border-radius: 4px; 5 | background-color: var(--color-background-lighter); 6 | box-shadow: var(--box-shadow-lighter); 7 | position: relative; 8 | font-size: .9em; 9 | 10 | &:before { 11 | content: '!'; 12 | position: absolute; 13 | top: 12px; 14 | left: -14px; 15 | display: block; 16 | width: 24px; 17 | height: 24px; 18 | background: var(--color-red); 19 | font-size: 12px; 20 | padding: 0 4px; 21 | box-sizing: border-box; 22 | text-align: center; 23 | font-weight: bold; 24 | color: #fff; 25 | line-height: 22px; 26 | border-radius: 50%; 27 | } 28 | 29 | & a { 30 | color: var(--color-red); 31 | } 32 | 33 | & :last-child { 34 | margin-bottom: 0; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /theme/assets/styles/anchor.css: -------------------------------------------------------------------------------- 1 | .anchor { 2 | display: block; 3 | float: left; 4 | position: absolute; 5 | padding-right: 2px; 6 | transform: translateX(-100%); 7 | text-decoration: none !important; 8 | } 9 | 10 | .anchor:focus { 11 | outline: none; 12 | } 13 | 14 | .anchor > * { 15 | visibility: hidden; 16 | } 17 | 18 | *:hover > .anchor > * { 19 | visibility: visible; 20 | } 21 | 22 | .anchor > *:before { 23 | content: '#'; 24 | font-weight: normal !important; 25 | color: var(--color-key-light); 26 | } 27 | 28 | .anchor--disable .anchor > *, 29 | .anchor.anchor--disable > * { 30 | visibility: hidden !important; 31 | } 32 | -------------------------------------------------------------------------------- /theme/assets/styles/base.css: -------------------------------------------------------------------------------- 1 | html { 2 | box-sizing: border-box; 3 | 4 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; 5 | font-size: 16px; 6 | line-height: 1.6; 7 | 8 | @media (max-width: 768px) { 9 | font-size: 18px; 10 | } 11 | } 12 | 13 | *, *:before, *:after { 14 | box-sizing: inherit; 15 | } 16 | 17 | body { 18 | margin: 0; 19 | color: var(--color-base); 20 | background-color: #fff; 21 | } 22 | 23 | a { 24 | color: var(--color-key); 25 | } 26 | 27 | a:hover { 28 | color: var(--color-key-light); 29 | text-decoration: underline; 30 | } 31 | 32 | blockquote { 33 | padding: 16px 16px 16px 24px; 34 | border-left: 4px solid var(--color-key); 35 | border-radius: 4px; 36 | background-color: var(--color-background-lighter); 37 | box-shadow: var(--box-shadow-lighter); 38 | position: relative; 39 | font-size: .875rem; 40 | 41 | &:before { 42 | content: "i"; 43 | position: absolute; 44 | top: 12px; 45 | left: -14px; 46 | display: block; 47 | width: 24px; 48 | height: 24px; 49 | background: var(--color-key); 50 | font-size: 12px; 51 | padding: 0 4px; 52 | box-sizing: border-box; 53 | text-align: center; 54 | font-weight: bold; 55 | color: #fff; 56 | line-height: 24px; 57 | border-radius: 50%; 58 | } 59 | 60 | & :last-child { 61 | margin-bottom: 0; 62 | } 63 | } 64 | 65 | p, ul, ol, hr, h1, h2, h3, h4, h5, h6, form, fieldset, blockquote { 66 | margin: 0 0 16px 0; 67 | } 68 | 69 | ul ul { 70 | margin-bottom: 0; 71 | } 72 | 73 | hr { 74 | clear: both; 75 | height: 0; 76 | border: 0; 77 | border-bottom: 1px dashed var(--color-background-light); 78 | padding: 0; 79 | } 80 | 81 | h1, h2, h3, h4, h5, h6 { 82 | font-weight: bold; 83 | line-height: 1; 84 | -webkit-font-smoothing: antialiased; 85 | color: var(--color-base); 86 | } 87 | 88 | h1, 89 | h2, 90 | h3, 91 | h4, 92 | h5, 93 | h6 { 94 | font-family: "Source Sans Pro","Helvetica Neue",Arial,sans-serif; 95 | font-weight: 700; 96 | 97 | & a, 98 | & a:hover { 99 | text-decoration: none; 100 | } 101 | } 102 | 103 | h1 { 104 | font-size: 2.5rem; 105 | margin-bottom: 32px; 106 | color: var(--color-key); 107 | letter-spacing: -1px; 108 | 109 | & a, 110 | & a:hover { 111 | color: var(--color-key); 112 | } 113 | } 114 | 115 | h1:not(:first-child) { 116 | margin-top: 32px; 117 | } 118 | 119 | h2 { 120 | font-size: 2rem; 121 | margin-bottom: 32px; 122 | color: var(--color-key); 123 | 124 | & a, 125 | & a:hover { 126 | color: var(--color-key); 127 | } 128 | } 129 | 130 | h2:not(:first-child) { 131 | margin-top: 32px; 132 | } 133 | 134 | h3 { 135 | font-size: 1.5rem; 136 | margin-bottom: 24px; 137 | color: var(--color-base); 138 | 139 | & a, 140 | & a:hover { 141 | color: var(--color-base); 142 | } 143 | } 144 | 145 | h3:not(:first-child) { 146 | margin-top: 24px; 147 | } 148 | 149 | h4 { 150 | font-size: 1.25rem; 151 | color: var(--color-key); 152 | 153 | & a, 154 | & a:hover { 155 | color: var(--color-key); 156 | } 157 | } 158 | 159 | h4:not(:first-child) { 160 | margin-top: 24px; 161 | } 162 | 163 | @media (max-width: 768px) { 164 | h1 { 165 | font-size: 2rem; 166 | } 167 | 168 | h2 { 169 | font-size: 1.75rem; 170 | margin-bottom: 32px; 171 | } 172 | } 173 | 174 | .container { 175 | padding: 32px; 176 | } 177 | 178 | @media (max-width: 768px) { 179 | .container { 180 | padding: 16px; 181 | } 182 | } 183 | 184 | .wrapper { 185 | max-width: 1600px; 186 | margin: auto; 187 | } 188 | 189 | .wrapper--medium { 190 | max-width: 1280px; 191 | } 192 | 193 | .wrapper--small { 194 | max-width: 960px; 195 | margin: auto; 196 | } 197 | 198 | .wrapper--narrow { 199 | max-width: 640px; 200 | } 201 | 202 | .main { 203 | width: calc(98% - 400px); 204 | margin-bottom: 32px; 205 | } 206 | 207 | .sidebar { 208 | width: calc(400px - 2%); 209 | margin-bottom: 32px; 210 | } 211 | 212 | @media (max-width: 1024px) { 213 | .main, 214 | .sidebar { 215 | width: auto; 216 | margin-top: 16px; 217 | } 218 | } 219 | 220 | .visually-hidden { 221 | position: absolute !important; 222 | height: 1px; 223 | width: 1px; 224 | overflow: hidden; 225 | clip: rect(1px, 1px, 1px, 1px); 226 | } 227 | -------------------------------------------------------------------------------- /theme/assets/styles/box.css: -------------------------------------------------------------------------------- 1 | .box { 2 | background: var(--color-background-lighter); 3 | box-shadow: var(--box-shadow-lighter); 4 | border-radius: 4px; 5 | text-align: left; 6 | vertical-align: top; 7 | padding: 24px; 8 | margin-top: 0; 9 | margin-bottom: 24px; 10 | text-decoration: none; 11 | color: inherit; 12 | overflow: auto; 13 | display: flex; 14 | flex-direction: column; 15 | } 16 | 17 | .box:hover { 18 | background: var(--color-background-light); 19 | box-shadow: var(--box-shadow-light); 20 | text-decoration: none; 21 | } 22 | 23 | .box p, 24 | .box ul, 25 | .box ol, 26 | .box hr, 27 | .box h1, 28 | .box h2, 29 | .box h3, 30 | .box h4, 31 | .box h5, 32 | .box h6 { 33 | margin-bottom: 8px; 34 | } 35 | 36 | .box h1, 37 | .box h2, 38 | .box h3, 39 | .box h4, 40 | .box h5, 41 | .box h6 { 42 | color:var(--color-base); 43 | } 44 | 45 | .box :first-child { 46 | margin-top: 0; 47 | } 48 | 49 | .box :last-child { 50 | margin-bottom: 0; 51 | } 52 | 53 | .box__content { 54 | flex-grow: 1; 55 | color: var(--color-base); 56 | text-decoration: none; 57 | 58 | & p { 59 | font-size: .875rem; 60 | } 61 | } 62 | 63 | .box__content:hover { 64 | color: var(--color-base); 65 | text-decoration: none; 66 | } 67 | 68 | .box__content:not(:last-child) { 69 | margin-bottom: 16px; 70 | } 71 | 72 | .box__link { 73 | display: block; 74 | font-size: .75rem; 75 | color: var(--color-key); 76 | text-decoration: none; 77 | } 78 | 79 | .box__link [class*="icon"] { 80 | color: var(--color-key); 81 | } 82 | 83 | .box__link:hover { 84 | color: var(--color-key-light); 85 | text-decoration: none; 86 | } 87 | -------------------------------------------------------------------------------- /theme/assets/styles/center.css: -------------------------------------------------------------------------------- 1 | .center { 2 | text-align: center; 3 | 4 | & h1, 5 | & h2, 6 | & h3, 7 | & h4, 8 | & h5, 9 | & h6 { 10 | display: inline-block; /* For anchor positioning */ 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /theme/assets/styles/code.css: -------------------------------------------------------------------------------- 1 | tt, code, pre { 2 | font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace; 3 | } 4 | 5 | code, tt { 6 | font-size: .75rem; 7 | padding: .3rem .45rem; 8 | margin: 0; 9 | background-color: rgba(0, 0, 0, 0.05); 10 | border-radius: 4px; 11 | } 12 | 13 | code br, tt br { 14 | display: none 15 | } 16 | 17 | del code { 18 | text-decoration: inherit 19 | } 20 | 21 | pre { 22 | word-wrap: normal; 23 | text-align: left; 24 | font-size: .875rem; 25 | line-height: 1.45; 26 | 27 | @media (max-width: 768px) { 28 | font-size: .75rem; 29 | } 30 | } 31 | 32 | pre > code { 33 | padding: 0; 34 | margin: 0; 35 | font-size: 100%; 36 | word-break: normal; 37 | white-space: pre; 38 | background: transparent; 39 | border: 0 40 | } 41 | 42 | .highlight { 43 | margin-bottom: 16px; 44 | } 45 | 46 | .highlight pre { 47 | margin-bottom: 0; 48 | word-break: normal 49 | } 50 | 51 | .highlight pre, pre { 52 | padding: 16px 16px 14px 16px; 53 | overflow: auto; 54 | background-color: var(--color-background-lightest); 55 | box-shadow: var(--box-shadow-lightest); 56 | color: var(--color-base); 57 | text-shadow: none !important; 58 | border-radius: 4px; 59 | } 60 | 61 | pre code, pre tt { 62 | display: inline; 63 | max-width: none; 64 | padding: 0; 65 | margin: 0; 66 | overflow: visible; 67 | line-height: inherit; 68 | word-wrap: normal; 69 | background-color: transparent; 70 | border: 0 71 | } 72 | 73 | pre code::before, pre code::after, pre tt::before, pre tt::after { 74 | content: normal 75 | } 76 | -------------------------------------------------------------------------------- /theme/assets/styles/footer.css: -------------------------------------------------------------------------------- 1 | .footer { 2 | background: var(--color-base); 3 | padding: 32px; 4 | text-align: center; 5 | text-shadow: 1px 1px 0 rgba(0, 0, 0, .125); 6 | } 7 | 8 | .footer .links a { 9 | color: var(--color-background-light); 10 | text-decoration: none; 11 | } 12 | 13 | .footer .links a:hover { 14 | color: var(--color-green-light); 15 | text-decoration: none; 16 | } 17 | -------------------------------------------------------------------------------- /theme/assets/styles/grid.css: -------------------------------------------------------------------------------- 1 | .grid { 2 | display: flex; 3 | flex-direction: row; 4 | flex-wrap: wrap; 5 | justify-content: center; 6 | width: 102%; 7 | margin-left: -2%; 8 | } 9 | 10 | .grid > * { 11 | margin-left: 2%; 12 | max-width: 100%; 13 | } 14 | 15 | .grid--4cols > * { 16 | flex-basis: 23%; 17 | } 18 | 19 | .grid--3cols > * { 20 | flex-basis: 31.33%; 21 | } 22 | 23 | .grid--2cols > * { 24 | flex-basis: 48%; 25 | } 26 | 27 | @media (max-width: 768px) { 28 | .grid { 29 | flex-direction: column; 30 | width: 100%; 31 | margin-left: 0; 32 | } 33 | 34 | .grid > * { 35 | width: 100%; 36 | flex: 0 0 auto; 37 | margin-left: 0; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /theme/assets/styles/hamburger.css: -------------------------------------------------------------------------------- 1 | .hamburger { 2 | padding: 14px 12px; 3 | display: inline-block; 4 | height: 48px; 5 | cursor: pointer; 6 | font: inherit; 7 | color: inherit; 8 | text-transform: none; 9 | background-color: transparent; 10 | border: 0; 11 | margin: 0; 12 | overflow: visible; 13 | outline: none; 14 | } 15 | 16 | .hamburger__box { 17 | width: 24px; 18 | height: 16px; 19 | display: inline-block; 20 | position: relative; 21 | } 22 | 23 | .hamburger__inner { 24 | display: block; 25 | top: 50%; 26 | margin-top: -2px; 27 | } 28 | 29 | .hamburger__inner, .hamburger__inner::before, .hamburger__inner::after { 30 | width: 24px; 31 | height: 3px; 32 | background-color: var(--color-base); 33 | border-radius: 2px; 34 | position: absolute; 35 | transition-property: transform; 36 | transition-duration: 0.15s; 37 | transition-timing-function: ease; 38 | } 39 | 40 | .hamburger__inner::before, .hamburger__inner::after { 41 | content: ""; 42 | display: block; 43 | } 44 | 45 | .hamburger__inner::before { 46 | top: -6px; 47 | } 48 | 49 | .hamburger__inner::after { 50 | bottom: -6px; 51 | } 52 | -------------------------------------------------------------------------------- /theme/assets/styles/header.css: -------------------------------------------------------------------------------- 1 | .header { 2 | width: 100%; 3 | background: #fefefe; 4 | box-shadow: var(--box-shadow-lightest); 5 | padding: 0 32px; 6 | 7 | @media (max-width: 768px) { 8 | padding: 0 16px; 9 | } 10 | } 11 | 12 | .header__container { 13 | width: 100%; 14 | position: relative; 15 | display: flex; 16 | align-items: center; 17 | justify-content: space-between; 18 | } 19 | 20 | .header__logo { 21 | display: block; 22 | line-height: 1; 23 | padding: 16px 0; 24 | } 25 | 26 | .header__logo svg { 27 | display: block; 28 | width: 120px; 29 | height: 18px; 30 | } 31 | 32 | .header__search { 33 | margin: 0; 34 | position: absolute; 35 | right: 48px; 36 | top: 7px; 37 | z-index: 799; 38 | 39 | & input { 40 | width: 400px; 41 | 42 | @media (max-width: 768px) { 43 | width: calc(100vw - 94px); 44 | } 45 | } 46 | } 47 | 48 | .header__menu { 49 | position: absolute; 50 | right: -12px; 51 | top: 0; 52 | z-index: 800; 53 | } 54 | -------------------------------------------------------------------------------- /theme/assets/styles/highlight.css: -------------------------------------------------------------------------------- 1 | .pl-c { 2 | color: #969896 3 | } 4 | 5 | .pl-c1, .pl-s .pl-v { 6 | color: #0086b3 7 | } 8 | 9 | .pl-e, .pl-en { 10 | color: #795da3 11 | } 12 | 13 | .pl-smi, .pl-s .pl-s1 { 14 | color: #444 15 | } 16 | 17 | .pl-ent { 18 | color: #63a35c 19 | } 20 | 21 | .pl-k { 22 | color: #a71d5d 23 | } 24 | 25 | .pl-s, .pl-pds, .pl-s .pl-pse .pl-s1, .pl-sr, .pl-sr .pl-cce, .pl-sr .pl-sre, .pl-sr .pl-sra { 26 | color: #183691 27 | } 28 | 29 | .pl-v, .pl-smw { 30 | color: #ed6a43 31 | } 32 | 33 | .pl-bu { 34 | color: #b52a1d 35 | } 36 | 37 | .pl-ii { 38 | color: #f8f8f8; 39 | background-color: #b52a1d 40 | } 41 | 42 | .pl-c2 { 43 | color: #f8f8f8; 44 | background-color: #b52a1d 45 | } 46 | 47 | .pl-c2::before { 48 | content: "^M" 49 | } 50 | 51 | .pl-sr .pl-cce { 52 | font-weight: bold; 53 | color: #63a35c 54 | } 55 | 56 | .pl-ml { 57 | color: #693a17 58 | } 59 | 60 | .pl-mh, .pl-mh .pl-en, .pl-ms { 61 | font-weight: bold; 62 | color: #1d3e81 63 | } 64 | 65 | .pl-mq { 66 | color: #008080 67 | } 68 | 69 | .pl-mi { 70 | font-style: italic; 71 | color: #333 72 | } 73 | 74 | .pl-mb { 75 | font-weight: bold; 76 | color: #333 77 | } 78 | 79 | .pl-md { 80 | color: #bd2c00; 81 | background-color: #ffecec 82 | } 83 | 84 | .pl-mi1 { 85 | color: #55a532; 86 | background-color: #eaffea 87 | } 88 | 89 | .pl-mc { 90 | color: #ef9700; 91 | background-color: #ffe3b4 92 | } 93 | 94 | .pl-mi2 { 95 | color: #d8d8d8; 96 | background-color: #808080 97 | } 98 | 99 | .pl-mdr { 100 | font-weight: bold; 101 | color: #795da3 102 | } 103 | 104 | .pl-mo { 105 | color: #1d3e81 106 | } 107 | 108 | .pl-ba { 109 | color: #595e62 110 | } 111 | 112 | .pl-sg { 113 | color: #c0c0c0 114 | } 115 | 116 | .pl-corl { 117 | text-decoration: underline; 118 | color: #183691 119 | } 120 | -------------------------------------------------------------------------------- /theme/assets/styles/iframe.css: -------------------------------------------------------------------------------- 1 | .iframe { 2 | position:relative; 3 | padding-bottom:56.25%; 4 | height:0; 5 | overflow:hidden; 6 | width:100%; 7 | } 8 | 9 | .iframe iframe { 10 | position:absolute; 11 | top:0; 12 | left:0; 13 | width:100%; 14 | height:100%; 15 | } 16 | -------------------------------------------------------------------------------- /theme/assets/styles/links.css: -------------------------------------------------------------------------------- 1 | .links { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | .links li { 7 | display: inline-block; 8 | margin: 0 8px; 9 | text-decoration: none; 10 | } 11 | 12 | .links li:first-child { 13 | margin-left: 0; 14 | } 15 | 16 | .links li:last-child { 17 | margin-right: 0; 18 | } 19 | 20 | .links a { 21 | display: block; 22 | text-decoration: none; 23 | } 24 | 25 | .links a:hover { 26 | text-decoration: none; 27 | } 28 | -------------------------------------------------------------------------------- /theme/assets/styles/searchbox.css: -------------------------------------------------------------------------------- 1 | .searchbox { 2 | width: 100%; 3 | 4 | &, 5 | &:focus { 6 | appearance: none; 7 | padding: 6px 8px 6px 32px; 8 | font-size: .875rem; 9 | line-height: 24px; 10 | color: var(--color-base); 11 | border: 0; 12 | background: var(--color-background-light) url(../img/search.svg) no-repeat 10px center; 13 | background-size: 16px 16px; 14 | box-shadow: var(--box-shadow-light); 15 | border-radius: 4px; 16 | outline: none; 17 | transition: width .35s cubic-bezier(0.23, 1, 0.32, 1); 18 | } 19 | 20 | &::-webkit-input-placeholder { 21 | color: var(--color-base-light); 22 | } 23 | &:-moz-placeholder { 24 | color: var(--color-base-light); 25 | } 26 | &::-moz-placeholder { 27 | color: var(--color-base-light); 28 | opacity: 1; 29 | } 30 | &:-ms-input-placeholder { 31 | color: var(--color-base-light); 32 | } 33 | 34 | &:focus { 35 | background-color: var(--color-background-lighter) !important; 36 | box-shadow: var(--box-shadow-lighter); 37 | } 38 | } 39 | 40 | .searchbox--collapsed { 41 | &:not(:focus) { 42 | background-color: transparent; 43 | border: 0; 44 | width: 32px !important; 45 | margin-right: -12px; 46 | cursor: pointer; 47 | box-shadow: none; 48 | 49 | &::-webkit-search-decoration { 50 | display: none; 51 | } 52 | &::-webkit-search-cancel-button { 53 | display: none; 54 | } 55 | &::-webkit-search-results-button { 56 | display: none; 57 | } 58 | &::-webkit-search-results-decoration { 59 | display: none; 60 | } 61 | &::-ms-clear { 62 | display: none; 63 | } 64 | } 65 | } 66 | 67 | .searchbox--large { 68 | &, 69 | &:focus { 70 | padding: 8px 12px 8px 40px; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /theme/assets/styles/styles.css: -------------------------------------------------------------------------------- 1 | @import "./variables.css"; 2 | @import "./base.css"; 3 | @import "./grid.css"; 4 | @import "./center.css"; 5 | @import "./hamburger.css"; 6 | @import "./header.css"; 7 | @import "./footer.css"; 8 | @import "./iframe.css"; 9 | @import "./links.css"; 10 | @import "./box.css"; 11 | @import "./code.css"; 12 | @import "./highlight.css"; 13 | @import "./anchor.css"; 14 | @import "./searchbox.css"; 15 | @import "./alert.css"; 16 | @import "./toc.css"; 17 | @import "./welcome.css"; 18 | -------------------------------------------------------------------------------- /theme/assets/styles/toc.css: -------------------------------------------------------------------------------- 1 | .toc { 2 | display: flex; 3 | flex-wrap: wrap; 4 | padding: 0; 5 | list-style: none; 6 | margin-left: -4px; 7 | 8 | & li { 9 | margin: 4px; 10 | } 11 | 12 | & a { 13 | display: flex; 14 | background-color: var(--color-base); 15 | box-shadow: var(--box-shadow-lighter); 16 | color: #fff; 17 | font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace; 18 | font-weight: bolder; 19 | letter-spacing: normal; 20 | padding: .25rem 1rem .15rem 1rem; 21 | border-radius: 4px; 22 | text-decoration: none; 23 | } 24 | 25 | & a:hover { 26 | text-decoration: none; 27 | color: #fff; 28 | } 29 | 30 | @media (max-width: 768px) { 31 | font-size: .85rem; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /theme/assets/styles/variables.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --color-key: #4f5b93; 3 | --color-key-light: #a2aacd; 4 | 5 | --color-base: #584b4f; 6 | --color-base-light: #afa1a5; 7 | 8 | --color-green: #40a977; 9 | --color-green-light: #9ad8bb; 10 | 11 | --color-red: #ba3525; 12 | --color-red-light: #e79187; 13 | 14 | --color-background: #d6d1c8; 15 | --color-background-light: #eae8e3; 16 | --color-background-lighter: #f4f3f1; 17 | --color-background-lightest: #f9f9f8; 18 | 19 | --box-shadow-light: 0 1px 0 0 rgba(0, 0, 0, .15); 20 | --box-shadow-lighter: 0 1px 0 0 rgba(0, 0, 0, .1); 21 | --box-shadow-lightest: 0 1px 0 0 rgba(0, 0, 0, .08); 22 | } 23 | -------------------------------------------------------------------------------- /theme/assets/styles/welcome.css: -------------------------------------------------------------------------------- 1 | .welcome__intro { 2 | padding: 16px 0 136px 0; 3 | border-bottom: 1px dashed var(--color-background-light); 4 | background-image: radial-gradient(ellipse at center, #fff 0%, var(--color-background-light) 100%); 5 | background-size: auto 100%; 6 | background-position: 50% 0; 7 | } 8 | 9 | .welcome__intro h1 { 10 | font-size: 2rem; 11 | margin-bottom: 16px; 12 | color: var(--color-key); 13 | } 14 | 15 | .welcome__logo { 16 | display: block; 17 | margin: 0 auto; 18 | max-width: 320px; 19 | } 20 | 21 | .welcome__logo svg { 22 | /*filter: drop-shadow(0 0 25px #fff);*/ 23 | display: block; 24 | height: 240px; 25 | } 26 | 27 | .welcome__content { 28 | padding-top: 16px; 29 | display: block; 30 | max-width: calc(98% - 320px); 31 | } 32 | 33 | .welcome__example { 34 | display: block; 35 | margin: auto; 36 | max-width: 850px; 37 | margin-top: -160px; 38 | } 39 | 40 | .welcome__example .highlight pre { 41 | padding: 32px; 42 | background: #fff; 43 | box-shadow: 0 0 16px var(--color-background); 44 | } 45 | 46 | .welcome__intro .links a { 47 | color: var(--color-base); 48 | text-decoration: none; 49 | } 50 | 51 | .welcome__intro .links a:hover { 52 | color: var(--color-key); 53 | text-decoration: none; 54 | } 55 | 56 | .welcome__team img { 57 | border-radius: 50%; 58 | max-width: 190px; 59 | display: inline-block; 60 | } 61 | 62 | .welcome__team h3 { 63 | display: block; 64 | margin: .2em 0; 65 | } 66 | 67 | .welcome__team div.grid > * { 68 | margin-bottom: 1em; 69 | } 70 | 71 | @media (max-width: 768px) { 72 | .welcome__content { 73 | padding: 32px 16px 16px 16px; 74 | max-width: 100%; 75 | } 76 | 77 | .welcome__logo svg { 78 | height: 160px; 79 | } 80 | 81 | .welcome__intro h1 { 82 | text-align: center; 83 | font-size: 1.75rem; 84 | margin-bottom: 16px; 85 | color: var(--color-key); 86 | } 87 | 88 | .welcome__intro .links { 89 | text-align: center; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /theme/assets/webpack-public-path.js: -------------------------------------------------------------------------------- 1 | __webpack_public_path__ = window.__assets; 2 | -------------------------------------------------------------------------------- /theme/changelog.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'default.html.twig' %} 2 | 3 | {% block head %} 4 | 5 | {% endblock %} 6 | 7 | {% block content %} 8 | 9 | 10 | 11 | {{ berti.content|raw }} 12 | 13 | {% include 'partials/changelog.html.twig' with {releases_by_year: releases_by_year, is_combined_changelog: true} %} 14 | 15 | 16 | 17 | 18 | 19 | Subscribe to the Changelog feed 20 | 21 | 22 | 23 | 24 | 25 | 26 | {% endblock %} 27 | -------------------------------------------------------------------------------- /theme/component-changelog.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'component.html.twig' %} 2 | 3 | {% block title %}{{ component.title ~ ': Changelog' }}{% endblock %} 4 | 5 | {% block head %} 6 | 7 | {% endblock %} 8 | 9 | {% block component_content %} 10 | {{ component.title }} Changelog 11 | 12 | {% include 'partials/changelog.html.twig' with {releases_by_year: component_releases_by_year, is_combined_changelog: false} %} 13 | 14 | 15 | 16 | 17 | 18 | Subscribe to the Changelog feed 19 | 20 | 21 | 22 | {% endblock %} 23 | -------------------------------------------------------------------------------- /theme/component-license.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'component.html.twig' %} 2 | 3 | {% block title %}{{ component.title ~ ': License' }}{% endblock %} 4 | {% block component_content %} 5 | {{ component.title }} License 6 | 7 | {{ berti.content|strip_title|emoji|raw }} 8 | {% endblock %} 9 | -------------------------------------------------------------------------------- /theme/component.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'default.html.twig' %} 2 | 3 | {% set _title = component.title %} 4 | {% if berti.title is not empty and berti.title != _title %} 5 | {% set _title = _title ~ ': ' ~ berti.title %} 6 | {% endif %} 7 | {% block title %}{{ _title }}{% endblock %} 8 | {% block description %}{{ component.description }}{% endblock %} 9 | 10 | {% block content %} 11 | 12 | 13 | 14 | 15 | {% block component_content %} 16 | {{ component.title }} 17 | 18 | {{ berti.content|strip_title|emoji|raw }} 19 | {% endblock %} 20 | 21 | 98 | 99 | 100 | 101 | {% endblock %} 102 | -------------------------------------------------------------------------------- /theme/default.html.twig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | {% spaceless %}{% block title %}{{ berti.title }}{% endblock %} - ReactPHP{% endspaceless %} 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | {% if not use_asset_dev_server %} 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | {% else %} 32 | 33 | {% endif %} 34 | {% block head %}{% endblock %} 35 | 36 | 37 | 38 | {% block header %} 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | {% include 'partials/header_menu.html.twig' %} 49 | 50 | 51 | 52 | {% endblock %} 53 | 54 | {% block content %} 55 | 56 | 57 | {{ berti.content|emoji|raw }} 58 | 59 | 60 | {% endblock %} 61 | 62 | {% block footer %} 63 | 72 | {% endblock %} 73 | 74 | 75 | -------------------------------------------------------------------------------- /theme/partials/changelog.html.twig: -------------------------------------------------------------------------------- 1 | 2 | {% for year, releases in releases_by_year %} 3 | {{ year }} 4 | {% endfor %} 5 | 6 | 7 | {% for year, releases in releases_by_year %} 8 | 9 | 10 | {{ year }} 11 | 12 | 13 | {% for release in releases %} 14 | 15 | {% set _id = release.version|replace({'.': ''}) ~ '-' ~ release.date|date('Y-m-d') %} 16 | {% if is_combined_changelog == true %} 17 | {% set _id = release.component|lower ~ '-' ~ _id %} 18 | {% endif %} 19 | 20 | 21 | 22 | {% if is_combined_changelog == true %}{{ release.component }} {% endif %}{{ release.version }} 23 | 24 | 25 | ({{ release.date|date('Y-m-d') }}) 26 | 27 | Release on GitHub 28 | 29 | 30 | 31 | 32 | {{ release.html|raw }} 33 | 34 | 35 | {% endfor %} 36 | {% endfor %} 37 | -------------------------------------------------------------------------------- /theme/partials/header_menu.html.twig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Menu 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | Home 18 | 19 | 20 | 21 | Changelog 22 | 23 | {% for category, components in components_by_category %} 24 | 25 | {{ category }} 26 | 27 | {% for component in components %} 28 | 29 | 30 | {{ component.title|emoji }} 31 | 32 | 33 | {{ component.releases[0].tag }} 34 | 35 | 36 | 37 | {% endfor %} 38 | 39 | 40 | {% endfor %} 41 | 42 | 43 | --------------------------------------------------------------------------------