diff --git a/content/de/index.md b/content/de/index.md index 200bbb2ab..243e1a06c 100755 --- a/content/de/index.md +++ b/content/de/index.md @@ -10,14 +10,10 @@ toc: false

Preact

-

Schnelle 3kB-Alternative zu React mit der gleichen ES6-API.

+

Schnelle 3kB-Alternative zu React mit der gleichen ES6-API.

- Fang an -   •   - Wechsle zu Preact -

-

- 5,000+ + Fang an + Wechsle zu Preact

@@ -35,6 +31,11 @@ function Counter() { } ``` +
+

Gesponsort von:

+ +
+

Eine Bibliothek der anderen Art.

@@ -111,7 +112,6 @@ function Counter() { @@ -232,8 +232,7 @@ render( Wähle die Anleitung aus, die für dich am besten geeignet ist!

- Fang an -   •   - Wechsle zu Preact + Fang an + Wechsle zu Preact

diff --git a/content/en/guide/v10/api-reference.md b/content/en/guide/v10/api-reference.md index 99266258e..a82a7d41f 100644 --- a/content/en/guide/v10/api-reference.md +++ b/content/en/guide/v10/api-reference.md @@ -44,7 +44,7 @@ Render a Preact component into the `containerNode` DOM node. Does not return any If the optional `replaceNode` DOM node is provided and is a child of `containerNode`, Preact will update or replace that element using its diffing algorithm. -```js +```jsx import { render } from 'preact'; const Foo = () =>
foo
; diff --git a/content/en/guide/v10/components.md b/content/en/guide/v10/components.md index 4ff5f020c..a09442701 100755 --- a/content/en/guide/v10/components.md +++ b/content/en/guide/v10/components.md @@ -39,14 +39,13 @@ Class components can have state and lifecycle methods. The latter are special me Here we have a simple class component called `` that displays the current time: -```js +```jsx class Clock extends Component { constructor() { super(); this.state = { time: Date.now() }; } - // Lifecycle: Called whenever our component is created componentDidMount() { @@ -159,7 +158,7 @@ const Bar = <>foo; You can also return arrays from your components: -```js +```jsx function Columns() { return [ Hello, @@ -170,7 +169,7 @@ function Columns() { Don't forget to add keys to `Fragments` if you create them in a loop: -```js +```jsx function Glossary(props) { return (
diff --git a/content/en/guide/v10/extending-component.md b/content/en/guide/v10/extending-component.md deleted file mode 100755 index fa77e6078..000000000 --- a/content/en/guide/v10/extending-component.md +++ /dev/null @@ -1,67 +0,0 @@ ---- -name: Extending Component -permalink: '/guide/extending-component' ---- - -# Extending Component - -It is possible that some projects would wish to extend Component with additional functionality. - -There are varying opinions on the value of inheritance in JavaScript, but if you wish to build your own "base class" from which all of your components inherit, Preact has you covered. - -Perhaps you want to do automatic connection to stores/reducers within a Flux-like architecture. Maybe you want to add property-based mixins to make it feel more like `React.createClass()` _(note: the [`@bind` decorator](https://github.com/developit/decko#bind) is preferable)_. - -In any case, just use ES2015 class inheritance to extend Preact's `Component` class: - -```js -class BoundComponent extends Component { - // example: get bound methods - binds() { - let list = this.bind || [], - binds = this._binds; - if (!binds) { - binds = this._binds = {}; - for (let i=list.length; i--; ) { - binds[list[i]] = this[list[i]].bind(this); - } - } - return binds; - } -} -``` - -Example Usage: - -```js -class Link extends BoundComponent { - bind = ['click']; - click() { - open(this.props.href); - } - render({ children }) { - let { click } = this.binds(); - return { children }; - } -} - -render( - Click Me, - document.body -); -``` - - -The possibilities are endless. Here's an extended `Component` class that supports rudimentary mixins: - -```js -class MixedComponent extends Component { - constructor() { - super(); - (this.mixins || []).forEach( m => Object.assign(this, m) ); - } -} -``` - ---- - -> **Footnote:** It's worth noting that inheritance can lock you into brittle parent-child relationships. Often when faced with a programming task that can be solved adequately with inheritance, there is a more functional way to achieve the same goal that would avoid creating such a relationship. diff --git a/content/en/guide/v10/external-dom-mutations.md b/content/en/guide/v10/external-dom-mutations.md index 486dd4825..7bb03708c 100755 --- a/content/en/guide/v10/external-dom-mutations.md +++ b/content/en/guide/v10/external-dom-mutations.md @@ -20,7 +20,7 @@ In Preact (and similarly in React), working with these types of libraries requir This can be as simple as defining a `shouldComponentUpdate()` method on your component, and having it return `false`: -```js +```jsx class Block extends Component { shouldComponentUpdate() { return false; @@ -30,7 +30,7 @@ class Block extends Component { ... or for shorthand: -```js +```jsx class Block extends Component { shouldComponentUpdate = () => false; } @@ -44,7 +44,7 @@ With this lifecycle hook in place and telling Preact not to re-render the Compon Here is an example of "turning off" re-rendering for a Component. Note that `render()` is still invoked as part of creating and mounting the Component, in order to generate its initial DOM structure. -```js +```jsx class Example extends Component { shouldComponentUpdate() { // do not re-render via diff: diff --git a/content/en/guide/v10/forms.md b/content/en/guide/v10/forms.md index c3f24ee6b..c2dbbf174 100755 --- a/content/en/guide/v10/forms.md +++ b/content/en/guide/v10/forms.md @@ -105,7 +105,7 @@ So, instead of listening for a `input` event we should listen for a `click` even ### Checkbox Example -```js +```jsx class MyForm extends Component { toggle = e => { let checked = !this.state.checked; diff --git a/content/en/guide/v10/getting-started.md b/content/en/guide/v10/getting-started.md index a84d6951b..7285aabe2 100644 --- a/content/en/guide/v10/getting-started.md +++ b/content/en/guide/v10/getting-started.md @@ -5,9 +5,9 @@ description: "How to get started with Preact. We'll learn how to setup the tooli # Getting Started -This guide helps you get up and running to start developing Preact apps. There are 3 popular ways to do so. +This guide helps you get up and running to start developing Preact apps. -If you're just starting out we highly recommend going with [preact-cli](#best-practices-powered-with-preact-cli). +There are 3 popular options. If you're new to Preact, we recommend starting with [Preact CLI](#best-practices-powered-by-preact-cli). --- @@ -17,78 +17,86 @@ If you're just starting out we highly recommend going with [preact-cli](#best-pr ## No build tools route -Preact has always been readily packaged to be used right in the browser. This doesn't require any build tools at all. +Preact is packaged to be used directly in the browser, and doesn't require any build or tools: -```js -import { h, Component, render } from 'https://unpkg.com/preact?module'; - -// Create your app -const app = h('div', null, 'Hello World!'); +```html + ``` -The only difference is that you cannot use JSX, because JSX needs to be transpiled. We got you covered with an alternative in the next section. So keep reading. +[🔨 Edit on Glitch](https://glitch.com/~preact-no-build-tools) + +The primary drawback of developing this way is the lack of JSX, which requires a build step. An ergonomic and performant alternative to JSX is documented in the next section. ### Alternatives to JSX -Writing raw `h` or `createElement` calls all the time is much less fun than using something JSX-like. JSX has the advantage of looking similar to HTML, which makes it easier to understand for many developers in our experience. It requires a built-step though, so we highly recommend an alternative called [htm]. +Writing raw `h` or `createElement` calls can be tedious. JSX has the advantage of looking similar to HTML, which makes it easier to understand for many developers in our experience. JSX requires a built-step though, so we highly recommend an alternative called [HTM][htm]. -In a nutshell [htm] can be best described as: JSX-like syntax in plain JavaScript without a need for a transpiler. Instead of using a custom syntax it relies on native tagged template strings which were added to JavaScript a while back. +[HTM][htm] is a JSX-like syntax that works in standard JavaScript. Instead of requiring a build step, it uses JavaScript's own [Tagged Templates](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#Tagged_templates) syntax, which was added in 2015 and is supported in [all modern browsers](https://caniuse.com/#feat=template-literals). This is an increasingly popular way to write Preact apps, since there are fewer moving parts to understand than a traditional front-end build tooling setup. -```js -import { h, Component, render } from 'https://unpkg.com/preact?module'; -import htm from 'https://unpkg.com/htm?module'; +```html + ``` -It's a very popular way of writing Preact apps and we highly recommend checking out htm's [README][htm] file if you're interested in going with this route. +[🔨 Edit on Glitch](https://glitch.com/~preact-with-htm) + +For more information on HTM, check out its [documentation][htm]. -## Best practices powered with `preact-cli` +## Best practices powered by Preact CLI -The `preact-cli` project is a ready made solution to bundle Preact applications with the optimal bundler configuration that's best for modern web application. It's built on standard tooling projects like `webpack`, `babel` and `postcss`. Because of the simplicity this is the most popular way to use Preact among our users. +[Preact CLI] is an off-the-shelf solution for building Preact applications that is optimized for modern web development. It's built on standard tooling projects like Webpack, Babel and PostCSS. Preact CLI does not require any configuration or prior knowledge to get started, and this simplicity makes it the most popular way to use Preact. -As the name implies, `preact-cli` is a **c**ommand-**li**ne tool that can be run in the terminal on your machine. Install it globally by running: +As the name implies, Preact CLI is a **c**ommand-**li**ne tool that can be run in the terminal on your machine. Install it globally by running: ```bash npm install -g preact-cli ``` -After that you'll have a new command in your terminal called `preact`. With it you can create a new application by executing the following command: +After that you'll have a new command in your terminal called `preact`. With it you can create a new application by running the `preact create` command: ```bash preact create default my-project ``` -The above command pulls the template from `preactjs-templates/default`, prompts for some information, and generates the project at `./my-project/`. +This will create a new application based on our [default template](https://github.com/preactjs-templates/default). You will be asked for some information about your project, which will then be generated in the directory you specified (`my-project` in this case). -> Tip: Any Github repo with a `'template'` folder can be used as a custom template: `preact create / ` +> **Tip:** Any GitHub repository with a `template/` folder can be used as a custom template: +> +> `preact create / ` ### Getting ready for development -Now we're ready to start our application. To fire up the development server run the following command inside the freshly generated project folder (`my-project` in this example): +Now we're ready to start our application. To start a development server, run the following command inside your newly generated project folder (`my-project` from above): ```bash # Go into the generated project folder -cd my-project/ +cd my-project -# Start the devserver +# Start a development server npm start ``` -Once the server is up you can access your app at the URL that was printed in the console. Now you're ready to develop your app! +Once the server has started, it will print a local development URL to open in your browser. +Now you're ready to start coding your app! ### Making a production build -There comes a time when you need to deploy your app somewhere. The CLI ships with a handy `build` command which will generate a highly optimized build. +There comes a time when you need to deploy your app somewhere. The CLI ships with a handy `build` command which will generate a highly optimized production build. ```bash npm run build @@ -96,7 +104,7 @@ npm run build Upon completion you'll have a new `build/` folder which can be deployed directly to a server. -> For a full list of all available commands check out the list in preact-cli's [README file](https://github.com/preactjs/preact-cli#cli-options). +> For a full list of all available commands check out the [Preact CLI Documentation](https://github.com/preactjs/preact-cli#cli-options). ## Integrating Into An Existing Pipeline @@ -117,7 +125,7 @@ To transpile JSX you need a babel plugin that converts it to valid JavaScript co } ``` -> [babeljs](https://babeljs.io/) has one of the best documentation out there. We highly recommend checking it out for questions surrounding babel and how to set it up. +> [babeljs](https://babeljs.io/) has some of the best documentation out there. We highly recommend checking it out for questions surrounding babel and how to set it up. ### Aliasing React to Preact @@ -175,4 +183,4 @@ jest configuration: ``` [htm]: https://github.com/developit/htm - +[Preact CLI]: https://github.com/preactjs/preact-cli diff --git a/content/en/guide/v10/options.md b/content/en/guide/v10/options.md index 00a56b5df..3fe4050b5 100644 --- a/content/en/guide/v10/options.md +++ b/content/en/guide/v10/options.md @@ -68,9 +68,9 @@ Invoked immediately after a vnode is rendered, once its DOM representation is co #### `options.event` -**Signature:** `(event: Event) => void` +**Signature:** `(event: Event) => any` -Invoked just before a DOM event is handled by its associated Virtual DOM listener. +Invoked just before a DOM event is handled by its associated Virtual DOM listener. When `options.event` is setted, the event which is event listener argument is replaced return value of `options.event`. #### `options.requestAnimationFrame` diff --git a/content/en/guide/v10/tutorial.md b/content/en/guide/v10/tutorial.md index 9c72acd9d..8c0205bc8 100755 --- a/content/en/guide/v10/tutorial.md +++ b/content/en/guide/v10/tutorial.md @@ -157,7 +157,7 @@ Boom! We're done! We can now enter a custom name, click "Update" and our new nam We wrote our first component, so let's get a little more practice. This time we build a clock. -```js +```jsx import { h, render, Component } from 'preact'; class Clock extends Component { @@ -174,7 +174,7 @@ Ok, that was easy enough! Problem is, that the time doesn't change. It's frozen So, we want to have a 1-second timer start once the Component gets added to the DOM, and stop if it is removed. We'll create the timer and store a reference to it in `componentDidMount`, and stop the timer in `componentWillUnmount`. On each timer tick, we'll update the component's `state` object with a new time value. Doing this will automatically re-render the component. -```js +```jsx import { h, render, Component } from 'preact'; class Clock extends Component { diff --git a/content/en/guide/v10/unit-testing-with-enzyme.md b/content/en/guide/v10/unit-testing-with-enzyme.md index bda27fe3d..1fc3dc367 100644 --- a/content/en/guide/v10/unit-testing-with-enzyme.md +++ b/content/en/guide/v10/unit-testing-with-enzyme.md @@ -56,7 +56,7 @@ documentation. Suppose we have a simple `Counter` component which displays an initial value, with a button to update it: -```js +```jsx import { h } from 'preact'; import { useState } from 'preact/hooks'; @@ -76,7 +76,7 @@ export default function Counter({ initialCount }) { Using a test runner such as mocha or Jest, you can write a test to check that it works as expected: -```js +```jsx import { expect } from 'chai'; import { h } from 'preact'; import { mount } from 'enzyme'; @@ -117,7 +117,7 @@ the output. Enzyme has three rendering "modes": -```js +```jsx import { mount, shallow, render } from 'enzyme'; // Render the full component tree: @@ -179,7 +179,7 @@ through the `simulate` method: import { act } from 'preact/test-utils'; ``` -```js +```jsx it('should increment after "Increment" button is clicked', () => { const wrapper = mount(); const onClick = wrapper.find('button').props().onClick; diff --git a/content/en/guide/v10/upgrade-guide.md b/content/en/guide/v10/upgrade-guide.md index b2175fa24..fe6461c4e 100644 --- a/content/en/guide/v10/upgrade-guide.md +++ b/content/en/guide/v10/upgrade-guide.md @@ -162,7 +162,7 @@ If you are looking for behavior that exactly matches how React's `render` method In Preact X we can't guarantee `props.children` to always be of type `array` anymore. This change was necessary to resolve parsing ambiguities in regards to `Fragments` and components that return an `array` of children. In most cases you may not even notice it. Only in places where you'll use array methods on `props.children` directly need to be wrapped with `toChildArray`. This function will always return an array. -```js +```jsx // Preact 8.x function Foo(props) { // `.length` is an array method. In Preact X when `props.children` is not an diff --git a/content/en/index.md b/content/en/index.md index b2b5d8f8e..beec407b9 100755 --- a/content/en/index.md +++ b/content/en/index.md @@ -10,13 +10,10 @@ description: 'Preact is a fast 3kB alternative to React with the same modern API

Preact

-

Fast 3kB alternative to React with the same modern API.

+

Fast 3kB alternative to React with the same modern API.

- Get Started - Switch to Preact -

-

- 20,000+ + Get Started + Switch to Preact

@@ -34,6 +31,11 @@ function Counter() { } ``` +
+

Proudly sponsored by:

+ +
+

A different kind of library.

@@ -108,7 +110,6 @@ function Counter() {
  • props, state and context are passed to render()
  • Use standard HTML attributes like class and for
  • -
  • Works with React DevTools right out of the box
@@ -226,8 +227,7 @@ render( Pick the guide that works best for you!

- Get Started -   •   - Switch to Preact + Get Started + Switch to Preact

diff --git a/content/es/index.md b/content/es/index.md index 64986a369..b0a124259 100755 --- a/content/es/index.md +++ b/content/es/index.md @@ -10,14 +10,10 @@ toc: false

Preact

-

Una alternativa veloz a React en 3kB con la misma API de ES6.

+

Una alternativa veloz a React en 3kB con la misma API de ES6.

- Primeros pasos -   •   - Cambiar a Preact -

-

- 5,000+ + Primeros pasos + Cambiar a Preact

@@ -35,6 +31,11 @@ function Counter() { } ``` + +

Una librería distinta.

@@ -237,8 +238,7 @@ render( ¡Elige la guía que mejor te funcione!

- Primeros pasos -   •   - Cambiando a Preact + Primeros pasos + Cambiando a Preact

diff --git a/content/fr/index.md b/content/fr/index.md index cb94e15a1..fb6c1bb9f 100755 --- a/content/fr/index.md +++ b/content/fr/index.md @@ -9,14 +9,10 @@ toc: false

Preact

-

Alternative légère et rapide à React avec le même API en seulement 3Ko.

+

Alternative légère et rapide à React avec le même API en seulement 3Ko.

- Commencer -   •   - Passer à preact -

-

- 5,000+ + Commencer + Passer à preact

@@ -34,6 +30,11 @@ function Counter() { } ``` + +

Un concept différent

@@ -111,7 +112,6 @@ function Counter() {
  • Les `props`, `state` et `context` sont passés en arguments de la méthode `render()`
  • Les attributs standards HTML comme `class` et `for` peuvent être utilisés
  • -
  • Fonctionnne avec React DevTools sans effort
@@ -231,8 +231,7 @@ render( Choisissez celui qui vous convient.

- Commencer -   •   - Passer à Preact + Commencer + Passer à Preact

diff --git a/content/it/index.md b/content/it/index.md index c90c0e241..5e0fcb896 100755 --- a/content/it/index.md +++ b/content/it/index.md @@ -10,14 +10,10 @@ toc: false

Preact

-

Un alternativa veloce e leggera 3Kb a React con le stesse moderne API.

+

Un alternativa veloce e leggera 3Kb a React con le stesse moderne API.

- Primi Passi -       - Passare a Preact -

-

- 19,000+ + Primi Passi + Passare a Preact

@@ -35,6 +31,11 @@ function Counter() { } ``` + +

Una Libreria differente!

@@ -116,7 +117,6 @@ function Counter() {
  • `props`, `state` e `context` sono passati a `render()`
  • Usa attributi standard dell' HTML come `class` e `for`
  • -
  • Funziona con React DevTools senza alcuna configurazione
@@ -238,8 +238,7 @@ render( Scegli la guida migliore per te!

- Primi passi -   •   - Passa a Preact + Primi passi + Passa a Preact

diff --git a/content/pt-br/guide/v10/api-reference.md b/content/pt-br/guide/v10/api-reference.md index 4b0758e0c..f089541fd 100644 --- a/content/pt-br/guide/v10/api-reference.md +++ b/content/pt-br/guide/v10/api-reference.md @@ -44,7 +44,7 @@ Renderizar um componente Preact no `containerNode` do DOM. Não retorna nada. Se o nó DOM opcional `replaceNode` for fornecido e for filho de `containerNode`, o Preact atualizará ou substituirá esse elemento usando seu algoritmo de comparação. -```js +```jsx import { render } from 'preact'; const Foo = () =>
foo
; diff --git a/content/pt-br/guide/v10/components.md b/content/pt-br/guide/v10/components.md index d5dbb9f6a..9a7b0a652 100755 --- a/content/pt-br/guide/v10/components.md +++ b/content/pt-br/guide/v10/components.md @@ -39,7 +39,7 @@ Os componentes de classe podem ter métodos de estado e ciclo de vida. Os últim Aqui temos um componente de classe simples chamado `` que exibe a hora atual: -```js +```jsx class Clock extends Component { state = { time: Date.now() } @@ -150,7 +150,7 @@ const Bar = <>foo; Você também pode retornar arrays de seus componentes: -```js +```jsx function Columns() { return [ Olá, @@ -161,7 +161,7 @@ function Columns() { Não se esqueça de adicionar chaves ao `Fragments` se você as criar em um loop: -```js +```jsx function Glossary(props) { return (
diff --git a/content/pt-br/guide/v10/debugging.md b/content/pt-br/guide/v10/debugging.md index 33867c0b0..e10cb5226 100644 --- a/content/pt-br/guide/v10/debugging.md +++ b/content/pt-br/guide/v10/debugging.md @@ -7,7 +7,7 @@ description: 'Como debugar aplicativos preact quando algo der errado.' O Preact é fornecido com muitas ferramentas para facilitar a depuração. Eles são empacotados em uma única importação e podem ser incluídos importando `preact / debug`. -Isso inclui uma ponte para a excelente [React Developer Tools] Extenção para o Chrome e Firefox. Se você já os tiver instalado, pode **experimentá-lo neste site.** Basta abrir os devtools e começar a inspecionar como o construímos. +Isso inclui uma ponte para a excelente [Preact Devtools] Extenção para o Chrome e Firefox. Se você já os tiver instalado, pode **experimentá-lo neste site.** Basta abrir os devtools e começar a inspecionar como o construímos. imprimiremos um aviso ou erro sempre que detectarmos algo errado, como aninhamento incorreto nos elementos ``. @@ -19,10 +19,11 @@ imprimiremos um aviso ou erro sempre que detectarmos algo errado, como aninhamen ## Intalação -O [React Developer Tools] pode ser instalado no loja de extensões do seu navegador. +O [Preact Devtools] pode ser instalado no loja de extensões do seu navegador. -- [Para o Chrome](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi) -- [Para o Firefox](https://addons.mozilla.org/en-US/firefox/addon/react-devtools/) +- [Para o Chrome](https://chrome.google.com/webstore/detail/preact-developer-tools/ilcajpmogmhpliinlbcdebhbcanbghmd) +- [Para o Firefox](https://addons.mozilla.org/en-US/firefox/addon/preact-devtools/) +- [Para o Edge](https://microsoftedge.microsoft.com/addons/detail/hdkhobcafnfejjieimdkmjaiihkjpmhk) Uma vez instalado, precisamos importar o `preact / debug` em algum lugar para inicializar a conexão com a extensão. Verifique se essa importação é **a primeira** importação em todo o aplicativo. @@ -43,7 +44,7 @@ render(, document.getElementById('root')); A maioria dos bundlers permite remover o código quando eles detectam que um ramo dentro de uma instrução `if` nunca será atingido. Podemos usar isso para incluir apenas `preact/debug` durante o desenvolvimento e salvar esses bytes preciosos em uma applição em produção. -```js +```jsx // Deve ser o primeiro import if (process.env.NODE_ENV==='development') { // Deve ser obrigatório o uso aqui, pois as instruções de importação são permitidas apenas @@ -94,7 +95,7 @@ render(, dom); O mesmo erro será gerado quando for o contrário. Quando você declara uma exportação `nomeada` e está tentando usá-la como uma exportação `padrão`. Uma maneira rápida de verificar isso (caso o seu editor ainda não o faça) é apenas desconectar a importação: -```js +```jsx // app.js export function App() { return
Olá Mundo
; @@ -175,11 +176,11 @@ function Foo() { Com o Preact X, fizemos algumas mudanças no formato interno do 'vnode'. -| Preact 8.x | Preact 10.x | -|---|---| -| `vnode.nodeName` | `vnode.type` | -| `vnode.attributes` | `vnode.props` | -| `vnode.children` | `vnode.props.children`| +| Preact 8.x | Preact 10.x | +| ------------------ | ---------------------- | +| `vnode.nodeName` | `vnode.type` | +| `vnode.attributes` | `vnode.props` | +| `vnode.children` | `vnode.props.children` | ### Encontrou filhos com a mesmas chaves @@ -208,4 +209,4 @@ const pessoas = [ ``` -[React Developer Tools]: https://github.com/facebook/react/tree/master/packages/react-devtools +[Preact Devtools]: https://preactjs.github.io/preact-devtools/ diff --git a/content/pt-br/guide/v10/extending-component.md b/content/pt-br/guide/v10/extending-component.md deleted file mode 100755 index 19f87104a..000000000 --- a/content/pt-br/guide/v10/extending-component.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -name: Extendendo Componentes -permalink: '/guide/extending-component' ---- - -# Extendendo Componentes - -É possível que alguns projetos queiram extender `Component` com funcionalidade adicional. - -Opniões sobre o valor da herança em JavaScript são variadas, mas se você deseja criar sua própria "class base" da qual todos os seus componentes herdem, Preact tem o que você precisa. - -Talvez você queira fazer conexão automática a `stores`/`reducers` dentro de uma arquitetura Flux. Talvez você queira adicionar _mixins_ baseados em propriedades para o fazer mais parecido com o `React.createClass()` _(nota: o [decorador `@bind`](https://github.com/developit/decko#bind) é preferível)_. - -Em qualquer caso, apenas use a herança de classes do ES2015 para extender a class `Component` do Preact: - - -```js -class BoundComponent extends Component { - // Exemplo: obter métodos vinculados - binds() { - let list = this.bind || [], - binds = this._binds; - if (!binds) { - binds = this._binds = {}; - for (let i=list.length; i--; ) { - binds[list[i]] = this[list[i]].bind(this); - } - } - return binds; - } -} -``` - -Exemplo de uso: - -```js -class Link extends BoundComponent { - bind = ['click']; - click() { - open(this.props.href); - } - render({ children }) { - let { click } = this.binds(); - return { children }; - } -} - -render( - Click Me, - document.body -); -``` - -As possibilidades são sem fim. Aqui, uma class `Componente` que suporta _mixins_ rudimentares: - - -```js -class MixedComponent extends Component { - constructor() { - super(); - (this.mixins || []).forEach( m => Object.assign(this, m) ); - } -} -``` - ---- - -> **Nota:** Vale a pena atentar-se de que a herança pode te prender em relacões _parent-child_ frágeis. Frequentemente quando encontra-se uma tarefa que pode ser resolvida com herança há uma maneira mais funcional de alcançar o mesmo objetivo que evitaria a criação de tal relacionamento. diff --git a/content/pt-br/guide/v10/external-dom-mutations.md b/content/pt-br/guide/v10/external-dom-mutations.md index bab2c97bf..887403b5e 100755 --- a/content/pt-br/guide/v10/external-dom-mutations.md +++ b/content/pt-br/guide/v10/external-dom-mutations.md @@ -46,7 +46,7 @@ Com esse gancho no _lifecycle_ adicionado, dizendo ao Preact para não re-render Aqui está um exemplo para "desligar" a re-renderização de com Componente. Note que `render()` ainda é invocado com parte da criação e montagem do Componente, de modo a gerar sua estrutura geral DOM. -```js +```jsx class Example extends Component { shouldComponentUpdate() { // não renderize via diff: diff --git a/content/pt-br/guide/v10/forms.md b/content/pt-br/guide/v10/forms.md index e72b2640f..570c62bff 100755 --- a/content/pt-br/guide/v10/forms.md +++ b/content/pt-br/guide/v10/forms.md @@ -107,7 +107,7 @@ Portanto, em vez de ouvir um evento `input`, devemos ouvir um evento `click`, qu ### Exemplo da caixa de seleção -```js +```jsx class MyForm extends Component { toggle = e => { let checked = !this.state.checked; diff --git a/content/pt-br/guide/v10/tutorial.md b/content/pt-br/guide/v10/tutorial.md index cffd4de87..b782370c9 100755 --- a/content/pt-br/guide/v10/tutorial.md +++ b/content/pt-br/guide/v10/tutorial.md @@ -157,7 +157,7 @@ Estrondo! Foram realizadas! Agora podemos inserir um nome personalizado, clicar Nós escrevemos nosso primeiro componente, então vamos praticar um pouco mais. Desta vez, construímos um relógio. -```js +```jsx import { h, render, Component } from 'preact'; class Clock extends Component { @@ -174,7 +174,7 @@ Ok, isso foi fácil! O problema é que o tempo não muda. Está congelado no mom Portanto, queremos que o cronômetro de 1 segundo seja iniciado assim que o componente for adicionado ao DOM e pare se for removido. Criaremos o timer e armazenaremos uma referência a ele em `componentDidMount`, e pararemos o timer em `componentWillUnmount`. Em cada marca de timer, atualizaremos o objeto `state 'do componente com um novo valor de tempo. Fazer isso renderiza automaticamente o componente. -```js +```jsx import { h, render, Component } from 'preact'; class Clock extends Component { diff --git a/content/pt-br/guide/v10/unit-testing-with-enzyme.md b/content/pt-br/guide/v10/unit-testing-with-enzyme.md index 486cd899c..3ddc08134 100644 --- a/content/pt-br/guide/v10/unit-testing-with-enzyme.md +++ b/content/pt-br/guide/v10/unit-testing-with-enzyme.md @@ -55,7 +55,7 @@ Seção [Guias](https://airbnb.io/enzyme/docs/guides.html) da documentação do Suponha que tenhamos um simples componente `Counter 'que exibe um valor inicial, com um botão para atualizá-lo: -```js +```jsx import { h } from 'preact'; import { useState } from 'preact/hooks'; @@ -75,7 +75,7 @@ export default function Counter({ initialCount }) { Usando um corredor de teste como mocha ou Jest, você pode escrever um teste para verificar se funciona como esperado: -```js +```jsx import { expect } from 'chai'; import { h } from 'preact'; import { mount } from 'enzyme'; @@ -116,7 +116,7 @@ a saída. A Enzyme possui três "modos" de renderização: -```js +```jsx import { mount, shallow, render } from 'enzyme'; // Renderiza a árvore de componentes completa: @@ -178,7 +178,7 @@ através do método `simulate`: import { act } from 'preact/test-utils'; ``` -```js +```jsx it("deve incrementar após clicar no botão 'Incrementar'", () => { const wrapper = mount(); const onClick = wrapper.find('button').props().onClick; diff --git a/content/pt-br/guide/v10/upgrade-guide.md b/content/pt-br/guide/v10/upgrade-guide.md index 58bbc9d87..a0e5ab7ee 100644 --- a/content/pt-br/guide/v10/upgrade-guide.md +++ b/content/pt-br/guide/v10/upgrade-guide.md @@ -102,7 +102,7 @@ _Nota: Esta alteração não afeta o `preact/compat`. Ele ainda tem uma exporta No Preact 8.x, `render ()` acrescenta um componente Preact quando `render ()` é repetido. No Preact X, `render ()` substitui um componente Preact existente quando `render ()` é repetido. -```js +```jsx render(

foo

, document.body); render(

bar

, document.body); @@ -114,7 +114,7 @@ render(

bar

, document.body); No Preact X, não podemos garantir que `props.children 'sempre seja do tipo` array'. Essa alteração foi necessária para resolver ambiguidades de análise em relação a `Fragmentos` e componentes que retornam um `array` de filhos. Na maioria dos casos, você pode nem perceber. Somente em lugares onde você usará métodos de array em `props.children` diretamente precisa ser envolvido com `toChildArray`. Esta função sempre retornará um array. -```js +```jsx // Preact 8.x function Foo(props) { // `.length` é um método de matriz. No Preact X, quando `props.children` não é um diff --git a/content/pt-br/index.md b/content/pt-br/index.md index e875e0032..6a972e34f 100755 --- a/content/pt-br/index.md +++ b/content/pt-br/index.md @@ -10,14 +10,10 @@ toc: false

Preact

-

Uma alternativa ao React com apenas 3kB e a mesma API ES6.

+

Uma alternativa ao React com apenas 3kB e a mesma API ES6.

- Como começar -   •   - Mudando para Preact -

-

- 5,000+ + Como começar + Mudando para Preact

@@ -35,6 +31,11 @@ function Counter() { } ``` + +

Uma biblioteca diferente.

@@ -107,7 +108,6 @@ function Counter() {
  • `props`, `state` e `context` são passados pro `render()` como parâmetro
  • Uso de atributos HTML padrão como `class` e `for`
  • -
  • Funciona com o React DevTools sem nenhuma configuração adicional
@@ -228,8 +228,7 @@ render( Escolha a melhor opção pra você!

- Como começar -   •   - Mudando para Preact + Como começar + Mudando para Preact

diff --git a/content/tr/index.md b/content/tr/index.md index 3f63fbf87..33542e341 100755 --- a/content/tr/index.md +++ b/content/tr/index.md @@ -10,18 +10,14 @@ toc: false

Preact

-

Aynı modern API ile React'e hızlı ve 3kB'lık alternatif.

+

Aynı modern API ile React'e hızlı ve 3kB'lık alternatif.

- Başlangıç -       - Preact'e Geçiş -

-

- 5,000+ + Başlangıç + Preact'e Geçiş

-```js +```jsx function Counter() { const [value, setValue] = useState(0); @@ -35,6 +31,11 @@ function Counter() { } ``` + +

Başka bir tür kütüphane.

@@ -118,7 +119,6 @@ function Counter() {
  • `props`, `state` ve `context` zaten `render()`'a paslanmış durumda.
  • `class` ve `for` gibi standart HTML attribute'larını kullanabilirsiniz.
  • -
  • Kutudan çıktığı gibi React DevTools ile çalışır.
@@ -240,8 +240,7 @@ render( Size uygun olan kılavuzu seçin!

- Başlangıç -   •   - Preact'e Geçiş + Başlangıç + Preact'e Geçiş

diff --git a/content/zh/index.md b/content/zh/index.md index 6f0275e2f..5ed11989f 100755 --- a/content/zh/index.md +++ b/content/zh/index.md @@ -10,14 +10,10 @@ toc: false

Preact

-

React 的 3kb 轻量化方案,拥有同样的 ES6 API

+

React 的 3kb 轻量化方案,拥有同样的 ES6 API

- 如何开始 -   •   - 切换到 preact -

-

- 5,000+ + 如何开始 + 切换到 preact

@@ -35,6 +31,11 @@ function Counter() { } ``` +
+

Proudly sponsored by:

+ +
+

与众不同的库

@@ -231,8 +232,7 @@ render( 选取最适合您的指导规范!

- 如何开始 -   •   - 切换到 Preact + 如何开始 + 切换到 Preact

diff --git a/size-plugin-browser.json b/size-plugin-browser.json index a7c55039b..ea722654c 100644 --- a/size-plugin-browser.json +++ b/size-plugin-browser.json @@ -1,6 +1,6 @@ [ { - "timestamp": 1581630230526, + "timestamp": 1583042842113, "files": [ { "filename": "sw-esm.js", @@ -56,24 +56,6 @@ "size": 2136, "diff": 0 }, - { - "filename": "runner.chunk.fbe16.esm.js", - "previous": 5849, - "size": 0, - "diff": -5849 - }, - { - "filename": "5.chunk.65231.css", - "previous": 1467, - "size": 1467, - "diff": 0 - }, - { - "filename": "5.chunk.2e498.esm.js", - "previous": 3382, - "size": 3382, - "diff": 0 - }, { "filename": "markdown.f1c81.worker.js", "previous": 10256, @@ -105,58 +87,70 @@ "diff": 0 }, { - "filename": "runner.chunk.0f446.js", - "previous": 5902, - "size": 0, - "diff": -5902 + "filename": "runner.chunk.cc4fb.esm.js", + "previous": 5860, + "size": 5860, + "diff": 0 }, { - "filename": "5.chunk.7d278.js", - "previous": 3456, - "size": 3456, + "filename": "runner.chunk.32860.js", + "previous": 5912, + "size": 5912, + "diff": 0 + }, + { + "filename": "5.chunk.429c6.css", + "previous": 1483, + "size": 1483, + "diff": 0 + }, + { + "filename": "5.chunk.63f0a.esm.js", + "previous": 3381, + "size": 3381, "diff": 0 }, { - "filename": "bundle.447b7.css", - "previous": 9336, - "size": 9336, + "filename": "5.chunk.13309.js", + "previous": 3455, + "size": 3455, "diff": 0 }, { - "filename": "bundle.094c0.esm.js", - "previous": 23844, + "filename": "bundle.605e4.css", + "previous": 9560, "size": 0, - "diff": -23844 + "diff": -9560 }, { - "filename": "bundle.e48e0.js", - "previous": 24260, + "filename": "bundle.89cbb.esm.js", + "previous": 24191, "size": 0, - "diff": -24260 + "diff": -24191 }, { - "filename": "bundle.00e28.esm.js", - "previous": 0, - "size": 23845, - "diff": 23845 + "filename": "bundle.cf3a7.js", + "previous": 24615, + "size": 0, + "diff": -24615 }, { - "filename": "runner.chunk.cc4fb.esm.js", + "filename": "bundle.7bfa4.css", "previous": 0, - "size": 5860, - "diff": 5860 + "size": 9684, + "diff": 9684 }, { - "filename": "bundle.80e34.js", + "filename": "bundle.6b182.esm.js", "previous": 0, - "size": 24260, - "diff": 24260 + "size": 24811, + "diff": 24811 }, { - "filename": "runner.chunk.32860.js", + "filename": "bundle.c4f1c.js", "previous": 0, - "size": 5912, - "diff": 5912 + "size": 25242, + "diff": 25242 } ] } diff --git a/size-plugin-ssr.json b/size-plugin-ssr.json index 0fe4c8910..2c0bb125c 100644 --- a/size-plugin-ssr.json +++ b/size-plugin-ssr.json @@ -1,6 +1,6 @@ [ { - "timestamp": 1581630148935, + "timestamp": 1583042762439, "files": [ { "filename": "editor.chunk.*****.js", @@ -16,15 +16,15 @@ }, { "filename": "runner.chunk.*****.js", - "previous": 5931, + "previous": 5943, "size": 5943, - "diff": 12 + "diff": 0 }, { "filename": "ssr-bundle.js", - "previous": 28285, - "size": 28286, - "diff": 1 + "previous": 28603, + "size": 29330, + "diff": 727 }, { "filename": "markdown.c9960.worker.js", @@ -51,10 +51,16 @@ "diff": 0 }, { - "filename": "ssr-bundle.8178b.css", - "previous": 11783, - "size": 11783, - "diff": 0 + "filename": "ssr-bundle.db1a2.css", + "previous": 12113, + "size": 0, + "diff": -12113 + }, + { + "filename": "ssr-bundle.2a517.css", + "previous": 0, + "size": 12287, + "diff": 12287 } ] } diff --git a/src/components/controllers/page/sidebar-nav.js b/src/components/controllers/page/sidebar-nav.js index deff66c77..93471d69c 100644 --- a/src/components/controllers/page/sidebar-nav.js +++ b/src/components/controllers/page/sidebar-nav.js @@ -1,7 +1,8 @@ -import { h } from 'preact'; +import { h, Fragment } from 'preact'; import cx from '../../../lib/cx'; import style from './sidebar-nav.less'; import { getCurrentUrl } from 'preact-router'; +import { useState, useCallback } from 'preact/hooks'; /** * @typedef {object} SidebarNavProps @@ -14,6 +15,8 @@ import { getCurrentUrl } from 'preact-router'; * @param {SidebarNavProps} props */ export default function SidebarNav({ items, onClick }) { + const [activeGroups, setActiveGroup] = useState({}); + // Remove trailing slash to fix activeCss check below. // Note that netlify will always append a slash to the url so that we end // up with something like "foo/bar/?lang=de". That's why we first remove @@ -27,18 +30,114 @@ export default function SidebarNav({ items, onClick }) { tabIndex="0" class={cx(style.toc, !(items && items.length > 1) && style.disabled)} > - {items.map(({ text, level, href }) => { - let activeCss = href === url ? style.linkActive : undefined; + {items.map(({ text, level, href, routes }) => { + if (!href) { + const headerId = `accordion_header_${text}`; + const id = `accordion_body_${text}`; + const isActive = + activeGroups[headerId] === undefined || !!activeGroups[headerId]; + routes.some(r => r.href === url); + + return ( + + + setActiveGroup({ ...activeGroups, [name]: value }) + } + > + {text} + + + + ); + } return ( - {text} - + ); })} ); } + +function SidebarGroup(props) { + const { id, level, onClick, children, isActive, controls } = props; + const onClickFn = useCallback(() => { + onClick(id, !isActive); + }, [onClick, id, isActive]); + + return ( + + ); +} + +function SidebarNavLink(props) { + const { href, onClick, level, isActive, children } = props; + let activeCss = isActive ? style.linkActive : undefined; + return ( + + {children} + + ); +} diff --git a/src/components/controllers/page/sidebar-nav.less b/src/components/controllers/page/sidebar-nav.less index 11d577b2d..b1fd61da7 100644 --- a/src/components/controllers/page/sidebar-nav.less +++ b/src/components/controllers/page/sidebar-nav.less @@ -44,6 +44,37 @@ } } +.category { + color: var(--color-sidebar-link-active); + text-transform: uppercase; + letter-spacing: 0.125em; + display: block; + margin-top: 1rem; + background: none; + border: none; + padding: 0.5rem 0; + width: 100%; + text-align: left; + cursor: pointer; + font-size: 0.9rem; + display: flex; + justify-content: space-between; + align-items: center; +} + +.accordionIcon { + transform: rotate(0); + transition: all 0.3s; + + &.active { + transform: rotate(-180deg); + } +} + +.accordionBody { + margin-top: 0.25rem; +} + .level-3 { padding-left: 2rem; } diff --git a/src/components/controllers/page/sidebar.js b/src/components/controllers/page/sidebar.js index 8a5fea184..0a56be77c 100644 --- a/src/components/controllers/page/sidebar.js +++ b/src/components/controllers/page/sidebar.js @@ -17,13 +17,38 @@ export default function Sidebar() { // Get menu items for the current version of the docs (guides) // TODO: allow multiple sections - config[meta.section] const docNav = config.docs - .filter(item => item.path.indexOf(`/v${docVersion}`) > -1) - .map(item => ({ - text: getRouteName(item, lang), - level: 2, - href: item.path - })); - + .filter(item => { + // We know that nested routes are part of the same + // doc version, so we just need to check the first + // route. + if (item.routes) { + item = item.routes[0]; + } + + return item.path.indexOf(`/v${docVersion}`) > -1; + }) + .reduce((acc, item) => { + if (item.routes) { + acc.push({ + text: getRouteName(item, lang), + level: 2, + href: null, + routes: item.routes.map(nested => ({ + text: getRouteName(nested, lang), + level: 3, + href: nested.path + })) + }); + } else { + acc.push({ + text: getRouteName(item, lang), + level: 2, + href: item.path + }); + } + return acc; + }, []); + // TODO: use URL match instead of .content const guide = config.nav.filter(item => item.content === 'guide')[0]; const sectionName = getRouteName(guide, lang); diff --git a/src/components/jumbotron/style.less b/src/components/jumbotron/style.less index 57c8db4b5..3a5c96ccf 100644 --- a/src/components/jumbotron/style.less +++ b/src/components/jumbotron/style.less @@ -9,21 +9,6 @@ // TODO: Fix specifity padding: 0 !important; - p:first-of-type { - display: inline-block; - font-size: 150%; - font-weight: 300; - line-height: 1.2; - color: white; - position: relative; - transform: translate3d(0, 0, 0); - - @media @sidebar-break { - margin: 1.6rem 1rem 1rem; - padding: 1rem; - } - } - h1 { color: #fff; text-transform: uppercase; @@ -42,6 +27,7 @@ + :global(pre.highlight) { margin-left: 1rem; margin-right: 1rem; + box-shadow: 0 5px 25px rgba(0,0,0,0.5); @media @sidebar-break { margin-left: auto; @@ -57,11 +43,11 @@ width: 100%; height: 100%; transform-origin: 0 100%; - transform: skewY(-10deg) scale(2.6) translate3d(-50%, -8%, 0); + transform: skewY(-10deg) scale(2.6) translate3d(-50%, 12%, 0); background: @color-brand; @media @sidebar-break { - transform: skewY(-6deg) scale(2.6) translate3d(-50%,-8%,0); + transform: skewY(-6deg) scale(2.6) translate3d(-50%, 22%, 0); } // TODO: Fix specifity diff --git a/src/components/logo.js b/src/components/logo.js index d4dee8b23..2bbcb516f 100644 --- a/src/components/logo.js +++ b/src/components/logo.js @@ -76,6 +76,7 @@ export default class Logo extends Component { return ( diff --git a/src/components/sponsors/index.js b/src/components/sponsors/index.js new file mode 100644 index 000000000..d7e1afca2 --- /dev/null +++ b/src/components/sponsors/index.js @@ -0,0 +1,26 @@ +import styles from './style.less'; +import AMPSvg from './amp.svg'; +import WebflowSvg from './webflow.svg'; + +/** + * Sponsors on the main page is a unique selling point of our + * gold and platinum tier on opencollective. See: + * https://opencollective.com/preact for an overview of + * available tiers and their advantages. + */ +export default function Sponsors() { + return ( + + ); +} diff --git a/src/components/sponsors/style.less b/src/components/sponsors/style.less new file mode 100644 index 000000000..845a63773 --- /dev/null +++ b/src/components/sponsors/style.less @@ -0,0 +1,49 @@ +:global(.sponsors) { + text-align: center; + margin-bottom: -2rem; + + p { + margin-bottom: 0; + } +} + +.sponsorList { + display: flex; + justify-content: center; + align-items: center; + padding: 0 !important; + margin: 1rem 0 0 0; +} + +.sponsorItem { + list-style: none; + opacity: 0.5; + transition: all 0.3s; + filter: grayscale(1); + + @media (prefers-color-scheme: dark) { + filter: brightness(0) invert(1); + } + :global(.dark) & { + filter: brightness(0) invert(1); + } + :global(.light) & { + filter: grayscale(1); + } + + &:hover { + opacity: 1; + } + + a { + text-decoration: none; + display: block; + color: transparent !important; + // Fix IE 11 border + background: none !important; + } + + & + .sponsorItem { + margin-left: 3rem; + } +} diff --git a/src/components/sponsors/webflow.svg b/src/components/sponsors/webflow.svg new file mode 100644 index 000000000..4762402e2 --- /dev/null +++ b/src/components/sponsors/webflow.svg @@ -0,0 +1,26 @@ + + + diff --git a/src/components/widgets.js b/src/components/widgets.js index 54b012c80..9e2219c30 100644 --- a/src/components/widgets.js +++ b/src/components/widgets.js @@ -4,6 +4,7 @@ import GithubStars from './github-stars'; import TodoList from './todo-list'; import Logo from './logo'; import Toc from './table-of-contents'; +import Sponsors from './sponsors'; export default { Toc, @@ -11,5 +12,6 @@ export default { Jumbotron, GithubStars, TodoList, + Sponsors, Logo }; diff --git a/src/config.json b/src/config.json index 55eaa321d..63ea159ac 100644 --- a/src/config.json +++ b/src/config.json @@ -218,142 +218,171 @@ }, { - "path": "/guide/v10/getting-started", "name": { - "en": "Getting Started", - "pt-br": "Começando", - "de": "Los geht's" - } - }, - { - "path": "/guide/v10/whats-new", - "name": { - "en": "What's new?", - "pt-br": "o que há de novo" - } - }, - { - "path": "/guide/v10/upgrade-guide", - "name": { - "en": "Upgrading from 8.x", - "pt-br": "Fazendo upgrade do 8.x", - "de": "Migration von 8.x" - } - }, - { - "path": "/guide/v10/tutorial", - "name": "Tutorial" - }, - { - "path": "/guide/v10/differences-to-react", - "name": { - "en": "Differences to React", - "pt-br": "Diferenças do React", - "de": "Unterschiede zu React" - } - }, - { - "path": "/guide/v10/switching-to-preact", - "name": { - "en": "Switching to Preact", - "pt-br": "Mudando para Preact", - "de": "Wechsel zu Preact" - } - }, - { - "path": "/guide/v10/components", - "name": { - "en": "Components", - "pt-br": "Componentes", - "de": "Komponenten" - } - }, - { - "path": "/guide/v10/hooks", - "name": "Hooks" - }, - { - "path": "/guide/v10/api-reference", - "name": { - "en": "API Reference", - "pt-br": "Referência da API", - "de": "API Referenz" - } - }, - { - "path": "/guide/v10/forms", - "name": { - "en": "Forms", - "pt-br": "Formulários", - "de": "Formulare" - } - }, - { - "path": "/guide/v10/refs", - "name": { - "en": "References", - "pt-br": "Referências", - "de": "Referenzen" - } - }, - { - "path": "/guide/v10/context", - "name": { - "en": "Context", - "pt-br": "Contexto", - "de": "Kontext" - } - }, - { - "path": "/guide/v10/external-dom-mutations", - "name": { - "en": "External DOM Mutations", - "pt-br": "Mutações do DOM externas", - "de": "Externe DOM Mutationen" - } + "en": "Introduction", + "de": "Einführung" + }, + "routes": [ + { + "path": "/guide/v10/getting-started", + "name": { + "en": "Getting Started", + "pt-br": "Começando", + "de": "Los geht's" + } + }, + { + "path": "/guide/v10/whats-new", + "name": { + "en": "What's new?", + "pt-br": "o que há de novo" + } + }, + { + "path": "/guide/v10/upgrade-guide", + "name": { + "en": "Upgrading from 8.x", + "pt-br": "Fazendo upgrade do 8.x", + "de": "Migration von 8.x" + } + }, + { + "path": "/guide/v10/tutorial", + "name": "Tutorial" + } + ] }, { - "path": "/guide/v10/debugging", "name": { - "en": "Debugging Tools", - "pt-br": "Ferramentas de depuração", - "de": "Entwickler-Tools" - } - }, - { - "path": "/guide/v10/server-side-rendering", - "name": "Server-Side Rendering" + "en": "Essentials" + }, + "routes": [ + { + "path": "/guide/v10/components", + "name": { + "en": "Components", + "pt-br": "Componentes", + "de": "Komponenten" + } + }, + { + "path": "/guide/v10/hooks", + "name": "Hooks" + }, + { + "path": "/guide/v10/forms", + "name": { + "en": "Forms", + "pt-br": "Formulários", + "de": "Formulare" + } + }, + { + "path": "/guide/v10/refs", + "name": { + "en": "References", + "pt-br": "Referências", + "de": "Referenzen" + } + }, + { + "path": "/guide/v10/context", + "name": { + "en": "Context", + "pt-br": "Contexto", + "de": "Kontext" + } + } + ] }, { - "path": "/guide/v10/extending-component", "name": { - "en": "Extending Component", - "pt-br": "Extendendo Componentes", - "de": "Komponente Erweitern" - } + "en": "Debug & Test" + }, + "routes": [ + { + "path": "/guide/v10/debugging", + "name": { + "en": "Debugging Tools", + "pt-br": "Ferramentas de depuração", + "de": "Entwickler-Tools" + } + }, + { + "path": "/guide/v10/unit-testing-with-enzyme", + "name": { + "en": "Unit Testing with Enzyme", + "pt-br": "Teste unitario com Enzyme", + "de": "Unit-Tests mit Enzyme" + } + } + ] }, { - "path": "/guide/v10/unit-testing-with-enzyme", "name": { - "en": "Unit Testing with Enzyme", - "pt-br": "Teste unitario com Enzyme", - "de": "Unit-Tests mit Enzyme" - } - }, - { - "path": "/guide/v10/web-components", - "name": "Web Components" - }, - { - "path": "/guide/v10/progressive-web-apps", - "name": "Progressive Web Apps" + "en": "React compatibility" + }, + "routes": [ + { + "path": "/guide/v10/differences-to-react", + "name": { + "en": "Differences to React", + "pt-br": "Diferenças do React", + "de": "Unterschiede zu React" + } + }, + { + "path": "/guide/v10/switching-to-preact", + "name": { + "en": "Switching to Preact", + "pt-br": "Mudando para Preact", + "de": "Wechsel zu Preact" + } + } + ] }, { - "path": "/guide/v10/options", "name": { - "en": "Options", - "de": "Optionen" - } + "en": "Advanced", + "de": "Fortgeschritten" + }, + "routes": [ + { + "path": "/guide/v10/api-reference", + "name": { + "en": "API Reference", + "pt-br": "Referência da API", + "de": "API Referenz" + } + }, + { + "path": "/guide/v10/web-components", + "name": "Web Components" + }, + { + "path": "/guide/v10/progressive-web-apps", + "name": "Progressive Web Apps" + }, + { + "path": "/guide/v10/server-side-rendering", + "name": "Server-Side Rendering" + }, + { + "path": "/guide/v10/external-dom-mutations", + "name": { + "en": "External DOM Mutations", + "pt-br": "Mutações do DOM externas", + "de": "Externe DOM Mutationen" + } + }, + { + "path": "/guide/v10/options", + "name": { + "en": "Options", + "de": "Optionen" + } + } + ] } ] } diff --git a/src/style/buttons.less b/src/style/buttons.less new file mode 100644 index 000000000..8255e38d3 --- /dev/null +++ b/src/style/buttons.less @@ -0,0 +1,40 @@ +.btn { + display: inline-block; + min-width: 16em; + padding: 0.5rem 1.5rem; + margin: 0 1rem; + box-shadow: 0 0.125rem 0 rgba(@color-brand, 0.3); + border: 0.2rem solid var(--color-btn-background); + border-radius: 0.25rem; + text-transform: uppercase; + white-space: nowrap; + letter-spacing: 0.075em; + + @media (min-width: 600px) { + padding: 0.75rem 2rem; + } + + &.primary { + background: var(--color-btn-background) !important; + color: black !important; + } + + &.secondary  { + background: transparent !important; + color: var(--color-btn-secondary) !important; + } + + .intro-buttons & { + &.secondary { + color: white !important; + } + } +} + +.btn + .btn { + margin-top: 1.3rem; + + @media (min-width: 600px) { + margin-top: 0; + } +} diff --git a/src/style/home.less b/src/style/home.less new file mode 100644 index 000000000..e6158fec3 --- /dev/null +++ b/src/style/home.less @@ -0,0 +1,9 @@ +.tagline { + display: block; + font-size: 1.5rem; + font-weight: 300; + line-height: 1.2; + color: white; + text-align: center; + margin: 3rem 0 3.5rem; +} diff --git a/src/style/index.less b/src/style/index.less index 11033cfcf..318614dbb 100755 --- a/src/style/index.less +++ b/src/style/index.less @@ -1,17 +1,21 @@ @import './helpers'; @import './reset'; +@import './buttons'; @import './markdown'; @import './gh-btn'; @import './list-view'; @import './prism.css'; @import './variables'; +@import './home'; // The following two classes may seem redundant, but they allow us to overwrite // the scheme defined by the browser if the user wants to. html.light { --color-page-bg: white; --color-text: #444; - --color-home-btn: #673ab8; + --color-btn: #673ab8; + --color-btn-secondary: #673ab8; + --color-btn-background: #eee; --color-heading: black; --color-link: #673ab8; --color-hr: #f8f8f8; @@ -47,7 +51,9 @@ html.dark { --color-text: #b0b0b0; --color-heading: #c5c5c5; --color-link: #ae80ff; - --color-home-btn: #673ab8; + --color-btn: #673ab8; + --color-btn-secondary: white; + --color-btn-background: #eee; --color-hr: #444; --color-quote-bg: #29475f; --color-quote-border: #3f6b9c; @@ -217,26 +223,16 @@ main .markup { display: flex; flex-direction: column; align-items: center; + margin-bottom: 3rem; @media (min-width: 600px) { flex-direction: row-reverse; justify-content: center; align-items: initial; - } - - .home-button + .home-button { - margin-top: 1.3rem; - - @media (min-width: 600px) { - margin-top: 0; - } + margin-bottom: 4.5rem; } } - .home-button { - margin: 0 1rem; - } - .home-demo { padding: 20px; background: #f8f8f8; @@ -315,32 +311,6 @@ main .markup { } } -.home-button { - display: inline-block; - min-width: 12em; - padding: 0.5em 0.9em; - background: #eee !important; - box-shadow: 0 2px 0 rgba(@color-brand, 0.3); - border: none; - border-radius: 4px; - color: var(--color-home-btn) !important; - font-weight: bold; - text-transform: uppercase; - white-space: nowrap; - - & + .home-button-sep + .home-button { - @media (max-width: 600px) { - margin-top: 1.3rem; - } - } -} - -.home-button-sep { - @media (max-width: 600px) { - display: none; - } -} - @break-s: ~'(min-width: 700px)'; // Styles for a typical media/flag layout where you have one image on the left diff --git a/src/style/markdown.less b/src/style/markdown.less index 4f25159b6..aba29f3a2 100644 --- a/src/style/markdown.less +++ b/src/style/markdown.less @@ -40,6 +40,7 @@ padding: 0; font-weight: bold; cursor: text; + position: relative; &:hover a.anchor { text-decoration: none; @@ -49,6 +50,7 @@ &:before { content: ''; display: block; + position: absolute; height: @header-height; margin: -@header-height 0 0; } diff --git a/src/style/variables.less b/src/style/variables.less index ff7671181..bc0fa2b3d 100644 --- a/src/style/variables.less +++ b/src/style/variables.less @@ -22,7 +22,9 @@ --color-text: #444; --color-heading: black; --color-link: #673ab8; - --color-home-btn: #673ab8; + --color-btn: #673ab8; + --color-btn-secondary: #673ab8; + --color-btn-background: #eee; --color-hr: #f8f8f8; --color-quote-bg: #ebf6ff; --color-quote-border: #5aa8ff; @@ -55,7 +57,9 @@ --color-text: #b0b0b0; --color-heading: #c5c5c5; --color-link: #ae80ff; - --color-home-btn: #673ab8; + --color-btn: #673ab8; + --color-btn-secondary: white; + --color-btn-background: #eee; --color-hr: #444; --color-quote-bg: #29475f; --color-quote-border: #3f6b9c;