Skip to content

Commit 9e2f3bd

Browse files
committed
bunch of doc updates
1 parent 367ffea commit 9e2f3bd

13 files changed

+300
-1384
lines changed

docs/SUMMARY.md

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,27 +9,31 @@
99
* [Routing and Mounting Components](rails-installation/routing-and-mounting-components.md)
1010
* [Other Rails Configuration Details](rails-installation/other-details.md)
1111
* [Why Rails? Other Frameworks?](rails-installation/why-rails.md)
12-
* [Client DSL](client-dsl/README.md)
13-
* [HTML & CSS DSL](client-dsl/html-css.md)
14-
* [Component DSL](client-dsl/component-basics.md)
12+
* [HyperComponent](client-dsl/README.md)
13+
* [Component Classes](client-dsl/component-basics.md)
14+
* [HTML Tags & CSS Classes](client-dsl/html-css.md)
1515
* [Component Children, Keys and Fragments](client-dsl/component-details.md)
16+
* [Component Params](client-dsl/params.md)
1617
* [Lifecycle Methods](client-dsl/lifecycle-methods.md)
17-
* [State](client-dsl/state.md)
18-
* [Event Handlers](client-dsl/event-handlers.md)
18+
* [Component State](client-dsl/state.md)
19+
* [Events and Callbacks](client-dsl/events-and-callbacks.md)
20+
* [Recovering from Errors](client-dsl/error-recovery.md)
1921
* [JavaScript Components](client-dsl/javascript-components.md)
20-
* [Client-side Routing](client-dsl/hyper-router.md)
21-
* [Stores](client-dsl/hyper-store.md)
2222
* [Elements and Rendering](client-dsl/elements-and-rendering.md)
23-
* [Further Reading](client-dsl/further-reading.md)
24-
* [List of Predefined Tags and Components](client-dsl/predefined-tags.md)
23+
* [Summary of Methods](client-dsl/methods.md)
24+
* [List of Predefined Tags & Components](client-dsl/predefined-tags.md)
25+
* [Predefined Events](client-dsl/predefined-events.md)
2526
* [Notes](client-dsl/notes.md)
26-
* [Isomorphic DSL](isomorphic-dsl/README.md)
27+
* [Further Reading](client-dsl/further-reading.md)
28+
* [HyperState](hyper-state/README.md)
29+
* [HyperRouter](hyper-router/README.md)
30+
* [HyperModel](isomorphic-dsl/README.md)
2731
* [Isomorphic Models](isomorphic-dsl/hyper-model.md)
28-
* [Isomorphic Operations](isomorphic-dsl/hyper-operation.md)
32+
* [Isomorphic Operations](isomorphic-dsl/hyper-operation.md)
2933
* [Policies](isomorphic-dsl/hyper-policy.md)
34+
* [Internationalization](development-workflow/hyper-i18n.md)
3035
* [Development Workflow](development-workflow/README.md)
3136
* [Debugging](development-workflow/debugging.md)
32-
* [Internationalization](development-workflow/hyper-i18n.md)
3337
* [HyperSpec](development-workflow/hyper-spec/README.md)
3438
* [Installation](development-workflow/hyper-spec/01-installation.md)
3539
* [Tutorial](development-workflow/hyper-spec/02-tutorial.md)

docs/client-dsl/README.md

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
1-
# Client DSL
2-
3-
## Hyperstack Component Classes and DSL
4-
51
Your Hyperstack Application is built from a series of *Components* which are Ruby Classes that display portions of the UI. Hyperstack Components are implemented using [React](https://reactjs.org/), and can interoperate with existing React components and libraries. Here is a simple example that displays a ticking clock:
62

73
```ruby
84
# Components inherit from the HyperComponent base class
95
# which supplies the DSL to translate from Ruby into React
106
# function calls
117
class Clock < HyperComponent
12-
# before_mount is an example of a life cycle method.
13-
before_mount do
14-
# before the component is first rendered (mounted)
8+
# Components can be parameterized.
9+
# in this case you can override the default
10+
# with a different format
11+
param format: "%m/%d/%Y %I:%M:%S"
12+
# After_mount is an example of a life cycle method.
13+
after_mount do
14+
# Before the component is first rendered (mounted)
1515
# we setup a periodic timer that will update the
1616
# current_time instance variable every second.
17+
# The mutate method signals a change in state
1718
every(1.second) { mutate @current_time = Time.now }
1819
end
1920
# every component has a render block which describes what will be
@@ -22,21 +23,9 @@ class Clock < HyperComponent
2223
# Components can render other components or primitive HTML or SVG
2324
# tags. Components also use their state to determine what to render,
2425
# in this case the @current_time instance variable
25-
DIV { @current_time.strftime("%m/%d/%Y %I:%M:%S")
26+
DIV { @current_time.strftime(format) }
2627
end
2728
end
2829
```
2930

30-
This documentation will cover the following core concepts, many of which
31-
are touched on in the above simple example:
32-
33-
+ [HTML & CSS DSL](html-css.md) which provides Ruby implementations of all of the HTML and CSS elements
34-
+ [The Component DSL](components.md) is a Ruby DSL which wraps ReactJS Components
35-
+ [Lifecycle Methods](lifecycle-methods.md) are methods which are invoked before, during and after rendering
36-
+ [State](state.md) - components rerender as needed when state changes.
37-
+ [Event Handlers](event-handlers.md) allow any HTML element or Component to respond to an event, plus custom events can be described.
38-
+ [JavaScript Components](javascript-components.md) access to the full universe of JS libraries in your Ruby code
39-
+ [Client-side Routing](hyper-router.md) a Ruby DSL which wraps ReactRouter
40-
+ [Stores](hyper-store.md) for application level state and Component communication
41-
+ [Elements and Rendering](elements-and-rendering.md) details of the underlying mechanisms.
42-
+ [Further Reading](further-reading.md) on React and Opal
31+
The following chapters cover these aspects and more in detail.

docs/client-dsl/component-basics.md

Lines changed: 69 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,6 @@
1-
# HyperComponent DSL - Basics
2-
31
The Hyperstack Component DSL is a set of class and instance methods that are used to describe React components and render the user-interface.
42

5-
The DSL has the following major areas:
6-
7-
* The `HyperComponent` class
8-
* HTML DSL elements
9-
* Component Lifecycle Methods \(`before_mount`, `after_mount`, `after_update`\)
10-
* The `param` and `render` methods
11-
* Event handlers
12-
* Miscellaneous methods
3+
The following sections give a brief orientation to the structure of a component and the methods that are used to define and control its behavior.
134

145
## Defining a Component
156

@@ -24,7 +15,7 @@ end
2415
2516
## The `render` Callback
2617

27-
At a minimum every *concrete* component class must define a `render` block which generates one or more child elements. Those children may in turn have an arbitrarily deep structure. **[More on concrete and abstract components](notes.md#abstract-and-concrete-components)**
18+
At a minimum every *concrete* component class must define a `render` block which generates one or more child elements. Those children may in turn have an arbitrarily deep structure. **[More on concrete and abstract components...](notes.md#abstract-and-concrete-components)**
2819

2920
```ruby
3021
class Component < HyperComponent
@@ -55,9 +46,7 @@ class FirstComponent < HyperComponent
5546
end
5647
```
5748

58-
Note that you should never redefine the `new` or `initialize` methods, or call them directly. The equivalent of `initialize` is the `before_mount` method.
59-
60-
> The one exception to using `new` is within a spec to create a "headless" component in order to access its internal state and methods.
49+
> While a component is defined as a class, and a rendered component is an instance of that class, we do not in general use the `new` method, or need to modify the components `initialize` method.
6150
6251
### Invoking Components
6352

@@ -68,15 +57,76 @@ MyCustomComponent {} # ok
6857
MyCustomComponent # <--- breaks
6958
> ```
7059
71-
## Multiple Components
60+
## Component Params
61+
62+
A component can receive params to customize its look and behavior:
63+
64+
```Ruby
65+
class SayHello < HyperComponent
66+
param :to
67+
render(DIV, class: :hello) do
68+
"Hello #{to}!"
69+
end
70+
end
71+
72+
...
73+
74+
SayHello(to: "Joe")
75+
```
76+
77+
Components can receive new params, causing the component to update. **[More on Params ...](params.md)**.
78+
79+
## Component State
80+
81+
Component also have *state*, which is stored in instance variables. You signal a state change using the `mutate` method. Component state is a fundamental concept covered **[here](state.md)**.
82+
83+
84+
## Life Cycle Callbacks
85+
86+
A component may be updated during its life time due to either changes in state or receiving new params. You can hook into the components life cycle using the
87+
the life cycle methods. Two of the most common lifecycle methods are `before_mount` and `after_mount` that are called before a component first renders, and
88+
just after a component first renders respectively.
89+
90+
```RUBY
91+
class Clock < HyperComponent
92+
param format: "%m/%d/%Y %I:%M:%S"
93+
after_mount do
94+
every(1.second) { mutate @current_time = Time.now }
95+
end
96+
render do
97+
DIV { @current_time.strftime(format) }
98+
end
99+
end
100+
```
101+
102+
The complete list of life cycle methods and their syntax is discussed in detail in the **[Lifecycle Methods](/lifecycle-methods)** section.
103+
104+
## Events, Event Handlers, and Component Callbacks
105+
106+
Events such as mouse clicks trigger callbacks, which can be attached using the `on` method:
107+
108+
```ruby
109+
class ClickCounter < HyperComponent
110+
before_mount { @clicks = 0 }
111+
def adverb
112+
@clicks.zero? ? 'please' : 'again'
113+
end
114+
render(DIV) do
115+
BUTTON { "click me #{adverb}" }
116+
.on(:click) { mutate @clicks += 1 } # attach a callback
117+
DIV { "I've been clicked #{pluralize(@clicks, 'time')}" } if @clicks > 0
118+
end
119+
end
120+
```
72121

73-
So far, we've looked at how to write a single component to display data. Next let's examine how components are combined to build an application.
122+
This example also shows how events and state mutations work together to change the look of the display. It also demonstrates that because a HyperComponent
123+
is just a Ruby class you can define helper methods, use conditional logic, and call on predefined methods like `pluralize`.
74124

75-
By building modular components that reuse other components with well-defined interfaces you can _separate the different concerns_ of your app. By building a custom component library for your application, you are expressing your UI in a way that best fits your domain.
125+
In addition components can fire custom events, and make callbacks to the upper level components. **[More details ...](events-and-callbacks.md)**
76126

77-
### Composition Example
127+
## Application Structure
78128

79-
Let's create a simple Avatar component which shows a profile picture and username using the Facebook Graph API.
129+
Your Application is built out of many smaller components using the above features to control the components behavior and communicate between components. To conclude this section let's create a simple Avatar component which shows a profile picture and username using the Facebook Graph API.
80130

81131
```ruby
82132
class Avatar < HyperComponent

0 commit comments

Comments
 (0)