Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 22 additions & 5 deletions Partas.Solid.FablePlugin/Plugin.fs
Original file line number Diff line number Diff line change
Expand Up @@ -901,15 +901,23 @@ module internal rec AST =
| Call(
Import({ Selector = "op_BangAt"; Kind = MemberImport(MemberRef({ FullName = "Partas.Solid.Builder" }, _)) }, _, _),
{
Args = Lambda(_, Call(callee, _, _, _), _) :: _
Args = Lambda(_, Call(callee, callInfo, _, _), _) :: _
},
_,
range
) ->
match callee with
// Some ident
| IdentExpr({ Type = Type.PartasName ctx typeName } as identee) ->
IdentExpr({ identee with Name = typeName |> Utils.trimReservedIdentifiers }) |> Some
match callInfo with
// In the case where the referenced tag is a constructor, then it is a SolidTypeComponent, and we
// actually intend to reference the name of the type.
| CallInfo.Constructor ctx ->
IdentExpr({ identee with Name = typeName |> Utils.trimReservedIdentifiers }) |> Some
// Where the above is not true, the referenced tag is a let binding, and therefore a SolidComponent,
// so we intent to reference the name of the binding.
| _ ->
callee |> Some
// prevent import of native tags
| Expr.NativeImportedConstructor ctx
& Import(
Expand All @@ -923,9 +931,18 @@ module internal rec AST =
| Import(
importInfo,
typ & Type.PartasName ctx typeName,
range) ->
Import({ importInfo with Selector = typeName }, typ, range)
|> Some
range) as expr->
// We determine if the imported tag was a constructor. If it was, then it is a SolidTypeComponent,
// and the name of the component will be the name of the type.
match callInfo with
| CallInfo.Constructor ctx ->
Import({ importInfo with Selector = typeName }, typ, range)
|> Some
// If the above is not true, then the tag is a SolidComponent let binding, and the name of the
// component will be the name of the binding.
| _ ->
expr
|> Some
| Import({ Kind = UserImport false }, _, _) ->
Some callee
| _ -> None
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@
<Content Include="AttributeCases\PartasImportAttr\PartasImportAttr.expected" />
<Compile Include="AttributeCases\Pojo\Pojo.fs" />
<Content Include="AttributeCases\Pojo\Pojo.expected" />
<Compile Include="SolidCases\SolidComponentAsTagValues\SolidComponentAsTagValuesTypes.fs" />
<Compile Include="SolidCases\SolidComponentAsTagValues\SolidComponentAsTagValues.fs" />
<Content Include="SolidCases\SolidComponentAsTagValues\SolidComponentAsTagValues.expected" />
<!-- <Content Include="Spec\Components.fs" />-->
</ItemGroup>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { splitProps, mergeProps } from "solid-js";
import { FakeImportedTag } from "fakeLibrary";
import { ModuleTag } from "./SolidComponentAsTagValuesTypes.fs.jsx";

export function CustomTag(props) {
props = mergeProps({
icon: button,
}, props);
const [PARTAS_LOCAL, PARTAS_OTHERS] = splitProps(props, ["icon"]);
return <div>
<PARTAS_LOCAL.icon class="KeyVal" />
<PARTAS_LOCAL.icon class="KeyVal2" />
<PARTAS_LOCAL.icon class="constructor">
<button>
internal
</button>
</PARTAS_LOCAL.icon>
</div>;
}

export function Rock() {
const Comp = FakeImportedTag;
return <CustomTag icon={a}>
<Comp other={ModuleTag} />
</CustomTag>;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
module Partas.Solid.Tests.SolidCases.SolidComponentAsTagValues.SolidComponentAsTagValues

open Partas.Solid.Tests.SolidCases.SolidComponentAsTagValues.SolidComponentAsTagValuesTypes
open Partas.Solid
open Fable.Core
open Fable.Core.JsInterop

[<Erase>]
type CustomTag() =
interface RegularNode

[<Erase>]
member val icon: TagValue = unbox null with get, set

[<SolidTypeComponent>]
member props.constructor =
props.icon <- !@button

div () {
props.icon % {| class' = "KeyVal" |}
props.icon % {| class' = "KeyVal2" |}
props.icon % div (class' = "constructor") { button () { "internal" } }

}

[<SolidComponent>]
let Rock () =
let Comp = !@Imported
CustomTag (icon = unbox !@a) { Comp % Imported (other = !@ModuleTag) }
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module Partas.Solid.Tests.SolidCases.SolidComponentAsTagValues.SolidComponentAsTagValuesTypes

open Partas.Solid
open Fable.Core

#nowarn 64

[<SolidComponent>]
let ModuleTag () = div ()

[<Import("FakeImportedTag", "fakeLibrary")>]
type Imported() =
interface RegularNode

[<Erase>]
member val other: TagValue = jsNative with get, set
4 changes: 3 additions & 1 deletion Partas.Solid.Tests.Plugin/Tests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,9 @@ let SolidCases =
"CssStyles"
|> runSolidCase "CssStyle definitions compiles correct output"
"ChildLambdaProvider"
|> runSolidCase "ChildLambdaProvider interfaces" ]
|> runSolidCase "ChildLambdaProvider interfaces"
"SolidComponentAsTagValues"
|> runSolidCase "SolidComponent let bindings as TagValues" ]

[<Tests>]
let AttributeCases =
Expand Down
5 changes: 3 additions & 2 deletions Partas.Solid/Builder.fs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ module Builder =
type VoidNode =
inherit HtmlTag


[<System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)>]
type IChildLambdaProvider =
inherit HtmlElement
Expand Down Expand Up @@ -142,7 +143,7 @@ module Builder =
/// let tag = !@div
/// </code></example>
[<Erase>]
type TagValue(tag: unit -> #HtmlElement) =
type TagValue(tag: FSharpFunc<_, #HtmlElement>) =
/// <summary>
/// Directs the plugin to build the call site as a Tag
/// in JSX.
Expand Down Expand Up @@ -200,7 +201,7 @@ module Builder =
/// let tag = !@div
/// </code></example>
[<Erase>]
let (!@) (this: unit -> 'T) =
let (!@) (this: FSharpFunc<_, #HtmlElement>) =
TagValue (unbox this)

/// Alias used in the provided builder
Expand Down
Loading