-
Notifications
You must be signed in to change notification settings - Fork 69
[Feature] Add a configuration option to transform props coming from Inertia #254
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
b4ac3e9
3f4c09d
8caa288
b5a83b4
720e3eb
43ec284
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -90,10 +90,13 @@ def merge_props(shared_props, props) | |
end | ||
|
||
def computed_props | ||
merged_props = merge_props(shared_data, props) | ||
deep_transform_props(merged_props).tap do |transformed_props| | ||
transformed_props[:_inertia_meta] = meta_tags if meta_tags.present? | ||
end | ||
merge_props(shared_data, props) | ||
# This performs the internal work of hydrating/filtering props | ||
.then { |props| deep_transform_props(props) } | ||
# Then we apply the user-defined prop transformer | ||
.then { |props| configuration.prop_transformer(props: props) } | ||
# Then we add meta tags after everything since they must not be transformed | ||
.tap { |props| props[:_inertia_meta] = meta_tags if meta_tags.present? } | ||
Comment on lines
+93
to
+99
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This order ensures that any current or future internal props (like |
||
end | ||
|
||
def page | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# frozen_string_literal: true | ||
|
||
class InertiaPropTransformerController < ApplicationController | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was kind of winging it with this. Open to feedback! |
||
inertia_config( | ||
prop_transformer: lambda do |props:| | ||
props.deep_transform_keys { |key| key.to_s.upcase } | ||
end | ||
) | ||
|
||
def just_props | ||
render inertia: 'TestComponent', props: { | ||
lower_prop: 'lower_value', | ||
parent_hash: { | ||
lower_child_prop: 'lower_child_value', | ||
}, | ||
} | ||
end | ||
|
||
def props_and_meta | ||
render inertia: 'TestComponent', | ||
props: { | ||
lower_prop: 'lower_value', | ||
}, | ||
meta: [ | ||
{ name: 'description', content: "Don't transform me!" } | ||
] | ||
end | ||
|
||
def no_props | ||
render inertia: 'TestComponent' | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
# frozen_string_literal: true | ||
|
||
require_relative '../../lib/inertia_rails/rspec' | ||
RSpec.describe 'props can be transformed', type: :request, inertia: true do | ||
let(:headers) do | ||
{ | ||
'X-Inertia' => true, | ||
'X-Inertia-Partial-Component' => 'TestComponent', | ||
} | ||
end | ||
|
||
context 'props are provided' do | ||
it 'transforms the props' do | ||
get prop_transformer_test_path, headers: headers | ||
|
||
expect_inertia.to render_component('TestComponent') | ||
.and have_exact_props({ | ||
'LOWER_PROP' => 'lower_value', | ||
'PARENT_HASH' => { | ||
'LOWER_CHILD_PROP' => 'lower_child_value', | ||
}, | ||
}) | ||
end | ||
end | ||
|
||
context 'props and meta are provided' do | ||
it 'transforms the props' do | ||
get prop_transformer_with_meta_test_path, headers: headers | ||
|
||
expect_inertia.to render_component('TestComponent') | ||
.and include_props({ | ||
'LOWER_PROP' => 'lower_value', | ||
}) | ||
end | ||
|
||
it 'does not transform the meta' do | ||
get prop_transformer_with_meta_test_path, headers: headers | ||
|
||
expect(response.parsed_body['props']['_inertia_meta']).to eq( | ||
[ | ||
{ | ||
'tagName' => 'meta', | ||
'name' => 'description', | ||
'content' => "Don't transform me!", | ||
'headKey' => 'meta-name-description', | ||
} | ||
] | ||
) | ||
end | ||
end | ||
|
||
context 'no props are provided' do | ||
it 'does not error' do | ||
get prop_transformer_no_props_test_path, headers: headers | ||
|
||
expect_inertia.to render_component('TestComponent') | ||
.and have_exact_props({}) | ||
end | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This probably needs work. Open to suggestions!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would drop this additional section about input props tbh, this configuration option is not only about casing, so it looks misplaced to me
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see where you're coming from, but I think it's very likely that prop casing is the principal usage of this feature. I can try adjusting the wording to be a little more generic but it makes sense to me to highlight the transformation isn't bidirectional