Skip to content

Commit 8aa14c4

Browse files
skryukovbknoles
authored andcommitted
Docs: add Available since component
1 parent 65f1175 commit 8aa14c4

File tree

8 files changed

+369
-12
lines changed

8 files changed

+369
-12
lines changed
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import MarkdownIt from 'markdown-it'
2+
3+
export interface AvailableSinceParams {
4+
rails?: string
5+
core?: string
6+
description?: string
7+
}
8+
9+
function parseAvailableSinceParams(info: string): AvailableSinceParams {
10+
const basicMatch = info.trim().match(/^available_since(?:\s+(.*))?$/)
11+
if (!basicMatch) return {}
12+
13+
const allParams = basicMatch[1] || ''
14+
const params: AvailableSinceParams = {}
15+
16+
// Parse out key=value pairs first
17+
const keyValueMatches = [...allParams.matchAll(/([a-z]+)(?:=("[^"]*"|[^\s"]+))?/g)]
18+
for (const [, key, value] of keyValueMatches) {
19+
let cleanValue = value ? value.replace(/^"|"$/g, '') : true
20+
21+
if (key === 'rails') params.rails = cleanValue as string
22+
if (key === 'core') params.core = cleanValue as string
23+
if (key === 'description') params.description = cleanValue as string
24+
}
25+
26+
return params
27+
}
28+
29+
export function availableSinceMarkdownPlugin(md: MarkdownIt) {
30+
md.block.ruler.before('paragraph', 'available_since_oneliner', (state, start, end, silent) => {
31+
const line = state.getLines(start, start + 1, 0, false).trim()
32+
33+
const match = line.match(/^@available_since\s+(.+)$/)
34+
if (!match) return false
35+
36+
if (silent) return true
37+
38+
const params = parseAvailableSinceParams(`available_since ${match[1]}`)
39+
const token = state.push('available_since_oneliner', '', 0)
40+
41+
token.content = renderAvailableSince(params, md)
42+
token.map = [start, start + 1]
43+
44+
state.line = start + 1
45+
return true
46+
})
47+
48+
// Render the one-liner available_since token
49+
md.renderer.rules.available_since_oneliner = (tokens, idx) => {
50+
return tokens[idx].content + '\n'
51+
}
52+
}
53+
54+
function renderAvailableSince(params: AvailableSinceParams, md: MarkdownIt): string {
55+
const railsAttr = params.rails ? `rails="${md.utils.escapeHtml(params.rails)}"` : ''
56+
const coreAttr = params.core ? `core="${md.utils.escapeHtml(params.core)}"` : ''
57+
const descriptionAttr = params.description ? `description="${md.utils.escapeHtml(params.description)}"` : ''
58+
59+
return `<AvailableSince ${railsAttr} ${coreAttr} ${descriptionAttr} />`
60+
}

docs/.vitepress/config.mts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { defineConfig } from 'vitepress'
22
import llmstxt from 'vitepress-plugin-llms'
3+
import { availableSinceMarkdownPlugin } from './availableSinceMarkdownPlugin'
34
import { tabsMarkdownPlugin } from './vitepress-plugin-tabs/tabsMarkdownPlugin'
45

56
const title = 'Inertia Rails'
@@ -25,6 +26,7 @@ export default defineConfig({
2526
markdown: {
2627
config(md) {
2728
md.use(tabsMarkdownPlugin)
29+
md.use(availableSinceMarkdownPlugin)
2830
},
2931
},
3032

docs/.vitepress/theme/components/AvailableSince.vue

Lines changed: 257 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import AvailableSince from './AvailableSince.vue'
2+
3+
export {
4+
AvailableSince,
5+
}

docs/.vitepress/theme/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type { Theme } from 'vitepress'
33
import { enhanceAppWithTabs } from 'vitepress-plugin-tabs/client'
44
import DefaultTheme from 'vitepress/theme'
55
import { h } from 'vue'
6+
import { AvailableSince } from './components'
67
import { setupFrameworksTabs } from './frameworksTabs'
78
import './style.css'
89

@@ -15,6 +16,7 @@ export default {
1516
},
1617
enhanceApp({ app, router, siteData }) {
1718
enhanceAppWithTabs(app)
19+
app.component('AvailableSince', AvailableSince)
1820
},
1921
setup() {
2022
setupFrameworksTabs()

docs/guide/configuration.md

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,38 +46,44 @@ Use `component_path_resolver` to customize component path resolution when [`defa
4646

4747
### `deep_merge_shared_data`
4848

49-
**Default**: `false`
49+
**Default**: `false`
5050
**ENV**: `INERTIA_DEEP_MERGE_SHARED_DATA`
5151

52+
@available_since rails=3.8.0
53+
5254
When enabled, props will be deep merged with shared data, combining hashes
5355
with the same keys instead of replacing them.
5456

5557
### `default_render`
5658

57-
**Default**: `false`
59+
**Default**: `false`
5860
**ENV**: `INERTIA_DEFAULT_RENDER`
5961

6062
Overrides Rails default rendering behavior to render using Inertia by default.
6163

6264
### `encrypt_history`
6365

64-
**Default**: `false`
66+
**Default**: `false`
6567
**ENV**: `INERTIA_ENCRYPT_HISTORY`
6668

69+
@available_since rails=3.7.0 core=2.0.0
70+
6771
When enabled, you instruct Inertia to encrypt your app's history, it uses
6872
the browser's built-in [`crypto` api](https://developer.mozilla.org/en-US/docs/Web/API/Crypto)
6973
to encrypt the current page's data before pushing it to the history state.
7074

7175
### `ssr_enabled` _(experimental)_
7276

73-
**Default**: `false`
77+
**Default**: `false`
7478
**ENV**: `INERTIA_SSR_ENABLED`
7579

80+
@available_since rails=3.6.0 core=2.0.0
81+
7682
Whether to use a JavaScript server to pre-render your JavaScript pages,
7783
allowing your visitors to receive fully rendered HTML when they first visit
7884
your application.
7985

80-
Requires a JS server to be available at `ssr_url`. [_Example_](https://github.com/ElMassimo/inertia-rails-ssr-template)
86+
Requires a JavaScript server to be available at `ssr_url`. [_Example_](https://github.com/ElMassimo/inertia-rails-ssr-template)
8187

8288
### `ssr_url` _(experimental)_
8389

docs/guide/deferred-props.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# Deferred props
22

3+
@available_since rails=3.6.0 core=2.0.0
4+
35
Inertia's deferred props feature allows you to defer the loading of certain page data until after the initial page render. This can be useful for improving the perceived performance of your app by allowing the initial page render to happen as quickly as possible.
46

57
## Server side

docs/guide/merging-props.md

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,31 +4,52 @@ By default, Inertia overwrites props with the same name when reloading a page. H
44

55
## Server side
66

7-
> `deep_merge` requires `@inertiajs/core` v2.0.8 or higher, and `inertia_rails` v3.8.0 or higher.
7+
### Using `merge`
88

9-
To specify that a prop should be merged, use the `merge` or `deep_merge` method on the prop's value.
9+
@available_since rails=3.8.0 core=2.0.8
1010

11-
Use `merge` for merging simple arrays, and `deep_merge` for handling nested objects that include arrays or complex structures, such as pagination objects.
11+
To specify that a prop should be merged, use the `merge` method on the prop's value. This is ideal for merging simple arrays.
12+
13+
On the client side, Inertia detects that this prop should be merged. If the prop returns an array, it will append the response to the current prop value. If it's an object, it will merge the response with the current prop value.
1214

1315
```ruby
1416
class UsersController < ApplicationController
1517
include Pagy::Backend
1618

1719
def index
18-
pagy, records = pagy(User.all)
20+
_pagy, records = pagy(User.all)
1921

2022
render inertia: {
2123
# simple array:
2224
users: InertiaRails.merge { records.as_json(...) },
25+
# with match_on parameter for smart merging:
26+
products: InertiaRails.merge(match_on: 'id') { Product.all.as_json(...) },
27+
}
28+
end
29+
end
30+
```
31+
32+
### Using `deep_merge`
33+
34+
@available_since rails=3.8.0 core=2.0.8
35+
36+
For handling nested objects that include arrays or complex structures, such as pagination objects, use the `deep_merge` method.
37+
38+
```ruby
39+
class UsersController < ApplicationController
40+
include Pagy::Backend
41+
42+
def index
43+
pagy, records = pagy(User.all)
44+
45+
render inertia: {
2346
# pagination object:
2447
data: InertiaRails.deep_merge {
2548
{
2649
records: records.as_json(...),
2750
pagy: pagy_metadata(pagy)
2851
}
2952
},
30-
# with match_on parameter for smart merging:
31-
products: InertiaRails.merge(match_on: 'id') { Product.all.as_json(...) },
3253
# nested objects with match_on:
3354
categories: InertiaRails.deep_merge(match_on: %w[items.id tags.id]) {
3455
{
@@ -41,10 +62,12 @@ class UsersController < ApplicationController
4162
end
4263
```
4364

44-
On the client side, Inertia detects that this prop should be merged. If the prop returns an array, it will append the response to the current prop value. If it's an object, it will merge the response with the current prop value. If you have opted to `deepMerge`, Inertia ensures a deep merge of the entire structure.
65+
If you have opted to use `deep_merge`, Inertia ensures a deep merge of the entire structure, including nested objects and arrays.
4566

4667
### Smart merging with `match_on`
4768

69+
@available_since rails=master core=2.0.13
70+
4871
By default, arrays are simply appended during merging. If you need to update specific items in an array or replace them based on a unique identifier, you can use the `match_on` parameter.
4972

5073
The `match_on` parameter enables smart merging by specifying a field to match on when merging arrays of objects:

0 commit comments

Comments
 (0)