Skip to content

Commit

Permalink
Update README
Browse files Browse the repository at this point in the history
  • Loading branch information
jho406 committed Oct 8, 2023
1 parent 5a7fb0f commit 1664d9d
Show file tree
Hide file tree
Showing 19 changed files with 409 additions and 294 deletions.
16 changes: 14 additions & 2 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,20 @@

All notable changes to this project will be documented in this file.

## 0.50
Updates generators to use redux starter kit. Superglue will also generate
a few handy slices for use. Generators will also use a new Rails helper
[form_props](https://github.com/thoughtbot/form_props) to make building
forms as easy as `form_with`

Move flash to a slice. This is a backward breaking change, to transition
see this [PR](https://github.com/thoughtbot/superglue/pull/25) for details
on how to transition to a slice.

Readme updated and non-working links fixed.

## 0.40
Scroll history and cache restore strategies (`fromCacheOnly`, `revisitOnly`,
Scroll history and cache restore strategies (`fromCacheOnly`, `revisitOnly`,
`fromCacheAndRevisitInBackground` default) added.

`history` npm package upgraded.
Expand All @@ -12,7 +24,7 @@ Scroll history and cache restore strategies (`fromCacheOnly`, `revisitOnly`,
Project renamed to superglue

## 0.20
Added back the `props_from_form_with` helper and update to use latest
Added back the `props_from_form_with` helper and update to use latest
html-dom-parser.

## 0.19
Expand Down
15 changes: 6 additions & 9 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ Use classic Rails to build rich React Redux applications with **NO APIs** and

[![Build Status](https://circleci.com/gh/thoughtbot/superglue.svg?style=shield)](https://circleci.com/gh/thoughtbot/superglue)

Superglue is a React Redux starter and library inspired by Turbolinks and designed
to complement classic Rails. You can enjoy the benefits of Redux state
management and React components without giving up the productivity of Rails form
helpers, UJS, tag helpers, the flash, cookie auth, and more.
Superglue makes React and Redux equally as productive as Hotwire, Turbo and
Stimulus. Its inspired by Turbolinks and designed to feel like a natural
extension of Rails. Enjoy the benefits of Redux state management and React
components without giving up the productivity of Rails form helpers, UJS,
tag helpers, flash, cookie auth, and more.

## Caution

Expand Down Expand Up @@ -67,7 +68,6 @@ The above will request for `/posts` with an `accept` of `application/json`, and
when the client receives the response, swap out the current component for the
component the response asks for, and `pushState` on history.


#### Partial updates
Some features rely on updating some parts of the existing page. In
addition to `data-sg-visit` and it's equivalent `this.props.visit`, Superglue
Expand Down Expand Up @@ -106,9 +106,8 @@ Documentation is hosted on [Github pages](https://thoughtbot.github.io/superglue

## Contributing

See the [CONTRIBUTING] document. Thank you, [contributors]!
Thank you, [contributors]!

[CONTRIBUTING]: CONTRIBUTING.md
[contributors]: https://github.com/thoughtbot/superglue/graphs/contributors

## Special Thanks
Expand All @@ -118,5 +117,3 @@ Thanks to [jbuilder](https://github.com/rails/jbuilder),
[turbolinks3](https://github.com/turbolinks/turbolinks-classic),
[turbograft](https://github.com/Shopify/turbograft/),
[turbostreamer](https://github.com/malomalo/turbostreamer)


2 changes: 1 addition & 1 deletion docs/_sidebar.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

- [Navigation](navigation.md)
- [Template querying](traversal-guide.md)
- [Updating fragments](updating-fragments.md)
- [Updating fragments](fragments-and-slices.md#fragments)

- API
- [React Redux](react-redux.md)
Expand Down
13 changes: 5 additions & 8 deletions docs/demo.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
# Demo Application

We have a non-trivial [demo] application built using SuperglueJS and the original
[Rails and StimulusJS] version built by the talented [Sean Doyle] The intent is
to help you compare and contrast both approaches and showcase how enjoyable and
We have a non-trivial [demo] application built using Superglue and the original
[Rails and StimulusJS] version built by [Sean Doyle] The intent is to help you
compare and contrast both approaches and showcase how enjoyable and
Rails-like Superglue/React/Redux can be.

![Demo App](images/demo.jpg)

We recommend going over the meticously verbose commit history on [Sean's
version] and comparing that with the [Superglue version].

[demo]: https://github.com/thoughtbot/select-your-own-seat
[demo]: https://github.com/thoughtbot/select-your-own-seat-superglue
[Rails and StimulusJS]: https://github.com/seanpdoyle/select-your-own-seat
[Sean Doyle]: https://github.com/seanpdoyle
[Sean's version]: https://github.com/seanpdoyle/select-your-own-seat/commits/main
[Superglue version]: https://github.com/thoughtbot/select-your-own-seat/commits/superglue_019



[Superglue version]: https://github.com/thoughtbot/select-your-own-seat-superglue/commits/superglue
197 changes: 197 additions & 0 deletions docs/fragments-and-slices.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
# Fragments and Slices

When building pages, we commonly use partials to extract crosscutting concerns.
For example, a shared header:

```
views/
application/
_header.json.props
posts/
index.json.props
comments/
index.json.props
```

By [design](./redux-state-shape.md) this results in duplicate JSON nodes
across our `pages` slice:

```json
{
pages: {
"/posts": {
data: {
header: {
email: "foo@foo.com"
}
}
},
"/comments": {
data: {
header: {
email: "foo@foo.com"
}
}
},
}
}
```

Superglue fragments, and Redux slices are two recommended ways for updating cross-cutting
concerns.

# Fragments

A fragment in Superglue is a rendered partial with a given name:

```
json.body do
json.side_bar partial: ["application/side_bar", fragment: "some_user_side_bar_type"]
end
```

By indicating that a partial is a fragment, we store the name of the fragment,
and the path where it was found. This metadata is then rendered at the top
level of the [page response].

This has been set up for you in `application.json.props`:

```ruby
json.data(search: path) do
yield json
end

json.fragments json.fragments!
```

The resulting JSON looks like this:

```json
data: {
...
},
fragments: [
{ type: :some_user_side_bar_type, partial: 'application/side_bar', path: 'body.sidebar' },
]
```

?> Fragments used in nodes that are [deferred](./navigation.md#deferments) do
not show up inside the metadata until the deferred nodes are loaded.

## Automatic updates

Fragments are automatically updated in two cases:

1. When a new page loads with a fragment Superglue will look at the page store and
update nodes marked with the same fragment name across all pages. For example,
a header that appears across multiple pages. This is similar to the idea of
a [Turbo-Frame](https://turbo.hotwired.dev/handbook/frames).

2. If you use a custom reducer to update the fragment, fragments of the same
name across all pages will also update. This behavior is controlled by a
`fragmentMiddleware`. This is included when generating a superglue app in
your `store.js` file.

You can turn this behavior off by removing the middleware.

## Slices

Fragments are a lightweight solution to updating cross cutting concerns. With
more complex needs, a Redux slice is recommended. Superglue has a few helpers
that can make this process easier.

### InitialState
You can render your slice's initial state in the [slices] `key` of the page
object, it'll be merged with the `initialState` passed to your `buildStore`
function in your [application.js](./react-redux.md#applicationbase)


### extraReducers
Use Superglue's redux actions in your slice's [extraReducers] to modify state
in response to lifecycle events. The `flashSlice` that was generated
with the installation is a good example of this.

`BEFORE_FETCH` - Action created before a before a fetch is called.

```
{
type: "@@superglue/BEFORE_FETCH",
payload: [..array args that are passed to fetch]
}
```

`BEFORE_VISIT` - Same as above, but called only for a [visit] action.

```
{
type: "@@superglue/BEFORE_VISIT",
payload: [..array args that are passed to fetch]
}
```

`BEFORE_REMOTE` - Same as above, but called only a [remote] action.

```
{
type: "@@superglue/BEFORE_REMOTE",
payload: [..array args that are passed to fetch]
}
```

`SAVE_RESPONSE` - Whenever a [page response] is received.

```
{
type: "@@superglue/SAVE_RESPONSE",
payload: {
pageKey: "/posts",
page: {...the page response},
},
}
```

`UPDATE_FRAGMENTS` - Whenever a fragment is recieved or changed.

```
{
type: "@@superglue/UPDATE_FRAGMENTS",
payload: {
changedFragments: {
nameOfYourFragment: renderedFragment,
...
},
},
}
```

### Turning a fragment into a slice

Whenever a fragment is received or updated `UPDATE_FRAGMENTS` is called.
You can pass the state from the payload to your slice to keep it updated.

For example:
```javascript
import { createSlice, createAction } from '@reduxjs/toolkit'
import { UPDATE_FRAGMENTS } from '@thoughtbot/superglue'
export const updateFragments = createAction(UPDATE_FRAGMENTS)

export const cartSlice = createSlice({
name: 'cart',
initialState: {},
extraReducers: (builder) => {
builder.addCase(updateFragments, (state, action) => {
const { changedFragments } = action.payload;

if ('cart' in changedFragments) {
return changedFragments['cart'];
} else {
return state;
}
})
}
})
```

[page response]: ./page-response.md
[slices]: ./page-response.md#slices
[extraReducers]: https://redux-toolkit.js.org/api/createSlice#extrareducers
18 changes: 1 addition & 17 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@

## Installation

If using Rails 6, ensure you have Webpacker and React installed. If using
Rails 7, ensure you are using esbuild (enabled with JSX in `.js`) and
have React installed.
Ensure you are using esbuild (enabled with JSX in `.js`)


Add the following to your Gemfile and run bundle.
Expand Down Expand Up @@ -42,19 +40,5 @@ The `visit` and `remote` thunks can be customized in
`app/javascript/packs/application_visit.js`. Functionality like loading
indicators can be added there.

## Configuring Reloads

Superglue will do a hard reload whenever a successful response returns new asset
fingerprints. Add an initializer to control how Superglue tracks Sprockets and
Webpack assets:

```ruby
# defaults
Superglue.configure do |config|
config.track_sprockets_assets = ['application.js', 'application.css']
config.track_pack_assets = ['application.js']
end
```


[preconfigured entry point]: https://github.com/thoughtbot/Superglue/blob/main/superglue_rails/lib/install/templates/web/application.js
4 changes: 2 additions & 2 deletions docs/navigation.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Navigation

Navigation is [inspired by turbolinks](./concepts#inspired-by-turbolinks).
Navigation is [inspired by turbolinks](./concepts.md#inspired-by-turbolinks).

## Visit and Remote

Expand Down Expand Up @@ -167,5 +167,5 @@ end
```

[one visit]: ./react-redux.md#visit
[data attribute]: ./react-redux#data-sg-visit
[data attribute]: ./react-redux.md#data-sg-visit

Loading

0 comments on commit 1664d9d

Please sign in to comment.