Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generator for updating index of icons #1

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>net9.0;netstandard2.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<Compile Include="Program.fs" />
</ItemGroup>
<Import Project="..\.paket\Paket.Restore.targets" />
</Project>
107 changes: 107 additions & 0 deletions Glutinum.Feliz.Lucide.Generator/Program.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
namespace Feliz.Lucide.Generator

open FParsec
open System

[<AutoOpen>]
module Helpers =
// Attributable to Shmew - taken from Feliz.Generator.MaterialUI/Common.fs
let appendApostropheToReservedKeywords =
let reserved =
[
"checked"; "static"; "fixed"; "inline"; "default"; "component";
"inherit"; "open"; "type"; "true"; "false"; "in"; "end"; "global"
]
|> Set.ofList
fun s -> if reserved.Contains s then s + "'" else s

module LabParsers =
/// Find next <c>value</c>.
let find value skip = skipCharsTillString value skip Int32.MaxValue >>. spaces
/// Finds next <c>declare const</c> in lucide index
let findValidDeclaration : Parser<_,_> = manyTill (find "declare" true >>. spaces ) ( followedBy (pstring "const") >>. pstring "const" )
/// Reads the identifier
let readIdentifier : Parser<_,_> = manyCharsTill (letter <|> digit ) (anyOf ": ")
// Lucide Lab Parsers
let getNextIconDecl : Parser<_,_> = findValidDeclaration >>. spaces >>. readIdentifier
let getDecls : Parser<_,_> = manyTill (getNextIconDecl) (notFollowedBy ( find "declare" true ))

module LabGenerator =
let parseIdentifiers target =
runParserOnFile LabParsers.getDecls () target (System.Text.UTF8Encoding())
|> function
| Success(result, _, _) -> result
| Failure(errorMsg,_,_) -> printfn $"{errorMsg}" |> exit 1

let renderIdentifierMember identifier =
$"""
static member inline {identifier} ( props : #ISvgAttribute list ) = import "{identifier}" "@lucide/lab" |> Interop.svgAttribute "iconNode" |> fun iconProp -> Interop.reactApi.createElement(import "Icon" "lucide-react", createObj !!(iconProp::!!props))"""

let renderDocument parsedIdentifiers =
[
"""
namespace Feliz.Lucide

// THIS FILE IS AUTO-GENERATED

open Feliz
open Fable.Core
open Fable.Core.JsInterop

[<Erase>]
type private icon =
static member inline iconNode ( value : string ) = Interop.svgAttribute "iconNode" value

module [<Erase>] Lab =
type Lucide with"""
for ( identifier : string ) in parsedIdentifiers do
renderIdentifierMember ( identifier |> appendApostropheToReservedKeywords )
] |> String.concat ""

module LucideParser =
let find value = skipCharsTillString value true Int32.MaxValue >>. spaces
let findDeclaration = manyTill ( find "declare" ) ( followedBy (pstring "const") ) >>. pstring "const" >>. spaces
let getIdentifier = manyCharsTill ( letter <|> digit <|> anyOf "_" ) ( anyOf " :" )
let getIdentifierOfType type' = manyTill findDeclaration ( followedBy (getIdentifier >>. skipAnyOf " :" >>. pstring type') ) >>. getIdentifier
let parser = manyTill (getIdentifierOfType "react") (notFollowedBy findDeclaration)

module LucideGenerator =
let parseIdentifiers target =
runParserOnFile LucideParser.parser () target (System.Text.UTF8Encoding())
|> function
| Success(result, _, _) -> result
| Failure(errorMsg,_,_) -> printfn $"{errorMsg}" |> exit 1

let renderIdentifierMember identifier =
$"""
static member inline {identifier} ( props : #ISvgAttribute list ) = Interop.reactApi.createElement(import "{identifier}" "lucide-react", createObj !!props)"""
let renderDocument parsedIdentifiers =
[
"""namespace Feliz.Lucide

// THIS FILE IS AUTO GENERATED

open Feliz
open Fable.Core
open Fable.Core.JsInterop

[<Erase>]
type Lucide ="""
for ( identifier : string ) in parsedIdentifiers do
if identifier <> "Icon" then
renderIdentifierMember ( identifier |> appendApostropheToReservedKeywords )
] |> String.concat ""


open System.IO

module Program =
[<EntryPoint>]
let main argv =
LabGenerator.parseIdentifiers "../node_modules/@lucide/lab/dist/lucide-lab.d.ts"
|> LabGenerator.renderDocument
|> fun render -> File.WriteAllText(@"..\src\LabExports.fs", render)
LucideGenerator.parseIdentifiers "../node_modules/lucide-react/dist/lucide-react.d.ts"
|> LucideGenerator.renderDocument
|> fun render -> File.WriteAllText(@"..\src\Exports.fs", render)
0
6 changes: 6 additions & 0 deletions Glutinum.Feliz.Lucide.sln
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Build", "build\Build.fsproj
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Demo", "demo\Demo.fsproj", "{054D7DBC-B3A3-42E7-909A-85817B211496}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Glutinum.Feliz.Lucide.Generator", "Glutinum.Feliz.Lucide.Generator\Glutinum.Feliz.Lucide.Generator.fsproj", "{EC7A06D4-56EA-483F-87AE-3CBECA6C8278}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -30,5 +32,9 @@ Global
{054D7DBC-B3A3-42E7-909A-85817B211496}.Debug|Any CPU.Build.0 = Debug|Any CPU
{054D7DBC-B3A3-42E7-909A-85817B211496}.Release|Any CPU.ActiveCfg = Release|Any CPU
{054D7DBC-B3A3-42E7-909A-85817B211496}.Release|Any CPU.Build.0 = Release|Any CPU
{EC7A06D4-56EA-483F-87AE-3CBECA6C8278}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EC7A06D4-56EA-483F-87AE-3CBECA6C8278}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EC7A06D4-56EA-483F-87AE-3CBECA6C8278}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EC7A06D4-56EA-483F-87AE-3CBECA6C8278}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
5 changes: 5 additions & 0 deletions demo/Main.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ open Feliz
open Browser.Dom
open Fable.Core.JsInterop
open Feliz.Lucide
open Feliz.Lucide.Lab

// Workaround to have React-refresh working
// I need to open an issue on react-refresh to see if they can improve the detection
Expand All @@ -21,6 +22,10 @@ let private Component () =
lucide.size 48
svg.fill "lightblue"
]
Lucide.ampersandSquare [
lucide.size 48
svg.fill "lightblue"
]
]
]

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"dependencies": {
"@lucide/lab": "^0.1.2",
"lucide-react": "^0.89.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Expand Down
Loading