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
4 changes: 4 additions & 0 deletions Partas.Solid.Tests/Partas.Solid.Tests.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@
<Compile Include="SolidCases\ChildLambdaProvider\ChildLambdaProvider.fs" />
<Content Include="SolidCases\ChildLambdaProvider\ChildLambdaProvider.expected" />
<None Include="SolidCases\ChildLambdaProvider\ChildLambdaProvider.fsproj" />
<Compile Include="SolidCases\SolidComponentAsTagValues\SolidComponentAsTagValuesTypes.fs" />
<Compile Include="SolidCases\SolidComponentAsTagValues\SolidComponentAsTagValues.fs" />
<Content Include="SolidCases\SolidComponentAsTagValues\SolidComponentAsTagValues.fsproj" />
<Content Include="SolidCases\SolidComponentAsTagValues\SolidComponentAsTagValues.expected" />
<Compile Include="IssueCases\CreateSignalTagConstructor\CreateSignalTagConstructorTypes.fs" />
<Compile Include="IssueCases\CreateSignalTagConstructor\CreateSignalTagConstructor.fs" />
<Content Include="IssueCases\CreateSignalTagConstructor\CreateSignalTagConstructor.expected" />
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,28 @@
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,17 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<Compile Include="SolidComponentAsTagValuesTypes.fs" />
<Compile Include="SolidComponentAsTagValues.fs" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\Partas.Solid\Partas.Solid.fsproj" />
</ItemGroup>

</Project>
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
6 changes: 5 additions & 1 deletion Partas.Solid.Tests/SolidTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ let ``Field getters and records are transformed`` () =
let ``Tags can be used as values`` () =
runSolidCase "TagsAsValuesSimple"

[<Fact>]
let ``SolidComponents can be used as TagValues`` () =
runSolidCase "SolidComponentAsTagValues"

[<Fact>]
let ``FieldGets like props.words.Length are transformed`` () =
runSolidCase "FieldGetExpressionsTransformed"
Expand All @@ -69,4 +73,4 @@ let ``CssStyle definitions compile correct output`` () =

[<Fact>]
let ``ChildLambdaProvider interfaces`` () =
runSolidCase "ChildLambdaProvider"
runSolidCase "ChildLambdaProvider"
4 changes: 2 additions & 2 deletions Partas.Solid/Builder.fs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,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 @@ -178,7 +178,7 @@ module Builder =
/// let tag = !@div
/// </code></example>
[<Erase>]
let (!@) (this: unit -> 'T) = TagValue(unbox this)
let (!@) (this: FSharpFunc<_,#HtmlElement>) = TagValue(unbox this)

/// Alias used in the provided builder
[<System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)>]
Expand Down
17 changes: 0 additions & 17 deletions ScratchTests/Test.fs

This file was deleted.