├── .config └── dotnet-tools.json ├── .github └── workflows │ ├── build-and-test.yml │ └── publish.yml ├── .gitignore ├── .paket └── Paket.Restore.targets ├── Feliz.Bulma.ViewEngine ├── Bulma.fs ├── ElementBuilders.fs ├── Feliz.Bulma.ViewEngine.fsproj ├── LICENSE ├── Modifiers.fs ├── Operators.fs ├── PropertyBuilders.fs └── paket.references ├── Feliz.ViewEngine.sln ├── LICENSE ├── LICENSE.Apache-2.0 ├── LICENSE.MIT ├── README.md ├── examples └── giraffe │ ├── Program.fs │ ├── README.md │ ├── build.bat │ ├── build.sh │ └── giraffe.fsproj ├── nuget-packages ├── Feliz.Bulma.ViewEngine.0.26.0.nupkg └── Feliz.ViewEngine.0.26.0.nupkg ├── paket.dependencies ├── paket.lock ├── src ├── Colors.fs ├── Feliz.ViewEngine.fsproj ├── Fonts.fs ├── Html.fs ├── Interop.fs ├── Properties.fs ├── React.fs ├── StyleTypes.fs ├── Styles.fs ├── TextDecorationLine.fs ├── TextDecorationStyle.fs ├── ViewEngine.fs └── paket.references └── test ├── Bulma.ViewEngineTest.fs ├── Program.fs ├── Tests.Feliz.ViewEngine.fsproj ├── ViewEngineTest.fs └── paket.references /.config/dotnet-tools.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "isRoot": true, 4 | "tools": { 5 | "paket": { 6 | "version": "9.0.2", 7 | "commands": [ 8 | "paket" 9 | ], 10 | "rollForward": false 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /.github/workflows/build-and-test.yml: -------------------------------------------------------------------------------- 1 | name: Build and Test 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | build: 11 | 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v4 16 | - name: Setup .NET Core 17 | uses: actions/setup-dotnet@v4 18 | with: 19 | dotnet-version: 9.0.300 20 | - name: Restore tools 21 | run: dotnet tool restore 22 | - name: Install dependencies 23 | run: dotnet paket restore 24 | - name: Build 25 | run: dotnet build --configuration Release 26 | - name: Test 27 | run: dotnet test --verbosity normal 28 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | tags: 4 | - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10 5 | 6 | name: Publish Release 7 | jobs: 8 | build: 9 | name: Create Release 10 | runs-on: ubuntu-latest 11 | timeout-minutes: 10 12 | steps: 13 | - name: Checkout code 14 | uses: actions/checkout@v4 15 | 16 | - name: Setup .NET Core 17 | uses: actions/setup-dotnet@v4 18 | with: 19 | dotnet-version: 9.0.300 20 | 21 | - name: Restore tools 22 | run: dotnet tool restore 23 | - name: Install dependencies 24 | run: dotnet paket restore 25 | - name: Build 26 | run: dotnet build --configuration Release 27 | - name: Pack 28 | run: dotnet pack -c Release -p:PackageVersion=${GITHUB_REF##*/v} 29 | 30 | - name: Push Feliz.ViewEngine Nuget 31 | run: dotnet nuget push src/bin/Release/*.nupkg -s https://api.nuget.org/v3/index.json -k ${{ secrets.NUGET_API_KEY }} 32 | continue-on-error: false 33 | - name: Push Feliz.Bulma.ViewEngine Nuget 34 | run: dotnet nuget push Feliz.Bulma.ViewEngine/bin/Release/*.nupkg -s https://api.nuget.org/v3/index.json -k ${{ secrets.NUGET_API_KEY }} 35 | continue-on-error: false 36 | 37 | - name: Create Release 38 | uses: actions/create-release@master 39 | env: 40 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 41 | with: 42 | tag_name: ${{ github.ref }} 43 | release_name: Release ${{ github.ref }} 44 | draft: false 45 | prerelease: false -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | src/obj 2 | .ionide 3 | paket-files 4 | examples/giraffe/bin 5 | examples/giraffe/obj 6 | bin 7 | obj 8 | .vs 9 | -------------------------------------------------------------------------------- /.paket/Paket.Restore.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 8 | 9 | $(MSBuildVersion) 10 | 15.0.0 11 | false 12 | true 13 | 14 | true 15 | $(MSBuildThisFileDirectory) 16 | $(MSBuildThisFileDirectory)..\ 17 | $(PaketRootPath)paket-files\paket.restore.cached 18 | $(PaketRootPath)paket.lock 19 | classic 20 | proj 21 | assembly 22 | native 23 | /Library/Frameworks/Mono.framework/Commands/mono 24 | mono 25 | 26 | 27 | $(PaketRootPath)paket.bootstrapper.exe 28 | $(PaketToolsPath)paket.bootstrapper.exe 29 | $([System.IO.Path]::GetDirectoryName("$(PaketBootStrapperExePath)"))\ 30 | 31 | "$(PaketBootStrapperExePath)" 32 | $(MonoPath) --runtime=v4.0.30319 "$(PaketBootStrapperExePath)" 33 | 34 | 35 | 36 | 37 | true 38 | true 39 | 40 | 41 | True 42 | 43 | 44 | False 45 | 46 | $(BaseIntermediateOutputPath.TrimEnd('\').TrimEnd('\/')) 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | $(PaketRootPath)paket 56 | $(PaketToolsPath)paket 57 | 58 | 59 | 60 | 61 | 62 | $(PaketRootPath)paket.exe 63 | $(PaketToolsPath)paket.exe 64 | 65 | 66 | 67 | 68 | 69 | <_DotnetToolsJson Condition="Exists('$(PaketRootPath)/.config/dotnet-tools.json')">$([System.IO.File]::ReadAllText("$(PaketRootPath)/.config/dotnet-tools.json")) 70 | <_ConfigContainsPaket Condition=" '$(_DotnetToolsJson)' != ''">$(_DotnetToolsJson.Contains('"paket"')) 71 | <_ConfigContainsPaket Condition=" '$(_ConfigContainsPaket)' == ''">false 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | <_PaketCommand>dotnet paket 83 | 84 | 85 | 86 | 87 | 88 | $(PaketToolsPath)paket 89 | $(PaketBootStrapperExeDir)paket 90 | 91 | 92 | paket 93 | 94 | 95 | 96 | 97 | <_PaketExeExtension>$([System.IO.Path]::GetExtension("$(PaketExePath)")) 98 | <_PaketCommand Condition=" '$(_PaketCommand)' == '' AND '$(_PaketExeExtension)' == '.dll' ">dotnet "$(PaketExePath)" 99 | <_PaketCommand Condition=" '$(_PaketCommand)' == '' AND '$(OS)' != 'Windows_NT' AND '$(_PaketExeExtension)' == '.exe' ">$(MonoPath) --runtime=v4.0.30319 "$(PaketExePath)" 100 | <_PaketCommand Condition=" '$(_PaketCommand)' == '' ">"$(PaketExePath)" 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | true 122 | $(NoWarn);NU1603;NU1604;NU1605;NU1608 123 | false 124 | true 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | $([System.IO.File]::ReadAllText('$(PaketRestoreCacheFile)')) 134 | 135 | 136 | 137 | 138 | 139 | 141 | $([System.Text.RegularExpressions.Regex]::Split(`%(Identity)`, `": "`)[0].Replace(`"`, ``).Replace(` `, ``)) 142 | $([System.Text.RegularExpressions.Regex]::Split(`%(Identity)`, `": "`)[1].Replace(`"`, ``).Replace(` `, ``)) 143 | 144 | 145 | 146 | 147 | %(PaketRestoreCachedKeyValue.Value) 148 | %(PaketRestoreCachedKeyValue.Value) 149 | 150 | 151 | 152 | 153 | true 154 | false 155 | true 156 | 157 | 158 | 162 | 163 | true 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | $(PaketIntermediateOutputPath)\$(MSBuildProjectFile).paket.references.cached 183 | 184 | $(MSBuildProjectFullPath).paket.references 185 | 186 | $(MSBuildProjectDirectory)\$(MSBuildProjectName).paket.references 187 | 188 | $(MSBuildProjectDirectory)\paket.references 189 | 190 | false 191 | true 192 | true 193 | references-file-or-cache-not-found 194 | 195 | 196 | 197 | 198 | $([System.IO.File]::ReadAllText('$(PaketReferencesCachedFilePath)')) 199 | $([System.IO.File]::ReadAllText('$(PaketOriginalReferencesFilePath)')) 200 | references-file 201 | false 202 | 203 | 204 | 205 | 206 | false 207 | 208 | 209 | 210 | 211 | true 212 | target-framework '$(TargetFramework)' or '$(TargetFrameworks)' files @(PaketResolvedFilePaths) 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | false 224 | true 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',').Length) 236 | $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[0]) 237 | $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[1]) 238 | $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[2]) 239 | $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[4]) 240 | $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[5]) 241 | $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[6]) 242 | $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[7]) 243 | $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[8]) 244 | 245 | 246 | %(PaketReferencesFileLinesInfo.PackageVersion) 247 | All 248 | runtime 249 | $(ExcludeAssets);contentFiles 250 | $(ExcludeAssets);build;buildMultitargeting;buildTransitive 251 | %(PaketReferencesFileLinesInfo.Aliases) 252 | true 253 | true 254 | 255 | 256 | 257 | 258 | %(PaketReferencesFileLinesInfo.PackageVersion) 259 | 260 | 261 | 262 | 263 | $(PaketIntermediateOutputPath)/$(MSBuildProjectFile).paket.clitools 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | $([System.String]::Copy('%(PaketCliToolFileLines.Identity)').Split(',')[0]) 273 | $([System.String]::Copy('%(PaketCliToolFileLines.Identity)').Split(',')[1]) 274 | 275 | 276 | %(PaketCliToolFileLinesInfo.PackageVersion) 277 | 278 | 279 | 280 | 284 | 285 | 286 | 287 | 288 | 289 | false 290 | 291 | 292 | 293 | 294 | 295 | <_NuspecFilesNewLocation Include="$(PaketIntermediateOutputPath)\$(Configuration)\*.nuspec"/> 296 | 297 | 298 | 299 | 300 | 301 | $(MSBuildProjectDirectory)/$(MSBuildProjectFile) 302 | true 303 | false 304 | true 305 | false 306 | true 307 | false 308 | true 309 | false 310 | true 311 | false 312 | true 313 | $(PaketIntermediateOutputPath)\$(Configuration) 314 | $(PaketIntermediateOutputPath) 315 | 316 | 317 | 318 | <_NuspecFiles Include="$(AdjustedNuspecOutputPath)\*.$(PackageVersion.Split(`+`)[0]).nuspec"/> 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 378 | 379 | 428 | 429 | 474 | 475 | 519 | 520 | 563 | 564 | 565 | 566 | -------------------------------------------------------------------------------- /Feliz.Bulma.ViewEngine/ElementBuilders.fs: -------------------------------------------------------------------------------- 1 | module Feliz.Bulma.ViewEngine.ElementBuilders 2 | 3 | open Feliz.ViewEngine 4 | 5 | module internal Helpers = 6 | let [] ClassName = "class" 7 | 8 | let inline getClasses (xs:IReactProperty list) = 9 | xs 10 | |> List.choose (function | KeyValue (k, v) -> Some (k, v) | _ -> None) 11 | |> List.filter (fun (k,_) -> 12 | k = ClassName) 13 | |> List.map (snd >> string) 14 | 15 | let inline partitionClasses (xs:IReactProperty list) = 16 | xs 17 | |> List.partition (function | KeyValue (k, v) -> k = ClassName | _ -> false) 18 | 19 | let inline combineClasses cn (xs:IReactProperty list) = 20 | xs 21 | |> getClasses 22 | |> List.append [cn] 23 | |> prop.classes 24 | 25 | module Div = 26 | let inline props (cn:string) (xs:IReactProperty list) = Html.div [ yield! Helpers.partitionClasses xs ||> (fun c p -> Helpers.combineClasses cn c :: p) ] 27 | let inline children (cn:string) (children:seq) = Html.div [ prop.className cn; prop.children children ] 28 | let inline valueElm (cn:string) (value:ReactElement) = value |> List.singleton |> children cn 29 | let inline valueStr (cn:string) (value:string) = Html.div [ prop.className cn; prop.text value ] 30 | let inline valueInt (cn:string) (value:int) = Html.div [ prop.className cn; prop.text value ] 31 | 32 | module Nav = 33 | let inline props (cn:string) (xs:IReactProperty list) = Html.nav [ yield! Helpers.partitionClasses xs ||> (fun c p -> Helpers.combineClasses cn c :: p) ] 34 | let inline children (cn:string) (children:seq) = Html.nav [ prop.className cn; prop.children children ] 35 | let inline valueElm (cn:string) (value:ReactElement) = value |> List.singleton |> children cn 36 | 37 | module Article = 38 | let inline props (cn:string) (xs:IReactProperty list) = Html.article [ yield! Helpers.partitionClasses xs ||> (fun c p -> Helpers.combineClasses cn c :: p) ] 39 | let inline children (cn:string) (children:seq) = Html.article [ prop.className cn; prop.children children ] 40 | let inline valueElm (cn:string) (value:ReactElement) = value |> List.singleton |> children cn 41 | 42 | module Section = 43 | let inline props (cn:string) (xs:IReactProperty list) = Html.section [ yield! Helpers.partitionClasses xs ||> (fun c p -> Helpers.combineClasses cn c :: p) ] 44 | let inline children (cn:string) (children:seq) = Html.section [ prop.className cn; prop.children children ] 45 | let inline valueElm (cn:string) (value:ReactElement) = value |> List.singleton |> children cn 46 | 47 | module Footer = 48 | let inline props (cn:string) (xs:IReactProperty list) = Html.footer [ yield! Helpers.partitionClasses xs ||> (fun c p -> Helpers.combineClasses cn c :: p) ] 49 | let inline children (cn:string) (children:seq) = Html.footer [ prop.className cn; prop.children children ] 50 | let inline valueElm (cn:string) (value:ReactElement) = value |> List.singleton |> children cn 51 | 52 | module Label = 53 | let inline props (cn:string) (xs:IReactProperty list) = Html.label [ yield! Helpers.partitionClasses xs ||> (fun c p -> Helpers.combineClasses cn c :: p) ] 54 | let inline children (cn:string) (children:seq) = Html.label [ prop.className cn; prop.children children ] 55 | let inline valueElm (cn:string) (value:ReactElement) = value |> List.singleton |> children cn 56 | let inline valueStr (cn:string) (value:string) = Html.label [ prop.className cn; prop.text value ] 57 | let inline valueInt (cn:string) (value:int) = Html.label [ prop.className cn; prop.text value ] 58 | 59 | module Input = 60 | let inline propsWithType (cn:string) (typ: IReactProperty) (xs:IReactProperty list) = 61 | Html.input [ typ; Helpers.combineClasses cn xs ] 62 | 63 | module Textarea = 64 | let inline props (cn:string) (xs:IReactProperty list) = Html.textarea [ yield! Helpers.partitionClasses xs ||> (fun c p -> Helpers.combineClasses cn c :: p) ] 65 | let inline children (cn:string) (children:seq) = Html.textarea [ prop.className cn; prop.children children ] 66 | let inline valueElm (cn:string) (value:ReactElement) = value |> List.singleton |> children cn 67 | 68 | module Button = 69 | let inline props (cn:string) (xs:IReactProperty list) = Html.button [ yield! Helpers.partitionClasses xs ||> (fun c p -> Helpers.combineClasses cn c :: p) ] 70 | let inline children (cn:string) (children:seq) = Html.button [ prop.className cn; prop.children children ] 71 | let inline valueElm (cn:string) (value:ReactElement) = value |> List.singleton |> children cn 72 | let inline valueStr (cn:string) (value:string) = Html.button [ prop.className cn; prop.text value ] 73 | let inline valueInt (cn:string) (value:int) = Html.button [ prop.className cn; prop.text value ] 74 | 75 | module Span = 76 | let inline props (cn:string) (xs:IReactProperty list) = Html.span [ yield! Helpers.partitionClasses xs ||> (fun c p -> Helpers.combineClasses cn c :: p) ] 77 | let inline children (cn:string) (children:seq) = Html.span [ prop.className cn; prop.children children ] 78 | let inline valueElm (cn:string) (value:ReactElement) = value |> List.singleton |> children cn 79 | let inline valueStr (cn:string) (value:string) = Html.span [ prop.className cn; prop.text value ] 80 | let inline valueInt (cn:string) (value:int) = Html.span [ prop.className cn; prop.text value ] 81 | 82 | module Figure = 83 | let inline props (cn:string) (xs:IReactProperty list) = Html.figure [ yield! Helpers.partitionClasses xs ||> (fun c p -> Helpers.combineClasses cn c :: p) ] 84 | let inline children (cn:string) (children:seq) = Html.figure [ prop.className cn; prop.children children ] 85 | let inline valueElm (cn:string) (value:ReactElement) = value |> List.singleton |> children cn 86 | 87 | module Progress = 88 | let inline props (cn:string) (xs:IReactProperty list) = Html.progress [ yield! Helpers.partitionClasses xs ||> (fun c p -> Helpers.combineClasses cn c :: p) ] 89 | let inline children (cn:string) (children:seq) = Html.progress [ prop.className cn; prop.children children ] 90 | let inline valueElm (cn:string) (value:ReactElement) = value |> List.singleton |> children cn 91 | let inline valueStr (cn:string) (value:string) = Html.progress [ prop.className cn; prop.text value ] 92 | let inline valueInt (cn:string) (value:int) = Html.progress [ prop.className cn; prop.text value ] 93 | 94 | module Table = 95 | let inline props (cn:string) (xs:IReactProperty list) = Html.table [ yield! Helpers.partitionClasses xs ||> (fun c p -> Helpers.combineClasses cn c :: p) ] 96 | let inline children (cn:string) (children:seq) = Html.table [ prop.className cn; prop.children children ] 97 | let inline valueElm (cn:string) (value:ReactElement) = value |> List.singleton |> children cn 98 | 99 | module H1 = 100 | let inline props (cn:string) (xs:IReactProperty list) = Html.h1 [ yield! Helpers.partitionClasses xs ||> (fun c p -> Helpers.combineClasses cn c :: p) ] 101 | let inline children (cn:string) (children:seq) = Html.h1 [ prop.className cn; prop.children children ] 102 | let inline valueElm (cn:string) (value:ReactElement) = value |> List.singleton |> children cn 103 | let inline valueStr (cn:string) (value:string) = Html.h1 [ prop.className cn; prop.text value ] 104 | let inline valueInt (cn:string) (value:int) = Html.h1 [ prop.className cn; prop.text value ] 105 | 106 | module H2 = 107 | let inline props (cn:string) (xs:IReactProperty list) = Html.h2 [ yield! Helpers.partitionClasses xs ||> (fun c p -> Helpers.combineClasses cn c :: p) ] 108 | let inline children (cn:string) (children:seq) = Html.h2 [ prop.className cn; prop.children children ] 109 | let inline valueElm (cn:string) (value:ReactElement) = value |> List.singleton |> children cn 110 | let inline valueStr (cn:string) (value:string) = Html.h2 [ prop.className cn; prop.text value ] 111 | let inline valueInt (cn:string) (value:int) = Html.h2 [ prop.className cn; prop.text value ] 112 | 113 | module H3 = 114 | let inline props (cn:string) (xs:IReactProperty list) = Html.h3 [ yield! Helpers.partitionClasses xs ||> (fun c p -> Helpers.combineClasses cn c :: p) ] 115 | let inline children (cn:string) (children:seq) = Html.h3 [ prop.className cn; prop.children children ] 116 | let inline valueElm (cn:string) (value:ReactElement) = value |> List.singleton |> children cn 117 | let inline valueStr (cn:string) (value:string) = Html.h3 [ prop.className cn; prop.text value ] 118 | let inline valueInt (cn:string) (value:int) = Html.h3 [ prop.className cn; prop.text value ] 119 | 120 | module H4 = 121 | let inline props (cn:string) (xs:IReactProperty list) = Html.h4 [ yield! Helpers.partitionClasses xs ||> (fun c p -> Helpers.combineClasses cn c :: p) ] 122 | let inline children (cn:string) (children:seq) = Html.h4 [ prop.className cn; prop.children children ] 123 | let inline valueElm (cn:string) (value:ReactElement) = value |> List.singleton |> children cn 124 | let inline valueStr (cn:string) (value:string) = Html.h4 [ prop.className cn; prop.text value ] 125 | let inline valueInt (cn:string) (value:int) = Html.h4 [ prop.className cn; prop.text value ] 126 | 127 | module H5 = 128 | let inline props (cn:string) (xs:IReactProperty list) = Html.h5 [ yield! Helpers.partitionClasses xs ||> (fun c p -> Helpers.combineClasses cn c :: p) ] 129 | let inline children (cn:string) (children:seq) = Html.h5 [ prop.className cn; prop.children children ] 130 | let inline valueElm (cn:string) (value:ReactElement) = value |> List.singleton |> children cn 131 | let inline valueStr (cn:string) (value:string) = Html.h5 [ prop.className cn; prop.text value ] 132 | let inline valueInt (cn:string) (value:int) = Html.h5 [ prop.className cn; prop.text value ] 133 | 134 | module H6 = 135 | let inline props (cn:string) (xs:IReactProperty list) = Html.h6 [ yield! Helpers.partitionClasses xs ||> (fun c p -> Helpers.combineClasses cn c :: p) ] 136 | let inline children (cn:string) (children:seq) = Html.h6 [ prop.className cn; prop.children children ] 137 | let inline valueElm (cn:string) (value:ReactElement) = value |> List.singleton |> children cn 138 | let inline valueStr (cn:string) (value:string) = Html.h6 [ prop.className cn; prop.text value ] 139 | let inline valueInt (cn:string) (value:int) = Html.h6 [ prop.className cn; prop.text value ] 140 | 141 | module Hr = 142 | let inline props (cn:string) (xs:IReactProperty list) = Html.hr [ yield! Helpers.partitionClasses xs ||> (fun c p -> Helpers.combineClasses cn c :: p) ] 143 | 144 | module Aside = 145 | let inline props (cn:string) (xs:IReactProperty list) = Html.aside [ yield! Helpers.partitionClasses xs ||> (fun c p -> Helpers.combineClasses cn c :: p) ] 146 | let inline children (cn:string) (children:seq) = Html.aside [ prop.className cn; prop.children children ] 147 | let inline valueElm (cn:string) (value:ReactElement) = value |> List.singleton |> children cn 148 | 149 | module P = 150 | let inline props (cn:string) (xs:IReactProperty list) = Html.p [ yield! Helpers.partitionClasses xs ||> (fun c p -> Helpers.combineClasses cn c :: p) ] 151 | let inline children (cn:string) (children:seq) = Html.p [ prop.className cn; prop.children children ] 152 | let inline valueElm (cn:string) (value:ReactElement) = value |> List.singleton |> children cn 153 | let inline valueStr (cn:string) (value:string) = Html.p [ prop.className cn; prop.text value ] 154 | let inline valueInt (cn:string) (value:int) = Html.p [ prop.className cn; prop.text value ] 155 | 156 | module Ul = 157 | let inline props (cn:string) (xs:IReactProperty list) = Html.ul [ yield! Helpers.partitionClasses xs ||> (fun c p -> Helpers.combineClasses cn c :: p) ] 158 | let inline children (cn:string) (children:seq) = Html.ul [ prop.className cn; prop.children children ] 159 | let inline valueElm (cn:string) (value:ReactElement) = value |> List.singleton |> children cn 160 | 161 | module Li = 162 | let inline props (cn:string) (xs:IReactProperty list) = Html.li [ yield! Helpers.partitionClasses xs ||> (fun c p -> Helpers.combineClasses cn c :: p) ] 163 | let inline children (cn:string) (children:seq) = Html.li [ prop.className cn; prop.children children ] 164 | let inline valueElm (cn:string) (value:ReactElement) = value |> List.singleton |> children cn 165 | 166 | module Header = 167 | let inline props (cn:string) (xs:IReactProperty list) = Html.header [ yield! Helpers.partitionClasses xs ||> (fun c p -> Helpers.combineClasses cn c :: p) ] 168 | let inline children (cn:string) (children:seq) = Html.header [ prop.className cn; prop.children children ] 169 | let inline valueElm (cn:string) (value:ReactElement) = value |> List.singleton |> children cn 170 | 171 | module A = 172 | let inline props (cn:string) (xs:IReactProperty list) = Html.a [ yield! Helpers.partitionClasses xs ||> (fun c p -> Helpers.combineClasses cn c :: p) ] 173 | let inline children (cn:string) (children:seq) = Html.a [ prop.className cn; prop.children children ] 174 | let inline valueElm (cn:string) (value:ReactElement) = value |> List.singleton |> children cn 175 | let inline valueStr (cn:string) (value:string) = Html.a [ prop.className cn; prop.text value ] 176 | let inline valueInt (cn:string) (value:int) = Html.a [ prop.className cn; prop.text value ] 177 | -------------------------------------------------------------------------------- /Feliz.Bulma.ViewEngine/Feliz.Bulma.ViewEngine.fsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0 5 | Feliz.Bulma.ViewEngine 6 | Dag Brattli 7 | Brattli Labs 8 | Roman Provazník 9 | LICENSE 10 | https://github.com/dbrattli/Feliz.ViewEngine 11 | true 12 | true 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /Feliz.Bulma.ViewEngine/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Roman Provazník 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Feliz.Bulma.ViewEngine/Operators.fs: -------------------------------------------------------------------------------- 1 | module Feliz.Bulma.ViewEngine.Operators 2 | 3 | open Feliz.ViewEngine 4 | 5 | let (++) (prop1: IReactProperty) (prop2: IReactProperty) = 6 | ElementBuilders.Helpers.getClasses [prop1; prop2] 7 | |> prop.classes -------------------------------------------------------------------------------- /Feliz.Bulma.ViewEngine/PropertyBuilders.fs: -------------------------------------------------------------------------------- 1 | module internal Feliz.Bulma.ViewEngine.PropertyBuilders 2 | 3 | open Feliz.ViewEngine 4 | 5 | let inline mkClass (value:string) = Interop.mkAttr "class" value 6 | let inline mkType (value:string) = Interop.mkAttr "type" value 7 | let inline mkValue (value:int) = Interop.mkAttr "value" value 8 | let inline mkMax (value:int) = Interop.mkAttr "max" value -------------------------------------------------------------------------------- /Feliz.Bulma.ViewEngine/paket.references: -------------------------------------------------------------------------------- 1 | group Bulma 2 | 3 | FSharp.Core 4 | Feliz.ViewEngine 5 | -------------------------------------------------------------------------------- /Feliz.ViewEngine.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26124.0 5 | MinimumVisualStudioVersion = 15.0.26124.0 6 | Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Feliz.ViewEngine", "src\Feliz.ViewEngine.fsproj", "{B9BCF160-840B-449C-B6D8-07909A4161EB}" 7 | EndProject 8 | Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Tests-Feliz.ViewEngine", "test\Tests.Feliz.ViewEngine.fsproj", "{477BDCE1-C00F-4A37-B52C-C2BC9AF05D57}" 9 | EndProject 10 | Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Feliz.Bulma.ViewEngine", "Feliz.Bulma.ViewEngine\Feliz.Bulma.ViewEngine.fsproj", "{69A365F4-9078-4421-8ABA-0D6E5B6A030E}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|Any CPU = Debug|Any CPU 15 | Debug|x64 = Debug|x64 16 | Debug|x86 = Debug|x86 17 | Release|Any CPU = Release|Any CPU 18 | Release|x64 = Release|x64 19 | Release|x86 = Release|x86 20 | EndGlobalSection 21 | GlobalSection(SolutionProperties) = preSolution 22 | HideSolutionNode = FALSE 23 | EndGlobalSection 24 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 25 | {B9BCF160-840B-449C-B6D8-07909A4161EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 26 | {B9BCF160-840B-449C-B6D8-07909A4161EB}.Debug|Any CPU.Build.0 = Debug|Any CPU 27 | {B9BCF160-840B-449C-B6D8-07909A4161EB}.Debug|x64.ActiveCfg = Debug|Any CPU 28 | {B9BCF160-840B-449C-B6D8-07909A4161EB}.Debug|x64.Build.0 = Debug|Any CPU 29 | {B9BCF160-840B-449C-B6D8-07909A4161EB}.Debug|x86.ActiveCfg = Debug|Any CPU 30 | {B9BCF160-840B-449C-B6D8-07909A4161EB}.Debug|x86.Build.0 = Debug|Any CPU 31 | {B9BCF160-840B-449C-B6D8-07909A4161EB}.Release|Any CPU.ActiveCfg = Release|Any CPU 32 | {B9BCF160-840B-449C-B6D8-07909A4161EB}.Release|Any CPU.Build.0 = Release|Any CPU 33 | {B9BCF160-840B-449C-B6D8-07909A4161EB}.Release|x64.ActiveCfg = Release|Any CPU 34 | {B9BCF160-840B-449C-B6D8-07909A4161EB}.Release|x64.Build.0 = Release|Any CPU 35 | {B9BCF160-840B-449C-B6D8-07909A4161EB}.Release|x86.ActiveCfg = Release|Any CPU 36 | {B9BCF160-840B-449C-B6D8-07909A4161EB}.Release|x86.Build.0 = Release|Any CPU 37 | {477BDCE1-C00F-4A37-B52C-C2BC9AF05D57}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 38 | {477BDCE1-C00F-4A37-B52C-C2BC9AF05D57}.Debug|Any CPU.Build.0 = Debug|Any CPU 39 | {477BDCE1-C00F-4A37-B52C-C2BC9AF05D57}.Debug|x64.ActiveCfg = Debug|Any CPU 40 | {477BDCE1-C00F-4A37-B52C-C2BC9AF05D57}.Debug|x64.Build.0 = Debug|Any CPU 41 | {477BDCE1-C00F-4A37-B52C-C2BC9AF05D57}.Debug|x86.ActiveCfg = Debug|Any CPU 42 | {477BDCE1-C00F-4A37-B52C-C2BC9AF05D57}.Debug|x86.Build.0 = Debug|Any CPU 43 | {477BDCE1-C00F-4A37-B52C-C2BC9AF05D57}.Release|Any CPU.ActiveCfg = Release|Any CPU 44 | {477BDCE1-C00F-4A37-B52C-C2BC9AF05D57}.Release|Any CPU.Build.0 = Release|Any CPU 45 | {477BDCE1-C00F-4A37-B52C-C2BC9AF05D57}.Release|x64.ActiveCfg = Release|Any CPU 46 | {477BDCE1-C00F-4A37-B52C-C2BC9AF05D57}.Release|x64.Build.0 = Release|Any CPU 47 | {477BDCE1-C00F-4A37-B52C-C2BC9AF05D57}.Release|x86.ActiveCfg = Release|Any CPU 48 | {477BDCE1-C00F-4A37-B52C-C2BC9AF05D57}.Release|x86.Build.0 = Release|Any CPU 49 | {69A365F4-9078-4421-8ABA-0D6E5B6A030E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 50 | {69A365F4-9078-4421-8ABA-0D6E5B6A030E}.Debug|Any CPU.Build.0 = Debug|Any CPU 51 | {69A365F4-9078-4421-8ABA-0D6E5B6A030E}.Debug|x64.ActiveCfg = Debug|Any CPU 52 | {69A365F4-9078-4421-8ABA-0D6E5B6A030E}.Debug|x64.Build.0 = Debug|Any CPU 53 | {69A365F4-9078-4421-8ABA-0D6E5B6A030E}.Debug|x86.ActiveCfg = Debug|Any CPU 54 | {69A365F4-9078-4421-8ABA-0D6E5B6A030E}.Debug|x86.Build.0 = Debug|Any CPU 55 | {69A365F4-9078-4421-8ABA-0D6E5B6A030E}.Release|Any CPU.ActiveCfg = Release|Any CPU 56 | {69A365F4-9078-4421-8ABA-0D6E5B6A030E}.Release|Any CPU.Build.0 = Release|Any CPU 57 | {69A365F4-9078-4421-8ABA-0D6E5B6A030E}.Release|x64.ActiveCfg = Release|Any CPU 58 | {69A365F4-9078-4421-8ABA-0D6E5B6A030E}.Release|x64.Build.0 = Release|Any CPU 59 | {69A365F4-9078-4421-8ABA-0D6E5B6A030E}.Release|x86.ActiveCfg = Release|Any CPU 60 | {69A365F4-9078-4421-8ABA-0D6E5B6A030E}.Release|x86.Build.0 = Release|Any CPU 61 | EndGlobalSection 62 | EndGlobal 63 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache-2.0 OR MIT 2 | 3 | See LICENSE.Apache-2.0 or LICENSE.MIT for details. -------------------------------------------------------------------------------- /LICENSE.Apache-2.0: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /LICENSE.MIT: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Dag Brattli, Zaid Ajaj 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Feliz.ViewEngine 2 | 3 | ![Build and Test](https://github.com/dbrattli/Feliz.ViewEngine/workflows/Build%20and%20Test/badge.svg) 4 | [![NuGet](https://img.shields.io/nuget/v/Feliz.ViewEngine.svg?maxAge=0&colorB=brightgreen)](https://www.nuget.org/packages/Feliz.ViewEngine) 5 | 6 | Feliz.ViewEngine lets you render [Feliz](https://github.com/Zaid-Ajaj/Feliz) DSL to plain HTML (or XML). Use with e.g 7 | Giraffe for handling Server Side Rendering (SSR), returning HTML or XML. You can use it for e.g generating HTML emails 8 | or any other use-case where you need to generate HTML output. 9 | 10 | Feliz.ViewEngine have no dependencies, is Fable compatible, and can thus be used with both servers (e.g Node.js) or 11 | clients. 12 | 13 | ## Installation 14 | 15 | Feliz.ViewEngine is available as a [NuGet package](https://www.nuget.org/packages/Feliz.ViewEngine/). To install: 16 | 17 | Using Package Manager: 18 | 19 | ```powershell 20 | Install-Package Feliz.ViewEngine 21 | ``` 22 | 23 | Using .NET CLI: 24 | 25 | ```bash 26 | dotnet add package Feliz.ViewEngine 27 | ``` 28 | 29 | ## Getting started 30 | 31 | ```fs 32 | open Feliz.ViewEngine 33 | 34 | let html = 35 | Html.h1 [ 36 | prop.style [ style.fontSize(100); style.color("#137373") ] 37 | prop.text "Hello, world!" 38 | ] 39 | |> Render.htmlView 40 | 41 | printfn "Output: %s" html 42 | // Will output "

Hello, world!

" 43 | ``` 44 | 45 | Giraffe example at 46 | 47 | ## Sharing views between client and server 48 | 49 | Feliz.ViewEngine re-implements Feliz DSL for server-side so you will need to choose Feliz for client side rendering and 50 | Feliz.ViewEngine for server side rendering: 51 | 52 | ```fs 53 | #if FABLE_COMPILER 54 | open Feliz 55 | #else 56 | open Feliz.ViewEngine 57 | #endif 58 | 59 | let view = ... 60 | ``` 61 | 62 | ## Documentation 63 | 64 | The following API is available for converting a `ReactElement` view into a string that you can return from e.g a Giraffe 65 | HTTP handler. 66 | 67 | ```fs 68 | type Render 69 | /// Create HTML document view with 70 | static member htmlDocument: document: ReactElement -> string 71 | /// Create HTML view 72 | static member htmlView: node: ReactElement -> string (+ 1 overloads) 73 | /// Create XML document view with 74 | static member xmlDocument: document: ReactElement -> string 75 | /// Create XML view 76 | static member xmlView: node: ReactElement -> string (+ 1 overloads) 77 | ``` 78 | 79 | Feliz has extensive documentation at with live examples along side code samples, check 80 | them out and if you have any question, let us know! 81 | 82 | ## Extensions 83 | 84 | - [Feliz.Bulma.ViewEngine](https://www.nuget.org/packages/Feliz.Bulma.ViewEngine/) - Port of 85 | [Feliz.Bulma](https://github.com/Dzoukr/Feliz.Bulma) to Feliz.ViewEngine. 86 | 87 | ## Common Pitfalls 88 | 89 | Feliz.ViewEngine (`ReactElement`) is not compatible with GiraffeViewEngine (`XmlNode`) so you cannot mix the two as you 90 | can with Feliz and Fable.React. Thus when you convert your existing server side rendering code, then all the elements 91 | must be converted to Feliz. 92 | 93 | ## Projects and Examples 94 | 95 | Projects and examples using Feliz.ViewEngine: 96 | 97 | - [Felizia](https://github.com/dbrattli/Felizia) - Uses Feliz.ViewEngine server-side for SSR and Feliz client-side 98 | - [Giraffe server](https://github.com/dbrattli/Feliz.ViewEngine/tree/master/examples/giraffe) - simple example 99 | 100 | ## Porting an Existing Feliz Library to Feliz.ViewEngine 101 | 102 | To port an existing `Feliz` library to `Feliz.ViewEngine` you basically need to reimplement everything from the library 103 | you want to port. However this is usually not a lot of work since you can reuse most of the files from the existing 104 | library, and you can do the work incrementally and add support for more elements and properties as needed. 105 | 106 | Start with the file that generates the HTML elements, comment out the whole file using `(* ... *)` and start enabling 107 | element by element. Then port properties, styles, colors, etc. 108 | 109 | The `Feliz.ViewEngine` types are different from `ReactElement`: 110 | 111 | ```fs 112 | type IReactProperty = 113 | | KeyValue of string * obj 114 | | Children of ReactElement list 115 | | Text of string 116 | 117 | and ReactElement = 118 | | Element of string * IReactProperty list 119 | | VoidElement of string * IReactProperty list 120 | | TextElement of string 121 | ``` 122 | 123 | However you usually don't have to care about the difference since the `Interop` interface is very similar: 124 | 125 | ```fs 126 | module Interop = 127 | /// Output a string where the content has been HTML encoded. 128 | val mkText: content : 'a -> IReactProperty 129 | val mkChildren: props: #seq -> IReactProperty 130 | val reactElementWithChildren: name: string -> children: #seq -> ReactElement 131 | val reactElementWithChild: name: string -> child: 'a -> ReactElement 132 | val createElement: name: string -> props: IReactProperty list -> ReactElement 133 | val createVoidElement: name: string -> props: IReactProperty list -> ReactElement 134 | val createTextElement: content : string -> ReactElement 135 | val createRawTextElement: content : string -> ReactElement 136 | let mkAttr: key: string -> value: obj -> IReactProperty 137 | val mkStyle: key: string -> value: obj -> IStyleAttribute 138 | ``` 139 | 140 | Using the `Interop` module, many elements is exactly the same for `Feliz` and `Feliz.ViewEngine`. E.g `Feliz` code such 141 | as: 142 | 143 | ```fs 144 | module Html = 145 | static member inline div xs = Interop.createElement "div" xs 146 | ``` 147 | 148 | For `Feliz.ViewEngine` it will be exactly the same: 149 | 150 | ```fs 151 | module Html = 152 | static member inline div xs = Interop.createElement "div" xs 153 | ``` 154 | 155 | However other elements may require some work. E.g all elements that use unboxing such as: 156 | 157 | ```fs 158 | static member inline none : ReactElement = unbox null 159 | static member inline text (value: int) : ReactElement = unbox value 160 | ``` 161 | 162 | For `Feliz.ViewEngine` this needs to be rewritten as: 163 | 164 | ```fs 165 | static member inline none : ReactElement = Interop.createTextElement "" 166 | static member inline text (value: int) : ReactElement = Interop.createTextElement (value.ToString ()) 167 | ``` 168 | 169 | Properties may also require some work, e.g: 170 | 171 | ```fs 172 | [] 173 | type prop = 174 | static member inline dangerouslySetInnerHTML (content: string) = Interop.mkAttr "dangerouslySetInnerHTML" (createObj [ "__html" ==> content ]) 175 | 176 | ``` 177 | 178 | For `Feliz.ViewEngine` this needs to be rewritten as: 179 | 180 | ```fs 181 | type prop = 182 | static member inline dangerouslySetInnerHTML (content: string) = Interop.mkChildren [ Interop.createRawTextElement content ] 183 | 184 | ``` 185 | 186 | As you go along, always remember that `Feliz.ViewEngine` and SSR is about generating HTML that will become text. You 187 | just need to make sure that the elements and properties you add generate the expected text output when rendered. Thus 188 | you can add unit-tests to check the output is as expected by calling `Render.htmlView`: 189 | 190 | ```fs 191 | [] 192 | let ``h1 element with text and style property with css unit is Ok``() = 193 | // Arrange / Act 194 | let result = 195 | Html.h1 [ 196 | prop.style [ style.fontSize(length.em(100)) ] 197 | prop.text "examples" 198 | ] 199 | |> Render.htmlView 200 | 201 | // Assert 202 | test <@ result = "

examples

" @> 203 | ``` 204 | 205 | ## License 206 | 207 | This work is dual-licensed under Apache 2.0 and MIT. You can choose between one of them if you use this work. 208 | 209 | `SPDX-License-Identifier: Apache-2.0 OR MIT` 210 | 211 | ## Duplication of Code 212 | 213 | Yes, Feliz.ViewEngine duplicates a lot of code and violates the [DRY 214 | principle](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself). This is currently [by 215 | design](https://www.sandimetz.com/blog/2016/1/20/the-wrong-abstraction). 216 | -------------------------------------------------------------------------------- /examples/giraffe/Program.fs: -------------------------------------------------------------------------------- 1 | module examples.App 2 | 3 | open System 4 | open Giraffe 5 | 6 | open Microsoft.AspNetCore.Hosting 7 | open Microsoft.Extensions.DependencyInjection 8 | open Microsoft.AspNetCore.Builder 9 | open Microsoft.Extensions.Logging 10 | open Microsoft.AspNetCore 11 | 12 | open Feliz.ViewEngine 13 | 14 | // --------------------------------- 15 | // Models 16 | // --------------------------------- 17 | 18 | type Message = { 19 | Text : string 20 | } 21 | 22 | // --------------------------------- 23 | // Views 24 | // --------------------------------- 25 | 26 | module Views = 27 | let layout (content: ReactElement list) = 28 | Html.html [ 29 | Html.head [ 30 | Html.title "examples" 31 | Html.link [ 32 | prop.rel "stylesheet" 33 | prop.type' "text/css" 34 | prop.href "/main.css" 35 | ] 36 | ] 37 | Html.body [ 38 | prop.style [ style.fontFamily("Arial, Helvetica, sans-serif"); style.color("#333") ] 39 | prop.children content 40 | ] 41 | ] 42 | 43 | let partial () = 44 | Html.h1 [ 45 | prop.style [ style.fontSize(100); style.color("#137373") ] 46 | prop.text "examples" 47 | ] 48 | 49 | let index (model : Message) = 50 | [ 51 | partial () 52 | Html.p [ Html.text model.Text ] 53 | ] |> layout 54 | 55 | // --------------------------------- 56 | // Web app 57 | // --------------------------------- 58 | 59 | let indexHandler (name : string) = 60 | let greetings = sprintf "Hello %s, from Giraffe!" name 61 | let model = { Text = greetings } 62 | let view = Views.index model 63 | 64 | htmlString (Render.htmlDocument view) 65 | 66 | let webApp : HttpHandler = 67 | choose [ 68 | GET >=> 69 | choose [ 70 | route "/" >=> indexHandler "world" 71 | routef "/hello/%s" indexHandler 72 | ] 73 | setStatusCode 404 >=> text "Not Found" ] 74 | 75 | type Startup() = 76 | member __.ConfigureServices (services : IServiceCollection) = 77 | // Register default Giraffe dependencies 78 | services.AddGiraffe() |> ignore 79 | 80 | member __.Configure (app: IApplicationBuilder) (env: IWebHostEnvironment) (loggerFactory: ILoggerFactory) = 81 | // Add Giraffe to the ASP.NET Core pipeline 82 | app.UseGiraffe webApp 83 | 84 | let port = 8080 85 | [] 86 | let main _ = 87 | WebHost 88 | .CreateDefaultBuilder() 89 | .UseStartup() 90 | .UseUrls("http://0.0.0.0:" + port.ToString () + "/") 91 | .Build() 92 | .Run() 93 | 94 | 0 -------------------------------------------------------------------------------- /examples/giraffe/README.md: -------------------------------------------------------------------------------- 1 | # examples 2 | 3 | A [Giraffe](https://github.com/giraffe-fsharp/Giraffe) web application, which has been created via the `dotnet new giraffe` command. 4 | 5 | ## Build and test the application 6 | 7 | ### Windows 8 | 9 | Run the `build.bat` script in order to restore, build and test (if you've selected to include tests) the application: 10 | 11 | ``` 12 | > ./build.bat 13 | ``` 14 | 15 | ### Linux/macOS 16 | 17 | Run the `build.sh` script in order to restore, build and test (if you've selected to include tests) the application: 18 | 19 | ``` 20 | $ ./build.sh 21 | ``` 22 | 23 | ## Run the application 24 | 25 | After a successful build you can start the web application by executing the following command in your terminal: 26 | 27 | ``` 28 | dotnet run src/examples 29 | ``` 30 | 31 | After the application has started visit [http://localhost:5000](http://localhost:5000) in your preferred browser. -------------------------------------------------------------------------------- /examples/giraffe/build.bat: -------------------------------------------------------------------------------- 1 | dotnet restore 2 | dotnet build 3 | 4 | -------------------------------------------------------------------------------- /examples/giraffe/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | dotnet restore 3 | dotnet build 4 | 5 | -------------------------------------------------------------------------------- /examples/giraffe/giraffe.fsproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | portable 6 | examples 7 | Exe 8 | false 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /nuget-packages/Feliz.Bulma.ViewEngine.0.26.0.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbrattli/Feliz.ViewEngine/66fa36f775ac2356d53fa75c0ce66745a9cce293/nuget-packages/Feliz.Bulma.ViewEngine.0.26.0.nupkg -------------------------------------------------------------------------------- /nuget-packages/Feliz.ViewEngine.0.26.0.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbrattli/Feliz.ViewEngine/66fa36f775ac2356d53fa75c0ce66745a9cce293/nuget-packages/Feliz.ViewEngine.0.26.0.nupkg -------------------------------------------------------------------------------- /paket.dependencies: -------------------------------------------------------------------------------- 1 | source https://www.nuget.org/api/v2 2 | storage: none 3 | 4 | group Main 5 | source https://www.nuget.org/api/v2 6 | storage: none 7 | framework: netstandard2.0 8 | nuget FSharp.Core ~> 4.7 lowest_matching: true 9 | 10 | group Test 11 | source https://www.nuget.org/api/v2 12 | storage: none 13 | 14 | nuget FSharp.Core ~> 4.7 15 | nuget coverlet.msbuild 16 | nuget Unquote ~> 4 17 | nuget xunit ~> 2 18 | nuget xunit.runner.visualstudio ~> 2 19 | nuget Microsoft.NET.Test.Sdk ~> 16 20 | nuget MSTest.TestAdapter ~> 1 21 | nuget MSTest.TestFramework ~> 1 22 | 23 | group Bulma 24 | source https://www.nuget.org/api/v2 25 | storage: none 26 | framework: netstandard2.0 27 | 28 | nuget FSharp.Core ~> 4.7 lowest_matching: true 29 | nuget Feliz.ViewEngine >= 0.15 30 | -------------------------------------------------------------------------------- /src/Colors.fs: -------------------------------------------------------------------------------- 1 | namespace Feliz.ViewEngine 2 | 3 | //fsharplint:disable 4 | 5 | /// Contains a list of HTML5 colors from https://htmlcolorcodes.com/color-names/ 6 | module color = 7 | /// Creates a color from components [hue](https://en.wikipedia.org/wiki/Hue), [saturation](https://en.wikipedia.org/wiki/Colorfulness) and [lightness](https://en.wikipedia.org/wiki/Lightness) where hue is a number that goes from 0 to 360 and both 8 | /// the `saturation` and `lightness` go from 0 to 100 as they are percentages. 9 | let hsl (hue: float, saturation: float, lightness: float) = 10 | "hsl(" + (string hue) + "," + (string saturation) + "%," + (string lightness) + "%)" 11 | let rgb (r: int, g: int, b: int) = 12 | "rgb(" + (string r) + "," + (string g) + "," + (string b) + ")" 13 | let rgba (r: int, g: int, b: int, a) = 14 | "rgba(" + (string r) + "," + (string g) + "," + (string b) + "," + (string a) + ")" 15 | let [] indianRed = "#CD5C5C" 16 | let [] lightCoral = "#F08080" 17 | let [] salmon = "#FA8072" 18 | let [] darkSalmon = "#E9967A" 19 | let [] lightSalmon = "#FFA07A" 20 | let [] crimson = "#DC143C" 21 | let [] red = "#FF0000" 22 | let [] fireBrick = "#B22222" 23 | let [] darkRed = "#8B0000" 24 | let [] pink = "#FFC0CB" 25 | let [] lightPink = "#FFB6C1" 26 | let [] hotPink = "#FF69B4" 27 | let [] deepPink = "#FF1493" 28 | let [] mediumVioletRed = "#C71585" 29 | let [] paleVioletRed = "#DB7093" 30 | let [] coral = "#FF7F50" 31 | let [] tomato = "#FF6347" 32 | let [] orangeRed = "#FF4500" 33 | let [] darkOrange = "#FF8C00" 34 | let [] orange = "#FFA500" 35 | let [] gold = "#FFD700" 36 | let [] yellow = "#FFFF00" 37 | let [] lightYellow = "#FFFFE0" 38 | let [] limonChiffon = "#FFFACD" 39 | let [] lightGoldenRodYellow = "#FAFAD2" 40 | let [] papayaWhip = "#FFEFD5" 41 | let [] moccasin = "#FFE4B5" 42 | let [] peachPuff = "#FFDAB9" 43 | let [] paleGoldenRod = "#EEE8AA" 44 | let [] khaki = "#F0E68C" 45 | let [] darkKhaki = "#BDB76B" 46 | let [] lavender = "#E6E6FA" 47 | let [] thistle = "#D8BFD8" 48 | let [] plum = "#DDA0DD" 49 | let [] violet = "#EE82EE" 50 | let [] orchid = "#DA70D6" 51 | let [] fuchsia = "#FF00FF" 52 | let [] magenta = "#FF00FF" 53 | let [] mediumOrchid = "#BA55D3" 54 | let [] mediumPurple = "#9370DB" 55 | let [] rebeccaPurple = "#663399" 56 | let [] blueViolet = "#8A2BE2" 57 | let [] darkViolet = "#9400D3" 58 | let [] darkOrchid = "#9932CC" 59 | let [] darkMagenta = "#8B008B" 60 | let [] purple = "#800080" 61 | let [] indigo = "#4B0082" 62 | let [] slateBlue = "#6A5ACD" 63 | let [] darkSlateBlue = "#483D8B" 64 | let [] mediumSlateBlue = "#7B68EE" 65 | let [] greenYellow = "#ADFF2F" 66 | let [] chartreuse = "#7FFF00" 67 | let [] lawnGreen = "#7CFC00" 68 | let [] lime = "#00FF00" 69 | let [] limeGreen = "#32CD32" 70 | let [] paleGreen = "#98FB98" 71 | let [] lightGreen = "#90EE90" 72 | let [] mediumSpringGreen = "#00FA9A" 73 | let [] springGreen = "#00FF7F" 74 | let [] mediumSeaGreen = "#3CB371" 75 | let [] seaGreen = "#2E8B57" 76 | let [] forestGreen = "#228B22" 77 | let [] green = "#008000" 78 | let [] darkGreen = "#006400" 79 | let [] yellowGreen = "#9ACD32" 80 | let [] oliveDrab = "#6B8E23" 81 | let [] olive = "#808000" 82 | let [] darkOliveGreen = "#556B2F" 83 | let [] mediumAquamarine = "#66CDAA" 84 | let [] darkSeaGreen = "#8FBC8B" 85 | let [] lightSeaGreen = "#20B2AA" 86 | let [] darkCyan = "#008B8B" 87 | let [] teal = "#008080" 88 | let [] aqua = "#00FFFF" 89 | let [] cyan = "#00FFFF" 90 | let [] lightCyan = "#E0FFFF" 91 | let [] paleTurqouise = "#AFEEEE" 92 | let [] aquaMarine = "#7FFFD4" 93 | let [] turqouise = "#AFEEEE" 94 | let [] mediumTurqouise = "#48D1CC" 95 | let [] darkTurqouise = "#00CED1" 96 | let [] cadetBlue = "#5F9EA0" 97 | let [] steelBlue = "#4682B4" 98 | let [] lightSteelBlue = "#B0C4DE" 99 | let [] powederBlue = "#B0E0E6" 100 | let [] lightBlue = "#ADD8E6" 101 | let [] skyBlue = "#87CEEB" 102 | let [] lightSkyBlue = "#87CEFA" 103 | let [] deepSkyBlue = "#00BFFF" 104 | let [] dodgerBlue = "#1E90FF" 105 | let [] cornFlowerBlue = "#6495ED" 106 | let [] royalBlue = "#4169E1" 107 | let [] blue = "#0000FF" 108 | let [] mediumBlue = "#0000CD" 109 | let [] darkBlue = "#00008B" 110 | let [] navy = "#000080" 111 | let [] midnightBlue = "#191970" 112 | let [] cornSilk = "#FFF8DC" 113 | let [] blanchedAlmond = "#FFEBCD" 114 | let [] bisque = "#FFE4C4" 115 | let [] navajoWhite = "#FFDEAD" 116 | let [] wheat = "#F5DEB3" 117 | let [] burlyWood = "#DEB887" 118 | let [] tan = "#D2B48C" 119 | let [] rosyBrown = "#BC8F8F" 120 | let [] sandyBrown = "#F4A460" 121 | let [] goldenRod = "#DAA520" 122 | let [] darkGoldenRod = "#B8860B" 123 | let [] peru = "#CD853F" 124 | let [] chocolate = "#D2691E" 125 | let [] saddleBrown = "#8B4513" 126 | let [] sienna = "#A0522D" 127 | let [] brown = "#A52A2A" 128 | let [] maroon = "#A52A2A" 129 | let [] white = "#FFFFFF" 130 | let [] snow = "#FFFAFA" 131 | let [] honeyDew = "#F0FFF0" 132 | let [] mintCream = "#F5FFFA" 133 | let [] azure = "#F0FFFF" 134 | let [] aliceBlue = "#F0F8FF" 135 | let [] ghostWhite = "#F8F8FF" 136 | let [] whiteSmoke = "#F5F5F5" 137 | let [] seaShell = "#FFF5EE" 138 | let [] beige = "#F5F5DC" 139 | let [] oldLace = "#FDF5E6" 140 | let [] floralWhite = "#FFFAF0" 141 | let [] ivory = "#FFFFF0" 142 | let [] antiqueWhite = "#FAEBD7" 143 | let [] linen = "#FAF0E6" 144 | let [] lavenderBlush = "#FFF0F5" 145 | let [] mistyRose = "#FFE4E1" 146 | let [] gainsBoro = "#DCDCDC" 147 | let [] lightGray = "#D3D3D3" 148 | let [] silver = "#C0C0C0" 149 | let [] darkGray = "#A9A9A9" 150 | let [] gray = "#808080" 151 | let [] dimGray = "#696969" 152 | let [] lightSlateGray = "#778899" 153 | let [] slateGray = "#708090" 154 | let [] darkSlateGray = "#2F4F4F" 155 | let [] black = "#000000" 156 | let [] transparent = "transparent" 157 | -------------------------------------------------------------------------------- /src/Feliz.ViewEngine.fsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0 5 | Feliz.ViewEngine 6 | Dag Brattli 7 | Brattli Labs 8 | Brattli Labs 9 | LICENSE 10 | https://github.com/dbrattli/Feliz.ViewEngine 11 | true 12 | true 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/Fonts.fs: -------------------------------------------------------------------------------- 1 | namespace Feliz.ViewEngine 2 | 3 | //fsharplint:disable 4 | 5 | // 6 | // Note that the rest of the file is manually copied directly from Feliz. 7 | // 8 | 9 | /// Contains a list of CSS Fonts from https://www.tutorialbrain.com/css_tutorial/css_font_family_list/ 10 | module font = 11 | let [] abadiMTCondensedLight = "Abadi MT Condensed Light" 12 | let [] aharoni = "Aharoni" 13 | let [] aharoniBold = "Aharoni Bold" 14 | let [] aldhabi = "Aldhabi" 15 | let [] alternateGothic2BT = "AlternateGothic2 BT" 16 | let [] andaleMono = "Andale Mono" 17 | let [] andalus = "Andalus" 18 | let [] angsanaNew = "Angsana New" 19 | let [] angsanaUPC = "AngsanaUPC" 20 | let [] aparajita = "Aparajita" 21 | let [] appleChancery = "Apple Chancery" 22 | let [] arabicTypesetting = "Arabic Typesetting" 23 | let [] arial = "Arial" 24 | let [] arialBlack = "Arial Black" 25 | let [] arialNarrow = "Arial narrow" 26 | let [] arialNova = "Arial Nova" 27 | let [] arialRoundedMTBold = "Arial Rounded MT Bold" 28 | let [] arnoldboecklin = "Arnoldboecklin" 29 | let [] avantaGarde = "Avanta Garde" 30 | let [] bahnschrift = "Bahnschrift" 31 | let [] bahnschriftLight = "Bahnschrift Light" 32 | let [] bahnschriftSemiBold = "Bahnschrift SemiBold" 33 | let [] bahnschriftSemiLight = "Bahnschrift SemiLight" 34 | let [] baskerville = "Baskerville" 35 | let [] batang = "Batang" 36 | let [] batangChe = "BatangChe" 37 | let [] bigCaslon = "Big Caslon" 38 | let [] bizUDGothic = "BIZ UDGothic" 39 | let [] bizUDMinchoMedium = "BIZ UDMincho Medium" 40 | let [] blippo = "Blippo" 41 | let [] bodoniMT = "Bodoni MT" 42 | let [] bookAntiqua = "Book Antiqua" 43 | let [] Bookman = "Bookman" 44 | let [] bradlyHand = "Bradley Hand" 45 | let [] browalliaNew = "Browallia New" 46 | let [] browalliaUPC = "BrowalliaUPC" 47 | let [] brushScriptMT = "Brush Script MT" 48 | let [] brushScriptStd = "Brush Script Std" 49 | let [] brushStroke = "Brushstroke" 50 | let [] calibri = "Calibri" 51 | let [] calibriLight = "Calibri Light" 52 | let [] calistoMT = "Calisto MT" 53 | let [] cambodian = "Cambodian" 54 | let [] cambria = "Cambria" 55 | let [] cambriaMath = "Cambria Math" 56 | let [] candara = "Candara" 57 | let [] centuryGothic = "Century Gothic" 58 | let [] chalkDuster = "Chalkduster" 59 | let [] cherokee = "Cherokee" 60 | let [] comicSans = "Comic Sans" 61 | let [] comicSansMS = "Comic Sans MS" 62 | let [] consolas = "Consolas" 63 | let [] constantia = "Constantia" 64 | let [] copperPlate = "Copperplate" 65 | let [] copperPlateGothicLight = "Copperplate Gothic Light" 66 | let [] copperPlateGothicBold = "Copperplate Gothic Bold" 67 | let [] corbel = "Corbel" 68 | let [] cordiaNew = "Cordia New" 69 | let [] cordiaUPC = "CordiaUPC" 70 | let [] coronetScript = "Coronet script" 71 | let [] courier = "Courier" 72 | let [] courierNew = "Courier New" 73 | let [] daunPenh = "DaunPenh" 74 | let [] david = "David" 75 | let [] dengXian = "DengXian" 76 | let [] dfKaiSB = "DFKai-SB" 77 | let [] didot = "Didot" 78 | let [] dilleniaUPC = "DilleniaUPC" 79 | let [] dokChampa = "DokChampa" 80 | let [] dotum = "Dotum" 81 | let [] dotumChe = "DotumChe" 82 | let [] ebrima = "Ebrima" 83 | let [] estrangeloEdessa = "Estrangelo Edessa" 84 | let [] eucrosiaUPC = "EucrosiaUPC" 85 | let [] euphemia = "Euphemia" 86 | let [] fangSong = "FangSong" 87 | let [] florence = "Florence" 88 | let [] franklinGothicMedium = "Franklin Gothic Medium" 89 | let [] frankRuehl = "FrankRuehl" 90 | let [] fressiaUPC = "FressiaUPC" 91 | let [] futara = "Futara" 92 | let [] gabriola = "Gabriola" 93 | let [] garamond = "Garamond" 94 | let [] gautami = "Gautami" 95 | let [] geneva = "Geneva" 96 | let [] georgia = "Georgia" 97 | let [] georgiaPro = "Georgia Pro" 98 | let [] gillSans = "Gill Sans" 99 | let [] gillSansNova = "Gill Sans Nova" 100 | let [] gisha = "Gisha" 101 | let [] goudyOldStyle = "Goudy Old Style" 102 | let [] gulim = "Gulim" 103 | let [] gulimChe = "GulimChe" 104 | let [] gungsuh = "Gungsuh" 105 | let [] gungsuhChe = "GungsuhChe" 106 | let [] hebrew = "Hebrew" 107 | let [] helvetica = "Helvetica" 108 | let [] hoeflerText = "Hoefler Text" 109 | let [] holoLensMDL2Assets = "HoloLens MDL2 Assets" 110 | let [] impact = "Impact" 111 | let [] inkFree = "Ink Free" 112 | let [] irisUPC = "IrisUPC" 113 | let [] iskoolaPota = "Iskoola Pota" 114 | let [] japanese = "Japanese" 115 | let [] jasmineUPC = "JasmineUPC" 116 | let [] javaneseText = "Javanese Text" 117 | let [] jazzLET = "Jazz LET" 118 | let [] kaiTi = "KaiTi" 119 | let [] kalinga = "Kalinga" 120 | let [] kartika = "Kartika" 121 | let [] khmerUI = "Khmer UI" 122 | let [] kodchiangUPC = "KodchiangUPC" 123 | let [] kokila = "Kokila" 124 | let [] korean = "Korean" 125 | let [] lao = "Lao" 126 | let [] laoUI = "Lao UI" 127 | let [] latha = "Latha" 128 | let [] leelawadee = "Leelawadee" 129 | let [] leelawadeeUI = "Leelawadee UI" 130 | let [] leelawadeeUISemilight = "Leelawadee UI Semilight" 131 | let [] levenimMT = "Levenim MT" 132 | let [] lilyUPC = "LilyUPC" 133 | let [] lucidaBright = "Lucida Bright" 134 | let [] lucidaConsole = "Lucida Console" 135 | let [] lucidaHandwriting = "Lucida Handwriting" 136 | let [] lucidaSans = "Lucida Sans" 137 | let [] lucidaSansTypewriter = "Lucida Sans Typewriter" 138 | let [] lucidaSansUnicode = "Lucida Sans Unicode" 139 | let [] lucidaTypewriter = "Lucidatypewriter" 140 | let [] luminari = "Luminari" 141 | let [] malgunGothic = "Malgun Gothic" 142 | let [] malgunGothicSemilight = "Malgun Gothic Semilight" 143 | let [] mangal = "Mangal" 144 | let [] markerFelt = "Marker Felt" 145 | let [] marlett = "Marlett" 146 | let [] meiryo = "Meiryo" 147 | let [] meiryoUI = "Meiryo UI" 148 | let [] microsoftHimalaya = "Microsoft Himalaya" 149 | let [] microsoftJhengHei = "Microsoft JhengHei" 150 | let [] microsoftJhengHeiUI = "Microsoft JhengHei UI" 151 | let [] microsoftNewTaiLue = "Microsoft New Tai Lue" 152 | let [] microsoftPhagsPa = "Microsoft PhagsPa" 153 | let [] microsoftSansSerif = "Microsoft Sans Serif" 154 | let [] microsoftTaiLe = "Microsoft Tai Le" 155 | let [] microsoftUighur = "Microsoft Uighur" 156 | let [] microsoftYaHei = "Microsoft YaHei" 157 | let [] microsoftYaHeiUI = "Microsoft YaHei UI" 158 | let [] microsoftYiBaiti = "Microsoft Yi Baiti" 159 | let [] mingLiU = "MingLiU" 160 | let [] mingLiUHKSCS = "MingLiU_HKSCS" 161 | let [] mingLiUHKSCSExtB = "MingLiU_HKSCS-ExtB" 162 | let [] mingLiUExtB = "MingLiU-ExtB" 163 | let [] miriam = "Miriam" 164 | let [] monaco = "Monaco" 165 | let [] mongolianBaiti = "Mongolian Baiti" 166 | let [] moolBoran = "MoolBoran" 167 | let [] msGothic = "MS Gothic" 168 | let [] msMincho = "MS Mincho" 169 | let [] msPGothic = "MS PGothic" 170 | let [] msPMincho = "MS PMincho" 171 | let [] msUIGothic = "MS UI Gothic" 172 | let [] mvBoli = "MV Boli" 173 | let [] myanmarText = "Myanmar Text" 174 | let [] narkisim = "Narkisim" 175 | let [] neueHaasGroteskTextPro = "Neue Haas Grotesk Text Pro" 176 | let [] newCenturySchoolbook = "New Century Schoolbook" 177 | let [] newsGothicMT = "News Gothic MT" 178 | let [] nirmalaUI = "Nirmala UI" 179 | let [] noAutoLanguageAssoc = "No automatic language associations" 180 | let [] noto = "Noto" 181 | let [] nSimSun = "NSimSun" 182 | let [] nyala = "Nyala" 183 | let [] oldTown = "Oldtown" 184 | let [] optima = "Optima" 185 | let [] palatino = "Palatino" 186 | let [] palatinoLinotype = "Palatino Linotype" 187 | let [] papyrus = "papyrus" 188 | let [] parkAvenue = "Parkavenue" 189 | let [] perpetua = "Perpetua" 190 | let [] plantagenetCherokee = "Plantagenet Cherokee" 191 | let [] PMingLiU = "PMingLiU" 192 | let [] raavi = "Raavi" 193 | let [] rockwell = "Rockwell" 194 | let [] rockwellExtraBold = "Rockwell Extra Bold" 195 | let [] rockwellNova = "Rockwell Nova" 196 | let [] rockwellNovaCond = "Rockwell Nova Cond" 197 | let [] rockwellNovaExtraBold = "Rockwell Nova Extra Bold" 198 | let [] rod = "Rod" 199 | let [] sakkalMajalla = "Sakkal Majalla" 200 | let [] sanskritText = "Sanskrit Text" 201 | let [] segoeMDL2Assets = "segoeMDL2Assets" 202 | let [] segoePrint = "Segoe Print" 203 | let [] segoeScript = "Segoe Script" 204 | let [] segoeUI = "Segoe UI" 205 | let [] segoeUIEmoji = "Segoe UI Emoji" 206 | let [] segoeUIHistoric = "Segoe UI Historic" 207 | let [] segoeUISymbol = "Segoe UI Symbol" 208 | let [] shonarBangla = "Shonar Bangla" 209 | let [] shruti = "Shruti" 210 | let [] simHei = "SimHei" 211 | let [] simKai = "SimKai" 212 | let [] simplifiedArabic = "Simplified Arabic" 213 | let [] simplifiedChinese = "Simplified Chinese" 214 | let [] simSun = "SimSun" 215 | let [] simSunExtB = "SimSun-ExtB" 216 | let [] sitka = "Sitka" 217 | let [] snellRoundhan = "Snell Roundhan" 218 | let [] stencilStd = "Stencil Std" 219 | let [] sylfaen = "Sylfaen" 220 | let [] symbol = "Symbol" 221 | let [] tahoma = "Tahoma" 222 | let [] thai = "Thai" 223 | let [] timesNewRoman = "Times New Roman" 224 | let [] traditionalArabic = "Traditional Arabic" 225 | let [] traditionalChinese = "Traditional Chinese" 226 | let [] trattatello = "Trattatello" 227 | let [] trebuchetMS = "Trebuchet MS" 228 | let [] udDigiKyokasho = "UD Digi Kyokasho" 229 | let [] udDigiKyokashoNKR = "UD Digi Kyokasho NK-R" 230 | let [] udDigiKyokashoNPR = "UD Digi Kyokasho NP-R" 231 | let [] udDigiKyokashoNR = "UD Digi Kyokasho N-R" 232 | let [] urduTypesetting = "Urdu Typesetting" 233 | let [] urwChancery = "URW Chancery" 234 | let [] utsaah = "Utsaah" 235 | let [] vani = "Vani" 236 | let [] verdana = "Verdana" 237 | let [] verdanaPro = "Verdana Pro" 238 | let [] vijaya = "Vijaya" 239 | let [] vrinda = "Vrinda" 240 | let [] Webdings = "Webdings" 241 | let [] westminster = "Westminster" 242 | let [] wingdings = "Wingdings" 243 | let [] yuGothic = "Yu Gothic" 244 | let [] yuGothicUI = "Yu Gothic UI" 245 | let [] yuMincho = "Yu Mincho" 246 | let [] zapfChancery = "Zapf Chancery" 247 | -------------------------------------------------------------------------------- /src/Html.fs: -------------------------------------------------------------------------------- 1 | namespace Feliz.ViewEngine 2 | 3 | // fsharplint:disable 4 | 5 | type Html = 6 | static member inline a xs = Interop.createElement "a" xs 7 | static member inline a (children: #seq) = Interop.reactElementWithChildren "a" children 8 | 9 | static member inline abbr xs = Interop.createElement "abbr" xs 10 | static member inline abbr (value: float) = Interop.reactElementWithChild "abbr" value 11 | static member inline abbr (value: int) = Interop.reactElementWithChild "abbr" value 12 | static member inline abbr (value: ReactElement) = Interop.reactElementWithChild "abbr" value 13 | static member inline abbr (value: string) = Interop.reactElementWithChild "abbr" value 14 | static member inline abbr (children: #seq) = Interop.reactElementWithChildren "abbr" children 15 | 16 | static member inline address xs = Interop.createElement "address" xs 17 | static member inline address (value: float) = Interop.reactElementWithChild "address" value 18 | static member inline address (value: int) = Interop.reactElementWithChild "address" value 19 | static member inline address (value: ReactElement) = Interop.reactElementWithChild "address" value 20 | static member inline address (value: string) = Interop.reactElementWithChild "address" value 21 | static member inline address (children: #seq) = Interop.reactElementWithChildren "address" children 22 | 23 | static member inline anchor xs = Interop.createElement "a" xs 24 | static member inline anchor (children: #seq) = Interop.reactElementWithChildren "a" children 25 | 26 | static member inline area xs = Interop.createElement "area" xs 27 | 28 | static member inline article xs = Interop.createElement "article" xs 29 | static member inline article (children: #seq) = Interop.reactElementWithChildren "article" children 30 | 31 | static member inline aside xs = Interop.createElement "aside" xs 32 | static member inline aside (children: #seq) = Interop.reactElementWithChildren "aside" children 33 | 34 | static member inline audio xs = Interop.createElement "audio" xs 35 | static member inline audio (children: #seq) = Interop.reactElementWithChildren "audio" children 36 | 37 | static member inline b xs = Interop.createElement "b" xs 38 | static member inline b (value: float) = Interop.reactElementWithChild "b" value 39 | static member inline b (value: int) = Interop.reactElementWithChild "b" value 40 | static member inline b (value: ReactElement) = Interop.reactElementWithChild "b" value 41 | static member inline b (value: string) = Interop.reactElementWithChild "b" value 42 | static member inline b (children: #seq) = Interop.reactElementWithChildren "b" children 43 | 44 | static member inline base' xs = Interop.createVoidElement "base" xs 45 | 46 | static member inline bdi xs = Interop.createElement "bdi" xs 47 | static member inline bdi (value: float) = Interop.reactElementWithChild "bdi" value 48 | static member inline bdi (value: int) = Interop.reactElementWithChild "bdi" value 49 | static member inline bdi (value: ReactElement) = Interop.reactElementWithChild "bdi" value 50 | static member inline bdi (value: string) = Interop.reactElementWithChild "bdi" value 51 | static member inline bdi (children: #seq) = Interop.reactElementWithChildren "bdi" children 52 | 53 | static member inline bdo xs = Interop.createElement "bdo" xs 54 | static member inline bdo (value: float) = Interop.reactElementWithChild "bdo" value 55 | static member inline bdo (value: int) = Interop.reactElementWithChild "bdo" value 56 | static member inline bdo (value: ReactElement) = Interop.reactElementWithChild "bdo" value 57 | static member inline bdo (value: string) = Interop.reactElementWithChild "bdo" value 58 | static member inline bdo (children: #seq) = Interop.reactElementWithChildren "bdo" children 59 | 60 | static member inline blockquote xs = Interop.createElement "blockquote" xs 61 | static member inline blockquote (value: float) = Interop.reactElementWithChild "blockquote" value 62 | static member inline blockquote (value: int) = Interop.reactElementWithChild "blockquote" value 63 | static member inline blockquote (value: ReactElement) = Interop.reactElementWithChild "blockquote" value 64 | static member inline blockquote (value: string) = Interop.reactElementWithChild "blockquote" value 65 | static member inline blockquote (children: #seq) = Interop.reactElementWithChildren "blockquote" children 66 | 67 | static member inline body xs = Interop.createElement "body" xs 68 | static member inline body (value: float) = Interop.reactElementWithChild "body" value 69 | static member inline body (value: int) = Interop.reactElementWithChild "body" value 70 | static member inline body (value: ReactElement) = Interop.reactElementWithChild "body" value 71 | static member inline body (value: string) = Interop.reactElementWithChild "body" value 72 | static member inline body (children: #seq) = Interop.reactElementWithChildren "body" children 73 | 74 | static member inline br xs = Interop.createVoidElement "br" xs 75 | 76 | static member inline button xs = Interop.createElement "button" xs 77 | static member inline button (children: #seq) = Interop.reactElementWithChildren "button" children 78 | 79 | static member inline canvas xs = Interop.createElement "canvas" xs 80 | 81 | static member inline caption xs = Interop.createElement "caption" xs 82 | static member inline caption (value: float) = Interop.reactElementWithChild "caption" value 83 | static member inline caption (value: int) = Interop.reactElementWithChild "caption" value 84 | static member inline caption (value: ReactElement) = Interop.reactElementWithChild "caption" value 85 | static member inline caption (value: string) = Interop.reactElementWithChild "caption" value 86 | static member inline caption (children: #seq) = Interop.reactElementWithChildren "caption" children 87 | 88 | static member inline cite xs = Interop.createElement "cite" xs 89 | static member inline cite (value: float) = Interop.reactElementWithChild "cite" value 90 | static member inline cite (value: int) = Interop.reactElementWithChild "cite" value 91 | static member inline cite (value: ReactElement) = Interop.reactElementWithChild "cite" value 92 | static member inline cite (value: string) = Interop.reactElementWithChild "cite" value 93 | static member inline cite (children: #seq) = Interop.reactElementWithChildren "cite" children 94 | 95 | static member inline circle xs = Interop.createElement "circle" xs 96 | static member inline circle (children: #seq) = Interop.reactElementWithChildren "circle" children 97 | 98 | static member inline clipPath xs = Interop.createElement "clipPath" xs 99 | static member inline clipPath (children: #seq) = Interop.reactElementWithChildren "clipPath" children 100 | 101 | static member inline code xs = Interop.createElement "code" xs 102 | static member inline code (value: bool) = Interop.reactElementWithChild "code" value 103 | static member inline code (value: float) = Interop.reactElementWithChild "code" value 104 | static member inline code (value: int) = Interop.reactElementWithChild "code" value 105 | static member inline code (value: ReactElement) = Interop.reactElementWithChild "code" value 106 | static member inline code (value: string) = Interop.reactElementWithChild "code" value 107 | static member inline code (children: #seq) = Interop.reactElementWithChildren "code" children 108 | 109 | static member inline col xs = Interop.createVoidElement "col" xs 110 | 111 | static member inline colgroup xs = Interop.createElement "colgroup" xs 112 | static member inline colgroup (children: #seq) = Interop.reactElementWithChildren "colgroup" children 113 | static member inline comment (content : string) = Interop.createRawTextElement (sprintf "" content) 114 | 115 | static member inline data xs = Interop.createElement "data" xs 116 | static member inline data (value: float) = Interop.reactElementWithChild "data" value 117 | static member inline data (value: int) = Interop.reactElementWithChild "data" value 118 | static member inline data (value: ReactElement) = Interop.reactElementWithChild "data" value 119 | static member inline data (value: string) = Interop.reactElementWithChild "data" value 120 | static member inline data (children: #seq) = Interop.reactElementWithChildren "data" children 121 | 122 | static member inline datalist xs = Interop.createElement "datalist" xs 123 | static member inline datalist (value: float) = Interop.reactElementWithChild "datalist" value 124 | static member inline datalist (value: int) = Interop.reactElementWithChild "datalist" value 125 | static member inline datalist (value: ReactElement) = Interop.reactElementWithChild "datalist" value 126 | static member inline datalist (value: string) = Interop.reactElementWithChild "datalist" value 127 | static member inline datalist (children: #seq) = Interop.reactElementWithChildren "datalist" children 128 | 129 | static member inline dd xs = Interop.createElement "dd" xs 130 | static member inline dd (value: float) = Interop.reactElementWithChild "dd" value 131 | static member inline dd (value: int) = Interop.reactElementWithChild "dd" value 132 | static member inline dd (value: ReactElement) = Interop.reactElementWithChild "dd" value 133 | static member inline dd (value: string) = Interop.reactElementWithChild "dd" value 134 | static member inline dd (children: #seq) = Interop.reactElementWithChildren "dd" children 135 | 136 | static member inline defs xs = Interop.createElement "defs" xs 137 | static member inline defs (children: #seq) = Interop.reactElementWithChildren "defs" children 138 | 139 | static member inline del xs = Interop.createElement "del" xs 140 | static member inline del (value: float) = Interop.reactElementWithChild "del" value 141 | static member inline del (value: int) = Interop.reactElementWithChild "del" value 142 | static member inline del (value: ReactElement) = Interop.reactElementWithChild "del" value 143 | static member inline del (value: string) = Interop.reactElementWithChild "del" value 144 | static member inline del (children: #seq) = Interop.reactElementWithChildren "del" children 145 | 146 | static member inline details xs = Interop.createElement "details" xs 147 | static member inline details (children: #seq) = Interop.reactElementWithChildren "details" children 148 | 149 | static member inline dfn xs = Interop.createElement "ins" xs 150 | static member inline dfn (value: float) = Interop.reactElementWithChild "dfn" value 151 | static member inline dfn (value: int) = Interop.reactElementWithChild "dfn" value 152 | static member inline dfn (value: ReactElement) = Interop.reactElementWithChild "dfn" value 153 | static member inline dfn (value: string) = Interop.reactElementWithChild "dfn" value 154 | static member inline dfn (children: #seq) = Interop.reactElementWithChildren "dfn" children 155 | 156 | static member inline dialog xs = Interop.createElement "dialog" xs 157 | static member inline dialog (value: float) = Interop.reactElementWithChild "dialog" value 158 | static member inline dialog (value: int) = Interop.reactElementWithChild "dialog" value 159 | static member inline dialog (value: ReactElement) = Interop.reactElementWithChild "dialog" value 160 | static member inline dialog (value: string) = Interop.reactElementWithChild "dialog" value 161 | static member inline dialog (children: #seq) = Interop.reactElementWithChildren "dialog" children 162 | 163 | /// The `
` tag defines a division or a section in an HTML document 164 | static member inline div xs = Interop.createElement "div" xs 165 | static member inline div (value: float) = Interop.reactElementWithChild "div" value 166 | static member inline div (value: int) = Interop.reactElementWithChild "div" value 167 | static member inline div (value: ReactElement) = Interop.reactElementWithChild "div" value 168 | static member inline div (value: string) = Interop.reactElementWithChild "div" value 169 | static member inline div (children: #seq) = Interop.reactElementWithChildren "div" children 170 | 171 | static member inline dl xs = Interop.createElement "dl" xs 172 | static member inline dl (children: #seq) = Interop.reactElementWithChildren "dl" children 173 | 174 | static member inline dt xs = Interop.createElement "dt" xs 175 | static member inline dt (value: float) = Interop.reactElementWithChild "dt" value 176 | static member inline dt (value: int) = Interop.reactElementWithChild "dt" value 177 | static member inline dt (value: ReactElement) = Interop.reactElementWithChild "dt" value 178 | static member inline dt (value: string) = Interop.reactElementWithChild "dt" value 179 | static member inline dt (children: #seq) = Interop.reactElementWithChildren "dt" children 180 | 181 | static member inline ellipse xs = Interop.createElement "ellipse" xs 182 | static member inline ellipse (children: #seq) = Interop.reactElementWithChildren "ellipse" children 183 | 184 | static member inline em xs = Interop.createElement "em" xs 185 | static member inline em (value: float) = Interop.reactElementWithChild "em" value 186 | static member inline em (value: int) = Interop.reactElementWithChild "em" value 187 | static member inline em (value: ReactElement) = Interop.reactElementWithChild "em" value 188 | static member inline em (value: string) = Interop.reactElementWithChild "em" value 189 | static member inline em (children: #seq) = Interop.reactElementWithChildren "em" children 190 | 191 | static member inline embed xs = Interop.createElement "embed" xs 192 | 193 | static member inline fieldSet xs = Interop.createElement "fieldset" xs 194 | static member inline fieldSet (children: #seq) = Interop.reactElementWithChildren "fieldset" children 195 | 196 | static member inline figcaption xs = Interop.createElement "figcaption" xs 197 | static member inline figcaption (children: #seq) = Interop.reactElementWithChildren "figcaption" children 198 | 199 | static member inline figure xs = Interop.createElement "figure" xs 200 | static member inline figure (children: #seq) = Interop.reactElementWithChildren "figure" children 201 | 202 | static member inline footer xs = Interop.createElement "footer" xs 203 | static member inline footer (children: #seq) = Interop.reactElementWithChildren "footer" children 204 | 205 | static member inline form xs = Interop.createElement "form" xs 206 | static member inline form (children: #seq) = Interop.reactElementWithChildren "form" children 207 | 208 | static member inline g xs = Interop.createElement "g" xs 209 | static member inline g (children: #seq) = Interop.reactElementWithChildren "g" children 210 | 211 | static member inline h1 xs = Interop.createElement "h1" xs 212 | static member inline h1 (value: float) = Interop.reactElementWithChild "h1" value 213 | static member inline h1 (value: int) = Interop.reactElementWithChild "h1" value 214 | static member inline h1 (value: ReactElement) = Interop.reactElementWithChild "h1" value 215 | static member inline h1 (value: string) = Interop.reactElementWithChild "h1" value 216 | static member inline h1 (children: #seq) = Interop.reactElementWithChildren "h1" children 217 | 218 | static member inline h2 xs = Interop.createElement "h2" xs 219 | static member inline h2 (value: float) = Interop.reactElementWithChild "h2" value 220 | static member inline h2 (value: int) = Interop.reactElementWithChild "h2" value 221 | static member inline h2 (value: ReactElement) = Interop.reactElementWithChild "h2" value 222 | static member inline h2 (value: string) = Interop.reactElementWithChild "h2" value 223 | static member inline h2 (children: #seq) = Interop.reactElementWithChildren "h2" children 224 | 225 | static member inline h3 xs = Interop.createElement "h3" xs 226 | static member inline h3 (value: float) = Interop.reactElementWithChild "h3" value 227 | static member inline h3 (value: int) = Interop.reactElementWithChild "h3" value 228 | static member inline h3 (value: ReactElement) = Interop.reactElementWithChild "h3" value 229 | static member inline h3 (value: string) = Interop.reactElementWithChild "h3" value 230 | static member inline h3 (children: #seq) = Interop.reactElementWithChildren "h3" children 231 | 232 | static member inline h4 xs = Interop.createElement "h4" xs 233 | static member inline h4 (value: float) = Interop.reactElementWithChild "h4" value 234 | static member inline h4 (value: int) = Interop.reactElementWithChild "h4" value 235 | static member inline h4 (value: ReactElement) = Interop.reactElementWithChild "h4" value 236 | static member inline h4 (value: string) = Interop.reactElementWithChild "h4" value 237 | static member inline h4 (children: #seq) = Interop.reactElementWithChildren "h4" children 238 | 239 | static member inline h5 xs = Interop.createElement "h5" xs 240 | static member inline h5 (value: float) = Interop.reactElementWithChild "h5" value 241 | static member inline h5 (value: int) = Interop.reactElementWithChild "h5" value 242 | static member inline h5 (value: ReactElement) = Interop.reactElementWithChild "h5" value 243 | static member inline h5 (value: string) = Interop.reactElementWithChild "h5" value 244 | static member inline h5 (children: #seq) = Interop.reactElementWithChildren "h5" children 245 | 246 | static member inline h6 xs = Interop.createElement "h6" xs 247 | static member inline h6 (value: float) = Interop.reactElementWithChild "h6" value 248 | static member inline h6 (value: int) = Interop.reactElementWithChild "h6" value 249 | static member inline h6 (value: ReactElement) = Interop.reactElementWithChild "h6" value 250 | static member inline h6 (value: string) = Interop.reactElementWithChild "h6" value 251 | static member inline h6 (children: #seq) = Interop.reactElementWithChildren "h6" children 252 | 253 | static member inline head xs = Interop.createElement "head" xs 254 | static member inline head (children: #seq) = Interop.reactElementWithChildren "head" children 255 | 256 | static member inline header xs = Interop.createElement "header" xs 257 | static member inline header (children: #seq) = Interop.reactElementWithChildren "header" children 258 | 259 | static member inline hr xs = Interop.createVoidElement "hr" xs 260 | 261 | static member inline html xs = Interop.createElement "html" xs 262 | static member inline html (children: #seq) = Interop.reactElementWithChildren "html" children 263 | 264 | static member inline i xs = Interop.createElement "i" xs 265 | static member inline i (value: float) = Interop.reactElementWithChild "i" value 266 | static member inline i (value: int) = Interop.reactElementWithChild "i" value 267 | static member inline i (value: ReactElement) = Interop.reactElementWithChild "i" value 268 | static member inline i (value: string) = Interop.reactElementWithChild "i" value 269 | static member inline i (children: #seq) = Interop.reactElementWithChildren "i" children 270 | 271 | static member inline iframe xs = Interop.createElement "iframe" xs 272 | 273 | static member inline img xs = Interop.createVoidElement "img" xs 274 | 275 | static member inline input xs = Interop.createVoidElement "input" xs 276 | 277 | static member inline ins xs = Interop.createElement "ins" xs 278 | static member inline ins (value: float) = Interop.reactElementWithChild "ins" value 279 | static member inline ins (value: int) = Interop.reactElementWithChild "ins" value 280 | static member inline ins (value: ReactElement) = Interop.reactElementWithChild "ins" value 281 | static member inline ins (value: string) = Interop.reactElementWithChild "ins" value 282 | static member inline ins (children: #seq) = Interop.reactElementWithChildren "ins" children 283 | 284 | static member inline kbd xs = Interop.createElement "kbd" xs 285 | static member inline kbd (value: float) = Interop.reactElementWithChild "kbd" value 286 | static member inline kbd (value: int) = Interop.reactElementWithChild "kbd" value 287 | static member inline kbd (value: ReactElement) = Interop.reactElementWithChild "kbd" value 288 | static member inline kbd (value: string) = Interop.reactElementWithChild "kbd" value 289 | static member inline kbd (children: #seq) = Interop.reactElementWithChildren "kbd" children 290 | 291 | static member inline label xs = Interop.createElement "label" xs 292 | static member inline label (children: #seq) = Interop.reactElementWithChildren "label" children 293 | 294 | static member inline legend xs = Interop.createElement "legend" xs 295 | static member inline legend (value: float) = Interop.reactElementWithChild "legend" value 296 | static member inline legend (value: int) = Interop.reactElementWithChild "legend" value 297 | static member inline legend (value: ReactElement) = Interop.reactElementWithChild "legend" value 298 | static member inline legend (value: string) = Interop.reactElementWithChild "legend" value 299 | static member inline legend (children: #seq) = Interop.reactElementWithChildren "legend" children 300 | 301 | static member inline li xs = Interop.createElement "li" xs 302 | static member inline li (value: float) = Interop.reactElementWithChild "li" value 303 | static member inline li (value: int) = Interop.reactElementWithChild "li" value 304 | static member inline li (value: ReactElement) = Interop.reactElementWithChild "li" value 305 | static member inline li (value: string) = Interop.reactElementWithChild "li" value 306 | static member inline li (children: #seq) = Interop.reactElementWithChildren "li" children 307 | 308 | static member inline line xs = Interop.createElement "line" xs 309 | static member inline line (children: #seq) = Interop.reactElementWithChildren "line" children 310 | 311 | static member inline linearGradient xs = Interop.createElement "linearGradient" xs 312 | static member inline linearGradient (children: #seq) = Interop.reactElementWithChildren "linearGradient" children 313 | 314 | static member inline link xs = Interop.createVoidElement "link" xs 315 | 316 | static member inline listItem xs = Interop.createElement "li" xs 317 | static member inline listItem (value: float) = Interop.reactElementWithChild "li" value 318 | static member inline listItem (value: int) = Interop.reactElementWithChild "li" value 319 | static member inline listItem (value: ReactElement) = Interop.reactElementWithChild "li" value 320 | static member inline listItem (value: string) = Interop.reactElementWithChild "li" value 321 | static member inline listItem (children: #seq) = Interop.reactElementWithChildren "li" children 322 | 323 | static member inline main xs = Interop.createElement "main" xs 324 | static member inline main (children: #seq) = Interop.reactElementWithChildren "main" children 325 | 326 | static member inline map xs = Interop.createElement "map" xs 327 | static member inline map (children: #seq) = Interop.reactElementWithChildren "map" children 328 | 329 | static member inline mark xs = Interop.createElement "mark" xs 330 | static member inline mark (value: float) = Interop.reactElementWithChild "mark" value 331 | static member inline mark (value: int) = Interop.reactElementWithChild "mark" value 332 | static member inline mark (value: ReactElement) = Interop.reactElementWithChild "mark" value 333 | static member inline mark (value: string) = Interop.reactElementWithChild "mark" value 334 | static member inline mark (children: #seq) = Interop.reactElementWithChildren "mark" children 335 | 336 | static member inline meta xs = Interop.createVoidElement "meta" xs 337 | 338 | static member inline meter xs = Interop.createElement "meter" xs 339 | static member inline meter (value: float) = Interop.reactElementWithChild "meter" value 340 | static member inline meter (value: int) = Interop.reactElementWithChild "meter" value 341 | static member inline meter (value: ReactElement) = Interop.reactElementWithChild "meter" value 342 | static member inline meter (value: string) = Interop.reactElementWithChild "meter" value 343 | static member inline meter (children: #seq) = Interop.reactElementWithChildren "meter" children 344 | 345 | static member inline nav xs = Interop.createElement "nav" xs 346 | static member inline nav (children: #seq) = Interop.reactElementWithChildren "nav" children 347 | 348 | /// The empty element, renders nothing on screen 349 | static member inline none : ReactElement = Interop.createTextElement "" 350 | 351 | static member inline noscript xs = Interop.createElement "noscript" xs 352 | static member inline noscript (children: #seq) = Interop.reactElementWithChildren "noscript" children 353 | 354 | static member inline object xs = Interop.createElement "object" xs 355 | static member inline object (children: #seq) = Interop.reactElementWithChildren "object" children 356 | 357 | static member inline ol xs = Interop.createElement "ol" xs 358 | static member inline ol (children: #seq) = Interop.reactElementWithChildren "ol" children 359 | 360 | static member inline option xs = Interop.createElement "option" xs 361 | static member inline option (value: float) = Interop.reactElementWithChild "option" value 362 | static member inline option (value: int) = Interop.reactElementWithChild "option" value 363 | static member inline option (value: ReactElement) = Interop.reactElementWithChild "option" value 364 | static member inline option (value: string) = Interop.reactElementWithChild "option" value 365 | static member inline option (children: #seq) = Interop.reactElementWithChildren "option" children 366 | 367 | static member inline optgroup xs = Interop.createElement "optgroup" xs 368 | static member inline optgroup (children: #seq) = Interop.reactElementWithChildren "optgroup" children 369 | 370 | static member inline orderedList xs = Interop.createElement "ol" xs 371 | static member inline orderedList (children: #seq) = Interop.reactElementWithChildren "ol" children 372 | 373 | static member inline output xs = Interop.createElement "output" xs 374 | static member inline output (value: float) = Interop.reactElementWithChild "output" value 375 | static member inline output (value: int) = Interop.reactElementWithChild "output" value 376 | static member inline output (value: ReactElement) = Interop.reactElementWithChild "output" value 377 | static member inline output (value: string) = Interop.reactElementWithChild "output" value 378 | static member inline output (children: #seq) = Interop.reactElementWithChildren "output" children 379 | 380 | static member inline p xs = Interop.createElement "p" xs 381 | static member inline p (value: float) = Interop.reactElementWithChild "p" value 382 | static member inline p (value: int) = Interop.reactElementWithChild "p" value 383 | static member inline p (value: ReactElement) = Interop.reactElementWithChild "p" value 384 | static member inline p (value: string) = Interop.reactElementWithChild "p" value 385 | static member inline p (children: #seq) = Interop.reactElementWithChildren "p" children 386 | 387 | static member inline paragraph xs = Interop.createElement "p" xs 388 | static member inline paragraph (value: float) = Interop.reactElementWithChild "p" value 389 | static member inline paragraph (value: int) = Interop.reactElementWithChild "p" value 390 | static member inline paragraph (value: ReactElement) = Interop.reactElementWithChild "p" value 391 | static member inline paragraph (value: string) = Interop.reactElementWithChild "p" value 392 | static member inline paragraph (children: #seq) = Interop.reactElementWithChildren "p" children 393 | 394 | static member inline param xs = Interop.createVoidElement "param" xs 395 | 396 | static member inline path xs = Interop.createElement "path" xs 397 | static member inline path (children: #seq) = Interop.reactElementWithChildren "path" children 398 | 399 | static member inline picture xs = Interop.createElement "picture" xs 400 | static member inline picture (children: #seq) = Interop.reactElementWithChildren "picture" children 401 | 402 | static member inline polygon xs = Interop.createElement "polygon" xs 403 | static member inline polygon (children: #seq) = Interop.reactElementWithChildren "polygon" children 404 | 405 | static member inline polyline xs = Interop.createElement "polyline" xs 406 | static member inline polyline (children: #seq) = Interop.reactElementWithChildren "polyline" children 407 | 408 | static member inline pre xs = Interop.createElement "pre" xs 409 | static member inline pre (value: bool) = Interop.reactElementWithChild "pre" value 410 | static member inline pre (value: float) = Interop.reactElementWithChild "pre" value 411 | static member inline pre (value: int) = Interop.reactElementWithChild "pre" value 412 | static member inline pre (value: ReactElement) = Interop.reactElementWithChild "pre" value 413 | static member inline pre (value: string) = Interop.reactElementWithChild "pre" value 414 | static member inline pre (children: #seq) = Interop.reactElementWithChildren "pre" children 415 | 416 | static member inline progress xs = Interop.createElement "progress" xs 417 | static member inline progress (children: #seq) = Interop.reactElementWithChildren "progress" children 418 | 419 | static member inline q xs = Interop.createElement "q" xs 420 | static member inline q (children: #seq) = Interop.reactElementWithChildren "q" children 421 | 422 | static member inline radialGradient xs = Interop.createElement "radialGradient" xs 423 | static member inline radialGradient (children: #seq) = Interop.reactElementWithChildren "radialGradient" children 424 | 425 | static member inline rb xs = Interop.createElement "rb" xs 426 | static member inline rb (value: float) = Interop.reactElementWithChild "rb" value 427 | static member inline rb (value: int) = Interop.reactElementWithChild "rb" value 428 | static member inline rb (value: ReactElement) = Interop.reactElementWithChild "rb" value 429 | static member inline rb (value: string) = Interop.reactElementWithChild "rb" value 430 | static member inline rb (children: #seq) = Interop.reactElementWithChildren "rb" children 431 | 432 | static member inline rect xs = Interop.createElement "rect" xs 433 | static member inline rect (children: #seq) = Interop.reactElementWithChildren "rect" children 434 | 435 | static member inline rp xs = Interop.createElement "rp" xs 436 | static member inline rp (value: float) = Interop.reactElementWithChild "rp" value 437 | static member inline rp (value: int) = Interop.reactElementWithChild "rp" value 438 | static member inline rp (value: ReactElement) = Interop.reactElementWithChild "rp" value 439 | static member inline rp (value: string) = Interop.reactElementWithChild "rp" value 440 | static member inline rp (children: #seq) = Interop.reactElementWithChildren "rp" children 441 | 442 | static member inline rt xs = Interop.createElement "rt" xs 443 | static member inline rt (value: float) = Interop.reactElementWithChild "rt" value 444 | static member inline rt (value: int) = Interop.reactElementWithChild "rt" value 445 | static member inline rt (value: ReactElement) = Interop.reactElementWithChild "rt" value 446 | static member inline rt (value: string) = Interop.reactElementWithChild "rt" value 447 | static member inline rt (children: #seq) = Interop.reactElementWithChildren "rt" children 448 | 449 | static member inline rtc xs = Interop.createElement "rtc" xs 450 | static member inline rtc (value: float) = Interop.reactElementWithChild "rtc" value 451 | static member inline rtc (value: int) = Interop.reactElementWithChild "rtc" value 452 | static member inline rtc (value: ReactElement) = Interop.reactElementWithChild "rtc" value 453 | static member inline rtc (value: string) = Interop.reactElementWithChild "rtc" value 454 | static member inline rtc (children: #seq) = Interop.reactElementWithChildren "rtc" children 455 | 456 | static member inline ruby xs = Interop.createElement "ruby" xs 457 | static member inline ruby (value: float) = Interop.reactElementWithChild "ruby" value 458 | static member inline ruby (value: int) = Interop.reactElementWithChild "ruby" value 459 | static member inline ruby (value: ReactElement) = Interop.reactElementWithChild "ruby" value 460 | static member inline ruby (value: string) = Interop.reactElementWithChild "ruby" value 461 | static member inline ruby (children: #seq) = Interop.reactElementWithChildren "ruby" children 462 | 463 | static member inline s xs = Interop.createElement "s" xs 464 | static member inline s (value: float) = Interop.reactElementWithChild "s" value 465 | static member inline s (value: int) = Interop.reactElementWithChild "s" value 466 | static member inline s (value: ReactElement) = Interop.reactElementWithChild "s" value 467 | static member inline s (value: string) = Interop.reactElementWithChild "s" value 468 | static member inline s (children: #seq) = Interop.reactElementWithChildren "s" children 469 | 470 | static member inline samp xs = Interop.createElement "samp" xs 471 | static member inline samp (value: float) = Interop.reactElementWithChild "samp" value 472 | static member inline samp (value: int) = Interop.reactElementWithChild "samp" value 473 | static member inline samp (value: ReactElement) = Interop.reactElementWithChild "samp" value 474 | static member inline samp (value: string) = Interop.reactElementWithChild "samp" value 475 | static member inline samp (children: #seq) = Interop.reactElementWithChildren "samp" children 476 | 477 | static member inline script xs = Interop.createElement "script" xs 478 | static member inline script (children: #seq) = Interop.reactElementWithChildren "script" children 479 | 480 | static member inline section xs = Interop.createElement "section" xs 481 | static member inline section (children: #seq) = Interop.reactElementWithChildren "section" children 482 | 483 | static member inline select xs = Interop.createElement "select" xs 484 | static member inline select (children: #seq) = Interop.reactElementWithChildren "select" children 485 | 486 | static member inline small xs = Interop.createElement "small" xs 487 | static member inline small (value: float) = Interop.reactElementWithChild "small" value 488 | static member inline small (value: int) = Interop.reactElementWithChild "small" value 489 | static member inline small (value: ReactElement) = Interop.reactElementWithChild "small" value 490 | static member inline small (value: string) = Interop.reactElementWithChild "small" value 491 | static member inline small (children: #seq) = Interop.reactElementWithChildren "small" children 492 | 493 | static member inline source xs = Interop.createVoidElement "source" xs 494 | 495 | static member inline span xs = Interop.createElement "span" xs 496 | static member inline span (value: float) = Interop.reactElementWithChild "span" value 497 | static member inline span (value: int) = Interop.reactElementWithChild "span" value 498 | static member inline span (value: ReactElement) = Interop.reactElementWithChild "span" value 499 | static member inline span (value: string) = Interop.reactElementWithChild "span" value 500 | static member inline span (children: #seq) = Interop.reactElementWithChildren "span" children 501 | 502 | static member inline stop xs = Interop.createElement "stop" xs 503 | static member inline stop (children: #seq) = Interop.reactElementWithChildren "stop" children 504 | 505 | static member inline strong xs = Interop.createElement "strong" xs 506 | static member inline strong (value: float) = Interop.reactElementWithChild "strong" value 507 | static member inline strong (value: int) = Interop.reactElementWithChild "strong" value 508 | static member inline strong (value: ReactElement) = Interop.reactElementWithChild "strong" value 509 | static member inline strong (value: string) = Interop.reactElementWithChild "strong" value 510 | static member inline strong (children: #seq) = Interop.reactElementWithChildren "strong" children 511 | 512 | static member inline style xs = Interop.createElement "style" xs 513 | static member inline style (value: string) = Interop.reactElementWithChild "style" value 514 | 515 | static member inline sub xs = Interop.createElement "sub" xs 516 | static member inline sub (value: float) = Interop.reactElementWithChild "sub" value 517 | static member inline sub (value: int) = Interop.reactElementWithChild "sub" value 518 | static member inline sub (value: ReactElement) = Interop.reactElementWithChild "sub" value 519 | static member inline sub (value: string) = Interop.reactElementWithChild "sub" value 520 | static member inline sub (children: #seq) = Interop.reactElementWithChildren "sub" children 521 | 522 | static member inline summary xs = Interop.createElement "summary" xs 523 | static member inline summary (value: float) = Interop.reactElementWithChild "summary" value 524 | static member inline summary (value: int) = Interop.reactElementWithChild "summary" value 525 | static member inline summary (value: ReactElement) = Interop.reactElementWithChild "summary" value 526 | static member inline summary (value: string) = Interop.reactElementWithChild "summary" value 527 | static member inline summary (children: #seq) = Interop.reactElementWithChildren "summary" children 528 | 529 | static member inline sup xs = Interop.createElement "sup" xs 530 | static member inline sup (value: float) = Interop.reactElementWithChild "sup" value 531 | static member inline sup (value: int) = Interop.reactElementWithChild "sup" value 532 | static member inline sup (value: ReactElement) = Interop.reactElementWithChild "sup" value 533 | static member inline sup (value: string) = Interop.reactElementWithChild "sup" value 534 | static member inline sup (children: #seq) = Interop.reactElementWithChildren "sup" children 535 | 536 | static member inline svg xs = Interop.createElement "svg" xs 537 | static member inline svg (children: #seq) = Interop.reactElementWithChildren "svg" children 538 | 539 | static member inline table xs = Interop.createElement "table" xs 540 | 541 | static member inline tableBody xs = Interop.createElement "tbody" xs 542 | static member inline tableBody (children: #seq) = Interop.reactElementWithChildren "tbody" children 543 | 544 | static member inline tableCell xs = Interop.createElement "td" xs 545 | 546 | static member inline tableHeader xs = Interop.createElement "th" xs 547 | static member inline tableHeader (children: #seq) = Interop.reactElementWithChildren "th" children 548 | 549 | static member inline tableRow xs = Interop.createElement "tr" xs 550 | 551 | static member inline tbody xs = Interop.createElement "tbody" xs 552 | static member inline tbody (children: #seq) = Interop.reactElementWithChildren "tbody" children 553 | 554 | static member inline td xs = Interop.createElement "td" xs 555 | static member inline td (value: float) = Interop.reactElementWithChild "td" value 556 | static member inline td (value: int) = Interop.reactElementWithChild "td" value 557 | static member inline td (value: ReactElement) = Interop.reactElementWithChild "td" value 558 | static member inline td (value: string) = Interop.reactElementWithChild "td" value 559 | static member inline td (children: #seq) = Interop.reactElementWithChildren "td" children 560 | 561 | static member inline template xs = Interop.createElement "template" xs 562 | static member inline template (children: #seq) = Interop.reactElementWithChildren "template" children 563 | 564 | static member inline text xs = Interop.createElement "text" xs 565 | static member inline text (value: float) : ReactElement = Interop.createTextElement (value.ToString ()) 566 | static member inline text (value: int) : ReactElement = Interop.createTextElement (value.ToString ()) 567 | static member inline text (value: string) : ReactElement = Interop.createTextElement value 568 | static member inline text (value: System.Guid) : ReactElement = Interop.createTextElement (string value) 569 | static member inline rawText (value: string) : ReactElement = Interop.createRawTextElement value 570 | 571 | static member inline textarea xs = Interop.createElement "textarea" xs 572 | static member inline textarea (children: #seq) = Interop.reactElementWithChildren "textarea" children 573 | 574 | static member inline tfoot xs = Interop.createElement "tfoot" xs 575 | static member inline tfoot (children: #seq) = Interop.reactElementWithChildren "tfoot" children 576 | 577 | static member inline th xs = Interop.createElement "th" xs 578 | static member inline th (value: float) = Interop.reactElementWithChild "th" value 579 | static member inline th (value: int) = Interop.reactElementWithChild "th" value 580 | static member inline th (value: ReactElement) = Interop.reactElementWithChild "th" value 581 | static member inline th (value: string) = Interop.reactElementWithChild "th" value 582 | static member inline th (children: #seq) = Interop.reactElementWithChildren "th" children 583 | 584 | static member inline thead xs = Interop.createElement "thead" xs 585 | static member inline thead (children: #seq) = Interop.reactElementWithChildren "thead" children 586 | 587 | static member inline time xs = Interop.createElement "time" xs 588 | static member inline time (children: #seq) = Interop.reactElementWithChildren "time" children 589 | 590 | static member inline title xs = Interop.createElement "title" xs 591 | static member inline title (value: float) = Interop.reactElementWithChild "title" value 592 | static member inline title (value: int) = Interop.reactElementWithChild "title" value 593 | static member inline title (value: ReactElement) = Interop.reactElementWithChild "title" value 594 | static member inline title (value: string) = Interop.reactElementWithChild "title" value 595 | static member inline title (children: #seq) = Interop.reactElementWithChildren "title" children 596 | 597 | static member inline tr xs = Interop.createElement "tr" xs 598 | static member inline tr (children: #seq) = Interop.reactElementWithChildren "tr" children 599 | 600 | static member inline track xs = Interop.createVoidElement "track" xs 601 | 602 | static member inline u xs = Interop.createElement "u" xs 603 | static member inline u (value: float) = Interop.reactElementWithChild "u" value 604 | static member inline u (value: int) = Interop.reactElementWithChild "u" value 605 | static member inline u (value: ReactElement) = Interop.reactElementWithChild "u" value 606 | static member inline u (value: string) = Interop.reactElementWithChild "u" value 607 | static member inline u (children: #seq) = Interop.reactElementWithChildren "u" children 608 | 609 | static member inline ul xs = Interop.createElement "ul" xs 610 | static member inline ul (children: #seq) = Interop.reactElementWithChildren "ul" children 611 | 612 | static member inline unorderedList xs = Interop.createElement "ul" xs 613 | static member inline unorderedList (children: #seq) = Interop.reactElementWithChildren "ul" children 614 | 615 | static member inline var xs = Interop.createElement "var" xs 616 | static member inline var (value: float) = Interop.reactElementWithChild "var" value 617 | static member inline var (value: int) = Interop.reactElementWithChild "var" value 618 | static member inline var (value: ReactElement) = Interop.reactElementWithChild "var" value 619 | static member inline var (value: string) = Interop.reactElementWithChild "var" value 620 | static member inline var (children: #seq) = Interop.reactElementWithChildren "var" children 621 | 622 | static member inline video xs = Interop.createElement "video" xs 623 | static member inline video (children: #seq) = Interop.reactElementWithChildren "video" children 624 | 625 | static member inline wbr xs = Interop.createVoidElement "wbr" xs 626 | -------------------------------------------------------------------------------- /src/Interop.fs: -------------------------------------------------------------------------------- 1 | namespace Feliz.ViewEngine 2 | 3 | open System 4 | open Feliz.ViewEngine.Styles 5 | 6 | #if FABLE_COMPILER 7 | type EraseAttribute = Fable.Core.EraseAttribute 8 | #else 9 | [] 10 | type EraseAttribute () = 11 | inherit Attribute () 12 | #endif 13 | 14 | /// Describes a basic style attribute. Interop between Feliz React and ViewEngine DSLs. 15 | [] 16 | module Interop = 17 | /// Output a string where the content has been HTML encoded. 18 | let mkText (content : 'a) = content.ToString () |> ViewBuilder.escape |> Text 19 | 20 | let inline mkChildren (props: #seq) = props |> List.ofSeq |> Children 21 | 22 | let inline reactElementWithChildren (name: string) (children: #seq) : ReactElement = 23 | Element (name, [ mkChildren children ]) 24 | let inline reactElementWithChild (name: string) (child: 'a) : ReactElement = 25 | Element (name, [ mkText child ]) 26 | 27 | let inline createElement name (props: IReactProperty list) : ReactElement = 28 | Element (name, props) 29 | let inline createElements (elements : ReactElement seq) : ReactElement = 30 | Elements elements 31 | let inline createVoidElement name (props: IReactProperty list) : ReactElement = 32 | VoidElement (name, props) 33 | let inline createTextElement (content : string) = ViewBuilder.escape content |> TextElement 34 | let inline createRawTextElement (content : string) = TextElement content 35 | 36 | let mkAttr (key: string) (value: obj) : IReactProperty = 37 | let result = 38 | match value with 39 | | :? bool -> value.ToString().ToLower() 40 | | _ -> value.ToString() |> ViewBuilder.escape 41 | KeyValue (key, result) 42 | 43 | let mkEventHandler(name: string) (handler: obj -> unit) : IReactProperty = 44 | let event = EventHandlerType.Event(handler) 45 | IReactProperty.KeyValue(name, event) 46 | 47 | let mkEventHandlerWithKey name key (handler: obj -> unit) = 48 | let keyEvent = EventHandlerType.KeyEvent(key, handler) 49 | IReactProperty.KeyValue(name, keyEvent) 50 | 51 | let inline mkStyle (key: string) (value: obj) : IStyleAttribute = Style (key, value) :> _ 52 | 53 | type FunctionComponent<'Props> = 'Props -> ReactElement -------------------------------------------------------------------------------- /src/React.fs: -------------------------------------------------------------------------------- 1 | namespace Feliz.ViewEngine 2 | 3 | open System 4 | 5 | //fsharplint:disable 6 | 7 | type React = 8 | /// 9 | /// Creates a React function component from a function that accepts a "props" object and renders a result. 10 | /// A component key can be provided in the props object, or a custom `withKey` function can be provided. 11 | /// 12 | /// A render function that returns an element. 13 | /// A function to derive a component key from the props. 14 | static member functionComponent(render: 'props -> ReactElement, ?withKey: 'props -> string) = 15 | render 16 | 17 | /// 18 | /// Creates a React function component from a function that accepts a "props" object and renders a result. 19 | /// A component key can be provided in the props object, or a custom `withKey` function can be provided. 20 | /// 21 | /// The component name to display in the React dev tools. 22 | /// A render function that returns an element. 23 | /// A function to derive a component key from the props. 24 | static member functionComponent(name: string, render: 'props -> ReactElement, ?withKey: 'props -> string) = 25 | render 26 | 27 | /// 28 | /// Creates a React function component from a function that accepts a "props" object and renders a result. 29 | /// A component key can be provided in the props object, or a custom `withKey` function can be provided. 30 | /// 31 | /// A render function that returns a list of elements. 32 | /// A function to derive a component key from the props. 33 | static member functionComponent(render: 'props -> #seq, ?withKey: 'props -> string) = 34 | render 35 | 36 | /// 37 | /// Creates a React function component from a function that accepts a "props" object and renders a result. 38 | /// A component key can be provided in the props object, or a custom `withKey` function can be provided. 39 | /// 40 | /// A render function that returns a list of elements. 41 | /// The component name to display in the React dev tools. 42 | /// A function to derive a component key from the props. 43 | static member functionComponent(name: string, render: 'props -> #seq, ?withKey: 'props -> string) = 44 | render 45 | 46 | /// 47 | /// The `React.fragment` component lets you return multiple elements in your `render()` method without creating an additional DOM element. 48 | /// 49 | /// A collection of elements to render without parent 50 | static member fragment(elements : #seq) = 51 | Interop.createElements elements -------------------------------------------------------------------------------- /src/StyleTypes.fs: -------------------------------------------------------------------------------- 1 | namespace Feliz.ViewEngine.Styles 2 | 3 | open System 4 | 5 | type IBorderStyle = interface end 6 | 7 | type ITextAlignment = interface end 8 | 9 | type ITextDecoration = interface end 10 | 11 | type ITextDecorationLine = interface end 12 | 13 | type IVisibility = interface end 14 | 15 | type IPosition = interface end 16 | 17 | type IAlignContent = interface end 18 | 19 | type IAlignItems = interface end 20 | 21 | type IAlignSelf = interface end 22 | 23 | type IDisplay = interface end 24 | 25 | type IFontStyle = interface end 26 | 27 | type IFontVariant = interface end 28 | 29 | type IFontWeight = interface end 30 | 31 | type IFontStretch = interface end 32 | 33 | type IFontKerning = interface end 34 | 35 | type IOverflow = interface end 36 | 37 | type IWordWrap = interface end 38 | 39 | type IBackgroundRepeat = interface end 40 | 41 | type IBackgroundClip = interface end 42 | 43 | type ICssUnit = interface end 44 | 45 | type ITransitionProperty = interface end 46 | 47 | type ITransformProperty = interface end 48 | 49 | type IStyleAttribute = interface end 50 | 51 | type StyleAttribute = 52 | | Style of string * obj 53 | interface IStyleAttribute 54 | 55 | override x.ToString () = 56 | let (Style (key, value)) = x 57 | String.Join(":", key, value) 58 | 59 | type CssUnit = 60 | | CssUnit of string 61 | interface ICssUnit 62 | 63 | override x.ToString () = 64 | let (CssUnit value) = x 65 | value 66 | 67 | type TextDecorationLine = 68 | | TextDecorationLine of string 69 | interface ITextDecorationLine 70 | 71 | override x.ToString () = 72 | let (TextDecorationLine value) = x 73 | value 74 | 75 | type TextDecoration = 76 | | TextDecoration of string 77 | interface ITextDecoration 78 | 79 | override x.ToString () = 80 | let (TextDecoration value) = x 81 | value -------------------------------------------------------------------------------- /src/TextDecorationLine.fs: -------------------------------------------------------------------------------- 1 | namespace Feliz.ViewEngine 2 | 3 | open Feliz.ViewEngine.Styles 4 | 5 | //fsharplint:disable 6 | 7 | [] 8 | type textDecorationLine = 9 | static member inline none : ITextDecorationLine = TextDecorationLine "none" :> _ 10 | static member inline underline : ITextDecorationLine = TextDecorationLine "underline" :> _ 11 | static member inline overline : ITextDecorationLine = TextDecorationLine "overline" :> _ 12 | static member inline lineThrough : ITextDecorationLine = TextDecorationLine "line-through" :> _ 13 | static member inline initial : ITextDecorationLine = TextDecorationLine "initial" :> _ 14 | static member inline inheritFromParent : ITextDecorationLine = TextDecorationLine "inherit" :> _ -------------------------------------------------------------------------------- /src/TextDecorationStyle.fs: -------------------------------------------------------------------------------- 1 | namespace Feliz.ViewEngine 2 | 3 | open Feliz.ViewEngine.Styles 4 | 5 | [] 6 | type textDecorationStyle = 7 | /// Default value. The line will display as a single line. 8 | /// 9 | /// See example https://www.w3schools.com/cssref/playit.asp?filename=playcss_text-decoration-style&preval=solid 10 | static member inline solid : ITextDecoration = TextDecoration "solid" :> _ 11 | /// The line will display as a double line. 12 | /// 13 | /// https://www.w3schools.com/cssref/playit.asp?filename=playcss_text-decoration-style&preval=double 14 | static member inline double : ITextDecoration = TextDecoration "double" :> _ 15 | /// The line will display as a dotted line. 16 | /// 17 | /// See example https://www.w3schools.com/cssref/playit.asp?filename=playcss_text-decoration-style&preval=dotted 18 | static member inline dotted : ITextDecoration = TextDecoration "dotted" :> _ 19 | /// The line will display as a dashed line. 20 | /// 21 | /// See example https://www.w3schools.com/cssref/playit.asp?filename=playcss_text-decoration-style&preval=dashed 22 | static member inline dashed : ITextDecoration = TextDecoration "dashed" :> _ 23 | /// The line will display as a wavy line. 24 | /// 25 | /// https://www.w3schools.com/cssref/playit.asp?filename=playcss_text-decoration-style&preval=wavy 26 | static member inline wavy : ITextDecoration = TextDecoration "wavy" :> _ 27 | /// Sets this property to its default value. 28 | /// 29 | /// See example https://www.w3schools.com/cssref/playit.asp?filename=playcss_text-decoration-style&preval=initial 30 | static member inline initial : ITextDecoration = TextDecoration "initial" :> _ 31 | /// Inherits this property from its parent element. 32 | static member inline inheritFromParent : ITextDecoration = TextDecoration "inherit" :> _ -------------------------------------------------------------------------------- /src/ViewEngine.fs: -------------------------------------------------------------------------------- 1 | // --------------------------- 2 | // Attribution to original authors of this code 3 | // --------------------------- 4 | // This code has been originally ported from Giraffe which was originally ported from Suave with small modifications 5 | // afterwards. 6 | // 7 | // The original code was authored by 8 | // * Dustin Moris Gorski (https://github.com/dustinmoris) 9 | // * Henrik Feldt (https://github.com/haf) 10 | // * Ademar Gonzalez (https://github.com/ademar) 11 | // 12 | // You can find the original implementations here: 13 | // - https://github.com/giraffe-fsharp/Giraffe/blob/master/src/Giraffe/GiraffeViewEngine.fs 14 | // - https://github.com/SuaveIO/suave/blob/master/src/Suave.Experimental/ViewEngine.fs 15 | // 16 | 17 | namespace Feliz.ViewEngine 18 | 19 | open System 20 | open System.Text 21 | 22 | type EventHandlerType = 23 | | Event of (obj -> unit) 24 | | KeyEvent of (obj * (obj -> unit)) 25 | 26 | type IReactProperty = 27 | | KeyValue of string * obj 28 | | Children of ReactElement list 29 | | Text of string 30 | 31 | and ReactElement = 32 | | Element of string * IReactProperty list // An element which may contain properties 33 | | VoidElement of string * IReactProperty list // An empty self-closed element which may contain properties 34 | | TextElement of string 35 | | Elements of ReactElement seq 36 | 37 | [] 38 | module ViewBuilder = 39 | let getEscapeSequence c = 40 | match c with 41 | | '<' -> "<" 42 | | '>' -> ">" 43 | | '\"' -> """ 44 | | '\'' -> "'" 45 | | '&' -> "&" 46 | | ch -> ch.ToString() 47 | 48 | let escape str = String.collect getEscapeSequence str 49 | 50 | let inline private (+=) (sb : StringBuilder) (text : string) = sb.Append(text) 51 | let inline private (+!) (sb : StringBuilder) (text : string) = sb.Append(text) |> ignore 52 | 53 | let inline private selfClosingBracket (isHtml : bool) = 54 | if isHtml then ">" else " />" 55 | 56 | let rec private buildNode (isHtml : bool) (sb : StringBuilder) (node : ReactElement) : unit = 57 | let splitProps (props: IReactProperty list) = 58 | let init = [], None, [] 59 | let folder (prop: IReactProperty) ((children, text, attrs) : ReactElement list * string option * (string*obj) list) = 60 | match prop with 61 | | KeyValue (k, v) -> 62 | match v with 63 | | :? EventHandlerType -> 64 | // ignore event handlers in render 65 | children, text, attrs 66 | | _ -> 67 | children, text, (k, v) :: attrs 68 | | Children ch -> List.append children ch, text, attrs 69 | | Text text -> children, Some text, attrs 70 | List.foldBack folder props init 71 | 72 | let buildElement closingBracket (elemName, props : (string*obj) list) = 73 | match props with 74 | | [] -> do sb += "<" += elemName +! closingBracket 75 | | _ -> 76 | do sb += "<" +! elemName 77 | 78 | props 79 | |> List.iter (fun (key, value) -> 80 | sb += " " += key += "=\"" += value.ToString () +! "\"") 81 | 82 | sb +! closingBracket 83 | 84 | let inline buildParentNode (elemName, attributes : (string*obj) list, nodes : ReactElement list) = 85 | buildElement ">" (elemName, attributes) 86 | for node in nodes do 87 | buildNode isHtml sb node 88 | sb += "" 89 | 90 | match node with 91 | | TextElement text -> sb +! text 92 | | VoidElement (name, props) -> 93 | let _, _, attrs = splitProps props 94 | buildElement (selfClosingBracket isHtml) (name, attrs) 95 | | Element (name, props) -> 96 | let children, text, attrs = splitProps props 97 | match children, text, attrs with 98 | | _, Some text, _ -> buildParentNode (name, attrs, TextElement text :: children) 99 | | _ -> buildParentNode (name, attrs, children) 100 | | Elements elements -> 101 | for element in elements do 102 | buildNode isHtml sb element 103 | 104 | let buildXmlNode = buildNode false 105 | let buildHtmlNode = buildNode true 106 | 107 | let buildXmlNodes sb (nodes : ReactElement list) = for n in nodes do buildXmlNode sb n 108 | let buildHtmlNodes sb (nodes : ReactElement list) = for n in nodes do buildHtmlNode sb n 109 | 110 | let buildHtmlDocument sb (document : ReactElement) = 111 | sb += "" +! Environment.NewLine 112 | buildHtmlNode sb document 113 | 114 | let buildXmlDocument sb (document : ReactElement) = 115 | sb += """""" +! Environment.NewLine 116 | buildXmlNode sb document 117 | 118 | // fsharplint:disable 119 | 120 | /// Render HTML/XML views fsharplint:disable 121 | type Render = 122 | /// Create XML view 123 | static member xmlView (node: ReactElement) : string = 124 | let sb = new StringBuilder() in ViewBuilder.buildXmlNode sb node 125 | sb.ToString() 126 | 127 | /// Create XML view 128 | static member xmlView (nodes: ReactElement list) : string = 129 | let sb = new StringBuilder() in ViewBuilder.buildXmlNodes sb nodes 130 | sb.ToString() 131 | 132 | /// Create XML document view with 133 | static member xmlDocument (document: ReactElement) : string = 134 | let sb = new StringBuilder() in ViewBuilder.buildXmlDocument sb document 135 | sb.ToString() 136 | 137 | /// Create HTML view 138 | static member htmlView (node: ReactElement) : string = 139 | let sb = new StringBuilder() in ViewBuilder.buildHtmlNode sb node 140 | sb.ToString() 141 | 142 | /// Create HTML view 143 | static member htmlView (nodes: ReactElement list) : string = 144 | let sb = new StringBuilder() in ViewBuilder.buildHtmlNodes sb nodes 145 | sb.ToString() 146 | 147 | /// Create HTML document view with 148 | static member htmlDocument (document: ReactElement) : string = 149 | let sb = new StringBuilder() in ViewBuilder.buildHtmlDocument sb document 150 | sb.ToString() 151 | -------------------------------------------------------------------------------- /src/paket.references: -------------------------------------------------------------------------------- 1 | group Main 2 | 3 | Fsharp.Core 4 | -------------------------------------------------------------------------------- /test/Bulma.ViewEngineTest.fs: -------------------------------------------------------------------------------- 1 | module Tests.Bulma.ViewEngine 2 | 3 | open Feliz.ViewEngine 4 | open Feliz.Bulma.ViewEngine 5 | open Feliz.Bulma.ViewEngine.Operators 6 | open Swensen.Unquote 7 | open Xunit 8 | 9 | 10 | [] 11 | let ``Test custom class to bulma elements are combined``() = 12 | // Arrange / Act 13 | let result = 14 | Bulma.section [ 15 | prop.classes ["test"] 16 | ] 17 | |> Render.htmlView 18 | 19 | // Assert 20 | test <@ result = "
" @> 21 | 22 | [] 23 | let ``Test custom classes to bulma elements are combined``() = 24 | // Arrange / Act 25 | let result = 26 | Bulma.section [ 27 | prop.classes ["test"; "ing"] 28 | ] 29 | |> Render.htmlView 30 | 31 | // Assert 32 | test <@ result = "
" @> 33 | 34 | [] 35 | let ``Test custom class to bulma elements with modifiers are combined``() = 36 | // Arrange / Act 37 | let result = 38 | Bulma.section [ 39 | section.isLarge 40 | color.isDanger 41 | ] 42 | |> Render.htmlView 43 | 44 | // Assert 45 | test <@ result = "
" @> 46 | 47 | [] 48 | let ``Test bulma modifiers with html elements are combined``() = 49 | // Arrange / Act 50 | let result = 51 | Html.div [ 52 | section.isLarge 53 | ++ color.isDanger 54 | ] 55 | |> Render.htmlView 56 | 57 | // Assert 58 | test <@ result = "
" @> 59 | 60 | 61 | [] 62 | let ``Test bulma input text has correct classes``() = 63 | // Arrange / Act 64 | let result = 65 | Bulma.input.text [ color.isDanger ] 66 | |> Render.htmlView 67 | 68 | // Assert 69 | test <@ result = "" @> 70 | -------------------------------------------------------------------------------- /test/Program.fs: -------------------------------------------------------------------------------- 1 | module Program = let [] main _ = 0 2 | -------------------------------------------------------------------------------- /test/Tests.Feliz.ViewEngine.fsproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net9.0 6 | false 7 | 8 | 9 | 10 | Feliz.ViewEngine.fsproj 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /test/ViewEngineTest.fs: -------------------------------------------------------------------------------- 1 | module Tests.ViewEngine 2 | 3 | open Feliz.ViewEngine 4 | open Swensen.Unquote 5 | open Xunit 6 | 7 | [] 8 | let ``Simple text element is Ok``() = 9 | // Arrange / Act 10 | let result = 11 | Html.text "test" 12 | |> Render.htmlView 13 | 14 | // Assert 15 | test <@ result = "test" @> 16 | 17 | [] 18 | let ``Simple text element is escaped Ok``() = 19 | // Arrange / Act 20 | let result = 21 | Html.text "te Render.htmlView 23 | 24 | // Assert 25 | test <@ result = "te<st" @> 26 | 27 | [] 28 | let ``p element with text is Ok``() = 29 | // Arrange / Act 30 | let result = 31 | Html.p "test" 32 | |> Render.htmlView 33 | 34 | // Assert 35 | test <@ result = "

test

" @> 36 | 37 | [] 38 | let ``p element with text is escaped Ok``() = 39 | // Arrange / Act 40 | let result = 41 | Html.p "te>st" 42 | |> Render.htmlView 43 | 44 | // Assert 45 | test <@ result = "

te>st

" @> 46 | 47 | [] 48 | let ``p element with text property is Ok``() = 49 | // Arrange / Act 50 | let result = 51 | Html.p [ 52 | prop.text "test" 53 | ] 54 | |> Render.htmlView 55 | 56 | // Assert 57 | test <@ result = "

test

" @> 58 | 59 | [] 60 | let ``p element with onchange handler is Ok``() = 61 | // Arrange / Act 62 | let result = 63 | Html.p [ 64 | prop.onChange (fun (ev: obj) -> ()) 65 | prop.text "test" 66 | ] 67 | |> Render.htmlView 68 | 69 | // Assert 70 | test <@ result = "

test

" @> 71 | 72 | [] 73 | let ``p element with text property is escaped Ok``() = 74 | // Arrange / Act 75 | let result = 76 | Html.p [ 77 | prop.text "tes&t" 78 | ] 79 | |> Render.htmlView 80 | 81 | // Assert 82 | test <@ result = "

tes&t

" @> 83 | 84 | [] 85 | let ``p element with text element is Ok``() = 86 | // Arrange / Act 87 | let result = 88 | Html.p [ 89 | Html.text "test" 90 | ] 91 | |> Render.htmlView 92 | 93 | // Assert 94 | test <@ result = "

test

" @> 95 | 96 | [] 97 | let ``p element with text element is escaped Ok``() = 98 | // Arrange / Act 99 | let result = 100 | Html.p [ 101 | Html.text "t\"est" 102 | ] 103 | |> Render.htmlView 104 | 105 | // Assert 106 | test <@ result = "

t"est

" @> 107 | 108 | [] 109 | let ``Closed element Ok``() = 110 | // Arrange / Act 111 | let result = 112 | Html.div [ 113 | Html.br [] 114 | ] 115 | |> Render.htmlView 116 | 117 | // Assert 118 | test <@ result = "

" @> 119 | 120 | [] 121 | let ``p element with text element and class property is Ok``() = 122 | // Arrange / Act 123 | let result = 124 | Html.p [ 125 | prop.className "main" 126 | prop.children [ 127 | Html.text "test" 128 | ] 129 | ] 130 | |> Render.htmlView 131 | 132 | // Assert 133 | test <@ result = "

test

" @> 134 | 135 | [] 136 | let ``p element with text element and classes property is Ok``() = 137 | // Arrange / Act 138 | let result = 139 | Html.p [ 140 | prop.classes ["c1"; "c2"] 141 | prop.children [ 142 | Html.text "test" 143 | ] 144 | ] 145 | |> Render.htmlView 146 | 147 | // Assert 148 | test <@ result = "

test

" @> 149 | 150 | 151 | [] 152 | let ``h1 element with text and style property is Ok``() = 153 | // Arrange / Act 154 | let result = 155 | Html.h1 [ 156 | prop.style [ style.fontSize(100); style.color("#137373") ] 157 | prop.text "examples" 158 | ] 159 | |> Render.htmlView 160 | 161 | // Assert 162 | test <@ result = "

examples

" @> 163 | 164 | [] 165 | let ``The order of properties for an element is preserved``() = 166 | // Arrange / Act 167 | let result = 168 | Html.link [ 169 | prop.rel.stylesheet 170 | prop.type' "text/css" 171 | prop.href "main.css" 172 | ] 173 | |> Render.htmlView 174 | 175 | // Assert 176 | test <@ result = "" @> 177 | 178 | [] 179 | let ``h1 element with text and style property with css unit is Ok``() = 180 | // Arrange / Act 181 | let result = 182 | Html.h1 [ 183 | prop.style [ style.fontSize(length.em(100)) ] 184 | prop.text "examples" 185 | ] 186 | |> Render.htmlView 187 | 188 | // Assert 189 | test <@ result = "

examples

" @> 190 | 191 | [] 192 | let ``Void tag in XML should be self closing tag`` () = 193 | let unary = Html.br [] |> Render.xmlView 194 | Assert.Equal("
", unary) 195 | 196 | [] 197 | let ``Void tag in HTML should be unary tag`` () = 198 | let unary = Html.br [] |> Render.htmlView 199 | Assert.Equal("
", unary) 200 | 201 | [] 202 | let ``None tag in HTML should render nothing`` () = 203 | let result = Html.none |> Render.htmlView 204 | Assert.Equal("", result) 205 | 206 | [] 207 | let ``Nested content should render correctly`` () = 208 | let nested = 209 | Html.div [ 210 | Html.comment "this is a test" 211 | Html.h1 [ Html.text "Header" ] 212 | Html.p [ 213 | Html.rawText "
" 214 | Html.strong [ Html.text "Ipsum" ] 215 | Html.text " dollar" 216 | ] 217 | ] 218 | let html = 219 | nested 220 | |> Render.xmlView 221 | Assert.Equal("

Header


Ipsum dollar

", html) 222 | 223 | [] 224 | let ``Fragment works correctly`` () = 225 | let withFragment = 226 | Html.div [ 227 | prop.className "test-class" 228 | prop.children [ 229 | Html.p "test outer p" 230 | React.fragment [ 231 | Html.p "test inner p" 232 | Html.span "test span" 233 | ] 234 | ] 235 | ] 236 | 237 | let html = 238 | withFragment 239 | |> Render.htmlView 240 | Assert.Equal("

test outer p

test inner p

test span
", html) 241 | 242 | 243 | [] 244 | let ``Event handlers props are included in the ReactElement DOM but not rendered`` () = 245 | 246 | let onClick _ = printfn "click" 247 | let onMouseOver _ = printfn "mouse-over" 248 | 249 | let withProps = 250 | Html.button [ 251 | prop.className "counter" 252 | prop.onClick onClick 253 | prop.onMouseOver onMouseOver 254 | ] 255 | 256 | let props = 257 | match withProps with 258 | | ReactElement.Element(tag, props) 259 | | ReactElement.VoidElement(tag, props) -> 260 | props 261 | |_ -> failwith "unsupported" 262 | 263 | // are contained in DOM (RectElement) 264 | Assert.Equal(3, props.Length) 265 | 266 | let eventNames = props |> List.choose (function 267 | | IReactProperty.KeyValue (k, v) -> 268 | match v with 269 | | :? EventHandlerType -> k |> Some 270 | | _ -> None 271 | | _ -> None 272 | ) 273 | 274 | Assert.Equal(2, eventNames.Length) 275 | Assert.Contains("onClick", eventNames) 276 | Assert.Contains("onMouseOver", eventNames) 277 | 278 | 279 | let html = 280 | withProps 281 | |> Render.htmlView 282 | 283 | Assert.Equal("", html) -------------------------------------------------------------------------------- /test/paket.references: -------------------------------------------------------------------------------- 1 | group Test 2 | 3 | Microsoft.NET.Test.Sdk 4 | coverlet.msbuild 5 | 6 | FSharp.Core 7 | 8 | xunit 9 | xunit.runner.visualstudio 10 | Unquote 11 | --------------------------------------------------------------------------------