Skip to content

Commit

Permalink
Add mount target
Browse files Browse the repository at this point in the history
  • Loading branch information
skryukov committed May 10, 2024
1 parent 679d004 commit 99cd746
Show file tree
Hide file tree
Showing 7 changed files with 37 additions and 14 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning].

## [Unreleased]

### Added

- Add a mount target to the base controller. ([@skryukov])

## [0.2.2] - 2024-05-09

### Fixed
Expand Down
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,17 @@ Then pass this controller the register method:
turboMount.register('SketchPicker', SketchPicker, TurboMountReactController);
```

### Mount target

You can add a mount target, which will be used to mount the component:

```erb
<%= turbo_mount_react_component("SketchPicker", props: {color: "#430"}) do |controller_name| %>
<h3>Color picker</h3>
<div data-<%= controller_name %>-target="mount"></div>
<% end %>
```

## Development

After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
Expand Down
3 changes: 2 additions & 1 deletion app/assets/javascripts/turbo-mount.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class TurboMountController extends Controller {
return this.propsValue;
}
get mountElement() {
return this.element;
return this.hasMountTarget ? this.mountTarget : this.element;
}
get resolvedComponent() {
return this.resolveComponent(this.componentValue);
Expand All @@ -33,6 +33,7 @@ TurboMountController.values = {
props: Object,
component: String
};
TurboMountController.targets = ["mount"];

class TurboMount {
constructor(props) {
Expand Down
2 changes: 1 addition & 1 deletion app/assets/javascripts/turbo-mount.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion app/assets/javascripts/turbo-mount.min.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 13 additions & 10 deletions lib/turbo/mount/helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,30 @@
module Turbo
module Mount
module Helpers
def turbo_mount_component(component_name, framework:, props: {}, tag: "div", **attrs)
def turbo_mount_component(component_name, framework:, props: {}, tag: "div", **attrs, &block)
raise TypeError, "Component name expected" unless component_name.is_a? String

attrs["data-controller"] = "turbo-mount-#{framework}-#{component_name.underscore.dasherize}"
prefix = "data-#{attrs["data-controller"]}"
controller_name = "turbo-mount-#{framework}-#{component_name.underscore.dasherize}"
attrs["data-controller"] = controller_name
prefix = "data-#{controller_name}"
attrs["#{prefix}-component-value"] = component_name
attrs["#{prefix}-props-value"] = json_escape(props.to_json) if props.present?

content_tag(tag, nil, attrs)
return content_tag(tag, nil, attrs) unless block

content_tag(tag, nil, attrs) { capture(controller_name, &block) }
end

def turbo_mount_react_component(component_name, **attrs)
turbo_mount_component(component_name, framework: "react", **attrs)
def turbo_mount_react_component(component_name, **attrs, &block)
turbo_mount_component(component_name, framework: "react", **attrs, &block)
end

def turbo_mount_svelte_component(component_name, **attrs)
turbo_mount_component(component_name, framework: "svelte", **attrs)
def turbo_mount_svelte_component(component_name, **attrs, &block)
turbo_mount_component(component_name, framework: "svelte", **attrs, &block)
end

def turbo_mount_vue_component(component_name, **attrs)
turbo_mount_component(component_name, framework: "vue", **attrs)
def turbo_mount_vue_component(component_name, **attrs, &block)
turbo_mount_component(component_name, framework: "vue", **attrs, &block)
end
end
end
Expand Down
6 changes: 5 additions & 1 deletion packages/turbo-mount/src/turbo-mount-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@ export abstract class TurboMountController<T> extends Controller {
props: Object,
component: String
}
static targets = [ "mount" ]

declare readonly propsValue: object;
declare readonly componentValue: string;
declare readonly hasMountTarget: boolean;
declare readonly mountTarget: Element;

abstract framework: string;

Expand All @@ -33,7 +37,7 @@ export abstract class TurboMountController<T> extends Controller {
}

get mountElement() {
return this.element;
return this.hasMountTarget ? this.mountTarget : this.element;
}

get resolvedComponent() {
Expand Down

0 comments on commit 99cd746

Please sign in to comment.