Yoga Docs: Delete the Old website (#1612)
Summary: Pull Request resolved: https://github.com/facebook/yoga/pull/1612 Moving new website to `/website` before publishing, so that edit links point to the right eventual place in the GitHub repo. Reviewed By: joevilches Differential Revision: D54837808 fbshipit-source-id: 46de8a638ad9bce18558fd768ed8c080892b828e
This commit is contained in:
committed by
Facebook GitHub Bot
parent
d7faf2c101
commit
108c2f30a2
23
.github/actions/setup-website/action.yml
vendored
23
.github/actions/setup-website/action.yml
vendored
@@ -1,23 +0,0 @@
|
||||
name: Setup Website envirionment
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
# TODO: Update to latest when website is moved to the workspace version of
|
||||
# yoga-layout
|
||||
- name: Setup Node environment
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 12.x
|
||||
cache: yarn
|
||||
cache-dependency-path: website/yarn.lock
|
||||
env:
|
||||
# https://github.com/actions/setup-node/issues/317
|
||||
FORCE_COLOR: 0
|
||||
|
||||
# TODO: the website should be in a yarn workspace with the library, but the
|
||||
# current version of gatsby is incompatible with hoisting.
|
||||
- name: yarn install
|
||||
shell: bash
|
||||
run: yarn install --frozen-lockfile --network-timeout 1000000
|
||||
working-directory: website
|
35
.github/workflows/publish-website.yml
vendored
35
.github/workflows/publish-website.yml
vendored
@@ -1,35 +0,0 @@
|
||||
name: Publish Website
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
name: Publish to GitHub Pages
|
||||
runs-on: ubuntu-20.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Setup
|
||||
uses: ./.github/actions/setup-website
|
||||
|
||||
- name: yarn build
|
||||
run: yarn build
|
||||
working-directory: website
|
||||
|
||||
- uses: peaceiris/actions-gh-pages@v3
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
publish_branch: gh-pages
|
||||
publish_dir: website/public
|
||||
cname: yogalayout.dev
|
||||
keep_files: true
|
||||
user_name: 'Yoga-bot'
|
||||
user_email: 'yogabot@fb.com'
|
16
.github/workflows/validate-website.yml
vendored
16
.github/workflows/validate-website.yml
vendored
@@ -10,22 +10,8 @@ on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build [Gatsby]
|
||||
runs-on: ubuntu-20.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Setup
|
||||
uses: ./.github/actions/setup-website
|
||||
|
||||
- name: yarn build
|
||||
run: yarn build
|
||||
working-directory: website
|
||||
|
||||
build_next:
|
||||
name: Build [Docusaurus]
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
|
@@ -1,15 +0,0 @@
|
||||
[ignore]
|
||||
|
||||
[include]
|
||||
|
||||
[libs]
|
||||
|
||||
[lints]
|
||||
|
||||
[options]
|
||||
types_first=false
|
||||
|
||||
[strict]
|
||||
|
||||
[version]
|
||||
^0.140.0
|
7
website/.gitignore
vendored
7
website/.gitignore
vendored
@@ -1,7 +0,0 @@
|
||||
# Project dependencies
|
||||
.cache/
|
||||
# Build directory
|
||||
public/
|
||||
.DS_Store
|
||||
yarn-error.log
|
||||
src/components/Playground/dist
|
@@ -1,35 +0,0 @@
|
||||
# Yoga documentation and playground
|
||||
|
||||
This site uses [gatsby.js](https://www.gatsbyjs.org/) as static site generator. Which transforms all markdown and react code to static HTML and JS files.
|
||||
|
||||
## Development
|
||||
```
|
||||
yarn install
|
||||
yarn develop
|
||||
```
|
||||
|
||||
### Structure
|
||||
Documentation pages are generated from the Markdown files in `contents/`. The files are organized in 4 sections/folders (getting-started, properties, examples, contributing) which are dynamically listed on the docs overview page. The Markdown files can have some header files containing metadata.
|
||||
|
||||
```
|
||||
---
|
||||
path: "docs/flexDirection"
|
||||
title: "Flex Direction"
|
||||
hasPlayground: true
|
||||
editableProperties: ['flexDirection']
|
||||
---
|
||||
```
|
||||
|
||||
The `path` can be any URL this page should be available at. The `title` is used as the page's HTML-title and when referencing the file from the documentation overview. There are two kinds of templates for a page: with and without playground. `hasPlayground` selects the corresponding template (`src/templates/{with|without}Playground.js`). When using `hasPlayground: true`, `editableProperties` can list all Yoga properties which are editable in the playground.
|
||||
|
||||
### Design
|
||||
We are using [antd](https://ant.design) for various UI elements. See their documentation for the components available. `gatsby-config.js` can be used to overwrite LESS-variables from antd.
|
||||
|
||||
For styling react components we create a CSS-file with the same name next to each component and import it in the component. E.g. there is `index.js` and `index.css`. In the react-component we import the stylesheet: `import './index.css'`.
|
||||
|
||||
## Build
|
||||
To generate the static files run:
|
||||
```
|
||||
yarn build
|
||||
```
|
||||
The output will be in `public/` and can be published on GitHub pages.
|
@@ -1,51 +0,0 @@
|
||||
---
|
||||
path: "/contributing/opening-a-pull-request"
|
||||
title: "Opening a Pull Request"
|
||||
hasPlayground: false
|
||||
---
|
||||
|
||||
# Opening a Pull Request
|
||||
|
||||
Before opening your first pull request to Yoga you have to know how to get the code,
|
||||
install build time dependencies, and test the code locally.
|
||||
|
||||
### Clone
|
||||
|
||||
```
|
||||
$> git clone https://github.com/facebook/yoga.git
|
||||
$> cd yoga
|
||||
```
|
||||
|
||||
### Install dependencies
|
||||
|
||||
```
|
||||
$> git submodule init
|
||||
$> git submodule update
|
||||
$> brew install buck
|
||||
```
|
||||
|
||||
### Build and Test
|
||||
|
||||
```
|
||||
$> buck build //:yoga
|
||||
$> buck test //:yoga
|
||||
```
|
||||
|
||||
## Making a Change
|
||||
|
||||
Now all you need to do is make your change and test it before submitting a pull request for review.
|
||||
Below is the general structure of the repo and where you may want to make your change. One you have
|
||||
made your change see the [testing documentation](/contributing/testing) for more on how to test your change.
|
||||
|
||||
``` bash
|
||||
/yoga
|
||||
|-- yoga # Home to the main Yoga codebase written in C++. Any algorithmic changes should be made here
|
||||
|-- lib # Yoga external dependencies. Be thoughtful adding any new ones
|
||||
|-- tests # Yoga's C++ test suite. Both manaul and generated tests
|
||||
|-- gentest
|
||||
| |-- fixtures # html fixtures for generated tests
|
||||
|-- java
|
||||
| |-- com/facebook/yoga # Java binding code
|
||||
| |-- jni # JNI binding code
|
||||
|-- javascript # emscripten / javascript bindings
|
||||
```
|
@@ -1,43 +0,0 @@
|
||||
---
|
||||
path: "/contributing/testing"
|
||||
title: "Testing"
|
||||
hasPlayground: false
|
||||
---
|
||||
|
||||
# Testing
|
||||
|
||||
Yoga tries to be as close as possible to chrome in its flexbox behaviour.
|
||||
To ensure this most of Yoga's test suite is automatically generateded from
|
||||
running the corresponding layout in chrome using a webdriver which then generates
|
||||
C++ test which asserts that Yoga will produce matching outputs for that layout.
|
||||
|
||||
## Running the Test Suite
|
||||
|
||||
1. Yoga builds with [buck](https://buckbuild.com). Follow their documentation to get up and running.
|
||||
2. For testing Yoga relies on [gtest](https://github.com/google/googletest) as a submodule. After cloning Yoga run `git submodule init` followed by `git submodule update`.
|
||||
3. In a terminal from the root of your Yoga checkout run `buck test //:yoga`.
|
||||
|
||||
## Adding a Test
|
||||
|
||||
Instead of manually writing a test which ensures parity with web implementations
|
||||
of Flexbox we make use of a generated test suite. We use `gentest/gentest.rb` to
|
||||
generate this test suite. Write the html which you want to verify in Yoga and put
|
||||
it in the `gentest/fixtures` folder, such as the following.
|
||||
|
||||
```html
|
||||
<div id="my_test" style="width: 100px; height: 100px; align-items: center;">
|
||||
<div style="width: 50px; height: 50px;"></div>
|
||||
</div>
|
||||
```
|
||||
|
||||
Run `gentest/gentest.rb` to generate test code and re-run `buck test //:yoga`
|
||||
to validate the behavior. One test case will be generated for every root `div`
|
||||
in the input html with the string in the `id` corresponding to the test name.
|
||||
|
||||
You should run `bundle install` in the `gentest` directory to install dependencies for the `gentest/gentest.rb` Ruby script.
|
||||
|
||||
## Manual test
|
||||
|
||||
For some aspects of Yoga we cannot generate a test using the test generation
|
||||
infrastructure described earlier. For these cases we manually write a test in
|
||||
the `/tests` directory.
|
@@ -1,52 +0,0 @@
|
||||
---
|
||||
path: "/contributing/writing-documentation"
|
||||
title: "Writing Documentation"
|
||||
hasPlayground: false
|
||||
---
|
||||
|
||||
## Writing Documentation
|
||||
|
||||
Documentation pages are generated from Markdown files in `contents/`.
|
||||
The files are organized in 4 sections/folders (getting-started, properties,
|
||||
examples, contributing) which are dynamically listed on the docs overview page.
|
||||
The Markdown files should contain a header with metadata.
|
||||
|
||||
```markdown
|
||||
---
|
||||
path: "docs/flexDirection"
|
||||
title: "Flex Direction"
|
||||
hasPlayground: true
|
||||
initialPlayground: eyJ3aWR0aCI6IjYwMCIsImhlaWdodCI6NTAwLCJjaGlsZHJlbiI6W3t9LHt9LHt9XX0=
|
||||
---
|
||||
```
|
||||
|
||||
- The `path` indicates the URL path this page will be available at.
|
||||
- The `title` is used as the page's HTML-title and when referencing
|
||||
the file from the documentation overview.
|
||||
- The `hasPlayground` property indicates whether this documentation
|
||||
has an associated playground to test out the documented feature.
|
||||
- The `initialPlayground` property is only relevant for documentation
|
||||
pages with playgrounds and contains the initial playground state.
|
||||
This base64 string is a reference to the hash (content after #)
|
||||
of a [playground](/playground) url.
|
||||
- The `redirect` property allows to redirect to the other page, the path of which is mentioned in the property `path`.
|
||||
|
||||
|
||||
Within the markdown of a documentation page which has an associated
|
||||
playground you can add controls to let the user play around with the feature
|
||||
directly from the documenation page.
|
||||
|
||||
```markdown
|
||||
<controls prop="alignContent"></controls>
|
||||
```
|
||||
|
||||
If you would like to redirect to another page (potentially an external link) the header would look something like this.
|
||||
|
||||
```markdown
|
||||
---
|
||||
path: "/playground?eyJ3aWR0aCI6IjYwMCIsImhlaWdodCI6NTAwLCJjaGlsZHJlbiI6W3t9LHt9LHt9XX0="
|
||||
title: "Flex Direction"
|
||||
redirect: true
|
||||
---
|
||||
|
||||
```
|
@@ -1,5 +0,0 @@
|
||||
---
|
||||
path: "/playground?eyJ3aWR0aCI6NTAwLCJoZWlnaHQiOjUwMCwiY2hpbGRyZW4iOlt7IndpZHRoIjoiNjAiLCJoZWlnaHQiOiI2MCIsIm1hcmdpbiI6eyJ0b3AiOiIyMCIsInJpZ2h0IjoiMjAiLCJib3R0b20iOiIyMCIsImxlZnQiOiIyMCJ9fSx7ImhlaWdodCI6IjYwIiwibWFyZ2luIjp7InRvcCI6IjIwIiwicmlnaHQiOiIyMCIsImJvdHRvbSI6IjIwIiwibGVmdCI6IjIwIn0sImZsZXhHcm93IjoiMSJ9LHsid2lkdGgiOiI0MCIsImhlaWdodCI6IjQwIiwibWFyZ2luIjp7InRvcCI6IjIwIiwicmlnaHQiOiIyMCIsImJvdHRvbSI6IjIwIiwibGVmdCI6IjIwIn19XX0="
|
||||
title: "Flexible Text"
|
||||
redirect: true
|
||||
---
|
@@ -1,5 +0,0 @@
|
||||
---
|
||||
path: "/playground?eyJ3aWR0aCI6NTAwLCJoZWlnaHQiOjUwMCwiY2hpbGRyZW4iOlt7IndpZHRoIjoxMDAsImhlaWdodCI6MTAwLCJwb3NpdGlvbiI6eyJ0b3AiOiJhdXRvIiwicmlnaHQiOiIxMCIsImJvdHRvbSI6IjEwIiwibGVmdCI6ImF1dG8ifSwicG9zaXRpb25UeXBlIjoxLCJtaW5XaWR0aCI6bnVsbCwibWF4V2lkdGgiOm51bGwsIm1pbkhlaWdodCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsfSx7IndpZHRoIjoxMDAsImhlaWdodCI6MTAwLCJtaW5XaWR0aCI6bnVsbCwibWF4V2lkdGgiOm51bGwsIm1pbkhlaWdodCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsfSx7IndpZHRoIjoxMDAsImhlaWdodCI6MTAwLCJtaW5XaWR0aCI6bnVsbCwibWF4V2lkdGgiOm51bGwsIm1pbkhlaWdodCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsfSx7IndpZHRoIjoxMDAsImhlaWdodCI6MTAwLCJtaW5XaWR0aCI6bnVsbCwibWF4V2lkdGgiOm51bGwsIm1pbkhlaWdodCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsfV0sIm1pbldpZHRoIjpudWxsLCJtYXhXaWR0aCI6bnVsbCwibWluSGVpZ2h0IjpudWxsLCJtYXhIZWlnaHQiOm51bGx9"
|
||||
title: "Floating Buttons"
|
||||
redirect: true
|
||||
---
|
@@ -1,5 +0,0 @@
|
||||
---
|
||||
path: "/playground?eyJ3aWR0aCI6NTAwLCJoZWlnaHQiOjUwMCwiY2hpbGRyZW4iOlt7IndpZHRoIjoxMDAsImhlaWdodCI6MTAwLCJtaW5XaWR0aCI6bnVsbCwibWF4V2lkdGgiOm51bGwsIm1pbkhlaWdodCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsfSx7IndpZHRoIjoxMDAsImhlaWdodCI6MTAwLCJtaW5XaWR0aCI6bnVsbCwibWF4V2lkdGgiOm51bGwsIm1pbkhlaWdodCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsfSx7IndpZHRoIjoiMTAwJSIsImhlaWdodCI6IjEwMCUiLCJwb3NpdGlvblR5cGUiOjEsIm1pbldpZHRoIjpudWxsLCJtYXhXaWR0aCI6bnVsbCwibWluSGVpZ2h0IjpudWxsLCJtYXhIZWlnaHQiOm51bGx9XSwibWluV2lkdGgiOm51bGwsIm1heFdpZHRoIjpudWxsLCJtaW5IZWlnaHQiOm51bGwsIm1heEhlaWdodCI6bnVsbH0="
|
||||
title: "Overlays"
|
||||
redirect: true
|
||||
---
|
@@ -1,5 +0,0 @@
|
||||
---
|
||||
path: "https://componentkit.org/docs/getting-started/"
|
||||
title: "ComponentKit"
|
||||
redirect: true
|
||||
---
|
@@ -1,5 +0,0 @@
|
||||
---
|
||||
path: "https://fblitho.com/docs/getting-started"
|
||||
title: "Litho"
|
||||
redirect: true
|
||||
---
|
@@ -1,5 +0,0 @@
|
||||
---
|
||||
path: "https://reactnative.dev/docs/getting-started"
|
||||
title: "React Native"
|
||||
redirect: true
|
||||
---
|
@@ -1,72 +0,0 @@
|
||||
---
|
||||
path: "/getting-started/standalone"
|
||||
title: "Standalone"
|
||||
hasPlayground: false
|
||||
---
|
||||
|
||||
# Standalone
|
||||
|
||||
Adding Yoga to a project is as simple as adding the dependency to your package manager of choice.
|
||||
|
||||
### Android
|
||||
|
||||
```groovy
|
||||
dependencies {
|
||||
implementation 'com.facebook.yoga.android:yoga-layout:x.x.x'
|
||||
}
|
||||
```
|
||||
|
||||
### Javascript
|
||||
|
||||
The JavaScript bindings for Yoga can be used from node.js and within the browser.
|
||||
When using Yoga from node.js the native library is used, in browsers a pure JS
|
||||
version is used (cross-compiled using [emscripten](https://emscripten.org/)).
|
||||
|
||||
```
|
||||
$> yarn add yoga-layout
|
||||
```
|
||||
|
||||
This is an example on how to use Yoga in JavaScript. For a full API reference,
|
||||
have a look at the [TypeScript type definitions](https://github.com/facebook/yoga/blob/main/javascript/src/wrapAssembly.ts).
|
||||
|
||||
```js
|
||||
import {loadYoga} from 'yoga-layout';
|
||||
|
||||
const Yoga = await loadYoga();
|
||||
const root = Yoga.Node.create();
|
||||
root.setWidth(500);
|
||||
root.setHeight(300);
|
||||
root.setJustifyContent(Yoga.JUSTIFY_CENTER);
|
||||
root.setFlexDirection(Yoga.FLEX_DIRECTION_ROW);
|
||||
|
||||
const node1 = Yoga.Node.create();
|
||||
node1.setWidth(100);
|
||||
node1.setHeight(100);
|
||||
|
||||
const node2 = Yoga.Node.create();
|
||||
node2.setWidth(100);
|
||||
node2.setHeight(100);
|
||||
|
||||
root.insertChild(node1, 0);
|
||||
root.insertChild(node2, 1);
|
||||
|
||||
root.calculateLayout(500, 300, Yoga.DIRECTION_LTR);
|
||||
console.log(root.getComputedLayout());
|
||||
// {left: 0, top: 0, width: 500, height: 300}
|
||||
console.log(node1.getComputedLayout());
|
||||
// {left: 150, top: 0, width: 100, height: 100}
|
||||
console.log(node2.getComputedLayout());
|
||||
// {left: 250, top: 0, width: 100, height: 100}
|
||||
```
|
||||
|
||||
### iOS
|
||||
|
||||
```
|
||||
pod 'YogaKit', '~> 1.7'
|
||||
```
|
||||
|
||||
## Including Yoga From Source
|
||||
|
||||
If you plan to include Yoga from Source in a C++ project then all you have to do is inlude
|
||||
the top level `yoga` folder. Make sure to look at the top level `BUCK` file to ensure you build
|
||||
using the same compiler flags.
|
@@ -1,30 +0,0 @@
|
||||
---
|
||||
path: "/docs/absolute-relative-layout"
|
||||
title: "Absolute/Relative Layout"
|
||||
hasPlayground: true
|
||||
---
|
||||
## Absolute/Relative Layout
|
||||
|
||||
The `position type` of an element defines how it is
|
||||
positioned within its parent.
|
||||
|
||||
**RELATIVE (DEFAULT)** By default an element is positioned
|
||||
relatively. This means an element is positioned according to the
|
||||
normal flow of the layout, and then offset relative to that position
|
||||
based on the values of `top`, `right`, `bottom`, and `left`.
|
||||
The offset does not affect the position of any sibling or parent elements.
|
||||
|
||||
**ABSOLUTE** When positioned absolutely an element doesn't take
|
||||
part in the normal layout flow. It is instead laid out independent
|
||||
of its siblings. The position is determined based on the
|
||||
`top`, `right`, `bottom`, and `left` values.
|
||||
|
||||
<controls prop="positionType"></controls>
|
||||
|
||||
The position values `top`, `right`, `bottom`, and `left` behave
|
||||
differently depending on the `position type` of the element. For
|
||||
a `relative` element they offset the position of the element in the
|
||||
direction specified. For `absolute` element though these properties
|
||||
specify the offset of the element's side from the same side on the parent.
|
||||
|
||||
<controls prop="position"></controls>
|
@@ -1,29 +0,0 @@
|
||||
---
|
||||
path: "/docs/align-content"
|
||||
title: "Align Content"
|
||||
hasPlayground: true
|
||||
initialPlayground: eyJ3aWR0aCI6NTAwLCJoZWlnaHQiOjUwMCwiYWxpZ25Db250ZW50IjoxLCJmbGV4V3JhcCI6MSwiY2hpbGRyZW4iOlt7IndpZHRoIjoxMDAsImhlaWdodCI6MTAwLCJtaW5XaWR0aCI6bnVsbCwibWF4V2lkdGgiOm51bGwsIm1pbkhlaWdodCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsfSx7IndpZHRoIjoxMDAsImhlaWdodCI6MTAwLCJtaW5XaWR0aCI6bnVsbCwibWF4V2lkdGgiOm51bGwsIm1pbkhlaWdodCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsfSx7IndpZHRoIjoxMDAsImhlaWdodCI6MTAwLCJtaW5XaWR0aCI6bnVsbCwibWF4V2lkdGgiOm51bGwsIm1pbkhlaWdodCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsfSx7IndpZHRoIjoxMDAsImhlaWdodCI6MTAwLCJtaW5XaWR0aCI6bnVsbCwibWF4V2lkdGgiOm51bGwsIm1pbkhlaWdodCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsfSx7IndpZHRoIjoxMDAsImhlaWdodCI6MTAwLCJtaW5XaWR0aCI6bnVsbCwibWF4V2lkdGgiOm51bGwsIm1pbkhlaWdodCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsfSx7IndpZHRoIjoxMDAsImhlaWdodCI6MTAwLCJtaW5XaWR0aCI6bnVsbCwibWF4V2lkdGgiOm51bGwsIm1pbkhlaWdodCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsfSx7IndpZHRoIjoxMDAsImhlaWdodCI6MTAwLCJtaW5XaWR0aCI6bnVsbCwibWF4V2lkdGgiOm51bGwsIm1pbkhlaWdodCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsfSx7IndpZHRoIjoxMDAsImhlaWdodCI6MTAwLCJtaW5XaWR0aCI6bnVsbCwibWF4V2lkdGgiOm51bGwsIm1pbkhlaWdodCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsfSx7IndpZHRoIjoxMDAsImhlaWdodCI6MTAwLCJtaW5XaWR0aCI6bnVsbCwibWF4V2lkdGgiOm51bGwsIm1pbkhlaWdodCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsfSx7IndpZHRoIjoxMDAsImhlaWdodCI6MTAwLCJhbGlnbkNvbnRlbnQiOjIsIm1pbldpZHRoIjpudWxsLCJtYXhXaWR0aCI6bnVsbCwibWluSGVpZ2h0IjpudWxsLCJtYXhIZWlnaHQiOm51bGx9XSwibWluV2lkdGgiOm51bGwsIm1heFdpZHRoIjpudWxsLCJtaW5IZWlnaHQiOm51bGwsIm1heEhlaWdodCI6bnVsbH0=
|
||||
---
|
||||
|
||||
## Align Content
|
||||
|
||||
Align content defines the distribution of lines along the cross-axis. This only
|
||||
has effect when items are wrapped to multiple lines using [`flex wrap`](/docs/flex-wrap).
|
||||
|
||||
**FLEX START (DEFAULT)** Align wrapped lines to the start of the container's cross axis.
|
||||
|
||||
**FLEX END** Align wrapped lines to the end of the container's cross axis.
|
||||
|
||||
**STRETCH** Stretch wrapped lines to match the `height` of the container's cross axis.
|
||||
|
||||
**CENTER** Align wrapped lines in the center of the container's cross axis.
|
||||
|
||||
**SPACE BETWEEN** Evenly space wrapped lines across the container's main axis, distributing
|
||||
remaining space between the lines.
|
||||
|
||||
**SPACE AROUND** Evenly space wrapped lines across the container's main axis, distributing
|
||||
remaining space around the lines. Compared to `space between` using
|
||||
`space around` will result in space being distributed to the begining of
|
||||
the first lines and end of the last line.
|
||||
|
||||
<controls prop="alignContent"></controls>
|
@@ -1,32 +0,0 @@
|
||||
---
|
||||
path: "/docs/align-items"
|
||||
title: "Align Items / Self"
|
||||
hasPlayground: true
|
||||
---
|
||||
|
||||
## Align Items
|
||||
|
||||
Align items describes how to align children along the cross axis of their container.
|
||||
Align items is very similar to [`justify content`](/docs/justify-content) but instead of
|
||||
applying to the main axis, `align items` applies to the cross axis.
|
||||
|
||||
**STRETCH (DEFAULT)** Stretch children of a container to match the `height` of the container's cross axis.
|
||||
|
||||
**FLEX START** Align children of a container to the start of the container's cross axis.
|
||||
|
||||
**FLEX END** Align children of a container to the end of the container's cross axis.
|
||||
|
||||
**CENTER** Align children of a container in the center of the container's cross axis.
|
||||
|
||||
**BASELINE** Align children of a container along a common baseline. Individual children can be set to be the reference baseline for their parents.
|
||||
|
||||
<controls prop="alignItems"></controls>
|
||||
|
||||
## Align Self
|
||||
|
||||
Align self has the same options and effect as `align items` but instead of
|
||||
affecting the children within a container, you can apply this property to
|
||||
a single child to change its alignment within its parent. `align self`
|
||||
overrides any option set by the parent with `align items`.
|
||||
|
||||
<controls prop="alignSelf"></controls>
|
@@ -1,21 +0,0 @@
|
||||
---
|
||||
path: "/docs/aspect-ratio"
|
||||
title: "Aspect Ratio"
|
||||
hasPlayground: true
|
||||
---
|
||||
|
||||
## Aspect Ratio
|
||||
|
||||
AspectRatio is a property introduced by Yoga and is not present as a settable
|
||||
property in the css flexbox specification. Flexbox does have the notion of
|
||||
aspect ratio though for things with intrinsic aspect ratio such as images.
|
||||
|
||||
The `aspect ratio` property in Yoga has the following properties:
|
||||
|
||||
- Accepts any floating point value > 0, the default is undefined.
|
||||
- Defined as the ratio between the `width` and the `height` of a node e.g. if a node has an aspect ratio of 2 then its `width` is twice the size of its `height`.
|
||||
- Respects the `min` and `max` dimensions of an item.
|
||||
- Has higher priority than `flex grow`
|
||||
- If `aspect ratio`, `width`, and `height` are set then the cross axis dimension is overridden.
|
||||
|
||||
<controls prop="aspectRatio"></controls>
|
@@ -1,26 +0,0 @@
|
||||
---
|
||||
path: "/docs/flex-direction"
|
||||
title: "Flex Direction"
|
||||
hasPlayground: true
|
||||
---
|
||||
|
||||
## Flex Direction
|
||||
|
||||
Flex direction controls the direction in which children of a node are laid out.
|
||||
This is also referred to as the main axis. The main axis is the direction in
|
||||
which children are laid out. The cross axis is the axis perpendicular to the
|
||||
main axis, or the axis which wrapping lines are laid out in.
|
||||
|
||||
**ROW (DEFAULT)** Align children from left to right. If [wrapping](/docs/flex-wrap) is enabled then
|
||||
the next line will start under the first item on the left of the container.
|
||||
|
||||
**COLUMN** Align children from top to bottom. If [wrapping](/docs/flex-wrap) is enabled then
|
||||
the next line will start to the left first item on the top of the container.
|
||||
|
||||
**ROW REVERSE** Align children from right to left. If [wrapping](/docs/flex-wrap) is enabled then
|
||||
the next line will start under the first item on the right of the container.
|
||||
|
||||
**COLUMN REVERSE** Align children from bottom to top. If [wrapping](/docs/flex-wrap) is enabled then
|
||||
the next line will start to the left first item on the bottom of the container.
|
||||
|
||||
<controls prop="flexDirection"></controls>
|
@@ -1,21 +0,0 @@
|
||||
---
|
||||
path: "/docs/flex-wrap"
|
||||
title: "Flex Wrap"
|
||||
hasPlayground: true
|
||||
initialPlayground: eyJ3aWR0aCI6NTAwLCJoZWlnaHQiOjUwMCwiYWxpZ25Db250ZW50IjoxLCJmbGV4V3JhcCI6MSwiY2hpbGRyZW4iOlt7IndpZHRoIjoxMDAsImhlaWdodCI6MTAwLCJtaW5XaWR0aCI6bnVsbCwibWF4V2lkdGgiOm51bGwsIm1pbkhlaWdodCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsfSx7IndpZHRoIjoxMDAsImhlaWdodCI6MTAwLCJtaW5XaWR0aCI6bnVsbCwibWF4V2lkdGgiOm51bGwsIm1pbkhlaWdodCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsfSx7IndpZHRoIjoxMDAsImhlaWdodCI6MTAwLCJtaW5XaWR0aCI6bnVsbCwibWF4V2lkdGgiOm51bGwsIm1pbkhlaWdodCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsfSx7IndpZHRoIjoxMDAsImhlaWdodCI6MTAwLCJtaW5XaWR0aCI6bnVsbCwibWF4V2lkdGgiOm51bGwsIm1pbkhlaWdodCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsfSx7IndpZHRoIjoxMDAsImhlaWdodCI6MTAwLCJtaW5XaWR0aCI6bnVsbCwibWF4V2lkdGgiOm51bGwsIm1pbkhlaWdodCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsfSx7IndpZHRoIjoxMDAsImhlaWdodCI6MTAwLCJtaW5XaWR0aCI6bnVsbCwibWF4V2lkdGgiOm51bGwsIm1pbkhlaWdodCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsfSx7IndpZHRoIjoxMDAsImhlaWdodCI6MTAwLCJtaW5XaWR0aCI6bnVsbCwibWF4V2lkdGgiOm51bGwsIm1pbkhlaWdodCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsfSx7IndpZHRoIjoxMDAsImhlaWdodCI6MTAwLCJtaW5XaWR0aCI6bnVsbCwibWF4V2lkdGgiOm51bGwsIm1pbkhlaWdodCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsfSx7IndpZHRoIjoxMDAsImhlaWdodCI6MTAwLCJtaW5XaWR0aCI6bnVsbCwibWF4V2lkdGgiOm51bGwsIm1pbkhlaWdodCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsfSx7IndpZHRoIjoxMDAsImhlaWdodCI6MTAwLCJtaW5XaWR0aCI6bnVsbCwibWF4V2lkdGgiOm51bGwsIm1pbkhlaWdodCI6bnVsbCwibWF4SGVpZ2h0IjpudWxsfV0sIm1pbldpZHRoIjpudWxsLCJtYXhXaWR0aCI6bnVsbCwibWluSGVpZ2h0IjpudWxsLCJtYXhIZWlnaHQiOm51bGx9
|
||||
---
|
||||
|
||||
## Flex Wrap
|
||||
|
||||
The `flex wrap` property is set on containers and controls what happens when
|
||||
children overflow the size of the container along the main axis. By default
|
||||
children are forced into a single line (which can shrink elements).
|
||||
|
||||
If wrapping is allowed items are wrapped into multiple lines along the main
|
||||
axis if needed. `wrap reverse` behaves the same, but the order of the lines is
|
||||
reversed.
|
||||
|
||||
<controls prop="flexWrap"></controls>
|
||||
|
||||
When wrapping lines [`align content`](/docs/align-content) can be used to specify how the
|
||||
lines are placed in the container.
|
@@ -1,36 +0,0 @@
|
||||
---
|
||||
path: "/docs/flex"
|
||||
title: "Flex Basis, Grow, and Shrink"
|
||||
hasPlayground: true
|
||||
---
|
||||
|
||||
## Flex Basis, Grow, and Shrink
|
||||
|
||||
**FLEX BASIS** is an axis-independent way of providing the default size of an item
|
||||
along the main axis. Setting the flex basis of a child is similar to setting the `width` of that
|
||||
child if its parent is a container with `flex direction: row` or setting the `height` of a child
|
||||
if its parent is a container with `flex direction: column`. The flex basis of an item is the
|
||||
default size of that item, the size of the item before any flex grow and flex shrink
|
||||
calculations are performed.
|
||||
|
||||
<controls prop="flexBasis"></controls>
|
||||
|
||||
**FLEX GROW** describes how any space within a container should be distributed
|
||||
among its children along the main axis. After laying out its children, a container will
|
||||
distribute any remaining space according to the flex grow values specified by its children.
|
||||
|
||||
Flex grow accepts any floating point value >= 0, with 0 being the default value.
|
||||
A container will distribute any remaining space among its children weighted by the child’s flex grow value.
|
||||
|
||||
<controls prop="flexGrow"></controls>
|
||||
|
||||
**FLEX SHRINK** describes how to shrink children along the main axis in the
|
||||
case that the total size of the children overflow the size of the container on the main axis.
|
||||
flex shrink is very similar to flex grow and can be thought of in the same way if
|
||||
any overflowing size is considered to be negative remaining space.
|
||||
These two properties also work well together by allowing children to grow and shrink as needed.
|
||||
|
||||
Flex shrink accepts any floating point value >= 0, with 1 being the default value.
|
||||
A container will shrink its children weighted by the child’s flex shrink value.
|
||||
|
||||
<controls prop="flexShrink"></controls>
|
@@ -1,30 +0,0 @@
|
||||
---
|
||||
path: "/docs/justify-content"
|
||||
title: "Justify Content"
|
||||
hasPlayground: true
|
||||
---
|
||||
|
||||
## Justify Content
|
||||
|
||||
Justify content describes how to align children within the main axis of their container.
|
||||
For example, you can use this property to center a child horizontally within a container
|
||||
with `flex direction` set to `row` or vertically within a container with `flex direction`
|
||||
set to `column`.
|
||||
|
||||
**FLEX START (DEFAULT)** Align children of a container to the start of the container's main axis.
|
||||
|
||||
**FLEX END** Align children of a container to the end of the container's main axis.
|
||||
|
||||
**CENTER** Align children of a container in the center of the container's main axis.
|
||||
|
||||
**SPACE BETWEEN** Evenly space of children across the container's main axis, distributing
|
||||
remaining space between the children.
|
||||
|
||||
**SPACE AROUND** Evenly space of children across the container's main axis, distributing
|
||||
remaining space around the children. Compared to `space between` using
|
||||
`space around` will result in space being distributed to the beginning of
|
||||
the first child and end of the last child.
|
||||
|
||||
**SPACE EVENLY** Evenly distributed within the alignment container along the main axis. The spacing between each pair of adjacent items, the main-start edge and the first item, and the main-end edge and the last item, are all exactly the same.
|
||||
|
||||
<controls prop="justifyContent"></controls>
|
@@ -1,23 +0,0 @@
|
||||
---
|
||||
path: "/docs/layout-direction"
|
||||
title: "Layout Direction"
|
||||
hasPlayground: false
|
||||
---
|
||||
|
||||
## Layout Direction
|
||||
|
||||
Layout direction specifies the direction in which children and text
|
||||
in a hierarchy should be laid out. Layout direction also effects what
|
||||
edge `start` and `end` refer to. By default Yoga lays out with `LTR`
|
||||
layout direction. In this mode `start` refers to `left` and `end`
|
||||
refers to `right`. When localizing your apps for markets with RTL languages
|
||||
you should customize this by either by passing a direction
|
||||
to the `CalculateLayout` call or by setting the direction on the root node.
|
||||
|
||||
**LTR (DEFAULT)** Text and children and laid out from left to right. Margin and
|
||||
padding applied the start of an element are applied on the left side.
|
||||
|
||||
**RTL** Text and children and laid out from right to left. Margin and
|
||||
padding applied the start of an element are applied on the right side.
|
||||
|
||||
<controls prop="layoutDirection"></controls>
|
@@ -1,28 +0,0 @@
|
||||
---
|
||||
path: "/docs/margins-paddings-borders"
|
||||
title: "Margins, Paddings, and Borders"
|
||||
hasPlayground: true
|
||||
---
|
||||
|
||||
## Margins, Paddings, and Borders
|
||||
|
||||
**MARGIN** effects the spacing around the outside of a node. A node with margin
|
||||
will offset itself from the bounds of its parent but also offset the
|
||||
location of any siblings. The margin of a node contributes to the total size
|
||||
of its parent if the parent is auto sized.
|
||||
|
||||
<controls prop="margin"></controls>
|
||||
|
||||
**PADDING** affects the size of the node it is applied to. Padding in Yoga acts as if
|
||||
`box-sizing: border-box;` was set. That is padding will not add to the total size
|
||||
of an element if it has an explicit size set. For auto sized nodes padding will increase
|
||||
the size of the node as well as offset the location of any children.
|
||||
|
||||
<controls prop="padding"></controls>
|
||||
|
||||
**BORDER** in Yoga acts exactly like padding and only exists as a seperate property so
|
||||
that higher level frameworks get a hint as to how thick to draw a border. Yoga however
|
||||
does not do any drawing so just uses this information during layout where border
|
||||
acts exactly like padding.
|
||||
|
||||
<controls prop="border"></controls>
|
@@ -1,28 +0,0 @@
|
||||
---
|
||||
path: "/docs/min-max"
|
||||
title: "Max / Min Width and Height"
|
||||
hasPlayground: true
|
||||
---
|
||||
|
||||
## Max / Min Width and Height
|
||||
|
||||
All the following properties set the maximum and minimum size constraints of an element.
|
||||
These properties have higher priority than all other properties and will always be respected.
|
||||
Constraints can be specified as either absolute pixel values or as percentages of their
|
||||
parent's size. By default all these constraints are `undefined`.
|
||||
|
||||
### Max Width
|
||||
|
||||
<controls prop="maxWidth"></controls>
|
||||
|
||||
### Min Width
|
||||
|
||||
<controls prop="minWidth"></controls>
|
||||
|
||||
### Max Height
|
||||
|
||||
<controls prop="maxHeight"></controls>
|
||||
|
||||
### Min Height
|
||||
|
||||
<controls prop="minHeight"></controls>
|
@@ -1,26 +0,0 @@
|
||||
---
|
||||
path: "/docs/width-height"
|
||||
title: "Width and Height"
|
||||
hasPlayground: true
|
||||
---
|
||||
|
||||
## Width and Height
|
||||
|
||||
The `width` property in Yoga specifies the width of the element's content area.
|
||||
Similarly `height` property specifies the height of the element's content area.
|
||||
|
||||
Both `width` and `height` can take following values:
|
||||
|
||||
**AUTO** Is the default Value, Yoga calculates the width/height for the element based
|
||||
on its content, whether that is other children, text, or an image.
|
||||
|
||||
**PIXELS** Defines the width/height in absolute pixels. Depending on other properties set on
|
||||
the Yoga node this may or may not be the final dimension of the node.
|
||||
|
||||
**PERCENTAGE** Defines the width or height in percentage of its parent's width or height respectively.
|
||||
|
||||
### Width
|
||||
<controls prop="width"></controls>
|
||||
|
||||
### Height
|
||||
<controls prop="height"></controls>
|
@@ -1,67 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
siteMetadata: {
|
||||
title: 'Yoga Layout',
|
||||
},
|
||||
plugins: [
|
||||
// using latest react version
|
||||
'gatsby-plugin-react-next',
|
||||
// setting head data like title from within components
|
||||
'gatsby-plugin-react-helmet',
|
||||
{
|
||||
resolve: `gatsby-plugin-less`,
|
||||
options: {
|
||||
theme: {
|
||||
'primary-color': '#6BCEBB',
|
||||
},
|
||||
},
|
||||
},
|
||||
// plugin for importing antd components
|
||||
{
|
||||
resolve: 'gatsby-plugin-antd',
|
||||
options: {
|
||||
style: true,
|
||||
},
|
||||
},
|
||||
// reading files from the file-system (used for markdown files)
|
||||
{
|
||||
resolve: `gatsby-source-filesystem`,
|
||||
options: {
|
||||
path: `${__dirname}/contents`,
|
||||
name: 'markdown-pages',
|
||||
},
|
||||
},
|
||||
// parse markdown files, used for content files
|
||||
{
|
||||
resolve: `gatsby-transformer-remark`,
|
||||
options: {
|
||||
// code-highlighting in markdown files
|
||||
plugins: [
|
||||
{
|
||||
resolve: `gatsby-remark-prismjs`,
|
||||
options: {
|
||||
classPrefix: 'language-',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
resolve: `gatsby-plugin-google-analytics`,
|
||||
options: {
|
||||
trackingId: 'UA-44373548-24',
|
||||
head: false,
|
||||
anonymize: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
@@ -1,52 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
const path = require('path');
|
||||
|
||||
exports.createPages = ({boundActionCreators, graphql}) => {
|
||||
const {createPage} = boundActionCreators;
|
||||
const withPlayground = path.resolve(`src/templates/withPlayground.js`);
|
||||
const withoutPlayground = path.resolve(`src/templates/withoutPlayground.js`);
|
||||
|
||||
return graphql(`
|
||||
{
|
||||
allMarkdownRemark {
|
||||
edges {
|
||||
node {
|
||||
frontmatter {
|
||||
path
|
||||
title
|
||||
hasPlayground
|
||||
initialPlayground
|
||||
redirect
|
||||
}
|
||||
html
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`).then(result => {
|
||||
if (result.errors) {
|
||||
return Promise.reject(result.errors);
|
||||
}
|
||||
|
||||
result.data.allMarkdownRemark.edges.forEach(({node}) => {
|
||||
if (!node.frontmatter.redirect) {
|
||||
createPage({
|
||||
path: node.frontmatter.path,
|
||||
component: node.frontmatter.hasPlayground
|
||||
? withPlayground
|
||||
: withoutPlayground,
|
||||
context: node,
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
@@ -1,40 +0,0 @@
|
||||
{
|
||||
"name": "gatsby-starter-default",
|
||||
"description": "Gatsby default starter",
|
||||
"version": "1.0.0",
|
||||
"author": "Kyle Mathews <mathews.kyle@gmail.com>",
|
||||
"dependencies": {
|
||||
"antd": "^3.6.5",
|
||||
"atob": "^2.1.1",
|
||||
"btoa": "^1.2.1",
|
||||
"gatsby": "^1.9.273",
|
||||
"gatsby-link": "^1.6.45",
|
||||
"gatsby-plugin-antd": "^1.0.12",
|
||||
"gatsby-plugin-google-analytics": "^1.0.31",
|
||||
"gatsby-plugin-less": "^1.1.8",
|
||||
"gatsby-plugin-react-helmet": "^2.0.11",
|
||||
"gatsby-plugin-react-next": "^1.0.11",
|
||||
"gatsby-remark-prismjs": "^2.0.4",
|
||||
"gatsby-source-filesystem": "^1.5.39",
|
||||
"gatsby-transformer-remark": "^1.7.44",
|
||||
"immutable": "^4.0.0-rc.9",
|
||||
"react-helmet": "^5.2.0",
|
||||
"react-syntax-highlighter": "^8.0.0",
|
||||
"yoga-layout": "^1.9.3"
|
||||
},
|
||||
"keywords": [
|
||||
"gatsby"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "n/a",
|
||||
"scripts": {
|
||||
"build": "gatsby build",
|
||||
"develop": "gatsby develop"
|
||||
},
|
||||
"devDependencies": {
|
||||
"prettier": "1.19.1"
|
||||
},
|
||||
"resolutions": {
|
||||
"nbind": "https://github.com/charto/nbind.git#fe3abe0"
|
||||
}
|
||||
}
|
@@ -1,33 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
.DocsSidebar {
|
||||
height: 100%;
|
||||
width: 450px;
|
||||
padding: 36px;
|
||||
padding-top: 0px;
|
||||
border-right: 1px solid #dddfe2;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.DocsSidebar h3 {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.DocsSidebar h4 {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 992px) {
|
||||
.DocsSidebar {
|
||||
width: 100%;
|
||||
padding: 20px;
|
||||
padding-top: 0px;
|
||||
border: none;
|
||||
}
|
||||
}
|
@@ -1,84 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import EditValue from '../components/Playground/src/EditValue';
|
||||
import Link from 'gatsby-link';
|
||||
import './DocsSidebar.css';
|
||||
import type {LayoutRecordT} from './Playground/src/LayoutRecord';
|
||||
|
||||
const TAG_PATTERN = /<controls prop="([A-Za-z]+)"><\/controls>/gi;
|
||||
|
||||
type Props = {
|
||||
markdown: string,
|
||||
onChange: (property: string, value: any) => void,
|
||||
layout: LayoutRecordT,
|
||||
};
|
||||
|
||||
export default class DocsSidebar extends Component<Props> {
|
||||
componentDidMount() {
|
||||
this.renderControls(this.props);
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps: Props) {
|
||||
this.renderControls(nextProps);
|
||||
}
|
||||
|
||||
renderControls = (props: Props) => {
|
||||
let match;
|
||||
while ((match = TAG_PATTERN.exec(props.markdown))) {
|
||||
const prop = match[1];
|
||||
const element = window.document.querySelector(
|
||||
`controls[prop="${match[1]}"]`,
|
||||
);
|
||||
|
||||
if (element) {
|
||||
if (element.childNodes.length !== 0) {
|
||||
console.warn(
|
||||
`The element <controls type="${prop}"> is not empty. It's content will be replaced by the react-component mounted in this element.`,
|
||||
);
|
||||
}
|
||||
ReactDOM.render(
|
||||
<EditValue
|
||||
property={prop}
|
||||
value={props.layout[prop]}
|
||||
onChange={(property, value) => {
|
||||
if (window.ga) {
|
||||
window.ga('send', {
|
||||
hitType: 'event',
|
||||
eventCategory: 'DocsSidebar',
|
||||
eventAction: 'valueChanged',
|
||||
eventLabel: prop,
|
||||
});
|
||||
}
|
||||
props.onChange(property, value);
|
||||
}}
|
||||
/>,
|
||||
element,
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="DocsSidebar">
|
||||
<div
|
||||
className="markdown"
|
||||
dangerouslySetInnerHTML={{__html: this.props.markdown}}
|
||||
/>
|
||||
<Link to="/docs" className="overview">
|
||||
BACK TO OVERVIEW
|
||||
</Link>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
@@ -1,21 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
import React, {Component} from 'react';
|
||||
|
||||
export default () => (
|
||||
<svg viewBox="0 0 1133.9 1133.9">
|
||||
<g>
|
||||
<path d="M 498.3 3.7 c 153.6 88.9 307.3 177.7 461.1 266.2 c 7.6 4.4 10.3 9.1 10.3 17.8 c -0.3 179.1 -0.2 358.3 0 537.4 c 0 8.1 -2.4 12.8 -9.7 17.1 c -154.5 88.9 -308.8 178.1 -462.9 267.5 c -9 5.2 -15.5 5.3 -24.6 0.1 c -153.9 -89.2 -307.9 -178 -462.1 -266.8 C 3 838.8 0 833.9 0 825.1 c 0.3 -179.1 0.2 -358.3 0 -537.4 c 0 -8.6 2.6 -13.6 10.2 -18 C 164.4 180.9 318.4 92 472.4 3 C 477 -1.5 494.3 -0.7 498.3 3.7 Z M 48.8 555.3 c 0 79.9 0.2 159.9 -0.2 239.8 c -0.1 10 3 15.6 11.7 20.6 c 137.2 78.8 274.2 157.8 411 237.3 c 9.9 5.7 17 5.7 26.8 0.1 c 137.5 -79.8 275.2 -159.2 412.9 -238.5 c 7.4 -4.3 10.5 -8.9 10.5 -17.8 c -0.3 -160.2 -0.3 -320.5 0 -480.7 c 0 -8.8 -2.8 -13.6 -10.3 -18 C 772.1 218 633.1 137.8 494.2 57.4 c -6.5 -3.8 -11.5 -4.5 -18.5 -0.5 C 336.8 137.4 197.9 217.7 58.8 297.7 c -7.7 4.4 -10.2 9.2 -10.2 17.9 C 48.9 395.5 48.8 475.4 48.8 555.3 Z" />
|
||||
<path d="M 184.4 555.9 c 0 -33.3 -1 -66.7 0.3 -100 c 1.9 -48 24.1 -86 64.7 -110.9 c 54.8 -33.6 110.7 -65.5 167 -96.6 c 45.7 -25.2 92.9 -24.7 138.6 1 c 54.4 30.6 108.7 61.5 162.2 93.7 c 44 26.5 67.3 66.8 68 118.4 c 0.9 63.2 0.9 126.5 0 189.7 c -0.7 50.6 -23.4 90.7 -66.6 116.9 c -55 33.4 -110.8 65.4 -167.1 96.5 c -43.4 24 -89 24.2 -132.3 0.5 c -57.5 -31.3 -114.2 -64 -170 -98.3 c -41 -25.1 -62.9 -63.7 -64.5 -112.2 C 183.5 621.9 184.3 588.9 184.4 555.9 Z M 232.9 556.3 c 0 29.5 0.5 59.1 -0.1 88.6 c -0.8 39.2 16.9 67.1 50.2 86.2 c 51.2 29.4 102.2 59.2 153.4 88.4 c 31.4 17.9 63.6 18.3 95 0.6 c 53.7 -30.3 107.1 -61.2 160.3 -92.5 c 29.7 -17.5 45 -44.5 45.3 -78.8 c 0.6 -61.7 0.5 -123.5 0 -185.2 c -0.3 -34.4 -15.3 -61.5 -44.9 -79 C 637.7 352.6 583 320.8 527.9 290 c -27.5 -15.4 -57.2 -16.1 -84.7 -0.7 c -56.9 31.6 -113.4 64 -169.1 97.6 c -26.4 15.9 -40.7 41.3 -41.1 72.9 C 232.6 491.9 232.9 524.1 232.9 556.3 Z" />
|
||||
<path d="M 484.9 424.4 c 69.8 -2.8 133.2 57.8 132.6 132 C 617 630 558.5 688.7 484.9 689.1 c -75.1 0.4 -132.6 -63.6 -132.7 -132.7 C 352.1 485 413.4 421.5 484.9 424.4 Z M 401.3 556.7 c -3.4 37.2 30.5 83.6 83 84.1 c 46.6 0.4 84.8 -37.6 84.9 -84 c 0.1 -46.6 -37.2 -84.4 -84.2 -84.6 C 432.2 472.1 397.9 518.3 401.3 556.7 Z" />
|
||||
</g>
|
||||
</svg>
|
||||
);
|
@@ -1,63 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
.Footer {
|
||||
display: flex;
|
||||
padding: 20px 15px;
|
||||
z-index: 4;
|
||||
align-items: center;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.Footer svg {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.Footer svg path {
|
||||
fill: #606770;
|
||||
}
|
||||
|
||||
.Footer .logoOSS {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: #606770;
|
||||
}
|
||||
|
||||
.Footer .logoOSS svg {
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.Footer a {
|
||||
margin: 0 15px;
|
||||
color: #606770;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.Footer a:hover {
|
||||
color: #6BCEBB;
|
||||
}
|
||||
|
||||
.Footer .SocialNetwork {
|
||||
display: flex;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 576px) {
|
||||
.Footer {
|
||||
padding: 10px 5px;
|
||||
}
|
||||
|
||||
.Footer .logoOSS svg {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.Footer a {
|
||||
margin: 0 10px;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
@@ -1,32 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import Link from 'gatsby-link';
|
||||
import {Icon} from 'antd';
|
||||
import './Footer.css';
|
||||
import FacebookOSSLogo from './FacebookOSSLogo';
|
||||
|
||||
export default class Footer extends Component<{}> {
|
||||
render() {
|
||||
return (
|
||||
<div className="Footer">
|
||||
<a href="https://code.facebook.com/projects/" className="logoOSS">
|
||||
<FacebookOSSLogo />
|
||||
Facebook Open Source
|
||||
</a>
|
||||
<div className="SocialNetwork">
|
||||
<a href="https://github.com/facebook/yoga">GitHub</a>
|
||||
<a href="https://twitter.com/yogalayout">Twitter</a>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
@@ -1,20 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
.Padded {
|
||||
width: 100%;
|
||||
max-width: 1200px;
|
||||
padding: 0 50px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 576px) {
|
||||
.Padded {
|
||||
padding: 0 20px;
|
||||
}
|
||||
}
|
@@ -1,21 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import './Padded.css';
|
||||
|
||||
type Props = {
|
||||
children: any,
|
||||
className?: string,
|
||||
};
|
||||
|
||||
export default (props: Props) => (
|
||||
<div className={`Padded ${props.className || ''}`}>{props.children}</div>
|
||||
);
|
@@ -1,62 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
@import url('https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700|Source+Code+Pro');
|
||||
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: 'Open Sans', sans-serif;
|
||||
color: #303845;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
code,
|
||||
pre {
|
||||
font-family: 'Source Code Pro', monospace;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2 {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.gatsby-highlight pre[class*="language-"] {
|
||||
background: none;
|
||||
padding: 0;
|
||||
font-size: 14px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.Page {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.PageContent {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.PageContent.withSpacing {
|
||||
padding-top: 35px;
|
||||
}
|
||||
|
||||
.Page .ant-dropdown-trigger {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding-left: 11px;
|
||||
padding-right: 11px;
|
||||
}
|
||||
|
||||
.Page .ant-dropdown-trigger .anticon {
|
||||
margin-top: 3px;
|
||||
}
|
@@ -1,39 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import Toolbar from './Toolbar';
|
||||
import Footer from './Footer';
|
||||
import Helmet from 'react-helmet';
|
||||
import favicon from '../pages/logos/favicon.png';
|
||||
import './Page.css';
|
||||
require('prismjs/themes/prism.css');
|
||||
|
||||
type Props = {|
|
||||
children: any,
|
||||
title?: string,
|
||||
className?: string,
|
||||
withSpacing?: boolean,
|
||||
shouldShowFooter?: boolean,
|
||||
|};
|
||||
|
||||
export default (props: Props) => (
|
||||
<div className={`Page ${props.className || ''}`}>
|
||||
<Helmet>
|
||||
<title>{`Yoga Layout${props.title ? ` | ${props.title}` : ''}`}</title>
|
||||
<link rel="shortcut icon" type="image/png" href={favicon} />
|
||||
</Helmet>
|
||||
<Toolbar />
|
||||
<div className={`PageContent ${props.withSpacing ? 'withSpacing' : ''}`}>
|
||||
{props.children}
|
||||
</div>
|
||||
{props.shouldShowFooter && <Footer />}
|
||||
</div>
|
||||
);
|
@@ -1,201 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
// @flow
|
||||
import yoga from 'yoga-layout/dist/entry-browser';
|
||||
import LayoutRecord from './LayoutRecord';
|
||||
import PositionRecord from './PositionRecord';
|
||||
import type {LayoutRecordT} from './LayoutRecord';
|
||||
import type {Yoga$Direction, Yoga$Node} from 'yoga-layout';
|
||||
|
||||
const enumLookup = {
|
||||
flexDirection: {
|
||||
[yoga.FLEX_DIRECTION_COLUMN]: 'CKFlexboxDirectionVertical',
|
||||
[yoga.FLEX_DIRECTION_ROW]: 'CKFlexboxDirectionHorizontal',
|
||||
[yoga.FLEX_DIRECTION_COLUMN_REVERSE]: 'CKFlexboxDirectionVerticalReverse',
|
||||
[yoga.FLEX_DIRECTION_ROW_REVERSE]: 'CKFlexboxDirectionHorizontalReverse',
|
||||
},
|
||||
alignItems: {
|
||||
[yoga.ALIGN_FLEX_START]: 'CKFlexboxAlignItemsStart',
|
||||
[yoga.ALIGN_FLEX_END]: 'CKFlexboxAlignItemsEnd',
|
||||
[yoga.ALIGN_CENTER]: 'CKFlexboxAlignItemsCenter',
|
||||
[yoga.ALIGN_BASELINE]: 'CKFlexboxAlignItemsBaseline',
|
||||
[yoga.ALIGN_STRETCH]: 'CKFlexboxAlignItemsStretch',
|
||||
},
|
||||
alignSelf: {
|
||||
[yoga.ALIGN_AUTO]: 'CKFlexboxAlignSelfAuto',
|
||||
[yoga.ALIGN_FLEX_START]: 'CKFlexboxAlignSelfStart',
|
||||
[yoga.ALIGN_FLEX_END]: 'CKFlexboxAlignSelfEnd',
|
||||
[yoga.ALIGN_CENTER]: 'CKFlexboxAlignSelfCenter',
|
||||
[yoga.ALIGN_BASELINE]: 'CKFlexboxAlignSelfBaseline',
|
||||
[yoga.ALIGN_STRETCH]: 'CKFlexboxAlignSelfStretch',
|
||||
},
|
||||
alignContent: {
|
||||
[yoga.ALIGN_FLEX_START]: 'CKFlexboxAlignContentStart',
|
||||
[yoga.ALIGN_FLEX_END]: 'CKFlexboxAlignContentEnd',
|
||||
[yoga.ALIGN_CENTER]: 'CKFlexboxAlignContentCenter',
|
||||
[yoga.ALIGN_SPACE_BETWEEN]: 'CKFlexboxAlignContentSpaceBetween',
|
||||
[yoga.ALIGN_SPACE_AROUND]: 'CKFlexboxAlignContentSpaceAround',
|
||||
[yoga.ALIGN_STRETCH]: 'CKFlexboxAlignContentStretch',
|
||||
},
|
||||
justifyContent: {
|
||||
[yoga.JUSTIFY_FLEX_START]: 'CKFlexboxJustifyContentStart',
|
||||
[yoga.JUSTIFY_CENTER]: 'CKFlexboxJustifyContentCenter',
|
||||
[yoga.JUSTIFY_FLEX_END]: 'CKFlexboxJustifyContentEnd',
|
||||
[yoga.JUSTIFY_SPACE_BETWEEN]: 'CKFlexboxJustifyContentSpaceBetween',
|
||||
[yoga.JUSTIFY_SPACE_AROUND]: 'CKFlexboxJustifyContentSpaceAround',
|
||||
},
|
||||
flexWrap: {
|
||||
[yoga.WRAP_NO_WRAP]: 'CKFlexboxWrapNoWrap',
|
||||
[yoga.WRAP_WRAP]: 'CKFlexboxWrapWrap',
|
||||
[yoga.WRAP_WRAP_REVERSE]: 'CKFlexboxWrapWrapReverse',
|
||||
},
|
||||
positionType: {
|
||||
[yoga.POSITION_TYPE_RELATIVE]: 'CKFlexboxPositionTypeRelative',
|
||||
[yoga.POSITION_TYPE_ABSOLUTE]: 'CKFlexboxPositionTypeAbsolute',
|
||||
},
|
||||
};
|
||||
|
||||
const untouchedLayout = LayoutRecord({});
|
||||
const untouchedPosition = PositionRecord({});
|
||||
|
||||
function keyLookup(key: string): string {
|
||||
const keyLookup = {
|
||||
flexWrap: 'wrap',
|
||||
flexDirection: 'direction',
|
||||
};
|
||||
return keyLookup[key] || key;
|
||||
}
|
||||
|
||||
function getValue(value) {
|
||||
if (typeof value === 'string' && /%$/.test(value)) {
|
||||
return `RCRelativeDimension::Percent(${parseFloat(value)})`;
|
||||
} else if (value === 'auto') {
|
||||
return 'RCRelativeDimension::Auto()';
|
||||
} else {
|
||||
return String(parseFloat(value));
|
||||
}
|
||||
}
|
||||
|
||||
function getLayoutCode(
|
||||
node: LayoutRecordT,
|
||||
indent: string = '',
|
||||
isRoot?: boolean,
|
||||
): string {
|
||||
const lines = [];
|
||||
const isFlexbox = node.children.size > 0;
|
||||
|
||||
lines.push(
|
||||
indent +
|
||||
`${isRoot ? '' : `.component = \n${indent}`}[${
|
||||
isFlexbox ? 'CKFlexboxComponent' : 'CKComponent'
|
||||
}`,
|
||||
);
|
||||
lines.push(indent + ` newWithView:{}`);
|
||||
lines.push(
|
||||
indent + ` size:{${getValue(node.width)},${getValue(node.height)}}`,
|
||||
);
|
||||
|
||||
const CKFlexboxComponentStyle = [
|
||||
'direction',
|
||||
'margin',
|
||||
'justifyContent',
|
||||
'alignItems',
|
||||
'alignContent',
|
||||
'wrap',
|
||||
'padding',
|
||||
'border',
|
||||
];
|
||||
const CKFlexboxComponentChild = [
|
||||
'margin',
|
||||
'padding',
|
||||
'flexGrow',
|
||||
'flexShrink',
|
||||
'flexBasis',
|
||||
'alignSelf',
|
||||
'position',
|
||||
];
|
||||
|
||||
if (isFlexbox) {
|
||||
// render styles
|
||||
lines.push(indent + ` style:{`);
|
||||
indent += '\t';
|
||||
CKFlexboxComponentStyle.forEach(key => {
|
||||
let line = renderKey(node, key, indent);
|
||||
if (line) {
|
||||
lines.push(line);
|
||||
}
|
||||
});
|
||||
indent = indent.substr(-1);
|
||||
lines.push(indent + ` }`);
|
||||
|
||||
// render children
|
||||
lines.push(indent + ' children:{');
|
||||
lines.push(
|
||||
...node.children
|
||||
.toJSON()
|
||||
.map(
|
||||
child =>
|
||||
`${indent}\t{\n${getLayoutCode(
|
||||
child,
|
||||
indent + '\t\t',
|
||||
)}\n${indent}\t},`,
|
||||
),
|
||||
);
|
||||
lines.push(indent + `}]${isRoot ? ';' : ','}`);
|
||||
} else {
|
||||
lines[lines.length - 1] += '],';
|
||||
CKFlexboxComponentChild.forEach(key => {
|
||||
let line = renderKey(node, key, indent);
|
||||
if (line) {
|
||||
lines.push(line);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return lines.join('\n');
|
||||
}
|
||||
|
||||
function renderKey(node: Yoga$Node, key: string, indent: string): ?string {
|
||||
if (
|
||||
node[key] instanceof PositionRecord &&
|
||||
!node[key].equals(untouchedPosition)
|
||||
) {
|
||||
const lines = [];
|
||||
lines.push(indent + `.${key} = {`);
|
||||
|
||||
if (key === 'position') {
|
||||
lines.push(
|
||||
indent + `\t.type = ${enumLookup.positionType[node.positionType]},`,
|
||||
);
|
||||
}
|
||||
|
||||
['top', 'start', 'end', 'bottom'].forEach(pKey => {
|
||||
if (node[key][pKey]) {
|
||||
lines.push(indent + `\t.${pKey} = ${getValue(node[key][pKey])},`);
|
||||
}
|
||||
});
|
||||
|
||||
lines.push(indent + `},`);
|
||||
return lines.join('\n');
|
||||
} else if (node[key] !== untouchedLayout[key]) {
|
||||
if (enumLookup[key]) {
|
||||
return indent + `.${keyLookup(key)} = ${enumLookup[key][node[key]]},`;
|
||||
} else {
|
||||
console.error(`Unknown property ${key}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default function generateCode(
|
||||
root: LayoutRecordT,
|
||||
direction: Yoga$Direction,
|
||||
): string {
|
||||
return ['CKFlexboxComponent *c =', getLayoutCode(root, '\t', true)].join(
|
||||
'\n',
|
||||
);
|
||||
}
|
@@ -1,27 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
.CodeGeneratorsTitle {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
|
||||
.CodeGeneratorsTitle a {
|
||||
font-size: 13px;
|
||||
font-weight: normal;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.CodeGeneratorsCopyText {
|
||||
position: absolute;
|
||||
top: -9999em;
|
||||
left: -9999em;
|
||||
pointer-events: none;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
@@ -1,158 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import {Menu, Button, Row, Col, Dropdown, Icon, Modal, Tooltip} from 'antd';
|
||||
import SyntaxHighlighter, {
|
||||
registerLanguage,
|
||||
} from 'react-syntax-highlighter/prism-light';
|
||||
import styles from 'react-syntax-highlighter/styles/prism/prism';
|
||||
import CodeJavaScript from './CodeJavaScript';
|
||||
import CodeLitho from './CodeLitho';
|
||||
import CodeReactNative from './CodeReactNative';
|
||||
import CodeComponentKit from './CodeComponentKit';
|
||||
import jsx from 'react-syntax-highlighter/languages/prism/jsx';
|
||||
//import javascript from 'react-syntax-highlighter/languages/prism/javascript';
|
||||
import java from 'react-syntax-highlighter/languages/prism/java';
|
||||
import objectivec from 'react-syntax-highlighter/languages/prism/objectivec';
|
||||
registerLanguage('jsx', jsx);
|
||||
//registerLanguage('javascript', javascript);
|
||||
registerLanguage('java', java);
|
||||
registerLanguage('objectivec', objectivec);
|
||||
|
||||
import './CodeGenerators.css';
|
||||
|
||||
import type {LayoutRecordT} from './LayoutRecord';
|
||||
import type {Yoga$Direction} from 'yoga-layout';
|
||||
|
||||
type Props = {
|
||||
layoutDefinition: LayoutRecordT,
|
||||
direction: Yoga$Direction,
|
||||
};
|
||||
type State = {
|
||||
showModal: ?string,
|
||||
copied: boolean,
|
||||
};
|
||||
|
||||
const LANGUAGES = {
|
||||
litho: {
|
||||
title: 'Litho',
|
||||
generator: CodeLitho,
|
||||
syntax: 'java',
|
||||
},
|
||||
componentKit: {
|
||||
title: 'ComponentKit',
|
||||
generator: CodeComponentKit,
|
||||
syntax: 'objectivec',
|
||||
},
|
||||
reactNative: {
|
||||
title: 'React Native',
|
||||
generator: CodeReactNative,
|
||||
syntax: 'jsx',
|
||||
},
|
||||
};
|
||||
['Litho', 'ComponentKit', 'React Native'];
|
||||
|
||||
export default class CodeGenerators extends Component<Props, State> {
|
||||
state = {
|
||||
showModal: null,
|
||||
copied: false,
|
||||
};
|
||||
|
||||
_ref: ?HTMLTextAreaElement;
|
||||
|
||||
onClick = ({key}: {key: string}) => {
|
||||
this.setState({showModal: key});
|
||||
if (window.ga) {
|
||||
window.ga('send', {
|
||||
hitType: 'event',
|
||||
eventCategory: 'CodeGenerators',
|
||||
eventAction: 'show',
|
||||
eventLabel: key,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
onCopy = () => {
|
||||
if (this._ref) {
|
||||
this._ref.select();
|
||||
document.execCommand('Copy');
|
||||
this.setState({copied: true});
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const {showModal} = this.state;
|
||||
|
||||
const menu = (
|
||||
<Menu onClick={this.onClick}>
|
||||
{Object.keys(LANGUAGES).map(key => (
|
||||
<Menu.Item key={key}>{LANGUAGES[key].title}</Menu.Item>
|
||||
))}
|
||||
</Menu>
|
||||
);
|
||||
|
||||
const code = showModal
|
||||
? LANGUAGES[showModal].generator(
|
||||
this.props.layoutDefinition,
|
||||
this.props.direction,
|
||||
)
|
||||
: '';
|
||||
|
||||
return [
|
||||
<Modal
|
||||
key="modal"
|
||||
title={
|
||||
showModal ? (
|
||||
<div className="CodeGeneratorsTitle">
|
||||
{LANGUAGES[showModal].title}
|
||||
<Tooltip
|
||||
title={this.state.copied ? 'Copied!' : 'Click to copy'}
|
||||
onVisibleChange={() => this.setState({copied: false})}>
|
||||
<a onClick={this.onCopy}>copy to clipboard</a>
|
||||
</Tooltip>
|
||||
</div>
|
||||
) : (
|
||||
''
|
||||
)
|
||||
}
|
||||
visible={Boolean(showModal)}
|
||||
footer={null}
|
||||
bodyStyle={{padding: 0}}
|
||||
onCancel={() => this.setState({showModal: null})}>
|
||||
{showModal && (
|
||||
<div>
|
||||
<textarea
|
||||
className="CodeGeneratorsCopyText"
|
||||
value={code}
|
||||
ref={ref => {
|
||||
this._ref = ref;
|
||||
}}
|
||||
/>
|
||||
<SyntaxHighlighter
|
||||
language={LANGUAGES[showModal].syntax}
|
||||
style={styles}
|
||||
customStyle={{fontSize: '13px', backgroundColor: 'white'}}
|
||||
lineNumberStyle={{userSelect: 'none', opacity: 0.5}}
|
||||
codeTagProps={{style: {tabSize: 4}}}
|
||||
showLineNumbers>
|
||||
{code}
|
||||
</SyntaxHighlighter>
|
||||
</div>
|
||||
)}
|
||||
</Modal>,
|
||||
<Dropdown overlay={menu} key="dropdown" trigger={['click']}>
|
||||
<Button>
|
||||
Get Code <Icon type="down" />
|
||||
</Button>
|
||||
</Dropdown>,
|
||||
];
|
||||
}
|
||||
}
|
@@ -1,138 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
import yoga from 'yoga-layout/dist/entry-browser';
|
||||
import LayoutRecord from './LayoutRecord';
|
||||
import PositionRecord from './PositionRecord';
|
||||
import type {LayoutRecordT} from './LayoutRecord';
|
||||
import type {Yoga$Direction} from 'yoga-layout';
|
||||
|
||||
export const JSEnumLookup = {
|
||||
justifyContent: 'JUSTIFY_',
|
||||
alignItems: 'ALIGN_',
|
||||
alignContent: 'ALIGN_',
|
||||
alignSelf: 'ALIGN_',
|
||||
position: 'POSITION_',
|
||||
flexDirection: 'DIRECTION_',
|
||||
flexWrap: 'WRAP_',
|
||||
positionType: 'POSITION_TYPE_',
|
||||
direction: 'DIRECTION_',
|
||||
};
|
||||
|
||||
function getEnum(yogaEnum: string, value: string | number): string {
|
||||
return `yoga.${
|
||||
Object.keys(yoga)
|
||||
.filter(key => key.toLowerCase().startsWith(yogaEnum.toLowerCase()))
|
||||
.find(key => yoga[key] === value) || value
|
||||
}`;
|
||||
}
|
||||
|
||||
function setProperty(
|
||||
name: string,
|
||||
key: string,
|
||||
value: string,
|
||||
enumValue?: string,
|
||||
): string {
|
||||
return [
|
||||
name,
|
||||
'.set',
|
||||
key[0].toUpperCase() + key.substr(1),
|
||||
'(',
|
||||
enumValue ? `${enumValue}, ` : '',
|
||||
JSEnumLookup[key] ? getEnum(JSEnumLookup[key], value) : value,
|
||||
');',
|
||||
].join('');
|
||||
}
|
||||
|
||||
function getLayoutCode(
|
||||
node: LayoutRecordT,
|
||||
name: string,
|
||||
index: number,
|
||||
): string {
|
||||
const lines = [];
|
||||
const childName = (i: number) => `${name === 'root' ? 'node' : name}_${i}`;
|
||||
|
||||
lines.push(
|
||||
...node.children.map((node, i) => getLayoutCode(node, childName(i), i)),
|
||||
);
|
||||
|
||||
lines.push('', `// create node ${name}`, `const ${name} = Node.create();`);
|
||||
const untouchedNode = LayoutRecord({width: '', height: ''});
|
||||
Object.keys(untouchedNode.toJS()).forEach(key => {
|
||||
if (key !== 'children' && untouchedNode[key] !== node[key]) {
|
||||
if (node[key] instanceof PositionRecord) {
|
||||
// iterate through position record
|
||||
const {top, left, right, bottom} = node[key].toJS();
|
||||
if (
|
||||
top !== untouchedNode[key].top &&
|
||||
top === left &&
|
||||
top === right &&
|
||||
top === bottom
|
||||
) {
|
||||
// all edges
|
||||
lines.push(setProperty(name, key, node[key].top, getEnum('edge', 8)));
|
||||
return;
|
||||
}
|
||||
const alreadySet = [];
|
||||
if (top !== untouchedNode[key].top && top === bottom) {
|
||||
lines.push(setProperty(name, key, node[key].top, getEnum('edge', 7)));
|
||||
alreadySet.push('top', 'bottom');
|
||||
}
|
||||
if (left !== untouchedNode[key].left && left === right) {
|
||||
lines.push(
|
||||
setProperty(name, key, node[key].left, getEnum('edge', 6)),
|
||||
);
|
||||
alreadySet.push('left', 'right');
|
||||
}
|
||||
['left', 'top', 'right', 'bottom'].forEach((pKey, i) => {
|
||||
if (
|
||||
node[key][pKey] !== untouchedNode[key][pKey] &&
|
||||
alreadySet.indexOf(pKey) === -1
|
||||
) {
|
||||
lines.push(
|
||||
setProperty(name, key, node[key][pKey], getEnum('edge', i)),
|
||||
);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
lines.push(setProperty(name, key, node[key]));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (node.children && node.children.size > 0) {
|
||||
lines.push(
|
||||
'',
|
||||
'// insert children',
|
||||
...node.children.map(
|
||||
(_, i) => `${name}.insertChild(${childName(i)}, ${i});`,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return lines.join('\n');
|
||||
}
|
||||
|
||||
export default function generateCode(
|
||||
root: LayoutRecordT,
|
||||
direction: Yoga$Direction,
|
||||
): string {
|
||||
const rootNodeName = 'root';
|
||||
return [
|
||||
`import yoga, {Node} from 'yoga-layout';`,
|
||||
getLayoutCode(root, rootNodeName, 0),
|
||||
'',
|
||||
`${rootNodeName}.calculateLayout(${root.width}, ${root.height}, ${getEnum(
|
||||
'direction',
|
||||
direction,
|
||||
)});`,
|
||||
`${rootNodeName}.getComputedLayout();`,
|
||||
].join('\n');
|
||||
}
|
@@ -1,219 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
import yoga from 'yoga-layout/dist/entry-browser';
|
||||
import LayoutRecord from './LayoutRecord';
|
||||
import PositionRecord from './PositionRecord';
|
||||
import {JSEnumLookup} from './CodeJavaScript';
|
||||
import type {LayoutRecordT} from './LayoutRecord';
|
||||
import type {Yoga$Direction} from 'yoga-layout';
|
||||
|
||||
function getEnum(yogaEnum: string, value: string | number): string {
|
||||
const enumLookup = {
|
||||
justifyContent: 'Justify',
|
||||
alignItems: 'Align',
|
||||
alignContent: 'Align',
|
||||
alignSelf: 'Align',
|
||||
position: 'Position',
|
||||
flexWrap: 'Wrap',
|
||||
positionType: 'PositionType',
|
||||
direction: 'Direction',
|
||||
};
|
||||
|
||||
if (!enumLookup[yogaEnum]) {
|
||||
return String(value);
|
||||
} else {
|
||||
const enumValue = Object.keys(yoga)
|
||||
.filter(key =>
|
||||
key.toLowerCase().startsWith(JSEnumLookup[yogaEnum].toLowerCase()),
|
||||
)
|
||||
.find(key => yoga[key] === value);
|
||||
|
||||
return `Yoga${enumLookup[yogaEnum]}.${
|
||||
enumValue ? enumValue.replace(/^([A-Z]+)_/, '') : value
|
||||
}`;
|
||||
}
|
||||
}
|
||||
|
||||
function dipOrPercent(value) {
|
||||
console.log(value);
|
||||
return value === 'auto'
|
||||
? 'Auto'
|
||||
: typeof value === 'string' && /%$/.test(value)
|
||||
? 'Percent'
|
||||
: 'Dip';
|
||||
}
|
||||
|
||||
function getValue(value) {
|
||||
return value === 'auto' ? '' : `, ${parseFloat(value)}`;
|
||||
}
|
||||
|
||||
function getLayoutCode(
|
||||
node: LayoutRecordT,
|
||||
indent: string = '',
|
||||
isReturning?: boolean,
|
||||
): string {
|
||||
const lines = [];
|
||||
const flexDirection = {
|
||||
[yoga.FLEX_DIRECTION_ROW]: 'Row',
|
||||
[yoga.FLEX_DIRECTION_ROW_REVERSE]: 'RowReverse',
|
||||
[yoga.FLEX_DIRECTION_COLUMN]: 'Column',
|
||||
[yoga.FLEX_DIRECTION_COLUMN_REVERSE]: 'ColumnReverse',
|
||||
};
|
||||
|
||||
lines.push(
|
||||
indent +
|
||||
`${isReturning ? 'return ' : ''}${
|
||||
flexDirection[node.flexDirection]
|
||||
}.create(c)`,
|
||||
);
|
||||
if (node.children.size > 0) {
|
||||
lines.push(
|
||||
...node.children
|
||||
.toJSON()
|
||||
.map(
|
||||
child =>
|
||||
`${indent}\t.child(\n${getLayoutCode(child, indent + '\t\t')})`,
|
||||
),
|
||||
);
|
||||
}
|
||||
const untouchedLayout = LayoutRecord();
|
||||
const untouchedPosition = PositionRecord({});
|
||||
Object.keys(node.toJSON()).forEach(key => {
|
||||
if (
|
||||
node[key] instanceof PositionRecord &&
|
||||
!node[key].equals(untouchedPosition)
|
||||
) {
|
||||
if (key === 'border') {
|
||||
lines.push(indent + '\t.border(', indent + '\t\tBorder.create(c)');
|
||||
}
|
||||
|
||||
const {top, left, right, bottom} = node[key].toJS();
|
||||
if (
|
||||
top !== untouchedPosition.top &&
|
||||
top === left &&
|
||||
top === right &&
|
||||
top === bottom
|
||||
) {
|
||||
// all edges
|
||||
lines.push(
|
||||
indent +
|
||||
(key === 'border'
|
||||
? `\t\t\t.width${dipOrPercent(
|
||||
node[key].top,
|
||||
)}(YogaEdge.ALL${getValue(node[key].top)})`
|
||||
: `\t.${key}${dipOrPercent(node[key].top)}(YogaEdge.ALL${getValue(
|
||||
node[key].top,
|
||||
)})`),
|
||||
);
|
||||
return;
|
||||
}
|
||||
const alreadySet = [];
|
||||
if (top !== untouchedPosition.top && top === bottom) {
|
||||
lines.push(
|
||||
indent +
|
||||
(key === 'border'
|
||||
? `\t\t\t.width${dipOrPercent(
|
||||
node[key].top,
|
||||
)}(YogaEdge.VERTICAL${getValue(node[key].top)})`
|
||||
: `\t.${key}${dipOrPercent(
|
||||
node[key].top,
|
||||
)}(YogaEdge.VERTICAL${getValue(node[key].top)})`),
|
||||
);
|
||||
alreadySet.push('top', 'bottom');
|
||||
}
|
||||
if (left !== untouchedPosition.left && left === right) {
|
||||
lines.push(
|
||||
indent +
|
||||
(key === 'border'
|
||||
? `\t\t\t.width${dipOrPercent(
|
||||
node[key].left,
|
||||
)}(YogaEdge.HORIZONTAL${getValue(node[key].left)})`
|
||||
: `\t.${key}${dipOrPercent(
|
||||
node[key].left,
|
||||
)}(YogaEdge.HORIZONTAL${getValue(node[key].left)})`),
|
||||
);
|
||||
alreadySet.push('left', 'right');
|
||||
}
|
||||
['left', 'top', 'right', 'bottom'].forEach((pKey, i) => {
|
||||
if (
|
||||
node[key][pKey] !== untouchedPosition[pKey] &&
|
||||
alreadySet.indexOf(pKey) === -1 &&
|
||||
node[key][pKey]
|
||||
) {
|
||||
lines.push(
|
||||
indent +
|
||||
(key === 'border'
|
||||
? `\t\t\t.width${dipOrPercent(
|
||||
node.border[pKey],
|
||||
)}(YogaEdge.${pKey.toUpperCase()}${getValue(
|
||||
node.border[pKey],
|
||||
)})`
|
||||
: `\t.${key}${dipOrPercent(
|
||||
node[key][pKey],
|
||||
)}(YogaEdge.${pKey.toUpperCase()}${getValue(
|
||||
node[key][pKey],
|
||||
)})`),
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
if (key === 'border') {
|
||||
lines.push(
|
||||
indent + '\t\t\t.color(YogaEdge.ALL, 0xfff36b7f)',
|
||||
indent + '\t\t\t.build())',
|
||||
);
|
||||
}
|
||||
} else if (
|
||||
key !== 'children' &&
|
||||
key !== 'flexDirection' &&
|
||||
node[key] !== untouchedLayout[key] &&
|
||||
node[key]
|
||||
) {
|
||||
if (node[key] === 'auto') {
|
||||
lines.push(indent + `\t.${key}Auto(${getEnum(key, node[key])})`);
|
||||
} else if (typeof node[key] === 'string' && /%$/.test(node[key])) {
|
||||
lines.push(indent + `\t.${key}Percent(${parseFloat(node[key])})`);
|
||||
} else if (
|
||||
[
|
||||
'width',
|
||||
'height',
|
||||
'minHeight',
|
||||
'maxHeight',
|
||||
'minWidth',
|
||||
'maxWidth',
|
||||
'flexBasis',
|
||||
].indexOf(key) > -1
|
||||
) {
|
||||
lines.push(indent + `\t.${key}Dip(${getEnum(key, node[key])})`);
|
||||
} else {
|
||||
lines.push(indent + `\t.${key}(${getEnum(key, node[key])})`);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return lines.join('\n');
|
||||
}
|
||||
|
||||
export default function generateCode(
|
||||
root: LayoutRecordT,
|
||||
direction: Yoga$Direction,
|
||||
): string {
|
||||
return [
|
||||
'@LayoutSpec',
|
||||
'public class PlaygroundComponentSpec {',
|
||||
'\t@OnCreateLayout',
|
||||
'\tstatic Component onCreateLayout(ComponentContext c) {',
|
||||
getLayoutCode(root, '\t\t', true),
|
||||
'\t\t\t.build();',
|
||||
'\t}',
|
||||
'}',
|
||||
].join('\n');
|
||||
}
|
@@ -1,151 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
import yoga from 'yoga-layout/dist/entry-browser';
|
||||
import LayoutRecord from './LayoutRecord';
|
||||
import PositionRecord from './PositionRecord';
|
||||
import {JSEnumLookup} from './CodeJavaScript';
|
||||
import type {LayoutRecordT} from './LayoutRecord';
|
||||
import type {Yoga$Direction} from 'yoga-layout';
|
||||
|
||||
function getValue(value) {
|
||||
return typeof value === 'number' || /^\d+$/.test(value)
|
||||
? String(value)
|
||||
: `'${value}'`;
|
||||
}
|
||||
|
||||
function getEnum(yogaEnum: string, value: string | number): string {
|
||||
console.log(yogaEnum);
|
||||
const enumValue = Object.keys(yoga)
|
||||
.filter(
|
||||
key =>
|
||||
JSEnumLookup[yogaEnum] &&
|
||||
key.toLowerCase().startsWith(JSEnumLookup[yogaEnum].toLowerCase()),
|
||||
)
|
||||
.find(key => yoga[key] === value);
|
||||
|
||||
return enumValue
|
||||
? "'" +
|
||||
enumValue
|
||||
.replace(/^([A-Z]+)_/, '')
|
||||
.replace('_', '-')
|
||||
.toLowerCase() +
|
||||
"'"
|
||||
: getValue(value);
|
||||
}
|
||||
|
||||
function getLayoutCode(node: LayoutRecordT, indent: string = ''): string {
|
||||
const lines = [];
|
||||
const untouchedLayout = LayoutRecord();
|
||||
lines.push(indent + '<View style={{');
|
||||
lines.push(indent + ' flex: 1,');
|
||||
Object.keys(node.toJSON()).forEach(key => {
|
||||
if (key === 'border' && !node.border.equals(untouchedLayout[key])) {
|
||||
['Top', 'Left', 'Right', 'Bottom'].forEach(pKey => {
|
||||
if (
|
||||
untouchedLayout[key][pKey.toLowerCase()] !==
|
||||
node.border[pKey.toLowerCase()]
|
||||
) {
|
||||
lines.push(
|
||||
indent +
|
||||
` border${pKey}Width: ${getValue(
|
||||
node.border[pKey.toLowerCase()],
|
||||
)},`,
|
||||
);
|
||||
}
|
||||
});
|
||||
} else if (
|
||||
node[key] instanceof PositionRecord &&
|
||||
!node[key].equals(untouchedLayout[key])
|
||||
) {
|
||||
const {top, left, right, bottom} = node[key].toJS();
|
||||
if (
|
||||
top &&
|
||||
top !== untouchedLayout[key].top &&
|
||||
top === left &&
|
||||
top === right &&
|
||||
top === bottom
|
||||
) {
|
||||
// all edges
|
||||
lines.push(indent + ` ${key}: ${node[key].top},`);
|
||||
return;
|
||||
}
|
||||
const alreadySet = [];
|
||||
if (top && top !== untouchedLayout[key].top && top === bottom) {
|
||||
lines.push(indent + ` ${key}Vertical: ${getValue(node[key].top)},`);
|
||||
alreadySet.push('top', 'bottom');
|
||||
}
|
||||
if (left && left !== untouchedLayout[key].left && left === right) {
|
||||
lines.push(indent + ` ${key}Horizontal: ${getValue(node[key].left)},`);
|
||||
alreadySet.push('left', 'right');
|
||||
}
|
||||
['left', 'top', 'right', 'bottom'].forEach((pKey, i) => {
|
||||
if (
|
||||
node[key][pKey] !== untouchedLayout[key][pKey] &&
|
||||
alreadySet.indexOf(pKey) === -1 &&
|
||||
node[key][pKey] &&
|
||||
!Number.isNaN(node[key][pKey])
|
||||
) {
|
||||
lines.push(
|
||||
indent +
|
||||
` ${key}${pKey[0].toUpperCase()}${pKey.substr(1)}: ${getValue(
|
||||
node[key][pKey],
|
||||
)},`,
|
||||
);
|
||||
}
|
||||
});
|
||||
} else if (
|
||||
key === 'positionType' &&
|
||||
node[key] === yoga.POSITION_TYPE_ABSOLUTE
|
||||
) {
|
||||
lines.push(indent + ` position: 'absolute',`);
|
||||
} else if (
|
||||
key !== 'children' &&
|
||||
node[key] !== untouchedLayout[key] &&
|
||||
node[key]
|
||||
) {
|
||||
lines.push(indent + ` ${key}: ${getEnum(key, node[key])},`);
|
||||
}
|
||||
});
|
||||
if (node.children.size > 0) {
|
||||
lines.push(indent + '}}>');
|
||||
} else {
|
||||
lines.push(indent + '}} />');
|
||||
}
|
||||
if (node.children.size > 0) {
|
||||
lines.push(
|
||||
...node.children
|
||||
.toJSON()
|
||||
.map(child => getLayoutCode(child, indent + ' ')),
|
||||
);
|
||||
}
|
||||
if (node.children.size > 0) {
|
||||
lines.push(indent + '</View>');
|
||||
}
|
||||
return lines.join('\n');
|
||||
}
|
||||
|
||||
export default function generateCode(
|
||||
root: LayoutRecordT,
|
||||
direction: Yoga$Direction,
|
||||
): string {
|
||||
return [
|
||||
`import React, {Component} from 'react';`,
|
||||
`import {View} from 'react-native';`,
|
||||
'',
|
||||
'export default class MyLayout extends Component {',
|
||||
' render() {',
|
||||
' return (',
|
||||
getLayoutCode(root, ' '),
|
||||
' );',
|
||||
' }',
|
||||
'};',
|
||||
].join('\n');
|
||||
}
|
@@ -1,42 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import YogaEnumSelect from './YogaEnumSelect';
|
||||
import YogaPositionEditor from './YogaPositionEditor';
|
||||
import {Input} from 'antd';
|
||||
|
||||
type Props<T> = {
|
||||
property: string,
|
||||
disabled?: boolean,
|
||||
value?: ?T,
|
||||
onChange: (property: string, value: T) => void,
|
||||
};
|
||||
|
||||
export default (props: Props<*>) => {
|
||||
if (YogaEnumSelect.availableProperties.indexOf(props.property) > -1) {
|
||||
return <YogaEnumSelect {...props} />;
|
||||
} else if (
|
||||
YogaPositionEditor.availableProperties.indexOf(props.property) > -1
|
||||
) {
|
||||
return <YogaPositionEditor {...props} />;
|
||||
} else {
|
||||
return (
|
||||
<Input
|
||||
type="text"
|
||||
{...props}
|
||||
onChange={e => props.onChange(props.property, e.target.value)}
|
||||
placeholder={props.placeholder || 'undefined'}
|
||||
onFocus={e => e.target.select()}
|
||||
value={Number.isNaN(props.value) ? '' : props.value}
|
||||
/>
|
||||
);
|
||||
}
|
||||
};
|
@@ -1,63 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
.Editor {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
border-top: 1px solid #E8E8E8;
|
||||
}
|
||||
|
||||
.Editor .field {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.Editor .ant-btn {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.Editor h2 {
|
||||
margin-bottom: 8px;
|
||||
margin-top: 20px;
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
color: #444950;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.Editor h2:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.Editor .ant-tabs-nav .ant-tabs-tab {
|
||||
margin-left: 16px;
|
||||
}
|
||||
|
||||
.Editor .EditorTabs {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.Editor .ant-tabs {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.Editor .ant-tabs-bar {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.Editor .ant-tabs-tabpane {
|
||||
overflow-y: auto;
|
||||
min-height: 320px;
|
||||
height: 100%;
|
||||
max-height: 25vh;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.Editor .EditorButtons {
|
||||
padding: 15px;
|
||||
}
|
@@ -1,356 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import {Row, Col, Button, Tabs} from 'antd';
|
||||
import EditValue from './EditValue';
|
||||
import type {LayoutRecordT} from './LayoutRecord';
|
||||
import type {Yoga$Direction} from 'yoga-layout';
|
||||
import InfoText from './InfoText';
|
||||
import './Editor.css';
|
||||
const TabPane = Tabs.TabPane;
|
||||
|
||||
type Props = {
|
||||
node: ?LayoutRecordT,
|
||||
onChangeLayout: (key: string, value: any) => void,
|
||||
onChangeSetting: (key: string, value: any) => void,
|
||||
direction: Yoga$Direction,
|
||||
selectedNodeIsRoot: boolean,
|
||||
onRemove?: () => void,
|
||||
onAdd?: () => void,
|
||||
};
|
||||
|
||||
export default class Editor extends Component<Props> {
|
||||
componentDidMount() {
|
||||
document.addEventListener('keydown', this.onKeyDown);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
document.removeEventListener('keydown', this.onKeyDown);
|
||||
}
|
||||
|
||||
onKeyDown = (e: KeyboardEvent) => {
|
||||
if (
|
||||
(e.key === 'Delete' || e.key === 'Backspace') &&
|
||||
this.props.onRemove &&
|
||||
!(e.target instanceof HTMLInputElement)
|
||||
) {
|
||||
this.props.onRemove();
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const {node, selectedNodeIsRoot} = this.props;
|
||||
const disabled = !Boolean(node);
|
||||
|
||||
return (
|
||||
<div className="Editor">
|
||||
<Tabs defaultActiveKey="1" className="EditorTabs">
|
||||
<TabPane tab="Flex" key="1">
|
||||
<h2>
|
||||
Direction
|
||||
<InfoText doclink="/docs/layout-direction">
|
||||
Defines the direction of which text and items are laid out
|
||||
</InfoText>
|
||||
</h2>
|
||||
<EditValue
|
||||
property="direction"
|
||||
value={this.props.direction}
|
||||
onChange={this.props.onChangeSetting}
|
||||
/>
|
||||
<h2>
|
||||
Flex Direction
|
||||
<InfoText doclink="/docs/flex-direction">
|
||||
Defines the direction of the main-axis
|
||||
</InfoText>
|
||||
</h2>
|
||||
<EditValue
|
||||
disabled={disabled}
|
||||
property="flexDirection"
|
||||
value={node ? node.flexDirection : undefined}
|
||||
onChange={this.props.onChangeLayout}
|
||||
/>
|
||||
|
||||
<Row gutter={15} style={{marginTop: 30}}>
|
||||
<Col span={8}>
|
||||
<h2>
|
||||
Basis
|
||||
<InfoText doclink="/docs/flex">
|
||||
Default size of a node along the main axis
|
||||
</InfoText>
|
||||
</h2>
|
||||
<EditValue
|
||||
type="text"
|
||||
property="flexBasis"
|
||||
placeholder="auto"
|
||||
disabled={disabled || selectedNodeIsRoot}
|
||||
value={node ? node.flexBasis : undefined}
|
||||
onChange={this.props.onChangeLayout}
|
||||
/>
|
||||
</Col>
|
||||
<Col span={8}>
|
||||
<h2>
|
||||
Grow
|
||||
<InfoText doclink="/docs/flex">
|
||||
The factor of remaining space should be given to this node
|
||||
</InfoText>
|
||||
</h2>
|
||||
<EditValue
|
||||
type="text"
|
||||
property="flexGrow"
|
||||
placeholder="0"
|
||||
disabled={disabled || selectedNodeIsRoot}
|
||||
value={node ? node.flexGrow : undefined}
|
||||
onChange={this.props.onChangeLayout}
|
||||
/>
|
||||
</Col>
|
||||
<Col span={8}>
|
||||
<h2>
|
||||
Shrink
|
||||
<InfoText doclink="/docs/flex">
|
||||
The shrink factor of this element if parent has no space
|
||||
left
|
||||
</InfoText>
|
||||
</h2>
|
||||
<EditValue
|
||||
type="text"
|
||||
property="flexShrink"
|
||||
placeholder="1"
|
||||
disabled={disabled || selectedNodeIsRoot}
|
||||
value={node ? node.flexShrink : undefined}
|
||||
onChange={this.props.onChangeLayout}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<h2>
|
||||
Flex Wrap
|
||||
<InfoText doclink="/docs/flex-wrap">
|
||||
Wrapping behaviour when child nodes don't fit into a single line
|
||||
</InfoText>
|
||||
</h2>
|
||||
<EditValue
|
||||
disabled={disabled}
|
||||
property="flexWrap"
|
||||
value={node ? node.flexWrap : undefined}
|
||||
onChange={this.props.onChangeLayout}
|
||||
/>
|
||||
</TabPane>
|
||||
<TabPane tab="Alignment" key="2">
|
||||
<h2>
|
||||
Justify Content
|
||||
<InfoText doclink="/docs/justify-content">
|
||||
Aligns child nodes along the main-axis
|
||||
</InfoText>
|
||||
</h2>
|
||||
<EditValue
|
||||
disabled={disabled}
|
||||
property="justifyContent"
|
||||
value={node ? node.justifyContent : undefined}
|
||||
onChange={this.props.onChangeLayout}
|
||||
/>
|
||||
|
||||
<h2>
|
||||
Align Items
|
||||
<InfoText doclink="/docs/align-items">
|
||||
Aligns child nodes along the cross-axis
|
||||
</InfoText>
|
||||
</h2>
|
||||
<EditValue
|
||||
disabled={disabled}
|
||||
property="alignItems"
|
||||
value={node ? node.alignItems : undefined}
|
||||
onChange={this.props.onChangeLayout}
|
||||
/>
|
||||
|
||||
<h2>
|
||||
Align Self
|
||||
<InfoText doclink="/docs/align-items">
|
||||
Override align items of parent
|
||||
</InfoText>
|
||||
</h2>
|
||||
<EditValue
|
||||
disabled={disabled || selectedNodeIsRoot}
|
||||
property="alignSelf"
|
||||
value={node ? node.alignSelf : undefined}
|
||||
onChange={this.props.onChangeLayout}
|
||||
/>
|
||||
|
||||
<h2>
|
||||
Align Content
|
||||
<InfoText doclink="/docs/align-content">
|
||||
Alignment of lines along the cross-axis when wrapping
|
||||
</InfoText>
|
||||
</h2>
|
||||
<EditValue
|
||||
disabled={disabled}
|
||||
property="alignContent"
|
||||
value={node ? node.alignContent : undefined}
|
||||
onChange={this.props.onChangeLayout}
|
||||
/>
|
||||
</TabPane>
|
||||
<TabPane tab="Layout" key="3" className="ant-tabs-tabpane">
|
||||
<h2>
|
||||
Width × Height
|
||||
<InfoText doclink="/docs/width-height">
|
||||
Dimensions of the node
|
||||
</InfoText>
|
||||
</h2>
|
||||
<Row gutter={15}>
|
||||
<Col span={12}>
|
||||
<EditValue
|
||||
type="text"
|
||||
placeholder="auto"
|
||||
property="width"
|
||||
disabled={disabled}
|
||||
value={node ? node.width : undefined}
|
||||
onChange={this.props.onChangeLayout}
|
||||
/>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<EditValue
|
||||
type="text"
|
||||
placeholder="auto"
|
||||
property="height"
|
||||
disabled={disabled}
|
||||
value={node ? node.height : undefined}
|
||||
onChange={this.props.onChangeLayout}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
<h2>
|
||||
Max-Width × Max-Height
|
||||
<InfoText doclink="/docs/min-max">
|
||||
Maximum dimensions of the node
|
||||
</InfoText>
|
||||
</h2>
|
||||
<Row gutter={15}>
|
||||
<Col span={12}>
|
||||
<EditValue
|
||||
type="text"
|
||||
placeholder="none"
|
||||
property="maxWidth"
|
||||
disabled={disabled}
|
||||
value={node ? node.maxWidth : undefined}
|
||||
onChange={this.props.onChangeLayout}
|
||||
/>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<EditValue
|
||||
type="text"
|
||||
placeholder="none"
|
||||
property="maxHeight"
|
||||
disabled={disabled}
|
||||
value={node ? node.maxHeight : undefined}
|
||||
onChange={this.props.onChangeLayout}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
<h2>
|
||||
Min-Width × Min-Height
|
||||
<InfoText doclink="/docs/min-max">
|
||||
Minimum dimensions of the node
|
||||
</InfoText>
|
||||
</h2>
|
||||
<Row gutter={15}>
|
||||
<Col span={12}>
|
||||
<EditValue
|
||||
type="text"
|
||||
placeholder="0"
|
||||
property="minWidth"
|
||||
disabled={disabled}
|
||||
value={node ? node.minWidth : undefined}
|
||||
onChange={this.props.onChangeLayout}
|
||||
/>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<EditValue
|
||||
type="text"
|
||||
placeholder="0"
|
||||
property="minHeight"
|
||||
disabled={disabled}
|
||||
value={node ? node.minHeight : undefined}
|
||||
onChange={this.props.onChangeLayout}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<h2>
|
||||
Aspect Ratio
|
||||
<InfoText doclink="/docs/aspect-ratio">
|
||||
Width/Height aspect ratio of node
|
||||
</InfoText>
|
||||
</h2>
|
||||
<EditValue
|
||||
type="text"
|
||||
placeholder="auto"
|
||||
property="aspectRatio"
|
||||
disabled={disabled}
|
||||
value={node ? node.aspectRatio : undefined}
|
||||
onChange={this.props.onChangeLayout}
|
||||
/>
|
||||
|
||||
{['padding', 'border', 'margin'].map(property => (
|
||||
<EditValue
|
||||
property={property}
|
||||
key={property}
|
||||
value={node ? node[property] : undefined}
|
||||
onChange={this.props.onChangeLayout}
|
||||
disabled={property === 'margin' && selectedNodeIsRoot}
|
||||
/>
|
||||
))}
|
||||
<h2>
|
||||
Position Type
|
||||
<InfoText doclink="/docs/absolute-relative-layout">
|
||||
Relative position offsets the node from it's calculated
|
||||
position. Absolute position removes the node from the flexbox
|
||||
flow and positions it at the given position.
|
||||
</InfoText>
|
||||
</h2>
|
||||
|
||||
<EditValue
|
||||
disabled={disabled || selectedNodeIsRoot}
|
||||
property="positionType"
|
||||
value={node ? node.positionType : undefined}
|
||||
onChange={this.props.onChangeLayout}
|
||||
/>
|
||||
<EditValue
|
||||
disabled={selectedNodeIsRoot}
|
||||
property="position"
|
||||
value={node ? node.position : undefined}
|
||||
onChange={this.props.onChangeLayout}
|
||||
/>
|
||||
</TabPane>
|
||||
</Tabs>
|
||||
|
||||
<Row gutter={15} className="EditorButtons">
|
||||
<Col span={12}>
|
||||
<Button
|
||||
icon="plus-circle-o"
|
||||
disabled={!Boolean(this.props.onAdd)}
|
||||
onClick={this.props.onAdd}
|
||||
type="primary">
|
||||
add child node
|
||||
</Button>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Button
|
||||
icon="close-circle-o"
|
||||
disabled={!Boolean(this.props.onRemove)}
|
||||
onClick={this.props.onRemove}
|
||||
type="danger">
|
||||
remove node
|
||||
</Button>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
@@ -1,22 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
.InfoText {
|
||||
max-width: 230px;
|
||||
line-height: 130%;
|
||||
}
|
||||
|
||||
.InfoText .docs-link {
|
||||
margin-top: 0px;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.InfoTextIcon {
|
||||
margin-left: 5px;
|
||||
opacity: 0.5;
|
||||
}
|
@@ -1,38 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import {Popover, Icon} from 'antd';
|
||||
import Link from 'gatsby-link';
|
||||
import './InfoText.css';
|
||||
|
||||
type Props = {
|
||||
children: any,
|
||||
doclink: string,
|
||||
};
|
||||
|
||||
export default class InfoText extends Component<Props> {
|
||||
render() {
|
||||
return (
|
||||
<Popover
|
||||
content={
|
||||
<div className="InfoText">
|
||||
<p>{this.props.children}</p>
|
||||
<Link className="docs-link" to={this.props.doclink}>
|
||||
DOCUMENTATION
|
||||
</Link>
|
||||
</div>
|
||||
}
|
||||
trigger="hover">
|
||||
<Icon className="InfoTextIcon" type="info-circle-o" />
|
||||
</Popover>
|
||||
);
|
||||
}
|
||||
}
|
@@ -1,89 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
import {Record, List} from 'immutable';
|
||||
import type {RecordOf} from 'immutable';
|
||||
import PositionRecord from './PositionRecord';
|
||||
import type {PositionRecordT} from './PositionRecord';
|
||||
import yoga from 'yoga-layout/dist/entry-browser';
|
||||
|
||||
import type {
|
||||
Yoga$Align,
|
||||
Yoga$Justify,
|
||||
Yoga$FlexDirection,
|
||||
Yoga$Wrap,
|
||||
Yoga$PositionType,
|
||||
} from 'yoga-layout';
|
||||
|
||||
export type LayoutRecordT = RecordOf<{
|
||||
width?: ?number,
|
||||
height?: ?number,
|
||||
minWidth?: ?number,
|
||||
minHeight?: ?number,
|
||||
maxWidth?: ?number,
|
||||
maxHeight?: ?number,
|
||||
justifyContent?: Yoga$Justify,
|
||||
padding: PositionRecordT,
|
||||
border: PositionRecordT,
|
||||
margin: PositionRecordT,
|
||||
position: PositionRecordT,
|
||||
positionType: Yoga$PositionType,
|
||||
alignItems?: Yoga$Align,
|
||||
alignSelf?: Yoga$Align,
|
||||
alignContent?: Yoga$Align,
|
||||
flexDirection?: Yoga$FlexDirection,
|
||||
flexBasis?: number | 'auto',
|
||||
flexGrow?: number,
|
||||
flexShrink?: number,
|
||||
padding?: number,
|
||||
flexWrap?: Yoga$Wrap,
|
||||
aspectRatio?: number,
|
||||
children?: List<LayoutRecordT>,
|
||||
minWidth?: number,
|
||||
maxWidth?: number,
|
||||
minHeight?: number,
|
||||
maxHeight?: number,
|
||||
}>;
|
||||
|
||||
const r: LayoutRecordT = Record({
|
||||
width: 'auto',
|
||||
height: 'auto',
|
||||
minWidth: 0,
|
||||
minHeight: 0,
|
||||
maxWidth: 'none',
|
||||
maxHeight: 'none',
|
||||
justifyContent: yoga.JUSTIFY_FLEX_START,
|
||||
alignItems: yoga.ALIGN_STRETCH,
|
||||
alignSelf: yoga.ALIGN_AUTO,
|
||||
alignContent: yoga.ALIGN_STRETCH,
|
||||
flexDirection: yoga.FLEX_DIRECTION_ROW,
|
||||
padding: PositionRecord(),
|
||||
margin: PositionRecord(),
|
||||
border: PositionRecord(),
|
||||
position: PositionRecord({
|
||||
left: NaN,
|
||||
top: NaN,
|
||||
right: NaN,
|
||||
bottom: NaN,
|
||||
}),
|
||||
positionType: yoga.POSITION_TYPE_RELATIVE,
|
||||
flexWrap: yoga.WRAP_NO_WRAP,
|
||||
flexBasis: 'auto',
|
||||
flexGrow: 0,
|
||||
flexShrink: 1,
|
||||
children: List(),
|
||||
aspectRatio: 'auto',
|
||||
minWidth: NaN,
|
||||
maxWidth: NaN,
|
||||
minHeight: NaN,
|
||||
maxHeight: NaN,
|
||||
});
|
||||
|
||||
export default r;
|
@@ -1,16 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
.PositionGuide {
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 10px;
|
||||
user-select: none;
|
||||
}
|
@@ -1,146 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import PositionRecord from './PositionRecord';
|
||||
import type {PositionRecordT} from './PositionRecord';
|
||||
import './PositionGuide.css';
|
||||
|
||||
type Props = {
|
||||
inset?: boolean,
|
||||
reverse?: boolean,
|
||||
position: PositionRecordT,
|
||||
offset: PositionRecordT,
|
||||
color: string,
|
||||
};
|
||||
|
||||
export default class PositionGuide extends Component<Props> {
|
||||
static defaultProps = {
|
||||
offset: PositionRecord({}),
|
||||
};
|
||||
|
||||
render() {
|
||||
const {position, offset, inset, color, reverse} = this.props;
|
||||
let {top, left, right, bottom} = position;
|
||||
let {top: oTop, left: oLeft, right: oRight, bottom: oBottom} = offset;
|
||||
|
||||
if (reverse) {
|
||||
let temp1 = left;
|
||||
left = right;
|
||||
right = temp1;
|
||||
temp1 = oLeft;
|
||||
oLeft = oRight;
|
||||
oRight = temp1;
|
||||
}
|
||||
|
||||
if (!top) {
|
||||
top = 0;
|
||||
}
|
||||
if (!left) {
|
||||
left = 0;
|
||||
}
|
||||
if (!right) {
|
||||
right = 0;
|
||||
}
|
||||
if (!bottom) {
|
||||
bottom = 0;
|
||||
}
|
||||
if (!oTop) {
|
||||
oTop = 0;
|
||||
}
|
||||
if (!oLeft) {
|
||||
oLeft = 0;
|
||||
}
|
||||
if (!oRight) {
|
||||
oRight = 0;
|
||||
}
|
||||
if (!oBottom) {
|
||||
oBottom = 0;
|
||||
}
|
||||
|
||||
if (!inset) {
|
||||
if (top < 0) {
|
||||
bottom -= top;
|
||||
top = 0;
|
||||
}
|
||||
if (bottom < 0) {
|
||||
top -= bottom;
|
||||
bottom = 0;
|
||||
}
|
||||
if (left < 0) {
|
||||
right -= left;
|
||||
left = 0;
|
||||
}
|
||||
if (right < 0) {
|
||||
left -= right;
|
||||
right = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
top !== 0 ? (
|
||||
<div
|
||||
key="top"
|
||||
className="PositionGuide"
|
||||
style={{
|
||||
backgroundColor: color,
|
||||
height: top,
|
||||
top: inset ? oTop : -top - oTop,
|
||||
left: inset ? left + oLeft : -left - oLeft,
|
||||
right: inset ? right + oRight : -right - oRight,
|
||||
}}>
|
||||
{top}
|
||||
</div>
|
||||
) : null,
|
||||
left !== 0 ? (
|
||||
<div
|
||||
key="left"
|
||||
className="PositionGuide"
|
||||
style={{
|
||||
backgroundColor: color,
|
||||
width: left,
|
||||
top: inset ? oTop : -oTop,
|
||||
bottom: inset ? oBottom : -oBottom,
|
||||
left: inset ? oLeft : -left - oLeft,
|
||||
}}>
|
||||
{left}
|
||||
</div>
|
||||
) : null,
|
||||
right !== 0 ? (
|
||||
<div
|
||||
key="right"
|
||||
className="PositionGuide"
|
||||
style={{
|
||||
backgroundColor: color,
|
||||
width: right,
|
||||
top: inset ? oTop : -oTop,
|
||||
bottom: inset ? oBottom : -oBottom,
|
||||
right: inset ? oRight : -right - oRight,
|
||||
}}>
|
||||
{right}
|
||||
</div>
|
||||
) : null,
|
||||
bottom !== 0 ? (
|
||||
<div
|
||||
key="bottom"
|
||||
className="PositionGuide"
|
||||
style={{
|
||||
backgroundColor: color,
|
||||
height: bottom,
|
||||
bottom: inset ? oBottom : -bottom - oBottom,
|
||||
left: inset ? left + oLeft : -left - oLeft,
|
||||
right: inset ? right + oRight : -right - oRight,
|
||||
}}>
|
||||
{bottom}
|
||||
</div>
|
||||
) : null,
|
||||
];
|
||||
}
|
||||
}
|
@@ -1,28 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
import {Record} from 'immutable';
|
||||
import type {RecordOf} from 'immutable';
|
||||
|
||||
export type PositionRecordT = RecordOf<{
|
||||
top: string | number,
|
||||
right: string | number,
|
||||
bottom: string | number,
|
||||
left: string | number,
|
||||
}>;
|
||||
|
||||
const r: PositionRecordT = Record({
|
||||
top: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
});
|
||||
|
||||
export default r;
|
@@ -1,22 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
.Sidebar {
|
||||
position: absolute;
|
||||
z-index: 3;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 350px;
|
||||
background: white;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 25px;
|
||||
max-height: calc(100% - 50px);
|
||||
border-radius: 6px;
|
||||
bottom: auto;
|
||||
box-shadow: 3px 3px 15px rgba(0, 0, 0, 0.15);
|
||||
}
|
@@ -1,27 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import './Sidebar.css';
|
||||
|
||||
type Props = {
|
||||
width?: number,
|
||||
children: any,
|
||||
};
|
||||
|
||||
export default class Sidebar extends Component<Props> {
|
||||
render() {
|
||||
return (
|
||||
<div className="Sidebar" style={{width: this.props.width}}>
|
||||
{this.props.children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
@@ -1,9 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
.URLShortener {
|
||||
}
|
@@ -1,86 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import {Tooltip, notification, Button, Input} from 'antd';
|
||||
import './URLShortener.css';
|
||||
|
||||
type State = {
|
||||
shortURL: ?string,
|
||||
loading: boolean,
|
||||
};
|
||||
|
||||
export default class URLShortener extends Component<{}, State> {
|
||||
_ref: ?HTMLElement = null;
|
||||
|
||||
state = {
|
||||
loading: false,
|
||||
shortURL: null,
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
window.addEventListener('popstate', this.onHashChange);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
window.removeEventListener('popstate', this.onHashChange);
|
||||
}
|
||||
|
||||
onHashChange = () => {
|
||||
this.setState({shortURL: null});
|
||||
};
|
||||
|
||||
onClick = () => {
|
||||
this.setState(
|
||||
{
|
||||
loading: true,
|
||||
},
|
||||
() => {
|
||||
if (window.ga) {
|
||||
window.ga('send', {
|
||||
hitType: 'event',
|
||||
eventCategory: 'URLShortener',
|
||||
eventAction: 'created',
|
||||
});
|
||||
}
|
||||
|
||||
fetch(
|
||||
`https://cors-anywhere.herokuapp.com/tinyurl.com/api-create.php?url=${window.location.href}`,
|
||||
)
|
||||
.then(res => res.text())
|
||||
.then(shortURL => this.setState({shortURL, loading: false}))
|
||||
.catch(() => this.setState({shortURL: null, loading: false}));
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
render() {
|
||||
return this.state.shortURL ? (
|
||||
<Input
|
||||
value={this.state.shortURL}
|
||||
autoFocus
|
||||
ref={ref => {
|
||||
if (ref) {
|
||||
ref.input.select();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<Button
|
||||
className="URLShortener"
|
||||
onClick={this.onClick}
|
||||
icon="share-alt"
|
||||
disabled={this.state.loading}
|
||||
type="primary">
|
||||
Share URL
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
}
|
@@ -1,25 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
.YogaEnumSelect {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.YogaEnumSelect.ant-radio-group .ant-radio-button-wrapper {
|
||||
flex-grow: 1;
|
||||
flex-basis: 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.YogaEnumSelect .ant-btn {
|
||||
flex-grow: 1;
|
||||
flex-basis: 0;
|
||||
}
|
||||
|
||||
.YogaEnumSelect .ant-radio-button-wrapper {
|
||||
white-space: nowrap;
|
||||
}
|
@@ -1,104 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import yoga from 'yoga-layout/dist/entry-browser';
|
||||
import {Radio, Menu, Dropdown, Button, Icon} from 'antd';
|
||||
import './YogaEnumSelect.css';
|
||||
const RadioButton = Radio.Button;
|
||||
const RadioGroup = Radio.Group;
|
||||
|
||||
const PROPERTY_LOOKUP = {
|
||||
flexDirection: 'FLEX_DIRECTION',
|
||||
direction: 'DIRECTION',
|
||||
justifyContent: 'JUSTIFY',
|
||||
alignSelf: 'ALIGN',
|
||||
alignContent: 'ALIGN',
|
||||
alignItems: 'ALIGN',
|
||||
positionType: 'POSITION_TYPE',
|
||||
flexWrap: 'WRAP',
|
||||
};
|
||||
|
||||
type Property = $Keys<typeof PROPERTY_LOOKUP>;
|
||||
|
||||
type Props = {
|
||||
property: Property,
|
||||
disabled?: boolean,
|
||||
value: string | number,
|
||||
onChange: (property: Property, value: number) => void,
|
||||
};
|
||||
|
||||
export default class YogaEnumSelect extends Component<Props> {
|
||||
static availableProperties = Object.keys(PROPERTY_LOOKUP);
|
||||
|
||||
values: Array<{key: string, value: number}>;
|
||||
|
||||
constructor({property}: Props) {
|
||||
super();
|
||||
property = PROPERTY_LOOKUP[property];
|
||||
// $FlowFixMe
|
||||
this.values = Object.keys(yoga)
|
||||
.map(key => ({key, value: yoga[key]}))
|
||||
.filter(
|
||||
({key}) => key.startsWith(property) && key !== `${property}_COUNT`,
|
||||
);
|
||||
}
|
||||
|
||||
handleMenuClick = ({key}: {key: string}) => {
|
||||
this.props.onChange(this.props.property, yoga[key]);
|
||||
};
|
||||
|
||||
getTitle = (property: string, key: string): string => {
|
||||
const replacer = new RegExp(`^${property}_`);
|
||||
return key.replace(replacer, '').replace('_', ' ').toLowerCase();
|
||||
};
|
||||
|
||||
render() {
|
||||
let {property, ...props} = this.props;
|
||||
property = PROPERTY_LOOKUP[property];
|
||||
const selected = this.values.find(
|
||||
({key, value}) => value === this.props.value,
|
||||
);
|
||||
|
||||
return this.values.length > 3 ? (
|
||||
<div className="YogaEnumSelect">
|
||||
<Dropdown
|
||||
trigger={['click']}
|
||||
disabled={props.disabled}
|
||||
overlay={
|
||||
<Menu onClick={this.handleMenuClick}>
|
||||
{this.values.map(({key, value}) => (
|
||||
<Menu.Item key={key} value={value}>
|
||||
{this.getTitle(property, key)}
|
||||
</Menu.Item>
|
||||
))}
|
||||
</Menu>
|
||||
}>
|
||||
<Button>
|
||||
{selected ? this.getTitle(property, selected.key) : ''}
|
||||
<Icon type="down" />
|
||||
</Button>
|
||||
</Dropdown>
|
||||
</div>
|
||||
) : (
|
||||
<RadioGroup
|
||||
{...props}
|
||||
onChange={e => this.props.onChange(this.props.property, e.target.value)}
|
||||
defaultValue="a"
|
||||
className="YogaEnumSelect">
|
||||
{this.values.map(({key, value}) => (
|
||||
<RadioButton key={key} value={value}>
|
||||
{this.getTitle(property, key)}
|
||||
</RadioButton>
|
||||
))}
|
||||
</RadioGroup>
|
||||
);
|
||||
}
|
||||
}
|
@@ -1,57 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
.YogaNode {
|
||||
background: white;
|
||||
position: absolute;
|
||||
transform: scale(1);
|
||||
box-shadow: inset 0 0 0px 1px rgba(48, 56, 69, 0.2);
|
||||
transition: 0.2s all, 0s outline, 0s box-shadow;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.YogaNode.hover {
|
||||
background-color: #F0FFF9;
|
||||
}
|
||||
|
||||
.YogaNode .YogaNode {
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
|
||||
.YogaNode .YogaNode.hover{
|
||||
background: rgba(240, 255, 249, 0.7);
|
||||
}
|
||||
|
||||
.YogaNode:focus {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.YogaNode.focused {
|
||||
box-shadow: 0 0 0 2px #68CFBB, 0 0 15px rgba(0, 0, 0, 0.2),
|
||||
inset 0 0 0px 1px rgba(255, 255, 255, 0.2);
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.YogaNode.invisible {
|
||||
transform: scale(0);
|
||||
}
|
||||
|
||||
.YogaNode .label {
|
||||
user-select: none;
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 20px;
|
||||
font-weight: 300;
|
||||
letter-spacing: 1px;
|
||||
}
|
@@ -1,296 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import yoga, {Node} from 'yoga-layout/dist/entry-browser';
|
||||
import PositionGuide from './PositionGuide';
|
||||
import PositionRecord from './PositionRecord';
|
||||
import LayoutRecord from './LayoutRecord';
|
||||
import type {LayoutRecordT} from './LayoutRecord';
|
||||
import type {Yoga$Direction, Yoga$Node} from 'yoga-layout';
|
||||
|
||||
import './YogaNode.css';
|
||||
|
||||
type ComputedLayout = {|
|
||||
left: number,
|
||||
top: number,
|
||||
width: number,
|
||||
height: number,
|
||||
children: Array<ComputedLayout>,
|
||||
node: Yoga$Node,
|
||||
|};
|
||||
|
||||
type Props = {|
|
||||
layoutDefinition: LayoutRecordT,
|
||||
className?: string,
|
||||
computedLayout?: ComputedLayout,
|
||||
path: Array<number>,
|
||||
selectedNodePath?: ?Array<number>,
|
||||
direction?: Yoga$Direction,
|
||||
label?: string,
|
||||
showGuides: boolean,
|
||||
onClick?: (path: Array<number>) => void,
|
||||
onDoubleClick?: (path: Array<number>) => void,
|
||||
|};
|
||||
|
||||
type State = {
|
||||
visible?: boolean,
|
||||
hovered: boolean,
|
||||
};
|
||||
|
||||
export default class YogaNode extends Component<Props, State> {
|
||||
node: Yoga$Node;
|
||||
|
||||
static defaultProps = {
|
||||
path: [],
|
||||
label: 'root',
|
||||
showGuides: true,
|
||||
};
|
||||
|
||||
state = {
|
||||
hovered: false,
|
||||
};
|
||||
computedLayout: ?ComputedLayout;
|
||||
rootNode: ?Yoga$Node;
|
||||
|
||||
constructor(props: Props) {
|
||||
super();
|
||||
if (!props.computedLayout) {
|
||||
// is root node
|
||||
this.calculateLayout(props);
|
||||
this.state = {
|
||||
visible: !Boolean(props.computedLayout),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
setTimeout(() => this.setState({visible: true}), 200);
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps: Props) {
|
||||
if (
|
||||
!nextProps.computedLayout &&
|
||||
(!this.props.layoutDefinition.equals(nextProps.layoutDefinition) ||
|
||||
this.props.direction !== nextProps.direction)
|
||||
) {
|
||||
// is root node and the layout definition or settings changed
|
||||
this.calculateLayout(nextProps);
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.rootNode) {
|
||||
this.rootNode.freeRecursive();
|
||||
}
|
||||
}
|
||||
|
||||
onMouseMove = e => {
|
||||
this.setState({hovered: e.target === this._ref});
|
||||
};
|
||||
|
||||
calculateLayout(props: Props) {
|
||||
const root = this.createYogaNodes(props.layoutDefinition);
|
||||
root.calculateLayout(
|
||||
props.layoutDefinition.width,
|
||||
props.layoutDefinition.height,
|
||||
props.direction,
|
||||
);
|
||||
this.computedLayout = this.getComputedLayout(root);
|
||||
this.rootNode = root;
|
||||
}
|
||||
|
||||
createYogaNodes = (layoutDefinition: LayoutRecordT): Yoga$Node => {
|
||||
const root = Node.create();
|
||||
|
||||
const defaultLayout = LayoutRecord({});
|
||||
[
|
||||
'width',
|
||||
'height',
|
||||
'minWidth',
|
||||
'maxWidth',
|
||||
'minHeight',
|
||||
'maxHeight',
|
||||
'justifyContent',
|
||||
'alignItems',
|
||||
'alignSelf',
|
||||
'alignContent',
|
||||
'flexGrow',
|
||||
'flexShrink',
|
||||
'positionType',
|
||||
'aspectRatio',
|
||||
'flexWrap',
|
||||
'flexDirection',
|
||||
].forEach(key => {
|
||||
try {
|
||||
const value =
|
||||
layoutDefinition[key] === ''
|
||||
? defaultLayout[key]
|
||||
: layoutDefinition[key];
|
||||
root[`set${key[0].toUpperCase()}${key.substr(1)}`](value);
|
||||
} catch (e) {}
|
||||
});
|
||||
|
||||
['padding', 'margin', 'position', 'border'].forEach(key => {
|
||||
['top', 'right', 'bottom', 'left'].forEach(direction => {
|
||||
try {
|
||||
root[`set${key[0].toUpperCase()}${key.substr(1)}`](
|
||||
yoga[`EDGE_${direction.toUpperCase()}`],
|
||||
layoutDefinition[key][direction],
|
||||
);
|
||||
} catch (e) {}
|
||||
});
|
||||
});
|
||||
|
||||
root.setDisplay(yoga.DISPLAY_FLEX);
|
||||
|
||||
(layoutDefinition.children || [])
|
||||
.map(this.createYogaNodes)
|
||||
.forEach((node, i) => {
|
||||
root.insertChild(node, i);
|
||||
});
|
||||
return root;
|
||||
};
|
||||
|
||||
getComputedLayout = (node: Yoga$Node): ComputedLayout => {
|
||||
return {
|
||||
...node.getComputedLayout(),
|
||||
node,
|
||||
children: Array.apply(null, Array(node.getChildCount())).map((_, i) =>
|
||||
this.getComputedLayout(node.getChild(i)),
|
||||
),
|
||||
};
|
||||
};
|
||||
|
||||
onClick = (e: SyntheticMouseEvent<>) => {
|
||||
const {onClick} = this.props;
|
||||
if (onClick) {
|
||||
e.stopPropagation();
|
||||
onClick(this.props.path);
|
||||
}
|
||||
};
|
||||
|
||||
onDoubleClick = (e: SyntheticMouseEvent<>) => {
|
||||
const {onDoubleClick} = this.props;
|
||||
if (onDoubleClick) {
|
||||
e.stopPropagation();
|
||||
onDoubleClick(this.props.path);
|
||||
}
|
||||
};
|
||||
|
||||
onMouseLeave = (e: SyntheticMouseEvent<>) => this.setState({hovered: false});
|
||||
|
||||
showPositionGuides({node}: ComputedLayout) {
|
||||
const padding = PositionRecord({
|
||||
top: node.getComputedPadding(yoga.EDGE_TOP),
|
||||
left: node.getComputedPadding(yoga.EDGE_LEFT),
|
||||
right: node.getComputedPadding(yoga.EDGE_RIGHT),
|
||||
bottom: node.getComputedPadding(yoga.EDGE_BOTTOM),
|
||||
});
|
||||
const border = PositionRecord({
|
||||
top: node.getComputedBorder(yoga.EDGE_TOP),
|
||||
left: node.getComputedBorder(yoga.EDGE_LEFT),
|
||||
right: node.getComputedBorder(yoga.EDGE_RIGHT),
|
||||
bottom: node.getComputedBorder(yoga.EDGE_BOTTOM),
|
||||
});
|
||||
const margin = PositionRecord({
|
||||
top: node.getComputedMargin(yoga.EDGE_TOP),
|
||||
left: node.getComputedMargin(yoga.EDGE_LEFT),
|
||||
right: node.getComputedMargin(yoga.EDGE_RIGHT),
|
||||
bottom: node.getComputedMargin(yoga.EDGE_BOTTOM),
|
||||
});
|
||||
const position = PositionRecord({
|
||||
top: node.getPosition(yoga.EDGE_TOP).value,
|
||||
left: node.getPosition(yoga.EDGE_LEFT).value,
|
||||
right: node.getPosition(yoga.EDGE_RIGHT).value,
|
||||
bottom: node.getPosition(yoga.EDGE_BOTTOM).value,
|
||||
});
|
||||
|
||||
return [
|
||||
<PositionGuide
|
||||
key="border"
|
||||
inset
|
||||
position={border}
|
||||
color="rgba(251, 170, 51, 0.15)"
|
||||
reverse={node.getFlexWrap() === yoga.WRAP_WRAP_REVERSE}
|
||||
/>,
|
||||
<PositionGuide
|
||||
key="padding"
|
||||
inset
|
||||
offset={border}
|
||||
position={padding}
|
||||
color="rgba(123, 179, 41, 0.1)"
|
||||
reverse={node.getFlexWrap() === yoga.WRAP_WRAP_REVERSE}
|
||||
/>,
|
||||
<PositionGuide
|
||||
key="margin"
|
||||
position={margin}
|
||||
color="rgba(214, 43, 28, 0.1)"
|
||||
/>,
|
||||
<PositionGuide
|
||||
key="position"
|
||||
offset={margin}
|
||||
position={position}
|
||||
color="rgba(115, 51, 205, 0.1)"
|
||||
/>,
|
||||
];
|
||||
}
|
||||
|
||||
render() {
|
||||
const {layoutDefinition, className, path, selectedNodePath, label} =
|
||||
this.props;
|
||||
|
||||
// $FlowFixMe
|
||||
const computedLayout: ComputedLayout =
|
||||
this.props.computedLayout || this.computedLayout;
|
||||
const {left, top, width, height, children} = computedLayout;
|
||||
|
||||
const isFocused = selectedNodePath && selectedNodePath.length === 0;
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`YogaNode ${isFocused ? 'focused' : ''} ${className || ''} ${
|
||||
this.state.visible ? '' : 'invisible'
|
||||
} ${this.state.hovered ? 'hover' : ''}`}
|
||||
style={path.length == 0 ? {width, height} : {left, top, width, height}}
|
||||
onDoubleClick={this.onDoubleClick}
|
||||
onMouseMove={this.onMouseMove}
|
||||
onMouseLeave={this.onMouseLeave}
|
||||
ref={ref => {
|
||||
this._ref = ref;
|
||||
}}
|
||||
onClick={this.onClick}>
|
||||
{label && <div className="label">{label}</div>}
|
||||
{isFocused &&
|
||||
this.props.showGuides &&
|
||||
this.showPositionGuides(computedLayout)}
|
||||
{(children || []).map((child: ComputedLayout, i) => (
|
||||
<YogaNode
|
||||
key={i}
|
||||
computedLayout={child}
|
||||
label={String(i + 1)}
|
||||
layoutDefinition={layoutDefinition.children.get(i)}
|
||||
selectedNodePath={
|
||||
selectedNodePath &&
|
||||
selectedNodePath.length > 0 &&
|
||||
selectedNodePath[0] === i
|
||||
? selectedNodePath.slice(1)
|
||||
: null
|
||||
}
|
||||
path={path.concat(i)}
|
||||
onClick={this.props.onClick}
|
||||
onDoubleClick={this.props.onDoubleClick}
|
||||
showGuides={this.props.showGuides}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
@@ -1,30 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
.YogaPositionEditor {
|
||||
text-align: center;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
width: 60%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.YogaPositionEditor input {
|
||||
width: 55px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.YogaPositionEditorRow {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
color: #444950;
|
||||
}
|
@@ -1,73 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import {Input} from 'antd';
|
||||
import PositionRecord from './PositionRecord';
|
||||
import type {PositionRecordT} from './PositionRecord';
|
||||
import './YogaPositionEditor.css';
|
||||
|
||||
type Property = 'position' | 'margin' | 'padding' | 'border';
|
||||
|
||||
type Props = {
|
||||
value: PositionRecordT,
|
||||
property: Property,
|
||||
disabled?: boolean,
|
||||
onChange: (property: Property, value: PositionRecordT) => void,
|
||||
};
|
||||
|
||||
export default class YogaPositionEditor extends Component<Props> {
|
||||
static availableProperties = ['position', 'margin', 'padding', 'border'];
|
||||
|
||||
static defaultProps = {
|
||||
value: PositionRecord(),
|
||||
};
|
||||
|
||||
render() {
|
||||
const {onChange, value, property, disabled} = this.props;
|
||||
return (
|
||||
<div className="YogaPositionEditor">
|
||||
<Input
|
||||
type="text"
|
||||
value={Number.isNaN(value.top) ? '' : value.top}
|
||||
disabled={disabled}
|
||||
onChange={e => onChange(property, value.set('top', e.target.value))}
|
||||
/>
|
||||
<div className="YogaPositionEditorRow">
|
||||
<Input
|
||||
type="text"
|
||||
value={Number.isNaN(value.left) ? '' : value.left}
|
||||
disabled={disabled}
|
||||
onChange={e =>
|
||||
onChange(property, value.set('left', e.target.value))
|
||||
}
|
||||
/>
|
||||
{property.toUpperCase()}
|
||||
<Input
|
||||
type="text"
|
||||
value={Number.isNaN(value.right) ? '' : value.right}
|
||||
disabled={disabled}
|
||||
onChange={e =>
|
||||
onChange(property, value.set('right', e.target.value))
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<Input
|
||||
type="text"
|
||||
value={Number.isNaN(value.bottom) ? '' : value.bottom}
|
||||
disabled={disabled}
|
||||
onChange={e =>
|
||||
onChange(property, value.set('bottom', e.target.value))
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
@@ -1,74 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
.PlaygroundContainer {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-grow: 1;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.Playground {
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
background: linear-gradient(-90deg, rgba(0, 0, 0, 0.02) 1px, transparent 1px),
|
||||
linear-gradient(rgba(0, 0, 0, 0.02) 1px, transparent 1px),
|
||||
linear-gradient(-90deg, rgba(0, 0, 0, 0.03) 1px, transparent 1px),
|
||||
linear-gradient(rgba(0, 0, 0, 0.03) 1px, transparent 1px),
|
||||
linear-gradient(
|
||||
transparent 4px,
|
||||
#f5f5f5 4px,
|
||||
#f5f5f5 97px,
|
||||
transparent 97px
|
||||
),
|
||||
linear-gradient(-90deg, #e5e5e5 1px, transparent 1px),
|
||||
linear-gradient(
|
||||
-90deg,
|
||||
transparent 4px,
|
||||
#f5f5f5 4px,
|
||||
#f5f5f5 97px,
|
||||
transparent 97px
|
||||
),
|
||||
linear-gradient(#e5e5e5 1px, transparent 1px), #f5f5f5;
|
||||
background-size: 10px 10px, 10px 10px, 100px 100px, 100px 100px, 100px 100px,
|
||||
100px 100px, 100px 100px, 100px 100px;
|
||||
}
|
||||
|
||||
.Playground > .YogaNode {
|
||||
margin: auto;
|
||||
position: static;
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.Playground.standalone > .YogaNode {
|
||||
transform: translateX(-175px);
|
||||
}
|
||||
|
||||
.Playground .Actions {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.Playground .Actions .ant-btn {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.Playground .NoContent {
|
||||
border-top: 1px solid #E8E8E8;
|
||||
font-size: 18px;
|
||||
padding: 30px 50px;
|
||||
text-align: center;
|
||||
color: #D9D9D9;
|
||||
font-weight: 300;
|
||||
line-height: 130%;
|
||||
}
|
||||
|
||||
.ant-modal-content {
|
||||
overflow: hidden;
|
||||
}
|
@@ -1,322 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import yoga from 'yoga-layout/dist/entry-browser';
|
||||
import YogaNode from './YogaNode';
|
||||
import CodeGenerators from './CodeGenerators';
|
||||
import URLShortener from './URLShortener';
|
||||
import Editor from './Editor';
|
||||
import {List, setIn} from 'immutable';
|
||||
import PositionRecord from './PositionRecord';
|
||||
import LayoutRecord from './LayoutRecord';
|
||||
import Sidebar from './Sidebar';
|
||||
import {Row, Col, Button} from 'antd';
|
||||
import btoa from 'btoa';
|
||||
import type {LayoutRecordT} from './LayoutRecord';
|
||||
import type {Yoga$Direction} from 'yoga-layout';
|
||||
import './index.css';
|
||||
|
||||
type Props = {
|
||||
layoutDefinition: Object,
|
||||
direction: Yoga$Direction,
|
||||
maxDepth: number,
|
||||
maxChildren?: number,
|
||||
minChildren?: number,
|
||||
selectedNodePath?: Array<number>,
|
||||
showGuides: boolean,
|
||||
className?: string,
|
||||
height?: string | number,
|
||||
persist?: boolean,
|
||||
renderSidebar?: (layoutDefinition: LayoutRecordT, onChange: Function) => any,
|
||||
};
|
||||
|
||||
type State = {
|
||||
selectedNodePath: ?Array<number>,
|
||||
layoutDefinition: LayoutRecordT,
|
||||
direction: Yoga$Direction,
|
||||
};
|
||||
|
||||
function getPath(path: Array<number>): Array<mixed> {
|
||||
return path.reduce((acc, cv) => acc.concat('children', cv), []);
|
||||
}
|
||||
|
||||
export default class Playground extends Component<Props, State> {
|
||||
_containerRef: ?HTMLElement;
|
||||
|
||||
static defaultProps = {
|
||||
layoutDefinition: {
|
||||
width: 500,
|
||||
height: 500,
|
||||
children: [
|
||||
{width: 100, height: 100},
|
||||
{width: 100, height: 100},
|
||||
{width: 100, height: 100},
|
||||
],
|
||||
},
|
||||
direction: yoga.DIRECTION_LTR,
|
||||
maxDepth: 3,
|
||||
showGuides: true,
|
||||
persist: false,
|
||||
};
|
||||
|
||||
rehydrate = (node: Object): LayoutRecord => {
|
||||
let record = LayoutRecord(node);
|
||||
record = record.set('padding', PositionRecord(record.padding));
|
||||
record = record.set('border', PositionRecord(record.border));
|
||||
record = record.set('margin', PositionRecord(record.margin));
|
||||
record = record.set('position', PositionRecord(record.position));
|
||||
record = record.set('children', List(record.children.map(this.rehydrate)));
|
||||
return record;
|
||||
};
|
||||
|
||||
state = {
|
||||
selectedNodePath: this.props.selectedNodePath,
|
||||
layoutDefinition: this.rehydrate(this.props.layoutDefinition),
|
||||
direction: this.props.direction,
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
document.addEventListener('keydown', this.onKeyDown);
|
||||
|
||||
// rehydrate
|
||||
if (window.location.search && window.location.search.length > 1) {
|
||||
try {
|
||||
const restoredState = JSON.parse(
|
||||
atob(window.location.search.substr(1)),
|
||||
);
|
||||
this.setState({layoutDefinition: this.rehydrate(restoredState)});
|
||||
} catch (e) {
|
||||
window.history.replaceState(
|
||||
{},
|
||||
null,
|
||||
window.location.origin + window.location.pathname,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
document.removeEventListener('keydown', this.onKeyDown);
|
||||
}
|
||||
|
||||
onKeyDown = (e: KeyboardEvent) => {
|
||||
if (e.key === 'Escape') {
|
||||
this.hideSidePanes();
|
||||
}
|
||||
};
|
||||
|
||||
onMouseDown = (e: MouseEvent) => {
|
||||
if (e.target === this._containerRef) {
|
||||
this.hideSidePanes();
|
||||
}
|
||||
};
|
||||
|
||||
hideSidePanes() {
|
||||
if (!Boolean(this.props.renderSidebar)) {
|
||||
// only unselect if we don't have an external sidebar, otherwise the
|
||||
// sidebar may rely on a certain node to be selected
|
||||
this.setState({
|
||||
selectedNodePath: null,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
onChangeLayout = (key: string, value: any) => {
|
||||
const {selectedNodePath} = this.state;
|
||||
if (selectedNodePath) {
|
||||
this.modifyAtPath([...getPath(selectedNodePath), key], value);
|
||||
}
|
||||
};
|
||||
|
||||
onRemove = () => {
|
||||
const {selectedNodePath, layoutDefinition} = this.state;
|
||||
if (selectedNodePath) {
|
||||
const index = selectedNodePath.pop();
|
||||
const path = getPath(selectedNodePath).concat('children');
|
||||
const updatedChildren = layoutDefinition.getIn(path).delete(index);
|
||||
this.modifyAtPath(path, updatedChildren);
|
||||
this.setState({selectedNodePath: null});
|
||||
}
|
||||
};
|
||||
|
||||
onAdd = () => {
|
||||
const {selectedNodePath, layoutDefinition} = this.state;
|
||||
if (selectedNodePath) {
|
||||
const path = getPath(selectedNodePath).concat('children');
|
||||
const updatedChildren = layoutDefinition
|
||||
.getIn(path)
|
||||
.push(LayoutRecord({width: 100, height: 100}));
|
||||
this.modifyAtPath(path, updatedChildren);
|
||||
}
|
||||
};
|
||||
|
||||
modifyAtPath(
|
||||
path: Array<any>,
|
||||
value: any,
|
||||
selectedNodePath?: ?Array<number> = this.state.selectedNodePath,
|
||||
) {
|
||||
// $FlowFixMe
|
||||
const layoutDefinition = setIn(this.state.layoutDefinition, path, value);
|
||||
this.setState({
|
||||
layoutDefinition,
|
||||
selectedNodePath,
|
||||
});
|
||||
|
||||
if (this.props.persist) {
|
||||
window.history.replaceState(
|
||||
{},
|
||||
null,
|
||||
window.location.origin +
|
||||
window.location.pathname +
|
||||
'?' +
|
||||
this.getHash(layoutDefinition),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
getHash = (
|
||||
layoutDefinition: LayoutRecordT = this.state.layoutDefinition,
|
||||
): string =>
|
||||
btoa(JSON.stringify(this.removeUnchangedProperties(layoutDefinition)));
|
||||
|
||||
removeUnchangedProperties = (node: LayoutRecordT): Object => {
|
||||
const untouchedLayout = LayoutRecord({});
|
||||
const untouchedPosition = PositionRecord({});
|
||||
const result = {};
|
||||
if (!node.equals(untouchedLayout)) {
|
||||
Object.keys(node.toJS()).forEach(key => {
|
||||
if (key === 'children' && node.children.size > 0) {
|
||||
result.children = node.children
|
||||
.toJSON()
|
||||
.map(this.removeUnchangedProperties);
|
||||
} else if (
|
||||
node[key] instanceof PositionRecord &&
|
||||
!node[key].equals(untouchedPosition)
|
||||
) {
|
||||
result[key] = {};
|
||||
Object.keys(untouchedPosition.toJS()).forEach(position => {
|
||||
if (node[key][position] !== untouchedPosition[position]) {
|
||||
result[key][position] = node[key][position];
|
||||
}
|
||||
});
|
||||
} else if (node[key] !== untouchedLayout[key]) {
|
||||
result[key] = node[key];
|
||||
}
|
||||
});
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
getChildrenCountForSelectedPath = (): number => {
|
||||
const selectedNode: ?LayoutRecordT = (
|
||||
this.state.selectedNodePath || []
|
||||
).reduce(
|
||||
(node: LayoutRecordT, cv) => node.children.get(cv),
|
||||
this.state.layoutDefinition,
|
||||
);
|
||||
return selectedNode ? selectedNode.children.size : 0;
|
||||
};
|
||||
|
||||
render() {
|
||||
const {layoutDefinition, selectedNodePath, direction} = this.state;
|
||||
const {height} = this.props;
|
||||
|
||||
const selectedNode: ?LayoutRecordT = selectedNodePath
|
||||
? layoutDefinition.getIn(getPath(selectedNodePath))
|
||||
: null;
|
||||
|
||||
const playground = (
|
||||
<div
|
||||
className={`Playground ${this.props.renderSidebar ? '' : 'standalone'}`}
|
||||
onMouseDown={this.onMouseDown}
|
||||
style={{height, maxHeight: height}}
|
||||
ref={ref => {
|
||||
this._containerRef = ref;
|
||||
}}>
|
||||
<YogaNode
|
||||
layoutDefinition={layoutDefinition}
|
||||
selectedNodePath={selectedNodePath}
|
||||
onClick={selectedNodePath => this.setState({selectedNodePath})}
|
||||
onDoubleClick={this.onAdd}
|
||||
direction={direction}
|
||||
showGuides={this.props.showGuides}
|
||||
/>
|
||||
{!this.props.renderSidebar && (
|
||||
<Sidebar>
|
||||
<div className="Actions">
|
||||
<Row gutter={15}>
|
||||
<Col span={12}>
|
||||
<CodeGenerators
|
||||
layoutDefinition={layoutDefinition}
|
||||
direction={direction}
|
||||
/>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
{this.props.persist ? (
|
||||
<URLShortener />
|
||||
) : (
|
||||
<Button
|
||||
href={`/playground?${this.getHash()}`}
|
||||
type="primary">
|
||||
Open Playground
|
||||
</Button>
|
||||
)}
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
{this.state.selectedNodePath ? (
|
||||
<Editor
|
||||
node={selectedNode}
|
||||
selectedNodeIsRoot={
|
||||
selectedNodePath ? selectedNodePath.length === 0 : false
|
||||
}
|
||||
onChangeLayout={this.onChangeLayout}
|
||||
onChangeSetting={(key, value) => this.setState({[key]: value})}
|
||||
direction={direction}
|
||||
onRemove={
|
||||
selectedNodePath && selectedNodePath.length > 0
|
||||
? this.onRemove
|
||||
: undefined
|
||||
}
|
||||
onAdd={
|
||||
selectedNodePath &&
|
||||
selectedNodePath.length < this.props.maxDepth
|
||||
? this.onAdd
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
) : (
|
||||
<div className="NoContent">
|
||||
Select a node to edit its properties
|
||||
</div>
|
||||
)}
|
||||
</Sidebar>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
||||
if (this.props.renderSidebar) {
|
||||
return (
|
||||
<div className={`PlaygroundContainer ${this.props.className || ''}`}>
|
||||
<div>
|
||||
{this.props.renderSidebar(
|
||||
layoutDefinition.getIn(getPath(selectedNodePath)),
|
||||
this.onChangeLayout,
|
||||
)}
|
||||
</div>
|
||||
{playground}
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return playground;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,56 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
.Toolbar {
|
||||
display: flex;
|
||||
padding: 20px 15px;
|
||||
z-index: 4;
|
||||
align-items: center;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.Toolbar .selected {
|
||||
color: #6BCEBB;
|
||||
}
|
||||
|
||||
.Toolbar .logo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.Toolbar a {
|
||||
margin: 0 15px;
|
||||
color: #606770;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.Toolbar a:hover {
|
||||
color: #6BCEBB;
|
||||
}
|
||||
|
||||
.Toolbar .ToolbarToggle {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.Toolbar .ToolbarToggle i {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 576px) {
|
||||
.Toolbar {
|
||||
padding: 10px 5px;
|
||||
}
|
||||
|
||||
.Toolbar a {
|
||||
margin: 0 10px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.Toolbar .ToolbarToggle {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
@@ -1,52 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import Link from 'gatsby-link';
|
||||
import {Icon, Row, Col} from 'antd';
|
||||
import logo from '../pages/logos/logo.svg';
|
||||
import './Toolbar.css';
|
||||
|
||||
type Props = {
|
||||
onShowCode?: () => void,
|
||||
};
|
||||
|
||||
export default class Toolbar extends Component<Props> {
|
||||
render() {
|
||||
return (
|
||||
<div className="Toolbar">
|
||||
<Link to="/" className="logo">
|
||||
<img src={logo} width="42" alt="Yoga logo" />
|
||||
</Link>
|
||||
|
||||
<Link to="/docs" activeClassName="selected">
|
||||
Documentation
|
||||
</Link>
|
||||
|
||||
<Row>
|
||||
<Col lg={24} md={0} sm={0} xs={0}>
|
||||
<Link to="/playground" activeClassName="selected">
|
||||
Playground
|
||||
</Link>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<a href="https://github.com/facebook/yoga">GitHub</a>
|
||||
|
||||
{this.props.onShowCode && (
|
||||
<a className="ToolbarToggle" onClick={this.props.onShowCode}>
|
||||
<Icon type={'code-o'} />
|
||||
Code
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
@@ -1,20 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
const NotFoundPage = () => (
|
||||
<div>
|
||||
<h1>NOT FOUND</h1>
|
||||
<p>You just hit a route that doesn't exist... the sadness.</p>
|
||||
</div>
|
||||
);
|
||||
|
||||
export default NotFoundPage;
|
@@ -1,73 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
.docs-landing .heading {
|
||||
padding-top: 50px;
|
||||
padding-bottom: 50px;
|
||||
}
|
||||
|
||||
.docs-landing h1 {
|
||||
color: #444950;
|
||||
font-size: 48px;
|
||||
font-weight: 300;
|
||||
line-height: 110%;
|
||||
}
|
||||
|
||||
.docs-landing p {
|
||||
color: #444950;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
line-height: 180%;
|
||||
}
|
||||
|
||||
.category {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
|
||||
.category h2 {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.category a {
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
line-height: 250%;
|
||||
color: #606770;
|
||||
}
|
||||
|
||||
.category a:hover {
|
||||
color: #6BCEBB;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 576px) {
|
||||
.docs-landing .heading {
|
||||
padding-top: 20px;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
.docs-landing h1 {
|
||||
font-size: 32px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.docs-landing p {
|
||||
line-height: 160%;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.category {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.category a {
|
||||
line-height: 200%;
|
||||
}
|
||||
}
|
@@ -1,87 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import Link from 'gatsby-link';
|
||||
import Page from '../../components/Page';
|
||||
import Padded from '../../components/Padded';
|
||||
import {Row, Col} from 'antd';
|
||||
import './index.css';
|
||||
|
||||
const CATEGORY_TITLE = {
|
||||
'getting-started': 'Getting Started',
|
||||
properties: 'Properties',
|
||||
examples: 'Examples',
|
||||
contributing: 'Contributing',
|
||||
};
|
||||
|
||||
export default ({data}) => (
|
||||
<Page className="docs-landing" shouldShowFooter title="Documentation">
|
||||
<Padded>
|
||||
<Row className="heading">
|
||||
<Col xl={16} lg={16} md={24} sm={24} xs={24}>
|
||||
<h1>Documentation</h1>
|
||||
<p>
|
||||
Welcome to Yoga's documentation page. Below you will find helpful
|
||||
documentation covering all the features of the library. Each page
|
||||
comes with an interactive playground for you to explore that
|
||||
feature. The examples section showcases some of the most common
|
||||
layouts and how to build them. This is a community project and
|
||||
contributions within documentation, code, and tests are more than
|
||||
welcome. The contributing section below covers how to get started.
|
||||
</p>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
{['getting-started', 'properties', 'examples', 'contributing'].map(
|
||||
category => (
|
||||
<Col lg={6} md={12} xs={24} key={category} className="category">
|
||||
<h2>{CATEGORY_TITLE[category]}</h2>
|
||||
{data.allMarkdownRemark.edges
|
||||
.filter(
|
||||
({node}) =>
|
||||
node.fileAbsolutePath.indexOf(`/${category}/`) > -1,
|
||||
)
|
||||
.map(({node}) =>
|
||||
node.frontmatter.redirect ? (
|
||||
<a key={node.id} href={node.frontmatter.path}>
|
||||
{node.frontmatter.title}
|
||||
</a>
|
||||
) : (
|
||||
<Link key={node.id} to={node.frontmatter.path}>
|
||||
{node.frontmatter.title}
|
||||
</Link>
|
||||
),
|
||||
)}
|
||||
</Col>
|
||||
),
|
||||
)}
|
||||
</Row>
|
||||
</Padded>
|
||||
</Page>
|
||||
);
|
||||
|
||||
export const query = graphql`
|
||||
query IndexQuery {
|
||||
allMarkdownRemark {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
frontmatter {
|
||||
title
|
||||
path
|
||||
redirect
|
||||
}
|
||||
fileAbsolutePath
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
@@ -1,222 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
.landing-page .hero {
|
||||
padding-top: 100px;
|
||||
padding-bottom: 100px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.landing-page .hero h3 {
|
||||
color: #BEC3C9;
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
line-height: 200%;
|
||||
}
|
||||
|
||||
.landing-page .hero h1 {
|
||||
color: #444950;
|
||||
font-size: 48px;
|
||||
font-weight: 300;
|
||||
line-height: 110%;
|
||||
}
|
||||
|
||||
.landing-page .hero p {
|
||||
color: #444950;
|
||||
line-height: 180%;
|
||||
font-size: 18px;
|
||||
font-weight: 400;
|
||||
margin-bottom: 1.5em;
|
||||
}
|
||||
|
||||
.landing-page .hero .button {
|
||||
color: white;
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
padding: 12px 30px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.landing-page .hero .blueprint {
|
||||
border-style: dashed;
|
||||
border-color: #444950;
|
||||
border-width: 1px;
|
||||
}
|
||||
|
||||
.landing-page .hero .blueprint-container {
|
||||
position: relative;
|
||||
margin: auto;
|
||||
height: 300px;
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
.landing-page .hero .blueprint-avatar {
|
||||
position: absolute;
|
||||
left: 15px;
|
||||
top: 15px;
|
||||
height: 50px;
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
.landing-page .hero .blueprint-title {
|
||||
position: absolute;
|
||||
left: 80px;
|
||||
top: 20px;
|
||||
height: 15px;
|
||||
width: 150px;
|
||||
}
|
||||
|
||||
.landing-page .hero .blueprint-subtitle {
|
||||
position: absolute;
|
||||
left: 80px;
|
||||
top: 40px;
|
||||
height: 15px;
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
.landing-page .hero .blueprint-content {
|
||||
position: absolute;
|
||||
left: 15px;
|
||||
right: 15px;
|
||||
bottom: 15px;
|
||||
top: 80px;
|
||||
}
|
||||
|
||||
.landing-page hr {
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
background-color: #BEC3C9;
|
||||
border-width: 0px;
|
||||
}
|
||||
|
||||
.landing-page .about-section {
|
||||
padding-top: 100px;
|
||||
padding-bottom: 100px;
|
||||
}
|
||||
|
||||
.landing-page .about-section h1 {
|
||||
color: #444950;
|
||||
font-size: 32px;
|
||||
font-weight: 400;
|
||||
line-height: 120%;
|
||||
}
|
||||
|
||||
.landing-page .about-section h3 {
|
||||
color: #6BCEBB;
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
margin-top: 50px;
|
||||
}
|
||||
|
||||
.landing-page .about-section p {
|
||||
color: #444950;
|
||||
line-height: 180%;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.landing-page .logo-group {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
margin-top: 50px;
|
||||
}
|
||||
|
||||
.landing-page .logo-group .logo {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-right: 100px;
|
||||
}
|
||||
|
||||
.landing-page .logo-group img {
|
||||
height: 130px;
|
||||
}
|
||||
|
||||
.landing-page .logo-group .logo h3 {
|
||||
color: #606770;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
margin-top: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
footer {
|
||||
display: flex;
|
||||
padding: 20px 15px;
|
||||
padding-left: 87px;
|
||||
z-index: 4;
|
||||
align-items: center;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
footer a {
|
||||
margin: 0 15px;
|
||||
color: #606770;
|
||||
}
|
||||
|
||||
footer a:hover {
|
||||
color: #6BCEBB;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 576px) {
|
||||
.landing-page .hero {
|
||||
padding-top: 20px;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
.landing-page .hero h3 {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.landing-page .hero h1 {
|
||||
font-size: 32px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.landing-page .hero p {
|
||||
line-height: 160%;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.landing-page .about-section {
|
||||
padding-top: 50px;
|
||||
padding-bottom: 50px;
|
||||
}
|
||||
|
||||
.landing-page .about-section h1 {
|
||||
font-size: 24px;
|
||||
line-height: 120%;
|
||||
}
|
||||
|
||||
.landing-page .about-section h3 {
|
||||
font-size: 14px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.landing-page .about-section p {
|
||||
line-height: 160%;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.landing-page .logo-group .logo {
|
||||
width: 33%;
|
||||
padding: 20px;
|
||||
margin-right: 0px;
|
||||
}
|
||||
|
||||
.landing-page .logo-group img {
|
||||
height: auto;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.landing-page .logo-group .logo h3 {
|
||||
font-size: 10px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
@@ -1,198 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
import {Button} from 'antd';
|
||||
import React from 'react';
|
||||
import Page from '../components/Page';
|
||||
import Padded from '../components/Padded';
|
||||
import Playground from '../components/Playground/src';
|
||||
import {Row, Col} from 'antd';
|
||||
import './index.css';
|
||||
import ReactNativeLogo from './logos/reactnative.png';
|
||||
import LithoLogo from './logos/litho.png';
|
||||
import ComponentKitLogo from './logos/componentkit.png';
|
||||
import ReactPDFLogo from './logos/reactpdf.png';
|
||||
import Link from 'gatsby-link';
|
||||
import Footer from '../components/Footer';
|
||||
|
||||
const playgroundInitialState = {
|
||||
width: 500,
|
||||
height: 500,
|
||||
alignItems: 1,
|
||||
padding: {
|
||||
top: '20',
|
||||
right: '20',
|
||||
bottom: '20',
|
||||
left: '20',
|
||||
},
|
||||
children: [
|
||||
{
|
||||
width: 100,
|
||||
height: 100,
|
||||
minWidth: null,
|
||||
maxWidth: null,
|
||||
minHeight: null,
|
||||
maxHeight: null,
|
||||
},
|
||||
{
|
||||
width: 100,
|
||||
height: 100,
|
||||
margin: {
|
||||
right: '20',
|
||||
left: '20',
|
||||
},
|
||||
flexGrow: '1',
|
||||
minWidth: null,
|
||||
maxWidth: null,
|
||||
minHeight: null,
|
||||
maxHeight: null,
|
||||
},
|
||||
{
|
||||
width: 100,
|
||||
height: 100,
|
||||
minWidth: null,
|
||||
maxWidth: null,
|
||||
minHeight: null,
|
||||
maxHeight: null,
|
||||
},
|
||||
],
|
||||
minWidth: null,
|
||||
maxWidth: null,
|
||||
minHeight: null,
|
||||
maxHeight: null,
|
||||
};
|
||||
|
||||
const HeroSection = () => (
|
||||
<Padded>
|
||||
<Row className="hero">
|
||||
<Col md={12} sm={24} xs={24}>
|
||||
<h3>INTRODUCING</h3>
|
||||
<h1>
|
||||
Flexible Layouts <br /> with Yoga
|
||||
</h1>
|
||||
<p>
|
||||
Build flexible layouts on any platform with a highly optimized open
|
||||
source layout engine designed with speed, size, and ease of use in
|
||||
mind.
|
||||
</p>
|
||||
|
||||
<Link to="/docs">
|
||||
<Button type="primary" className="button">
|
||||
LEARN MORE
|
||||
</Button>
|
||||
</Link>
|
||||
</Col>
|
||||
<Col md={12} sm={0} xs={0}>
|
||||
<div className="blueprint blueprint-container">
|
||||
<div className="blueprint blueprint-avatar" />
|
||||
<div className="blueprint blueprint-title" />
|
||||
<div className="blueprint blueprint-subtitle" />
|
||||
<div className="blueprint blueprint-content" />
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</Padded>
|
||||
);
|
||||
|
||||
const PlaygroundSection = () => (
|
||||
<Row>
|
||||
<Col lg={24} md={0} sm={0} xs={0}>
|
||||
<Playground
|
||||
selectedNodePath={[]}
|
||||
showGuides={true}
|
||||
height={601}
|
||||
layoutDefinition={playgroundInitialState}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
);
|
||||
|
||||
const AboutSectionOne = () => (
|
||||
<Padded className="about-section">
|
||||
<Row>
|
||||
<Col xl={16} lg={16} md={24} sm={24} xs={24}>
|
||||
<h1>Open Source Adoption</h1>
|
||||
<p>
|
||||
Yoga already powers widely used open source frameworks. It enables
|
||||
these frameworks to offer a simple and intuitive layout API that
|
||||
allows for engineers to collaborate more easily across platforms. Yoga
|
||||
has unlocked exciting features such as calculating layouts off of the
|
||||
main thread to help ensure smooth UI performance.
|
||||
</p>
|
||||
</Col>
|
||||
</Row>
|
||||
<div className="logo-group">
|
||||
<a href="https://fblitho.com" target="_blank" className="logo">
|
||||
<img src={LithoLogo} />
|
||||
<h3>Litho</h3>
|
||||
</a>
|
||||
<a href="https://componentkit.org" target="_blank" className="logo">
|
||||
<img src={ComponentKitLogo} />
|
||||
<h3>ComponentKit</h3>
|
||||
</a>
|
||||
<a href="https://reactnative.dev" target="_blank" className="logo">
|
||||
<img src={ReactNativeLogo} />
|
||||
<h3>React Native</h3>
|
||||
</a>
|
||||
<a href="https://react-pdf.org/" target="_blank" className="logo">
|
||||
<img src={ReactPDFLogo} />
|
||||
<h3>React-PDF</h3>
|
||||
</a>
|
||||
</div>
|
||||
</Padded>
|
||||
);
|
||||
|
||||
const AboutSectionTwo = () => (
|
||||
<Padded className="about-section">
|
||||
<Row>
|
||||
<Col xl={16} lg={16} md={24} sm={24} xs={24}>
|
||||
<h1>Why You May Consider Yoga</h1>
|
||||
|
||||
<h3>PERFORMANCE</h3>
|
||||
<p>
|
||||
Yoga was built to be fast and performance will always be one of Yoga's
|
||||
primary goals. For a layout engine to be able to power any range of
|
||||
applications, it needs to be fast and never stand in the way of a
|
||||
fluid user experience.
|
||||
</p>
|
||||
|
||||
<h3>CROSS PLATFORM</h3>
|
||||
<p>
|
||||
Yoga is built with cross platform in mind. To ensure Yoga can be used
|
||||
anywhere, it was written in portable C/C++ and has a low number of
|
||||
dependencies and small binary size. This means Yoga can be used on iOS
|
||||
and Android, sharing knowledge, and potentially code, between
|
||||
platforms.
|
||||
</p>
|
||||
|
||||
<h3>EASY TO LEARN</h3>
|
||||
<p>
|
||||
Yoga is easy to pick up and learn. The interactive documentation pages
|
||||
and a fully fledged layout editor makes it easy to play and learn all
|
||||
the features. If used with any of the major UI frameworks the layout
|
||||
editor even provides code generation.
|
||||
</p>
|
||||
</Col>
|
||||
</Row>
|
||||
</Padded>
|
||||
);
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<Page className="landing-page" title="A cross-platform layout engine">
|
||||
<HeroSection />
|
||||
<PlaygroundSection />
|
||||
<AboutSectionOne />
|
||||
<hr />
|
||||
<AboutSectionTwo />
|
||||
<Footer />
|
||||
</Page>
|
||||
</div>
|
||||
);
|
Binary file not shown.
Before Width: | Height: | Size: 9.4 KiB |
Binary file not shown.
Before Width: | Height: | Size: 5.9 KiB |
Binary file not shown.
Before Width: | Height: | Size: 24 KiB |
@@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 200 200" enable-background="new 0 0 200 200" xml:space="preserve">
|
||||
<g>
|
||||
<circle fill="#303846" cx="100" cy="100" r="74"/>
|
||||
<g>
|
||||
<path fill="none" stroke="#97DCCF" stroke-width="5" stroke-miterlimit="10" d="M100.6,130.6c5.9-10.3,6.3-23.3,0-34.3
|
||||
c-6.3-11-17.9-17.1-29.7-17.1c-5.9,10.3-6.3,23.3,0,34.3C77.2,124.4,88.7,130.6,100.6,130.6z"/>
|
||||
<path fill="none" stroke="#97DCCF" stroke-width="5" stroke-miterlimit="10" d="M99.4,130.6c11.8,0,23.3-6.1,29.7-17.1
|
||||
c6.3-11,5.9-24,0-34.3c-11.8,0-23.3,6.1-29.7,17.1C93.1,107.3,93.5,120.3,99.4,130.6z"/>
|
||||
</g>
|
||||
<path fill="none" stroke="#97DCCF" stroke-width="5" stroke-miterlimit="10" d="M100,129.4c10.2-5.9,17.1-17,17.1-29.7
|
||||
c0-12.7-6.9-23.8-17.1-29.7c-10.2,5.9-17.1,17-17.1,29.7C82.9,112.4,89.8,123.5,100,129.4z"/>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
Before Width: | Height: | Size: 51 KiB |
Binary file not shown.
Before Width: | Height: | Size: 86 KiB |
@@ -1,28 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
.playground-page {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
@media (max-width: 991px) {
|
||||
.playground-page .error-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
.playground-page .error-text {
|
||||
color: #444950;
|
||||
line-height: 180%;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
text-align: center;
|
||||
}
|
@@ -1,31 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import Page from '../../components/Page';
|
||||
import Playground from '../../components/Playground/src';
|
||||
import {Row, Col} from 'antd';
|
||||
import './index.css';
|
||||
|
||||
export default () => (
|
||||
<Page title="Playground">
|
||||
<Row className="playground-page">
|
||||
<Col lg={24} md={0} sm={0} xs={0}>
|
||||
<Playground height="100%" selectedNodePath={[]} persist />
|
||||
</Col>
|
||||
|
||||
<Col lg={0} xs={24} className="error-container">
|
||||
<p className="error-text">
|
||||
Sorry! The playground only works on larger displays currently.
|
||||
</p>
|
||||
</Col>
|
||||
</Row>
|
||||
</Page>
|
||||
);
|
@@ -1,141 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
.doc-block.playground {
|
||||
height: 1vh;
|
||||
}
|
||||
|
||||
.no-playground .markdown {
|
||||
padding-top: 50px;
|
||||
}
|
||||
|
||||
.doc-block .markdown {
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
.doc-block .overview {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
padding-bottom: 30px;
|
||||
}
|
||||
|
||||
.doc-block h1 {
|
||||
color: #444950;
|
||||
font-size: 48px;
|
||||
font-weight: 300;
|
||||
line-height: 110%;
|
||||
}
|
||||
|
||||
.doc-block h2 {
|
||||
color: #444950;
|
||||
font-size: 32px;
|
||||
font-weight: 400;
|
||||
line-height: 120%;
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.doc-block h3 {
|
||||
line-height: 180%;
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
color: #444950;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.doc-block p {
|
||||
color: #444950;
|
||||
line-height: 160%;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.doc-block li {
|
||||
color: #444950;
|
||||
line-height: 150%;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.doc-block .prop {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.doc-block pre {
|
||||
background-color: #f5f5f5 !important;
|
||||
border-radius: 3px;
|
||||
padding: 10px !important;
|
||||
}
|
||||
|
||||
.doc-block pre, .doc-block code {
|
||||
background-color: #f5f5f5;
|
||||
border-radius: 3px;
|
||||
padding-left: 3px;
|
||||
padding-right: 3px;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 992px) {
|
||||
.playground .Playground {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.playground controls {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 576px) {
|
||||
.no-playground .markdown {
|
||||
padding-top: 15px;
|
||||
}
|
||||
|
||||
.doc-block .markdown {
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.doc-block .overview {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.doc-block h1 {
|
||||
font-size: 32px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.doc-block h2 {
|
||||
font-size: 24px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.doc-block h3 {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.doc-block p {
|
||||
line-height: 160%;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.doc-block li {
|
||||
font-size: 14px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.doc-block .prop {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.doc-block pre {
|
||||
padding: 5px !important;
|
||||
}
|
||||
|
||||
.doc-block code {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
@@ -1,58 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import Page from '../components/Page';
|
||||
import Playground from '../components/Playground/src';
|
||||
import DocsSidebar from '../components/DocsSidebar';
|
||||
import EditValue from '../components/Playground/src/EditValue';
|
||||
import Link from 'gatsby-link';
|
||||
import {Button, Icon, Row, Col} from 'antd';
|
||||
import './index.css';
|
||||
import atob from 'atob';
|
||||
|
||||
type Props = {
|
||||
pathContext: {
|
||||
html: string,
|
||||
frontmatter: {
|
||||
initialPlayground?: string,
|
||||
},
|
||||
},
|
||||
};
|
||||
const REGEX = /<controls prop="([A-Za-z]+)"\s?\/>/gi;
|
||||
|
||||
export default class withPlayground extends Component<Props> {
|
||||
render() {
|
||||
let layoutDefinition;
|
||||
if (this.props.pathContext.frontmatter.initialPlayground) {
|
||||
layoutDefinition = JSON.parse(
|
||||
atob(this.props.pathContext.frontmatter.initialPlayground),
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Page
|
||||
className="doc-block playground"
|
||||
title={this.props.pathContext.frontmatter.title}>
|
||||
<Playground
|
||||
layoutDefinition={layoutDefinition}
|
||||
selectedNodePath={[]}
|
||||
showGuides={false}
|
||||
renderSidebar={(layout, onChange) => (
|
||||
<DocsSidebar
|
||||
layout={layout}
|
||||
onChange={onChange}
|
||||
markdown={this.props.pathContext.html}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</Page>
|
||||
);
|
||||
}
|
||||
}
|
@@ -1,39 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import Page from '../components/Page';
|
||||
import Padded from '../components/Padded';
|
||||
import {Row, Col} from 'antd';
|
||||
import Link from 'gatsby-link';
|
||||
import './index.css';
|
||||
|
||||
export default ({pathContext}) => {
|
||||
return (
|
||||
<Page
|
||||
className="doc-block no-playground"
|
||||
shouldShowFooter
|
||||
title={pathContext.frontmatter.title}>
|
||||
<Padded>
|
||||
<Row>
|
||||
<Col xl={16} lg={16} md={24} sm={24} xs={24}>
|
||||
<div
|
||||
className="markdown"
|
||||
dangerouslySetInnerHTML={{__html: pathContext.html}}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
<Link to="/docs" className="overview">
|
||||
BACK TO OVERVIEW
|
||||
</Link>
|
||||
</Padded>
|
||||
</Page>
|
||||
);
|
||||
};
|
11999
website/yarn.lock
11999
website/yarn.lock
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user